Common Errors & Troubleshooting

Quick solutions to common issues you might encounter.

Build Errors

Jekyll Build Fails

Error: jekyll 3.9.0 | Error: Permission denied

Solution:

# Fix permissions
chmod -R 755 _site

# Or clean and rebuild
bundle exec jekyll clean
bundle exec jekyll build

Error: Dependency Error: Yikes! It looks like you don't have bundler

Solution:

gem install bundler
bundle install

Error: Could not find gem 'jekyll'

Solution:

bundle install
# Or
gem install jekyll

Liquid Syntax Errors

Error: Liquid Exception: Liquid syntax error

Solution:

<!-- Bad: Unclosed tag -->
{% for item in array

<!-- Good: Properly closed -->
{% for item in array

<!-- Good: Properly closed -->
{% for item in array %}
  {{ item }}
{% endfor %}

Error: undefined method 'map' for nil:NilClass

Solution:

<!-- Check if variable exists first -->

YAML Frontmatter Issues

Error: YAML Exception reading file

Solution:

# Bad: Missing closing quotes
---
title: "My Title
---

# Good: Properly quoted
---
title: "My Title"
description: "My description"
---

# Or use literal block for multiline
---
title: My Title
description: |
  This is a longer
  description text
---

Styling Issues

Styles Not Loading

Problem: CSS changes not appearing

Solutions:

# 1. Clear cache
bundle exec jekyll clean
bundle exec jekyll build

# 2. Hard refresh browser
# Mac: Cmd + Shift + R
# Windows/Linux: Ctrl + Shift + R

# 3. Check file path
# Should be: /assets/css/main.css
# Not: /assets/css/main.css (without filter)

CSS Not Compiling

Error: Sass Error: Invalid CSS

Solution:

// Bad: Missing semicolon
.element {
  color: red
  background: blue;
}

// Good:
.element {
  color: red;
  background: blue;
}

Theme Toggle Not Working

Problem: Theme switch doesn’t persist

Solution:

// Check localStorage is working
if (typeof Storage !== "undefined") {
  localStorage.setItem("theme", "dark");
  console.log(localStorage.getItem("theme"));
} else {
  console.error("LocalStorage not supported");
}

// Ensure theme is set on page load
document.addEventListener("DOMContentLoaded", () => {
  const theme = localStorage.getItem("theme") || "dark";
  document.documentElement.setAttribute("data-theme", theme);
});

Asset Loading Issues

Images Not Displaying

Problem: Broken image icons

Solutions:

<!-- Bad: Absolute path without baseurl -->
<img src="/assets/images/logo.png">

<!-- Good: Use relative_url filter -->
<img src="/assets/images/logo.png">

<!-- For external URLs -->
<img src="https://cdn.modrinth.com/data/abc/icon.png">

Check file exists:

# List image directory
ls -la assets/images/

# Check file permissions
chmod 644 assets/images/logo.png

Font Awesome Icons Not Showing

Problem: Boxes or missing icons

Solutions:

<!-- 1. Verify CDN link is correct -->
<link
  rel="stylesheet"
  href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
/>

<!-- 2. Check icon class syntax -->
<!-- Bad -->
<i class="fa-gear"></i>

<!-- Good -->
<i class="fa-solid fa-gear"></i>

Test icon loading:

// Check if Font Awesome loaded
if (window.FontAwesome) {
  console.log("Font Awesome loaded");
} else {
  console.error("Font Awesome not loaded");
}

Data Issues

Modpack Data Not Rendering

Problem: Projects page is empty

Solutions:

# 1. Check JSON is valid
cat _data/mods.json | jq .

# 2. Verify file location
ls -la _data/mods.json

# 3. Check YAML config
grep -A 5 "data_dir" _config.yml

Debug in template:

<!-- Check if data exists -->

  <p>No data found</p>


<!-- Inspect data structure -->
<pre>null</pre>

JSON Parsing Errors

Error: Unexpected token in JSON

Solution:

# Validate JSON
cat _data/mods.json | python -m json.tool

# Or use jq
jq '.' _data/mods.json

Common JSON mistakes:

// Bad: Trailing comma
{
  "modpacks": [
    {"name": "Pack 1"},
  ]
}

// Good: No trailing comma
{
  "modpacks": [
    {"name": "Pack 1"}
  ]
}

// Bad: Single quotes
{'name': 'value'}

// Good: Double quotes
{"name": "value"}

Deployment Issues

GitHub Pages 404 Error

Problem: Pages work locally but 404 on GitHub Pages

Solutions:

# 1. Check baseurl in _config.yml
baseurl: "/your-repo-name" # Must match repo name
url: "https://username.github.io"
# 2. Ensure GitHub Pages is enabled
# Settings > Pages > Source: GitHub Actions or main branch
<!-- Use relative_url in all links -->
<a href="/docs/">Docs</a>
<link rel="stylesheet" href="/assets/css/main.css">

Build Succeeds But Site Not Updating

Solutions:

# 1. Clear GitHub Actions cache
# Go to Actions > Select workflow > Re-run jobs > Clear cache

# 2. Check deployment status
# Actions tab > View latest workflow run

# 3. Verify _config.yml excludes
exclude:
  - node_modules/
  - vendor/
  - .git/

Netlify Build Fails

Error: Command failed with exit code 127

Solution:

# netlify.toml
[build.environment]
  RUBY_VERSION = "3.1"

[build]
  command = "bundle install && bundle exec jekyll build"
  publish = "_site"

Performance Issues

Slow Build Times

Problem: Build takes 30+ seconds

Solutions:

# 1. Exclude unnecessary files
exclude:
  - node_modules/
  - src/
  - vendor/
  - .git/
  - README.md

# 2. Use incremental builds (dev only)
# bundle exec jekyll serve --incremental

# 3. Limit collection size
collections:
  docs:
    output: true

Slow Page Load

Problem: Pages take 5+ seconds to load

Solutions:

<!-- 1. Defer non-critical CSS -->
<link
  rel="preload"
  href="/assets/css/main.css"
  as="style"
  onload="this.rel='stylesheet'"
/>

<!-- 2. Lazy load images -->
<img src="image.jpg" loading="lazy" />

<!-- 3. Defer JavaScript -->
<script src="/assets/js/main.js" defer></script>

See Performance Guide for more.

Search & Filter Issues

Search Not Working

Problem: Typing in search input doesn’t filter results

Debug:

// Check if docs are loaded
console.log("Total docs:", allDocs.length);

// Test search function
const results = searchDocs("setup");
console.log("Search results:", results);

// Verify event listener
document.getElementById("docs-search").addEventListener("input", (e) => {
  console.log("Search query:", e.target.value);
});

Common fixes:

// Ensure correct element IDs
const searchInput = document.getElementById("docs-search");
const categorySelect = document.getElementById("docs-category");

// Case-insensitive search
const query = searchInput.value.toLowerCase();
const matches = allDocs.filter((doc) =>
  doc.title.toLowerCase().includes(query)
);

Browser Compatibility

Site Broken in Safari

Problem: CSS Grid not working

Solution:

/* Add fallback for older browsers */
.grid {
  display: flex;
  flex-wrap: wrap;
}

@supports (display: grid) {
  .grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  }
}

JavaScript Errors in IE11

Problem: Unexpected token errors

Solution:

// Don't use arrow functions in IE11
// Bad:
const myFunc = () => {};

// Good:
var myFunc = function () {};

// Or add polyfills
// <script src="https://polyfill.io/v3/polyfill.min.js"></script>

Git Issues

Large Files Rejected

Error: remote: error: File too large

Solution:

# Remove large file from history
git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch path/to/large-file' \
  --prune-empty --tag-name-filter cat -- --all

# Force push
git push origin --force --all

# Add to .gitignore
echo "path/to/large-files/" >> .gitignore

Merge Conflicts

Problem: CONFLICT (content): Merge conflict in file

Solution:

# View conflicted files
git status

# Edit file to resolve conflicts
# Look for:
<<<<<<< HEAD
Your changes
=======
Their changes
>>>>>>> branch-name

# Choose one or combine, then:
git add resolved-file.txt
git commit -m "Resolved merge conflict"

Debugging Tips

Enable Verbose Output

# Jekyll
bundle exec jekyll build --verbose

# Show full error traces
bundle exec jekyll build --trace

# Profile build time
bundle exec jekyll build --profile

Browser DevTools

// Check for JavaScript errors
// Open DevTools > Console

// Inspect element styles
// Right-click > Inspect

// Network tab for asset loading
// DevTools > Network > Reload page

Liquid Debugging

<!-- Print variable contents -->
nil

<!-- Check variable type -->

  Variable is nil


<!-- Debug entire site data -->
<pre>{"pages":["{% assign page_lang = page.url | split: '/' | second %}\n{% if page_lang == 'fr' %}\n{% assign page_lang = 'fr' %}\n{% else %}\n{% assign page_lang = 'en' %}\n{% endif %}\n{% assign t = site.data[page_lang] %}\n\n<section class=\"hero\" style=\"min-height: 60vh; display: flex; align-items: center; justify-content: center;\">\n  <div class=\"hero-card\" style=\"text-align: center; max-width: 600px;\">\n    <div style=\"font-size: 120px; font-weight: 700; color: var(--accent-primary); margin-bottom: 24px; line-height: 1;\">\n      404\n    </div>\n    <h1 style=\"margin: 0 0 16px 0; font-size: 32px;\">{{ t.error_404_title }}</h1>\n    <p class=\"muted\" style=\"font-size: 16px; margin-bottom: 32px;\">{{ t.error_404_message }}</p>\n    \n    <div class=\"cta-row\" style=\"flex-direction: column; gap: 12px;\">\n      <a class=\"btn primary\" href=\"{% if page_lang == 'fr' %}/abc-site/fr/{% else %}/abc-site/{% endif %}\">\n        <i class=\"fas fa-home\"></i> {{ t.error_404_back_home }}\n      </a>\n      <a class=\"btn ghost\" href=\"{% if page_lang == 'fr' %}/abc-site/fr/projects/{% else %}/abc-site/projects/{% endif %}\">\n        <i class=\"fas fa-list\"></i> {{ t.error_404_browse }}\n      </a>\n    </div>\n\n    <div style=\"margin-top: 48px; padding-top: 32px; border-top: 1px solid var(--border);\">\n      <p class=\"muted\" style=\"font-size: 13px; margin: 0;\">\n        {% if page_lang == 'fr' %}\n          Si vous pensez que c'est une erreur, <a href=\"{{ '/contact/' | relative_url }}\" style=\"color: var(--accent-primary); text-decoration: none;\">contactez-nous</a>.\n        {% else %}\n          If you think this is a mistake, <a href=\"{{ '/contact/' | relative_url }}\" style=\"color: var(--accent-primary); text-decoration: none;\">contact us</a>.\n        {% endif %}\n      </p>\n    </div>\n\n  </div>\n</section>\n\n<style>\n  .cta-row {\n    display: flex;\n    gap: 16px;\n    justify-content: center;\n    flex-wrap: wrap;\n  }\n\n  @media (max-width: 640px) {\n    .hero-card {\n      padding: 32px 16px !important;\n    }\n    \n    .cta-row {\n      flex-direction: column;\n      gap: 12px;\n    }\n    \n    .hero-card h1 {\n      font-size: 24px !important;\n    }\n  }\n</style>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>About Us</h1>\n    <p class=\"muted\">A community-driven showcase for the best Minecraft mods, resource packs, datapacks, modpacks, and plugins.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>Our Mission</h2>\n  <p class=\"muted\">To provide an organized, beautiful, and accessible platform for discovering and showcasing high-quality Minecraft content.</p>\n  \n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-bullseye\"></i> Curated Collection</h3>\n      <p>We handpick projects from the Modrinth ecosystem, ensuring quality and relevance for our community.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-users\"></i> Community Focused</h3>\n      <p>Built by and for the Minecraft community. Your feedback and contributions shape our platform.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-code\"></i> Open Source</h3>\n      <p>Completely open-source and transparent. Fork, modify, and contribute on GitHub.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-bolt\"></i> Fast & Reliable</h3>\n      <p>Static site hosted on GitHub Pages. Zero downtime, global CDN, instant loading.</p>\n    </div>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>How It Works</h2>\n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-database\"></i> Live Data</h3>\n      <p>We sync project data daily from Modrinth, keeping our showcase fresh and up-to-date with the latest versions and downloads.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-filter\"></i> Smart Filtering</h3>\n      <p>Filter projects by type, loader, and game version. Find exactly what you're looking for in seconds.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-chart-line\"></i> Statistics</h3>\n      <p>Real-time statistics show total downloads, supported versions, popular categories, and trending projects.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-link\"></i> Direct Links</h3>\n      <p>Every project links directly to Modrinth, ensuring you always download from the official source.</p>\n    </div>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>Get Involved</h2>\n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3><i class=\"fa-brands fa-discord\"></i> Join Discord</h3>\n      <p class=\"muted\">Chat with our community, get support, and suggest improvements.</p>\n      {% if site.social.discord %}\n        <a class=\"btn primary\" href=\"{{ site.social.discord }}\" target=\"_blank\" rel=\"noopener\">Open Discord</a>\n      {% endif %}\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-brands fa-github\"></i> Contribute</h3>\n      <p class=\"muted\">Found a bug? Have an idea? Star and contribute to our repository.</p>\n      {% if site.social.github %}\n        <a class=\"btn ghost\" href=\"{{ site.social.github }}\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n      {% endif %}\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-heart\"></i> Support</h3>\n      <p class=\"muted\">Enjoying the platform? Follow our socials and spread the word!</p>\n      {% if site.social.twitter %}\n        <a class=\"btn ghost\" href=\"{{ site.social.twitter }}\" target=\"_blank\" rel=\"noopener\">Follow Twitter</a>\n      {% endif %}\n    </div>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>Our Values</h2>\n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3>Accessibility</h3>\n      <p>We believe everyone should have access to quality Minecraft content, regardless of technical skill or platform.</p>\n    </div>\n    <div class=\"card\">\n      <h3>Transparency</h3>\n      <p>Open source code, public data, and clear communication. We have nothing to hide.</p>\n    </div>\n    <div class=\"card\">\n      <h3>Community</h3>\n      <p>Built together, not for profit. We prioritize creator and player needs over monetization.</p>\n    </div>\n    <div class=\"card\">\n      <h3>Quality</h3>\n      <p>Every project showcased meets our standards for functionality, documentation, and community support.</p>\n    </div>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>Contact & Support</h2>\n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-envelope\"></i> Need Help?</h3>\n      <p class=\"muted\">Have questions? Check our documentation or reach out on Discord.</p>\n      <a class=\"btn primary\" href=\"{{ '/docs/' | relative_url }}\">Read Docs</a>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-bug\"></i> Found a Bug?</h3>\n      <p class=\"muted\">Report issues and suggest features on our GitHub repository.</p>\n      {% if site.social.github %}\n        <a class=\"btn primary\" href=\"{{ site.social.github }}/issues\" target=\"_blank\" rel=\"noopener\">Report Issue</a>\n      {% endif %}\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-handshake\"></i> Let's Collaborate</h3>\n      <p class=\"muted\">Interested in partnering or featuring your project? Let's talk!</p>\n      {% if site.social.discord %}\n        <a class=\"btn ghost\" href=\"{{ site.social.discord }}\" target=\"_blank\" rel=\"noopener\">Chat with Us</a>\n      {% endif %}\n    </div>\n  </div>\n</section>\n","<section class=\"section\">\n  <h1>Blog</h1>\n  <p class=\"muted\">Updates from the team — releases, dev logs, and tips.</p>\n\n  <div class=\"filters\" style=\"margin: 12px 0 20px; display:flex; gap:8px; flex-wrap:wrap;\">\n    {% assign all_tags = site.tags %}\n    {% for tag in all_tags %}\n      <a href=\"{{ '/blog/#' | append: tag[0] | relative_url }}\" style=\"padding:6px 10px; border:1px solid var(--border); border-radius:999px; text-decoration:none; color:var(--text-secondary);\">#{{ tag[0] }}</a>\n    {% endfor %}\n  </div>\n\n  <div class=\"filters\" style=\"margin: 0 0 24px; display:flex; gap:8px; flex-wrap:wrap;\">\n    {% assign all_categories = site.categories %}\n    {% for category in all_categories %}\n      <a href=\"{{ '/blog/#' | append: category[0] | relative_url }}\" style=\"padding:6px 10px; border:1px solid var(--border); border-radius:999px; text-decoration:none; color:var(--text-secondary);\">{{ category[0] }}</a>\n    {% endfor %}\n  </div>\n\n  <div class=\"post-list\" style=\"display: grid; gap: 16px;\">\n    {% assign posts = site.posts | where_exp: 'p', 'p.published != false' %}\n    {% for post in posts %}\n    <article style=\"border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; background: var(--bg-primary);\">\n      <h2 style=\"margin: 0;\">\n        <a href=\"{{ post.url | relative_url }}\" style=\"color: var(--text); text-decoration: none;\">{{ post.title }}</a>\n      </h2>\n      <p class=\"muted\" style=\"margin: 6px 0 12px;\">{{ post.date | date: \"%B %d, %Y\" }}{{ post.author | default: site.site.name }}</p>\n      {% if post.excerpt %}\n        <p style=\"margin: 0 0 8px;\">{{ post.excerpt }}</p>\n      {% endif %}\n      {% if post.tags %}\n        <div style=\"margin:8px 0;\">\n          {% for tag in post.tags %}\n            <span style=\"display:inline-block; padding: 4px 8px; border: 1px solid var(--border); border-radius: 999px; margin-right: 6px; font-size: 12px;\">#{{ tag }}</span>\n          {% endfor %}\n        </div>\n      {% endif %}\n      <a href=\"{{ post.url | relative_url }}\" class=\"button\" style=\"display:inline-block; padding: 8px 12px; background: var(--accent-primary); color: #000; border-radius: var(--radius); text-decoration: none;\">Read More</a>\n    </article>\n    {% endfor %}\n\n    {% if posts.size == 0 %}\n      <p class=\"muted\">No posts yet. Stay tuned!</p>\n    {% endif %}\n\n  </div>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Community & Contributing</h1>\n    <p class=\"muted\">Learn how to contribute to the ABC showcase and get involved.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px;\">\n    {% assign category_docs = site.docs | where: \"category\", \"Community\" %}\n    {% for doc in category_docs %}\n      <div class=\"card\">\n        <h3>{{ doc.title }}</h3>\n        <p class=\"muted\" style=\"font-size: 13px; margin-bottom: 12px;\">{{ doc.description }}</p>\n        <div style=\"display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;\">\n          {% for tag in doc.tags %}\n            <span style=\"display: inline-block; padding: 4px 8px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 4px; font-size: 12px;\">#{{ tag }}</span>\n          {% endfor %}\n        </div>\n        <a class=\"btn primary\" href=\"{{ doc.url | relative_url }}\" style=\"width: 100%; display: block; text-align: center;\">Read More</a>\n      </div>\n    {% endfor %}\n  </div>\n</section>\n\n<section class=\"section\">\n  <div style=\"text-align: center;\">\n    <p><a href=\"{{ '/docs/' | relative_url }}\">← Back to all documentation</a></p>\n  </div>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Developer Resources</h1>\n    <p class=\"muted\">Technical documentation, architecture, and API reference.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px;\">\n    {% assign category_docs = site.docs | where: \"category\", \"Developer\" %}\n    {% for doc in category_docs %}\n      <div class=\"card\">\n        <h3>{{ doc.title }}</h3>\n        <p class=\"muted\" style=\"font-size: 13px; margin-bottom: 12px;\">{{ doc.description }}</p>\n        <div style=\"display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;\">\n          {% for tag in doc.tags %}\n            <span style=\"display: inline-block; padding: 4px 8px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 4px; font-size: 12px;\">#{{ tag }}</span>\n          {% endfor %}\n        </div>\n        <a class=\"btn primary\" href=\"{{ doc.url | relative_url }}\" style=\"width: 100%; display: block; text-align: center;\">Read More</a>\n      </div>\n    {% endfor %}\n  </div>\n</section>\n\n<section class=\"section\">\n  <div style=\"text-align: center;\">\n    <p><a href=\"{{ '/docs/' | relative_url }}\">← Back to all documentation</a></p>\n  </div>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Help & Troubleshooting</h1>\n    <p class=\"muted\">Find answers to common questions and fix issues quickly.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px;\">\n    {% assign category_docs = site.docs | where: \"category\", \"Help\" %}\n    {% for doc in category_docs %}\n      <div class=\"card\">\n        <h3>{{ doc.title }}</h3>\n        <p class=\"muted\" style=\"font-size: 13px; margin-bottom: 12px;\">{{ doc.description }}</p>\n        <div style=\"display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;\">\n          {% for tag in doc.tags %}\n            <span style=\"display: inline-block; padding: 4px 8px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 4px; font-size: 12px;\">#{{ tag }}</span>\n          {% endfor %}\n        </div>\n        <a class=\"btn primary\" href=\"{{ doc.url | relative_url }}\" style=\"width: 100%; display: block; text-align: center;\">Read More</a>\n      </div>\n    {% endfor %}\n  </div>\n</section>\n\n<section class=\"section\">\n  <div style=\"text-align: center;\">\n    <p><a href=\"{{ '/docs/' | relative_url }}\">← Back to all documentation</a></p>\n  </div>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Setup & Configuration</h1>\n    <p class=\"muted\">Get the ABC showcase installed and configured for your needs.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px;\">\n    {% assign category_docs = site.docs | where: \"category\", \"Setup\" %}\n    {% for doc in category_docs %}\n      <div class=\"card\">\n        <h3>{{ doc.title }}</h3>\n        <p class=\"muted\" style=\"font-size: 13px; margin-bottom: 12px;\">{{ doc.description }}</p>\n        <div style=\"display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;\">\n          {% for tag in doc.tags %}\n            <span style=\"display: inline-block; padding: 4px 8px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 4px; font-size: 12px;\">#{{ tag }}</span>\n          {% endfor %}\n        </div>\n        <a class=\"btn primary\" href=\"{{ doc.url | relative_url }}\" style=\"width: 100%; display: block; text-align: center;\">Read More</a>\n      </div>\n    {% endfor %}\n  </div>\n</section>\n\n<section class=\"section\">\n  <div style=\"text-align: center;\">\n    <p><a href=\"{{ '/docs/' | relative_url }}\">← Back to all documentation</a></p>\n  </div>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Styling & Customization</h1>\n    <p class=\"muted\">Customize colors, themes, and appearance of your ABC showcase.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px;\">\n    {% assign category_docs = site.docs | where: \"category\", \"Styling\" %}\n    {% for doc in category_docs %}\n      <div class=\"card\">\n        <h3>{{ doc.title }}</h3>\n        <p class=\"muted\" style=\"font-size: 13px; margin-bottom: 12px;\">{{ doc.description }}</p>\n        <div style=\"display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;\">\n          {% for tag in doc.tags %}\n            <span style=\"display: inline-block; padding: 4px 8px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 4px; font-size: 12px;\">#{{ tag }}</span>\n          {% endfor %}\n        </div>\n        <a class=\"btn primary\" href=\"{{ doc.url | relative_url }}\" style=\"width: 100%; display: block; text-align: center;\">Read More</a>\n      </div>\n    {% endfor %}\n  </div>\n</section>\n\n<section class=\"section\">\n  <div style=\"text-align: center;\">\n    <p><a href=\"{{ '/docs/' | relative_url }}\">← Back to all documentation</a></p>\n  </div>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>User Guide</h1>\n    <p class=\"muted\">Everything you need to know as a user or project manager.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px;\">\n    {% assign category_docs = site.docs | where: \"category\", \"User Guide\" %}\n    {% for doc in category_docs %}\n      <div class=\"card\">\n        <h3>{{ doc.title }}</h3>\n        <p class=\"muted\" style=\"font-size: 13px; margin-bottom: 12px;\">{{ doc.description }}</p>\n        <div style=\"display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;\">\n          {% for tag in doc.tags %}\n            <span style=\"display: inline-block; padding: 4px 8px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 4px; font-size: 12px;\">#{{ tag }}</span>\n          {% endfor %}\n        </div>\n        <a class=\"btn primary\" href=\"{{ doc.url | relative_url }}\" style=\"width: 100%; display: block; text-align: center;\">Read More</a>\n      </div>\n    {% endfor %}\n  </div>\n</section>\n\n<section class=\"section\">\n  <div style=\"text-align: center;\">\n    <p><a href=\"{{ '/docs/' | relative_url }}\">← Back to all documentation</a></p>\n  </div>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <p class=\"muted\" style=\"margin-bottom: 6px; letter-spacing: 0.5px; text-transform: uppercase; font-size: 12px;\">Releases</p>\n    <h1>Changelog</h1>\n    <p class=\"muted\">Track the freshest updates across ABC mods, modpacks, resource packs, and datapacks.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div style=\"display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 16px;\">\n    <div style=\"display: flex; gap: 10px; align-items: center;\">\n      <i class=\"fa-solid fa-rocket\" style=\"color: var(--accent-primary);\"></i>\n      <p class=\"muted\" style=\"margin: 0;\">Sorted by latest update time</p>\n    </div>\n    <div id=\"changelog-count\" class=\"muted\" style=\"font-size: 14px;\"></div>\n  </div>\n\n  <div id=\"changelog-list\" class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px;\"></div>\n  <div id=\"changelog-empty\" class=\"muted\" style=\"display: none; text-align: center; margin: 24px 0;\">No releases found yet. Add entries to <code>data/mods.json</code> or <code>data/modpacks.json</code>.</div>\n</section>\n\n<script>\n  document.addEventListener('DOMContentLoaded', () => {\n    const listEl = document.getElementById('changelog-list');\n    const countEl = document.getElementById('changelog-count');\n    const emptyEl = document.getElementById('changelog-empty');\n\n    function formatDate(value) {\n      if (!value) return 'N/A';\n      const date = new Date(value);\n      return isNaN(date.getTime()) ? 'N/A' : date.toLocaleDateString();\n    }\n\n    function renderCard(item) {\n      const versions = (item.game_versions || []).slice(0, 4).map(v => `<span class=\"version-badge\">${v}</span>`).join('');\n      const categories = (item.categories || []).slice(0, 3).map(cat => `<span class=\"category-pill\">${cat}</span>`).join('');\n      const updated = formatDate(item.updated || item.date_modified || item.published);\n      const typeLabel = (item.project_type || item.type || 'mod').replace(/_/g, ' ');\n\n      return `\n        <article class=\"card\">\n          <div style=\"display:flex;align-items:center;gap:12px;\">\n            ${item.icon_url ? `<img src=\"${item.icon_url}\" alt=\"${item.name}\" style=\"width:48px;height:48px;border-radius:12px;border:1px solid var(--border);object-fit:cover;\" />` : '<div style=\"width:48px;height:48px;border-radius:12px;border:1px dashed var(--border);\"></div>'}\n            <div>\n              <p class=\"muted\" style=\"margin:0;font-size:12px;text-transform:uppercase;letter-spacing:0.6px;\">${typeLabel}</p>\n              <h3 style=\"margin:4px 0 0;\">${item.title || item.name}</h3>\n            </div>\n          </div>\n          <p class=\"muted\" style=\"margin: 4px 0 0;\">${item.short_description || item.description || 'No description available.'}</p>\n          <div style=\"display:flex;gap:8px;flex-wrap:wrap;align-items:center;\">\n            ${versions || '<span class=\"version-badge\">All versions</span>'}\n          </div>\n          <div style=\"display:flex;gap:10px;flex-wrap:wrap;align-items:center;\">\n            ${categories}\n          </div>\n          <div style=\"display:flex;gap:12px;flex-wrap:wrap;font-size:13px;color:var(--text-muted);\">\n            <span><i class=\"fa-regular fa-clock\"></i> Updated ${updated}</span>\n            <span><i class=\"fa-solid fa-download\"></i> ${(item.downloads || 0).toLocaleString()} downloads</span>\n            <span><i class=\"fa-solid fa-users\"></i> ${(item.followers || 0).toLocaleString()} followers</span>\n          </div>\n          <div style=\"display:flex;gap:8px;flex-wrap:wrap;\">\n            ${item.download ? `<a class=\"btn ghost\" href=\"${item.download}\" target=\"_blank\"><i class=\"fa-solid fa-arrow-up-right-from-square\"></i> View Project</a>` : ''}\n            ${item.source_url ? `<a class=\"btn ghost\" href=\"${item.source_url}\" target=\"_blank\"><i class=\"fa-brands fa-github\"></i> Source</a>` : ''}\n          </div>\n        </article>\n      `;\n    }\n\n    async function fetchJson(url) {\n      try {\n        const res = await fetch(url);\n        if (!res.ok) throw new Error(`Request failed: ${res.status}`);\n        return await res.json();\n      } catch (err) {\n        console.warn('Changelog fetch failed', err);\n        return [];\n      }\n    }\n\n    async function loadChangelog() {\n      const [mods, modpacks] = await Promise.all([\n        fetchJson('{{ '/data/mods.json' | relative_url }}'),\n        fetchJson('{{ '/data/modpacks.json' | relative_url }}')\n      ]);\n\n      const items = [...mods, ...modpacks].map(item => ({\n        ...item,\n        updated: item.updated || item.date_modified || item.published || null,\n      })).filter(item => item);\n\n      if (!items.length) {\n        emptyEl.style.display = 'block';\n        countEl.textContent = '';\n        return;\n      }\n\n      items.sort((a, b) => {\n        const dateA = new Date(a.updated || 0).getTime();\n        const dateB = new Date(b.updated || 0).getTime();\n        return dateB - dateA;\n      });\n\n      listEl.innerHTML = items.map(renderCard).join('');\n      countEl.textContent = `${items.length} releases`;\n    }\n\n    loadChangelog();\n  });\n</script>\n","<div class=\"hero\" style=\"background-image: url('{{ '/assets/images/blocks.svg' | relative_url }}'); background-size: cover; background-position: center; min-height: 120px; padding: 0.5rem 0 !important;\">\n  <div class=\"hero-content\">\n    <h1 class=\"hero-title fade-in\">Compare Modpacks</h1>\n    <p class=\"hero-description fade-in-up\">Compare features, performance, and content across modpacks</p>\n  </div>\n</div>\n\n<div class=\"comparison-container\">\n  <div class=\"comparison-header\">\n    <h2>Select Modpacks to Compare</h2>\n    <p>Choose up to 3 modpacks to compare side-by-side</p>\n  </div>\n\n  <div class=\"comparison-selector\">\n    <div class=\"selector-box\">\n      <label for=\"compare-1\">Modpack 1</label>\n      <select id=\"compare-1\" class=\"modpack-select\">\n        <option value=\"\">Select a modpack...</option>\n      </select>\n    </div>\n    <div class=\"selector-box\">\n      <label for=\"compare-2\">Modpack 2</label>\n      <select id=\"compare-2\" class=\"modpack-select\">\n        <option value=\"\">Select a modpack...</option>\n      </select>\n    </div>\n    <div class=\"selector-box\">\n      <label for=\"compare-3\">Modpack 3</label>\n      <select id=\"compare-3\" class=\"modpack-select\">\n        <option value=\"\">Select a modpack...</option>\n      </select>\n    </div>\n  </div>\n\n  <div class=\"comparison-actions\">\n    <button id=\"compare-btn\" class=\"btn btn-primary\" disabled>\n      <i class=\"fas fa-balance-scale\"></i> Compare Selected\n    </button>\n    <button id=\"clear-btn\" class=\"btn btn-secondary\">\n      <i class=\"fas fa-times\"></i> Clear All\n    </button>\n  </div>\n\n  <div id=\"comparison-results\" class=\"comparison-results hidden\">\n    <div class=\"comparison-table-wrapper\">\n      <table class=\"comparison-table\">\n        <thead>\n          <tr>\n            <th class=\"feature-col\">Feature</th>\n            <th class=\"modpack-col\" id=\"header-1\"></th>\n            <th class=\"modpack-col\" id=\"header-2\"></th>\n            <th class=\"modpack-col\" id=\"header-3\"></th>\n          </tr>\n        </thead>\n        <tbody>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-image\"></i> Icon</td>\n            <td id=\"icon-1\"></td>\n            <td id=\"icon-2\"></td>\n            <td id=\"icon-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-layer-group\"></i> Type</td>\n            <td id=\"type-1\"></td>\n            <td id=\"type-2\"></td>\n            <td id=\"type-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-info-circle\"></i> Description</td>\n            <td id=\"description-1\"></td>\n            <td id=\"description-2\"></td>\n            <td id=\"description-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-gamepad\"></i> Supported MC Versions</td>\n            <td id=\"version-1\"></td>\n            <td id=\"version-2\"></td>\n            <td id=\"version-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-download\"></i> Downloads</td>\n            <td id=\"downloads-1\"></td>\n            <td id=\"downloads-2\"></td>\n            <td id=\"downloads-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-users\"></i> Followers</td>\n            <td id=\"followers-1\"></td>\n            <td id=\"followers-2\"></td>\n            <td id=\"followers-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-calendar\"></i> Last Updated</td>\n            <td id=\"updated-1\"></td>\n            <td id=\"updated-2\"></td>\n            <td id=\"updated-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-tag\"></i> Categories</td>\n            <td id=\"categories-1\"></td>\n            <td id=\"categories-2\"></td>\n            <td id=\"categories-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-link\"></i> Links</td>\n            <td id=\"links-1\"></td>\n            <td id=\"links-2\"></td>\n            <td id=\"links-3\"></td>\n          </tr>\n        </tbody>\n      </table>\n    </div>\n  </div>\n</div>\n\n<style>\n.comparison-container {\n  max-width: 1400px;\n  margin: 3rem auto;\n  padding: 0 1rem;\n}\n\n.comparison-header {\n  text-align: center;\n  margin-bottom: 2rem;\n}\n\n.comparison-header h2 {\n  font-size: 2rem;\n  margin-bottom: 0.5rem;\n}\n\n.comparison-header p {\n  color: var(--text-muted);\n}\n\n.comparison-selector {\n  display: grid;\n  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n  gap: 1.5rem;\n  margin-bottom: 2rem;\n}\n\n.selector-box {\n  display: flex;\n  flex-direction: column;\n  gap: 0.5rem;\n}\n\n.selector-box label {\n  font-weight: 600;\n  color: var(--text);\n}\n\n.modpack-select {\n  padding: 0.75rem;\n  border: 2px solid var(--border);\n  border-radius: 8px;\n  background: var(--bg);\n  color: var(--text);\n  font-size: 1rem;\n  cursor: pointer;\n  transition: all 0.2s;\n}\n\n.modpack-select:hover {\n  border-color: var(--accent);\n}\n\n.modpack-select:focus {\n  outline: none;\n  border-color: var(--accent);\n  box-shadow: 0 0 0 3px rgba(0, 255, 157, 0.1);\n}\n\n.comparison-actions {\n  display: flex;\n  gap: 1rem;\n  justify-content: center;\n  margin-bottom: 3rem;\n}\n\n.btn {\n  padding: 0.75rem 1.5rem;\n  border: none;\n  border-radius: 8px;\n  font-size: 1rem;\n  font-weight: 600;\n  cursor: pointer;\n  transition: all 0.2s;\n  display: inline-flex;\n  align-items: center;\n  gap: 0.5rem;\n}\n\n.btn-primary {\n  background: var(--accent);\n  color: var(--bg);\n}\n\n.btn-primary:hover:not(:disabled) {\n  background: var(--accent-hover);\n  transform: translateY(-2px);\n  box-shadow: 0 4px 12px rgba(0, 255, 157, 0.3);\n}\n\n.btn-primary:disabled {\n  opacity: 0.5;\n  cursor: not-allowed;\n}\n\n.btn-secondary {\n  background: var(--bg-secondary);\n  color: var(--text);\n  border: 2px solid var(--border);\n}\n\n.btn-secondary:hover {\n  background: var(--bg-tertiary);\n  border-color: var(--text-muted);\n}\n\n.comparison-results {\n  opacity: 1;\n  transition: opacity 0.3s;\n}\n\n.comparison-results.hidden {\n  display: none;\n  opacity: 0;\n}\n\n.comparison-table-wrapper {\n  overflow-x: auto;\n  border-radius: 12px;\n  border: 2px solid var(--border);\n}\n\n.comparison-table {\n  width: 100%;\n  border-collapse: collapse;\n  background: var(--bg);\n}\n\n.comparison-table thead {\n  background: var(--bg-secondary);\n  position: sticky;\n  top: 0;\n  z-index: 10;\n}\n\n.comparison-table th,\n.comparison-table td {\n  padding: 1rem;\n  text-align: left;\n  border-bottom: 1px solid var(--border);\n}\n\n.comparison-table th {\n  font-weight: 700;\n  color: var(--text);\n}\n\n.feature-col {\n  width: 200px;\n  font-weight: 600;\n  background: var(--bg-secondary);\n  position: sticky;\n  left: 0;\n  z-index: 5;\n}\n\n.feature-name {\n  font-weight: 600;\n  background: var(--bg-secondary);\n  position: sticky;\n  left: 0;\n  z-index: 5;\n}\n\n.feature-name i {\n  margin-right: 0.5rem;\n  color: var(--accent);\n}\n\n.modpack-col {\n  min-width: 250px;\n}\n\n.comparison-table tbody tr:hover {\n  background: var(--bg-tertiary);\n}\n\n.modpack-icon {\n  width: 64px;\n  height: 64px;\n  border-radius: 8px;\n  object-fit: cover;\n}\n\n.category-pill {\n  display: inline-block;\n  padding: 0.25rem 0.75rem;\n  background: var(--accent);\n  color: var(--bg);\n  border-radius: 999px;\n  font-size: 0.875rem;\n  margin: 0.25rem;\n}\n\n.link-button {\n  display: inline-flex;\n  align-items: center;\n  gap: 0.5rem;\n  padding: 0.5rem 1rem;\n  background: var(--accent);\n  color: var(--bg);\n  text-decoration: none;\n  border-radius: 8px;\n  margin: 0.25rem;\n  transition: all 0.2s;\n}\n\n.link-button:hover {\n  background: var(--accent-hover);\n  transform: translateY(-2px);\n}\n\n@media (max-width: 768px) {\n  .comparison-selector {\n    grid-template-columns: 1fr;\n  }\n  \n  .comparison-actions {\n    flex-direction: column;\n  }\n  \n  .btn {\n    width: 100%;\n  }\n  \n  .feature-col,\n  .feature-name {\n    position: static;\n  }\n}\n</style>\n\n<script>\n// Populate selects with any content type\nconst modpacksData = {{ site.data.modpacks | default: \"[]\" | jsonify }};\nconst modsData = {{ site.data.mods | default: \"[]\" | jsonify }};\n\n// Normalize datasets and merge\nfunction parseData(raw, fallbackType) {\n  const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw || [];\n  return Array.isArray(parsed)\n    ? parsed.map((item) => ({\n        ...item,\n        content_type: item.type || item.project_type || fallbackType,\n      }))\n    : [];\n}\n\nconst items = [\n  ...parseData(modpacksData, 'modpack'),\n  ...parseData(modsData, 'mod'),\n];\n\nconst selects = ['compare-1', 'compare-2', 'compare-3'];\n\nif (Array.isArray(items) && items.length > 0) {\n  selects.forEach((selectId) => {\n    const select = document.getElementById(selectId);\n    items.forEach((item) => {\n      const option = document.createElement('option');\n      option.value = item.id;\n      const typeLabel = (item.content_type || 'modpack').replace(/_/g, ' ');\n      option.textContent = `${item.name} (${typeLabel})`;\n      select.appendChild(option);\n    });\n  });\n} else {\n  // Show message if no content available\n  document.querySelector('.comparison-selector').innerHTML =\n    '<p style=\"text-align:center;color:var(--text-muted);padding:2rem;\">No content available for comparison. Add data to _data/modpacks.json or _data/mods.json to enable this feature.</p>';\n  document.querySelector('.comparison-actions').style.display = 'none';\n}\n\n// Enable/disable compare button (guard if DOM missing)\nfunction updateCompareButton() {\n  const compareBtn = document.getElementById('compare-btn');\n  if (!compareBtn) return;\n  const selected = selects\n    .map(id => document.getElementById(id))\n    .filter(Boolean)\n    .map(el => el.value)\n    .filter(Boolean);\n  compareBtn.disabled = selected.length < 2;\n}\n\nselects.forEach(id => {\n  const el = document.getElementById(id);\n  if (el) el.addEventListener('change', updateCompareButton);\n});\n\nconst compareBtnEl = document.getElementById('compare-btn');\nconst clearBtnEl = document.getElementById('clear-btn');\n\n// Compare functionality\ncompareBtnEl?.addEventListener('click', () => {\n  const selectedIds = selects\n    .map(id => document.getElementById(id))\n    .filter(Boolean)\n    .map(el => el.value)\n    .filter(Boolean);\n  const selectedItems = selectedIds\n    .map(id => items.find(m => m.id === id))\n    .filter(Boolean);\n  \n  // Populate table\n  selectedItems.forEach((item, index) => {\n    const col = index + 1;\n    const typeLabel = (item.content_type || 'modpack').replace(/_/g, ' ');\n    \n    // Header\n    document.getElementById(`header-${col}`).innerHTML = `<strong>${item.name}</strong>`;\n    \n    // Icon\n    document.getElementById(`icon-${col}`).innerHTML = \n      item.icon_url ? `<img src=\"${item.icon_url}\" alt=\"${item.name}\" class=\"modpack-icon\">` : 'N/A';\n\n    // Type\n    document.getElementById(`type-${col}`).textContent = typeLabel;\n    \n    // Description\n    document.getElementById(`description-${col}`).textContent = item.short_description || item.description || 'N/A';\n    \n    // Versions\n    const versionBadges = (item.game_versions || []).slice(0, 4).map(v => `<span class=\"version-badge\">${v}</span>`).join('');\n    document.getElementById(`version-${col}`).innerHTML = versionBadges || 'N/A';\n    \n    // Downloads\n    document.getElementById(`downloads-${col}`).innerHTML = \n      `<strong>${(item.downloads || 0).toLocaleString()}</strong>`;\n    \n    // Followers\n    document.getElementById(`followers-${col}`).innerHTML = \n      `<strong>${(item.followers || 0).toLocaleString()}</strong>`;\n    \n    // Updated\n    const date = item.date_modified || item.updated;\n    const dateText = date ? new Date(date).toLocaleDateString() : 'N/A';\n    document.getElementById(`updated-${col}`).textContent = dateText;\n    \n    // Categories\n    const categories = (item.categories || []).map(cat => \n      `<span class=\"category-pill\">${cat}</span>`\n    ).join('');\n    document.getElementById(`categories-${col}`).innerHTML = categories || 'N/A';\n    \n    // Links\n    const links = [\n      item.project_url || item.download ? `<a href=\"${item.project_url || item.download}\" class=\"link-button\" target=\"_blank\"><i class=\"fas fa-external-link-alt\"></i> View Project</a>` : '',\n      item.source_url ? `<a href=\"${item.source_url}\" class=\"link-button\" target=\"_blank\"><i class=\"fab fa-github\"></i> Source</a>` : ''\n    ].filter(l => l).join('');\n    document.getElementById(`links-${col}`).innerHTML = links || 'N/A';\n  });\n  \n  // Clear remaining columns\n  for (let i = selectedItems.length + 1; i <= 3; i++) {\n    document.getElementById(`header-${i}`).innerHTML = '';\n    ['icon', 'description', 'version', 'downloads', 'followers', 'updated', 'categories', 'links'].forEach(field => {\n      document.getElementById(`${field}-${i}`).innerHTML = '';\n    });\n  }\n  \n  // Show results with animation\n  const results = document.getElementById('comparison-results');\n  results.classList.remove('hidden');\n  setTimeout(() => results.style.opacity = '1', 10);\n  \n  // Scroll to results\n  results.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\ndocument.getElementById('clear-btn').addEventListener('click', () => {\n});\n\n// Clear functionality\nclearBtnEl?.addEventListener('click', () => {\n  selects.forEach(id => {\n    const el = document.getElementById(id);\n    if (el) el.value = '';\n  });\n  updateCompareButton();\n  const results = document.getElementById('comparison-results');\n  if (results) results.classList.add('hidden');\n});\n</script>\n","<section class=\"section\">\n  <h1>Contact & Support</h1>\n  <p class=\"muted\">Reach out for issues, feedback, or collaboration.</p>\n\n  <h2>Fastest ways</h2>\n  <ul>\n    <li>Discord: <a href=\"{{ site.social.discord }}\" target=\"_blank\" rel=\"noopener\">Join our server</a></li>\n    <li>GitHub: <a href=\"{{ site.social.github }}\" target=\"_blank\" rel=\"noopener\">Open an issue</a> on our repos</li>\n  </ul>\n\n  <h2>Feedback</h2>\n  <p>Use the \"Was this helpful?\" widget on docs pages for quick feedback. For broader requests, ping us on Discord.</p>\n</section>\n","# Cookie Policy\n\n**Last Updated:** December 2024\n\nWe use cookies and similar tracking technologies to enhance your experience on our site. This policy explains what cookies are, how we use them, and your rights regarding them.\n\n## What Are Cookies?\n\nCookies are small text files stored on your browser or device that help websites remember information about your visits. They can be:\n\n- **Session cookies**: Deleted when you close your browser\n- **Persistent cookies**: Remain on your device for a set period\n- **First-party cookies**: Set by our domain\n- **Third-party cookies**: Set by external services (analytics, ads, etc.)\n\n## Cookies We Use\n\n### Analytics\n\nWe use Google Analytics to understand how visitors use our site:\n\n- `_ga` – Identifies unique visitors\n- `_ga_*` – Tracks sessions and page views\n- `_gat` – Throttles request rate\n\n**Purpose**: Analyzing site traffic and user behavior  \n**Retention**: 2 years\n\n### Functional Cookies\n\n- `theme` – Remembers your color theme preference\n- `language` – Stores your preferred language\n\n**Purpose**: Improving site usability  \n**Retention**: 1 year\n\n### Consent Management\n\n- `cookie_consent` – Stores your cookie preferences\n- `cookie_consent_timestamp` – Records when consent was given\n\n**Purpose**: Respecting your privacy choices  \n**Retention**: 1 year\n\n## Third-Party Services\n\nWe may use services that set their own cookies:\n\n| Service          | Cookies         | Purpose        | Policy                                                |\n| ---------------- | --------------- | -------------- | ----------------------------------------------------- |\n| Google Analytics | `_ga*`, `_gat`  | Site analytics | [Privacy Policy](https://policies.google.com/privacy) |\n| Font Awesome     | Session cookies | Icon delivery  | [Privacy](https://fontawesome.com/privacy)            |\n| Discord          | If embedded     | Embeds/widgets | [Privacy](https://discord.com/privacy)                |\n\n## Cookie Preferences\n\nYou can manage your cookie preferences using our cookie consent banner at the bottom of the page. You can:\n\n- Accept all cookies\n- Reject non-essential cookies\n- Customize preferences\n\n### Browser Controls\n\nMost browsers allow you to:\n\n- Block cookies entirely\n- Clear cookies on exit\n- View stored cookies\n- Opt-out of tracking\n\n**Note**: Blocking essential cookies may affect site functionality.\n\n## Your Rights\n\nUnder GDPR and similar privacy laws, you have the right to:\n\n- Know what cookies are used\n- Opt-out of non-essential cookies\n- Request deletion of your data\n- Access or port your data\n\n## Contact\n\nIf you have questions about our cookie practices:\n\n**Email**: [contact information from site config]\n\nWe will respond within 30 days.\n\n## Changes\n\nWe may update this policy periodically. Your continued use of the site constitutes acceptance of any changes.\n\n---\n\n_This Cookie Policy is part of our overall Privacy Policy and Terms of Service._\n","<section class=\"section\">\n  <h1>Disclaimer & Liability Waiver</h1>\n  <p class=\"muted\">Last updated: December 11, 2025</p>\n\n  <p>This page contains important disclaimers and limitations of liability. Please read carefully before using our website and projects.</p>\n\n  <h2>1. Website & Content Disclaimer</h2>\n\n  <h3>1.1 \"As Is\" Provision</h3>\n  <p>Our website and all materials are provided \"AS IS\" and \"AS AVAILABLE\" without warranties of any kind, either express or implied. We make no warranties regarding:</p>\n  <ul>\n    <li>Accuracy, completeness, or timeliness of information</li>\n    <li>Fitness for a particular purpose</li>\n    <li>Functionality or performance</li>\n    <li>Non-infringement of rights</li>\n    <li>Quality or reliability</li>\n  </ul>\n\n  <h3>1.2 No Professional Advice</h3>\n  <p>Content on our site is for informational purposes only and does not constitute:</p>\n  <ul>\n    <li>Legal advice</li>\n    <li>Technical support (though we'll help if we can)</li>\n    <li>Professional consulting</li>\n    <li>Warranty or guarantee</li>\n  </ul>\n  <p>Always consult appropriate professionals for critical decisions.</p>\n\n  <h2>2. Minecraft Project Disclaimer</h2>\n\n  <h3>2.1 No Warranty for Mods/Datapacks/Plugins</h3>\n  <p>All our Minecraft projects are provided \"AS IS\" without any warranty. We do not guarantee:</p>\n  <ul>\n    <li>The mod will work with your specific Minecraft version</li>\n    <li>The mod will work with other mods you have installed (compatibility)</li>\n    <li>The mod won't cause crashes or performance issues</li>\n    <li>The mod won't corrupt your world or save files</li>\n    <li>The mod will continue to be maintained or updated</li>\n    <li>The mod is free of bugs or issues</li>\n  </ul>\n\n  <h3>2.2 Save File Loss</h3>\n  <p><strong>YOU ARE RESPONSIBLE FOR BACKING UP YOUR MINECRAFT WORLDS AND SAVES.</strong></p>\n  <ul>\n    <li>Always backup important worlds before installing mods</li>\n    <li>Test mods in a separate test world first</li>\n    <li>Keep multiple backups of valuable worlds</li>\n    <li>We are NOT liable for corrupted, lost, or deleted save files</li>\n  </ul>\n\n  <h3>2.3 Crashes & Compatibility</h3>\n  <ul>\n    <li>Mod conflicts, crashes, and performance issues are common in modded Minecraft</li>\n    <li>We provide projects \"as is\" without technical support guarantee</li>\n    <li>We'll do our best to help troubleshoot but cannot guarantee solutions</li>\n    <li>Some issues may require reinstalling Java, Minecraft, or removing conflicting mods</li>\n  </ul>\n\n  <h2>3. Limitation of Liability</h2>\n\n  <h3>3.1 No Liability For</h3>\n  <p><strong>In no event shall ABC, its owners, employees, contributors, or partners be liable for:</strong></p>\n  <ul>\n    <li>Lost or corrupted Minecraft save files or worlds</li>\n    <li>Game crashes, performance degradation, or lag</li>\n    <li>System damage or instability caused by our projects</li>\n    <li>Loss of income, profits, or business opportunities</li>\n    <li>Loss of data or information (in any form)</li>\n    <li>Any indirect, incidental, special, consequential, or punitive damages</li>\n    <li>Damages arising from your use or inability to use our site/projects</li>\n    <li>Issues caused by other mods or software on your system</li>\n    <li>Your failure to backup important data</li>\n    <li>Time or inconvenience</li>\n  </ul>\n  <p>This applies even if we have been advised of the possibility of such damages.</p>\n\n  <h3>3.2 Damages Cap</h3>\n  <p>If any court overrides the above disclaimer, our total liability is limited to <strong>zero dollars</strong> ($0). We are providing these projects for free.</p>\n\n  <h2>4. Assumption of Risk</h2>\n\n  <p>By using our website and projects, you acknowledge and assume all risks associated with:</p>\n  <ul>\n    <li>Installing and using mods/datapacks/plugins</li>\n    <li>Potential loss of save files or worlds</li>\n    <li>Game crashes or instability</li>\n    <li>Compatibility issues with your setup</li>\n    <li>System performance changes</li>\n    <li>Following installation instructions incorrectly</li>\n    <li>Running outdated Java or Minecraft versions</li>\n    <li>Conflicts with other mods or software</li>\n  </ul>\n\n  <h2>5. User Responsibility</h2>\n\n  <p>You are responsible for:</p>\n  <ul>\n    <li>✓ Reading and understanding installation instructions</li>\n    <li>✓ Keeping your Minecraft and Java updated</li>\n    <li>✓ Backing up your worlds and save files regularly</li>\n    <li>✓ Testing mods in a test world first</li>\n    <li>✓ Managing your system and mod installations</li>\n    <li>✓ Removing conflicting mods if issues arise</li>\n    <li>✓ Reporting issues accurately and completely</li>\n    <li>✓ Following applicable laws and terms (EULA, etc.)</li>\n  </ul>\n\n  <h2>6. Third-Party Services Disclaimer</h2>\n\n  <p>Our website uses third-party services and links:</p>\n  <ul>\n    <li><strong>Modrinth:</strong> We are not responsible for content, quality, or policies</li>\n    <li><strong>GitHub:</strong> External service; we don't control availability or policies</li>\n    <li><strong>Discord:</strong> Community platform; moderation is best-effort</li>\n    <li><strong>Google Analytics:</strong> Data collection per their privacy policy</li>\n  </ul>\n  <p>Review each service's terms and privacy policy before using.</p>\n\n  <h2>7. Availability Disclaimer</h2>\n\n  <ul>\n    <li>We do not guarantee continuous service availability</li>\n    <li>The website may be offline for maintenance without notice</li>\n    <li>Projects may be discontinued or archived</li>\n    <li>Downloads from third-party sites may become unavailable</li>\n    <li>We are not liable for service interruptions or data loss</li>\n  </ul>\n\n  <h2>8. Accuracy Disclaimer</h2>\n\n  <ul>\n    <li>We strive for accuracy but do not guarantee all information is correct</li>\n    <li>Documentation may become outdated</li>\n    <li>Minecraft updates may change how our projects work</li>\n    <li>We are not liable for decisions based on incorrect information</li>\n    <li>Always verify critical information independently</li>\n  </ul>\n\n  <h2>9. Health & Safety Disclaimer</h2>\n\n  <p>Using computers for extended periods can cause:</p>\n  <ul>\n    <li>Eye strain</li>\n    <li>Repetitive stress injuries (RSI)</li>\n    <li>Sleep disruption</li>\n    <li>Posture problems</li>\n  </ul>\n  <p>Take regular breaks, maintain good posture, and consult a doctor if experiencing discomfort.</p>\n\n  <h2>10. Indemnification</h2>\n\n  <p>You agree to indemnify and hold harmless ABC and its representatives from any claims, damages, or losses arising from:</p>\n  <ul>\n    <li>Your use of our site or projects</li>\n    <li>Violation of these disclaimers or our Terms</li>\n    <li>Your violation of any laws or third-party rights</li>\n    <li>Your content or actions</li>\n  </ul>\n\n  <h2>11. Questions or Concerns?</h2>\n\n  <p>If you don't agree with these disclaimers or have concerns:</p>\n  <ul>\n    <li>Do not use our site or projects</li>\n    <li><a href=\"{{ '/contact/' | relative_url }}\">Contact us</a> with specific concerns</li>\n  </ul>\n\n  <hr style=\"margin: 32px 0; border: none; border-top: 1px solid var(--border);\">\n\n  <p class=\"muted\" style=\"font-size: 12px;\">\n    <strong>Bottom Line:</strong> Our projects are free. Use at your own risk. Backup your saves. Test before using on important worlds. We're not responsible for any damages. Questions? Ask us.\n  </p>\n</section>\n","If you are not redirected automatically, join here: {{ site.social.discord }}\n","# End User License Agreement (EULA)\n\n**Last Updated:** December 2024\n\nThis End User License Agreement (\"EULA\") is a legal agreement between you and ABC Team governing your use of our projects, mods, datapacks, plugins, and related software (\"Software\").\n\n## 1. Grant of License\n\nWe grant you a non-exclusive, non-transferable, limited license to use the Software for personal, non-commercial purposes, subject to the terms of this agreement.\n\n### Permitted Uses\n\n✅ Install and use on your personal devices  \n✅ Create content using the Software (videos, streams, guides)  \n✅ Modify the Software for personal use  \n✅ Use in private multiplayer servers\n\n### Prohibited Uses\n\n❌ Commercial redistribution without permission  \n❌ Reselling modified versions  \n❌ Claiming ownership of the Software  \n❌ Reverse engineering for competitive purposes  \n❌ Removing attribution or license notices\n\n## 2. Intellectual Property Rights\n\nAll Software, including code, assets, textures, and designs, are owned by ABC Team or our contributors. You may not claim ownership or use the Software outside the scope of this license.\n\n### Attribution\n\nWhen using or referencing the Software, you agree to:\n\n- Maintain original credits\n- Link to our GitHub or website\n- Not remove license files\n- Acknowledge ABC Team as creators\n\n## 3. Modifications\n\nYou may modify the Software for personal use. However:\n\n- Modified versions cannot be redistributed commercially\n- You must maintain original licenses and credits\n- We are not responsible for issues caused by your modifications\n- Private use of mods is always permitted\n\n## 4. Server Usage\n\nYou may:\n\n- Run the Software on private servers\n- Run on public servers (community/multiplayer)\n- Accept donations (but not force payment)\n\nYou must:\n\n- Display credits/links in server descriptions\n- Not claim the Software as your own creation\n- Not charge for access to unmodified Software\n\n## 5. Content & Creator Policy\n\n**Streaming & YouTube**: Fully allowed. No permission required.\n\n**Monetization**: You may monetize content featuring the Software (ads, sponsorships, Patreon). You do not owe us revenue share.\n\n**Attribution**: Simply crediting \"ABC Team\" or linking to our GitHub is appreciated but not required.\n\n## 6. Warranty Disclaimer\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.\n\nWe do not warrant that:\n\n- The Software will meet your requirements\n- The Software will be error-free or bug-free\n- The Software will be compatible with all platforms\n- Updates will be provided\n\n## 7. Limitation of Liability\n\nTO THE MAXIMUM EXTENT PERMITTED BY LAW, WE SHALL NOT BE LIABLE FOR:\n\n- Data loss or corruption\n- Loss of profit or revenue\n- Interruption of service\n- Any indirect, incidental, or consequential damages\n\nEven if we have been advised of the possibility of such damages.\n\n## 8. Termination\n\nWe may terminate this license if you:\n\n- Violate any terms of this EULA\n- Use the Software for illegal purposes\n- Redistribute the Software commercially without permission\n- Harass or abuse our team\n\nUpon termination, you must cease using the Software.\n\n## 9. Third-Party Components\n\nThe Software may include third-party libraries or assets. You acknowledge and agree to comply with their respective licenses, which are listed in the project repository.\n\n## 10. Governing Law\n\nThis EULA is governed by and construed in accordance with applicable laws. Any disputes shall be resolved through negotiation or mediation.\n\n## 11. Changes to This EULA\n\nWe may update this EULA at any time. Continued use of the Software constitutes acceptance of changes. We recommend reviewing this EULA periodically.\n\n## 12. Contact\n\nIf you have questions about this EULA:\n\n**GitHub**: [Link from site config]  \n**Discord**: [Link from site config]\n\n---\n\n**By installing or using this Software, you acknowledge that you have read, understood, and agree to be bound by the terms of this EULA.**\n\nLast Updated: December 2024\n","{% assign t = site.data[page.lang] %}\n\n<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>{{ t.hero_title }}</h1>\n    <p class=\"muted\">{{ t.hero_subtitle }}</p>\n    <div class=\"cta-row\">\n      <a class=\"btn primary\" href=\"{{ '/fr/projects/' | relative_url }}\">{{ t.browse_projects }}</a>\n      <a class=\"btn ghost\" href=\"{{ '/fr/about/' | relative_url }}\">{{ t.learn_more }}</a>\n    </div>\n  </div>\n</section>\n\n<section id=\"featured\" class=\"section\">\n  <h2>{{ t.featured_title }}</h2>\n  <p class=\"muted\">{{ t.featured_subtitle }}</p>\n  \n  {% if site.data.modpacks and site.data.modpacks.size > 0 %}\n  <div class=\"featured-spotlight\" style=\"margin-bottom: 2rem;\">\n    <div class=\"spotlight-grid\">\n      {% assign sorted_modpacks = site.data.modpacks | sort: 'date_modified' | reverse %}\n      {% for modpack in sorted_modpacks limit:3 %}\n      <div class=\"spotlight-card animate-on-scroll scale-in stagger-{{ forloop.index }}\">\n        <div class=\"spotlight-badge\">\n          <i class=\"fas fa-star\"></i> {{ t.featured_badge }}\n        </div>\n        <div class=\"spotlight-image\" style=\"background-image: url('{{ modpack.icon_url }}')\"></div>\n        <div class=\"spotlight-content\">\n          <h3>{{ modpack.name }}</h3>\n          <p class=\"muted\">{{ modpack.description | truncate: 100 }}</p>\n          <div class=\"spotlight-meta\">\n            <span class=\"meta-item\">\n              <i class=\"fas fa-download\"></i> {{ modpack.downloads | default: 0 | divided_by: 1000 }}K\n            </span>\n            <span class=\"meta-item\">\n              <i class=\"fas fa-heart\"></i> {{ modpack.followers | default: 0 }}\n            </span>\n            {% if modpack.game_versions and modpack.game_versions.size > 0 %}\n            <span class=\"meta-item\">\n              <i class=\"fas fa-gamepad\"></i> {{ modpack.game_versions[0] }}\n            </span>\n            {% endif %}\n          </div>\n          <div class=\"spotlight-actions\">\n            <a href=\"{{ modpack.project_url }}\" class=\"btn-spotlight primary\" target=\"_blank\" rel=\"noopener\">\n              <i class=\"fas fa-external-link-alt\"></i> {{ t.view_project }}\n            </a>\n            {% if modpack.source_url %}\n            <a href=\"{{ modpack.source_url }}\" class=\"btn-spotlight ghost\" target=\"_blank\" rel=\"noopener\">\n              <i class=\"fab fa-github\"></i> {{ t.source }}\n            </a>\n            {% endif %}\n          </div>\n        </div>\n      </div>\n      {% endfor %}\n    </div>\n  </div>\n  {% endif %}\n  \n  {% include modpacks.html %}\n</section>\n\n<section class=\"section\" id=\"project-stats\">\n  <h2>{{ t.stats_title }}</h2>\n  <p class=\"muted\">{{ t.stats_subtitle }}</p>\n  <div class=\"stats-grid\" id=\"stats-grid\">\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_total_projects }}</p>\n      <div class=\"stat-number\" id=\"stat-projects\">—</div>\n      <div class=\"stat-sub\" id=\"stat-projects-sub\">{{ t.stat_loading }}</div>\n    </div>\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_total_downloads }}</p>\n      <div class=\"stat-number\" id=\"stat-downloads\">—</div>\n      <div class=\"stat-sub\" id=\"stat-downloads-sub\">{{ t.stat_loading }}</div>\n    </div>\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_supported_loaders }}</p>\n      <div class=\"stat-number\" id=\"stat-loaders-count\">—</div>\n      <div class=\"stat-sub\" id=\"stat-loaders\">{{ t.stat_loading }}</div>\n    </div>\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_game_versions }}</p>\n      <div class=\"stat-number\" id=\"stat-versions\">—</div>\n      <div class=\"stat-sub\" id=\"stat-versions-sub\">{{ t.stat_loading }}</div>\n    </div>\n  </div>\n  <div class=\"card\" id=\"top-categories\" style=\"margin-top:16px;\">\n    <h3 style=\"margin-top:0\">{{ t.stat_top_categories }}</h3>\n    <div id=\"stat-categories\" class=\"pill-row\">{{ t.stat_loading }}</div>\n  </div>\n  <div class=\"card\" id=\"downloads-card\" style=\"margin-top:16px;\">\n    <h3 style=\"margin-top:0\">{{ t.stat_top_downloads }}</h3>\n    <p class=\"muted\" id=\"stat-downloads-note\">{{ t.stat_downloads_note }}</p>\n    <div class=\"line-chart\" id=\"downloads-chart\"></div>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div class=\"card\">\n    <h2 style=\"margin-top: 0\">🚀 Modrinth Organization</h2>\n    <div style=\"display: grid; gap: 16px\">\n      <p class=\"muted\">Tous nos projets sont publiés et maintenus via Modrinth.</p>\n      <a class=\"btn ghost\" href=\"{{ site.modrinth.organization_url | default: site.social.modrinth }}\" target=\"_blank\" rel=\"noopener\">Aller sur Modrinth</a>\n    </div>\n  </div>\n</section>\n\n<script>\n  // Load stats from cached mods.json and populate snapshot cards\n  document.addEventListener('DOMContentLoaded', async () => {\n    const modsUrl = '{{ '/data/mods.json' | relative_url }}';\n    const statProjects = document.getElementById('stat-projects');\n    const statProjectsSub = document.getElementById('stat-projects-sub');\n    const statDownloads = document.getElementById('stat-downloads');\n    const statDownloadsSub = document.getElementById('stat-downloads-sub');\n    const statLoaders = document.getElementById('stat-loaders');\n    const statLoadersCount = document.getElementById('stat-loaders-count');\n    const statVersions = document.getElementById('stat-versions');\n    const statVersionsSub = document.getElementById('stat-versions-sub');\n    const statCategories = document.getElementById('stat-categories');\n    const downloadsChart = document.getElementById('downloads-chart');\n    const downloadsNote = document.getElementById('stat-downloads-note');\n\n    try {\n      const res = await fetch(modsUrl);\n      if (!res.ok) throw new Error(`HTTP ${res.status}`);\n      const mods = await res.json();\n      if (!Array.isArray(mods) || mods.length === 0) throw new Error('{{ t.no_projects_found }}');\n\n      const loaders = new Set();\n      const versions = new Set();\n      const categories = new Map();\n      let totalDownloads = 0;\n\n      mods.forEach(m => {\n        (m.loaders || []).forEach(l => loaders.add(l));\n        (m.game_versions || []).forEach(v => versions.add(v));\n        totalDownloads += Number(m.downloads || 0);\n        (m.categories || []).forEach(c => {\n          categories.set(c, (categories.get(c) || 0) + 1);\n        });\n        (m.display_categories || []).forEach(c => {\n          categories.set(c, (categories.get(c) || 0) + 1);\n        });\n      });\n\n      const formatNumber = (n) => n.toLocaleString(undefined, { maximumFractionDigits: 0 });\n      \n      const t = {\n        projects_catalog: '{{ t.stat_projects_catalog }}',\n        avg_per_project: '{{ t.stat_avg_per_project }}',\n        unique_versions: '{{ t.stat_unique_versions }}',\n        no_categories: '{{ t.stat_no_categories }}',\n        no_data: '{{ t.stat_no_data }}',\n        unavailable: '{{ t.stat_unavailable }}'\n      };\n\n      statProjects.textContent = formatNumber(mods.length);\n      statProjectsSub.textContent = t.projects_catalog;\n\n      statDownloads.textContent = formatNumber(totalDownloads);\n      const avgDownloads = mods.length ? Math.round(totalDownloads / mods.length) : 0;\n      statDownloadsSub.textContent = `${formatNumber(avgDownloads)} ${t.avg_per_project}`;\n\n      const loaderList = Array.from(loaders).sort();\n      const versionCount = versions.size;\n\n      statLoadersCount.textContent = loaderList.length ? formatNumber(loaderList.length) : '—';\n      statLoaders.textContent = loaderList.length ? loaderList.join(', ') : '—';\n      statVersions.textContent = versionCount ? formatNumber(versionCount) : '—';\n      statVersionsSub.textContent = versionCount ? t.unique_versions : '—';\n\n      const topCats = Array.from(categories.entries())\n        .sort((a, b) => b[1] - a[1])\n        .slice(0, 6)\n        .map(([c, count]) => `<span class=\"pill\">${c} (${count})</span>`) || [];\n      statCategories.innerHTML = topCats.length ? topCats.join(' ') : t.no_categories;\n\n      // Top downloads multi-line chart (simulated week data)\n      const topDownloads = [...mods]\n        .filter(m => typeof m.downloads === 'number')\n        .sort((a, b) => (b.downloads || 0) - (a.downloads || 0))\n        .slice(0, 11);\n\n      if (topDownloads.length && downloadsChart) {\n        downloadsChart.innerHTML = '';\n        \n        const colors = [\n          '#1bd96f', '#10a8e0', '#22d3ee', '#a78bfa', '#f472b6',\n          '#fb923c', '#fbbf24', '#4ade80', '#60a5fa', '#c084fc', '#f87171'\n        ];\n\n        // Simulate week data with realistic curves (7 days)\n        const days = 7;\n        const maxValue = Math.max(...topDownloads.map(m => m.downloads || 0));\n        \n        const chartWrapper = document.createElement('div');\n        chartWrapper.style.cssText = 'display:flex;gap:20px;align-items:stretch;margin-bottom:12px;';\n\n        // Left side: chart\n        const chartContainer = document.createElement('div');\n        chartContainer.style.cssText = 'flex:1;background:var(--bg-primary);border:1px solid var(--border);padding:16px;box-sizing:border-box;position:relative;';\n\n        const svgWrapper = document.createElement('div');\n        svgWrapper.style.cssText = 'width:100%;height:240px;position:relative;';\n        \n        // Tooltip\n        const tooltip = document.createElement('div');\n        tooltip.style.cssText = 'position:absolute;background:rgba(0,0,0,0.8);color:white;border:1px solid var(--border);padding:8px 12px;border-radius:6px;font-size:12px;pointer-events:none;opacity:0;transition:opacity 0.2s;z-index:10;white-space:nowrap;box-shadow:0 4px 12px rgba(0,0,0,0.4);';\n        chartContainer.appendChild(tooltip);\n\n        const width = 800;\n        const height = 200;\n\n        const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n        svg.setAttribute('viewBox', `0 0 ${width} ${height}`);\n        svg.setAttribute('preserveAspectRatio', 'none');\n        svg.style.cssText = 'width:100%;height:100%;display:block;';\n\n        topDownloads.forEach((mod, idx) => {\n          const color = colors[idx % colors.length];\n          const baseValue = mod.downloads || 0;\n          \n          const points = [];\n          \n          for (let day = 0; day < days; day++) {\n            const x = (day / (days - 1)) * width;\n            const variance = Math.sin(day * 0.8 + idx) * 0.3 + Math.cos(day * 1.2 - idx) * 0.2;\n            const normalizedValue = (baseValue / maxValue) * (0.4 + variance * 0.6);\n            const y = height - Math.max(4, Math.min(height - 4, normalizedValue * (height * 0.9)));\n            const simulatedDownloads = Math.round(baseValue * normalizedValue);\n            points.push({ x, y, downloads: simulatedDownloads, day });\n          }\n\n          const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n          const d = points.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x} ${p.y}`).join(' ');\n          path.setAttribute('d', d);\n          path.setAttribute('fill', 'none');\n          path.setAttribute('stroke', color);\n          path.setAttribute('stroke-width', '2');\n          path.setAttribute('opacity', '0.85');\n          path.style.cursor = 'pointer';\n          \n          points.forEach(p => {\n            const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n            circle.setAttribute('cx', p.x);\n            circle.setAttribute('cy', p.y);\n            circle.setAttribute('r', '4.5');\n            circle.setAttribute('fill', color);\n            circle.setAttribute('opacity', '0.9');\n            circle.style.cursor = 'pointer';\n            svg.appendChild(circle);\n          });\n          \n          path.addEventListener('mouseenter', () => {\n            path.setAttribute('stroke-width', '3');\n            path.setAttribute('opacity', '1');\n          });\n          path.addEventListener('mouseleave', () => {\n            path.setAttribute('stroke-width', '2');\n            path.setAttribute('opacity', '0.85');\n            tooltip.style.opacity = '0';\n          });\n          path.addEventListener('mousemove', (e) => {\n            const rect = chartContainer.getBoundingClientRect();\n            const svgRect = svg.getBoundingClientRect();\n            const relX = ((e.clientX - svgRect.left) / svgRect.width) * width;\n            const closestPoint = points.reduce((prev, curr) => \n              Math.abs(curr.x - relX) < Math.abs(prev.x - relX) ? curr : prev\n            );\n            \n            tooltip.innerHTML = `<div style=\"color:${color};font-weight:600;margin-bottom:2px;\">${mod.title || mod.name}</div><div>Jour ${closestPoint.day + 1}: ${formatNumber(closestPoint.downloads)} téléchargements</div>`;\n            tooltip.style.opacity = '1';\n            tooltip.style.left = Math.min(rect.width - tooltip.offsetWidth - 10, Math.max(10, e.clientX - rect.left + 10)) + 'px';\n            tooltip.style.top = Math.max(10, e.clientY - rect.top - 40) + 'px';\n          });\n          \n          svg.appendChild(path);\n        });\n\n        svgWrapper.appendChild(svg);\n        chartContainer.appendChild(svgWrapper);\n\n        const legendContainer = document.createElement('div');\n        legendContainer.style.cssText = 'width:200px;display:flex;flex-direction:column;gap:8px;overflow-y:auto;max-height:240px;padding-right:8px;';\n        legendContainer.className = 'line-legend';\n        legendContainer.innerHTML = topDownloads.map((m, idx) => {\n          const color = colors[idx % colors.length];\n          return `<div class=\"legend-item\" style=\"display:flex;align-items:center;gap:8px;font-size:13px;color:var(--text-secondary);\"><span style=\"width:8px;height:8px;border-radius:50%;background:${color};display:inline-block;flex-shrink:0;\"></span><span style=\"overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\">${m.title || m.name}</span></div>`;\n        }).join('');\n\n        chartWrapper.appendChild(chartContainer);\n        chartWrapper.appendChild(legendContainer);\n        downloadsChart.appendChild(chartWrapper);\n      } else if (downloadsNote) {\n        downloadsNote.textContent = t.no_data;\n      }\n    } catch (e) {\n      statProjects.textContent = '—';\n      statProjectsSub.textContent = t.unavailable;\n      statDownloads.textContent = '—';\n      statDownloadsSub.textContent = t.unavailable;\n      statLoadersCount.textContent = '—';\n      statLoaders.textContent = t.unavailable;\n      statVersions.textContent = '—';\n      statVersionsSub.textContent = t.unavailable;\n      statCategories.textContent = `{{ t.error_loading }} ${e.message}`;\n      if (downloadsNote) downloadsNote.textContent = `{{ t.error_loading }}`;\n      console.warn('{{ t.failed_to_load }}:', e);\n    }\n  });\n</script>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Documentation</h1>\n    <p class=\"muted\">Complete guides for setting up, customizing, and contributing to the ABC showcase.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2 style=\"margin-bottom: 16px;\">Search & Filter</h2>\n  <div style=\"display: flex; gap: 16px; margin-bottom: 32px; flex-wrap: wrap;\">\n    <input id=\"docs-search\" type=\"search\" placeholder=\"Search documentation...\" style=\"flex: 1; min-width: 200px; padding: 10px 12px; border: 1px solid var(--border); background: var(--bg-secondary); color: var(--text); border-radius: 6px; font-size: 14px;\">\n    <select id=\"docs-category\" style=\"padding: 10px 12px; border: 1px solid var(--border); background: var(--bg-secondary); color: var(--text); border-radius: 6px; font-size: 14px;\">\n      <option value=\"\">All Categories</option>\n      <option value=\"Setup\">Setup</option>\n      <option value=\"Styling\">Styling</option>\n      <option value=\"Community\">Community</option>\n      <option value=\"Help\">Help</option>\n      <option value=\"User Guide\">User Guide</option>\n      <option value=\"Developer\">Developer</option>\n    </select>\n  </div>\n\n  <h3 style=\"margin-bottom: 16px;\">Browse by Category</h3>\n  <div class=\"grid docs-grid\">\n    <a class=\"card\" href=\"{{ '/docs/category/setup/' | relative_url }}\" style=\"text-decoration: none; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;\">\n      <i class=\"fa-solid fa-gear\" style=\"font-size: 24px; color: var(--accent-primary);\"></i>\n      <div>\n        <h3 style=\"margin: 0;\">Setup</h3>\n        <p class=\"muted\" style=\"margin: 0; font-size: 13px;\">Installation & configuration</p>\n      </div>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/styling/' | relative_url }}\" style=\"text-decoration: none; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;\">\n      <i class=\"fa-solid fa-palette\" style=\"font-size: 24px; color: var(--accent-primary);\"></i>\n      <div>\n        <h3 style=\"margin: 0;\">Styling</h3>\n        <p class=\"muted\" style=\"margin: 0; font-size: 13px;\">Themes & customization</p>\n      </div>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/user-guide/' | relative_url }}\" style=\"text-decoration: none; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;\">\n      <i class=\"fa-solid fa-book-open\" style=\"font-size: 24px; color: var(--accent-primary);\"></i>\n      <div>\n        <h3 style=\"margin: 0;\">User Guide</h3>\n        <p class=\"muted\" style=\"margin: 0; font-size: 13px;\">For end users</p>\n      </div>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/community/' | relative_url }}\" style=\"text-decoration: none; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;\">\n      <i class=\"fa-solid fa-users\" style=\"font-size: 24px; color: var(--accent-primary);\"></i>\n      <div>\n        <h3 style=\"margin: 0;\">Community</h3>\n        <p class=\"muted\" style=\"margin: 0; font-size: 13px;\">Contributing & support</p>\n      </div>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/developer/' | relative_url }}\" style=\"text-decoration: none; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;\">\n      <i class=\"fa-solid fa-code\" style=\"font-size: 24px; color: var(--accent-primary);\"></i>\n      <div>\n        <h3 style=\"margin: 0;\">Developer</h3>\n        <p class=\"muted\" style=\"margin: 0; font-size: 13px;\">Technical reference</p>\n      </div>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/help/' | relative_url }}\" style=\"text-decoration: none; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;\">\n      <i class=\"fa-solid fa-circle-question\" style=\"font-size: 24px; color: var(--accent-primary);\"></i>\n      <div>\n        <h3 style=\"margin: 0;\">Help</h3>\n        <p class=\"muted\" style=\"margin: 0; font-size: 13px;\">FAQ & troubleshooting</p>\n      </div>\n    </a>\n  </div>\n\n  <h3 style=\"margin-bottom: 16px;\">All Documentation</h3>\n  <div id=\"docs-results\" class=\"grid docs-results-grid\">\n    <!-- Results will be populated by JavaScript -->\n  </div>\n  <div id=\"load-more-container\" style=\"text-align: center; margin-top: 24px; display: none;\">\n    <button id=\"load-more-btn\" class=\"btn primary\" style=\"padding: 12px 32px;\">\n      <i class=\"fa-solid fa-angle-down\"></i>\n      Load More\n    </button>\n  </div>\n</section>\n\n<script>\n  document.addEventListener('DOMContentLoaded', () => {\n    const docs = [\n      {% assign sorted_docs = site.docs | sort: 'nav_order' %}\n      {% for doc in sorted_docs %}\n        {% unless doc.url contains '/category/' %}\n        {\n          title: {{ doc.title | jsonify }},\n          description: {{ doc.description | default: 'No description available' | jsonify }},\n          url: {{ doc.url | relative_url | jsonify }},\n          category: {{ doc.category | default: 'Other' | jsonify }},\n          tags: {{ doc.tags | jsonify }},\n          content: {{ doc.content | strip_html | truncatewords: 20 | jsonify }}\n        }{% unless forloop.last %},{% endunless %}\n        {% endunless %}\n      {% endfor %}\n    ];\n\n    const searchEl = document.getElementById('docs-search');\n    const categoryEl = document.getElementById('docs-category');\n    const resultsEl = document.getElementById('docs-results');\n    const loadMoreBtn = document.getElementById('load-more-btn');\n    const loadMoreContainer = document.getElementById('load-more-container');\n    \n    let currentFiltered = [];\n    let displayCount = 9;\n    let isSearching = false;\n\n    function renderDocs(filtered, count = displayCount) {\n      currentFiltered = filtered;\n      const docsToShow = isSearching ? filtered : filtered.slice(0, count);\n      \n      resultsEl.innerHTML = docsToShow.length \n        ? docsToShow.map(doc => `\n          <div class=\"card\">\n            <h3>${doc.title}</h3>\n            <p class=\"muted\" style=\"font-size: 13px; margin-bottom: 12px;\">${doc.description}</p>\n            <div style=\"display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;\">\n              <span style=\"display: inline-block; padding: 4px 8px; background: var(--bg-secondary); color: var(--text-secondary); border-radius: 4px; font-size: 12px;\">${doc.category}</span>\n              ${doc.tags.map(tag => `<span style=\"display: inline-block; padding: 4px 8px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 4px; font-size: 12px;\">#${tag}</span>`).join('')}\n            </div>\n            <a class=\"btn primary\" href=\"${doc.url}\" style=\"width: 100%; display: block; text-align: center;\">Read More</a>\n          </div>\n        `).join('')\n        : '<p class=\"muted\" style=\"grid-column: 1 / -1; text-align: center;\">No documentation found.</p>';\n      \n      // Show/hide load more button\n      if (isSearching || filtered.length <= count) {\n        loadMoreContainer.style.display = 'none';\n      } else {\n        loadMoreContainer.style.display = 'block';\n        loadMoreBtn.innerHTML = `<i class=\"fa-solid fa-angle-down\"></i> Load More (${filtered.length - count} remaining)`;\n      }\n    }\n\n    function filterDocs() {\n      const query = searchEl.value.toLowerCase();\n      const category = categoryEl.value;\n      \n      isSearching = !!(query || category);\n\n      const filtered = docs.filter(doc => {\n        const matchesSearch = !query || \n          doc.title.toLowerCase().includes(query) ||\n          doc.description.toLowerCase().includes(query) ||\n          doc.tags.some(tag => tag.toLowerCase().includes(query));\n        \n        const matchesCategory = !category || doc.category === category;\n        \n        return matchesSearch && matchesCategory;\n      });\n\n      displayCount = 9; // Reset display count when filtering\n      renderDocs(filtered);\n    }\n\n    loadMoreBtn.addEventListener('click', () => {\n      displayCount += 9;\n      renderDocs(currentFiltered, displayCount);\n    });\n\n    searchEl.addEventListener('input', filterDocs);\n    categoryEl.addEventListener('change', filterDocs);\n\n    // Initial render\n    renderDocs(docs);\n  });\n</script>\n","{% assign t = site.data[page.lang] %}\n\n<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>{{ t.hero_title }}</h1>\n    <p class=\"muted\">{{ t.hero_subtitle }}</p>\n    <div class=\"cta-row\">\n      <a class=\"btn primary\" href=\"{{ '/projects/' | relative_url }}\">{{ t.browse_projects }}</a>\n      <a class=\"btn ghost\" href=\"{{ '/about/' | relative_url }}\">{{ t.learn_more }}</a>\n    </div>\n  </div>\n</section>\n\n<section id=\"featured\" class=\"section\">\n  <h2>{{ t.featured_title }}</h2>\n  <p class=\"muted\">{{ t.featured_subtitle }}</p>\n  \n  {% if site.data.modpacks and site.data.modpacks.size > 0 %}\n  <div class=\"featured-spotlight\" style=\"margin-bottom: 2rem;\">\n    <div class=\"spotlight-grid\">\n      {% assign sorted_modpacks = site.data.modpacks | sort: 'date_modified' | reverse %}\n      {% for modpack in sorted_modpacks limit:3 %}\n      <div class=\"spotlight-card animate-on-scroll scale-in stagger-{{ forloop.index }}\">\n        <div class=\"spotlight-badge\">\n          <i class=\"fas fa-star\"></i> {{ t.featured_badge }}\n        </div>\n        <div class=\"spotlight-image\" style=\"background-image: url('{{ modpack.icon_url }}')\"></div>\n        <div class=\"spotlight-content\">\n          <h3>{{ modpack.name }}</h3>\n          <p class=\"muted\">{{ modpack.description | truncate: 100 }}</p>\n          <div class=\"spotlight-meta\">\n            <span class=\"meta-item\">\n              <i class=\"fas fa-download\"></i> {{ modpack.downloads | default: 0 | divided_by: 1000 }}K\n            </span>\n            <span class=\"meta-item\">\n              <i class=\"fas fa-heart\"></i> {{ modpack.followers | default: 0 }}\n            </span>\n            {% if modpack.game_versions and modpack.game_versions.size > 0 %}\n            <span class=\"meta-item\">\n              <i class=\"fas fa-gamepad\"></i> {{ modpack.game_versions[0] }}\n            </span>\n            {% endif %}\n          </div>\n          <div class=\"spotlight-actions\">\n            <a href=\"{{ modpack.project_url }}\" class=\"btn-spotlight primary\" target=\"_blank\" rel=\"noopener\">\n              <i class=\"fas fa-external-link-alt\"></i> {{ t.view_project }}\n            </a>\n            {% if modpack.source_url %}\n            <a href=\"{{ modpack.source_url }}\" class=\"btn-spotlight ghost\" target=\"_blank\" rel=\"noopener\">\n              <i class=\"fab fa-github\"></i> {{ t.source }}\n            </a>\n            {% endif %}\n          </div>\n        </div>\n      </div>\n      {% endfor %}\n    </div>\n  </div>\n  {% endif %}\n  \n  {% include modpacks.html %}\n</section>\n\n<section class=\"section\" id=\"project-stats\">\n  <h2>{{ t.stats_title }}</h2>\n  <p class=\"muted\">{{ t.stats_subtitle }}</p>\n  <div class=\"stats-grid\" id=\"stats-grid\">\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_total_projects }}</p>\n      <div class=\"stat-number\" id=\"stat-projects\">—</div>\n      <div class=\"stat-sub\" id=\"stat-projects-sub\">{{ t.stat_loading }}</div>\n    </div>\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_total_downloads }}</p>\n      <div class=\"stat-number\" id=\"stat-downloads\">—</div>\n      <div class=\"stat-sub\" id=\"stat-downloads-sub\">{{ t.stat_loading }}</div>\n    </div>\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_supported_loaders }}</p>\n      <div class=\"stat-number\" id=\"stat-loaders-count\">—</div>\n      <div class=\"stat-sub\" id=\"stat-loaders\">{{ t.stat_loading }}</div>\n    </div>\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_game_versions }}</p>\n      <div class=\"stat-number\" id=\"stat-versions\">—</div>\n      <div class=\"stat-sub\" id=\"stat-versions-sub\">{{ t.stat_loading }}</div>\n    </div>\n  </div>\n  <div class=\"card\" id=\"top-categories\" style=\"margin-top:16px;\">\n    <h3 style=\"margin-top:0\">{{ t.stat_top_categories }}</h3>\n    <div id=\"stat-categories\" class=\"pill-row\">{{ t.stat_loading }}</div>\n  </div>\n  <div class=\"card\" id=\"downloads-card\" style=\"margin-top:16px;\">\n    <h3 style=\"margin-top:0\">{{ t.stat_top_downloads }}</h3>\n    <p class=\"muted\" id=\"stat-downloads-note\">{{ t.stat_downloads_note }}</p>\n    <div class=\"line-chart\" id=\"downloads-chart\"></div>\n  </div>\n</section>\n\n{% assign featured_docs = site.docs | sort: 'nav_order' | slice: 0, 3 %}\n{% if featured_docs and featured_docs.size > 0 %}\n\n<section class=\"section\" id=\"featured-docs\">\n  <h2>Docs Spotlight</h2>\n  <p class=\"muted\">Quick links to key guides</p>\n  <div class=\"grid\">\n    {% for doc in featured_docs %}\n      <a class=\"card\" href=\"{{ doc.url | relative_url }}\" style=\"text-decoration:none\">\n        <h3 style=\"margin-top:0\">{{ doc.title }}</h3>\n        {% if doc.description %}<p class=\"muted\">{{ doc.description }}</p>{% else %}<p class=\"muted\">Read more</p>{% endif %}\n        <span class=\"pill\">Docs</span>\n      </a>\n    {% endfor %}\n  </div>\n</section>\n{% endif %}\n\n<section class=\"section\">\n  <h2>How It Works</h2>\n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-box\"></i> Static Content</h3>\n      <p>All projects are stored as static data. No database needed.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-arrows-rotate\"></i> Auto-Update</h3>\n      <p>Daily syncs from Modrinth keep your showcase fresh.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-bolt\"></i> Lightning Fast</h3>\n      <p>Deployed globally on GitHub Pages for instant loading.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-palette\"></i> Beautiful</h3>\n      <p>Modern design with smooth animations and blur effects.</p>\n    </div>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>Get Started</h2>\n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3>Read the Docs</h3>\n      <p class=\"muted\">Configure branding, fetch projects, and deploy.</p>\n      <a class=\"btn primary\" href=\"{{ '/docs/' | relative_url }}\">Open Docs</a>\n    </div>\n    <div class=\"card\">\n      <h3>Browse Projects</h3>\n      <p class=\"muted\">Filter by type, loader, or version.</p>\n      <a class=\"btn primary\" href=\"{{ '/projects/' | relative_url }}\">View Catalog</a>\n    </div>\n    <div class=\"card\">\n      <h3>Sync from Modrinth</h3>\n      <p class=\"muted\">Run <code>npm run fetch</code> or use the scheduled workflow.</p>\n      <a class=\"btn ghost\" href=\"{{ '/docs/' | relative_url }}\">See Setup</a>\n    </div>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>Stay in the Loop</h2>\n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3>Join Discord</h3>\n      <p class=\"muted\">Get support, share feedback, and see previews.</p>\n      <a class=\"btn ghost\" href=\"{{ site.social.discord }}\" target=\"_blank\" rel=\"noopener\">Open Discord</a>\n    </div>\n    <div class=\"card\">\n      <h3>Watch GitHub</h3>\n      <p class=\"muted\">Track updates, file issues, or contribute.</p>\n      <a class=\"btn ghost\" href=\"{{ site.social.github }}\" target=\"_blank\" rel=\"noopener\">View Repo</a>\n    </div>\n    <div class=\"card\">\n      <h3>Follow Modrinth</h3>\n      <p class=\"muted\">Stay updated on releases across all projects.</p>\n      <a class=\"btn ghost\" href=\"{{ site.modrinth.organization_url | default: site.social.modrinth }}\" target=\"_blank\" rel=\"noopener\">Go to Modrinth</a>\n    </div>\n  </div>\n</section>\n\n<script>\n  // Load stats from cached mods.json and populate snapshot cards\n  document.addEventListener('DOMContentLoaded', async () => {\n    const modsUrl = '{{ '/data/mods.json' | relative_url }}';\n    const statProjects = document.getElementById('stat-projects');\n    const statProjectsSub = document.getElementById('stat-projects-sub');\n    const statDownloads = document.getElementById('stat-downloads');\n    const statDownloadsSub = document.getElementById('stat-downloads-sub');\n    const statLoaders = document.getElementById('stat-loaders');\n    const statLoadersCount = document.getElementById('stat-loaders-count');\n    const statVersions = document.getElementById('stat-versions');\n    const statVersionsSub = document.getElementById('stat-versions-sub');\n    const statCategories = document.getElementById('stat-categories');\n    const downloadsChart = document.getElementById('downloads-chart');\n    const downloadsNote = document.getElementById('stat-downloads-note');\n\n    try {\n      const res = await fetch(modsUrl);\n      if (!res.ok) throw new Error(`HTTP ${res.status}`);\n      const mods = await res.json();\n      if (!Array.isArray(mods) || mods.length === 0) throw new Error('No projects found');\n\n      const loaders = new Set();\n      const versions = new Set();\n      const categories = new Map();\n      let totalDownloads = 0;\n\n      mods.forEach(m => {\n        (m.loaders || []).forEach(l => loaders.add(l));\n        (m.game_versions || []).forEach(v => versions.add(v));\n        totalDownloads += Number(m.downloads || 0);\n        (m.categories || []).forEach(c => {\n          categories.set(c, (categories.get(c) || 0) + 1);\n        });\n        (m.display_categories || []).forEach(c => {\n          categories.set(c, (categories.get(c) || 0) + 1);\n        });\n      });\n\n      const formatNumber = (n) => n.toLocaleString(undefined, { maximumFractionDigits: 0 });\n      \n      const t = {\n        projects_catalog: '{{ t.stat_projects_catalog }}',\n        avg_per_project: '{{ t.stat_avg_per_project }}',\n        unique_versions: '{{ t.stat_unique_versions }}',\n        no_categories: '{{ t.stat_no_categories }}',\n        no_data: '{{ t.stat_no_data }}',\n        unavailable: '{{ t.stat_unavailable }}'\n      };\n\n      statProjects.textContent = formatNumber(mods.length);\n      statProjectsSub.textContent = t.projects_catalog;\n\n      statDownloads.textContent = formatNumber(totalDownloads);\n      const avgDownloads = mods.length ? Math.round(totalDownloads / mods.length) : 0;\n      statDownloadsSub.textContent = `${formatNumber(avgDownloads)} ${t.avg_per_project}`;\n\n      const loaderList = Array.from(loaders).sort();\n      const versionCount = versions.size;\n\n      statLoadersCount.textContent = loaderList.length ? formatNumber(loaderList.length) : '—';\n      statLoaders.textContent = loaderList.length ? loaderList.join(', ') : '—';\n      statVersions.textContent = versionCount ? formatNumber(versionCount) : '—';\n      statVersionsSub.textContent = versionCount ? t.unique_versions : '—';\n\n      const topCats = Array.from(categories.entries())\n        .sort((a, b) => b[1] - a[1])\n        .slice(0, 6)\n        .map(([c, count]) => `<span class=\"pill\">${c} (${count})</span>`) || [];\n      statCategories.innerHTML = topCats.length ? topCats.join(' ') : t.no_categories;\n\n      // Top downloads multi-line chart (simulated week data)\n      const topDownloads = [...mods]\n        .filter(m => typeof m.downloads === 'number')\n        .sort((a, b) => (b.downloads || 0) - (a.downloads || 0))\n        .slice(0, 11);\n\n      if (topDownloads.length && downloadsChart) {\n        downloadsChart.innerHTML = '';\n        \n        const colors = [\n          '#1bd96f', '#10a8e0', '#22d3ee', '#a78bfa', '#f472b6',\n          '#fb923c', '#fbbf24', '#4ade80', '#60a5fa', '#c084fc', '#f87171'\n        ];\n\n        // Simulate week data with realistic curves (7 days)\n        const days = 7;\n        const maxValue = Math.max(...topDownloads.map(m => m.downloads || 0));\n        \n        const chartWrapper = document.createElement('div');\n        chartWrapper.style.cssText = 'display:flex;gap:20px;align-items:stretch;margin-bottom:12px;';\n\n        // Left side: chart\n        const chartContainer = document.createElement('div');\n        chartContainer.style.cssText = 'flex:1;background:var(--bg-primary);border:1px solid var(--border);padding:16px;box-sizing:border-box;position:relative;';\n\n        const svgWrapper = document.createElement('div');\n        svgWrapper.style.cssText = 'width:100%;height:240px;position:relative;';\n        \n        // Tooltip\n        const tooltip = document.createElement('div');\n        tooltip.style.cssText = 'position:absolute;background:rgba(0,0,0,0.8);color:white;border:1px solid var(--border);padding:8px 12px;border-radius:6px;font-size:12px;pointer-events:none;opacity:0;transition:opacity 0.2s;z-index:10;white-space:nowrap;box-shadow:0 4px 12px rgba(0,0,0,0.4);';\n        chartContainer.appendChild(tooltip);\n\n        // Use actual pixel dimensions\n        const width = 800;  // Fixed width for consistent rendering\n        const height = 200; // Fixed height\n\n        const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n        svg.setAttribute('viewBox', `0 0 ${width} ${height}`);\n        svg.setAttribute('preserveAspectRatio', 'none');\n        svg.style.cssText = 'width:100%;height:100%;display:block;';\n\n        topDownloads.forEach((mod, idx) => {\n          const color = colors[idx % colors.length];\n          const baseValue = mod.downloads || 0;\n          \n          // Generate smooth curve with variation\n          const points = [];\n          \n          for (let day = 0; day < days; day++) {\n            const x = (day / (days - 1)) * width;\n            const variance = Math.sin(day * 0.8 + idx) * 0.3 + Math.cos(day * 1.2 - idx) * 0.2;\n            const normalizedValue = (baseValue / maxValue) * (0.4 + variance * 0.6);\n            const y = height - Math.max(4, Math.min(height - 4, normalizedValue * (height * 0.9)));\n            const simulatedDownloads = Math.round(baseValue * normalizedValue);\n            points.push({ x, y, downloads: simulatedDownloads, day });\n          }\n\n          const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n          const d = points.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x} ${p.y}`).join(' ');\n          path.setAttribute('d', d);\n          path.setAttribute('fill', 'none');\n          path.setAttribute('stroke', color);\n          path.setAttribute('stroke-width', '2');\n          path.setAttribute('opacity', '0.85');\n          path.style.cursor = 'pointer';\n          \n          // Add dots at each data point\n          points.forEach(p => {\n            const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n            circle.setAttribute('cx', p.x);\n            circle.setAttribute('cy', p.y);\n            circle.setAttribute('r', '4.5');\n            circle.setAttribute('fill', color);\n            circle.setAttribute('opacity', '0.9');\n            circle.style.cursor = 'pointer';\n            svg.appendChild(circle);\n          });\n          \n          // Hover effect\n          path.addEventListener('mouseenter', () => {\n            path.setAttribute('stroke-width', '3');\n            path.setAttribute('opacity', '1');\n          });\n          path.addEventListener('mouseleave', () => {\n            path.setAttribute('stroke-width', '2');\n            path.setAttribute('opacity', '0.85');\n            tooltip.style.opacity = '0';\n          });\n          path.addEventListener('mousemove', (e) => {\n            const rect = chartContainer.getBoundingClientRect();\n            const svgRect = svg.getBoundingClientRect();\n            const relX = ((e.clientX - svgRect.left) / svgRect.width) * width;\n            const closestPoint = points.reduce((prev, curr) => \n              Math.abs(curr.x - relX) < Math.abs(prev.x - relX) ? curr : prev\n            );\n            \n            tooltip.innerHTML = `<div style=\"color:${color};font-weight:600;margin-bottom:2px;\">${mod.title || mod.name}</div><div>Day ${closestPoint.day + 1}: ${formatNumber(closestPoint.downloads)} downloads</div>`;\n            tooltip.style.opacity = '1';\n            tooltip.style.left = Math.min(rect.width - tooltip.offsetWidth - 10, Math.max(10, e.clientX - rect.left + 10)) + 'px';\n            tooltip.style.top = Math.max(10, e.clientY - rect.top - 40) + 'px';\n          });\n          \n          svg.appendChild(path);\n        });\n\n        svgWrapper.appendChild(svg);\n        chartContainer.appendChild(svgWrapper);\n\n        // Right side: legend\n        const legendContainer = document.createElement('div');\n        legendContainer.style.cssText = 'width:200px;display:flex;flex-direction:column;gap:8px;overflow-y:auto;max-height:240px;padding-right:8px;';\n        legendContainer.className = 'line-legend';\n        legendContainer.innerHTML = topDownloads.map((m, idx) => {\n          const color = colors[idx % colors.length];\n          return `<div class=\"legend-item\" style=\"display:flex;align-items:center;gap:8px;font-size:13px;color:var(--text-secondary);\"><span style=\"width:8px;height:8px;border-radius:50%;background:${color};display:inline-block;flex-shrink:0;\"></span><span style=\"overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\">${m.title || m.name}</span></div>`;\n        }).join('');\n\n        chartWrapper.appendChild(chartContainer);\n        chartWrapper.appendChild(legendContainer);\n        downloadsChart.appendChild(chartWrapper);\n      } else if (downloadsNote) {\n        downloadsNote.textContent = t.no_data;\n      }\n    } catch (e) {\n      statProjects.textContent = '—';\n      statProjectsSub.textContent = t.unavailable;\n      statDownloads.textContent = '—';\n      statDownloadsSub.textContent = t.unavailable;\n      statLoadersCount.textContent = '—';\n      statLoaders.textContent = t.unavailable;\n      statVersions.textContent = '—';\n      statVersionsSub.textContent = t.unavailable;\n      statCategories.textContent = `{{ t.error_loading }} ${e.message}`;\n      if (downloadsNote) downloadsNote.textContent = `{{ t.error_loading }}`;\n      console.warn('{{ t.failed_to_load }}:', e);\n    }\n  });\n</script>\n","# Licensing & Attribution\n\n**Last Updated:** December 2024\n\nThis page outlines the licenses used across our projects and how to properly attribute them.\n\n## Project Licenses\n\n| Project       | License   | Repository | Key Terms                           |\n| ------------- | --------- | ---------- | ----------------------------------- |\n| Core Projects | MIT       | GitHub     | Permissive; attribution appreciated |\n| Datapacks     | CC0 / MIT | GitHub     | Check individual README             |\n| Plugins       | MIT       | GitHub     | Permissive; include license         |\n| Documentation | CC-BY-4.0 | This Site  | Attribute ABC Team                  |\n\n## MIT License Summary\n\n**Permissions**:\n\n- ✅ Commercial use\n- ✅ Modification\n- ✅ Distribution\n- ✅ Private use\n\n**Conditions**:\n\n- ⚠️ Include license and copyright notice\n- ⚠️ Disclose changes\n\n**Limitations**:\n\n- ❌ No liability\n- ❌ No warranty\n\n## Creative Commons (CC-BY-4.0)\n\nUsed for documentation and educational content.\n\n**You are free to**:\n\n- Share the material\n- Adapt and remix\n- Use commercially\n\n**You must**:\n\n- Give appropriate credit\n- Provide a link to the license\n- Indicate if changes were made\n\n## How to Attribute\n\n### For Code\n\n```\nBased on ABC Team's [Project Name]\nLicense: MIT\nSource: https://github.com/devvyyxyz/[repo]\n```\n\n### For Documentation\n\n```\nContent adapted from ABC Team\nLicense: CC-BY-4.0\nSource: [abc-site-url]\n```\n\n### For Derivative Projects\n\nIf you create a modified version:\n\n1. Include the original license file\n2. Add a notice of modifications\n3. State the original source\n4. Link to our GitHub\n\nExample:\n\n```\nThis project is based on ABC Team's [Original Project]\nOriginal License: MIT\nOriginal Source: https://github.com/devvyyxyz/[repo]\nModifications: [describe changes]\n```\n\n## Third-Party Dependencies\n\nOur projects use open-source libraries. See `LICENSE` and `LICENSES/` directories in each repository for full details.\n\n### Common Dependencies\n\n| Dependency | License    | Link                                                       |\n| ---------- | ---------- | ---------------------------------------------------------- |\n| Fabric API | Apache 2.0 | [GitHub](https://github.com/FabricMC/fabric)               |\n| Forge      | LGPL 2.1   | [GitHub](https://github.com/MinecraftForge/MinecraftForge) |\n| Quilt      | Apache 2.0 | [GitHub](https://github.com/QuiltMC)                       |\n\n## Minecraft & Mojang\n\nOur projects are designed for Minecraft and follow Mojang's Brand and Asset Guidelines:\n\n- Minecraft is owned by Mojang Studios / Microsoft\n- Our projects are independent community mods\n- We do not sell Minecraft or charge for access\n- See [Minecraft EULA](https://account.mojang.com/terms)\n\n## Using Our Projects Commercially\n\n**Yes, you can use our projects commercially!**\n\n**Requirements**:\n\n1. Include the MIT license file\n2. Attribute ABC Team in credits or documentation\n3. Disclose if you modified the software\n4. Provide source code access (for MIT)\n\n**Server Usage**:\n\n- Personal servers: Fully permitted\n- Public servers: Permitted with attribution\n- Paid servers: Permitted (no revenue share)\n\n**Content Creation**:\n\n- YouTube/Twitch: Fully permitted (no permission needed)\n- Monetization: Fully permitted (no revenue share)\n- Attribution appreciated but not required\n\n## Questions About Licensing\n\n- **Can I sell modifications?** No. Modified versions must remain free.\n- **Can I bundle your code?** Yes, if you include the license.\n- **Can I relicense your code?** Only under compatible licenses (MIT to Apache 2.0, etc.).\n- **Can I use your code in closed-source?** No. MIT requires source disclosure or available code.\n\n## Dispute Resolution\n\nIf you believe our projects infringe on your intellectual property, please contact us:\n\n**Email**: [contact from config]  \n**GitHub Issues**: [Repository link]\n\nWe will respond within 7 days to address concerns.\n\n---\n\n**Our Mission**: Create amazing, free, open-source mods and tools for the Minecraft community.\n\nFor the full legal text of each license, see the `LICENSE` file in each repository.\n","<section class=\"section\">\n  <h1>Privacy Policy</h1>\n  <p class=\"muted\">How we collect, use, and protect information on this site.</p>\n\n  <h2>What we collect</h2>\n  <ul>\n    <li>No account data is collected by this static site.</li>\n    <li>Server logs (via hosting) may include IP address, user-agent, and request metadata for basic operations and security.</li>\n    <li>If you submit feedback (e.g., the docs widget), it is stored locally in your browser only.</li>\n  </ul>\n\n  <h2>Cookies & storage</h2>\n  <ul>\n    <li>Theme and feedback choices are stored in <code>localStorage</code> for your convenience.</li>\n    <li>No tracking or advertising cookies are set by this site.</li>\n  </ul>\n\n  <h2>Third-party links</h2>\n  <p>Links to Modrinth, GitHub, and Discord follow their respective privacy policies.</p>\n\n  <h2>Contact</h2>\n  <p>Questions or removal requests? <a href=\"{{ '/contact/' | relative_url }}\">Contact us</a>.</p>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Browse All Projects</h1>\n    <p class=\"muted\">Explore our curated collection of mods, resource packs, datapacks, modpacks, and plugins.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h1>Projects</h1>\n  <p class=\"muted\">Latest projects from ABC organization</p>\n\n  <div class=\"filters\" id=\"projects-filters\">\n    <input id=\"filter-search\" type=\"search\" placeholder=\"Search projects...\" aria-label=\"Search projects\">\n    <select id=\"filter-type\" aria-label=\"Filter by type\">\n      <option value=\"all\">All types</option>\n    </select>\n    <select id=\"filter-loader\" aria-label=\"Filter by loader\">\n      <option value=\"all\">All loaders</option>\n    </select>\n    <select id=\"filter-version\" aria-label=\"Filter by version\">\n      <option value=\"all\">All versions</option>\n    </select>\n  </div>\n\n  <div id=\"projects-count\" class=\"muted\" style=\"margin-top:10px\"></div>\n  <div id=\"mods-list\" class=\"modpacks-list\"></div>\n</section>\n\n<script>\n  // Load projects from cached JSON file with filtering and rich metadata\n  document.addEventListener('DOMContentLoaded', async () => {\n    const container = document.getElementById('mods-list');\n    const countEl = document.getElementById('projects-count');\n    const searchEl = document.getElementById('filter-search');\n    const typeEl = document.getElementById('filter-type');\n    const loaderEl = document.getElementById('filter-loader');\n    const versionEl = document.getElementById('filter-version');\n\n    const state = {\n      projects: [],\n      filters: { search: '', type: 'all', loader: 'all', version: 'all' }\n    };\n\n    // Base options so filters always have choices even if data is missing them\n    const baseTypes = ['mod', 'modpack', 'datapack', 'resourcepack', 'plugin', 'shader', 'world', 'library'];\n    const baseLoaders = ['fabric', 'forge', 'quilt', 'neoforge', 'liteloader', 'rift', 'bukkit', 'paper', 'purpur', 'datapack', 'minecraft', 'resourcepack', 'shaders'];\n    const baseVersions = ['1.16', '1.16.5', '1.17.1', '1.18.2', '1.19.4', '1.20', '1.20.1', '1.20.2', '1.20.4', '1.20.6', '1.21', '1.21.1', '1.21.2', '1.21.3', '1.21.4', '1.21.5'];\n\n    function formatDate(value) {\n      if (!value) return 'Unknown';\n      const d = new Date(value);\n      if (Number.isNaN(d.getTime())) return 'Unknown';\n      return d.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\n    }\n\n    function populateFilters(items) {\n      const types = new Set(baseTypes);\n      const loaders = new Set(baseLoaders);\n      const versions = new Set(baseVersions);\n\n      items.forEach(p => {\n        if (p.project_type) types.add(p.project_type);\n        (p.loaders || []).forEach(l => loaders.add(l));\n        (p.game_versions || []).forEach(v => versions.add(v));\n      });\n\n      typeEl.innerHTML = '<option value=\"all\">All types</option>' +\n        Array.from(types).sort().map(t => `<option value=\"${t}\">${t}</option>`).join('');\n      loaderEl.innerHTML = '<option value=\"all\">All loaders</option>' +\n        Array.from(loaders).sort().map(l => `<option value=\"${l}\">${l}</option>`).join('');\n      versionEl.innerHTML = '<option value=\"all\">All versions</option>' +\n        Array.from(versions).sort((a, b) => a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' })).map(v => `<option value=\"${v}\">${v}</option>`).join('');\n    }\n\n    function applyFilters() {\n      let items = [...state.projects];\n      const { search, type, loader, version } = state.filters;\n\n      if (search) {\n        const q = search.toLowerCase();\n        items = items.filter(p => (\n          (p.title || p.name || '').toLowerCase().includes(q) ||\n          (p.short_description || '').toLowerCase().includes(q)\n        ));\n      }\n\n      if (type !== 'all') {\n        items = items.filter(p => (p.project_type || p.type) === type);\n      }\n\n      if (loader !== 'all') {\n        items = items.filter(p => (p.loaders || []).includes(loader));\n      }\n\n      if (version !== 'all') {\n        items = items.filter(p => (p.game_versions || []).includes(version));\n      }\n\n      renderProjects(items);\n    }\n\n    function renderProjects(items) {\n      if (!items.length) {\n        container.innerHTML = '<p class=\"muted\">No projects found for this filter.</p>';\n        countEl.textContent = '0 projects';\n        return;\n      }\n\n      container.innerHTML = '';\n      countEl.textContent = `${items.length} project${items.length === 1 ? '' : 's'}`;\n\n      items.forEach((m, i) => {\n        const el = document.createElement('div');\n        el.className = 'modpack';\n        el.style.animationDelay = (i * 60) + 'ms';\n\n        // Generate project slug for detail page link\n        const slug = (m.slug || m.title.toLowerCase().replace(/\\s+/g, '-').replace(/[^a-z0-9-]/g, ''));\n        const detailPageUrl = `/abc-site/projects/${slug}/`;\n\n        const thumb = document.createElement('div');\n        thumb.className = 'thumb';\n        thumb.style.backgroundImage = `url(${m.icon_url || m.thumbnail || '/assets/images/favicon.svg'})`;\n        thumb.style.cursor = 'pointer';\n        thumb.addEventListener('click', () => window.location.href = detailPageUrl);\n\n        const meta = document.createElement('div');\n        meta.className = 'meta';\n        meta.style.cursor = 'pointer';\n        meta.addEventListener('click', () => window.location.href = detailPageUrl);\n        const shortDesc = m.short_description || m.summary || m.description || '';\n        const desc = shortDesc.length > 160 ? `${shortDesc.substring(0, 160)}...` : shortDesc;\n        const versions = (m.game_versions || []).slice(-3).reverse();\n        const loaders = (m.loaders || []).slice(0, 3);\n\n        const pill = (label, icon) => `<span class=\"pill\">${icon ? `<i class=\"fa-solid fa-${icon}\"></i>` : ''}${label}</span>`;\n        const metaInfo = [\n          m.updated || m.published ? pill(`Updated ${formatDate(m.updated || m.published)}`, 'clock') : '',\n          versions.length ? pill(`MC ${versions.join(', ')}`, 'cube') : '',\n          loaders.length ? pill(`Loaders: ${loaders.join(', ')}`, 'cogs') : '',\n          m.license_id ? pill(`License: ${m.license_id}`, 'file-alt') : ''\n        ].filter(Boolean).join('');\n\n        meta.innerHTML = `\n          <h3>${m.title || m.name}</h3>\n          <p>${desc}</p>\n        `;\n\n        const pillSection = document.createElement('div');\n        pillSection.className = 'pill-section';\n        const metaInfoHTML = [\n          m.updated || m.published ? pill(`Updated ${formatDate(m.updated || m.published)}`, 'clock') : '',\n          versions.length ? pill(`MC ${versions.join(', ')}`, 'cube') : '',\n          loaders.length ? pill(`Loaders: ${loaders.join(', ')}`, 'cogs') : '',\n          m.license_id ? pill(`License: ${m.license_id}`, 'file-alt') : ''\n        ].filter(Boolean).join('');\n        \n        const categoriesHTML = (m.display_categories || m.categories || []).slice(0, 4).map(c => `<span class=\"pill\">#${c}</span>`).join(' ');\n        \n        pillSection.innerHTML = `${metaInfoHTML} ${categoriesHTML}`;\n\n        const action = document.createElement('div');\n        action.className = 'actions';\n        \n        // Check if source_url exists (GitHub link)\n        const sourceUrl = m.source_url || m.repository;\n        \n        let buttonsHTML = '';\n        buttonsHTML += `<a class=\"btn primary\" href=\"${detailPageUrl}\" title=\"View details\">Details</a>`;\n        if (sourceUrl) {\n          buttonsHTML += `<a class=\"btn secondary\" href=\"${sourceUrl}\" target=\"_blank\" rel=\"noopener\" title=\"View source\"><i class=\"fa-brands fa-github\"></i></a>`;\n        }\n        buttonsHTML += `<a class=\"btn ghost\" href=\"${m.download || `https://modrinth.com/mod/${m.slug}`}\" target=\"_blank\" rel=\"noopener\">View</a>`;\n        \n        action.innerHTML = buttonsHTML;\n\n        el.appendChild(thumb);\n        el.appendChild(meta);\n        el.appendChild(pillSection);\n        el.appendChild(action);\n        container.appendChild(el);\n      });\n    }\n\n    function handleFilterChange() {\n      state.filters = {\n        search: searchEl.value.trim(),\n        type: typeEl.value,\n        loader: loaderEl.value,\n        version: versionEl.value\n      };\n      applyFilters();\n    }\n\n    // Wire up filters\n    searchEl.addEventListener('input', () => {\n      state.filters.search = searchEl.value.trim();\n      applyFilters();\n    });\n    [typeEl, loaderEl, versionEl].forEach(el => el.addEventListener('change', handleFilterChange));\n\n    try {\n      const res = await fetch('{{ '/data/mods.json' | relative_url }}');\n      if (!res.ok) throw new Error(`HTTP ${res.status}: Failed to load projects`);\n      const projects = await res.json();\n\n      if (!Array.isArray(projects) || projects.length === 0) {\n        container.innerHTML = '<p class=\"muted\">No projects found. Projects will be synced automatically.</p>';\n        return;\n      }\n\n      // Sort newest updated first\n      state.projects = projects.sort((a, b) => new Date(b.updated || b.published || 0) - new Date(a.updated || a.published || 0));\n      populateFilters(state.projects);\n      applyFilters();\n    } catch (e) {\n      console.error('Failed to load projects:', e);\n      container.innerHTML = `<p class=\"muted\">Error: ${e.message}</p>`;\n    }\n  });\n</script>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Documentation Overview</h1>\n    <p class=\"muted\">Complete reference of all available guides and resources.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>📚 All Documentation Pages</h2>\n\n  <h3>Setup & Configuration (2 pages)</h3>\n  <ul style=\"list-style: none; padding: 0;\">\n    <li><strong><a href=\"{{ '/docs/getting-started/' | relative_url }}\">Getting Started</a></strong> — Quick start guide for new users</li>\n    <li><strong><a href=\"{{ '/docs/setup/' | relative_url }}\">Setup & Configuration</a></strong> — Detailed setup and Modrinth integration instructions</li>\n  </ul>\n\n  <h3>Styling & Customization (1 page)</h3>\n  <ul style=\"list-style: none; padding: 0;\">\n    <li><strong><a href=\"{{ '/docs/customization/' | relative_url }}\">Customization</a></strong> — Theming, colors, and CSS customization</li>\n  </ul>\n\n  <h3>Community & Contributing (1 page)</h3>\n  <ul style=\"list-style: none; padding: 0;\">\n    <li><strong><a href=\"{{ '/docs/contributing/' | relative_url }}\">Contributing</a></strong> — Guidelines for contributors and pull requests</li>\n  </ul>\n\n  <h3>Help & Troubleshooting (2 pages)</h3>\n  <ul style=\"list-style: none; padding: 0;\">\n    <li><strong><a href=\"{{ '/docs/faq/' | relative_url }}\">FAQ</a></strong> — Frequently asked questions</li>\n    <li><strong><a href=\"{{ '/docs/troubleshooting/' | relative_url }}\">Troubleshooting</a></strong> — Common issues and solutions</li>\n  </ul>\n\n  <h3>User Guide (1 page)</h3>\n  <ul style=\"list-style: none; padding: 0;\">\n    <li><strong><a href=\"{{ '/docs/how-to-install/' | relative_url }}\">How to Install</a></strong> — Step-by-step installation guide</li>\n  </ul>\n\n  <h3>Developer Resources (3 pages)</h3>\n  <ul style=\"list-style: none; padding: 0;\">\n    <li><strong><a href=\"{{ '/docs/api-reference/' | relative_url }}\">API Reference</a></strong> — Project data structure and Modrinth API</li>\n    <li><strong><a href=\"{{ '/docs/project-structure/' | relative_url }}\">Project Structure</a></strong> — File organization and architecture</li>\n    <li><strong><a href=\"{{ '/docs/troubleshooting/' | relative_url }}\">Troubleshooting</a></strong> — Debugging and common errors</li>\n  </ul>\n\n</section>\n\n<section class=\"section\">\n  <h2>🏷️ Tag Cloud</h2>\n  <div style=\"display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 24px;\">\n    {% assign all_tags = site.docs | map: \"tags\" | join: \",\" | default: \"\" | split: \",\" | uniq | sort %}\n    {% for tag in all_tags %}\n      {% if tag != \"\" %}\n        <span style=\"display: inline-block; padding: 6px 12px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 999px; border: 1px solid var(--accent-primary); font-size: 13px; cursor: pointer;\" onclick=\"document.location.href='{{ '/docs/' | relative_url }}?filter={{ tag }}'\">\n          #{{ tag }}\n        </span>\n      {% endif %}\n    {% endfor %}\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>📂 Browse by Category</h2>\n  <div class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px;\">\n    <a class=\"card\" href=\"{{ '/docs/category/setup/' | relative_url }}\" style=\"text-decoration: none;\">\n      <h3>⚙️ Setup</h3>\n      <p class=\"muted\">Installation and configuration guides</p>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/styling/' | relative_url }}\" style=\"text-decoration: none;\">\n      <h3>🎨 Styling</h3>\n      <p class=\"muted\">Theming and customization</p>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/user-guide/' | relative_url }}\" style=\"text-decoration: none;\">\n      <h3>📖 User Guide</h3>\n      <p class=\"muted\">For end users and managers</p>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/community/' | relative_url }}\" style=\"text-decoration: none;\">\n      <h3>🤝 Community</h3>\n      <p class=\"muted\">Contributing and support</p>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/developer/' | relative_url }}\" style=\"text-decoration: none;\">\n      <h3>💻 Developer</h3>\n      <p class=\"muted\">Technical reference</p>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/help/' | relative_url }}\" style=\"text-decoration: none;\">\n      <h3>❓ Help</h3>\n      <p class=\"muted\">FAQ and troubleshooting</p>\n    </a>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>🔍 Quick Search</h2>\n  <p class=\"muted\">Use the <a href=\"{{ '/docs/' | relative_url }}\">main documentation page</a> to search and filter all guides by keyword or category.</p>\n</section>\n","<section class=\"section\">\n  <h1>Terms of Use</h1>\n  <p class=\"muted\">Guidelines for using this site and its content.</p>\n\n  <h2>Content</h2>\n  <ul>\n    <li>Downloads link to Modrinth or other platforms; their licenses govern use.</li>\n    <li>Site content is provided \"as is\" without warranties.</li>\n  </ul>\n\n  <h2>Acceptable use</h2>\n  <ul>\n    <li>Do not misuse the site, attempt to break security, or scrape abusively.</li>\n    <li>Respect the licenses of each mod, pack, or resource.</li>\n  </ul>\n\n  <h2>Attribution</h2>\n  <p>Credit the project authors as listed on their respective pages and licenses.</p>\n\n  <h2>Contact</h2>\n  <p>Questions? <a href=\"{{ '/contact/' | relative_url }}\">Contact us</a>.</p>\n</section>\n","# Testing & Validation Checklist\n\n## 1. Polish & Preloader Testing\n\n### Preloader Functionality\n- [ ] Preloader appears on page load\n- [ ] Preloader spinner animates smoothly\n- [ ] Preloader hides after page content loads\n- [ ] No content visible behind preloader during load\n\n### Responsive Scaling\n- [ ] Hero section scales properly on mobile (320px)\n- [ ] Navigation responsive at tablet (768px) and desktop (1200px)\n- [ ] Typography scales fluidly using clamp()\n- [ ] Grid gaps adjust based on viewport width\n- [ ] Buttons and cards maintain proper spacing on all screens\n\n### Cross-browser Testing\n- [ ] Chrome/Chromium: Full functionality\n- [ ] Firefox: Full functionality\n- [ ] Safari: Full functionality\n- [ ] Mobile Safari: Responsive and preloader works\n- [ ] Edge: Full functionality\n\n---\n\n## 2. Theme Toggle & Animations\n\n### Dark/Light Mode Toggle\n- [ ] Toggle button appears in nav\n- [ ] Dark mode applies correct CSS variables\n- [ ] Light mode applies correct CSS variables\n- [ ] Theme preference persists in localStorage\n- [ ] System preference detected on first visit\n- [ ] Respects prefers-color-scheme\n- [ ] Both themes have sufficient contrast\n\n### Enhanced Animations\n- [ ] Card entries animate on page load\n- [ ] Stat cards stagger animation works\n- [ ] Button ripple effect on click\n- [ ] Smooth scroll behavior enabled\n- [ ] Page transitions fade smoothly\n- [ ] Focus states visible and animated\n\n---\n\n## 3. Performance Optimization\n\n### Lazy Loading\n- [ ] Images load only when scrolled into view\n- [ ] Fallback works for older browsers\n- [ ] Performance impact measured\n\n### Resource Optimization\n- [ ] Critical CSS inlined in head\n- [ ] Non-critical CSS deferred\n- [ ] JavaScript split and loaded asynchronously\n- [ ] Unused styles removed\n- [ ] Images optimized and compressed\n\n### Scroll to Top Button\n- [ ] Button appears after scrolling 300px down\n- [ ] Button scrolls page smoothly to top\n- [ ] Button disappears when at top\n- [ ] Keyboard accessible (Enter/Space)\n\n---\n\n## 4. SEO & Content Structure\n\n### Sitemap & Robots\n- [ ] sitemap.xml generates correctly\n- [ ] robots.txt blocks aggressive crawlers\n- [ ] Canonical URLs set on all pages\n- [ ] Meta descriptions present\n\n### Schema Markup\n- [ ] Organization schema correct\n- [ ] Breadcrumb schema renders properly\n- [ ] Article/Page schema includes date\n- [ ] Schema validates with Google SDTT\n\n### Heading Hierarchy\n- [ ] H1 only appears once per page\n- [ ] Heading levels flow logically\n- [ ] Headings use semantic HTML\n\n---\n\n## 5. Accessibility (a11y)\n\n### WCAG 2.1 Compliance\n- [ ] Color contrast meets AA standard (4.5:1 for text)\n- [ ] All buttons and links keyboard accessible\n- [ ] Focus states visible\n- [ ] Skip to main content link works\n\n### Keyboard Navigation\n- [ ] Tab through all interactive elements\n- [ ] Enter/Space activates buttons\n- [ ] Escape closes modals\n- [ ] Focus order logical\n\n### Screen Reader Testing\n- [ ] Page structure announced properly\n- [ ] Images have alt text or are decorative (role=\"presentation\")\n- [ ] Form labels associated with inputs\n- [ ] ARIA labels on icon-only buttons\n- [ ] Live regions for dynamic content\n\n### Responsive Text\n- [ ] Text resizes with browser zoom (150%)\n- [ ] No horizontal scroll at 200% zoom\n- [ ] Text remains readable\n\n### Motion & Animation\n- [ ] Animations respect prefers-reduced-motion\n- [ ] Critical content not animation-dependent\n- [ ] No auto-playing media\n\n---\n\n## 6. Mobile & Touch Testing\n\n### Touch Targets\n- [ ] All buttons minimum 44x44px\n- [ ] Touch targets have adequate spacing\n- [ ] No accidental click overlap\n\n### Viewport Testing\n- [ ] Mobile (320px, 375px, 414px)\n- [ ] Tablet (768px, 1024px)\n- [ ] Desktop (1440px, 1920px, 4K)\n\n### Performance on Mobile\n- [ ] Page loads in < 3s on 4G\n- [ ] Preloader doesn't block interaction\n- [ ] Navigation doesn't cover content\n\n---\n\n## Performance Metrics\n\n### Core Web Vitals\n- [ ] LCP (Largest Contentful Paint): < 2.5s\n- [ ] FID (First Input Delay): < 100ms\n- [ ] CLS (Cumulative Layout Shift): < 0.1\n\n### Additional Metrics\n- [ ] First Contentful Paint: < 1.8s\n- [ ] Time to Interactive: < 3.8s\n- [ ] Total Blocking Time: < 200ms\n\n### Lighthouse Score\n- [ ] Performance: > 90\n- [ ] Accessibility: > 95\n- [ ] Best Practices: > 90\n- [ ] SEO: > 95\n\n---\n\n## Testing Tools\n\n### Online Tools\n- [Google PageSpeed Insights](https://pagespeed.web.dev/)\n- [Google Mobile-Friendly Test](https://search.google.com/test/mobile-friendly)\n- [Schema.org Structured Data Tester](https://validator.schema.org/)\n- [WAVE Accessibility Checker](https://wave.webaim.org/)\n- [Lighthouse CI](https://github.com/GoogleChrome/lighthouse-ci)\n\n### Browser DevTools\n- Chrome DevTools Lighthouse\n- Firefox Accessibility Inspector\n- Safari Accessibility Inspector\n\n---\n\n## Sign-off\n\n- [ ] All tests passed\n- [ ] No critical issues\n- [ ] Accessibility approved\n- [ ] Performance validated\n- [ ] SEO optimized\n- [ ] Ready for production\n\n**Date Tested:** _______________  \n**Tested By:** _______________  \n**Approved By:** _______________\n","<?xml version=\"1.0\" encoding=\"utf-8\"?>{% if page.xsl %}<?xml-stylesheet type=\"text/xml\" href=\"{{ '/feed.xslt.xml' | absolute_url }}\"?>{% endif %}<feed xmlns=\"http://www.w3.org/2005/Atom\" {% if site.lang %}xml:lang=\"{{ site.lang }}\"{% endif %}><generator uri=\"https://jekyllrb.com/\" version=\"{{ jekyll.version }}\">Jekyll</generator><link href=\"{{ page.url | absolute_url }}\" rel=\"self\" type=\"application/atom+xml\" /><link href=\"{{ '/' | absolute_url }}\" rel=\"alternate\" type=\"text/html\" {% if site.lang %}hreflang=\"{{ site.lang }}\" {% endif %}/><updated>{{ site.time | date_to_xmlschema }}</updated><id>{{ page.url | absolute_url | xml_escape }}</id>{% assign title = site.title | default: site.name %}{% if page.collection != \"posts\" %}{% assign collection = page.collection | capitalize %}{% assign title = title | append: \" | \" | append: collection %}{% endif %}{% if page.category %}{% assign category = page.category | capitalize %}{% assign title = title | append: \" | \" | append: category %}{% endif %}{% if title %}<title type=\"html\">{{ title | smartify | xml_escape }}</title>{% endif %}{% if site.description %}<subtitle>{{ site.description | xml_escape }}</subtitle>{% endif %}{% if site.author %}<author><name>{{ site.author.name | default: site.author | xml_escape }}</name>{% if site.author.email %}<email>{{ site.author.email | xml_escape }}</email>{% endif %}{% if site.author.uri %}<uri>{{ site.author.uri | xml_escape }}</uri>{% endif %}</author>{% endif %}{% if page.tags %}{% assign posts = site.tags[page.tags] %}{% else %}{% assign posts = site[page.collection] %}{% endif %}{% if page.category %}{% assign posts = posts | where: \"categories\", page.category %}{% endif %}{% unless site.show_drafts %}{% assign posts = posts | where_exp: \"post\", \"post.draft != true\" %}{% endunless %}{% assign posts = posts | sort: \"date\" | reverse %}{% assign posts_limit = site.feed.posts_limit | default: 10 %}{% for post in posts limit: posts_limit %}<entry{% if post.lang %}{{\" \"}}xml:lang=\"{{ post.lang }}\"{% endif %}>{% assign post_title = post.title | smartify | strip_html | normalize_whitespace | xml_escape %}<title type=\"html\">{{ post_title }}</title><link href=\"{{ post.url | absolute_url }}\" rel=\"alternate\" type=\"text/html\" title=\"{{ post_title }}\" /><published>{{ post.date | date_to_xmlschema }}</published><updated>{{ post.last_modified_at | default: post.date | date_to_xmlschema }}</updated><id>{{ post.id | absolute_url | xml_escape }}</id>{% assign excerpt_only = post.feed.excerpt_only | default: site.feed.excerpt_only %}{% unless excerpt_only %}<content type=\"html\" xml:base=\"{{ post.url | absolute_url | xml_escape }}\"><![CDATA[{{ post.content | strip }}]]></content>{% endunless %}{% assign post_author = post.author | default: post.authors[0] | default: site.author %}{% assign post_author = site.data.authors[post_author] | default: post_author %}{% assign post_author_email = post_author.email | default: nil %}{% assign post_author_uri = post_author.uri | default: nil %}{% assign post_author_name = post_author.name | default: post_author %}<author><name>{{ post_author_name | default: \"\" | xml_escape }}</name>{% if post_author_email %}<email>{{ post_author_email | xml_escape }}</email>{% endif %}{% if post_author_uri %}<uri>{{ post_author_uri | xml_escape }}</uri>{% endif %}</author>{% if post.category %}<category term=\"{{ post.category | xml_escape }}\" />{% elsif post.categories %}{% for category in post.categories %}<category term=\"{{ category | xml_escape }}\" />{% endfor %}{% endif %}{% for tag in post.tags %}<category term=\"{{ tag | xml_escape }}\" />{% endfor %}{% assign post_summary = post.description | default: post.excerpt %}{% if post_summary and post_summary != empty %}<summary type=\"html\"><![CDATA[{{ post_summary | strip_html | normalize_whitespace }}]]></summary>{% endif %}{% assign post_image = post.image.path | default: post.image %}{% if post_image %}{% unless post_image contains \"://\" %}{% assign post_image = post_image | absolute_url %}{% endunless %}<media:thumbnail xmlns:media=\"http://search.yahoo.com/mrss/\" url=\"{{ post_image | xml_escape }}\" /><media:content medium=\"image\" url=\"{{ post_image | xml_escape }}\" xmlns:media=\"http://search.yahoo.com/mrss/\" />{% endif %}</entry>{% endfor %}</feed>"],"time":"2025-12-17 01:31:20 +0000","posts":["\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <title>Welcome to the Blog</title>\n    <meta\n      name=\"description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta\n      name=\"robots\"\n      content=\"index, follow\"\n    />\n\n    <!-- SEO Meta Tags -->\n          \n\n    <meta\n      property=\"og:title\"\n      content=\"Welcome to the Blog\"\n    />\n    <meta\n      property=\"og:description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta property=\"og:url\" content=\"https://abc-site.devvyy.xyz/blog/blog-test/\" />\n    <meta property=\"og:image\" content=\"https://abc-site.devvyy.xyz/assets/images/logo.svg\" />\n    <meta property=\"og:image:alt\" content=\"ABC Mods & Packs\" />\n    <meta property=\"og:type\" content=\"post\" />\n    <meta property=\"og:site_name\" content=\"ABC\" />\n    <meta\n      property=\"og:locale\"\n      content=\"en_US\"\n    />\n\n    <!-- hreflang tags for multilingual SEO -->\n    <link\n      rel=\"alternate\"\n      hreflang=\"en\"\n      href=\"https://abc-site.devvyy.xyz/blog/blog-test/\"\n    />\n    <link\n      rel=\"alternate\"\n      hreflang=\"fr\"\n      href=\"https://abc-site.devvyy.xyz/fr/blog/blog-test/\"\n    />\n    <link\n      rel=\"alternate\"\n      hreflang=\"x-default\"\n      href=\"https://abc-site.devvyy.xyz/blog/blog-test/\"\n    />\n\n    <!-- Twitter Card -->\n    <meta name=\"twitter:card\" content=\"summary_large_image\" />\n    <meta\n      name=\"twitter:title\"\n      content=\"Welcome to the Blog\"\n    />\n    <meta\n      name=\"twitter:description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta\n      name=\"twitter:image\"\n      content=\"https://abc-site.devvyy.xyz/assets/images/logo.svg\"\n    />\n    <meta name=\"twitter:image:alt\" content=\"ABC Mods & Packs\" />\n    <meta\n      name=\"twitter:creator\"\n      content=\"@devvyyxyz\"\n    />\n    <meta\n      name=\"twitter:site\"\n      content=\"@devvyyxyz\"\n    />\n\n    <meta\n      name=\"theme-color\"\n      content=\"#1bd96f\"\n    />\n\n    <!-- Favicon -->\n    <link\n      rel=\"icon\"\n      type=\"image/svg+xml\"\n      href=\"/favicon.svg\"\n    />\n    <link\n      rel=\"icon\"\n      type=\"image/x-icon\"\n      href=\"/favicon.svg\"\n    />\n    <link\n      rel=\"apple-touch-icon\"\n      href=\"/assets/images/logo.svg\"\n    />\n\n    <!-- Google Fonts - Preload -->\n    <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n    <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n    <link\n      rel=\"preload\"\n      as=\"style\"\n      href=\"https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap\"\n    />\n    <link\n      href=\"https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap\"\n      rel=\"stylesheet\"\n    />\n\n    <!-- Font Awesome Icons - Async load -->\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <noscript>\n      <link\n        rel=\"stylesheet\"\n        href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n      />\n    </noscript>\n\n    <!-- Stylesheets - Critical -->\n    <link rel=\"stylesheet\" href=\"/assets/css/root.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/layout.css\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/loading.css\"\n    />\n\n    <!-- Stylesheets - Deferred (non-critical) -->\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/components.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/modpacks.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/animations.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/theme.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/a11y.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/visual-enhancements.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/mobile.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <noscript>\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/components.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/modpacks.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/animations.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/theme.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/a11y.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/visual-enhancements.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/mobile.css\"\n      />\n    </noscript>\n\n    <!-- Canonical URL -->\n    <link rel=\"canonical\" href=\"https://abc-site.devvyy.xyz/blog/blog-test/\" />\n\n    <!-- Schema Markup -->\n    <!-- Schema.org JSON-LD -->\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"Organization\",\n    \"name\": \"ABC\",\n    \"description\": \"Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins.\",\n    \"url\": \"https://abc-site.devvyy.xyz\",\n    \"logo\": \"https://abc-site.devvyy.xyz/assets/images/logo.svg\",\n    \"sameAs\": [\n      \"https://github.com/devvyyxyz\",\n      \"https://twitter.com/devvyyxyz\",\n      \"https://dc.gg/devvyyxyz\"\n    ],\n    \"contactPoint\": {\n      \"@type\": \"ContactPoint\",\n      \"contactType\": \"Community Support\",\n      \"url\": \"https://dc.gg/devvyyxyz\"\n    }\n  }\n</script>\n\n<!-- Breadcrumb Schema -->\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"BreadcrumbList\",\n    \"itemListElement\": [\n      {\n        \"@type\": \"ListItem\",\n        \"position\": 1,\n        \"name\": \"Home\",\n        \"item\": \"https://abc-site.devvyy.xyz\"\n      }\n      \n      , {\n        \"@type\": \"ListItem\",\n        \"position\": 2,\n        \"name\": \"Welcome to the Blog\",\n        \"item\": \"https://abc-site.devvyy.xyz/blog/blog-test/\"\n      }\n      \n    ]\n  }\n</script>\n\n<!-- Project/Software Application Schema (for project pages) -->\n\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"Article\",\n    \"headline\": \"Welcome to the Blog\",\n    \"description\": \"Kicking off our new blog — what's coming next.\",\n    \"image\": \"\",\n    \"datePublished\": \"2025-12-16T00:00:00+00:00\",\n    \"dateModified\": \"2025-12-16T00:00:00+00:00\",\n    \"author\": {\n      \"@type\": \"Organization\",\n      \"name\": \"ABC\"\n    },\n    \"publisher\": {\n      \"@type\": \"Organization\",\n      \"name\": \"ABC\",\n      \"logo\": {\n        \"@type\": \"ImageObject\",\n        \"url\": \"https://abc-site.devvyy.xyz/assets/images/logo.svg\"\n      }\n    }\n  }\n</script>\n<!-- WebPage Schema -->\n\n\n\n    <!-- Preloader Script (critical, inline) -->\n    <script>\n      (function () {\n        if (!document.body) return; // Exit if body not ready yet\n\n        const isDarkMode =\n          window.matchMedia &&\n          window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n        const bgColor = isDarkMode ? \"#0d0d0d\" : \"#f6fbfa\";\n        document.documentElement.style.backgroundColor = bgColor;\n        document.body.style.backgroundColor = bgColor;\n\n        const overlay = document.createElement(\"div\");\n        overlay.className = \"loading-overlay\";\n        overlay.id = \"loading-overlay\";\n        overlay.innerHTML = '<div class=\"spinner\"></div>';\n        document.body.appendChild(overlay);\n\n        if (document.readyState === \"loading\") {\n          document.addEventListener(\"DOMContentLoaded\", hidePreloader);\n        } else {\n          hidePreloader();\n        }\n\n        function hidePreloader() {\n          const preloader = document.getElementById(\"loading-overlay\");\n          if (preloader) {\n            preloader.classList.add(\"hidden\");\n          }\n        }\n\n        window.hidePreloader = hidePreloader;\n      })();\n    </script>\n  </head>\n  <body>\n    <a href=\"#main\" class=\"skip-to-main\">Skip to main content</a>\n    <header class=\"floating-nav\">\n  <div class=\"nav-inner\">\n    <a\n      class=\"logo\"\n      href=\"/\"\n      style=\"display: flex; align-items: center; gap: 8px\"\n      aria-label=\"ABC\"\n    >\n      <img\n        src=\"/assets/images/logo.svg\"\n        alt=\"ABC\"\n        style=\"height: 32px; width: auto\"\n      />\n      \n    </a>\n    <button\n      class=\"mobile-menu-toggle\"\n      aria-label=\"Toggle menu\"\n      id=\"mobile-menu-toggle\"\n    >\n      <i class=\"fas fa-bars\"></i>\n    </button>\n    <nav class=\"links\" id=\"mobile-nav\">\n      <a href=\"/\">Home</a>\n      <a href=\"/about/\">About</a>\n      <a href=\"/docs/\">Docs</a>\n      <a href=\"/changelog/\">Changelog</a>\n      <a href=\"/blog/\">Blog</a>\n      <div class=\"nav-dropdown\">\n        <a href=\"/projects/\" class=\"dropdown-toggle\">\n          Projects <i class=\"fas fa-chevron-down\"></i>\n        </a>\n        <div class=\"dropdown-menu\">\n          <a href=\"/projects/\">All Projects</a>\n          <a href=\"/compare/\"\n            ><i class=\"fas fa-balance-scale\"></i> Compare Modpacks</a\n          >\n          <a href=\"/changelog/\"\n            ><i class=\"fas fa-rocket\"></i> Releases & Changelog</a\n          >\n        </div>\n      </div>\n      <div class=\"nav-dropdown\">\n        <a href=\"#\" class=\"dropdown-toggle\">\n          Legal <i class=\"fas fa-chevron-down\"></i>\n        </a>\n        <div class=\"dropdown-menu\">\n          <a href=\"/privacy/\">Privacy Policy</a>\n          <a href=\"/terms/\">Terms of Service</a>\n          <a href=\"/cookie-policy/\">Cookie Policy</a>\n          <a href=\"/licensing/\">Licensing</a>\n          <a href=\"/eula/\">EULA</a>\n          <a href=\"/disclaimer/\">Disclaimer</a>\n        </div>\n      </div>\n      <a\n        href=\"https://modrinth.com/organization/abcxyz\"\n        target=\"_blank\"\n        rel=\"noopener\"\n        >Organization</a\n      >\n    </nav>\n    <div class=\"nav-actions\">\n      <div\n        id=\"social-links-nav\"\n        style=\"display: flex; gap: 6px; align-items: center\"\n      ></div>\n      <!-- Theme Toggle -->\n<div class=\"theme-toggle\" id=\"theme-toggle\" title=\"Toggle dark/light mode\">\n  <button id=\"theme-dark\" class=\"active\" aria-label=\"Dark mode\" title=\"Dark mode\">\n    <i class=\"fa-solid fa-moon\"></i>\n  </button>\n  <button id=\"theme-light\" aria-label=\"Light mode\" title=\"Light mode\">\n    <i class=\"fa-solid fa-sun\"></i>\n  </button>\n</div>\n\n<script>\n  // Theme toggle functionality\n  const themeToggle = {\n    init() {\n      this.darkBtn = document.getElementById('theme-dark');\n      this.lightBtn = document.getElementById('theme-light');\n      this.html = document.documentElement;\n\n      // Load saved theme or use system preference\n      const saved = localStorage.getItem('theme');\n      const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;\n      const theme = saved || (systemDark ? 'dark' : 'light');\n\n      this.setTheme(theme);\n\n      // Listen for changes\n      this.darkBtn.addEventListener('click', () => this.setTheme('dark'));\n      this.lightBtn.addEventListener('click', () => this.setTheme('light'));\n\n      // Listen for system theme changes\n      window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {\n        if (!localStorage.getItem('theme')) {\n          this.setTheme(e.matches ? 'dark' : 'light');\n        }\n      });\n    },\n\n    setTheme(theme) {\n      this.html.setAttribute('data-theme', theme);\n      localStorage.setItem('theme', theme);\n\n      this.darkBtn.classList.toggle('active', theme === 'dark');\n      this.lightBtn.classList.toggle('active', theme === 'light');\n\n      // Update meta theme-color\n      const color = theme === 'dark' ? '#1bd96f' : '#1bd96f';\n      document.querySelector('meta[name=\"theme-color\"]').setAttribute('content', color);\n    }\n  };\n\n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', () => themeToggle.init());\n  } else {\n    themeToggle.init();\n  }\n</script>\n\n    </div>\n  </div>\n</header>\n\n<script>\n  // Mobile menu toggle\n  document.addEventListener(\"DOMContentLoaded\", () => {\n    const toggle = document.getElementById(\"mobile-menu-toggle\");\n    const nav = document.getElementById(\"mobile-nav\");\n\n    if (toggle && nav) {\n      toggle.addEventListener(\"click\", () => {\n        nav.classList.toggle(\"mobile-open\");\n        const icon = toggle.querySelector(\"i\");\n        if (nav.classList.contains(\"mobile-open\")) {\n          icon.classList.remove(\"fa-bars\");\n          icon.classList.add(\"fa-times\");\n        } else {\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        }\n      });\n\n      // Close menu when clicking a link\n      nav.querySelectorAll(\"a\").forEach((link) => {\n        link.addEventListener(\"click\", () => {\n          nav.classList.remove(\"mobile-open\");\n          const icon = toggle.querySelector(\"i\");\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        });\n      });\n\n      // Close menu when clicking outside\n      document.addEventListener(\"click\", (e) => {\n        if (!toggle.contains(e.target) && !nav.contains(e.target)) {\n          nav.classList.remove(\"mobile-open\");\n          const icon = toggle.querySelector(\"i\");\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        }\n      });\n    }\n  });\n</script>\n\n\n    <main id=\"main\" class=\"container\"><main class=\"content\">\n  <article class=\"post\" style=\"max-width: 820px; margin: 0 auto; padding: 24px\">\n    <header>\n      <h1 style=\"margin: 0 0 8px\">Welcome to the Blog</h1>\n      <p class=\"muted\" style=\"margin: 0 0 16px\">\n        December 16, 2025 • ABC Team\n      </p>\n    </header>\n    <section class=\"post-body\"><p>We’re launching a blog to share updates, release notes, and behind-the-scenes dev logs.</p>\n\n<!--more-->\n\n<p>What you can expect:</p>\n\n<ul>\n  <li>Deep dives into mods, datapacks, and plugins</li>\n  <li>Roadmap updates and upcoming releases</li>\n  <li>Performance tips and compatibility notes</li>\n  <li>Community showcases and contributions</li>\n</ul>\n\n<p>If you have topics you’d like us to cover, let us know on the contact page or Discord.</p>\n</section>\n\n    \n    <footer style=\"margin-top: 24px\">\n      <strong>Tags:</strong>\n      \n      <span\n        style=\"\n          display: inline-block;\n          padding: 4px 8px;\n          border: 1px solid var(--border);\n          border-radius: 999px;\n          margin-right: 6px;\n          font-size: 12px;\n        \"\n        >#announcement</span\n      >\n      \n      <span\n        style=\"\n          display: inline-block;\n          padding: 4px 8px;\n          border: 1px solid var(--border);\n          border-radius: 999px;\n          margin-right: 6px;\n          font-size: 12px;\n        \"\n        >#roadmap</span\n      >\n       \n      <div style=\"margin-top: 8px\">\n        <strong>Categories:</strong>\n        \n        <span\n          style=\"\n            display: inline-block;\n            padding: 4px 8px;\n            border: 1px solid var(--border);\n            border-radius: 999px;\n            margin-right: 6px;\n            font-size: 12px;\n          \"\n          >updates</span\n        >\n        \n      </div>\n      \n    </footer>\n    \n  </article>\n</main>\n</main>\n\n    <footer class=\"floating-footer\">\n  <div class=\"footer-inner\">\n    <div style=\"display: flex; gap: 16px; align-items: flex-start\">\n      <img\n        src=\"/assets/images/logo.svg\"\n        alt=\"ABC logo\"\n        style=\"height: 100px; flex-shrink: 0; width: auto\"\n        width=\"100\"\n        height=\"100\"\n      />\n      <div style=\"display: flex; flex-direction: column; gap: 8px\">\n        <div>\n          <h4\n            style=\"\n              margin: 0;\n              font-size: 18px;\n              font-weight: 700;\n              color: var(--text);\n            \"\n          >\n            ABC\n          </h4>\n          <p\n            style=\"\n              margin: 2px 0 0 0;\n              font-size: 12px;\n              color: var(--text-secondary);\n            \"\n          >\n            Established 2025\n          </p>\n        </div>\n        <p\n          style=\"\n            margin: 0;\n            font-size: 13px;\n            color: var(--text-secondary);\n            line-height: 1.6;\n          \"\n        >\n          Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins.\n        </p>\n      </div>\n    </div>\n    <div style=\"display: flex; gap: 48px\">\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Links\n        </h4>\n        <div\n          style=\"\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n            gap: 10px 12px;\n            font-size: 13px;\n            max-width: 320px;\n          \"\n        >\n          <a\n            href=\"/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Home</a\n          >\n          <a\n            href=\"/about/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >About</a\n          >\n          <a\n            href=\"/docs/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Docs</a\n          >\n          <a\n            href=\"/projects/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Projects</a\n          >\n          <a\n            href=\"/compare/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Compare</a\n          >\n          <a\n            href=\"/changelog/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Changelog</a\n          >\n          <a\n            href=\"https://modrinth.com/organization/abcxyz\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            target=\"_blank\"\n            rel=\"noopener\"\n            >Modrinth Org</a\n          >\n          <a\n            href=\"https://github.com/devvyyxyz\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            target=\"_blank\"\n            rel=\"noopener\"\n            >GitHub Org</a\n          >\n          <a\n            href=\"/sitemap.xml\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Sitemap</a\n          >\n          <a\n            href=\"/feed.xml\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >RSS Feed</a\n          >\n          <a\n            href=\"/blog/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Blog</a\n          >\n        </div>\n      </div>\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Help\n        </h4>\n        <div\n          style=\"\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n            gap: 10px 12px;\n            font-size: 13px;\n            max-width: 320px;\n          \"\n        >\n          <a\n            href=\"/contact/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Contact</a\n          >\n          <a\n            href=\"/docs/faq/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >FAQ</a\n          >\n          <a\n            href=\"/docs/troubleshooting/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Troubleshooting</a\n          >\n          <a\n            href=\"/docs/contributing/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Contributing</a\n          >\n          <a\n            href=\"/status/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Status</a\n          >\n        </div>\n      </div>\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Community\n        </h4>\n        <div\n          id=\"social-links-footer\"\n          style=\"display: flex; gap: 12px; flex-direction: column\"\n        ></div>\n      </div>\n    </div>\n  </div>\n  <div\n    style=\"\n      border-top: 1px solid var(--border);\n      margin-top: 32px;\n      padding-top: 24px;\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      font-size: 12px;\n      color: var(--text-secondary);\n      flex-wrap: wrap;\n      gap: 16px;\n    \"\n  >\n    <div style=\"display: flex; gap: 16px; align-items: center; flex-wrap: wrap\">\n      <div>\n        © <span id=\"year\"></span> ABC. All rights reserved.\n      </div>\n      <div\n        id=\"language-switcher\"\n        style=\"display: flex; gap: 8px; align-items: center\"\n      >\n        <span style=\"font-size: 12px; color: var(--text-secondary)\"\n          >Language:</span\n        >\n        <select\n          id=\"lang-select\"\n          style=\"\n            padding: 4px 8px;\n            border: 1px solid var(--border);\n            border-radius: var(--radius);\n            background: var(--bg-secondary);\n            color: var(--text);\n            font-size: 12px;\n            cursor: pointer;\n          \"\n        >\n          <option value=\"en\">English</option>\n          <option value=\"fr\">Français</option>\n        </select>\n      </div>\n    </div>\n    <div style=\"display: flex; gap: 20px\">\n      <a\n        href=\"/privacy/\"\n        style=\"\n          color: var(--text-secondary);\n          text-decoration: none;\n          transition: color 0.2s;\n        \"\n        >Privacy</a\n      >\n      <a\n        href=\"/terms/\"\n        style=\"\n          color: var(--text-secondary);\n          text-decoration: none;\n          transition: color 0.2s;\n        \"\n        >Terms</a\n      >\n    </div>\n  </div>\n</footer>\n\n<script>\n  // Social links configuration\n  const socials = {\n    github: {\n      name: \"GitHub\",\n      icon: \"fab fa-github\",\n      url: \"https://github.com/devvyyxyz\",\n    },\n    twitter: {\n      name: \"Twitter\",\n      icon: \"fab fa-x-twitter\",\n      url: \"https://twitter.com/devvyyxyz\",\n    },\n    discord: {\n      name: \"Discord\",\n      icon: \"fab fa-discord\",\n      url: \"https://dc.gg/devvyyxyz\",\n    },\n  };\n\n  function renderSocialLinks() {\n    const navContainer = document.getElementById(\"social-links-nav\");\n    const footerContainer = document.getElementById(\"social-links-footer\");\n\n    Object.entries(socials).forEach(([key, social]) => {\n      if (social.url && social.url.trim()) {\n        // Nav icon button\n        const navLink = document.createElement(\"a\");\n        navLink.href = social.url;\n        navLink.target = \"_blank\";\n        navLink.rel = \"noopener\";\n        navLink.title = social.name;\n        navLink.style.cssText =\n          \"display:flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:var(--radius);background:var(--bg-secondary);color:var(--text-secondary);text-decoration:none;font-size:16px;transition:all 0.2s ease;border:1px solid var(--border)\";\n        const icon = document.createElement(\"i\");\n        icon.className = social.icon;\n        icon.style.fontSize = \"18px\";\n        navLink.appendChild(icon);\n        navLink.onmouseover = () => {\n          navLink.style.background = \"var(--accent-primary)\";\n          navLink.style.color = \"#000000\";\n          navLink.style.borderColor = \"var(--accent-primary)\";\n        };\n        navLink.onmouseout = () => {\n          navLink.style.background = \"var(--bg-secondary)\";\n          navLink.style.color = \"var(--text-secondary)\";\n          navLink.style.borderColor = \"var(--border)\";\n        };\n        if (navContainer) navContainer.appendChild(navLink);\n\n        // Footer text link with icon\n        const footerLink = document.createElement(\"a\");\n        footerLink.href = social.url;\n        footerLink.target = \"_blank\";\n        footerLink.rel = \"noopener\";\n        footerLink.style.cssText =\n          \"display:flex;align-items:center;gap:8px;color:var(--text-secondary);text-decoration:none;transition:color 0.2s;font-size:13px\";\n        const footerIcon = document.createElement(\"i\");\n        footerIcon.className = social.icon;\n        footerIcon.style.width = \"16px\";\n        const footerText = document.createElement(\"span\");\n        footerText.textContent = social.name;\n        footerLink.appendChild(footerIcon);\n        footerLink.appendChild(footerText);\n        footerLink.onmouseover = () => {\n          footerLink.style.color = \"var(--accent-primary)\";\n        };\n        footerLink.onmouseout = () => {\n          footerLink.style.color = \"var(--text-secondary)\";\n        };\n        if (footerContainer) footerContainer.appendChild(footerLink);\n      }\n    });\n  }\n\n  document.addEventListener(\"DOMContentLoaded\", renderSocialLinks);\n\n  // Set year in footer\n  document.getElementById(\"year\").textContent = new Date().getFullYear();\n\n  // Language switcher\n  const langSelect = document.getElementById(\"lang-select\");\n  if (langSelect) {\n    const currentLang = 'en';\n    langSelect.value = currentLang;\n\n    langSelect.addEventListener(\"change\", (e) => {\n      const selectedLang = e.target.value;\n      const currentPath = window.location.pathname;\n      const baseUrl = \"\";\n\n      // Remove existing language prefix\n      let cleanPath = currentPath.replace(baseUrl, \"\");\n      cleanPath = cleanPath.replace(/^\\/(en|fr)/, \"\");\n\n      // Build new URL\n      const newPath =\n        selectedLang === \"en\"\n          ? baseUrl + cleanPath\n          : baseUrl + \"/\" + selectedLang + cleanPath;\n\n      window.location.href = newPath;\n    });\n  }\n</script>\n <!-- Scroll to top button -->\n<button id=\"scroll-to-top\" class=\"scroll-to-top\" aria-label=\"Scroll to top\" title=\"Back to top\">\n  <i class=\"fa-solid fa-chevron-up\"></i>\n</button>\n\n<script>\n  // Scroll to top functionality\n  const scrollButton = document.getElementById('scroll-to-top');\n\n  window.addEventListener('scroll', () => {\n    if (window.scrollY > 300) {\n      scrollButton.classList.add('visible');\n    } else {\n      scrollButton.classList.remove('visible');\n    }\n  });\n\n  scrollButton.addEventListener('click', () => {\n    window.scrollTo({ top: 0, behavior: 'smooth' });\n  });\n\n  // Handle keyboard interaction\n  scrollButton.addEventListener('keydown', (e) => {\n    if (e.key === 'Enter' || e.key === ' ') {\n      e.preventDefault();\n      window.scrollTo({ top: 0, behavior: 'smooth' });\n    }\n  });\n</script>\n\n<!-- Lazy loading images with placeholder -->\n<script>\n  // Intersection Observer for lazy loading\n  if ('IntersectionObserver' in window) {\n    const imageObserver = new IntersectionObserver((entries, observer) => {\n      entries.forEach(entry => {\n        if (entry.isIntersecting) {\n          const img = entry.target;\n          img.src = img.dataset.src || img.src;\n          img.classList.remove('lazy');\n          observer.unobserve(img);\n        }\n      });\n    }, {\n      rootMargin: '50px 0px',\n      threshold: 0.01\n    });\n\n    document.querySelectorAll('img[data-src]').forEach(img => {\n      imageObserver.observe(img);\n    });\n  }\n</script>\n\n<!-- Smooth page transitions -->\n<script>\n  // Add page transition class on load\n  document.addEventListener('DOMContentLoaded', () => {\n    document.body.classList.add('page-transition');\n  });\n\n  // Handle link clicks for smooth transitions\n  document.addEventListener('click', (e) => {\n    const link = e.target.closest('a');\n    if (link && !link.target && link.hostname === window.location.hostname) {\n      // Internal link - add transition\n      e.preventDefault();\n      document.body.style.opacity = '0.8';\n      setTimeout(() => {\n        window.location.href = link.href;\n      }, 150);\n    }\n  });\n</script>\n\n\n    <!-- Cookie Consent Banner -->\n    <div\n  id=\"cookie-consent\"\n  class=\"cookie-consent-banner\"\n  role=\"alertdialog\"\n  aria-labelledby=\"cookie-title\"\n  aria-describedby=\"cookie-description\"\n  style=\"display: none\"\n>\n  <div class=\"cookie-consent-content\">\n    <div class=\"cookie-consent-text\">\n      <h3 id=\"cookie-title\" class=\"cookie-consent-title\">\n          Cookie Preferences\n      </h3>\n      <p id=\"cookie-description\" class=\"cookie-consent-message\">\n        We use cookies to improve your experience and analyze site performance. No personal data is collected.\n      </p>\n      <p class=\"cookie-consent-subtext\">\n        <a\n          href=\"/privacy/\"\n          target=\"_blank\"\n          rel=\"noopener\"\n          >Privacy Policy</a\n        >\n      </p>\n    </div>\n    <div class=\"cookie-consent-actions\">\n      <button\n        id=\"cookie-manage\"\n        class=\"cookie-btn cookie-btn-manage\"\n        aria-label=\"Manage cookie preferences\"\n      >\n        Manage Preferences\n      </button>\n      <button\n        id=\"cookie-reject\"\n        class=\"cookie-btn cookie-btn-reject\"\n        aria-label=\"Reject cookies\"\n      >\n        Reject\n      </button>\n      <button\n        id=\"cookie-accept\"\n        class=\"cookie-btn cookie-btn-accept\"\n        aria-label=\"Accept all cookies\"\n      >\n        Accept All\n      </button>\n    </div>\n  </div>\n</div>\n\n<!-- Cookie Settings Modal -->\n<div\n  id=\"cookie-modal\"\n  class=\"cookie-modal\"\n  style=\"display: none\"\n  role=\"dialog\"\n  aria-labelledby=\"modal-title\"\n  aria-hidden=\"true\"\n>\n  <div class=\"cookie-modal-overlay\"></div>\n  <div class=\"cookie-modal-content\">\n    <div class=\"cookie-modal-header\">\n      <h2 id=\"modal-title\" class=\"cookie-modal-title\">Cookie Preferences</h2>\n      <button\n        id=\"modal-close\"\n        class=\"cookie-modal-close\"\n        aria-label=\"Close modal\"\n      >\n        <i class=\"fas fa-times\"></i>\n      </button>\n    </div>\n\n    <div class=\"cookie-modal-body\">\n      <!-- Categories -->\n      <div class=\"cookie-categories\">\n        <!-- Essential -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-essential\"\n                class=\"cookie-checkbox\"\n                checked\n                disabled\n              />\n              <span class=\"cookie-category-title\"\n                >Essential</span\n              >\n            </label>\n            <span class=\"cookie-badge essential\">Essential</span>\n          </div>\n          <p class=\"cookie-category-desc\">Required for core site functionality. Always enabled.</p>\n        </div>\n\n        <!-- Analytics -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-analytics\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Analytics</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Help us understand how you use our site to improve it.</p>\n          <details class=\"cookie-details\">\n            <summary>All Cookies</summary>\n            <div class=\"cookie-list\">\n              <div class=\"cookie-item\">\n                <span class=\"cookie-item-name\">_ga, _ga_*</span>\n                <span class=\"cookie-item-expiration\">2 years</span>\n              </div>\n              <div class=\"cookie-item\">\n                <span class=\"cookie-item-name\">_gat</span>\n                <span class=\"cookie-item-expiration\">1 minute</span>\n              </div>\n            </div>\n          </details>\n        </div>\n\n        <!-- Performance -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-performance\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Performance</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Improve page speed and user experience.</p>\n        </div>\n\n        <!-- Marketing -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-marketing\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Marketing</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Allow us to show you relevant content and offers.</p>\n        </div>\n      </div>\n\n      <div class=\"cookie-modal-footer-info\">\n        <small class=\"cookie-updated\"\n          >Last updated: December 11, 2025</small\n        >\n      </div>\n    </div>\n\n    <div class=\"cookie-modal-footer\">\n      <button id=\"modal-reject\" class=\"cookie-btn cookie-btn-reject\">\n        Reject\n      </button>\n      <button id=\"modal-save\" class=\"cookie-btn cookie-btn-accept\">\n        Save Preferences\n      </button>\n    </div>\n  </div>\n</div>\n\n<style>\n  .cookie-consent-banner {\n    position: fixed;\n    bottom: 0;\n    left: 0;\n    right: 0;\n    background: var(--bg-secondary);\n    border-top: 1px solid var(--border);\n    border-left: 3px solid var(--accent-primary);\n    padding: 20px;\n    z-index: 1000;\n    box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.15);\n    animation: slideUp 0.3s ease-out;\n  }\n\n  @keyframes slideUp {\n    from {\n      transform: translateY(100%);\n      opacity: 0;\n    }\n    to {\n      transform: translateY(0);\n      opacity: 1;\n    }\n  }\n\n  .cookie-consent-content {\n    max-width: 1200px;\n    margin: 0 auto;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    gap: 24px;\n    flex-wrap: wrap;\n  }\n\n  .cookie-consent-text {\n    flex: 1;\n    min-width: 280px;\n  }\n\n  .cookie-consent-title {\n    margin: 0 0 8px 0;\n    font-size: 16px;\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-consent-message {\n    margin: 0 0 8px 0;\n    font-size: 14px;\n    color: var(--text-secondary);\n    line-height: 1.5;\n  }\n\n  .cookie-consent-subtext {\n    margin: 8px 0 0 0;\n    font-size: 12px;\n    color: var(--text-secondary);\n  }\n\n  .cookie-consent-subtext a {\n    color: var(--accent-primary);\n    text-decoration: none;\n    font-weight: 500;\n  }\n\n  .cookie-consent-subtext a:hover {\n    text-decoration: underline;\n  }\n\n  .cookie-consent-actions {\n    display: flex;\n    gap: 12px;\n    flex-shrink: 0;\n  }\n\n  .cookie-btn {\n    padding: 8px 16px;\n    border-radius: var(--radius);\n    border: 1px solid var(--border);\n    font-size: 13px;\n    font-weight: 500;\n    cursor: pointer;\n    transition: all 0.2s ease;\n    white-space: nowrap;\n  }\n\n  .cookie-btn-manage {\n    background: var(--bg-primary);\n    color: var(--accent-primary);\n    border-color: var(--accent-primary);\n    font-weight: 600;\n  }\n\n  .cookie-btn-manage:hover {\n    background: var(--bg);\n    opacity: 0.9;\n  }\n\n  .cookie-btn-reject {\n    background: var(--bg-primary);\n    color: var(--text);\n    border-color: var(--border);\n  }\n\n  .cookie-btn-reject:hover {\n    background: var(--bg);\n    border-color: var(--text-secondary);\n  }\n\n  .cookie-btn-accept {\n    background: var(--accent-primary);\n    color: #000000;\n    border-color: var(--accent-primary);\n    font-weight: 600;\n  }\n\n  .cookie-btn-accept:hover {\n    opacity: 0.9;\n    transform: translateY(-1px);\n    box-shadow: 0 2px 8px rgba(27, 217, 111, 0.2);\n  }\n\n  .cookie-btn:active {\n    transform: translateY(0);\n  }\n\n  @media (max-width: 768px) {\n    .cookie-consent-banner {\n      padding: 16px;\n    }\n\n    .cookie-consent-content {\n      flex-direction: column;\n      gap: 16px;\n    }\n\n    .cookie-consent-actions {\n      width: 100%;\n      flex-direction: column;\n    }\n\n    .cookie-btn {\n      width: 100%;\n      padding: 10px 16px;\n    }\n  }\n\n  /* Modal Styles */\n  .cookie-modal {\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    z-index: 2000;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    animation: fadeIn 0.3s ease-out;\n  }\n\n  @keyframes fadeIn {\n    from {\n      opacity: 0;\n    }\n    to {\n      opacity: 1;\n    }\n  }\n\n  .cookie-modal-overlay {\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0, 0, 0, 0.5);\n    cursor: pointer;\n  }\n\n  .cookie-modal-content {\n    position: relative;\n    background: var(--bg-secondary);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n    max-width: 600px;\n    width: 90%;\n    max-height: 90vh;\n    overflow: auto;\n    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n    animation: slideIn 0.3s ease-out;\n  }\n\n  @keyframes slideIn {\n    from {\n      transform: scale(0.95);\n      opacity: 0;\n    }\n    to {\n      transform: scale(1);\n      opacity: 1;\n    }\n  }\n\n  .cookie-modal-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    padding: 24px;\n    border-bottom: 1px solid var(--border);\n  }\n\n  .cookie-modal-title {\n    margin: 0;\n    font-size: 20px;\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-modal-close {\n    background: none;\n    border: none;\n    color: var(--text-secondary);\n    font-size: 20px;\n    cursor: pointer;\n    padding: 0;\n    width: 32px;\n    height: 32px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    border-radius: var(--radius);\n    transition: all 0.2s;\n  }\n\n  .cookie-modal-close:hover {\n    background: var(--border);\n    color: var(--text);\n  }\n\n  .cookie-modal-body {\n    padding: 24px;\n  }\n\n  .cookie-categories {\n    display: flex;\n    flex-direction: column;\n    gap: 24px;\n    margin-bottom: 24px;\n  }\n\n  .cookie-category {\n    padding: 16px;\n    background: var(--bg-primary);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n  }\n\n  .cookie-category-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    margin-bottom: 8px;\n  }\n\n  .cookie-checkbox-label {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    cursor: pointer;\n    flex: 1;\n  }\n\n  .cookie-checkbox {\n    width: 18px;\n    height: 18px;\n    cursor: pointer;\n    accent-color: var(--accent-primary);\n  }\n\n  .cookie-checkbox:disabled {\n    opacity: 0.5;\n    cursor: not-allowed;\n  }\n\n  .cookie-category-title {\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-badge {\n    display: inline-block;\n    padding: 4px 8px;\n    border-radius: 4px;\n    font-size: 11px;\n    font-weight: 600;\n    text-transform: uppercase;\n    background: var(--accent-primary);\n    color: #000000;\n  }\n\n  .cookie-category-desc {\n    margin: 8px 0 0 28px;\n    font-size: 13px;\n    color: var(--text-secondary);\n    line-height: 1.5;\n  }\n\n  .cookie-details {\n    margin: 12px 0 0 28px;\n    cursor: pointer;\n  }\n\n  .cookie-details summary {\n    font-size: 12px;\n    color: var(--accent-primary);\n    font-weight: 500;\n    text-decoration: underline;\n    padding: 4px 0;\n  }\n\n  .cookie-details summary:hover {\n    opacity: 0.8;\n  }\n\n  .cookie-list {\n    margin-top: 8px;\n    padding: 8px;\n    background: var(--bg);\n    border-radius: 4px;\n    border: 1px solid var(--border);\n  }\n\n  .cookie-item {\n    display: flex;\n    justify-content: space-between;\n    font-size: 12px;\n    padding: 6px 0;\n    color: var(--text-secondary);\n    border-bottom: 1px solid var(--border);\n  }\n\n  .cookie-item:last-child {\n    border-bottom: none;\n  }\n\n  .cookie-item-name {\n    font-family: monospace;\n    font-weight: 500;\n    color: var(--text);\n  }\n\n  .cookie-item-expiration {\n    font-size: 11px;\n  }\n\n  .cookie-modal-footer-info {\n    margin-bottom: 16px;\n    padding-top: 16px;\n    border-top: 1px solid var(--border);\n  }\n\n  .cookie-updated {\n    font-size: 12px;\n    color: var(--text-secondary);\n  }\n\n  .cookie-modal-footer {\n    display: flex;\n    gap: 12px;\n    padding: 16px 24px;\n    border-top: 1px solid var(--border);\n    background: var(--bg-primary);\n    justify-content: flex-end;\n  }\n\n  .cookie-modal-footer .cookie-btn {\n    flex: 1;\n  }\n\n  @media (max-width: 640px) {\n    .cookie-modal-content {\n      width: 95%;\n      max-height: 95vh;\n    }\n\n    .cookie-modal-header {\n      padding: 16px;\n    }\n\n    .cookie-modal-body {\n      padding: 16px;\n    }\n\n    .cookie-modal-footer {\n      flex-direction: column;\n      padding: 16px;\n    }\n\n    .cookie-modal-footer .cookie-btn {\n      width: 100%;\n    }\n\n    .cookie-category-desc {\n      margin-left: 28px;\n    }\n\n    .cookie-details {\n      margin-left: 28px;\n    }\n  }\n</style>\n\n<script>\n  document.addEventListener(\"DOMContentLoaded\", () => {\n    const banner = document.getElementById(\"cookie-consent\");\n    const modal = document.getElementById(\"cookie-modal\");\n    const acceptBtn = document.getElementById(\"cookie-accept\");\n    const rejectBtn = document.getElementById(\"cookie-reject\");\n    const manageBtn = document.getElementById(\"cookie-manage\");\n    const modalClose = document.getElementById(\"modal-close\");\n    const modalOverlay = document.querySelector(\".cookie-modal-overlay\");\n    const modalRejectBtn = document.getElementById(\"modal-reject\");\n    const modalSaveBtn = document.getElementById(\"modal-save\");\n    const consentKey = \"abc-cookie-consent\";\n    const categoriesKey = \"abc-cookie-categories\";\n\n    // Preference checkboxes\n    const analyticsCheckbox = document.getElementById(\"cookie-analytics\");\n    const performanceCheckbox = document.getElementById(\"cookie-performance\");\n    const marketingCheckbox = document.getElementById(\"cookie-marketing\");\n\n    // Load saved preferences\n    const loadPreferences = () => {\n      const saved = localStorage.getItem(categoriesKey);\n      if (saved) {\n        const prefs = JSON.parse(saved);\n        analyticsCheckbox.checked = prefs.analytics || false;\n        performanceCheckbox.checked = prefs.performance || false;\n        marketingCheckbox.checked = prefs.marketing || false;\n      }\n    };\n\n    // Save preferences\n    const savePreferences = () => {\n      const prefs = {\n        analytics: analyticsCheckbox.checked,\n        performance: performanceCheckbox.checked,\n        marketing: marketingCheckbox.checked,\n      };\n      localStorage.setItem(categoriesKey, JSON.stringify(prefs));\n      localStorage.setItem(consentKey, \"custom\");\n      dismissBanner();\n      updateConsent(prefs);\n    };\n\n    // Dismiss banner with animation\n    const dismissBanner = () => {\n      banner.style.animation = \"slideDown 0.3s ease-out forwards\";\n      setTimeout(() => {\n        banner.style.display = \"none\";\n      }, 300);\n      modal.style.animation = \"fadeOut 0.3s ease-out forwards\";\n      setTimeout(() => {\n        modal.style.display = \"none\";\n      }, 300);\n    };\n\n    // Update analytics consent\n    const updateConsent = (prefs) => {\n      if (window.gtag) {\n        gtag(\"consent\", \"update\", {\n          analytics_storage: prefs.analytics ? \"granted\" : \"denied\",\n        });\n      }\n    };\n\n    // Check if user has already made a choice\n    const userConsent = localStorage.getItem(consentKey);\n\n    if (!userConsent) {\n      setTimeout(() => {\n        banner.style.display = \"flex\";\n      }, 1000);\n    }\n\n    loadPreferences();\n\n    // Accept all cookies\n    acceptBtn.addEventListener(\"click\", () => {\n      analyticsCheckbox.checked = true;\n      performanceCheckbox.checked = true;\n      marketingCheckbox.checked = true;\n      savePreferences();\n    });\n\n    // Reject all cookies (keep only essential)\n    const rejectAllCookies = () => {\n      analyticsCheckbox.checked = false;\n      performanceCheckbox.checked = false;\n      marketingCheckbox.checked = false;\n      localStorage.setItem(\n        categoriesKey,\n        JSON.stringify({\n          analytics: false,\n          performance: false,\n          marketing: false,\n        })\n      );\n      localStorage.setItem(consentKey, \"rejected\");\n      dismissBanner();\n      updateConsent({ analytics: false, performance: false, marketing: false });\n    };\n\n    rejectBtn.addEventListener(\"click\", rejectAllCookies);\n    modalRejectBtn.addEventListener(\"click\", rejectAllCookies);\n\n    // Manage preferences\n    manageBtn.addEventListener(\"click\", () => {\n      modal.style.display = \"flex\";\n      loadPreferences();\n    });\n\n    // Modal controls\n    modalClose.addEventListener(\"click\", () => {\n      modal.style.animation = \"fadeOut 0.3s ease-out forwards\";\n      setTimeout(() => {\n        modal.style.display = \"none\";\n      }, 300);\n    });\n\n    modalOverlay.addEventListener(\"click\", () => {\n      modalClose.click();\n    });\n\n    // Save preferences from modal\n    modalSaveBtn.addEventListener(\"click\", savePreferences);\n\n    // ESC key to close modal\n    document.addEventListener(\"keydown\", (e) => {\n      if (e.key === \"Escape\" && modal.style.display === \"flex\") {\n        modalClose.click();\n      }\n    });\n\n    // Add fadeOut animation\n    const style = document.createElement(\"style\");\n    style.textContent = `\n      @keyframes slideDown {\n        to {\n          transform: translateY(100%);\n          opacity: 0;\n        }\n      }\n      @keyframes fadeOut {\n        to {\n          opacity: 0;\n        }\n      }\n    `;\n    document.head.appendChild(style);\n  });\n</script>\n\n\n    <!-- Scripts -->\n    <script src=\"/assets/js/search.js\"></script>\n    <script src=\"/assets/js/performance.js\"></script>\n    <script src=\"/assets/js/visual-enhancements.js\"></script>\n  </body>\n</html>\n"],"config":null,"data":{"en":{"hero_title":"Showcase: Minecraft Mods & Packs","hero_subtitle":"Mods, resource packs, datapacks, modpacks and plugins — curated from our organization.","browse_projects":"Browse Projects","learn_more":"Learn More","featured_title":"Featured Highlights","featured_subtitle":"Latest additions to our growing collection","featured_badge":"Featured","view_project":"View Project","source":"Source","stats_title":"Project Snapshot","stats_subtitle":"Live data pulled from our Modrinth cache","stat_total_projects":"Total Projects","stat_total_downloads":"Total Downloads","stat_supported_loaders":"Supported Loaders","stat_game_versions":"Game Versions","stat_top_categories":"Top Categories","stat_top_downloads":"Top Downloads","stat_downloads_note":"Highest downloaded projects","stat_loading":"Loading…","stat_unavailable":"Unavailable","stat_projects_catalog":"Projects in catalog","stat_avg_per_project":"avg per project","stat_unique_versions":"Unique game versions","stat_no_categories":"No categories yet","stat_no_data":"No download data available yet","error_loading":"Error loading","failed_to_load":"Failed to load","no_projects_found":"No projects found. They will sync automatically.","error_404_title":"Page Not Found","error_404_description":"The page you're looking for doesn't exist.","error_404_message":"Sorry, we couldn't find what you were looking for.","error_404_back_home":"Back to Home","error_404_browse":"Browse Projects","cookie_title":"Cookie Preferences","cookie_message":"We use cookies to improve your experience and analyze site performance. No personal data is collected.","cookie_accept":"Accept All","cookie_reject":"Reject","cookie_learn_more":"Learn More","cookie_manage":"Manage Preferences","cookie_close":"Close","cookie_save":"Save Preferences","cookie_privacy_policy":"Privacy Policy","cookie_essential":"Essential","cookie_essential_desc":"Required for core site functionality. Always enabled.","cookie_analytics":"Analytics","cookie_analytics_desc":"Help us understand how you use our site to improve it.","cookie_marketing":"Marketing","cookie_marketing_desc":"Allow us to show you relevant content and offers.","cookie_performance":"Performance","cookie_performance_desc":"Improve page speed and user experience.","cookie_last_updated":"Last updated","cookie_all_cookies":"All Cookies","cookie_cookie_name":"Cookie Name","cookie_purpose":"Purpose","cookie_expiration":"Expiration"},"fr":{"hero_title":"Vitrine : Mods & Packs Minecraft","hero_subtitle":"Mods, packs de ressources, datapacks, modpacks et plugins — sélectionnés par notre organisation.","browse_projects":"Parcourir les Projets","learn_more":"En Savoir Plus","featured_title":"Points Forts","featured_subtitle":"Derniers ajouts à notre collection","featured_badge":"En Vedette","view_project":"Voir le Projet","source":"Source","stats_title":"Aperçu des Projets","stats_subtitle":"Données en direct de notre cache Modrinth","stat_total_projects":"Projets Totaux","stat_total_downloads":"Téléchargements Totaux","stat_supported_loaders":"Chargeurs Supportés","stat_game_versions":"Versions du Jeu","stat_top_categories":"Meilleures Catégories","stat_top_downloads":"Meilleurs Téléchargements","stat_downloads_note":"Projets les plus téléchargés","stat_loading":"Chargement…","stat_unavailable":"Indisponible","stat_projects_catalog":"Projets dans le catalogue","stat_avg_per_project":"moy par projet","stat_unique_versions":"Versions de jeu uniques","stat_no_categories":"Pas encore de catégories","stat_no_data":"Aucune donnée de téléchargement disponible","error_loading":"Erreur de chargement","failed_to_load":"Échec du chargement","no_projects_found":"Aucun projet trouvé. Ils se synchroniseront automatiquement.","error_404_title":"Page Non Trouvée","error_404_description":"La page que vous recherchez n'existe pas.","error_404_message":"Désolé, nous n'avons pas pu trouver ce que vous cherchiez.","error_404_back_home":"Retour à l'Accueil","error_404_browse":"Parcourir les Projets","cookie_title":"Préférences de Cookies","cookie_message":"Nous utilisons des cookies pour améliorer votre expérience et analyser les performances du site. Aucune donnée personnelle n'est collectée.","cookie_accept":"Accepter Tous","cookie_reject":"Rejeter","cookie_learn_more":"En Savoir Plus","cookie_manage":"Gérer les Préférences","cookie_close":"Fermer","cookie_save":"Enregistrer les Préférences","cookie_privacy_policy":"Politique de Confidentialité","cookie_essential":"Essentiels","cookie_essential_desc":"Requis pour les fonctionnalités principales du site. Toujours activés.","cookie_analytics":"Analyse","cookie_analytics_desc":"Nous aider à comprendre comment vous utilisez notre site pour l'améliorer.","cookie_marketing":"Marketing","cookie_marketing_desc":"Nous permettre de vous montrer du contenu et des offres pertinents.","cookie_performance":"Performance","cookie_performance_desc":"Améliorer la vitesse et l'expérience utilisateur des pages.","cookie_last_updated":"Dernière mise à jour","cookie_all_cookies":"Tous les Cookies","cookie_cookie_name":"Nom du Cookie","cookie_purpose":"Objet","cookie_expiration":"Expiration"}},"static_files":[{"name":"LICENSE","modified_time":"2025-12-17 01:31:14 +0000","basename":"LICENSE","extname":"","path":"/LICENSE","collection":null},{"name":"README.md","modified_time":"2025-12-17 01:31:14 +0000","basename":"README","extname":".md","path":"/README.md","collection":null},{"name":"a11y.css","modified_time":"2025-12-17 01:31:14 +0000","basename":"a11y","extname":".css","path":"/assets/css/a11y.css","collection":null},{"name":"animations.css","modified_time":"2025-12-17 01:31:14 +0000","basename":"animations","extname":".css","path":"/assets/css/animations.css","collection":null},{"name":"components.css","modified_time":"2025-12-17 01:31:14 +0000","basename":"components","extname":".css","path":"/assets/css/components.css","collection":null},{"name":"docs.css","modified_time":"2025-12-17 01:31:14 +0000","basename":"docs","extname":".css","path":"/assets/css/docs.css","collection":null},{"name":"layout.css","modified_time":"2025-12-17 01:31:14 +0000","basename":"layout","extname":".css","path":"/assets/css/layout.css","collection":null},{"name":"loading.css","modified_time":"2025-12-17 01:31:14 +0000","basename":"loading","extname":".css","path":"/assets/css/loading.css","collection":null},{"name":"mobile.css","modified_time":"2025-12-17 01:31:14 +0000","basename":"mobile","extname":".css","path":"/assets/css/mobile.css","collection":null},{"name":"modpacks.css","modified_time":"2025-12-17 01:31:14 +0000","basename":"modpacks","extname":".css","path":"/assets/css/modpacks.css","collection":null},{"name":"root.css","modified_time":"2025-12-17 01:31:14 +0000","basename":"root","extname":".css","path":"/assets/css/root.css","collection":null},{"name":"styles.css","modified_time":"2025-12-17 01:31:14 +0000","basename":"styles","extname":".css","path":"/assets/css/styles.css","collection":null},{"name":"theme.css","modified_time":"2025-12-17 01:31:14 +0000","basename":"theme","extname":".css","path":"/assets/css/theme.css","collection":null},{"name":"visual-enhancements.css","modified_time":"2025-12-17 01:31:14 +0000","basename":"visual-enhancements","extname":".css","path":"/assets/css/visual-enhancements.css","collection":null},{"name":"abc.svg","modified_time":"2025-12-17 01:31:14 +0000","basename":"abc","extname":".svg","path":"/assets/images/abc.svg","collection":null},{"name":"blocks.svg","modified_time":"2025-12-17 01:31:14 +0000","basename":"blocks","extname":".svg","path":"/assets/images/blocks.svg","collection":null},{"name":"favicon.ico","modified_time":"2025-12-17 01:31:14 +0000","basename":"favicon","extname":".ico","path":"/assets/images/favicon.ico","collection":null},{"name":"favicon.svg","modified_time":"2025-12-17 01:31:14 +0000","basename":"favicon","extname":".svg","path":"/assets/images/favicon.svg","collection":null},{"name":"logo.svg","modified_time":"2025-12-17 01:31:14 +0000","basename":"logo","extname":".svg","path":"/assets/images/logo.svg","collection":null},{"name":"Compatibility.png","modified_time":"2025-12-17 01:31:14 +0000","basename":"Compatibility","extname":".png","path":"/assets/images/titles/Compatibility.png","collection":null},{"name":"Configuration.png","modified_time":"2025-12-17 01:31:14 +0000","basename":"Configuration","extname":".png","path":"/assets/images/titles/Configuration.png","collection":null},{"name":"Credits.png","modified_time":"2025-12-17 01:31:14 +0000","basename":"Credits","extname":".png","path":"/assets/images/titles/Credits.png","collection":null},{"name":"Features.png","modified_time":"2025-12-17 01:31:14 +0000","basename":"Features","extname":".png","path":"/assets/images/titles/Features.png","collection":null},{"name":"Installation.png","modified_time":"2025-12-17 01:31:14 +0000","basename":"Installation","extname":".png","path":"/assets/images/titles/Installation.png","collection":null},{"name":"Limitations.png","modified_time":"2025-12-17 01:31:14 +0000","basename":"Limitations","extname":".png","path":"/assets/images/titles/Limitations.png","collection":null},{"name":"Overview.png","modified_time":"2025-12-17 01:31:14 +0000","basename":"Overview","extname":".png","path":"/assets/images/titles/Overview.png","collection":null},{"name":"Project.png","modified_time":"2025-12-17 01:31:14 +0000","basename":"Project","extname":".png","path":"/assets/images/titles/Project.png","collection":null},{"name":"Q&A.png","modified_time":"2025-12-17 01:31:14 +0000","basename":"Q&A","extname":".png","path":"/assets/images/titles/Q&A.png","collection":null},{"name":"Roadmap.png","modified_time":"2025-12-17 01:31:14 +0000","basename":"Roadmap","extname":".png","path":"/assets/images/titles/Roadmap.png","collection":null},{"name":"Screenshots.png","modified_time":"2025-12-17 01:31:14 +0000","basename":"Screenshots","extname":".png","path":"/assets/images/titles/Screenshots.png","collection":null},{"name":"Translations.png","modified_time":"2025-12-17 01:31:14 +0000","basename":"Translations","extname":".png","path":"/assets/images/titles/Translations.png","collection":null},{"name":"config.js","modified_time":"2025-12-17 01:31:14 +0000","basename":"config","extname":".js","path":"/assets/js/config.js","collection":null},{"name":"include.js","modified_time":"2025-12-17 01:31:14 +0000","basename":"include","extname":".js","path":"/assets/js/include.js","collection":null},{"name":"main.js","modified_time":"2025-12-17 01:31:14 +0000","basename":"main","extname":".js","path":"/assets/js/main.js","collection":null},{"name":"modrinth.js","modified_time":"2025-12-17 01:31:14 +0000","basename":"modrinth","extname":".js","path":"/assets/js/modrinth.js","collection":null},{"name":"performance.js","modified_time":"2025-12-17 01:31:14 +0000","basename":"performance","extname":".js","path":"/assets/js/performance.js","collection":null},{"name":"search.js","modified_time":"2025-12-17 01:31:14 +0000","basename":"search","extname":".js","path":"/assets/js/search.js","collection":null},{"name":"social-links.js","modified_time":"2025-12-17 01:31:14 +0000","basename":"social-links","extname":".js","path":"/assets/js/social-links.js","collection":null},{"name":"visual-enhancements.js","modified_time":"2025-12-17 01:31:14 +0000","basename":"visual-enhancements","extname":".js","path":"/assets/js/visual-enhancements.js","collection":null},{"name":"mods.json","modified_time":"2025-12-17 01:31:14 +0000","basename":"mods","extname":".json","path":"/data/mods.json","collection":null},{"name":"CONTRIBUTING.md","modified_time":"2025-12-17 01:31:14 +0000","basename":"CONTRIBUTING","extname":".md","path":"/docs/CONTRIBUTING.md","collection":null},{"name":"PROJECT_STRUCTURE.md","modified_time":"2025-12-17 01:31:14 +0000","basename":"PROJECT_STRUCTURE","extname":".md","path":"/docs/PROJECT_STRUCTURE.md","collection":null},{"name":"favicon.ico","modified_time":"2025-12-17 01:31:14 +0000","basename":"favicon","extname":".ico","path":"/favicon.ico","collection":null},{"name":"favicon.svg","modified_time":"2025-12-17 01:31:14 +0000","basename":"favicon","extname":".svg","path":"/favicon.svg","collection":null},{"name":"package-lock.json","modified_time":"2025-12-17 01:31:14 +0000","basename":"package-lock","extname":".json","path":"/package-lock.json","collection":null},{"name":"package.json","modified_time":"2025-12-17 01:31:14 +0000","basename":"package","extname":".json","path":"/package.json","collection":null},{"name":"robots.txt","modified_time":"2025-12-17 01:31:14 +0000","basename":"robots","extname":".txt","path":"/robots.txt","collection":null},{"name":"sitemap.xml","modified_time":"2025-12-17 01:31:14 +0000","basename":"sitemap","extname":".xml","path":"/sitemap.xml","collection":null}],"categories":{"updates":["\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <title>Welcome to the Blog</title>\n    <meta\n      name=\"description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta\n      name=\"robots\"\n      content=\"index, follow\"\n    />\n\n    <!-- SEO Meta Tags -->\n          \n\n    <meta\n      property=\"og:title\"\n      content=\"Welcome to the Blog\"\n    />\n    <meta\n      property=\"og:description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta property=\"og:url\" content=\"https://abc-site.devvyy.xyz/blog/blog-test/\" />\n    <meta property=\"og:image\" content=\"https://abc-site.devvyy.xyz/assets/images/logo.svg\" />\n    <meta property=\"og:image:alt\" content=\"ABC Mods & Packs\" />\n    <meta property=\"og:type\" content=\"post\" />\n    <meta property=\"og:site_name\" content=\"ABC\" />\n    <meta\n      property=\"og:locale\"\n      content=\"en_US\"\n    />\n\n    <!-- hreflang tags for multilingual SEO -->\n    <link\n      rel=\"alternate\"\n      hreflang=\"en\"\n      href=\"https://abc-site.devvyy.xyz/blog/blog-test/\"\n    />\n    <link\n      rel=\"alternate\"\n      hreflang=\"fr\"\n      href=\"https://abc-site.devvyy.xyz/fr/blog/blog-test/\"\n    />\n    <link\n      rel=\"alternate\"\n      hreflang=\"x-default\"\n      href=\"https://abc-site.devvyy.xyz/blog/blog-test/\"\n    />\n\n    <!-- Twitter Card -->\n    <meta name=\"twitter:card\" content=\"summary_large_image\" />\n    <meta\n      name=\"twitter:title\"\n      content=\"Welcome to the Blog\"\n    />\n    <meta\n      name=\"twitter:description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta\n      name=\"twitter:image\"\n      content=\"https://abc-site.devvyy.xyz/assets/images/logo.svg\"\n    />\n    <meta name=\"twitter:image:alt\" content=\"ABC Mods & Packs\" />\n    <meta\n      name=\"twitter:creator\"\n      content=\"@devvyyxyz\"\n    />\n    <meta\n      name=\"twitter:site\"\n      content=\"@devvyyxyz\"\n    />\n\n    <meta\n      name=\"theme-color\"\n      content=\"#1bd96f\"\n    />\n\n    <!-- Favicon -->\n    <link\n      rel=\"icon\"\n      type=\"image/svg+xml\"\n      href=\"/favicon.svg\"\n    />\n    <link\n      rel=\"icon\"\n      type=\"image/x-icon\"\n      href=\"/favicon.svg\"\n    />\n    <link\n      rel=\"apple-touch-icon\"\n      href=\"/assets/images/logo.svg\"\n    />\n\n    <!-- Google Fonts - Preload -->\n    <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n    <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n    <link\n      rel=\"preload\"\n      as=\"style\"\n      href=\"https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap\"\n    />\n    <link\n      href=\"https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap\"\n      rel=\"stylesheet\"\n    />\n\n    <!-- Font Awesome Icons - Async load -->\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <noscript>\n      <link\n        rel=\"stylesheet\"\n        href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n      />\n    </noscript>\n\n    <!-- Stylesheets - Critical -->\n    <link rel=\"stylesheet\" href=\"/assets/css/root.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/layout.css\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/loading.css\"\n    />\n\n    <!-- Stylesheets - Deferred (non-critical) -->\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/components.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/modpacks.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/animations.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/theme.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/a11y.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/visual-enhancements.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/mobile.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <noscript>\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/components.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/modpacks.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/animations.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/theme.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/a11y.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/visual-enhancements.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/mobile.css\"\n      />\n    </noscript>\n\n    <!-- Canonical URL -->\n    <link rel=\"canonical\" href=\"https://abc-site.devvyy.xyz/blog/blog-test/\" />\n\n    <!-- Schema Markup -->\n    <!-- Schema.org JSON-LD -->\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"Organization\",\n    \"name\": \"ABC\",\n    \"description\": \"Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins.\",\n    \"url\": \"https://abc-site.devvyy.xyz\",\n    \"logo\": \"https://abc-site.devvyy.xyz/assets/images/logo.svg\",\n    \"sameAs\": [\n      \"https://github.com/devvyyxyz\",\n      \"https://twitter.com/devvyyxyz\",\n      \"https://dc.gg/devvyyxyz\"\n    ],\n    \"contactPoint\": {\n      \"@type\": \"ContactPoint\",\n      \"contactType\": \"Community Support\",\n      \"url\": \"https://dc.gg/devvyyxyz\"\n    }\n  }\n</script>\n\n<!-- Breadcrumb Schema -->\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"BreadcrumbList\",\n    \"itemListElement\": [\n      {\n        \"@type\": \"ListItem\",\n        \"position\": 1,\n        \"name\": \"Home\",\n        \"item\": \"https://abc-site.devvyy.xyz\"\n      }\n      \n      , {\n        \"@type\": \"ListItem\",\n        \"position\": 2,\n        \"name\": \"Welcome to the Blog\",\n        \"item\": \"https://abc-site.devvyy.xyz/blog/blog-test/\"\n      }\n      \n    ]\n  }\n</script>\n\n<!-- Project/Software Application Schema (for project pages) -->\n\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"Article\",\n    \"headline\": \"Welcome to the Blog\",\n    \"description\": \"Kicking off our new blog — what's coming next.\",\n    \"image\": \"\",\n    \"datePublished\": \"2025-12-16T00:00:00+00:00\",\n    \"dateModified\": \"2025-12-16T00:00:00+00:00\",\n    \"author\": {\n      \"@type\": \"Organization\",\n      \"name\": \"ABC\"\n    },\n    \"publisher\": {\n      \"@type\": \"Organization\",\n      \"name\": \"ABC\",\n      \"logo\": {\n        \"@type\": \"ImageObject\",\n        \"url\": \"https://abc-site.devvyy.xyz/assets/images/logo.svg\"\n      }\n    }\n  }\n</script>\n<!-- WebPage Schema -->\n\n\n\n    <!-- Preloader Script (critical, inline) -->\n    <script>\n      (function () {\n        if (!document.body) return; // Exit if body not ready yet\n\n        const isDarkMode =\n          window.matchMedia &&\n          window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n        const bgColor = isDarkMode ? \"#0d0d0d\" : \"#f6fbfa\";\n        document.documentElement.style.backgroundColor = bgColor;\n        document.body.style.backgroundColor = bgColor;\n\n        const overlay = document.createElement(\"div\");\n        overlay.className = \"loading-overlay\";\n        overlay.id = \"loading-overlay\";\n        overlay.innerHTML = '<div class=\"spinner\"></div>';\n        document.body.appendChild(overlay);\n\n        if (document.readyState === \"loading\") {\n          document.addEventListener(\"DOMContentLoaded\", hidePreloader);\n        } else {\n          hidePreloader();\n        }\n\n        function hidePreloader() {\n          const preloader = document.getElementById(\"loading-overlay\");\n          if (preloader) {\n            preloader.classList.add(\"hidden\");\n          }\n        }\n\n        window.hidePreloader = hidePreloader;\n      })();\n    </script>\n  </head>\n  <body>\n    <a href=\"#main\" class=\"skip-to-main\">Skip to main content</a>\n    <header class=\"floating-nav\">\n  <div class=\"nav-inner\">\n    <a\n      class=\"logo\"\n      href=\"/\"\n      style=\"display: flex; align-items: center; gap: 8px\"\n      aria-label=\"ABC\"\n    >\n      <img\n        src=\"/assets/images/logo.svg\"\n        alt=\"ABC\"\n        style=\"height: 32px; width: auto\"\n      />\n      \n    </a>\n    <button\n      class=\"mobile-menu-toggle\"\n      aria-label=\"Toggle menu\"\n      id=\"mobile-menu-toggle\"\n    >\n      <i class=\"fas fa-bars\"></i>\n    </button>\n    <nav class=\"links\" id=\"mobile-nav\">\n      <a href=\"/\">Home</a>\n      <a href=\"/about/\">About</a>\n      <a href=\"/docs/\">Docs</a>\n      <a href=\"/changelog/\">Changelog</a>\n      <a href=\"/blog/\">Blog</a>\n      <div class=\"nav-dropdown\">\n        <a href=\"/projects/\" class=\"dropdown-toggle\">\n          Projects <i class=\"fas fa-chevron-down\"></i>\n        </a>\n        <div class=\"dropdown-menu\">\n          <a href=\"/projects/\">All Projects</a>\n          <a href=\"/compare/\"\n            ><i class=\"fas fa-balance-scale\"></i> Compare Modpacks</a\n          >\n          <a href=\"/changelog/\"\n            ><i class=\"fas fa-rocket\"></i> Releases & Changelog</a\n          >\n        </div>\n      </div>\n      <div class=\"nav-dropdown\">\n        <a href=\"#\" class=\"dropdown-toggle\">\n          Legal <i class=\"fas fa-chevron-down\"></i>\n        </a>\n        <div class=\"dropdown-menu\">\n          <a href=\"/privacy/\">Privacy Policy</a>\n          <a href=\"/terms/\">Terms of Service</a>\n          <a href=\"/cookie-policy/\">Cookie Policy</a>\n          <a href=\"/licensing/\">Licensing</a>\n          <a href=\"/eula/\">EULA</a>\n          <a href=\"/disclaimer/\">Disclaimer</a>\n        </div>\n      </div>\n      <a\n        href=\"https://modrinth.com/organization/abcxyz\"\n        target=\"_blank\"\n        rel=\"noopener\"\n        >Organization</a\n      >\n    </nav>\n    <div class=\"nav-actions\">\n      <div\n        id=\"social-links-nav\"\n        style=\"display: flex; gap: 6px; align-items: center\"\n      ></div>\n      <!-- Theme Toggle -->\n<div class=\"theme-toggle\" id=\"theme-toggle\" title=\"Toggle dark/light mode\">\n  <button id=\"theme-dark\" class=\"active\" aria-label=\"Dark mode\" title=\"Dark mode\">\n    <i class=\"fa-solid fa-moon\"></i>\n  </button>\n  <button id=\"theme-light\" aria-label=\"Light mode\" title=\"Light mode\">\n    <i class=\"fa-solid fa-sun\"></i>\n  </button>\n</div>\n\n<script>\n  // Theme toggle functionality\n  const themeToggle = {\n    init() {\n      this.darkBtn = document.getElementById('theme-dark');\n      this.lightBtn = document.getElementById('theme-light');\n      this.html = document.documentElement;\n\n      // Load saved theme or use system preference\n      const saved = localStorage.getItem('theme');\n      const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;\n      const theme = saved || (systemDark ? 'dark' : 'light');\n\n      this.setTheme(theme);\n\n      // Listen for changes\n      this.darkBtn.addEventListener('click', () => this.setTheme('dark'));\n      this.lightBtn.addEventListener('click', () => this.setTheme('light'));\n\n      // Listen for system theme changes\n      window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {\n        if (!localStorage.getItem('theme')) {\n          this.setTheme(e.matches ? 'dark' : 'light');\n        }\n      });\n    },\n\n    setTheme(theme) {\n      this.html.setAttribute('data-theme', theme);\n      localStorage.setItem('theme', theme);\n\n      this.darkBtn.classList.toggle('active', theme === 'dark');\n      this.lightBtn.classList.toggle('active', theme === 'light');\n\n      // Update meta theme-color\n      const color = theme === 'dark' ? '#1bd96f' : '#1bd96f';\n      document.querySelector('meta[name=\"theme-color\"]').setAttribute('content', color);\n    }\n  };\n\n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', () => themeToggle.init());\n  } else {\n    themeToggle.init();\n  }\n</script>\n\n    </div>\n  </div>\n</header>\n\n<script>\n  // Mobile menu toggle\n  document.addEventListener(\"DOMContentLoaded\", () => {\n    const toggle = document.getElementById(\"mobile-menu-toggle\");\n    const nav = document.getElementById(\"mobile-nav\");\n\n    if (toggle && nav) {\n      toggle.addEventListener(\"click\", () => {\n        nav.classList.toggle(\"mobile-open\");\n        const icon = toggle.querySelector(\"i\");\n        if (nav.classList.contains(\"mobile-open\")) {\n          icon.classList.remove(\"fa-bars\");\n          icon.classList.add(\"fa-times\");\n        } else {\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        }\n      });\n\n      // Close menu when clicking a link\n      nav.querySelectorAll(\"a\").forEach((link) => {\n        link.addEventListener(\"click\", () => {\n          nav.classList.remove(\"mobile-open\");\n          const icon = toggle.querySelector(\"i\");\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        });\n      });\n\n      // Close menu when clicking outside\n      document.addEventListener(\"click\", (e) => {\n        if (!toggle.contains(e.target) && !nav.contains(e.target)) {\n          nav.classList.remove(\"mobile-open\");\n          const icon = toggle.querySelector(\"i\");\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        }\n      });\n    }\n  });\n</script>\n\n\n    <main id=\"main\" class=\"container\"><main class=\"content\">\n  <article class=\"post\" style=\"max-width: 820px; margin: 0 auto; padding: 24px\">\n    <header>\n      <h1 style=\"margin: 0 0 8px\">Welcome to the Blog</h1>\n      <p class=\"muted\" style=\"margin: 0 0 16px\">\n        December 16, 2025 • ABC Team\n      </p>\n    </header>\n    <section class=\"post-body\"><p>We’re launching a blog to share updates, release notes, and behind-the-scenes dev logs.</p>\n\n<!--more-->\n\n<p>What you can expect:</p>\n\n<ul>\n  <li>Deep dives into mods, datapacks, and plugins</li>\n  <li>Roadmap updates and upcoming releases</li>\n  <li>Performance tips and compatibility notes</li>\n  <li>Community showcases and contributions</li>\n</ul>\n\n<p>If you have topics you’d like us to cover, let us know on the contact page or Discord.</p>\n</section>\n\n    \n    <footer style=\"margin-top: 24px\">\n      <strong>Tags:</strong>\n      \n      <span\n        style=\"\n          display: inline-block;\n          padding: 4px 8px;\n          border: 1px solid var(--border);\n          border-radius: 999px;\n          margin-right: 6px;\n          font-size: 12px;\n        \"\n        >#announcement</span\n      >\n      \n      <span\n        style=\"\n          display: inline-block;\n          padding: 4px 8px;\n          border: 1px solid var(--border);\n          border-radius: 999px;\n          margin-right: 6px;\n          font-size: 12px;\n        \"\n        >#roadmap</span\n      >\n       \n      <div style=\"margin-top: 8px\">\n        <strong>Categories:</strong>\n        \n        <span\n          style=\"\n            display: inline-block;\n            padding: 4px 8px;\n            border: 1px solid var(--border);\n            border-radius: 999px;\n            margin-right: 6px;\n            font-size: 12px;\n          \"\n          >updates</span\n        >\n        \n      </div>\n      \n    </footer>\n    \n  </article>\n</main>\n</main>\n\n    <footer class=\"floating-footer\">\n  <div class=\"footer-inner\">\n    <div style=\"display: flex; gap: 16px; align-items: flex-start\">\n      <img\n        src=\"/assets/images/logo.svg\"\n        alt=\"ABC logo\"\n        style=\"height: 100px; flex-shrink: 0; width: auto\"\n        width=\"100\"\n        height=\"100\"\n      />\n      <div style=\"display: flex; flex-direction: column; gap: 8px\">\n        <div>\n          <h4\n            style=\"\n              margin: 0;\n              font-size: 18px;\n              font-weight: 700;\n              color: var(--text);\n            \"\n          >\n            ABC\n          </h4>\n          <p\n            style=\"\n              margin: 2px 0 0 0;\n              font-size: 12px;\n              color: var(--text-secondary);\n            \"\n          >\n            Established 2025\n          </p>\n        </div>\n        <p\n          style=\"\n            margin: 0;\n            font-size: 13px;\n            color: var(--text-secondary);\n            line-height: 1.6;\n          \"\n        >\n          Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins.\n        </p>\n      </div>\n    </div>\n    <div style=\"display: flex; gap: 48px\">\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Links\n        </h4>\n        <div\n          style=\"\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n            gap: 10px 12px;\n            font-size: 13px;\n            max-width: 320px;\n          \"\n        >\n          <a\n            href=\"/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Home</a\n          >\n          <a\n            href=\"/about/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >About</a\n          >\n          <a\n            href=\"/docs/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Docs</a\n          >\n          <a\n            href=\"/projects/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Projects</a\n          >\n          <a\n            href=\"/compare/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Compare</a\n          >\n          <a\n            href=\"/changelog/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Changelog</a\n          >\n          <a\n            href=\"https://modrinth.com/organization/abcxyz\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            target=\"_blank\"\n            rel=\"noopener\"\n            >Modrinth Org</a\n          >\n          <a\n            href=\"https://github.com/devvyyxyz\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            target=\"_blank\"\n            rel=\"noopener\"\n            >GitHub Org</a\n          >\n          <a\n            href=\"/sitemap.xml\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Sitemap</a\n          >\n          <a\n            href=\"/feed.xml\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >RSS Feed</a\n          >\n          <a\n            href=\"/blog/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Blog</a\n          >\n        </div>\n      </div>\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Help\n        </h4>\n        <div\n          style=\"\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n            gap: 10px 12px;\n            font-size: 13px;\n            max-width: 320px;\n          \"\n        >\n          <a\n            href=\"/contact/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Contact</a\n          >\n          <a\n            href=\"/docs/faq/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >FAQ</a\n          >\n          <a\n            href=\"/docs/troubleshooting/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Troubleshooting</a\n          >\n          <a\n            href=\"/docs/contributing/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Contributing</a\n          >\n          <a\n            href=\"/status/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Status</a\n          >\n        </div>\n      </div>\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Community\n        </h4>\n        <div\n          id=\"social-links-footer\"\n          style=\"display: flex; gap: 12px; flex-direction: column\"\n        ></div>\n      </div>\n    </div>\n  </div>\n  <div\n    style=\"\n      border-top: 1px solid var(--border);\n      margin-top: 32px;\n      padding-top: 24px;\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      font-size: 12px;\n      color: var(--text-secondary);\n      flex-wrap: wrap;\n      gap: 16px;\n    \"\n  >\n    <div style=\"display: flex; gap: 16px; align-items: center; flex-wrap: wrap\">\n      <div>\n        © <span id=\"year\"></span> ABC. All rights reserved.\n      </div>\n      <div\n        id=\"language-switcher\"\n        style=\"display: flex; gap: 8px; align-items: center\"\n      >\n        <span style=\"font-size: 12px; color: var(--text-secondary)\"\n          >Language:</span\n        >\n        <select\n          id=\"lang-select\"\n          style=\"\n            padding: 4px 8px;\n            border: 1px solid var(--border);\n            border-radius: var(--radius);\n            background: var(--bg-secondary);\n            color: var(--text);\n            font-size: 12px;\n            cursor: pointer;\n          \"\n        >\n          <option value=\"en\">English</option>\n          <option value=\"fr\">Français</option>\n        </select>\n      </div>\n    </div>\n    <div style=\"display: flex; gap: 20px\">\n      <a\n        href=\"/privacy/\"\n        style=\"\n          color: var(--text-secondary);\n          text-decoration: none;\n          transition: color 0.2s;\n        \"\n        >Privacy</a\n      >\n      <a\n        href=\"/terms/\"\n        style=\"\n          color: var(--text-secondary);\n          text-decoration: none;\n          transition: color 0.2s;\n        \"\n        >Terms</a\n      >\n    </div>\n  </div>\n</footer>\n\n<script>\n  // Social links configuration\n  const socials = {\n    github: {\n      name: \"GitHub\",\n      icon: \"fab fa-github\",\n      url: \"https://github.com/devvyyxyz\",\n    },\n    twitter: {\n      name: \"Twitter\",\n      icon: \"fab fa-x-twitter\",\n      url: \"https://twitter.com/devvyyxyz\",\n    },\n    discord: {\n      name: \"Discord\",\n      icon: \"fab fa-discord\",\n      url: \"https://dc.gg/devvyyxyz\",\n    },\n  };\n\n  function renderSocialLinks() {\n    const navContainer = document.getElementById(\"social-links-nav\");\n    const footerContainer = document.getElementById(\"social-links-footer\");\n\n    Object.entries(socials).forEach(([key, social]) => {\n      if (social.url && social.url.trim()) {\n        // Nav icon button\n        const navLink = document.createElement(\"a\");\n        navLink.href = social.url;\n        navLink.target = \"_blank\";\n        navLink.rel = \"noopener\";\n        navLink.title = social.name;\n        navLink.style.cssText =\n          \"display:flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:var(--radius);background:var(--bg-secondary);color:var(--text-secondary);text-decoration:none;font-size:16px;transition:all 0.2s ease;border:1px solid var(--border)\";\n        const icon = document.createElement(\"i\");\n        icon.className = social.icon;\n        icon.style.fontSize = \"18px\";\n        navLink.appendChild(icon);\n        navLink.onmouseover = () => {\n          navLink.style.background = \"var(--accent-primary)\";\n          navLink.style.color = \"#000000\";\n          navLink.style.borderColor = \"var(--accent-primary)\";\n        };\n        navLink.onmouseout = () => {\n          navLink.style.background = \"var(--bg-secondary)\";\n          navLink.style.color = \"var(--text-secondary)\";\n          navLink.style.borderColor = \"var(--border)\";\n        };\n        if (navContainer) navContainer.appendChild(navLink);\n\n        // Footer text link with icon\n        const footerLink = document.createElement(\"a\");\n        footerLink.href = social.url;\n        footerLink.target = \"_blank\";\n        footerLink.rel = \"noopener\";\n        footerLink.style.cssText =\n          \"display:flex;align-items:center;gap:8px;color:var(--text-secondary);text-decoration:none;transition:color 0.2s;font-size:13px\";\n        const footerIcon = document.createElement(\"i\");\n        footerIcon.className = social.icon;\n        footerIcon.style.width = \"16px\";\n        const footerText = document.createElement(\"span\");\n        footerText.textContent = social.name;\n        footerLink.appendChild(footerIcon);\n        footerLink.appendChild(footerText);\n        footerLink.onmouseover = () => {\n          footerLink.style.color = \"var(--accent-primary)\";\n        };\n        footerLink.onmouseout = () => {\n          footerLink.style.color = \"var(--text-secondary)\";\n        };\n        if (footerContainer) footerContainer.appendChild(footerLink);\n      }\n    });\n  }\n\n  document.addEventListener(\"DOMContentLoaded\", renderSocialLinks);\n\n  // Set year in footer\n  document.getElementById(\"year\").textContent = new Date().getFullYear();\n\n  // Language switcher\n  const langSelect = document.getElementById(\"lang-select\");\n  if (langSelect) {\n    const currentLang = 'en';\n    langSelect.value = currentLang;\n\n    langSelect.addEventListener(\"change\", (e) => {\n      const selectedLang = e.target.value;\n      const currentPath = window.location.pathname;\n      const baseUrl = \"\";\n\n      // Remove existing language prefix\n      let cleanPath = currentPath.replace(baseUrl, \"\");\n      cleanPath = cleanPath.replace(/^\\/(en|fr)/, \"\");\n\n      // Build new URL\n      const newPath =\n        selectedLang === \"en\"\n          ? baseUrl + cleanPath\n          : baseUrl + \"/\" + selectedLang + cleanPath;\n\n      window.location.href = newPath;\n    });\n  }\n</script>\n <!-- Scroll to top button -->\n<button id=\"scroll-to-top\" class=\"scroll-to-top\" aria-label=\"Scroll to top\" title=\"Back to top\">\n  <i class=\"fa-solid fa-chevron-up\"></i>\n</button>\n\n<script>\n  // Scroll to top functionality\n  const scrollButton = document.getElementById('scroll-to-top');\n\n  window.addEventListener('scroll', () => {\n    if (window.scrollY > 300) {\n      scrollButton.classList.add('visible');\n    } else {\n      scrollButton.classList.remove('visible');\n    }\n  });\n\n  scrollButton.addEventListener('click', () => {\n    window.scrollTo({ top: 0, behavior: 'smooth' });\n  });\n\n  // Handle keyboard interaction\n  scrollButton.addEventListener('keydown', (e) => {\n    if (e.key === 'Enter' || e.key === ' ') {\n      e.preventDefault();\n      window.scrollTo({ top: 0, behavior: 'smooth' });\n    }\n  });\n</script>\n\n<!-- Lazy loading images with placeholder -->\n<script>\n  // Intersection Observer for lazy loading\n  if ('IntersectionObserver' in window) {\n    const imageObserver = new IntersectionObserver((entries, observer) => {\n      entries.forEach(entry => {\n        if (entry.isIntersecting) {\n          const img = entry.target;\n          img.src = img.dataset.src || img.src;\n          img.classList.remove('lazy');\n          observer.unobserve(img);\n        }\n      });\n    }, {\n      rootMargin: '50px 0px',\n      threshold: 0.01\n    });\n\n    document.querySelectorAll('img[data-src]').forEach(img => {\n      imageObserver.observe(img);\n    });\n  }\n</script>\n\n<!-- Smooth page transitions -->\n<script>\n  // Add page transition class on load\n  document.addEventListener('DOMContentLoaded', () => {\n    document.body.classList.add('page-transition');\n  });\n\n  // Handle link clicks for smooth transitions\n  document.addEventListener('click', (e) => {\n    const link = e.target.closest('a');\n    if (link && !link.target && link.hostname === window.location.hostname) {\n      // Internal link - add transition\n      e.preventDefault();\n      document.body.style.opacity = '0.8';\n      setTimeout(() => {\n        window.location.href = link.href;\n      }, 150);\n    }\n  });\n</script>\n\n\n    <!-- Cookie Consent Banner -->\n    <div\n  id=\"cookie-consent\"\n  class=\"cookie-consent-banner\"\n  role=\"alertdialog\"\n  aria-labelledby=\"cookie-title\"\n  aria-describedby=\"cookie-description\"\n  style=\"display: none\"\n>\n  <div class=\"cookie-consent-content\">\n    <div class=\"cookie-consent-text\">\n      <h3 id=\"cookie-title\" class=\"cookie-consent-title\">\n          Cookie Preferences\n      </h3>\n      <p id=\"cookie-description\" class=\"cookie-consent-message\">\n        We use cookies to improve your experience and analyze site performance. No personal data is collected.\n      </p>\n      <p class=\"cookie-consent-subtext\">\n        <a\n          href=\"/privacy/\"\n          target=\"_blank\"\n          rel=\"noopener\"\n          >Privacy Policy</a\n        >\n      </p>\n    </div>\n    <div class=\"cookie-consent-actions\">\n      <button\n        id=\"cookie-manage\"\n        class=\"cookie-btn cookie-btn-manage\"\n        aria-label=\"Manage cookie preferences\"\n      >\n        Manage Preferences\n      </button>\n      <button\n        id=\"cookie-reject\"\n        class=\"cookie-btn cookie-btn-reject\"\n        aria-label=\"Reject cookies\"\n      >\n        Reject\n      </button>\n      <button\n        id=\"cookie-accept\"\n        class=\"cookie-btn cookie-btn-accept\"\n        aria-label=\"Accept all cookies\"\n      >\n        Accept All\n      </button>\n    </div>\n  </div>\n</div>\n\n<!-- Cookie Settings Modal -->\n<div\n  id=\"cookie-modal\"\n  class=\"cookie-modal\"\n  style=\"display: none\"\n  role=\"dialog\"\n  aria-labelledby=\"modal-title\"\n  aria-hidden=\"true\"\n>\n  <div class=\"cookie-modal-overlay\"></div>\n  <div class=\"cookie-modal-content\">\n    <div class=\"cookie-modal-header\">\n      <h2 id=\"modal-title\" class=\"cookie-modal-title\">Cookie Preferences</h2>\n      <button\n        id=\"modal-close\"\n        class=\"cookie-modal-close\"\n        aria-label=\"Close modal\"\n      >\n        <i class=\"fas fa-times\"></i>\n      </button>\n    </div>\n\n    <div class=\"cookie-modal-body\">\n      <!-- Categories -->\n      <div class=\"cookie-categories\">\n        <!-- Essential -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-essential\"\n                class=\"cookie-checkbox\"\n                checked\n                disabled\n              />\n              <span class=\"cookie-category-title\"\n                >Essential</span\n              >\n            </label>\n            <span class=\"cookie-badge essential\">Essential</span>\n          </div>\n          <p class=\"cookie-category-desc\">Required for core site functionality. Always enabled.</p>\n        </div>\n\n        <!-- Analytics -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-analytics\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Analytics</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Help us understand how you use our site to improve it.</p>\n          <details class=\"cookie-details\">\n            <summary>All Cookies</summary>\n            <div class=\"cookie-list\">\n              <div class=\"cookie-item\">\n                <span class=\"cookie-item-name\">_ga, _ga_*</span>\n                <span class=\"cookie-item-expiration\">2 years</span>\n              </div>\n              <div class=\"cookie-item\">\n                <span class=\"cookie-item-name\">_gat</span>\n                <span class=\"cookie-item-expiration\">1 minute</span>\n              </div>\n            </div>\n          </details>\n        </div>\n\n        <!-- Performance -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-performance\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Performance</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Improve page speed and user experience.</p>\n        </div>\n\n        <!-- Marketing -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-marketing\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Marketing</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Allow us to show you relevant content and offers.</p>\n        </div>\n      </div>\n\n      <div class=\"cookie-modal-footer-info\">\n        <small class=\"cookie-updated\"\n          >Last updated: December 11, 2025</small\n        >\n      </div>\n    </div>\n\n    <div class=\"cookie-modal-footer\">\n      <button id=\"modal-reject\" class=\"cookie-btn cookie-btn-reject\">\n        Reject\n      </button>\n      <button id=\"modal-save\" class=\"cookie-btn cookie-btn-accept\">\n        Save Preferences\n      </button>\n    </div>\n  </div>\n</div>\n\n<style>\n  .cookie-consent-banner {\n    position: fixed;\n    bottom: 0;\n    left: 0;\n    right: 0;\n    background: var(--bg-secondary);\n    border-top: 1px solid var(--border);\n    border-left: 3px solid var(--accent-primary);\n    padding: 20px;\n    z-index: 1000;\n    box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.15);\n    animation: slideUp 0.3s ease-out;\n  }\n\n  @keyframes slideUp {\n    from {\n      transform: translateY(100%);\n      opacity: 0;\n    }\n    to {\n      transform: translateY(0);\n      opacity: 1;\n    }\n  }\n\n  .cookie-consent-content {\n    max-width: 1200px;\n    margin: 0 auto;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    gap: 24px;\n    flex-wrap: wrap;\n  }\n\n  .cookie-consent-text {\n    flex: 1;\n    min-width: 280px;\n  }\n\n  .cookie-consent-title {\n    margin: 0 0 8px 0;\n    font-size: 16px;\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-consent-message {\n    margin: 0 0 8px 0;\n    font-size: 14px;\n    color: var(--text-secondary);\n    line-height: 1.5;\n  }\n\n  .cookie-consent-subtext {\n    margin: 8px 0 0 0;\n    font-size: 12px;\n    color: var(--text-secondary);\n  }\n\n  .cookie-consent-subtext a {\n    color: var(--accent-primary);\n    text-decoration: none;\n    font-weight: 500;\n  }\n\n  .cookie-consent-subtext a:hover {\n    text-decoration: underline;\n  }\n\n  .cookie-consent-actions {\n    display: flex;\n    gap: 12px;\n    flex-shrink: 0;\n  }\n\n  .cookie-btn {\n    padding: 8px 16px;\n    border-radius: var(--radius);\n    border: 1px solid var(--border);\n    font-size: 13px;\n    font-weight: 500;\n    cursor: pointer;\n    transition: all 0.2s ease;\n    white-space: nowrap;\n  }\n\n  .cookie-btn-manage {\n    background: var(--bg-primary);\n    color: var(--accent-primary);\n    border-color: var(--accent-primary);\n    font-weight: 600;\n  }\n\n  .cookie-btn-manage:hover {\n    background: var(--bg);\n    opacity: 0.9;\n  }\n\n  .cookie-btn-reject {\n    background: var(--bg-primary);\n    color: var(--text);\n    border-color: var(--border);\n  }\n\n  .cookie-btn-reject:hover {\n    background: var(--bg);\n    border-color: var(--text-secondary);\n  }\n\n  .cookie-btn-accept {\n    background: var(--accent-primary);\n    color: #000000;\n    border-color: var(--accent-primary);\n    font-weight: 600;\n  }\n\n  .cookie-btn-accept:hover {\n    opacity: 0.9;\n    transform: translateY(-1px);\n    box-shadow: 0 2px 8px rgba(27, 217, 111, 0.2);\n  }\n\n  .cookie-btn:active {\n    transform: translateY(0);\n  }\n\n  @media (max-width: 768px) {\n    .cookie-consent-banner {\n      padding: 16px;\n    }\n\n    .cookie-consent-content {\n      flex-direction: column;\n      gap: 16px;\n    }\n\n    .cookie-consent-actions {\n      width: 100%;\n      flex-direction: column;\n    }\n\n    .cookie-btn {\n      width: 100%;\n      padding: 10px 16px;\n    }\n  }\n\n  /* Modal Styles */\n  .cookie-modal {\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    z-index: 2000;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    animation: fadeIn 0.3s ease-out;\n  }\n\n  @keyframes fadeIn {\n    from {\n      opacity: 0;\n    }\n    to {\n      opacity: 1;\n    }\n  }\n\n  .cookie-modal-overlay {\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0, 0, 0, 0.5);\n    cursor: pointer;\n  }\n\n  .cookie-modal-content {\n    position: relative;\n    background: var(--bg-secondary);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n    max-width: 600px;\n    width: 90%;\n    max-height: 90vh;\n    overflow: auto;\n    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n    animation: slideIn 0.3s ease-out;\n  }\n\n  @keyframes slideIn {\n    from {\n      transform: scale(0.95);\n      opacity: 0;\n    }\n    to {\n      transform: scale(1);\n      opacity: 1;\n    }\n  }\n\n  .cookie-modal-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    padding: 24px;\n    border-bottom: 1px solid var(--border);\n  }\n\n  .cookie-modal-title {\n    margin: 0;\n    font-size: 20px;\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-modal-close {\n    background: none;\n    border: none;\n    color: var(--text-secondary);\n    font-size: 20px;\n    cursor: pointer;\n    padding: 0;\n    width: 32px;\n    height: 32px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    border-radius: var(--radius);\n    transition: all 0.2s;\n  }\n\n  .cookie-modal-close:hover {\n    background: var(--border);\n    color: var(--text);\n  }\n\n  .cookie-modal-body {\n    padding: 24px;\n  }\n\n  .cookie-categories {\n    display: flex;\n    flex-direction: column;\n    gap: 24px;\n    margin-bottom: 24px;\n  }\n\n  .cookie-category {\n    padding: 16px;\n    background: var(--bg-primary);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n  }\n\n  .cookie-category-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    margin-bottom: 8px;\n  }\n\n  .cookie-checkbox-label {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    cursor: pointer;\n    flex: 1;\n  }\n\n  .cookie-checkbox {\n    width: 18px;\n    height: 18px;\n    cursor: pointer;\n    accent-color: var(--accent-primary);\n  }\n\n  .cookie-checkbox:disabled {\n    opacity: 0.5;\n    cursor: not-allowed;\n  }\n\n  .cookie-category-title {\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-badge {\n    display: inline-block;\n    padding: 4px 8px;\n    border-radius: 4px;\n    font-size: 11px;\n    font-weight: 600;\n    text-transform: uppercase;\n    background: var(--accent-primary);\n    color: #000000;\n  }\n\n  .cookie-category-desc {\n    margin: 8px 0 0 28px;\n    font-size: 13px;\n    color: var(--text-secondary);\n    line-height: 1.5;\n  }\n\n  .cookie-details {\n    margin: 12px 0 0 28px;\n    cursor: pointer;\n  }\n\n  .cookie-details summary {\n    font-size: 12px;\n    color: var(--accent-primary);\n    font-weight: 500;\n    text-decoration: underline;\n    padding: 4px 0;\n  }\n\n  .cookie-details summary:hover {\n    opacity: 0.8;\n  }\n\n  .cookie-list {\n    margin-top: 8px;\n    padding: 8px;\n    background: var(--bg);\n    border-radius: 4px;\n    border: 1px solid var(--border);\n  }\n\n  .cookie-item {\n    display: flex;\n    justify-content: space-between;\n    font-size: 12px;\n    padding: 6px 0;\n    color: var(--text-secondary);\n    border-bottom: 1px solid var(--border);\n  }\n\n  .cookie-item:last-child {\n    border-bottom: none;\n  }\n\n  .cookie-item-name {\n    font-family: monospace;\n    font-weight: 500;\n    color: var(--text);\n  }\n\n  .cookie-item-expiration {\n    font-size: 11px;\n  }\n\n  .cookie-modal-footer-info {\n    margin-bottom: 16px;\n    padding-top: 16px;\n    border-top: 1px solid var(--border);\n  }\n\n  .cookie-updated {\n    font-size: 12px;\n    color: var(--text-secondary);\n  }\n\n  .cookie-modal-footer {\n    display: flex;\n    gap: 12px;\n    padding: 16px 24px;\n    border-top: 1px solid var(--border);\n    background: var(--bg-primary);\n    justify-content: flex-end;\n  }\n\n  .cookie-modal-footer .cookie-btn {\n    flex: 1;\n  }\n\n  @media (max-width: 640px) {\n    .cookie-modal-content {\n      width: 95%;\n      max-height: 95vh;\n    }\n\n    .cookie-modal-header {\n      padding: 16px;\n    }\n\n    .cookie-modal-body {\n      padding: 16px;\n    }\n\n    .cookie-modal-footer {\n      flex-direction: column;\n      padding: 16px;\n    }\n\n    .cookie-modal-footer .cookie-btn {\n      width: 100%;\n    }\n\n    .cookie-category-desc {\n      margin-left: 28px;\n    }\n\n    .cookie-details {\n      margin-left: 28px;\n    }\n  }\n</style>\n\n<script>\n  document.addEventListener(\"DOMContentLoaded\", () => {\n    const banner = document.getElementById(\"cookie-consent\");\n    const modal = document.getElementById(\"cookie-modal\");\n    const acceptBtn = document.getElementById(\"cookie-accept\");\n    const rejectBtn = document.getElementById(\"cookie-reject\");\n    const manageBtn = document.getElementById(\"cookie-manage\");\n    const modalClose = document.getElementById(\"modal-close\");\n    const modalOverlay = document.querySelector(\".cookie-modal-overlay\");\n    const modalRejectBtn = document.getElementById(\"modal-reject\");\n    const modalSaveBtn = document.getElementById(\"modal-save\");\n    const consentKey = \"abc-cookie-consent\";\n    const categoriesKey = \"abc-cookie-categories\";\n\n    // Preference checkboxes\n    const analyticsCheckbox = document.getElementById(\"cookie-analytics\");\n    const performanceCheckbox = document.getElementById(\"cookie-performance\");\n    const marketingCheckbox = document.getElementById(\"cookie-marketing\");\n\n    // Load saved preferences\n    const loadPreferences = () => {\n      const saved = localStorage.getItem(categoriesKey);\n      if (saved) {\n        const prefs = JSON.parse(saved);\n        analyticsCheckbox.checked = prefs.analytics || false;\n        performanceCheckbox.checked = prefs.performance || false;\n        marketingCheckbox.checked = prefs.marketing || false;\n      }\n    };\n\n    // Save preferences\n    const savePreferences = () => {\n      const prefs = {\n        analytics: analyticsCheckbox.checked,\n        performance: performanceCheckbox.checked,\n        marketing: marketingCheckbox.checked,\n      };\n      localStorage.setItem(categoriesKey, JSON.stringify(prefs));\n      localStorage.setItem(consentKey, \"custom\");\n      dismissBanner();\n      updateConsent(prefs);\n    };\n\n    // Dismiss banner with animation\n    const dismissBanner = () => {\n      banner.style.animation = \"slideDown 0.3s ease-out forwards\";\n      setTimeout(() => {\n        banner.style.display = \"none\";\n      }, 300);\n      modal.style.animation = \"fadeOut 0.3s ease-out forwards\";\n      setTimeout(() => {\n        modal.style.display = \"none\";\n      }, 300);\n    };\n\n    // Update analytics consent\n    const updateConsent = (prefs) => {\n      if (window.gtag) {\n        gtag(\"consent\", \"update\", {\n          analytics_storage: prefs.analytics ? \"granted\" : \"denied\",\n        });\n      }\n    };\n\n    // Check if user has already made a choice\n    const userConsent = localStorage.getItem(consentKey);\n\n    if (!userConsent) {\n      setTimeout(() => {\n        banner.style.display = \"flex\";\n      }, 1000);\n    }\n\n    loadPreferences();\n\n    // Accept all cookies\n    acceptBtn.addEventListener(\"click\", () => {\n      analyticsCheckbox.checked = true;\n      performanceCheckbox.checked = true;\n      marketingCheckbox.checked = true;\n      savePreferences();\n    });\n\n    // Reject all cookies (keep only essential)\n    const rejectAllCookies = () => {\n      analyticsCheckbox.checked = false;\n      performanceCheckbox.checked = false;\n      marketingCheckbox.checked = false;\n      localStorage.setItem(\n        categoriesKey,\n        JSON.stringify({\n          analytics: false,\n          performance: false,\n          marketing: false,\n        })\n      );\n      localStorage.setItem(consentKey, \"rejected\");\n      dismissBanner();\n      updateConsent({ analytics: false, performance: false, marketing: false });\n    };\n\n    rejectBtn.addEventListener(\"click\", rejectAllCookies);\n    modalRejectBtn.addEventListener(\"click\", rejectAllCookies);\n\n    // Manage preferences\n    manageBtn.addEventListener(\"click\", () => {\n      modal.style.display = \"flex\";\n      loadPreferences();\n    });\n\n    // Modal controls\n    modalClose.addEventListener(\"click\", () => {\n      modal.style.animation = \"fadeOut 0.3s ease-out forwards\";\n      setTimeout(() => {\n        modal.style.display = \"none\";\n      }, 300);\n    });\n\n    modalOverlay.addEventListener(\"click\", () => {\n      modalClose.click();\n    });\n\n    // Save preferences from modal\n    modalSaveBtn.addEventListener(\"click\", savePreferences);\n\n    // ESC key to close modal\n    document.addEventListener(\"keydown\", (e) => {\n      if (e.key === \"Escape\" && modal.style.display === \"flex\") {\n        modalClose.click();\n      }\n    });\n\n    // Add fadeOut animation\n    const style = document.createElement(\"style\");\n    style.textContent = `\n      @keyframes slideDown {\n        to {\n          transform: translateY(100%);\n          opacity: 0;\n        }\n      }\n      @keyframes fadeOut {\n        to {\n          opacity: 0;\n        }\n      }\n    `;\n    document.head.appendChild(style);\n  });\n</script>\n\n\n    <!-- Scripts -->\n    <script src=\"/assets/js/search.js\"></script>\n    <script src=\"/assets/js/performance.js\"></script>\n    <script src=\"/assets/js/visual-enhancements.js\"></script>\n  </body>\n</html>\n"]},"tags":{"announcement":["\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <title>Welcome to the Blog</title>\n    <meta\n      name=\"description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta\n      name=\"robots\"\n      content=\"index, follow\"\n    />\n\n    <!-- SEO Meta Tags -->\n          \n\n    <meta\n      property=\"og:title\"\n      content=\"Welcome to the Blog\"\n    />\n    <meta\n      property=\"og:description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta property=\"og:url\" content=\"https://abc-site.devvyy.xyz/blog/blog-test/\" />\n    <meta property=\"og:image\" content=\"https://abc-site.devvyy.xyz/assets/images/logo.svg\" />\n    <meta property=\"og:image:alt\" content=\"ABC Mods & Packs\" />\n    <meta property=\"og:type\" content=\"post\" />\n    <meta property=\"og:site_name\" content=\"ABC\" />\n    <meta\n      property=\"og:locale\"\n      content=\"en_US\"\n    />\n\n    <!-- hreflang tags for multilingual SEO -->\n    <link\n      rel=\"alternate\"\n      hreflang=\"en\"\n      href=\"https://abc-site.devvyy.xyz/blog/blog-test/\"\n    />\n    <link\n      rel=\"alternate\"\n      hreflang=\"fr\"\n      href=\"https://abc-site.devvyy.xyz/fr/blog/blog-test/\"\n    />\n    <link\n      rel=\"alternate\"\n      hreflang=\"x-default\"\n      href=\"https://abc-site.devvyy.xyz/blog/blog-test/\"\n    />\n\n    <!-- Twitter Card -->\n    <meta name=\"twitter:card\" content=\"summary_large_image\" />\n    <meta\n      name=\"twitter:title\"\n      content=\"Welcome to the Blog\"\n    />\n    <meta\n      name=\"twitter:description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta\n      name=\"twitter:image\"\n      content=\"https://abc-site.devvyy.xyz/assets/images/logo.svg\"\n    />\n    <meta name=\"twitter:image:alt\" content=\"ABC Mods & Packs\" />\n    <meta\n      name=\"twitter:creator\"\n      content=\"@devvyyxyz\"\n    />\n    <meta\n      name=\"twitter:site\"\n      content=\"@devvyyxyz\"\n    />\n\n    <meta\n      name=\"theme-color\"\n      content=\"#1bd96f\"\n    />\n\n    <!-- Favicon -->\n    <link\n      rel=\"icon\"\n      type=\"image/svg+xml\"\n      href=\"/favicon.svg\"\n    />\n    <link\n      rel=\"icon\"\n      type=\"image/x-icon\"\n      href=\"/favicon.svg\"\n    />\n    <link\n      rel=\"apple-touch-icon\"\n      href=\"/assets/images/logo.svg\"\n    />\n\n    <!-- Google Fonts - Preload -->\n    <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n    <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n    <link\n      rel=\"preload\"\n      as=\"style\"\n      href=\"https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap\"\n    />\n    <link\n      href=\"https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap\"\n      rel=\"stylesheet\"\n    />\n\n    <!-- Font Awesome Icons - Async load -->\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <noscript>\n      <link\n        rel=\"stylesheet\"\n        href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n      />\n    </noscript>\n\n    <!-- Stylesheets - Critical -->\n    <link rel=\"stylesheet\" href=\"/assets/css/root.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/layout.css\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/loading.css\"\n    />\n\n    <!-- Stylesheets - Deferred (non-critical) -->\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/components.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/modpacks.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/animations.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/theme.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/a11y.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/visual-enhancements.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/mobile.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <noscript>\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/components.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/modpacks.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/animations.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/theme.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/a11y.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/visual-enhancements.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/mobile.css\"\n      />\n    </noscript>\n\n    <!-- Canonical URL -->\n    <link rel=\"canonical\" href=\"https://abc-site.devvyy.xyz/blog/blog-test/\" />\n\n    <!-- Schema Markup -->\n    <!-- Schema.org JSON-LD -->\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"Organization\",\n    \"name\": \"ABC\",\n    \"description\": \"Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins.\",\n    \"url\": \"https://abc-site.devvyy.xyz\",\n    \"logo\": \"https://abc-site.devvyy.xyz/assets/images/logo.svg\",\n    \"sameAs\": [\n      \"https://github.com/devvyyxyz\",\n      \"https://twitter.com/devvyyxyz\",\n      \"https://dc.gg/devvyyxyz\"\n    ],\n    \"contactPoint\": {\n      \"@type\": \"ContactPoint\",\n      \"contactType\": \"Community Support\",\n      \"url\": \"https://dc.gg/devvyyxyz\"\n    }\n  }\n</script>\n\n<!-- Breadcrumb Schema -->\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"BreadcrumbList\",\n    \"itemListElement\": [\n      {\n        \"@type\": \"ListItem\",\n        \"position\": 1,\n        \"name\": \"Home\",\n        \"item\": \"https://abc-site.devvyy.xyz\"\n      }\n      \n      , {\n        \"@type\": \"ListItem\",\n        \"position\": 2,\n        \"name\": \"Welcome to the Blog\",\n        \"item\": \"https://abc-site.devvyy.xyz/blog/blog-test/\"\n      }\n      \n    ]\n  }\n</script>\n\n<!-- Project/Software Application Schema (for project pages) -->\n\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"Article\",\n    \"headline\": \"Welcome to the Blog\",\n    \"description\": \"Kicking off our new blog — what's coming next.\",\n    \"image\": \"\",\n    \"datePublished\": \"2025-12-16T00:00:00+00:00\",\n    \"dateModified\": \"2025-12-16T00:00:00+00:00\",\n    \"author\": {\n      \"@type\": \"Organization\",\n      \"name\": \"ABC\"\n    },\n    \"publisher\": {\n      \"@type\": \"Organization\",\n      \"name\": \"ABC\",\n      \"logo\": {\n        \"@type\": \"ImageObject\",\n        \"url\": \"https://abc-site.devvyy.xyz/assets/images/logo.svg\"\n      }\n    }\n  }\n</script>\n<!-- WebPage Schema -->\n\n\n\n    <!-- Preloader Script (critical, inline) -->\n    <script>\n      (function () {\n        if (!document.body) return; // Exit if body not ready yet\n\n        const isDarkMode =\n          window.matchMedia &&\n          window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n        const bgColor = isDarkMode ? \"#0d0d0d\" : \"#f6fbfa\";\n        document.documentElement.style.backgroundColor = bgColor;\n        document.body.style.backgroundColor = bgColor;\n\n        const overlay = document.createElement(\"div\");\n        overlay.className = \"loading-overlay\";\n        overlay.id = \"loading-overlay\";\n        overlay.innerHTML = '<div class=\"spinner\"></div>';\n        document.body.appendChild(overlay);\n\n        if (document.readyState === \"loading\") {\n          document.addEventListener(\"DOMContentLoaded\", hidePreloader);\n        } else {\n          hidePreloader();\n        }\n\n        function hidePreloader() {\n          const preloader = document.getElementById(\"loading-overlay\");\n          if (preloader) {\n            preloader.classList.add(\"hidden\");\n          }\n        }\n\n        window.hidePreloader = hidePreloader;\n      })();\n    </script>\n  </head>\n  <body>\n    <a href=\"#main\" class=\"skip-to-main\">Skip to main content</a>\n    <header class=\"floating-nav\">\n  <div class=\"nav-inner\">\n    <a\n      class=\"logo\"\n      href=\"/\"\n      style=\"display: flex; align-items: center; gap: 8px\"\n      aria-label=\"ABC\"\n    >\n      <img\n        src=\"/assets/images/logo.svg\"\n        alt=\"ABC\"\n        style=\"height: 32px; width: auto\"\n      />\n      \n    </a>\n    <button\n      class=\"mobile-menu-toggle\"\n      aria-label=\"Toggle menu\"\n      id=\"mobile-menu-toggle\"\n    >\n      <i class=\"fas fa-bars\"></i>\n    </button>\n    <nav class=\"links\" id=\"mobile-nav\">\n      <a href=\"/\">Home</a>\n      <a href=\"/about/\">About</a>\n      <a href=\"/docs/\">Docs</a>\n      <a href=\"/changelog/\">Changelog</a>\n      <a href=\"/blog/\">Blog</a>\n      <div class=\"nav-dropdown\">\n        <a href=\"/projects/\" class=\"dropdown-toggle\">\n          Projects <i class=\"fas fa-chevron-down\"></i>\n        </a>\n        <div class=\"dropdown-menu\">\n          <a href=\"/projects/\">All Projects</a>\n          <a href=\"/compare/\"\n            ><i class=\"fas fa-balance-scale\"></i> Compare Modpacks</a\n          >\n          <a href=\"/changelog/\"\n            ><i class=\"fas fa-rocket\"></i> Releases & Changelog</a\n          >\n        </div>\n      </div>\n      <div class=\"nav-dropdown\">\n        <a href=\"#\" class=\"dropdown-toggle\">\n          Legal <i class=\"fas fa-chevron-down\"></i>\n        </a>\n        <div class=\"dropdown-menu\">\n          <a href=\"/privacy/\">Privacy Policy</a>\n          <a href=\"/terms/\">Terms of Service</a>\n          <a href=\"/cookie-policy/\">Cookie Policy</a>\n          <a href=\"/licensing/\">Licensing</a>\n          <a href=\"/eula/\">EULA</a>\n          <a href=\"/disclaimer/\">Disclaimer</a>\n        </div>\n      </div>\n      <a\n        href=\"https://modrinth.com/organization/abcxyz\"\n        target=\"_blank\"\n        rel=\"noopener\"\n        >Organization</a\n      >\n    </nav>\n    <div class=\"nav-actions\">\n      <div\n        id=\"social-links-nav\"\n        style=\"display: flex; gap: 6px; align-items: center\"\n      ></div>\n      <!-- Theme Toggle -->\n<div class=\"theme-toggle\" id=\"theme-toggle\" title=\"Toggle dark/light mode\">\n  <button id=\"theme-dark\" class=\"active\" aria-label=\"Dark mode\" title=\"Dark mode\">\n    <i class=\"fa-solid fa-moon\"></i>\n  </button>\n  <button id=\"theme-light\" aria-label=\"Light mode\" title=\"Light mode\">\n    <i class=\"fa-solid fa-sun\"></i>\n  </button>\n</div>\n\n<script>\n  // Theme toggle functionality\n  const themeToggle = {\n    init() {\n      this.darkBtn = document.getElementById('theme-dark');\n      this.lightBtn = document.getElementById('theme-light');\n      this.html = document.documentElement;\n\n      // Load saved theme or use system preference\n      const saved = localStorage.getItem('theme');\n      const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;\n      const theme = saved || (systemDark ? 'dark' : 'light');\n\n      this.setTheme(theme);\n\n      // Listen for changes\n      this.darkBtn.addEventListener('click', () => this.setTheme('dark'));\n      this.lightBtn.addEventListener('click', () => this.setTheme('light'));\n\n      // Listen for system theme changes\n      window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {\n        if (!localStorage.getItem('theme')) {\n          this.setTheme(e.matches ? 'dark' : 'light');\n        }\n      });\n    },\n\n    setTheme(theme) {\n      this.html.setAttribute('data-theme', theme);\n      localStorage.setItem('theme', theme);\n\n      this.darkBtn.classList.toggle('active', theme === 'dark');\n      this.lightBtn.classList.toggle('active', theme === 'light');\n\n      // Update meta theme-color\n      const color = theme === 'dark' ? '#1bd96f' : '#1bd96f';\n      document.querySelector('meta[name=\"theme-color\"]').setAttribute('content', color);\n    }\n  };\n\n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', () => themeToggle.init());\n  } else {\n    themeToggle.init();\n  }\n</script>\n\n    </div>\n  </div>\n</header>\n\n<script>\n  // Mobile menu toggle\n  document.addEventListener(\"DOMContentLoaded\", () => {\n    const toggle = document.getElementById(\"mobile-menu-toggle\");\n    const nav = document.getElementById(\"mobile-nav\");\n\n    if (toggle && nav) {\n      toggle.addEventListener(\"click\", () => {\n        nav.classList.toggle(\"mobile-open\");\n        const icon = toggle.querySelector(\"i\");\n        if (nav.classList.contains(\"mobile-open\")) {\n          icon.classList.remove(\"fa-bars\");\n          icon.classList.add(\"fa-times\");\n        } else {\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        }\n      });\n\n      // Close menu when clicking a link\n      nav.querySelectorAll(\"a\").forEach((link) => {\n        link.addEventListener(\"click\", () => {\n          nav.classList.remove(\"mobile-open\");\n          const icon = toggle.querySelector(\"i\");\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        });\n      });\n\n      // Close menu when clicking outside\n      document.addEventListener(\"click\", (e) => {\n        if (!toggle.contains(e.target) && !nav.contains(e.target)) {\n          nav.classList.remove(\"mobile-open\");\n          const icon = toggle.querySelector(\"i\");\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        }\n      });\n    }\n  });\n</script>\n\n\n    <main id=\"main\" class=\"container\"><main class=\"content\">\n  <article class=\"post\" style=\"max-width: 820px; margin: 0 auto; padding: 24px\">\n    <header>\n      <h1 style=\"margin: 0 0 8px\">Welcome to the Blog</h1>\n      <p class=\"muted\" style=\"margin: 0 0 16px\">\n        December 16, 2025 • ABC Team\n      </p>\n    </header>\n    <section class=\"post-body\"><p>We’re launching a blog to share updates, release notes, and behind-the-scenes dev logs.</p>\n\n<!--more-->\n\n<p>What you can expect:</p>\n\n<ul>\n  <li>Deep dives into mods, datapacks, and plugins</li>\n  <li>Roadmap updates and upcoming releases</li>\n  <li>Performance tips and compatibility notes</li>\n  <li>Community showcases and contributions</li>\n</ul>\n\n<p>If you have topics you’d like us to cover, let us know on the contact page or Discord.</p>\n</section>\n\n    \n    <footer style=\"margin-top: 24px\">\n      <strong>Tags:</strong>\n      \n      <span\n        style=\"\n          display: inline-block;\n          padding: 4px 8px;\n          border: 1px solid var(--border);\n          border-radius: 999px;\n          margin-right: 6px;\n          font-size: 12px;\n        \"\n        >#announcement</span\n      >\n      \n      <span\n        style=\"\n          display: inline-block;\n          padding: 4px 8px;\n          border: 1px solid var(--border);\n          border-radius: 999px;\n          margin-right: 6px;\n          font-size: 12px;\n        \"\n        >#roadmap</span\n      >\n       \n      <div style=\"margin-top: 8px\">\n        <strong>Categories:</strong>\n        \n        <span\n          style=\"\n            display: inline-block;\n            padding: 4px 8px;\n            border: 1px solid var(--border);\n            border-radius: 999px;\n            margin-right: 6px;\n            font-size: 12px;\n          \"\n          >updates</span\n        >\n        \n      </div>\n      \n    </footer>\n    \n  </article>\n</main>\n</main>\n\n    <footer class=\"floating-footer\">\n  <div class=\"footer-inner\">\n    <div style=\"display: flex; gap: 16px; align-items: flex-start\">\n      <img\n        src=\"/assets/images/logo.svg\"\n        alt=\"ABC logo\"\n        style=\"height: 100px; flex-shrink: 0; width: auto\"\n        width=\"100\"\n        height=\"100\"\n      />\n      <div style=\"display: flex; flex-direction: column; gap: 8px\">\n        <div>\n          <h4\n            style=\"\n              margin: 0;\n              font-size: 18px;\n              font-weight: 700;\n              color: var(--text);\n            \"\n          >\n            ABC\n          </h4>\n          <p\n            style=\"\n              margin: 2px 0 0 0;\n              font-size: 12px;\n              color: var(--text-secondary);\n            \"\n          >\n            Established 2025\n          </p>\n        </div>\n        <p\n          style=\"\n            margin: 0;\n            font-size: 13px;\n            color: var(--text-secondary);\n            line-height: 1.6;\n          \"\n        >\n          Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins.\n        </p>\n      </div>\n    </div>\n    <div style=\"display: flex; gap: 48px\">\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Links\n        </h4>\n        <div\n          style=\"\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n            gap: 10px 12px;\n            font-size: 13px;\n            max-width: 320px;\n          \"\n        >\n          <a\n            href=\"/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Home</a\n          >\n          <a\n            href=\"/about/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >About</a\n          >\n          <a\n            href=\"/docs/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Docs</a\n          >\n          <a\n            href=\"/projects/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Projects</a\n          >\n          <a\n            href=\"/compare/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Compare</a\n          >\n          <a\n            href=\"/changelog/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Changelog</a\n          >\n          <a\n            href=\"https://modrinth.com/organization/abcxyz\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            target=\"_blank\"\n            rel=\"noopener\"\n            >Modrinth Org</a\n          >\n          <a\n            href=\"https://github.com/devvyyxyz\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            target=\"_blank\"\n            rel=\"noopener\"\n            >GitHub Org</a\n          >\n          <a\n            href=\"/sitemap.xml\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Sitemap</a\n          >\n          <a\n            href=\"/feed.xml\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >RSS Feed</a\n          >\n          <a\n            href=\"/blog/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Blog</a\n          >\n        </div>\n      </div>\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Help\n        </h4>\n        <div\n          style=\"\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n            gap: 10px 12px;\n            font-size: 13px;\n            max-width: 320px;\n          \"\n        >\n          <a\n            href=\"/contact/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Contact</a\n          >\n          <a\n            href=\"/docs/faq/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >FAQ</a\n          >\n          <a\n            href=\"/docs/troubleshooting/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Troubleshooting</a\n          >\n          <a\n            href=\"/docs/contributing/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Contributing</a\n          >\n          <a\n            href=\"/status/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Status</a\n          >\n        </div>\n      </div>\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Community\n        </h4>\n        <div\n          id=\"social-links-footer\"\n          style=\"display: flex; gap: 12px; flex-direction: column\"\n        ></div>\n      </div>\n    </div>\n  </div>\n  <div\n    style=\"\n      border-top: 1px solid var(--border);\n      margin-top: 32px;\n      padding-top: 24px;\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      font-size: 12px;\n      color: var(--text-secondary);\n      flex-wrap: wrap;\n      gap: 16px;\n    \"\n  >\n    <div style=\"display: flex; gap: 16px; align-items: center; flex-wrap: wrap\">\n      <div>\n        © <span id=\"year\"></span> ABC. All rights reserved.\n      </div>\n      <div\n        id=\"language-switcher\"\n        style=\"display: flex; gap: 8px; align-items: center\"\n      >\n        <span style=\"font-size: 12px; color: var(--text-secondary)\"\n          >Language:</span\n        >\n        <select\n          id=\"lang-select\"\n          style=\"\n            padding: 4px 8px;\n            border: 1px solid var(--border);\n            border-radius: var(--radius);\n            background: var(--bg-secondary);\n            color: var(--text);\n            font-size: 12px;\n            cursor: pointer;\n          \"\n        >\n          <option value=\"en\">English</option>\n          <option value=\"fr\">Français</option>\n        </select>\n      </div>\n    </div>\n    <div style=\"display: flex; gap: 20px\">\n      <a\n        href=\"/privacy/\"\n        style=\"\n          color: var(--text-secondary);\n          text-decoration: none;\n          transition: color 0.2s;\n        \"\n        >Privacy</a\n      >\n      <a\n        href=\"/terms/\"\n        style=\"\n          color: var(--text-secondary);\n          text-decoration: none;\n          transition: color 0.2s;\n        \"\n        >Terms</a\n      >\n    </div>\n  </div>\n</footer>\n\n<script>\n  // Social links configuration\n  const socials = {\n    github: {\n      name: \"GitHub\",\n      icon: \"fab fa-github\",\n      url: \"https://github.com/devvyyxyz\",\n    },\n    twitter: {\n      name: \"Twitter\",\n      icon: \"fab fa-x-twitter\",\n      url: \"https://twitter.com/devvyyxyz\",\n    },\n    discord: {\n      name: \"Discord\",\n      icon: \"fab fa-discord\",\n      url: \"https://dc.gg/devvyyxyz\",\n    },\n  };\n\n  function renderSocialLinks() {\n    const navContainer = document.getElementById(\"social-links-nav\");\n    const footerContainer = document.getElementById(\"social-links-footer\");\n\n    Object.entries(socials).forEach(([key, social]) => {\n      if (social.url && social.url.trim()) {\n        // Nav icon button\n        const navLink = document.createElement(\"a\");\n        navLink.href = social.url;\n        navLink.target = \"_blank\";\n        navLink.rel = \"noopener\";\n        navLink.title = social.name;\n        navLink.style.cssText =\n          \"display:flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:var(--radius);background:var(--bg-secondary);color:var(--text-secondary);text-decoration:none;font-size:16px;transition:all 0.2s ease;border:1px solid var(--border)\";\n        const icon = document.createElement(\"i\");\n        icon.className = social.icon;\n        icon.style.fontSize = \"18px\";\n        navLink.appendChild(icon);\n        navLink.onmouseover = () => {\n          navLink.style.background = \"var(--accent-primary)\";\n          navLink.style.color = \"#000000\";\n          navLink.style.borderColor = \"var(--accent-primary)\";\n        };\n        navLink.onmouseout = () => {\n          navLink.style.background = \"var(--bg-secondary)\";\n          navLink.style.color = \"var(--text-secondary)\";\n          navLink.style.borderColor = \"var(--border)\";\n        };\n        if (navContainer) navContainer.appendChild(navLink);\n\n        // Footer text link with icon\n        const footerLink = document.createElement(\"a\");\n        footerLink.href = social.url;\n        footerLink.target = \"_blank\";\n        footerLink.rel = \"noopener\";\n        footerLink.style.cssText =\n          \"display:flex;align-items:center;gap:8px;color:var(--text-secondary);text-decoration:none;transition:color 0.2s;font-size:13px\";\n        const footerIcon = document.createElement(\"i\");\n        footerIcon.className = social.icon;\n        footerIcon.style.width = \"16px\";\n        const footerText = document.createElement(\"span\");\n        footerText.textContent = social.name;\n        footerLink.appendChild(footerIcon);\n        footerLink.appendChild(footerText);\n        footerLink.onmouseover = () => {\n          footerLink.style.color = \"var(--accent-primary)\";\n        };\n        footerLink.onmouseout = () => {\n          footerLink.style.color = \"var(--text-secondary)\";\n        };\n        if (footerContainer) footerContainer.appendChild(footerLink);\n      }\n    });\n  }\n\n  document.addEventListener(\"DOMContentLoaded\", renderSocialLinks);\n\n  // Set year in footer\n  document.getElementById(\"year\").textContent = new Date().getFullYear();\n\n  // Language switcher\n  const langSelect = document.getElementById(\"lang-select\");\n  if (langSelect) {\n    const currentLang = 'en';\n    langSelect.value = currentLang;\n\n    langSelect.addEventListener(\"change\", (e) => {\n      const selectedLang = e.target.value;\n      const currentPath = window.location.pathname;\n      const baseUrl = \"\";\n\n      // Remove existing language prefix\n      let cleanPath = currentPath.replace(baseUrl, \"\");\n      cleanPath = cleanPath.replace(/^\\/(en|fr)/, \"\");\n\n      // Build new URL\n      const newPath =\n        selectedLang === \"en\"\n          ? baseUrl + cleanPath\n          : baseUrl + \"/\" + selectedLang + cleanPath;\n\n      window.location.href = newPath;\n    });\n  }\n</script>\n <!-- Scroll to top button -->\n<button id=\"scroll-to-top\" class=\"scroll-to-top\" aria-label=\"Scroll to top\" title=\"Back to top\">\n  <i class=\"fa-solid fa-chevron-up\"></i>\n</button>\n\n<script>\n  // Scroll to top functionality\n  const scrollButton = document.getElementById('scroll-to-top');\n\n  window.addEventListener('scroll', () => {\n    if (window.scrollY > 300) {\n      scrollButton.classList.add('visible');\n    } else {\n      scrollButton.classList.remove('visible');\n    }\n  });\n\n  scrollButton.addEventListener('click', () => {\n    window.scrollTo({ top: 0, behavior: 'smooth' });\n  });\n\n  // Handle keyboard interaction\n  scrollButton.addEventListener('keydown', (e) => {\n    if (e.key === 'Enter' || e.key === ' ') {\n      e.preventDefault();\n      window.scrollTo({ top: 0, behavior: 'smooth' });\n    }\n  });\n</script>\n\n<!-- Lazy loading images with placeholder -->\n<script>\n  // Intersection Observer for lazy loading\n  if ('IntersectionObserver' in window) {\n    const imageObserver = new IntersectionObserver((entries, observer) => {\n      entries.forEach(entry => {\n        if (entry.isIntersecting) {\n          const img = entry.target;\n          img.src = img.dataset.src || img.src;\n          img.classList.remove('lazy');\n          observer.unobserve(img);\n        }\n      });\n    }, {\n      rootMargin: '50px 0px',\n      threshold: 0.01\n    });\n\n    document.querySelectorAll('img[data-src]').forEach(img => {\n      imageObserver.observe(img);\n    });\n  }\n</script>\n\n<!-- Smooth page transitions -->\n<script>\n  // Add page transition class on load\n  document.addEventListener('DOMContentLoaded', () => {\n    document.body.classList.add('page-transition');\n  });\n\n  // Handle link clicks for smooth transitions\n  document.addEventListener('click', (e) => {\n    const link = e.target.closest('a');\n    if (link && !link.target && link.hostname === window.location.hostname) {\n      // Internal link - add transition\n      e.preventDefault();\n      document.body.style.opacity = '0.8';\n      setTimeout(() => {\n        window.location.href = link.href;\n      }, 150);\n    }\n  });\n</script>\n\n\n    <!-- Cookie Consent Banner -->\n    <div\n  id=\"cookie-consent\"\n  class=\"cookie-consent-banner\"\n  role=\"alertdialog\"\n  aria-labelledby=\"cookie-title\"\n  aria-describedby=\"cookie-description\"\n  style=\"display: none\"\n>\n  <div class=\"cookie-consent-content\">\n    <div class=\"cookie-consent-text\">\n      <h3 id=\"cookie-title\" class=\"cookie-consent-title\">\n          Cookie Preferences\n      </h3>\n      <p id=\"cookie-description\" class=\"cookie-consent-message\">\n        We use cookies to improve your experience and analyze site performance. No personal data is collected.\n      </p>\n      <p class=\"cookie-consent-subtext\">\n        <a\n          href=\"/privacy/\"\n          target=\"_blank\"\n          rel=\"noopener\"\n          >Privacy Policy</a\n        >\n      </p>\n    </div>\n    <div class=\"cookie-consent-actions\">\n      <button\n        id=\"cookie-manage\"\n        class=\"cookie-btn cookie-btn-manage\"\n        aria-label=\"Manage cookie preferences\"\n      >\n        Manage Preferences\n      </button>\n      <button\n        id=\"cookie-reject\"\n        class=\"cookie-btn cookie-btn-reject\"\n        aria-label=\"Reject cookies\"\n      >\n        Reject\n      </button>\n      <button\n        id=\"cookie-accept\"\n        class=\"cookie-btn cookie-btn-accept\"\n        aria-label=\"Accept all cookies\"\n      >\n        Accept All\n      </button>\n    </div>\n  </div>\n</div>\n\n<!-- Cookie Settings Modal -->\n<div\n  id=\"cookie-modal\"\n  class=\"cookie-modal\"\n  style=\"display: none\"\n  role=\"dialog\"\n  aria-labelledby=\"modal-title\"\n  aria-hidden=\"true\"\n>\n  <div class=\"cookie-modal-overlay\"></div>\n  <div class=\"cookie-modal-content\">\n    <div class=\"cookie-modal-header\">\n      <h2 id=\"modal-title\" class=\"cookie-modal-title\">Cookie Preferences</h2>\n      <button\n        id=\"modal-close\"\n        class=\"cookie-modal-close\"\n        aria-label=\"Close modal\"\n      >\n        <i class=\"fas fa-times\"></i>\n      </button>\n    </div>\n\n    <div class=\"cookie-modal-body\">\n      <!-- Categories -->\n      <div class=\"cookie-categories\">\n        <!-- Essential -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-essential\"\n                class=\"cookie-checkbox\"\n                checked\n                disabled\n              />\n              <span class=\"cookie-category-title\"\n                >Essential</span\n              >\n            </label>\n            <span class=\"cookie-badge essential\">Essential</span>\n          </div>\n          <p class=\"cookie-category-desc\">Required for core site functionality. Always enabled.</p>\n        </div>\n\n        <!-- Analytics -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-analytics\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Analytics</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Help us understand how you use our site to improve it.</p>\n          <details class=\"cookie-details\">\n            <summary>All Cookies</summary>\n            <div class=\"cookie-list\">\n              <div class=\"cookie-item\">\n                <span class=\"cookie-item-name\">_ga, _ga_*</span>\n                <span class=\"cookie-item-expiration\">2 years</span>\n              </div>\n              <div class=\"cookie-item\">\n                <span class=\"cookie-item-name\">_gat</span>\n                <span class=\"cookie-item-expiration\">1 minute</span>\n              </div>\n            </div>\n          </details>\n        </div>\n\n        <!-- Performance -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-performance\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Performance</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Improve page speed and user experience.</p>\n        </div>\n\n        <!-- Marketing -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-marketing\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Marketing</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Allow us to show you relevant content and offers.</p>\n        </div>\n      </div>\n\n      <div class=\"cookie-modal-footer-info\">\n        <small class=\"cookie-updated\"\n          >Last updated: December 11, 2025</small\n        >\n      </div>\n    </div>\n\n    <div class=\"cookie-modal-footer\">\n      <button id=\"modal-reject\" class=\"cookie-btn cookie-btn-reject\">\n        Reject\n      </button>\n      <button id=\"modal-save\" class=\"cookie-btn cookie-btn-accept\">\n        Save Preferences\n      </button>\n    </div>\n  </div>\n</div>\n\n<style>\n  .cookie-consent-banner {\n    position: fixed;\n    bottom: 0;\n    left: 0;\n    right: 0;\n    background: var(--bg-secondary);\n    border-top: 1px solid var(--border);\n    border-left: 3px solid var(--accent-primary);\n    padding: 20px;\n    z-index: 1000;\n    box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.15);\n    animation: slideUp 0.3s ease-out;\n  }\n\n  @keyframes slideUp {\n    from {\n      transform: translateY(100%);\n      opacity: 0;\n    }\n    to {\n      transform: translateY(0);\n      opacity: 1;\n    }\n  }\n\n  .cookie-consent-content {\n    max-width: 1200px;\n    margin: 0 auto;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    gap: 24px;\n    flex-wrap: wrap;\n  }\n\n  .cookie-consent-text {\n    flex: 1;\n    min-width: 280px;\n  }\n\n  .cookie-consent-title {\n    margin: 0 0 8px 0;\n    font-size: 16px;\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-consent-message {\n    margin: 0 0 8px 0;\n    font-size: 14px;\n    color: var(--text-secondary);\n    line-height: 1.5;\n  }\n\n  .cookie-consent-subtext {\n    margin: 8px 0 0 0;\n    font-size: 12px;\n    color: var(--text-secondary);\n  }\n\n  .cookie-consent-subtext a {\n    color: var(--accent-primary);\n    text-decoration: none;\n    font-weight: 500;\n  }\n\n  .cookie-consent-subtext a:hover {\n    text-decoration: underline;\n  }\n\n  .cookie-consent-actions {\n    display: flex;\n    gap: 12px;\n    flex-shrink: 0;\n  }\n\n  .cookie-btn {\n    padding: 8px 16px;\n    border-radius: var(--radius);\n    border: 1px solid var(--border);\n    font-size: 13px;\n    font-weight: 500;\n    cursor: pointer;\n    transition: all 0.2s ease;\n    white-space: nowrap;\n  }\n\n  .cookie-btn-manage {\n    background: var(--bg-primary);\n    color: var(--accent-primary);\n    border-color: var(--accent-primary);\n    font-weight: 600;\n  }\n\n  .cookie-btn-manage:hover {\n    background: var(--bg);\n    opacity: 0.9;\n  }\n\n  .cookie-btn-reject {\n    background: var(--bg-primary);\n    color: var(--text);\n    border-color: var(--border);\n  }\n\n  .cookie-btn-reject:hover {\n    background: var(--bg);\n    border-color: var(--text-secondary);\n  }\n\n  .cookie-btn-accept {\n    background: var(--accent-primary);\n    color: #000000;\n    border-color: var(--accent-primary);\n    font-weight: 600;\n  }\n\n  .cookie-btn-accept:hover {\n    opacity: 0.9;\n    transform: translateY(-1px);\n    box-shadow: 0 2px 8px rgba(27, 217, 111, 0.2);\n  }\n\n  .cookie-btn:active {\n    transform: translateY(0);\n  }\n\n  @media (max-width: 768px) {\n    .cookie-consent-banner {\n      padding: 16px;\n    }\n\n    .cookie-consent-content {\n      flex-direction: column;\n      gap: 16px;\n    }\n\n    .cookie-consent-actions {\n      width: 100%;\n      flex-direction: column;\n    }\n\n    .cookie-btn {\n      width: 100%;\n      padding: 10px 16px;\n    }\n  }\n\n  /* Modal Styles */\n  .cookie-modal {\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    z-index: 2000;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    animation: fadeIn 0.3s ease-out;\n  }\n\n  @keyframes fadeIn {\n    from {\n      opacity: 0;\n    }\n    to {\n      opacity: 1;\n    }\n  }\n\n  .cookie-modal-overlay {\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0, 0, 0, 0.5);\n    cursor: pointer;\n  }\n\n  .cookie-modal-content {\n    position: relative;\n    background: var(--bg-secondary);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n    max-width: 600px;\n    width: 90%;\n    max-height: 90vh;\n    overflow: auto;\n    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n    animation: slideIn 0.3s ease-out;\n  }\n\n  @keyframes slideIn {\n    from {\n      transform: scale(0.95);\n      opacity: 0;\n    }\n    to {\n      transform: scale(1);\n      opacity: 1;\n    }\n  }\n\n  .cookie-modal-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    padding: 24px;\n    border-bottom: 1px solid var(--border);\n  }\n\n  .cookie-modal-title {\n    margin: 0;\n    font-size: 20px;\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-modal-close {\n    background: none;\n    border: none;\n    color: var(--text-secondary);\n    font-size: 20px;\n    cursor: pointer;\n    padding: 0;\n    width: 32px;\n    height: 32px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    border-radius: var(--radius);\n    transition: all 0.2s;\n  }\n\n  .cookie-modal-close:hover {\n    background: var(--border);\n    color: var(--text);\n  }\n\n  .cookie-modal-body {\n    padding: 24px;\n  }\n\n  .cookie-categories {\n    display: flex;\n    flex-direction: column;\n    gap: 24px;\n    margin-bottom: 24px;\n  }\n\n  .cookie-category {\n    padding: 16px;\n    background: var(--bg-primary);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n  }\n\n  .cookie-category-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    margin-bottom: 8px;\n  }\n\n  .cookie-checkbox-label {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    cursor: pointer;\n    flex: 1;\n  }\n\n  .cookie-checkbox {\n    width: 18px;\n    height: 18px;\n    cursor: pointer;\n    accent-color: var(--accent-primary);\n  }\n\n  .cookie-checkbox:disabled {\n    opacity: 0.5;\n    cursor: not-allowed;\n  }\n\n  .cookie-category-title {\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-badge {\n    display: inline-block;\n    padding: 4px 8px;\n    border-radius: 4px;\n    font-size: 11px;\n    font-weight: 600;\n    text-transform: uppercase;\n    background: var(--accent-primary);\n    color: #000000;\n  }\n\n  .cookie-category-desc {\n    margin: 8px 0 0 28px;\n    font-size: 13px;\n    color: var(--text-secondary);\n    line-height: 1.5;\n  }\n\n  .cookie-details {\n    margin: 12px 0 0 28px;\n    cursor: pointer;\n  }\n\n  .cookie-details summary {\n    font-size: 12px;\n    color: var(--accent-primary);\n    font-weight: 500;\n    text-decoration: underline;\n    padding: 4px 0;\n  }\n\n  .cookie-details summary:hover {\n    opacity: 0.8;\n  }\n\n  .cookie-list {\n    margin-top: 8px;\n    padding: 8px;\n    background: var(--bg);\n    border-radius: 4px;\n    border: 1px solid var(--border);\n  }\n\n  .cookie-item {\n    display: flex;\n    justify-content: space-between;\n    font-size: 12px;\n    padding: 6px 0;\n    color: var(--text-secondary);\n    border-bottom: 1px solid var(--border);\n  }\n\n  .cookie-item:last-child {\n    border-bottom: none;\n  }\n\n  .cookie-item-name {\n    font-family: monospace;\n    font-weight: 500;\n    color: var(--text);\n  }\n\n  .cookie-item-expiration {\n    font-size: 11px;\n  }\n\n  .cookie-modal-footer-info {\n    margin-bottom: 16px;\n    padding-top: 16px;\n    border-top: 1px solid var(--border);\n  }\n\n  .cookie-updated {\n    font-size: 12px;\n    color: var(--text-secondary);\n  }\n\n  .cookie-modal-footer {\n    display: flex;\n    gap: 12px;\n    padding: 16px 24px;\n    border-top: 1px solid var(--border);\n    background: var(--bg-primary);\n    justify-content: flex-end;\n  }\n\n  .cookie-modal-footer .cookie-btn {\n    flex: 1;\n  }\n\n  @media (max-width: 640px) {\n    .cookie-modal-content {\n      width: 95%;\n      max-height: 95vh;\n    }\n\n    .cookie-modal-header {\n      padding: 16px;\n    }\n\n    .cookie-modal-body {\n      padding: 16px;\n    }\n\n    .cookie-modal-footer {\n      flex-direction: column;\n      padding: 16px;\n    }\n\n    .cookie-modal-footer .cookie-btn {\n      width: 100%;\n    }\n\n    .cookie-category-desc {\n      margin-left: 28px;\n    }\n\n    .cookie-details {\n      margin-left: 28px;\n    }\n  }\n</style>\n\n<script>\n  document.addEventListener(\"DOMContentLoaded\", () => {\n    const banner = document.getElementById(\"cookie-consent\");\n    const modal = document.getElementById(\"cookie-modal\");\n    const acceptBtn = document.getElementById(\"cookie-accept\");\n    const rejectBtn = document.getElementById(\"cookie-reject\");\n    const manageBtn = document.getElementById(\"cookie-manage\");\n    const modalClose = document.getElementById(\"modal-close\");\n    const modalOverlay = document.querySelector(\".cookie-modal-overlay\");\n    const modalRejectBtn = document.getElementById(\"modal-reject\");\n    const modalSaveBtn = document.getElementById(\"modal-save\");\n    const consentKey = \"abc-cookie-consent\";\n    const categoriesKey = \"abc-cookie-categories\";\n\n    // Preference checkboxes\n    const analyticsCheckbox = document.getElementById(\"cookie-analytics\");\n    const performanceCheckbox = document.getElementById(\"cookie-performance\");\n    const marketingCheckbox = document.getElementById(\"cookie-marketing\");\n\n    // Load saved preferences\n    const loadPreferences = () => {\n      const saved = localStorage.getItem(categoriesKey);\n      if (saved) {\n        const prefs = JSON.parse(saved);\n        analyticsCheckbox.checked = prefs.analytics || false;\n        performanceCheckbox.checked = prefs.performance || false;\n        marketingCheckbox.checked = prefs.marketing || false;\n      }\n    };\n\n    // Save preferences\n    const savePreferences = () => {\n      const prefs = {\n        analytics: analyticsCheckbox.checked,\n        performance: performanceCheckbox.checked,\n        marketing: marketingCheckbox.checked,\n      };\n      localStorage.setItem(categoriesKey, JSON.stringify(prefs));\n      localStorage.setItem(consentKey, \"custom\");\n      dismissBanner();\n      updateConsent(prefs);\n    };\n\n    // Dismiss banner with animation\n    const dismissBanner = () => {\n      banner.style.animation = \"slideDown 0.3s ease-out forwards\";\n      setTimeout(() => {\n        banner.style.display = \"none\";\n      }, 300);\n      modal.style.animation = \"fadeOut 0.3s ease-out forwards\";\n      setTimeout(() => {\n        modal.style.display = \"none\";\n      }, 300);\n    };\n\n    // Update analytics consent\n    const updateConsent = (prefs) => {\n      if (window.gtag) {\n        gtag(\"consent\", \"update\", {\n          analytics_storage: prefs.analytics ? \"granted\" : \"denied\",\n        });\n      }\n    };\n\n    // Check if user has already made a choice\n    const userConsent = localStorage.getItem(consentKey);\n\n    if (!userConsent) {\n      setTimeout(() => {\n        banner.style.display = \"flex\";\n      }, 1000);\n    }\n\n    loadPreferences();\n\n    // Accept all cookies\n    acceptBtn.addEventListener(\"click\", () => {\n      analyticsCheckbox.checked = true;\n      performanceCheckbox.checked = true;\n      marketingCheckbox.checked = true;\n      savePreferences();\n    });\n\n    // Reject all cookies (keep only essential)\n    const rejectAllCookies = () => {\n      analyticsCheckbox.checked = false;\n      performanceCheckbox.checked = false;\n      marketingCheckbox.checked = false;\n      localStorage.setItem(\n        categoriesKey,\n        JSON.stringify({\n          analytics: false,\n          performance: false,\n          marketing: false,\n        })\n      );\n      localStorage.setItem(consentKey, \"rejected\");\n      dismissBanner();\n      updateConsent({ analytics: false, performance: false, marketing: false });\n    };\n\n    rejectBtn.addEventListener(\"click\", rejectAllCookies);\n    modalRejectBtn.addEventListener(\"click\", rejectAllCookies);\n\n    // Manage preferences\n    manageBtn.addEventListener(\"click\", () => {\n      modal.style.display = \"flex\";\n      loadPreferences();\n    });\n\n    // Modal controls\n    modalClose.addEventListener(\"click\", () => {\n      modal.style.animation = \"fadeOut 0.3s ease-out forwards\";\n      setTimeout(() => {\n        modal.style.display = \"none\";\n      }, 300);\n    });\n\n    modalOverlay.addEventListener(\"click\", () => {\n      modalClose.click();\n    });\n\n    // Save preferences from modal\n    modalSaveBtn.addEventListener(\"click\", savePreferences);\n\n    // ESC key to close modal\n    document.addEventListener(\"keydown\", (e) => {\n      if (e.key === \"Escape\" && modal.style.display === \"flex\") {\n        modalClose.click();\n      }\n    });\n\n    // Add fadeOut animation\n    const style = document.createElement(\"style\");\n    style.textContent = `\n      @keyframes slideDown {\n        to {\n          transform: translateY(100%);\n          opacity: 0;\n        }\n      }\n      @keyframes fadeOut {\n        to {\n          opacity: 0;\n        }\n      }\n    `;\n    document.head.appendChild(style);\n  });\n</script>\n\n\n    <!-- Scripts -->\n    <script src=\"/assets/js/search.js\"></script>\n    <script src=\"/assets/js/performance.js\"></script>\n    <script src=\"/assets/js/visual-enhancements.js\"></script>\n  </body>\n</html>\n"],"roadmap":["\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <title>Welcome to the Blog</title>\n    <meta\n      name=\"description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta\n      name=\"robots\"\n      content=\"index, follow\"\n    />\n\n    <!-- SEO Meta Tags -->\n          \n\n    <meta\n      property=\"og:title\"\n      content=\"Welcome to the Blog\"\n    />\n    <meta\n      property=\"og:description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta property=\"og:url\" content=\"https://abc-site.devvyy.xyz/blog/blog-test/\" />\n    <meta property=\"og:image\" content=\"https://abc-site.devvyy.xyz/assets/images/logo.svg\" />\n    <meta property=\"og:image:alt\" content=\"ABC Mods & Packs\" />\n    <meta property=\"og:type\" content=\"post\" />\n    <meta property=\"og:site_name\" content=\"ABC\" />\n    <meta\n      property=\"og:locale\"\n      content=\"en_US\"\n    />\n\n    <!-- hreflang tags for multilingual SEO -->\n    <link\n      rel=\"alternate\"\n      hreflang=\"en\"\n      href=\"https://abc-site.devvyy.xyz/blog/blog-test/\"\n    />\n    <link\n      rel=\"alternate\"\n      hreflang=\"fr\"\n      href=\"https://abc-site.devvyy.xyz/fr/blog/blog-test/\"\n    />\n    <link\n      rel=\"alternate\"\n      hreflang=\"x-default\"\n      href=\"https://abc-site.devvyy.xyz/blog/blog-test/\"\n    />\n\n    <!-- Twitter Card -->\n    <meta name=\"twitter:card\" content=\"summary_large_image\" />\n    <meta\n      name=\"twitter:title\"\n      content=\"Welcome to the Blog\"\n    />\n    <meta\n      name=\"twitter:description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta\n      name=\"twitter:image\"\n      content=\"https://abc-site.devvyy.xyz/assets/images/logo.svg\"\n    />\n    <meta name=\"twitter:image:alt\" content=\"ABC Mods & Packs\" />\n    <meta\n      name=\"twitter:creator\"\n      content=\"@devvyyxyz\"\n    />\n    <meta\n      name=\"twitter:site\"\n      content=\"@devvyyxyz\"\n    />\n\n    <meta\n      name=\"theme-color\"\n      content=\"#1bd96f\"\n    />\n\n    <!-- Favicon -->\n    <link\n      rel=\"icon\"\n      type=\"image/svg+xml\"\n      href=\"/favicon.svg\"\n    />\n    <link\n      rel=\"icon\"\n      type=\"image/x-icon\"\n      href=\"/favicon.svg\"\n    />\n    <link\n      rel=\"apple-touch-icon\"\n      href=\"/assets/images/logo.svg\"\n    />\n\n    <!-- Google Fonts - Preload -->\n    <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n    <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n    <link\n      rel=\"preload\"\n      as=\"style\"\n      href=\"https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap\"\n    />\n    <link\n      href=\"https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap\"\n      rel=\"stylesheet\"\n    />\n\n    <!-- Font Awesome Icons - Async load -->\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <noscript>\n      <link\n        rel=\"stylesheet\"\n        href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n      />\n    </noscript>\n\n    <!-- Stylesheets - Critical -->\n    <link rel=\"stylesheet\" href=\"/assets/css/root.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/layout.css\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/loading.css\"\n    />\n\n    <!-- Stylesheets - Deferred (non-critical) -->\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/components.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/modpacks.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/animations.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/theme.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/a11y.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/visual-enhancements.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/mobile.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <noscript>\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/components.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/modpacks.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/animations.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/theme.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/a11y.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/visual-enhancements.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/mobile.css\"\n      />\n    </noscript>\n\n    <!-- Canonical URL -->\n    <link rel=\"canonical\" href=\"https://abc-site.devvyy.xyz/blog/blog-test/\" />\n\n    <!-- Schema Markup -->\n    <!-- Schema.org JSON-LD -->\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"Organization\",\n    \"name\": \"ABC\",\n    \"description\": \"Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins.\",\n    \"url\": \"https://abc-site.devvyy.xyz\",\n    \"logo\": \"https://abc-site.devvyy.xyz/assets/images/logo.svg\",\n    \"sameAs\": [\n      \"https://github.com/devvyyxyz\",\n      \"https://twitter.com/devvyyxyz\",\n      \"https://dc.gg/devvyyxyz\"\n    ],\n    \"contactPoint\": {\n      \"@type\": \"ContactPoint\",\n      \"contactType\": \"Community Support\",\n      \"url\": \"https://dc.gg/devvyyxyz\"\n    }\n  }\n</script>\n\n<!-- Breadcrumb Schema -->\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"BreadcrumbList\",\n    \"itemListElement\": [\n      {\n        \"@type\": \"ListItem\",\n        \"position\": 1,\n        \"name\": \"Home\",\n        \"item\": \"https://abc-site.devvyy.xyz\"\n      }\n      \n      , {\n        \"@type\": \"ListItem\",\n        \"position\": 2,\n        \"name\": \"Welcome to the Blog\",\n        \"item\": \"https://abc-site.devvyy.xyz/blog/blog-test/\"\n      }\n      \n    ]\n  }\n</script>\n\n<!-- Project/Software Application Schema (for project pages) -->\n\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"Article\",\n    \"headline\": \"Welcome to the Blog\",\n    \"description\": \"Kicking off our new blog — what's coming next.\",\n    \"image\": \"\",\n    \"datePublished\": \"2025-12-16T00:00:00+00:00\",\n    \"dateModified\": \"2025-12-16T00:00:00+00:00\",\n    \"author\": {\n      \"@type\": \"Organization\",\n      \"name\": \"ABC\"\n    },\n    \"publisher\": {\n      \"@type\": \"Organization\",\n      \"name\": \"ABC\",\n      \"logo\": {\n        \"@type\": \"ImageObject\",\n        \"url\": \"https://abc-site.devvyy.xyz/assets/images/logo.svg\"\n      }\n    }\n  }\n</script>\n<!-- WebPage Schema -->\n\n\n\n    <!-- Preloader Script (critical, inline) -->\n    <script>\n      (function () {\n        if (!document.body) return; // Exit if body not ready yet\n\n        const isDarkMode =\n          window.matchMedia &&\n          window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n        const bgColor = isDarkMode ? \"#0d0d0d\" : \"#f6fbfa\";\n        document.documentElement.style.backgroundColor = bgColor;\n        document.body.style.backgroundColor = bgColor;\n\n        const overlay = document.createElement(\"div\");\n        overlay.className = \"loading-overlay\";\n        overlay.id = \"loading-overlay\";\n        overlay.innerHTML = '<div class=\"spinner\"></div>';\n        document.body.appendChild(overlay);\n\n        if (document.readyState === \"loading\") {\n          document.addEventListener(\"DOMContentLoaded\", hidePreloader);\n        } else {\n          hidePreloader();\n        }\n\n        function hidePreloader() {\n          const preloader = document.getElementById(\"loading-overlay\");\n          if (preloader) {\n            preloader.classList.add(\"hidden\");\n          }\n        }\n\n        window.hidePreloader = hidePreloader;\n      })();\n    </script>\n  </head>\n  <body>\n    <a href=\"#main\" class=\"skip-to-main\">Skip to main content</a>\n    <header class=\"floating-nav\">\n  <div class=\"nav-inner\">\n    <a\n      class=\"logo\"\n      href=\"/\"\n      style=\"display: flex; align-items: center; gap: 8px\"\n      aria-label=\"ABC\"\n    >\n      <img\n        src=\"/assets/images/logo.svg\"\n        alt=\"ABC\"\n        style=\"height: 32px; width: auto\"\n      />\n      \n    </a>\n    <button\n      class=\"mobile-menu-toggle\"\n      aria-label=\"Toggle menu\"\n      id=\"mobile-menu-toggle\"\n    >\n      <i class=\"fas fa-bars\"></i>\n    </button>\n    <nav class=\"links\" id=\"mobile-nav\">\n      <a href=\"/\">Home</a>\n      <a href=\"/about/\">About</a>\n      <a href=\"/docs/\">Docs</a>\n      <a href=\"/changelog/\">Changelog</a>\n      <a href=\"/blog/\">Blog</a>\n      <div class=\"nav-dropdown\">\n        <a href=\"/projects/\" class=\"dropdown-toggle\">\n          Projects <i class=\"fas fa-chevron-down\"></i>\n        </a>\n        <div class=\"dropdown-menu\">\n          <a href=\"/projects/\">All Projects</a>\n          <a href=\"/compare/\"\n            ><i class=\"fas fa-balance-scale\"></i> Compare Modpacks</a\n          >\n          <a href=\"/changelog/\"\n            ><i class=\"fas fa-rocket\"></i> Releases & Changelog</a\n          >\n        </div>\n      </div>\n      <div class=\"nav-dropdown\">\n        <a href=\"#\" class=\"dropdown-toggle\">\n          Legal <i class=\"fas fa-chevron-down\"></i>\n        </a>\n        <div class=\"dropdown-menu\">\n          <a href=\"/privacy/\">Privacy Policy</a>\n          <a href=\"/terms/\">Terms of Service</a>\n          <a href=\"/cookie-policy/\">Cookie Policy</a>\n          <a href=\"/licensing/\">Licensing</a>\n          <a href=\"/eula/\">EULA</a>\n          <a href=\"/disclaimer/\">Disclaimer</a>\n        </div>\n      </div>\n      <a\n        href=\"https://modrinth.com/organization/abcxyz\"\n        target=\"_blank\"\n        rel=\"noopener\"\n        >Organization</a\n      >\n    </nav>\n    <div class=\"nav-actions\">\n      <div\n        id=\"social-links-nav\"\n        style=\"display: flex; gap: 6px; align-items: center\"\n      ></div>\n      <!-- Theme Toggle -->\n<div class=\"theme-toggle\" id=\"theme-toggle\" title=\"Toggle dark/light mode\">\n  <button id=\"theme-dark\" class=\"active\" aria-label=\"Dark mode\" title=\"Dark mode\">\n    <i class=\"fa-solid fa-moon\"></i>\n  </button>\n  <button id=\"theme-light\" aria-label=\"Light mode\" title=\"Light mode\">\n    <i class=\"fa-solid fa-sun\"></i>\n  </button>\n</div>\n\n<script>\n  // Theme toggle functionality\n  const themeToggle = {\n    init() {\n      this.darkBtn = document.getElementById('theme-dark');\n      this.lightBtn = document.getElementById('theme-light');\n      this.html = document.documentElement;\n\n      // Load saved theme or use system preference\n      const saved = localStorage.getItem('theme');\n      const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;\n      const theme = saved || (systemDark ? 'dark' : 'light');\n\n      this.setTheme(theme);\n\n      // Listen for changes\n      this.darkBtn.addEventListener('click', () => this.setTheme('dark'));\n      this.lightBtn.addEventListener('click', () => this.setTheme('light'));\n\n      // Listen for system theme changes\n      window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {\n        if (!localStorage.getItem('theme')) {\n          this.setTheme(e.matches ? 'dark' : 'light');\n        }\n      });\n    },\n\n    setTheme(theme) {\n      this.html.setAttribute('data-theme', theme);\n      localStorage.setItem('theme', theme);\n\n      this.darkBtn.classList.toggle('active', theme === 'dark');\n      this.lightBtn.classList.toggle('active', theme === 'light');\n\n      // Update meta theme-color\n      const color = theme === 'dark' ? '#1bd96f' : '#1bd96f';\n      document.querySelector('meta[name=\"theme-color\"]').setAttribute('content', color);\n    }\n  };\n\n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', () => themeToggle.init());\n  } else {\n    themeToggle.init();\n  }\n</script>\n\n    </div>\n  </div>\n</header>\n\n<script>\n  // Mobile menu toggle\n  document.addEventListener(\"DOMContentLoaded\", () => {\n    const toggle = document.getElementById(\"mobile-menu-toggle\");\n    const nav = document.getElementById(\"mobile-nav\");\n\n    if (toggle && nav) {\n      toggle.addEventListener(\"click\", () => {\n        nav.classList.toggle(\"mobile-open\");\n        const icon = toggle.querySelector(\"i\");\n        if (nav.classList.contains(\"mobile-open\")) {\n          icon.classList.remove(\"fa-bars\");\n          icon.classList.add(\"fa-times\");\n        } else {\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        }\n      });\n\n      // Close menu when clicking a link\n      nav.querySelectorAll(\"a\").forEach((link) => {\n        link.addEventListener(\"click\", () => {\n          nav.classList.remove(\"mobile-open\");\n          const icon = toggle.querySelector(\"i\");\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        });\n      });\n\n      // Close menu when clicking outside\n      document.addEventListener(\"click\", (e) => {\n        if (!toggle.contains(e.target) && !nav.contains(e.target)) {\n          nav.classList.remove(\"mobile-open\");\n          const icon = toggle.querySelector(\"i\");\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        }\n      });\n    }\n  });\n</script>\n\n\n    <main id=\"main\" class=\"container\"><main class=\"content\">\n  <article class=\"post\" style=\"max-width: 820px; margin: 0 auto; padding: 24px\">\n    <header>\n      <h1 style=\"margin: 0 0 8px\">Welcome to the Blog</h1>\n      <p class=\"muted\" style=\"margin: 0 0 16px\">\n        December 16, 2025 • ABC Team\n      </p>\n    </header>\n    <section class=\"post-body\"><p>We’re launching a blog to share updates, release notes, and behind-the-scenes dev logs.</p>\n\n<!--more-->\n\n<p>What you can expect:</p>\n\n<ul>\n  <li>Deep dives into mods, datapacks, and plugins</li>\n  <li>Roadmap updates and upcoming releases</li>\n  <li>Performance tips and compatibility notes</li>\n  <li>Community showcases and contributions</li>\n</ul>\n\n<p>If you have topics you’d like us to cover, let us know on the contact page or Discord.</p>\n</section>\n\n    \n    <footer style=\"margin-top: 24px\">\n      <strong>Tags:</strong>\n      \n      <span\n        style=\"\n          display: inline-block;\n          padding: 4px 8px;\n          border: 1px solid var(--border);\n          border-radius: 999px;\n          margin-right: 6px;\n          font-size: 12px;\n        \"\n        >#announcement</span\n      >\n      \n      <span\n        style=\"\n          display: inline-block;\n          padding: 4px 8px;\n          border: 1px solid var(--border);\n          border-radius: 999px;\n          margin-right: 6px;\n          font-size: 12px;\n        \"\n        >#roadmap</span\n      >\n       \n      <div style=\"margin-top: 8px\">\n        <strong>Categories:</strong>\n        \n        <span\n          style=\"\n            display: inline-block;\n            padding: 4px 8px;\n            border: 1px solid var(--border);\n            border-radius: 999px;\n            margin-right: 6px;\n            font-size: 12px;\n          \"\n          >updates</span\n        >\n        \n      </div>\n      \n    </footer>\n    \n  </article>\n</main>\n</main>\n\n    <footer class=\"floating-footer\">\n  <div class=\"footer-inner\">\n    <div style=\"display: flex; gap: 16px; align-items: flex-start\">\n      <img\n        src=\"/assets/images/logo.svg\"\n        alt=\"ABC logo\"\n        style=\"height: 100px; flex-shrink: 0; width: auto\"\n        width=\"100\"\n        height=\"100\"\n      />\n      <div style=\"display: flex; flex-direction: column; gap: 8px\">\n        <div>\n          <h4\n            style=\"\n              margin: 0;\n              font-size: 18px;\n              font-weight: 700;\n              color: var(--text);\n            \"\n          >\n            ABC\n          </h4>\n          <p\n            style=\"\n              margin: 2px 0 0 0;\n              font-size: 12px;\n              color: var(--text-secondary);\n            \"\n          >\n            Established 2025\n          </p>\n        </div>\n        <p\n          style=\"\n            margin: 0;\n            font-size: 13px;\n            color: var(--text-secondary);\n            line-height: 1.6;\n          \"\n        >\n          Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins.\n        </p>\n      </div>\n    </div>\n    <div style=\"display: flex; gap: 48px\">\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Links\n        </h4>\n        <div\n          style=\"\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n            gap: 10px 12px;\n            font-size: 13px;\n            max-width: 320px;\n          \"\n        >\n          <a\n            href=\"/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Home</a\n          >\n          <a\n            href=\"/about/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >About</a\n          >\n          <a\n            href=\"/docs/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Docs</a\n          >\n          <a\n            href=\"/projects/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Projects</a\n          >\n          <a\n            href=\"/compare/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Compare</a\n          >\n          <a\n            href=\"/changelog/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Changelog</a\n          >\n          <a\n            href=\"https://modrinth.com/organization/abcxyz\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            target=\"_blank\"\n            rel=\"noopener\"\n            >Modrinth Org</a\n          >\n          <a\n            href=\"https://github.com/devvyyxyz\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            target=\"_blank\"\n            rel=\"noopener\"\n            >GitHub Org</a\n          >\n          <a\n            href=\"/sitemap.xml\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Sitemap</a\n          >\n          <a\n            href=\"/feed.xml\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >RSS Feed</a\n          >\n          <a\n            href=\"/blog/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Blog</a\n          >\n        </div>\n      </div>\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Help\n        </h4>\n        <div\n          style=\"\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n            gap: 10px 12px;\n            font-size: 13px;\n            max-width: 320px;\n          \"\n        >\n          <a\n            href=\"/contact/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Contact</a\n          >\n          <a\n            href=\"/docs/faq/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >FAQ</a\n          >\n          <a\n            href=\"/docs/troubleshooting/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Troubleshooting</a\n          >\n          <a\n            href=\"/docs/contributing/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Contributing</a\n          >\n          <a\n            href=\"/status/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Status</a\n          >\n        </div>\n      </div>\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Community\n        </h4>\n        <div\n          id=\"social-links-footer\"\n          style=\"display: flex; gap: 12px; flex-direction: column\"\n        ></div>\n      </div>\n    </div>\n  </div>\n  <div\n    style=\"\n      border-top: 1px solid var(--border);\n      margin-top: 32px;\n      padding-top: 24px;\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      font-size: 12px;\n      color: var(--text-secondary);\n      flex-wrap: wrap;\n      gap: 16px;\n    \"\n  >\n    <div style=\"display: flex; gap: 16px; align-items: center; flex-wrap: wrap\">\n      <div>\n        © <span id=\"year\"></span> ABC. All rights reserved.\n      </div>\n      <div\n        id=\"language-switcher\"\n        style=\"display: flex; gap: 8px; align-items: center\"\n      >\n        <span style=\"font-size: 12px; color: var(--text-secondary)\"\n          >Language:</span\n        >\n        <select\n          id=\"lang-select\"\n          style=\"\n            padding: 4px 8px;\n            border: 1px solid var(--border);\n            border-radius: var(--radius);\n            background: var(--bg-secondary);\n            color: var(--text);\n            font-size: 12px;\n            cursor: pointer;\n          \"\n        >\n          <option value=\"en\">English</option>\n          <option value=\"fr\">Français</option>\n        </select>\n      </div>\n    </div>\n    <div style=\"display: flex; gap: 20px\">\n      <a\n        href=\"/privacy/\"\n        style=\"\n          color: var(--text-secondary);\n          text-decoration: none;\n          transition: color 0.2s;\n        \"\n        >Privacy</a\n      >\n      <a\n        href=\"/terms/\"\n        style=\"\n          color: var(--text-secondary);\n          text-decoration: none;\n          transition: color 0.2s;\n        \"\n        >Terms</a\n      >\n    </div>\n  </div>\n</footer>\n\n<script>\n  // Social links configuration\n  const socials = {\n    github: {\n      name: \"GitHub\",\n      icon: \"fab fa-github\",\n      url: \"https://github.com/devvyyxyz\",\n    },\n    twitter: {\n      name: \"Twitter\",\n      icon: \"fab fa-x-twitter\",\n      url: \"https://twitter.com/devvyyxyz\",\n    },\n    discord: {\n      name: \"Discord\",\n      icon: \"fab fa-discord\",\n      url: \"https://dc.gg/devvyyxyz\",\n    },\n  };\n\n  function renderSocialLinks() {\n    const navContainer = document.getElementById(\"social-links-nav\");\n    const footerContainer = document.getElementById(\"social-links-footer\");\n\n    Object.entries(socials).forEach(([key, social]) => {\n      if (social.url && social.url.trim()) {\n        // Nav icon button\n        const navLink = document.createElement(\"a\");\n        navLink.href = social.url;\n        navLink.target = \"_blank\";\n        navLink.rel = \"noopener\";\n        navLink.title = social.name;\n        navLink.style.cssText =\n          \"display:flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:var(--radius);background:var(--bg-secondary);color:var(--text-secondary);text-decoration:none;font-size:16px;transition:all 0.2s ease;border:1px solid var(--border)\";\n        const icon = document.createElement(\"i\");\n        icon.className = social.icon;\n        icon.style.fontSize = \"18px\";\n        navLink.appendChild(icon);\n        navLink.onmouseover = () => {\n          navLink.style.background = \"var(--accent-primary)\";\n          navLink.style.color = \"#000000\";\n          navLink.style.borderColor = \"var(--accent-primary)\";\n        };\n        navLink.onmouseout = () => {\n          navLink.style.background = \"var(--bg-secondary)\";\n          navLink.style.color = \"var(--text-secondary)\";\n          navLink.style.borderColor = \"var(--border)\";\n        };\n        if (navContainer) navContainer.appendChild(navLink);\n\n        // Footer text link with icon\n        const footerLink = document.createElement(\"a\");\n        footerLink.href = social.url;\n        footerLink.target = \"_blank\";\n        footerLink.rel = \"noopener\";\n        footerLink.style.cssText =\n          \"display:flex;align-items:center;gap:8px;color:var(--text-secondary);text-decoration:none;transition:color 0.2s;font-size:13px\";\n        const footerIcon = document.createElement(\"i\");\n        footerIcon.className = social.icon;\n        footerIcon.style.width = \"16px\";\n        const footerText = document.createElement(\"span\");\n        footerText.textContent = social.name;\n        footerLink.appendChild(footerIcon);\n        footerLink.appendChild(footerText);\n        footerLink.onmouseover = () => {\n          footerLink.style.color = \"var(--accent-primary)\";\n        };\n        footerLink.onmouseout = () => {\n          footerLink.style.color = \"var(--text-secondary)\";\n        };\n        if (footerContainer) footerContainer.appendChild(footerLink);\n      }\n    });\n  }\n\n  document.addEventListener(\"DOMContentLoaded\", renderSocialLinks);\n\n  // Set year in footer\n  document.getElementById(\"year\").textContent = new Date().getFullYear();\n\n  // Language switcher\n  const langSelect = document.getElementById(\"lang-select\");\n  if (langSelect) {\n    const currentLang = 'en';\n    langSelect.value = currentLang;\n\n    langSelect.addEventListener(\"change\", (e) => {\n      const selectedLang = e.target.value;\n      const currentPath = window.location.pathname;\n      const baseUrl = \"\";\n\n      // Remove existing language prefix\n      let cleanPath = currentPath.replace(baseUrl, \"\");\n      cleanPath = cleanPath.replace(/^\\/(en|fr)/, \"\");\n\n      // Build new URL\n      const newPath =\n        selectedLang === \"en\"\n          ? baseUrl + cleanPath\n          : baseUrl + \"/\" + selectedLang + cleanPath;\n\n      window.location.href = newPath;\n    });\n  }\n</script>\n <!-- Scroll to top button -->\n<button id=\"scroll-to-top\" class=\"scroll-to-top\" aria-label=\"Scroll to top\" title=\"Back to top\">\n  <i class=\"fa-solid fa-chevron-up\"></i>\n</button>\n\n<script>\n  // Scroll to top functionality\n  const scrollButton = document.getElementById('scroll-to-top');\n\n  window.addEventListener('scroll', () => {\n    if (window.scrollY > 300) {\n      scrollButton.classList.add('visible');\n    } else {\n      scrollButton.classList.remove('visible');\n    }\n  });\n\n  scrollButton.addEventListener('click', () => {\n    window.scrollTo({ top: 0, behavior: 'smooth' });\n  });\n\n  // Handle keyboard interaction\n  scrollButton.addEventListener('keydown', (e) => {\n    if (e.key === 'Enter' || e.key === ' ') {\n      e.preventDefault();\n      window.scrollTo({ top: 0, behavior: 'smooth' });\n    }\n  });\n</script>\n\n<!-- Lazy loading images with placeholder -->\n<script>\n  // Intersection Observer for lazy loading\n  if ('IntersectionObserver' in window) {\n    const imageObserver = new IntersectionObserver((entries, observer) => {\n      entries.forEach(entry => {\n        if (entry.isIntersecting) {\n          const img = entry.target;\n          img.src = img.dataset.src || img.src;\n          img.classList.remove('lazy');\n          observer.unobserve(img);\n        }\n      });\n    }, {\n      rootMargin: '50px 0px',\n      threshold: 0.01\n    });\n\n    document.querySelectorAll('img[data-src]').forEach(img => {\n      imageObserver.observe(img);\n    });\n  }\n</script>\n\n<!-- Smooth page transitions -->\n<script>\n  // Add page transition class on load\n  document.addEventListener('DOMContentLoaded', () => {\n    document.body.classList.add('page-transition');\n  });\n\n  // Handle link clicks for smooth transitions\n  document.addEventListener('click', (e) => {\n    const link = e.target.closest('a');\n    if (link && !link.target && link.hostname === window.location.hostname) {\n      // Internal link - add transition\n      e.preventDefault();\n      document.body.style.opacity = '0.8';\n      setTimeout(() => {\n        window.location.href = link.href;\n      }, 150);\n    }\n  });\n</script>\n\n\n    <!-- Cookie Consent Banner -->\n    <div\n  id=\"cookie-consent\"\n  class=\"cookie-consent-banner\"\n  role=\"alertdialog\"\n  aria-labelledby=\"cookie-title\"\n  aria-describedby=\"cookie-description\"\n  style=\"display: none\"\n>\n  <div class=\"cookie-consent-content\">\n    <div class=\"cookie-consent-text\">\n      <h3 id=\"cookie-title\" class=\"cookie-consent-title\">\n          Cookie Preferences\n      </h3>\n      <p id=\"cookie-description\" class=\"cookie-consent-message\">\n        We use cookies to improve your experience and analyze site performance. No personal data is collected.\n      </p>\n      <p class=\"cookie-consent-subtext\">\n        <a\n          href=\"/privacy/\"\n          target=\"_blank\"\n          rel=\"noopener\"\n          >Privacy Policy</a\n        >\n      </p>\n    </div>\n    <div class=\"cookie-consent-actions\">\n      <button\n        id=\"cookie-manage\"\n        class=\"cookie-btn cookie-btn-manage\"\n        aria-label=\"Manage cookie preferences\"\n      >\n        Manage Preferences\n      </button>\n      <button\n        id=\"cookie-reject\"\n        class=\"cookie-btn cookie-btn-reject\"\n        aria-label=\"Reject cookies\"\n      >\n        Reject\n      </button>\n      <button\n        id=\"cookie-accept\"\n        class=\"cookie-btn cookie-btn-accept\"\n        aria-label=\"Accept all cookies\"\n      >\n        Accept All\n      </button>\n    </div>\n  </div>\n</div>\n\n<!-- Cookie Settings Modal -->\n<div\n  id=\"cookie-modal\"\n  class=\"cookie-modal\"\n  style=\"display: none\"\n  role=\"dialog\"\n  aria-labelledby=\"modal-title\"\n  aria-hidden=\"true\"\n>\n  <div class=\"cookie-modal-overlay\"></div>\n  <div class=\"cookie-modal-content\">\n    <div class=\"cookie-modal-header\">\n      <h2 id=\"modal-title\" class=\"cookie-modal-title\">Cookie Preferences</h2>\n      <button\n        id=\"modal-close\"\n        class=\"cookie-modal-close\"\n        aria-label=\"Close modal\"\n      >\n        <i class=\"fas fa-times\"></i>\n      </button>\n    </div>\n\n    <div class=\"cookie-modal-body\">\n      <!-- Categories -->\n      <div class=\"cookie-categories\">\n        <!-- Essential -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-essential\"\n                class=\"cookie-checkbox\"\n                checked\n                disabled\n              />\n              <span class=\"cookie-category-title\"\n                >Essential</span\n              >\n            </label>\n            <span class=\"cookie-badge essential\">Essential</span>\n          </div>\n          <p class=\"cookie-category-desc\">Required for core site functionality. Always enabled.</p>\n        </div>\n\n        <!-- Analytics -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-analytics\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Analytics</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Help us understand how you use our site to improve it.</p>\n          <details class=\"cookie-details\">\n            <summary>All Cookies</summary>\n            <div class=\"cookie-list\">\n              <div class=\"cookie-item\">\n                <span class=\"cookie-item-name\">_ga, _ga_*</span>\n                <span class=\"cookie-item-expiration\">2 years</span>\n              </div>\n              <div class=\"cookie-item\">\n                <span class=\"cookie-item-name\">_gat</span>\n                <span class=\"cookie-item-expiration\">1 minute</span>\n              </div>\n            </div>\n          </details>\n        </div>\n\n        <!-- Performance -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-performance\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Performance</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Improve page speed and user experience.</p>\n        </div>\n\n        <!-- Marketing -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-marketing\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Marketing</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Allow us to show you relevant content and offers.</p>\n        </div>\n      </div>\n\n      <div class=\"cookie-modal-footer-info\">\n        <small class=\"cookie-updated\"\n          >Last updated: December 11, 2025</small\n        >\n      </div>\n    </div>\n\n    <div class=\"cookie-modal-footer\">\n      <button id=\"modal-reject\" class=\"cookie-btn cookie-btn-reject\">\n        Reject\n      </button>\n      <button id=\"modal-save\" class=\"cookie-btn cookie-btn-accept\">\n        Save Preferences\n      </button>\n    </div>\n  </div>\n</div>\n\n<style>\n  .cookie-consent-banner {\n    position: fixed;\n    bottom: 0;\n    left: 0;\n    right: 0;\n    background: var(--bg-secondary);\n    border-top: 1px solid var(--border);\n    border-left: 3px solid var(--accent-primary);\n    padding: 20px;\n    z-index: 1000;\n    box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.15);\n    animation: slideUp 0.3s ease-out;\n  }\n\n  @keyframes slideUp {\n    from {\n      transform: translateY(100%);\n      opacity: 0;\n    }\n    to {\n      transform: translateY(0);\n      opacity: 1;\n    }\n  }\n\n  .cookie-consent-content {\n    max-width: 1200px;\n    margin: 0 auto;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    gap: 24px;\n    flex-wrap: wrap;\n  }\n\n  .cookie-consent-text {\n    flex: 1;\n    min-width: 280px;\n  }\n\n  .cookie-consent-title {\n    margin: 0 0 8px 0;\n    font-size: 16px;\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-consent-message {\n    margin: 0 0 8px 0;\n    font-size: 14px;\n    color: var(--text-secondary);\n    line-height: 1.5;\n  }\n\n  .cookie-consent-subtext {\n    margin: 8px 0 0 0;\n    font-size: 12px;\n    color: var(--text-secondary);\n  }\n\n  .cookie-consent-subtext a {\n    color: var(--accent-primary);\n    text-decoration: none;\n    font-weight: 500;\n  }\n\n  .cookie-consent-subtext a:hover {\n    text-decoration: underline;\n  }\n\n  .cookie-consent-actions {\n    display: flex;\n    gap: 12px;\n    flex-shrink: 0;\n  }\n\n  .cookie-btn {\n    padding: 8px 16px;\n    border-radius: var(--radius);\n    border: 1px solid var(--border);\n    font-size: 13px;\n    font-weight: 500;\n    cursor: pointer;\n    transition: all 0.2s ease;\n    white-space: nowrap;\n  }\n\n  .cookie-btn-manage {\n    background: var(--bg-primary);\n    color: var(--accent-primary);\n    border-color: var(--accent-primary);\n    font-weight: 600;\n  }\n\n  .cookie-btn-manage:hover {\n    background: var(--bg);\n    opacity: 0.9;\n  }\n\n  .cookie-btn-reject {\n    background: var(--bg-primary);\n    color: var(--text);\n    border-color: var(--border);\n  }\n\n  .cookie-btn-reject:hover {\n    background: var(--bg);\n    border-color: var(--text-secondary);\n  }\n\n  .cookie-btn-accept {\n    background: var(--accent-primary);\n    color: #000000;\n    border-color: var(--accent-primary);\n    font-weight: 600;\n  }\n\n  .cookie-btn-accept:hover {\n    opacity: 0.9;\n    transform: translateY(-1px);\n    box-shadow: 0 2px 8px rgba(27, 217, 111, 0.2);\n  }\n\n  .cookie-btn:active {\n    transform: translateY(0);\n  }\n\n  @media (max-width: 768px) {\n    .cookie-consent-banner {\n      padding: 16px;\n    }\n\n    .cookie-consent-content {\n      flex-direction: column;\n      gap: 16px;\n    }\n\n    .cookie-consent-actions {\n      width: 100%;\n      flex-direction: column;\n    }\n\n    .cookie-btn {\n      width: 100%;\n      padding: 10px 16px;\n    }\n  }\n\n  /* Modal Styles */\n  .cookie-modal {\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    z-index: 2000;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    animation: fadeIn 0.3s ease-out;\n  }\n\n  @keyframes fadeIn {\n    from {\n      opacity: 0;\n    }\n    to {\n      opacity: 1;\n    }\n  }\n\n  .cookie-modal-overlay {\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0, 0, 0, 0.5);\n    cursor: pointer;\n  }\n\n  .cookie-modal-content {\n    position: relative;\n    background: var(--bg-secondary);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n    max-width: 600px;\n    width: 90%;\n    max-height: 90vh;\n    overflow: auto;\n    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n    animation: slideIn 0.3s ease-out;\n  }\n\n  @keyframes slideIn {\n    from {\n      transform: scale(0.95);\n      opacity: 0;\n    }\n    to {\n      transform: scale(1);\n      opacity: 1;\n    }\n  }\n\n  .cookie-modal-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    padding: 24px;\n    border-bottom: 1px solid var(--border);\n  }\n\n  .cookie-modal-title {\n    margin: 0;\n    font-size: 20px;\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-modal-close {\n    background: none;\n    border: none;\n    color: var(--text-secondary);\n    font-size: 20px;\n    cursor: pointer;\n    padding: 0;\n    width: 32px;\n    height: 32px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    border-radius: var(--radius);\n    transition: all 0.2s;\n  }\n\n  .cookie-modal-close:hover {\n    background: var(--border);\n    color: var(--text);\n  }\n\n  .cookie-modal-body {\n    padding: 24px;\n  }\n\n  .cookie-categories {\n    display: flex;\n    flex-direction: column;\n    gap: 24px;\n    margin-bottom: 24px;\n  }\n\n  .cookie-category {\n    padding: 16px;\n    background: var(--bg-primary);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n  }\n\n  .cookie-category-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    margin-bottom: 8px;\n  }\n\n  .cookie-checkbox-label {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    cursor: pointer;\n    flex: 1;\n  }\n\n  .cookie-checkbox {\n    width: 18px;\n    height: 18px;\n    cursor: pointer;\n    accent-color: var(--accent-primary);\n  }\n\n  .cookie-checkbox:disabled {\n    opacity: 0.5;\n    cursor: not-allowed;\n  }\n\n  .cookie-category-title {\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-badge {\n    display: inline-block;\n    padding: 4px 8px;\n    border-radius: 4px;\n    font-size: 11px;\n    font-weight: 600;\n    text-transform: uppercase;\n    background: var(--accent-primary);\n    color: #000000;\n  }\n\n  .cookie-category-desc {\n    margin: 8px 0 0 28px;\n    font-size: 13px;\n    color: var(--text-secondary);\n    line-height: 1.5;\n  }\n\n  .cookie-details {\n    margin: 12px 0 0 28px;\n    cursor: pointer;\n  }\n\n  .cookie-details summary {\n    font-size: 12px;\n    color: var(--accent-primary);\n    font-weight: 500;\n    text-decoration: underline;\n    padding: 4px 0;\n  }\n\n  .cookie-details summary:hover {\n    opacity: 0.8;\n  }\n\n  .cookie-list {\n    margin-top: 8px;\n    padding: 8px;\n    background: var(--bg);\n    border-radius: 4px;\n    border: 1px solid var(--border);\n  }\n\n  .cookie-item {\n    display: flex;\n    justify-content: space-between;\n    font-size: 12px;\n    padding: 6px 0;\n    color: var(--text-secondary);\n    border-bottom: 1px solid var(--border);\n  }\n\n  .cookie-item:last-child {\n    border-bottom: none;\n  }\n\n  .cookie-item-name {\n    font-family: monospace;\n    font-weight: 500;\n    color: var(--text);\n  }\n\n  .cookie-item-expiration {\n    font-size: 11px;\n  }\n\n  .cookie-modal-footer-info {\n    margin-bottom: 16px;\n    padding-top: 16px;\n    border-top: 1px solid var(--border);\n  }\n\n  .cookie-updated {\n    font-size: 12px;\n    color: var(--text-secondary);\n  }\n\n  .cookie-modal-footer {\n    display: flex;\n    gap: 12px;\n    padding: 16px 24px;\n    border-top: 1px solid var(--border);\n    background: var(--bg-primary);\n    justify-content: flex-end;\n  }\n\n  .cookie-modal-footer .cookie-btn {\n    flex: 1;\n  }\n\n  @media (max-width: 640px) {\n    .cookie-modal-content {\n      width: 95%;\n      max-height: 95vh;\n    }\n\n    .cookie-modal-header {\n      padding: 16px;\n    }\n\n    .cookie-modal-body {\n      padding: 16px;\n    }\n\n    .cookie-modal-footer {\n      flex-direction: column;\n      padding: 16px;\n    }\n\n    .cookie-modal-footer .cookie-btn {\n      width: 100%;\n    }\n\n    .cookie-category-desc {\n      margin-left: 28px;\n    }\n\n    .cookie-details {\n      margin-left: 28px;\n    }\n  }\n</style>\n\n<script>\n  document.addEventListener(\"DOMContentLoaded\", () => {\n    const banner = document.getElementById(\"cookie-consent\");\n    const modal = document.getElementById(\"cookie-modal\");\n    const acceptBtn = document.getElementById(\"cookie-accept\");\n    const rejectBtn = document.getElementById(\"cookie-reject\");\n    const manageBtn = document.getElementById(\"cookie-manage\");\n    const modalClose = document.getElementById(\"modal-close\");\n    const modalOverlay = document.querySelector(\".cookie-modal-overlay\");\n    const modalRejectBtn = document.getElementById(\"modal-reject\");\n    const modalSaveBtn = document.getElementById(\"modal-save\");\n    const consentKey = \"abc-cookie-consent\";\n    const categoriesKey = \"abc-cookie-categories\";\n\n    // Preference checkboxes\n    const analyticsCheckbox = document.getElementById(\"cookie-analytics\");\n    const performanceCheckbox = document.getElementById(\"cookie-performance\");\n    const marketingCheckbox = document.getElementById(\"cookie-marketing\");\n\n    // Load saved preferences\n    const loadPreferences = () => {\n      const saved = localStorage.getItem(categoriesKey);\n      if (saved) {\n        const prefs = JSON.parse(saved);\n        analyticsCheckbox.checked = prefs.analytics || false;\n        performanceCheckbox.checked = prefs.performance || false;\n        marketingCheckbox.checked = prefs.marketing || false;\n      }\n    };\n\n    // Save preferences\n    const savePreferences = () => {\n      const prefs = {\n        analytics: analyticsCheckbox.checked,\n        performance: performanceCheckbox.checked,\n        marketing: marketingCheckbox.checked,\n      };\n      localStorage.setItem(categoriesKey, JSON.stringify(prefs));\n      localStorage.setItem(consentKey, \"custom\");\n      dismissBanner();\n      updateConsent(prefs);\n    };\n\n    // Dismiss banner with animation\n    const dismissBanner = () => {\n      banner.style.animation = \"slideDown 0.3s ease-out forwards\";\n      setTimeout(() => {\n        banner.style.display = \"none\";\n      }, 300);\n      modal.style.animation = \"fadeOut 0.3s ease-out forwards\";\n      setTimeout(() => {\n        modal.style.display = \"none\";\n      }, 300);\n    };\n\n    // Update analytics consent\n    const updateConsent = (prefs) => {\n      if (window.gtag) {\n        gtag(\"consent\", \"update\", {\n          analytics_storage: prefs.analytics ? \"granted\" : \"denied\",\n        });\n      }\n    };\n\n    // Check if user has already made a choice\n    const userConsent = localStorage.getItem(consentKey);\n\n    if (!userConsent) {\n      setTimeout(() => {\n        banner.style.display = \"flex\";\n      }, 1000);\n    }\n\n    loadPreferences();\n\n    // Accept all cookies\n    acceptBtn.addEventListener(\"click\", () => {\n      analyticsCheckbox.checked = true;\n      performanceCheckbox.checked = true;\n      marketingCheckbox.checked = true;\n      savePreferences();\n    });\n\n    // Reject all cookies (keep only essential)\n    const rejectAllCookies = () => {\n      analyticsCheckbox.checked = false;\n      performanceCheckbox.checked = false;\n      marketingCheckbox.checked = false;\n      localStorage.setItem(\n        categoriesKey,\n        JSON.stringify({\n          analytics: false,\n          performance: false,\n          marketing: false,\n        })\n      );\n      localStorage.setItem(consentKey, \"rejected\");\n      dismissBanner();\n      updateConsent({ analytics: false, performance: false, marketing: false });\n    };\n\n    rejectBtn.addEventListener(\"click\", rejectAllCookies);\n    modalRejectBtn.addEventListener(\"click\", rejectAllCookies);\n\n    // Manage preferences\n    manageBtn.addEventListener(\"click\", () => {\n      modal.style.display = \"flex\";\n      loadPreferences();\n    });\n\n    // Modal controls\n    modalClose.addEventListener(\"click\", () => {\n      modal.style.animation = \"fadeOut 0.3s ease-out forwards\";\n      setTimeout(() => {\n        modal.style.display = \"none\";\n      }, 300);\n    });\n\n    modalOverlay.addEventListener(\"click\", () => {\n      modalClose.click();\n    });\n\n    // Save preferences from modal\n    modalSaveBtn.addEventListener(\"click\", savePreferences);\n\n    // ESC key to close modal\n    document.addEventListener(\"keydown\", (e) => {\n      if (e.key === \"Escape\" && modal.style.display === \"flex\") {\n        modalClose.click();\n      }\n    });\n\n    // Add fadeOut animation\n    const style = document.createElement(\"style\");\n    style.textContent = `\n      @keyframes slideDown {\n        to {\n          transform: translateY(100%);\n          opacity: 0;\n        }\n      }\n      @keyframes fadeOut {\n        to {\n          opacity: 0;\n        }\n      }\n    `;\n    document.head.appendChild(style);\n  });\n</script>\n\n\n    <!-- Scripts -->\n    <script src=\"/assets/js/search.js\"></script>\n    <script src=\"/assets/js/performance.js\"></script>\n    <script src=\"/assets/js/visual-enhancements.js\"></script>\n  </body>\n</html>\n"]},"html_pages":["{% assign page_lang = page.url | split: '/' | second %}\n{% if page_lang == 'fr' %}\n{% assign page_lang = 'fr' %}\n{% else %}\n{% assign page_lang = 'en' %}\n{% endif %}\n{% assign t = site.data[page_lang] %}\n\n<section class=\"hero\" style=\"min-height: 60vh; display: flex; align-items: center; justify-content: center;\">\n  <div class=\"hero-card\" style=\"text-align: center; max-width: 600px;\">\n    <div style=\"font-size: 120px; font-weight: 700; color: var(--accent-primary); margin-bottom: 24px; line-height: 1;\">\n      404\n    </div>\n    <h1 style=\"margin: 0 0 16px 0; font-size: 32px;\">{{ t.error_404_title }}</h1>\n    <p class=\"muted\" style=\"font-size: 16px; margin-bottom: 32px;\">{{ t.error_404_message }}</p>\n    \n    <div class=\"cta-row\" style=\"flex-direction: column; gap: 12px;\">\n      <a class=\"btn primary\" href=\"{% if page_lang == 'fr' %}/abc-site/fr/{% else %}/abc-site/{% endif %}\">\n        <i class=\"fas fa-home\"></i> {{ t.error_404_back_home }}\n      </a>\n      <a class=\"btn ghost\" href=\"{% if page_lang == 'fr' %}/abc-site/fr/projects/{% else %}/abc-site/projects/{% endif %}\">\n        <i class=\"fas fa-list\"></i> {{ t.error_404_browse }}\n      </a>\n    </div>\n\n    <div style=\"margin-top: 48px; padding-top: 32px; border-top: 1px solid var(--border);\">\n      <p class=\"muted\" style=\"font-size: 13px; margin: 0;\">\n        {% if page_lang == 'fr' %}\n          Si vous pensez que c'est une erreur, <a href=\"{{ '/contact/' | relative_url }}\" style=\"color: var(--accent-primary); text-decoration: none;\">contactez-nous</a>.\n        {% else %}\n          If you think this is a mistake, <a href=\"{{ '/contact/' | relative_url }}\" style=\"color: var(--accent-primary); text-decoration: none;\">contact us</a>.\n        {% endif %}\n      </p>\n    </div>\n\n  </div>\n</section>\n\n<style>\n  .cta-row {\n    display: flex;\n    gap: 16px;\n    justify-content: center;\n    flex-wrap: wrap;\n  }\n\n  @media (max-width: 640px) {\n    .hero-card {\n      padding: 32px 16px !important;\n    }\n    \n    .cta-row {\n      flex-direction: column;\n      gap: 12px;\n    }\n    \n    .hero-card h1 {\n      font-size: 24px !important;\n    }\n  }\n</style>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>About Us</h1>\n    <p class=\"muted\">A community-driven showcase for the best Minecraft mods, resource packs, datapacks, modpacks, and plugins.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>Our Mission</h2>\n  <p class=\"muted\">To provide an organized, beautiful, and accessible platform for discovering and showcasing high-quality Minecraft content.</p>\n  \n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-bullseye\"></i> Curated Collection</h3>\n      <p>We handpick projects from the Modrinth ecosystem, ensuring quality and relevance for our community.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-users\"></i> Community Focused</h3>\n      <p>Built by and for the Minecraft community. Your feedback and contributions shape our platform.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-code\"></i> Open Source</h3>\n      <p>Completely open-source and transparent. Fork, modify, and contribute on GitHub.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-bolt\"></i> Fast & Reliable</h3>\n      <p>Static site hosted on GitHub Pages. Zero downtime, global CDN, instant loading.</p>\n    </div>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>How It Works</h2>\n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-database\"></i> Live Data</h3>\n      <p>We sync project data daily from Modrinth, keeping our showcase fresh and up-to-date with the latest versions and downloads.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-filter\"></i> Smart Filtering</h3>\n      <p>Filter projects by type, loader, and game version. Find exactly what you're looking for in seconds.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-chart-line\"></i> Statistics</h3>\n      <p>Real-time statistics show total downloads, supported versions, popular categories, and trending projects.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-link\"></i> Direct Links</h3>\n      <p>Every project links directly to Modrinth, ensuring you always download from the official source.</p>\n    </div>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>Get Involved</h2>\n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3><i class=\"fa-brands fa-discord\"></i> Join Discord</h3>\n      <p class=\"muted\">Chat with our community, get support, and suggest improvements.</p>\n      {% if site.social.discord %}\n        <a class=\"btn primary\" href=\"{{ site.social.discord }}\" target=\"_blank\" rel=\"noopener\">Open Discord</a>\n      {% endif %}\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-brands fa-github\"></i> Contribute</h3>\n      <p class=\"muted\">Found a bug? Have an idea? Star and contribute to our repository.</p>\n      {% if site.social.github %}\n        <a class=\"btn ghost\" href=\"{{ site.social.github }}\" target=\"_blank\" rel=\"noopener\">View on GitHub</a>\n      {% endif %}\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-heart\"></i> Support</h3>\n      <p class=\"muted\">Enjoying the platform? Follow our socials and spread the word!</p>\n      {% if site.social.twitter %}\n        <a class=\"btn ghost\" href=\"{{ site.social.twitter }}\" target=\"_blank\" rel=\"noopener\">Follow Twitter</a>\n      {% endif %}\n    </div>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>Our Values</h2>\n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3>Accessibility</h3>\n      <p>We believe everyone should have access to quality Minecraft content, regardless of technical skill or platform.</p>\n    </div>\n    <div class=\"card\">\n      <h3>Transparency</h3>\n      <p>Open source code, public data, and clear communication. We have nothing to hide.</p>\n    </div>\n    <div class=\"card\">\n      <h3>Community</h3>\n      <p>Built together, not for profit. We prioritize creator and player needs over monetization.</p>\n    </div>\n    <div class=\"card\">\n      <h3>Quality</h3>\n      <p>Every project showcased meets our standards for functionality, documentation, and community support.</p>\n    </div>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>Contact & Support</h2>\n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-envelope\"></i> Need Help?</h3>\n      <p class=\"muted\">Have questions? Check our documentation or reach out on Discord.</p>\n      <a class=\"btn primary\" href=\"{{ '/docs/' | relative_url }}\">Read Docs</a>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-bug\"></i> Found a Bug?</h3>\n      <p class=\"muted\">Report issues and suggest features on our GitHub repository.</p>\n      {% if site.social.github %}\n        <a class=\"btn primary\" href=\"{{ site.social.github }}/issues\" target=\"_blank\" rel=\"noopener\">Report Issue</a>\n      {% endif %}\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-handshake\"></i> Let's Collaborate</h3>\n      <p class=\"muted\">Interested in partnering or featuring your project? Let's talk!</p>\n      {% if site.social.discord %}\n        <a class=\"btn ghost\" href=\"{{ site.social.discord }}\" target=\"_blank\" rel=\"noopener\">Chat with Us</a>\n      {% endif %}\n    </div>\n  </div>\n</section>\n","<section class=\"section\">\n  <h1>Blog</h1>\n  <p class=\"muted\">Updates from the team — releases, dev logs, and tips.</p>\n\n  <div class=\"filters\" style=\"margin: 12px 0 20px; display:flex; gap:8px; flex-wrap:wrap;\">\n    {% assign all_tags = site.tags %}\n    {% for tag in all_tags %}\n      <a href=\"{{ '/blog/#' | append: tag[0] | relative_url }}\" style=\"padding:6px 10px; border:1px solid var(--border); border-radius:999px; text-decoration:none; color:var(--text-secondary);\">#{{ tag[0] }}</a>\n    {% endfor %}\n  </div>\n\n  <div class=\"filters\" style=\"margin: 0 0 24px; display:flex; gap:8px; flex-wrap:wrap;\">\n    {% assign all_categories = site.categories %}\n    {% for category in all_categories %}\n      <a href=\"{{ '/blog/#' | append: category[0] | relative_url }}\" style=\"padding:6px 10px; border:1px solid var(--border); border-radius:999px; text-decoration:none; color:var(--text-secondary);\">{{ category[0] }}</a>\n    {% endfor %}\n  </div>\n\n  <div class=\"post-list\" style=\"display: grid; gap: 16px;\">\n    {% assign posts = site.posts | where_exp: 'p', 'p.published != false' %}\n    {% for post in posts %}\n    <article style=\"border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; background: var(--bg-primary);\">\n      <h2 style=\"margin: 0;\">\n        <a href=\"{{ post.url | relative_url }}\" style=\"color: var(--text); text-decoration: none;\">{{ post.title }}</a>\n      </h2>\n      <p class=\"muted\" style=\"margin: 6px 0 12px;\">{{ post.date | date: \"%B %d, %Y\" }}{{ post.author | default: site.site.name }}</p>\n      {% if post.excerpt %}\n        <p style=\"margin: 0 0 8px;\">{{ post.excerpt }}</p>\n      {% endif %}\n      {% if post.tags %}\n        <div style=\"margin:8px 0;\">\n          {% for tag in post.tags %}\n            <span style=\"display:inline-block; padding: 4px 8px; border: 1px solid var(--border); border-radius: 999px; margin-right: 6px; font-size: 12px;\">#{{ tag }}</span>\n          {% endfor %}\n        </div>\n      {% endif %}\n      <a href=\"{{ post.url | relative_url }}\" class=\"button\" style=\"display:inline-block; padding: 8px 12px; background: var(--accent-primary); color: #000; border-radius: var(--radius); text-decoration: none;\">Read More</a>\n    </article>\n    {% endfor %}\n\n    {% if posts.size == 0 %}\n      <p class=\"muted\">No posts yet. Stay tuned!</p>\n    {% endif %}\n\n  </div>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Community & Contributing</h1>\n    <p class=\"muted\">Learn how to contribute to the ABC showcase and get involved.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px;\">\n    {% assign category_docs = site.docs | where: \"category\", \"Community\" %}\n    {% for doc in category_docs %}\n      <div class=\"card\">\n        <h3>{{ doc.title }}</h3>\n        <p class=\"muted\" style=\"font-size: 13px; margin-bottom: 12px;\">{{ doc.description }}</p>\n        <div style=\"display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;\">\n          {% for tag in doc.tags %}\n            <span style=\"display: inline-block; padding: 4px 8px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 4px; font-size: 12px;\">#{{ tag }}</span>\n          {% endfor %}\n        </div>\n        <a class=\"btn primary\" href=\"{{ doc.url | relative_url }}\" style=\"width: 100%; display: block; text-align: center;\">Read More</a>\n      </div>\n    {% endfor %}\n  </div>\n</section>\n\n<section class=\"section\">\n  <div style=\"text-align: center;\">\n    <p><a href=\"{{ '/docs/' | relative_url }}\">← Back to all documentation</a></p>\n  </div>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Developer Resources</h1>\n    <p class=\"muted\">Technical documentation, architecture, and API reference.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px;\">\n    {% assign category_docs = site.docs | where: \"category\", \"Developer\" %}\n    {% for doc in category_docs %}\n      <div class=\"card\">\n        <h3>{{ doc.title }}</h3>\n        <p class=\"muted\" style=\"font-size: 13px; margin-bottom: 12px;\">{{ doc.description }}</p>\n        <div style=\"display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;\">\n          {% for tag in doc.tags %}\n            <span style=\"display: inline-block; padding: 4px 8px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 4px; font-size: 12px;\">#{{ tag }}</span>\n          {% endfor %}\n        </div>\n        <a class=\"btn primary\" href=\"{{ doc.url | relative_url }}\" style=\"width: 100%; display: block; text-align: center;\">Read More</a>\n      </div>\n    {% endfor %}\n  </div>\n</section>\n\n<section class=\"section\">\n  <div style=\"text-align: center;\">\n    <p><a href=\"{{ '/docs/' | relative_url }}\">← Back to all documentation</a></p>\n  </div>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Help & Troubleshooting</h1>\n    <p class=\"muted\">Find answers to common questions and fix issues quickly.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px;\">\n    {% assign category_docs = site.docs | where: \"category\", \"Help\" %}\n    {% for doc in category_docs %}\n      <div class=\"card\">\n        <h3>{{ doc.title }}</h3>\n        <p class=\"muted\" style=\"font-size: 13px; margin-bottom: 12px;\">{{ doc.description }}</p>\n        <div style=\"display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;\">\n          {% for tag in doc.tags %}\n            <span style=\"display: inline-block; padding: 4px 8px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 4px; font-size: 12px;\">#{{ tag }}</span>\n          {% endfor %}\n        </div>\n        <a class=\"btn primary\" href=\"{{ doc.url | relative_url }}\" style=\"width: 100%; display: block; text-align: center;\">Read More</a>\n      </div>\n    {% endfor %}\n  </div>\n</section>\n\n<section class=\"section\">\n  <div style=\"text-align: center;\">\n    <p><a href=\"{{ '/docs/' | relative_url }}\">← Back to all documentation</a></p>\n  </div>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Setup & Configuration</h1>\n    <p class=\"muted\">Get the ABC showcase installed and configured for your needs.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px;\">\n    {% assign category_docs = site.docs | where: \"category\", \"Setup\" %}\n    {% for doc in category_docs %}\n      <div class=\"card\">\n        <h3>{{ doc.title }}</h3>\n        <p class=\"muted\" style=\"font-size: 13px; margin-bottom: 12px;\">{{ doc.description }}</p>\n        <div style=\"display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;\">\n          {% for tag in doc.tags %}\n            <span style=\"display: inline-block; padding: 4px 8px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 4px; font-size: 12px;\">#{{ tag }}</span>\n          {% endfor %}\n        </div>\n        <a class=\"btn primary\" href=\"{{ doc.url | relative_url }}\" style=\"width: 100%; display: block; text-align: center;\">Read More</a>\n      </div>\n    {% endfor %}\n  </div>\n</section>\n\n<section class=\"section\">\n  <div style=\"text-align: center;\">\n    <p><a href=\"{{ '/docs/' | relative_url }}\">← Back to all documentation</a></p>\n  </div>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Styling & Customization</h1>\n    <p class=\"muted\">Customize colors, themes, and appearance of your ABC showcase.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px;\">\n    {% assign category_docs = site.docs | where: \"category\", \"Styling\" %}\n    {% for doc in category_docs %}\n      <div class=\"card\">\n        <h3>{{ doc.title }}</h3>\n        <p class=\"muted\" style=\"font-size: 13px; margin-bottom: 12px;\">{{ doc.description }}</p>\n        <div style=\"display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;\">\n          {% for tag in doc.tags %}\n            <span style=\"display: inline-block; padding: 4px 8px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 4px; font-size: 12px;\">#{{ tag }}</span>\n          {% endfor %}\n        </div>\n        <a class=\"btn primary\" href=\"{{ doc.url | relative_url }}\" style=\"width: 100%; display: block; text-align: center;\">Read More</a>\n      </div>\n    {% endfor %}\n  </div>\n</section>\n\n<section class=\"section\">\n  <div style=\"text-align: center;\">\n    <p><a href=\"{{ '/docs/' | relative_url }}\">← Back to all documentation</a></p>\n  </div>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>User Guide</h1>\n    <p class=\"muted\">Everything you need to know as a user or project manager.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px;\">\n    {% assign category_docs = site.docs | where: \"category\", \"User Guide\" %}\n    {% for doc in category_docs %}\n      <div class=\"card\">\n        <h3>{{ doc.title }}</h3>\n        <p class=\"muted\" style=\"font-size: 13px; margin-bottom: 12px;\">{{ doc.description }}</p>\n        <div style=\"display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;\">\n          {% for tag in doc.tags %}\n            <span style=\"display: inline-block; padding: 4px 8px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 4px; font-size: 12px;\">#{{ tag }}</span>\n          {% endfor %}\n        </div>\n        <a class=\"btn primary\" href=\"{{ doc.url | relative_url }}\" style=\"width: 100%; display: block; text-align: center;\">Read More</a>\n      </div>\n    {% endfor %}\n  </div>\n</section>\n\n<section class=\"section\">\n  <div style=\"text-align: center;\">\n    <p><a href=\"{{ '/docs/' | relative_url }}\">← Back to all documentation</a></p>\n  </div>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <p class=\"muted\" style=\"margin-bottom: 6px; letter-spacing: 0.5px; text-transform: uppercase; font-size: 12px;\">Releases</p>\n    <h1>Changelog</h1>\n    <p class=\"muted\">Track the freshest updates across ABC mods, modpacks, resource packs, and datapacks.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div style=\"display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 16px;\">\n    <div style=\"display: flex; gap: 10px; align-items: center;\">\n      <i class=\"fa-solid fa-rocket\" style=\"color: var(--accent-primary);\"></i>\n      <p class=\"muted\" style=\"margin: 0;\">Sorted by latest update time</p>\n    </div>\n    <div id=\"changelog-count\" class=\"muted\" style=\"font-size: 14px;\"></div>\n  </div>\n\n  <div id=\"changelog-list\" class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px;\"></div>\n  <div id=\"changelog-empty\" class=\"muted\" style=\"display: none; text-align: center; margin: 24px 0;\">No releases found yet. Add entries to <code>data/mods.json</code> or <code>data/modpacks.json</code>.</div>\n</section>\n\n<script>\n  document.addEventListener('DOMContentLoaded', () => {\n    const listEl = document.getElementById('changelog-list');\n    const countEl = document.getElementById('changelog-count');\n    const emptyEl = document.getElementById('changelog-empty');\n\n    function formatDate(value) {\n      if (!value) return 'N/A';\n      const date = new Date(value);\n      return isNaN(date.getTime()) ? 'N/A' : date.toLocaleDateString();\n    }\n\n    function renderCard(item) {\n      const versions = (item.game_versions || []).slice(0, 4).map(v => `<span class=\"version-badge\">${v}</span>`).join('');\n      const categories = (item.categories || []).slice(0, 3).map(cat => `<span class=\"category-pill\">${cat}</span>`).join('');\n      const updated = formatDate(item.updated || item.date_modified || item.published);\n      const typeLabel = (item.project_type || item.type || 'mod').replace(/_/g, ' ');\n\n      return `\n        <article class=\"card\">\n          <div style=\"display:flex;align-items:center;gap:12px;\">\n            ${item.icon_url ? `<img src=\"${item.icon_url}\" alt=\"${item.name}\" style=\"width:48px;height:48px;border-radius:12px;border:1px solid var(--border);object-fit:cover;\" />` : '<div style=\"width:48px;height:48px;border-radius:12px;border:1px dashed var(--border);\"></div>'}\n            <div>\n              <p class=\"muted\" style=\"margin:0;font-size:12px;text-transform:uppercase;letter-spacing:0.6px;\">${typeLabel}</p>\n              <h3 style=\"margin:4px 0 0;\">${item.title || item.name}</h3>\n            </div>\n          </div>\n          <p class=\"muted\" style=\"margin: 4px 0 0;\">${item.short_description || item.description || 'No description available.'}</p>\n          <div style=\"display:flex;gap:8px;flex-wrap:wrap;align-items:center;\">\n            ${versions || '<span class=\"version-badge\">All versions</span>'}\n          </div>\n          <div style=\"display:flex;gap:10px;flex-wrap:wrap;align-items:center;\">\n            ${categories}\n          </div>\n          <div style=\"display:flex;gap:12px;flex-wrap:wrap;font-size:13px;color:var(--text-muted);\">\n            <span><i class=\"fa-regular fa-clock\"></i> Updated ${updated}</span>\n            <span><i class=\"fa-solid fa-download\"></i> ${(item.downloads || 0).toLocaleString()} downloads</span>\n            <span><i class=\"fa-solid fa-users\"></i> ${(item.followers || 0).toLocaleString()} followers</span>\n          </div>\n          <div style=\"display:flex;gap:8px;flex-wrap:wrap;\">\n            ${item.download ? `<a class=\"btn ghost\" href=\"${item.download}\" target=\"_blank\"><i class=\"fa-solid fa-arrow-up-right-from-square\"></i> View Project</a>` : ''}\n            ${item.source_url ? `<a class=\"btn ghost\" href=\"${item.source_url}\" target=\"_blank\"><i class=\"fa-brands fa-github\"></i> Source</a>` : ''}\n          </div>\n        </article>\n      `;\n    }\n\n    async function fetchJson(url) {\n      try {\n        const res = await fetch(url);\n        if (!res.ok) throw new Error(`Request failed: ${res.status}`);\n        return await res.json();\n      } catch (err) {\n        console.warn('Changelog fetch failed', err);\n        return [];\n      }\n    }\n\n    async function loadChangelog() {\n      const [mods, modpacks] = await Promise.all([\n        fetchJson('{{ '/data/mods.json' | relative_url }}'),\n        fetchJson('{{ '/data/modpacks.json' | relative_url }}')\n      ]);\n\n      const items = [...mods, ...modpacks].map(item => ({\n        ...item,\n        updated: item.updated || item.date_modified || item.published || null,\n      })).filter(item => item);\n\n      if (!items.length) {\n        emptyEl.style.display = 'block';\n        countEl.textContent = '';\n        return;\n      }\n\n      items.sort((a, b) => {\n        const dateA = new Date(a.updated || 0).getTime();\n        const dateB = new Date(b.updated || 0).getTime();\n        return dateB - dateA;\n      });\n\n      listEl.innerHTML = items.map(renderCard).join('');\n      countEl.textContent = `${items.length} releases`;\n    }\n\n    loadChangelog();\n  });\n</script>\n","<div class=\"hero\" style=\"background-image: url('{{ '/assets/images/blocks.svg' | relative_url }}'); background-size: cover; background-position: center; min-height: 120px; padding: 0.5rem 0 !important;\">\n  <div class=\"hero-content\">\n    <h1 class=\"hero-title fade-in\">Compare Modpacks</h1>\n    <p class=\"hero-description fade-in-up\">Compare features, performance, and content across modpacks</p>\n  </div>\n</div>\n\n<div class=\"comparison-container\">\n  <div class=\"comparison-header\">\n    <h2>Select Modpacks to Compare</h2>\n    <p>Choose up to 3 modpacks to compare side-by-side</p>\n  </div>\n\n  <div class=\"comparison-selector\">\n    <div class=\"selector-box\">\n      <label for=\"compare-1\">Modpack 1</label>\n      <select id=\"compare-1\" class=\"modpack-select\">\n        <option value=\"\">Select a modpack...</option>\n      </select>\n    </div>\n    <div class=\"selector-box\">\n      <label for=\"compare-2\">Modpack 2</label>\n      <select id=\"compare-2\" class=\"modpack-select\">\n        <option value=\"\">Select a modpack...</option>\n      </select>\n    </div>\n    <div class=\"selector-box\">\n      <label for=\"compare-3\">Modpack 3</label>\n      <select id=\"compare-3\" class=\"modpack-select\">\n        <option value=\"\">Select a modpack...</option>\n      </select>\n    </div>\n  </div>\n\n  <div class=\"comparison-actions\">\n    <button id=\"compare-btn\" class=\"btn btn-primary\" disabled>\n      <i class=\"fas fa-balance-scale\"></i> Compare Selected\n    </button>\n    <button id=\"clear-btn\" class=\"btn btn-secondary\">\n      <i class=\"fas fa-times\"></i> Clear All\n    </button>\n  </div>\n\n  <div id=\"comparison-results\" class=\"comparison-results hidden\">\n    <div class=\"comparison-table-wrapper\">\n      <table class=\"comparison-table\">\n        <thead>\n          <tr>\n            <th class=\"feature-col\">Feature</th>\n            <th class=\"modpack-col\" id=\"header-1\"></th>\n            <th class=\"modpack-col\" id=\"header-2\"></th>\n            <th class=\"modpack-col\" id=\"header-3\"></th>\n          </tr>\n        </thead>\n        <tbody>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-image\"></i> Icon</td>\n            <td id=\"icon-1\"></td>\n            <td id=\"icon-2\"></td>\n            <td id=\"icon-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-layer-group\"></i> Type</td>\n            <td id=\"type-1\"></td>\n            <td id=\"type-2\"></td>\n            <td id=\"type-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-info-circle\"></i> Description</td>\n            <td id=\"description-1\"></td>\n            <td id=\"description-2\"></td>\n            <td id=\"description-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-gamepad\"></i> Supported MC Versions</td>\n            <td id=\"version-1\"></td>\n            <td id=\"version-2\"></td>\n            <td id=\"version-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-download\"></i> Downloads</td>\n            <td id=\"downloads-1\"></td>\n            <td id=\"downloads-2\"></td>\n            <td id=\"downloads-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-users\"></i> Followers</td>\n            <td id=\"followers-1\"></td>\n            <td id=\"followers-2\"></td>\n            <td id=\"followers-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-calendar\"></i> Last Updated</td>\n            <td id=\"updated-1\"></td>\n            <td id=\"updated-2\"></td>\n            <td id=\"updated-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-tag\"></i> Categories</td>\n            <td id=\"categories-1\"></td>\n            <td id=\"categories-2\"></td>\n            <td id=\"categories-3\"></td>\n          </tr>\n          <tr>\n            <td class=\"feature-name\"><i class=\"fas fa-link\"></i> Links</td>\n            <td id=\"links-1\"></td>\n            <td id=\"links-2\"></td>\n            <td id=\"links-3\"></td>\n          </tr>\n        </tbody>\n      </table>\n    </div>\n  </div>\n</div>\n\n<style>\n.comparison-container {\n  max-width: 1400px;\n  margin: 3rem auto;\n  padding: 0 1rem;\n}\n\n.comparison-header {\n  text-align: center;\n  margin-bottom: 2rem;\n}\n\n.comparison-header h2 {\n  font-size: 2rem;\n  margin-bottom: 0.5rem;\n}\n\n.comparison-header p {\n  color: var(--text-muted);\n}\n\n.comparison-selector {\n  display: grid;\n  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n  gap: 1.5rem;\n  margin-bottom: 2rem;\n}\n\n.selector-box {\n  display: flex;\n  flex-direction: column;\n  gap: 0.5rem;\n}\n\n.selector-box label {\n  font-weight: 600;\n  color: var(--text);\n}\n\n.modpack-select {\n  padding: 0.75rem;\n  border: 2px solid var(--border);\n  border-radius: 8px;\n  background: var(--bg);\n  color: var(--text);\n  font-size: 1rem;\n  cursor: pointer;\n  transition: all 0.2s;\n}\n\n.modpack-select:hover {\n  border-color: var(--accent);\n}\n\n.modpack-select:focus {\n  outline: none;\n  border-color: var(--accent);\n  box-shadow: 0 0 0 3px rgba(0, 255, 157, 0.1);\n}\n\n.comparison-actions {\n  display: flex;\n  gap: 1rem;\n  justify-content: center;\n  margin-bottom: 3rem;\n}\n\n.btn {\n  padding: 0.75rem 1.5rem;\n  border: none;\n  border-radius: 8px;\n  font-size: 1rem;\n  font-weight: 600;\n  cursor: pointer;\n  transition: all 0.2s;\n  display: inline-flex;\n  align-items: center;\n  gap: 0.5rem;\n}\n\n.btn-primary {\n  background: var(--accent);\n  color: var(--bg);\n}\n\n.btn-primary:hover:not(:disabled) {\n  background: var(--accent-hover);\n  transform: translateY(-2px);\n  box-shadow: 0 4px 12px rgba(0, 255, 157, 0.3);\n}\n\n.btn-primary:disabled {\n  opacity: 0.5;\n  cursor: not-allowed;\n}\n\n.btn-secondary {\n  background: var(--bg-secondary);\n  color: var(--text);\n  border: 2px solid var(--border);\n}\n\n.btn-secondary:hover {\n  background: var(--bg-tertiary);\n  border-color: var(--text-muted);\n}\n\n.comparison-results {\n  opacity: 1;\n  transition: opacity 0.3s;\n}\n\n.comparison-results.hidden {\n  display: none;\n  opacity: 0;\n}\n\n.comparison-table-wrapper {\n  overflow-x: auto;\n  border-radius: 12px;\n  border: 2px solid var(--border);\n}\n\n.comparison-table {\n  width: 100%;\n  border-collapse: collapse;\n  background: var(--bg);\n}\n\n.comparison-table thead {\n  background: var(--bg-secondary);\n  position: sticky;\n  top: 0;\n  z-index: 10;\n}\n\n.comparison-table th,\n.comparison-table td {\n  padding: 1rem;\n  text-align: left;\n  border-bottom: 1px solid var(--border);\n}\n\n.comparison-table th {\n  font-weight: 700;\n  color: var(--text);\n}\n\n.feature-col {\n  width: 200px;\n  font-weight: 600;\n  background: var(--bg-secondary);\n  position: sticky;\n  left: 0;\n  z-index: 5;\n}\n\n.feature-name {\n  font-weight: 600;\n  background: var(--bg-secondary);\n  position: sticky;\n  left: 0;\n  z-index: 5;\n}\n\n.feature-name i {\n  margin-right: 0.5rem;\n  color: var(--accent);\n}\n\n.modpack-col {\n  min-width: 250px;\n}\n\n.comparison-table tbody tr:hover {\n  background: var(--bg-tertiary);\n}\n\n.modpack-icon {\n  width: 64px;\n  height: 64px;\n  border-radius: 8px;\n  object-fit: cover;\n}\n\n.category-pill {\n  display: inline-block;\n  padding: 0.25rem 0.75rem;\n  background: var(--accent);\n  color: var(--bg);\n  border-radius: 999px;\n  font-size: 0.875rem;\n  margin: 0.25rem;\n}\n\n.link-button {\n  display: inline-flex;\n  align-items: center;\n  gap: 0.5rem;\n  padding: 0.5rem 1rem;\n  background: var(--accent);\n  color: var(--bg);\n  text-decoration: none;\n  border-radius: 8px;\n  margin: 0.25rem;\n  transition: all 0.2s;\n}\n\n.link-button:hover {\n  background: var(--accent-hover);\n  transform: translateY(-2px);\n}\n\n@media (max-width: 768px) {\n  .comparison-selector {\n    grid-template-columns: 1fr;\n  }\n  \n  .comparison-actions {\n    flex-direction: column;\n  }\n  \n  .btn {\n    width: 100%;\n  }\n  \n  .feature-col,\n  .feature-name {\n    position: static;\n  }\n}\n</style>\n\n<script>\n// Populate selects with any content type\nconst modpacksData = {{ site.data.modpacks | default: \"[]\" | jsonify }};\nconst modsData = {{ site.data.mods | default: \"[]\" | jsonify }};\n\n// Normalize datasets and merge\nfunction parseData(raw, fallbackType) {\n  const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw || [];\n  return Array.isArray(parsed)\n    ? parsed.map((item) => ({\n        ...item,\n        content_type: item.type || item.project_type || fallbackType,\n      }))\n    : [];\n}\n\nconst items = [\n  ...parseData(modpacksData, 'modpack'),\n  ...parseData(modsData, 'mod'),\n];\n\nconst selects = ['compare-1', 'compare-2', 'compare-3'];\n\nif (Array.isArray(items) && items.length > 0) {\n  selects.forEach((selectId) => {\n    const select = document.getElementById(selectId);\n    items.forEach((item) => {\n      const option = document.createElement('option');\n      option.value = item.id;\n      const typeLabel = (item.content_type || 'modpack').replace(/_/g, ' ');\n      option.textContent = `${item.name} (${typeLabel})`;\n      select.appendChild(option);\n    });\n  });\n} else {\n  // Show message if no content available\n  document.querySelector('.comparison-selector').innerHTML =\n    '<p style=\"text-align:center;color:var(--text-muted);padding:2rem;\">No content available for comparison. Add data to _data/modpacks.json or _data/mods.json to enable this feature.</p>';\n  document.querySelector('.comparison-actions').style.display = 'none';\n}\n\n// Enable/disable compare button (guard if DOM missing)\nfunction updateCompareButton() {\n  const compareBtn = document.getElementById('compare-btn');\n  if (!compareBtn) return;\n  const selected = selects\n    .map(id => document.getElementById(id))\n    .filter(Boolean)\n    .map(el => el.value)\n    .filter(Boolean);\n  compareBtn.disabled = selected.length < 2;\n}\n\nselects.forEach(id => {\n  const el = document.getElementById(id);\n  if (el) el.addEventListener('change', updateCompareButton);\n});\n\nconst compareBtnEl = document.getElementById('compare-btn');\nconst clearBtnEl = document.getElementById('clear-btn');\n\n// Compare functionality\ncompareBtnEl?.addEventListener('click', () => {\n  const selectedIds = selects\n    .map(id => document.getElementById(id))\n    .filter(Boolean)\n    .map(el => el.value)\n    .filter(Boolean);\n  const selectedItems = selectedIds\n    .map(id => items.find(m => m.id === id))\n    .filter(Boolean);\n  \n  // Populate table\n  selectedItems.forEach((item, index) => {\n    const col = index + 1;\n    const typeLabel = (item.content_type || 'modpack').replace(/_/g, ' ');\n    \n    // Header\n    document.getElementById(`header-${col}`).innerHTML = `<strong>${item.name}</strong>`;\n    \n    // Icon\n    document.getElementById(`icon-${col}`).innerHTML = \n      item.icon_url ? `<img src=\"${item.icon_url}\" alt=\"${item.name}\" class=\"modpack-icon\">` : 'N/A';\n\n    // Type\n    document.getElementById(`type-${col}`).textContent = typeLabel;\n    \n    // Description\n    document.getElementById(`description-${col}`).textContent = item.short_description || item.description || 'N/A';\n    \n    // Versions\n    const versionBadges = (item.game_versions || []).slice(0, 4).map(v => `<span class=\"version-badge\">${v}</span>`).join('');\n    document.getElementById(`version-${col}`).innerHTML = versionBadges || 'N/A';\n    \n    // Downloads\n    document.getElementById(`downloads-${col}`).innerHTML = \n      `<strong>${(item.downloads || 0).toLocaleString()}</strong>`;\n    \n    // Followers\n    document.getElementById(`followers-${col}`).innerHTML = \n      `<strong>${(item.followers || 0).toLocaleString()}</strong>`;\n    \n    // Updated\n    const date = item.date_modified || item.updated;\n    const dateText = date ? new Date(date).toLocaleDateString() : 'N/A';\n    document.getElementById(`updated-${col}`).textContent = dateText;\n    \n    // Categories\n    const categories = (item.categories || []).map(cat => \n      `<span class=\"category-pill\">${cat}</span>`\n    ).join('');\n    document.getElementById(`categories-${col}`).innerHTML = categories || 'N/A';\n    \n    // Links\n    const links = [\n      item.project_url || item.download ? `<a href=\"${item.project_url || item.download}\" class=\"link-button\" target=\"_blank\"><i class=\"fas fa-external-link-alt\"></i> View Project</a>` : '',\n      item.source_url ? `<a href=\"${item.source_url}\" class=\"link-button\" target=\"_blank\"><i class=\"fab fa-github\"></i> Source</a>` : ''\n    ].filter(l => l).join('');\n    document.getElementById(`links-${col}`).innerHTML = links || 'N/A';\n  });\n  \n  // Clear remaining columns\n  for (let i = selectedItems.length + 1; i <= 3; i++) {\n    document.getElementById(`header-${i}`).innerHTML = '';\n    ['icon', 'description', 'version', 'downloads', 'followers', 'updated', 'categories', 'links'].forEach(field => {\n      document.getElementById(`${field}-${i}`).innerHTML = '';\n    });\n  }\n  \n  // Show results with animation\n  const results = document.getElementById('comparison-results');\n  results.classList.remove('hidden');\n  setTimeout(() => results.style.opacity = '1', 10);\n  \n  // Scroll to results\n  results.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\ndocument.getElementById('clear-btn').addEventListener('click', () => {\n});\n\n// Clear functionality\nclearBtnEl?.addEventListener('click', () => {\n  selects.forEach(id => {\n    const el = document.getElementById(id);\n    if (el) el.value = '';\n  });\n  updateCompareButton();\n  const results = document.getElementById('comparison-results');\n  if (results) results.classList.add('hidden');\n});\n</script>\n","<section class=\"section\">\n  <h1>Contact & Support</h1>\n  <p class=\"muted\">Reach out for issues, feedback, or collaboration.</p>\n\n  <h2>Fastest ways</h2>\n  <ul>\n    <li>Discord: <a href=\"{{ site.social.discord }}\" target=\"_blank\" rel=\"noopener\">Join our server</a></li>\n    <li>GitHub: <a href=\"{{ site.social.github }}\" target=\"_blank\" rel=\"noopener\">Open an issue</a> on our repos</li>\n  </ul>\n\n  <h2>Feedback</h2>\n  <p>Use the \"Was this helpful?\" widget on docs pages for quick feedback. For broader requests, ping us on Discord.</p>\n</section>\n","# Cookie Policy\n\n**Last Updated:** December 2024\n\nWe use cookies and similar tracking technologies to enhance your experience on our site. This policy explains what cookies are, how we use them, and your rights regarding them.\n\n## What Are Cookies?\n\nCookies are small text files stored on your browser or device that help websites remember information about your visits. They can be:\n\n- **Session cookies**: Deleted when you close your browser\n- **Persistent cookies**: Remain on your device for a set period\n- **First-party cookies**: Set by our domain\n- **Third-party cookies**: Set by external services (analytics, ads, etc.)\n\n## Cookies We Use\n\n### Analytics\n\nWe use Google Analytics to understand how visitors use our site:\n\n- `_ga` – Identifies unique visitors\n- `_ga_*` – Tracks sessions and page views\n- `_gat` – Throttles request rate\n\n**Purpose**: Analyzing site traffic and user behavior  \n**Retention**: 2 years\n\n### Functional Cookies\n\n- `theme` – Remembers your color theme preference\n- `language` – Stores your preferred language\n\n**Purpose**: Improving site usability  \n**Retention**: 1 year\n\n### Consent Management\n\n- `cookie_consent` – Stores your cookie preferences\n- `cookie_consent_timestamp` – Records when consent was given\n\n**Purpose**: Respecting your privacy choices  \n**Retention**: 1 year\n\n## Third-Party Services\n\nWe may use services that set their own cookies:\n\n| Service          | Cookies         | Purpose        | Policy                                                |\n| ---------------- | --------------- | -------------- | ----------------------------------------------------- |\n| Google Analytics | `_ga*`, `_gat`  | Site analytics | [Privacy Policy](https://policies.google.com/privacy) |\n| Font Awesome     | Session cookies | Icon delivery  | [Privacy](https://fontawesome.com/privacy)            |\n| Discord          | If embedded     | Embeds/widgets | [Privacy](https://discord.com/privacy)                |\n\n## Cookie Preferences\n\nYou can manage your cookie preferences using our cookie consent banner at the bottom of the page. You can:\n\n- Accept all cookies\n- Reject non-essential cookies\n- Customize preferences\n\n### Browser Controls\n\nMost browsers allow you to:\n\n- Block cookies entirely\n- Clear cookies on exit\n- View stored cookies\n- Opt-out of tracking\n\n**Note**: Blocking essential cookies may affect site functionality.\n\n## Your Rights\n\nUnder GDPR and similar privacy laws, you have the right to:\n\n- Know what cookies are used\n- Opt-out of non-essential cookies\n- Request deletion of your data\n- Access or port your data\n\n## Contact\n\nIf you have questions about our cookie practices:\n\n**Email**: [contact information from site config]\n\nWe will respond within 30 days.\n\n## Changes\n\nWe may update this policy periodically. Your continued use of the site constitutes acceptance of any changes.\n\n---\n\n_This Cookie Policy is part of our overall Privacy Policy and Terms of Service._\n","<section class=\"section\">\n  <h1>Disclaimer & Liability Waiver</h1>\n  <p class=\"muted\">Last updated: December 11, 2025</p>\n\n  <p>This page contains important disclaimers and limitations of liability. Please read carefully before using our website and projects.</p>\n\n  <h2>1. Website & Content Disclaimer</h2>\n\n  <h3>1.1 \"As Is\" Provision</h3>\n  <p>Our website and all materials are provided \"AS IS\" and \"AS AVAILABLE\" without warranties of any kind, either express or implied. We make no warranties regarding:</p>\n  <ul>\n    <li>Accuracy, completeness, or timeliness of information</li>\n    <li>Fitness for a particular purpose</li>\n    <li>Functionality or performance</li>\n    <li>Non-infringement of rights</li>\n    <li>Quality or reliability</li>\n  </ul>\n\n  <h3>1.2 No Professional Advice</h3>\n  <p>Content on our site is for informational purposes only and does not constitute:</p>\n  <ul>\n    <li>Legal advice</li>\n    <li>Technical support (though we'll help if we can)</li>\n    <li>Professional consulting</li>\n    <li>Warranty or guarantee</li>\n  </ul>\n  <p>Always consult appropriate professionals for critical decisions.</p>\n\n  <h2>2. Minecraft Project Disclaimer</h2>\n\n  <h3>2.1 No Warranty for Mods/Datapacks/Plugins</h3>\n  <p>All our Minecraft projects are provided \"AS IS\" without any warranty. We do not guarantee:</p>\n  <ul>\n    <li>The mod will work with your specific Minecraft version</li>\n    <li>The mod will work with other mods you have installed (compatibility)</li>\n    <li>The mod won't cause crashes or performance issues</li>\n    <li>The mod won't corrupt your world or save files</li>\n    <li>The mod will continue to be maintained or updated</li>\n    <li>The mod is free of bugs or issues</li>\n  </ul>\n\n  <h3>2.2 Save File Loss</h3>\n  <p><strong>YOU ARE RESPONSIBLE FOR BACKING UP YOUR MINECRAFT WORLDS AND SAVES.</strong></p>\n  <ul>\n    <li>Always backup important worlds before installing mods</li>\n    <li>Test mods in a separate test world first</li>\n    <li>Keep multiple backups of valuable worlds</li>\n    <li>We are NOT liable for corrupted, lost, or deleted save files</li>\n  </ul>\n\n  <h3>2.3 Crashes & Compatibility</h3>\n  <ul>\n    <li>Mod conflicts, crashes, and performance issues are common in modded Minecraft</li>\n    <li>We provide projects \"as is\" without technical support guarantee</li>\n    <li>We'll do our best to help troubleshoot but cannot guarantee solutions</li>\n    <li>Some issues may require reinstalling Java, Minecraft, or removing conflicting mods</li>\n  </ul>\n\n  <h2>3. Limitation of Liability</h2>\n\n  <h3>3.1 No Liability For</h3>\n  <p><strong>In no event shall ABC, its owners, employees, contributors, or partners be liable for:</strong></p>\n  <ul>\n    <li>Lost or corrupted Minecraft save files or worlds</li>\n    <li>Game crashes, performance degradation, or lag</li>\n    <li>System damage or instability caused by our projects</li>\n    <li>Loss of income, profits, or business opportunities</li>\n    <li>Loss of data or information (in any form)</li>\n    <li>Any indirect, incidental, special, consequential, or punitive damages</li>\n    <li>Damages arising from your use or inability to use our site/projects</li>\n    <li>Issues caused by other mods or software on your system</li>\n    <li>Your failure to backup important data</li>\n    <li>Time or inconvenience</li>\n  </ul>\n  <p>This applies even if we have been advised of the possibility of such damages.</p>\n\n  <h3>3.2 Damages Cap</h3>\n  <p>If any court overrides the above disclaimer, our total liability is limited to <strong>zero dollars</strong> ($0). We are providing these projects for free.</p>\n\n  <h2>4. Assumption of Risk</h2>\n\n  <p>By using our website and projects, you acknowledge and assume all risks associated with:</p>\n  <ul>\n    <li>Installing and using mods/datapacks/plugins</li>\n    <li>Potential loss of save files or worlds</li>\n    <li>Game crashes or instability</li>\n    <li>Compatibility issues with your setup</li>\n    <li>System performance changes</li>\n    <li>Following installation instructions incorrectly</li>\n    <li>Running outdated Java or Minecraft versions</li>\n    <li>Conflicts with other mods or software</li>\n  </ul>\n\n  <h2>5. User Responsibility</h2>\n\n  <p>You are responsible for:</p>\n  <ul>\n    <li>✓ Reading and understanding installation instructions</li>\n    <li>✓ Keeping your Minecraft and Java updated</li>\n    <li>✓ Backing up your worlds and save files regularly</li>\n    <li>✓ Testing mods in a test world first</li>\n    <li>✓ Managing your system and mod installations</li>\n    <li>✓ Removing conflicting mods if issues arise</li>\n    <li>✓ Reporting issues accurately and completely</li>\n    <li>✓ Following applicable laws and terms (EULA, etc.)</li>\n  </ul>\n\n  <h2>6. Third-Party Services Disclaimer</h2>\n\n  <p>Our website uses third-party services and links:</p>\n  <ul>\n    <li><strong>Modrinth:</strong> We are not responsible for content, quality, or policies</li>\n    <li><strong>GitHub:</strong> External service; we don't control availability or policies</li>\n    <li><strong>Discord:</strong> Community platform; moderation is best-effort</li>\n    <li><strong>Google Analytics:</strong> Data collection per their privacy policy</li>\n  </ul>\n  <p>Review each service's terms and privacy policy before using.</p>\n\n  <h2>7. Availability Disclaimer</h2>\n\n  <ul>\n    <li>We do not guarantee continuous service availability</li>\n    <li>The website may be offline for maintenance without notice</li>\n    <li>Projects may be discontinued or archived</li>\n    <li>Downloads from third-party sites may become unavailable</li>\n    <li>We are not liable for service interruptions or data loss</li>\n  </ul>\n\n  <h2>8. Accuracy Disclaimer</h2>\n\n  <ul>\n    <li>We strive for accuracy but do not guarantee all information is correct</li>\n    <li>Documentation may become outdated</li>\n    <li>Minecraft updates may change how our projects work</li>\n    <li>We are not liable for decisions based on incorrect information</li>\n    <li>Always verify critical information independently</li>\n  </ul>\n\n  <h2>9. Health & Safety Disclaimer</h2>\n\n  <p>Using computers for extended periods can cause:</p>\n  <ul>\n    <li>Eye strain</li>\n    <li>Repetitive stress injuries (RSI)</li>\n    <li>Sleep disruption</li>\n    <li>Posture problems</li>\n  </ul>\n  <p>Take regular breaks, maintain good posture, and consult a doctor if experiencing discomfort.</p>\n\n  <h2>10. Indemnification</h2>\n\n  <p>You agree to indemnify and hold harmless ABC and its representatives from any claims, damages, or losses arising from:</p>\n  <ul>\n    <li>Your use of our site or projects</li>\n    <li>Violation of these disclaimers or our Terms</li>\n    <li>Your violation of any laws or third-party rights</li>\n    <li>Your content or actions</li>\n  </ul>\n\n  <h2>11. Questions or Concerns?</h2>\n\n  <p>If you don't agree with these disclaimers or have concerns:</p>\n  <ul>\n    <li>Do not use our site or projects</li>\n    <li><a href=\"{{ '/contact/' | relative_url }}\">Contact us</a> with specific concerns</li>\n  </ul>\n\n  <hr style=\"margin: 32px 0; border: none; border-top: 1px solid var(--border);\">\n\n  <p class=\"muted\" style=\"font-size: 12px;\">\n    <strong>Bottom Line:</strong> Our projects are free. Use at your own risk. Backup your saves. Test before using on important worlds. We're not responsible for any damages. Questions? Ask us.\n  </p>\n</section>\n","If you are not redirected automatically, join here: {{ site.social.discord }}\n","# End User License Agreement (EULA)\n\n**Last Updated:** December 2024\n\nThis End User License Agreement (\"EULA\") is a legal agreement between you and ABC Team governing your use of our projects, mods, datapacks, plugins, and related software (\"Software\").\n\n## 1. Grant of License\n\nWe grant you a non-exclusive, non-transferable, limited license to use the Software for personal, non-commercial purposes, subject to the terms of this agreement.\n\n### Permitted Uses\n\n✅ Install and use on your personal devices  \n✅ Create content using the Software (videos, streams, guides)  \n✅ Modify the Software for personal use  \n✅ Use in private multiplayer servers\n\n### Prohibited Uses\n\n❌ Commercial redistribution without permission  \n❌ Reselling modified versions  \n❌ Claiming ownership of the Software  \n❌ Reverse engineering for competitive purposes  \n❌ Removing attribution or license notices\n\n## 2. Intellectual Property Rights\n\nAll Software, including code, assets, textures, and designs, are owned by ABC Team or our contributors. You may not claim ownership or use the Software outside the scope of this license.\n\n### Attribution\n\nWhen using or referencing the Software, you agree to:\n\n- Maintain original credits\n- Link to our GitHub or website\n- Not remove license files\n- Acknowledge ABC Team as creators\n\n## 3. Modifications\n\nYou may modify the Software for personal use. However:\n\n- Modified versions cannot be redistributed commercially\n- You must maintain original licenses and credits\n- We are not responsible for issues caused by your modifications\n- Private use of mods is always permitted\n\n## 4. Server Usage\n\nYou may:\n\n- Run the Software on private servers\n- Run on public servers (community/multiplayer)\n- Accept donations (but not force payment)\n\nYou must:\n\n- Display credits/links in server descriptions\n- Not claim the Software as your own creation\n- Not charge for access to unmodified Software\n\n## 5. Content & Creator Policy\n\n**Streaming & YouTube**: Fully allowed. No permission required.\n\n**Monetization**: You may monetize content featuring the Software (ads, sponsorships, Patreon). You do not owe us revenue share.\n\n**Attribution**: Simply crediting \"ABC Team\" or linking to our GitHub is appreciated but not required.\n\n## 6. Warranty Disclaimer\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.\n\nWe do not warrant that:\n\n- The Software will meet your requirements\n- The Software will be error-free or bug-free\n- The Software will be compatible with all platforms\n- Updates will be provided\n\n## 7. Limitation of Liability\n\nTO THE MAXIMUM EXTENT PERMITTED BY LAW, WE SHALL NOT BE LIABLE FOR:\n\n- Data loss or corruption\n- Loss of profit or revenue\n- Interruption of service\n- Any indirect, incidental, or consequential damages\n\nEven if we have been advised of the possibility of such damages.\n\n## 8. Termination\n\nWe may terminate this license if you:\n\n- Violate any terms of this EULA\n- Use the Software for illegal purposes\n- Redistribute the Software commercially without permission\n- Harass or abuse our team\n\nUpon termination, you must cease using the Software.\n\n## 9. Third-Party Components\n\nThe Software may include third-party libraries or assets. You acknowledge and agree to comply with their respective licenses, which are listed in the project repository.\n\n## 10. Governing Law\n\nThis EULA is governed by and construed in accordance with applicable laws. Any disputes shall be resolved through negotiation or mediation.\n\n## 11. Changes to This EULA\n\nWe may update this EULA at any time. Continued use of the Software constitutes acceptance of changes. We recommend reviewing this EULA periodically.\n\n## 12. Contact\n\nIf you have questions about this EULA:\n\n**GitHub**: [Link from site config]  \n**Discord**: [Link from site config]\n\n---\n\n**By installing or using this Software, you acknowledge that you have read, understood, and agree to be bound by the terms of this EULA.**\n\nLast Updated: December 2024\n","{% assign t = site.data[page.lang] %}\n\n<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>{{ t.hero_title }}</h1>\n    <p class=\"muted\">{{ t.hero_subtitle }}</p>\n    <div class=\"cta-row\">\n      <a class=\"btn primary\" href=\"{{ '/fr/projects/' | relative_url }}\">{{ t.browse_projects }}</a>\n      <a class=\"btn ghost\" href=\"{{ '/fr/about/' | relative_url }}\">{{ t.learn_more }}</a>\n    </div>\n  </div>\n</section>\n\n<section id=\"featured\" class=\"section\">\n  <h2>{{ t.featured_title }}</h2>\n  <p class=\"muted\">{{ t.featured_subtitle }}</p>\n  \n  {% if site.data.modpacks and site.data.modpacks.size > 0 %}\n  <div class=\"featured-spotlight\" style=\"margin-bottom: 2rem;\">\n    <div class=\"spotlight-grid\">\n      {% assign sorted_modpacks = site.data.modpacks | sort: 'date_modified' | reverse %}\n      {% for modpack in sorted_modpacks limit:3 %}\n      <div class=\"spotlight-card animate-on-scroll scale-in stagger-{{ forloop.index }}\">\n        <div class=\"spotlight-badge\">\n          <i class=\"fas fa-star\"></i> {{ t.featured_badge }}\n        </div>\n        <div class=\"spotlight-image\" style=\"background-image: url('{{ modpack.icon_url }}')\"></div>\n        <div class=\"spotlight-content\">\n          <h3>{{ modpack.name }}</h3>\n          <p class=\"muted\">{{ modpack.description | truncate: 100 }}</p>\n          <div class=\"spotlight-meta\">\n            <span class=\"meta-item\">\n              <i class=\"fas fa-download\"></i> {{ modpack.downloads | default: 0 | divided_by: 1000 }}K\n            </span>\n            <span class=\"meta-item\">\n              <i class=\"fas fa-heart\"></i> {{ modpack.followers | default: 0 }}\n            </span>\n            {% if modpack.game_versions and modpack.game_versions.size > 0 %}\n            <span class=\"meta-item\">\n              <i class=\"fas fa-gamepad\"></i> {{ modpack.game_versions[0] }}\n            </span>\n            {% endif %}\n          </div>\n          <div class=\"spotlight-actions\">\n            <a href=\"{{ modpack.project_url }}\" class=\"btn-spotlight primary\" target=\"_blank\" rel=\"noopener\">\n              <i class=\"fas fa-external-link-alt\"></i> {{ t.view_project }}\n            </a>\n            {% if modpack.source_url %}\n            <a href=\"{{ modpack.source_url }}\" class=\"btn-spotlight ghost\" target=\"_blank\" rel=\"noopener\">\n              <i class=\"fab fa-github\"></i> {{ t.source }}\n            </a>\n            {% endif %}\n          </div>\n        </div>\n      </div>\n      {% endfor %}\n    </div>\n  </div>\n  {% endif %}\n  \n  {% include modpacks.html %}\n</section>\n\n<section class=\"section\" id=\"project-stats\">\n  <h2>{{ t.stats_title }}</h2>\n  <p class=\"muted\">{{ t.stats_subtitle }}</p>\n  <div class=\"stats-grid\" id=\"stats-grid\">\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_total_projects }}</p>\n      <div class=\"stat-number\" id=\"stat-projects\">—</div>\n      <div class=\"stat-sub\" id=\"stat-projects-sub\">{{ t.stat_loading }}</div>\n    </div>\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_total_downloads }}</p>\n      <div class=\"stat-number\" id=\"stat-downloads\">—</div>\n      <div class=\"stat-sub\" id=\"stat-downloads-sub\">{{ t.stat_loading }}</div>\n    </div>\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_supported_loaders }}</p>\n      <div class=\"stat-number\" id=\"stat-loaders-count\">—</div>\n      <div class=\"stat-sub\" id=\"stat-loaders\">{{ t.stat_loading }}</div>\n    </div>\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_game_versions }}</p>\n      <div class=\"stat-number\" id=\"stat-versions\">—</div>\n      <div class=\"stat-sub\" id=\"stat-versions-sub\">{{ t.stat_loading }}</div>\n    </div>\n  </div>\n  <div class=\"card\" id=\"top-categories\" style=\"margin-top:16px;\">\n    <h3 style=\"margin-top:0\">{{ t.stat_top_categories }}</h3>\n    <div id=\"stat-categories\" class=\"pill-row\">{{ t.stat_loading }}</div>\n  </div>\n  <div class=\"card\" id=\"downloads-card\" style=\"margin-top:16px;\">\n    <h3 style=\"margin-top:0\">{{ t.stat_top_downloads }}</h3>\n    <p class=\"muted\" id=\"stat-downloads-note\">{{ t.stat_downloads_note }}</p>\n    <div class=\"line-chart\" id=\"downloads-chart\"></div>\n  </div>\n</section>\n\n<section class=\"section\">\n  <div class=\"card\">\n    <h2 style=\"margin-top: 0\">🚀 Modrinth Organization</h2>\n    <div style=\"display: grid; gap: 16px\">\n      <p class=\"muted\">Tous nos projets sont publiés et maintenus via Modrinth.</p>\n      <a class=\"btn ghost\" href=\"{{ site.modrinth.organization_url | default: site.social.modrinth }}\" target=\"_blank\" rel=\"noopener\">Aller sur Modrinth</a>\n    </div>\n  </div>\n</section>\n\n<script>\n  // Load stats from cached mods.json and populate snapshot cards\n  document.addEventListener('DOMContentLoaded', async () => {\n    const modsUrl = '{{ '/data/mods.json' | relative_url }}';\n    const statProjects = document.getElementById('stat-projects');\n    const statProjectsSub = document.getElementById('stat-projects-sub');\n    const statDownloads = document.getElementById('stat-downloads');\n    const statDownloadsSub = document.getElementById('stat-downloads-sub');\n    const statLoaders = document.getElementById('stat-loaders');\n    const statLoadersCount = document.getElementById('stat-loaders-count');\n    const statVersions = document.getElementById('stat-versions');\n    const statVersionsSub = document.getElementById('stat-versions-sub');\n    const statCategories = document.getElementById('stat-categories');\n    const downloadsChart = document.getElementById('downloads-chart');\n    const downloadsNote = document.getElementById('stat-downloads-note');\n\n    try {\n      const res = await fetch(modsUrl);\n      if (!res.ok) throw new Error(`HTTP ${res.status}`);\n      const mods = await res.json();\n      if (!Array.isArray(mods) || mods.length === 0) throw new Error('{{ t.no_projects_found }}');\n\n      const loaders = new Set();\n      const versions = new Set();\n      const categories = new Map();\n      let totalDownloads = 0;\n\n      mods.forEach(m => {\n        (m.loaders || []).forEach(l => loaders.add(l));\n        (m.game_versions || []).forEach(v => versions.add(v));\n        totalDownloads += Number(m.downloads || 0);\n        (m.categories || []).forEach(c => {\n          categories.set(c, (categories.get(c) || 0) + 1);\n        });\n        (m.display_categories || []).forEach(c => {\n          categories.set(c, (categories.get(c) || 0) + 1);\n        });\n      });\n\n      const formatNumber = (n) => n.toLocaleString(undefined, { maximumFractionDigits: 0 });\n      \n      const t = {\n        projects_catalog: '{{ t.stat_projects_catalog }}',\n        avg_per_project: '{{ t.stat_avg_per_project }}',\n        unique_versions: '{{ t.stat_unique_versions }}',\n        no_categories: '{{ t.stat_no_categories }}',\n        no_data: '{{ t.stat_no_data }}',\n        unavailable: '{{ t.stat_unavailable }}'\n      };\n\n      statProjects.textContent = formatNumber(mods.length);\n      statProjectsSub.textContent = t.projects_catalog;\n\n      statDownloads.textContent = formatNumber(totalDownloads);\n      const avgDownloads = mods.length ? Math.round(totalDownloads / mods.length) : 0;\n      statDownloadsSub.textContent = `${formatNumber(avgDownloads)} ${t.avg_per_project}`;\n\n      const loaderList = Array.from(loaders).sort();\n      const versionCount = versions.size;\n\n      statLoadersCount.textContent = loaderList.length ? formatNumber(loaderList.length) : '—';\n      statLoaders.textContent = loaderList.length ? loaderList.join(', ') : '—';\n      statVersions.textContent = versionCount ? formatNumber(versionCount) : '—';\n      statVersionsSub.textContent = versionCount ? t.unique_versions : '—';\n\n      const topCats = Array.from(categories.entries())\n        .sort((a, b) => b[1] - a[1])\n        .slice(0, 6)\n        .map(([c, count]) => `<span class=\"pill\">${c} (${count})</span>`) || [];\n      statCategories.innerHTML = topCats.length ? topCats.join(' ') : t.no_categories;\n\n      // Top downloads multi-line chart (simulated week data)\n      const topDownloads = [...mods]\n        .filter(m => typeof m.downloads === 'number')\n        .sort((a, b) => (b.downloads || 0) - (a.downloads || 0))\n        .slice(0, 11);\n\n      if (topDownloads.length && downloadsChart) {\n        downloadsChart.innerHTML = '';\n        \n        const colors = [\n          '#1bd96f', '#10a8e0', '#22d3ee', '#a78bfa', '#f472b6',\n          '#fb923c', '#fbbf24', '#4ade80', '#60a5fa', '#c084fc', '#f87171'\n        ];\n\n        // Simulate week data with realistic curves (7 days)\n        const days = 7;\n        const maxValue = Math.max(...topDownloads.map(m => m.downloads || 0));\n        \n        const chartWrapper = document.createElement('div');\n        chartWrapper.style.cssText = 'display:flex;gap:20px;align-items:stretch;margin-bottom:12px;';\n\n        // Left side: chart\n        const chartContainer = document.createElement('div');\n        chartContainer.style.cssText = 'flex:1;background:var(--bg-primary);border:1px solid var(--border);padding:16px;box-sizing:border-box;position:relative;';\n\n        const svgWrapper = document.createElement('div');\n        svgWrapper.style.cssText = 'width:100%;height:240px;position:relative;';\n        \n        // Tooltip\n        const tooltip = document.createElement('div');\n        tooltip.style.cssText = 'position:absolute;background:rgba(0,0,0,0.8);color:white;border:1px solid var(--border);padding:8px 12px;border-radius:6px;font-size:12px;pointer-events:none;opacity:0;transition:opacity 0.2s;z-index:10;white-space:nowrap;box-shadow:0 4px 12px rgba(0,0,0,0.4);';\n        chartContainer.appendChild(tooltip);\n\n        const width = 800;\n        const height = 200;\n\n        const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n        svg.setAttribute('viewBox', `0 0 ${width} ${height}`);\n        svg.setAttribute('preserveAspectRatio', 'none');\n        svg.style.cssText = 'width:100%;height:100%;display:block;';\n\n        topDownloads.forEach((mod, idx) => {\n          const color = colors[idx % colors.length];\n          const baseValue = mod.downloads || 0;\n          \n          const points = [];\n          \n          for (let day = 0; day < days; day++) {\n            const x = (day / (days - 1)) * width;\n            const variance = Math.sin(day * 0.8 + idx) * 0.3 + Math.cos(day * 1.2 - idx) * 0.2;\n            const normalizedValue = (baseValue / maxValue) * (0.4 + variance * 0.6);\n            const y = height - Math.max(4, Math.min(height - 4, normalizedValue * (height * 0.9)));\n            const simulatedDownloads = Math.round(baseValue * normalizedValue);\n            points.push({ x, y, downloads: simulatedDownloads, day });\n          }\n\n          const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n          const d = points.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x} ${p.y}`).join(' ');\n          path.setAttribute('d', d);\n          path.setAttribute('fill', 'none');\n          path.setAttribute('stroke', color);\n          path.setAttribute('stroke-width', '2');\n          path.setAttribute('opacity', '0.85');\n          path.style.cursor = 'pointer';\n          \n          points.forEach(p => {\n            const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n            circle.setAttribute('cx', p.x);\n            circle.setAttribute('cy', p.y);\n            circle.setAttribute('r', '4.5');\n            circle.setAttribute('fill', color);\n            circle.setAttribute('opacity', '0.9');\n            circle.style.cursor = 'pointer';\n            svg.appendChild(circle);\n          });\n          \n          path.addEventListener('mouseenter', () => {\n            path.setAttribute('stroke-width', '3');\n            path.setAttribute('opacity', '1');\n          });\n          path.addEventListener('mouseleave', () => {\n            path.setAttribute('stroke-width', '2');\n            path.setAttribute('opacity', '0.85');\n            tooltip.style.opacity = '0';\n          });\n          path.addEventListener('mousemove', (e) => {\n            const rect = chartContainer.getBoundingClientRect();\n            const svgRect = svg.getBoundingClientRect();\n            const relX = ((e.clientX - svgRect.left) / svgRect.width) * width;\n            const closestPoint = points.reduce((prev, curr) => \n              Math.abs(curr.x - relX) < Math.abs(prev.x - relX) ? curr : prev\n            );\n            \n            tooltip.innerHTML = `<div style=\"color:${color};font-weight:600;margin-bottom:2px;\">${mod.title || mod.name}</div><div>Jour ${closestPoint.day + 1}: ${formatNumber(closestPoint.downloads)} téléchargements</div>`;\n            tooltip.style.opacity = '1';\n            tooltip.style.left = Math.min(rect.width - tooltip.offsetWidth - 10, Math.max(10, e.clientX - rect.left + 10)) + 'px';\n            tooltip.style.top = Math.max(10, e.clientY - rect.top - 40) + 'px';\n          });\n          \n          svg.appendChild(path);\n        });\n\n        svgWrapper.appendChild(svg);\n        chartContainer.appendChild(svgWrapper);\n\n        const legendContainer = document.createElement('div');\n        legendContainer.style.cssText = 'width:200px;display:flex;flex-direction:column;gap:8px;overflow-y:auto;max-height:240px;padding-right:8px;';\n        legendContainer.className = 'line-legend';\n        legendContainer.innerHTML = topDownloads.map((m, idx) => {\n          const color = colors[idx % colors.length];\n          return `<div class=\"legend-item\" style=\"display:flex;align-items:center;gap:8px;font-size:13px;color:var(--text-secondary);\"><span style=\"width:8px;height:8px;border-radius:50%;background:${color};display:inline-block;flex-shrink:0;\"></span><span style=\"overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\">${m.title || m.name}</span></div>`;\n        }).join('');\n\n        chartWrapper.appendChild(chartContainer);\n        chartWrapper.appendChild(legendContainer);\n        downloadsChart.appendChild(chartWrapper);\n      } else if (downloadsNote) {\n        downloadsNote.textContent = t.no_data;\n      }\n    } catch (e) {\n      statProjects.textContent = '—';\n      statProjectsSub.textContent = t.unavailable;\n      statDownloads.textContent = '—';\n      statDownloadsSub.textContent = t.unavailable;\n      statLoadersCount.textContent = '—';\n      statLoaders.textContent = t.unavailable;\n      statVersions.textContent = '—';\n      statVersionsSub.textContent = t.unavailable;\n      statCategories.textContent = `{{ t.error_loading }} ${e.message}`;\n      if (downloadsNote) downloadsNote.textContent = `{{ t.error_loading }}`;\n      console.warn('{{ t.failed_to_load }}:', e);\n    }\n  });\n</script>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Documentation</h1>\n    <p class=\"muted\">Complete guides for setting up, customizing, and contributing to the ABC showcase.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2 style=\"margin-bottom: 16px;\">Search & Filter</h2>\n  <div style=\"display: flex; gap: 16px; margin-bottom: 32px; flex-wrap: wrap;\">\n    <input id=\"docs-search\" type=\"search\" placeholder=\"Search documentation...\" style=\"flex: 1; min-width: 200px; padding: 10px 12px; border: 1px solid var(--border); background: var(--bg-secondary); color: var(--text); border-radius: 6px; font-size: 14px;\">\n    <select id=\"docs-category\" style=\"padding: 10px 12px; border: 1px solid var(--border); background: var(--bg-secondary); color: var(--text); border-radius: 6px; font-size: 14px;\">\n      <option value=\"\">All Categories</option>\n      <option value=\"Setup\">Setup</option>\n      <option value=\"Styling\">Styling</option>\n      <option value=\"Community\">Community</option>\n      <option value=\"Help\">Help</option>\n      <option value=\"User Guide\">User Guide</option>\n      <option value=\"Developer\">Developer</option>\n    </select>\n  </div>\n\n  <h3 style=\"margin-bottom: 16px;\">Browse by Category</h3>\n  <div class=\"grid docs-grid\">\n    <a class=\"card\" href=\"{{ '/docs/category/setup/' | relative_url }}\" style=\"text-decoration: none; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;\">\n      <i class=\"fa-solid fa-gear\" style=\"font-size: 24px; color: var(--accent-primary);\"></i>\n      <div>\n        <h3 style=\"margin: 0;\">Setup</h3>\n        <p class=\"muted\" style=\"margin: 0; font-size: 13px;\">Installation & configuration</p>\n      </div>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/styling/' | relative_url }}\" style=\"text-decoration: none; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;\">\n      <i class=\"fa-solid fa-palette\" style=\"font-size: 24px; color: var(--accent-primary);\"></i>\n      <div>\n        <h3 style=\"margin: 0;\">Styling</h3>\n        <p class=\"muted\" style=\"margin: 0; font-size: 13px;\">Themes & customization</p>\n      </div>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/user-guide/' | relative_url }}\" style=\"text-decoration: none; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;\">\n      <i class=\"fa-solid fa-book-open\" style=\"font-size: 24px; color: var(--accent-primary);\"></i>\n      <div>\n        <h3 style=\"margin: 0;\">User Guide</h3>\n        <p class=\"muted\" style=\"margin: 0; font-size: 13px;\">For end users</p>\n      </div>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/community/' | relative_url }}\" style=\"text-decoration: none; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;\">\n      <i class=\"fa-solid fa-users\" style=\"font-size: 24px; color: var(--accent-primary);\"></i>\n      <div>\n        <h3 style=\"margin: 0;\">Community</h3>\n        <p class=\"muted\" style=\"margin: 0; font-size: 13px;\">Contributing & support</p>\n      </div>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/developer/' | relative_url }}\" style=\"text-decoration: none; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;\">\n      <i class=\"fa-solid fa-code\" style=\"font-size: 24px; color: var(--accent-primary);\"></i>\n      <div>\n        <h3 style=\"margin: 0;\">Developer</h3>\n        <p class=\"muted\" style=\"margin: 0; font-size: 13px;\">Technical reference</p>\n      </div>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/help/' | relative_url }}\" style=\"text-decoration: none; display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;\">\n      <i class=\"fa-solid fa-circle-question\" style=\"font-size: 24px; color: var(--accent-primary);\"></i>\n      <div>\n        <h3 style=\"margin: 0;\">Help</h3>\n        <p class=\"muted\" style=\"margin: 0; font-size: 13px;\">FAQ & troubleshooting</p>\n      </div>\n    </a>\n  </div>\n\n  <h3 style=\"margin-bottom: 16px;\">All Documentation</h3>\n  <div id=\"docs-results\" class=\"grid docs-results-grid\">\n    <!-- Results will be populated by JavaScript -->\n  </div>\n  <div id=\"load-more-container\" style=\"text-align: center; margin-top: 24px; display: none;\">\n    <button id=\"load-more-btn\" class=\"btn primary\" style=\"padding: 12px 32px;\">\n      <i class=\"fa-solid fa-angle-down\"></i>\n      Load More\n    </button>\n  </div>\n</section>\n\n<script>\n  document.addEventListener('DOMContentLoaded', () => {\n    const docs = [\n      {% assign sorted_docs = site.docs | sort: 'nav_order' %}\n      {% for doc in sorted_docs %}\n        {% unless doc.url contains '/category/' %}\n        {\n          title: {{ doc.title | jsonify }},\n          description: {{ doc.description | default: 'No description available' | jsonify }},\n          url: {{ doc.url | relative_url | jsonify }},\n          category: {{ doc.category | default: 'Other' | jsonify }},\n          tags: {{ doc.tags | jsonify }},\n          content: {{ doc.content | strip_html | truncatewords: 20 | jsonify }}\n        }{% unless forloop.last %},{% endunless %}\n        {% endunless %}\n      {% endfor %}\n    ];\n\n    const searchEl = document.getElementById('docs-search');\n    const categoryEl = document.getElementById('docs-category');\n    const resultsEl = document.getElementById('docs-results');\n    const loadMoreBtn = document.getElementById('load-more-btn');\n    const loadMoreContainer = document.getElementById('load-more-container');\n    \n    let currentFiltered = [];\n    let displayCount = 9;\n    let isSearching = false;\n\n    function renderDocs(filtered, count = displayCount) {\n      currentFiltered = filtered;\n      const docsToShow = isSearching ? filtered : filtered.slice(0, count);\n      \n      resultsEl.innerHTML = docsToShow.length \n        ? docsToShow.map(doc => `\n          <div class=\"card\">\n            <h3>${doc.title}</h3>\n            <p class=\"muted\" style=\"font-size: 13px; margin-bottom: 12px;\">${doc.description}</p>\n            <div style=\"display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px;\">\n              <span style=\"display: inline-block; padding: 4px 8px; background: var(--bg-secondary); color: var(--text-secondary); border-radius: 4px; font-size: 12px;\">${doc.category}</span>\n              ${doc.tags.map(tag => `<span style=\"display: inline-block; padding: 4px 8px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 4px; font-size: 12px;\">#${tag}</span>`).join('')}\n            </div>\n            <a class=\"btn primary\" href=\"${doc.url}\" style=\"width: 100%; display: block; text-align: center;\">Read More</a>\n          </div>\n        `).join('')\n        : '<p class=\"muted\" style=\"grid-column: 1 / -1; text-align: center;\">No documentation found.</p>';\n      \n      // Show/hide load more button\n      if (isSearching || filtered.length <= count) {\n        loadMoreContainer.style.display = 'none';\n      } else {\n        loadMoreContainer.style.display = 'block';\n        loadMoreBtn.innerHTML = `<i class=\"fa-solid fa-angle-down\"></i> Load More (${filtered.length - count} remaining)`;\n      }\n    }\n\n    function filterDocs() {\n      const query = searchEl.value.toLowerCase();\n      const category = categoryEl.value;\n      \n      isSearching = !!(query || category);\n\n      const filtered = docs.filter(doc => {\n        const matchesSearch = !query || \n          doc.title.toLowerCase().includes(query) ||\n          doc.description.toLowerCase().includes(query) ||\n          doc.tags.some(tag => tag.toLowerCase().includes(query));\n        \n        const matchesCategory = !category || doc.category === category;\n        \n        return matchesSearch && matchesCategory;\n      });\n\n      displayCount = 9; // Reset display count when filtering\n      renderDocs(filtered);\n    }\n\n    loadMoreBtn.addEventListener('click', () => {\n      displayCount += 9;\n      renderDocs(currentFiltered, displayCount);\n    });\n\n    searchEl.addEventListener('input', filterDocs);\n    categoryEl.addEventListener('change', filterDocs);\n\n    // Initial render\n    renderDocs(docs);\n  });\n</script>\n","{% assign t = site.data[page.lang] %}\n\n<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>{{ t.hero_title }}</h1>\n    <p class=\"muted\">{{ t.hero_subtitle }}</p>\n    <div class=\"cta-row\">\n      <a class=\"btn primary\" href=\"{{ '/projects/' | relative_url }}\">{{ t.browse_projects }}</a>\n      <a class=\"btn ghost\" href=\"{{ '/about/' | relative_url }}\">{{ t.learn_more }}</a>\n    </div>\n  </div>\n</section>\n\n<section id=\"featured\" class=\"section\">\n  <h2>{{ t.featured_title }}</h2>\n  <p class=\"muted\">{{ t.featured_subtitle }}</p>\n  \n  {% if site.data.modpacks and site.data.modpacks.size > 0 %}\n  <div class=\"featured-spotlight\" style=\"margin-bottom: 2rem;\">\n    <div class=\"spotlight-grid\">\n      {% assign sorted_modpacks = site.data.modpacks | sort: 'date_modified' | reverse %}\n      {% for modpack in sorted_modpacks limit:3 %}\n      <div class=\"spotlight-card animate-on-scroll scale-in stagger-{{ forloop.index }}\">\n        <div class=\"spotlight-badge\">\n          <i class=\"fas fa-star\"></i> {{ t.featured_badge }}\n        </div>\n        <div class=\"spotlight-image\" style=\"background-image: url('{{ modpack.icon_url }}')\"></div>\n        <div class=\"spotlight-content\">\n          <h3>{{ modpack.name }}</h3>\n          <p class=\"muted\">{{ modpack.description | truncate: 100 }}</p>\n          <div class=\"spotlight-meta\">\n            <span class=\"meta-item\">\n              <i class=\"fas fa-download\"></i> {{ modpack.downloads | default: 0 | divided_by: 1000 }}K\n            </span>\n            <span class=\"meta-item\">\n              <i class=\"fas fa-heart\"></i> {{ modpack.followers | default: 0 }}\n            </span>\n            {% if modpack.game_versions and modpack.game_versions.size > 0 %}\n            <span class=\"meta-item\">\n              <i class=\"fas fa-gamepad\"></i> {{ modpack.game_versions[0] }}\n            </span>\n            {% endif %}\n          </div>\n          <div class=\"spotlight-actions\">\n            <a href=\"{{ modpack.project_url }}\" class=\"btn-spotlight primary\" target=\"_blank\" rel=\"noopener\">\n              <i class=\"fas fa-external-link-alt\"></i> {{ t.view_project }}\n            </a>\n            {% if modpack.source_url %}\n            <a href=\"{{ modpack.source_url }}\" class=\"btn-spotlight ghost\" target=\"_blank\" rel=\"noopener\">\n              <i class=\"fab fa-github\"></i> {{ t.source }}\n            </a>\n            {% endif %}\n          </div>\n        </div>\n      </div>\n      {% endfor %}\n    </div>\n  </div>\n  {% endif %}\n  \n  {% include modpacks.html %}\n</section>\n\n<section class=\"section\" id=\"project-stats\">\n  <h2>{{ t.stats_title }}</h2>\n  <p class=\"muted\">{{ t.stats_subtitle }}</p>\n  <div class=\"stats-grid\" id=\"stats-grid\">\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_total_projects }}</p>\n      <div class=\"stat-number\" id=\"stat-projects\">—</div>\n      <div class=\"stat-sub\" id=\"stat-projects-sub\">{{ t.stat_loading }}</div>\n    </div>\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_total_downloads }}</p>\n      <div class=\"stat-number\" id=\"stat-downloads\">—</div>\n      <div class=\"stat-sub\" id=\"stat-downloads-sub\">{{ t.stat_loading }}</div>\n    </div>\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_supported_loaders }}</p>\n      <div class=\"stat-number\" id=\"stat-loaders-count\">—</div>\n      <div class=\"stat-sub\" id=\"stat-loaders\">{{ t.stat_loading }}</div>\n    </div>\n    <div class=\"stat-card\">\n      <p class=\"muted\">{{ t.stat_game_versions }}</p>\n      <div class=\"stat-number\" id=\"stat-versions\">—</div>\n      <div class=\"stat-sub\" id=\"stat-versions-sub\">{{ t.stat_loading }}</div>\n    </div>\n  </div>\n  <div class=\"card\" id=\"top-categories\" style=\"margin-top:16px;\">\n    <h3 style=\"margin-top:0\">{{ t.stat_top_categories }}</h3>\n    <div id=\"stat-categories\" class=\"pill-row\">{{ t.stat_loading }}</div>\n  </div>\n  <div class=\"card\" id=\"downloads-card\" style=\"margin-top:16px;\">\n    <h3 style=\"margin-top:0\">{{ t.stat_top_downloads }}</h3>\n    <p class=\"muted\" id=\"stat-downloads-note\">{{ t.stat_downloads_note }}</p>\n    <div class=\"line-chart\" id=\"downloads-chart\"></div>\n  </div>\n</section>\n\n{% assign featured_docs = site.docs | sort: 'nav_order' | slice: 0, 3 %}\n{% if featured_docs and featured_docs.size > 0 %}\n\n<section class=\"section\" id=\"featured-docs\">\n  <h2>Docs Spotlight</h2>\n  <p class=\"muted\">Quick links to key guides</p>\n  <div class=\"grid\">\n    {% for doc in featured_docs %}\n      <a class=\"card\" href=\"{{ doc.url | relative_url }}\" style=\"text-decoration:none\">\n        <h3 style=\"margin-top:0\">{{ doc.title }}</h3>\n        {% if doc.description %}<p class=\"muted\">{{ doc.description }}</p>{% else %}<p class=\"muted\">Read more</p>{% endif %}\n        <span class=\"pill\">Docs</span>\n      </a>\n    {% endfor %}\n  </div>\n</section>\n{% endif %}\n\n<section class=\"section\">\n  <h2>How It Works</h2>\n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-box\"></i> Static Content</h3>\n      <p>All projects are stored as static data. No database needed.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-arrows-rotate\"></i> Auto-Update</h3>\n      <p>Daily syncs from Modrinth keep your showcase fresh.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-bolt\"></i> Lightning Fast</h3>\n      <p>Deployed globally on GitHub Pages for instant loading.</p>\n    </div>\n    <div class=\"card\">\n      <h3><i class=\"fa-solid fa-palette\"></i> Beautiful</h3>\n      <p>Modern design with smooth animations and blur effects.</p>\n    </div>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>Get Started</h2>\n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3>Read the Docs</h3>\n      <p class=\"muted\">Configure branding, fetch projects, and deploy.</p>\n      <a class=\"btn primary\" href=\"{{ '/docs/' | relative_url }}\">Open Docs</a>\n    </div>\n    <div class=\"card\">\n      <h3>Browse Projects</h3>\n      <p class=\"muted\">Filter by type, loader, or version.</p>\n      <a class=\"btn primary\" href=\"{{ '/projects/' | relative_url }}\">View Catalog</a>\n    </div>\n    <div class=\"card\">\n      <h3>Sync from Modrinth</h3>\n      <p class=\"muted\">Run <code>npm run fetch</code> or use the scheduled workflow.</p>\n      <a class=\"btn ghost\" href=\"{{ '/docs/' | relative_url }}\">See Setup</a>\n    </div>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>Stay in the Loop</h2>\n  <div class=\"grid\">\n    <div class=\"card\">\n      <h3>Join Discord</h3>\n      <p class=\"muted\">Get support, share feedback, and see previews.</p>\n      <a class=\"btn ghost\" href=\"{{ site.social.discord }}\" target=\"_blank\" rel=\"noopener\">Open Discord</a>\n    </div>\n    <div class=\"card\">\n      <h3>Watch GitHub</h3>\n      <p class=\"muted\">Track updates, file issues, or contribute.</p>\n      <a class=\"btn ghost\" href=\"{{ site.social.github }}\" target=\"_blank\" rel=\"noopener\">View Repo</a>\n    </div>\n    <div class=\"card\">\n      <h3>Follow Modrinth</h3>\n      <p class=\"muted\">Stay updated on releases across all projects.</p>\n      <a class=\"btn ghost\" href=\"{{ site.modrinth.organization_url | default: site.social.modrinth }}\" target=\"_blank\" rel=\"noopener\">Go to Modrinth</a>\n    </div>\n  </div>\n</section>\n\n<script>\n  // Load stats from cached mods.json and populate snapshot cards\n  document.addEventListener('DOMContentLoaded', async () => {\n    const modsUrl = '{{ '/data/mods.json' | relative_url }}';\n    const statProjects = document.getElementById('stat-projects');\n    const statProjectsSub = document.getElementById('stat-projects-sub');\n    const statDownloads = document.getElementById('stat-downloads');\n    const statDownloadsSub = document.getElementById('stat-downloads-sub');\n    const statLoaders = document.getElementById('stat-loaders');\n    const statLoadersCount = document.getElementById('stat-loaders-count');\n    const statVersions = document.getElementById('stat-versions');\n    const statVersionsSub = document.getElementById('stat-versions-sub');\n    const statCategories = document.getElementById('stat-categories');\n    const downloadsChart = document.getElementById('downloads-chart');\n    const downloadsNote = document.getElementById('stat-downloads-note');\n\n    try {\n      const res = await fetch(modsUrl);\n      if (!res.ok) throw new Error(`HTTP ${res.status}`);\n      const mods = await res.json();\n      if (!Array.isArray(mods) || mods.length === 0) throw new Error('No projects found');\n\n      const loaders = new Set();\n      const versions = new Set();\n      const categories = new Map();\n      let totalDownloads = 0;\n\n      mods.forEach(m => {\n        (m.loaders || []).forEach(l => loaders.add(l));\n        (m.game_versions || []).forEach(v => versions.add(v));\n        totalDownloads += Number(m.downloads || 0);\n        (m.categories || []).forEach(c => {\n          categories.set(c, (categories.get(c) || 0) + 1);\n        });\n        (m.display_categories || []).forEach(c => {\n          categories.set(c, (categories.get(c) || 0) + 1);\n        });\n      });\n\n      const formatNumber = (n) => n.toLocaleString(undefined, { maximumFractionDigits: 0 });\n      \n      const t = {\n        projects_catalog: '{{ t.stat_projects_catalog }}',\n        avg_per_project: '{{ t.stat_avg_per_project }}',\n        unique_versions: '{{ t.stat_unique_versions }}',\n        no_categories: '{{ t.stat_no_categories }}',\n        no_data: '{{ t.stat_no_data }}',\n        unavailable: '{{ t.stat_unavailable }}'\n      };\n\n      statProjects.textContent = formatNumber(mods.length);\n      statProjectsSub.textContent = t.projects_catalog;\n\n      statDownloads.textContent = formatNumber(totalDownloads);\n      const avgDownloads = mods.length ? Math.round(totalDownloads / mods.length) : 0;\n      statDownloadsSub.textContent = `${formatNumber(avgDownloads)} ${t.avg_per_project}`;\n\n      const loaderList = Array.from(loaders).sort();\n      const versionCount = versions.size;\n\n      statLoadersCount.textContent = loaderList.length ? formatNumber(loaderList.length) : '—';\n      statLoaders.textContent = loaderList.length ? loaderList.join(', ') : '—';\n      statVersions.textContent = versionCount ? formatNumber(versionCount) : '—';\n      statVersionsSub.textContent = versionCount ? t.unique_versions : '—';\n\n      const topCats = Array.from(categories.entries())\n        .sort((a, b) => b[1] - a[1])\n        .slice(0, 6)\n        .map(([c, count]) => `<span class=\"pill\">${c} (${count})</span>`) || [];\n      statCategories.innerHTML = topCats.length ? topCats.join(' ') : t.no_categories;\n\n      // Top downloads multi-line chart (simulated week data)\n      const topDownloads = [...mods]\n        .filter(m => typeof m.downloads === 'number')\n        .sort((a, b) => (b.downloads || 0) - (a.downloads || 0))\n        .slice(0, 11);\n\n      if (topDownloads.length && downloadsChart) {\n        downloadsChart.innerHTML = '';\n        \n        const colors = [\n          '#1bd96f', '#10a8e0', '#22d3ee', '#a78bfa', '#f472b6',\n          '#fb923c', '#fbbf24', '#4ade80', '#60a5fa', '#c084fc', '#f87171'\n        ];\n\n        // Simulate week data with realistic curves (7 days)\n        const days = 7;\n        const maxValue = Math.max(...topDownloads.map(m => m.downloads || 0));\n        \n        const chartWrapper = document.createElement('div');\n        chartWrapper.style.cssText = 'display:flex;gap:20px;align-items:stretch;margin-bottom:12px;';\n\n        // Left side: chart\n        const chartContainer = document.createElement('div');\n        chartContainer.style.cssText = 'flex:1;background:var(--bg-primary);border:1px solid var(--border);padding:16px;box-sizing:border-box;position:relative;';\n\n        const svgWrapper = document.createElement('div');\n        svgWrapper.style.cssText = 'width:100%;height:240px;position:relative;';\n        \n        // Tooltip\n        const tooltip = document.createElement('div');\n        tooltip.style.cssText = 'position:absolute;background:rgba(0,0,0,0.8);color:white;border:1px solid var(--border);padding:8px 12px;border-radius:6px;font-size:12px;pointer-events:none;opacity:0;transition:opacity 0.2s;z-index:10;white-space:nowrap;box-shadow:0 4px 12px rgba(0,0,0,0.4);';\n        chartContainer.appendChild(tooltip);\n\n        // Use actual pixel dimensions\n        const width = 800;  // Fixed width for consistent rendering\n        const height = 200; // Fixed height\n\n        const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n        svg.setAttribute('viewBox', `0 0 ${width} ${height}`);\n        svg.setAttribute('preserveAspectRatio', 'none');\n        svg.style.cssText = 'width:100%;height:100%;display:block;';\n\n        topDownloads.forEach((mod, idx) => {\n          const color = colors[idx % colors.length];\n          const baseValue = mod.downloads || 0;\n          \n          // Generate smooth curve with variation\n          const points = [];\n          \n          for (let day = 0; day < days; day++) {\n            const x = (day / (days - 1)) * width;\n            const variance = Math.sin(day * 0.8 + idx) * 0.3 + Math.cos(day * 1.2 - idx) * 0.2;\n            const normalizedValue = (baseValue / maxValue) * (0.4 + variance * 0.6);\n            const y = height - Math.max(4, Math.min(height - 4, normalizedValue * (height * 0.9)));\n            const simulatedDownloads = Math.round(baseValue * normalizedValue);\n            points.push({ x, y, downloads: simulatedDownloads, day });\n          }\n\n          const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n          const d = points.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x} ${p.y}`).join(' ');\n          path.setAttribute('d', d);\n          path.setAttribute('fill', 'none');\n          path.setAttribute('stroke', color);\n          path.setAttribute('stroke-width', '2');\n          path.setAttribute('opacity', '0.85');\n          path.style.cursor = 'pointer';\n          \n          // Add dots at each data point\n          points.forEach(p => {\n            const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n            circle.setAttribute('cx', p.x);\n            circle.setAttribute('cy', p.y);\n            circle.setAttribute('r', '4.5');\n            circle.setAttribute('fill', color);\n            circle.setAttribute('opacity', '0.9');\n            circle.style.cursor = 'pointer';\n            svg.appendChild(circle);\n          });\n          \n          // Hover effect\n          path.addEventListener('mouseenter', () => {\n            path.setAttribute('stroke-width', '3');\n            path.setAttribute('opacity', '1');\n          });\n          path.addEventListener('mouseleave', () => {\n            path.setAttribute('stroke-width', '2');\n            path.setAttribute('opacity', '0.85');\n            tooltip.style.opacity = '0';\n          });\n          path.addEventListener('mousemove', (e) => {\n            const rect = chartContainer.getBoundingClientRect();\n            const svgRect = svg.getBoundingClientRect();\n            const relX = ((e.clientX - svgRect.left) / svgRect.width) * width;\n            const closestPoint = points.reduce((prev, curr) => \n              Math.abs(curr.x - relX) < Math.abs(prev.x - relX) ? curr : prev\n            );\n            \n            tooltip.innerHTML = `<div style=\"color:${color};font-weight:600;margin-bottom:2px;\">${mod.title || mod.name}</div><div>Day ${closestPoint.day + 1}: ${formatNumber(closestPoint.downloads)} downloads</div>`;\n            tooltip.style.opacity = '1';\n            tooltip.style.left = Math.min(rect.width - tooltip.offsetWidth - 10, Math.max(10, e.clientX - rect.left + 10)) + 'px';\n            tooltip.style.top = Math.max(10, e.clientY - rect.top - 40) + 'px';\n          });\n          \n          svg.appendChild(path);\n        });\n\n        svgWrapper.appendChild(svg);\n        chartContainer.appendChild(svgWrapper);\n\n        // Right side: legend\n        const legendContainer = document.createElement('div');\n        legendContainer.style.cssText = 'width:200px;display:flex;flex-direction:column;gap:8px;overflow-y:auto;max-height:240px;padding-right:8px;';\n        legendContainer.className = 'line-legend';\n        legendContainer.innerHTML = topDownloads.map((m, idx) => {\n          const color = colors[idx % colors.length];\n          return `<div class=\"legend-item\" style=\"display:flex;align-items:center;gap:8px;font-size:13px;color:var(--text-secondary);\"><span style=\"width:8px;height:8px;border-radius:50%;background:${color};display:inline-block;flex-shrink:0;\"></span><span style=\"overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\">${m.title || m.name}</span></div>`;\n        }).join('');\n\n        chartWrapper.appendChild(chartContainer);\n        chartWrapper.appendChild(legendContainer);\n        downloadsChart.appendChild(chartWrapper);\n      } else if (downloadsNote) {\n        downloadsNote.textContent = t.no_data;\n      }\n    } catch (e) {\n      statProjects.textContent = '—';\n      statProjectsSub.textContent = t.unavailable;\n      statDownloads.textContent = '—';\n      statDownloadsSub.textContent = t.unavailable;\n      statLoadersCount.textContent = '—';\n      statLoaders.textContent = t.unavailable;\n      statVersions.textContent = '—';\n      statVersionsSub.textContent = t.unavailable;\n      statCategories.textContent = `{{ t.error_loading }} ${e.message}`;\n      if (downloadsNote) downloadsNote.textContent = `{{ t.error_loading }}`;\n      console.warn('{{ t.failed_to_load }}:', e);\n    }\n  });\n</script>\n","# Licensing & Attribution\n\n**Last Updated:** December 2024\n\nThis page outlines the licenses used across our projects and how to properly attribute them.\n\n## Project Licenses\n\n| Project       | License   | Repository | Key Terms                           |\n| ------------- | --------- | ---------- | ----------------------------------- |\n| Core Projects | MIT       | GitHub     | Permissive; attribution appreciated |\n| Datapacks     | CC0 / MIT | GitHub     | Check individual README             |\n| Plugins       | MIT       | GitHub     | Permissive; include license         |\n| Documentation | CC-BY-4.0 | This Site  | Attribute ABC Team                  |\n\n## MIT License Summary\n\n**Permissions**:\n\n- ✅ Commercial use\n- ✅ Modification\n- ✅ Distribution\n- ✅ Private use\n\n**Conditions**:\n\n- ⚠️ Include license and copyright notice\n- ⚠️ Disclose changes\n\n**Limitations**:\n\n- ❌ No liability\n- ❌ No warranty\n\n## Creative Commons (CC-BY-4.0)\n\nUsed for documentation and educational content.\n\n**You are free to**:\n\n- Share the material\n- Adapt and remix\n- Use commercially\n\n**You must**:\n\n- Give appropriate credit\n- Provide a link to the license\n- Indicate if changes were made\n\n## How to Attribute\n\n### For Code\n\n```\nBased on ABC Team's [Project Name]\nLicense: MIT\nSource: https://github.com/devvyyxyz/[repo]\n```\n\n### For Documentation\n\n```\nContent adapted from ABC Team\nLicense: CC-BY-4.0\nSource: [abc-site-url]\n```\n\n### For Derivative Projects\n\nIf you create a modified version:\n\n1. Include the original license file\n2. Add a notice of modifications\n3. State the original source\n4. Link to our GitHub\n\nExample:\n\n```\nThis project is based on ABC Team's [Original Project]\nOriginal License: MIT\nOriginal Source: https://github.com/devvyyxyz/[repo]\nModifications: [describe changes]\n```\n\n## Third-Party Dependencies\n\nOur projects use open-source libraries. See `LICENSE` and `LICENSES/` directories in each repository for full details.\n\n### Common Dependencies\n\n| Dependency | License    | Link                                                       |\n| ---------- | ---------- | ---------------------------------------------------------- |\n| Fabric API | Apache 2.0 | [GitHub](https://github.com/FabricMC/fabric)               |\n| Forge      | LGPL 2.1   | [GitHub](https://github.com/MinecraftForge/MinecraftForge) |\n| Quilt      | Apache 2.0 | [GitHub](https://github.com/QuiltMC)                       |\n\n## Minecraft & Mojang\n\nOur projects are designed for Minecraft and follow Mojang's Brand and Asset Guidelines:\n\n- Minecraft is owned by Mojang Studios / Microsoft\n- Our projects are independent community mods\n- We do not sell Minecraft or charge for access\n- See [Minecraft EULA](https://account.mojang.com/terms)\n\n## Using Our Projects Commercially\n\n**Yes, you can use our projects commercially!**\n\n**Requirements**:\n\n1. Include the MIT license file\n2. Attribute ABC Team in credits or documentation\n3. Disclose if you modified the software\n4. Provide source code access (for MIT)\n\n**Server Usage**:\n\n- Personal servers: Fully permitted\n- Public servers: Permitted with attribution\n- Paid servers: Permitted (no revenue share)\n\n**Content Creation**:\n\n- YouTube/Twitch: Fully permitted (no permission needed)\n- Monetization: Fully permitted (no revenue share)\n- Attribution appreciated but not required\n\n## Questions About Licensing\n\n- **Can I sell modifications?** No. Modified versions must remain free.\n- **Can I bundle your code?** Yes, if you include the license.\n- **Can I relicense your code?** Only under compatible licenses (MIT to Apache 2.0, etc.).\n- **Can I use your code in closed-source?** No. MIT requires source disclosure or available code.\n\n## Dispute Resolution\n\nIf you believe our projects infringe on your intellectual property, please contact us:\n\n**Email**: [contact from config]  \n**GitHub Issues**: [Repository link]\n\nWe will respond within 7 days to address concerns.\n\n---\n\n**Our Mission**: Create amazing, free, open-source mods and tools for the Minecraft community.\n\nFor the full legal text of each license, see the `LICENSE` file in each repository.\n","<section class=\"section\">\n  <h1>Privacy Policy</h1>\n  <p class=\"muted\">How we collect, use, and protect information on this site.</p>\n\n  <h2>What we collect</h2>\n  <ul>\n    <li>No account data is collected by this static site.</li>\n    <li>Server logs (via hosting) may include IP address, user-agent, and request metadata for basic operations and security.</li>\n    <li>If you submit feedback (e.g., the docs widget), it is stored locally in your browser only.</li>\n  </ul>\n\n  <h2>Cookies & storage</h2>\n  <ul>\n    <li>Theme and feedback choices are stored in <code>localStorage</code> for your convenience.</li>\n    <li>No tracking or advertising cookies are set by this site.</li>\n  </ul>\n\n  <h2>Third-party links</h2>\n  <p>Links to Modrinth, GitHub, and Discord follow their respective privacy policies.</p>\n\n  <h2>Contact</h2>\n  <p>Questions or removal requests? <a href=\"{{ '/contact/' | relative_url }}\">Contact us</a>.</p>\n</section>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Browse All Projects</h1>\n    <p class=\"muted\">Explore our curated collection of mods, resource packs, datapacks, modpacks, and plugins.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h1>Projects</h1>\n  <p class=\"muted\">Latest projects from ABC organization</p>\n\n  <div class=\"filters\" id=\"projects-filters\">\n    <input id=\"filter-search\" type=\"search\" placeholder=\"Search projects...\" aria-label=\"Search projects\">\n    <select id=\"filter-type\" aria-label=\"Filter by type\">\n      <option value=\"all\">All types</option>\n    </select>\n    <select id=\"filter-loader\" aria-label=\"Filter by loader\">\n      <option value=\"all\">All loaders</option>\n    </select>\n    <select id=\"filter-version\" aria-label=\"Filter by version\">\n      <option value=\"all\">All versions</option>\n    </select>\n  </div>\n\n  <div id=\"projects-count\" class=\"muted\" style=\"margin-top:10px\"></div>\n  <div id=\"mods-list\" class=\"modpacks-list\"></div>\n</section>\n\n<script>\n  // Load projects from cached JSON file with filtering and rich metadata\n  document.addEventListener('DOMContentLoaded', async () => {\n    const container = document.getElementById('mods-list');\n    const countEl = document.getElementById('projects-count');\n    const searchEl = document.getElementById('filter-search');\n    const typeEl = document.getElementById('filter-type');\n    const loaderEl = document.getElementById('filter-loader');\n    const versionEl = document.getElementById('filter-version');\n\n    const state = {\n      projects: [],\n      filters: { search: '', type: 'all', loader: 'all', version: 'all' }\n    };\n\n    // Base options so filters always have choices even if data is missing them\n    const baseTypes = ['mod', 'modpack', 'datapack', 'resourcepack', 'plugin', 'shader', 'world', 'library'];\n    const baseLoaders = ['fabric', 'forge', 'quilt', 'neoforge', 'liteloader', 'rift', 'bukkit', 'paper', 'purpur', 'datapack', 'minecraft', 'resourcepack', 'shaders'];\n    const baseVersions = ['1.16', '1.16.5', '1.17.1', '1.18.2', '1.19.4', '1.20', '1.20.1', '1.20.2', '1.20.4', '1.20.6', '1.21', '1.21.1', '1.21.2', '1.21.3', '1.21.4', '1.21.5'];\n\n    function formatDate(value) {\n      if (!value) return 'Unknown';\n      const d = new Date(value);\n      if (Number.isNaN(d.getTime())) return 'Unknown';\n      return d.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\n    }\n\n    function populateFilters(items) {\n      const types = new Set(baseTypes);\n      const loaders = new Set(baseLoaders);\n      const versions = new Set(baseVersions);\n\n      items.forEach(p => {\n        if (p.project_type) types.add(p.project_type);\n        (p.loaders || []).forEach(l => loaders.add(l));\n        (p.game_versions || []).forEach(v => versions.add(v));\n      });\n\n      typeEl.innerHTML = '<option value=\"all\">All types</option>' +\n        Array.from(types).sort().map(t => `<option value=\"${t}\">${t}</option>`).join('');\n      loaderEl.innerHTML = '<option value=\"all\">All loaders</option>' +\n        Array.from(loaders).sort().map(l => `<option value=\"${l}\">${l}</option>`).join('');\n      versionEl.innerHTML = '<option value=\"all\">All versions</option>' +\n        Array.from(versions).sort((a, b) => a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' })).map(v => `<option value=\"${v}\">${v}</option>`).join('');\n    }\n\n    function applyFilters() {\n      let items = [...state.projects];\n      const { search, type, loader, version } = state.filters;\n\n      if (search) {\n        const q = search.toLowerCase();\n        items = items.filter(p => (\n          (p.title || p.name || '').toLowerCase().includes(q) ||\n          (p.short_description || '').toLowerCase().includes(q)\n        ));\n      }\n\n      if (type !== 'all') {\n        items = items.filter(p => (p.project_type || p.type) === type);\n      }\n\n      if (loader !== 'all') {\n        items = items.filter(p => (p.loaders || []).includes(loader));\n      }\n\n      if (version !== 'all') {\n        items = items.filter(p => (p.game_versions || []).includes(version));\n      }\n\n      renderProjects(items);\n    }\n\n    function renderProjects(items) {\n      if (!items.length) {\n        container.innerHTML = '<p class=\"muted\">No projects found for this filter.</p>';\n        countEl.textContent = '0 projects';\n        return;\n      }\n\n      container.innerHTML = '';\n      countEl.textContent = `${items.length} project${items.length === 1 ? '' : 's'}`;\n\n      items.forEach((m, i) => {\n        const el = document.createElement('div');\n        el.className = 'modpack';\n        el.style.animationDelay = (i * 60) + 'ms';\n\n        // Generate project slug for detail page link\n        const slug = (m.slug || m.title.toLowerCase().replace(/\\s+/g, '-').replace(/[^a-z0-9-]/g, ''));\n        const detailPageUrl = `/abc-site/projects/${slug}/`;\n\n        const thumb = document.createElement('div');\n        thumb.className = 'thumb';\n        thumb.style.backgroundImage = `url(${m.icon_url || m.thumbnail || '/assets/images/favicon.svg'})`;\n        thumb.style.cursor = 'pointer';\n        thumb.addEventListener('click', () => window.location.href = detailPageUrl);\n\n        const meta = document.createElement('div');\n        meta.className = 'meta';\n        meta.style.cursor = 'pointer';\n        meta.addEventListener('click', () => window.location.href = detailPageUrl);\n        const shortDesc = m.short_description || m.summary || m.description || '';\n        const desc = shortDesc.length > 160 ? `${shortDesc.substring(0, 160)}...` : shortDesc;\n        const versions = (m.game_versions || []).slice(-3).reverse();\n        const loaders = (m.loaders || []).slice(0, 3);\n\n        const pill = (label, icon) => `<span class=\"pill\">${icon ? `<i class=\"fa-solid fa-${icon}\"></i>` : ''}${label}</span>`;\n        const metaInfo = [\n          m.updated || m.published ? pill(`Updated ${formatDate(m.updated || m.published)}`, 'clock') : '',\n          versions.length ? pill(`MC ${versions.join(', ')}`, 'cube') : '',\n          loaders.length ? pill(`Loaders: ${loaders.join(', ')}`, 'cogs') : '',\n          m.license_id ? pill(`License: ${m.license_id}`, 'file-alt') : ''\n        ].filter(Boolean).join('');\n\n        meta.innerHTML = `\n          <h3>${m.title || m.name}</h3>\n          <p>${desc}</p>\n        `;\n\n        const pillSection = document.createElement('div');\n        pillSection.className = 'pill-section';\n        const metaInfoHTML = [\n          m.updated || m.published ? pill(`Updated ${formatDate(m.updated || m.published)}`, 'clock') : '',\n          versions.length ? pill(`MC ${versions.join(', ')}`, 'cube') : '',\n          loaders.length ? pill(`Loaders: ${loaders.join(', ')}`, 'cogs') : '',\n          m.license_id ? pill(`License: ${m.license_id}`, 'file-alt') : ''\n        ].filter(Boolean).join('');\n        \n        const categoriesHTML = (m.display_categories || m.categories || []).slice(0, 4).map(c => `<span class=\"pill\">#${c}</span>`).join(' ');\n        \n        pillSection.innerHTML = `${metaInfoHTML} ${categoriesHTML}`;\n\n        const action = document.createElement('div');\n        action.className = 'actions';\n        \n        // Check if source_url exists (GitHub link)\n        const sourceUrl = m.source_url || m.repository;\n        \n        let buttonsHTML = '';\n        buttonsHTML += `<a class=\"btn primary\" href=\"${detailPageUrl}\" title=\"View details\">Details</a>`;\n        if (sourceUrl) {\n          buttonsHTML += `<a class=\"btn secondary\" href=\"${sourceUrl}\" target=\"_blank\" rel=\"noopener\" title=\"View source\"><i class=\"fa-brands fa-github\"></i></a>`;\n        }\n        buttonsHTML += `<a class=\"btn ghost\" href=\"${m.download || `https://modrinth.com/mod/${m.slug}`}\" target=\"_blank\" rel=\"noopener\">View</a>`;\n        \n        action.innerHTML = buttonsHTML;\n\n        el.appendChild(thumb);\n        el.appendChild(meta);\n        el.appendChild(pillSection);\n        el.appendChild(action);\n        container.appendChild(el);\n      });\n    }\n\n    function handleFilterChange() {\n      state.filters = {\n        search: searchEl.value.trim(),\n        type: typeEl.value,\n        loader: loaderEl.value,\n        version: versionEl.value\n      };\n      applyFilters();\n    }\n\n    // Wire up filters\n    searchEl.addEventListener('input', () => {\n      state.filters.search = searchEl.value.trim();\n      applyFilters();\n    });\n    [typeEl, loaderEl, versionEl].forEach(el => el.addEventListener('change', handleFilterChange));\n\n    try {\n      const res = await fetch('{{ '/data/mods.json' | relative_url }}');\n      if (!res.ok) throw new Error(`HTTP ${res.status}: Failed to load projects`);\n      const projects = await res.json();\n\n      if (!Array.isArray(projects) || projects.length === 0) {\n        container.innerHTML = '<p class=\"muted\">No projects found. Projects will be synced automatically.</p>';\n        return;\n      }\n\n      // Sort newest updated first\n      state.projects = projects.sort((a, b) => new Date(b.updated || b.published || 0) - new Date(a.updated || a.published || 0));\n      populateFilters(state.projects);\n      applyFilters();\n    } catch (e) {\n      console.error('Failed to load projects:', e);\n      container.innerHTML = `<p class=\"muted\">Error: ${e.message}</p>`;\n    }\n  });\n</script>\n","<section class=\"hero\">\n  <div class=\"hero-card\">\n    <h1>Documentation Overview</h1>\n    <p class=\"muted\">Complete reference of all available guides and resources.</p>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>📚 All Documentation Pages</h2>\n\n  <h3>Setup & Configuration (2 pages)</h3>\n  <ul style=\"list-style: none; padding: 0;\">\n    <li><strong><a href=\"{{ '/docs/getting-started/' | relative_url }}\">Getting Started</a></strong> — Quick start guide for new users</li>\n    <li><strong><a href=\"{{ '/docs/setup/' | relative_url }}\">Setup & Configuration</a></strong> — Detailed setup and Modrinth integration instructions</li>\n  </ul>\n\n  <h3>Styling & Customization (1 page)</h3>\n  <ul style=\"list-style: none; padding: 0;\">\n    <li><strong><a href=\"{{ '/docs/customization/' | relative_url }}\">Customization</a></strong> — Theming, colors, and CSS customization</li>\n  </ul>\n\n  <h3>Community & Contributing (1 page)</h3>\n  <ul style=\"list-style: none; padding: 0;\">\n    <li><strong><a href=\"{{ '/docs/contributing/' | relative_url }}\">Contributing</a></strong> — Guidelines for contributors and pull requests</li>\n  </ul>\n\n  <h3>Help & Troubleshooting (2 pages)</h3>\n  <ul style=\"list-style: none; padding: 0;\">\n    <li><strong><a href=\"{{ '/docs/faq/' | relative_url }}\">FAQ</a></strong> — Frequently asked questions</li>\n    <li><strong><a href=\"{{ '/docs/troubleshooting/' | relative_url }}\">Troubleshooting</a></strong> — Common issues and solutions</li>\n  </ul>\n\n  <h3>User Guide (1 page)</h3>\n  <ul style=\"list-style: none; padding: 0;\">\n    <li><strong><a href=\"{{ '/docs/how-to-install/' | relative_url }}\">How to Install</a></strong> — Step-by-step installation guide</li>\n  </ul>\n\n  <h3>Developer Resources (3 pages)</h3>\n  <ul style=\"list-style: none; padding: 0;\">\n    <li><strong><a href=\"{{ '/docs/api-reference/' | relative_url }}\">API Reference</a></strong> — Project data structure and Modrinth API</li>\n    <li><strong><a href=\"{{ '/docs/project-structure/' | relative_url }}\">Project Structure</a></strong> — File organization and architecture</li>\n    <li><strong><a href=\"{{ '/docs/troubleshooting/' | relative_url }}\">Troubleshooting</a></strong> — Debugging and common errors</li>\n  </ul>\n\n</section>\n\n<section class=\"section\">\n  <h2>🏷️ Tag Cloud</h2>\n  <div style=\"display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 24px;\">\n    {% assign all_tags = site.docs | map: \"tags\" | join: \",\" | default: \"\" | split: \",\" | uniq | sort %}\n    {% for tag in all_tags %}\n      {% if tag != \"\" %}\n        <span style=\"display: inline-block; padding: 6px 12px; background: rgba(27, 217, 111, 0.1); color: var(--accent-primary); border-radius: 999px; border: 1px solid var(--accent-primary); font-size: 13px; cursor: pointer;\" onclick=\"document.location.href='{{ '/docs/' | relative_url }}?filter={{ tag }}'\">\n          #{{ tag }}\n        </span>\n      {% endif %}\n    {% endfor %}\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>📂 Browse by Category</h2>\n  <div class=\"grid\" style=\"grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px;\">\n    <a class=\"card\" href=\"{{ '/docs/category/setup/' | relative_url }}\" style=\"text-decoration: none;\">\n      <h3>⚙️ Setup</h3>\n      <p class=\"muted\">Installation and configuration guides</p>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/styling/' | relative_url }}\" style=\"text-decoration: none;\">\n      <h3>🎨 Styling</h3>\n      <p class=\"muted\">Theming and customization</p>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/user-guide/' | relative_url }}\" style=\"text-decoration: none;\">\n      <h3>📖 User Guide</h3>\n      <p class=\"muted\">For end users and managers</p>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/community/' | relative_url }}\" style=\"text-decoration: none;\">\n      <h3>🤝 Community</h3>\n      <p class=\"muted\">Contributing and support</p>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/developer/' | relative_url }}\" style=\"text-decoration: none;\">\n      <h3>💻 Developer</h3>\n      <p class=\"muted\">Technical reference</p>\n    </a>\n    <a class=\"card\" href=\"{{ '/docs/category/help/' | relative_url }}\" style=\"text-decoration: none;\">\n      <h3>❓ Help</h3>\n      <p class=\"muted\">FAQ and troubleshooting</p>\n    </a>\n  </div>\n</section>\n\n<section class=\"section\">\n  <h2>🔍 Quick Search</h2>\n  <p class=\"muted\">Use the <a href=\"{{ '/docs/' | relative_url }}\">main documentation page</a> to search and filter all guides by keyword or category.</p>\n</section>\n","<section class=\"section\">\n  <h1>Terms of Use</h1>\n  <p class=\"muted\">Guidelines for using this site and its content.</p>\n\n  <h2>Content</h2>\n  <ul>\n    <li>Downloads link to Modrinth or other platforms; their licenses govern use.</li>\n    <li>Site content is provided \"as is\" without warranties.</li>\n  </ul>\n\n  <h2>Acceptable use</h2>\n  <ul>\n    <li>Do not misuse the site, attempt to break security, or scrape abusively.</li>\n    <li>Respect the licenses of each mod, pack, or resource.</li>\n  </ul>\n\n  <h2>Attribution</h2>\n  <p>Credit the project authors as listed on their respective pages and licenses.</p>\n\n  <h2>Contact</h2>\n  <p>Questions? <a href=\"{{ '/contact/' | relative_url }}\">Contact us</a>.</p>\n</section>\n","# Testing & Validation Checklist\n\n## 1. Polish & Preloader Testing\n\n### Preloader Functionality\n- [ ] Preloader appears on page load\n- [ ] Preloader spinner animates smoothly\n- [ ] Preloader hides after page content loads\n- [ ] No content visible behind preloader during load\n\n### Responsive Scaling\n- [ ] Hero section scales properly on mobile (320px)\n- [ ] Navigation responsive at tablet (768px) and desktop (1200px)\n- [ ] Typography scales fluidly using clamp()\n- [ ] Grid gaps adjust based on viewport width\n- [ ] Buttons and cards maintain proper spacing on all screens\n\n### Cross-browser Testing\n- [ ] Chrome/Chromium: Full functionality\n- [ ] Firefox: Full functionality\n- [ ] Safari: Full functionality\n- [ ] Mobile Safari: Responsive and preloader works\n- [ ] Edge: Full functionality\n\n---\n\n## 2. Theme Toggle & Animations\n\n### Dark/Light Mode Toggle\n- [ ] Toggle button appears in nav\n- [ ] Dark mode applies correct CSS variables\n- [ ] Light mode applies correct CSS variables\n- [ ] Theme preference persists in localStorage\n- [ ] System preference detected on first visit\n- [ ] Respects prefers-color-scheme\n- [ ] Both themes have sufficient contrast\n\n### Enhanced Animations\n- [ ] Card entries animate on page load\n- [ ] Stat cards stagger animation works\n- [ ] Button ripple effect on click\n- [ ] Smooth scroll behavior enabled\n- [ ] Page transitions fade smoothly\n- [ ] Focus states visible and animated\n\n---\n\n## 3. Performance Optimization\n\n### Lazy Loading\n- [ ] Images load only when scrolled into view\n- [ ] Fallback works for older browsers\n- [ ] Performance impact measured\n\n### Resource Optimization\n- [ ] Critical CSS inlined in head\n- [ ] Non-critical CSS deferred\n- [ ] JavaScript split and loaded asynchronously\n- [ ] Unused styles removed\n- [ ] Images optimized and compressed\n\n### Scroll to Top Button\n- [ ] Button appears after scrolling 300px down\n- [ ] Button scrolls page smoothly to top\n- [ ] Button disappears when at top\n- [ ] Keyboard accessible (Enter/Space)\n\n---\n\n## 4. SEO & Content Structure\n\n### Sitemap & Robots\n- [ ] sitemap.xml generates correctly\n- [ ] robots.txt blocks aggressive crawlers\n- [ ] Canonical URLs set on all pages\n- [ ] Meta descriptions present\n\n### Schema Markup\n- [ ] Organization schema correct\n- [ ] Breadcrumb schema renders properly\n- [ ] Article/Page schema includes date\n- [ ] Schema validates with Google SDTT\n\n### Heading Hierarchy\n- [ ] H1 only appears once per page\n- [ ] Heading levels flow logically\n- [ ] Headings use semantic HTML\n\n---\n\n## 5. Accessibility (a11y)\n\n### WCAG 2.1 Compliance\n- [ ] Color contrast meets AA standard (4.5:1 for text)\n- [ ] All buttons and links keyboard accessible\n- [ ] Focus states visible\n- [ ] Skip to main content link works\n\n### Keyboard Navigation\n- [ ] Tab through all interactive elements\n- [ ] Enter/Space activates buttons\n- [ ] Escape closes modals\n- [ ] Focus order logical\n\n### Screen Reader Testing\n- [ ] Page structure announced properly\n- [ ] Images have alt text or are decorative (role=\"presentation\")\n- [ ] Form labels associated with inputs\n- [ ] ARIA labels on icon-only buttons\n- [ ] Live regions for dynamic content\n\n### Responsive Text\n- [ ] Text resizes with browser zoom (150%)\n- [ ] No horizontal scroll at 200% zoom\n- [ ] Text remains readable\n\n### Motion & Animation\n- [ ] Animations respect prefers-reduced-motion\n- [ ] Critical content not animation-dependent\n- [ ] No auto-playing media\n\n---\n\n## 6. Mobile & Touch Testing\n\n### Touch Targets\n- [ ] All buttons minimum 44x44px\n- [ ] Touch targets have adequate spacing\n- [ ] No accidental click overlap\n\n### Viewport Testing\n- [ ] Mobile (320px, 375px, 414px)\n- [ ] Tablet (768px, 1024px)\n- [ ] Desktop (1440px, 1920px, 4K)\n\n### Performance on Mobile\n- [ ] Page loads in < 3s on 4G\n- [ ] Preloader doesn't block interaction\n- [ ] Navigation doesn't cover content\n\n---\n\n## Performance Metrics\n\n### Core Web Vitals\n- [ ] LCP (Largest Contentful Paint): < 2.5s\n- [ ] FID (First Input Delay): < 100ms\n- [ ] CLS (Cumulative Layout Shift): < 0.1\n\n### Additional Metrics\n- [ ] First Contentful Paint: < 1.8s\n- [ ] Time to Interactive: < 3.8s\n- [ ] Total Blocking Time: < 200ms\n\n### Lighthouse Score\n- [ ] Performance: > 90\n- [ ] Accessibility: > 95\n- [ ] Best Practices: > 90\n- [ ] SEO: > 95\n\n---\n\n## Testing Tools\n\n### Online Tools\n- [Google PageSpeed Insights](https://pagespeed.web.dev/)\n- [Google Mobile-Friendly Test](https://search.google.com/test/mobile-friendly)\n- [Schema.org Structured Data Tester](https://validator.schema.org/)\n- [WAVE Accessibility Checker](https://wave.webaim.org/)\n- [Lighthouse CI](https://github.com/GoogleChrome/lighthouse-ci)\n\n### Browser DevTools\n- Chrome DevTools Lighthouse\n- Firefox Accessibility Inspector\n- Safari Accessibility Inspector\n\n---\n\n## Sign-off\n\n- [ ] All tests passed\n- [ ] No critical issues\n- [ ] Accessibility approved\n- [ ] Performance validated\n- [ ] SEO optimized\n- [ ] Ready for production\n\n**Date Tested:** _______________  \n**Tested By:** _______________  \n**Approved By:** _______________\n"],"collections":[{"label":"docs","docs":["<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"dark\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>\n      Accessibility Guide | Minecraft Mods & Packs Showcase\n    </title>\n\n    <!-- Stylesheets -->\n    <link rel=\"stylesheet\" href=\"/assets/css/main.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/layout.css\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/modpacks.css\"\n    />\n    <link rel=\"stylesheet\" href=\"/assets/css/docs.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n    />\n\n    <script>\n      if (!document.body) {\n        console.warn(\"Body not ready, skipping preloader\");\n      } else {\n        window.addEventListener(\"load\", () => {\n          document.body.classList.add(\"loaded\");\n        });\n      }\n\n      const savedTheme = localStorage.getItem(\"theme\") || \"dark\";\n      document.documentElement.setAttribute(\"data-theme\", savedTheme);\n    </script>\n  </head>\n  <body>\n    <!-- Preloader -->\n    <div class=\"preloader\">\n      <div class=\"spinner\"></div>\n    </div>\n\n    <!-- Mobile Menu Toggle -->\n    <button\n      id=\"mobile-sidebar-toggle\"\n      class=\"mobile-sidebar-toggle\"\n      aria-label=\"Toggle sidebar\"\n    >\n      <i class=\"fa-solid fa-bars\"></i>\n    </button>\n\n    <!-- Docs Sidebar -->\n    <aside id=\"docs-sidebar\" class=\"docs-sidebar\">\n      <div class=\"sidebar-header\">\n        <a href=\"/\" class=\"sidebar-logo\">\n          <i class=\"fa-solid fa-cube\"></i>\n          <span>Minecraft Mods & Packs Showcase</span>\n        </a>\n        <button\n          id=\"sidebar-close\"\n          class=\"sidebar-close\"\n          aria-label=\"Close sidebar\"\n        >\n          <i class=\"fa-solid fa-times\"></i>\n        </button>\n      </div>\n\n      <!-- Search in Sidebar -->\n      <div class=\"sidebar-search\">\n        <input\n          type=\"search\"\n          id=\"sidebar-search\"\n          placeholder=\"Search docs...\"\n          aria-label=\"Search documentation\"\n        />\n        <i class=\"fa-solid fa-search\"></i>\n      </div>\n\n      <!-- Navigation Tree -->\n      <nav class=\"sidebar-nav\">\n            \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"setup\"\n          >\n            <i\n              class=\"fa-solid fa-gear \"\n            ></i>\n            <span>Setup</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-setup\"\n          >\n            \n             \n            <a\n              href=\"/docs/getting-started/\"\n              class=\"nav-item \"\n            >\n              Getting Started\n            </a>\n              \n            <a\n              href=\"/docs/setup/\"\n              class=\"nav-item \"\n            >\n              Setup & Configuration\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"styling\"\n          >\n            <i\n              class=\"fa-solid fa-palette \"\n            ></i>\n            <span>Styling</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-styling\"\n          >\n            \n             \n            <a\n              href=\"/docs/customization/\"\n              class=\"nav-item \"\n            >\n              Customization\n            </a>\n              \n            <a\n              href=\"/docs/css-variables/\"\n              class=\"nav-item \"\n            >\n              CSS Variables Reference\n            </a>\n             \n          </div>\n        </div>\n              \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"community\"\n          >\n            <i\n              class=\"fa-solid fa-users \"\n            ></i>\n            <span>Community</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-community\"\n          >\n            \n             \n            <a\n              href=\"/docs/contributing/\"\n              class=\"nav-item \"\n            >\n              Contributing\n            </a>\n              \n            <a\n              href=\"/docs/content-guidelines/\"\n              class=\"nav-item \"\n            >\n              Content Guidelines\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"developer\"\n          >\n            <i\n              class=\"fa-solid fa-code \"\n            ></i>\n            <span>Developer</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-developer\"\n          >\n            \n             \n            <a\n              href=\"/docs/api-reference/\"\n              class=\"nav-item \"\n            >\n              API Reference\n            </a>\n              \n            <a\n              href=\"/docs/deployment/\"\n              class=\"nav-item \"\n            >\n              Deployment Guide\n            </a>\n              \n            <a\n              href=\"/docs/github-actions/\"\n              class=\"nav-item \"\n            >\n              GitHub Actions\n            </a>\n              \n            <a\n              href=\"/docs/project-structure/\"\n              class=\"nav-item \"\n            >\n              Project Structure\n            </a>\n              \n            <a\n              href=\"/docs/liquid-templates/\"\n              class=\"nav-item \"\n            >\n              Liquid Templates\n            </a>\n              \n            <a\n              href=\"/docs/performance/\"\n              class=\"nav-item \"\n            >\n              Performance Optimization\n            </a>\n              \n            <a\n              href=\"/docs/seo-guide/\"\n              class=\"nav-item \"\n            >\n              SEO Guide\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle active\"\n            data-category=\"help\"\n          >\n            <i\n              class=\"fa-solid fa-circle-question \"\n            ></i>\n            <span>Help</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items expanded\"\n            id=\"category-help\"\n          >\n            \n             \n            <a\n              href=\"/docs/faq/\"\n              class=\"nav-item \"\n            >\n              FAQ\n            </a>\n              \n            <a\n              href=\"/docs/troubleshooting/\"\n              class=\"nav-item \"\n            >\n              Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/accessibility/\"\n              class=\"nav-item active\"\n            >\n              Accessibility Guide\n            </a>\n              \n            <a\n              href=\"/docs/common-errors/\"\n              class=\"nav-item \"\n            >\n              Common Errors & Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/browser-support/\"\n              class=\"nav-item \"\n            >\n              Browser Support\n            </a>\n             \n          </div>\n        </div>\n         \n      </nav>\n\n      <!-- Quick Links -->\n      <div class=\"sidebar-footer\">\n        <a href=\"/docs/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-home\"></i>\n          All Docs\n        </a>\n        <a href=\"/projects/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-folder\"></i>\n          Projects\n        </a>\n      </div>\n    </aside>\n\n    <!-- Sidebar Overlay (for mobile) -->\n    <div id=\"sidebar-overlay\" class=\"sidebar-overlay\"></div>\n\n    <!-- Main Content -->\n    <div class=\"docs-layout\">\n      <!-- Breadcrumbs -->\n      \n      <nav class=\"breadcrumbs\" aria-label=\"Breadcrumb\">\n        <a href=\"/\">\n          <i class=\"fa-solid fa-home\"></i>\n          Home\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a href=\"/docs/\">Docs</a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a\n          href=\"/docs-category-help/\"\n        >\n          Help\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <span class=\"current\">Accessibility Guide</span>\n      </nav>\n      \n\n      <!-- Page Content -->\n      <main class=\"docs-content\">\n        <article><h1 id=\"accessibility-guide\">Accessibility Guide</h1>\n\n<p>Make your ABC showcase accessible to all users, including those with disabilities.</p>\n\n<h2 id=\"wcag-compliance\">WCAG Compliance</h2>\n\n<h3 id=\"target-level-aa\">Target Level: AA</h3>\n\n<p>Follow <a href=\"https://www.w3.org/WAI/WCAG21/quickref/\">Web Content Accessibility Guidelines (WCAG) 2.1 Level AA</a> for:</p>\n\n<ul>\n  <li><strong>Perceivable</strong>: Content is available to senses</li>\n  <li><strong>Operable</strong>: Interface is usable</li>\n  <li><strong>Understandable</strong>: Content and operation are clear</li>\n  <li><strong>Robust</strong>: Works with assistive technologies</li>\n</ul>\n\n<h2 id=\"semantic-html\">Semantic HTML</h2>\n\n<h3 id=\"use-proper-elements\">Use Proper Elements</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Good: Semantic --&gt;</span>\n<span class=\"nt\">&lt;nav&gt;</span>\n  <span class=\"nt\">&lt;ul&gt;</span>\n    <span class=\"nt\">&lt;li&gt;&lt;a</span> <span class=\"na\">href=</span><span class=\"s\">\"/\"</span><span class=\"nt\">&gt;</span>Home<span class=\"nt\">&lt;/a&gt;&lt;/li&gt;</span>\n  <span class=\"nt\">&lt;/ul&gt;</span>\n<span class=\"nt\">&lt;/nav&gt;</span>\n\n<span class=\"nt\">&lt;main&gt;</span>\n  <span class=\"nt\">&lt;article&gt;</span>\n    <span class=\"nt\">&lt;h1&gt;</span>Title<span class=\"nt\">&lt;/h1&gt;</span>\n    <span class=\"nt\">&lt;p&gt;</span>Content<span class=\"nt\">&lt;/p&gt;</span>\n  <span class=\"nt\">&lt;/article&gt;</span>\n<span class=\"nt\">&lt;/main&gt;</span>\n\n<span class=\"nt\">&lt;footer&gt;</span>\n  <span class=\"nt\">&lt;p&gt;</span><span class=\"ni\">&amp;copy;</span> 2025<span class=\"nt\">&lt;/p&gt;</span>\n<span class=\"nt\">&lt;/footer&gt;</span>\n\n<span class=\"c\">&lt;!-- Bad: Non-semantic --&gt;</span>\n<span class=\"nt\">&lt;div</span> <span class=\"na\">class=</span><span class=\"s\">\"nav\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;div</span> <span class=\"na\">class=</span><span class=\"s\">\"link\"</span><span class=\"nt\">&gt;</span>Home<span class=\"nt\">&lt;/div&gt;</span>\n<span class=\"nt\">&lt;/div&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"heading-hierarchy\">Heading Hierarchy</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Correct hierarchy --&gt;</span>\n<span class=\"nt\">&lt;h1&gt;</span>Main Title<span class=\"nt\">&lt;/h1&gt;</span>\n<span class=\"nt\">&lt;h2&gt;</span>Section<span class=\"nt\">&lt;/h2&gt;</span>\n<span class=\"nt\">&lt;h3&gt;</span>Subsection<span class=\"nt\">&lt;/h3&gt;</span>\n<span class=\"nt\">&lt;h2&gt;</span>Another Section<span class=\"nt\">&lt;/h2&gt;</span>\n\n<span class=\"c\">&lt;!-- Avoid skipping levels --&gt;</span>\n<span class=\"nt\">&lt;h1&gt;</span>Title<span class=\"nt\">&lt;/h1&gt;</span>\n<span class=\"nt\">&lt;h3&gt;</span>Subsection<span class=\"nt\">&lt;/h3&gt;</span>\n<span class=\"c\">&lt;!-- Bad: skipped h2 --&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"keyboard-navigation\">Keyboard Navigation</h2>\n\n<h3 id=\"focusable-elements\">Focusable Elements</h3>\n\n<p>Ensure all interactive elements are keyboard accessible:</p>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;button&gt;</span>Click Me<span class=\"nt\">&lt;/button&gt;</span>\n<span class=\"nt\">&lt;a</span> <span class=\"na\">href=</span><span class=\"s\">\"/page\"</span><span class=\"nt\">&gt;</span>Link<span class=\"nt\">&lt;/a&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"text\"</span> <span class=\"nt\">/&gt;</span>\n<span class=\"nt\">&lt;select&gt;</span>\n  <span class=\"nt\">&lt;option&gt;</span>Option<span class=\"nt\">&lt;/option&gt;</span>\n<span class=\"nt\">&lt;/select&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"focus-indicators\">Focus Indicators</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Always visible focus styles */</span>\n<span class=\"nd\">:focus</span> <span class=\"p\">{</span>\n  <span class=\"nl\">outline</span><span class=\"p\">:</span> <span class=\"m\">2px</span> <span class=\"nb\">solid</span> <span class=\"n\">var</span><span class=\"p\">(</span><span class=\"n\">--accent-primary</span><span class=\"p\">);</span>\n  <span class=\"nl\">outline-offset</span><span class=\"p\">:</span> <span class=\"m\">2px</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Better focus for dark theme */</span>\n<span class=\"nd\">:focus-visible</span> <span class=\"p\">{</span>\n  <span class=\"nl\">outline</span><span class=\"p\">:</span> <span class=\"m\">2px</span> <span class=\"nb\">solid</span> <span class=\"n\">var</span><span class=\"p\">(</span><span class=\"n\">--accent-primary</span><span class=\"p\">);</span>\n  <span class=\"nl\">outline-offset</span><span class=\"p\">:</span> <span class=\"m\">2px</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Don't remove outlines */</span>\n<span class=\"c\">/* BAD: button:focus { outline: none; } */</span>\n</code></pre></div></div>\n\n<h3 id=\"skip-links\">Skip Links</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;a</span> <span class=\"na\">href=</span><span class=\"s\">\"#main-content\"</span> <span class=\"na\">class=</span><span class=\"s\">\"skip-link\"</span><span class=\"nt\">&gt;</span> Skip to main content <span class=\"nt\">&lt;/a&gt;</span>\n\n<span class=\"nt\">&lt;main</span> <span class=\"na\">id=</span><span class=\"s\">\"main-content\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"c\">&lt;!-- Content --&gt;</span>\n<span class=\"nt\">&lt;/main&gt;</span>\n</code></pre></div></div>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">.skip-link</span> <span class=\"p\">{</span>\n  <span class=\"nl\">position</span><span class=\"p\">:</span> <span class=\"nb\">absolute</span><span class=\"p\">;</span>\n  <span class=\"nl\">top</span><span class=\"p\">:</span> <span class=\"m\">-40px</span><span class=\"p\">;</span>\n  <span class=\"nl\">left</span><span class=\"p\">:</span> <span class=\"m\">0</span><span class=\"p\">;</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"n\">var</span><span class=\"p\">(</span><span class=\"n\">--accent-primary</span><span class=\"p\">);</span>\n  <span class=\"nl\">color</span><span class=\"p\">:</span> <span class=\"no\">white</span><span class=\"p\">;</span>\n  <span class=\"nl\">padding</span><span class=\"p\">:</span> <span class=\"m\">8px</span><span class=\"p\">;</span>\n  <span class=\"nl\">z-index</span><span class=\"p\">:</span> <span class=\"m\">1000</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"nc\">.skip-link</span><span class=\"nd\">:focus</span> <span class=\"p\">{</span>\n  <span class=\"nl\">top</span><span class=\"p\">:</span> <span class=\"m\">0</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h3 id=\"tab-order\">Tab Order</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Natural tab order (default) --&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">tabindex=</span><span class=\"s\">\"0\"</span> <span class=\"nt\">/&gt;</span>\n<span class=\"nt\">&lt;button</span> <span class=\"na\">tabindex=</span><span class=\"s\">\"0\"</span><span class=\"nt\">&gt;</span>Submit<span class=\"nt\">&lt;/button&gt;</span>\n\n<span class=\"c\">&lt;!-- Custom tab order (use sparingly) --&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">tabindex=</span><span class=\"s\">\"1\"</span> <span class=\"nt\">/&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">tabindex=</span><span class=\"s\">\"2\"</span> <span class=\"nt\">/&gt;</span>\n\n<span class=\"c\">&lt;!-- Remove from tab order --&gt;</span>\n<span class=\"nt\">&lt;div</span> <span class=\"na\">tabindex=</span><span class=\"s\">\"-1\"</span><span class=\"nt\">&gt;</span>Not focusable<span class=\"nt\">&lt;/div&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"aria-labels\">ARIA Labels</h2>\n\n<h3 id=\"landmarks\">Landmarks</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;header</span> <span class=\"na\">role=</span><span class=\"s\">\"banner\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;nav</span> <span class=\"na\">role=</span><span class=\"s\">\"navigation\"</span> <span class=\"na\">aria-label=</span><span class=\"s\">\"Main navigation\"</span><span class=\"nt\">&gt;</span>\n    <span class=\"c\">&lt;!-- Nav items --&gt;</span>\n  <span class=\"nt\">&lt;/nav&gt;</span>\n<span class=\"nt\">&lt;/header&gt;</span>\n\n<span class=\"nt\">&lt;main</span> <span class=\"na\">role=</span><span class=\"s\">\"main\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;section</span> <span class=\"na\">aria-labelledby=</span><span class=\"s\">\"projects-heading\"</span><span class=\"nt\">&gt;</span>\n    <span class=\"nt\">&lt;h2</span> <span class=\"na\">id=</span><span class=\"s\">\"projects-heading\"</span><span class=\"nt\">&gt;</span>Projects<span class=\"nt\">&lt;/h2&gt;</span>\n  <span class=\"nt\">&lt;/section&gt;</span>\n<span class=\"nt\">&lt;/main&gt;</span>\n\n<span class=\"nt\">&lt;aside</span> <span class=\"na\">role=</span><span class=\"s\">\"complementary\"</span> <span class=\"na\">aria-label=</span><span class=\"s\">\"Sidebar\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"c\">&lt;!-- Sidebar content --&gt;</span>\n<span class=\"nt\">&lt;/aside&gt;</span>\n\n<span class=\"nt\">&lt;footer</span> <span class=\"na\">role=</span><span class=\"s\">\"contentinfo\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"c\">&lt;!-- Footer content --&gt;</span>\n<span class=\"nt\">&lt;/footer&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"button-labels\">Button Labels</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Icon buttons need labels --&gt;</span>\n<span class=\"nt\">&lt;button</span> <span class=\"na\">aria-label=</span><span class=\"s\">\"Toggle theme\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;i</span> <span class=\"na\">class=</span><span class=\"s\">\"fa-sun\"</span><span class=\"nt\">&gt;&lt;/i&gt;</span>\n<span class=\"nt\">&lt;/button&gt;</span>\n\n<span class=\"nt\">&lt;button</span> <span class=\"na\">aria-label=</span><span class=\"s\">\"Close modal\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;i</span> <span class=\"na\">class=</span><span class=\"s\">\"fa-times\"</span><span class=\"nt\">&gt;&lt;/i&gt;</span>\n<span class=\"nt\">&lt;/button&gt;</span>\n\n<span class=\"c\">&lt;!-- Links with icons --&gt;</span>\n<span class=\"nt\">&lt;a</span> <span class=\"na\">href=</span><span class=\"s\">\"https://github.com/user/repo\"</span> <span class=\"na\">aria-label=</span><span class=\"s\">\"View on GitHub\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;i</span> <span class=\"na\">class=</span><span class=\"s\">\"fab fa-github\"</span><span class=\"nt\">&gt;&lt;/i&gt;</span>\n<span class=\"nt\">&lt;/a&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"live-regions\">Live Regions</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Announce dynamic content --&gt;</span>\n<span class=\"nt\">&lt;div</span> <span class=\"na\">role=</span><span class=\"s\">\"status\"</span> <span class=\"na\">aria-live=</span><span class=\"s\">\"polite\"</span> <span class=\"na\">aria-atomic=</span><span class=\"s\">\"true\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;p</span> <span class=\"na\">id=</span><span class=\"s\">\"search-results\"</span><span class=\"nt\">&gt;</span>Found 5 results<span class=\"nt\">&lt;/p&gt;</span>\n<span class=\"nt\">&lt;/div&gt;</span>\n\n<span class=\"c\">&lt;!-- Alerts --&gt;</span>\n<span class=\"nt\">&lt;div</span> <span class=\"na\">role=</span><span class=\"s\">\"alert\"</span> <span class=\"na\">aria-live=</span><span class=\"s\">\"assertive\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;p&gt;</span>Error: Form submission failed<span class=\"nt\">&lt;/p&gt;</span>\n<span class=\"nt\">&lt;/div&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"form-labels\">Form Labels</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Always label inputs --&gt;</span>\n<span class=\"nt\">&lt;label</span> <span class=\"na\">for=</span><span class=\"s\">\"search\"</span><span class=\"nt\">&gt;</span>Search<span class=\"nt\">&lt;/label&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"search\"</span> <span class=\"na\">id=</span><span class=\"s\">\"search\"</span> <span class=\"na\">name=</span><span class=\"s\">\"search\"</span> <span class=\"nt\">/&gt;</span>\n\n<span class=\"c\">&lt;!-- Or use aria-label --&gt;</span>\n<span class=\"nt\">&lt;input</span>\n  <span class=\"na\">type=</span><span class=\"s\">\"search\"</span>\n  <span class=\"na\">aria-label=</span><span class=\"s\">\"Search documentation\"</span>\n  <span class=\"na\">placeholder=</span><span class=\"s\">\"Search...\"</span>\n<span class=\"nt\">/&gt;</span>\n\n<span class=\"c\">&lt;!-- Group related inputs --&gt;</span>\n<span class=\"nt\">&lt;fieldset&gt;</span>\n  <span class=\"nt\">&lt;legend&gt;</span>Filter Options<span class=\"nt\">&lt;/legend&gt;</span>\n  <span class=\"nt\">&lt;label&gt;&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"checkbox\"</span> <span class=\"na\">name=</span><span class=\"s\">\"category\"</span> <span class=\"na\">value=</span><span class=\"s\">\"setup\"</span> <span class=\"nt\">/&gt;</span> Setup<span class=\"nt\">&lt;/label&gt;</span>\n  <span class=\"nt\">&lt;label</span>\n    <span class=\"nt\">&gt;&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"checkbox\"</span> <span class=\"na\">name=</span><span class=\"s\">\"category\"</span> <span class=\"na\">value=</span><span class=\"s\">\"styling\"</span> <span class=\"nt\">/&gt;</span> Styling<span class=\"nt\">&lt;/label</span>\n  <span class=\"nt\">&gt;</span>\n<span class=\"nt\">&lt;/fieldset&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"color-and-contrast\">Color and Contrast</h2>\n\n<h3 id=\"contrast-ratios\">Contrast Ratios</h3>\n\n<p><strong>WCAG AA Requirements:</strong></p>\n\n<ul>\n  <li>Normal text: 4.5:1</li>\n  <li>Large text (18pt+): 3:1</li>\n  <li>UI components: 3:1</li>\n</ul>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Good contrast examples */</span>\n<span class=\"nc\">.dark-theme</span> <span class=\"p\">{</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"m\">#1a1a1a</span><span class=\"p\">;</span>\n  <span class=\"nl\">color</span><span class=\"p\">:</span> <span class=\"m\">#e0e0e0</span><span class=\"p\">;</span> <span class=\"c\">/* 12.6:1 ratio */</span>\n<span class=\"p\">}</span>\n\n<span class=\"nc\">.light-theme</span> <span class=\"p\">{</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"m\">#ffffff</span><span class=\"p\">;</span>\n  <span class=\"nl\">color</span><span class=\"p\">:</span> <span class=\"m\">#212121</span><span class=\"p\">;</span> <span class=\"c\">/* 16.1:1 ratio */</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Check with browser DevTools or tools like:\n   - WebAIM Contrast Checker\n   - Color Contrast Analyzer\n*/</span>\n</code></pre></div></div>\n\n<h3 id=\"dont-rely-on-color-alone\">Don’t Rely on Color Alone</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Bad: Color only --&gt;</span>\n<span class=\"nt\">&lt;span</span> <span class=\"na\">style=</span><span class=\"s\">\"color: red;\"</span><span class=\"nt\">&gt;</span>Required<span class=\"nt\">&lt;/span&gt;</span>\n\n<span class=\"c\">&lt;!-- Good: Color + text/icon --&gt;</span>\n<span class=\"nt\">&lt;span</span> <span class=\"na\">class=</span><span class=\"s\">\"required\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;i</span> <span class=\"na\">class=</span><span class=\"s\">\"fa-asterisk\"</span> <span class=\"na\">aria-hidden=</span><span class=\"s\">\"true\"</span><span class=\"nt\">&gt;&lt;/i&gt;</span>\n  Required\n<span class=\"nt\">&lt;/span&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"images-and-media\">Images and Media</h2>\n\n<h3 id=\"alt-text\">Alt Text</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Informative images --&gt;</span>\n<span class=\"nt\">&lt;img</span> <span class=\"na\">src=</span><span class=\"s\">\"logo.png\"</span> <span class=\"na\">alt=</span><span class=\"s\">\"ABC Showcase logo\"</span> <span class=\"nt\">/&gt;</span>\n\n<span class=\"c\">&lt;!-- Decorative images --&gt;</span>\n<span class=\"nt\">&lt;img</span> <span class=\"na\">src=</span><span class=\"s\">\"decoration.svg\"</span> <span class=\"na\">alt=</span><span class=\"s\">\"\"</span> <span class=\"na\">role=</span><span class=\"s\">\"presentation\"</span> <span class=\"nt\">/&gt;</span>\n\n<span class=\"c\">&lt;!-- Complex images --&gt;</span>\n<span class=\"nt\">&lt;figure&gt;</span>\n  <span class=\"nt\">&lt;img</span> <span class=\"na\">src=</span><span class=\"s\">\"chart.png\"</span> <span class=\"na\">alt=</span><span class=\"s\">\"Sales chart showing 20% growth\"</span> <span class=\"nt\">/&gt;</span>\n  <span class=\"nt\">&lt;figcaption&gt;</span>\n    Detailed description: Sales increased from $100k in Q1 to $120k in Q2,\n    representing 20% growth.\n  <span class=\"nt\">&lt;/figcaption&gt;</span>\n<span class=\"nt\">&lt;/figure&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"videos\">Videos</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;video</span> <span class=\"na\">controls</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;source</span> <span class=\"na\">src=</span><span class=\"s\">\"video.mp4\"</span> <span class=\"na\">type=</span><span class=\"s\">\"video/mp4\"</span> <span class=\"nt\">/&gt;</span>\n  <span class=\"nt\">&lt;track</span> <span class=\"na\">kind=</span><span class=\"s\">\"captions\"</span> <span class=\"na\">src=</span><span class=\"s\">\"captions.vtt\"</span> <span class=\"na\">srclang=</span><span class=\"s\">\"en\"</span> <span class=\"na\">label=</span><span class=\"s\">\"English\"</span> <span class=\"nt\">/&gt;</span>\n  <span class=\"nt\">&lt;track</span> <span class=\"na\">kind=</span><span class=\"s\">\"descriptions\"</span> <span class=\"na\">src=</span><span class=\"s\">\"descriptions.vtt\"</span> <span class=\"na\">srclang=</span><span class=\"s\">\"en\"</span> <span class=\"nt\">/&gt;</span>\n  Your browser doesn't support video.\n<span class=\"nt\">&lt;/video&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"screen-reader-support\">Screen Reader Support</h2>\n\n<h3 id=\"hidden-content\">Hidden Content</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Visually hidden but screen reader accessible */</span>\n<span class=\"nc\">.sr-only</span> <span class=\"p\">{</span>\n  <span class=\"nl\">position</span><span class=\"p\">:</span> <span class=\"nb\">absolute</span><span class=\"p\">;</span>\n  <span class=\"nl\">width</span><span class=\"p\">:</span> <span class=\"m\">1px</span><span class=\"p\">;</span>\n  <span class=\"nl\">height</span><span class=\"p\">:</span> <span class=\"m\">1px</span><span class=\"p\">;</span>\n  <span class=\"nl\">padding</span><span class=\"p\">:</span> <span class=\"m\">0</span><span class=\"p\">;</span>\n  <span class=\"nl\">margin</span><span class=\"p\">:</span> <span class=\"m\">-1px</span><span class=\"p\">;</span>\n  <span class=\"nl\">overflow</span><span class=\"p\">:</span> <span class=\"nb\">hidden</span><span class=\"p\">;</span>\n  <span class=\"nl\">clip</span><span class=\"p\">:</span> <span class=\"n\">rect</span><span class=\"p\">(</span><span class=\"m\">0</span><span class=\"p\">,</span> <span class=\"m\">0</span><span class=\"p\">,</span> <span class=\"m\">0</span><span class=\"p\">,</span> <span class=\"m\">0</span><span class=\"p\">);</span>\n  <span class=\"nl\">white-space</span><span class=\"p\">:</span> <span class=\"nb\">nowrap</span><span class=\"p\">;</span>\n  <span class=\"nl\">border</span><span class=\"p\">:</span> <span class=\"m\">0</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Hidden from everyone */</span>\n<span class=\"nc\">.hidden</span> <span class=\"p\">{</span>\n  <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"nb\">none</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Use aria-hidden for decorative content */</span>\n<span class=\"o\">&lt;</span><span class=\"nt\">i</span> <span class=\"nt\">class</span><span class=\"o\">=</span><span class=\"s1\">\"fa-icon\"</span> <span class=\"nt\">aria-hidden</span><span class=\"o\">=</span><span class=\"s1\">\"true\"</span><span class=\"o\">&gt;&lt;/</span><span class=\"nt\">i</span><span class=\"o\">&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"descriptive-text\">Descriptive Text</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Generic link text is bad --&gt;</span>\n<span class=\"nt\">&lt;a</span> <span class=\"na\">href=</span><span class=\"s\">\"/docs\"</span><span class=\"nt\">&gt;</span>Click here<span class=\"nt\">&lt;/a&gt;</span>\n\n<span class=\"c\">&lt;!-- Descriptive link text is good --&gt;</span>\n<span class=\"nt\">&lt;a</span> <span class=\"na\">href=</span><span class=\"s\">\"/docs\"</span><span class=\"nt\">&gt;</span>Read the documentation<span class=\"nt\">&lt;/a&gt;</span>\n\n<span class=\"c\">&lt;!-- Or add context --&gt;</span>\n<span class=\"nt\">&lt;a</span> <span class=\"na\">href=</span><span class=\"s\">\"/download\"</span><span class=\"nt\">&gt;</span>\n  Download\n  <span class=\"nt\">&lt;span</span> <span class=\"na\">class=</span><span class=\"s\">\"sr-only\"</span><span class=\"nt\">&gt;</span> modpack installer<span class=\"nt\">&lt;/span&gt;</span>\n<span class=\"nt\">&lt;/a&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"forms\">Forms</h2>\n\n<h3 id=\"error-messages\">Error Messages</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;form&gt;</span>\n  <span class=\"nt\">&lt;div</span> <span class=\"na\">class=</span><span class=\"s\">\"form-group\"</span><span class=\"nt\">&gt;</span>\n    <span class=\"nt\">&lt;label</span> <span class=\"na\">for=</span><span class=\"s\">\"email\"</span><span class=\"nt\">&gt;</span>Email<span class=\"nt\">&lt;/label&gt;</span>\n    <span class=\"nt\">&lt;input</span>\n      <span class=\"na\">type=</span><span class=\"s\">\"email\"</span>\n      <span class=\"na\">id=</span><span class=\"s\">\"email\"</span>\n      <span class=\"na\">aria-describedby=</span><span class=\"s\">\"email-error\"</span>\n      <span class=\"na\">aria-invalid=</span><span class=\"s\">\"true\"</span>\n    <span class=\"nt\">/&gt;</span>\n    <span class=\"nt\">&lt;span</span> <span class=\"na\">id=</span><span class=\"s\">\"email-error\"</span> <span class=\"na\">role=</span><span class=\"s\">\"alert\"</span><span class=\"nt\">&gt;</span>\n      Please enter a valid email address\n    <span class=\"nt\">&lt;/span&gt;</span>\n  <span class=\"nt\">&lt;/div&gt;</span>\n<span class=\"nt\">&lt;/form&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"required-fields\">Required Fields</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;label</span> <span class=\"na\">for=</span><span class=\"s\">\"username\"</span><span class=\"nt\">&gt;</span>\n  Username\n  <span class=\"nt\">&lt;span</span> <span class=\"na\">aria-label=</span><span class=\"s\">\"required\"</span><span class=\"nt\">&gt;</span>*<span class=\"nt\">&lt;/span&gt;</span>\n<span class=\"nt\">&lt;/label&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"text\"</span> <span class=\"na\">id=</span><span class=\"s\">\"username\"</span> <span class=\"na\">required</span> <span class=\"na\">aria-required=</span><span class=\"s\">\"true\"</span> <span class=\"nt\">/&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"help-text\">Help Text</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;label</span> <span class=\"na\">for=</span><span class=\"s\">\"password\"</span><span class=\"nt\">&gt;</span>Password<span class=\"nt\">&lt;/label&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"password\"</span> <span class=\"na\">id=</span><span class=\"s\">\"password\"</span> <span class=\"na\">aria-describedby=</span><span class=\"s\">\"password-help\"</span> <span class=\"nt\">/&gt;</span>\n<span class=\"nt\">&lt;small</span> <span class=\"na\">id=</span><span class=\"s\">\"password-help\"</span><span class=\"nt\">&gt;</span> Must be at least 8 characters with 1 number <span class=\"nt\">&lt;/small&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"modals-and-overlays\">Modals and Overlays</h2>\n\n<h3 id=\"focus-management\">Focus Management</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// Trap focus in modal</span>\n<span class=\"kd\">const</span> <span class=\"nx\">modal</span> <span class=\"o\">=</span> <span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">querySelector</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">.modal</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n<span class=\"kd\">const</span> <span class=\"nx\">focusableElements</span> <span class=\"o\">=</span> <span class=\"nx\">modal</span><span class=\"p\">.</span><span class=\"nx\">querySelectorAll</span><span class=\"p\">(</span>\n  <span class=\"dl\">'</span><span class=\"s1\">button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])</span><span class=\"dl\">'</span>\n<span class=\"p\">);</span>\n<span class=\"kd\">const</span> <span class=\"nx\">firstFocusable</span> <span class=\"o\">=</span> <span class=\"nx\">focusableElements</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">];</span>\n<span class=\"kd\">const</span> <span class=\"nx\">lastFocusable</span> <span class=\"o\">=</span> <span class=\"nx\">focusableElements</span><span class=\"p\">[</span><span class=\"nx\">focusableElements</span><span class=\"p\">.</span><span class=\"nx\">length</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">];</span>\n\n<span class=\"nx\">modal</span><span class=\"p\">.</span><span class=\"nx\">addEventListener</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">keydown</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">e</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">e</span><span class=\"p\">.</span><span class=\"nx\">key</span> <span class=\"o\">===</span> <span class=\"dl\">\"</span><span class=\"s2\">Tab</span><span class=\"dl\">\"</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">e</span><span class=\"p\">.</span><span class=\"nx\">shiftKey</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n      <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">activeElement</span> <span class=\"o\">===</span> <span class=\"nx\">firstFocusable</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"nx\">lastFocusable</span><span class=\"p\">.</span><span class=\"nx\">focus</span><span class=\"p\">();</span>\n        <span class=\"nx\">e</span><span class=\"p\">.</span><span class=\"nx\">preventDefault</span><span class=\"p\">();</span>\n      <span class=\"p\">}</span>\n    <span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n      <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">activeElement</span> <span class=\"o\">===</span> <span class=\"nx\">lastFocusable</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"nx\">firstFocusable</span><span class=\"p\">.</span><span class=\"nx\">focus</span><span class=\"p\">();</span>\n        <span class=\"nx\">e</span><span class=\"p\">.</span><span class=\"nx\">preventDefault</span><span class=\"p\">();</span>\n      <span class=\"p\">}</span>\n    <span class=\"p\">}</span>\n  <span class=\"p\">}</span>\n\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">e</span><span class=\"p\">.</span><span class=\"nx\">key</span> <span class=\"o\">===</span> <span class=\"dl\">\"</span><span class=\"s2\">Escape</span><span class=\"dl\">\"</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"nx\">closeModal</span><span class=\"p\">();</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">});</span>\n</code></pre></div></div>\n\n<h3 id=\"aria-modal\">ARIA Modal</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;div</span>\n  <span class=\"na\">role=</span><span class=\"s\">\"dialog\"</span>\n  <span class=\"na\">aria-modal=</span><span class=\"s\">\"true\"</span>\n  <span class=\"na\">aria-labelledby=</span><span class=\"s\">\"modal-title\"</span>\n  <span class=\"na\">aria-describedby=</span><span class=\"s\">\"modal-description\"</span>\n<span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;h2</span> <span class=\"na\">id=</span><span class=\"s\">\"modal-title\"</span><span class=\"nt\">&gt;</span>Confirm Action<span class=\"nt\">&lt;/h2&gt;</span>\n  <span class=\"nt\">&lt;p</span> <span class=\"na\">id=</span><span class=\"s\">\"modal-description\"</span><span class=\"nt\">&gt;</span>Are you sure you want to proceed?<span class=\"nt\">&lt;/p&gt;</span>\n  <span class=\"nt\">&lt;button&gt;</span>Confirm<span class=\"nt\">&lt;/button&gt;</span>\n  <span class=\"nt\">&lt;button&gt;</span>Cancel<span class=\"nt\">&lt;/button&gt;</span>\n<span class=\"nt\">&lt;/div&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"testing\">Testing</h2>\n\n<h3 id=\"automated-testing\">Automated Testing</h3>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\"># Install pa11y</span>\nnpm <span class=\"nb\">install</span> <span class=\"nt\">-g</span> pa11y\n\n<span class=\"c\"># Run accessibility test</span>\npa11y https://yoursite.com\n\n<span class=\"c\"># Test multiple pages</span>\npa11y-ci <span class=\"nt\">--sitemap</span> https://yoursite.com/sitemap.xml\n</code></pre></div></div>\n\n<h3 id=\"manual-testing\">Manual Testing</h3>\n\n<ol>\n  <li><strong>Keyboard only</strong>: Navigate entire site with Tab, Enter, Space, Arrow keys</li>\n  <li><strong>Screen reader</strong>: Test with NVDA (Windows), JAWS (Windows), VoiceOver (macOS/iOS)</li>\n  <li><strong>Zoom</strong>: Test at 200% zoom</li>\n  <li><strong>Color blind mode</strong>: Use browser extensions</li>\n  <li><strong>High contrast</strong>: Test with Windows High Contrast mode</li>\n</ol>\n\n<h3 id=\"checklist\">Checklist</h3>\n\n<ul class=\"task-list\">\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />All images have alt text</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Sufficient color contrast (4.5:1 minimum)</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Keyboard navigation works throughout</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Focus indicators are visible</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Form inputs have labels</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Headings follow logical hierarchy</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Links have descriptive text</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />ARIA labels for icon buttons</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Skip links implemented</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />No keyboard traps</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Error messages are descriptive</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Live regions for dynamic content</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Modal focus management</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Video captions available</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Works with screen readers</li>\n</ul>\n\n<h2 id=\"common-issues\">Common Issues</h2>\n\n<h3 id=\"issue-low-contrast\">Issue: Low Contrast</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Bad: 2.1:1 ratio */</span>\n<span class=\"nc\">.link</span> <span class=\"p\">{</span>\n  <span class=\"nl\">color</span><span class=\"p\">:</span> <span class=\"m\">#666666</span><span class=\"p\">;</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"m\">#ffffff</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Good: 7.0:1 ratio */</span>\n<span class=\"nc\">.link</span> <span class=\"p\">{</span>\n  <span class=\"nl\">color</span><span class=\"p\">:</span> <span class=\"m\">#333333</span><span class=\"p\">;</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"m\">#ffffff</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h3 id=\"issue-missing-labels\">Issue: Missing Labels</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Bad --&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"search\"</span> <span class=\"na\">placeholder=</span><span class=\"s\">\"Search\"</span> <span class=\"nt\">/&gt;</span>\n\n<span class=\"c\">&lt;!-- Good --&gt;</span>\n<span class=\"nt\">&lt;label</span> <span class=\"na\">for=</span><span class=\"s\">\"search\"</span><span class=\"nt\">&gt;</span>Search<span class=\"nt\">&lt;/label&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"search\"</span> <span class=\"na\">id=</span><span class=\"s\">\"search\"</span> <span class=\"na\">placeholder=</span><span class=\"s\">\"Search\"</span> <span class=\"nt\">/&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"issue-click-handlers-on-divs\">Issue: Click Handlers on Divs</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Bad --&gt;</span>\n<span class=\"nt\">&lt;div</span> <span class=\"na\">onclick=</span><span class=\"s\">\"doSomething()\"</span><span class=\"nt\">&gt;</span>Click me<span class=\"nt\">&lt;/div&gt;</span>\n\n<span class=\"c\">&lt;!-- Good --&gt;</span>\n<span class=\"nt\">&lt;button</span> <span class=\"na\">onclick=</span><span class=\"s\">\"doSomething()\"</span><span class=\"nt\">&gt;</span>Click me<span class=\"nt\">&lt;/button&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"resources\">Resources</h2>\n\n<ul>\n  <li><a href=\"https://www.w3.org/WAI/WCAG21/quickref/\">WCAG 2.1 Guidelines</a></li>\n  <li><a href=\"https://webaim.org/\">WebAIM</a> - Training and tools</li>\n  <li><a href=\"https://www.a11yproject.com/\">A11y Project</a> - Community-driven resources</li>\n  <li><a href=\"https://www.w3.org/WAI/ARIA/apg/\">ARIA Authoring Practices</a> - Design patterns</li>\n  <li><a href=\"https://webaim.org/resources/contrastchecker/\">Color Contrast Checker</a></li>\n</ul>\n\n<h2 id=\"next-steps\">Next Steps</h2>\n\n<ul>\n  <li><a href=\"performance.html\">Performance Guide</a> - Fast and accessible</li>\n  <li><a href=\"seo-guide.html\">SEO Guide</a> - Accessible and discoverable</li>\n  <li><a href=\"browser-support.html\">Browser Support</a> - Cross-browser accessibility</li>\n</ul>\n</article>\n\n        <section\n          class=\"feedback-card\"\n          id=\"feedback-card\"\n          aria-label=\"Page feedback\"\n        >\n          <div class=\"feedback-header\">\n            <div>\n              <p class=\"feedback-kicker\">Feedback</p>\n              <h3>Was this page helpful?</h3>\n              <p class=\"feedback-subtext\">\n                Share quick feedback to improve these docs.\n              </p>\n            </div>\n            <div class=\"feedback-badges\" aria-label=\"Applies to versions\">\n                  \n              <span class=\"version-badge\" aria-label=\"Minecraft 1.21.x\"\n                >1.21.x</span\n              >\n               \n            </div>\n          </div>\n\n          <div class=\"feedback-actions\" role=\"group\" aria-label=\"Helpful?\">\n            <button type=\"button\" class=\"feedback-btn yes\" data-feedback=\"yes\">\n              <i class=\"fa-solid fa-thumbs-up\"></i>\n              Yes\n            </button>\n            <button type=\"button\" class=\"feedback-btn no\" data-feedback=\"no\">\n              <i class=\"fa-solid fa-thumbs-down\"></i>\n              No\n            </button>\n          </div>\n\n          <div class=\"feedback-followup\" id=\"feedback-followup\" hidden>\n            <label for=\"feedback-notes\">What can we improve?</label>\n            <textarea\n              id=\"feedback-notes\"\n              rows=\"3\"\n              placeholder=\"Optional: missing steps, unclear wording, broken links\"\n            ></textarea>\n            <button type=\"button\" class=\"feedback-submit\" id=\"feedback-submit\">\n              <i class=\"fa-solid fa-paper-plane\"></i>\n              Send feedback\n            </button>\n          </div>\n\n          <p\n            class=\"feedback-status\"\n            id=\"feedback-status\"\n            role=\"status\"\n            aria-live=\"polite\"\n          ></p>\n        </section>\n\n        <!-- Page Navigation (Prev/Next) -->\n                                                 \n      </main>\n\n      <!-- Table of Contents (optional) -->\n      <aside class=\"docs-toc\">\n        <div class=\"toc-header\">\n          <h3>On This Page</h3>\n        </div>\n        <nav id=\"toc-nav\" class=\"toc-nav\">\n          <!-- Generated by JavaScript -->\n        </nav>\n\n        <!-- Theme Toggle in TOC -->\n        <button\n          id=\"theme-toggle-docs\"\n          class=\"theme-toggle\"\n          aria-label=\"Toggle theme\"\n        >\n          <i class=\"fa-solid fa-sun\"></i>\n          <i class=\"fa-solid fa-moon\"></i>\n        </button>\n      </aside>\n    </div>\n\n    <script>\n      // Theme Toggle\n      const themeToggle = document.getElementById(\"theme-toggle-docs\");\n      themeToggle?.addEventListener(\"click\", () => {\n        const current = document.documentElement.getAttribute(\"data-theme\");\n        const next = current === \"light\" ? \"dark\" : \"light\";\n        document.documentElement.setAttribute(\"data-theme\", next);\n        localStorage.setItem(\"theme\", next);\n      });\n\n      // Mobile Sidebar Toggle\n      const mobileToggle = document.getElementById(\"mobile-sidebar-toggle\");\n      const sidebar = document.getElementById(\"docs-sidebar\");\n      const overlay = document.getElementById(\"sidebar-overlay\");\n      const sidebarClose = document.getElementById(\"sidebar-close\");\n\n      function toggleSidebar() {\n        sidebar.classList.toggle(\"open\");\n        overlay.classList.toggle(\"active\");\n        document.body.style.overflow = sidebar.classList.contains(\"open\")\n          ? \"hidden\"\n          : \"\";\n      }\n\n      mobileToggle?.addEventListener(\"click\", toggleSidebar);\n      overlay?.addEventListener(\"click\", toggleSidebar);\n      sidebarClose?.addEventListener(\"click\", toggleSidebar);\n\n      // Category Toggle\n      document.querySelectorAll(\".category-toggle\").forEach((toggle) => {\n        toggle.addEventListener(\"click\", () => {\n          const category = toggle.dataset.category;\n          const items = document.getElementById(`category-${category}`);\n          toggle.classList.toggle(\"active\");\n          items.classList.toggle(\"expanded\");\n        });\n      });\n\n      // Generate Table of Contents\n      const content = document.querySelector(\".docs-content article\");\n      const tocNav = document.getElementById(\"toc-nav\");\n\n      if (content && tocNav) {\n        const headings = content.querySelectorAll(\"h2, h3\");\n\n        if (headings.length > 0) {\n          headings.forEach((heading, index) => {\n            // Add ID if not present\n            if (!heading.id) {\n              heading.id = heading.textContent\n                .toLowerCase()\n                .replace(/[^a-z0-9]+/g, \"-\")\n                .replace(/^-|-$/g, \"\");\n            }\n\n            const link = document.createElement(\"a\");\n            link.href = `#${heading.id}`;\n            link.textContent = heading.textContent;\n            link.className = `toc-link toc-${heading.tagName.toLowerCase()}`;\n            tocNav.appendChild(link);\n          });\n\n          // Highlight current section\n          const observer = new IntersectionObserver(\n            (entries) => {\n              entries.forEach((entry) => {\n                if (entry.isIntersecting) {\n                  const id = entry.target.id;\n                  tocNav.querySelectorAll(\".toc-link\").forEach((link) => {\n                    link.classList.toggle(\n                      \"active\",\n                      link.getAttribute(\"href\") === `#${id}`\n                    );\n                  });\n                }\n              });\n            },\n            { rootMargin: \"-20% 0px -80% 0px\" }\n          );\n\n          headings.forEach((heading) => observer.observe(heading));\n        }\n      }\n\n      // Sidebar Search\n      const sidebarSearch = document.getElementById(\"sidebar-search\");\n      sidebarSearch?.addEventListener(\"input\", (e) => {\n        const query = e.target.value.toLowerCase();\n        const items = document.querySelectorAll(\".nav-item\");\n\n        items.forEach((item) => {\n          const text = item.textContent.toLowerCase();\n          const matches = text.includes(query);\n          item.style.display = matches || !query ? \"\" : \"none\";\n\n          // Expand category if item matches\n          if (matches && query) {\n            const category = item.closest(\".category-items\");\n            const toggle = category?.previousElementSibling;\n            category?.classList.add(\"expanded\");\n            toggle?.classList.add(\"active\");\n          }\n        });\n      });\n\n      // Docs micro-feedback (local only)\n      const feedbackCard = document.getElementById(\"feedback-card\");\n      const feedbackButtons = document.querySelectorAll(\".feedback-btn\");\n      const feedbackFollowup = document.getElementById(\"feedback-followup\");\n      const feedbackSubmit = document.getElementById(\"feedback-submit\");\n      const feedbackStatus = document.getElementById(\"feedback-status\");\n      const feedbackNotes = document.getElementById(\"feedback-notes\");\n      const feedbackStorageKey = `docs-feedback:${window.location.pathname}`;\n\n      function completeFeedback(message) {\n        if (feedbackCard) feedbackCard.classList.add(\"feedback-complete\");\n        if (feedbackFollowup) feedbackFollowup.hidden = true;\n        if (feedbackStatus) feedbackStatus.textContent = message;\n        try {\n          localStorage.setItem(feedbackStorageKey, \"submitted\");\n        } catch (err) {\n          console.warn(\"Feedback storage failed\", err);\n        }\n      }\n\n      function maybeDisableFeedback() {\n        let stored = null;\n        try {\n          stored = localStorage.getItem(feedbackStorageKey);\n        } catch (err) {\n          console.warn(\"Feedback storage read failed\", err);\n        }\n\n        if (stored && feedbackCard) {\n          feedbackCard.classList.add(\"feedback-complete\");\n          if (feedbackFollowup) feedbackFollowup.hidden = true;\n          if (feedbackStatus)\n            feedbackStatus.textContent = \"Thanks—feedback already recorded.\";\n        }\n      }\n\n      feedbackButtons.forEach((btn) => {\n        btn.addEventListener(\"click\", () => {\n          const value = btn.dataset.feedback;\n          if (value === \"no\") {\n            if (feedbackFollowup) feedbackFollowup.hidden = false;\n            if (feedbackStatus)\n              feedbackStatus.textContent = \"Tell us what to improve.\";\n          } else {\n            completeFeedback(\"Thanks for the feedback!\");\n          }\n        });\n      });\n\n      feedbackSubmit?.addEventListener(\"click\", () => {\n        const note = feedbackNotes?.value?.trim();\n        const suffix = note ? \" We will review your note.\" : \"\";\n        completeFeedback(`Got it!${suffix}`);\n      });\n\n      maybeDisableFeedback();\n    </script>\n  </body>\n</html>\n","<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"dark\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>\n      Adding Modpacks | Minecraft Mods & Packs Showcase\n    </title>\n\n    <!-- Stylesheets -->\n    <link rel=\"stylesheet\" href=\"/assets/css/main.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/layout.css\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/modpacks.css\"\n    />\n    <link rel=\"stylesheet\" href=\"/assets/css/docs.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n    />\n\n    <script>\n      if (!document.body) {\n        console.warn(\"Body not ready, skipping preloader\");\n      } else {\n        window.addEventListener(\"load\", () => {\n          document.body.classList.add(\"loaded\");\n        });\n      }\n\n      const savedTheme = localStorage.getItem(\"theme\") || \"dark\";\n      document.documentElement.setAttribute(\"data-theme\", savedTheme);\n    </script>\n  </head>\n  <body>\n    <!-- Preloader -->\n    <div class=\"preloader\">\n      <div class=\"spinner\"></div>\n    </div>\n\n    <!-- Mobile Menu Toggle -->\n    <button\n      id=\"mobile-sidebar-toggle\"\n      class=\"mobile-sidebar-toggle\"\n      aria-label=\"Toggle sidebar\"\n    >\n      <i class=\"fa-solid fa-bars\"></i>\n    </button>\n\n    <!-- Docs Sidebar -->\n    <aside id=\"docs-sidebar\" class=\"docs-sidebar\">\n      <div class=\"sidebar-header\">\n        <a href=\"/\" class=\"sidebar-logo\">\n          <i class=\"fa-solid fa-cube\"></i>\n          <span>Minecraft Mods & Packs Showcase</span>\n        </a>\n        <button\n          id=\"sidebar-close\"\n          class=\"sidebar-close\"\n          aria-label=\"Close sidebar\"\n        >\n          <i class=\"fa-solid fa-times\"></i>\n        </button>\n      </div>\n\n      <!-- Search in Sidebar -->\n      <div class=\"sidebar-search\">\n        <input\n          type=\"search\"\n          id=\"sidebar-search\"\n          placeholder=\"Search docs...\"\n          aria-label=\"Search documentation\"\n        />\n        <i class=\"fa-solid fa-search\"></i>\n      </div>\n\n      <!-- Navigation Tree -->\n      <nav class=\"sidebar-nav\">\n            \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"setup\"\n          >\n            <i\n              class=\"fa-solid fa-gear \"\n            ></i>\n            <span>Setup</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-setup\"\n          >\n            \n             \n            <a\n              href=\"/docs/getting-started/\"\n              class=\"nav-item \"\n            >\n              Getting Started\n            </a>\n              \n            <a\n              href=\"/docs/setup/\"\n              class=\"nav-item \"\n            >\n              Setup & Configuration\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"styling\"\n          >\n            <i\n              class=\"fa-solid fa-palette \"\n            ></i>\n            <span>Styling</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-styling\"\n          >\n            \n             \n            <a\n              href=\"/docs/customization/\"\n              class=\"nav-item \"\n            >\n              Customization\n            </a>\n              \n            <a\n              href=\"/docs/css-variables/\"\n              class=\"nav-item \"\n            >\n              CSS Variables Reference\n            </a>\n             \n          </div>\n        </div>\n              \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"community\"\n          >\n            <i\n              class=\"fa-solid fa-users \"\n            ></i>\n            <span>Community</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-community\"\n          >\n            \n             \n            <a\n              href=\"/docs/contributing/\"\n              class=\"nav-item \"\n            >\n              Contributing\n            </a>\n              \n            <a\n              href=\"/docs/content-guidelines/\"\n              class=\"nav-item \"\n            >\n              Content Guidelines\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"developer\"\n          >\n            <i\n              class=\"fa-solid fa-code \"\n            ></i>\n            <span>Developer</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-developer\"\n          >\n            \n             \n            <a\n              href=\"/docs/api-reference/\"\n              class=\"nav-item \"\n            >\n              API Reference\n            </a>\n              \n            <a\n              href=\"/docs/deployment/\"\n              class=\"nav-item \"\n            >\n              Deployment Guide\n            </a>\n              \n            <a\n              href=\"/docs/github-actions/\"\n              class=\"nav-item \"\n            >\n              GitHub Actions\n            </a>\n              \n            <a\n              href=\"/docs/project-structure/\"\n              class=\"nav-item \"\n            >\n              Project Structure\n            </a>\n              \n            <a\n              href=\"/docs/liquid-templates/\"\n              class=\"nav-item \"\n            >\n              Liquid Templates\n            </a>\n              \n            <a\n              href=\"/docs/performance/\"\n              class=\"nav-item \"\n            >\n              Performance Optimization\n            </a>\n              \n            <a\n              href=\"/docs/seo-guide/\"\n              class=\"nav-item \"\n            >\n              SEO Guide\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"help\"\n          >\n            <i\n              class=\"fa-solid fa-circle-question \"\n            ></i>\n            <span>Help</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-help\"\n          >\n            \n             \n            <a\n              href=\"/docs/faq/\"\n              class=\"nav-item \"\n            >\n              FAQ\n            </a>\n              \n            <a\n              href=\"/docs/troubleshooting/\"\n              class=\"nav-item \"\n            >\n              Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/accessibility/\"\n              class=\"nav-item \"\n            >\n              Accessibility Guide\n            </a>\n              \n            <a\n              href=\"/docs/common-errors/\"\n              class=\"nav-item \"\n            >\n              Common Errors & Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/browser-support/\"\n              class=\"nav-item \"\n            >\n              Browser Support\n            </a>\n             \n          </div>\n        </div>\n         \n      </nav>\n\n      <!-- Quick Links -->\n      <div class=\"sidebar-footer\">\n        <a href=\"/docs/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-home\"></i>\n          All Docs\n        </a>\n        <a href=\"/projects/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-folder\"></i>\n          Projects\n        </a>\n      </div>\n    </aside>\n\n    <!-- Sidebar Overlay (for mobile) -->\n    <div id=\"sidebar-overlay\" class=\"sidebar-overlay\"></div>\n\n    <!-- Main Content -->\n    <div class=\"docs-layout\">\n      <!-- Breadcrumbs -->\n      \n      <nav class=\"breadcrumbs\" aria-label=\"Breadcrumb\">\n        <a href=\"/\">\n          <i class=\"fa-solid fa-home\"></i>\n          Home\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a href=\"/docs/\">Docs</a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a\n          href=\"/docs-category-user-guide/\"\n        >\n          User Guide\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <span class=\"current\">Adding Modpacks</span>\n      </nav>\n      \n\n      <!-- Page Content -->\n      <main class=\"docs-content\">\n        <article><h1 id=\"adding-modpacks\">Adding Modpacks</h1>\n\n<p>Learn how to add new modpacks to your ABC showcase.</p>\n\n<h2 id=\"quick-start\">Quick Start</h2>\n\n<h3 id=\"1-locate-the-data-file\">1. Locate the Data File</h3>\n\n<p>Find <code class=\"language-plaintext highlighter-rouge\">_data/mods.json</code> in your project root.</p>\n\n<h3 id=\"2-add-modpack-entry\">2. Add Modpack Entry</h3>\n\n<p>Add your modpack to the <code class=\"language-plaintext highlighter-rouge\">modpacks</code> array:</p>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{</span><span class=\"w\">\n  </span><span class=\"nl\">\"modpacks\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"w\">\n    </span><span class=\"p\">{</span><span class=\"w\">\n      </span><span class=\"nl\">\"slug\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"your-modpack-slug\"</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"name\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"Your Modpack Name\"</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"description\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"A brief description of your modpack\"</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"icon_url\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"https://cdn.modrinth.com/data/PROJECT_ID/icon.png\"</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"downloads\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"mi\">5000</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"followers\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"mi\">150</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"categories\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"s2\">\"adventure\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"technology\"</span><span class=\"p\">],</span><span class=\"w\">\n      </span><span class=\"nl\">\"game_versions\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"s2\">\"1.20.1\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"1.19.2\"</span><span class=\"p\">],</span><span class=\"w\">\n      </span><span class=\"nl\">\"loaders\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"s2\">\"fabric\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"forge\"</span><span class=\"p\">],</span><span class=\"w\">\n      </span><span class=\"nl\">\"source_url\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"https://modrinth.com/modpack/your-modpack-slug\"</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"repository\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"https://github.com/username/your-modpack\"</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"updated_at\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"2025-12-10T10:00:00Z\"</span><span class=\"w\">\n    </span><span class=\"p\">}</span><span class=\"w\">\n  </span><span class=\"p\">]</span><span class=\"w\">\n</span><span class=\"p\">}</span><span class=\"w\">\n</span></code></pre></div></div>\n\n<h3 id=\"3-rebuild-site\">3. Rebuild Site</h3>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>bundle <span class=\"nb\">exec </span>jekyll build\n</code></pre></div></div>\n\n<h2 id=\"field-reference\">Field Reference</h2>\n\n<h3 id=\"required-fields\">Required Fields</h3>\n\n<table>\n  <thead>\n    <tr>\n      <th>Field</th>\n      <th>Type</th>\n      <th>Description</th>\n      <th>Example</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">slug</code></td>\n      <td>string</td>\n      <td>Unique identifier (URL-safe)</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">\"awesome-pack\"</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">name</code></td>\n      <td>string</td>\n      <td>Display name</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">\"Awesome Modpack\"</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">description</code></td>\n      <td>string</td>\n      <td>Brief description (1-2 sentences)</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">\"A tech-focused modpack...\"</code></td>\n    </tr>\n  </tbody>\n</table>\n\n<h3 id=\"optional-fields\">Optional Fields</h3>\n\n<table>\n  <thead>\n    <tr>\n      <th>Field</th>\n      <th>Type</th>\n      <th>Description</th>\n      <th>Example</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">icon_url</code></td>\n      <td>string</td>\n      <td>URL to 512x512 icon</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">\"https://cdn.modrinth.com/...\"</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">downloads</code></td>\n      <td>number</td>\n      <td>Total download count</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">50000</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">followers</code></td>\n      <td>number</td>\n      <td>Follower count</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">1200</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">categories</code></td>\n      <td>array</td>\n      <td>Category tags</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">[\"tech\", \"adventure\"]</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">game_versions</code></td>\n      <td>array</td>\n      <td>Supported MC versions</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">[\"1.20.1\"]</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">loaders</code></td>\n      <td>array</td>\n      <td>Mod loaders</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">[\"fabric\", \"forge\"]</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">source_url</code></td>\n      <td>string</td>\n      <td>Modrinth/CF page</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">\"https://modrinth.com/...\"</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">repository</code></td>\n      <td>string</td>\n      <td>GitHub repo URL</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">\"https://github.com/...\"</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">updated_at</code></td>\n      <td>string</td>\n      <td>Last update (ISO 8601)</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">\"2025-12-10T10:00:00Z\"</code></td>\n    </tr>\n  </tbody>\n</table>\n\n<h2 id=\"from-modrinth\">From Modrinth</h2>\n\n<h3 id=\"manual-method\">Manual Method</h3>\n\n<ol>\n  <li><strong>Find your modpack</strong> on <a href=\"https://modrinth.com/\">Modrinth</a></li>\n  <li><strong>Copy project data</strong> from the page</li>\n  <li><strong>Add to <code class=\"language-plaintext highlighter-rouge\">_data/mods.json</code></strong></li>\n</ol>\n\n<h3 id=\"automated-method\">Automated Method</h3>\n\n<p>Create a script to fetch from Modrinth API:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\"># Save as scripts/add-modpack.sh</span>\n<span class=\"c\">#!/bin/bash</span>\n\n<span class=\"nv\">SLUG</span><span class=\"o\">=</span><span class=\"nv\">$1</span>\n<span class=\"nv\">API_URL</span><span class=\"o\">=</span><span class=\"s2\">\"https://api.modrinth.com/v2/project/</span><span class=\"nv\">$SLUG</span><span class=\"s2\">\"</span>\n\n<span class=\"c\"># Fetch data</span>\n<span class=\"nv\">DATA</span><span class=\"o\">=</span><span class=\"si\">$(</span>curl <span class=\"nt\">-s</span> <span class=\"s2\">\"</span><span class=\"nv\">$API_URL</span><span class=\"s2\">\"</span><span class=\"si\">)</span>\n\n<span class=\"c\"># Extract fields</span>\n<span class=\"nv\">NAME</span><span class=\"o\">=</span><span class=\"si\">$(</span><span class=\"nb\">echo</span> <span class=\"s2\">\"</span><span class=\"nv\">$DATA</span><span class=\"s2\">\"</span> | jq <span class=\"nt\">-r</span> <span class=\"s1\">'.title'</span><span class=\"si\">)</span>\n<span class=\"nv\">DESC</span><span class=\"o\">=</span><span class=\"si\">$(</span><span class=\"nb\">echo</span> <span class=\"s2\">\"</span><span class=\"nv\">$DATA</span><span class=\"s2\">\"</span> | jq <span class=\"nt\">-r</span> <span class=\"s1\">'.description'</span><span class=\"si\">)</span>\n<span class=\"nv\">ICON</span><span class=\"o\">=</span><span class=\"si\">$(</span><span class=\"nb\">echo</span> <span class=\"s2\">\"</span><span class=\"nv\">$DATA</span><span class=\"s2\">\"</span> | jq <span class=\"nt\">-r</span> <span class=\"s1\">'.icon_url'</span><span class=\"si\">)</span>\n<span class=\"nv\">DOWNLOADS</span><span class=\"o\">=</span><span class=\"si\">$(</span><span class=\"nb\">echo</span> <span class=\"s2\">\"</span><span class=\"nv\">$DATA</span><span class=\"s2\">\"</span> | jq <span class=\"nt\">-r</span> <span class=\"s1\">'.downloads'</span><span class=\"si\">)</span>\n<span class=\"nv\">FOLLOWERS</span><span class=\"o\">=</span><span class=\"si\">$(</span><span class=\"nb\">echo</span> <span class=\"s2\">\"</span><span class=\"nv\">$DATA</span><span class=\"s2\">\"</span> | jq <span class=\"nt\">-r</span> <span class=\"s1\">'.followers'</span><span class=\"si\">)</span>\n\n<span class=\"nb\">echo</span> <span class=\"s2\">\"Adding: </span><span class=\"nv\">$NAME</span><span class=\"s2\">\"</span>\n\n<span class=\"c\"># TODO: Append to _data/mods.json</span>\n<span class=\"c\"># (Implementation left as exercise)</span>\n</code></pre></div></div>\n\n<p>Usage:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nb\">chmod</span> +x scripts/add-modpack.sh\n./scripts/add-modpack.sh your-modpack-slug\n</code></pre></div></div>\n\n<h3 id=\"using-nodejs\">Using Node.js</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// scripts/add-modpack.js</span>\n<span class=\"kd\">const</span> <span class=\"nx\">fs</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">fs</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n\n<span class=\"k\">async</span> <span class=\"kd\">function</span> <span class=\"nx\">addModpack</span><span class=\"p\">(</span><span class=\"nx\">slug</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"kd\">const</span> <span class=\"nx\">response</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"nx\">fetch</span><span class=\"p\">(</span><span class=\"s2\">`https://api.modrinth.com/v2/project/</span><span class=\"p\">${</span><span class=\"nx\">slug</span><span class=\"p\">}</span><span class=\"s2\">`</span><span class=\"p\">);</span>\n  <span class=\"kd\">const</span> <span class=\"nx\">data</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"nx\">response</span><span class=\"p\">.</span><span class=\"nx\">json</span><span class=\"p\">();</span>\n\n  <span class=\"kd\">const</span> <span class=\"nx\">modpack</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"na\">slug</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">slug</span><span class=\"p\">,</span>\n    <span class=\"na\">name</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">title</span><span class=\"p\">,</span>\n    <span class=\"na\">description</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">description</span><span class=\"p\">,</span>\n    <span class=\"na\">icon_url</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">icon_url</span><span class=\"p\">,</span>\n    <span class=\"na\">downloads</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">downloads</span><span class=\"p\">,</span>\n    <span class=\"na\">followers</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">followers</span><span class=\"p\">,</span>\n    <span class=\"na\">categories</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">categories</span><span class=\"p\">,</span>\n    <span class=\"na\">game_versions</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">game_versions</span><span class=\"p\">,</span>\n    <span class=\"na\">loaders</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">loaders</span><span class=\"p\">,</span>\n    <span class=\"na\">source_url</span><span class=\"p\">:</span> <span class=\"s2\">`https://modrinth.com/modpack/</span><span class=\"p\">${</span><span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">slug</span><span class=\"p\">}</span><span class=\"s2\">`</span><span class=\"p\">,</span>\n    <span class=\"na\">repository</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">source_url</span><span class=\"p\">,</span>\n    <span class=\"na\">updated_at</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">updated</span><span class=\"p\">,</span>\n  <span class=\"p\">};</span>\n\n  <span class=\"c1\">// Read existing data</span>\n  <span class=\"kd\">const</span> <span class=\"nx\">modsData</span> <span class=\"o\">=</span> <span class=\"nx\">JSON</span><span class=\"p\">.</span><span class=\"nx\">parse</span><span class=\"p\">(</span><span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">readFileSync</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">_data/mods.json</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">utf8</span><span class=\"dl\">\"</span><span class=\"p\">));</span>\n\n  <span class=\"c1\">// Add new modpack</span>\n  <span class=\"nx\">modsData</span><span class=\"p\">.</span><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">push</span><span class=\"p\">(</span><span class=\"nx\">modpack</span><span class=\"p\">);</span>\n\n  <span class=\"c1\">// Write back</span>\n  <span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">writeFileSync</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">_data/mods.json</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"nx\">JSON</span><span class=\"p\">.</span><span class=\"nx\">stringify</span><span class=\"p\">(</span><span class=\"nx\">modsData</span><span class=\"p\">,</span> <span class=\"kc\">null</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">));</span>\n\n  <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"s2\">`Added: </span><span class=\"p\">${</span><span class=\"nx\">modpack</span><span class=\"p\">.</span><span class=\"nx\">name</span><span class=\"p\">}</span><span class=\"s2\">`</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n\n<span class=\"c1\">// Usage: node scripts/add-modpack.js your-modpack-slug</span>\n<span class=\"kd\">const</span> <span class=\"nx\">slug</span> <span class=\"o\">=</span> <span class=\"nx\">process</span><span class=\"p\">.</span><span class=\"nx\">argv</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">];</span>\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">slug</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nx\">addModpack</span><span class=\"p\">(</span><span class=\"nx\">slug</span><span class=\"p\">);</span>\n<span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n  <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">Usage: node add-modpack.js &lt;slug&gt;</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Run it:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>node scripts/add-modpack.js awesome-pack\n</code></pre></div></div>\n\n<h2 id=\"custom-icons\">Custom Icons</h2>\n\n<h3 id=\"upload-to-repository\">Upload to Repository</h3>\n\n<ol>\n  <li><strong>Add icon</strong> to <code class=\"language-plaintext highlighter-rouge\">assets/images/modpacks/</code></li>\n  <li><strong>Reference in JSON</strong>:</li>\n</ol>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{</span><span class=\"w\">\n  </span><span class=\"nl\">\"icon_url\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"/assets/images/modpacks/my-pack-icon.png\"</span><span class=\"w\">\n</span><span class=\"p\">}</span><span class=\"w\">\n</span></code></pre></div></div>\n\n<h3 id=\"requirements\">Requirements</h3>\n\n<ul>\n  <li><strong>Format</strong>: PNG or WebP</li>\n  <li><strong>Size</strong>: 512x512px recommended</li>\n  <li><strong>Max file size</strong>: 500KB</li>\n  <li><strong>Transparency</strong>: Supported</li>\n</ul>\n\n<h3 id=\"optimize-icons\">Optimize Icons</h3>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\"># Resize to 512x512</span>\nmagick convert original.png <span class=\"nt\">-resize</span> 512x512 icon.png\n\n<span class=\"c\"># Optimize PNG</span>\npngquant <span class=\"nt\">--quality</span> 65-80 icon.png\n\n<span class=\"c\"># Convert to WebP</span>\nmagick convert icon.png <span class=\"nt\">-quality</span> 80 icon.webp\n</code></pre></div></div>\n\n<h2 id=\"categories\">Categories</h2>\n\n<h3 id=\"available-categories\">Available Categories</h3>\n\n<p>Use these standard categories:</p>\n\n<ul>\n  <li><code class=\"language-plaintext highlighter-rouge\">adventure</code> - Adventure &amp; exploration</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">technology</code> - Tech &amp; automation</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">magic</code> - Magic &amp; spells</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">decoration</code> - Building &amp; decoration</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">utility</code> - Quality of life</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">optimization</code> - Performance mods</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">cursed</code> - Experimental/chaotic</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">kitchen-sink</code> - Everything included</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">lightweight</code> - Minimal modpacks</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">multiplayer</code> - Server-friendly</li>\n</ul>\n\n<h3 id=\"custom-categories\">Custom Categories</h3>\n\n<p>Add your own:</p>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{</span><span class=\"w\">\n  </span><span class=\"nl\">\"categories\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"s2\">\"custom-category\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"another-category\"</span><span class=\"p\">]</span><span class=\"w\">\n</span><span class=\"p\">}</span><span class=\"w\">\n</span></code></pre></div></div>\n\n<p>Style them in CSS:</p>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">.pill</span><span class=\"o\">[</span><span class=\"nt\">data-category</span><span class=\"o\">=</span><span class=\"s1\">\"custom-category\"</span><span class=\"o\">]</span> <span class=\"p\">{</span>\n  <span class=\"py\">--pill-bg</span><span class=\"p\">:</span> <span class=\"n\">rgba</span><span class=\"p\">(</span><span class=\"m\">255</span><span class=\"p\">,</span> <span class=\"m\">87</span><span class=\"p\">,</span> <span class=\"m\">34</span><span class=\"p\">,</span> <span class=\"m\">0.15</span><span class=\"p\">);</span>\n  <span class=\"py\">--pill-text</span><span class=\"p\">:</span> <span class=\"m\">#ff5722</span><span class=\"p\">;</span>\n  <span class=\"py\">--pill-border</span><span class=\"p\">:</span> <span class=\"m\">#ff5722</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"bulk-import\">Bulk Import</h2>\n\n<h3 id=\"from-json-file\">From JSON File</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// scripts/bulk-import.js</span>\n<span class=\"kd\">const</span> <span class=\"nx\">fs</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">fs</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n\n<span class=\"kd\">const</span> <span class=\"nx\">newModpacks</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n  <span class=\"p\">{</span> <span class=\"na\">slug</span><span class=\"p\">:</span> <span class=\"dl\">\"</span><span class=\"s2\">pack-1</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"na\">name</span><span class=\"p\">:</span> <span class=\"dl\">\"</span><span class=\"s2\">Pack One</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"na\">description</span><span class=\"p\">:</span> <span class=\"dl\">\"</span><span class=\"s2\">Description...</span><span class=\"dl\">\"</span> <span class=\"p\">},</span>\n  <span class=\"p\">{</span> <span class=\"na\">slug</span><span class=\"p\">:</span> <span class=\"dl\">\"</span><span class=\"s2\">pack-2</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"na\">name</span><span class=\"p\">:</span> <span class=\"dl\">\"</span><span class=\"s2\">Pack Two</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"na\">description</span><span class=\"p\">:</span> <span class=\"dl\">\"</span><span class=\"s2\">Description...</span><span class=\"dl\">\"</span> <span class=\"p\">},</span>\n  <span class=\"c1\">// ... more modpacks</span>\n<span class=\"p\">];</span>\n\n<span class=\"kd\">const</span> <span class=\"nx\">modsData</span> <span class=\"o\">=</span> <span class=\"nx\">JSON</span><span class=\"p\">.</span><span class=\"nx\">parse</span><span class=\"p\">(</span><span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">readFileSync</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">_data/mods.json</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">utf8</span><span class=\"dl\">\"</span><span class=\"p\">));</span>\n<span class=\"nx\">modsData</span><span class=\"p\">.</span><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">push</span><span class=\"p\">(...</span><span class=\"nx\">newModpacks</span><span class=\"p\">);</span>\n<span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">writeFileSync</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">_data/mods.json</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"nx\">JSON</span><span class=\"p\">.</span><span class=\"nx\">stringify</span><span class=\"p\">(</span><span class=\"nx\">modsData</span><span class=\"p\">,</span> <span class=\"kc\">null</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">));</span>\n\n<span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"s2\">`Imported </span><span class=\"p\">${</span><span class=\"nx\">newModpacks</span><span class=\"p\">.</span><span class=\"nx\">length</span><span class=\"p\">}</span><span class=\"s2\"> modpacks`</span><span class=\"p\">);</span>\n</code></pre></div></div>\n\n<h3 id=\"from-csv\">From CSV</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// scripts/import-csv.js</span>\n<span class=\"kd\">const</span> <span class=\"nx\">fs</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">fs</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n<span class=\"kd\">const</span> <span class=\"nx\">csv</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">csv-parser</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n\n<span class=\"kd\">const</span> <span class=\"nx\">modpacks</span> <span class=\"o\">=</span> <span class=\"p\">[];</span>\n\n<span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">createReadStream</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">modpacks.csv</span><span class=\"dl\">\"</span><span class=\"p\">)</span>\n  <span class=\"p\">.</span><span class=\"nx\">pipe</span><span class=\"p\">(</span><span class=\"nx\">csv</span><span class=\"p\">())</span>\n  <span class=\"p\">.</span><span class=\"nx\">on</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">data</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">row</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">push</span><span class=\"p\">({</span>\n      <span class=\"na\">slug</span><span class=\"p\">:</span> <span class=\"nx\">row</span><span class=\"p\">.</span><span class=\"nx\">slug</span><span class=\"p\">,</span>\n      <span class=\"na\">name</span><span class=\"p\">:</span> <span class=\"nx\">row</span><span class=\"p\">.</span><span class=\"nx\">name</span><span class=\"p\">,</span>\n      <span class=\"na\">description</span><span class=\"p\">:</span> <span class=\"nx\">row</span><span class=\"p\">.</span><span class=\"nx\">description</span><span class=\"p\">,</span>\n      <span class=\"na\">icon_url</span><span class=\"p\">:</span> <span class=\"nx\">row</span><span class=\"p\">.</span><span class=\"nx\">icon_url</span><span class=\"p\">,</span>\n      <span class=\"na\">downloads</span><span class=\"p\">:</span> <span class=\"nb\">parseInt</span><span class=\"p\">(</span><span class=\"nx\">row</span><span class=\"p\">.</span><span class=\"nx\">downloads</span><span class=\"p\">)</span> <span class=\"o\">||</span> <span class=\"mi\">0</span><span class=\"p\">,</span>\n      <span class=\"na\">categories</span><span class=\"p\">:</span> <span class=\"nx\">row</span><span class=\"p\">.</span><span class=\"nx\">categories</span> <span class=\"p\">?</span> <span class=\"nx\">row</span><span class=\"p\">.</span><span class=\"nx\">categories</span><span class=\"p\">.</span><span class=\"nx\">split</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">,</span><span class=\"dl\">\"</span><span class=\"p\">)</span> <span class=\"p\">:</span> <span class=\"p\">[],</span>\n    <span class=\"p\">});</span>\n  <span class=\"p\">})</span>\n  <span class=\"p\">.</span><span class=\"nx\">on</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">end</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"p\">()</span> <span class=\"o\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"kd\">const</span> <span class=\"nx\">modsData</span> <span class=\"o\">=</span> <span class=\"nx\">JSON</span><span class=\"p\">.</span><span class=\"nx\">parse</span><span class=\"p\">(</span><span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">readFileSync</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">_data/mods.json</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">utf8</span><span class=\"dl\">\"</span><span class=\"p\">));</span>\n    <span class=\"nx\">modsData</span><span class=\"p\">.</span><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">push</span><span class=\"p\">(...</span><span class=\"nx\">modpacks</span><span class=\"p\">);</span>\n    <span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">writeFileSync</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">_data/mods.json</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"nx\">JSON</span><span class=\"p\">.</span><span class=\"nx\">stringify</span><span class=\"p\">(</span><span class=\"nx\">modsData</span><span class=\"p\">,</span> <span class=\"kc\">null</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">));</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"s2\">`Imported </span><span class=\"p\">${</span><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">length</span><span class=\"p\">}</span><span class=\"s2\"> modpacks`</span><span class=\"p\">);</span>\n  <span class=\"p\">});</span>\n</code></pre></div></div>\n\n<p>CSV format:</p>\n\n<pre><code class=\"language-csv\">slug,name,description,icon_url,downloads,categories\nawesome-pack,Awesome Pack,A great modpack,https://...,5000,\"tech,adventure\"\n</code></pre>\n\n<h2 id=\"sorting--ordering\">Sorting &amp; Ordering</h2>\n\n<h3 id=\"sort-by-downloads\">Sort by Downloads</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// In JavaScript rendering</span>\n<span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">sort</span><span class=\"p\">((</span><span class=\"nx\">a</span><span class=\"p\">,</span> <span class=\"nx\">b</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">downloads</span> <span class=\"o\">-</span> <span class=\"nx\">a</span><span class=\"p\">.</span><span class=\"nx\">downloads</span><span class=\"p\">);</span>\n</code></pre></div></div>\n\n<h3 id=\"sort-alphabetically\">Sort Alphabetically</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">sort</span><span class=\"p\">((</span><span class=\"nx\">a</span><span class=\"p\">,</span> <span class=\"nx\">b</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"nx\">a</span><span class=\"p\">.</span><span class=\"nx\">name</span><span class=\"p\">.</span><span class=\"nx\">localeCompare</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">name</span><span class=\"p\">));</span>\n</code></pre></div></div>\n\n<h3 id=\"sort-by-update-date\">Sort by Update Date</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">sort</span><span class=\"p\">((</span><span class=\"nx\">a</span><span class=\"p\">,</span> <span class=\"nx\">b</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"k\">new</span> <span class=\"nb\">Date</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">updated_at</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"k\">new</span> <span class=\"nb\">Date</span><span class=\"p\">(</span><span class=\"nx\">a</span><span class=\"p\">.</span><span class=\"nx\">updated_at</span><span class=\"p\">));</span>\n</code></pre></div></div>\n\n<h3 id=\"custom-order\">Custom Order</h3>\n\n<p>Add <code class=\"language-plaintext highlighter-rouge\">order</code> field:</p>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{</span><span class=\"w\">\n  </span><span class=\"nl\">\"slug\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"featured-pack\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"name\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"Featured Pack\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"order\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"w\">\n</span><span class=\"p\">}</span><span class=\"w\">\n</span></code></pre></div></div>\n\n<p>Sort by order:</p>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">sort</span><span class=\"p\">((</span><span class=\"nx\">a</span><span class=\"p\">,</span> <span class=\"nx\">b</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"p\">(</span><span class=\"nx\">a</span><span class=\"p\">.</span><span class=\"nx\">order</span> <span class=\"o\">||</span> <span class=\"mi\">999</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">order</span> <span class=\"o\">||</span> <span class=\"mi\">999</span><span class=\"p\">));</span>\n</code></pre></div></div>\n\n<h2 id=\"validation\">Validation</h2>\n\n<h3 id=\"validate-json\">Validate JSON</h3>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\"># Check JSON is valid</span>\n<span class=\"nb\">cat </span>_data/mods.json | python <span class=\"nt\">-m</span> json.tool\n\n<span class=\"c\"># Or with jq</span>\njq <span class=\"s1\">'.'</span> _data/mods.json\n\n<span class=\"c\"># Or with Node.js</span>\nnode <span class=\"nt\">-e</span> <span class=\"s2\">\"console.log(JSON.parse(require('fs').readFileSync('_data/mods.json', 'utf8')))\"</span>\n</code></pre></div></div>\n\n<h3 id=\"validate-schema\">Validate Schema</h3>\n\n<p>Create validation script:</p>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// scripts/validate-mods.js</span>\n<span class=\"kd\">const</span> <span class=\"nx\">fs</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">fs</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n\n<span class=\"kd\">const</span> <span class=\"nx\">modsData</span> <span class=\"o\">=</span> <span class=\"nx\">JSON</span><span class=\"p\">.</span><span class=\"nx\">parse</span><span class=\"p\">(</span><span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">readFileSync</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">_data/mods.json</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">utf8</span><span class=\"dl\">\"</span><span class=\"p\">));</span>\n\n<span class=\"nx\">modsData</span><span class=\"p\">.</span><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">forEach</span><span class=\"p\">((</span><span class=\"nx\">mod</span><span class=\"p\">,</span> <span class=\"nx\">index</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Check required fields</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nx\">mod</span><span class=\"p\">.</span><span class=\"nx\">slug</span><span class=\"p\">)</span> <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">(</span><span class=\"s2\">`Modpack </span><span class=\"p\">${</span><span class=\"nx\">index</span><span class=\"p\">}</span><span class=\"s2\">: Missing slug`</span><span class=\"p\">);</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nx\">mod</span><span class=\"p\">.</span><span class=\"nx\">name</span><span class=\"p\">)</span> <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">(</span><span class=\"s2\">`Modpack </span><span class=\"p\">${</span><span class=\"nx\">index</span><span class=\"p\">}</span><span class=\"s2\">: Missing name`</span><span class=\"p\">);</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nx\">mod</span><span class=\"p\">.</span><span class=\"nx\">description</span><span class=\"p\">)</span> <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">(</span><span class=\"s2\">`Modpack </span><span class=\"p\">${</span><span class=\"nx\">index</span><span class=\"p\">}</span><span class=\"s2\">: Missing description`</span><span class=\"p\">);</span>\n\n  <span class=\"c1\">// Check slug format</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">mod</span><span class=\"p\">.</span><span class=\"nx\">slug</span> <span class=\"o\">&amp;&amp;</span> <span class=\"o\">!</span><span class=\"sr\">/^</span><span class=\"se\">[</span><span class=\"sr\">a-z0-9-</span><span class=\"se\">]</span><span class=\"sr\">+$/</span><span class=\"p\">.</span><span class=\"nx\">test</span><span class=\"p\">(</span><span class=\"nx\">mod</span><span class=\"p\">.</span><span class=\"nx\">slug</span><span class=\"p\">))</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">(</span><span class=\"s2\">`Modpack </span><span class=\"p\">${</span><span class=\"nx\">index</span><span class=\"p\">}</span><span class=\"s2\">: Invalid slug format`</span><span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n\n  <span class=\"c1\">// Check downloads type</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">mod</span><span class=\"p\">.</span><span class=\"nx\">downloads</span> <span class=\"o\">&amp;&amp;</span> <span class=\"k\">typeof</span> <span class=\"nx\">mod</span><span class=\"p\">.</span><span class=\"nx\">downloads</span> <span class=\"o\">!==</span> <span class=\"dl\">\"</span><span class=\"s2\">number</span><span class=\"dl\">\"</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">(</span><span class=\"s2\">`Modpack </span><span class=\"p\">${</span><span class=\"nx\">index</span><span class=\"p\">}</span><span class=\"s2\">: downloads must be a number`</span><span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">});</span>\n\n<span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">Validation complete</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n</code></pre></div></div>\n\n<p>Run:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>node scripts/validate-mods.js\n</code></pre></div></div>\n\n<h2 id=\"auto-update-from-modrinth\">Auto-Update from Modrinth</h2>\n\n<p>Set up automatic updates:</p>\n\n<div class=\"language-yaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\"># .github/workflows/update-mods.yml</span>\n<span class=\"na\">name</span><span class=\"pi\">:</span> <span class=\"s\">Update Modpack Data</span>\n\n<span class=\"na\">on</span><span class=\"pi\">:</span>\n  <span class=\"na\">schedule</span><span class=\"pi\">:</span>\n    <span class=\"pi\">-</span> <span class=\"na\">cron</span><span class=\"pi\">:</span> <span class=\"s2\">\"</span><span class=\"s\">0</span><span class=\"nv\"> </span><span class=\"s\">0</span><span class=\"nv\"> </span><span class=\"s\">*</span><span class=\"nv\"> </span><span class=\"s\">*</span><span class=\"nv\"> </span><span class=\"s\">*\"</span> <span class=\"c1\"># Daily at midnight</span>\n  <span class=\"na\">workflow_dispatch</span><span class=\"pi\">:</span>\n\n<span class=\"na\">jobs</span><span class=\"pi\">:</span>\n  <span class=\"na\">update</span><span class=\"pi\">:</span>\n    <span class=\"na\">runs-on</span><span class=\"pi\">:</span> <span class=\"s\">ubuntu-latest</span>\n    <span class=\"na\">steps</span><span class=\"pi\">:</span>\n      <span class=\"pi\">-</span> <span class=\"na\">uses</span><span class=\"pi\">:</span> <span class=\"s\">actions/checkout@v4</span>\n\n      <span class=\"pi\">-</span> <span class=\"na\">name</span><span class=\"pi\">:</span> <span class=\"s\">Setup Node</span>\n        <span class=\"na\">uses</span><span class=\"pi\">:</span> <span class=\"s\">actions/setup-node@v4</span>\n        <span class=\"na\">with</span><span class=\"pi\">:</span>\n          <span class=\"na\">node-version</span><span class=\"pi\">:</span> <span class=\"s2\">\"</span><span class=\"s\">18\"</span>\n\n      <span class=\"pi\">-</span> <span class=\"na\">name</span><span class=\"pi\">:</span> <span class=\"s\">Update data</span>\n        <span class=\"na\">run</span><span class=\"pi\">:</span> <span class=\"s\">node scripts/update-modrinth.js</span>\n\n      <span class=\"pi\">-</span> <span class=\"na\">name</span><span class=\"pi\">:</span> <span class=\"s\">Commit changes</span>\n        <span class=\"na\">uses</span><span class=\"pi\">:</span> <span class=\"s\">stefanzweifel/git-auto-commit-action@v5</span>\n        <span class=\"na\">with</span><span class=\"pi\">:</span>\n          <span class=\"na\">commit_message</span><span class=\"pi\">:</span> <span class=\"s2\">\"</span><span class=\"s\">chore:</span><span class=\"nv\"> </span><span class=\"s\">update</span><span class=\"nv\"> </span><span class=\"s\">modpack</span><span class=\"nv\"> </span><span class=\"s\">data\"</span>\n          <span class=\"na\">file_pattern</span><span class=\"pi\">:</span> <span class=\"s2\">\"</span><span class=\"s\">_data/mods.json\"</span>\n</code></pre></div></div>\n\n<h2 id=\"troubleshooting\">Troubleshooting</h2>\n\n<h3 id=\"issue-modpack-not-showing\">Issue: Modpack Not Showing</h3>\n\n<p><strong>Check</strong>:</p>\n\n<ol>\n  <li>JSON is valid (no syntax errors)</li>\n  <li>Required fields present (<code class=\"language-plaintext highlighter-rouge\">slug</code>, <code class=\"language-plaintext highlighter-rouge\">name</code>, <code class=\"language-plaintext highlighter-rouge\">description</code>)</li>\n  <li>Rebuild site: <code class=\"language-plaintext highlighter-rouge\">bundle exec jekyll build</code></li>\n  <li>Check browser console for errors</li>\n</ol>\n\n<h3 id=\"issue-icon-not-displaying\">Issue: Icon Not Displaying</h3>\n\n<p><strong>Solutions</strong>:</p>\n\n<ul>\n  <li>Verify <code class=\"language-plaintext highlighter-rouge\">icon_url</code> is correct</li>\n  <li>Check image exists and is accessible</li>\n  <li>Try full URL instead of relative path</li>\n  <li>Ensure image is not too large (&lt; 1MB)</li>\n</ul>\n\n<h3 id=\"issue-duplicate-slugs\">Issue: Duplicate Slugs</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// Find duplicates</span>\n<span class=\"kd\">const</span> <span class=\"nx\">slugs</span> <span class=\"o\">=</span> <span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">map</span><span class=\"p\">((</span><span class=\"nx\">m</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"nx\">m</span><span class=\"p\">.</span><span class=\"nx\">slug</span><span class=\"p\">);</span>\n<span class=\"kd\">const</span> <span class=\"nx\">duplicates</span> <span class=\"o\">=</span> <span class=\"nx\">slugs</span><span class=\"p\">.</span><span class=\"nx\">filter</span><span class=\"p\">((</span><span class=\"nx\">s</span><span class=\"p\">,</span> <span class=\"nx\">i</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"nx\">slugs</span><span class=\"p\">.</span><span class=\"nx\">indexOf</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span> <span class=\"o\">!==</span> <span class=\"nx\">i</span><span class=\"p\">);</span>\n<span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">Duplicates:</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"nx\">duplicates</span><span class=\"p\">);</span>\n</code></pre></div></div>\n\n<h2 id=\"best-practices\">Best Practices</h2>\n\n<ol>\n  <li><strong>Use descriptive slugs</strong>: <code class=\"language-plaintext highlighter-rouge\">create-tech-pack</code> not <code class=\"language-plaintext highlighter-rouge\">pack1</code></li>\n  <li><strong>Keep descriptions concise</strong>: 1-2 sentences</li>\n  <li><strong>Optimize icons</strong>: 512x512px, &lt; 500KB</li>\n  <li><strong>Include all relevant tags</strong>: Helps with filtering</li>\n  <li><strong>Update regularly</strong>: Keep download counts fresh</li>\n  <li><strong>Validate before committing</strong>: Catch errors early</li>\n  <li><strong>Use semantic versioning</strong>: For game_versions</li>\n  <li><strong>Link to sources</strong>: Always include <code class=\"language-plaintext highlighter-rouge\">source_url</code></li>\n</ol>\n\n<h2 id=\"next-steps\">Next Steps</h2>\n\n<ul>\n  <li><a href=\"content-guidelines.html\">Content Guidelines</a> - Writing standards</li>\n  <li><a href=\"api-reference.html\">API Reference</a> - Data structure details</li>\n  <li><a href=\"github-actions.html\">GitHub Actions</a> - Automate updates</li>\n</ul>\n</article>\n\n        <section\n          class=\"feedback-card\"\n          id=\"feedback-card\"\n          aria-label=\"Page feedback\"\n        >\n          <div class=\"feedback-header\">\n            <div>\n              <p class=\"feedback-kicker\">Feedback</p>\n              <h3>Was this page helpful?</h3>\n              <p class=\"feedback-subtext\">\n                Share quick feedback to improve these docs.\n              </p>\n            </div>\n            <div class=\"feedback-badges\" aria-label=\"Applies to versions\">\n                  \n              <span class=\"version-badge\" aria-label=\"Minecraft 1.21.x\"\n                >1.21.x</span\n              >\n               \n            </div>\n          </div>\n\n          <div class=\"feedback-actions\" role=\"group\" aria-label=\"Helpful?\">\n            <button type=\"button\" class=\"feedback-btn yes\" data-feedback=\"yes\">\n              <i class=\"fa-solid fa-thumbs-up\"></i>\n              Yes\n            </button>\n            <button type=\"button\" class=\"feedback-btn no\" data-feedback=\"no\">\n              <i class=\"fa-solid fa-thumbs-down\"></i>\n              No\n            </button>\n          </div>\n\n          <div class=\"feedback-followup\" id=\"feedback-followup\" hidden>\n            <label for=\"feedback-notes\">What can we improve?</label>\n            <textarea\n              id=\"feedback-notes\"\n              rows=\"3\"\n              placeholder=\"Optional: missing steps, unclear wording, broken links\"\n            ></textarea>\n            <button type=\"button\" class=\"feedback-submit\" id=\"feedback-submit\">\n              <i class=\"fa-solid fa-paper-plane\"></i>\n              Send feedback\n            </button>\n          </div>\n\n          <p\n            class=\"feedback-status\"\n            id=\"feedback-status\"\n            role=\"status\"\n            aria-live=\"polite\"\n          ></p>\n        </section>\n\n        <!-- Page Navigation (Prev/Next) -->\n                                                 \n      </main>\n\n      <!-- Table of Contents (optional) -->\n      <aside class=\"docs-toc\">\n        <div class=\"toc-header\">\n          <h3>On This Page</h3>\n        </div>\n        <nav id=\"toc-nav\" class=\"toc-nav\">\n          <!-- Generated by JavaScript -->\n        </nav>\n\n        <!-- Theme Toggle in TOC -->\n        <button\n          id=\"theme-toggle-docs\"\n          class=\"theme-toggle\"\n          aria-label=\"Toggle theme\"\n        >\n          <i class=\"fa-solid fa-sun\"></i>\n          <i class=\"fa-solid fa-moon\"></i>\n        </button>\n      </aside>\n    </div>\n\n    <script>\n      // Theme Toggle\n      const themeToggle = document.getElementById(\"theme-toggle-docs\");\n      themeToggle?.addEventListener(\"click\", () => {\n        const current = document.documentElement.getAttribute(\"data-theme\");\n        const next = current === \"light\" ? \"dark\" : \"light\";\n        document.documentElement.setAttribute(\"data-theme\", next);\n        localStorage.setItem(\"theme\", next);\n      });\n\n      // Mobile Sidebar Toggle\n      const mobileToggle = document.getElementById(\"mobile-sidebar-toggle\");\n      const sidebar = document.getElementById(\"docs-sidebar\");\n      const overlay = document.getElementById(\"sidebar-overlay\");\n      const sidebarClose = document.getElementById(\"sidebar-close\");\n\n      function toggleSidebar() {\n        sidebar.classList.toggle(\"open\");\n        overlay.classList.toggle(\"active\");\n        document.body.style.overflow = sidebar.classList.contains(\"open\")\n          ? \"hidden\"\n          : \"\";\n      }\n\n      mobileToggle?.addEventListener(\"click\", toggleSidebar);\n      overlay?.addEventListener(\"click\", toggleSidebar);\n      sidebarClose?.addEventListener(\"click\", toggleSidebar);\n\n      // Category Toggle\n      document.querySelectorAll(\".category-toggle\").forEach((toggle) => {\n        toggle.addEventListener(\"click\", () => {\n          const category = toggle.dataset.category;\n          const items = document.getElementById(`category-${category}`);\n          toggle.classList.toggle(\"active\");\n          items.classList.toggle(\"expanded\");\n        });\n      });\n\n      // Generate Table of Contents\n      const content = document.querySelector(\".docs-content article\");\n      const tocNav = document.getElementById(\"toc-nav\");\n\n      if (content && tocNav) {\n        const headings = content.querySelectorAll(\"h2, h3\");\n\n        if (headings.length > 0) {\n          headings.forEach((heading, index) => {\n            // Add ID if not present\n            if (!heading.id) {\n              heading.id = heading.textContent\n                .toLowerCase()\n                .replace(/[^a-z0-9]+/g, \"-\")\n                .replace(/^-|-$/g, \"\");\n            }\n\n            const link = document.createElement(\"a\");\n            link.href = `#${heading.id}`;\n            link.textContent = heading.textContent;\n            link.className = `toc-link toc-${heading.tagName.toLowerCase()}`;\n            tocNav.appendChild(link);\n          });\n\n          // Highlight current section\n          const observer = new IntersectionObserver(\n            (entries) => {\n              entries.forEach((entry) => {\n                if (entry.isIntersecting) {\n                  const id = entry.target.id;\n                  tocNav.querySelectorAll(\".toc-link\").forEach((link) => {\n                    link.classList.toggle(\n                      \"active\",\n                      link.getAttribute(\"href\") === `#${id}`\n                    );\n                  });\n                }\n              });\n            },\n            { rootMargin: \"-20% 0px -80% 0px\" }\n          );\n\n          headings.forEach((heading) => observer.observe(heading));\n        }\n      }\n\n      // Sidebar Search\n      const sidebarSearch = document.getElementById(\"sidebar-search\");\n      sidebarSearch?.addEventListener(\"input\", (e) => {\n        const query = e.target.value.toLowerCase();\n        const items = document.querySelectorAll(\".nav-item\");\n\n        items.forEach((item) => {\n          const text = item.textContent.toLowerCase();\n          const matches = text.includes(query);\n          item.style.display = matches || !query ? \"\" : \"none\";\n\n          // Expand category if item matches\n          if (matches && query) {\n            const category = item.closest(\".category-items\");\n            const toggle = category?.previousElementSibling;\n            category?.classList.add(\"expanded\");\n            toggle?.classList.add(\"active\");\n          }\n        });\n      });\n\n      // Docs micro-feedback (local only)\n      const feedbackCard = document.getElementById(\"feedback-card\");\n      const feedbackButtons = document.querySelectorAll(\".feedback-btn\");\n      const feedbackFollowup = document.getElementById(\"feedback-followup\");\n      const feedbackSubmit = document.getElementById(\"feedback-submit\");\n      const feedbackStatus = document.getElementById(\"feedback-status\");\n      const feedbackNotes = document.getElementById(\"feedback-notes\");\n      const feedbackStorageKey = `docs-feedback:${window.location.pathname}`;\n\n      function completeFeedback(message) {\n        if (feedbackCard) feedbackCard.classList.add(\"feedback-complete\");\n        if (feedbackFollowup) feedbackFollowup.hidden = true;\n        if (feedbackStatus) feedbackStatus.textContent = message;\n        try {\n          localStorage.setItem(feedbackStorageKey, \"submitted\");\n        } catch (err) {\n          console.warn(\"Feedback storage failed\", err);\n        }\n      }\n\n      function maybeDisableFeedback() {\n        let stored = null;\n        try {\n          stored = localStorage.getItem(feedbackStorageKey);\n        } catch (err) {\n          console.warn(\"Feedback storage read failed\", err);\n        }\n\n        if (stored && feedbackCard) {\n          feedbackCard.classList.add(\"feedback-complete\");\n          if (feedbackFollowup) feedbackFollowup.hidden = true;\n          if (feedbackStatus)\n            feedbackStatus.textContent = \"Thanks—feedback already recorded.\";\n        }\n      }\n\n      feedbackButtons.forEach((btn) => {\n        btn.addEventListener(\"click\", () => {\n          const value = btn.dataset.feedback;\n          if (value === \"no\") {\n            if (feedbackFollowup) feedbackFollowup.hidden = false;\n            if (feedbackStatus)\n              feedbackStatus.textContent = \"Tell us what to improve.\";\n          } else {\n            completeFeedback(\"Thanks for the feedback!\");\n          }\n        });\n      });\n\n      feedbackSubmit?.addEventListener(\"click\", () => {\n        const note = feedbackNotes?.value?.trim();\n        const suffix = note ? \" We will review your note.\" : \"\";\n        completeFeedback(`Got it!${suffix}`);\n      });\n\n      maybeDisableFeedback();\n    </script>\n  </body>\n</html>\n","<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"dark\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>\n      API Reference | Minecraft Mods & Packs Showcase\n    </title>\n\n    <!-- Stylesheets -->\n    <link rel=\"stylesheet\" href=\"/assets/css/main.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/layout.css\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/modpacks.css\"\n    />\n    <link rel=\"stylesheet\" href=\"/assets/css/docs.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n    />\n\n    <script>\n      if (!document.body) {\n        console.warn(\"Body not ready, skipping preloader\");\n      } else {\n        window.addEventListener(\"load\", () => {\n          document.body.classList.add(\"loaded\");\n        });\n      }\n\n      const savedTheme = localStorage.getItem(\"theme\") || \"dark\";\n      document.documentElement.setAttribute(\"data-theme\", savedTheme);\n    </script>\n  </head>\n  <body>\n    <!-- Preloader -->\n    <div class=\"preloader\">\n      <div class=\"spinner\"></div>\n    </div>\n\n    <!-- Mobile Menu Toggle -->\n    <button\n      id=\"mobile-sidebar-toggle\"\n      class=\"mobile-sidebar-toggle\"\n      aria-label=\"Toggle sidebar\"\n    >\n      <i class=\"fa-solid fa-bars\"></i>\n    </button>\n\n    <!-- Docs Sidebar -->\n    <aside id=\"docs-sidebar\" class=\"docs-sidebar\">\n      <div class=\"sidebar-header\">\n        <a href=\"/\" class=\"sidebar-logo\">\n          <i class=\"fa-solid fa-cube\"></i>\n          <span>Minecraft Mods & Packs Showcase</span>\n        </a>\n        <button\n          id=\"sidebar-close\"\n          class=\"sidebar-close\"\n          aria-label=\"Close sidebar\"\n        >\n          <i class=\"fa-solid fa-times\"></i>\n        </button>\n      </div>\n\n      <!-- Search in Sidebar -->\n      <div class=\"sidebar-search\">\n        <input\n          type=\"search\"\n          id=\"sidebar-search\"\n          placeholder=\"Search docs...\"\n          aria-label=\"Search documentation\"\n        />\n        <i class=\"fa-solid fa-search\"></i>\n      </div>\n\n      <!-- Navigation Tree -->\n      <nav class=\"sidebar-nav\">\n            \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"setup\"\n          >\n            <i\n              class=\"fa-solid fa-gear \"\n            ></i>\n            <span>Setup</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-setup\"\n          >\n            \n             \n            <a\n              href=\"/docs/getting-started/\"\n              class=\"nav-item \"\n            >\n              Getting Started\n            </a>\n              \n            <a\n              href=\"/docs/setup/\"\n              class=\"nav-item \"\n            >\n              Setup & Configuration\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"styling\"\n          >\n            <i\n              class=\"fa-solid fa-palette \"\n            ></i>\n            <span>Styling</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-styling\"\n          >\n            \n             \n            <a\n              href=\"/docs/customization/\"\n              class=\"nav-item \"\n            >\n              Customization\n            </a>\n              \n            <a\n              href=\"/docs/css-variables/\"\n              class=\"nav-item \"\n            >\n              CSS Variables Reference\n            </a>\n             \n          </div>\n        </div>\n              \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"community\"\n          >\n            <i\n              class=\"fa-solid fa-users \"\n            ></i>\n            <span>Community</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-community\"\n          >\n            \n             \n            <a\n              href=\"/docs/contributing/\"\n              class=\"nav-item \"\n            >\n              Contributing\n            </a>\n              \n            <a\n              href=\"/docs/content-guidelines/\"\n              class=\"nav-item \"\n            >\n              Content Guidelines\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle active\"\n            data-category=\"developer\"\n          >\n            <i\n              class=\"fa-solid fa-code \"\n            ></i>\n            <span>Developer</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items expanded\"\n            id=\"category-developer\"\n          >\n            \n             \n            <a\n              href=\"/docs/api-reference/\"\n              class=\"nav-item active\"\n            >\n              API Reference\n            </a>\n              \n            <a\n              href=\"/docs/deployment/\"\n              class=\"nav-item \"\n            >\n              Deployment Guide\n            </a>\n              \n            <a\n              href=\"/docs/github-actions/\"\n              class=\"nav-item \"\n            >\n              GitHub Actions\n            </a>\n              \n            <a\n              href=\"/docs/project-structure/\"\n              class=\"nav-item \"\n            >\n              Project Structure\n            </a>\n              \n            <a\n              href=\"/docs/liquid-templates/\"\n              class=\"nav-item \"\n            >\n              Liquid Templates\n            </a>\n              \n            <a\n              href=\"/docs/performance/\"\n              class=\"nav-item \"\n            >\n              Performance Optimization\n            </a>\n              \n            <a\n              href=\"/docs/seo-guide/\"\n              class=\"nav-item \"\n            >\n              SEO Guide\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"help\"\n          >\n            <i\n              class=\"fa-solid fa-circle-question \"\n            ></i>\n            <span>Help</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-help\"\n          >\n            \n             \n            <a\n              href=\"/docs/faq/\"\n              class=\"nav-item \"\n            >\n              FAQ\n            </a>\n              \n            <a\n              href=\"/docs/troubleshooting/\"\n              class=\"nav-item \"\n            >\n              Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/accessibility/\"\n              class=\"nav-item \"\n            >\n              Accessibility Guide\n            </a>\n              \n            <a\n              href=\"/docs/common-errors/\"\n              class=\"nav-item \"\n            >\n              Common Errors & Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/browser-support/\"\n              class=\"nav-item \"\n            >\n              Browser Support\n            </a>\n             \n          </div>\n        </div>\n         \n      </nav>\n\n      <!-- Quick Links -->\n      <div class=\"sidebar-footer\">\n        <a href=\"/docs/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-home\"></i>\n          All Docs\n        </a>\n        <a href=\"/projects/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-folder\"></i>\n          Projects\n        </a>\n      </div>\n    </aside>\n\n    <!-- Sidebar Overlay (for mobile) -->\n    <div id=\"sidebar-overlay\" class=\"sidebar-overlay\"></div>\n\n    <!-- Main Content -->\n    <div class=\"docs-layout\">\n      <!-- Breadcrumbs -->\n      \n      <nav class=\"breadcrumbs\" aria-label=\"Breadcrumb\">\n        <a href=\"/\">\n          <i class=\"fa-solid fa-home\"></i>\n          Home\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a href=\"/docs/\">Docs</a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a\n          href=\"/docs-category-developer/\"\n        >\n          Developer\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <span class=\"current\">API Reference</span>\n      </nav>\n      \n\n      <!-- Page Content -->\n      <main class=\"docs-content\">\n        <article><h2 id=\"project-data-structure\">Project Data Structure</h2>\n\n<p>The <code class=\"language-plaintext highlighter-rouge\">data/mods.json</code> file contains project data pulled from Modrinth. Here’s the structure:</p>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{</span><span class=\"w\">\n  </span><span class=\"nl\">\"id\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"project_id\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"slug\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"project-slug\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"name\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"Project Name\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"title\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"Display Title\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"description\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"Full description...\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"short_description\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"Brief summary\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"project_type\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"mod|plugin|resourcepack|etc\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"author\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"author_name\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"thumbnail\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"https://cdn.modrinth.com/...\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"icon_url\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"https://cdn.modrinth.com/...\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"download\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"https://modrinth.com/mod/...\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"categories\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"s2\">\"category1\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"category2\"</span><span class=\"p\">],</span><span class=\"w\">\n  </span><span class=\"nl\">\"loaders\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"s2\">\"fabric\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"forge\"</span><span class=\"p\">],</span><span class=\"w\">\n  </span><span class=\"nl\">\"game_versions\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"s2\">\"1.20\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"1.20.1\"</span><span class=\"p\">],</span><span class=\"w\">\n  </span><span class=\"nl\">\"downloads\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"mi\">12345</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"followers\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"mi\">678</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"published\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"2025-01-01T00:00:00Z\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"updated\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"2025-12-10T07:24:19Z\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"license_id\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"MIT\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"source_url\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"https://github.com/...\"</span><span class=\"w\">\n</span><span class=\"p\">}</span><span class=\"w\">\n</span></code></pre></div></div>\n\n<h2 id=\"accessing-data-in-templates\">Accessing Data in Templates</h2>\n\n<p>Use Liquid templates to access project data:</p>\n\n<div class=\"language-liquid highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>\n</code></pre></div></div>\n\n<h2 id=\"modrinth-api\">Modrinth API</h2>\n\n<p>The site uses Modrinth’s public API to fetch project data. No authentication required for public projects.</p>\n\n<p><strong>Endpoint:</strong> <code class=\"language-plaintext highlighter-rouge\">https://api.modrinth.com/v2/organization/{id}/projects</code></p>\n\n<p><strong>Example:</strong></p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>curl https://api.modrinth.com/v2/organization/abcxyz/projects\n</code></pre></div></div>\n\n<hr />\n\n<p>See <a href=\"setup\">Setup &amp; Configuration</a> for more about data integration.</p>\n</article>\n\n        <section\n          class=\"feedback-card\"\n          id=\"feedback-card\"\n          aria-label=\"Page feedback\"\n        >\n          <div class=\"feedback-header\">\n            <div>\n              <p class=\"feedback-kicker\">Feedback</p>\n              <h3>Was this page helpful?</h3>\n              <p class=\"feedback-subtext\">\n                Share quick feedback to improve these docs.\n              </p>\n            </div>\n            <div class=\"feedback-badges\" aria-label=\"Applies to versions\">\n                  \n              <span class=\"version-badge\" aria-label=\"Minecraft 1.21.x\"\n                >1.21.x</span\n              >\n               \n            </div>\n          </div>\n\n          <div class=\"feedback-actions\" role=\"group\" aria-label=\"Helpful?\">\n            <button type=\"button\" class=\"feedback-btn yes\" data-feedback=\"yes\">\n              <i class=\"fa-solid fa-thumbs-up\"></i>\n              Yes\n            </button>\n            <button type=\"button\" class=\"feedback-btn no\" data-feedback=\"no\">\n              <i class=\"fa-solid fa-thumbs-down\"></i>\n              No\n            </button>\n          </div>\n\n          <div class=\"feedback-followup\" id=\"feedback-followup\" hidden>\n            <label for=\"feedback-notes\">What can we improve?</label>\n            <textarea\n              id=\"feedback-notes\"\n              rows=\"3\"\n              placeholder=\"Optional: missing steps, unclear wording, broken links\"\n            ></textarea>\n            <button type=\"button\" class=\"feedback-submit\" id=\"feedback-submit\">\n              <i class=\"fa-solid fa-paper-plane\"></i>\n              Send feedback\n            </button>\n          </div>\n\n          <p\n            class=\"feedback-status\"\n            id=\"feedback-status\"\n            role=\"status\"\n            aria-live=\"polite\"\n          ></p>\n        </section>\n\n        <!-- Page Navigation (Prev/Next) -->\n                                                 \n      </main>\n\n      <!-- Table of Contents (optional) -->\n      <aside class=\"docs-toc\">\n        <div class=\"toc-header\">\n          <h3>On This Page</h3>\n        </div>\n        <nav id=\"toc-nav\" class=\"toc-nav\">\n          <!-- Generated by JavaScript -->\n        </nav>\n\n        <!-- Theme Toggle in TOC -->\n        <button\n          id=\"theme-toggle-docs\"\n          class=\"theme-toggle\"\n          aria-label=\"Toggle theme\"\n        >\n          <i class=\"fa-solid fa-sun\"></i>\n          <i class=\"fa-solid fa-moon\"></i>\n        </button>\n      </aside>\n    </div>\n\n    <script>\n      // Theme Toggle\n      const themeToggle = document.getElementById(\"theme-toggle-docs\");\n      themeToggle?.addEventListener(\"click\", () => {\n        const current = document.documentElement.getAttribute(\"data-theme\");\n        const next = current === \"light\" ? \"dark\" : \"light\";\n        document.documentElement.setAttribute(\"data-theme\", next);\n        localStorage.setItem(\"theme\", next);\n      });\n\n      // Mobile Sidebar Toggle\n      const mobileToggle = document.getElementById(\"mobile-sidebar-toggle\");\n      const sidebar = document.getElementById(\"docs-sidebar\");\n      const overlay = document.getElementById(\"sidebar-overlay\");\n      const sidebarClose = document.getElementById(\"sidebar-close\");\n\n      function toggleSidebar() {\n        sidebar.classList.toggle(\"open\");\n        overlay.classList.toggle(\"active\");\n        document.body.style.overflow = sidebar.classList.contains(\"open\")\n          ? \"hidden\"\n          : \"\";\n      }\n\n      mobileToggle?.addEventListener(\"click\", toggleSidebar);\n      overlay?.addEventListener(\"click\", toggleSidebar);\n      sidebarClose?.addEventListener(\"click\", toggleSidebar);\n\n      // Category Toggle\n      document.querySelectorAll(\".category-toggle\").forEach((toggle) => {\n        toggle.addEventListener(\"click\", () => {\n          const category = toggle.dataset.category;\n          const items = document.getElementById(`category-${category}`);\n          toggle.classList.toggle(\"active\");\n          items.classList.toggle(\"expanded\");\n        });\n      });\n\n      // Generate Table of Contents\n      const content = document.querySelector(\".docs-content article\");\n      const tocNav = document.getElementById(\"toc-nav\");\n\n      if (content && tocNav) {\n        const headings = content.querySelectorAll(\"h2, h3\");\n\n        if (headings.length > 0) {\n          headings.forEach((heading, index) => {\n            // Add ID if not present\n            if (!heading.id) {\n              heading.id = heading.textContent\n                .toLowerCase()\n                .replace(/[^a-z0-9]+/g, \"-\")\n                .replace(/^-|-$/g, \"\");\n            }\n\n            const link = document.createElement(\"a\");\n            link.href = `#${heading.id}`;\n            link.textContent = heading.textContent;\n            link.className = `toc-link toc-${heading.tagName.toLowerCase()}`;\n            tocNav.appendChild(link);\n          });\n\n          // Highlight current section\n          const observer = new IntersectionObserver(\n            (entries) => {\n              entries.forEach((entry) => {\n                if (entry.isIntersecting) {\n                  const id = entry.target.id;\n                  tocNav.querySelectorAll(\".toc-link\").forEach((link) => {\n                    link.classList.toggle(\n                      \"active\",\n                      link.getAttribute(\"href\") === `#${id}`\n                    );\n                  });\n                }\n              });\n            },\n            { rootMargin: \"-20% 0px -80% 0px\" }\n          );\n\n          headings.forEach((heading) => observer.observe(heading));\n        }\n      }\n\n      // Sidebar Search\n      const sidebarSearch = document.getElementById(\"sidebar-search\");\n      sidebarSearch?.addEventListener(\"input\", (e) => {\n        const query = e.target.value.toLowerCase();\n        const items = document.querySelectorAll(\".nav-item\");\n\n        items.forEach((item) => {\n          const text = item.textContent.toLowerCase();\n          const matches = text.includes(query);\n          item.style.display = matches || !query ? \"\" : \"none\";\n\n          // Expand category if item matches\n          if (matches && query) {\n            const category = item.closest(\".category-items\");\n            const toggle = category?.previousElementSibling;\n            category?.classList.add(\"expanded\");\n            toggle?.classList.add(\"active\");\n          }\n        });\n      });\n\n      // Docs micro-feedback (local only)\n      const feedbackCard = document.getElementById(\"feedback-card\");\n      const feedbackButtons = document.querySelectorAll(\".feedback-btn\");\n      const feedbackFollowup = document.getElementById(\"feedback-followup\");\n      const feedbackSubmit = document.getElementById(\"feedback-submit\");\n      const feedbackStatus = document.getElementById(\"feedback-status\");\n      const feedbackNotes = document.getElementById(\"feedback-notes\");\n      const feedbackStorageKey = `docs-feedback:${window.location.pathname}`;\n\n      function completeFeedback(message) {\n        if (feedbackCard) feedbackCard.classList.add(\"feedback-complete\");\n        if (feedbackFollowup) feedbackFollowup.hidden = true;\n        if (feedbackStatus) feedbackStatus.textContent = message;\n        try {\n          localStorage.setItem(feedbackStorageKey, \"submitted\");\n        } catch (err) {\n          console.warn(\"Feedback storage failed\", err);\n        }\n      }\n\n      function maybeDisableFeedback() {\n        let stored = null;\n        try {\n          stored = localStorage.getItem(feedbackStorageKey);\n        } catch (err) {\n          console.warn(\"Feedback storage read failed\", err);\n        }\n\n        if (stored && feedbackCard) {\n          feedbackCard.classList.add(\"feedback-complete\");\n          if (feedbackFollowup) feedbackFollowup.hidden = true;\n          if (feedbackStatus)\n            feedbackStatus.textContent = \"Thanks—feedback already recorded.\";\n        }\n      }\n\n      feedbackButtons.forEach((btn) => {\n        btn.addEventListener(\"click\", () => {\n          const value = btn.dataset.feedback;\n          if (value === \"no\") {\n            if (feedbackFollowup) feedbackFollowup.hidden = false;\n            if (feedbackStatus)\n              feedbackStatus.textContent = \"Tell us what to improve.\";\n          } else {\n            completeFeedback(\"Thanks for the feedback!\");\n          }\n        });\n      });\n\n      feedbackSubmit?.addEventListener(\"click\", () => {\n        const note = feedbackNotes?.value?.trim();\n        const suffix = note ? \" We will review your note.\" : \"\";\n        completeFeedback(`Got it!${suffix}`);\n      });\n\n      maybeDisableFeedback();\n    </script>\n  </body>\n</html>\n","<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"dark\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>\n      Browser Support | Minecraft Mods & Packs Showcase\n    </title>\n\n    <!-- Stylesheets -->\n    <link rel=\"stylesheet\" href=\"/assets/css/main.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/layout.css\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/modpacks.css\"\n    />\n    <link rel=\"stylesheet\" href=\"/assets/css/docs.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n    />\n\n    <script>\n      if (!document.body) {\n        console.warn(\"Body not ready, skipping preloader\");\n      } else {\n        window.addEventListener(\"load\", () => {\n          document.body.classList.add(\"loaded\");\n        });\n      }\n\n      const savedTheme = localStorage.getItem(\"theme\") || \"dark\";\n      document.documentElement.setAttribute(\"data-theme\", savedTheme);\n    </script>\n  </head>\n  <body>\n    <!-- Preloader -->\n    <div class=\"preloader\">\n      <div class=\"spinner\"></div>\n    </div>\n\n    <!-- Mobile Menu Toggle -->\n    <button\n      id=\"mobile-sidebar-toggle\"\n      class=\"mobile-sidebar-toggle\"\n      aria-label=\"Toggle sidebar\"\n    >\n      <i class=\"fa-solid fa-bars\"></i>\n    </button>\n\n    <!-- Docs Sidebar -->\n    <aside id=\"docs-sidebar\" class=\"docs-sidebar\">\n      <div class=\"sidebar-header\">\n        <a href=\"/\" class=\"sidebar-logo\">\n          <i class=\"fa-solid fa-cube\"></i>\n          <span>Minecraft Mods & Packs Showcase</span>\n        </a>\n        <button\n          id=\"sidebar-close\"\n          class=\"sidebar-close\"\n          aria-label=\"Close sidebar\"\n        >\n          <i class=\"fa-solid fa-times\"></i>\n        </button>\n      </div>\n\n      <!-- Search in Sidebar -->\n      <div class=\"sidebar-search\">\n        <input\n          type=\"search\"\n          id=\"sidebar-search\"\n          placeholder=\"Search docs...\"\n          aria-label=\"Search documentation\"\n        />\n        <i class=\"fa-solid fa-search\"></i>\n      </div>\n\n      <!-- Navigation Tree -->\n      <nav class=\"sidebar-nav\">\n            \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"setup\"\n          >\n            <i\n              class=\"fa-solid fa-gear \"\n            ></i>\n            <span>Setup</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-setup\"\n          >\n            \n             \n            <a\n              href=\"/docs/getting-started/\"\n              class=\"nav-item \"\n            >\n              Getting Started\n            </a>\n              \n            <a\n              href=\"/docs/setup/\"\n              class=\"nav-item \"\n            >\n              Setup & Configuration\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"styling\"\n          >\n            <i\n              class=\"fa-solid fa-palette \"\n            ></i>\n            <span>Styling</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-styling\"\n          >\n            \n             \n            <a\n              href=\"/docs/customization/\"\n              class=\"nav-item \"\n            >\n              Customization\n            </a>\n              \n            <a\n              href=\"/docs/css-variables/\"\n              class=\"nav-item \"\n            >\n              CSS Variables Reference\n            </a>\n             \n          </div>\n        </div>\n              \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"community\"\n          >\n            <i\n              class=\"fa-solid fa-users \"\n            ></i>\n            <span>Community</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-community\"\n          >\n            \n             \n            <a\n              href=\"/docs/contributing/\"\n              class=\"nav-item \"\n            >\n              Contributing\n            </a>\n              \n            <a\n              href=\"/docs/content-guidelines/\"\n              class=\"nav-item \"\n            >\n              Content Guidelines\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"developer\"\n          >\n            <i\n              class=\"fa-solid fa-code \"\n            ></i>\n            <span>Developer</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-developer\"\n          >\n            \n             \n            <a\n              href=\"/docs/api-reference/\"\n              class=\"nav-item \"\n            >\n              API Reference\n            </a>\n              \n            <a\n              href=\"/docs/deployment/\"\n              class=\"nav-item \"\n            >\n              Deployment Guide\n            </a>\n              \n            <a\n              href=\"/docs/github-actions/\"\n              class=\"nav-item \"\n            >\n              GitHub Actions\n            </a>\n              \n            <a\n              href=\"/docs/project-structure/\"\n              class=\"nav-item \"\n            >\n              Project Structure\n            </a>\n              \n            <a\n              href=\"/docs/liquid-templates/\"\n              class=\"nav-item \"\n            >\n              Liquid Templates\n            </a>\n              \n            <a\n              href=\"/docs/performance/\"\n              class=\"nav-item \"\n            >\n              Performance Optimization\n            </a>\n              \n            <a\n              href=\"/docs/seo-guide/\"\n              class=\"nav-item \"\n            >\n              SEO Guide\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle active\"\n            data-category=\"help\"\n          >\n            <i\n              class=\"fa-solid fa-circle-question \"\n            ></i>\n            <span>Help</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items expanded\"\n            id=\"category-help\"\n          >\n            \n             \n            <a\n              href=\"/docs/faq/\"\n              class=\"nav-item \"\n            >\n              FAQ\n            </a>\n              \n            <a\n              href=\"/docs/troubleshooting/\"\n              class=\"nav-item \"\n            >\n              Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/accessibility/\"\n              class=\"nav-item \"\n            >\n              Accessibility Guide\n            </a>\n              \n            <a\n              href=\"/docs/common-errors/\"\n              class=\"nav-item \"\n            >\n              Common Errors & Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/browser-support/\"\n              class=\"nav-item active\"\n            >\n              Browser Support\n            </a>\n             \n          </div>\n        </div>\n         \n      </nav>\n\n      <!-- Quick Links -->\n      <div class=\"sidebar-footer\">\n        <a href=\"/docs/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-home\"></i>\n          All Docs\n        </a>\n        <a href=\"/projects/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-folder\"></i>\n          Projects\n        </a>\n      </div>\n    </aside>\n\n    <!-- Sidebar Overlay (for mobile) -->\n    <div id=\"sidebar-overlay\" class=\"sidebar-overlay\"></div>\n\n    <!-- Main Content -->\n    <div class=\"docs-layout\">\n      <!-- Breadcrumbs -->\n      \n      <nav class=\"breadcrumbs\" aria-label=\"Breadcrumb\">\n        <a href=\"/\">\n          <i class=\"fa-solid fa-home\"></i>\n          Home\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a href=\"/docs/\">Docs</a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a\n          href=\"/docs-category-help/\"\n        >\n          Help\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <span class=\"current\">Browser Support</span>\n      </nav>\n      \n\n      <!-- Page Content -->\n      <main class=\"docs-content\">\n        <article><h1 id=\"browser-support\">Browser Support</h1>\n\n<p>Ensure your ABC showcase works across different browsers and devices.</p>\n\n<h2 id=\"supported-browsers\">Supported Browsers</h2>\n\n<h3 id=\"modern-browsers-full-support\">Modern Browsers (Full Support)</h3>\n\n<table>\n  <thead>\n    <tr>\n      <th>Browser</th>\n      <th>Minimum Version</th>\n      <th>Notes</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>Chrome</td>\n      <td>90+</td>\n      <td>Full ES6 support</td>\n    </tr>\n    <tr>\n      <td>Firefox</td>\n      <td>88+</td>\n      <td>Full CSS Grid support</td>\n    </tr>\n    <tr>\n      <td>Safari</td>\n      <td>14+</td>\n      <td>webkit prefixes may be needed</td>\n    </tr>\n    <tr>\n      <td>Edge</td>\n      <td>90+</td>\n      <td>Chromium-based</td>\n    </tr>\n    <tr>\n      <td>Opera</td>\n      <td>76+</td>\n      <td>Chromium-based</td>\n    </tr>\n  </tbody>\n</table>\n\n<h3 id=\"mobile-browsers\">Mobile Browsers</h3>\n\n<table>\n  <thead>\n    <tr>\n      <th>Browser</th>\n      <th>Minimum Version</th>\n      <th>Notes</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>Chrome Mobile</td>\n      <td>90+</td>\n      <td>Android 5+</td>\n    </tr>\n    <tr>\n      <td>Safari Mobile</td>\n      <td>14+</td>\n      <td>iOS 14+</td>\n    </tr>\n    <tr>\n      <td>Samsung Internet</td>\n      <td>14+</td>\n      <td>Android 7+</td>\n    </tr>\n    <tr>\n      <td>Firefox Mobile</td>\n      <td>88+</td>\n      <td>Android 5+</td>\n    </tr>\n  </tbody>\n</table>\n\n<h3 id=\"limited-support\">Limited Support</h3>\n\n<table>\n  <thead>\n    <tr>\n      <th>Browser</th>\n      <th>Support Level</th>\n      <th>Notes</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>IE 11</td>\n      <td>Degraded</td>\n      <td>Requires polyfills</td>\n    </tr>\n    <tr>\n      <td>Safari 13</td>\n      <td>Partial</td>\n      <td>Some CSS features unsupported</td>\n    </tr>\n    <tr>\n      <td>Older mobile browsers</td>\n      <td>Basic</td>\n      <td>Fallbacks required</td>\n    </tr>\n  </tbody>\n</table>\n\n<h2 id=\"feature-support\">Feature Support</h2>\n\n<h3 id=\"css-features\">CSS Features</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* CSS Grid */</span>\n<span class=\"k\">@supports</span> <span class=\"p\">(</span><span class=\"n\">display</span><span class=\"p\">:</span> <span class=\"n\">grid</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nc\">.grid</span> <span class=\"p\">{</span>\n    <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"n\">grid</span><span class=\"p\">;</span>\n    <span class=\"py\">grid-template-columns</span><span class=\"p\">:</span> <span class=\"nb\">repeat</span><span class=\"p\">(</span><span class=\"n\">auto-fit</span><span class=\"p\">,</span> <span class=\"n\">minmax</span><span class=\"p\">(</span><span class=\"m\">280px</span><span class=\"p\">,</span> <span class=\"m\">1</span><span class=\"n\">fr</span><span class=\"p\">));</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Fallback for older browsers */</span>\n<span class=\"nc\">.grid</span> <span class=\"p\">{</span>\n  <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"n\">flex</span><span class=\"p\">;</span>\n  <span class=\"nl\">flex-wrap</span><span class=\"p\">:</span> <span class=\"n\">wrap</span><span class=\"p\">;</span>\n  <span class=\"py\">gap</span><span class=\"p\">:</span> <span class=\"m\">16px</span><span class=\"p\">;</span> <span class=\"c\">/* Fallback with margin if gap unsupported */</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Custom Properties (CSS Variables) */</span>\n<span class=\"nd\">:root</span> <span class=\"p\">{</span>\n  <span class=\"py\">--accent</span><span class=\"p\">:</span> <span class=\"m\">#4caf50</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Fallback */</span>\n<span class=\"nc\">.button</span> <span class=\"p\">{</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"m\">#4caf50</span><span class=\"p\">;</span> <span class=\"c\">/* Fallback */</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"n\">var</span><span class=\"p\">(</span><span class=\"n\">--accent</span><span class=\"p\">);</span> <span class=\"c\">/* Modern */</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h3 id=\"javascript-features\">JavaScript Features</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// ES6+ Features Detection</span>\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"k\">typeof</span> <span class=\"nb\">Symbol</span> <span class=\"o\">!==</span> <span class=\"dl\">\"</span><span class=\"s2\">undefined</span><span class=\"dl\">\"</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Symbols supported</span>\n<span class=\"p\">}</span>\n\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"k\">typeof</span> <span class=\"nb\">Promise</span> <span class=\"o\">!==</span> <span class=\"dl\">\"</span><span class=\"s2\">undefined</span><span class=\"dl\">\"</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Promises supported</span>\n<span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Load polyfill</span>\n<span class=\"p\">}</span>\n\n<span class=\"c1\">// Modern API Detection</span>\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">IntersectionObserver</span><span class=\"dl\">\"</span> <span class=\"k\">in</span> <span class=\"nb\">window</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Use IntersectionObserver</span>\n<span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Fallback to scroll events</span>\n<span class=\"p\">}</span>\n\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">serviceWorker</span><span class=\"dl\">\"</span> <span class=\"k\">in</span> <span class=\"nb\">navigator</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Service Worker supported</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"progressive-enhancement\">Progressive Enhancement</h2>\n\n<h3 id=\"mobile-first-approach\">Mobile-First Approach</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Base styles for mobile */</span>\n<span class=\"nc\">.container</span> <span class=\"p\">{</span>\n  <span class=\"nl\">padding</span><span class=\"p\">:</span> <span class=\"m\">20px</span><span class=\"p\">;</span>\n  <span class=\"nl\">font-size</span><span class=\"p\">:</span> <span class=\"m\">16px</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Enhance for tablets */</span>\n<span class=\"k\">@media</span> <span class=\"p\">(</span><span class=\"n\">min-width</span><span class=\"p\">:</span> <span class=\"m\">768px</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nc\">.container</span> <span class=\"p\">{</span>\n    <span class=\"nl\">padding</span><span class=\"p\">:</span> <span class=\"m\">40px</span><span class=\"p\">;</span>\n    <span class=\"nl\">font-size</span><span class=\"p\">:</span> <span class=\"m\">18px</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Enhance for desktop */</span>\n<span class=\"k\">@media</span> <span class=\"p\">(</span><span class=\"n\">min-width</span><span class=\"p\">:</span> <span class=\"m\">1024px</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nc\">.container</span> <span class=\"p\">{</span>\n    <span class=\"nl\">max-width</span><span class=\"p\">:</span> <span class=\"m\">1200px</span><span class=\"p\">;</span>\n    <span class=\"nl\">margin</span><span class=\"p\">:</span> <span class=\"m\">0</span> <span class=\"nb\">auto</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h3 id=\"feature-detection\">Feature Detection</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// Check for localStorage</span>\n<span class=\"kd\">function</span> <span class=\"nx\">hasLocalStorage</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"k\">try</span> <span class=\"p\">{</span>\n    <span class=\"nx\">localStorage</span><span class=\"p\">.</span><span class=\"nx\">setItem</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">test</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">test</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n    <span class=\"nx\">localStorage</span><span class=\"p\">.</span><span class=\"nx\">removeItem</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">test</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n    <span class=\"k\">return</span> <span class=\"kc\">true</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span> <span class=\"k\">catch</span> <span class=\"p\">(</span><span class=\"nx\">e</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"kc\">false</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">hasLocalStorage</span><span class=\"p\">())</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Use localStorage</span>\n<span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Use cookies or session storage</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"vendor-prefixes\">Vendor Prefixes</h2>\n\n<h3 id=\"autoprefixer-recommended\">Autoprefixer (Recommended)</h3>\n\n<p>Install and configure:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>npm <span class=\"nb\">install</span> <span class=\"nt\">--save-dev</span> autoprefixer postcss-cli\n</code></pre></div></div>\n\n<p>Create <code class=\"language-plaintext highlighter-rouge\">postcss.config.js</code>:</p>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n  <span class=\"na\">plugins</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n    <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">autoprefixer</span><span class=\"dl\">\"</span><span class=\"p\">)({</span>\n      <span class=\"na\">overrideBrowserslist</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"dl\">\"</span><span class=\"s2\">last 2 versions</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">&gt; 1%</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">not dead</span><span class=\"dl\">\"</span><span class=\"p\">],</span>\n    <span class=\"p\">}),</span>\n  <span class=\"p\">],</span>\n<span class=\"p\">};</span>\n</code></pre></div></div>\n\n<h3 id=\"manual-prefixes\">Manual Prefixes</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Flexbox */</span>\n<span class=\"nc\">.flex</span> <span class=\"p\">{</span>\n  <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"n\">-webkit-box</span><span class=\"p\">;</span>\n  <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"n\">-ms-flexbox</span><span class=\"p\">;</span>\n  <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"n\">flex</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Transform */</span>\n<span class=\"nc\">.rotate</span> <span class=\"p\">{</span>\n  <span class=\"nl\">-webkit-transform</span><span class=\"p\">:</span> <span class=\"n\">rotate</span><span class=\"p\">(</span><span class=\"m\">45deg</span><span class=\"p\">);</span>\n  <span class=\"nl\">-ms-transform</span><span class=\"p\">:</span> <span class=\"n\">rotate</span><span class=\"p\">(</span><span class=\"m\">45deg</span><span class=\"p\">);</span>\n  <span class=\"nl\">transform</span><span class=\"p\">:</span> <span class=\"n\">rotate</span><span class=\"p\">(</span><span class=\"m\">45deg</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Transition */</span>\n<span class=\"nc\">.transition</span> <span class=\"p\">{</span>\n  <span class=\"nl\">-webkit-transition</span><span class=\"p\">:</span> <span class=\"n\">all</span> <span class=\"m\">0.3s</span> <span class=\"n\">ease</span><span class=\"p\">;</span>\n  <span class=\"nl\">-o-transition</span><span class=\"p\">:</span> <span class=\"n\">all</span> <span class=\"m\">0.3s</span> <span class=\"n\">ease</span><span class=\"p\">;</span>\n  <span class=\"nl\">transition</span><span class=\"p\">:</span> <span class=\"n\">all</span> <span class=\"m\">0.3s</span> <span class=\"n\">ease</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Backdrop Filter */</span>\n<span class=\"nc\">.blur</span> <span class=\"p\">{</span>\n  <span class=\"nl\">-webkit-backdrop-filter</span><span class=\"p\">:</span> <span class=\"n\">blur</span><span class=\"p\">(</span><span class=\"m\">10px</span><span class=\"p\">);</span>\n  <span class=\"py\">backdrop-filter</span><span class=\"p\">:</span> <span class=\"n\">blur</span><span class=\"p\">(</span><span class=\"m\">10px</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"polyfills\">Polyfills</h2>\n\n<h3 id=\"core-polyfills\">Core Polyfills</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Polyfill.io (automatic) --&gt;</span>\n<span class=\"nt\">&lt;script </span><span class=\"na\">src=</span><span class=\"s\">\"https://polyfill.io/v3/polyfill.min.js?features=default,IntersectionObserver,fetch\"</span><span class=\"nt\">&gt;&lt;/script&gt;</span>\n\n<span class=\"c\">&lt;!-- Or manual polyfills --&gt;</span>\n<span class=\"nt\">&lt;script </span><span class=\"na\">src=</span><span class=\"s\">\"/assets/js/polyfills.js\"</span><span class=\"nt\">&gt;&lt;/script&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"custom-polyfill-bundle\">Custom Polyfill Bundle</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// polyfills.js</span>\n\n<span class=\"c1\">// Array.from (IE 11)</span>\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nb\">Array</span><span class=\"p\">.</span><span class=\"k\">from</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nb\">Array</span><span class=\"p\">.</span><span class=\"k\">from</span> <span class=\"o\">=</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">arrayLike</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"nb\">Array</span><span class=\"p\">.</span><span class=\"nx\">prototype</span><span class=\"p\">.</span><span class=\"nx\">slice</span><span class=\"p\">.</span><span class=\"nx\">call</span><span class=\"p\">(</span><span class=\"nx\">arrayLike</span><span class=\"p\">);</span>\n  <span class=\"p\">};</span>\n<span class=\"p\">}</span>\n\n<span class=\"c1\">// Object.assign (IE 11)</span>\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"k\">typeof</span> <span class=\"nb\">Object</span><span class=\"p\">.</span><span class=\"nx\">assign</span> <span class=\"o\">!==</span> <span class=\"dl\">\"</span><span class=\"s2\">function</span><span class=\"dl\">\"</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nb\">Object</span><span class=\"p\">.</span><span class=\"nx\">assign</span> <span class=\"o\">=</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">target</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">target</span> <span class=\"o\">==</span> <span class=\"kc\">null</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n      <span class=\"k\">throw</span> <span class=\"k\">new</span> <span class=\"nx\">TypeError</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">Cannot convert undefined or null to object</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n    <span class=\"p\">}</span>\n    <span class=\"kd\">var</span> <span class=\"nx\">to</span> <span class=\"o\">=</span> <span class=\"nb\">Object</span><span class=\"p\">(</span><span class=\"nx\">target</span><span class=\"p\">);</span>\n    <span class=\"k\">for</span> <span class=\"p\">(</span><span class=\"kd\">var</span> <span class=\"nx\">index</span> <span class=\"o\">=</span> <span class=\"mi\">1</span><span class=\"p\">;</span> <span class=\"nx\">index</span> <span class=\"o\">&lt;</span> <span class=\"nx\">arguments</span><span class=\"p\">.</span><span class=\"nx\">length</span><span class=\"p\">;</span> <span class=\"nx\">index</span><span class=\"o\">++</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n      <span class=\"kd\">var</span> <span class=\"nx\">nextSource</span> <span class=\"o\">=</span> <span class=\"nx\">arguments</span><span class=\"p\">[</span><span class=\"nx\">index</span><span class=\"p\">];</span>\n      <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">nextSource</span> <span class=\"o\">!=</span> <span class=\"kc\">null</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"k\">for</span> <span class=\"p\">(</span><span class=\"kd\">var</span> <span class=\"nx\">nextKey</span> <span class=\"k\">in</span> <span class=\"nx\">nextSource</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n          <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nb\">Object</span><span class=\"p\">.</span><span class=\"nx\">prototype</span><span class=\"p\">.</span><span class=\"nx\">hasOwnProperty</span><span class=\"p\">.</span><span class=\"nx\">call</span><span class=\"p\">(</span><span class=\"nx\">nextSource</span><span class=\"p\">,</span> <span class=\"nx\">nextKey</span><span class=\"p\">))</span> <span class=\"p\">{</span>\n            <span class=\"nx\">to</span><span class=\"p\">[</span><span class=\"nx\">nextKey</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"nx\">nextSource</span><span class=\"p\">[</span><span class=\"nx\">nextKey</span><span class=\"p\">];</span>\n          <span class=\"p\">}</span>\n        <span class=\"p\">}</span>\n      <span class=\"p\">}</span>\n    <span class=\"p\">}</span>\n    <span class=\"k\">return</span> <span class=\"nx\">to</span><span class=\"p\">;</span>\n  <span class=\"p\">};</span>\n<span class=\"p\">}</span>\n\n<span class=\"c1\">// Fetch API (older browsers)</span>\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nb\">window</span><span class=\"p\">.</span><span class=\"nx\">fetch</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Load fetch polyfill</span>\n  <span class=\"kd\">var</span> <span class=\"nx\">script</span> <span class=\"o\">=</span> <span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">createElement</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">script</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n  <span class=\"nx\">script</span><span class=\"p\">.</span><span class=\"nx\">src</span> <span class=\"o\">=</span> <span class=\"dl\">\"</span><span class=\"s2\">https://unpkg.com/[email protected]/dist/fetch.umd.js</span><span class=\"dl\">\"</span><span class=\"p\">;</span>\n  <span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">head</span><span class=\"p\">.</span><span class=\"nx\">appendChild</span><span class=\"p\">(</span><span class=\"nx\">script</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n\n<span class=\"c1\">// IntersectionObserver (Safari &lt; 12.1)</span>\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">IntersectionObserver</span><span class=\"dl\">\"</span> <span class=\"k\">in</span> <span class=\"nb\">window</span><span class=\"p\">))</span> <span class=\"p\">{</span>\n  <span class=\"kd\">var</span> <span class=\"nx\">script</span> <span class=\"o\">=</span> <span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">createElement</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">script</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n  <span class=\"nx\">script</span><span class=\"p\">.</span><span class=\"nx\">src</span> <span class=\"o\">=</span>\n    <span class=\"dl\">\"</span><span class=\"s2\">https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver</span><span class=\"dl\">\"</span><span class=\"p\">;</span>\n  <span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">head</span><span class=\"p\">.</span><span class=\"nx\">appendChild</span><span class=\"p\">(</span><span class=\"nx\">script</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"testing-across-browsers\">Testing Across Browsers</h2>\n\n<h3 id=\"local-testing\">Local Testing</h3>\n\n<p><strong>BrowserStack</strong> (free for open source):</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>https://www.browserstack.com/open-source\n</code></pre></div></div>\n\n<p><strong>Browser DevTools Device Mode</strong>:</p>\n\n<ul>\n  <li>Chrome: F12 &gt; Toggle device toolbar</li>\n  <li>Firefox: F12 &gt; Responsive Design Mode</li>\n  <li>Safari: Develop &gt; Enter Responsive Design Mode</li>\n</ul>\n\n<h3 id=\"automated-testing\">Automated Testing</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// Example with Playwright</span>\n<span class=\"kd\">const</span> <span class=\"p\">{</span> <span class=\"nx\">chromium</span><span class=\"p\">,</span> <span class=\"nx\">firefox</span><span class=\"p\">,</span> <span class=\"nx\">webkit</span> <span class=\"p\">}</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">playwright</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n\n<span class=\"p\">(</span><span class=\"k\">async</span> <span class=\"p\">()</span> <span class=\"o\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"k\">for</span> <span class=\"p\">(</span><span class=\"kd\">const</span> <span class=\"nx\">browserType</span> <span class=\"k\">of</span> <span class=\"p\">[</span><span class=\"nx\">chromium</span><span class=\"p\">,</span> <span class=\"nx\">firefox</span><span class=\"p\">,</span> <span class=\"nx\">webkit</span><span class=\"p\">])</span> <span class=\"p\">{</span>\n    <span class=\"kd\">const</span> <span class=\"nx\">browser</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"nx\">browserType</span><span class=\"p\">.</span><span class=\"nx\">launch</span><span class=\"p\">();</span>\n    <span class=\"kd\">const</span> <span class=\"nx\">page</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"nx\">browser</span><span class=\"p\">.</span><span class=\"nx\">newPage</span><span class=\"p\">();</span>\n    <span class=\"k\">await</span> <span class=\"nx\">page</span><span class=\"p\">.</span><span class=\"nx\">goto</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">http://localhost:4000</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n    <span class=\"k\">await</span> <span class=\"nx\">page</span><span class=\"p\">.</span><span class=\"nx\">screenshot</span><span class=\"p\">({</span> <span class=\"na\">path</span><span class=\"p\">:</span> <span class=\"s2\">`screenshot-</span><span class=\"p\">${</span><span class=\"nx\">browserType</span><span class=\"p\">.</span><span class=\"nx\">name</span><span class=\"p\">()}</span><span class=\"s2\">.png`</span> <span class=\"p\">});</span>\n    <span class=\"k\">await</span> <span class=\"nx\">browser</span><span class=\"p\">.</span><span class=\"nx\">close</span><span class=\"p\">();</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">})();</span>\n</code></pre></div></div>\n\n<h2 id=\"graceful-degradation\">Graceful Degradation</h2>\n\n<h3 id=\"no-javascript-fallback\">No JavaScript Fallback</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;noscript&gt;</span>\n  <span class=\"nt\">&lt;style&gt;</span>\n    <span class=\"nc\">.js-only</span> <span class=\"p\">{</span>\n      <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"nb\">none</span><span class=\"p\">;</span>\n    <span class=\"p\">}</span>\n  <span class=\"nt\">&lt;/style&gt;</span>\n  <span class=\"nt\">&lt;div</span> <span class=\"na\">class=</span><span class=\"s\">\"no-js-message\"</span><span class=\"nt\">&gt;</span>\n    <span class=\"nt\">&lt;p&gt;</span>This site works best with JavaScript enabled.<span class=\"nt\">&lt;/p&gt;</span>\n  <span class=\"nt\">&lt;/div&gt;</span>\n<span class=\"nt\">&lt;/noscript&gt;</span>\n\n<span class=\"c\">&lt;!-- Progressive enhancement --&gt;</span>\n<span class=\"nt\">&lt;div</span> <span class=\"na\">class=</span><span class=\"s\">\"content\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;p&gt;</span>Content visible without JS<span class=\"nt\">&lt;/p&gt;</span>\n  <span class=\"nt\">&lt;div</span> <span class=\"na\">class=</span><span class=\"s\">\"js-only\"</span> <span class=\"na\">style=</span><span class=\"s\">\"display: none;\"</span><span class=\"nt\">&gt;</span>\n    <span class=\"nt\">&lt;p&gt;</span>Enhanced content with JS<span class=\"nt\">&lt;/p&gt;</span>\n  <span class=\"nt\">&lt;/div&gt;</span>\n<span class=\"nt\">&lt;/div&gt;</span>\n\n<span class=\"nt\">&lt;script&gt;</span>\n  <span class=\"c1\">// Show JS-only content</span>\n  <span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">querySelectorAll</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">.js-only</span><span class=\"dl\">\"</span><span class=\"p\">).</span><span class=\"nx\">forEach</span><span class=\"p\">((</span><span class=\"nx\">el</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">el</span><span class=\"p\">.</span><span class=\"nx\">style</span><span class=\"p\">.</span><span class=\"nx\">display</span> <span class=\"o\">=</span> <span class=\"dl\">\"</span><span class=\"s2\">block</span><span class=\"dl\">\"</span><span class=\"p\">;</span>\n  <span class=\"p\">});</span>\n<span class=\"nt\">&lt;/script&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"css-fallbacks\">CSS Fallbacks</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Background with fallback */</span>\n<span class=\"nc\">.element</span> <span class=\"p\">{</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"m\">#1a1a1a</span><span class=\"p\">;</span> <span class=\"c\">/* Fallback */</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"n\">linear-gradient</span><span class=\"p\">(</span><span class=\"m\">135deg</span><span class=\"p\">,</span> <span class=\"m\">#1a1a1a</span> <span class=\"m\">0%</span><span class=\"p\">,</span> <span class=\"m\">#2a2a2a</span> <span class=\"m\">100%</span><span class=\"p\">);</span> <span class=\"c\">/* Modern */</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Custom properties with fallback */</span>\n<span class=\"nc\">.button</span> <span class=\"p\">{</span>\n  <span class=\"nl\">color</span><span class=\"p\">:</span> <span class=\"m\">#4caf50</span><span class=\"p\">;</span> <span class=\"c\">/* Fallback */</span>\n  <span class=\"nl\">color</span><span class=\"p\">:</span> <span class=\"n\">var</span><span class=\"p\">(</span><span class=\"n\">--accent-primary</span><span class=\"p\">,</span> <span class=\"m\">#4caf50</span><span class=\"p\">);</span> <span class=\"c\">/* Modern with fallback */</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"common-compatibility-issues\">Common Compatibility Issues</h2>\n\n<h3 id=\"issue-css-grid-not-working\">Issue: CSS Grid Not Working</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Solution: Provide flexbox fallback */</span>\n<span class=\"nc\">.grid</span> <span class=\"p\">{</span>\n  <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"n\">flex</span><span class=\"p\">;</span>\n  <span class=\"nl\">flex-wrap</span><span class=\"p\">:</span> <span class=\"n\">wrap</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"nc\">.grid</span> <span class=\"o\">&gt;</span> <span class=\"o\">*</span> <span class=\"p\">{</span>\n  <span class=\"nl\">flex</span><span class=\"p\">:</span> <span class=\"m\">1</span> <span class=\"m\">1</span> <span class=\"m\">280px</span><span class=\"p\">;</span>\n  <span class=\"nl\">margin</span><span class=\"p\">:</span> <span class=\"m\">8px</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"k\">@supports</span> <span class=\"p\">(</span><span class=\"n\">display</span><span class=\"p\">:</span> <span class=\"n\">grid</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nc\">.grid</span> <span class=\"p\">{</span>\n    <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"n\">grid</span><span class=\"p\">;</span>\n    <span class=\"py\">grid-template-columns</span><span class=\"p\">:</span> <span class=\"nb\">repeat</span><span class=\"p\">(</span><span class=\"n\">auto-fit</span><span class=\"p\">,</span> <span class=\"n\">minmax</span><span class=\"p\">(</span><span class=\"m\">280px</span><span class=\"p\">,</span> <span class=\"m\">1</span><span class=\"n\">fr</span><span class=\"p\">));</span>\n    <span class=\"py\">gap</span><span class=\"p\">:</span> <span class=\"m\">16px</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span>\n\n  <span class=\"nc\">.grid</span> <span class=\"o\">&gt;</span> <span class=\"o\">*</span> <span class=\"p\">{</span>\n    <span class=\"nl\">margin</span><span class=\"p\">:</span> <span class=\"m\">0</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h3 id=\"issue-backdrop-filter-not-supported\">Issue: backdrop-filter Not Supported</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Fallback for backdrop-filter */</span>\n<span class=\"nc\">.navbar</span> <span class=\"p\">{</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"n\">rgba</span><span class=\"p\">(</span><span class=\"m\">31</span><span class=\"p\">,</span> <span class=\"m\">31</span><span class=\"p\">,</span> <span class=\"m\">31</span><span class=\"p\">,</span> <span class=\"m\">0.9</span><span class=\"p\">);</span> <span class=\"c\">/* Solid fallback */</span>\n<span class=\"p\">}</span>\n\n<span class=\"k\">@supports</span> <span class=\"p\">(</span><span class=\"n\">backdrop-filter</span><span class=\"p\">:</span> <span class=\"n\">blur</span><span class=\"p\">(</span><span class=\"m\">10px</span><span class=\"p\">))</span> <span class=\"p\">{</span>\n  <span class=\"nc\">.navbar</span> <span class=\"p\">{</span>\n    <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"n\">rgba</span><span class=\"p\">(</span><span class=\"m\">31</span><span class=\"p\">,</span> <span class=\"m\">31</span><span class=\"p\">,</span> <span class=\"m\">31</span><span class=\"p\">,</span> <span class=\"m\">0.7</span><span class=\"p\">);</span> <span class=\"c\">/* More transparent */</span>\n    <span class=\"py\">backdrop-filter</span><span class=\"p\">:</span> <span class=\"n\">blur</span><span class=\"p\">(</span><span class=\"m\">10px</span><span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h3 id=\"issue-sticky-positioning\">Issue: Sticky Positioning</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Fallback for position: sticky */</span>\n<span class=\"nc\">.sidebar</span> <span class=\"p\">{</span>\n  <span class=\"nl\">position</span><span class=\"p\">:</span> <span class=\"nb\">relative</span><span class=\"p\">;</span> <span class=\"c\">/* Fallback */</span>\n<span class=\"p\">}</span>\n\n<span class=\"k\">@supports</span> <span class=\"p\">(</span><span class=\"n\">position</span><span class=\"p\">:</span> <span class=\"n\">sticky</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nc\">.sidebar</span> <span class=\"p\">{</span>\n    <span class=\"nl\">position</span><span class=\"p\">:</span> <span class=\"n\">sticky</span><span class=\"p\">;</span>\n    <span class=\"nl\">top</span><span class=\"p\">:</span> <span class=\"m\">20px</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"performance-on-older-browsers\">Performance on Older Browsers</h2>\n\n<h3 id=\"reduce-javascript-bundle-size\">Reduce JavaScript Bundle Size</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Only load for modern browsers --&gt;</span>\n<span class=\"nt\">&lt;script </span><span class=\"na\">type=</span><span class=\"s\">\"module\"</span> <span class=\"na\">src=</span><span class=\"s\">\"/assets/js/modern.js\"</span><span class=\"nt\">&gt;&lt;/script&gt;</span>\n\n<span class=\"c\">&lt;!-- Fallback for older browsers --&gt;</span>\n<span class=\"nt\">&lt;script </span><span class=\"na\">nomodule</span> <span class=\"na\">src=</span><span class=\"s\">\"/assets/js/legacy.js\"</span><span class=\"nt\">&gt;&lt;/script&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"optimize-for-mobile\">Optimize for Mobile</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Responsive images --&gt;</span>\n<span class=\"nt\">&lt;picture&gt;</span>\n  <span class=\"nt\">&lt;source</span>\n    <span class=\"na\">srcset=</span><span class=\"s\">\"\n      image-large.webp  1200w,\n      image-medium.webp  800w,\n      image-small.webp   400w\n    \"</span>\n    <span class=\"na\">type=</span><span class=\"s\">\"image/webp\"</span>\n  <span class=\"nt\">/&gt;</span>\n  <span class=\"nt\">&lt;img</span>\n    <span class=\"na\">src=</span><span class=\"s\">\"image.jpg\"</span>\n    <span class=\"na\">srcset=</span><span class=\"s\">\"image-large.jpg 1200w, image-medium.jpg 800w, image-small.jpg 400w\"</span>\n    <span class=\"na\">sizes=</span><span class=\"s\">\"(max-width: 600px) 400px, (max-width: 900px) 800px, 1200px\"</span>\n    <span class=\"na\">alt=</span><span class=\"s\">\"Description\"</span>\n  <span class=\"nt\">/&gt;</span>\n<span class=\"nt\">&lt;/picture&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"browser-detection\">Browser Detection</h2>\n\n<h3 id=\"user-agent-detection-not-recommended\">User Agent Detection (Not Recommended)</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// Avoid this approach</span>\n<span class=\"kd\">const</span> <span class=\"nx\">isIE</span> <span class=\"o\">=</span> <span class=\"sr\">/MSIE|Trident/</span><span class=\"p\">.</span><span class=\"nx\">test</span><span class=\"p\">(</span><span class=\"nb\">navigator</span><span class=\"p\">.</span><span class=\"nx\">userAgent</span><span class=\"p\">);</span>\n</code></pre></div></div>\n\n<h3 id=\"feature-detection-recommended\">Feature Detection (Recommended)</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// Detect features, not browsers</span>\n<span class=\"kd\">const</span> <span class=\"nx\">supportsGrid</span> <span class=\"o\">=</span> <span class=\"nx\">CSS</span><span class=\"p\">.</span><span class=\"nx\">supports</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">display</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">grid</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n<span class=\"kd\">const</span> <span class=\"nx\">supportsCustomProperties</span> <span class=\"o\">=</span> <span class=\"nx\">CSS</span><span class=\"p\">.</span><span class=\"nx\">supports</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">--custom</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">property</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">supportsGrid</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">.</span><span class=\"nx\">classList</span><span class=\"p\">.</span><span class=\"nx\">add</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">supports-grid</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"testing-checklist\">Testing Checklist</h2>\n\n<ul class=\"task-list\">\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Test in Chrome, Firefox, Safari, Edge</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Test on iOS Safari and Android Chrome</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Verify responsive design at multiple breakpoints</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Check with JavaScript disabled</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Test with screen readers</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Verify keyboard navigation</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Check CSS Grid/Flexbox layouts</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Test custom properties (CSS variables)</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Verify backdrop-filter fallbacks</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Check font loading</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Test lazy loading functionality</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Verify service worker (if implemented)</li>\n</ul>\n\n<h2 id=\"resources\">Resources</h2>\n\n<ul>\n  <li><a href=\"https://caniuse.com/\">Can I Use</a> - Browser feature support tables</li>\n  <li><a href=\"https://developer.mozilla.org/en-US/docs/Web/Guide/Browser_Detection_and_Cross_Browser_Support\">MDN Browser Compatibility</a></li>\n  <li><a href=\"https://autoprefixer.github.io/\">Autoprefixer</a> - Automatic vendor prefixes</li>\n  <li><a href=\"https://polyfill.io/\">Polyfill.io</a> - Automatic polyfills</li>\n  <li><a href=\"https://www.browserstack.com/\">BrowserStack</a> - Cross-browser testing</li>\n</ul>\n\n<h2 id=\"next-steps\">Next Steps</h2>\n\n<ul>\n  <li><a href=\"accessibility.html\">Accessibility Guide</a> - Inclusive design</li>\n  <li><a href=\"performance.html\">Performance Guide</a> - Optimization</li>\n  <li><a href=\"common-errors.html\">Common Errors</a> - Troubleshooting</li>\n</ul>\n</article>\n\n        <section\n          class=\"feedback-card\"\n          id=\"feedback-card\"\n          aria-label=\"Page feedback\"\n        >\n          <div class=\"feedback-header\">\n            <div>\n              <p class=\"feedback-kicker\">Feedback</p>\n              <h3>Was this page helpful?</h3>\n              <p class=\"feedback-subtext\">\n                Share quick feedback to improve these docs.\n              </p>\n            </div>\n            <div class=\"feedback-badges\" aria-label=\"Applies to versions\">\n                  \n              <span class=\"version-badge\" aria-label=\"Minecraft 1.21.x\"\n                >1.21.x</span\n              >\n               \n            </div>\n          </div>\n\n          <div class=\"feedback-actions\" role=\"group\" aria-label=\"Helpful?\">\n            <button type=\"button\" class=\"feedback-btn yes\" data-feedback=\"yes\">\n              <i class=\"fa-solid fa-thumbs-up\"></i>\n              Yes\n            </button>\n            <button type=\"button\" class=\"feedback-btn no\" data-feedback=\"no\">\n              <i class=\"fa-solid fa-thumbs-down\"></i>\n              No\n            </button>\n          </div>\n\n          <div class=\"feedback-followup\" id=\"feedback-followup\" hidden>\n            <label for=\"feedback-notes\">What can we improve?</label>\n            <textarea\n              id=\"feedback-notes\"\n              rows=\"3\"\n              placeholder=\"Optional: missing steps, unclear wording, broken links\"\n            ></textarea>\n            <button type=\"button\" class=\"feedback-submit\" id=\"feedback-submit\">\n              <i class=\"fa-solid fa-paper-plane\"></i>\n              Send feedback\n            </button>\n          </div>\n\n          <p\n            class=\"feedback-status\"\n            id=\"feedback-status\"\n            role=\"status\"\n            aria-live=\"polite\"\n          ></p>\n        </section>\n\n        <!-- Page Navigation (Prev/Next) -->\n                                                 \n      </main>\n\n      <!-- Table of Contents (optional) -->\n      <aside class=\"docs-toc\">\n        <div class=\"toc-header\">\n          <h3>On This Page</h3>\n        </div>\n        <nav id=\"toc-nav\" class=\"toc-nav\">\n          <!-- Generated by JavaScript -->\n        </nav>\n\n        <!-- Theme Toggle in TOC -->\n        <button\n          id=\"theme-toggle-docs\"\n          class=\"theme-toggle\"\n          aria-label=\"Toggle theme\"\n        >\n          <i class=\"fa-solid fa-sun\"></i>\n          <i class=\"fa-solid fa-moon\"></i>\n        </button>\n      </aside>\n    </div>\n\n    <script>\n      // Theme Toggle\n      const themeToggle = document.getElementById(\"theme-toggle-docs\");\n      themeToggle?.addEventListener(\"click\", () => {\n        const current = document.documentElement.getAttribute(\"data-theme\");\n        const next = current === \"light\" ? \"dark\" : \"light\";\n        document.documentElement.setAttribute(\"data-theme\", next);\n        localStorage.setItem(\"theme\", next);\n      });\n\n      // Mobile Sidebar Toggle\n      const mobileToggle = document.getElementById(\"mobile-sidebar-toggle\");\n      const sidebar = document.getElementById(\"docs-sidebar\");\n      const overlay = document.getElementById(\"sidebar-overlay\");\n      const sidebarClose = document.getElementById(\"sidebar-close\");\n\n      function toggleSidebar() {\n        sidebar.classList.toggle(\"open\");\n        overlay.classList.toggle(\"active\");\n        document.body.style.overflow = sidebar.classList.contains(\"open\")\n          ? \"hidden\"\n          : \"\";\n      }\n\n      mobileToggle?.addEventListener(\"click\", toggleSidebar);\n      overlay?.addEventListener(\"click\", toggleSidebar);\n      sidebarClose?.addEventListener(\"click\", toggleSidebar);\n\n      // Category Toggle\n      document.querySelectorAll(\".category-toggle\").forEach((toggle) => {\n        toggle.addEventListener(\"click\", () => {\n          const category = toggle.dataset.category;\n          const items = document.getElementById(`category-${category}`);\n          toggle.classList.toggle(\"active\");\n          items.classList.toggle(\"expanded\");\n        });\n      });\n\n      // Generate Table of Contents\n      const content = document.querySelector(\".docs-content article\");\n      const tocNav = document.getElementById(\"toc-nav\");\n\n      if (content && tocNav) {\n        const headings = content.querySelectorAll(\"h2, h3\");\n\n        if (headings.length > 0) {\n          headings.forEach((heading, index) => {\n            // Add ID if not present\n            if (!heading.id) {\n              heading.id = heading.textContent\n                .toLowerCase()\n                .replace(/[^a-z0-9]+/g, \"-\")\n                .replace(/^-|-$/g, \"\");\n            }\n\n            const link = document.createElement(\"a\");\n            link.href = `#${heading.id}`;\n            link.textContent = heading.textContent;\n            link.className = `toc-link toc-${heading.tagName.toLowerCase()}`;\n            tocNav.appendChild(link);\n          });\n\n          // Highlight current section\n          const observer = new IntersectionObserver(\n            (entries) => {\n              entries.forEach((entry) => {\n                if (entry.isIntersecting) {\n                  const id = entry.target.id;\n                  tocNav.querySelectorAll(\".toc-link\").forEach((link) => {\n                    link.classList.toggle(\n                      \"active\",\n                      link.getAttribute(\"href\") === `#${id}`\n                    );\n                  });\n                }\n              });\n            },\n            { rootMargin: \"-20% 0px -80% 0px\" }\n          );\n\n          headings.forEach((heading) => observer.observe(heading));\n        }\n      }\n\n      // Sidebar Search\n      const sidebarSearch = document.getElementById(\"sidebar-search\");\n      sidebarSearch?.addEventListener(\"input\", (e) => {\n        const query = e.target.value.toLowerCase();\n        const items = document.querySelectorAll(\".nav-item\");\n\n        items.forEach((item) => {\n          const text = item.textContent.toLowerCase();\n          const matches = text.includes(query);\n          item.style.display = matches || !query ? \"\" : \"none\";\n\n          // Expand category if item matches\n          if (matches && query) {\n            const category = item.closest(\".category-items\");\n            const toggle = category?.previousElementSibling;\n            category?.classList.add(\"expanded\");\n            toggle?.classList.add(\"active\");\n          }\n        });\n      });\n\n      // Docs micro-feedback (local only)\n      const feedbackCard = document.getElementById(\"feedback-card\");\n      const feedbackButtons = document.querySelectorAll(\".feedback-btn\");\n      const feedbackFollowup = document.getElementById(\"feedback-followup\");\n      const feedbackSubmit = document.getElementById(\"feedback-submit\");\n      const feedbackStatus = document.getElementById(\"feedback-status\");\n      const feedbackNotes = document.getElementById(\"feedback-notes\");\n      const feedbackStorageKey = `docs-feedback:${window.location.pathname}`;\n\n      function completeFeedback(message) {\n        if (feedbackCard) feedbackCard.classList.add(\"feedback-complete\");\n        if (feedbackFollowup) feedbackFollowup.hidden = true;\n        if (feedbackStatus) feedbackStatus.textContent = message;\n        try {\n          localStorage.setItem(feedbackStorageKey, \"submitted\");\n        } catch (err) {\n          console.warn(\"Feedback storage failed\", err);\n        }\n      }\n\n      function maybeDisableFeedback() {\n        let stored = null;\n        try {\n          stored = localStorage.getItem(feedbackStorageKey);\n        } catch (err) {\n          console.warn(\"Feedback storage read failed\", err);\n        }\n\n        if (stored && feedbackCard) {\n          feedbackCard.classList.add(\"feedback-complete\");\n          if (feedbackFollowup) feedbackFollowup.hidden = true;\n          if (feedbackStatus)\n            feedbackStatus.textContent = \"Thanks—feedback already recorded.\";\n        }\n      }\n\n      feedbackButtons.forEach((btn) => {\n        btn.addEventListener(\"click\", () => {\n          const value = btn.dataset.feedback;\n          if (value === \"no\") {\n            if (feedbackFollowup) feedbackFollowup.hidden = false;\n            if (feedbackStatus)\n              feedbackStatus.textContent = \"Tell us what to improve.\";\n          } else {\n            completeFeedback(\"Thanks for the feedback!\");\n          }\n        });\n      });\n\n      feedbackSubmit?.addEventListener(\"click\", () => {\n        const note = feedbackNotes?.value?.trim();\n        const suffix = note ? \" We will review your note.\" : \"\";\n        completeFeedback(`Got it!${suffix}`);\n      });\n\n      maybeDisableFeedback();\n    </script>\n  </body>\n</html>\n","# Common Errors & Troubleshooting\n\nQuick solutions to common issues you might encounter.\n\n## Build Errors\n\n### Jekyll Build Fails\n\n**Error**: `jekyll 3.9.0 | Error:  Permission denied`\n\n**Solution**:\n\n```bash\n# Fix permissions\nchmod -R 755 _site\n\n# Or clean and rebuild\nbundle exec jekyll clean\nbundle exec jekyll build\n```\n\n**Error**: `Dependency Error: Yikes! It looks like you don't have bundler`\n\n**Solution**:\n\n```bash\ngem install bundler\nbundle install\n```\n\n**Error**: `Could not find gem 'jekyll'`\n\n**Solution**:\n\n```bash\nbundle install\n# Or\ngem install jekyll\n```\n\n### Liquid Syntax Errors\n\n**Error**: `Liquid Exception: Liquid syntax error`\n\n**Solution**:\n\n{% raw %}\n\n```liquid\n<!-- Bad: Unclosed tag -->\n{% for item in array\n\n<!-- Good: Properly closed -->\n{% for item in array %}\n  {{ item }}\n{% endfor %}\n```\n\n{% endraw %}\n\n**Error**: `undefined method 'map' for nil:NilClass`\n\n**Solution**:\n\n```liquid\n<!-- Check if variable exists first -->\n{% if site.data.mods.modpacks %}\n  {% assign names = site.data.mods.modpacks | map: \"name\" %}\n{% endif %}\n```\n\n### YAML Frontmatter Issues\n\n**Error**: `YAML Exception reading file`\n\n**Solution**:\n\n```yaml\n# Bad: Missing closing quotes\n---\ntitle: \"My Title\n---\n\n# Good: Properly quoted\n---\ntitle: \"My Title\"\ndescription: \"My description\"\n---\n\n# Or use literal block for multiline\n---\ntitle: My Title\ndescription: |\n  This is a longer\n  description text\n---\n```\n\n## Styling Issues\n\n### Styles Not Loading\n\n**Problem**: CSS changes not appearing\n\n**Solutions**:\n\n```bash\n# 1. Clear cache\nbundle exec jekyll clean\nbundle exec jekyll build\n\n# 2. Hard refresh browser\n# Mac: Cmd + Shift + R\n# Windows/Linux: Ctrl + Shift + R\n\n# 3. Check file path\n# Should be: {{ '/assets/css/main.css' | relative_url }}\n# Not: /assets/css/main.css (without filter)\n```\n\n### CSS Not Compiling\n\n**Error**: `Sass Error: Invalid CSS`\n\n**Solution**:\n\n```scss\n// Bad: Missing semicolon\n.element {\n  color: red\n  background: blue;\n}\n\n// Good:\n.element {\n  color: red;\n  background: blue;\n}\n```\n\n### Theme Toggle Not Working\n\n**Problem**: Theme switch doesn't persist\n\n**Solution**:\n\n```javascript\n// Check localStorage is working\nif (typeof Storage !== \"undefined\") {\n  localStorage.setItem(\"theme\", \"dark\");\n  console.log(localStorage.getItem(\"theme\"));\n} else {\n  console.error(\"LocalStorage not supported\");\n}\n\n// Ensure theme is set on page load\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n  const theme = localStorage.getItem(\"theme\") || \"dark\";\n  document.documentElement.setAttribute(\"data-theme\", theme);\n});\n```\n\n## Asset Loading Issues\n\n### Images Not Displaying\n\n**Problem**: Broken image icons\n\n**Solutions**:\n\n```liquid\n<!-- Bad: Absolute path without baseurl -->\n<img src=\"/assets/images/logo.png\">\n\n<!-- Good: Use relative_url filter -->\n<img src=\"{{ '/assets/images/logo.png' | relative_url }}\">\n\n<!-- For external URLs -->\n<img src=\"https://cdn.modrinth.com/data/abc/icon.png\">\n```\n\n**Check file exists**:\n\n```bash\n# List image directory\nls -la assets/images/\n\n# Check file permissions\nchmod 644 assets/images/logo.png\n```\n\n### Font Awesome Icons Not Showing\n\n**Problem**: Boxes or missing icons\n\n**Solutions**:\n\n```html\n<!-- 1. Verify CDN link is correct -->\n<link\n  rel=\"stylesheet\"\n  href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n/>\n\n<!-- 2. Check icon class syntax -->\n<!-- Bad -->\n<i class=\"fa-gear\"></i>\n\n<!-- Good -->\n<i class=\"fa-solid fa-gear\"></i>\n```\n\n**Test icon loading**:\n\n```javascript\n// Check if Font Awesome loaded\nif (window.FontAwesome) {\n  console.log(\"Font Awesome loaded\");\n} else {\n  console.error(\"Font Awesome not loaded\");\n}\n```\n\n## Data Issues\n\n### Modpack Data Not Rendering\n\n**Problem**: Projects page is empty\n\n**Solutions**:\n\n```bash\n# 1. Check JSON is valid\ncat _data/mods.json | jq .\n\n# 2. Verify file location\nls -la _data/mods.json\n\n# 3. Check YAML config\ngrep -A 5 \"data_dir\" _config.yml\n```\n\n**Debug in template**:\n\n```liquid\n<!-- Check if data exists -->\n{% if site.data.mods %}\n  <p>Data loaded: {{ site.data.mods.modpacks | size }} modpacks</p>\n{% else %}\n  <p>No data found</p>\n{% endif %}\n\n<!-- Inspect data structure -->\n<pre>{{ site.data.mods | jsonify }}</pre>\n```\n\n### JSON Parsing Errors\n\n**Error**: `Unexpected token in JSON`\n\n**Solution**:\n\n```bash\n# Validate JSON\ncat _data/mods.json | python -m json.tool\n\n# Or use jq\njq '.' _data/mods.json\n```\n\nCommon JSON mistakes:\n\n```json\n// Bad: Trailing comma\n{\n  \"modpacks\": [\n    {\"name\": \"Pack 1\"},\n  ]\n}\n\n// Good: No trailing comma\n{\n  \"modpacks\": [\n    {\"name\": \"Pack 1\"}\n  ]\n}\n\n// Bad: Single quotes\n{'name': 'value'}\n\n// Good: Double quotes\n{\"name\": \"value\"}\n```\n\n## Deployment Issues\n\n### GitHub Pages 404 Error\n\n**Problem**: Pages work locally but 404 on GitHub Pages\n\n**Solutions**:\n\n```yaml\n# 1. Check baseurl in _config.yml\nbaseurl: \"/your-repo-name\" # Must match repo name\nurl: \"https://username.github.io\"\n# 2. Ensure GitHub Pages is enabled\n# Settings > Pages > Source: GitHub Actions or main branch\n```\n\n```liquid\n<!-- Use relative_url in all links -->\n<a href=\"{{ '/docs/' | relative_url }}\">Docs</a>\n<link rel=\"stylesheet\" href=\"{{ '/assets/css/main.css' | relative_url }}\">\n```\n\n### Build Succeeds But Site Not Updating\n\n**Solutions**:\n\n```bash\n# 1. Clear GitHub Actions cache\n# Go to Actions > Select workflow > Re-run jobs > Clear cache\n\n# 2. Check deployment status\n# Actions tab > View latest workflow run\n\n# 3. Verify _config.yml excludes\nexclude:\n  - node_modules/\n  - vendor/\n  - .git/\n```\n\n### Netlify Build Fails\n\n**Error**: `Command failed with exit code 127`\n\n**Solution**:\n\n```toml\n# netlify.toml\n[build.environment]\n  RUBY_VERSION = \"3.1\"\n\n[build]\n  command = \"bundle install && bundle exec jekyll build\"\n  publish = \"_site\"\n```\n\n## Performance Issues\n\n### Slow Build Times\n\n**Problem**: Build takes 30+ seconds\n\n**Solutions**:\n\n```yaml\n# 1. Exclude unnecessary files\nexclude:\n  - node_modules/\n  - src/\n  - vendor/\n  - .git/\n  - README.md\n\n# 2. Use incremental builds (dev only)\n# bundle exec jekyll serve --incremental\n\n# 3. Limit collection size\ncollections:\n  docs:\n    output: true\n```\n\n### Slow Page Load\n\n**Problem**: Pages take 5+ seconds to load\n\n**Solutions**:\n\n```html\n<!-- 1. Defer non-critical CSS -->\n<link\n  rel=\"preload\"\n  href=\"/assets/css/main.css\"\n  as=\"style\"\n  onload=\"this.rel='stylesheet'\"\n/>\n\n<!-- 2. Lazy load images -->\n<img src=\"image.jpg\" loading=\"lazy\" />\n\n<!-- 3. Defer JavaScript -->\n<script src=\"/assets/js/main.js\" defer></script>\n```\n\nSee [Performance Guide](performance.html) for more.\n\n## Search & Filter Issues\n\n### Search Not Working\n\n**Problem**: Typing in search input doesn't filter results\n\n**Debug**:\n\n```javascript\n// Check if docs are loaded\nconsole.log(\"Total docs:\", allDocs.length);\n\n// Test search function\nconst results = searchDocs(\"setup\");\nconsole.log(\"Search results:\", results);\n\n// Verify event listener\ndocument.getElementById(\"docs-search\").addEventListener(\"input\", (e) => {\n  console.log(\"Search query:\", e.target.value);\n});\n```\n\n**Common fixes**:\n\n```javascript\n// Ensure correct element IDs\nconst searchInput = document.getElementById(\"docs-search\");\nconst categorySelect = document.getElementById(\"docs-category\");\n\n// Case-insensitive search\nconst query = searchInput.value.toLowerCase();\nconst matches = allDocs.filter((doc) =>\n  doc.title.toLowerCase().includes(query)\n);\n```\n\n## Browser Compatibility\n\n### Site Broken in Safari\n\n**Problem**: CSS Grid not working\n\n**Solution**:\n\n```css\n/* Add fallback for older browsers */\n.grid {\n  display: flex;\n  flex-wrap: wrap;\n}\n\n@supports (display: grid) {\n  .grid {\n    display: grid;\n    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n  }\n}\n```\n\n### JavaScript Errors in IE11\n\n**Problem**: `Unexpected token` errors\n\n**Solution**:\n\n```javascript\n// Don't use arrow functions in IE11\n// Bad:\nconst myFunc = () => {};\n\n// Good:\nvar myFunc = function () {};\n\n// Or add polyfills\n// <script src=\"https://polyfill.io/v3/polyfill.min.js\"></script>\n```\n\n## Git Issues\n\n### Large Files Rejected\n\n**Error**: `remote: error: File too large`\n\n**Solution**:\n\n```bash\n# Remove large file from history\ngit filter-branch --force --index-filter \\\n  'git rm --cached --ignore-unmatch path/to/large-file' \\\n  --prune-empty --tag-name-filter cat -- --all\n\n# Force push\ngit push origin --force --all\n\n# Add to .gitignore\necho \"path/to/large-files/\" >> .gitignore\n```\n\n### Merge Conflicts\n\n**Problem**: `CONFLICT (content): Merge conflict in file`\n\n**Solution**:\n\n```bash\n# View conflicted files\ngit status\n\n# Edit file to resolve conflicts\n# Look for:\n<<<<<<< HEAD\nYour changes\n=======\nTheir changes\n>>>>>>> branch-name\n\n# Choose one or combine, then:\ngit add resolved-file.txt\ngit commit -m \"Resolved merge conflict\"\n```\n\n## Debugging Tips\n\n### Enable Verbose Output\n\n```bash\n# Jekyll\nbundle exec jekyll build --verbose\n\n# Show full error traces\nbundle exec jekyll build --trace\n\n# Profile build time\nbundle exec jekyll build --profile\n```\n\n### Browser DevTools\n\n```javascript\n// Check for JavaScript errors\n// Open DevTools > Console\n\n// Inspect element styles\n// Right-click > Inspect\n\n// Network tab for asset loading\n// DevTools > Network > Reload page\n```\n\n### Liquid Debugging\n\n```liquid\n<!-- Print variable contents -->\n{{ variable | inspect }}\n\n<!-- Check variable type -->\n{% if variable == nil %}\n  Variable is nil\n{% elsif variable == blank %}\n  Variable is blank\n{% else %}\n  Variable exists: {{ variable }}\n{% endif %}\n\n<!-- Debug entire site data -->\n<pre>{{ site | jsonify }}</pre>\n```\n\n## Getting Help\n\n### Before Asking\n\n1. **Search existing issues** on GitHub\n2. **Check documentation** thoroughly\n3. **Test in fresh browser** (incognito mode)\n4. **Try latest version** of dependencies\n5. **Create minimal reproduction** of the issue\n\n### Where to Ask\n\n- [Jekyll Talk Forum](https://talk.jekyllrb.com/)\n- [Stack Overflow](https://stackoverflow.com/questions/tagged/jekyll) - Tag with `jekyll`\n- [GitHub Issues](https://github.com/jekyll/jekyll/issues)\n- Project-specific Discord/community\n\n### Provide Details\n\nWhen reporting issues, include:\n\n```markdown\n**Environment:**\n\n- OS: macOS 13.0\n- Ruby: 3.1.2\n- Jekyll: 3.9.0\n- Browser: Chrome 120\n\n**Steps to reproduce:**\n\n1. Run `bundle exec jekyll serve`\n2. Navigate to /projects/\n3. Click on first project\n\n**Expected:** Project page loads\n**Actual:** 404 error\n\n**Logs:**\n```\n\n[error log here]\n\n```\n\n```\n\n## Next Steps\n\n- [FAQ](faq.html) - Frequently asked questions\n- [Contributing](contributing.html) - Report bugs and contribute\n- [GitHub Actions](github-actions.html) - Automate testing\n","# Content Guidelines\n\nMaintain consistent, high-quality content across your ABC showcase.\n\n## Writing Style\n\n### Voice & Tone\n\n**Be Clear and Concise:**\n\n```markdown\n<!-- Good -->\n\nInstall dependencies with `bundle install`.\n\n<!-- Avoid -->\n\nYou should probably install the dependencies using the bundle install command.\n```\n\n**Be Helpful:**\n\n```markdown\n<!-- Good -->\n\nIf the build fails, check your Ruby version with `ruby -v`.\n\n<!-- Avoid -->\n\nThe build might fail for various reasons.\n```\n\n**Be Friendly:**\n\n```markdown\n<!-- Good -->\n\nGreat! Your site is now live.\n\n<!-- Avoid -->\n\nThe deployment process has completed successfully.\n```\n\n### Grammar & Formatting\n\n**Use Active Voice:**\n\n```markdown\n<!-- Good -->\n\nRun `jekyll build` to compile your site.\n\n<!-- Avoid -->\n\nYour site can be compiled by running `jekyll build`.\n```\n\n**Use Present Tense:**\n\n```markdown\n<!-- Good -->\n\nThe theme toggle changes between light and dark mode.\n\n<!-- Avoid -->\n\nThe theme toggle will change between light and dark mode.\n```\n\n**Use Second Person:**\n\n```markdown\n<!-- Good -->\n\nYou can customize colors in `src/styles/variables.css`.\n\n<!-- Avoid -->\n\nUsers can customize colors in `src/styles/variables.css`.\n```\n\n## Documentation Structure\n\n### Page Template\n\n```yaml\n---\nlayout: docs\ntitle: Clear, Descriptive Title\ndescription: One-sentence summary of what this page covers.\nnav_order: 5\ncategory: Setup\ntags: [relevant, searchable, tags]\n---\n\n# Page Title\n\nBrief introduction explaining what users will learn.\n\n## Section 1\n\nContent with examples...\n\n## Section 2\n\nMore content...\n\n## Next Steps\n\n- [Related Page 1](link1.html)\n- [Related Page 2](link2.html)\n```\n\n### Headings\n\nUse hierarchical structure:\n\n```markdown\n# H1 - Page Title (only one per page)\n\n## H2 - Major Section\n\n### H3 - Subsection\n\n#### H4 - Minor Point\n\n##### H5 - Rarely Used\n\n###### H6 - Avoid\n```\n\n**Good Heading Structure:**\n\n```markdown\n# Deployment Guide\n\n## Prerequisites\n\n## GitHub Pages\n\n### Configuration\n\n### Deployment\n\n## Netlify\n\n### Configuration\n```\n\n## Code Examples\n\n### Format Code Blocks\n\nUse language-specific syntax highlighting:\n\n````markdown\n```bash\n# Bash commands\nbundle exec jekyll build\n```\n\n```yaml\n# YAML configuration\ntitle: My Site\nbaseurl: /my-site\n```\n\n```javascript\n// JavaScript code\nfunction toggleTheme() {\n  // ...\n}\n```\n\n```liquid\n<!-- Liquid templates -->\n{% for item in array %}\n  {{ item }}\n{% endfor %}\n```\n````\n\n### Inline Code\n\nUse backticks for:\n\n- Commands: `bundle install`\n- File names: `_config.yml`\n- Code variables: `site.title`\n- Short code: `npm start`\n\n```markdown\nEdit the `_config.yml` file and set `baseurl` to your repository name.\n```\n\n### Example Comments\n\n```javascript\n// Good: Explain WHY, not WHAT\n// Cache the theme value to avoid repeated lookups\nconst theme = localStorage.getItem(\"theme\");\n\n// Avoid: Explaining obvious code\n// Get theme from localStorage\nconst theme = localStorage.getItem(\"theme\");\n```\n\n## Links & References\n\n### Internal Links\n\n```liquid\n<!-- Use relative_url filter -->\nSee the [setup guide]({{ '/docs/setup/' | relative_url }}).\n\n<!-- Or for same section -->\nSee [Configuration](#configuration) below.\n```\n\n### External Links\n\n```markdown\n<!-- Open in new tab with security -->\n\nVisit [Modrinth](https://modrinth.com/){:target=\"\\_blank\" rel=\"noopener\"}.\n\n<!-- Or in HTML -->\n\n<a href=\"https://modrinth.com/\" target=\"_blank\" rel=\"noopener\">Modrinth</a>\n```\n\n### Link Text\n\n```markdown\n<!-- Good: Descriptive -->\n\nRead the [deployment guide](deployment.html) for more details.\n\n<!-- Avoid: Generic -->\n\nClick [here](deployment.html) to learn more.\n```\n\n## Lists\n\n### Unordered Lists\n\n```markdown\n- First item\n- Second item\n  - Nested item\n  - Another nested item\n- Third item\n```\n\n### Ordered Lists\n\n```markdown\n1. First step\n2. Second step\n   1. Substep\n   2. Another substep\n3. Third step\n```\n\n### Task Lists\n\n```markdown\n- [x] Completed task\n- [ ] Pending task\n- [ ] Another pending task\n```\n\n## Tables\n\n### Simple Tables\n\n```markdown\n| Header 1 | Header 2 | Header 3 |\n| -------- | -------- | -------- |\n| Cell 1   | Cell 2   | Cell 3   |\n| Cell 4   | Cell 5   | Cell 6   |\n```\n\n### Alignment\n\n```markdown\n| Left | Center | Right |\n| :--- | :----: | ----: |\n| L1   |   C1   |    R1 |\n| L2   |   C2   |    R2 |\n```\n\n### Complex Tables\n\n```markdown\n| Field       | Type   | Required | Description       |\n| ----------- | ------ | -------- | ----------------- |\n| `slug`      | string | Yes      | Unique identifier |\n| `name`      | string | Yes      | Display name      |\n| `downloads` | number | No       | Download count    |\n```\n\n## Admonitions & Callouts\n\n### Info Boxes\n\n```markdown\n> **Note:** This feature requires Jekyll 3.9 or higher.\n\n> **Tip:** Use incremental builds during development for faster rebuilds.\n\n> **Warning:** Clearing the cache will remove all saved preferences.\n\n> **Important:** Always backup your data before making major changes.\n```\n\n### Code with Explanations\n\n````markdown\nRun the following command:\n\n```bash\nbundle exec jekyll build --verbose\n```\n````\n\nThis will:\n\n- Build your site\n- Show detailed output\n- Help identify errors\n\n````\n\n## Images\n\n### Inline Images\n\n```markdown\n![Alt text description](/assets/images/screenshot.png)\n````\n\n### Images with Captions\n\n```html\n<figure>\n  <img src=\"/assets/images/demo.png\" alt=\"Demo screenshot\" />\n  <figcaption>The project card layout showing icons and badges</figcaption>\n</figure>\n```\n\n### Responsive Images\n\n```html\n<picture>\n  <source srcset=\"/assets/images/hero-large.webp\" media=\"(min-width: 1024px)\" />\n  <source srcset=\"/assets/images/hero-medium.webp\" media=\"(min-width: 768px)\" />\n  <img src=\"/assets/images/hero-small.webp\" alt=\"Hero banner\" />\n</picture>\n```\n\n## File & Path References\n\n### Consistent Formatting\n\n```markdown\n<!-- Files -->\n\nEdit `_config.yml`\nOpen `src/styles/layout.css`\nCheck `_data/mods.json`\n\n<!-- Directories -->\n\nNavigate to `_docs/`\nCreate `assets/images/`\n\n<!-- Paths -->\n\n`/docs/setup/`\n`https://yoursite.com/projects/`\n```\n\n### File Trees\n\n```\nproject/\n├── _config.yml\n├── _data/\n│   └── mods.json\n├── _docs/\n│   ├── getting-started.md\n│   └── setup.md\n├── assets/\n│   ├── css/\n│   └── images/\n└── index.md\n```\n\n## Command Line Examples\n\n### Format\n\n```bash\n# Comment explaining what this does\ncommand --flag argument\n\n# Example output (optional)\n# > Success message\n```\n\n### Multiple Commands\n\n```bash\n# Install dependencies\nbundle install\n\n# Build the site\nbundle exec jekyll build\n\n# Serve locally\nbundle exec jekyll serve\n```\n\n### Interactive Sessions\n\n```bash\n$ git status\nOn branch main\nYour branch is up to date with 'origin/main'.\n\n$ git add .\n$ git commit -m \"Update documentation\"\n[main abc1234] Update documentation\n 1 file changed, 10 insertions(+)\n```\n\n## Modpack Descriptions\n\n### Structure\n\n```markdown\n**Name**: Clear, memorable name\n**Description**: 1-2 sentences summarizing the pack\n**Key Features**:\n\n- Feature 1\n- Feature 2\n- Feature 3\n\n**Recommended For**: Target audience\n```\n\n### Example\n\n```markdown\n**Name**: Create: Engineering Adventures\n\n**Description**: A technology-focused modpack centered around the Create mod, offering complex automation challenges and engineering puzzles suitable for both solo and multiplayer gameplay.\n\n**Key Features**:\n\n- 150+ mods focused on automation and engineering\n- Custom quests guiding progression\n- Balanced for survival gameplay\n- Multiplayer-optimized\n\n**Recommended For**: Players who enjoy technical challenges and building complex machines\n```\n\n### Writing Tips\n\n**Be Specific:**\n\n```markdown\n<!-- Good -->\n\nIncludes 50+ magic mods with custom spell progression\n\n<!-- Avoid -->\n\nHas magic stuff\n```\n\n**Highlight Unique Features:**\n\n```markdown\n<!-- Good -->\n\nFeatures a unique progression system that unlocks mods as you complete challenges\n\n<!-- Avoid -->\n\nHas progression\n```\n\n**Mention Prerequisites:**\n\n```markdown\n<!-- Good -->\n\nRequires 8GB+ RAM. Best with 16GB.\n\n<!-- Avoid -->\n\nNeeds memory\n```\n\n## Version Numbers\n\n### Format\n\n```markdown\n<!-- Semantic versioning -->\n\nv1.2.3\nVersion 2.0.0\n\n<!-- Minecraft versions -->\n\n1.20.1\n1.19.2-1.20.1\n\n<!-- Mod loader versions -->\n\nFabric 0.14.21\nForge 47.1.0\n```\n\n## Dates & Times\n\n### Format\n\n```markdown\n<!-- ISO 8601 for data -->\n\n2025-12-10T10:30:00Z\n\n<!-- Human-readable for display -->\n\nDecember 10, 2025\nDec 10, 2025\n2025-12-10\n```\n\n## Accessibility\n\n### Alt Text\n\n```markdown\n<!-- Descriptive alt text -->\n\n![Project card showing Create Adventures modpack with green icon and 50K downloads](/path/to/image.png)\n\n<!-- Not just the file name -->\n\n![screenshot-1.png](/path/to/image.png)\n```\n\n### Link Descriptions\n\n```markdown\n<!-- Good -->\n\nRead the [accessibility guide](accessibility.html) for WCAG compliance details\n\n<!-- Avoid -->\n\n[Click here](accessibility.html) for more\n```\n\n## SEO Best Practices\n\n### Meta Descriptions\n\n```yaml\n---\ntitle: Setup Guide\ndescription: Learn how to set up your ABC showcase in under 5 minutes with this step-by-step guide.\n---\n```\n\n**Requirements:**\n\n- 150-160 characters\n- Include target keyword\n- Be compelling\n- Unique per page\n\n### Keywords in Content\n\n```markdown\n<!-- Natural keyword usage -->\n\nThis **deployment guide** shows you how to **deploy your Jekyll site** to GitHub Pages, Netlify, or Vercel.\n\n<!-- Avoid keyword stuffing -->\n\nDeploy deployment deploying Jekyll Jekyll site site deploy...\n```\n\n## Review Checklist\n\nBefore publishing content:\n\n- [ ] Spelling and grammar checked\n- [ ] Code examples tested and working\n- [ ] Links verified (no 404s)\n- [ ] Images optimized and have alt text\n- [ ] Headings follow hierarchy (H1 → H2 → H3)\n- [ ] Consistent formatting throughout\n- [ ] Meta description written (150-160 chars)\n- [ ] Tags relevant and useful\n- [ ] Category assigned correctly\n- [ ] Mobile-friendly formatting\n- [ ] Accessible to screen readers\n- [ ] Next steps / related links included\n\n## Style Guide Summary\n\n| Element     | Format                              |\n| ----------- | ----------------------------------- |\n| Commands    | `backticks`                         |\n| Files       | `_config.yml`                       |\n| Directories | `_docs/`                            |\n| Variables   | `site.title`                        |\n| Links       | `[text](url)`                       |\n| Emphasis    | **bold** for UI, _italic_ for terms |\n| Code blocks | Use language syntax highlighting    |\n| Lists       | Parallel structure                  |\n| Headings    | Title case                          |\n\n## Common Mistakes\n\n### Inconsistent Terminology\n\n```markdown\n<!-- Pick one and stick with it -->\n\nmodpack / mod pack\nsetup / set up (noun vs verb)\nGitHub / Github\n```\n\n### Overcomplicating\n\n```markdown\n<!-- Good -->\n\nClick the theme toggle to switch between light and dark mode.\n\n<!-- Too complex -->\n\nIn order to facilitate the modification of the visual appearance schema, one must engage with the theme selection mechanism located in the navigation component.\n```\n\n### Missing Context\n\n````markdown\n<!-- Bad: No context -->\n\nRun this command:\n\n```bash\nnpm install\n```\n````\n\n<!-- Good: With context -->\n\nInstall Node dependencies:\n\n```bash\nnpm install\n```\n\n```\n\n## Next Steps\n\n- [Adding Modpacks](add-modpack.html) - Content creation\n- [Contributing Guide](contributing.html) - Submission process\n- [SEO Guide](seo-guide.html) - Optimize content\n```\n","## How to Contribute\n\nWe welcome contributions from the community! Whether it's bug reports, feature suggestions, or code improvements, your help is valuable.\n\n## Reporting Issues\n\nFound a bug or have a suggestion? Open an issue on [GitHub]({{ site.social.github }}/issues):\n\n1. **Check existing issues** to avoid duplicates\n2. **Be clear and descriptive** - include steps to reproduce for bugs\n3. **Include screenshots** if relevant\n4. **Mention your environment** - browser, OS, etc.\n\n## Suggesting Features\n\nHave an idea to improve the showcase?\n\n1. **Open a GitHub discussion** or issue with the `enhancement` label\n2. **Explain the use case** - why would this be useful?\n3. **Show examples** - mockups or references are helpful\n4. **Get feedback** - discuss with maintainers before starting work\n\n## Contributing Code\n\n### Setup\n\n```bash\ngit clone {{ site.social.github }}.git\ncd abc-site\nbundle install\nnpm install\nbundle exec jekyll serve --livereload\n```\n\n### Making Changes\n\n1. **Create a branch** - `git checkout -b feature/your-feature-name`\n2. **Make your changes** - keep commits focused and descriptive\n3. **Test locally** - verify the site builds and works correctly\n4. **Follow conventions** - match existing code style and patterns\n5. **Push and create a PR** - describe what you changed and why\n\n### Code Style\n\n- **CSS**: Use existing variables and patterns; keep it minimal\n- **JavaScript**: Vanilla JS, no frameworks; add comments for complex logic\n- **Markdown**: Use consistent formatting; check Jekyll renders correctly\n- **Naming**: Use kebab-case for files, camelCase for variables\n\n### PR Guidelines\n\n- Link related issues in the PR description\n- Provide before/after screenshots for UI changes\n- Ensure all checks pass (if applicable)\n- Be open to feedback and revisions\n\n## Documentation\n\nHelp improve the docs:\n\n1. **Fix typos** - spot a mistake? Let us know\n2. **Clarify sections** - is something unclear?\n3. **Add examples** - show how to use features\n4. **Translate** - help reach more developers\n\n## Community\n\n- **GitHub Discussions** - Ask questions, share ideas\n- **Discord** - Join our community server (if available)\n- **Twitter** - Follow for updates and announcements\n\n## Code of Conduct\n\nPlease be respectful and constructive. We're all here to learn and build together.\n\n---\n\nThank you for contributing! 🎉\n","# CSS Variables Reference\n\nComplete reference for all CSS custom properties used in the ABC showcase.\n\n## Color Variables\n\n### Background Colors\n\n```css\n:root {\n  --bg-primary: #1a1a1a; /* Main background */\n  --bg-secondary: #222222; /* Cards, secondary surfaces */\n  --bg-tertiary: #2a2a2a; /* Hover states, elevated surfaces */\n  --bg-overlay: rgba(31, 31, 31, 0.9); /* Modal/navbar overlays */\n}\n\n[data-theme=\"light\"] {\n  --bg-primary: #ffffff;\n  --bg-secondary: #f5f5f5;\n  --bg-tertiary: #e0e0e0;\n  --bg-overlay: rgba(255, 255, 255, 0.9);\n}\n```\n\n### Text Colors\n\n```css\n:root {\n  --text: #e0e0e0; /* Primary text */\n  --text-secondary: #b0b0b0; /* Secondary text */\n  --text-muted: #999999; /* Muted/disabled text */\n  --text-inverse: #1a1a1a; /* Text on accent backgrounds */\n}\n\n[data-theme=\"light\"] {\n  --text: #212121;\n  --text-secondary: #424242;\n  --text-muted: #666666;\n  --text-inverse: #ffffff;\n}\n```\n\n### Accent Colors\n\n```css\n:root {\n  --accent-primary: #4caf50; /* Primary actions, links */\n  --accent-secondary: #2196f3; /* Secondary actions */\n  --accent-tertiary: #9c27b0; /* Tertiary highlights */\n  --accent-success: #4caf50; /* Success states */\n  --accent-warning: #ff9800; /* Warning states */\n  --accent-error: #f44336; /* Error states */\n  --accent-info: #2196f3; /* Info messages */\n}\n```\n\n### Border Colors\n\n```css\n:root {\n  --border: #333333; /* Default borders */\n  --border-light: #404040; /* Light borders */\n  --border-dark: #2a2a2a; /* Dark borders */\n  --border-focus: var(--accent-primary); /* Focus states */\n}\n\n[data-theme=\"light\"] {\n  --border: #e0e0e0;\n  --border-light: #f0f0f0;\n  --border-dark: #d0d0d0;\n}\n```\n\n## Spacing Variables\n\n### Base Spacing\n\n```css\n:root {\n  --spacing-xs: 4px;\n  --spacing-sm: 8px;\n  --spacing-md: 16px;\n  --spacing-lg: 24px;\n  --spacing-xl: 32px;\n  --spacing-2xl: 48px;\n  --spacing-3xl: 64px;\n}\n```\n\n### Container Spacing\n\n```css\n:root {\n  --container-padding: 20px; /* Mobile padding */\n  --container-max-width: 1200px;\n  --section-spacing: 80px; /* Between sections */\n  --card-gap: 16px; /* Grid gap for cards */\n}\n\n@media (min-width: 768px) {\n  :root {\n    --container-padding: 40px;\n  }\n}\n```\n\n## Typography Variables\n\n### Font Families\n\n```css\n:root {\n  --font-body: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen,\n    Ubuntu, Cantarell, sans-serif;\n  --font-heading: var(--font-body);\n  --font-mono: \"Monaco\", \"Courier New\", \"Courier\", monospace;\n}\n```\n\n### Font Sizes\n\n```css\n:root {\n  --font-xs: 12px;\n  --font-sm: 14px;\n  --font-md: 16px;\n  --font-lg: 18px;\n  --font-xl: 24px;\n  --font-2xl: 32px;\n  --font-3xl: 48px;\n  --font-4xl: 64px;\n}\n```\n\n### Font Weights\n\n```css\n:root {\n  --font-light: 300;\n  --font-normal: 400;\n  --font-medium: 500;\n  --font-semibold: 600;\n  --font-bold: 700;\n}\n```\n\n### Line Heights\n\n```css\n:root {\n  --line-height-tight: 1.2;\n  --line-height-normal: 1.5;\n  --line-height-relaxed: 1.75;\n  --line-height-loose: 2;\n}\n```\n\n## Layout Variables\n\n### Border Radius\n\n```css\n:root {\n  --radius-sm: 4px;\n  --radius-md: 8px;\n  --radius-lg: 12px;\n  --radius-xl: 16px;\n  --radius-full: 999px; /* Pills/circular */\n}\n```\n\n### Shadows\n\n```css\n:root {\n  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.1);\n  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);\n  --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.2);\n  --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.3);\n}\n\n[data-theme=\"light\"] {\n  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);\n  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);\n  --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);\n  --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.15);\n}\n```\n\n### Z-Index Layers\n\n```css\n:root {\n  --z-base: 1;\n  --z-dropdown: 100;\n  --z-sticky: 200;\n  --z-fixed: 300;\n  --z-modal-backdrop: 400;\n  --z-modal: 500;\n  --z-popover: 600;\n  --z-tooltip: 700;\n}\n```\n\n## Effects Variables\n\n### Transitions\n\n```css\n:root {\n  --transition-fast: 0.1s ease;\n  --transition-normal: 0.2s ease;\n  --transition-slow: 0.3s ease;\n  --transition-all: all 0.2s ease;\n}\n```\n\n### Backdrop Blur\n\n```css\n:root {\n  --blur-sm: 5px;\n  --blur-md: 10px;\n  --blur-lg: 20px;\n  --blur-xl: 40px;\n}\n```\n\n### Opacity\n\n```css\n:root {\n  --opacity-disabled: 0.5;\n  --opacity-hover: 0.8;\n  --opacity-overlay: 0.9;\n}\n```\n\n## Component-Specific Variables\n\n### Navbar\n\n```css\n:root {\n  --navbar-height: 64px;\n  --navbar-bg: var(--bg-overlay);\n  --navbar-blur: var(--blur-md);\n  --navbar-padding: var(--spacing-md);\n}\n```\n\n### Cards\n\n```css\n:root {\n  --card-bg: var(--bg-secondary);\n  --card-border: var(--border);\n  --card-radius: var(--radius-md);\n  --card-padding: var(--spacing-lg);\n  --card-shadow: var(--shadow-md);\n  --card-hover-shadow: var(--shadow-lg);\n}\n```\n\n### Buttons\n\n```css\n:root {\n  --button-bg: var(--accent-primary);\n  --button-text: var(--text-inverse);\n  --button-radius: var(--radius-md);\n  --button-padding: var(--spacing-sm) var(--spacing-md);\n  --button-hover-opacity: var(--opacity-hover);\n}\n```\n\n### Pills/Tags\n\n```css\n:root {\n  --pill-bg: rgba(76, 175, 80, 0.15);\n  --pill-text: var(--accent-primary);\n  --pill-border: var(--accent-primary);\n  --pill-radius: var(--radius-full);\n  --pill-padding: 4px 12px;\n}\n```\n\n### Forms\n\n```css\n:root {\n  --input-bg: var(--bg-secondary);\n  --input-border: var(--border);\n  --input-text: var(--text);\n  --input-placeholder: var(--text-muted);\n  --input-focus-border: var(--accent-primary);\n  --input-radius: var(--radius-md);\n  --input-padding: var(--spacing-sm) var(--spacing-md);\n}\n```\n\n## Usage Examples\n\n### Basic Usage\n\n```css\n.my-element {\n  background: var(--bg-secondary);\n  color: var(--text);\n  padding: var(--spacing-md);\n  border-radius: var(--radius-md);\n  transition: var(--transition-normal);\n}\n```\n\n### With Fallbacks\n\n```css\n.my-element {\n  color: var(--text, #e0e0e0);\n  font-size: var(--font-md, 16px);\n}\n```\n\n### Computed Values\n\n```css\n.my-element {\n  /* Calculate based on variables */\n  padding: calc(var(--spacing-md) * 2);\n  margin: calc(var(--spacing-lg) + 8px);\n\n  /* Combine variables */\n  border: 1px solid var(--border);\n  box-shadow: var(--shadow-md);\n}\n```\n\n### Dynamic Theme Colors\n\n```css\n.custom-accent {\n  --my-accent: #ff5722;\n  background: var(--my-accent);\n  border-color: var(--my-accent);\n}\n\n.custom-accent:hover {\n  background: color-mix(in srgb, var(--my-accent) 80%, white);\n}\n```\n\n## Responsive Variables\n\n### Breakpoints\n\nDefine custom breakpoints:\n\n```css\n:root {\n  --breakpoint-sm: 640px;\n  --breakpoint-md: 768px;\n  --breakpoint-lg: 1024px;\n  --breakpoint-xl: 1280px;\n}\n```\n\n### Responsive Spacing\n\n```css\n:root {\n  --section-spacing: 40px;\n}\n\n@media (min-width: 768px) {\n  :root {\n    --section-spacing: 80px;\n  }\n}\n\n@media (min-width: 1024px) {\n  :root {\n    --section-spacing: 120px;\n  }\n}\n```\n\n## Advanced Techniques\n\n### Scoped Variables\n\n```css\n.dark-section {\n  --bg-primary: #000000;\n  --text: #ffffff;\n\n  background: var(--bg-primary);\n  color: var(--text);\n}\n```\n\n### Color Manipulation\n\n```css\n:root {\n  --accent-rgb: 76, 175, 80;\n}\n\n.element {\n  background: rgb(var(--accent-rgb));\n  border: 1px solid rgba(var(--accent-rgb), 0.3);\n  box-shadow: 0 4px 12px rgba(var(--accent-rgb), 0.2);\n}\n```\n\n### Variable Inheritance\n\n```css\n:root {\n  --base-size: 16px;\n  --heading-multiplier: 2;\n  --heading-size: calc(var(--base-size) * var(--heading-multiplier));\n}\n\nh1 {\n  font-size: var(--heading-size);\n}\n```\n\n## Best Practices\n\n1. **Use semantic names:**\n\n   ```css\n   /* Good */\n   --text-primary: #e0e0e0;\n\n   /* Avoid */\n   --gray-light: #e0e0e0;\n   ```\n\n2. **Group related variables:**\n\n   ```css\n   :root {\n     /* Colors */\n     --bg-primary: #1a1a1a;\n     --bg-secondary: #222222;\n\n     /* Spacing */\n     --spacing-sm: 8px;\n     --spacing-md: 16px;\n   }\n   ```\n\n3. **Provide fallbacks:**\n\n   ```css\n   color: var(--text, #e0e0e0);\n   ```\n\n4. **Document complex variables:**\n   ```css\n   :root {\n     /* Used for navbar and modal backdrops */\n     --bg-overlay: rgba(31, 31, 31, 0.9);\n   }\n   ```\n\n## Debugging\n\n### Inspect Variables\n\nUse browser DevTools:\n\n```javascript\n// Get computed value\ngetComputedStyle(document.documentElement).getPropertyValue(\"--accent-primary\");\n\n// Set variable dynamically\ndocument.documentElement.style.setProperty(\"--accent-primary\", \"#FF5722\");\n```\n\n### List All Variables\n\n```javascript\n// Get all custom properties\nconst allVars = Array.from(document.styleSheets)\n  .flatMap((sheet) => Array.from(sheet.cssRules))\n  .filter((rule) => rule.selectorText === \":root\")\n  .flatMap((rule) => Array.from(rule.style))\n  .filter((prop) => prop.startsWith(\"--\"));\n\nconsole.log(allVars);\n```\n\n## Next Steps\n\n- [Customization Guide](customization.html) - Apply these variables\n- [Liquid Templates](liquid-templates.html) - Dynamic styling\n- [Performance Guide](performance.html) - Optimize CSS delivery\n","## Theme Colors\n\nEdit `src/styles/root.css` to customize the color scheme:\n\n```css\n:root {\n  --bg: #0d0d0d; /* Page background */\n  --bg-secondary: #1a1a1a; /* Secondary background */\n  --card: #1f1f1f; /* Card background */\n  --border: #2a2a2a; /* Border color */\n  --text: #ffffff; /* Primary text */\n  --text-secondary: #b0b0b0; /* Secondary text */\n  --muted: #808080; /* Muted text */\n  --accent-primary: #1bd96f; /* Primary accent (green) */\n  --gradient-primary: linear-gradient(135deg, #1bd96f 0%, #15a853 100%);\n}\n```\n\nChanges apply instantly with `jekyll serve --livereload`.\n\n## Layout & Spacing\n\nCustomize responsive sizing in `src/styles/root.css`:\n\n```css\n:root {\n  --radius: 6px; /* Border radius */\n  --content-max: 1200px; /* Max content width */\n  --container-inline: clamp(16px, 5vw, 32px); /* Side padding */\n  --nav-height: 76px; /* Navbar height */\n}\n```\n\n### Responsive Breakpoints\n\nModify media queries in CSS files (e.g., `src/styles/layout.css`):\n\n```css\n@media (max-width: 960px) {\n  /* Tablet styles */\n}\n\n@media (max-width: 640px) {\n  /* Mobile styles */\n}\n```\n\n## Typography\n\nGoogle Fonts is configured to M PLUS Rounded 1c. To change:\n\nIn `_layouts/default.html`:\n\n```html\n<link\n  href=\"https://fonts.googleapis.com/css2?family=Your+Font&display=swap\"\n  rel=\"stylesheet\"\n/>\n```\n\nIn `src/styles/root.css`:\n\n```css\nbody {\n  font-family: \"Your Font\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto,\n    sans-serif;\n}\n```\n\n## Component Styling\n\n### Cards\n\nEdit `.card` in `src/styles/components.css`:\n\n```css\n.card {\n  padding: 24px;\n  border-radius: var(--radius);\n  background: var(--card);\n  border: 1px solid var(--border);\n  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n}\n```\n\n### Buttons\n\nCustomize `.btn` variants:\n\n```css\n.btn.primary {\n  background: var(--gradient-primary);\n  color: #000000;\n}\n\n.btn.ghost {\n  background: transparent;\n  border: 1px solid var(--border);\n}\n```\n\n## Navigation Bar\n\nThe pill-style navbar is in `src/styles/layout.css`:\n\n```css\n.nav-inner {\n  background: rgba(31, 31, 31, 0.9);\n  border-radius: 999px;\n  padding: 10px clamp(16px, 4vw, 28px);\n  backdrop-filter: blur(10px);\n}\n```\n\nAdjust `border-radius`, `padding`, and `backdrop-filter` to change appearance.\n\n## Hero Banner\n\nThe hero section background image and overlay in `src/styles/layout.css`:\n\n```css\n.hero {\n  background-image: url(\"/abc-site/assets/images/blocks.svg\");\n  background-size: auto 100%;\n  background-position: left center;\n}\n\n.hero::before {\n  background: linear-gradient(\n    135deg,\n    rgba(13, 13, 13, 0.85) 0%,\n    rgba(13, 13, 13, 0.7) 100%\n  );\n}\n```\n\nReplace the SVG path to use a different banner image.\n\n## Project Card Layout\n\nProject cards are defined in `src/styles/modpacks.css`:\n\n```css\n.modpack {\n  display: grid;\n  grid-template-columns: auto 1fr;\n  grid-template-rows: auto auto auto;\n  /* ... */\n}\n```\n\nModify grid structure to change the layout of thumbnail, title, pills, and buttons.\n\n## Building & Testing\n\nAfter making changes:\n\n```bash\nbundle exec jekyll build\n```\n\nCheck `_site/` to see compiled output. Rerun `jekyll serve` to test live changes.\n\n---\n\n**Tips:** Use CSS variables for consistent theming. Test on mobile to ensure responsive design works.\n","# Deployment Guide\n\nLearn how to deploy your ABC showcase to popular hosting platforms.\n\n## GitHub Pages\n\n### Automatic Deployment\n\n1. **Enable GitHub Pages** in repository settings\n2. **Set source** to GitHub Actions\n3. **Create workflow** file `.github/workflows/jekyll.yml`:\n\n```yaml\nname: Deploy Jekyll site to Pages\n\non:\n  push:\n    branches: [\"main\"]\n  workflow_dispatch:\n\npermissions:\n  contents: read\n  pages: write\n  id-token: write\n\nconcurrency:\n  group: \"pages\"\n  cancel-in-progress: false\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: \"3.1\"\n          bundler-cache: true\n      - name: Setup Pages\n        uses: actions/configure-pages@v4\n      - name: Build with Jekyll\n        run: bundle exec jekyll build --baseurl \"${{ steps.pages.outputs.base_path }}\"\n        env:\n          JEKYLL_ENV: production\n      - name: Upload artifact\n        uses: actions/upload-pages-artifact@v3\n\n  deploy:\n    environment:\n      name: github-pages\n      url: ${{ steps.deployment.outputs.page_url }}\n    runs-on: ubuntu-latest\n    needs: build\n    steps:\n      - name: Deploy to GitHub Pages\n        id: deployment\n        uses: actions/deploy-pages@v4\n```\n\n### Configuration\n\nUpdate `_config.yml` with your repository name:\n\n```yaml\nbaseurl: \"/your-repo-name\"\nurl: \"https://username.github.io\"\n```\n\n## Netlify\n\n### One-Click Deploy\n\n1. **Connect repository** to Netlify\n2. **Configure build settings**:\n   - Build command: `bundle exec jekyll build`\n   - Publish directory: `_site`\n3. **Set environment variables**:\n   - `JEKYLL_ENV`: `production`\n\n### netlify.toml\n\nCreate `netlify.toml` in root:\n\n```toml\n[build]\n  command = \"bundle exec jekyll build\"\n  publish = \"_site\"\n\n[build.environment]\n  JEKYLL_ENV = \"production\"\n  RUBY_VERSION = \"3.1\"\n\n[[headers]]\n  for = \"/*\"\n  [headers.values]\n    X-Frame-Options = \"DENY\"\n    X-XSS-Protection = \"1; mode=block\"\n    X-Content-Type-Options = \"nosniff\"\n\n[[redirects]]\n  from = \"/*\"\n  to = \"/404.html\"\n  status = 404\n```\n\n## Vercel\n\n### Deploy with Vercel CLI\n\n1. **Install Vercel CLI**: `npm i -g vercel`\n2. **Run**: `vercel`\n3. **Follow prompts** to link repository\n\n### vercel.json\n\nCreate `vercel.json`:\n\n```json\n{\n  \"buildCommand\": \"bundle exec jekyll build\",\n  \"outputDirectory\": \"_site\",\n  \"framework\": \"jekyll\",\n  \"installCommand\": \"bundle install\"\n}\n```\n\n## Environment Variables\n\n### Production Settings\n\nSet these for optimal production builds:\n\n- `JEKYLL_ENV=production` - Enables production mode\n- `BUNDLE_WITHOUT=development` - Skip dev dependencies\n\n### Custom Variables\n\nAdd to `_config.yml`:\n\n```yaml\n# Development\ndevelopment:\n  api_url: \"http://localhost:4000\"\n\n# Production\nproduction:\n  api_url: \"https://api.yoursite.com\"\n```\n\nAccess in templates:\n\n```liquid\n{% if jekyll.environment == \"production\" %}\n  {{ site.production.api_url }}\n{% else %}\n  {{ site.development.api_url }}\n{% endif %}\n```\n\n## Performance Optimization\n\n### Build Optimization\n\n1. **Exclude unnecessary files** in `_config.yml`\n2. **Enable incremental builds**: `jekyll build --incremental`\n3. **Use caching** in CI/CD pipelines\n\n### Asset Optimization\n\n```yaml\n# _config.yml\nsass:\n  style: compressed\n\nexclude:\n  - node_modules/\n  - src/\n  - Gemfile\n  - Gemfile.lock\n  - README.md\n```\n\n## Troubleshooting\n\n### Build Failures\n\n**Missing dependencies:**\n\n```bash\nbundle install\nbundle update\n```\n\n**Path issues:**\n\n- Check `baseurl` in `_config.yml`\n- Use `{{ '/path' | relative_url }}` in templates\n\n**Version conflicts:**\n\n```bash\nbundle exec jekyll build --verbose\n```\n\n### Cache Issues\n\nClear build cache:\n\n```bash\n# Local\nrm -rf _site .jekyll-cache\n\n# Netlify: Clear cache in Deploy settings\n# Vercel: Redeploy without cache\n# GitHub Pages: Re-run workflow\n```\n\n## Next Steps\n\n- [GitHub Actions Guide](github-actions.html) - Automate workflows\n- [Performance Optimization](performance.html) - Speed up your site\n- [SEO Guide](seo-guide.html) - Improve search rankings\n","## General\n\n**Q: What is ABC?**\nA: ABC is a static site showcase for curated Minecraft projects (mods, resource packs, datapacks, modpacks, plugins) from a Modrinth organization.\n\n**Q: Can I fork and customize it?**\nA: Yes! The site is open-source. Fork the [GitHub repo]({{ site.social.github }}), configure it for your organization, and deploy.\n\n**Q: Do I need technical knowledge to use it?**\nA: Basic familiarity with Git and command line helps, but the setup is straightforward. Check our [Getting Started](getting-started) guide.\n\n## Setup & Configuration\n\n**Q: How do I connect my Modrinth organization?**\nA: Set `modrinth.org_slug` in `_config.yml` to your organization slug, then run `npm run fetch` to sync projects.\n\n**Q: Can I customize colors?**\nA: Yes! Edit `src/styles/root.css` to change the theme colors, fonts, and spacing.\n\n**Q: How do I add a logo?**\nA: Replace `assets/images/logo.svg` with your logo, then update the path in `_config.yml` if needed.\n\n**Q: Where do social links appear?**\nA: In the navbar (top right) and footer. Configure them in `_config.yml` under `social`.\n\n## Projects & Data\n\n**Q: How often does the project list update?**\nA: Run `npm run fetch` manually, or set up a scheduled GitHub Action to auto-sync daily.\n\n**Q: Can I filter projects by type or version?**\nA: Yes! The projects page has built-in filters for type, loader, and Minecraft version.\n\n**Q: What data comes from Modrinth?**\nA: Title, description, icon, downloads, versions, loaders, categories, and links. All pulled from the Modrinth API.\n\n**Q: Can I add projects manually?**\nA: You can edit `data/mods.json` directly, but it's better to add them to Modrinth and sync via `npm run fetch`.\n\n## Deployment\n\n**Q: How do I deploy to GitHub Pages?**\nA: Configure `baseurl` in `_config.yml` to your repo name, then GitHub Actions auto-deploys on push (if enabled).\n\n**Q: Can I host it elsewhere?**\nA: Yes! Run `bundle exec jekyll build` and upload the `_site/` folder to any static hosting (Netlify, Vercel, etc.).\n\n**Q: What's the baseurl?**\nA: It's the URL path where your site lives. For `github.io/abc-site`, set `baseurl: /abc-site`.\n\n## Performance\n\n**Q: Why is the build slow?**\nA: Large `node_modules/` and `src/` folders are excluded by default. Check `_config.yml` to ensure unnecessary folders aren't processed.\n\n**Q: How do I optimize for mobile?**\nA: The site is responsive by default using CSS `clamp()`. Test on phone to verify layouts work.\n\n## Troubleshooting\n\n**Q: Site won't build**\nA: Check Ruby version (`ruby -v`). We use 2.6+. Run `bundle install` to install dependencies.\n\n**Q: Projects don't show**\nA: Verify `data/mods.json` exists and is valid JSON. Run `npm run fetch` to regenerate it.\n\n**Q: Navbar looks broken**\nA: Hard refresh (Cmd+Shift+R). Clear browser cache if using `jekyll serve`.\n\n**Q: Styles not updating**\nA: Changes to source files (`src/styles/`) need to be compiled. Either build with `bundle exec jekyll build` or ensure `jekyll serve` is watching the files.\n\n## Contributing\n\n**Q: How do I contribute code?**\nA: Fork the repo, make changes on a branch, and open a PR. See [Contributing](contributing) for details.\n\n**Q: Can I suggest features?**\nA: Yes! Open a GitHub issue or discussion. We'd love to hear your ideas.\n\n---\n\n**Still have questions?** Open an [issue]({{ site.social.github }}/issues) or [reach out on Discord]({{ site.social.discord }}).\n","## Rebrand\n\n- Edit `_config.yml` (`site` block) for name, title, description, logo.\n- Swap icons: update `meta.favicon`, `meta.apple_touch_icon`, `meta.og_image` and replace files in `assets/images/`.\n\n## Configure Modrinth\n\n- Set `modrinth.org_slug` (and `MODRINTH_API_TOKEN` if you want private projects).\n- Run `npm run fetch` to refresh `data/mods.json`.\n\n## Run locally\n\n```bash\nbundle exec jekyll serve --livereload\n# visit http://localhost:4000/abc-site/\n```\n","# GitHub Actions Guide\n\nAutomate your ABC showcase with GitHub Actions workflows.\n\n## Basic Build Workflow\n\n### Jekyll Build & Deploy\n\nCreate `.github/workflows/build.yml`:\n\n```yaml\nname: Build and Deploy\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: \"3.1\"\n          bundler-cache: true\n\n      - name: Build site\n        run: bundle exec jekyll build\n        env:\n          JEKYLL_ENV: production\n\n      - name: Test HTML\n        run: |\n          bundle exec htmlproofer ./_site \\\n            --disable-external \\\n            --allow-hash-href\n```\n\n## Advanced Workflows\n\n### Link Checker\n\nCheck for broken links:\n\n```yaml\nname: Link Check\n\non:\n  schedule:\n    - cron: \"0 0 * * 0\" # Weekly\n  workflow_dispatch:\n\njobs:\n  link-check:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: \"3.1\"\n          bundler-cache: true\n\n      - name: Build site\n        run: bundle exec jekyll build\n\n      - name: Check links\n        uses: lycheeverse/lychee-action@v1\n        with:\n          args: --verbose --no-progress './_site/**/*.html'\n```\n\n### Auto-Update Dependencies\n\nKeep gems updated:\n\n```yaml\nname: Update Dependencies\n\non:\n  schedule:\n    - cron: \"0 0 * * 1\" # Weekly on Monday\n  workflow_dispatch:\n\njobs:\n  update:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: \"3.1\"\n\n      - name: Update gems\n        run: bundle update\n\n      - name: Create Pull Request\n        uses: peter-evans/create-pull-request@v5\n        with:\n          commit-message: \"chore: update dependencies\"\n          title: \"Update Ruby dependencies\"\n          body: \"Automated dependency updates\"\n          branch: update-dependencies\n```\n\n### Lighthouse CI\n\nPerformance testing:\n\n```yaml\nname: Lighthouse CI\n\non:\n  pull_request:\n    branches: [main]\n\njobs:\n  lighthouse:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: \"3.1\"\n          bundler-cache: true\n\n      - name: Build site\n        run: bundle exec jekyll build\n\n      - name: Run Lighthouse CI\n        uses: treosh/lighthouse-ci-action@v10\n        with:\n          urls: |\n            http://localhost:4000\n            http://localhost:4000/projects/\n            http://localhost:4000/docs/\n          uploadArtifacts: true\n```\n\n## Modrinth Data Sync\n\n### Auto-Fetch Latest Mods\n\nKeep mod data fresh:\n\n```yaml\nname: Sync Modrinth Data\n\non:\n  schedule:\n    - cron: \"0 */6 * * *\" # Every 6 hours\n  workflow_dispatch:\n\njobs:\n  sync:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Setup Node\n        uses: actions/setup-node@v4\n        with:\n          node-version: \"18\"\n\n      - name: Fetch Modrinth data\n        run: |\n          # Your script to fetch from Modrinth API\n          node scripts/fetch-modrinth.js\n\n      - name: Commit changes\n        uses: stefanzweifel/git-auto-commit-action@v5\n        with:\n          commit_message: \"chore: update Modrinth data\"\n          file_pattern: \"_data/mods.json\"\n```\n\n## Caching Strategies\n\n### Bundle Cache\n\nSpeed up builds with caching:\n\n{% raw %}\n\n```yaml\n- name: Setup Ruby\n  uses: ruby/setup-ruby@v1\n  with:\n    ruby-version: \"3.1\"\n    bundler-cache: true # Automatic bundler caching\n\n- name: Cache Jekyll build\n  uses: actions/cache@v3\n  with:\n    path: |\n      .jekyll-cache\n      _site\n    key: ${{ runner.os }}-jekyll-${{ hashFiles('**/*.md', '**/*.html') }}\n    restore-keys: |\n      ${{ runner.os }}-jekyll-\n```\n\n{% endraw %}\n\n## Notifications\n\n### Slack Integration\n\nGet notified on deployment:\n\n```yaml\n- name: Slack Notification\n  uses: 8398a7/action-slack@v3\n  with:\n    status: ${{ job.status }}\n    text: \"Deployment completed!\"\n    webhook_url: ${{ secrets.SLACK_WEBHOOK }}\n  if: always()\n```\n\n### Discord Webhook\n\n```yaml\n- name: Discord notification\n  uses: Ilshidur/action-discord@master\n  env:\n    DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}\n  with:\n    args: \"Site deployed successfully! 🚀\"\n```\n\n## Security Scanning\n\n### Dependency Scanning\n\n```yaml\nname: Security Scan\n\non:\n  push:\n    branches: [main]\n  schedule:\n    - cron: \"0 0 * * 0\"\n\njobs:\n  security:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Run bundle audit\n        run: |\n          gem install bundler-audit\n          bundle audit --update\n```\n\n## Secrets Management\n\n### Required Secrets\n\nAdd in Settings > Secrets and variables > Actions:\n\n- `GITHUB_TOKEN` - Automatically provided\n- `SLACK_WEBHOOK` - For Slack notifications\n- `DISCORD_WEBHOOK` - For Discord notifications\n- Custom API keys for integrations\n\n### Using Secrets\n\n```yaml\n- name: Deploy to custom server\n  env:\n    API_KEY: ${{ secrets.API_KEY }}\n    SERVER_URL: ${{ secrets.SERVER_URL }}\n  run: |\n    curl -X POST \"$SERVER_URL\" \\\n      -H \"Authorization: Bearer $API_KEY\"\n```\n\n## Workflow Triggers\n\n### Available Triggers\n\n```yaml\non:\n  push:\n    branches: [main]\n    paths:\n      - \"**.md\"\n      - \"**.html\"\n  pull_request:\n  schedule:\n    - cron: \"0 0 * * *\"\n  workflow_dispatch:\n  release:\n    types: [published]\n```\n\n## Best Practices\n\n1. **Use caching** to speed up builds\n2. **Run tests on PRs** before merging\n3. **Schedule maintenance tasks** (link checks, updates)\n4. **Secure secrets** properly\n5. **Monitor workflow costs** and runtime\n6. **Use matrix builds** for testing multiple versions\n\n## Troubleshooting\n\n### Failed Builds\n\nCheck logs:\n\n1. Click on failed workflow\n2. Expand failed step\n3. Review error messages\n\nCommon fixes:\n\n- Update action versions\n- Clear cache\n- Check secrets configuration\n\n### Timeout Issues\n\n```yaml\njobs:\n  build:\n    runs-on: ubuntu-latest\n    timeout-minutes: 30 # Increase if needed\n```\n\n## Next Steps\n\n- [Deployment Guide](deployment.html) - Deploy to hosting platforms\n- [Performance Guide](performance.html) - Optimize build times\n- [API Reference](api-reference.html) - Data structure documentation\n","## Step-by-Step Guide\n\n1. **Open the Project Page**  \n   Visit the Modrinth, CurseForge, GitHub, or project website for the content you want to download.\n\n2. **Find the Versions or Files Section**  \n   Look for a tab or section labelled **Versions**, **Files**, **Releases**, or **Downloads**.\n\n3. **Select Your Minecraft Version**\n\n   - Locate a list or dropdown called **Version**, **Game Version**, or **Supported Versions**.\n   - Pick the version that matches your Minecraft installation (e.g., _1.20.1_, _1.19.2_).\n\n4. **Choose the Correct File Type**  \n   The file type depends on the kind of content:\n\n   - **Mods:** `.jar`\n   - **Plugins:** `.jar`\n   - **Addons (Bedrock):** `.mcaddon` / `.mcpack`\n   - **Texture Packs:** `.zip`\n   - **Data Packs:** `.zip` or extracted folder\n   - **Capes / Skin Addons:** whichever format the creator provides\n\n5. **Download the File**  \n   Click the **Download**, **Get**, or **File** button next to the version you need.  \n   Save the file to your device.\n\n6. **Install According to Content Type**\n\n   - **Mods:** place the `.jar` inside `.minecraft/mods`.\n   - **Plugins:** move the `.jar` into your server's `plugins` folder.\n   - **Texture Packs:** place the `.zip` into `.minecraft/resourcepacks`.\n   - **Data Packs:** put inside `world/datapacks`.\n   - **Addons (Bedrock):** double-click `.mcaddon` or `.mcpack` to import automatically.\n\n7. **Restart Minecraft or Your Server**  \n   Reload or restart to apply the new content.\n","# Liquid Templates Guide\n\nMaster Jekyll's Liquid templating language for dynamic content generation.\n\n## Basics\n\n### Output Tags\n\nDisplay variables and expressions:\n\n```liquid\n{{ variable }}\n{{ site.title }}\n{{ page.description }}\n```\n\n### Logic Tags\n\nControl flow and iteration:\n\n```liquid\n{% if condition %}\n  ...\n{% elsif other_condition %}\n  ...\n{% else %}\n  ...\n{% endif %}\n\n{% for item in array %}\n  {{ item }}\n{% endfor %}\n```\n\n## Variables\n\n### Site Variables\n\n```liquid\n{{ site.title }}              # From _config.yml\n{{ site.description }}\n{{ site.baseurl }}\n{{ site.url }}\n{{ site.time }}               # Build timestamp\n{{ site.pages }}              # All pages\n{{ site.posts }}              # All posts\n{{ site.data }}               # Data files\n```\n\n### Page Variables\n\n{% raw %}\n\n```liquid\n{{ page.title }}              # Current page title\n{{ page.url }}                # Page URL\n{{ page.date }}               # Post date\n{{ page.content }}            # Page content\n{{ page.excerpt }}            # Auto excerpt\n{{ page.custom_field }}       # Custom frontmatter\n```\n\n{% endraw %}\n\n### Custom Data\n\nAccess `_data/` files:\n\n```liquid\n{% for modpack in site.data.mods.modpacks %}\n  {{ modpack.name }}\n  {{ modpack.description }}\n{% endfor %}\n```\n\n## Filters\n\n### String Filters\n\n```liquid\n{{ \"hello world\" | capitalize }}        # \"Hello world\"\n{{ \"hello world\" | upcase }}            # \"HELLO WORLD\"\n{{ \"HELLO WORLD\" | downcase }}          # \"hello world\"\n{{ \"hello world\" | truncate: 8 }}       # \"hello...\"\n{{ \"hello world\" | replace: \"world\", \"there\" }}  # \"hello there\"\n{{ \"a,b,c\" | split: \",\" }}              # [\"a\", \"b\", \"c\"]\n{{ \" hello \" | strip }}                 # \"hello\"\n{{ \"hello\" | append: \" world\" }}        # \"hello world\"\n{{ \"world\" | prepend: \"hello \" }}       # \"hello world\"\n{{ \"hello-world\" | slugify }}           # \"hello-world\"\n```\n\n### Number Filters\n\n```liquid\n{{ 4 | plus: 2 }}              # 6\n{{ 4 | minus: 2 }}             # 2\n{{ 4 | times: 2 }}             # 8\n{{ 4 | divided_by: 2 }}        # 2\n{{ 4.5 | round }}              # 5\n{{ 4.5 | ceil }}               # 5\n{{ 4.5 | floor }}              # 4\n{{ 1234 | divided_by: 100.0 }} # 12.34\n```\n\n### Array Filters\n\n{% raw %}\n\n```liquid\n{{ array | join: \", \" }}       # Join with separator\n{{ array | first }}            # First element\n{{ array | last }}             # Last element\n{{ array | size }}             # Array length\n{{ array | reverse }}          # Reverse order\n{{ array | sort }}             # Sort ascending\n{{ array | uniq }}             # Remove duplicates\n{{ array | where: \"key\", \"value\" }}  # Filter by property\n{{ array | map: \"name\" }}      # Extract property\n```\n\n{% endraw %}\n\n### Date Filters\n\n```liquid\n{{ page.date | date: \"%Y-%m-%d\" }}           # 2025-12-10\n{{ page.date | date: \"%B %d, %Y\" }}          # December 10, 2025\n{{ page.date | date_to_string }}             # 10 Dec 2025\n{{ page.date | date_to_long_string }}        # 10 December 2025\n{{ page.date | date_to_rfc822 }}             # RFC-822 format\n{{ \"2025-12-10\" | date: \"%Y\" }}              # 2025\n```\n\n### URL Filters\n\n```liquid\n{{ \"/assets/style.css\" | relative_url }}     # /abc-site/assets/style.css\n{{ \"/page\" | absolute_url }}                 # https://site.com/abc-site/page\n{{ \"path/to/file.md\" | replace: \".md\", \".html\" }}\n```\n\n### Jekyll-Specific Filters\n\n```liquid\n{{ content | markdownify }}             # Convert Markdown to HTML\n{{ content | strip_html }}              # Remove HTML tags\n{{ content | number_of_words }}         # Word count\n{{ content | jsonify }}                 # Convert to JSON\n{{ content | xml_escape }}              # Escape XML characters\n{{ content | cgi_escape }}              # URL encode\n{{ content | uri_escape }}              # URI encode\n```\n\n## Control Flow\n\n### If Statements\n\n```liquid\n{% if page.category == \"Developer\" %}\n  <span class=\"badge\">Developer</span>\n{% endif %}\n\n{% if page.tags contains \"featured\" %}\n  <span class=\"featured\">★</span>\n{% endif %}\n\n{% unless page.published == false %}\n  {{ page.content }}\n{% endunless %}\n```\n\n### Case Statements\n\n```liquid\n{% case page.category %}\n  {% when \"Setup\" %}\n    <i class=\"fa-gear\"></i>\n  {% when \"Styling\" %}\n    <i class=\"fa-palette\"></i>\n  {% else %}\n    <i class=\"fa-file\"></i>\n{% endcase %}\n```\n\n### Loops\n\n```liquid\n{% for doc in site.docs %}\n  <li>{{ doc.title }}</li>\n{% endfor %}\n\n{% for doc in site.docs limit:5 %}\n  <!-- First 5 only -->\n{% endfor %}\n\n{% for doc in site.docs offset:5 %}\n  <!-- Skip first 5 -->\n{% endfor %}\n\n{% for doc in site.docs reversed %}\n  <!-- Reverse order -->\n{% endfor %}\n```\n\n### Loop Variables\n\n```liquid\n{% for item in array %}\n  {{ forloop.index }}        # 1, 2, 3, ...\n  {{ forloop.index0 }}       # 0, 1, 2, ...\n  {{ forloop.first }}        # true on first iteration\n  {{ forloop.last }}         # true on last iteration\n  {{ forloop.length }}       # Total iterations\n  {{ forloop.rindex }}       # Reverse index (from end)\n{% endfor %}\n```\n\n### Break & Continue\n\n```liquid\n{% for item in array %}\n  {% if item.hide %}\n    {% continue %}\n  {% endif %}\n\n  {% if forloop.index > 10 %}\n    {% break %}\n  {% endif %}\n\n  {{ item.name }}\n{% endfor %}\n```\n\n## Advanced Techniques\n\n### Assign Variables\n\n```liquid\n{% assign my_var = \"value\" %}\n{% assign count = site.docs | size %}\n{% assign featured = site.docs | where: \"featured\", true %}\n```\n\n### Capture Blocks\n\n```liquid\n{% capture my_variable %}\n  Complex content with {{ page.title }}\n  and calculations: {{ 5 | times: 10 }}\n{% endcapture %}\n\n{{ my_variable }}\n```\n\n### Includes\n\nCreate reusable components in `_includes/`:\n\n{% raw %}\n\n```liquid\n{% include header.html %}\n{% include card.html title=\"Test\" description=\"Description\" %}\n```\n\n{% endraw %}\n\nWith parameters:\n\n{% raw %}\n\n```liquid\n<!-- _includes/card.html -->\n<div class=\"card\">\n  <h3>{{ include.title }}</h3>\n  <p>{{ include.description }}</p>\n</div>\n```\n\n{% endraw %}\n\n### Layouts\n\nInherit from layouts:\n\n```liquid\n<!-- _layouts/docs.html -->\n<!DOCTYPE html>\n<html>\n  <body>\n    {{ content }}\n  </body>\n</html>\n```\n\nIn page frontmatter:\n\n```yaml\n---\nlayout: docs\ntitle: My Page\n---\n```\n\n## Practical Examples\n\n### Navigation Menu\n\n```liquid\n<nav>\n  {% for item in site.data.navigation %}\n    <a href=\"{{ item.url | relative_url }}\"\n       {% if page.url == item.url %}class=\"active\"{% endif %}>\n      {{ item.title }}\n    </a>\n  {% endfor %}\n</nav>\n```\n\n### Breadcrumbs\n\n```liquid\n<nav class=\"breadcrumbs\">\n  <a href=\"{{ '/' | relative_url }}\">Home</a>\n  {% if page.category %}\n    <span>/</span>\n    <a href=\"{{ '/docs/category/' | append: page.category | slugify | append: '/' | relative_url }}\">\n      {{ page.category }}\n    </a>\n  {% endif %}\n  <span>/</span>\n  <span>{{ page.title }}</span>\n</nav>\n```\n\n### Pagination\n\n```liquid\n{% if paginator.total_pages > 1 %}\n  <div class=\"pagination\">\n    {% if paginator.previous_page %}\n      <a href=\"{{ paginator.previous_page_path | relative_url }}\">Previous</a>\n    {% endif %}\n\n    <span>Page {{ paginator.page }} of {{ paginator.total_pages }}</span>\n\n    {% if paginator.next_page %}\n      <a href=\"{{ paginator.next_page_path | relative_url }}\">Next</a>\n    {% endif %}\n  </div>\n{% endif %}\n```\n\n### Related Posts\n\n```liquid\n{% assign related = site.docs | where: \"category\", page.category |\n                    where_exp: \"doc\", \"doc.url != page.url\" |\n                    limit: 3 %}\n\n{% if related.size > 0 %}\n  <h3>Related Documentation</h3>\n  <ul>\n    {% for doc in related %}\n      <li><a href=\"{{ doc.url | relative_url }}\">{{ doc.title }}</a></li>\n    {% endfor %}\n  </ul>\n{% endif %}\n```\n\n### Conditional CSS Classes\n\n```liquid\n<article class=\"\n  {% if page.featured %}featured{% endif %}\n  {% if page.category %}category-{{ page.category | slugify }}{% endif %}\n  {% if page.tags contains 'important' %}important{% endif %}\n\">\n  {{ content }}\n</article>\n```\n\n## Performance Tips\n\n1. **Assign once, use many times:**\n\n   ```liquid\n   {% assign docs = site.docs | where: \"category\", \"Setup\" %}\n   ```\n\n2. **Avoid nested loops when possible:**\n\n   ```liquid\n   <!-- Slow -->\n   {% for doc in site.docs %}\n     {% for tag in doc.tags %}\n       ...\n     {% endfor %}\n   {% endfor %}\n\n   <!-- Faster -->\n   {% assign all_tags = site.docs | map: \"tags\" | join: \",\" | default: \"\" | split: \",\" | uniq %}\n   ```\n\n3. **Cache expensive operations:**\n   ```liquid\n   {% capture cached_content %}\n     <!-- Complex logic here -->\n   {% endcapture %}\n   ```\n\n## Debugging\n\n### Inspect Variables\n\n```liquid\n{{ variable | inspect }}\n{{ site.data | jsonify }}\n```\n\n### Check Types\n\n```liquid\n{% if variable %}\n  Variable exists and is truthy\n{% endif %}\n\n{% if variable == nil %}\n  Variable is nil\n{% endif %}\n\n{% if variable == blank %}\n  Variable is nil, false, or empty\n{% endif %}\n```\n\n## Next Steps\n\n- [API Reference](api-reference.html) - Data structure documentation\n- [CSS Variables](css-variables.html) - Theme customization\n- [Customization Guide](customization.html) - Practical examples\n","# Performance Optimization\n\nOptimize your ABC showcase for blazing-fast load times and smooth interactions.\n\n## Build Performance\n\n### Jekyll Build Optimization\n\n**Exclude unnecessary files:**\n\n```yaml\n# _config.yml\nexclude:\n  - node_modules/\n  - src/\n  - vendor/\n  - .git/\n  - .github/\n  - README.md\n  - Gemfile\n  - Gemfile.lock\n  - package.json\n  - package-lock.json\n```\n\n**Use incremental builds:**\n\n```bash\nbundle exec jekyll build --incremental\n```\n\n**Profile build time:**\n\n```bash\nbundle exec jekyll build --profile\n```\n\n### Optimize Data Files\n\n**Reduce `_data/mods.json` size:**\n\n```json\n{\n  \"modpacks\": [\n    {\n      \"slug\": \"abc\",\n      \"name\": \"ABC Pack\",\n      \"desc\": \"Brief description\",\n      \"icon\": \"/path/to/icon.png\",\n      \"dl\": 50000,\n      \"cat\": [\"tech\"]\n    }\n  ]\n}\n```\n\nUse abbreviated keys and remove unnecessary fields.\n\n**Compress JSON:**\n\n```bash\n# Install jq\nbrew install jq\n\n# Minify JSON\njq -c . _data/mods.json > _data/mods.min.json\n```\n\n## Asset Optimization\n\n### Images\n\n**Use WebP format:**\n\n```html\n<picture>\n  <source srcset=\"image.webp\" type=\"image/webp\" />\n  <img src=\"image.png\" alt=\"Description\" />\n</picture>\n```\n\n**Convert images:**\n\n```bash\n# Install ImageMagick\nbrew install imagemagick\n\n# Convert to WebP\nmagick convert input.png -quality 80 output.webp\n```\n\n**Optimize existing images:**\n\n```bash\n# PNG optimization\npngquant --quality 65-80 image.png\n\n# JPG optimization\njpegoptim --max=85 image.jpg\n```\n\n**Lazy loading:**\n\n```html\n<img src=\"image.jpg\" loading=\"lazy\" alt=\"Description\" />\n```\n\n### CSS Optimization\n\n**Minify CSS:**\n\n```yaml\n# _config.yml\nsass:\n  style: compressed\n```\n\n**Critical CSS:**\n\nExtract above-the-fold styles:\n\n```html\n<head>\n  <style>\n    /* Critical CSS inline */\n    body {\n      margin: 0;\n      font-family: sans-serif;\n    }\n    .hero {\n      min-height: 100vh;\n    }\n  </style>\n\n  <!-- Defer non-critical CSS -->\n  <link\n    rel=\"preload\"\n    href=\"/assets/css/main.css\"\n    as=\"style\"\n    onload=\"this.onload=null;this.rel='stylesheet'\"\n  />\n  <noscript><link rel=\"stylesheet\" href=\"/assets/css/main.css\" /></noscript>\n</head>\n```\n\n**Remove unused CSS:**\n\n```bash\nnpm install -g purgecss\n\npurgecss --css assets/css/*.css \\\n         --content _site/**/*.html \\\n         --output assets/css/\n```\n\n### JavaScript Optimization\n\n**Defer non-critical scripts:**\n\n```html\n<script src=\"/assets/js/main.js\" defer></script>\n```\n\n**Async for independent scripts:**\n\n```html\n<script src=\"/assets/js/analytics.js\" async></script>\n```\n\n**Minify JavaScript:**\n\n```bash\nnpm install -g terser\n\nterser input.js -o output.min.js -c -m\n```\n\n**Code splitting:**\n\n```html\n<!-- Load only what's needed -->\n{% if page.layout == 'docs' %}\n<script src=\"/assets/js/docs.js\" defer></script>\n{% endif %}\n```\n\n## Caching Strategies\n\n### HTTP Caching\n\n**Add cache headers:**\n\n```html\n<!-- Netlify: _headers file -->\n/assets/* Cache-Control: public, max-age=31536000, immutable /css/*\nCache-Control: public, max-age=31536000, immutable /js/* Cache-Control: public,\nmax-age=31536000, immutable /*.html Cache-Control: public, max-age=0,\nmust-revalidate\n```\n\n**Versioning assets:**\n\n```liquid\n<link rel=\"stylesheet\" href=\"{{ '/assets/css/main.css' | relative_url }}?v={{ site.time | date: '%s' }}\">\n```\n\n### Service Worker\n\n**Basic service worker:**\n\n```javascript\n// sw.js\nconst CACHE_NAME = \"abc-site-v1\";\nconst urlsToCache = [\n  \"/\",\n  \"/assets/css/main.css\",\n  \"/assets/js/main.js\",\n  \"/assets/images/logo.svg\",\n];\n\nself.addEventListener(\"install\", (event) => {\n  event.waitUntil(\n    caches.open(CACHE_NAME).then((cache) => cache.addAll(urlsToCache))\n  );\n});\n\nself.addEventListener(\"fetch\", (event) => {\n  event.respondWith(\n    caches\n      .match(event.request)\n      .then((response) => response || fetch(event.request))\n  );\n});\n```\n\n**Register service worker:**\n\n```html\n<script>\n  if (\"serviceWorker\" in navigator) {\n    navigator.serviceWorker.register(\"/sw.js\");\n  }\n</script>\n```\n\n## Loading Optimization\n\n### Resource Hints\n\n**Preconnect to external domains:**\n\n```html\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n<link rel=\"preconnect\" href=\"https://cdn.modrinth.com\" />\n```\n\n**Prefetch next page:**\n\n```html\n<link rel=\"prefetch\" href=\"{{ next_page.url | relative_url }}\" />\n```\n\n**Preload critical resources:**\n\n```html\n<link\n  rel=\"preload\"\n  href=\"/assets/fonts/main.woff2\"\n  as=\"font\"\n  type=\"font/woff2\"\n  crossorigin\n/>\n<link rel=\"preload\" href=\"/assets/images/hero.webp\" as=\"image\" />\n```\n\n### Font Optimization\n\n**Use system fonts:**\n\n```css\nbody {\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen,\n    Ubuntu, Cantarell, sans-serif;\n}\n```\n\n**Or optimize web fonts:**\n\n```css\n/* Only load needed weights and styles */\n@font-face {\n  font-family: \"CustomFont\";\n  src: url(\"/fonts/custom-regular.woff2\") format(\"woff2\");\n  font-weight: 400;\n  font-display: swap;\n}\n```\n\n**Subset fonts:**\n\n```bash\n# Install glyphhanger\nnpm install -g glyphhanger\n\n# Generate subset\nglyphhanger --subset=font.ttf \\\n            --formats=woff2 \\\n            --whitelist=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\"\n```\n\n## Runtime Performance\n\n### Efficient JavaScript\n\n**Debounce expensive operations:**\n\n```javascript\nfunction debounce(func, wait) {\n  let timeout;\n  return function (...args) {\n    clearTimeout(timeout);\n    timeout = setTimeout(() => func.apply(this, args), wait);\n  };\n}\n\n// Usage\nconst search = debounce((query) => {\n  // Expensive search operation\n}, 300);\n\ninput.addEventListener(\"input\", (e) => search(e.target.value));\n```\n\n**Use requestAnimationFrame:**\n\n```javascript\nfunction updateAnimation() {\n  // Animation logic\n  requestAnimationFrame(updateAnimation);\n}\n\nrequestAnimationFrame(updateAnimation);\n```\n\n**Lazy load images:**\n\n```javascript\nconst observer = new IntersectionObserver((entries) => {\n  entries.forEach((entry) => {\n    if (entry.isIntersecting) {\n      const img = entry.target;\n      img.src = img.dataset.src;\n      observer.unobserve(img);\n    }\n  });\n});\n\ndocument.querySelectorAll(\"img[data-src]\").forEach((img) => {\n  observer.observe(img);\n});\n```\n\n### CSS Performance\n\n**Avoid expensive selectors:**\n\n```css\n/* Slow */\ndiv > div > div > p {\n}\n\n/* Fast */\n.paragraph {\n}\n```\n\n**Use transforms over position:**\n\n```css\n/* Slow */\n.element {\n  left: 100px;\n  top: 100px;\n}\n\n/* Fast */\n.element {\n  transform: translate(100px, 100px);\n}\n```\n\n**Enable GPU acceleration:**\n\n```css\n.animated {\n  transform: translateZ(0);\n  will-change: transform;\n}\n```\n\n## Monitoring\n\n### Lighthouse\n\n```bash\nnpm install -g lighthouse\n\nlighthouse https://yoursite.com \\\n  --output html \\\n  --output-path ./report.html\n```\n\n### Web Vitals\n\n**Measure Core Web Vitals:**\n\n```html\n<script type=\"module\">\n  import {\n    getCLS,\n    getFID,\n    getFCP,\n    getLCP,\n    getTTFB,\n  } from \"https://unpkg.com/web-vitals@3/dist/web-vitals.js\";\n\n  function sendToAnalytics(metric) {\n    console.log(metric);\n    // Send to analytics service\n  }\n\n  getCLS(sendToAnalytics);\n  getFID(sendToAnalytics);\n  getFCP(sendToAnalytics);\n  getLCP(sendToAnalytics);\n  getTTFB(sendToAnalytics);\n</script>\n```\n\n### Performance API\n\n```javascript\n// Measure page load time\nwindow.addEventListener(\"load\", () => {\n  const perfData = performance.getEntriesByType(\"navigation\")[0];\n  console.log(\"Page load time:\", perfData.loadEventEnd - perfData.fetchStart);\n});\n\n// Custom timing\nperformance.mark(\"search-start\");\n// ... search operation\nperformance.mark(\"search-end\");\nperformance.measure(\"search\", \"search-start\", \"search-end\");\n```\n\n## Checklist\n\n- [ ] Enable SASS compression\n- [ ] Exclude unnecessary files from build\n- [ ] Optimize and compress images\n- [ ] Minify CSS and JavaScript\n- [ ] Add lazy loading for images\n- [ ] Implement resource hints (preconnect, prefetch)\n- [ ] Configure HTTP caching headers\n- [ ] Use system fonts or subset web fonts\n- [ ] Defer non-critical JavaScript\n- [ ] Enable gzip/brotli compression\n- [ ] Remove unused CSS\n- [ ] Optimize data file sizes\n- [ ] Test with Lighthouse\n- [ ] Monitor Core Web Vitals\n- [ ] Set up service worker for offline support\n\n## Benchmarking\n\n### Before Optimization\n\n```\nLighthouse Score: 65\nFirst Contentful Paint: 2.5s\nLargest Contentful Paint: 4.2s\nTotal Bundle Size: 850KB\n```\n\n### After Optimization\n\n```\nLighthouse Score: 95\nFirst Contentful Paint: 0.8s\nLargest Contentful Paint: 1.2s\nTotal Bundle Size: 220KB\n```\n\n## Next Steps\n\n- [Deployment Guide](deployment.html) - Deploy optimized site\n- [Accessibility Guide](accessibility.html) - Performance + accessibility\n- [SEO Guide](seo-guide.html) - Performance + SEO\n","## Directory Layout\n\n```\nabc-site/\n├── _docs/              # Documentation pages\n├── _includes/          # Reusable HTML components\n├── _layouts/           # Page templates\n├── assets/\n│   ├── css/           # Compiled stylesheets\n│   ├── images/        # Logo, icons, banners\n│   └── js/            # JavaScript files\n├── data/              # JSON data files (projects)\n├── docs/              # Rendered docs output\n├── src/\n│   ├── scripts/       # Source JS files\n│   └── styles/        # Source CSS (compiles to assets/css/)\n├── _config.yml        # Site configuration\n├── Gemfile            # Ruby dependencies\n├── package.json       # Node dependencies\n└── index.md           # Homepage\n```\n\n## Key Files\n\n| File                    | Purpose                                     |\n| ----------------------- | ------------------------------------------- |\n| `_config.yml`           | Site settings, branding, Modrinth config    |\n| `_layouts/default.html` | Main page template                          |\n| `_includes/nav.html`    | Navigation bar component                    |\n| `_includes/footer.html` | Footer component                            |\n| `data/mods.json`        | Project data (generated by `npm run fetch`) |\n| `assets/css/`           | Compiled stylesheets                        |\n| `src/styles/`           | Source stylesheets                          |\n\n## Front Matter\n\nEach Markdown page has YAML front matter:\n\n```yaml\n---\nlayout: default # Template to use\ntitle: Page Title # Page heading\ndescription: ... # Meta description\ncategory: Category # (for docs only)\ntags: [tag1, tag2] # (for docs only)\npermalink: /custom-url/ # Custom URL\n---\n```\n\n## Collections\n\n### `_docs/` - Documentation pages\n\nLocated in `_docs/` directory, rendered to `/docs/`.\n\nEach page needs:\n\n```yaml\nlayout: doc\nnav_order: 1\ncategory: Category Name\ntags: [tag1, tag2]\n```\n\n### `_includes/` - Components\n\nReusable HTML snippets included in templates:\n\n- `nav.html` - Navigation bar\n- `footer.html` - Footer\n- `theme-controls.html` - Theme toggle\n- `schema-markup.html` - SEO schema\n\n---\n\nSee [Contributing](contributing) to modify the structure.\n","# SEO Guide\n\nOptimize your ABC showcase for better search rankings and social media sharing.\n\n## Meta Tags\n\n### Basic SEO Meta Tags\n\n```html\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <title>{{ page.title }} | {{ site.title }}</title>\n  <meta\n    name=\"description\"\n    content=\"{{ page.description | default: site.description }}\"\n  />\n  <meta name=\"keywords\" content=\"{{ page.tags | join: ', ' }}\" />\n  <meta name=\"author\" content=\"{{ site.author }}\" />\n  <link rel=\"canonical\" href=\"{{ page.url | absolute_url }}\" />\n</head>\n```\n\n### Jekyll SEO Tag Plugin\n\nInstall and configure:\n\n```ruby\n# Gemfile\ngem 'jekyll-seo-tag'\n```\n\n```yaml\n# _config.yml\nplugins:\n  - jekyll-seo-tag\n\ntitle: ABC Showcase\ndescription: Showcase your Minecraft modpacks beautifully\nurl: https://yoursite.com\nauthor:\n  name: Your Name\n  twitter: yourusername\n\nsocial:\n  name: ABC Showcase\n  links:\n    - https://twitter.com/yourusername\n    - https://github.com/yourusername\n```\n\nInclude in layout:\n\n{% raw %}\n\n```html\n<head>\n  {% seo %}\n</head>\n```\n\n{% endraw %}\n\n## Open Graph Tags\n\n### For Social Media Sharing\n\n```html\n<meta property=\"og:title\" content=\"{{ page.title }}\" />\n<meta property=\"og:description\" content=\"{{ page.description }}\" />\n<meta\n  property=\"og:image\"\n  content=\"{{ page.image | default: site.image | absolute_url }}\"\n/>\n<meta property=\"og:url\" content=\"{{ page.url | absolute_url }}\" />\n<meta property=\"og:type\" content=\"website\" />\n<meta property=\"og:site_name\" content=\"{{ site.title }}\" />\n```\n\n### Twitter Cards\n\n```html\n<meta name=\"twitter:card\" content=\"summary_large_image\" />\n<meta name=\"twitter:site\" content=\"@yourusername\" />\n<meta name=\"twitter:creator\" content=\"@yourusername\" />\n<meta name=\"twitter:title\" content=\"{{ page.title }}\" />\n<meta name=\"twitter:description\" content=\"{{ page.description }}\" />\n<meta name=\"twitter:image\" content=\"{{ page.image | absolute_url }}\" />\n```\n\n### Page-Specific OG Images\n\n```yaml\n# In page frontmatter\n---\ntitle: My Modpack\ndescription: An amazing tech-focused modpack\nimage: /assets/images/modpack-preview.png\n---\n```\n\n## Structured Data\n\n### JSON-LD for Projects\n\n```html\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"SoftwareApplication\",\n    \"name\": \"{{ modpack.name }}\",\n    \"description\": \"{{ modpack.description }}\",\n    \"url\": \"{{ modpack.source_url }}\",\n    \"downloadUrl\": \"{{ modpack.source_url }}\",\n    \"image\": \"{{ modpack.icon_url }}\",\n    \"applicationCategory\": \"Game\",\n    \"operatingSystem\": \"Windows, macOS, Linux\",\n    \"aggregateRating\": {\n      \"@type\": \"AggregateRating\",\n      \"ratingValue\": \"4.5\",\n      \"ratingCount\": \"{{ modpack.followers }}\"\n    },\n    \"offers\": {\n      \"@type\": \"Offer\",\n      \"price\": \"0\",\n      \"priceCurrency\": \"USD\"\n    }\n  }\n</script>\n```\n\n### Organization Schema\n\n```html\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"Organization\",\n    \"name\": \"{{ site.title }}\",\n    \"url\": \"{{ site.url }}\",\n    \"logo\": \"{{ '/assets/images/logo.png' | absolute_url }}\",\n    \"sameAs\": [\n      \"https://twitter.com/yourusername\",\n      \"https://github.com/yourusername\"\n    ]\n  }\n</script>\n```\n\n### Breadcrumb Schema\n\n```html\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"BreadcrumbList\",\n    \"itemListElement\": [\n      {\n        \"@type\": \"ListItem\",\n        \"position\": 1,\n        \"name\": \"Home\",\n        \"item\": \"{{ '/' | absolute_url }}\"\n      },\n      {\n        \"@type\": \"ListItem\",\n        \"position\": 2,\n        \"name\": \"{{ page.category }}\",\n        \"item\": \"{{ '/docs/category/' | append: page.category | slugify | append: '/' | absolute_url }}\"\n      },\n      {\n        \"@type\": \"ListItem\",\n        \"position\": 3,\n        \"name\": \"{{ page.title }}\"\n      }\n    ]\n  }\n</script>\n```\n\n## Sitemap\n\n### Generate with Jekyll\n\n```ruby\n# Gemfile\ngem 'jekyll-sitemap'\n```\n\n```yaml\n# _config.yml\nplugins:\n  - jekyll-sitemap\n\nurl: https://yoursite.com\n```\n\n### Custom Sitemap\n\nCreate `sitemap.xml`:\n\n```xml\n---\nlayout: null\n---\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n  <url>\n    <loc>{{ '/' | absolute_url }}</loc>\n    <lastmod>{{ site.time | date_to_xmlschema }}</lastmod>\n    <changefreq>daily</changefreq>\n    <priority>1.0</priority>\n  </url>\n  {% for page in site.pages %}\n    {% unless page.url contains 'feed' or page.url contains 'sitemap' %}\n    <url>\n      <loc>{{ page.url | absolute_url }}</loc>\n      <lastmod>{{ site.time | date_to_xmlschema }}</lastmod>\n      <changefreq>weekly</changefreq>\n      <priority>0.8</priority>\n    </url>\n    {% endunless %}\n  {% endfor %}\n  {% for doc in site.docs %}\n    <url>\n      <loc>{{ doc.url | absolute_url }}</loc>\n      <lastmod>{{ doc.date | default: site.time | date_to_xmlschema }}</lastmod>\n      <changefreq>monthly</changefreq>\n      <priority>0.6</priority>\n    </url>\n  {% endfor %}\n</urlset>\n```\n\n## Robots.txt\n\n```\n# /robots.txt\nUser-agent: *\nAllow: /\nDisallow: /admin/\nDisallow: /_site/\nSitemap: https://yoursite.com/sitemap.xml\n```\n\n## URL Structure\n\n### SEO-Friendly URLs\n\n```yaml\n# _config.yml\npermalink: /:categories/:title/\n\ncollections:\n  docs:\n    output: true\n    permalink: /docs/:name/\n```\n\n**Good URLs:**\n\n- `/docs/getting-started/`\n- `/projects/`\n- `/docs/category/setup/`\n\n**Bad URLs:**\n\n- `/page.html?id=123`\n- `/p/456`\n- `/docs/doc1/`\n\n## Content Optimization\n\n### Title Tags\n\n```liquid\n<!-- Page titles -->\n<title>{% if page.title %}{{ page.title }} | {% endif %}{{ site.title }}</title>\n\n<!-- Keep under 60 characters -->\n<!-- Include primary keyword -->\n<!-- Make descriptive and unique -->\n```\n\n### Meta Descriptions\n\n```yaml\n---\ndescription: Learn how to set up your ABC showcase in under 5 minutes with this comprehensive guide.\n---\n```\n\n**Best practices:**\n\n- 150-160 characters\n- Include target keyword\n- Make compelling and actionable\n- Unique for each page\n\n### Heading Structure\n\n```html\n<h1>Main Page Title</h1>\n<!-- Only one per page -->\n<h2>Major Section</h2>\n<h3>Subsection</h3>\n<h2>Another Section</h2>\n```\n\n### Internal Linking\n\n```liquid\n<!-- Link to related content -->\n<p>See our <a href=\"{{ '/docs/setup/' | relative_url }}\">setup guide</a> for more details.</p>\n\n<!-- Use descriptive anchor text -->\n<!-- Avoid \"click here\" -->\n```\n\n## Performance for SEO\n\n### Page Speed\n\n```yaml\n# Fast loading = better SEO\n# Target metrics:\n# - First Contentful Paint: < 1.8s\n# - Largest Contentful Paint: < 2.5s\n# - Time to Interactive: < 3.8s\n```\n\nSee [Performance Guide](performance.html) for optimization.\n\n### Mobile-Friendly\n\n```html\n<!-- Responsive viewport -->\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n```\n\n```css\n/* Mobile-first design */\n.container {\n  padding: 20px;\n}\n\n@media (min-width: 768px) {\n  .container {\n    padding: 40px;\n  }\n}\n```\n\n## Analytics\n\n### Google Analytics 4\n\n```html\n<!-- Global site tag (gtag.js) -->\n<script\n  async\n  src=\"https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX\"\n></script>\n<script>\n  window.dataLayer = window.dataLayer || [];\n  function gtag() {\n    dataLayer.push(arguments);\n  }\n  gtag(\"js\", new Date());\n  gtag(\"config\", \"G-XXXXXXXXXX\");\n</script>\n```\n\n### Google Search Console\n\n1. Add property at [search.google.com/search-console](https://search.google.com/search-console)\n2. Verify ownership via HTML tag or DNS\n3. Submit sitemap\n4. Monitor performance and issues\n\n### Track Important Metrics\n\n- Organic search traffic\n- Click-through rates\n- Average position\n- Core Web Vitals\n- Mobile usability\n- Index coverage\n\n## Social Sharing Optimization\n\n### Social Share Buttons\n\n```html\n<div class=\"share-buttons\">\n  <a\n    href=\"https://twitter.com/intent/tweet?url={{ page.url | absolute_url }}&text={{ page.title }}\"\n    target=\"_blank\"\n    rel=\"noopener\"\n    aria-label=\"Share on Twitter\"\n  >\n    <i class=\"fab fa-twitter\"></i>\n  </a>\n\n  <a\n    href=\"https://www.facebook.com/sharer/sharer.php?u={{ page.url | absolute_url }}\"\n    target=\"_blank\"\n    rel=\"noopener\"\n    aria-label=\"Share on Facebook\"\n  >\n    <i class=\"fab fa-facebook\"></i>\n  </a>\n\n  <a\n    href=\"https://reddit.com/submit?url={{ page.url | absolute_url }}&title={{ page.title }}\"\n    target=\"_blank\"\n    rel=\"noopener\"\n    aria-label=\"Share on Reddit\"\n  >\n    <i class=\"fab fa-reddit\"></i>\n  </a>\n</div>\n```\n\n### Test Social Cards\n\n- [Twitter Card Validator](https://cards-dev.twitter.com/validator)\n- [Facebook Sharing Debugger](https://developers.facebook.com/tools/debug/)\n- [LinkedIn Post Inspector](https://www.linkedin.com/post-inspector/)\n\n## Best Practices Checklist\n\n- [ ] Unique title and description for each page\n- [ ] Proper heading hierarchy (h1 → h2 → h3)\n- [ ] SEO-friendly URLs (descriptive, lowercase, hyphens)\n- [ ] Alt text for all images\n- [ ] Internal linking between related pages\n- [ ] Mobile-responsive design\n- [ ] Fast page load times (< 3s)\n- [ ] HTTPS enabled\n- [ ] Sitemap.xml submitted to search engines\n- [ ] Robots.txt configured\n- [ ] Structured data (JSON-LD) implemented\n- [ ] Open Graph tags for social sharing\n- [ ] Canonical URLs set\n- [ ] No broken links\n- [ ] Google Analytics installed\n- [ ] Google Search Console configured\n\n## Common Issues\n\n### Duplicate Content\n\n```html\n<!-- Use canonical tags -->\n<link rel=\"canonical\" href=\"{{ page.url | absolute_url }}\" />\n```\n\n### Broken Links\n\n```bash\n# Check with htmlproofer\ngem install html-proofer\nbundle exec htmlproofer ./_site --assume-extension\n```\n\n### Missing Alt Text\n\n```liquid\n{% for modpack in site.data.mods.modpacks %}\n  <img src=\"{{ modpack.icon_url }}\"\n       alt=\"{{ modpack.name }} icon\"\n       loading=\"lazy\">\n{% endfor %}\n```\n\n## Tools\n\n- **Google Search Console**: Monitor search performance\n- **Google PageSpeed Insights**: Test page speed\n- **Screaming Frog**: Crawl and audit your site\n- **Ahrefs/SEMrush**: Keyword research and tracking\n- **Lighthouse**: Automated SEO auditing\n\n## Next Steps\n\n- [Performance Guide](performance.html) - Speed optimization\n- [Accessibility Guide](accessibility.html) - Inclusive design\n- [Deployment Guide](deployment.html) - Launch your site\n","## Rebranding\n\nEdit `_config.yml` to customize your showcase:\n\n```yaml\nsite:\n  name: Your Site Name\n  title: Your Site Title\n  description: A brief description\n  logo: /assets/images/your-logo.svg\n  color: \"#1bd96f\"\n```\n\nReplace images in `assets/images/`:\n\n- `logo.svg` - Navbar logo\n- `favicon.svg` - Browser tab icon\n- `favicon.ico` - Fallback favicon\n\nUpdate SEO metadata:\n\n```yaml\nmeta:\n  og_image: /assets/images/og-image.png\n  apple_touch_icon: /assets/images/apple-touch.png\n```\n\n## Modrinth Integration\n\n### Set Organization\n\nIn `_config.yml`:\n\n```yaml\nmodrinth:\n  org_slug: your-org-slug\n```\n\n### Fetch Projects\n\nAutomatically pull your projects from Modrinth:\n\n```bash\nnpm run fetch\n```\n\nThis updates `data/mods.json` with live project data including downloads, versions, and metadata.\n\n### API Token (Optional)\n\nFor private projects, set the environment variable:\n\n```bash\nexport MODRINTH_API_TOKEN=your_token_here\nnpm run fetch\n```\n\nGet your token from [Modrinth Settings](https://modrinth.com/dashboard/settings).\n\n## Social Links\n\nConfigure social links in `_config.yml`:\n\n```yaml\nsocial:\n  github: https://github.com/your-org/your-repo\n  discord: https://discord.gg/your-invite\n  twitter: https://twitter.com/your-handle\n  modrinth: https://modrinth.com/organization/your-org\n```\n\nThese appear in the navigation and footer.\n\n## Running Locally\n\n### Development\n\n```bash\nbundle install\nnpm install\nbundle exec jekyll serve --livereload\n```\n\nVisit `http://localhost:4000/abc-site/` (adjust baseurl if needed)\n\n### Production Build\n\n```bash\nbundle exec jekyll build\n```\n\nOutput goes to `_site/` ready for deployment.\n\n## Deployment\n\n### GitHub Pages\n\nThe site auto-deploys on push to `main` via GitHub Actions (if configured).\n\n**Manual deployment:**\n\n```bash\nbundle exec jekyll build\ngit add _site/\ngit commit -m \"Update site\"\ngit push origin main\n```\n\n### Custom Hosting\n\nBuild the site:\n\n```bash\nJEKYLL_ENV=production bundle exec jekyll build\n```\n\nUpload `_site/` contents to your hosting provider.\n\n---\n\n**Questions?** Check the [Getting Started](getting-started) guide or open an [issue]({{ site.social.github }}/issues).\n","## Build Fails\n\n**Issue:** `bundle exec jekyll build` fails with an error\n\n**Solutions:**\n\n1. Check Ruby version: `ruby -v` (need 2.6+)\n2. Update gems: `bundle update`\n3. Clear cache: `rm -rf .bundle _site`\n4. Check for syntax errors in YAML files\n\n## Projects Not Showing\n\n**Issue:** Project cards are empty or don't display\n\n**Solutions:**\n\n1. Verify `data/mods.json` exists and is valid JSON\n2. Run `npm run fetch` to regenerate data\n3. Check Modrinth organization slug in `_config.yml`\n4. Ensure API token is set if fetching private projects: `export MODRINTH_API_TOKEN=your_token`\n\n## Styles Not Updating\n\n**Issue:** CSS changes don't appear after editing\n\n**Solutions:**\n\n1. Hard refresh browser: **Cmd+Shift+R** (Mac) or **Ctrl+Shift+R** (Windows)\n2. Restart Jekyll: `bundle exec jekyll serve --livereload`\n3. Clear `_site/` folder: `rm -rf _site`\n4. Ensure you're editing `src/styles/` (will compile to `assets/css/`)\n\n## Navigation Links Broken\n\n**Issue:** Links show 404 or lead to wrong pages\n\n**Solutions:**\n\n1. Check `baseurl` in `_config.yml` matches your deploy path\n2. Verify file exists and permalink is correct in front matter\n3. Use `relative_url` filter: `{{ '/docs/' | relative_url }}`\n\n## Navbar Not Full Width\n\n**Issue:** Header/footer doesn't span the full page\n\n**Solutions:**\n\n1. Check header CSS has `width: 100vw` and `box-sizing: border-box`\n2. Ensure no parent element constrains the width\n3. Verify `padding` isn't adding extra width\n\n## Performance Issues\n\n**Issue:** Site builds slowly\n\n**Solutions:**\n\n1. Check `_config.yml` excludes large folders: `node_modules`, `src/`\n2. Reduce image sizes in `assets/images/`\n3. Remove unused CSS/JS files\n4. Consider using incremental builds: `bundle exec jekyll serve -I`\n\n## Search Not Working\n\n**Issue:** Search bar doesn't filter results\n\n**Solutions:**\n\n1. Ensure `search.js` is loaded in layout\n2. Check that project data is loaded: open DevTools Console\n3. Verify JSON file path is correct\n\n---\n\n**Still stuck?** [Open an issue]({{ site.social.github }}/issues) or check the [FAQ](faq).\n"],"files":[],"output":true,"relative_directory":"_docs","directory":"/home/runner/work/abc-site/abc-site/_docs","permalink":"/docs/:path/"},{"label":"posts","docs":["\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <title>Welcome to the Blog</title>\n    <meta\n      name=\"description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta\n      name=\"robots\"\n      content=\"index, follow\"\n    />\n\n    <!-- SEO Meta Tags -->\n          \n\n    <meta\n      property=\"og:title\"\n      content=\"Welcome to the Blog\"\n    />\n    <meta\n      property=\"og:description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta property=\"og:url\" content=\"https://abc-site.devvyy.xyz/blog/blog-test/\" />\n    <meta property=\"og:image\" content=\"https://abc-site.devvyy.xyz/assets/images/logo.svg\" />\n    <meta property=\"og:image:alt\" content=\"ABC Mods & Packs\" />\n    <meta property=\"og:type\" content=\"post\" />\n    <meta property=\"og:site_name\" content=\"ABC\" />\n    <meta\n      property=\"og:locale\"\n      content=\"en_US\"\n    />\n\n    <!-- hreflang tags for multilingual SEO -->\n    <link\n      rel=\"alternate\"\n      hreflang=\"en\"\n      href=\"https://abc-site.devvyy.xyz/blog/blog-test/\"\n    />\n    <link\n      rel=\"alternate\"\n      hreflang=\"fr\"\n      href=\"https://abc-site.devvyy.xyz/fr/blog/blog-test/\"\n    />\n    <link\n      rel=\"alternate\"\n      hreflang=\"x-default\"\n      href=\"https://abc-site.devvyy.xyz/blog/blog-test/\"\n    />\n\n    <!-- Twitter Card -->\n    <meta name=\"twitter:card\" content=\"summary_large_image\" />\n    <meta\n      name=\"twitter:title\"\n      content=\"Welcome to the Blog\"\n    />\n    <meta\n      name=\"twitter:description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta\n      name=\"twitter:image\"\n      content=\"https://abc-site.devvyy.xyz/assets/images/logo.svg\"\n    />\n    <meta name=\"twitter:image:alt\" content=\"ABC Mods & Packs\" />\n    <meta\n      name=\"twitter:creator\"\n      content=\"@devvyyxyz\"\n    />\n    <meta\n      name=\"twitter:site\"\n      content=\"@devvyyxyz\"\n    />\n\n    <meta\n      name=\"theme-color\"\n      content=\"#1bd96f\"\n    />\n\n    <!-- Favicon -->\n    <link\n      rel=\"icon\"\n      type=\"image/svg+xml\"\n      href=\"/favicon.svg\"\n    />\n    <link\n      rel=\"icon\"\n      type=\"image/x-icon\"\n      href=\"/favicon.svg\"\n    />\n    <link\n      rel=\"apple-touch-icon\"\n      href=\"/assets/images/logo.svg\"\n    />\n\n    <!-- Google Fonts - Preload -->\n    <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n    <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n    <link\n      rel=\"preload\"\n      as=\"style\"\n      href=\"https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap\"\n    />\n    <link\n      href=\"https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap\"\n      rel=\"stylesheet\"\n    />\n\n    <!-- Font Awesome Icons - Async load -->\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <noscript>\n      <link\n        rel=\"stylesheet\"\n        href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n      />\n    </noscript>\n\n    <!-- Stylesheets - Critical -->\n    <link rel=\"stylesheet\" href=\"/assets/css/root.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/layout.css\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/loading.css\"\n    />\n\n    <!-- Stylesheets - Deferred (non-critical) -->\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/components.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/modpacks.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/animations.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/theme.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/a11y.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/visual-enhancements.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/mobile.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <noscript>\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/components.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/modpacks.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/animations.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/theme.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/a11y.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/visual-enhancements.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/mobile.css\"\n      />\n    </noscript>\n\n    <!-- Canonical URL -->\n    <link rel=\"canonical\" href=\"https://abc-site.devvyy.xyz/blog/blog-test/\" />\n\n    <!-- Schema Markup -->\n    <!-- Schema.org JSON-LD -->\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"Organization\",\n    \"name\": \"ABC\",\n    \"description\": \"Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins.\",\n    \"url\": \"https://abc-site.devvyy.xyz\",\n    \"logo\": \"https://abc-site.devvyy.xyz/assets/images/logo.svg\",\n    \"sameAs\": [\n      \"https://github.com/devvyyxyz\",\n      \"https://twitter.com/devvyyxyz\",\n      \"https://dc.gg/devvyyxyz\"\n    ],\n    \"contactPoint\": {\n      \"@type\": \"ContactPoint\",\n      \"contactType\": \"Community Support\",\n      \"url\": \"https://dc.gg/devvyyxyz\"\n    }\n  }\n</script>\n\n<!-- Breadcrumb Schema -->\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"BreadcrumbList\",\n    \"itemListElement\": [\n      {\n        \"@type\": \"ListItem\",\n        \"position\": 1,\n        \"name\": \"Home\",\n        \"item\": \"https://abc-site.devvyy.xyz\"\n      }\n      \n      , {\n        \"@type\": \"ListItem\",\n        \"position\": 2,\n        \"name\": \"Welcome to the Blog\",\n        \"item\": \"https://abc-site.devvyy.xyz/blog/blog-test/\"\n      }\n      \n    ]\n  }\n</script>\n\n<!-- Project/Software Application Schema (for project pages) -->\n\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"Article\",\n    \"headline\": \"Welcome to the Blog\",\n    \"description\": \"Kicking off our new blog — what's coming next.\",\n    \"image\": \"\",\n    \"datePublished\": \"2025-12-16T00:00:00+00:00\",\n    \"dateModified\": \"2025-12-16T00:00:00+00:00\",\n    \"author\": {\n      \"@type\": \"Organization\",\n      \"name\": \"ABC\"\n    },\n    \"publisher\": {\n      \"@type\": \"Organization\",\n      \"name\": \"ABC\",\n      \"logo\": {\n        \"@type\": \"ImageObject\",\n        \"url\": \"https://abc-site.devvyy.xyz/assets/images/logo.svg\"\n      }\n    }\n  }\n</script>\n<!-- WebPage Schema -->\n\n\n\n    <!-- Preloader Script (critical, inline) -->\n    <script>\n      (function () {\n        if (!document.body) return; // Exit if body not ready yet\n\n        const isDarkMode =\n          window.matchMedia &&\n          window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n        const bgColor = isDarkMode ? \"#0d0d0d\" : \"#f6fbfa\";\n        document.documentElement.style.backgroundColor = bgColor;\n        document.body.style.backgroundColor = bgColor;\n\n        const overlay = document.createElement(\"div\");\n        overlay.className = \"loading-overlay\";\n        overlay.id = \"loading-overlay\";\n        overlay.innerHTML = '<div class=\"spinner\"></div>';\n        document.body.appendChild(overlay);\n\n        if (document.readyState === \"loading\") {\n          document.addEventListener(\"DOMContentLoaded\", hidePreloader);\n        } else {\n          hidePreloader();\n        }\n\n        function hidePreloader() {\n          const preloader = document.getElementById(\"loading-overlay\");\n          if (preloader) {\n            preloader.classList.add(\"hidden\");\n          }\n        }\n\n        window.hidePreloader = hidePreloader;\n      })();\n    </script>\n  </head>\n  <body>\n    <a href=\"#main\" class=\"skip-to-main\">Skip to main content</a>\n    <header class=\"floating-nav\">\n  <div class=\"nav-inner\">\n    <a\n      class=\"logo\"\n      href=\"/\"\n      style=\"display: flex; align-items: center; gap: 8px\"\n      aria-label=\"ABC\"\n    >\n      <img\n        src=\"/assets/images/logo.svg\"\n        alt=\"ABC\"\n        style=\"height: 32px; width: auto\"\n      />\n      \n    </a>\n    <button\n      class=\"mobile-menu-toggle\"\n      aria-label=\"Toggle menu\"\n      id=\"mobile-menu-toggle\"\n    >\n      <i class=\"fas fa-bars\"></i>\n    </button>\n    <nav class=\"links\" id=\"mobile-nav\">\n      <a href=\"/\">Home</a>\n      <a href=\"/about/\">About</a>\n      <a href=\"/docs/\">Docs</a>\n      <a href=\"/changelog/\">Changelog</a>\n      <a href=\"/blog/\">Blog</a>\n      <div class=\"nav-dropdown\">\n        <a href=\"/projects/\" class=\"dropdown-toggle\">\n          Projects <i class=\"fas fa-chevron-down\"></i>\n        </a>\n        <div class=\"dropdown-menu\">\n          <a href=\"/projects/\">All Projects</a>\n          <a href=\"/compare/\"\n            ><i class=\"fas fa-balance-scale\"></i> Compare Modpacks</a\n          >\n          <a href=\"/changelog/\"\n            ><i class=\"fas fa-rocket\"></i> Releases & Changelog</a\n          >\n        </div>\n      </div>\n      <div class=\"nav-dropdown\">\n        <a href=\"#\" class=\"dropdown-toggle\">\n          Legal <i class=\"fas fa-chevron-down\"></i>\n        </a>\n        <div class=\"dropdown-menu\">\n          <a href=\"/privacy/\">Privacy Policy</a>\n          <a href=\"/terms/\">Terms of Service</a>\n          <a href=\"/cookie-policy/\">Cookie Policy</a>\n          <a href=\"/licensing/\">Licensing</a>\n          <a href=\"/eula/\">EULA</a>\n          <a href=\"/disclaimer/\">Disclaimer</a>\n        </div>\n      </div>\n      <a\n        href=\"https://modrinth.com/organization/abcxyz\"\n        target=\"_blank\"\n        rel=\"noopener\"\n        >Organization</a\n      >\n    </nav>\n    <div class=\"nav-actions\">\n      <div\n        id=\"social-links-nav\"\n        style=\"display: flex; gap: 6px; align-items: center\"\n      ></div>\n      <!-- Theme Toggle -->\n<div class=\"theme-toggle\" id=\"theme-toggle\" title=\"Toggle dark/light mode\">\n  <button id=\"theme-dark\" class=\"active\" aria-label=\"Dark mode\" title=\"Dark mode\">\n    <i class=\"fa-solid fa-moon\"></i>\n  </button>\n  <button id=\"theme-light\" aria-label=\"Light mode\" title=\"Light mode\">\n    <i class=\"fa-solid fa-sun\"></i>\n  </button>\n</div>\n\n<script>\n  // Theme toggle functionality\n  const themeToggle = {\n    init() {\n      this.darkBtn = document.getElementById('theme-dark');\n      this.lightBtn = document.getElementById('theme-light');\n      this.html = document.documentElement;\n\n      // Load saved theme or use system preference\n      const saved = localStorage.getItem('theme');\n      const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;\n      const theme = saved || (systemDark ? 'dark' : 'light');\n\n      this.setTheme(theme);\n\n      // Listen for changes\n      this.darkBtn.addEventListener('click', () => this.setTheme('dark'));\n      this.lightBtn.addEventListener('click', () => this.setTheme('light'));\n\n      // Listen for system theme changes\n      window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {\n        if (!localStorage.getItem('theme')) {\n          this.setTheme(e.matches ? 'dark' : 'light');\n        }\n      });\n    },\n\n    setTheme(theme) {\n      this.html.setAttribute('data-theme', theme);\n      localStorage.setItem('theme', theme);\n\n      this.darkBtn.classList.toggle('active', theme === 'dark');\n      this.lightBtn.classList.toggle('active', theme === 'light');\n\n      // Update meta theme-color\n      const color = theme === 'dark' ? '#1bd96f' : '#1bd96f';\n      document.querySelector('meta[name=\"theme-color\"]').setAttribute('content', color);\n    }\n  };\n\n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', () => themeToggle.init());\n  } else {\n    themeToggle.init();\n  }\n</script>\n\n    </div>\n  </div>\n</header>\n\n<script>\n  // Mobile menu toggle\n  document.addEventListener(\"DOMContentLoaded\", () => {\n    const toggle = document.getElementById(\"mobile-menu-toggle\");\n    const nav = document.getElementById(\"mobile-nav\");\n\n    if (toggle && nav) {\n      toggle.addEventListener(\"click\", () => {\n        nav.classList.toggle(\"mobile-open\");\n        const icon = toggle.querySelector(\"i\");\n        if (nav.classList.contains(\"mobile-open\")) {\n          icon.classList.remove(\"fa-bars\");\n          icon.classList.add(\"fa-times\");\n        } else {\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        }\n      });\n\n      // Close menu when clicking a link\n      nav.querySelectorAll(\"a\").forEach((link) => {\n        link.addEventListener(\"click\", () => {\n          nav.classList.remove(\"mobile-open\");\n          const icon = toggle.querySelector(\"i\");\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        });\n      });\n\n      // Close menu when clicking outside\n      document.addEventListener(\"click\", (e) => {\n        if (!toggle.contains(e.target) && !nav.contains(e.target)) {\n          nav.classList.remove(\"mobile-open\");\n          const icon = toggle.querySelector(\"i\");\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        }\n      });\n    }\n  });\n</script>\n\n\n    <main id=\"main\" class=\"container\"><main class=\"content\">\n  <article class=\"post\" style=\"max-width: 820px; margin: 0 auto; padding: 24px\">\n    <header>\n      <h1 style=\"margin: 0 0 8px\">Welcome to the Blog</h1>\n      <p class=\"muted\" style=\"margin: 0 0 16px\">\n        December 16, 2025 • ABC Team\n      </p>\n    </header>\n    <section class=\"post-body\"><p>We’re launching a blog to share updates, release notes, and behind-the-scenes dev logs.</p>\n\n<!--more-->\n\n<p>What you can expect:</p>\n\n<ul>\n  <li>Deep dives into mods, datapacks, and plugins</li>\n  <li>Roadmap updates and upcoming releases</li>\n  <li>Performance tips and compatibility notes</li>\n  <li>Community showcases and contributions</li>\n</ul>\n\n<p>If you have topics you’d like us to cover, let us know on the contact page or Discord.</p>\n</section>\n\n    \n    <footer style=\"margin-top: 24px\">\n      <strong>Tags:</strong>\n      \n      <span\n        style=\"\n          display: inline-block;\n          padding: 4px 8px;\n          border: 1px solid var(--border);\n          border-radius: 999px;\n          margin-right: 6px;\n          font-size: 12px;\n        \"\n        >#announcement</span\n      >\n      \n      <span\n        style=\"\n          display: inline-block;\n          padding: 4px 8px;\n          border: 1px solid var(--border);\n          border-radius: 999px;\n          margin-right: 6px;\n          font-size: 12px;\n        \"\n        >#roadmap</span\n      >\n       \n      <div style=\"margin-top: 8px\">\n        <strong>Categories:</strong>\n        \n        <span\n          style=\"\n            display: inline-block;\n            padding: 4px 8px;\n            border: 1px solid var(--border);\n            border-radius: 999px;\n            margin-right: 6px;\n            font-size: 12px;\n          \"\n          >updates</span\n        >\n        \n      </div>\n      \n    </footer>\n    \n  </article>\n</main>\n</main>\n\n    <footer class=\"floating-footer\">\n  <div class=\"footer-inner\">\n    <div style=\"display: flex; gap: 16px; align-items: flex-start\">\n      <img\n        src=\"/assets/images/logo.svg\"\n        alt=\"ABC logo\"\n        style=\"height: 100px; flex-shrink: 0; width: auto\"\n        width=\"100\"\n        height=\"100\"\n      />\n      <div style=\"display: flex; flex-direction: column; gap: 8px\">\n        <div>\n          <h4\n            style=\"\n              margin: 0;\n              font-size: 18px;\n              font-weight: 700;\n              color: var(--text);\n            \"\n          >\n            ABC\n          </h4>\n          <p\n            style=\"\n              margin: 2px 0 0 0;\n              font-size: 12px;\n              color: var(--text-secondary);\n            \"\n          >\n            Established 2025\n          </p>\n        </div>\n        <p\n          style=\"\n            margin: 0;\n            font-size: 13px;\n            color: var(--text-secondary);\n            line-height: 1.6;\n          \"\n        >\n          Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins.\n        </p>\n      </div>\n    </div>\n    <div style=\"display: flex; gap: 48px\">\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Links\n        </h4>\n        <div\n          style=\"\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n            gap: 10px 12px;\n            font-size: 13px;\n            max-width: 320px;\n          \"\n        >\n          <a\n            href=\"/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Home</a\n          >\n          <a\n            href=\"/about/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >About</a\n          >\n          <a\n            href=\"/docs/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Docs</a\n          >\n          <a\n            href=\"/projects/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Projects</a\n          >\n          <a\n            href=\"/compare/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Compare</a\n          >\n          <a\n            href=\"/changelog/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Changelog</a\n          >\n          <a\n            href=\"https://modrinth.com/organization/abcxyz\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            target=\"_blank\"\n            rel=\"noopener\"\n            >Modrinth Org</a\n          >\n          <a\n            href=\"https://github.com/devvyyxyz\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            target=\"_blank\"\n            rel=\"noopener\"\n            >GitHub Org</a\n          >\n          <a\n            href=\"/sitemap.xml\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Sitemap</a\n          >\n          <a\n            href=\"/feed.xml\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >RSS Feed</a\n          >\n          <a\n            href=\"/blog/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Blog</a\n          >\n        </div>\n      </div>\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Help\n        </h4>\n        <div\n          style=\"\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n            gap: 10px 12px;\n            font-size: 13px;\n            max-width: 320px;\n          \"\n        >\n          <a\n            href=\"/contact/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Contact</a\n          >\n          <a\n            href=\"/docs/faq/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >FAQ</a\n          >\n          <a\n            href=\"/docs/troubleshooting/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Troubleshooting</a\n          >\n          <a\n            href=\"/docs/contributing/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Contributing</a\n          >\n          <a\n            href=\"/status/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Status</a\n          >\n        </div>\n      </div>\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Community\n        </h4>\n        <div\n          id=\"social-links-footer\"\n          style=\"display: flex; gap: 12px; flex-direction: column\"\n        ></div>\n      </div>\n    </div>\n  </div>\n  <div\n    style=\"\n      border-top: 1px solid var(--border);\n      margin-top: 32px;\n      padding-top: 24px;\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      font-size: 12px;\n      color: var(--text-secondary);\n      flex-wrap: wrap;\n      gap: 16px;\n    \"\n  >\n    <div style=\"display: flex; gap: 16px; align-items: center; flex-wrap: wrap\">\n      <div>\n        © <span id=\"year\"></span> ABC. All rights reserved.\n      </div>\n      <div\n        id=\"language-switcher\"\n        style=\"display: flex; gap: 8px; align-items: center\"\n      >\n        <span style=\"font-size: 12px; color: var(--text-secondary)\"\n          >Language:</span\n        >\n        <select\n          id=\"lang-select\"\n          style=\"\n            padding: 4px 8px;\n            border: 1px solid var(--border);\n            border-radius: var(--radius);\n            background: var(--bg-secondary);\n            color: var(--text);\n            font-size: 12px;\n            cursor: pointer;\n          \"\n        >\n          <option value=\"en\">English</option>\n          <option value=\"fr\">Français</option>\n        </select>\n      </div>\n    </div>\n    <div style=\"display: flex; gap: 20px\">\n      <a\n        href=\"/privacy/\"\n        style=\"\n          color: var(--text-secondary);\n          text-decoration: none;\n          transition: color 0.2s;\n        \"\n        >Privacy</a\n      >\n      <a\n        href=\"/terms/\"\n        style=\"\n          color: var(--text-secondary);\n          text-decoration: none;\n          transition: color 0.2s;\n        \"\n        >Terms</a\n      >\n    </div>\n  </div>\n</footer>\n\n<script>\n  // Social links configuration\n  const socials = {\n    github: {\n      name: \"GitHub\",\n      icon: \"fab fa-github\",\n      url: \"https://github.com/devvyyxyz\",\n    },\n    twitter: {\n      name: \"Twitter\",\n      icon: \"fab fa-x-twitter\",\n      url: \"https://twitter.com/devvyyxyz\",\n    },\n    discord: {\n      name: \"Discord\",\n      icon: \"fab fa-discord\",\n      url: \"https://dc.gg/devvyyxyz\",\n    },\n  };\n\n  function renderSocialLinks() {\n    const navContainer = document.getElementById(\"social-links-nav\");\n    const footerContainer = document.getElementById(\"social-links-footer\");\n\n    Object.entries(socials).forEach(([key, social]) => {\n      if (social.url && social.url.trim()) {\n        // Nav icon button\n        const navLink = document.createElement(\"a\");\n        navLink.href = social.url;\n        navLink.target = \"_blank\";\n        navLink.rel = \"noopener\";\n        navLink.title = social.name;\n        navLink.style.cssText =\n          \"display:flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:var(--radius);background:var(--bg-secondary);color:var(--text-secondary);text-decoration:none;font-size:16px;transition:all 0.2s ease;border:1px solid var(--border)\";\n        const icon = document.createElement(\"i\");\n        icon.className = social.icon;\n        icon.style.fontSize = \"18px\";\n        navLink.appendChild(icon);\n        navLink.onmouseover = () => {\n          navLink.style.background = \"var(--accent-primary)\";\n          navLink.style.color = \"#000000\";\n          navLink.style.borderColor = \"var(--accent-primary)\";\n        };\n        navLink.onmouseout = () => {\n          navLink.style.background = \"var(--bg-secondary)\";\n          navLink.style.color = \"var(--text-secondary)\";\n          navLink.style.borderColor = \"var(--border)\";\n        };\n        if (navContainer) navContainer.appendChild(navLink);\n\n        // Footer text link with icon\n        const footerLink = document.createElement(\"a\");\n        footerLink.href = social.url;\n        footerLink.target = \"_blank\";\n        footerLink.rel = \"noopener\";\n        footerLink.style.cssText =\n          \"display:flex;align-items:center;gap:8px;color:var(--text-secondary);text-decoration:none;transition:color 0.2s;font-size:13px\";\n        const footerIcon = document.createElement(\"i\");\n        footerIcon.className = social.icon;\n        footerIcon.style.width = \"16px\";\n        const footerText = document.createElement(\"span\");\n        footerText.textContent = social.name;\n        footerLink.appendChild(footerIcon);\n        footerLink.appendChild(footerText);\n        footerLink.onmouseover = () => {\n          footerLink.style.color = \"var(--accent-primary)\";\n        };\n        footerLink.onmouseout = () => {\n          footerLink.style.color = \"var(--text-secondary)\";\n        };\n        if (footerContainer) footerContainer.appendChild(footerLink);\n      }\n    });\n  }\n\n  document.addEventListener(\"DOMContentLoaded\", renderSocialLinks);\n\n  // Set year in footer\n  document.getElementById(\"year\").textContent = new Date().getFullYear();\n\n  // Language switcher\n  const langSelect = document.getElementById(\"lang-select\");\n  if (langSelect) {\n    const currentLang = 'en';\n    langSelect.value = currentLang;\n\n    langSelect.addEventListener(\"change\", (e) => {\n      const selectedLang = e.target.value;\n      const currentPath = window.location.pathname;\n      const baseUrl = \"\";\n\n      // Remove existing language prefix\n      let cleanPath = currentPath.replace(baseUrl, \"\");\n      cleanPath = cleanPath.replace(/^\\/(en|fr)/, \"\");\n\n      // Build new URL\n      const newPath =\n        selectedLang === \"en\"\n          ? baseUrl + cleanPath\n          : baseUrl + \"/\" + selectedLang + cleanPath;\n\n      window.location.href = newPath;\n    });\n  }\n</script>\n <!-- Scroll to top button -->\n<button id=\"scroll-to-top\" class=\"scroll-to-top\" aria-label=\"Scroll to top\" title=\"Back to top\">\n  <i class=\"fa-solid fa-chevron-up\"></i>\n</button>\n\n<script>\n  // Scroll to top functionality\n  const scrollButton = document.getElementById('scroll-to-top');\n\n  window.addEventListener('scroll', () => {\n    if (window.scrollY > 300) {\n      scrollButton.classList.add('visible');\n    } else {\n      scrollButton.classList.remove('visible');\n    }\n  });\n\n  scrollButton.addEventListener('click', () => {\n    window.scrollTo({ top: 0, behavior: 'smooth' });\n  });\n\n  // Handle keyboard interaction\n  scrollButton.addEventListener('keydown', (e) => {\n    if (e.key === 'Enter' || e.key === ' ') {\n      e.preventDefault();\n      window.scrollTo({ top: 0, behavior: 'smooth' });\n    }\n  });\n</script>\n\n<!-- Lazy loading images with placeholder -->\n<script>\n  // Intersection Observer for lazy loading\n  if ('IntersectionObserver' in window) {\n    const imageObserver = new IntersectionObserver((entries, observer) => {\n      entries.forEach(entry => {\n        if (entry.isIntersecting) {\n          const img = entry.target;\n          img.src = img.dataset.src || img.src;\n          img.classList.remove('lazy');\n          observer.unobserve(img);\n        }\n      });\n    }, {\n      rootMargin: '50px 0px',\n      threshold: 0.01\n    });\n\n    document.querySelectorAll('img[data-src]').forEach(img => {\n      imageObserver.observe(img);\n    });\n  }\n</script>\n\n<!-- Smooth page transitions -->\n<script>\n  // Add page transition class on load\n  document.addEventListener('DOMContentLoaded', () => {\n    document.body.classList.add('page-transition');\n  });\n\n  // Handle link clicks for smooth transitions\n  document.addEventListener('click', (e) => {\n    const link = e.target.closest('a');\n    if (link && !link.target && link.hostname === window.location.hostname) {\n      // Internal link - add transition\n      e.preventDefault();\n      document.body.style.opacity = '0.8';\n      setTimeout(() => {\n        window.location.href = link.href;\n      }, 150);\n    }\n  });\n</script>\n\n\n    <!-- Cookie Consent Banner -->\n    <div\n  id=\"cookie-consent\"\n  class=\"cookie-consent-banner\"\n  role=\"alertdialog\"\n  aria-labelledby=\"cookie-title\"\n  aria-describedby=\"cookie-description\"\n  style=\"display: none\"\n>\n  <div class=\"cookie-consent-content\">\n    <div class=\"cookie-consent-text\">\n      <h3 id=\"cookie-title\" class=\"cookie-consent-title\">\n          Cookie Preferences\n      </h3>\n      <p id=\"cookie-description\" class=\"cookie-consent-message\">\n        We use cookies to improve your experience and analyze site performance. No personal data is collected.\n      </p>\n      <p class=\"cookie-consent-subtext\">\n        <a\n          href=\"/privacy/\"\n          target=\"_blank\"\n          rel=\"noopener\"\n          >Privacy Policy</a\n        >\n      </p>\n    </div>\n    <div class=\"cookie-consent-actions\">\n      <button\n        id=\"cookie-manage\"\n        class=\"cookie-btn cookie-btn-manage\"\n        aria-label=\"Manage cookie preferences\"\n      >\n        Manage Preferences\n      </button>\n      <button\n        id=\"cookie-reject\"\n        class=\"cookie-btn cookie-btn-reject\"\n        aria-label=\"Reject cookies\"\n      >\n        Reject\n      </button>\n      <button\n        id=\"cookie-accept\"\n        class=\"cookie-btn cookie-btn-accept\"\n        aria-label=\"Accept all cookies\"\n      >\n        Accept All\n      </button>\n    </div>\n  </div>\n</div>\n\n<!-- Cookie Settings Modal -->\n<div\n  id=\"cookie-modal\"\n  class=\"cookie-modal\"\n  style=\"display: none\"\n  role=\"dialog\"\n  aria-labelledby=\"modal-title\"\n  aria-hidden=\"true\"\n>\n  <div class=\"cookie-modal-overlay\"></div>\n  <div class=\"cookie-modal-content\">\n    <div class=\"cookie-modal-header\">\n      <h2 id=\"modal-title\" class=\"cookie-modal-title\">Cookie Preferences</h2>\n      <button\n        id=\"modal-close\"\n        class=\"cookie-modal-close\"\n        aria-label=\"Close modal\"\n      >\n        <i class=\"fas fa-times\"></i>\n      </button>\n    </div>\n\n    <div class=\"cookie-modal-body\">\n      <!-- Categories -->\n      <div class=\"cookie-categories\">\n        <!-- Essential -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-essential\"\n                class=\"cookie-checkbox\"\n                checked\n                disabled\n              />\n              <span class=\"cookie-category-title\"\n                >Essential</span\n              >\n            </label>\n            <span class=\"cookie-badge essential\">Essential</span>\n          </div>\n          <p class=\"cookie-category-desc\">Required for core site functionality. Always enabled.</p>\n        </div>\n\n        <!-- Analytics -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-analytics\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Analytics</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Help us understand how you use our site to improve it.</p>\n          <details class=\"cookie-details\">\n            <summary>All Cookies</summary>\n            <div class=\"cookie-list\">\n              <div class=\"cookie-item\">\n                <span class=\"cookie-item-name\">_ga, _ga_*</span>\n                <span class=\"cookie-item-expiration\">2 years</span>\n              </div>\n              <div class=\"cookie-item\">\n                <span class=\"cookie-item-name\">_gat</span>\n                <span class=\"cookie-item-expiration\">1 minute</span>\n              </div>\n            </div>\n          </details>\n        </div>\n\n        <!-- Performance -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-performance\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Performance</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Improve page speed and user experience.</p>\n        </div>\n\n        <!-- Marketing -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-marketing\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Marketing</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Allow us to show you relevant content and offers.</p>\n        </div>\n      </div>\n\n      <div class=\"cookie-modal-footer-info\">\n        <small class=\"cookie-updated\"\n          >Last updated: December 11, 2025</small\n        >\n      </div>\n    </div>\n\n    <div class=\"cookie-modal-footer\">\n      <button id=\"modal-reject\" class=\"cookie-btn cookie-btn-reject\">\n        Reject\n      </button>\n      <button id=\"modal-save\" class=\"cookie-btn cookie-btn-accept\">\n        Save Preferences\n      </button>\n    </div>\n  </div>\n</div>\n\n<style>\n  .cookie-consent-banner {\n    position: fixed;\n    bottom: 0;\n    left: 0;\n    right: 0;\n    background: var(--bg-secondary);\n    border-top: 1px solid var(--border);\n    border-left: 3px solid var(--accent-primary);\n    padding: 20px;\n    z-index: 1000;\n    box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.15);\n    animation: slideUp 0.3s ease-out;\n  }\n\n  @keyframes slideUp {\n    from {\n      transform: translateY(100%);\n      opacity: 0;\n    }\n    to {\n      transform: translateY(0);\n      opacity: 1;\n    }\n  }\n\n  .cookie-consent-content {\n    max-width: 1200px;\n    margin: 0 auto;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    gap: 24px;\n    flex-wrap: wrap;\n  }\n\n  .cookie-consent-text {\n    flex: 1;\n    min-width: 280px;\n  }\n\n  .cookie-consent-title {\n    margin: 0 0 8px 0;\n    font-size: 16px;\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-consent-message {\n    margin: 0 0 8px 0;\n    font-size: 14px;\n    color: var(--text-secondary);\n    line-height: 1.5;\n  }\n\n  .cookie-consent-subtext {\n    margin: 8px 0 0 0;\n    font-size: 12px;\n    color: var(--text-secondary);\n  }\n\n  .cookie-consent-subtext a {\n    color: var(--accent-primary);\n    text-decoration: none;\n    font-weight: 500;\n  }\n\n  .cookie-consent-subtext a:hover {\n    text-decoration: underline;\n  }\n\n  .cookie-consent-actions {\n    display: flex;\n    gap: 12px;\n    flex-shrink: 0;\n  }\n\n  .cookie-btn {\n    padding: 8px 16px;\n    border-radius: var(--radius);\n    border: 1px solid var(--border);\n    font-size: 13px;\n    font-weight: 500;\n    cursor: pointer;\n    transition: all 0.2s ease;\n    white-space: nowrap;\n  }\n\n  .cookie-btn-manage {\n    background: var(--bg-primary);\n    color: var(--accent-primary);\n    border-color: var(--accent-primary);\n    font-weight: 600;\n  }\n\n  .cookie-btn-manage:hover {\n    background: var(--bg);\n    opacity: 0.9;\n  }\n\n  .cookie-btn-reject {\n    background: var(--bg-primary);\n    color: var(--text);\n    border-color: var(--border);\n  }\n\n  .cookie-btn-reject:hover {\n    background: var(--bg);\n    border-color: var(--text-secondary);\n  }\n\n  .cookie-btn-accept {\n    background: var(--accent-primary);\n    color: #000000;\n    border-color: var(--accent-primary);\n    font-weight: 600;\n  }\n\n  .cookie-btn-accept:hover {\n    opacity: 0.9;\n    transform: translateY(-1px);\n    box-shadow: 0 2px 8px rgba(27, 217, 111, 0.2);\n  }\n\n  .cookie-btn:active {\n    transform: translateY(0);\n  }\n\n  @media (max-width: 768px) {\n    .cookie-consent-banner {\n      padding: 16px;\n    }\n\n    .cookie-consent-content {\n      flex-direction: column;\n      gap: 16px;\n    }\n\n    .cookie-consent-actions {\n      width: 100%;\n      flex-direction: column;\n    }\n\n    .cookie-btn {\n      width: 100%;\n      padding: 10px 16px;\n    }\n  }\n\n  /* Modal Styles */\n  .cookie-modal {\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    z-index: 2000;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    animation: fadeIn 0.3s ease-out;\n  }\n\n  @keyframes fadeIn {\n    from {\n      opacity: 0;\n    }\n    to {\n      opacity: 1;\n    }\n  }\n\n  .cookie-modal-overlay {\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0, 0, 0, 0.5);\n    cursor: pointer;\n  }\n\n  .cookie-modal-content {\n    position: relative;\n    background: var(--bg-secondary);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n    max-width: 600px;\n    width: 90%;\n    max-height: 90vh;\n    overflow: auto;\n    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n    animation: slideIn 0.3s ease-out;\n  }\n\n  @keyframes slideIn {\n    from {\n      transform: scale(0.95);\n      opacity: 0;\n    }\n    to {\n      transform: scale(1);\n      opacity: 1;\n    }\n  }\n\n  .cookie-modal-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    padding: 24px;\n    border-bottom: 1px solid var(--border);\n  }\n\n  .cookie-modal-title {\n    margin: 0;\n    font-size: 20px;\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-modal-close {\n    background: none;\n    border: none;\n    color: var(--text-secondary);\n    font-size: 20px;\n    cursor: pointer;\n    padding: 0;\n    width: 32px;\n    height: 32px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    border-radius: var(--radius);\n    transition: all 0.2s;\n  }\n\n  .cookie-modal-close:hover {\n    background: var(--border);\n    color: var(--text);\n  }\n\n  .cookie-modal-body {\n    padding: 24px;\n  }\n\n  .cookie-categories {\n    display: flex;\n    flex-direction: column;\n    gap: 24px;\n    margin-bottom: 24px;\n  }\n\n  .cookie-category {\n    padding: 16px;\n    background: var(--bg-primary);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n  }\n\n  .cookie-category-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    margin-bottom: 8px;\n  }\n\n  .cookie-checkbox-label {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    cursor: pointer;\n    flex: 1;\n  }\n\n  .cookie-checkbox {\n    width: 18px;\n    height: 18px;\n    cursor: pointer;\n    accent-color: var(--accent-primary);\n  }\n\n  .cookie-checkbox:disabled {\n    opacity: 0.5;\n    cursor: not-allowed;\n  }\n\n  .cookie-category-title {\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-badge {\n    display: inline-block;\n    padding: 4px 8px;\n    border-radius: 4px;\n    font-size: 11px;\n    font-weight: 600;\n    text-transform: uppercase;\n    background: var(--accent-primary);\n    color: #000000;\n  }\n\n  .cookie-category-desc {\n    margin: 8px 0 0 28px;\n    font-size: 13px;\n    color: var(--text-secondary);\n    line-height: 1.5;\n  }\n\n  .cookie-details {\n    margin: 12px 0 0 28px;\n    cursor: pointer;\n  }\n\n  .cookie-details summary {\n    font-size: 12px;\n    color: var(--accent-primary);\n    font-weight: 500;\n    text-decoration: underline;\n    padding: 4px 0;\n  }\n\n  .cookie-details summary:hover {\n    opacity: 0.8;\n  }\n\n  .cookie-list {\n    margin-top: 8px;\n    padding: 8px;\n    background: var(--bg);\n    border-radius: 4px;\n    border: 1px solid var(--border);\n  }\n\n  .cookie-item {\n    display: flex;\n    justify-content: space-between;\n    font-size: 12px;\n    padding: 6px 0;\n    color: var(--text-secondary);\n    border-bottom: 1px solid var(--border);\n  }\n\n  .cookie-item:last-child {\n    border-bottom: none;\n  }\n\n  .cookie-item-name {\n    font-family: monospace;\n    font-weight: 500;\n    color: var(--text);\n  }\n\n  .cookie-item-expiration {\n    font-size: 11px;\n  }\n\n  .cookie-modal-footer-info {\n    margin-bottom: 16px;\n    padding-top: 16px;\n    border-top: 1px solid var(--border);\n  }\n\n  .cookie-updated {\n    font-size: 12px;\n    color: var(--text-secondary);\n  }\n\n  .cookie-modal-footer {\n    display: flex;\n    gap: 12px;\n    padding: 16px 24px;\n    border-top: 1px solid var(--border);\n    background: var(--bg-primary);\n    justify-content: flex-end;\n  }\n\n  .cookie-modal-footer .cookie-btn {\n    flex: 1;\n  }\n\n  @media (max-width: 640px) {\n    .cookie-modal-content {\n      width: 95%;\n      max-height: 95vh;\n    }\n\n    .cookie-modal-header {\n      padding: 16px;\n    }\n\n    .cookie-modal-body {\n      padding: 16px;\n    }\n\n    .cookie-modal-footer {\n      flex-direction: column;\n      padding: 16px;\n    }\n\n    .cookie-modal-footer .cookie-btn {\n      width: 100%;\n    }\n\n    .cookie-category-desc {\n      margin-left: 28px;\n    }\n\n    .cookie-details {\n      margin-left: 28px;\n    }\n  }\n</style>\n\n<script>\n  document.addEventListener(\"DOMContentLoaded\", () => {\n    const banner = document.getElementById(\"cookie-consent\");\n    const modal = document.getElementById(\"cookie-modal\");\n    const acceptBtn = document.getElementById(\"cookie-accept\");\n    const rejectBtn = document.getElementById(\"cookie-reject\");\n    const manageBtn = document.getElementById(\"cookie-manage\");\n    const modalClose = document.getElementById(\"modal-close\");\n    const modalOverlay = document.querySelector(\".cookie-modal-overlay\");\n    const modalRejectBtn = document.getElementById(\"modal-reject\");\n    const modalSaveBtn = document.getElementById(\"modal-save\");\n    const consentKey = \"abc-cookie-consent\";\n    const categoriesKey = \"abc-cookie-categories\";\n\n    // Preference checkboxes\n    const analyticsCheckbox = document.getElementById(\"cookie-analytics\");\n    const performanceCheckbox = document.getElementById(\"cookie-performance\");\n    const marketingCheckbox = document.getElementById(\"cookie-marketing\");\n\n    // Load saved preferences\n    const loadPreferences = () => {\n      const saved = localStorage.getItem(categoriesKey);\n      if (saved) {\n        const prefs = JSON.parse(saved);\n        analyticsCheckbox.checked = prefs.analytics || false;\n        performanceCheckbox.checked = prefs.performance || false;\n        marketingCheckbox.checked = prefs.marketing || false;\n      }\n    };\n\n    // Save preferences\n    const savePreferences = () => {\n      const prefs = {\n        analytics: analyticsCheckbox.checked,\n        performance: performanceCheckbox.checked,\n        marketing: marketingCheckbox.checked,\n      };\n      localStorage.setItem(categoriesKey, JSON.stringify(prefs));\n      localStorage.setItem(consentKey, \"custom\");\n      dismissBanner();\n      updateConsent(prefs);\n    };\n\n    // Dismiss banner with animation\n    const dismissBanner = () => {\n      banner.style.animation = \"slideDown 0.3s ease-out forwards\";\n      setTimeout(() => {\n        banner.style.display = \"none\";\n      }, 300);\n      modal.style.animation = \"fadeOut 0.3s ease-out forwards\";\n      setTimeout(() => {\n        modal.style.display = \"none\";\n      }, 300);\n    };\n\n    // Update analytics consent\n    const updateConsent = (prefs) => {\n      if (window.gtag) {\n        gtag(\"consent\", \"update\", {\n          analytics_storage: prefs.analytics ? \"granted\" : \"denied\",\n        });\n      }\n    };\n\n    // Check if user has already made a choice\n    const userConsent = localStorage.getItem(consentKey);\n\n    if (!userConsent) {\n      setTimeout(() => {\n        banner.style.display = \"flex\";\n      }, 1000);\n    }\n\n    loadPreferences();\n\n    // Accept all cookies\n    acceptBtn.addEventListener(\"click\", () => {\n      analyticsCheckbox.checked = true;\n      performanceCheckbox.checked = true;\n      marketingCheckbox.checked = true;\n      savePreferences();\n    });\n\n    // Reject all cookies (keep only essential)\n    const rejectAllCookies = () => {\n      analyticsCheckbox.checked = false;\n      performanceCheckbox.checked = false;\n      marketingCheckbox.checked = false;\n      localStorage.setItem(\n        categoriesKey,\n        JSON.stringify({\n          analytics: false,\n          performance: false,\n          marketing: false,\n        })\n      );\n      localStorage.setItem(consentKey, \"rejected\");\n      dismissBanner();\n      updateConsent({ analytics: false, performance: false, marketing: false });\n    };\n\n    rejectBtn.addEventListener(\"click\", rejectAllCookies);\n    modalRejectBtn.addEventListener(\"click\", rejectAllCookies);\n\n    // Manage preferences\n    manageBtn.addEventListener(\"click\", () => {\n      modal.style.display = \"flex\";\n      loadPreferences();\n    });\n\n    // Modal controls\n    modalClose.addEventListener(\"click\", () => {\n      modal.style.animation = \"fadeOut 0.3s ease-out forwards\";\n      setTimeout(() => {\n        modal.style.display = \"none\";\n      }, 300);\n    });\n\n    modalOverlay.addEventListener(\"click\", () => {\n      modalClose.click();\n    });\n\n    // Save preferences from modal\n    modalSaveBtn.addEventListener(\"click\", savePreferences);\n\n    // ESC key to close modal\n    document.addEventListener(\"keydown\", (e) => {\n      if (e.key === \"Escape\" && modal.style.display === \"flex\") {\n        modalClose.click();\n      }\n    });\n\n    // Add fadeOut animation\n    const style = document.createElement(\"style\");\n    style.textContent = `\n      @keyframes slideDown {\n        to {\n          transform: translateY(100%);\n          opacity: 0;\n        }\n      }\n      @keyframes fadeOut {\n        to {\n          opacity: 0;\n        }\n      }\n    `;\n    document.head.appendChild(style);\n  });\n</script>\n\n\n    <!-- Scripts -->\n    <script src=\"/assets/js/search.js\"></script>\n    <script src=\"/assets/js/performance.js\"></script>\n    <script src=\"/assets/js/visual-enhancements.js\"></script>\n  </body>\n</html>\n"],"files":[],"output":true,"relative_directory":"_posts","directory":"/home/runner/work/abc-site/abc-site/_posts","permalink":"/:categories/:year/:month/:day/:title:output_ext"},{"label":"projects","docs":["<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n"],"files":[],"output":true,"relative_directory":"_projects","directory":"/home/runner/work/abc-site/abc-site/_projects","permalink":"/projects/:slug/"}],"documents":["\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <title>Welcome to the Blog</title>\n    <meta\n      name=\"description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta\n      name=\"robots\"\n      content=\"index, follow\"\n    />\n\n    <!-- SEO Meta Tags -->\n          \n\n    <meta\n      property=\"og:title\"\n      content=\"Welcome to the Blog\"\n    />\n    <meta\n      property=\"og:description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta property=\"og:url\" content=\"https://abc-site.devvyy.xyz/blog/blog-test/\" />\n    <meta property=\"og:image\" content=\"https://abc-site.devvyy.xyz/assets/images/logo.svg\" />\n    <meta property=\"og:image:alt\" content=\"ABC Mods & Packs\" />\n    <meta property=\"og:type\" content=\"post\" />\n    <meta property=\"og:site_name\" content=\"ABC\" />\n    <meta\n      property=\"og:locale\"\n      content=\"en_US\"\n    />\n\n    <!-- hreflang tags for multilingual SEO -->\n    <link\n      rel=\"alternate\"\n      hreflang=\"en\"\n      href=\"https://abc-site.devvyy.xyz/blog/blog-test/\"\n    />\n    <link\n      rel=\"alternate\"\n      hreflang=\"fr\"\n      href=\"https://abc-site.devvyy.xyz/fr/blog/blog-test/\"\n    />\n    <link\n      rel=\"alternate\"\n      hreflang=\"x-default\"\n      href=\"https://abc-site.devvyy.xyz/blog/blog-test/\"\n    />\n\n    <!-- Twitter Card -->\n    <meta name=\"twitter:card\" content=\"summary_large_image\" />\n    <meta\n      name=\"twitter:title\"\n      content=\"Welcome to the Blog\"\n    />\n    <meta\n      name=\"twitter:description\"\n      content=\"Kicking off our new blog — what's coming next.\"\n    />\n    <meta\n      name=\"twitter:image\"\n      content=\"https://abc-site.devvyy.xyz/assets/images/logo.svg\"\n    />\n    <meta name=\"twitter:image:alt\" content=\"ABC Mods & Packs\" />\n    <meta\n      name=\"twitter:creator\"\n      content=\"@devvyyxyz\"\n    />\n    <meta\n      name=\"twitter:site\"\n      content=\"@devvyyxyz\"\n    />\n\n    <meta\n      name=\"theme-color\"\n      content=\"#1bd96f\"\n    />\n\n    <!-- Favicon -->\n    <link\n      rel=\"icon\"\n      type=\"image/svg+xml\"\n      href=\"/favicon.svg\"\n    />\n    <link\n      rel=\"icon\"\n      type=\"image/x-icon\"\n      href=\"/favicon.svg\"\n    />\n    <link\n      rel=\"apple-touch-icon\"\n      href=\"/assets/images/logo.svg\"\n    />\n\n    <!-- Google Fonts - Preload -->\n    <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n    <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n    <link\n      rel=\"preload\"\n      as=\"style\"\n      href=\"https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap\"\n    />\n    <link\n      href=\"https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap\"\n      rel=\"stylesheet\"\n    />\n\n    <!-- Font Awesome Icons - Async load -->\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <noscript>\n      <link\n        rel=\"stylesheet\"\n        href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n      />\n    </noscript>\n\n    <!-- Stylesheets - Critical -->\n    <link rel=\"stylesheet\" href=\"/assets/css/root.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/layout.css\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/loading.css\"\n    />\n\n    <!-- Stylesheets - Deferred (non-critical) -->\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/components.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/modpacks.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/animations.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/theme.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/a11y.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/visual-enhancements.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/mobile.css\"\n      media=\"print\"\n      onload=\"this.media='all'\"\n    />\n    <noscript>\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/components.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/modpacks.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/animations.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/theme.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/a11y.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/visual-enhancements.css\"\n      />\n      <link\n        rel=\"stylesheet\"\n        href=\"/assets/css/mobile.css\"\n      />\n    </noscript>\n\n    <!-- Canonical URL -->\n    <link rel=\"canonical\" href=\"https://abc-site.devvyy.xyz/blog/blog-test/\" />\n\n    <!-- Schema Markup -->\n    <!-- Schema.org JSON-LD -->\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"Organization\",\n    \"name\": \"ABC\",\n    \"description\": \"Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins.\",\n    \"url\": \"https://abc-site.devvyy.xyz\",\n    \"logo\": \"https://abc-site.devvyy.xyz/assets/images/logo.svg\",\n    \"sameAs\": [\n      \"https://github.com/devvyyxyz\",\n      \"https://twitter.com/devvyyxyz\",\n      \"https://dc.gg/devvyyxyz\"\n    ],\n    \"contactPoint\": {\n      \"@type\": \"ContactPoint\",\n      \"contactType\": \"Community Support\",\n      \"url\": \"https://dc.gg/devvyyxyz\"\n    }\n  }\n</script>\n\n<!-- Breadcrumb Schema -->\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"BreadcrumbList\",\n    \"itemListElement\": [\n      {\n        \"@type\": \"ListItem\",\n        \"position\": 1,\n        \"name\": \"Home\",\n        \"item\": \"https://abc-site.devvyy.xyz\"\n      }\n      \n      , {\n        \"@type\": \"ListItem\",\n        \"position\": 2,\n        \"name\": \"Welcome to the Blog\",\n        \"item\": \"https://abc-site.devvyy.xyz/blog/blog-test/\"\n      }\n      \n    ]\n  }\n</script>\n\n<!-- Project/Software Application Schema (for project pages) -->\n\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"Article\",\n    \"headline\": \"Welcome to the Blog\",\n    \"description\": \"Kicking off our new blog — what's coming next.\",\n    \"image\": \"\",\n    \"datePublished\": \"2025-12-16T00:00:00+00:00\",\n    \"dateModified\": \"2025-12-16T00:00:00+00:00\",\n    \"author\": {\n      \"@type\": \"Organization\",\n      \"name\": \"ABC\"\n    },\n    \"publisher\": {\n      \"@type\": \"Organization\",\n      \"name\": \"ABC\",\n      \"logo\": {\n        \"@type\": \"ImageObject\",\n        \"url\": \"https://abc-site.devvyy.xyz/assets/images/logo.svg\"\n      }\n    }\n  }\n</script>\n<!-- WebPage Schema -->\n\n\n\n    <!-- Preloader Script (critical, inline) -->\n    <script>\n      (function () {\n        if (!document.body) return; // Exit if body not ready yet\n\n        const isDarkMode =\n          window.matchMedia &&\n          window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n        const bgColor = isDarkMode ? \"#0d0d0d\" : \"#f6fbfa\";\n        document.documentElement.style.backgroundColor = bgColor;\n        document.body.style.backgroundColor = bgColor;\n\n        const overlay = document.createElement(\"div\");\n        overlay.className = \"loading-overlay\";\n        overlay.id = \"loading-overlay\";\n        overlay.innerHTML = '<div class=\"spinner\"></div>';\n        document.body.appendChild(overlay);\n\n        if (document.readyState === \"loading\") {\n          document.addEventListener(\"DOMContentLoaded\", hidePreloader);\n        } else {\n          hidePreloader();\n        }\n\n        function hidePreloader() {\n          const preloader = document.getElementById(\"loading-overlay\");\n          if (preloader) {\n            preloader.classList.add(\"hidden\");\n          }\n        }\n\n        window.hidePreloader = hidePreloader;\n      })();\n    </script>\n  </head>\n  <body>\n    <a href=\"#main\" class=\"skip-to-main\">Skip to main content</a>\n    <header class=\"floating-nav\">\n  <div class=\"nav-inner\">\n    <a\n      class=\"logo\"\n      href=\"/\"\n      style=\"display: flex; align-items: center; gap: 8px\"\n      aria-label=\"ABC\"\n    >\n      <img\n        src=\"/assets/images/logo.svg\"\n        alt=\"ABC\"\n        style=\"height: 32px; width: auto\"\n      />\n      \n    </a>\n    <button\n      class=\"mobile-menu-toggle\"\n      aria-label=\"Toggle menu\"\n      id=\"mobile-menu-toggle\"\n    >\n      <i class=\"fas fa-bars\"></i>\n    </button>\n    <nav class=\"links\" id=\"mobile-nav\">\n      <a href=\"/\">Home</a>\n      <a href=\"/about/\">About</a>\n      <a href=\"/docs/\">Docs</a>\n      <a href=\"/changelog/\">Changelog</a>\n      <a href=\"/blog/\">Blog</a>\n      <div class=\"nav-dropdown\">\n        <a href=\"/projects/\" class=\"dropdown-toggle\">\n          Projects <i class=\"fas fa-chevron-down\"></i>\n        </a>\n        <div class=\"dropdown-menu\">\n          <a href=\"/projects/\">All Projects</a>\n          <a href=\"/compare/\"\n            ><i class=\"fas fa-balance-scale\"></i> Compare Modpacks</a\n          >\n          <a href=\"/changelog/\"\n            ><i class=\"fas fa-rocket\"></i> Releases & Changelog</a\n          >\n        </div>\n      </div>\n      <div class=\"nav-dropdown\">\n        <a href=\"#\" class=\"dropdown-toggle\">\n          Legal <i class=\"fas fa-chevron-down\"></i>\n        </a>\n        <div class=\"dropdown-menu\">\n          <a href=\"/privacy/\">Privacy Policy</a>\n          <a href=\"/terms/\">Terms of Service</a>\n          <a href=\"/cookie-policy/\">Cookie Policy</a>\n          <a href=\"/licensing/\">Licensing</a>\n          <a href=\"/eula/\">EULA</a>\n          <a href=\"/disclaimer/\">Disclaimer</a>\n        </div>\n      </div>\n      <a\n        href=\"https://modrinth.com/organization/abcxyz\"\n        target=\"_blank\"\n        rel=\"noopener\"\n        >Organization</a\n      >\n    </nav>\n    <div class=\"nav-actions\">\n      <div\n        id=\"social-links-nav\"\n        style=\"display: flex; gap: 6px; align-items: center\"\n      ></div>\n      <!-- Theme Toggle -->\n<div class=\"theme-toggle\" id=\"theme-toggle\" title=\"Toggle dark/light mode\">\n  <button id=\"theme-dark\" class=\"active\" aria-label=\"Dark mode\" title=\"Dark mode\">\n    <i class=\"fa-solid fa-moon\"></i>\n  </button>\n  <button id=\"theme-light\" aria-label=\"Light mode\" title=\"Light mode\">\n    <i class=\"fa-solid fa-sun\"></i>\n  </button>\n</div>\n\n<script>\n  // Theme toggle functionality\n  const themeToggle = {\n    init() {\n      this.darkBtn = document.getElementById('theme-dark');\n      this.lightBtn = document.getElementById('theme-light');\n      this.html = document.documentElement;\n\n      // Load saved theme or use system preference\n      const saved = localStorage.getItem('theme');\n      const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;\n      const theme = saved || (systemDark ? 'dark' : 'light');\n\n      this.setTheme(theme);\n\n      // Listen for changes\n      this.darkBtn.addEventListener('click', () => this.setTheme('dark'));\n      this.lightBtn.addEventListener('click', () => this.setTheme('light'));\n\n      // Listen for system theme changes\n      window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {\n        if (!localStorage.getItem('theme')) {\n          this.setTheme(e.matches ? 'dark' : 'light');\n        }\n      });\n    },\n\n    setTheme(theme) {\n      this.html.setAttribute('data-theme', theme);\n      localStorage.setItem('theme', theme);\n\n      this.darkBtn.classList.toggle('active', theme === 'dark');\n      this.lightBtn.classList.toggle('active', theme === 'light');\n\n      // Update meta theme-color\n      const color = theme === 'dark' ? '#1bd96f' : '#1bd96f';\n      document.querySelector('meta[name=\"theme-color\"]').setAttribute('content', color);\n    }\n  };\n\n  if (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', () => themeToggle.init());\n  } else {\n    themeToggle.init();\n  }\n</script>\n\n    </div>\n  </div>\n</header>\n\n<script>\n  // Mobile menu toggle\n  document.addEventListener(\"DOMContentLoaded\", () => {\n    const toggle = document.getElementById(\"mobile-menu-toggle\");\n    const nav = document.getElementById(\"mobile-nav\");\n\n    if (toggle && nav) {\n      toggle.addEventListener(\"click\", () => {\n        nav.classList.toggle(\"mobile-open\");\n        const icon = toggle.querySelector(\"i\");\n        if (nav.classList.contains(\"mobile-open\")) {\n          icon.classList.remove(\"fa-bars\");\n          icon.classList.add(\"fa-times\");\n        } else {\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        }\n      });\n\n      // Close menu when clicking a link\n      nav.querySelectorAll(\"a\").forEach((link) => {\n        link.addEventListener(\"click\", () => {\n          nav.classList.remove(\"mobile-open\");\n          const icon = toggle.querySelector(\"i\");\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        });\n      });\n\n      // Close menu when clicking outside\n      document.addEventListener(\"click\", (e) => {\n        if (!toggle.contains(e.target) && !nav.contains(e.target)) {\n          nav.classList.remove(\"mobile-open\");\n          const icon = toggle.querySelector(\"i\");\n          icon.classList.remove(\"fa-times\");\n          icon.classList.add(\"fa-bars\");\n        }\n      });\n    }\n  });\n</script>\n\n\n    <main id=\"main\" class=\"container\"><main class=\"content\">\n  <article class=\"post\" style=\"max-width: 820px; margin: 0 auto; padding: 24px\">\n    <header>\n      <h1 style=\"margin: 0 0 8px\">Welcome to the Blog</h1>\n      <p class=\"muted\" style=\"margin: 0 0 16px\">\n        December 16, 2025 • ABC Team\n      </p>\n    </header>\n    <section class=\"post-body\"><p>We’re launching a blog to share updates, release notes, and behind-the-scenes dev logs.</p>\n\n<!--more-->\n\n<p>What you can expect:</p>\n\n<ul>\n  <li>Deep dives into mods, datapacks, and plugins</li>\n  <li>Roadmap updates and upcoming releases</li>\n  <li>Performance tips and compatibility notes</li>\n  <li>Community showcases and contributions</li>\n</ul>\n\n<p>If you have topics you’d like us to cover, let us know on the contact page or Discord.</p>\n</section>\n\n    \n    <footer style=\"margin-top: 24px\">\n      <strong>Tags:</strong>\n      \n      <span\n        style=\"\n          display: inline-block;\n          padding: 4px 8px;\n          border: 1px solid var(--border);\n          border-radius: 999px;\n          margin-right: 6px;\n          font-size: 12px;\n        \"\n        >#announcement</span\n      >\n      \n      <span\n        style=\"\n          display: inline-block;\n          padding: 4px 8px;\n          border: 1px solid var(--border);\n          border-radius: 999px;\n          margin-right: 6px;\n          font-size: 12px;\n        \"\n        >#roadmap</span\n      >\n       \n      <div style=\"margin-top: 8px\">\n        <strong>Categories:</strong>\n        \n        <span\n          style=\"\n            display: inline-block;\n            padding: 4px 8px;\n            border: 1px solid var(--border);\n            border-radius: 999px;\n            margin-right: 6px;\n            font-size: 12px;\n          \"\n          >updates</span\n        >\n        \n      </div>\n      \n    </footer>\n    \n  </article>\n</main>\n</main>\n\n    <footer class=\"floating-footer\">\n  <div class=\"footer-inner\">\n    <div style=\"display: flex; gap: 16px; align-items: flex-start\">\n      <img\n        src=\"/assets/images/logo.svg\"\n        alt=\"ABC logo\"\n        style=\"height: 100px; flex-shrink: 0; width: auto\"\n        width=\"100\"\n        height=\"100\"\n      />\n      <div style=\"display: flex; flex-direction: column; gap: 8px\">\n        <div>\n          <h4\n            style=\"\n              margin: 0;\n              font-size: 18px;\n              font-weight: 700;\n              color: var(--text);\n            \"\n          >\n            ABC\n          </h4>\n          <p\n            style=\"\n              margin: 2px 0 0 0;\n              font-size: 12px;\n              color: var(--text-secondary);\n            \"\n          >\n            Established 2025\n          </p>\n        </div>\n        <p\n          style=\"\n            margin: 0;\n            font-size: 13px;\n            color: var(--text-secondary);\n            line-height: 1.6;\n          \"\n        >\n          Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins.\n        </p>\n      </div>\n    </div>\n    <div style=\"display: flex; gap: 48px\">\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Links\n        </h4>\n        <div\n          style=\"\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n            gap: 10px 12px;\n            font-size: 13px;\n            max-width: 320px;\n          \"\n        >\n          <a\n            href=\"/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Home</a\n          >\n          <a\n            href=\"/about/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >About</a\n          >\n          <a\n            href=\"/docs/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Docs</a\n          >\n          <a\n            href=\"/projects/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Projects</a\n          >\n          <a\n            href=\"/compare/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Compare</a\n          >\n          <a\n            href=\"/changelog/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Changelog</a\n          >\n          <a\n            href=\"https://modrinth.com/organization/abcxyz\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            target=\"_blank\"\n            rel=\"noopener\"\n            >Modrinth Org</a\n          >\n          <a\n            href=\"https://github.com/devvyyxyz\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            target=\"_blank\"\n            rel=\"noopener\"\n            >GitHub Org</a\n          >\n          <a\n            href=\"/sitemap.xml\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Sitemap</a\n          >\n          <a\n            href=\"/feed.xml\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >RSS Feed</a\n          >\n          <a\n            href=\"/blog/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Blog</a\n          >\n        </div>\n      </div>\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Help\n        </h4>\n        <div\n          style=\"\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n            gap: 10px 12px;\n            font-size: 13px;\n            max-width: 320px;\n          \"\n        >\n          <a\n            href=\"/contact/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Contact</a\n          >\n          <a\n            href=\"/docs/faq/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >FAQ</a\n          >\n          <a\n            href=\"/docs/troubleshooting/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Troubleshooting</a\n          >\n          <a\n            href=\"/docs/contributing/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Contributing</a\n          >\n          <a\n            href=\"/status/\"\n            style=\"\n              color: var(--text-secondary);\n              text-decoration: none;\n              transition: color 0.2s;\n            \"\n            >Status</a\n          >\n        </div>\n      </div>\n      <div>\n        <h4\n          style=\"\n            margin: 0 0 16px;\n            font-size: 11px;\n            font-weight: 700;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n            color: var(--text);\n          \"\n        >\n          Community\n        </h4>\n        <div\n          id=\"social-links-footer\"\n          style=\"display: flex; gap: 12px; flex-direction: column\"\n        ></div>\n      </div>\n    </div>\n  </div>\n  <div\n    style=\"\n      border-top: 1px solid var(--border);\n      margin-top: 32px;\n      padding-top: 24px;\n      display: flex;\n      justify-content: space-between;\n      align-items: center;\n      font-size: 12px;\n      color: var(--text-secondary);\n      flex-wrap: wrap;\n      gap: 16px;\n    \"\n  >\n    <div style=\"display: flex; gap: 16px; align-items: center; flex-wrap: wrap\">\n      <div>\n        © <span id=\"year\"></span> ABC. All rights reserved.\n      </div>\n      <div\n        id=\"language-switcher\"\n        style=\"display: flex; gap: 8px; align-items: center\"\n      >\n        <span style=\"font-size: 12px; color: var(--text-secondary)\"\n          >Language:</span\n        >\n        <select\n          id=\"lang-select\"\n          style=\"\n            padding: 4px 8px;\n            border: 1px solid var(--border);\n            border-radius: var(--radius);\n            background: var(--bg-secondary);\n            color: var(--text);\n            font-size: 12px;\n            cursor: pointer;\n          \"\n        >\n          <option value=\"en\">English</option>\n          <option value=\"fr\">Français</option>\n        </select>\n      </div>\n    </div>\n    <div style=\"display: flex; gap: 20px\">\n      <a\n        href=\"/privacy/\"\n        style=\"\n          color: var(--text-secondary);\n          text-decoration: none;\n          transition: color 0.2s;\n        \"\n        >Privacy</a\n      >\n      <a\n        href=\"/terms/\"\n        style=\"\n          color: var(--text-secondary);\n          text-decoration: none;\n          transition: color 0.2s;\n        \"\n        >Terms</a\n      >\n    </div>\n  </div>\n</footer>\n\n<script>\n  // Social links configuration\n  const socials = {\n    github: {\n      name: \"GitHub\",\n      icon: \"fab fa-github\",\n      url: \"https://github.com/devvyyxyz\",\n    },\n    twitter: {\n      name: \"Twitter\",\n      icon: \"fab fa-x-twitter\",\n      url: \"https://twitter.com/devvyyxyz\",\n    },\n    discord: {\n      name: \"Discord\",\n      icon: \"fab fa-discord\",\n      url: \"https://dc.gg/devvyyxyz\",\n    },\n  };\n\n  function renderSocialLinks() {\n    const navContainer = document.getElementById(\"social-links-nav\");\n    const footerContainer = document.getElementById(\"social-links-footer\");\n\n    Object.entries(socials).forEach(([key, social]) => {\n      if (social.url && social.url.trim()) {\n        // Nav icon button\n        const navLink = document.createElement(\"a\");\n        navLink.href = social.url;\n        navLink.target = \"_blank\";\n        navLink.rel = \"noopener\";\n        navLink.title = social.name;\n        navLink.style.cssText =\n          \"display:flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:var(--radius);background:var(--bg-secondary);color:var(--text-secondary);text-decoration:none;font-size:16px;transition:all 0.2s ease;border:1px solid var(--border)\";\n        const icon = document.createElement(\"i\");\n        icon.className = social.icon;\n        icon.style.fontSize = \"18px\";\n        navLink.appendChild(icon);\n        navLink.onmouseover = () => {\n          navLink.style.background = \"var(--accent-primary)\";\n          navLink.style.color = \"#000000\";\n          navLink.style.borderColor = \"var(--accent-primary)\";\n        };\n        navLink.onmouseout = () => {\n          navLink.style.background = \"var(--bg-secondary)\";\n          navLink.style.color = \"var(--text-secondary)\";\n          navLink.style.borderColor = \"var(--border)\";\n        };\n        if (navContainer) navContainer.appendChild(navLink);\n\n        // Footer text link with icon\n        const footerLink = document.createElement(\"a\");\n        footerLink.href = social.url;\n        footerLink.target = \"_blank\";\n        footerLink.rel = \"noopener\";\n        footerLink.style.cssText =\n          \"display:flex;align-items:center;gap:8px;color:var(--text-secondary);text-decoration:none;transition:color 0.2s;font-size:13px\";\n        const footerIcon = document.createElement(\"i\");\n        footerIcon.className = social.icon;\n        footerIcon.style.width = \"16px\";\n        const footerText = document.createElement(\"span\");\n        footerText.textContent = social.name;\n        footerLink.appendChild(footerIcon);\n        footerLink.appendChild(footerText);\n        footerLink.onmouseover = () => {\n          footerLink.style.color = \"var(--accent-primary)\";\n        };\n        footerLink.onmouseout = () => {\n          footerLink.style.color = \"var(--text-secondary)\";\n        };\n        if (footerContainer) footerContainer.appendChild(footerLink);\n      }\n    });\n  }\n\n  document.addEventListener(\"DOMContentLoaded\", renderSocialLinks);\n\n  // Set year in footer\n  document.getElementById(\"year\").textContent = new Date().getFullYear();\n\n  // Language switcher\n  const langSelect = document.getElementById(\"lang-select\");\n  if (langSelect) {\n    const currentLang = 'en';\n    langSelect.value = currentLang;\n\n    langSelect.addEventListener(\"change\", (e) => {\n      const selectedLang = e.target.value;\n      const currentPath = window.location.pathname;\n      const baseUrl = \"\";\n\n      // Remove existing language prefix\n      let cleanPath = currentPath.replace(baseUrl, \"\");\n      cleanPath = cleanPath.replace(/^\\/(en|fr)/, \"\");\n\n      // Build new URL\n      const newPath =\n        selectedLang === \"en\"\n          ? baseUrl + cleanPath\n          : baseUrl + \"/\" + selectedLang + cleanPath;\n\n      window.location.href = newPath;\n    });\n  }\n</script>\n <!-- Scroll to top button -->\n<button id=\"scroll-to-top\" class=\"scroll-to-top\" aria-label=\"Scroll to top\" title=\"Back to top\">\n  <i class=\"fa-solid fa-chevron-up\"></i>\n</button>\n\n<script>\n  // Scroll to top functionality\n  const scrollButton = document.getElementById('scroll-to-top');\n\n  window.addEventListener('scroll', () => {\n    if (window.scrollY > 300) {\n      scrollButton.classList.add('visible');\n    } else {\n      scrollButton.classList.remove('visible');\n    }\n  });\n\n  scrollButton.addEventListener('click', () => {\n    window.scrollTo({ top: 0, behavior: 'smooth' });\n  });\n\n  // Handle keyboard interaction\n  scrollButton.addEventListener('keydown', (e) => {\n    if (e.key === 'Enter' || e.key === ' ') {\n      e.preventDefault();\n      window.scrollTo({ top: 0, behavior: 'smooth' });\n    }\n  });\n</script>\n\n<!-- Lazy loading images with placeholder -->\n<script>\n  // Intersection Observer for lazy loading\n  if ('IntersectionObserver' in window) {\n    const imageObserver = new IntersectionObserver((entries, observer) => {\n      entries.forEach(entry => {\n        if (entry.isIntersecting) {\n          const img = entry.target;\n          img.src = img.dataset.src || img.src;\n          img.classList.remove('lazy');\n          observer.unobserve(img);\n        }\n      });\n    }, {\n      rootMargin: '50px 0px',\n      threshold: 0.01\n    });\n\n    document.querySelectorAll('img[data-src]').forEach(img => {\n      imageObserver.observe(img);\n    });\n  }\n</script>\n\n<!-- Smooth page transitions -->\n<script>\n  // Add page transition class on load\n  document.addEventListener('DOMContentLoaded', () => {\n    document.body.classList.add('page-transition');\n  });\n\n  // Handle link clicks for smooth transitions\n  document.addEventListener('click', (e) => {\n    const link = e.target.closest('a');\n    if (link && !link.target && link.hostname === window.location.hostname) {\n      // Internal link - add transition\n      e.preventDefault();\n      document.body.style.opacity = '0.8';\n      setTimeout(() => {\n        window.location.href = link.href;\n      }, 150);\n    }\n  });\n</script>\n\n\n    <!-- Cookie Consent Banner -->\n    <div\n  id=\"cookie-consent\"\n  class=\"cookie-consent-banner\"\n  role=\"alertdialog\"\n  aria-labelledby=\"cookie-title\"\n  aria-describedby=\"cookie-description\"\n  style=\"display: none\"\n>\n  <div class=\"cookie-consent-content\">\n    <div class=\"cookie-consent-text\">\n      <h3 id=\"cookie-title\" class=\"cookie-consent-title\">\n          Cookie Preferences\n      </h3>\n      <p id=\"cookie-description\" class=\"cookie-consent-message\">\n        We use cookies to improve your experience and analyze site performance. No personal data is collected.\n      </p>\n      <p class=\"cookie-consent-subtext\">\n        <a\n          href=\"/privacy/\"\n          target=\"_blank\"\n          rel=\"noopener\"\n          >Privacy Policy</a\n        >\n      </p>\n    </div>\n    <div class=\"cookie-consent-actions\">\n      <button\n        id=\"cookie-manage\"\n        class=\"cookie-btn cookie-btn-manage\"\n        aria-label=\"Manage cookie preferences\"\n      >\n        Manage Preferences\n      </button>\n      <button\n        id=\"cookie-reject\"\n        class=\"cookie-btn cookie-btn-reject\"\n        aria-label=\"Reject cookies\"\n      >\n        Reject\n      </button>\n      <button\n        id=\"cookie-accept\"\n        class=\"cookie-btn cookie-btn-accept\"\n        aria-label=\"Accept all cookies\"\n      >\n        Accept All\n      </button>\n    </div>\n  </div>\n</div>\n\n<!-- Cookie Settings Modal -->\n<div\n  id=\"cookie-modal\"\n  class=\"cookie-modal\"\n  style=\"display: none\"\n  role=\"dialog\"\n  aria-labelledby=\"modal-title\"\n  aria-hidden=\"true\"\n>\n  <div class=\"cookie-modal-overlay\"></div>\n  <div class=\"cookie-modal-content\">\n    <div class=\"cookie-modal-header\">\n      <h2 id=\"modal-title\" class=\"cookie-modal-title\">Cookie Preferences</h2>\n      <button\n        id=\"modal-close\"\n        class=\"cookie-modal-close\"\n        aria-label=\"Close modal\"\n      >\n        <i class=\"fas fa-times\"></i>\n      </button>\n    </div>\n\n    <div class=\"cookie-modal-body\">\n      <!-- Categories -->\n      <div class=\"cookie-categories\">\n        <!-- Essential -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-essential\"\n                class=\"cookie-checkbox\"\n                checked\n                disabled\n              />\n              <span class=\"cookie-category-title\"\n                >Essential</span\n              >\n            </label>\n            <span class=\"cookie-badge essential\">Essential</span>\n          </div>\n          <p class=\"cookie-category-desc\">Required for core site functionality. Always enabled.</p>\n        </div>\n\n        <!-- Analytics -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-analytics\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Analytics</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Help us understand how you use our site to improve it.</p>\n          <details class=\"cookie-details\">\n            <summary>All Cookies</summary>\n            <div class=\"cookie-list\">\n              <div class=\"cookie-item\">\n                <span class=\"cookie-item-name\">_ga, _ga_*</span>\n                <span class=\"cookie-item-expiration\">2 years</span>\n              </div>\n              <div class=\"cookie-item\">\n                <span class=\"cookie-item-name\">_gat</span>\n                <span class=\"cookie-item-expiration\">1 minute</span>\n              </div>\n            </div>\n          </details>\n        </div>\n\n        <!-- Performance -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-performance\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Performance</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Improve page speed and user experience.</p>\n        </div>\n\n        <!-- Marketing -->\n        <div class=\"cookie-category\">\n          <div class=\"cookie-category-header\">\n            <label class=\"cookie-checkbox-label\">\n              <input\n                type=\"checkbox\"\n                id=\"cookie-marketing\"\n                class=\"cookie-checkbox\"\n              />\n              <span class=\"cookie-category-title\"\n                >Marketing</span\n              >\n            </label>\n          </div>\n          <p class=\"cookie-category-desc\">Allow us to show you relevant content and offers.</p>\n        </div>\n      </div>\n\n      <div class=\"cookie-modal-footer-info\">\n        <small class=\"cookie-updated\"\n          >Last updated: December 11, 2025</small\n        >\n      </div>\n    </div>\n\n    <div class=\"cookie-modal-footer\">\n      <button id=\"modal-reject\" class=\"cookie-btn cookie-btn-reject\">\n        Reject\n      </button>\n      <button id=\"modal-save\" class=\"cookie-btn cookie-btn-accept\">\n        Save Preferences\n      </button>\n    </div>\n  </div>\n</div>\n\n<style>\n  .cookie-consent-banner {\n    position: fixed;\n    bottom: 0;\n    left: 0;\n    right: 0;\n    background: var(--bg-secondary);\n    border-top: 1px solid var(--border);\n    border-left: 3px solid var(--accent-primary);\n    padding: 20px;\n    z-index: 1000;\n    box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.15);\n    animation: slideUp 0.3s ease-out;\n  }\n\n  @keyframes slideUp {\n    from {\n      transform: translateY(100%);\n      opacity: 0;\n    }\n    to {\n      transform: translateY(0);\n      opacity: 1;\n    }\n  }\n\n  .cookie-consent-content {\n    max-width: 1200px;\n    margin: 0 auto;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    gap: 24px;\n    flex-wrap: wrap;\n  }\n\n  .cookie-consent-text {\n    flex: 1;\n    min-width: 280px;\n  }\n\n  .cookie-consent-title {\n    margin: 0 0 8px 0;\n    font-size: 16px;\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-consent-message {\n    margin: 0 0 8px 0;\n    font-size: 14px;\n    color: var(--text-secondary);\n    line-height: 1.5;\n  }\n\n  .cookie-consent-subtext {\n    margin: 8px 0 0 0;\n    font-size: 12px;\n    color: var(--text-secondary);\n  }\n\n  .cookie-consent-subtext a {\n    color: var(--accent-primary);\n    text-decoration: none;\n    font-weight: 500;\n  }\n\n  .cookie-consent-subtext a:hover {\n    text-decoration: underline;\n  }\n\n  .cookie-consent-actions {\n    display: flex;\n    gap: 12px;\n    flex-shrink: 0;\n  }\n\n  .cookie-btn {\n    padding: 8px 16px;\n    border-radius: var(--radius);\n    border: 1px solid var(--border);\n    font-size: 13px;\n    font-weight: 500;\n    cursor: pointer;\n    transition: all 0.2s ease;\n    white-space: nowrap;\n  }\n\n  .cookie-btn-manage {\n    background: var(--bg-primary);\n    color: var(--accent-primary);\n    border-color: var(--accent-primary);\n    font-weight: 600;\n  }\n\n  .cookie-btn-manage:hover {\n    background: var(--bg);\n    opacity: 0.9;\n  }\n\n  .cookie-btn-reject {\n    background: var(--bg-primary);\n    color: var(--text);\n    border-color: var(--border);\n  }\n\n  .cookie-btn-reject:hover {\n    background: var(--bg);\n    border-color: var(--text-secondary);\n  }\n\n  .cookie-btn-accept {\n    background: var(--accent-primary);\n    color: #000000;\n    border-color: var(--accent-primary);\n    font-weight: 600;\n  }\n\n  .cookie-btn-accept:hover {\n    opacity: 0.9;\n    transform: translateY(-1px);\n    box-shadow: 0 2px 8px rgba(27, 217, 111, 0.2);\n  }\n\n  .cookie-btn:active {\n    transform: translateY(0);\n  }\n\n  @media (max-width: 768px) {\n    .cookie-consent-banner {\n      padding: 16px;\n    }\n\n    .cookie-consent-content {\n      flex-direction: column;\n      gap: 16px;\n    }\n\n    .cookie-consent-actions {\n      width: 100%;\n      flex-direction: column;\n    }\n\n    .cookie-btn {\n      width: 100%;\n      padding: 10px 16px;\n    }\n  }\n\n  /* Modal Styles */\n  .cookie-modal {\n    position: fixed;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    z-index: 2000;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    animation: fadeIn 0.3s ease-out;\n  }\n\n  @keyframes fadeIn {\n    from {\n      opacity: 0;\n    }\n    to {\n      opacity: 1;\n    }\n  }\n\n  .cookie-modal-overlay {\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    background: rgba(0, 0, 0, 0.5);\n    cursor: pointer;\n  }\n\n  .cookie-modal-content {\n    position: relative;\n    background: var(--bg-secondary);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n    max-width: 600px;\n    width: 90%;\n    max-height: 90vh;\n    overflow: auto;\n    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n    animation: slideIn 0.3s ease-out;\n  }\n\n  @keyframes slideIn {\n    from {\n      transform: scale(0.95);\n      opacity: 0;\n    }\n    to {\n      transform: scale(1);\n      opacity: 1;\n    }\n  }\n\n  .cookie-modal-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    padding: 24px;\n    border-bottom: 1px solid var(--border);\n  }\n\n  .cookie-modal-title {\n    margin: 0;\n    font-size: 20px;\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-modal-close {\n    background: none;\n    border: none;\n    color: var(--text-secondary);\n    font-size: 20px;\n    cursor: pointer;\n    padding: 0;\n    width: 32px;\n    height: 32px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    border-radius: var(--radius);\n    transition: all 0.2s;\n  }\n\n  .cookie-modal-close:hover {\n    background: var(--border);\n    color: var(--text);\n  }\n\n  .cookie-modal-body {\n    padding: 24px;\n  }\n\n  .cookie-categories {\n    display: flex;\n    flex-direction: column;\n    gap: 24px;\n    margin-bottom: 24px;\n  }\n\n  .cookie-category {\n    padding: 16px;\n    background: var(--bg-primary);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n  }\n\n  .cookie-category-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    margin-bottom: 8px;\n  }\n\n  .cookie-checkbox-label {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    cursor: pointer;\n    flex: 1;\n  }\n\n  .cookie-checkbox {\n    width: 18px;\n    height: 18px;\n    cursor: pointer;\n    accent-color: var(--accent-primary);\n  }\n\n  .cookie-checkbox:disabled {\n    opacity: 0.5;\n    cursor: not-allowed;\n  }\n\n  .cookie-category-title {\n    font-weight: 600;\n    color: var(--text);\n  }\n\n  .cookie-badge {\n    display: inline-block;\n    padding: 4px 8px;\n    border-radius: 4px;\n    font-size: 11px;\n    font-weight: 600;\n    text-transform: uppercase;\n    background: var(--accent-primary);\n    color: #000000;\n  }\n\n  .cookie-category-desc {\n    margin: 8px 0 0 28px;\n    font-size: 13px;\n    color: var(--text-secondary);\n    line-height: 1.5;\n  }\n\n  .cookie-details {\n    margin: 12px 0 0 28px;\n    cursor: pointer;\n  }\n\n  .cookie-details summary {\n    font-size: 12px;\n    color: var(--accent-primary);\n    font-weight: 500;\n    text-decoration: underline;\n    padding: 4px 0;\n  }\n\n  .cookie-details summary:hover {\n    opacity: 0.8;\n  }\n\n  .cookie-list {\n    margin-top: 8px;\n    padding: 8px;\n    background: var(--bg);\n    border-radius: 4px;\n    border: 1px solid var(--border);\n  }\n\n  .cookie-item {\n    display: flex;\n    justify-content: space-between;\n    font-size: 12px;\n    padding: 6px 0;\n    color: var(--text-secondary);\n    border-bottom: 1px solid var(--border);\n  }\n\n  .cookie-item:last-child {\n    border-bottom: none;\n  }\n\n  .cookie-item-name {\n    font-family: monospace;\n    font-weight: 500;\n    color: var(--text);\n  }\n\n  .cookie-item-expiration {\n    font-size: 11px;\n  }\n\n  .cookie-modal-footer-info {\n    margin-bottom: 16px;\n    padding-top: 16px;\n    border-top: 1px solid var(--border);\n  }\n\n  .cookie-updated {\n    font-size: 12px;\n    color: var(--text-secondary);\n  }\n\n  .cookie-modal-footer {\n    display: flex;\n    gap: 12px;\n    padding: 16px 24px;\n    border-top: 1px solid var(--border);\n    background: var(--bg-primary);\n    justify-content: flex-end;\n  }\n\n  .cookie-modal-footer .cookie-btn {\n    flex: 1;\n  }\n\n  @media (max-width: 640px) {\n    .cookie-modal-content {\n      width: 95%;\n      max-height: 95vh;\n    }\n\n    .cookie-modal-header {\n      padding: 16px;\n    }\n\n    .cookie-modal-body {\n      padding: 16px;\n    }\n\n    .cookie-modal-footer {\n      flex-direction: column;\n      padding: 16px;\n    }\n\n    .cookie-modal-footer .cookie-btn {\n      width: 100%;\n    }\n\n    .cookie-category-desc {\n      margin-left: 28px;\n    }\n\n    .cookie-details {\n      margin-left: 28px;\n    }\n  }\n</style>\n\n<script>\n  document.addEventListener(\"DOMContentLoaded\", () => {\n    const banner = document.getElementById(\"cookie-consent\");\n    const modal = document.getElementById(\"cookie-modal\");\n    const acceptBtn = document.getElementById(\"cookie-accept\");\n    const rejectBtn = document.getElementById(\"cookie-reject\");\n    const manageBtn = document.getElementById(\"cookie-manage\");\n    const modalClose = document.getElementById(\"modal-close\");\n    const modalOverlay = document.querySelector(\".cookie-modal-overlay\");\n    const modalRejectBtn = document.getElementById(\"modal-reject\");\n    const modalSaveBtn = document.getElementById(\"modal-save\");\n    const consentKey = \"abc-cookie-consent\";\n    const categoriesKey = \"abc-cookie-categories\";\n\n    // Preference checkboxes\n    const analyticsCheckbox = document.getElementById(\"cookie-analytics\");\n    const performanceCheckbox = document.getElementById(\"cookie-performance\");\n    const marketingCheckbox = document.getElementById(\"cookie-marketing\");\n\n    // Load saved preferences\n    const loadPreferences = () => {\n      const saved = localStorage.getItem(categoriesKey);\n      if (saved) {\n        const prefs = JSON.parse(saved);\n        analyticsCheckbox.checked = prefs.analytics || false;\n        performanceCheckbox.checked = prefs.performance || false;\n        marketingCheckbox.checked = prefs.marketing || false;\n      }\n    };\n\n    // Save preferences\n    const savePreferences = () => {\n      const prefs = {\n        analytics: analyticsCheckbox.checked,\n        performance: performanceCheckbox.checked,\n        marketing: marketingCheckbox.checked,\n      };\n      localStorage.setItem(categoriesKey, JSON.stringify(prefs));\n      localStorage.setItem(consentKey, \"custom\");\n      dismissBanner();\n      updateConsent(prefs);\n    };\n\n    // Dismiss banner with animation\n    const dismissBanner = () => {\n      banner.style.animation = \"slideDown 0.3s ease-out forwards\";\n      setTimeout(() => {\n        banner.style.display = \"none\";\n      }, 300);\n      modal.style.animation = \"fadeOut 0.3s ease-out forwards\";\n      setTimeout(() => {\n        modal.style.display = \"none\";\n      }, 300);\n    };\n\n    // Update analytics consent\n    const updateConsent = (prefs) => {\n      if (window.gtag) {\n        gtag(\"consent\", \"update\", {\n          analytics_storage: prefs.analytics ? \"granted\" : \"denied\",\n        });\n      }\n    };\n\n    // Check if user has already made a choice\n    const userConsent = localStorage.getItem(consentKey);\n\n    if (!userConsent) {\n      setTimeout(() => {\n        banner.style.display = \"flex\";\n      }, 1000);\n    }\n\n    loadPreferences();\n\n    // Accept all cookies\n    acceptBtn.addEventListener(\"click\", () => {\n      analyticsCheckbox.checked = true;\n      performanceCheckbox.checked = true;\n      marketingCheckbox.checked = true;\n      savePreferences();\n    });\n\n    // Reject all cookies (keep only essential)\n    const rejectAllCookies = () => {\n      analyticsCheckbox.checked = false;\n      performanceCheckbox.checked = false;\n      marketingCheckbox.checked = false;\n      localStorage.setItem(\n        categoriesKey,\n        JSON.stringify({\n          analytics: false,\n          performance: false,\n          marketing: false,\n        })\n      );\n      localStorage.setItem(consentKey, \"rejected\");\n      dismissBanner();\n      updateConsent({ analytics: false, performance: false, marketing: false });\n    };\n\n    rejectBtn.addEventListener(\"click\", rejectAllCookies);\n    modalRejectBtn.addEventListener(\"click\", rejectAllCookies);\n\n    // Manage preferences\n    manageBtn.addEventListener(\"click\", () => {\n      modal.style.display = \"flex\";\n      loadPreferences();\n    });\n\n    // Modal controls\n    modalClose.addEventListener(\"click\", () => {\n      modal.style.animation = \"fadeOut 0.3s ease-out forwards\";\n      setTimeout(() => {\n        modal.style.display = \"none\";\n      }, 300);\n    });\n\n    modalOverlay.addEventListener(\"click\", () => {\n      modalClose.click();\n    });\n\n    // Save preferences from modal\n    modalSaveBtn.addEventListener(\"click\", savePreferences);\n\n    // ESC key to close modal\n    document.addEventListener(\"keydown\", (e) => {\n      if (e.key === \"Escape\" && modal.style.display === \"flex\") {\n        modalClose.click();\n      }\n    });\n\n    // Add fadeOut animation\n    const style = document.createElement(\"style\");\n    style.textContent = `\n      @keyframes slideDown {\n        to {\n          transform: translateY(100%);\n          opacity: 0;\n        }\n      }\n      @keyframes fadeOut {\n        to {\n          opacity: 0;\n        }\n      }\n    `;\n    document.head.appendChild(style);\n  });\n</script>\n\n\n    <!-- Scripts -->\n    <script src=\"/assets/js/search.js\"></script>\n    <script src=\"/assets/js/performance.js\"></script>\n    <script src=\"/assets/js/visual-enhancements.js\"></script>\n  </body>\n</html>\n","<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"dark\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>\n      Accessibility Guide | Minecraft Mods & Packs Showcase\n    </title>\n\n    <!-- Stylesheets -->\n    <link rel=\"stylesheet\" href=\"/assets/css/main.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/layout.css\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/modpacks.css\"\n    />\n    <link rel=\"stylesheet\" href=\"/assets/css/docs.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n    />\n\n    <script>\n      if (!document.body) {\n        console.warn(\"Body not ready, skipping preloader\");\n      } else {\n        window.addEventListener(\"load\", () => {\n          document.body.classList.add(\"loaded\");\n        });\n      }\n\n      const savedTheme = localStorage.getItem(\"theme\") || \"dark\";\n      document.documentElement.setAttribute(\"data-theme\", savedTheme);\n    </script>\n  </head>\n  <body>\n    <!-- Preloader -->\n    <div class=\"preloader\">\n      <div class=\"spinner\"></div>\n    </div>\n\n    <!-- Mobile Menu Toggle -->\n    <button\n      id=\"mobile-sidebar-toggle\"\n      class=\"mobile-sidebar-toggle\"\n      aria-label=\"Toggle sidebar\"\n    >\n      <i class=\"fa-solid fa-bars\"></i>\n    </button>\n\n    <!-- Docs Sidebar -->\n    <aside id=\"docs-sidebar\" class=\"docs-sidebar\">\n      <div class=\"sidebar-header\">\n        <a href=\"/\" class=\"sidebar-logo\">\n          <i class=\"fa-solid fa-cube\"></i>\n          <span>Minecraft Mods & Packs Showcase</span>\n        </a>\n        <button\n          id=\"sidebar-close\"\n          class=\"sidebar-close\"\n          aria-label=\"Close sidebar\"\n        >\n          <i class=\"fa-solid fa-times\"></i>\n        </button>\n      </div>\n\n      <!-- Search in Sidebar -->\n      <div class=\"sidebar-search\">\n        <input\n          type=\"search\"\n          id=\"sidebar-search\"\n          placeholder=\"Search docs...\"\n          aria-label=\"Search documentation\"\n        />\n        <i class=\"fa-solid fa-search\"></i>\n      </div>\n\n      <!-- Navigation Tree -->\n      <nav class=\"sidebar-nav\">\n            \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"setup\"\n          >\n            <i\n              class=\"fa-solid fa-gear \"\n            ></i>\n            <span>Setup</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-setup\"\n          >\n            \n             \n            <a\n              href=\"/docs/getting-started/\"\n              class=\"nav-item \"\n            >\n              Getting Started\n            </a>\n              \n            <a\n              href=\"/docs/setup/\"\n              class=\"nav-item \"\n            >\n              Setup & Configuration\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"styling\"\n          >\n            <i\n              class=\"fa-solid fa-palette \"\n            ></i>\n            <span>Styling</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-styling\"\n          >\n            \n             \n            <a\n              href=\"/docs/customization/\"\n              class=\"nav-item \"\n            >\n              Customization\n            </a>\n              \n            <a\n              href=\"/docs/css-variables/\"\n              class=\"nav-item \"\n            >\n              CSS Variables Reference\n            </a>\n             \n          </div>\n        </div>\n              \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"community\"\n          >\n            <i\n              class=\"fa-solid fa-users \"\n            ></i>\n            <span>Community</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-community\"\n          >\n            \n             \n            <a\n              href=\"/docs/contributing/\"\n              class=\"nav-item \"\n            >\n              Contributing\n            </a>\n              \n            <a\n              href=\"/docs/content-guidelines/\"\n              class=\"nav-item \"\n            >\n              Content Guidelines\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"developer\"\n          >\n            <i\n              class=\"fa-solid fa-code \"\n            ></i>\n            <span>Developer</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-developer\"\n          >\n            \n             \n            <a\n              href=\"/docs/api-reference/\"\n              class=\"nav-item \"\n            >\n              API Reference\n            </a>\n              \n            <a\n              href=\"/docs/deployment/\"\n              class=\"nav-item \"\n            >\n              Deployment Guide\n            </a>\n              \n            <a\n              href=\"/docs/github-actions/\"\n              class=\"nav-item \"\n            >\n              GitHub Actions\n            </a>\n              \n            <a\n              href=\"/docs/project-structure/\"\n              class=\"nav-item \"\n            >\n              Project Structure\n            </a>\n              \n            <a\n              href=\"/docs/liquid-templates/\"\n              class=\"nav-item \"\n            >\n              Liquid Templates\n            </a>\n              \n            <a\n              href=\"/docs/performance/\"\n              class=\"nav-item \"\n            >\n              Performance Optimization\n            </a>\n              \n            <a\n              href=\"/docs/seo-guide/\"\n              class=\"nav-item \"\n            >\n              SEO Guide\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle active\"\n            data-category=\"help\"\n          >\n            <i\n              class=\"fa-solid fa-circle-question \"\n            ></i>\n            <span>Help</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items expanded\"\n            id=\"category-help\"\n          >\n            \n             \n            <a\n              href=\"/docs/faq/\"\n              class=\"nav-item \"\n            >\n              FAQ\n            </a>\n              \n            <a\n              href=\"/docs/troubleshooting/\"\n              class=\"nav-item \"\n            >\n              Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/accessibility/\"\n              class=\"nav-item active\"\n            >\n              Accessibility Guide\n            </a>\n              \n            <a\n              href=\"/docs/common-errors/\"\n              class=\"nav-item \"\n            >\n              Common Errors & Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/browser-support/\"\n              class=\"nav-item \"\n            >\n              Browser Support\n            </a>\n             \n          </div>\n        </div>\n         \n      </nav>\n\n      <!-- Quick Links -->\n      <div class=\"sidebar-footer\">\n        <a href=\"/docs/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-home\"></i>\n          All Docs\n        </a>\n        <a href=\"/projects/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-folder\"></i>\n          Projects\n        </a>\n      </div>\n    </aside>\n\n    <!-- Sidebar Overlay (for mobile) -->\n    <div id=\"sidebar-overlay\" class=\"sidebar-overlay\"></div>\n\n    <!-- Main Content -->\n    <div class=\"docs-layout\">\n      <!-- Breadcrumbs -->\n      \n      <nav class=\"breadcrumbs\" aria-label=\"Breadcrumb\">\n        <a href=\"/\">\n          <i class=\"fa-solid fa-home\"></i>\n          Home\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a href=\"/docs/\">Docs</a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a\n          href=\"/docs-category-help/\"\n        >\n          Help\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <span class=\"current\">Accessibility Guide</span>\n      </nav>\n      \n\n      <!-- Page Content -->\n      <main class=\"docs-content\">\n        <article><h1 id=\"accessibility-guide\">Accessibility Guide</h1>\n\n<p>Make your ABC showcase accessible to all users, including those with disabilities.</p>\n\n<h2 id=\"wcag-compliance\">WCAG Compliance</h2>\n\n<h3 id=\"target-level-aa\">Target Level: AA</h3>\n\n<p>Follow <a href=\"https://www.w3.org/WAI/WCAG21/quickref/\">Web Content Accessibility Guidelines (WCAG) 2.1 Level AA</a> for:</p>\n\n<ul>\n  <li><strong>Perceivable</strong>: Content is available to senses</li>\n  <li><strong>Operable</strong>: Interface is usable</li>\n  <li><strong>Understandable</strong>: Content and operation are clear</li>\n  <li><strong>Robust</strong>: Works with assistive technologies</li>\n</ul>\n\n<h2 id=\"semantic-html\">Semantic HTML</h2>\n\n<h3 id=\"use-proper-elements\">Use Proper Elements</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Good: Semantic --&gt;</span>\n<span class=\"nt\">&lt;nav&gt;</span>\n  <span class=\"nt\">&lt;ul&gt;</span>\n    <span class=\"nt\">&lt;li&gt;&lt;a</span> <span class=\"na\">href=</span><span class=\"s\">\"/\"</span><span class=\"nt\">&gt;</span>Home<span class=\"nt\">&lt;/a&gt;&lt;/li&gt;</span>\n  <span class=\"nt\">&lt;/ul&gt;</span>\n<span class=\"nt\">&lt;/nav&gt;</span>\n\n<span class=\"nt\">&lt;main&gt;</span>\n  <span class=\"nt\">&lt;article&gt;</span>\n    <span class=\"nt\">&lt;h1&gt;</span>Title<span class=\"nt\">&lt;/h1&gt;</span>\n    <span class=\"nt\">&lt;p&gt;</span>Content<span class=\"nt\">&lt;/p&gt;</span>\n  <span class=\"nt\">&lt;/article&gt;</span>\n<span class=\"nt\">&lt;/main&gt;</span>\n\n<span class=\"nt\">&lt;footer&gt;</span>\n  <span class=\"nt\">&lt;p&gt;</span><span class=\"ni\">&amp;copy;</span> 2025<span class=\"nt\">&lt;/p&gt;</span>\n<span class=\"nt\">&lt;/footer&gt;</span>\n\n<span class=\"c\">&lt;!-- Bad: Non-semantic --&gt;</span>\n<span class=\"nt\">&lt;div</span> <span class=\"na\">class=</span><span class=\"s\">\"nav\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;div</span> <span class=\"na\">class=</span><span class=\"s\">\"link\"</span><span class=\"nt\">&gt;</span>Home<span class=\"nt\">&lt;/div&gt;</span>\n<span class=\"nt\">&lt;/div&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"heading-hierarchy\">Heading Hierarchy</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Correct hierarchy --&gt;</span>\n<span class=\"nt\">&lt;h1&gt;</span>Main Title<span class=\"nt\">&lt;/h1&gt;</span>\n<span class=\"nt\">&lt;h2&gt;</span>Section<span class=\"nt\">&lt;/h2&gt;</span>\n<span class=\"nt\">&lt;h3&gt;</span>Subsection<span class=\"nt\">&lt;/h3&gt;</span>\n<span class=\"nt\">&lt;h2&gt;</span>Another Section<span class=\"nt\">&lt;/h2&gt;</span>\n\n<span class=\"c\">&lt;!-- Avoid skipping levels --&gt;</span>\n<span class=\"nt\">&lt;h1&gt;</span>Title<span class=\"nt\">&lt;/h1&gt;</span>\n<span class=\"nt\">&lt;h3&gt;</span>Subsection<span class=\"nt\">&lt;/h3&gt;</span>\n<span class=\"c\">&lt;!-- Bad: skipped h2 --&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"keyboard-navigation\">Keyboard Navigation</h2>\n\n<h3 id=\"focusable-elements\">Focusable Elements</h3>\n\n<p>Ensure all interactive elements are keyboard accessible:</p>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;button&gt;</span>Click Me<span class=\"nt\">&lt;/button&gt;</span>\n<span class=\"nt\">&lt;a</span> <span class=\"na\">href=</span><span class=\"s\">\"/page\"</span><span class=\"nt\">&gt;</span>Link<span class=\"nt\">&lt;/a&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"text\"</span> <span class=\"nt\">/&gt;</span>\n<span class=\"nt\">&lt;select&gt;</span>\n  <span class=\"nt\">&lt;option&gt;</span>Option<span class=\"nt\">&lt;/option&gt;</span>\n<span class=\"nt\">&lt;/select&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"focus-indicators\">Focus Indicators</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Always visible focus styles */</span>\n<span class=\"nd\">:focus</span> <span class=\"p\">{</span>\n  <span class=\"nl\">outline</span><span class=\"p\">:</span> <span class=\"m\">2px</span> <span class=\"nb\">solid</span> <span class=\"n\">var</span><span class=\"p\">(</span><span class=\"n\">--accent-primary</span><span class=\"p\">);</span>\n  <span class=\"nl\">outline-offset</span><span class=\"p\">:</span> <span class=\"m\">2px</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Better focus for dark theme */</span>\n<span class=\"nd\">:focus-visible</span> <span class=\"p\">{</span>\n  <span class=\"nl\">outline</span><span class=\"p\">:</span> <span class=\"m\">2px</span> <span class=\"nb\">solid</span> <span class=\"n\">var</span><span class=\"p\">(</span><span class=\"n\">--accent-primary</span><span class=\"p\">);</span>\n  <span class=\"nl\">outline-offset</span><span class=\"p\">:</span> <span class=\"m\">2px</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Don't remove outlines */</span>\n<span class=\"c\">/* BAD: button:focus { outline: none; } */</span>\n</code></pre></div></div>\n\n<h3 id=\"skip-links\">Skip Links</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;a</span> <span class=\"na\">href=</span><span class=\"s\">\"#main-content\"</span> <span class=\"na\">class=</span><span class=\"s\">\"skip-link\"</span><span class=\"nt\">&gt;</span> Skip to main content <span class=\"nt\">&lt;/a&gt;</span>\n\n<span class=\"nt\">&lt;main</span> <span class=\"na\">id=</span><span class=\"s\">\"main-content\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"c\">&lt;!-- Content --&gt;</span>\n<span class=\"nt\">&lt;/main&gt;</span>\n</code></pre></div></div>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">.skip-link</span> <span class=\"p\">{</span>\n  <span class=\"nl\">position</span><span class=\"p\">:</span> <span class=\"nb\">absolute</span><span class=\"p\">;</span>\n  <span class=\"nl\">top</span><span class=\"p\">:</span> <span class=\"m\">-40px</span><span class=\"p\">;</span>\n  <span class=\"nl\">left</span><span class=\"p\">:</span> <span class=\"m\">0</span><span class=\"p\">;</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"n\">var</span><span class=\"p\">(</span><span class=\"n\">--accent-primary</span><span class=\"p\">);</span>\n  <span class=\"nl\">color</span><span class=\"p\">:</span> <span class=\"no\">white</span><span class=\"p\">;</span>\n  <span class=\"nl\">padding</span><span class=\"p\">:</span> <span class=\"m\">8px</span><span class=\"p\">;</span>\n  <span class=\"nl\">z-index</span><span class=\"p\">:</span> <span class=\"m\">1000</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"nc\">.skip-link</span><span class=\"nd\">:focus</span> <span class=\"p\">{</span>\n  <span class=\"nl\">top</span><span class=\"p\">:</span> <span class=\"m\">0</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h3 id=\"tab-order\">Tab Order</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Natural tab order (default) --&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">tabindex=</span><span class=\"s\">\"0\"</span> <span class=\"nt\">/&gt;</span>\n<span class=\"nt\">&lt;button</span> <span class=\"na\">tabindex=</span><span class=\"s\">\"0\"</span><span class=\"nt\">&gt;</span>Submit<span class=\"nt\">&lt;/button&gt;</span>\n\n<span class=\"c\">&lt;!-- Custom tab order (use sparingly) --&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">tabindex=</span><span class=\"s\">\"1\"</span> <span class=\"nt\">/&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">tabindex=</span><span class=\"s\">\"2\"</span> <span class=\"nt\">/&gt;</span>\n\n<span class=\"c\">&lt;!-- Remove from tab order --&gt;</span>\n<span class=\"nt\">&lt;div</span> <span class=\"na\">tabindex=</span><span class=\"s\">\"-1\"</span><span class=\"nt\">&gt;</span>Not focusable<span class=\"nt\">&lt;/div&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"aria-labels\">ARIA Labels</h2>\n\n<h3 id=\"landmarks\">Landmarks</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;header</span> <span class=\"na\">role=</span><span class=\"s\">\"banner\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;nav</span> <span class=\"na\">role=</span><span class=\"s\">\"navigation\"</span> <span class=\"na\">aria-label=</span><span class=\"s\">\"Main navigation\"</span><span class=\"nt\">&gt;</span>\n    <span class=\"c\">&lt;!-- Nav items --&gt;</span>\n  <span class=\"nt\">&lt;/nav&gt;</span>\n<span class=\"nt\">&lt;/header&gt;</span>\n\n<span class=\"nt\">&lt;main</span> <span class=\"na\">role=</span><span class=\"s\">\"main\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;section</span> <span class=\"na\">aria-labelledby=</span><span class=\"s\">\"projects-heading\"</span><span class=\"nt\">&gt;</span>\n    <span class=\"nt\">&lt;h2</span> <span class=\"na\">id=</span><span class=\"s\">\"projects-heading\"</span><span class=\"nt\">&gt;</span>Projects<span class=\"nt\">&lt;/h2&gt;</span>\n  <span class=\"nt\">&lt;/section&gt;</span>\n<span class=\"nt\">&lt;/main&gt;</span>\n\n<span class=\"nt\">&lt;aside</span> <span class=\"na\">role=</span><span class=\"s\">\"complementary\"</span> <span class=\"na\">aria-label=</span><span class=\"s\">\"Sidebar\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"c\">&lt;!-- Sidebar content --&gt;</span>\n<span class=\"nt\">&lt;/aside&gt;</span>\n\n<span class=\"nt\">&lt;footer</span> <span class=\"na\">role=</span><span class=\"s\">\"contentinfo\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"c\">&lt;!-- Footer content --&gt;</span>\n<span class=\"nt\">&lt;/footer&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"button-labels\">Button Labels</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Icon buttons need labels --&gt;</span>\n<span class=\"nt\">&lt;button</span> <span class=\"na\">aria-label=</span><span class=\"s\">\"Toggle theme\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;i</span> <span class=\"na\">class=</span><span class=\"s\">\"fa-sun\"</span><span class=\"nt\">&gt;&lt;/i&gt;</span>\n<span class=\"nt\">&lt;/button&gt;</span>\n\n<span class=\"nt\">&lt;button</span> <span class=\"na\">aria-label=</span><span class=\"s\">\"Close modal\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;i</span> <span class=\"na\">class=</span><span class=\"s\">\"fa-times\"</span><span class=\"nt\">&gt;&lt;/i&gt;</span>\n<span class=\"nt\">&lt;/button&gt;</span>\n\n<span class=\"c\">&lt;!-- Links with icons --&gt;</span>\n<span class=\"nt\">&lt;a</span> <span class=\"na\">href=</span><span class=\"s\">\"https://github.com/user/repo\"</span> <span class=\"na\">aria-label=</span><span class=\"s\">\"View on GitHub\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;i</span> <span class=\"na\">class=</span><span class=\"s\">\"fab fa-github\"</span><span class=\"nt\">&gt;&lt;/i&gt;</span>\n<span class=\"nt\">&lt;/a&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"live-regions\">Live Regions</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Announce dynamic content --&gt;</span>\n<span class=\"nt\">&lt;div</span> <span class=\"na\">role=</span><span class=\"s\">\"status\"</span> <span class=\"na\">aria-live=</span><span class=\"s\">\"polite\"</span> <span class=\"na\">aria-atomic=</span><span class=\"s\">\"true\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;p</span> <span class=\"na\">id=</span><span class=\"s\">\"search-results\"</span><span class=\"nt\">&gt;</span>Found 5 results<span class=\"nt\">&lt;/p&gt;</span>\n<span class=\"nt\">&lt;/div&gt;</span>\n\n<span class=\"c\">&lt;!-- Alerts --&gt;</span>\n<span class=\"nt\">&lt;div</span> <span class=\"na\">role=</span><span class=\"s\">\"alert\"</span> <span class=\"na\">aria-live=</span><span class=\"s\">\"assertive\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;p&gt;</span>Error: Form submission failed<span class=\"nt\">&lt;/p&gt;</span>\n<span class=\"nt\">&lt;/div&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"form-labels\">Form Labels</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Always label inputs --&gt;</span>\n<span class=\"nt\">&lt;label</span> <span class=\"na\">for=</span><span class=\"s\">\"search\"</span><span class=\"nt\">&gt;</span>Search<span class=\"nt\">&lt;/label&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"search\"</span> <span class=\"na\">id=</span><span class=\"s\">\"search\"</span> <span class=\"na\">name=</span><span class=\"s\">\"search\"</span> <span class=\"nt\">/&gt;</span>\n\n<span class=\"c\">&lt;!-- Or use aria-label --&gt;</span>\n<span class=\"nt\">&lt;input</span>\n  <span class=\"na\">type=</span><span class=\"s\">\"search\"</span>\n  <span class=\"na\">aria-label=</span><span class=\"s\">\"Search documentation\"</span>\n  <span class=\"na\">placeholder=</span><span class=\"s\">\"Search...\"</span>\n<span class=\"nt\">/&gt;</span>\n\n<span class=\"c\">&lt;!-- Group related inputs --&gt;</span>\n<span class=\"nt\">&lt;fieldset&gt;</span>\n  <span class=\"nt\">&lt;legend&gt;</span>Filter Options<span class=\"nt\">&lt;/legend&gt;</span>\n  <span class=\"nt\">&lt;label&gt;&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"checkbox\"</span> <span class=\"na\">name=</span><span class=\"s\">\"category\"</span> <span class=\"na\">value=</span><span class=\"s\">\"setup\"</span> <span class=\"nt\">/&gt;</span> Setup<span class=\"nt\">&lt;/label&gt;</span>\n  <span class=\"nt\">&lt;label</span>\n    <span class=\"nt\">&gt;&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"checkbox\"</span> <span class=\"na\">name=</span><span class=\"s\">\"category\"</span> <span class=\"na\">value=</span><span class=\"s\">\"styling\"</span> <span class=\"nt\">/&gt;</span> Styling<span class=\"nt\">&lt;/label</span>\n  <span class=\"nt\">&gt;</span>\n<span class=\"nt\">&lt;/fieldset&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"color-and-contrast\">Color and Contrast</h2>\n\n<h3 id=\"contrast-ratios\">Contrast Ratios</h3>\n\n<p><strong>WCAG AA Requirements:</strong></p>\n\n<ul>\n  <li>Normal text: 4.5:1</li>\n  <li>Large text (18pt+): 3:1</li>\n  <li>UI components: 3:1</li>\n</ul>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Good contrast examples */</span>\n<span class=\"nc\">.dark-theme</span> <span class=\"p\">{</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"m\">#1a1a1a</span><span class=\"p\">;</span>\n  <span class=\"nl\">color</span><span class=\"p\">:</span> <span class=\"m\">#e0e0e0</span><span class=\"p\">;</span> <span class=\"c\">/* 12.6:1 ratio */</span>\n<span class=\"p\">}</span>\n\n<span class=\"nc\">.light-theme</span> <span class=\"p\">{</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"m\">#ffffff</span><span class=\"p\">;</span>\n  <span class=\"nl\">color</span><span class=\"p\">:</span> <span class=\"m\">#212121</span><span class=\"p\">;</span> <span class=\"c\">/* 16.1:1 ratio */</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Check with browser DevTools or tools like:\n   - WebAIM Contrast Checker\n   - Color Contrast Analyzer\n*/</span>\n</code></pre></div></div>\n\n<h3 id=\"dont-rely-on-color-alone\">Don’t Rely on Color Alone</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Bad: Color only --&gt;</span>\n<span class=\"nt\">&lt;span</span> <span class=\"na\">style=</span><span class=\"s\">\"color: red;\"</span><span class=\"nt\">&gt;</span>Required<span class=\"nt\">&lt;/span&gt;</span>\n\n<span class=\"c\">&lt;!-- Good: Color + text/icon --&gt;</span>\n<span class=\"nt\">&lt;span</span> <span class=\"na\">class=</span><span class=\"s\">\"required\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;i</span> <span class=\"na\">class=</span><span class=\"s\">\"fa-asterisk\"</span> <span class=\"na\">aria-hidden=</span><span class=\"s\">\"true\"</span><span class=\"nt\">&gt;&lt;/i&gt;</span>\n  Required\n<span class=\"nt\">&lt;/span&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"images-and-media\">Images and Media</h2>\n\n<h3 id=\"alt-text\">Alt Text</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Informative images --&gt;</span>\n<span class=\"nt\">&lt;img</span> <span class=\"na\">src=</span><span class=\"s\">\"logo.png\"</span> <span class=\"na\">alt=</span><span class=\"s\">\"ABC Showcase logo\"</span> <span class=\"nt\">/&gt;</span>\n\n<span class=\"c\">&lt;!-- Decorative images --&gt;</span>\n<span class=\"nt\">&lt;img</span> <span class=\"na\">src=</span><span class=\"s\">\"decoration.svg\"</span> <span class=\"na\">alt=</span><span class=\"s\">\"\"</span> <span class=\"na\">role=</span><span class=\"s\">\"presentation\"</span> <span class=\"nt\">/&gt;</span>\n\n<span class=\"c\">&lt;!-- Complex images --&gt;</span>\n<span class=\"nt\">&lt;figure&gt;</span>\n  <span class=\"nt\">&lt;img</span> <span class=\"na\">src=</span><span class=\"s\">\"chart.png\"</span> <span class=\"na\">alt=</span><span class=\"s\">\"Sales chart showing 20% growth\"</span> <span class=\"nt\">/&gt;</span>\n  <span class=\"nt\">&lt;figcaption&gt;</span>\n    Detailed description: Sales increased from $100k in Q1 to $120k in Q2,\n    representing 20% growth.\n  <span class=\"nt\">&lt;/figcaption&gt;</span>\n<span class=\"nt\">&lt;/figure&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"videos\">Videos</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;video</span> <span class=\"na\">controls</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;source</span> <span class=\"na\">src=</span><span class=\"s\">\"video.mp4\"</span> <span class=\"na\">type=</span><span class=\"s\">\"video/mp4\"</span> <span class=\"nt\">/&gt;</span>\n  <span class=\"nt\">&lt;track</span> <span class=\"na\">kind=</span><span class=\"s\">\"captions\"</span> <span class=\"na\">src=</span><span class=\"s\">\"captions.vtt\"</span> <span class=\"na\">srclang=</span><span class=\"s\">\"en\"</span> <span class=\"na\">label=</span><span class=\"s\">\"English\"</span> <span class=\"nt\">/&gt;</span>\n  <span class=\"nt\">&lt;track</span> <span class=\"na\">kind=</span><span class=\"s\">\"descriptions\"</span> <span class=\"na\">src=</span><span class=\"s\">\"descriptions.vtt\"</span> <span class=\"na\">srclang=</span><span class=\"s\">\"en\"</span> <span class=\"nt\">/&gt;</span>\n  Your browser doesn't support video.\n<span class=\"nt\">&lt;/video&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"screen-reader-support\">Screen Reader Support</h2>\n\n<h3 id=\"hidden-content\">Hidden Content</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Visually hidden but screen reader accessible */</span>\n<span class=\"nc\">.sr-only</span> <span class=\"p\">{</span>\n  <span class=\"nl\">position</span><span class=\"p\">:</span> <span class=\"nb\">absolute</span><span class=\"p\">;</span>\n  <span class=\"nl\">width</span><span class=\"p\">:</span> <span class=\"m\">1px</span><span class=\"p\">;</span>\n  <span class=\"nl\">height</span><span class=\"p\">:</span> <span class=\"m\">1px</span><span class=\"p\">;</span>\n  <span class=\"nl\">padding</span><span class=\"p\">:</span> <span class=\"m\">0</span><span class=\"p\">;</span>\n  <span class=\"nl\">margin</span><span class=\"p\">:</span> <span class=\"m\">-1px</span><span class=\"p\">;</span>\n  <span class=\"nl\">overflow</span><span class=\"p\">:</span> <span class=\"nb\">hidden</span><span class=\"p\">;</span>\n  <span class=\"nl\">clip</span><span class=\"p\">:</span> <span class=\"n\">rect</span><span class=\"p\">(</span><span class=\"m\">0</span><span class=\"p\">,</span> <span class=\"m\">0</span><span class=\"p\">,</span> <span class=\"m\">0</span><span class=\"p\">,</span> <span class=\"m\">0</span><span class=\"p\">);</span>\n  <span class=\"nl\">white-space</span><span class=\"p\">:</span> <span class=\"nb\">nowrap</span><span class=\"p\">;</span>\n  <span class=\"nl\">border</span><span class=\"p\">:</span> <span class=\"m\">0</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Hidden from everyone */</span>\n<span class=\"nc\">.hidden</span> <span class=\"p\">{</span>\n  <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"nb\">none</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Use aria-hidden for decorative content */</span>\n<span class=\"o\">&lt;</span><span class=\"nt\">i</span> <span class=\"nt\">class</span><span class=\"o\">=</span><span class=\"s1\">\"fa-icon\"</span> <span class=\"nt\">aria-hidden</span><span class=\"o\">=</span><span class=\"s1\">\"true\"</span><span class=\"o\">&gt;&lt;/</span><span class=\"nt\">i</span><span class=\"o\">&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"descriptive-text\">Descriptive Text</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Generic link text is bad --&gt;</span>\n<span class=\"nt\">&lt;a</span> <span class=\"na\">href=</span><span class=\"s\">\"/docs\"</span><span class=\"nt\">&gt;</span>Click here<span class=\"nt\">&lt;/a&gt;</span>\n\n<span class=\"c\">&lt;!-- Descriptive link text is good --&gt;</span>\n<span class=\"nt\">&lt;a</span> <span class=\"na\">href=</span><span class=\"s\">\"/docs\"</span><span class=\"nt\">&gt;</span>Read the documentation<span class=\"nt\">&lt;/a&gt;</span>\n\n<span class=\"c\">&lt;!-- Or add context --&gt;</span>\n<span class=\"nt\">&lt;a</span> <span class=\"na\">href=</span><span class=\"s\">\"/download\"</span><span class=\"nt\">&gt;</span>\n  Download\n  <span class=\"nt\">&lt;span</span> <span class=\"na\">class=</span><span class=\"s\">\"sr-only\"</span><span class=\"nt\">&gt;</span> modpack installer<span class=\"nt\">&lt;/span&gt;</span>\n<span class=\"nt\">&lt;/a&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"forms\">Forms</h2>\n\n<h3 id=\"error-messages\">Error Messages</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;form&gt;</span>\n  <span class=\"nt\">&lt;div</span> <span class=\"na\">class=</span><span class=\"s\">\"form-group\"</span><span class=\"nt\">&gt;</span>\n    <span class=\"nt\">&lt;label</span> <span class=\"na\">for=</span><span class=\"s\">\"email\"</span><span class=\"nt\">&gt;</span>Email<span class=\"nt\">&lt;/label&gt;</span>\n    <span class=\"nt\">&lt;input</span>\n      <span class=\"na\">type=</span><span class=\"s\">\"email\"</span>\n      <span class=\"na\">id=</span><span class=\"s\">\"email\"</span>\n      <span class=\"na\">aria-describedby=</span><span class=\"s\">\"email-error\"</span>\n      <span class=\"na\">aria-invalid=</span><span class=\"s\">\"true\"</span>\n    <span class=\"nt\">/&gt;</span>\n    <span class=\"nt\">&lt;span</span> <span class=\"na\">id=</span><span class=\"s\">\"email-error\"</span> <span class=\"na\">role=</span><span class=\"s\">\"alert\"</span><span class=\"nt\">&gt;</span>\n      Please enter a valid email address\n    <span class=\"nt\">&lt;/span&gt;</span>\n  <span class=\"nt\">&lt;/div&gt;</span>\n<span class=\"nt\">&lt;/form&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"required-fields\">Required Fields</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;label</span> <span class=\"na\">for=</span><span class=\"s\">\"username\"</span><span class=\"nt\">&gt;</span>\n  Username\n  <span class=\"nt\">&lt;span</span> <span class=\"na\">aria-label=</span><span class=\"s\">\"required\"</span><span class=\"nt\">&gt;</span>*<span class=\"nt\">&lt;/span&gt;</span>\n<span class=\"nt\">&lt;/label&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"text\"</span> <span class=\"na\">id=</span><span class=\"s\">\"username\"</span> <span class=\"na\">required</span> <span class=\"na\">aria-required=</span><span class=\"s\">\"true\"</span> <span class=\"nt\">/&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"help-text\">Help Text</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;label</span> <span class=\"na\">for=</span><span class=\"s\">\"password\"</span><span class=\"nt\">&gt;</span>Password<span class=\"nt\">&lt;/label&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"password\"</span> <span class=\"na\">id=</span><span class=\"s\">\"password\"</span> <span class=\"na\">aria-describedby=</span><span class=\"s\">\"password-help\"</span> <span class=\"nt\">/&gt;</span>\n<span class=\"nt\">&lt;small</span> <span class=\"na\">id=</span><span class=\"s\">\"password-help\"</span><span class=\"nt\">&gt;</span> Must be at least 8 characters with 1 number <span class=\"nt\">&lt;/small&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"modals-and-overlays\">Modals and Overlays</h2>\n\n<h3 id=\"focus-management\">Focus Management</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// Trap focus in modal</span>\n<span class=\"kd\">const</span> <span class=\"nx\">modal</span> <span class=\"o\">=</span> <span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">querySelector</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">.modal</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n<span class=\"kd\">const</span> <span class=\"nx\">focusableElements</span> <span class=\"o\">=</span> <span class=\"nx\">modal</span><span class=\"p\">.</span><span class=\"nx\">querySelectorAll</span><span class=\"p\">(</span>\n  <span class=\"dl\">'</span><span class=\"s1\">button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])</span><span class=\"dl\">'</span>\n<span class=\"p\">);</span>\n<span class=\"kd\">const</span> <span class=\"nx\">firstFocusable</span> <span class=\"o\">=</span> <span class=\"nx\">focusableElements</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">];</span>\n<span class=\"kd\">const</span> <span class=\"nx\">lastFocusable</span> <span class=\"o\">=</span> <span class=\"nx\">focusableElements</span><span class=\"p\">[</span><span class=\"nx\">focusableElements</span><span class=\"p\">.</span><span class=\"nx\">length</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">];</span>\n\n<span class=\"nx\">modal</span><span class=\"p\">.</span><span class=\"nx\">addEventListener</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">keydown</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">e</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">e</span><span class=\"p\">.</span><span class=\"nx\">key</span> <span class=\"o\">===</span> <span class=\"dl\">\"</span><span class=\"s2\">Tab</span><span class=\"dl\">\"</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">e</span><span class=\"p\">.</span><span class=\"nx\">shiftKey</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n      <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">activeElement</span> <span class=\"o\">===</span> <span class=\"nx\">firstFocusable</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"nx\">lastFocusable</span><span class=\"p\">.</span><span class=\"nx\">focus</span><span class=\"p\">();</span>\n        <span class=\"nx\">e</span><span class=\"p\">.</span><span class=\"nx\">preventDefault</span><span class=\"p\">();</span>\n      <span class=\"p\">}</span>\n    <span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n      <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">activeElement</span> <span class=\"o\">===</span> <span class=\"nx\">lastFocusable</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"nx\">firstFocusable</span><span class=\"p\">.</span><span class=\"nx\">focus</span><span class=\"p\">();</span>\n        <span class=\"nx\">e</span><span class=\"p\">.</span><span class=\"nx\">preventDefault</span><span class=\"p\">();</span>\n      <span class=\"p\">}</span>\n    <span class=\"p\">}</span>\n  <span class=\"p\">}</span>\n\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">e</span><span class=\"p\">.</span><span class=\"nx\">key</span> <span class=\"o\">===</span> <span class=\"dl\">\"</span><span class=\"s2\">Escape</span><span class=\"dl\">\"</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"nx\">closeModal</span><span class=\"p\">();</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">});</span>\n</code></pre></div></div>\n\n<h3 id=\"aria-modal\">ARIA Modal</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;div</span>\n  <span class=\"na\">role=</span><span class=\"s\">\"dialog\"</span>\n  <span class=\"na\">aria-modal=</span><span class=\"s\">\"true\"</span>\n  <span class=\"na\">aria-labelledby=</span><span class=\"s\">\"modal-title\"</span>\n  <span class=\"na\">aria-describedby=</span><span class=\"s\">\"modal-description\"</span>\n<span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;h2</span> <span class=\"na\">id=</span><span class=\"s\">\"modal-title\"</span><span class=\"nt\">&gt;</span>Confirm Action<span class=\"nt\">&lt;/h2&gt;</span>\n  <span class=\"nt\">&lt;p</span> <span class=\"na\">id=</span><span class=\"s\">\"modal-description\"</span><span class=\"nt\">&gt;</span>Are you sure you want to proceed?<span class=\"nt\">&lt;/p&gt;</span>\n  <span class=\"nt\">&lt;button&gt;</span>Confirm<span class=\"nt\">&lt;/button&gt;</span>\n  <span class=\"nt\">&lt;button&gt;</span>Cancel<span class=\"nt\">&lt;/button&gt;</span>\n<span class=\"nt\">&lt;/div&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"testing\">Testing</h2>\n\n<h3 id=\"automated-testing\">Automated Testing</h3>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\"># Install pa11y</span>\nnpm <span class=\"nb\">install</span> <span class=\"nt\">-g</span> pa11y\n\n<span class=\"c\"># Run accessibility test</span>\npa11y https://yoursite.com\n\n<span class=\"c\"># Test multiple pages</span>\npa11y-ci <span class=\"nt\">--sitemap</span> https://yoursite.com/sitemap.xml\n</code></pre></div></div>\n\n<h3 id=\"manual-testing\">Manual Testing</h3>\n\n<ol>\n  <li><strong>Keyboard only</strong>: Navigate entire site with Tab, Enter, Space, Arrow keys</li>\n  <li><strong>Screen reader</strong>: Test with NVDA (Windows), JAWS (Windows), VoiceOver (macOS/iOS)</li>\n  <li><strong>Zoom</strong>: Test at 200% zoom</li>\n  <li><strong>Color blind mode</strong>: Use browser extensions</li>\n  <li><strong>High contrast</strong>: Test with Windows High Contrast mode</li>\n</ol>\n\n<h3 id=\"checklist\">Checklist</h3>\n\n<ul class=\"task-list\">\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />All images have alt text</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Sufficient color contrast (4.5:1 minimum)</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Keyboard navigation works throughout</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Focus indicators are visible</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Form inputs have labels</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Headings follow logical hierarchy</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Links have descriptive text</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />ARIA labels for icon buttons</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Skip links implemented</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />No keyboard traps</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Error messages are descriptive</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Live regions for dynamic content</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Modal focus management</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Video captions available</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Works with screen readers</li>\n</ul>\n\n<h2 id=\"common-issues\">Common Issues</h2>\n\n<h3 id=\"issue-low-contrast\">Issue: Low Contrast</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Bad: 2.1:1 ratio */</span>\n<span class=\"nc\">.link</span> <span class=\"p\">{</span>\n  <span class=\"nl\">color</span><span class=\"p\">:</span> <span class=\"m\">#666666</span><span class=\"p\">;</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"m\">#ffffff</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Good: 7.0:1 ratio */</span>\n<span class=\"nc\">.link</span> <span class=\"p\">{</span>\n  <span class=\"nl\">color</span><span class=\"p\">:</span> <span class=\"m\">#333333</span><span class=\"p\">;</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"m\">#ffffff</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h3 id=\"issue-missing-labels\">Issue: Missing Labels</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Bad --&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"search\"</span> <span class=\"na\">placeholder=</span><span class=\"s\">\"Search\"</span> <span class=\"nt\">/&gt;</span>\n\n<span class=\"c\">&lt;!-- Good --&gt;</span>\n<span class=\"nt\">&lt;label</span> <span class=\"na\">for=</span><span class=\"s\">\"search\"</span><span class=\"nt\">&gt;</span>Search<span class=\"nt\">&lt;/label&gt;</span>\n<span class=\"nt\">&lt;input</span> <span class=\"na\">type=</span><span class=\"s\">\"search\"</span> <span class=\"na\">id=</span><span class=\"s\">\"search\"</span> <span class=\"na\">placeholder=</span><span class=\"s\">\"Search\"</span> <span class=\"nt\">/&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"issue-click-handlers-on-divs\">Issue: Click Handlers on Divs</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Bad --&gt;</span>\n<span class=\"nt\">&lt;div</span> <span class=\"na\">onclick=</span><span class=\"s\">\"doSomething()\"</span><span class=\"nt\">&gt;</span>Click me<span class=\"nt\">&lt;/div&gt;</span>\n\n<span class=\"c\">&lt;!-- Good --&gt;</span>\n<span class=\"nt\">&lt;button</span> <span class=\"na\">onclick=</span><span class=\"s\">\"doSomething()\"</span><span class=\"nt\">&gt;</span>Click me<span class=\"nt\">&lt;/button&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"resources\">Resources</h2>\n\n<ul>\n  <li><a href=\"https://www.w3.org/WAI/WCAG21/quickref/\">WCAG 2.1 Guidelines</a></li>\n  <li><a href=\"https://webaim.org/\">WebAIM</a> - Training and tools</li>\n  <li><a href=\"https://www.a11yproject.com/\">A11y Project</a> - Community-driven resources</li>\n  <li><a href=\"https://www.w3.org/WAI/ARIA/apg/\">ARIA Authoring Practices</a> - Design patterns</li>\n  <li><a href=\"https://webaim.org/resources/contrastchecker/\">Color Contrast Checker</a></li>\n</ul>\n\n<h2 id=\"next-steps\">Next Steps</h2>\n\n<ul>\n  <li><a href=\"performance.html\">Performance Guide</a> - Fast and accessible</li>\n  <li><a href=\"seo-guide.html\">SEO Guide</a> - Accessible and discoverable</li>\n  <li><a href=\"browser-support.html\">Browser Support</a> - Cross-browser accessibility</li>\n</ul>\n</article>\n\n        <section\n          class=\"feedback-card\"\n          id=\"feedback-card\"\n          aria-label=\"Page feedback\"\n        >\n          <div class=\"feedback-header\">\n            <div>\n              <p class=\"feedback-kicker\">Feedback</p>\n              <h3>Was this page helpful?</h3>\n              <p class=\"feedback-subtext\">\n                Share quick feedback to improve these docs.\n              </p>\n            </div>\n            <div class=\"feedback-badges\" aria-label=\"Applies to versions\">\n                  \n              <span class=\"version-badge\" aria-label=\"Minecraft 1.21.x\"\n                >1.21.x</span\n              >\n               \n            </div>\n          </div>\n\n          <div class=\"feedback-actions\" role=\"group\" aria-label=\"Helpful?\">\n            <button type=\"button\" class=\"feedback-btn yes\" data-feedback=\"yes\">\n              <i class=\"fa-solid fa-thumbs-up\"></i>\n              Yes\n            </button>\n            <button type=\"button\" class=\"feedback-btn no\" data-feedback=\"no\">\n              <i class=\"fa-solid fa-thumbs-down\"></i>\n              No\n            </button>\n          </div>\n\n          <div class=\"feedback-followup\" id=\"feedback-followup\" hidden>\n            <label for=\"feedback-notes\">What can we improve?</label>\n            <textarea\n              id=\"feedback-notes\"\n              rows=\"3\"\n              placeholder=\"Optional: missing steps, unclear wording, broken links\"\n            ></textarea>\n            <button type=\"button\" class=\"feedback-submit\" id=\"feedback-submit\">\n              <i class=\"fa-solid fa-paper-plane\"></i>\n              Send feedback\n            </button>\n          </div>\n\n          <p\n            class=\"feedback-status\"\n            id=\"feedback-status\"\n            role=\"status\"\n            aria-live=\"polite\"\n          ></p>\n        </section>\n\n        <!-- Page Navigation (Prev/Next) -->\n                                                 \n      </main>\n\n      <!-- Table of Contents (optional) -->\n      <aside class=\"docs-toc\">\n        <div class=\"toc-header\">\n          <h3>On This Page</h3>\n        </div>\n        <nav id=\"toc-nav\" class=\"toc-nav\">\n          <!-- Generated by JavaScript -->\n        </nav>\n\n        <!-- Theme Toggle in TOC -->\n        <button\n          id=\"theme-toggle-docs\"\n          class=\"theme-toggle\"\n          aria-label=\"Toggle theme\"\n        >\n          <i class=\"fa-solid fa-sun\"></i>\n          <i class=\"fa-solid fa-moon\"></i>\n        </button>\n      </aside>\n    </div>\n\n    <script>\n      // Theme Toggle\n      const themeToggle = document.getElementById(\"theme-toggle-docs\");\n      themeToggle?.addEventListener(\"click\", () => {\n        const current = document.documentElement.getAttribute(\"data-theme\");\n        const next = current === \"light\" ? \"dark\" : \"light\";\n        document.documentElement.setAttribute(\"data-theme\", next);\n        localStorage.setItem(\"theme\", next);\n      });\n\n      // Mobile Sidebar Toggle\n      const mobileToggle = document.getElementById(\"mobile-sidebar-toggle\");\n      const sidebar = document.getElementById(\"docs-sidebar\");\n      const overlay = document.getElementById(\"sidebar-overlay\");\n      const sidebarClose = document.getElementById(\"sidebar-close\");\n\n      function toggleSidebar() {\n        sidebar.classList.toggle(\"open\");\n        overlay.classList.toggle(\"active\");\n        document.body.style.overflow = sidebar.classList.contains(\"open\")\n          ? \"hidden\"\n          : \"\";\n      }\n\n      mobileToggle?.addEventListener(\"click\", toggleSidebar);\n      overlay?.addEventListener(\"click\", toggleSidebar);\n      sidebarClose?.addEventListener(\"click\", toggleSidebar);\n\n      // Category Toggle\n      document.querySelectorAll(\".category-toggle\").forEach((toggle) => {\n        toggle.addEventListener(\"click\", () => {\n          const category = toggle.dataset.category;\n          const items = document.getElementById(`category-${category}`);\n          toggle.classList.toggle(\"active\");\n          items.classList.toggle(\"expanded\");\n        });\n      });\n\n      // Generate Table of Contents\n      const content = document.querySelector(\".docs-content article\");\n      const tocNav = document.getElementById(\"toc-nav\");\n\n      if (content && tocNav) {\n        const headings = content.querySelectorAll(\"h2, h3\");\n\n        if (headings.length > 0) {\n          headings.forEach((heading, index) => {\n            // Add ID if not present\n            if (!heading.id) {\n              heading.id = heading.textContent\n                .toLowerCase()\n                .replace(/[^a-z0-9]+/g, \"-\")\n                .replace(/^-|-$/g, \"\");\n            }\n\n            const link = document.createElement(\"a\");\n            link.href = `#${heading.id}`;\n            link.textContent = heading.textContent;\n            link.className = `toc-link toc-${heading.tagName.toLowerCase()}`;\n            tocNav.appendChild(link);\n          });\n\n          // Highlight current section\n          const observer = new IntersectionObserver(\n            (entries) => {\n              entries.forEach((entry) => {\n                if (entry.isIntersecting) {\n                  const id = entry.target.id;\n                  tocNav.querySelectorAll(\".toc-link\").forEach((link) => {\n                    link.classList.toggle(\n                      \"active\",\n                      link.getAttribute(\"href\") === `#${id}`\n                    );\n                  });\n                }\n              });\n            },\n            { rootMargin: \"-20% 0px -80% 0px\" }\n          );\n\n          headings.forEach((heading) => observer.observe(heading));\n        }\n      }\n\n      // Sidebar Search\n      const sidebarSearch = document.getElementById(\"sidebar-search\");\n      sidebarSearch?.addEventListener(\"input\", (e) => {\n        const query = e.target.value.toLowerCase();\n        const items = document.querySelectorAll(\".nav-item\");\n\n        items.forEach((item) => {\n          const text = item.textContent.toLowerCase();\n          const matches = text.includes(query);\n          item.style.display = matches || !query ? \"\" : \"none\";\n\n          // Expand category if item matches\n          if (matches && query) {\n            const category = item.closest(\".category-items\");\n            const toggle = category?.previousElementSibling;\n            category?.classList.add(\"expanded\");\n            toggle?.classList.add(\"active\");\n          }\n        });\n      });\n\n      // Docs micro-feedback (local only)\n      const feedbackCard = document.getElementById(\"feedback-card\");\n      const feedbackButtons = document.querySelectorAll(\".feedback-btn\");\n      const feedbackFollowup = document.getElementById(\"feedback-followup\");\n      const feedbackSubmit = document.getElementById(\"feedback-submit\");\n      const feedbackStatus = document.getElementById(\"feedback-status\");\n      const feedbackNotes = document.getElementById(\"feedback-notes\");\n      const feedbackStorageKey = `docs-feedback:${window.location.pathname}`;\n\n      function completeFeedback(message) {\n        if (feedbackCard) feedbackCard.classList.add(\"feedback-complete\");\n        if (feedbackFollowup) feedbackFollowup.hidden = true;\n        if (feedbackStatus) feedbackStatus.textContent = message;\n        try {\n          localStorage.setItem(feedbackStorageKey, \"submitted\");\n        } catch (err) {\n          console.warn(\"Feedback storage failed\", err);\n        }\n      }\n\n      function maybeDisableFeedback() {\n        let stored = null;\n        try {\n          stored = localStorage.getItem(feedbackStorageKey);\n        } catch (err) {\n          console.warn(\"Feedback storage read failed\", err);\n        }\n\n        if (stored && feedbackCard) {\n          feedbackCard.classList.add(\"feedback-complete\");\n          if (feedbackFollowup) feedbackFollowup.hidden = true;\n          if (feedbackStatus)\n            feedbackStatus.textContent = \"Thanks—feedback already recorded.\";\n        }\n      }\n\n      feedbackButtons.forEach((btn) => {\n        btn.addEventListener(\"click\", () => {\n          const value = btn.dataset.feedback;\n          if (value === \"no\") {\n            if (feedbackFollowup) feedbackFollowup.hidden = false;\n            if (feedbackStatus)\n              feedbackStatus.textContent = \"Tell us what to improve.\";\n          } else {\n            completeFeedback(\"Thanks for the feedback!\");\n          }\n        });\n      });\n\n      feedbackSubmit?.addEventListener(\"click\", () => {\n        const note = feedbackNotes?.value?.trim();\n        const suffix = note ? \" We will review your note.\" : \"\";\n        completeFeedback(`Got it!${suffix}`);\n      });\n\n      maybeDisableFeedback();\n    </script>\n  </body>\n</html>\n","<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"dark\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>\n      Adding Modpacks | Minecraft Mods & Packs Showcase\n    </title>\n\n    <!-- Stylesheets -->\n    <link rel=\"stylesheet\" href=\"/assets/css/main.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/layout.css\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/modpacks.css\"\n    />\n    <link rel=\"stylesheet\" href=\"/assets/css/docs.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n    />\n\n    <script>\n      if (!document.body) {\n        console.warn(\"Body not ready, skipping preloader\");\n      } else {\n        window.addEventListener(\"load\", () => {\n          document.body.classList.add(\"loaded\");\n        });\n      }\n\n      const savedTheme = localStorage.getItem(\"theme\") || \"dark\";\n      document.documentElement.setAttribute(\"data-theme\", savedTheme);\n    </script>\n  </head>\n  <body>\n    <!-- Preloader -->\n    <div class=\"preloader\">\n      <div class=\"spinner\"></div>\n    </div>\n\n    <!-- Mobile Menu Toggle -->\n    <button\n      id=\"mobile-sidebar-toggle\"\n      class=\"mobile-sidebar-toggle\"\n      aria-label=\"Toggle sidebar\"\n    >\n      <i class=\"fa-solid fa-bars\"></i>\n    </button>\n\n    <!-- Docs Sidebar -->\n    <aside id=\"docs-sidebar\" class=\"docs-sidebar\">\n      <div class=\"sidebar-header\">\n        <a href=\"/\" class=\"sidebar-logo\">\n          <i class=\"fa-solid fa-cube\"></i>\n          <span>Minecraft Mods & Packs Showcase</span>\n        </a>\n        <button\n          id=\"sidebar-close\"\n          class=\"sidebar-close\"\n          aria-label=\"Close sidebar\"\n        >\n          <i class=\"fa-solid fa-times\"></i>\n        </button>\n      </div>\n\n      <!-- Search in Sidebar -->\n      <div class=\"sidebar-search\">\n        <input\n          type=\"search\"\n          id=\"sidebar-search\"\n          placeholder=\"Search docs...\"\n          aria-label=\"Search documentation\"\n        />\n        <i class=\"fa-solid fa-search\"></i>\n      </div>\n\n      <!-- Navigation Tree -->\n      <nav class=\"sidebar-nav\">\n            \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"setup\"\n          >\n            <i\n              class=\"fa-solid fa-gear \"\n            ></i>\n            <span>Setup</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-setup\"\n          >\n            \n             \n            <a\n              href=\"/docs/getting-started/\"\n              class=\"nav-item \"\n            >\n              Getting Started\n            </a>\n              \n            <a\n              href=\"/docs/setup/\"\n              class=\"nav-item \"\n            >\n              Setup & Configuration\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"styling\"\n          >\n            <i\n              class=\"fa-solid fa-palette \"\n            ></i>\n            <span>Styling</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-styling\"\n          >\n            \n             \n            <a\n              href=\"/docs/customization/\"\n              class=\"nav-item \"\n            >\n              Customization\n            </a>\n              \n            <a\n              href=\"/docs/css-variables/\"\n              class=\"nav-item \"\n            >\n              CSS Variables Reference\n            </a>\n             \n          </div>\n        </div>\n              \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"community\"\n          >\n            <i\n              class=\"fa-solid fa-users \"\n            ></i>\n            <span>Community</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-community\"\n          >\n            \n             \n            <a\n              href=\"/docs/contributing/\"\n              class=\"nav-item \"\n            >\n              Contributing\n            </a>\n              \n            <a\n              href=\"/docs/content-guidelines/\"\n              class=\"nav-item \"\n            >\n              Content Guidelines\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"developer\"\n          >\n            <i\n              class=\"fa-solid fa-code \"\n            ></i>\n            <span>Developer</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-developer\"\n          >\n            \n             \n            <a\n              href=\"/docs/api-reference/\"\n              class=\"nav-item \"\n            >\n              API Reference\n            </a>\n              \n            <a\n              href=\"/docs/deployment/\"\n              class=\"nav-item \"\n            >\n              Deployment Guide\n            </a>\n              \n            <a\n              href=\"/docs/github-actions/\"\n              class=\"nav-item \"\n            >\n              GitHub Actions\n            </a>\n              \n            <a\n              href=\"/docs/project-structure/\"\n              class=\"nav-item \"\n            >\n              Project Structure\n            </a>\n              \n            <a\n              href=\"/docs/liquid-templates/\"\n              class=\"nav-item \"\n            >\n              Liquid Templates\n            </a>\n              \n            <a\n              href=\"/docs/performance/\"\n              class=\"nav-item \"\n            >\n              Performance Optimization\n            </a>\n              \n            <a\n              href=\"/docs/seo-guide/\"\n              class=\"nav-item \"\n            >\n              SEO Guide\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"help\"\n          >\n            <i\n              class=\"fa-solid fa-circle-question \"\n            ></i>\n            <span>Help</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-help\"\n          >\n            \n             \n            <a\n              href=\"/docs/faq/\"\n              class=\"nav-item \"\n            >\n              FAQ\n            </a>\n              \n            <a\n              href=\"/docs/troubleshooting/\"\n              class=\"nav-item \"\n            >\n              Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/accessibility/\"\n              class=\"nav-item \"\n            >\n              Accessibility Guide\n            </a>\n              \n            <a\n              href=\"/docs/common-errors/\"\n              class=\"nav-item \"\n            >\n              Common Errors & Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/browser-support/\"\n              class=\"nav-item \"\n            >\n              Browser Support\n            </a>\n             \n          </div>\n        </div>\n         \n      </nav>\n\n      <!-- Quick Links -->\n      <div class=\"sidebar-footer\">\n        <a href=\"/docs/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-home\"></i>\n          All Docs\n        </a>\n        <a href=\"/projects/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-folder\"></i>\n          Projects\n        </a>\n      </div>\n    </aside>\n\n    <!-- Sidebar Overlay (for mobile) -->\n    <div id=\"sidebar-overlay\" class=\"sidebar-overlay\"></div>\n\n    <!-- Main Content -->\n    <div class=\"docs-layout\">\n      <!-- Breadcrumbs -->\n      \n      <nav class=\"breadcrumbs\" aria-label=\"Breadcrumb\">\n        <a href=\"/\">\n          <i class=\"fa-solid fa-home\"></i>\n          Home\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a href=\"/docs/\">Docs</a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a\n          href=\"/docs-category-user-guide/\"\n        >\n          User Guide\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <span class=\"current\">Adding Modpacks</span>\n      </nav>\n      \n\n      <!-- Page Content -->\n      <main class=\"docs-content\">\n        <article><h1 id=\"adding-modpacks\">Adding Modpacks</h1>\n\n<p>Learn how to add new modpacks to your ABC showcase.</p>\n\n<h2 id=\"quick-start\">Quick Start</h2>\n\n<h3 id=\"1-locate-the-data-file\">1. Locate the Data File</h3>\n\n<p>Find <code class=\"language-plaintext highlighter-rouge\">_data/mods.json</code> in your project root.</p>\n\n<h3 id=\"2-add-modpack-entry\">2. Add Modpack Entry</h3>\n\n<p>Add your modpack to the <code class=\"language-plaintext highlighter-rouge\">modpacks</code> array:</p>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{</span><span class=\"w\">\n  </span><span class=\"nl\">\"modpacks\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"w\">\n    </span><span class=\"p\">{</span><span class=\"w\">\n      </span><span class=\"nl\">\"slug\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"your-modpack-slug\"</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"name\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"Your Modpack Name\"</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"description\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"A brief description of your modpack\"</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"icon_url\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"https://cdn.modrinth.com/data/PROJECT_ID/icon.png\"</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"downloads\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"mi\">5000</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"followers\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"mi\">150</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"categories\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"s2\">\"adventure\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"technology\"</span><span class=\"p\">],</span><span class=\"w\">\n      </span><span class=\"nl\">\"game_versions\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"s2\">\"1.20.1\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"1.19.2\"</span><span class=\"p\">],</span><span class=\"w\">\n      </span><span class=\"nl\">\"loaders\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"s2\">\"fabric\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"forge\"</span><span class=\"p\">],</span><span class=\"w\">\n      </span><span class=\"nl\">\"source_url\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"https://modrinth.com/modpack/your-modpack-slug\"</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"repository\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"https://github.com/username/your-modpack\"</span><span class=\"p\">,</span><span class=\"w\">\n      </span><span class=\"nl\">\"updated_at\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"2025-12-10T10:00:00Z\"</span><span class=\"w\">\n    </span><span class=\"p\">}</span><span class=\"w\">\n  </span><span class=\"p\">]</span><span class=\"w\">\n</span><span class=\"p\">}</span><span class=\"w\">\n</span></code></pre></div></div>\n\n<h3 id=\"3-rebuild-site\">3. Rebuild Site</h3>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>bundle <span class=\"nb\">exec </span>jekyll build\n</code></pre></div></div>\n\n<h2 id=\"field-reference\">Field Reference</h2>\n\n<h3 id=\"required-fields\">Required Fields</h3>\n\n<table>\n  <thead>\n    <tr>\n      <th>Field</th>\n      <th>Type</th>\n      <th>Description</th>\n      <th>Example</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">slug</code></td>\n      <td>string</td>\n      <td>Unique identifier (URL-safe)</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">\"awesome-pack\"</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">name</code></td>\n      <td>string</td>\n      <td>Display name</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">\"Awesome Modpack\"</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">description</code></td>\n      <td>string</td>\n      <td>Brief description (1-2 sentences)</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">\"A tech-focused modpack...\"</code></td>\n    </tr>\n  </tbody>\n</table>\n\n<h3 id=\"optional-fields\">Optional Fields</h3>\n\n<table>\n  <thead>\n    <tr>\n      <th>Field</th>\n      <th>Type</th>\n      <th>Description</th>\n      <th>Example</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">icon_url</code></td>\n      <td>string</td>\n      <td>URL to 512x512 icon</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">\"https://cdn.modrinth.com/...\"</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">downloads</code></td>\n      <td>number</td>\n      <td>Total download count</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">50000</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">followers</code></td>\n      <td>number</td>\n      <td>Follower count</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">1200</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">categories</code></td>\n      <td>array</td>\n      <td>Category tags</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">[\"tech\", \"adventure\"]</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">game_versions</code></td>\n      <td>array</td>\n      <td>Supported MC versions</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">[\"1.20.1\"]</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">loaders</code></td>\n      <td>array</td>\n      <td>Mod loaders</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">[\"fabric\", \"forge\"]</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">source_url</code></td>\n      <td>string</td>\n      <td>Modrinth/CF page</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">\"https://modrinth.com/...\"</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">repository</code></td>\n      <td>string</td>\n      <td>GitHub repo URL</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">\"https://github.com/...\"</code></td>\n    </tr>\n    <tr>\n      <td><code class=\"language-plaintext highlighter-rouge\">updated_at</code></td>\n      <td>string</td>\n      <td>Last update (ISO 8601)</td>\n      <td><code class=\"language-plaintext highlighter-rouge\">\"2025-12-10T10:00:00Z\"</code></td>\n    </tr>\n  </tbody>\n</table>\n\n<h2 id=\"from-modrinth\">From Modrinth</h2>\n\n<h3 id=\"manual-method\">Manual Method</h3>\n\n<ol>\n  <li><strong>Find your modpack</strong> on <a href=\"https://modrinth.com/\">Modrinth</a></li>\n  <li><strong>Copy project data</strong> from the page</li>\n  <li><strong>Add to <code class=\"language-plaintext highlighter-rouge\">_data/mods.json</code></strong></li>\n</ol>\n\n<h3 id=\"automated-method\">Automated Method</h3>\n\n<p>Create a script to fetch from Modrinth API:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\"># Save as scripts/add-modpack.sh</span>\n<span class=\"c\">#!/bin/bash</span>\n\n<span class=\"nv\">SLUG</span><span class=\"o\">=</span><span class=\"nv\">$1</span>\n<span class=\"nv\">API_URL</span><span class=\"o\">=</span><span class=\"s2\">\"https://api.modrinth.com/v2/project/</span><span class=\"nv\">$SLUG</span><span class=\"s2\">\"</span>\n\n<span class=\"c\"># Fetch data</span>\n<span class=\"nv\">DATA</span><span class=\"o\">=</span><span class=\"si\">$(</span>curl <span class=\"nt\">-s</span> <span class=\"s2\">\"</span><span class=\"nv\">$API_URL</span><span class=\"s2\">\"</span><span class=\"si\">)</span>\n\n<span class=\"c\"># Extract fields</span>\n<span class=\"nv\">NAME</span><span class=\"o\">=</span><span class=\"si\">$(</span><span class=\"nb\">echo</span> <span class=\"s2\">\"</span><span class=\"nv\">$DATA</span><span class=\"s2\">\"</span> | jq <span class=\"nt\">-r</span> <span class=\"s1\">'.title'</span><span class=\"si\">)</span>\n<span class=\"nv\">DESC</span><span class=\"o\">=</span><span class=\"si\">$(</span><span class=\"nb\">echo</span> <span class=\"s2\">\"</span><span class=\"nv\">$DATA</span><span class=\"s2\">\"</span> | jq <span class=\"nt\">-r</span> <span class=\"s1\">'.description'</span><span class=\"si\">)</span>\n<span class=\"nv\">ICON</span><span class=\"o\">=</span><span class=\"si\">$(</span><span class=\"nb\">echo</span> <span class=\"s2\">\"</span><span class=\"nv\">$DATA</span><span class=\"s2\">\"</span> | jq <span class=\"nt\">-r</span> <span class=\"s1\">'.icon_url'</span><span class=\"si\">)</span>\n<span class=\"nv\">DOWNLOADS</span><span class=\"o\">=</span><span class=\"si\">$(</span><span class=\"nb\">echo</span> <span class=\"s2\">\"</span><span class=\"nv\">$DATA</span><span class=\"s2\">\"</span> | jq <span class=\"nt\">-r</span> <span class=\"s1\">'.downloads'</span><span class=\"si\">)</span>\n<span class=\"nv\">FOLLOWERS</span><span class=\"o\">=</span><span class=\"si\">$(</span><span class=\"nb\">echo</span> <span class=\"s2\">\"</span><span class=\"nv\">$DATA</span><span class=\"s2\">\"</span> | jq <span class=\"nt\">-r</span> <span class=\"s1\">'.followers'</span><span class=\"si\">)</span>\n\n<span class=\"nb\">echo</span> <span class=\"s2\">\"Adding: </span><span class=\"nv\">$NAME</span><span class=\"s2\">\"</span>\n\n<span class=\"c\"># TODO: Append to _data/mods.json</span>\n<span class=\"c\"># (Implementation left as exercise)</span>\n</code></pre></div></div>\n\n<p>Usage:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nb\">chmod</span> +x scripts/add-modpack.sh\n./scripts/add-modpack.sh your-modpack-slug\n</code></pre></div></div>\n\n<h3 id=\"using-nodejs\">Using Node.js</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// scripts/add-modpack.js</span>\n<span class=\"kd\">const</span> <span class=\"nx\">fs</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">fs</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n\n<span class=\"k\">async</span> <span class=\"kd\">function</span> <span class=\"nx\">addModpack</span><span class=\"p\">(</span><span class=\"nx\">slug</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"kd\">const</span> <span class=\"nx\">response</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"nx\">fetch</span><span class=\"p\">(</span><span class=\"s2\">`https://api.modrinth.com/v2/project/</span><span class=\"p\">${</span><span class=\"nx\">slug</span><span class=\"p\">}</span><span class=\"s2\">`</span><span class=\"p\">);</span>\n  <span class=\"kd\">const</span> <span class=\"nx\">data</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"nx\">response</span><span class=\"p\">.</span><span class=\"nx\">json</span><span class=\"p\">();</span>\n\n  <span class=\"kd\">const</span> <span class=\"nx\">modpack</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"na\">slug</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">slug</span><span class=\"p\">,</span>\n    <span class=\"na\">name</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">title</span><span class=\"p\">,</span>\n    <span class=\"na\">description</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">description</span><span class=\"p\">,</span>\n    <span class=\"na\">icon_url</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">icon_url</span><span class=\"p\">,</span>\n    <span class=\"na\">downloads</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">downloads</span><span class=\"p\">,</span>\n    <span class=\"na\">followers</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">followers</span><span class=\"p\">,</span>\n    <span class=\"na\">categories</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">categories</span><span class=\"p\">,</span>\n    <span class=\"na\">game_versions</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">game_versions</span><span class=\"p\">,</span>\n    <span class=\"na\">loaders</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">loaders</span><span class=\"p\">,</span>\n    <span class=\"na\">source_url</span><span class=\"p\">:</span> <span class=\"s2\">`https://modrinth.com/modpack/</span><span class=\"p\">${</span><span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">slug</span><span class=\"p\">}</span><span class=\"s2\">`</span><span class=\"p\">,</span>\n    <span class=\"na\">repository</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">source_url</span><span class=\"p\">,</span>\n    <span class=\"na\">updated_at</span><span class=\"p\">:</span> <span class=\"nx\">data</span><span class=\"p\">.</span><span class=\"nx\">updated</span><span class=\"p\">,</span>\n  <span class=\"p\">};</span>\n\n  <span class=\"c1\">// Read existing data</span>\n  <span class=\"kd\">const</span> <span class=\"nx\">modsData</span> <span class=\"o\">=</span> <span class=\"nx\">JSON</span><span class=\"p\">.</span><span class=\"nx\">parse</span><span class=\"p\">(</span><span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">readFileSync</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">_data/mods.json</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">utf8</span><span class=\"dl\">\"</span><span class=\"p\">));</span>\n\n  <span class=\"c1\">// Add new modpack</span>\n  <span class=\"nx\">modsData</span><span class=\"p\">.</span><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">push</span><span class=\"p\">(</span><span class=\"nx\">modpack</span><span class=\"p\">);</span>\n\n  <span class=\"c1\">// Write back</span>\n  <span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">writeFileSync</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">_data/mods.json</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"nx\">JSON</span><span class=\"p\">.</span><span class=\"nx\">stringify</span><span class=\"p\">(</span><span class=\"nx\">modsData</span><span class=\"p\">,</span> <span class=\"kc\">null</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">));</span>\n\n  <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"s2\">`Added: </span><span class=\"p\">${</span><span class=\"nx\">modpack</span><span class=\"p\">.</span><span class=\"nx\">name</span><span class=\"p\">}</span><span class=\"s2\">`</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n\n<span class=\"c1\">// Usage: node scripts/add-modpack.js your-modpack-slug</span>\n<span class=\"kd\">const</span> <span class=\"nx\">slug</span> <span class=\"o\">=</span> <span class=\"nx\">process</span><span class=\"p\">.</span><span class=\"nx\">argv</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">];</span>\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">slug</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nx\">addModpack</span><span class=\"p\">(</span><span class=\"nx\">slug</span><span class=\"p\">);</span>\n<span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n  <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">Usage: node add-modpack.js &lt;slug&gt;</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<p>Run it:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>node scripts/add-modpack.js awesome-pack\n</code></pre></div></div>\n\n<h2 id=\"custom-icons\">Custom Icons</h2>\n\n<h3 id=\"upload-to-repository\">Upload to Repository</h3>\n\n<ol>\n  <li><strong>Add icon</strong> to <code class=\"language-plaintext highlighter-rouge\">assets/images/modpacks/</code></li>\n  <li><strong>Reference in JSON</strong>:</li>\n</ol>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{</span><span class=\"w\">\n  </span><span class=\"nl\">\"icon_url\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"/assets/images/modpacks/my-pack-icon.png\"</span><span class=\"w\">\n</span><span class=\"p\">}</span><span class=\"w\">\n</span></code></pre></div></div>\n\n<h3 id=\"requirements\">Requirements</h3>\n\n<ul>\n  <li><strong>Format</strong>: PNG or WebP</li>\n  <li><strong>Size</strong>: 512x512px recommended</li>\n  <li><strong>Max file size</strong>: 500KB</li>\n  <li><strong>Transparency</strong>: Supported</li>\n</ul>\n\n<h3 id=\"optimize-icons\">Optimize Icons</h3>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\"># Resize to 512x512</span>\nmagick convert original.png <span class=\"nt\">-resize</span> 512x512 icon.png\n\n<span class=\"c\"># Optimize PNG</span>\npngquant <span class=\"nt\">--quality</span> 65-80 icon.png\n\n<span class=\"c\"># Convert to WebP</span>\nmagick convert icon.png <span class=\"nt\">-quality</span> 80 icon.webp\n</code></pre></div></div>\n\n<h2 id=\"categories\">Categories</h2>\n\n<h3 id=\"available-categories\">Available Categories</h3>\n\n<p>Use these standard categories:</p>\n\n<ul>\n  <li><code class=\"language-plaintext highlighter-rouge\">adventure</code> - Adventure &amp; exploration</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">technology</code> - Tech &amp; automation</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">magic</code> - Magic &amp; spells</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">decoration</code> - Building &amp; decoration</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">utility</code> - Quality of life</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">optimization</code> - Performance mods</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">cursed</code> - Experimental/chaotic</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">kitchen-sink</code> - Everything included</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">lightweight</code> - Minimal modpacks</li>\n  <li><code class=\"language-plaintext highlighter-rouge\">multiplayer</code> - Server-friendly</li>\n</ul>\n\n<h3 id=\"custom-categories\">Custom Categories</h3>\n\n<p>Add your own:</p>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{</span><span class=\"w\">\n  </span><span class=\"nl\">\"categories\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"s2\">\"custom-category\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"another-category\"</span><span class=\"p\">]</span><span class=\"w\">\n</span><span class=\"p\">}</span><span class=\"w\">\n</span></code></pre></div></div>\n\n<p>Style them in CSS:</p>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nc\">.pill</span><span class=\"o\">[</span><span class=\"nt\">data-category</span><span class=\"o\">=</span><span class=\"s1\">\"custom-category\"</span><span class=\"o\">]</span> <span class=\"p\">{</span>\n  <span class=\"py\">--pill-bg</span><span class=\"p\">:</span> <span class=\"n\">rgba</span><span class=\"p\">(</span><span class=\"m\">255</span><span class=\"p\">,</span> <span class=\"m\">87</span><span class=\"p\">,</span> <span class=\"m\">34</span><span class=\"p\">,</span> <span class=\"m\">0.15</span><span class=\"p\">);</span>\n  <span class=\"py\">--pill-text</span><span class=\"p\">:</span> <span class=\"m\">#ff5722</span><span class=\"p\">;</span>\n  <span class=\"py\">--pill-border</span><span class=\"p\">:</span> <span class=\"m\">#ff5722</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"bulk-import\">Bulk Import</h2>\n\n<h3 id=\"from-json-file\">From JSON File</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// scripts/bulk-import.js</span>\n<span class=\"kd\">const</span> <span class=\"nx\">fs</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">fs</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n\n<span class=\"kd\">const</span> <span class=\"nx\">newModpacks</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n  <span class=\"p\">{</span> <span class=\"na\">slug</span><span class=\"p\">:</span> <span class=\"dl\">\"</span><span class=\"s2\">pack-1</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"na\">name</span><span class=\"p\">:</span> <span class=\"dl\">\"</span><span class=\"s2\">Pack One</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"na\">description</span><span class=\"p\">:</span> <span class=\"dl\">\"</span><span class=\"s2\">Description...</span><span class=\"dl\">\"</span> <span class=\"p\">},</span>\n  <span class=\"p\">{</span> <span class=\"na\">slug</span><span class=\"p\">:</span> <span class=\"dl\">\"</span><span class=\"s2\">pack-2</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"na\">name</span><span class=\"p\">:</span> <span class=\"dl\">\"</span><span class=\"s2\">Pack Two</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"na\">description</span><span class=\"p\">:</span> <span class=\"dl\">\"</span><span class=\"s2\">Description...</span><span class=\"dl\">\"</span> <span class=\"p\">},</span>\n  <span class=\"c1\">// ... more modpacks</span>\n<span class=\"p\">];</span>\n\n<span class=\"kd\">const</span> <span class=\"nx\">modsData</span> <span class=\"o\">=</span> <span class=\"nx\">JSON</span><span class=\"p\">.</span><span class=\"nx\">parse</span><span class=\"p\">(</span><span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">readFileSync</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">_data/mods.json</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">utf8</span><span class=\"dl\">\"</span><span class=\"p\">));</span>\n<span class=\"nx\">modsData</span><span class=\"p\">.</span><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">push</span><span class=\"p\">(...</span><span class=\"nx\">newModpacks</span><span class=\"p\">);</span>\n<span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">writeFileSync</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">_data/mods.json</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"nx\">JSON</span><span class=\"p\">.</span><span class=\"nx\">stringify</span><span class=\"p\">(</span><span class=\"nx\">modsData</span><span class=\"p\">,</span> <span class=\"kc\">null</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">));</span>\n\n<span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"s2\">`Imported </span><span class=\"p\">${</span><span class=\"nx\">newModpacks</span><span class=\"p\">.</span><span class=\"nx\">length</span><span class=\"p\">}</span><span class=\"s2\"> modpacks`</span><span class=\"p\">);</span>\n</code></pre></div></div>\n\n<h3 id=\"from-csv\">From CSV</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// scripts/import-csv.js</span>\n<span class=\"kd\">const</span> <span class=\"nx\">fs</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">fs</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n<span class=\"kd\">const</span> <span class=\"nx\">csv</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">csv-parser</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n\n<span class=\"kd\">const</span> <span class=\"nx\">modpacks</span> <span class=\"o\">=</span> <span class=\"p\">[];</span>\n\n<span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">createReadStream</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">modpacks.csv</span><span class=\"dl\">\"</span><span class=\"p\">)</span>\n  <span class=\"p\">.</span><span class=\"nx\">pipe</span><span class=\"p\">(</span><span class=\"nx\">csv</span><span class=\"p\">())</span>\n  <span class=\"p\">.</span><span class=\"nx\">on</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">data</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"p\">(</span><span class=\"nx\">row</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">push</span><span class=\"p\">({</span>\n      <span class=\"na\">slug</span><span class=\"p\">:</span> <span class=\"nx\">row</span><span class=\"p\">.</span><span class=\"nx\">slug</span><span class=\"p\">,</span>\n      <span class=\"na\">name</span><span class=\"p\">:</span> <span class=\"nx\">row</span><span class=\"p\">.</span><span class=\"nx\">name</span><span class=\"p\">,</span>\n      <span class=\"na\">description</span><span class=\"p\">:</span> <span class=\"nx\">row</span><span class=\"p\">.</span><span class=\"nx\">description</span><span class=\"p\">,</span>\n      <span class=\"na\">icon_url</span><span class=\"p\">:</span> <span class=\"nx\">row</span><span class=\"p\">.</span><span class=\"nx\">icon_url</span><span class=\"p\">,</span>\n      <span class=\"na\">downloads</span><span class=\"p\">:</span> <span class=\"nb\">parseInt</span><span class=\"p\">(</span><span class=\"nx\">row</span><span class=\"p\">.</span><span class=\"nx\">downloads</span><span class=\"p\">)</span> <span class=\"o\">||</span> <span class=\"mi\">0</span><span class=\"p\">,</span>\n      <span class=\"na\">categories</span><span class=\"p\">:</span> <span class=\"nx\">row</span><span class=\"p\">.</span><span class=\"nx\">categories</span> <span class=\"p\">?</span> <span class=\"nx\">row</span><span class=\"p\">.</span><span class=\"nx\">categories</span><span class=\"p\">.</span><span class=\"nx\">split</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">,</span><span class=\"dl\">\"</span><span class=\"p\">)</span> <span class=\"p\">:</span> <span class=\"p\">[],</span>\n    <span class=\"p\">});</span>\n  <span class=\"p\">})</span>\n  <span class=\"p\">.</span><span class=\"nx\">on</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">end</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"p\">()</span> <span class=\"o\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"kd\">const</span> <span class=\"nx\">modsData</span> <span class=\"o\">=</span> <span class=\"nx\">JSON</span><span class=\"p\">.</span><span class=\"nx\">parse</span><span class=\"p\">(</span><span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">readFileSync</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">_data/mods.json</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">utf8</span><span class=\"dl\">\"</span><span class=\"p\">));</span>\n    <span class=\"nx\">modsData</span><span class=\"p\">.</span><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">push</span><span class=\"p\">(...</span><span class=\"nx\">modpacks</span><span class=\"p\">);</span>\n    <span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">writeFileSync</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">_data/mods.json</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"nx\">JSON</span><span class=\"p\">.</span><span class=\"nx\">stringify</span><span class=\"p\">(</span><span class=\"nx\">modsData</span><span class=\"p\">,</span> <span class=\"kc\">null</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">));</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"s2\">`Imported </span><span class=\"p\">${</span><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">length</span><span class=\"p\">}</span><span class=\"s2\"> modpacks`</span><span class=\"p\">);</span>\n  <span class=\"p\">});</span>\n</code></pre></div></div>\n\n<p>CSV format:</p>\n\n<pre><code class=\"language-csv\">slug,name,description,icon_url,downloads,categories\nawesome-pack,Awesome Pack,A great modpack,https://...,5000,\"tech,adventure\"\n</code></pre>\n\n<h2 id=\"sorting--ordering\">Sorting &amp; Ordering</h2>\n\n<h3 id=\"sort-by-downloads\">Sort by Downloads</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// In JavaScript rendering</span>\n<span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">sort</span><span class=\"p\">((</span><span class=\"nx\">a</span><span class=\"p\">,</span> <span class=\"nx\">b</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">downloads</span> <span class=\"o\">-</span> <span class=\"nx\">a</span><span class=\"p\">.</span><span class=\"nx\">downloads</span><span class=\"p\">);</span>\n</code></pre></div></div>\n\n<h3 id=\"sort-alphabetically\">Sort Alphabetically</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">sort</span><span class=\"p\">((</span><span class=\"nx\">a</span><span class=\"p\">,</span> <span class=\"nx\">b</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"nx\">a</span><span class=\"p\">.</span><span class=\"nx\">name</span><span class=\"p\">.</span><span class=\"nx\">localeCompare</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">name</span><span class=\"p\">));</span>\n</code></pre></div></div>\n\n<h3 id=\"sort-by-update-date\">Sort by Update Date</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">sort</span><span class=\"p\">((</span><span class=\"nx\">a</span><span class=\"p\">,</span> <span class=\"nx\">b</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"k\">new</span> <span class=\"nb\">Date</span><span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">updated_at</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"k\">new</span> <span class=\"nb\">Date</span><span class=\"p\">(</span><span class=\"nx\">a</span><span class=\"p\">.</span><span class=\"nx\">updated_at</span><span class=\"p\">));</span>\n</code></pre></div></div>\n\n<h3 id=\"custom-order\">Custom Order</h3>\n\n<p>Add <code class=\"language-plaintext highlighter-rouge\">order</code> field:</p>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{</span><span class=\"w\">\n  </span><span class=\"nl\">\"slug\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"featured-pack\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"name\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"Featured Pack\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"order\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"mi\">1</span><span class=\"w\">\n</span><span class=\"p\">}</span><span class=\"w\">\n</span></code></pre></div></div>\n\n<p>Sort by order:</p>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">sort</span><span class=\"p\">((</span><span class=\"nx\">a</span><span class=\"p\">,</span> <span class=\"nx\">b</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"p\">(</span><span class=\"nx\">a</span><span class=\"p\">.</span><span class=\"nx\">order</span> <span class=\"o\">||</span> <span class=\"mi\">999</span><span class=\"p\">)</span> <span class=\"o\">-</span> <span class=\"p\">(</span><span class=\"nx\">b</span><span class=\"p\">.</span><span class=\"nx\">order</span> <span class=\"o\">||</span> <span class=\"mi\">999</span><span class=\"p\">));</span>\n</code></pre></div></div>\n\n<h2 id=\"validation\">Validation</h2>\n\n<h3 id=\"validate-json\">Validate JSON</h3>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\"># Check JSON is valid</span>\n<span class=\"nb\">cat </span>_data/mods.json | python <span class=\"nt\">-m</span> json.tool\n\n<span class=\"c\"># Or with jq</span>\njq <span class=\"s1\">'.'</span> _data/mods.json\n\n<span class=\"c\"># Or with Node.js</span>\nnode <span class=\"nt\">-e</span> <span class=\"s2\">\"console.log(JSON.parse(require('fs').readFileSync('_data/mods.json', 'utf8')))\"</span>\n</code></pre></div></div>\n\n<h3 id=\"validate-schema\">Validate Schema</h3>\n\n<p>Create validation script:</p>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// scripts/validate-mods.js</span>\n<span class=\"kd\">const</span> <span class=\"nx\">fs</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">fs</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n\n<span class=\"kd\">const</span> <span class=\"nx\">modsData</span> <span class=\"o\">=</span> <span class=\"nx\">JSON</span><span class=\"p\">.</span><span class=\"nx\">parse</span><span class=\"p\">(</span><span class=\"nx\">fs</span><span class=\"p\">.</span><span class=\"nx\">readFileSync</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">_data/mods.json</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">utf8</span><span class=\"dl\">\"</span><span class=\"p\">));</span>\n\n<span class=\"nx\">modsData</span><span class=\"p\">.</span><span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">forEach</span><span class=\"p\">((</span><span class=\"nx\">mod</span><span class=\"p\">,</span> <span class=\"nx\">index</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Check required fields</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nx\">mod</span><span class=\"p\">.</span><span class=\"nx\">slug</span><span class=\"p\">)</span> <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">(</span><span class=\"s2\">`Modpack </span><span class=\"p\">${</span><span class=\"nx\">index</span><span class=\"p\">}</span><span class=\"s2\">: Missing slug`</span><span class=\"p\">);</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nx\">mod</span><span class=\"p\">.</span><span class=\"nx\">name</span><span class=\"p\">)</span> <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">(</span><span class=\"s2\">`Modpack </span><span class=\"p\">${</span><span class=\"nx\">index</span><span class=\"p\">}</span><span class=\"s2\">: Missing name`</span><span class=\"p\">);</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nx\">mod</span><span class=\"p\">.</span><span class=\"nx\">description</span><span class=\"p\">)</span> <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">(</span><span class=\"s2\">`Modpack </span><span class=\"p\">${</span><span class=\"nx\">index</span><span class=\"p\">}</span><span class=\"s2\">: Missing description`</span><span class=\"p\">);</span>\n\n  <span class=\"c1\">// Check slug format</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">mod</span><span class=\"p\">.</span><span class=\"nx\">slug</span> <span class=\"o\">&amp;&amp;</span> <span class=\"o\">!</span><span class=\"sr\">/^</span><span class=\"se\">[</span><span class=\"sr\">a-z0-9-</span><span class=\"se\">]</span><span class=\"sr\">+$/</span><span class=\"p\">.</span><span class=\"nx\">test</span><span class=\"p\">(</span><span class=\"nx\">mod</span><span class=\"p\">.</span><span class=\"nx\">slug</span><span class=\"p\">))</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">(</span><span class=\"s2\">`Modpack </span><span class=\"p\">${</span><span class=\"nx\">index</span><span class=\"p\">}</span><span class=\"s2\">: Invalid slug format`</span><span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n\n  <span class=\"c1\">// Check downloads type</span>\n  <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">mod</span><span class=\"p\">.</span><span class=\"nx\">downloads</span> <span class=\"o\">&amp;&amp;</span> <span class=\"k\">typeof</span> <span class=\"nx\">mod</span><span class=\"p\">.</span><span class=\"nx\">downloads</span> <span class=\"o\">!==</span> <span class=\"dl\">\"</span><span class=\"s2\">number</span><span class=\"dl\">\"</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">error</span><span class=\"p\">(</span><span class=\"s2\">`Modpack </span><span class=\"p\">${</span><span class=\"nx\">index</span><span class=\"p\">}</span><span class=\"s2\">: downloads must be a number`</span><span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">});</span>\n\n<span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">Validation complete</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n</code></pre></div></div>\n\n<p>Run:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>node scripts/validate-mods.js\n</code></pre></div></div>\n\n<h2 id=\"auto-update-from-modrinth\">Auto-Update from Modrinth</h2>\n\n<p>Set up automatic updates:</p>\n\n<div class=\"language-yaml highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\"># .github/workflows/update-mods.yml</span>\n<span class=\"na\">name</span><span class=\"pi\">:</span> <span class=\"s\">Update Modpack Data</span>\n\n<span class=\"na\">on</span><span class=\"pi\">:</span>\n  <span class=\"na\">schedule</span><span class=\"pi\">:</span>\n    <span class=\"pi\">-</span> <span class=\"na\">cron</span><span class=\"pi\">:</span> <span class=\"s2\">\"</span><span class=\"s\">0</span><span class=\"nv\"> </span><span class=\"s\">0</span><span class=\"nv\"> </span><span class=\"s\">*</span><span class=\"nv\"> </span><span class=\"s\">*</span><span class=\"nv\"> </span><span class=\"s\">*\"</span> <span class=\"c1\"># Daily at midnight</span>\n  <span class=\"na\">workflow_dispatch</span><span class=\"pi\">:</span>\n\n<span class=\"na\">jobs</span><span class=\"pi\">:</span>\n  <span class=\"na\">update</span><span class=\"pi\">:</span>\n    <span class=\"na\">runs-on</span><span class=\"pi\">:</span> <span class=\"s\">ubuntu-latest</span>\n    <span class=\"na\">steps</span><span class=\"pi\">:</span>\n      <span class=\"pi\">-</span> <span class=\"na\">uses</span><span class=\"pi\">:</span> <span class=\"s\">actions/checkout@v4</span>\n\n      <span class=\"pi\">-</span> <span class=\"na\">name</span><span class=\"pi\">:</span> <span class=\"s\">Setup Node</span>\n        <span class=\"na\">uses</span><span class=\"pi\">:</span> <span class=\"s\">actions/setup-node@v4</span>\n        <span class=\"na\">with</span><span class=\"pi\">:</span>\n          <span class=\"na\">node-version</span><span class=\"pi\">:</span> <span class=\"s2\">\"</span><span class=\"s\">18\"</span>\n\n      <span class=\"pi\">-</span> <span class=\"na\">name</span><span class=\"pi\">:</span> <span class=\"s\">Update data</span>\n        <span class=\"na\">run</span><span class=\"pi\">:</span> <span class=\"s\">node scripts/update-modrinth.js</span>\n\n      <span class=\"pi\">-</span> <span class=\"na\">name</span><span class=\"pi\">:</span> <span class=\"s\">Commit changes</span>\n        <span class=\"na\">uses</span><span class=\"pi\">:</span> <span class=\"s\">stefanzweifel/git-auto-commit-action@v5</span>\n        <span class=\"na\">with</span><span class=\"pi\">:</span>\n          <span class=\"na\">commit_message</span><span class=\"pi\">:</span> <span class=\"s2\">\"</span><span class=\"s\">chore:</span><span class=\"nv\"> </span><span class=\"s\">update</span><span class=\"nv\"> </span><span class=\"s\">modpack</span><span class=\"nv\"> </span><span class=\"s\">data\"</span>\n          <span class=\"na\">file_pattern</span><span class=\"pi\">:</span> <span class=\"s2\">\"</span><span class=\"s\">_data/mods.json\"</span>\n</code></pre></div></div>\n\n<h2 id=\"troubleshooting\">Troubleshooting</h2>\n\n<h3 id=\"issue-modpack-not-showing\">Issue: Modpack Not Showing</h3>\n\n<p><strong>Check</strong>:</p>\n\n<ol>\n  <li>JSON is valid (no syntax errors)</li>\n  <li>Required fields present (<code class=\"language-plaintext highlighter-rouge\">slug</code>, <code class=\"language-plaintext highlighter-rouge\">name</code>, <code class=\"language-plaintext highlighter-rouge\">description</code>)</li>\n  <li>Rebuild site: <code class=\"language-plaintext highlighter-rouge\">bundle exec jekyll build</code></li>\n  <li>Check browser console for errors</li>\n</ol>\n\n<h3 id=\"issue-icon-not-displaying\">Issue: Icon Not Displaying</h3>\n\n<p><strong>Solutions</strong>:</p>\n\n<ul>\n  <li>Verify <code class=\"language-plaintext highlighter-rouge\">icon_url</code> is correct</li>\n  <li>Check image exists and is accessible</li>\n  <li>Try full URL instead of relative path</li>\n  <li>Ensure image is not too large (&lt; 1MB)</li>\n</ul>\n\n<h3 id=\"issue-duplicate-slugs\">Issue: Duplicate Slugs</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// Find duplicates</span>\n<span class=\"kd\">const</span> <span class=\"nx\">slugs</span> <span class=\"o\">=</span> <span class=\"nx\">modpacks</span><span class=\"p\">.</span><span class=\"nx\">map</span><span class=\"p\">((</span><span class=\"nx\">m</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"nx\">m</span><span class=\"p\">.</span><span class=\"nx\">slug</span><span class=\"p\">);</span>\n<span class=\"kd\">const</span> <span class=\"nx\">duplicates</span> <span class=\"o\">=</span> <span class=\"nx\">slugs</span><span class=\"p\">.</span><span class=\"nx\">filter</span><span class=\"p\">((</span><span class=\"nx\">s</span><span class=\"p\">,</span> <span class=\"nx\">i</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"nx\">slugs</span><span class=\"p\">.</span><span class=\"nx\">indexOf</span><span class=\"p\">(</span><span class=\"nx\">s</span><span class=\"p\">)</span> <span class=\"o\">!==</span> <span class=\"nx\">i</span><span class=\"p\">);</span>\n<span class=\"nx\">console</span><span class=\"p\">.</span><span class=\"nx\">log</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">Duplicates:</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"nx\">duplicates</span><span class=\"p\">);</span>\n</code></pre></div></div>\n\n<h2 id=\"best-practices\">Best Practices</h2>\n\n<ol>\n  <li><strong>Use descriptive slugs</strong>: <code class=\"language-plaintext highlighter-rouge\">create-tech-pack</code> not <code class=\"language-plaintext highlighter-rouge\">pack1</code></li>\n  <li><strong>Keep descriptions concise</strong>: 1-2 sentences</li>\n  <li><strong>Optimize icons</strong>: 512x512px, &lt; 500KB</li>\n  <li><strong>Include all relevant tags</strong>: Helps with filtering</li>\n  <li><strong>Update regularly</strong>: Keep download counts fresh</li>\n  <li><strong>Validate before committing</strong>: Catch errors early</li>\n  <li><strong>Use semantic versioning</strong>: For game_versions</li>\n  <li><strong>Link to sources</strong>: Always include <code class=\"language-plaintext highlighter-rouge\">source_url</code></li>\n</ol>\n\n<h2 id=\"next-steps\">Next Steps</h2>\n\n<ul>\n  <li><a href=\"content-guidelines.html\">Content Guidelines</a> - Writing standards</li>\n  <li><a href=\"api-reference.html\">API Reference</a> - Data structure details</li>\n  <li><a href=\"github-actions.html\">GitHub Actions</a> - Automate updates</li>\n</ul>\n</article>\n\n        <section\n          class=\"feedback-card\"\n          id=\"feedback-card\"\n          aria-label=\"Page feedback\"\n        >\n          <div class=\"feedback-header\">\n            <div>\n              <p class=\"feedback-kicker\">Feedback</p>\n              <h3>Was this page helpful?</h3>\n              <p class=\"feedback-subtext\">\n                Share quick feedback to improve these docs.\n              </p>\n            </div>\n            <div class=\"feedback-badges\" aria-label=\"Applies to versions\">\n                  \n              <span class=\"version-badge\" aria-label=\"Minecraft 1.21.x\"\n                >1.21.x</span\n              >\n               \n            </div>\n          </div>\n\n          <div class=\"feedback-actions\" role=\"group\" aria-label=\"Helpful?\">\n            <button type=\"button\" class=\"feedback-btn yes\" data-feedback=\"yes\">\n              <i class=\"fa-solid fa-thumbs-up\"></i>\n              Yes\n            </button>\n            <button type=\"button\" class=\"feedback-btn no\" data-feedback=\"no\">\n              <i class=\"fa-solid fa-thumbs-down\"></i>\n              No\n            </button>\n          </div>\n\n          <div class=\"feedback-followup\" id=\"feedback-followup\" hidden>\n            <label for=\"feedback-notes\">What can we improve?</label>\n            <textarea\n              id=\"feedback-notes\"\n              rows=\"3\"\n              placeholder=\"Optional: missing steps, unclear wording, broken links\"\n            ></textarea>\n            <button type=\"button\" class=\"feedback-submit\" id=\"feedback-submit\">\n              <i class=\"fa-solid fa-paper-plane\"></i>\n              Send feedback\n            </button>\n          </div>\n\n          <p\n            class=\"feedback-status\"\n            id=\"feedback-status\"\n            role=\"status\"\n            aria-live=\"polite\"\n          ></p>\n        </section>\n\n        <!-- Page Navigation (Prev/Next) -->\n                                                 \n      </main>\n\n      <!-- Table of Contents (optional) -->\n      <aside class=\"docs-toc\">\n        <div class=\"toc-header\">\n          <h3>On This Page</h3>\n        </div>\n        <nav id=\"toc-nav\" class=\"toc-nav\">\n          <!-- Generated by JavaScript -->\n        </nav>\n\n        <!-- Theme Toggle in TOC -->\n        <button\n          id=\"theme-toggle-docs\"\n          class=\"theme-toggle\"\n          aria-label=\"Toggle theme\"\n        >\n          <i class=\"fa-solid fa-sun\"></i>\n          <i class=\"fa-solid fa-moon\"></i>\n        </button>\n      </aside>\n    </div>\n\n    <script>\n      // Theme Toggle\n      const themeToggle = document.getElementById(\"theme-toggle-docs\");\n      themeToggle?.addEventListener(\"click\", () => {\n        const current = document.documentElement.getAttribute(\"data-theme\");\n        const next = current === \"light\" ? \"dark\" : \"light\";\n        document.documentElement.setAttribute(\"data-theme\", next);\n        localStorage.setItem(\"theme\", next);\n      });\n\n      // Mobile Sidebar Toggle\n      const mobileToggle = document.getElementById(\"mobile-sidebar-toggle\");\n      const sidebar = document.getElementById(\"docs-sidebar\");\n      const overlay = document.getElementById(\"sidebar-overlay\");\n      const sidebarClose = document.getElementById(\"sidebar-close\");\n\n      function toggleSidebar() {\n        sidebar.classList.toggle(\"open\");\n        overlay.classList.toggle(\"active\");\n        document.body.style.overflow = sidebar.classList.contains(\"open\")\n          ? \"hidden\"\n          : \"\";\n      }\n\n      mobileToggle?.addEventListener(\"click\", toggleSidebar);\n      overlay?.addEventListener(\"click\", toggleSidebar);\n      sidebarClose?.addEventListener(\"click\", toggleSidebar);\n\n      // Category Toggle\n      document.querySelectorAll(\".category-toggle\").forEach((toggle) => {\n        toggle.addEventListener(\"click\", () => {\n          const category = toggle.dataset.category;\n          const items = document.getElementById(`category-${category}`);\n          toggle.classList.toggle(\"active\");\n          items.classList.toggle(\"expanded\");\n        });\n      });\n\n      // Generate Table of Contents\n      const content = document.querySelector(\".docs-content article\");\n      const tocNav = document.getElementById(\"toc-nav\");\n\n      if (content && tocNav) {\n        const headings = content.querySelectorAll(\"h2, h3\");\n\n        if (headings.length > 0) {\n          headings.forEach((heading, index) => {\n            // Add ID if not present\n            if (!heading.id) {\n              heading.id = heading.textContent\n                .toLowerCase()\n                .replace(/[^a-z0-9]+/g, \"-\")\n                .replace(/^-|-$/g, \"\");\n            }\n\n            const link = document.createElement(\"a\");\n            link.href = `#${heading.id}`;\n            link.textContent = heading.textContent;\n            link.className = `toc-link toc-${heading.tagName.toLowerCase()}`;\n            tocNav.appendChild(link);\n          });\n\n          // Highlight current section\n          const observer = new IntersectionObserver(\n            (entries) => {\n              entries.forEach((entry) => {\n                if (entry.isIntersecting) {\n                  const id = entry.target.id;\n                  tocNav.querySelectorAll(\".toc-link\").forEach((link) => {\n                    link.classList.toggle(\n                      \"active\",\n                      link.getAttribute(\"href\") === `#${id}`\n                    );\n                  });\n                }\n              });\n            },\n            { rootMargin: \"-20% 0px -80% 0px\" }\n          );\n\n          headings.forEach((heading) => observer.observe(heading));\n        }\n      }\n\n      // Sidebar Search\n      const sidebarSearch = document.getElementById(\"sidebar-search\");\n      sidebarSearch?.addEventListener(\"input\", (e) => {\n        const query = e.target.value.toLowerCase();\n        const items = document.querySelectorAll(\".nav-item\");\n\n        items.forEach((item) => {\n          const text = item.textContent.toLowerCase();\n          const matches = text.includes(query);\n          item.style.display = matches || !query ? \"\" : \"none\";\n\n          // Expand category if item matches\n          if (matches && query) {\n            const category = item.closest(\".category-items\");\n            const toggle = category?.previousElementSibling;\n            category?.classList.add(\"expanded\");\n            toggle?.classList.add(\"active\");\n          }\n        });\n      });\n\n      // Docs micro-feedback (local only)\n      const feedbackCard = document.getElementById(\"feedback-card\");\n      const feedbackButtons = document.querySelectorAll(\".feedback-btn\");\n      const feedbackFollowup = document.getElementById(\"feedback-followup\");\n      const feedbackSubmit = document.getElementById(\"feedback-submit\");\n      const feedbackStatus = document.getElementById(\"feedback-status\");\n      const feedbackNotes = document.getElementById(\"feedback-notes\");\n      const feedbackStorageKey = `docs-feedback:${window.location.pathname}`;\n\n      function completeFeedback(message) {\n        if (feedbackCard) feedbackCard.classList.add(\"feedback-complete\");\n        if (feedbackFollowup) feedbackFollowup.hidden = true;\n        if (feedbackStatus) feedbackStatus.textContent = message;\n        try {\n          localStorage.setItem(feedbackStorageKey, \"submitted\");\n        } catch (err) {\n          console.warn(\"Feedback storage failed\", err);\n        }\n      }\n\n      function maybeDisableFeedback() {\n        let stored = null;\n        try {\n          stored = localStorage.getItem(feedbackStorageKey);\n        } catch (err) {\n          console.warn(\"Feedback storage read failed\", err);\n        }\n\n        if (stored && feedbackCard) {\n          feedbackCard.classList.add(\"feedback-complete\");\n          if (feedbackFollowup) feedbackFollowup.hidden = true;\n          if (feedbackStatus)\n            feedbackStatus.textContent = \"Thanks—feedback already recorded.\";\n        }\n      }\n\n      feedbackButtons.forEach((btn) => {\n        btn.addEventListener(\"click\", () => {\n          const value = btn.dataset.feedback;\n          if (value === \"no\") {\n            if (feedbackFollowup) feedbackFollowup.hidden = false;\n            if (feedbackStatus)\n              feedbackStatus.textContent = \"Tell us what to improve.\";\n          } else {\n            completeFeedback(\"Thanks for the feedback!\");\n          }\n        });\n      });\n\n      feedbackSubmit?.addEventListener(\"click\", () => {\n        const note = feedbackNotes?.value?.trim();\n        const suffix = note ? \" We will review your note.\" : \"\";\n        completeFeedback(`Got it!${suffix}`);\n      });\n\n      maybeDisableFeedback();\n    </script>\n  </body>\n</html>\n","<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"dark\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>\n      API Reference | Minecraft Mods & Packs Showcase\n    </title>\n\n    <!-- Stylesheets -->\n    <link rel=\"stylesheet\" href=\"/assets/css/main.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/layout.css\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/modpacks.css\"\n    />\n    <link rel=\"stylesheet\" href=\"/assets/css/docs.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n    />\n\n    <script>\n      if (!document.body) {\n        console.warn(\"Body not ready, skipping preloader\");\n      } else {\n        window.addEventListener(\"load\", () => {\n          document.body.classList.add(\"loaded\");\n        });\n      }\n\n      const savedTheme = localStorage.getItem(\"theme\") || \"dark\";\n      document.documentElement.setAttribute(\"data-theme\", savedTheme);\n    </script>\n  </head>\n  <body>\n    <!-- Preloader -->\n    <div class=\"preloader\">\n      <div class=\"spinner\"></div>\n    </div>\n\n    <!-- Mobile Menu Toggle -->\n    <button\n      id=\"mobile-sidebar-toggle\"\n      class=\"mobile-sidebar-toggle\"\n      aria-label=\"Toggle sidebar\"\n    >\n      <i class=\"fa-solid fa-bars\"></i>\n    </button>\n\n    <!-- Docs Sidebar -->\n    <aside id=\"docs-sidebar\" class=\"docs-sidebar\">\n      <div class=\"sidebar-header\">\n        <a href=\"/\" class=\"sidebar-logo\">\n          <i class=\"fa-solid fa-cube\"></i>\n          <span>Minecraft Mods & Packs Showcase</span>\n        </a>\n        <button\n          id=\"sidebar-close\"\n          class=\"sidebar-close\"\n          aria-label=\"Close sidebar\"\n        >\n          <i class=\"fa-solid fa-times\"></i>\n        </button>\n      </div>\n\n      <!-- Search in Sidebar -->\n      <div class=\"sidebar-search\">\n        <input\n          type=\"search\"\n          id=\"sidebar-search\"\n          placeholder=\"Search docs...\"\n          aria-label=\"Search documentation\"\n        />\n        <i class=\"fa-solid fa-search\"></i>\n      </div>\n\n      <!-- Navigation Tree -->\n      <nav class=\"sidebar-nav\">\n            \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"setup\"\n          >\n            <i\n              class=\"fa-solid fa-gear \"\n            ></i>\n            <span>Setup</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-setup\"\n          >\n            \n             \n            <a\n              href=\"/docs/getting-started/\"\n              class=\"nav-item \"\n            >\n              Getting Started\n            </a>\n              \n            <a\n              href=\"/docs/setup/\"\n              class=\"nav-item \"\n            >\n              Setup & Configuration\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"styling\"\n          >\n            <i\n              class=\"fa-solid fa-palette \"\n            ></i>\n            <span>Styling</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-styling\"\n          >\n            \n             \n            <a\n              href=\"/docs/customization/\"\n              class=\"nav-item \"\n            >\n              Customization\n            </a>\n              \n            <a\n              href=\"/docs/css-variables/\"\n              class=\"nav-item \"\n            >\n              CSS Variables Reference\n            </a>\n             \n          </div>\n        </div>\n              \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"community\"\n          >\n            <i\n              class=\"fa-solid fa-users \"\n            ></i>\n            <span>Community</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-community\"\n          >\n            \n             \n            <a\n              href=\"/docs/contributing/\"\n              class=\"nav-item \"\n            >\n              Contributing\n            </a>\n              \n            <a\n              href=\"/docs/content-guidelines/\"\n              class=\"nav-item \"\n            >\n              Content Guidelines\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle active\"\n            data-category=\"developer\"\n          >\n            <i\n              class=\"fa-solid fa-code \"\n            ></i>\n            <span>Developer</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items expanded\"\n            id=\"category-developer\"\n          >\n            \n             \n            <a\n              href=\"/docs/api-reference/\"\n              class=\"nav-item active\"\n            >\n              API Reference\n            </a>\n              \n            <a\n              href=\"/docs/deployment/\"\n              class=\"nav-item \"\n            >\n              Deployment Guide\n            </a>\n              \n            <a\n              href=\"/docs/github-actions/\"\n              class=\"nav-item \"\n            >\n              GitHub Actions\n            </a>\n              \n            <a\n              href=\"/docs/project-structure/\"\n              class=\"nav-item \"\n            >\n              Project Structure\n            </a>\n              \n            <a\n              href=\"/docs/liquid-templates/\"\n              class=\"nav-item \"\n            >\n              Liquid Templates\n            </a>\n              \n            <a\n              href=\"/docs/performance/\"\n              class=\"nav-item \"\n            >\n              Performance Optimization\n            </a>\n              \n            <a\n              href=\"/docs/seo-guide/\"\n              class=\"nav-item \"\n            >\n              SEO Guide\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"help\"\n          >\n            <i\n              class=\"fa-solid fa-circle-question \"\n            ></i>\n            <span>Help</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-help\"\n          >\n            \n             \n            <a\n              href=\"/docs/faq/\"\n              class=\"nav-item \"\n            >\n              FAQ\n            </a>\n              \n            <a\n              href=\"/docs/troubleshooting/\"\n              class=\"nav-item \"\n            >\n              Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/accessibility/\"\n              class=\"nav-item \"\n            >\n              Accessibility Guide\n            </a>\n              \n            <a\n              href=\"/docs/common-errors/\"\n              class=\"nav-item \"\n            >\n              Common Errors & Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/browser-support/\"\n              class=\"nav-item \"\n            >\n              Browser Support\n            </a>\n             \n          </div>\n        </div>\n         \n      </nav>\n\n      <!-- Quick Links -->\n      <div class=\"sidebar-footer\">\n        <a href=\"/docs/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-home\"></i>\n          All Docs\n        </a>\n        <a href=\"/projects/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-folder\"></i>\n          Projects\n        </a>\n      </div>\n    </aside>\n\n    <!-- Sidebar Overlay (for mobile) -->\n    <div id=\"sidebar-overlay\" class=\"sidebar-overlay\"></div>\n\n    <!-- Main Content -->\n    <div class=\"docs-layout\">\n      <!-- Breadcrumbs -->\n      \n      <nav class=\"breadcrumbs\" aria-label=\"Breadcrumb\">\n        <a href=\"/\">\n          <i class=\"fa-solid fa-home\"></i>\n          Home\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a href=\"/docs/\">Docs</a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a\n          href=\"/docs-category-developer/\"\n        >\n          Developer\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <span class=\"current\">API Reference</span>\n      </nav>\n      \n\n      <!-- Page Content -->\n      <main class=\"docs-content\">\n        <article><h2 id=\"project-data-structure\">Project Data Structure</h2>\n\n<p>The <code class=\"language-plaintext highlighter-rouge\">data/mods.json</code> file contains project data pulled from Modrinth. Here’s the structure:</p>\n\n<div class=\"language-json highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"p\">{</span><span class=\"w\">\n  </span><span class=\"nl\">\"id\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"project_id\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"slug\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"project-slug\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"name\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"Project Name\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"title\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"Display Title\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"description\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"Full description...\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"short_description\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"Brief summary\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"project_type\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"mod|plugin|resourcepack|etc\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"author\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"author_name\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"thumbnail\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"https://cdn.modrinth.com/...\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"icon_url\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"https://cdn.modrinth.com/...\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"download\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"https://modrinth.com/mod/...\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"categories\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"s2\">\"category1\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"category2\"</span><span class=\"p\">],</span><span class=\"w\">\n  </span><span class=\"nl\">\"loaders\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"s2\">\"fabric\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"forge\"</span><span class=\"p\">],</span><span class=\"w\">\n  </span><span class=\"nl\">\"game_versions\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"p\">[</span><span class=\"s2\">\"1.20\"</span><span class=\"p\">,</span><span class=\"w\"> </span><span class=\"s2\">\"1.20.1\"</span><span class=\"p\">],</span><span class=\"w\">\n  </span><span class=\"nl\">\"downloads\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"mi\">12345</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"followers\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"mi\">678</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"published\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"2025-01-01T00:00:00Z\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"updated\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"2025-12-10T07:24:19Z\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"license_id\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"MIT\"</span><span class=\"p\">,</span><span class=\"w\">\n  </span><span class=\"nl\">\"source_url\"</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"s2\">\"https://github.com/...\"</span><span class=\"w\">\n</span><span class=\"p\">}</span><span class=\"w\">\n</span></code></pre></div></div>\n\n<h2 id=\"accessing-data-in-templates\">Accessing Data in Templates</h2>\n\n<p>Use Liquid templates to access project data:</p>\n\n<div class=\"language-liquid highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>\n</code></pre></div></div>\n\n<h2 id=\"modrinth-api\">Modrinth API</h2>\n\n<p>The site uses Modrinth’s public API to fetch project data. No authentication required for public projects.</p>\n\n<p><strong>Endpoint:</strong> <code class=\"language-plaintext highlighter-rouge\">https://api.modrinth.com/v2/organization/{id}/projects</code></p>\n\n<p><strong>Example:</strong></p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>curl https://api.modrinth.com/v2/organization/abcxyz/projects\n</code></pre></div></div>\n\n<hr />\n\n<p>See <a href=\"setup\">Setup &amp; Configuration</a> for more about data integration.</p>\n</article>\n\n        <section\n          class=\"feedback-card\"\n          id=\"feedback-card\"\n          aria-label=\"Page feedback\"\n        >\n          <div class=\"feedback-header\">\n            <div>\n              <p class=\"feedback-kicker\">Feedback</p>\n              <h3>Was this page helpful?</h3>\n              <p class=\"feedback-subtext\">\n                Share quick feedback to improve these docs.\n              </p>\n            </div>\n            <div class=\"feedback-badges\" aria-label=\"Applies to versions\">\n                  \n              <span class=\"version-badge\" aria-label=\"Minecraft 1.21.x\"\n                >1.21.x</span\n              >\n               \n            </div>\n          </div>\n\n          <div class=\"feedback-actions\" role=\"group\" aria-label=\"Helpful?\">\n            <button type=\"button\" class=\"feedback-btn yes\" data-feedback=\"yes\">\n              <i class=\"fa-solid fa-thumbs-up\"></i>\n              Yes\n            </button>\n            <button type=\"button\" class=\"feedback-btn no\" data-feedback=\"no\">\n              <i class=\"fa-solid fa-thumbs-down\"></i>\n              No\n            </button>\n          </div>\n\n          <div class=\"feedback-followup\" id=\"feedback-followup\" hidden>\n            <label for=\"feedback-notes\">What can we improve?</label>\n            <textarea\n              id=\"feedback-notes\"\n              rows=\"3\"\n              placeholder=\"Optional: missing steps, unclear wording, broken links\"\n            ></textarea>\n            <button type=\"button\" class=\"feedback-submit\" id=\"feedback-submit\">\n              <i class=\"fa-solid fa-paper-plane\"></i>\n              Send feedback\n            </button>\n          </div>\n\n          <p\n            class=\"feedback-status\"\n            id=\"feedback-status\"\n            role=\"status\"\n            aria-live=\"polite\"\n          ></p>\n        </section>\n\n        <!-- Page Navigation (Prev/Next) -->\n                                                 \n      </main>\n\n      <!-- Table of Contents (optional) -->\n      <aside class=\"docs-toc\">\n        <div class=\"toc-header\">\n          <h3>On This Page</h3>\n        </div>\n        <nav id=\"toc-nav\" class=\"toc-nav\">\n          <!-- Generated by JavaScript -->\n        </nav>\n\n        <!-- Theme Toggle in TOC -->\n        <button\n          id=\"theme-toggle-docs\"\n          class=\"theme-toggle\"\n          aria-label=\"Toggle theme\"\n        >\n          <i class=\"fa-solid fa-sun\"></i>\n          <i class=\"fa-solid fa-moon\"></i>\n        </button>\n      </aside>\n    </div>\n\n    <script>\n      // Theme Toggle\n      const themeToggle = document.getElementById(\"theme-toggle-docs\");\n      themeToggle?.addEventListener(\"click\", () => {\n        const current = document.documentElement.getAttribute(\"data-theme\");\n        const next = current === \"light\" ? \"dark\" : \"light\";\n        document.documentElement.setAttribute(\"data-theme\", next);\n        localStorage.setItem(\"theme\", next);\n      });\n\n      // Mobile Sidebar Toggle\n      const mobileToggle = document.getElementById(\"mobile-sidebar-toggle\");\n      const sidebar = document.getElementById(\"docs-sidebar\");\n      const overlay = document.getElementById(\"sidebar-overlay\");\n      const sidebarClose = document.getElementById(\"sidebar-close\");\n\n      function toggleSidebar() {\n        sidebar.classList.toggle(\"open\");\n        overlay.classList.toggle(\"active\");\n        document.body.style.overflow = sidebar.classList.contains(\"open\")\n          ? \"hidden\"\n          : \"\";\n      }\n\n      mobileToggle?.addEventListener(\"click\", toggleSidebar);\n      overlay?.addEventListener(\"click\", toggleSidebar);\n      sidebarClose?.addEventListener(\"click\", toggleSidebar);\n\n      // Category Toggle\n      document.querySelectorAll(\".category-toggle\").forEach((toggle) => {\n        toggle.addEventListener(\"click\", () => {\n          const category = toggle.dataset.category;\n          const items = document.getElementById(`category-${category}`);\n          toggle.classList.toggle(\"active\");\n          items.classList.toggle(\"expanded\");\n        });\n      });\n\n      // Generate Table of Contents\n      const content = document.querySelector(\".docs-content article\");\n      const tocNav = document.getElementById(\"toc-nav\");\n\n      if (content && tocNav) {\n        const headings = content.querySelectorAll(\"h2, h3\");\n\n        if (headings.length > 0) {\n          headings.forEach((heading, index) => {\n            // Add ID if not present\n            if (!heading.id) {\n              heading.id = heading.textContent\n                .toLowerCase()\n                .replace(/[^a-z0-9]+/g, \"-\")\n                .replace(/^-|-$/g, \"\");\n            }\n\n            const link = document.createElement(\"a\");\n            link.href = `#${heading.id}`;\n            link.textContent = heading.textContent;\n            link.className = `toc-link toc-${heading.tagName.toLowerCase()}`;\n            tocNav.appendChild(link);\n          });\n\n          // Highlight current section\n          const observer = new IntersectionObserver(\n            (entries) => {\n              entries.forEach((entry) => {\n                if (entry.isIntersecting) {\n                  const id = entry.target.id;\n                  tocNav.querySelectorAll(\".toc-link\").forEach((link) => {\n                    link.classList.toggle(\n                      \"active\",\n                      link.getAttribute(\"href\") === `#${id}`\n                    );\n                  });\n                }\n              });\n            },\n            { rootMargin: \"-20% 0px -80% 0px\" }\n          );\n\n          headings.forEach((heading) => observer.observe(heading));\n        }\n      }\n\n      // Sidebar Search\n      const sidebarSearch = document.getElementById(\"sidebar-search\");\n      sidebarSearch?.addEventListener(\"input\", (e) => {\n        const query = e.target.value.toLowerCase();\n        const items = document.querySelectorAll(\".nav-item\");\n\n        items.forEach((item) => {\n          const text = item.textContent.toLowerCase();\n          const matches = text.includes(query);\n          item.style.display = matches || !query ? \"\" : \"none\";\n\n          // Expand category if item matches\n          if (matches && query) {\n            const category = item.closest(\".category-items\");\n            const toggle = category?.previousElementSibling;\n            category?.classList.add(\"expanded\");\n            toggle?.classList.add(\"active\");\n          }\n        });\n      });\n\n      // Docs micro-feedback (local only)\n      const feedbackCard = document.getElementById(\"feedback-card\");\n      const feedbackButtons = document.querySelectorAll(\".feedback-btn\");\n      const feedbackFollowup = document.getElementById(\"feedback-followup\");\n      const feedbackSubmit = document.getElementById(\"feedback-submit\");\n      const feedbackStatus = document.getElementById(\"feedback-status\");\n      const feedbackNotes = document.getElementById(\"feedback-notes\");\n      const feedbackStorageKey = `docs-feedback:${window.location.pathname}`;\n\n      function completeFeedback(message) {\n        if (feedbackCard) feedbackCard.classList.add(\"feedback-complete\");\n        if (feedbackFollowup) feedbackFollowup.hidden = true;\n        if (feedbackStatus) feedbackStatus.textContent = message;\n        try {\n          localStorage.setItem(feedbackStorageKey, \"submitted\");\n        } catch (err) {\n          console.warn(\"Feedback storage failed\", err);\n        }\n      }\n\n      function maybeDisableFeedback() {\n        let stored = null;\n        try {\n          stored = localStorage.getItem(feedbackStorageKey);\n        } catch (err) {\n          console.warn(\"Feedback storage read failed\", err);\n        }\n\n        if (stored && feedbackCard) {\n          feedbackCard.classList.add(\"feedback-complete\");\n          if (feedbackFollowup) feedbackFollowup.hidden = true;\n          if (feedbackStatus)\n            feedbackStatus.textContent = \"Thanks—feedback already recorded.\";\n        }\n      }\n\n      feedbackButtons.forEach((btn) => {\n        btn.addEventListener(\"click\", () => {\n          const value = btn.dataset.feedback;\n          if (value === \"no\") {\n            if (feedbackFollowup) feedbackFollowup.hidden = false;\n            if (feedbackStatus)\n              feedbackStatus.textContent = \"Tell us what to improve.\";\n          } else {\n            completeFeedback(\"Thanks for the feedback!\");\n          }\n        });\n      });\n\n      feedbackSubmit?.addEventListener(\"click\", () => {\n        const note = feedbackNotes?.value?.trim();\n        const suffix = note ? \" We will review your note.\" : \"\";\n        completeFeedback(`Got it!${suffix}`);\n      });\n\n      maybeDisableFeedback();\n    </script>\n  </body>\n</html>\n","<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"dark\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>\n      Browser Support | Minecraft Mods & Packs Showcase\n    </title>\n\n    <!-- Stylesheets -->\n    <link rel=\"stylesheet\" href=\"/assets/css/main.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/layout.css\"\n    />\n    <link\n      rel=\"stylesheet\"\n      href=\"/assets/css/modpacks.css\"\n    />\n    <link rel=\"stylesheet\" href=\"/assets/css/docs.css\" />\n    <link\n      rel=\"stylesheet\"\n      href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n    />\n\n    <script>\n      if (!document.body) {\n        console.warn(\"Body not ready, skipping preloader\");\n      } else {\n        window.addEventListener(\"load\", () => {\n          document.body.classList.add(\"loaded\");\n        });\n      }\n\n      const savedTheme = localStorage.getItem(\"theme\") || \"dark\";\n      document.documentElement.setAttribute(\"data-theme\", savedTheme);\n    </script>\n  </head>\n  <body>\n    <!-- Preloader -->\n    <div class=\"preloader\">\n      <div class=\"spinner\"></div>\n    </div>\n\n    <!-- Mobile Menu Toggle -->\n    <button\n      id=\"mobile-sidebar-toggle\"\n      class=\"mobile-sidebar-toggle\"\n      aria-label=\"Toggle sidebar\"\n    >\n      <i class=\"fa-solid fa-bars\"></i>\n    </button>\n\n    <!-- Docs Sidebar -->\n    <aside id=\"docs-sidebar\" class=\"docs-sidebar\">\n      <div class=\"sidebar-header\">\n        <a href=\"/\" class=\"sidebar-logo\">\n          <i class=\"fa-solid fa-cube\"></i>\n          <span>Minecraft Mods & Packs Showcase</span>\n        </a>\n        <button\n          id=\"sidebar-close\"\n          class=\"sidebar-close\"\n          aria-label=\"Close sidebar\"\n        >\n          <i class=\"fa-solid fa-times\"></i>\n        </button>\n      </div>\n\n      <!-- Search in Sidebar -->\n      <div class=\"sidebar-search\">\n        <input\n          type=\"search\"\n          id=\"sidebar-search\"\n          placeholder=\"Search docs...\"\n          aria-label=\"Search documentation\"\n        />\n        <i class=\"fa-solid fa-search\"></i>\n      </div>\n\n      <!-- Navigation Tree -->\n      <nav class=\"sidebar-nav\">\n            \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"setup\"\n          >\n            <i\n              class=\"fa-solid fa-gear \"\n            ></i>\n            <span>Setup</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-setup\"\n          >\n            \n             \n            <a\n              href=\"/docs/getting-started/\"\n              class=\"nav-item \"\n            >\n              Getting Started\n            </a>\n              \n            <a\n              href=\"/docs/setup/\"\n              class=\"nav-item \"\n            >\n              Setup & Configuration\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"styling\"\n          >\n            <i\n              class=\"fa-solid fa-palette \"\n            ></i>\n            <span>Styling</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-styling\"\n          >\n            \n             \n            <a\n              href=\"/docs/customization/\"\n              class=\"nav-item \"\n            >\n              Customization\n            </a>\n              \n            <a\n              href=\"/docs/css-variables/\"\n              class=\"nav-item \"\n            >\n              CSS Variables Reference\n            </a>\n             \n          </div>\n        </div>\n              \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"community\"\n          >\n            <i\n              class=\"fa-solid fa-users \"\n            ></i>\n            <span>Community</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-community\"\n          >\n            \n             \n            <a\n              href=\"/docs/contributing/\"\n              class=\"nav-item \"\n            >\n              Contributing\n            </a>\n              \n            <a\n              href=\"/docs/content-guidelines/\"\n              class=\"nav-item \"\n            >\n              Content Guidelines\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle \"\n            data-category=\"developer\"\n          >\n            <i\n              class=\"fa-solid fa-code \"\n            ></i>\n            <span>Developer</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items \"\n            id=\"category-developer\"\n          >\n            \n             \n            <a\n              href=\"/docs/api-reference/\"\n              class=\"nav-item \"\n            >\n              API Reference\n            </a>\n              \n            <a\n              href=\"/docs/deployment/\"\n              class=\"nav-item \"\n            >\n              Deployment Guide\n            </a>\n              \n            <a\n              href=\"/docs/github-actions/\"\n              class=\"nav-item \"\n            >\n              GitHub Actions\n            </a>\n              \n            <a\n              href=\"/docs/project-structure/\"\n              class=\"nav-item \"\n            >\n              Project Structure\n            </a>\n              \n            <a\n              href=\"/docs/liquid-templates/\"\n              class=\"nav-item \"\n            >\n              Liquid Templates\n            </a>\n              \n            <a\n              href=\"/docs/performance/\"\n              class=\"nav-item \"\n            >\n              Performance Optimization\n            </a>\n              \n            <a\n              href=\"/docs/seo-guide/\"\n              class=\"nav-item \"\n            >\n              SEO Guide\n            </a>\n             \n          </div>\n        </div>\n           \n        <div class=\"nav-category\">\n          <button\n            class=\"category-toggle active\"\n            data-category=\"help\"\n          >\n            <i\n              class=\"fa-solid fa-circle-question \"\n            ></i>\n            <span>Help</span>\n            <i class=\"fa-solid fa-chevron-down toggle-icon\"></i>\n          </button>\n          <div\n            class=\"category-items expanded\"\n            id=\"category-help\"\n          >\n            \n             \n            <a\n              href=\"/docs/faq/\"\n              class=\"nav-item \"\n            >\n              FAQ\n            </a>\n              \n            <a\n              href=\"/docs/troubleshooting/\"\n              class=\"nav-item \"\n            >\n              Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/accessibility/\"\n              class=\"nav-item \"\n            >\n              Accessibility Guide\n            </a>\n              \n            <a\n              href=\"/docs/common-errors/\"\n              class=\"nav-item \"\n            >\n              Common Errors & Troubleshooting\n            </a>\n              \n            <a\n              href=\"/docs/browser-support/\"\n              class=\"nav-item active\"\n            >\n              Browser Support\n            </a>\n             \n          </div>\n        </div>\n         \n      </nav>\n\n      <!-- Quick Links -->\n      <div class=\"sidebar-footer\">\n        <a href=\"/docs/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-home\"></i>\n          All Docs\n        </a>\n        <a href=\"/projects/\" class=\"footer-link\">\n          <i class=\"fa-solid fa-folder\"></i>\n          Projects\n        </a>\n      </div>\n    </aside>\n\n    <!-- Sidebar Overlay (for mobile) -->\n    <div id=\"sidebar-overlay\" class=\"sidebar-overlay\"></div>\n\n    <!-- Main Content -->\n    <div class=\"docs-layout\">\n      <!-- Breadcrumbs -->\n      \n      <nav class=\"breadcrumbs\" aria-label=\"Breadcrumb\">\n        <a href=\"/\">\n          <i class=\"fa-solid fa-home\"></i>\n          Home\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a href=\"/docs/\">Docs</a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <a\n          href=\"/docs-category-help/\"\n        >\n          Help\n        </a>\n        <i class=\"fa-solid fa-chevron-right\"></i>\n        <span class=\"current\">Browser Support</span>\n      </nav>\n      \n\n      <!-- Page Content -->\n      <main class=\"docs-content\">\n        <article><h1 id=\"browser-support\">Browser Support</h1>\n\n<p>Ensure your ABC showcase works across different browsers and devices.</p>\n\n<h2 id=\"supported-browsers\">Supported Browsers</h2>\n\n<h3 id=\"modern-browsers-full-support\">Modern Browsers (Full Support)</h3>\n\n<table>\n  <thead>\n    <tr>\n      <th>Browser</th>\n      <th>Minimum Version</th>\n      <th>Notes</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>Chrome</td>\n      <td>90+</td>\n      <td>Full ES6 support</td>\n    </tr>\n    <tr>\n      <td>Firefox</td>\n      <td>88+</td>\n      <td>Full CSS Grid support</td>\n    </tr>\n    <tr>\n      <td>Safari</td>\n      <td>14+</td>\n      <td>webkit prefixes may be needed</td>\n    </tr>\n    <tr>\n      <td>Edge</td>\n      <td>90+</td>\n      <td>Chromium-based</td>\n    </tr>\n    <tr>\n      <td>Opera</td>\n      <td>76+</td>\n      <td>Chromium-based</td>\n    </tr>\n  </tbody>\n</table>\n\n<h3 id=\"mobile-browsers\">Mobile Browsers</h3>\n\n<table>\n  <thead>\n    <tr>\n      <th>Browser</th>\n      <th>Minimum Version</th>\n      <th>Notes</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>Chrome Mobile</td>\n      <td>90+</td>\n      <td>Android 5+</td>\n    </tr>\n    <tr>\n      <td>Safari Mobile</td>\n      <td>14+</td>\n      <td>iOS 14+</td>\n    </tr>\n    <tr>\n      <td>Samsung Internet</td>\n      <td>14+</td>\n      <td>Android 7+</td>\n    </tr>\n    <tr>\n      <td>Firefox Mobile</td>\n      <td>88+</td>\n      <td>Android 5+</td>\n    </tr>\n  </tbody>\n</table>\n\n<h3 id=\"limited-support\">Limited Support</h3>\n\n<table>\n  <thead>\n    <tr>\n      <th>Browser</th>\n      <th>Support Level</th>\n      <th>Notes</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>IE 11</td>\n      <td>Degraded</td>\n      <td>Requires polyfills</td>\n    </tr>\n    <tr>\n      <td>Safari 13</td>\n      <td>Partial</td>\n      <td>Some CSS features unsupported</td>\n    </tr>\n    <tr>\n      <td>Older mobile browsers</td>\n      <td>Basic</td>\n      <td>Fallbacks required</td>\n    </tr>\n  </tbody>\n</table>\n\n<h2 id=\"feature-support\">Feature Support</h2>\n\n<h3 id=\"css-features\">CSS Features</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* CSS Grid */</span>\n<span class=\"k\">@supports</span> <span class=\"p\">(</span><span class=\"n\">display</span><span class=\"p\">:</span> <span class=\"n\">grid</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nc\">.grid</span> <span class=\"p\">{</span>\n    <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"n\">grid</span><span class=\"p\">;</span>\n    <span class=\"py\">grid-template-columns</span><span class=\"p\">:</span> <span class=\"nb\">repeat</span><span class=\"p\">(</span><span class=\"n\">auto-fit</span><span class=\"p\">,</span> <span class=\"n\">minmax</span><span class=\"p\">(</span><span class=\"m\">280px</span><span class=\"p\">,</span> <span class=\"m\">1</span><span class=\"n\">fr</span><span class=\"p\">));</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Fallback for older browsers */</span>\n<span class=\"nc\">.grid</span> <span class=\"p\">{</span>\n  <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"n\">flex</span><span class=\"p\">;</span>\n  <span class=\"nl\">flex-wrap</span><span class=\"p\">:</span> <span class=\"n\">wrap</span><span class=\"p\">;</span>\n  <span class=\"py\">gap</span><span class=\"p\">:</span> <span class=\"m\">16px</span><span class=\"p\">;</span> <span class=\"c\">/* Fallback with margin if gap unsupported */</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Custom Properties (CSS Variables) */</span>\n<span class=\"nd\">:root</span> <span class=\"p\">{</span>\n  <span class=\"py\">--accent</span><span class=\"p\">:</span> <span class=\"m\">#4caf50</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Fallback */</span>\n<span class=\"nc\">.button</span> <span class=\"p\">{</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"m\">#4caf50</span><span class=\"p\">;</span> <span class=\"c\">/* Fallback */</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"n\">var</span><span class=\"p\">(</span><span class=\"n\">--accent</span><span class=\"p\">);</span> <span class=\"c\">/* Modern */</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h3 id=\"javascript-features\">JavaScript Features</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// ES6+ Features Detection</span>\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"k\">typeof</span> <span class=\"nb\">Symbol</span> <span class=\"o\">!==</span> <span class=\"dl\">\"</span><span class=\"s2\">undefined</span><span class=\"dl\">\"</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Symbols supported</span>\n<span class=\"p\">}</span>\n\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"k\">typeof</span> <span class=\"nb\">Promise</span> <span class=\"o\">!==</span> <span class=\"dl\">\"</span><span class=\"s2\">undefined</span><span class=\"dl\">\"</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Promises supported</span>\n<span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Load polyfill</span>\n<span class=\"p\">}</span>\n\n<span class=\"c1\">// Modern API Detection</span>\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">IntersectionObserver</span><span class=\"dl\">\"</span> <span class=\"k\">in</span> <span class=\"nb\">window</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Use IntersectionObserver</span>\n<span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Fallback to scroll events</span>\n<span class=\"p\">}</span>\n\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">serviceWorker</span><span class=\"dl\">\"</span> <span class=\"k\">in</span> <span class=\"nb\">navigator</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Service Worker supported</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"progressive-enhancement\">Progressive Enhancement</h2>\n\n<h3 id=\"mobile-first-approach\">Mobile-First Approach</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Base styles for mobile */</span>\n<span class=\"nc\">.container</span> <span class=\"p\">{</span>\n  <span class=\"nl\">padding</span><span class=\"p\">:</span> <span class=\"m\">20px</span><span class=\"p\">;</span>\n  <span class=\"nl\">font-size</span><span class=\"p\">:</span> <span class=\"m\">16px</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Enhance for tablets */</span>\n<span class=\"k\">@media</span> <span class=\"p\">(</span><span class=\"n\">min-width</span><span class=\"p\">:</span> <span class=\"m\">768px</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nc\">.container</span> <span class=\"p\">{</span>\n    <span class=\"nl\">padding</span><span class=\"p\">:</span> <span class=\"m\">40px</span><span class=\"p\">;</span>\n    <span class=\"nl\">font-size</span><span class=\"p\">:</span> <span class=\"m\">18px</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Enhance for desktop */</span>\n<span class=\"k\">@media</span> <span class=\"p\">(</span><span class=\"n\">min-width</span><span class=\"p\">:</span> <span class=\"m\">1024px</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nc\">.container</span> <span class=\"p\">{</span>\n    <span class=\"nl\">max-width</span><span class=\"p\">:</span> <span class=\"m\">1200px</span><span class=\"p\">;</span>\n    <span class=\"nl\">margin</span><span class=\"p\">:</span> <span class=\"m\">0</span> <span class=\"nb\">auto</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h3 id=\"feature-detection\">Feature Detection</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// Check for localStorage</span>\n<span class=\"kd\">function</span> <span class=\"nx\">hasLocalStorage</span><span class=\"p\">()</span> <span class=\"p\">{</span>\n  <span class=\"k\">try</span> <span class=\"p\">{</span>\n    <span class=\"nx\">localStorage</span><span class=\"p\">.</span><span class=\"nx\">setItem</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">test</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">test</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n    <span class=\"nx\">localStorage</span><span class=\"p\">.</span><span class=\"nx\">removeItem</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">test</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n    <span class=\"k\">return</span> <span class=\"kc\">true</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span> <span class=\"k\">catch</span> <span class=\"p\">(</span><span class=\"nx\">e</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"kc\">false</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">hasLocalStorage</span><span class=\"p\">())</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Use localStorage</span>\n<span class=\"p\">}</span> <span class=\"k\">else</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Use cookies or session storage</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"vendor-prefixes\">Vendor Prefixes</h2>\n\n<h3 id=\"autoprefixer-recommended\">Autoprefixer (Recommended)</h3>\n\n<p>Install and configure:</p>\n\n<div class=\"language-bash highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>npm <span class=\"nb\">install</span> <span class=\"nt\">--save-dev</span> autoprefixer postcss-cli\n</code></pre></div></div>\n\n<p>Create <code class=\"language-plaintext highlighter-rouge\">postcss.config.js</code>:</p>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nx\">module</span><span class=\"p\">.</span><span class=\"nx\">exports</span> <span class=\"o\">=</span> <span class=\"p\">{</span>\n  <span class=\"na\">plugins</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n    <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">autoprefixer</span><span class=\"dl\">\"</span><span class=\"p\">)({</span>\n      <span class=\"na\">overrideBrowserslist</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"dl\">\"</span><span class=\"s2\">last 2 versions</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">&gt; 1%</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">not dead</span><span class=\"dl\">\"</span><span class=\"p\">],</span>\n    <span class=\"p\">}),</span>\n  <span class=\"p\">],</span>\n<span class=\"p\">};</span>\n</code></pre></div></div>\n\n<h3 id=\"manual-prefixes\">Manual Prefixes</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Flexbox */</span>\n<span class=\"nc\">.flex</span> <span class=\"p\">{</span>\n  <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"n\">-webkit-box</span><span class=\"p\">;</span>\n  <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"n\">-ms-flexbox</span><span class=\"p\">;</span>\n  <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"n\">flex</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Transform */</span>\n<span class=\"nc\">.rotate</span> <span class=\"p\">{</span>\n  <span class=\"nl\">-webkit-transform</span><span class=\"p\">:</span> <span class=\"n\">rotate</span><span class=\"p\">(</span><span class=\"m\">45deg</span><span class=\"p\">);</span>\n  <span class=\"nl\">-ms-transform</span><span class=\"p\">:</span> <span class=\"n\">rotate</span><span class=\"p\">(</span><span class=\"m\">45deg</span><span class=\"p\">);</span>\n  <span class=\"nl\">transform</span><span class=\"p\">:</span> <span class=\"n\">rotate</span><span class=\"p\">(</span><span class=\"m\">45deg</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Transition */</span>\n<span class=\"nc\">.transition</span> <span class=\"p\">{</span>\n  <span class=\"nl\">-webkit-transition</span><span class=\"p\">:</span> <span class=\"n\">all</span> <span class=\"m\">0.3s</span> <span class=\"n\">ease</span><span class=\"p\">;</span>\n  <span class=\"nl\">-o-transition</span><span class=\"p\">:</span> <span class=\"n\">all</span> <span class=\"m\">0.3s</span> <span class=\"n\">ease</span><span class=\"p\">;</span>\n  <span class=\"nl\">transition</span><span class=\"p\">:</span> <span class=\"n\">all</span> <span class=\"m\">0.3s</span> <span class=\"n\">ease</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Backdrop Filter */</span>\n<span class=\"nc\">.blur</span> <span class=\"p\">{</span>\n  <span class=\"nl\">-webkit-backdrop-filter</span><span class=\"p\">:</span> <span class=\"n\">blur</span><span class=\"p\">(</span><span class=\"m\">10px</span><span class=\"p\">);</span>\n  <span class=\"py\">backdrop-filter</span><span class=\"p\">:</span> <span class=\"n\">blur</span><span class=\"p\">(</span><span class=\"m\">10px</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"polyfills\">Polyfills</h2>\n\n<h3 id=\"core-polyfills\">Core Polyfills</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Polyfill.io (automatic) --&gt;</span>\n<span class=\"nt\">&lt;script </span><span class=\"na\">src=</span><span class=\"s\">\"https://polyfill.io/v3/polyfill.min.js?features=default,IntersectionObserver,fetch\"</span><span class=\"nt\">&gt;&lt;/script&gt;</span>\n\n<span class=\"c\">&lt;!-- Or manual polyfills --&gt;</span>\n<span class=\"nt\">&lt;script </span><span class=\"na\">src=</span><span class=\"s\">\"/assets/js/polyfills.js\"</span><span class=\"nt\">&gt;&lt;/script&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"custom-polyfill-bundle\">Custom Polyfill Bundle</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// polyfills.js</span>\n\n<span class=\"c1\">// Array.from (IE 11)</span>\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nb\">Array</span><span class=\"p\">.</span><span class=\"k\">from</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nb\">Array</span><span class=\"p\">.</span><span class=\"k\">from</span> <span class=\"o\">=</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">arrayLike</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"k\">return</span> <span class=\"nb\">Array</span><span class=\"p\">.</span><span class=\"nx\">prototype</span><span class=\"p\">.</span><span class=\"nx\">slice</span><span class=\"p\">.</span><span class=\"nx\">call</span><span class=\"p\">(</span><span class=\"nx\">arrayLike</span><span class=\"p\">);</span>\n  <span class=\"p\">};</span>\n<span class=\"p\">}</span>\n\n<span class=\"c1\">// Object.assign (IE 11)</span>\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"k\">typeof</span> <span class=\"nb\">Object</span><span class=\"p\">.</span><span class=\"nx\">assign</span> <span class=\"o\">!==</span> <span class=\"dl\">\"</span><span class=\"s2\">function</span><span class=\"dl\">\"</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nb\">Object</span><span class=\"p\">.</span><span class=\"nx\">assign</span> <span class=\"o\">=</span> <span class=\"kd\">function</span> <span class=\"p\">(</span><span class=\"nx\">target</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n    <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">target</span> <span class=\"o\">==</span> <span class=\"kc\">null</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n      <span class=\"k\">throw</span> <span class=\"k\">new</span> <span class=\"nx\">TypeError</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">Cannot convert undefined or null to object</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n    <span class=\"p\">}</span>\n    <span class=\"kd\">var</span> <span class=\"nx\">to</span> <span class=\"o\">=</span> <span class=\"nb\">Object</span><span class=\"p\">(</span><span class=\"nx\">target</span><span class=\"p\">);</span>\n    <span class=\"k\">for</span> <span class=\"p\">(</span><span class=\"kd\">var</span> <span class=\"nx\">index</span> <span class=\"o\">=</span> <span class=\"mi\">1</span><span class=\"p\">;</span> <span class=\"nx\">index</span> <span class=\"o\">&lt;</span> <span class=\"nx\">arguments</span><span class=\"p\">.</span><span class=\"nx\">length</span><span class=\"p\">;</span> <span class=\"nx\">index</span><span class=\"o\">++</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n      <span class=\"kd\">var</span> <span class=\"nx\">nextSource</span> <span class=\"o\">=</span> <span class=\"nx\">arguments</span><span class=\"p\">[</span><span class=\"nx\">index</span><span class=\"p\">];</span>\n      <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">nextSource</span> <span class=\"o\">!=</span> <span class=\"kc\">null</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n        <span class=\"k\">for</span> <span class=\"p\">(</span><span class=\"kd\">var</span> <span class=\"nx\">nextKey</span> <span class=\"k\">in</span> <span class=\"nx\">nextSource</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n          <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nb\">Object</span><span class=\"p\">.</span><span class=\"nx\">prototype</span><span class=\"p\">.</span><span class=\"nx\">hasOwnProperty</span><span class=\"p\">.</span><span class=\"nx\">call</span><span class=\"p\">(</span><span class=\"nx\">nextSource</span><span class=\"p\">,</span> <span class=\"nx\">nextKey</span><span class=\"p\">))</span> <span class=\"p\">{</span>\n            <span class=\"nx\">to</span><span class=\"p\">[</span><span class=\"nx\">nextKey</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"nx\">nextSource</span><span class=\"p\">[</span><span class=\"nx\">nextKey</span><span class=\"p\">];</span>\n          <span class=\"p\">}</span>\n        <span class=\"p\">}</span>\n      <span class=\"p\">}</span>\n    <span class=\"p\">}</span>\n    <span class=\"k\">return</span> <span class=\"nx\">to</span><span class=\"p\">;</span>\n  <span class=\"p\">};</span>\n<span class=\"p\">}</span>\n\n<span class=\"c1\">// Fetch API (older browsers)</span>\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"nb\">window</span><span class=\"p\">.</span><span class=\"nx\">fetch</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"c1\">// Load fetch polyfill</span>\n  <span class=\"kd\">var</span> <span class=\"nx\">script</span> <span class=\"o\">=</span> <span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">createElement</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">script</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n  <span class=\"nx\">script</span><span class=\"p\">.</span><span class=\"nx\">src</span> <span class=\"o\">=</span> <span class=\"dl\">\"</span><span class=\"s2\">https://unpkg.com/[email protected]/dist/fetch.umd.js</span><span class=\"dl\">\"</span><span class=\"p\">;</span>\n  <span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">head</span><span class=\"p\">.</span><span class=\"nx\">appendChild</span><span class=\"p\">(</span><span class=\"nx\">script</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n\n<span class=\"c1\">// IntersectionObserver (Safari &lt; 12.1)</span>\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"o\">!</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">IntersectionObserver</span><span class=\"dl\">\"</span> <span class=\"k\">in</span> <span class=\"nb\">window</span><span class=\"p\">))</span> <span class=\"p\">{</span>\n  <span class=\"kd\">var</span> <span class=\"nx\">script</span> <span class=\"o\">=</span> <span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">createElement</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">script</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n  <span class=\"nx\">script</span><span class=\"p\">.</span><span class=\"nx\">src</span> <span class=\"o\">=</span>\n    <span class=\"dl\">\"</span><span class=\"s2\">https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver</span><span class=\"dl\">\"</span><span class=\"p\">;</span>\n  <span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">head</span><span class=\"p\">.</span><span class=\"nx\">appendChild</span><span class=\"p\">(</span><span class=\"nx\">script</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"testing-across-browsers\">Testing Across Browsers</h2>\n\n<h3 id=\"local-testing\">Local Testing</h3>\n\n<p><strong>BrowserStack</strong> (free for open source):</p>\n\n<div class=\"language-plaintext highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code>https://www.browserstack.com/open-source\n</code></pre></div></div>\n\n<p><strong>Browser DevTools Device Mode</strong>:</p>\n\n<ul>\n  <li>Chrome: F12 &gt; Toggle device toolbar</li>\n  <li>Firefox: F12 &gt; Responsive Design Mode</li>\n  <li>Safari: Develop &gt; Enter Responsive Design Mode</li>\n</ul>\n\n<h3 id=\"automated-testing\">Automated Testing</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// Example with Playwright</span>\n<span class=\"kd\">const</span> <span class=\"p\">{</span> <span class=\"nx\">chromium</span><span class=\"p\">,</span> <span class=\"nx\">firefox</span><span class=\"p\">,</span> <span class=\"nx\">webkit</span> <span class=\"p\">}</span> <span class=\"o\">=</span> <span class=\"nx\">require</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">playwright</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n\n<span class=\"p\">(</span><span class=\"k\">async</span> <span class=\"p\">()</span> <span class=\"o\">=&gt;</span> <span class=\"p\">{</span>\n  <span class=\"k\">for</span> <span class=\"p\">(</span><span class=\"kd\">const</span> <span class=\"nx\">browserType</span> <span class=\"k\">of</span> <span class=\"p\">[</span><span class=\"nx\">chromium</span><span class=\"p\">,</span> <span class=\"nx\">firefox</span><span class=\"p\">,</span> <span class=\"nx\">webkit</span><span class=\"p\">])</span> <span class=\"p\">{</span>\n    <span class=\"kd\">const</span> <span class=\"nx\">browser</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"nx\">browserType</span><span class=\"p\">.</span><span class=\"nx\">launch</span><span class=\"p\">();</span>\n    <span class=\"kd\">const</span> <span class=\"nx\">page</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"nx\">browser</span><span class=\"p\">.</span><span class=\"nx\">newPage</span><span class=\"p\">();</span>\n    <span class=\"k\">await</span> <span class=\"nx\">page</span><span class=\"p\">.</span><span class=\"nx\">goto</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">http://localhost:4000</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n    <span class=\"k\">await</span> <span class=\"nx\">page</span><span class=\"p\">.</span><span class=\"nx\">screenshot</span><span class=\"p\">({</span> <span class=\"na\">path</span><span class=\"p\">:</span> <span class=\"s2\">`screenshot-</span><span class=\"p\">${</span><span class=\"nx\">browserType</span><span class=\"p\">.</span><span class=\"nx\">name</span><span class=\"p\">()}</span><span class=\"s2\">.png`</span> <span class=\"p\">});</span>\n    <span class=\"k\">await</span> <span class=\"nx\">browser</span><span class=\"p\">.</span><span class=\"nx\">close</span><span class=\"p\">();</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">})();</span>\n</code></pre></div></div>\n\n<h2 id=\"graceful-degradation\">Graceful Degradation</h2>\n\n<h3 id=\"no-javascript-fallback\">No JavaScript Fallback</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"nt\">&lt;noscript&gt;</span>\n  <span class=\"nt\">&lt;style&gt;</span>\n    <span class=\"nc\">.js-only</span> <span class=\"p\">{</span>\n      <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"nb\">none</span><span class=\"p\">;</span>\n    <span class=\"p\">}</span>\n  <span class=\"nt\">&lt;/style&gt;</span>\n  <span class=\"nt\">&lt;div</span> <span class=\"na\">class=</span><span class=\"s\">\"no-js-message\"</span><span class=\"nt\">&gt;</span>\n    <span class=\"nt\">&lt;p&gt;</span>This site works best with JavaScript enabled.<span class=\"nt\">&lt;/p&gt;</span>\n  <span class=\"nt\">&lt;/div&gt;</span>\n<span class=\"nt\">&lt;/noscript&gt;</span>\n\n<span class=\"c\">&lt;!-- Progressive enhancement --&gt;</span>\n<span class=\"nt\">&lt;div</span> <span class=\"na\">class=</span><span class=\"s\">\"content\"</span><span class=\"nt\">&gt;</span>\n  <span class=\"nt\">&lt;p&gt;</span>Content visible without JS<span class=\"nt\">&lt;/p&gt;</span>\n  <span class=\"nt\">&lt;div</span> <span class=\"na\">class=</span><span class=\"s\">\"js-only\"</span> <span class=\"na\">style=</span><span class=\"s\">\"display: none;\"</span><span class=\"nt\">&gt;</span>\n    <span class=\"nt\">&lt;p&gt;</span>Enhanced content with JS<span class=\"nt\">&lt;/p&gt;</span>\n  <span class=\"nt\">&lt;/div&gt;</span>\n<span class=\"nt\">&lt;/div&gt;</span>\n\n<span class=\"nt\">&lt;script&gt;</span>\n  <span class=\"c1\">// Show JS-only content</span>\n  <span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">querySelectorAll</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">.js-only</span><span class=\"dl\">\"</span><span class=\"p\">).</span><span class=\"nx\">forEach</span><span class=\"p\">((</span><span class=\"nx\">el</span><span class=\"p\">)</span> <span class=\"o\">=&gt;</span> <span class=\"p\">{</span>\n    <span class=\"nx\">el</span><span class=\"p\">.</span><span class=\"nx\">style</span><span class=\"p\">.</span><span class=\"nx\">display</span> <span class=\"o\">=</span> <span class=\"dl\">\"</span><span class=\"s2\">block</span><span class=\"dl\">\"</span><span class=\"p\">;</span>\n  <span class=\"p\">});</span>\n<span class=\"nt\">&lt;/script&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"css-fallbacks\">CSS Fallbacks</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Background with fallback */</span>\n<span class=\"nc\">.element</span> <span class=\"p\">{</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"m\">#1a1a1a</span><span class=\"p\">;</span> <span class=\"c\">/* Fallback */</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"n\">linear-gradient</span><span class=\"p\">(</span><span class=\"m\">135deg</span><span class=\"p\">,</span> <span class=\"m\">#1a1a1a</span> <span class=\"m\">0%</span><span class=\"p\">,</span> <span class=\"m\">#2a2a2a</span> <span class=\"m\">100%</span><span class=\"p\">);</span> <span class=\"c\">/* Modern */</span>\n<span class=\"p\">}</span>\n\n<span class=\"c\">/* Custom properties with fallback */</span>\n<span class=\"nc\">.button</span> <span class=\"p\">{</span>\n  <span class=\"nl\">color</span><span class=\"p\">:</span> <span class=\"m\">#4caf50</span><span class=\"p\">;</span> <span class=\"c\">/* Fallback */</span>\n  <span class=\"nl\">color</span><span class=\"p\">:</span> <span class=\"n\">var</span><span class=\"p\">(</span><span class=\"n\">--accent-primary</span><span class=\"p\">,</span> <span class=\"m\">#4caf50</span><span class=\"p\">);</span> <span class=\"c\">/* Modern with fallback */</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"common-compatibility-issues\">Common Compatibility Issues</h2>\n\n<h3 id=\"issue-css-grid-not-working\">Issue: CSS Grid Not Working</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Solution: Provide flexbox fallback */</span>\n<span class=\"nc\">.grid</span> <span class=\"p\">{</span>\n  <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"n\">flex</span><span class=\"p\">;</span>\n  <span class=\"nl\">flex-wrap</span><span class=\"p\">:</span> <span class=\"n\">wrap</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"nc\">.grid</span> <span class=\"o\">&gt;</span> <span class=\"o\">*</span> <span class=\"p\">{</span>\n  <span class=\"nl\">flex</span><span class=\"p\">:</span> <span class=\"m\">1</span> <span class=\"m\">1</span> <span class=\"m\">280px</span><span class=\"p\">;</span>\n  <span class=\"nl\">margin</span><span class=\"p\">:</span> <span class=\"m\">8px</span><span class=\"p\">;</span>\n<span class=\"p\">}</span>\n\n<span class=\"k\">@supports</span> <span class=\"p\">(</span><span class=\"n\">display</span><span class=\"p\">:</span> <span class=\"n\">grid</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nc\">.grid</span> <span class=\"p\">{</span>\n    <span class=\"nl\">display</span><span class=\"p\">:</span> <span class=\"n\">grid</span><span class=\"p\">;</span>\n    <span class=\"py\">grid-template-columns</span><span class=\"p\">:</span> <span class=\"nb\">repeat</span><span class=\"p\">(</span><span class=\"n\">auto-fit</span><span class=\"p\">,</span> <span class=\"n\">minmax</span><span class=\"p\">(</span><span class=\"m\">280px</span><span class=\"p\">,</span> <span class=\"m\">1</span><span class=\"n\">fr</span><span class=\"p\">));</span>\n    <span class=\"py\">gap</span><span class=\"p\">:</span> <span class=\"m\">16px</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span>\n\n  <span class=\"nc\">.grid</span> <span class=\"o\">&gt;</span> <span class=\"o\">*</span> <span class=\"p\">{</span>\n    <span class=\"nl\">margin</span><span class=\"p\">:</span> <span class=\"m\">0</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h3 id=\"issue-backdrop-filter-not-supported\">Issue: backdrop-filter Not Supported</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Fallback for backdrop-filter */</span>\n<span class=\"nc\">.navbar</span> <span class=\"p\">{</span>\n  <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"n\">rgba</span><span class=\"p\">(</span><span class=\"m\">31</span><span class=\"p\">,</span> <span class=\"m\">31</span><span class=\"p\">,</span> <span class=\"m\">31</span><span class=\"p\">,</span> <span class=\"m\">0.9</span><span class=\"p\">);</span> <span class=\"c\">/* Solid fallback */</span>\n<span class=\"p\">}</span>\n\n<span class=\"k\">@supports</span> <span class=\"p\">(</span><span class=\"n\">backdrop-filter</span><span class=\"p\">:</span> <span class=\"n\">blur</span><span class=\"p\">(</span><span class=\"m\">10px</span><span class=\"p\">))</span> <span class=\"p\">{</span>\n  <span class=\"nc\">.navbar</span> <span class=\"p\">{</span>\n    <span class=\"nl\">background</span><span class=\"p\">:</span> <span class=\"n\">rgba</span><span class=\"p\">(</span><span class=\"m\">31</span><span class=\"p\">,</span> <span class=\"m\">31</span><span class=\"p\">,</span> <span class=\"m\">31</span><span class=\"p\">,</span> <span class=\"m\">0.7</span><span class=\"p\">);</span> <span class=\"c\">/* More transparent */</span>\n    <span class=\"py\">backdrop-filter</span><span class=\"p\">:</span> <span class=\"n\">blur</span><span class=\"p\">(</span><span class=\"m\">10px</span><span class=\"p\">);</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h3 id=\"issue-sticky-positioning\">Issue: Sticky Positioning</h3>\n\n<div class=\"language-css highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">/* Fallback for position: sticky */</span>\n<span class=\"nc\">.sidebar</span> <span class=\"p\">{</span>\n  <span class=\"nl\">position</span><span class=\"p\">:</span> <span class=\"nb\">relative</span><span class=\"p\">;</span> <span class=\"c\">/* Fallback */</span>\n<span class=\"p\">}</span>\n\n<span class=\"k\">@supports</span> <span class=\"p\">(</span><span class=\"n\">position</span><span class=\"p\">:</span> <span class=\"n\">sticky</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nc\">.sidebar</span> <span class=\"p\">{</span>\n    <span class=\"nl\">position</span><span class=\"p\">:</span> <span class=\"n\">sticky</span><span class=\"p\">;</span>\n    <span class=\"nl\">top</span><span class=\"p\">:</span> <span class=\"m\">20px</span><span class=\"p\">;</span>\n  <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"performance-on-older-browsers\">Performance on Older Browsers</h2>\n\n<h3 id=\"reduce-javascript-bundle-size\">Reduce JavaScript Bundle Size</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Only load for modern browsers --&gt;</span>\n<span class=\"nt\">&lt;script </span><span class=\"na\">type=</span><span class=\"s\">\"module\"</span> <span class=\"na\">src=</span><span class=\"s\">\"/assets/js/modern.js\"</span><span class=\"nt\">&gt;&lt;/script&gt;</span>\n\n<span class=\"c\">&lt;!-- Fallback for older browsers --&gt;</span>\n<span class=\"nt\">&lt;script </span><span class=\"na\">nomodule</span> <span class=\"na\">src=</span><span class=\"s\">\"/assets/js/legacy.js\"</span><span class=\"nt\">&gt;&lt;/script&gt;</span>\n</code></pre></div></div>\n\n<h3 id=\"optimize-for-mobile\">Optimize for Mobile</h3>\n\n<div class=\"language-html highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c\">&lt;!-- Responsive images --&gt;</span>\n<span class=\"nt\">&lt;picture&gt;</span>\n  <span class=\"nt\">&lt;source</span>\n    <span class=\"na\">srcset=</span><span class=\"s\">\"\n      image-large.webp  1200w,\n      image-medium.webp  800w,\n      image-small.webp   400w\n    \"</span>\n    <span class=\"na\">type=</span><span class=\"s\">\"image/webp\"</span>\n  <span class=\"nt\">/&gt;</span>\n  <span class=\"nt\">&lt;img</span>\n    <span class=\"na\">src=</span><span class=\"s\">\"image.jpg\"</span>\n    <span class=\"na\">srcset=</span><span class=\"s\">\"image-large.jpg 1200w, image-medium.jpg 800w, image-small.jpg 400w\"</span>\n    <span class=\"na\">sizes=</span><span class=\"s\">\"(max-width: 600px) 400px, (max-width: 900px) 800px, 1200px\"</span>\n    <span class=\"na\">alt=</span><span class=\"s\">\"Description\"</span>\n  <span class=\"nt\">/&gt;</span>\n<span class=\"nt\">&lt;/picture&gt;</span>\n</code></pre></div></div>\n\n<h2 id=\"browser-detection\">Browser Detection</h2>\n\n<h3 id=\"user-agent-detection-not-recommended\">User Agent Detection (Not Recommended)</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// Avoid this approach</span>\n<span class=\"kd\">const</span> <span class=\"nx\">isIE</span> <span class=\"o\">=</span> <span class=\"sr\">/MSIE|Trident/</span><span class=\"p\">.</span><span class=\"nx\">test</span><span class=\"p\">(</span><span class=\"nb\">navigator</span><span class=\"p\">.</span><span class=\"nx\">userAgent</span><span class=\"p\">);</span>\n</code></pre></div></div>\n\n<h3 id=\"feature-detection-recommended\">Feature Detection (Recommended)</h3>\n\n<div class=\"language-javascript highlighter-rouge\"><div class=\"highlight\"><pre class=\"highlight\"><code><span class=\"c1\">// Detect features, not browsers</span>\n<span class=\"kd\">const</span> <span class=\"nx\">supportsGrid</span> <span class=\"o\">=</span> <span class=\"nx\">CSS</span><span class=\"p\">.</span><span class=\"nx\">supports</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">display</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">grid</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n<span class=\"kd\">const</span> <span class=\"nx\">supportsCustomProperties</span> <span class=\"o\">=</span> <span class=\"nx\">CSS</span><span class=\"p\">.</span><span class=\"nx\">supports</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">--custom</span><span class=\"dl\">\"</span><span class=\"p\">,</span> <span class=\"dl\">\"</span><span class=\"s2\">property</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n\n<span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nx\">supportsGrid</span><span class=\"p\">)</span> <span class=\"p\">{</span>\n  <span class=\"nb\">document</span><span class=\"p\">.</span><span class=\"nx\">body</span><span class=\"p\">.</span><span class=\"nx\">classList</span><span class=\"p\">.</span><span class=\"nx\">add</span><span class=\"p\">(</span><span class=\"dl\">\"</span><span class=\"s2\">supports-grid</span><span class=\"dl\">\"</span><span class=\"p\">);</span>\n<span class=\"p\">}</span>\n</code></pre></div></div>\n\n<h2 id=\"testing-checklist\">Testing Checklist</h2>\n\n<ul class=\"task-list\">\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Test in Chrome, Firefox, Safari, Edge</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Test on iOS Safari and Android Chrome</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Verify responsive design at multiple breakpoints</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Check with JavaScript disabled</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Test with screen readers</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Verify keyboard navigation</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Check CSS Grid/Flexbox layouts</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Test custom properties (CSS variables)</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Verify backdrop-filter fallbacks</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Check font loading</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Test lazy loading functionality</li>\n  <li class=\"task-list-item\"><input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled=\"disabled\" />Verify service worker (if implemented)</li>\n</ul>\n\n<h2 id=\"resources\">Resources</h2>\n\n<ul>\n  <li><a href=\"https://caniuse.com/\">Can I Use</a> - Browser feature support tables</li>\n  <li><a href=\"https://developer.mozilla.org/en-US/docs/Web/Guide/Browser_Detection_and_Cross_Browser_Support\">MDN Browser Compatibility</a></li>\n  <li><a href=\"https://autoprefixer.github.io/\">Autoprefixer</a> - Automatic vendor prefixes</li>\n  <li><a href=\"https://polyfill.io/\">Polyfill.io</a> - Automatic polyfills</li>\n  <li><a href=\"https://www.browserstack.com/\">BrowserStack</a> - Cross-browser testing</li>\n</ul>\n\n<h2 id=\"next-steps\">Next Steps</h2>\n\n<ul>\n  <li><a href=\"accessibility.html\">Accessibility Guide</a> - Inclusive design</li>\n  <li><a href=\"performance.html\">Performance Guide</a> - Optimization</li>\n  <li><a href=\"common-errors.html\">Common Errors</a> - Troubleshooting</li>\n</ul>\n</article>\n\n        <section\n          class=\"feedback-card\"\n          id=\"feedback-card\"\n          aria-label=\"Page feedback\"\n        >\n          <div class=\"feedback-header\">\n            <div>\n              <p class=\"feedback-kicker\">Feedback</p>\n              <h3>Was this page helpful?</h3>\n              <p class=\"feedback-subtext\">\n                Share quick feedback to improve these docs.\n              </p>\n            </div>\n            <div class=\"feedback-badges\" aria-label=\"Applies to versions\">\n                  \n              <span class=\"version-badge\" aria-label=\"Minecraft 1.21.x\"\n                >1.21.x</span\n              >\n               \n            </div>\n          </div>\n\n          <div class=\"feedback-actions\" role=\"group\" aria-label=\"Helpful?\">\n            <button type=\"button\" class=\"feedback-btn yes\" data-feedback=\"yes\">\n              <i class=\"fa-solid fa-thumbs-up\"></i>\n              Yes\n            </button>\n            <button type=\"button\" class=\"feedback-btn no\" data-feedback=\"no\">\n              <i class=\"fa-solid fa-thumbs-down\"></i>\n              No\n            </button>\n          </div>\n\n          <div class=\"feedback-followup\" id=\"feedback-followup\" hidden>\n            <label for=\"feedback-notes\">What can we improve?</label>\n            <textarea\n              id=\"feedback-notes\"\n              rows=\"3\"\n              placeholder=\"Optional: missing steps, unclear wording, broken links\"\n            ></textarea>\n            <button type=\"button\" class=\"feedback-submit\" id=\"feedback-submit\">\n              <i class=\"fa-solid fa-paper-plane\"></i>\n              Send feedback\n            </button>\n          </div>\n\n          <p\n            class=\"feedback-status\"\n            id=\"feedback-status\"\n            role=\"status\"\n            aria-live=\"polite\"\n          ></p>\n        </section>\n\n        <!-- Page Navigation (Prev/Next) -->\n                                                 \n      </main>\n\n      <!-- Table of Contents (optional) -->\n      <aside class=\"docs-toc\">\n        <div class=\"toc-header\">\n          <h3>On This Page</h3>\n        </div>\n        <nav id=\"toc-nav\" class=\"toc-nav\">\n          <!-- Generated by JavaScript -->\n        </nav>\n\n        <!-- Theme Toggle in TOC -->\n        <button\n          id=\"theme-toggle-docs\"\n          class=\"theme-toggle\"\n          aria-label=\"Toggle theme\"\n        >\n          <i class=\"fa-solid fa-sun\"></i>\n          <i class=\"fa-solid fa-moon\"></i>\n        </button>\n      </aside>\n    </div>\n\n    <script>\n      // Theme Toggle\n      const themeToggle = document.getElementById(\"theme-toggle-docs\");\n      themeToggle?.addEventListener(\"click\", () => {\n        const current = document.documentElement.getAttribute(\"data-theme\");\n        const next = current === \"light\" ? \"dark\" : \"light\";\n        document.documentElement.setAttribute(\"data-theme\", next);\n        localStorage.setItem(\"theme\", next);\n      });\n\n      // Mobile Sidebar Toggle\n      const mobileToggle = document.getElementById(\"mobile-sidebar-toggle\");\n      const sidebar = document.getElementById(\"docs-sidebar\");\n      const overlay = document.getElementById(\"sidebar-overlay\");\n      const sidebarClose = document.getElementById(\"sidebar-close\");\n\n      function toggleSidebar() {\n        sidebar.classList.toggle(\"open\");\n        overlay.classList.toggle(\"active\");\n        document.body.style.overflow = sidebar.classList.contains(\"open\")\n          ? \"hidden\"\n          : \"\";\n      }\n\n      mobileToggle?.addEventListener(\"click\", toggleSidebar);\n      overlay?.addEventListener(\"click\", toggleSidebar);\n      sidebarClose?.addEventListener(\"click\", toggleSidebar);\n\n      // Category Toggle\n      document.querySelectorAll(\".category-toggle\").forEach((toggle) => {\n        toggle.addEventListener(\"click\", () => {\n          const category = toggle.dataset.category;\n          const items = document.getElementById(`category-${category}`);\n          toggle.classList.toggle(\"active\");\n          items.classList.toggle(\"expanded\");\n        });\n      });\n\n      // Generate Table of Contents\n      const content = document.querySelector(\".docs-content article\");\n      const tocNav = document.getElementById(\"toc-nav\");\n\n      if (content && tocNav) {\n        const headings = content.querySelectorAll(\"h2, h3\");\n\n        if (headings.length > 0) {\n          headings.forEach((heading, index) => {\n            // Add ID if not present\n            if (!heading.id) {\n              heading.id = heading.textContent\n                .toLowerCase()\n                .replace(/[^a-z0-9]+/g, \"-\")\n                .replace(/^-|-$/g, \"\");\n            }\n\n            const link = document.createElement(\"a\");\n            link.href = `#${heading.id}`;\n            link.textContent = heading.textContent;\n            link.className = `toc-link toc-${heading.tagName.toLowerCase()}`;\n            tocNav.appendChild(link);\n          });\n\n          // Highlight current section\n          const observer = new IntersectionObserver(\n            (entries) => {\n              entries.forEach((entry) => {\n                if (entry.isIntersecting) {\n                  const id = entry.target.id;\n                  tocNav.querySelectorAll(\".toc-link\").forEach((link) => {\n                    link.classList.toggle(\n                      \"active\",\n                      link.getAttribute(\"href\") === `#${id}`\n                    );\n                  });\n                }\n              });\n            },\n            { rootMargin: \"-20% 0px -80% 0px\" }\n          );\n\n          headings.forEach((heading) => observer.observe(heading));\n        }\n      }\n\n      // Sidebar Search\n      const sidebarSearch = document.getElementById(\"sidebar-search\");\n      sidebarSearch?.addEventListener(\"input\", (e) => {\n        const query = e.target.value.toLowerCase();\n        const items = document.querySelectorAll(\".nav-item\");\n\n        items.forEach((item) => {\n          const text = item.textContent.toLowerCase();\n          const matches = text.includes(query);\n          item.style.display = matches || !query ? \"\" : \"none\";\n\n          // Expand category if item matches\n          if (matches && query) {\n            const category = item.closest(\".category-items\");\n            const toggle = category?.previousElementSibling;\n            category?.classList.add(\"expanded\");\n            toggle?.classList.add(\"active\");\n          }\n        });\n      });\n\n      // Docs micro-feedback (local only)\n      const feedbackCard = document.getElementById(\"feedback-card\");\n      const feedbackButtons = document.querySelectorAll(\".feedback-btn\");\n      const feedbackFollowup = document.getElementById(\"feedback-followup\");\n      const feedbackSubmit = document.getElementById(\"feedback-submit\");\n      const feedbackStatus = document.getElementById(\"feedback-status\");\n      const feedbackNotes = document.getElementById(\"feedback-notes\");\n      const feedbackStorageKey = `docs-feedback:${window.location.pathname}`;\n\n      function completeFeedback(message) {\n        if (feedbackCard) feedbackCard.classList.add(\"feedback-complete\");\n        if (feedbackFollowup) feedbackFollowup.hidden = true;\n        if (feedbackStatus) feedbackStatus.textContent = message;\n        try {\n          localStorage.setItem(feedbackStorageKey, \"submitted\");\n        } catch (err) {\n          console.warn(\"Feedback storage failed\", err);\n        }\n      }\n\n      function maybeDisableFeedback() {\n        let stored = null;\n        try {\n          stored = localStorage.getItem(feedbackStorageKey);\n        } catch (err) {\n          console.warn(\"Feedback storage read failed\", err);\n        }\n\n        if (stored && feedbackCard) {\n          feedbackCard.classList.add(\"feedback-complete\");\n          if (feedbackFollowup) feedbackFollowup.hidden = true;\n          if (feedbackStatus)\n            feedbackStatus.textContent = \"Thanks—feedback already recorded.\";\n        }\n      }\n\n      feedbackButtons.forEach((btn) => {\n        btn.addEventListener(\"click\", () => {\n          const value = btn.dataset.feedback;\n          if (value === \"no\") {\n            if (feedbackFollowup) feedbackFollowup.hidden = false;\n            if (feedbackStatus)\n              feedbackStatus.textContent = \"Tell us what to improve.\";\n          } else {\n            completeFeedback(\"Thanks for the feedback!\");\n          }\n        });\n      });\n\n      feedbackSubmit?.addEventListener(\"click\", () => {\n        const note = feedbackNotes?.value?.trim();\n        const suffix = note ? \" We will review your note.\" : \"\";\n        completeFeedback(`Got it!${suffix}`);\n      });\n\n      maybeDisableFeedback();\n    </script>\n  </body>\n</html>\n","# Common Errors & Troubleshooting\n\nQuick solutions to common issues you might encounter.\n\n## Build Errors\n\n### Jekyll Build Fails\n\n**Error**: `jekyll 3.9.0 | Error:  Permission denied`\n\n**Solution**:\n\n```bash\n# Fix permissions\nchmod -R 755 _site\n\n# Or clean and rebuild\nbundle exec jekyll clean\nbundle exec jekyll build\n```\n\n**Error**: `Dependency Error: Yikes! It looks like you don't have bundler`\n\n**Solution**:\n\n```bash\ngem install bundler\nbundle install\n```\n\n**Error**: `Could not find gem 'jekyll'`\n\n**Solution**:\n\n```bash\nbundle install\n# Or\ngem install jekyll\n```\n\n### Liquid Syntax Errors\n\n**Error**: `Liquid Exception: Liquid syntax error`\n\n**Solution**:\n\n{% raw %}\n\n```liquid\n<!-- Bad: Unclosed tag -->\n{% for item in array\n\n<!-- Good: Properly closed -->\n{% for item in array %}\n  {{ item }}\n{% endfor %}\n```\n\n{% endraw %}\n\n**Error**: `undefined method 'map' for nil:NilClass`\n\n**Solution**:\n\n```liquid\n<!-- Check if variable exists first -->\n{% if site.data.mods.modpacks %}\n  {% assign names = site.data.mods.modpacks | map: \"name\" %}\n{% endif %}\n```\n\n### YAML Frontmatter Issues\n\n**Error**: `YAML Exception reading file`\n\n**Solution**:\n\n```yaml\n# Bad: Missing closing quotes\n---\ntitle: \"My Title\n---\n\n# Good: Properly quoted\n---\ntitle: \"My Title\"\ndescription: \"My description\"\n---\n\n# Or use literal block for multiline\n---\ntitle: My Title\ndescription: |\n  This is a longer\n  description text\n---\n```\n\n## Styling Issues\n\n### Styles Not Loading\n\n**Problem**: CSS changes not appearing\n\n**Solutions**:\n\n```bash\n# 1. Clear cache\nbundle exec jekyll clean\nbundle exec jekyll build\n\n# 2. Hard refresh browser\n# Mac: Cmd + Shift + R\n# Windows/Linux: Ctrl + Shift + R\n\n# 3. Check file path\n# Should be: {{ '/assets/css/main.css' | relative_url }}\n# Not: /assets/css/main.css (without filter)\n```\n\n### CSS Not Compiling\n\n**Error**: `Sass Error: Invalid CSS`\n\n**Solution**:\n\n```scss\n// Bad: Missing semicolon\n.element {\n  color: red\n  background: blue;\n}\n\n// Good:\n.element {\n  color: red;\n  background: blue;\n}\n```\n\n### Theme Toggle Not Working\n\n**Problem**: Theme switch doesn't persist\n\n**Solution**:\n\n```javascript\n// Check localStorage is working\nif (typeof Storage !== \"undefined\") {\n  localStorage.setItem(\"theme\", \"dark\");\n  console.log(localStorage.getItem(\"theme\"));\n} else {\n  console.error(\"LocalStorage not supported\");\n}\n\n// Ensure theme is set on page load\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n  const theme = localStorage.getItem(\"theme\") || \"dark\";\n  document.documentElement.setAttribute(\"data-theme\", theme);\n});\n```\n\n## Asset Loading Issues\n\n### Images Not Displaying\n\n**Problem**: Broken image icons\n\n**Solutions**:\n\n```liquid\n<!-- Bad: Absolute path without baseurl -->\n<img src=\"/assets/images/logo.png\">\n\n<!-- Good: Use relative_url filter -->\n<img src=\"{{ '/assets/images/logo.png' | relative_url }}\">\n\n<!-- For external URLs -->\n<img src=\"https://cdn.modrinth.com/data/abc/icon.png\">\n```\n\n**Check file exists**:\n\n```bash\n# List image directory\nls -la assets/images/\n\n# Check file permissions\nchmod 644 assets/images/logo.png\n```\n\n### Font Awesome Icons Not Showing\n\n**Problem**: Boxes or missing icons\n\n**Solutions**:\n\n```html\n<!-- 1. Verify CDN link is correct -->\n<link\n  rel=\"stylesheet\"\n  href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\"\n/>\n\n<!-- 2. Check icon class syntax -->\n<!-- Bad -->\n<i class=\"fa-gear\"></i>\n\n<!-- Good -->\n<i class=\"fa-solid fa-gear\"></i>\n```\n\n**Test icon loading**:\n\n```javascript\n// Check if Font Awesome loaded\nif (window.FontAwesome) {\n  console.log(\"Font Awesome loaded\");\n} else {\n  console.error(\"Font Awesome not loaded\");\n}\n```\n\n## Data Issues\n\n### Modpack Data Not Rendering\n\n**Problem**: Projects page is empty\n\n**Solutions**:\n\n```bash\n# 1. Check JSON is valid\ncat _data/mods.json | jq .\n\n# 2. Verify file location\nls -la _data/mods.json\n\n# 3. Check YAML config\ngrep -A 5 \"data_dir\" _config.yml\n```\n\n**Debug in template**:\n\n```liquid\n<!-- Check if data exists -->\n{% if site.data.mods %}\n  <p>Data loaded: {{ site.data.mods.modpacks | size }} modpacks</p>\n{% else %}\n  <p>No data found</p>\n{% endif %}\n\n<!-- Inspect data structure -->\n<pre>{{ site.data.mods | jsonify }}</pre>\n```\n\n### JSON Parsing Errors\n\n**Error**: `Unexpected token in JSON`\n\n**Solution**:\n\n```bash\n# Validate JSON\ncat _data/mods.json | python -m json.tool\n\n# Or use jq\njq '.' _data/mods.json\n```\n\nCommon JSON mistakes:\n\n```json\n// Bad: Trailing comma\n{\n  \"modpacks\": [\n    {\"name\": \"Pack 1\"},\n  ]\n}\n\n// Good: No trailing comma\n{\n  \"modpacks\": [\n    {\"name\": \"Pack 1\"}\n  ]\n}\n\n// Bad: Single quotes\n{'name': 'value'}\n\n// Good: Double quotes\n{\"name\": \"value\"}\n```\n\n## Deployment Issues\n\n### GitHub Pages 404 Error\n\n**Problem**: Pages work locally but 404 on GitHub Pages\n\n**Solutions**:\n\n```yaml\n# 1. Check baseurl in _config.yml\nbaseurl: \"/your-repo-name\" # Must match repo name\nurl: \"https://username.github.io\"\n# 2. Ensure GitHub Pages is enabled\n# Settings > Pages > Source: GitHub Actions or main branch\n```\n\n```liquid\n<!-- Use relative_url in all links -->\n<a href=\"{{ '/docs/' | relative_url }}\">Docs</a>\n<link rel=\"stylesheet\" href=\"{{ '/assets/css/main.css' | relative_url }}\">\n```\n\n### Build Succeeds But Site Not Updating\n\n**Solutions**:\n\n```bash\n# 1. Clear GitHub Actions cache\n# Go to Actions > Select workflow > Re-run jobs > Clear cache\n\n# 2. Check deployment status\n# Actions tab > View latest workflow run\n\n# 3. Verify _config.yml excludes\nexclude:\n  - node_modules/\n  - vendor/\n  - .git/\n```\n\n### Netlify Build Fails\n\n**Error**: `Command failed with exit code 127`\n\n**Solution**:\n\n```toml\n# netlify.toml\n[build.environment]\n  RUBY_VERSION = \"3.1\"\n\n[build]\n  command = \"bundle install && bundle exec jekyll build\"\n  publish = \"_site\"\n```\n\n## Performance Issues\n\n### Slow Build Times\n\n**Problem**: Build takes 30+ seconds\n\n**Solutions**:\n\n```yaml\n# 1. Exclude unnecessary files\nexclude:\n  - node_modules/\n  - src/\n  - vendor/\n  - .git/\n  - README.md\n\n# 2. Use incremental builds (dev only)\n# bundle exec jekyll serve --incremental\n\n# 3. Limit collection size\ncollections:\n  docs:\n    output: true\n```\n\n### Slow Page Load\n\n**Problem**: Pages take 5+ seconds to load\n\n**Solutions**:\n\n```html\n<!-- 1. Defer non-critical CSS -->\n<link\n  rel=\"preload\"\n  href=\"/assets/css/main.css\"\n  as=\"style\"\n  onload=\"this.rel='stylesheet'\"\n/>\n\n<!-- 2. Lazy load images -->\n<img src=\"image.jpg\" loading=\"lazy\" />\n\n<!-- 3. Defer JavaScript -->\n<script src=\"/assets/js/main.js\" defer></script>\n```\n\nSee [Performance Guide](performance.html) for more.\n\n## Search & Filter Issues\n\n### Search Not Working\n\n**Problem**: Typing in search input doesn't filter results\n\n**Debug**:\n\n```javascript\n// Check if docs are loaded\nconsole.log(\"Total docs:\", allDocs.length);\n\n// Test search function\nconst results = searchDocs(\"setup\");\nconsole.log(\"Search results:\", results);\n\n// Verify event listener\ndocument.getElementById(\"docs-search\").addEventListener(\"input\", (e) => {\n  console.log(\"Search query:\", e.target.value);\n});\n```\n\n**Common fixes**:\n\n```javascript\n// Ensure correct element IDs\nconst searchInput = document.getElementById(\"docs-search\");\nconst categorySelect = document.getElementById(\"docs-category\");\n\n// Case-insensitive search\nconst query = searchInput.value.toLowerCase();\nconst matches = allDocs.filter((doc) =>\n  doc.title.toLowerCase().includes(query)\n);\n```\n\n## Browser Compatibility\n\n### Site Broken in Safari\n\n**Problem**: CSS Grid not working\n\n**Solution**:\n\n```css\n/* Add fallback for older browsers */\n.grid {\n  display: flex;\n  flex-wrap: wrap;\n}\n\n@supports (display: grid) {\n  .grid {\n    display: grid;\n    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n  }\n}\n```\n\n### JavaScript Errors in IE11\n\n**Problem**: `Unexpected token` errors\n\n**Solution**:\n\n```javascript\n// Don't use arrow functions in IE11\n// Bad:\nconst myFunc = () => {};\n\n// Good:\nvar myFunc = function () {};\n\n// Or add polyfills\n// <script src=\"https://polyfill.io/v3/polyfill.min.js\"></script>\n```\n\n## Git Issues\n\n### Large Files Rejected\n\n**Error**: `remote: error: File too large`\n\n**Solution**:\n\n```bash\n# Remove large file from history\ngit filter-branch --force --index-filter \\\n  'git rm --cached --ignore-unmatch path/to/large-file' \\\n  --prune-empty --tag-name-filter cat -- --all\n\n# Force push\ngit push origin --force --all\n\n# Add to .gitignore\necho \"path/to/large-files/\" >> .gitignore\n```\n\n### Merge Conflicts\n\n**Problem**: `CONFLICT (content): Merge conflict in file`\n\n**Solution**:\n\n```bash\n# View conflicted files\ngit status\n\n# Edit file to resolve conflicts\n# Look for:\n<<<<<<< HEAD\nYour changes\n=======\nTheir changes\n>>>>>>> branch-name\n\n# Choose one or combine, then:\ngit add resolved-file.txt\ngit commit -m \"Resolved merge conflict\"\n```\n\n## Debugging Tips\n\n### Enable Verbose Output\n\n```bash\n# Jekyll\nbundle exec jekyll build --verbose\n\n# Show full error traces\nbundle exec jekyll build --trace\n\n# Profile build time\nbundle exec jekyll build --profile\n```\n\n### Browser DevTools\n\n```javascript\n// Check for JavaScript errors\n// Open DevTools > Console\n\n// Inspect element styles\n// Right-click > Inspect\n\n// Network tab for asset loading\n// DevTools > Network > Reload page\n```\n\n### Liquid Debugging\n\n```liquid\n<!-- Print variable contents -->\n{{ variable | inspect }}\n\n<!-- Check variable type -->\n{% if variable == nil %}\n  Variable is nil\n{% elsif variable == blank %}\n  Variable is blank\n{% else %}\n  Variable exists: {{ variable }}\n{% endif %}\n\n<!-- Debug entire site data -->\n<pre>{{ site | jsonify }}</pre>\n```\n\n## Getting Help\n\n### Before Asking\n\n1. **Search existing issues** on GitHub\n2. **Check documentation** thoroughly\n3. **Test in fresh browser** (incognito mode)\n4. **Try latest version** of dependencies\n5. **Create minimal reproduction** of the issue\n\n### Where to Ask\n\n- [Jekyll Talk Forum](https://talk.jekyllrb.com/)\n- [Stack Overflow](https://stackoverflow.com/questions/tagged/jekyll) - Tag with `jekyll`\n- [GitHub Issues](https://github.com/jekyll/jekyll/issues)\n- Project-specific Discord/community\n\n### Provide Details\n\nWhen reporting issues, include:\n\n```markdown\n**Environment:**\n\n- OS: macOS 13.0\n- Ruby: 3.1.2\n- Jekyll: 3.9.0\n- Browser: Chrome 120\n\n**Steps to reproduce:**\n\n1. Run `bundle exec jekyll serve`\n2. Navigate to /projects/\n3. Click on first project\n\n**Expected:** Project page loads\n**Actual:** 404 error\n\n**Logs:**\n```\n\n[error log here]\n\n```\n\n```\n\n## Next Steps\n\n- [FAQ](faq.html) - Frequently asked questions\n- [Contributing](contributing.html) - Report bugs and contribute\n- [GitHub Actions](github-actions.html) - Automate testing\n","# Content Guidelines\n\nMaintain consistent, high-quality content across your ABC showcase.\n\n## Writing Style\n\n### Voice & Tone\n\n**Be Clear and Concise:**\n\n```markdown\n<!-- Good -->\n\nInstall dependencies with `bundle install`.\n\n<!-- Avoid -->\n\nYou should probably install the dependencies using the bundle install command.\n```\n\n**Be Helpful:**\n\n```markdown\n<!-- Good -->\n\nIf the build fails, check your Ruby version with `ruby -v`.\n\n<!-- Avoid -->\n\nThe build might fail for various reasons.\n```\n\n**Be Friendly:**\n\n```markdown\n<!-- Good -->\n\nGreat! Your site is now live.\n\n<!-- Avoid -->\n\nThe deployment process has completed successfully.\n```\n\n### Grammar & Formatting\n\n**Use Active Voice:**\n\n```markdown\n<!-- Good -->\n\nRun `jekyll build` to compile your site.\n\n<!-- Avoid -->\n\nYour site can be compiled by running `jekyll build`.\n```\n\n**Use Present Tense:**\n\n```markdown\n<!-- Good -->\n\nThe theme toggle changes between light and dark mode.\n\n<!-- Avoid -->\n\nThe theme toggle will change between light and dark mode.\n```\n\n**Use Second Person:**\n\n```markdown\n<!-- Good -->\n\nYou can customize colors in `src/styles/variables.css`.\n\n<!-- Avoid -->\n\nUsers can customize colors in `src/styles/variables.css`.\n```\n\n## Documentation Structure\n\n### Page Template\n\n```yaml\n---\nlayout: docs\ntitle: Clear, Descriptive Title\ndescription: One-sentence summary of what this page covers.\nnav_order: 5\ncategory: Setup\ntags: [relevant, searchable, tags]\n---\n\n# Page Title\n\nBrief introduction explaining what users will learn.\n\n## Section 1\n\nContent with examples...\n\n## Section 2\n\nMore content...\n\n## Next Steps\n\n- [Related Page 1](link1.html)\n- [Related Page 2](link2.html)\n```\n\n### Headings\n\nUse hierarchical structure:\n\n```markdown\n# H1 - Page Title (only one per page)\n\n## H2 - Major Section\n\n### H3 - Subsection\n\n#### H4 - Minor Point\n\n##### H5 - Rarely Used\n\n###### H6 - Avoid\n```\n\n**Good Heading Structure:**\n\n```markdown\n# Deployment Guide\n\n## Prerequisites\n\n## GitHub Pages\n\n### Configuration\n\n### Deployment\n\n## Netlify\n\n### Configuration\n```\n\n## Code Examples\n\n### Format Code Blocks\n\nUse language-specific syntax highlighting:\n\n````markdown\n```bash\n# Bash commands\nbundle exec jekyll build\n```\n\n```yaml\n# YAML configuration\ntitle: My Site\nbaseurl: /my-site\n```\n\n```javascript\n// JavaScript code\nfunction toggleTheme() {\n  // ...\n}\n```\n\n```liquid\n<!-- Liquid templates -->\n{% for item in array %}\n  {{ item }}\n{% endfor %}\n```\n````\n\n### Inline Code\n\nUse backticks for:\n\n- Commands: `bundle install`\n- File names: `_config.yml`\n- Code variables: `site.title`\n- Short code: `npm start`\n\n```markdown\nEdit the `_config.yml` file and set `baseurl` to your repository name.\n```\n\n### Example Comments\n\n```javascript\n// Good: Explain WHY, not WHAT\n// Cache the theme value to avoid repeated lookups\nconst theme = localStorage.getItem(\"theme\");\n\n// Avoid: Explaining obvious code\n// Get theme from localStorage\nconst theme = localStorage.getItem(\"theme\");\n```\n\n## Links & References\n\n### Internal Links\n\n```liquid\n<!-- Use relative_url filter -->\nSee the [setup guide]({{ '/docs/setup/' | relative_url }}).\n\n<!-- Or for same section -->\nSee [Configuration](#configuration) below.\n```\n\n### External Links\n\n```markdown\n<!-- Open in new tab with security -->\n\nVisit [Modrinth](https://modrinth.com/){:target=\"\\_blank\" rel=\"noopener\"}.\n\n<!-- Or in HTML -->\n\n<a href=\"https://modrinth.com/\" target=\"_blank\" rel=\"noopener\">Modrinth</a>\n```\n\n### Link Text\n\n```markdown\n<!-- Good: Descriptive -->\n\nRead the [deployment guide](deployment.html) for more details.\n\n<!-- Avoid: Generic -->\n\nClick [here](deployment.html) to learn more.\n```\n\n## Lists\n\n### Unordered Lists\n\n```markdown\n- First item\n- Second item\n  - Nested item\n  - Another nested item\n- Third item\n```\n\n### Ordered Lists\n\n```markdown\n1. First step\n2. Second step\n   1. Substep\n   2. Another substep\n3. Third step\n```\n\n### Task Lists\n\n```markdown\n- [x] Completed task\n- [ ] Pending task\n- [ ] Another pending task\n```\n\n## Tables\n\n### Simple Tables\n\n```markdown\n| Header 1 | Header 2 | Header 3 |\n| -------- | -------- | -------- |\n| Cell 1   | Cell 2   | Cell 3   |\n| Cell 4   | Cell 5   | Cell 6   |\n```\n\n### Alignment\n\n```markdown\n| Left | Center | Right |\n| :--- | :----: | ----: |\n| L1   |   C1   |    R1 |\n| L2   |   C2   |    R2 |\n```\n\n### Complex Tables\n\n```markdown\n| Field       | Type   | Required | Description       |\n| ----------- | ------ | -------- | ----------------- |\n| `slug`      | string | Yes      | Unique identifier |\n| `name`      | string | Yes      | Display name      |\n| `downloads` | number | No       | Download count    |\n```\n\n## Admonitions & Callouts\n\n### Info Boxes\n\n```markdown\n> **Note:** This feature requires Jekyll 3.9 or higher.\n\n> **Tip:** Use incremental builds during development for faster rebuilds.\n\n> **Warning:** Clearing the cache will remove all saved preferences.\n\n> **Important:** Always backup your data before making major changes.\n```\n\n### Code with Explanations\n\n````markdown\nRun the following command:\n\n```bash\nbundle exec jekyll build --verbose\n```\n````\n\nThis will:\n\n- Build your site\n- Show detailed output\n- Help identify errors\n\n````\n\n## Images\n\n### Inline Images\n\n```markdown\n![Alt text description](/assets/images/screenshot.png)\n````\n\n### Images with Captions\n\n```html\n<figure>\n  <img src=\"/assets/images/demo.png\" alt=\"Demo screenshot\" />\n  <figcaption>The project card layout showing icons and badges</figcaption>\n</figure>\n```\n\n### Responsive Images\n\n```html\n<picture>\n  <source srcset=\"/assets/images/hero-large.webp\" media=\"(min-width: 1024px)\" />\n  <source srcset=\"/assets/images/hero-medium.webp\" media=\"(min-width: 768px)\" />\n  <img src=\"/assets/images/hero-small.webp\" alt=\"Hero banner\" />\n</picture>\n```\n\n## File & Path References\n\n### Consistent Formatting\n\n```markdown\n<!-- Files -->\n\nEdit `_config.yml`\nOpen `src/styles/layout.css`\nCheck `_data/mods.json`\n\n<!-- Directories -->\n\nNavigate to `_docs/`\nCreate `assets/images/`\n\n<!-- Paths -->\n\n`/docs/setup/`\n`https://yoursite.com/projects/`\n```\n\n### File Trees\n\n```\nproject/\n├── _config.yml\n├── _data/\n│   └── mods.json\n├── _docs/\n│   ├── getting-started.md\n│   └── setup.md\n├── assets/\n│   ├── css/\n│   └── images/\n└── index.md\n```\n\n## Command Line Examples\n\n### Format\n\n```bash\n# Comment explaining what this does\ncommand --flag argument\n\n# Example output (optional)\n# > Success message\n```\n\n### Multiple Commands\n\n```bash\n# Install dependencies\nbundle install\n\n# Build the site\nbundle exec jekyll build\n\n# Serve locally\nbundle exec jekyll serve\n```\n\n### Interactive Sessions\n\n```bash\n$ git status\nOn branch main\nYour branch is up to date with 'origin/main'.\n\n$ git add .\n$ git commit -m \"Update documentation\"\n[main abc1234] Update documentation\n 1 file changed, 10 insertions(+)\n```\n\n## Modpack Descriptions\n\n### Structure\n\n```markdown\n**Name**: Clear, memorable name\n**Description**: 1-2 sentences summarizing the pack\n**Key Features**:\n\n- Feature 1\n- Feature 2\n- Feature 3\n\n**Recommended For**: Target audience\n```\n\n### Example\n\n```markdown\n**Name**: Create: Engineering Adventures\n\n**Description**: A technology-focused modpack centered around the Create mod, offering complex automation challenges and engineering puzzles suitable for both solo and multiplayer gameplay.\n\n**Key Features**:\n\n- 150+ mods focused on automation and engineering\n- Custom quests guiding progression\n- Balanced for survival gameplay\n- Multiplayer-optimized\n\n**Recommended For**: Players who enjoy technical challenges and building complex machines\n```\n\n### Writing Tips\n\n**Be Specific:**\n\n```markdown\n<!-- Good -->\n\nIncludes 50+ magic mods with custom spell progression\n\n<!-- Avoid -->\n\nHas magic stuff\n```\n\n**Highlight Unique Features:**\n\n```markdown\n<!-- Good -->\n\nFeatures a unique progression system that unlocks mods as you complete challenges\n\n<!-- Avoid -->\n\nHas progression\n```\n\n**Mention Prerequisites:**\n\n```markdown\n<!-- Good -->\n\nRequires 8GB+ RAM. Best with 16GB.\n\n<!-- Avoid -->\n\nNeeds memory\n```\n\n## Version Numbers\n\n### Format\n\n```markdown\n<!-- Semantic versioning -->\n\nv1.2.3\nVersion 2.0.0\n\n<!-- Minecraft versions -->\n\n1.20.1\n1.19.2-1.20.1\n\n<!-- Mod loader versions -->\n\nFabric 0.14.21\nForge 47.1.0\n```\n\n## Dates & Times\n\n### Format\n\n```markdown\n<!-- ISO 8601 for data -->\n\n2025-12-10T10:30:00Z\n\n<!-- Human-readable for display -->\n\nDecember 10, 2025\nDec 10, 2025\n2025-12-10\n```\n\n## Accessibility\n\n### Alt Text\n\n```markdown\n<!-- Descriptive alt text -->\n\n![Project card showing Create Adventures modpack with green icon and 50K downloads](/path/to/image.png)\n\n<!-- Not just the file name -->\n\n![screenshot-1.png](/path/to/image.png)\n```\n\n### Link Descriptions\n\n```markdown\n<!-- Good -->\n\nRead the [accessibility guide](accessibility.html) for WCAG compliance details\n\n<!-- Avoid -->\n\n[Click here](accessibility.html) for more\n```\n\n## SEO Best Practices\n\n### Meta Descriptions\n\n```yaml\n---\ntitle: Setup Guide\ndescription: Learn how to set up your ABC showcase in under 5 minutes with this step-by-step guide.\n---\n```\n\n**Requirements:**\n\n- 150-160 characters\n- Include target keyword\n- Be compelling\n- Unique per page\n\n### Keywords in Content\n\n```markdown\n<!-- Natural keyword usage -->\n\nThis **deployment guide** shows you how to **deploy your Jekyll site** to GitHub Pages, Netlify, or Vercel.\n\n<!-- Avoid keyword stuffing -->\n\nDeploy deployment deploying Jekyll Jekyll site site deploy...\n```\n\n## Review Checklist\n\nBefore publishing content:\n\n- [ ] Spelling and grammar checked\n- [ ] Code examples tested and working\n- [ ] Links verified (no 404s)\n- [ ] Images optimized and have alt text\n- [ ] Headings follow hierarchy (H1 → H2 → H3)\n- [ ] Consistent formatting throughout\n- [ ] Meta description written (150-160 chars)\n- [ ] Tags relevant and useful\n- [ ] Category assigned correctly\n- [ ] Mobile-friendly formatting\n- [ ] Accessible to screen readers\n- [ ] Next steps / related links included\n\n## Style Guide Summary\n\n| Element     | Format                              |\n| ----------- | ----------------------------------- |\n| Commands    | `backticks`                         |\n| Files       | `_config.yml`                       |\n| Directories | `_docs/`                            |\n| Variables   | `site.title`                        |\n| Links       | `[text](url)`                       |\n| Emphasis    | **bold** for UI, _italic_ for terms |\n| Code blocks | Use language syntax highlighting    |\n| Lists       | Parallel structure                  |\n| Headings    | Title case                          |\n\n## Common Mistakes\n\n### Inconsistent Terminology\n\n```markdown\n<!-- Pick one and stick with it -->\n\nmodpack / mod pack\nsetup / set up (noun vs verb)\nGitHub / Github\n```\n\n### Overcomplicating\n\n```markdown\n<!-- Good -->\n\nClick the theme toggle to switch between light and dark mode.\n\n<!-- Too complex -->\n\nIn order to facilitate the modification of the visual appearance schema, one must engage with the theme selection mechanism located in the navigation component.\n```\n\n### Missing Context\n\n````markdown\n<!-- Bad: No context -->\n\nRun this command:\n\n```bash\nnpm install\n```\n````\n\n<!-- Good: With context -->\n\nInstall Node dependencies:\n\n```bash\nnpm install\n```\n\n```\n\n## Next Steps\n\n- [Adding Modpacks](add-modpack.html) - Content creation\n- [Contributing Guide](contributing.html) - Submission process\n- [SEO Guide](seo-guide.html) - Optimize content\n```\n","## How to Contribute\n\nWe welcome contributions from the community! Whether it's bug reports, feature suggestions, or code improvements, your help is valuable.\n\n## Reporting Issues\n\nFound a bug or have a suggestion? Open an issue on [GitHub]({{ site.social.github }}/issues):\n\n1. **Check existing issues** to avoid duplicates\n2. **Be clear and descriptive** - include steps to reproduce for bugs\n3. **Include screenshots** if relevant\n4. **Mention your environment** - browser, OS, etc.\n\n## Suggesting Features\n\nHave an idea to improve the showcase?\n\n1. **Open a GitHub discussion** or issue with the `enhancement` label\n2. **Explain the use case** - why would this be useful?\n3. **Show examples** - mockups or references are helpful\n4. **Get feedback** - discuss with maintainers before starting work\n\n## Contributing Code\n\n### Setup\n\n```bash\ngit clone {{ site.social.github }}.git\ncd abc-site\nbundle install\nnpm install\nbundle exec jekyll serve --livereload\n```\n\n### Making Changes\n\n1. **Create a branch** - `git checkout -b feature/your-feature-name`\n2. **Make your changes** - keep commits focused and descriptive\n3. **Test locally** - verify the site builds and works correctly\n4. **Follow conventions** - match existing code style and patterns\n5. **Push and create a PR** - describe what you changed and why\n\n### Code Style\n\n- **CSS**: Use existing variables and patterns; keep it minimal\n- **JavaScript**: Vanilla JS, no frameworks; add comments for complex logic\n- **Markdown**: Use consistent formatting; check Jekyll renders correctly\n- **Naming**: Use kebab-case for files, camelCase for variables\n\n### PR Guidelines\n\n- Link related issues in the PR description\n- Provide before/after screenshots for UI changes\n- Ensure all checks pass (if applicable)\n- Be open to feedback and revisions\n\n## Documentation\n\nHelp improve the docs:\n\n1. **Fix typos** - spot a mistake? Let us know\n2. **Clarify sections** - is something unclear?\n3. **Add examples** - show how to use features\n4. **Translate** - help reach more developers\n\n## Community\n\n- **GitHub Discussions** - Ask questions, share ideas\n- **Discord** - Join our community server (if available)\n- **Twitter** - Follow for updates and announcements\n\n## Code of Conduct\n\nPlease be respectful and constructive. We're all here to learn and build together.\n\n---\n\nThank you for contributing! 🎉\n","# CSS Variables Reference\n\nComplete reference for all CSS custom properties used in the ABC showcase.\n\n## Color Variables\n\n### Background Colors\n\n```css\n:root {\n  --bg-primary: #1a1a1a; /* Main background */\n  --bg-secondary: #222222; /* Cards, secondary surfaces */\n  --bg-tertiary: #2a2a2a; /* Hover states, elevated surfaces */\n  --bg-overlay: rgba(31, 31, 31, 0.9); /* Modal/navbar overlays */\n}\n\n[data-theme=\"light\"] {\n  --bg-primary: #ffffff;\n  --bg-secondary: #f5f5f5;\n  --bg-tertiary: #e0e0e0;\n  --bg-overlay: rgba(255, 255, 255, 0.9);\n}\n```\n\n### Text Colors\n\n```css\n:root {\n  --text: #e0e0e0; /* Primary text */\n  --text-secondary: #b0b0b0; /* Secondary text */\n  --text-muted: #999999; /* Muted/disabled text */\n  --text-inverse: #1a1a1a; /* Text on accent backgrounds */\n}\n\n[data-theme=\"light\"] {\n  --text: #212121;\n  --text-secondary: #424242;\n  --text-muted: #666666;\n  --text-inverse: #ffffff;\n}\n```\n\n### Accent Colors\n\n```css\n:root {\n  --accent-primary: #4caf50; /* Primary actions, links */\n  --accent-secondary: #2196f3; /* Secondary actions */\n  --accent-tertiary: #9c27b0; /* Tertiary highlights */\n  --accent-success: #4caf50; /* Success states */\n  --accent-warning: #ff9800; /* Warning states */\n  --accent-error: #f44336; /* Error states */\n  --accent-info: #2196f3; /* Info messages */\n}\n```\n\n### Border Colors\n\n```css\n:root {\n  --border: #333333; /* Default borders */\n  --border-light: #404040; /* Light borders */\n  --border-dark: #2a2a2a; /* Dark borders */\n  --border-focus: var(--accent-primary); /* Focus states */\n}\n\n[data-theme=\"light\"] {\n  --border: #e0e0e0;\n  --border-light: #f0f0f0;\n  --border-dark: #d0d0d0;\n}\n```\n\n## Spacing Variables\n\n### Base Spacing\n\n```css\n:root {\n  --spacing-xs: 4px;\n  --spacing-sm: 8px;\n  --spacing-md: 16px;\n  --spacing-lg: 24px;\n  --spacing-xl: 32px;\n  --spacing-2xl: 48px;\n  --spacing-3xl: 64px;\n}\n```\n\n### Container Spacing\n\n```css\n:root {\n  --container-padding: 20px; /* Mobile padding */\n  --container-max-width: 1200px;\n  --section-spacing: 80px; /* Between sections */\n  --card-gap: 16px; /* Grid gap for cards */\n}\n\n@media (min-width: 768px) {\n  :root {\n    --container-padding: 40px;\n  }\n}\n```\n\n## Typography Variables\n\n### Font Families\n\n```css\n:root {\n  --font-body: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen,\n    Ubuntu, Cantarell, sans-serif;\n  --font-heading: var(--font-body);\n  --font-mono: \"Monaco\", \"Courier New\", \"Courier\", monospace;\n}\n```\n\n### Font Sizes\n\n```css\n:root {\n  --font-xs: 12px;\n  --font-sm: 14px;\n  --font-md: 16px;\n  --font-lg: 18px;\n  --font-xl: 24px;\n  --font-2xl: 32px;\n  --font-3xl: 48px;\n  --font-4xl: 64px;\n}\n```\n\n### Font Weights\n\n```css\n:root {\n  --font-light: 300;\n  --font-normal: 400;\n  --font-medium: 500;\n  --font-semibold: 600;\n  --font-bold: 700;\n}\n```\n\n### Line Heights\n\n```css\n:root {\n  --line-height-tight: 1.2;\n  --line-height-normal: 1.5;\n  --line-height-relaxed: 1.75;\n  --line-height-loose: 2;\n}\n```\n\n## Layout Variables\n\n### Border Radius\n\n```css\n:root {\n  --radius-sm: 4px;\n  --radius-md: 8px;\n  --radius-lg: 12px;\n  --radius-xl: 16px;\n  --radius-full: 999px; /* Pills/circular */\n}\n```\n\n### Shadows\n\n```css\n:root {\n  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.1);\n  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);\n  --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.2);\n  --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.3);\n}\n\n[data-theme=\"light\"] {\n  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);\n  --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);\n  --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);\n  --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.15);\n}\n```\n\n### Z-Index Layers\n\n```css\n:root {\n  --z-base: 1;\n  --z-dropdown: 100;\n  --z-sticky: 200;\n  --z-fixed: 300;\n  --z-modal-backdrop: 400;\n  --z-modal: 500;\n  --z-popover: 600;\n  --z-tooltip: 700;\n}\n```\n\n## Effects Variables\n\n### Transitions\n\n```css\n:root {\n  --transition-fast: 0.1s ease;\n  --transition-normal: 0.2s ease;\n  --transition-slow: 0.3s ease;\n  --transition-all: all 0.2s ease;\n}\n```\n\n### Backdrop Blur\n\n```css\n:root {\n  --blur-sm: 5px;\n  --blur-md: 10px;\n  --blur-lg: 20px;\n  --blur-xl: 40px;\n}\n```\n\n### Opacity\n\n```css\n:root {\n  --opacity-disabled: 0.5;\n  --opacity-hover: 0.8;\n  --opacity-overlay: 0.9;\n}\n```\n\n## Component-Specific Variables\n\n### Navbar\n\n```css\n:root {\n  --navbar-height: 64px;\n  --navbar-bg: var(--bg-overlay);\n  --navbar-blur: var(--blur-md);\n  --navbar-padding: var(--spacing-md);\n}\n```\n\n### Cards\n\n```css\n:root {\n  --card-bg: var(--bg-secondary);\n  --card-border: var(--border);\n  --card-radius: var(--radius-md);\n  --card-padding: var(--spacing-lg);\n  --card-shadow: var(--shadow-md);\n  --card-hover-shadow: var(--shadow-lg);\n}\n```\n\n### Buttons\n\n```css\n:root {\n  --button-bg: var(--accent-primary);\n  --button-text: var(--text-inverse);\n  --button-radius: var(--radius-md);\n  --button-padding: var(--spacing-sm) var(--spacing-md);\n  --button-hover-opacity: var(--opacity-hover);\n}\n```\n\n### Pills/Tags\n\n```css\n:root {\n  --pill-bg: rgba(76, 175, 80, 0.15);\n  --pill-text: var(--accent-primary);\n  --pill-border: var(--accent-primary);\n  --pill-radius: var(--radius-full);\n  --pill-padding: 4px 12px;\n}\n```\n\n### Forms\n\n```css\n:root {\n  --input-bg: var(--bg-secondary);\n  --input-border: var(--border);\n  --input-text: var(--text);\n  --input-placeholder: var(--text-muted);\n  --input-focus-border: var(--accent-primary);\n  --input-radius: var(--radius-md);\n  --input-padding: var(--spacing-sm) var(--spacing-md);\n}\n```\n\n## Usage Examples\n\n### Basic Usage\n\n```css\n.my-element {\n  background: var(--bg-secondary);\n  color: var(--text);\n  padding: var(--spacing-md);\n  border-radius: var(--radius-md);\n  transition: var(--transition-normal);\n}\n```\n\n### With Fallbacks\n\n```css\n.my-element {\n  color: var(--text, #e0e0e0);\n  font-size: var(--font-md, 16px);\n}\n```\n\n### Computed Values\n\n```css\n.my-element {\n  /* Calculate based on variables */\n  padding: calc(var(--spacing-md) * 2);\n  margin: calc(var(--spacing-lg) + 8px);\n\n  /* Combine variables */\n  border: 1px solid var(--border);\n  box-shadow: var(--shadow-md);\n}\n```\n\n### Dynamic Theme Colors\n\n```css\n.custom-accent {\n  --my-accent: #ff5722;\n  background: var(--my-accent);\n  border-color: var(--my-accent);\n}\n\n.custom-accent:hover {\n  background: color-mix(in srgb, var(--my-accent) 80%, white);\n}\n```\n\n## Responsive Variables\n\n### Breakpoints\n\nDefine custom breakpoints:\n\n```css\n:root {\n  --breakpoint-sm: 640px;\n  --breakpoint-md: 768px;\n  --breakpoint-lg: 1024px;\n  --breakpoint-xl: 1280px;\n}\n```\n\n### Responsive Spacing\n\n```css\n:root {\n  --section-spacing: 40px;\n}\n\n@media (min-width: 768px) {\n  :root {\n    --section-spacing: 80px;\n  }\n}\n\n@media (min-width: 1024px) {\n  :root {\n    --section-spacing: 120px;\n  }\n}\n```\n\n## Advanced Techniques\n\n### Scoped Variables\n\n```css\n.dark-section {\n  --bg-primary: #000000;\n  --text: #ffffff;\n\n  background: var(--bg-primary);\n  color: var(--text);\n}\n```\n\n### Color Manipulation\n\n```css\n:root {\n  --accent-rgb: 76, 175, 80;\n}\n\n.element {\n  background: rgb(var(--accent-rgb));\n  border: 1px solid rgba(var(--accent-rgb), 0.3);\n  box-shadow: 0 4px 12px rgba(var(--accent-rgb), 0.2);\n}\n```\n\n### Variable Inheritance\n\n```css\n:root {\n  --base-size: 16px;\n  --heading-multiplier: 2;\n  --heading-size: calc(var(--base-size) * var(--heading-multiplier));\n}\n\nh1 {\n  font-size: var(--heading-size);\n}\n```\n\n## Best Practices\n\n1. **Use semantic names:**\n\n   ```css\n   /* Good */\n   --text-primary: #e0e0e0;\n\n   /* Avoid */\n   --gray-light: #e0e0e0;\n   ```\n\n2. **Group related variables:**\n\n   ```css\n   :root {\n     /* Colors */\n     --bg-primary: #1a1a1a;\n     --bg-secondary: #222222;\n\n     /* Spacing */\n     --spacing-sm: 8px;\n     --spacing-md: 16px;\n   }\n   ```\n\n3. **Provide fallbacks:**\n\n   ```css\n   color: var(--text, #e0e0e0);\n   ```\n\n4. **Document complex variables:**\n   ```css\n   :root {\n     /* Used for navbar and modal backdrops */\n     --bg-overlay: rgba(31, 31, 31, 0.9);\n   }\n   ```\n\n## Debugging\n\n### Inspect Variables\n\nUse browser DevTools:\n\n```javascript\n// Get computed value\ngetComputedStyle(document.documentElement).getPropertyValue(\"--accent-primary\");\n\n// Set variable dynamically\ndocument.documentElement.style.setProperty(\"--accent-primary\", \"#FF5722\");\n```\n\n### List All Variables\n\n```javascript\n// Get all custom properties\nconst allVars = Array.from(document.styleSheets)\n  .flatMap((sheet) => Array.from(sheet.cssRules))\n  .filter((rule) => rule.selectorText === \":root\")\n  .flatMap((rule) => Array.from(rule.style))\n  .filter((prop) => prop.startsWith(\"--\"));\n\nconsole.log(allVars);\n```\n\n## Next Steps\n\n- [Customization Guide](customization.html) - Apply these variables\n- [Liquid Templates](liquid-templates.html) - Dynamic styling\n- [Performance Guide](performance.html) - Optimize CSS delivery\n","## Theme Colors\n\nEdit `src/styles/root.css` to customize the color scheme:\n\n```css\n:root {\n  --bg: #0d0d0d; /* Page background */\n  --bg-secondary: #1a1a1a; /* Secondary background */\n  --card: #1f1f1f; /* Card background */\n  --border: #2a2a2a; /* Border color */\n  --text: #ffffff; /* Primary text */\n  --text-secondary: #b0b0b0; /* Secondary text */\n  --muted: #808080; /* Muted text */\n  --accent-primary: #1bd96f; /* Primary accent (green) */\n  --gradient-primary: linear-gradient(135deg, #1bd96f 0%, #15a853 100%);\n}\n```\n\nChanges apply instantly with `jekyll serve --livereload`.\n\n## Layout & Spacing\n\nCustomize responsive sizing in `src/styles/root.css`:\n\n```css\n:root {\n  --radius: 6px; /* Border radius */\n  --content-max: 1200px; /* Max content width */\n  --container-inline: clamp(16px, 5vw, 32px); /* Side padding */\n  --nav-height: 76px; /* Navbar height */\n}\n```\n\n### Responsive Breakpoints\n\nModify media queries in CSS files (e.g., `src/styles/layout.css`):\n\n```css\n@media (max-width: 960px) {\n  /* Tablet styles */\n}\n\n@media (max-width: 640px) {\n  /* Mobile styles */\n}\n```\n\n## Typography\n\nGoogle Fonts is configured to M PLUS Rounded 1c. To change:\n\nIn `_layouts/default.html`:\n\n```html\n<link\n  href=\"https://fonts.googleapis.com/css2?family=Your+Font&display=swap\"\n  rel=\"stylesheet\"\n/>\n```\n\nIn `src/styles/root.css`:\n\n```css\nbody {\n  font-family: \"Your Font\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto,\n    sans-serif;\n}\n```\n\n## Component Styling\n\n### Cards\n\nEdit `.card` in `src/styles/components.css`:\n\n```css\n.card {\n  padding: 24px;\n  border-radius: var(--radius);\n  background: var(--card);\n  border: 1px solid var(--border);\n  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n}\n```\n\n### Buttons\n\nCustomize `.btn` variants:\n\n```css\n.btn.primary {\n  background: var(--gradient-primary);\n  color: #000000;\n}\n\n.btn.ghost {\n  background: transparent;\n  border: 1px solid var(--border);\n}\n```\n\n## Navigation Bar\n\nThe pill-style navbar is in `src/styles/layout.css`:\n\n```css\n.nav-inner {\n  background: rgba(31, 31, 31, 0.9);\n  border-radius: 999px;\n  padding: 10px clamp(16px, 4vw, 28px);\n  backdrop-filter: blur(10px);\n}\n```\n\nAdjust `border-radius`, `padding`, and `backdrop-filter` to change appearance.\n\n## Hero Banner\n\nThe hero section background image and overlay in `src/styles/layout.css`:\n\n```css\n.hero {\n  background-image: url(\"/abc-site/assets/images/blocks.svg\");\n  background-size: auto 100%;\n  background-position: left center;\n}\n\n.hero::before {\n  background: linear-gradient(\n    135deg,\n    rgba(13, 13, 13, 0.85) 0%,\n    rgba(13, 13, 13, 0.7) 100%\n  );\n}\n```\n\nReplace the SVG path to use a different banner image.\n\n## Project Card Layout\n\nProject cards are defined in `src/styles/modpacks.css`:\n\n```css\n.modpack {\n  display: grid;\n  grid-template-columns: auto 1fr;\n  grid-template-rows: auto auto auto;\n  /* ... */\n}\n```\n\nModify grid structure to change the layout of thumbnail, title, pills, and buttons.\n\n## Building & Testing\n\nAfter making changes:\n\n```bash\nbundle exec jekyll build\n```\n\nCheck `_site/` to see compiled output. Rerun `jekyll serve` to test live changes.\n\n---\n\n**Tips:** Use CSS variables for consistent theming. Test on mobile to ensure responsive design works.\n","# Deployment Guide\n\nLearn how to deploy your ABC showcase to popular hosting platforms.\n\n## GitHub Pages\n\n### Automatic Deployment\n\n1. **Enable GitHub Pages** in repository settings\n2. **Set source** to GitHub Actions\n3. **Create workflow** file `.github/workflows/jekyll.yml`:\n\n```yaml\nname: Deploy Jekyll site to Pages\n\non:\n  push:\n    branches: [\"main\"]\n  workflow_dispatch:\n\npermissions:\n  contents: read\n  pages: write\n  id-token: write\n\nconcurrency:\n  group: \"pages\"\n  cancel-in-progress: false\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: \"3.1\"\n          bundler-cache: true\n      - name: Setup Pages\n        uses: actions/configure-pages@v4\n      - name: Build with Jekyll\n        run: bundle exec jekyll build --baseurl \"${{ steps.pages.outputs.base_path }}\"\n        env:\n          JEKYLL_ENV: production\n      - name: Upload artifact\n        uses: actions/upload-pages-artifact@v3\n\n  deploy:\n    environment:\n      name: github-pages\n      url: ${{ steps.deployment.outputs.page_url }}\n    runs-on: ubuntu-latest\n    needs: build\n    steps:\n      - name: Deploy to GitHub Pages\n        id: deployment\n        uses: actions/deploy-pages@v4\n```\n\n### Configuration\n\nUpdate `_config.yml` with your repository name:\n\n```yaml\nbaseurl: \"/your-repo-name\"\nurl: \"https://username.github.io\"\n```\n\n## Netlify\n\n### One-Click Deploy\n\n1. **Connect repository** to Netlify\n2. **Configure build settings**:\n   - Build command: `bundle exec jekyll build`\n   - Publish directory: `_site`\n3. **Set environment variables**:\n   - `JEKYLL_ENV`: `production`\n\n### netlify.toml\n\nCreate `netlify.toml` in root:\n\n```toml\n[build]\n  command = \"bundle exec jekyll build\"\n  publish = \"_site\"\n\n[build.environment]\n  JEKYLL_ENV = \"production\"\n  RUBY_VERSION = \"3.1\"\n\n[[headers]]\n  for = \"/*\"\n  [headers.values]\n    X-Frame-Options = \"DENY\"\n    X-XSS-Protection = \"1; mode=block\"\n    X-Content-Type-Options = \"nosniff\"\n\n[[redirects]]\n  from = \"/*\"\n  to = \"/404.html\"\n  status = 404\n```\n\n## Vercel\n\n### Deploy with Vercel CLI\n\n1. **Install Vercel CLI**: `npm i -g vercel`\n2. **Run**: `vercel`\n3. **Follow prompts** to link repository\n\n### vercel.json\n\nCreate `vercel.json`:\n\n```json\n{\n  \"buildCommand\": \"bundle exec jekyll build\",\n  \"outputDirectory\": \"_site\",\n  \"framework\": \"jekyll\",\n  \"installCommand\": \"bundle install\"\n}\n```\n\n## Environment Variables\n\n### Production Settings\n\nSet these for optimal production builds:\n\n- `JEKYLL_ENV=production` - Enables production mode\n- `BUNDLE_WITHOUT=development` - Skip dev dependencies\n\n### Custom Variables\n\nAdd to `_config.yml`:\n\n```yaml\n# Development\ndevelopment:\n  api_url: \"http://localhost:4000\"\n\n# Production\nproduction:\n  api_url: \"https://api.yoursite.com\"\n```\n\nAccess in templates:\n\n```liquid\n{% if jekyll.environment == \"production\" %}\n  {{ site.production.api_url }}\n{% else %}\n  {{ site.development.api_url }}\n{% endif %}\n```\n\n## Performance Optimization\n\n### Build Optimization\n\n1. **Exclude unnecessary files** in `_config.yml`\n2. **Enable incremental builds**: `jekyll build --incremental`\n3. **Use caching** in CI/CD pipelines\n\n### Asset Optimization\n\n```yaml\n# _config.yml\nsass:\n  style: compressed\n\nexclude:\n  - node_modules/\n  - src/\n  - Gemfile\n  - Gemfile.lock\n  - README.md\n```\n\n## Troubleshooting\n\n### Build Failures\n\n**Missing dependencies:**\n\n```bash\nbundle install\nbundle update\n```\n\n**Path issues:**\n\n- Check `baseurl` in `_config.yml`\n- Use `{{ '/path' | relative_url }}` in templates\n\n**Version conflicts:**\n\n```bash\nbundle exec jekyll build --verbose\n```\n\n### Cache Issues\n\nClear build cache:\n\n```bash\n# Local\nrm -rf _site .jekyll-cache\n\n# Netlify: Clear cache in Deploy settings\n# Vercel: Redeploy without cache\n# GitHub Pages: Re-run workflow\n```\n\n## Next Steps\n\n- [GitHub Actions Guide](github-actions.html) - Automate workflows\n- [Performance Optimization](performance.html) - Speed up your site\n- [SEO Guide](seo-guide.html) - Improve search rankings\n","## General\n\n**Q: What is ABC?**\nA: ABC is a static site showcase for curated Minecraft projects (mods, resource packs, datapacks, modpacks, plugins) from a Modrinth organization.\n\n**Q: Can I fork and customize it?**\nA: Yes! The site is open-source. Fork the [GitHub repo]({{ site.social.github }}), configure it for your organization, and deploy.\n\n**Q: Do I need technical knowledge to use it?**\nA: Basic familiarity with Git and command line helps, but the setup is straightforward. Check our [Getting Started](getting-started) guide.\n\n## Setup & Configuration\n\n**Q: How do I connect my Modrinth organization?**\nA: Set `modrinth.org_slug` in `_config.yml` to your organization slug, then run `npm run fetch` to sync projects.\n\n**Q: Can I customize colors?**\nA: Yes! Edit `src/styles/root.css` to change the theme colors, fonts, and spacing.\n\n**Q: How do I add a logo?**\nA: Replace `assets/images/logo.svg` with your logo, then update the path in `_config.yml` if needed.\n\n**Q: Where do social links appear?**\nA: In the navbar (top right) and footer. Configure them in `_config.yml` under `social`.\n\n## Projects & Data\n\n**Q: How often does the project list update?**\nA: Run `npm run fetch` manually, or set up a scheduled GitHub Action to auto-sync daily.\n\n**Q: Can I filter projects by type or version?**\nA: Yes! The projects page has built-in filters for type, loader, and Minecraft version.\n\n**Q: What data comes from Modrinth?**\nA: Title, description, icon, downloads, versions, loaders, categories, and links. All pulled from the Modrinth API.\n\n**Q: Can I add projects manually?**\nA: You can edit `data/mods.json` directly, but it's better to add them to Modrinth and sync via `npm run fetch`.\n\n## Deployment\n\n**Q: How do I deploy to GitHub Pages?**\nA: Configure `baseurl` in `_config.yml` to your repo name, then GitHub Actions auto-deploys on push (if enabled).\n\n**Q: Can I host it elsewhere?**\nA: Yes! Run `bundle exec jekyll build` and upload the `_site/` folder to any static hosting (Netlify, Vercel, etc.).\n\n**Q: What's the baseurl?**\nA: It's the URL path where your site lives. For `github.io/abc-site`, set `baseurl: /abc-site`.\n\n## Performance\n\n**Q: Why is the build slow?**\nA: Large `node_modules/` and `src/` folders are excluded by default. Check `_config.yml` to ensure unnecessary folders aren't processed.\n\n**Q: How do I optimize for mobile?**\nA: The site is responsive by default using CSS `clamp()`. Test on phone to verify layouts work.\n\n## Troubleshooting\n\n**Q: Site won't build**\nA: Check Ruby version (`ruby -v`). We use 2.6+. Run `bundle install` to install dependencies.\n\n**Q: Projects don't show**\nA: Verify `data/mods.json` exists and is valid JSON. Run `npm run fetch` to regenerate it.\n\n**Q: Navbar looks broken**\nA: Hard refresh (Cmd+Shift+R). Clear browser cache if using `jekyll serve`.\n\n**Q: Styles not updating**\nA: Changes to source files (`src/styles/`) need to be compiled. Either build with `bundle exec jekyll build` or ensure `jekyll serve` is watching the files.\n\n## Contributing\n\n**Q: How do I contribute code?**\nA: Fork the repo, make changes on a branch, and open a PR. See [Contributing](contributing) for details.\n\n**Q: Can I suggest features?**\nA: Yes! Open a GitHub issue or discussion. We'd love to hear your ideas.\n\n---\n\n**Still have questions?** Open an [issue]({{ site.social.github }}/issues) or [reach out on Discord]({{ site.social.discord }}).\n","## Rebrand\n\n- Edit `_config.yml` (`site` block) for name, title, description, logo.\n- Swap icons: update `meta.favicon`, `meta.apple_touch_icon`, `meta.og_image` and replace files in `assets/images/`.\n\n## Configure Modrinth\n\n- Set `modrinth.org_slug` (and `MODRINTH_API_TOKEN` if you want private projects).\n- Run `npm run fetch` to refresh `data/mods.json`.\n\n## Run locally\n\n```bash\nbundle exec jekyll serve --livereload\n# visit http://localhost:4000/abc-site/\n```\n","# GitHub Actions Guide\n\nAutomate your ABC showcase with GitHub Actions workflows.\n\n## Basic Build Workflow\n\n### Jekyll Build & Deploy\n\nCreate `.github/workflows/build.yml`:\n\n```yaml\nname: Build and Deploy\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: \"3.1\"\n          bundler-cache: true\n\n      - name: Build site\n        run: bundle exec jekyll build\n        env:\n          JEKYLL_ENV: production\n\n      - name: Test HTML\n        run: |\n          bundle exec htmlproofer ./_site \\\n            --disable-external \\\n            --allow-hash-href\n```\n\n## Advanced Workflows\n\n### Link Checker\n\nCheck for broken links:\n\n```yaml\nname: Link Check\n\non:\n  schedule:\n    - cron: \"0 0 * * 0\" # Weekly\n  workflow_dispatch:\n\njobs:\n  link-check:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: \"3.1\"\n          bundler-cache: true\n\n      - name: Build site\n        run: bundle exec jekyll build\n\n      - name: Check links\n        uses: lycheeverse/lychee-action@v1\n        with:\n          args: --verbose --no-progress './_site/**/*.html'\n```\n\n### Auto-Update Dependencies\n\nKeep gems updated:\n\n```yaml\nname: Update Dependencies\n\non:\n  schedule:\n    - cron: \"0 0 * * 1\" # Weekly on Monday\n  workflow_dispatch:\n\njobs:\n  update:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: \"3.1\"\n\n      - name: Update gems\n        run: bundle update\n\n      - name: Create Pull Request\n        uses: peter-evans/create-pull-request@v5\n        with:\n          commit-message: \"chore: update dependencies\"\n          title: \"Update Ruby dependencies\"\n          body: \"Automated dependency updates\"\n          branch: update-dependencies\n```\n\n### Lighthouse CI\n\nPerformance testing:\n\n```yaml\nname: Lighthouse CI\n\non:\n  pull_request:\n    branches: [main]\n\njobs:\n  lighthouse:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: \"3.1\"\n          bundler-cache: true\n\n      - name: Build site\n        run: bundle exec jekyll build\n\n      - name: Run Lighthouse CI\n        uses: treosh/lighthouse-ci-action@v10\n        with:\n          urls: |\n            http://localhost:4000\n            http://localhost:4000/projects/\n            http://localhost:4000/docs/\n          uploadArtifacts: true\n```\n\n## Modrinth Data Sync\n\n### Auto-Fetch Latest Mods\n\nKeep mod data fresh:\n\n```yaml\nname: Sync Modrinth Data\n\non:\n  schedule:\n    - cron: \"0 */6 * * *\" # Every 6 hours\n  workflow_dispatch:\n\njobs:\n  sync:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Setup Node\n        uses: actions/setup-node@v4\n        with:\n          node-version: \"18\"\n\n      - name: Fetch Modrinth data\n        run: |\n          # Your script to fetch from Modrinth API\n          node scripts/fetch-modrinth.js\n\n      - name: Commit changes\n        uses: stefanzweifel/git-auto-commit-action@v5\n        with:\n          commit_message: \"chore: update Modrinth data\"\n          file_pattern: \"_data/mods.json\"\n```\n\n## Caching Strategies\n\n### Bundle Cache\n\nSpeed up builds with caching:\n\n{% raw %}\n\n```yaml\n- name: Setup Ruby\n  uses: ruby/setup-ruby@v1\n  with:\n    ruby-version: \"3.1\"\n    bundler-cache: true # Automatic bundler caching\n\n- name: Cache Jekyll build\n  uses: actions/cache@v3\n  with:\n    path: |\n      .jekyll-cache\n      _site\n    key: ${{ runner.os }}-jekyll-${{ hashFiles('**/*.md', '**/*.html') }}\n    restore-keys: |\n      ${{ runner.os }}-jekyll-\n```\n\n{% endraw %}\n\n## Notifications\n\n### Slack Integration\n\nGet notified on deployment:\n\n```yaml\n- name: Slack Notification\n  uses: 8398a7/action-slack@v3\n  with:\n    status: ${{ job.status }}\n    text: \"Deployment completed!\"\n    webhook_url: ${{ secrets.SLACK_WEBHOOK }}\n  if: always()\n```\n\n### Discord Webhook\n\n```yaml\n- name: Discord notification\n  uses: Ilshidur/action-discord@master\n  env:\n    DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}\n  with:\n    args: \"Site deployed successfully! 🚀\"\n```\n\n## Security Scanning\n\n### Dependency Scanning\n\n```yaml\nname: Security Scan\n\non:\n  push:\n    branches: [main]\n  schedule:\n    - cron: \"0 0 * * 0\"\n\njobs:\n  security:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Run bundle audit\n        run: |\n          gem install bundler-audit\n          bundle audit --update\n```\n\n## Secrets Management\n\n### Required Secrets\n\nAdd in Settings > Secrets and variables > Actions:\n\n- `GITHUB_TOKEN` - Automatically provided\n- `SLACK_WEBHOOK` - For Slack notifications\n- `DISCORD_WEBHOOK` - For Discord notifications\n- Custom API keys for integrations\n\n### Using Secrets\n\n```yaml\n- name: Deploy to custom server\n  env:\n    API_KEY: ${{ secrets.API_KEY }}\n    SERVER_URL: ${{ secrets.SERVER_URL }}\n  run: |\n    curl -X POST \"$SERVER_URL\" \\\n      -H \"Authorization: Bearer $API_KEY\"\n```\n\n## Workflow Triggers\n\n### Available Triggers\n\n```yaml\non:\n  push:\n    branches: [main]\n    paths:\n      - \"**.md\"\n      - \"**.html\"\n  pull_request:\n  schedule:\n    - cron: \"0 0 * * *\"\n  workflow_dispatch:\n  release:\n    types: [published]\n```\n\n## Best Practices\n\n1. **Use caching** to speed up builds\n2. **Run tests on PRs** before merging\n3. **Schedule maintenance tasks** (link checks, updates)\n4. **Secure secrets** properly\n5. **Monitor workflow costs** and runtime\n6. **Use matrix builds** for testing multiple versions\n\n## Troubleshooting\n\n### Failed Builds\n\nCheck logs:\n\n1. Click on failed workflow\n2. Expand failed step\n3. Review error messages\n\nCommon fixes:\n\n- Update action versions\n- Clear cache\n- Check secrets configuration\n\n### Timeout Issues\n\n```yaml\njobs:\n  build:\n    runs-on: ubuntu-latest\n    timeout-minutes: 30 # Increase if needed\n```\n\n## Next Steps\n\n- [Deployment Guide](deployment.html) - Deploy to hosting platforms\n- [Performance Guide](performance.html) - Optimize build times\n- [API Reference](api-reference.html) - Data structure documentation\n","## Step-by-Step Guide\n\n1. **Open the Project Page**  \n   Visit the Modrinth, CurseForge, GitHub, or project website for the content you want to download.\n\n2. **Find the Versions or Files Section**  \n   Look for a tab or section labelled **Versions**, **Files**, **Releases**, or **Downloads**.\n\n3. **Select Your Minecraft Version**\n\n   - Locate a list or dropdown called **Version**, **Game Version**, or **Supported Versions**.\n   - Pick the version that matches your Minecraft installation (e.g., _1.20.1_, _1.19.2_).\n\n4. **Choose the Correct File Type**  \n   The file type depends on the kind of content:\n\n   - **Mods:** `.jar`\n   - **Plugins:** `.jar`\n   - **Addons (Bedrock):** `.mcaddon` / `.mcpack`\n   - **Texture Packs:** `.zip`\n   - **Data Packs:** `.zip` or extracted folder\n   - **Capes / Skin Addons:** whichever format the creator provides\n\n5. **Download the File**  \n   Click the **Download**, **Get**, or **File** button next to the version you need.  \n   Save the file to your device.\n\n6. **Install According to Content Type**\n\n   - **Mods:** place the `.jar` inside `.minecraft/mods`.\n   - **Plugins:** move the `.jar` into your server's `plugins` folder.\n   - **Texture Packs:** place the `.zip` into `.minecraft/resourcepacks`.\n   - **Data Packs:** put inside `world/datapacks`.\n   - **Addons (Bedrock):** double-click `.mcaddon` or `.mcpack` to import automatically.\n\n7. **Restart Minecraft or Your Server**  \n   Reload or restart to apply the new content.\n","# Liquid Templates Guide\n\nMaster Jekyll's Liquid templating language for dynamic content generation.\n\n## Basics\n\n### Output Tags\n\nDisplay variables and expressions:\n\n```liquid\n{{ variable }}\n{{ site.title }}\n{{ page.description }}\n```\n\n### Logic Tags\n\nControl flow and iteration:\n\n```liquid\n{% if condition %}\n  ...\n{% elsif other_condition %}\n  ...\n{% else %}\n  ...\n{% endif %}\n\n{% for item in array %}\n  {{ item }}\n{% endfor %}\n```\n\n## Variables\n\n### Site Variables\n\n```liquid\n{{ site.title }}              # From _config.yml\n{{ site.description }}\n{{ site.baseurl }}\n{{ site.url }}\n{{ site.time }}               # Build timestamp\n{{ site.pages }}              # All pages\n{{ site.posts }}              # All posts\n{{ site.data }}               # Data files\n```\n\n### Page Variables\n\n{% raw %}\n\n```liquid\n{{ page.title }}              # Current page title\n{{ page.url }}                # Page URL\n{{ page.date }}               # Post date\n{{ page.content }}            # Page content\n{{ page.excerpt }}            # Auto excerpt\n{{ page.custom_field }}       # Custom frontmatter\n```\n\n{% endraw %}\n\n### Custom Data\n\nAccess `_data/` files:\n\n```liquid\n{% for modpack in site.data.mods.modpacks %}\n  {{ modpack.name }}\n  {{ modpack.description }}\n{% endfor %}\n```\n\n## Filters\n\n### String Filters\n\n```liquid\n{{ \"hello world\" | capitalize }}        # \"Hello world\"\n{{ \"hello world\" | upcase }}            # \"HELLO WORLD\"\n{{ \"HELLO WORLD\" | downcase }}          # \"hello world\"\n{{ \"hello world\" | truncate: 8 }}       # \"hello...\"\n{{ \"hello world\" | replace: \"world\", \"there\" }}  # \"hello there\"\n{{ \"a,b,c\" | split: \",\" }}              # [\"a\", \"b\", \"c\"]\n{{ \" hello \" | strip }}                 # \"hello\"\n{{ \"hello\" | append: \" world\" }}        # \"hello world\"\n{{ \"world\" | prepend: \"hello \" }}       # \"hello world\"\n{{ \"hello-world\" | slugify }}           # \"hello-world\"\n```\n\n### Number Filters\n\n```liquid\n{{ 4 | plus: 2 }}              # 6\n{{ 4 | minus: 2 }}             # 2\n{{ 4 | times: 2 }}             # 8\n{{ 4 | divided_by: 2 }}        # 2\n{{ 4.5 | round }}              # 5\n{{ 4.5 | ceil }}               # 5\n{{ 4.5 | floor }}              # 4\n{{ 1234 | divided_by: 100.0 }} # 12.34\n```\n\n### Array Filters\n\n{% raw %}\n\n```liquid\n{{ array | join: \", \" }}       # Join with separator\n{{ array | first }}            # First element\n{{ array | last }}             # Last element\n{{ array | size }}             # Array length\n{{ array | reverse }}          # Reverse order\n{{ array | sort }}             # Sort ascending\n{{ array | uniq }}             # Remove duplicates\n{{ array | where: \"key\", \"value\" }}  # Filter by property\n{{ array | map: \"name\" }}      # Extract property\n```\n\n{% endraw %}\n\n### Date Filters\n\n```liquid\n{{ page.date | date: \"%Y-%m-%d\" }}           # 2025-12-10\n{{ page.date | date: \"%B %d, %Y\" }}          # December 10, 2025\n{{ page.date | date_to_string }}             # 10 Dec 2025\n{{ page.date | date_to_long_string }}        # 10 December 2025\n{{ page.date | date_to_rfc822 }}             # RFC-822 format\n{{ \"2025-12-10\" | date: \"%Y\" }}              # 2025\n```\n\n### URL Filters\n\n```liquid\n{{ \"/assets/style.css\" | relative_url }}     # /abc-site/assets/style.css\n{{ \"/page\" | absolute_url }}                 # https://site.com/abc-site/page\n{{ \"path/to/file.md\" | replace: \".md\", \".html\" }}\n```\n\n### Jekyll-Specific Filters\n\n```liquid\n{{ content | markdownify }}             # Convert Markdown to HTML\n{{ content | strip_html }}              # Remove HTML tags\n{{ content | number_of_words }}         # Word count\n{{ content | jsonify }}                 # Convert to JSON\n{{ content | xml_escape }}              # Escape XML characters\n{{ content | cgi_escape }}              # URL encode\n{{ content | uri_escape }}              # URI encode\n```\n\n## Control Flow\n\n### If Statements\n\n```liquid\n{% if page.category == \"Developer\" %}\n  <span class=\"badge\">Developer</span>\n{% endif %}\n\n{% if page.tags contains \"featured\" %}\n  <span class=\"featured\">★</span>\n{% endif %}\n\n{% unless page.published == false %}\n  {{ page.content }}\n{% endunless %}\n```\n\n### Case Statements\n\n```liquid\n{% case page.category %}\n  {% when \"Setup\" %}\n    <i class=\"fa-gear\"></i>\n  {% when \"Styling\" %}\n    <i class=\"fa-palette\"></i>\n  {% else %}\n    <i class=\"fa-file\"></i>\n{% endcase %}\n```\n\n### Loops\n\n```liquid\n{% for doc in site.docs %}\n  <li>{{ doc.title }}</li>\n{% endfor %}\n\n{% for doc in site.docs limit:5 %}\n  <!-- First 5 only -->\n{% endfor %}\n\n{% for doc in site.docs offset:5 %}\n  <!-- Skip first 5 -->\n{% endfor %}\n\n{% for doc in site.docs reversed %}\n  <!-- Reverse order -->\n{% endfor %}\n```\n\n### Loop Variables\n\n```liquid\n{% for item in array %}\n  {{ forloop.index }}        # 1, 2, 3, ...\n  {{ forloop.index0 }}       # 0, 1, 2, ...\n  {{ forloop.first }}        # true on first iteration\n  {{ forloop.last }}         # true on last iteration\n  {{ forloop.length }}       # Total iterations\n  {{ forloop.rindex }}       # Reverse index (from end)\n{% endfor %}\n```\n\n### Break & Continue\n\n```liquid\n{% for item in array %}\n  {% if item.hide %}\n    {% continue %}\n  {% endif %}\n\n  {% if forloop.index > 10 %}\n    {% break %}\n  {% endif %}\n\n  {{ item.name }}\n{% endfor %}\n```\n\n## Advanced Techniques\n\n### Assign Variables\n\n```liquid\n{% assign my_var = \"value\" %}\n{% assign count = site.docs | size %}\n{% assign featured = site.docs | where: \"featured\", true %}\n```\n\n### Capture Blocks\n\n```liquid\n{% capture my_variable %}\n  Complex content with {{ page.title }}\n  and calculations: {{ 5 | times: 10 }}\n{% endcapture %}\n\n{{ my_variable }}\n```\n\n### Includes\n\nCreate reusable components in `_includes/`:\n\n{% raw %}\n\n```liquid\n{% include header.html %}\n{% include card.html title=\"Test\" description=\"Description\" %}\n```\n\n{% endraw %}\n\nWith parameters:\n\n{% raw %}\n\n```liquid\n<!-- _includes/card.html -->\n<div class=\"card\">\n  <h3>{{ include.title }}</h3>\n  <p>{{ include.description }}</p>\n</div>\n```\n\n{% endraw %}\n\n### Layouts\n\nInherit from layouts:\n\n```liquid\n<!-- _layouts/docs.html -->\n<!DOCTYPE html>\n<html>\n  <body>\n    {{ content }}\n  </body>\n</html>\n```\n\nIn page frontmatter:\n\n```yaml\n---\nlayout: docs\ntitle: My Page\n---\n```\n\n## Practical Examples\n\n### Navigation Menu\n\n```liquid\n<nav>\n  {% for item in site.data.navigation %}\n    <a href=\"{{ item.url | relative_url }}\"\n       {% if page.url == item.url %}class=\"active\"{% endif %}>\n      {{ item.title }}\n    </a>\n  {% endfor %}\n</nav>\n```\n\n### Breadcrumbs\n\n```liquid\n<nav class=\"breadcrumbs\">\n  <a href=\"{{ '/' | relative_url }}\">Home</a>\n  {% if page.category %}\n    <span>/</span>\n    <a href=\"{{ '/docs/category/' | append: page.category | slugify | append: '/' | relative_url }}\">\n      {{ page.category }}\n    </a>\n  {% endif %}\n  <span>/</span>\n  <span>{{ page.title }}</span>\n</nav>\n```\n\n### Pagination\n\n```liquid\n{% if paginator.total_pages > 1 %}\n  <div class=\"pagination\">\n    {% if paginator.previous_page %}\n      <a href=\"{{ paginator.previous_page_path | relative_url }}\">Previous</a>\n    {% endif %}\n\n    <span>Page {{ paginator.page }} of {{ paginator.total_pages }}</span>\n\n    {% if paginator.next_page %}\n      <a href=\"{{ paginator.next_page_path | relative_url }}\">Next</a>\n    {% endif %}\n  </div>\n{% endif %}\n```\n\n### Related Posts\n\n```liquid\n{% assign related = site.docs | where: \"category\", page.category |\n                    where_exp: \"doc\", \"doc.url != page.url\" |\n                    limit: 3 %}\n\n{% if related.size > 0 %}\n  <h3>Related Documentation</h3>\n  <ul>\n    {% for doc in related %}\n      <li><a href=\"{{ doc.url | relative_url }}\">{{ doc.title }}</a></li>\n    {% endfor %}\n  </ul>\n{% endif %}\n```\n\n### Conditional CSS Classes\n\n```liquid\n<article class=\"\n  {% if page.featured %}featured{% endif %}\n  {% if page.category %}category-{{ page.category | slugify }}{% endif %}\n  {% if page.tags contains 'important' %}important{% endif %}\n\">\n  {{ content }}\n</article>\n```\n\n## Performance Tips\n\n1. **Assign once, use many times:**\n\n   ```liquid\n   {% assign docs = site.docs | where: \"category\", \"Setup\" %}\n   ```\n\n2. **Avoid nested loops when possible:**\n\n   ```liquid\n   <!-- Slow -->\n   {% for doc in site.docs %}\n     {% for tag in doc.tags %}\n       ...\n     {% endfor %}\n   {% endfor %}\n\n   <!-- Faster -->\n   {% assign all_tags = site.docs | map: \"tags\" | join: \",\" | default: \"\" | split: \",\" | uniq %}\n   ```\n\n3. **Cache expensive operations:**\n   ```liquid\n   {% capture cached_content %}\n     <!-- Complex logic here -->\n   {% endcapture %}\n   ```\n\n## Debugging\n\n### Inspect Variables\n\n```liquid\n{{ variable | inspect }}\n{{ site.data | jsonify }}\n```\n\n### Check Types\n\n```liquid\n{% if variable %}\n  Variable exists and is truthy\n{% endif %}\n\n{% if variable == nil %}\n  Variable is nil\n{% endif %}\n\n{% if variable == blank %}\n  Variable is nil, false, or empty\n{% endif %}\n```\n\n## Next Steps\n\n- [API Reference](api-reference.html) - Data structure documentation\n- [CSS Variables](css-variables.html) - Theme customization\n- [Customization Guide](customization.html) - Practical examples\n","# Performance Optimization\n\nOptimize your ABC showcase for blazing-fast load times and smooth interactions.\n\n## Build Performance\n\n### Jekyll Build Optimization\n\n**Exclude unnecessary files:**\n\n```yaml\n# _config.yml\nexclude:\n  - node_modules/\n  - src/\n  - vendor/\n  - .git/\n  - .github/\n  - README.md\n  - Gemfile\n  - Gemfile.lock\n  - package.json\n  - package-lock.json\n```\n\n**Use incremental builds:**\n\n```bash\nbundle exec jekyll build --incremental\n```\n\n**Profile build time:**\n\n```bash\nbundle exec jekyll build --profile\n```\n\n### Optimize Data Files\n\n**Reduce `_data/mods.json` size:**\n\n```json\n{\n  \"modpacks\": [\n    {\n      \"slug\": \"abc\",\n      \"name\": \"ABC Pack\",\n      \"desc\": \"Brief description\",\n      \"icon\": \"/path/to/icon.png\",\n      \"dl\": 50000,\n      \"cat\": [\"tech\"]\n    }\n  ]\n}\n```\n\nUse abbreviated keys and remove unnecessary fields.\n\n**Compress JSON:**\n\n```bash\n# Install jq\nbrew install jq\n\n# Minify JSON\njq -c . _data/mods.json > _data/mods.min.json\n```\n\n## Asset Optimization\n\n### Images\n\n**Use WebP format:**\n\n```html\n<picture>\n  <source srcset=\"image.webp\" type=\"image/webp\" />\n  <img src=\"image.png\" alt=\"Description\" />\n</picture>\n```\n\n**Convert images:**\n\n```bash\n# Install ImageMagick\nbrew install imagemagick\n\n# Convert to WebP\nmagick convert input.png -quality 80 output.webp\n```\n\n**Optimize existing images:**\n\n```bash\n# PNG optimization\npngquant --quality 65-80 image.png\n\n# JPG optimization\njpegoptim --max=85 image.jpg\n```\n\n**Lazy loading:**\n\n```html\n<img src=\"image.jpg\" loading=\"lazy\" alt=\"Description\" />\n```\n\n### CSS Optimization\n\n**Minify CSS:**\n\n```yaml\n# _config.yml\nsass:\n  style: compressed\n```\n\n**Critical CSS:**\n\nExtract above-the-fold styles:\n\n```html\n<head>\n  <style>\n    /* Critical CSS inline */\n    body {\n      margin: 0;\n      font-family: sans-serif;\n    }\n    .hero {\n      min-height: 100vh;\n    }\n  </style>\n\n  <!-- Defer non-critical CSS -->\n  <link\n    rel=\"preload\"\n    href=\"/assets/css/main.css\"\n    as=\"style\"\n    onload=\"this.onload=null;this.rel='stylesheet'\"\n  />\n  <noscript><link rel=\"stylesheet\" href=\"/assets/css/main.css\" /></noscript>\n</head>\n```\n\n**Remove unused CSS:**\n\n```bash\nnpm install -g purgecss\n\npurgecss --css assets/css/*.css \\\n         --content _site/**/*.html \\\n         --output assets/css/\n```\n\n### JavaScript Optimization\n\n**Defer non-critical scripts:**\n\n```html\n<script src=\"/assets/js/main.js\" defer></script>\n```\n\n**Async for independent scripts:**\n\n```html\n<script src=\"/assets/js/analytics.js\" async></script>\n```\n\n**Minify JavaScript:**\n\n```bash\nnpm install -g terser\n\nterser input.js -o output.min.js -c -m\n```\n\n**Code splitting:**\n\n```html\n<!-- Load only what's needed -->\n{% if page.layout == 'docs' %}\n<script src=\"/assets/js/docs.js\" defer></script>\n{% endif %}\n```\n\n## Caching Strategies\n\n### HTTP Caching\n\n**Add cache headers:**\n\n```html\n<!-- Netlify: _headers file -->\n/assets/* Cache-Control: public, max-age=31536000, immutable /css/*\nCache-Control: public, max-age=31536000, immutable /js/* Cache-Control: public,\nmax-age=31536000, immutable /*.html Cache-Control: public, max-age=0,\nmust-revalidate\n```\n\n**Versioning assets:**\n\n```liquid\n<link rel=\"stylesheet\" href=\"{{ '/assets/css/main.css' | relative_url }}?v={{ site.time | date: '%s' }}\">\n```\n\n### Service Worker\n\n**Basic service worker:**\n\n```javascript\n// sw.js\nconst CACHE_NAME = \"abc-site-v1\";\nconst urlsToCache = [\n  \"/\",\n  \"/assets/css/main.css\",\n  \"/assets/js/main.js\",\n  \"/assets/images/logo.svg\",\n];\n\nself.addEventListener(\"install\", (event) => {\n  event.waitUntil(\n    caches.open(CACHE_NAME).then((cache) => cache.addAll(urlsToCache))\n  );\n});\n\nself.addEventListener(\"fetch\", (event) => {\n  event.respondWith(\n    caches\n      .match(event.request)\n      .then((response) => response || fetch(event.request))\n  );\n});\n```\n\n**Register service worker:**\n\n```html\n<script>\n  if (\"serviceWorker\" in navigator) {\n    navigator.serviceWorker.register(\"/sw.js\");\n  }\n</script>\n```\n\n## Loading Optimization\n\n### Resource Hints\n\n**Preconnect to external domains:**\n\n```html\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n<link rel=\"preconnect\" href=\"https://cdn.modrinth.com\" />\n```\n\n**Prefetch next page:**\n\n```html\n<link rel=\"prefetch\" href=\"{{ next_page.url | relative_url }}\" />\n```\n\n**Preload critical resources:**\n\n```html\n<link\n  rel=\"preload\"\n  href=\"/assets/fonts/main.woff2\"\n  as=\"font\"\n  type=\"font/woff2\"\n  crossorigin\n/>\n<link rel=\"preload\" href=\"/assets/images/hero.webp\" as=\"image\" />\n```\n\n### Font Optimization\n\n**Use system fonts:**\n\n```css\nbody {\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen,\n    Ubuntu, Cantarell, sans-serif;\n}\n```\n\n**Or optimize web fonts:**\n\n```css\n/* Only load needed weights and styles */\n@font-face {\n  font-family: \"CustomFont\";\n  src: url(\"/fonts/custom-regular.woff2\") format(\"woff2\");\n  font-weight: 400;\n  font-display: swap;\n}\n```\n\n**Subset fonts:**\n\n```bash\n# Install glyphhanger\nnpm install -g glyphhanger\n\n# Generate subset\nglyphhanger --subset=font.ttf \\\n            --formats=woff2 \\\n            --whitelist=\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\"\n```\n\n## Runtime Performance\n\n### Efficient JavaScript\n\n**Debounce expensive operations:**\n\n```javascript\nfunction debounce(func, wait) {\n  let timeout;\n  return function (...args) {\n    clearTimeout(timeout);\n    timeout = setTimeout(() => func.apply(this, args), wait);\n  };\n}\n\n// Usage\nconst search = debounce((query) => {\n  // Expensive search operation\n}, 300);\n\ninput.addEventListener(\"input\", (e) => search(e.target.value));\n```\n\n**Use requestAnimationFrame:**\n\n```javascript\nfunction updateAnimation() {\n  // Animation logic\n  requestAnimationFrame(updateAnimation);\n}\n\nrequestAnimationFrame(updateAnimation);\n```\n\n**Lazy load images:**\n\n```javascript\nconst observer = new IntersectionObserver((entries) => {\n  entries.forEach((entry) => {\n    if (entry.isIntersecting) {\n      const img = entry.target;\n      img.src = img.dataset.src;\n      observer.unobserve(img);\n    }\n  });\n});\n\ndocument.querySelectorAll(\"img[data-src]\").forEach((img) => {\n  observer.observe(img);\n});\n```\n\n### CSS Performance\n\n**Avoid expensive selectors:**\n\n```css\n/* Slow */\ndiv > div > div > p {\n}\n\n/* Fast */\n.paragraph {\n}\n```\n\n**Use transforms over position:**\n\n```css\n/* Slow */\n.element {\n  left: 100px;\n  top: 100px;\n}\n\n/* Fast */\n.element {\n  transform: translate(100px, 100px);\n}\n```\n\n**Enable GPU acceleration:**\n\n```css\n.animated {\n  transform: translateZ(0);\n  will-change: transform;\n}\n```\n\n## Monitoring\n\n### Lighthouse\n\n```bash\nnpm install -g lighthouse\n\nlighthouse https://yoursite.com \\\n  --output html \\\n  --output-path ./report.html\n```\n\n### Web Vitals\n\n**Measure Core Web Vitals:**\n\n```html\n<script type=\"module\">\n  import {\n    getCLS,\n    getFID,\n    getFCP,\n    getLCP,\n    getTTFB,\n  } from \"https://unpkg.com/web-vitals@3/dist/web-vitals.js\";\n\n  function sendToAnalytics(metric) {\n    console.log(metric);\n    // Send to analytics service\n  }\n\n  getCLS(sendToAnalytics);\n  getFID(sendToAnalytics);\n  getFCP(sendToAnalytics);\n  getLCP(sendToAnalytics);\n  getTTFB(sendToAnalytics);\n</script>\n```\n\n### Performance API\n\n```javascript\n// Measure page load time\nwindow.addEventListener(\"load\", () => {\n  const perfData = performance.getEntriesByType(\"navigation\")[0];\n  console.log(\"Page load time:\", perfData.loadEventEnd - perfData.fetchStart);\n});\n\n// Custom timing\nperformance.mark(\"search-start\");\n// ... search operation\nperformance.mark(\"search-end\");\nperformance.measure(\"search\", \"search-start\", \"search-end\");\n```\n\n## Checklist\n\n- [ ] Enable SASS compression\n- [ ] Exclude unnecessary files from build\n- [ ] Optimize and compress images\n- [ ] Minify CSS and JavaScript\n- [ ] Add lazy loading for images\n- [ ] Implement resource hints (preconnect, prefetch)\n- [ ] Configure HTTP caching headers\n- [ ] Use system fonts or subset web fonts\n- [ ] Defer non-critical JavaScript\n- [ ] Enable gzip/brotli compression\n- [ ] Remove unused CSS\n- [ ] Optimize data file sizes\n- [ ] Test with Lighthouse\n- [ ] Monitor Core Web Vitals\n- [ ] Set up service worker for offline support\n\n## Benchmarking\n\n### Before Optimization\n\n```\nLighthouse Score: 65\nFirst Contentful Paint: 2.5s\nLargest Contentful Paint: 4.2s\nTotal Bundle Size: 850KB\n```\n\n### After Optimization\n\n```\nLighthouse Score: 95\nFirst Contentful Paint: 0.8s\nLargest Contentful Paint: 1.2s\nTotal Bundle Size: 220KB\n```\n\n## Next Steps\n\n- [Deployment Guide](deployment.html) - Deploy optimized site\n- [Accessibility Guide](accessibility.html) - Performance + accessibility\n- [SEO Guide](seo-guide.html) - Performance + SEO\n","## Directory Layout\n\n```\nabc-site/\n├── _docs/              # Documentation pages\n├── _includes/          # Reusable HTML components\n├── _layouts/           # Page templates\n├── assets/\n│   ├── css/           # Compiled stylesheets\n│   ├── images/        # Logo, icons, banners\n│   └── js/            # JavaScript files\n├── data/              # JSON data files (projects)\n├── docs/              # Rendered docs output\n├── src/\n│   ├── scripts/       # Source JS files\n│   └── styles/        # Source CSS (compiles to assets/css/)\n├── _config.yml        # Site configuration\n├── Gemfile            # Ruby dependencies\n├── package.json       # Node dependencies\n└── index.md           # Homepage\n```\n\n## Key Files\n\n| File                    | Purpose                                     |\n| ----------------------- | ------------------------------------------- |\n| `_config.yml`           | Site settings, branding, Modrinth config    |\n| `_layouts/default.html` | Main page template                          |\n| `_includes/nav.html`    | Navigation bar component                    |\n| `_includes/footer.html` | Footer component                            |\n| `data/mods.json`        | Project data (generated by `npm run fetch`) |\n| `assets/css/`           | Compiled stylesheets                        |\n| `src/styles/`           | Source stylesheets                          |\n\n## Front Matter\n\nEach Markdown page has YAML front matter:\n\n```yaml\n---\nlayout: default # Template to use\ntitle: Page Title # Page heading\ndescription: ... # Meta description\ncategory: Category # (for docs only)\ntags: [tag1, tag2] # (for docs only)\npermalink: /custom-url/ # Custom URL\n---\n```\n\n## Collections\n\n### `_docs/` - Documentation pages\n\nLocated in `_docs/` directory, rendered to `/docs/`.\n\nEach page needs:\n\n```yaml\nlayout: doc\nnav_order: 1\ncategory: Category Name\ntags: [tag1, tag2]\n```\n\n### `_includes/` - Components\n\nReusable HTML snippets included in templates:\n\n- `nav.html` - Navigation bar\n- `footer.html` - Footer\n- `theme-controls.html` - Theme toggle\n- `schema-markup.html` - SEO schema\n\n---\n\nSee [Contributing](contributing) to modify the structure.\n","# SEO Guide\n\nOptimize your ABC showcase for better search rankings and social media sharing.\n\n## Meta Tags\n\n### Basic SEO Meta Tags\n\n```html\n<head>\n  <meta charset=\"UTF-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n  <title>{{ page.title }} | {{ site.title }}</title>\n  <meta\n    name=\"description\"\n    content=\"{{ page.description | default: site.description }}\"\n  />\n  <meta name=\"keywords\" content=\"{{ page.tags | join: ', ' }}\" />\n  <meta name=\"author\" content=\"{{ site.author }}\" />\n  <link rel=\"canonical\" href=\"{{ page.url | absolute_url }}\" />\n</head>\n```\n\n### Jekyll SEO Tag Plugin\n\nInstall and configure:\n\n```ruby\n# Gemfile\ngem 'jekyll-seo-tag'\n```\n\n```yaml\n# _config.yml\nplugins:\n  - jekyll-seo-tag\n\ntitle: ABC Showcase\ndescription: Showcase your Minecraft modpacks beautifully\nurl: https://yoursite.com\nauthor:\n  name: Your Name\n  twitter: yourusername\n\nsocial:\n  name: ABC Showcase\n  links:\n    - https://twitter.com/yourusername\n    - https://github.com/yourusername\n```\n\nInclude in layout:\n\n{% raw %}\n\n```html\n<head>\n  {% seo %}\n</head>\n```\n\n{% endraw %}\n\n## Open Graph Tags\n\n### For Social Media Sharing\n\n```html\n<meta property=\"og:title\" content=\"{{ page.title }}\" />\n<meta property=\"og:description\" content=\"{{ page.description }}\" />\n<meta\n  property=\"og:image\"\n  content=\"{{ page.image | default: site.image | absolute_url }}\"\n/>\n<meta property=\"og:url\" content=\"{{ page.url | absolute_url }}\" />\n<meta property=\"og:type\" content=\"website\" />\n<meta property=\"og:site_name\" content=\"{{ site.title }}\" />\n```\n\n### Twitter Cards\n\n```html\n<meta name=\"twitter:card\" content=\"summary_large_image\" />\n<meta name=\"twitter:site\" content=\"@yourusername\" />\n<meta name=\"twitter:creator\" content=\"@yourusername\" />\n<meta name=\"twitter:title\" content=\"{{ page.title }}\" />\n<meta name=\"twitter:description\" content=\"{{ page.description }}\" />\n<meta name=\"twitter:image\" content=\"{{ page.image | absolute_url }}\" />\n```\n\n### Page-Specific OG Images\n\n```yaml\n# In page frontmatter\n---\ntitle: My Modpack\ndescription: An amazing tech-focused modpack\nimage: /assets/images/modpack-preview.png\n---\n```\n\n## Structured Data\n\n### JSON-LD for Projects\n\n```html\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"SoftwareApplication\",\n    \"name\": \"{{ modpack.name }}\",\n    \"description\": \"{{ modpack.description }}\",\n    \"url\": \"{{ modpack.source_url }}\",\n    \"downloadUrl\": \"{{ modpack.source_url }}\",\n    \"image\": \"{{ modpack.icon_url }}\",\n    \"applicationCategory\": \"Game\",\n    \"operatingSystem\": \"Windows, macOS, Linux\",\n    \"aggregateRating\": {\n      \"@type\": \"AggregateRating\",\n      \"ratingValue\": \"4.5\",\n      \"ratingCount\": \"{{ modpack.followers }}\"\n    },\n    \"offers\": {\n      \"@type\": \"Offer\",\n      \"price\": \"0\",\n      \"priceCurrency\": \"USD\"\n    }\n  }\n</script>\n```\n\n### Organization Schema\n\n```html\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"Organization\",\n    \"name\": \"{{ site.title }}\",\n    \"url\": \"{{ site.url }}\",\n    \"logo\": \"{{ '/assets/images/logo.png' | absolute_url }}\",\n    \"sameAs\": [\n      \"https://twitter.com/yourusername\",\n      \"https://github.com/yourusername\"\n    ]\n  }\n</script>\n```\n\n### Breadcrumb Schema\n\n```html\n<script type=\"application/ld+json\">\n  {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"BreadcrumbList\",\n    \"itemListElement\": [\n      {\n        \"@type\": \"ListItem\",\n        \"position\": 1,\n        \"name\": \"Home\",\n        \"item\": \"{{ '/' | absolute_url }}\"\n      },\n      {\n        \"@type\": \"ListItem\",\n        \"position\": 2,\n        \"name\": \"{{ page.category }}\",\n        \"item\": \"{{ '/docs/category/' | append: page.category | slugify | append: '/' | absolute_url }}\"\n      },\n      {\n        \"@type\": \"ListItem\",\n        \"position\": 3,\n        \"name\": \"{{ page.title }}\"\n      }\n    ]\n  }\n</script>\n```\n\n## Sitemap\n\n### Generate with Jekyll\n\n```ruby\n# Gemfile\ngem 'jekyll-sitemap'\n```\n\n```yaml\n# _config.yml\nplugins:\n  - jekyll-sitemap\n\nurl: https://yoursite.com\n```\n\n### Custom Sitemap\n\nCreate `sitemap.xml`:\n\n```xml\n---\nlayout: null\n---\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n  <url>\n    <loc>{{ '/' | absolute_url }}</loc>\n    <lastmod>{{ site.time | date_to_xmlschema }}</lastmod>\n    <changefreq>daily</changefreq>\n    <priority>1.0</priority>\n  </url>\n  {% for page in site.pages %}\n    {% unless page.url contains 'feed' or page.url contains 'sitemap' %}\n    <url>\n      <loc>{{ page.url | absolute_url }}</loc>\n      <lastmod>{{ site.time | date_to_xmlschema }}</lastmod>\n      <changefreq>weekly</changefreq>\n      <priority>0.8</priority>\n    </url>\n    {% endunless %}\n  {% endfor %}\n  {% for doc in site.docs %}\n    <url>\n      <loc>{{ doc.url | absolute_url }}</loc>\n      <lastmod>{{ doc.date | default: site.time | date_to_xmlschema }}</lastmod>\n      <changefreq>monthly</changefreq>\n      <priority>0.6</priority>\n    </url>\n  {% endfor %}\n</urlset>\n```\n\n## Robots.txt\n\n```\n# /robots.txt\nUser-agent: *\nAllow: /\nDisallow: /admin/\nDisallow: /_site/\nSitemap: https://yoursite.com/sitemap.xml\n```\n\n## URL Structure\n\n### SEO-Friendly URLs\n\n```yaml\n# _config.yml\npermalink: /:categories/:title/\n\ncollections:\n  docs:\n    output: true\n    permalink: /docs/:name/\n```\n\n**Good URLs:**\n\n- `/docs/getting-started/`\n- `/projects/`\n- `/docs/category/setup/`\n\n**Bad URLs:**\n\n- `/page.html?id=123`\n- `/p/456`\n- `/docs/doc1/`\n\n## Content Optimization\n\n### Title Tags\n\n```liquid\n<!-- Page titles -->\n<title>{% if page.title %}{{ page.title }} | {% endif %}{{ site.title }}</title>\n\n<!-- Keep under 60 characters -->\n<!-- Include primary keyword -->\n<!-- Make descriptive and unique -->\n```\n\n### Meta Descriptions\n\n```yaml\n---\ndescription: Learn how to set up your ABC showcase in under 5 minutes with this comprehensive guide.\n---\n```\n\n**Best practices:**\n\n- 150-160 characters\n- Include target keyword\n- Make compelling and actionable\n- Unique for each page\n\n### Heading Structure\n\n```html\n<h1>Main Page Title</h1>\n<!-- Only one per page -->\n<h2>Major Section</h2>\n<h3>Subsection</h3>\n<h2>Another Section</h2>\n```\n\n### Internal Linking\n\n```liquid\n<!-- Link to related content -->\n<p>See our <a href=\"{{ '/docs/setup/' | relative_url }}\">setup guide</a> for more details.</p>\n\n<!-- Use descriptive anchor text -->\n<!-- Avoid \"click here\" -->\n```\n\n## Performance for SEO\n\n### Page Speed\n\n```yaml\n# Fast loading = better SEO\n# Target metrics:\n# - First Contentful Paint: < 1.8s\n# - Largest Contentful Paint: < 2.5s\n# - Time to Interactive: < 3.8s\n```\n\nSee [Performance Guide](performance.html) for optimization.\n\n### Mobile-Friendly\n\n```html\n<!-- Responsive viewport -->\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n```\n\n```css\n/* Mobile-first design */\n.container {\n  padding: 20px;\n}\n\n@media (min-width: 768px) {\n  .container {\n    padding: 40px;\n  }\n}\n```\n\n## Analytics\n\n### Google Analytics 4\n\n```html\n<!-- Global site tag (gtag.js) -->\n<script\n  async\n  src=\"https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX\"\n></script>\n<script>\n  window.dataLayer = window.dataLayer || [];\n  function gtag() {\n    dataLayer.push(arguments);\n  }\n  gtag(\"js\", new Date());\n  gtag(\"config\", \"G-XXXXXXXXXX\");\n</script>\n```\n\n### Google Search Console\n\n1. Add property at [search.google.com/search-console](https://search.google.com/search-console)\n2. Verify ownership via HTML tag or DNS\n3. Submit sitemap\n4. Monitor performance and issues\n\n### Track Important Metrics\n\n- Organic search traffic\n- Click-through rates\n- Average position\n- Core Web Vitals\n- Mobile usability\n- Index coverage\n\n## Social Sharing Optimization\n\n### Social Share Buttons\n\n```html\n<div class=\"share-buttons\">\n  <a\n    href=\"https://twitter.com/intent/tweet?url={{ page.url | absolute_url }}&text={{ page.title }}\"\n    target=\"_blank\"\n    rel=\"noopener\"\n    aria-label=\"Share on Twitter\"\n  >\n    <i class=\"fab fa-twitter\"></i>\n  </a>\n\n  <a\n    href=\"https://www.facebook.com/sharer/sharer.php?u={{ page.url | absolute_url }}\"\n    target=\"_blank\"\n    rel=\"noopener\"\n    aria-label=\"Share on Facebook\"\n  >\n    <i class=\"fab fa-facebook\"></i>\n  </a>\n\n  <a\n    href=\"https://reddit.com/submit?url={{ page.url | absolute_url }}&title={{ page.title }}\"\n    target=\"_blank\"\n    rel=\"noopener\"\n    aria-label=\"Share on Reddit\"\n  >\n    <i class=\"fab fa-reddit\"></i>\n  </a>\n</div>\n```\n\n### Test Social Cards\n\n- [Twitter Card Validator](https://cards-dev.twitter.com/validator)\n- [Facebook Sharing Debugger](https://developers.facebook.com/tools/debug/)\n- [LinkedIn Post Inspector](https://www.linkedin.com/post-inspector/)\n\n## Best Practices Checklist\n\n- [ ] Unique title and description for each page\n- [ ] Proper heading hierarchy (h1 → h2 → h3)\n- [ ] SEO-friendly URLs (descriptive, lowercase, hyphens)\n- [ ] Alt text for all images\n- [ ] Internal linking between related pages\n- [ ] Mobile-responsive design\n- [ ] Fast page load times (< 3s)\n- [ ] HTTPS enabled\n- [ ] Sitemap.xml submitted to search engines\n- [ ] Robots.txt configured\n- [ ] Structured data (JSON-LD) implemented\n- [ ] Open Graph tags for social sharing\n- [ ] Canonical URLs set\n- [ ] No broken links\n- [ ] Google Analytics installed\n- [ ] Google Search Console configured\n\n## Common Issues\n\n### Duplicate Content\n\n```html\n<!-- Use canonical tags -->\n<link rel=\"canonical\" href=\"{{ page.url | absolute_url }}\" />\n```\n\n### Broken Links\n\n```bash\n# Check with htmlproofer\ngem install html-proofer\nbundle exec htmlproofer ./_site --assume-extension\n```\n\n### Missing Alt Text\n\n```liquid\n{% for modpack in site.data.mods.modpacks %}\n  <img src=\"{{ modpack.icon_url }}\"\n       alt=\"{{ modpack.name }} icon\"\n       loading=\"lazy\">\n{% endfor %}\n```\n\n## Tools\n\n- **Google Search Console**: Monitor search performance\n- **Google PageSpeed Insights**: Test page speed\n- **Screaming Frog**: Crawl and audit your site\n- **Ahrefs/SEMrush**: Keyword research and tracking\n- **Lighthouse**: Automated SEO auditing\n\n## Next Steps\n\n- [Performance Guide](performance.html) - Speed optimization\n- [Accessibility Guide](accessibility.html) - Inclusive design\n- [Deployment Guide](deployment.html) - Launch your site\n","## Rebranding\n\nEdit `_config.yml` to customize your showcase:\n\n```yaml\nsite:\n  name: Your Site Name\n  title: Your Site Title\n  description: A brief description\n  logo: /assets/images/your-logo.svg\n  color: \"#1bd96f\"\n```\n\nReplace images in `assets/images/`:\n\n- `logo.svg` - Navbar logo\n- `favicon.svg` - Browser tab icon\n- `favicon.ico` - Fallback favicon\n\nUpdate SEO metadata:\n\n```yaml\nmeta:\n  og_image: /assets/images/og-image.png\n  apple_touch_icon: /assets/images/apple-touch.png\n```\n\n## Modrinth Integration\n\n### Set Organization\n\nIn `_config.yml`:\n\n```yaml\nmodrinth:\n  org_slug: your-org-slug\n```\n\n### Fetch Projects\n\nAutomatically pull your projects from Modrinth:\n\n```bash\nnpm run fetch\n```\n\nThis updates `data/mods.json` with live project data including downloads, versions, and metadata.\n\n### API Token (Optional)\n\nFor private projects, set the environment variable:\n\n```bash\nexport MODRINTH_API_TOKEN=your_token_here\nnpm run fetch\n```\n\nGet your token from [Modrinth Settings](https://modrinth.com/dashboard/settings).\n\n## Social Links\n\nConfigure social links in `_config.yml`:\n\n```yaml\nsocial:\n  github: https://github.com/your-org/your-repo\n  discord: https://discord.gg/your-invite\n  twitter: https://twitter.com/your-handle\n  modrinth: https://modrinth.com/organization/your-org\n```\n\nThese appear in the navigation and footer.\n\n## Running Locally\n\n### Development\n\n```bash\nbundle install\nnpm install\nbundle exec jekyll serve --livereload\n```\n\nVisit `http://localhost:4000/abc-site/` (adjust baseurl if needed)\n\n### Production Build\n\n```bash\nbundle exec jekyll build\n```\n\nOutput goes to `_site/` ready for deployment.\n\n## Deployment\n\n### GitHub Pages\n\nThe site auto-deploys on push to `main` via GitHub Actions (if configured).\n\n**Manual deployment:**\n\n```bash\nbundle exec jekyll build\ngit add _site/\ngit commit -m \"Update site\"\ngit push origin main\n```\n\n### Custom Hosting\n\nBuild the site:\n\n```bash\nJEKYLL_ENV=production bundle exec jekyll build\n```\n\nUpload `_site/` contents to your hosting provider.\n\n---\n\n**Questions?** Check the [Getting Started](getting-started) guide or open an [issue]({{ site.social.github }}/issues).\n","## Build Fails\n\n**Issue:** `bundle exec jekyll build` fails with an error\n\n**Solutions:**\n\n1. Check Ruby version: `ruby -v` (need 2.6+)\n2. Update gems: `bundle update`\n3. Clear cache: `rm -rf .bundle _site`\n4. Check for syntax errors in YAML files\n\n## Projects Not Showing\n\n**Issue:** Project cards are empty or don't display\n\n**Solutions:**\n\n1. Verify `data/mods.json` exists and is valid JSON\n2. Run `npm run fetch` to regenerate data\n3. Check Modrinth organization slug in `_config.yml`\n4. Ensure API token is set if fetching private projects: `export MODRINTH_API_TOKEN=your_token`\n\n## Styles Not Updating\n\n**Issue:** CSS changes don't appear after editing\n\n**Solutions:**\n\n1. Hard refresh browser: **Cmd+Shift+R** (Mac) or **Ctrl+Shift+R** (Windows)\n2. Restart Jekyll: `bundle exec jekyll serve --livereload`\n3. Clear `_site/` folder: `rm -rf _site`\n4. Ensure you're editing `src/styles/` (will compile to `assets/css/`)\n\n## Navigation Links Broken\n\n**Issue:** Links show 404 or lead to wrong pages\n\n**Solutions:**\n\n1. Check `baseurl` in `_config.yml` matches your deploy path\n2. Verify file exists and permalink is correct in front matter\n3. Use `relative_url` filter: `{{ '/docs/' | relative_url }}`\n\n## Navbar Not Full Width\n\n**Issue:** Header/footer doesn't span the full page\n\n**Solutions:**\n\n1. Check header CSS has `width: 100vw` and `box-sizing: border-box`\n2. Ensure no parent element constrains the width\n3. Verify `padding` isn't adding extra width\n\n## Performance Issues\n\n**Issue:** Site builds slowly\n\n**Solutions:**\n\n1. Check `_config.yml` excludes large folders: `node_modules`, `src/`\n2. Reduce image sizes in `assets/images/`\n3. Remove unused CSS/JS files\n4. Consider using incremental builds: `bundle exec jekyll serve -I`\n\n## Search Not Working\n\n**Issue:** Search bar doesn't filter results\n\n**Solutions:**\n\n1. Ensure `search.js` is loaded in layout\n2. Check that project data is loaded: open DevTools Console\n3. Verify JSON file path is correct\n\n---\n\n**Still stuck?** [Open an issue]({{ site.social.github }}/issues) or check the [FAQ](faq).\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n","<!-- Project page generated from mods.json -->\n"],"related_posts":[],"source":"/home/runner/work/abc-site/abc-site","destination":"/home/runner/work/abc-site/abc-site/_site","collections_dir":"","plugins_dir":"_plugins","layouts_dir":"_layouts","data_dir":"_data","includes_dir":"_includes","safe":false,"include":[".htaccess"],"exclude":[".gitignore","scripts/","Gemfile","Gemfile.lock","vendor/","node_modules/","src/"],"keep_files":[".git",".svn"],"encoding":"utf-8","markdown_ext":"markdown,mkdown,mkdn,mkd,md","strict_front_matter":false,"show_drafts":null,"limit_posts":0,"future":false,"unpublished":false,"whitelist":[],"plugins":["jekyll-sitemap","jekyll-feed"],"markdown":"kramdown","highlighter":"rouge","lsi":false,"excerpt_separator":"<!--more-->","incremental":false,"detach":false,"port":"4000","host":"127.0.0.1","baseurl":"","show_dir_listing":false,"permalink":"date","paginate_path":"/page:num","timezone":null,"quiet":false,"verbose":false,"defaults":[{"scope":{"path":"","type":"posts"},"values":{"permalink":"/blog/:title/"}}],"liquid":{"error_mode":"warn","strict_filters":false,"strict_variables":false},"rdiscount":{"extensions":[]},"redcarpet":{"extensions":[]},"kramdown":{"auto_ids":true,"toc_levels":"1..6","entity_output":"as_char","smart_quotes":"lsquo,rsquo,ldquo,rdquo","input":"GFM","hard_wrap":false,"guess_lang":true,"footnote_nr":1,"show_warnings":false,"syntax_highlighter":"rouge","syntax_highlighter_opts":{"default_lang":"plaintext","guess_lang":true},"coderay":{},"auto_ids":true,"toc_levels":"1..6","entity_output":"as_char","smart_quotes":"lsquo,rsquo,ldquo,rdquo","input":"GFM","hard_wrap":false,"guess_lang":true,"footnote_nr":1,"show_warnings":false,"syntax_highlighter":"rouge","syntax_highlighter_opts":{"default_lang":"plaintext","guess_lang":true},"coderay":{}},"title":"Minecraft Mods & Packs Showcase","description":"Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins from our organization.","url":"https://abc-site.devvyy.xyz","site":{"name":"ABC","title":"Minecraft Mods & Packs Showcase","description":"Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins.","logo":"/assets/images/logo.svg","color":"#1bd96f"},"branding":{"accent":"#1bd96f","meta":{"favicon":"/favicon.svg","apple_touch_icon":"/assets/images/logo.svg","og_image":"/assets/images/logo.svg","og_title":"ABC | Mods & Packs","og_description":"Browse curated Minecraft mods, resource packs, datapacks, modpacks and plugins.","twitter_card":"summary_large_image","twitter_site":"@devvyyxyz","twitter_creator":"@devvyyxyz","embeds":{"default":{"image":"/assets/images/logo.svg","alt":"ABC Mods & Packs"},"discord":{"image":"/assets/images/logo.svg","color":"#1bd96f"},"twitter":{"image":"/assets/images/logo.svg","card":"summary_large_image","alt":"ABC Mods & Packs"},"image":"/assets/images/logo.svg","card":"summary_large_image","alt":"ABC Mods & Packs"}}},"modrinth":{"org_slug":"abcxyz","organization_url":"https://modrinth.com/organization/abcxyz","user_agent":"ABC-Site (github.com/devvyyxyz/abc-site)","api_token_env":"MODRINTH_API_TOKEN"},"social":{"discord":"https://dc.gg/devvyyxyz","twitter":"https://twitter.com/devvyyxyz","github":"https://github.com/devvyyxyz","modrinth":"https://modrinth.com/organization/abcxyz"},"links":{"status_url":"/status/","sitemap":"/sitemap.xml","rss":"/feed.xml"},"serving":false}</pre>

Getting Help

Before Asking

  1. Search existing issues on GitHub
  2. Check documentation thoroughly
  3. Test in fresh browser (incognito mode)
  4. Try latest version of dependencies
  5. Create minimal reproduction of the issue

Where to Ask

Provide Details

When reporting issues, include:

**Environment:**

- OS: macOS 13.0
- Ruby: 3.1.2
- Jekyll: 3.9.0
- Browser: Chrome 120

**Steps to reproduce:**

1. Run `bundle exec jekyll serve`
2. Navigate to /projects/
3. Click on first project

**Expected:** Project page loads
**Actual:** 404 error

**Logs:**

[error log here]


Next Steps