diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..e868be9
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,41 @@
+# EditorConfig helps maintain consistent coding styles across different editors and IDEs
+# https://editorconfig.org/
+
+root = true
+
+# Default settings — Tabs preferred, width = 2 spaces
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+indent_style = tab
+tab_width = 2
+
+# PowerShell scripts — tabs, 2-space visual width
+[*.ps1]
+indent_style = tab
+tab_width = 2
+end_of_line = crlf
+
+# Markdown files — keep trailing whitespace for line breaks
+[*.md]
+trim_trailing_whitespace = false
+
+# JSON / YAML files — tabs, 2-space visual width
+[*.{json,yml,yaml}]
+indent_style = tab
+tab_width = 2
+
+# Makefiles — always tabs, default width
+[Makefile]
+indent_style = tab
+tab_width = 2
+
+# Windows batch scripts — keep CRLF endings
+[*.{bat,cmd}]
+end_of_line = crlf
+
+# Shell scripts — ensure LF endings
+[*.sh]
+end_of_line = lf
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..72f9fd4
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,17 @@
+# Force LF line endings for all text files
+* text=auto eol=lf
+
+# Explicitly mark binary files
+*.png binary
+*.jpg binary
+*.jpeg binary
+*.gif binary
+*.ico binary
+*.svg text eol=lf
+*.woff binary
+*.woff2 binary
+*.ttf binary
+*.eot binary
+*.zip binary
+*.gz binary
+*.tar binary
diff --git a/.github/.mokostandards b/.github/.mokostandards
new file mode 100644
index 0000000..09b7828
--- /dev/null
+++ b/.github/.mokostandards
@@ -0,0 +1 @@
+platform: waas-component
diff --git a/.github/CLAUDE.md b/.github/CLAUDE.md
new file mode 100644
index 0000000..3bffc4c
--- /dev/null
+++ b/.github/CLAUDE.md
@@ -0,0 +1,304 @@
+
+
+> [!IMPORTANT]
+> **🔧 AI Self-Update Required on First Use**
+>
+> This file may contain unfilled `{{TOKEN}}` placeholders. The MokoStandards bulk-sync system
+> replaces them automatically at sync time; if you can still see them, sync has not yet run for
+> this repository — or this is a brand-new repo.
+>
+> **On your very first interaction in this repository, before answering any other question:**
+>
+> 1. Check whether any `{{TOKEN}}` placeholders remain in this file.
+> 2. If they do, locate the values as described in the table below and replace every occurrence
+> in **both** `.github/copilot-instructions.md` and `.github/CLAUDE.md`.
+> 3. After replacing all tokens, **delete this entire notice block** (from `> [!IMPORTANT]`
+> through the closing `> ---` line) in both files.
+> 4. Tell the developer: *"I've self-updated the AI context files with this repository's
+> values — all set."*
+>
+> | Placeholder | Where to find the value |
+> |---|---|
+> | `MokoOnyx` | The GitHub repository name (visible in the URL, `README.md` heading, or `git remote -v`) |
+> | `https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx` | Full GitHub URL, e.g. `https://git.mokoconsulting.tech/MokoConsulting/` |
+> | `{{EXTENSION_NAME}}` | The `` element in `manifest.xml` at the repository root |
+> | `{{EXTENSION_TYPE}}` | The `type` attribute of the `` tag in `manifest.xml` (`component`, `module`, `plugin`, or `template`) |
+> | `{{EXTENSION_ELEMENT}}` | The `` tag in `manifest.xml`, or the filename prefix (e.g. `com_myextension`, `mod_mymodule`) |
+>
+> ---
+
+# MokoOnyx — GitHub Copilot Custom Instructions
+
+## What This Repo Is
+
+This is a **Moko Consulting MokoWaaS** (Joomla) repository governed by [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards). All coding standards, workflows, and policies are defined there and enforced here via bulk sync.
+
+Repository URL: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
+Extension name: **{{EXTENSION_NAME}}**
+Extension type: **{{EXTENSION_TYPE}}** (`{{EXTENSION_ELEMENT}}`)
+Platform: **Joomla 4.x / MokoWaaS**
+
+---
+
+## Primary Language
+
+**PHP** (≥ 7.4) is the primary language for this Joomla extension. JavaScript may be used for frontend enhancements. YAML uses 2-space indentation. All other text files use tabs per `.editorconfig`.
+
+---
+
+## File Header — Always Required on New Files
+
+Every new file needs a copyright header as its first content.
+
+**PHP:**
+```php
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * FILE INFORMATION
+ * DEFGROUP: MokoOnyx.{{EXTENSION_TYPE}}
+ * INGROUP: MokoOnyx
+ * REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
+ * PATH: /path/to/file.php
+ * VERSION: XX.YY.ZZ
+ * BRIEF: One-line description of purpose
+ */
+
+defined('_JEXEC') or die;
+```
+
+**Markdown:**
+```markdown
+
+```
+
+**YAML / Shell / XML:** Use the appropriate comment syntax with the same fields. JSON files are exempt.
+
+---
+
+## Version Management
+
+**`README.md` is the single source of truth for the repository version.**
+
+- **Bump the patch version on every PR** — increment `XX.YY.ZZ` (e.g. `01.02.03` → `01.02.04`) in `README.md` before opening the PR; the `sync-version-on-merge` workflow propagates it automatically to all badges and `FILE INFORMATION` headers on merge to `main`.
+- The `VERSION: XX.YY.ZZ` field in `README.md` governs all other version references.
+- Version format is zero-padded semver: `XX.YY.ZZ` (e.g. `01.02.03`).
+- Never hardcode a specific version in document body text — use the badge or FILE INFORMATION header only.
+
+### Joomla Version Alignment
+
+The version in `README.md` **must always match** the `` tag in `manifest.xml` and the latest entry in `updates.xml`. The `make release` command / release workflow updates all three automatically.
+
+```xml
+
+01.02.04
+
+
+
+
+ {{EXTENSION_NAME}}
+ 01.02.04
+
+
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/01.02.04/{{EXTENSION_ELEMENT}}-01.02.04.zip
+
+
+
+
+
+
+```
+
+---
+
+## Joomla Extension Structure
+
+```
+MokoOnyx/
+├── manifest.xml # Joomla installer manifest (root — required)
+├── updates.xml # Update server manifest (root — required, see below)
+├── site/ # Frontend (site) code
+│ ├── controller.php
+│ ├── controllers/
+│ ├── models/
+│ └── views/
+├── admin/ # Backend (admin) code
+│ ├── controller.php
+│ ├── controllers/
+│ ├── models/
+│ ├── views/
+│ └── sql/
+├── language/ # Language INI files
+├── media/ # CSS, JS, images (deployed to /media/{{EXTENSION_ELEMENT}}/)
+├── docs/ # Technical documentation
+├── tests/ # Test suite
+├── .github/
+│ ├── workflows/
+│ ├── copilot-instructions.md # This file
+│ └── CLAUDE.md
+├── README.md # Version source of truth
+├── CHANGELOG.md
+├── CONTRIBUTING.md
+├── LICENSE # GPL-3.0-or-later
+└── Makefile # Build automation
+```
+
+---
+
+## updates.xml — Required in Repo Root
+
+`updates.xml` **must exist at the repository root**. It is the Joomla update server manifest that allows Joomla installations to check for new versions of this extension.
+
+The `manifest.xml` must reference it via:
+```xml
+
+
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/raw/main/updates.xml
+
+
+```
+
+**Rules:**
+- Every release must prepend a new `` block at the top of `updates.xml` — old entries must be preserved below.
+- The `` in `updates.xml` must exactly match `` in `manifest.xml` and the version in `README.md`.
+- The `` must be a publicly accessible direct download link (GitHub Releases asset URL).
+- `` — the backslash is a **literal backslash character** in the XML attribute value; Joomla's update-server parser treats the value as a regular expression, so `\.` matches a literal dot and `[0-9]+` matches one or more digits. Do not double-escape it.
+
+---
+
+## manifest.xml Rules
+
+- Lives at the repo root as `manifest.xml` (not inside `site/` or `admin/`).
+- `` tag must be kept in sync with `README.md` version and `updates.xml`.
+- Must include `` block pointing to this repo's `updates.xml`.
+- Must include `` and `` sections.
+- Joomla 4.x requires `Moko\{{EXTENSION_NAME}} ` for namespaced extensions.
+
+---
+
+## GitHub Actions — Token Usage
+
+Every workflow must use **`secrets.GH_TOKEN`** (the org-level Personal Access Token).
+
+```yaml
+# ✅ Correct
+- uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.GH_TOKEN }}
+
+env:
+ GH_TOKEN: ${{ secrets.GH_TOKEN }}
+```
+
+```yaml
+# ❌ Wrong — never use these in workflows
+token: ${{ github.token }}
+token: ${{ secrets.GITHUB_TOKEN }}
+```
+
+---
+
+## MokoStandards Reference
+
+This repository is governed by [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards). Authoritative policies:
+
+| Document | Purpose |
+|----------|---------|
+| [file-header-standards.md](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/blob/main/docs/policy/file-header-standards.md) | Copyright-header rules for every file type |
+| [coding-style-guide.md](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/blob/main/docs/policy/coding-style-guide.md) | Naming and formatting conventions |
+| [branching-strategy.md](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/blob/main/docs/policy/branching-strategy.md) | Branch naming, hierarchy, and release workflow |
+| [merge-strategy.md](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/blob/main/docs/policy/merge-strategy.md) | Squash-merge policy and PR title/body conventions |
+| [changelog-standards.md](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/blob/main/docs/policy/changelog-standards.md) | How and when to update CHANGELOG.md |
+| [joomla-development-guide.md](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/blob/main/docs/guide/waas/joomla-development-guide.md) | MokoWaaS Joomla extension development guide |
+
+---
+
+## Naming Conventions
+
+| Context | Convention | Example |
+|---------|-----------|---------|
+| PHP class | `PascalCase` | `MyController` |
+| PHP method / function | `camelCase` | `getItems()` |
+| PHP variable | `$snake_case` | `$item_id` |
+| PHP constant | `UPPER_SNAKE_CASE` | `MAX_ITEMS` |
+| PHP class file | `PascalCase.php` | `ItemModel.php` |
+| YAML workflow | `kebab-case.yml` | `ci-joomla.yml` |
+| Markdown doc | `kebab-case.md` | `installation-guide.md` |
+
+---
+
+## Commit Messages
+
+Format: `(): ` — imperative, lower-case subject, no trailing period.
+
+Valid types: `feat` · `fix` · `docs` · `chore` · `ci` · `refactor` · `style` · `test` · `perf` · `revert` · `build`
+
+---
+
+## Branch Naming
+
+Format: `/[/description]`
+
+Approved prefixes: `dev/` · `rc/` · `version/` · `patch/` · `copilot/` · `dependabot/`
+
+---
+
+## Keeping Documentation Current
+
+| Change type | Documentation to update |
+|-------------|------------------------|
+| New or renamed PHP class/method | PHPDoc block; `docs/api/` entry |
+| New or changed manifest.xml | Update `updates.xml` version; bump README.md version |
+| New release | Prepend `` block to `updates.xml`; update CHANGELOG.md; bump README.md version |
+| New or changed workflow | `docs/workflows/.md` |
+| Any modified file | Update the `VERSION` field in that file's `FILE INFORMATION` block |
+| **Every PR** | **Bump the patch version** — increment `XX.YY.ZZ` in `README.md`; `sync-version-on-merge` propagates it |
+
+---
+
+## Key Constraints
+
+- Never commit directly to `main` — all changes go via PR, squash-merged
+- Never skip the FILE INFORMATION block on a new file
+- Never add `defined('_JEXEC') or die;` to CLI scripts or model tests — only to web-accessible PHP files
+- Never hardcode version numbers in body text — update `README.md` and let automation propagate
+- Never use `github.token` or `secrets.GITHUB_TOKEN` in workflows — always use `secrets.GH_TOKEN`
+- Never let `manifest.xml` version, `updates.xml` version, and `README.md` version go out of sync
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000..e7e6e80
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,55 @@
+# Copyright (C) 2026 Moko Consulting
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# CODEOWNERS — require approval from jmiller-moko for protected paths
+# Synced from MokoStandards. Do not edit manually.
+#
+# Changes to these paths require review from the listed owners before merge.
+# Combined with branch protection (require PR reviews), this prevents
+# unauthorized modifications to workflows, configs, and governance files.
+
+# ── Synced workflows (managed by MokoStandards — do not edit manually) ────
+/.github/workflows/deploy-dev.yml @jmiller-moko
+/.github/workflows/deploy-demo.yml @jmiller-moko
+/.github/workflows/deploy-manual.yml @jmiller-moko
+/.github/workflows/auto-release.yml @jmiller-moko
+/.github/workflows/auto-dev-issue.yml @jmiller-moko
+/.github/workflows/auto-assign.yml @jmiller-moko
+/.github/workflows/sync-version-on-merge.yml @jmiller-moko
+/.github/workflows/enterprise-firewall-setup.yml @jmiller-moko
+/.github/workflows/repository-cleanup.yml @jmiller-moko
+/.github/workflows/standards-compliance.yml @jmiller-moko
+/.github/workflows/codeql-analysis.yml @jmiller-moko
+/.github/workflows/repo_health.yml @jmiller-moko
+/.github/workflows/ci-joomla.yml @jmiller-moko
+/.github/workflows/update-server.yml @jmiller-moko
+/.github/workflows/deploy-manual.yml @jmiller-moko
+/.github/workflows/ci-dolibarr.yml @jmiller-moko
+/.github/workflows/publish-to-mokodolimods.yml @jmiller-moko
+/.github/workflows/changelog-validation.yml @jmiller-moko
+/.github/workflows/branch-freeze.yml @jmiller-moko
+# Custom workflows in .github/workflows/ not listed above are repo-owned.
+
+# ── GitHub configuration ─────────────────────────────────────────────────
+/.github/ISSUE_TEMPLATE/ @jmiller-moko
+/.github/CODEOWNERS @jmiller-moko
+/.github/copilot.yml @jmiller-moko
+/.github/copilot-instructions.md @jmiller-moko
+/.github/CLAUDE.md @jmiller-moko
+/.github/.mokostandards @jmiller-moko
+
+# ── Build and config files ───────────────────────────────────────────────
+/composer.json @jmiller-moko
+/phpstan.neon @jmiller-moko
+/Makefile @jmiller-moko
+/.ftpignore @jmiller-moko
+/.gitignore @jmiller-moko
+/.gitattributes @jmiller-moko
+/.editorconfig @jmiller-moko
+
+# ── Governance documents ─────────────────────────────────────────────────
+/LICENSE @jmiller-moko
+/CONTRIBUTING.md @jmiller-moko
+/SECURITY.md @jmiller-moko
+/GOVERNANCE.md @jmiller-moko
+/CODE_OF_CONDUCT.md @jmiller-moko
diff --git a/.github/ISSUE_TEMPLATE/adr.md b/.github/ISSUE_TEMPLATE/adr.md
new file mode 100644
index 0000000..eb40760
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/adr.md
@@ -0,0 +1,110 @@
+---
+name: Architecture Decision Record (ADR)
+about: Propose or document an architectural decision
+title: '[ADR] '
+labels: 'architecture, decision'
+assignees: ''
+
+---
+
+
+## ADR Number
+ADR-XXXX
+
+## Status
+- [ ] Proposed
+- [ ] Accepted
+- [ ] Deprecated
+- [ ] Superseded by ADR-XXXX
+
+## Context
+Describe the issue or problem that motivates this decision.
+
+## Decision
+State the architecture decision and provide rationale.
+
+## Consequences
+### Positive
+- List positive consequences
+
+### Negative
+- List negative consequences or trade-offs
+
+### Neutral
+- List neutral aspects
+
+## Alternatives Considered
+### Alternative 1
+- Description
+- Pros
+- Cons
+- Why not chosen
+
+### Alternative 2
+- Description
+- Pros
+- Cons
+- Why not chosen
+
+## Implementation Plan
+1. Step 1
+2. Step 2
+3. Step 3
+
+## Stakeholders
+- **Decision Makers**: @user1, @user2
+- **Consulted**: @user3, @user4
+- **Informed**: team-name
+
+## Technical Details
+### Architecture Diagram
+```
+[Add diagram or link]
+```
+
+### Dependencies
+- Dependency 1
+- Dependency 2
+
+### Impact Analysis
+- **Performance**: [Impact description]
+- **Security**: [Impact description]
+- **Scalability**: [Impact description]
+- **Maintainability**: [Impact description]
+
+## Testing Strategy
+- [ ] Unit tests
+- [ ] Integration tests
+- [ ] Performance tests
+- [ ] Security tests
+
+## Documentation
+- [ ] Architecture documentation updated
+- [ ] API documentation updated
+- [ ] Developer guide updated
+- [ ] Runbook created
+
+## Migration Path
+Describe how to migrate from current state to new architecture.
+
+## Rollback Plan
+Describe how to rollback if issues occur.
+
+## Timeline
+- **Proposal Date**:
+- **Decision Date**:
+- **Implementation Start**:
+- **Expected Completion**:
+
+## References
+- Related ADRs:
+- External resources:
+- RFCs:
+
+## Review Checklist
+- [ ] Aligns with enterprise architecture principles
+- [ ] Security implications reviewed
+- [ ] Performance implications reviewed
+- [ ] Cost implications reviewed
+- [ ] Compliance requirements met
+- [ ] Team consensus achieved
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..38a16a7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,48 @@
+---
+name: Bug Report
+about: Report a bug or issue with the project
+title: '[BUG] '
+labels: 'bug'
+assignees: ''
+
+---
+
+
+## Bug Description
+A clear and concise description of what the bug is.
+
+## Steps to Reproduce
+1. Go to '...'
+2. Click on '...'
+3. Scroll down to '...'
+4. See error
+
+## Expected Behavior
+A clear and concise description of what you expected to happen.
+
+## Actual Behavior
+A clear and concise description of what actually happened.
+
+## Screenshots
+If applicable, add screenshots to help explain your problem.
+
+## Environment
+- **Project**: [e.g., MokoDoliTools, moko-cassiopeia]
+- **Version**: [e.g., 1.2.3]
+- **Platform**: [e.g., Dolibarr 18.0, Joomla 5.0]
+- **PHP Version**: [e.g., 8.1]
+- **Database**: [e.g., MySQL 8.0, PostgreSQL 14]
+- **Browser** (if applicable): [e.g., Chrome 120, Firefox 121]
+- **OS**: [e.g., Ubuntu 22.04, Windows 11]
+
+## Additional Context
+Add any other context about the problem here.
+
+## Possible Solution
+If you have suggestions on how to fix the issue, please describe them here.
+
+## Checklist
+- [ ] I have searched for similar issues before creating this one
+- [ ] I have provided all the requested information
+- [ ] I have tested this on the latest stable version
+- [ ] I have checked the documentation and couldn't find a solution
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..e9f2f60
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,18 @@
+---
+blank_issues_enabled: true
+contact_links:
+ - name: 💼 Enterprise Support
+ url: https://mokoconsulting.tech/enterprise
+ about: Enterprise-level support and consultation services
+ - name: 💬 Ask a Question
+ url: https://mokoconsulting.tech/
+ about: Get help or ask questions through our website
+ - name: 📚 MokoStandards Documentation
+ url: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+ about: View our coding standards and best practices
+ - name: 🔒 Report a Security Vulnerability
+ url: https://git.mokoconsulting.tech/MokoConsulting/.github-private/security/advisories/new
+ about: Report security vulnerabilities privately (for critical issues)
+ - name: 💡 Community Discussions
+ url: https://github.com/orgs/mokoconsulting-tech/discussions
+ about: Join community discussions and Q&A
diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md
new file mode 100644
index 0000000..ed4dabc
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/documentation.md
@@ -0,0 +1,52 @@
+---
+name: Documentation Issue
+about: Report an issue with documentation
+title: '[DOCS] '
+labels: 'documentation'
+assignees: ''
+
+---
+
+
+## Documentation Issue
+
+**Location**:
+
+
+## Issue Type
+
+- [ ] Typo or grammar error
+- [ ] Outdated information
+- [ ] Missing documentation
+- [ ] Unclear explanation
+- [ ] Broken links
+- [ ] Missing examples
+- [ ] Other (specify below)
+
+## Description
+
+
+## Current Content
+
+```
+Current text here
+```
+
+## Suggested Improvement
+
+```
+Suggested text here
+```
+
+## Additional Context
+
+
+## Standards Alignment
+- [ ] Follows MokoStandards documentation guidelines
+- [ ] Uses en_US/en_GB localization
+- [ ] Includes proper SPDX headers where applicable
+
+## Checklist
+- [ ] I have searched for similar documentation issues
+- [ ] I have provided a clear description
+- [ ] I have suggested an improvement (if applicable)
diff --git a/.github/ISSUE_TEMPLATE/enterprise_support.md b/.github/ISSUE_TEMPLATE/enterprise_support.md
new file mode 100644
index 0000000..4c3f0b4
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/enterprise_support.md
@@ -0,0 +1,85 @@
+---
+name: Enterprise Support Request
+about: Request enterprise-level support or consultation
+title: '[ENTERPRISE] '
+labels: 'enterprise, support'
+assignees: ''
+
+---
+
+
+## Support Request Type
+- [ ] Critical Production Issue
+- [ ] Performance Optimization
+- [ ] Security Audit
+- [ ] Architecture Review
+- [ ] Custom Development
+- [ ] Migration Support
+- [ ] Training & Onboarding
+- [ ] Other (please specify)
+
+## Priority Level
+- [ ] P0 - Critical (Production Down)
+- [ ] P1 - High (Major Feature Broken)
+- [ ] P2 - Medium (Non-Critical Issue)
+- [ ] P3 - Low (Enhancement/Question)
+
+## Organization Details
+- **Company Name**:
+- **Contact Person**:
+- **Email**:
+- **Phone** (for P0/P1 issues):
+- **Timezone**:
+
+## Issue Description
+Provide a clear and detailed description of your request or issue.
+
+## Business Impact
+Describe the impact on your business operations:
+- Number of users affected:
+- Revenue impact (if applicable):
+- Deadline/SLA requirements:
+
+## Environment Details
+- **Deployment Type**: [On-Premise / Cloud / Hybrid]
+- **Platform**: [Joomla / Dolibarr / Custom]
+- **Version**:
+- **Infrastructure**: [AWS / Azure / GCP / Other]
+- **Scale**: [Users / Transactions / Data Volume]
+
+## Current Configuration
+```yaml
+# Paste relevant configuration (sanitize sensitive data)
+```
+
+## Logs and Diagnostics
+```
+# Paste relevant logs (sanitize sensitive data)
+```
+
+## Attempted Solutions
+Describe any troubleshooting steps already taken.
+
+## Expected Resolution
+Describe your expected outcome or resolution.
+
+## Additional Resources
+- **Documentation Links**:
+- **Related Issues**:
+- **Screenshots/Videos**:
+
+## Enterprise SLA
+- [ ] Standard Support (initial response within 1–3 weeks)
+- [ ] Premium Support (initial response within 5 business days)
+- [ ] Critical Support (initial response within 72 hours)
+- [ ] Custom SLA (specify):
+
+## Compliance Requirements
+- [ ] GDPR
+- [ ] HIPAA
+- [ ] SOC 2
+- [ ] ISO 27001
+- [ ] Other (specify):
+
+---
+**Note**: Enterprise support requests require an active support contract. If you don't have one, please contact us at enterprise@mokoconsulting.tech
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..7b76dc9
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,51 @@
+---
+name: Feature Request
+about: Suggest a new feature or enhancement
+title: '[FEATURE] '
+labels: 'enhancement'
+assignees: ''
+
+---
+
+
+## Feature Description
+A clear and concise description of the feature you'd like to see.
+
+## Problem or Use Case
+Describe the problem this feature would solve or the use case it addresses.
+Ex. I'm always frustrated when [...]
+
+## Proposed Solution
+A clear and concise description of what you want to happen.
+
+## Alternative Solutions
+A clear and concise description of any alternative solutions or features you've considered.
+
+## Benefits
+Describe how this feature would benefit users:
+- Who would use this feature?
+- What problems does it solve?
+- What value does it add?
+
+## Implementation Details (Optional)
+If you have ideas about how this could be implemented, share them here:
+- Technical approach
+- Files/components that might need changes
+- Any concerns or challenges you foresee
+
+## Additional Context
+Add any other context, mockups, or screenshots about the feature request here.
+
+## Relevant Standards
+Does this relate to any standards in [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards)?
+- [ ] Accessibility (WCAG 2.1 AA)
+- [ ] Localization (en_US/en_GB)
+- [ ] Security best practices
+- [ ] Code quality standards
+- [ ] Other: [specify]
+
+## Checklist
+- [ ] I have searched for similar feature requests before creating this one
+- [ ] I have clearly described the use case and benefits
+- [ ] I have considered alternative solutions
+- [ ] This feature aligns with the project's goals and scope
diff --git a/.github/ISSUE_TEMPLATE/firewall-request.md b/.github/ISSUE_TEMPLATE/firewall-request.md
new file mode 100644
index 0000000..4a43395
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/firewall-request.md
@@ -0,0 +1,190 @@
+---
+name: Firewall Request
+about: Request firewall rule changes or access to external resources
+title: '[FIREWALL] [Resource Name] - [Brief Description]'
+labels: ['firewall-request', 'infrastructure', 'security']
+assignees: []
+---
+
+
+## Firewall Request
+
+### Request Type
+- [ ] Allow outbound access to external service/API
+- [ ] Allow inbound access from external source
+- [ ] Modify existing firewall rule
+- [ ] Remove/revoke firewall rule
+- [ ] Other (specify):
+
+### Resource Information
+**Service/Domain Name**:
+**IP Address(es)**:
+**Port(s)**:
+**Protocol**:
+- [ ] HTTP (80)
+- [ ] HTTPS (443)
+- [ ] SSH (22)
+- [ ] FTP (21)
+- [ ] SFTP (22)
+- [ ] Custom (specify): _______________
+
+### Requestor Information
+**Name**:
+**GitHub Username**: @
+**Email**: @mokoconsulting.tech
+**Team/Department**:
+**Manager**: @
+
+### Business Justification
+**Why is this access needed?**
+
+**Which project(s) require this access?**
+
+**What functionality will break without this access?**
+
+**Is there an alternative solution?**
+- [ ] Yes (explain):
+- [ ] No
+
+### Security Considerations
+**Data Classification**:
+- [ ] Public
+- [ ] Internal
+- [ ] Confidential
+- [ ] Restricted
+
+**Sensitive Data Transmission**:
+- [ ] No sensitive data will be transmitted
+- [ ] Sensitive data will be transmitted (encryption required)
+- [ ] Authentication credentials will be transmitted (secure storage required)
+
+**Third-Party Service**:
+- [ ] This is a trusted/verified third-party service
+- [ ] This is a new/unverified service (security review required)
+
+**Service Documentation**:
+(Provide link to service documentation or API specs)
+
+### Access Scope
+**Affected Systems**:
+- [ ] Development environment only
+- [ ] Staging environment only
+- [ ] Production environment
+- [ ] All environments
+
+**Access Duration**:
+- [ ] Permanent (ongoing business need)
+- [ ] Temporary (specify end date): _______________
+- [ ] Testing only (specify duration): _______________
+
+### Technical Details
+**Source System(s)**:
+(Which internal systems need access?)
+
+**Destination System(s)**:
+(Which external systems need to be accessed?)
+
+**Expected Traffic Volume**:
+(e.g., requests per hour/day)
+
+**Traffic Pattern**:
+- [ ] Continuous
+- [ ] Periodic (specify frequency): _______________
+- [ ] On-demand/manual
+- [ ] Scheduled (specify schedule): _______________
+
+### Testing Requirements
+**Pre-Production Testing**:
+- [ ] Request includes dev/staging access for testing
+- [ ] Testing can be done with production access only
+- [ ] No testing required (modify existing rule)
+
+**Testing Plan**:
+
+**Rollback Plan**:
+(What happens if access needs to be revoked?)
+
+### Compliance & Audit
+**Compliance Requirements**:
+- [ ] GDPR considerations
+- [ ] SOC 2 compliance required
+- [ ] PCI DSS considerations
+- [ ] Other regulatory requirements: _______________
+- [ ] No specific compliance requirements
+
+**Audit/Logging Requirements**:
+- [ ] Standard logging sufficient
+- [ ] Enhanced logging/monitoring required
+- [ ] Real-time alerting required
+
+### Urgency
+- [ ] Critical (production down, immediate access needed)
+- [ ] High (needed within 24 hours)
+- [ ] Normal (needed within 1 week)
+- [ ] Low priority (needed within 1 month)
+
+**If critical/high urgency, explain why:**
+
+### Approvals
+**Manager Approval**:
+- [ ] Manager has been notified and approves this request
+
+**Security Team Review Required**:
+- [ ] Yes (new external service, sensitive data)
+- [ ] No (minor change, established service)
+
+### Additional Information
+
+**Related Documentation**:
+(Links to relevant docs, RFCs, tickets, etc.)
+
+**Dependencies**:
+(Other systems or changes this depends on)
+
+**Comments/Questions**:
+
+---
+
+## For Infrastructure/Security Team Use Only
+
+**Do not edit below this line**
+
+### Security Review
+- [ ] Security team review completed
+- [ ] Risk assessment: Low / Medium / High
+- [ ] Encryption required: Yes / No
+- [ ] VPN required: Yes / No
+- [ ] Additional security controls: _______________
+
+**Reviewed By**: @_______________
+**Review Date**: _______________
+**Review Notes**:
+
+### Implementation
+- [ ] Firewall rule created/modified
+- [ ] Rule tested in dev/staging
+- [ ] Rule deployed to production
+- [ ] Monitoring/alerting configured
+- [ ] Documentation updated
+
+**Firewall Rule ID**: _______________
+**Implementation Date**: _______________
+**Implemented By**: @_______________
+
+**Configuration Details**:
+```
+Source:
+Destination:
+Port/Protocol:
+Action: Allow/Deny
+```
+
+### Verification
+- [ ] Requestor confirmed access working
+- [ ] Logs reviewed (no anomalies)
+- [ ] Security scan completed (if applicable)
+
+**Verification Date**: _______________
+**Verified By**: @_______________
+
+### Notes
diff --git a/.github/ISSUE_TEMPLATE/joomla_issue.md b/.github/ISSUE_TEMPLATE/joomla_issue.md
new file mode 100644
index 0000000..d808f79
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/joomla_issue.md
@@ -0,0 +1,87 @@
+---
+name: Joomla Extension Issue
+about: Report an issue with a Joomla extension
+title: '[JOOMLA] '
+labels: 'joomla'
+assignees: ''
+
+---
+
+
+## Issue Type
+- [ ] Component Issue
+- [ ] Module Issue
+- [ ] Plugin Issue
+- [ ] Template Issue
+
+## Extension Details
+- **Extension Name**: [e.g., moko-cassiopeia]
+- **Extension Version**: [e.g., 1.2.3]
+- **Extension Type**: [Component / Module / Plugin / Template]
+
+## Joomla Environment
+- **Joomla Version**: [e.g., 4.4.0, 5.0.0]
+- **PHP Version**: [e.g., 8.1.0]
+- **Database**: [MySQL / PostgreSQL / MariaDB]
+- **Database Version**: [e.g., 8.0]
+- **Server**: [Apache / Nginx / IIS]
+- **Hosting**: [Shared / VPS / Dedicated / Cloud]
+
+## Issue Description
+Provide a clear and detailed description of the issue.
+
+## Steps to Reproduce
+1. Go to '...'
+2. Click on '...'
+3. Configure '...'
+4. See error
+
+## Expected Behavior
+What you expected to happen.
+
+## Actual Behavior
+What actually happened.
+
+## Error Messages
+```
+# Paste any error messages from Joomla error logs
+# Location: administrator/logs/error.php
+```
+
+## Browser Console Errors
+```javascript
+// Paste any JavaScript console errors (F12 in browser)
+```
+
+## Screenshots
+Add screenshots to help explain the issue.
+
+## Configuration
+```ini
+# Paste extension configuration (sanitize sensitive data)
+```
+
+## Installed Extensions
+List other installed extensions that might conflict:
+- Extension 1 (version)
+- Extension 2 (version)
+
+## Template Overrides
+- [ ] Using template overrides
+- [ ] Custom CSS
+- [ ] Custom JavaScript
+
+## Additional Context
+- **Multilingual Site**: [Yes / No]
+- **Cache Enabled**: [Yes / No]
+- **Debug Mode**: [Yes / No]
+- **SEF URLs**: [Yes / No]
+
+## Checklist
+- [ ] I have cleared Joomla cache
+- [ ] I have disabled other extensions to test for conflicts
+- [ ] I have checked Joomla error logs
+- [ ] I have tested with a default Joomla template
+- [ ] I have checked browser console for JavaScript errors
+- [ ] I have searched for similar issues
+- [ ] I am using a supported Joomla version
diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md
new file mode 100644
index 0000000..e17850b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/question.md
@@ -0,0 +1,82 @@
+---
+name: Question
+about: Ask a question about usage, features, or best practices
+title: '[QUESTION] '
+labels: ['question']
+assignees: []
+---
+
+
+## Question
+
+**Your question:**
+
+
+## Context
+
+**What are you trying to accomplish?**
+
+
+**What have you already tried?**
+
+
+**Category**:
+- [ ] Script usage
+- [ ] Configuration
+- [ ] Workflow setup
+- [ ] Documentation interpretation
+- [ ] Best practices
+- [ ] Integration
+- [ ] Other: __________
+
+## Environment (if relevant)
+
+**Your setup**:
+- Operating System:
+- Version:
+
+## What You've Researched
+
+**Documentation reviewed**:
+- [ ] README.md
+- [ ] Project documentation
+- [ ] Other (specify): __________
+
+**Similar issues/questions found**:
+- #
+- #
+
+## Expected Outcome
+
+**What result are you hoping for?**
+
+
+## Code/Configuration Samples
+
+**Relevant code or configuration** (if applicable):
+
+```bash
+# Your code here
+```
+
+## Additional Context
+
+**Any other relevant information:**
+
+
+**Screenshots** (if helpful):
+
+
+## Urgency
+
+- [ ] Urgent (blocking work)
+- [ ] Normal (can work on other things meanwhile)
+- [ ] Low priority (just curious)
+
+## Checklist
+
+- [ ] I have searched existing issues and discussions
+- [ ] I have reviewed relevant documentation
+- [ ] I have provided sufficient context
+- [ ] I have included code/configuration samples if relevant
+- [ ] This is a genuine question (not a bug report or feature request)
diff --git a/.github/ISSUE_TEMPLATE/request-license.md b/.github/ISSUE_TEMPLATE/request-license.md
new file mode 100644
index 0000000..52c3b74
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/request-license.md
@@ -0,0 +1,107 @@
+---
+name: License Request
+about: Request an organization license for Sublime Text
+title: '[LICENSE REQUEST] Sublime Text - [Your Name]'
+labels: ['license-request', 'admin']
+assignees: []
+---
+
+
+## License Request
+
+### Tool Information
+**Tool Name**: Sublime Text
+
+**License Type Requested**: Organization Pool
+
+**Personal Purchase**:
+- [ ] I prefer to purchase my own license ($99 USD - recommended, immediate access)
+- [ ] I prefer an organization license (1-2 business days, organization use only)
+- [ ] I have already purchased my own license (registration only for support)
+
+### Requestor Information
+**Name**:
+**GitHub Username**: @
+**Email**: @mokoconsulting.tech
+**Team/Department**:
+**Manager**: @
+
+### Justification
+**Why do you need this license?**
+
+**Primary use case**:
+- [ ] Remote development (SFTP to servers)
+- [ ] Local development
+- [ ] Code review
+- [ ] Documentation editing
+- [ ] Other (specify):
+
+**Which projects/repositories will you work on?**
+
+**Have you evaluated the free trial?**
+- [ ] Yes, I've used the trial and Sublime Text meets my needs
+- [ ] No, requesting license before trial
+
+**Alternative tools considered**:
+- [ ] VS Code (free alternative)
+- [ ] Vim/Neovim (free, terminal-based)
+- [ ] Other: _______________
+
+### Platform
+- [ ] Windows
+- [ ] macOS
+- [ ] Linux (distribution: ________)
+
+### Urgency
+- [ ] Urgent (needed within 24 hours - please justify)
+- [ ] Normal (1-2 business days)
+- [ ] Low priority (when available)
+
+**If urgent, please explain why:**
+
+### SFTP Plugin
+**Note**: Sublime SFTP plugin ($16 USD) is a **separate personal purchase** and is NOT provided by the organization.
+
+- [ ] I understand SFTP plugin requires separate personal purchase
+- [ ] I have already purchased SFTP plugin
+- [ ] I will purchase SFTP plugin if needed for my work
+- [ ] I don't need SFTP plugin (local development only)
+
+### Acknowledgments
+- [ ] I have read the License Management Policy (/docs/github-private/LICENSE_MANAGEMENT.md)
+- [ ] I understand organization licenses are for work use only
+- [ ] I understand organization licenses must be returned upon leaving
+- [ ] I understand personal purchases ($99) are an alternative with lifetime access
+- [ ] I understand SFTP plugin ($16) requires separate personal purchase
+- [ ] I agree to the terms of use
+
+### Additional Information
+
+**Expected daily usage hours**: _____ hours/day
+
+**Duration of need**:
+- [ ] Permanent (ongoing role)
+- [ ] Temporary project (_____ months)
+- [ ] Trial/Evaluation (_____ weeks)
+
+**Comments/Questions**:
+
+---
+
+## For Admin Use Only
+
+**Do not edit below this line**
+
+- [ ] Manager approval received (@manager-username)
+- [ ] License available in pool (current: __/20)
+- [ ] License type confirmed (Organization / Personal registration)
+- [ ] License key sent via encrypted email
+- [ ] Activation confirmed by user
+- [ ] Added to license tracking sheet
+- [ ] User notified of SFTP plugin requirement
+
+**License Key ID**: _____________
+**Date Issued**: _____________
+**Issued By**: @_____________
+
+**Notes**:
diff --git a/.github/ISSUE_TEMPLATE/rfc.md b/.github/ISSUE_TEMPLATE/rfc.md
new file mode 100644
index 0000000..6f09af7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/rfc.md
@@ -0,0 +1,126 @@
+---
+name: Request for Comments (RFC)
+about: Propose a significant change for community discussion
+title: '[RFC] '
+labels: 'rfc, discussion'
+assignees: ''
+
+---
+
+
+## RFC Summary
+One-paragraph summary of the proposal.
+
+## Motivation
+Why are we doing this? What use cases does it support? What is the expected outcome?
+
+## Detailed Design
+### Overview
+Provide a detailed explanation of the proposed change.
+
+### API Changes (if applicable)
+```php
+// Before
+function oldApi($param1) { }
+
+// After
+function newApi($param1, $param2) { }
+```
+
+### User Experience Changes
+Describe how users will interact with this change.
+
+### Implementation Approach
+High-level implementation strategy.
+
+## Drawbacks
+Why should we *not* do this?
+
+## Alternatives
+What other designs have been considered? What is the impact of not doing this?
+
+### Alternative 1
+- Description
+- Trade-offs
+
+### Alternative 2
+- Description
+- Trade-offs
+
+## Adoption Strategy
+How will existing users adopt this? Is this a breaking change?
+
+### Migration Guide
+```bash
+# Steps to migrate
+```
+
+### Deprecation Timeline
+- **Announcement**:
+- **Deprecation**:
+- **Removal**:
+
+## Unresolved Questions
+- Question 1
+- Question 2
+
+## Future Possibilities
+What future work does this enable?
+
+## Impact Assessment
+### Performance
+Expected performance impact.
+
+### Security
+Security considerations and implications.
+
+### Compatibility
+- **Backward Compatible**: [Yes / No]
+- **Breaking Changes**: [List]
+
+### Maintenance
+Long-term maintenance considerations.
+
+## Community Input
+### Stakeholders
+- [ ] Core team
+- [ ] Module developers
+- [ ] End users
+- [ ] Enterprise customers
+
+### Feedback Period
+**Duration**: [e.g., 2 weeks]
+**Deadline**: [date]
+
+## Implementation Timeline
+### Phase 1: Design
+- [ ] RFC discussion
+- [ ] Design finalization
+- [ ] Approval
+
+### Phase 2: Implementation
+- [ ] Core implementation
+- [ ] Tests
+- [ ] Documentation
+
+### Phase 3: Release
+- [ ] Beta release
+- [ ] Feedback collection
+- [ ] Stable release
+
+## Success Metrics
+How will we measure success?
+- Metric 1
+- Metric 2
+
+## References
+- Related RFCs:
+- External documentation:
+- Prior art:
+
+## Open Questions for Community
+1. Question 1?
+2. Question 2?
+
+---
+**Note**: This RFC is open for community discussion. Please provide feedback in the comments below.
diff --git a/.github/ISSUE_TEMPLATE/security.md b/.github/ISSUE_TEMPLATE/security.md
new file mode 100644
index 0000000..f57b284
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/security.md
@@ -0,0 +1,51 @@
+---
+name: Security Vulnerability Report
+about: Report a security vulnerability (use only for non-critical issues)
+title: '[SECURITY] '
+labels: 'security'
+assignees: ''
+
+---
+
+
+## ⚠️ IMPORTANT: Private Disclosure Required
+
+**For critical security vulnerabilities, DO NOT use this template.**
+Follow the process in [SECURITY.md](../SECURITY.md) for responsible disclosure.
+
+Use this template only for:
+- Security improvements
+- Non-critical security suggestions
+- Security documentation updates
+
+---
+
+## Security Issue
+
+**Severity**:
+
+
+## Description
+
+
+## Affected Components
+
+
+## Suggested Mitigation
+
+
+## Standards Reference
+Does this relate to security standards in [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards)?
+- [ ] SPDX license identifiers
+- [ ] Secret management
+- [ ] Dependency security
+- [ ] Access control
+- [ ] Other: [specify]
+
+## Additional Context
+
+
+## Checklist
+- [ ] This is NOT a critical vulnerability requiring private disclosure
+- [ ] I have reviewed the SECURITY.md policy
+- [ ] I have provided sufficient detail for evaluation
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 0000000..3bffc4c
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,304 @@
+
+
+> [!IMPORTANT]
+> **🔧 AI Self-Update Required on First Use**
+>
+> This file may contain unfilled `{{TOKEN}}` placeholders. The MokoStandards bulk-sync system
+> replaces them automatically at sync time; if you can still see them, sync has not yet run for
+> this repository — or this is a brand-new repo.
+>
+> **On your very first interaction in this repository, before answering any other question:**
+>
+> 1. Check whether any `{{TOKEN}}` placeholders remain in this file.
+> 2. If they do, locate the values as described in the table below and replace every occurrence
+> in **both** `.github/copilot-instructions.md` and `.github/CLAUDE.md`.
+> 3. After replacing all tokens, **delete this entire notice block** (from `> [!IMPORTANT]`
+> through the closing `> ---` line) in both files.
+> 4. Tell the developer: *"I've self-updated the AI context files with this repository's
+> values — all set."*
+>
+> | Placeholder | Where to find the value |
+> |---|---|
+> | `MokoOnyx` | The GitHub repository name (visible in the URL, `README.md` heading, or `git remote -v`) |
+> | `https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx` | Full GitHub URL, e.g. `https://git.mokoconsulting.tech/MokoConsulting/` |
+> | `{{EXTENSION_NAME}}` | The `` element in `manifest.xml` at the repository root |
+> | `{{EXTENSION_TYPE}}` | The `type` attribute of the `` tag in `manifest.xml` (`component`, `module`, `plugin`, or `template`) |
+> | `{{EXTENSION_ELEMENT}}` | The `` tag in `manifest.xml`, or the filename prefix (e.g. `com_myextension`, `mod_mymodule`) |
+>
+> ---
+
+# MokoOnyx — GitHub Copilot Custom Instructions
+
+## What This Repo Is
+
+This is a **Moko Consulting MokoWaaS** (Joomla) repository governed by [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards). All coding standards, workflows, and policies are defined there and enforced here via bulk sync.
+
+Repository URL: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
+Extension name: **{{EXTENSION_NAME}}**
+Extension type: **{{EXTENSION_TYPE}}** (`{{EXTENSION_ELEMENT}}`)
+Platform: **Joomla 4.x / MokoWaaS**
+
+---
+
+## Primary Language
+
+**PHP** (≥ 7.4) is the primary language for this Joomla extension. JavaScript may be used for frontend enhancements. YAML uses 2-space indentation. All other text files use tabs per `.editorconfig`.
+
+---
+
+## File Header — Always Required on New Files
+
+Every new file needs a copyright header as its first content.
+
+**PHP:**
+```php
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * FILE INFORMATION
+ * DEFGROUP: MokoOnyx.{{EXTENSION_TYPE}}
+ * INGROUP: MokoOnyx
+ * REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
+ * PATH: /path/to/file.php
+ * VERSION: XX.YY.ZZ
+ * BRIEF: One-line description of purpose
+ */
+
+defined('_JEXEC') or die;
+```
+
+**Markdown:**
+```markdown
+
+```
+
+**YAML / Shell / XML:** Use the appropriate comment syntax with the same fields. JSON files are exempt.
+
+---
+
+## Version Management
+
+**`README.md` is the single source of truth for the repository version.**
+
+- **Bump the patch version on every PR** — increment `XX.YY.ZZ` (e.g. `01.02.03` → `01.02.04`) in `README.md` before opening the PR; the `sync-version-on-merge` workflow propagates it automatically to all badges and `FILE INFORMATION` headers on merge to `main`.
+- The `VERSION: XX.YY.ZZ` field in `README.md` governs all other version references.
+- Version format is zero-padded semver: `XX.YY.ZZ` (e.g. `01.02.03`).
+- Never hardcode a specific version in document body text — use the badge or FILE INFORMATION header only.
+
+### Joomla Version Alignment
+
+The version in `README.md` **must always match** the `` tag in `manifest.xml` and the latest entry in `updates.xml`. The `make release` command / release workflow updates all three automatically.
+
+```xml
+
+01.02.04
+
+
+
+
+ {{EXTENSION_NAME}}
+ 01.02.04
+
+
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/01.02.04/{{EXTENSION_ELEMENT}}-01.02.04.zip
+
+
+
+
+
+
+```
+
+---
+
+## Joomla Extension Structure
+
+```
+MokoOnyx/
+├── manifest.xml # Joomla installer manifest (root — required)
+├── updates.xml # Update server manifest (root — required, see below)
+├── site/ # Frontend (site) code
+│ ├── controller.php
+│ ├── controllers/
+│ ├── models/
+│ └── views/
+├── admin/ # Backend (admin) code
+│ ├── controller.php
+│ ├── controllers/
+│ ├── models/
+│ ├── views/
+│ └── sql/
+├── language/ # Language INI files
+├── media/ # CSS, JS, images (deployed to /media/{{EXTENSION_ELEMENT}}/)
+├── docs/ # Technical documentation
+├── tests/ # Test suite
+├── .github/
+│ ├── workflows/
+│ ├── copilot-instructions.md # This file
+│ └── CLAUDE.md
+├── README.md # Version source of truth
+├── CHANGELOG.md
+├── CONTRIBUTING.md
+├── LICENSE # GPL-3.0-or-later
+└── Makefile # Build automation
+```
+
+---
+
+## updates.xml — Required in Repo Root
+
+`updates.xml` **must exist at the repository root**. It is the Joomla update server manifest that allows Joomla installations to check for new versions of this extension.
+
+The `manifest.xml` must reference it via:
+```xml
+
+
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/raw/main/updates.xml
+
+
+```
+
+**Rules:**
+- Every release must prepend a new `` block at the top of `updates.xml` — old entries must be preserved below.
+- The `` in `updates.xml` must exactly match `` in `manifest.xml` and the version in `README.md`.
+- The `` must be a publicly accessible direct download link (GitHub Releases asset URL).
+- `` — the backslash is a **literal backslash character** in the XML attribute value; Joomla's update-server parser treats the value as a regular expression, so `\.` matches a literal dot and `[0-9]+` matches one or more digits. Do not double-escape it.
+
+---
+
+## manifest.xml Rules
+
+- Lives at the repo root as `manifest.xml` (not inside `site/` or `admin/`).
+- `` tag must be kept in sync with `README.md` version and `updates.xml`.
+- Must include `` block pointing to this repo's `updates.xml`.
+- Must include `` and `` sections.
+- Joomla 4.x requires `Moko\{{EXTENSION_NAME}} ` for namespaced extensions.
+
+---
+
+## GitHub Actions — Token Usage
+
+Every workflow must use **`secrets.GH_TOKEN`** (the org-level Personal Access Token).
+
+```yaml
+# ✅ Correct
+- uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.GH_TOKEN }}
+
+env:
+ GH_TOKEN: ${{ secrets.GH_TOKEN }}
+```
+
+```yaml
+# ❌ Wrong — never use these in workflows
+token: ${{ github.token }}
+token: ${{ secrets.GITHUB_TOKEN }}
+```
+
+---
+
+## MokoStandards Reference
+
+This repository is governed by [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards). Authoritative policies:
+
+| Document | Purpose |
+|----------|---------|
+| [file-header-standards.md](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/blob/main/docs/policy/file-header-standards.md) | Copyright-header rules for every file type |
+| [coding-style-guide.md](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/blob/main/docs/policy/coding-style-guide.md) | Naming and formatting conventions |
+| [branching-strategy.md](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/blob/main/docs/policy/branching-strategy.md) | Branch naming, hierarchy, and release workflow |
+| [merge-strategy.md](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/blob/main/docs/policy/merge-strategy.md) | Squash-merge policy and PR title/body conventions |
+| [changelog-standards.md](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/blob/main/docs/policy/changelog-standards.md) | How and when to update CHANGELOG.md |
+| [joomla-development-guide.md](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/blob/main/docs/guide/waas/joomla-development-guide.md) | MokoWaaS Joomla extension development guide |
+
+---
+
+## Naming Conventions
+
+| Context | Convention | Example |
+|---------|-----------|---------|
+| PHP class | `PascalCase` | `MyController` |
+| PHP method / function | `camelCase` | `getItems()` |
+| PHP variable | `$snake_case` | `$item_id` |
+| PHP constant | `UPPER_SNAKE_CASE` | `MAX_ITEMS` |
+| PHP class file | `PascalCase.php` | `ItemModel.php` |
+| YAML workflow | `kebab-case.yml` | `ci-joomla.yml` |
+| Markdown doc | `kebab-case.md` | `installation-guide.md` |
+
+---
+
+## Commit Messages
+
+Format: `(): ` — imperative, lower-case subject, no trailing period.
+
+Valid types: `feat` · `fix` · `docs` · `chore` · `ci` · `refactor` · `style` · `test` · `perf` · `revert` · `build`
+
+---
+
+## Branch Naming
+
+Format: `/[/description]`
+
+Approved prefixes: `dev/` · `rc/` · `version/` · `patch/` · `copilot/` · `dependabot/`
+
+---
+
+## Keeping Documentation Current
+
+| Change type | Documentation to update |
+|-------------|------------------------|
+| New or renamed PHP class/method | PHPDoc block; `docs/api/` entry |
+| New or changed manifest.xml | Update `updates.xml` version; bump README.md version |
+| New release | Prepend `` block to `updates.xml`; update CHANGELOG.md; bump README.md version |
+| New or changed workflow | `docs/workflows/.md` |
+| Any modified file | Update the `VERSION` field in that file's `FILE INFORMATION` block |
+| **Every PR** | **Bump the patch version** — increment `XX.YY.ZZ` in `README.md`; `sync-version-on-merge` propagates it |
+
+---
+
+## Key Constraints
+
+- Never commit directly to `main` — all changes go via PR, squash-merged
+- Never skip the FILE INFORMATION block on a new file
+- Never add `defined('_JEXEC') or die;` to CLI scripts or model tests — only to web-accessible PHP files
+- Never hardcode version numbers in body text — update `README.md` and let automation propagate
+- Never use `github.token` or `secrets.GITHUB_TOKEN` in workflows — always use `secrets.GH_TOKEN`
+- Never let `manifest.xml` version, `updates.xml` version, and `README.md` version go out of sync
diff --git a/.github/copilot.yml b/.github/copilot.yml
new file mode 100644
index 0000000..f00b751
--- /dev/null
+++ b/.github/copilot.yml
@@ -0,0 +1,137 @@
+# GitHub Copilot Configuration
+# This file configures GitHub Copilot settings for the repository
+
+# Allowed domains for Copilot to access
+# These domains are trusted sources that Copilot can fetch information from
+allowed_domains:
+ # Standard license providers
+ - "www.gnu.org" # GNU licenses (GPL, LGPL, AGPL)
+ - "opensource.org" # Open Source Initiative
+ - "choosealicense.com" # GitHub's license chooser
+ - "spdx.org" # Software Package Data Exchange
+ - "creativecommons.org" # Creative Commons licenses
+ - "apache.org" # Apache Software Foundation
+ - "fsf.org" # Free Software Foundation
+
+ # Documentation and standards
+ - "semver.org" # Semantic Versioning
+ - "keepachangelog.com" # Changelog standards
+ - "conventionalcommits.org" # Commit message standards
+
+ # GitHub and related
+ - "github.com" # GitHub main site
+ - "docs.github.com" # GitHub documentation
+ - "raw.githubusercontent.com" # GitHub raw content
+
+ # Package managers and registries
+ - "npmjs.com" # npm registry
+ - "pypi.org" # Python Package Index
+ - "packagist.org" # PHP Composer packages
+ - "rubygems.org" # Ruby gems
+
+ # Standards and specifications
+ - "json-schema.org" # JSON Schema
+ - "w3.org" # W3C standards
+ - "ietf.org" # IETF RFCs and standards
+
+ # PHP and Joomla specific
+ - "joomla.org" # Joomla CMS
+ - "docs.joomla.org" # Joomla documentation
+ - "downloads.joomla.org" # Joomla core downloads
+ - "php.net" # PHP documentation
+ - "getcomposer.org" # Composer dependency manager
+ - "packagist.org" # Composer package registry (also listed under packages)
+
+ # Dolibarr specific
+ - "dolibarr.org" # Dolibarr ERP/CRM
+ - "wiki.dolibarr.org" # Dolibarr wiki
+ - "docs.dolibarr.org" # Dolibarr developer documentation
+
+ # Moko Consulting
+ - "mokoconsulting.tech" # Moko Consulting main site
+ - "*.mokoconsulting.tech" # All Moko Consulting subdomains (API, docs, CDN, etc.)
+
+ # Google services
+ - "drive.google.com" # Google Drive (file sharing and assets)
+ - "docs.google.com" # Google Docs
+ - "sheets.google.com" # Google Sheets
+ - "accounts.google.com" # Google authentication
+ - "storage.googleapis.com" # Google Cloud Storage
+ - "*.googleapis.com" # Google APIs (Maps, Fonts, etc.)
+ - "*.googleusercontent.com" # Google user-uploaded content and CDN
+ - "fonts.googleapis.com" # Google Fonts CSS
+ - "fonts.gstatic.com" # Google Fonts static assets
+
+ # GitHub extended
+ - "api.github.com" # GitHub REST API
+ - "upload.github.com" # GitHub file uploads
+ - "objects.githubusercontent.com" # GitHub release assets and LFS
+ - "user-images.githubusercontent.com" # GitHub issue/PR image attachments
+ - "codeload.github.com" # GitHub archive downloads
+ - "ghcr.io" # GitHub Container Registry
+ - "pkg.github.com" # GitHub Packages
+
+ # Developer reference
+ - "developer.mozilla.org" # MDN Web Docs
+ - "stackoverflow.com" # Stack Overflow
+ - "git-scm.com" # Git documentation
+
+ # CDN and infrastructure
+ - "cdn.jsdelivr.net" # jsDelivr CDN
+ - "unpkg.com" # unpkg CDN
+ - "cdnjs.cloudflare.com" # Cloudflare CDN
+ - "img.shields.io" # Shields.io badge images
+ - "shields.io" # Shields.io badge service
+
+ # Container registries
+ - "hub.docker.com" # Docker Hub
+ - "registry-1.docker.io" # Docker registry pulls
+ - "index.docker.io" # Docker index
+
+ # CI / code quality
+ - "codecov.io" # Code coverage reporting
+ - "coveralls.io" # Coveralls coverage service
+ - "sonarcloud.io" # SonarCloud static analysis
+
+ # Terraform / infrastructure
+ - "registry.terraform.io" # Terraform provider registry
+ - "releases.hashicorp.com" # HashiCorp release downloads
+ - "checkpoint-api.hashicorp.com" # HashiCorp update checks
+
+# Settings for code generation and suggestions
+copilot:
+ # Enable Copilot for this repository
+ enabled: true
+
+ # File patterns to include for Copilot suggestions
+ include:
+ - "**/*.py"
+ - "**/*.js"
+ - "**/*.php"
+ - "**/*.md"
+ - "**/*.yml"
+ - "**/*.yaml"
+ - "**/*.json"
+ - "**/*.xml"
+ - "**/*.sh"
+
+ # File patterns to exclude from Copilot suggestions
+ exclude:
+ - "**/node_modules/**"
+ - "**/vendor/**"
+ - "**/build/**"
+ - "**/dist/**"
+ - "**/.git/**"
+ - "**/LICENSE"
+ - "**/CHANGELOG.md"
+
+# Notes:
+# ------
+# - This configuration allows GitHub Copilot to fetch information from trusted sources
+# - License providers are included to help with license text and compliance information
+# - Package registries help with dependency management and version checking
+# - Standards organizations provide authoritative specifications
+# - Platform-specific sites (Joomla, Dolibarr, PHP) support our technology stack
+# - All domains listed are well-known, reputable sources in their respective domains
+# - This list focuses on read-only access to public information
+# - No authentication credentials should be used with these domains
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..96a5cd0
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,107 @@
+# Copyright (C) 2026 Moko Consulting
+# SPDX-License-Identifier: GPL-3.0-or-later
+# FILE INFORMATION
+# DEFGROUP: GitHub.Dependabot
+# INGROUP: MokoStandards.Security
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /.github/dependabot.yml
+# VERSION: 03.09.03
+# BRIEF: Dependabot configuration for automated dependency updates and security patches
+# NOTE: Monitors GitHub Actions for vulnerabilities and keeps ecosystem secure
+
+version: 2
+updates:
+ # Monitor GitHub Actions for security updates
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "monthly"
+ open-pull-requests-limit: 1
+ labels:
+ - "dependencies"
+ - "security"
+ - "automated"
+ commit-message:
+ prefix: "chore(deps)"
+ include: "scope"
+ reviewers:
+ - "mokoconsulting-tech/maintainers"
+ assignees:
+ - "jmiller-moko"
+ # Group all updates together
+ groups:
+ github-actions:
+ patterns:
+ - "*"
+
+ # Monitor Python dependencies for security updates
+ - package-ecosystem: "pip"
+ directory: "/"
+ schedule:
+ interval: "monthly"
+ open-pull-requests-limit: 1
+ labels:
+ - "dependencies"
+ - "security"
+ - "automated"
+ - "python"
+ commit-message:
+ prefix: "chore(deps)"
+ include: "scope"
+ reviewers:
+ - "mokoconsulting-tech/maintainers"
+ assignees:
+ - "jmiller-moko"
+ # Group all updates together
+ groups:
+ python-dependencies:
+ patterns:
+ - "*"
+
+ # Monitor npm dependencies for security updates
+ - package-ecosystem: "npm"
+ directory: "/"
+ schedule:
+ interval: "monthly"
+ open-pull-requests-limit: 1
+ labels:
+ - "dependencies"
+ - "security"
+ - "automated"
+ - "javascript"
+ commit-message:
+ prefix: "chore(deps)"
+ include: "scope"
+ reviewers:
+ - "mokoconsulting-tech/maintainers"
+ assignees:
+ - "jmiller-moko"
+ # Group all updates together
+ groups:
+ npm-dependencies:
+ patterns:
+ - "*"
+
+ # Monitor Composer dependencies for security updates
+ - package-ecosystem: "composer"
+ directory: "/"
+ schedule:
+ interval: "monthly"
+ open-pull-requests-limit: 1
+ labels:
+ - "dependencies"
+ - "security"
+ - "automated"
+ - "php"
+ commit-message:
+ prefix: "chore(deps)"
+ include: "scope"
+ reviewers:
+ - "mokoconsulting-tech/maintainers"
+ assignees:
+ - "jmiller-moko"
+ # Group all updates together
+ groups:
+ composer-dependencies:
+ patterns:
+ - "*"
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000..d1b972f
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,20 @@
+# Pull Request
+
+## Purpose
+
+## Change Summary
+
+## Testing Evidence
+
+## Risk and Rollback
+
+## Checklist
+- [ ] Follows Conventional Commits
+- [ ] Tests added or updated
+- [ ] Documentation updated if required
+- [ ] License header present where applicable
+- [ ] Linked issue(s) referenced
+
+## Reviewer Notes
+
+## Review and Approval
diff --git a/.github/workflows/auto-assign.yml b/.github/workflows/auto-assign.yml
new file mode 100644
index 0000000..4d38fc6
--- /dev/null
+++ b/.github/workflows/auto-assign.yml
@@ -0,0 +1,76 @@
+# Copyright (C) 2026 Moko Consulting
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow
+# INGROUP: MokoStandards.Workflows.Shared
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /.github/workflows/auto-assign.yml
+# VERSION: 04.06.00
+# BRIEF: Auto-assign jmiller to unassigned issues and PRs every 15 minutes
+
+name: Auto-Assign Issues & PRs
+
+on:
+ issues:
+ types: [opened]
+ pull_request_target:
+ types: [opened]
+ schedule:
+ - cron: '0 */12 * * *'
+ workflow_dispatch:
+
+permissions:
+ issues: write
+ pull-requests: write
+
+jobs:
+ auto-assign:
+ name: Assign unassigned issues and PRs
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Assign unassigned issues
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ REPO="${{ github.repository }}"
+ ASSIGNEE="jmiller"
+
+ echo "## 🏷️ Auto-Assign Report" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ ASSIGNED_ISSUES=0
+ ASSIGNED_PRS=0
+
+ # Assign unassigned open issues
+ ISSUES=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/issues?state=open&per_page=100&assignee=none" | jq -r '.[].number' 2>/dev/null || true)
+ for NUM in $ISSUES; do
+ # Skip PRs (the issues endpoint returns PRs too)
+ IS_PR=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/issues/$NUM" | jq -r '.pull_request // empty' 2>/dev/null || true)
+ if [ -z "$IS_PR" ]; then
+ curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/issues/$NUM/assignees" 2>/dev/null -X POST -f "assignees[]=$ASSIGNEE" --silent 2>/dev/null && {
+ ASSIGNED_ISSUES=$((ASSIGNED_ISSUES + 1))
+ echo " Assigned issue #$NUM"
+ } || true
+ fi
+ done
+
+ # Assign unassigned open PRs
+ PRS=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/pulls?state=open&per_page=100" | jq -r '.[] | select(.assignees | length == 0) | .number' 2>/dev/null || true)
+ for NUM in $PRS; do
+ curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/issues/$NUM/assignees" 2>/dev/null -X POST -f "assignees[]=$ASSIGNEE" --silent 2>/dev/null && {
+ ASSIGNED_PRS=$((ASSIGNED_PRS + 1))
+ echo " Assigned PR #$NUM"
+ } || true
+ done
+
+ echo "| Type | Assigned |" >> $GITHUB_STEP_SUMMARY
+ echo "|------|----------|" >> $GITHUB_STEP_SUMMARY
+ echo "| Issues | $ASSIGNED_ISSUES |" >> $GITHUB_STEP_SUMMARY
+ echo "| Pull Requests | $ASSIGNED_PRS |" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$ASSIGNED_ISSUES" -eq 0 ] && [ "$ASSIGNED_PRS" -eq 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "✅ All issues and PRs already have assignees" >> $GITHUB_STEP_SUMMARY
+ fi
diff --git a/.github/workflows/auto-dev-issue.yml b/.github/workflows/auto-dev-issue.yml
new file mode 100644
index 0000000..b0fe690
--- /dev/null
+++ b/.github/workflows/auto-dev-issue.yml
@@ -0,0 +1,207 @@
+# Copyright (C) 2026 Moko Consulting
+#
+# This file is part of a Moko Consulting project.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow
+# INGROUP: MokoStandards.Automation
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /templates/workflows/shared/auto-dev-issue.yml.template
+# VERSION: 04.06.00
+# BRIEF: Auto-create tracking issue with sub-issues for dev/rc branch workflow
+# NOTE: Synced via bulk-repo-sync to .github/workflows/auto-dev-issue.yml in all governed repos.
+
+name: Dev/RC Branch Issue
+
+on:
+ # Auto-create on RC branch creation
+ create:
+ # Manual trigger for dev branches
+ workflow_dispatch:
+ inputs:
+ branch:
+ description: 'Branch name (e.g., dev/my-feature or dev/04.06)'
+ required: true
+ type: string
+
+env:
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
+
+permissions:
+ contents: read
+ issues: write
+
+jobs:
+ create-issue:
+ name: Create version tracking issue
+ runs-on: ubuntu-latest
+ if: >-
+ (github.event_name == 'workflow_dispatch') ||
+ (github.event.ref_type == 'branch' &&
+ (startsWith(github.event.ref, 'rc/') ||
+ startsWith(github.event.ref, 'alpha/') ||
+ startsWith(github.event.ref, 'beta/')))
+
+ steps:
+ - name: Create tracking issue and sub-issues
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ # For manual dispatch, use input; for auto, use event ref
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
+ BRANCH="${{ inputs.branch }}"
+ else
+ BRANCH="${{ github.event.ref }}"
+ fi
+ REPO="${{ github.repository }}"
+ ACTOR="${{ github.actor }}"
+ NOW=$(date -u '+%Y-%m-%d %H:%M UTC')
+
+ # Determine branch type and version
+ if [[ "$BRANCH" == rc/* ]]; then
+ VERSION="${BRANCH#rc/}"
+ BRANCH_TYPE="Release Candidate"
+ LABEL_TYPE="type: release"
+ TITLE_PREFIX="rc"
+ elif [[ "$BRANCH" == beta/* ]]; then
+ VERSION="${BRANCH#beta/}"
+ BRANCH_TYPE="Beta"
+ LABEL_TYPE="type: release"
+ TITLE_PREFIX="beta"
+ elif [[ "$BRANCH" == alpha/* ]]; then
+ VERSION="${BRANCH#alpha/}"
+ BRANCH_TYPE="Alpha"
+ LABEL_TYPE="type: release"
+ TITLE_PREFIX="alpha"
+ else
+ VERSION="${BRANCH#dev/}"
+ BRANCH_TYPE="Development"
+ LABEL_TYPE="type: feature"
+ TITLE_PREFIX="feat"
+ fi
+
+ TITLE="${TITLE_PREFIX}(${VERSION}): ${BRANCH_TYPE} tracking for ${BRANCH}"
+
+ # Check for existing issue with same title prefix
+ EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/issues?state=open&per_page=10" 2>/dev/null \
+ | jq -r ".[] | select(.title | startswith(\"${TITLE_PREFIX}(${VERSION})\")) | .number" 2>/dev/null | head -1)
+
+ if [ -n "$EXISTING" ]; then
+ echo "ℹ️ Issue #${EXISTING} already exists for ${VERSION}" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
+ # ── Define sub-issues for the workflow ─────────────────────────
+ if [[ "$BRANCH" == rc/* ]]; then
+ SUB_ISSUES=(
+ "RC Testing|Verify all features work on rc branch|type: test,release-candidate"
+ "Regression Testing|Run full regression suite before merge|type: test,release-candidate"
+ "Version Bump|Bump version in README.md and all headers|type: version,release-candidate"
+ "Changelog Update|Update CHANGELOG.md with release notes|documentation,release-candidate"
+ "Merge to Version Branch|Create PR to version/XX|type: release,needs-review"
+ )
+ elif [[ "$BRANCH" == alpha/* ]] || [[ "$BRANCH" == beta/* ]]; then
+ SUB_ISSUES=(
+ "Testing|Verify features on ${BRANCH_TYPE} branch|type: test,status: in-progress"
+ "Bug Fixes|Fix issues found during ${BRANCH_TYPE} testing|type: bug,status: pending"
+ "Promote to Next Stage|Create PR to promote to next release stage|type: release,needs-review"
+ )
+ else
+ SUB_ISSUES=(
+ "Development|Implement feature/fix on dev branch|type: feature,status: in-progress"
+ "Unit Testing|Write and pass unit tests|type: test,status: pending"
+ "Code Review|Request and complete code review|needs-review,status: pending"
+ "Version Bump|Bump version in README.md and all headers|type: version,status: pending"
+ "Changelog Update|Update CHANGELOG.md with release notes|documentation,status: pending"
+ "Create RC Branch|Promote dev to rc branch for final testing|type: release,status: pending"
+ "Merge to Main|Create PR from rc/dev to main|type: release,needs-review,status: pending"
+ )
+ fi
+
+ # ── Create sub-issues first ───────────────────────────────────────
+ SUB_LIST=""
+ SUB_NUMBERS=""
+ for SUB in "${SUB_ISSUES[@]}"; do
+ IFS='|' read -r SUB_TITLE SUB_DESC SUB_LABELS <<< "$SUB"
+ SUB_FULL_TITLE="${TITLE_PREFIX}(${VERSION}): ${SUB_TITLE}"
+
+ SUB_BODY=$(printf '### %s\n\n%s\n\n| Field | Value |\n|-------|-------|\n| **Parent Branch** | `%s` |\n| **Version** | `%s` |\n\n---\n*Sub-issue of the %s tracking issue for `%s`.*' \
+ "$SUB_TITLE" "$SUB_DESC" "$BRANCH" "$VERSION" "$BRANCH_TYPE" "$BRANCH")
+
+ SUB_URL=$(gh issue create \
+ --repo "$REPO" \
+ --title "$SUB_FULL_TITLE" \
+ --body "$SUB_BODY" \
+ --label "${SUB_LABELS}" \
+ --assignee "jmiller" 2>&1)
+
+ SUB_NUM=$(echo "$SUB_URL" | grep -oE '[0-9]+$')
+ if [ -n "$SUB_NUM" ]; then
+ SUB_LIST="${SUB_LIST}\n- [ ] ${SUB_TITLE} (#${SUB_NUM})"
+ SUB_NUMBERS="${SUB_NUMBERS} #${SUB_NUM}"
+ fi
+ sleep 0.3
+ done
+
+ # ── Create parent tracking issue ──────────────────────────────────
+ PARENT_BODY=$(printf '## %s Branch Created\n\n| Field | Value |\n|-------|-------|\n| **Branch** | `%s` |\n| **Version** | `%s` |\n| **Type** | %s |\n| **Created by** | @%s |\n| **Created at** | %s |\n| **Repository** | `%s` |\n\n## Workflow Sub-Issues\n\n%b\n\n---\n*Auto-created by [auto-dev-issue.yml](.github/workflows/auto-dev-issue.yml) on branch creation.*' \
+ "$BRANCH_TYPE" "$BRANCH" "$VERSION" "$BRANCH_TYPE" "$ACTOR" "$NOW" "$REPO" "$SUB_LIST")
+
+ PARENT_URL=$(gh issue create \
+ --repo "$REPO" \
+ --title "$TITLE" \
+ --body "$PARENT_BODY" \
+ --label "${LABEL_TYPE},version" \
+ --assignee "jmiller" 2>&1)
+
+ PARENT_NUM=$(echo "$PARENT_URL" | grep -oE '[0-9]+$')
+
+ # ── Link sub-issues back to parent ────────────────────────────────
+ if [ -n "$PARENT_NUM" ]; then
+ for SUB in "${SUB_ISSUES[@]}"; do
+ IFS='|' read -r SUB_TITLE _ _ <<< "$SUB"
+ SUB_FULL_TITLE="${TITLE_PREFIX}(${VERSION}): ${SUB_TITLE}"
+ SUB_NUM=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/issues?state=open&per_page=20" 2>/dev/null \
+ | jq -r ".[] | select(.title == \"${SUB_FULL_TITLE}\") | .number" 2>/dev/null | head -1)
+ if [ -n "$SUB_NUM" ]; then
+ curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/issues/${SUB_NUM}" 2>/dev/null -X PATCH \
+ -f body="$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/issues/${SUB_NUM}" | jq -r '.body' 2>/dev/null)
+
+ > **Parent Issue:** #${PARENT_NUM}" --silent 2>/dev/null || true
+ fi
+ sleep 0.2
+ done
+ fi
+
+ # ── Create or update prerelease for alpha/beta/rc ────────────────
+ if [[ "$BRANCH" == rc/* ]] || [[ "$BRANCH" == alpha/* ]] || [[ "$BRANCH" == beta/* ]]; then
+ case "$BRANCH_TYPE" in
+ Alpha) RELEASE_TAG="alpha" ;;
+ Beta) RELEASE_TAG="beta" ;;
+ "Release Candidate") RELEASE_TAG="release-candidate" ;;
+ esac
+
+ EXISTING=$(gh release view "$RELEASE_TAG" --json tagName -q .tagName 2>/dev/null || true)
+ if [ -z "$EXISTING" ]; then
+ gh release create "$RELEASE_TAG" \
+ --title "${RELEASE_TAG} (${VERSION})" \
+ --notes "## ${BRANCH_TYPE} ${VERSION}\n\nBranch: \`${BRANCH}\`\nTracking issue: ${PARENT_URL}" \
+ --prerelease \
+ --target main 2>/dev/null || true
+ echo "${BRANCH_TYPE} release created: ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY
+ else
+ gh release edit "$RELEASE_TAG" \
+ --title "${RELEASE_TAG} (${VERSION})" --prerelease 2>/dev/null || true
+ echo "${BRANCH_TYPE} release updated: ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY
+ fi
+ fi
+
+ # ── Summary ───────────────────────────────────────────────────────
+ echo "## Dev Workflow Issues Created" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| Item | Issue |" >> $GITHUB_STEP_SUMMARY
+ echo "|------|-------|" >> $GITHUB_STEP_SUMMARY
+ echo "| **Parent** | ${PARENT_URL} |" >> $GITHUB_STEP_SUMMARY
+ echo "| **Sub-issues** |${SUB_NUMBERS} |" >> $GITHUB_STEP_SUMMARY
diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml
new file mode 100644
index 0000000..8933815
--- /dev/null
+++ b/.github/workflows/auto-release.yml
@@ -0,0 +1,563 @@
+# Copyright (C) 2026 Moko Consulting
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow
+# INGROUP: MokoStandards.Release
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /templates/workflows/joomla/auto-release.yml.template
+# VERSION: 04.06.00
+# BRIEF: Joomla build & release — ZIP package, updates.xml, SHA-256 checksum
+#
+# +========================================================================+
+# | BUILD & RELEASE PIPELINE (JOOMLA) |
+# +========================================================================+
+# | |
+# | Triggers on push to main (skips bot commits + [skip ci]): |
+# | |
+# | Every push: |
+# | 1. Read version from README.md |
+# | 3. Set platform version (Joomla ) |
+# | 4. Update [VERSION: XX.YY.ZZ] badges in markdown files |
+# | 5. Write updates.xml (Joomla update server XML) |
+# | 6. Create git tag vXX.YY.ZZ |
+# | 7a. Patch: update existing GitHub Release for this minor |
+# | 8. Build ZIP, upload asset, write SHA-256 to updates.xml |
+# | |
+# | Every version change: archives main -> version/XX.YY branch |
+# | Patch 00 = development (no release). First release = patch 01. |
+# | First release only (patch == 01): |
+# | 7b. Create new GitHub Release |
+# | |
+# +========================================================================+
+
+name: Build & Release
+
+on:
+ pull_request:
+ types: [closed]
+ branches:
+ - main
+ paths:
+ - 'src/**'
+ - 'htdocs/**'
+ workflow_dispatch:
+
+env:
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
+
+permissions:
+ contents: write
+
+jobs:
+ release:
+ name: Build & Release Pipeline
+ runs-on: release
+ if: >-
+ github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch'
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ with:
+ token: ${{ secrets.GA_TOKEN || github.token }}
+ fetch-depth: 0
+
+ - name: Set authenticated push URL
+ run: git remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
+
+ - name: Setup MokoStandards tools
+ env:
+ GA_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GA_TOKEN || github.token }}"}}'
+ run: |
+ git clone --depth 1 --branch version/04 --quiet \
+ "https://x-access-token:${GH_TOKEN}@git.mokoconsulting.tech/MokoConsulting/MokoStandards-API.git" \
+ /tmp/mokostandards-api
+ cd /tmp/mokostandards-api
+ composer install --no-dev --no-interaction --quiet
+
+ # -- STEP 1: Read version -----------------------------------------------
+ - name: "Step 1: Read version from README.md"
+ id: version
+ run: |
+ VERSION=$(php /tmp/mokostandards-api/cli/version_read.php --path . 2>/dev/null)
+ if [ -z "$VERSION" ]; then
+ echo "No VERSION in README.md — skipping release"
+ echo "skip=true" >> "$GITHUB_OUTPUT"
+ exit 0
+ fi
+ # Derive major.minor for branch naming (patches update existing branch)
+ MINOR=$(echo "$VERSION" | awk -F. '{printf "%s.%s", $1, $2}')
+ PATCH=$(echo "$VERSION" | awk -F. '{print $3}')
+
+ MAJOR=$(echo "$VERSION" | awk -F. '{print $1}')
+ MINOR_NUM=$(echo "$VERSION" | awk -F. '{print $2}')
+
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
+ echo "branch=version/${MAJOR}" >> "$GITHUB_OUTPUT"
+ echo "minor=$MINOR" >> "$GITHUB_OUTPUT"
+ echo "major=$MAJOR" >> "$GITHUB_OUTPUT"
+ echo "release_tag=v${MAJOR}" >> "$GITHUB_OUTPUT"
+ if [ "$PATCH" = "00" ]; then
+ echo "skip=true" >> "$GITHUB_OUTPUT"
+ echo "is_minor=false" >> "$GITHUB_OUTPUT"
+ echo "Version: $VERSION (patch 00 = development — skipping release)"
+ else
+ echo "skip=false" >> "$GITHUB_OUTPUT"
+ if [ "$PATCH" = "01" ]; then
+ echo "is_minor=true" >> "$GITHUB_OUTPUT"
+ echo "Version: $VERSION (first release — full pipeline)"
+ else
+ echo "is_minor=false" >> "$GITHUB_OUTPUT"
+ echo "Version: $VERSION (patch — platform version + badges only)"
+ fi
+ fi
+
+ - name: Check if already released
+ if: steps.version.outputs.skip != 'true'
+ id: check
+ run: |
+ TAG="${{ steps.version.outputs.release_tag }}"
+ BRANCH="${{ steps.version.outputs.branch }}"
+
+ TAG_EXISTS=false
+ BRANCH_EXISTS=false
+
+ git rev-parse "$TAG" >/dev/null 2>&1 && TAG_EXISTS=true
+ git ls-remote --heads origin "$BRANCH" 2>/dev/null | grep -q "$BRANCH" && BRANCH_EXISTS=true
+
+ echo "tag_exists=$TAG_EXISTS" >> "$GITHUB_OUTPUT"
+ echo "branch_exists=$BRANCH_EXISTS" >> "$GITHUB_OUTPUT"
+
+ if [ "$TAG_EXISTS" = "true" ] && [ "$BRANCH_EXISTS" = "true" ]; then
+ echo "already_released=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "already_released=false" >> "$GITHUB_OUTPUT"
+ fi
+
+ # -- SANITY CHECKS -------------------------------------------------------
+ - name: "Sanity: Pre-release validation"
+ if: >-
+ steps.version.outputs.skip != 'true' &&
+ steps.check.outputs.already_released != 'true'
+ run: |
+ VERSION="${{ steps.version.outputs.version }}"
+ ERRORS=0
+
+ echo "## Pre-Release Sanity Checks (Joomla)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # -- Version drift check (must pass before release) --------
+ README_VER=$(sed -n 's/.*VERSION:[[:space:]]*\([0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\).*/\1/p' README.md 2>/dev/null | head -1)
+ if [ "$README_VER" != "$VERSION" ]; then
+ echo "- Version drift: README says \`${README_VER}\` but releasing \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS+1))
+ else
+ echo "- Version consistent: \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Check CHANGELOG version matches
+ CL_VER=$(sed -n 's/.*VERSION:[[:space:]]*\([0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\).*/\1/p' CHANGELOG.md 2>/dev/null | head -1)
+ if [ -n "$CL_VER" ] && [ "$CL_VER" != "$VERSION" ]; then
+ echo "- CHANGELOG drift: \`${CL_VER}\` != \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS+1))
+ fi
+
+ # Check composer.json version if present
+ if [ -f "composer.json" ]; then
+ COMP_VER=$(sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' composer.json 2>/dev/null | head -1)
+ if [ -n "$COMP_VER" ] && [ "$COMP_VER" != "$VERSION" ]; then
+ echo "- composer.json drift: \`${COMP_VER}\` != \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS+1))
+ fi
+ fi
+
+ # Common checks
+ if [ ! -f "LICENSE" ]; then
+ echo "- Missing LICENSE file" >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS+1))
+ else
+ echo "- LICENSE present" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ if [ ! -d "src" ] && [ ! -d "htdocs" ]; then
+ echo "- Warning: No src/ or htdocs/ directory" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "- Source directory present" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # -- Joomla: manifest version drift --------
+ MANIFEST=$(find . -maxdepth 2 -name "*.xml" -exec grep -l '/dev/null | head -1)
+ if [ -n "$MANIFEST" ]; then
+ XML_VER=$(sed -n 's/.*\([^<]*\)<\/version>.*/\1/p' "$MANIFEST" 2>/dev/null | head -1)
+ if [ -n "$XML_VER" ] && [ "$XML_VER" != "$VERSION" ]; then
+ echo "- Manifest drift: \`${XML_VER}\` != \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS+1))
+ else
+ echo "- Manifest version: \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY
+ fi
+ fi
+
+ # -- Joomla: XML manifest existence --------
+ if [ -z "$MANIFEST" ]; then
+ echo "- No Joomla XML manifest found" >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS+1))
+ else
+ echo "- Manifest: \`${MANIFEST}\`" >> $GITHUB_STEP_SUMMARY
+
+ # -- Joomla: extension type check --------
+ TYPE=$(sed -n 's/.*]*type="\([^"]*\)".*/\1/p' "$MANIFEST" 2>/dev/null)
+ echo "- Extension type: ${TYPE:-unknown}" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ if [ "$ERRORS" -gt 0 ]; then
+ echo "**${ERRORS} error(s) — release may be incomplete**" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "**All sanity checks passed**" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # -- STEP 2: Create or update version/XX.YY archive branch ---------------
+ # Always runs — every version change on main archives to version/XX.YY
+ - name: "Step 2: Version archive branch"
+ if: steps.check.outputs.already_released != 'true'
+ run: |
+ BRANCH="${{ steps.version.outputs.branch }}"
+ IS_MINOR="${{ steps.version.outputs.is_minor }}"
+ PATCH="${{ steps.version.outputs.version }}"
+ PATCH_NUM=$(echo "$PATCH" | awk -F. '{print $3}')
+
+ # Check if branch exists
+ if git ls-remote --heads origin "$BRANCH" | grep -q "$BRANCH"; then
+ git push origin HEAD:"$BRANCH" --force
+ echo "Updated archive branch: ${BRANCH} (patch ${PATCH_NUM})" >> $GITHUB_STEP_SUMMARY
+ else
+ git checkout -b "$BRANCH" 2>/dev/null || git checkout "$BRANCH"
+ git push origin "$BRANCH" --force
+ echo "Created archive branch: ${BRANCH}" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # -- STEP 3: Set platform version ----------------------------------------
+ - name: "Step 3: Set platform version"
+ if: >-
+ steps.version.outputs.skip != 'true' &&
+ steps.check.outputs.already_released != 'true'
+ run: |
+ VERSION="${{ steps.version.outputs.version }}"
+ php /tmp/mokostandards-api/cli/version_set_platform.php \
+ --path . --version "$VERSION" --branch main
+
+ # -- STEP 4: Update version badges ----------------------------------------
+ - name: "Step 4: Update version badges"
+ if: >-
+ steps.version.outputs.skip != 'true' &&
+ steps.check.outputs.already_released != 'true'
+ run: |
+ VERSION="${{ steps.version.outputs.version }}"
+ find . -name "*.md" ! -path "./.git/*" ! -path "./vendor/*" | while read -r f; do
+ if grep -q '\[VERSION:' "$f" 2>/dev/null; then
+ sed -i "s/\[VERSION:[[:space:]]*[0-9]\{2\}\.[0-9]\{2\}\.[0-9]\{2\}\]/[VERSION: ${VERSION}]/" "$f"
+ fi
+ done
+
+ # -- STEP 5: Write updates.xml (Joomla update server) ---------------------
+ - name: "Step 5: Write updates.xml"
+ if: >-
+ steps.version.outputs.skip != 'true' &&
+ steps.check.outputs.already_released != 'true'
+ run: |
+ VERSION="${{ steps.version.outputs.version }}"
+ REPO="${{ github.repository }}"
+
+ # -- Parse extension metadata from XML manifest ----------------
+ MANIFEST=$(find . -maxdepth 2 -name "*.xml" -exec grep -l '/dev/null | head -1)
+ if [ -z "$MANIFEST" ]; then
+ echo "Warning: No Joomla XML manifest found — skipping updates.xml" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
+ # Extract fields using sed (portable — no grep -P)
+ EXT_NAME=$(sed -n 's/.*\([^<]*\)<\/name>.*/\1/p' "$MANIFEST" | head -1)
+ EXT_TYPE=$(sed -n 's/.*]*type="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1)
+ EXT_ELEMENT=$(sed -n 's/.*\([^<]*\)<\/element>.*/\1/p' "$MANIFEST" | head -1)
+ EXT_CLIENT=$(sed -n 's/.*]*client="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1)
+ EXT_FOLDER=$(sed -n 's/.*]*group="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1)
+ TARGET_PLATFORM=$(sed -n 's/.*\( \).*/\1/p' "$MANIFEST" | head -1)
+ PHP_MINIMUM=$(sed -n 's/.*\([^<]*\)<\/php_minimum>.*/\1/p' "$MANIFEST" | head -1)
+
+ # Fallbacks
+ [ -z "$EXT_NAME" ] && EXT_NAME="${{ github.event.repository.name }}"
+ [ -z "$EXT_TYPE" ] && EXT_TYPE="component"
+
+ # Templates/modules don't have — derive from (lowercased)
+ if [ -z "$EXT_ELEMENT" ]; then
+ EXT_ELEMENT=$(echo "$EXT_NAME" | tr '[:upper:]' '[:lower:]' | tr -d ' ')
+ fi
+
+ # Build client tag: plugins and frontend modules need site
+ CLIENT_TAG=""
+ if [ -n "$EXT_CLIENT" ]; then
+ CLIENT_TAG="${EXT_CLIENT} "
+ elif [ "$EXT_TYPE" = "module" ] || [ "$EXT_TYPE" = "plugin" ]; then
+ CLIENT_TAG="site "
+ fi
+
+ # Build folder tag for plugins (required for Joomla to match the update)
+ FOLDER_TAG=""
+ if [ -n "$EXT_FOLDER" ] && [ "$EXT_TYPE" = "plugin" ]; then
+ FOLDER_TAG="${EXT_FOLDER} "
+ fi
+
+ # Build targetplatform (fallback to Joomla 5 if not in manifest)
+ if [ -z "$TARGET_PLATFORM" ]; then
+ TARGET_PLATFORM=$(printf '' "/")
+ fi
+
+ # Build php_minimum tag
+ PHP_TAG=""
+ if [ -n "$PHP_MINIMUM" ]; then
+ PHP_TAG="${PHP_MINIMUM} "
+ fi
+
+ DOWNLOAD_URL="https://git.mokoconsulting.tech/${{ github.repository }}/releases/download/v${VERSION}/${EXT_ELEMENT}-${VERSION}.zip"
+ INFO_URL="https://git.mokoconsulting.tech/${{ github.repository }}/releases/tag/v${VERSION}"
+
+ # -- Build stable entry to temp file ─────────────────────────
+ {
+ printf '%s\n' ' '
+ printf '%s\n' " ${EXT_NAME} "
+ printf '%s\n' " ${EXT_NAME} update "
+ printf '%s\n' " ${EXT_ELEMENT} "
+ printf '%s\n' " ${EXT_TYPE} "
+ printf '%s\n' " ${VERSION} "
+ [ -n "$CLIENT_TAG" ] && printf '%s\n' " ${CLIENT_TAG}"
+ [ -n "$FOLDER_TAG" ] && printf '%s\n' " ${FOLDER_TAG}"
+ printf '%s\n' ' '
+ printf '%s\n' ' stable '
+ printf '%s\n' ' '
+ printf '%s\n' " ${INFO_URL} "
+ printf '%s\n' ' '
+ printf '%s\n' " ${DOWNLOAD_URL} "
+ printf '%s\n' ' '
+ printf '%s\n' " ${TARGET_PLATFORM}"
+ [ -n "$PHP_TAG" ] && printf '%s\n' " ${PHP_TAG}"
+ printf '%s\n' ' Moko Consulting '
+ printf '%s\n' ' https://mokoconsulting.tech '
+ printf '%s\n' ' '
+ } > /tmp/stable_entry.xml
+
+ # -- Write updates.xml preserving dev/rc entries ──────────────
+ # Extract existing entries for other stability levels
+ # Order reflects release workflow: development → alpha → beta → rc → stable
+ if [ -f "updates.xml" ]; then
+ printf 'import re, sys\n' > /tmp/extract.py
+ printf 'with open("updates.xml") as f: c = f.read()\n' >> /tmp/extract.py
+ printf 'tag = sys.argv[1]\n' >> /tmp/extract.py
+ printf 'm = re.search(r"( .*?" + re.escape(tag) + r" .*? )", c, re.DOTALL)\n' >> /tmp/extract.py
+ printf 'if m: print(m.group(1))\n' >> /tmp/extract.py
+ fi
+ DEV_ENTRY=$(python3 /tmp/extract.py development 2>/dev/null || true)
+ ALPHA_ENTRY=$(python3 /tmp/extract.py alpha 2>/dev/null || true)
+ BETA_ENTRY=$(python3 /tmp/extract.py beta 2>/dev/null || true)
+ RC_ENTRY=$(python3 /tmp/extract.py rc 2>/dev/null || true)
+
+ {
+ printf '%s\n' ''
+ printf '%s\n' ''
+ [ -n "$DEV_ENTRY" ] && echo "$DEV_ENTRY"
+ [ -n "$ALPHA_ENTRY" ] && echo "$ALPHA_ENTRY"
+ [ -n "$BETA_ENTRY" ] && echo "$BETA_ENTRY"
+ [ -n "$RC_ENTRY" ] && echo "$RC_ENTRY"
+ cat /tmp/stable_entry.xml
+ printf '%s\n' ' '
+ } > updates.xml
+
+ echo "updates.xml: ${VERSION} (stable + rc/dev preserved)" >> $GITHUB_STEP_SUMMARY
+
+ # -- Commit all changes ---------------------------------------------------
+ - name: Commit release changes
+ if: >-
+ steps.version.outputs.skip != 'true' &&
+ steps.check.outputs.already_released != 'true'
+ run: |
+ if git diff --quiet && git diff --cached --quiet; then
+ echo "No changes to commit"
+ exit 0
+ fi
+ VERSION="${{ steps.version.outputs.version }}"
+ git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
+ git config --local user.name "gitea-actions[bot]"
+ git add -A
+ git commit -m "chore(release): build ${VERSION} [skip ci]" \
+ --author="gitea-actions[bot] "
+ git push
+
+ # -- STEP 6: Create tag ---------------------------------------------------
+ - name: "Step 6: Create git tag"
+ if: >-
+ steps.version.outputs.skip != 'true' &&
+ steps.check.outputs.tag_exists != 'true' &&
+ steps.version.outputs.is_minor == 'true'
+ run: |
+ RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
+ # Only create the major release tag if it doesn't exist yet
+ if ! git rev-parse "$RELEASE_TAG" >/dev/null 2>&1; then
+ git tag "$RELEASE_TAG"
+ git push origin "$RELEASE_TAG"
+ echo "Tag created: ${RELEASE_TAG}" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "Tag ${RELEASE_TAG} already exists" >> $GITHUB_STEP_SUMMARY
+ fi
+ echo "Tag: ${TAG}" >> $GITHUB_STEP_SUMMARY
+
+ # -- STEP 7: Create or update GitHub Release ------------------------------
+ - name: "Step 7: GitHub Release"
+ if: >-
+ steps.version.outputs.skip != 'true' &&
+ steps.check.outputs.tag_exists != 'true'
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ VERSION="${{ steps.version.outputs.version }}"
+ RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
+ BRANCH="${{ steps.version.outputs.branch }}"
+ MAJOR="${{ steps.version.outputs.major }}"
+
+ NOTES=$(php /tmp/mokostandards-api/cli/release_notes.php --path . --version "$VERSION" 2>/dev/null)
+ [ -z "$NOTES" ] && NOTES="Release ${VERSION}"
+ echo "$NOTES" > /tmp/release_notes.md
+
+ # Check if the major release already exists
+ EXISTING=$(gh release view "$RELEASE_TAG" --json tagName -q .tagName 2>/dev/null || true)
+
+ if [ -z "$EXISTING" ]; then
+ # First release for this major
+ gh release create "$RELEASE_TAG" \
+ --title "v${MAJOR} (latest: ${VERSION})" \
+ --notes-file /tmp/release_notes.md \
+ --target "$BRANCH"
+ echo "Release created: ${RELEASE_TAG} (${VERSION})" >> $GITHUB_STEP_SUMMARY
+ else
+ # Append version notes to existing major release
+ CURRENT_NOTES=$(gh release view "$RELEASE_TAG" --json body -q .body 2>/dev/null || true)
+ {
+ echo "$CURRENT_NOTES"
+ echo ""
+ echo "---"
+ echo "### ${VERSION}"
+ echo ""
+ cat /tmp/release_notes.md
+ } > /tmp/updated_notes.md
+
+ gh release edit "$RELEASE_TAG" \
+ --title "v${MAJOR} (latest: ${VERSION})" \
+ --notes-file /tmp/updated_notes.md
+ echo "Release updated: ${RELEASE_TAG} -> ${VERSION}" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # -- STEP 8: Build Joomla install ZIP + SHA-256 checksum ------------------
+ # Every patch builds an install-ready ZIP and uploads it to the minor release.
+ # Result: one Release per minor version with a ZIP for each patch.
+ - name: "Step 8: Build Joomla package and update checksum"
+ if: >-
+ steps.version.outputs.skip != 'true'
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ VERSION="${{ steps.version.outputs.version }}"
+ RELEASE_TAG="${{ steps.version.outputs.release_tag }}"
+ REPO="${{ github.repository }}"
+
+ # All ZIPs upload to the major release tag (vXX)
+ gh release view "$RELEASE_TAG" --json tagName > /dev/null 2>&1 || {
+ echo "No release ${RELEASE_TAG} found — skipping ZIP upload"
+ exit 0
+ }
+
+ # Find extension element name from manifest
+ MANIFEST=$(find . -maxdepth 2 -name "*.xml" -exec grep -l '/dev/null | head -1 || true)
+ [ -z "$MANIFEST" ] && exit 0
+
+ EXT_ELEMENT=$(sed -n 's/.*\([^<]*\)<\/element>.*/\1/p' "$MANIFEST" 2>/dev/null | head -1 || basename "$MANIFEST" .xml)
+ ZIP_NAME="${EXT_ELEMENT}-${VERSION}.zip"
+ TAR_NAME="${EXT_ELEMENT}-${VERSION}.tar.gz"
+
+ # -- Build install packages from src/ ----------------------------
+ SOURCE_DIR="src"
+ [ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs"
+ [ ! -d "$SOURCE_DIR" ] && { echo "No src/ or htdocs/ — skipping package"; exit 0; }
+
+ EXCLUDES=".ftpignore sftp-config* *.ppk *.pem *.key .env*"
+
+ # ZIP package
+ cd "$SOURCE_DIR"
+ zip -r "/tmp/${ZIP_NAME}" . -x $EXCLUDES
+ cd ..
+
+ # tar.gz package
+ tar -czf "/tmp/${TAR_NAME}" -C "$SOURCE_DIR" \
+ --exclude='.ftpignore' --exclude='sftp-config*' \
+ --exclude='*.ppk' --exclude='*.pem' --exclude='*.key' --exclude='.env*' .
+
+ ZIP_SIZE=$(stat -c%s "/tmp/${ZIP_NAME}" 2>/dev/null || stat -f%z "/tmp/${ZIP_NAME}" 2>/dev/null || echo "unknown")
+ TAR_SIZE=$(stat -c%s "/tmp/${TAR_NAME}" 2>/dev/null || stat -f%z "/tmp/${TAR_NAME}" 2>/dev/null || echo "unknown")
+
+ # -- Calculate SHA-256 for both ----------------------------------
+ SHA256_ZIP=$(sha256sum "/tmp/${ZIP_NAME}" | cut -d' ' -f1)
+ SHA256_TAR=$(sha256sum "/tmp/${TAR_NAME}" | cut -d' ' -f1)
+
+ # -- Upload both to release tag ----------------------------------
+ gh release upload "$RELEASE_TAG" "/tmp/${ZIP_NAME}" --clobber 2>/dev/null || true
+ gh release upload "$RELEASE_TAG" "/tmp/${TAR_NAME}" --clobber 2>/dev/null || true
+
+ # -- Update updates.xml with both download formats ---------------
+ if [ -f "updates.xml" ]; then
+ ZIP_URL="https://git.mokoconsulting.tech/${{ github.repository }}/releases/download/${RELEASE_TAG}/${ZIP_NAME}"
+ TAR_URL="https://git.mokoconsulting.tech/${{ github.repository }}/releases/download/${RELEASE_TAG}/${TAR_NAME}"
+
+ # Replace downloads block with both formats + SHA
+ sed -i "s|.* |\n ${ZIP_URL} \n ${TAR_URL} \n |" updates.xml 2>/dev/null || true
+ if grep -q '' updates.xml; then
+ sed -i "s|.* |${SHA256_ZIP} |" updates.xml
+ else
+ sed -i "s||\n ${SHA256_ZIP} |" updates.xml
+ fi
+
+ git add updates.xml
+ git commit -m "chore(release): ZIP + tar.gz for ${VERSION} [skip ci]" \
+ --author="gitea-actions[bot] " || true
+ git push || true
+ fi
+
+ echo "### Joomla Packages" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| Package | Size | SHA-256 |" >> $GITHUB_STEP_SUMMARY
+ echo "|---------|------|---------|" >> $GITHUB_STEP_SUMMARY
+ echo "| \`${ZIP_NAME}\` | ${ZIP_SIZE} | \`${SHA256_ZIP}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| \`${TAR_NAME}\` | ${TAR_SIZE} | \`${SHA256_TAR}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Release | \`${RELEASE_TAG}\` | |" >> $GITHUB_STEP_SUMMARY
+ echo "| Download | [${PACKAGE_NAME}](https://git.mokoconsulting.tech/${{ github.repository }}/releases/download/${RELEASE_TAG}/${PACKAGE_NAME}) |" >> $GITHUB_STEP_SUMMARY
+
+ # -- Summary --------------------------------------------------------------
+ - name: Pipeline Summary
+ if: always()
+ run: |
+ VERSION="${{ steps.version.outputs.version }}"
+ if [ "${{ steps.version.outputs.skip }}" = "true" ]; then
+ echo "## Release Skipped" >> $GITHUB_STEP_SUMMARY
+ echo "No VERSION in README.md" >> $GITHUB_STEP_SUMMARY
+ elif [ "${{ steps.check.outputs.already_released }}" = "true" ]; then
+ echo "## Already Released — ${VERSION}" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "## Build & Release Complete (Joomla)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| Step | Result |" >> $GITHUB_STEP_SUMMARY
+ echo "|------|--------|" >> $GITHUB_STEP_SUMMARY
+ echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Branch | \`${{ steps.version.outputs.branch }}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Tag | \`${{ steps.version.outputs.tag }}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Release | [View](https://github.com/${{ github.repository }}/releases/tag/${{ steps.version.outputs.tag }}) |" >> $GITHUB_STEP_SUMMARY
+ fi
diff --git a/.github/workflows/auto-update-sha.yml b/.github/workflows/auto-update-sha.yml
new file mode 100644
index 0000000..711e86c
--- /dev/null
+++ b/.github/workflows/auto-update-sha.yml
@@ -0,0 +1,144 @@
+# Copyright (C) 2026 Moko Consulting
+# SPDX-License-Identifier: GPL-3.0-or-later
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow
+# INGROUP: MokoOnyx.Automation
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
+# PATH: /.github/workflows/auto-update-sha.yml
+# VERSION: 03.09.03
+# BRIEF: Automatically update SHA-256 hash in updates.xml after release
+# NOTE: Ensures updates.xml stays synchronized with release packages
+
+name: Auto-Update SHA Hash
+
+on:
+ release:
+ types: [published]
+ workflow_dispatch:
+ inputs:
+ tag:
+ description: 'Release tag to update SHA for (e.g., 03.08.03)'
+ required: true
+ type: string
+
+permissions:
+ contents: write
+
+jobs:
+ update-sha:
+ name: Update SHA-256 Hash in updates.xml
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ ref: main
+
+ - name: Get release tag
+ id: tag
+ run: |
+ if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
+ TAG="${{ inputs.tag }}"
+ else
+ TAG="${{ github.event.release.tag_name }}"
+ fi
+ echo "tag=${TAG}" >> $GITHUB_OUTPUT
+ echo "Processing release: ${TAG}"
+
+ - name: Download release package
+ run: |
+ TAG="${{ steps.tag.outputs.tag }}"
+ PACKAGE_NAME="mokoonyx-src-${TAG}.zip"
+ DOWNLOAD_URL="https://github.com/${{ github.repository }}/releases/download/${TAG}/${PACKAGE_NAME}"
+
+ echo "Downloading: ${DOWNLOAD_URL}"
+ curl -L -o "${PACKAGE_NAME}" "${DOWNLOAD_URL}"
+
+ if [ ! -f "${PACKAGE_NAME}" ]; then
+ echo "Error: Failed to download package"
+ exit 1
+ fi
+
+ echo "PACKAGE_NAME=${PACKAGE_NAME}" >> $GITHUB_ENV
+
+ - name: Calculate SHA-256 hash
+ id: sha
+ run: |
+ SHA256_HASH=$(sha256sum "${PACKAGE_NAME}" | cut -d' ' -f1)
+ echo "sha256=${SHA256_HASH}" >> $GITHUB_OUTPUT
+ echo "SHA-256 Hash: ${SHA256_HASH}"
+
+ - name: Update updates.xml
+ run: |
+ TAG="${{ steps.tag.outputs.tag }}"
+ SHA256="${{ steps.sha.outputs.sha256 }}"
+ DATE=$(date +%Y-%m-%d)
+
+ # Update version
+ sed -i "s|.* |${TAG} |" updates.xml
+
+ # Update creation date
+ sed -i "s|.* |${DATE} |" updates.xml
+
+ # Update download URL
+ sed -i "s|.* |https://github.com/${{ github.repository }}/releases/download/${TAG}/mokoonyx-src-${TAG}.zip |" updates.xml
+
+ # Update or add SHA-256 hash
+ if grep -q "" updates.xml; then
+ sed -i "s|.* |sha256:${SHA256} |" updates.xml
+ else
+ # Add SHA-256 after downloadurl
+ sed -i "/<\/downloadurl>/a\ sha256:${SHA256}<\/sha256>" updates.xml
+ fi
+
+ echo "Updated updates.xml with:"
+ echo " Version: ${TAG}"
+ echo " Date: ${DATE}"
+ echo " SHA-256: ${SHA256}"
+
+ - name: Check for changes
+ id: changes
+ run: |
+ if git diff --quiet updates.xml; then
+ echo "has_changes=false" >> $GITHUB_OUTPUT
+ echo "No changes to updates.xml"
+ else
+ echo "has_changes=true" >> $GITHUB_OUTPUT
+ echo "Changes detected in updates.xml"
+ git diff updates.xml
+ fi
+
+ - name: Commit and push changes
+ if: steps.changes.outputs.has_changes == 'true'
+ run: |
+ TAG="${{ steps.tag.outputs.tag }}"
+
+ git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
+ git config --local user.name "gitea-actions[bot]"
+
+ git add updates.xml
+ git commit -m "chore: Update SHA-256 hash for release ${TAG} - SHA: ${{ steps.sha.outputs.sha256 }}"
+
+ git push origin main
+
+ echo "Successfully updated updates.xml with SHA-256 hash for release ${TAG}"
+
+ - name: Summary
+ if: steps.changes.outputs.has_changes == 'true'
+ run: |
+ echo "### SHA-256 Hash Updated Successfully" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "- Release: ${{ steps.tag.outputs.tag }}" >> $GITHUB_STEP_SUMMARY
+ echo "- SHA-256: \`${{ steps.sha.outputs.sha256 }}\`" >> $GITHUB_STEP_SUMMARY
+ echo "- File: updates.xml" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "The Joomla update server will now provide the correct package hash." >> $GITHUB_STEP_SUMMARY
+
+ - name: Summary (no changes)
+ if: steps.changes.outputs.has_changes == 'false'
+ run: |
+ echo "### No Updates Needed" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "updates.xml already contains the correct SHA-256 hash for release ${{ steps.tag.outputs.tag }}" >> $GITHUB_STEP_SUMMARY
diff --git a/.github/workflows/branch-freeze.yml b/.github/workflows/branch-freeze.yml
new file mode 100644
index 0000000..45d7044
--- /dev/null
+++ b/.github/workflows/branch-freeze.yml
@@ -0,0 +1,114 @@
+# Copyright (C) 2026 Moko Consulting
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow
+# INGROUP: MokoStandards.Automation
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /templates/workflows/shared/branch-freeze.yml.template
+# VERSION: 04.06.00
+# BRIEF: Freeze or unfreeze any branch via ruleset — manual workflow_dispatch
+
+name: Branch Freeze
+
+on:
+ workflow_dispatch:
+ inputs:
+ branch:
+ description: 'Branch to freeze/unfreeze (e.g., version/04, dev/feature)'
+ required: true
+ type: string
+ action:
+ description: 'Action to perform'
+ required: true
+ type: choice
+ options:
+ - freeze
+ - unfreeze
+
+env:
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
+
+permissions:
+ contents: read
+
+jobs:
+ manage-freeze:
+ name: "${{ inputs.action }} branch: ${{ inputs.branch }}"
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Check permissions
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ ACTOR="${{ github.actor }}"
+ REPO="${{ github.repository }}"
+ PERMISSION=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/collaborators/${ACTOR}/permission" 2>/dev/null \
+ 2>/dev/null | jq -r '.permission' || echo "read")
+ if [ "$PERMISSION" != "admin" ]; then
+ echo "Denied: only admins can freeze/unfreeze branches (${ACTOR} has ${PERMISSION})"
+ exit 1
+ fi
+
+ - name: "${{ inputs.action }} branch"
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ BRANCH="${{ inputs.branch }}"
+ ACTION="${{ inputs.action }}"
+ REPO="${{ github.repository }}"
+ RULESET_NAME="FROZEN: ${BRANCH}"
+
+ echo "## Branch Freeze" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$ACTION" = "freeze" ]; then
+ # Check if ruleset already exists
+ EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/rulesets" 2>/dev/null \
+ | jq -r ".[] | select(.name == \"${RULESET_NAME}\") | .id" 2>/dev/null || true)
+
+ if [ -n "$EXISTING" ]; then
+ echo "Branch \`${BRANCH}\` is already frozen (ruleset #${EXISTING})" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
+ # Create freeze ruleset — blocks all updates except admin bypass
+ printf '{"name":"%s","target":"branch","enforcement":"active",' "${RULESET_NAME}" > /tmp/ruleset.json
+ printf '"bypass_actors":[{"actor_id":5,"actor_type":"RepositoryRole","bypass_mode":"always"}],' >> /tmp/ruleset.json
+ printf '"conditions":{"ref_name":{"include":["refs/heads/%s"],"exclude":[]}},' "${BRANCH}" >> /tmp/ruleset.json
+ printf '"rules":[{"type":"update"},{"type":"deletion"},{"type":"non_fast_forward"}]}' >> /tmp/ruleset.json
+
+ RESULT=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/rulesets" 2>/dev/null -X POST -d @/tmp/ruleset.json 2>&1 | jq -r '.id') || true
+
+ if echo "$RESULT" | grep -qE '^[0-9]+$'; then
+ echo "Frozen \`${BRANCH}\` — ruleset #${RESULT}" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
+ echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
+ echo "| Branch | \`${BRANCH}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Ruleset | #${RESULT} |" >> $GITHUB_STEP_SUMMARY
+ echo "| Rules | No updates, no deletion, no force push |" >> $GITHUB_STEP_SUMMARY
+ echo "| Bypass | Repository admins only |" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "Failed to freeze: ${RESULT}" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ fi
+
+ elif [ "$ACTION" = "unfreeze" ]; then
+ # Find and delete the freeze ruleset
+ RULESET_ID=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/rulesets" 2>/dev/null \
+ | jq -r ".[] | select(.name == \"${RULESET_NAME}\") | .id" 2>/dev/null || true)
+
+ if [ -z "$RULESET_ID" ]; then
+ echo "Branch \`${BRANCH}\` is not frozen (no ruleset found)" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
+ curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/rulesets/${RULESET_ID}" 2>/dev/null -X DELETE --silent 2>/dev/null
+
+ echo "Unfrozen \`${BRANCH}\` — ruleset #${RULESET_ID} deleted" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ rm -f /tmp/ruleset.json
diff --git a/.github/workflows/changelog-validation.yml b/.github/workflows/changelog-validation.yml
new file mode 100644
index 0000000..c15324b
--- /dev/null
+++ b/.github/workflows/changelog-validation.yml
@@ -0,0 +1,99 @@
+# Copyright (C) 2026 Moko Consulting
+#
+# This file is part of a Moko Consulting project.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow.Template
+# INGROUP: MokoStandards.CI
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /templates/workflows/shared/changelog-validation.yml.template
+# VERSION: 04.06.00
+# BRIEF: Validates CHANGELOG.md format and version consistency
+# NOTE: Deployed to .github/workflows/changelog-validation.yml in governed repos.
+
+name: Changelog Validation
+
+on:
+ pull_request:
+ branches:
+ - main
+ - 'dev/**'
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+env:
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
+
+jobs:
+ validate-changelog:
+ name: Validate CHANGELOG.md
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check CHANGELOG.md exists
+ run: |
+ echo "### Changelog Validation" >> $GITHUB_STEP_SUMMARY
+ if [ ! -f "CHANGELOG.md" ]; then
+ echo "CHANGELOG.md not found in repository root." >> $GITHUB_STEP_SUMMARY
+ exit 1
+ fi
+ echo "CHANGELOG.md exists." >> $GITHUB_STEP_SUMMARY
+
+ - name: Check VERSION header matches README.md
+ run: |
+ # Extract version from README.md FILE INFORMATION block
+ README_VERSION=$(grep -oP '^\s*VERSION:\s*\K[0-9]{2}\.[0-9]{2}\.[0-9]{2}' README.md | head -1)
+ if [ -z "$README_VERSION" ]; then
+ echo "No VERSION found in README.md FILE INFORMATION block." >> $GITHUB_STEP_SUMMARY
+ exit 1
+ fi
+
+ # Check that CHANGELOG.md has a matching version header
+ CHANGELOG_VERSION=$(grep -oP '^\#\#\s*\[\K[0-9]{2}\.[0-9]{2}\.[0-9]{2}' CHANGELOG.md | head -1)
+ if [ -z "$CHANGELOG_VERSION" ]; then
+ echo "No version header found in CHANGELOG.md (expected \`## [XX.YY.ZZ] - YYYY-MM-DD\`)." >> $GITHUB_STEP_SUMMARY
+ exit 1
+ fi
+
+ if [ "$CHANGELOG_VERSION" != "$README_VERSION" ]; then
+ echo "CHANGELOG latest version \`${CHANGELOG_VERSION}\` does not match README VERSION \`${README_VERSION}\`." >> $GITHUB_STEP_SUMMARY
+ exit 1
+ fi
+
+ echo "CHANGELOG version \`${CHANGELOG_VERSION}\` matches README VERSION." >> $GITHUB_STEP_SUMMARY
+
+ - name: Validate conventional changelog format
+ run: |
+ ERRORS=0
+
+ # Check that version entries follow ## [XX.YY.ZZ] - YYYY-MM-DD format
+ while IFS= read -r LINE; do
+ if ! echo "$LINE" | grep -qP '^\#\#\s*\[[0-9]{2}\.[0-9]{2}\.[0-9]{2}\]\s*-\s*[0-9]{4}-[0-9]{2}-[0-9]{2}'; then
+ echo "Malformed version header: \`${LINE}\`" >> $GITHUB_STEP_SUMMARY
+ echo " Expected format: \`## [XX.YY.ZZ] - YYYY-MM-DD\`" >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ fi
+ done < <(grep -P '^\#\#\s*\[' CHANGELOG.md)
+
+ ENTRY_COUNT=$(grep -cP '^\#\#\s*\[' CHANGELOG.md || echo "0")
+ if [ "$ENTRY_COUNT" -eq 0 ]; then
+ echo "No version entries found in CHANGELOG.md." >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ else
+ echo "Found ${ENTRY_COUNT} version entr(ies) in CHANGELOG.md." >> $GITHUB_STEP_SUMMARY
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ if [ "${ERRORS}" -gt 0 ]; then
+ echo "**${ERRORS} format issue(s) found.**" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ else
+ echo "**Changelog format validation passed.**" >> $GITHUB_STEP_SUMMARY
+ fi
diff --git a/.github/workflows/ci-joomla.yml b/.github/workflows/ci-joomla.yml
new file mode 100644
index 0000000..f3394c2
--- /dev/null
+++ b/.github/workflows/ci-joomla.yml
@@ -0,0 +1,376 @@
+# Copyright (C) 2026 Moko Consulting
+#
+# This file is part of a Moko Consulting project.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow.Template
+# INGROUP: MokoStandards.CI
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /templates/workflows/joomla/ci-joomla.yml.template
+# VERSION: 04.06.00
+# BRIEF: CI workflow for Joomla extensions — lint, validate, test
+# NOTE: Deployed to .github/workflows/ci-joomla.yml in governed Joomla extension repos.
+
+name: Joomla Extension CI
+
+on:
+ pull_request:
+ branches:
+ - main
+ - 'dev/**'
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pull-requests: write
+
+env:
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
+
+jobs:
+ lint-and-validate:
+ name: Lint & Validate
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Setup PHP
+ run: |
+ php -v && composer --version
+
+ - name: Clone MokoStandards
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ git clone --depth 1 --branch version/04 --quiet \
+ "https://x-access-token:${GH_TOKEN}@git.mokoconsulting.tech/MokoConsulting/MokoStandards.git" \
+ /tmp/mokostandards
+
+ - name: Install dependencies
+ env:
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GA_TOKEN || github.token }}"}}'
+ run: |
+ if [ -f "composer.json" ]; then
+ composer install \
+ --no-interaction \
+ --prefer-dist \
+ --optimize-autoloader
+ else
+ echo "No composer.json found — skipping dependency install"
+ fi
+
+ - name: PHP syntax check
+ run: |
+ ERRORS=0
+ for DIR in src/ htdocs/; do
+ if [ -d "$DIR" ]; then
+ FOUND=1
+ while IFS= read -r -d '' FILE; do
+ OUTPUT=$(php -l "$FILE" 2>&1)
+ if echo "$OUTPUT" | grep -q "Parse error"; then
+ echo "::error file=${FILE}::${OUTPUT}"
+ ERRORS=$((ERRORS + 1))
+ fi
+ done < <(find "$DIR" -name "*.php" -print0)
+ fi
+ done
+ echo "### PHP Syntax Check" >> $GITHUB_STEP_SUMMARY
+ if [ "${ERRORS}" -gt 0 ]; then
+ echo "**${ERRORS} syntax error(s) found.**" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ else
+ echo "All PHP files passed syntax check." >> $GITHUB_STEP_SUMMARY
+ fi
+
+ - name: XML manifest validation
+ run: |
+ echo "### XML Manifest Validation" >> $GITHUB_STEP_SUMMARY
+ ERRORS=0
+
+ # Find the extension manifest (XML with /dev/null; then
+ MANIFEST="$XML_FILE"
+ break
+ fi
+ done
+
+ if [ -z "$MANIFEST" ]; then
+ echo "No Joomla extension manifest found (XML file with \`> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ else
+ echo "Manifest found: \`${MANIFEST}\`" >> $GITHUB_STEP_SUMMARY
+
+ # Validate well-formed XML
+ php -r "
+ \$xml = @simplexml_load_file('$MANIFEST');
+ if (\$xml === false) {
+ echo 'INVALID';
+ exit(1);
+ }
+ echo 'VALID';
+ " > /tmp/xml_result 2>&1
+ XML_RESULT=$(cat /tmp/xml_result)
+ if [ "$XML_RESULT" != "VALID" ]; then
+ echo "Manifest is not well-formed XML." >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ else
+ echo "Manifest is well-formed XML." >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Check required tags: name, version, author, namespace (Joomla 5+)
+ for TAG in name version author namespace; do
+ if ! grep -q "<${TAG}>" "$MANIFEST" 2>/dev/null; then
+ echo "Missing required tag: \`<${TAG}>\`" >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ else
+ echo "Found required tag: \`<${TAG}>\`" >> $GITHUB_STEP_SUMMARY
+ fi
+ done
+ fi
+
+ if [ "${ERRORS}" -gt 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**${ERRORS} manifest issue(s) found.**" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ else
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Manifest validation passed.**" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ - name: Check language files referenced in manifest
+ run: |
+ echo "### Language File Check" >> $GITHUB_STEP_SUMMARY
+ ERRORS=0
+
+ MANIFEST=""
+ for XML_FILE in $(find . -maxdepth 2 -name "*.xml" -not -path "./.git/*" -not -path "./vendor/*"); do
+ if grep -q "/dev/null; then
+ MANIFEST="$XML_FILE"
+ break
+ fi
+ done
+
+ if [ -n "$MANIFEST" ]; then
+ # Extract language file references from manifest
+ LANG_FILES=$(grep -oP 'language\s+tag="[^"]*"[^>]*>\K[^<]+' "$MANIFEST" 2>/dev/null || true)
+ if [ -z "$LANG_FILES" ]; then
+ echo "No language file references found in manifest — skipping." >> $GITHUB_STEP_SUMMARY
+ else
+ while IFS= read -r LANG_FILE; do
+ LANG_FILE=$(echo "$LANG_FILE" | xargs)
+ if [ -z "$LANG_FILE" ]; then
+ continue
+ fi
+ # Check in common locations
+ FOUND=0
+ for BASE in "." "src" "htdocs"; do
+ if [ -f "${BASE}/${LANG_FILE}" ]; then
+ FOUND=1
+ break
+ fi
+ done
+ if [ "$FOUND" -eq 0 ]; then
+ echo "Missing language file: \`${LANG_FILE}\`" >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ else
+ echo "Language file present: \`${LANG_FILE}\`" >> $GITHUB_STEP_SUMMARY
+ fi
+ done <<< "$LANG_FILES"
+ fi
+ else
+ echo "No manifest found — skipping language check." >> $GITHUB_STEP_SUMMARY
+ fi
+
+ if [ "${ERRORS}" -gt 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**${ERRORS} missing language file(s).**" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ else
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Language file check passed.**" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ - name: Check index.html files in directories
+ run: |
+ echo "### Index.html Check" >> $GITHUB_STEP_SUMMARY
+ MISSING=0
+ CHECKED=0
+
+ for DIR in src/ htdocs/; do
+ if [ -d "$DIR" ]; then
+ while IFS= read -r -d '' SUBDIR; do
+ CHECKED=$((CHECKED + 1))
+ if [ ! -f "${SUBDIR}/index.html" ]; then
+ echo "Missing index.html in: \`${SUBDIR}\`" >> $GITHUB_STEP_SUMMARY
+ MISSING=$((MISSING + 1))
+ fi
+ done < <(find "$DIR" -type d -print0)
+ fi
+ done
+
+ if [ "${CHECKED}" -eq 0 ]; then
+ echo "No src/ or htdocs/ directories found — skipping." >> $GITHUB_STEP_SUMMARY
+ elif [ "${MISSING}" -gt 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**${MISSING} director(ies) missing index.html out of ${CHECKED} checked.**" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ else
+ echo "All ${CHECKED} directories contain index.html." >> $GITHUB_STEP_SUMMARY
+ fi
+
+ release-readiness:
+ name: Release Readiness Check
+ runs-on: ubuntu-latest
+ if: github.event_name == 'pull_request' && github.base_ref == 'main'
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Validate release readiness
+ run: |
+ echo "## Release Readiness" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ ERRORS=0
+
+ # Extract version from README.md
+ README_VERSION=$(grep -oP '^\s*VERSION:\s*\K[0-9]{2}\.[0-9]{2}\.[0-9]{2}' README.md | head -1)
+ if [ -z "$README_VERSION" ]; then
+ echo "No VERSION found in README.md FILE INFORMATION block." >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ else
+ echo "README version: \`${README_VERSION}\`" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Find the extension manifest
+ MANIFEST=""
+ for XML_FILE in $(find . -maxdepth 2 -name "*.xml" -not -path "./.git/*" -not -path "./vendor/*"); do
+ if grep -q "/dev/null; then
+ MANIFEST="$XML_FILE"
+ break
+ fi
+ done
+
+ if [ -z "$MANIFEST" ]; then
+ echo "No Joomla extension manifest found." >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ else
+ echo "Manifest: \`${MANIFEST}\`" >> $GITHUB_STEP_SUMMARY
+
+ # Check matches README VERSION
+ MANIFEST_VERSION=$(grep -oP '\K[^<]+' "$MANIFEST" | head -1)
+ if [ -z "$MANIFEST_VERSION" ]; then
+ echo "No \`\` tag in manifest." >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ elif [ -n "$README_VERSION" ] && [ "$MANIFEST_VERSION" != "$README_VERSION" ]; then
+ echo "Manifest version \`${MANIFEST_VERSION}\` does not match README \`${README_VERSION}\`." >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ else
+ echo "Manifest version: \`${MANIFEST_VERSION}\`" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Check extension type, element, client attributes
+ EXT_TYPE=$(grep -oP ']*\btype="\K[^"]+' "$MANIFEST" | head -1)
+ if [ -z "$EXT_TYPE" ]; then
+ echo "Missing \`type\` attribute on \`\` tag." >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ else
+ echo "Extension type: \`${EXT_TYPE}\`" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Element check (component/module/plugin name)
+ HAS_ELEMENT=$(grep -cP '<(element|name)>' "$MANIFEST" 2>/dev/null || echo "0")
+ if [ "$HAS_ELEMENT" -eq 0 ]; then
+ echo "Missing \`\` or \`\` in manifest." >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ fi
+
+ # Client attribute for site/admin modules and plugins
+ if echo "$EXT_TYPE" | grep -qP "^(module|plugin)$"; then
+ HAS_CLIENT=$(grep -cP ']*\bclient=' "$MANIFEST" 2>/dev/null || echo "0")
+ if [ "$HAS_CLIENT" -eq 0 ]; then
+ echo "Missing \`client\` attribute for ${EXT_TYPE} extension." >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ fi
+ fi
+ fi
+
+ # Check updates.xml exists
+ if [ -f "updates.xml" ] || [ -f "updates.xml" ]; then
+ echo "Update XML present." >> $GITHUB_STEP_SUMMARY
+ else
+ echo "No updates.xml found." >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ fi
+
+ # Check CHANGELOG.md exists
+ if [ -f "CHANGELOG.md" ]; then
+ echo "CHANGELOG.md present." >> $GITHUB_STEP_SUMMARY
+ else
+ echo "No CHANGELOG.md found." >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + 1))
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ if [ $ERRORS -gt 0 ]; then
+ echo "**${ERRORS} issue(s) must be resolved before release.**" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ else
+ echo "**Extension is ready for release.**" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ test:
+ name: Tests (PHP ${{ matrix.php }})
+ runs-on: ubuntu-latest
+ needs: lint-and-validate
+
+ strategy:
+ fail-fast: false
+ matrix:
+ php: ['8.2', '8.3']
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Setup PHP ${{ matrix.php }}
+ run: |
+ php -v && composer --version
+
+ - name: Install dependencies
+ env:
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GA_TOKEN || github.token }}"}}'
+ run: |
+ if [ -f "composer.json" ]; then
+ composer install \
+ --no-interaction \
+ --prefer-dist \
+ --optimize-autoloader
+ else
+ echo "No composer.json found — skipping dependency install"
+ fi
+
+ - name: Run tests
+ run: |
+ echo "### Test Results (PHP ${{ matrix.php }})" >> $GITHUB_STEP_SUMMARY
+ if [ -f "phpunit.xml" ] || [ -f "phpunit.xml.dist" ]; then
+ vendor/bin/phpunit --testdox 2>&1 | tee /tmp/test-output.log
+ EXIT=${PIPESTATUS[0]}
+ if [ $EXIT -eq 0 ]; then
+ echo "All tests passed." >> $GITHUB_STEP_SUMMARY
+ else
+ echo "Test failures detected — see log." >> $GITHUB_STEP_SUMMARY
+ echo '```' >> $GITHUB_STEP_SUMMARY
+ cat /tmp/test-output.log >> $GITHUB_STEP_SUMMARY
+ echo '```' >> $GITHUB_STEP_SUMMARY
+ fi
+ exit $EXIT
+ else
+ echo "No phpunit.xml found — skipping tests." >> $GITHUB_STEP_SUMMARY
+ fi
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 0000000..f40e3e3
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,108 @@
+# Copyright (C) 2026 Moko Consulting
+#
+# This file is part of a Moko Consulting project.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow.Template
+# INGROUP: MokoStandards.Security
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /templates/workflows/generic/codeql-analysis.yml.template
+# VERSION: 03.09.03
+# BRIEF: CodeQL security scanning workflow (generic — all repo types)
+# NOTE: Deployed to .github/workflows/codeql-analysis.yml in governed repos.
+# CodeQL does not support PHP directly; JavaScript scans JSON/YAML/shell.
+# For PHP-specific security scanning see standards-compliance.yml.
+
+name: CodeQL Security Scanning
+
+on:
+ push:
+ branches:
+ - main
+ - version/*
+ schedule:
+ # Weekly on Monday at 06:00 UTC
+ - cron: '0 6 * * 1'
+ workflow_dispatch:
+
+permissions:
+ actions: read
+ contents: read
+ security-events: write
+ pull-requests: read
+
+jobs:
+ analyze:
+ name: Analyze (${{ matrix.language }})
+ runs-on: ubuntu-latest
+ timeout-minutes: 360
+
+ strategy:
+ fail-fast: false
+ matrix:
+ # CodeQL does not support PHP. Use 'javascript' to scan JSON, YAML,
+ # and shell scripts. Add 'actions' to scan GitHub Actions workflows.
+ language: ['javascript', 'actions']
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v3
+ with:
+ languages: ${{ matrix.language }}
+ queries: security-extended,security-and-quality
+
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v3
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v3
+ with:
+ category: "/language:${{ matrix.language }}"
+ upload: true
+ output: sarif-results
+ wait-for-processing: true
+
+ - name: Upload SARIF results
+ if: always()
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.5.0
+ with:
+ name: codeql-results-${{ matrix.language }}
+ path: sarif-results
+ retention-days: 30
+
+ - name: Step summary
+ if: always()
+ run: |
+ echo "### 🔍 CodeQL — ${{ matrix.language }}" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ URL="https://github.com/${{ github.repository }}/security/code-scanning"
+ echo "See the [Security tab]($URL) for findings." >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| Severity | SLA |" >> $GITHUB_STEP_SUMMARY
+ echo "|----------|-----|" >> $GITHUB_STEP_SUMMARY
+ echo "| Critical | 7 days |" >> $GITHUB_STEP_SUMMARY
+ echo "| High | 14 days |" >> $GITHUB_STEP_SUMMARY
+ echo "| Medium | 30 days |" >> $GITHUB_STEP_SUMMARY
+ echo "| Low | 60 days / next release |" >> $GITHUB_STEP_SUMMARY
+
+ summary:
+ name: Security Scan Summary
+ runs-on: ubuntu-latest
+ needs: analyze
+ if: always()
+
+ steps:
+ - name: Summary
+ run: |
+ echo "### 🛡️ CodeQL Complete" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Trigger:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
+ echo "**Branch:** ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
+ SECURITY_URL="https://github.com/${{ github.repository }}/security"
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "📊 [View all security alerts]($SECURITY_URL)" >> $GITHUB_STEP_SUMMARY
diff --git a/.github/workflows/deploy-manual.yml b/.github/workflows/deploy-manual.yml
new file mode 100644
index 0000000..9d39ca1
--- /dev/null
+++ b/.github/workflows/deploy-manual.yml
@@ -0,0 +1,128 @@
+# Copyright (C) 2026 Moko Consulting
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow
+# INGROUP: MokoStandards.Deploy
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /templates/workflows/joomla/deploy-manual.yml.template
+# VERSION: 04.06.00
+# BRIEF: Manual SFTP deploy to dev server for Joomla repos
+# NOTE: Joomla repos use update.xml for distribution. This is for manual
+# dev server testing only — triggered via workflow_dispatch.
+
+name: Deploy to Dev (Manual)
+
+on:
+ workflow_dispatch:
+ inputs:
+ clear_remote:
+ description: 'Delete all remote files before uploading'
+ required: false
+ default: 'false'
+ type: boolean
+
+env:
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
+
+permissions:
+ contents: read
+
+jobs:
+ deploy:
+ name: SFTP Deploy to Dev
+ runs-on: release
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Setup PHP
+ run: |
+ php -v && composer --version
+
+ - name: Setup MokoStandards tools
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GA_TOKEN || github.token }}"}}'
+ run: |
+ git clone --depth 1 --branch version/04 --quiet \
+ "https://x-access-token:${GH_TOKEN}@git.mokoconsulting.tech/MokoConsulting/MokoStandards.git" \
+ /tmp/mokostandards 2>/dev/null || true
+ if [ -d "/tmp/mokostandards" ] && [ -f "/tmp/mokostandards/composer.json" ]; then
+ cd /tmp/mokostandards && composer install --no-dev --no-interaction --quiet 2>/dev/null || true
+ fi
+
+ - name: Check FTP configuration
+ id: check
+ env:
+ HOST: ${{ vars.DEV_FTP_HOST }}
+ PATH_VAR: ${{ vars.DEV_FTP_PATH }}
+ SUFFIX: ${{ vars.DEV_FTP_SUFFIX }}
+ PORT: ${{ vars.DEV_FTP_PORT }}
+ run: |
+ if [ -z "$HOST" ] || [ -z "$PATH_VAR" ]; then
+ echo "DEV_FTP_HOST or DEV_FTP_PATH not configured — cannot deploy"
+ echo "skip=true" >> "$GITHUB_OUTPUT"
+ exit 0
+ fi
+ echo "skip=false" >> "$GITHUB_OUTPUT"
+ echo "host=$HOST" >> "$GITHUB_OUTPUT"
+
+ REMOTE="${PATH_VAR%/}"
+ [ -n "$SUFFIX" ] && REMOTE="${REMOTE}/${SUFFIX#/}"
+ echo "remote=$REMOTE" >> "$GITHUB_OUTPUT"
+
+ [ -z "$PORT" ] && PORT="22"
+ echo "port=$PORT" >> "$GITHUB_OUTPUT"
+
+ - name: Deploy via SFTP
+ if: steps.check.outputs.skip != 'true'
+ env:
+ SFTP_KEY: ${{ secrets.DEV_FTP_KEY }}
+ SFTP_PASS: ${{ secrets.DEV_FTP_PASSWORD }}
+ SFTP_USER: ${{ vars.DEV_FTP_USERNAME }}
+ run: |
+ SOURCE_DIR="src"
+ [ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs"
+ [ ! -d "$SOURCE_DIR" ] && { echo "No src/ or htdocs/ — nothing to deploy"; exit 0; }
+
+ printf '{"host":"%s","port":%s,"username":"%s","remotePath":"%s"' \
+ "${{ steps.check.outputs.host }}" "${{ steps.check.outputs.port }}" "$SFTP_USER" "${{ steps.check.outputs.remote }}" \
+ > /tmp/sftp-config.json
+
+ if [ -n "$SFTP_KEY" ]; then
+ echo "$SFTP_KEY" > /tmp/deploy_key
+ chmod 600 /tmp/deploy_key
+ printf ',"privateKeyPath":"/tmp/deploy_key"}' >> /tmp/sftp-config.json
+ else
+ printf ',"password":"%s"}' "$SFTP_PASS" >> /tmp/sftp-config.json
+ fi
+
+ DEPLOY_ARGS=(--path . --src-dir "$SOURCE_DIR" --config /tmp/sftp-config.json)
+ [ "${{ inputs.clear_remote }}" = "true" ] && DEPLOY_ARGS+=(--clear-remote)
+
+ PLATFORM=$(php /tmp/mokostandards/api/cli/platform_detect.php --path . 2>/dev/null || true)
+ if [ "$PLATFORM" = "waas-component" ] && [ -f "/tmp/mokostandards/api/deploy/deploy-joomla.php" ]; then
+ php /tmp/mokostandards/api/deploy/deploy-joomla.php "${DEPLOY_ARGS[@]}"
+ else
+ php /tmp/mokostandards/api/deploy/deploy-sftp.php "${DEPLOY_ARGS[@]}"
+ fi
+
+ rm -f /tmp/deploy_key /tmp/sftp-config.json
+
+ - name: Summary
+ if: always()
+ run: |
+ if [ "${{ steps.check.outputs.skip }}" = "true" ]; then
+ echo "### Deploy Skipped — FTP not configured" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "### Manual Dev Deploy Complete" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
+ echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
+ echo "| Host | \`${{ steps.check.outputs.host }}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Remote | \`${{ steps.check.outputs.remote }}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Clear | ${{ inputs.clear_remote }} |" >> $GITHUB_STEP_SUMMARY
+ fi
diff --git a/.github/workflows/enterprise-firewall-setup.yml b/.github/workflows/enterprise-firewall-setup.yml
new file mode 100644
index 0000000..550787b
--- /dev/null
+++ b/.github/workflows/enterprise-firewall-setup.yml
@@ -0,0 +1,758 @@
+# Copyright (C) 2026 Moko Consulting
+#
+# This file is part of a Moko Consulting project.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow
+# INGROUP: MokoStandards.Firewall
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /templates/workflows/shared/enterprise-firewall-setup.yml.template
+# VERSION: 04.06.00
+# BRIEF: Enterprise firewall configuration — generates outbound allow-rules including SFTP deployment server
+# NOTE: Reads DEV_FTP_HOST / DEV_FTP_PORT variables to include SFTP egress rules alongside HTTPS rules.
+
+name: Enterprise Firewall Configuration
+
+# This workflow provides firewall configuration guidance for enterprise-ready sites
+# It generates firewall rules for allowing outbound access to trusted domains
+# including license providers, documentation sources, package registries,
+# and the SFTP deployment server (DEV_FTP_HOST / DEV_FTP_PORT).
+#
+# Runs automatically when:
+# - Coding agent workflows are triggered (pull requests with copilot/ prefix)
+# - Manual workflow dispatch for custom configurations
+
+on:
+ workflow_dispatch:
+ inputs:
+ firewall_type:
+ description: 'Target firewall type'
+ required: true
+ type: choice
+ options:
+ - 'iptables'
+ - 'ufw'
+ - 'firewalld'
+ - 'aws-security-group'
+ - 'azure-nsg'
+ - 'gcp-firewall'
+ - 'cloudflare'
+ - 'all'
+ default: 'all'
+ output_format:
+ description: 'Output format'
+ required: true
+ type: choice
+ options:
+ - 'shell-script'
+ - 'json'
+ - 'yaml'
+ - 'markdown'
+ - 'all'
+ default: 'markdown'
+
+ # Auto-run when coding agent creates or updates PRs
+ pull_request:
+ branches:
+ - 'copilot/**'
+ - 'agent/**'
+ types: [opened, synchronize, reopened]
+
+ # Auto-run on push to coding agent branches
+ push:
+ branches:
+ - 'copilot/**'
+ - 'agent/**'
+
+permissions:
+ contents: read
+ actions: read
+
+jobs:
+ generate-firewall-rules:
+ name: Generate Firewall Rules
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Set up Python
+ uses: actions/setup-python@v6
+ with:
+ python-version: '3.11'
+
+ - name: Apply Firewall Rules to Runner (Auto-run only)
+ if: github.event_name != 'workflow_dispatch'
+ env:
+ DEV_FTP_HOST: ${{ vars.DEV_FTP_HOST }}
+ DEV_FTP_PORT: ${{ vars.DEV_FTP_PORT }}
+ run: |
+ echo "🔥 Applying firewall rules for coding agent environment..."
+ echo ""
+ echo "This step ensures the GitHub Actions runner can access trusted domains"
+ echo "including license providers, package registries, and documentation sources."
+ echo ""
+
+ # Note: GitHub Actions runners are ephemeral and run in controlled environments
+ # This step documents what domains are being accessed during the workflow
+ # Actual firewall configuration is managed by GitHub
+
+ cat > /tmp/trusted-domains.txt << 'EOF'
+ # Trusted domains for coding agent environment
+ # License Providers
+ www.gnu.org
+ opensource.org
+ choosealicense.com
+ spdx.org
+ creativecommons.org
+ apache.org
+ fsf.org
+
+ # Documentation & Standards
+ semver.org
+ keepachangelog.com
+ conventionalcommits.org
+
+ # GitHub & Related
+ github.com
+ api.github.com
+ docs.github.com
+ raw.githubusercontent.com
+ ghcr.io
+
+ # Package Registries
+ npmjs.com
+ registry.npmjs.org
+ pypi.org
+ files.pythonhosted.org
+ packagist.org
+ repo.packagist.org
+ rubygems.org
+
+ # Platform-Specific
+ joomla.org
+ downloads.joomla.org
+ docs.joomla.org
+ php.net
+ getcomposer.org
+ dolibarr.org
+ wiki.dolibarr.org
+ docs.dolibarr.org
+
+ # Moko Consulting
+ mokoconsulting.tech
+
+ # SFTP Deployment Server (DEV_FTP_HOST)
+ ${DEV_FTP_HOST:-}
+
+ # Google Services
+ drive.google.com
+ docs.google.com
+ sheets.google.com
+ accounts.google.com
+ storage.googleapis.com
+ fonts.googleapis.com
+ fonts.gstatic.com
+
+ # GitHub Extended
+ upload.github.com
+ objects.githubusercontent.com
+ user-images.githubusercontent.com
+ codeload.github.com
+ pkg.github.com
+
+ # Developer Reference
+ developer.mozilla.org
+ stackoverflow.com
+ git-scm.com
+
+ # CDN & Infrastructure
+ cdn.jsdelivr.net
+ unpkg.com
+ cdnjs.cloudflare.com
+ img.shields.io
+
+ # Container Registries
+ hub.docker.com
+ registry-1.docker.io
+
+ # CI & Code Quality
+ codecov.io
+ sonarcloud.io
+
+ # Terraform & Infrastructure
+ registry.terraform.io
+ releases.hashicorp.com
+ checkpoint-api.hashicorp.com
+ EOF
+
+ echo "✓ Trusted domains documented for this runner"
+ echo "✓ GitHub Actions runners have network access to these domains"
+ echo ""
+
+ # Test connectivity to key domains
+ echo "Testing connectivity to key domains..."
+ for domain in "github.com" "www.gnu.org" "npmjs.com" "pypi.org"; do
+ if curl -s --max-time 3 -o /dev/null -w "%{http_code}" "https://$domain" | grep -q "200\|301\|302"; then
+ echo " ✓ $domain is accessible"
+ else
+ echo " ⚠️ $domain connectivity check failed (may be expected)"
+ fi
+ done
+
+ # Test SFTP server connectivity (TCP port check)
+ SFTP_HOST="${DEV_FTP_HOST:-}"
+ SFTP_PORT="${DEV_FTP_PORT:-22}"
+ if [ -n "$SFTP_HOST" ]; then
+ # Strip any embedded :port suffix
+ SFTP_HOST="${SFTP_HOST%%:*}"
+ echo ""
+ echo "Testing SFTP deployment server connectivity..."
+ if timeout 5 bash -c "echo >/dev/tcp/${SFTP_HOST}/${SFTP_PORT}" 2>/dev/null; then
+ echo " ✓ SFTP server ${SFTP_HOST}:${SFTP_PORT} is reachable"
+ else
+ echo " ⚠️ SFTP server ${SFTP_HOST}:${SFTP_PORT} is not reachable from runner (firewall rule needed)"
+ fi
+ else
+ echo ""
+ echo " ℹ️ DEV_FTP_HOST not configured — skipping SFTP connectivity check"
+ fi
+
+ - name: Generate Firewall Configuration
+ id: generate
+ env:
+ DEV_FTP_HOST: ${{ vars.DEV_FTP_HOST }}
+ DEV_FTP_PORT: ${{ vars.DEV_FTP_PORT }}
+ run: |
+ cat > generate_firewall_config.py << 'PYTHON_EOF'
+ #!/usr/bin/env python3
+ """
+ Enterprise Firewall Configuration Generator
+
+ Generates firewall rules for enterprise-ready deployments allowing
+ access to trusted domains including license providers, documentation
+ sources, package registries, and platform-specific sites.
+ """
+
+ import json
+ import os
+ import yaml
+ import sys
+ from typing import List, Dict
+
+ # SFTP deployment server from org variables
+ _sftp_host_raw = os.environ.get("DEV_FTP_HOST", "").strip()
+ _sftp_port = os.environ.get("DEV_FTP_PORT", "").strip() or "22"
+ # Strip embedded :port suffix if present
+ _sftp_host = _sftp_host_raw.split(":")[0] if _sftp_host_raw else ""
+ if ":" in _sftp_host_raw and not _sftp_port:
+ _sftp_port = _sftp_host_raw.split(":")[1]
+
+ SFTP_HOST = _sftp_host
+ SFTP_PORT = int(_sftp_port) if _sftp_port.isdigit() else 22
+
+ # Trusted domains from .github/copilot.yml
+ TRUSTED_DOMAINS = {
+ "license_providers": [
+ "www.gnu.org",
+ "opensource.org",
+ "choosealicense.com",
+ "spdx.org",
+ "creativecommons.org",
+ "apache.org",
+ "fsf.org",
+ ],
+ "documentation_standards": [
+ "semver.org",
+ "keepachangelog.com",
+ "conventionalcommits.org",
+ ],
+ "github_related": [
+ "github.com",
+ "api.github.com",
+ "docs.github.com",
+ "raw.githubusercontent.com",
+ "ghcr.io",
+ ],
+ "package_registries": [
+ "npmjs.com",
+ "registry.npmjs.org",
+ "pypi.org",
+ "files.pythonhosted.org",
+ "packagist.org",
+ "repo.packagist.org",
+ "rubygems.org",
+ ],
+ "standards_organizations": [
+ "json-schema.org",
+ "w3.org",
+ "ietf.org",
+ ],
+ "platform_specific": [
+ "joomla.org",
+ "downloads.joomla.org",
+ "docs.joomla.org",
+ "php.net",
+ "getcomposer.org",
+ "dolibarr.org",
+ "wiki.dolibarr.org",
+ "docs.dolibarr.org",
+ ],
+ "moko_consulting": [
+ "mokoconsulting.tech",
+ ],
+ "google_services": [
+ "drive.google.com",
+ "docs.google.com",
+ "sheets.google.com",
+ "accounts.google.com",
+ "storage.googleapis.com",
+ "fonts.googleapis.com",
+ "fonts.gstatic.com",
+ ],
+ "github_extended": [
+ "upload.github.com",
+ "objects.githubusercontent.com",
+ "user-images.githubusercontent.com",
+ "codeload.github.com",
+ "pkg.github.com",
+ ],
+ "developer_reference": [
+ "developer.mozilla.org",
+ "stackoverflow.com",
+ "git-scm.com",
+ ],
+ "cdn_and_infrastructure": [
+ "cdn.jsdelivr.net",
+ "unpkg.com",
+ "cdnjs.cloudflare.com",
+ "img.shields.io",
+ ],
+ "container_registries": [
+ "hub.docker.com",
+ "registry-1.docker.io",
+ ],
+ "ci_code_quality": [
+ "codecov.io",
+ "sonarcloud.io",
+ ],
+ "terraform_infrastructure": [
+ "registry.terraform.io",
+ "releases.hashicorp.com",
+ "checkpoint-api.hashicorp.com",
+ ],
+ }
+
+ # Inject SFTP deployment server as a separate category (port 22, not 443)
+ if SFTP_HOST:
+ TRUSTED_DOMAINS["sftp_deployment_server"] = [SFTP_HOST]
+ print(f"ℹ️ SFTP deployment server: {SFTP_HOST}:{SFTP_PORT}")
+
+ def generate_sftp_iptables_rules(host: str, port: int) -> str:
+ """Generate iptables rules specifically for SFTP egress"""
+ return (
+ f"# Allow SFTP to deployment server {host}:{port}\n"
+ f"iptables -A OUTPUT -p tcp -d $(dig +short {host} | head -1)"
+ f" --dport {port} -j ACCEPT # SFTP deploy\n"
+ )
+
+ def generate_sftp_ufw_rules(host: str, port: int) -> str:
+ """Generate UFW rules for SFTP egress"""
+ return (
+ f"# Allow SFTP to deployment server\n"
+ f"ufw allow out to $(dig +short {host} | head -1)"
+ f" port {port} proto tcp comment 'SFTP deploy to {host}'\n"
+ )
+
+ def generate_sftp_firewalld_rules(host: str, port: int) -> str:
+ """Generate firewalld rules for SFTP egress"""
+ return (
+ f"# Allow SFTP to deployment server\n"
+ f"firewall-cmd --permanent --add-rich-rule='"
+ f"rule family=ipv4 destination address=$(dig +short {host} | head -1)"
+ f" port port={port} protocol=tcp accept' # SFTP deploy\n"
+ )
+
+ def generate_iptables_rules(domains: List[str]) -> str:
+ """Generate iptables firewall rules"""
+ rules = ["#!/bin/bash", "", "# Enterprise Firewall Rules - iptables", ""]
+ rules.append("# Allow outbound HTTPS to trusted domains")
+ rules.append("")
+
+ for domain in domains:
+ rules.append(f"# Allow {domain}")
+ rules.append(f"iptables -A OUTPUT -p tcp -d $(dig +short {domain} | head -1) --dport 443 -j ACCEPT")
+
+ rules.append("")
+ rules.append("# Allow DNS lookups")
+ rules.append("iptables -A OUTPUT -p udp --dport 53 -j ACCEPT")
+ rules.append("iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT")
+
+ return "\n".join(rules)
+
+ def generate_ufw_rules(domains: List[str]) -> str:
+ """Generate UFW firewall rules"""
+ rules = ["#!/bin/bash", "", "# Enterprise Firewall Rules - UFW", ""]
+ rules.append("# Allow outbound HTTPS to trusted domains")
+ rules.append("")
+
+ for domain in domains:
+ rules.append(f"# Allow {domain}")
+ rules.append(f"ufw allow out to $(dig +short {domain} | head -1) port 443 proto tcp comment 'Allow {domain}'")
+
+ rules.append("")
+ rules.append("# Allow DNS")
+ rules.append("ufw allow out 53/udp comment 'Allow DNS UDP'")
+ rules.append("ufw allow out 53/tcp comment 'Allow DNS TCP'")
+
+ return "\n".join(rules)
+
+ def generate_firewalld_rules(domains: List[str]) -> str:
+ """Generate firewalld rules"""
+ rules = ["#!/bin/bash", "", "# Enterprise Firewall Rules - firewalld", ""]
+ rules.append("# Add trusted domains to firewall")
+ rules.append("")
+
+ for domain in domains:
+ rules.append(f"# Allow {domain}")
+ rules.append(f"firewall-cmd --permanent --add-rich-rule='rule family=ipv4 destination address=$(dig +short {domain} | head -1) port port=443 protocol=tcp accept'")
+
+ rules.append("")
+ rules.append("# Reload firewall")
+ rules.append("firewall-cmd --reload")
+
+ return "\n".join(rules)
+
+ def generate_aws_security_group(domains: List[str]) -> Dict:
+ """Generate AWS Security Group rules (JSON format)"""
+ rules = {
+ "SecurityGroupRules": {
+ "Egress": []
+ }
+ }
+
+ for domain in domains:
+ rules["SecurityGroupRules"]["Egress"].append({
+ "Description": f"Allow HTTPS to {domain}",
+ "IpProtocol": "tcp",
+ "FromPort": 443,
+ "ToPort": 443,
+ "CidrIp": "0.0.0.0/0", # In practice, resolve to specific IPs
+ "Tags": [{
+ "Key": "Domain",
+ "Value": domain
+ }]
+ })
+
+ # Add DNS
+ rules["SecurityGroupRules"]["Egress"].append({
+ "Description": "Allow DNS",
+ "IpProtocol": "udp",
+ "FromPort": 53,
+ "ToPort": 53,
+ "CidrIp": "0.0.0.0/0"
+ })
+
+ return rules
+
+ def generate_markdown_documentation(domains_by_category: Dict[str, List[str]]) -> str:
+ """Generate markdown documentation"""
+ md = ["# Enterprise Firewall Configuration Guide", ""]
+ md.append("## Overview")
+ md.append("")
+ md.append("This document provides firewall configuration guidance for enterprise-ready deployments.")
+ md.append("It lists trusted domains that should be whitelisted for outbound access to ensure")
+ md.append("proper functionality of license validation, package management, and documentation access.")
+ md.append("")
+
+ md.append("## Trusted Domains by Category")
+ md.append("")
+
+ all_domains = []
+ for category, domains in domains_by_category.items():
+ category_name = category.replace("_", " ").title()
+ md.append(f"### {category_name}")
+ md.append("")
+ md.append("| Domain | Purpose |")
+ md.append("|--------|---------|")
+
+ for domain in domains:
+ all_domains.append(domain)
+ purpose = get_domain_purpose(domain)
+ md.append(f"| `{domain}` | {purpose} |")
+
+ md.append("")
+
+ md.append("## Implementation Examples")
+ md.append("")
+
+ md.append("### iptables Example")
+ md.append("")
+ md.append("```bash")
+ md.append("# Allow HTTPS to trusted domain")
+ md.append(f"iptables -A OUTPUT -p tcp -d $(dig +short {all_domains[0]}) --dport 443 -j ACCEPT")
+ md.append("```")
+ md.append("")
+
+ md.append("### UFW Example")
+ md.append("")
+ md.append("```bash")
+ md.append("# Allow HTTPS to trusted domain")
+ md.append(f"ufw allow out to {all_domains[0]} port 443 proto tcp")
+ md.append("```")
+ md.append("")
+
+ md.append("### AWS Security Group Example")
+ md.append("")
+ md.append("```json")
+ md.append("{")
+ md.append(' "IpPermissions": [{')
+ md.append(' "IpProtocol": "tcp",')
+ md.append(' "FromPort": 443,')
+ md.append(' "ToPort": 443,')
+ md.append(' "IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "HTTPS to trusted domains"}]')
+ md.append(" }]")
+ md.append("}")
+ md.append("```")
+ md.append("")
+
+ md.append("## Ports Required")
+ md.append("")
+ md.append("| Port | Protocol | Purpose |")
+ md.append("|------|----------|---------|")
+ md.append("| 443 | TCP | HTTPS (secure web access) |")
+ md.append("| 80 | TCP | HTTP (redirects to HTTPS) |")
+ md.append("| 53 | UDP/TCP | DNS resolution |")
+ md.append("")
+
+ md.append("## Security Considerations")
+ md.append("")
+ md.append("1. **DNS Resolution**: Ensure DNS queries are allowed (port 53 UDP/TCP)")
+ md.append("2. **Certificate Validation**: HTTPS requires ability to reach certificate authorities")
+ md.append("3. **Dynamic IPs**: Some domains use CDNs with dynamic IPs - consider using FQDNs in rules")
+ md.append("4. **Regular Updates**: Review and update whitelist as services change")
+ md.append("5. **Logging**: Enable logging for blocked connections to identify missing rules")
+ md.append("")
+
+ md.append("## Compliance Notes")
+ md.append("")
+ md.append("- All listed domains provide read-only access to public information")
+ md.append("- License providers enable GPL compliance verification")
+ md.append("- Package registries support dependency security scanning")
+ md.append("- No authentication credentials are transmitted to these domains")
+ md.append("")
+
+ return "\n".join(md)
+
+ def get_domain_purpose(domain: str) -> str:
+ """Get human-readable purpose for a domain"""
+ purposes = {
+ "www.gnu.org": "GNU licenses and documentation",
+ "opensource.org": "Open Source Initiative resources",
+ "choosealicense.com": "GitHub license selection tool",
+ "spdx.org": "Software Package Data Exchange identifiers",
+ "creativecommons.org": "Creative Commons licenses",
+ "apache.org": "Apache Software Foundation licenses",
+ "fsf.org": "Free Software Foundation resources",
+ "semver.org": "Semantic versioning specification",
+ "keepachangelog.com": "Changelog format standards",
+ "conventionalcommits.org": "Commit message conventions",
+ "github.com": "GitHub platform access",
+ "api.github.com": "GitHub API access",
+ "docs.github.com": "GitHub documentation",
+ "raw.githubusercontent.com": "GitHub raw content access",
+ "npmjs.com": "npm package registry",
+ "pypi.org": "Python Package Index",
+ "packagist.org": "PHP Composer package registry",
+ "rubygems.org": "Ruby gems registry",
+ "joomla.org": "Joomla CMS platform",
+ "php.net": "PHP documentation and downloads",
+ "dolibarr.org": "Dolibarr ERP/CRM platform",
+ }
+ return purposes.get(domain, "Trusted resource")
+
+ def main():
+ # Use inputs if provided (manual dispatch), otherwise use defaults (auto-run)
+ firewall_type = "${{ github.event.inputs.firewall_type }}" or "all"
+ output_format = "${{ github.event.inputs.output_format }}" or "markdown"
+
+ print(f"Running in {'manual' if '${{ github.event.inputs.firewall_type }}' else 'automatic'} mode")
+ print(f"Firewall type: {firewall_type}")
+ print(f"Output format: {output_format}")
+ print("")
+
+ # Collect all domains
+ all_domains = []
+ for domains in TRUSTED_DOMAINS.values():
+ all_domains.extend(domains)
+
+ # Remove duplicates and sort
+ all_domains = sorted(set(all_domains))
+
+ print(f"Generating firewall rules for {len(all_domains)} trusted domains...")
+ print("")
+
+ # Exclude SFTP server from HTTPS rule generation (different port)
+ https_domains = [d for d in all_domains if d != SFTP_HOST]
+
+ # Generate based on firewall type
+ if firewall_type in ["iptables", "all"]:
+ rules = generate_iptables_rules(https_domains)
+ if SFTP_HOST:
+ rules += "\n# ── SFTP Deployment Server ──────────────────────────────\n"
+ rules += generate_sftp_iptables_rules(SFTP_HOST, SFTP_PORT)
+ with open("firewall-rules-iptables.sh", "w") as f:
+ f.write(rules)
+ print("✓ Generated iptables rules: firewall-rules-iptables.sh")
+
+ if firewall_type in ["ufw", "all"]:
+ rules = generate_ufw_rules(https_domains)
+ if SFTP_HOST:
+ rules += "\n# ── SFTP Deployment Server ──────────────────────────────\n"
+ rules += generate_sftp_ufw_rules(SFTP_HOST, SFTP_PORT)
+ with open("firewall-rules-ufw.sh", "w") as f:
+ f.write(rules)
+ print("✓ Generated UFW rules: firewall-rules-ufw.sh")
+
+ if firewall_type in ["firewalld", "all"]:
+ rules = generate_firewalld_rules(https_domains)
+ if SFTP_HOST:
+ rules += "\n# ── SFTP Deployment Server ──────────────────────────────\n"
+ rules += generate_sftp_firewalld_rules(SFTP_HOST, SFTP_PORT)
+ with open("firewall-rules-firewalld.sh", "w") as f:
+ f.write(rules)
+ print("✓ Generated firewalld rules: firewall-rules-firewalld.sh")
+
+ if firewall_type in ["aws-security-group", "all"]:
+ rules = generate_aws_security_group(all_domains)
+ with open("firewall-rules-aws-sg.json", "w") as f:
+ json.dump(rules, f, indent=2)
+ print("✓ Generated AWS Security Group rules: firewall-rules-aws-sg.json")
+
+ if output_format in ["yaml", "all"]:
+ with open("trusted-domains.yml", "w") as f:
+ yaml.dump(TRUSTED_DOMAINS, f, default_flow_style=False)
+ print("✓ Generated YAML domain list: trusted-domains.yml")
+
+ if output_format in ["json", "all"]:
+ with open("trusted-domains.json", "w") as f:
+ json.dump(TRUSTED_DOMAINS, f, indent=2)
+ print("✓ Generated JSON domain list: trusted-domains.json")
+
+ if output_format in ["markdown", "all"]:
+ md = generate_markdown_documentation(TRUSTED_DOMAINS)
+ with open("FIREWALL_CONFIGURATION.md", "w") as f:
+ f.write(md)
+ print("✓ Generated documentation: FIREWALL_CONFIGURATION.md")
+
+ print("")
+ print("Domain Categories:")
+ for category, domains in TRUSTED_DOMAINS.items():
+ print(f" - {category}: {len(domains)} domains")
+
+ print("")
+ print("Total unique domains: ", len(all_domains))
+
+ if __name__ == "__main__":
+ main()
+ PYTHON_EOF
+
+ chmod +x generate_firewall_config.py
+ pip install PyYAML
+ python3 generate_firewall_config.py
+
+ - name: Upload Firewall Configuration Artifacts
+ uses: actions/upload-artifact@v6
+ with:
+ name: firewall-configurations
+ path: |
+ firewall-rules-*.sh
+ firewall-rules-*.json
+ trusted-domains.*
+ FIREWALL_CONFIGURATION.md
+ retention-days: 90
+
+ - name: Display Summary
+ run: |
+ echo "## Firewall Configuration" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
+ echo "**Mode**: Manual Execution" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "Firewall rules have been generated for enterprise-ready deployments." >> $GITHUB_STEP_SUMMARY
+ else
+ echo "**Mode**: Automatic Execution (Coding Agent Active)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "This workflow ran automatically because a coding agent (GitHub Copilot) is active." >> $GITHUB_STEP_SUMMARY
+ echo "Firewall configuration has been validated for the coding agent environment." >> $GITHUB_STEP_SUMMARY
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### Files Generated" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ if ls firewall-rules-* trusted-domains.* FIREWALL_CONFIGURATION.md 2>/dev/null; then
+ ls -lh firewall-rules-* trusted-domains.* FIREWALL_CONFIGURATION.md 2>/dev/null | awk '{print "- " $9 " (" $5 ")"}' >> $GITHUB_STEP_SUMMARY
+ else
+ echo "- Documentation generated" >> $GITHUB_STEP_SUMMARY
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
+ echo "### Download Artifacts" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "Download the generated firewall configurations from the workflow artifacts." >> $GITHUB_STEP_SUMMARY
+ else
+ echo "### Trusted Domains Active" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "The coding agent has access to:" >> $GITHUB_STEP_SUMMARY
+ echo "- License providers (GPL, OSI, SPDX, Apache, etc.)" >> $GITHUB_STEP_SUMMARY
+ echo "- Package registries (npm, PyPI, Packagist, RubyGems)" >> $GITHUB_STEP_SUMMARY
+ echo "- Documentation sources (GitHub, Joomla, Dolibarr, PHP)" >> $GITHUB_STEP_SUMMARY
+ echo "- Standards organizations (W3C, IETF, JSON Schema)" >> $GITHUB_STEP_SUMMARY
+ fi
+
+# Usage Instructions:
+#
+# This workflow runs in two modes:
+#
+# 1. AUTOMATIC MODE (Coding Agent):
+# - Triggers when coding agent branches (copilot/**, agent/**) are pushed or PR'd
+# - Validates firewall configuration for the coding agent environment
+# - Documents accessible domains for compliance
+# - Ensures license sources and package registries are available
+#
+# 2. MANUAL MODE (Enterprise Configuration):
+# - Manually trigger from the Actions tab
+# - Select desired firewall type and output format
+# - Download generated artifacts
+# - Apply firewall rules to your enterprise environment
+#
+# Configuration:
+# - Trusted domains are sourced from .github/copilot.yml
+# - Modify copilot.yml to add/remove trusted domains
+# - Changes automatically propagate to firewall rules
+#
+# Important Notes:
+# - Review generated rules before applying to production
+# - Some domains may use CDNs with dynamic IPs
+# - Consider using FQDN-based rules where supported
+# - Test thoroughly in staging environment first
+# - Monitor logs for blocked connections
+# - Update rules as domains/services change
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..a11943e
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,446 @@
+# Copyright (C) 2026 Moko Consulting
+#
+# This file is part of a Moko Consulting project.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow
+# INGROUP: MokoOnyx.Release
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
+# PATH: /.github/workflows/release.yml
+# VERSION: 03.09.16
+# BRIEF: Joomla release — build ZIP, publish to Gitea, mirror to GitHub
+
+name: Create Release
+
+on:
+ push:
+ tags:
+ - '[0-9][0-9].[0-9][0-9].[0-9][0-9]'
+ workflow_dispatch:
+ inputs:
+ version:
+ description: 'Release version (e.g., 03.09.16)'
+ required: true
+ type: string
+ prerelease:
+ description: 'Mark as pre-release'
+ required: false
+ type: boolean
+ default: false
+ stability:
+ description: 'Stability tag (development, alpha, beta, rc, stable)'
+ required: false
+ type: string
+ default: 'development'
+
+permissions:
+ contents: write
+
+env:
+ GITEA_URL: https://git.mokoconsulting.tech
+ GITEA_ORG: MokoConsulting
+ GITEA_REPO: MokoOnyx
+ EXT_ELEMENT: mokoonyx
+
+jobs:
+ build:
+ name: Build Release Package
+ runs-on: release
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Setup PHP
+ run: |
+ sudo apt-get update -qq
+ sudo apt-get install -y -qq php-cli php-mbstring php-xml php-zip php-curl composer >/dev/null 2>&1
+ php -v
+ composer --version
+
+ - name: Get version and stability
+ id: meta
+ run: |
+ if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
+ VERSION="${{ inputs.version }}"
+ STABILITY="${{ inputs.stability }}"
+ PRERELEASE="${{ inputs.prerelease }}"
+ else
+ VERSION=${GITHUB_REF#refs/tags/}
+ STABILITY="stable"
+ PRERELEASE="false"
+ fi
+
+ # Derive suffix and tag from stability
+ case "$STABILITY" in
+ development) SUFFIX="-dev"; TAG_NAME="development" ;;
+ alpha) SUFFIX="-alpha"; TAG_NAME="alpha" ;;
+ beta) SUFFIX="-beta"; TAG_NAME="beta" ;;
+ rc) SUFFIX="-rc"; TAG_NAME="release-candidate" ;;
+ stable) SUFFIX=""; TAG_NAME="v${VERSION%%.*}" ;;
+ *) SUFFIX="-dev"; TAG_NAME="development" ;;
+ esac
+
+ ZIP_NAME="${EXT_ELEMENT}-${VERSION}${SUFFIX}.zip"
+
+ echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
+ echo "stability=${STABILITY}" >> "$GITHUB_OUTPUT"
+ echo "prerelease=${PRERELEASE}" >> "$GITHUB_OUTPUT"
+ echo "suffix=${SUFFIX}" >> "$GITHUB_OUTPUT"
+ echo "tag_name=${TAG_NAME}" >> "$GITHUB_OUTPUT"
+ echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT"
+ echo "Building: ${ZIP_NAME} (${STABILITY})"
+
+ - name: Install dependencies
+ env:
+ COMPOSER_AUTH: '{"http-basic":{"git.mokoconsulting.tech":{"username":"token","password":"${{ secrets.GA_TOKEN }}"}}}'
+ run: |
+ if [ -f "composer.json" ]; then
+ composer install --no-dev --optimize-autoloader --no-interaction
+ fi
+
+ - name: Create package
+ run: |
+ mkdir -p build/package
+ rsync -av \
+ --exclude='sftp-config*' \
+ --exclude='.ftpignore' \
+ --exclude='*.ppk' \
+ --exclude='*.pem' \
+ --exclude='*.key' \
+ --exclude='.env*' \
+ --exclude='*.local' \
+ src/ build/package/
+
+ - name: Build ZIP
+ id: zip
+ run: |
+ ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
+ cd build/package
+ zip -r "../${ZIP_NAME}" .
+ cd ..
+
+ SHA256=$(sha256sum "${ZIP_NAME}" | cut -d' ' -f1)
+ SIZE=$(stat -c%s "${ZIP_NAME}")
+
+ echo "sha256=${SHA256}" >> "$GITHUB_OUTPUT"
+ echo "size=${SIZE}" >> "$GITHUB_OUTPUT"
+ echo "SHA-256: ${SHA256}"
+ echo "Size: ${SIZE} bytes"
+
+ # ── Gitea Release (PRIMARY) ──────────────────────────────────────
+ - name: "Gitea: Delete existing release"
+ run: |
+ TAG="${{ steps.meta.outputs.tag_name }}"
+ TOKEN="${{ secrets.GA_TOKEN }}"
+ API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
+
+ # Find and delete existing release by tag (may not exist — ignore 404)
+ RELEASE_ID=$(curl -s -H "Authorization: token ${TOKEN}" \
+ "${API}/releases/tags/${TAG}" 2>/dev/null | jq -r '.id // empty')
+
+ if [ -n "$RELEASE_ID" ]; then
+ curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \
+ "${API}/releases/${RELEASE_ID}" || true
+ echo "Deleted existing release id=${RELEASE_ID}"
+ fi
+
+ # Delete existing tag
+ curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \
+ "${API}/tags/${TAG}" 2>/dev/null || true
+
+ - name: "Gitea: Create release"
+ id: gitea_release
+ run: |
+ TAG="${{ steps.meta.outputs.tag_name }}"
+ VERSION="${{ steps.meta.outputs.version }}"
+ STABILITY="${{ steps.meta.outputs.stability }}"
+ PRERELEASE="${{ steps.meta.outputs.prerelease }}"
+ SHA256="${{ steps.zip.outputs.sha256 }}"
+ TOKEN="${{ secrets.GA_TOKEN }}"
+ API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
+
+ # Build release body
+ BODY="## ${EXT_ELEMENT} ${VERSION} (${STABILITY})
+
+ ### SHA-256
+ \`${SHA256}\`"
+
+ # Extract changelog if available
+ if [ -f "CHANGELOG.md" ]; then
+ NOTES=$(awk "/## \[${VERSION}\]/,/## \[/{if(/## \[${VERSION}\]/)next;if(/## \[/)exit;print}" CHANGELOG.md)
+ if [ -n "$NOTES" ]; then
+ BODY="## ${EXT_ELEMENT} ${VERSION} (${STABILITY})
+
+ ${NOTES}
+
+ ### SHA-256
+ \`${SHA256}\`"
+ fi
+ fi
+
+ IS_PRE="true"
+ if [ "$STABILITY" = "stable" ]; then
+ IS_PRE="false"
+ fi
+
+ RESULT=$(curl -sf -X POST -H "Authorization: token ${TOKEN}" \
+ -H "Content-Type: application/json" \
+ "${API}/releases" \
+ -d "$(jq -n \
+ --arg tag "$TAG" \
+ --arg target "${{ github.ref_name }}" \
+ --arg name "${EXT_ELEMENT} ${VERSION} ${STABILITY^}" \
+ --arg body "$BODY" \
+ --argjson pre "$IS_PRE" \
+ '{tag_name: $tag, target_commitish: $target, name: $name, body: $body, prerelease: $pre}'
+ )")
+
+ RELEASE_ID=$(echo "$RESULT" | jq -r '.id')
+ echo "release_id=${RELEASE_ID}" >> "$GITHUB_OUTPUT"
+ echo "Gitea release created: id=${RELEASE_ID}, tag=${TAG}"
+
+ - name: "Gitea: Upload ZIP"
+ run: |
+ RELEASE_ID="${{ steps.gitea_release.outputs.release_id }}"
+ ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
+ TOKEN="${{ secrets.GA_TOKEN }}"
+ API="${GITEA_URL}/api/v1/repos/${GITEA_ORG}/${GITEA_REPO}"
+
+ curl -sf -X POST \
+ -H "Authorization: token ${TOKEN}" \
+ -H "Content-Type: application/octet-stream" \
+ "${API}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}" \
+ --data-binary "@build/${ZIP_NAME}"
+
+ echo "Uploaded ${ZIP_NAME} to Gitea release ${RELEASE_ID}"
+
+ # ── GitHub Mirror (BACKUP) ───────────────────────────────────────
+ - name: "GitHub: Mirror release (stable/rc only)"
+ if: ${{ steps.meta.outputs.stability == 'stable' || steps.meta.outputs.stability == 'rc' }}
+ continue-on-error: true
+ run: |
+ TAG="${{ steps.meta.outputs.tag_name }}"
+ VERSION="${{ steps.meta.outputs.version }}"
+ STABILITY="${{ steps.meta.outputs.stability }}"
+ ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
+ SHA256="${{ steps.zip.outputs.sha256 }}"
+ TOKEN="${{ secrets.GH_TOKEN }}"
+ GH_REPO="mokoconsulting-tech/${GITEA_REPO}"
+ GH_API="https://api.github.com/repos/${GH_REPO}"
+
+ IS_PRE="true"
+ [ "$STABILITY" = "stable" ] && IS_PRE="false"
+
+ # Delete existing release by tag
+ EXISTING=$(curl -sf -H "Authorization: token ${TOKEN}" \
+ "${GH_API}/releases/tags/${TAG}" 2>/dev/null | jq -r '.id // empty')
+ if [ -n "$EXISTING" ]; then
+ curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \
+ "${GH_API}/releases/${EXISTING}" || true
+ fi
+
+ # Delete tag
+ curl -sf -X DELETE -H "Authorization: token ${TOKEN}" \
+ "${GH_API}/git/refs/tags/${TAG}" 2>/dev/null || true
+
+ # Create release
+ RELEASE_ID=$(curl -sf -X POST -H "Authorization: token ${TOKEN}" \
+ -H "Content-Type: application/json" \
+ "${GH_API}/releases" \
+ -d "$(jq -n \
+ --arg tag "$TAG" \
+ --arg target "${{ github.sha }}" \
+ --arg name "${EXT_ELEMENT} ${VERSION} ${STABILITY^} (mirror)" \
+ --arg body "Mirror of Gitea release. SHA-256: \`${SHA256}\`" \
+ --argjson pre "$IS_PRE" \
+ '{tag_name: $tag, target_commitish: $target, name: $name, body: $body, prerelease: $pre, draft: false}'
+ )" | jq -r '.id')
+
+ # Upload ZIP
+ if [ -n "$RELEASE_ID" ] && [ "$RELEASE_ID" != "null" ]; then
+ curl -sf -X POST \
+ -H "Authorization: token ${TOKEN}" \
+ -H "Content-Type: application/octet-stream" \
+ "https://uploads.github.com/repos/${GH_REPO}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}" \
+ --data-binary "@build/${ZIP_NAME}"
+ echo "GitHub mirror: uploaded ${ZIP_NAME}"
+ fi
+
+ # ── Update updates.xml ──────────────────────────────────────────
+ - name: "Update updates.xml for this channel"
+ run: |
+ STABILITY="${{ steps.meta.outputs.stability }}"
+ VERSION="${{ steps.meta.outputs.version }}"
+ SHA256="${{ steps.zip.outputs.sha256 }}"
+ ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
+ TAG="${{ steps.meta.outputs.tag_name }}"
+ DATE=$(date +%Y-%m-%d)
+
+ if [ ! -f "updates.xml" ] || [ -z "$SHA256" ]; then
+ echo "No updates.xml or no SHA — skipping"
+ exit 0
+ fi
+
+ export PY_STABILITY="$STABILITY" PY_VERSION="$VERSION" PY_SHA256="$SHA256" \
+ PY_ZIP_NAME="$ZIP_NAME" PY_TAG="$TAG" PY_DATE="$DATE" \
+ PY_GITEA_ORG="$GITEA_ORG" PY_GITEA_REPO="$GITEA_REPO"
+ python3 << 'PYEOF'
+ import re, os
+
+ stability = os.environ["PY_STABILITY"]
+ version = os.environ["PY_VERSION"]
+ sha256 = os.environ["PY_SHA256"]
+ zip_name = os.environ["PY_ZIP_NAME"]
+ tag = os.environ["PY_TAG"]
+ date = os.environ["PY_DATE"]
+ gitea_org = os.environ["PY_GITEA_ORG"]
+ gitea_repo = os.environ["PY_GITEA_REPO"]
+
+ # Map stability to the value in updates.xml
+ tag_map = {
+ "development": "development",
+ "alpha": "alpha",
+ "beta": "beta",
+ "rc": "rc",
+ "stable": "stable",
+ }
+ xml_tag = tag_map.get(stability, "development")
+
+ with open("updates.xml", "r") as f:
+ content = f.read()
+
+ # Build regex to find the specific block for this stability tag
+ # Use negative lookahead to avoid matching across multiple blocks
+ block_pattern = r"((?:(?! ).)*?" + re.escape(xml_tag) + r" .*? )"
+ match = re.search(block_pattern, content, re.DOTALL)
+
+ if not match:
+ print(f"No block found for {xml_tag} ")
+ exit(0)
+
+ block = match.group(1)
+ original_block = block
+
+ # Update version
+ block = re.sub(r"[^<]* ", f"{version} ", block)
+
+ # Update creation date
+ block = re.sub(r"[^<]* ", f"{date} ", block)
+
+ # Update SHA-256
+ block = re.sub(r"[^<]* ", f"{sha256} ", block)
+
+ # Update Gitea download URL
+ gitea_url = f"https://git.mokoconsulting.tech/{gitea_org}/{gitea_repo}/releases/download/{tag}/{zip_name}"
+ block = re.sub(
+ r"(]*>)https://git\.mokoconsulting\.tech/[^<]*( )",
+ rf"\g<1>{gitea_url}\g<2>",
+ block
+ )
+
+ # Update GitHub download URL only for RC and stable (others are Gitea-only)
+ if stability in ("rc", "stable"):
+ gh_url = f"https://github.com/mokoconsulting-tech/{gitea_repo}/releases/download/{tag}/{zip_name}"
+ block = re.sub(
+ r"(]*>)https://github\.com/[^<]*( )",
+ rf"\g<1>{gh_url}\g<2>",
+ block
+ )
+ else:
+ # Remove any GitHub download URL for dev/alpha/beta
+ block = re.sub(
+ r"\n\s*]*>https://github\.com/[^<]* ",
+ "",
+ block
+ )
+
+ content = content.replace(original_block, block)
+
+ with open("updates.xml", "w") as f:
+ f.write(content)
+
+ print(f"Updated {xml_tag} channel: version={version}, sha={sha256[:16]}..., date={date}")
+ PYEOF
+
+ - name: "Commit updates.xml to current branch and main"
+ run: |
+ if git diff --quiet updates.xml 2>/dev/null; then
+ echo "No changes to updates.xml"
+ exit 0
+ fi
+
+ STABILITY="${{ steps.meta.outputs.stability }}"
+ VERSION="${{ steps.meta.outputs.version }}"
+ CURRENT_BRANCH="${{ github.ref_name }}"
+ TOKEN="${{ secrets.GA_TOKEN }}"
+
+ git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
+ git config --local user.name "gitea-actions[bot]"
+ git add updates.xml
+ git commit -m "chore: update ${STABILITY} SHA-256 for ${VERSION} [skip ci]" \
+ --author="gitea-actions[bot] "
+
+ # Set push URL with GA_TOKEN for authenticated pushes (branch protection requires jmiller)
+ git remote set-url origin "https://jmiller:${{ secrets.GA_TOKEN }}@git.mokoconsulting.tech/${{ github.repository }}.git"
+
+ # Push to current branch
+ git push || true
+
+ # Also update updates.xml on main via Gitea API (git push blocked by branch protection)
+ if [ "$CURRENT_BRANCH" != "main" ]; then
+ GA_TOKEN="${{ secrets.GA_TOKEN }}"
+ API="${GITEA_URL}/api/v1/repos/${{ github.repository }}"
+
+ # Get current file SHA on main (required for update)
+ FILE_SHA=$(curl -sf -H "Authorization: token ${GA_TOKEN}" \
+ "${API}/contents/updates.xml?ref=main" | jq -r '.sha // empty')
+
+ if [ -n "$FILE_SHA" ]; then
+ # Base64-encode the updates.xml content from working tree (has updated SHA)
+ CONTENT=$(base64 -w0 updates.xml)
+
+ RESPONSE=$(curl -s -w "\n%{http_code}" -X PUT -H "Authorization: token ${GA_TOKEN}" \
+ -H "Content-Type: application/json" \
+ "${API}/contents/updates.xml" \
+ -d "$(jq -n \
+ --arg content "$CONTENT" \
+ --arg sha "$FILE_SHA" \
+ --arg msg "chore: update ${STABILITY} channel to ${VERSION} on main [skip ci]" \
+ --arg branch "main" \
+ '{content: $content, sha: $sha, message: $msg, branch: $branch}'
+ )")
+ HTTP_CODE=$(echo "$RESPONSE" | tail -1)
+ if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "201" ]; then
+ echo "updates.xml synced to main via API (HTTP ${HTTP_CODE})"
+ else
+ echo "WARNING: failed to sync updates.xml to main (HTTP ${HTTP_CODE})"
+ echo "$RESPONSE" | head -5
+ fi
+ else
+ echo "WARNING: could not get file SHA for updates.xml on main"
+ fi
+ fi
+
+ - name: Summary
+ run: |
+ VERSION="${{ steps.meta.outputs.version }}"
+ STABILITY="${{ steps.meta.outputs.stability }}"
+ ZIP_NAME="${{ steps.meta.outputs.zip_name }}"
+ SHA256="${{ steps.zip.outputs.sha256 }}"
+ TAG="${{ steps.meta.outputs.tag_name }}"
+
+ echo "### Release Created" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
+ echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
+ echo "| Version | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Stability | ${STABILITY} |" >> $GITHUB_STEP_SUMMARY
+ echo "| Tag | \`${TAG}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Package | \`${ZIP_NAME}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| SHA-256 | \`${SHA256}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Gitea | [Release](${GITEA_URL}/${GITEA_ORG}/${GITEA_REPO}/releases/tag/${TAG}) |" >> $GITHUB_STEP_SUMMARY
diff --git a/.github/workflows/repo_health.yml b/.github/workflows/repo_health.yml
new file mode 100644
index 0000000..f4193b7
--- /dev/null
+++ b/.github/workflows/repo_health.yml
@@ -0,0 +1,787 @@
+# ============================================================================
+# Copyright (C) 2025 Moko Consulting
+#
+# This file is part of a Moko Consulting project.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow
+# INGROUP: MokoStandards.Validation
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /.github/workflows/repo_health.yml
+# VERSION: 04.06.00
+# BRIEF: Enforces repository guardrails by validating release configuration, scripts governance, tooling availability, and core repository health artifacts.
+# NOTE: Field is user-managed.
+# ============================================================================
+
+name: Repo Health
+
+concurrency:
+ group: repo-health-${{ github.repository }}-${{ github.ref }}
+ cancel-in-progress: true
+
+defaults:
+ run:
+ shell: bash
+
+on:
+ workflow_dispatch:
+ inputs:
+ profile:
+ description: 'Validation profile: all, release, scripts, or repo'
+ required: true
+ default: all
+ type: choice
+ options:
+ - all
+ - release
+ - scripts
+ - repo
+ pull_request:
+ push:
+
+permissions:
+ contents: read
+
+env:
+ # Release policy - Repository Variables Only
+ RELEASE_REQUIRED_REPO_VARS: RS_FTP_PATH_SUFFIX
+ RELEASE_OPTIONAL_REPO_VARS: DEV_FTP_SUFFIX
+
+ # Scripts governance policy
+ # Note: directories listed without a trailing slash.
+ SCRIPTS_REQUIRED_DIRS:
+ SCRIPTS_ALLOWED_DIRS: scripts,scripts/fix,scripts/lib,scripts/release,scripts/run,scripts/validate
+
+ # Repo health policy
+ # Files are listed as-is; directories must end with a trailing slash.
+ REPO_REQUIRED_ARTIFACTS: README.md,LICENSE,CHANGELOG.md,CONTRIBUTING.md,CODE_OF_CONDUCT.md,.github/workflows/
+ REPO_OPTIONAL_FILES: SECURITY.md,GOVERNANCE.md,.editorconfig,.gitattributes,.gitignore,README.md,docs/
+ REPO_DISALLOWED_DIRS:
+ REPO_DISALLOWED_FILES: TODO.md,todo.md
+
+ # Extended checks toggles
+ EXTENDED_CHECKS: "true"
+
+ # File / directory variables (moved to top-level env)
+ DOCS_INDEX: docs/docs-index.md
+ SCRIPT_DIR: scripts
+ WORKFLOWS_DIR: .github/workflows
+ SHELLCHECK_PATTERN: '*.sh'
+ SPDX_FILE_GLOBS: '*.sh,*.php,*.js,*.ts,*.css,*.xml,*.yml,*.yaml'
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
+
+jobs:
+ access_check:
+ name: Access control
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+ permissions:
+ contents: read
+
+ outputs:
+ allowed: ${{ steps.perm.outputs.allowed }}
+ permission: ${{ steps.perm.outputs.permission }}
+
+ steps:
+ - name: Check actor permission (admin only)
+ id: perm
+ run: |
+ ACTOR="${{ github.actor }}"
+ REPO="${{ github.repository }}"
+ TOKEN="${{ secrets.GA_TOKEN }}"
+ GITEA_API="${GITEA_URL:-https://git.mokoconsulting.tech}/api/v1"
+
+ PERMISSION="unknown"
+ ALLOWED="false"
+ METHOD=""
+
+ # Hardcoded authorized users
+ if [ "$ACTOR" = "jmiller" ] || [ "$ACTOR" = "gitea-actions[bot]" ]; then
+ PERMISSION="admin"
+ ALLOWED="true"
+ METHOD="hardcoded allowlist"
+ else
+ # Check via Gitea API
+ RESULT=$(curl -sf -H "Authorization: token ${TOKEN}" \
+ "${GITEA_API}/repos/${REPO}/collaborators/${ACTOR}/permission" 2>/dev/null || echo '{}')
+ PERMISSION=$(echo "$RESULT" | jq -r '.permission // "unknown"')
+ if [ "$PERMISSION" = "admin" ] || [ "$PERMISSION" = "owner" ] || [ "$PERMISSION" = "maintain" ]; then
+ ALLOWED="true"
+ fi
+ METHOD="Gitea collaborator API"
+ fi
+
+ echo "permission=${PERMISSION}" >> "$GITHUB_OUTPUT"
+ echo "allowed=${ALLOWED}" >> "$GITHUB_OUTPUT"
+
+ {
+ echo "## 🔐 Access Authorization"
+ echo ""
+ echo "| Field | Value |"
+ echo "|-------|-------|"
+ echo "| **Actor** | \`${ACTOR}\` |"
+ echo "| **Repository** | \`${REPO}\` |"
+ echo "| **Permission** | \`${PERMISSION}\` |"
+ echo "| **Method** | ${METHOD} |"
+ echo "| **Authorized** | ${ALLOWED} |"
+ echo "| **Trigger** | \`${{ github.event_name }}\` |"
+ echo "| **Branch** | \`${GITHUB_REF#refs/heads/}\` |"
+ echo ""
+ if [ "$ALLOWED" = "true" ]; then
+ echo "✅ ${ACTOR} authorized (${METHOD})"
+ else
+ echo "❌ ${ACTOR} is NOT authorized. Requires admin or maintain role."
+ fi
+ } >> "$GITHUB_STEP_SUMMARY"
+
+ - name: Deny execution when not permitted
+ if: ${{ steps.perm.outputs.allowed != 'true' }}
+ run: |
+ set -euo pipefail
+ printf '%s\n' 'ERROR: Access denied. Admin permission required.' >> "${GITHUB_STEP_SUMMARY}"
+ exit 1
+
+ release_config:
+ name: Release configuration
+ needs: access_check
+ if: ${{ needs.access_check.outputs.allowed == 'true' }}
+ runs-on: ubuntu-latest
+ timeout-minutes: 20
+ permissions:
+ contents: read
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ with:
+ fetch-depth: 0
+
+ - name: Guardrails release vars
+ env:
+ PROFILE_RAW: ${{ github.event.inputs.profile }}
+ RS_FTP_PATH_SUFFIX: ${{ vars.RS_FTP_PATH_SUFFIX }}
+ DEV_FTP_SUFFIX: ${{ vars.DEV_FTP_SUFFIX }}
+ run: |
+ set -euo pipefail
+
+ profile="${PROFILE_RAW:-all}"
+ case "${profile}" in
+ all|release|scripts|repo) ;;
+ *)
+ printf '%s\n' "ERROR: Unknown profile: ${profile}" >> "${GITHUB_STEP_SUMMARY}"
+ exit 1
+ ;;
+ esac
+
+ if [ "${profile}" = 'scripts' ] || [ "${profile}" = 'repo' ]; then
+ {
+ printf '%s\n' '### Release configuration (Repository Variables)'
+ printf '%s\n' "Profile: ${profile}"
+ printf '%s\n' 'Status: SKIPPED'
+ printf '%s\n' 'Reason: profile excludes release validation'
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ exit 0
+ fi
+
+ IFS=',' read -r -a required <<< "${RELEASE_REQUIRED_REPO_VARS}"
+ IFS=',' read -r -a optional <<< "${RELEASE_OPTIONAL_REPO_VARS}"
+
+ missing=()
+ missing_optional=()
+
+ for k in "${required[@]}"; do
+ v="${!k:-}"
+ [ -z "${v}" ] && missing+=("${k}")
+ done
+
+ for k in "${optional[@]}"; do
+ v="${!k:-}"
+ [ -z "${v}" ] && missing_optional+=("${k}")
+ done
+
+ {
+ printf '%s\n' '### Release configuration (Repository Variables)'
+ printf '%s\n' "Profile: ${profile}"
+ printf '%s\n' '| Variable | Status |'
+ printf '%s\n' '|---|---|'
+ printf '%s\n' "| RS_FTP_PATH_SUFFIX | ${RS_FTP_PATH_SUFFIX:-NOT SET} |"
+ printf '%s\n' "| DEV_FTP_SUFFIX | ${DEV_FTP_SUFFIX:-NOT SET} |"
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+
+ if [ "${#missing_optional[@]}" -gt 0 ]; then
+ {
+ printf '%s\n' '### Missing optional repository variables'
+ for m in "${missing_optional[@]}"; do printf '%s\n' "- ${m}"; done
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ fi
+
+ if [ "${#missing[@]}" -gt 0 ]; then
+ {
+ printf '%s\n' '### Missing required repository variables'
+ for m in "${missing[@]}"; do printf '%s\n' "- ${m}"; done
+ printf '%s\n' 'ERROR: Guardrails failed. Missing required repository variables.'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ exit 1
+ fi
+
+ {
+ printf '%s\n' '### Repository variables validation result'
+ printf '%s\n' 'Status: OK'
+ printf '%s\n' 'All required repository variables present.'
+ printf '%s\n' ''
+ printf '%s\n' '**Note**: Organization secrets (RS_FTP_HOST, RS_FTP_USER, etc.) are validated at deployment time, not in repository health checks.'
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+
+ scripts_governance:
+ name: Scripts governance
+ needs: access_check
+ if: ${{ needs.access_check.outputs.allowed == 'true' }}
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ permissions:
+ contents: read
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ with:
+ fetch-depth: 0
+
+ - name: Scripts folder checks
+ env:
+ PROFILE_RAW: ${{ github.event.inputs.profile }}
+ run: |
+ set -euo pipefail
+
+ profile="${PROFILE_RAW:-all}"
+ case "${profile}" in
+ all|release|scripts|repo) ;;
+ *)
+ printf '%s\n' "ERROR: Unknown profile: ${profile}" >> "${GITHUB_STEP_SUMMARY}"
+ exit 1
+ ;;
+ esac
+
+ if [ "${profile}" = 'release' ] || [ "${profile}" = 'repo' ]; then
+ {
+ printf '%s\n' '### Scripts governance'
+ printf '%s\n' "Profile: ${profile}"
+ printf '%s\n' 'Status: SKIPPED'
+ printf '%s\n' 'Reason: profile excludes scripts governance'
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ exit 0
+ fi
+
+ if [ ! -d "${SCRIPT_DIR}" ]; then
+ {
+ printf '%s\n' '### Scripts governance'
+ printf '%s\n' 'Status: OK (advisory)'
+ printf '%s\n' 'scripts/ directory not present. No scripts governance enforced.'
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ exit 0
+ fi
+
+ IFS=',' read -r -a required_dirs <<< "${SCRIPTS_REQUIRED_DIRS}"
+ IFS=',' read -r -a allowed_dirs <<< "${SCRIPTS_ALLOWED_DIRS}"
+
+ missing_dirs=()
+ unapproved_dirs=()
+
+ for d in "${required_dirs[@]}"; do
+ req="${d%/}"
+ [ ! -d "${req}" ] && missing_dirs+=("${req}/")
+ done
+
+ while IFS= read -r d; do
+ allowed=false
+ for a in "${allowed_dirs[@]}"; do
+ a_norm="${a%/}"
+ [ "${d%/}" = "${a_norm}" ] && allowed=true
+ done
+ [ "${allowed}" = false ] && unapproved_dirs+=("${d%/}/")
+ done < <(find "${SCRIPT_DIR}" -maxdepth 1 -mindepth 1 -type d 2>/dev/null | sed 's#^\./##')
+
+ {
+ printf '%s\n' '### Scripts governance'
+ printf '%s\n' "Profile: ${profile}"
+ printf '%s\n' '| Area | Status | Notes |'
+ printf '%s\n' '|---|---|---|'
+
+ if [ "${#missing_dirs[@]}" -gt 0 ]; then
+ printf '%s\n' '| Required directories | Warning | Missing required subfolders |'
+ else
+ printf '%s\n' '| Required directories | OK | All required subfolders present |'
+ fi
+
+ if [ "${#unapproved_dirs[@]}" -gt 0 ]; then
+ printf '%s\n' '| Directory policy | Warning | Unapproved directories detected |'
+ else
+ printf '%s\n' '| Directory policy | OK | No unapproved directories |'
+ fi
+
+ printf '%s\n' '| Enforcement mode | Advisory | scripts folder is optional |'
+ printf '\n'
+
+ if [ "${#missing_dirs[@]}" -gt 0 ]; then
+ printf '%s\n' 'Missing required script directories:'
+ for m in "${missing_dirs[@]}"; do printf '%s\n' "- ${m}"; done
+ printf '\n'
+ else
+ printf '%s\n' 'Missing required script directories: none.'
+ printf '\n'
+ fi
+
+ if [ "${#unapproved_dirs[@]}" -gt 0 ]; then
+ printf '%s\n' 'Unapproved script directories detected:'
+ for m in "${unapproved_dirs[@]}"; do printf '%s\n' "- ${m}"; done
+ printf '\n'
+ else
+ printf '%s\n' 'Unapproved script directories detected: none.'
+ printf '\n'
+ fi
+
+ printf '%s\n' 'Scripts governance completed in advisory mode.'
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+
+ repo_health:
+ name: Repository health
+ needs: access_check
+ if: ${{ needs.access_check.outputs.allowed == 'true' }}
+ runs-on: ubuntu-latest
+ timeout-minutes: 20
+ permissions:
+ contents: read
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ with:
+ fetch-depth: 0
+
+ - name: Repository health checks
+ env:
+ PROFILE_RAW: ${{ github.event.inputs.profile }}
+ run: |
+ set -euo pipefail
+
+ profile="${PROFILE_RAW:-all}"
+ case "${profile}" in
+ all|release|scripts|repo) ;;
+ *)
+ printf '%s\n' "ERROR: Unknown profile: ${profile}" >> "${GITHUB_STEP_SUMMARY}"
+ exit 1
+ ;;
+ esac
+
+ if [ "${profile}" = 'release' ] || [ "${profile}" = 'scripts' ]; then
+ {
+ printf '%s\n' '### Repository health'
+ printf '%s\n' "Profile: ${profile}"
+ printf '%s\n' 'Status: SKIPPED'
+ printf '%s\n' 'Reason: profile excludes repository health'
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ exit 0
+ fi
+
+ # Source directory: src/ or htdocs/ (either is valid)
+ if [ -d "src" ]; then
+ SOURCE_DIR="src"
+ elif [ -d "htdocs" ]; then
+ SOURCE_DIR="htdocs"
+ else
+ missing_required+=("src/ or htdocs/ (source directory required)")
+ fi
+
+ IFS=',' read -r -a required_artifacts <<< "${REPO_REQUIRED_ARTIFACTS}"
+ IFS=',' read -r -a optional_files <<< "${REPO_OPTIONAL_FILES}"
+ IFS=',' read -r -a disallowed_dirs <<< "${REPO_DISALLOWED_DIRS}"
+ IFS=',' read -r -a disallowed_files <<< "${REPO_DISALLOWED_FILES}"
+
+ missing_required=()
+ missing_optional=()
+
+ for item in "${required_artifacts[@]}"; do
+ if printf '%s' "${item}" | grep -q '/$'; then
+ d="${item%/}"
+ [ ! -d "${d}" ] && missing_required+=("${item}")
+ else
+ [ ! -f "${item}" ] && missing_required+=("${item}")
+ fi
+ done
+
+ # Optional entries: handle files and directories (trailing slash indicates dir)
+ for f in "${optional_files[@]}"; do
+ if printf '%s' "${f}" | grep -q '/$'; then
+ d="${f%/}"
+ [ ! -d "${d}" ] && missing_optional+=("${f}")
+ else
+ [ ! -f "${f}" ] && missing_optional+=("${f}")
+ fi
+ done
+
+ for d in "${disallowed_dirs[@]}"; do
+ d_norm="${d%/}"
+ [ -d "${d_norm}" ] && missing_required+=("${d_norm}/ (disallowed)")
+ done
+
+ for f in "${disallowed_files[@]}"; do
+ [ -f "${f}" ] && missing_required+=("${f} (disallowed)")
+ done
+
+ git fetch origin --prune
+
+ dev_paths=()
+ dev_branches=()
+
+ # Look for remote branches matching origin/dev*.
+ # A plain origin/dev is considered invalid; we require dev/ branches.
+ while IFS= read -r b; do
+ name="${b#origin/}"
+ if [ "${name}" = 'dev' ]; then
+ dev_branches+=("${name}")
+ else
+ dev_paths+=("${name}")
+ fi
+ done < <(git branch -r --list 'origin/dev*' | sed 's/^ *//')
+
+ # If there are no dev/* branches, fail the guardrail.
+ if [ "${#dev_paths[@]}" -eq 0 ]; then
+ missing_required+=("dev/* branch (e.g. dev/01.00.00)")
+ fi
+
+ # If a plain dev branch exists (origin/dev), flag it as invalid.
+ if [ "${#dev_branches[@]}" -gt 0 ]; then
+ missing_required+=("invalid branch dev (must be dev/)")
+ fi
+
+ content_warnings=()
+
+ if [ -f 'CHANGELOG.md' ] && ! grep -Eq '^# Changelog' CHANGELOG.md; then
+ content_warnings+=("CHANGELOG.md missing '# Changelog' header")
+ fi
+
+ if [ -f 'CHANGELOG.md' ] && grep -Eq '^[# ]*Unreleased' CHANGELOG.md; then
+ content_warnings+=("CHANGELOG.md contains Unreleased section (review release readiness)")
+ fi
+
+ if [ -f 'LICENSE' ] && ! grep -qiE 'GNU GENERAL PUBLIC LICENSE|GPL' LICENSE; then
+ content_warnings+=("LICENSE does not look like a GPL text")
+ fi
+
+ if [ -f 'README.md' ] && ! grep -qiE 'moko|Moko' README.md; then
+ content_warnings+=("README.md missing expected brand keyword")
+ fi
+
+ export PROFILE_RAW="${profile}"
+ export MISSING_REQUIRED="$(printf '%s\n' "${missing_required[@]:-}")"
+ export MISSING_OPTIONAL="$(printf '%s\n' "${missing_optional[@]:-}")"
+ export CONTENT_WARNINGS="$(printf '%s\n' "${content_warnings[@]:-}")"
+
+ report_json="$(python3 - <<'PY'
+ import json
+ import os
+
+ profile = os.environ.get('PROFILE_RAW') or 'all'
+
+ missing_required = os.environ.get('MISSING_REQUIRED', '').splitlines() if os.environ.get('MISSING_REQUIRED') else []
+ missing_optional = os.environ.get('MISSING_OPTIONAL', '').splitlines() if os.environ.get('MISSING_OPTIONAL') else []
+ content_warnings = os.environ.get('CONTENT_WARNINGS', '').splitlines() if os.environ.get('CONTENT_WARNINGS') else []
+
+ out = {
+ 'profile': profile,
+ 'missing_required': [x for x in missing_required if x],
+ 'missing_optional': [x for x in missing_optional if x],
+ 'content_warnings': [x for x in content_warnings if x],
+ }
+
+ print(json.dumps(out, indent=2))
+ PY
+ )"
+
+ {
+ printf '%s\n' '### Repository health'
+ printf '%s\n' "Profile: ${profile}"
+ printf '%s\n' '| Metric | Value |'
+ printf '%s\n' '|---|---|'
+ printf '%s\n' "| Missing required | ${#missing_required[@]} |"
+ printf '%s\n' "| Missing optional | ${#missing_optional[@]} |"
+ printf '%s\n' "| Content warnings | ${#content_warnings[@]} |"
+ printf '\n'
+
+ printf '%s\n' '### Guardrails report (JSON)'
+ printf '%s\n' '```json'
+ printf '%s\n' "${report_json}"
+ printf '%s\n' '```'
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+
+ if [ "${#missing_required[@]}" -gt 0 ]; then
+ {
+ printf '%s\n' '### Missing required repo artifacts'
+ for m in "${missing_required[@]}"; do printf '%s\n' "- ${m}"; done
+ printf '%s\n' 'ERROR: Guardrails failed. Missing required repository artifacts.'
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ exit 1
+ fi
+
+ if [ "${#missing_optional[@]}" -gt 0 ]; then
+ {
+ printf '%s\n' '### Missing optional repo artifacts'
+ for m in "${missing_optional[@]}"; do printf '%s\n' "- ${m}"; done
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ fi
+
+ if [ "${#content_warnings[@]}" -gt 0 ]; then
+ {
+ printf '%s\n' '### Repo content warnings'
+ for m in "${content_warnings[@]}"; do printf '%s\n' "- ${m}"; done
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ fi
+
+ # ── Joomla-specific checks ───────────────────────────────────────
+ joomla_findings=()
+
+ # XML manifest: find any XML file containing tag)")
+ else
+ # Check tag exists
+ if ! grep -qP '' "${MANIFEST}"; then
+ joomla_findings+=("XML manifest: tag missing")
+ fi
+ # Check extension type attribute
+ if ! grep -qP 'type="(component|module|plugin|library|package|template|language)"' "${MANIFEST}"; then
+ joomla_findings+=("XML manifest: type attribute missing or invalid")
+ fi
+ # Check tag
+ if ! grep -qP '' "${MANIFEST}"; then
+ joomla_findings+=("XML manifest: tag missing")
+ fi
+ # Check tag
+ if ! grep -qP '' "${MANIFEST}"; then
+ joomla_findings+=("XML manifest: tag missing")
+ fi
+ # Check for Joomla 5+
+ if ! grep -qP ' missing (required for Joomla 5+)")
+ fi
+ fi
+
+ # Language files: check for at least one .ini file
+ INI_COUNT="$(find . -name '*.ini' -type f 2>/dev/null | wc -l)"
+ if [ "${INI_COUNT}" -eq 0 ]; then
+ joomla_findings+=("No .ini language files found")
+ fi
+
+ # updates.xml must exist in root (Joomla update server)
+ if [ ! -f 'updates.xml' ]; then
+ joomla_findings+=("updates.xml missing in root (required for Joomla update server)")
+ fi
+
+ # index.html files for directory listing protection
+ INDEX_DIRS=("${SOURCE_DIR}" "${SOURCE_DIR}/admin" "${SOURCE_DIR}/site")
+ for dir in "${INDEX_DIRS[@]}"; do
+ if [ -d "${dir}" ] && [ ! -f "${dir}/index.html" ]; then
+ joomla_findings+=("${dir}/index.html missing (directory listing protection)")
+ fi
+ done
+
+ if [ "${#joomla_findings[@]}" -gt 0 ]; then
+ {
+ printf '%s\n' '### Joomla extension checks'
+ printf '%s\n' '| Check | Status |'
+ printf '%s\n' '|---|---|'
+ for f in "${joomla_findings[@]}"; do
+ printf '%s\n' "| ${f} | Warning |"
+ done
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ else
+ {
+ printf '%s\n' '### Joomla extension checks'
+ printf '%s\n' 'All Joomla-specific checks passed.'
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ fi
+
+ extended_enabled="${EXTENDED_CHECKS:-true}"
+ extended_findings=()
+
+ if [ "${extended_enabled}" = 'true' ]; then
+ # CODEOWNERS presence
+ if [ -f '.github/CODEOWNERS' ] || [ -f 'CODEOWNERS' ] || [ -f 'docs/CODEOWNERS' ]; then
+ :
+ else
+ extended_findings+=("CODEOWNERS not found (.github/CODEOWNERS preferred)")
+ fi
+
+ # Workflow pinning advisory: flag uses @main/@master
+ if ls "${WORKFLOWS_DIR}"/*.yml >/dev/null 2>&1 || ls "${WORKFLOWS_DIR}"/*.yaml >/dev/null 2>&1; then
+ bad_refs="$(grep -RIn --include='*.yml' --include='*.yaml' -E '^[[:space:]]*uses:[[:space:]]*[^#]+@(main|master)\b' "${WORKFLOWS_DIR}" 2>/dev/null || true)"
+ if [ -n "${bad_refs}" ]; then
+ extended_findings+=("Workflows reference actions @main/@master (pin versions): see log excerpt")
+ {
+ printf '%s\n' '### Workflow pinning advisory'
+ printf '%s\n' 'Found uses: entries pinned to main/master:'
+ printf '%s\n' '```'
+ printf '%s\n' "${bad_refs}"
+ printf '%s\n' '```'
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ fi
+ fi
+
+ # Docs index link integrity (docs/docs-index.md)
+ if [ -f "${DOCS_INDEX}" ]; then
+ missing_links="$(python3 - <<'PY'
+ import os
+ import re
+
+ idx = os.environ.get('DOCS_INDEX', 'docs/docs-index.md')
+ base = os.getcwd()
+
+ bad = []
+ pat = re.compile(r'\[[^\]]+\]\(([^)]+)\)')
+
+ with open(idx, 'r', encoding='utf-8') as f:
+ for line in f:
+ for m in pat.findall(line):
+ link = m.strip()
+ if link.startswith('http://') or link.startswith('https://') or link.startswith('#') or link.startswith('mailto:'):
+ continue
+ if link.startswith('/'):
+ rel = link.lstrip('/')
+ else:
+ rel = os.path.normpath(os.path.join(os.path.dirname(idx), link))
+ rel = rel.split('#', 1)[0]
+ rel = rel.split('?', 1)[0]
+ if not rel:
+ continue
+ p = os.path.join(base, rel)
+ if not os.path.exists(p):
+ bad.append(rel)
+
+ print('\n'.join(sorted(set(bad))))
+ PY
+ )"
+ if [ -n "${missing_links}" ]; then
+ extended_findings+=("docs/docs-index.md contains broken relative links")
+ {
+ printf '%s\n' '### Docs index link integrity'
+ printf '%s\n' 'Broken relative links:'
+ while IFS= read -r l; do [ -n "${l}" ] && printf '%s\n' "- ${l}"; done <<< "${missing_links}"
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ fi
+ fi
+
+ # ShellCheck advisory
+ if [ -d "${SCRIPT_DIR}" ]; then
+ if ! command -v shellcheck >/dev/null 2>&1; then
+ sudo apt-get update -qq
+ sudo apt-get install -y shellcheck >/dev/null
+ fi
+
+ sc_out=''
+ while IFS= read -r shf; do
+ [ -z "${shf}" ] && continue
+ out_one="$(shellcheck -S warning -x "${shf}" 2>/dev/null || true)"
+ if [ -n "${out_one}" ]; then
+ sc_out="${sc_out}${out_one}\n"
+ fi
+ done < <(find "${SCRIPT_DIR}" -type f -name "${SHELLCHECK_PATTERN}" 2>/dev/null | sort)
+
+ if [ -n "${sc_out}" ]; then
+ extended_findings+=("ShellCheck warnings detected (advisory)")
+ sc_head="$(printf '%s' "${sc_out}" | head -n 200)"
+ {
+ printf '%s\n' '### ShellCheck (advisory)'
+ printf '%s\n' '```'
+ printf '%s\n' "${sc_head}"
+ printf '%s\n' '```'
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ fi
+ fi
+
+ # SPDX header advisory for common source types
+ spdx_missing=()
+ IFS=',' read -r -a spdx_globs <<< "${SPDX_FILE_GLOBS}"
+ spdx_args=()
+ for g in "${spdx_globs[@]}"; do spdx_args+=("${g}"); done
+
+ while IFS= read -r f; do
+ [ -z "${f}" ] && continue
+ if ! head -n 40 "${f}" | grep -q 'SPDX-License-Identifier:'; then
+ spdx_missing+=("${f}")
+ fi
+ done < <(git ls-files "${spdx_args[@]}" 2>/dev/null || true)
+
+ if [ "${#spdx_missing[@]}" -gt 0 ]; then
+ extended_findings+=("SPDX header missing in some tracked files (advisory)")
+ {
+ printf '%s\n' '### SPDX header advisory'
+ printf '%s\n' 'Files missing SPDX-License-Identifier (first 40 lines scan):'
+ for f in "${spdx_missing[@]}"; do printf '%s\n' "- ${f}"; done
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ fi
+
+ # Git hygiene advisory: branches older than 180 days (remote)
+ stale_cutoff_days=180
+ stale_branches="$(git for-each-ref --format='%(refname:short) %(committerdate:unix)' refs/remotes/origin 2>/dev/null | awk -v now="$(date +%s)" -v days="${stale_cutoff_days}" '{if (now-$2 [...]
+ if [ -n "${stale_branches}" ]; then
+ extended_findings+=("Stale remote branches detected (advisory)")
+ {
+ printf '%s\n' '### Git hygiene advisory'
+ printf '%s\n' "Branches with last commit older than ${stale_cutoff_days} days (sample up to 50):"
+ while IFS= read -r b; do [ -n "${b}" ] && printf '%s\n' "- ${b}"; done <<< "${stale_branches}"
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ fi
+ fi
+
+ {
+ printf '%s\n' '### Guardrails coverage matrix'
+ printf '%s\n' '| Domain | Status | Notes |'
+ printf '%s\n' '|---|---|---|'
+ printf '%s\n' '| Access control | OK | Admin-only execution gate |'
+ printf '%s\n' '| Release variables | OK | Repository variables validation |'
+ printf '%s\n' '| Scripts governance | OK | Directory policy and advisory reporting |'
+ printf '%s\n' '| Repo required artifacts | OK | Required, optional, disallowed enforcement |'
+ printf '%s\n' '| Repo content heuristics | OK | Brand, license, changelog structure |'
+ if [ "${extended_enabled}" = 'true' ]; then
+ if [ "${#extended_findings[@]}" -gt 0 ]; then
+ printf '%s\n' '| Extended checks | Warning | See extended findings below |'
+ else
+ printf '%s\n' '| Extended checks | OK | No findings |'
+ fi
+ else
+ printf '%s\n' '| Extended checks | SKIPPED | EXTENDED_CHECKS disabled |'
+ fi
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+
+ if [ "${extended_enabled}" = 'true' ] && [ "${#extended_findings[@]}" -gt 0 ]; then
+ {
+ printf '%s\n' '### Extended findings (advisory)'
+ for f in "${extended_findings[@]}"; do printf '%s\n' "- ${f}"; done
+ printf '\n'
+ } >> "${GITHUB_STEP_SUMMARY}"
+ fi
+
+ printf '%s\n' 'Repository health guardrails passed.' >> "${GITHUB_STEP_SUMMARY}"
diff --git a/.github/workflows/repository-cleanup.yml b/.github/workflows/repository-cleanup.yml
new file mode 100644
index 0000000..3c2270d
--- /dev/null
+++ b/.github/workflows/repository-cleanup.yml
@@ -0,0 +1,525 @@
+# Copyright (C) 2026 Moko Consulting
+#
+# This file is part of a Moko Consulting project.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow
+# INGROUP: MokoStandards.Maintenance
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /templates/workflows/shared/repository-cleanup.yml.template
+# VERSION: 04.06.00
+# BRIEF: Recurring repository maintenance — labels, branches, workflows, logs, doc indexes
+# NOTE: Synced via bulk-repo-sync to .github/workflows/repository-cleanup.yml in all governed repos.
+# Runs on the 1st and 15th of each month at 6:00 AM UTC, and on manual dispatch.
+
+name: Repository Cleanup
+
+on:
+ schedule:
+ - cron: '0 6 1,15 * *'
+ workflow_dispatch:
+ inputs:
+ reset_labels:
+ description: 'Delete ALL existing labels and recreate the standard set'
+ type: boolean
+ default: false
+ clean_branches:
+ description: 'Delete old chore/sync-mokostandards-* branches'
+ type: boolean
+ default: true
+ clean_workflows:
+ description: 'Delete orphaned workflow runs (cancelled, stale)'
+ type: boolean
+ default: true
+ clean_logs:
+ description: 'Delete workflow run logs older than 30 days'
+ type: boolean
+ default: true
+ fix_templates:
+ description: 'Strip copyright comment blocks from issue templates'
+ type: boolean
+ default: true
+ rebuild_indexes:
+ description: 'Rebuild docs/ index files'
+ type: boolean
+ default: true
+ delete_closed_issues:
+ description: 'Delete issues that have been closed for more than 30 days'
+ type: boolean
+ default: false
+
+env:
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
+
+permissions:
+ contents: write
+ issues: write
+ actions: write
+
+jobs:
+ cleanup:
+ name: Repository Maintenance
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ with:
+ token: ${{ secrets.GA_TOKEN || github.token }}
+ fetch-depth: 0
+
+ - name: Check actor permission
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ ACTOR="${{ github.actor }}"
+ # Schedule triggers use gitea-actions[bot]
+ if [ "${{ github.event_name }}" = "schedule" ]; then
+ echo "✅ Scheduled run — authorized"
+ exit 0
+ fi
+ AUTHORIZED_USERS="jmiller gitea-actions[bot]"
+ for user in $AUTHORIZED_USERS; do
+ if [ "$ACTOR" = "$user" ]; then
+ echo "✅ ${ACTOR} authorized"
+ exit 0
+ fi
+ done
+ PERMISSION=$(gh api "repos/${{ github.repository }}/collaborators/${ACTOR}/permission" \
+ 2>/dev/null | jq -r '.permission')
+ case "$PERMISSION" in
+ admin|maintain) echo "✅ ${ACTOR} has ${PERMISSION}" ;;
+ *) echo "❌ Admin or maintain required"; exit 1 ;;
+ esac
+
+ # ── Determine which tasks to run ─────────────────────────────────────
+ # On schedule: run all tasks with safe defaults (labels NOT reset)
+ # On dispatch: use input toggles
+ - name: Set task flags
+ id: tasks
+ run: |
+ if [ "${{ github.event_name }}" = "schedule" ]; then
+ echo "reset_labels=false" >> $GITHUB_OUTPUT
+ echo "clean_branches=true" >> $GITHUB_OUTPUT
+ echo "clean_workflows=true" >> $GITHUB_OUTPUT
+ echo "clean_logs=true" >> $GITHUB_OUTPUT
+ echo "fix_templates=true" >> $GITHUB_OUTPUT
+ echo "rebuild_indexes=true" >> $GITHUB_OUTPUT
+ echo "delete_closed_issues=false" >> $GITHUB_OUTPUT
+ else
+ echo "reset_labels=${{ inputs.reset_labels }}" >> $GITHUB_OUTPUT
+ echo "clean_branches=${{ inputs.clean_branches }}" >> $GITHUB_OUTPUT
+ echo "clean_workflows=${{ inputs.clean_workflows }}" >> $GITHUB_OUTPUT
+ echo "clean_logs=${{ inputs.clean_logs }}" >> $GITHUB_OUTPUT
+ echo "fix_templates=${{ inputs.fix_templates }}" >> $GITHUB_OUTPUT
+ echo "rebuild_indexes=${{ inputs.rebuild_indexes }}" >> $GITHUB_OUTPUT
+ echo "delete_closed_issues=${{ inputs.delete_closed_issues }}" >> $GITHUB_OUTPUT
+ fi
+
+ # ── DELETE RETIRED WORKFLOWS (always runs) ────────────────────────────
+ - name: Delete retired workflow files
+ run: |
+ echo "## 🗑️ Retired Workflow Cleanup" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ RETIRED=(
+ ".github/workflows/build.yml"
+ ".github/workflows/code-quality.yml"
+ ".github/workflows/release-cycle.yml"
+ ".github/workflows/release-pipeline.yml"
+ ".github/workflows/branch-cleanup.yml"
+ ".github/workflows/auto-update-changelog.yml"
+ ".github/workflows/enterprise-issue-manager.yml"
+ ".github/workflows/flush-actions-cache.yml"
+ ".github/workflows/mokostandards-script-runner.yml"
+ ".github/workflows/unified-ci.yml"
+ ".github/workflows/unified-platform-testing.yml"
+ ".github/workflows/reusable-build.yml"
+ ".github/workflows/reusable-ci-validation.yml"
+ ".github/workflows/reusable-deploy.yml"
+ ".github/workflows/reusable-php-quality.yml"
+ ".github/workflows/reusable-platform-testing.yml"
+ ".github/workflows/reusable-project-detector.yml"
+ ".github/workflows/reusable-release.yml"
+ ".github/workflows/reusable-script-executor.yml"
+ ".github/workflows/rebuild-docs-indexes.yml"
+ ".github/workflows/setup-project-v2.yml"
+ ".github/workflows/sync-docs-to-project.yml"
+ ".github/workflows/release.yml"
+ ".github/workflows/sync-changelogs.yml"
+ ".github/workflows/version_branch.yml"
+ "update.json"
+ ".github/workflows/auto-version-branch.yml"
+ ".github/workflows/publish-to-mokodolibarr.yml"
+ ".github/workflows/ci.yml"
+ ".github/workflows/deploy-rs.yml"
+ "sftp-config.json"
+ "sftp-config.json.template"
+ "scripts/sftp-config"
+ )
+
+ DELETED=0
+ for wf in "${RETIRED[@]}"; do
+ if [ -f "$wf" ]; then
+ git rm "$wf" 2>/dev/null || rm -f "$wf"
+ echo " Deleted: \`$(basename $wf)\`" >> $GITHUB_STEP_SUMMARY
+ DELETED=$((DELETED+1))
+ fi
+ done
+
+ if [ "$DELETED" -gt 0 ]; then
+ git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
+ git config --local user.name "gitea-actions[bot]"
+ git add -A
+ git commit -m "chore: delete ${DELETED} retired workflow file(s) [skip ci]" \
+ --author="gitea-actions[bot] "
+ git push
+ echo "✅ ${DELETED} retired workflow(s) deleted" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ No retired workflows found" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # ── LABEL RESET ──────────────────────────────────────────────────────
+ - name: Reset labels to standard set
+ if: steps.tasks.outputs.reset_labels == 'true'
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ REPO="${{ github.repository }}"
+ echo "## 🏷️ Label Reset" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/labels?per_page=100" 2>/dev/null | jq -r '.[].name' | while read -r label; do
+ ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$label', safe=''))")
+ gh api -X DELETE "repos/${REPO}/labels/${ENCODED}" --silent 2>/dev/null || true
+ done
+
+ while IFS='|' read -r name color description; do
+ [ -z "$name" ] && continue
+ curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/labels" 2>/dev/null \
+ -f name="$name" -f color="$color" -f description="$description" \
+ --silent 2>/dev/null || true
+ done << 'LABELS'
+ joomla|7F52FF|Joomla extension or component
+ dolibarr|FF6B6B|Dolibarr module or extension
+ generic|808080|Generic project or library
+ php|4F5D95|PHP code changes
+ javascript|F7DF1E|JavaScript code changes
+ typescript|3178C6|TypeScript code changes
+ python|3776AB|Python code changes
+ css|1572B6|CSS/styling changes
+ html|E34F26|HTML template changes
+ documentation|0075CA|Documentation changes
+ ci-cd|000000|CI/CD pipeline changes
+ docker|2496ED|Docker configuration changes
+ tests|00FF00|Test suite changes
+ security|FF0000|Security-related changes
+ dependencies|0366D6|Dependency updates
+ config|F9D0C4|Configuration file changes
+ build|FFA500|Build system changes
+ automation|8B4513|Automated processes or scripts
+ mokostandards|B60205|MokoStandards compliance
+ needs-review|FBCA04|Awaiting code review
+ work-in-progress|D93F0B|Work in progress, not ready for merge
+ breaking-change|D73A4A|Breaking API or functionality change
+ priority: critical|B60205|Critical priority, must be addressed immediately
+ priority: high|D93F0B|High priority
+ priority: medium|FBCA04|Medium priority
+ priority: low|0E8A16|Low priority
+ type: bug|D73A4A|Something isn't working
+ type: feature|A2EEEF|New feature or request
+ type: enhancement|84B6EB|Enhancement to existing feature
+ type: refactor|F9D0C4|Code refactoring
+ type: chore|FEF2C0|Maintenance tasks
+ type: version|0E8A16|Version-related change
+ status: pending|FBCA04|Pending action or decision
+ status: in-progress|0E8A16|Currently being worked on
+ status: blocked|B60205|Blocked by another issue or dependency
+ status: on-hold|D4C5F9|Temporarily on hold
+ status: wontfix|FFFFFF|This will not be worked on
+ size/xs|C5DEF5|Extra small change (1-10 lines)
+ size/s|6FD1E2|Small change (11-30 lines)
+ size/m|F9DD72|Medium change (31-100 lines)
+ size/l|FFA07A|Large change (101-300 lines)
+ size/xl|FF6B6B|Extra large change (301-1000 lines)
+ size/xxl|B60205|Extremely large change (1000+ lines)
+ health: excellent|0E8A16|Health score 90-100
+ health: good|FBCA04|Health score 70-89
+ health: fair|FFA500|Health score 50-69
+ health: poor|FF6B6B|Health score below 50
+ standards-update|B60205|MokoStandards sync update
+ standards-drift|FBCA04|Repository drifted from MokoStandards
+ sync-report|0075CA|Bulk sync run report
+ sync-failure|D73A4A|Bulk sync failure requiring attention
+ push-failure|D73A4A|File push failure requiring attention
+ health-check|0E8A16|Repository health check results
+ version-drift|FFA500|Version mismatch detected
+ deploy-failure|CC0000|Automated deploy failure tracking
+ template-validation-failure|D73A4A|Template workflow validation failure
+ version|0E8A16|Version bump or release
+ LABELS
+
+ echo "✅ Standard labels created" >> $GITHUB_STEP_SUMMARY
+
+ # ── BRANCH CLEANUP ───────────────────────────────────────────────────
+ - name: Delete old sync branches
+ if: steps.tasks.outputs.clean_branches == 'true'
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ REPO="${{ github.repository }}"
+ CURRENT="chore/sync-mokostandards-v04.05"
+ echo "## 🌿 Branch Cleanup" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ FOUND=false
+ curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/branches?per_page=100" | jq -r '.[].name' 2>/dev/null | \
+ grep "^chore/sync-mokostandards" | \
+ grep -v "^${CURRENT}$" | while read -r branch; do
+ gh pr list --repo "$REPO" --head "$branch" --state open --json number 2>/dev/null | jq -r '.[].number' | while read -r pr; do
+ gh pr close "$pr" --repo "$REPO" --comment "Superseded by \`${CURRENT}\`" 2>/dev/null || true
+ echo " Closed PR #${pr}" >> $GITHUB_STEP_SUMMARY
+ done
+ gh api -X DELETE "repos/${REPO}/git/refs/heads/${branch}" --silent 2>/dev/null || true
+ echo " Deleted: \`${branch}\`" >> $GITHUB_STEP_SUMMARY
+ FOUND=true
+ done
+
+ if [ "$FOUND" != "true" ]; then
+ echo "✅ No old sync branches found" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # ── WORKFLOW RUN CLEANUP ─────────────────────────────────────────────
+ - name: Clean up workflow runs
+ if: steps.tasks.outputs.clean_workflows == 'true'
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ REPO="${{ github.repository }}"
+ echo "## 🔄 Workflow Run Cleanup" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ DELETED=0
+ # Delete cancelled and stale workflow runs
+ for status in cancelled stale; do
+ curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/actions/runs?status=${status}&per_page=100" 2>/dev/null \
+ 2>/dev/null | jq -r '.workflow_runs[].id' | while read -r run_id; do
+ gh api -X DELETE "repos/${REPO}/actions/runs/${run_id}" --silent 2>/dev/null || true
+ DELETED=$((DELETED+1))
+ done
+ done
+
+ echo "✅ Cleaned cancelled/stale workflow runs" >> $GITHUB_STEP_SUMMARY
+
+ # ── LOG CLEANUP ──────────────────────────────────────────────────────
+ - name: Delete old workflow run logs
+ if: steps.tasks.outputs.clean_logs == 'true'
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ REPO="${{ github.repository }}"
+ CUTOFF=$(date -u -d '30 days ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-30d +%Y-%m-%dT%H:%M:%SZ)
+ echo "## 📋 Log Cleanup" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "Deleting logs older than: ${CUTOFF}" >> $GITHUB_STEP_SUMMARY
+
+ DELETED=0
+ curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/actions/runs?created=<${CUTOFF}&per_page=100" 2>/dev/null \
+ 2>/dev/null | jq -r '.workflow_runs[].id' | while read -r run_id; do
+ gh api -X DELETE "repos/${REPO}/actions/runs/${run_id}/logs" --silent 2>/dev/null || true
+ DELETED=$((DELETED+1))
+ done
+
+ echo "✅ Cleaned old workflow run logs" >> $GITHUB_STEP_SUMMARY
+
+ # ── ISSUE TEMPLATE FIX ──────────────────────────────────────────────
+ - name: Strip copyright headers from issue templates
+ if: steps.tasks.outputs.fix_templates == 'true'
+ run: |
+ echo "## 📋 Issue Template Cleanup" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ FIXED=0
+ for f in .github/ISSUE_TEMPLATE/*.md; do
+ [ -f "$f" ] || continue
+ if grep -q '^$/d' "$f"
+ echo " Cleaned: \`$(basename $f)\`" >> $GITHUB_STEP_SUMMARY
+ FIXED=$((FIXED+1))
+ fi
+ done
+
+ if [ "$FIXED" -gt 0 ]; then
+ git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
+ git config --local user.name "gitea-actions[bot]"
+ git add .github/ISSUE_TEMPLATE/
+ git commit -m "fix: strip copyright comment blocks from issue templates [skip ci]" \
+ --author="gitea-actions[bot] "
+ git push
+ echo "✅ ${FIXED} template(s) cleaned and committed" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ No templates need cleaning" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # ── REBUILD DOC INDEXES ─────────────────────────────────────────────
+ - name: Rebuild docs/ index files
+ if: steps.tasks.outputs.rebuild_indexes == 'true'
+ run: |
+ echo "## 📚 Documentation Index Rebuild" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ ! -d "docs" ]; then
+ echo "⏭️ No docs/ directory — skipping" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
+ UPDATED=0
+ # Generate index.md for each docs/ subdirectory
+ find docs -type d | while read -r dir; do
+ INDEX="${dir}/index.md"
+ FILES=$(find "$dir" -maxdepth 1 -name "*.md" ! -name "index.md" -printf "- [%f](./%f)\n" 2>/dev/null | sort)
+ if [ -z "$FILES" ]; then
+ continue
+ fi
+
+ cat > "$INDEX" << INDEXEOF
+ # $(basename "$dir")
+
+ ## Documents
+
+ ${FILES}
+
+ ---
+ *Auto-generated by repository-cleanup workflow*
+ INDEXEOF
+ # Dedent
+ sed -i 's/^ //' "$INDEX"
+ UPDATED=$((UPDATED+1))
+ done
+
+ if [ "$UPDATED" -gt 0 ]; then
+ git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
+ git config --local user.name "gitea-actions[bot]"
+ git add docs/
+ if ! git diff --cached --quiet; then
+ git commit -m "docs: rebuild documentation indexes [skip ci]" \
+ --author="gitea-actions[bot] "
+ git push
+ echo "✅ ${UPDATED} index file(s) rebuilt and committed" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ All indexes already up to date" >> $GITHUB_STEP_SUMMARY
+ fi
+ else
+ echo "✅ No indexes to rebuild" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # ── VERSION DRIFT DETECTION ──────────────────────────────────────────
+ - name: Check for version drift
+ run: |
+ echo "## 📦 Version Drift Check" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ ! -f "README.md" ]; then
+ echo "⏭️ No README.md — skipping" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
+ README_VERSION=$(grep -oP '^\s*VERSION:\s*\K[0-9]{2}\.[0-9]{2}\.[0-9]{2}' README.md 2>/dev/null | head -1)
+ if [ -z "$README_VERSION" ]; then
+ echo "⚠️ No VERSION found in README.md FILE INFORMATION block" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
+ echo "**README version:** \`${README_VERSION}\`" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ DRIFT=0
+ CHECKED=0
+
+ # Check all files with FILE INFORMATION blocks
+ while IFS= read -r -d '' file; do
+ FILE_VERSION=$(grep -oP '^\s*\*?\s*VERSION:\s*\K[0-9]{2}\.[0-9]{2}\.[0-9]{2}' "$file" 2>/dev/null | head -1)
+ [ -z "$FILE_VERSION" ] && continue
+ CHECKED=$((CHECKED+1))
+ if [ "$FILE_VERSION" != "$README_VERSION" ]; then
+ echo " ⚠️ \`${file}\`: \`${FILE_VERSION}\` (expected \`${README_VERSION}\`)" >> $GITHUB_STEP_SUMMARY
+ DRIFT=$((DRIFT+1))
+ fi
+ done < <(find . -maxdepth 4 -type f \( -name "*.php" -o -name "*.md" -o -name "*.yml" \) ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" -print0 2>/dev/null)
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ if [ "$DRIFT" -gt 0 ]; then
+ echo "⚠️ **${DRIFT}** file(s) out of ${CHECKED} have version drift" >> $GITHUB_STEP_SUMMARY
+ echo "Run \`sync-version-on-merge\` workflow or update manually" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ All ${CHECKED} file(s) match README version \`${README_VERSION}\`" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # ── PROTECT CUSTOM WORKFLOWS ────────────────────────────────────────
+ - name: Ensure custom workflow directory exists
+ run: |
+ echo "## 🔧 Custom Workflows" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ ! -d ".github/workflows/custom" ]; then
+ mkdir -p .github/workflows/custom
+ cat > .github/workflows/custom/README.md << 'CWEOF'
+ # Custom Workflows
+
+ Place repo-specific workflows here. Files in this directory are:
+ - **Never overwritten** by MokoStandards bulk sync
+ - **Never deleted** by the repository-cleanup workflow
+ - Safe for custom CI, notifications, or repo-specific automation
+
+ Synced workflows live in `.github/workflows/` (parent directory).
+ CWEOF
+ sed -i 's/^ //' .github/workflows/custom/README.md
+ git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
+ git config --local user.name "gitea-actions[bot]"
+ git add .github/workflows/custom/
+ if ! git diff --cached --quiet; then
+ git commit -m "chore: create .github/workflows/custom/ for repo-specific workflows [skip ci]" \
+ --author="gitea-actions[bot] "
+ git push
+ echo "✅ Created \`.github/workflows/custom/\` directory" >> $GITHUB_STEP_SUMMARY
+ fi
+ else
+ CUSTOM_COUNT=$(find .github/workflows/custom -name "*.yml" -o -name "*.yaml" 2>/dev/null | wc -l)
+ echo "✅ Custom workflow directory exists (${CUSTOM_COUNT} workflow(s))" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # ── DELETE CLOSED ISSUES ──────────────────────────────────────────────
+ - name: Delete old closed issues
+ if: steps.tasks.outputs.delete_closed_issues == 'true'
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ REPO="${{ github.repository }}"
+ CUTOFF=$(date -u -d '30 days ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -v-30d +%Y-%m-%dT%H:%M:%SZ)
+ echo "## 🗑️ Closed Issue Cleanup" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "Deleting issues closed before: ${CUTOFF}" >> $GITHUB_STEP_SUMMARY
+
+ DELETED=0
+ curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/issues?state=closed&since=1970-01-01T00:00:00Z&per_page=100&sort=updated&direction=asc" 2>/dev/null \
+ | jq -r ".[] | select(.closed_at < \"${CUTOFF}\") | .number" 2>/dev/null | while read -r num; do
+ # Lock and close with "not_planned" to mark as cleaned up
+ curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/issues/${num}/lock" 2>/dev/null -X PUT -f lock_reason="resolved" --silent 2>/dev/null || true
+ echo " Locked issue #${num}" >> $GITHUB_STEP_SUMMARY
+ DELETED=$((DELETED+1))
+ done
+
+ if [ "$DELETED" -eq 0 ] 2>/dev/null; then
+ echo "✅ No old closed issues found" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ Locked ${DELETED} old closed issue(s)" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ - name: Summary
+ if: always()
+ run: |
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "---" >> $GITHUB_STEP_SUMMARY
+ echo "*Run by @${{ github.actor }} — trigger: ${{ github.event_name }}*" >> $GITHUB_STEP_SUMMARY
diff --git a/.github/workflows/standards-compliance.yml b/.github/workflows/standards-compliance.yml
new file mode 100644
index 0000000..bcc037a
--- /dev/null
+++ b/.github/workflows/standards-compliance.yml
@@ -0,0 +1,2598 @@
+# Copyright (C) 2026 Moko Consulting
+# SPDX-License-Identifier: GPL-3.0-or-later
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow
+# INGROUP: MokoStandards.Compliance
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /.github/workflows/standards-compliance.yml
+# VERSION: 04.06.00
+# BRIEF: MokoStandards compliance validation workflow
+# NOTE: Validates repository structure, documentation, and coding standards
+
+name: Standards Compliance
+
+# ╔════════════════════════════════════════════════════════════════════════╗
+# ║ MOKOSTANDARDS COMPLIANCE WORKFLOW ║
+# ╠════════════════════════════════════════════════════════════════════════╣
+# ║ ║
+# ║ 28 checks across 4 priority tiers: ║
+# ║ ║
+# ║ TIER 1 — CRITICAL (must pass) ║
+# ║ secret-scanning, license-compliance, repository-structure, ║
+# ║ coding-standards, version-consistency ║
+# ║ ║
+# ║ TIER 2 — IMPORTANT (should pass) ║
+# ║ workflow-validation, documentation-quality, readme-completeness, ║
+# ║ git-hygiene, script-integrity ║
+# ║ ║
+# ║ TIER 3 — QUALITY (code metrics) ║
+# ║ line-length, file-naming, insecure-patterns, complexity, ║
+# ║ duplication, dead-code ║
+# ║ ║
+# ║ TIER 4 — SUPPLEMENTARY (informational) ║
+# ║ file-size, binary, todo, deps, links, api-docs, accessibility, ║
+# ║ performance, enterprise, health, terraform ║
+# ║ ║
+# ║ File size: warning >15MB, critical >20MB ║
+# ║ Exempt: .mmdb, .woff2, .woff, .ttf, .otf ║
+# ║ ║
+# ╚════════════════════════════════════════════════════════════════════════╝
+
+env:
+ WORKFLOW_VERSION: "04.04.01"
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
+
+# MokoStandards Policy Compliance:
+# - File formatting: Enforces organizational coding standards
+# - Reference: docs/policy/file-formatting.md
+
+# ┌─────────────────────────────────────────────────────────────────────────┐
+# │ WORKFLOW FLOW DIAGRAM │
+# └─────────────────────────────────────────────────────────────────────────┘
+#
+# TRIGGER: Push/PR to main/dev/rc branches
+# │
+# ▼
+# ┌──────────────────────────────────────────────────────────────┐
+# │ PARALLEL VALIDATION CHECKS │
+# └──────────────────────────────────────────────────────────────┘
+# │
+# ├─────────────┬──────────────┬──────────────┬────────────┐
+# ▼ ▼ ▼ ▼ ▼
+# ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐
+# │Repository │File Header │Code Style│ │ Docs │ │ License │
+# │Structure│ │ Validation│ │ Check │ │ Check │ │ Check │
+# └─────────┘ └──────────┘ └──────────┘ └─────────┘ └──────────┘
+# │ │ │ │ │
+# ▼ ▼ ▼ ▼ ▼
+# ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐
+# │ Check │ │ Verify │ │ Run │ │ Check │ │ Verify │
+# │Required │ │Copyright │ │ Linters │ │README │ │SPDX-ID │
+# │ Dirs │ │ Header │ │(Python, │ │ Exists │ │ Present │
+# │ │ │ Format │ │PHP,YAML) │ │ │ │ │
+# └─────────┘ └──────────┘ └──────────┘ └─────────┘ └──────────┘
+# │ │ │ │ │
+# └─────────────┴──────────────┴──────────────┴────────────┘
+# │
+# ▼
+# ┌──────────────────┐
+# │ All Checks Pass?│
+# └──────────────────┘
+# │ │
+# YES │ │ NO
+# ▼ ▼
+# ┌──────────┐ ┌──────────────┐
+# │ SUCCESS │ │ CREATE ISSUE │
+# │ Summary │ │ with Failure │
+# └──────────┘ │ Details │
+# └──────────────┘
+
+on:
+ push:
+ branches: [main, dev/**, rc/**, version/**]
+ pull_request:
+ branches: [main, dev/**, rc/**]
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pull-requests: write
+ issues: write
+
+jobs:
+ # ════════════════════════════════════════════════════════════════════════
+ # TIER 1 — CRITICAL (must pass, blocks merge)
+ # ════════════════════════════════════════════════════════════════════════
+ secret-scanning:
+ name: Secret Scanning
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Scan for Secrets
+ run: |
+ set -x
+ echo "## 🔒 Secret Scanning" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "Scanning for hardcoded secrets and credentials." >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Define secret patterns
+ VIOLATIONS=0
+
+ # Check for common secret patterns
+ echo "### Secret Patterns" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Helper: scan with a pattern, show results with file:line, return count
+ scan_pattern() {
+ local label="$1" icon="$2" tmpfile="$3"
+ local count=0
+ if [ -f "$tmpfile" ]; then
+ count=$(wc -l < "$tmpfile")
+ fi
+ if [ "$count" -gt 0 ]; then
+ echo "${icon} **${label}**: ${count} finding(s)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View locations " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| File | Line | Match |" >> $GITHUB_STEP_SUMMARY
+ echo "|------|------|-------|" >> $GITHUB_STEP_SUMMARY
+ head -20 "$tmpfile" | while IFS= read -r line; do
+ FILE=$(echo "$line" | cut -d: -f1 | sed 's|^\./||')
+ LINENO=$(echo "$line" | cut -d: -f2)
+ MATCH=$(echo "$line" | cut -d: -f3- | head -c 80 | sed 's/|/\\|/g')
+ echo "| \`${FILE}\` | ${LINENO} | \`${MATCH}\` |" >> $GITHUB_STEP_SUMMARY
+ done
+ if [ "$count" -gt 20 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "*... and $((count - 20)) more*" >> $GITHUB_STEP_SUMMARY
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ VIOLATIONS=$((VIOLATIONS + count))
+ fi
+ }
+
+ # Pattern 1: password/secret assignments
+ grep -r -n -E "(password|passwd|pwd|secret|api[_-]?key|token).*=.*['\"]" . \
+ --include="*.php" --include="*.py" --include="*.js" --include="*.ts" \
+ --exclude-dir=".git" --exclude-dir="vendor" --exclude-dir="node_modules" 2>/dev/null | \
+ grep -v -E '(test|example|sample|getenv|getString|getArgument|config\[|/\.\*/|^\s*//|^\s*\*|CREDENTIAL_PATTERNS|SecurityValidator|SECRET_PATTERN|===|!==|ApiClient|str_contains|gen_wrappers)' | \
+ grep -v "= ''" | grep -v '= ""' | grep -v '\$this->config' | \
+ grep -v 'type="password"' | grep -v 'type="text"' | grep -v 'name="password"' | grep -v 'name="secretkey"' | \
+ grep -v ' /tmp/secrets1.txt 2>/dev/null || true
+ scan_pattern "Secret assignments" "⚠️" /tmp/secrets1.txt
+
+ # Pattern 2: Private keys
+ grep -r -n "BEGIN.*PRIVATE KEY" . \
+ --include="*.pem" --include="*.key" --include="*.txt" \
+ --exclude-dir=".git" --exclude-dir="vendor" --exclude-dir="node_modules" 2>/dev/null > /tmp/secrets2.txt || true
+ scan_pattern "Private keys" "❌" /tmp/secrets2.txt
+
+ # Pattern 3: AWS keys
+ grep -r -n -E "AKIA[0-9A-Z]{16}" . \
+ --include="*.php" --include="*.py" --include="*.js" --include="*.txt" --include="*.env" \
+ --exclude-dir=".git" --exclude-dir="vendor" --exclude-dir="node_modules" 2>/dev/null > /tmp/secrets3.txt || true
+ scan_pattern "AWS access keys" "❌" /tmp/secrets3.txt
+
+ # Pattern 4: GitHub tokens
+ grep -r -n -E "gh[ps]_[a-zA-Z0-9]{36}" . \
+ --include="*.php" --include="*.py" --include="*.js" --include="*.txt" --include="*.env" \
+ --exclude-dir=".git" --exclude-dir="vendor" --exclude-dir="node_modules" 2>/dev/null > /tmp/secrets4.txt || true
+ scan_pattern "GitHub tokens" "❌" /tmp/secrets4.txt
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$VIOLATIONS" -gt 0 ]; then
+ echo "**Total Violations**: $VIOLATIONS" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View detected secrets (file paths only) " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ cat /tmp/secrets*.txt 2>/dev/null | cut -d: -f1 | sort -u >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required**: Remove hardcoded secrets immediately!" >> $GITHUB_STEP_SUMMARY
+ echo "Use environment variables or secrets management instead." >> $GITHUB_STEP_SUMMARY
+ exit 1
+ else
+ echo "✅ No hardcoded secrets detected" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ license-compliance:
+ name: License Header Validation
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check SPDX Headers
+ run: |
+ set -x
+ echo "### SPDX License Header Check" >> $GITHUB_STEP_SUMMARY
+
+ # Count source files with and without SPDX headers
+ TOTAL_PHP=0
+ WITH_SPDX_PHP=0
+
+ if find . -name "*.php" -type f ! -path "./vendor/*" | head -1 | grep -q .; then
+ TOTAL_PHP=$(find . -name "*.php" -type f ! -path "./vendor/*" | wc -l)
+ WITH_SPDX_PHP=$(find . -name "*.php" -type f ! -path "./vendor/*" -exec grep -l "SPDX-License-Identifier" {} \; | wc -l)
+ fi
+
+ if [ "$TOTAL_PHP" -gt 0 ]; then
+ PERCENT=$((WITH_SPDX_PHP * 100 / TOTAL_PHP))
+ echo "- PHP files: $WITH_SPDX_PHP/$TOTAL_PHP ($PERCENT%) with SPDX headers" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$PERCENT" -lt 80 ]; then
+ echo "⚠️ Less than 80% of PHP files have SPDX headers" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ Good SPDX header coverage" >> $GITHUB_STEP_SUMMARY
+ fi
+ fi
+
+ - name: Validate License File
+ run: |
+ set -x
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### License File Validation" >> $GITHUB_STEP_SUMMARY
+
+ if [ ! -f "LICENSE" ]; then
+ echo "❌ LICENSE file not found" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ❌ Validation Failed: LICENSE File Missing" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Error:** LICENSE file is required for all MokoStandards-compliant repositories" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required:** Add LICENSE file with appropriate open-source license (GPL-3.0-or-later recommended)" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "❌ ERROR: LICENSE file not found - This is a critical requirement"
+ exit 1
+ fi
+
+ # Check license type
+ if grep -qi "GNU GENERAL PUBLIC LICENSE" LICENSE; then
+ VERSION=$(grep -i "Version 3" LICENSE || echo "")
+ if [ -n "$VERSION" ]; then
+ echo "✅ GPL-3.0-or-later license detected" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "⚠️ GPL license detected but version unclear" >> $GITHUB_STEP_SUMMARY
+ fi
+ elif grep -qi "MIT License" LICENSE; then
+ echo "✅ MIT license detected" >> $GITHUB_STEP_SUMMARY
+ elif grep -qi "Apache License" LICENSE; then
+ echo "✅ Apache license detected" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "ℹ️ License type could not be automatically detected" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ repository-structure:
+ name: Repository Structure Validation
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check Required Directories
+ run: |
+ set -x
+ echo "## 📁 Repository Structure Validation" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ MISSING=0
+ PRESENT=0
+ TOTAL=2
+
+ echo "### Required Directories" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| Directory | Status | Files | Size | Notes |" >> $GITHUB_STEP_SUMMARY
+ echo "|-----------|--------|-------|------|-------|" >> $GITHUB_STEP_SUMMARY
+
+ # Check required directories
+ for dir in docs .github; do
+ if [ -d "$dir" ]; then
+ FILE_COUNT=$(find "$dir" -type f 2>/dev/null | wc -l)
+ DIR_SIZE=$(du -sh "$dir" 2>/dev/null | cut -f1)
+ echo "| $dir/ | ✅ Pass | $FILE_COUNT files | $DIR_SIZE | Complete |" >> $GITHUB_STEP_SUMMARY
+ PRESENT=$((PRESENT + 1))
+ else
+ echo "| $dir/ | ❌ **Missing** | - | - | **Action Required** |" >> $GITHUB_STEP_SUMMARY
+ MISSING=$((MISSING + 1))
+ fi
+ done
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ PERCENT=$((PRESENT * 100 / TOTAL))
+ echo "**Compliance Score:** $PERCENT% ($PRESENT/$TOTAL directories present)" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$MISSING" -gt 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### 🔴 Critical Issues: $MISSING" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Remediation Steps:**" >> $GITHUB_STEP_SUMMARY
+ [ ! -d "docs" ] && echo "- Create docs directory: \`mkdir docs && echo '# Documentation' > docs/README.md\`" >> $GITHUB_STEP_SUMMARY
+ [ ! -d ".github" ] && echo "- Create .github directory: \`mkdir -p .github/workflows\`" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "📚 Reference: [MokoStandards Repository Structure](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/tree/main/docs/policy/core-structure.md)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ❌ Validation Failed: Required Directories Missing" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Status:** Repository structure does not meet MokoStandards requirements" >> $GITHUB_STEP_SUMMARY
+ echo "**Missing:** $MISSING required director(y|ies)" >> $GITHUB_STEP_SUMMARY
+ echo "**Compliance:** $PERCENT% ($PRESENT/$TOTAL directories present)" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "❌ ERROR: Required directories missing - See job summary for remediation steps"
+ exit 1
+ fi
+
+ - name: Check Required Files
+ run: |
+ set -x
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### Required Files" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ MISSING=0
+ PRESENT=0
+ TOTAL=5
+
+ echo "| File | Status | Size | Last Modified | Notes |" >> $GITHUB_STEP_SUMMARY
+ echo "|------|--------|------|---------------|-------|" >> $GITHUB_STEP_SUMMARY
+
+ # Check required files (CHANGELOG handled separately via find -iname to support src/ChangeLog.md)
+ for file in README.md LICENSE CONTRIBUTING.md SECURITY.md .editorconfig; do
+ if [ -f "$file" ]; then
+ FILE_SIZE=$(wc -c < "$file" 2>/dev/null | awk '{printf "%.1f KB", $1/1024}')
+ LAST_MOD=$(stat -c %y "$file" 2>/dev/null | cut -d' ' -f1 || echo "Unknown")
+ CONTENT_CHECK=""
+
+ # Basic content validation
+ case "$file" in
+ "README.md")
+ LINES=$(wc -l < "$file")
+ [ "$LINES" -lt 10 ] && CONTENT_CHECK="⚠️ Too short"
+ ;;
+ "LICENSE")
+ [ $(wc -c < "$file") -lt 100 ] && CONTENT_CHECK="⚠️ Incomplete?"
+ ;;
+ esac
+
+ echo "| $file | ✅ Pass | $FILE_SIZE | $LAST_MOD | Complete $CONTENT_CHECK |" >> $GITHUB_STEP_SUMMARY
+ PRESENT=$((PRESENT + 1))
+ else
+ echo "| $file | ❌ **Missing** | - | - | **Required** |" >> $GITHUB_STEP_SUMMARY
+ MISSING=$((MISSING + 1))
+ fi
+ done
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ PERCENT=$((PRESENT * 100 / TOTAL))
+ echo "**Compliance Score:** $PERCENT% ($PRESENT/$TOTAL files present)" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$MISSING" -gt 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### 🔴 Critical Issues: $MISSING" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Remediation Steps:**" >> $GITHUB_STEP_SUMMARY
+ [ ! -f "README.md" ] && echo "- Create README.md: Use [template](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/tree/main/templates/docs/required/README.md)" >> $GITHUB_STEP_SUMMARY
+ [ ! -f "LICENSE" ] && echo "- Add LICENSE file: Choose from [OSI-approved licenses](https://opensource.org/licenses)" >> $GITHUB_STEP_SUMMARY
+ [ ! -f "CONTRIBUTING.md" ] && echo "- Create CONTRIBUTING.md: Use [template](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/tree/main/templates/docs/required/CONTRIBUTING.md)" >> $GITHUB_STEP_SUMMARY
+ [ ! -f "SECURITY.md" ] && echo "- Create SECURITY.md: Use [template](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/tree/main/templates/docs/required/SECURITY.md)" >> $GITHUB_STEP_SUMMARY
+ [ ! -f ".editorconfig" ] && echo "- Add .editorconfig: Use [template](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/tree/main/templates/.editorconfig)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "📚 Reference: [MokoStandards File Requirements](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/tree/main/docs/policy/file-header-standards.md)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ❌ Validation Failed: Required Files Missing" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Status:** Repository files do not meet MokoStandards requirements" >> $GITHUB_STEP_SUMMARY
+ echo "**Missing:** $MISSING required file(s)" >> $GITHUB_STEP_SUMMARY
+ echo "**Compliance:** $PERCENT% ($PRESENT/$TOTAL files present)" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "❌ ERROR: Required files missing - See job summary for remediation steps"
+ exit 1
+ fi
+
+ coding-standards:
+ name: Coding Standards Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check for Tab Characters
+ run: |
+ set -x
+ echo "### Tab Character Detection" >> $GITHUB_STEP_SUMMARY
+
+ # Policy: Tabs are DEFAULT. Only check for tabs in files that REQUIRE spaces.
+ # Languages requiring spaces: YAML, Python, Haskell, F#, CoffeeScript, Nim, JSON, RST
+ TABS_IN_SPACES_FILES=$(find . -type f \
+ \( -name "*.yml" -o -name "*.yaml" \
+ -o -name "*.py" \
+ -o -name "*.hs" -o -name "*.lhs" \
+ -o -name "*.fs" -o -name "*.fsx" -o -name "*.fsi" \
+ -o -name "*.coffee" -o -name "*.litcoffee" \
+ -o -name "*.nim" -o -name "*.nims" -o -name "*.nimble" \
+ -o -name "*.json" \
+ -o -name "*.rst" \) \
+ ! -path "./vendor/*" \
+ ! -path "./node_modules/*" \
+ ! -path "./.git/*" \
+ -exec grep -l $'\t' {} \; 2>/dev/null | head -10)
+
+ if [ -n "$TABS_IN_SPACES_FILES" ]; then
+ echo "⚠️ Tab characters found in files that require spaces:" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "$TABS_IN_SPACES_FILES" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "These languages require spaces (tabs will break): YAML, Python, Haskell, F#, CoffeeScript, Nim, JSON, RST" >> $GITHUB_STEP_SUMMARY
+ echo "All other files (including .md, .ps1, LICENSE, etc.) may use tabs per MokoStandards policy" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ No tabs found in files requiring spaces" >> $GITHUB_STEP_SUMMARY
+ echo "Note: Tabs are allowed in most files (policy default). Only checked files requiring spaces." >> $GITHUB_STEP_SUMMARY
+ fi
+
+ - name: Check File Encoding
+ run: |
+ set -x
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### File Encoding Check" >> $GITHUB_STEP_SUMMARY
+
+ # Check for UTF-8 encoding (ASCII is a subset of UTF-8 and is acceptable)
+ NON_UTF8=$(find . -type f \( -name "*.php" -o -name "*.js" -o -name "*.md" \) \
+ ! -path "./vendor/*" \
+ ! -path "./node_modules/*" \
+ ! -path "./.git/*" \
+ -exec file {} \; | grep -v "UTF-8" | grep -v "ASCII" | head -5)
+
+ if [ -n "$NON_UTF8" ]; then
+ echo "⚠️ Non-UTF-8 files detected:" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "$NON_UTF8" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ All source files appear to be UTF-8 encoded" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ - name: Check Line Endings
+ run: |
+ set -x
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### Line Ending Check" >> $GITHUB_STEP_SUMMARY
+
+ # Check for CRLF line endings
+ CRLF_FILES=$(find . -type f \( -name "*.php" -o -name "*.js" -o -name "*.md" \) \
+ ! -path "./vendor/*" \
+ ! -path "./node_modules/*" \
+ ! -path "./.git/*" \
+ -exec file {} \; | grep "CRLF" | head -5)
+
+ if [ -n "$CRLF_FILES" ]; then
+ echo "⚠️ Files with CRLF line endings found:" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "$CRLF_FILES" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "MokoStandards requires LF line endings" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ Line endings are consistent (LF)" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ version-consistency:
+ name: Version Consistency Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Set up PHP
+ run: |
+ php -v && composer --version
+
+ - name: Setup MokoStandards tools
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GA_TOKEN || github.token }}"}}'
+ run: |
+ git clone --depth 1 --branch version/04 --quiet \
+ "https://x-access-token:${GH_TOKEN}@git.mokoconsulting.tech/MokoConsulting/MokoStandards.git" \
+ /tmp/mokostandards 2>/dev/null || true
+ if [ -d "/tmp/mokostandards" ] && [ -f "/tmp/mokostandards/composer.json" ]; then
+ cd /tmp/mokostandards
+ composer install --no-dev --no-interaction --quiet 2>/dev/null || true
+ fi
+
+ - name: Run Version Consistency Check
+ id: version_check
+ run: |
+ set -x
+ echo "## 🔢 Version Consistency Validation" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Use MokoStandards tools (no Composer needed on the governed repo)
+ if [ -f "/tmp/mokostandards/api/validate/check_version_consistency.php" ]; then
+ php /tmp/mokostandards/api/validate/check_version_consistency.php --path . --verbose 2>&1 | tee /tmp/version-check.log
+ EXIT_CODE=${PIPESTATUS[0]}
+ elif [ -f "api/validate/check_version_consistency.php" ]; then
+ php api/validate/check_version_consistency.php --path . --verbose 2>&1 | tee /tmp/version-check.log
+ EXIT_CODE=${PIPESTATUS[0]}
+ else
+ echo "⏭️ MokoStandards tools not available — skipping version check" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
+ echo '```' >> $GITHUB_STEP_SUMMARY
+ cat /tmp/version-check.log >> $GITHUB_STEP_SUMMARY
+ echo '```' >> $GITHUB_STEP_SUMMARY
+
+ if [ "$EXIT_CODE" -eq 0 ]; then
+ echo "✅ All version numbers are consistent" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "❌ Version drift detected" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ fi
+
+
+ # ════════════════════════════════════════════════════════════════════════
+ # TIER 2 — IMPORTANT (should pass)
+ # ════════════════════════════════════════════════════════════════════════
+ workflow-validation:
+ name: Workflow Configuration Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check Required Workflows
+ run: |
+ set -x
+ echo "### GitHub Actions Workflows" >> $GITHUB_STEP_SUMMARY
+
+ WORKFLOWS_DIR=".github/workflows"
+
+ if [ ! -d "$WORKFLOWS_DIR" ]; then
+ echo "❌ No workflows directory found" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ❌ Validation Failed: Workflows Directory Missing" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Error:** .github/workflows directory is required for CI/CD automation" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required:** Create .github/workflows directory and add GitHub Actions workflows" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "❌ ERROR: .github/workflows directory not found"
+ exit 1
+ fi
+
+ # Check for recommended workflows
+ CI_FOUND=false
+ for wf in ci.yml build.yml ci-dolibarr.yml ci-joomla.yml; do
+ if [ -f "$WORKFLOWS_DIR/$wf" ]; then
+ echo "✅ CI workflow present ($wf)" >> $GITHUB_STEP_SUMMARY
+ CI_FOUND=true
+ break
+ fi
+ done
+ if [ "$CI_FOUND" = "false" ]; then
+ echo "⚠️ No CI workflow found (ci.yml, build.yml, ci-dolibarr.yml, or ci-joomla.yml)" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ if [ -f "$WORKFLOWS_DIR/codeql-analysis.yml" ]; then
+ echo "✅ CodeQL security scanning present" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "⚠️ CodeQL workflow not found" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Check for MokoStandards-synced workflows
+ for wf in deploy-dev.yml deploy-demo.yml deploy-rs.yml sync-version-on-merge.yml auto-release.yml standards-compliance.yml enterprise-firewall-setup.yml; do
+ if [ -f "$WORKFLOWS_DIR/$wf" ]; then
+ echo "✅ ${wf}" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "⚠️ ${wf} not found (synced from MokoStandards)" >> $GITHUB_STEP_SUMMARY
+ fi
+ done
+
+ - name: Validate Workflow Syntax
+ run: |
+ set -x
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### Workflow YAML Syntax" >> $GITHUB_STEP_SUMMARY
+
+ INVALID=0
+ for workflow in $(find .github/workflows -maxdepth 1 -type f \( -name "*.yml" -o -name "*.yaml" \) 2>/dev/null); do
+ if [ -f "$workflow" ]; then
+ if python3 -c "import yaml, sys; yaml.safe_load(open(sys.argv[1]))" "$workflow" 2>/dev/null; then
+ echo "✅ $(basename $workflow)" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "❌ $(basename $workflow) - invalid YAML" >> $GITHUB_STEP_SUMMARY
+ INVALID=$((INVALID + 1))
+ fi
+ fi
+ done
+
+ if [ "$INVALID" -gt 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ❌ Validation Failed: Invalid Workflow YAML Syntax" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Error:** $INVALID workflow file(s) have invalid YAML syntax" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required:** Fix YAML syntax errors in the marked workflow files" >> $GITHUB_STEP_SUMMARY
+ echo "**Tool:** Run \`python3 -c \"import yaml; yaml.safe_load(open('.github/workflows/FILE.yml'))\"\` locally" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "❌ ERROR: $INVALID workflow file(s) with invalid YAML syntax"
+ exit 1
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ✅ All Workflow Files Have Valid YAML Syntax" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "✅ SUCCESS: All workflow files passed YAML validation"
+
+ - name: Validate CodeQL Configuration
+ if: hashFiles('.github/workflows/codeql-analysis.yml') != ''
+ run: |
+ set -e
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### CodeQL Language Configuration" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Inline validation (rewritten from Python to bash for PHP-only architecture)
+ CODEQL_FILE=".github/workflows/codeql-analysis.yml"
+
+ if [ ! -f "$CODEQL_FILE" ]; then
+ echo "⚠️ CodeQL workflow file not found" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ⚠️ CodeQL Workflow Not Found" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Status:** CodeQL workflow file not present - skipping language validation" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "⚠️ INFO: CodeQL workflow not found - Skipping validation"
+ exit 0
+ fi
+
+ echo "**CodeQL Configuration Analysis**" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Extract configured languages from workflow
+ LANGUAGES=$(grep -A5 "language:" "$CODEQL_FILE" | grep -oP "(?<=')[^']+(?=')" | tr '\n' ' ' || echo "")
+
+ # Check if this is a configuration-only scan (no languages specified)
+ if grep -q "category.*language:config" "$CODEQL_FILE"; then
+ echo "**Scan Type:** Configuration-only (no language matrix)" >> $GITHUB_STEP_SUMMARY
+ echo "**Status:** ✅ Valid configuration for PHP-only repository" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "This CodeQL workflow scans YAML, JSON, shell scripts for security issues." >> $GITHUB_STEP_SUMMARY
+ echo "PHP security is handled by SecurityValidator enterprise library." >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "✅ SUCCESS: CodeQL configuration-only scan properly configured"
+ exit 0
+ fi
+
+ if [ -z "$LANGUAGES" ]; then
+ echo "❌ No languages configured in CodeQL workflow" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ❌ Validation Failed: CodeQL Languages Not Configured" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Error:** CodeQL workflow exists but has no languages configured" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required:** Configure appropriate languages in codeql-analysis.yml" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "❌ ERROR: No languages configured in CodeQL workflow"
+ exit 1
+ fi
+
+ echo "**Configured Languages:** $LANGUAGES" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Validate language presence in repository
+ INVALID_LANGS=""
+ VALID_LANGS=""
+
+ for LANG in $LANGUAGES; do
+ case "$LANG" in
+ python)
+ # Check for Python files (should be none in v04.00.04)
+ if find . -name "*.py" -type f ! -path "./.git/*" | grep -q .; then
+ VALID_LANGS="$VALID_LANGS python"
+ echo "✅ Python: Found Python files" >> $GITHUB_STEP_SUMMARY
+ else
+ INVALID_LANGS="$INVALID_LANGS python"
+ echo "❌ Python: No Python files found (PHP-only repository)" >> $GITHUB_STEP_SUMMARY
+ fi
+ ;;
+ javascript|typescript)
+ # Check for JS/TS files
+ if find . \( -name "*.js" -o -name "*.ts" -o -name "*.json" \) -type f ! -path "./.git/*" ! -path "./node_modules/*" | grep -q .; then
+ VALID_LANGS="$VALID_LANGS $LANG"
+ echo "✅ $LANG: Found JavaScript/TypeScript/JSON files" >> $GITHUB_STEP_SUMMARY
+ else
+ INVALID_LANGS="$INVALID_LANGS $LANG"
+ echo "⚠️ $LANG: No JavaScript/TypeScript files found" >> $GITHUB_STEP_SUMMARY
+ fi
+ ;;
+ java)
+ if find . -name "*.java" -type f ! -path "./.git/*" | grep -q .; then
+ VALID_LANGS="$VALID_LANGS java"
+ echo "✅ Java: Found Java files" >> $GITHUB_STEP_SUMMARY
+ else
+ INVALID_LANGS="$INVALID_LANGS java"
+ echo "⚠️ Java: No Java files found" >> $GITHUB_STEP_SUMMARY
+ fi
+ ;;
+ go)
+ if find . -name "*.go" -type f ! -path "./.git/*" | grep -q .; then
+ VALID_LANGS="$VALID_LANGS go"
+ echo "✅ Go: Found Go files" >> $GITHUB_STEP_SUMMARY
+ else
+ INVALID_LANGS="$INVALID_LANGS go"
+ echo "⚠️ Go: No Go files found" >> $GITHUB_STEP_SUMMARY
+ fi
+ ;;
+ cpp|c)
+ if find . \( -name "*.cpp" -o -name "*.c" -o -name "*.h" \) -type f ! -path "./.git/*" | grep -q .; then
+ VALID_LANGS="$VALID_LANGS $LANG"
+ echo "✅ $LANG: Found C/C++ files" >> $GITHUB_STEP_SUMMARY
+ else
+ INVALID_LANGS="$INVALID_LANGS $LANG"
+ echo "⚠️ $LANG: No C/C++ files found" >> $GITHUB_STEP_SUMMARY
+ fi
+ ;;
+ ruby)
+ if find . -name "*.rb" -type f ! -path "./.git/*" | grep -q .; then
+ VALID_LANGS="$VALID_LANGS ruby"
+ echo "✅ Ruby: Found Ruby files" >> $GITHUB_STEP_SUMMARY
+ else
+ INVALID_LANGS="$INVALID_LANGS ruby"
+ echo "⚠️ Ruby: No Ruby files found" >> $GITHUB_STEP_SUMMARY
+ fi
+ ;;
+ *)
+ echo "⚠️ $LANG: Unknown language, skipping validation" >> $GITHUB_STEP_SUMMARY
+ ;;
+ esac
+ done
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Report results
+ if [ -n "$INVALID_LANGS" ]; then
+ echo "**⚠️ Warning:** Some configured languages may not have corresponding files:" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "Invalid languages: $INVALID_LANGS" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Note:** This is informational. CodeQL will skip languages without source files." >> $GITHUB_STEP_SUMMARY
+ echo "For PHP repository (v04.00.04), JavaScript language covers JSON/YAML/shell scripts." >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ **All configured CodeQL languages have corresponding source files**" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Always succeed - this is informational only
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ✅ CodeQL Configuration Validation Complete" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Status:** CodeQL language configuration reviewed successfully" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "✅ SUCCESS: CodeQL validation complete"
+ exit 0
+
+ documentation-quality:
+ name: Documentation Quality Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Validate README.md
+ run: |
+ set -x
+ echo "## 📚 Documentation Quality Check" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### README.md Analysis" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ ! -f "README.md" ]; then
+ echo "❌ **Critical:** README.md not found" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ❌ Validation Failed: README.md Missing" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Error:** README.md is required for all MokoStandards-compliant repositories" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required:** Create README.md with project description, setup instructions, and usage examples" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "❌ ERROR: README.md not found - This is a critical requirement"
+ exit 1
+ fi
+
+ # Detailed content analysis
+ SIZE=$(wc -c < README.md)
+ LINES=$(wc -l < README.md)
+ WORDS=$(wc -w < README.md)
+ HEADINGS=$(grep -c "^#" README.md || echo 0)
+ LINKS=$(grep -c "\[.*\](.*)" README.md || echo 0)
+ CODE_BLOCKS=$(grep -c '```' README.md || echo 0)
+
+ echo "| Metric | Value | Status | Recommendation |" >> $GITHUB_STEP_SUMMARY
+ echo "|--------|-------|--------|----------------|" >> $GITHUB_STEP_SUMMARY
+
+ # Size check
+ SIZE_STATUS="✅ Good"
+ SIZE_REC="Adequate length"
+ if [ "$SIZE" -lt 500 ]; then
+ SIZE_STATUS="⚠️ Warning"
+ SIZE_REC="Add more content (min 500 bytes)"
+ elif [ "$SIZE" -gt 50000 ]; then
+ SIZE_STATUS="⚠️ Warning"
+ SIZE_REC="Consider splitting into multiple docs"
+ fi
+ echo "| Size | $SIZE bytes | $SIZE_STATUS | $SIZE_REC |" >> $GITHUB_STEP_SUMMARY
+
+ # Line count
+ LINES_STATUS="✅ Good"
+ LINES_REC="Good size"
+ if [ "$LINES" -lt 20 ]; then
+ LINES_STATUS="⚠️ Warning"
+ LINES_REC="Add more sections (min 20 lines)"
+ fi
+ echo "| Lines | $LINES | $LINES_STATUS | $LINES_REC |" >> $GITHUB_STEP_SUMMARY
+
+ # Word count
+ WORDS_STATUS="✅ Good"
+ WORDS_REC="Good detail"
+ if [ "$WORDS" -lt 100 ]; then
+ WORDS_STATUS="⚠️ Warning"
+ WORDS_REC="Add more description (min 100 words)"
+ fi
+ echo "| Words | $WORDS | $WORDS_STATUS | $WORDS_REC |" >> $GITHUB_STEP_SUMMARY
+
+ # Headings
+ HEADINGS_STATUS="✅ Good"
+ HEADINGS_REC="Well structured"
+ if [ "$HEADINGS" -lt 3 ]; then
+ HEADINGS_STATUS="⚠️ Warning"
+ HEADINGS_REC="Add more sections (min 3 headings)"
+ fi
+ echo "| Headings | $HEADINGS | $HEADINGS_STATUS | $HEADINGS_REC |" >> $GITHUB_STEP_SUMMARY
+
+ # Links
+ LINKS_STATUS="✅ Good"
+ LINKS_REC="Includes references"
+ if [ "$LINKS" -lt 1 ]; then
+ LINKS_STATUS="ℹ️ Info"
+ LINKS_REC="Consider adding useful links"
+ fi
+ echo "| Links | $LINKS | $LINKS_STATUS | $LINKS_REC |" >> $GITHUB_STEP_SUMMARY
+
+ # Code blocks
+ CODE_STATUS="✅ Good"
+ CODE_REC="Includes examples"
+ if [ "$CODE_BLOCKS" -eq 0 ]; then
+ CODE_STATUS="ℹ️ Info"
+ CODE_REC="Consider adding code examples"
+ fi
+ echo "| Code blocks | $CODE_BLOCKS | $CODE_STATUS | $CODE_REC |" >> $GITHUB_STEP_SUMMARY
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Check for key sections
+ echo "**Section Coverage:**" >> $GITHUB_STEP_SUMMARY
+ MISSING_COUNT=0
+ grep -qi "install\|setup\|getting started" README.md && echo "- ✅ Installation/Setup instructions" >> $GITHUB_STEP_SUMMARY || { echo "- ⚠️ Missing: Installation/Setup" >> $GITHUB_STEP_SUMMARY; MISSING_COUNT=$((MISSING_COUNT + 1)); }
+ grep -qi "usage\|example\|how to" README.md && echo "- ✅ Usage examples" >> $GITHUB_STEP_SUMMARY || { echo "- ⚠️ Missing: Usage examples" >> $GITHUB_STEP_SUMMARY; MISSING_COUNT=$((MISSING_COUNT + 1)); }
+ grep -qi "license" README.md && echo "- ✅ License information" >> $GITHUB_STEP_SUMMARY || { echo "- ⚠️ Missing: License information" >> $GITHUB_STEP_SUMMARY; MISSING_COUNT=$((MISSING_COUNT + 1)); }
+ grep -qi "contribut" README.md && echo "- ✅ Contributing guidelines" >> $GITHUB_STEP_SUMMARY || echo "- ℹ️ Optional: Contributing section" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$MISSING_COUNT" -gt 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**⚠️ $MISSING_COUNT important sections missing**" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ - name: Validate CHANGELOG.md
+ run: |
+ set -x
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### CHANGELOG.md Analysis" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Locate changelog case-insensitively; accepted at root, src/, or docs/
+ CHANGELOG_PATH=$(find . -maxdepth 3 \( -path ./.git -o -path ./node_modules \) -prune \
+ -o -iname "changelog.md" -print | head -1 | sed 's|^\./||')
+
+ if [ -z "$CHANGELOG_PATH" ]; then
+ echo "❌ **Critical:** CHANGELOG.md not found (checked root, src/, docs/)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ❌ Validation Failed: CHANGELOG.md Missing" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Error:** CHANGELOG.md is required for all MokoStandards-compliant repositories" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required:** Create CHANGELOG.md following [Keep a Changelog](https://keepachangelog.com/) format" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "❌ ERROR: CHANGELOG.md not found - This is a critical requirement"
+ exit 1
+ fi
+
+ echo "📄 Found: $CHANGELOG_PATH" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Analyze changelog structure
+ VERSIONS=$(grep -c "## \[" "$CHANGELOG_PATH" || echo 0)
+ UNRELEASED=$(grep -c "## \[Unreleased\]" "$CHANGELOG_PATH" || echo 0)
+ DATES=$(grep -c "[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}" "$CHANGELOG_PATH" || echo 0)
+ SIZE=$(wc -c < "$CHANGELOG_PATH")
+
+ echo "| Metric | Value | Status | Notes |" >> $GITHUB_STEP_SUMMARY
+ echo "|--------|-------|--------|-------|" >> $GITHUB_STEP_SUMMARY
+
+ # Check format
+ if grep -qi "## \[.*\]" "$CHANGELOG_PATH"; then
+ echo "| Format | Keep a Changelog | ✅ Pass | Standard format |" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "| Format | Custom | ⚠️ Warning | Consider [Keep a Changelog](https://keepachangelog.com/) |" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Version count
+ VERSIONS_STATUS="✅ Good"
+ VERSIONS_NOTE="Well maintained"
+ if [ "$VERSIONS" -lt 1 ]; then
+ VERSIONS_STATUS="⚠️ Warning"
+ VERSIONS_NOTE="Add version entries"
+ fi
+ echo "| Versions | $VERSIONS | $VERSIONS_STATUS | $VERSIONS_NOTE |" >> $GITHUB_STEP_SUMMARY
+
+ # Unreleased section
+ if [ "$UNRELEASED" -gt 0 ]; then
+ echo "| Unreleased | Yes | ✅ Good | Active development tracked |" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "| Unreleased | No | ℹ️ Info | Consider adding [Unreleased] section |" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Dates
+ DATES_STATUS="✅ Good"
+ if [ "$DATES" -lt 1 ]; then
+ DATES_STATUS="⚠️ Warning"
+ DATES_NOTE="Add release dates"
+ else
+ DATES_NOTE="Dates present"
+ fi
+ echo "| Release dates | $DATES | $DATES_STATUS | $DATES_NOTE |" >> $GITHUB_STEP_SUMMARY
+
+ # Check for standard sections
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Changelog Sections:**" >> $GITHUB_STEP_SUMMARY
+ grep -qi "### Added" "$CHANGELOG_PATH" && echo "- ✅ Added section" >> $GITHUB_STEP_SUMMARY || echo "- ℹ️ Added section (optional)" >> $GITHUB_STEP_SUMMARY
+ grep -qi "### Changed" "$CHANGELOG_PATH" && echo "- ✅ Changed section" >> $GITHUB_STEP_SUMMARY || echo "- ℹ️ Changed section (optional)" >> $GITHUB_STEP_SUMMARY
+ grep -qi "### Fixed" "$CHANGELOG_PATH" && echo "- ✅ Fixed section" >> $GITHUB_STEP_SUMMARY || echo "- ℹ️ Fixed section (optional)" >> $GITHUB_STEP_SUMMARY
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "📚 Reference: [Keep a Changelog](https://keepachangelog.com/)" >> $GITHUB_STEP_SUMMARY
+
+ - name: Check Documentation Index
+ run: |
+ set -x
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### Documentation Index" >> $GITHUB_STEP_SUMMARY
+
+ if [ -f "docs/index.md" ] || [ -f "docs/README.md" ]; then
+ echo "✅ Documentation index found" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "⚠️ No documentation index (docs/index.md or docs/README.md)" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ readme-completeness:
+ name: README Completeness Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check README Sections
+ run: |
+ set -x
+ echo "## 📄 README Completeness Check" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ ! -f "README.md" ]; then
+ echo "❌ README.md not found" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ fi
+
+ # Required sections
+ REQUIRED_SECTIONS=("Installation" "Usage" "Contributing" "License")
+ MISSING=0
+ PRESENT=0
+
+ echo "### Required Sections" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ for section in "${REQUIRED_SECTIONS[@]}"; do
+ if grep -qi "##.*$section" README.md; then
+ echo "✅ $section" >> $GITHUB_STEP_SUMMARY
+ PRESENT=$((PRESENT + 1))
+ else
+ echo "❌ $section" >> $GITHUB_STEP_SUMMARY
+ MISSING=$((MISSING + 1))
+ fi
+ done
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Completeness**: $PRESENT/${#REQUIRED_SECTIONS[@]} required sections present" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$MISSING" -gt 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required**: Add missing sections to README.md" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ fi
+
+ # ============================================================================
+ # PHASE 3: Future Enhancements
+ # ============================================================================
+
+ git-hygiene:
+ name: Git Repository Hygiene
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ with:
+ fetch-depth: 0
+
+ - name: Check .gitignore
+ run: |
+ set -x
+ echo "### .gitignore Validation" >> $GITHUB_STEP_SUMMARY
+
+ if [ ! -f ".gitignore" ]; then
+ echo "⚠️ .gitignore file not found" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ⚠️ Warning: .gitignore Not Found" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Status:** .gitignore file is recommended but not required" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation:** Add .gitignore to exclude build artifacts, dependencies, and temporary files" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "⚠️ WARNING: .gitignore file not found - Continuing validation"
+ exit 0
+ fi
+
+ # Check for common exclusions
+ MISSING=""
+ grep -q "vendor/" .gitignore || MISSING="${MISSING}vendor/ "
+ grep -q "node_modules/" .gitignore || MISSING="${MISSING}node_modules/ "
+
+ if [ -n "$MISSING" ]; then
+ echo "⚠️ .gitignore may be missing common exclusions: $MISSING" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ .gitignore appears complete" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ - name: Check for Large Files
+ run: |
+ set -x
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### Large File Detection" >> $GITHUB_STEP_SUMMARY
+
+ # Find files larger than 1MB
+ LARGE_FILES=$(find . -type f -size +1M ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" | head -5)
+
+ if [ -n "$LARGE_FILES" ]; then
+ echo "⚠️ Large files detected (>1MB):" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "$LARGE_FILES" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "Consider using Git LFS for large binary files" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ No unusually large files detected" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ script-integrity:
+ name: Script Integrity Validation
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Set up Python
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ with:
+ python-version: '3.x'
+
+ - name: Validate Script Integrity
+ id: script_check
+ run: |
+ set -x
+ echo "## 🔐 Script Integrity Validation" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ -f "api/.script-registry.json" ]; then
+ echo "### Critical Scripts" >> $GITHUB_STEP_SUMMARY
+ php api/maintenance/update_sha_hashes.php \
+ --dry-run --verbose | tee /tmp/script-validation.log
+
+ EXIT_CODE=$?
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ cat /tmp/script-validation.log >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$EXIT_CODE" -eq 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "✅ All critical scripts validated successfully!" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ else
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "❌ Script integrity violations detected" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required:** Review validation report and update registry" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ fi
+ else
+ echo "ℹ️ Script registry not found - skipping integrity check" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
+
+ # ════════════════════════════════════════════════════════════════════════
+ # TIER 3 — QUALITY (code quality metrics)
+ # ════════════════════════════════════════════════════════════════════════
+ line-length-validation:
+ name: Line Length Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check Line Lengths
+ run: |
+ set -x
+ echo "## 📏 Line Length Validation" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Line length standards:
+ # - General source code: 120 characters (hard limit)
+ # - YAML workflows: 180 characters (exception for GitHub Actions)
+ # - Markdown files: No limit (content-focused)
+
+ echo "### Line Length Standards" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| File Type | Soft Limit | Hard Limit |" >> $GITHUB_STEP_SUMMARY
+ echo "|-----------|------------|------------|" >> $GITHUB_STEP_SUMMARY
+ echo "| General source code | 80 chars | 120 chars |" >> $GITHUB_STEP_SUMMARY
+ echo "| YAML workflows | 80 chars | 180 chars |" >> $GITHUB_STEP_SUMMARY
+ echo "| Markdown files | N/A | No limit |" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Check YAML files (using yamllint which is already configured)
+ echo "### YAML Files (180 char limit)" >> $GITHUB_STEP_SUMMARY
+
+ YAML_VIOLATIONS=0
+ if command -v yamllint >/dev/null 2>&1; then
+ # Install yamllint if not present
+ :
+ else
+ pip install yamllint >/dev/null 2>&1
+ fi
+
+ # Run yamllint and count line-length warnings
+ YAML_OUTPUT=$(yamllint .github/workflows/*.yml 2>&1 | grep "line too long" || true)
+ if [ -n "$YAML_OUTPUT" ]; then
+ YAML_VIOLATIONS=$(echo "$YAML_OUTPUT" | wc -l)
+ echo "⚠️ Found $YAML_VIOLATIONS lines exceeding 180 characters in YAML files" >> $GITHUB_STEP_SUMMARY
+ echo "View warnings (informational only) " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "$YAML_OUTPUT" | head -20 >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ All YAML files comply with 180 character limit" >> $GITHUB_STEP_SUMMARY
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Check source code files (PHP, Python, JavaScript, etc.) for 120 char limit
+ echo "### Source Code Files (120 char limit)" >> $GITHUB_STEP_SUMMARY
+
+ LONG_LINES=$(find . -type f \
+ \( -name "*.php" -o -name "*.py" -o -name "*.js" -o -name "*.ts" \
+ -o -name "*.go" -o -name "*.rs" -o -name "*.java" -o -name "*.c" \
+ -o -name "*.cpp" -o -name "*.h" -o -name "*.sh" \) \
+ ! -path "./vendor/*" \
+ ! -path "./node_modules/*" \
+ ! -path "./.git/*" \
+ ! -path "./build/*" \
+ ! -path "./dist/*" \
+ -exec awk 'length > 120 { print FILENAME ":" NR ": " length " chars" }' {} \; 2>/dev/null | head -20)
+
+ if [ -n "$LONG_LINES" ]; then
+ LINE_COUNT=$(echo "$LONG_LINES" | wc -l)
+ echo "⚠️ Found $LINE_COUNT source code lines exceeding 120 characters" >> $GITHUB_STEP_SUMMARY
+ echo "View violations (informational) " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "$LONG_LINES" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ All source code files comply with 120 character limit" >> $GITHUB_STEP_SUMMARY
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Confirm Markdown files are not checked
+ echo "### Markdown Files" >> $GITHUB_STEP_SUMMARY
+ echo "✅ Markdown files have no line length limit per coding standards" >> $GITHUB_STEP_SUMMARY
+ echo "Rationale: Content-focused format, URLs, tables, and natural prose flow" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Summary
+ echo "### Summary" >> $GITHUB_STEP_SUMMARY
+ echo "This check is **informational only** and does not block merges." >> $GITHUB_STEP_SUMMARY
+ echo "Line length standards help maintain code readability." >> $GITHUB_STEP_SUMMARY
+ echo "Exceptions documented in: \`docs/policy/coding-style-guide.md\`" >> $GITHUB_STEP_SUMMARY
+
+ file-naming-standards:
+ name: File Naming Standards
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check File Naming
+ run: |
+ set -x
+ echo "## 📝 File Naming Standards" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ VIOLATIONS=0
+
+ # Check PHP files (should be PascalCase for classes)
+ INVALID_PHP=$(find . -name "*.php" ! -path "./vendor/*" ! -path "./.git/*" ! -regex ".*/[A-Z][a-zA-Z0-9]*\.php" ! -name "index.php" ! -name "functions.php" | wc -l || echo 0)
+
+ # Check config files (should be kebab-case)
+ INVALID_CONFIG=$(find . -name "*.yml" -o -name "*.yaml" -o -name "*.json" ! -path "./vendor/*" ! -path "./.git/*" ! -path "./node_modules/*" | grep -E "[A-Z_]" | wc -l || echo 0)
+
+ echo "### Naming Violations" >> $GITHUB_STEP_SUMMARY
+ echo "- **PHP files not PascalCase**: $INVALID_PHP" >> $GITHUB_STEP_SUMMARY
+ echo "- **Config files not kebab-case**: $INVALID_CONFIG" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ VIOLATIONS=$((INVALID_PHP + INVALID_CONFIG))
+
+ if [ "$VIOLATIONS" -gt 0 ]; then
+ echo "⚠️ Found $VIOLATIONS naming convention violation(s)" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Follow naming conventions for consistency" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ File naming conventions followed" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ insecure-patterns:
+ name: Insecure Code Pattern Detection
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Scan for Insecure Patterns
+ run: |
+ set -x
+ echo "## 🔒 Insecure Code Pattern Detection" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ VIOLATIONS=0
+
+ # PHP: SQL injection patterns
+ if grep -r -n "\\$_\(GET\|POST\|REQUEST\).*mysql_query\|mysqli_query" . --include="*.php" ! -path "./vendor/*" 2>/dev/null > /tmp/sql_inject.txt; then
+ COUNT=$(wc -l < /tmp/sql_inject.txt)
+ echo "⚠️ Found $COUNT potential SQL injection pattern(s)" >> $GITHUB_STEP_SUMMARY
+ VIOLATIONS=$((VIOLATIONS + COUNT))
+ fi
+
+ # PHP: eval/exec usage
+ if grep -r -n "eval\|exec\|system\|passthru\|shell_exec" . --include="*.php" ! -path "./vendor/*" 2>/dev/null > /tmp/exec.txt; then
+ COUNT=$(wc -l < /tmp/exec.txt)
+ echo "⚠️ Found $COUNT dangerous function call(s)" >> $GITHUB_STEP_SUMMARY
+ VIOLATIONS=$((VIOLATIONS + COUNT))
+ fi
+
+ # Python: eval usage
+ if grep -r -n "eval(" . --include="*.py" 2>/dev/null > /tmp/py_eval.txt; then
+ COUNT=$(wc -l < /tmp/py_eval.txt)
+ echo "⚠️ Found $COUNT Python eval() usage(s)" >> $GITHUB_STEP_SUMMARY
+ VIOLATIONS=$((VIOLATIONS + COUNT))
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$VIOLATIONS" -gt 0 ]; then
+ echo "**Total Violations**: $VIOLATIONS" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Review and secure flagged patterns" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ No insecure patterns detected" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ code-complexity:
+ name: Code Complexity Analysis
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Setup PHP
+ run: |
+ php -v && composer --version
+
+ - name: Analyze Complexity
+ run: |
+ set -x
+ echo "## 📊 Code Complexity Analysis" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ PHP_COUNT=$(find . -name "*.php" ! -path "./vendor/*" ! -path "./.git/*" | wc -l)
+
+ if [ "$PHP_COUNT" -gt 0 ]; then
+ # Install phploc
+ wget https://phar.phpunit.de/phploc.phar 2>/dev/null
+ chmod +x phploc.phar
+
+ echo "### PHP Code Metrics" >> $GITHUB_STEP_SUMMARY
+ if ./phploc.phar --exclude vendor --exclude .git . 2>&1 | tee /tmp/phploc.txt; then
+ COMPLEXITY=$(grep "Cyclomatic Complexity" /tmp/phploc.txt | grep "Average" | awk '{print $NF}' || echo "N/A")
+ echo "**Average Cyclomatic Complexity**: $COMPLEXITY" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$COMPLEXITY" != "N/A" ] && [ $(echo "$COMPLEXITY > 10" | bc -l) -eq 1 ]; then
+ echo "⚠️ Average complexity exceeds recommended threshold (10)" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Refactor complex functions" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ Code complexity within acceptable limits" >> $GITHUB_STEP_SUMMARY
+ fi
+ fi
+ else
+ echo "ℹ️ No PHP files found for complexity analysis" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ code-duplication:
+ name: Code Duplication Detection
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Setup PHP
+ run: |
+ php -v && composer --version
+
+ - name: Detect Duplicates
+ run: |
+ set -x
+ echo "## 🔁 Code Duplication Detection" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Check if PHP files exist
+ PHP_COUNT=$(find . -name "*.php" ! -path "./vendor/*" ! -path "./.git/*" | wc -l)
+
+ if [ "$PHP_COUNT" -gt 0 ]; then
+ echo "### PHP Code Duplication" >> $GITHUB_STEP_SUMMARY
+
+ # Install phpcpd
+ wget https://phar.phpunit.de/phpcpd.phar 2>/dev/null
+ chmod +x phpcpd.phar
+
+ # Run duplication detection
+ if ./phpcpd.phar --exclude vendor --exclude .git . 2>&1 | tee /tmp/phpcpd.txt; then
+ DUPLICATION=$(grep "Found" /tmp/phpcpd.txt | grep -oE "[0-9]+\.[0-9]+%" | head -1 || echo "0.00%")
+ echo "📊 **Duplication Rate**: $DUPLICATION" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ DUPLICATION_NUM=$(echo "$DUPLICATION" | sed 's/%//')
+ if [ $(echo "$DUPLICATION_NUM > 5.0" | bc -l) -eq 1 ]; then
+ echo "⚠️ Code duplication exceeds 5% threshold" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View duplication details " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ cat /tmp/phpcpd.txt >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ Code duplication within acceptable limits (<5%)" >> $GITHUB_STEP_SUMMARY
+ fi
+ else
+ echo "✅ No significant code duplication detected" >> $GITHUB_STEP_SUMMARY
+ fi
+ else
+ echo "ℹ️ No PHP files found for duplication analysis" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Note**: This is an informational check to encourage DRY principles." >> $GITHUB_STEP_SUMMARY
+
+ dead-code-detection:
+ name: Dead Code Detection
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Setup Python
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ with:
+ python-version: '3.x'
+
+ - name: Detect Dead Code
+ run: |
+ set -x
+ echo "## 🗑️ Dead Code Detection" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ PY_COUNT=$(find . -name "*.py" ! -path "./vendor/*" ! -path "./.git/*" ! -path "./venv/*" | wc -l)
+
+ if [ "$PY_COUNT" -gt 0 ]; then
+ pip install vulture 2>/dev/null
+ echo "### Python Dead Code" >> $GITHUB_STEP_SUMMARY
+
+ if vulture . --exclude vendor,venv,.git 2>&1 | tee /tmp/vulture.txt; then
+ DEAD_COUNT=$(wc -l < /tmp/vulture.txt || echo 0)
+ if [ "$DEAD_COUNT" -gt 0 ]; then
+ echo "⚠️ Found $DEAD_COUNT potential dead code item(s)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View dead code " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ head -50 /tmp/vulture.txt >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ No dead code detected" >> $GITHUB_STEP_SUMMARY
+ fi
+ fi
+ else
+ echo "ℹ️ No Python files found for dead code analysis" >> $GITHUB_STEP_SUMMARY
+ fi
+
+
+ # ════════════════════════════════════════════════════════════════════════
+ # TIER 4 — SUPPLEMENTARY (informational)
+ # ════════════════════════════════════════════════════════════════════════
+ file-size-limits:
+ name: File Size Limits
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check File Sizes
+ run: |
+ set -x
+ echo "## 📦 File Size Validation" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Exempt file types (allowed to be large)
+ EXEMPT="! -name *.mmdb ! -name *.woff2 ! -name *.woff ! -name *.ttf ! -name *.otf"
+
+ # Find large files (>15MB warning, >20MB critical)
+ LARGE_FILES=$(find . -type f -size +15M $EXEMPT ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" 2>/dev/null | wc -l)
+ HUGE_FILES=$(find . -type f -size +20M $EXEMPT ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" 2>/dev/null | wc -l)
+
+ echo "### Size Thresholds" >> $GITHUB_STEP_SUMMARY
+ echo "- **Warning**: Files >15MB" >> $GITHUB_STEP_SUMMARY
+ echo "- **Critical**: Files >20MB" >> $GITHUB_STEP_SUMMARY
+ echo "- **Exempt**: .mmdb, .woff2, .woff, .ttf, .otf" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$HUGE_FILES" -gt 0 ]; then
+ echo "❌ **Critical**: Found $HUGE_FILES file(s) exceeding 20MB" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View files >20MB " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ find . -type f -size +20M $EXEMPT ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" -exec ls -lh {} + 2>/dev/null | awk '{print $5, $9}' >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required**: Remove or optimize files >20MB" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ elif [ "$LARGE_FILES" -gt 0 ]; then
+ echo "⚠️ **Warning**: Found $LARGE_FILES file(s) between 15MB and 20MB" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View files >15MB " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ find . -type f -size +15M $EXEMPT ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" -exec ls -lh {} + 2>/dev/null | awk '{print $5, $9}' >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Consider optimizing large files" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ All files within acceptable size limits" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ binary-file-detection:
+ name: Binary File Detection
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Detect Binary Files
+ run: |
+ set -x
+ echo "## 🔍 Binary File Detection" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Find binary files excluding allowed types
+ BINARIES=$(find . -type f ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" \
+ ! -name "*.png" ! -name "*.jpg" ! -name "*.jpeg" ! -name "*.gif" ! -name "*.svg" ! -name "*.ico" \
+ ! -name "*.woff" ! -name "*.woff2" ! -name "*.ttf" ! -name "*.eot" \
+ -exec file {} \; | grep -v "text" | grep -v "empty" | wc -l || echo 0)
+
+ if [ "$BINARIES" -gt 0 ]; then
+ echo "⚠️ Found $BINARIES non-image binary file(s)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View binary files " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ find . -type f ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" \
+ ! -name "*.png" ! -name "*.jpg" ! -name "*.jpeg" ! -name "*.gif" ! -name "*.svg" ! -name "*.ico" \
+ ! -name "*.woff" ! -name "*.woff2" ! -name "*.ttf" ! -name "*.eot" \
+ -exec file {} \; | grep -v "text" | grep -v "empty" | cut -d: -f1 >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Source control should primarily contain text files" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ No unexpected binary files detected" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # ============================================================================
+ # PHASE 4: Nice to Have Checks
+ # ============================================================================
+
+ todo-fixme-tracking:
+ name: TODO/FIXME Tracking
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Track Technical Debt
+ run: |
+ set -x
+ echo "## 📝 TODO/FIXME Tracking" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "Tracking technical debt markers in source code." >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Search for technical debt markers
+ PATTERNS="TODO|FIXME|HACK|XXX"
+ EXTENSIONS="*.php *.py *.js *.ts *.go *.rs *.java *.c *.cpp *.h *.hpp *.sh"
+
+ echo "### Technical Debt Summary" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ TOTAL_COUNT=0
+ for ext in $EXTENSIONS; do
+ COUNT=$(find . -type f -name "$ext" ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" -exec grep -n -E "($PATTERNS)" {} + 2>/dev/null | wc -l || echo 0)
+ TOTAL_COUNT=$((TOTAL_COUNT + COUNT))
+ done
+
+ if [ "$TOTAL_COUNT" -gt 0 ]; then
+ echo "⚠️ Found **$TOTAL_COUNT** technical debt item(s)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View technical debt items " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ for ext in $EXTENSIONS; do
+ find . -type f -name "$ext" ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" -exec grep -n -H -E "($PATTERNS)" {} + 2>/dev/null | head -100 || true
+ done >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ No technical debt markers found" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Note**: This is an informational check. Technical debt items don't block compliance." >> $GITHUB_STEP_SUMMARY
+
+ dependency-vulnerabilities:
+ name: Dependency Vulnerability Scanning
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Setup PHP
+ run: |
+ php -v && composer --version
+
+ - name: Setup Python
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ with:
+ python-version: '3.x'
+
+ - name: Scan Dependencies
+ run: |
+ set -x
+ echo "## 🛡️ Dependency Vulnerability Scanning" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ VULNERABILITIES=0
+
+ # PHP Dependencies
+ if [ -f "composer.json" ]; then
+ echo "### PHP Dependencies (composer)" >> $GITHUB_STEP_SUMMARY
+ if composer audit --no-dev 2>&1 | tee /tmp/php_audit.txt; then
+ echo "✅ No PHP vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
+ else
+ VULN_COUNT=$(grep -c "vulnerability" /tmp/php_audit.txt || echo 0)
+ echo "⚠️ Found $VULN_COUNT PHP vulnerability/vulnerabilities" >> $GITHUB_STEP_SUMMARY
+ VULNERABILITIES=$((VULNERABILITIES + VULN_COUNT))
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Python Dependencies
+ if [ -f "requirements.txt" ]; then
+ echo "### Python Dependencies" >> $GITHUB_STEP_SUMMARY
+ pip install pip-audit 2>&1 > /dev/null
+ if pip-audit -r requirements.txt 2>&1 | tee /tmp/py_audit.txt; then
+ echo "✅ No Python vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
+ else
+ VULN_COUNT=$(grep -c "vulnerability" /tmp/py_audit.txt || echo 0)
+ echo "⚠️ Found $VULN_COUNT Python vulnerability/vulnerabilities" >> $GITHUB_STEP_SUMMARY
+ VULNERABILITIES=$((VULNERABILITIES + VULN_COUNT))
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # NPM Dependencies
+ if [ -f "package.json" ]; then
+ echo "### NPM Dependencies" >> $GITHUB_STEP_SUMMARY
+ if npm audit --production 2>&1 | tee /tmp/npm_audit.txt; then
+ echo "✅ No NPM vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
+ else
+ VULN_COUNT=$(grep -c "vulnerability" /tmp/npm_audit.txt || echo 0)
+ echo "⚠️ Found $VULN_COUNT NPM vulnerability/vulnerabilities" >> $GITHUB_STEP_SUMMARY
+ VULNERABILITIES=$((VULNERABILITIES + VULN_COUNT))
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ if [ "$VULNERABILITIES" -gt 0 ]; then
+ echo "**Total Vulnerabilities**: $VULNERABILITIES" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required**: Update vulnerable dependencies" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ else
+ echo "✅ No dependency vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ unused-dependencies:
+ name: Unused Dependencies Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Setup PHP
+ run: |
+ php -v && composer --version
+
+ - name: Check Unused Dependencies
+ run: |
+ set -x
+ echo "## 📦 Unused Dependencies Check" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ -f "composer.json" ]; then
+ echo "### PHP Dependencies" >> $GITHUB_STEP_SUMMARY
+
+ # Install composer-unused
+ composer global require icanhazstring/composer-unused 2>/dev/null || true
+
+ if composer global exec composer-unused 2>&1 | tee /tmp/unused.txt; then
+ UNUSED_COUNT=$(grep "unused" /tmp/unused.txt | wc -l || echo 0)
+ if [ "$UNUSED_COUNT" -gt 0 ]; then
+ echo "⚠️ Found $UNUSED_COUNT unused dependency/dependencies" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View unused dependencies " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ cat /tmp/unused.txt >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ No unused dependencies detected" >> $GITHUB_STEP_SUMMARY
+ fi
+ else
+ echo "✅ All dependencies appear to be in use" >> $GITHUB_STEP_SUMMARY
+ fi
+ else
+ echo "ℹ️ No composer.json found" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Remove unused dependencies to reduce attack surface" >> $GITHUB_STEP_SUMMARY
+
+ broken-link-detection:
+ name: Broken Link Detection
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check Internal Links
+ run: |
+ set -x
+ echo "## 🔗 Broken Link Detection" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "Checking internal links in markdown files." >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ BROKEN_LINKS=0
+ CHECKED_LINKS=0
+
+ # Find all markdown files
+ MD_FILES=$(find . -name "*.md" ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*")
+
+ for file in $MD_FILES; do
+ # Extract markdown links [text](path)
+ while IFS= read -r line; do
+ # Extract path from [text](path)
+ link=$(echo "$line" | sed -n 's/.*\](\([^)]*\)).*/\1/p')
+
+ # Skip external links (http/https)
+ if echo "$link" | grep -qE "^https?://"; then
+ continue
+ fi
+
+ # Skip anchors only
+ if echo "$link" | grep -qE "^#"; then
+ continue
+ fi
+
+ CHECKED_LINKS=$((CHECKED_LINKS + 1))
+
+ # Get directory of the markdown file
+ basedir=$(dirname "$file")
+
+ # Resolve relative path
+ if [ -n "$link" ]; then
+ # Remove anchor if present
+ clean_link=$(echo "$link" | sed 's/#.*//')
+
+ # Check if file exists
+ if [ ! -e "$basedir/$clean_link" ] && [ ! -e "$clean_link" ]; then
+ echo "Broken link in $file: $link" >> /tmp/broken_links.txt
+ BROKEN_LINKS=$((BROKEN_LINKS + 1))
+ fi
+ fi
+ done < <(grep -o '\[.*\](.*)' "$file" 2>/dev/null || true)
+ done
+
+ echo "### Link Validation Results" >> $GITHUB_STEP_SUMMARY
+ echo "- **Links Checked**: $CHECKED_LINKS" >> $GITHUB_STEP_SUMMARY
+ echo "- **Broken Links**: $BROKEN_LINKS" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$BROKEN_LINKS" -gt 0 ]; then
+ echo "⚠️ Found $BROKEN_LINKS broken internal link(s)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View broken links " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ cat /tmp/broken_links.txt 2>/dev/null >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Fix or remove broken links to maintain documentation quality" >> $GITHUB_STEP_SUMMARY
+ else
+ if [ "$CHECKED_LINKS" -gt 0 ]; then
+ echo "✅ All internal links are valid" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "ℹ️ No internal links found to check" >> $GITHUB_STEP_SUMMARY
+ fi
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Note**: This check validates internal file references only. External URLs are not validated." >> $GITHUB_STEP_SUMMARY
+
+ # ============================================================================
+ # PHASE 2: Medium Priority Checks
+ # ============================================================================
+
+ api-documentation:
+ name: API Documentation Coverage
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check Documentation
+ run: |
+ set -x
+ echo "## 📚 API Documentation Coverage" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Count public functions/classes
+ PUBLIC_METHODS=$(grep -r "public function" . --include="*.php" ! -path "./vendor/*" | wc -l || echo 0)
+ DOCUMENTED=$(grep -B5 -r "public function" . --include="*.php" ! -path "./vendor/*" | grep -c "/\*\*" || echo 0)
+
+ if [ "$PUBLIC_METHODS" -gt 0 ]; then
+ COVERAGE=$((DOCUMENTED * 100 / PUBLIC_METHODS))
+ echo "**Documentation Coverage**: $COVERAGE% ($DOCUMENTED/$PUBLIC_METHODS)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$COVERAGE" -lt 80 ]; then
+ echo "⚠️ Documentation coverage below 80% threshold" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Add PHPDoc blocks to public methods" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ Good documentation coverage" >> $GITHUB_STEP_SUMMARY
+ fi
+ else
+ echo "ℹ️ No public methods found for documentation check" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ accessibility-check:
+ name: Accessibility Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check Accessibility
+ run: |
+ set -x
+ echo "## ♿ Accessibility Check" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ HTML_COUNT=$(find . -name "*.html" ! -path "./vendor/*" ! -path "./.git/*" ! -path "./node_modules/*" | wc -l || echo 0)
+ MD_IMG_COUNT=$(find . -name "*.md" ! -path "./vendor/*" ! -path "./.git/*" -exec grep -l "!\[" {} + 2>/dev/null | wc -l || echo 0)
+
+ if [ "$HTML_COUNT" -gt 0 ] || [ "$MD_IMG_COUNT" -gt 0 ]; then
+ # Check for images without alt text
+ MISSING_ALT=0
+
+ if [ "$HTML_COUNT" -gt 0 ]; then
+ MISSING_ALT=$(grep -r " > $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$MISSING_ALT" -gt 0 ]; then
+ echo "⚠️ Found images without alt text" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Add descriptive alt text for accessibility" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ All images have alt text" >> $GITHUB_STEP_SUMMARY
+ fi
+ else
+ echo "ℹ️ No HTML files found for accessibility check" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ performance-metrics:
+ name: Performance Metrics
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check Performance Metrics
+ run: |
+ set -x
+ echo "## ⚡ Performance Metrics" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Check if JavaScript bundles exist
+ if [ -f "package.json" ]; then
+ echo "### Bundle Analysis" >> $GITHUB_STEP_SUMMARY
+
+ # Check for common bundle files
+ BUNDLE_SIZE=0
+ if [ -d "dist" ]; then
+ BUNDLE_SIZE=$(du -sb dist/ 2>/dev/null | cut -f1 || echo 0)
+ elif [ -d "build" ]; then
+ BUNDLE_SIZE=$(du -sb build/ 2>/dev/null | cut -f1 || echo 0)
+ fi
+
+ if [ "$BUNDLE_SIZE" -gt 0 ]; then
+ BUNDLE_MB=$((BUNDLE_SIZE / 1024 / 1024))
+ echo "**Bundle Size**: ${BUNDLE_MB}MB" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$BUNDLE_MB" -gt 5 ]; then
+ echo "⚠️ Bundle size exceeds 5MB threshold" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Optimize bundle size" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ Bundle size within acceptable limits" >> $GITHUB_STEP_SUMMARY
+ fi
+ else
+ echo "ℹ️ No build artifacts found" >> $GITHUB_STEP_SUMMARY
+ fi
+ else
+ echo "ℹ️ Not a JavaScript project" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ enterprise-readiness:
+ name: Enterprise Readiness Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Set up PHP
+ run: |
+ php -v && composer --version
+
+ - name: Install API Package
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GA_TOKEN || github.token }}"}}'
+ run: |
+ if [ -f "composer.json" ]; then
+ composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
+ else
+ echo "No composer.json — pulling MokoStandards tools"
+ if [ ! -d "/tmp/mokostandards" ]; then
+ git clone --depth 1 --branch version/04 --quiet \
+ "https://x-access-token:${GH_TOKEN}@git.mokoconsulting.tech/MokoConsulting/MokoStandards.git" \
+ /tmp/mokostandards 2>/dev/null || true
+ if [ -f "/tmp/mokostandards/composer.json" ]; then
+ cd /tmp/mokostandards && composer install --no-dev --no-interaction --quiet 2>/dev/null || true
+ cd -
+ fi
+ fi
+ fi
+
+ - name: Check Enterprise Readiness
+ id: enterprise_check
+ run: |
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ SCRIPT=""
+ if [ -f "api/validate/check_enterprise_readiness.php" ]; then
+ SCRIPT="api/validate/check_enterprise_readiness.php"
+ elif [ -f "/tmp/mokostandards/api/validate/check_enterprise_readiness.php" ]; then
+ SCRIPT="/tmp/mokostandards/api/validate/check_enterprise_readiness.php"
+ fi
+
+ if [ -n "$SCRIPT" ]; then
+ php "$SCRIPT" --verbose | tee /tmp/enterprise-check.log
+ EXIT_CODE=$?
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ cat /tmp/enterprise-check.log >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$EXIT_CODE" -eq 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "✅ Repository meets enterprise readiness criteria!" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ else
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "⚠️ Enterprise readiness issues detected" >> $GITHUB_STEP_SUMMARY
+ echo "**Note:** This is informational - review recommendations to improve" >> $GITHUB_STEP_SUMMARY
+ exit 0 # Non-blocking
+ fi
+ else
+ echo "ℹ️ Enterprise readiness check script not found - skipping" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
+ repository-health:
+ name: Repository Health Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Set up PHP
+ run: |
+ php -v && composer --version
+
+ - name: Install API Package
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GA_TOKEN || github.token }}"}}'
+ run: |
+ if [ -f "composer.json" ]; then
+ composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
+ else
+ echo "No composer.json — pulling MokoStandards tools"
+ if [ ! -d "/tmp/mokostandards" ]; then
+ git clone --depth 1 --branch version/04 --quiet \
+ "https://x-access-token:${GH_TOKEN}@git.mokoconsulting.tech/MokoConsulting/MokoStandards.git" \
+ /tmp/mokostandards 2>/dev/null || true
+ if [ -f "/tmp/mokostandards/composer.json" ]; then
+ cd /tmp/mokostandards && composer install --no-dev --no-interaction --quiet 2>/dev/null || true
+ cd -
+ fi
+ fi
+ fi
+
+ - name: Check Repository Health
+ id: health_check
+ run: |
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ SCRIPT=""
+ if [ -f "api/validate/check_repo_health.php" ]; then
+ SCRIPT="api/validate/check_repo_health.php"
+ elif [ -f "/tmp/mokostandards/api/validate/check_repo_health.php" ]; then
+ SCRIPT="/tmp/mokostandards/api/validate/check_repo_health.php"
+ fi
+
+ if [ -n "$SCRIPT" ]; then
+ php "$SCRIPT" --verbose | tee /tmp/health-check.log
+ EXIT_CODE=$?
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ cat /tmp/health-check.log >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$EXIT_CODE" -eq 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "✅ Repository health check passed!" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ else
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "⚠️ Repository health issues detected" >> $GITHUB_STEP_SUMMARY
+ echo "**Note:** This is informational - review recommendations to improve" >> $GITHUB_STEP_SUMMARY
+ exit 0 # Non-blocking
+ fi
+ else
+ echo "ℹ️ Repository health check script not found - skipping" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
+ terraform-validation:
+ name: Terraform Configuration Validation
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Setup Terraform
+ uses: hashicorp/setup-terraform@5e8dbf3c6d9deaf4193ca7a8fb23f2ac83bb6c85 # v4.0.0
+ with:
+ terraform_version: "1.0"
+
+ - name: Validate Terraform Files
+ run: |
+ set -x
+ echo "## 🏗️ Terraform Configuration Validation" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Check if terraform files exist
+ TF_COUNT=$(find . -name "*.tf" -type f | wc -l || echo 0)
+
+ if [ "$TF_COUNT" -eq 0 ]; then
+ echo "ℹ️ No Terraform files found in repository" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
+ echo "**Terraform Files Found**: $TF_COUNT" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Validation Results
+ VALIDATION_PASSED=true
+ WARNINGS=0
+ ERRORS=0
+
+ # 1. Check .github/config.tf location (not root override files)
+ echo "### Override Configuration Check" >> $GITHUB_STEP_SUMMARY
+ LEGACY_OVERRIDES=$(find . -maxdepth 1 -name "*override*.tf" -o -name "MokoStandards.override.tf" 2>/dev/null | wc -l || echo 0)
+ if [ "$LEGACY_OVERRIDES" -gt 0 ]; then
+ echo "⚠️ Found legacy override files in root directory" >> $GITHUB_STEP_SUMMARY
+ echo "**Expected Location**: .github/config.tf" >> $GITHUB_STEP_SUMMARY
+ echo "**Legacy files found**: $LEGACY_OVERRIDES" >> $GITHUB_STEP_SUMMARY
+ WARNINGS=$((WARNINGS + 1))
+ else
+ if [ -f ".github/config.tf" ]; then
+ echo "✅ Override configuration in correct location (.github/config.tf)" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "ℹ️ No override configuration found" >> $GITHUB_STEP_SUMMARY
+ fi
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # 2. Terraform Syntax Validation
+ echo "### Terraform Syntax Validation" >> $GITHUB_STEP_SUMMARY
+ SYNTAX_ERRORS=0
+
+ # Find all directories with terraform files
+ for dir in $(find . -name "*.tf" -type f -exec dirname {} \; | sort -u); do
+ cd "$dir" || continue
+ echo "Validating: $dir" >> $GITHUB_STEP_SUMMARY
+
+ # Initialize without backend
+ terraform init -backend=false > /dev/null 2>&1 || true
+
+ # Validate
+ if terraform validate -no-color > /tmp/tf_validate.txt 2>&1; then
+ echo " ✅ Syntax valid" >> $GITHUB_STEP_SUMMARY
+ else
+ echo " ❌ Syntax errors found" >> $GITHUB_STEP_SUMMARY
+ cat /tmp/tf_validate.txt >> $GITHUB_STEP_SUMMARY
+ SYNTAX_ERRORS=$((SYNTAX_ERRORS + 1))
+ VALIDATION_PASSED=false
+ fi
+ cd - > /dev/null
+ done
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$SYNTAX_ERRORS" -eq 0 ]; then
+ echo "✅ All Terraform files have valid syntax" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "❌ Found $SYNTAX_ERRORS directories with syntax errors" >> $GITHUB_STEP_SUMMARY
+ ERRORS=$((ERRORS + SYNTAX_ERRORS))
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # 3. Terraform Formatting Check
+ echo "### Terraform Formatting Check" >> $GITHUB_STEP_SUMMARY
+ FORMAT_ISSUES=0
+
+ for tf_file in $(find . -name "*.tf" -type f); do
+ if ! terraform fmt -check=true -no-color "$tf_file" > /dev/null 2>&1; then
+ FORMAT_ISSUES=$((FORMAT_ISSUES + 1))
+ fi
+ done
+
+ if [ "$FORMAT_ISSUES" -eq 0 ]; then
+ echo "✅ All Terraform files properly formatted" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "⚠️ Found $FORMAT_ISSUES files with formatting issues" >> $GITHUB_STEP_SUMMARY
+ echo "**Fix**: Run \`terraform fmt -recursive\`" >> $GITHUB_STEP_SUMMARY
+ WARNINGS=$((WARNINGS + 1))
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # 4. Check for file_metadata blocks
+ echo "### File Metadata Validation" >> $GITHUB_STEP_SUMMARY
+ MISSING_METADATA=0
+
+ for tf_file in $(find . -name "*.tf" -type f); do
+ if ! grep -q "file_metadata" "$tf_file"; then
+ MISSING_METADATA=$((MISSING_METADATA + 1))
+ fi
+ done
+
+ if [ "$MISSING_METADATA" -eq 0 ]; then
+ echo "✅ All Terraform files contain file_metadata block" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "⚠️ Found $MISSING_METADATA files missing file_metadata block" >> $GITHUB_STEP_SUMMARY
+ echo "**Reference**: docs/policy/terraform-file-standards.md" >> $GITHUB_STEP_SUMMARY
+ WARNINGS=$((WARNINGS + 1))
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # 5. Version Consistency Check
+ echo "### Version Consistency Check" >> $GITHUB_STEP_SUMMARY
+ VERSION_MISMATCHES=0
+ EXPECTED_VERSION="04.00.04"
+
+ for tf_file in $(find . -name "*.tf" -type f); do
+ if grep -q "version.*=" "$tf_file"; then
+ if ! grep -q "version.*=.*\"$EXPECTED_VERSION\"" "$tf_file"; then
+ VERSION_MISMATCHES=$((VERSION_MISMATCHES + 1))
+ fi
+ fi
+ done
+
+ if [ "$VERSION_MISMATCHES" -eq 0 ]; then
+ echo "✅ All Terraform file versions match $EXPECTED_VERSION" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "⚠️ Found $VERSION_MISMATCHES files with version mismatches" >> $GITHUB_STEP_SUMMARY
+ echo "**Expected Version**: $EXPECTED_VERSION" >> $GITHUB_STEP_SUMMARY
+ WARNINGS=$((WARNINGS + 1))
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # 6. Copyright Header Check
+ echo "### Copyright Header Check" >> $GITHUB_STEP_SUMMARY
+ MISSING_COPYRIGHT=0
+
+ for tf_file in $(find . -name "*.tf" -type f); do
+ if ! grep -q "Copyright (C)" "$tf_file"; then
+ MISSING_COPYRIGHT=$((MISSING_COPYRIGHT + 1))
+ fi
+ done
+
+ if [ "$MISSING_COPYRIGHT" -eq 0 ]; then
+ echo "✅ All Terraform files have copyright headers" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "⚠️ Found $MISSING_COPYRIGHT files missing copyright headers" >> $GITHUB_STEP_SUMMARY
+ echo "**Reference**: docs/policy/terraform-file-standards.md" >> $GITHUB_STEP_SUMMARY
+ WARNINGS=$((WARNINGS + 1))
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Summary
+ echo "---" >> $GITHUB_STEP_SUMMARY
+ echo "### Validation Summary" >> $GITHUB_STEP_SUMMARY
+ echo "**Total Files**: $TF_COUNT" >> $GITHUB_STEP_SUMMARY
+ echo "**Errors**: $ERRORS" >> $GITHUB_STEP_SUMMARY
+ echo "**Warnings**: $WARNINGS" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$VALIDATION_PASSED" = true ] && [ "$ERRORS" -eq 0 ]; then
+ echo "✅ **Terraform Validation: PASSED**" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ elif [ "$ERRORS" -gt 0 ]; then
+ echo "❌ **Terraform Validation: FAILED**" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Note**: This is an informational check and does not block merges" >> $GITHUB_STEP_SUMMARY
+ exit 0 # Informational only
+ else
+ echo "⚠️ **Terraform Validation: PASSED WITH WARNINGS**" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Note**: This is an informational check and does not block merges" >> $GITHUB_STEP_SUMMARY
+ exit 0 # Informational only
+ fi
+
+ summary:
+ name: Compliance Summary
+ runs-on: ubuntu-latest
+ needs: [
+ repository-structure, documentation-quality, coding-standards, line-length-validation, license-compliance, git-hygiene, workflow-validation, version-consistency, script-integrity, enterprise-readiness, repository-health,
+ todo-fixme-tracking, file-size-limits, secret-scanning, broken-link-detection,
+ dependency-vulnerabilities, code-duplication, unused-dependencies, readme-completeness,
+ code-complexity, api-documentation, insecure-patterns, binary-file-detection,
+ dead-code-detection, file-naming-standards, accessibility-check, performance-metrics, terraform-validation
+ ]
+ if: always()
+
+ steps:
+ - name: Generate Compliance Report
+ run: |
+ set -x
+ echo "# 📊 MokoStandards Compliance Report" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Calculate overall status
+ REPO_STATUS="${{ needs.repository-structure.result }}"
+ DOCS_STATUS="${{ needs.documentation-quality.result }}"
+ CODE_STATUS="${{ needs.coding-standards.result }}"
+ LINE_LENGTH_STATUS="${{ needs.line-length-validation.result }}"
+ LICENSE_STATUS="${{ needs.license-compliance.result }}"
+ GIT_STATUS="${{ needs.git-hygiene.result }}"
+ WORKFLOW_STATUS="${{ needs.workflow-validation.result }}"
+ VERSION_STATUS="${{ needs.version-consistency.result }}"
+ SCRIPT_STATUS="${{ needs.script-integrity.result }}"
+ ENTERPRISE_STATUS="${{ needs.enterprise-readiness.result }}"
+ HEALTH_STATUS="${{ needs.repository-health.result }}"
+ TERRAFORM_STATUS="${{ needs.terraform-validation.result }}"
+
+ PASSED=0
+ FAILED=0
+ WARNINGS=0
+ TOTAL=28
+
+ # Critical checks (must pass)
+ [ "$REPO_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
+ [ "$DOCS_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
+ [ "$CODE_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
+ [ "$LICENSE_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
+ [ "$GIT_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
+ [ "$WORKFLOW_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
+ [ "$VERSION_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
+ [ "$SCRIPT_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
+
+ # Informational checks (don't fail build)
+ if [ "$ENTERPRISE_STATUS" = "success" ]; then
+ PASSED=$((PASSED + 1))
+ else
+ WARNINGS=$((WARNINGS + 1))
+ fi
+
+ if [ "$HEALTH_STATUS" = "success" ]; then
+ PASSED=$((PASSED + 1))
+ else
+ WARNINGS=$((WARNINGS + 1))
+ fi
+
+ if [ "$TERRAFORM_STATUS" = "success" ]; then
+ PASSED=$((PASSED + 1))
+ else
+ WARNINGS=$((WARNINGS + 1))
+ fi
+
+ # Adjust total to only count critical checks for compliance percentage
+ CRITICAL_TOTAL=8
+ CRITICAL_PASSED=$((PASSED - WARNINGS))
+ COMPLIANCE_PERCENT=$((CRITICAL_PASSED * 100 / CRITICAL_TOTAL))
+
+ # Overall status badge
+ if [ "$COMPLIANCE_PERCENT" -eq 100 ]; then
+ echo "## ✅ Overall Status: **COMPLIANT** ($COMPLIANCE_PERCENT%)" >> $GITHUB_STEP_SUMMARY
+ elif [ "$COMPLIANCE_PERCENT" -ge 80 ]; then
+ echo "## ⚠️ Overall Status: **MOSTLY COMPLIANT** ($COMPLIANCE_PERCENT%)" >> $GITHUB_STEP_SUMMARY
+ elif [ "$COMPLIANCE_PERCENT" -ge 50 ]; then
+ echo "## ⚠️ Overall Status: **PARTIALLY COMPLIANT** ($COMPLIANCE_PERCENT%)" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "## ❌ Overall Status: **NON-COMPLIANT** ($COMPLIANCE_PERCENT%)" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Critical Checks:** $CRITICAL_PASSED/$CRITICAL_TOTAL passed" >> $GITHUB_STEP_SUMMARY
+ echo "**Total Checks:** $PASSED/$TOTAL passed" >> $GITHUB_STEP_SUMMARY
+ if [ "$WARNINGS" -gt 0 ]; then
+ echo "**Informational:** $WARNINGS warning(s)" >> $GITHUB_STEP_SUMMARY
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Progress bar
+ FILLED=$((COMPLIANCE_PERCENT / 5))
+ EMPTY=$((20 - FILLED))
+ BAR=""
+ for i in $(seq 1 $FILLED); do BAR="${BAR}█"; done
+ for i in $(seq 1 $EMPTY); do BAR="${BAR}░"; done
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "$BAR $COMPLIANCE_PERCENT%" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Detailed breakdown
+ echo "## Validation Results" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| Area | Status | Result | Priority |" >> $GITHUB_STEP_SUMMARY
+ echo "|------|--------|--------|----------|" >> $GITHUB_STEP_SUMMARY
+
+ # Repository Structure
+ if [ "$REPO_STATUS" = "success" ]; then
+ echo "| 📁 Repository Structure | ✅ Pass | Compliant | - |" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "| 📁 Repository Structure | ❌ Fail | **Action Required** | 🔴 Critical |" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Documentation Quality
+ if [ "$DOCS_STATUS" = "success" ]; then
+ echo "| 📚 Documentation Quality | ✅ Pass | Compliant | - |" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "| 📚 Documentation Quality | ❌ Fail | **Action Required** | 🔴 Critical |" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Coding Standards
+ if [ "$CODE_STATUS" = "success" ]; then
+ echo "| 💻 Coding Standards | ✅ Pass | Compliant | - |" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "| 💻 Coding Standards | ⚠️ Warning | Review Recommended | 🟡 Medium |" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # License Compliance
+ if [ "$LICENSE_STATUS" = "success" ]; then
+ echo "| ⚖️ License Compliance | ✅ Pass | Compliant | - |" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "| ⚖️ License Compliance | ❌ Fail | **Action Required** | 🔴 Critical |" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Git Hygiene
+ if [ "$GIT_STATUS" = "success" ]; then
+ echo "| 🧹 Git Repository Hygiene | ✅ Pass | Compliant | - |" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "| 🧹 Git Repository Hygiene | ⚠️ Warning | Review Recommended | 🟡 Medium |" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Workflow Configuration
+ if [ "$WORKFLOW_STATUS" = "success" ]; then
+ echo "| ⚙️ Workflow Configuration | ✅ Pass | Compliant | - |" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "| ⚙️ Workflow Configuration | ⚠️ Warning | Review Recommended | 🟡 Medium |" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Version Consistency
+ if [ "$VERSION_STATUS" = "success" ]; then
+ echo "| 🔢 Version Consistency | ✅ Pass | All versions match | - |" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "| 🔢 Version Consistency | ❌ Fail | **Action Required** | 🔴 Critical |" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Script Integrity
+ if [ "$SCRIPT_STATUS" = "success" ]; then
+ echo "| 🔐 Script Integrity | ✅ Pass | SHA hashes validated | - |" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "| 🔐 Script Integrity | ❌ Fail | **Action Required** | 🔴 Critical |" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Enterprise Readiness (Informational)
+ if [ "$ENTERPRISE_STATUS" = "success" ]; then
+ echo "| 🏢 Enterprise Readiness | ✅ Pass | Ready for enterprise | ℹ️ Info |" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "| 🏢 Enterprise Readiness | ℹ️ Info | Review suggestions | ℹ️ Info |" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Repository Health (Informational)
+ if [ "$HEALTH_STATUS" = "success" ]; then
+ echo "| 🏥 Repository Health | ✅ Pass | Health check passed | ℹ️ Info |" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "| 🏥 Repository Health | ℹ️ Info | Review recommendations | ℹ️ Info |" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Action items summary
+ if [ "$FAILED" -gt 0 ]; then
+ echo "## ⚡ Action Items" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**$FAILED validation area(s) require attention:**" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ [ "$REPO_STATUS" != "success" ] && echo "- 🔴 **Critical:** Fix repository structure issues" >> $GITHUB_STEP_SUMMARY
+ [ "$DOCS_STATUS" != "success" ] && echo "- 🔴 **Critical:** Improve documentation quality" >> $GITHUB_STEP_SUMMARY
+ [ "$LICENSE_STATUS" != "success" ] && echo "- 🔴 **Critical:** Resolve license compliance issues" >> $GITHUB_STEP_SUMMARY
+ [ "$CODE_STATUS" != "success" ] && echo "- 🟡 **Medium:** Review coding standards violations" >> $GITHUB_STEP_SUMMARY
+ [ "$GIT_STATUS" != "success" ] && echo "- 🟡 **Medium:** Address git repository hygiene items" >> $GITHUB_STEP_SUMMARY
+ [ "$WORKFLOW_STATUS" != "success" ] && echo "- 🟡 **Medium:** Review workflow configuration" >> $GITHUB_STEP_SUMMARY
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Next Steps:**" >> $GITHUB_STEP_SUMMARY
+ echo "1. Review detailed results in individual job outputs above" >> $GITHUB_STEP_SUMMARY
+ echo "2. Follow remediation steps provided for each failure" >> $GITHUB_STEP_SUMMARY
+ echo "3. Re-run this workflow after making corrections" >> $GITHUB_STEP_SUMMARY
+ echo "4. Reach 100% compliance before merging" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "## 🎉 Excellent!" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "Your repository is **fully compliant** with MokoStandards!" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Achievements:**" >> $GITHUB_STEP_SUMMARY
+ echo "- ✅ All required directories and files present" >> $GITHUB_STEP_SUMMARY
+ echo "- ✅ Documentation meets quality standards" >> $GITHUB_STEP_SUMMARY
+ echo "- ✅ Coding standards followed" >> $GITHUB_STEP_SUMMARY
+ echo "- ✅ License compliance verified" >> $GITHUB_STEP_SUMMARY
+ echo "- ✅ Git repository well-maintained" >> $GITHUB_STEP_SUMMARY
+ echo "- ✅ Workflows properly configured" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "---" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "📚 **Resources:**" >> $GITHUB_STEP_SUMMARY
+ echo "- [MokoStandards Documentation](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards)" >> $GITHUB_STEP_SUMMARY
+ echo "- [Repository Structure Guide](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/tree/main/docs/policy/core-structure.md)" >> $GITHUB_STEP_SUMMARY
+ echo "- [Documentation Standards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/tree/main/docs/policy/document-formatting.md)" >> $GITHUB_STEP_SUMMARY
+ echo "- [Coding Standards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards/tree/main/docs/policy/coding-style-guide.md)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "_Generated by MokoStandards Compliance Workflow v${WORKFLOW_VERSION}_" >> $GITHUB_STEP_SUMMARY
+
+ # Create tracking issue for non-compliance if on push
+ if [ "$COMPLIANCE_PERCENT" -lt 100 ] && [ "${{ github.event_name }}" = "push" ]; then
+ echo "Creating tracking issue for standards violations..."
+ fi
+
+ # Exit with error if not fully compliant
+ if [ "$COMPLIANCE_PERCENT" -lt 100 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ❌ Standards Compliance Failed" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Overall Compliance:** $COMPLIANCE_PERCENT%" >> $GITHUB_STEP_SUMMARY
+ echo "**Status:** Repository does not meet 100% compliance requirement" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required:** Review and fix all validation failures above" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "❌ ERROR: Standards compliance at $COMPLIANCE_PERCENT% - 100% required"
+ exit 1
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ✅ Full Standards Compliance Achieved" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Overall Compliance:** 100%" >> $GITHUB_STEP_SUMMARY
+ echo "**Status:** Repository meets all MokoStandards requirements" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "✅ SUCCESS: Repository is fully MokoStandards compliant"
+
+ - name: Create or reopen tracking issue for standards violations
+ if: failure()
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ REPO="${{ github.repository }}"
+ RUN_URL="${{ github.server_url }}/${REPO}/actions/runs/${{ github.run_id }}"
+ DATE=$(date -u '+%Y-%m-%d')
+ SHA="${{ github.sha }}"
+ ACTOR="${{ github.actor }}"
+ BRANCH="${{ github.ref_name }}"
+
+ # Collect failed checks
+ FAILED=""
+ [ "${{ needs.repository-structure.result }}" != "success" ] && FAILED="${FAILED}\n- Repository Structure"
+ [ "${{ needs.documentation-quality.result }}" != "success" ] && FAILED="${FAILED}\n- Documentation Quality"
+ [ "${{ needs.coding-standards.result }}" != "success" ] && FAILED="${FAILED}\n- Coding Standards"
+ [ "${{ needs.license-compliance.result }}" != "success" ] && FAILED="${FAILED}\n- License Compliance"
+ [ "${{ needs.git-hygiene.result }}" != "success" ] && FAILED="${FAILED}\n- Git Hygiene"
+ [ "${{ needs.workflow-validation.result }}" != "success" ] && FAILED="${FAILED}\n- Workflow Validation"
+ [ "${{ needs.version-consistency.result }}" != "success" ] && FAILED="${FAILED}\n- Version Consistency"
+ [ "${{ needs.script-integrity.result }}" != "success" ] && FAILED="${FAILED}\n- Script Integrity"
+ [ "${{ needs.secret-scanning.result }}" != "success" ] && FAILED="${FAILED}\n- Secret Scanning"
+ [ "${{ needs.line-length-validation.result }}" != "success" ] && FAILED="${FAILED}\n- Line Length"
+ [ "${{ needs.file-size-limits.result }}" != "success" ] && FAILED="${FAILED}\n- File Size Limits"
+ [ "${{ needs.readme-completeness.result }}" != "success" ] && FAILED="${FAILED}\n- README Completeness"
+
+ if [ -z "$FAILED" ]; then
+ echo "No failed checks to report"
+ exit 0
+ fi
+
+ TITLE="[Standards] Compliance violations — ${DATE}"
+ BODY="## Standards Compliance Violations
+
+ | Field | Value |
+ |-------|-------|
+ | **Branch** | \`${BRANCH}\` |
+ | **Commit** | \`${SHA:0:7}\` |
+ | **Actor** | @${ACTOR} |
+ | **Run** | [View workflow](${RUN_URL}) |
+
+ ### Failed Checks
+ $(printf '%b' "$FAILED")
+
+ ### Required Actions
+ 1. Review the [workflow run](${RUN_URL}) for details
+ 2. Fix each failed check
+ 3. Push to trigger a new scan
+
+ ---
+ *Auto-created by standards-compliance workflow*"
+
+ BODY=$(echo "$BODY" | sed 's/^ //')
+ LABEL="standards-violation"
+
+ gh label create "$LABEL" --repo "$REPO" --color "D73A4A" --description "Standards compliance failure" --force 2>/dev/null || true
+
+ EXISTING=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/issues?labels=${LABEL}&state=all&per_page=1&sort=created&direction=desc" 2>/dev/null \
+ 2>/dev/null | jq -r '.[0].number')
+
+ if [ -n "$EXISTING" ] && [ "$EXISTING" != "null" ]; then
+ curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/issues/${EXISTING}" 2>/dev/null -X PATCH \
+ -f title="$TITLE" -f body="$BODY" -f state="open" --silent
+ echo "Updated issue #${EXISTING}"
+ else
+ gh issue create --repo "$REPO" --title "$TITLE" --body "$BODY" \
+ --label "$LABEL" --assignee "jmiller"
+ fi
+
+# CUSTOMIZATION:
+#
+# 1. Adjust severity of checks (convert warnings to errors or vice versa)
+# 2. Add project-specific validation rules
+# 3. Integrate with custom linting tools
+# 4. Add notification steps for compliance failures
+# 5. Customize required files/directories for your project type
+
diff --git a/.github/workflows/sync-version-on-merge.yml b/.github/workflows/sync-version-on-merge.yml
new file mode 100644
index 0000000..d737457
--- /dev/null
+++ b/.github/workflows/sync-version-on-merge.yml
@@ -0,0 +1,133 @@
+# Copyright (C) 2026 Moko Consulting
+#
+# This file is part of a Moko Consulting project.
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow
+# INGROUP: MokoStandards.Automation
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /templates/workflows/shared/sync-version-on-merge.yml.template
+# VERSION: 04.06.00
+# BRIEF: Auto-bump patch version on every push to main and propagate to all file headers
+# NOTE: Synced via bulk-repo-sync to .github/workflows/sync-version-on-merge.yml in all governed repos.
+# README.md is the single source of truth for the repository version.
+
+name: Sync Version from README
+
+on:
+ pull_request:
+ types: [closed]
+ branches:
+ - main
+ workflow_dispatch:
+ inputs:
+ dry_run:
+ description: 'Dry run (preview only, no commit)'
+ type: boolean
+ default: false
+
+permissions:
+ contents: write
+ issues: write
+
+env:
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
+
+jobs:
+ sync-version:
+ name: Propagate README version
+ runs-on: ubuntu-latest
+ if: >-
+ github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch'
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ with:
+ token: ${{ secrets.GA_TOKEN || github.token }}
+ fetch-depth: 0
+
+ - name: Set up PHP
+ run: |
+ php -v && composer --version
+
+ - name: Setup MokoStandards tools
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GA_TOKEN || github.token }}"}}'
+ run: |
+ git clone --depth 1 --branch version/04 --quiet \
+ "https://x-access-token:${GH_TOKEN}@git.mokoconsulting.tech/MokoConsulting/MokoStandards.git" \
+ /tmp/mokostandards
+ cd /tmp/mokostandards
+ composer install --no-dev --no-interaction --quiet
+
+ - name: Auto-bump patch version
+ if: ${{ github.event_name != 'workflow_dispatch' && github.actor != 'gitea-actions[bot]' }}
+ run: |
+ if git diff --name-only HEAD~1 HEAD 2>/dev/null | grep -q '^README\.md$'; then
+ echo "README.md changed in this push — skipping auto-bump"
+ exit 0
+ fi
+
+ RESULT=$(php /tmp/mokostandards/api/cli/version_bump.php --path .) || {
+ echo "⚠️ Could not bump version — skipping"
+ exit 0
+ }
+ echo "Auto-bumping patch: $RESULT"
+ git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
+ git config --local user.name "gitea-actions[bot]"
+ git add README.md
+ git commit -m "chore(version): auto-bump patch ${RESULT} [skip ci]" \
+ --author="gitea-actions[bot] "
+ git push
+
+ - name: Extract version from README.md
+ id: readme_version
+ run: |
+ git pull --ff-only 2>/dev/null || true
+ VERSION=$(php /tmp/mokostandards/api/cli/version_read.php --path . 2>/dev/null)
+ if [ -z "$VERSION" ]; then
+ echo "⚠️ No VERSION in README.md — skipping propagation"
+ echo "skip=true" >> $GITHUB_OUTPUT
+ exit 0
+ fi
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
+ echo "skip=false" >> $GITHUB_OUTPUT
+ echo "✅ README.md version: $VERSION"
+
+ - name: Run version sync
+ if: ${{ steps.readme_version.outputs.skip != 'true' && inputs.dry_run != true }}
+ run: |
+ php /tmp/mokostandards/api/maintenance/update_version_from_readme.php \
+ --path . \
+ --create-issue \
+ --repo "${{ github.repository }}"
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+
+ - name: Commit updated files
+ if: ${{ steps.readme_version.outputs.skip != 'true' && inputs.dry_run != true }}
+ run: |
+ git pull --ff-only 2>/dev/null || true
+ if git diff --quiet; then
+ echo "ℹ️ No version changes needed — already up to date"
+ exit 0
+ fi
+ VERSION="${{ steps.readme_version.outputs.version }}"
+ git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
+ git config --local user.name "gitea-actions[bot]"
+ git add -A
+ git commit -m "chore(version): sync badges and headers to ${VERSION} [skip ci]" \
+ --author="gitea-actions[bot] "
+ git push
+
+ - name: Summary
+ run: |
+ VERSION="${{ steps.readme_version.outputs.version }}"
+ echo "## 📦 Version Sync — ${VERSION}" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Source:** \`README.md\` FILE INFORMATION block" >> $GITHUB_STEP_SUMMARY
+ echo "**Version:** \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY
diff --git a/.github/workflows/update-server.yml b/.github/workflows/update-server.yml
new file mode 100644
index 0000000..4f1c117
--- /dev/null
+++ b/.github/workflows/update-server.yml
@@ -0,0 +1,346 @@
+# Copyright (C) 2026 Moko Consulting
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# FILE INFORMATION
+# DEFGROUP: Gitea.Workflow
+# INGROUP: MokoStandards.Joomla
+# REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards
+# PATH: /templates/workflows/joomla/update-server.yml.template
+# VERSION: 04.06.00
+# BRIEF: Update Joomla update server XML feed with stable/rc/dev entries
+#
+# Writes updates.xml with multiple entries:
+# - stable on push to main (from auto-release)
+# - rc on push to rc/**
+# - development on push to dev/**
+#
+# Joomla filters by user's "Minimum Stability" setting.
+
+name: Update Joomla Update Server XML Feed
+
+on:
+ pull_request:
+ types: [closed]
+ branches:
+ - 'dev/**'
+ - 'alpha/**'
+ - 'beta/**'
+ - 'rc/**'
+ paths:
+ - 'src/**'
+ - 'htdocs/**'
+ workflow_dispatch:
+ inputs:
+ stability:
+ description: 'Stability tag'
+ required: true
+ default: 'development'
+ type: choice
+ options:
+ - development
+ - alpha
+ - beta
+ - rc
+ - stable
+
+env:
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
+
+permissions:
+ contents: write
+
+jobs:
+ update-xml:
+ name: Update updates.xml
+ runs-on: release
+ if: >-
+ github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch'
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ with:
+ token: ${{ secrets.GA_TOKEN || github.token }}
+ fetch-depth: 0
+
+ - name: Setup MokoStandards tools
+ env:
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GA_TOKEN || github.token }}"}}'
+ run: |
+ git clone --depth 1 --branch version/04 --quiet \
+ "https://x-access-token:${GH_TOKEN}@git.mokoconsulting.tech/MokoConsulting/MokoStandards.git" \
+ /tmp/mokostandards 2>/dev/null || true
+ if [ -d "/tmp/mokostandards" ] && [ -f "/tmp/mokostandards/composer.json" ]; then
+ cd /tmp/mokostandards && composer install --no-dev --no-interaction --quiet 2>/dev/null || true
+ fi
+
+ - name: Generate updates.xml entry
+ run: |
+ BRANCH="${{ github.ref_name }}"
+ REPO="${{ github.repository }}"
+ VERSION=$(php /tmp/mokostandards/api/cli/version_read.php --path . 2>/dev/null || echo "0.0.0")
+
+ # Auto-bump patch on alpha/beta/rc branches (not dev — dev bumps manually)
+ if [[ "$BRANCH" != dev/* ]]; then
+ git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
+ git config --local user.name "gitea-actions[bot]"
+ BUMPED=$(php /tmp/mokostandards/api/cli/version_bump.php --path . 2>/dev/null || true)
+ if [ -n "$BUMPED" ]; then
+ VERSION=$(php /tmp/mokostandards/api/cli/version_read.php --path . 2>/dev/null || echo "$VERSION")
+ git add -A
+ git commit -m "chore(version): auto-bump patch ${VERSION} [skip ci]" \
+ --author="gitea-actions[bot] " 2>/dev/null || true
+ git push 2>/dev/null || true
+ fi
+ fi
+
+ # Determine stability from branch or input
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
+ STABILITY="${{ inputs.stability }}"
+ elif [[ "$BRANCH" == rc/* ]]; then
+ STABILITY="rc"
+ elif [[ "$BRANCH" == beta/* ]]; then
+ STABILITY="beta"
+ elif [[ "$BRANCH" == alpha/* ]]; then
+ STABILITY="alpha"
+ elif [[ "$BRANCH" == dev/* ]]; then
+ STABILITY="development"
+ else
+ STABILITY="stable"
+ fi
+
+ # Parse manifest (portable — no grep -P)
+ MANIFEST=$(find . -maxdepth 2 -name "*.xml" -exec grep -l '/dev/null | head -1)
+ if [ -z "$MANIFEST" ]; then
+ echo "No Joomla manifest found — skipping"
+ exit 0
+ fi
+
+ # Extract fields using sed (works on all runners)
+ EXT_NAME=$(sed -n 's/.*\([^<]*\)<\/name>.*/\1/p' "$MANIFEST" | head -1)
+ EXT_TYPE=$(sed -n 's/.*]*type="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1)
+ EXT_ELEMENT=$(sed -n 's/.*\([^<]*\)<\/element>.*/\1/p' "$MANIFEST" | head -1)
+ EXT_CLIENT=$(sed -n 's/.*]*client="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1)
+ EXT_FOLDER=$(sed -n 's/.*]*group="\([^"]*\)".*/\1/p' "$MANIFEST" | head -1)
+ EXT_VERSION=$(sed -n 's/.*\([^<]*\)<\/version>.*/\1/p' "$MANIFEST" | head -1)
+ TARGET_PLATFORM=$(sed -n 's/.*\( \).*/\1/p' "$MANIFEST" | head -1)
+ PHP_MINIMUM=$(sed -n 's/.*\([^<]*\)<\/php_minimum>.*/\1/p' "$MANIFEST" | head -1)
+
+ # Fallbacks
+ [ -z "$EXT_NAME" ] && EXT_NAME="${{ github.event.repository.name }}"
+ [ -z "$EXT_TYPE" ] && EXT_TYPE="component"
+
+ # Templates and modules don't have — derive from
+ if [ -z "$EXT_ELEMENT" ]; then
+ EXT_ELEMENT=$(echo "$EXT_NAME" | tr '[:upper:]' '[:lower:]' | tr -d ' ')
+ fi
+
+ # Use manifest version if README version is empty
+ [ "$VERSION" = "0.0.0" ] && [ -n "$EXT_VERSION" ] && VERSION="$EXT_VERSION"
+
+ [ -z "$TARGET_PLATFORM" ] && TARGET_PLATFORM=$(printf '' "/")
+
+ CLIENT_TAG=""
+ [ -n "$EXT_CLIENT" ] && CLIENT_TAG="${EXT_CLIENT} "
+ [ -z "$CLIENT_TAG" ] && ([ "$EXT_TYPE" = "module" ] || [ "$EXT_TYPE" = "plugin" ]) && CLIENT_TAG="site "
+
+ FOLDER_TAG=""
+ [ -n "$EXT_FOLDER" ] && [ "$EXT_TYPE" = "plugin" ] && FOLDER_TAG="${EXT_FOLDER} "
+
+ PHP_TAG=""
+ [ -n "$PHP_MINIMUM" ] && PHP_TAG="${PHP_MINIMUM} "
+
+ # Version suffix for non-stable
+ DISPLAY_VERSION="$VERSION"
+ case "$STABILITY" in
+ development) DISPLAY_VERSION="${VERSION}-dev" ;;
+ alpha) DISPLAY_VERSION="${VERSION}-alpha" ;;
+ beta) DISPLAY_VERSION="${VERSION}-beta" ;;
+ rc) DISPLAY_VERSION="${VERSION}-rc" ;;
+ esac
+
+ MAJOR=$(echo "$VERSION" | awk -F. '{print $1}')
+
+ # Each stability level has its own release tag
+ case "$STABILITY" in
+ development) RELEASE_TAG="development" ;;
+ alpha) RELEASE_TAG="alpha" ;;
+ beta) RELEASE_TAG="beta" ;;
+ rc) RELEASE_TAG="release-candidate" ;;
+ *) RELEASE_TAG="v${MAJOR}" ;;
+ esac
+
+ PACKAGE_NAME="${EXT_ELEMENT}-${DISPLAY_VERSION}.zip"
+ DOWNLOAD_URL="https://git.mokoconsulting.tech/${{ github.repository }}/releases/download/${RELEASE_TAG}/${PACKAGE_NAME}"
+ INFO_URL="https://github.com/${REPO}"
+
+ # ── Build install packages (ZIP + tar.gz) ───────────────────
+ SOURCE_DIR="src"
+ [ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs"
+ if [ -d "$SOURCE_DIR" ]; then
+ EXCLUDES=".ftpignore sftp-config* *.ppk *.pem *.key .env*"
+ TAR_NAME="${EXT_ELEMENT}-${DISPLAY_VERSION}.tar.gz"
+
+ cd "$SOURCE_DIR"
+ zip -r "/tmp/${PACKAGE_NAME}" . -x $EXCLUDES
+ cd ..
+ tar -czf "/tmp/${TAR_NAME}" -C "$SOURCE_DIR" \
+ --exclude='.ftpignore' --exclude='sftp-config*' \
+ --exclude='*.ppk' --exclude='*.pem' --exclude='*.key' --exclude='.env*' .
+
+ SHA256=$(sha256sum "/tmp/${PACKAGE_NAME}" | cut -d' ' -f1)
+
+ # Ensure release exists
+ gh release view "$RELEASE_TAG" --json tagName > /dev/null 2>&1 || \
+ gh release create "$RELEASE_TAG" --title "${RELEASE_TAG} (${DISPLAY_VERSION})" --notes "${STABILITY} release" --prerelease --target main 2>/dev/null || true
+
+ # Upload both formats
+ gh release upload "$RELEASE_TAG" "/tmp/${PACKAGE_NAME}" --clobber 2>/dev/null || true
+ gh release upload "$RELEASE_TAG" "/tmp/${TAR_NAME}" --clobber 2>/dev/null || true
+
+ echo "Packages: ${PACKAGE_NAME} + ${TAR_NAME} (SHA: ${SHA256})" >> $GITHUB_STEP_SUMMARY
+ else
+ SHA256=""
+ fi
+
+ # ── Build the new entry ───────────────────────────────────────
+ NEW_ENTRY=""
+ NEW_ENTRY="${NEW_ENTRY} \n"
+ NEW_ENTRY="${NEW_ENTRY} ${EXT_NAME} \n"
+ NEW_ENTRY="${NEW_ENTRY} ${EXT_NAME} (${STABILITY}) \n"
+ NEW_ENTRY="${NEW_ENTRY} ${EXT_ELEMENT} \n"
+ NEW_ENTRY="${NEW_ENTRY} ${EXT_TYPE} \n"
+ NEW_ENTRY="${NEW_ENTRY} ${DISPLAY_VERSION} \n"
+ [ -n "$CLIENT_TAG" ] && NEW_ENTRY="${NEW_ENTRY} ${CLIENT_TAG}\n"
+ [ -n "$FOLDER_TAG" ] && NEW_ENTRY="${NEW_ENTRY} ${FOLDER_TAG}\n"
+ NEW_ENTRY="${NEW_ENTRY} \n"
+ NEW_ENTRY="${NEW_ENTRY} ${STABILITY} \n"
+ NEW_ENTRY="${NEW_ENTRY} \n"
+ NEW_ENTRY="${NEW_ENTRY} ${INFO_URL} \n"
+ NEW_ENTRY="${NEW_ENTRY} \n"
+ TAR_URL="https://git.mokoconsulting.tech/${{ github.repository }}/releases/download/${RELEASE_TAG}/${EXT_ELEMENT}-${DISPLAY_VERSION}.tar.gz"
+ NEW_ENTRY="${NEW_ENTRY} ${DOWNLOAD_URL} \n"
+ NEW_ENTRY="${NEW_ENTRY} ${TAR_URL} \n"
+ NEW_ENTRY="${NEW_ENTRY} \n"
+ [ -n "$SHA256" ] && NEW_ENTRY="${NEW_ENTRY} sha256:${SHA256} \n"
+ NEW_ENTRY="${NEW_ENTRY} ${TARGET_PLATFORM}\n"
+ [ -n "$PHP_TAG" ] && NEW_ENTRY="${NEW_ENTRY} ${PHP_TAG}\n"
+ NEW_ENTRY="${NEW_ENTRY} Moko Consulting \n"
+ NEW_ENTRY="${NEW_ENTRY} https://mokoconsulting.tech \n"
+ NEW_ENTRY="${NEW_ENTRY} "
+
+ # ── Write new entry to temp file ───────────────────────────────
+ printf '%b' "$NEW_ENTRY" > /tmp/new_entry.xml
+
+ # ── Merge into updates.xml ─────────────────────────────────────
+ if [ ! -f "updates.xml" ]; then
+ printf '%s\n' '' > updates.xml
+ printf '%s\n' '' >> updates.xml
+ cat /tmp/new_entry.xml >> updates.xml
+ printf '\n%s\n' ' ' >> updates.xml
+ else
+ # Remove existing entry for this stability, insert new one
+ printf 'import re\nstability = "%s"\n' "${STABILITY}" > /tmp/merge_xml.py
+ printf 'with open("updates.xml") as f: content = f.read()\n' >> /tmp/merge_xml.py
+ printf 'with open("/tmp/new_entry.xml") as f: new_entry = f.read()\n' >> /tmp/merge_xml.py
+ printf 'pattern = r" .*?" + re.escape(stability) + r" .*? \\n?"\n' >> /tmp/merge_xml.py
+ printf 'content = re.sub(pattern, "", content, flags=re.DOTALL)\n' >> /tmp/merge_xml.py
+ printf 'content = content.replace("", new_entry + "\\n")\n' >> /tmp/merge_xml.py
+ printf 'content = re.sub(r"\\n{3,}", "\\n\\n", content)\n' >> /tmp/merge_xml.py
+ printf 'with open("updates.xml", "w") as f: f.write(content)\n' >> /tmp/merge_xml.py
+ python3 /tmp/merge_xml.py 2>/dev/null || {
+ # Fallback: rebuild keeping other stability entries
+ {
+ printf '%s\n' ''
+ printf '%s\n' ''
+ for TAG in stable rc development; do
+ [ "$TAG" = "${STABILITY}" ] && continue
+ if grep -q "${TAG} " updates.xml 2>/dev/null; then
+ sed -n "//,/<\/update>/{ /${TAG}<\/tag>/p; }" updates.xml
+ fi
+ done
+ cat /tmp/new_entry.xml
+ printf '\n%s\n' ' '
+ } > /tmp/updates_new.xml
+ mv /tmp/updates_new.xml updates.xml
+ }
+ fi
+
+ # Commit
+ git config --local user.email "gitea-actions[bot]@mokoconsulting.tech"
+ git config --local user.name "gitea-actions[bot]"
+ git add updates.xml
+ git diff --cached --quiet || {
+ git commit -m "chore: update updates.xml (${STABILITY}: ${DISPLAY_VERSION}) [skip ci]" \
+ --author="gitea-actions[bot] "
+ git push
+ }
+
+ - name: SFTP deploy to dev server
+ if: contains(github.ref, 'dev/')
+ env:
+ DEV_HOST: ${{ vars.DEV_FTP_HOST }}
+ DEV_PATH: ${{ vars.DEV_FTP_PATH }}
+ DEV_SUFFIX: ${{ vars.DEV_FTP_SUFFIX }}
+ DEV_USER: ${{ vars.DEV_FTP_USERNAME }}
+ DEV_PORT: ${{ vars.DEV_FTP_PORT }}
+ DEV_KEY: ${{ secrets.DEV_FTP_KEY }}
+ DEV_PASS: ${{ secrets.DEV_FTP_PASSWORD }}
+ GH_TOKEN: ${{ secrets.GA_TOKEN || github.token }}
+ run: |
+ # ── Permission check: admin or maintain role required ──────
+ ACTOR="${{ github.actor }}"
+ REPO="${{ github.repository }}"
+ PERMISSION=$(curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/collaborators/${ACTOR}/permission" 2>/dev/null \
+ 2>/dev/null | jq -r '.permission' || \
+ curl -sf -H "Authorization: token ${{ secrets.GA_TOKEN }}" "${{GITEA_URL:-https://git.mokoconsulting.tech}}/api/v1/repos/${{ github.repository }}/collaborators/${ACTOR}" 2>/dev/null \
+ 2>/dev/null | jq -r '.role' || echo "read")
+ case "$PERMISSION" in
+ admin|maintain|write) ;;
+ *)
+ echo "Deploy denied: ${ACTOR} has '${PERMISSION}' — requires admin, maintain, or write"
+ exit 0
+ ;;
+ esac
+
+ [ -z "$DEV_HOST" ] || [ -z "$DEV_PATH" ] && { echo "DEV FTP not configured — skipping SFTP"; exit 0; }
+
+ SOURCE_DIR="src"
+ [ ! -d "$SOURCE_DIR" ] && SOURCE_DIR="htdocs"
+ [ ! -d "$SOURCE_DIR" ] && exit 0
+
+ PORT="${DEV_PORT:-22}"
+ REMOTE="${DEV_PATH%/}"
+ [ -n "$DEV_SUFFIX" ] && REMOTE="${REMOTE}/${DEV_SUFFIX#/}"
+
+ printf '{"host":"%s","port":%s,"username":"%s","remotePath":"%s"' \
+ "$DEV_HOST" "$PORT" "$DEV_USER" "$REMOTE" > /tmp/sftp-config.json
+ if [ -n "$DEV_KEY" ]; then
+ echo "$DEV_KEY" > /tmp/deploy_key && chmod 600 /tmp/deploy_key
+ printf ',"privateKeyPath":"/tmp/deploy_key"}' >> /tmp/sftp-config.json
+ else
+ printf ',"password":"%s"}' "$DEV_PASS" >> /tmp/sftp-config.json
+ fi
+
+ PLATFORM=$(php /tmp/mokostandards/api/cli/platform_detect.php --path . 2>/dev/null || true)
+ if [ "$PLATFORM" = "waas-component" ] && [ -f "/tmp/mokostandards/api/deploy/deploy-joomla.php" ]; then
+ php /tmp/mokostandards/api/deploy/deploy-joomla.php --path . --src-dir "$SOURCE_DIR" --config /tmp/sftp-config.json
+ elif [ -f "/tmp/mokostandards/api/deploy/deploy-sftp.php" ]; then
+ php /tmp/mokostandards/api/deploy/deploy-sftp.php --path . --src-dir "$SOURCE_DIR" --config /tmp/sftp-config.json
+ fi
+ rm -f /tmp/deploy_key /tmp/sftp-config.json
+ echo "SFTP deploy to dev complete" >> $GITHUB_STEP_SUMMARY
+
+ - name: Summary
+ if: always()
+ run: |
+ echo "## Joomla Update Server" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
+ echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
+ echo "| Stability | \`${STABILITY}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Version | \`${DISPLAY_VERSION}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Element | \`${EXT_ELEMENT}\` |" >> $GITHUB_STEP_SUMMARY
+ echo "| Download | [ZIP](${DOWNLOAD_URL}) |" >> $GITHUB_STEP_SUMMARY
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f62ed2d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,207 @@
+# ============================================================
+# Local task tracking (not version controlled)
+# ============================================================
+TODO.md
+
+# ============================================================
+# Environment and secrets
+# ============================================================
+.env
+.env.local
+.env.*.local
+*.local.php
+*.secret.php
+configuration.php
+configuration.*.php
+configuration.local.php
+conf/conf.php
+conf/conf*.php
+secrets/
+*.secrets.*
+
+# ============================================================
+# Logs, dumps and databases
+# ============================================================
+*.db
+*.db-journal
+*.dump
+*.log
+*.pid
+*.seed
+
+
+# ============================================================
+# OS / Editor / IDE cruft
+# ============================================================
+.DS_Store
+Thumbs.db
+desktop.ini
+Thumbs.db:encryptable
+ehthumbs.db
+ehthumbs_vista.db
+$RECYCLE.BIN/
+System Volume Information/
+*.lnk
+Icon?
+.idea/
+.settings/
+.claude/
+.vscode/*
+!.vscode/tasks.json
+!.vscode/settings.json.example
+!.vscode/extensions.json
+*.code-workspace
+*.sublime*
+.project
+.buildpath
+.classpath
+*.bak
+*.swp
+*.swo
+*.tmp
+*.old
+*.orig
+
+# ============================================================
+# Dev scripts and scratch
+# ============================================================
+TODO.md
+todo*
+*ffs*
+
+# ============================================================
+# SFTP / sync tools
+# ============================================================
+sftp-config*.json
+sftp-config.json.template
+sftp-settings.json
+
+# ============================================================
+# Sublime SFTP / FTP sync
+# ============================================================
+*.sublime-project
+*.sublime-workspace
+*.sublime-settings
+.libsass.json
+*.ffs*
+
+# ============================================================
+# Replit / cloud IDE
+# ============================================================
+.replit
+replit.md
+
+# ============================================================
+# Archives / release artifacts
+# ============================================================
+*.7z
+*.rar
+*.tar
+*.tar.gz
+*.tgz
+*.zip
+artifacts/
+release/
+releases/
+
+# ============================================================
+# Build outputs and site generators
+# ============================================================
+.mkdocs-build/
+.cache/
+.parcel-cache/
+build/
+dist/
+out/
+site/
+*.map
+*.css.map
+*.js.map
+*.tsbuildinfo
+
+# ============================================================
+# CI / test artifacts
+# ============================================================
+.coverage
+.coverage.*
+coverage/
+coverage.xml
+htmlcov/
+junit.xml
+reports/
+test-results/
+tests/_output/
+.github/local/
+.github/workflows/*.log
+
+# ============================================================
+# Node / JavaScript
+# ============================================================
+node_modules/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+.pnpm-store/
+.yarn/
+.npmrc
+.eslintcache
+package-lock.json
+
+# ============================================================
+# PHP / Composer tooling
+# ============================================================
+composer.lock
+*.phar
+codeception.phar
+.phpunit.result.cache
+.php_cs.cache
+.php-cs-fixer.cache
+.phpstan.cache
+.phplint-cache
+phpmd-cache/
+.psalm/
+.rector/
+
+# ============================================================
+# Python
+# ============================================================
+__pycache__/
+*.py[cod]
+*.pyc
+*$py.class
+*.so
+.Python
+.eggs/
+*.egg
+*.egg-info/
+.installed.cfg
+MANIFEST
+develop-eggs/
+downloads/
+eggs/
+parts/
+sdist/
+var/
+wheels/
+ENV/
+env/
+.venv/
+venv/
+.pytest_cache/
+.mypy_cache/
+.ruff_cache/
+.pyright/
+.tox/
+.nox/
+*.cover
+*.coverage
+hypothesis/
+
+# Custom theme palettes (site-specific, not version controlled)
+# Note: src/templates/*.custom.css are STARTER templates (tracked)
+src/media/css/theme/*.custom.css
+src/media/css/theme/*.custom.min.css
+templates/*.custom.css
+update.xml
+.moko-standards
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..727767a
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,630 @@
+
+
+# Changelog — MokoOnyx (VERSION: 03.09.03)
+
+All notable changes to the MokoOnyx Joomla template are documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [03.10.00] - 2026-04-18 — Bridge Release (MokoOnyx → MokoOnyx)
+
+### Important
+- **Template Rename** — MokoOnyx is being renamed to **MokoOnyx**. This bridge release automatically migrates your template settings, menu assignments, and files to the new name. MokoOnyx can be safely uninstalled after this update.
+
+### Added
+- **Offline page redesign** — Full-viewport background from Joomla offline_image or header background, glass card overlay, centered logo with glow, login accordion, copyright footer
+- **CSS variable click-to-copy** — Text containing `--variable-name` patterns is wrapped in clickable chips that copy to clipboard with toast notification
+- **Brand-aside 3-column layout** — Flex columns like top-a with card style
+- **mod_stats table layout** — Converted from definition list to semantic table
+- **Favicon multi-format support** — Now handles PNG, JPEG, GIF, WebP, BMP (not just PNG)
+- **Theme variables** — `--theme-fab-bg`, `--theme-fab-color`, `--theme-fab-btn-bg`, `--theme-fab-border`, `--offline-card-bg`
+- **Footer CSS variables** — Added to CSS Variables reference tab
+- **Bridge migration script** — `helper/bridge.php` handles automatic MokoOnyx → MokoOnyx migration
+- **Dedicated release runner** — Release workflows run on isolated `release` label runner
+- **Runner fleet** — 3 CI + 1 release runner (12 concurrent jobs)
+
+### Changed
+- **Gitea-primary CI/CD** — All workflows use Gitea API, GitHub is backup for stable/RC only
+- **Theme switcher** — Larger, bordered, theme-aware colors (off-white on dark, primary on light)
+- **Auto switch** — Red when off, green when on
+- **A11y toolbar** — Theme-aware colors for dark mode visibility
+- **Search button border** — Matches input border (`--input-border-color`)
+- **Offline message** — 0=hidden, 1=custom message, 2=system language string
+- **Light theme fonts** — Fixed trailing `)` syntax error, normalized quote style to match dark
+- **`--accent-color-secondary`** — Unified to `#6fb3ff` across both themes
+- **`--alert-color`** — Set to `#000` in light theme
+
+### Removed
+- Brand showcase tab (redundant with theme preview)
+- Position selectors for a11y/theme FAB (forced to bottom-right)
+- Custom theme CSS from git tracking (site-specific, gitignored)
+
+### Fixed
+- SHA-256 checksum format — Removed `sha256:` prefix (Joomla expects raw hex)
+- Favicon path resolution — Strips `#joomlaImage://` fragment, tries multiple path candidates
+- `REQUIRE_SIGNIN_VIEW` — Set to `false` for public release downloads
+- Release workflow — Uses Gitea API to update `updates.xml` on main (bypasses branch protection)
+- Language loading on offline page — `com_users` and core language files loaded explicitly
+
+---
+
+## [Unreleased] - 2026-04-02
+
+### Added
+
+- **Favicon configuration** — New "Favicon" tab in template config; upload a PNG and all favicon sizes are auto-generated via PHP GD (ICO, Apple Touch Icon 180px, Android Chrome 192/512px, site.webmanifest)
+- **Module overrides** — 11 new `default.php` layout overrides for Joomla core modules: `mod_custom`, `mod_articles_latest`, `mod_articles_popular`, `mod_articles_news`, `mod_articles_category`, `mod_breadcrumbs`, `mod_footer`, `mod_login`, `mod_finder`, `mod_tags_popular`, `mod_tags_similar`, `mod_related_items`
+- **Module title support** — All module overrides respect `$module->showtitle`, `header_tag`, `header_class`, and `moduleclass_sfx` parameters
+- **Module CSS** — BEM-scoped styles for module titles, article lists, tag badges, search forms, login forms, breadcrumbs, and footer content
+- **Hero card variables** — Full variable-driven hero system: `--hero-card-bg`, `--hero-card-color`, `--hero-card-overlay`, `--hero-card-border-radius`, `--hero-card-padding-x/y`, `--hero-card-max-width`, plus `--hero-alt-card-*` for secondary variant
+- **Hero mobile breakpoint** — Photo background hidden on mobile (≤767.98px), hero card becomes full-bleed (100dvh, no border-radius)
+- **CSS fallback values** — 1365 `var()` calls in template.css now include inline fallback values
+- **Card border-radius** — `.card` now has `.25rem` fallback on `var(--card-border-radius)`
+- **Usage section in README** — Added missing "Usage" section required by MokoStandards
+
+### Changed
+
+- **Button backgrounds** — `--btn-bg: transparent` changed to `var(--body-bg)` in dark and light themes
+- **Offcanvas close button** — `.offcanvas-header .btn-close` now gets `background-color` from `--offcanvas-bg`
+- **Custom template sync** — Both `dark.custom.css` and `light.custom.css` now contain all variables from their standard counterparts (was missing 223 variables)
+- **Overlay layer** — Added `--hero-overlay-bg-position` and `--hero-overlay-bg-size` variables
+- **Legacy CSS cleanup** — Removed vendor prefixes (`-webkit-box`, `-ms-flexbox`) from `.overlay` rules, replaced with modern flexbox
+
+### Removed
+
+- **FILE INFORMATION headers** — Stripped DEFGROUP/INGROUP/PATH/VERSION/BRIEF metadata from all PHP, CSS, JS, INI, and HTML files (kept in XML and README per policy)
+- **Mobile overrides** — Deleted 26 `mobile.php` layout files and their empty parent directories
+- **Joomla-specific gitignore entries** — Removed ~700 lines of Joomla CMS core paths from `.gitignore` (not applicable to a template repository)
+
+### Fixed
+
+- **CI: composer install** — Workflow `standards-compliance.yml` now conditionally runs `composer install` only when `composer.json` exists
+- **CI: YAML syntax** — Fixed invalid YAML in `auto-update-sha.yml` caused by multiline commit message in run block
+
+---
+
+## [03.09.02] - 2026-03-26
+
+### Added - Hero Variant System & Block Color System
+
+#### Hero Variants
+- **`.hero#primary`** and **`.hero#secondary`** CSS variant system for visually distinct hero treatments
+- Shared `.hero` base class with `background-size: cover`, `border-radius: .5rem`, and `overflow: hidden`
+- Six new CSS variables (`--hero-primary-bg-color`, `--hero-primary-overlay`, `--hero-primary-color`, and secondary equivalents)
+- Light and dark mode defaults in custom palette templates
+
+#### Block Color System
+- Automatic `:nth-child()` slot palette for `top-a`, `top-b`, `bottom-a`, `bottom-b` module positions
+- Four color slots (`--block-color-1` through `--block-color-4`) with matching text variables
+- Named per-module overrides: `#block-highlight`, `#block-cta`, `#block-alert`
+- ID specificity wins over `:nth-child()` — no `!important` needed
+
+#### Files Modified
+- `src/media/css/template.css` — hero variant rules, block color `:nth-child()` rules, named override rules
+- `src/media/css/theme/light.standard.css` — hero and block color variables (light standard)
+- `src/media/css/theme/dark.standard.css` — hero and block color variables (dark standard)
+- `src/templates/light.custom.css` — hero and block color variables (light custom starter)
+- `src/templates/dark.custom.css` — hero and block color variables (dark custom starter)
+- `src/templateDetails.xml` — Theme Preview tab, hero/block note fields, scriptfile registration, version bump to 03.09.02
+- `src/language/en-GB/tpl_mokoonyx.ini` — language strings for new admin fields (British English)
+- `src/language/en-US/tpl_mokoonyx.ini` — language strings for new admin fields (American English)
+- `docs/CSS_VARIABLES.md` — full variable reference for both systems, sync script documentation
+- `CHANGELOG.md` — this entry
+
+#### Files Added
+- `src/templates/theme-test.html` — Bootstrap-style test page with branded showcase, CSS variable swatches, hero demos, block color demos, and color test image
+- `src/script.php` — Joomla install/update lifecycle script (runs CSS variable sync on upgrade, checks PHP/Joomla minimum versions)
+- `src/sync_custom_vars.php` — CLI/library utility that detects missing CSS variables in user custom palettes and injects them
+- `src/templates/brand-showcase.html` — Interactive color system gradients with hover pixel sampler, Bootstrap component showcase
+
+#### Variable Audit
+- All 20 hero/block variables confirmed present in all 4 theme files (light/dark standard + custom)
+- No duplicate variable declarations found across any theme file
+- `--gutter-x` references in template.css are self-scoped to grid containers (standard Bootstrap 5 behavior, not a `:root` variable)
+
+---
+
+## [03.08.03] - 2026-02-27
+
+### Added - Main Menu Collapsible Dropdown Override
+
+**New feature**: Added responsive "Main Menu" mod_menu override with Bootstrap 5 collapsible dropdown functionality.
+
+#### What's New
+- **Main Menu module override** with full Bootstrap 5 responsive navbar
+- Collapsible hamburger menu for mobile devices
+- Multi-level dropdown support with hover on desktop, tap on mobile
+- WCAG 2.1 compliant touch targets (48px on mobile, 44px on desktop)
+- BEM naming convention: `.mod-menu-main__*`
+- **Appears as "Mainmenu" layout option** in Joomla admin module settings
+
+#### Files Added
+- `src/templates/html/mod_menu/mainmenu.php` - Main layout with Bootstrap navbar
+- `src/templates/html/mod_menu/mainmenu_component.php` - Component menu items
+- `src/templates/html/mod_menu/mainmenu_heading.php` - Heading menu items
+- `src/templates/html/mod_menu/mainmenu_separator.php` - Separator menu items
+- `src/templates/html/mod_menu/mainmenu_url.php` - URL menu items
+- `src/templates/html/mod_menu/index.html` - Security file
+
+#### Features
+- **Bootstrap 5 Navbar**: Uses Bootstrap's native navbar-nav structure
+- **Collapsible on Mobile**: Hamburger menu with smooth collapse animation
+- **Dropdown Menus**: Multi-level dropdown support with caret indicators
+- **Responsive Breakpoints**: Mobile-first design adapting at 768px and 992px
+- **Touch-Friendly**: 48px minimum touch targets on mobile
+- **Accessible**: ARIA labels and keyboard navigation support
+- **Active States**: Visual indicators for current and active menu items
+- **Alternative Layout**: Named `mainmenu.php` (not `default.php`) to appear as selectable layout option in Joomla admin
+
+#### CSS Architecture
+- 200+ lines of responsive CSS in template.css
+- BEM naming: `.mod-menu-main`, `.mod-menu-main__list`, `.mod-menu-main__link`
+- CSS variables integration for colors and borders
+- Hover effects on desktop, tap effects on mobile
+- Smooth transitions and animations
+
+#### Module Count Update
+- **Before**: 16 module overrides
+- **After**: 17 module overrides (added mod_menu "Main Menu")
+- **Component overrides**: Still 7 (unchanged)
+
+### Removed - mod_search Override
+
+**Cassiopeia approach**: Removed mod_search override to align with Cassiopeia template philosophy of not overriding standard Joomla modules.
+
+#### Reason for Removal
+- mod_search is a standard Joomla core module
+- Following Cassiopeia template approach: use core layouts for standard modules
+- Prevents potential language loading issues
+- Ensures compatibility with future Joomla updates
+- Core mod_search already includes responsive design and accessibility features
+
+#### Files Removed
+- `src/templates/html/mod_search/default.php` - Custom search module layout
+- `src/templates/html/mod_search/index.html` - Security file
+
+#### Module Count Update (After Removal)
+- **Before**: 17 module overrides
+- **After**: 16 module overrides (removed mod_search)
+- **Component overrides**: Still 7 (unchanged)
+
+### Removed - Documentation Cleanup
+
+**Documentation policy**: Removed all markdown files from `src/templates/html/` directory. All documentation belongs in `docs/` folder only.
+
+#### Files Removed (9 markdown files)
+- `src/templates/html/STANDARD_MODULES_README.md`
+- `src/templates/html/INDUSTRY_MODULES_README.md`
+- `src/templates/html/VIRTUEMART_MODULES_README.md`
+- `src/templates/html/mod_virtuemart_cart/README.md`
+- `src/templates/html/mod_virtuemart_category/README.md`
+- `src/templates/html/mod_virtuemart_currencies/README.md`
+- `src/templates/html/mod_virtuemart_manufacturer/README.md`
+- `src/templates/html/mod_virtuemart_product/README.md`
+- `src/templates/html/mod_search/README.md`
+
+**Note**: All module override documentation is consolidated in `docs/MODULE_OVERRIDES.md`. The `src/templates/html/` directory now contains only PHP override files and `index.html` security files.
+
+**Note**: Unlike the previously removed mod_menu override (v03.08.01), this new "Main Menu" override is properly structured based on Joomla core layouts and Bootstrap 5, ensuring language strings load correctly and menu functionality works as expected. The layout is named `mainmenu.php` (not `default.php`) to appear as an alternative layout option "Mainmenu" in the Joomla admin module dropdown selector, preserving Joomla's core default menu layout.
+
+## [03.08.02] - 2026-02-27
+
+### Removed - Fix Language Loading in All Module Overrides
+
+**Critical fix**: Removed standard Joomla module overrides to fix language string loading issues. Following Cassiopeia template approach.
+
+#### Problem
+- Default language strings not loading in module overrides (mod_breadcrumbs, mod_login, mod_articles_latest)
+- Language constants displayed instead of translated text (e.g., "MOD_LOGIN_VALUE_USERNAME" instead of "Username")
+- Custom overrides interfered with Joomla's module initialization and language loading process
+
+#### Solution - Cassiopeia Approach
+- **Removed** standard Joomla module overrides:
+ - `src/templates/html/mod_breadcrumbs/` (2 files)
+ - `src/templates/html/mod_login/` (2 files)
+ - `src/templates/html/mod_articles_latest/` (2 files)
+- Template now uses Joomla's core module layouts for standard modules
+- Language files load automatically via Joomla's module system
+- Custom styling can still be applied via CSS using module-specific classes
+- **Retained** third-party extension overrides where they add mobile-responsive value:
+ - VirtueMart modules (5): mod_virtuemart_cart, _category, _currencies, _manufacturer, _product
+ - Community Builder modules (2): mod_cblogin, mod_comprofilerOnline
+ - Other extensions (9): mod_acymailing, mod_hikashop_cart, mod_k2_content, mod_kunena*, mod_osmembership, mod_search
+
+#### Cassiopeia Template Philosophy
+- Cassiopeia (Joomla's default template) does NOT override standard module layouts
+- It relies on core Joomla module files and applies styling via CSS
+- Overrides are only created when structural changes are absolutely necessary
+- This ensures compatibility, automatic language loading, and easier maintenance
+
+#### Module Count Update
+- **Before**: 19 module overrides
+- **After**: 16 module overrides
+- **Removed**: 3 standard Joomla modules (breadcrumbs, login, articles_latest)
+- **Component overrides**: Still 7 (unchanged)
+
+#### Files Removed
+- `src/templates/html/mod_breadcrumbs/default.php`
+- `src/templates/html/mod_breadcrumbs/index.html`
+- `src/templates/html/mod_login/default.php`
+- `src/templates/html/mod_login/index.html`
+- `src/templates/html/mod_articles_latest/default.php`
+- `src/templates/html/mod_articles_latest/index.html`
+
+**Note**: This follows Joomla best practices by using core layouts for standard modules. Styling is handled via CSS. Third-party extension overrides remain for mobile responsiveness.
+
+## [03.08.01] - 2026-02-27
+
+### Removed - Fix Breaking Overrides
+
+**Critical fix**: Removed mod_menu override that was causing menu links to break and language strings not to load.
+
+#### Problem
+- mod_menu override files (default.php, default_component.php, default_url.php) were attempting to load menu-specific layouts that don't exist in the template
+- This broke Joomla's core menu rendering system
+- Menu links were not functional
+- Language strings were not loading properly in menus
+
+#### Solution
+- **Removed** entire `src/templates/html/mod_menu/` directory (4 files)
+- Template now uses Joomla's default menu rendering
+- Custom styling can still be applied via CSS using `.mod-menu` class
+- All menu functionality restored to standard Joomla behavior
+
+#### Documentation Updates
+- Updated MODULE_OVERRIDES.md: Changed count from 20 to 19 module overrides, removed mod_menu section, added note about removal
+- Updated STANDARD_MODULES_README.md: Removed mod_menu documentation, renumbered remaining modules, updated file structure
+- Updated testing checklists to remove mod_menu references
+- **Added clarification**: MokoOnyx is a standalone template extension (not a package)
+- Updated updates.xml to version 03.08.01
+
+#### Files Removed
+- `src/templates/html/mod_menu/default.php`
+- `src/templates/html/mod_menu/default_component.php`
+- `src/templates/html/mod_menu/default_url.php`
+- `src/templates/html/mod_menu/index.html`
+
+**Note**: This is a patch release that removes problematic overrides to restore core functionality. Menu styling via CSS remains intact. MokoOnyx remains a standalone Joomla template extension (type="template"), not bundled as a package.
+
+## [03.08.00] - 2026-02-22
+
+### Added - Community Builder Component Overrides
+
+Minor version bump adding **4 Community Builder component view overrides** to complement the existing CB module overrides (mod_cblogin, mod_comprofilerOnline).
+
+#### Community Builder Components (4 views)
+- **com_comprofiler/userprofile**: User profile display with avatar, tabs, and custom fields in responsive layout
+- **com_comprofiler/userslist**: User directory with search functionality and responsive grid (1-3 columns)
+- **com_comprofiler/registers**: User registration form with multi-step fieldsets, validation, captcha support
+- **com_comprofiler/login**: Login page with remember me checkbox, registration and password recovery links
+
+#### CSS Architecture (600+ lines)
+- Mobile-first responsive design with Bootstrap breakpoints (576px, 768px, 992px)
+- BEM naming convention (`.cb-profile__`, `.cb-userslist__`, `.cb-register__`, `.cb-login__`)
+- Integrated with template CSS variables for consistent theming
+- 48px touch targets on mobile, 44px on desktop (WCAG 2.1 Level AA)
+- 16px input font size on mobile to prevent iOS zoom
+- Responsive grids adapting from 1 column (mobile) to 2-3 columns (desktop)
+
+#### Accessibility Features
+- Full ARIA labels and descriptions for screen readers
+- Semantic HTML5 structure with proper landmarks
+- Keyboard navigation support throughout
+- Required field indicators with visually-hidden labels
+- Focus states with visible outlines
+
+#### Security Best Practices
+- Proper output escaping with htmlspecialchars() and ENT_QUOTES
+- _JEXEC security checks in all PHP files
+- index.html protection files in all directories (6 files)
+- CSRF token support in forms
+- Input validation and error display
+
+### Technical Details
+- **Files Added**: 11 (4 component view files + 6 index.html + 1 root index.html)
+- **CSS Lines Added**: 600+ lines of responsive styles
+- **PHP Validation**: All files pass syntax validation
+- **Component Views**: userprofile, userslist, registers, login
+- **Documentation**: Ready for MODULE_OVERRIDES.md update
+
+## [03.07.00] - 2026-02-22
+
+### Added - Mobile-Responsive Module & Component Overrides
+
+This major release introduces **20 mobile-responsive module overrides** and **3 component overrides** designed to enhance the mobile user experience across standard Joomla, VirtueMart, Community Builder, and popular third-party extensions.
+
+#### Search Module
+- **mod_search**: Mobile-responsive search with multiple button positions (left, right, top, bottom), 48px touch targets, 16px input font to prevent iOS zoom
+
+#### VirtueMart E-Commerce Modules (5 modules)
+- **mod_virtuemart_cart**: Shopping cart with responsive product cards, remove buttons, price display
+- **mod_virtuemart_product**: Product showcase with responsive grid (1-4 columns), hover effects, ratings
+- **mod_virtuemart_currencies**: Currency selector dropdown with accessible styling
+- **mod_virtuemart_category**: Category navigation with hierarchical display, product counts
+- **mod_virtuemart_manufacturer**: Manufacturer/brand display with responsive grid (2-4 columns)
+- **VIRTUEMART_MODULES_README.md**: Comprehensive master documentation for all VirtueMart overrides
+
+#### Standard Joomla & Community Builder Modules (6 modules)
+- **mod_menu**: Main navigation with multiple layout files (default, component, URL), responsive horizontal/vertical layouts
+- **mod_breadcrumbs**: Breadcrumb navigation with Schema.org markup for SEO
+- **mod_login**: User login/logout form with 2FA support, remember me checkbox
+- **mod_articles_latest**: Latest articles with responsive cards, metadata, featured badges
+- **mod_cblogin**: Community Builder login with avatar display, profile links
+- **mod_comprofilerOnline**: CB online users with avatar grid, online status indicators
+- **STANDARD_MODULES_README.md**: Comprehensive master documentation for standard module overrides
+
+#### Industry Extension Modules (8 modules + 2 components)
+- **mod_k2_content**: K2 content display with responsive grid (1-3 columns), featured images, metadata
+- **mod_acymailing**: Newsletter subscription form with validation, GDPR compliance
+- **mod_hikashop_cart**: HikaShop shopping cart with product list, quantity adjustment
+- **mod_kunenalatest**: Kunena forum latest posts with excerpts, avatars, reply counts
+- **mod_kunenalogin**: Kunena forum login with user avatar, statistics, quick login
+- **mod_kunenasearch**: Kunena forum search with multiple button positions
+- **mod_kunenastats**: Kunena forum statistics with visual cards, member/topic counts
+- **mod_osmembership**: OS Membership Pro plans with pricing cards, feature lists, badges
+- **com_kunena/category**: Kunena forum category list component view
+- **com_osmembership/plans**: OS Membership Pro responsive pricing table component view
+- **INDUSTRY_MODULES_README.md**: Comprehensive master documentation for industry extensions
+
+#### CSS & Styling
+- Added **2,000+ lines** of mobile-responsive CSS to `src/media/css/template.css`
+- Four dedicated CSS sections for organized styling:
+ - MOD_SEARCH MOBILE RESPONSIVE STYLES
+ - VIRTUEMART MODULE MOBILE RESPONSIVE STYLES
+ - STANDARD JOOMLA & COMMUNITY BUILDER MODULE STYLES
+ - INDUSTRY EXTENSION MODULE STYLES
+ - ADDITIONAL KUNENA & MEMBERSHIP PRO MODULE STYLES
+- BEM naming convention for all CSS classes (`.mod-search__button`, `.mod-vm-product__grid`, etc.)
+- Integration with existing template CSS variables for seamless theming
+- Responsive grids with Bootstrap-aligned breakpoints (sm, md, lg, xl, xxl)
+
+#### Documentation
+- **docs/MODULE_OVERRIDES.md**: Comprehensive guide covering all 23 overrides
+ - Feature descriptions and specifications
+ - CSS architecture and customization guide
+ - Accessibility features documentation
+ - Troubleshooting guide
+ - Best practices and usage examples
+- Individual README.md files for VirtueMart module groups (5 modules)
+- Master README files for each category (VirtueMart, Standard, Industry)
+- Security index.html files in all override directories (23 files)
+
+### Key Features Across All Overrides
+
+#### Mobile-First Responsive Design
+- Touch targets: 48px on mobile, 44px on desktop (WCAG 2.1 compliant)
+- 16px minimum input font size on mobile (prevents iOS zoom)
+- Responsive layouts: 1-4 columns based on screen size
+- Mobile-first CSS with progressive enhancement
+- Bootstrap-aligned breakpoints: 576px, 768px, 992px, 1200px, 1400px
+
+#### Accessibility
+- Full ARIA labels and descriptions on all interactive elements
+- Keyboard navigation support throughout
+- Screen reader compatible with semantic HTML5
+- WCAG 2.1 Level AA compliance
+- Proper heading hierarchy and focus management
+- Alternative text for images and icons
+
+#### Security
+- Proper output escaping with Joomla escapeHtml()
+- _JEXEC security checks in all PHP files
+- index.html protection files in all directories
+- Input validation where applicable
+- CSRF token support in forms
+
+#### Maintainability
+- BEM naming convention for CSS classes
+- Consistent code structure across all overrides
+- Comprehensive inline documentation
+- Modular, reusable components
+- Integration with template CSS variables
+
+### Changed
+- **Version**: Updated to 03.07.00 across all files
+
+### Technical Details
+- **Total Files**: 66 new files created
+ - 42 PHP override files
+ - 23 index.html security files
+ - 1 comprehensive MODULE_OVERRIDES.md documentation
+- **CSS Added**: 2,000+ lines of responsive styles
+- **Documentation**: 15,000+ words across all README files
+
+### Migration Notes
+- All overrides are opt-in and non-breaking
+- Existing sites will continue to work without changes
+- Overrides automatically apply when modules are used
+- No database changes or migration required
+- Custom overrides can coexist with template overrides
+
+### Testing
+- All PHP syntax validated
+- Code review completed (all issues resolved)
+- CodeQL security scan passed
+- Responsive design tested across breakpoints
+- Accessibility validated with ARIA compliance
+
+---
+
+## [03.06.03] - 2026-01-30
+
+### Added
+- **Templates Directory**: Created `/templates/` directory with ready-to-use color palette templates
+ - `colors_custom_light.css` - Comprehensive light mode color template with all available variables
+ - `colors_custom_dark.css` - Comprehensive dark mode color template with all available variables
+- **CSS Variables Documentation**: Added complete CSS variables reference guide (`docs/CSS_VARIABLES.md`)
+ - Complete list of all customizable CSS variables
+ - Organized by category (colors, typography, borders, etc.)
+ - Usage examples and tips for customization
+ - Light and dark mode variable differences documented
+
+### Changed
+- **README**: Updated title to "README - MokoOnyx (VERSION: 03.09.03)"
+- **README**: Fixed custom color variables instructions with correct file paths
+- **README**: Updated example CSS variables to use actual template variable names (e.g., `--color-link` instead of `--cassiopeia-color-link`)
+- **README**: Added note that custom color files are excluded from version control via `.gitignore`
+- **README**: Enhanced Custom Color Palettes section with step-by-step instructions
+- **README**: Added link to CSS Variables documentation for complete reference
+- **TOC CSS**: Updated bootstrap-toc.css to use template color variables for proper theme integration
+- **Version**: Updated version to 03.06.03 across all files
+
+### Documentation
+- **docs/README.md**: Added CSS Variables Reference to developer documentation section
+- **docs/README.md**: Updated project structure to include `/templates/` directory
+- **docs/README.md**: Updated version to 03.06.03
+- Clarified that `colors_custom.css` files are gitignored to prevent fork-specific customizations from being committed
+
+## [03.06.02] - 2026-01-30
+
+### Major Rebrand
+This release includes a complete rebrand from "Moko-Cassiopeia" (hyphenated) to "MokoOnyx" (camelCase).
+
+### Changed
+- **Naming Convention**: Changed template identifier from `moko-cassiopeia` to `mokoonyx` across all files
+- **Display Name**: Updated from "Moko-Cassiopeia" to "MokoOnyx" in all documentation and language files
+- **Language Constants**: Renamed all language keys from `TPL_MOKO-CASSIOPEIA_*` to `TPL_MOKOONYX_*`
+- **Language Files**: Renamed from `tpl_moko-cassiopeia.*` to `tpl_mokoonyx.*` (4 files)
+- **Media Paths**: Updated from `media/templates/site/moko-cassiopeia/` to `media/templates/site/mokoonyx/`
+- **Repository URLs**: Updated all references to use `MokoOnyx` casing
+- **Template Element**: Changed Joomla extension element name from `moko-cassiopeia` to `mokoonyx`
+- **Documentation**: Updated all markdown files, XML manifests, and code comments
+
+### Removed
+- **Default Assets**: Removed `logo.svg` and `favicon.ico` to allow clean installations
+- **Template Overrides**: Removed all template override files (48 files, ~4,500 lines)
+ - Removed `src/templates/html/` folder entirely
+ - Removed overrides for: com_content, com_contact, com_engage, mod_menu, mod_custom, mod_gabble, layouts/chromes
+ - Template now inherits all rendering from Joomla Cassiopeia defaults
+ - Updated `templateDetails.xml` to remove html folder reference
+
+### Breaking Changes
+⚠️ **Important**: This release contains breaking changes:
+- Existing installations will see template name change in Joomla admin
+- Custom code referencing old language constants (`TPL_MOKO-CASSIOPEIA_*`) will need updates
+- Custom code referencing old media paths will need updates
+- Sites relying on custom template overrides will revert to Cassiopeia defaults
+- Extension element name changed (may require reinstallation in some cases)
+
+### Migration Notes
+- Backup your site before upgrading
+- Review any custom code for references to old naming convention
+- Test thoroughly after upgrade, especially if using custom overrides
+
+## [03.06.00] - 2026-01-28
+
+### Changed
+- Updated version to 03.06.00 across all files
+- Standardized version numbering format
+
+## [03.05.01] - 2026-01-09
+
+### Added
+- Added `dependency-review.yml` workflow for dependency vulnerability scanning
+- Added `standards-compliance.yml` workflow for MokoStandards validation
+- Added `.github/dependabot.yml` configuration for automated security updates
+- Added `docs/README.md` as documentation index
+
+### Changed
+- Removed custom `codeql-analysis.yml` workflow (repository uses GitHub's default CodeQL setup)
+- Enforced repository compliance with MokoStandards requirements
+- Improved security posture with automated scanning and dependency management
+
+## [03.05.00] - 2026-01-04
+
+### Added
+- Created `.github/workflows` directory structure
+
+### Changed
+- Replaced `./CODE_OF_CONDUCT.md` from `MokoStandards`
+- Replaced `./CONTRIBUTING.md` from `MokoStandards`
+- TODO split to own file
+
+## [03.01.00] - 2025-12-16
+
+### Added
+- Created `.github/workflows/` directory for GitHub Actions
+
+## [03.00.00] - 2025-12-09
+
+### Changed
+- Copyright Headers updated to MokoCodingDefaults standards
+- Fixed `./templates/mokoonyx/index.php` color style injection
+- Upgraded Font Awesome 6 to Font Awesome 7 Free
+- Added Font Awesome 7 Free style fallback
+
+### Removed
+- Removed `./CODE_OF_CONDUCT.md` (replaced with MokoStandards version)
+- Removed `./CONTRIBUTING.md` (replaced with MokoStandards version)
+
+## [02.01.05] - 2025-09-04
+
+### Changed
+- Repaired template.css and colors_standard.css
+
+### Removed
+- Removed vmbasic.css
+
+## [02.00.00] - 2025-08-30
+
+### Added - Dark Mode Toggle
+- Frontend toggle switch included in template
+- JavaScript handles switching between light/dark modes
+- Dark mode CSS rules applied across template styles
+- Automatic persistence of user choice (via localStorage)
+- Admins can override default mode in template settings
+
+### Added - Header Parameters Update
+- Added logo parameter support in template settings
+- Updated metadata & copyright header
+
+### Added - Expanded TOC (Table of Contents)
+- Automatic TOC injection when enabled
+- User selects placement via article > options > layout (`toc-left` or `toc-right`)
+
+### Changed
+- Cleaned up `index.php` by removing skip-to-content duplicate calls
+- Consolidated JavaScript asset loading (ensuring dark-mode script is loaded correctly from external JS file)
+- Streamlined CSS for toggle switch, ensuring it inherits Bootstrap/Cassiopeia defaults
+- General accessibility refinements in typography and color contrast
+- Fixed missing logo param in header output
+- Corrected stylesheet inconsistencies between Bootstrap 5 helpers and template overrides
+- Patched redundant calls in script includes
+
+## [01.00.00] - 2025-01-01
+
+### Added - Initial Public Release
+- Font Awesome 6 integration (later upgraded to FA7)
+- Bootstrap 5 helpers (grid, utility classes)
+- Automatic Table of Contents (TOC) utility
+- Moko Expansions: Google Tag Manager / GA4 hooks
+- Built on top of Joomla's default Cassiopeia template
+- Minimal core template overrides for maximum upgrade compatibility
+
+---
+
+## Links
+
+- **Full Roadmap**: [MokoOnyx Roadmap](https://mokoconsulting.tech/support/joomla-cms/mokoonyx-roadmap)
+- **Repository**: [GitHub](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+- **Issue Tracker**: [GitHub Issues](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/issues)
+
+## Version Format
+
+This project uses semantic versioning: `MAJOR.MINOR.PATCH`
+- **MAJOR**: Incompatible API changes or major overhauls
+- **MINOR**: New features, backwards-compatible
+- **PATCH**: Bug fixes, backwards-compatible
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..1415337
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,98 @@
+
+
+## Code of Conduct
+
+This Code of Conduct establishes expectations for behavior within the MokoOnyx project community. The objective is to maintain a professional, inclusive, and respectful environment aligned with open source governance best practices.
+
+## Scope
+
+This Code of Conduct applies to all project spaces, including:
+
+* GitHub repositories, issues, pull requests, discussions, and security advisories.
+* Project documentation, workflows, and release processes.
+* Any communication channels officially associated with the project.
+
+## Our Standards
+
+Participants are expected to:
+
+* Communicate professionally and respectfully.
+* Provide constructive feedback focused on technical merit and project objectives.
+* Respect differing viewpoints, experience levels, and backgrounds.
+* Follow documented contribution, security, and governance policies.
+
+Unacceptable behavior includes:
+
+* Harassment, discrimination, or exclusionary conduct.
+* Personal attacks, insults, or inflammatory comments.
+* Publishing private information without consent.
+* Disruptive behavior that materially interferes with project operations.
+
+## Enforcement Responsibilities
+
+Project maintainers are responsible for:
+
+* Clarifying standards when questions arise.
+* Taking appropriate and proportionate corrective action when violations occur.
+* Maintaining confidentiality to the extent practical during investigations.
+
+## Reporting
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported through:
+
+* Email: `hello@mokoconsulting.tech` with subject `CODE OF CONDUCT: MokoOnyx`.
+
+Reports should include relevant context, links, screenshots, or other supporting information.
+
+## Enforcement Guidelines
+
+Corrective actions may include, but are not limited to:
+
+* Private warning or request for corrective action.
+* Temporary or permanent restriction from project participation.
+* Removal of content that violates this Code of Conduct.
+
+Decisions are made based on impact, severity, and pattern of behavior.
+
+## No Retaliation
+
+Retaliation against individuals who report concerns in good faith is not tolerated. Any retaliatory behavior will be treated as a separate violation.
+
+## Jurisdiction
+
+This project is managed from Tennessee, USA. This statement is informational and does not constitute legal advice.
+
+---
+
+## Metadata
+
+* **Document:** CODE_OF_CONDUCT.md
+* **Repository:** [https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+* **Path:** /CODE_OF_CONDUCT.md
+* **Owner:** Moko Consulting
+* **Version:** 03.06.00
+* **Status:** Active
+* **Effective Date:** 2025-12-18
+* **Last Reviewed:** 2025-12-18
+
+## Revision History
+
+| Date | Change Summary | Author |
+| ---------- | ----------------------------------------------------------------------------- | --------------- |
+| 2025-12-18 | Initial publication of contributor conduct standards and enforcement process. | Moko Consulting |
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..f6d6af7
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,145 @@
+
+
+## Contributing
+
+This document defines how to contribute to the MokoOnyx project. The goal is to ensure changes are reviewable, auditable, and aligned with project governance and release processes.
+
+## Scope
+
+These guidelines apply to all contributions, including:
+
+* Source code changes
+* Documentation updates
+* Bug reports and enhancement proposals
+
+## Prerequisites
+
+Contributors are expected to:
+
+* Have a working understanding of Joomla template structure.
+* Be familiar with Git and GitHub pull request workflows.
+* Review repository governance documents prior to submitting changes.
+* Set up the development environment using the provided tools.
+
+### Quick Setup
+
+For first-time contributors:
+
+```bash
+# Clone the repository
+git clone https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx.git
+cd MokoOnyx
+```
+
+See [docs/QUICK_START.md](./docs/QUICK_START.md) for detailed setup instructions.
+
+## Development Tools
+
+The repository provides several tools to streamline development:
+
+* **Pre-commit Hooks**: Automatic local validation before commits
+
+## Contribution Workflow
+
+1. Fork the repository.
+2. Create a branch from the active development branch.
+3. Make focused, minimal changes that address a single concern.
+4. Submit a pull request with a clear description of intent and impact.
+
+Direct commits to protected branches are not permitted.
+
+## Branching and Versioning
+
+* Development work occurs on designated development branches.
+* Releases are produced from versioned branches following repository standards.
+* Contributors should not bump version numbers unless explicitly requested.
+
+## Coding and Formatting Standards
+
+All contributions must:
+
+* Follow Joomla coding standards where applicable.
+* Conform to Moko Consulting repository standards for headers, metadata, and file structure.
+* Avoid introducing tabs, inconsistent path separators, or non portable assumptions.
+
+Automated checks may reject changes that do not meet these requirements.
+
+## Documentation Standards
+
+Documentation changes must:
+
+* Include required metadata and revision history sections.
+* Avoid embedding version numbers in revision history tables.
+* Preserve existing structure unless a structural change is explicitly proposed.
+
+## Commit Messages
+
+Commit messages should:
+
+* Be concise and descriptive.
+* Focus on what changed and why.
+* Avoid referencing internal issue trackers unless required.
+
+## Reporting Issues
+
+Bug reports and enhancement requests should be filed as GitHub issues and include:
+
+* Clear reproduction steps or use cases.
+* Expected versus actual behavior.
+* Relevant environment details.
+
+Security related issues must follow the process defined in SECURITY.md and must not be reported publicly.
+
+## Review Process
+
+All pull requests are subject to review. Review criteria include:
+
+* Technical correctness
+* Alignment with project goals
+* Maintainability and clarity
+* Risk introduced to release and update processes
+
+Maintainers may request changes prior to approval.
+
+## License
+
+By contributing, you agree that your contributions will be licensed under GPL-3.0-or-later, consistent with the rest of the project.
+
+## Code of Conduct
+
+Participation in this project is governed by the Code of Conduct. Unacceptable behavior may result in contribution restrictions.
+
+---
+
+## Metadata
+
+* **Document:** CONTRIBUTING.md
+* **Repository:** [https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+* **Path:** /CONTRIBUTING.md
+* **Owner:** Moko Consulting
+* **Version:** 03.06.00
+* **Status:** Active
+* **Effective Date:** 2025-12-18
+* **Last Reviewed:** 2025-12-18
+
+## Revision History
+
+| Date | Change Summary | Author |
+| ---------- | ------------------------------------------------------------------------- | --------------- |
+| 2025-12-18 | Initial publication of contribution guidelines and workflow expectations. | Moko Consulting |
diff --git a/GOVERNANCE.md b/GOVERNANCE.md
new file mode 100644
index 0000000..defdf37
--- /dev/null
+++ b/GOVERNANCE.md
@@ -0,0 +1,115 @@
+
+
+## Governance Overview
+
+This document defines the governance framework for the MokoOnyx project. The objective is to ensure clear ownership, predictable decision making, and accountable stewardship across development, releases, and community interaction.
+
+## Project Ownership
+
+MokoOnyx is owned and maintained by **Moko Consulting**. Final authority for project direction, releases, and policy enforcement resides with the project owner.
+
+## Roles and Responsibilities
+
+### Maintainers
+
+Maintainers are responsible for:
+
+* Setting technical direction and release priorities.
+* Reviewing and approving pull requests.
+* Managing releases and distribution artifacts.
+* Enforcing repository policies, including security and conduct requirements.
+
+### Contributors
+
+Contributors may:
+
+* Submit pull requests and issues.
+* Propose enhancements and report defects.
+* Participate in technical discussions.
+
+Contributors do not have merge authority unless explicitly granted.
+
+## Decision Making
+
+Decisions are made using a maintainers led model:
+
+* Routine changes are approved through pull request review.
+* Material changes affecting architecture, branding, licensing, or release processes require maintainer consensus.
+* The project owner retains final decision authority if consensus cannot be reached.
+
+## Change Management
+
+Significant changes should:
+
+* Be documented through issues or pull requests with clear rationale.
+* Consider backward compatibility and upgrade impact.
+* Include documentation updates when behavior or usage changes.
+
+## Release Authority
+
+Only maintainers may:
+
+* Cut releases and publish artifacts.
+* Update version numbers and manifests.
+* Publish update metadata or advisories.
+
+Release processes follow documented workflows and automation standards.
+
+## Security Governance
+
+Security issues are governed by the SECURITY.md policy. Maintainers are responsible for confidential handling, coordinated disclosure, and publication of advisories when appropriate.
+
+## Conduct Enforcement
+
+Behavior within the project is governed by CODE_OF_CONDUCT.md. Maintainers are responsible for enforcement actions and escalation handling.
+
+## Conflict Resolution
+
+Conflicts are handled through:
+
+* Direct discussion between involved parties when appropriate.
+* Maintainer mediation when necessary.
+* Final determination by the project owner if required.
+
+## External Dependencies
+
+The project depends on Joomla core and other third party components. Governance of upstream projects remains outside the scope of this repository, but upstream changes may influence project decisions.
+
+## Jurisdiction
+
+This project is managed from Tennessee, USA. This statement is informational and does not constitute legal advice.
+
+---
+
+## Metadata
+
+* **Document:** GOVERNANCE.md
+* **Repository:** [https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+* **Path:** /GOVERNANCE.md
+* **Owner:** Moko Consulting
+* **Version:** 03.06.00
+* **Status:** Active
+* **Effective Date:** 2025-12-18
+* **Last Reviewed:** 2025-12-18
+
+## Revision History
+
+| Date | Change Summary | Author |
+| ---------- | ----------------------------------------------------------------------- | --------------- |
+| 2025-12-18 | Initial publication of governance model, roles, and decision processes. | Moko Consulting |
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..331197a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,696 @@
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+ .
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..2263186
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,199 @@
+# Makefile for MokoOnyx Joomla Template
+# Copyright (C) 2026 Moko Consulting
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# Build and validation powered by MokoStandards Enterprise API
+# Install: composer install
+
+# ==============================================================================
+# CONFIGURATION
+# ==============================================================================
+
+EXTENSION_NAME := mokoonyx
+EXTENSION_TYPE := template
+EXTENSION_VERSION := $(shell grep -oP 'VERSION:\s*\K[0-9.]+' README.md 2>/dev/null || echo "0.0.0")
+
+SRC_DIR := src
+BUILD_DIR := build
+DIST_DIR := dist
+
+PHP := php
+COMPOSER := composer
+MOKO := vendor/bin/moko
+
+# Colors
+COLOR_RESET := \033[0m
+COLOR_GREEN := \033[32m
+COLOR_YELLOW := \033[33m
+COLOR_BLUE := \033[34m
+COLOR_RED := \033[31m
+
+# ==============================================================================
+# TARGETS
+# ==============================================================================
+
+.PHONY: help
+help: ## Show this help message
+ @echo "$(COLOR_BLUE)╔════════════════════════════════════════════════════════════╗$(COLOR_RESET)"
+ @echo "$(COLOR_BLUE)║ MokoOnyx Template Build ║$(COLOR_RESET)"
+ @echo "$(COLOR_BLUE)╚════════════════════════════════════════════════════════════╝$(COLOR_RESET)"
+ @echo ""
+ @echo "Extension: $(EXTENSION_NAME) ($(EXTENSION_TYPE)) v$(EXTENSION_VERSION)"
+ @echo "Powered by: MokoStandards Enterprise API"
+ @echo ""
+ @echo "$(COLOR_GREEN)Available targets:$(COLOR_RESET)"
+ @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " $(COLOR_BLUE)%-20s$(COLOR_RESET) %s\n", $$1, $$2}'
+ @echo ""
+
+# ── Dependencies ──────────────────────────────────────────────────────────────
+
+.PHONY: install-deps
+install-deps: ## Install Composer dependencies (includes MokoStandards API)
+ @echo "$(COLOR_BLUE)Installing dependencies...$(COLOR_RESET)"
+ @$(COMPOSER) install
+ @echo "$(COLOR_GREEN)✓ Dependencies installed$(COLOR_RESET)"
+
+.PHONY: update-deps
+update-deps: ## Update Composer dependencies
+ @echo "$(COLOR_BLUE)Updating dependencies...$(COLOR_RESET)"
+ @$(COMPOSER) update
+ @echo "$(COLOR_GREEN)✓ Dependencies updated$(COLOR_RESET)"
+
+# ── Validation (MokoStandards API) ────────────────────────────────────────────
+
+.PHONY: check-moko
+check-moko:
+ @if [ ! -f "$(MOKO)" ]; then \
+ echo "$(COLOR_RED)✗ MokoStandards CLI not found. Run: make install-deps$(COLOR_RESET)"; \
+ exit 1; \
+ fi
+
+.PHONY: lint
+lint: check-moko ## PHP syntax check via MokoStandards
+ @echo "$(COLOR_BLUE)Running PHP syntax check...$(COLOR_RESET)"
+ @$(PHP) $(MOKO) check:syntax -- --path .
+ @echo "$(COLOR_GREEN)✓ PHP syntax OK$(COLOR_RESET)"
+
+.PHONY: check-joomla
+check-joomla: check-moko ## Validate Joomla manifest via MokoStandards
+ @echo "$(COLOR_BLUE)Validating Joomla manifest...$(COLOR_RESET)"
+ @$(PHP) $(MOKO) check:joomla -- --path .
+ @echo "$(COLOR_GREEN)✓ Joomla manifest valid$(COLOR_RESET)"
+
+.PHONY: check-version
+check-version: check-moko ## Verify version consistency across files
+ @echo "$(COLOR_BLUE)Checking version consistency...$(COLOR_RESET)"
+ @$(PHP) $(MOKO) check:version -- --path .
+ @echo "$(COLOR_GREEN)✓ Versions consistent$(COLOR_RESET)"
+
+.PHONY: check-headers
+check-headers: check-moko ## Check license headers on source files
+ @echo "$(COLOR_BLUE)Checking license headers...$(COLOR_RESET)"
+ @$(PHP) $(MOKO) check:headers -- --path .
+ @echo "$(COLOR_GREEN)✓ Headers OK$(COLOR_RESET)"
+
+.PHONY: check-secrets
+check-secrets: check-moko ## Scan for leaked credentials
+ @echo "$(COLOR_BLUE)Scanning for secrets...$(COLOR_RESET)"
+ @$(PHP) $(MOKO) check:secrets -- --path .
+ @echo "$(COLOR_GREEN)✓ No secrets found$(COLOR_RESET)"
+
+.PHONY: check-xml
+check-xml: check-moko ## Validate XML files are well-formed
+ @echo "$(COLOR_BLUE)Checking XML files...$(COLOR_RESET)"
+ @$(PHP) $(MOKO) check:xml -- --path .
+ @echo "$(COLOR_GREEN)✓ XML well-formed$(COLOR_RESET)"
+
+.PHONY: validate
+validate: lint check-joomla check-version check-xml check-headers check-secrets ## Run all MokoStandards validation checks
+ @echo "$(COLOR_GREEN)✓ All validation checks passed$(COLOR_RESET)"
+
+.PHONY: health
+health: check-moko ## Full repository health check via MokoStandards
+ @echo "$(COLOR_BLUE)Running full health check...$(COLOR_RESET)"
+ @$(PHP) $(MOKO) health -- --path .
+
+# ── Build ─────────────────────────────────────────────────────────────────────
+
+.PHONY: clean
+clean: ## Clean build artifacts
+ @echo "$(COLOR_BLUE)Cleaning build artifacts...$(COLOR_RESET)"
+ @rm -rf $(BUILD_DIR) $(DIST_DIR)
+ @echo "$(COLOR_GREEN)✓ Build artifacts cleaned$(COLOR_RESET)"
+
+.PHONY: build
+build: clean ## Build template installable ZIP from src/
+ @echo "$(COLOR_BLUE)Building $(EXTENSION_NAME) v$(EXTENSION_VERSION)...$(COLOR_RESET)"
+ @mkdir -p $(BUILD_DIR)/package $(DIST_DIR)
+ @cp -r $(SRC_DIR)/* $(BUILD_DIR)/package/
+ @cd $(BUILD_DIR)/package && \
+ if command -v zip >/dev/null 2>&1; then \
+ zip -r "../../$(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION).zip" .; \
+ elif command -v pwsh >/dev/null 2>&1; then \
+ pwsh -Command "Compress-Archive -Path '*' -DestinationPath '../../$(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION).zip' -Force"; \
+ elif command -v powershell >/dev/null 2>&1; then \
+ powershell -Command "Compress-Archive -Path '*' -DestinationPath '../../$(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION).zip' -Force"; \
+ else \
+ echo "$(COLOR_RED)✗ No zip tool found (zip, pwsh, powershell)$(COLOR_RESET)"; \
+ exit 1; \
+ fi
+ @echo "$(COLOR_GREEN)✓ Package: $(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION).zip$(COLOR_RESET)"
+
+.PHONY: build-beta
+build-beta: clean ## Build beta release ZIP
+ @echo "$(COLOR_BLUE)Building $(EXTENSION_NAME) v$(EXTENSION_VERSION)-beta...$(COLOR_RESET)"
+ @mkdir -p $(BUILD_DIR)/package $(DIST_DIR)
+ @cp -r $(SRC_DIR)/* $(BUILD_DIR)/package/
+ @cd $(BUILD_DIR)/package && \
+ if command -v zip >/dev/null 2>&1; then \
+ zip -r "../../$(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION)-beta.zip" .; \
+ elif command -v pwsh >/dev/null 2>&1; then \
+ pwsh -Command "Compress-Archive -Path '*' -DestinationPath '../../$(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION)-beta.zip' -Force"; \
+ elif command -v powershell >/dev/null 2>&1; then \
+ powershell -Command "Compress-Archive -Path '*' -DestinationPath '../../$(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION)-beta.zip' -Force"; \
+ else \
+ echo "$(COLOR_RED)✗ No zip tool found$(COLOR_RESET)"; \
+ exit 1; \
+ fi
+ @echo "$(COLOR_GREEN)✓ Package: $(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION)-beta.zip$(COLOR_RESET)"
+
+.PHONY: checksum
+checksum: ## Generate SHA-256 checksums for dist packages
+ @echo "$(COLOR_BLUE)Generating checksums...$(COLOR_RESET)"
+ @for f in $(DIST_DIR)/*.zip; do \
+ sha256sum "$$f" | tee "$${f}.sha256"; \
+ done
+ @echo "$(COLOR_GREEN)✓ Checksums generated$(COLOR_RESET)"
+
+# ── Release ───────────────────────────────────────────────────────────────────
+
+.PHONY: release
+release: validate build checksum ## Full release pipeline (validate + build + checksum)
+ @echo "$(COLOR_GREEN)✓ Release package ready$(COLOR_RESET)"
+ @echo ""
+ @echo "$(COLOR_BLUE)Next steps:$(COLOR_RESET)"
+ @echo " 1. Tag: git tag $(EXTENSION_VERSION)"
+ @echo " 2. Push: git push origin --tags"
+ @echo " 3. Create Gitea release and attach $(DIST_DIR)/$(EXTENSION_NAME)-$(EXTENSION_VERSION).zip"
+ @echo ""
+
+# ── Info ──────────────────────────────────────────────────────────────────────
+
+.PHONY: version
+version: ## Display version and extension info
+ @echo "$(COLOR_BLUE)Extension Information:$(COLOR_RESET)"
+ @echo " Name: $(EXTENSION_NAME)"
+ @echo " Type: $(EXTENSION_TYPE)"
+ @echo " Version: $(EXTENSION_VERSION)"
+
+.PHONY: security-check
+security-check: ## Run Composer security audit
+ @echo "$(COLOR_BLUE)Running security checks...$(COLOR_RESET)"
+ @$(COMPOSER) audit
+ @echo "$(COLOR_GREEN)✓ Security check complete$(COLOR_RESET)"
+
+.PHONY: all
+all: install-deps validate build checksum ## Full pipeline: deps → validate → build → checksum
+ @echo "$(COLOR_GREEN)✓ Complete build pipeline finished$(COLOR_RESET)"
+
+.DEFAULT_GOAL := help
diff --git a/README.md b/README.md
index 2b17a7f..2a7b219 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,520 @@
-# MokoOnyx
+
+
+# MokoOnyx → MokoOnyx
+
+> **This template is being renamed to MokoOnyx.** Version 01.00.00 is the bridge release that automatically migrates your settings. After updating, MokoOnyx will be your active template and MokoOnyx can be safely uninstalled.
+
+**A Modern, Lightweight Joomla Template Based on Cassiopeia**
+
+[](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/tag/v03)
+[](LICENSE)
+[](https://www.joomla.org)
+[](https://www.php.net)
+
+MokoOnyx is a modern, lightweight enhancement layer built on top of Joomla's Cassiopeia template. It adds **Font Awesome 7**, **Bootstrap 5** helpers, an automatic **Table of Contents (TOC)** utility, advanced **Dark Mode** theming, and optional integrations for **Google Tag Manager** and **Google Analytics (GA4)**—all while maintaining minimal core template overrides for maximum upgrade compatibility.
+
+---
+
+## 📑 Table of Contents
+
+- [Features](#-features)
+- [Requirements](#-requirements)
+- [Installation](#-installation)
+- [Quick Start](#-quick-start)
+- [Configuration](#️-configuration)
+- [Theme System](#-theme-system)
+- [Development](#-development)
+- [Documentation](#-documentation)
+- [Changelog](#-changelog)
+- [Support](#-support)
+- [Contributing](#-contributing)
+- [Included Libraries](#-included-libraries)
+- [License](#-license)
+
+---
+
+## ✨ Features
+
+### Core Enhancements
+
+- **Built on Cassiopeia**: Extends Joomla's default template with minimal overrides
+- **Font Awesome 7**: Fully integrated into Joomla's asset manager with 2,000+ icons
+- **Bootstrap 5**: Extended utility classes and responsive grid system
+- **No Template Overrides**: Clean installation that inherits all Cassiopeia defaults
+- **Upgrade-Friendly**: Minimal modifications ensure smooth Joomla updates
+
+### Advanced Theming
+
+- **Dark Mode Support**: Built-in light/dark mode toggle with system preference detection
+- **Color Palettes**: Standard, Alternative, and Custom color schemes
+- **Theme Persistence**: User preferences saved via localStorage
+- **Theme Control Options**: Switch, radio buttons, or hidden controls
+- **Auto Dark Mode**: Optional automatic dark mode based on time/system settings
+- **Meta Tags**: Automatic color-scheme and theme-color meta tags
+
+### Developer Features
+
+- **Custom Code Injection**: Add custom HTML to `` start/end
+- **Drawer Sidebars**: Configurable left/right drawer positions with custom icons
+- **Font Options**: Local and web fonts (Roboto, Fira Sans, Noto Sans)
+- **Sticky Header**: Optional sticky navigation
+- **Back to Top**: Floating back-to-top button
+
+### Analytics & Tracking
+
+- **Google Tag Manager**: Optional GTM integration with container ID configuration
+- **Google Analytics**: Optional GA4 integration with measurement ID
+- **Privacy-Friendly**: All tracking features are optional and easily disabled
+
+### Content Features
+
+- **Table of Contents**: Automatic TOC generation for long articles
+ - Placement options: `toc-left` or `toc-right` layouts
+ - Automatic heading extraction and navigation
+ - Responsive sidebar positioning
+
+---
+
+## 📋 Requirements
+
+- **Joomla**: 4.4.x or 5.x
+- **PHP**: 8.0 or higher
+- **Database**: MySQL 5.7+ / MariaDB 10.2+ / PostgreSQL 11+
+- **Browser Support**: Modern browsers (Chrome, Firefox, Safari, Edge)
+
+---
+
+## 📦 Installation
+
+**Note**: MokoOnyx is a **standalone Joomla template extension** (not bundled as a package). Install it directly via Joomla's Extension Manager.
+
+### Via Joomla Extension Manager
+
+1. Download the latest `mokoonyx-{version}.zip` from [Releases](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases)
+2. In Joomla admin, navigate to **System → Install → Extensions**
+3. Upload the ZIP file and click **Upload & Install**
+4. Navigate to **System → Site Templates**
+5. Set **MokoOnyx** as your default template
+
+### Via Git (Development)
+
+```bash
+git clone https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx.git
+cd MokoOnyx
+```
+
+See [Development Guide](./docs/JOOMLA_DEVELOPMENT.md) for development setup.
+
+---
+
+## 🚀 Quick Start
+
+### 1. Install the Template
+
+Install `mokoonyx.zip` via Joomla's Extension Manager.
+
+### 2. Set as Default
+
+Navigate to **System → Site Templates** and set **MokoOnyx** as default.
+
+### 3. Configure Template Options
+
+Go to **System → Site Templates → MokoOnyx** to configure:
+
+- **Branding**: Upload logo, set site title/description
+- **Theme**: Configure color schemes and dark mode
+- **Layout**: Set container type (static/fluid), sticky header
+- **Analytics**: Add GTM/GA4 tracking codes (optional)
+- **Custom Code**: Inject custom HTML/CSS/JS
+
+### 4. Test Dark Mode
+
+The template includes a dark mode toggle. Test it by:
+- Using the floating theme toggle button (bottom-right by default)
+- Checking theme persistence across page loads
+- Verifying system preference detection
+
+---
+
+## Usage
+
+Once installed and set as the default site template, MokoOnyx works out of the box with Joomla's standard content and module system. Key usage points:
+
+- **Template Options** — Configure via **System → Site Templates → MokoOnyx** (theme colours, layout, analytics, favicon, drawers)
+- **Custom Colour Schemes** — Copy `templates/mokoonyx/templates/light.custom.css` or `dark.custom.css` to `media/templates/site/mokoonyx/css/theme/` and select "Custom" in the Theme tab
+- **Custom CSS/JS** — Create `media/templates/site/mokoonyx/css/user.css` or `js/user.js` for site-specific overrides that survive template updates
+- **Module Overrides** — The template includes overrides for common Joomla modules with consistent title rendering, Bootstrap 5 styling, and Font Awesome 7 icons
+- **Dark Mode** — Enabled by default with a floating toggle button; respects system preference and persists via localStorage
+
+See [Configuration](#️-configuration) below for detailed parameter reference.
+
+---
+
+## ⚙️ Configuration
+
+### Global Parameters
+
+Access template configuration via **System → Site Templates → MokoOnyx**.
+
+#### Theme Tab
+
+**General Settings:**
+- **Theme Enabled**: Enable/disable theme system
+- **Theme Control Type**: Switch (Light↔Dark), Radios (Light/Dark/System), or None
+- **Default Choice**: System, Light, or Dark
+- **Auto Dark Mode**: Automatic dark mode based on time
+- **Meta Tags**: Enable color-scheme and theme-color meta tags
+- **Bridge Bootstrap ARIA**: Sync theme with Bootstrap's data-bs-theme
+
+**Variables & Palettes:**
+- **Light Mode Palette**: Standard, Alternative, or Custom
+- **Dark Mode Palette**: Standard, Alternative, or Custom
+
+**Typography:**
+- **Font Scheme**: Local (Roboto) or Web fonts (Fira Sans, Roboto+Noto Sans)
+
+**Branding & Icons:**
+- **Brand**: Enable/disable site branding
+- **Logo File**: Upload custom logo (no default logo included)
+- **Site Title**: Custom site title
+- **Site Description**: Tagline/description
+- **Font Awesome Kit**: Optional FA Pro kit code
+
+**Header & Navigation:**
+- **Sticky Header**: Enable fixed header on scroll
+- **Back to Top**: Enable floating back-to-top button
+
+**Theme Toggle UI:**
+- **FAB Enabled**: Enable floating action button toggle
+- **FAB Position**: Bottom-right, Bottom-left, Top-right, or Top-left
+
+#### Advanced Tab
+
+- **Layout**: Static or Fluid container
+
+#### Google Tab
+
+- **Google Tag Manager**: Enable and configure GTM container ID
+- **Google Analytics**: Enable and configure GA4 measurement ID
+
+#### Custom Code Tab
+
+- **Custom Head Start**: HTML injected at start of ``
+- **Custom Head End**: HTML injected at end of ``
+
+#### Drawers Tab
+
+- **Left Drawer Icon**: Font Awesome icon class (e.g., `fa-solid fa-chevron-right`)
+- **Right Drawer Icon**: Font Awesome icon class (e.g., `fa-solid fa-chevron-left`)
+
+### Custom Theme Palettes
+
+MokoOnyx supports custom theme schemes:
+
+1. **Copy template files** from `/templates/` directory:
+ - `light.custom.css` → `media/templates/site/mokoonyx/css/theme/light.custom.css`
+ - `dark.custom.css` → `media/templates/site/mokoonyx/css/theme/dark.custom.css`
+2. **Customize** the CSS variables to match your brand colors
+3. **Enable in Joomla**: System → Site Templates → MokoOnyx → Theme tab → Set palette to "Custom"
+4. **Save** and view your site with custom colors
+
+**Note:** Custom color files are excluded from version control (`.gitignore`) to prevent fork-specific customizations from being committed.
+
+**Quick Example:**
+
+```css
+:root[data-bs-theme="light"] {
+ --color-primary: #1e40af;
+ --color-link: #2563eb;
+ --color-hover: #1d4ed8;
+ --body-color: #1f2937;
+ --body-bg: #ffffff;
+}
+```
+
+**Complete Reference:** See [CSS Variables Documentation](./docs/CSS_VARIABLES.md) for all available variables and detailed usage examples.
+
+### Table of Contents
+
+Enable automatic TOC for articles:
+
+1. Edit an article in Joomla admin
+2. Navigate to **Options → Layout**
+3. Select **toc-left** or **toc-right**
+4. Save the article
+
+The TOC will automatically generate from article headings (H2, H3, etc.) and appear as a sidebar.
+
+---
+
+## 🎨 Theme System
+
+### Dark Mode Features
+
+- **Automatic Detection**: Respects user's system preferences
+- **Manual Toggle**: Floating button or radio controls
+- **Persistence**: Saves preference in localStorage
+- **Smooth Transitions**: Animated theme switching
+- **Comprehensive Support**: All components themed for dark mode
+
+### Theme Control Types
+
+1. **Switch**: Simple light/dark toggle button
+2. **Radios**: Three options - Light, Dark, System
+3. **None**: No visible control (respects system only)
+
+### Meta Tags
+
+When enabled, the template adds:
+
+```html
+
+
+
+```
+
+---
+
+## 🛠 Development
+
+### For Contributors
+
+**New to the project?** See [Quick Start Guide](./docs/QUICK_START.md) for a 5-minute setup.
+
+### Development Resources
+
+- **[Quick Start Guide](./docs/QUICK_START.md)** - Setup and first steps
+- **[Joomla Development Guide](./docs/JOOMLA_DEVELOPMENT.md)** - Testing, quality checks, deployment
+- **[Workflow Guide](./docs/WORKFLOW_GUIDE.md)** - Git workflow and branching
+- **[Contributing Guide](./CONTRIBUTING.md)** - Contribution guidelines
+- **[Roadmap](./docs/ROADMAP.md)** - Feature roadmap and planning
+
+### Development Tools
+
+- **Pre-commit Hooks**: Automatic validation before commits
+- **PHP CodeSniffer**: Code style validation (Joomla standards)
+- **PHPStan**: Static analysis for PHP code
+- **Codeception**: Testing framework
+
+### Quick Development Setup
+
+```bash
+# Clone repository
+git clone https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx.git
+cd MokoOnyx
+
+# Install development dependencies (if using Composer)
+composer install --dev
+
+# Run code quality checks
+make validate # or manual commands
+```
+
+### Building Template Package
+
+See [Joomla Development Guide](./docs/JOOMLA_DEVELOPMENT.md) for packaging instructions.
+
+---
+
+## 📚 Documentation
+
+### User Documentation
+
+- **[README](./README.md)** - This file (overview and features)
+- **[CHANGELOG](./CHANGELOG.md)** - Version history and changes
+- **[Roadmap](./docs/ROADMAP.md)** - Planned features and timeline
+
+### Developer Documentation
+
+- **[Quick Start](./docs/QUICK_START.md)** - 5-minute developer setup
+- **[Development Guide](./docs/JOOMLA_DEVELOPMENT.md)** - Comprehensive development guide
+- **[Workflow Guide](./docs/WORKFLOW_GUIDE.md)** - Git workflow and processes
+- **[CSS Variables Reference](./docs/CSS_VARIABLES.md)** - Complete CSS customization guide
+- **[Documentation Index](./docs/README.md)** - All documentation links
+
+### Governance
+
+- **[Contributing](./CONTRIBUTING.md)** - How to contribute
+- **[Code of Conduct](./CODE_OF_CONDUCT.md)** - Community standards
+- **[Governance](./GOVERNANCE.md)** - Project governance model
+- **[Security Policy](./SECURITY.md)** - Security reporting and procedures
+
+---
+
+## 📖 Changelog
+
+See the [CHANGELOG.md](./CHANGELOG.md) for detailed version history.
+
+### Recent Releases
+
+- **[03.06.03]** (2026-01-30) - README updates and TOC color variable improvements
+- **[03.06.02]** (2026-01-30) - Complete rebrand to MokoOnyx, removed all overrides
+- **[03.06.00]** (2026-01-28) - Version standardization
+- **[03.05.01]** (2026-01-09) - Security and compliance improvements
+- **[02.00.00]** (2025-08-30) - Dark mode toggle and improved theming
+
+---
+
+## 💬 Support
+
+### Getting Help
+
+- **Documentation**: Check this README and [docs folder](./docs/)
+- **Issues**: Report bugs via [GitHub Issues](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/issues)
+- **Discussions**: Ask questions in [GitHub Discussions](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/discussions)
+- **Roadmap**: View planned features in [Roadmap](https://mokoconsulting.tech/support/joomla-cms/mokoonyx-roadmap)
+
+### Reporting Bugs
+
+Please include:
+- Joomla version
+- PHP version
+- Template version
+- Steps to reproduce
+- Expected vs actual behavior
+- Screenshots (if applicable)
+
+### Security Issues
+
+**Do not** report security vulnerabilities via public issues. See [SECURITY.md](./SECURITY.md) for reporting procedures.
+
+---
+
+## 🤝 Contributing
+
+We welcome contributions! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
+
+### How to Contribute
+
+1. Fork the repository
+2. Create a feature branch (`git checkout -b feature/amazing-feature`)
+3. Make your changes
+4. Run quality checks
+5. Commit your changes (`git commit -m 'Add amazing feature'`)
+6. Push to the branch (`git push origin feature/amazing-feature`)
+7. Open a Pull Request
+
+### Development Workflow
+
+See [Workflow Guide](./docs/WORKFLOW_GUIDE.md) for detailed Git workflow.
+
+### Customizations
+
+For template customizations, use Joomla's built-in template settings (System → Site Templates → MokoOnyx → Custom Code tab) for HTML/CSS/JS customizations.
+
+---
+
+## 📦 Included Libraries
+
+MokoOnyx includes the following third-party libraries to provide enhanced functionality:
+
+### Bootstrap TOC
+
+- **Version**: 1.0.1
+- **Author**: Aidan Feldman
+- **License**: MIT License
+- **Source**: [GitHub Repository](https://github.com/afeld/bootstrap-toc)
+- **Release**: [v1.0.1 Release](https://github.com/afeld/bootstrap-toc/releases/tag/v1.0.1)
+- **Purpose**: Automatically generates a table of contents from article headings with scrollspy support
+- **Location**: `src/media/vendor/bootstrap-toc/`
+- **Integration**: Registered in `joomla.asset.json` as `vendor.bootstrap-toc` (CSS) and `vendor.bootstrap-toc.js` (JavaScript)
+- **Usage**: Activated when using `toc-left` or `toc-right` article layouts
+- **Features**:
+ - Automatic TOC generation from H1-H6 headings
+ - Hierarchical nested navigation
+ - Active state highlighting with scrollspy
+ - Responsive design (collapses on mobile)
+ - Smooth scrolling to sections
+ - Automatic unique ID generation for headings
+- **Customizations**: CSS adapted to use Cassiopeia CSS variables for theme compatibility
+
+### Font Awesome 7 Free
+
+- **Version**: 7.0 (Free)
+- **License**: Font Awesome Free License
+- **Source**: [Font Awesome](https://fontawesome.com)
+- **Purpose**: Provides 2,000+ vector icons for interface elements
+- **Location**: `src/media/vendor/fa7free/`
+- **Integration**: Fully integrated into Joomla's asset manager
+- **Styles Available**: Solid, Regular, Brands
+
+### Bootstrap 5
+
+- **Version**: 5.x (via Joomla)
+- **License**: MIT License
+- **Source**: [Bootstrap](https://getbootstrap.com)
+- **Purpose**: Provides responsive grid system and utility classes
+- **Integration**: Inherited from Joomla's Cassiopeia template, extended with additional helpers
+- **Components Used**: Grid, utilities, modal, dropdown, collapse, offcanvas, tooltip, popover, scrollspy
+
+### Integration Method
+
+All third-party libraries are:
+- ✅ Properly licensed and attributed
+- ✅ Registered in Joomla's Web Asset Manager (`joomla.asset.json`)
+- ✅ Loaded on-demand to optimize performance
+- ✅ Versioned and documented for maintenance
+- ✅ Compatible with Joomla 4.4.x and 5.x
+
+---
+
+## 📄 License
+
+This project is licensed under the **GNU General Public License v3.0** - see the [LICENSE](./LICENSE) file for details.
+
+### Third-Party Licenses
+
+- **Joomla! CMS**: GPL-2.0-or-later
+- **Cassiopeia Template**: GPL-2.0-or-later (Joomla Project)
+- **Font Awesome 7 Free**: Font Awesome Free License
+- **Bootstrap 5**: MIT License
+- **Bootstrap TOC**: MIT License (A. Feld)
+
+All third-party libraries and assets remain the property of their respective authors and are credited in source files.
+
+---
+
+## 🔗 Links
+
+- **Repository**: [GitHub](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+- **Issue Tracker**: [GitHub Issues](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/issues)
+- **Discussions**: [GitHub Discussions](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/discussions)
+- **Roadmap**: [Full Roadmap](https://mokoconsulting.tech/support/joomla-cms/mokoonyx-roadmap)
+- **Moko Consulting**: [Website](https://mokoconsulting.tech)
+
+---
+
+## 📊 Metadata
+
+- **Maintainer**: Moko Consulting Engineering
+- **Author**: Jonathan Miller (@jmiller-moko)
+- **Repository**: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
+- **License**: GPL-3.0-or-later
+- **Classification**: Public Open Source Standards
+
+## 📝 Revision History
+
+| Date | Version | Change Summary | Author |
+| ---------- | -------- | ------------------------------------------------------------------------- | ------------------------------- |
+| 2026-01-30 | 03.06.03 | Updated README title, fixed custom color variables instructions, improved TOC color scheme integration | Copilot Agent |
+| 2026-01-30 | 03.06.02 | Regenerated README with comprehensive documentation and updated structure | Copilot Agent |
+| 2026-01-30 | 03.06.02 | Complete rebrand to MokoOnyx, removed overrides | Copilot Agent |
+| 2026-01-05 | 03.00.00 | Initial publication of template documentation and feature overview | Moko Consulting |
+| 2026-01-05 | 03.00.00 | Fixed malformed markdown table formatting in revision history | Jonathan Miller (@jmiller-moko) |
+
+---
+
+**Made with ❤️ by [Moko Consulting](https://mokoconsulting.tech)**
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..7016afe
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,185 @@
+
+
+## Security Policy
+
+This document defines how MokoOnyx handles vulnerability intake, triage, remediation, and disclosure. The objective is to reduce risk, protect downstream users, and preserve operational continuity with a verifiable audit trail.
+
+## Scope
+
+This policy applies to:
+
+* Repository source code, workflows, scripts, and build artifacts.
+* Release packaging (ZIP outputs) generated from the repository.
+* Configuration and metadata used for distribution (for example manifests and update metadata).
+
+Out of scope:
+
+* Vulnerabilities in upstream Joomla core, third party extensions, or external infrastructure not controlled by this repository.
+* Issues that require physical access to a host, compromised administrator credentials, or a compromised hosting provider, unless the repository materially increases impact.
+
+## Supported Versions
+
+Security fixes are prioritized for:
+
+* The latest released version.
+* The current development line when it is actively used for release engineering.
+
+Backports may be provided based on impact, deployment footprint, and engineering capacity.
+
+## Reporting a Vulnerability
+
+Use one of the following channels:
+
+* GitHub Security Advisories (preferred): use the repository security tab to submit a private report.
+* Email: send details to `hello@mokoconsulting.tech` with subject `SECURITY: MokoOnyx vulnerability report`.
+
+Do not file a public GitHub issue for suspected security vulnerabilities.
+
+### What to include
+
+Provide enough detail to reproduce and triage:
+
+* A clear description of the vulnerability and expected impact.
+* A minimal proof of concept or reproduction steps.
+* Affected versions, configuration assumptions, and environment details.
+* Any proposed mitigation or patch.
+* Your preferred contact details for follow up.
+
+## Triage and Response Targets
+
+The project operates with response targets aligned to practical delivery realities:
+
+* **Acknowledgement:** within 3 business days.
+* **Initial triage:** within 10 business days.
+* **Fix plan:** communicated once severity is confirmed.
+
+These targets are not guarantees. Complex issues, supply chain considerations, and coordination with upstream vendors may extend timelines.
+
+## Severity Assessment
+
+Issues are triaged based on business impact and technical exploitability, including:
+
+* Remote exploitability and required privileges.
+* Data confidentiality, integrity, and availability impact.
+* Likelihood of exploitation in typical Joomla deployments.
+* Exposure surface (public endpoints, administrator area, installation flows, and update mechanisms).
+
+When appropriate, industry standard scoring such as CVSS may be used for internal prioritization.
+
+## Coordinated Disclosure
+
+The project follows coordinated vulnerability disclosure:
+
+* Reports are treated as confidential until remediation is available.
+* A public advisory may be published once a fix is released.
+* A reasonable embargo period is expected to enable patch distribution.
+
+If you believe disclosure is time sensitive due to active exploitation, include that assessment and any supporting indicators.
+
+## Security Updates and Advisories
+
+Security updates are distributed through:
+
+* GitHub releases for the repository.
+* GitHub Security Advisories when applicable.
+
+Advisories may include:
+
+* Affected versions and fixed versions.
+* Mitigations and workarounds when a fix is not immediately available.
+* Upgrade guidance.
+
+## Dependencies and Supply Chain Controls
+
+The project aims to manage supply chain risk through:
+
+* Pinning and review of workflow dependencies where feasible.
+* Minimizing privileged GitHub token permissions.
+* Validating build inputs prior to packaging releases.
+
+If you identify a supply chain issue (for example compromised action, dependency confusion, or malicious upstream artifact), report it as a vulnerability.
+
+## Secure Development and CI Expectations
+
+Security posture is reinforced through operational controls:
+
+* CI validation for packaging inputs and manifest integrity.
+* Consistent path normalization and whitespace hygiene checks where required for release correctness.
+* Least privilege for GitHub Actions permissions.
+
+### Template Security Features
+
+**Custom Head Content Injection**
+
+The template provides Custom Head Code fields (`custom_head_start` and `custom_head_end`) that allow administrators to inject custom HTML, CSS, and JavaScript code. This is an intentional feature for:
+
+* Adding analytics scripts (Google Analytics, Google Tag Manager)
+* Custom meta tags
+* Third-party integrations
+* Custom styling
+
+**Security Considerations:**
+
+* These fields use `filter="raw"` to allow HTML/JS injection
+* **Access is restricted to Joomla administrators only** via template configuration
+* This is not an XSS vulnerability as it requires administrator privileges
+* Administrators should only add trusted code from verified sources
+* Regular security audits should review custom head content
+
+This policy does not guarantee that all vulnerabilities will be prevented. It defines how risk is managed when issues are discovered.
+
+## Safe Harbor
+
+The project supports good faith security research. When you:
+
+* Avoid privacy violations, data destruction, and service disruption.
+* Limit testing to systems you own or have explicit permission to test.
+* Provide a reasonable window for coordinated disclosure.
+
+Then the project will treat your report as a constructive security contribution.
+
+Jurisdiction note: this repository is managed from Tennessee, USA. This note is informational only and does not constitute legal advice.
+
+## Public Communications
+
+Only maintainers will publish security advisories or public statements for confirmed vulnerabilities. Public communication will focus on actionable remediation and operational risk reduction.
+
+## Acknowledgements
+
+If you want credit, include the name or handle to list in an advisory. If you prefer anonymity, state that explicitly.
+
+---
+
+## Metadata
+
+* **Document:** SECURITY.md
+* **Repository:** [https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+* **Path:** /SECURITY.md
+* **Owner:** Moko Consulting
+* **Version:** 03.06.00
+* **Status:** Active
+* **Effective Date:** 2025-12-18
+* **Last Reviewed:** 2025-12-18
+
+## Revision History
+
+| Date | Change Summary | Author |
+| ---------- | ------------------------------------------------------------------------------------------------ | --------------- |
+| 2026-01-30 | Added Template Security Features section documenting custom head content injection controls. | Copilot Agent |
+| 2025-12-18 | Initial publication of security policy, intake channels, triage targets, and disclosure process. | Moko Consulting |
diff --git a/codeception.yml b/codeception.yml
new file mode 100644
index 0000000..f1ebe4e
--- /dev/null
+++ b/codeception.yml
@@ -0,0 +1,34 @@
+namespace: Tests
+paths:
+ tests: tests
+ output: tests/_output
+ data: tests/_data
+ support: tests/_support
+ envs: tests/_envs
+settings:
+ shuffle: false
+ lint: true
+ colors: true
+ memory_limit: 1024M
+coverage:
+ enabled: true
+ include:
+ - src/*
+ exclude:
+ - src/vendor/*
+ - src/media/*
+ - src/language/*
+extensions:
+ enabled:
+ - Codeception\Extension\RunFailed
+params:
+ - env
+modules:
+ config:
+ Db:
+ dsn: 'mysql:host=localhost;dbname=joomla_test'
+ user: 'root'
+ password: ''
+ dump: tests/_data/dump.sql
+ populate: true
+ cleanup: true
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..a7a23b0
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,30 @@
+{
+ "name": "mokoconsulting/mokoonyx",
+ "description": "MokoOnyx \u00e2\u20ac\u201d Joomla site template based on Cassiopeia",
+ "type": "joomla-template",
+ "license": "GPL-3.0-or-later",
+ "authors": [
+ {
+ "name": "Jonathan Miller",
+ "email": "hello@mokoconsulting.tech"
+ }
+ ],
+ "require": {
+ "php": ">=8.1",
+ "ext-zip": "*"
+ },
+ "require-dev": {
+ "mokoconsulting-tech/enterprise": "^4.0"
+ },
+ "config": {
+ "sort-packages": true,
+ "optimize-autoloader": true,
+ "preferred-install": "dist"
+ },
+ "repositories": [
+ {
+ "type": "composer",
+ "url": "https://git.mokoconsulting.tech/api/packages/MokoConsulting/composer"
+ }
+ ]
+}
diff --git a/docs/CSS_VARIABLES.md b/docs/CSS_VARIABLES.md
new file mode 100644
index 0000000..0816f0a
--- /dev/null
+++ b/docs/CSS_VARIABLES.md
@@ -0,0 +1,1460 @@
+
+
+# CSS Variables Reference - MokoOnyx
+
+This document provides a complete reference of all CSS variables available in the MokoOnyx template for customization.
+
+## Table of Contents
+
+- [Using Custom Color Palettes](#using-custom-color-palettes)
+- [Primary Brand Colors](#primary-brand-colors)
+- [Link Colors](#link-colors)
+- [Navigation Colors](#navigation-colors)
+- [Navbar Variables](#navbar-variables)
+- [Offcanvas Variables](#offcanvas-variables)
+- [Header Background](#header-background)
+- [Container Backgrounds](#container-backgrounds)
+- [Bootstrap Color Palette](#bootstrap-color-palette)
+- [Body & Typography](#body--typography)
+- [Additional Theme Colors](#additional-theme-colors)
+- [Borders & Shadows](#borders--shadows)
+- [Button Utilities](#button-utilities)
+- [Card Variables](#card-variables)
+- [Form Colors](#form-colors)
+- [Responsive Tokens & Breakpoints](#responsive-tokens--breakpoints)
+- [VirtueMart Variables](#virtuemart-variables)
+- [Gable Variables](#gable-variables)
+- [Hero Variant Variables](#hero-variant-variables)
+- [Block Color Variables](#block-color-variables)
+
+---
+
+## Using Custom Color Palettes
+
+To create custom color schemes:
+
+1. **Copy template files** from `./templates/` directory:
+ - `light.custom.css` → `media/templates/site/mokoonyx/css/theme/light.custom.css`
+ - `dark.custom.css` → `media/templates/site/mokoonyx/css/theme/dark.custom.css`
+
+2. **Edit the variables** in the copied files to match your brand
+
+3. **Enable in Joomla**:
+ - Navigate to: System → Site Templates → MokoOnyx
+ - Under "Theme" tab, set palette to "Custom"
+ - Save changes
+
+4. **Note**: Custom files are gitignored and won't be committed to the repository
+
+5. **On upgrade**: When the template is updated, `script.php` automatically runs `sync_custom_vars.php` to detect any new variables added to the starter templates and inject them into your existing custom palette files. Your existing values are never overwritten — only genuinely new variables are added. You can also run this manually:
+ ```bash
+ php templates/mokoonyx/sync_custom_vars.php --dry-run # preview what would be added
+ php templates/mokoonyx/sync_custom_vars.php # apply missing variables
+ ```
+
+---
+
+## Primary Brand Colors
+
+### `--color-primary`
+- **Description**: Main brand color used throughout the template
+- **Light Mode Default**: `#112855`
+- **Dark Mode Default**: `#112855`
+- **Usage**: Headers, primary buttons, brand elements
+
+### `--accent-color-primary`
+- **Description**: Primary accent color for interactive elements
+- **Light Mode Default**: `#3f8ff0`
+- **Dark Mode Default**: `#3f8ff0`
+- **Usage**: Hover states, focus indicators, call-to-action elements
+
+### `--accent-color-secondary`
+- **Description**: Secondary accent color
+- **Light Mode Default**: `#3f8ff0`
+- **Dark Mode Default**: `#6fb3ff`
+- **Usage**: Secondary highlights, alternative styling
+
+---
+
+## Link Colors
+
+### `--color-link`
+- **Description**: Default color for hyperlinks
+- **Light Mode Default**: `#224FAA`
+- **Dark Mode Default**: `white`
+- **Usage**: All text links in content
+
+### `--color-hover`
+- **Description**: Color when hovering over links and interactive elements
+- **Light Mode Default**: `var(--accent-color-primary)`
+- **Dark Mode Default**: `gray`
+- **Usage**: Hover states for links and buttons
+
+### `--color-active`
+- **Description**: Color for active/selected links
+- **Light Mode Default**: (not set)
+- **Dark Mode Default**: `var(--mainmenu-nav-link-color)`
+- **Usage**: Active navigation items, selected states
+
+### `--link-color`
+- **Description**: Bootstrap-compatible link color variable
+- **Light Mode Default**: `#224faa`
+- **Dark Mode Default**: `#8ab4f8`
+- **Usage**: Alternative link color variable for Bootstrap compatibility
+
+### `--link-hover-color`
+- **Description**: Bootstrap-compatible hover color
+- **Light Mode Default**: `#424077`
+- **Dark Mode Default**: `#c3d6ff`
+- **Usage**: Link hover state for Bootstrap components
+
+---
+
+## Navigation Colors
+
+### `--mainmenu-nav-link-color`
+- **Description**: Text color for main navigation menu
+- **Light Mode Default**: `white`
+- **Dark Mode Default**: `#fff`
+- **Usage**: Navigation menu text
+
+### `--nav-text-color`
+- **Description**: General navigation text color
+- **Light Mode Default**: `white`
+- **Dark Mode Default**: `gray`
+- **Usage**: Navigation elements
+
+### `--nav-bg-color`
+- **Description**: Background color for navigation bars
+- **Light Mode Default**: `var(--color-link)`
+- **Dark Mode Default**: `var(--color-primary)`
+- **Usage**: Navigation background
+
+---
+
+## Navbar Variables
+
+### `--navbar-padding-x`
+- **Description**: Horizontal padding for navbar
+- **Default**: `1rem`
+- **Usage**: Navbar horizontal spacing
+
+### `--navbar-padding-y`
+- **Description**: Vertical padding for navbar
+- **Default**: `0.5rem`
+- **Usage**: Navbar vertical spacing
+
+### `--navbar-color`
+- **Description**: Default text color for navbar items
+- **Light Mode Default**: `rgba(0, 0, 0, 0.55)`
+- **Dark Mode Default**: `rgba(255, 255, 255, 0.55)`
+- **Usage**: Navbar text color
+
+### `--navbar-active-color`
+- **Description**: Text color for active navbar items
+- **Light Mode Default**: `rgba(0, 0, 0, 0.9)`
+- **Dark Mode Default**: `rgba(255, 255, 255, 0.9)`
+- **Usage**: Active navbar item color
+
+### `--navbar-disabled-color`
+- **Description**: Text color for disabled navbar items
+- **Light Mode Default**: `rgba(0, 0, 0, 0.3)`
+- **Dark Mode Default**: `rgba(255, 255, 255, 0.3)`
+- **Usage**: Disabled navbar item color
+
+### `--navbar-brand-padding-y`
+- **Description**: Vertical padding for navbar brand
+- **Default**: `0.3125rem`
+- **Usage**: Navbar brand vertical spacing
+
+### `--navbar-brand-margin-end`
+- **Description**: Right margin for navbar brand
+- **Default**: `1rem`
+- **Usage**: Space after navbar brand
+
+### `--navbar-brand-font-size`
+- **Description**: Font size for navbar brand
+- **Default**: `1.25rem`
+- **Usage**: Navbar brand text size
+
+### `--navbar-brand-color`
+- **Description**: Color for navbar brand
+- **Default**: Inherits from `--navbar-color`
+- **Usage**: Navbar brand text color
+
+### `--navbar-brand-active-color`
+- **Description**: Color for navbar brand when active
+- **Default**: Inherits from `--navbar-active-color`
+- **Usage**: Active navbar brand color
+
+### `--navbar-toggler-padding-x`
+- **Description**: Horizontal padding for navbar toggler button
+- **Default**: `0.75rem`
+- **Usage**: Toggler button horizontal spacing
+
+### `--navbar-toggler-padding-y`
+- **Description**: Vertical padding for navbar toggler button
+- **Default**: `0.25rem`
+- **Usage**: Toggler button vertical spacing
+
+### `--navbar-toggler-font-size`
+- **Description**: Font size for navbar toggler icon
+- **Default**: `1.25rem`
+- **Usage**: Toggler icon size
+
+### `--navbar-toggler-border-color`
+- **Description**: Border color for navbar toggler
+- **Light Mode Default**: `rgba(0, 0, 0, 0.1)`
+- **Dark Mode Default**: `rgba(255, 255, 255, 0.1)`
+- **Usage**: Toggler button border
+
+### `--navbar-toggler-border-radius`
+- **Description**: Border radius for navbar toggler
+- **Default**: `0.25rem`
+- **Usage**: Toggler button corner rounding
+
+### `--navbar-toggler-focus-width`
+- **Description**: Width of focus outline on toggler
+- **Default**: `0.25rem`
+- **Usage**: Focus indicator width
+
+### `--navbar-toggler-transition`
+- **Description**: CSS transition for toggler state changes
+- **Default**: `box-shadow 0.15s ease-in-out`
+- **Usage**: Toggler animation
+
+### `--nav-link-padding-x`
+- **Description**: Horizontal padding for nav links
+- **Default**: `0.5rem`
+- **Usage**: Nav link horizontal spacing
+
+### `--nav-link-padding-y`
+- **Description**: Vertical padding for nav links
+- **Default**: `0.5rem`
+- **Usage**: Nav link vertical spacing
+
+### `--nav-link-font-weight`
+- **Description**: Font weight for nav links
+- **Default**: `400`
+- **Usage**: Nav link text weight
+
+### `--nav-link-color`
+- **Description**: Color for nav links
+- **Default**: Inherits from `--navbar-color`
+- **Usage**: Nav link text color
+
+### `--nav-link-active-color`
+- **Description**: Color for active nav links
+- **Default**: Inherits from `--navbar-active-color`
+- **Usage**: Active nav link color
+
+### `--nav-link-disabled-color`
+- **Description**: Color for disabled nav links
+- **Default**: Inherits from `--navbar-disabled-color`
+- **Usage**: Disabled nav link color
+
+---
+
+## Offcanvas Variables
+
+### `--offcanvas-color`
+- **Description**: Text color for offcanvas content
+- **Light Mode Default**: `var(--body-color)`
+- **Dark Mode Default**: `var(--body-color)`
+- **Usage**: Offcanvas text color
+
+### `--offcanvas-padding-x`
+- **Description**: Horizontal padding for offcanvas content
+- **Default**: `1.5rem`
+- **Usage**: Offcanvas horizontal spacing
+
+### `--offcanvas-padding-y`
+- **Description**: Vertical padding for offcanvas content
+- **Default**: `1.5rem`
+- **Usage**: Offcanvas vertical spacing
+
+---
+
+## Header Background
+
+### `--header-background-image`
+- **Description**: Background image URL for header
+- **Default**: `url('../../../../../../media/templates/site/mokoonyx/images/bg.svg')`
+- **Usage**: Header section background
+
+### `--header-background-attachment`
+- **Description**: CSS background-attachment property
+- **Default**: `fixed`
+- **Options**: `scroll`, `fixed`, `local`
+
+### `--header-background-repeat`
+- **Description**: CSS background-repeat property
+- **Default**: `repeat`
+- **Options**: `repeat`, `repeat-x`, `repeat-y`, `no-repeat`
+
+### `--header-background-size`
+- **Description**: CSS background-size property
+- **Default**: `auto`
+- **Options**: `auto`, `cover`, `contain`, specific sizes
+
+---
+
+## Container Backgrounds
+
+Each container section has the following customizable properties:
+
+### Container Sections
+- `below-topbar` - Below top navigation bar
+- `top-a` - Top section A
+- `top-b` - Top section B
+- `toc` - Table of Contents sidebar
+- `sidebar` - Sidebar area
+- `bottom-a` - Bottom section A
+- `bottom-b` - Bottom section B
+
+### Available Properties per Container
+Replace `{section}` with the container name:
+
+- `--container-{section}-bg-image` - Background image URL
+- `--container-{section}-bg-color` - Background color
+- `--container-{section}-bg-position` - Background position
+- `--container-{section}-bg-attachment` - Attachment (scroll/fixed)
+- `--container-{section}-bg-repeat` - Repeat pattern
+- `--container-{section}-bg-size` - Background size
+- `--container-{section}-border` - Border styling
+- `--container-{section}-border-radius` - Border radius
+
+### Special TOC Variables
+
+#### `--container-toc-bg`
+- **Description**: Background color for TOC container
+- **Light Mode Default**: `var(--mainmenu-nav-link-color)`
+- **Dark Mode Default**: (empty, transparent)
+
+#### `--container-toc-color`
+- **Description**: Text color for TOC
+- **Light Mode Default**: `var(--color-primary)`
+- **Dark Mode Default**: `#dbe3ff`
+
+---
+
+## Bootstrap Color Palette
+
+### Contextual Colors
+
+#### `--primary`
+- **Light Mode**: `#010156`
+- **Dark Mode**: `#010156`
+- **Usage**: Primary theme color
+
+#### `--secondary`
+- **Light Mode**: `#6d757e`
+- **Dark Mode**: `#48525d`
+- **Usage**: Secondary elements
+
+#### `--success`
+- **Light Mode**: `#448344`
+- **Dark Mode**: `#4aa664`
+- **Usage**: Success messages, positive actions
+
+#### `--info`
+- **Light Mode**: `#30638d`
+- **Dark Mode**: `#4f7aa0`
+- **Usage**: Informational messages
+
+#### `--warning`
+- **Light Mode**: `#ad6200`
+- **Dark Mode**: `#c77a00`
+- **Usage**: Warning messages
+
+#### `--danger`
+- **Light Mode**: `#a51f18`
+- **Dark Mode**: `#c23a31`
+- **Usage**: Error messages, destructive actions
+
+#### `--light`
+- **Light Mode**: `#f9fafb`
+- **Dark Mode**: `#1b2027`
+- **Usage**: Light backgrounds
+
+#### `--dark`
+- **Light Mode**: `#353b41`
+- **Dark Mode**: `#0f1318`
+- **Usage**: Dark backgrounds
+
+### Standard Colors
+
+Available in both themes:
+- `--blue`, `--indigo`, `--purple`, `--pink`
+- `--red`, `--orange`, `--yellow`, `--green`
+- `--teal`, `--cyan`
+- `--black`, `--white`
+
+### Gray Scale
+
+Available in 9 shades: `--gray-100` through `--gray-900`
+
+Light mode ranges from very light (`#f9fafb`) to very dark (`#22262a`).
+Dark mode ranges are inverted for better contrast on dark backgrounds.
+
+### Opacity Utilities
+
+**New in v03.08.04**: Opacity utility variables for creating translucent colors:
+
+- `--opacity-0`: `0` (fully transparent)
+- `--opacity-5`: `0.05`
+- `--opacity-10`: `0.1`
+- `--opacity-15`: `0.15`
+- `--opacity-20`: `0.2`
+- `--opacity-25`: `0.25`
+- `--opacity-30`: `0.3`
+- `--opacity-50`: `0.5`
+- `--opacity-75`: `0.75`
+- `--opacity-100`: `1` (fully opaque)
+
+**Usage Example:**
+```css
+background-color: rgba(var(--black-rgb), var(--opacity-10));
+border-color: rgba(var(--white-rgb), var(--opacity-25));
+```
+
+### Shadow Color Utilities
+
+**New in v03.08.04**: Pre-defined shadow color variables for consistent shadow styling:
+
+**Light Theme:**
+- `--shadow-color-light`: `rgba(var(--black-rgb), var(--opacity-15))` - Light shadows
+- `--shadow-color-medium`: `rgba(var(--black-rgb), var(--opacity-25))` - Medium shadows
+- `--shadow-color-dark`: `rgba(var(--black-rgb), var(--opacity-30))` - Dark shadows
+- `--border-color-translucent`: `rgba(var(--black-rgb), var(--opacity-10))` - Translucent borders
+- `--highlight-translucent`: `rgba(var(--white-rgb), var(--opacity-15))` - Highlight overlays
+
+**Dark Theme:**
+- `--shadow-color-light`: `rgba(var(--black-rgb), var(--opacity-30))` - Adjusted for dark backgrounds
+- `--shadow-color-medium`: `rgba(var(--black-rgb), var(--opacity-50))`
+- `--shadow-color-dark`: `rgba(var(--black-rgb), var(--opacity-75))`
+- `--border-color-translucent`: `rgba(var(--white-rgb), var(--opacity-10))`
+- `--highlight-translucent`: `rgba(var(--white-rgb), var(--opacity-5))`
+
+**Usage Example:**
+```css
+box-shadow: 0 0.5rem 1rem var(--shadow-color-light);
+border: 1px solid var(--border-color-translucent);
+```
+
+---
+
+## Body & Typography
+
+### `--body-font-family`
+- **Description**: Default font stack for body text
+- **Default**: `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif`
+- **Usage**: All body text
+
+### `--body-font-size`
+- **Description**: Base font size
+- **Default**: `1rem` (typically 16px)
+- **Usage**: Base typography size
+
+### `--body-font-weight`
+- **Description**: Default font weight
+- **Default**: `400`
+- **Usage**: Body text weight
+
+### `--body-line-height`
+- **Description**: Line height for body text
+- **Default**: `1.5`
+- **Usage**: Text line spacing
+
+### `--body-color`
+- **Description**: Main text color
+- **Light Mode Default**: `#22262a`
+- **Dark Mode Default**: `#e6ebf1`
+- **Usage**: Body text color
+
+### `--body-bg`
+- **Description**: Main background color
+- **Light Mode Default**: `#fff`
+- **Dark Mode Default**: `#0e1318`
+- **Usage**: Page background
+
+### `--heading-color`
+- **Description**: Color for headings (h1-h6)
+- **Light Mode Default**: `inherit`
+- **Dark Mode Default**: `#f1f5f9`
+- **Usage**: Heading text
+
+---
+
+## Additional Theme Colors
+
+### `--muted-color`
+- **Default**: `#6d757e`
+- **Usage**: Muted/secondary text
+
+### `--code-color`
+- **Light Mode**: `#e93f8e`
+- **Dark Mode**: `#ff7abd`
+- **Usage**: Inline code elements
+
+### `--highlight-bg`
+- **Light Mode**: `#fbeea8`
+- **Dark Mode**: `#ffe28a1a`
+- **Usage**: Text highlighting, mark elements
+
+### `--emphasis-color`
+- **Light Mode**: `#000`
+- **Dark Mode**: `#fff`
+- **Usage**: Emphasized text
+
+### `--secondary-bg`
+- **Light Mode**: `#eaedf0`
+- **Dark Mode**: `#151b22`
+- **Usage**: Secondary backgrounds, alternate rows
+
+### `--tertiary-bg`
+- **Light Mode**: `#f9fafb`
+- **Dark Mode**: `#10151b`
+- **Usage**: Tertiary backgrounds, subtle contrast
+
+---
+
+## Borders & Shadows
+
+### Border Variables
+
+#### `--border`
+- **Default**: `5px`
+- **Usage**: Border width shorthand
+
+#### `--border-width`
+- **Default**: `1px`
+- **Usage**: Standard border width
+
+#### `--border-style`
+- **Default**: `solid`
+- **Usage**: Border style
+
+#### `--border-color`
+- **Light Mode**: `#dfe3e7`
+- **Dark Mode**: `#2b323b`
+- **Usage**: Standard border color
+
+#### `--border-color-translucent`
+- **Light Mode**: `#0000002d`
+- **Dark Mode**: `#ffffff26`
+- **Usage**: Semi-transparent borders
+
+### Border Radius
+
+- `--border-radius`: `.25rem` (default)
+- `--border-radius-sm`: `.2rem` (small)
+- `--border-radius-lg`: `.3rem` (large)
+- `--border-radius-xl`: `.3rem` (extra large)
+- `--border-radius-xxl`: `2rem` (2x extra large)
+- `--border-radius-pill`: `50rem` (pill-shaped)
+
+### Box Shadows
+
+#### `--box-shadow`
+- **Default**: `0 .5rem 1rem rgba(0,0,0,.15)`
+- **Usage**: Standard drop shadow
+
+#### `--box-shadow-sm`
+- **Default**: `0 .125rem .25rem rgba(0,0,0,.075)`
+- **Usage**: Small/subtle shadow
+
+#### `--box-shadow-lg`
+- **Default**: `0 1rem 3rem rgba(0,0,0,.175)`
+- **Usage**: Large/prominent shadow
+
+#### `--box-shadow-inset`
+- **Default**: `inset 0 1px 2px rgba(0,0,0,.075)`
+- **Usage**: Inset/inner shadow
+
+---
+
+## Bootstrap Button Variants
+
+**New in v03.08.04**: Complete Bootstrap button color definitions for both light and dark themes.
+
+### Available Button Classes
+
+All button variants support hover, active, focus, and disabled states using CSS variables:
+
+**Solid Buttons:**
+- `.btn-primary` - Primary brand button
+- `.btn-secondary` - Secondary button
+- `.btn-success` - Success/positive action button
+- `.btn-info` - Informational button
+- `.btn-warning` - Warning/caution button
+- `.btn-danger` - Danger/destructive action button
+- `.btn-light` - Light background button
+- `.btn-dark` - Dark background button
+
+**Outline Buttons:**
+- `.btn-outline-primary` through `.btn-outline-dark` - Outlined variants of above
+
+### Button CSS Variables
+
+Each button variant defines the following CSS variables:
+
+- `--btn-color`: Text color
+- `--btn-bg`: Background color
+- `--btn-border-color`: Border color
+- `--btn-hover-color`: Hover state text color
+- `--btn-hover-bg`: Hover state background
+- `--btn-hover-border-color`: Hover state border
+- `--btn-focus-shadow-rgb`: Focus ring RGB values
+- `--btn-active-color`: Active state text color
+- `--btn-active-bg`: Active state background
+- `--btn-active-border-color`: Active state border
+- `--btn-active-shadow`: Active state shadow
+- `--btn-disabled-color`: Disabled state text color
+- `--btn-disabled-bg`: Disabled state background
+- `--btn-disabled-border-color`: Disabled state border
+
+### Customizing Button Colors
+
+To customize button colors in your custom color palette:
+
+```css
+:root[data-bs-theme="light"] {
+ /* Override Bootstrap state colors */
+ --success: #28a745;
+ --danger: #dc3545;
+}
+
+.btn-primary {
+ --btn-bg: var(--color-primary);
+ --btn-border-color: var(--color-primary);
+ /* Other button states... */
+}
+```
+
+See `templates/light.custom.css` and `templates/dark.custom.css` for complete examples.
+
+---
+
+## Button Utilities
+
+### `--btn-border-radius`
+- **Description**: Border radius for buttons
+- **Default**: `0.25rem`
+- **Usage**: Button corner rounding
+
+### `--btn-box-shadow`
+- **Description**: Box shadow for buttons
+- **Default**: `inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075)`
+- **Usage**: Button shadow styling
+
+---
+
+## Card Variables
+
+### `--card-spacer-x`
+- **Description**: Horizontal spacing for card padding
+- **Default**: `1rem`
+- **Usage**: Card horizontal padding
+
+### `--card-spacer-y`
+- **Description**: Vertical spacing for card padding
+- **Default**: `1rem`
+- **Usage**: Card vertical padding
+
+### `--card-title-spacer-y`
+- **Description**: Spacing below card title
+- **Default**: `0.5rem`
+- **Usage**: Card title bottom margin
+
+### `--card-border-width`
+- **Description**: Width of card border
+- **Default**: `1px`
+- **Usage**: Card border thickness
+
+### `--card-border-color`
+- **Description**: Color of card border
+- **Light Mode Default**: `rgba(0, 0, 0, 0.125)`
+- **Dark Mode Default**: `rgba(255, 255, 255, 0.125)`
+- **Usage**: Card border color
+
+### `--card-border-radius`
+- **Description**: Border radius for cards
+- **Default**: `0.25rem`
+- **Usage**: Card corner rounding
+
+### `--card-box-shadow`
+- **Description**: Box shadow for cards
+- **Default**: `none`
+- **Usage**: Card shadow effect
+
+### `--card-inner-border-radius`
+- **Description**: Inner border radius for nested card elements
+- **Default**: `calc(0.25rem - 1px)`
+- **Usage**: Inner card element corners
+
+### `--card-cap-padding-x`
+- **Description**: Horizontal padding for card header/footer
+- **Default**: `1rem`
+- **Usage**: Card cap horizontal spacing
+
+### `--card-cap-padding-y`
+- **Description**: Vertical padding for card header/footer
+- **Default**: `0.5rem`
+- **Usage**: Card cap vertical spacing
+
+### `--card-cap-bg`
+- **Description**: Background color for card header/footer
+- **Light Mode Default**: `rgba(0, 0, 0, 0.03)`
+- **Dark Mode Default**: `rgba(255, 255, 255, 0.03)`
+- **Usage**: Card cap background
+
+### `--card-cap-color`
+- **Description**: Text color for card header/footer
+- **Default**: Inherits from body color
+- **Usage**: Card cap text color
+
+### `--card-height`
+- **Description**: Height constraint for cards
+- **Default**: `auto`
+- **Usage**: Card height control
+
+### `--card-color`
+- **Description**: Text color for card content
+- **Default**: Inherits from body color
+- **Usage**: Card text color
+
+### `--card-bg`
+- **Description**: Background color for cards
+- **Light Mode Default**: `#fff`
+- **Dark Mode Default**: `#212529`
+- **Usage**: Card background
+
+### `--card-img-overlay-padding`
+- **Description**: Padding for card image overlays
+- **Default**: `1rem`
+- **Usage**: Card image overlay spacing
+
+### `--card-group-margin`
+- **Description**: Margin between cards in card groups
+- **Default**: `0.75rem`
+- **Usage**: Card group spacing
+
+---
+
+## Form Colors
+
+### Focus Ring
+
+#### `--focus-ring-width`
+- **Default**: `.25rem`
+- **Usage**: Width of focus indicators
+
+#### `--focus-ring-opacity`
+- **Light Mode**: `.25`
+- **Dark Mode**: `.6`
+- **Usage**: Opacity of focus ring
+
+#### `--focus-ring-color`
+- **Light Mode**: `rgba(1,1,86,.25)`
+- **Dark Mode**: `rgba(84,114,255,.4)`
+- **Usage**: Color of focus indicators
+
+### Validation Colors
+
+#### Valid State
+- `--form-valid-color`: Success green
+ - Light: `#448344`
+ - Dark: `#78d694`
+- `--form-valid-border-color`: Matching border color
+
+#### Invalid State
+- `--form-invalid-color`: Error red
+ - Light: `#a51f18`
+ - Dark: `#ff8e86`
+- `--form-invalid-border-color`: Matching border color
+
+### Form Control Enhancements
+
+**New in v03.08.04**: Additional form control color variables:
+
+#### `--input-file-button-active-bg`
+- **Light Mode**: `#dee1e4`
+- **Dark Mode**: `#2b3441`
+- **Usage**: Background color for file input button in active state
+
+#### `--form-range-thumb-active-bg`
+- **Light Mode**: `#b8bfcc`
+- **Dark Mode**: `#4a5766`
+- **Usage**: Background color for range slider thumb in active state
+
+### Alert Link Colors
+
+**New in v03.08.04**: Dedicated variables for alert link colors:
+
+- `--alert-primary-link-color`: Link color in primary alerts
+- `--alert-secondary-link-color`: Link color in secondary alerts
+- `--alert-success-link-color`: Link color in success alerts
+- `--alert-info-link-color`: Link color in info alerts
+- `--alert-warning-link-color`: Link color in warning alerts
+- `--alert-danger-link-color`: Link color in danger alerts
+- `--alert-light-link-color`: Link color in light alerts
+- `--alert-dark-link-color`: Link color in dark alerts
+
+These ensure optimal readability for links within alert boxes.
+
+---
+
+## Responsive Tokens & Breakpoints
+
+### Breakpoint Variables
+
+#### `--bp-xs`
+- **Description**: Extra small breakpoint
+- **Default**: `0px`
+- **Usage**: Mobile devices
+
+#### `--bp-sm`
+- **Description**: Small breakpoint
+- **Default**: `576px`
+- **Usage**: Small tablets, large phones
+
+#### `--bp-md`
+- **Description**: Medium breakpoint
+- **Default**: `768px`
+- **Usage**: Tablets
+
+#### `--bp-lg`
+- **Description**: Large breakpoint
+- **Default**: `992px`
+- **Usage**: Desktops
+
+#### `--bp-xl`
+- **Description**: Extra large breakpoint
+- **Default**: `1200px`
+- **Usage**: Large desktops
+
+### Responsive Utilities
+
+#### `--nav-toggle-size`
+- **Description**: Size of navigation toggle button
+- **Default**: `40px`
+- **Usage**: Mobile menu toggle button dimensions
+
+#### `--bg-opacity`
+- **Description**: Background opacity for overlay elements
+- **Default**: `0.5`
+- **Usage**: Overlay transparency
+
+#### `--padding-x`
+- **Description**: General horizontal padding utility
+- **Default**: `1rem`
+- **Usage**: Horizontal spacing utility
+
+#### `--padding-y`
+- **Description**: General vertical padding utility
+- **Default**: `1rem`
+- **Usage**: Vertical spacing utility
+
+---
+
+## VirtueMart Variables
+
+### VM Surfaces
+
+#### `--vm-surface`
+- **Description**: Primary VirtueMart surface background
+- **Light Mode Default**: `#ffffff`
+- **Dark Mode Default**: `#1e1e1e`
+- **Usage**: Main VM component backgrounds
+
+#### `--vm-surface-2`
+- **Description**: Secondary VirtueMart surface background
+- **Light Mode Default**: `#f8f9fa`
+- **Dark Mode Default**: `#2d2d2d`
+- **Usage**: Alternate VM backgrounds
+
+#### `--vm-text`
+- **Description**: Default VirtueMart text color
+- **Light Mode Default**: `#212529`
+- **Dark Mode Default**: `#e9ecef`
+- **Usage**: VM body text
+
+#### `--vm-text-strong`
+- **Description**: Strong/emphasized VirtueMart text
+- **Light Mode Default**: `#000000`
+- **Dark Mode Default**: `#ffffff`
+- **Usage**: VM headings, emphasized text
+
+#### `--vm-text-muted`
+- **Description**: Muted VirtueMart text
+- **Light Mode Default**: `#6c757d`
+- **Dark Mode Default**: `#adb5bd`
+- **Usage**: VM secondary text, captions
+
+#### `--vm-border`
+- **Description**: Border color for VirtueMart components
+- **Light Mode Default**: `#dee2e6`
+- **Dark Mode Default**: `#495057`
+- **Usage**: VM borders, dividers
+
+#### `--vm-price-color`
+- **Description**: Color for product prices
+- **Light Mode Default**: `#198754`
+- **Dark Mode Default**: `#20c997`
+- **Usage**: Product price display
+
+### VM Layout
+
+#### `--vm-container-max-width`
+- **Description**: Maximum width for VM containers
+- **Default**: `1200px`
+- **Usage**: VM content width constraint
+
+#### `--vm-section-gap`
+- **Description**: Gap between VM sections
+- **Default**: `2rem`
+- **Usage**: VM section spacing
+
+#### `--vm-block-radius`
+- **Description**: Border radius for VM blocks
+- **Default**: `0.375rem`
+- **Usage**: VM component corner rounding
+
+#### `--vm-block-shadow`
+- **Description**: Shadow for VM blocks
+- **Default**: `0 2px 4px rgba(0, 0, 0, 0.1)`
+- **Usage**: VM component shadows
+
+### VM Typography
+
+#### `--vm-title-1-size`
+- **Description**: Size for h1 titles in VM
+- **Default**: `2.5rem`
+- **Usage**: VM main headings
+
+#### `--vm-title-1-weight`
+- **Description**: Font weight for h1 titles
+- **Default**: `700`
+- **Usage**: VM main heading weight
+
+#### `--vm-title-2-size`
+- **Description**: Size for h2 titles in VM
+- **Default**: `2rem`
+- **Usage**: VM section headings
+
+#### `--vm-title-2-weight`
+- **Description**: Font weight for h2 titles
+- **Default**: `600`
+- **Usage**: VM section heading weight
+
+#### `--vm-title-3-size`
+- **Description**: Size for h3 titles in VM
+- **Default**: `1.75rem`
+- **Usage**: VM subsection headings
+
+#### `--vm-title-3-weight`
+- **Description**: Font weight for h3 titles
+- **Default**: `600`
+- **Usage**: VM subsection heading weight
+
+#### `--vm-title-4-size`
+- **Description**: Size for h4 titles in VM
+- **Default**: `1.5rem`
+- **Usage**: VM component headings
+
+#### `--vm-title-4-weight`
+- **Description**: Font weight for h4 titles
+- **Default**: `500`
+- **Usage**: VM component heading weight
+
+#### `--vm-title-5-size`
+- **Description**: Size for h5 titles in VM
+- **Default**: `1.25rem`
+- **Usage**: VM small headings
+
+#### `--vm-title-5-weight`
+- **Description**: Font weight for h5 titles
+- **Default**: `500`
+- **Usage**: VM small heading weight
+
+### VM Controls
+
+#### `--vm-input-border`
+- **Description**: Border style for VM inputs
+- **Light Mode Default**: `1px solid #ced4da`
+- **Dark Mode Default**: `1px solid #495057`
+- **Usage**: VM form input borders
+
+#### `--vm-input-bg`
+- **Description**: Background color for VM inputs
+- **Light Mode Default**: `#ffffff`
+- **Dark Mode Default**: `#212529`
+- **Usage**: VM form input backgrounds
+
+#### `--vm-input-text`
+- **Description**: Text color for VM inputs
+- **Light Mode Default**: `#212529`
+- **Dark Mode Default**: `#e9ecef`
+- **Usage**: VM form input text
+
+#### `--vm-qty-width`
+- **Description**: Width for quantity input fields
+- **Default**: `80px`
+- **Usage**: Product quantity selectors
+
+#### `--vm-cart-dropdown-min-width`
+- **Description**: Minimum width for cart dropdown
+- **Default**: `300px`
+- **Usage**: Shopping cart dropdown sizing
+
+### VM Alerts
+
+#### `--vm-alert-success-bg`
+- **Description**: Background for success alerts
+- **Light Mode Default**: `#d1e7dd`
+- **Dark Mode Default**: `#0f5132`
+- **Usage**: VM success messages
+
+#### `--vm-alert-error-bg`
+- **Description**: Background for error alerts
+- **Light Mode Default**: `#f8d7da`
+- **Dark Mode Default**: `#842029`
+- **Usage**: VM error messages
+
+#### `--vm-availability-in-stock`
+- **Description**: Color for in-stock indicator
+- **Light Mode Default**: `#198754`
+- **Dark Mode Default**: `#20c997`
+- **Usage**: Product availability display
+
+#### `--vm-availability-out-of-stock`
+- **Description**: Color for out-of-stock indicator
+- **Light Mode Default**: `#dc3545`
+- **Dark Mode Default**: `#ea868f`
+- **Usage**: Product unavailability display
+
+### VM Buttons
+
+#### `--vm-btn-padding-x`
+- **Description**: Horizontal padding for VM buttons
+- **Default**: `1rem`
+- **Usage**: VM button horizontal spacing
+
+#### `--vm-btn-padding-y`
+- **Description**: Vertical padding for VM buttons
+- **Default**: `0.5rem`
+- **Usage**: VM button vertical spacing
+
+#### `--vm-btn-radius`
+- **Description**: Border radius for VM buttons
+- **Default**: `0.25rem`
+- **Usage**: VM button corner rounding
+
+#### `--vm-btn-shadow`
+- **Description**: Shadow for VM buttons
+- **Default**: `0 2px 4px rgba(0, 0, 0, 0.1)`
+- **Usage**: VM button shadows
+
+#### `--vm-btn-primary-bg`
+- **Description**: Background for primary VM buttons
+- **Light Mode Default**: `#0d6efd`
+- **Dark Mode Default**: `#0a58ca`
+- **Usage**: Primary VM action buttons
+
+#### `--vm-btn-primary-text`
+- **Description**: Text color for primary VM buttons
+- **Default**: `#ffffff`
+- **Usage**: Primary VM button text
+
+#### `--vm-btn-secondary-bg`
+- **Description**: Background for secondary VM buttons
+- **Light Mode Default**: `#6c757d`
+- **Dark Mode Default**: `#565e64`
+- **Usage**: Secondary VM action buttons
+
+#### `--vm-btn-secondary-text`
+- **Description**: Text color for secondary VM buttons
+- **Default**: `#ffffff`
+- **Usage**: Secondary VM button text
+
+#### `--vm-btn-add-to-cart-bg`
+- **Description**: Background for add-to-cart button
+- **Light Mode Default**: `#198754`
+- **Dark Mode Default**: `#146c43`
+- **Usage**: Add to cart button styling
+
+### VM Image Overlays
+
+#### `--vm-overlay-gap`
+- **Description**: Gap in image overlay elements
+- **Default**: `0.5rem`
+- **Usage**: Spacing in product image overlays
+
+#### `--vm-overlay-top`
+- **Description**: Top position for overlay elements
+- **Default**: `1rem`
+- **Usage**: Overlay vertical positioning
+
+#### `--vm-overlay-right`
+- **Description**: Right position for overlay elements
+- **Default**: `1rem`
+- **Usage**: Overlay horizontal positioning
+
+#### `--vm-overlay-btn-size`
+- **Description**: Size for overlay buttons
+- **Default**: `40px`
+- **Usage**: Quick view, wishlist button dimensions
+
+#### `--vm-overlay-btn-bg`
+- **Description**: Background for overlay buttons
+- **Light Mode Default**: `rgba(255, 255, 255, 0.9)`
+- **Dark Mode Default**: `rgba(0, 0, 0, 0.9)`
+- **Usage**: Overlay button background
+
+#### `--vm-overlay-btn-text`
+- **Description**: Text color for overlay buttons
+- **Light Mode Default**: `#212529`
+- **Dark Mode Default**: `#e9ecef`
+- **Usage**: Overlay button text
+
+#### `--vm-overlay-btn-hover-bg`
+- **Description**: Background for overlay buttons on hover
+- **Light Mode Default**: `#ffffff`
+- **Dark Mode Default**: `#000000`
+- **Usage**: Overlay button hover state
+
+#### `--vm-overlay-btn-radius`
+- **Description**: Border radius for overlay buttons
+- **Default**: `50%`
+- **Usage**: Circular overlay buttons
+
+#### `--vm-overlay-btn-shadow`
+- **Description**: Shadow for overlay buttons
+- **Default**: `0 2px 8px rgba(0, 0, 0, 0.15)`
+- **Usage**: Overlay button shadows
+
+### VM Vendor Menu
+
+#### `--vm-vendor-menu-bg`
+- **Description**: Background for vendor menu
+- **Light Mode Default**: `#ffffff`
+- **Dark Mode Default**: `#212529`
+- **Usage**: Vendor menu background
+
+#### `--vm-vendor-menu-text`
+- **Description**: Text color for vendor menu
+- **Light Mode Default**: `#212529`
+- **Dark Mode Default**: `#e9ecef`
+- **Usage**: Vendor menu text
+
+#### `--vm-vendor-menu-border`
+- **Description**: Border for vendor menu
+- **Light Mode Default**: `1px solid #dee2e6`
+- **Dark Mode Default**: `1px solid #495057`
+- **Usage**: Vendor menu borders
+
+#### `--vm-vendor-menu-hover-bg`
+- **Description**: Background on hover for vendor menu items
+- **Light Mode Default**: `#f8f9fa`
+- **Dark Mode Default**: `#2d2d2d`
+- **Usage**: Vendor menu hover state
+
+#### `--vm-vendor-menu-active-bg`
+- **Description**: Background for active vendor menu items
+- **Light Mode Default**: `#e9ecef`
+- **Dark Mode Default**: `#343a40`
+- **Usage**: Active vendor menu item
+
+#### `--vm-vendor-menu-active-text`
+- **Description**: Text color for active vendor menu items
+- **Light Mode Default**: `#0d6efd`
+- **Dark Mode Default**: `#6ea8fe`
+- **Usage**: Active vendor menu text
+
+#### `--vm-vendor-menu-padding-x`
+- **Description**: Horizontal padding for vendor menu items
+- **Default**: `1rem`
+- **Usage**: Vendor menu item horizontal spacing
+
+#### `--vm-vendor-menu-padding-y`
+- **Description**: Vertical padding for vendor menu items
+- **Default**: `0.75rem`
+- **Usage**: Vendor menu item vertical spacing
+
+#### `--vm-vendor-menu-font-size`
+- **Description**: Font size for vendor menu
+- **Default**: `0.875rem`
+- **Usage**: Vendor menu text size
+
+#### `--vm-vendor-menu-font-weight`
+- **Description**: Font weight for vendor menu
+- **Default**: `400`
+- **Usage**: Vendor menu text weight
+
+#### `--vm-vendor-menu-radius`
+- **Description**: Border radius for vendor menu
+- **Default**: `0.25rem`
+- **Usage**: Vendor menu corner rounding
+
+#### `--vm-vendor-menu-shadow`
+- **Description**: Shadow for vendor menu
+- **Default**: `0 2px 4px rgba(0, 0, 0, 0.1)`
+- **Usage**: Vendor menu drop shadow
+
+#### `--vm-vendor-menu-width`
+- **Description**: Width for vendor menu
+- **Default**: `250px`
+- **Usage**: Vendor menu sizing
+
+#### `--vm-vendor-menu-item-gap`
+- **Description**: Gap between vendor menu items
+- **Default**: `0.25rem`
+- **Usage**: Vendor menu item spacing
+
+#### `--vm-vendor-menu-icon-size`
+- **Description**: Size for vendor menu icons
+- **Default**: `1.25rem`
+- **Usage**: Vendor menu icon dimensions
+
+---
+
+## Gable Variables
+
+### `--gab-blue`
+- **Description**: Gable primary blue color
+- **Default**: `#1e88e5`
+- **Usage**: Gable brand blue accent
+
+### `--gab-green`
+- **Description**: Gable green color
+- **Default**: `#43a047`
+- **Usage**: Gable success/positive indicators
+
+### `--gab-red`
+- **Description**: Gable red color
+- **Default**: `#e53935`
+- **Usage**: Gable error/alert indicators
+
+### `--gab-orange`
+- **Description**: Gable orange color
+- **Default**: `#fb8c00`
+- **Usage**: Gable warning indicators
+
+### `--gab-gray1`
+- **Description**: Gable light gray
+- **Light Mode Default**: `#f5f5f5`
+- **Dark Mode Default**: `#424242`
+- **Usage**: Gable light backgrounds
+
+### `--gab-gray2`
+- **Description**: Gable medium gray
+- **Light Mode Default**: `#e0e0e0`
+- **Dark Mode Default**: `#616161`
+- **Usage**: Gable medium backgrounds, borders
+
+### `--gab-gray3`
+- **Description**: Gable dark gray
+- **Light Mode Default**: `#9e9e9e`
+- **Dark Mode Default**: `#9e9e9e`
+- **Usage**: Gable text, icons
+
+---
+
+## Usage Examples
+
+### Example 1: Custom Brand Colors
+
+```css
+:root[data-bs-theme="light"] {
+ --color-primary: #1e40af;
+ --accent-color-primary: #3b82f6;
+ --color-link: #2563eb;
+ --color-hover: #1d4ed8;
+}
+```
+
+### Example 2: Custom Container Background
+
+```css
+:root[data-bs-theme="light"] {
+ --container-top-a-bg-color: #f3f4f6;
+ --container-top-a-bg-image: url('/images/pattern.svg');
+ --container-top-a-bg-repeat: repeat;
+ --container-top-a-border-radius: 8px;
+}
+```
+
+### Example 3: Custom Typography
+
+```css
+:root[data-bs-theme="light"] {
+ --body-font-family: 'Inter', sans-serif;
+ --body-font-size: 1.125rem;
+ --heading-color: #1f2937;
+}
+```
+
+### Example 4: Custom Card Styling
+
+```css
+:root[data-bs-theme="light"] {
+ --card-border-radius: 0.5rem;
+ --card-box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+ --card-spacer-x: 1.5rem;
+ --card-spacer-y: 1.5rem;
+}
+```
+
+### Example 5: VirtueMart Custom Colors
+
+```css
+:root[data-bs-theme="light"] {
+ --vm-btn-primary-bg: #0d6efd;
+ --vm-btn-add-to-cart-bg: #198754;
+ --vm-price-color: #dc3545;
+ --vm-surface: #ffffff;
+}
+```
+
+### Example 6: Responsive Navbar
+
+```css
+:root[data-bs-theme="light"] {
+ --navbar-padding-x: 1.5rem;
+ --navbar-padding-y: 0.75rem;
+ --nav-toggle-size: 48px;
+ --navbar-toggler-border-radius: 0.5rem;
+}
+```
+
+---
+
+## Tips for Customization
+
+1. **Start with templates**: Use the provided template files as a starting point
+2. **Test both themes**: Ensure your colors work well in both light and dark modes
+3. **Use CSS variables**: Reference other variables with `var()` for consistency
+4. **Check contrast**: Ensure text remains readable against backgrounds
+5. **Use fallbacks**: Provide fallback values in `var()` functions
+6. **Test responsively**: Verify colors work on all screen sizes
+7. **Document changes**: Keep notes on custom color choices
+
+---
+
+## See Also
+
+- [README](../README.md) - Main documentation
+- [Quick Start Guide](./QUICK_START.md) - Getting started
+- [Development Guide](./JOOMLA_DEVELOPMENT.md) - Developer resources
+- Template files in `/templates/` directory
+
+---
+
+## Hero Variant Variables
+
+### `--hero-primary-bg-color`
+- **Description**: Fallback background color for the primary hero variant
+- **Light Mode Default**: `var(--color-primary)`
+- **Dark Mode Default**: `#0d1e3a`
+- **Usage**: `.hero#primary` background when no image loads
+
+### `--hero-primary-overlay`
+- **Description**: Gradient overlay tint for primary hero
+- **Light Mode Default**: `linear-gradient(rgba(163, 205, 226, .45), rgba(163, 205, 226, .45))`
+- **Dark Mode Default**: `linear-gradient(rgba(13, 30, 58, .65), rgba(13, 30, 58, .65))`
+- **Usage**: Semi-transparent color wash over hero background image
+
+### `--hero-primary-color`
+- **Description**: Text color for primary hero content
+- **Light Mode Default**: `var(--color-primary)`
+- **Dark Mode Default**: `#f1f5f9`
+- **Usage**: Headings and body text inside `.hero#primary`
+
+### `--hero-secondary-bg-color`
+- **Description**: Fallback background color for the secondary hero variant
+- **Light Mode Default**: `var(--color-primary)`
+- **Dark Mode Default**: `#080f1e`
+- **Usage**: `.hero#secondary` background when no image loads
+
+### `--hero-secondary-overlay`
+- **Description**: Gradient overlay tint for secondary hero
+- **Light Mode Default**: `linear-gradient(rgba(17, 40, 85, .75), rgba(17, 40, 85, .75))`
+- **Dark Mode Default**: `linear-gradient(rgba(8, 15, 30, .80), rgba(8, 15, 30, .80))`
+- **Usage**: Stronger overlay for inner-page heroes
+
+### `--hero-secondary-color`
+- **Description**: Text color for secondary hero content
+- **Light Mode Default**: `#f1f5f9`
+- **Dark Mode Default**: `#f1f5f9`
+- **Usage**: Headings and body text inside `.hero#secondary`
+
+---
+
+## Block Color Variables
+
+### Slot Palette (automatic by position order)
+
+| Variable | Purpose | Light Default | Dark Default |
+|---|---|---|---|
+| `--block-color-1` | Background for 1st module | `var(--color-primary)` | `var(--secondary-bg)` |
+| `--block-text-1` | Text for 1st module | `var(--body-color)` | `var(--body-color)` |
+| `--block-color-2` | Background for 2nd module | `var(--accent-color-primary)` | `var(--accent-color-primary)` |
+| `--block-text-2` | Text for 2nd module | `#fff` | `#fff` |
+| `--block-color-3` | Background for 3rd module | `var(--warning, #eec234)` | `rgba(238, 194, 52, .15)` |
+| `--block-text-3` | Text for 3rd module | `var(--body-color)` | `var(--body-color)` |
+| `--block-color-4` | Background for 4th module | `var(--success-bg-subtle, #eef7f0)` | `rgba(74, 166, 100, .15)` |
+| `--block-text-4` | Text for 4th module | `var(--body-color)` | `var(--body-color)` |
+
+### Named Per-Module Overrides
+
+| Variable | Purpose |
+|---|---|
+| `--block-highlight-bg` | Background for `#block-highlight` module |
+| `--block-highlight-text` | Text color for `#block-highlight` module |
+| `--block-cta-bg` | Background for `#block-cta` module |
+| `--block-cta-text` | Text color for `#block-cta` module |
+| `--block-alert-bg` | Background for `#block-alert` module |
+| `--block-alert-text` | Text color for `#block-alert` module |
+
+### Override Priority
+
+| Priority | Method | How applied |
+|---|---|---|
+| 1 (highest) | Named module ID (`#block-highlight`) | ID in module HTML, named variable in palette |
+| 2 | Slot color (`--block-color-1` etc.) | Automatic by `:nth-child()` order |
+
+---
+
+## Metadata
+
+* Document: docs/CSS_VARIABLES.md
+* Repository: [https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+* Path: /docs/CSS_VARIABLES.md
+* Owner: Moko Consulting
+* Version: 03.09.02
+* Status: Active
+* Effective Date: 2026-03-26
+* Classification: Public Open Source Documentation
+
+## Revision History
+
+| Date | Change Summary | Author |
+| ---------- | ----------------------------------------------------- | --------------- |
+| 2026-03-26 | Added hero variant and block color variable docs | Claude |
+| 2026-02-07 | Added missing CSS variable documentation | GitHub Copilot |
+| 2026-01-30 | Initial CSS variables reference documentation created | GitHub Copilot |
diff --git a/docs/JOOMLA_DEVELOPMENT.md b/docs/JOOMLA_DEVELOPMENT.md
new file mode 100644
index 0000000..d83b2f4
--- /dev/null
+++ b/docs/JOOMLA_DEVELOPMENT.md
@@ -0,0 +1,376 @@
+# Joomla Development Workflows and Scripts
+
+This document describes the Joomla-aware development workflows and scripts available in this repository.
+
+## Table of Contents
+
+- [Overview](#overview)
+- [Requirements](#requirements)
+- [Scripts](#scripts)
+- [GitHub Actions Workflows](#github-actions-workflows)
+- [Testing](#testing)
+- [Code Quality](#code-quality)
+- [Deployment](#deployment)
+
+## Overview
+
+This repository includes comprehensive Joomla development workflows and scripts for:
+
+1. **Extension Packaging** - Create distributable ZIP packages
+2. **Joomla Testing** - Automated testing with multiple Joomla versions
+3. **Code Quality** - PHPStan, PHP_CodeSniffer, and compatibility checks
+4. **Deployment** - Staging and production deployment workflows
+
+## Requirements
+
+### Local Development
+
+- PHP 8.0 or higher
+- Composer (for PHPStan and PHP_CodeSniffer)
+- Node.js 18+ (for some workflows)
+- MySQL/MariaDB (for Joomla testing)
+
+### CI/CD (GitHub Actions)
+
+All requirements are automatically installed in CI/CD pipelines.
+
+## Scripts
+
+### Extension Packaging
+
+Package the Joomla template as a distributable ZIP file:
+
+```bash
+make package
+```
+
+This creates a ZIP file in the `dist` directory with all necessary template files, excluding development files.
+
+## GitHub Actions Workflows
+
+### 1. PHP Code Quality (`php_quality.yml`)
+
+Runs on every push and pull request to main branches.
+
+**Jobs:**
+- **PHP_CodeSniffer** - Checks code style and standards
+- **PHPStan** - Static analysis at level 5
+- **PHP Compatibility** - Ensures PHP 8.0+ compatibility
+
+**Matrix Testing:**
+- PHP versions: 8.0, 8.1, 8.2, 8.3
+
+**Trigger:**
+```bash
+# Automatically runs on push/PR
+git push origin dev/3.5.0
+```
+
+### 2. Joomla Testing (`joomla_testing.yml`)
+
+Tests template with multiple Joomla and PHP versions.
+
+**Jobs:**
+- **Joomla Setup** - Installs Joomla CMS
+- **Template Installation** - Installs template into Joomla
+- **Validation** - Validates template functionality
+- **Codeception** - Runs test framework
+
+**Matrix Testing:**
+- PHP versions: 8.0, 8.1, 8.2, 8.3
+- Joomla versions: 4.4 (LTS), 5.0, 5.1
+- MySQL version: 8.0
+
+**Example:**
+```bash
+# Automatically runs on push to main branches
+git push origin main
+```
+
+### 3. Deploy to Staging (`deploy_staging.yml`)
+
+Manual deployment to staging/development environments.
+
+**Parameters:**
+- `environment`: Target environment (staging, development, preview)
+- `version`: Version to deploy (optional, defaults to latest)
+
+**Usage:**
+1. Go to Actions → Deploy to Staging
+2. Click "Run workflow"
+3. Select environment and version
+4. Click "Run workflow"
+
+**Required Secrets:**
+For staging deployment, configure these repository secrets:
+- `STAGING_HOST` - SFTP server hostname
+- `STAGING_USER` - SFTP username
+- `STAGING_KEY` - SSH private key (recommended) or use `STAGING_PASSWORD`
+- `STAGING_PATH` - Remote path for deployment
+- `STAGING_PORT` - SSH port (optional, default: 22)
+
+## Testing
+
+### Codeception Framework
+
+The repository is configured with Codeception for acceptance and unit testing.
+
+#### Running Tests Locally
+
+1. Install Codeception:
+```bash
+composer global require "codeception/codeception" --with-all-dependencies
+```
+
+2. Run tests:
+```bash
+# Run all tests
+codecept run
+
+# Run acceptance tests only
+codecept run acceptance
+
+# Run unit tests only
+codecept run unit
+
+# Run with verbose output
+codecept run --debug
+```
+
+#### Test Structure
+
+```
+tests/
+├── _data/ # Test data and fixtures
+├── _output/ # Test reports and screenshots
+├── _support/ # Helper classes
+├── acceptance/ # Acceptance tests
+│ └── TemplateInstallationCest.php
+├── unit/ # Unit tests
+│ └── TemplateConfigurationTest.php
+├── acceptance.suite.yml
+└── unit.suite.yml
+```
+
+#### Writing Tests
+
+**Unit Test Example:**
+```php
+assertTrue(true);
+ }
+}
+```
+
+**Acceptance Test Example:**
+```php
+amOnPage('/');
+ $I->see('Welcome');
+ }
+}
+```
+
+## Code Quality
+
+### PHPStan
+
+Static analysis configuration in `phpstan.neon`:
+
+```bash
+# Run PHPStan locally
+phpstan analyse --configuration=phpstan.neon
+```
+
+**Configuration:**
+- Analysis level: 5
+- Target paths: `src/`
+- PHP version: 8.0+
+
+### PHP_CodeSniffer
+
+Coding standards configuration in `phpcs.xml`:
+
+```bash
+# Check code style
+phpcs --standard=phpcs.xml
+
+# Fix auto-fixable issues
+phpcbf --standard=phpcs.xml
+```
+
+**Standards:**
+- PSR-12 as base
+- PHP 8.0+ compatibility checks
+- Joomla coding conventions (when available)
+
+### Running Quality Checks Locally
+
+1. Install tools:
+```bash
+composer global require "squizlabs/php_codesniffer:^3.0" --with-all-dependencies
+composer global require "phpstan/phpstan:^1.0" --with-all-dependencies
+composer global require "phpcompatibility/php-compatibility:^9.0" --with-all-dependencies
+```
+
+2. Configure PHPCompatibility:
+```bash
+phpcs --config-set installed_paths ~/.composer/vendor/phpcompatibility/php-compatibility
+```
+
+3. Run checks:
+```bash
+# PHP syntax check
+make validate-required
+
+# CodeSniffer
+phpcs --standard=phpcs.xml src/
+
+# PHPStan
+phpstan analyse --configuration=phpstan.neon
+
+# PHP Compatibility
+phpcs --standard=PHPCompatibility --runtime-set testVersion 8.0- src/
+```
+
+## Deployment
+
+### Manual Deployment
+
+Use the package script to create a distribution:
+
+```bash
+# Create package
+make package
+
+# Upload to server
+scp dist/moko-cassiopeia-3.5.0-template.zip user@server:/path/to/joomla/
+```
+
+### Automated Deployment
+
+Use the GitHub Actions workflow:
+
+1. **Staging Deployment:**
+ - Go to Actions → Deploy to Staging
+ - Select "staging" environment
+ - Click "Run workflow"
+
+2. **Development Testing:**
+ - Select "development" environment
+ - Useful for quick testing without affecting staging
+
+3. **Preview Deployment:**
+ - Select "preview" environment
+ - For showcasing features before staging
+
+### Post-Deployment Steps
+
+After deployment to Joomla:
+
+1. Log in to Joomla administrator
+2. Go to System → Extensions → Discover
+3. Click "Discover" to find the template
+4. Click "Install" to complete installation
+5. Go to System → Site Templates
+6. Configure template settings
+7. Set as default template if desired
+
+## CI/CD Pipeline Details
+
+### Build Process
+
+1. **Validation** - All scripts validate before packaging
+2. **Packaging** - Create ZIP with proper structure
+3. **Testing** - Run on multiple PHP/Joomla versions
+4. **Quality** - PHPStan and PHPCS analysis
+5. **Deployment** - SFTP upload to target environment
+
+### Matrix Testing Strategy
+
+- **PHP Versions:** 8.0, 8.1, 8.2, 8.3
+- **Joomla Versions:** 4.4 LTS, 5.0, 5.1
+- **Exclusions:** PHP 8.3 not tested with Joomla 4.4 (incompatible)
+
+## Troubleshooting
+
+### Common Issues
+
+**Issue: PHP_CodeSniffer not found**
+```bash
+composer global require "squizlabs/php_codesniffer:^3.0"
+export PATH="$PATH:$HOME/.composer/vendor/bin"
+```
+
+**Issue: PHPStan errors**
+```bash
+# Increase analysis memory
+php -d memory_limit=1G $(which phpstan) analyse
+```
+
+**Issue: Joomla installation fails in CI**
+- Check MySQL service is running
+- Verify database credentials
+- Ensure PHP extensions are installed
+
+**Issue: SFTP deployment fails**
+- Verify SSH key is correctly formatted
+- Check firewall allows port 22
+- Ensure STAGING_PATH exists on server
+
+## Contributing
+
+When adding new workflows or scripts:
+
+1. Follow existing script structure
+2. Add proper error handling
+3. Include usage documentation
+4. Test with multiple PHP versions
+5. Update this documentation
+
+## Support
+
+For issues or questions:
+- Open an issue on GitHub
+- Check existing workflow runs for examples
+- Review test output in Actions tab
+
+## License
+
+All scripts and workflows are licensed under GPL-3.0-or-later, same as the main project.
+
+---
+
+## Metadata
+
+* Document: docs/JOOMLA_DEVELOPMENT.md
+* Repository: [https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+* Path: /docs/JOOMLA_DEVELOPMENT.md
+* Owner: Moko Consulting
+* Version: 03.06.03
+* Status: Active
+* Effective Date: 2026-01-30
+* Classification: Public Open Source Documentation
+
+## Revision History
+
+| Date | Change Summary | Author |
+| ---------- | ----------------------------------------------------- | --------------- |
+| 2026-01-30 | Updated metadata to MokoStandards format | GitHub Copilot |
+| 2025-01-04 | Initial Joomla development guide created | GitHub Copilot |
diff --git a/docs/MANUAL_DEPLOYMENT.md b/docs/MANUAL_DEPLOYMENT.md
new file mode 100644
index 0000000..aa11a64
--- /dev/null
+++ b/docs/MANUAL_DEPLOYMENT.md
@@ -0,0 +1,310 @@
+# Manual Deployment Guide - MokoOnyx
+
+This guide explains how to manually deploy the MokoOnyx template from the `src` directory to a Joomla installation without using the build/packaging process.
+
+## Table of Contents
+
+- [Overview](#overview)
+- [Understanding the Structure](#understanding-the-structure)
+- [Manual Deployment Methods](#manual-deployment-methods)
+- [Troubleshooting](#troubleshooting)
+- [When to Use Manual Deployment](#when-to-use-manual-deployment)
+
+## Overview
+
+**Important**: The `src` directory in this repository is the development source, not a ready-to-install package. For production use, we recommend using the packaged ZIP file from [Releases](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases).
+
+However, for development or testing purposes, you can manually deploy files from the `src` directory to your Joomla installation.
+
+## Understanding the Structure
+
+### Repository Structure
+
+The `src/` directory contains:
+
+```
+src/
+├── component.php # Template file
+├── error.php # Template file
+├── index.php # Main template file
+├── offline.php # Template file
+├── templateDetails.xml # Template manifest
+├── joomla.asset.json # Asset registration
+├── html/ # Module & component overrides
+├── language/ # Frontend language files
+├── administrator/ # Backend language files
+│ └── language/
+└── media/ # Assets (CSS, JS, images, fonts)
+ ├── css/
+ ├── js/
+ ├── images/
+ └── fonts/
+```
+
+### Joomla Installation Structure
+
+Joomla expects template files in these locations:
+
+```
+YOUR_JOOMLA_ROOT/
+├── templates/
+│ └── mokoonyx/ # Template files go here
+│ ├── component.php
+│ ├── error.php
+│ ├── index.php
+│ ├── offline.php
+│ ├── templateDetails.xml
+│ ├── joomla.asset.json
+│ ├── html/
+│ ├── language/
+│ └── administrator/
+└── media/
+ └── templates/
+ └── site/
+ └── mokoonyx/ # Media files go here
+ ├── css/
+ ├── js/
+ ├── images/
+ └── fonts/
+```
+
+**Key Point**: Template files and media files go to **different locations** in Joomla!
+
+## Manual Deployment Methods
+
+### Method 1: Recommended - Upload as ZIP (Still Manual)
+
+This method mimics what Joomla's installer does automatically.
+
+1. **Prepare the template directory**:
+ ```bash
+ # From the repository root
+ cd src
+
+ # Copy all files EXCEPT media to a temp directory
+ mkdir -p /tmp/mokoonyx
+ cp component.php /tmp/mokoonyx/
+ cp error.php /tmp/mokoonyx/
+ cp index.php /tmp/mokoonyx/
+ cp offline.php /tmp/mokoonyx/
+ cp templateDetails.xml /tmp/mokoonyx/
+ cp joomla.asset.json /tmp/mokoonyx/
+ cp -r html /tmp/mokoonyx/
+ cp -r language /tmp/mokoonyx/
+ cp -r administrator /tmp/mokoonyx/
+
+ # Copy media to a separate temp directory
+ mkdir -p /tmp/mokoonyx_media
+ cp -r media/* /tmp/mokoonyx_media/
+ ```
+
+2. **Upload to Joomla via FTP/SFTP**:
+ ```bash
+ # Upload template files
+ # Replace with your actual Joomla path
+ scp -r /tmp/mokoonyx/* user@yourserver:/path/to/joomla/templates/mokoonyx/
+
+ # Upload media files
+ scp -r /tmp/mokoonyx_media/* user@yourserver:/path/to/joomla/media/templates/site/mokoonyx/
+ ```
+
+3. **Set proper permissions**:
+ ```bash
+ # On your server
+ cd /path/to/joomla
+ chmod 755 templates/mokoonyx
+ chmod 644 templates/mokoonyx/*
+ chmod 755 templates/mokoonyx/html
+ chmod 755 media/templates/site/mokoonyx
+ ```
+
+### Method 2: Direct Copy to Existing Installation
+
+If you have direct filesystem access (e.g., local development):
+
+1. **Copy template files** (excluding media):
+ ```bash
+ # From repository root
+ cd src
+
+ # Copy to Joomla templates directory
+ cp component.php /path/to/joomla/templates/mokoonyx/
+ cp error.php /path/to/joomla/templates/mokoonyx/
+ cp index.php /path/to/joomla/templates/mokoonyx/
+ cp offline.php /path/to/joomla/templates/mokoonyx/
+ cp templateDetails.xml /path/to/joomla/templates/mokoonyx/
+ cp joomla.asset.json /path/to/joomla/templates/mokoonyx/
+
+ # Copy directories
+ cp -r html /path/to/joomla/templates/mokoonyx/
+ cp -r language /path/to/joomla/templates/mokoonyx/
+ cp -r administrator /path/to/joomla/templates/mokoonyx/
+ ```
+
+2. **Copy media files separately**:
+ ```bash
+ # Copy media to the media directory
+ cp -r media/* /path/to/joomla/media/templates/site/mokoonyx/
+ ```
+
+3. **Clear Joomla cache**:
+ - In Joomla admin: **System → Clear Cache**
+ - Or delete: `/path/to/joomla/cache/*` and `/path/to/joomla/administrator/cache/*`
+
+### Method 3: Symlink for Development (Linux/Mac only)
+
+For active development where you want changes to immediately reflect:
+
+1. **Create symlinks**:
+ ```bash
+ # Remove existing directory if present
+ rm -rf /path/to/joomla/templates/mokoonyx
+ rm -rf /path/to/joomla/media/templates/site/mokoonyx
+
+ # Create parent directories if needed
+ mkdir -p /path/to/joomla/templates
+ mkdir -p /path/to/joomla/media/templates/site
+
+ # Symlink template files
+ ln -s /path/to/MokoOnyx/src /path/to/joomla/templates/mokoonyx
+
+ # Symlink media files
+ ln -s /path/to/MokoOnyx/src/media /path/to/joomla/media/templates/site/mokoonyx
+ ```
+
+2. **Note**: This won't work as-is because the src directory includes the media folder. You'll need to:
+ ```bash
+ # Better approach for symlinks:
+ # Link everything except media at template root
+ cd /path/to/joomla/templates
+ mkdir -p mokoonyx
+ cd mokoonyx
+
+ ln -s /path/to/MokoOnyx/src/component.php
+ ln -s /path/to/MokoOnyx/src/error.php
+ ln -s /path/to/MokoOnyx/src/index.php
+ ln -s /path/to/MokoOnyx/src/offline.php
+ ln -s /path/to/MokoOnyx/src/templateDetails.xml
+ ln -s /path/to/MokoOnyx/src/joomla.asset.json
+ ln -s /path/to/MokoOnyx/src/html
+ ln -s /path/to/MokoOnyx/src/language
+ ln -s /path/to/MokoOnyx/src/administrator
+
+ # Link media separately
+ ln -s /path/to/MokoOnyx/src/media /path/to/joomla/media/templates/site/mokoonyx
+ ```
+
+## Troubleshooting
+
+### Language Files Not Loading
+
+**Problem**: Language strings appear as language keys (e.g., `TPL_MOKOONYX_LABEL`)
+
+**Solution**: Ensure the `language` and `administrator` folders are present in your template directory:
+
+```bash
+# Check if folders exist
+ls -la /path/to/joomla/templates/mokoonyx/language
+ls -la /path/to/joomla/templates/mokoonyx/administrator
+```
+
+The `templateDetails.xml` should contain (lines 54-55):
+```xml
+
+
+ language
+ administrator
+
+```
+
+### CSS/JS Not Loading
+
+**Problem**: Styles or scripts don't apply
+
+**Solution**: Verify media files are in the correct location:
+
+```bash
+# Check media directory structure
+ls -la /path/to/joomla/media/templates/site/mokoonyx/
+# Should show: css/, js/, images/, fonts/
+```
+
+Clear Joomla cache:
+- Admin: **System → Clear Cache**
+- Check browser developer console for 404 errors
+
+### Template Not Appearing in Template Manager
+
+**Problem**: MokoOnyx doesn't show in **System → Site Templates**
+
+**Solution**:
+1. Verify `templateDetails.xml` is present in `/path/to/joomla/templates/mokoonyx/`
+2. Check file permissions (should be readable by web server)
+3. Verify XML is well-formed:
+ ```bash
+ xmllint --noout /path/to/joomla/templates/mokoonyx/templateDetails.xml
+ ```
+4. Check Joomla's error logs for XML parsing errors
+
+### File Permission Issues
+
+**Problem**: "Permission denied" or template files not readable
+
+**Solution**:
+```bash
+# Set proper ownership (replace www-data with your web server user)
+chown -R www-data:www-data /path/to/joomla/templates/mokoonyx
+chown -R www-data:www-data /path/to/joomla/media/templates/site/mokoonyx
+
+# Set proper permissions
+find /path/to/joomla/templates/mokoonyx -type d -exec chmod 755 {} \;
+find /path/to/joomla/templates/mokoonyx -type f -exec chmod 644 {} \;
+find /path/to/joomla/media/templates/site/mokoonyx -type d -exec chmod 755 {} \;
+find /path/to/joomla/media/templates/site/mokoonyx -type f -exec chmod 644 {} \;
+```
+
+## When to Use Manual Deployment
+
+### ✅ Use Manual Deployment For:
+
+- **Active Development**: Testing changes immediately without rebuilding packages
+- **Local Development**: Working on a local Joomla instance
+- **Quick Fixes**: Making emergency hotfixes directly on a development server
+- **Learning**: Understanding the template structure and Joomla's file organization
+
+### ❌ Don't Use Manual Deployment For:
+
+- **Production Sites**: Always use packaged ZIP files from releases
+- **Client Sites**: Use proper Joomla extension installation
+- **Version Control**: Can lead to inconsistent deployments
+- **Staging Environments**: Use CI/CD or release packages
+
+## Best Practices
+
+1. **Always Test Locally First**: Don't deploy untested changes to production
+2. **Keep Backups**: Back up both template and media directories before updating
+3. **Use Version Control**: Track your customizations separately from manual deployments
+4. **Document Changes**: Note any manual file modifications
+5. **Clear Cache**: Always clear Joomla cache after manual file updates
+6. **Verify Permissions**: Ensure web server can read all files
+
+## Related Documentation
+
+- **[Quick Start Guide](QUICK_START.md)** - Development environment setup
+- **[Joomla Development Guide](JOOMLA_DEVELOPMENT.md)** - Complete development workflows
+- **[Release Process](RELEASE_PROCESS.md)** - How to create proper release packages
+
+## Support
+
+If you encounter issues with manual deployment:
+
+1. Check this troubleshooting guide first
+2. Review [Joomla's template documentation](https://docs.joomla.org/J4.x:Creating_a_Simple_Template)
+3. Open an issue on [GitHub](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/issues)
+4. Contact: hello@mokoconsulting.tech
+
+---
+
+**Document Version**: 1.0.0
+**Last Updated**: 2026-03-01
+**Status**: Active
diff --git a/docs/MODULE_OVERRIDES.md b/docs/MODULE_OVERRIDES.md
new file mode 100644
index 0000000..fddf8d7
--- /dev/null
+++ b/docs/MODULE_OVERRIDES.md
@@ -0,0 +1,725 @@
+
+
+# Module & Component Overrides — MokoOnyx
+
+This document provides a comprehensive guide to all mobile-responsive module and component overrides included in MokoOnyx.
+
+## Overview
+
+MokoOnyx includes **16 mobile-responsive module overrides** and **12 component view overrides** designed to enhance the mobile user experience for third-party extensions and the Main Menu navigation.
+
+**Important**: Following Cassiopeia template best practices, MokoOnyx avoids overriding standard Joomla core modules (such as mod_search, mod_login, mod_breadcrumbs) to ensure proper language loading and compatibility. **Exception**: mod_menu "Main Menu" override provides essential Bootstrap 5 collapsible dropdown functionality.
+
+### Alternative Layouts, Not Replacements
+
+**All MokoOnyx overrides use alternative layout names (`mobile.php`) instead of replacing default layouts (`default.php`).** This means:
+
+- ✅ Default Joomla layouts continue to work unchanged
+- ✅ You must explicitly select the "mobile" layout in module/menu item settings
+- ✅ Joomla core updates don't break your site
+- ✅ Full control over which modules use enhanced layouts
+
+**📖 See [OVERRIDE_PHILOSOPHY.md](OVERRIDE_PHILOSOPHY.md) for complete details on how to activate and use these alternative layouts.**
+
+### Key Features
+
+All module overrides share these characteristics:
+
+- **Mobile-First Design**: Optimized for mobile devices with responsive breakpoints
+- **Touch Targets**: 48px on mobile, 44px on desktop (WCAG 2.1 compliant)
+- **Input Font Size**: 16px minimum on mobile (prevents iOS zoom)
+- **Accessibility**: Full ARIA labels, keyboard navigation, semantic HTML
+- **BEM Naming**: Consistent CSS class naming convention
+- **CSS Variables**: Integration with template color schemes
+- **Security**: Proper escaping, _JEXEC checks, index.html protection
+- **Documentation**: Each override includes comprehensive README
+
+## Module Categories
+
+### 1. VirtueMart E-Commerce Modules
+
+Five comprehensive overrides for VirtueMart shopping functionality.
+
+**Master Documentation**: [VIRTUEMART_MODULES_README.md](../src/html/VIRTUEMART_MODULES_README.md)
+
+#### mod_virtuemart_cart
+**Location**: `src/html/mod_virtuemart_cart/`
+
+Shopping cart display with product list and checkout button.
+
+**Features**:
+- Responsive product cards
+- Remove item buttons with confirmations
+- Price display with currency formatting
+- Checkout button with prominent styling
+
+#### mod_virtuemart_product
+**Location**: `src/html/mod_virtuemart_product/`
+
+Product showcase with grid layouts.
+
+**Features**:
+- Responsive grid: 1-4 columns based on screen size
+- Product images with hover effects
+- Price display and "Add to Cart" buttons
+- Rating display support
+
+#### mod_virtuemart_currencies
+**Location**: `src/html/mod_virtuemart_currencies/`
+
+Currency selector dropdown for multi-currency stores.
+
+**Features**:
+- Accessible dropdown with proper labels
+- Currency symbol and name display
+- Responsive button styling
+
+#### mod_virtuemart_category
+**Location**: `src/html/mod_virtuemart_category/`
+
+Category navigation with hierarchical display.
+
+**Features**:
+- Expandable subcategories
+- Product count display
+- Hierarchical indentation
+- Active category highlighting
+
+#### mod_virtuemart_manufacturer
+**Location**: `src/html/mod_virtuemart_manufacturer/`
+
+Manufacturer/brand display with grid layout.
+
+**Features**:
+- Responsive grid: 2-4 columns
+- Logo display support
+- Product count per manufacturer
+
+---
+
+### 2. Main Menu & Community Builder Modules
+
+Three essential Community Builder and navigation module overrides.
+
+#### mod_menu (Main Menu)
+**Location**: `src/html/mod_menu/`
+
+Bootstrap 5 responsive navigation menu with collapsible dropdown functionality.
+
+**Files**:
+- `mainmenu.php` - Main layout with Bootstrap navbar
+- `mainmenu_component.php` - Component menu items
+- `mainmenu_heading.php` - Heading menu items
+- `mainmenu_separator.php` - Separator menu items
+- `mainmenu_url.php` - URL menu items
+
+**Features**:
+- Bootstrap 5 navbar structure with collapsible hamburger menu
+- Multi-level dropdown support (hover on desktop, tap on mobile)
+- WCAG 2.1 compliant touch targets (48px mobile, 44px desktop)
+- BEM naming convention: `.mod-menu-main__*`
+- Active state indicators for current menu items
+- ARIA labels and keyboard navigation support
+- Alternative layout named `mainmenu.php` (not `default.php`)
+
+**Activation**: Select "Mainmenu" layout in Joomla Administrator → Modules → Menu Module → Advanced Tab → Alternative Layout
+
+**Note**: Unlike the broken mod_menu override removed in v03.08.01, this v03.08.03 version is properly structured based on Joomla core layouts and Bootstrap 5, ensuring language strings load correctly and menu functionality works as expected.
+
+#### mod_cblogin
+**Location**: `src/html/mod_cblogin/`
+
+Community Builder login with avatar display.
+
+**Features**:
+- User avatar when logged in
+- CB-specific login form
+- Profile link
+- Logout button
+
+#### mod_comprofilerOnline
+**Location**: `src/html/mod_comprofilerOnline/`
+
+Community Builder online users display.
+
+**Features**:
+- User count display
+- Avatar grid layout
+- Username display
+- Online status indicators
+
+---
+
+### 3. Industry Extension Modules
+
+Eight popular third-party extension module overrides plus component views.
+
+#### K2 Content Extension
+
+##### mod_k2_content
+**Location**: `src/html/mod_k2_content/`
+
+K2 content display with advanced layouts.
+
+**Features**:
+- Responsive grid: 1-3 columns
+- Featured images with lazy loading
+- Category, author, date metadata
+- Excerpt support
+- Tag display
+
+#### AcyMailing Newsletter
+
+##### mod_acymailing
+**Location**: `src/html/mod_acymailing/`
+
+Newsletter subscription form.
+
+**Features**:
+- Email validation
+- Privacy checkbox
+- Success/error messaging
+- GDPR compliance fields
+
+#### HikaShop E-Commerce
+
+##### mod_hikashop_cart
+**Location**: `src/html/mod_hikashop_cart/`
+
+HikaShop shopping cart module.
+
+**Features**:
+- Product list with images
+- Quantity adjustment
+- Price totals
+- Checkout button
+
+#### Kunena Forum
+
+Four comprehensive forum modules plus component view.
+
+##### mod_kunenalatest
+**Location**: `src/html/mod_kunenalatest/`
+
+Latest forum posts display.
+
+**Features**:
+- Post excerpts
+- Author avatars
+- Reply count
+- Post date
+
+##### mod_kunenalogin
+**Location**: `src/html/mod_kunenalogin/`
+
+Forum-specific login module.
+
+**Features**:
+- User avatar display
+- Forum statistics
+- Quick login form
+- Profile link
+
+##### mod_kunenasearch
+**Location**: `src/html/mod_kunenasearch/`
+
+Forum search with button positions.
+
+**Features**:
+- Multiple button positions (left, right, top)
+- Search placeholder text
+- Icon support
+- 48px touch targets
+
+##### mod_kunenastats
+**Location**: `src/html/mod_kunenastats/`
+
+Forum statistics display.
+
+**Features**:
+- Visual stat cards
+- Member count
+- Topic/post totals
+- Latest member
+- Responsive grid layout
+
+##### com_kunena (Component)
+**Location**: `src/html/com_kunena/`
+
+Forum category list view.
+
+**Views**:
+- `category/default.php` - Category listing with icons
+
+#### OS Membership Pro
+
+Module and component overrides for membership management.
+
+##### mod_osmembership
+**Location**: `src/html/mod_osmembership/`
+
+Membership plans module.
+
+**Features**:
+- Plan cards with pricing
+- Feature lists
+- Signup buttons
+- Badge displays (popular, featured)
+
+##### com_osmembership (Component)
+**Location**: `src/html/com_osmembership/`
+
+Membership pricing tables.
+
+**Views**:
+- `plans/default.php` - Responsive pricing table with comparison features
+
+---
+
+### 4. Community Builder Components
+
+Four comprehensive component view overrides for Community Builder user management.
+
+#### com_comprofiler
+**Location**: `src/html/com_comprofiler/`
+
+Mobile-responsive views for Community Builder user profiles, registration, and login.
+
+##### userprofile
+User profile display with tabbed interface.
+
+**Features**:
+- Large avatar display (150px)
+- Tabbed interface for profile sections
+- Custom field display with labels
+- Online status indicator
+- Responsive layout: vertical mobile → horizontal desktop
+
+##### userslist
+User directory with search and grid layout.
+
+**Features**:
+- Search functionality with accessible form
+- Responsive grid: 1 column mobile → 2-3 columns desktop
+- User cards with avatars (80px)
+- Custom field display
+- Profile view buttons
+- Pagination support
+
+##### registers
+Multi-step registration form with validation.
+
+**Features**:
+- Fieldset organization with legends
+- Required field indicators (*)
+- Input validation and error display
+- Captcha support section
+- Terms & conditions checkbox
+- GDPR-compliant design
+- 16px input font on mobile
+
+##### login
+Login page with remember me and helper links.
+
+**Features**:
+- Centered login container (max-width: 450px)
+- Username/password fields with autocomplete
+- Remember me checkbox
+- Registration and password recovery links
+- CSRF token support
+- Responsive padding adjustments
+
+### 5. JEM (Joomla Event Manager) Components
+
+Five comprehensive component view overrides for JEM event management.
+
+#### com_jem
+**Location**: `src/html/com_jem/`
+
+Mobile-responsive views for JEM event listings, details, calendar, venues, and categories.
+
+##### eventslist
+Event listing with card-based layout.
+
+**Features**:
+- Event cards with date, time, and venue
+- Category badges with color coding
+- Responsive event grid layout
+- Event description excerpts
+- Read more buttons with clear calls-to-action
+- Pagination support
+- Empty state messaging
+
+##### event
+Single event details view with comprehensive information.
+
+**Features**:
+- Large event image display (responsive)
+- Date and time with structured data
+- Venue information with maps link
+- Event description with full content
+- Category display with badges
+- Registration information (if enabled)
+- Contact information display
+- Back to events navigation
+- Meta information with icons
+
+##### calendar
+Monthly calendar view with event indicators.
+
+**Features**:
+- Month navigation (previous/next)
+- Calendar grid with weekday headers
+- Event indicators on dates with events
+- Responsive calendar layout
+- Today highlighting
+- Event list for selected month
+- Event count per day display
+- Touch-friendly navigation buttons
+
+##### venue
+Venue details with location and upcoming events.
+
+**Features**:
+- Venue image display
+- Complete address information
+- Website link (external)
+- Google Maps integration
+- Venue description
+- Upcoming events at venue
+- Location coordinates display
+- Back navigation
+
+##### categories
+Event category listing with descriptions.
+
+**Features**:
+- Category cards with images
+- Category descriptions
+- Event count per category
+- View category buttons
+- Responsive grid layout
+- Empty state messaging
+- Pagination support
+
+---
+
+## CSS Architecture
+
+All module styles are located in `src/media/css/template.css` with dedicated sections:
+
+### CSS Sections
+
+1. **MOD_SEARCH MOBILE RESPONSIVE STYLES** (Lines ~18400+)
+ - Search box layouts
+ - Button position variants
+ - Input styling
+
+2. **VIRTUEMART MODULE MOBILE RESPONSIVE STYLES** (Lines ~18500+)
+ - Cart product cards
+ - Product grids
+ - Currency selector
+ - Category navigation
+ - Manufacturer displays
+
+3. **STANDARD JOOMLA & COMMUNITY BUILDER MODULE STYLES** (Lines ~19300+)
+ - Menu navigation
+ - Breadcrumbs
+ - Login forms
+ - Article displays
+ - CB module components
+
+4. **INDUSTRY EXTENSION MODULE STYLES** (Lines ~19800+)
+ - K2 content grids
+ - AcyMailing forms
+ - HikaShop cart
+ - Kunena forum modules
+ - OS Membership pricing
+
+5. **COMMUNITY BUILDER COMPONENT STYLES** (Lines ~21000+)
+ - User profile layouts
+ - Users list grids
+ - Registration forms
+ - Login pages
+ - Tab interfaces
+
+6. **JEM COMPONENT STYLES** (Lines ~22000+)
+ - Event list cards
+ - Event details layout
+ - Calendar grid
+ - Venue information
+ - Category displays
+
+### CSS Variables Integration
+
+All modules integrate with template CSS variables:
+
+```css
+/* Common Variables Used */
+--body-color /* Text color */
+--link-color /* Link color */
+--link-hover-color /* Link hover color */
+--border-color /* Border color */
+--secondary-bg /* Background color */
+--border-radius /* Border radius */
+--input-bg /* Input background */
+--input-border-color /* Input border */
+--btn-primary-bg /* Primary button */
+--btn-primary-hover-bg /* Button hover */
+```
+
+See [CSS_VARIABLES.md](CSS_VARIABLES.md) for complete reference.
+
+---
+
+## Responsive Breakpoints
+
+All modules use Bootstrap-aligned breakpoints:
+
+| Breakpoint | Size | Typical Changes |
+|------------|-----------|-----------------------------------|
+| `xs` | < 576px | Single column, stacked layouts |
+| `sm` | ≥ 576px | 2 columns for grids |
+| `md` | ≥ 768px | 3 columns, horizontal layouts |
+| `lg` | ≥ 992px | 4 columns, expanded spacing |
+| `xl` | ≥ 1200px | Maximum width, optimal spacing |
+| `xxl` | ≥ 1400px | Extra spacing |
+
+---
+
+## Accessibility Features
+
+All overrides implement comprehensive accessibility:
+
+### ARIA Labels
+- Descriptive labels for all interactive elements
+- `aria-label` for icon-only buttons
+- `aria-describedby` for form fields
+- `aria-live` for dynamic content
+
+### Keyboard Navigation
+- Proper tab order
+- Focus states on all interactive elements
+- Keyboard-accessible dropdowns
+- Skip links where appropriate
+
+### Screen Readers
+- Semantic HTML5 elements
+- Hidden text for icon-only elements
+- Proper heading hierarchy
+- Alternative text for images
+
+### WCAG 2.1 Compliance
+- Touch targets: 48px minimum on mobile
+- Color contrast ratios meet AA standards
+- Text resizable to 200% without loss
+- No content relies on color alone
+
+---
+
+## Customization Guide
+
+### Override Customization
+
+Each module can be customized in two ways:
+
+#### 1. CSS Customization
+
+Edit `src/media/css/user.css` to add custom styles:
+
+```css
+/* Example: Change product grid columns */
+@media (min-width: 768px) {
+ .mod-vm-product__grid {
+ grid-template-columns: repeat(3, 1fr);
+ }
+}
+
+/* Example: Customize cart button */
+.mod-vm-cart__checkout-button {
+ background-color: #28a745;
+}
+```
+
+#### 2. Template Override Customization
+
+Copy the entire module directory and modify:
+
+```bash
+# Keep original override as reference
+cp -r src/html/mod_virtuemart_cart src/html/mod_virtuemart_cart_original
+
+# Modify your version
+# Edit src/html/mod_virtuemart_cart/default.php
+```
+
+### CSS Variables Override
+
+Override CSS variables in your custom color scheme:
+
+```css
+/* src/media/css/theme/light.custom.css */
+:root {
+ --vm-price-color: #28a745;
+ --vm-cart-bg: #f8f9fa;
+ --vm-button-primary: #007bff;
+}
+```
+
+---
+
+## Best Practices
+
+### When Using Overrides
+
+1. **Test Across Devices**: Always test on actual mobile devices
+2. **Maintain Accessibility**: Don't remove ARIA labels or keyboard navigation
+3. **Keep BEM Naming**: Use established class naming patterns
+4. **Security First**: Always escape output and validate input
+5. **Document Changes**: Comment your customizations
+
+### When Updating
+
+1. **Backup First**: Always backup your site before updating
+2. **Review Changes**: Check CHANGELOG.md for breaking changes
+3. **Test Thoroughly**: Test all modules after updates
+4. **Custom Overrides**: May need adjustments after template updates
+
+---
+
+## Troubleshooting
+
+### Common Issues
+
+#### Module Not Displaying Correctly
+1. Clear Joomla cache (System → Clear Cache)
+2. Check module is published and assigned to correct position
+3. Verify template is assigned to menu items
+4. Check browser console for JavaScript errors
+
+#### Styles Not Applying
+1. Clear browser cache (Ctrl+F5 / Cmd+Shift+R)
+2. Verify `template.css` is loading
+3. Check CSS specificity conflicts
+4. Review custom CSS in `user.css`
+
+#### Mobile View Issues
+1. Test with browser dev tools responsive mode
+2. Check viewport meta tag in template
+3. Verify breakpoint media queries
+4. Test on actual devices when possible
+
+#### Accessibility Issues
+1. Run WAVE or axe DevTools accessibility check
+2. Test with keyboard navigation only
+3. Verify screen reader compatibility
+4. Check color contrast ratios
+
+### Getting Help
+
+- **Documentation**: Check module-specific README files
+- **GitHub Issues**: [Report issues](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/issues)
+- **Support**: hello@mokoconsulting.tech
+
+---
+
+## How to Activate Alternative Layouts
+
+All MokoOnyx overrides are **alternative layouts** that must be explicitly activated. They do not automatically replace default layouts.
+
+### Quick Start: Enable Mobile Layout
+
+1. **Go to Joomla Administrator** → Extensions → Modules
+2. **Open the module** you want to enhance (e.g., VirtueMart Cart)
+3. **Navigate to Advanced tab**
+4. **Find "Alternative Layout" field**
+5. **Select "MokoOnyx - mobile"** from dropdown
+6. **Save & Close**
+
+### For Menu Items (Component Views)
+
+1. **Go to Menus** → Select your menu
+2. **Open the menu item** (e.g., Events List)
+3. **Navigate to Advanced Options or Page Display tab**
+4. **Find "Alternative Layout" field**
+5. **Select "MokoOnyx - mobile"** from dropdown
+6. **Save & Close**
+
+### Apply to All Modules in a Position
+
+In your template's `index.php`, specify layout for entire module position:
+
+```php
+
+```
+
+**📖 For complete documentation, see [OVERRIDE_PHILOSOPHY.md](OVERRIDE_PHILOSOPHY.md)**
+
+---
+
+## Version History
+
+| Version | Date | Changes |
+|----------|------------|--------------------------------------------------|
+| 03.08.04 | 2026-02-27 | Added alternative layout activation instructions, JEM overrides |
+| 03.08.03 | 2026-02-25 | Removed mod_search override per Cassiopeia philosophy |
+| 03.08.00 | 2026-02-22 | Added Community Builder component overrides |
+| 03.07.00 | 2026-02-22 | Initial release of all mobile-responsive overrides |
+
+---
+
+## Additional Resources
+
+- **Override Philosophy**: [OVERRIDE_PHILOSOPHY.md](OVERRIDE_PHILOSOPHY.md) ⭐ **Start here**
+- **Main README**: [README.md](../README.md)
+- **Changelog**: [CHANGELOG.md](../CHANGELOG.md)
+- **CSS Variables**: [CSS_VARIABLES.md](CSS_VARIABLES.md)
+- **Repository**: [GitHub](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+
+---
+
+## Metadata
+
+* Document: docs/MODULE_OVERRIDES.md
+* Repository: [https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+* Path: /docs/MODULE_OVERRIDES.md
+* Owner: Moko Consulting
+* Version: 03.07.00
+* Status: Active
+* Effective Date: 2026-02-22
+* Classification: Public Open Source Documentation
+
+## Revision History
+
+| Date | Change Summary | Author |
+| ---------- | ----------------------------------------------------- | --------------- |
+| 2026-02-22 | Initial creation with comprehensive module override documentation | GitHub Copilot |
diff --git a/docs/OVERRIDE_PHILOSOPHY.md b/docs/OVERRIDE_PHILOSOPHY.md
new file mode 100644
index 0000000..0761a8d
--- /dev/null
+++ b/docs/OVERRIDE_PHILOSOPHY.md
@@ -0,0 +1,332 @@
+
+
+# Override Philosophy — MokoOnyx
+
+## Core Principle: Add-On, Not Replacement
+
+**MokoOnyx overrides are designed as alternative layouts, not replacements of default Joomla layouts.**
+
+This means:
+- ✅ Default Joomla layouts continue to work unchanged
+- ✅ Site administrators can choose when to use our enhanced layouts
+- ✅ Updates to Joomla core layouts don't break the site
+- ✅ Compatibility with other extensions is maintained
+- ✅ Users have control over which layouts to use
+
+---
+
+## Technical Implementation
+
+### Layout Naming Convention
+
+All MokoOnyx overrides use **`mobile.php`** naming instead of **`default.php`**:
+
+```
+❌ BAD (Replaces default):
+src/html/mod_virtuemart_cart/default.php
+
+✅ GOOD (Alternative layout):
+src/html/mod_virtuemart_cart/mobile.php
+```
+
+### How Joomla Handles Layouts
+
+When a module or component looks for a layout, Joomla searches in this order:
+
+1. **Template override with specified layout name**: `templates/mokoonyx/html/{extension}/{view}/{layout}.php`
+2. **Extension's specified layout**: `{extension}/tmpl/{view}/{layout}.php`
+3. **Template override for default layout**: `templates/mokoonyx/html/{extension}/{view}/default.php`
+4. **Extension's default layout**: `{extension}/tmpl/{view}/default.php`
+
+By naming our overrides `mobile.php` instead of `default.php`, they become **step 1** alternatives that must be explicitly selected, rather than **step 3** replacements that are automatically used.
+
+---
+
+## How to Use Alternative Layouts
+
+### Method 1: Module/Menu Item Settings
+
+When editing a module or menu item in Joomla administrator:
+
+1. Open the module/menu item for editing
+2. Navigate to the **Advanced** tab
+3. Find the **Alternative Layout** field
+4. Select **MokoOnyx - mobile** from the dropdown
+5. Save
+
+### Method 2: Override in Module Position
+
+If you want all modules in a specific position to use the mobile layout:
+
+```php
+
+countModules('sidebar-left')) : ?>
+
+
+```
+
+### Method 3: Module Chrome (Advanced)
+
+Create a custom module chrome in `templates/mokoonyx/html/layouts/chromes/` that automatically applies the mobile layout.
+
+---
+
+## Exception: Main Menu
+
+**The only exception** to this philosophy is `mod_menu` with the "Main Menu" module type.
+
+The template includes files like:
+- `src/html/mod_menu/mainmenu.php`
+- `src/html/mod_menu/mainmenu_component.php`
+- `src/html/mod_menu/mainmenu_heading.php`
+- `src/html/mod_menu/mainmenu_url.php`
+- `src/html/mod_menu/mainmenu_separator.php`
+
+These use a **custom layout name** (`mainmenu`) instead of replacing `default.php`, which allows the site to:
+- Use the enhanced Bootstrap 5 collapsible menu for main navigation
+- Keep standard Joomla menus working in other positions
+- Provide better mobile navigation without breaking existing menus
+
+To use this layout, set the module's **Alternative Layout** to **MokoOnyx - mainmenu**.
+
+---
+
+## Override Inventory
+
+### Module Overrides (16 total)
+
+All use `mobile.php` naming (alternative layout):
+
+**VirtueMart (5)**:
+- `mod_virtuemart_cart/mobile.php`
+- `mod_virtuemart_product/mobile.php`
+- `mod_virtuemart_currencies/mobile.php`
+- `mod_virtuemart_category/mobile.php`
+- `mod_virtuemart_manufacturer/mobile.php`
+
+**Community Builder (2)**:
+- `mod_cblogin/mobile.php`
+- `mod_comprofilerOnline/mobile.php`
+
+**Main Menu (1)**:
+- `mod_menu/mainmenu.php` (custom layout name)
+
+**Industry Extensions (8)**:
+- `mod_k2_content/mobile.php`
+- `mod_acymailing/mobile.php`
+- `mod_hikashop_cart/mobile.php`
+- `mod_kunenalatest/mobile.php`
+- `mod_kunenalogin/mobile.php`
+- `mod_kunenasearch/mobile.php`
+- `mod_kunenastats/mobile.php`
+- `mod_osmembership/mobile.php`
+
+### Component View Overrides (12 total)
+
+All use `mobile.php` naming (alternative layout):
+
+**Community Builder (4)**:
+- `com_comprofiler/userprofile/mobile.php`
+- `com_comprofiler/userslist/mobile.php`
+- `com_comprofiler/registers/mobile.php`
+- `com_comprofiler/login/mobile.php`
+
+**JEM - Joomla Event Manager (5)**:
+- `com_jem/eventslist/mobile.php`
+- `com_jem/event/mobile.php`
+- `com_jem/calendar/mobile.php`
+- `com_jem/venue/mobile.php`
+- `com_jem/categories/mobile.php`
+
+**Kunena Forum (1)**:
+- `com_kunena/category/mobile.php`
+
+**OSMembership (2)**:
+- `com_osmembership/plan/mobile.php`
+- `com_osmembership/plans/mobile.php`
+
+**Joomla Core (2)**:
+- `com_content/article/toc-left.php` (custom layout name)
+- `com_content/article/toc-right.php` (custom layout name)
+
+---
+
+## Benefits of This Approach
+
+### 1. **Zero Breaking Changes**
+
+Existing sites continue to work exactly as before. No layouts are forcibly changed.
+
+### 2. **Gradual Adoption**
+
+Site administrators can:
+- Test mobile layouts on specific modules first
+- Roll out changes module-by-module
+- Keep some modules using default layouts if needed
+- Easily revert by changing the Alternative Layout setting
+
+### 3. **Extension Compatibility**
+
+Third-party extensions' default layouts remain untouched, preventing conflicts with:
+- Extension updates
+- Other templates
+- Custom development
+
+### 4. **Joomla Core Updates**
+
+When Joomla core updates:
+- Default layouts get new features/bug fixes automatically
+- Mobile layouts remain stable and tested
+- No emergency fixes needed after Joomla updates
+
+### 5. **Multi-Language Support**
+
+Joomla's language system loads extension language files properly because:
+- Extensions aren't hijacked by template overrides
+- Language strings come from the correct source
+- Translations work as expected
+
+---
+
+## Standards Not Overridden
+
+Following Cassiopeia template best practices, MokoOnyx **does not override** standard Joomla core modules:
+
+- ❌ `mod_breadcrumbs` - Use Joomla core layout
+- ❌ `mod_login` - Use Joomla core layout
+- ❌ `mod_articles_latest` - Use Joomla core layout
+- ❌ `mod_articles_category` - Use Joomla core layout
+- ❌ `mod_articles_news` - Use Joomla core layout
+- ❌ `mod_search` - Use Joomla core layout (removed in v03.08.03)
+
+**Reason**: These modules have robust core layouts with proper language loading, accessibility, and ongoing Joomla maintenance.
+
+---
+
+## Developer Guidelines
+
+When adding new overrides to MokoOnyx:
+
+### ✅ DO:
+
+1. Name files `mobile.php` or use descriptive custom names (`mainmenu.php`, `toc-left.php`)
+2. Document the alternative layout in MODULE_OVERRIDES.md
+3. Add CSS with BEM naming: `.{extension}-{view}__element`
+4. Test that default layouts still work
+5. Provide clear instructions for selecting the layout
+
+### ❌ DON'T:
+
+1. Create `default.php` files that replace core layouts
+2. Override standard Joomla core modules without strong justification
+3. Break backward compatibility
+4. Assume users will automatically get your layout
+5. Forget to document how to enable the alternative layout
+
+---
+
+## Migration from Replacing Overrides
+
+If you're migrating from a template that used `default.php` overrides:
+
+### Step 1: Identify Replaced Layouts
+
+```bash
+find templates/oldtemplate/html -name "default.php"
+```
+
+### Step 2: Rename to Alternative Layouts
+
+```bash
+# For each default.php found:
+mv default.php mobile.php
+```
+
+### Step 3: Update Module Settings
+
+For each module using the old override:
+1. Edit module in administrator
+2. Advanced tab → Alternative Layout
+3. Select "mobile" from dropdown
+4. Save
+
+### Step 4: Test
+
+- Verify module displays correctly
+- Check that other modules still use default layouts
+- Confirm language strings load properly
+
+---
+
+## Troubleshooting
+
+### My Alternative Layout Doesn't Appear in Dropdown
+
+**Check:**
+1. File is in correct location: `templates/mokoonyx/html/{extension}/{view}/`
+2. File has `.php` extension
+3. File is not named `default.php`
+4. Cache is cleared (System → Clear Cache)
+
+### Module Still Uses Default Layout
+
+**Check:**
+1. Module's Alternative Layout setting in administrator
+2. Module position's `layout` parameter in `` tag
+3. File permissions (must be readable)
+4. Template is assigned to correct pages
+
+### Layout Works But Looks Wrong
+
+**Check:**
+1. CSS is loaded: inspect element and check for `.{extension}-{view}__` classes
+2. `template.css` is up to date
+3. Browser cache is cleared
+4. CSS variables are defined in template
+
+---
+
+## References
+
+- [Joomla Docs: Layout Overrides](https://docs.joomla.org/Layout_Overrides_in_Joomla)
+- [Joomla Docs: Alternative Layouts](https://docs.joomla.org/J3.x:How_to_use_the_alternative_layout_feature)
+- [MODULE_OVERRIDES.md](MODULE_OVERRIDES.md) - Complete override inventory
+- [CSS_VARIABLES.md](CSS_VARIABLES.md) - Template styling system
+
+---
+
+## Version History
+
+- **03.08.04**: Created OVERRIDE_PHILOSOPHY.md document
+- **03.08.03**: Removed mod_search override to align with philosophy
+- **03.08.02**: Removed standard Joomla module overrides for proper language loading
+- **Earlier**: Renamed all overrides from default.php to mobile.php (21 files)
diff --git a/docs/QUICK_START.md b/docs/QUICK_START.md
new file mode 100644
index 0000000..7cc82e0
--- /dev/null
+++ b/docs/QUICK_START.md
@@ -0,0 +1,333 @@
+# Quick Start Guide - MokoOnyx Development
+
+Get up and running with MokoOnyx development in minutes.
+
+## Prerequisites
+
+Before you begin, ensure you have:
+
+- **Git** - For version control
+- **PHP 8.0+** - Required runtime
+- **Composer** - PHP dependency manager
+- **Make** (optional) - For convenient commands
+- **Code Editor** - VS Code recommended (tasks pre-configured)
+
+## 5-Minute Setup
+
+### 1. Clone the Repository
+
+```bash
+git clone https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx.git
+cd MokoOnyx
+```
+
+### 2. Install Development Dependencies
+
+```bash
+# Using Make (recommended)
+make dev-setup
+
+# Or manually
+composer global require "squizlabs/php_codesniffer:^3.0"
+composer global require phpstan/phpstan
+composer global require "phpcompatibility/php-compatibility:^9.0"
+composer global require codeception/codeception
+```
+
+### 3. Validate Everything Works
+
+```bash
+# Quick validation
+make validate-required
+
+# Or comprehensive validation
+make validate
+```
+
+## Common Tasks
+
+### Development Workflow
+
+```bash
+# 1. Make your changes
+vim src/index.php
+
+# 2. Validate locally
+make validate-required
+
+# 3. Check code quality
+make quality
+
+# 4. Commit
+git add -A
+git commit -m "feat: add new feature"
+# (pre-commit hook runs automatically)
+
+# 5. Push
+git push origin your-branch
+```
+
+### Testing
+
+```bash
+# Run all tests
+make test
+
+# Run unit tests only
+make test-unit
+
+# Run acceptance tests only
+make test-acceptance
+```
+
+### Code Quality
+
+```bash
+# Check everything
+make quality
+
+# PHP CodeSniffer only
+make phpcs
+
+# Auto-fix PHPCS issues
+make phpcs-fix
+
+# PHPStan only
+make phpstan
+
+# PHP compatibility check
+make phpcompat
+```
+
+### Creating a Release Package
+
+```bash
+# Package with auto-detected version
+make package
+
+# Check package contents
+ls -lh dist/
+unzip -l dist/mokoonyx-*.zip
+```
+
+## VS Code Integration
+
+If using VS Code, press `Ctrl+Shift+P` (or `Cmd+Shift+P` on Mac) and type "Run Task" to see available tasks:
+
+- **Validate All** - Run all validation scripts (default test task)
+- **Validate Required** - Run only required validations
+- **PHP CodeSniffer** - Check code style
+- **PHP CodeSniffer - Auto Fix** - Fix code style issues
+- **PHPStan** - Static analysis
+- **Run Tests** - Execute all tests
+- **Create Package** - Build distribution ZIP
+- **Install Git Hooks** - Set up pre-commit hooks
+
+## Available Make Commands
+
+Run `make help` to see all available commands:
+
+```bash
+make help # Show all commands
+make dev-setup # Complete environment setup
+make validate # Run all validations
+make test # Run all tests
+make quality # Check code quality
+make package # Create distribution package
+make clean # Remove generated files
+make check # Quick check (validate + quality)
+make all # Complete build pipeline
+```
+
+## Project Structure
+
+```
+moko-cassiopeia/
+├── src/ # Joomla template source (template root)
+│ ├── component.php # Component template file
+│ ├── index.php # Main template file
+│ ├── offline.php # Offline page template
+│ ├── error.php # Error page template
+│ ├── templateDetails.xml # Template manifest
+│ ├── html/ # Module & component overrides
+│ ├── media/ # Assets (CSS, JS, images, fonts)
+│ ├── language/ # Frontend language files (en-GB, en-US)
+│ └── administrator/ # Backend files
+│ └── language/ # Backend language files
+├── tests/ # Test suites
+├── docs/ # Documentation
+├── scripts/ # Build scripts
+├── .github/workflows/ # CI/CD workflows
+├── Makefile # Make commands
+└── README.md # Project overview
+```
+
+## Next Steps
+
+### Learning the Workflow
+
+1. **Read the Workflow Guide**: [docs/WORKFLOW_GUIDE.md](./WORKFLOW_GUIDE.md)
+2. **Review Joomla Development**: [docs/JOOMLA_DEVELOPMENT.md](./JOOMLA_DEVELOPMENT.md)
+
+### Creating Your First Feature
+
+1. **Create a version branch** via GitHub Actions:
+ - Go to Actions → Create version branch
+ - Enter version (e.g., 03.06.00)
+ - Select branch prefix: `dev/`
+ - Run workflow
+
+2. **Checkout the branch**:
+ ```bash
+ git fetch origin
+ git checkout dev/03.06.00
+ ```
+
+3. **Make changes and test**:
+ ```bash
+ # Edit files
+ vim src/index.php
+
+ # Validate
+ make validate-required
+
+ # Check quality
+ make quality
+ ```
+
+4. **Commit and push**:
+ ```bash
+ git add -A
+ git commit -m "feat: your feature description"
+ git push origin dev/03.06.00
+ ```
+
+5. **Watch CI**: Check GitHub Actions for automated testing
+
+### Understanding the Release Process
+
+```
+Development → RC → Stable → Production
+ (dev/) (rc/) (version/) (main)
+```
+
+1. **dev/X.Y.Z** - Active development
+2. **rc/X.Y.Z** - Release candidate testing
+3. **version/X.Y.Z** - Stable release
+4. **main** - Production (auto-merged from version/)
+
+Use the Release Pipeline workflow to promote between stages.
+
+## Troubleshooting
+
+### Scripts Not Executable
+
+```bash
+make fix-permissions
+### PHPStan/PHPCS Not Found
+
+```bash
+make install
+# Or manually:
+composer global require "squizlabs/php_codesniffer:^3.0" phpstan/phpstan
+```
+
+### CI Workflow Fails
+
+1. Check the workflow logs in GitHub Actions
+2. Run validation locally:
+ ```bash
+ make validate-required
+ make quality
+ ```
+
+### Need Help?
+
+- **Documentation**: Check [docs/](../docs/) directory
+- **Issues**: Open an issue on GitHub
+- **Contributing**: See [CONTRIBUTING.md](../CONTRIBUTING.md)
+
+## Best Practices
+
+### Before Committing
+
+```bash
+# Always validate first
+make validate-required
+
+# Check quality for PHP changes
+make quality
+
+# Run tests if you changed functionality
+make test
+```
+
+### Code Style
+
+- Follow PSR-12 standards
+- Use `make phpcs-fix` to auto-fix issues
+- Add SPDX license headers to new files
+- Keep functions small and focused
+
+### Documentation
+
+- Update docs when changing workflows
+- Add comments for complex logic
+- Update CHANGELOG.md with changes
+- Keep README.md current
+
+### Version Management
+
+- Use semantic versioning: Major.Minor.Patch (03.06.00)
+- Update CHANGELOG.md with all changes
+- Follow the version hierarchy: dev → rc → version → main
+- Never skip stages in the release process
+
+## Useful Resources
+
+- [Joomla Documentation](https://docs.joomla.org/)
+- [PSR-12 Coding Standard](https://www.php-fig.org/psr/psr-12/)
+- [Semantic Versioning](https://semver.org/)
+- [Conventional Commits](https://www.conventionalcommits.org/)
+
+## Quick Reference Card
+
+```bash
+# Setup
+make dev-setup # Initial setup
+
+# Development
+make validate-required # Quick validation
+make quality # Code quality
+make test # Run tests
+
+# Building
+make package # Create ZIP
+
+# Maintenance
+make clean # Clean generated files
+make fix-permissions # Fix script permissions
+
+# Help
+make help # Show all commands
+```
+
+---
+
+## Metadata
+
+* Document: docs/QUICK_START.md
+* Repository: [https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+* Path: /docs/QUICK_START.md
+* Owner: Moko Consulting
+* Version: 03.06.03
+* Status: Active
+* Effective Date: 2026-01-30
+* Classification: Public Open Source Documentation
+
+## Revision History
+
+| Date | Change Summary | Author |
+| ---------- | ----------------------------------------------------- | --------------- |
+| 2026-01-30 | Updated metadata to MokoStandards format | GitHub Copilot |
+| 2025-01-04 | Initial quick start guide created | GitHub Copilot |
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..676335c
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,188 @@
+
+
+# MokoOnyx Documentation
+
+This directory contains comprehensive documentation for the MokoOnyx Joomla template.
+
+## Documentation Overview
+
+### Developer Documentation
+
+* **[Quick Start Guide](QUICK_START.md)** - Get up and running in 5 minutes
+ * Development environment setup
+ * Essential commands and workflows
+ * First-time contributor guide
+
+* **[Workflow Guide](WORKFLOW_GUIDE.md)** - Complete workflow reference
+ * Git branching strategy
+ * Development workflow
+ * Pull request guidelines
+
+* **[Release Process](RELEASE_PROCESS.md)** ⭐ - Complete release documentation
+ * Automated release workflow with GitHub Actions
+ * Manual release procedures
+ * Update server configuration
+ * Testing and rollback procedures
+ * Build scripts and tools
+
+* **[Joomla Development Guide](JOOMLA_DEVELOPMENT.md)** - Joomla-specific development
+ * Testing with Codeception
+ * PHP quality checks (PHPStan, PHPCS)
+ * Joomla extension packaging
+ * Multi-version testing
+
+* **[Manual Deployment Guide](MANUAL_DEPLOYMENT.md)** - Deploy src directory without building
+ * Understanding src vs. installed structure
+ * Manual deployment methods (copy, symlink)
+ * Troubleshooting language files and media
+ * Best practices for development deployments
+
+* **[CSS Variables Reference](CSS_VARIABLES.md)** - Complete CSS customization guide
+ * All available CSS variables
+ * Custom color palette creation
+ * Usage examples and tips
+ * Light and dark mode theming
+
+* **[Module & Component Overrides](MODULE_OVERRIDES.md)** - Mobile-responsive overrides guide
+ * 16 module overrides + 12 component overrides
+ * VirtueMart, Community Builder, JEM, Kunena, industry extensions
+ * Mobile-first responsive design patterns
+ * Accessibility features and customization
+
+* **[Override Philosophy](OVERRIDE_PHILOSOPHY.md)** ⭐ - Alternative layouts, not replacements
+ * Why overrides use `mobile.php` naming instead of `default.php`
+ * How to activate alternative layouts in Joomla
+ * Benefits of non-replacing overrides
+ * Developer guidelines and best practices
+
+* **[Roadmap](ROADMAP.md)** - Version-specific roadmap
+ * Current features (v03.07.00)
+ * Feature evolution timeline
+ * Planned enhancements
+ * Development priorities
+
+### User Documentation
+
+For end-user documentation, installation instructions, and feature guides, see the main [README.md](../README.md) in the repository root.
+
+## Project Structure
+
+```
+moko-cassiopeia/
+├── docs/ # Documentation (you are here)
+│ ├── README.md # This file - documentation index
+│ ├── QUICK_START.md # Quick start guide for developers
+│ ├── WORKFLOW_GUIDE.md # Development workflow guide
+│ ├── JOOMLA_DEVELOPMENT.md # Joomla-specific development guide
+│ ├── CSS_VARIABLES.md # CSS variables reference
+│ ├── MODULE_OVERRIDES.md # Module & component overrides guide
+│ └── ROADMAP.md # Version-specific roadmap
+├── src/ # Template source code (Joomla template root)
+│ ├── component.php # Component template
+│ ├── index.php # Main template file
+│ ├── offline.php # Offline template
+│ ├── error.php # Error page template
+│ ├── templateDetails.xml # Template manifest
+│ ├── html/ # Module & component overrides (16 modules, 12 components)
+│ ├── media/ # Assets (CSS, JS, images, fonts)
+│ │ ├── css/ # Stylesheets
+│ │ │ └── colors/ # Color schemes
+│ │ │ ├── light/ # Light mode color files (colors_standard.css)
+│ │ │ └── dark/ # Dark mode color files (colors_standard.css)
+│ │ ├── js/ # JavaScript files
+│ │ ├── images/ # Image assets
+│ │ └── fonts/ # Font files
+│ ├── language/ # Frontend language files
+│ │ ├── en-GB/ # English (UK) translations
+│ │ └── en-US/ # English (US) translations
+│ └── administrator/ # Backend files
+│ └── language/ # Backend language files
+│ ├── en-GB/ # English (UK) system translations
+│ └── en-US/ # English (US) system translations
+├── templates/ # Reserved for future template files
+│ └── README.md # Templates directory guide
+├── scripts/ # Build and utility scripts
+├── tests/ # Automated tests
+└── .github/ # GitHub configuration and workflows
+```
+
+## Contributing
+
+Before contributing, please read:
+
+1. **[CONTRIBUTING.md](../CONTRIBUTING.md)** - Contribution guidelines and standards
+2. **[CODE_OF_CONDUCT.md](../CODE_OF_CONDUCT.md)** - Community standards and expectations
+3. **[SECURITY.md](../SECURITY.md)** - Security policy and reporting procedures
+
+## Standards Compliance
+
+This project adheres to [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards) for:
+
+* Coding standards and formatting
+* Documentation requirements
+* Git workflow and branching
+* CI/CD pipeline configuration
+* Security scanning and dependency management
+
+## Additional Resources
+
+* **Repository**: [https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+* **Issue Tracker**: [GitHub Issues](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/issues)
+* **Changelog**: [CHANGELOG.md](../CHANGELOG.md)
+* **License**: [GPL-3.0-or-later](../LICENSE)
+
+## Support
+
+* **Email**: hello@mokoconsulting.tech
+* **Website**: https://mokoconsulting.tech/support/joomla-cms/moko-cassiopeia-roadmap
+
+---
+
+## Metadata
+
+* Document: docs/README.md
+* Repository: [https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+* Path: /docs/README.md
+* Owner: Moko Consulting
+* Version: 03.07.00
+* Status: Active
+* Effective Date: 2026-01-30
+* Classification: Public Open Source Documentation
+
+## Revision History
+
+| Date | Change Summary | Author |
+| ---------- | ----------------------------------------------------- | --------------- |
+| 2026-02-22 | Added MODULE_OVERRIDES.md reference, updated version to 03.07.00 | GitHub Copilot |
+| 2026-01-30 | Added CSS Variables reference, updated version to 03.06.03 | GitHub Copilot |
+| 2026-01-09 | Initial documentation index created for MokoStandards compliance. | GitHub Copilot |
+| 2026-01-27 | Updated with roadmap link and version to 03.05.01. | GitHub Copilot |
diff --git a/docs/RELEASE_PROCESS.md b/docs/RELEASE_PROCESS.md
new file mode 100644
index 0000000..d0daa66
--- /dev/null
+++ b/docs/RELEASE_PROCESS.md
@@ -0,0 +1,638 @@
+
+
+# Release Process — MokoOnyx
+
+This document describes the complete release process for MokoOnyx Joomla template, including automated workflows and manual procedures.
+
+## Table of Contents
+
+1. [Overview](#overview)
+2. [Release Types](#release-types)
+3. [Automated Release Process](#automated-release-process)
+4. [Manual Release Process](#manual-release-process)
+5. [Update Server Configuration](#update-server-configuration)
+6. [Testing Releases](#testing-releases)
+7. [Rollback Procedures](#rollback-procedures)
+8. [Troubleshooting](#troubleshooting)
+
+---
+
+## Overview
+
+MokoOnyx uses an automated release system powered by GitHub Actions. The system:
+
+- **Builds** installation packages automatically
+- **Generates** checksums for security verification
+- **Creates** GitHub Releases with downloadable artifacts
+- **Updates** the Joomla update server (`updates.xml`) automatically
+- **Validates** package integrity with SHA-256 hashes
+
+### Key Components
+
+1. **Release Workflow** (`.github/workflows/release.yml`): Builds and publishes releases
+2. **Auto-Update SHA** (`.github/workflows/auto-update-sha.yml`): Updates `updates.xml` after release
+3. **Build Script** (`scripts/build-release.sh`): Local development builds
+4. **Update Server** (`updates.xml`): Joomla update server manifest
+
+---
+
+## Release Types
+
+### Patch Release (Third Digit)
+
+**Format**: `XX.XX.XX` → `XX.XX.XX+1` (e.g., `03.08.03` → `03.08.04`)
+
+**When to use**:
+- Bug fixes
+- Security patches
+- Documentation updates
+- Minor CSS/styling tweaks
+- No breaking changes
+
+**Example**: `03.08.03` → `03.08.04`
+
+### Minor Release (Second Digit)
+
+**Format**: `XX.XX.00` → `XX.XX+1.00` (e.g., `03.08.03` → `03.09.00`)
+
+**When to use**:
+- New features
+- New module/component overrides
+- Significant styling changes
+- Backward-compatible changes
+
+**Example**: `03.08.03` → `03.09.00`
+
+### Major Release (First Digit)
+
+**Format**: `XX.00.00` → `XX+1.00.00` (e.g., `03.08.03` → `04.00.00`)
+
+**When to use**:
+- Breaking changes
+- Major architecture changes
+- Joomla version upgrades
+- Complete redesigns
+
+**Example**: `03.08.03` → `04.00.00`
+
+---
+
+## Automated Release Process
+
+**Recommended for most releases**
+
+### Prerequisites
+
+- [ ] All changes merged to `main` branch
+- [ ] Tests passing
+- [ ] Documentation updated
+- [ ] CHANGELOG.md updated
+- [ ] Local testing completed
+
+### Step 1: Prepare Release Branch
+
+```bash
+# Create release branch
+git checkout main
+git pull
+git checkout -b release/03.08.04
+
+# Update version in templateDetails.xml
+# Edit: src/templateDetails.xml
+# Change: 03.08.03
+# To: 03.08.04
+
+# Update CHANGELOG.md
+# Add new section:
+## [03.08.04] - 2026-02-27
+
+### Added
+- Feature descriptions
+
+### Fixed
+- Bug fix descriptions
+
+### Changed
+- Change descriptions
+
+# Commit changes
+git add src/templateDetails.xml CHANGELOG.md
+git commit -m "chore: Prepare release 03.08.04"
+git push origin release/03.08.04
+```
+
+### Step 2: Create Pull Request
+
+1. Go to GitHub repository
+2. Click "Pull requests" → "New pull request"
+3. Base: `main`, Compare: `release/03.08.04`
+4. Title: `Release 03.08.04`
+5. Description: Copy relevant CHANGELOG entries
+6. Create pull request
+7. Review and merge
+
+### Step 3: Create and Push Tag
+
+```bash
+# Switch to main and pull changes
+git checkout main
+git pull
+
+# Create tag
+git tag 03.08.04
+
+# Push tag (triggers release workflow)
+git push origin 03.08.04
+```
+
+### Step 4: Monitor Automated Process
+
+1. **Go to GitHub Actions tab**
+2. **Watch "Create Release" workflow**:
+ - Builds package
+ - Generates checksums
+ - Creates GitHub Release
+ - Uploads artifacts
+
+3. **Watch "Auto-Update SHA Hash" workflow**:
+ - Downloads release package
+ - Calculates SHA-256 hash
+ - Updates `updates.xml`
+ - Commits to main branch
+
+### Step 5: Verify Release
+
+1. **Check GitHub Release**:
+ - Go to Releases tab
+ - Verify release `03.08.04` exists
+ - Download ZIP package
+ - Verify checksums match
+
+2. **Check updates.xml**:
+ ```bash
+ git pull
+ cat updates.xml
+ ```
+ - Verify version is `03.08.04`
+ - Verify download URL is correct
+ - Verify SHA-256 hash is present
+
+3. **Test Joomla Update**:
+ - Install previous version in Joomla
+ - Go to Extensions → Update
+ - Verify update is detected
+ - Perform update
+ - Verify template works correctly
+
+---
+
+## Manual Release Process
+
+**Use when automation fails or for local testing**
+
+### Step 1: Prepare Repository
+
+```bash
+# Update version numbers
+# Edit: src/templateDetails.xml
+# Edit: CHANGELOG.md
+
+# Commit changes
+git add src/templateDetails.xml CHANGELOG.md
+git commit -m "chore: Prepare release 03.08.04"
+git push
+```
+
+### Step 2: Build Package Locally
+
+```bash
+# Run build script
+./scripts/build-release.sh 03.08.04
+
+# Output will be in build/ directory:
+# - mokoonyx-src-03.08.04.zip
+# - mokoonyx-src-03.08.04.zip.sha256
+# - mokoonyx-src-03.08.04.zip.md5
+```
+
+### Step 3: Test Package
+
+```bash
+# Install in Joomla test environment
+# Extensions → Manage → Install → Upload Package File
+# Select: build/mokoonyx-src-03.08.04.zip
+
+# Test all features:
+# - Template displays correctly
+# - Module overrides work
+# - Alternative layouts selectable
+# - Dark mode works
+# - No JavaScript errors
+```
+
+### Step 4: Create GitHub Release
+
+1. **Go to GitHub Releases**
+2. **Click "Create a new release"**
+3. **Tag**: `03.08.04` (create new tag)
+4. **Release title**: `Release 03.08.04`
+5. **Description**: Copy from CHANGELOG.md
+6. **Upload files**:
+ - `mokoonyx-src-03.08.04.zip`
+ - `mokoonyx-src-03.08.04.zip.sha256`
+ - `mokoonyx-src-03.08.04.zip.md5`
+7. **Publish release**
+
+### Step 5: Update updates.xml Manually
+
+```bash
+# Extract SHA-256 hash
+cat build/mokoonyx-src-03.08.04.zip.sha256
+# Example output: a1b2c3d4e5f6...
+
+# Edit updates.xml
+# Update 03.08.04
+# Update 2026-02-27
+# Update https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/03.08.04/mokoonyx-src-03.08.04.zip
+# Update sha256:a1b2c3d4e5f6...
+
+# Commit and push
+git add updates.xml
+git commit -m "chore: Update updates.xml for release 03.08.04"
+git push
+```
+
+---
+
+## Update Server Configuration
+
+### updates.xml Structure
+
+```xml
+
+
+ MokoOnyx
+ Moko Consulting's site template based on Cassiopeia.
+ mokoonyx
+ template
+ site
+
+ 03.08.04
+ 2026-02-27
+ Jonathan Miller || Moko Consulting
+ hello@mokoconsulting.tech
+ (C)GNU General Public License Version 3 - 2026 Moko Consulting
+
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
+
+
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/03.08.04/mokoonyx-src-03.08.04.zip
+ sha256:a1b2c3d4e5f6...
+
+
+
+ stable
+
+
+ Moko Consulting
+ https://www.mokoconsulting.tech
+
+
+
+
+```
+
+### Hosting Update Server
+
+The `updates.xml` file is hosted directly on GitHub:
+
+**URL**: `https://raw.githubusercontent.com/mokoconsulting-tech/MokoOnyx/main/updates.xml`
+
+This URL is configured in `src/templateDetails.xml`:
+
+```xml
+
+
+ https://raw.githubusercontent.com/mokoconsulting-tech/MokoOnyx/main/updates.xml
+
+
+```
+
+---
+
+## Testing Releases
+
+### Pre-Release Testing
+
+```bash
+# 1. Build package locally
+./scripts/build-release.sh
+
+# 2. Set up Joomla test environment
+# - Clean Joomla 5.x installation
+# - Previous MokoOnyx version installed
+
+# 3. Test current version features
+# - All module overrides
+# - Alternative layouts
+# - Dark mode toggle
+# - Responsive behavior
+
+# 4. Install new package
+# Extensions → Manage → Install → Upload Package
+
+# 5. Verify upgrade process
+# - No errors during installation
+# - Settings preserved
+# - Custom modifications retained
+
+# 6. Test new features
+# - New functionality works
+# - Bug fixes applied
+# - No regressions
+```
+
+### Update Server Testing
+
+```bash
+# 1. Install previous version in Joomla
+# 2. Go to: Extensions → Update
+# 3. Click "Find Updates"
+# 4. Verify update shows: "MokoOnyx 03.08.04"
+# 5. Click "Update"
+# 6. Verify successful update
+# 7. Test template functionality
+```
+
+### Checklist
+
+- [ ] Package installs without errors
+- [ ] Template activates correctly
+- [ ] All module overrides work
+- [ ] Alternative layouts selectable
+- [ ] Dark mode functions
+- [ ] Responsive on mobile/tablet/desktop
+- [ ] No JavaScript console errors
+- [ ] No PHP errors in Joomla logs
+- [ ] Update server detects new version
+- [ ] Update process completes successfully
+
+---
+
+## Rollback Procedures
+
+### Rollback Release
+
+If a release has critical issues:
+
+1. **Delete GitHub Release**:
+ - Go to Releases
+ - Click release to delete
+ - Click "Delete"
+ - Confirm deletion
+
+2. **Delete Git Tag**:
+ ```bash
+ # Delete local tag
+ git tag -d 03.08.04
+
+ # Delete remote tag
+ git push --delete origin 03.08.04
+ ```
+
+3. **Revert updates.xml**:
+ ```bash
+ # Revert to previous version
+ git revert
+ git push
+ ```
+
+4. **Notify Users**:
+ - Create GitHub issue explaining the problem
+ - Pin the issue
+ - Provide rollback instructions for users
+
+### User Rollback Instructions
+
+For users who installed the problematic version:
+
+1. **Download previous version** from GitHub Releases
+2. **Uninstall current version**:
+ - Extensions → Manage → Manage
+ - Find MokoOnyx
+ - Click "Uninstall"
+3. **Install previous version**:
+ - Extensions → Manage → Install
+ - Upload previous version ZIP
+4. **Verify functionality**
+
+---
+
+## Troubleshooting
+
+### Release Workflow Fails
+
+**Problem**: Build fails with "rsync: command not found"
+
+**Solution**: The GitHub Actions runner always has rsync installed. If this occurs, check the workflow file syntax.
+
+**Problem**: ZIP creation fails
+
+**Solution**: Check that `src/` and `src/media/` directories exist and contain files.
+
+**Problem**: Version update fails
+
+**Solution**: Verify `sed` commands in workflow match actual XML structure.
+
+### Auto-Update SHA Fails
+
+**Problem**: Cannot download release package
+
+**Solution**:
+- Verify release was published (not draft)
+- Check package naming: `mokoonyx-src-{version}.zip`
+- Verify release tag format
+
+**Problem**: SHA-256 hash mismatch
+
+**Solution**:
+- Package may have been modified after calculation
+- Re-run the workflow manually
+- Verify package integrity
+
+**Problem**: Commit fails
+
+**Solution**:
+- Check workflow has write permissions
+- Verify no branch protection rules blocking bot commits
+
+### Manual Build Issues
+
+**Problem**: `./scripts/build-release.sh: Permission denied`
+
+**Solution**:
+```bash
+chmod +x scripts/build-release.sh
+./scripts/build-release.sh
+```
+
+**Problem**: Build directory exists
+
+**Solution**:
+```bash
+rm -rf build/
+./scripts/build-release.sh
+```
+
+### Update Server Issues
+
+**Problem**: Joomla doesn't detect update
+
+**Solution**:
+1. Check `updates.xml` is accessible:
+ ```bash
+ curl https://raw.githubusercontent.com/mokoconsulting-tech/MokoOnyx/main/updates.xml
+ ```
+2. Verify version number is higher than installed version
+3. Clear Joomla cache: System → Clear Cache
+4. Check update URL in templateDetails.xml
+
+**Problem**: Update fails with "Invalid package"
+
+**Solution**:
+- Verify SHA-256 hash matches
+- Re-download package and check integrity
+- Verify package structure is correct
+
+---
+
+## Best Practices
+
+### Version Numbering
+
+- **Always increment** version numbers sequentially
+- **Never reuse** version numbers
+- **Use consistent** format: `XX.XX.XX`
+
+### Changelog
+
+- **Update before** release
+- **Include all changes** since last version
+- **Categorize** changes: Added, Changed, Fixed, Removed
+- **Write clear descriptions** for users
+
+### Testing
+
+- **Test locally** before pushing tag
+- **Test update process** from previous version
+- **Test on clean** Joomla installation
+- **Test different** configurations
+
+### Communication
+
+- **Announce releases** on GitHub Discussions
+- **Document breaking changes** clearly
+- **Provide migration guides** for major changes
+- **Respond promptly** to issue reports
+
+---
+
+## Quick Reference
+
+### Automated Release Commands
+
+```bash
+# 1. Create release branch
+git checkout -b release/03.08.04
+
+# 2. Update version and CHANGELOG
+# (edit files)
+
+# 3. Commit and push
+git add .
+git commit -m "chore: Prepare release 03.08.04"
+git push origin release/03.08.04
+
+# 4. Create and merge PR (via GitHub UI)
+
+# 5. Create and push tag
+git checkout main
+git pull
+git tag 03.08.04
+git push origin 03.08.04
+
+# 6. Wait for automation to complete
+```
+
+### Manual Release Commands
+
+```bash
+# Build locally
+./scripts/build-release.sh 03.08.04
+
+# Test installation
+# (manual Joomla testing)
+
+# Create release on GitHub
+# (via GitHub UI)
+
+# Update updates.xml
+# (edit file with SHA-256)
+git add updates.xml
+git commit -m "chore: Update updates.xml for 03.08.04"
+git push
+```
+
+---
+
+## Related Documentation
+
+- **Build Scripts**: [scripts/README.md](../scripts/README.md)
+- **Workflow Guide**: [WORKFLOW_GUIDE.md](WORKFLOW_GUIDE.md)
+- **Contributing**: [CONTRIBUTING.md](../CONTRIBUTING.md)
+- **Changelog**: [CHANGELOG.md](../CHANGELOG.md)
+
+---
+
+## Support
+
+- **Issues**: [GitHub Issues](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/issues)
+- **Discussions**: [GitHub Discussions](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/discussions)
+- **Email**: hello@mokoconsulting.tech
+
+---
+
+## License
+
+Copyright (C) 2026 Moko Consulting
+
+This documentation is licensed under GPL-3.0-or-later.
diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md
new file mode 100644
index 0000000..0221b3f
--- /dev/null
+++ b/docs/ROADMAP.md
@@ -0,0 +1,917 @@
+
+
+# MokoOnyx Roadmap (VERSION: 03.09.03)
+
+This document provides a comprehensive, version-specific roadmap for the MokoOnyx Joomla template, tracking feature evolution, current capabilities, and planned enhancements.
+
+## Table of Contents
+
+- [Version Timeline](#version-timeline)
+ - [Past Releases](#past-releases)
+ - [Future Roadmap (5-Year Plan)](#future-roadmap-5-year-plan)
+- [Current Release (v03.06.03)](#current-release-v030603)
+- [Implemented Features](#implemented-features)
+- [Planned Features](#planned-features)
+- [Development Priorities](#development-priorities)
+- [Long-term Vision](#long-term-vision)
+- [External Resources](#external-resources)
+
+---
+
+## Version Timeline
+
+### Past Releases
+
+### v03.05.01 (2026-01-09) - Standards & Security
+**Status**: Released (CHANGELOG entry exists, code files pending version update)
+
+**Added**:
+- Dependency review workflow for vulnerability scanning
+- Standards compliance workflow for MokoStandards validation
+- Dependabot configuration for automated security updates
+- Documentation index (`docs/README.md`)
+
+**Changed**:
+- Removed custom CodeQL workflow (using GitHub's default setup)
+- Enforced repository compliance with MokoStandards
+- Improved security posture with automated scanning
+
+### v03.06.00 (2026-01-28) - Version Update
+**Status**: Current Release (in code)
+
+**Changed**:
+- Updated version to 03.06.00 across all files
+
+### v03.05.00 (2026-01-04) - Workflow & Governance
+**Status**: Mentioned in CHANGELOG (v03.05.00)
+
+**Added**:
+- `.github/workflows` directory structure
+- CODE_OF_CONDUCT.md from MokoStandards
+- CONTRIBUTING.md from MokoStandards
+
+**Changed**:
+- TODO items to be split to separate file (tracked)
+
+### v03.01.00 (2025-12-16) - CI/CD Foundation
+**Added**:
+- Initial GitHub Actions workflows
+
+### v03.00.00 (2025-12-09) - Font Awesome 7 Upgrade
+**Updated**:
+- Copyright headers to MokoCodingDefaults standards
+- Fixed color style injection in `index.php`
+- Upgraded Font Awesome 6 to Font Awesome 7 Free
+- Added Font Awesome 7 Free style fallback
+
+**Removed**:
+- Deprecated CODE_OF_CONDUCT.md
+- Deprecated CONTRIBUTING.md
+
+### v02.01.05 (2025-09-04) - CSS Refinement
+**Fixed**:
+- Removed vmbasic.css
+- Repaired template.css and colors_standard.css
+
+### v02.00.00 (2025-08-30) - Dark Mode & TOC
+**Major Features**:
+- **Dark Mode Toggle System**
+ - Frontend toggle switch with localStorage persistence
+ - Admin-configurable default mode
+ - CSS rules for light/dark themes
+ - JavaScript-powered mode switching
+
+- **Enhanced Template Parameters**
+ - Logo parameter support
+ - GTM container ID configuration
+ - Dark mode defaults in settings
+ - Updated metadata and copyright headers
+
+- **Expanded Table of Contents**
+ - Automatic TOC injection
+ - User-selectable placement (`toc-left` or `toc-right`)
+ - Article options integration
+
+**Improvements**:
+- Cleaned up `index.php` (removed duplicate skip-to-content calls)
+- Consolidated JavaScript asset loading
+- Streamlined CSS for toggle switch
+- Accessibility refinements (typography, color contrast)
+- Fixed missing logo parameter in header
+- Corrected stylesheet inconsistencies
+- Patched redundant script includes
+
+### v01.00.00 - Initial Public Release
+**Core Features**:
+- Font Awesome 6 integration
+- Bootstrap 5 helpers and utilities
+- Automatic Table of Contents (TOC) utility
+- Moko Expansions: Google Tag Manager / GA4 hooks
+- Built on Joomla's Cassiopeia template
+
+---
+
+### Future Roadmap (5-Year Plan)
+
+The following versions represent our planned annual major releases, each building upon the previous version's foundation.
+
+#### v04.00.00 (Q4 2027) - Enhanced Accessibility & Performance
+**Status**: Planned
+**Target Release**: December 2027
+
+**Major Template Features**:
+- **WCAG 2.1 AA Compliance**
+ - Full accessibility audit and remediation
+ - High-contrast theme options
+ - Screen reader optimizations
+ - Keyboard navigation enhancements
+ - ARIA landmark improvements
+ - Skip navigation enhancements
+
+- **Template Performance Optimizations**
+ - Critical CSS inlining for faster first paint
+ - Lazy loading for images and below-fold content
+ - WebP image support with automatic fallbacks
+ - Advanced asset bundling and minification
+ - Template asset caching (CSS/JS bundles)
+
+- **Enhanced Layout System**
+ - Additional responsive grid layouts
+ - Flexible module position system
+ - Column layout presets (2-col, 3-col, 4-col variations)
+ - Grid/masonry article layouts
+ - Sticky sidebar options
+
+- **Typography Enhancements**
+ - Advanced typography controls in template settings
+ - Additional font pairing presets
+ - Custom font upload support
+ - Line height and letter spacing controls
+ - Responsive typography scaling
+
+- **Developer Experience**
+ - Development mode enablement (unminified assets, debug output)
+ - Live reload during development
+ - Enhanced error logging and diagnostics
+ - Template debugging tools
+ - Style guide generator
+
+- **Content Display Features**
+ - Soft offline mode (category-based access during maintenance)
+ - Enhanced article layouts (grid, masonry, timeline)
+ - Image caption styling options
+ - Quote block styling variations
+ - Enhanced breadcrumb customization
+
+**Template Infrastructure**:
+- Expanded template parameter validation
+- Enhanced template override detection
+- Automated template compatibility testing
+- Template performance profiling tools
+
+---
+
+#### v05.00.00 (Q4 2028) - Advanced Layouts & Template Customization
+**Status**: Planned
+**Target Release**: December 2028
+
+**Major Template Features**:
+- **Enhanced Layout Builder**
+ - Template-based page layout variations
+ - Configurable layout options via template parameters
+ - Layout presets library (blog, portfolio, business, magazine)
+ - Module position layout manager
+ - Visual layout preview in admin
+
+- **Advanced Styling System**
+ - Extended color palette management (unlimited custom palettes)
+ - CSS variable editor in template settings
+ - Style presets for different site types
+ - Border radius and spacing controls
+ - Box shadow and effect controls
+
+- **Template Component Enhancements**
+ - Enhanced menu styling options (mega menu support)
+ - Advanced header variations (transparent, sticky, minimal)
+ - Footer layout options (column variations, widgets)
+ - Sidebar styling and behavior options
+ - Hero section templates and variations
+
+- **Content Display Options**
+ - Article intro/full text display controls
+ - Category layout variations (grid, list, masonry, cards)
+ - Featured content sections
+ - Related articles display options
+ - Author bio box styling
+
+- **Responsive Design Improvements**
+ - Mobile-first navigation patterns
+ - Tablet-specific layout controls
+ - Responsive image sizing options
+ - Mobile header variations
+ - Touch-friendly interface elements
+
+- **Template Integration Features**
+ - Enhanced VirtueMart template overrides
+ - Contact form styling variations
+ - Search result layout options
+ - Error page customization
+ - Archive page templates
+
+**Template Infrastructure**:
+- Joomla 6.x template compatibility (if released)
+- PHP 8.2+ support
+- Template child theme support
+- Template preset import/export functionality
+
+---
+
+#### v06.00.00 (Q4 2029) - Template Extensions & Advanced Features
+**Status**: Planned
+**Target Release**: December 2029
+
+**Major Template Features**:
+- **Template Marketplace & Extensions**
+ - Template addon system for modular features
+ - Community-contributed template extensions
+ - Template preset marketplace
+ - Style pack distribution system
+ - Template component library
+
+- **Advanced Module System**
+ - Custom module chrome options
+ - Module animation effects
+ - Module visibility controls (scroll, time-based)
+ - Module group management
+ - Module style inheritance
+
+- **Enhanced Media Handling**
+ - Background image options per page/section
+ - Image overlay controls
+ - Parallax scrolling effects
+ - Video background support
+ - Gallery template variations
+
+- **Template Branding Options**
+ - Multiple logo upload (standard, retina, mobile)
+ - Favicon and app icon management
+ - Custom loading screen/animations
+ - Watermark options
+ - Brand color scheme generator
+
+- **Advanced Header/Footer**
+ - Multiple header layout presets
+ - Sticky header variations and behaviors
+ - Header transparency controls
+ - Footer widget areas expansion
+ - Floating action buttons
+
+- **Content Enhancement Features**
+ - Reading progress indicator
+ - Social sharing buttons (template-integrated)
+ - Print-friendly styles
+ - Reading time estimation display
+ - Content table enhancements
+
+- **Template SEO Features**
+ - Schema markup templates for common types
+ - Open Graph tag management
+ - Twitter Card support
+ - Breadcrumb schema integration
+ - Meta tag template controls
+
+**Template Infrastructure**:
+- Template versioning system
+- Template backup/restore functionality
+- Template A/B testing support
+- Multi-language template variations
+- Template documentation generator
+
+---
+
+#### v07.00.00 (Q4 2030) - Modern Template Standards & Enhancements
+**Status**: Planned
+**Target Release**: December 2030
+
+**Major Template Features**:
+- **Modern CSS Features**
+ - CSS Grid layout system integration
+ - CSS Container Queries support
+ - CSS Cascade Layers implementation (layered style priority system)
+ - Custom properties (CSS variables) UI
+ - Modern filter and backdrop effects
+
+- **Progressive Template Features**
+ - Offline-capable template assets
+ - Service worker template integration
+ - App manifest generation
+ - Install to home screen support
+ - Template asset preloading strategies
+
+- **Animation & Interaction**
+ - Scroll-triggered animations
+ - Hover effect library
+ - Page transition effects
+ - Micro-interactions for UI elements
+ - Loading animation options
+
+- **Advanced Responsive Features**
+ - Container-based responsive design
+ - Element visibility by viewport
+ - Responsive navigation patterns library
+ - Mobile-optimized interactions
+ - Adaptive image loading
+
+- **Template Accessibility Features**
+ - Focus indicators customization
+ - Reduced motion preferences support
+ - High contrast mode automation
+ - Keyboard navigation patterns
+ - ARIA live regions for dynamic content
+
+- **Content Presentation**
+ - Advanced blockquote styles
+ - Code snippet highlighting themes
+ - Table styling variations
+ - List styling options
+ - Custom content block templates
+
+- **Template Performance**
+ - Resource hints (preconnect, prefetch)
+ - Optimal asset delivery strategies
+ - Image format optimization (AVIF support)
+ - Font loading optimization
+ - Template metrics dashboard
+
+**Template Infrastructure**:
+- Template pattern library
+- Design token system
+- Template component documentation
+- Automated template testing suite
+- Template performance monitoring
+
+---
+
+#### v08.00.00 (Q4 2031) - Next-Generation Template Features
+**Status**: Conceptual
+**Target Release**: December 2031
+
+**Major Template Features**:
+- **Advanced Layout Systems**
+ - Subgrid support for complex layouts
+ - Multi-column layout variations
+ - Asymmetric grid systems
+ - Dynamic layout switching
+ - Layout constraint system
+
+- **Enhanced Visual Customization**
+ - Real-time style editor
+ - Template style variations manager
+ - Custom CSS injection with validation
+ - Style inheritance and override system
+ - Visual design tokens editor
+
+- **Template Component Library**
+ - Comprehensive UI component set
+ - Reusable template blocks
+ - Component variation system
+ - Template snippet library
+ - Pattern library integration
+
+- **Advanced Typography System**
+ - Variable font support
+ - Advanced typographic scales
+ - Font pairing recommendations
+ - Fluid typography system
+ - Custom font fallback chains
+
+- **Template Integration Features**
+ - Enhanced component overrides
+ - Template hooks system
+ - Event-based template modifications
+ - Custom field rendering templates
+ - Module position API enhancements
+
+- **Responsive & Adaptive Design**
+ - Advanced breakpoint management
+ - Element-specific responsive controls
+ - Adaptive images with art direction
+ - Responsive typography system
+ - Context-aware component rendering
+
+- **Template Ecosystem**
+ - Child template framework
+ - Template derivative system
+ - Community template marketplace
+ - Template rating and review system
+ - Professional template support network
+
+- **Template Quality & Maintenance**
+ - Automated accessibility testing
+ - Template performance auditing
+ - Code quality monitoring
+ - Update notification system
+ - Template health dashboard
+
+**Template Infrastructure**:
+- Template API for extensibility
+- Template package manager
+- Template development CLI tools
+- Template migration utilities
+- Comprehensive template documentation system
+
+---
+
+## Current Release (v03.06.03)
+
+### System Requirements
+- **Joomla**: 4.4.x or 5.x
+- **PHP**: 8.0+
+- **Database**: MySQL/MariaDB compatible
+
+### Architecture
+- **Base Template**: Joomla Cassiopeia
+- **Enhancement Layer**: Non-invasive overrides
+- **Asset Management**: Joomla Web Asset Manager (WAM)
+- **Frontend Framework**: Bootstrap 5
+- **Icon Library**: Font Awesome 7 Free
+
+---
+
+## Implemented Features
+
+### 🎨 Theming & Visual Design
+
+#### Color Palette System
+- **3 Built-in Palettes**: Standard, Alternative, Custom
+- **Dual Mode Support**: Separate light and dark configurations
+- **Custom Palettes**: User-definable via `colors_custom.css`
+- **Location**: `src/media/css/colors/{light|dark}/`
+
+#### Dark Mode System
+- **Toggle Controls**: Switch (Light↔Dark) or Radios (Light/Dark/System)
+- **Default Mode**: Admin-configurable (system, light, or dark)
+- **Persistence**: localStorage for user preferences
+- **Auto-Detection**: Optional system preference detection
+- **Meta Tags**: `color-scheme` and `theme-color` support
+- **ARIA Bridge**: Bootstrap ARIA compatibility
+
+#### Typography
+- **Font Schemes**:
+ - Local: Roboto
+ - Web (Google Fonts): Fira Sans, Roboto + Noto Sans
+- **Admin-Configurable**: Template settings dropdown
+
+#### Branding
+- **Logo Support**: Custom logo upload
+- **Site Title**: Text-based branding option
+- **Site Description**: Tagline/subtitle field
+- **Font Awesome Kit**: Optional custom kit integration
+
+### 📐 Layout & Structure
+
+#### Module Positions (23 Total)
+**Header Area**:
+- topbar, below-topbar, below-logo, menu, search, banner
+
+**Content Area**:
+- top-a, top-b, main-top, main-bottom, breadcrumbs
+- sidebar-left, sidebar-right
+
+**Footer Area**:
+- bottom-a, bottom-b, footer-menu, footer
+
+**Special**:
+- debug, offline-header, offline, offline-footer
+- drawer-left, drawer-right
+
+#### Layout Options
+- **Container Type**: Fluid or Static
+- **Sticky Header**: Optional fixed navigation
+- **Back-to-Top Button**: Scrollable page support
+
+### 📝 Content Features
+
+#### Table of Contents (TOC)
+- **Automatic Generation**: From article headings
+- **Placement Options**: `toc-left` or `toc-right` layouts
+- **Article Integration**: Via Options → Layout dropdown
+- **Responsive**: Mobile-friendly sidebar placement
+
+#### Article Layouts
+- **Default**: Standard Cassiopeia layout
+- **TOC Variants**: Left-sidebar or right-sidebar TOC
+- **Custom Overrides**: Located in `html/com_content/article/`
+
+### 📊 Analytics & Tracking
+
+#### Google Tag Manager (GTM)
+- **Enable/Disable**: Admin toggle
+- **Container ID**: Template parameter field
+- **Implementation**: Head and body script injection
+- **GDPR-Ready**: Configurable consent defaults
+
+#### Google Analytics 4 (GA4)
+- **Enable/Disable**: Admin toggle
+- **Property ID**: Template parameter field
+- **Universal Analytics Fallback**: Legacy UA support
+- **Privacy-First**: Conditional loading based on settings
+
+### 🎛️ Customization & Developer Tools
+
+#### Custom Code Injection
+- **Head Start**: Custom HTML/JS before ``
+- **Head End**: Custom HTML/JS at end of ``
+- **Raw HTML**: Unfiltered code injection for advanced users
+
+#### Drawer System
+- **Left/Right Drawers**: Offcanvas menu areas
+- **Icon Customization**: Font Awesome icon selection
+- **Default Icons**:
+ - Left: `fa-solid fa-chevron-right`
+ - Right: `fa-solid fa-chevron-left`
+
+#### Asset Management
+- **Joomla WAM**: Complete asset registry in `joomla.asset.json`
+- **Development/Production Modes**: Minified and unminified assets
+- **Dependency Management**: Automatic script/style loading
+
+### 🏗️ Template Overrides
+
+#### Component Overrides
+**Content (com_content)**:
+- Article layouts (default, toc-left, toc-right)
+- Category layouts (blog, list)
+- Featured articles
+
+**Contact (com_contact)**:
+- Contact form layouts
+
+**Engage (com_engage)**:
+- Comment system integration
+
+#### Module Overrides
+**Menu (mod_menu)**:
+- Metis dropdown menu
+- Offcanvas navigation
+
+**VirtueMart**:
+- Product display (`mod_virtuemart_product`)
+- Shopping cart (`mod_virtuemart_cart`)
+- Manufacturer display (`mod_virtuemart_manufacturer`)
+- Category display (`mod_virtuemart_category`)
+- Currency selector (`mod_virtuemart_currencies`)
+
+**Other Modules**:
+- Custom HTML (`mod_custom`)
+- GABble social integration (`mod_gabble`)
+
+**Membership System (OS Membership)**:
+- Plan layouts (default, pricing tables)
+- Member management interfaces
+
+### 🔧 Configuration Parameters
+
+#### Theme Tab
+**General**:
+- `theme_enabled` - Enable/disable theme system
+- `theme_control_type` - Toggle UI type (switch/radios/none)
+- `theme_default_choice` - Default mode (system/light/dark)
+- `theme_auto_dark` - Auto-detect system preference
+- `theme_meta_color_scheme` - Inject `color-scheme` meta tag
+- `theme_meta_theme_color` - Inject `theme-color` meta tag
+- `theme_bridge_bs_aria` - Bootstrap ARIA compatibility
+
+**Variables & Palettes**:
+- `colorLightName` - Light mode color scheme
+- `colorDarkName` - Dark mode color scheme
+
+**Typography**:
+- `useFontScheme` - Font selection (local/web)
+
+**Branding & Icons**:
+- `brand` - Show/hide branding
+- `logoFile` - Logo upload path
+- `siteTitle` - Site title text
+- `siteDescription` - Site tagline
+- `fA6KitCode` - Font Awesome kit code
+
+**Header & Navigation**:
+- `stickyHeader` - Fixed navigation
+- `backTop` - Back-to-top button
+
+**Toggle UI**:
+- `theme_fab_enabled` - Floating action button for theme toggle
+- `theme_fab_pos` - FAB position (br/bl/tr/tl)
+
+#### Google Tab
+- `googletagmanager` - Enable GTM
+- `googletagmanagerid` - GTM container ID
+- `googleanalytics` - Enable GA4
+- `googleanalyticsid` - GA4 property ID
+
+#### Custom Code Tab
+- `custom_head_start` - Custom code at head start
+- `custom_head_end` - Custom code at head end
+
+#### Drawers Tab
+- `drawerLeftIcon` - Left drawer icon (Font Awesome class)
+- `drawerRightIcon` - Right drawer icon (Font Awesome class)
+
+#### Advanced Tab
+- `fluidContainer` - Container layout (static/fluid)
+
+### 🛠️ Development Tools
+
+#### Quality Assurance
+- **Codeception**: Automated testing framework
+- **PHPStan**: Static analysis (level 8+)
+- **PHPCS**: Code style validation (PSR-12)
+- **PHPCompatibility**: PHP 8.0+ compatibility checks
+
+#### CI/CD Workflows
+- **Dependency Review**: Vulnerability scanning
+- **Standards Compliance**: MokoStandards validation
+- **CodeQL**: Security analysis (GitHub default)
+- **Dependabot**: Automated dependency updates
+
+#### Documentation
+- **Quick Start**: 5-minute developer setup
+- **Workflow Guide**: Git strategy, branching, releases
+- **Joomla Development**: Testing, packaging, multi-version support
+
+---
+
+## Planned Features
+
+### 🚧 In Development
+
+#### Soft Offline Mode (v03.07.00 - Planned)
+**Status**: Planned for v03.07.00
+**Priority**: High
+**Description**: Keep selected categories accessible during site maintenance mode with persistent links to essential pages
+
+**Use Cases**:
+- Legal documents remain viewable during downtime
+- Policy pages accessible for compliance requirements
+- Terms of service always available to users
+- Privacy policy accessible at all times
+- Essential public information during maintenance
+
+**Technical Specifications**:
+- **Configuration Method**: Template parameters in `templateDetails.xml`
+- **Category Access**: Category IDs stored as comma-separated values
+- **Persistent Links**: Direct article/menu item links always visible
+- **Access Control**: Check in `offline.php` template file
+- **Content Rendering**: Use Joomla's content component to fetch articles
+- **Security**: Maintain proper access levels and permissions
+
+**Implementation Plan**:
+1. Add category selection field to template parameters
+2. Add persistent link configuration (Terms of Service, Privacy Policy, etc.)
+3. Modify `offline.php` to check for allowed categories
+4. Add persistent link display in offline mode header/footer
+5. Implement category content fetching during offline mode
+6. Add styling for offline mode category display and persistent links
+7. Test with various category and link configurations
+8. Document admin configuration steps
+
+**Configuration Interface**:
+- **Category Field Type**: Category multiselect in template settings
+ - **Label**: "Categories Accessible During Offline Mode"
+ - **Default**: None (all content hidden by default)
+- **Persistent Links**: Text fields for essential always-available links
+ - **Terms of Service URL**: Direct link to TOS article/page
+ - **Privacy Policy URL**: Direct link to privacy policy
+ - **Contact URL**: Optional contact page link
+ - **Custom Link 1-3**: Additional persistent links if needed
+- **Admin Path**: System → Site Templates → MokoOnyx → Advanced → Offline Mode Settings
+
+**Persistent Links Feature**:
+- **Display Location**: Footer of offline page
+- **Styling**: Clearly visible, accessible links
+- **Format**: "Terms of Service | Privacy Policy | Contact"
+- **Behavior**: Links bypass offline mode restrictions
+- **Validation**: Check if URLs are valid Joomla routes
+
+**Benefits**:
+- ✅ Compliance: Keep legal pages accessible
+- ✅ Transparency: Users can access essential information
+- ✅ Flexibility: Admin control over which categories remain visible
+- ✅ Security: Respects Joomla access levels
+- ✅ Legal Protection: Terms of Service always accessible
+- ✅ User Trust: Privacy policy always available
+
+**Milestone**: Target release v03.07.00 (Q2 2026)
+
+#### TODO Tracking System
+**Status**: Mentioned in CHANGELOG (v03.05.00)
+**Description**: Separate TODO tracking file
+**Purpose**: Centralized issue and feature tracking outside changelog
+
+### 🔮 Future Enhancements
+
+#### Development Mode (Commented Out)
+**Status**: Code exists but disabled
+**Location**: `templateDetails.xml` line 91
+**Description**: Comprehensive development mode toggle
+**Potential Features**:
+- Unminified asset loading
+- Debug output
+- Performance profiling
+- Template cache bypass
+
+#### Potential Features (Community Requested)
+*Note: These are conceptual and not yet officially planned*
+
+**Enhanced Accessibility**:
+- WCAG 2.1 AAA compliance mode
+- High-contrast themes
+- Screen reader optimizations
+- Keyboard navigation improvements
+
+**Template Layout Features**:
+- Advanced responsive grid layouts
+- Multiple column variations
+- Custom module position system
+- Layout preset library
+
+**Template Styling Features**:
+- Extended color palette management
+- Custom font upload support
+- Typography scale controls
+- Visual style editor
+
+---
+
+## Development Priorities
+
+### Immediate Focus (v03.x - 2026)
+1. **Bootstrap TOC Integration**: Complete and document v1.0.1 implementation ✅
+2. **Soft Offline Mode**: Implement category-based offline access (Target: v03.07.00)
+3. **TODO Tracking System**: Implement separate file for issue tracking
+4. **Security Updates**: Maintain Dependabot and CodeQL scans
+5. **Documentation**: Keep docs synchronized with features
+6. **Bug Fixes**: Address reported issues and edge cases
+
+### v04.00.00 Priorities (2027) - Template Foundation
+1. **WCAG 2.1 AA Compliance**: Full template accessibility audit and implementation
+2. **Template Performance**: Critical CSS, lazy loading, WebP support
+3. **Layout System**: Enhanced responsive grid and module positions
+4. **Development Mode**: Enable comprehensive template developer tools
+
+### v05.00.00 Priorities (2028) - Template Customization
+1. **Layout Builder**: Template-based page layout system
+2. **Styling System**: Extended color palettes and CSS variable management
+3. **Template Components**: Enhanced header, footer, and menu variations
+4. **Responsive Design**: Mobile-first navigation and layout improvements
+
+### v06.00.00 Priorities (2029) - Template Extensions
+1. **Template Marketplace**: Addon system and community extensions
+2. **Module System**: Advanced module chrome and animation options
+3. **Media Handling**: Background images, parallax, video backgrounds
+4. **Template SEO**: Schema markup templates and meta tag controls
+
+### v07.00.00+ Priorities (2030+) - Modern Standards
+1. **Modern CSS**: Grid, Container Queries, Cascade Layers
+2. **Progressive Template**: Offline-capable assets and PWA features
+3. **Animation System**: Scroll-triggered effects and micro-interactions
+4. **Template Performance**: Advanced optimization and monitoring
+
+---
+
+## Long-term Vision
+
+### Mission Statement
+MokoOnyx aims to be the **most developer-friendly, user-customizable, and standards-compliant Joomla template** while maintaining minimal core overrides for maximum upgrade compatibility.
+
+### Core Principles
+1. **Non-Invasive**: Minimal Cassiopeia overrides
+2. **Standards-First**: MokoStandards compliance
+3. **Accessibility**: WCAG 2.1 compliance
+4. **Performance**: Fast, optimized delivery
+5. **Developer Experience**: Clear docs, easy setup, powerful tools
+6. **Template-Focused**: Pure template features without complex external dependencies
+
+### 5-Year Strategic Roadmap (Template Features)
+
+#### 2027 (v04.00.00) - Accessibility & Performance
+- Achieve WCAG 2.1 AA compliance for all template elements
+- Implement critical template performance optimizations
+- Enhance template layout system with flexible grids
+- Enable comprehensive development mode for template developers
+
+#### 2028 (v05.00.00) - Layouts & Customization
+- Launch template-based layout builder system
+- Deploy extended styling and customization options
+- Enhance template component variations (headers, footers, menus)
+- Improve responsive design patterns for all devices
+
+#### 2029 (v06.00.00) - Extensions & Enhancements
+- Introduce template addon and extension system
+- Launch template preset marketplace
+- Deploy advanced module styling and animation features
+- Implement comprehensive template SEO controls
+
+#### 2030 (v07.00.00) - Modern Standards
+- Adopt modern CSS standards (Grid, Container Queries, Cascade Layers)
+- Implement progressive template features (PWA support)
+- Deploy advanced animation and interaction system
+- Enhance template performance monitoring and optimization
+
+#### 2031 (v08.00.00) - Next-Generation Template
+- Advanced layout systems with subgrid support
+- Comprehensive template component library
+- Enhanced visual customization tools
+- Template ecosystem with child themes and derivatives
+
+---
+
+## External Resources
+
+### Official Links
+- **Full Roadmap**: [https://mokoconsulting.tech/support/joomla-cms/mokoonyx-roadmap](https://mokoconsulting.tech/support/joomla-cms/mokoonyx-roadmap)
+- **Repository**: [https://git.mokoconsulting.tech/MokoConsulting/moko-cassiopeia](https://git.mokoconsulting.tech/MokoConsulting/moko-cassiopeia)
+- **Issue Tracker**: [GitHub Issues](https://git.mokoconsulting.tech/MokoConsulting/moko-cassiopeia/issues)
+- **Changelog**: [CHANGELOG.md](../CHANGELOG.md)
+
+### Community
+- **Email Support**: hello@mokoconsulting.tech
+- **Contributing**: [CONTRIBUTING.md](../CONTRIBUTING.md)
+- **Code of Conduct**: [CODE_OF_CONDUCT.md](../CODE_OF_CONDUCT.md)
+
+### Documentation
+- **Quick Start**: [docs/QUICK_START.md](./QUICK_START.md)
+- **Workflow Guide**: [docs/WORKFLOW_GUIDE.md](./WORKFLOW_GUIDE.md)
+- **Joomla Development**: [docs/JOOMLA_DEVELOPMENT.md](./JOOMLA_DEVELOPMENT.md)
+- **Main README**: [README.md](../README.md)
+
+---
+
+## Contributing to the Roadmap
+
+Have ideas for future features? We welcome community input!
+
+**How to Suggest Features**:
+1. Check the [GitHub Issues](https://git.mokoconsulting.tech/MokoConsulting/moko-cassiopeia/issues) for existing requests
+2. Open a new issue with the `enhancement` label
+3. Provide clear use cases and benefits
+4. Engage in community discussion
+
+**Feature Evaluation Criteria**:
+- Alignment with core principles
+- User demand and use cases
+- Technical feasibility
+- Maintenance burden
+- Performance impact
+- Security implications
+
+---
+
+## Metadata
+
+* Document: docs/ROADMAP.md
+* Repository: [https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+* Path: /docs/ROADMAP.md
+* Owner: Moko Consulting
+* Version: 03.06.03
+* Status: Active
+* Effective Date: 2026-01-30
+* Classification: Public Open Source Documentation
+
+## Revision History
+
+| Date | Change Summary | Author |
+| ---------- | ----------------------------------------------------- | --------------- |
+| 2026-01-27 | Initial version-specific roadmap generated from codebase scan. | GitHub Copilot |
+| 2026-01-27 | Added 5-year future roadmap with annual major version releases (v04-v08). | GitHub Copilot |
+| 2026-01-27 | Refocused roadmap to concentrate on template-oriented features only. | GitHub Copilot |
diff --git a/docs/WORKFLOW_GUIDE.md b/docs/WORKFLOW_GUIDE.md
new file mode 100644
index 0000000..38c787c
--- /dev/null
+++ b/docs/WORKFLOW_GUIDE.md
@@ -0,0 +1,459 @@
+# Workflow Guide - Moko Cassiopeia
+
+Quick reference guide for GitHub Actions workflows and common development tasks.
+
+## Table of Contents
+
+- [Overview](#overview)
+- [Workflow Quick Reference](#workflow-quick-reference)
+- [Common Development Tasks](#common-development-tasks)
+- [Troubleshooting](#troubleshooting)
+- [Best Practices](#best-practices)
+
+## Overview
+
+This repository uses GitHub Actions for continuous integration, testing, quality checks, and deployment. All workflows are located in `.github/workflows/`.
+
+### Workflow Execution Model
+
+```
+┌─────────────────┐
+│ Code Changes │
+└────────┬────────┘
+ │
+ ▼
+┌─────────────────┐
+│ CI Pipeline │ ← Validation, Testing, Quality
+└────────┬────────┘
+ │
+ ▼
+┌─────────────────┐
+│ Version Branch │ ← Create dev/X.Y.Z branch
+└────────┬────────┘
+ │
+ ▼
+┌─────────────────┐
+│ Release Pipeline│ ← dev → rc → version → main
+└────────┬────────┘
+ │
+ ▼
+┌─────────────────┐
+│ Distribution │ ← ZIP package + GitHub Release
+└─────────────────┘
+```
+
+## Workflow Quick Reference
+
+### Continuous Integration (ci.yml)
+
+**Trigger:** Automatic on push/PR to main, dev/*, rc/*, version/* branches
+
+**Purpose:** Validates code quality and repository structure
+
+**What it does:**
+- ✅ Validates Joomla manifest XML
+- ✅ Checks XML well-formedness
+- ✅ Validates GitHub Actions workflows
+- ✅ Runs PHP syntax checks
+- ✅ Checks for secrets in code
+- ✅ Validates license headers
+- ✅ Verifies version alignment
+
+**When to check:** After every commit
+
+**How to view results:**
+```bash
+# Via GitHub CLI
+gh run list --workflow=ci.yml --limit 5
+gh run view --log
+```
+
+### PHP Quality Checks (php_quality.yml)
+
+**Trigger:** Automatic on push/PR to main, dev/*, rc/*, version/* branches
+
+**Purpose:** Ensures PHP code quality and compatibility
+
+**What it does:**
+- 🔍 PHPStan static analysis (level 5)
+- 📏 PHP_CodeSniffer with PSR-12 standards
+- ✔️ PHP 8.0+ compatibility checks
+
+**Matrix:** PHP 8.0, 8.1, 8.2, 8.3
+
+**When to check:** Before committing PHP changes
+
+**How to run locally:**
+```bash
+# Install tools
+composer global require "squizlabs/php_codesniffer:^3.0" --with-all-dependencies
+composer global require "phpstan/phpstan:^1.0" --with-all-dependencies
+
+# Run checks
+phpcs --standard=phpcs.xml src/
+phpstan analyse --configuration=phpstan.neon
+```
+
+### Joomla Testing (joomla_testing.yml)
+
+**Trigger:** Automatic on push/PR to main, dev/*, rc/* branches
+
+**Purpose:** Tests template compatibility with Joomla versions
+
+**What it does:**
+- 📦 Downloads and installs Joomla (4.4, 5.0, 5.1)
+- 🔧 Installs template into Joomla
+- ✅ Validates template installation
+- 🧪 Runs Codeception tests
+
+**Matrix:** Joomla 4.4/5.0/5.1 × PHP 8.0/8.1/8.2/8.3
+
+**When to check:** Before releasing new versions
+
+**How to test locally:**
+```bash
+# See docs/JOOMLA_DEVELOPMENT.md for local testing setup
+codecept run
+```
+
+### Version Branch Creation (version_branch.yml)
+
+**Trigger:** Manual workflow dispatch
+
+**Purpose:** Creates a new version branch and bumps version numbers
+
+**What it does:**
+- 🏷️ Creates dev/*, rc/*, or version/* branch
+- 📝 Updates version in all files
+- 📅 Updates manifest dates
+- 📋 Moves CHANGELOG unreleased to version
+- ✅ Validates version hierarchy
+
+**When to use:** Starting work on a new version
+
+**How to run:**
+1. Go to Actions → Create version branch
+2. Click "Run workflow"
+3. Enter version (e.g., 03.06.00)
+4. Select branch prefix (dev/, rc/, or version/)
+5. Click "Run workflow"
+
+**Example:**
+```yaml
+new_version: 03.06.00
+branch_prefix: dev/
+version_text: beta
+```
+
+### Release Pipeline (release_pipeline.yml)
+
+**Trigger:** Manual workflow dispatch or release event
+
+**Purpose:** Promotes branches through release stages and creates distributions
+
+**What it does:**
+- 🔄 Promotes branches: dev → rc → version → main
+- 📅 Normalizes dates in manifest and CHANGELOG
+- 📦 Builds distributable ZIP package
+- 🚀 Uploads to SFTP server
+- 🏷️ Creates Git tag
+- 📋 Creates GitHub Release
+- 🔒 Attests build provenance
+
+**When to use:** Promoting a version through release stages
+
+**How to run:**
+1. Go to Actions → Release Pipeline
+2. Click "Run workflow"
+3. Select classification (auto/rc/stable)
+4. Click "Run workflow"
+
+**Release flow:**
+```
+dev/X.Y.Z → rc/X.Y.Z → version/X.Y.Z → main
+ (dev) (RC) (stable) (production)
+```
+
+### Deploy to Staging (deploy_staging.yml)
+
+**Trigger:** Manual workflow dispatch
+
+**Purpose:** Deploys template to staging/development environments
+
+**What it does:**
+- ✅ Validates deployment prerequisites
+- 📦 Builds deployment package
+- 🚀 Uploads via SFTP to environment
+- 📝 Creates deployment summary
+
+**When to use:** Testing in staging before production release
+
+**How to run:**
+1. Go to Actions → Deploy to Staging
+2. Click "Run workflow"
+3. Select environment (staging/development/preview)
+4. Optionally specify version
+5. Click "Run workflow"
+
+**Required secrets:**
+- `STAGING_HOST` - SFTP hostname
+- `STAGING_USER` - SFTP username
+- `STAGING_KEY` - SSH private key (or `STAGING_PASSWORD`)
+- `STAGING_PATH` - Remote deployment path
+
+### Repository Health (repo_health.yml)
+
+**Trigger:** Manual workflow dispatch (admin only)
+
+**Purpose:** Comprehensive repository health and configuration checks
+
+**What it does:**
+- 🔐 Validates release configuration
+- 🌐 Tests SFTP connectivity
+- 📂 Checks scripts governance
+- 📄 Validates required artifacts
+- 🔍 Extended checks (SPDX, ShellCheck, etc.)
+
+**When to use:** Before major releases or when debugging deployment issues
+
+**How to run:**
+1. Go to Actions → Repo Health
+2. Click "Run workflow"
+3. Select profile (all/release/repo)
+4. Click "Run workflow"
+
+**Profiles:**
+- `all` - Run all checks
+- `release` - Release configuration and SFTP only
+- `scripts` - Scripts governance only
+- `repo` - Repository health only
+
+## Common Development Tasks
+
+### Starting a New Feature
+
+```bash
+# 1. Create a new version branch via GitHub Actions
+# Actions → Create version branch → dev/X.Y.Z
+
+# 2. Clone and checkout the new branch
+git fetch origin
+git checkout dev/X.Y.Z
+
+# 3. Make your changes
+vim src/index.php
+
+# 4. Validate locally
+make validate-required
+
+# 5. Commit and push
+git add -A
+git commit -m "feat: add new feature"
+git push origin dev/X.Y.Z
+```
+
+### Running All Validations Locally
+
+```bash
+# Run comprehensive validation suite
+make validate-required
+
+# Run quality checks
+make quality
+```
+
+### Creating a Release Package
+
+```bash
+# Package with auto-detected version
+```bash
+# Package with auto-detected version
+make package
+
+# Verify package contents
+unzip -l dist/moko-cassiopeia-*.zip
+```
+
+### Updating Version Numbers
+
+```bash
+# Via GitHub Actions (recommended)
+# Actions → Release Management workflow
+```
+
+### Updating CHANGELOG
+
+Update CHANGELOG.md manually or via pull request following the existing format.
+
+## Troubleshooting
+
+### CI Failures
+
+#### PHP Syntax Errors
+
+```bash
+# Check specific file
+php -l src/index.php
+
+# Run validation
+make validate-required
+```
+
+#### Manifest Validation Failed
+
+```bash
+# Validate manifest and XML files
+make validate-required
+```
+
+#### Version Alignment Issues
+
+```bash
+# Check version consistency
+make validate-required
+```
+
+### Workflow Failures
+
+#### "Branch already exists"
+
+```bash
+# Check existing branches
+git branch -r | grep dev/
+
+# Delete remote branch if needed (carefully!)
+git push origin --delete dev/03.06.00
+```
+
+#### "Missing required secrets"
+
+Go to repository Settings → Secrets and variables → Actions, and add:
+- `FTP_SERVER`
+- `FTP_USER`
+- `FTP_KEY` or `FTP_PASSWORD`
+- `FTP_PATH`
+
+#### SFTP Connection Failed
+
+1. Verify credentials in repo_health workflow:
+ - Actions → Repo Health → profile: release
+
+2. Check SSH key format (OpenSSH, not PuTTY PPK)
+
+3. Verify server allows connections from GitHub IPs
+
+### Quality Check Failures
+
+#### PHPStan Errors
+
+```bash
+# Run locally to see full output
+phpstan analyse --configuration=phpstan.neon
+
+# Generate baseline to ignore existing issues
+phpstan analyse --configuration=phpstan.neon --generate-baseline
+```
+
+#### PHPCS Violations
+
+```bash
+# Check violations
+phpcs --standard=phpcs.xml src/
+
+# Auto-fix where possible
+phpcbf --standard=phpcs.xml src/
+
+# Show specific error codes
+phpcs --standard=phpcs.xml --report=source src/
+```
+
+#### Joomla Testing Failed
+
+1. Check PHP/Joomla version matrix compatibility
+2. Review MySQL connection errors
+3. Verify template manifest structure
+4. Check template file paths
+
+## Best Practices
+
+### Version Management
+
+1. **Always use version branches:** dev/X.Y.Z, rc/X.Y.Z, version/X.Y.Z
+2. **Follow hierarchy:** dev → rc → version → main
+3. **Update CHANGELOG:** Document all changes in Unreleased section
+4. **Semantic versioning:** Major.Minor.Patch (03.06.00)
+
+### Code Quality
+
+1. **Run validations locally** before pushing
+2. **Fix PHPStan warnings** at level 5
+3. **Follow PSR-12** coding standards
+4. **Add SPDX license headers** to new files
+5. **Keep functions small** and well-documented
+
+### Workflow Usage
+
+1. **Use CI for every commit** - automated validation
+2. **Run repo_health before releases** - comprehensive checks
+3. **Test on staging first** - never deploy directly to production
+4. **Monitor workflow runs** - fix failures promptly
+5. **Review workflow logs** - understand what changed
+
+### Release Process
+
+1. **Create dev branch** → Work on features
+2. **Promote to rc** → Release candidate testing
+3. **Promote to version** → Stable release
+4. **Merge to main** → Production (auto-merged via PR)
+5. **Create GitHub Release** → Public distribution
+
+### Security
+
+1. **Never commit secrets** - use GitHub Secrets
+2. **Use SSH keys** for SFTP (not passwords)
+3. **Scan for secrets** - runs automatically in CI
+4. **Keep dependencies updated** - security patches
+5. **Review security advisories** - GitHub Dependabot
+
+### Documentation
+
+1. **Update docs with code** - keep in sync
+2. **Document workflow changes** - update this guide
+3. **Add examples** - show, don't just tell
+4. **Link to relevant docs** - cross-reference
+5. **Keep README current** - first impression matters
+
+## Quick Links
+
+- [Main README](../README.md) - Project overview
+- [Joomla Development Guide](./JOOMLA_DEVELOPMENT.md) - Testing and quality
+- [CHANGELOG](../CHANGELOG.md) - Version history
+- [CONTRIBUTING](../CONTRIBUTING.md) - Contribution guidelines
+
+## Getting Help
+
+1. **Check workflow logs** - Most issues have clear error messages
+2. **Review this guide** - Common solutions documented
+3. **Run validation scripts** - Identify specific issues
+4. **Open an issue** - For bugs or questions
+5. **Contact maintainers** - For access or configuration issues
+
+---
+
+## Metadata
+
+* Document: docs/WORKFLOW_GUIDE.md
+* Repository: [https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx](https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx)
+* Path: /docs/WORKFLOW_GUIDE.md
+* Owner: Moko Consulting
+* Version: 03.06.03
+* Status: Active
+* Effective Date: 2026-01-30
+* Classification: Public Open Source Documentation
+
+## Revision History
+
+| Date | Change Summary | Author |
+| ---------- | ----------------------------------------------------- | --------------- |
+| 2026-01-30 | Updated metadata to MokoStandards format | GitHub Copilot |
+| 2025-01-04 | Initial workflow guide created | GitHub Copilot |
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..168f11b
--- /dev/null
+++ b/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "mokoonyx-build",
+ "private": true,
+ "description": "Build tooling for MokoOnyx Joomla template",
+ "scripts": {
+ "minify": "node scripts/minify.js"
+ },
+ "devDependencies": {
+ "clean-css": "^5.3.3",
+ "terser": "^5.39.0"
+ }
+}
diff --git a/phpcs.xml b/phpcs.xml
new file mode 100644
index 0000000..30d3686
--- /dev/null
+++ b/phpcs.xml
@@ -0,0 +1,77 @@
+
+
+ Joomla coding standards for MokoOnyx
+
+
+
+
+
+
+
+
+
+
+
+ */node_modules/*
+ */vendor/*
+ */tests/_output/*
+ */cache/*
+ */tmp/*
+ */.git/*
+
+
+ src
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/phpstan.neon b/phpstan.neon
new file mode 100644
index 0000000..3d4adca
--- /dev/null
+++ b/phpstan.neon
@@ -0,0 +1,32 @@
+# Copyright (C) 2026 Moko Consulting
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# PHPStan configuration for Joomla extension repositories.
+# Extends the base MokoStandards config and adds Joomla framework class stubs
+# so PHPStan can resolve Factory, CMSApplication, User, Table, etc.
+# without requiring a full Joomla installation.
+
+parameters:
+ level: 5
+
+ paths:
+ - src
+
+ excludePaths:
+ - vendor
+ - node_modules
+
+ # Joomla framework stubs — resolved via the enterprise package from vendor/
+ stubFiles:
+ - vendor/mokoconsulting-tech/enterprise/templates/stubs/joomla.php
+
+ # Suppress errors that are structural in Joomla's service-container architecture
+ ignoreErrors:
+ # Joomla's service-based dependency injection returns mixed from getApplication()
+ - '#Cannot call method .+ on Joomla\\CMS\\Application\\CMSApplication\|null#'
+ # Factory::getX() patterns are safe at runtime even when nullable in stubs
+ - '#Call to static method [a-zA-Z]+\(\) on an interface#'
+
+ reportUnmatchedIgnoredErrors: false
+ checkMissingIterableValueType: false
+ checkGenericClassInNonGenericObjectType: false
diff --git a/scripts/download-google-fonts.php b/scripts/download-google-fonts.php
new file mode 100644
index 0000000..e91143c
--- /dev/null
+++ b/scripts/download-google-fonts.php
@@ -0,0 +1,73 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * # FILE INFORMATION
+ * DEFGROUP: Joomla.Template.Site
+ * INGROUP: MokoOnyx
+ * PATH: scripts/download-google-fonts.php
+ * VERSION: 03.09.03
+ * BRIEF: Download Google Fonts (woff2) for local self-hosting
+ */
+
+$fontsDir = __DIR__ . '/../src/media/fonts';
+
+if (!is_dir($fontsDir)) {
+ fwrite(STDERR, "Error: Fonts directory not found: {$fontsDir}\n");
+ exit(1);
+}
+
+$fonts = [
+ 'Roboto' => 'https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;700&display=swap',
+ 'Noto Sans' => 'https://fonts.googleapis.com/css2?family=Noto+Sans:wght@100;300;400;700&display=swap',
+ 'Fira Sans' => 'https://fonts.googleapis.com/css2?family=Fira+Sans:wght@100;300;400;700&display=swap',
+];
+
+$userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
+
+echo "Google Fonts Downloader for MokoOnyx\n";
+echo str_repeat('=', 48) . "\n";
+echo "Target: {$fontsDir}\n\n";
+
+foreach ($fonts as $name => $url) {
+ echo "Downloading {$name}...\n";
+
+ $ctx = stream_context_create(['http' => ['header' => "User-Agent: {$userAgent}\r\n"]]);
+ $css = @file_get_contents($url, false, $ctx);
+
+ if ($css === false) {
+ fwrite(STDERR, " FAIL: could not fetch CSS for {$name}\n");
+ continue;
+ }
+
+ preg_match_all('#https://fonts\.gstatic\.com[^)]*\.woff2#', $css, $matches);
+
+ if (empty($matches[0])) {
+ fwrite(STDERR, " FAIL: no woff2 URLs found for {$name}\n");
+ continue;
+ }
+
+ $count = 0;
+ foreach ($matches[0] as $fontUrl) {
+ $filename = basename($fontUrl);
+ $dest = $fontsDir . '/' . $filename;
+
+ $data = @file_get_contents($fontUrl, false, $ctx);
+ if ($data === false) {
+ fwrite(STDERR, " FAIL: {$filename}\n");
+ continue;
+ }
+
+ file_put_contents($dest, $data);
+ $size = round(strlen($data) / 1024, 1);
+ echo " OK: {$filename} ({$size} KB)\n";
+ $count++;
+ }
+
+ echo " {$count} file(s) downloaded\n\n";
+}
+
+echo "Done.\n";
diff --git a/src/component.php b/src/component.php
new file mode 100644
index 0000000..fb329e4
--- /dev/null
+++ b/src/component.php
@@ -0,0 +1,170 @@
+
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Uri\Uri;
+use Joomla\CMS\Component\ComponentHelper;
+
+/** @var Joomla\CMS\Document\HtmlDocument $this */
+
+$app = Factory::getApplication();
+$input = $app->getInput();
+$document = $app->getDocument();
+$wa = $document->getWebAssetManager();
+
+// Template params - Component uses minimal configuration
+$params_googletagmanager = $this->params->get('googletagmanager', false);
+$params_googletagmanagerid = $this->params->get('googletagmanagerid', null);
+$params_googleanalytics = $this->params->get('googleanalytics', false);
+$params_googleanalyticsid = $this->params->get('googleanalyticsid', null);
+$params_googlesitekey = $this->params->get('googlesitekey', null);
+
+if (!empty($params_googlesitekey)) {
+ $this->setMetaData('google-site-verification', htmlspecialchars($params_googlesitekey, ENT_QUOTES, 'UTF-8'));
+}
+
+// Detecting Active Variables
+$option = $input->getCmd('option', '');
+$view = $input->getCmd('view', '');
+$layout = $input->getCmd('layout', '');
+$task = $input->getCmd('task', '');
+$itemid = $input->getCmd('Itemid', '');
+$sitenameR = $app->get('sitename'); // raw for title composition
+$sitename = htmlspecialchars($sitenameR, ENT_QUOTES, 'UTF-8');
+$menu = $app->getMenu()->getActive();
+$pageclass = $menu !== null ? $menu->getParams()->get('pageclass_sfx', '') : '';
+
+// Template/Media path
+$templatePath = 'media/templates/site/mokoonyx';
+
+// Core template CSS
+$wa->useStyle('template.base'); // css/template.css
+
+// Component always uses light theme only (no theme switching)
+$wa->useStyle('template.light.standard'); // css/theme/light.standard.css
+
+// Load Osaka font for site title
+$wa->useStyle('template.font.osaka');
+
+// Brand: logo from params OR siteTitle
+// -------------------------------------
+$brandHtml = '';
+$logoFile = (string) $this->params->get('logoFile');
+
+if ($logoFile !== '') {
+ $brandHtml = HTMLHelper::_(
+ 'image',
+ Uri::root(false) . htmlspecialchars($logoFile, ENT_QUOTES, 'UTF-8'),
+ $sitename,
+ ['class' => 'logo d-inline-block', 'loading' => 'eager', 'decoding' => 'async'],
+ false,
+ 0
+ );
+} else {
+ // If no logo file, show the title (defaults to "MokoOnyx" if not set)
+ $siteTitle = $this->params->get('siteTitle', 'MokoOnyx');
+ $brandHtml = ''
+ . htmlspecialchars($siteTitle, ENT_COMPAT, 'UTF-8')
+ . ' ';
+}
+
+?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ params->get('brand', 1)) : ?>
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/custom.php b/src/custom.php
new file mode 100644
index 0000000..79167a8
--- /dev/null
+++ b/src/custom.php
@@ -0,0 +1,20 @@
+
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+ function console_log($output, $with_script_tags = true) {
+ $js_code = 'console.log(' . json_encode($output, JSON_HEX_TAG) .
+ ');';
+ if ($with_script_tags) {
+ $js_code = '';
+ }
+ echo $js_code;
+ }
+?>
+
diff --git a/src/error.php b/src/error.php
new file mode 100644
index 0000000..34dcc3a
--- /dev/null
+++ b/src/error.php
@@ -0,0 +1,452 @@
+
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Uri\Uri;
+
+/** @var Joomla\CMS\Document\ErrorDocument|Joomla\CMS\Document\HtmlDocument $this */
+$app = Factory::getApplication();
+$params = $this->params;
+$wa = $this->getWebAssetManager();
+
+// Template params
+$params_LightColorName = (string) $params->get('colorLightName', 'standard'); // standard|custom
+
+$params_DarkColorName = (string) $params->get('colorDarkName', 'standard'); // standard|custom
+
+$params_googletagmanager = $params->get('googletagmanager', false);
+$params_googletagmanagerid = $params->get('googletagmanagerid', '');
+$params_googleanalytics = $params->get('googleanalytics', false);
+$params_googleanalyticsid = $params->get('googleanalyticsid', '');
+$params_custom_head_start = $params->get('custom_head_start', '');
+$params_custom_head_end = $params->get('custom_head_end', '');
+$params_developmentmode = $params->get('developmentmode', false);
+
+// ------------------ Params ------------------
+$fluidContainer = (bool) $params->get('fluidContainer', 0);
+$wrapper = $fluidContainer ? 'wrapper-fluid' : 'wrapper-static';
+$stickyHeader = (bool) $params->get('stickyHeader', 0);
+
+// Drawer icon params (escaped)
+$params_leftIcon = htmlspecialchars($params->get('drawerLeftIcon', 'fa-solid fa-chevron-left'), ENT_QUOTES, 'UTF-8');
+$params_rightIcon = htmlspecialchars($params->get('drawerRightIcon', 'fa-solid fa-chevron-right'), ENT_QUOTES, 'UTF-8');
+
+// Template/Media path
+$templatePath = 'media/templates/site/mokoonyx';
+
+// ===========================
+// Web Asset Manager (WAM) — matches your joomla.asset.json
+// ===========================
+
+// Core template CSS
+$wa->useStyle('template.base'); // css/template.css
+
+// Load theme palette stylesheets based on configuration
+$wa->useStyle('template.light.standard'); // css/theme/light.standard.css
+$wa->useStyle('template.dark.standard'); // css/theme/dark.standard.css
+
+// Load custom palettes only if selected in template configuration AND files exist
+if ($params_LightColorName === 'custom' && file_exists(JPATH_ROOT . '/media/templates/site/mokoonyx/css/theme/light.custom.css'))
+{
+ $wa->useStyle('template.light.custom');
+}
+if ($params_DarkColorName === 'custom' && file_exists(JPATH_ROOT . '/media/templates/site/mokoonyx/css/theme/dark.custom.css'))
+{
+ $wa->useStyle('template.dark.custom');
+}
+
+// Scripts
+$wa->useScript('template.js');
+
+// Load Osaka font for site title
+$wa->useStyle('template.font.osaka');
+
+// Smart Bootstrap component loading - only load what's needed
+if ($this->countModules('drawer-left', true) || $this->countModules('drawer-right', true)) {
+ // Load Bootstrap Offcanvas component for drawers
+ HTMLHelper::_('bootstrap.offcanvas');
+}
+
+// Meta
+$this->setMetaData('viewport', 'width=device-width, initial-scale=1');
+
+if ($this->params->get('faKitCode')) {
+ $faKit = "https://kit.fontawesome.com/" . $this->params->get('faKitCode') . ".js";
+ HTMLHelper::_('script', $faKit, ['crossorigin' => 'anonymous']);
+} else {
+ try {
+ if ($params_developmentmode){
+ $wa->useStyle('vendor.fa7free.all');
+ $wa->useStyle('vendor.fa7free.brands');
+ $wa->useStyle('vendor.fa7free.fontawesome');
+ $wa->useStyle('vendor.fa7free.regular');
+ $wa->useStyle('vendor.fa7free.solid');
+ } else {
+ $wa->useStyle('vendor.fa7free.all.min');
+ $wa->useStyle('vendor.fa7free.brands.min');
+ $wa->useStyle('vendor.fa7free.fontawesome.min');
+ $wa->useStyle('vendor.fa7free.regular.min');
+ $wa->useStyle('vendor.fa7free.solid.min');
+ }
+ } catch (\Throwable $e) {
+ if ($params_developmentmode){
+ $wa->registerAndUseStyle('vendor.fa7free.all.dynamic', $templatePath . '/vendor/fa7free/css/all.css');
+ $wa->registerAndUseStyle('vendor.fa7free.brands.dynamic', $templatePath . '/vendor/fa7free/css/brands.css');
+ $wa->registerAndUseStyle('vendor.fa7free.fontawesome.dynamic', $templatePath . '/vendor/fa7free/css/fontawesome.css');
+ $wa->registerAndUseStyle('vendor.fa7free.regular.dynamic', $templatePath . '/vendor/fa7free/css/regular.css');
+ $wa->registerAndUseStyle('vendor.fa7free.solid.dynamic', $templatePath . '/vendor/fa7free/css/solid.css');
+ } else {
+ $wa->registerAndUseStyle('vendor.fa7free.all.min.dynamic', $templatePath . '/vendor/fa7free/css/all.min.css');
+ $wa->registerAndUseStyle('vendor.fa7free.brands.min.dynamic', $templatePath . '/vendor/fa7free/css/brands.min.css');
+ $wa->registerAndUseStyle('vendor.fa7free.fontawesome.min.dynamic', $templatePath . '/vendor/fa7free/css/fontawesome.min.css');
+ $wa->registerAndUseStyle('vendor.fa7free.regular.min.dynamic', $templatePath . '/vendor/fa7free/css/regular.min.css');
+ $wa->registerAndUseStyle('vendor.fa7free.solid.min.dynamic', $templatePath . '/vendor/fa7free/css/solid.min.css');
+ }
+
+ }
+}
+
+// ------------------ Context (logo, bootstrap needs) ------------------
+$sitename = htmlspecialchars($app->get('sitename'), ENT_QUOTES, 'UTF-8');
+
+// -------------------------------------
+// Brand: logo from params OR siteTitle
+// -------------------------------------
+$brandHtml = '';
+$logoFile = (string) $this->params->get('logoFile');
+
+if ($logoFile !== '') {
+ $brandHtml = HTMLHelper::_(
+ 'image',
+ Uri::root(false) . htmlspecialchars($logoFile, ENT_QUOTES, 'UTF-8'),
+ $sitename,
+ ['class' => 'logo d-inline-block', 'loading' => 'eager', 'decoding' => 'async'],
+ false,
+ 0
+ );
+} else {
+ // If no logo file, show the title (defaults to "MokoOnyx" if not set)
+ $siteTitle = $this->params->get('siteTitle', 'MokoOnyx');
+ $brandHtml = ''
+ . htmlspecialchars($siteTitle, ENT_COMPAT, 'UTF-8')
+ . ' ';
+}
+
+// ------------------ Error details ------------------
+$errorObj = isset($this->error) && is_object($this->error) ? $this->error : null;
+$errorCode = $errorObj ? (int) $errorObj->getCode() : 500;
+$errorMsg = $errorObj ? $errorObj->getMessage() : Text::_('JERROR_AN_ERROR_HAS_OCCURRED');
+$debugOn = defined('JDEBUG') && JDEBUG;
+
+// Load user assets last (after all other styles and scripts)
+$wa->useStyle('template.user'); // css/user.css
+$wa->useScript('user.js'); // js/user.js
+?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Debug mode is ON — detailed error information is shown below.
+
+
+
+
+
+ Class
+
+
+ Code
+ getCode(); ?>
+
+ Message
+ getMessage(), ENT_QUOTES, 'UTF-8'); ?>
+
+ File
+ getFile(), ENT_QUOTES, 'UTF-8'); ?> : getLine(); ?>
+
+
+
+
+ getTrace() : []; ?>
+
+
+
+
+
+ $frame) :
+ $file = $frame['file'] ?? '[internal]';
+ $line = isset($frame['line']) ? (int) $frame['line'] : 0;
+ $func = $frame['function'] ?? '';
+ $class= $frame['class'] ?? '';
+ $type = $frame['type'] ?? '';
+ ?>
+
+ # ()
+
+
+
+
+
+
No stack trace available.
+
+
+
+
+
+
+
+
+params->get('backTop') == 1) : ?>
+
+
+
+
+
+countModules('drawer-left', true)) : ?>
+
+
+
+
+countModules('drawer-right', true)) : ?>
+
+
+
+
+
+
+
+
diff --git a/src/helper/favicon.php b/src/helper/favicon.php
new file mode 100644
index 0000000..bd1bdc9
--- /dev/null
+++ b/src/helper/favicon.php
@@ -0,0 +1,518 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Favicon generator — creates ICO, Apple Touch Icon, and Android icons
+ * from a single source image uploaded via the template config.
+ *
+ * Supports three backends in priority order:
+ * 1. GD (fastest, most common)
+ * 2. Imagick (common on shared hosting)
+ * 3. Pure PHP (zero-dependency fallback using raw PNG manipulation)
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Log\Log;
+
+class MokoFaviconHelper
+{
+ private const SIZES = [
+ 'apple-touch-icon.png' => [180, 180],
+ 'favicon-32x32.png' => [32, 32],
+ 'favicon-16x16.png' => [16, 16],
+ 'android-chrome-192x192.png' => [192, 192],
+ 'android-chrome-512x512.png' => [512, 512],
+ ];
+
+ /**
+ * Generate all favicon files from a source image.
+ */
+ public static function generate(string $sourcePath, string $outputDir): bool
+ {
+ if (!is_file($sourcePath)) {
+ self::log('Favicon: source file not found: ' . $sourcePath, 'warning');
+ return false;
+ }
+
+ if (!is_dir($outputDir)) {
+ mkdir($outputDir, 0755, true);
+ }
+
+ $sourceTime = filemtime($sourcePath);
+ $stampFile = $outputDir . '/.favicon_generated';
+
+ if (is_file($stampFile) && filemtime($stampFile) >= $sourceTime) {
+ return true;
+ }
+
+ // Strip #joomlaImage fragment if present
+ $sourcePath = strtok($sourcePath, '#');
+
+ // Select backend
+ if (extension_loaded('gd')) {
+ $result = self::generateWithGd($sourcePath, $outputDir);
+ } elseif (extension_loaded('imagick')) {
+ $result = self::generateWithImagick($sourcePath, $outputDir);
+ } else {
+ $result = self::generatePurePHP($sourcePath, $outputDir);
+ }
+
+ if ($result) {
+ self::generateManifest($outputDir);
+ file_put_contents($stampFile, date('c'));
+ }
+
+ return $result;
+ }
+
+ // ── GD Backend ──────────────────────────────────────────────────
+
+ private static function generateWithGd(string $sourcePath, string $outputDir): bool
+ {
+ $imageInfo = @getimagesize($sourcePath);
+ if ($imageInfo === false) {
+ self::log('Favicon: cannot read image: ' . $sourcePath, 'warning');
+ return false;
+ }
+
+ $source = match ($imageInfo[2]) {
+ IMAGETYPE_PNG => @imagecreatefrompng($sourcePath),
+ IMAGETYPE_JPEG => @imagecreatefromjpeg($sourcePath),
+ IMAGETYPE_GIF => @imagecreatefromgif($sourcePath),
+ IMAGETYPE_WEBP => function_exists('imagecreatefromwebp') ? @imagecreatefromwebp($sourcePath) : false,
+ default => false,
+ };
+
+ if (!$source) {
+ self::log('Favicon: unsupported image type', 'warning');
+ return false;
+ }
+
+ imagealphablending($source, false);
+ imagesavealpha($source, true);
+ $srcW = imagesx($source);
+ $srcH = imagesy($source);
+
+ foreach (self::SIZES as $filename => [$w, $h]) {
+ $resized = imagecreatetruecolor($w, $h);
+ imagealphablending($resized, false);
+ imagesavealpha($resized, true);
+ imagefill($resized, 0, 0, imagecolorallocatealpha($resized, 0, 0, 0, 127));
+ imagecopyresampled($resized, $source, 0, 0, 0, 0, $w, $h, $srcW, $srcH);
+ imagepng($resized, $outputDir . '/' . $filename, 9);
+ imagedestroy($resized);
+ }
+
+ // ICO from GD
+ $icoEntries = [];
+ foreach ([16, 32] as $size) {
+ $resized = imagecreatetruecolor($size, $size);
+ imagealphablending($resized, false);
+ imagesavealpha($resized, true);
+ imagefill($resized, 0, 0, imagecolorallocatealpha($resized, 0, 0, 0, 127));
+ imagecopyresampled($resized, $source, 0, 0, 0, 0, $size, $size, $srcW, $srcH);
+ ob_start();
+ imagepng($resized, null, 9);
+ $icoEntries[] = ['size' => $size, 'data' => ob_get_clean()];
+ imagedestroy($resized);
+ }
+ self::writeIco($icoEntries, $outputDir . '/favicon.ico');
+
+ imagedestroy($source);
+ self::log('Favicon: generated with GD');
+ return true;
+ }
+
+ // ── Imagick Backend ─────────────────────────────────────────────
+
+ private static function generateWithImagick(string $sourcePath, string $outputDir): bool
+ {
+ try {
+ foreach (self::SIZES as $filename => [$w, $h]) {
+ $img = new \Imagick($sourcePath);
+ $img->setImageFormat('png');
+ $img->setImageCompressionQuality(95);
+ $img->thumbnailImage($w, $h, true);
+ // Center on transparent canvas if not square
+ $canvas = new \Imagick();
+ $canvas->newImage($w, $h, new \ImagickPixel('transparent'), 'png');
+ $offsetX = (int)(($w - $img->getImageWidth()) / 2);
+ $offsetY = (int)(($h - $img->getImageHeight()) / 2);
+ $canvas->compositeImage($img, \Imagick::COMPOSITE_OVER, $offsetX, $offsetY);
+ $canvas->writeImage($outputDir . '/' . $filename);
+ $img->destroy();
+ $canvas->destroy();
+ }
+
+ // ICO from Imagick
+ $icoEntries = [];
+ foreach ([16, 32] as $size) {
+ $img = new \Imagick($sourcePath);
+ $img->setImageFormat('png');
+ $img->thumbnailImage($size, $size, true);
+ $icoEntries[] = ['size' => $size, 'data' => (string) $img];
+ $img->destroy();
+ }
+ self::writeIco($icoEntries, $outputDir . '/favicon.ico');
+
+ self::log('Favicon: generated with Imagick');
+ return true;
+ } catch (\Exception $e) {
+ self::log('Favicon: Imagick failed: ' . $e->getMessage(), 'warning');
+ return false;
+ }
+ }
+
+ // ── Pure PHP Backend (zero dependencies) ────────────────────────
+
+ private static function generatePurePHP(string $sourcePath, string $outputDir): bool
+ {
+ $pngData = @file_get_contents($sourcePath);
+ if ($pngData === false) {
+ self::log('Favicon: cannot read source file', 'warning');
+ return false;
+ }
+
+ // Detect format — we can only resize PNG in pure PHP
+ // For JPEG/other formats, just copy the source as-is for each size
+ $isPng = (substr($pngData, 0, 8) === "\x89PNG\r\n\x1a\n");
+
+ if (!$isPng) {
+ // Non-PNG: copy source file for all sizes (no resize capability without extensions)
+ foreach (self::SIZES as $filename => [$w, $h]) {
+ copy($sourcePath, $outputDir . '/' . $filename);
+ }
+ // ICO: embed the raw source for 16 and 32 entries
+ self::writeIco([
+ ['size' => 16, 'data' => $pngData],
+ ['size' => 32, 'data' => $pngData],
+ ], $outputDir . '/favicon.ico');
+ self::log('Favicon: non-PNG source copied without resize (no GD/Imagick)');
+ return true;
+ }
+
+ // Parse PNG dimensions from IHDR
+ $ihdr = self::parsePngIhdr($pngData);
+ if (!$ihdr) {
+ self::log('Favicon: cannot parse PNG header', 'warning');
+ return false;
+ }
+
+ $srcW = $ihdr['width'];
+ $srcH = $ihdr['height'];
+
+ // Decode PNG to raw RGBA pixel array
+ $pixels = self::decodePngToRgba($pngData, $srcW, $srcH, $ihdr);
+ if ($pixels === null) {
+ // Fallback: copy source for all sizes
+ foreach (self::SIZES as $filename => [$w, $h]) {
+ copy($sourcePath, $outputDir . '/' . $filename);
+ }
+ self::writeIco([
+ ['size' => 16, 'data' => $pngData],
+ ['size' => 32, 'data' => $pngData],
+ ], $outputDir . '/favicon.ico');
+ self::log('Favicon: PNG decode failed, copied source without resize');
+ return true;
+ }
+
+ // Generate resized PNGs
+ foreach (self::SIZES as $filename => [$w, $h]) {
+ $resized = self::resizePixels($pixels, $srcW, $srcH, $w, $h);
+ $png = self::encodePng($resized, $w, $h);
+ file_put_contents($outputDir . '/' . $filename, $png);
+ }
+
+ // ICO
+ $icoEntries = [];
+ foreach ([16, 32] as $size) {
+ $resized = self::resizePixels($pixels, $srcW, $srcH, $size, $size);
+ $icoEntries[] = ['size' => $size, 'data' => self::encodePng($resized, $size, $size)];
+ }
+ self::writeIco($icoEntries, $outputDir . '/favicon.ico');
+
+ self::log('Favicon: generated with pure PHP');
+ return true;
+ }
+
+ /**
+ * Parse PNG IHDR chunk.
+ */
+ private static function parsePngIhdr(string $data): ?array
+ {
+ if (strlen($data) < 33) return null;
+ // Skip 8-byte signature, 4-byte chunk length, 4-byte "IHDR"
+ $width = unpack('N', substr($data, 16, 4))[1];
+ $height = unpack('N', substr($data, 20, 4))[1];
+ $bitDepth = ord($data[24]);
+ $colorType = ord($data[25]);
+ return ['width' => $width, 'height' => $height, 'bitDepth' => $bitDepth, 'colorType' => $colorType];
+ }
+
+ /**
+ * Decode PNG to flat RGBA array using zlib decompression.
+ *
+ * @return array|null Flat array of [r,g,b,a, r,g,b,a, ...] or null on failure.
+ */
+ private static function decodePngToRgba(string $data, int $w, int $h, array $ihdr): ?array
+ {
+ // Only support 8-bit RGBA (color type 6) and RGB (color type 2) for simplicity
+ $colorType = $ihdr['colorType'];
+ $bitDepth = $ihdr['bitDepth'];
+
+ if ($bitDepth !== 8 || ($colorType !== 6 && $colorType !== 2 && $colorType !== 3)) {
+ return null; // Unsupported format
+ }
+
+ // Collect all IDAT chunks
+ $idatData = '';
+ $pos = 8; // Skip PNG signature
+ $palette = null;
+ $trns = null;
+
+ while ($pos < strlen($data) - 4) {
+ $chunkLen = unpack('N', substr($data, $pos, 4))[1];
+ $chunkType = substr($data, $pos + 4, 4);
+
+ if ($chunkType === 'IDAT') {
+ $idatData .= substr($data, $pos + 8, $chunkLen);
+ } elseif ($chunkType === 'PLTE') {
+ $palette = substr($data, $pos + 8, $chunkLen);
+ } elseif ($chunkType === 'tRNS') {
+ $trns = substr($data, $pos + 8, $chunkLen);
+ } elseif ($chunkType === 'IEND') {
+ break;
+ }
+
+ $pos += 12 + $chunkLen; // 4 len + 4 type + data + 4 crc
+ }
+
+ $raw = @gzuncompress($idatData);
+ if ($raw === false) {
+ $raw = @gzinflate($idatData);
+ }
+ if ($raw === false) {
+ // Try with zlib header
+ $raw = @gzinflate(substr($idatData, 2));
+ }
+ if ($raw === false) {
+ return null;
+ }
+
+ $bpp = $colorType === 6 ? 4 : ($colorType === 2 ? 3 : 1); // bytes per pixel
+ $stride = 1 + $w * $bpp; // +1 for filter byte per row
+ $pixels = [];
+
+ $prevRow = array_fill(0, $w * $bpp, 0);
+
+ for ($y = 0; $y < $h; $y++) {
+ $rowStart = $y * $stride;
+ if ($rowStart >= strlen($raw)) break;
+
+ $filter = ord($raw[$rowStart]);
+ $row = [];
+
+ for ($x = 0; $x < $w * $bpp; $x++) {
+ $rawByte = ord($raw[$rowStart + 1 + $x]);
+ $a = ($x >= $bpp) ? $row[$x - $bpp] : 0;
+ $b = $prevRow[$x];
+ $c = ($x >= $bpp) ? $prevRow[$x - $bpp] : 0;
+
+ $val = match ($filter) {
+ 0 => $rawByte,
+ 1 => ($rawByte + $a) & 0xFF,
+ 2 => ($rawByte + $b) & 0xFF,
+ 3 => ($rawByte + (int)(($a + $b) / 2)) & 0xFF,
+ 4 => ($rawByte + self::paethPredictor($a, $b, $c)) & 0xFF,
+ default => $rawByte,
+ };
+
+ $row[] = $val;
+ }
+
+ // Convert row to RGBA
+ for ($x = 0; $x < $w; $x++) {
+ if ($colorType === 6) { // RGBA
+ $pixels[] = $row[$x * 4];
+ $pixels[] = $row[$x * 4 + 1];
+ $pixels[] = $row[$x * 4 + 2];
+ $pixels[] = $row[$x * 4 + 3];
+ } elseif ($colorType === 2) { // RGB
+ $pixels[] = $row[$x * 3];
+ $pixels[] = $row[$x * 3 + 1];
+ $pixels[] = $row[$x * 3 + 2];
+ $pixels[] = 255;
+ } elseif ($colorType === 3 && $palette) { // Indexed
+ $idx = $row[$x];
+ $pixels[] = ord($palette[$idx * 3]);
+ $pixels[] = ord($palette[$idx * 3 + 1]);
+ $pixels[] = ord($palette[$idx * 3 + 2]);
+ $pixels[] = ($trns && $idx < strlen($trns)) ? ord($trns[$idx]) : 255;
+ }
+ }
+
+ $prevRow = $row;
+ }
+
+ return $pixels;
+ }
+
+ private static function paethPredictor(int $a, int $b, int $c): int
+ {
+ $p = $a + $b - $c;
+ $pa = abs($p - $a);
+ $pb = abs($p - $b);
+ $pc = abs($p - $c);
+ if ($pa <= $pb && $pa <= $pc) return $a;
+ if ($pb <= $pc) return $b;
+ return $c;
+ }
+
+ /**
+ * Bilinear resize of RGBA pixel array.
+ */
+ private static function resizePixels(array $src, int $srcW, int $srcH, int $dstW, int $dstH): array
+ {
+ $dst = [];
+ $xRatio = $srcW / $dstW;
+ $yRatio = $srcH / $dstH;
+
+ for ($y = 0; $y < $dstH; $y++) {
+ $srcY = $y * $yRatio;
+ $y0 = (int) $srcY;
+ $y1 = min($y0 + 1, $srcH - 1);
+ $yFrac = $srcY - $y0;
+
+ for ($x = 0; $x < $dstW; $x++) {
+ $srcX = $x * $xRatio;
+ $x0 = (int) $srcX;
+ $x1 = min($x0 + 1, $srcW - 1);
+ $xFrac = $srcX - $x0;
+
+ for ($c = 0; $c < 4; $c++) {
+ $tl = $src[($y0 * $srcW + $x0) * 4 + $c];
+ $tr = $src[($y0 * $srcW + $x1) * 4 + $c];
+ $bl = $src[($y1 * $srcW + $x0) * 4 + $c];
+ $br = $src[($y1 * $srcW + $x1) * 4 + $c];
+
+ $top = $tl + ($tr - $tl) * $xFrac;
+ $bot = $bl + ($br - $bl) * $xFrac;
+ $dst[] = (int) round($top + ($bot - $top) * $yFrac);
+ }
+ }
+ }
+
+ return $dst;
+ }
+
+ /**
+ * Encode RGBA pixel array to PNG binary.
+ */
+ private static function encodePng(array $pixels, int $w, int $h): string
+ {
+ // Build raw image data with filter byte 0 (None) per row
+ $raw = '';
+ for ($y = 0; $y < $h; $y++) {
+ $raw .= "\x00"; // filter: None
+ for ($x = 0; $x < $w; $x++) {
+ $i = ($y * $w + $x) * 4;
+ $raw .= chr($pixels[$i]) . chr($pixels[$i + 1]) . chr($pixels[$i + 2]) . chr($pixels[$i + 3]);
+ }
+ }
+
+ $compressed = gzcompress($raw);
+
+ // Build PNG
+ $png = "\x89PNG\r\n\x1a\n";
+
+ // IHDR
+ $ihdr = pack('NNCCCC', $w, $h, 8, 6, 0, 0, 0); // 8-bit RGBA
+ $png .= self::pngChunk('IHDR', $ihdr);
+
+ // IDAT
+ $png .= self::pngChunk('IDAT', $compressed);
+
+ // IEND
+ $png .= self::pngChunk('IEND', '');
+
+ return $png;
+ }
+
+ private static function pngChunk(string $type, string $data): string
+ {
+ $chunk = $type . $data;
+ return pack('N', strlen($data)) . $chunk . pack('N', crc32($chunk));
+ }
+
+ // ── Shared Utilities ────────────────────────────────────────────
+
+ /**
+ * Write ICO file from PNG data entries.
+ */
+ private static function writeIco(array $entries, string $outPath): void
+ {
+ $count = count($entries);
+ $ico = pack('vvv', 0, 1, $count);
+ $offset = 6 + ($count * 16);
+ $imageData = '';
+
+ foreach ($entries as $entry) {
+ $size = $entry['size'] >= 256 ? 0 : $entry['size'];
+ $dataLen = strlen($entry['data']);
+ $ico .= pack('CCCCvvVV', $size, $size, 0, 0, 1, 32, $dataLen, $offset);
+ $imageData .= $entry['data'];
+ $offset += $dataLen;
+ }
+
+ file_put_contents($outPath, $ico . $imageData);
+ }
+
+ private static function generateManifest(string $outputDir): void
+ {
+ $manifest = [
+ 'icons' => [
+ ['src' => 'android-chrome-192x192.png', 'sizes' => '192x192', 'type' => 'image/png'],
+ ['src' => 'android-chrome-512x512.png', 'sizes' => '512x512', 'type' => 'image/png'],
+ ],
+ ];
+ file_put_contents(
+ $outputDir . '/site.webmanifest',
+ json_encode($manifest, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
+ );
+ }
+
+ public static function getHeadTags(string $basePath): string
+ {
+ $basePath = htmlspecialchars(rtrim($basePath, '/'), ENT_QUOTES, 'UTF-8');
+
+ return ' ' . "\n"
+ . ' ' . "\n"
+ . ' ' . "\n"
+ . ' ' . "\n"
+ . ' ' . "\n";
+ }
+
+ private static function log(string $message, string $priority = 'info'): void
+ {
+ $priorities = [
+ 'info' => Log::INFO,
+ 'warning' => Log::WARNING,
+ 'error' => Log::ERROR,
+ ];
+
+ Log::addLogger(
+ ['text_file' => 'mokoonyx.log.php'],
+ Log::ALL,
+ ['mokoonyx']
+ );
+
+ Log::add($message, $priorities[$priority] ?? Log::INFO, 'mokoonyx');
+ }
+}
diff --git a/src/helper/index.html b/src/helper/index.html
new file mode 100644
index 0000000..2efb97f
--- /dev/null
+++ b/src/helper/index.html
@@ -0,0 +1 @@
+
diff --git a/src/helper/minify.php b/src/helper/minify.php
new file mode 100644
index 0000000..5189837
--- /dev/null
+++ b/src/helper/minify.php
@@ -0,0 +1,165 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * CSS/JS minifier — generates .min files from source when dev mode is off,
+ * deletes them when dev mode is on.
+ */
+
+defined('_JEXEC') or die;
+
+class MokoMinifyHelper
+{
+ /**
+ * Files to minify: source path relative to template media root.
+ * The .min variant is derived automatically (template.css → template.min.css).
+ */
+ private const CSS_FILES = [
+ 'css/template.css',
+ 'css/offline.css',
+ 'css/editor.css',
+ 'css/a11y-high-contrast.css',
+ 'css/theme/light.standard.css',
+ 'css/theme/dark.standard.css',
+ 'css/theme/light.custom.css',
+ 'css/theme/dark.custom.css',
+ ];
+
+ private const JS_FILES = [
+ 'js/template.js',
+ ];
+
+ /**
+ * When dev mode is ON: delete all .min files.
+ * When dev mode is OFF: regenerate .min files if source is newer.
+ *
+ * @param string $mediaRoot Absolute path to the template media directory.
+ * @param bool $devMode Whether development mode is enabled.
+ */
+ public static function sync(string $mediaRoot, bool $devMode): void
+ {
+ $mediaRoot = rtrim($mediaRoot, '/\\');
+
+ foreach (self::CSS_FILES as $relPath) {
+ $source = $mediaRoot . '/' . $relPath;
+ $min = self::minPath($source);
+
+ if ($devMode) {
+ self::deleteIfExists($min);
+ } else {
+ self::buildIfStale($source, $min, 'css');
+ }
+ }
+
+ foreach (self::JS_FILES as $relPath) {
+ $source = $mediaRoot . '/' . $relPath;
+ $min = self::minPath($source);
+
+ if ($devMode) {
+ self::deleteIfExists($min);
+ } else {
+ self::buildIfStale($source, $min, 'js');
+ }
+ }
+ }
+
+ /**
+ * Derive the .min path from a source path.
+ * template.css → template.min.css
+ */
+ private static function minPath(string $path): string
+ {
+ $info = pathinfo($path);
+ return $info['dirname'] . '/' . $info['filename'] . '.min.' . $info['extension'];
+ }
+
+ /**
+ * Delete a file if it exists.
+ */
+ private static function deleteIfExists(string $path): void
+ {
+ if (is_file($path)) {
+ @unlink($path);
+ }
+ }
+
+ /**
+ * Build the minified file if the source is newer or the min file is missing.
+ */
+ private static function buildIfStale(string $source, string $min, string $type): void
+ {
+ if (!is_file($source)) {
+ return;
+ }
+
+ // Skip if min file exists and is newer than source
+ if (is_file($min) && filemtime($min) >= filemtime($source)) {
+ return;
+ }
+
+ $content = file_get_contents($source);
+ if ($content === false) {
+ return;
+ }
+
+ $minified = ($type === 'css')
+ ? self::minifyCss($content)
+ : self::minifyJs($content);
+
+ file_put_contents($min, $minified);
+ }
+
+ /**
+ * Minify CSS by stripping comments, excess whitespace, and unnecessary characters.
+ */
+ private static function minifyCss(string $css): string
+ {
+ // Remove comments (but keep IE hacks like /*\*/)
+ $css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
+
+ // Remove whitespace around { } : ; , > + ~
+ $css = preg_replace('/\s*([{}:;,>+~])\s*/', '$1', $css);
+
+ // Remove remaining newlines and tabs
+ $css = preg_replace('/\s+/', ' ', $css);
+
+ // Remove spaces around selectors
+ $css = str_replace(['{ ', ' {', '; ', ' ;'], ['{', '{', ';', ';'], $css);
+
+ // Remove trailing semicolons before closing braces
+ $css = str_replace(';}', '}', $css);
+
+ // Remove leading/trailing whitespace
+ return trim($css);
+ }
+
+ /**
+ * Minify JS by stripping single-line comments, multi-line comments,
+ * and collapsing whitespace. Preserves string literals.
+ */
+ private static function minifyJs(string $js): string
+ {
+ // Remove multi-line comments
+ $js = preg_replace('!/\*.*?\*/!s', '', $js);
+
+ // Remove single-line comments (but not URLs like http://)
+ $js = preg_replace('!(?<=^|[\s;{}()\[\]])//[^\n]*!m', '', $js);
+
+ // Collapse whitespace
+ $js = preg_replace('/\s+/', ' ', $js);
+
+ // Remove spaces around operators and punctuation
+ $js = preg_replace('/\s*([{}();,=+\-*\/<>!&|?:])\s*/', '$1', $js);
+
+ // Restore necessary spaces (after keywords)
+ $js = preg_replace('/(var|let|const|return|typeof|instanceof|new|delete|throw|case|in|of)([^\s;})><=!&|?:,])/', '$1 $2', $js);
+
+ return trim($js);
+ }
+}
diff --git a/src/html/com_content/article/index.html b/src/html/com_content/article/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/com_content/article/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/com_content/article/toc-left.php b/src/html/com_content/article/toc-left.php
new file mode 100644
index 0000000..204e23c
--- /dev/null
+++ b/src/html/com_content/article/toc-left.php
@@ -0,0 +1,135 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Associations;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Layout\LayoutHelper;
+
+// Load Bootstrap TOC assets
+$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
+$wa->useStyle('vendor.bootstrap-toc');
+$wa->useScript('vendor.bootstrap-toc.js');
+
+// Get article params
+$params = $this->item->params;
+$images = json_decode($this->item->images);
+$urls = json_decode($this->item->urls);
+$canEdit = $params->get('access-edit');
+$info = $params->get('info_block_position', 0);
+
+// Check if associations are implemented
+$assocParam = (Associations::isEnabled() && $params->get('show_associations'));
+?>
+
+
+
+
+
+
+
+
+
+
+ params->get('show_page_heading')) : ?>
+
+
+
+ print) : ?>
+ get('show_print_icon') || $params->get('show_email_icon')) : ?>
+ $params, 'item' => $this->item, 'print' => false]); ?>
+
+
+ get('show_print_icon')) : ?>
+ $params, 'item' => $this->item, 'print' => true]); ?>
+
+
+
+ item->event->afterDisplayTitle; ?>
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ item->tags->itemTags); ?>
+
+
+ item->event->beforeDisplayContent; ?>
+
+ urls_position) && $urls->urls_position == '0') || ($params->get('urls_position') == '0' && empty($urls->urls_position))) || (empty($urls->urls_position) && (!$params->get('urls_position')))) : ?>
+ loadTemplate('links'); ?>
+
+
+ get('access-view')) : ?>
+ item); ?>
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ $this->item, 'params' => $params, 'position' => 'above']); ?>
+
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ item->tags->itemTags); ?>
+
+
+
+ item->text; ?>
+
+
+ urls_position) && $urls->urls_position == '1') || ($params->get('urls_position') == '1'))) : ?>
+ loadTemplate('links'); ?>
+
+ get('show_noauth') == true && $this->user->get('guest')) : ?>
+ item); ?>
+ item->introtext); ?>
+
+
+ item->event->afterDisplayContent; ?>
+
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ item->tags->itemTags); ?>
+
+ $this->item, 'params' => $params, 'position' => 'below']); ?>
+
+
+
+
+
+
diff --git a/src/html/com_content/article/toc-right.php b/src/html/com_content/article/toc-right.php
new file mode 100644
index 0000000..a2bc9c6
--- /dev/null
+++ b/src/html/com_content/article/toc-right.php
@@ -0,0 +1,135 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Associations;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Layout\LayoutHelper;
+
+// Load Bootstrap TOC assets
+$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
+$wa->useStyle('vendor.bootstrap-toc');
+$wa->useScript('vendor.bootstrap-toc.js');
+
+// Get article params
+$params = $this->item->params;
+$images = json_decode($this->item->images);
+$urls = json_decode($this->item->urls);
+$canEdit = $params->get('access-edit');
+$info = $params->get('info_block_position', 0);
+
+// Check if associations are implemented
+$assocParam = (Associations::isEnabled() && $params->get('show_associations'));
+?>
+
+
+
+
+
+
+
+ params->get('show_page_heading')) : ?>
+
+
+
+ print) : ?>
+ get('show_print_icon') || $params->get('show_email_icon')) : ?>
+ $params, 'item' => $this->item, 'print' => false]); ?>
+
+
+ get('show_print_icon')) : ?>
+ $params, 'item' => $this->item, 'print' => true]); ?>
+
+
+
+ item->event->afterDisplayTitle; ?>
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ item->tags->itemTags); ?>
+
+
+ item->event->beforeDisplayContent; ?>
+
+ urls_position) && $urls->urls_position == '0') || ($params->get('urls_position') == '0' && empty($urls->urls_position))) || (empty($urls->urls_position) && (!$params->get('urls_position')))) : ?>
+ loadTemplate('links'); ?>
+
+
+ get('access-view')) : ?>
+ item); ?>
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ $this->item, 'params' => $params, 'position' => 'above']); ?>
+
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ item->tags->itemTags); ?>
+
+
+
+ item->text; ?>
+
+
+ urls_position) && $urls->urls_position == '1') || ($params->get('urls_position') == '1'))) : ?>
+ loadTemplate('links'); ?>
+
+ get('show_noauth') == true && $this->user->get('guest')) : ?>
+ item); ?>
+ item->introtext); ?>
+
+
+ item->event->afterDisplayContent; ?>
+
+
+ get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
+ item->tags->itemTags); ?>
+
+ $this->item, 'params' => $params, 'position' => 'below']); ?>
+
+
+
+
+
+
+
+
+
diff --git a/src/html/mod_articles_archive/default.php b/src/html/mod_articles_archive/default.php
new file mode 100644
index 0000000..e76a8dd
--- /dev/null
+++ b/src/html/mod_articles_archive/default.php
@@ -0,0 +1,36 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_articles_archive.
+ * Adds showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+if (empty($list)) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
+ showtitle) : ?>
+ < class="mod-articles-archive__title">title; ?>>
+
+
+
diff --git a/src/html/mod_articles_archive/index.html b/src/html/mod_articles_archive/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_articles_archive/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_articles_categories/default.php b/src/html/mod_articles_categories/default.php
new file mode 100644
index 0000000..7b37853
--- /dev/null
+++ b/src/html/mod_articles_categories/default.php
@@ -0,0 +1,44 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_articles_categories.
+ * Adds showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+if (empty($list)) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+$showDescription = $params->get('show_description', 0);
+$numitems = $params->get('numitems', 0);
+?>
+
+ showtitle) : ?>
+ < class="mod-articles-categories__title">title; ?>>
+
+
+
+
+ title; ?>
+
+ (numitems; ?>)
+
+ description)) : ?>
+ description; ?>
+
+
+
+
+
diff --git a/src/html/mod_articles_categories/index.html b/src/html/mod_articles_categories/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_articles_categories/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_articles_category/default.php b/src/html/mod_articles_category/default.php
new file mode 100644
index 0000000..079d6b6
--- /dev/null
+++ b/src/html/mod_articles_category/default.php
@@ -0,0 +1,78 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_articles_category.
+ * Adds showtitle support and respects module settings.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+
+Factory::getApplication()->getLanguage()->load('mod_articles_category', JPATH_SITE);
+
+if (empty($list)) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
+ showtitle) : ?>
+ < class="mod-articles-category__title">title; ?>>
+
+
+
+
+ get('link_titles') == 1) : ?>
+
+ title; ?>
+
+
+ title; ?>
+
+
+ displayHits) : ?>
+
+ (displayHits; ?>)
+
+
+
+ get('show_author', 0)) : ?>
+
+ displayAuthorName; ?>
+
+
+
+ displayDate) : ?>
+
+ displayDate; ?>
+
+
+
+ get('show_introtext', 0)) : ?>
+
+ displayIntrotext; ?>
+
+
+
+ get('show_readmore', 0)) : ?>
+
+
+
+
+
+
+
+
diff --git a/src/html/mod_articles_category/index.html b/src/html/mod_articles_category/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_articles_category/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_articles_latest/default.php b/src/html/mod_articles_latest/default.php
new file mode 100644
index 0000000..4df78bb
--- /dev/null
+++ b/src/html/mod_articles_latest/default.php
@@ -0,0 +1,40 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_articles_latest.
+ * Adds showtitle support and respects module settings.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Language\Text;
+
+if (empty($list)) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
+ showtitle) : ?>
+ < class="mod-articles-latest__title">title; ?>>
+
+
+
diff --git a/src/html/mod_articles_latest/index.html b/src/html/mod_articles_latest/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_articles_latest/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_articles_news/default.php b/src/html/mod_articles_news/default.php
new file mode 100644
index 0000000..aa46eac
--- /dev/null
+++ b/src/html/mod_articles_news/default.php
@@ -0,0 +1,58 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_articles_news (newsflash).
+ * Adds showtitle support with card-based layout.
+ */
+
+defined('_JEXEC') or die;
+
+if (empty($list)) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
+ showtitle) : ?>
+ < class="mod-articles-news__title">title; ?>>
+
+
+
+ get('item_title')) : ?>
+
+ link !== '' && $params->get('link_titles')) : ?>
+ title; ?>
+
+ title; ?>
+
+
+
+
+ afterDisplayTitle)) : ?>
+ afterDisplayTitle; ?>
+
+
+ get('show_introtext', 1)) : ?>
+
+ introtext; ?>
+
+
+
+ readmore) && $item->readmore) : ?>
+
+ linkText; ?>
+
+
+
+
+
diff --git a/src/html/mod_articles_news/index.html b/src/html/mod_articles_news/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_articles_news/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_articles_popular/default.php b/src/html/mod_articles_popular/default.php
new file mode 100644
index 0000000..6d3c6be
--- /dev/null
+++ b/src/html/mod_articles_popular/default.php
@@ -0,0 +1,38 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_articles_popular.
+ * Adds showtitle support and respects module settings.
+ */
+
+defined('_JEXEC') or die;
+
+if (empty($list)) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
+ showtitle) : ?>
+ < class="mod-articles-popular__title">title; ?>>
+
+
+
diff --git a/src/html/mod_articles_popular/index.html b/src/html/mod_articles_popular/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_articles_popular/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_banners/default.php b/src/html/mod_banners/default.php
new file mode 100644
index 0000000..455e633
--- /dev/null
+++ b/src/html/mod_banners/default.php
@@ -0,0 +1,52 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_banners.
+ * Adds showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+
+if (empty($list)) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
+ showtitle) : ?>
+ < class="mod-banners__title">title; ?>>
+
+
+
+ params->get('url') ?: ''; ?>
+ type == 1) : ?>
+
+ params->get('imageurl', ''); ?>
+ name, ENT_COMPAT, 'UTF-8'); ?>
+
+
+
+
+
+
+
+
+
+ custombannercode; ?>
+
+
+
+
diff --git a/src/html/mod_banners/index.html b/src/html/mod_banners/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_banners/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_breadcrumbs/default.php b/src/html/mod_breadcrumbs/default.php
new file mode 100644
index 0000000..b81fc8c
--- /dev/null
+++ b/src/html/mod_breadcrumbs/default.php
@@ -0,0 +1,53 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_breadcrumbs.
+ * Bootstrap 5 breadcrumb with schema.org BreadcrumbList markup.
+ * Module settings (showHome, showLast, homeText) are handled by Joomla core
+ * before $list reaches this template.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Language\Text;
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+$showHere = $params->get('showHere', 1);
+
+if (empty($list)) {
+ return;
+}
+?>
+
+ showtitle) : ?>
+ < class="mod-breadcrumbs__title">title; ?>>
+
+
+
+
+
+ $item) : ?>
+
+ >
+ link)) : ?>
+
+ name; ?>
+
+
+ name; ?>
+
+
+
+
+
+
diff --git a/src/html/mod_breadcrumbs/index.html b/src/html/mod_breadcrumbs/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_breadcrumbs/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_custom/default.php b/src/html/mod_custom/default.php
new file mode 100644
index 0000000..5e03a50
--- /dev/null
+++ b/src/html/mod_custom/default.php
@@ -0,0 +1,39 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_custom.
+ * Adds showtitle support and respects all module settings.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Uri\Uri;
+
+$modId = 'mod-custom' . $module->id;
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+
+if ($params->get('backgroundimage')) {
+ /** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
+ $wa = $app->getDocument()->getWebAssetManager();
+ $wa->addInlineStyle(
+ '#' . $modId . '{background-image: url("' . Uri::root(true) . '/' . HTMLHelper::_('cleanImageURL', $params->get('backgroundimage'))->url . '");}',
+ ['name' => $modId]
+ );
+}
+?>
+
+ showtitle) : ?>
+ < class="mod-custom__title">title; ?>>
+
+ content; ?>
+
diff --git a/src/html/mod_custom/hero.php b/src/html/mod_custom/hero.php
new file mode 100644
index 0000000..d7368d6
--- /dev/null
+++ b/src/html/mod_custom/hero.php
@@ -0,0 +1,42 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Template override for mod_custom adding banner-overlay wrapper pattern.
+ * Based on Cassiopeia's banner layout approach.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Uri\Uri;
+
+$modId = 'mod-custom' . $module->id;
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+
+if ($params->get('backgroundimage')) {
+ /** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
+ $wa = $app->getDocument()->getWebAssetManager();
+ $wa->addInlineStyle(
+ '#' . $modId . '{background-image: url("' . Uri::root(true) . '/' . HTMLHelper::_('cleanImageURL', $params->get('backgroundimage'))->url . '");}',
+ ['name' => $modId]
+ );
+}
+?>
+
+
+ showtitle) : ?>
+ < class="mod-custom__title">title; ?>>
+
+ content; ?>
+
+
diff --git a/src/html/mod_feed/default.php b/src/html/mod_feed/default.php
new file mode 100644
index 0000000..f9ddb8f
--- /dev/null
+++ b/src/html/mod_feed/default.php
@@ -0,0 +1,88 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_feed.
+ * Adds showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\HTML\HTMLHelper;
+
+if (!$feed) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+$rssurl = $params->get('rssurl', '');
+$rsstitle = $params->get('rsstitle', 1);
+$rssdesc = $params->get('rssrtl', 0) ? ' feed-rtl' : '';
+$rssimage = $params->get('rssimage', 1);
+$rssitems = $params->get('rssitems', 5);
+$rssitemdesc = $params->get('rssitemdesc', 1);
+$word_count = $params->get('word_count', 0);
+?>
+
diff --git a/src/html/mod_feed/index.html b/src/html/mod_feed/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_feed/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_finder/default.php b/src/html/mod_finder/default.php
new file mode 100644
index 0000000..af54099
--- /dev/null
+++ b/src/html/mod_finder/default.php
@@ -0,0 +1,85 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_finder (Smart Search).
+ * Bootstrap 5 search form with showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Router\Route;
+
+// Load component language for search labels
+$lang = $app->getLanguage();
+$lang->load('com_finder', JPATH_SITE);
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+
+$showLabel = $params->get('show_label', 1);
+$labelClass = (!$showLabel ? 'visually-hidden ' : '') . 'finder';
+
+Text::script('MOD_FINDER_SEARCH_VALUE');
+
+/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
+$wa = $app->getDocument()->getWebAssetManager();
+$wa->getRegistry()->addExtensionRegistryFile('com_finder');
+
+if ($params->get('show_autosuggest', 1)) {
+ $wa->usePreset('awesomplete');
+ $app->getDocument()->addScriptOptions('finder-search', ['url' => Route::_('index.php?option=com_finder&task=suggestions.suggest&format=json&tmpl=component', false)]);
+ Text::script('COM_FINDER_SEARCH_FORM_LIST_LABEL');
+ Text::script('JLIB_JS_AJAX_ERROR_OTHER');
+ Text::script('JLIB_JS_AJAX_ERROR_PARSE');
+}
+
+$wa->useScript('com_finder.finder');
+?>
+
+ showtitle) : ?>
+ < class="mod-finder__title">title; ?>>
+
+
+
diff --git a/src/html/mod_finder/index.html b/src/html/mod_finder/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_finder/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_footer/default.php b/src/html/mod_footer/default.php
new file mode 100644
index 0000000..aea199f
--- /dev/null
+++ b/src/html/mod_footer/default.php
@@ -0,0 +1,29 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_footer.
+ * Adds showtitle support and respects module settings.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Language\Text;
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
diff --git a/src/html/mod_footer/index.html b/src/html/mod_footer/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_footer/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_languages/default.php b/src/html/mod_languages/default.php
new file mode 100644
index 0000000..d382ca3
--- /dev/null
+++ b/src/html/mod_languages/default.php
@@ -0,0 +1,63 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_languages.
+ * Adds showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Uri\Uri;
+
+if (empty($list)) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
+ showtitle) : ?>
+ < class="mod-languages__title">title; ?>>
+
+
+
diff --git a/src/html/mod_languages/index.html b/src/html/mod_languages/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_languages/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_login/default.php b/src/html/mod_login/default.php
new file mode 100644
index 0000000..7071b4f
--- /dev/null
+++ b/src/html/mod_login/default.php
@@ -0,0 +1,126 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_login.
+ * Bootstrap 5 login form with showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Router\Route;
+
+Factory::getApplication()->getLanguage()->load('mod_login', JPATH_SITE);
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
+ showtitle) : ?>
+ < class="mod-login__title">title; ?>>
+
+
+
+
+
+
+
+
diff --git a/src/html/mod_login/index.html b/src/html/mod_login/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_login/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_menu/default.php b/src/html/mod_menu/default.php
new file mode 100644
index 0000000..aecbceb
--- /dev/null
+++ b/src/html/mod_menu/default.php
@@ -0,0 +1,95 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_menu.
+ * Simple list menu with showtitle support, suitable for sidebars and footers.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Helper\ModuleHelper;
+
+$id = '';
+
+if ($tagId = $params->get('tag_id', '')) {
+ $id = ' id="' . $tagId . '"';
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
diff --git a/src/html/mod_menu/horizontal.php b/src/html/mod_menu/horizontal.php
new file mode 100644
index 0000000..d24ffcb
--- /dev/null
+++ b/src/html/mod_menu/horizontal.php
@@ -0,0 +1,106 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Main Menu - Mobile responsive collapsible dropdown menu override
+ * Bootstrap 5 responsive navbar with hamburger menu
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Helper\ModuleHelper;
+
+$id = '';
+
+if ($tagId = $params->get('tag_id', '')) {
+ $id = ' id="' . $tagId . '"';
+}
+
+// Get module class suffix
+$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+
+// The menu class is deprecated. Use mod-menu instead
+?>
+>
+
+
+
+
+
+
+
+
+
+
diff --git a/src/html/mod_menu/horizontal_component.php b/src/html/mod_menu/horizontal_component.php
new file mode 100644
index 0000000..dfcfa7f
--- /dev/null
+++ b/src/html/mod_menu/horizontal_component.php
@@ -0,0 +1,66 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Main Menu - Component item layout
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Filter\OutputFilter;
+use Joomla\CMS\HTML\HTMLHelper;
+
+$attributes = [];
+
+if ($item->anchor_title) {
+ $attributes['title'] = $item->anchor_title;
+}
+
+if ($item->anchor_css) {
+ $attributes['class'] = $item->anchor_css;
+}
+
+if ($item->anchor_rel) {
+ $attributes['rel'] = $item->anchor_rel;
+}
+
+$linktype = $item->title;
+
+if ($item->menu_icon) {
+ // The link is an icon
+ if ($itemParams->get('menu_text', 1)) {
+ // If the link text is to be displayed, the icon is added with aria-hidden
+ $linktype = '' . $item->title;
+ } else {
+ // If the icon itself is the link, it needs a visually hidden text
+ $linktype = '' . $item->title . ' ';
+ }
+}
+
+if ($item->browserNav == 1) {
+ $attributes['target'] = '_blank';
+ $attributes['rel'] = 'noopener noreferrer';
+} elseif ($item->browserNav == 2) {
+ $options = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,' . $params->get('window_open');
+
+ $attributes['onclick'] = "window.open(this.href, 'targetWindow', '" . $options . "'); return false;";
+}
+
+// Add dropdown toggle for items with children
+$linkClass = 'nav-link mod-menu-main__link';
+if ($item->deeper) {
+ $linkClass .= ' dropdown-toggle';
+ $attributes['data-bs-toggle'] = 'dropdown';
+ $attributes['role'] = 'button';
+ $attributes['aria-expanded'] = 'false';
+}
+
+$attributes['class'] = $linkClass;
+
+echo HTMLHelper::_('link', OutputFilter::ampReplace(htmlspecialchars($item->flink, ENT_COMPAT, 'UTF-8', false)), $linktype, $attributes);
diff --git a/src/html/mod_menu/horizontal_heading.php b/src/html/mod_menu/horizontal_heading.php
new file mode 100644
index 0000000..990077e
--- /dev/null
+++ b/src/html/mod_menu/horizontal_heading.php
@@ -0,0 +1,39 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Main Menu - Heading item layout
+ */
+
+defined('_JEXEC') or die;
+
+$title = $item->anchor_title ? ' title="' . $item->anchor_title . '"' : '';
+$anchor_css = $item->anchor_css ?: '';
+
+$linktype = $item->title;
+
+if ($item->menu_icon) {
+ // The link is an icon
+ if ($itemParams->get('menu_text', 1)) {
+ // If the link text is to be displayed, the icon is added with aria-hidden
+ $linktype = '' . $item->title;
+ } else {
+ // If the icon itself is the link, it needs a visually hidden text
+ $linktype = '' . $item->title . ' ';
+ }
+}
+
+// Add dropdown toggle for items with children
+$headingClass = 'nav-link mod-menu-main__heading';
+if ($item->deeper) {
+ $headingClass .= ' dropdown-toggle';
+}
+
+?>
+>
diff --git a/src/html/mod_menu/horizontal_separator.php b/src/html/mod_menu/horizontal_separator.php
new file mode 100644
index 0000000..2c0c587
--- /dev/null
+++ b/src/html/mod_menu/horizontal_separator.php
@@ -0,0 +1,33 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Main Menu - Separator item layout
+ */
+
+defined('_JEXEC') or die;
+
+$title = $item->anchor_title ? ' title="' . $item->anchor_title . '"' : '';
+$anchor_css = $item->anchor_css ?: '';
+
+$linktype = $item->title;
+
+if ($item->menu_icon) {
+ // The link is an icon
+ if ($itemParams->get('menu_text', 1)) {
+ // If the link text is to be displayed, the icon is added with aria-hidden
+ $linktype = '' . $item->title;
+ } else {
+ // If the icon itself is the link, it needs a visually hidden text
+ $linktype = '' . $item->title . ' ';
+ }
+}
+
+?>
+>
diff --git a/src/html/mod_menu/horizontal_url.php b/src/html/mod_menu/horizontal_url.php
new file mode 100644
index 0000000..10b380b
--- /dev/null
+++ b/src/html/mod_menu/horizontal_url.php
@@ -0,0 +1,71 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Main Menu - URL item layout
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Filter\OutputFilter;
+use Joomla\CMS\HTML\HTMLHelper;
+
+$attributes = [];
+
+if ($item->anchor_title) {
+ $attributes['title'] = $item->anchor_title;
+}
+
+if ($item->anchor_css) {
+ $attributes['class'] = $item->anchor_css;
+}
+
+if ($item->anchor_rel) {
+ $attributes['rel'] = $item->anchor_rel;
+}
+
+$linktype = $item->title;
+
+if ($item->menu_icon) {
+ // The link is an icon
+ if ($itemParams->get('menu_text', 1)) {
+ // If the link text is to be displayed, the icon is added with aria-hidden
+ $linktype = '' . $item->title;
+ } else {
+ // If the icon itself is the link, it needs a visually hidden text
+ $linktype = '' . $item->title . ' ';
+ }
+}
+
+if ($item->browserNav == 1) {
+ $attributes['target'] = '_blank';
+ $attributes['rel'] = 'noopener noreferrer';
+} elseif ($item->browserNav == 2) {
+ $options = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,' . $params->get('window_open');
+
+ $attributes['onclick'] = "window.open(this.href, 'targetWindow', '" . $options . "'); return false;";
+}
+
+// Add dropdown toggle for items with children
+$linkClass = 'nav-link mod-menu-main__link';
+if ($item->deeper) {
+ $linkClass .= ' dropdown-toggle';
+ $attributes['data-bs-toggle'] = 'dropdown';
+ $attributes['role'] = 'button';
+ $attributes['aria-expanded'] = 'false';
+}
+
+// Merge existing class with our class
+if (isset($attributes['class'])) {
+ $attributes['class'] .= ' ' . $linkClass;
+} else {
+ $attributes['class'] = $linkClass;
+}
+
+echo HTMLHelper::_('link', OutputFilter::ampReplace(htmlspecialchars($item->flink, ENT_COMPAT, 'UTF-8', false)), $linktype, $attributes);
diff --git a/src/html/mod_menu/index.html b/src/html/mod_menu/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_menu/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_menu/mainmenu.php b/src/html/mod_menu/mainmenu.php
new file mode 100644
index 0000000..1ee4c96
--- /dev/null
+++ b/src/html/mod_menu/mainmenu.php
@@ -0,0 +1,106 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Main Menu - Mobile responsive collapsible dropdown menu override
+ * Bootstrap 5 responsive navbar with hamburger menu
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Helper\ModuleHelper;
+
+$id = '';
+
+if ($tagId = $params->get('tag_id', '')) {
+ $id = ' id="' . $tagId . '"';
+}
+
+// Get module class suffix
+$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+
+// The menu class is deprecated. Use mod-menu instead
+?>
+>
+
+
+
+
+
+
+
+
+
+ &$item) :
+ $itemParams = $item->getParams();
+ $class = 'nav-item mod-menu-main__item item-' . $item->id;
+
+ if ($item->id == $default_id) {
+ $class .= ' default';
+ }
+
+ if ($item->id == $active_id || ($item->type === 'alias' && $itemParams->get('aliasoptions') == $active_id)) {
+ $class .= ' current';
+ }
+
+ if (in_array($item->id, $path)) {
+ $class .= ' active';
+ } elseif ($item->type === 'alias') {
+ $aliasToId = $itemParams->get('aliasoptions');
+
+ if (count($path) > 0 && $aliasToId == $path[count($path) - 1]) {
+ $class .= ' active';
+ } elseif (in_array($aliasToId, $path)) {
+ $class .= ' alias-parent-active';
+ }
+ }
+
+ if ($item->type === 'separator') {
+ $class .= ' divider';
+ }
+
+ if ($item->deeper) {
+ $class .= ' deeper dropdown';
+ }
+
+ if ($item->parent) {
+ $class .= ' parent';
+ }
+
+ echo '';
+
+ switch ($item->type) :
+ case 'separator':
+ case 'component':
+ case 'heading':
+ case 'url':
+ require ModuleHelper::getLayoutPath('mod_menu', 'mainmenu_' . $item->type);
+ break;
+
+ default:
+ require ModuleHelper::getLayoutPath('mod_menu', 'mainmenu_url');
+ break;
+ endswitch;
+
+ // The next item is deeper.
+ if ($item->deeper) {
+ echo '';
+ } elseif ($item->shallower) {
+ // The next item is shallower.
+ echo ' ';
+ echo str_repeat(' ', $item->level_diff);
+ } else {
+ // The next item is on the same level.
+ echo '';
+ }
+endforeach;
+?>
+
+
+
diff --git a/src/html/mod_menu/mainmenu_component.php b/src/html/mod_menu/mainmenu_component.php
new file mode 100644
index 0000000..dfcfa7f
--- /dev/null
+++ b/src/html/mod_menu/mainmenu_component.php
@@ -0,0 +1,66 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Main Menu - Component item layout
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Filter\OutputFilter;
+use Joomla\CMS\HTML\HTMLHelper;
+
+$attributes = [];
+
+if ($item->anchor_title) {
+ $attributes['title'] = $item->anchor_title;
+}
+
+if ($item->anchor_css) {
+ $attributes['class'] = $item->anchor_css;
+}
+
+if ($item->anchor_rel) {
+ $attributes['rel'] = $item->anchor_rel;
+}
+
+$linktype = $item->title;
+
+if ($item->menu_icon) {
+ // The link is an icon
+ if ($itemParams->get('menu_text', 1)) {
+ // If the link text is to be displayed, the icon is added with aria-hidden
+ $linktype = '' . $item->title;
+ } else {
+ // If the icon itself is the link, it needs a visually hidden text
+ $linktype = '' . $item->title . ' ';
+ }
+}
+
+if ($item->browserNav == 1) {
+ $attributes['target'] = '_blank';
+ $attributes['rel'] = 'noopener noreferrer';
+} elseif ($item->browserNav == 2) {
+ $options = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,' . $params->get('window_open');
+
+ $attributes['onclick'] = "window.open(this.href, 'targetWindow', '" . $options . "'); return false;";
+}
+
+// Add dropdown toggle for items with children
+$linkClass = 'nav-link mod-menu-main__link';
+if ($item->deeper) {
+ $linkClass .= ' dropdown-toggle';
+ $attributes['data-bs-toggle'] = 'dropdown';
+ $attributes['role'] = 'button';
+ $attributes['aria-expanded'] = 'false';
+}
+
+$attributes['class'] = $linkClass;
+
+echo HTMLHelper::_('link', OutputFilter::ampReplace(htmlspecialchars($item->flink, ENT_COMPAT, 'UTF-8', false)), $linktype, $attributes);
diff --git a/src/html/mod_menu/mainmenu_heading.php b/src/html/mod_menu/mainmenu_heading.php
new file mode 100644
index 0000000..990077e
--- /dev/null
+++ b/src/html/mod_menu/mainmenu_heading.php
@@ -0,0 +1,39 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Main Menu - Heading item layout
+ */
+
+defined('_JEXEC') or die;
+
+$title = $item->anchor_title ? ' title="' . $item->anchor_title . '"' : '';
+$anchor_css = $item->anchor_css ?: '';
+
+$linktype = $item->title;
+
+if ($item->menu_icon) {
+ // The link is an icon
+ if ($itemParams->get('menu_text', 1)) {
+ // If the link text is to be displayed, the icon is added with aria-hidden
+ $linktype = '' . $item->title;
+ } else {
+ // If the icon itself is the link, it needs a visually hidden text
+ $linktype = '' . $item->title . ' ';
+ }
+}
+
+// Add dropdown toggle for items with children
+$headingClass = 'nav-link mod-menu-main__heading';
+if ($item->deeper) {
+ $headingClass .= ' dropdown-toggle';
+}
+
+?>
+>
diff --git a/src/html/mod_menu/mainmenu_separator.php b/src/html/mod_menu/mainmenu_separator.php
new file mode 100644
index 0000000..2c0c587
--- /dev/null
+++ b/src/html/mod_menu/mainmenu_separator.php
@@ -0,0 +1,33 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Main Menu - Separator item layout
+ */
+
+defined('_JEXEC') or die;
+
+$title = $item->anchor_title ? ' title="' . $item->anchor_title . '"' : '';
+$anchor_css = $item->anchor_css ?: '';
+
+$linktype = $item->title;
+
+if ($item->menu_icon) {
+ // The link is an icon
+ if ($itemParams->get('menu_text', 1)) {
+ // If the link text is to be displayed, the icon is added with aria-hidden
+ $linktype = '' . $item->title;
+ } else {
+ // If the icon itself is the link, it needs a visually hidden text
+ $linktype = '' . $item->title . ' ';
+ }
+}
+
+?>
+>
diff --git a/src/html/mod_menu/mainmenu_url.php b/src/html/mod_menu/mainmenu_url.php
new file mode 100644
index 0000000..10b380b
--- /dev/null
+++ b/src/html/mod_menu/mainmenu_url.php
@@ -0,0 +1,71 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Main Menu - URL item layout
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Filter\OutputFilter;
+use Joomla\CMS\HTML\HTMLHelper;
+
+$attributes = [];
+
+if ($item->anchor_title) {
+ $attributes['title'] = $item->anchor_title;
+}
+
+if ($item->anchor_css) {
+ $attributes['class'] = $item->anchor_css;
+}
+
+if ($item->anchor_rel) {
+ $attributes['rel'] = $item->anchor_rel;
+}
+
+$linktype = $item->title;
+
+if ($item->menu_icon) {
+ // The link is an icon
+ if ($itemParams->get('menu_text', 1)) {
+ // If the link text is to be displayed, the icon is added with aria-hidden
+ $linktype = '' . $item->title;
+ } else {
+ // If the icon itself is the link, it needs a visually hidden text
+ $linktype = '' . $item->title . ' ';
+ }
+}
+
+if ($item->browserNav == 1) {
+ $attributes['target'] = '_blank';
+ $attributes['rel'] = 'noopener noreferrer';
+} elseif ($item->browserNav == 2) {
+ $options = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,' . $params->get('window_open');
+
+ $attributes['onclick'] = "window.open(this.href, 'targetWindow', '" . $options . "'); return false;";
+}
+
+// Add dropdown toggle for items with children
+$linkClass = 'nav-link mod-menu-main__link';
+if ($item->deeper) {
+ $linkClass .= ' dropdown-toggle';
+ $attributes['data-bs-toggle'] = 'dropdown';
+ $attributes['role'] = 'button';
+ $attributes['aria-expanded'] = 'false';
+}
+
+// Merge existing class with our class
+if (isset($attributes['class'])) {
+ $attributes['class'] .= ' ' . $linkClass;
+} else {
+ $attributes['class'] = $linkClass;
+}
+
+echo HTMLHelper::_('link', OutputFilter::ampReplace(htmlspecialchars($item->flink, ENT_COMPAT, 'UTF-8', false)), $linktype, $attributes);
diff --git a/src/html/mod_random_image/default.php b/src/html/mod_random_image/default.php
new file mode 100644
index 0000000..2d89070
--- /dev/null
+++ b/src/html/mod_random_image/default.php
@@ -0,0 +1,41 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_random_image.
+ * Adds showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+if (empty($image)) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
diff --git a/src/html/mod_random_image/index.html b/src/html/mod_random_image/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_random_image/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_related_items/default.php b/src/html/mod_related_items/default.php
new file mode 100644
index 0000000..8014400
--- /dev/null
+++ b/src/html/mod_related_items/default.php
@@ -0,0 +1,44 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_related_items.
+ * Adds showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\HTML\HTMLHelper;
+
+if (empty($list)) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+$showDate = $params->get('showDate', 0);
+?>
+
diff --git a/src/html/mod_related_items/index.html b/src/html/mod_related_items/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_related_items/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_stats/default.php b/src/html/mod_stats/default.php
new file mode 100644
index 0000000..7b6fdcf
--- /dev/null
+++ b/src/html/mod_stats/default.php
@@ -0,0 +1,39 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_stats.
+ * Adds showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+if (empty($list)) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
+ showtitle) : ?>
+ < class="mod-stats__title">title; ?>>
+
+
+
+
+
+ title; ?>
+ data; ?>
+
+
+
+
+
diff --git a/src/html/mod_stats/index.html b/src/html/mod_stats/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_stats/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_syndicate/default.php b/src/html/mod_syndicate/default.php
new file mode 100644
index 0000000..b56bec9
--- /dev/null
+++ b/src/html/mod_syndicate/default.php
@@ -0,0 +1,31 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_syndicate.
+ * Adds showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Language\Text;
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
+ showtitle) : ?>
+ < class="mod-syndicate__title">title; ?>>
+
+
+
+
+
+
diff --git a/src/html/mod_syndicate/index.html b/src/html/mod_syndicate/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_syndicate/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_tags_popular/default.php b/src/html/mod_tags_popular/default.php
new file mode 100644
index 0000000..96e2b53
--- /dev/null
+++ b/src/html/mod_tags_popular/default.php
@@ -0,0 +1,41 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_tags_popular.
+ * Adds showtitle support with Bootstrap badge-style tags.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Language\Text;
+
+if (empty($list)) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
diff --git a/src/html/mod_tags_popular/index.html b/src/html/mod_tags_popular/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_tags_popular/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_tags_similar/default.php b/src/html/mod_tags_similar/default.php
new file mode 100644
index 0000000..c850961
--- /dev/null
+++ b/src/html/mod_tags_similar/default.php
@@ -0,0 +1,38 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_tags_similar.
+ * Adds showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Language\Text;
+
+if (empty($list)) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
diff --git a/src/html/mod_tags_similar/index.html b/src/html/mod_tags_similar/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_tags_similar/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_users_latest/default.php b/src/html/mod_users_latest/default.php
new file mode 100644
index 0000000..48c3404
--- /dev/null
+++ b/src/html/mod_users_latest/default.php
@@ -0,0 +1,41 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_users_latest.
+ * Adds showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\HTML\HTMLHelper;
+
+if (empty($names)) {
+ return;
+}
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+?>
+
+ showtitle) : ?>
+ < class="mod-users-latest__title">title; ?>>
+
+
+
+
+ name, ENT_COMPAT, 'UTF-8'); ?>
+
+ registerDate, 'DATE_FORMAT_LC3'); ?>
+
+
+
+
+
diff --git a/src/html/mod_users_latest/index.html b/src/html/mod_users_latest/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_users_latest/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_whosonline/default.php b/src/html/mod_whosonline/default.php
new file mode 100644
index 0000000..e3942fc
--- /dev/null
+++ b/src/html/mod_whosonline/default.php
@@ -0,0 +1,43 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_whosonline.
+ * Adds showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Language\Text;
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+$showmode = $params->get('showmode', 0);
+?>
+
+ showtitle) : ?>
+ < class="mod-whosonline__title">title; ?>>
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/html/mod_whosonline/index.html b/src/html/mod_whosonline/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_whosonline/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/html/mod_wrapper/default.php b/src/html/mod_wrapper/default.php
new file mode 100644
index 0000000..91b608b
--- /dev/null
+++ b/src/html/mod_wrapper/default.php
@@ -0,0 +1,39 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Default layout override for mod_wrapper.
+ * Adds showtitle support.
+ */
+
+defined('_JEXEC') or die;
+
+$suffix = htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_COMPAT, 'UTF-8');
+$headerTag = htmlspecialchars($params->get('header_tag', 'h3'), ENT_COMPAT, 'UTF-8');
+$headerClass = htmlspecialchars($params->get('header_class', ''), ENT_COMPAT, 'UTF-8');
+$url = htmlspecialchars($params->get('url', ''), ENT_COMPAT, 'UTF-8');
+$width = htmlspecialchars($params->get('width', '100%'), ENT_COMPAT, 'UTF-8');
+$height = htmlspecialchars($params->get('height', '500'), ENT_COMPAT, 'UTF-8');
+$scrolling = $params->get('scrolling', 'auto');
+$frameborder = $params->get('frameborder', 0) ? '1' : '0';
+?>
+
+ showtitle) : ?>
+ < class="mod-wrapper__title">title; ?>>
+
+
+
diff --git a/src/html/mod_wrapper/index.html b/src/html/mod_wrapper/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/html/mod_wrapper/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/index.html b/src/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/index.php b/src/index.php
new file mode 100644
index 0000000..5de0bc1
--- /dev/null
+++ b/src/index.php
@@ -0,0 +1,590 @@
+
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Uri\Uri;
+use Joomla\CMS\Component\ComponentHelper;
+
+/** @var Joomla\CMS\Document\HtmlDocument $this */
+
+$app = Factory::getApplication();
+$input = $app->getInput();
+$document = $app->getDocument();
+$wa = $document->getWebAssetManager();
+
+// Template params
+$params_LightColorName = (string) $this->params->get('colorLightName', 'standard'); // standard|custom
+
+$params_DarkColorName = (string) $this->params->get('colorDarkName', 'standard'); // standard|custom
+
+$params_googletagmanager = $this->params->get('googletagmanager', false);
+$params_googletagmanagerid = $this->params->get('googletagmanagerid', null);
+$params_googleanalytics = $this->params->get('googleanalytics', false);
+$params_googleanalyticsid = $this->params->get('googleanalyticsid', null);
+$params_googlesitekey = $this->params->get('googlesitekey', null);
+$params_custom_head_start = $this->params->get('custom_head_start', null);
+$params_custom_head_end = $this->params->get('custom_head_end', null);
+$params_developmentmode = $this->params->get('developmentmode', false) || $app->get('debug', false);
+$params_favicon_source = (string) $this->params->get('favicon_source', '');
+
+// Theme params
+$params_theme_enabled = $this->params->get('theme_enabled', 1);
+$params_theme_control_type = (string) $this->params->get('theme_control_type', 'radios');
+$params_theme_fab_enabled = $this->params->get('theme_fab_enabled', 1);
+$params_theme_fab_pos = 'br';
+
+// Accessibility params
+$params_a11y_toolbar = $this->params->get('a11y_toolbar_enabled', 1);
+$params_a11y_resize = $this->params->get('a11y_text_resize', 1);
+$params_a11y_invert = $this->params->get('a11y_color_inversion', 1);
+$params_a11y_contrast = $this->params->get('a11y_high_contrast', 1);
+$params_a11y_links = $this->params->get('a11y_highlight_links', 1);
+$params_a11y_font = $this->params->get('a11y_readable_font', 1);
+$params_a11y_animations = $this->params->get('a11y_pause_animations', 1);
+$params_a11y_pos = 'br';
+
+// Detecting Active Variables
+$option = $input->getCmd('option', '');
+$view = $input->getCmd('view', '');
+$layout = $input->getCmd('layout', '');
+$task = $input->getCmd('task', '');
+$itemid = $input->getCmd('Itemid', '');
+$sitenameR = $app->get('sitename'); // raw for title composition
+$sitename = htmlspecialchars($sitenameR, ENT_QUOTES, 'UTF-8');
+$menu = $app->getMenu()->getActive();
+$pageclass = $menu !== null ? $menu->getParams()->get('pageclass_sfx', '') : '';
+
+// Template/Media path
+$templatePath = 'media/templates/site/mokoonyx';
+
+// Favicon generation
+$faviconHeadTags = '';
+if ($params_favicon_source) {
+ require_once __DIR__ . '/helper/favicon.php';
+ // Joomla's media field returns paths like:
+ // 'images/logo.png' (images folder)
+ // 'media/templates/site/mokoonyx/images/logo.png' (template media)
+ // 'logo.png' (bare filename)
+ // Strip Joomla's #joomlaImage:// fragment from media field value
+ $faviconSourceRel = strtok(ltrim($params_favicon_source, '/'), '#');
+ $faviconSourceAbs = JPATH_ROOT . '/' . $faviconSourceRel;
+ // Try common prefixes if not found
+ if (!is_file($faviconSourceAbs)) {
+ $candidates = [
+ JPATH_ROOT . '/images/' . $faviconSourceRel,
+ JPATH_ROOT . '/media/templates/site/' . $this->template . '/' . $faviconSourceRel,
+ JPATH_ROOT . '/media/templates/site/' . $this->template . '/images/' . basename($faviconSourceRel),
+ ];
+ foreach ($candidates as $candidate) {
+ if (is_file($candidate)) {
+ $faviconSourceAbs = $candidate;
+ break;
+ }
+ }
+ }
+ $faviconOutputDir = JPATH_ROOT . '/images/favicons';
+ $faviconUrlBase = Uri::root(true) . '/images/favicons';
+
+ if (MokoFaviconHelper::generate($faviconSourceAbs, $faviconOutputDir)) {
+ $faviconHeadTags = MokoFaviconHelper::getHeadTags($faviconUrlBase);
+ }
+}
+
+// Minification: dev mode ON → delete .min files; OFF → regenerate if stale
+require_once __DIR__ . '/helper/minify.php';
+MokoMinifyHelper::sync(JPATH_ROOT . '/' . $templatePath, (bool) $params_developmentmode);
+
+// Core template CSS + JS — use minified when not in development mode
+if ($params_developmentmode) {
+ $wa->useStyle('template.base'); // css/template.css
+ $wa->useScript('template.js'); // js/template.js
+} else {
+ $wa->useStyle('template.base.min'); // css/template.min.css
+ $wa->useScript('template.js.min'); // js/template.min.js
+}
+
+// Load Osaka font for site title
+$wa->useStyle('template.font.osaka');
+
+// Load GTM script if GTM is enabled
+if (!empty($params_googletagmanager) && !empty($params_googletagmanagerid)) {
+ $wa->useScript('gtm.js');
+}
+
+/**
+ * VirtueMart detection:
+ * - Component must exist and be enabled
+ */
+$isVirtueMartActive = ComponentHelper::isEnabled('com_virtuemart', true);
+
+if ($isVirtueMartActive) {
+ /**
+ * Load a VirtueMart-specific stylesheet defined in your template manifest.
+ * This assumes you defined an asset named "template.virtuemart".
+ */
+ $wa->useStyle('vendor.vm');
+}
+
+// Font scheme (external or local) + CSS custom properties
+$params_FontScheme = $this->params->get('useFontScheme', false);
+$fontStyles = '';
+
+if ($params_FontScheme) {
+ if (stripos($params_FontScheme, 'https://') === 0) {
+ $this->getPreloadManager()->preload($params_FontScheme, ['as' => 'style', 'crossorigin' => 'anonymous']);
+ $wa->registerAndUseStyle('fontscheme.current', $params_FontScheme, [], [
+ 'media' => 'print',
+ 'rel' => 'lazy-stylesheet',
+ 'onload' => 'this.media=\'all\'',
+ 'crossorigin' => 'anonymous'
+ ]);
+
+ if (preg_match_all('/family=([^?:]*):/i', $params_FontScheme, $matches) > 0) {
+ $fontStyles = '--font-family-body: "' . str_replace('+', ' ', $matches[1][0]) . '", sans-serif;' . "\n";
+ $fontStyles .= '--font-family-headings: "' . str_replace('+', ' ', isset($matches[1][1]) ? $matches[1][1] : $matches[1][0]) . '", sans-serif;' . "\n";
+ $fontStyles .= '--font-weight-normal: 400;' . "\n";
+ $fontStyles .= '--font-weight-headings: 700;';
+ }
+ } else {
+ $wa->registerAndUseStyle('fontscheme.current', $params_FontScheme, ['version' => 'auto'], [
+ 'media' => 'print',
+ 'rel' => 'lazy-stylesheet',
+ 'onload' => 'this.media=\'all\''
+ ]);
+ $this->getPreloadManager()->preload(
+ $wa->getAsset('style', 'fontscheme.current')->getUri() . '?' . $this->getMediaVersion(),
+ ['as' => 'style']
+ );
+ }
+}
+
+// -------------------------------------
+// Brand: logo from params OR siteTitle
+// -------------------------------------
+$brandHtml = '';
+$logoFile = (string) $this->params->get('logoFile');
+
+if ($logoFile !== '') {
+ $brandHtml = HTMLHelper::_(
+ 'image',
+ Uri::root(false) . htmlspecialchars($logoFile, ENT_QUOTES, 'UTF-8'),
+ $sitename,
+ ['class' => 'logo d-inline-block', 'loading' => 'eager', 'decoding' => 'async'],
+ false,
+ 0
+ );
+} else {
+ // If no logo file, show the title (defaults to "MokoOnyx" if not set)
+ $siteTitle = $this->params->get('siteTitle', 'MokoOnyx');
+ $brandHtml = ''
+ . htmlspecialchars($siteTitle, ENT_COMPAT, 'UTF-8')
+ . ' ';
+}
+
+// Layout flags
+$hasClass = '';
+if ($this->countModules('sidebar-left', true)) { $hasClass .= ' has-sidebar-left'; }
+if ($this->countModules('sidebar-right', true)) { $hasClass .= ' has-sidebar-right'; }
+if ($this->countModules('drawer-left', true)) { $hasClass .= ' has-drawer-left'; }
+if ($this->countModules('drawer-right', true)) { $hasClass .= ' has-drawer-right'; }
+
+// Smart Bootstrap component loading - only load what's needed
+HTMLHelper::_('bootstrap.collapse');
+if ($this->countModules('drawer-left', true) || $this->countModules('drawer-right', true)) {
+ HTMLHelper::_('bootstrap.offcanvas');
+}
+
+// Container
+$wrapper = $this->params->get('fluidContainer') ? 'wrapper-fluid' : 'wrapper-static';
+$stickyHeader = $this->params->get('stickyHeader') ? 'position-sticky sticky-top' : '';
+
+// Meta
+$this->setMetaData('viewport', 'width=device-width, initial-scale=1');
+if (!empty($params_googlesitekey)) {
+ $this->setMetaData('google-site-verification', htmlspecialchars($params_googlesitekey, ENT_QUOTES, 'UTF-8'));
+}
+
+// Font Awesome 7 — Kit (CDN) or local files
+$faKitCode = trim((string) $this->params->get('fA6KitCode', ''));
+if ($faKitCode !== '') {
+ HTMLHelper::_('script', 'https://kit.fontawesome.com/' . $faKitCode . '.js', ['crossorigin' => 'anonymous']);
+} else {
+ // Load local FA7 Free — all.css via WebAsset
+ // Resolve the actual filesystem path: media dir (Joomla install) or template dir (SFTP deploy)
+ $faCssFile = $params_developmentmode ? 'vendor/fa7free/css/all.css' : 'vendor/fa7free/css/all.min.css';
+ $faCandidates = [
+ $templatePath . '/' . $faCssFile, // media/templates/site/mokoonyx/...
+ 'templates/site/' . $this->template . '/media/' . $faCssFile, // templates/site/mokoonyx/media/...
+ ];
+
+ // Also check via __DIR__ for edge cases
+ $faFromDir = __DIR__ . '/media/' . $faCssFile;
+ if (is_file($faFromDir)) {
+ $faCandidates[] = ltrim(str_replace('\\', '/', str_replace(JPATH_ROOT, '', $faFromDir)), '/');
+ }
+
+ $faRegistered = false;
+ foreach ($faCandidates as $faPath) {
+ if (is_file(JPATH_ROOT . '/' . $faPath)) {
+ $wa->registerStyle('vendor.fa7free.all', $faPath);
+ $faRegistered = true;
+ break;
+ }
+ }
+
+ // Use the asset — either our dynamic registration or the one from joomla.asset.json
+ try {
+ $wa->useStyle('vendor.fa7free.all');
+ } catch (\Throwable $e) {
+ // All paths exhausted — FA icons will rely on the IcoMoon compat layer
+ }
+}
+$params_leftIcon = htmlspecialchars($this->params->get('drawerLeftIcon', 'fa-solid fa-chevron-left'), ENT_COMPAT, 'UTF-8');
+$params_rightIcon = htmlspecialchars($this->params->get('drawerRightIcon', 'fa-solid fa-chevron-right'), ENT_COMPAT, 'UTF-8');
+
+// Load theme palette stylesheets — minified when not in development mode
+$suffix = $params_developmentmode ? '' : '.min';
+$wa->useStyle('template.light.standard' . $suffix);
+$wa->useStyle('template.dark.standard' . $suffix);
+
+// Load custom palettes only if selected in template configuration AND files exist
+if ($params_LightColorName === 'custom' && file_exists(JPATH_ROOT . '/media/templates/site/mokoonyx/css/theme/light.custom.css'))
+{
+ $wa->useStyle('template.light.custom' . $suffix);
+}
+if ($params_DarkColorName === 'custom' && file_exists(JPATH_ROOT . '/media/templates/site/mokoonyx/css/theme/dark.custom.css'))
+{
+ $wa->useStyle('template.dark.custom' . $suffix);
+}
+
+// Load user assets last (after all other styles and scripts)
+$wa->useStyle('template.user'); // css/user.css
+$wa->useScript('user.js'); // js/user.js
+?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ countModules('banner', true)) : ?>
+
+
+
+
+
+ countModules('top-a', true)) : ?>
+
+
+
+
+
+ countModules('top-b', true)) : ?>
+
+
+
+
+
+ countModules('sidebar-left', true)) : ?>
+
+
+
+
+
+ countModules('main-top', true)) : ?>
+
+
+
+
+
+
+
+
+ countModules('main-bottom', true)) : ?>
+
+
+
+
+
+
+ countModules('sidebar-right', true)) : ?>
+
+
+
+ countModules('bottom-a', true)) : ?>
+
+
+
+
+
+ countModules('bottom-b', true)) : ?>
+
+
+
+
+
+
+
+
+params->get('backTop') == 1) : ?>
+
+
+
+
+
+countModules('drawer-left', true)) : ?>
+
+
+
+
+countModules('drawer-right', true)) : ?>
+
+
+
+
+
+
+
+
diff --git a/src/joomla.asset.json b/src/joomla.asset.json
new file mode 100644
index 0000000..d926bd6
--- /dev/null
+++ b/src/joomla.asset.json
@@ -0,0 +1,248 @@
+{
+ "$schema": "https://developer.joomla.org/schemas/json-schema/web_assets.json",
+ "name": "mokoonyx",
+ "description": "MokoOnyx template assets",
+ "license": "GPL-3.0-or-later",
+ "x-header": {
+ "copyright_year": 2026,
+ "author": "Jonathan Miller",
+ "owner": "Moko Consulting",
+ "contact": "hello@mokoconsulting.tech",
+ "project": "MokoOnyx Template",
+ "spdx_license": "GPL-3.0-or-later",
+ "notice": "This file is part of a Moko Consulting project.",
+ "disclaimer": "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.",
+ "repo": "https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx",
+ "file_information": {
+ "defgroup": "Joomla.Template.Site",
+ "ingroup": "MokoOnyx.Template.Assets",
+ "path": "./media/templates/site/mokoonyx/joomla.asset.json",
+ "version": "01.00.00",
+ "brief": "Joomla asset registry for MokoOnyx"
+ }
+ },
+ "assets": [
+ {
+ "name": "template.base",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/template.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.base.min",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/template.min.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.offline",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/offline.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.offline.min",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/offline.min.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.user",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/user.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.user.min",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/user.min.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "user.js",
+ "type": "script",
+ "uri": "media/templates/site/mokoonyx/js/user.js",
+ "attributes": {"defer": true}
+ },
+ {
+ "name": "user.js.min",
+ "type": "script",
+ "uri": "media/templates/site/mokoonyx/js/user.min.js",
+ "attributes": {"defer": true}
+ },
+ {
+ "name": "template.font.osaka",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/fonts/osaka.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.editor",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/editor.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.editor.min",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/editor.min.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.light.standard",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/theme/light.standard.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.light.standard.min",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/theme/light.standard.min.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.light.custom",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/theme/light.custom.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.light.custom.min",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/theme/light.custom.min.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.dark.standard",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/theme/dark.standard.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.dark.standard.min",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/theme/dark.standard.min.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.dark.custom",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/theme/dark.custom.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.dark.custom.min",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/theme/dark.custom.min.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.a11y-high-contrast",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/a11y-high-contrast.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "template.js",
+ "type": "script",
+ "uri": "media/templates/site/mokoonyx/js/template.js",
+ "attributes": {"defer": true}
+ },
+ {
+ "name": "template.js.min",
+ "type": "script",
+ "uri": "media/templates/site/mokoonyx/js/template.min.js",
+ "attributes": {"defer": true}
+ },
+ {
+ "name": "gtm.js",
+ "type": "script",
+ "uri": "media/templates/site/mokoonyx/js/gtm.js",
+ "attributes": {"defer": true}
+ },
+ {
+ "name": "gtm.min.js",
+ "type": "script",
+ "uri": "media/templates/site/mokoonyx/js/gtm.min.js",
+ "attributes": {"defer": true}
+ },
+ {
+ "name": "vendor.fa7free.all",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/vendor/fa7free/css/all.css"
+ },
+ {
+ "name": "vendor.fa7free.all.min",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/vendor/fa7free/css/all.min.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "vendor.fa7free.brands",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/vendor/fa7free/css/brands.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "vendor.fa7free.brands.min",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/vendor/fa7free/css/brands.min.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "vendor.fa7free.fontawesome",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/vendor/fa7free/css/fontawesome.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "vendor.fa7free.fontawesome.min",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/vendor/fa7free/css/fontawesome.min.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "vendor.fa7free.regular",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/vendor/fa7free/css/regular.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "vendor.fa7free.regular.min",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/vendor/fa7free/css/regular.min.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "vendor.fa7free.solid",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/vendor/fa7free/css/solid.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "vendor.fa7free.solid.min",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/vendor/fa7free/css/solid.min.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "vendor.vm",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/css/vendor/vm.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "vendor.bootstrap-toc",
+ "type": "style",
+ "uri": "media/templates/site/mokoonyx/vendor/bootstrap-toc/bootstrap-toc.css",
+ "attributes": {"media": "all"}
+ },
+ {
+ "name": "vendor.bootstrap-toc.js",
+ "type": "script",
+ "uri": "media/templates/site/mokoonyx/vendor/bootstrap-toc/bootstrap-toc.js",
+ "dependencies": ["jquery"],
+ "attributes": {"defer": true}
+ }
+ ]
+}
diff --git a/src/language/en-GB/index.html b/src/language/en-GB/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/language/en-GB/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/language/en-GB/tpl_mokoonyx.ini b/src/language/en-GB/tpl_mokoonyx.ini
new file mode 100644
index 0000000..e507402
--- /dev/null
+++ b/src/language/en-GB/tpl_mokoonyx.ini
@@ -0,0 +1,273 @@
+; Copyright (C) 2025 Moko Consulting
+;
+; This file is part of a Moko Consulting project.
+;
+; SPDX-License-Identifier: GPL-3.0-or-later
+
+; ===== System / layout =====
+TPL_MOKOONYX_DEVELOPMENTMODE_LABEL="Development Mode"
+TPL_MOKOONYX_DEVELOPMENTMODE_DESC="When enabled, unminified CSS and JavaScript files are loaded for easier debugging. When disabled, minified assets are served for faster page loads. Google Tag Manager and Google Analytics may also be disabled in development mode."
+TPL_MOKOONYX_FLUID_LABEL="Layout"
+TPL_MOKOONYX_STATIC="Static"
+TPL_MOKOONYX_FLUID="Fluid"
+
+; ===== Custom Code tab =====
+TPL_MOKOONYX_CUSTOM_CODE_FIELDSET="Custom Code"
+TPL_MOKOONYX_CUSTOM_HEAD_START_LABEL="Custom Head: Start"
+TPL_MOKOONYX_CUSTOM_HEAD_START_DESC="This content will be inserted at the beginning of the <head> tag"
+TPL_MOKOONYX_CUSTOM_HEAD_END_LABEL="Custom Head: End"
+TPL_MOKOONYX_CUSTOM_HEAD_END_DESC="This content will be inserted at the end of the <head> tag"
+TPL_MOKOONYX_OFFLINEEMBED_LABEL="Offline Page Embed Code"
+TPL_MOKOONYX_OFFLINEEMBED_DESC="In addition to the 'Offline message' defined in 'Global Configuration', this will be displayed on the offline page.Use for Mailchimp code and Social Icons "
+
+; ===== Drawers =====
+TPL_MOKOONYX_DRAWERS_FIELDSET_LABEL="Drawers"
+TPL_MOKOONYX_DRAWER_LEFT_ICON_LABEL="Drawer Left Icon CSS"
+TPL_MOKOONYX_DRAWER_LEFT_ICON_DESC="Enter the Font-Awesome class for the left drawer toggle (e.g. 'fas fa-chevron-left')."
+TPL_MOKOONYX_DRAWER_RIGHT_ICON_LABEL="Drawer Right Icon CSS"
+TPL_MOKOONYX_DRAWER_RIGHT_ICON_DESC="Enter the Font-Awesome class for the right drawer toggle (e.g. 'fas fa-chevron-right')."
+
+; ===== Favicon =====
+TPL_MOKOONYX_FAVICON_FIELDSET_LABEL="Favicon"
+TPL_MOKOONYX_FAVICON_NOTE="Upload a square PNG image (recommended 512×512 or larger). The template will automatically generate all required favicon sizes including ICO, Apple Touch Icon (180×180), and Android icons (192×192, 512×512). Generated files are cached in images/favicons/.
"
+TPL_MOKOONYX_FAVICON_SOURCE_LABEL="Favicon Source Image"
+TPL_MOKOONYX_FAVICON_SOURCE_DESC="Select a square PNG image to use as the site favicon. Recommended size: 512×512 pixels or larger."
+
+; ===== Google =====
+TPL_MOKOONYX_GOOGLE_FIELDSET_LABEL="Google"
+TPL_MOKOONYX_GOOGLE_NOTE_TEXT="PLEASE NOTE: If fields are left blank, relative Google features will not be used"
+TPL_MOKOONYX_GOOGLETAGMANAGER_LABEL="Use Google Tag Manager?"
+TPL_MOKOONYX_GOOGLETAGMANAGER_DESC="Do you want to use Google Tag Manager? More information on Google Tag Manager can be found here. "
+TPL_MOKOONYX_GOOGLETAGMANAGERID_LABEL="Google Tag Manager ID"
+TPL_MOKOONYX_GOOGLETAGMANAGERID_DESC="Begins with 'GTM-'"
+TPL_MOKOONYX_GOOGLEANALYTICS_LABEL="Use Google Analytics?"
+TPL_MOKOONYX_GOOGLEANALYTICS_DESC="Do you want to use Google Analytics? More information on Google Analytics can be found here. "
+TPL_MOKOONYX_GOOGLEANALYTICSID_LABEL="Google Analytics ID"
+TPL_MOKOONYX_GOOGLEANALYTICSID_DESC="Begins with 'G-'"
+TPL_MOKOONYX_GOOGLESITEKEY_LABEL="Google Search Console Verification"
+TPL_MOKOONYX_GOOGLESITEKEY_DESC="Paste the content value from the <meta name="google-site-verification"> tag. Find this in Google Search Console under Ownership Verification → HTML tag method."
+
+; ===== Branding & icons (Theme tab) =====
+TPL_MOKOONYX_BRAND_LABEL="Brand"
+TPL_MOKOONYX_LOGO_LABEL="Logo"
+TPL_MOKOONYX_TITLE="Title (alternative to logo)"
+TPL_MOKOONYX_TAGLINE_LABEL="Tagline"
+TPL_MOKOONYX_TAGLINE_DESC="Optional text to show as a subheading"
+TPL_MOKOONYX_FA7KITCODE_LABEL="Font Awesome 7 Kit Unique Code"
+TPL_MOKOONYX_FA7KITCODE_DESC="If left blank, Font Awesome 7 Free will be used. Copy the unique Kit embed code above and paste it into the <head> of your project's HTML file or template.More information at the Font Awesome website. "
+
+; ===== Typography (Theme tab) =====
+TPL_MOKOONYX_FONT_LABEL="Fonts Scheme"
+TPL_MOKOONYX_FONT_LABEL_DESC="Select a font scheme for your site. Local fonts are loaded from the template folder, while web fonts are loaded from external sources (Google Fonts). The default is Roboto (local). See the note below for important privacy and performance considerations."
+TPL_MOKOONYX_FONT_GROUP_LOCAL="Fonts from Folder"
+TPL_MOKOONYX_FONT_GROUP_WEB="Fonts from Web"
+TPL_MOKOONYX_FONT_NOTE_TEXT="Loading fonts from external sources might be against privacy regulations in some countries. Loading fonts from a local folder might have a performance impact on your site."
+
+; ===== Header & navigation (Theme tab) =====
+TPL_MOKOONYX_STICKY_LABEL="Sticky Header"
+TPL_MOKOONYX_BACKTOTOP="Back to Top"
+TPL_MOKOONYX_TOC_TITLE="Table of Contents"
+TPL_MOKOONYX_BACKTOTOP_LABEL="Back-to-top Link"
+TPL_MOKOONYX_TOC="Table of Contents"
+
+; ===== Color palette choices (shared) =====
+TPL_MOKOONYX_COLOR_NAME_STANDARD="Standard"
+TPL_MOKOONYX_COLOR_NAME_CUSTOM="Custom"
+; New labels for Theme tab dropdowns
+TPL_MOKOONYX_COLOR_LIGHT_NAME_LABEL="Light colour palette"
+TPL_MOKOONYX_COLOR_LIGHT_NAME_DESC="Select a colour palette for light mode. Standard uses the default blue theme with comprehensive styling for all components. Custom loads media/templates/site/mokoonyx/css/theme/light.custom.css — copy the starter file from templates/mokoonyx/templates/light.custom.css and customise the CSS variables to match your brand. This file is stored in the media folder and will not be overwritten by template updates."
+TPL_MOKOONYX_COLOR_DARK_NAME_LABEL="Dark colour palette"
+TPL_MOKOONYX_COLOR_DARK_NAME_DESC="Select a colour palette for dark mode. Standard uses the default blue theme optimised for dark backgrounds with proper contrast. Custom loads media/templates/site/mokoonyx/css/theme/dark.custom.css — copy the starter file from templates/mokoonyx/templates/dark.custom.css and customise the CSS variables to match your brand. This file is stored in the media folder and will not be overwritten by template updates."
+
+; ===== Theme tab (core feature strings) =====
+TPL_MOKO_THEME_FIELDSET="Theme"
+TPL_MOKO_THEME_SECTION_GENERAL="General"
+TPL_MOKO_THEME_SECTION_VARS="Variables & Palettes"
+TPL_MOKO_THEME_SECTION_TYPO="Typography"
+TPL_MOKO_THEME_SECTION_BRAND="Branding & Icons"
+TPL_MOKO_THEME_SECTION_HEADER="Header & Navigation"
+TPL_MOKO_THEME_SECTION_TOGGLE="Theme Toggle UI"
+
+TPL_MOKO_THEME_ENABLED="Enable theme feature"
+TPL_MOKO_THEME_ENABLED_DESC="Turn the entire light/dark feature on or off."
+TPL_MOKO_THEME_CONTROL_TYPE="Theme Control Type"
+TPL_MOKO_THEME_CONTROL_TYPE_DESC="Choose a visible toggle (Switch or Radios), or no control to follow System only."
+TPL_MOKO_THEME_DEFAULT_CHOICE="Default Choice"
+TPL_MOKO_THEME_DEFAULT_CHOICE_DESC="Initial theme when no user preference is stored."
+TPL_MOKO_THEME_AUTO_DARK="Auto Dark Mode"
+TPL_MOKO_THEME_AUTO_DARK_DESC="Force the site to switch to dark mode automatically. When enabled, the template will override the default and use dark unless the user explicitly selects otherwise."
+TPL_MOKO_THEME_META_COLOR_SCHEME="Add <meta name="color-scheme">"
+TPL_MOKO_THEME_META_COLOR_SCHEME_DESC="Advertise light/dark support for UA controls."
+TPL_MOKO_THEME_META_THEME_COLOR="Add <meta name="theme-color">"
+TPL_MOKO_THEME_META_THEME_COLOR_DESC="Update mobile address bar color."
+TPL_MOKO_THEME_BASE_CSS="Base template CSS"
+TPL_MOKO_THEME_BASE_CSS_DESC="Main stylesheet that consumes variables."
+TPL_MOKO_THEME_BRIDGE="Sync data-bs-theme with data-aria-theme"
+TPL_MOKO_THEME_BRIDGE_DESC="Keep both attributes in lockstep so Bootstrap and custom CSS stay aligned."
+TPL_MOKO_THEME_FAB_ENABLED="Show floating theme switch"
+TPL_MOKO_THEME_FAB_ENABLED_DESC="Display a persistent, accessible theme toggle."
+TPL_MOKO_THEME_FAB_POS="Floating switch position"
+TPL_MOKO_THEME_FAB_POS_DESC="Screen corner for the toggle."
+
+; ===== Accessibility toolbar =====
+TPL_MOKO_A11Y_TOOLBAR_ENABLED="Accessibility toolbar"
+TPL_MOKO_A11Y_TOOLBAR_ENABLED_DESC="Show a floating accessibility toolbar with text resize and colour inversion controls."
+TPL_MOKO_A11Y_TEXT_RESIZE="Text resize"
+TPL_MOKO_A11Y_TEXT_RESIZE_DESC="Allow visitors to increase or decrease text size."
+TPL_MOKO_A11Y_COLOR_INVERSION="Colour inversion"
+TPL_MOKO_A11Y_COLOR_INVERSION_DESC="Allow visitors to invert page colours for improved readability."
+TPL_MOKO_A11Y_TOOLBAR_POS="Toolbar position"
+TPL_MOKO_A11Y_TOOLBAR_POS_DESC="Screen corner for the accessibility toolbar."
+TPL_MOKO_A11Y_BTN_LABEL="Accessibility options"
+TPL_MOKO_A11Y_TEXT_DECREASE="Decrease text size"
+TPL_MOKO_A11Y_TEXT_RESET="Reset text size"
+TPL_MOKO_A11Y_TEXT_INCREASE="Increase text size"
+TPL_MOKO_A11Y_INVERT_COLORS="Invert colours"
+TPL_MOKO_A11Y_HIGH_CONTRAST="High contrast"
+TPL_MOKO_A11Y_HIGH_CONTRAST_DESC="Allow visitors to boost page contrast for improved readability."
+TPL_MOKO_A11Y_HIGHLIGHT_LINKS="Highlight links"
+TPL_MOKO_A11Y_HIGHLIGHT_LINKS_DESC="Allow visitors to outline all links so they stand out from surrounding text."
+TPL_MOKO_A11Y_READABLE_FONT="Readable font"
+TPL_MOKO_A11Y_READABLE_FONT_DESC="Allow visitors to switch to a clean system font optimised for readability."
+TPL_MOKO_A11Y_PAUSE_ANIMATIONS="Pause animations"
+TPL_MOKO_A11Y_PAUSE_ANIMATIONS_DESC="Allow visitors to stop all CSS animations and transitions."
+
+; ===== CSS Variables tab =====
+TPL_MOKOONYX_CSS_VARS_FIELDSET_LABEL="CSS Variables"
+TPL_MOKOONYX_CSS_VARS_INTRO="All colours, spacing and layout values are driven by CSS custom properties. To override any variable without editing the template, add your overrides to media/templates/site/mokoonyx/css/user.css, or create a custom palette file (see the Theme tab). Variables are scoped to :root[data-bs-theme="light"] or :root[data-bs-theme="dark"] so light and dark values are independent.
"
+
+TPL_MOKOONYX_CSS_VARS_BRAND_LABEL="Brand & Theme Colours"
+TPL_MOKOONYX_CSS_VARS_BRAND_DESC="--color-primary — Primary brand colour (default: #112855)--accent-color-primary — Primary accent (default: #3f8ff0)--accent-color-secondary — Secondary accent"
+
+TPL_MOKOONYX_CSS_VARS_LINKS_LABEL="Links & Link Utilities"
+TPL_MOKOONYX_CSS_VARS_LINKS_DESC="Core link tokens --color-link — Base link colour--color-hover — Base hover colour--link-color / --link-hover-color — Bootstrap link colours--link-decoration — Default text-decoration--link-active-color — Active stateSemantic link utilities (replace {colour} with primary, secondary, success, info, warning, danger, light, dark)--link-{colour}-color — Colour for .link-{colour}--link-{colour}-hover-color — Hover colour"
+
+TPL_MOKOONYX_CSS_VARS_TYPO_LABEL="Typography & Body"
+TPL_MOKOONYX_CSS_VARS_TYPO_DESC="--body-color — Default text colour (default: #22262a)--body-bg — Page background (default: #fff)--body-font-family — Font stack--body-font-size — Base size (default: 1rem)--body-font-weight — Base weight (default: 400)--body-line-height — Line height (default: 1.5)--heading-color — Heading colour (default: inherit)--muted-color — Muted/secondary text (default: #6d757e)--code-color — Inline code colour--emphasis-color — Strong emphasis colour--secondary-color / --tertiary-color — Stepped text opacities--highlight-color / --highlight-bg — <mark> colours--font-sans-serif / --font-monospace — Font stacks"
+
+TPL_MOKOONYX_CSS_VARS_NAV_LABEL="Navigation, Navbar & Offcanvas"
+TPL_MOKOONYX_CSS_VARS_NAV_DESC="Theme nav --nav-bg-color — Navbar background--nav-text-color — Navbar text--mainmenu-nav-link-color — Active nav linkNavbar tokens --navbar-padding-x / --navbar-padding-y — Navbar padding--navbar-brand-font-size — Brand font size--navbar-toggler-border-color — Mobile toggler border--nav-link-padding-x / --nav-link-padding-y — Link padding--nav-link-font-weight — Link weight--nav-link-disabled-color — Disabled link colourOffcanvas --offcanvas-color — Offcanvas text colour--offcanvas-padding-x / --offcanvas-padding-y — Offcanvas padding"
+
+TPL_MOKOONYX_CSS_VARS_LAYOUT_LABEL="Layout & Spacing"
+TPL_MOKOONYX_CSS_VARS_LAYOUT_DESC="--padding-x / --padding-y — Default component padding--nav-toggle-size — Mobile nav toggle button size (default: 3rem)--secondary-bg — Secondary surface background (default: #eaedf0)--tertiary-bg — Tertiary surface background (default: #f9fafb)--hr-color — Horizontal rule colour--border-color-soft — Soft border variant--kbd-bg / --kbd-ink — Keyboard element colours--toc-bg / --toc-ink — Table of contents colours--selection-bg / --selection-ink — Text selection colours--gradient — Bootstrap gradient overlay value--bg-opacity — Background opacity utility base"
+
+TPL_MOKOONYX_CSS_VARS_BP_LABEL="Breakpoints"
+TPL_MOKOONYX_CSS_VARS_BP_DESC="Read-only reference values matching Bootstrap breakpoints.--bp-xs — 0--bp-sm — 576px--bp-md — 768px--bp-lg — 992px--bp-xl — 1200px"
+
+TPL_MOKOONYX_CSS_VARS_BS_LABEL="Bootstrap Semantic Palette"
+TPL_MOKOONYX_CSS_VARS_BS_DESC="These map to Bootstrap components (buttons, alerts, badges). Override to retheme all components at once.--primary — #010156--secondary — #6d757e--success — #448344--info — #30638d--warning — #ad6200--danger — #a51f18--light — #f9fafb--dark — #353b41 Each colour also has an --{color}-rgb variant for use in rgba() expressions."
+
+TPL_MOKOONYX_CSS_VARS_BS_STATES_LABEL="Bootstrap State Colours"
+TPL_MOKOONYX_CSS_VARS_BS_STATES_DESC="Contextual state tokens used by alerts, badges and list groups. Replace {color} with primary, secondary, success, info, warning, danger, light, or dark.--{color}-text-emphasis — High-contrast text on subtle backgrounds--{color}-bg-subtle — Tinted component background--{color}-border-subtle — Tinted component border"
+
+TPL_MOKOONYX_CSS_VARS_ALERT_LIST_LABEL="Alert & List Group Colours"
+TPL_MOKOONYX_CSS_VARS_ALERT_LIST_DESC="Alert link colours — override to adjust link contrast inside .alert-{color} components.--alert-{color}-link-color — e.g. --alert-primary-link-colorList group item colours — contextual surfaces for .list-group-item-{color}.--list-group-item-{color}-color — Text colour--list-group-item-{color}-bg — Background--list-group-item-{color}-active-bg — Active state background"
+
+TPL_MOKOONYX_CSS_VARS_COLORS_LABEL="Standard Colours, Grays & Opacity"
+TPL_MOKOONYX_CSS_VARS_COLORS_DESC="Named colours --blue, --indigo, --purple, --pink, --red, --orange, --yellow, --green, --teal, --cyan, --black, --whiteGray scale --gray-100 through --gray-900 plus --white-rgb and --black-rgbOpacity utilities --opacity-0, --opacity-5, --opacity-10, --opacity-15, --opacity-20, --opacity-25, --opacity-30, --opacity-50, --opacity-75, --opacity-100"
+
+TPL_MOKOONYX_CSS_VARS_HERO_LABEL="Hero / Banner Overlay"
+TPL_MOKOONYX_CSS_VARS_HERO_DESC="Applied to the .custom-hero / .banner-overlay layout. Set on :root[data-bs-theme] so light and dark values are independent.--hero-height — Banner height (default: 70vh)--hero-color — Base text colour--hero-bg-repeat — Background repeat (default: no-repeat)--hero-bg-attachment — Background attachment (default: fixed)--hero-bg-position — Background position (default: top center)--hero-bg-size — Background size (default: cover)--hero-border-bottom — Bottom border (default: solid var(--accent-color-secondary))--hero-overlay-bg — Overlay tint colour (light default: hsla(0,0%,0%,0.1) / dark default: hsla(0,0%,0%,0.3))--hero-overlay-padding — Overlay inner padding (default: 1em)--hero-overlay-text-align — Overlay text alignment (default: center)--hero-overlay-text-color — Overlay text colour"
+
+TPL_MOKOONYX_CSS_VARS_HERO_VARIANTS_LABEL="Hero Variants (.hero#primary / .hero#secondary)"
+TPL_MOKOONYX_CSS_VARS_HERO_VARIANTS_DESC="Two-variant hero system using .hero#primary and .hero#secondary. Each variant resolves its own CSS variable set per theme.Primary variant — homepage, main landing pages (sky blue tint, softer overlay)--hero-primary-bg-color — Fallback background colour--hero-primary-overlay — Gradient overlay tint--hero-primary-color — Text colourSecondary variant — inner pages, events, about (navy overlay, lighter text)--hero-secondary-bg-color — Fallback background colour--hero-secondary-overlay — Gradient overlay tint--hero-secondary-color — Text colourHTML usage: <div class="hero" id="primary" style="background-image:url(...)">"
+
+TPL_MOKOONYX_CSS_VARS_BLOCK_COLORS_LABEL="Block Colour System (top-a / top-b / bottom-a / bottom-b)"
+TPL_MOKOONYX_CSS_VARS_BLOCK_COLORS_DESC="Automatic brand colour palette for modules in top-a, top-b, bottom-a, and bottom-b positions. Colours assigned by :nth-child() order — no classes needed.Slot palette --block-color-1 / --block-text-1 — 1st module--block-color-2 / --block-text-2 — 2nd module--block-color-3 / --block-text-3 — 3rd module--block-color-4 / --block-text-4 — 4th moduleNamed overrides (add an ID to the module HTML to bypass slot colour)--block-highlight-bg / --block-highlight-text — for #block-highlight--block-cta-bg / --block-cta-text — for #block-cta--block-alert-bg / --block-alert-text — for #block-alertPriority: Named ID > Slot colour. No !important needed — specificity handles it."
+
+TPL_MOKOONYX_CSS_VARS_HEADER_LABEL="Header Background"
+TPL_MOKOONYX_CSS_VARS_HEADER_DESC="Controls the background of the topbar/header area.--header-background-image — CSS background-image value (default: built-in SVG pattern)--header-background-attachment — fixed or scroll--header-background-repeat — e.g. repeat, no-repeat--header-background-size — e.g. auto, cover, contain"
+
+TPL_MOKOONYX_CSS_VARS_CONTAINERS_LABEL="Container Backgrounds"
+TPL_MOKOONYX_CSS_VARS_CONTAINERS_DESC="Each layout container has its own background variables. Replace {pos} with: below-topbar, top-a, top-b, sidebar, bottom-a, or bottom-b.--container-{pos}-bg-image — Background image (default: none)--container-{pos}-bg-color — Background colour (default: transparent)--container-{pos}-bg-position — Background position--container-{pos}-bg-attachment — fixed or scroll--container-{pos}-bg-repeat — Repeat behaviour--container-{pos}-bg-size — e.g. cover, auto--container-{pos}-border — Border shorthand--container-{pos}-border-radius — Border radius Also: --container-toc-bg / --container-toc-color for the TOC sidebar."
+
+TPL_MOKOONYX_CSS_VARS_BORDERS_LABEL="Borders"
+TPL_MOKOONYX_CSS_VARS_BORDERS_DESC="--border-width — Default width (default: 1px)--border-style — Default style (default: solid)--border-color — Default border colour (default: #dfe3e7)--border-color-translucent — Semi-transparent border--border-radius — Default radius (default: .25rem)--border-radius-sm — Small radius--border-radius-lg — Large radius--border-radius-xl — Extra large radius--border-radius-xxl — 2XL radius (default: 2rem)--border-radius-pill — Pill radius (default: 50rem)"
+
+TPL_MOKOONYX_CSS_VARS_SHADOWS_LABEL="Shadows & Shadow Tokens"
+TPL_MOKOONYX_CSS_VARS_SHADOWS_DESC="Box shadows --box-shadow — Standard shadow--box-shadow-sm — Subtle shadow--box-shadow-lg — Prominent shadow--box-shadow-inset — Inset shadowShadow colour tokens — used as building blocks by component shadows--shadow-color-light — rgba(black, 0.15)--shadow-color-medium — rgba(black, 0.25)--shadow-color-dark — rgba(black, 0.30)--highlight-translucent — rgba(white, 0.15)"
+
+TPL_MOKOONYX_CSS_VARS_FORMS_LABEL="Focus & Forms"
+TPL_MOKOONYX_CSS_VARS_FORMS_DESC="--focus-ring-width — Keyboard focus ring width (default: .25rem)--focus-ring-opacity — Focus ring opacity--focus-ring-color — Focus ring colour--input-color — Input text colour--input-bg — Input background--input-border-color — Input border colour--input-focus-border-color — Focused border colour--input-focus-box-shadow — Focused input shadow--input-placeholder-color — Placeholder text colour--input-disabled-bg — Disabled input background--input-disabled-border-color — Disabled input border--form-valid-color / --form-valid-border-color — Valid state--form-invalid-color / --form-invalid-border-color — Invalid state"
+
+TPL_MOKOONYX_CSS_VARS_BUTTONS_LABEL="Buttons"
+TPL_MOKOONYX_CSS_VARS_BUTTONS_DESC="Applied on :root for global button defaults:--btn-border-radius — Button border radius--btn-box-shadow — Button box shadow Applied on .btn for base button tokens (overridable per variant):--btn-padding-x / --btn-padding-y — Padding--btn-font-size / --btn-font-weight / --btn-line-height — Typography--btn-color / --btn-bg / --btn-border-color — Default state--btn-hover-color / --btn-hover-bg / --btn-hover-border-color — Hover state--btn-active-color / --btn-active-bg / --btn-active-shadow — Active state--btn-disabled-opacity — Disabled opacity Each .btn-{color} and .btn-outline-{color} class inherits these tokens and sets its own values."
+
+TPL_MOKOONYX_CSS_VARS_CARDS_LABEL="Cards"
+TPL_MOKOONYX_CSS_VARS_CARDS_DESC="--card-spacer-y / --card-spacer-x — Body padding (default: 1rem)--card-title-spacer-y — Title bottom margin (default: 0.5rem)--card-border-width — Border width (default: 1px)--card-border-color — Border colour--card-border-radius — Border radius--card-box-shadow — Card shadow (default: none)--card-cap-padding-y / --card-cap-padding-x — Header/footer padding--card-cap-bg — Header/footer background--card-cap-color — Header/footer text colour--card-color — Body text colour--card-bg — Card background"
+
+TPL_MOKOONYX_CSS_VARS_ACCORDION_LABEL="Accordion"
+TPL_MOKOONYX_CSS_VARS_ACCORDION_DESC="Colours --accordion-color — Panel text colour--accordion-bg — Panel background--accordion-border-color — Border colour--accordion-btn-color — Button text colour--accordion-btn-bg — Button background--accordion-btn-focus-border-color — Button focus border colour--accordion-btn-focus-box-shadow — Button focus ring--accordion-active-color — Active item text colour--accordion-active-bg — Active item backgroundDimensions --accordion-border-width — Border width--accordion-border-radius — Outer border radius--accordion-inner-border-radius — Inner border radius--accordion-btn-padding-x / --accordion-btn-padding-y — Button padding--accordion-body-padding-x / --accordion-body-padding-y — Body paddingIcon & Animation --accordion-btn-icon — Collapse icon (collapsed state)--accordion-btn-icon-width — Icon size--accordion-btn-icon-transform — Icon rotation when expanded--accordion-btn-icon-transition — Icon rotation transition--accordion-btn-active-icon — Icon (expanded state)--accordion-transition — Panel open/close transitionStacking --accordion-zindex — z-index"
+
+TPL_MOKOONYX_CSS_VARS_ALERT_BASE_LABEL="Alert (Base)"
+TPL_MOKOONYX_CSS_VARS_ALERT_BASE_DESC="Colours --alert-color — Alert text colour--alert-bg — Alert background--alert-border-color — Border colour--alert-border — Full border shorthandDimensions --alert-padding-x / --alert-padding-y — Inner padding--alert-margin-bottom — Bottom margin--alert-border-radius — Border radiusNote: per-variant contextual tokens (colours, backgrounds, borders) are covered in the Bootstrap State Colours section above. "
+
+TPL_MOKOONYX_CSS_VARS_BADGE_LABEL="Badge"
+TPL_MOKOONYX_CSS_VARS_BADGE_DESC="Colours --badge-color — Badge text colourTypography --badge-font-size — Font size--badge-font-weight — Font weightDimensions --badge-padding-x / --badge-padding-y — Padding--badge-border-radius — Border radius"
+
+TPL_MOKOONYX_CSS_VARS_BACKDROP_LABEL="Backdrop"
+TPL_MOKOONYX_CSS_VARS_BACKDROP_DESC="Colours --backdrop-bg — Backdrop colour (default: #000)--backdrop-opacity — Backdrop opacity (default: 0.5)Stacking --backdrop-zindex — z-index (default: 1040)"
+
+TPL_MOKOONYX_CSS_VARS_BREADCRUMB_LABEL="Breadcrumb"
+TPL_MOKOONYX_CSS_VARS_BREADCRUMB_DESC="Colours --breadcrumb-bg — Background colour--breadcrumb-divider-color — Divider colour--breadcrumb-item-active-color — Active item colourDimensions --breadcrumb-padding-x / --breadcrumb-padding-y — Container padding--breadcrumb-margin-bottom — Bottom margin--breadcrumb-item-padding-x — Spacing between items--breadcrumb-border-radius — Container border radius"
+
+TPL_MOKOONYX_CSS_VARS_DROPDOWN_MENU_LABEL="Dropdown Menu"
+TPL_MOKOONYX_CSS_VARS_DROPDOWN_MENU_DESC="Colours --dropdown-color — Default text colour--dropdown-bg — Menu background--dropdown-border-color — Border colour--dropdown-divider-bg — Divider colour--dropdown-box-shadow — Menu shadow--dropdown-link-color — Link text colour--dropdown-link-active-color — Active link text colour--dropdown-link-active-bg — Active link background--dropdown-link-disabled-color — Disabled link colour--dropdown-header-color — Header text colourDimensions --dropdown-min-width — Minimum width--dropdown-padding-x / --dropdown-padding-y — Menu padding--dropdown-spacer — Gap from toggle--dropdown-border-width — Border width--dropdown-border-radius — Outer border radius--dropdown-inner-border-radius — Inner border radius--dropdown-divider-margin-y — Divider vertical margin--dropdown-item-padding-x / --dropdown-item-padding-y — Item padding--dropdown-header-padding-x / --dropdown-header-padding-y — Header paddingTypography --dropdown-font-size — Menu font sizeStacking --dropdown-zindex — z-index"
+
+TPL_MOKOONYX_CSS_VARS_LIST_GROUP_LABEL="List Group"
+TPL_MOKOONYX_CSS_VARS_LIST_GROUP_DESC="Colours --list-group-color — Default text colour--list-group-bg — Default background--list-group-border-color — Border colour--list-group-action-color — Clickable item text colour--list-group-action-active-color — Clickable item active text colour--list-group-action-active-bg — Clickable item active background--list-group-disabled-color — Disabled item text colour--list-group-disabled-bg — Disabled item background--list-group-active-color — Active item text colour--list-group-active-bg — Active item background--list-group-active-border-color — Active item border colourDimensions --list-group-border-width — Border width--list-group-border-radius — Border radius--list-group-item-padding-x / --list-group-item-padding-y — Item padding"
+
+TPL_MOKOONYX_CSS_VARS_MODAL_LABEL="Modal"
+TPL_MOKOONYX_CSS_VARS_MODAL_DESC="Colours --modal-color — Modal text colour--modal-bg — Modal background--modal-border-color — Outer border colour--modal-box-shadow — Modal shadow--modal-header-border-color — Header border colour--modal-footer-bg — Footer background--modal-footer-border-color — Footer border colourDimensions --modal-width — Default modal width--modal-padding — Body padding--modal-margin — Outer margin--modal-border-width — Outer border width--modal-border-radius — Outer border radius--modal-inner-border-radius — Inner border radius--modal-header-padding-x / --modal-header-padding-y — Header padding--modal-header-padding — Header padding shorthand--modal-header-border-width — Header border width--modal-title-line-height — Title line height--modal-footer-gap — Footer button gap--modal-footer-border-width — Footer border widthStacking --modal-zindex — z-index"
+
+TPL_MOKOONYX_CSS_VARS_NAV_TABS_LABEL="Nav Tabs"
+TPL_MOKOONYX_CSS_VARS_NAV_TABS_DESC="Colours --nav-tabs-border-color — Tab bar border colour--nav-tabs-link-active-color — Active tab text colour--nav-tabs-link-active-bg — Active tab background--nav-tabs-link-active-border-color — Active tab border colourDimensions --nav-tabs-border-width — Border width--nav-tabs-border-radius — Tab border radius"
+
+TPL_MOKOONYX_CSS_VARS_NAV_PILLS_LABEL="Nav Pills"
+TPL_MOKOONYX_CSS_VARS_NAV_PILLS_DESC="Colours --nav-pills-link-active-color — Active pill text colour--nav-pills-link-active-bg — Active pill backgroundDimensions --nav-pills-border-radius — Pill border radius"
+
+TPL_MOKOONYX_CSS_VARS_PAGINATION_LABEL="Pagination"
+TPL_MOKOONYX_CSS_VARS_PAGINATION_DESC="Colours --pagination-color — Default link colour--pagination-bg — Default background--pagination-border-color — Default border colour--pagination-focus-color — Focused link colour--pagination-focus-bg — Focused background--pagination-focus-box-shadow — Focus ring--pagination-active-color — Active page text colour--pagination-active-bg — Active page background--pagination-active-border-color — Active page border colour--pagination-disabled-color — Disabled link colour--pagination-disabled-bg — Disabled background--pagination-disabled-border-color — Disabled border colourDimensions --pagination-padding-x / --pagination-padding-y — Item padding--pagination-border-width — Border width--pagination-border-radius — Border radiusTypography --pagination-font-size — Font size"
+
+TPL_MOKOONYX_CSS_VARS_POPOVER_LABEL="Popover"
+TPL_MOKOONYX_CSS_VARS_POPOVER_DESC="Colours --popover-bg — Popover background--popover-border-color — Border colour--popover-box-shadow — Popover shadow--popover-header-color — Header text colour--popover-header-bg — Header background--popover-body-color — Body text colour--popover-arrow-border — Arrow border colourDimensions --popover-max-width — Maximum width--popover-border-width — Border width--popover-border-radius — Outer border radius--popover-inner-border-radius — Inner border radius--popover-header-padding-x / --popover-header-padding-y — Header padding--popover-body-padding-x / --popover-body-padding-y — Body padding--popover-arrow-width / --popover-arrow-height — Arrow dimensionsTypography --popover-font-size — Font size--popover-header-font-size — Header font sizeStacking --popover-zindex — z-index"
+
+TPL_MOKOONYX_CSS_VARS_PROGRESS_LABEL="Progress Bar"
+TPL_MOKOONYX_CSS_VARS_PROGRESS_DESC="Colours --progress-bg — Track background--progress-bar-color — Bar text colour--progress-bar-bg — Bar fill colour--progress-box-shadow — Track shadowDimensions --progress-height — Track height--progress-border-radius — Track border radiusTypography --progress-font-size — Label font sizeAnimation --progress-bar-transition — Bar width transition"
+
+TPL_MOKOONYX_CSS_VARS_SPINNER_LABEL="Spinner"
+TPL_MOKOONYX_CSS_VARS_SPINNER_DESC="Dimensions --spinner-width — Spinner width--spinner-height — Spinner height--spinner-vertical-align — Inline vertical alignment--spinner-border-width — Border-style spinner track widthAnimation --spinner-animation-speed — Rotation duration"
+
+TPL_MOKOONYX_CSS_VARS_TABLE_LABEL="Table"
+TPL_MOKOONYX_CSS_VARS_TABLE_DESC="Colours --table-color — Default cell text colour--table-bg — Default cell background--table-border-color — Border colour--table-accent-bg — Accent row background (used by variants)--table-striped-color — Striped row text colour--table-striped-bg — Striped row background--table-active-color — Hovered/active row text colour--table-active-bg — Hovered/active row background"
+
+TPL_MOKOONYX_CSS_VARS_TOAST_LABEL="Toast"
+TPL_MOKOONYX_CSS_VARS_TOAST_DESC="Colours --toast-color — Body text colour--toast-bg — Body background--toast-border-color — Border colour--toast-box-shadow — Toast shadow--toast-header-color — Header text colour--toast-header-bg — Header background--toast-header-border-color — Header border colourDimensions --toast-max-width — Maximum width--toast-padding-x / --toast-padding-y — Body padding--toast-spacing — Gap between stacked toasts--toast-border-width — Border width--toast-border-radius — Border radiusTypography --toast-font-size — Font sizeStacking --toast-zindex — z-index"
+
+TPL_MOKOONYX_CSS_VARS_TOOLTIP_LABEL="Tooltip"
+TPL_MOKOONYX_CSS_VARS_TOOLTIP_DESC="Colours --tooltip-color — Text colour--tooltip-bg — Background--tooltip-opacity — Overall opacityDimensions --tooltip-max-width — Maximum width--tooltip-padding-x / --tooltip-padding-y — Inner padding--tooltip-margin — Offset from target--tooltip-border-radius — Border radius--tooltip-arrow-width / --tooltip-arrow-height — Arrow dimensionsTypography --tooltip-font-size — Font sizeStacking --tooltip-zindex — z-index"
+
+TPL_MOKOONYX_CSS_VARS_COMPONENTS_LABEL="Component & Plugin Colours"
+TPL_MOKOONYX_CSS_VARS_COMPONENTS_DESC="Misc components --mod-finder-link-hover — Smart Search hover background--form-legend-color — Form legend text colour--border-gray — General gray border--subhead-color — Subheading colour--item-list-color — Item list background--notification-badge-bg — Notification badgeTable of Contents (TOC) --toc-link-color — TOC link colour--toc-link-active-color — Active TOC linkChoices.js select --choices-inner-bg — Inner background--choices-dropdown-bg — Dropdown background--choices-item-bg — Tag item background--choices-item-hover-bg — Tag hover--choices-disabled-bg — Disabled state--choices-focused-border — Focused borderTab buttons (taba) --taba-btn-green, --taba-btn-blue, --taba-btn-red, --taba-btn-gray"
+
+TPL_MOKOONYX_CSS_VARS_OFFCANVAS_LABEL="Offcanvas Panel"
+TPL_MOKOONYX_CSS_VARS_OFFCANVAS_DESC="Dimensions --offcanvas-width — Panel width (default: 400px)--offcanvas-height — Panel height for top/bottom variants (default: 30vh)--offcanvas-padding-x / --offcanvas-padding-y — Inner paddingColours --offcanvas-bg — Panel background (default: var(--body-bg))--offcanvas-color — Panel text colour (default: var(--body-color))--offcanvas-border-width / --offcanvas-border-color — Panel border--offcanvas-box-shadow — Drop shadowStacking --offcanvas-zindex — z-index (default: 1045)"
+
+TPL_MOKOONYX_CSS_VARS_VM_LABEL="VirtueMart"
+TPL_MOKOONYX_CSS_VARS_VM_DESC="Surfaces & text --vm-surface / --vm-surface-2 — Card/panel backgrounds--vm-text / --vm-text-strong / --vm-text-muted — Text variants--vm-border — Border colour--vm-price-color — Price text colourLayout & density --vm-container-max-width — Max content width (default: 1200px)--vm-section-gap — Section spacing (default: 2rem)--vm-block-radius / --vm-block-shadow — Block appearanceTypography --vm-category-title-size — Category heading size--vm-product-title-size — Product title size--vm-price-size — Price sizeButtons --vm-btn-primary-bg / --vm-btn-primary-text — Primary button--vm-btn-secondary-bg / --vm-btn-secondary-text — Secondary buttonImage overlay controls --vm-image-overlay-btn-bg / --vm-image-overlay-btn-color — Overlay button appearance"
+
+TPL_MOKOONYX_CSS_VARS_GABLE_LABEL="Gable"
+TPL_MOKOONYX_CSS_VARS_GABLE_DESC="Colour tokens used by the Gable extension.--gab-blue — #0066cc--gab-green — #28a745--gab-red — #dc3545--gab-orange — #fd7e14--gab-gray1 — #495057--gab-gray2 — #6c757d--gab-gray3 — #adb5bd"
+
+TPL_MOKOONYX_CSS_VARS_FOOTER_LABEL="Footer"
+TPL_MOKOONYX_CSS_VARS_FOOTER_DESC="Spacing --footer-padding-top — Top padding (default: 1rem)--footer-padding-bottom — Bottom padding (default: 80px)--footer-grid-padding-y — Grid vertical padding (default: 2.5rem)--footer-grid-padding-x — Grid horizontal padding (default: 0.5em)"
+
+; ===== Theme Preview tab =====
+TPL_MOKOONYX_THEME_PREVIEW_FIELDSET_LABEL="Theme Preview"
+TPL_MOKOONYX_THEME_PREVIEW_INTRO="Live preview of all CSS variables, hero variants, block colours, and Bootstrap components rendered with your active theme. Use the Toggle Light / Dark button inside the preview to switch modes. This page is also available as a standalone file at templates/mokoonyx/templates/theme-test.html.
"
+TPL_MOKOONYX_THEME_PREVIEW_FRAME=""
+
+; ===== Misc =====
+MOD_BREADCRUMBS_HERE="YOU ARE HERE:"
+
+JGLOBAL_OFFLINE="Offline"
diff --git a/src/language/en-GB/tpl_mokoonyx.sys.ini b/src/language/en-GB/tpl_mokoonyx.sys.ini
new file mode 100644
index 0000000..daff00a
--- /dev/null
+++ b/src/language/en-GB/tpl_mokoonyx.sys.ini
@@ -0,0 +1,31 @@
+; Copyright (C) 2025 Moko Consulting
+;
+; This file is part of a Moko Consulting project.
+;
+; SPDX-License-Identifier: GPL-3.0-or-later
+;
+TPL_MOKOONYX="MokoOnyx Site template"
+TPL_MOKOONYX_GOOGLE_FIELDSET_LABEL="Google"
+TPL_MOKOONYX_DRAWERS_FIELDSET_LABEL="Drawers"
+TPL_MOKOONYX_MOD_MENU_LAYOUT_COLLAPSE_METISMENU="Collapsible Dropdown"
+TPL_MOKOONYX_MOD_MENU_LAYOUT_DROPDOWN_METISMENU="Dropdown"
+TPL_MOKOONYX_POSITION_BANNER="Banner"
+TPL_MOKOONYX_POSITION_BELOW_TOP="Below Topbar"
+TPL_MOKOONYX_POSITION_BRAND_ASIDE="Brand Aside"
+TPL_MOKOONYX_POSITION_BOTTOM_A="Bottom-A"
+TPL_MOKOONYX_POSITION_BOTTOM_B="Bottom-B"
+TPL_MOKOONYX_POSITION_BREADCRUMBS="Breadcrumbs"
+TPL_MOKOONYX_POSITION_DEBUG="Debug"
+TPL_MOKOONYX_POSITION_FOOTER="Footer"
+TPL_MOKOONYX_POSITION_MAIN_BOTTOM="Main-bottom"
+TPL_MOKOONYX_POSITION_MAIN_TOP="Main-top"
+TPL_MOKOONYX_POSITION_MENU="Menu"
+TPL_MOKOONYX_POSITION_SEARCH="Search"
+TPL_MOKOONYX_POSITION_SIDEBAR_LEFT="Sidebar-left"
+TPL_MOKOONYX_POSITION_SIDEBAR_RIGHT="Sidebar-right"
+TPL_MOKOONYX_POSITION_TOP_A="Top-a"
+TPL_MOKOONYX_POSITION_TOP_B="Top-b"
+TPL_MOKOONYX_POSITION_TOPBAR="Top Bar"
+TPL_MOKOONYX_POSITION_DRAWER_LEFT="Drawer-Left"
+TPL_MOKOONYX_POSITION_DRAWER_RIGHT="Drawer-Right"
+TPL_MOKOONYX_XML_DESCRIPTION="MokoOnyx Template Description MokoOnyx continues Joomla’s tradition of space-themed default templates— building on the legacy of Solarflare (Joomla 1.0), Milkyway (Joomla 1.5), and Protostar (Joomla 3.0).
This template is a customized fork of the Cassiopeia template introduced in Joomla 4, preserving its modern, accessible, and mobile-first foundation while introducing new stylistic enhancements and structural refinements specifically tailored for use by Moko Consulting.
Custom Colour Themes Starter palette files are included with the template. To create a custom colour scheme, copy templates/mokoonyx/templates/light.custom.css to media/templates/site/mokoonyx/css/theme/light.custom.css, or templates/mokoonyx/templates/dark.custom.css to media/templates/site/mokoonyx/css/theme/dark.custom.css. Customise the CSS variables to match your brand, then activate your palette in System → Site Templates → MokoOnyx → Theme tab by selecting "Custom" for the Light or Dark Mode Palette. A full variable reference is available in the CSS Variables tab in template options.
Custom CSS & JavaScript For site-specific styles and scripts that should survive template updates, create the following files:
media/templates/site/mokoonyx/css/user.css — loaded on every page for custom CSS overrides. media/templates/site/mokoonyx/js/user.js — loaded on every page for custom JavaScript. These files are gitignored and will not be overwritten by template updates.
Code Attribution This template is based on the original Cassiopeia template developed by the Joomla! Project and released under the GNU General Public License.
Modifications and enhancements have been made by Moko Consulting in accordance with open-source licensing standards.
It includes integration with Bootstrap TOC , an open-source table of contents generator by A. Feld, licensed under the MIT License.
All third-party libraries and assets remain the property of their respective authors and are credited within their source files where applicable.
"
diff --git a/src/language/en-US/index.html b/src/language/en-US/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/language/en-US/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/language/en-US/tpl_mokoonyx.ini b/src/language/en-US/tpl_mokoonyx.ini
new file mode 100644
index 0000000..0175c48
--- /dev/null
+++ b/src/language/en-US/tpl_mokoonyx.ini
@@ -0,0 +1,273 @@
+; Copyright (C) 2025 Moko Consulting
+;
+; This file is part of a Moko Consulting project.
+;
+; SPDX-License-Identifier: GPL-3.0-or-later
+
+; ===== System / layout =====
+TPL_MOKOONYX_DEVELOPMENTMODE_LABEL="Development Mode"
+TPL_MOKOONYX_DEVELOPMENTMODE_DESC="When enabled, unminified CSS and JavaScript files are loaded for easier debugging. When disabled, minified assets are served for faster page loads. Google Tag Manager and Google Analytics may also be disabled in development mode."
+TPL_MOKOONYX_FLUID_LABEL="Layout"
+TPL_MOKOONYX_STATIC="Static"
+TPL_MOKOONYX_FLUID="Fluid"
+
+; ===== Custom Code tab =====
+TPL_MOKOONYX_CUSTOM_CODE_FIELDSET="Custom Code"
+TPL_MOKOONYX_CUSTOM_HEAD_START_LABEL="Custom Head: Start"
+TPL_MOKOONYX_CUSTOM_HEAD_START_DESC="This content will be inserted at the beginning of the <head> tag"
+TPL_MOKOONYX_CUSTOM_HEAD_END_LABEL="Custom Head: End"
+TPL_MOKOONYX_CUSTOM_HEAD_END_DESC="This content will be inserted at the end of the <head> tag"
+TPL_MOKOONYX_OFFLINEEMBED_LABEL="Offline Page Embed Code"
+TPL_MOKOONYX_OFFLINEEMBED_DESC="In addition to the 'Offline message' defined in 'Global Configuration', this will be displayed on the offline page.Use for Mailchimp code and Social Icons "
+
+; ===== Drawers =====
+TPL_MOKOONYX_DRAWERS_FIELDSET_LABEL="Drawers"
+TPL_MOKOONYX_DRAWER_LEFT_ICON_LABEL="Drawer Left Icon CSS"
+TPL_MOKOONYX_DRAWER_LEFT_ICON_DESC="Enter the Font-Awesome class for the left drawer toggle (e.g. 'fas fa-chevron-left')."
+TPL_MOKOONYX_DRAWER_RIGHT_ICON_LABEL="Drawer Right Icon CSS"
+TPL_MOKOONYX_DRAWER_RIGHT_ICON_DESC="Enter the Font-Awesome class for the right drawer toggle (e.g. 'fas fa-chevron-right')."
+
+; ===== Favicon =====
+TPL_MOKOONYX_FAVICON_FIELDSET_LABEL="Favicon"
+TPL_MOKOONYX_FAVICON_NOTE="Upload a square PNG image (recommended 512×512 or larger). The template will automatically generate all required favicon sizes including ICO, Apple Touch Icon (180×180), and Android icons (192×192, 512×512). Generated files are cached in images/favicons/.
"
+TPL_MOKOONYX_FAVICON_SOURCE_LABEL="Favicon Source Image"
+TPL_MOKOONYX_FAVICON_SOURCE_DESC="Select a square PNG image to use as the site favicon. Recommended size: 512×512 pixels or larger."
+
+; ===== Google =====
+TPL_MOKOONYX_GOOGLE_FIELDSET_LABEL="Google"
+TPL_MOKOONYX_GOOGLE_NOTE_TEXT="PLEASE NOTE: If fields are left blank, relative Google features will not be used"
+TPL_MOKOONYX_GOOGLETAGMANAGER_LABEL="Use Google Tag Manager?"
+TPL_MOKOONYX_GOOGLETAGMANAGER_DESC="Do you want to use Google Tag Manager? More information on Google Tag Manager can be found here. "
+TPL_MOKOONYX_GOOGLETAGMANAGERID_LABEL="Google Tag Manager ID"
+TPL_MOKOONYX_GOOGLETAGMANAGERID_DESC="Begins with 'GTM-'"
+TPL_MOKOONYX_GOOGLEANALYTICS_LABEL="Use Google Analytics?"
+TPL_MOKOONYX_GOOGLEANALYTICS_DESC="Do you want to use Google Analytics? More information on Google Analytics can be found here. "
+TPL_MOKOONYX_GOOGLEANALYTICSID_LABEL="Google Analytics ID"
+TPL_MOKOONYX_GOOGLEANALYTICSID_DESC="Begins with 'G-'"
+TPL_MOKOONYX_GOOGLESITEKEY_LABEL="Google Search Console Verification"
+TPL_MOKOONYX_GOOGLESITEKEY_DESC="Paste the content value from the <meta name="google-site-verification"> tag. Find this in Google Search Console under Ownership Verification → HTML tag method."
+
+; ===== Branding & icons (Theme tab) =====
+TPL_MOKOONYX_BRAND_LABEL="Brand"
+TPL_MOKOONYX_LOGO_LABEL="Logo"
+TPL_MOKOONYX_TITLE="Title (alternative to logo)"
+TPL_MOKOONYX_TAGLINE_LABEL="Tagline"
+TPL_MOKOONYX_TAGLINE_DESC="Optional text to show as a subheading"
+TPL_MOKOONYX_FA7KITCODE_LABEL="Font Awesome 7 Kit Unique Code"
+TPL_MOKOONYX_FA7KITCODE_DESC="If left blank, Font Awesome 7 Free will be used. Copy the unique Kit embed code above and paste it into the <head> of your project's HTML file or template.More information at the Font Awesome website. "
+
+; ===== Typography (Theme tab) =====
+TPL_MOKOONYX_FONT_LABEL="Fonts Scheme"
+TPL_MOKOONYX_FONT_LABEL_DESC="Select a font scheme for your site. Local fonts are loaded from the template folder, while web fonts are loaded from external sources (Google Fonts). The default is Roboto (local). See the note below for important privacy and performance considerations."
+TPL_MOKOONYX_FONT_GROUP_LOCAL="Fonts from Folder"
+TPL_MOKOONYX_FONT_GROUP_WEB="Fonts from Web"
+TPL_MOKOONYX_FONT_NOTE_TEXT="Loading fonts from external sources might be against privacy regulations in some countries. Loading fonts from a local folder might have a performance impact on your site."
+
+; ===== Header & navigation (Theme tab) =====
+TPL_MOKOONYX_STICKY_LABEL="Sticky Header"
+TPL_MOKOONYX_BACKTOTOP="Back to Top"
+TPL_MOKOONYX_TOC_TITLE="Table of Contents"
+TPL_MOKOONYX_BACKTOTOP_LABEL="Back-to-top Link"
+TPL_MOKOONYX_TOC="Table of Contents"
+
+; ===== Color palette choices (shared) =====
+TPL_MOKOONYX_COLOR_NAME_STANDARD="Standard"
+TPL_MOKOONYX_COLOR_NAME_CUSTOM="Custom"
+; New labels for Theme tab dropdowns
+TPL_MOKOONYX_COLOR_LIGHT_NAME_LABEL="Light color palette"
+TPL_MOKOONYX_COLOR_LIGHT_NAME_DESC="Select a color palette for light mode. Standard uses the default blue theme with comprehensive styling for all components. Custom loads media/templates/site/mokoonyx/css/theme/light.custom.css — copy the starter file from templates/mokoonyx/templates/light.custom.css and customize the CSS variables to match your brand. This file is stored in the media folder and will not be overwritten by template updates."
+TPL_MOKOONYX_COLOR_DARK_NAME_LABEL="Dark color palette"
+TPL_MOKOONYX_COLOR_DARK_NAME_DESC="Select a color palette for dark mode. Standard uses the default blue theme optimized for dark backgrounds with proper contrast. Custom loads media/templates/site/mokoonyx/css/theme/dark.custom.css — copy the starter file from templates/mokoonyx/templates/dark.custom.css and customize the CSS variables to match your brand. This file is stored in the media folder and will not be overwritten by template updates."
+
+; ===== Theme tab (core feature strings) =====
+TPL_MOKO_THEME_FIELDSET="Theme"
+TPL_MOKO_THEME_SECTION_GENERAL="General"
+TPL_MOKO_THEME_SECTION_VARS="Variables & Palettes"
+TPL_MOKO_THEME_SECTION_TYPO="Typography"
+TPL_MOKO_THEME_SECTION_BRAND="Branding & Icons"
+TPL_MOKO_THEME_SECTION_HEADER="Header & Navigation"
+TPL_MOKO_THEME_SECTION_TOGGLE="Theme Toggle UI"
+
+TPL_MOKO_THEME_ENABLED="Enable theme feature"
+TPL_MOKO_THEME_ENABLED_DESC="Turn the entire light/dark feature on or off."
+TPL_MOKO_THEME_CONTROL_TYPE="Theme Control Type"
+TPL_MOKO_THEME_CONTROL_TYPE_DESC="Choose a visible toggle (Switch or Radios), or no control to follow System only."
+TPL_MOKO_THEME_DEFAULT_CHOICE="Default Choice"
+TPL_MOKO_THEME_DEFAULT_CHOICE_DESC="Initial theme when no user preference is stored."
+TPL_MOKO_THEME_AUTO_DARK="Auto Dark Mode"
+TPL_MOKO_THEME_AUTO_DARK_DESC="Force the site to switch to dark mode automatically. When enabled, the template will override the default and use dark unless the user explicitly selects otherwise."
+TPL_MOKO_THEME_META_COLOR_SCHEME="Add <meta name="color-scheme">"
+TPL_MOKO_THEME_META_COLOR_SCHEME_DESC="Advertise light/dark support for UA controls."
+TPL_MOKO_THEME_META_THEME_COLOR="Add <meta name="theme-color">"
+TPL_MOKO_THEME_META_THEME_COLOR_DESC="Update mobile address bar color."
+TPL_MOKO_THEME_BASE_CSS="Base template CSS"
+TPL_MOKO_THEME_BASE_CSS_DESC="Main stylesheet that consumes variables."
+TPL_MOKO_THEME_BRIDGE="Sync data-bs-theme with data-aria-theme"
+TPL_MOKO_THEME_BRIDGE_DESC="Keep both attributes in lockstep so Bootstrap and custom CSS stay aligned."
+TPL_MOKO_THEME_FAB_ENABLED="Show floating theme switch"
+TPL_MOKO_THEME_FAB_ENABLED_DESC="Display a persistent, accessible theme toggle."
+TPL_MOKO_THEME_FAB_POS="Floating switch position"
+TPL_MOKO_THEME_FAB_POS_DESC="Screen corner for the toggle."
+
+; ===== Accessibility toolbar =====
+TPL_MOKO_A11Y_TOOLBAR_ENABLED="Accessibility toolbar"
+TPL_MOKO_A11Y_TOOLBAR_ENABLED_DESC="Show a floating accessibility toolbar with text resize and color inversion controls."
+TPL_MOKO_A11Y_TEXT_RESIZE="Text resize"
+TPL_MOKO_A11Y_TEXT_RESIZE_DESC="Allow visitors to increase or decrease text size."
+TPL_MOKO_A11Y_COLOR_INVERSION="Color inversion"
+TPL_MOKO_A11Y_COLOR_INVERSION_DESC="Allow visitors to invert page colors for improved readability."
+TPL_MOKO_A11Y_TOOLBAR_POS="Toolbar position"
+TPL_MOKO_A11Y_TOOLBAR_POS_DESC="Screen corner for the accessibility toolbar."
+TPL_MOKO_A11Y_BTN_LABEL="Accessibility options"
+TPL_MOKO_A11Y_TEXT_DECREASE="Decrease text size"
+TPL_MOKO_A11Y_TEXT_RESET="Reset text size"
+TPL_MOKO_A11Y_TEXT_INCREASE="Increase text size"
+TPL_MOKO_A11Y_INVERT_COLORS="Invert colors"
+TPL_MOKO_A11Y_HIGH_CONTRAST="High contrast"
+TPL_MOKO_A11Y_HIGH_CONTRAST_DESC="Allow visitors to boost page contrast for improved readability."
+TPL_MOKO_A11Y_HIGHLIGHT_LINKS="Highlight links"
+TPL_MOKO_A11Y_HIGHLIGHT_LINKS_DESC="Allow visitors to outline all links so they stand out from surrounding text."
+TPL_MOKO_A11Y_READABLE_FONT="Readable font"
+TPL_MOKO_A11Y_READABLE_FONT_DESC="Allow visitors to switch to a clean system font optimized for readability."
+TPL_MOKO_A11Y_PAUSE_ANIMATIONS="Pause animations"
+TPL_MOKO_A11Y_PAUSE_ANIMATIONS_DESC="Allow visitors to stop all CSS animations and transitions."
+
+; ===== CSS Variables tab =====
+TPL_MOKOONYX_CSS_VARS_FIELDSET_LABEL="CSS Variables"
+TPL_MOKOONYX_CSS_VARS_INTRO="All colors, spacing and layout values are driven by CSS custom properties. To override any variable without editing the template, add your overrides to media/templates/site/mokoonyx/css/user.css, or create a custom palette file (see the Theme tab). Variables are scoped to :root[data-bs-theme="light"] or :root[data-bs-theme="dark"] so light and dark values are independent.
"
+
+TPL_MOKOONYX_CSS_VARS_BRAND_LABEL="Brand & Theme Colors"
+TPL_MOKOONYX_CSS_VARS_BRAND_DESC="--color-primary — Primary brand color (default: #112855)--accent-color-primary — Primary accent (default: #3f8ff0)--accent-color-secondary — Secondary accent"
+
+TPL_MOKOONYX_CSS_VARS_LINKS_LABEL="Links & Link Utilities"
+TPL_MOKOONYX_CSS_VARS_LINKS_DESC="Core link tokens --color-link — Base link color--color-hover — Base hover color--link-color / --link-hover-color — Bootstrap link colors--link-decoration — Default text-decoration--link-active-color — Active stateSemantic link utilities (replace {color} with primary, secondary, success, info, warning, danger, light, dark)--link-{color}-color — Color for .link-{color}--link-{color}-hover-color — Hover color"
+
+TPL_MOKOONYX_CSS_VARS_TYPO_LABEL="Typography & Body"
+TPL_MOKOONYX_CSS_VARS_TYPO_DESC="--body-color — Default text color (default: #22262a)--body-bg — Page background (default: #fff)--body-font-family — Font stack--body-font-size — Base size (default: 1rem)--body-font-weight — Base weight (default: 400)--body-line-height — Line height (default: 1.5)--heading-color — Heading color (default: inherit)--muted-color — Muted/secondary text (default: #6d757e)--code-color — Inline code color--emphasis-color — Strong emphasis color--secondary-color / --tertiary-color — Stepped text opacities--highlight-color / --highlight-bg — <mark> colors--font-sans-serif / --font-monospace — Font stacks"
+
+TPL_MOKOONYX_CSS_VARS_NAV_LABEL="Navigation, Navbar & Offcanvas"
+TPL_MOKOONYX_CSS_VARS_NAV_DESC="Theme nav --nav-bg-color — Navbar background--nav-text-color — Navbar text--mainmenu-nav-link-color — Active nav linkNavbar tokens --navbar-padding-x / --navbar-padding-y — Navbar padding--navbar-brand-font-size — Brand font size--navbar-toggler-border-color — Mobile toggler border--nav-link-padding-x / --nav-link-padding-y — Link padding--nav-link-font-weight — Link weight--nav-link-disabled-color — Disabled link colorOffcanvas --offcanvas-color — Offcanvas text color--offcanvas-padding-x / --offcanvas-padding-y — Offcanvas padding"
+
+TPL_MOKOONYX_CSS_VARS_LAYOUT_LABEL="Layout & Spacing"
+TPL_MOKOONYX_CSS_VARS_LAYOUT_DESC="--padding-x / --padding-y — Default component padding--nav-toggle-size — Mobile nav toggle button size (default: 3rem)--secondary-bg — Secondary surface background (default: #eaedf0)--tertiary-bg — Tertiary surface background (default: #f9fafb)--hr-color — Horizontal rule color--border-color-soft — Soft border variant--kbd-bg / --kbd-ink — Keyboard element colors--toc-bg / --toc-ink — Table of contents colors--selection-bg / --selection-ink — Text selection colors--gradient — Bootstrap gradient overlay value--bg-opacity — Background opacity utility base"
+
+TPL_MOKOONYX_CSS_VARS_BP_LABEL="Breakpoints"
+TPL_MOKOONYX_CSS_VARS_BP_DESC="Read-only reference values matching Bootstrap breakpoints.--bp-xs — 0--bp-sm — 576px--bp-md — 768px--bp-lg — 992px--bp-xl — 1200px"
+
+TPL_MOKOONYX_CSS_VARS_BS_LABEL="Bootstrap Semantic Palette"
+TPL_MOKOONYX_CSS_VARS_BS_DESC="These map to Bootstrap components (buttons, alerts, badges). Override to retheme all components at once.--primary — #010156--secondary — #6d757e--success — #448344--info — #30638d--warning — #ad6200--danger — #a51f18--light — #f9fafb--dark — #353b41 Each color also has an --{color}-rgb variant for use in rgba() expressions."
+
+TPL_MOKOONYX_CSS_VARS_BS_STATES_LABEL="Bootstrap State Colors"
+TPL_MOKOONYX_CSS_VARS_BS_STATES_DESC="Contextual state tokens used by alerts, badges and list groups. Replace {color} with primary, secondary, success, info, warning, danger, light, or dark.--{color}-text-emphasis — High-contrast text on subtle backgrounds--{color}-bg-subtle — Tinted component background--{color}-border-subtle — Tinted component border"
+
+TPL_MOKOONYX_CSS_VARS_ALERT_LIST_LABEL="Alert & List Group Colors"
+TPL_MOKOONYX_CSS_VARS_ALERT_LIST_DESC="Alert link colors — override to adjust link contrast inside .alert-{color} components.--alert-{color}-link-color — e.g. --alert-primary-link-colorList group item colors — contextual surfaces for .list-group-item-{color}.--list-group-item-{color}-color — Text color--list-group-item-{color}-bg — Background--list-group-item-{color}-active-bg — Active state background"
+
+TPL_MOKOONYX_CSS_VARS_COLORS_LABEL="Standard Colors, Grays & Opacity"
+TPL_MOKOONYX_CSS_VARS_COLORS_DESC="Named colors --blue, --indigo, --purple, --pink, --red, --orange, --yellow, --green, --teal, --cyan, --black, --whiteGray scale --gray-100 through --gray-900 plus --white-rgb and --black-rgbOpacity utilities --opacity-0, --opacity-5, --opacity-10, --opacity-15, --opacity-20, --opacity-25, --opacity-30, --opacity-50, --opacity-75, --opacity-100"
+
+TPL_MOKOONYX_CSS_VARS_HERO_LABEL="Hero / Banner Overlay"
+TPL_MOKOONYX_CSS_VARS_HERO_DESC="Applied to the .custom-hero / .banner-overlay layout. Set on :root[data-bs-theme] so light and dark values are independent.--hero-height — Banner height (default: 70vh)--hero-color — Base text color--hero-bg-repeat — Background repeat (default: no-repeat)--hero-bg-attachment — Background attachment (default: fixed)--hero-bg-position — Background position (default: top center)--hero-bg-size — Background size (default: cover)--hero-border-bottom — Bottom border (default: solid var(--accent-color-secondary))--hero-overlay-bg — Overlay tint color (light default: hsla(0,0%,0%,0.1) / dark default: hsla(0,0%,0%,0.3))--hero-overlay-padding — Overlay inner padding (default: 1em)--hero-overlay-text-align — Overlay text alignment (default: center)--hero-overlay-text-color — Overlay text color"
+
+TPL_MOKOONYX_CSS_VARS_HERO_VARIANTS_LABEL="Hero Variants (.hero#primary / .hero#secondary)"
+TPL_MOKOONYX_CSS_VARS_HERO_VARIANTS_DESC="Two-variant hero system using .hero#primary and .hero#secondary. Each variant resolves its own CSS variable set per theme.Primary variant — homepage, main landing pages (sky blue tint, softer overlay)--hero-primary-bg-color — Fallback background color--hero-primary-overlay — Gradient overlay tint--hero-primary-color — Text colorSecondary variant — inner pages, events, about (navy overlay, lighter text)--hero-secondary-bg-color — Fallback background color--hero-secondary-overlay — Gradient overlay tint--hero-secondary-color — Text colorHTML usage: <div class="hero" id="primary" style="background-image:url(...)">"
+
+TPL_MOKOONYX_CSS_VARS_BLOCK_COLORS_LABEL="Block Color System (top-a / top-b / bottom-a / bottom-b)"
+TPL_MOKOONYX_CSS_VARS_BLOCK_COLORS_DESC="Automatic brand color palette for modules in top-a, top-b, bottom-a, and bottom-b positions. Colors assigned by :nth-child() order — no classes needed.Slot palette --block-color-1 / --block-text-1 — 1st module--block-color-2 / --block-text-2 — 2nd module--block-color-3 / --block-text-3 — 3rd module--block-color-4 / --block-text-4 — 4th moduleNamed overrides (add an ID to the module HTML to bypass slot color)--block-highlight-bg / --block-highlight-text — for #block-highlight--block-cta-bg / --block-cta-text — for #block-cta--block-alert-bg / --block-alert-text — for #block-alertPriority: Named ID > Slot color. No !important needed — specificity handles it."
+
+TPL_MOKOONYX_CSS_VARS_HEADER_LABEL="Header Background"
+TPL_MOKOONYX_CSS_VARS_HEADER_DESC="Controls the background of the topbar/header area.--header-background-image — CSS background-image value (default: built-in SVG pattern)--header-background-attachment — fixed or scroll--header-background-repeat — e.g. repeat, no-repeat--header-background-size — e.g. auto, cover, contain"
+
+TPL_MOKOONYX_CSS_VARS_CONTAINERS_LABEL="Container Backgrounds"
+TPL_MOKOONYX_CSS_VARS_CONTAINERS_DESC="Each layout container has its own background variables. Replace {pos} with: below-topbar, top-a, top-b, sidebar, bottom-a, or bottom-b.--container-{pos}-bg-image — Background image (default: none)--container-{pos}-bg-color — Background color (default: transparent)--container-{pos}-bg-position — Background position--container-{pos}-bg-attachment — fixed or scroll--container-{pos}-bg-repeat — Repeat behavior--container-{pos}-bg-size — e.g. cover, auto--container-{pos}-border — Border shorthand--container-{pos}-border-radius — Border radius Also: --container-toc-bg / --container-toc-color for the TOC sidebar."
+
+TPL_MOKOONYX_CSS_VARS_BORDERS_LABEL="Borders"
+TPL_MOKOONYX_CSS_VARS_BORDERS_DESC="--border-width — Default width (default: 1px)--border-style — Default style (default: solid)--border-color — Default border color (default: #dfe3e7)--border-color-translucent — Semi-transparent border--border-radius — Default radius (default: .25rem)--border-radius-sm — Small radius--border-radius-lg — Large radius--border-radius-xl — Extra large radius--border-radius-xxl — 2XL radius (default: 2rem)--border-radius-pill — Pill radius (default: 50rem)"
+
+TPL_MOKOONYX_CSS_VARS_SHADOWS_LABEL="Shadows & Shadow Tokens"
+TPL_MOKOONYX_CSS_VARS_SHADOWS_DESC="Box shadows --box-shadow — Standard shadow--box-shadow-sm — Subtle shadow--box-shadow-lg — Prominent shadow--box-shadow-inset — Inset shadowShadow color tokens — used as building blocks by component shadows--shadow-color-light — rgba(black, 0.15)--shadow-color-medium — rgba(black, 0.25)--shadow-color-dark — rgba(black, 0.30)--highlight-translucent — rgba(white, 0.15)"
+
+TPL_MOKOONYX_CSS_VARS_FORMS_LABEL="Focus & Forms"
+TPL_MOKOONYX_CSS_VARS_FORMS_DESC="--focus-ring-width — Keyboard focus ring width (default: .25rem)--focus-ring-opacity — Focus ring opacity--focus-ring-color — Focus ring color--input-color — Input text color--input-bg — Input background--input-border-color — Input border color--input-focus-border-color — Focused border color--input-focus-box-shadow — Focused input shadow--input-placeholder-color — Placeholder text color--input-disabled-bg — Disabled input background--input-disabled-border-color — Disabled input border--form-valid-color / --form-valid-border-color — Valid state--form-invalid-color / --form-invalid-border-color — Invalid state"
+
+TPL_MOKOONYX_CSS_VARS_BUTTONS_LABEL="Buttons"
+TPL_MOKOONYX_CSS_VARS_BUTTONS_DESC="Applied on :root for global button defaults:--btn-border-radius — Button border radius--btn-box-shadow — Button box shadow Applied on .btn for base button tokens (overridable per variant):--btn-padding-x / --btn-padding-y — Padding--btn-font-size / --btn-font-weight / --btn-line-height — Typography--btn-color / --btn-bg / --btn-border-color — Default state--btn-hover-color / --btn-hover-bg / --btn-hover-border-color — Hover state--btn-active-color / --btn-active-bg / --btn-active-shadow — Active state--btn-disabled-opacity — Disabled opacity Each .btn-{color} and .btn-outline-{color} class inherits these tokens and sets its own values."
+
+TPL_MOKOONYX_CSS_VARS_CARDS_LABEL="Cards"
+TPL_MOKOONYX_CSS_VARS_CARDS_DESC="--card-spacer-y / --card-spacer-x — Body padding (default: 1rem)--card-title-spacer-y — Title bottom margin (default: 0.5rem)--card-border-width — Border width (default: 1px)--card-border-color — Border color--card-border-radius — Border radius--card-box-shadow — Card shadow (default: none)--card-cap-padding-y / --card-cap-padding-x — Header/footer padding--card-cap-bg — Header/footer background--card-cap-color — Header/footer text color--card-color — Body text color--card-bg — Card background"
+
+TPL_MOKOONYX_CSS_VARS_ACCORDION_LABEL="Accordion"
+TPL_MOKOONYX_CSS_VARS_ACCORDION_DESC="Colors --accordion-color — Panel text color--accordion-bg — Panel background--accordion-border-color — Border color--accordion-btn-color — Button text color--accordion-btn-bg — Button background--accordion-btn-focus-border-color — Button focus border color--accordion-btn-focus-box-shadow — Button focus ring--accordion-active-color — Active item text color--accordion-active-bg — Active item backgroundDimensions --accordion-border-width — Border width--accordion-border-radius — Outer border radius--accordion-inner-border-radius — Inner border radius--accordion-btn-padding-x / --accordion-btn-padding-y — Button padding--accordion-body-padding-x / --accordion-body-padding-y — Body paddingIcon & Animation --accordion-btn-icon — Collapse icon (collapsed state)--accordion-btn-icon-width — Icon size--accordion-btn-icon-transform — Icon rotation when expanded--accordion-btn-icon-transition — Icon rotation transition--accordion-btn-active-icon — Icon (expanded state)--accordion-transition — Panel open/close transitionStacking --accordion-zindex — z-index"
+
+TPL_MOKOONYX_CSS_VARS_ALERT_BASE_LABEL="Alert (Base)"
+TPL_MOKOONYX_CSS_VARS_ALERT_BASE_DESC="Colors --alert-color — Alert text color--alert-bg — Alert background--alert-border-color — Border color--alert-border — Full border shorthandDimensions --alert-padding-x / --alert-padding-y — Inner padding--alert-margin-bottom — Bottom margin--alert-border-radius — Border radiusNote: per-variant contextual tokens (colors, backgrounds, borders) are covered in the Bootstrap State Colors section above. "
+
+TPL_MOKOONYX_CSS_VARS_BADGE_LABEL="Badge"
+TPL_MOKOONYX_CSS_VARS_BADGE_DESC="Colors --badge-color — Badge text colorTypography --badge-font-size — Font size--badge-font-weight — Font weightDimensions --badge-padding-x / --badge-padding-y — Padding--badge-border-radius — Border radius"
+
+TPL_MOKOONYX_CSS_VARS_BACKDROP_LABEL="Backdrop"
+TPL_MOKOONYX_CSS_VARS_BACKDROP_DESC="Colors --backdrop-bg — Backdrop color (default: #000)--backdrop-opacity — Backdrop opacity (default: 0.5)Stacking --backdrop-zindex — z-index (default: 1040)"
+
+TPL_MOKOONYX_CSS_VARS_BREADCRUMB_LABEL="Breadcrumb"
+TPL_MOKOONYX_CSS_VARS_BREADCRUMB_DESC="Colors --breadcrumb-bg — Background color--breadcrumb-divider-color — Divider color--breadcrumb-item-active-color — Active item colorDimensions --breadcrumb-padding-x / --breadcrumb-padding-y — Container padding--breadcrumb-margin-bottom — Bottom margin--breadcrumb-item-padding-x — Spacing between items--breadcrumb-border-radius — Container border radius"
+
+TPL_MOKOONYX_CSS_VARS_DROPDOWN_MENU_LABEL="Dropdown Menu"
+TPL_MOKOONYX_CSS_VARS_DROPDOWN_MENU_DESC="Colors --dropdown-color — Default text color--dropdown-bg — Menu background--dropdown-border-color — Border color--dropdown-divider-bg — Divider color--dropdown-box-shadow — Menu shadow--dropdown-link-color — Link text color--dropdown-link-active-color — Active link text color--dropdown-link-active-bg — Active link background--dropdown-link-disabled-color — Disabled link color--dropdown-header-color — Header text colorDimensions --dropdown-min-width — Minimum width--dropdown-padding-x / --dropdown-padding-y — Menu padding--dropdown-spacer — Gap from toggle--dropdown-border-width — Border width--dropdown-border-radius — Outer border radius--dropdown-inner-border-radius — Inner border radius--dropdown-divider-margin-y — Divider vertical margin--dropdown-item-padding-x / --dropdown-item-padding-y — Item padding--dropdown-header-padding-x / --dropdown-header-padding-y — Header paddingTypography --dropdown-font-size — Menu font sizeStacking --dropdown-zindex — z-index"
+
+TPL_MOKOONYX_CSS_VARS_LIST_GROUP_LABEL="List Group"
+TPL_MOKOONYX_CSS_VARS_LIST_GROUP_DESC="Colors --list-group-color — Default text color--list-group-bg — Default background--list-group-border-color — Border color--list-group-action-color — Clickable item text color--list-group-action-active-color — Clickable item active text color--list-group-action-active-bg — Clickable item active background--list-group-disabled-color — Disabled item text color--list-group-disabled-bg — Disabled item background--list-group-active-color — Active item text color--list-group-active-bg — Active item background--list-group-active-border-color — Active item border colorDimensions --list-group-border-width — Border width--list-group-border-radius — Border radius--list-group-item-padding-x / --list-group-item-padding-y — Item padding"
+
+TPL_MOKOONYX_CSS_VARS_MODAL_LABEL="Modal"
+TPL_MOKOONYX_CSS_VARS_MODAL_DESC="Colors --modal-color — Modal text color--modal-bg — Modal background--modal-border-color — Outer border color--modal-box-shadow — Modal shadow--modal-header-border-color — Header border color--modal-footer-bg — Footer background--modal-footer-border-color — Footer border colorDimensions --modal-width — Default modal width--modal-padding — Body padding--modal-margin — Outer margin--modal-border-width — Outer border width--modal-border-radius — Outer border radius--modal-inner-border-radius — Inner border radius--modal-header-padding-x / --modal-header-padding-y — Header padding--modal-header-padding — Header padding shorthand--modal-header-border-width — Header border width--modal-title-line-height — Title line height--modal-footer-gap — Footer button gap--modal-footer-border-width — Footer border widthStacking --modal-zindex — z-index"
+
+TPL_MOKOONYX_CSS_VARS_NAV_TABS_LABEL="Nav Tabs"
+TPL_MOKOONYX_CSS_VARS_NAV_TABS_DESC="Colors --nav-tabs-border-color — Tab bar border color--nav-tabs-link-active-color — Active tab text color--nav-tabs-link-active-bg — Active tab background--nav-tabs-link-active-border-color — Active tab border colorDimensions --nav-tabs-border-width — Border width--nav-tabs-border-radius — Tab border radius"
+
+TPL_MOKOONYX_CSS_VARS_NAV_PILLS_LABEL="Nav Pills"
+TPL_MOKOONYX_CSS_VARS_NAV_PILLS_DESC="Colors --nav-pills-link-active-color — Active pill text color--nav-pills-link-active-bg — Active pill backgroundDimensions --nav-pills-border-radius — Pill border radius"
+
+TPL_MOKOONYX_CSS_VARS_PAGINATION_LABEL="Pagination"
+TPL_MOKOONYX_CSS_VARS_PAGINATION_DESC="Colors --pagination-color — Default link color--pagination-bg — Default background--pagination-border-color — Default border color--pagination-focus-color — Focused link color--pagination-focus-bg — Focused background--pagination-focus-box-shadow — Focus ring--pagination-active-color — Active page text color--pagination-active-bg — Active page background--pagination-active-border-color — Active page border color--pagination-disabled-color — Disabled link color--pagination-disabled-bg — Disabled background--pagination-disabled-border-color — Disabled border colorDimensions --pagination-padding-x / --pagination-padding-y — Item padding--pagination-border-width — Border width--pagination-border-radius — Border radiusTypography --pagination-font-size — Font size"
+
+TPL_MOKOONYX_CSS_VARS_POPOVER_LABEL="Popover"
+TPL_MOKOONYX_CSS_VARS_POPOVER_DESC="Colors --popover-bg — Popover background--popover-border-color — Border color--popover-box-shadow — Popover shadow--popover-header-color — Header text color--popover-header-bg — Header background--popover-body-color — Body text color--popover-arrow-border — Arrow border colorDimensions --popover-max-width — Maximum width--popover-border-width — Border width--popover-border-radius — Outer border radius--popover-inner-border-radius — Inner border radius--popover-header-padding-x / --popover-header-padding-y — Header padding--popover-body-padding-x / --popover-body-padding-y — Body padding--popover-arrow-width / --popover-arrow-height — Arrow dimensionsTypography --popover-font-size — Font size--popover-header-font-size — Header font sizeStacking --popover-zindex — z-index"
+
+TPL_MOKOONYX_CSS_VARS_PROGRESS_LABEL="Progress Bar"
+TPL_MOKOONYX_CSS_VARS_PROGRESS_DESC="Colors --progress-bg — Track background--progress-bar-color — Bar text color--progress-bar-bg — Bar fill color--progress-box-shadow — Track shadowDimensions --progress-height — Track height--progress-border-radius — Track border radiusTypography --progress-font-size — Label font sizeAnimation --progress-bar-transition — Bar width transition"
+
+TPL_MOKOONYX_CSS_VARS_SPINNER_LABEL="Spinner"
+TPL_MOKOONYX_CSS_VARS_SPINNER_DESC="Dimensions --spinner-width — Spinner width--spinner-height — Spinner height--spinner-vertical-align — Inline vertical alignment--spinner-border-width — Border-style spinner track widthAnimation --spinner-animation-speed — Rotation duration"
+
+TPL_MOKOONYX_CSS_VARS_TABLE_LABEL="Table"
+TPL_MOKOONYX_CSS_VARS_TABLE_DESC="Colors --table-color — Default cell text color--table-bg — Default cell background--table-border-color — Border color--table-accent-bg — Accent row background (used by variants)--table-striped-color — Striped row text color--table-striped-bg — Striped row background--table-active-color — Hovered/active row text color--table-active-bg — Hovered/active row background"
+
+TPL_MOKOONYX_CSS_VARS_TOAST_LABEL="Toast"
+TPL_MOKOONYX_CSS_VARS_TOAST_DESC="Colors --toast-color — Body text color--toast-bg — Body background--toast-border-color — Border color--toast-box-shadow — Toast shadow--toast-header-color — Header text color--toast-header-bg — Header background--toast-header-border-color — Header border colorDimensions --toast-max-width — Maximum width--toast-padding-x / --toast-padding-y — Body padding--toast-spacing — Gap between stacked toasts--toast-border-width — Border width--toast-border-radius — Border radiusTypography --toast-font-size — Font sizeStacking --toast-zindex — z-index"
+
+TPL_MOKOONYX_CSS_VARS_TOOLTIP_LABEL="Tooltip"
+TPL_MOKOONYX_CSS_VARS_TOOLTIP_DESC="Colors --tooltip-color — Text color--tooltip-bg — Background--tooltip-opacity — Overall opacityDimensions --tooltip-max-width — Maximum width--tooltip-padding-x / --tooltip-padding-y — Inner padding--tooltip-margin — Offset from target--tooltip-border-radius — Border radius--tooltip-arrow-width / --tooltip-arrow-height — Arrow dimensionsTypography --tooltip-font-size — Font sizeStacking --tooltip-zindex — z-index"
+
+TPL_MOKOONYX_CSS_VARS_COMPONENTS_LABEL="Component & Plugin Colors"
+TPL_MOKOONYX_CSS_VARS_COMPONENTS_DESC="Misc components --mod-finder-link-hover — Smart Search hover background--form-legend-color — Form legend text color--border-gray — General gray border--subhead-color — Subheading color--item-list-color — Item list background--notification-badge-bg — Notification badgeTable of Contents (TOC) --toc-link-color — TOC link color--toc-link-active-color — Active TOC linkChoices.js select --choices-inner-bg — Inner background--choices-dropdown-bg — Dropdown background--choices-item-bg — Tag item background--choices-item-hover-bg — Tag hover--choices-disabled-bg — Disabled state--choices-focused-border — Focused borderTab buttons (taba) --taba-btn-green, --taba-btn-blue, --taba-btn-red, --taba-btn-gray"
+
+TPL_MOKOONYX_CSS_VARS_OFFCANVAS_LABEL="Offcanvas Panel"
+TPL_MOKOONYX_CSS_VARS_OFFCANVAS_DESC="Dimensions --offcanvas-width — Panel width (default: 400px)--offcanvas-height — Panel height for top/bottom variants (default: 30vh)--offcanvas-padding-x / --offcanvas-padding-y — Inner paddingColors --offcanvas-bg — Panel background (default: var(--body-bg))--offcanvas-color — Panel text color (default: var(--body-color))--offcanvas-border-width / --offcanvas-border-color — Panel border--offcanvas-box-shadow — Drop shadowStacking --offcanvas-zindex — z-index (default: 1045)"
+
+TPL_MOKOONYX_CSS_VARS_VM_LABEL="VirtueMart"
+TPL_MOKOONYX_CSS_VARS_VM_DESC="Surfaces & text --vm-surface / --vm-surface-2 — Card/panel backgrounds--vm-text / --vm-text-strong / --vm-text-muted — Text variants--vm-border — Border color--vm-price-color — Price text colorLayout & density --vm-container-max-width — Max content width (default: 1200px)--vm-section-gap — Section spacing (default: 2rem)--vm-block-radius / --vm-block-shadow — Block appearanceTypography --vm-category-title-size — Category heading size--vm-product-title-size — Product title size--vm-price-size — Price sizeButtons --vm-btn-primary-bg / --vm-btn-primary-text — Primary button--vm-btn-secondary-bg / --vm-btn-secondary-text — Secondary buttonImage overlay controls --vm-image-overlay-btn-bg / --vm-image-overlay-btn-color — Overlay button appearance"
+
+TPL_MOKOONYX_CSS_VARS_GABLE_LABEL="Gable"
+TPL_MOKOONYX_CSS_VARS_GABLE_DESC="Color tokens used by the Gable extension.--gab-blue — #0066cc--gab-green — #28a745--gab-red — #dc3545--gab-orange — #fd7e14--gab-gray1 — #495057--gab-gray2 — #6c757d--gab-gray3 — #adb5bd"
+
+TPL_MOKOONYX_CSS_VARS_FOOTER_LABEL="Footer"
+TPL_MOKOONYX_CSS_VARS_FOOTER_DESC="Spacing --footer-padding-top — Top padding (default: 1rem)--footer-padding-bottom — Bottom padding (default: 80px)--footer-grid-padding-y — Grid vertical padding (default: 2.5rem)--footer-grid-padding-x — Grid horizontal padding (default: 0.5em)"
+
+; ===== Theme Preview tab =====
+TPL_MOKOONYX_THEME_PREVIEW_FIELDSET_LABEL="Theme Preview"
+TPL_MOKOONYX_THEME_PREVIEW_INTRO="Live preview of all CSS variables, hero variants, block colors, and Bootstrap components rendered with your active theme. Use the Toggle Light / Dark button inside the preview to switch modes. This page is also available as a standalone file at templates/mokoonyx/templates/theme-test.html.
"
+TPL_MOKOONYX_THEME_PREVIEW_FRAME=""
+
+; ===== Misc =====
+MOD_BREADCRUMBS_HERE="YOU ARE HERE:"
+
+JGLOBAL_OFFLINE="Offline"
diff --git a/src/language/en-US/tpl_mokoonyx.sys.ini b/src/language/en-US/tpl_mokoonyx.sys.ini
new file mode 100644
index 0000000..e68fd6a
--- /dev/null
+++ b/src/language/en-US/tpl_mokoonyx.sys.ini
@@ -0,0 +1,31 @@
+; Copyright (C) 2025 Moko Consulting
+;
+; This file is part of a Moko Consulting project.
+;
+; SPDX-License-Identifier: GPL-3.0-or-later
+;
+TPL_MOKOONYX="MokoOnyx Site template"
+TPL_MOKOONYX_GOOGLE_FIELDSET_LABEL="Google"
+TPL_MOKOONYX_DRAWERS_FIELDSET_LABEL="Drawers"
+TPL_MOKOONYX_MOD_MENU_LAYOUT_COLLAPSE_METISMENU="Collapsible Dropdown"
+TPL_MOKOONYX_MOD_MENU_LAYOUT_DROPDOWN_METISMENU="Dropdown"
+TPL_MOKOONYX_POSITION_BANNER="Banner"
+TPL_MOKOONYX_POSITION_BELOW_TOPBAR="Below Topbar"
+TPL_MOKOONYX_POSITION_BRAND_ASIDE="Brand Aside"
+TPL_MOKOONYX_POSITION_BOTTOM_A="Bottom-A"
+TPL_MOKOONYX_POSITION_BOTTOM_B="Bottom-B"
+TPL_MOKOONYX_POSITION_BREADCRUMBS="Breadcrumbs"
+TPL_MOKOONYX_POSITION_DEBUG="Debug"
+TPL_MOKOONYX_POSITION_FOOTER="Footer"
+TPL_MOKOONYX_POSITION_MAIN_BOTTOM="Main-bottom"
+TPL_MOKOONYX_POSITION_MAIN_TOP="Main-top"
+TPL_MOKOONYX_POSITION_MENU="Menu"
+TPL_MOKOONYX_POSITION_SEARCH="Search"
+TPL_MOKOONYX_POSITION_SIDEBAR_LEFT="Sidebar-left"
+TPL_MOKOONYX_POSITION_SIDEBAR_RIGHT="Sidebar-right"
+TPL_MOKOONYX_POSITION_TOP_A="Top-a"
+TPL_MOKOONYX_POSITION_TOP_B="Top-b"
+TPL_MOKOONYX_POSITION_TOPBAR="Top Bar"
+TPL_MOKOONYX_POSITION_DRAWER_LEFT="Drawer-Left"
+TPL_MOKOONYX_POSITION_DRAWER_RIGHT="Drawer-Right"
+TPL_MOKOONYX_XML_DESCRIPTION="MokoOnyx Template Description MokoOnyx continues Joomla’s tradition of space-themed default templates— building on the legacy of Solarflare (Joomla 1.0), Milkyway (Joomla 1.5), and Protostar (Joomla 3.0).
This template is a customized fork of the Cassiopeia template introduced in Joomla 4, preserving its modern, accessible, and mobile-first foundation while introducing new stylistic enhancements and structural refinements specifically tailored for use by Moko Consulting.
Custom Color Themes Starter palette files are included with the template. To create a custom color scheme, copy templates/mokoonyx/templates/light.custom.css to media/templates/site/mokoonyx/css/theme/light.custom.css, or templates/mokoonyx/templates/dark.custom.css to media/templates/site/mokoonyx/css/theme/dark.custom.css. Customize the CSS variables to match your brand, then activate your palette in System → Site Templates → MokoOnyx → Theme tab by selecting "Custom" for the Light or Dark Mode Palette. A full variable reference is available in the CSS Variables tab in template options.
Custom CSS & JavaScript For site-specific styles and scripts that should survive template updates, create the following files:
media/templates/site/mokoonyx/css/user.css — loaded on every page for custom CSS overrides. media/templates/site/mokoonyx/js/user.js — loaded on every page for custom JavaScript. These files are gitignored and will not be overwritten by template updates.
Code Attribution This template is based on the original Cassiopeia template developed by the Joomla! Project and released under the GNU General Public License.
Modifications and enhancements have been made by Moko Consulting in accordance with open-source licensing standards.
It includes integration with Bootstrap TOC , an open-source table of contents generator by A. Feld, licensed under the MIT License.
All third-party libraries and assets remain the property of their respective authors and are credited within their source files where applicable.
"
diff --git a/src/language/index.html b/src/language/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/language/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/media/css/a11y-high-contrast.css b/src/media/css/a11y-high-contrast.css
new file mode 100644
index 0000000..dac45c4
--- /dev/null
+++ b/src/media/css/a11y-high-contrast.css
@@ -0,0 +1,227 @@
+@charset "UTF-8";
+/* Copyright (C) 2026 Moko Consulting
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * FILE INFORMATION
+ * DEFGROUP: Joomla.Template.Site
+ * INGROUP: MokoOnyx.Accessibility
+ * REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx
+ * PATH: ./media/css/a11y-high-contrast.css
+ * VERSION: 03.09.14
+ * BRIEF: High-contrast stylesheet for accessibility toolbar
+ */
+
+/* ===================================================================
+ * HIGH CONTRAST MODE
+ * Applied when .a11y-high-contrast is on .
+ * Overrides theme variables to maximise contrast ratios (WCAG AAA).
+ * =================================================================== */
+
+/* ── Light mode high contrast ─────────────────────────────────────── */
+:root[data-bs-theme="light"].a11y-high-contrast {
+ --body-color: #000;
+ --body-color-rgb: 0, 0, 0;
+ --body-bg: #fff;
+ --body-bg-rgb: 255, 255, 255;
+ --heading-color: #000;
+ --emphasis-color: #000;
+ --secondary-color: #000000bf;
+ --tertiary-color: #00000080;
+ --muted-color: #333;
+
+ /* Links — strong blue on white */
+ --color-link: #0000ee;
+ --link-color: #0000ee;
+ --link-color-rgb: 0, 0, 238;
+ --color-hover: #cc0000;
+ --link-hover-color: #cc0000;
+ --link-hover-color-rgb: 204, 0, 0;
+
+ /* Borders — visible on all backgrounds */
+ --border-color: #000;
+ --border-color-soft: #333;
+
+ /* Backgrounds */
+ --secondary-bg: #e0e0e0;
+ --secondary-bg-rgb: 224, 224, 224;
+ --tertiary-bg: #f0f0f0;
+ --tertiary-bg-rgb: 240, 240, 240;
+
+ /* Navigation */
+ --nav-bg-color: #000;
+ --nav-text-color: #fff;
+ --mainmenu-nav-link-color: #fff;
+
+ /* Buttons */
+ --btn-color: #fff;
+ --btn-bg: #000;
+ --btn-border-color: #000;
+ --btn-hover-color: #000;
+ --btn-hover-bg: #ffff00;
+ --btn-hover-border-color: #000;
+ --btn-active-color: #000;
+ --btn-active-bg: #ffff00;
+ --btn-active-border-color: #000;
+
+ /* Forms */
+ --input-color: #000;
+ --input-bg: #fff;
+ --input-border-color: #000;
+ --input-focus-color: #000;
+ --input-focus-bg: #ffffcc;
+ --input-focus-border-color: #0000ee;
+ --input-placeholder-color: #555;
+
+ /* Cards */
+ --card-border-color: #000;
+ --card-bg: #fff;
+ --card-cap-bg: #e0e0e0;
+
+ /* Tables */
+ --table-color: #000;
+ --table-bg: #fff;
+ --table-border-color: #000;
+ --table-striped-bg: #f0f0f0;
+ --table-hover-bg: #ffff99;
+
+ /* Alerts */
+ --alert-border-width: 2px;
+
+ /* Code */
+ --code-color: #000;
+ --code-bg-color: #ffffcc;
+
+ /* Selection */
+ --selection-bg: #0000ee;
+ --selection-ink: #fff;
+
+ /* Focus indicator — always visible */
+ --focus-ring-color: #0000ee;
+ --focus-ring-width: 3px;
+}
+
+/* ── Dark mode high contrast ──────────────────────────────────────── */
+:root[data-bs-theme="dark"].a11y-high-contrast {
+ --body-color: #fff;
+ --body-color-rgb: 255, 255, 255;
+ --body-bg: #000;
+ --body-bg-rgb: 0, 0, 0;
+ --heading-color: #fff;
+ --emphasis-color: #fff;
+ --secondary-color: #ffffffbf;
+ --tertiary-color: #ffffff80;
+ --muted-color: #ccc;
+
+ /* Links — bright yellow on black */
+ --color-link: #ffff00;
+ --link-color: #ffff00;
+ --link-color-rgb: 255, 255, 0;
+ --color-hover: #00ffff;
+ --link-hover-color: #00ffff;
+ --link-hover-color-rgb: 0, 255, 255;
+
+ /* Borders */
+ --border-color: #fff;
+ --border-color-soft: #ccc;
+
+ /* Backgrounds */
+ --secondary-bg: #1a1a1a;
+ --secondary-bg-rgb: 26, 26, 26;
+ --tertiary-bg: #111;
+ --tertiary-bg-rgb: 17, 17, 17;
+
+ /* Navigation */
+ --nav-bg-color: #000;
+ --nav-text-color: #fff;
+ --mainmenu-nav-link-color: #ffff00;
+
+ /* Buttons */
+ --btn-color: #000;
+ --btn-bg: #ffff00;
+ --btn-border-color: #ffff00;
+ --btn-hover-color: #000;
+ --btn-hover-bg: #00ffff;
+ --btn-hover-border-color: #00ffff;
+ --btn-active-color: #000;
+ --btn-active-bg: #00ffff;
+ --btn-active-border-color: #00ffff;
+
+ /* Forms */
+ --input-color: #fff;
+ --input-bg: #000;
+ --input-border-color: #fff;
+ --input-focus-color: #fff;
+ --input-focus-bg: #1a1a1a;
+ --input-focus-border-color: #ffff00;
+ --input-placeholder-color: #aaa;
+
+ /* Cards */
+ --card-border-color: #fff;
+ --card-bg: #000;
+ --card-cap-bg: #1a1a1a;
+
+ /* Tables */
+ --table-color: #fff;
+ --table-bg: #000;
+ --table-border-color: #fff;
+ --table-striped-bg: #111;
+ --table-hover-bg: #333;
+
+ /* Alerts */
+ --alert-border-width: 2px;
+
+ /* Code */
+ --code-color: #00ff00;
+ --code-bg-color: #1a1a1a;
+
+ /* Selection */
+ --selection-bg: #ffff00;
+ --selection-ink: #000;
+
+ /* Focus indicator */
+ --focus-ring-color: #ffff00;
+ --focus-ring-width: 3px;
+}
+
+/* ── Shared high-contrast overrides (both modes) ──────────────────── */
+.a11y-high-contrast * {
+ border-color: var(--border-color) !important;
+}
+
+.a11y-high-contrast *:focus-visible {
+ outline: var(--focus-ring-width, 3px) solid var(--focus-ring-color, #0000ee) !important;
+ outline-offset: 2px !important;
+}
+
+.a11y-high-contrast img {
+ outline: 2px solid var(--border-color);
+}
+
+.a11y-high-contrast a {
+ text-decoration: underline !important;
+ text-decoration-thickness: 2px !important;
+}
+
+.a11y-high-contrast button,
+.a11y-high-contrast .btn,
+.a11y-high-contrast input,
+.a11y-high-contrast select,
+.a11y-high-contrast textarea {
+ border-width: 2px !important;
+ border-style: solid !important;
+}
+
+.a11y-high-contrast .badge,
+.a11y-high-contrast .alert {
+ border: 2px solid var(--border-color) !important;
+}
+
+/* Ensure disabled states are still distinguishable */
+.a11y-high-contrast [disabled],
+.a11y-high-contrast .disabled {
+ opacity: .5 !important;
+ text-decoration: line-through !important;
+}
diff --git a/src/media/css/editor.css b/src/media/css/editor.css
new file mode 100644
index 0000000..0488a2a
--- /dev/null
+++ b/src/media/css/editor.css
@@ -0,0 +1,79 @@
+@charset "UTF-8";
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/* STYLES FOR JOOMLA! EDITOR */
+body {
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: 1.5;
+ color: #22262a;
+ background-color: #fff;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ margin-top: 0;
+ margin-bottom: 0.5rem;
+ font-weight: 700;
+ line-height: 1.2;
+}
+
+h1 {
+ font-size: calc(1.375rem + 1.5vw);
+}
+
+h2 {
+ font-size: calc(1.325rem + 0.9vw);
+}
+
+h3 {
+ font-size: calc(1.3rem + 0.6vw);
+}
+
+h4 {
+ font-size: calc(1.275rem + 0.3vw);
+}
+
+h5 {
+ font-size: 1.25rem;
+}
+
+h6 {
+ font-size: 1rem;
+}
+
+a {
+ text-decoration: none;
+}
+a:link {
+ color: #224faa;
+}
+a:hover {
+ color: #424077;
+}
+
+p {
+ margin-top: 0;
+ margin-bottom: 1rem;
+}
+
+/* STYLES FOR JOOMLA! EDITOR */
+hr#system-readmore {
+ color: #f00;
+ border: #f00 dashed 1px;
+}
+
+span[lang] {
+ padding: 2px;
+ border: 1px dashed #bbb;
+}
+span[lang]:after {
+ font-size: smaller;
+ color: #f00;
+ vertical-align: super;
+ content: attr(lang);
+}
diff --git a/src/media/css/editor.min.css b/src/media/css/editor.min.css
new file mode 100644
index 0000000..3422b9a
--- /dev/null
+++ b/src/media/css/editor.min.css
@@ -0,0 +1 @@
+@charset "UTF-8";body{font-size:1rem;font-weight:400;line-height:1.5;color:#22262a;background-color:#fff}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:700;line-height:1.2}h1{font-size:calc(1.375rem + 1.5vw)}h2{font-size:calc(1.325rem + .9vw)}h3{font-size:calc(1.3rem + .6vw)}h4{font-size:calc(1.275rem + .3vw)}h5{font-size:1.25rem}h6{font-size:1rem}a{text-decoration:none}a:link{color:#224faa}a:hover{color:#424077}p{margin-top:0;margin-bottom:1rem}hr#system-readmore{color:red;border:1px dashed red}span[lang]{padding:2px;border:1px dashed #bbb}span[lang]:after{font-size:smaller;color:red;vertical-align:super;content:attr(lang)}
\ No newline at end of file
diff --git a/src/media/css/fonts/fredoka.css b/src/media/css/fonts/fredoka.css
new file mode 100644
index 0000000..206ceb3
--- /dev/null
+++ b/src/media/css/fonts/fredoka.css
@@ -0,0 +1,10 @@
+/* Copyright (C) 2026 Moko Consulting
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ * Fredoka — self-hosted from src/media/fonts/
+ */
+
+@font-face { font-family: 'Fredoka'; font-style: normal; font-weight: 300; font-display: swap; src: url('../../fonts/fredoka-v17-latin-300.woff2') format('woff2'); }
+@font-face { font-family: 'Fredoka'; font-style: normal; font-weight: 400; font-display: swap; src: url('../../fonts/fredoka-v17-latin-regular.woff2') format('woff2'); }
+@font-face { font-family: 'Fredoka'; font-style: normal; font-weight: 500; font-display: swap; src: url('../../fonts/fredoka-v17-latin-500.woff2') format('woff2'); }
+@font-face { font-family: 'Fredoka'; font-style: normal; font-weight: 600; font-display: swap; src: url('../../fonts/fredoka-v17-latin-600.woff2') format('woff2'); }
+@font-face { font-family: 'Fredoka'; font-style: normal; font-weight: 700; font-display: swap; src: url('../../fonts/fredoka-v17-latin-700.woff2') format('woff2'); }
diff --git a/src/media/css/fonts/osaka.css b/src/media/css/fonts/osaka.css
new file mode 100644
index 0000000..1f75ffd
--- /dev/null
+++ b/src/media/css/fonts/osaka.css
@@ -0,0 +1,14 @@
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+@font-face {
+font-family: 'Osaka';
+src: url('../../fonts/osaka-re.ttf') format('truetype');
+font-weight: normal;
+font-style: normal;
+font-display: swap;
+}
diff --git a/src/media/css/fonts/pacifico.css b/src/media/css/fonts/pacifico.css
new file mode 100644
index 0000000..ee29925
--- /dev/null
+++ b/src/media/css/fonts/pacifico.css
@@ -0,0 +1,6 @@
+/* Copyright (C) 2026 Moko Consulting
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ * Pacifico — self-hosted from src/media/fonts/
+ */
+
+@font-face { font-family: 'Pacifico'; font-style: normal; font-weight: 400; font-display: swap; src: url('../../fonts/pacifico-v23-latin-regular.woff2') format('woff2'); }
diff --git a/src/media/css/fonts/roboto.css b/src/media/css/fonts/roboto.css
new file mode 100644
index 0000000..45ce183
--- /dev/null
+++ b/src/media/css/fonts/roboto.css
@@ -0,0 +1,23 @@
+/* Copyright (C) 2026 Moko Consulting
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ * Roboto — self-hosted from src/media/fonts/
+ */
+
+@font-face { font-family: 'Roboto'; font-style: normal; font-weight: 100; font-display: swap; src: url('../../fonts/roboto-v51-latin-100.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: italic; font-weight: 100; font-display: swap; src: url('../../fonts/roboto-v51-latin-100italic.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: normal; font-weight: 200; font-display: swap; src: url('../../fonts/roboto-v51-latin-200.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: italic; font-weight: 200; font-display: swap; src: url('../../fonts/roboto-v51-latin-200italic.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: normal; font-weight: 300; font-display: swap; src: url('../../fonts/roboto-v51-latin-300.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: italic; font-weight: 300; font-display: swap; src: url('../../fonts/roboto-v51-latin-300italic.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: normal; font-weight: 400; font-display: swap; src: url('../../fonts/roboto-v51-latin-regular.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: italic; font-weight: 400; font-display: swap; src: url('../../fonts/roboto-v51-latin-italic.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: normal; font-weight: 500; font-display: swap; src: url('../../fonts/roboto-v51-latin-500.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: italic; font-weight: 500; font-display: swap; src: url('../../fonts/roboto-v51-latin-500italic.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: normal; font-weight: 600; font-display: swap; src: url('../../fonts/roboto-v51-latin-600.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: italic; font-weight: 600; font-display: swap; src: url('../../fonts/roboto-v51-latin-600italic.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: normal; font-weight: 700; font-display: swap; src: url('../../fonts/roboto-v51-latin-700.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: italic; font-weight: 700; font-display: swap; src: url('../../fonts/roboto-v51-latin-700italic.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: normal; font-weight: 800; font-display: swap; src: url('../../fonts/roboto-v51-latin-800.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: italic; font-weight: 800; font-display: swap; src: url('../../fonts/roboto-v51-latin-800italic.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: normal; font-weight: 900; font-display: swap; src: url('../../fonts/roboto-v51-latin-900.woff2') format('woff2'); }
+@font-face { font-family: 'Roboto'; font-style: italic; font-weight: 900; font-display: swap; src: url('../../fonts/roboto-v51-latin-900italic.woff2') format('woff2'); }
diff --git a/src/media/css/index.html b/src/media/css/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/media/css/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/media/css/offline.css b/src/media/css/offline.css
new file mode 100644
index 0000000..6e5ab58
--- /dev/null
+++ b/src/media/css/offline.css
@@ -0,0 +1,258 @@
+/* Copyright (C) 2026 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/* === Offline Page — Full-viewport background with centered overlay card === */
+
+.moko-offline-wrap {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 2rem 1rem;
+ color: #fff;
+ font-family: var(--body-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif);
+ /* Background: offline_image set inline, or fall back to header background */
+ background-color: var(--color-primary, #112855);
+ background-image: var(--header-background-image, none);
+ background-position: var(--header-background-position, center);
+ background-attachment: var(--header-background-attachment, fixed);
+ background-repeat: no-repeat;
+ background-size: cover;
+}
+
+/* Dark theme: overlay to darken the background */
+:root[data-bs-theme="dark"] .moko-offline-wrap {
+ position: relative;
+}
+
+:root[data-bs-theme="dark"] .moko-offline-wrap::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.5);
+ z-index: 0;
+}
+
+/* === Centered Card Overlay === */
+.moko-offline-card {
+ width: 100%;
+ max-width: 720px;
+ background: var(--offline-card-bg, rgba(0, 0, 0, 0.6));
+ backdrop-filter: blur(8px);
+ -webkit-backdrop-filter: blur(8px);
+ border-radius: 0.875rem;
+ padding: 2.5rem 2rem;
+ text-align: center;
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
+}
+
+@media (min-width: 768px) {
+ .moko-offline-card {
+ padding: 3rem;
+ }
+}
+
+@media (max-width: 575.98px) {
+ .moko-offline-wrap {
+ padding: 1rem 0.75rem;
+ }
+
+ .moko-offline-card {
+ padding: 2rem 1.25rem;
+ }
+}
+
+/* === Logo header area === */
+.moko-offline-brand {
+ display: block;
+ text-align: center;
+ text-decoration: none;
+ color: #fff;
+ margin-bottom: 1.5rem;
+}
+
+.moko-offline-brand:hover {
+ color: var(--accent-color-primary, #3f8ff0);
+}
+
+.moko-offline-brand img {
+ max-width: 100%;
+ height: auto;
+}
+
+.moko-offline-brand .site-title {
+ display: block;
+ font-size: 2rem;
+ font-weight: 700;
+ font-family: 'Osaka', var(--body-font-family, sans-serif);
+ color: var(--accent-color-secondary, #6fb3ff);
+}
+
+.moko-offline-brand .brand-tagline {
+ display: block;
+ opacity: 0.7;
+ font-size: 0.9rem;
+ margin-top: 0.25rem;
+}
+
+/* === Offline Message === */
+.moko-offline-message {
+ margin-bottom: 1.5rem;
+}
+
+.moko-offline-message h1 {
+ font-size: 1.5rem;
+ font-weight: 700;
+ color: #fff;
+ margin-bottom: 0.5rem;
+ text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
+}
+
+.moko-offline-message p {
+ color: rgba(255, 255, 255, 0.85);
+ line-height: 1.6;
+ margin: 0;
+}
+
+/* === Offline Module Position === */
+.moko-offline-modules {
+ margin-bottom: 1.5rem;
+ text-align: left;
+}
+
+/* === Copyright Footer === */
+.moko-offline-copyright {
+ font-size: 0.8rem;
+ color: rgba(255, 255, 255, 0.45);
+ margin-top: 1.5rem;
+ padding-top: 1rem;
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.moko-offline-copyright a {
+ color: rgba(255, 255, 255, 0.6);
+ text-decoration: underline;
+}
+
+.moko-offline-copyright a:hover {
+ color: #fff;
+}
+
+/* === Login Accordion (translucent on overlay) === */
+.moko-offline-card .accordion {
+ text-align: left;
+}
+
+.moko-offline-card .accordion-item {
+ background: transparent;
+ border-color: rgba(255, 255, 255, 0.15);
+}
+
+.moko-offline-card .accordion-button {
+ background: transparent;
+ color: rgba(255, 255, 255, 0.8);
+ font-size: 0.9rem;
+ padding: 0.75rem 1rem;
+}
+
+.moko-offline-card .accordion-button:not(.collapsed) {
+ background: rgba(255, 255, 255, 0.05);
+ color: #fff;
+ box-shadow: none;
+}
+
+.moko-offline-card .accordion-button::after {
+ filter: invert(1) brightness(2);
+}
+
+.moko-offline-card .accordion-body {
+ background: transparent;
+ padding: 1rem;
+}
+
+/* === Form Controls (glass effect) === */
+.moko-offline-card .form-control {
+ background-color: rgba(255, 255, 255, 0.1);
+ border-color: rgba(255, 255, 255, 0.2);
+ color: #fff;
+}
+
+.moko-offline-card .form-control::placeholder {
+ color: rgba(255, 255, 255, 0.4);
+}
+
+.moko-offline-card .form-control:focus {
+ background-color: rgba(255, 255, 255, 0.15);
+ border-color: var(--accent-color-primary, #3f8ff0);
+ color: #fff;
+ box-shadow: 0 0 0 0.25rem rgba(63, 143, 240, 0.25);
+}
+
+.moko-offline-card .form-label {
+ color: rgba(255, 255, 255, 0.8);
+ font-size: 0.875rem;
+}
+
+.moko-offline-card .form-check-label {
+ color: rgba(255, 255, 255, 0.7);
+}
+
+.moko-offline-card .form-check-input {
+ background-color: rgba(255, 255, 255, 0.1);
+ border-color: rgba(255, 255, 255, 0.3);
+}
+
+.moko-offline-card .form-check-input:checked {
+ background-color: var(--accent-color-primary, #3f8ff0);
+ border-color: var(--accent-color-primary, #3f8ff0);
+}
+
+/* === Button === */
+.moko-offline-card .btn-primary {
+ background-color: var(--color-primary, #112855);
+ border-color: rgba(255, 255, 255, 0.15);
+ color: #fff;
+}
+
+.moko-offline-card .btn-primary:hover {
+ background-color: var(--accent-color-primary, #3f8ff0);
+ border-color: var(--accent-color-primary, #3f8ff0);
+}
+
+/* === Links === */
+.moko-offline-card a {
+ color: var(--accent-color-primary, #3f8ff0);
+}
+
+.moko-offline-card a:hover {
+ color: #fff;
+}
+
+/* === Joomla system messages === */
+.moko-offline-messages {
+ width: 100%;
+ max-width: 720px;
+ margin-bottom: 1rem;
+}
+
+/* === Skip Link === */
+.skip-link {
+ position: absolute;
+ left: -9999px;
+ top: auto;
+ width: 1px;
+ height: 1px;
+ overflow: hidden;
+}
+
+.skip-link:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ padding: 0.5rem 1rem;
+}
diff --git a/src/media/css/system/index.html b/src/media/css/system/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/media/css/system/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/media/css/system/searchtools/index.html b/src/media/css/system/searchtools/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/media/css/system/searchtools/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/media/css/system/searchtools/searchtools.css b/src/media/css/system/searchtools/searchtools.css
new file mode 100644
index 0000000..1a9bd2d
--- /dev/null
+++ b/src/media/css/system/searchtools/searchtools.css
@@ -0,0 +1,57 @@
+@charset "UTF-8";
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+.js-stools-container-bar {
+ padding: 10px 20px;
+}
+.js-stools-container-bar .btn-toolbar {
+ -webkit-box-pack: end;
+ -ms-flex-pack: end;
+ justify-content: flex-end;
+}
+.js-stools-container-bar .btn-toolbar > * {
+ margin: 4px 0;
+ -webkit-margin-end: 8px;
+ margin-inline-end: 8px;
+}
+.js-stools-container-bar .btn-toolbar .js-stools-btn-clear {
+ background-color: hsl(207, 49%, 37%);
+ border: 0;
+}
+.js-stools-container-bar .ordering-select {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+}
+
+.js-stools-container-filters {
+ display: none;
+ padding: 0 20px;
+ margin-bottom: 20px;
+}
+.js-stools-container-filters-visible {
+ display: grid;
+ grid-gap: 8px;
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
+ padding: 10px;
+ background-color: hsl(0, 0%, 100%);
+}
+.js-stools-container-filters > * {
+ margin: 4px 0;
+ -webkit-margin-end: 8px;
+ margin-inline-end: 8px;
+}
+
+.js-stools-field-list + .js-stools-field-list {
+ -webkit-margin-start: 8px;
+ margin-inline-start: 8px;
+}
+
+.js-stools-field-selector .form-select {
+ width: auto;
+}
diff --git a/src/media/css/template-rtl.css b/src/media/css/template-rtl.css
new file mode 100644
index 0000000..42d6c42
--- /dev/null
+++ b/src/media/css/template-rtl.css
@@ -0,0 +1,4369 @@
+@charset "UTF-8";
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/*!
+ * RTL Overrides for template.css
+ * Strategy: For blocks that contain directional declarations, we emit
+ * [dir="rtl"]-prefixed overrides with left/right swapped and aligned.
+ * This file assumes the base CSS uses logical tokens; only direction-
+ * sensitive rules are mirrored here to keep file size reasonable.
+ */
+
+[dir="rtl"] .table-of-contents-ck-wrap {
+
+ width: 30%;
+ float: left;
+ border: 1px solid var(--color-primary);
+}
+
+[dir="rtl"] .drawer-toggle-left {
+
+ position: fixed;
+ top: 250px;
+ right: 0px;
+ z-index: 1050;
+ background-color: var(--nav-bg-color) !important;
+ color: var(--nav-text-color) !important;
+ padding-left: calc(var(--btn-padding-x)*0.5) !important;
+ padding-right: calc(var(--btn-padding-x)*0.5) !important;
+}
+
+[dir="rtl"] .drawer-toggle-right {
+
+ position: fixed;
+ top: 250px;
+ left: 0px;
+ z-index: 1050;
+ background-color: var(--nav-bg-color) !important;
+ color: var(--nav-text-color) !important;
+ padding-left: calc(var(--btn-padding-x)*0.5) !important;
+ padding-right: calc(var(--btn-padding-x)*0.5) !important;
+}
+
+[dir="rtl"] ol,
+[dir="rtl"] ul {
+
+ padding-left: 2rem;
+}
+
+[dir="rtl"] dd {
+
+ margin-bottom: 0.5rem;
+ margin-left: 0;
+}
+
+[dir="rtl"] caption {
+
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ color: var(--secondary-color);
+ text-align: left;
+}
+
+[dir="rtl"] legend {
+
+ float: left;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 0.5rem;
+ font-size: calc(1.275rem + 0.3vw);
+ line-height: inherit;
+}
+
+[dir="rtl"] }
+
+legend+* {
+
+ clear: left;
+}
+
+[dir="rtl"] }
+
+.list-unstyled {
+
+ padding-left: 0;
+ list-style: none;
+}
+
+[dir="rtl"] .list-inline {
+
+ padding-left: 0;
+ list-style: none;
+}
+
+[dir="rtl"] .list-inline-item:not(:last-child) {
+
+ margin-right: 0.5rem;
+}
+
+[dir="rtl"] .container-component,
+[dir="rtl"] .container,
+[dir="rtl"] .container-fluid,
+[dir="rtl"] .container-xxl,
+[dir="rtl"] .container-xl,
+[dir="rtl"] .container-lg,
+[dir="rtl"] .container-md,
+[dir="rtl"] .container-sm {
+
+ --gutter-x: 1rem;
+ --gutter-y: 0;
+ width: 100%;
+ padding-right: calc(var(--gutter-x) * 0.5);
+ padding-left: calc(var(--gutter-x) * 0.5);
+ margin-right: auto;
+ margin-left: auto;
+ padding-bottom: calc(var(--gutter-x) * 0.5);
+}
+
+[dir="rtl"] }
+
+.row {
+
+ --gutter-x: 1rem;
+ --gutter-y: 0;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ margin-top: calc(-1 * var(--gutter-y));
+ margin-right: calc(-0.5 * var(--gutter-x));
+ margin-left: calc(-0.5 * var(--gutter-x));
+}
+
+[dir="rtl"] .row>* {
+
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
+ width: 100%;
+ max-width: 100%;
+ padding-right: 0;
+ padding-left: 0;
+ margin-top: var(--gutter-y);
+}
+
+[dir="rtl"] .product-container {
+
+ margin-right: calc(var(--gutter-x) * .25);
+ margin-left: calc(var(--gutter-x) * .25);
+ padding-right: calc(var(--gutter-x) * .25);
+ padding-left: calc(var(--gutter-x) * .25);
+ margin-top: var(--gutter-y);
+ //background-color: var(--gray-200);
+ -webkit-border-radius: var(--border-radius);
+ -moz-border-radius: var(--border-radius);
+ border-radius: var(--border-radius);
+}
+
+[dir="rtl"] .offset-1 {
+
+ margin-left: 8.33333333%;
+}
+
+[dir="rtl"] .offset-2 {
+
+ margin-left: 16.66666667%;
+}
+
+[dir="rtl"] .offset-3 {
+
+ margin-left: 25%;
+}
+
+[dir="rtl"] .offset-4 {
+
+ margin-left: 33.33333333%;
+}
+
+[dir="rtl"] .offset-5 {
+
+ margin-left: 41.66666667%;
+}
+
+[dir="rtl"] .offset-6 {
+
+ margin-left: 50%;
+}
+
+[dir="rtl"] .offset-7 {
+
+ margin-left: 58.33333333%;
+}
+
+[dir="rtl"] .offset-8 {
+
+ margin-left: 66.66666667%;
+}
+
+[dir="rtl"] .offset-9 {
+
+ margin-left: 75%;
+}
+
+[dir="rtl"] .offset-10 {
+
+ margin-left: 83.33333333%;
+}
+
+[dir="rtl"] .offset-11 {
+
+ margin-left: 91.66666667%;
+}
+
+[dir="rtl"] .offset-sm-0 {
+
+ margin-left: 0;
+
+}
+
+[dir="rtl"] .offset-sm-1 {
+
+ margin-left: 8.33333333%;
+
+}
+
+[dir="rtl"] .offset-sm-2 {
+
+ margin-left: 16.66666667%;
+
+}
+
+[dir="rtl"] .offset-sm-3 {
+
+ margin-left: 25%;
+
+}
+
+[dir="rtl"] .offset-sm-4 {
+
+ margin-left: 33.33333333%;
+
+}
+
+[dir="rtl"] .offset-sm-5 {
+
+ margin-left: 41.66666667%;
+
+}
+
+[dir="rtl"] .offset-sm-6 {
+
+ margin-left: 50%;
+
+}
+
+[dir="rtl"] .offset-sm-7 {
+
+ margin-left: 58.33333333%;
+
+}
+
+[dir="rtl"] .offset-sm-8 {
+
+ margin-left: 66.66666667%;
+
+}
+
+[dir="rtl"] .offset-sm-9 {
+
+ margin-left: 75%;
+
+}
+
+[dir="rtl"] .offset-sm-10 {
+
+ margin-left: 83.33333333%;
+
+}
+
+[dir="rtl"] .offset-sm-11 {
+
+ margin-left: 91.66666667%;
+
+}
+
+[dir="rtl"] .offset-md-0 {
+
+ margin-left: 0;
+
+}
+
+[dir="rtl"] .offset-md-1 {
+
+ margin-left: 8.33333333%;
+
+}
+
+[dir="rtl"] .offset-md-2 {
+
+ margin-left: 16.66666667%;
+
+}
+
+[dir="rtl"] .offset-md-3 {
+
+ margin-left: 25%;
+
+}
+
+[dir="rtl"] .offset-md-4 {
+
+ margin-left: 33.33333333%;
+
+}
+
+[dir="rtl"] .offset-md-5 {
+
+ margin-left: 41.66666667%;
+
+}
+
+[dir="rtl"] .offset-md-6 {
+
+ margin-left: 50%;
+
+}
+
+[dir="rtl"] .offset-md-7 {
+
+ margin-left: 58.33333333%;
+
+}
+
+[dir="rtl"] .offset-md-8 {
+
+ margin-left: 66.66666667%;
+
+}
+
+[dir="rtl"] .offset-md-9 {
+
+ margin-left: 75%;
+
+}
+
+[dir="rtl"] .offset-md-10 {
+
+ margin-left: 83.33333333%;
+
+}
+
+[dir="rtl"] .offset-md-11 {
+
+ margin-left: 91.66666667%;
+
+}
+
+[dir="rtl"] .offset-lg-0 {
+
+ margin-left: 0;
+
+}
+
+[dir="rtl"] .offset-lg-1 {
+
+ margin-left: 8.33333333%;
+
+}
+
+[dir="rtl"] .offset-lg-2 {
+
+ margin-left: 16.66666667%;
+
+}
+
+[dir="rtl"] .offset-lg-3 {
+
+ margin-left: 25%;
+
+}
+
+[dir="rtl"] .offset-lg-4 {
+
+ margin-left: 33.33333333%;
+
+}
+
+[dir="rtl"] .offset-lg-5 {
+
+ margin-left: 41.66666667%;
+
+}
+
+[dir="rtl"] .offset-lg-6 {
+
+ margin-left: 50%;
+
+}
+
+[dir="rtl"] .offset-lg-7 {
+
+ margin-left: 58.33333333%;
+
+}
+
+[dir="rtl"] .offset-lg-8 {
+
+ margin-left: 66.66666667%;
+
+}
+
+[dir="rtl"] .offset-lg-9 {
+
+ margin-left: 75%;
+
+}
+
+[dir="rtl"] .offset-lg-10 {
+
+ margin-left: 83.33333333%;
+
+}
+
+[dir="rtl"] .offset-lg-11 {
+
+ margin-left: 91.66666667%;
+
+}
+
+[dir="rtl"] .offset-xl-0 {
+
+ margin-left: 0;
+
+}
+
+[dir="rtl"] .offset-xl-1 {
+
+ margin-left: 8.33333333%;
+
+}
+
+[dir="rtl"] .offset-xl-2 {
+
+ margin-left: 16.66666667%;
+
+}
+
+[dir="rtl"] .offset-xl-3 {
+
+ margin-left: 25%;
+
+}
+
+[dir="rtl"] .offset-xl-4 {
+
+ margin-left: 33.33333333%;
+
+}
+
+[dir="rtl"] .offset-xl-5 {
+
+ margin-left: 41.66666667%;
+
+}
+
+[dir="rtl"] .offset-xl-6 {
+
+ margin-left: 50%;
+
+}
+
+[dir="rtl"] .offset-xl-7 {
+
+ margin-left: 58.33333333%;
+
+}
+
+[dir="rtl"] .offset-xl-8 {
+
+ margin-left: 66.66666667%;
+
+}
+
+[dir="rtl"] .offset-xl-9 {
+
+ margin-left: 75%;
+
+}
+
+[dir="rtl"] .offset-xl-10 {
+
+ margin-left: 83.33333333%;
+
+}
+
+[dir="rtl"] .offset-xl-11 {
+
+ margin-left: 91.66666667%;
+
+}
+
+[dir="rtl"] .offset-xxl-0 {
+
+ margin-left: 0;
+
+}
+
+[dir="rtl"] .offset-xxl-1 {
+
+ margin-left: 8.33333333%;
+
+}
+
+[dir="rtl"] .offset-xxl-2 {
+
+ margin-left: 16.66666667%;
+
+}
+
+[dir="rtl"] .offset-xxl-3 {
+
+ margin-left: 25%;
+
+}
+
+[dir="rtl"] .offset-xxl-4 {
+
+ margin-left: 33.33333333%;
+
+}
+
+[dir="rtl"] .offset-xxl-5 {
+
+ margin-left: 41.66666667%;
+
+}
+
+[dir="rtl"] .offset-xxl-6 {
+
+ margin-left: 50%;
+
+}
+
+[dir="rtl"] .offset-xxl-7 {
+
+ margin-left: 58.33333333%;
+
+}
+
+[dir="rtl"] .offset-xxl-8 {
+
+ margin-left: 66.66666667%;
+
+}
+
+[dir="rtl"] .offset-xxl-9 {
+
+ margin-left: 75%;
+
+}
+
+[dir="rtl"] .offset-xxl-10 {
+
+ margin-left: 83.33333333%;
+
+}
+
+[dir="rtl"] .offset-xxl-11 {
+
+ margin-left: 91.66666667%;
+
+}
+
+[dir="rtl"] .form-control-plaintext.form-control-sm,
+[dir="rtl"] .form-control-plaintext.form-control-lg {
+
+ padding-right: 0;
+ padding-left: 0;
+}
+
+[dir="rtl"] .form-select[multiple],
+[dir="rtl"] [multiple].custom-select,
+[dir="rtl"] .form-select[size]:not([size="1"]),
+[dir="rtl"] [size].custom-select:not([size="1"]) {
+
+ padding-right: 1rem;
+ background-image: none;
+}
+
+[dir="rtl"] .form-select-sm {
+
+ padding-top: 0.25rem;
+ padding-bottom: 0.25rem;
+ padding-left: 0.5rem;
+ font-size: 0.875rem;
+ border-radius: 0.2rem;
+}
+
+[dir="rtl"] .form-select-lg {
+
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ padding-left: 1rem;
+ font-size: 1.25rem;
+ border-radius: 0.3rem;
+}
+
+[dir="rtl"] .form-check {
+
+ display: block;
+ min-height: 1.5rem;
+ padding-left: 1.5rem;
+ margin-bottom: 0.125rem;
+}
+
+[dir="rtl"] .form-check .form-check-input {
+
+ float: left;
+ margin-left: -1.5rem;
+}
+
+[dir="rtl"] .form-check-reverse {
+
+ padding-right: 1.5rem;
+ padding-left: 0;
+ text-align: left;
+}
+
+[dir="rtl"] .form-check-reverse .form-check-input {
+
+ float: left;
+ margin-right: -1.5rem;
+ margin-left: 0;
+}
+
+[dir="rtl"] .form-switch {
+
+ padding-left: 2.5rem;
+}
+
+[dir="rtl"] .form-switch .form-check-input {
+
+ width: 2rem;
+ margin-left: -2.5rem;
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");
+ background-position: left center;
+ border-radius: 2rem;
+ -webkit-transition: background-position 0.15s ease-in-out;
+ -o-transition: background-position 0.15s ease-in-out;
+ transition: background-position 0.15s ease-in-out;
+}
+
+[dir="rtl"] .form-switch.form-check-reverse {
+
+ padding-right: 2.5rem;
+ padding-left: 0;
+}
+
+[dir="rtl"] .form-switch.form-check-reverse .form-check-input {
+
+ margin-right: -2.5rem;
+ margin-left: 0;
+}
+
+[dir="rtl"] .form-check-inline {
+
+ display: inline-block;
+ margin-right: 1rem;
+}
+
+[dir="rtl"] .form-floating>label {
+
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 100%;
+ height: 100%;
+ padding: 1rem 1rem;
+ overflow: hidden;
+ text-align: start;
+ -o-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ pointer-events: none;
+ border: 1px solid transparent;
+ -webkit-transform-origin: 0 0;
+ transform-origin: 0 0;
+ -webkit-transition: opacity 0.1s ease-in-out, -webkit-transform 0.1s ease-in-out;
+ transition: opacity 0.1s ease-in-out, -webkit-transform 0.1s ease-in-out;
+ -o-transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;
+ transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;
+ transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out, -webkit-transform 0.1s ease-in-out;
+}
+
+[dir="rtl"] .input-group-lg>.form-select,
+[dir="rtl"] .input-group-lg>.custom-select,
+[dir="rtl"] .input-group-sm>.form-select,
+[dir="rtl"] .input-group-sm>.custom-select {
+
+ padding-right: 4rem;
+}
+
+[dir="rtl"] .input-group> :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) {
+
+ margin-left: -1px;
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+[dir="rtl"] .was-validated .form-control:valid,
+[dir="rtl"] .form-control.is-valid {
+
+ border-color: hsl(120, 32%, 39%);
+ padding-right: calc(1.5rem + 1.2rem);
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='hsl%28120, 32%, 39%%29' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
+ background-repeat: no-repeat;
+ background-position: right calc(0.375rem + 0.3rem) center;
+ background-size: calc(0.75rem + 0.6rem) calc(0.75rem + 0.6rem);
+}
+
+[dir="rtl"] .was-validated textarea.form-control:valid,
+[dir="rtl"] textarea.form-control.is-valid {
+
+ padding-right: calc(1.5rem + 1.2rem);
+ background-position: top calc(0.375rem + 0.3rem) right calc(0.375rem + 0.3rem);
+}
+
+[dir="rtl"] .was-validated .form-select:valid:not([multiple]):not([size]),
+[dir="rtl"] .was-validated .custom-select:valid:not([multiple]):not([size]),
+[dir="rtl"] .was-validated .form-select:valid:not([multiple])[size="1"],
+[dir="rtl"] .was-validated .custom-select:valid:not([multiple])[size="1"],
+[dir="rtl"] .form-select.is-valid:not([multiple]):not([size]),
+[dir="rtl"] .is-valid.custom-select:not([multiple]):not([size]),
+[dir="rtl"] .form-select.is-valid:not([multiple])[size="1"],
+[dir="rtl"] .is-valid.custom-select:not([multiple])[size="1"] {
+
+ padding-right: 5.5rem;
+ background-image: url("../images/select-bg.svg"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='hsl%28120, 32%, 39%%29' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
+ background-position: right 1rem center, center right 3rem;
+ background-size: 116rem, calc(0.75rem + 0.6rem) calc(0.75rem + 0.6rem);
+}
+
+[dir="rtl"] .form-check-inline .form-check-input~.valid-feedback {
+
+ margin-left: 0.5rem;
+}
+
+[dir="rtl"] .was-validated .form-control:invalid,
+[dir="rtl"] .form-control.is-invalid {
+
+ border-color: hsl(3, 75%, 37%);
+ padding-right: calc(1.5rem + 1.2rem);
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='hsl%283, 75%, 37%%29'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='hsl%283, 75%, 37%%29' stroke='none'/%3e%3c/svg%3e");
+ background-repeat: no-repeat;
+ background-position: right calc(0.375rem + 0.3rem) center;
+ background-size: calc(0.75rem + 0.6rem) calc(0.75rem + 0.6rem);
+}
+
+[dir="rtl"] .was-validated textarea.form-control:invalid,
+[dir="rtl"] textarea.form-control.is-invalid {
+
+ padding-right: calc(1.5rem + 1.2rem);
+ background-position: top calc(0.375rem + 0.3rem) right calc(0.375rem + 0.3rem);
+}
+
+[dir="rtl"] .was-validated .form-select:invalid:not([multiple]):not([size]),
+[dir="rtl"] .was-validated .custom-select:invalid:not([multiple]):not([size]),
+[dir="rtl"] .was-validated .form-select:invalid:not([multiple])[size="1"],
+[dir="rtl"] .was-validated .custom-select:invalid:not([multiple])[size="1"],
+[dir="rtl"] .form-select.is-invalid:not([multiple]):not([size]),
+[dir="rtl"] .is-invalid.custom-select:not([multiple]):not([size]),
+[dir="rtl"] .form-select.is-invalid:not([multiple])[size="1"],
+[dir="rtl"] .is-invalid.custom-select:not([multiple])[size="1"] {
+
+ padding-right: 5.5rem;
+ background-image: url("../images/select-bg.svg"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='hsl%283, 75%, 37%%29'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='hsl%283, 75%, 37%%29' stroke='none'/%3e%3c/svg%3e");
+ background-position: right 1rem center, center right 3rem;
+ background-size: 116rem, calc(0.75rem + 0.6rem) calc(0.75rem + 0.6rem);
+}
+
+[dir="rtl"] .form-check-inline .form-check-input~.invalid-feedback {
+
+ margin-left: 0.5rem;
+}
+
+[dir="rtl"] .dropdown-toggle::after {
+
+ display: inline-block;
+ margin-left: 0.255rem;
+ vertical-align: 0.255rem;
+ content: "";
+ border-top: 0.3rem solid;
+ border-right: 0.3rem solid transparent;
+ border-bottom: 0;
+ border-left: 0.3rem solid transparent;
+}
+
+[dir="rtl"] .dropdown-toggle:empty::after {
+
+ margin-left: 0;
+}
+
+[dir="rtl"] .dropdown-menu {
+
+ --dropdown-zindex: 1000;
+ --dropdown-min-width: 10rem;
+ --dropdown-padding-x: 0;
+ --dropdown-padding-y: 0.5rem;
+ --dropdown-spacer: 0.125rem;
+ --dropdown-font-size: 1rem;
+ --dropdown-color: var(--body-color);
+ --dropdown-bg: hsl(0, 0%, 100%);
+ --dropdown-border-color: var(--border-color-translucent);
+ --dropdown-border-radius: 0.25rem;
+ --dropdown-border-width: 1px;
+ --dropdown-inner-border-radius: calc(0.25rem - 1px);
+ --dropdown-divider-bg: var(--border-color-translucent);
+ --dropdown-divider-margin-y: 0.5rem;
+ --dropdown-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
+ --dropdown-link-color: var(--body-color);
+ --dropdown-link-active-color: #1f2226;
+ --dropdown-link-active-bg: var(--secondary-bg);
+ --dropdown-link-active-color: var(--white);
+ --dropdown-link-active-bg: hsl(240, 98%, 17%);
+ --dropdown-link-disabled-color: hsl(210, 11%, 71%);
+ --dropdown-item-padding-x: 1rem;
+ --dropdown-item-padding-y: 0.25rem;
+ --dropdown-header-color: var(--secondary-color);
+ --dropdown-header-padding-x: 1rem;
+ --dropdown-header-padding-y: 0.5rem;
+ position: absolute;
+ z-index: var(--dropdown-zindex);
+ display: none;
+ min-width: var(--dropdown-min-width);
+ padding: var(--dropdown-padding-y) var(--dropdown-padding-x);
+ margin: 0;
+ font-size: var(--dropdown-font-size);
+ color: var(--dropdown-color);
+ text-align: left;
+ list-style: none;
+ background-color: var(--dropdown-bg);
+ background-clip: padding-box;
+ border: var(--dropdown-border-width) solid var(--dropdown-border-color);
+ border-radius: var(--dropdown-border-radius);
+}
+
+[dir="rtl"] .dropdown-menu[data-bs-popper] {
+
+ top: 100%;
+ right: 0;
+ margin-top: var(--dropdown-spacer);
+}
+
+[dir="rtl"] .dropdown-menu-start[data-bs-popper] {
+
+ left: auto;
+ right: 0;
+}
+
+[dir="rtl"] .dropdown-menu-end[data-bs-popper] {
+
+ left: 0;
+ right: auto;
+}
+
+[dir="rtl"] .dropdown-menu-sm-start[data-bs-popper] {
+
+ left: auto;
+ right: 0;
+
+}
+
+[dir="rtl"] .dropdown-menu-sm-end[data-bs-popper] {
+
+ left: 0;
+ right: auto;
+
+}
+
+[dir="rtl"] .dropdown-menu-md-start[data-bs-popper] {
+
+ left: auto;
+ right: 0;
+
+}
+
+[dir="rtl"] .dropdown-menu-md-end[data-bs-popper] {
+
+ left: 0;
+ right: auto;
+
+}
+
+[dir="rtl"] .dropdown-menu-lg-start[data-bs-popper] {
+
+ left: auto;
+ right: 0;
+
+}
+
+[dir="rtl"] .dropdown-menu-lg-end[data-bs-popper] {
+
+ left: 0;
+ right: auto;
+
+}
+
+[dir="rtl"] .dropdown-menu-xl-start[data-bs-popper] {
+
+ left: auto;
+ right: 0;
+
+}
+
+[dir="rtl"] .dropdown-menu-xl-end[data-bs-popper] {
+
+ left: 0;
+ right: auto;
+
+}
+
+[dir="rtl"] .dropdown-menu-xxl-start[data-bs-popper] {
+
+ left: auto;
+ right: 0;
+
+}
+
+[dir="rtl"] .dropdown-menu-xxl-end[data-bs-popper] {
+
+ left: 0;
+ right: auto;
+
+}
+
+[dir="rtl"] .dropup .dropdown-toggle::after {
+
+ display: inline-block;
+ margin-left: 0.255rem;
+ vertical-align: 0.255rem;
+ content: "";
+ border-top: 0;
+ border-right: 0.3rem solid transparent;
+ border-bottom: 0.3rem solid;
+ border-left: 0.3rem solid transparent;
+}
+
+[dir="rtl"] .dropup .dropdown-toggle:empty::after {
+
+ margin-left: 0;
+}
+
+[dir="rtl"] .dropend .dropdown-menu[data-bs-popper] {
+
+ top: 0;
+ left: auto;
+ right: 100%;
+ margin-top: 0;
+ margin-left: var(--dropdown-spacer);
+}
+
+[dir="rtl"] .dropend .dropdown-toggle::after {
+
+ display: inline-block;
+ margin-left: 0.255rem;
+ vertical-align: 0.255rem;
+ content: "";
+ border-top: 0.3rem solid transparent;
+ border-right: 0;
+ border-bottom: 0.3rem solid transparent;
+ border-left: 0.3rem solid;
+}
+
+[dir="rtl"] .dropend .dropdown-toggle:empty::after {
+
+ margin-left: 0;
+}
+
+[dir="rtl"] .dropstart .dropdown-menu[data-bs-popper] {
+
+ top: 0;
+ left: 100%;
+ right: auto;
+ margin-top: 0;
+ margin-right: var(--dropdown-spacer);
+}
+
+[dir="rtl"] .dropstart .dropdown-toggle::after {
+
+ display: inline-block;
+ margin-left: 0.255rem;
+ vertical-align: 0.255rem;
+ content: "";
+}
+
+[dir="rtl"] .dropstart .dropdown-toggle::before {
+
+ display: inline-block;
+ margin-right: 0.255rem;
+ vertical-align: 0.255rem;
+ content: "";
+ border-top: 0.3rem solid transparent;
+ border-right: 0.3rem solid;
+ border-bottom: 0.3rem solid transparent;
+}
+
+[dir="rtl"] .dropstart .dropdown-toggle:empty::after {
+
+ margin-left: 0;
+}
+
+[dir="rtl"] .btn-group> :not(.btn-check:first-child)+.btn,
+[dir="rtl"] .btn-group>.btn-group:not(:first-child) {
+
+ margin-left: -1px;
+}
+
+[dir="rtl"] .dropdown-toggle-split {
+
+ padding-right: 0.75rem;
+ padding-left: 0.75rem;
+}
+
+[dir="rtl"] .dropdown-toggle-split::after,
+[dir="rtl"] .dropup .dropdown-toggle-split::after,
+[dir="rtl"] .dropend .dropdown-toggle-split::after {
+
+ margin-left: 0;
+}
+
+[dir="rtl"] .dropstart .dropdown-toggle-split::before {
+
+ margin-right: 0;
+}
+
+[dir="rtl"] .btn-sm+.dropdown-toggle-split,
+[dir="rtl"] .btn-group-sm>.btn+.dropdown-toggle-split {
+
+ padding-right: 0.375rem;
+ padding-left: 0.375rem;
+}
+
+[dir="rtl"] .btn-lg+.dropdown-toggle-split,
+[dir="rtl"] .btn-group-lg>.btn+.dropdown-toggle-split {
+
+ padding-right: 0.75rem;
+ padding-left: 0.75rem;
+}
+
+[dir="rtl"] .nav {
+
+ --nav-link-padding-x: 1rem;
+ --nav-link-padding-y: 0.5rem;
+ --nav-link-font-weight: ;
+ --nav-link-color: var(--link-color);
+ --nav-link-active-color: var(--link-active-color);
+ --nav-link-disabled-color: var(--secondary-color);
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+
+[dir="rtl"] .navbar-brand {
+
+ padding-top: var(--navbar-brand-padding-y);
+ padding-bottom: var(--navbar-brand-padding-y);
+ margin-right: var(--navbar-brand-margin-end);
+ font-size: var(--navbar-brand-font-size);
+ color: var(--navbar-brand-color);
+ text-decoration: none;
+ white-space: nowrap;
+}
+
+[dir="rtl"] .navbar-nav {
+
+ --nav-link-padding-x: 0;
+ --nav-link-padding-y: 0.5rem;
+ --nav-link-font-weight: ;
+ --nav-link-color: var(--navbar-color);
+ --nav-link-active-color: var(--navbar-active-color);
+ --nav-link-disabled-color: var(--navbar-disabled-color);
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+
+[dir="rtl"] .navbar-expand-sm .navbar-nav .nav-link {
+
+ padding-right: var(--navbar-nav-link-padding-x);
+ padding-left: var(--navbar-nav-link-padding-x);
+
+}
+
+[dir="rtl"] .navbar-expand-md .navbar-nav .nav-link {
+
+ padding-right: var(--navbar-nav-link-padding-x);
+ padding-left: var(--navbar-nav-link-padding-x);
+
+}
+
+[dir="rtl"] .navbar-expand-lg .navbar-nav .nav-link {
+
+ padding-right: var(--navbar-nav-link-padding-x);
+ padding-left: var(--navbar-nav-link-padding-x);
+
+}
+
+[dir="rtl"] .navbar-expand-xl .navbar-nav .nav-link {
+
+ padding-right: var(--navbar-nav-link-padding-x);
+ padding-left: var(--navbar-nav-link-padding-x);
+
+}
+
+[dir="rtl"] .navbar-expand-xxl .navbar-nav .nav-link {
+
+ padding-right: var(--navbar-nav-link-padding-x);
+ padding-left: var(--navbar-nav-link-padding-x);
+
+}
+
+[dir="rtl"] .navbar-expand .navbar-nav .nav-link {
+
+ padding-right: var(--navbar-nav-link-padding-x);
+ padding-left: var(--navbar-nav-link-padding-x);
+}
+
+[dir="rtl"] .card>hr {
+
+ margin-right: 0;
+ margin-left: 0;
+}
+
+[dir="rtl"] .card-link+.card-link {
+
+ margin-left: var(--card-spacer-x);
+}
+
+[dir="rtl"] .card-header-tabs {
+
+ margin-right: calc(-0.5 * var(--card-cap-padding-x));
+ margin-bottom: calc(-1 * var(--card-cap-padding-y));
+ margin-left: calc(-0.5 * var(--card-cap-padding-x));
+ border-bottom: 0;
+}
+
+[dir="rtl"] .card-header-pills {
+
+ margin-right: calc(-0.5 * var(--card-cap-padding-x));
+ margin-left: calc(-0.5 * var(--card-cap-padding-x));
+}
+
+[dir="rtl"] .card-img-overlay {
+
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ padding: var(--card-img-overlay-padding);
+ border-radius: var(--card-inner-border-radius);
+}
+
+[dir="rtl"] .card-group>.card+.card {
+
+ margin-left: 0;
+ border-left: 0;
+
+}
+
+[dir="rtl"] .accordion-button {
+
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ width: 100%;
+ padding: var(--accordion-btn-padding-y) var(--accordion-btn-padding-x);
+ font-size: 1rem;
+ color: var(--accordion-btn-color);
+ text-align: left;
+ background-color: var(--accordion-btn-bg);
+ border: 0;
+ border-radius: 0;
+ overflow-anchor: none;
+ -webkit-transition: var(--accordion-transition);
+ -o-transition: var(--accordion-transition);
+ transition: var(--accordion-transition);
+}
+
+[dir="rtl"] .accordion-button::after {
+
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
+ width: var(--accordion-btn-icon-width);
+ height: var(--accordion-btn-icon-width);
+ margin-left: auto;
+ content: "";
+ background-image: var(--accordion-btn-icon);
+ background-repeat: no-repeat;
+ background-size: var(--accordion-btn-icon-width);
+ -webkit-transition: var(--accordion-btn-icon-transition);
+ -o-transition: var(--accordion-btn-icon-transition);
+ transition: var(--accordion-btn-icon-transition);
+}
+
+[dir="rtl"] .accordion-flush .accordion-item {
+
+ border-right: 0;
+ border-left: 0;
+ border-radius: 0;
+}
+
+[dir="rtl"] .breadcrumb-item+.breadcrumb-item {
+
+ padding-left: var(--breadcrumb-item-padding-x);
+}
+
+[dir="rtl"] .breadcrumb-item+.breadcrumb-item::before {
+
+ float: left;
+ padding-right: var(--breadcrumb-item-padding-x);
+ color: var(--breadcrumb-divider-color);
+ content: var(--breadcrumb-divider, "/")
+ /* rtl: var(--breadcrumb-divider, "/") */
+ ;
+}
+
+[dir="rtl"] .pagination {
+
+ --pagination-padding-x: 0.75rem;
+ --pagination-padding-y: 0.375rem;
+ --pagination-font-size: 1rem;
+ --pagination-color: var(--link-color);
+ --pagination-bg: hsl(0, 0%, 100%);
+ --pagination-border-width: 1px;
+ --pagination-border-color: hsl(210, 14%, 89%);
+ --pagination-border-radius: 0.25rem;
+ --pagination-active-color: var(--link-active-color);
+ --pagination-active-bg: var(--secondary-bg);
+ --pagination-active-border-color: hsl(210, 14%, 89%);
+ --pagination-focus-color: var(--link-active-color);
+ --pagination-focus-bg: var(--secondary-bg);
+ --pagination-focus-box-shadow: 0 0 0 0.25rem var(--focus-ring-color);
+ --pagination-active-color: var(--white);
+ --pagination-active-bg: hsl(240, 98%, 17%);
+ --pagination-active-border-color: hsl(240, 98%, 17%);
+ --pagination-disabled-color: var(--secondary-color);
+ --pagination-disabled-bg: hsl(0, 0%, 100%);
+ --pagination-disabled-border-color: hsl(210, 14%, 89%);
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ padding-left: 0;
+ list-style: none;
+}
+
+[dir="rtl"] .page-item:not(:first-child) .page-link {
+
+ margin-left: -1px;
+}
+
+[dir="rtl"] .alert-dismissible {
+
+ padding-right: 3rem;
+}
+
+[dir="rtl"] .alert-dismissible .btn-close {
+
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 2;
+ padding: 1.25rem 1rem;
+}
+
+[dir="rtl"] }
+
+.list-group {
+
+ --list-group-color: var(--body-color);
+ --list-group-bg: hsl(0, 0%, 100%);
+ --list-group-border-color: rgba(0, 0, 0, 0.125);
+ --list-group-border-width: 1px;
+ --list-group-border-radius: 0.25rem;
+ --list-group-item-padding-x: 1rem;
+ --list-group-item-padding-y: 0.5rem;
+ --list-group-action-color: hsl(210, 9%, 31%);
+ --list-group-action-active-color: hsl(210, 9%, 31%);
+ --list-group-action-active-bg: hsl(210, 17%, 98%);
+ --list-group-action-active-color: var(--body-color);
+ --list-group-action-active-bg: var(--secondary-bg);
+ --list-group-disabled-color: var(--secondary-color);
+ --list-group-disabled-bg: hsl(0, 0%, 100%);
+ --list-group-active-color: var(--white);
+ --list-group-active-bg: hsl(240, 98%, 17%);
+ --list-group-active-border-color: hsl(240, 98%, 17%);
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ padding-left: 0;
+ margin-bottom: 0;
+ border-radius: var(--list-group-border-radius);
+}
+
+[dir="rtl"] .list-group-horizontal>.list-group-item+.list-group-item {
+
+ border-top-width: var(--list-group-border-width);
+ border-right-width: 0;
+}
+
+[dir="rtl"] .list-group-horizontal>.list-group-item+.list-group-item.active {
+
+ margin-left: calc(-1 * var(--list-group-border-width));
+ border-right-width: var(--list-group-border-width);
+}
+
+[dir="rtl"] .list-group-horizontal-sm>.list-group-item+.list-group-item {
+
+ border-top-width: var(--list-group-border-width);
+ border-right-width: 0;
+
+}
+
+[dir="rtl"] .list-group-horizontal-sm>.list-group-item+.list-group-item.active {
+
+ margin-left: calc(-1 * var(--list-group-border-width));
+ border-right-width: var(--list-group-border-width);
+
+}
+
+[dir="rtl"] .list-group-horizontal-md>.list-group-item+.list-group-item {
+
+ border-top-width: var(--list-group-border-width);
+ border-right-width: 0;
+
+}
+
+[dir="rtl"] .list-group-horizontal-md>.list-group-item+.list-group-item.active {
+
+ margin-left: calc(-1 * var(--list-group-border-width));
+ border-right-width: var(--list-group-border-width);
+
+}
+
+[dir="rtl"] .list-group-horizontal-lg>.list-group-item+.list-group-item {
+
+ border-top-width: var(--list-group-border-width);
+ border-right-width: 0;
+
+}
+
+[dir="rtl"] .list-group-horizontal-lg>.list-group-item+.list-group-item.active {
+
+ margin-left: calc(-1 * var(--list-group-border-width));
+ border-right-width: var(--list-group-border-width);
+
+}
+
+[dir="rtl"] .list-group-horizontal-xl>.list-group-item+.list-group-item {
+
+ border-top-width: var(--list-group-border-width);
+ border-right-width: 0;
+
+}
+
+[dir="rtl"] .list-group-horizontal-xl>.list-group-item+.list-group-item.active {
+
+ margin-left: calc(-1 * var(--list-group-border-width));
+ border-right-width: var(--list-group-border-width);
+
+}
+
+[dir="rtl"] .list-group-horizontal-xxl>.list-group-item+.list-group-item {
+
+ border-top-width: var(--list-group-border-width);
+ border-right-width: 0;
+
+}
+
+[dir="rtl"] .list-group-horizontal-xxl>.list-group-item+.list-group-item.active {
+
+ margin-left: calc(-1 * var(--list-group-border-width));
+ border-right-width: var(--list-group-border-width);
+
+}
+
+[dir="rtl"] .toast-header .btn-close {
+
+ margin-right: calc(-0.5 * var(--toast-padding-x));
+ margin-left: var(--toast-padding-x);
+}
+
+[dir="rtl"] .modal {
+
+ --modal-zindex: 1050;
+ --modal-width: 500px;
+ --modal-padding: 1rem;
+ --modal-margin: 0.5rem;
+ --modal-color: ;
+ --modal-bg: hsl(0, 0%, 100%);
+ --modal-border-color: var(--border-color-translucent);
+ --modal-border-width: 1px;
+ --modal-border-radius: 0.3rem;
+ --modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
+ --modal-inner-border-radius: calc(0.3rem - 1px);
+ --modal-header-padding-x: 1rem;
+ --modal-header-padding-y: 1rem;
+ --modal-header-padding: 1rem 1rem;
+ --modal-header-border-color: var(--border-color);
+ --modal-header-border-width: 1px;
+ --modal-title-line-height: 1.5;
+ --modal-footer-gap: 0.5rem;
+ --modal-footer-bg: ;
+ --modal-footer-border-color: var(--border-color);
+ --modal-footer-border-width: 1px;
+ position: fixed;
+ top: 0;
+ right: 0;
+ z-index: var(--modal-zindex);
+ display: none;
+ width: 100%;
+ height: 100%;
+ overflow-x: hidden;
+ overflow-y: auto;
+ outline: 0;
+}
+
+[dir="rtl"] .modal-backdrop {
+
+ --backdrop-zindex: 1040;
+ --backdrop-bg: hsl(0, 0%, 0%);
+ --backdrop-opacity: 0.5;
+ position: fixed;
+ top: 0;
+ right: 0;
+ z-index: var(--backdrop-zindex);
+ width: 100vw;
+ height: 100vh;
+ background-color: var(--backdrop-bg);
+}
+
+[dir="rtl"] .modal-dialog {
+
+ max-width: var(--modal-width);
+ margin-right: auto;
+ margin-left: auto;
+
+}
+
+[dir="rtl"] }
+
+.tooltip {
+
+ --tooltip-zindex: 1070;
+ --tooltip-max-width: 200px;
+ --tooltip-padding-x: 0.5rem;
+ --tooltip-padding-y: 0.25rem;
+ --tooltip-margin: ;
+ --tooltip-font-size: 0.875rem;
+ --tooltip-color: var(--white);
+ --tooltip-bg: hsl(0, 0%, 0%);
+ --tooltip-border-radius: 0.25rem;
+ --tooltip-opacity: 0.9;
+ --tooltip-arrow-width: 0.8rem;
+ --tooltip-arrow-height: 0.4rem;
+ z-index: var(--tooltip-zindex);
+ display: block;
+ padding: var(--tooltip-arrow-height);
+ margin: var(--tooltip-margin);
+ font-family: var(--font-family-body, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");
+ font-style: normal;
+ font-weight: 400;
+ line-height: 1.5;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ white-space: normal;
+ word-spacing: normal;
+ line-break: auto;
+ font-size: var(--tooltip-font-size);
+ word-wrap: break-word;
+ opacity: 0;
+}
+
+[dir="rtl"] /* rtl:begin:ignore */
+.bs-tooltip-end .tooltip-arrow,
+[dir="rtl"] .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow {
+
+ right: 0;
+ width: var(--tooltip-arrow-height);
+ height: var(--tooltip-arrow-width);
+}
+
+[dir="rtl"] .bs-tooltip-end .tooltip-arrow::before,
+[dir="rtl"] .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before {
+
+ left: -1px;
+ border-width: calc(var(--tooltip-arrow-width) * 0.5) var(--tooltip-arrow-height) calc(var(--tooltip-arrow-width) * 0.5) 0;
+ border-left-color: var(--tooltip-bg);
+}
+
+[dir="rtl"] /* rtl:begin:ignore */
+.bs-tooltip-start .tooltip-arrow,
+[dir="rtl"] .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow {
+
+ left: 0;
+ width: var(--tooltip-arrow-height);
+ height: var(--tooltip-arrow-width);
+}
+
+[dir="rtl"] .bs-tooltip-start .tooltip-arrow::before,
+[dir="rtl"] .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before {
+
+ right: -1px;
+ border-width: calc(var(--tooltip-arrow-width) * 0.5) 0 calc(var(--tooltip-arrow-width) * 0.5) var(--tooltip-arrow-height);
+ border-right-color: var(--tooltip-bg);
+}
+
+[dir="rtl"] .popover {
+
+ --popover-zindex: 1060;
+ --popover-max-width: 276px;
+ --popover-font-size: 0.875rem;
+ --popover-bg: hsl(0, 0%, 100%);
+ --popover-border-width: 1px;
+ --popover-border-color: var(--border-color-translucent);
+ --popover-border-radius: 0.3rem;
+ --popover-inner-border-radius: calc(0.3rem - 1px);
+ --popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
+ --popover-header-padding-x: 1rem;
+ --popover-header-padding-y: 0.5rem;
+ --popover-header-font-size: 1rem;
+ --popover-header-color: ;
+ --popover-header-bg: #f0f0f0;
+ --popover-body-padding-x: 1rem;
+ --popover-body-padding-y: 1rem;
+ --popover-body-color: var(--body-color);
+ --popover-arrow-width: 1rem;
+ --popover-arrow-height: 0.5rem;
+ --popover-arrow-border: var(--popover-border-color);
+ z-index: var(--popover-zindex);
+ display: block;
+ max-width: var(--popover-max-width);
+ font-family: var(--font-family-body, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");
+ font-style: normal;
+ font-weight: 400;
+ line-height: 1.5;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ white-space: normal;
+ word-spacing: normal;
+ line-break: auto;
+ font-size: var(--popover-font-size);
+ word-wrap: break-word;
+ background-color: var(--popover-bg);
+ background-clip: padding-box;
+ border: var(--popover-border-width) solid var(--popover-border-color);
+ border-radius: var(--popover-border-radius);
+}
+
+[dir="rtl"] /* rtl:begin:ignore */
+.bs-popover-end>.popover-arrow,
+[dir="rtl"] .bs-popover-auto[data-popper-placement^=right]>.popover-arrow {
+
+ right: calc(-1 * (var(--popover-arrow-height)) - var(--popover-border-width));
+ width: var(--popover-arrow-height);
+ height: var(--popover-arrow-width);
+}
+
+[dir="rtl"] .bs-popover-end>.popover-arrow::before,
+[dir="rtl"] .bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before {
+
+ right: 0;
+ border-left-color: var(--popover-arrow-border);
+}
+
+[dir="rtl"] .bs-popover-end>.popover-arrow::after,
+[dir="rtl"] .bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after {
+
+ right: var(--popover-border-width);
+ border-left-color: var(--popover-bg);
+}
+
+[dir="rtl"] .bs-popover-bottom .popover-header::before,
+[dir="rtl"] .bs-popover-auto[data-popper-placement^=bottom] .popover-header::before {
+
+ position: absolute;
+ top: 0;
+ right: 50%;
+ display: block;
+ width: var(--popover-arrow-width);
+ margin-left: calc(-0.5 * var(--popover-arrow-width));
+ content: "";
+ border-bottom: var(--popover-border-width) solid var(--popover-header-bg);
+}
+
+[dir="rtl"] /* rtl:begin:ignore */
+.bs-popover-start>.popover-arrow,
+[dir="rtl"] .bs-popover-auto[data-popper-placement^=left]>.popover-arrow {
+
+ left: calc(-1 * (var(--popover-arrow-height)) - var(--popover-border-width));
+ width: var(--popover-arrow-height);
+ height: var(--popover-arrow-width);
+}
+
+[dir="rtl"] .bs-popover-start>.popover-arrow::before,
+[dir="rtl"] .bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before {
+
+ left: 0;
+ border-right-color: var(--popover-arrow-border);
+}
+
+[dir="rtl"] .bs-popover-start>.popover-arrow::after,
+[dir="rtl"] .bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after {
+
+ left: var(--popover-border-width);
+ border-right-color: var(--popover-bg);
+}
+
+[dir="rtl"] .carousel-item {
+
+ position: relative;
+ display: none;
+ float: left;
+ width: 100%;
+ margin-right: -100%;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ -webkit-transition: -webkit-transform 0.6s ease-in-out;
+ transition: -webkit-transform 0.6s ease-in-out;
+ -o-transition: transform 0.6s ease-in-out;
+ transition: transform 0.6s ease-in-out;
+ transition: transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;
+}
+
+[dir="rtl"] .carousel-control-prev {
+
+ right: 0;
+}
+
+[dir="rtl"] .carousel-control-next {
+
+ left: 0;
+}
+
+[dir="rtl"] .carousel-indicators {
+
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ z-index: 2;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ padding: 0;
+ margin-right: 15%;
+ margin-bottom: 1rem;
+ margin-left: 15%;
+ list-style: none;
+}
+
+[dir="rtl"] .carousel-indicators [data-bs-target] {
+
+ -webkit-box-sizing: content-box;
+ box-sizing: content-box;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 1 auto;
+ flex: 0 1 auto;
+ width: 30px;
+ height: 3px;
+ padding: 0;
+ margin-right: 3px;
+ margin-left: 3px;
+ text-indent: -999px;
+ cursor: pointer;
+ background-color: var(--body-bg);
+ background-clip: padding-box;
+ border: 0;
+ border-top: 10px solid transparent;
+ border-bottom: 10px solid transparent;
+ opacity: 0.5;
+ -webkit-transition: opacity 0.6s ease;
+ -o-transition: opacity 0.6s ease;
+ transition: opacity 0.6s ease;
+}
+
+[dir="rtl"] .carousel-caption {
+
+ position: absolute;
+ left: 15%;
+ bottom: 1.25rem;
+ right: 15%;
+ padding-top: 1.25rem;
+ padding-bottom: 1.25rem;
+ color: var(--white);
+ text-align: center;
+}
+
+[dir="rtl"] }
+
+.spinner-border {
+
+ --spinner-width: 2rem;
+ --spinner-height: 2rem;
+ --spinner-vertical-align: -0.125rem;
+ --spinner-border-width: 0.25rem;
+ --spinner-animation-speed: 0.75s;
+ --spinner-animation-name: spinner-border;
+ border: var(--spinner-border-width) solid currentcolor;
+ border-left-color: transparent;
+}
+
+[dir="rtl"] }
+
+@media (max-width: 575.98px) {
+
+ .offcanvas-sm.offcanvas-start {
+ top: 0;
+ right: 0;
+ width: var(--offcanvas-width);
+ border-right: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 575.98px) {
+
+ .offcanvas-sm.offcanvas-end {
+ top: 0;
+ left: 0;
+ width: var(--offcanvas-width);
+ border-left: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 575.98px) {
+
+ .offcanvas-sm.offcanvas-top {
+ top: 0;
+ left: 0;
+ right: 0;
+ height: var(--offcanvas-height);
+ max-height: 100%;
+ border-bottom: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 575.98px) {
+
+ .offcanvas-sm.offcanvas-bottom {
+ left: 0;
+ right: 0;
+ height: var(--offcanvas-height);
+ max-height: 100%;
+ border-top: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 767.98px) {
+
+ .offcanvas-md.offcanvas-start {
+ top: 0;
+ right: 0;
+ width: var(--offcanvas-width);
+ border-right: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 767.98px) {
+
+ .offcanvas-md.offcanvas-end {
+ top: 0;
+ left: 0;
+ width: var(--offcanvas-width);
+ border-left: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 767.98px) {
+
+ .offcanvas-md.offcanvas-top {
+ top: 0;
+ left: 0;
+ right: 0;
+ height: var(--offcanvas-height);
+ max-height: 100%;
+ border-bottom: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 767.98px) {
+
+ .offcanvas-md.offcanvas-bottom {
+ left: 0;
+ right: 0;
+ height: var(--offcanvas-height);
+ max-height: 100%;
+ border-top: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 991.98px) {
+
+ .offcanvas-lg.offcanvas-start {
+ top: 0;
+ right: 0;
+ width: var(--offcanvas-width);
+ border-right: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 991.98px) {
+
+ .offcanvas-lg.offcanvas-end {
+ top: 0;
+ left: 0;
+ width: var(--offcanvas-width);
+ border-left: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 991.98px) {
+
+ .offcanvas-lg.offcanvas-top {
+ top: 0;
+ left: 0;
+ right: 0;
+ height: var(--offcanvas-height);
+ max-height: 100%;
+ border-bottom: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 991.98px) {
+
+ .offcanvas-lg.offcanvas-bottom {
+ left: 0;
+ right: 0;
+ height: var(--offcanvas-height);
+ max-height: 100%;
+ border-top: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 1199.98px) {
+
+ .offcanvas-xl.offcanvas-start {
+ top: 0;
+ right: 0;
+ width: var(--offcanvas-width);
+ border-right: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 1199.98px) {
+
+ .offcanvas-xl.offcanvas-end {
+ top: 0;
+ left: 0;
+ width: var(--offcanvas-width);
+ border-left: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 1199.98px) {
+
+ .offcanvas-xl.offcanvas-top {
+ top: 0;
+ left: 0;
+ right: 0;
+ height: var(--offcanvas-height);
+ max-height: 100%;
+ border-bottom: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 1199.98px) {
+
+ .offcanvas-xl.offcanvas-bottom {
+ left: 0;
+ right: 0;
+ height: var(--offcanvas-height);
+ max-height: 100%;
+ border-top: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 1399.98px) {
+
+ .offcanvas-xxl.offcanvas-start {
+ top: 0;
+ right: 0;
+ width: var(--offcanvas-width);
+ border-right: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 1399.98px) {
+
+ .offcanvas-xxl.offcanvas-end {
+ top: 0;
+ left: 0;
+ width: var(--offcanvas-width);
+ border-left: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 1399.98px) {
+
+ .offcanvas-xxl.offcanvas-top {
+ top: 0;
+ left: 0;
+ right: 0;
+ height: var(--offcanvas-height);
+ max-height: 100%;
+ border-bottom: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+
+}
+
+[dir="rtl"] }
+
+@media (max-width: 1399.98px) {
+
+ .offcanvas-xxl.offcanvas-bottom {
+ left: 0;
+ right: 0;
+ height: var(--offcanvas-height);
+ max-height: 100%;
+ border-top: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+
+}
+
+[dir="rtl"] }
+
+.offcanvas.offcanvas-start {
+
+ top: 0;
+ right: 0;
+ width: var(--offcanvas-width);
+ border-right: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+}
+
+[dir="rtl"] .offcanvas.offcanvas-end {
+
+ top: 0;
+ left: 0;
+ width: var(--offcanvas-width);
+ border-left: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+}
+
+[dir="rtl"] .offcanvas.offcanvas-top {
+
+ top: 0;
+ left: 0;
+ right: 0;
+ height: var(--offcanvas-height);
+ max-height: 100%;
+ border-bottom: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+}
+
+[dir="rtl"] .offcanvas.offcanvas-bottom {
+
+ left: 0;
+ right: 0;
+ height: var(--offcanvas-height);
+ max-height: 100%;
+ border-top: var(--offcanvas-border-width) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+}
+
+[dir="rtl"] .offcanvas-backdrop {
+
+ position: fixed;
+ top: 0;
+ right: 0;
+ z-index: 1040;
+ width: 100vw;
+ height: 100vh;
+ background-color: hsl(0, 0%, 0%);
+}
+
+[dir="rtl"] .offcanvas-header .btn-close {
+
+ padding: calc(var(--offcanvas-padding-y) * 0.5) calc(var(--offcanvas-padding-x) * 0.5);
+ margin-top: calc(-0.5 * var(--offcanvas-padding-y));
+ margin-right: calc(-0.5 * var(--offcanvas-padding-x));
+ margin-bottom: calc(-0.5 * var(--offcanvas-padding-y));
+}
+
+[dir="rtl"] .ratio>* {
+
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 100%;
+ height: 100%;
+}
+
+[dir="rtl"] .fixed-top {
+
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 1030;
+}
+
+[dir="rtl"] .fixed-bottom {
+
+ position: fixed;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ z-index: 1030;
+}
+
+[dir="rtl"] .stretched-link::after {
+
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ z-index: 1;
+ content: "";
+}
+
+[dir="rtl"] .float-start {
+
+ float: left !important;
+}
+
+[dir="rtl"] .float-end {
+
+ float: left !important;
+}
+
+[dir="rtl"] .start-0 {
+
+ right: 0 !important;
+}
+
+[dir="rtl"] .start-50 {
+
+ right: 50% !important;
+}
+
+[dir="rtl"] .start-100 {
+
+ right: 100% !important;
+}
+
+[dir="rtl"] .end-0 {
+
+ left: 0 !important;
+}
+
+[dir="rtl"] .end-50 {
+
+ left: 50% !important;
+}
+
+[dir="rtl"] .end-100 {
+
+ left: 100% !important;
+}
+
+[dir="rtl"] .border-end {
+
+ border-right: var(--border-width) var(--border-style) var(--border-color) !important;
+}
+
+[dir="rtl"] .border-end-0 {
+
+ border-right: 0 !important;
+}
+
+[dir="rtl"] .border-start {
+
+ border-left: var(--border-width) var(--border-style) var(--border-color) !important;
+}
+
+[dir="rtl"] .border-start-0 {
+
+ border-left: 0 !important;
+}
+
+[dir="rtl"] .mx-0 {
+
+ margin-right: 0 !important;
+ margin-left: 0 !important;
+}
+
+[dir="rtl"] .mx-1 {
+
+ margin-right: 0.25rem !important;
+ margin-left: 0.25rem !important;
+}
+
+[dir="rtl"] .mx-2 {
+
+ margin-right: 0.5rem !important;
+ margin-left: 0.5rem !important;
+}
+
+[dir="rtl"] .mx-3 {
+
+ margin-right: 1rem !important;
+ margin-left: 1rem !important;
+}
+
+[dir="rtl"] .mx-4 {
+
+ margin-right: 1.5rem !important;
+ margin-left: 1.5rem !important;
+}
+
+[dir="rtl"] .mx-5 {
+
+ margin-right: 3rem !important;
+ margin-left: 3rem !important;
+}
+
+[dir="rtl"] .mx-auto {
+
+ margin-right: auto !important;
+ margin-left: auto !important;
+}
+
+[dir="rtl"] .me-0 {
+
+ margin-right: 0 !important;
+}
+
+[dir="rtl"] .me-1 {
+
+ margin-right: 0.25rem !important;
+}
+
+[dir="rtl"] .me-2 {
+
+ margin-right: 0.5rem !important;
+}
+
+[dir="rtl"] .me-3 {
+
+ margin-right: 1rem !important;
+}
+
+[dir="rtl"] .me-4 {
+
+ margin-right: 1.5rem !important;
+}
+
+[dir="rtl"] .me-5 {
+
+ margin-right: 3rem !important;
+}
+
+[dir="rtl"] .me-auto {
+
+ margin-right: auto !important;
+}
+
+[dir="rtl"] .ms-0 {
+
+ margin-left: 0 !important;
+}
+
+[dir="rtl"] .ms-1 {
+
+ margin-left: 0.25rem !important;
+}
+
+[dir="rtl"] .ms-2 {
+
+ margin-left: 0.5rem !important;
+}
+
+[dir="rtl"] .ms-3 {
+
+ margin-left: 1rem !important;
+}
+
+[dir="rtl"] .ms-4 {
+
+ margin-left: 1.5rem !important;
+}
+
+[dir="rtl"] .ms-5 {
+
+ margin-left: 3rem !important;
+}
+
+[dir="rtl"] .ms-auto {
+
+ margin-left: auto !important;
+}
+
+[dir="rtl"] .px-0 {
+
+ padding-right: 0 !important;
+ padding-left: 0 !important;
+}
+
+[dir="rtl"] .px-1 {
+
+ padding-right: 0.25rem !important;
+ padding-left: 0.25rem !important;
+}
+
+[dir="rtl"] .px-2 {
+
+ padding-right: 0.5rem !important;
+ padding-left: 0.5rem !important;
+}
+
+[dir="rtl"] .px-3 {
+
+ padding-right: 1rem !important;
+ padding-left: 1rem !important;
+}
+
+[dir="rtl"] .px-4 {
+
+ padding-right: 1.5rem !important;
+ padding-left: 1.5rem !important;
+}
+
+[dir="rtl"] .px-5 {
+
+ padding-right: 3rem !important;
+ padding-left: 3rem !important;
+}
+
+[dir="rtl"] .pe-0 {
+
+ padding-right: 0 !important;
+}
+
+[dir="rtl"] .pe-1 {
+
+ padding-right: 0.25rem !important;
+}
+
+[dir="rtl"] .pe-2 {
+
+ padding-right: 0.5rem !important;
+}
+
+[dir="rtl"] .pe-3 {
+
+ padding-right: 1rem !important;
+}
+
+[dir="rtl"] .pe-4 {
+
+ padding-right: 1.5rem !important;
+}
+
+[dir="rtl"] .pe-5 {
+
+ padding-right: 3rem !important;
+}
+
+[dir="rtl"] .ps-0 {
+
+ padding-left: 0 !important;
+}
+
+[dir="rtl"] .ps-1 {
+
+ padding-left: 0.25rem !important;
+}
+
+[dir="rtl"] .ps-2 {
+
+ padding-left: 0.5rem !important;
+}
+
+[dir="rtl"] .ps-3 {
+
+ padding-left: 1rem !important;
+}
+
+[dir="rtl"] .ps-4 {
+
+ padding-left: 1.5rem !important;
+}
+
+[dir="rtl"] .ps-5 {
+
+ padding-left: 3rem !important;
+}
+
+[dir="rtl"] .text-start {
+
+ text-align: left !important;
+}
+
+[dir="rtl"] .text-end {
+
+ text-align: left !important;
+}
+
+[dir="rtl"] @media (min-width: 576px) {
+
+ .float-sm-start {
+ float: left !important;
+
+}
+
+[dir="rtl"] .float-sm-end {
+
+ float: left !important;
+
+}
+
+[dir="rtl"] .mx-sm-0 {
+
+ margin-right: 0 !important;
+ margin-left: 0 !important;
+
+}
+
+[dir="rtl"] .mx-sm-1 {
+
+ margin-right: 0.25rem !important;
+ margin-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .mx-sm-2 {
+
+ margin-right: 0.5rem !important;
+ margin-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .mx-sm-3 {
+
+ margin-right: 1rem !important;
+ margin-left: 1rem !important;
+
+}
+
+[dir="rtl"] .mx-sm-4 {
+
+ margin-right: 1.5rem !important;
+ margin-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .mx-sm-5 {
+
+ margin-right: 3rem !important;
+ margin-left: 3rem !important;
+
+}
+
+[dir="rtl"] .mx-sm-auto {
+
+ margin-right: auto !important;
+ margin-left: auto !important;
+
+}
+
+[dir="rtl"] .me-sm-0 {
+
+ margin-right: 0 !important;
+
+}
+
+[dir="rtl"] .me-sm-1 {
+
+ margin-right: 0.25rem !important;
+
+}
+
+[dir="rtl"] .me-sm-2 {
+
+ margin-right: 0.5rem !important;
+
+}
+
+[dir="rtl"] .me-sm-3 {
+
+ margin-right: 1rem !important;
+
+}
+
+[dir="rtl"] .me-sm-4 {
+
+ margin-right: 1.5rem !important;
+
+}
+
+[dir="rtl"] .me-sm-5 {
+
+ margin-right: 3rem !important;
+
+}
+
+[dir="rtl"] .me-sm-auto {
+
+ margin-right: auto !important;
+
+}
+
+[dir="rtl"] .ms-sm-0 {
+
+ margin-left: 0 !important;
+
+}
+
+[dir="rtl"] .ms-sm-1 {
+
+ margin-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .ms-sm-2 {
+
+ margin-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .ms-sm-3 {
+
+ margin-left: 1rem !important;
+
+}
+
+[dir="rtl"] .ms-sm-4 {
+
+ margin-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .ms-sm-5 {
+
+ margin-left: 3rem !important;
+
+}
+
+[dir="rtl"] .ms-sm-auto {
+
+ margin-left: auto !important;
+
+}
+
+[dir="rtl"] .px-sm-0 {
+
+ padding-right: 0 !important;
+ padding-left: 0 !important;
+
+}
+
+[dir="rtl"] .px-sm-1 {
+
+ padding-right: 0.25rem !important;
+ padding-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .px-sm-2 {
+
+ padding-right: 0.5rem !important;
+ padding-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .px-sm-3 {
+
+ padding-right: 1rem !important;
+ padding-left: 1rem !important;
+
+}
+
+[dir="rtl"] .px-sm-4 {
+
+ padding-right: 1.5rem !important;
+ padding-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .px-sm-5 {
+
+ padding-right: 3rem !important;
+ padding-left: 3rem !important;
+
+}
+
+[dir="rtl"] .pe-sm-0 {
+
+ padding-right: 0 !important;
+
+}
+
+[dir="rtl"] .pe-sm-1 {
+
+ padding-right: 0.25rem !important;
+
+}
+
+[dir="rtl"] .pe-sm-2 {
+
+ padding-right: 0.5rem !important;
+
+}
+
+[dir="rtl"] .pe-sm-3 {
+
+ padding-right: 1rem !important;
+
+}
+
+[dir="rtl"] .pe-sm-4 {
+
+ padding-right: 1.5rem !important;
+
+}
+
+[dir="rtl"] .pe-sm-5 {
+
+ padding-right: 3rem !important;
+
+}
+
+[dir="rtl"] .ps-sm-0 {
+
+ padding-left: 0 !important;
+
+}
+
+[dir="rtl"] .ps-sm-1 {
+
+ padding-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .ps-sm-2 {
+
+ padding-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .ps-sm-3 {
+
+ padding-left: 1rem !important;
+
+}
+
+[dir="rtl"] .ps-sm-4 {
+
+ padding-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .ps-sm-5 {
+
+ padding-left: 3rem !important;
+
+}
+
+[dir="rtl"] .text-sm-start {
+
+ text-align: left !important;
+
+}
+
+[dir="rtl"] .text-sm-end {
+
+ text-align: left !important;
+
+}
+
+[dir="rtl"] }
+
+@media (min-width: 768px) {
+
+ .float-md-start {
+ float: left !important;
+
+}
+
+[dir="rtl"] .float-md-end {
+
+ float: left !important;
+
+}
+
+[dir="rtl"] .mx-md-0 {
+
+ margin-right: 0 !important;
+ margin-left: 0 !important;
+
+}
+
+[dir="rtl"] .mx-md-1 {
+
+ margin-right: 0.25rem !important;
+ margin-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .mx-md-2 {
+
+ margin-right: 0.5rem !important;
+ margin-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .mx-md-3 {
+
+ margin-right: 1rem !important;
+ margin-left: 1rem !important;
+
+}
+
+[dir="rtl"] .mx-md-4 {
+
+ margin-right: 1.5rem !important;
+ margin-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .mx-md-5 {
+
+ margin-right: 3rem !important;
+ margin-left: 3rem !important;
+
+}
+
+[dir="rtl"] .mx-md-auto {
+
+ margin-right: auto !important;
+ margin-left: auto !important;
+
+}
+
+[dir="rtl"] .me-md-0 {
+
+ margin-right: 0 !important;
+
+}
+
+[dir="rtl"] .me-md-1 {
+
+ margin-right: 0.25rem !important;
+
+}
+
+[dir="rtl"] .me-md-2 {
+
+ margin-right: 0.5rem !important;
+
+}
+
+[dir="rtl"] .me-md-3 {
+
+ margin-right: 1rem !important;
+
+}
+
+[dir="rtl"] .me-md-4 {
+
+ margin-right: 1.5rem !important;
+
+}
+
+[dir="rtl"] .me-md-5 {
+
+ margin-right: 3rem !important;
+
+}
+
+[dir="rtl"] .me-md-auto {
+
+ margin-right: auto !important;
+
+}
+
+[dir="rtl"] .ms-md-0 {
+
+ margin-left: 0 !important;
+
+}
+
+[dir="rtl"] .ms-md-1 {
+
+ margin-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .ms-md-2 {
+
+ margin-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .ms-md-3 {
+
+ margin-left: 1rem !important;
+
+}
+
+[dir="rtl"] .ms-md-4 {
+
+ margin-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .ms-md-5 {
+
+ margin-left: 3rem !important;
+
+}
+
+[dir="rtl"] .ms-md-auto {
+
+ margin-left: auto !important;
+
+}
+
+[dir="rtl"] .px-md-0 {
+
+ padding-right: 0 !important;
+ padding-left: 0 !important;
+
+}
+
+[dir="rtl"] .px-md-1 {
+
+ padding-right: 0.25rem !important;
+ padding-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .px-md-2 {
+
+ padding-right: 0.5rem !important;
+ padding-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .px-md-3 {
+
+ padding-right: 1rem !important;
+ padding-left: 1rem !important;
+
+}
+
+[dir="rtl"] .px-md-4 {
+
+ padding-right: 1.5rem !important;
+ padding-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .px-md-5 {
+
+ padding-right: 3rem !important;
+ padding-left: 3rem !important;
+
+}
+
+[dir="rtl"] .pe-md-0 {
+
+ padding-right: 0 !important;
+
+}
+
+[dir="rtl"] .pe-md-1 {
+
+ padding-right: 0.25rem !important;
+
+}
+
+[dir="rtl"] .pe-md-2 {
+
+ padding-right: 0.5rem !important;
+
+}
+
+[dir="rtl"] .pe-md-3 {
+
+ padding-right: 1rem !important;
+
+}
+
+[dir="rtl"] .pe-md-4 {
+
+ padding-right: 1.5rem !important;
+
+}
+
+[dir="rtl"] .pe-md-5 {
+
+ padding-right: 3rem !important;
+
+}
+
+[dir="rtl"] .ps-md-0 {
+
+ padding-left: 0 !important;
+
+}
+
+[dir="rtl"] .ps-md-1 {
+
+ padding-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .ps-md-2 {
+
+ padding-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .ps-md-3 {
+
+ padding-left: 1rem !important;
+
+}
+
+[dir="rtl"] .ps-md-4 {
+
+ padding-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .ps-md-5 {
+
+ padding-left: 3rem !important;
+
+}
+
+[dir="rtl"] .text-md-start {
+
+ text-align: left !important;
+
+}
+
+[dir="rtl"] .text-md-end {
+
+ text-align: left !important;
+
+}
+
+[dir="rtl"] }
+
+@media (min-width: 992px) {
+
+ .float-lg-start {
+ float: left !important;
+
+}
+
+[dir="rtl"] .float-lg-end {
+
+ float: left !important;
+
+}
+
+[dir="rtl"] .mx-lg-0 {
+
+ margin-right: 0 !important;
+ margin-left: 0 !important;
+
+}
+
+[dir="rtl"] .mx-lg-1 {
+
+ margin-right: 0.25rem !important;
+ margin-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .mx-lg-2 {
+
+ margin-right: 0.5rem !important;
+ margin-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .mx-lg-3 {
+
+ margin-right: 1rem !important;
+ margin-left: 1rem !important;
+
+}
+
+[dir="rtl"] .mx-lg-4 {
+
+ margin-right: 1.5rem !important;
+ margin-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .mx-lg-5 {
+
+ margin-right: 3rem !important;
+ margin-left: 3rem !important;
+
+}
+
+[dir="rtl"] .mx-lg-auto {
+
+ margin-right: auto !important;
+ margin-left: auto !important;
+
+}
+
+[dir="rtl"] .me-lg-0 {
+
+ margin-right: 0 !important;
+
+}
+
+[dir="rtl"] .me-lg-1 {
+
+ margin-right: 0.25rem !important;
+
+}
+
+[dir="rtl"] .me-lg-2 {
+
+ margin-right: 0.5rem !important;
+
+}
+
+[dir="rtl"] .me-lg-3 {
+
+ margin-right: 1rem !important;
+
+}
+
+[dir="rtl"] .me-lg-4 {
+
+ margin-right: 1.5rem !important;
+
+}
+
+[dir="rtl"] .me-lg-5 {
+
+ margin-right: 3rem !important;
+
+}
+
+[dir="rtl"] .me-lg-auto {
+
+ margin-right: auto !important;
+
+}
+
+[dir="rtl"] .ms-lg-0 {
+
+ margin-left: 0 !important;
+
+}
+
+[dir="rtl"] .ms-lg-1 {
+
+ margin-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .ms-lg-2 {
+
+ margin-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .ms-lg-3 {
+
+ margin-left: 1rem !important;
+
+}
+
+[dir="rtl"] .ms-lg-4 {
+
+ margin-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .ms-lg-5 {
+
+ margin-left: 3rem !important;
+
+}
+
+[dir="rtl"] .ms-lg-auto {
+
+ margin-left: auto !important;
+
+}
+
+[dir="rtl"] .px-lg-0 {
+
+ padding-right: 0 !important;
+ padding-left: 0 !important;
+
+}
+
+[dir="rtl"] .px-lg-1 {
+
+ padding-right: 0.25rem !important;
+ padding-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .px-lg-2 {
+
+ padding-right: 0.5rem !important;
+ padding-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .px-lg-3 {
+
+ padding-right: 1rem !important;
+ padding-left: 1rem !important;
+
+}
+
+[dir="rtl"] .px-lg-4 {
+
+ padding-right: 1.5rem !important;
+ padding-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .px-lg-5 {
+
+ padding-right: 3rem !important;
+ padding-left: 3rem !important;
+
+}
+
+[dir="rtl"] .pe-lg-0 {
+
+ padding-right: 0 !important;
+
+}
+
+[dir="rtl"] .pe-lg-1 {
+
+ padding-right: 0.25rem !important;
+
+}
+
+[dir="rtl"] .pe-lg-2 {
+
+ padding-right: 0.5rem !important;
+
+}
+
+[dir="rtl"] .pe-lg-3 {
+
+ padding-right: 1rem !important;
+
+}
+
+[dir="rtl"] .pe-lg-4 {
+
+ padding-right: 1.5rem !important;
+
+}
+
+[dir="rtl"] .pe-lg-5 {
+
+ padding-right: 3rem !important;
+
+}
+
+[dir="rtl"] .ps-lg-0 {
+
+ padding-left: 0 !important;
+
+}
+
+[dir="rtl"] .ps-lg-1 {
+
+ padding-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .ps-lg-2 {
+
+ padding-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .ps-lg-3 {
+
+ padding-left: 1rem !important;
+
+}
+
+[dir="rtl"] .ps-lg-4 {
+
+ padding-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .ps-lg-5 {
+
+ padding-left: 3rem !important;
+
+}
+
+[dir="rtl"] .text-lg-start {
+
+ text-align: left !important;
+
+}
+
+[dir="rtl"] .text-lg-end {
+
+ text-align: left !important;
+
+}
+
+[dir="rtl"] }
+
+@media (min-width: 1200px) {
+
+ .float-xl-start {
+ float: left !important;
+
+}
+
+[dir="rtl"] .float-xl-end {
+
+ float: left !important;
+
+}
+
+[dir="rtl"] .mx-xl-0 {
+
+ margin-right: 0 !important;
+ margin-left: 0 !important;
+
+}
+
+[dir="rtl"] .mx-xl-1 {
+
+ margin-right: 0.25rem !important;
+ margin-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .mx-xl-2 {
+
+ margin-right: 0.5rem !important;
+ margin-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .mx-xl-3 {
+
+ margin-right: 1rem !important;
+ margin-left: 1rem !important;
+
+}
+
+[dir="rtl"] .mx-xl-4 {
+
+ margin-right: 1.5rem !important;
+ margin-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .mx-xl-5 {
+
+ margin-right: 3rem !important;
+ margin-left: 3rem !important;
+
+}
+
+[dir="rtl"] .mx-xl-auto {
+
+ margin-right: auto !important;
+ margin-left: auto !important;
+
+}
+
+[dir="rtl"] .me-xl-0 {
+
+ margin-right: 0 !important;
+
+}
+
+[dir="rtl"] .me-xl-1 {
+
+ margin-right: 0.25rem !important;
+
+}
+
+[dir="rtl"] .me-xl-2 {
+
+ margin-right: 0.5rem !important;
+
+}
+
+[dir="rtl"] .me-xl-3 {
+
+ margin-right: 1rem !important;
+
+}
+
+[dir="rtl"] .me-xl-4 {
+
+ margin-right: 1.5rem !important;
+
+}
+
+[dir="rtl"] .me-xl-5 {
+
+ margin-right: 3rem !important;
+
+}
+
+[dir="rtl"] .me-xl-auto {
+
+ margin-right: auto !important;
+
+}
+
+[dir="rtl"] .ms-xl-0 {
+
+ margin-left: 0 !important;
+
+}
+
+[dir="rtl"] .ms-xl-1 {
+
+ margin-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .ms-xl-2 {
+
+ margin-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .ms-xl-3 {
+
+ margin-left: 1rem !important;
+
+}
+
+[dir="rtl"] .ms-xl-4 {
+
+ margin-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .ms-xl-5 {
+
+ margin-left: 3rem !important;
+
+}
+
+[dir="rtl"] .ms-xl-auto {
+
+ margin-left: auto !important;
+
+}
+
+[dir="rtl"] .px-xl-0 {
+
+ padding-right: 0 !important;
+ padding-left: 0 !important;
+
+}
+
+[dir="rtl"] .px-xl-1 {
+
+ padding-right: 0.25rem !important;
+ padding-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .px-xl-2 {
+
+ padding-right: 0.5rem !important;
+ padding-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .px-xl-3 {
+
+ padding-right: 1rem !important;
+ padding-left: 1rem !important;
+
+}
+
+[dir="rtl"] .px-xl-4 {
+
+ padding-right: 1.5rem !important;
+ padding-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .px-xl-5 {
+
+ padding-right: 3rem !important;
+ padding-left: 3rem !important;
+
+}
+
+[dir="rtl"] .pe-xl-0 {
+
+ padding-right: 0 !important;
+
+}
+
+[dir="rtl"] .pe-xl-1 {
+
+ padding-right: 0.25rem !important;
+
+}
+
+[dir="rtl"] .pe-xl-2 {
+
+ padding-right: 0.5rem !important;
+
+}
+
+[dir="rtl"] .pe-xl-3 {
+
+ padding-right: 1rem !important;
+
+}
+
+[dir="rtl"] .pe-xl-4 {
+
+ padding-right: 1.5rem !important;
+
+}
+
+[dir="rtl"] .pe-xl-5 {
+
+ padding-right: 3rem !important;
+
+}
+
+[dir="rtl"] .ps-xl-0 {
+
+ padding-left: 0 !important;
+
+}
+
+[dir="rtl"] .ps-xl-1 {
+
+ padding-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .ps-xl-2 {
+
+ padding-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .ps-xl-3 {
+
+ padding-left: 1rem !important;
+
+}
+
+[dir="rtl"] .ps-xl-4 {
+
+ padding-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .ps-xl-5 {
+
+ padding-left: 3rem !important;
+
+}
+
+[dir="rtl"] .text-xl-start {
+
+ text-align: left !important;
+
+}
+
+[dir="rtl"] .text-xl-end {
+
+ text-align: left !important;
+
+}
+
+[dir="rtl"] }
+
+@media (min-width: 1400px) {
+
+ .float-xxl-start {
+ float: left !important;
+
+}
+
+[dir="rtl"] .float-xxl-end {
+
+ float: left !important;
+
+}
+
+[dir="rtl"] .mx-xxl-0 {
+
+ margin-right: 0 !important;
+ margin-left: 0 !important;
+
+}
+
+[dir="rtl"] .mx-xxl-1 {
+
+ margin-right: 0.25rem !important;
+ margin-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .mx-xxl-2 {
+
+ margin-right: 0.5rem !important;
+ margin-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .mx-xxl-3 {
+
+ margin-right: 1rem !important;
+ margin-left: 1rem !important;
+
+}
+
+[dir="rtl"] .mx-xxl-4 {
+
+ margin-right: 1.5rem !important;
+ margin-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .mx-xxl-5 {
+
+ margin-right: 3rem !important;
+ margin-left: 3rem !important;
+
+}
+
+[dir="rtl"] .mx-xxl-auto {
+
+ margin-right: auto !important;
+ margin-left: auto !important;
+
+}
+
+[dir="rtl"] .me-xxl-0 {
+
+ margin-right: 0 !important;
+
+}
+
+[dir="rtl"] .me-xxl-1 {
+
+ margin-right: 0.25rem !important;
+
+}
+
+[dir="rtl"] .me-xxl-2 {
+
+ margin-right: 0.5rem !important;
+
+}
+
+[dir="rtl"] .me-xxl-3 {
+
+ margin-right: 1rem !important;
+
+}
+
+[dir="rtl"] .me-xxl-4 {
+
+ margin-right: 1.5rem !important;
+
+}
+
+[dir="rtl"] .me-xxl-5 {
+
+ margin-right: 3rem !important;
+
+}
+
+[dir="rtl"] .me-xxl-auto {
+
+ margin-right: auto !important;
+
+}
+
+[dir="rtl"] .ms-xxl-0 {
+
+ margin-left: 0 !important;
+
+}
+
+[dir="rtl"] .ms-xxl-1 {
+
+ margin-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .ms-xxl-2 {
+
+ margin-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .ms-xxl-3 {
+
+ margin-left: 1rem !important;
+
+}
+
+[dir="rtl"] .ms-xxl-4 {
+
+ margin-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .ms-xxl-5 {
+
+ margin-left: 3rem !important;
+
+}
+
+[dir="rtl"] .ms-xxl-auto {
+
+ margin-left: auto !important;
+
+}
+
+[dir="rtl"] .px-xxl-0 {
+
+ padding-right: 0 !important;
+ padding-left: 0 !important;
+
+}
+
+[dir="rtl"] .px-xxl-1 {
+
+ padding-right: 0.25rem !important;
+ padding-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .px-xxl-2 {
+
+ padding-right: 0.5rem !important;
+ padding-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .px-xxl-3 {
+
+ padding-right: 1rem !important;
+ padding-left: 1rem !important;
+
+}
+
+[dir="rtl"] .px-xxl-4 {
+
+ padding-right: 1.5rem !important;
+ padding-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .px-xxl-5 {
+
+ padding-right: 3rem !important;
+ padding-left: 3rem !important;
+
+}
+
+[dir="rtl"] .pe-xxl-0 {
+
+ padding-right: 0 !important;
+
+}
+
+[dir="rtl"] .pe-xxl-1 {
+
+ padding-right: 0.25rem !important;
+
+}
+
+[dir="rtl"] .pe-xxl-2 {
+
+ padding-right: 0.5rem !important;
+
+}
+
+[dir="rtl"] .pe-xxl-3 {
+
+ padding-right: 1rem !important;
+
+}
+
+[dir="rtl"] .pe-xxl-4 {
+
+ padding-right: 1.5rem !important;
+
+}
+
+[dir="rtl"] .pe-xxl-5 {
+
+ padding-right: 3rem !important;
+
+}
+
+[dir="rtl"] .ps-xxl-0 {
+
+ padding-left: 0 !important;
+
+}
+
+[dir="rtl"] .ps-xxl-1 {
+
+ padding-left: 0.25rem !important;
+
+}
+
+[dir="rtl"] .ps-xxl-2 {
+
+ padding-left: 0.5rem !important;
+
+}
+
+[dir="rtl"] .ps-xxl-3 {
+
+ padding-left: 1rem !important;
+
+}
+
+[dir="rtl"] .ps-xxl-4 {
+
+ padding-left: 1.5rem !important;
+
+}
+
+[dir="rtl"] .ps-xxl-5 {
+
+ padding-left: 3rem !important;
+
+}
+
+[dir="rtl"] .text-xxl-start {
+
+ text-align: left !important;
+
+}
+
+[dir="rtl"] .text-xxl-end {
+
+ text-align: left !important;
+
+}
+
+[dir="rtl"] .minicolors-theme-bootstrap .minicolors-swatch>.minicolors-sprite {
+
+ top: 50%;
+ right: 8px;
+ border-radius: 0;
+ -webkit-transform: translateY(-50%);
+ transform: translateY(-50%);
+}
+
+[dir="rtl"] .com-contact__thumbnail {
+
+ text-align: left;
+ margin: 2rem;
+ padding:1rem;
+}
+
+[dir="rtl"] .com-contact__container .com-contact__thumbnail {
+
+ grid-column: 1/5;
+ grid-row: 2/5;
+ text-align: left;
+
+}
+
+[dir="rtl"] figure.float-start {
+
+ margin-right: 1rem;
+}
+
+[dir="rtl"] figure.float-end {
+
+ margin-left: 1rem;
+}
+
+[dir="rtl"] .pagenavigation .pagination .next:only-child,
+[dir="rtl"] .pager .pagination .next:only-child {
+
+ margin-left: auto;
+}
+
+[dir="rtl"] .checkboxes .checkbox input {
+
+ position: static;
+ margin-left: 0;
+}
+
+[dir="rtl"] [role=tooltip]:not(.show) {
+
+ left: 5rem;
+ z-index: 1070;
+ display: none;
+ max-width: 100%;
+ padding: 0.5rem;
+ margin: 0.5rem;
+ color: hsl(0, 0%, 0%);
+ text-align: start;
+ background: var(--body-bg);
+ border: 1px solid hsl(210, 7%, 46%);
+ border-radius: 0.25rem;
+ -webkit-box-shadow: 0 0 0.5rem rgba(0, 0, 0, 0.8);
+ box-shadow: 0 0 0.5rem rgba(0, 0, 0, 0.8);
+}
+
+[dir="rtl"] [role=tooltip]:not(.show)[id^=editarticle-] {
+
+ left: auto;
+ -webkit-margin-start: -10rem;
+ margin-inline-start: -10rem;
+}
+
+[dir="rtl"] [role=tooltip]:not(.show)[id^=editcontact-] {
+
+ left: auto;
+ -webkit-margin-start: -10rem;
+ margin-inline-start: -10rem;
+}
+
+[dir="rtl"] [role=tooltip]:not(.show)[id^=id-skip-] {
+
+ left: auto;
+}
+
+[dir="rtl"] [role=tooltip]:not(.show)[id^=cbunpublish] {
+
+ left: auto;
+}
+
+[dir="rtl"] .btn.jmodedit {
+
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: auto;
+ z-index: 900;
+ color: var(--color-link);
+ background-color: rgba(255, 255, 255, 0.5);
+ border: 1px solid #58595a;
+ border-radius: 0.25rem;
+}
+
+[dir="rtl"] .container-header .container-nav {
+
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ padding-bottom: 0.3rem;
+ background-color: var(--nav-bg-color);
+ border-width: var(--border) 0;
+ border-top: solid var(--accent-color-primary);
+ border-bottom: solid var(--accent-color-secondary);
+ border-left: none;
+ border-right: none;
+}
+
+[dir="rtl"] }
+
+.container-header .container-nav .container-search:only-child {
+
+ margin-left: auto;
+}
+
+[dir="rtl"] @media (min-width: 992px) {
+
+ .container-header .mod-menu>li+li {
+ margin-left: 1.55rem;
+
+}
+
+[dir="rtl"] @media (min-width: 992px) {
+
+ .container-header .mod-menu>li::after {
+ position: absolute;
+ left: 50%;
+ bottom: 0;
+ right: 50%;
+ display: block;
+ height: 2px;
+ margin: auto;
+ content: "";
+ background: transparent;
+ opacity: 0.2;
+ -webkit-transition: all 0.2s ease, background-color 0.2s ease;
+ -o-transition: all 0.2s ease, background-color 0.2s ease;
+ transition: all 0.2s ease, background-color 0.2s ease;
+
+}
+
+[dir="rtl"] }
+
+.container-header .mod-menu>li.active::after,
+[dir="rtl"] .container-header .mod-menu>li:active::after {
+
+ left: 2px;
+ right: 0;
+ background: var(--navbar-brand-color);
+}
+
+[dir="rtl"] .container-header .metismenu>li+li {
+
+ margin-left: 0;
+}
+
+[dir="rtl"] @media (min-width: 992px) {
+
+
+ .container-header .metismenu>li>a::after,
+ .container-header .metismenu>li>button::before {
+ position: absolute;
+ left: 50%;
+ bottom: 0;
+ right: 50%;
+ display: block;
+ height: 2px;
+ margin: auto;
+ content: "";
+ background: transparent;
+ opacity: 0.2;
+ -webkit-transition: all 0.2s ease, background-color 0.2s ease;
+ -o-transition: all 0.2s ease, background-color 0.2s ease;
+ transition: all 0.2s ease, background-color 0.2s ease;
+
+}
+
+[dir="rtl"] }
+
+.container-header .metismenu>li>a:active::after,
+[dir="rtl"] .container-header .metismenu>li>button:active::before,
+[dir="rtl"] .container-header .metismenu>li.active>a::after,
+[dir="rtl"] .container-header .metismenu>li.active>button::before {
+
+ left: 0;
+ right: 0;
+ background: var(--navbar-color);
+}
+
+[dir="rtl"] .container-header .metismenu>li>button.mm-toggler-link:active::before,
+[dir="rtl"] .container-header .metismenu>li.active>button.mm-toggler-link::before {
+
+ left: 0;
+ right: 0.5rem;
+}
+
+[dir="rtl"] .grid-child {
+
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ margin-right: auto;
+ margin-left: auto;
+}
+
+[dir="rtl"] .modal .btn {
+
+ margin-right: 0.5rem;
+}
+
+[dir="rtl"] }
+
+.blog-items {
+
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ width: 100%;
+ padding: 0;
+ margin-right: -0.5rem;
+ margin-bottom: 1rem;
+ margin-left: -0.5rem;
+}
+
+[dir="rtl"] }
+
+.readmore {
+
+ text-align: left;
+}
+
+[dir="rtl"] .image-left .blog-item .item-content {
+
+ padding-left: 25px;
+}
+
+[dir="rtl"] .image-right .blog-item .item-content {
+
+ padding-right: 25px;
+}
+
+[dir="rtl"] .image-left .blog-item .item-image,
+[dir="rtl"] .image-right .blog-item .item-image {
+
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 40%;
+ flex: 1 0 40%;
+ max-width: 35%;
+ margin-right: 1rem;
+
+}
+
+[dir="rtl"] .image-alternate.image-left .blog-item:nth-of-type(2n+1) .item-image {
+
+ margin-right: 0;
+ margin-left: 25px;
+ -webkit-box-ordinal-group: 2;
+ -ms-flex-order: 1;
+ order: 1;
+}
+
+[dir="rtl"] .mod-list li .mod-menu__sub {
+
+ padding-left: 1rem;
+}
+
+[dir="rtl"] .subhead {
+
+ position: sticky;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 1000;
+ width: auto;
+ min-height: 43px;
+ padding: 0.25rem;
+ color: #495057;
+ background: var(--body-bg);
+ -webkit-box-shadow: -3px -2px 22px #ddd;
+ box-shadow: -3px -2px 22px #ddd;
+}
+
+[dir="rtl"] .subhead .row {
+
+ margin-right: 0;
+ margin-left: 0;
+}
+
+[dir="rtl"] .subhead joomla-toolbar-button,
+[dir="rtl"] .subhead .btn-group,
+[dir="rtl"] .subhead .btn {
+
+ width: 100%;
+ margin-left: 0;
+ text-align: left;
+
+}
+
+[dir="rtl"] .subhead .btn-toolbar>.btn-group,
+[dir="rtl"] .subhead .btn-toolbar>joomla-toolbar-button {
+
+ margin-left: 0;
+
+}
+
+[dir="rtl"] }
+
+.left.item-image {
+
+ float: left;
+}
+
+[dir="rtl"] .right.item-image {
+
+ float: left;
+ width: 40%;
+ max-width: 300px;
+}
+
+[dir="rtl"] body.wrapper-fluid header>.grid-child,
+[dir="rtl"] body.wrapper-fluid footer>.grid-child {
+
+ padding-right: 2rem;
+ padding-left: 2rem;
+ padding-top: 0;
+ padding-bottom: 0;
+ //margin-left: 6rem;
+ //margin-right: 6rem;
+}
+
+[dir="rtl"] header .grid-child .navbar-brand {
+
+ padding-left: 0;
+ padding-right: 0;
+}
+
+[dir="rtl"] .dropdown-menu-end::after {
+
+ left: 0.9rem;
+ right: auto;
+}
+
+[dir="rtl"] .list-unstyled .list-unstyled {
+
+ padding-left: 20px;
+}
+
+[dir="rtl"] .nav.nav-tabs .nav-item {
+
+ margin-bottom: 0;
+ margin-left: 0;
+}
+
+[dir="rtl"] .nav.nav-tabs .nav-link.active {
+
+ background-color: hsla(0, 0%, 0%, 0.3);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(hsla(0, 0%, 0%, 0)), to(hsla(0, 0%, 0%, 0.05)));
+ background-image: -o-linear-gradient(top, hsla(0, 0%, 0%, 0), hsla(0, 0%, 0%, 0.05) 100%);
+ background-image: linear-gradient(to bottom, hsla(0, 0%, 0%, 0), hsla(0, 0%, 0%, 0.05) 100%);
+ border-right: 0;
+ border-left: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ -webkit-box-shadow: inset 2px 0 1px -1px hsla(0, 0%, 0%, 0.08), inset -2px 0 1px -1px hsla(0, 0%, 0%, 0.08), inset 0 1px 0 hsla(0, 0%, 0%, 0.02);
+ box-shadow: inset 2px 0 1px -1px hsla(0, 0%, 0%, 0.08), inset -2px 0 1px -1px hsla(0, 0%, 0%, 0.08), inset 0 1px 0 hsla(0, 0%, 0%, 0.02);
+}
+
+[dir="rtl"] .nav.nav-tabs .nav-link.active::after {
+
+ position: absolute;
+ left: 0;
+ bottom: -1px;
+ right: 0;
+ height: 5px;
+ content: "";
+ background-color: var(--color-primary);
+ opacity: 0.8;
+}
+
+[dir="rtl"] .chosen-container.chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
+
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 100%;
+ background: hsla(0, 0%, 0%, 0.2);
+ background-image: none !important;
+}
+
+[dir="rtl"] .chosen-container.chosen-container-multi .chosen-choices li.search-choice .search-choice-close::before {
+
+ position: absolute;
+ top: 6px;
+ left: 5px;
+ font-size: 1rem;
+ color: var(--white);
+ content: "×";
+}
+
+[dir="rtl"] .metismenu.mod-menu .metismenu-item.divider:not(.parent) {
+
+ width: 1px;
+ padding: 0;
+ margin: 0.25rem;
+ overflow: hidden;
+ border-right: 1px solid var(--border-color);
+}
+
+[dir="rtl"] .metismenu.mod-menu .mm-toggler:after {
+
+ width: 0;
+ height: 0;
+ -webkit-margin-start: 0.5rem;
+ margin-inline-start: 0.5rem;
+ content: "";
+ border-top: 0.5rem solid currentColor;
+ border-right: 0.5rem solid transparent;
+ border-left: 0.5rem solid transparent;
+ -webkit-transition: all 0.3s ease-out;
+ -o-transition: all 0.3s ease-out;
+ transition: all 0.3s ease-out;
+}
+
+[dir="rtl"] /*!
+ * Bootstrap Table of Contents v1.0.1 (http://afeld.github.io/bootstrap-toc/)
+ * Copyright 2015 Aidan Feldman
+ * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE)
+ *
+ * Custom layout/styling modifications by Moko Consulting
+ * © 2025 Moko Consulting — All Rights Reserved
+ * Website: https://mokoconsulting.tech
+ * Email: hello@mokoconsulting.tech
+ * Phone: +1 (931) 279-6313
+ */
+
+
+/* --- TOC right-rail container (non-invasive) --- */
+.container-toc-right {
+
+ float: left;
+ width: 280px;
+ margin: 0 0 1.25rem 1.25rem;
+ /* gap from main content */
+ position: relative;
+ z-index: 1;
+ color: var(--container-toc-color);
+}
+
+[dir="rtl"] }
+
+/* --- TOC left-rail container (non-invasive) --- */
+.container-toc-left {
+
+ float: left;
+ width: 280px;
+ margin: 0 1.25rem 1.25rem 0;
+ /* space on right side for main content */
+ position: relative;
+ z-index: 1;
+ color: var(--container-toc-color);
+}
+
+[dir="rtl"] .container-top-a {
+
+ padding-left: var(--border);
+ padding-right: var(--border);
+ background-image: var(--container-top-a-bg-image);
+ background-color: var(--container-top-a-bg-color);
+ background-size: var(--container-top-a-bg-size);
+ -webkit-box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ background-repeat: var(--container-top-a-background-repeat);
+ -webkit-border-radius: var(--container-top-a-border-radius);
+ -moz-border-radius: var(--container-top-a-border-radius);
+ border-radius: var(--container-top-a-border-radius);
+ border: var(--container-top-a-border);
+}
+
+[dir="rtl"] .container-top-b {
+
+ padding-left: var(--border);
+ padding-right: var(--border);
+ background-image: var(--container-top-b-bg-image);
+ background-color: var(--container-top-b-bg-color);
+ background-size: var(--container-top-b-bg-size);
+ -webkit-box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ background-repeat: var(--container-top-b-background-repeat);
+ -webkit-border-radius: var(--container-top-b-border-radius);
+ -moz-border-radius: var(--container-top-b-border-radius);
+ border-radius: var(--container-top-b-border-radius);
+ border: var(--container-top-b-border);
+}
+
+[dir="rtl"] .container-sidebar-left,
+[dir="rtl"] .container-sidebar-right {
+
+ padding-left: var(--border);
+ padding-right: var(--border);
+ background-image: var(--container-sidebar-bg-image);
+ background-color: var(--container-sidebar-bg-color);
+ background-size: var(--container-sidebar-bg-size);
+ -webkit-box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ background-repeat: var(--container-sidebar-background-repeat);
+ -webkit-border-radius: var(--container-sidebar-border-radius);
+ -moz-border-radius: var(--container-sidebar-border-radius);
+ border-radius: var(--container-sidebar-border-radius);
+ border: var(--container-sidebar-border);
+}
+
+[dir="rtl"] .container-bottom-a {
+
+ padding-left: var(--border);
+ padding-right: var(--border);
+ background-image: var(--container-bottom-a-bg-image);
+ background-color: var(--container-bottom-a-bg-color);
+ background-size: var(--container-bottom-a-bg-size);
+ -webkit-box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ background-repeat: var(--container-bottom-a-background-repeat);
+ -webkit-border-radius: var(--container-bottom-a-border-radius);
+ -moz-border-radius: var(--container-bottom-a-border-radius);
+ border-radius: var(--container-bottom-a-border-radius);
+ border: var(--container-bottom-a-border);
+}
+
+[dir="rtl"] .container-bottom-b {
+
+ padding-left: var(--border);
+ padding-right: var(--border);
+ background-image: var(--container-bottom-b-bg-image);
+ background-color: var(--container-bottom-b-bg-color);
+ background-size: var(--container-bottom-b-bg-size);
+ -webkit-box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ background-repeat: var(--container-bottom-b-background-repeat);
+ -webkit-border-radius: var(--container-bottom-b-border-radius);
+ -moz-border-radius: var(--container-bottom-b-border-radius);
+ border-radius: var(--container-bottom-b-border-radius);
+ border: var(--container-bottom-b-border);
+}
+
+[dir="rtl"] #mokoThemeFab.pos-br {
+ left: 1rem; bottom: 1rem;
+}
+
+[dir="rtl"] #mokoThemeFab.pos-bl {
+ right: 1rem; bottom: 1rem;
+}
+
+[dir="rtl"] #mokoThemeFab.pos-tr {
+ left: 1rem; top: 1rem;
+}
+
+[dir="rtl"] #mokoThemeFab.pos-tl {
+ right: 1rem; top: 1rem;
+}
+
+[dir="rtl"] #mokoThemeFab .knob {
+
+ position: absolute; top: 2px; right: 2px;
+ width: 20px; height: 20px; border-radius: 50%;
+ background: var(--bs-body-bg, #fff);
+ box-shadow: 0 1px 3px rgba(0,0,0,.25);
+ transition: transform .2s ease;
+}
diff --git a/src/media/css/template.css b/src/media/css/template.css
new file mode 100644
index 0000000..7b5da4f
--- /dev/null
+++ b/src/media/css/template.css
@@ -0,0 +1,23449 @@
+@charset "UTF-8";
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+*,
+*::before,
+*::after {
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+/* Smooth scroll and colour transitions; gated so reduced-motion users are unaffected. */
+@media (prefers-reduced-motion: no-preference) {
+ :root {
+ scroll-behavior: smooth;
+ }
+
+ :root,
+ body,
+ .container-wrapper,
+ .container-main,
+ nav,
+ header,
+ footer {
+ transition:
+ background-color 0.3s ease,
+ color 0.3s ease,
+ border-color 0.3s ease;
+ }
+}
+
+@media print {
+
+ nav,
+ .container-topbar,
+ .container-nav,
+ #rssocial-133,
+ .container-sidebar-right,
+ .container-sidebar-left,
+ .container-bottom-a,
+ .container-bottom-b,
+ #lhc_container_v2 *,
+ footer,
+ .fb-comments {
+ display: none ;
+ }
+}
+
+body {
+ margin: 0;
+ font-family: var(--body-font-family);
+ font-size: var(--body-font-size, 1rem);
+ font-weight: var(--body-font-weight, 400);
+ line-height: var(--body-line-height, 1.5);
+ color: var(--body-color, #e6ebf1);
+ text-align: var(--body-text-align);
+ background: var(--body-bg, #0e1318);
+ -webkit-text-size-adjust: 100%;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+form {
+ margin-block-end: 1em;
+}
+
+.table-of-contents-ck-wrap {
+ width: 30%;
+ float: right;
+ border: 1px solid var(--color-primary, #112855);
+}
+
+.table-of-contents-ck-toggler {
+ font-size: 2em;
+ font-weight: bold;
+ background-color: var(--gray-500, #36404a);
+ padding: var(--btn-padding-y, 0.6rem) var(--btn-padding-x, 1rem);
+ color: var(--color-link, white);
+ text-align: center;
+}
+
+.table-of-contents-ck-toggler a {
+ font-size: .5em;
+ font-weight: normal;
+ color: var(--color-link, white);
+ display: block;
+ text-align: center;
+}
+
+.table-of-contents-ck,
+.table-of-contents-ck a {
+ font-size: 1.25em;
+ color: var(--color-link, white);
+}
+
+.offcanvas-start,
+.offcanvas-end {
+ width: 280px;
+}
+
+.drawer-toggle-left{
+ position: fixed;
+ top: 50%;
+ left: 0px;
+ z-index: 1050;
+ background-color: var(--nav-bg-color);
+ color: var(--nav-text-color, gray);
+ padding-left: .5rem;
+ padding-right: .5rem;
+}
+
+.drawer-toggle-right{
+ position: fixed;
+ top: 50%;
+ right: 0px;
+ z-index: 1050;
+ background-color: var(--nav-bg-color);
+ color: var(--nav-text-color, gray);
+ padding-left: .5rem;
+ padding-right: .5rem;
+}
+
+hr {
+ margin: 1rem 0;
+ color: inherit;
+ border: 0;
+ border-top: 1px solid;
+ opacity: 0.25;
+}
+
+h6,
+.h6,
+h5,
+.h5,
+h4,
+.h4,
+h3,
+.h3,
+h2,
+.h2,
+h1,
+.h1 {
+ margin-top: 0;
+ margin-bottom: 0.5rem;
+ font-weight: 500;
+ line-height: 1.2;
+}
+
+h1,
+.h1 {
+ font-size: calc(1.375rem + 1.5vw);
+}
+
+@media (min-width: 1200px) {
+
+ h1,
+ .h1 {
+ font-size: 2.5rem;
+ }
+}
+
+h2,
+.h2 {
+ font-size: calc(1.325rem + 0.9vw);
+}
+
+@media (min-width: 1200px) {
+
+ h2,
+ .h2 {
+ font-size: 2rem;
+ }
+}
+
+h3,
+.h3 {
+ font-size: calc(1.3rem + 0.6vw);
+}
+
+@media (min-width: 1200px) {
+
+ h3,
+ .h3 {
+ font-size: 1.75rem;
+ }
+}
+
+h4,
+.h4 {
+ font-size: calc(1.275rem + 0.3vw);
+}
+
+@media (min-width: 1200px) {
+
+ h4,
+ .h4 {
+ font-size: 1.5rem;
+ }
+}
+
+h5,
+.h5 {
+ font-size: 1.25rem;
+}
+
+h6,
+.h6 {
+ font-size: 1rem;
+}
+
+p {
+ margin-top: 0;
+ margin-bottom: 1rem;
+}
+
+abbr[title] {
+ -webkit-text-decoration: underline dotted;
+ text-decoration: underline dotted;
+ cursor: help;
+ -webkit-text-decoration-skip-ink: none;
+ text-decoration-skip-ink: none;
+}
+
+address {
+ margin-bottom: 1rem;
+ font-style: normal;
+ line-height: inherit;
+}
+
+ol,
+ul {
+ padding-left: 2rem;
+}
+
+ol,
+ul,
+dl {
+ margin-top: 0;
+ margin-bottom: 1rem;
+}
+
+ol ol,
+ul ul,
+ol ul,
+ul ol {
+ margin-bottom: 0;
+}
+
+dt {
+ font-weight: 700;
+}
+
+dd {
+ margin-bottom: 0.5rem;
+ margin-left: 0;
+}
+
+blockquote {
+ margin: 0 0 1rem;
+}
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+small,
+.small {
+ font-size: 0.875em;
+}
+
+mark,
+.mark {
+ padding: 0.1875em;
+ background-color: var(--highlight-bg, #ffe28a1a);
+}
+
+sub,
+sup {
+ position: relative;
+ font-size: 0.75em;
+ line-height: 0;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+a {
+ color: var(--link-color, #8ab4f8);
+ text-decoration: underline;
+}
+
+a:active {
+ color: var(--link-active-color);
+}
+
+a:not([href]):not([class]),
+a:not([href]):not([class]):active {
+ color: inherit;
+ text-decoration: none;
+}
+
+pre,
+code,
+kbd,
+samp {
+ font-family: var(--font-monospace);
+ font-size: 1em;
+}
+
+pre {
+ display: block;
+ margin-top: 0;
+ margin-bottom: 1rem;
+ overflow: auto;
+ font-size: 0.875em;
+}
+
+pre code {
+ font-size: inherit;
+ color: inherit;
+ word-break: normal;
+}
+
+code {
+ font-size: 0.875em;
+ color: var(--code-color, black);
+ word-wrap: break-word;
+ padding: calc(var(--padding-x, 0.15rem) * 3);
+ background-color: var(--code-bg-color, lightgreen);
+}
+
+a>code {
+ color: inherit;
+}
+
+kbd {
+ padding: 0.1875rem 0.375rem;
+ font-size: 0.875em;
+ color: var(--body-bg, #0e1318);
+ background-color: var(--body-color, #e6ebf1);
+ border-radius: 0.2rem;
+}
+
+kbd kbd {
+ padding: 0;
+ font-size: 1em;
+}
+
+figure {
+ margin: 0 0 1rem;
+}
+
+img,
+svg {
+ vertical-align: middle;
+}
+
+table {
+ caption-side: bottom;
+ border-collapse: collapse;
+}
+
+caption {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ color: hsl(210, 7%, 46%);
+ text-align: left;
+}
+
+th {
+ text-align: inherit;
+ text-align: -webkit-match-parent;
+}
+
+thead,
+tbody,
+tfoot,
+tr,
+td,
+th {
+ border-color: inherit;
+ border-style: solid;
+ border-width: 0;
+}
+
+label {
+ display: inline-block;
+}
+
+button {
+ border-radius: 0;
+}
+
+button:focus:not(:focus-visible) {
+ outline: 0;
+}
+
+input,
+button,
+select,
+optgroup,
+textarea {
+ margin: 0;
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+
+button,
+select {
+ text-transform: none;
+}
+
+[role=button] {
+ cursor: pointer;
+}
+
+select {
+ word-wrap: normal;
+}
+
+select:disabled {
+ opacity: 1;
+}
+
+[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
+ display: none ;
+}
+
+button,
+[type=button],
+[type=reset],
+[type=submit] {
+ -webkit-appearance: button;
+}
+
+button:not(:disabled),
+[type=button]:not(:disabled),
+[type=reset]:not(:disabled),
+[type=submit]:not(:disabled) {
+ cursor: pointer;
+}
+
+::-moz-focus-inner {
+ padding: 0;
+ border-style: none;
+}
+
+textarea {
+ resize: vertical;
+}
+
+fieldset {
+ min-width: 0;
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+
+legend {
+ float: left;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 0.5rem;
+ font-size: calc(1.275rem + 0.3vw);
+ line-height: inherit;
+}
+
+@media (min-width: 1200px) {
+ legend {
+ font-size: 1.5rem;
+ }
+}
+
+legend+* {
+ clear: left;
+}
+
+::-webkit-datetime-edit-fields-wrapper,
+::-webkit-datetime-edit-text,
+::-webkit-datetime-edit-minute,
+::-webkit-datetime-edit-hour-field,
+::-webkit-datetime-edit-day-field,
+::-webkit-datetime-edit-month-field,
+::-webkit-datetime-edit-year-field {
+ padding: 0;
+}
+
+::-webkit-inner-spin-button {
+ height: auto;
+}
+
+[type=search] {
+ outline-offset: -2px;
+ -webkit-appearance: textfield;
+}
+
+/* rtl:raw:
+[type="tel"],
+[type="url"],
+[type="email"],
+[type="number"] {
+ direction: ltr;
+}
+*/
+::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+::-webkit-color-swatch-wrapper {
+ padding: 0;
+}
+
+::-webkit-file-upload-button {
+ font: inherit;
+ -webkit-appearance: button;
+}
+
+::file-selector-button {
+ font: inherit;
+ -webkit-appearance: button;
+}
+
+output {
+ display: inline-block;
+}
+
+iframe {
+ border: 0;
+}
+
+summary {
+ display: list-item;
+ cursor: pointer;
+}
+
+progress {
+ vertical-align: baseline;
+}
+
+[hidden] {
+ display: none ;
+}
+
+.lead {
+ font-size: 1.25rem;
+ font-weight: 300;
+}
+
+.display-1 {
+ font-size: calc(1.625rem + 4.5vw);
+ font-weight: 300;
+ line-height: 1.2;
+}
+
+@media (min-width: 1200px) {
+ .display-1 {
+ font-size: 5rem;
+ }
+}
+
+.display-2 {
+ font-size: calc(1.575rem + 3.9vw);
+ font-weight: 300;
+ line-height: 1.2;
+}
+
+@media (min-width: 1200px) {
+ .display-2 {
+ font-size: 4.5rem;
+ }
+}
+
+.display-3 {
+ font-size: calc(1.525rem + 3.3vw);
+ font-weight: 300;
+ line-height: 1.2;
+}
+
+@media (min-width: 1200px) {
+ .display-3 {
+ font-size: 4rem;
+ }
+}
+
+.display-4 {
+ font-size: calc(1.475rem + 2.7vw);
+ font-weight: 300;
+ line-height: 1.2;
+}
+
+@media (min-width: 1200px) {
+ .display-4 {
+ font-size: 3.5rem;
+ }
+}
+
+.display-5 {
+ font-size: calc(1.425rem + 2.1vw);
+ font-weight: 300;
+ line-height: 1.2;
+}
+
+@media (min-width: 1200px) {
+ .display-5 {
+ font-size: 3rem;
+ }
+}
+
+.display-6 {
+ font-size: calc(1.375rem + 1.5vw);
+ font-weight: 300;
+ line-height: 1.2;
+}
+
+@media (min-width: 1200px) {
+ .display-6 {
+ font-size: 2.5rem;
+ }
+}
+
+.list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
+
+.list-inline {
+ padding-left: 0;
+ list-style: none;
+}
+
+.list-inline-item {
+ display: inline-block;
+}
+
+.list-inline-item:not(:last-child) {
+ margin-right: 0.5rem;
+}
+
+.initialism {
+ font-size: 0.875em;
+ text-transform: uppercase;
+}
+
+.blockquote {
+ margin-bottom: 1rem;
+ font-size: 1.25rem;
+}
+
+.blockquote> :last-child {
+ margin-bottom: 0;
+}
+
+.blockquote-footer {
+ margin-top: -1rem;
+ margin-bottom: 1rem;
+ font-size: 0.875em;
+ color: hsl(210, 7%, 46%);
+}
+
+.blockquote-footer::before {
+ content: "— ";
+}
+
+.img-fluid {
+ max-width: 100%;
+ height: auto;
+}
+
+.img-thumbnail {
+ padding: 0.25rem;
+ background-color: var(--body-color, #e6ebf1);
+ border: 1px solid var(--border-color, #2b323b);
+ border-radius: 0.25rem;
+ max-width: 100%;
+ height: auto;
+}
+
+.figure {
+ display: inline-block;
+}
+
+.figure-img {
+ margin-bottom: 0.5rem;
+ line-height: 1;
+}
+
+.figure-caption {
+ font-size: 0.875em;
+ color: hsl(210, 7%, 46%);
+}
+
+.container-component,
+.container,
+.container-fluid,
+.container-xxl,
+.container-xl,
+.container-lg,
+.container-md,
+.container-sm {
+ --gutter-x: 1em;
+ --gutter-y: 0;
+ width: 100%;
+ padding-right: calc(var(--gutter-x) * 0.5);
+ padding-left: calc(var(--gutter-x) * 0.5);
+ margin-right: auto;
+ margin-left: auto;
+}
+
+.topten-view,
+.featured-view,
+.latest-view,
+.recent-view,
+.products-view {
+ border-top: var(--accent-color-primary, #3f8ff0) 1px groove;
+}
+
+@media (min-width: 576px) {
+
+ .container-sm,
+ .container {
+ max-width: 540px;
+ }
+}
+
+@media (min-width: 768px) {
+
+ .container-md,
+ .container-sm,
+ .container {
+ max-width: 720px;
+ }
+}
+
+@media (min-width: 992px) {
+
+ .container-lg,
+ .container-md,
+ .container-sm,
+ .container {
+ max-width: 960px;
+ }
+}
+
+@media (min-width: 1200px) {
+
+ .container-xl,
+ .container-lg,
+ .container-md,
+ .container-sm,
+ .container {
+ max-width: 1140px;
+ }
+}
+
+@media (min-width: 1400px) {
+
+ .container-xxl,
+ .container-xl,
+ .container-lg,
+ .container-md,
+ .container-sm,
+ .container {
+ max-width: 1320px;
+ }
+}
+
+.row {
+ --gutter-x: 1em;
+ --gutter-y: 0;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ margin-top: 0;
+ margin-right: 0;
+ margin-left: 0;
+}
+
+.row > * {
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
+ width: 100%;
+ max-width: 100%;
+ padding-right: calc(0.25 * var(--gutter-x));
+ padding-left: calc(0.25 * var(--gutter-x));
+}
+
+.latest-view {
+ margin-top: var(--gutter-x);
+}
+
+.col {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 0%;
+ flex: 1 0 0%;
+}
+
+.row-cols-auto>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: auto;
+}
+
+.row-cols-1>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 100%;
+}
+
+.row-cols-2>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 50%;
+}
+
+.row-cols-3>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+}
+
+.row-cols-4>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 25%;
+}
+
+.row-cols-5>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 20%;
+}
+
+.row-cols-6>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+}
+
+.col-auto {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: auto;
+}
+
+.col-1 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 8.33333333%;
+}
+
+.col-2 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 16.66666667%;
+}
+
+.col-3 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 25%;
+}
+
+.col-4 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 33.33333333%;
+}
+
+.col-5 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 41.66666667%;
+}
+
+.col-6 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 50%;
+}
+
+.col-7 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 58.33333333%;
+}
+
+.col-8 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 66.66666667%;
+}
+
+.col-9 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 75%;
+}
+
+.col-10 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 83.33333333%;
+}
+
+.col-11 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 91.66666667%;
+}
+
+.col-12 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 100%;
+}
+
+.offset-1 {
+ margin-left: 8.33333333%;
+}
+
+.offset-2 {
+ margin-left: 16.66666667%;
+}
+
+.offset-3 {
+ margin-left: 25%;
+}
+
+.offset-4 {
+ margin-left: 33.33333333%;
+}
+
+.offset-5 {
+ margin-left: 41.66666667%;
+}
+
+.offset-6 {
+ margin-left: 50%;
+}
+
+.offset-7 {
+ margin-left: 58.33333333%;
+}
+
+.offset-8 {
+ margin-left: 66.66666667%;
+}
+
+.offset-9 {
+ margin-left: 75%;
+}
+
+.offset-10 {
+ margin-left: 83.33333333%;
+}
+
+.offset-11 {
+ margin-left: 91.66666667%;
+}
+
+.g-0,
+.gx-0 {
+ --gutter-x: 0;
+}
+
+.g-0,
+.gy-0 {
+ --gutter-y: 0;
+}
+
+.g-1,
+.gx-1 {
+ --gutter-x: 0.25rem;
+}
+
+.g-1,
+.gy-1 {
+ --gutter-y: 0.25rem;
+}
+
+.g-2,
+.gx-2 {
+ --gutter-x: 0.5rem;
+}
+
+.g-2,
+.gy-2 {
+ --gutter-y: 0.5rem;
+}
+
+.g-3,
+.gx-3 {
+ --gutter-x: 1rem;
+}
+
+.g-3,
+.gy-3 {
+ --gutter-y: 1rem;
+}
+
+.g-4,
+.gx-4 {
+ --gutter-x: 1.5rem;
+}
+
+.g-4,
+.gy-4 {
+ --gutter-y: 1.5rem;
+}
+
+.g-5,
+.gx-5 {
+ --gutter-x: 3rem;
+}
+
+.g-5,
+.gy-5 {
+ --gutter-y: 3rem;
+}
+
+@media (min-width: 576px) {
+ .col-sm {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 0%;
+ flex: 1 0 0%;
+ }
+
+ .row-cols-sm-auto>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .row-cols-sm-1>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .row-cols-sm-2>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .row-cols-sm-3>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+
+ .row-cols-sm-4>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .row-cols-sm-5>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 20%;
+ }
+
+ .row-cols-sm-6>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+
+ .col-sm-auto {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .col-sm-1 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 8.33333333%;
+ }
+
+ .col-sm-2 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 16.66666667%;
+ }
+
+ .col-sm-3 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .col-sm-4 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 33.33333333%;
+ }
+
+ .col-sm-5 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 41.66666667%;
+ }
+
+ .col-sm-6 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .col-sm-7 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 58.33333333%;
+ }
+
+ .col-sm-8 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 66.66666667%;
+ }
+
+ .col-sm-9 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 75%;
+ }
+
+ .col-sm-10 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 83.33333333%;
+ }
+
+ .col-sm-11 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 91.66666667%;
+ }
+
+ .col-sm-12 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .offset-sm-0 {
+ margin-left: 0;
+ }
+
+ .offset-sm-1 {
+ margin-left: 8.33333333%;
+ }
+
+ .offset-sm-2 {
+ margin-left: 16.66666667%;
+ }
+
+ .offset-sm-3 {
+ margin-left: 25%;
+ }
+
+ .offset-sm-4 {
+ margin-left: 33.33333333%;
+ }
+
+ .offset-sm-5 {
+ margin-left: 41.66666667%;
+ }
+
+ .offset-sm-6 {
+ margin-left: 50%;
+ }
+
+ .offset-sm-7 {
+ margin-left: 58.33333333%;
+ }
+
+ .offset-sm-8 {
+ margin-left: 66.66666667%;
+ }
+
+ .offset-sm-9 {
+ margin-left: 75%;
+ }
+
+ .offset-sm-10 {
+ margin-left: 83.33333333%;
+ }
+
+ .offset-sm-11 {
+ margin-left: 91.66666667%;
+ }
+
+ .g-sm-0,
+ .gx-sm-0 {
+ --gutter-x: 0;
+ }
+
+ .g-sm-0,
+ .gy-sm-0 {
+ --gutter-y: 0;
+ }
+
+ .g-sm-1,
+ .gx-sm-1 {
+ --gutter-x: 0.25rem;
+ }
+
+ .g-sm-1,
+ .gy-sm-1 {
+ --gutter-y: 0.25rem;
+ }
+
+ .g-sm-2,
+ .gx-sm-2 {
+ --gutter-x: 0.5rem;
+ }
+
+ .g-sm-2,
+ .gy-sm-2 {
+ --gutter-y: 0.5rem;
+ }
+
+ .g-sm-3,
+ .gx-sm-3 {
+ --gutter-x: 1rem;
+ }
+
+ .g-sm-3,
+ .gy-sm-3 {
+ --gutter-y: 1rem;
+ }
+
+ .g-sm-4,
+ .gx-sm-4 {
+ --gutter-x: 1.5rem;
+ }
+
+ .g-sm-4,
+ .gy-sm-4 {
+ --gutter-y: 1.5rem;
+ }
+
+ .g-sm-5,
+ .gx-sm-5 {
+ --gutter-x: 3rem;
+ }
+
+ .g-sm-5,
+ .gy-sm-5 {
+ --gutter-y: 3rem;
+ }
+}
+
+@media (min-width: 768px) {
+ .col-md {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 0%;
+ flex: 1 0 0%;
+ }
+
+ .row-cols-md-auto>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .row-cols-md-1>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .row-cols-md-2>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .row-cols-md-3>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+
+ .row-cols-md-4>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .row-cols-md-5>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 20%;
+ }
+
+ .row-cols-md-6>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+
+ .col-md-auto {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .col-md-1 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 8.33333333%;
+ }
+
+ .col-md-2 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 16.66666667%;
+ }
+
+ .col-md-3 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .col-md-4 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 33.33333333%;
+ }
+
+ .col-md-5 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 41.66666667%;
+ }
+
+ .col-md-6 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .col-md-7 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 58.33333333%;
+ }
+
+ .col-md-8 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 66.66666667%;
+ }
+
+ .col-md-9 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 75%;
+ }
+
+ .col-md-10 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 83.33333333%;
+ }
+
+ .col-md-11 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 91.66666667%;
+ }
+
+ .col-md-12 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .offset-md-0 {
+ margin-left: 0;
+ }
+
+ .offset-md-1 {
+ margin-left: 8.33333333%;
+ }
+
+ .offset-md-2 {
+ margin-left: 16.66666667%;
+ }
+
+ .offset-md-3 {
+ margin-left: 25%;
+ }
+
+ .offset-md-4 {
+ margin-left: 33.33333333%;
+ }
+
+ .offset-md-5 {
+ margin-left: 41.66666667%;
+ }
+
+ .offset-md-6 {
+ margin-left: 50%;
+ }
+
+ .offset-md-7 {
+ margin-left: 58.33333333%;
+ }
+
+ .offset-md-8 {
+ margin-left: 66.66666667%;
+ }
+
+ .offset-md-9 {
+ margin-left: 75%;
+ }
+
+ .offset-md-10 {
+ margin-left: 83.33333333%;
+ }
+
+ .offset-md-11 {
+ margin-left: 91.66666667%;
+ }
+
+ .g-md-0,
+ .gx-md-0 {
+ --gutter-x: 0;
+ }
+
+ .g-md-0,
+ .gy-md-0 {
+ --gutter-y: 0;
+ }
+
+ .g-md-1,
+ .gx-md-1 {
+ --gutter-x: 0.25rem;
+ }
+
+ .g-md-1,
+ .gy-md-1 {
+ --gutter-y: 0.25rem;
+ }
+
+ .g-md-2,
+ .gx-md-2 {
+ --gutter-x: 0.5rem;
+ }
+
+ .g-md-2,
+ .gy-md-2 {
+ --gutter-y: 0.5rem;
+ }
+
+ .g-md-3,
+ .gx-md-3 {
+ --gutter-x: 1rem;
+ }
+
+ .g-md-3,
+ .gy-md-3 {
+ --gutter-y: 1rem;
+ }
+
+ .g-md-4,
+ .gx-md-4 {
+ --gutter-x: 1.5rem;
+ }
+
+ .g-md-4,
+ .gy-md-4 {
+ --gutter-y: 1.5rem;
+ }
+
+ .g-md-5,
+ .gx-md-5 {
+ --gutter-x: 3rem;
+ }
+
+ .g-md-5,
+ .gy-md-5 {
+ --gutter-y: 3rem;
+ }
+}
+
+@media (min-width: 992px) {
+ .col-lg {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 0%;
+ flex: 1 0 0%;
+ }
+
+ .row-cols-lg-auto>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .row-cols-lg-1>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .row-cols-lg-2>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .row-cols-lg-3>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+
+ .row-cols-lg-4>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .row-cols-lg-5>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 20%;
+ }
+
+ .row-cols-lg-6>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+
+ .col-lg-auto {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .col-lg-1 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 8.33333333%;
+ }
+
+ .col-lg-2 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 16.66666667%;
+ }
+
+ .col-lg-3 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .col-lg-4 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 33.33333333%;
+ }
+
+ .col-lg-5 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 41.66666667%;
+ }
+
+ .col-lg-6 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .col-lg-7 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 58.33333333%;
+ }
+
+ .col-lg-8 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 66.66666667%;
+ }
+
+ .col-lg-9 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 75%;
+ }
+
+ .col-lg-10 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 83.33333333%;
+ }
+
+ .col-lg-11 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 91.66666667%;
+ }
+
+ .col-lg-12 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .offset-lg-0 {
+ margin-left: 0;
+ }
+
+ .offset-lg-1 {
+ margin-left: 8.33333333%;
+ }
+
+ .offset-lg-2 {
+ margin-left: 16.66666667%;
+ }
+
+ .offset-lg-3 {
+ margin-left: 25%;
+ }
+
+ .offset-lg-4 {
+ margin-left: 33.33333333%;
+ }
+
+ .offset-lg-5 {
+ margin-left: 41.66666667%;
+ }
+
+ .offset-lg-6 {
+ margin-left: 50%;
+ }
+
+ .offset-lg-7 {
+ margin-left: 58.33333333%;
+ }
+
+ .offset-lg-8 {
+ margin-left: 66.66666667%;
+ }
+
+ .offset-lg-9 {
+ margin-left: 75%;
+ }
+
+ .offset-lg-10 {
+ margin-left: 83.33333333%;
+ }
+
+ .offset-lg-11 {
+ margin-left: 91.66666667%;
+ }
+
+ .g-lg-0,
+ .gx-lg-0 {
+ --gutter-x: 0;
+ }
+
+ .g-lg-0,
+ .gy-lg-0 {
+ --gutter-y: 0;
+ }
+
+ .g-lg-1,
+ .gx-lg-1 {
+ --gutter-x: 0.25rem;
+ }
+
+ .g-lg-1,
+ .gy-lg-1 {
+ --gutter-y: 0.25rem;
+ }
+
+ .g-lg-2,
+ .gx-lg-2 {
+ --gutter-x: 0.5rem;
+ }
+
+ .g-lg-2,
+ .gy-lg-2 {
+ --gutter-y: 0.5rem;
+ }
+
+ .g-lg-3,
+ .gx-lg-3 {
+ --gutter-x: 1rem;
+ }
+
+ .g-lg-3,
+ .gy-lg-3 {
+ --gutter-y: 1rem;
+ }
+
+ .g-lg-4,
+ .gx-lg-4 {
+ --gutter-x: 1.5rem;
+ }
+
+ .g-lg-4,
+ .gy-lg-4 {
+ --gutter-y: 1.5rem;
+ }
+
+ .g-lg-5,
+ .gx-lg-5 {
+ --gutter-x: 3rem;
+ }
+
+ .g-lg-5,
+ .gy-lg-5 {
+ --gutter-y: 3rem;
+ }
+}
+
+@media (min-width: 1200px) {
+ .col-xl {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 0%;
+ flex: 1 0 0%;
+ }
+
+ .row-cols-xl-auto>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .row-cols-xl-1>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .row-cols-xl-2>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .row-cols-xl-3>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+
+ .row-cols-xl-4>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .row-cols-xl-5>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 20%;
+ }
+
+ .row-cols-xl-6>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+
+ .col-xl-auto {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .col-xl-1 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 8.33333333%;
+ }
+
+ .col-xl-2 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 16.66666667%;
+ }
+
+ .col-xl-3 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .col-xl-4 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 33.33333333%;
+ }
+
+ .col-xl-5 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 41.66666667%;
+ }
+
+ .col-xl-6 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .col-xl-7 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 58.33333333%;
+ }
+
+ .col-xl-8 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 66.66666667%;
+ }
+
+ .col-xl-9 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 75%;
+ }
+
+ .col-xl-10 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 83.33333333%;
+ }
+
+ .col-xl-11 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 91.66666667%;
+ }
+
+ .col-xl-12 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .offset-xl-0 {
+ margin-left: 0;
+ }
+
+ .offset-xl-1 {
+ margin-left: 8.33333333%;
+ }
+
+ .offset-xl-2 {
+ margin-left: 16.66666667%;
+ }
+
+ .offset-xl-3 {
+ margin-left: 25%;
+ }
+
+ .offset-xl-4 {
+ margin-left: 33.33333333%;
+ }
+
+ .offset-xl-5 {
+ margin-left: 41.66666667%;
+ }
+
+ .offset-xl-6 {
+ margin-left: 50%;
+ }
+
+ .offset-xl-7 {
+ margin-left: 58.33333333%;
+ }
+
+ .offset-xl-8 {
+ margin-left: 66.66666667%;
+ }
+
+ .offset-xl-9 {
+ margin-left: 75%;
+ }
+
+ .offset-xl-10 {
+ margin-left: 83.33333333%;
+ }
+
+ .offset-xl-11 {
+ margin-left: 91.66666667%;
+ }
+
+ .g-xl-0,
+ .gx-xl-0 {
+ --gutter-x: 0;
+ }
+
+ .g-xl-0,
+ .gy-xl-0 {
+ --gutter-y: 0;
+ }
+
+ .g-xl-1,
+ .gx-xl-1 {
+ --gutter-x: 0.25rem;
+ }
+
+ .g-xl-1,
+ .gy-xl-1 {
+ --gutter-y: 0.25rem;
+ }
+
+ .g-xl-2,
+ .gx-xl-2 {
+ --gutter-x: 0.5rem;
+ }
+
+ .g-xl-2,
+ .gy-xl-2 {
+ --gutter-y: 0.5rem;
+ }
+
+ .g-xl-3,
+ .gx-xl-3 {
+ --gutter-x: 1rem;
+ }
+
+ .g-xl-3,
+ .gy-xl-3 {
+ --gutter-y: 1rem;
+ }
+
+ .g-xl-4,
+ .gx-xl-4 {
+ --gutter-x: 1.5rem;
+ }
+
+ .g-xl-4,
+ .gy-xl-4 {
+ --gutter-y: 1.5rem;
+ }
+
+ .g-xl-5,
+ .gx-xl-5 {
+ --gutter-x: 3rem;
+ }
+
+ .g-xl-5,
+ .gy-xl-5 {
+ --gutter-y: 3rem;
+ }
+}
+
+@media (min-width: 1400px) {
+ .col-xxl {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 0%;
+ flex: 1 0 0%;
+ }
+
+ .row-cols-xxl-auto>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .row-cols-xxl-1>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .row-cols-xxl-2>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .row-cols-xxl-3>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+
+ .row-cols-xxl-4>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .row-cols-xxl-5>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 20%;
+ }
+
+ .row-cols-xxl-6>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+
+ .col-xxl-auto {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: auto;
+ }
+
+ .col-xxl-1 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 8.33333333%;
+ }
+
+ .col-xxl-2 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 16.66666667%;
+ }
+
+ .col-xxl-3 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 25%;
+ }
+
+ .col-xxl-4 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 33.33333333%;
+ }
+
+ .col-xxl-5 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 41.66666667%;
+ }
+
+ .col-xxl-6 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 50%;
+ }
+
+ .col-xxl-7 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 58.33333333%;
+ }
+
+ .col-xxl-8 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 66.66666667%;
+ }
+
+ .col-xxl-9 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 75%;
+ }
+
+ .col-xxl-10 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 83.33333333%;
+ }
+
+ .col-xxl-11 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 91.66666667%;
+ }
+
+ .col-xxl-12 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 100%;
+ }
+
+ .offset-xxl-0 {
+ margin-left: 0;
+ }
+
+ .offset-xxl-1 {
+ margin-left: 8.33333333%;
+ }
+
+ .offset-xxl-2 {
+ margin-left: 16.66666667%;
+ }
+
+ .offset-xxl-3 {
+ margin-left: 25%;
+ }
+
+ .offset-xxl-4 {
+ margin-left: 33.33333333%;
+ }
+
+ .offset-xxl-5 {
+ margin-left: 41.66666667%;
+ }
+
+ .offset-xxl-6 {
+ margin-left: 50%;
+ }
+
+ .offset-xxl-7 {
+ margin-left: 58.33333333%;
+ }
+
+ .offset-xxl-8 {
+ margin-left: 66.66666667%;
+ }
+
+ .offset-xxl-9 {
+ margin-left: 75%;
+ }
+
+ .offset-xxl-10 {
+ margin-left: 83.33333333%;
+ }
+
+ .offset-xxl-11 {
+ margin-left: 91.66666667%;
+ }
+
+ .g-xxl-0,
+ .gx-xxl-0 {
+ --gutter-x: 0;
+ }
+
+ .g-xxl-0,
+ .gy-xxl-0 {
+ --gutter-y: 0;
+ }
+
+ .g-xxl-1,
+ .gx-xxl-1 {
+ --gutter-x: 0.25rem;
+ }
+
+ .g-xxl-1,
+ .gy-xxl-1 {
+ --gutter-y: 0.25rem;
+ }
+
+ .g-xxl-2,
+ .gx-xxl-2 {
+ --gutter-x: 0.5rem;
+ }
+
+ .g-xxl-2,
+ .gy-xxl-2 {
+ --gutter-y: 0.5rem;
+ }
+
+ .g-xxl-3,
+ .gx-xxl-3 {
+ --gutter-x: 1rem;
+ }
+
+ .g-xxl-3,
+ .gy-xxl-3 {
+ --gutter-y: 1rem;
+ }
+
+ .g-xxl-4,
+ .gx-xxl-4 {
+ --gutter-x: 1.5rem;
+ }
+
+ .g-xxl-4,
+ .gy-xxl-4 {
+ --gutter-y: 1.5rem;
+ }
+
+ .g-xxl-5,
+ .gx-xxl-5 {
+ --gutter-x: 3rem;
+ }
+
+ .g-xxl-5,
+ .gy-xxl-5 {
+ --gutter-y: 3rem;
+ }
+}
+
+.table {
+ /* Values defined in light.standard.css / dark.standard.css */
+ width: 100%;
+ margin-bottom: 1rem;
+ color: var(--table-color);
+ vertical-align: top;
+ border-color: var(--table-border-color);
+}
+
+.table> :not(caption)>*>* {
+ padding: 0.5rem 0.5rem;
+ background-color: var(--table-bg, transparent);
+ border-bottom-width: 1px;
+ -webkit-box-shadow: inset 0 0 0 9999px var(--table-accent-bg, transparent);
+ box-shadow: inset 0 0 0 9999px var(--table-accent-bg, transparent);
+}
+
+.table>tbody {
+ vertical-align: inherit;
+}
+
+.table>thead {
+ vertical-align: bottom;
+}
+
+.table-group-divider {
+ border-top: 2px solid currentcolor;
+}
+
+.caption-top {
+ caption-side: top;
+}
+
+.table-sm> :not(caption)>*>* {
+ padding: 0.25rem 0.25rem;
+}
+
+.table-bordered> :not(caption)>* {
+ border-width: 1px 0;
+}
+
+.table-bordered> :not(caption)>*>* {
+ border-width: 0 1px;
+}
+
+.table-borderless> :not(caption)>*>* {
+ border-bottom-width: 0;
+}
+
+.table-borderless> :not(:first-child) {
+ border-top-width: 0;
+}
+
+.table-striped>tbody>tr:nth-of-type(odd)>* {
+ --table-accent-bg: var(--table-striped-bg, rgba(var(--white-rgb), var(--opacity-5)));
+ color: var(--table-striped-color);
+}
+
+.table-striped-columns> :not(caption)>tr> :nth-child(even) {
+ --table-accent-bg: var(--table-striped-bg, rgba(var(--white-rgb), var(--opacity-5)));
+ color: var(--table-striped-color);
+}
+
+.table-active {
+ --table-accent-bg: var(--table-active-bg, rgba(var(--white-rgb), 0.1));
+ color: var(--table-active-color);
+}
+
+.table-active>tbody>tr:active>* {
+ --table-accent-bg: var(--table-active-bg, rgba(var(--white-rgb), 0.1));
+ color: var(--table-active-color);
+}
+
+.table-primary {
+ --table-color: hsl(0, 0%, 0%);
+ --table-bg: #cfd4dd;
+ --table-border-color: #babfc7;
+ --table-striped-bg: #c5c9d2;
+ --table-striped-color: hsl(0, 0%, 0%);
+ --table-active-bg: #babfc7;
+ --table-active-color: hsl(0, 0%, 0%);
+ --table-active-bg: #bfc4cc;
+ --table-active-color: hsl(0, 0%, 0%);
+ color: var(--table-color);
+ border-color: var(--table-border-color);
+}
+
+.table-secondary {
+ --table-color: hsl(0, 0%, 0%);
+ --table-bg: #e2e3e5;
+ --table-border-color: #cbccce;
+ --table-striped-bg: #d7d8da;
+ --table-striped-color: hsl(0, 0%, 0%);
+ --table-active-bg: #cbccce;
+ --table-active-color: hsl(0, 0%, 0%);
+ --table-active-bg: #d1d2d4;
+ --table-active-color: hsl(0, 0%, 0%);
+ color: var(--table-color);
+ border-color: var(--table-border-color);
+}
+
+.table-success {
+ --table-color: hsl(0, 0%, 0%);
+ --table-bg: #dae6da;
+ --table-border-color: #c4cfc4;
+ --table-striped-bg: #cfdbcf;
+ --table-striped-color: hsl(0, 0%, 0%);
+ --table-active-bg: #c4cfc4;
+ --table-active-color: hsl(0, 0%, 0%);
+ --table-active-bg: #cad5ca;
+ --table-active-color: hsl(0, 0%, 0%);
+ color: var(--table-color);
+ border-color: var(--table-border-color);
+}
+
+.table-info {
+ --table-color: hsl(0, 0%, 0%);
+ --table-bg: #d6e0e8;
+ --table-border-color: #c1cad1;
+ --table-striped-bg: #cbd5dc;
+ --table-striped-color: hsl(0, 0%, 0%);
+ --table-active-bg: #c1cad1;
+ --table-active-color: hsl(0, 0%, 0%);
+ --table-active-bg: #c6cfd7;
+ --table-active-color: hsl(0, 0%, 0%);
+ color: var(--table-color);
+ border-color: var(--table-border-color);
+}
+
+.table-warning {
+ --table-color: hsl(0, 0%, 0%);
+ --table-bg: #efe0cc;
+ --table-border-color: #d7cab8;
+ --table-striped-bg: #e3d5c2;
+ --table-striped-color: hsl(0, 0%, 0%);
+ --table-active-bg: #d7cab8;
+ --table-active-color: hsl(0, 0%, 0%);
+ --table-active-bg: #ddcfbd;
+ --table-active-color: hsl(0, 0%, 0%);
+ color: var(--table-color);
+ border-color: var(--table-border-color);
+}
+
+.table-danger {
+ --table-color: hsl(0, 0%, 0%);
+ --table-bg: #edd2d1;
+ --table-border-color: #d5bdbc;
+ --table-striped-bg: #e1c8c7;
+ --table-striped-color: hsl(0, 0%, 0%);
+ --table-active-bg: #d5bdbc;
+ --table-active-color: hsl(0, 0%, 0%);
+ --table-active-bg: #dbc2c1;
+ --table-active-color: hsl(0, 0%, 0%);
+ color: var(--table-color);
+ border-color: var(--table-border-color);
+}
+
+.table-light {
+ --table-color: hsl(0, 0%, 0%);
+ --table-bg: hsl(210, 17%, 98%);
+ --table-border-color: #e0e1e2;
+ --table-striped-bg: #edeeee;
+ --table-striped-color: hsl(0, 0%, 0%);
+ --table-active-bg: #e0e1e2;
+ --table-active-color: hsl(0, 0%, 0%);
+ --table-active-bg: #e6e7e8;
+ --table-active-color: hsl(0, 0%, 0%);
+ color: var(--table-color);
+ border-color: var(--table-border-color);
+}
+
+.table-dark {
+ --table-color: var(--body-color, #e6ebf1);
+ --table-bg: hsl(210, 10%, 23%);
+ --table-border-color: #494f54;
+ --table-striped-bg: #3f454b;
+ --table-striped-color: var(--body-color, #e6ebf1);
+ --table-active-bg: #494f54;
+ --table-active-color: var(--body-color, #e6ebf1);
+ --table-active-bg: #444a4f;
+ --table-active-color: var(--body-color, #e6ebf1);
+ color: var(--table-color);
+ border-color: var(--table-border-color);
+}
+
+.table-responsive {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+}
+
+@media (max-width: 575.98px) {
+ .table-responsive-sm {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ }
+}
+
+@media (max-width: 767.98px) {
+ .table-responsive-md {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ }
+}
+
+@media (max-width: 991.98px) {
+ .table-responsive-lg {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ }
+}
+
+@media (max-width: 1199.98px) {
+ .table-responsive-xl {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ }
+}
+
+@media (max-width: 1399.98px) {
+ .table-responsive-xxl {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ }
+}
+
+.form-label {
+ margin-bottom: 0.5rem;
+}
+
+.col-form-label {
+ padding-top: calc(0.6rem + 1px);
+ padding-bottom: calc(0.6rem + 1px);
+ margin-bottom: 0;
+ font-size: inherit;
+ line-height: 1.5;
+}
+
+.col-form-label-lg {
+ padding-top: calc(0.5rem + 1px);
+ padding-bottom: calc(0.5rem + 1px);
+ font-size: 1.25rem;
+}
+
+.col-form-label-sm {
+ padding-top: calc(0.25rem + 1px);
+ padding-bottom: calc(0.25rem + 1px);
+ font-size: 0.875rem;
+}
+
+.form-text {
+ margin-top: 0.25rem;
+ font-size: 0.875em;
+ color: hsl(210, 7%, 46%);
+}
+
+.form-control {
+ display: block;
+ width: 100%;
+ padding: 0.6rem 1rem;
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: 1;
+ color: var(--input-color, #e6ebf1);
+ background-color: var(--input-bg, #1a2332);
+ background-clip: padding-box;
+ border: 1px solid var(--input-border-color, #3a4250);
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ border-radius: 0.25rem;
+ -webkit-transition: border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ transition: border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ -o-transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .form-control {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.form-control[type=file] {
+ overflow: hidden;
+}
+
+.form-control[type=file]:not(:disabled):not([readonly]) {
+ cursor: pointer;
+}
+
+.form-control:focus {
+ color: var(--input-color, #e6ebf1);
+ background-color: var(--input-bg, #1a2332);
+ border-color: var(--input-focus-border-color, #5472ff);
+ outline: 0;
+ -webkit-box-shadow: var(--input-focus-box-shadow, 0 0 0 0.25rem rgba(84, 114, 255, 0.25));
+ box-shadow: var(--input-focus-box-shadow, 0 0 0 0.25rem rgba(84, 114, 255, 0.25));
+}
+
+.form-control::-webkit-date-and-time-value {
+ height: 1.5em;
+}
+
+.form-control::-webkit-input-placeholder {
+ color: var(--input-placeholder-color, #8894aa);
+ opacity: 1;
+}
+
+.form-control::-moz-placeholder {
+ color: var(--input-placeholder-color, #8894aa);
+ opacity: 1;
+}
+
+.form-control:-ms-input-placeholder {
+ color: var(--input-placeholder-color, #8894aa);
+ opacity: 1;
+}
+
+.form-control::-ms-input-placeholder {
+ color: var(--input-placeholder-color, #8894aa);
+ opacity: 1;
+}
+
+.form-control::placeholder {
+ color: var(--input-placeholder-color, #8894aa);
+ opacity: 1;
+}
+
+.form-control:disabled {
+ background-color: var(--input-disabled-bg, #0f1318);
+ border-color: var(--input-disabled-border-color, #2b323b);
+ opacity: 1;
+}
+
+.form-control::-webkit-file-upload-button {
+ padding: 0.6rem 1rem;
+ margin: -0.6rem -1rem;
+ -webkit-margin-end: 1rem;
+ margin-inline-end: 1rem;
+ color: hsl(210, 11%, 15%);
+ background-color: hsl(210, 16%, 93%);
+ pointer-events: none;
+ border-color: inherit;
+ border-style: solid;
+ border-width: 0;
+ border-inline-end-width: 1px;
+ border-radius: 0;
+ -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+}
+
+.form-control::file-selector-button {
+ padding: 0.6rem 1rem;
+ margin: -0.6rem -1rem;
+ -webkit-margin-end: 1rem;
+ margin-inline-end: 1rem;
+ color: hsl(210, 11%, 15%);
+ background-color: hsl(210, 16%, 93%);
+ pointer-events: none;
+ border-color: inherit;
+ border-style: solid;
+ border-width: 0;
+ border-inline-end-width: 1px;
+ border-radius: 0;
+ -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ -o-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .form-control::-webkit-file-upload-button {
+ -webkit-transition: none;
+ transition: none;
+ }
+
+ .form-control::file-selector-button {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.form-control:active:not(:disabled):not([readonly])::-webkit-file-upload-button {
+ background-color: var(--input-file-button-active-bg, #2b3441);
+}
+
+.form-control:active:not(:disabled):not([readonly])::file-selector-button {
+ background-color: var(--input-file-button-active-bg, #2b3441);
+}
+
+.form-control-plaintext {
+ display: block;
+ width: 100%;
+ padding: 0.6rem 0;
+ margin-bottom: 0;
+ line-height: 1.5;
+ color: hsl(210, 11%, 15%);
+ background-color: transparent;
+ border: solid transparent;
+ border-width: 1px 0;
+}
+
+.form-control-plaintext:focus {
+ outline: 0;
+}
+
+.form-control-plaintext.form-control-sm,
+.form-control-plaintext.form-control-lg {
+ padding-right: 0;
+ padding-left: 0;
+}
+
+.form-control-sm {
+ min-height: calc(1.5em + 0.5rem + 2px);
+ padding: 0.25rem 0.5rem;
+ font-size: 0.875rem;
+ border-radius: 0.2rem;
+}
+
+.form-control-sm::-webkit-file-upload-button {
+ padding: 0.25rem 0.5rem;
+ margin: -0.25rem -0.5rem;
+ -webkit-margin-end: 0.5rem;
+ margin-inline-end: 0.5rem;
+}
+
+.form-control-sm::file-selector-button {
+ padding: 0.25rem 0.5rem;
+ margin: -0.25rem -0.5rem;
+ -webkit-margin-end: 0.5rem;
+ margin-inline-end: 0.5rem;
+}
+
+.form-control-lg {
+ min-height: calc(1.5em + 1rem + 2px);
+ padding: 0.5rem 1rem;
+ font-size: 1.25rem;
+ border-radius: 0.3rem;
+}
+
+.form-control-lg::-webkit-file-upload-button {
+ padding: 0.5rem 1rem;
+ margin: -0.5rem -1rem;
+ -webkit-margin-end: 1rem;
+ margin-inline-end: 1rem;
+}
+
+.form-control-lg::file-selector-button {
+ padding: 0.5rem 1rem;
+ margin: -0.5rem -1rem;
+ -webkit-margin-end: 1rem;
+ margin-inline-end: 1rem;
+}
+
+textarea.form-control {
+ min-height: calc(1.5em + 1.2rem + 2px);
+}
+
+textarea.form-control-sm {
+ min-height: calc(1.5em + 0.5rem + 2px);
+}
+
+textarea.form-control-lg {
+ min-height: calc(1.5em + 1rem + 2px);
+}
+
+.form-control-color {
+ width: 3rem;
+ height: calc(1.5em + 1.2rem + 2px);
+ padding: 0.6rem;
+}
+
+.form-control-color:not(:disabled):not([readonly]) {
+ cursor: pointer;
+}
+
+.form-control-color::-moz-color-swatch {
+ border: 0 ;
+ border-radius: 0.25rem;
+}
+
+.form-control-color::-webkit-color-swatch {
+ border-radius: 0.25rem;
+}
+
+.form-control-color.form-control-sm {
+ height: calc(1.5em + 0.5rem + 2px);
+}
+
+.form-control-color.form-control-lg {
+ height: calc(1.5em + 1rem + 2px);
+}
+
+.form-select,
+.custom-select {
+ display: block;
+ width: 100%;
+ padding: 0.6rem 3rem 0.6rem 1rem;
+ -moz-padding-start: calc(1rem - 3px);
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: 1.5;
+ color: hsl(210, 11%, 15%);
+ background-color: hsl(210, 16%, 93%);
+ background-image: url("../images/select-bg.svg");
+ background-repeat: no-repeat;
+ background-position: right 1rem center;
+ background-size: 116rem;
+ border: 1px solid hsl(210, 14%, 83%);
+ border-radius: 0.25rem;
+ -webkit-transition: border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ transition: border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ -o-transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+}
+
+@media (prefers-reduced-motion: reduce) {
+
+ .form-select,
+ .custom-select {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.form-select:focus,
+.custom-select:focus {
+ border-color: var(--input-focus-border-color, #5472ff);
+ outline: 0;
+ -webkit-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+ box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+}
+
+.form-select[multiple],
+[multiple].custom-select,
+.form-select[size]:not([size="1"]),
+[size].custom-select:not([size="1"]) {
+ padding-right: 1rem;
+ background-image: none;
+}
+
+.form-select:disabled,
+.custom-select:disabled {
+ background-color: hsl(210, 16%, 93%);
+}
+
+.form-select:-moz-focusring,
+.custom-select:-moz-focusring {
+ color: transparent;
+ text-shadow: 0 0 0 hsl(210, 11%, 15%);
+}
+
+.form-select-sm {
+ padding-top: 0.25rem;
+ padding-bottom: 0.25rem;
+ padding-left: 0.5rem;
+ font-size: 0.875rem;
+ border-radius: 0.2rem;
+}
+
+.form-select-lg {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ padding-left: 1rem;
+ font-size: 1.25rem;
+ border-radius: 0.3rem;
+}
+
+.form-check {
+ display: block;
+ min-height: 1.5rem;
+ padding-left: 1.5em;
+ margin-bottom: 0.125rem;
+}
+
+.form-check .form-check-input {
+ float: left;
+ margin-left: -1.5em;
+}
+
+.form-check-reverse {
+ padding-right: 1.5em;
+ padding-left: 0;
+ text-align: right;
+}
+
+.form-check-reverse .form-check-input {
+ float: right;
+ margin-right: -1.5em;
+ margin-left: 0;
+}
+
+.form-check-input {
+ width: 1em;
+ height: 1em;
+ margin-top: 0.25em;
+ vertical-align: top;
+ background-color: var(--body-color, #e6ebf1);
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: contain;
+ border: 1px solid rgba(0, 0, 0, 0.25);
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ -webkit-print-color-adjust: exact;
+ print-color-adjust: exact;
+}
+
+.form-check-input[type=checkbox] {
+ border-radius: 0.25em;
+}
+
+.form-check-input[type=radio] {
+ border-radius: 50%;
+}
+
+.form-check-input:active {
+ -webkit-filter: brightness(90%);
+ filter: brightness(90%);
+}
+
+.form-check-input:focus {
+ border-color: var(--input-focus-border-color, #5472ff);
+ outline: 0;
+ -webkit-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+ box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+}
+
+.form-check-input:checked {
+ background-color: hsl(240, 98%, 17%);
+ border-color: hsl(240, 98%, 17%);
+}
+
+.form-check-input:checked[type=checkbox] {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='hsl%280, 0%, 100%%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
+}
+
+.form-check-input:checked[type=radio] {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='hsl%280, 0%, 100%%29'/%3e%3c/svg%3e");
+}
+
+.form-check-input[type=checkbox]:indeterminate {
+ background-color: hsl(240, 98%, 17%);
+ border-color: hsl(240, 98%, 17%);
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='hsl%280, 0%, 100%%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e");
+}
+
+.form-check-input:disabled {
+ pointer-events: none;
+ -webkit-filter: none;
+ filter: none;
+ opacity: 0.5;
+}
+
+.form-check-input[disabled]~.form-check-label,
+.form-check-input:disabled~.form-check-label {
+ cursor: default;
+ opacity: 0.5;
+}
+
+.form-switch {
+ padding-left: 2.5em;
+}
+
+.form-switch .form-check-input {
+ width: 2em;
+ margin-left: -2.5em;
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");
+ background-position: left center;
+ border-radius: 2em;
+ -webkit-transition: background-position 0.15s ease-in-out;
+ -o-transition: background-position 0.15s ease-in-out;
+ transition: background-position 0.15s ease-in-out;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .form-switch .form-check-input {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.form-switch .form-check-input:focus {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%238894aa'/%3e%3c/svg%3e");
+}
+
+.form-switch .form-check-input:checked {
+ background-position: right center;
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='hsl%280, 0%, 100%%29'/%3e%3c/svg%3e");
+}
+
+.form-switch.form-check-reverse {
+ padding-right: 2.5em;
+ padding-left: 0;
+}
+
+.form-switch.form-check-reverse .form-check-input {
+ margin-right: -2.5em;
+ margin-left: 0;
+}
+
+.form-check-inline {
+ display: inline-block;
+ margin-right: 1rem;
+}
+
+.btn-check {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+}
+
+.btn-check[disabled]+.btn,
+.btn-check:disabled+.btn {
+ pointer-events: none;
+ -webkit-filter: none;
+ filter: none;
+ opacity: 0.65;
+}
+
+.form-range {
+ width: 100%;
+ height: 1.5rem;
+ padding: 0;
+ background-color: transparent;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+}
+
+.form-range:focus {
+ outline: 0;
+}
+
+.form-range:focus::-webkit-slider-thumb {
+ -webkit-box-shadow: 0 0 0 1px var(--body-color, #e6ebf1), 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+ box-shadow: 0 0 0 1px var(--body-color, #e6ebf1), 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+}
+
+.form-range:focus::-moz-range-thumb {
+ box-shadow: 0 0 0 1px var(--body-color, #e6ebf1), 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+}
+
+.form-range::-moz-focus-outer {
+ border: 0;
+}
+
+.form-range::-webkit-slider-thumb {
+ width: 1rem;
+ height: 1rem;
+ margin-top: -0.25rem;
+ background-color: hsl(240, 98%, 17%);
+ border: 0;
+ border-radius: 1rem;
+ -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ -webkit-appearance: none;
+ appearance: none;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .form-range::-webkit-slider-thumb {
+ -webkit-transition: none;
+ transition: none;
+ }
+}
+
+.form-range::-webkit-slider-thumb:active {
+ background-color: var(--form-range-thumb-active-bg, #4a5766);
+}
+
+.form-range::-webkit-slider-runnable-track {
+ width: 100%;
+ height: 0.5rem;
+ color: transparent;
+ cursor: pointer;
+ background-color: hsl(210, 14%, 89%);
+ border-color: transparent;
+ border-radius: 1rem;
+}
+
+.form-range::-moz-range-thumb {
+ width: 1rem;
+ height: 1rem;
+ background-color: hsl(240, 98%, 17%);
+ border: 0;
+ border-radius: 1rem;
+ -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ -moz-appearance: none;
+ appearance: none;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .form-range::-moz-range-thumb {
+ -moz-transition: none;
+ transition: none;
+ }
+}
+
+.form-range::-moz-range-thumb:active {
+ background-color: var(--form-range-thumb-active-bg, #4a5766);
+}
+
+.form-range::-moz-range-track {
+ width: 100%;
+ height: 0.5rem;
+ color: transparent;
+ cursor: pointer;
+ background-color: hsl(210, 14%, 89%);
+ border-color: transparent;
+ border-radius: 1rem;
+}
+
+.form-range:disabled {
+ pointer-events: none;
+}
+
+.form-range:disabled::-webkit-slider-thumb {
+ background-color: hsl(210, 11%, 71%);
+}
+
+.form-range:disabled::-moz-range-thumb {
+ background-color: hsl(210, 11%, 71%);
+}
+
+.form-floating {
+ position: relative;
+}
+
+.form-floating>.form-control,
+.form-floating>.form-control-plaintext,
+.form-floating>.form-select,
+.form-floating>.custom-select {
+ height: calc(3.5rem + 2px);
+ line-height: 1.25;
+}
+
+.form-floating>label {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ padding: 1rem 1rem;
+ overflow: hidden;
+ text-align: start;
+ -o-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ pointer-events: none;
+ border: 1px solid transparent;
+ -webkit-transform-origin: 0 0;
+ transform-origin: 0 0;
+ -webkit-transition: opacity 0.1s ease-in-out, -webkit-transform 0.1s ease-in-out;
+ transition: opacity 0.1s ease-in-out, -webkit-transform 0.1s ease-in-out;
+ -o-transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;
+ transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;
+ transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out, -webkit-transform 0.1s ease-in-out;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .form-floating>label {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.form-floating>.form-control,
+.form-floating>.form-control-plaintext {
+ padding: 1rem 1rem;
+}
+
+.form-floating>.form-control::-webkit-input-placeholder,
+.form-floating>.form-control-plaintext::-webkit-input-placeholder {
+ color: transparent;
+}
+
+.form-floating>.form-control::-moz-placeholder,
+.form-floating>.form-control-plaintext::-moz-placeholder {
+ color: transparent;
+}
+
+.form-floating>.form-control:-ms-input-placeholder,
+.form-floating>.form-control-plaintext:-ms-input-placeholder {
+ color: transparent;
+}
+
+.form-floating>.form-control::-ms-input-placeholder,
+.form-floating>.form-control-plaintext::-ms-input-placeholder {
+ color: transparent;
+}
+
+.form-floating>.form-control::placeholder,
+.form-floating>.form-control-plaintext::placeholder {
+ color: transparent;
+}
+
+.form-floating>.form-control:not(:-moz-placeholder-shown),
+.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown) {
+ padding-top: 1.625rem;
+ padding-bottom: 0.625rem;
+}
+
+.form-floating>.form-control:not(:-ms-input-placeholder),
+.form-floating>.form-control-plaintext:not(:-ms-input-placeholder) {
+ padding-top: 1.625rem;
+ padding-bottom: 0.625rem;
+}
+
+.form-floating>.form-control:focus,
+.form-floating>.form-control:not(:placeholder-shown),
+.form-floating>.form-control-plaintext:focus,
+.form-floating>.form-control-plaintext:not(:placeholder-shown) {
+ padding-top: 1.625rem;
+ padding-bottom: 0.625rem;
+}
+
+.form-floating>.form-control:-webkit-autofill,
+.form-floating>.form-control-plaintext:-webkit-autofill {
+ padding-top: 1.625rem;
+ padding-bottom: 0.625rem;
+}
+
+.form-floating>.form-select,
+.form-floating>.custom-select {
+ padding-top: 1.625rem;
+ padding-bottom: 0.625rem;
+}
+
+.form-floating>.form-control:not(:-moz-placeholder-shown)~label {
+ opacity: 0.65;
+ transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
+}
+
+.form-floating>.form-control:not(:-ms-input-placeholder)~label {
+ opacity: 0.65;
+ transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
+}
+
+.form-floating>.form-control:focus~label,
+.form-floating>.form-control:not(:placeholder-shown)~label,
+.form-floating>.form-control-plaintext~label,
+.form-floating>.form-select~label,
+.form-floating>.custom-select~label {
+ opacity: 0.65;
+ -webkit-transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
+ transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
+}
+
+.form-floating>.form-control:-webkit-autofill~label {
+ opacity: 0.65;
+ -webkit-transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
+ transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
+}
+
+.form-floating>.form-control-plaintext~label {
+ border-width: 1px 0;
+}
+
+.input-group {
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-box-align: stretch;
+ -ms-flex-align: stretch;
+ align-items: stretch;
+ width: 100%;
+}
+
+.input-group>.form-control,
+.input-group>.form-select,
+.input-group>.custom-select,
+.input-group>.form-floating {
+ position: relative;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+ width: 1%;
+ min-width: 0;
+}
+
+.input-group>.form-control:focus,
+.input-group>.form-select:focus,
+.input-group>.custom-select:focus,
+.input-group>.form-floating:focus-within {
+ z-index: 5;
+}
+
+.input-group .btn {
+ position: relative;
+ z-index: 2;
+}
+
+.input-group .btn:focus {
+ z-index: 5;
+}
+
+.input-group-text {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ padding: 0.6rem 1rem;
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: 1.5;
+ color: hsl(210, 11%, 15%);
+ text-align: center;
+ white-space: nowrap;
+ background-color: hsl(210, 16%, 93%);
+ border: 1px solid hsl(210, 14%, 83%);
+ border-radius: 0.25rem;
+}
+
+.input-group-lg>.form-control,
+.input-group-lg>.form-select,
+.input-group-lg>.custom-select,
+.input-group-lg>.input-group-text,
+.input-group-lg>.btn {
+ padding: 0.5rem 1rem;
+ font-size: 1.25rem;
+ border-radius: 0.3rem;
+}
+
+.input-group-sm>.form-control,
+.input-group-sm>.form-select,
+.input-group-sm>.custom-select,
+.input-group-sm>.input-group-text,
+.input-group-sm>.btn {
+ padding: 0.25rem 0.5rem;
+ font-size: 0.875rem;
+ border-radius: 0.2rem;
+}
+
+.input-group-lg>.form-select,
+.input-group-lg>.custom-select,
+.input-group-sm>.form-select,
+.input-group-sm>.custom-select {
+ padding-right: 4rem;
+}
+
+.input-group:not(.has-validation)> :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),
+.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),
+.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,
+.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,
+.input-group:not(.has-validation)>.form-floating:not(:last-child)>.custom-select {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.input-group.has-validation> :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),
+.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),
+.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,
+.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,
+.input-group.has-validation>.form-floating:nth-last-child(n+3)>.custom-select {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.input-group> :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) {
+ margin-left: -0.0625rem;
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.input-group>.form-floating:not(:first-child)>.form-control,
+.input-group>.form-floating:not(:first-child)>.form-select,
+.input-group>.form-floating:not(:first-child)>.custom-select {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.valid-feedback {
+ display: none;
+ width: 100%;
+ margin-top: 0.25rem;
+ font-size: 0.875em;
+ color: hsl(120, 32%, 39%);
+}
+
+.valid-tooltip {
+ position: absolute;
+ top: 100%;
+ z-index: 5;
+ display: none;
+ max-width: 100%;
+ padding: 0.25rem 0.5rem;
+ margin-top: 0.1rem;
+ font-size: 0.875rem;
+ color: var(--body-color, #e6ebf1);
+ background-color: rgba(68, 131, 68, 0.9);
+ border-radius: 0.25rem;
+}
+
+.was-validated :valid~.valid-feedback,
+.was-validated :valid~.valid-tooltip,
+.is-valid~.valid-feedback,
+.is-valid~.valid-tooltip {
+ display: block;
+}
+
+.was-validated .form-control:valid,
+.form-control.is-valid {
+ border-color: hsl(120, 32%, 39%);
+ padding-right: calc(1.5em + 1.2rem);
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='hsl%28120, 32%, 39%%29' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
+ background-repeat: no-repeat;
+ background-position: right calc(0.375em + 0.3rem) center;
+ background-size: calc(0.75em + 0.6rem) calc(0.75em + 0.6rem);
+}
+
+.was-validated .form-control:valid:focus,
+.form-control.is-valid:focus {
+ border-color: hsl(120, 32%, 39%);
+ -webkit-box-shadow: 0 0 0 0.25rem rgba(68, 131, 68, 0.25);
+ box-shadow: 0 0 0 0.25rem rgba(68, 131, 68, 0.25);
+}
+
+.was-validated textarea.form-control:valid,
+textarea.form-control.is-valid {
+ padding-right: calc(1.5em + 1.2rem);
+ background-position: top calc(0.375em + 0.3rem) right calc(0.375em + 0.3rem);
+}
+
+.was-validated .form-select:valid,
+.was-validated .custom-select:valid,
+.form-select.is-valid,
+.is-valid.custom-select {
+ border-color: hsl(120, 32%, 39%);
+}
+
+.was-validated .form-select:valid:not([multiple]):not([size]),
+.was-validated .custom-select:valid:not([multiple]):not([size]),
+.was-validated .form-select:valid:not([multiple])[size="1"],
+.was-validated .custom-select:valid:not([multiple])[size="1"],
+.form-select.is-valid:not([multiple]):not([size]),
+.is-valid.custom-select:not([multiple]):not([size]),
+.form-select.is-valid:not([multiple])[size="1"],
+.is-valid.custom-select:not([multiple])[size="1"] {
+ padding-right: 5.5rem;
+ background-image: url("../images/select-bg.svg"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='hsl%28120, 32%, 39%%29' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
+ background-position: right 1rem center, center right 3rem;
+ background-size: 116rem, calc(0.75em + 0.6rem) calc(0.75em + 0.6rem);
+}
+
+.was-validated .form-select:valid:focus,
+.was-validated .custom-select:valid:focus,
+.form-select.is-valid:focus,
+.is-valid.custom-select:focus {
+ border-color: hsl(120, 32%, 39%);
+ -webkit-box-shadow: 0 0 0 0.25rem rgba(68, 131, 68, 0.25);
+ box-shadow: 0 0 0 0.25rem rgba(68, 131, 68, 0.25);
+}
+
+.was-validated .form-control-color:valid,
+.form-control-color.is-valid {
+ width: calc(3rem + calc(1.5em + 1.2rem));
+}
+
+.was-validated .form-check-input:valid,
+.form-check-input.is-valid {
+ border-color: hsl(120, 32%, 39%);
+}
+
+.was-validated .form-check-input:valid:checked,
+.form-check-input.is-valid:checked {
+ background-color: hsl(120, 32%, 39%);
+}
+
+.was-validated .form-check-input:valid:focus,
+.form-check-input.is-valid:focus {
+ -webkit-box-shadow: 0 0 0 0.25rem rgba(68, 131, 68, 0.25);
+ box-shadow: 0 0 0 0.25rem rgba(68, 131, 68, 0.25);
+}
+
+.was-validated .form-check-input:valid~.form-check-label,
+.form-check-input.is-valid~.form-check-label {
+ color: hsl(120, 32%, 39%);
+}
+
+.form-check-inline .form-check-input~.valid-feedback {
+ margin-left: 0.5em;
+}
+
+.was-validated .input-group>.form-control:not(:focus):valid,
+.input-group>.form-control:not(:focus).is-valid,
+.was-validated .input-group>.form-select:not(:focus):valid,
+.was-validated .input-group>.custom-select:not(:focus):valid,
+.input-group>.form-select:not(:focus).is-valid,
+.input-group>.custom-select:not(:focus).is-valid,
+.was-validated .input-group>.form-floating:not(:focus-within):valid,
+.input-group>.form-floating:not(:focus-within).is-valid {
+ z-index: 3;
+}
+
+.invalid-feedback {
+ display: none;
+ width: 100%;
+ margin-top: 0.25rem;
+ font-size: 0.875em;
+ color: hsl(3, 75%, 37%);
+}
+
+.invalid-tooltip {
+ position: absolute;
+ top: 100%;
+ z-index: 5;
+ display: none;
+ max-width: 100%;
+ padding: 0.25rem 0.5rem;
+ margin-top: 0.1rem;
+ font-size: 0.875rem;
+ color: var(--body-color, #e6ebf1);
+ background-color: rgba(165, 31, 24, 0.9);
+ border-radius: 0.25rem;
+}
+
+.was-validated :invalid~.invalid-feedback,
+.was-validated :invalid~.invalid-tooltip,
+.is-invalid~.invalid-feedback,
+.is-invalid~.invalid-tooltip {
+ display: block;
+}
+
+.was-validated .form-control:invalid,
+.form-control.is-invalid {
+ border-color: hsl(3, 75%, 37%);
+ padding-right: calc(1.5em + 1.2rem);
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='hsl%283, 75%, 37%%29'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='hsl%283, 75%, 37%%29' stroke='none'/%3e%3c/svg%3e");
+ background-repeat: no-repeat;
+ background-position: right calc(0.375em + 0.3rem) center;
+ background-size: calc(0.75em + 0.6rem) calc(0.75em + 0.6rem);
+}
+
+.was-validated .form-control:invalid:focus,
+.form-control.is-invalid:focus {
+ border-color: hsl(3, 75%, 37%);
+ -webkit-box-shadow: 0 0 0 0.25rem rgba(165, 31, 24, 0.25);
+ box-shadow: 0 0 0 0.25rem rgba(165, 31, 24, 0.25);
+}
+
+.was-validated textarea.form-control:invalid,
+textarea.form-control.is-invalid {
+ padding-right: calc(1.5em + 1.2rem);
+ background-position: top calc(0.375em + 0.3rem) right calc(0.375em + 0.3rem);
+}
+
+.was-validated .form-select:invalid,
+.was-validated .custom-select:invalid,
+.form-select.is-invalid,
+.is-invalid.custom-select {
+ border-color: hsl(3, 75%, 37%);
+}
+
+.was-validated .form-select:invalid:not([multiple]):not([size]),
+.was-validated .custom-select:invalid:not([multiple]):not([size]),
+.was-validated .form-select:invalid:not([multiple])[size="1"],
+.was-validated .custom-select:invalid:not([multiple])[size="1"],
+.form-select.is-invalid:not([multiple]):not([size]),
+.is-invalid.custom-select:not([multiple]):not([size]),
+.form-select.is-invalid:not([multiple])[size="1"],
+.is-invalid.custom-select:not([multiple])[size="1"] {
+ padding-right: 5.5rem;
+ background-image: url("../images/select-bg.svg"), url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='hsl%283, 75%, 37%%29'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='hsl%283, 75%, 37%%29' stroke='none'/%3e%3c/svg%3e");
+ background-position: right 1rem center, center right 3rem;
+ background-size: 116rem, calc(0.75em + 0.6rem) calc(0.75em + 0.6rem);
+}
+
+.was-validated .form-select:invalid:focus,
+.was-validated .custom-select:invalid:focus,
+.form-select.is-invalid:focus,
+.is-invalid.custom-select:focus {
+ border-color: hsl(3, 75%, 37%);
+ -webkit-box-shadow: 0 0 0 0.25rem rgba(165, 31, 24, 0.25);
+ box-shadow: 0 0 0 0.25rem rgba(165, 31, 24, 0.25);
+}
+
+.was-validated .form-control-color:invalid,
+.form-control-color.is-invalid {
+ width: calc(3rem + calc(1.5em + 1.2rem));
+}
+
+.was-validated .form-check-input:invalid,
+.form-check-input.is-invalid {
+ border-color: hsl(3, 75%, 37%);
+}
+
+.was-validated .form-check-input:invalid:checked,
+.form-check-input.is-invalid:checked {
+ background-color: hsl(3, 75%, 37%);
+}
+
+.was-validated .form-check-input:invalid:focus,
+.form-check-input.is-invalid:focus {
+ -webkit-box-shadow: 0 0 0 0.25rem rgba(165, 31, 24, 0.25);
+ box-shadow: 0 0 0 0.25rem rgba(165, 31, 24, 0.25);
+}
+
+.was-validated .form-check-input:invalid~.form-check-label,
+.form-check-input.is-invalid~.form-check-label {
+ color: hsl(3, 75%, 37%);
+}
+
+.form-check-inline .form-check-input~.invalid-feedback {
+ margin-left: 0.5em;
+}
+
+.was-validated .input-group>.form-control:not(:focus):invalid,
+.input-group>.form-control:not(:focus).is-invalid,
+.was-validated .input-group>.form-select:not(:focus):invalid,
+.was-validated .input-group>.custom-select:not(:focus):invalid,
+.input-group>.form-select:not(:focus).is-invalid,
+.input-group>.custom-select:not(:focus).is-invalid,
+.was-validated .input-group>.form-floating:not(:focus-within):invalid,
+.input-group>.form-floating:not(:focus-within).is-invalid {
+ z-index: 4;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .btn {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.btn:active {
+ color: var(--btn-active-color);
+ background-color: var(--btn-active-bg, hsl(210, 10%, 30%));
+ border-color: var(--btn-active-border-color, transparent);
+}
+
+.btn-check+.btn:active {
+ color: var(--btn-color);
+ background-color: var(--btn-bg, transparent);
+ border-color: var(--btn-border-color, transparent);
+}
+
+.btn:focus-visible {
+ color: var(--btn-active-color);
+ background-color: var(--btn-active-bg, hsl(210, 10%, 30%));
+ border-color: var(--btn-active-border-color, transparent);
+ outline: 0;
+ -webkit-box-shadow: var(--btn-focus-box-shadow, 0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb), .5));
+ box-shadow: var(--btn-focus-box-shadow, 0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb), .5));
+}
+
+.btn-check:focus-visible+.btn {
+ border-color: var(--btn-active-border-color, transparent);
+ outline: 0;
+ -webkit-box-shadow: var(--btn-focus-box-shadow, 0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb), .5));
+ box-shadow: var(--btn-focus-box-shadow, 0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb), .5));
+}
+
+.btn-check:checked+.btn,
+:not(.btn-check)+.btn:active,
+.btn:first-child:active,
+.btn.active,
+.btn.show {
+ color: var(--btn-active-color);
+ background-color: var(--btn-active-bg, hsl(210, 10%, 30%));
+ border-color: var(--btn-active-border-color, transparent);
+}
+
+.btn-check:checked+.btn:focus-visible,
+:not(.btn-check)+.btn:active:focus-visible,
+.btn:first-child:active:focus-visible,
+.btn.active:focus-visible,
+.btn.show:focus-visible {
+ -webkit-box-shadow: var(--btn-focus-box-shadow, 0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb), .5));
+ box-shadow: var(--btn-focus-box-shadow, 0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb), .5));
+}
+
+.btn:disabled,
+.btn.disabled,
+fieldset:disabled .btn {
+ color: var(--btn-disabled-color, #6d7781);
+ pointer-events: none;
+ background-color: var(--btn-disabled-bg, transparent);
+ border-color: var(--btn-disabled-border-color, transparent);
+ opacity: var(--btn-disabled-opacity, 0.65);
+}
+
+.btn-link {
+ --btn-font-weight: 400;
+ --btn-color: var(--link-color, #8ab4f8);
+ --btn-bg: transparent;
+ --btn-border-color: transparent;
+ --btn-active-color: var(--link-active-color);
+ --btn-active-border-color: transparent;
+ --btn-active-color: var(--link-active-color);
+ --btn-active-border-color: transparent;
+ --btn-disabled-color: hsl(210, 7%, 46%);
+ --btn-disabled-border-color: transparent;
+ --btn-box-shadow: none;
+ --btn-focus-shadow-rgb: 39, 39, 111;
+ text-decoration: underline;
+}
+
+.btn-link:focus-visible {
+ color: var(--btn-color);
+}
+
+.btn-link:active {
+ color: var(--btn-active-color);
+}
+
+.btn-lg,
+.btn-group-lg>.btn {
+ --btn-padding-y: 0.5rem;
+ --btn-padding-x: 1rem;
+ --btn-font-size: 1.25rem;
+ --btn-border-radius: 0.3rem;
+}
+
+.btn-sm,
+.btn-group-sm>.btn {
+ --btn-padding-y: 0.25rem;
+ --btn-padding-x: 0.5rem;
+ --btn-font-size: 0.875rem;
+ --btn-border-radius: 0.2rem;
+}
+
+.fade {
+ -webkit-transition: opacity 0.15s linear;
+ -o-transition: opacity 0.15s linear;
+ transition: opacity 0.15s linear;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .fade {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.fade:not(.show) {
+ opacity: 0;
+}
+
+.collapse:not(.show) {
+ display: none;
+}
+
+.collapsing {
+ height: 0;
+ overflow: hidden;
+ -webkit-transition: height 0.35s ease;
+ -o-transition: height 0.35s ease;
+ transition: height 0.35s ease;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .collapsing {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.collapsing.collapse-horizontal {
+ width: 0;
+ height: auto;
+ -webkit-transition: width 0.35s ease;
+ -o-transition: width 0.35s ease;
+ transition: width 0.35s ease;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .collapsing.collapse-horizontal {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.dropup,
+.dropend,
+.dropdown,
+.dropstart,
+.dropup-center,
+.dropdown-center {
+ position: relative;
+}
+
+.dropdown-toggle {
+ white-space: nowrap;
+}
+
+.dropdown-toggle::after {
+ display: inline-block;
+ margin-left: 0.255em;
+ vertical-align: 0.255em;
+ content: "";
+ border-top: 0.3em solid;
+ border-right: 0.3em solid transparent;
+ border-bottom: 0;
+ border-left: 0.3em solid transparent;
+}
+
+.dropdown-toggle:empty::after {
+ margin-left: 0;
+}
+
+.dropdown-menu {
+ /* Values defined in light.standard.css / dark.standard.css */
+ position: absolute;
+ z-index: var(--dropdown-zindex, 1000);
+ display: none;
+ min-width: var(--dropdown-min-width, 10rem);
+ padding: var(--dropdown-padding-y, 0.5rem) var(--dropdown-padding-x, 0);
+ margin: 0;
+ font-size: var(--dropdown-font-size, 1rem);
+ color: var(--dropdown-color);
+ text-align: left;
+ list-style: none;
+ background-color: var(--dropdown-bg);
+ background-clip: padding-box;
+ border: var(--dropdown-border-width, 1px) solid var(--dropdown-border-color);
+ border-radius: var(--dropdown-border-radius, 0.25rem);
+}
+
+.dropdown-menu[data-bs-popper] {
+ top: 100%;
+ left: 0;
+ margin-top: var(--dropdown-spacer, 0.125rem);
+}
+
+.dropdown-menu-start {
+ --bs-position: start;
+}
+
+.dropdown-menu-start[data-bs-popper] {
+ right: auto;
+ left: 0;
+}
+
+.dropdown-menu-end {
+ --bs-position: end;
+}
+
+.dropdown-menu-end[data-bs-popper] {
+ right: 0;
+ left: auto;
+}
+
+@media (min-width: 576px) {
+ .dropdown-menu-sm-start {
+ --bs-position: start;
+ }
+
+ .dropdown-menu-sm-start[data-bs-popper] {
+ right: auto;
+ left: 0;
+ }
+
+ .dropdown-menu-sm-end {
+ --bs-position: end;
+ }
+
+ .dropdown-menu-sm-end[data-bs-popper] {
+ right: 0;
+ left: auto;
+ }
+}
+
+@media (min-width: 768px) {
+ .dropdown-menu-md-start {
+ --bs-position: start;
+ }
+
+ .dropdown-menu-md-start[data-bs-popper] {
+ right: auto;
+ left: 0;
+ }
+
+ .dropdown-menu-md-end {
+ --bs-position: end;
+ }
+
+ .dropdown-menu-md-end[data-bs-popper] {
+ right: 0;
+ left: auto;
+ }
+}
+
+@media (min-width: 992px) {
+ .dropdown-menu-lg-start {
+ --bs-position: start;
+ }
+
+ .dropdown-menu-lg-start[data-bs-popper] {
+ right: auto;
+ left: 0;
+ }
+
+ .dropdown-menu-lg-end {
+ --bs-position: end;
+ }
+
+ .dropdown-menu-lg-end[data-bs-popper] {
+ right: 0;
+ left: auto;
+ }
+}
+
+@media (min-width: 1200px) {
+ .dropdown-menu-xl-start {
+ --bs-position: start;
+ }
+
+ .dropdown-menu-xl-start[data-bs-popper] {
+ right: auto;
+ left: 0;
+ }
+
+ .dropdown-menu-xl-end {
+ --bs-position: end;
+ }
+
+ .dropdown-menu-xl-end[data-bs-popper] {
+ right: 0;
+ left: auto;
+ }
+}
+
+@media (min-width: 1400px) {
+ .dropdown-menu-xxl-start {
+ --bs-position: start;
+ }
+
+ .dropdown-menu-xxl-start[data-bs-popper] {
+ right: auto;
+ left: 0;
+ }
+
+ .dropdown-menu-xxl-end {
+ --bs-position: end;
+ }
+
+ .dropdown-menu-xxl-end[data-bs-popper] {
+ right: 0;
+ left: auto;
+ }
+}
+
+.dropup .dropdown-menu[data-bs-popper] {
+ top: auto;
+ bottom: 100%;
+ margin-top: 0;
+ margin-bottom: var(--dropdown-spacer, 0.125rem);
+}
+
+.dropup .dropdown-toggle::after {
+ display: inline-block;
+ margin-left: 0.255em;
+ vertical-align: 0.255em;
+ content: "";
+ border-top: 0;
+ border-right: 0.3em solid transparent;
+ border-bottom: 0.3em solid;
+ border-left: 0.3em solid transparent;
+}
+
+.dropup .dropdown-toggle:empty::after {
+ margin-left: 0;
+}
+
+.dropend .dropdown-menu[data-bs-popper] {
+ top: 0;
+ right: auto;
+ left: 100%;
+ margin-top: 0;
+ margin-left: var(--dropdown-spacer, 0.125rem);
+}
+
+.dropend .dropdown-toggle::after {
+ display: inline-block;
+ margin-left: 0.255em;
+ vertical-align: 0.255em;
+ content: "";
+ border-top: 0.3em solid transparent;
+ border-right: 0;
+ border-bottom: 0.3em solid transparent;
+ border-left: 0.3em solid;
+}
+
+.dropend .dropdown-toggle:empty::after {
+ margin-left: 0;
+}
+
+.dropend .dropdown-toggle::after {
+ vertical-align: 0;
+}
+
+.dropstart .dropdown-menu[data-bs-popper] {
+ top: 0;
+ right: 100%;
+ left: auto;
+ margin-top: 0;
+ margin-right: var(--dropdown-spacer, 0.125rem);
+}
+
+.dropstart .dropdown-toggle::after {
+ display: inline-block;
+ margin-left: 0.255em;
+ vertical-align: 0.255em;
+ content: "";
+}
+
+.dropstart .dropdown-toggle::after {
+ display: none;
+}
+
+.dropstart .dropdown-toggle::before {
+ display: inline-block;
+ margin-right: 0.255em;
+ vertical-align: 0.255em;
+ content: "";
+ border-top: 0.3em solid transparent;
+ border-right: 0.3em solid;
+ border-bottom: 0.3em solid transparent;
+}
+
+.dropstart .dropdown-toggle:empty::after {
+ margin-left: 0;
+}
+
+.dropstart .dropdown-toggle::before {
+ vertical-align: 0;
+}
+
+.dropdown-divider {
+ height: 0;
+ margin: var(--dropdown-divider-margin-y, 0.5rem) 0;
+ overflow: hidden;
+ border-top: 1px solid var(--dropdown-divider-bg);
+ opacity: 1;
+}
+
+.dropdown-item {
+ display: block;
+ width: 100%;
+ padding: var(--dropdown-item-padding-y, 0.25rem) var(--dropdown-item-padding-x, 1rem);
+ clear: both;
+ font-weight: 400;
+ color: var(--dropdown-link-color);
+ text-align: inherit;
+ text-decoration: none;
+ white-space: nowrap;
+ background-color: transparent;
+ border: 0;
+}
+
+.dropdown-item:active,
+.dropdown-item:focus {
+ color: var(--dropdown-link-active-color);
+ background-color: var(--dropdown-link-active-bg, hsl(240, 98%, 17%));
+}
+
+.dropdown-item.active,
+.dropdown-item:active {
+ color: var(--dropdown-link-active-color);
+ text-decoration: none;
+ background-color: var(--dropdown-link-active-bg, hsl(240, 98%, 17%));
+}
+
+.dropdown-item.disabled,
+.dropdown-item:disabled {
+ color: var(--dropdown-link-disabled-color);
+ pointer-events: none;
+ background-color: transparent;
+}
+
+.dropdown-menu.show {
+ display: block;
+}
+
+.dropdown-header {
+ display: block;
+ padding: var(--dropdown-header-padding-y, 0.5rem) var(--dropdown-header-padding-x, 1rem);
+ margin-bottom: 0;
+ font-size: 0.875rem;
+ color: var(--dropdown-header-color);
+ white-space: nowrap;
+}
+
+.dropdown-item-text {
+ display: block;
+ padding: var(--dropdown-item-padding-y, 0.25rem) var(--dropdown-item-padding-x, 1rem);
+ color: var(--dropdown-link-color);
+}
+
+.dropdown-menu-dark {
+ --dropdown-color: hsl(210, 14%, 89%);
+ --dropdown-bg: hsl(210, 10%, 23%);
+ --dropdown-border-color: var(--border-color-translucent, #ffffff26);
+ --dropdown-box-shadow: ;
+ --dropdown-link-color: hsl(210, 14%, 89%);
+ --dropdown-link-active-color: var(--body-color, #e6ebf1);
+ --dropdown-divider-bg: var(--border-color-translucent, #ffffff26);
+ --dropdown-link-active-bg: rgba(255, 255, 255, 0.15);
+ --dropdown-link-active-color: var(--body-color, #e6ebf1);
+ --dropdown-link-active-bg: hsl(240, 98%, 17%);
+ --dropdown-link-disabled-color: hsl(210, 11%, 71%);
+ --dropdown-header-color: hsl(210, 11%, 71%);
+}
+
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: -webkit-inline-box;
+ display: -ms-inline-flexbox;
+ display: inline-flex;
+ vertical-align: middle;
+}
+
+.btn-group>.btn,
+.btn-group-vertical>.btn {
+ position: relative;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+}
+
+.btn-group>.btn-check:checked+.btn,
+.btn-group>.btn-check:focus+.btn,
+.btn-group>.btn:active,
+.btn-group>.btn:focus,
+.btn-group>.btn:active,
+.btn-group>.btn.active,
+.btn-group-vertical>.btn-check:checked+.btn,
+.btn-group-vertical>.btn-check:focus+.btn,
+.btn-group-vertical>.btn:active,
+.btn-group-vertical>.btn:focus,
+.btn-group-vertical>.btn:active,
+.btn-group-vertical>.btn.active {
+ z-index: 1;
+}
+
+.btn-toolbar {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+}
+
+.btn-toolbar .input-group {
+ width: auto;
+}
+
+.btn-group {
+ border-radius: 0.25rem;
+}
+
+.btn-group> :not(.btn-check:first-child)+.btn,
+.btn-group>.btn-group:not(:first-child) {
+ margin-left: -0.0625rem;
+}
+
+.btn-group>.btn:not(:last-child):not(.dropdown-toggle),
+.btn-group>.btn.dropdown-toggle-split:first-child,
+.btn-group>.btn-group:not(:last-child)>.btn {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.btn-group>.btn:nth-child(n+3),
+.btn-group> :not(.btn-check)+.btn,
+.btn-group>.btn-group:not(:first-child)>.btn {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.dropdown-toggle-split {
+ padding-right: 0.75rem;
+ padding-left: 0.75rem;
+}
+
+.dropdown-toggle-split::after,
+.dropup .dropdown-toggle-split::after,
+.dropend .dropdown-toggle-split::after {
+ margin-left: 0;
+}
+
+.dropstart .dropdown-toggle-split::before {
+ margin-right: 0;
+}
+
+.btn-sm+.dropdown-toggle-split,
+.btn-group-sm>.btn+.dropdown-toggle-split {
+ padding-right: 0.375rem;
+ padding-left: 0.375rem;
+}
+
+.btn-lg+.dropdown-toggle-split,
+.btn-group-lg>.btn+.dropdown-toggle-split {
+ padding-right: 0.75rem;
+ padding-left: 0.75rem;
+}
+
+.btn-group-vertical {
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-align: start;
+ -ms-flex-align: start;
+ align-items: flex-start;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+}
+
+.btn-group-vertical>.btn,
+.btn-group-vertical>.btn-group {
+ width: 100%;
+}
+
+.btn-group-vertical>.btn:not(:first-child),
+.btn-group-vertical>.btn-group:not(:first-child) {
+ margin-top: -0.0625rem;
+}
+
+.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle),
+.btn-group-vertical>.btn-group:not(:last-child)>.btn {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.btn-group-vertical>.btn~.btn,
+.btn-group-vertical>.btn-group:not(:first-child)>.btn {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+
+.nav {
+ /* Values defined in light.standard.css / dark.standard.css */
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+
+.nav-link {
+ display: block;
+ padding: var(--nav-link-padding-y, 0.5rem) var(--nav-link-padding-x, 1rem);
+ font-size: var(--nav-link-font-size);
+ font-weight: var(--nav-link-font-weight, 400);
+ color: var(--nav-link-color);
+ text-decoration: none;
+ -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
+ -o-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .nav-link {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.nav-link:active,
+.nav-link:focus {
+ color: var(--nav-link-active-color);
+}
+
+.nav-link.disabled {
+ color: var(--nav-link-disabled-color, #6c757d);
+ pointer-events: none;
+ cursor: default;
+}
+
+.nav-tabs {
+ /* Values defined in light.standard.css / dark.standard.css */
+ border-bottom: var(--nav-tabs-border-width, 1px) solid var(--nav-tabs-border-color);
+}
+
+.nav-tabs .nav-link {
+ margin-bottom: calc(-1 * var(--nav-tabs-border-width, 1px));
+ background: none;
+ border: var(--nav-tabs-border-width, 1px) solid transparent;
+ border-top-left-radius: var(--nav-tabs-border-radius, 0.25rem);
+ border-top-right-radius: var(--nav-tabs-border-radius, 0.25rem);
+}
+
+.nav-tabs .nav-link:active,
+.nav-tabs .nav-link:focus {
+ isolation: isolate;
+ border-color: var(--nav-tabs-link-active-border-color);
+}
+
+.nav-tabs .nav-link.disabled,
+.nav-tabs .nav-link:disabled {
+ color: var(--nav-link-disabled-color, #6c757d);
+ background-color: transparent;
+ border-color: transparent;
+}
+
+.nav-tabs .nav-link.active,
+.nav-tabs .nav-item.show .nav-link {
+ color: var(--nav-tabs-link-active-color);
+ background-color: var(--nav-tabs-link-active-bg);
+ border-color: var(--nav-tabs-link-active-border-color);
+}
+
+.nav-tabs .dropdown-menu {
+ margin-top: calc(-1 * var(--nav-tabs-border-width, 1px));
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+
+.nav-pills {
+ /* Values defined in light.standard.css / dark.standard.css */
+}
+
+.nav-pills .nav-link {
+ background: none;
+ border: 0;
+ border-radius: var(--nav-pills-border-radius, 0.25rem);
+}
+
+.nav-pills .nav-link:disabled {
+ color: var(--nav-link-disabled-color, #6c757d);
+ background-color: transparent;
+ border-color: transparent;
+}
+
+.nav-pills .nav-link.active,
+.nav-pills .show>.nav-link {
+ color: var(--nav-pills-link-active-color);
+ background-color: var(--nav-pills-link-active-bg, hsl(240, 98%, 17%));
+}
+
+.nav-fill>.nav-link,
+.nav-fill .nav-item {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+ text-align: center;
+}
+
+.nav-justified>.nav-link,
+.nav-justified .nav-item {
+ -ms-flex-preferred-size: 0;
+ flex-basis: 0;
+ -webkit-box-flex: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1;
+ text-align: center;
+}
+
+.nav-fill .nav-item .nav-link,
+.nav-justified .nav-item .nav-link {
+ width: 100%;
+}
+
+.tab-content>.tab-pane {
+ display: none;
+}
+
+.tab-content>.active {
+ display: block;
+}
+
+.navbar {
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ padding: var(--navbar-padding-y, 0.5rem) var(--navbar-padding-x, 1rem);
+}
+
+.navbar>.container,
+.navbar>.container-fluid,
+.navbar>.container-sm,
+.navbar>.container-md,
+.navbar>.container-lg,
+.navbar>.container-xl,
+.navbar>.container-xxl {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: inherit;
+ flex-wrap: inherit;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+}
+
+.navbar-brand {
+ padding-top: var(--navbar-brand-padding-y, 0.3125rem);
+ padding-bottom: var(--navbar-brand-padding-y, 0.3125rem);
+ margin-right: var(--navbar-brand-margin-end, 1rem);
+ font-size: var(--navbar-brand-font-size, 1.25rem);
+ color: var(--navbar-brand-color);
+ text-decoration: none;
+ white-space: nowrap;
+}
+
+.navbar-brand:active,
+.navbar-brand:focus {
+ color: var(--navbar-brand-active-color);
+}
+
+.navbar-nav {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+
+.navbar-nav .show>.nav-link,
+.navbar-nav .nav-link.active {
+ color: var(--navbar-active-color);
+}
+
+.navbar-nav .dropdown-menu {
+ position: static;
+}
+
+.navbar-text {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ color: var(--navbar-color);
+}
+
+.navbar-text a,
+.navbar-text a:active,
+.navbar-text a:focus {
+ color: var(--navbar-active-color);
+}
+
+.navbar-collapse {
+ -ms-flex-preferred-size: 100%;
+ flex-basis: 100%;
+ -webkit-box-flex: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+
+.navbar-toggler {
+ padding: var(--navbar-toggler-padding-y, 0.25rem) var(--navbar-toggler-padding-x, 0.75rem);
+ font-size: var(--navbar-toggler-font-size, 1.25rem);
+ line-height: 1;
+ color: var(--navbar-color);
+ background-color: transparent;
+ border: 0;
+ -webkit-transition: var(--navbar-toggler-transition, box-shadow 0.15s ease-in-out);
+ -o-transition: var(--navbar-toggler-transition, box-shadow 0.15s ease-in-out);
+ transition: var(--navbar-toggler-transition, box-shadow 0.15s ease-in-out);
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .navbar-toggler {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.navbar-toggler:active {
+ text-decoration: none;
+}
+
+.navbar-toggler:focus {
+ text-decoration: none;
+ outline: 0;
+ color: var(--color-primary, #112855);
+}
+
+.navbar-toggler-icon {
+ display: inline-block;
+ width: 1.5em;
+ height: 1.5em;
+ vertical-align: middle;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: 100%;
+}
+
+.navbar-nav-scroll {
+ max-height: var(--scroll-height, 75vh);
+ overflow-y: auto;
+}
+
+@media (min-width: 576px) {
+ .navbar-expand-sm {
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ }
+
+ .navbar-expand-sm .navbar-nav {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ }
+
+ .navbar-expand-sm .navbar-nav .dropdown-menu {
+ position: absolute;
+ }
+
+ .navbar-expand-sm .navbar-nav .nav-link {
+ padding-right: var(--navbar-nav-link-padding-x, 0.5rem);
+ padding-left: var(--navbar-nav-link-padding-x, 0.5rem);
+ }
+
+ .navbar-expand-sm .navbar-nav-scroll {
+ overflow: visible;
+ }
+
+ .navbar-expand-sm .navbar-collapse {
+ display: -webkit-box ;
+ display: -ms-flexbox ;
+ display: flex ;
+ -ms-flex-preferred-size: auto;
+ flex-basis: auto;
+ }
+
+ .navbar-expand-sm .navbar-toggler {
+ display: none;
+ }
+
+ .navbar-expand-sm .offcanvas {
+ position: static;
+ z-index: auto;
+ -webkit-box-flex: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1;
+ width: auto ;
+ height: auto ;
+ visibility: visible ;
+ background-color: transparent ;
+ border: 0 ;
+ -webkit-transform: none ;
+ transform: none ;
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+
+ .navbar-expand-sm .offcanvas .offcanvas-header {
+ display: none;
+ }
+
+ .navbar-expand-sm .offcanvas .offcanvas-body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 0;
+ -ms-flex-positive: 0;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ }
+}
+
+@media (min-width: 768px) {
+ .navbar-expand-md {
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ }
+
+ .navbar-expand-md .navbar-nav {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ }
+
+ .navbar-expand-md .navbar-nav .dropdown-menu {
+ position: absolute;
+ }
+
+ .navbar-expand-md .navbar-nav .nav-link {
+ padding-right: var(--navbar-nav-link-padding-x, 0.5rem);
+ padding-left: var(--navbar-nav-link-padding-x, 0.5rem);
+ }
+
+ .navbar-expand-md .navbar-nav-scroll {
+ overflow: visible;
+ }
+
+ .navbar-expand-md .navbar-collapse {
+ display: -webkit-box ;
+ display: -ms-flexbox ;
+ display: flex ;
+ -ms-flex-preferred-size: auto;
+ flex-basis: auto;
+ }
+
+ .navbar-expand-md .navbar-toggler {
+ display: none;
+ }
+
+ .navbar-expand-md .offcanvas {
+ position: static;
+ z-index: auto;
+ -webkit-box-flex: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1;
+ width: auto ;
+ height: auto ;
+ visibility: visible ;
+ background-color: transparent ;
+ border: 0 ;
+ -webkit-transform: none ;
+ transform: none ;
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+
+ .navbar-expand-md .offcanvas .offcanvas-header {
+ display: none;
+ }
+
+ .navbar-expand-md .offcanvas .offcanvas-body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 0;
+ -ms-flex-positive: 0;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ }
+}
+
+@media (min-width: 992px) {
+ .navbar-expand-lg {
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ }
+
+ .navbar-expand-lg .navbar-nav {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ }
+
+ .navbar-expand-lg .navbar-nav .dropdown-menu {
+ position: absolute;
+ }
+
+ .navbar-expand-lg .navbar-nav .nav-link {
+ padding-right: var(--navbar-nav-link-padding-x, 0.5rem);
+ padding-left: var(--navbar-nav-link-padding-x, 0.5rem);
+ }
+
+ .navbar-expand-lg .navbar-nav-scroll {
+ overflow: visible;
+ }
+
+ .navbar-expand-lg .navbar-collapse {
+ display: -webkit-box ;
+ display: -ms-flexbox ;
+ display: flex ;
+ -ms-flex-preferred-size: auto;
+ flex-basis: auto;
+ }
+
+ .navbar-expand-lg .navbar-toggler {
+ display: none;
+ }
+
+ .navbar-expand-lg .offcanvas {
+ position: static;
+ z-index: auto;
+ -webkit-box-flex: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1;
+ width: auto ;
+ height: auto ;
+ visibility: visible ;
+ background-color: transparent ;
+ border: 0 ;
+ -webkit-transform: none ;
+ transform: none ;
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+
+ .navbar-expand-lg .offcanvas .offcanvas-header {
+ display: none;
+ }
+
+ .navbar-expand-lg .offcanvas .offcanvas-body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 0;
+ -ms-flex-positive: 0;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ }
+}
+
+@media (min-width: 1200px) {
+ .navbar-expand-xl {
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ }
+
+ .navbar-expand-xl .navbar-nav {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ }
+
+ .navbar-expand-xl .navbar-nav .dropdown-menu {
+ position: absolute;
+ }
+
+ .navbar-expand-xl .navbar-nav .nav-link {
+ padding-right: var(--navbar-nav-link-padding-x, 0.5rem);
+ padding-left: var(--navbar-nav-link-padding-x, 0.5rem);
+ }
+
+ .navbar-expand-xl .navbar-nav-scroll {
+ overflow: visible;
+ }
+
+ .navbar-expand-xl .navbar-collapse {
+ display: -webkit-box ;
+ display: -ms-flexbox ;
+ display: flex ;
+ -ms-flex-preferred-size: auto;
+ flex-basis: auto;
+ }
+
+ .navbar-expand-xl .navbar-toggler {
+ display: none;
+ }
+
+ .navbar-expand-xl .offcanvas {
+ position: static;
+ z-index: auto;
+ -webkit-box-flex: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1;
+ width: auto ;
+ height: auto ;
+ visibility: visible ;
+ background-color: transparent ;
+ border: 0 ;
+ -webkit-transform: none ;
+ transform: none ;
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+
+ .navbar-expand-xl .offcanvas .offcanvas-header {
+ display: none;
+ }
+
+ .navbar-expand-xl .offcanvas .offcanvas-body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 0;
+ -ms-flex-positive: 0;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ }
+}
+
+@media (min-width: 1400px) {
+ .navbar-expand-xxl {
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ }
+
+ .navbar-expand-xxl .navbar-nav {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ }
+
+ .navbar-expand-xxl .navbar-nav .dropdown-menu {
+ position: absolute;
+ }
+
+ .navbar-expand-xxl .navbar-nav .nav-link {
+ padding-right: var(--navbar-nav-link-padding-x, 0.5rem);
+ padding-left: var(--navbar-nav-link-padding-x, 0.5rem);
+ }
+
+ .navbar-expand-xxl .navbar-nav-scroll {
+ overflow: visible;
+ }
+
+ .navbar-expand-xxl .navbar-collapse {
+ display: -webkit-box ;
+ display: -ms-flexbox ;
+ display: flex ;
+ -ms-flex-preferred-size: auto;
+ flex-basis: auto;
+ }
+
+ .navbar-expand-xxl .navbar-toggler {
+ display: none;
+ }
+
+ .navbar-expand-xxl .offcanvas {
+ position: static;
+ z-index: auto;
+ -webkit-box-flex: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1;
+ width: auto ;
+ height: auto ;
+ visibility: visible ;
+ background-color: transparent ;
+ border: 0 ;
+ -webkit-transform: none ;
+ transform: none ;
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+
+ .navbar-expand-xxl .offcanvas .offcanvas-header {
+ display: none;
+ }
+
+ .navbar-expand-xxl .offcanvas .offcanvas-body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 0;
+ -ms-flex-positive: 0;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ }
+}
+
+.navbar-expand {
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+}
+
+.navbar-expand .navbar-nav {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+}
+
+.navbar-expand .navbar-nav .dropdown-menu {
+ position: absolute;
+}
+
+.navbar-expand .navbar-nav .nav-link {
+ padding-right: var(--navbar-nav-link-padding-x, 0.5rem);
+ padding-left: var(--navbar-nav-link-padding-x, 0.5rem);
+}
+
+.navbar-expand .navbar-nav-scroll {
+ overflow: visible;
+}
+
+.navbar-expand .navbar-collapse {
+ display: -webkit-box ;
+ display: -ms-flexbox ;
+ display: flex ;
+ -ms-flex-preferred-size: auto;
+ flex-basis: auto;
+}
+
+.navbar-expand .navbar-toggler {
+ display: none;
+}
+
+.navbar-expand .offcanvas {
+ position: static;
+ z-index: auto;
+ -webkit-box-flex: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1;
+ width: auto ;
+ height: auto ;
+ visibility: visible ;
+ background-color: transparent ;
+ border: 0 ;
+ -webkit-transform: none ;
+ transform: none ;
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+}
+
+.navbar-expand .offcanvas .offcanvas-header {
+ display: none;
+}
+
+.navbar-expand .offcanvas .offcanvas-body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 0;
+ -ms-flex-positive: 0;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+}
+
+.card {
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ min-width: 0;
+ height: var(--card-height, auto);
+ word-wrap: break-word;
+ background-color: var(--card-bg);
+ background-clip: border-box;
+ border: var(--card-border-width, 1px) solid var(--card-border-color);
+ border-radius: var(--card-border-radius, .25rem);
+}
+
+.card>hr {
+ margin-right: 0;
+ margin-left: 0;
+}
+
+.card>.list-group {
+ border-top: inherit;
+ border-bottom: inherit;
+}
+
+.card>.list-group:first-child {
+ border-top-width: 0;
+ border-top-left-radius: var(--card-inner-border-radius, calc(var(--border-radius) - 1px));
+ border-top-right-radius: var(--card-inner-border-radius, calc(var(--border-radius) - 1px));
+}
+
+.card>.list-group:last-child {
+ border-bottom-width: 0;
+ border-bottom-right-radius: var(--card-inner-border-radius, calc(var(--border-radius) - 1px));
+ border-bottom-left-radius: var(--card-inner-border-radius, calc(var(--border-radius) - 1px));
+}
+
+.card>.card-header+.list-group,
+.card>.list-group+.card-footer {
+ border-top: 0;
+}
+
+.card-body {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+ padding: var(--card-spacer-y, 1rem) var(--card-spacer-x, 1rem);
+ color: var(--card-color);
+}
+
+.card-title {
+ margin-bottom: var(--card-title-spacer-y, 0.5rem);
+}
+
+.card-subtitle {
+ margin-top: calc(-0.5 * var(--card-title-spacer-y, 0.5rem));
+ margin-bottom: 0;
+}
+
+.card-text:last-child {
+ margin-bottom: 0;
+}
+
+.card-link+.card-link {
+ margin-left: var(--card-spacer-x, 1rem);
+}
+
+.card-header {
+ padding: var(--card-cap-padding-y, 0.5rem) var(--card-cap-padding-x, 1rem);
+ margin-bottom: 0;
+ color: var(--card-cap-color);
+ background-color: var(--card-cap-bg, rgba(255, 255, 255, 0.03));
+ border-bottom: var(--card-border-width, 1px) solid var(--card-border-color);
+}
+
+.card-header:first-child {
+ border-radius: var(--card-inner-border-radius, calc(var(--border-radius) - 1px)) var(--card-inner-border-radius, calc(var(--border-radius) - 1px)) 0 0;
+}
+
+.card-footer {
+ padding: var(--card-cap-padding-y, 0.5rem) var(--card-cap-padding-x, 1rem);
+ color: var(--card-cap-color);
+ background-color: var(--card-cap-bg, rgba(255, 255, 255, 0.03));
+ border-top: var(--card-border-width, 1px) solid var(--card-border-color);
+}
+
+.card-footer:last-child {
+ border-radius: 0 0 var(--card-inner-border-radius, calc(var(--border-radius) - 1px)) var(--card-inner-border-radius, calc(var(--border-radius) - 1px));
+}
+
+.card-header-tabs {
+ margin-right: calc(-0.5 * var(--card-cap-padding-x, 1rem));
+ margin-bottom: calc(-1 * var(--card-cap-padding-y, 0.5rem));
+ margin-left: calc(-0.5 * var(--card-cap-padding-x, 1rem));
+ border-bottom: 0;
+}
+
+.card-header-tabs .nav-link.active {
+ background-color: var(--card-bg);
+ border-bottom-color: var(--card-bg);
+}
+
+.card-header-pills {
+ margin-right: calc(-0.5 * var(--card-cap-padding-x, 1rem));
+ margin-left: calc(-0.5 * var(--card-cap-padding-x, 1rem));
+}
+
+.card-img-overlay {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ padding: var(--card-img-overlay-padding, 1rem);
+ border-radius: var(--card-inner-border-radius, calc(var(--border-radius) - 1px));
+}
+
+.card-img,
+.card-img-top,
+.card-img-bottom {
+ width: 100%;
+}
+
+.card-img,
+.card-img-top {
+ border-top-left-radius: var(--card-inner-border-radius, calc(var(--border-radius) - 1px));
+ border-top-right-radius: var(--card-inner-border-radius, calc(var(--border-radius) - 1px));
+}
+
+.card-img,
+.card-img-bottom {
+ border-bottom-right-radius: var(--card-inner-border-radius, calc(var(--border-radius) - 1px));
+ border-bottom-left-radius: var(--card-inner-border-radius, calc(var(--border-radius) - 1px));
+}
+
+.card-group>.card {
+ margin-bottom: var(--card-group-margin, 0.75rem);
+}
+
+@media (min-width: 576px) {
+ .card-group {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-flow: row wrap;
+ flex-flow: row wrap;
+ }
+
+ .card-group>.card {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 0%;
+ flex: 1 0 0%;
+ margin-bottom: 0;
+ }
+
+ .card-group>.card+.card {
+ margin-left: 0;
+ border-left: 0;
+ }
+
+ .card-group>.card:not(:last-child) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ }
+
+ .card-group>.card:not(:last-child) .card-img-top,
+ .card-group>.card:not(:last-child) .card-header {
+ border-top-right-radius: 0;
+ }
+
+ .card-group>.card:not(:last-child) .card-img-bottom,
+ .card-group>.card:not(:last-child) .card-footer {
+ border-bottom-right-radius: 0;
+ }
+
+ .card-group>.card:not(:first-child) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+
+ .card-group>.card:not(:first-child) .card-img-top,
+ .card-group>.card:not(:first-child) .card-header {
+ border-top-left-radius: 0;
+ }
+
+ .card-group>.card:not(:first-child) .card-img-bottom,
+ .card-group>.card:not(:first-child) .card-footer {
+ border-bottom-left-radius: 0;
+ }
+}
+
+.accordion {
+ /* Values defined in light.standard.css / dark.standard.css */
+}
+
+.accordion-button {
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ width: 100%;
+ padding: var(--accordion-btn-padding-y, 1rem) var(--accordion-btn-padding-x, 1.25rem);
+ font-size: 1rem;
+ color: var(--accordion-btn-color);
+ text-align: left;
+ background-color: var(--accordion-btn-bg);
+ border: 0;
+ border-radius: 0;
+ overflow-anchor: none;
+ -webkit-transition: var(--accordion-transition);
+ -o-transition: var(--accordion-transition);
+ transition: var(--accordion-transition);
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .accordion-button {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.accordion-button:not(.collapsed) {
+ color: var(--accordion-active-color);
+ background-color: var(--accordion-active-bg);
+ -webkit-box-shadow: inset 0 calc(-1 * var(--accordion-border-width, 1px)) 0 var(--accordion-border-color);
+ box-shadow: inset 0 calc(-1 * var(--accordion-border-width, 1px)) 0 var(--accordion-border-color);
+}
+
+.accordion-button:not(.collapsed)::after {
+ background-image: var(--accordion-btn-active-icon);
+ -webkit-transform: var(--accordion-btn-icon-transform, rotate(-180deg));
+ transform: var(--accordion-btn-icon-transform, rotate(-180deg));
+}
+
+.accordion-button::after {
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
+ width: var(--accordion-btn-icon-width, 1.25rem);
+ height: var(--accordion-btn-icon-width, 1.25rem);
+ margin-left: auto;
+ content: "";
+ background-image: var(--accordion-btn-icon);
+ background-repeat: no-repeat;
+ background-size: var(--accordion-btn-icon-width, 1.25rem);
+ -webkit-transition: var(--accordion-btn-icon-transition, transform 0.2s ease-in-out);
+ -o-transition: var(--accordion-btn-icon-transition, transform 0.2s ease-in-out);
+ transition: var(--accordion-btn-icon-transition, transform 0.2s ease-in-out);
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .accordion-button::after {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.accordion-button:active {
+ z-index: 2;
+}
+
+.accordion-button:focus {
+ z-index: 3;
+ border-color: var(--accordion-btn-focus-border-color);
+ outline: 0;
+ -webkit-box-shadow: var(--accordion-btn-focus-box-shadow, 0 0 0 0.25rem rgba(84, 114, 255, 0.25));
+ box-shadow: var(--accordion-btn-focus-box-shadow, 0 0 0 0.25rem rgba(84, 114, 255, 0.25));
+}
+
+.accordion-header {
+ margin-bottom: 0;
+}
+
+.accordion-item {
+ color: var(--accordion-color);
+ background-color: var(--accordion-bg);
+ border: var(--accordion-border-width, 1px) solid var(--accordion-border-color);
+}
+
+.accordion-item:first-of-type {
+ border-top-left-radius: var(--accordion-border-radius, 0.25rem);
+ border-top-right-radius: var(--accordion-border-radius, 0.25rem);
+}
+
+.accordion-item:first-of-type .accordion-button {
+ border-top-left-radius: var(--accordion-inner-border-radius, calc(0.25rem - 1px));
+ border-top-right-radius: var(--accordion-inner-border-radius, calc(0.25rem - 1px));
+}
+
+.accordion-item:not(:first-of-type) {
+ border-top: 0;
+}
+
+.accordion-item:last-of-type {
+ border-bottom-right-radius: var(--accordion-border-radius, 0.25rem);
+ border-bottom-left-radius: var(--accordion-border-radius, 0.25rem);
+}
+
+.accordion-item:last-of-type .accordion-button.collapsed {
+ border-bottom-right-radius: var(--accordion-inner-border-radius, calc(0.25rem - 1px));
+ border-bottom-left-radius: var(--accordion-inner-border-radius, calc(0.25rem - 1px));
+}
+
+.accordion-item:last-of-type .accordion-collapse {
+ border-bottom-right-radius: var(--accordion-border-radius, 0.25rem);
+ border-bottom-left-radius: var(--accordion-border-radius, 0.25rem);
+}
+
+.accordion-body {
+ padding: var(--accordion-body-padding-y, 1rem) var(--accordion-body-padding-x, 1.25rem);
+}
+
+.accordion-flush .accordion-collapse {
+ border-width: 0;
+}
+
+.accordion-flush .accordion-item {
+ border-right: 0;
+ border-left: 0;
+ border-radius: 0;
+}
+
+.accordion-flush .accordion-item:first-child {
+ border-top: 0;
+}
+
+.accordion-flush .accordion-item:last-child {
+ border-bottom: 0;
+}
+
+.accordion-flush .accordion-item .accordion-button,
+.accordion-flush .accordion-item .accordion-button.collapsed {
+ border-radius: 0;
+}
+
+.breadcrumb {
+ /* Values defined in light.standard.css / dark.standard.css */
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ padding: var(--breadcrumb-padding-y, 0) var(--breadcrumb-padding-x, 0);
+ margin-bottom: var(--breadcrumb-margin-bottom, 1rem);
+ font-size: var(--breadcrumb-font-size);
+ list-style: none;
+ background-color: var(--breadcrumb-bg, );
+ border-radius: var(--breadcrumb-border-radius, );
+}
+
+.breadcrumb-item+.breadcrumb-item {
+ padding-left: var(--breadcrumb-item-padding-x, 0.5rem);
+}
+
+.breadcrumb-item+.breadcrumb-item::before {
+ float: left;
+ padding-right: var(--breadcrumb-item-padding-x, 0.5rem);
+ color: var(--breadcrumb-divider-color);
+ content: var(--breadcrumb-divider, "\00a0/\00a0");
+ ;
+}
+
+.breadcrumb-item.active {
+ color: var(--breadcrumb-item-active-color);
+}
+
+.pagination {
+ /* Values defined in light.standard.css / dark.standard.css */
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ padding-left: 0;
+ list-style: none;
+}
+
+.page-link {
+ position: relative;
+ display: block;
+ padding: var(--pagination-padding-y, 0.375rem) var(--pagination-padding-x, 0.75rem);
+ font-size: var(--pagination-font-size, 1rem);
+ color: var(--pagination-color);
+ text-decoration: none;
+ background-color: var(--pagination-bg);
+ border: var(--pagination-border-width, 1px) solid var(--pagination-border-color);
+ -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ -o-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .page-link {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.page-link:active {
+ z-index: 2;
+ color: var(--pagination-active-color);
+ background-color: var(--pagination-active-bg, hsl(240, 98%, 17%));
+ border-color: var(--pagination-active-border-color, hsl(240, 98%, 17%));
+}
+
+.page-link:focus {
+ z-index: 3;
+ color: var(--pagination-focus-color);
+ background-color: var(--pagination-focus-bg);
+ outline: 0;
+ -webkit-box-shadow: var(--pagination-focus-box-shadow, 0 0 0 0.25rem rgba(84, 114, 255, 0.25));
+ box-shadow: var(--pagination-focus-box-shadow, 0 0 0 0.25rem rgba(84, 114, 255, 0.25));
+}
+
+.page-link.active,
+.active>.page-link {
+ z-index: 3;
+ color: var(--pagination-active-color);
+ background-color: var(--pagination-active-bg, hsl(240, 98%, 17%));
+ border-color: var(--pagination-active-border-color, hsl(240, 98%, 17%));
+}
+
+.page-link.disabled,
+.disabled>.page-link {
+ color: var(--pagination-disabled-color);
+ pointer-events: none;
+ background-color: var(--pagination-disabled-bg);
+ border-color: var(--pagination-disabled-border-color);
+}
+
+.page-item:not(:first-child) .page-link {
+ margin-left: -0.0625rem;
+}
+
+.page-item:first-child .page-link {
+ border-top-left-radius: var(--pagination-border-radius, 0.25rem);
+ border-bottom-left-radius: var(--pagination-border-radius, 0.25rem);
+}
+
+.page-item:last-child .page-link {
+ border-top-right-radius: var(--pagination-border-radius, 0.25rem);
+ border-bottom-right-radius: var(--pagination-border-radius, 0.25rem);
+}
+
+.pagination-lg {
+ --pagination-padding-x: 1.5rem;
+ --pagination-padding-y: 0.75rem;
+ --pagination-font-size: 1.25rem;
+ --pagination-border-radius: 0.3rem;
+}
+
+.pagination-sm {
+ --pagination-padding-x: 0.5rem;
+ --pagination-padding-y: 0.25rem;
+ --pagination-font-size: 0.875rem;
+ --pagination-border-radius: 0.2rem;
+}
+
+.badge {
+ /* Values defined in light.standard.css / dark.standard.css */
+ display: inline-block;
+ padding: var(--badge-padding-y, 0.35em) var(--badge-padding-x, 0.65em);
+ font-size: var(--badge-font-size, 0.75em);
+ font-weight: var(--badge-font-weight, 700);
+ line-height: 1;
+ color: var(--badge-color);
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: var(--badge-border-radius, 0.25rem);
+}
+
+.badge:empty {
+ display: none;
+}
+
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+
+.alert {
+ /* Values defined in light.standard.css / dark.standard.css */
+ position: relative;
+ padding: var(--alert-padding-y, 1rem) var(--alert-padding-x, 1rem);
+ margin-bottom: var(--alert-margin-bottom, 1rem);
+ color: var(--alert-color, inherit);
+ background-color: var(--alert-bg, transparent);
+ border: var(--alert-border, 1px solid var(--alert-border-color));
+ border-radius: var(--alert-border-radius, 0.25rem);
+}
+
+.alert-heading {
+ color: inherit;
+}
+
+.alert-link {
+ font-weight: 700;
+}
+
+.alert-dismissible {
+ padding-right: 3rem;
+}
+
+.alert-dismissible .btn-close {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 2;
+ padding: 1.25rem 1rem;
+}
+
+.alert-primary {
+ --alert-color: #010134;
+ --alert-bg: #ccccdd;
+ --alert-border-color: #b3b3cc;
+}
+
+.alert-primary .alert-link {
+ color: var(--alert-primary-link-color, #b3c1ff);
+}
+
+.alert-secondary {
+ --alert-color: #41464c;
+ --alert-bg: #e2e3e5;
+ --alert-border-color: #d3d6d8;
+}
+
+.alert-secondary .alert-link {
+ color: var(--alert-secondary-link-color, #9fa6ad);
+}
+
+.alert-success {
+ --alert-color: #294f29;
+ --alert-bg: #dae6da;
+ --alert-border-color: #c7dac7;
+}
+
+.alert-success .alert-link {
+ color: var(--alert-success-link-color, #a0e5b3);
+}
+
+.alert-info {
+ --alert-color: #1d3b55;
+ --alert-bg: #d6e0e8;
+ --alert-border-color: #c1d0dd;
+}
+
+.alert-info .alert-link {
+ color: var(--alert-info-link-color, #8eccf2);
+}
+
+.alert-warning {
+ --alert-color: #683b00;
+ --alert-bg: #efe0cc;
+ --alert-border-color: #e6d0b3;
+}
+
+.alert-warning .alert-link {
+ color: var(--alert-warning-link-color, #ffe4a0);
+}
+
+.alert-danger {
+ --alert-color: #63130e;
+ --alert-bg: #edd2d1;
+ --alert-border-color: #e4bcba;
+}
+
+.alert-danger .alert-link {
+ color: var(--alert-danger-link-color, #ffa8a3);
+}
+
+.alert-light {
+ --alert-color: #646464;
+ --alert-bg: #fefefe;
+ --alert-border-color: #fdfefe;
+}
+
+.alert-light .alert-link {
+ color: var(--alert-light-link-color, #f0f4f8);
+}
+
+.alert-dark {
+ --alert-color: #202327;
+ --alert-bg: #d7d8d9;
+ --alert-border-color: #c2c4c6;
+}
+
+.alert-dark .alert-link {
+ color: var(--alert-dark-link-color, #9fa6ad);
+}
+
+@-webkit-keyframes progress-bar-stripes {
+ 0% {
+ background-position-x: 1rem;
+ }
+}
+
+@keyframes progress-bar-stripes {
+ 0% {
+ background-position-x: 1rem;
+ }
+}
+
+.progress {
+ /* Values defined in light.standard.css / dark.standard.css */
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ height: var(--progress-height, 1rem);
+ overflow: hidden;
+ font-size: var(--progress-font-size, 0.75rem);
+ background-color: var(--progress-bg);
+ border-radius: var(--progress-border-radius, 0.25rem);
+}
+
+.progress-bar {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ overflow: hidden;
+ color: var(--progress-bar-color);
+ text-align: center;
+ white-space: nowrap;
+ background-color: var(--progress-bar-bg, hsl(240, 98%, 40%));
+ -webkit-transition: var(--progress-bar-transition, width 0.6s ease);
+ -o-transition: var(--progress-bar-transition, width 0.6s ease);
+ transition: var(--progress-bar-transition, width 0.6s ease);
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .progress-bar {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.progress-bar-striped {
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-size: var(--progress-height, 1rem) var(--progress-height, 1rem);
+}
+
+.progress-bar-animated {
+ -webkit-animation: 1s linear infinite progress-bar-stripes;
+ animation: 1s linear infinite progress-bar-stripes;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .progress-bar-animated {
+ -webkit-animation: none;
+ animation: none;
+ }
+}
+
+.list-group {
+ /* Values defined in light.standard.css / dark.standard.css */
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ padding-left: 0;
+ margin-bottom: 0;
+ border-radius: var(--list-group-border-radius, 0.25rem);
+}
+
+.list-group-numbered {
+ list-style-type: none;
+ counter-reset: section;
+}
+
+.list-group-numbered>.list-group-item::before {
+ content: counters(section, ".") ". ";
+ counter-increment: section;
+}
+
+.list-group-item-action {
+ width: 100%;
+ color: var(--list-group-action-color);
+ text-align: inherit;
+}
+
+.list-group-item-action:active,
+.list-group-item-action:focus {
+ z-index: 1;
+ color: var(--list-group-action-active-color);
+ text-decoration: none;
+ background-color: var(--list-group-action-active-bg);
+}
+
+.list-group-item-action:active {
+ color: var(--list-group-action-active-color);
+ background-color: var(--list-group-action-active-bg);
+}
+
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: var(--list-group-item-padding-y, 0.5rem) var(--list-group-item-padding-x, 1rem);
+ color: var(--list-group-color);
+ text-decoration: none;
+ background-color: var(--list-group-bg);
+ border: var(--list-group-border-width, 1px) solid var(--list-group-border-color, rgba(var(--white-rgb), 0.125));
+}
+
+.list-group-item:first-child {
+ border-top-left-radius: inherit;
+ border-top-right-radius: inherit;
+}
+
+.list-group-item:last-child {
+ border-bottom-right-radius: inherit;
+ border-bottom-left-radius: inherit;
+}
+
+.list-group-item.disabled,
+.list-group-item:disabled {
+ color: var(--list-group-disabled-color);
+ pointer-events: none;
+ background-color: var(--list-group-disabled-bg);
+}
+
+.list-group-item.active {
+ z-index: 2;
+ color: var(--list-group-active-color);
+ background-color: var(--list-group-active-bg, hsl(240, 98%, 17%));
+ border-color: var(--list-group-active-border-color, hsl(240, 98%, 17%));
+}
+
+.list-group-item+.list-group-item {
+ border-top-width: 0;
+}
+
+.list-group-item+.list-group-item.active {
+ margin-top: calc(-1 * var(--list-group-border-width, 1px));
+ border-top-width: var(--list-group-border-width, 1px);
+}
+
+.list-group-horizontal {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+}
+
+.list-group-horizontal>.list-group-item:first-child:not(:last-child) {
+ border-bottom-left-radius: var(--list-group-border-radius, 0.25rem);
+ border-top-right-radius: 0;
+}
+
+.list-group-horizontal>.list-group-item:last-child:not(:first-child) {
+ border-top-right-radius: var(--list-group-border-radius, 0.25rem);
+ border-bottom-left-radius: 0;
+}
+
+.list-group-horizontal>.list-group-item.active {
+ margin-top: 0;
+}
+
+.list-group-horizontal>.list-group-item+.list-group-item {
+ border-top-width: var(--list-group-border-width, 1px);
+ border-left-width: 0;
+}
+
+.list-group-horizontal>.list-group-item+.list-group-item.active {
+ margin-left: calc(-1 * var(--list-group-border-width, 1px));
+ border-left-width: var(--list-group-border-width, 1px);
+}
+
+@media (min-width: 576px) {
+ .list-group-horizontal-sm {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ }
+
+ .list-group-horizontal-sm>.list-group-item:first-child:not(:last-child) {
+ border-bottom-left-radius: var(--list-group-border-radius, 0.25rem);
+ border-top-right-radius: 0;
+ }
+
+ .list-group-horizontal-sm>.list-group-item:last-child:not(:first-child) {
+ border-top-right-radius: var(--list-group-border-radius, 0.25rem);
+ border-bottom-left-radius: 0;
+ }
+
+ .list-group-horizontal-sm>.list-group-item.active {
+ margin-top: 0;
+ }
+
+ .list-group-horizontal-sm>.list-group-item+.list-group-item {
+ border-top-width: var(--list-group-border-width, 1px);
+ border-left-width: 0;
+ }
+
+ .list-group-horizontal-sm>.list-group-item+.list-group-item.active {
+ margin-left: calc(-1 * var(--list-group-border-width, 1px));
+ border-left-width: var(--list-group-border-width, 1px);
+ }
+}
+
+@media (min-width: 768px) {
+ .list-group-horizontal-md {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ }
+
+ .list-group-horizontal-md>.list-group-item:first-child:not(:last-child) {
+ border-bottom-left-radius: var(--list-group-border-radius, 0.25rem);
+ border-top-right-radius: 0;
+ }
+
+ .list-group-horizontal-md>.list-group-item:last-child:not(:first-child) {
+ border-top-right-radius: var(--list-group-border-radius, 0.25rem);
+ border-bottom-left-radius: 0;
+ }
+
+ .list-group-horizontal-md>.list-group-item.active {
+ margin-top: 0;
+ }
+
+ .list-group-horizontal-md>.list-group-item+.list-group-item {
+ border-top-width: var(--list-group-border-width, 1px);
+ border-left-width: 0;
+ }
+
+ .list-group-horizontal-md>.list-group-item+.list-group-item.active {
+ margin-left: calc(-1 * var(--list-group-border-width, 1px));
+ border-left-width: var(--list-group-border-width, 1px);
+ }
+}
+
+@media (min-width: 992px) {
+ .list-group-horizontal-lg {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ }
+
+ .list-group-horizontal-lg>.list-group-item:first-child:not(:last-child) {
+ border-bottom-left-radius: var(--list-group-border-radius, 0.25rem);
+ border-top-right-radius: 0;
+ }
+
+ .list-group-horizontal-lg>.list-group-item:last-child:not(:first-child) {
+ border-top-right-radius: var(--list-group-border-radius, 0.25rem);
+ border-bottom-left-radius: 0;
+ }
+
+ .list-group-horizontal-lg>.list-group-item.active {
+ margin-top: 0;
+ }
+
+ .list-group-horizontal-lg>.list-group-item+.list-group-item {
+ border-top-width: var(--list-group-border-width, 1px);
+ border-left-width: 0;
+ }
+
+ .list-group-horizontal-lg>.list-group-item+.list-group-item.active {
+ margin-left: calc(-1 * var(--list-group-border-width, 1px));
+ border-left-width: var(--list-group-border-width, 1px);
+ }
+}
+
+@media (min-width: 1200px) {
+ .list-group-horizontal-xl {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ }
+
+ .list-group-horizontal-xl>.list-group-item:first-child:not(:last-child) {
+ border-bottom-left-radius: var(--list-group-border-radius, 0.25rem);
+ border-top-right-radius: 0;
+ }
+
+ .list-group-horizontal-xl>.list-group-item:last-child:not(:first-child) {
+ border-top-right-radius: var(--list-group-border-radius, 0.25rem);
+ border-bottom-left-radius: 0;
+ }
+
+ .list-group-horizontal-xl>.list-group-item.active {
+ margin-top: 0;
+ }
+
+ .list-group-horizontal-xl>.list-group-item+.list-group-item {
+ border-top-width: var(--list-group-border-width, 1px);
+ border-left-width: 0;
+ }
+
+ .list-group-horizontal-xl>.list-group-item+.list-group-item.active {
+ margin-left: calc(-1 * var(--list-group-border-width, 1px));
+ border-left-width: var(--list-group-border-width, 1px);
+ }
+}
+
+@media (min-width: 1400px) {
+ .list-group-horizontal-xxl {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ }
+
+ .list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child) {
+ border-bottom-left-radius: var(--list-group-border-radius, 0.25rem);
+ border-top-right-radius: 0;
+ }
+
+ .list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child) {
+ border-top-right-radius: var(--list-group-border-radius, 0.25rem);
+ border-bottom-left-radius: 0;
+ }
+
+ .list-group-horizontal-xxl>.list-group-item.active {
+ margin-top: 0;
+ }
+
+ .list-group-horizontal-xxl>.list-group-item+.list-group-item {
+ border-top-width: var(--list-group-border-width, 1px);
+ border-left-width: 0;
+ }
+
+ .list-group-horizontal-xxl>.list-group-item+.list-group-item.active {
+ margin-left: calc(-1 * var(--list-group-border-width, 1px));
+ border-left-width: var(--list-group-border-width, 1px);
+ }
+}
+
+.list-group-flush {
+ border-radius: 0;
+}
+
+.list-group-flush>.list-group-item {
+ border-width: 0 0 var(--list-group-border-width, 1px);
+}
+
+.list-group-flush>.list-group-item:last-child {
+ border-bottom-width: 0;
+}
+
+.list-group-item-primary {
+ color: var(--list-group-item-primary-color, #8ca3ff);
+ background-color: var(--list-group-item-primary-bg, #1a2550);
+}
+
+.list-group-item-primary.list-group-item-action:active,
+.list-group-item-primary.list-group-item-action:focus {
+ color: var(--list-group-item-primary-color, #8ca3ff);
+ background-color: var(--list-group-item-primary-active-bg, #223066);
+}
+
+.list-group-item-primary.list-group-item-action.active {
+ color: var(--body-color, #e6ebf1);
+ background-color: var(--list-group-item-primary-color, #8ca3ff);
+ border-color: var(--list-group-item-primary-color, #8ca3ff);
+}
+
+.list-group-item-secondary {
+ color: var(--list-group-item-secondary-color, #9fa6ad);
+ background-color: var(--list-group-item-secondary-bg, #2b323b);
+}
+
+.list-group-item-secondary.list-group-item-action:active,
+.list-group-item-secondary.list-group-item-action:focus {
+ color: var(--list-group-item-secondary-color, #9fa6ad);
+ background-color: var(--list-group-item-secondary-active-bg, #363d47);
+}
+
+.list-group-item-secondary.list-group-item-action.active {
+ color: var(--body-color, #e6ebf1);
+ background-color: var(--list-group-item-secondary-color, #9fa6ad);
+ border-color: var(--list-group-item-secondary-color, #9fa6ad);
+}
+
+.list-group-item-success {
+ color: var(--list-group-item-success-color, #a0e5b3);
+ background-color: var(--list-group-item-success-bg, #1e3d2d);
+}
+
+.list-group-item-success.list-group-item-action:active,
+.list-group-item-success.list-group-item-action:focus {
+ color: var(--list-group-item-success-color, #a0e5b3);
+ background-color: var(--list-group-item-success-active-bg, #275538);
+}
+
+.list-group-item-success.list-group-item-action.active {
+ color: var(--body-color, #e6ebf1);
+ background-color: var(--list-group-item-success-color, #a0e5b3);
+ border-color: var(--list-group-item-success-color, #a0e5b3);
+}
+
+.list-group-item-info {
+ color: var(--list-group-item-info-color, #8eccf2);
+ background-color: var(--list-group-item-info-bg, #1a3448);
+}
+
+.list-group-item-info.list-group-item-action:active,
+.list-group-item-info.list-group-item-action:focus {
+ color: var(--list-group-item-info-color, #8eccf2);
+ background-color: var(--list-group-item-info-active-bg, #234459);
+}
+
+.list-group-item-info.list-group-item-action.active {
+ color: var(--body-color, #e6ebf1);
+ background-color: var(--list-group-item-info-color, #8eccf2);
+ border-color: var(--list-group-item-info-color, #8eccf2);
+}
+
+.list-group-item-warning {
+ color: var(--list-group-item-warning-color, #ffe4a0);
+ background-color: var(--list-group-item-warning-bg, #4a3410);
+}
+
+.list-group-item-warning.list-group-item-action:active,
+.list-group-item-warning.list-group-item-action:focus {
+ color: var(--list-group-item-warning-color, #ffe4a0);
+ background-color: var(--list-group-item-warning-active-bg, #5c4216);
+}
+
+.list-group-item-warning.list-group-item-action.active {
+ color: var(--body-color, #e6ebf1);
+ background-color: var(--list-group-item-warning-color, #ffe4a0);
+ border-color: var(--list-group-item-warning-color, #ffe4a0);
+}
+
+.list-group-item-danger {
+ color: var(--list-group-item-danger-color, #ffa8a3);
+ background-color: var(--list-group-item-danger-bg, #4a1e1c);
+}
+
+.list-group-item-danger.list-group-item-action:active,
+.list-group-item-danger.list-group-item-action:focus {
+ color: var(--list-group-item-danger-color, #ffa8a3);
+ background-color: var(--list-group-item-danger-active-bg, #5c2823);
+}
+
+.list-group-item-danger.list-group-item-action.active {
+ color: var(--body-color, #e6ebf1);
+ background-color: var(--list-group-item-danger-color, #ffa8a3);
+ border-color: var(--list-group-item-danger-color, #ffa8a3);
+}
+
+.list-group-item-light {
+ color: var(--list-group-item-light-color, #e9ecef);
+ background-color: var(--list-group-item-light-bg, #1e2430);
+}
+
+.list-group-item-light.list-group-item-action:active,
+.list-group-item-light.list-group-item-action:focus {
+ color: var(--list-group-item-light-color, #e9ecef);
+ background-color: var(--list-group-item-light-active-bg, #282f3d);
+}
+
+.list-group-item-light.list-group-item-action.active {
+ color: var(--body-color, #e6ebf1);
+ background-color: var(--list-group-item-light-color, #e9ecef);
+ border-color: var(--list-group-item-light-color, #e9ecef);
+}
+
+.list-group-item-dark {
+ color: var(--list-group-item-dark-color, #48525d);
+ background-color: var(--list-group-item-dark-bg, #0e1318);
+}
+
+.list-group-item-dark.list-group-item-action:active,
+.list-group-item-dark.list-group-item-action:focus {
+ color: var(--list-group-item-dark-color, #48525d);
+ background-color: var(--list-group-item-dark-active-bg, #161b22);
+}
+
+.list-group-item-dark.list-group-item-action.active {
+ color: var(--body-color, #e6ebf1);
+ background-color: var(--list-group-item-dark-color, #48525d);
+ border-color: var(--list-group-item-dark-color, #48525d);
+}
+
+.btn-close {
+ -webkit-box-sizing: content-box;
+ box-sizing: content-box;
+ width: 1em;
+ height: 1em;
+ padding: 0.25em 0.25em;
+ color: var(--body-color, #e6ebf1);
+ background: transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='hsl%280, 0%, 0%%29'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;
+ border: 0;
+ border-radius: 0.25rem;
+ opacity: 0.5;
+}
+
+.btn-close:active {
+ text-decoration: none;
+ opacity: 0.75;
+}
+
+.btn-close:focus {
+ outline: 0;
+ -webkit-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+ box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+ opacity: 1;
+}
+
+.btn-close:disabled,
+.btn-close.disabled {
+ pointer-events: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ opacity: 0.25;
+}
+
+.btn-close-white {
+ -webkit-filter: invert(1) grayscale(100%) brightness(200%);
+ filter: invert(1) grayscale(100%) brightness(200%);
+}
+
+.toast {
+ /* Values defined in light.standard.css / dark.standard.css */
+ width: var(--toast-max-width, 350px);
+ max-width: 100%;
+ font-size: var(--toast-font-size, 0.875rem);
+ color: var(--toast-color, );
+ pointer-events: auto;
+ background-color: var(--toast-bg, rgba(21, 27, 34, 0.9));
+ background-clip: padding-box;
+ border: var(--toast-border-width, 1px) solid var(--toast-border-color);
+ -webkit-box-shadow: var(--toast-box-shadow, 0 0.5rem 1rem var(--shadow-color-medium));
+ box-shadow: var(--toast-box-shadow, 0 0.5rem 1rem var(--shadow-color-medium));
+ border-radius: var(--toast-border-radius, 0.25rem);
+}
+
+.toast.showing {
+ opacity: 0;
+}
+
+.toast:not(.show) {
+ display: none;
+}
+
+.toast-container {
+ --toast-zindex: 1090;
+ position: absolute;
+ z-index: var(--toast-zindex, 1090);
+ width: -webkit-max-content;
+ width: -moz-max-content;
+ width: max-content;
+ max-width: 100%;
+ pointer-events: none;
+}
+
+.toast-container> :not(:last-child) {
+ margin-bottom: var(--toast-spacing, 1em);
+}
+
+.toast-header {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ padding: var(--toast-padding-y, 0.5rem) var(--toast-padding-x, 0.75rem);
+ color: var(--toast-header-color);
+ background-color: var(--toast-header-bg, rgba(21, 27, 34, 0.85));
+ background-clip: padding-box;
+ border-bottom: var(--toast-border-width, 1px) solid var(--toast-header-border-color, rgba(var(--white-rgb), var(--opacity-10)));
+ border-top-left-radius: calc(var(--toast-border-radius, 0.25rem) - var(--toast-border-width, 1px));
+ border-top-right-radius: calc(var(--toast-border-radius, 0.25rem) - var(--toast-border-width, 1px));
+}
+
+.toast-header .btn-close {
+ margin-right: calc(-0.5 * var(--toast-padding-x, 0.75rem));
+ margin-left: var(--toast-padding-x, 0.75rem);
+}
+
+.toast-body {
+ padding: var(--toast-padding-x, 0.75rem);
+ word-wrap: break-word;
+}
+
+.modal {
+ /* Values defined in light.standard.css / dark.standard.css */
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: var(--modal-zindex, 1050);
+ display: none;
+ width: 100%;
+ height: 100%;
+ overflow-x: hidden;
+ overflow-y: auto;
+ outline: 0;
+}
+
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: var(--modal-margin, 0.5rem);
+ pointer-events: none;
+}
+
+.modal.fade .modal-dialog {
+ -webkit-transition: -webkit-transform 0.3s ease-out;
+ transition: -webkit-transform 0.3s ease-out;
+ -o-transition: transform 0.3s ease-out;
+ transition: transform 0.3s ease-out;
+ transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out;
+ -webkit-transform: translate(0, -50px);
+ transform: translate(0, -50px);
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .modal.fade .modal-dialog {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.modal.show .modal-dialog {
+ -webkit-transform: none;
+ transform: none;
+}
+
+.modal.modal-static .modal-dialog {
+ -webkit-transform: scale(1.02);
+ transform: scale(1.02);
+}
+
+.modal-dialog-scrollable {
+ height: calc(100% - var(--modal-margin, 0.5rem) * 2);
+}
+
+.modal-dialog-scrollable .modal-content {
+ max-height: 100%;
+ overflow: hidden;
+}
+
+.modal-dialog-scrollable .modal-body {
+ overflow-y: auto;
+}
+
+.modal-dialog-centered {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ min-height: calc(100% - var(--modal-margin, 0.5rem) * 2);
+}
+
+.modal-content {
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ width: 100%;
+ color: var(--modal-color, );
+ pointer-events: auto;
+ background-color: var(--modal-bg);
+ background-clip: padding-box;
+ border: var(--modal-border-width, 1px) solid var(--modal-border-color);
+ border-radius: var(--modal-border-radius, 0.3rem);
+ outline: 0;
+}
+
+.modal-backdrop {
+ /* Values defined in light.standard.css / dark.standard.css */
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: var(--backdrop-zindex, 1040);
+ width: 100vw;
+ height: 100vh;
+ background-color: var(--backdrop-bg, hsl(0, 0%, 0%));
+}
+
+.modal-backdrop.fade {
+ opacity: 0;
+}
+
+.modal-backdrop.show {
+ opacity: var(--backdrop-opacity, 0.5);
+}
+
+.modal-header {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ padding: var(--modal-header-padding, 1rem 1rem);
+ border-bottom: var(--modal-header-border-width, 1px) solid var(--modal-header-border-color);
+ border-top-left-radius: var(--modal-inner-border-radius, calc(0.3rem - 1px));
+ border-top-right-radius: var(--modal-inner-border-radius, calc(0.3rem - 1px));
+}
+
+.modal-header .btn-close {
+ padding: calc(var(--modal-header-padding-y, 1rem) * 0.5) calc(var(--modal-header-padding-x, 1rem) * 0.5);
+ margin: calc(-0.5 * var(--modal-header-padding-y, 1rem)) calc(-0.5 * var(--modal-header-padding-x, 1rem)) calc(-0.5 * var(--modal-header-padding-y, 1rem)) auto;
+}
+
+.modal-title {
+ margin-bottom: 0;
+ line-height: var(--modal-title-line-height, 1.5);
+}
+
+.modal-body {
+ position: relative;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+ padding: var(--modal-padding, 1rem);
+}
+
+.modal-footer {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: end;
+ -ms-flex-pack: end;
+ justify-content: flex-end;
+ padding: calc(var(--modal-padding, 1rem) - var(--modal-footer-gap, 0.5rem) * 0.5);
+ background-color: var(--modal-footer-bg, );
+ border-top: var(--modal-footer-border-width, 1px) solid var(--modal-footer-border-color);
+ border-bottom-right-radius: var(--modal-inner-border-radius, calc(0.3rem - 1px));
+ border-bottom-left-radius: var(--modal-inner-border-radius, calc(0.3rem - 1px));
+}
+
+.modal-footer>* {
+ margin: calc(var(--modal-footer-gap, 0.5rem) * 0.5);
+}
+
+@media (min-width: 576px) {
+ .modal {
+ --modal-margin: 1.75rem;
+ --modal-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
+ }
+
+ .modal-dialog {
+ max-width: var(--modal-width, 500px);
+ margin-right: auto;
+ margin-left: auto;
+ }
+
+ .modal-sm {
+ --modal-width: 300px;
+ }
+}
+
+@media (min-width: 992px) {
+
+ .modal-lg,
+ .modal-xl {
+ --modal-width: 800px;
+ }
+}
+
+@media (min-width: 1200px) {
+ .modal-xl {
+ --modal-width: 1140px;
+ }
+}
+
+.modal-fullscreen {
+ width: 100vw;
+ max-width: none;
+ height: 100%;
+ margin: 0;
+}
+
+.modal-fullscreen .modal-content {
+ height: 100%;
+ border: 0;
+ border-radius: 0;
+}
+
+.modal-fullscreen .modal-header,
+.modal-fullscreen .modal-footer {
+ border-radius: 0;
+}
+
+.modal-fullscreen .modal-body {
+ overflow-y: auto;
+}
+
+@media (max-width: 575.98px) {
+ .modal-fullscreen-sm-down {
+ width: 100vw;
+ max-width: none;
+ height: 100%;
+ margin: 0;
+ }
+
+ .modal-fullscreen-sm-down .modal-content {
+ height: 100%;
+ border: 0;
+ border-radius: 0;
+ }
+
+ .modal-fullscreen-sm-down .modal-header,
+ .modal-fullscreen-sm-down .modal-footer {
+ border-radius: 0;
+ }
+
+ .modal-fullscreen-sm-down .modal-body {
+ overflow-y: auto;
+ }
+}
+
+@media (max-width: 767.98px) {
+ .modal-fullscreen-md-down {
+ width: 100vw;
+ max-width: none;
+ height: 100%;
+ margin: 0;
+ }
+
+ .modal-fullscreen-md-down .modal-content {
+ height: 100%;
+ border: 0;
+ border-radius: 0;
+ }
+
+ .modal-fullscreen-md-down .modal-header,
+ .modal-fullscreen-md-down .modal-footer {
+ border-radius: 0;
+ }
+
+ .modal-fullscreen-md-down .modal-body {
+ overflow-y: auto;
+ }
+}
+
+@media (max-width: 991.98px) {
+ .modal-fullscreen-lg-down {
+ width: 100vw;
+ max-width: none;
+ height: 100%;
+ margin: 0;
+ }
+
+ .modal-fullscreen-lg-down .modal-content {
+ height: 100%;
+ border: 0;
+ border-radius: 0;
+ }
+
+ .modal-fullscreen-lg-down .modal-header,
+ .modal-fullscreen-lg-down .modal-footer {
+ border-radius: 0;
+ }
+
+ .modal-fullscreen-lg-down .modal-body {
+ overflow-y: auto;
+ }
+}
+
+@media (max-width: 1199.98px) {
+ .modal-fullscreen-xl-down {
+ width: 100vw;
+ max-width: none;
+ height: 100%;
+ margin: 0;
+ }
+
+ .modal-fullscreen-xl-down .modal-content {
+ height: 100%;
+ border: 0;
+ border-radius: 0;
+ }
+
+ .modal-fullscreen-xl-down .modal-header,
+ .modal-fullscreen-xl-down .modal-footer {
+ border-radius: 0;
+ }
+
+ .modal-fullscreen-xl-down .modal-body {
+ overflow-y: auto;
+ }
+}
+
+@media (max-width: 1399.98px) {
+ .modal-fullscreen-xxl-down {
+ width: 100vw;
+ max-width: none;
+ height: 100%;
+ margin: 0;
+ }
+
+ .modal-fullscreen-xxl-down .modal-content {
+ height: 100%;
+ border: 0;
+ border-radius: 0;
+ }
+
+ .modal-fullscreen-xxl-down .modal-header,
+ .modal-fullscreen-xxl-down .modal-footer {
+ border-radius: 0;
+ }
+
+ .modal-fullscreen-xxl-down .modal-body {
+ overflow-y: auto;
+ }
+}
+
+.tooltip {
+ /* Values defined in light.standard.css / dark.standard.css */
+ z-index: var(--tooltip-zindex, 1070);
+ display: block;
+ padding: var(--tooltip-arrow-height, 0.4rem);
+ margin: var(--tooltip-margin, );
+ font-family: v-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ font-style: normal;
+ font-weight: 400;
+ line-height: 1.5;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ white-space: normal;
+ word-spacing: normal;
+ line-break: auto;
+ font-size: var(--tooltip-font-size, 0.875rem);
+ word-wrap: break-word;
+ opacity: 0;
+}
+
+.tooltip.show {
+ opacity: var(--tooltip-opacity, 0.9);
+}
+
+.tooltip .tooltip-arrow {
+ display: block;
+ width: var(--tooltip-arrow-width, 0.8rem);
+ height: var(--tooltip-arrow-height, 0.4rem);
+}
+
+.tooltip .tooltip-arrow::before {
+ position: absolute;
+ content: "";
+ border-color: transparent;
+ border-style: solid;
+}
+
+.bs-tooltip-top .tooltip-arrow,
+.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow {
+ bottom: 0;
+}
+
+.bs-tooltip-top .tooltip-arrow::before,
+.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before {
+ top: -1px;
+ border-width: var(--tooltip-arrow-height, 0.4rem) calc(var(--tooltip-arrow-width, 0.8rem) * 0.5) 0;
+ border-top-color: var(--tooltip-bg, hsl(0, 0%, 0%));
+}
+
+/* rtl:begin:ignore */
+.bs-tooltip-end .tooltip-arrow,
+.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow {
+ left: 0;
+ width: var(--tooltip-arrow-height, 0.4rem);
+ height: var(--tooltip-arrow-width, 0.8rem);
+}
+
+.bs-tooltip-end .tooltip-arrow::before,
+.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before {
+ right: -1px;
+ border-width: calc(var(--tooltip-arrow-width, 0.8rem) * 0.5) var(--tooltip-arrow-height, 0.4rem) calc(var(--tooltip-arrow-width, 0.8rem) * 0.5) 0;
+ border-right-color: var(--tooltip-bg, hsl(0, 0%, 0%));
+}
+
+/* rtl:end:ignore */
+.bs-tooltip-bottom .tooltip-arrow,
+.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow {
+ top: 0;
+}
+
+.bs-tooltip-bottom .tooltip-arrow::before,
+.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before {
+ bottom: -1px;
+ border-width: 0 calc(var(--tooltip-arrow-width, 0.8rem) * 0.5) var(--tooltip-arrow-height, 0.4rem);
+ border-bottom-color: var(--tooltip-bg, hsl(0, 0%, 0%));
+}
+
+/* rtl:begin:ignore */
+.bs-tooltip-start .tooltip-arrow,
+.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow {
+ right: 0;
+ width: var(--tooltip-arrow-height, 0.4rem);
+ height: var(--tooltip-arrow-width, 0.8rem);
+}
+
+.bs-tooltip-start .tooltip-arrow::before,
+.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before {
+ left: -1px;
+ border-width: calc(var(--tooltip-arrow-width, 0.8rem) * 0.5) 0 calc(var(--tooltip-arrow-width, 0.8rem) * 0.5) var(--tooltip-arrow-height, 0.4rem);
+ border-left-color: var(--tooltip-bg, hsl(0, 0%, 0%));
+}
+
+/* rtl:end:ignore */
+.tooltip-inner {
+ max-width: var(--tooltip-max-width, 200px);
+ padding: var(--tooltip-padding-y, 0.25rem) var(--tooltip-padding-x, 0.5rem);
+ color: var(--tooltip-color);
+ text-align: center;
+ background-color: var(--tooltip-bg, hsl(0, 0%, 0%));
+ border-radius: var(--tooltip-border-radius, 0.25rem);
+}
+
+.popover {
+ /* Values defined in light.standard.css / dark.standard.css */
+ z-index: var(--popover-zindex, 1060);
+ display: block;
+ max-width: var(--popover-max-width, 276px);
+ font-family: var(--font-family-body, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");
+ font-style: normal;
+ font-weight: 400;
+ line-height: 1.5;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ white-space: normal;
+ word-spacing: normal;
+ line-break: auto;
+ font-size: var(--popover-font-size, 0.875rem);
+ word-wrap: break-word;
+ background-color: var(--popover-bg);
+ background-clip: padding-box;
+ border: var(--popover-border-width, 1px) solid var(--popover-border-color);
+ border-radius: var(--popover-border-radius, 0.3rem);
+}
+
+.popover .popover-arrow {
+ display: block;
+ width: var(--popover-arrow-width, 1rem);
+ height: var(--popover-arrow-height, 0.5rem);
+}
+
+.popover .popover-arrow::before,
+.popover .popover-arrow::after {
+ position: absolute;
+ display: block;
+ content: "";
+ border-color: transparent;
+ border-style: solid;
+ border-width: 0;
+}
+
+.bs-popover-top>.popover-arrow,
+.bs-popover-auto[data-popper-placement^=top]>.popover-arrow {
+ bottom: calc(-1 * (var(--popover-arrow-height, 0.5rem)) - var(--popover-border-width, 1px));
+}
+
+.bs-popover-top>.popover-arrow::before,
+.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,
+.bs-popover-top>.popover-arrow::after,
+.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after {
+ border-width: var(--popover-arrow-height, 0.5rem) calc(var(--popover-arrow-width, 1rem) * 0.5) 0;
+}
+
+.bs-popover-top>.popover-arrow::before,
+.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before {
+ bottom: 0;
+ border-top-color: var(--popover-arrow-border);
+}
+
+.bs-popover-top>.popover-arrow::after,
+.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after {
+ bottom: var(--popover-border-width, 1px);
+ border-top-color: var(--popover-bg);
+}
+
+/* rtl:begin:ignore */
+.bs-popover-end>.popover-arrow,
+.bs-popover-auto[data-popper-placement^=right]>.popover-arrow {
+ left: calc(-1 * (var(--popover-arrow-height, 0.5rem)) - var(--popover-border-width, 1px));
+ width: var(--popover-arrow-height, 0.5rem);
+ height: var(--popover-arrow-width, 1rem);
+}
+
+.bs-popover-end>.popover-arrow::before,
+.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,
+.bs-popover-end>.popover-arrow::after,
+.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after {
+ border-width: calc(var(--popover-arrow-width, 1rem) * 0.5) var(--popover-arrow-height, 0.5rem) calc(var(--popover-arrow-width, 1rem) * 0.5) 0;
+}
+
+.bs-popover-end>.popover-arrow::before,
+.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before {
+ left: 0;
+ border-right-color: var(--popover-arrow-border);
+}
+
+.bs-popover-end>.popover-arrow::after,
+.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after {
+ left: var(--popover-border-width, 1px);
+ border-right-color: var(--popover-bg);
+}
+
+/* rtl:end:ignore */
+.bs-popover-bottom>.popover-arrow,
+.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow {
+ top: calc(-1 * (var(--popover-arrow-height, 0.5rem)) - var(--popover-border-width, 1px));
+}
+
+.bs-popover-bottom>.popover-arrow::before,
+.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,
+.bs-popover-bottom>.popover-arrow::after,
+.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after {
+ border-width: 0 calc(var(--popover-arrow-width, 1rem) * 0.5) var(--popover-arrow-height, 0.5rem);
+}
+
+.bs-popover-bottom>.popover-arrow::before,
+.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before {
+ top: 0;
+ border-bottom-color: var(--popover-arrow-border);
+}
+
+.bs-popover-bottom>.popover-arrow::after,
+.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after {
+ top: var(--popover-border-width, 1px);
+ border-bottom-color: var(--popover-bg);
+}
+
+.bs-popover-bottom .popover-header::before,
+.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before {
+ position: absolute;
+ top: 0;
+ left: 50%;
+ display: block;
+ width: var(--popover-arrow-width, 1rem);
+ margin-left: calc(-0.5 * var(--popover-arrow-width, 1rem));
+ content: "";
+ border-bottom: var(--popover-border-width, 1px) solid var(--popover-header-bg);
+}
+
+/* rtl:begin:ignore */
+.bs-popover-start>.popover-arrow,
+.bs-popover-auto[data-popper-placement^=left]>.popover-arrow {
+ right: calc(-1 * (var(--popover-arrow-height, 0.5rem)) - var(--popover-border-width, 1px));
+ width: var(--popover-arrow-height, 0.5rem);
+ height: var(--popover-arrow-width, 1rem);
+}
+
+.bs-popover-start>.popover-arrow::before,
+.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,
+.bs-popover-start>.popover-arrow::after,
+.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after {
+ border-width: calc(var(--popover-arrow-width, 1rem) * 0.5) 0 calc(var(--popover-arrow-width, 1rem) * 0.5) var(--popover-arrow-height, 0.5rem);
+}
+
+.bs-popover-start>.popover-arrow::before,
+.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before {
+ right: 0;
+ border-left-color: var(--popover-arrow-border);
+}
+
+.bs-popover-start>.popover-arrow::after,
+.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after {
+ right: var(--popover-border-width, 1px);
+ border-left-color: var(--popover-bg);
+}
+
+/* rtl:end:ignore */
+.popover-header {
+ padding: var(--popover-header-padding-y, 0.5rem) var(--popover-header-padding-x, 1rem);
+ margin-bottom: 0;
+ font-size: var(--popover-header-font-size, 1rem);
+ color: var(--popover-header-color, );
+ background-color: var(--popover-header-bg);
+ border-bottom: var(--popover-border-width, 1px) solid var(--popover-border-color);
+ border-top-left-radius: var(--popover-inner-border-radius, calc(0.3rem - 1px));
+ border-top-right-radius: var(--popover-inner-border-radius, calc(0.3rem - 1px));
+}
+
+.popover-header:empty {
+ display: none;
+}
+
+.popover-body {
+ padding: var(--popover-body-padding-y, 1rem) var(--popover-body-padding-x, 1rem);
+ color: var(--popover-body-color);
+}
+
+.carousel {
+ position: relative;
+}
+
+.carousel.pointer-event {
+ -ms-touch-action: pan-y;
+ touch-action: pan-y;
+}
+
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+}
+
+.carousel-inner::after {
+ display: block;
+ clear: both;
+ content: "";
+}
+
+.carousel-item {
+ position: relative;
+ display: none;
+ float: left;
+ width: 100%;
+ margin-right: -100%;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ -webkit-transition: -webkit-transform 0.6s ease-in-out;
+ transition: -webkit-transform 0.6s ease-in-out;
+ -o-transition: transform 0.6s ease-in-out;
+ transition: transform 0.6s ease-in-out;
+ transition: transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .carousel-item {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.carousel-item.active,
+.carousel-item-next,
+.carousel-item-prev {
+ display: block;
+}
+
+.carousel-item-next:not(.carousel-item-start),
+.active.carousel-item-end {
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+}
+
+.carousel-item-prev:not(.carousel-item-end),
+.active.carousel-item-start {
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+}
+
+.carousel-fade .carousel-item {
+ opacity: 0;
+ -webkit-transition-property: opacity;
+ -o-transition-property: opacity;
+ transition-property: opacity;
+ -webkit-transform: none;
+ transform: none;
+}
+
+.carousel-fade .carousel-item.active,
+.carousel-fade .carousel-item-next.carousel-item-start,
+.carousel-fade .carousel-item-prev.carousel-item-end {
+ z-index: 1;
+ opacity: 1;
+}
+
+.carousel-fade .active.carousel-item-start,
+.carousel-fade .active.carousel-item-end {
+ z-index: 0;
+ opacity: 0;
+ -webkit-transition: opacity 0s 0.6s;
+ -o-transition: opacity 0s 0.6s;
+ transition: opacity 0s 0.6s;
+}
+
+@media (prefers-reduced-motion: reduce) {
+
+ .carousel-fade .active.carousel-item-start,
+ .carousel-fade .active.carousel-item-end {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.carousel-control-prev,
+.carousel-control-next {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ z-index: 1;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ width: 15%;
+ padding: 0;
+ color: var(--body-color, #e6ebf1);
+ text-align: center;
+ background: none;
+ border: 0;
+ opacity: 0.5;
+ -webkit-transition: opacity 0.15s ease;
+ -o-transition: opacity 0.15s ease;
+ transition: opacity 0.15s ease;
+}
+
+@media (prefers-reduced-motion: reduce) {
+
+ .carousel-control-prev,
+ .carousel-control-next {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.carousel-control-prev:active,
+.carousel-control-prev:focus,
+.carousel-control-next:active,
+.carousel-control-next:focus {
+ color: var(--body-color, #e6ebf1);
+ text-decoration: none;
+ outline: 0;
+ opacity: 0.9;
+}
+
+.carousel-control-prev {
+ left: 0;
+}
+
+.carousel-control-next {
+ right: 0;
+}
+
+.carousel-control-prev-icon,
+.carousel-control-next-icon {
+ display: inline-block;
+ width: 2rem;
+ height: 2rem;
+ background-repeat: no-repeat;
+ background-position: 50%;
+ background-size: 100% 100%;
+}
+
+/* rtl:options: {
+ "autoRename": true,
+ "stringMap":[ {
+ "name" : "prev-next",
+ "search" : "prev",
+ "replace" : "next"
+ } ]
+} */
+.carousel-control-prev-icon {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='hsl%280, 0%, 100%%29'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e");
+}
+
+.carousel-control-next-icon {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='hsl%280, 0%, 100%%29'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+}
+
+.carousel-indicators {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 2;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ padding: 0;
+ margin-right: 15%;
+ margin-bottom: 1rem;
+ margin-left: 15%;
+ list-style: none;
+}
+
+.carousel-indicators [data-bs-target] {
+ -webkit-box-sizing: content-box;
+ box-sizing: content-box;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 1 auto;
+ flex: 0 1 auto;
+ width: 30px;
+ height: 3px;
+ padding: 0;
+ margin-right: 0.1875rem;
+ margin-left: 0.1875rem;
+ text-indent: -999px;
+ cursor: pointer;
+ background-color: var(--body-color, #e6ebf1);
+ background-clip: padding-box;
+ border: 0;
+ border-top: 10px solid transparent;
+ border-bottom: 10px solid transparent;
+ opacity: 0.5;
+ -webkit-transition: opacity 0.6s ease;
+ -o-transition: opacity 0.6s ease;
+ transition: opacity 0.6s ease;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .carousel-indicators [data-bs-target] {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.carousel-indicators .active {
+ opacity: 1;
+}
+
+.carousel-caption {
+ position: absolute;
+ right: 15%;
+ bottom: 1.25rem;
+ left: 15%;
+ padding-top: 1.25rem;
+ padding-bottom: 1.25rem;
+ color: var(--body-color, #e6ebf1);
+ text-align: center;
+}
+
+.carousel-dark .carousel-control-prev-icon,
+.carousel-dark .carousel-control-next-icon {
+ -webkit-filter: invert(1) grayscale(100);
+ filter: invert(1) grayscale(100);
+}
+
+.carousel-dark .carousel-indicators [data-bs-target] {
+ background-color: hsl(0, 0%, 0%);
+}
+
+.carousel-dark .carousel-caption {
+ color: hsl(0, 0%, 0%);
+}
+
+.spinner-grow,
+.spinner-border {
+ display: inline-block;
+ width: var(--spinner-width, 2rem);
+ height: var(--spinner-height, 2rem);
+ vertical-align: var(--spinner-vertical-align, -0.125em);
+ border-radius: 50%;
+ -webkit-animation: var(--spinner-animation-speed, 0.75s) linear infinite var(--spinner-animation-name);
+ animation: var(--spinner-animation-speed, 0.75s) linear infinite var(--spinner-animation-name);
+}
+
+@-webkit-keyframes spinner-border {
+ to {
+ -webkit-transform: rotate(360deg)
+ /* rtl:ignore */
+ ;
+ transform: rotate(360deg)
+ /* rtl:ignore */
+ ;
+ }
+}
+
+@keyframes spinner-border {
+ to {
+ -webkit-transform: rotate(360deg)
+ /* rtl:ignore */
+ ;
+ transform: rotate(360deg)
+ /* rtl:ignore */
+ ;
+ }
+}
+
+.spinner-border {
+ /* Values defined in light.standard.css / dark.standard.css */
+ --spinner-animation-name: spinner-border;
+ border: var(--spinner-border-width, 0.25em) solid currentcolor;
+ border-right-color: transparent;
+}
+
+.spinner-border-sm {
+ --spinner-width: 1rem;
+ --spinner-height: 1rem;
+ --spinner-border-width: 0.2em;
+}
+
+@-webkit-keyframes spinner-grow {
+ 0% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ }
+
+ 50% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@keyframes spinner-grow {
+ 0% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ }
+
+ 50% {
+ opacity: 1;
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+.spinner-grow {
+ /* Values defined in light.standard.css / dark.standard.css */
+ --spinner-animation-name: spinner-grow;
+ background-color: currentcolor;
+ opacity: 0;
+}
+
+.spinner-grow-sm {
+ --spinner-width: 1rem;
+ --spinner-height: 1rem;
+}
+
+@media (prefers-reduced-motion: reduce) {
+
+ .spinner-border,
+ .spinner-grow {
+ --spinner-animation-speed: 1.5s;
+ }
+}
+
+.offcanvas,
+.offcanvas-xxl,
+.offcanvas-xl,
+.offcanvas-lg,
+.offcanvas-md,
+.offcanvas-sm {
+ /* Values defined in light.standard.css / dark.standard.css under :root */
+}
+
+@media (max-width: 575.98px) {
+ .offcanvas-sm {
+ position: fixed;
+ bottom: 0;
+ z-index: var(--offcanvas-zindex, 1045);
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ max-width: 100%;
+ color: var(--offcanvas-color);
+ visibility: hidden;
+ background-color: var(--offcanvas-bg);
+ background-clip: padding-box;
+ outline: 0;
+ -webkit-transition: -webkit-transform 0.3s ease-in-out;
+ transition: -webkit-transform 0.3s ease-in-out;
+ -o-transition: transform 0.3s ease-in-out;
+ transition: transform 0.3s ease-in-out;
+ transition: transform 0.3s ease-in-out, -webkit-transform 0.3s ease-in-out;
+ }
+}
+
+@media (max-width: 575.98px) and (prefers-reduced-motion: reduce) {
+ .offcanvas-sm {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+@media (max-width: 575.98px) {
+ .offcanvas-sm.offcanvas-start {
+ top: 0;
+ left: 0;
+ width: var(--offcanvas-width, 400px);
+ border-right: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+ }
+}
+
+@media (max-width: 575.98px) {
+ .offcanvas-sm.offcanvas-end {
+ top: 0;
+ right: 0;
+ width: var(--offcanvas-width, 400px);
+ border-left: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+ }
+}
+
+@media (max-width: 575.98px) {
+ .offcanvas-sm.offcanvas-top {
+ top: 0;
+ right: 0;
+ left: 0;
+ height: var(--offcanvas-height, 30vh);
+ max-height: 100%;
+ border-bottom: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ }
+}
+
+@media (max-width: 575.98px) {
+ .offcanvas-sm.offcanvas-bottom {
+ right: 0;
+ left: 0;
+ height: var(--offcanvas-height, 30vh);
+ max-height: 100%;
+ border-top: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+ }
+}
+
+@media (max-width: 575.98px) {
+
+ .offcanvas-sm.showing,
+ .offcanvas-sm.show:not(.hiding) {
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@media (max-width: 575.98px) {
+
+ .offcanvas-sm.showing,
+ .offcanvas-sm.hiding,
+ .offcanvas-sm.show {
+ visibility: visible;
+ }
+}
+
+@media (min-width: 576px) {
+ .offcanvas-sm {
+ --offcanvas-height: auto;
+ --offcanvas-border-width: 0;
+ background-color: transparent ;
+ }
+
+ .offcanvas-sm .offcanvas-header {
+ display: none;
+ }
+
+ .offcanvas-sm .offcanvas-body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 0;
+ -ms-flex-positive: 0;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ background-color: transparent ;
+ }
+}
+
+@media (max-width: 767.98px) {
+ .offcanvas-md {
+ position: fixed;
+ bottom: 0;
+ z-index: var(--offcanvas-zindex, 1045);
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ max-width: 100%;
+ color: var(--offcanvas-color);
+ visibility: hidden;
+ background-color: var(--offcanvas-bg);
+ background-clip: padding-box;
+ outline: 0;
+ -webkit-transition: -webkit-transform 0.3s ease-in-out;
+ transition: -webkit-transform 0.3s ease-in-out;
+ -o-transition: transform 0.3s ease-in-out;
+ transition: transform 0.3s ease-in-out;
+ transition: transform 0.3s ease-in-out, -webkit-transform 0.3s ease-in-out;
+ }
+}
+
+@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) {
+ .offcanvas-md {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+@media (max-width: 767.98px) {
+ .offcanvas-md.offcanvas-start {
+ top: 0;
+ left: 0;
+ width: var(--offcanvas-width, 400px);
+ border-right: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+ }
+}
+
+@media (max-width: 767.98px) {
+ .offcanvas-md.offcanvas-end {
+ top: 0;
+ right: 0;
+ width: var(--offcanvas-width, 400px);
+ border-left: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+ }
+}
+
+@media (max-width: 767.98px) {
+ .offcanvas-md.offcanvas-top {
+ top: 0;
+ right: 0;
+ left: 0;
+ height: var(--offcanvas-height, 30vh);
+ max-height: 100%;
+ border-bottom: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ }
+}
+
+@media (max-width: 767.98px) {
+ .offcanvas-md.offcanvas-bottom {
+ right: 0;
+ left: 0;
+ height: var(--offcanvas-height, 30vh);
+ max-height: 100%;
+ border-top: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+ }
+}
+
+@media (max-width: 767.98px) {
+
+ .offcanvas-md.showing,
+ .offcanvas-md.show:not(.hiding) {
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@media (max-width: 767.98px) {
+
+ .offcanvas-md.showing,
+ .offcanvas-md.hiding,
+ .offcanvas-md.show {
+ visibility: visible;
+ }
+}
+
+@media (min-width: 768px) {
+ .offcanvas-md {
+ --offcanvas-height: auto;
+ --offcanvas-border-width: 0;
+ background-color: transparent ;
+ }
+
+ .offcanvas-md .offcanvas-header {
+ display: none;
+ }
+
+ .offcanvas-md .offcanvas-body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 0;
+ -ms-flex-positive: 0;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ background-color: transparent ;
+ }
+}
+
+@media (max-width: 991.98px) {
+ .offcanvas-lg {
+ position: fixed;
+ bottom: 0;
+ z-index: var(--offcanvas-zindex, 1045);
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ max-width: 100%;
+ color: var(--offcanvas-color);
+ visibility: hidden;
+ background-color: var(--offcanvas-bg);
+ background-clip: padding-box;
+ outline: 0;
+ -webkit-transition: -webkit-transform 0.3s ease-in-out;
+ transition: -webkit-transform 0.3s ease-in-out;
+ -o-transition: transform 0.3s ease-in-out;
+ transition: transform 0.3s ease-in-out;
+ transition: transform 0.3s ease-in-out, -webkit-transform 0.3s ease-in-out;
+ }
+}
+
+@media (max-width: 991.98px) and (prefers-reduced-motion: reduce) {
+ .offcanvas-lg {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+@media (max-width: 991.98px) {
+ .offcanvas-lg.offcanvas-start {
+ top: 0;
+ left: 0;
+ width: var(--offcanvas-width, 400px);
+ border-right: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+ }
+}
+
+@media (max-width: 991.98px) {
+ .offcanvas-lg.offcanvas-end {
+ top: 0;
+ right: 0;
+ width: var(--offcanvas-width, 400px);
+ border-left: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+ }
+}
+
+@media (max-width: 991.98px) {
+ .offcanvas-lg.offcanvas-top {
+ top: 0;
+ right: 0;
+ left: 0;
+ height: var(--offcanvas-height, 30vh);
+ max-height: 100%;
+ border-bottom: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ }
+}
+
+@media (max-width: 991.98px) {
+ .offcanvas-lg.offcanvas-bottom {
+ right: 0;
+ left: 0;
+ height: var(--offcanvas-height, 30vh);
+ max-height: 100%;
+ border-top: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+ }
+}
+
+@media (max-width: 991.98px) {
+
+ .offcanvas-lg.showing,
+ .offcanvas-lg.show:not(.hiding) {
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@media (max-width: 991.98px) {
+
+ .offcanvas-lg.showing,
+ .offcanvas-lg.hiding,
+ .offcanvas-lg.show {
+ visibility: visible;
+ }
+}
+
+@media (min-width: 992px) {
+ .offcanvas-lg {
+ --offcanvas-height: auto;
+ --offcanvas-border-width: 0;
+ background-color: transparent ;
+ }
+
+ .offcanvas-lg .offcanvas-header {
+ display: none;
+ }
+
+ .offcanvas-lg .offcanvas-body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 0;
+ -ms-flex-positive: 0;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ background-color: transparent ;
+ }
+}
+
+@media (max-width: 1199.98px) {
+ .offcanvas-xl {
+ position: fixed;
+ bottom: 0;
+ z-index: var(--offcanvas-zindex, 1045);
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ max-width: 100%;
+ color: var(--offcanvas-color);
+ visibility: hidden;
+ background-color: var(--offcanvas-bg);
+ background-clip: padding-box;
+ outline: 0;
+ -webkit-transition: -webkit-transform 0.3s ease-in-out;
+ transition: -webkit-transform 0.3s ease-in-out;
+ -o-transition: transform 0.3s ease-in-out;
+ transition: transform 0.3s ease-in-out;
+ transition: transform 0.3s ease-in-out, -webkit-transform 0.3s ease-in-out;
+ }
+}
+
+@media (max-width: 1199.98px) and (prefers-reduced-motion: reduce) {
+ .offcanvas-xl {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+@media (max-width: 1199.98px) {
+ .offcanvas-xl.offcanvas-start {
+ top: 0;
+ left: 0;
+ width: var(--offcanvas-width, 400px);
+ border-right: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+ }
+}
+
+@media (max-width: 1199.98px) {
+ .offcanvas-xl.offcanvas-end {
+ top: 0;
+ right: 0;
+ width: var(--offcanvas-width, 400px);
+ border-left: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+ }
+}
+
+@media (max-width: 1199.98px) {
+ .offcanvas-xl.offcanvas-top {
+ top: 0;
+ right: 0;
+ left: 0;
+ height: var(--offcanvas-height, 30vh);
+ max-height: 100%;
+ border-bottom: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ }
+}
+
+@media (max-width: 1199.98px) {
+ .offcanvas-xl.offcanvas-bottom {
+ right: 0;
+ left: 0;
+ height: var(--offcanvas-height, 30vh);
+ max-height: 100%;
+ border-top: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+ }
+}
+
+@media (max-width: 1199.98px) {
+
+ .offcanvas-xl.showing,
+ .offcanvas-xl.show:not(.hiding) {
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@media (max-width: 1199.98px) {
+
+ .offcanvas-xl.showing,
+ .offcanvas-xl.hiding,
+ .offcanvas-xl.show {
+ visibility: visible;
+ }
+}
+
+@media (min-width: 1200px) {
+ .offcanvas-xl {
+ --offcanvas-height: auto;
+ --offcanvas-border-width: 0;
+ background-color: transparent ;
+ }
+
+ .offcanvas-xl .offcanvas-header {
+ display: none;
+ }
+
+ .offcanvas-xl .offcanvas-body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 0;
+ -ms-flex-positive: 0;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ background-color: transparent ;
+ }
+}
+
+@media (max-width: 1399.98px) {
+ .offcanvas-xxl {
+ position: fixed;
+ bottom: 0;
+ z-index: var(--offcanvas-zindex, 1045);
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ max-width: 100%;
+ color: var(--offcanvas-color);
+ visibility: hidden;
+ background-color: var(--offcanvas-bg);
+ background-clip: padding-box;
+ outline: 0;
+ -webkit-transition: -webkit-transform 0.3s ease-in-out;
+ transition: -webkit-transform 0.3s ease-in-out;
+ -o-transition: transform 0.3s ease-in-out;
+ transition: transform 0.3s ease-in-out;
+ transition: transform 0.3s ease-in-out, -webkit-transform 0.3s ease-in-out;
+ }
+}
+
+@media (max-width: 1399.98px) and (prefers-reduced-motion: reduce) {
+ .offcanvas-xxl {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+@media (max-width: 1399.98px) {
+ .offcanvas-xxl.offcanvas-start {
+ top: 0;
+ left: 0;
+ width: var(--offcanvas-width, 400px);
+ border-right: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+ }
+}
+
+@media (max-width: 1399.98px) {
+ .offcanvas-xxl.offcanvas-end {
+ top: 0;
+ right: 0;
+ width: var(--offcanvas-width, 400px);
+ border-left: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+ }
+}
+
+@media (max-width: 1399.98px) {
+ .offcanvas-xxl.offcanvas-top {
+ top: 0;
+ right: 0;
+ left: 0;
+ height: var(--offcanvas-height, 30vh);
+ max-height: 100%;
+ border-bottom: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ }
+}
+
+@media (max-width: 1399.98px) {
+ .offcanvas-xxl.offcanvas-bottom {
+ right: 0;
+ left: 0;
+ height: var(--offcanvas-height, 30vh);
+ max-height: 100%;
+ border-top: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+ }
+}
+
+@media (max-width: 1399.98px) {
+
+ .offcanvas-xxl.showing,
+ .offcanvas-xxl.show:not(.hiding) {
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+
+@media (max-width: 1399.98px) {
+
+ .offcanvas-xxl.showing,
+ .offcanvas-xxl.hiding,
+ .offcanvas-xxl.show {
+ visibility: visible;
+ }
+}
+
+@media (min-width: 1400px) {
+ .offcanvas-xxl {
+ --offcanvas-height: auto;
+ --offcanvas-border-width: 0;
+ background-color: transparent ;
+ }
+
+ .offcanvas-xxl .offcanvas-header {
+ display: none;
+ }
+
+ .offcanvas-xxl .offcanvas-body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 0;
+ -ms-flex-positive: 0;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ background-color: transparent ;
+ }
+}
+
+.offcanvas {
+ position: fixed;
+ bottom: 0;
+ z-index: var(--offcanvas-zindex, 1045);
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ max-width: 100%;
+ color: var(--offcanvas-color);
+ visibility: hidden;
+ background-color: var(--offcanvas-bg);
+ background-clip: padding-box;
+ outline: 0;
+ -webkit-transition: -webkit-transform 0.3s ease-in-out;
+ transition: -webkit-transform 0.3s ease-in-out;
+ -o-transition: transform 0.3s ease-in-out;
+ transition: transform 0.3s ease-in-out;
+ transition: transform 0.3s ease-in-out, -webkit-transform 0.3s ease-in-out;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .offcanvas {
+ -webkit-transition: none;
+ -o-transition: none;
+ transition: none;
+ }
+}
+
+.offcanvas.offcanvas-start {
+ top: 0;
+ left: 0;
+ width: var(--offcanvas-width, 400px);
+ border-right: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+}
+
+.offcanvas.offcanvas-end {
+ top: 0;
+ right: 0;
+ width: var(--offcanvas-width, 400px);
+ border-left: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+}
+
+.offcanvas.offcanvas-top {
+ top: 0;
+ right: 0;
+ left: 0;
+ height: var(--offcanvas-height, 30vh);
+ max-height: 100%;
+ border-bottom: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+}
+
+.offcanvas.offcanvas-bottom {
+ right: 0;
+ left: 0;
+ height: var(--offcanvas-height, 30vh);
+ max-height: 100%;
+ border-top: var(--offcanvas-border-width, 1px) solid var(--offcanvas-border-color);
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+}
+
+.offcanvas.showing,
+.offcanvas.show:not(.hiding) {
+ -webkit-transform: none;
+ transform: none;
+}
+
+.offcanvas.showing,
+.offcanvas.hiding,
+.offcanvas.show {
+ visibility: visible;
+}
+
+.offcanvas-backdrop {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1040;
+ width: 100vw;
+ height: 100vh;
+ background-color: hsl(0, 0%, 0%);
+}
+
+.offcanvas-backdrop.fade {
+ opacity: 0;
+}
+
+.offcanvas-backdrop.show {
+ opacity: 0.5;
+}
+
+.offcanvas-header {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ padding: var(--offcanvas-padding-y, 1rem) var(--offcanvas-padding-x, 1rem);
+}
+
+.offcanvas-header .btn-close {
+ padding: calc(var(--offcanvas-padding-y, 1rem) * 0.5) calc(var(--offcanvas-padding-x, 1rem) * 0.5);
+ margin-top: calc(-0.5 * var(--offcanvas-padding-y, 1rem));
+ margin-right: calc(-0.5 * var(--offcanvas-padding-x, 1rem));
+ margin-bottom: calc(-0.5 * var(--offcanvas-padding-y, 1rem));
+ color: var(--mainmenu-nav-link-color, #fff);
+ background-color: var(--offcanvas-bg);
+}
+
+.offcanvas-title {
+ margin-bottom: 0;
+ line-height: 1.5;
+}
+
+.offcanvas-body {
+ -webkit-box-flex: 1;
+ -ms-flex-positive: 1;
+ flex-grow: 1;
+ padding: var(--offcanvas-padding-y, 1rem) var(--offcanvas-padding-x, 1rem);
+ overflow-y: auto;
+}
+
+.placeholder {
+ display: inline-block;
+ min-height: 1em;
+ vertical-align: middle;
+ cursor: wait;
+ background-color: currentcolor;
+ opacity: 0.5;
+}
+
+.placeholder.btn::before {
+ display: inline-block;
+ content: "";
+}
+
+.placeholder-xs {
+ min-height: 0.6em;
+}
+
+.placeholder-sm {
+ min-height: 0.8em;
+}
+
+.placeholder-lg {
+ min-height: 1.2em;
+}
+
+.placeholder-glow .placeholder {
+ -webkit-animation: placeholder-glow 2s ease-in-out infinite;
+ animation: placeholder-glow 2s ease-in-out infinite;
+}
+
+@-webkit-keyframes placeholder-glow {
+ 50% {
+ opacity: 0.2;
+ }
+}
+
+@keyframes placeholder-glow {
+ 50% {
+ opacity: 0.2;
+ }
+}
+
+.placeholder-wave {
+ -webkit-mask-image: linear-gradient(130deg, hsl(0, 0%, 0%) 55%, rgba(0, 0, 0, 0.8) 75%, hsl(0, 0%, 0%) 95%);
+ mask-image: linear-gradient(130deg, hsl(0, 0%, 0%) 55%, rgba(0, 0, 0, 0.8) 75%, hsl(0, 0%, 0%) 95%);
+ -webkit-mask-size: 200% 100%;
+ mask-size: 200% 100%;
+ -webkit-animation: placeholder-wave 2s linear infinite;
+ animation: placeholder-wave 2s linear infinite;
+}
+
+@-webkit-keyframes placeholder-wave {
+ 100% {
+ -webkit-mask-position: -200% 0%;
+ mask-position: -200% 0%;
+ }
+}
+
+@keyframes placeholder-wave {
+ 100% {
+ -webkit-mask-position: -200% 0%;
+ mask-position: -200% 0%;
+ }
+}
+
+.clearfix::after {
+ display: block;
+ clear: both;
+ content: "";
+}
+
+.text-bg-primary {
+ color: var(--body-color, #e6ebf1);
+ background-color: var(--primary, #010156);
+}
+
+
+.text-bg-secondary {
+ color: var(--body-color, #e6ebf1) ;
+ background-color: RGBA(109, 117, 126, var(--bg-opacity, 1)) ;
+}
+
+.text-bg-success {
+ color: var(--body-color, #e6ebf1) ;
+ background-color: RGBA(68, 131, 68, var(--bg-opacity, 1)) ;
+}
+
+.text-bg-info {
+ color: var(--body-color, #e6ebf1) ;
+ background-color: RGBA(48, 99, 141, var(--bg-opacity, 1)) ;
+}
+
+.text-bg-warning {
+ color: var(--body-color, #e6ebf1) ;
+ background-color: RGBA(173, 98, 0, var(--bg-opacity, 1)) ;
+}
+
+.text-bg-danger {
+ color: var(--body-color, #e6ebf1) ;
+ background-color: RGBA(165, 31, 24, var(--bg-opacity, 1)) ;
+}
+
+.text-bg-light {
+ color: hsl(0, 0%, 0%) ;
+ background-color: RGBA(249, 250, 251, var(--bg-opacity, 1)) ;
+}
+
+.text-bg-dark {
+ color: var(--body-color, #e6ebf1) ;
+ background-color: RGBA(53, 59, 65, var(--bg-opacity, 1)) ;
+}
+
+.link-primary {
+ color: var(--link-primary-color, hsl(240, 98%, 50%));
+}
+
+.link-primary:active,
+.link-primary:focus {
+ color: var(--link-primary-hover-color, hsl(240, 98%, 45%));
+}
+
+.link-secondary {
+ color: var(--link-secondary-color, hsl(210, 15%, 70%));
+}
+
+.link-secondary:active,
+.link-secondary:focus {
+ color: var(--link-secondary-hover-color, hsl(210, 15%, 65%));
+}
+
+.link-success {
+ color: var(--link-success-color, hsl(120, 40%, 60%));
+}
+
+.link-success:active,
+.link-success:focus {
+ color: var(--link-success-hover-color, hsl(120, 40%, 55%));
+}
+
+.link-info {
+ color: var(--link-info-color, hsl(207, 60%, 65%));
+}
+
+.link-info:active,
+.link-info:focus {
+ color: var(--link-info-hover-color, hsl(207, 60%, 60%));
+}
+
+.link-warning {
+ color: var(--link-warning-color, hsl(38, 100%, 65%));
+}
+
+.link-warning:active,
+.link-warning:focus {
+ color: var(--link-warning-hover-color, hsl(38, 100%, 60%));
+}
+
+.link-danger {
+ color: var(--link-danger-color, hsl(3, 85%, 65%));
+}
+
+.link-danger:active,
+.link-danger:focus {
+ color: var(--link-danger-hover-color, hsl(3, 85%, 60%));
+}
+
+.link-light {
+ color: var(--link-light-color, hsl(210, 20%, 90%));
+}
+
+.link-light:active,
+.link-light:focus {
+ color: var(--link-light-hover-color, hsl(210, 20%, 85%));
+}
+
+.link-dark {
+ color: var(--link-dark-color, hsl(210, 10%, 35%));
+}
+
+.link-dark:active,
+.link-dark:focus {
+ color: var(--link-dark-hover-color, hsl(210, 10%, 30%));
+}
+
+.ratio {
+ position: relative;
+ width: 100%;
+}
+
+.ratio::before {
+ display: block;
+ padding-top: var(--aspect-ratio);
+ content: "";
+}
+
+.ratio>* {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+}
+
+.ratio-1x1 {
+ --aspect-ratio: 100%;
+}
+
+.ratio-4x3 {
+ --aspect-ratio: 75%;
+}
+
+.ratio-16x9 {
+ --aspect-ratio: 56.25%;
+}
+
+.ratio-21x9 {
+ --aspect-ratio: 42.8571428571%;
+}
+
+.fixed-top {
+ position: fixed;
+ top: 0;
+ right: 0;
+ left: 0;
+ z-index: 1030;
+}
+
+.fixed-bottom {
+ position: fixed;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1030;
+}
+
+.sticky-top {
+ position: sticky ;
+ top: 0;
+ z-index: 1020;
+}
+
+.sticky-bottom {
+ position: sticky;
+ bottom: 0;
+ z-index: 1020;
+}
+
+@media (min-width: 576px) {
+ .sticky-sm-top {
+ position: sticky;
+ top: 0;
+ z-index: 1020;
+ }
+
+ .sticky-sm-bottom {
+ position: sticky;
+ bottom: 0;
+ z-index: 1020;
+ }
+}
+
+@media (min-width: 768px) {
+ .sticky-md-top {
+ position: sticky;
+ top: 0;
+ z-index: 1020;
+ }
+
+ .sticky-md-bottom {
+ position: sticky;
+ bottom: 0;
+ z-index: 1020;
+ }
+}
+
+@media (min-width: 992px) {
+ .sticky-lg-top {
+ position: sticky;
+ top: 0;
+ z-index: 1020;
+ }
+
+ .sticky-lg-bottom {
+ position: sticky;
+ bottom: 0;
+ z-index: 1020;
+ }
+}
+
+@media (min-width: 1200px) {
+ .sticky-xl-top {
+ position: sticky;
+ top: 0;
+ z-index: 1020;
+ }
+
+ .sticky-xl-bottom {
+ position: sticky;
+ bottom: 0;
+ z-index: 1020;
+ }
+}
+
+@media (min-width: 1400px) {
+ .sticky-xxl-top {
+ position: sticky;
+ top: 0;
+ z-index: 1020;
+ }
+
+ .sticky-xxl-bottom {
+ position: sticky;
+ bottom: 0;
+ z-index: 1020;
+ }
+}
+
+.hstack {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -ms-flex-item-align: stretch;
+ align-self: stretch;
+}
+
+.vstack {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -ms-flex-item-align: stretch;
+ align-self: stretch;
+}
+
+.visually-hidden,
+.sr-only,
+.visually-hidden-focusable:not(:focus):not(:focus-within) {
+ position: absolute ;
+ width: 1px ;
+ height: 1px ;
+ padding: 0 ;
+ margin: -0.0625rem ;
+ overflow: hidden ;
+ clip: rect(0, 0, 0, 0) ;
+ white-space: nowrap ;
+ border: 0 ;
+}
+
+.stretched-link::after {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1;
+ content: "";
+}
+
+.text-truncate {
+ overflow: hidden;
+ -o-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.vr {
+ display: inline-block;
+ -ms-flex-item-align: stretch;
+ align-self: stretch;
+ width: 1px;
+ min-height: 1em;
+ background-color: currentcolor;
+ opacity: 0.25;
+}
+
+.align-baseline {
+ vertical-align: baseline ;
+}
+
+.align-top {
+ vertical-align: top ;
+}
+
+.align-middle {
+ vertical-align: middle ;
+}
+
+.align-bottom {
+ vertical-align: bottom ;
+}
+
+.align-text-bottom {
+ vertical-align: text-bottom ;
+}
+
+.align-text-top {
+ vertical-align: text-top ;
+}
+
+.float-start {
+ float: left ;
+}
+
+.float-end {
+ float: right ;
+}
+
+.float-none {
+ float: none ;
+}
+
+.opacity-0 {
+ opacity: 0 ;
+}
+
+.opacity-25 {
+ opacity: 0.25 ;
+}
+
+.opacity-50 {
+ opacity: 0.5 ;
+}
+
+.opacity-75 {
+ opacity: 0.75 ;
+}
+
+.opacity-100 {
+ opacity: 1 ;
+}
+
+.overflow-auto {
+ overflow: auto ;
+}
+
+.overflow-hidden {
+ overflow: hidden ;
+}
+
+.overflow-visible {
+ overflow: visible ;
+}
+
+.overflow-scroll {
+ overflow: scroll ;
+}
+
+.d-inline {
+ display: inline ;
+}
+
+.d-inline-block {
+ display: inline-block ;
+}
+
+.d-block {
+ display: block ;
+}
+
+.d-grid {
+ display: grid ;
+}
+
+.d-table {
+ display: table ;
+}
+
+.d-table-row {
+ display: table-row ;
+}
+
+.d-table-cell {
+ display: table-cell ;
+}
+
+.d-flex {
+ display: -webkit-box ;
+ display: -ms-flexbox ;
+ display: flex ;
+}
+
+.d-inline-flex {
+ display: -webkit-inline-box ;
+ display: -ms-inline-flexbox ;
+ display: inline-flex ;
+}
+
+.d-none {
+ display: none ;
+}
+
+.shadow {
+ -webkit-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) ;
+ box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) ;
+}
+
+.shadow-sm {
+ -webkit-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) ;
+ box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) ;
+}
+
+.shadow-lg {
+ -webkit-box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) ;
+ box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) ;
+}
+
+.shadow-none {
+ -webkit-box-shadow: none ;
+ box-shadow: none ;
+}
+
+.position-static {
+ position: static ;
+}
+
+.position-relative {
+ position: relative ;
+}
+
+.position-absolute {
+ position: absolute ;
+}
+
+.position-fixed {
+ position: fixed ;
+}
+
+.position-sticky {
+ position: sticky ;
+}
+
+.top-0 {
+ top: 0 ;
+}
+
+.top-50 {
+ top: 50% ;
+}
+
+.top-100 {
+ top: 100% ;
+}
+
+.bottom-0 {
+ bottom: 0 ;
+}
+
+.bottom-50 {
+ bottom: 50% ;
+}
+
+.bottom-100 {
+ bottom: 100% ;
+}
+
+.start-0 {
+ left: 0 ;
+}
+
+.start-50 {
+ left: 50% ;
+}
+
+.start-100 {
+ left: 100% ;
+}
+
+.end-0 {
+ right: 0 ;
+}
+
+.end-50 {
+ right: 50% ;
+}
+
+.end-100 {
+ right: 100% ;
+}
+
+.translate-middle {
+ -webkit-transform: translate(-50%, -50%) ;
+ transform: translate(-50%, -50%) ;
+}
+
+.translate-middle-x {
+ -webkit-transform: translateX(-50%) ;
+ transform: translateX(-50%) ;
+}
+
+.translate-middle-y {
+ -webkit-transform: translateY(-50%) ;
+ transform: translateY(-50%) ;
+}
+
+.border {
+ border: var(--border-width, 1px) var(--border-style, solid) var(--border-color, #2b323b) ;
+}
+
+.border-0 {
+ border: 0 ;
+}
+
+.border-top {
+ border-top: var(--border-width, 1px) var(--border-style, solid) var(--border-color, #2b323b) ;
+}
+
+.border-top-0 {
+ border-top: 0 ;
+}
+
+.border-end {
+ border-right: var(--border-width, 1px) var(--border-style, solid) var(--border-color, #2b323b) ;
+}
+
+.border-end-0 {
+ border-right: 0 ;
+}
+
+.border-bottom {
+ border-bottom: var(--border-width, 1px) var(--border-style, solid) var(--border-color, #2b323b) ;
+}
+
+.border-bottom-0 {
+ border-bottom: 0 ;
+}
+
+.border-start {
+ border-left: var(--border-width, 1px) var(--border-style, solid) var(--border-color, #2b323b) ;
+}
+
+.border-start-0 {
+ border-left: 0 ;
+}
+
+.border-primary {
+ --border-opacity: 1;
+ border-color: rgba(var(--primary-rgb, 1,1,86), var(--border-opacity)) ;
+}
+
+.border-secondary {
+ --border-opacity: 1;
+ border-color: rgba(var(--secondary-rgb, 72,82,93), var(--border-opacity)) ;
+}
+
+.border-success {
+ --border-opacity: 1;
+ border-color: rgba(var(--success-rgb, 74,166,100), var(--border-opacity)) ;
+}
+
+.border-info {
+ --border-opacity: 1;
+ border-color: rgba(var(--info-rgb, 79,122,160), var(--border-opacity)) ;
+}
+
+.border-warning {
+ --border-opacity: 1;
+ border-color: rgba(var(--warning-rgb, 199,122,0), var(--border-opacity)) ;
+}
+
+.border-danger {
+ --border-opacity: 1;
+ border-color: rgba(var(--danger-rgb, 194,58,49), var(--border-opacity)) ;
+}
+
+.border-light {
+ --border-opacity: 1;
+ border-color: rgba(var(--light-rgb, 27,32,39), var(--border-opacity)) ;
+}
+
+.border-dark {
+ --border-opacity: 1;
+ border-color: rgba(var(--dark-rgb, 15,19,24), var(--border-opacity)) ;
+}
+
+.border-white {
+ --border-opacity: 1;
+ border-color: rgba(var(--white-rgb, 255, 255, 255), var(--border-opacity)) ;
+}
+
+.border-1 {
+ --border-width: 1px;
+}
+
+.border-2 {
+ --border-width: 2px;
+}
+
+.border-3 {
+ --border-width: 3px;
+}
+
+.border-4 {
+ --border-width: 4px;
+}
+
+.border-5 {
+ --border-width: 5px;
+}
+
+.border-opacity-10 {
+ --border-opacity: 0.1;
+}
+
+.border-opacity-25 {
+ --border-opacity: 0.25;
+}
+
+.border-opacity-50 {
+ --border-opacity: 0.5;
+}
+
+.border-opacity-75 {
+ --border-opacity: 0.75;
+}
+
+.border-opacity-100 {
+ --border-opacity: 1;
+}
+
+.w-25 {
+ width: 25% ;
+}
+
+.w-50 {
+ width: 50% ;
+}
+
+.w-75 {
+ width: 75% ;
+}
+
+.w-100 {
+ width: 100% ;
+}
+
+.w-auto {
+ width: auto ;
+}
+
+.mw-100 {
+ max-width: 100% ;
+}
+
+.vw-100 {
+ width: 100vw ;
+}
+
+.min-vw-100 {
+ min-width: 100vw ;
+}
+
+.h-25 {
+ height: 25% ;
+}
+
+.h-50 {
+ height: 50% ;
+}
+
+.h-75 {
+ height: 75% ;
+}
+
+.h-100 {
+ height: 100% ;
+}
+
+.h-auto {
+ height: auto ;
+}
+
+.mh-100 {
+ max-height: 100% ;
+}
+
+.vh-100 {
+ height: 100vh ;
+}
+
+.min-vh-100 {
+ min-height: 100vh ;
+}
+
+.flex-fill {
+ -webkit-box-flex: 1 ;
+ -ms-flex: 1 1 auto ;
+ flex: 1 1 auto ;
+}
+
+.flex-row {
+ -webkit-box-orient: horizontal ;
+ -webkit-box-direction: normal ;
+ -ms-flex-direction: row ;
+ flex-direction: row ;
+}
+
+.flex-column {
+ -webkit-box-orient: vertical ;
+ -webkit-box-direction: normal ;
+ -ms-flex-direction: column ;
+ flex-direction: column ;
+}
+
+.flex-row-reverse {
+ -webkit-box-orient: horizontal ;
+ -webkit-box-direction: reverse ;
+ -ms-flex-direction: row-reverse ;
+ flex-direction: row-reverse ;
+}
+
+.flex-column-reverse {
+ -webkit-box-orient: vertical ;
+ -webkit-box-direction: reverse ;
+ -ms-flex-direction: column-reverse ;
+ flex-direction: column-reverse ;
+}
+
+.flex-grow-0 {
+ -webkit-box-flex: 0 ;
+ -ms-flex-positive: 0 ;
+ flex-grow: 0 ;
+}
+
+.flex-grow-1 {
+ -webkit-box-flex: 1 ;
+ -ms-flex-positive: 1 ;
+ flex-grow: 1 ;
+}
+
+.flex-shrink-0 {
+ -ms-flex-negative: 0 ;
+ flex-shrink: 0 ;
+}
+
+.flex-shrink-1 {
+ -ms-flex-negative: 1 ;
+ flex-shrink: 1 ;
+}
+
+.flex-wrap {
+ -ms-flex-wrap: wrap ;
+ flex-wrap: wrap ;
+}
+
+.flex-nowrap {
+ -ms-flex-wrap: nowrap ;
+ flex-wrap: nowrap ;
+}
+
+.flex-wrap-reverse {
+ -ms-flex-wrap: wrap-reverse ;
+ flex-wrap: wrap-reverse ;
+}
+
+.justify-content-start {
+ -webkit-box-pack: start ;
+ -ms-flex-pack: start ;
+ justify-content: flex-start ;
+}
+
+.justify-content-end {
+ -webkit-box-pack: end ;
+ -ms-flex-pack: end ;
+ justify-content: flex-end ;
+}
+
+.justify-content-center {
+ -webkit-box-pack: center ;
+ -ms-flex-pack: center ;
+ justify-content: center ;
+}
+
+.justify-content-between {
+ -webkit-box-pack: justify ;
+ -ms-flex-pack: justify ;
+ justify-content: space-between ;
+}
+
+.justify-content-around {
+ -ms-flex-pack: distribute ;
+ justify-content: space-around ;
+}
+
+.justify-content-evenly {
+ -webkit-box-pack: space-evenly ;
+ -ms-flex-pack: space-evenly ;
+ justify-content: space-evenly ;
+}
+
+.align-items-start {
+ -webkit-box-align: start ;
+ -ms-flex-align: start ;
+ align-items: flex-start ;
+}
+
+.align-items-end {
+ -webkit-box-align: end ;
+ -ms-flex-align: end ;
+ align-items: flex-end ;
+}
+
+.align-items-center {
+ -webkit-box-align: center ;
+ -ms-flex-align: center ;
+ align-items: center ;
+}
+
+.align-items-baseline {
+ -webkit-box-align: baseline ;
+ -ms-flex-align: baseline ;
+ align-items: baseline ;
+}
+
+.align-items-stretch {
+ -webkit-box-align: stretch ;
+ -ms-flex-align: stretch ;
+ align-items: stretch ;
+}
+
+.align-content-start {
+ -ms-flex-line-pack: start ;
+ align-content: flex-start ;
+}
+
+.align-content-end {
+ -ms-flex-line-pack: end ;
+ align-content: flex-end ;
+}
+
+.align-content-center {
+ -ms-flex-line-pack: center ;
+ align-content: center ;
+}
+
+.align-content-between {
+ -ms-flex-line-pack: justify ;
+ align-content: space-between ;
+}
+
+.align-content-around {
+ -ms-flex-line-pack: distribute ;
+ align-content: space-around ;
+}
+
+.align-content-stretch {
+ -ms-flex-line-pack: stretch ;
+ align-content: stretch ;
+}
+
+.align-self-auto {
+ -ms-flex-item-align: auto ;
+ align-self: auto ;
+}
+
+.align-self-start {
+ -ms-flex-item-align: start ;
+ align-self: flex-start ;
+}
+
+.align-self-end {
+ -ms-flex-item-align: end ;
+ align-self: flex-end ;
+}
+
+.align-self-center {
+ -ms-flex-item-align: center ;
+ align-self: center ;
+}
+
+.align-self-baseline {
+ -ms-flex-item-align: baseline ;
+ align-self: baseline ;
+}
+
+.align-self-stretch {
+ -ms-flex-item-align: stretch ;
+ align-self: stretch ;
+}
+
+.order-first {
+ -webkit-box-ordinal-group: 0 ;
+ -ms-flex-order: -1 ;
+ order: -1 ;
+}
+
+.order-0 {
+ -webkit-box-ordinal-group: 1 ;
+ -ms-flex-order: 0 ;
+ order: 0 ;
+}
+
+.order-1 {
+ -webkit-box-ordinal-group: 2 ;
+ -ms-flex-order: 1 ;
+ order: 1 ;
+}
+
+.order-2 {
+ -webkit-box-ordinal-group: 3 ;
+ -ms-flex-order: 2 ;
+ order: 2 ;
+}
+
+.order-3 {
+ -webkit-box-ordinal-group: 4 ;
+ -ms-flex-order: 3 ;
+ order: 3 ;
+}
+
+.order-4 {
+ -webkit-box-ordinal-group: 5 ;
+ -ms-flex-order: 4 ;
+ order: 4 ;
+}
+
+.order-5 {
+ -webkit-box-ordinal-group: 6 ;
+ -ms-flex-order: 5 ;
+ order: 5 ;
+}
+
+.order-last {
+ -webkit-box-ordinal-group: 7 ;
+ -ms-flex-order: 6 ;
+ order: 6 ;
+}
+
+.m-0 {
+ margin: 0 ;
+}
+
+.m-1 {
+ margin: 0.25rem ;
+}
+
+.m-2 {
+ margin: 0.5rem ;
+}
+
+.m-3 {
+ margin: 1rem ;
+}
+
+.m-4 {
+ margin: 1.5rem ;
+}
+
+.m-5 {
+ margin: 3rem ;
+}
+
+.m-auto {
+ margin: auto ;
+}
+
+.mx-0 {
+ margin-right: 0 ;
+ margin-left: 0 ;
+}
+
+.mx-1 {
+ margin-right: 0.25rem ;
+ margin-left: 0.25rem ;
+}
+
+.mx-2 {
+ margin-right: 0.5rem ;
+ margin-left: 0.5rem ;
+}
+
+.mx-3 {
+ margin-right: 1rem ;
+ margin-left: 1rem ;
+}
+
+.mx-4 {
+ margin-right: 1.5rem ;
+ margin-left: 1.5rem ;
+}
+
+.mx-5 {
+ margin-right: 3rem ;
+ margin-left: 3rem ;
+}
+
+.mx-auto {
+ margin-right: auto ;
+ margin-left: auto ;
+}
+
+.my-0 {
+ margin-top: 0 ;
+ margin-bottom: 0 ;
+}
+
+.my-1 {
+ margin-top: 0.25rem ;
+ margin-bottom: 0.25rem ;
+}
+
+.my-2 {
+ margin-top: 0.5rem ;
+ margin-bottom: 0.5rem ;
+}
+
+.my-3 {
+ margin-top: 1rem ;
+ margin-bottom: 1rem ;
+}
+
+.my-4 {
+ margin-top: 1.5rem ;
+ margin-bottom: 1.5rem ;
+}
+
+.my-5 {
+ margin-top: 3rem ;
+ margin-bottom: 3rem ;
+}
+
+.my-auto {
+ margin-top: auto ;
+ margin-bottom: auto ;
+}
+
+.mt-0 {
+ margin-top: 0 ;
+}
+
+.mt-1 {
+ margin-top: 0.25rem ;
+}
+
+.mt-2 {
+ margin-top: 0.5rem ;
+}
+
+.mt-3 {
+ margin-top: 1rem ;
+}
+
+.mt-4 {
+ margin-top: 1.5rem ;
+}
+
+.mt-5 {
+ margin-top: 3rem ;
+}
+
+.mt-auto {
+ margin-top: auto ;
+}
+
+.me-0 {
+ margin-right: 0 ;
+}
+
+.me-1 {
+ margin-right: 0.25rem ;
+}
+
+.me-2 {
+ margin-right: 0.5rem ;
+}
+
+.me-3 {
+ margin-right: 1rem ;
+}
+
+.me-4 {
+ margin-right: 1.5rem ;
+}
+
+.me-5 {
+ margin-right: 3rem ;
+}
+
+.me-auto {
+ margin-right: auto ;
+}
+
+.mb-0 {
+ margin-bottom: 0 ;
+ margin-top: 0 ;
+}
+
+.mb-1 {
+ margin-bottom: 0.1rem ;
+ margin-top: 0.1rem ;
+}
+
+.mb-2 {
+ margin-bottom: 0.2rem ;
+ margin-top: 0.2rem ;
+}
+
+.mb-3,
+.form-group {
+ margin-bottom: 0.3rem ;
+ margin-top: 0.3rem ;
+}
+
+.mb-4 {
+ margin-bottom: 0.4rem ;
+ margin-top: 0.4rem ;
+}
+
+.mb-5 {
+ margin-bottom: 0.5rem ;
+ margin-top: 0.5rem ;
+}
+
+.mb-auto {
+ margin-bottom: auto ;
+ margin-top: auto ;
+}
+
+.ms-0 {
+ margin-left: 0 ;
+}
+
+.ms-1 {
+ margin-left: 0.25rem ;
+}
+
+.ms-2 {
+ margin-left: 0.5rem ;
+}
+
+.ms-3 {
+ margin-left: 1rem ;
+}
+
+.ms-4 {
+ margin-left: 1.5rem ;
+}
+
+.ms-5 {
+ margin-left: 3rem ;
+}
+
+.ms-auto {
+ margin-left: auto ;
+}
+
+.p-0 {
+ padding: 0 ;
+}
+
+.p-1 {
+ padding: 0.25rem ;
+}
+
+.p-2 {
+ padding: 0.5rem ;
+}
+
+.p-3 {
+ padding: 1rem ;
+}
+
+.p-4 {
+ padding: 1.5rem ;
+}
+
+.p-5 {
+ padding: 3rem ;
+}
+
+.px-0 {
+ padding-right: 0 ;
+ padding-left: 0 ;
+}
+
+.px-1 {
+ padding-right: 0.25rem ;
+ padding-left: 0.25rem ;
+}
+
+.px-2 {
+ padding-right: 0.5rem ;
+ padding-left: 0.5rem ;
+}
+
+.px-3 {
+ padding-right: 1rem ;
+ padding-left: 1rem ;
+}
+
+.px-4 {
+ padding-right: 1.5rem ;
+ padding-left: 1.5rem ;
+}
+
+.px-5 {
+ padding-right: 3rem ;
+ padding-left: 3rem ;
+}
+
+.py-0 {
+ padding-top: 0 ;
+ padding-bottom: 0 ;
+}
+
+.py-1 {
+ padding-top: 0.25rem ;
+ padding-bottom: 0.25rem ;
+}
+
+.py-2 {
+ padding-top: 0.5rem ;
+ padding-bottom: 0.5rem ;
+}
+
+.py-3 {
+ padding-top: 1rem ;
+ padding-bottom: 1rem ;
+}
+
+.py-4 {
+ padding-top: 1.5rem ;
+ padding-bottom: 1.5rem ;
+}
+
+.py-5 {
+ padding-top: 3rem ;
+ padding-bottom: 3rem ;
+}
+
+.pt-0 {
+ padding-top: 0 ;
+}
+
+.pt-1 {
+ padding-top: 0.25rem ;
+}
+
+.pt-2 {
+ padding-top: 0.5rem ;
+}
+
+.pt-3 {
+ padding-top: 1rem ;
+}
+
+.pt-4 {
+ padding-top: 1.5rem ;
+}
+
+.pt-5 {
+ padding-top: 3rem ;
+}
+
+.pe-0 {
+ padding-right: 0 ;
+}
+
+.pe-1 {
+ padding-right: 0.25rem ;
+}
+
+.pe-2 {
+ padding-right: 0.5rem ;
+}
+
+.pe-3 {
+ padding-right: 1rem ;
+}
+
+.pe-4 {
+ padding-right: 1.5rem ;
+}
+
+.pe-5 {
+ padding-right: 3rem ;
+}
+
+.pb-0 {
+ padding-bottom: 0 ;
+}
+
+.pb-1 {
+ padding-bottom: 0.25rem ;
+}
+
+.pb-2 {
+ padding-bottom: 0.5rem ;
+}
+
+.pb-3 {
+ padding-bottom: 1rem ;
+}
+
+.pb-4 {
+ padding-bottom: 1.5rem ;
+}
+
+.pb-5 {
+ padding-bottom: 3rem ;
+}
+
+.ps-0 {
+ padding-left: 0 ;
+}
+
+.ps-1 {
+ padding-left: 0.25rem ;
+}
+
+.ps-2 {
+ padding-left: 0.5rem ;
+}
+
+.ps-3 {
+ padding-left: 1rem ;
+}
+
+.ps-4 {
+ padding-left: 1.5rem ;
+}
+
+.ps-5 {
+ padding-left: 3rem ;
+}
+
+.gap-0 {
+ gap: 0 ;
+}
+
+.gap-1 {
+ gap: 0.25rem ;
+}
+
+.gap-2 {
+ gap: 0.5rem ;
+}
+
+.gap-3 {
+ gap: 1rem ;
+}
+
+.gap-4 {
+ gap: 1.5rem ;
+}
+
+.gap-5 {
+ gap: 3rem ;
+}
+
+.font-monospace {
+ font-family: var(--font-monospace) ;
+}
+
+.fs-1 {
+ font-size: calc(1.375rem + 1.5vw) ;
+}
+
+.fs-2 {
+ font-size: calc(1.325rem + 0.9vw) ;
+}
+
+.fs-3 {
+ font-size: calc(1.3rem + 0.6vw) ;
+}
+
+.fs-4 {
+ font-size: calc(1.275rem + 0.3vw) ;
+}
+
+.fs-5 {
+ font-size: 1.25rem ;
+}
+
+.fs-6 {
+ font-size: 1rem ;
+}
+
+.fst-italic {
+ font-style: italic ;
+}
+
+.fst-normal {
+ font-style: normal ;
+}
+
+.fw-light {
+ font-weight: 300 ;
+}
+
+.fw-lighter {
+ font-weight: lighter ;
+}
+
+.fw-normal {
+ font-weight: 400 ;
+}
+
+.fw-bold {
+ font-weight: 700 ;
+}
+
+.fw-semibold {
+ font-weight: 600 ;
+}
+
+.fw-bolder {
+ font-weight: bolder ;
+}
+
+.lh-1 {
+ line-height: 1 ;
+}
+
+.lh-sm {
+ line-height: 1.25 ;
+}
+
+.lh-base {
+ line-height: 1.5 ;
+}
+
+.lh-lg {
+ line-height: 2 ;
+}
+
+.text-start {
+ text-align: left;
+}
+
+.text-end {
+ text-align: right;
+}
+
+.text-center {
+ text-align: center ;
+}
+
+.text-decoration-none {
+ text-decoration: none ;
+}
+
+.text-decoration-underline {
+ text-decoration: underline ;
+}
+
+.text-decoration-line-through {
+ text-decoration: line-through ;
+}
+
+.text-lowercase {
+ text-transform: lowercase ;
+}
+
+.text-uppercase {
+ text-transform: uppercase ;
+}
+
+.text-capitalize {
+ text-transform: capitalize ;
+}
+
+.text-wrap {
+ white-space: normal ;
+}
+
+.text-nowrap {
+ white-space: nowrap ;
+}
+
+/* rtl:begin:remove */
+.text-break {
+ word-wrap: break-word ;
+ word-break: break-word ;
+}
+
+/* rtl:end:remove */
+.text-primary {
+ --text-opacity: 1;
+ color: rgba(var(--primary-rgb, 1,1,86), var(--text-opacity)) ;
+}
+
+.text-secondary {
+ --text-opacity: 1;
+ color: rgba(var(--secondary-rgb, 72,82,93), var(--text-opacity)) ;
+}
+
+.text-success {
+ --text-opacity: 1;
+ color: rgba(var(--success-rgb, 74,166,100), var(--text-opacity)) ;
+}
+
+.text-info {
+ --text-opacity: 1;
+ color: rgba(var(--info-rgb, 79,122,160), var(--text-opacity)) ;
+}
+
+.text-warning {
+ --text-opacity: 1;
+ color: rgba(var(--warning-rgb, 199,122,0), var(--text-opacity)) ;
+}
+
+.text-danger {
+ --text-opacity: 1;
+ color: rgba(var(--danger-rgb, 194,58,49), var(--text-opacity)) ;
+}
+
+.text-light {
+ --text-opacity: 1;
+ color: rgba(var(--light-rgb, 27,32,39), var(--text-opacity)) ;
+}
+
+.text-dark {
+ --text-opacity: 1;
+ color: rgba(var(--dark-rgb, 15,19,24), var(--text-opacity)) ;
+}
+
+.text-black {
+ --text-opacity: 1;
+ color: rgba(var(--black-rgb, 0, 0, 0), var(--text-opacity)) ;
+}
+
+.text-white {
+ --text-opacity: 1;
+ color: rgba(var(--white-rgb, 255, 255, 255), var(--text-opacity)) ;
+}
+
+.text-body {
+ --text-opacity: 1;
+ color: rgba(var(--body-color-rgb, 230, 235, 241), var(--text-opacity)) ;
+}
+
+.text-muted {
+ --text-opacity: 1;
+ color: hsl(210, 7%, 46%) ;
+}
+
+.text-black-50 {
+ --text-opacity: 1;
+ color: rgba(0, 0, 0, 0.5) ;
+}
+
+.text-white-50 {
+ --text-opacity: 1;
+ color: rgba(255, 255, 255, 0.5) ;
+}
+
+.text-reset {
+ --text-opacity: 1;
+}
+
+.text-opacity-25 {
+ --text-opacity: 0.25;
+}
+
+.text-opacity-50 {
+ --text-opacity: 0.5;
+}
+
+.text-opacity-75 {
+ --text-opacity: 0.75;
+}
+
+.text-opacity-100 {
+ --text-opacity: 1;
+}
+
+.bg-primary {
+ --bg-opacity: 1;
+ background-color: rgba(var(--primary-rgb, 1,1,86), var(--bg-opacity, 1)) ;
+}
+
+.bg-secondary {
+ --bg-opacity: 1;
+ background-color: rgba(var(--secondary-rgb, 72,82,93), var(--bg-opacity, 1)) ;
+}
+
+.bg-success {
+ --bg-opacity: 1;
+ background-color: rgba(var(--success-rgb, 74,166,100), var(--bg-opacity, 1)) ;
+}
+
+.bg-info {
+ --bg-opacity: 1;
+ background-color: rgba(var(--info-rgb, 79,122,160), var(--bg-opacity, 1)) ;
+}
+
+.bg-warning {
+ --bg-opacity: 1;
+ background-color: rgba(var(--warning-rgb, 199,122,0), var(--bg-opacity, 1)) ;
+}
+
+.bg-danger {
+ --bg-opacity: 1;
+ background-color: rgba(var(--danger-rgb, 194,58,49), var(--bg-opacity, 1)) ;
+}
+
+.bg-light {
+ --bg-opacity: 1;
+ background-color: rgba(var(--light-rgb, 27,32,39), var(--bg-opacity, 1)) ;
+}
+
+.bg-dark {
+ --bg-opacity: 1;
+ background-color: rgba(var(--dark-rgb, 15,19,24), var(--bg-opacity, 1)) ;
+}
+
+.bg-black {
+ --bg-opacity: 1;
+ background-color: rgba(var(--black-rgb, 0, 0, 0), var(--bg-opacity, 1)) ;
+}
+
+.bg-white {
+ --bg-opacity: 1;
+ background-color: rgba(var(--white-rgb, 255, 255, 255), var(--bg-opacity, 1)) ;
+}
+
+.bg-body {
+ --bg-opacity: 1;
+ background-color: rgba(var(--body-bg-rgb, 14, 19, 24), var(--bg-opacity, 1)) ;
+}
+
+.bg-transparent {
+ --bg-opacity: 1;
+ background-color: transparent ;
+}
+
+.bg-opacity-10 {
+ --bg-opacity: 0.1;
+}
+
+.bg-opacity-25 {
+ --bg-opacity: 0.25;
+}
+
+.bg-opacity-50 {
+ --bg-opacity: 0.5;
+}
+
+.bg-opacity-75 {
+ --bg-opacity: 0.75;
+}
+
+.bg-opacity-100 {
+ --bg-opacity: 1;
+}
+
+.bg-gradient {
+ background-image: var(--gradient, none) ;
+}
+
+.user-select-all {
+ -webkit-user-select: all ;
+ -moz-user-select: all ;
+ user-select: all ;
+}
+
+.user-select-auto {
+ -webkit-user-select: auto ;
+ -moz-user-select: auto ;
+ -ms-user-select: auto ;
+ user-select: auto ;
+}
+
+.user-select-none {
+ -webkit-user-select: none ;
+ -moz-user-select: none ;
+ -ms-user-select: none ;
+ user-select: none ;
+}
+
+.pe-none {
+ pointer-events: none ;
+}
+
+.pe-auto {
+ pointer-events: auto ;
+}
+
+.rounded {
+ border-radius: var(--border-radius, .25rem) ;
+}
+
+.rounded-0 {
+ border-radius: 0 ;
+}
+
+.rounded-1 {
+ border-radius: var(--border-radius-sm, .2rem) ;
+}
+
+.rounded-2 {
+ border-radius: var(--border-radius, .25rem) ;
+}
+
+.rounded-3 {
+ border-radius: var(--border-radius-lg, .3rem) ;
+}
+
+.rounded-4 {
+ border-radius: var(--border-radius-xl, .3rem) ;
+}
+
+.rounded-5 {
+ border-radius: var(--border-radius-2xl) ;
+}
+
+.rounded-circle {
+ border-radius: 50% ;
+}
+
+.rounded-pill {
+ border-radius: var(--border-radius-pill, 50rem) ;
+}
+
+.rounded-top {
+ border-top-left-radius: var(--border-radius, .25rem) ;
+ border-top-right-radius: var(--border-radius, .25rem) ;
+}
+
+.rounded-end {
+ border-top-right-radius: var(--border-radius, .25rem) ;
+ border-bottom-right-radius: var(--border-radius, .25rem) ;
+}
+
+.rounded-bottom {
+ border-bottom-right-radius: var(--border-radius, .25rem) ;
+ border-bottom-left-radius: var(--border-radius, .25rem) ;
+}
+
+.rounded-start {
+ border-bottom-left-radius: var(--border-radius, .25rem) ;
+ border-top-left-radius: var(--border-radius, .25rem) ;
+}
+
+.visible {
+ visibility: visible ;
+}
+
+.invisible {
+ visibility: hidden ;
+}
+
+@media (min-width: 576px) {
+ .float-sm-start {
+ float: left ;
+ }
+
+ .float-sm-end {
+ float: right ;
+ }
+
+ .float-sm-none {
+ float: none ;
+ }
+
+ .d-sm-inline {
+ display: inline ;
+ }
+
+ .d-sm-inline-block {
+ display: inline-block ;
+ }
+
+ .d-sm-block {
+ display: block ;
+ }
+
+ .d-sm-grid {
+ display: grid ;
+ }
+
+ .d-sm-table {
+ display: table ;
+ }
+
+ .d-sm-table-row {
+ display: table-row ;
+ }
+
+ .d-sm-table-cell {
+ display: table-cell ;
+ }
+
+ .d-sm-flex {
+ display: -webkit-box ;
+ display: -ms-flexbox ;
+ display: flex ;
+ }
+
+ .d-sm-inline-flex {
+ display: -webkit-inline-box ;
+ display: -ms-inline-flexbox ;
+ display: inline-flex ;
+ }
+
+ .d-sm-none {
+ display: none ;
+ }
+
+ .flex-sm-fill {
+ -webkit-box-flex: 1 ;
+ -ms-flex: 1 1 auto ;
+ flex: 1 1 auto ;
+ }
+
+ .flex-sm-row {
+ -webkit-box-orient: horizontal ;
+ -webkit-box-direction: normal ;
+ -ms-flex-direction: row ;
+ flex-direction: row ;
+ }
+
+ .flex-sm-column {
+ -webkit-box-orient: vertical ;
+ -webkit-box-direction: normal ;
+ -ms-flex-direction: column ;
+ flex-direction: column ;
+ }
+
+ .flex-sm-row-reverse {
+ -webkit-box-orient: horizontal ;
+ -webkit-box-direction: reverse ;
+ -ms-flex-direction: row-reverse ;
+ flex-direction: row-reverse ;
+ }
+
+ .flex-sm-column-reverse {
+ -webkit-box-orient: vertical ;
+ -webkit-box-direction: reverse ;
+ -ms-flex-direction: column-reverse ;
+ flex-direction: column-reverse ;
+ }
+
+ .flex-sm-grow-0 {
+ -webkit-box-flex: 0 ;
+ -ms-flex-positive: 0 ;
+ flex-grow: 0 ;
+ }
+
+ .flex-sm-grow-1 {
+ -webkit-box-flex: 1 ;
+ -ms-flex-positive: 1 ;
+ flex-grow: 1 ;
+ }
+
+ .flex-sm-shrink-0 {
+ -ms-flex-negative: 0 ;
+ flex-shrink: 0 ;
+ }
+
+ .flex-sm-shrink-1 {
+ -ms-flex-negative: 1 ;
+ flex-shrink: 1 ;
+ }
+
+ .flex-sm-wrap {
+ -ms-flex-wrap: wrap ;
+ flex-wrap: wrap ;
+ }
+
+ .flex-sm-nowrap {
+ -ms-flex-wrap: nowrap ;
+ flex-wrap: nowrap ;
+ }
+
+ .flex-sm-wrap-reverse {
+ -ms-flex-wrap: wrap-reverse ;
+ flex-wrap: wrap-reverse ;
+ }
+
+ .justify-content-sm-start {
+ -webkit-box-pack: start ;
+ -ms-flex-pack: start ;
+ justify-content: flex-start ;
+ }
+
+ .justify-content-sm-end {
+ -webkit-box-pack: end ;
+ -ms-flex-pack: end ;
+ justify-content: flex-end ;
+ }
+
+ .justify-content-sm-center {
+ -webkit-box-pack: center ;
+ -ms-flex-pack: center ;
+ justify-content: center ;
+ }
+
+ .justify-content-sm-between {
+ -webkit-box-pack: justify ;
+ -ms-flex-pack: justify ;
+ justify-content: space-between ;
+ }
+
+ .justify-content-sm-around {
+ -ms-flex-pack: distribute ;
+ justify-content: space-around ;
+ }
+
+ .justify-content-sm-evenly {
+ -webkit-box-pack: space-evenly ;
+ -ms-flex-pack: space-evenly ;
+ justify-content: space-evenly ;
+ }
+
+ .align-items-sm-start {
+ -webkit-box-align: start ;
+ -ms-flex-align: start ;
+ align-items: flex-start ;
+ }
+
+ .align-items-sm-end {
+ -webkit-box-align: end ;
+ -ms-flex-align: end ;
+ align-items: flex-end ;
+ }
+
+ .align-items-sm-center {
+ -webkit-box-align: center ;
+ -ms-flex-align: center ;
+ align-items: center ;
+ }
+
+ .align-items-sm-baseline {
+ -webkit-box-align: baseline ;
+ -ms-flex-align: baseline ;
+ align-items: baseline ;
+ }
+
+ .align-items-sm-stretch {
+ -webkit-box-align: stretch ;
+ -ms-flex-align: stretch ;
+ align-items: stretch ;
+ }
+
+ .align-content-sm-start {
+ -ms-flex-line-pack: start ;
+ align-content: flex-start ;
+ }
+
+ .align-content-sm-end {
+ -ms-flex-line-pack: end ;
+ align-content: flex-end ;
+ }
+
+ .align-content-sm-center {
+ -ms-flex-line-pack: center ;
+ align-content: center ;
+ }
+
+ .align-content-sm-between {
+ -ms-flex-line-pack: justify ;
+ align-content: space-between ;
+ }
+
+ .align-content-sm-around {
+ -ms-flex-line-pack: distribute ;
+ align-content: space-around ;
+ }
+
+ .align-content-sm-stretch {
+ -ms-flex-line-pack: stretch ;
+ align-content: stretch ;
+ }
+
+ .align-self-sm-auto {
+ -ms-flex-item-align: auto ;
+ align-self: auto ;
+ }
+
+ .align-self-sm-start {
+ -ms-flex-item-align: start ;
+ align-self: flex-start ;
+ }
+
+ .align-self-sm-end {
+ -ms-flex-item-align: end ;
+ align-self: flex-end ;
+ }
+
+ .align-self-sm-center {
+ -ms-flex-item-align: center ;
+ align-self: center ;
+ }
+
+ .align-self-sm-baseline {
+ -ms-flex-item-align: baseline ;
+ align-self: baseline ;
+ }
+
+ .align-self-sm-stretch {
+ -ms-flex-item-align: stretch ;
+ align-self: stretch ;
+ }
+
+ .order-sm-first {
+ -webkit-box-ordinal-group: 0 ;
+ -ms-flex-order: -1 ;
+ order: -1 ;
+ }
+
+ .order-sm-0 {
+ -webkit-box-ordinal-group: 1 ;
+ -ms-flex-order: 0 ;
+ order: 0 ;
+ }
+
+ .order-sm-1 {
+ -webkit-box-ordinal-group: 2 ;
+ -ms-flex-order: 1 ;
+ order: 1 ;
+ }
+
+ .order-sm-2 {
+ -webkit-box-ordinal-group: 3 ;
+ -ms-flex-order: 2 ;
+ order: 2 ;
+ }
+
+ .order-sm-3 {
+ -webkit-box-ordinal-group: 4 ;
+ -ms-flex-order: 3 ;
+ order: 3 ;
+ }
+
+ .order-sm-4 {
+ -webkit-box-ordinal-group: 5 ;
+ -ms-flex-order: 4 ;
+ order: 4 ;
+ }
+
+ .order-sm-5 {
+ -webkit-box-ordinal-group: 6 ;
+ -ms-flex-order: 5 ;
+ order: 5 ;
+ }
+
+ .order-sm-last {
+ -webkit-box-ordinal-group: 7 ;
+ -ms-flex-order: 6 ;
+ order: 6 ;
+ }
+
+ .m-sm-0 {
+ margin: 0 ;
+ }
+
+ .m-sm-1 {
+ margin: 0.25rem ;
+ }
+
+ .m-sm-2 {
+ margin: 0.5rem ;
+ }
+
+ .m-sm-3 {
+ margin: 1rem ;
+ }
+
+ .m-sm-4 {
+ margin: 1.5rem ;
+ }
+
+ .m-sm-5 {
+ margin: 3rem ;
+ }
+
+ .m-sm-auto {
+ margin: auto ;
+ }
+
+ .mx-sm-0 {
+ margin-right: 0 ;
+ margin-left: 0 ;
+ }
+
+ .mx-sm-1 {
+ margin-right: 0.25rem ;
+ margin-left: 0.25rem ;
+ }
+
+ .mx-sm-2 {
+ margin-right: 0.5rem ;
+ margin-left: 0.5rem ;
+ }
+
+ .mx-sm-3 {
+ margin-right: 1rem ;
+ margin-left: 1rem ;
+ }
+
+ .mx-sm-4 {
+ margin-right: 1.5rem ;
+ margin-left: 1.5rem ;
+ }
+
+ .mx-sm-5 {
+ margin-right: 3rem ;
+ margin-left: 3rem ;
+ }
+
+ .mx-sm-auto {
+ margin-right: auto ;
+ margin-left: auto ;
+ }
+
+ .my-sm-0 {
+ margin-top: 0 ;
+ margin-bottom: 0 ;
+ }
+
+ .my-sm-1 {
+ margin-top: 0.25rem ;
+ margin-bottom: 0.25rem ;
+ }
+
+ .my-sm-2 {
+ margin-top: 0.5rem ;
+ margin-bottom: 0.5rem ;
+ }
+
+ .my-sm-3 {
+ margin-top: 1rem ;
+ margin-bottom: 1rem ;
+ }
+
+ .my-sm-4 {
+ margin-top: 1.5rem ;
+ margin-bottom: 1.5rem ;
+ }
+
+ .my-sm-5 {
+ margin-top: 3rem ;
+ margin-bottom: 3rem ;
+ }
+
+ .my-sm-auto {
+ margin-top: auto ;
+ margin-bottom: auto ;
+ }
+
+ .mt-sm-0 {
+ margin-top: 0 ;
+ }
+
+ .mt-sm-1 {
+ margin-top: 0.25rem ;
+ }
+
+ .mt-sm-2 {
+ margin-top: 0.5rem ;
+ }
+
+ .mt-sm-3 {
+ margin-top: 1rem ;
+ }
+
+ .mt-sm-4 {
+ margin-top: 1.5rem ;
+ }
+
+ .mt-sm-5 {
+ margin-top: 3rem ;
+ }
+
+ .mt-sm-auto {
+ margin-top: auto ;
+ }
+
+ .me-sm-0 {
+ margin-right: 0 ;
+ }
+
+ .me-sm-1 {
+ margin-right: 0.25rem ;
+ }
+
+ .me-sm-2 {
+ margin-right: 0.5rem ;
+ }
+
+ .me-sm-3 {
+ margin-right: 1rem ;
+ }
+
+ .me-sm-4 {
+ margin-right: 1.5rem ;
+ }
+
+ .me-sm-5 {
+ margin-right: 3rem ;
+ }
+
+ .me-sm-auto {
+ margin-right: auto ;
+ }
+
+ .mb-sm-0 {
+ margin-bottom: 0 ;
+ }
+
+ .mb-sm-1 {
+ margin-bottom: 0.25rem ;
+ }
+
+ .mb-sm-2 {
+ margin-bottom: 0.5rem ;
+ }
+
+ .mb-sm-3 {
+ margin-bottom: 1rem ;
+ }
+
+ .mb-sm-4 {
+ margin-bottom: 1.5rem ;
+ }
+
+ .mb-sm-5 {
+ margin-bottom: 3rem ;
+ }
+
+ .mb-sm-auto {
+ margin-bottom: auto ;
+ }
+
+ .ms-sm-0 {
+ margin-left: 0 ;
+ }
+
+ .ms-sm-1 {
+ margin-left: 0.25rem ;
+ }
+
+ .ms-sm-2 {
+ margin-left: 0.5rem ;
+ }
+
+ .ms-sm-3 {
+ margin-left: 1rem ;
+ }
+
+ .ms-sm-4 {
+ margin-left: 1.5rem ;
+ }
+
+ .ms-sm-5 {
+ margin-left: 3rem ;
+ }
+
+ .ms-sm-auto {
+ margin-left: auto ;
+ }
+
+ .p-sm-0 {
+ padding: 0 ;
+ }
+
+ .p-sm-1 {
+ padding: 0.25rem ;
+ }
+
+ .p-sm-2 {
+ padding: 0.5rem ;
+ }
+
+ .p-sm-3 {
+ padding: 1rem ;
+ }
+
+ .p-sm-4 {
+ padding: 1.5rem ;
+ }
+
+ .p-sm-5 {
+ padding: 3rem ;
+ }
+
+ .px-sm-0 {
+ padding-right: 0 ;
+ padding-left: 0 ;
+ }
+
+ .px-sm-1 {
+ padding-right: 0.25rem ;
+ padding-left: 0.25rem ;
+ }
+
+ .px-sm-2 {
+ padding-right: 0.5rem ;
+ padding-left: 0.5rem ;
+ }
+
+ .px-sm-3 {
+ padding-right: 1rem ;
+ padding-left: 1rem ;
+ }
+
+ .px-sm-4 {
+ padding-right: 1.5rem ;
+ padding-left: 1.5rem ;
+ }
+
+ .px-sm-5 {
+ padding-right: 3rem ;
+ padding-left: 3rem ;
+ }
+
+ .py-sm-0 {
+ padding-top: 0 ;
+ padding-bottom: 0 ;
+ }
+
+ .py-sm-1 {
+ padding-top: 0.25rem ;
+ padding-bottom: 0.25rem ;
+ }
+
+ .py-sm-2 {
+ padding-top: 0.5rem ;
+ padding-bottom: 0.5rem ;
+ }
+
+ .py-sm-3 {
+ padding-top: 1rem ;
+ padding-bottom: 1rem ;
+ }
+
+ .py-sm-4 {
+ padding-top: 1.5rem ;
+ padding-bottom: 1.5rem ;
+ }
+
+ .py-sm-5 {
+ padding-top: 3rem ;
+ padding-bottom: 3rem ;
+ }
+
+ .pt-sm-0 {
+ padding-top: 0 ;
+ }
+
+ .pt-sm-1 {
+ padding-top: 0.25rem ;
+ }
+
+ .pt-sm-2 {
+ padding-top: 0.5rem ;
+ }
+
+ .pt-sm-3 {
+ padding-top: 1rem ;
+ }
+
+ .pt-sm-4 {
+ padding-top: 1.5rem ;
+ }
+
+ .pt-sm-5 {
+ padding-top: 3rem ;
+ }
+
+ .pe-sm-0 {
+ padding-right: 0 ;
+ }
+
+ .pe-sm-1 {
+ padding-right: 0.25rem ;
+ }
+
+ .pe-sm-2 {
+ padding-right: 0.5rem ;
+ }
+
+ .pe-sm-3 {
+ padding-right: 1rem ;
+ }
+
+ .pe-sm-4 {
+ padding-right: 1.5rem ;
+ }
+
+ .pe-sm-5 {
+ padding-right: 3rem ;
+ }
+
+ .pb-sm-0 {
+ padding-bottom: 0 ;
+ }
+
+ .pb-sm-1 {
+ padding-bottom: 0.25rem ;
+ }
+
+ .pb-sm-2 {
+ padding-bottom: 0.5rem ;
+ }
+
+ .pb-sm-3 {
+ padding-bottom: 1rem ;
+ }
+
+ .pb-sm-4 {
+ padding-bottom: 1.5rem ;
+ }
+
+ .pb-sm-5 {
+ padding-bottom: 3rem ;
+ }
+
+ .ps-sm-0 {
+ padding-left: 0 ;
+ }
+
+ .ps-sm-1 {
+ padding-left: 0.25rem ;
+ }
+
+ .ps-sm-2 {
+ padding-left: 0.5rem ;
+ }
+
+ .ps-sm-3 {
+ padding-left: 1rem ;
+ }
+
+ .ps-sm-4 {
+ padding-left: 1.5rem ;
+ }
+
+ .ps-sm-5 {
+ padding-left: 3rem ;
+ }
+
+ .gap-sm-0 {
+ gap: 0 ;
+ }
+
+ .gap-sm-1 {
+ gap: 0.25rem ;
+ }
+
+ .gap-sm-2 {
+ gap: 0.5rem ;
+ }
+
+ .gap-sm-3 {
+ gap: 1rem ;
+ }
+
+ .gap-sm-4 {
+ gap: 1.5rem ;
+ }
+
+ .gap-sm-5 {
+ gap: 3rem ;
+ }
+
+ .text-sm-start {
+ text-align: left ;
+ }
+
+ .text-sm-end {
+ text-align: right ;
+ }
+
+ .text-sm-center {
+ text-align: center ;
+ }
+}
+
+@media (min-width: 768px) {
+ .float-md-start {
+ float: left ;
+ }
+
+ .float-md-end {
+ float: right ;
+ }
+
+ .float-md-none {
+ float: none ;
+ }
+
+ .d-md-inline {
+ display: inline ;
+ }
+
+ .d-md-inline-block {
+ display: inline-block ;
+ }
+
+ .d-md-block {
+ display: block ;
+ }
+
+ .d-md-grid {
+ display: grid ;
+ }
+
+ .d-md-table {
+ display: table ;
+ }
+
+ .d-md-table-row {
+ display: table-row ;
+ }
+
+ .d-md-table-cell {
+ display: table-cell ;
+ }
+
+ .d-md-flex {
+ display: -webkit-box ;
+ display: -ms-flexbox ;
+ display: flex ;
+ }
+
+ .d-md-inline-flex {
+ display: -webkit-inline-box ;
+ display: -ms-inline-flexbox ;
+ display: inline-flex ;
+ }
+
+ .d-md-none {
+ display: none ;
+ }
+
+ .flex-md-fill {
+ -webkit-box-flex: 1 ;
+ -ms-flex: 1 1 auto ;
+ flex: 1 1 auto ;
+ }
+
+ .flex-md-row {
+ -webkit-box-orient: horizontal ;
+ -webkit-box-direction: normal ;
+ -ms-flex-direction: row ;
+ flex-direction: row ;
+ }
+
+ .flex-md-column {
+ -webkit-box-orient: vertical ;
+ -webkit-box-direction: normal ;
+ -ms-flex-direction: column ;
+ flex-direction: column ;
+ }
+
+ .flex-md-row-reverse {
+ -webkit-box-orient: horizontal ;
+ -webkit-box-direction: reverse ;
+ -ms-flex-direction: row-reverse ;
+ flex-direction: row-reverse ;
+ }
+
+ .flex-md-column-reverse {
+ -webkit-box-orient: vertical ;
+ -webkit-box-direction: reverse ;
+ -ms-flex-direction: column-reverse ;
+ flex-direction: column-reverse ;
+ }
+
+ .flex-md-grow-0 {
+ -webkit-box-flex: 0 ;
+ -ms-flex-positive: 0 ;
+ flex-grow: 0 ;
+ }
+
+ .flex-md-grow-1 {
+ -webkit-box-flex: 1 ;
+ -ms-flex-positive: 1 ;
+ flex-grow: 1 ;
+ }
+
+ .flex-md-shrink-0 {
+ -ms-flex-negative: 0 ;
+ flex-shrink: 0 ;
+ }
+
+ .flex-md-shrink-1 {
+ -ms-flex-negative: 1 ;
+ flex-shrink: 1 ;
+ }
+
+ .flex-md-wrap {
+ -ms-flex-wrap: wrap ;
+ flex-wrap: wrap ;
+ }
+
+ .flex-md-nowrap {
+ -ms-flex-wrap: nowrap ;
+ flex-wrap: nowrap ;
+ }
+
+ .flex-md-wrap-reverse {
+ -ms-flex-wrap: wrap-reverse ;
+ flex-wrap: wrap-reverse ;
+ }
+
+ .justify-content-md-start {
+ -webkit-box-pack: start ;
+ -ms-flex-pack: start ;
+ justify-content: flex-start ;
+ }
+
+ .justify-content-md-end {
+ -webkit-box-pack: end ;
+ -ms-flex-pack: end ;
+ justify-content: flex-end ;
+ }
+
+ .justify-content-md-center {
+ -webkit-box-pack: center ;
+ -ms-flex-pack: center ;
+ justify-content: center ;
+ }
+
+ .justify-content-md-between {
+ -webkit-box-pack: justify ;
+ -ms-flex-pack: justify ;
+ justify-content: space-between ;
+ }
+
+ .justify-content-md-around {
+ -ms-flex-pack: distribute ;
+ justify-content: space-around ;
+ }
+
+ .justify-content-md-evenly {
+ -webkit-box-pack: space-evenly ;
+ -ms-flex-pack: space-evenly ;
+ justify-content: space-evenly ;
+ }
+
+ .align-items-md-start {
+ -webkit-box-align: start ;
+ -ms-flex-align: start ;
+ align-items: flex-start ;
+ }
+
+ .align-items-md-end {
+ -webkit-box-align: end ;
+ -ms-flex-align: end ;
+ align-items: flex-end ;
+ }
+
+ .align-items-md-center {
+ -webkit-box-align: center ;
+ -ms-flex-align: center ;
+ align-items: center ;
+ }
+
+ .align-items-md-baseline {
+ -webkit-box-align: baseline ;
+ -ms-flex-align: baseline ;
+ align-items: baseline ;
+ }
+
+ .align-items-md-stretch {
+ -webkit-box-align: stretch ;
+ -ms-flex-align: stretch ;
+ align-items: stretch ;
+ }
+
+ .align-content-md-start {
+ -ms-flex-line-pack: start ;
+ align-content: flex-start ;
+ }
+
+ .align-content-md-end {
+ -ms-flex-line-pack: end ;
+ align-content: flex-end ;
+ }
+
+ .align-content-md-center {
+ -ms-flex-line-pack: center ;
+ align-content: center ;
+ }
+
+ .align-content-md-between {
+ -ms-flex-line-pack: justify ;
+ align-content: space-between ;
+ }
+
+ .align-content-md-around {
+ -ms-flex-line-pack: distribute ;
+ align-content: space-around ;
+ }
+
+ .align-content-md-stretch {
+ -ms-flex-line-pack: stretch ;
+ align-content: stretch ;
+ }
+
+ .align-self-md-auto {
+ -ms-flex-item-align: auto ;
+ align-self: auto ;
+ }
+
+ .align-self-md-start {
+ -ms-flex-item-align: start ;
+ align-self: flex-start ;
+ }
+
+ .align-self-md-end {
+ -ms-flex-item-align: end ;
+ align-self: flex-end ;
+ }
+
+ .align-self-md-center {
+ -ms-flex-item-align: center ;
+ align-self: center ;
+ }
+
+ .align-self-md-baseline {
+ -ms-flex-item-align: baseline ;
+ align-self: baseline ;
+ }
+
+ .align-self-md-stretch {
+ -ms-flex-item-align: stretch ;
+ align-self: stretch ;
+ }
+
+ .order-md-first {
+ -webkit-box-ordinal-group: 0 ;
+ -ms-flex-order: -1 ;
+ order: -1 ;
+ }
+
+ .order-md-0 {
+ -webkit-box-ordinal-group: 1 ;
+ -ms-flex-order: 0 ;
+ order: 0 ;
+ }
+
+ .order-md-1 {
+ -webkit-box-ordinal-group: 2 ;
+ -ms-flex-order: 1 ;
+ order: 1 ;
+ }
+
+ .order-md-2 {
+ -webkit-box-ordinal-group: 3 ;
+ -ms-flex-order: 2 ;
+ order: 2 ;
+ }
+
+ .order-md-3 {
+ -webkit-box-ordinal-group: 4 ;
+ -ms-flex-order: 3 ;
+ order: 3 ;
+ }
+
+ .order-md-4 {
+ -webkit-box-ordinal-group: 5 ;
+ -ms-flex-order: 4 ;
+ order: 4 ;
+ }
+
+ .order-md-5 {
+ -webkit-box-ordinal-group: 6 ;
+ -ms-flex-order: 5 ;
+ order: 5 ;
+ }
+
+ .order-md-last {
+ -webkit-box-ordinal-group: 7 ;
+ -ms-flex-order: 6 ;
+ order: 6 ;
+ }
+
+ .m-md-0 {
+ margin: 0 ;
+ }
+
+ .m-md-1 {
+ margin: 0.25rem ;
+ }
+
+ .m-md-2 {
+ margin: 0.5rem ;
+ }
+
+ .m-md-3 {
+ margin: 1rem ;
+ }
+
+ .m-md-4 {
+ margin: 1.5rem ;
+ }
+
+ .m-md-5 {
+ margin: 3rem ;
+ }
+
+ .m-md-auto {
+ margin: auto ;
+ }
+
+ .mx-md-0 {
+ margin-right: 0 ;
+ margin-left: 0 ;
+ }
+
+ .mx-md-1 {
+ margin-right: 0.25rem ;
+ margin-left: 0.25rem ;
+ }
+
+ .mx-md-2 {
+ margin-right: 0.5rem ;
+ margin-left: 0.5rem ;
+ }
+
+ .mx-md-3 {
+ margin-right: 1rem ;
+ margin-left: 1rem ;
+ }
+
+ .mx-md-4 {
+ margin-right: 1.5rem ;
+ margin-left: 1.5rem ;
+ }
+
+ .mx-md-5 {
+ margin-right: 3rem ;
+ margin-left: 3rem ;
+ }
+
+ .mx-md-auto {
+ margin-right: auto ;
+ margin-left: auto ;
+ }
+
+ .my-md-0 {
+ margin-top: 0 ;
+ margin-bottom: 0 ;
+ }
+
+ .my-md-1 {
+ margin-top: 0.25rem ;
+ margin-bottom: 0.25rem ;
+ }
+
+ .my-md-2 {
+ margin-top: 0.5rem ;
+ margin-bottom: 0.5rem ;
+ }
+
+ .my-md-3 {
+ margin-top: 1rem ;
+ margin-bottom: 1rem ;
+ }
+
+ .my-md-4 {
+ margin-top: 1.5rem ;
+ margin-bottom: 1.5rem ;
+ }
+
+ .my-md-5 {
+ margin-top: 3rem ;
+ margin-bottom: 3rem ;
+ }
+
+ .my-md-auto {
+ margin-top: auto ;
+ margin-bottom: auto ;
+ }
+
+ .mt-md-0 {
+ margin-top: 0 ;
+ }
+
+ .mt-md-1 {
+ margin-top: 0.25rem ;
+ }
+
+ .mt-md-2 {
+ margin-top: 0.5rem ;
+ }
+
+ .mt-md-3 {
+ margin-top: 1rem ;
+ }
+
+ .mt-md-4 {
+ margin-top: 1.5rem ;
+ }
+
+ .mt-md-5 {
+ margin-top: 3rem ;
+ }
+
+ .mt-md-auto {
+ margin-top: auto ;
+ }
+
+ .me-md-0 {
+ margin-right: 0 ;
+ }
+
+ .me-md-1 {
+ margin-right: 0.25rem ;
+ }
+
+ .me-md-2 {
+ margin-right: 0.5rem ;
+ }
+
+ .me-md-3 {
+ margin-right: 1rem ;
+ }
+
+ .me-md-4 {
+ margin-right: 1.5rem ;
+ }
+
+ .me-md-5 {
+ margin-right: 3rem ;
+ }
+
+ .me-md-auto {
+ margin-right: auto ;
+ }
+
+ .mb-md-0 {
+ margin-bottom: 0 ;
+ }
+
+ .mb-md-1 {
+ margin-bottom: 0.25rem ;
+ }
+
+ .mb-md-2 {
+ margin-bottom: 0.5rem ;
+ }
+
+ .mb-md-3 {
+ margin-bottom: 1rem ;
+ }
+
+ .mb-md-4 {
+ margin-bottom: 1.5rem ;
+ }
+
+ .mb-md-5 {
+ margin-bottom: 3rem ;
+ }
+
+ .mb-md-auto {
+ margin-bottom: auto ;
+ }
+
+ .ms-md-0 {
+ margin-left: 0 ;
+ }
+
+ .ms-md-1 {
+ margin-left: 0.25rem ;
+ }
+
+ .ms-md-2 {
+ margin-left: 0.5rem ;
+ }
+
+ .ms-md-3 {
+ margin-left: 1rem ;
+ }
+
+ .ms-md-4 {
+ margin-left: 1.5rem ;
+ }
+
+ .ms-md-5 {
+ margin-left: 3rem ;
+ }
+
+ .ms-md-auto {
+ margin-left: auto ;
+ }
+
+ .p-md-0 {
+ padding: 0 ;
+ }
+
+ .p-md-1 {
+ padding: 0.25rem ;
+ }
+
+ .p-md-2 {
+ padding: 0.5rem ;
+ }
+
+ .p-md-3 {
+ padding: 1rem ;
+ }
+
+ .p-md-4 {
+ padding: 1.5rem ;
+ }
+
+ .p-md-5 {
+ padding: 3rem ;
+ }
+
+ .px-md-0 {
+ padding-right: 0 ;
+ padding-left: 0 ;
+ }
+
+ .px-md-1 {
+ padding-right: 0.25rem ;
+ padding-left: 0.25rem ;
+ }
+
+ .px-md-2 {
+ padding-right: 0.5rem ;
+ padding-left: 0.5rem ;
+ }
+
+ .px-md-3 {
+ padding-right: 1rem ;
+ padding-left: 1rem ;
+ }
+
+ .px-md-4 {
+ padding-right: 1.5rem ;
+ padding-left: 1.5rem ;
+ }
+
+ .px-md-5 {
+ padding-right: 3rem ;
+ padding-left: 3rem ;
+ }
+
+ .py-md-0 {
+ padding-top: 0 ;
+ padding-bottom: 0 ;
+ }
+
+ .py-md-1 {
+ padding-top: 0.25rem ;
+ padding-bottom: 0.25rem ;
+ }
+
+ .py-md-2 {
+ padding-top: 0.5rem ;
+ padding-bottom: 0.5rem ;
+ }
+
+ .py-md-3 {
+ padding-top: 1rem ;
+ padding-bottom: 1rem ;
+ }
+
+ .py-md-4 {
+ padding-top: 1.5rem ;
+ padding-bottom: 1.5rem ;
+ }
+
+ .py-md-5 {
+ padding-top: 3rem ;
+ padding-bottom: 3rem ;
+ }
+
+ .pt-md-0 {
+ padding-top: 0 ;
+ }
+
+ .pt-md-1 {
+ padding-top: 0.25rem ;
+ }
+
+ .pt-md-2 {
+ padding-top: 0.5rem ;
+ }
+
+ .pt-md-3 {
+ padding-top: 1rem ;
+ }
+
+ .pt-md-4 {
+ padding-top: 1.5rem ;
+ }
+
+ .pt-md-5 {
+ padding-top: 3rem ;
+ }
+
+ .pe-md-0 {
+ padding-right: 0 ;
+ }
+
+ .pe-md-1 {
+ padding-right: 0.25rem ;
+ }
+
+ .pe-md-2 {
+ padding-right: 0.5rem ;
+ }
+
+ .pe-md-3 {
+ padding-right: 1rem ;
+ }
+
+ .pe-md-4 {
+ padding-right: 1.5rem ;
+ }
+
+ .pe-md-5 {
+ padding-right: 3rem ;
+ }
+
+ .pb-md-0 {
+ padding-bottom: 0 ;
+ }
+
+ .pb-md-1 {
+ padding-bottom: 0.25rem ;
+ }
+
+ .pb-md-2 {
+ padding-bottom: 0.5rem ;
+ }
+
+ .pb-md-3 {
+ padding-bottom: 1rem ;
+ }
+
+ .pb-md-4 {
+ padding-bottom: 1.5rem ;
+ }
+
+ .pb-md-5 {
+ padding-bottom: 3rem ;
+ }
+
+ .ps-md-0 {
+ padding-left: 0 ;
+ }
+
+ .ps-md-1 {
+ padding-left: 0.25rem ;
+ }
+
+ .ps-md-2 {
+ padding-left: 0.5rem ;
+ }
+
+ .ps-md-3 {
+ padding-left: 1rem ;
+ }
+
+ .ps-md-4 {
+ padding-left: 1.5rem ;
+ }
+
+ .ps-md-5 {
+ padding-left: 3rem ;
+ }
+
+ .gap-md-0 {
+ gap: 0 ;
+ }
+
+ .gap-md-1 {
+ gap: 0.25rem ;
+ }
+
+ .gap-md-2 {
+ gap: 0.5rem ;
+ }
+
+ .gap-md-3 {
+ gap: 1rem ;
+ }
+
+ .gap-md-4 {
+ gap: 1.5rem ;
+ }
+
+ .gap-md-5 {
+ gap: 3rem ;
+ }
+
+ .text-md-start {
+ text-align: left ;
+ }
+
+ .text-md-end {
+ text-align: right ;
+ }
+
+ .text-md-center {
+ text-align: center ;
+ }
+}
+
+@media (min-width: 992px) {
+ .float-lg-start {
+ float: left ;
+ }
+
+ .float-lg-end {
+ float: right ;
+ }
+
+ .float-lg-none {
+ float: none ;
+ }
+
+ .d-lg-inline {
+ display: inline ;
+ }
+
+ .d-lg-inline-block {
+ display: inline-block ;
+ }
+
+ .d-lg-block {
+ display: block ;
+ }
+
+ .d-lg-grid {
+ display: grid ;
+ }
+
+ .d-lg-table {
+ display: table ;
+ }
+
+ .d-lg-table-row {
+ display: table-row ;
+ }
+
+ .d-lg-table-cell {
+ display: table-cell ;
+ }
+
+ .d-lg-flex {
+ display: -webkit-box ;
+ display: -ms-flexbox ;
+ display: flex ;
+ }
+
+ .d-lg-inline-flex {
+ display: -webkit-inline-box ;
+ display: -ms-inline-flexbox ;
+ display: inline-flex ;
+ }
+
+ .d-lg-none {
+ display: none ;
+ }
+
+ .flex-lg-fill {
+ -webkit-box-flex: 1 ;
+ -ms-flex: 1 1 auto ;
+ flex: 1 1 auto ;
+ }
+
+ .flex-lg-row {
+ -webkit-box-orient: horizontal ;
+ -webkit-box-direction: normal ;
+ -ms-flex-direction: row ;
+ flex-direction: row ;
+ }
+
+ .flex-lg-column {
+ -webkit-box-orient: vertical ;
+ -webkit-box-direction: normal ;
+ -ms-flex-direction: column ;
+ flex-direction: column ;
+ }
+
+ .flex-lg-row-reverse {
+ -webkit-box-orient: horizontal ;
+ -webkit-box-direction: reverse ;
+ -ms-flex-direction: row-reverse ;
+ flex-direction: row-reverse ;
+ }
+
+ .flex-lg-column-reverse {
+ -webkit-box-orient: vertical ;
+ -webkit-box-direction: reverse ;
+ -ms-flex-direction: column-reverse ;
+ flex-direction: column-reverse ;
+ }
+
+ .flex-lg-grow-0 {
+ -webkit-box-flex: 0 ;
+ -ms-flex-positive: 0 ;
+ flex-grow: 0 ;
+ }
+
+ .flex-lg-grow-1 {
+ -webkit-box-flex: 1 ;
+ -ms-flex-positive: 1 ;
+ flex-grow: 1 ;
+ }
+
+ .flex-lg-shrink-0 {
+ -ms-flex-negative: 0 ;
+ flex-shrink: 0 ;
+ }
+
+ .flex-lg-shrink-1 {
+ -ms-flex-negative: 1 ;
+ flex-shrink: 1 ;
+ }
+
+ .flex-lg-wrap {
+ -ms-flex-wrap: wrap ;
+ flex-wrap: wrap ;
+ }
+
+ .flex-lg-nowrap {
+ -ms-flex-wrap: nowrap ;
+ flex-wrap: nowrap ;
+ }
+
+ .flex-lg-wrap-reverse {
+ -ms-flex-wrap: wrap-reverse ;
+ flex-wrap: wrap-reverse ;
+ }
+
+ .justify-content-lg-start {
+ -webkit-box-pack: start ;
+ -ms-flex-pack: start ;
+ justify-content: flex-start ;
+ }
+
+ .justify-content-lg-end {
+ -webkit-box-pack: end ;
+ -ms-flex-pack: end ;
+ justify-content: flex-end ;
+ }
+
+ .justify-content-lg-center {
+ -webkit-box-pack: center ;
+ -ms-flex-pack: center ;
+ justify-content: center ;
+ }
+
+ .justify-content-lg-between {
+ -webkit-box-pack: justify ;
+ -ms-flex-pack: justify ;
+ justify-content: space-between ;
+ }
+
+ .justify-content-lg-around {
+ -ms-flex-pack: distribute ;
+ justify-content: space-around ;
+ }
+
+ .justify-content-lg-evenly {
+ -webkit-box-pack: space-evenly ;
+ -ms-flex-pack: space-evenly ;
+ justify-content: space-evenly ;
+ }
+
+ .align-items-lg-start {
+ -webkit-box-align: start ;
+ -ms-flex-align: start ;
+ align-items: flex-start ;
+ }
+
+ .align-items-lg-end {
+ -webkit-box-align: end ;
+ -ms-flex-align: end ;
+ align-items: flex-end ;
+ }
+
+ .align-items-lg-center {
+ -webkit-box-align: center ;
+ -ms-flex-align: center ;
+ align-items: center ;
+ }
+
+ .align-items-lg-baseline {
+ -webkit-box-align: baseline ;
+ -ms-flex-align: baseline ;
+ align-items: baseline ;
+ }
+
+ .align-items-lg-stretch {
+ -webkit-box-align: stretch ;
+ -ms-flex-align: stretch ;
+ align-items: stretch ;
+ }
+
+ .align-content-lg-start {
+ -ms-flex-line-pack: start ;
+ align-content: flex-start ;
+ }
+
+ .align-content-lg-end {
+ -ms-flex-line-pack: end ;
+ align-content: flex-end ;
+ }
+
+ .align-content-lg-center {
+ -ms-flex-line-pack: center ;
+ align-content: center ;
+ }
+
+ .align-content-lg-between {
+ -ms-flex-line-pack: justify ;
+ align-content: space-between ;
+ }
+
+ .align-content-lg-around {
+ -ms-flex-line-pack: distribute ;
+ align-content: space-around ;
+ }
+
+ .align-content-lg-stretch {
+ -ms-flex-line-pack: stretch ;
+ align-content: stretch ;
+ }
+
+ .align-self-lg-auto {
+ -ms-flex-item-align: auto ;
+ align-self: auto ;
+ }
+
+ .align-self-lg-start {
+ -ms-flex-item-align: start ;
+ align-self: flex-start ;
+ }
+
+ .align-self-lg-end {
+ -ms-flex-item-align: end ;
+ align-self: flex-end ;
+ }
+
+ .align-self-lg-center {
+ -ms-flex-item-align: center ;
+ align-self: center ;
+ }
+
+ .align-self-lg-baseline {
+ -ms-flex-item-align: baseline ;
+ align-self: baseline ;
+ }
+
+ .align-self-lg-stretch {
+ -ms-flex-item-align: stretch ;
+ align-self: stretch ;
+ }
+
+ .order-lg-first {
+ -webkit-box-ordinal-group: 0 ;
+ -ms-flex-order: -1 ;
+ order: -1 ;
+ }
+
+ .order-lg-0 {
+ -webkit-box-ordinal-group: 1 ;
+ -ms-flex-order: 0 ;
+ order: 0 ;
+ }
+
+ .order-lg-1 {
+ -webkit-box-ordinal-group: 2 ;
+ -ms-flex-order: 1 ;
+ order: 1 ;
+ }
+
+ .order-lg-2 {
+ -webkit-box-ordinal-group: 3 ;
+ -ms-flex-order: 2 ;
+ order: 2 ;
+ }
+
+ .order-lg-3 {
+ -webkit-box-ordinal-group: 4 ;
+ -ms-flex-order: 3 ;
+ order: 3 ;
+ }
+
+ .order-lg-4 {
+ -webkit-box-ordinal-group: 5 ;
+ -ms-flex-order: 4 ;
+ order: 4 ;
+ }
+
+ .order-lg-5 {
+ -webkit-box-ordinal-group: 6 ;
+ -ms-flex-order: 5 ;
+ order: 5 ;
+ }
+
+ .order-lg-last {
+ -webkit-box-ordinal-group: 7 ;
+ -ms-flex-order: 6 ;
+ order: 6 ;
+ }
+
+ .m-lg-0 {
+ margin: 0 ;
+ }
+
+ .m-lg-1 {
+ margin: 0.25rem ;
+ }
+
+ .m-lg-2 {
+ margin: 0.5rem ;
+ }
+
+ .m-lg-3 {
+ margin: 1rem ;
+ }
+
+ .m-lg-4 {
+ margin: 1.5rem ;
+ }
+
+ .m-lg-5 {
+ margin: 3rem ;
+ }
+
+ .m-lg-auto {
+ margin: auto ;
+ }
+
+ .mx-lg-0 {
+ margin-right: 0 ;
+ margin-left: 0 ;
+ }
+
+ .mx-lg-1 {
+ margin-right: 0.25rem ;
+ margin-left: 0.25rem ;
+ }
+
+ .mx-lg-2 {
+ margin-right: 0.5rem ;
+ margin-left: 0.5rem ;
+ }
+
+ .mx-lg-3 {
+ margin-right: 1rem ;
+ margin-left: 1rem ;
+ }
+
+ .mx-lg-4 {
+ margin-right: 1.5rem ;
+ margin-left: 1.5rem ;
+ }
+
+ .mx-lg-5 {
+ margin-right: 3rem ;
+ margin-left: 3rem ;
+ }
+
+ .mx-lg-auto {
+ margin-right: auto ;
+ margin-left: auto ;
+ }
+
+ .my-lg-0 {
+ margin-top: 0 ;
+ margin-bottom: 0 ;
+ }
+
+ .my-lg-1 {
+ margin-top: 0.25rem ;
+ margin-bottom: 0.25rem ;
+ }
+
+ .my-lg-2 {
+ margin-top: 0.5rem ;
+ margin-bottom: 0.5rem ;
+ }
+
+ .my-lg-3 {
+ margin-top: 1rem ;
+ margin-bottom: 1rem ;
+ }
+
+ .my-lg-4 {
+ margin-top: 1.5rem ;
+ margin-bottom: 1.5rem ;
+ }
+
+ .my-lg-5 {
+ margin-top: 3rem ;
+ margin-bottom: 3rem ;
+ }
+
+ .my-lg-auto {
+ margin-top: auto ;
+ margin-bottom: auto ;
+ }
+
+ .mt-lg-0 {
+ margin-top: 0 ;
+ }
+
+ .mt-lg-1 {
+ margin-top: 0.25rem ;
+ }
+
+ .mt-lg-2 {
+ margin-top: 0.5rem ;
+ }
+
+ .mt-lg-3 {
+ margin-top: 1rem ;
+ }
+
+ .mt-lg-4 {
+ margin-top: 1.5rem ;
+ }
+
+ .mt-lg-5 {
+ margin-top: 3rem ;
+ }
+
+ .mt-lg-auto {
+ margin-top: auto ;
+ }
+
+ .me-lg-0 {
+ margin-right: 0 ;
+ }
+
+ .me-lg-1 {
+ margin-right: 0.25rem ;
+ }
+
+ .me-lg-2 {
+ margin-right: 0.5rem ;
+ }
+
+ .me-lg-3 {
+ margin-right: 1rem ;
+ }
+
+ .me-lg-4 {
+ margin-right: 1.5rem ;
+ }
+
+ .me-lg-5 {
+ margin-right: 3rem ;
+ }
+
+ .me-lg-auto {
+ margin-right: auto ;
+ }
+
+ .mb-lg-0 {
+ margin-bottom: 0 ;
+ }
+
+ .mb-lg-1 {
+ margin-bottom: 0.25rem ;
+ }
+
+ .mb-lg-2 {
+ margin-bottom: 0.5rem ;
+ }
+
+ .mb-lg-3 {
+ margin-bottom: 1rem ;
+ }
+
+ .mb-lg-4 {
+ margin-bottom: 1.5rem ;
+ }
+
+ .mb-lg-5 {
+ margin-bottom: 3rem ;
+ }
+
+ .mb-lg-auto {
+ margin-bottom: auto ;
+ }
+
+ .ms-lg-0 {
+ margin-left: 0 ;
+ }
+
+ .ms-lg-1 {
+ margin-left: 0.25rem ;
+ }
+
+ .ms-lg-2 {
+ margin-left: 0.5rem ;
+ }
+
+ .ms-lg-3 {
+ margin-left: 1rem ;
+ }
+
+ .ms-lg-4 {
+ margin-left: 1.5rem ;
+ }
+
+ .ms-lg-5 {
+ margin-left: 3rem ;
+ }
+
+ .ms-lg-auto {
+ margin-left: auto ;
+ }
+
+ .p-lg-0 {
+ padding: 0 ;
+ }
+
+ .p-lg-1 {
+ padding: 0.25rem ;
+ }
+
+ .p-lg-2 {
+ padding: 0.5rem ;
+ }
+
+ .p-lg-3 {
+ padding: 1rem ;
+ }
+
+ .p-lg-4 {
+ padding: 1.5rem ;
+ }
+
+ .p-lg-5 {
+ padding: 3rem ;
+ }
+
+ .px-lg-0 {
+ padding-right: 0 ;
+ padding-left: 0 ;
+ }
+
+ .px-lg-1 {
+ padding-right: 0.25rem ;
+ padding-left: 0.25rem ;
+ }
+
+ .px-lg-2 {
+ padding-right: 0.5rem ;
+ padding-left: 0.5rem ;
+ }
+
+ .px-lg-3 {
+ padding-right: 1rem ;
+ padding-left: 1rem ;
+ }
+
+ .px-lg-4 {
+ padding-right: 1.5rem ;
+ padding-left: 1.5rem ;
+ }
+
+ .px-lg-5 {
+ padding-right: 3rem ;
+ padding-left: 3rem ;
+ }
+
+ .py-lg-0 {
+ padding-top: 0 ;
+ padding-bottom: 0 ;
+ }
+
+ .py-lg-1 {
+ padding-top: 0.25rem ;
+ padding-bottom: 0.25rem ;
+ }
+
+ .py-lg-2 {
+ padding-top: 0.5rem ;
+ padding-bottom: 0.5rem ;
+ }
+
+ .py-lg-3 {
+ padding-top: 1rem ;
+ padding-bottom: 1rem ;
+ }
+
+ .py-lg-4 {
+ padding-top: 1.5rem ;
+ padding-bottom: 1.5rem ;
+ }
+
+ .py-lg-5 {
+ padding-top: 3rem ;
+ padding-bottom: 3rem ;
+ }
+
+ .pt-lg-0 {
+ padding-top: 0 ;
+ }
+
+ .pt-lg-1 {
+ padding-top: 0.25rem ;
+ }
+
+ .pt-lg-2 {
+ padding-top: 0.5rem ;
+ }
+
+ .pt-lg-3 {
+ padding-top: 1rem ;
+ }
+
+ .pt-lg-4 {
+ padding-top: 1.5rem ;
+ }
+
+ .pt-lg-5 {
+ padding-top: 3rem ;
+ }
+
+ .pe-lg-0 {
+ padding-right: 0 ;
+ }
+
+ .pe-lg-1 {
+ padding-right: 0.25rem ;
+ }
+
+ .pe-lg-2 {
+ padding-right: 0.5rem ;
+ }
+
+ .pe-lg-3 {
+ padding-right: 1rem ;
+ }
+
+ .pe-lg-4 {
+ padding-right: 1.5rem ;
+ }
+
+ .pe-lg-5 {
+ padding-right: 3rem ;
+ }
+
+ .pb-lg-0 {
+ padding-bottom: 0 ;
+ }
+
+ .pb-lg-1 {
+ padding-bottom: 0.25rem ;
+ }
+
+ .pb-lg-2 {
+ padding-bottom: 0.5rem ;
+ }
+
+ .pb-lg-3 {
+ padding-bottom: 1rem ;
+ }
+
+ .pb-lg-4 {
+ padding-bottom: 1.5rem ;
+ }
+
+ .pb-lg-5 {
+ padding-bottom: 3rem ;
+ }
+
+ .ps-lg-0 {
+ padding-left: 0 ;
+ }
+
+ .ps-lg-1 {
+ padding-left: 0.25rem ;
+ }
+
+ .ps-lg-2 {
+ padding-left: 0.5rem ;
+ }
+
+ .ps-lg-3 {
+ padding-left: 1rem ;
+ }
+
+ .ps-lg-4 {
+ padding-left: 1.5rem ;
+ }
+
+ .ps-lg-5 {
+ padding-left: 3rem ;
+ }
+
+ .gap-lg-0 {
+ gap: 0 ;
+ }
+
+ .gap-lg-1 {
+ gap: 0.25rem ;
+ }
+
+ .gap-lg-2 {
+ gap: 0.5rem ;
+ }
+
+ .gap-lg-3 {
+ gap: 1rem ;
+ }
+
+ .gap-lg-4 {
+ gap: 1.5rem ;
+ }
+
+ .gap-lg-5 {
+ gap: 3rem ;
+ }
+
+ .text-lg-start {
+ text-align: left ;
+ }
+
+ .text-lg-end {
+ text-align: right ;
+ }
+
+ .text-lg-center {
+ text-align: center ;
+ }
+}
+
+@media (min-width: 1200px) {
+ .float-xl-start {
+ float: left ;
+ }
+
+ .float-xl-end {
+ float: right ;
+ }
+
+ .float-xl-none {
+ float: none ;
+ }
+
+ .d-xl-inline {
+ display: inline ;
+ }
+
+ .d-xl-inline-block {
+ display: inline-block ;
+ }
+
+ .d-xl-block {
+ display: block ;
+ }
+
+ .d-xl-grid {
+ display: grid ;
+ }
+
+ .d-xl-table {
+ display: table ;
+ }
+
+ .d-xl-table-row {
+ display: table-row ;
+ }
+
+ .d-xl-table-cell {
+ display: table-cell ;
+ }
+
+ .d-xl-flex {
+ display: -webkit-box ;
+ display: -ms-flexbox ;
+ display: flex ;
+ }
+
+ .d-xl-inline-flex {
+ display: -webkit-inline-box ;
+ display: -ms-inline-flexbox ;
+ display: inline-flex ;
+ }
+
+ .d-xl-none {
+ display: none ;
+ }
+
+ .flex-xl-fill {
+ -webkit-box-flex: 1 ;
+ -ms-flex: 1 1 auto ;
+ flex: 1 1 auto ;
+ }
+
+ .flex-xl-row {
+ -webkit-box-orient: horizontal ;
+ -webkit-box-direction: normal ;
+ -ms-flex-direction: row ;
+ flex-direction: row ;
+ }
+
+ .flex-xl-column {
+ -webkit-box-orient: vertical ;
+ -webkit-box-direction: normal ;
+ -ms-flex-direction: column ;
+ flex-direction: column ;
+ }
+
+ .flex-xl-row-reverse {
+ -webkit-box-orient: horizontal ;
+ -webkit-box-direction: reverse ;
+ -ms-flex-direction: row-reverse ;
+ flex-direction: row-reverse ;
+ }
+
+ .flex-xl-column-reverse {
+ -webkit-box-orient: vertical ;
+ -webkit-box-direction: reverse ;
+ -ms-flex-direction: column-reverse ;
+ flex-direction: column-reverse ;
+ }
+
+ .flex-xl-grow-0 {
+ -webkit-box-flex: 0 ;
+ -ms-flex-positive: 0 ;
+ flex-grow: 0 ;
+ }
+
+ .flex-xl-grow-1 {
+ -webkit-box-flex: 1 ;
+ -ms-flex-positive: 1 ;
+ flex-grow: 1 ;
+ }
+
+ .flex-xl-shrink-0 {
+ -ms-flex-negative: 0 ;
+ flex-shrink: 0 ;
+ }
+
+ .flex-xl-shrink-1 {
+ -ms-flex-negative: 1 ;
+ flex-shrink: 1 ;
+ }
+
+ .flex-xl-wrap {
+ -ms-flex-wrap: wrap ;
+ flex-wrap: wrap ;
+ }
+
+ .flex-xl-nowrap {
+ -ms-flex-wrap: nowrap ;
+ flex-wrap: nowrap ;
+ }
+
+ .flex-xl-wrap-reverse {
+ -ms-flex-wrap: wrap-reverse ;
+ flex-wrap: wrap-reverse ;
+ }
+
+ .justify-content-xl-start {
+ -webkit-box-pack: start ;
+ -ms-flex-pack: start ;
+ justify-content: flex-start ;
+ }
+
+ .justify-content-xl-end {
+ -webkit-box-pack: end ;
+ -ms-flex-pack: end ;
+ justify-content: flex-end ;
+ }
+
+ .justify-content-xl-center {
+ -webkit-box-pack: center ;
+ -ms-flex-pack: center ;
+ justify-content: center ;
+ }
+
+ .justify-content-xl-between {
+ -webkit-box-pack: justify ;
+ -ms-flex-pack: justify ;
+ justify-content: space-between ;
+ }
+
+ .justify-content-xl-around {
+ -ms-flex-pack: distribute ;
+ justify-content: space-around ;
+ }
+
+ .justify-content-xl-evenly {
+ -webkit-box-pack: space-evenly ;
+ -ms-flex-pack: space-evenly ;
+ justify-content: space-evenly ;
+ }
+
+ .align-items-xl-start {
+ -webkit-box-align: start ;
+ -ms-flex-align: start ;
+ align-items: flex-start ;
+ }
+
+ .align-items-xl-end {
+ -webkit-box-align: end ;
+ -ms-flex-align: end ;
+ align-items: flex-end ;
+ }
+
+ .align-items-xl-center {
+ -webkit-box-align: center ;
+ -ms-flex-align: center ;
+ align-items: center ;
+ }
+
+ .align-items-xl-baseline {
+ -webkit-box-align: baseline ;
+ -ms-flex-align: baseline ;
+ align-items: baseline ;
+ }
+
+ .align-items-xl-stretch {
+ -webkit-box-align: stretch ;
+ -ms-flex-align: stretch ;
+ align-items: stretch ;
+ }
+
+ .align-content-xl-start {
+ -ms-flex-line-pack: start ;
+ align-content: flex-start ;
+ }
+
+ .align-content-xl-end {
+ -ms-flex-line-pack: end ;
+ align-content: flex-end ;
+ }
+
+ .align-content-xl-center {
+ -ms-flex-line-pack: center ;
+ align-content: center ;
+ }
+
+ .align-content-xl-between {
+ -ms-flex-line-pack: justify ;
+ align-content: space-between ;
+ }
+
+ .align-content-xl-around {
+ -ms-flex-line-pack: distribute ;
+ align-content: space-around ;
+ }
+
+ .align-content-xl-stretch {
+ -ms-flex-line-pack: stretch ;
+ align-content: stretch ;
+ }
+
+ .align-self-xl-auto {
+ -ms-flex-item-align: auto ;
+ align-self: auto ;
+ }
+
+ .align-self-xl-start {
+ -ms-flex-item-align: start ;
+ align-self: flex-start ;
+ }
+
+ .align-self-xl-end {
+ -ms-flex-item-align: end ;
+ align-self: flex-end ;
+ }
+
+ .align-self-xl-center {
+ -ms-flex-item-align: center ;
+ align-self: center ;
+ }
+
+ .align-self-xl-baseline {
+ -ms-flex-item-align: baseline ;
+ align-self: baseline ;
+ }
+
+ .align-self-xl-stretch {
+ -ms-flex-item-align: stretch ;
+ align-self: stretch ;
+ }
+
+ .order-xl-first {
+ -webkit-box-ordinal-group: 0 ;
+ -ms-flex-order: -1 ;
+ order: -1 ;
+ }
+
+ .order-xl-0 {
+ -webkit-box-ordinal-group: 1 ;
+ -ms-flex-order: 0 ;
+ order: 0 ;
+ }
+
+ .order-xl-1 {
+ -webkit-box-ordinal-group: 2 ;
+ -ms-flex-order: 1 ;
+ order: 1 ;
+ }
+
+ .order-xl-2 {
+ -webkit-box-ordinal-group: 3 ;
+ -ms-flex-order: 2 ;
+ order: 2 ;
+ }
+
+ .order-xl-3 {
+ -webkit-box-ordinal-group: 4 ;
+ -ms-flex-order: 3 ;
+ order: 3 ;
+ }
+
+ .order-xl-4 {
+ -webkit-box-ordinal-group: 5 ;
+ -ms-flex-order: 4 ;
+ order: 4 ;
+ }
+
+ .order-xl-5 {
+ -webkit-box-ordinal-group: 6 ;
+ -ms-flex-order: 5 ;
+ order: 5 ;
+ }
+
+ .order-xl-last {
+ -webkit-box-ordinal-group: 7 ;
+ -ms-flex-order: 6 ;
+ order: 6 ;
+ }
+
+ .m-xl-0 {
+ margin: 0 ;
+ }
+
+ .m-xl-1 {
+ margin: 0.25rem ;
+ }
+
+ .m-xl-2 {
+ margin: 0.5rem ;
+ }
+
+ .m-xl-3 {
+ margin: 1rem ;
+ }
+
+ .m-xl-4 {
+ margin: 1.5rem ;
+ }
+
+ .m-xl-5 {
+ margin: 3rem ;
+ }
+
+ .m-xl-auto {
+ margin: auto ;
+ }
+
+ .mx-xl-0 {
+ margin-right: 0 ;
+ margin-left: 0 ;
+ }
+
+ .mx-xl-1 {
+ margin-right: 0.25rem ;
+ margin-left: 0.25rem ;
+ }
+
+ .mx-xl-2 {
+ margin-right: 0.5rem ;
+ margin-left: 0.5rem ;
+ }
+
+ .mx-xl-3 {
+ margin-right: 1rem ;
+ margin-left: 1rem ;
+ }
+
+ .mx-xl-4 {
+ margin-right: 1.5rem ;
+ margin-left: 1.5rem ;
+ }
+
+ .mx-xl-5 {
+ margin-right: 3rem ;
+ margin-left: 3rem ;
+ }
+
+ .mx-xl-auto {
+ margin-right: auto ;
+ margin-left: auto ;
+ }
+
+ .my-xl-0 {
+ margin-top: 0 ;
+ margin-bottom: 0 ;
+ }
+
+ .my-xl-1 {
+ margin-top: 0.25rem ;
+ margin-bottom: 0.25rem ;
+ }
+
+ .my-xl-2 {
+ margin-top: 0.5rem ;
+ margin-bottom: 0.5rem ;
+ }
+
+ .my-xl-3 {
+ margin-top: 1rem ;
+ margin-bottom: 1rem ;
+ }
+
+ .my-xl-4 {
+ margin-top: 1.5rem ;
+ margin-bottom: 1.5rem ;
+ }
+
+ .my-xl-5 {
+ margin-top: 3rem ;
+ margin-bottom: 3rem ;
+ }
+
+ .my-xl-auto {
+ margin-top: auto ;
+ margin-bottom: auto ;
+ }
+
+ .mt-xl-0 {
+ margin-top: 0 ;
+ }
+
+ .mt-xl-1 {
+ margin-top: 0.25rem ;
+ }
+
+ .mt-xl-2 {
+ margin-top: 0.5rem ;
+ }
+
+ .mt-xl-3 {
+ margin-top: 1rem ;
+ }
+
+ .mt-xl-4 {
+ margin-top: 1.5rem ;
+ }
+
+ .mt-xl-5 {
+ margin-top: 3rem ;
+ }
+
+ .mt-xl-auto {
+ margin-top: auto ;
+ }
+
+ .me-xl-0 {
+ margin-right: 0 ;
+ }
+
+ .me-xl-1 {
+ margin-right: 0.25rem ;
+ }
+
+ .me-xl-2 {
+ margin-right: 0.5rem ;
+ }
+
+ .me-xl-3 {
+ margin-right: 1rem ;
+ }
+
+ .me-xl-4 {
+ margin-right: 1.5rem ;
+ }
+
+ .me-xl-5 {
+ margin-right: 3rem ;
+ }
+
+ .me-xl-auto {
+ margin-right: auto ;
+ }
+
+ .mb-xl-0 {
+ margin-bottom: 0 ;
+ }
+
+ .mb-xl-1 {
+ margin-bottom: 0.25rem ;
+ }
+
+ .mb-xl-2 {
+ margin-bottom: 0.5rem ;
+ }
+
+ .mb-xl-3 {
+ margin-bottom: 1rem ;
+ }
+
+ .mb-xl-4 {
+ margin-bottom: 1.5rem ;
+ }
+
+ .mb-xl-5 {
+ margin-bottom: 3rem ;
+ }
+
+ .mb-xl-auto {
+ margin-bottom: auto ;
+ }
+
+ .ms-xl-0 {
+ margin-left: 0 ;
+ }
+
+ .ms-xl-1 {
+ margin-left: 0.25rem ;
+ }
+
+ .ms-xl-2 {
+ margin-left: 0.5rem ;
+ }
+
+ .ms-xl-3 {
+ margin-left: 1rem ;
+ }
+
+ .ms-xl-4 {
+ margin-left: 1.5rem ;
+ }
+
+ .ms-xl-5 {
+ margin-left: 3rem ;
+ }
+
+ .ms-xl-auto {
+ margin-left: auto ;
+ }
+
+ .p-xl-0 {
+ padding: 0 ;
+ }
+
+ .p-xl-1 {
+ padding: 0.25rem ;
+ }
+
+ .p-xl-2 {
+ padding: 0.5rem ;
+ }
+
+ .p-xl-3 {
+ padding: 1rem ;
+ }
+
+ .p-xl-4 {
+ padding: 1.5rem ;
+ }
+
+ .p-xl-5 {
+ padding: 3rem ;
+ }
+
+ .px-xl-0 {
+ padding-right: 0 ;
+ padding-left: 0 ;
+ }
+
+ .px-xl-1 {
+ padding-right: 0.25rem ;
+ padding-left: 0.25rem ;
+ }
+
+ .px-xl-2 {
+ padding-right: 0.5rem ;
+ padding-left: 0.5rem ;
+ }
+
+ .px-xl-3 {
+ padding-right: 1rem ;
+ padding-left: 1rem ;
+ }
+
+ .px-xl-4 {
+ padding-right: 1.5rem ;
+ padding-left: 1.5rem ;
+ }
+
+ .px-xl-5 {
+ padding-right: 3rem ;
+ padding-left: 3rem ;
+ }
+
+ .py-xl-0 {
+ padding-top: 0 ;
+ padding-bottom: 0 ;
+ }
+
+ .py-xl-1 {
+ padding-top: 0.25rem ;
+ padding-bottom: 0.25rem ;
+ }
+
+ .py-xl-2 {
+ padding-top: 0.5rem ;
+ padding-bottom: 0.5rem ;
+ }
+
+ .py-xl-3 {
+ padding-top: 1rem ;
+ padding-bottom: 1rem ;
+ }
+
+ .py-xl-4 {
+ padding-top: 1.5rem ;
+ padding-bottom: 1.5rem ;
+ }
+
+ .py-xl-5 {
+ padding-top: 3rem ;
+ padding-bottom: 3rem ;
+ }
+
+ .pt-xl-0 {
+ padding-top: 0 ;
+ }
+
+ .pt-xl-1 {
+ padding-top: 0.25rem ;
+ }
+
+ .pt-xl-2 {
+ padding-top: 0.5rem ;
+ }
+
+ .pt-xl-3 {
+ padding-top: 1rem ;
+ }
+
+ .pt-xl-4 {
+ padding-top: 1.5rem ;
+ }
+
+ .pt-xl-5 {
+ padding-top: 3rem ;
+ }
+
+ .pe-xl-0 {
+ padding-right: 0 ;
+ }
+
+ .pe-xl-1 {
+ padding-right: 0.25rem ;
+ }
+
+ .pe-xl-2 {
+ padding-right: 0.5rem ;
+ }
+
+ .pe-xl-3 {
+ padding-right: 1rem ;
+ }
+
+ .pe-xl-4 {
+ padding-right: 1.5rem ;
+ }
+
+ .pe-xl-5 {
+ padding-right: 3rem ;
+ }
+
+ .pb-xl-0 {
+ padding-bottom: 0 ;
+ }
+
+ .pb-xl-1 {
+ padding-bottom: 0.25rem ;
+ }
+
+ .pb-xl-2 {
+ padding-bottom: 0.5rem ;
+ }
+
+ .pb-xl-3 {
+ padding-bottom: 1rem ;
+ }
+
+ .pb-xl-4 {
+ padding-bottom: 1.5rem ;
+ }
+
+ .pb-xl-5 {
+ padding-bottom: 3rem ;
+ }
+
+ .ps-xl-0 {
+ padding-left: 0 ;
+ }
+
+ .ps-xl-1 {
+ padding-left: 0.25rem ;
+ }
+
+ .ps-xl-2 {
+ padding-left: 0.5rem ;
+ }
+
+ .ps-xl-3 {
+ padding-left: 1rem ;
+ }
+
+ .ps-xl-4 {
+ padding-left: 1.5rem ;
+ }
+
+ .ps-xl-5 {
+ padding-left: 3rem ;
+ }
+
+ .gap-xl-0 {
+ gap: 0 ;
+ }
+
+ .gap-xl-1 {
+ gap: 0.25rem ;
+ }
+
+ .gap-xl-2 {
+ gap: 0.5rem ;
+ }
+
+ .gap-xl-3 {
+ gap: 1rem ;
+ }
+
+ .gap-xl-4 {
+ gap: 1.5rem ;
+ }
+
+ .gap-xl-5 {
+ gap: 3rem ;
+ }
+
+ .text-xl-start {
+ text-align: left ;
+ }
+
+ .text-xl-end {
+ text-align: right ;
+ }
+
+ .text-xl-center {
+ text-align: center ;
+ }
+}
+
+@media (min-width: 1400px) {
+ .float-xxl-start {
+ float: left ;
+ }
+
+ .float-xxl-end {
+ float: right ;
+ }
+
+ .float-xxl-none {
+ float: none ;
+ }
+
+ .d-xxl-inline {
+ display: inline ;
+ }
+
+ .d-xxl-inline-block {
+ display: inline-block ;
+ }
+
+ .d-xxl-block {
+ display: block ;
+ }
+
+ .d-xxl-grid {
+ display: grid ;
+ }
+
+ .d-xxl-table {
+ display: table ;
+ }
+
+ .d-xxl-table-row {
+ display: table-row ;
+ }
+
+ .d-xxl-table-cell {
+ display: table-cell ;
+ }
+
+ .d-xxl-flex {
+ display: -webkit-box ;
+ display: -ms-flexbox ;
+ display: flex ;
+ }
+
+ .d-xxl-inline-flex {
+ display: -webkit-inline-box ;
+ display: -ms-inline-flexbox ;
+ display: inline-flex ;
+ }
+
+ .d-xxl-none {
+ display: none ;
+ }
+
+ .flex-xxl-fill {
+ -webkit-box-flex: 1 ;
+ -ms-flex: 1 1 auto ;
+ flex: 1 1 auto ;
+ }
+
+ .flex-xxl-row {
+ -webkit-box-orient: horizontal ;
+ -webkit-box-direction: normal ;
+ -ms-flex-direction: row ;
+ flex-direction: row ;
+ }
+
+ .flex-xxl-column {
+ -webkit-box-orient: vertical ;
+ -webkit-box-direction: normal ;
+ -ms-flex-direction: column ;
+ flex-direction: column ;
+ }
+
+ .flex-xxl-row-reverse {
+ -webkit-box-orient: horizontal ;
+ -webkit-box-direction: reverse ;
+ -ms-flex-direction: row-reverse ;
+ flex-direction: row-reverse ;
+ }
+
+ .flex-xxl-column-reverse {
+ -webkit-box-orient: vertical ;
+ -webkit-box-direction: reverse ;
+ -ms-flex-direction: column-reverse ;
+ flex-direction: column-reverse ;
+ }
+
+ .flex-xxl-grow-0 {
+ -webkit-box-flex: 0 ;
+ -ms-flex-positive: 0 ;
+ flex-grow: 0 ;
+ }
+
+ .flex-xxl-grow-1 {
+ -webkit-box-flex: 1 ;
+ -ms-flex-positive: 1 ;
+ flex-grow: 1 ;
+ }
+
+ .flex-xxl-shrink-0 {
+ -ms-flex-negative: 0 ;
+ flex-shrink: 0 ;
+ }
+
+ .flex-xxl-shrink-1 {
+ -ms-flex-negative: 1 ;
+ flex-shrink: 1 ;
+ }
+
+ .flex-xxl-wrap {
+ -ms-flex-wrap: wrap ;
+ flex-wrap: wrap ;
+ }
+
+ .flex-xxl-nowrap {
+ -ms-flex-wrap: nowrap ;
+ flex-wrap: nowrap ;
+ }
+
+ .flex-xxl-wrap-reverse {
+ -ms-flex-wrap: wrap-reverse ;
+ flex-wrap: wrap-reverse ;
+ }
+
+ .justify-content-xxl-start {
+ -webkit-box-pack: start ;
+ -ms-flex-pack: start ;
+ justify-content: flex-start ;
+ }
+
+ .justify-content-xxl-end {
+ -webkit-box-pack: end ;
+ -ms-flex-pack: end ;
+ justify-content: flex-end ;
+ }
+
+ .justify-content-xxl-center {
+ -webkit-box-pack: center ;
+ -ms-flex-pack: center ;
+ justify-content: center ;
+ }
+
+ .justify-content-xxl-between {
+ -webkit-box-pack: justify ;
+ -ms-flex-pack: justify ;
+ justify-content: space-between ;
+ }
+
+ .justify-content-xxl-around {
+ -ms-flex-pack: distribute ;
+ justify-content: space-around ;
+ }
+
+ .justify-content-xxl-evenly {
+ -webkit-box-pack: space-evenly ;
+ -ms-flex-pack: space-evenly ;
+ justify-content: space-evenly ;
+ }
+
+ .align-items-xxl-start {
+ -webkit-box-align: start ;
+ -ms-flex-align: start ;
+ align-items: flex-start ;
+ }
+
+ .align-items-xxl-end {
+ -webkit-box-align: end ;
+ -ms-flex-align: end ;
+ align-items: flex-end ;
+ }
+
+ .align-items-xxl-center {
+ -webkit-box-align: center ;
+ -ms-flex-align: center ;
+ align-items: center ;
+ }
+
+ .align-items-xxl-baseline {
+ -webkit-box-align: baseline ;
+ -ms-flex-align: baseline ;
+ align-items: baseline ;
+ }
+
+ .align-items-xxl-stretch {
+ -webkit-box-align: stretch ;
+ -ms-flex-align: stretch ;
+ align-items: stretch ;
+ }
+
+ .align-content-xxl-start {
+ -ms-flex-line-pack: start ;
+ align-content: flex-start ;
+ }
+
+ .align-content-xxl-end {
+ -ms-flex-line-pack: end ;
+ align-content: flex-end ;
+ }
+
+ .align-content-xxl-center {
+ -ms-flex-line-pack: center ;
+ align-content: center ;
+ }
+
+ .align-content-xxl-between {
+ -ms-flex-line-pack: justify ;
+ align-content: space-between ;
+ }
+
+ .align-content-xxl-around {
+ -ms-flex-line-pack: distribute ;
+ align-content: space-around ;
+ }
+
+ .align-content-xxl-stretch {
+ -ms-flex-line-pack: stretch ;
+ align-content: stretch ;
+ }
+
+ .align-self-xxl-auto {
+ -ms-flex-item-align: auto ;
+ align-self: auto ;
+ }
+
+ .align-self-xxl-start {
+ -ms-flex-item-align: start ;
+ align-self: flex-start ;
+ }
+
+ .align-self-xxl-end {
+ -ms-flex-item-align: end ;
+ align-self: flex-end ;
+ }
+
+ .align-self-xxl-center {
+ -ms-flex-item-align: center ;
+ align-self: center ;
+ }
+
+ .align-self-xxl-baseline {
+ -ms-flex-item-align: baseline ;
+ align-self: baseline ;
+ }
+
+ .align-self-xxl-stretch {
+ -ms-flex-item-align: stretch ;
+ align-self: stretch ;
+ }
+
+ .order-xxl-first {
+ -webkit-box-ordinal-group: 0 ;
+ -ms-flex-order: -1 ;
+ order: -1 ;
+ }
+
+ .order-xxl-0 {
+ -webkit-box-ordinal-group: 1 ;
+ -ms-flex-order: 0 ;
+ order: 0 ;
+ }
+
+ .order-xxl-1 {
+ -webkit-box-ordinal-group: 2 ;
+ -ms-flex-order: 1 ;
+ order: 1 ;
+ }
+
+ .order-xxl-2 {
+ -webkit-box-ordinal-group: 3 ;
+ -ms-flex-order: 2 ;
+ order: 2 ;
+ }
+
+ .order-xxl-3 {
+ -webkit-box-ordinal-group: 4 ;
+ -ms-flex-order: 3 ;
+ order: 3 ;
+ }
+
+ .order-xxl-4 {
+ -webkit-box-ordinal-group: 5 ;
+ -ms-flex-order: 4 ;
+ order: 4 ;
+ }
+
+ .order-xxl-5 {
+ -webkit-box-ordinal-group: 6 ;
+ -ms-flex-order: 5 ;
+ order: 5 ;
+ }
+
+ .order-xxl-last {
+ -webkit-box-ordinal-group: 7 ;
+ -ms-flex-order: 6 ;
+ order: 6 ;
+ }
+
+ .m-xxl-0 {
+ margin: 0 ;
+ }
+
+ .m-xxl-1 {
+ margin: 0.25rem ;
+ }
+
+ .m-xxl-2 {
+ margin: 0.5rem ;
+ }
+
+ .m-xxl-3 {
+ margin: 1rem ;
+ }
+
+ .m-xxl-4 {
+ margin: 1.5rem ;
+ }
+
+ .m-xxl-5 {
+ margin: 3rem ;
+ }
+
+ .m-xxl-auto {
+ margin: auto ;
+ }
+
+ .mx-xxl-0 {
+ margin-right: 0 ;
+ margin-left: 0 ;
+ }
+
+ .mx-xxl-1 {
+ margin-right: 0.25rem ;
+ margin-left: 0.25rem ;
+ }
+
+ .mx-xxl-2 {
+ margin-right: 0.5rem ;
+ margin-left: 0.5rem ;
+ }
+
+ .mx-xxl-3 {
+ margin-right: 1rem ;
+ margin-left: 1rem ;
+ }
+
+ .mx-xxl-4 {
+ margin-right: 1.5rem ;
+ margin-left: 1.5rem ;
+ }
+
+ .mx-xxl-5 {
+ margin-right: 3rem ;
+ margin-left: 3rem ;
+ }
+
+ .mx-xxl-auto {
+ margin-right: auto ;
+ margin-left: auto ;
+ }
+
+ .my-xxl-0 {
+ margin-top: 0 ;
+ margin-bottom: 0 ;
+ }
+
+ .my-xxl-1 {
+ margin-top: 0.25rem ;
+ margin-bottom: 0.25rem ;
+ }
+
+ .my-xxl-2 {
+ margin-top: 0.5rem ;
+ margin-bottom: 0.5rem ;
+ }
+
+ .my-xxl-3 {
+ margin-top: 1rem ;
+ margin-bottom: 1rem ;
+ }
+
+ .my-xxl-4 {
+ margin-top: 1.5rem ;
+ margin-bottom: 1.5rem ;
+ }
+
+ .my-xxl-5 {
+ margin-top: 3rem ;
+ margin-bottom: 3rem ;
+ }
+
+ .my-xxl-auto {
+ margin-top: auto ;
+ margin-bottom: auto ;
+ }
+
+ .mt-xxl-0 {
+ margin-top: 0 ;
+ }
+
+ .mt-xxl-1 {
+ margin-top: 0.25rem ;
+ }
+
+ .mt-xxl-2 {
+ margin-top: 0.5rem ;
+ }
+
+ .mt-xxl-3 {
+ margin-top: 1rem ;
+ }
+
+ .mt-xxl-4 {
+ margin-top: 1.5rem ;
+ }
+
+ .mt-xxl-5 {
+ margin-top: 3rem ;
+ }
+
+ .mt-xxl-auto {
+ margin-top: auto ;
+ }
+
+ .me-xxl-0 {
+ margin-right: 0 ;
+ }
+
+ .me-xxl-1 {
+ margin-right: 0.25rem ;
+ }
+
+ .me-xxl-2 {
+ margin-right: 0.5rem ;
+ }
+
+ .me-xxl-3 {
+ margin-right: 1rem ;
+ }
+
+ .me-xxl-4 {
+ margin-right: 1.5rem ;
+ }
+
+ .me-xxl-5 {
+ margin-right: 3rem ;
+ }
+
+ .me-xxl-auto {
+ margin-right: auto ;
+ }
+
+ .mb-xxl-0 {
+ margin-bottom: 0 ;
+ }
+
+ .mb-xxl-1 {
+ margin-bottom: 0.25rem ;
+ }
+
+ .mb-xxl-2 {
+ margin-bottom: 0.5rem ;
+ }
+
+ .mb-xxl-3 {
+ margin-bottom: 1rem ;
+ }
+
+ .mb-xxl-4 {
+ margin-bottom: 1.5rem ;
+ }
+
+ .mb-xxl-5 {
+ margin-bottom: 3rem ;
+ }
+
+ .mb-xxl-auto {
+ margin-bottom: auto ;
+ }
+
+ .ms-xxl-0 {
+ margin-left: 0 ;
+ }
+
+ .ms-xxl-1 {
+ margin-left: 0.25rem ;
+ }
+
+ .ms-xxl-2 {
+ margin-left: 0.5rem ;
+ }
+
+ .ms-xxl-3 {
+ margin-left: 1rem ;
+ }
+
+ .ms-xxl-4 {
+ margin-left: 1.5rem ;
+ }
+
+ .ms-xxl-5 {
+ margin-left: 3rem ;
+ }
+
+ .ms-xxl-auto {
+ margin-left: auto ;
+ }
+
+ .p-xxl-0 {
+ padding: 0 ;
+ }
+
+ .p-xxl-1 {
+ padding: 0.25rem ;
+ }
+
+ .p-xxl-2 {
+ padding: 0.5rem ;
+ }
+
+ .p-xxl-3 {
+ padding: 1rem ;
+ }
+
+ .p-xxl-4 {
+ padding: 1.5rem ;
+ }
+
+ .p-xxl-5 {
+ padding: 3rem ;
+ }
+
+ .px-xxl-0 {
+ padding-right: 0 ;
+ padding-left: 0 ;
+ }
+
+ .px-xxl-1 {
+ padding-right: 0.25rem ;
+ padding-left: 0.25rem ;
+ }
+
+ .px-xxl-2 {
+ padding-right: 0.5rem ;
+ padding-left: 0.5rem ;
+ }
+
+ .px-xxl-3 {
+ padding-right: 1rem ;
+ padding-left: 1rem ;
+ }
+
+ .px-xxl-4 {
+ padding-right: 1.5rem ;
+ padding-left: 1.5rem ;
+ }
+
+ .px-xxl-5 {
+ padding-right: 3rem ;
+ padding-left: 3rem ;
+ }
+
+ .py-xxl-0 {
+ padding-top: 0 ;
+ padding-bottom: 0 ;
+ }
+
+ .py-xxl-1 {
+ padding-top: 0.25rem ;
+ padding-bottom: 0.25rem ;
+ }
+
+ .py-xxl-2 {
+ padding-top: 0.5rem ;
+ padding-bottom: 0.5rem ;
+ }
+
+ .py-xxl-3 {
+ padding-top: 1rem ;
+ padding-bottom: 1rem ;
+ }
+
+ .py-xxl-4 {
+ padding-top: 1.5rem ;
+ padding-bottom: 1.5rem ;
+ }
+
+ .py-xxl-5 {
+ padding-top: 3rem ;
+ padding-bottom: 3rem ;
+ }
+
+ .pt-xxl-0 {
+ padding-top: 0 ;
+ }
+
+ .pt-xxl-1 {
+ padding-top: 0.25rem ;
+ }
+
+ .pt-xxl-2 {
+ padding-top: 0.5rem ;
+ }
+
+ .pt-xxl-3 {
+ padding-top: 1rem ;
+ }
+
+ .pt-xxl-4 {
+ padding-top: 1.5rem ;
+ }
+
+ .pt-xxl-5 {
+ padding-top: 3rem ;
+ }
+
+ .pe-xxl-0 {
+ padding-right: 0 ;
+ }
+
+ .pe-xxl-1 {
+ padding-right: 0.25rem ;
+ }
+
+ .pe-xxl-2 {
+ padding-right: 0.5rem ;
+ }
+
+ .pe-xxl-3 {
+ padding-right: 1rem ;
+ }
+
+ .pe-xxl-4 {
+ padding-right: 1.5rem ;
+ }
+
+ .pe-xxl-5 {
+ padding-right: 3rem ;
+ }
+
+ .pb-xxl-0 {
+ padding-bottom: 0 ;
+ }
+
+ .pb-xxl-1 {
+ padding-bottom: 0.25rem ;
+ }
+
+ .pb-xxl-2 {
+ padding-bottom: 0.5rem ;
+ }
+
+ .pb-xxl-3 {
+ padding-bottom: 1rem ;
+ }
+
+ .pb-xxl-4 {
+ padding-bottom: 1.5rem ;
+ }
+
+ .pb-xxl-5 {
+ padding-bottom: 3rem ;
+ }
+
+ .ps-xxl-0 {
+ padding-left: 0 ;
+ }
+
+ .ps-xxl-1 {
+ padding-left: 0.25rem ;
+ }
+
+ .ps-xxl-2 {
+ padding-left: 0.5rem ;
+ }
+
+ .ps-xxl-3 {
+ padding-left: 1rem ;
+ }
+
+ .ps-xxl-4 {
+ padding-left: 1.5rem ;
+ }
+
+ .ps-xxl-5 {
+ padding-left: 3rem ;
+ }
+
+ .gap-xxl-0 {
+ gap: 0 ;
+ }
+
+ .gap-xxl-1 {
+ gap: 0.25rem ;
+ }
+
+ .gap-xxl-2 {
+ gap: 0.5rem ;
+ }
+
+ .gap-xxl-3 {
+ gap: 1rem ;
+ }
+
+ .gap-xxl-4 {
+ gap: 1.5rem ;
+ }
+
+ .gap-xxl-5 {
+ gap: 3rem ;
+ }
+
+ .text-xxl-start {
+ text-align: left ;
+ }
+
+ .text-xxl-end {
+ text-align: right ;
+ }
+
+ .text-xxl-center {
+ text-align: center ;
+ }
+}
+
+@media (min-width: 1200px) {
+ .fs-1 {
+ font-size: 2.5rem ;
+ }
+
+ .fs-2 {
+ font-size: 2rem ;
+ }
+
+ .fs-3 {
+ font-size: 1.75rem ;
+ }
+
+ .fs-4 {
+ font-size: 1.5rem ;
+ }
+}
+
+@media print {
+ .d-print-inline {
+ display: inline ;
+ }
+
+ .d-print-inline-block {
+ display: inline-block ;
+ }
+
+ .d-print-block {
+ display: block ;
+ }
+
+ .d-print-grid {
+ display: grid ;
+ }
+
+ .d-print-table {
+ display: table ;
+ }
+
+ .d-print-table-row {
+ display: table-row ;
+ }
+
+ .d-print-table-cell {
+ display: table-cell ;
+ }
+
+ .d-print-flex {
+ display: -webkit-box ;
+ display: -ms-flexbox ;
+ display: flex ;
+ }
+
+ .d-print-inline-flex {
+ display: -webkit-inline-box ;
+ display: -ms-inline-flexbox ;
+ display: inline-flex ;
+ }
+
+ .d-print-none {
+ display: none ;
+ }
+}
+
+.minicolors-theme-bootstrap .minicolors-swatch {
+ width: 36px;
+ height: 36px;
+}
+
+.minicolors-theme-bootstrap .minicolors-swatch>.minicolors-sprite {
+ top: 50%;
+ left: 8px;
+ border-radius: 0;
+ -webkit-transform: translateY(-50%);
+ transform: translateY(-50%);
+}
+
+span.minicolors-swatch-color {
+ cursor: pointer;
+}
+
+:root {
+ scroll-behavior: smooth;
+}
+
+@media screen and (prefers-reduced-motion: reduce) {
+ :root {
+ scroll-behavior: auto;
+ }
+}
+
+html {
+ background-color: var(--body-bg, #0e1318);
+}
+
+body {
+ position: relative;
+ min-height: 100vh;
+}
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+h1,
+.h1,
+h2,
+.h2,
+h3,
+.h3,
+h4,
+.h4,
+h5,
+.h5,
+h6,
+.h6 {
+ font-family: var(--font-family-headings, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");
+ font-weight: var(--font-weight-headings, 700);
+}
+
+.display-1 {
+ font-size: clamp(2.7rem, 8vw, 5.5rem);
+}
+
+.display-2 {
+ font-size: clamp(2.3rem, 7vw, 4.5rem);
+}
+
+.display-3 {
+ font-size: clamp(1.9rem, 6vw, 3.5rem);
+}
+
+.display-4 {
+ font-size: clamp(1.5rem, 5vw, 2.5rem);
+}
+
+.lead {
+ font-size: clamp(1.1rem, 3vw, 1.25rem);
+}
+
+a {
+ color: var(--color-link, white);
+}
+
+a:not([class]) {
+ text-decoration: underline;
+}
+
+a:active,
+a:focus {
+ color: var(--color-active);
+}
+
+a.navbar-brand {
+ color: var(--color-brand);
+}
+
+.btn-primary {
+ background-color: var(--color-primary, #112855);
+ border-color: var(--color-primary, #112855);
+}
+
+.btn-primary:active,
+.btn-primary:focus {
+ background-color: var(--color-active);
+ border-color: var(--color-active);
+}
+
+.btn-group {
+ margin-bottom: 1em;
+}
+
+.btn-group>input {
+ padding: 0.5em;
+ border: 1px solid hsl(210, 14%, 83%);
+ border-top-left-radius: 0.25rem;
+ border-bottom-left-radius: 0.25rem;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.btn-group>.btn-group {
+ margin-bottom: 0;
+}
+
+.com-content-article ol,
+.com-content-article ul {
+ overflow: hidden;
+}
+
+.com-content-category__pagination {
+ margin-bottom: 1em;
+}
+
+small,
+.small {
+ font-size: 0.875rem;
+}
+
+dd {
+ padding: 0;
+ word-wrap: break-word;
+}
+
+th dd {
+ font-weight: var(--font-weight-normal, 400);
+}
+
+.com-contact__thumbnail {
+ text-align: left;
+ margin: 2em;
+ padding: 1rem;
+}
+
+[data-bs-theme='dark'] .com-contact__thumbnail {
+ background-color: var(--nav-text-color, gray);
+}
+
+@media (min-width: 1200px) {
+ dl.dl-horizontal {
+ display: grid;
+ grid-template-columns: auto 1fr;
+ }
+
+ dl.dl-horizontal dt {
+ grid-column-start: 1;
+ grid-column-end: 2;
+ }
+
+ dl.dl-horizontal dd {
+ grid-column-start: 2;
+ grid-column-end: 3;
+ padding: 0 0 0 1em;
+ margin-bottom: 0;
+ }
+
+ .com-contact__container {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ grid-template-rows: repeat(4, auto);
+ grid-gap: 1rem;
+ margin-bottom: 1em;
+ }
+
+ .com-contact__container h3,
+ .com-contact__container .h3 {
+ grid-column: 1/5;
+ }
+
+ .com-contact__container .com-contact__thumbnail {
+ grid-column: 1/5;
+ grid-row: 2/5;
+ text-align: right;
+ }
+
+ .com-contact__container .com-contact__position {
+ grid-column: 1/3;
+ grid-row: 2/3;
+ }
+
+ .com-contact__container .com-contact__info {
+ grid-column: 1/3;
+ grid-row: 3/4;
+ }
+
+ .com-users-profile dt {
+ min-width: 180px;
+ }
+}
+
+figure {
+ margin: 0 0 2em;
+}
+
+figure.float-start {
+ margin-right: 1em;
+}
+
+figure.float-end {
+ margin-left: 1em;
+}
+
+figcaption {
+ font-size: 0.9em;
+ color: hsl(210, 7%, 46%);
+}
+
+.mod-menu {
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+}
+
+meter {
+ width: 100%;
+}
+
+.pagenavigation,
+.pager {
+ clear: both;
+}
+
+.pagenavigation .pagination,
+.pager .pagination {
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ padding: 0;
+ margin: 1em 0;
+}
+
+.pagenavigation .pagination .next:only-child,
+.pager .pagination .next:only-child {
+ margin-left: auto;
+}
+
+.pager .pagination {
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+}
+
+[dir=rtl] li.next .page-link {
+ border-top-left-radius: 0.25rem;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0.25rem;
+}
+
+[dir=rtl] li.previous .page-link {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0.25rem;
+ border-bottom-right-radius: 0.25rem;
+ border-bottom-left-radius: 0;
+}
+
+.j-main-container .alert {
+ margin: 0.75rem;
+}
+
+.alert-heading {
+ font-size: 1.5rem;
+}
+
+@-webkit-keyframes fadeIn {
+ from {
+ opacity: 0;
+ -webkit-transform: translateY(-1rem);
+ transform: translateY(-1rem);
+ }
+
+ to {
+ opacity: 1;
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ -webkit-transform: translateY(-1rem);
+ transform: translateY(-1rem);
+ }
+
+ to {
+ opacity: 1;
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+}
+
+/**
+* Back to Top
+*/
+.back-to-top-link {
+ position: absolute;
+ inset-inline-end: 1rem;
+ bottom: 1rem;
+ z-index: 10000;
+ padding: 0.5em;
+ color: var(--color-primary, hsl(220, 67%, 20%));
+ pointer-events: all;
+ background-color: var(--white, var(--body-color, #e6ebf1));
+ border: 1px solid var(--color-primary, hsl(220, 67%, 20%));
+ border-radius: 0.25rem;
+ opacity: 0;
+ -webkit-transition: opacity 200ms ease-in;
+ -o-transition: opacity 200ms ease-in;
+ transition: opacity 200ms ease-in;
+}
+
+.back-to-top-link.visible {
+ opacity: 1;
+}
+
+.back-to-top-link:active,
+.back-to-top-link:focus {
+ color: var(--white, var(--body-color, #e6ebf1));
+ background-color: var(--color-active);
+ border-color: var(--white, var(--body-color, #e6ebf1));
+}
+
+.container-banner img {
+ display: block;
+ margin: auto;
+}
+
+.container-banner .banner-overlay {
+ height: var(--hero-height, 60vh);
+ color: var(--hero-color, var(--body-color, #e6ebf1));
+ background-repeat: var(--hero-bg-repeat, no-repeat);
+ background-attachment: var(--hero-bg-attachment, fixed);
+ background-position: var(--hero-bg-position, top center);
+ background-size: var(--hero-bg-size, cover);
+ border-bottom: var(--hero-border-bottom, solid var(--accent-color-secondary, #6fb3ff));
+}
+
+/* Legacy: standard Cassiopeia banner with an explicit .overlay child */
+.container-banner .banner-overlay .overlay {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: 100%;
+ text-align: var(--hero-overlay-text-align, center);
+ color: var(--hero-overlay-text-color, var(--body-color, #e6ebf1));
+ background-color: var(--hero-overlay-bg, hsla(0, 0%, 0%, 0.5));
+ background-position: var(--hero-overlay-bg-position, center);
+ background-size: var(--hero-overlay-bg-size, cover);
+ background-repeat: no-repeat;
+}
+
+/* Hero layout (hero.php): outer wrapper — visual overlay is handled by the .overlay child */
+.container-banner .banner-overlay.custom-hero {
+ /* Selector kept as a customisation hook; see .banner-overlay .overlay for overlay styles */
+}
+
+.container-banner .banner-overlay .overlay .text-thin {
+ font-weight: lighter;
+}
+
+.container-banner .banner-overlay .overlay .text-thin::after {
+ display: block;
+ width: 30%;
+ height: 4px;
+ margin: 1rem auto 2rem;
+ content: "";
+ background: var(--body-color, #e6ebf1);
+}
+
+.container-banner .banner-overlay .overlay .text-thin .lead {
+ font-size: 150vh;
+}
+
+@media screen and (max-height: 740px) {
+ .container-banner .banner-overlay {
+ height: 100vh;
+ }
+}
+
+/* ── HERO CARD BASE ── */
+.hero {
+ max-width: var(--hero-card-max-width, 600px);
+ padding: var(--hero-card-padding-y, 3rem) var(--hero-card-padding-x, 2rem);
+ background-color: var(--hero-card-bg, var(--hero-primary-bg-color, #0d1e3a));
+ background-image: var(--hero-card-overlay, none);
+ background-size: cover;
+ background-position: center;
+ color: var(--hero-card-color, var(--hero-primary-color, #f1f5f9));
+ border-radius: var(--hero-card-border-radius, .5rem);
+}
+
+/* ── PRIMARY VARIANT (uses default card vars) ── */
+.hero#primary {
+ background-color: var(--hero-card-bg, #0d1e3a);
+ background-image: var(--hero-card-overlay, none);
+ color: var(--hero-card-color, #f1f5f9);
+}
+
+/* ── SECONDARY / ALTERNATIVE VARIANT ── */
+.hero#secondary {
+ max-width: var(--hero-alt-card-max-width, 600px);
+ padding: var(--hero-alt-card-padding-y, 3rem) var(--hero-alt-card-padding-x, 2rem);
+ background-color: var(--hero-alt-card-bg, #080f1e);
+ background-image: var(--hero-alt-card-overlay, none);
+ color: var(--hero-alt-card-color, #f1f5f9);
+ border-radius: var(--hero-alt-card-border-radius, .5rem);
+}
+
+/* ── HERO MOBILE: hide photo bg, full-bleed card ── */
+@media (max-width: 767.98px) {
+ .container-banner .banner-overlay {
+ height: auto;
+ background-image: none !important;
+ background-attachment: scroll;
+ border-bottom: none;
+ }
+ .container-banner .banner-overlay .overlay {
+ background-color: transparent;
+ background-image: none;
+ }
+ .hero {
+ max-width: 100%;
+ width: 100%;
+ min-height: 100vh;
+ min-height: 100dvh;
+ border-radius: 0;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ }
+}
+
+.footer {
+ color: var(--mainmenu-nav-link-color, #fff);
+ background-color: var(--nav-bg-color);
+ padding-bottom: var(--footer-padding-bottom, 80px);
+}
+
+.footer .grid-child {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ width: 100%;
+}
+
+.footer a {
+ color: var(--mainmenu-nav-link-color, #fff);
+}
+
+.footer .mod-menu {
+ position: relative;
+}
+
+.footer .metismenu.mod-menu .mm-collapse {
+ background: var(--color-primary, #112855);
+}
+
+@media (max-width: 991.98px) {
+ .footer .grid-child {
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ }
+
+ .footer .grid-child .mod-footer {
+ margin: 0.375rem 0;
+ }
+}
+
+.form-control {
+ max-width: 100%;
+}
+
+.form-control.input-xlarge {
+ max-width: 21.875rem;
+}
+
+.form-control.input-xxlarge {
+ max-width: 34.375rem;
+}
+
+.form-control.input-full {
+ max-width: 100%;
+}
+
+.spacer hr {
+ width: 23.75rem;
+}
+
+.form-select,
+.custom-select {
+ max-width: 100%;
+}
+
+.form-inline .form-select,
+.form-inline .custom-select {
+ display: inline-block;
+ width: auto;
+}
+
+@media (max-width: 991.98px) {
+
+ .form-inline .form-select,
+ .form-inline .custom-select {
+ width: 100%;
+ }
+}
+
+td .form-control {
+ display: inline-block;
+ width: auto;
+}
+
+.checkboxes {
+ padding-top: 0.3125rem;
+}
+
+.checkboxes .checkbox input {
+ position: static;
+ margin-left: 0;
+}
+
+.modal label {
+ width: 100%;
+}
+
+.invalid {
+ color: hsl(3, 75%, 37%);
+ border-color: hsl(3, 75%, 37%);
+}
+
+.valid {
+ border-color: hsl(120, 32%, 39%);
+}
+
+.form-control-feedback {
+ display: block;
+}
+
+[role=tooltip]:not(.show) {
+ right: 5em;
+ z-index: 1070;
+ display: none;
+ max-width: 100%;
+ padding: 0.5em;
+ margin: 0.5em;
+ color: hsl(0, 0%, 0%);
+ text-align: start;
+ background: var(--body-color, #e6ebf1);
+ border: 1px solid hsl(210, 7%, 46%);
+ border-radius: 0.25rem;
+ -webkit-box-shadow: 0 0 0.5rem rgba(0, 0, 0, 0.8);
+ box-shadow: 0 0 0.5rem rgba(0, 0, 0, 0.8);
+}
+
+[role=tooltip]:not(.show)[id^=editarticle-] {
+ right: auto;
+ -webkit-margin-start: -10em;
+ margin-inline-start: -10em;
+}
+
+[role=tooltip]:not(.show)[id^=editcontact-] {
+ right: auto;
+ -webkit-margin-start: -10em;
+ margin-inline-start: -10em;
+}
+
+[role=tooltip]:not(.show)[id^=id-skip-] {
+ right: auto;
+}
+
+[role=tooltip]:not(.show)[id^=cbunpublish] {
+ right: auto;
+}
+
+:focus+[role=tooltip],
+:active+[role=tooltip] {
+ position: absolute;
+ display: block;
+}
+
+.filter-search-bar__description {
+ bottom: 100%;
+}
+
+fieldset {
+ margin-bottom: 2em;
+}
+
+fieldset+fieldset {
+ margin-top: 2em;
+}
+
+fieldset>* {
+ margin-bottom: 0;
+}
+
+.control-group {
+ margin: 1em 0;
+}
+
+.container-popup .filter-search-bar__description {
+ top: 100%;
+ bottom: auto;
+}
+
+.com-users-login__options {
+ margin-top: 2em;
+}
+
+.com-users-logout__submit button {
+ width: 100%;
+}
+
+.com-users-profile__edit #jform_privacyconsent_privacy .radio,
+.com-users-profile__edit #jform_profile_tos .radio,
+.com-users-profile__edit #jform_terms_terms .radio,
+.com-users-registration #jform_privacyconsent_privacy .radio,
+.com-users-registration #jform_profile_tos .radio,
+.com-users-registration #jform_terms_terms .radio {
+ display: -webkit-inline-box;
+ display: -ms-inline-flexbox;
+ display: inline-flex;
+ gap: 1rem;
+}
+
+.btn.jmodedit {
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: auto;
+ z-index: 900;
+ color: var(--color-link, white);
+ background-color: rgba(255, 255, 255, 0.5);
+ border: 1px solid #58595a;
+ border-radius: 0.25rem;
+ --btn-padding-x: 0.25rem;
+ --btn-padding-y: 0.1rem;
+}
+
+.container-header {
+ z-index: 100;
+ background: var(--header-background-image, url('../../../../../../media/templates/site/mokoonyx/images/bg.svg'));
+ background-size: var(--header-background-size, auto);
+ box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ background-repeat: var(--header-background-repeat, repeat);
+}
+
+/* Sticky header: override z-index to stay above all content */
+.container-header.sticky-top {
+ z-index: 1020;
+}
+
+/* Disable sticky on mobile — full-width header works better as static */
+@media (max-width: 991.98px) {
+ .container-header.sticky-top {
+ position: relative;
+ z-index: 100;
+ }
+}
+
+.container-header .grid-child {
+ padding: var(--padding-x, 0.15rem) var(--padding-y, 0.15rem);
+}
+
+.container-header .site-description {
+ font-size: 1rem;
+ color: var(--body-color, #e6ebf1);
+ white-space: normal;
+}
+
+/* Header aside: module position to the right of the logo */
+.header-brand-wrap {
+ display: flex;
+ align-items: center;
+ width: 100%;
+}
+
+.container-brand-aside {
+ margin-inline-start: auto;
+ display: flex;
+ align-items: center;
+ gap: 1em;
+}
+
+.container-brand-aside>* {
+ flex: 1;
+ margin: 0.5em 0;
+}
+
+@media (max-width: 991.98px) {
+ .header-brand-wrap {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ .container-brand-aside {
+ margin-inline-start: 0;
+ flex-direction: column;
+ }
+
+ .container-brand-aside>* {
+ flex: 0 1 auto;
+ }
+}
+
+.container-header .navbar-brand {
+ position: relative;
+ display: inline-block;
+ padding-top: var(--navbar-brand-padding-y, 0.3125rem);
+ padding-bottom: var(--navbar-brand-padding-y, 0.3125rem);
+ font-size: 2rem;
+ color: var(--nav-text-color, gray);
+ -webkit-margin-end: auto;
+ margin-inline-end: auto;
+}
+
+.container-header .navbar-brand a {
+ color: var(--nav-text-color, gray);
+}
+
+.navbar-brand img {
+ max-width: 250px;
+ max-height: 100px;
+ width: auto;
+ height: auto;
+}
+
+.container-header .navbar-brand:active,
+.container-header .navbar-brand:focus {
+ color: var(--nav-text-color, gray);
+}
+
+.container-header .container-nav a {
+ color: var(--mainmenu-nav-link-color, #fff);
+ text-decoration: none;
+}
+
+.container-header .container-nav a:hover,
+.container-header .container-nav a:focus {
+ color: var(--link-hover-color, #c3d6ff);
+}
+
+.container-header .container-nav {
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ background-color: var(--nav-bg-color);
+ border-width: var(--border-width, 1px);
+ border-top: solid var(--accent-color-primary, #3f8ff0);
+ border-bottom: solid var(--accent-color-secondary, #6fb3ff);
+ border-left: none;
+ border-right: none;
+}
+
+@media (max-width: 767.98px) {
+ .container-header .container-nav nav {
+ margin-top: 0.4rem;
+ }
+}
+
+.container-header .container-nav .container-search:only-child {
+ margin-left: auto;
+}
+
+.container-header .navbar-collapse.show {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+}
+
+.container-header .mod-menu {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 100%;
+ flex: 1 0 100%;
+ padding: 0;
+ margin: 0;
+ color: var(--mainmenu-nav-link-color, #fff);
+ list-style: none;
+ font-size: 1.2em;
+}
+
+@media (min-width: 992px) {
+ .container-header .mod-menu {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 0%;
+ flex: 1 1 0%;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ }
+}
+
+.container-header .mod-menu>li {
+ position: relative;
+}
+
+li.active a,
+li.current a {
+ font-weight: bold;
+}
+
+@media (min-width: 992px) {
+ .container-header .mod-menu>li+li {
+ margin-left: 1.55em;
+ }
+}
+
+.container-header .mod-menu>li>a,
+.container-header .mod-menu>li>span,
+.container-header .nav-link,
+.container-header .mod-menu-main__link {
+ position: relative;
+ color: var(--mainmenu-nav-link-color, #fff);
+ text-decoration: none;
+}
+
+.container-header .nav-link:hover,
+.container-header .nav-link:focus,
+.container-header .mod-menu-main__link:hover,
+.container-header .mod-menu-main__link:focus {
+ color: var(--link-hover-color, #c3d6ff);
+}
+
+@media (min-width: 992px) {
+ .container-header .mod-menu>li::after {
+ position: absolute;
+ right: 50%;
+ bottom: 0;
+ left: 50%;
+ display: block;
+ height: 2px;
+ margin: auto;
+ content: "";
+ background: transparent;
+ opacity: 0.2;
+ -webkit-transition: all 0.2s ease, background-color 0.2s ease;
+ -o-transition: all 0.2s ease, background-color 0.2s ease;
+ transition: all 0.2s ease, background-color 0.2s ease;
+ }
+}
+
+.container-header .mod-menu>li.active::after,
+.container-header .mod-menu>li:active::after {
+ right: 2px;
+ left: 0;
+ background: var(--navbar-brand-color);
+}
+
+@media (max-width: 991.98px) {
+
+ .container-header .mod-menu>li.active>a,
+ .container-header .mod-menu>li.active>span,
+ .container-header .mod-menu>li>a:active {
+ text-decoration: underline;
+ }
+}
+
+.container-header .mod-menu .parent>ul {
+ display: none;
+ color: hsl(210, 11%, 15%);
+}
+
+.container-header .metismenu>li+li {
+ margin-left: 0;
+}
+
+@media (min-width: 992px) {
+
+ .container-header .metismenu>li>a::after,
+ .container-header .metismenu>li>button::before {
+ position: absolute;
+ right: 50%;
+ bottom: 0;
+ left: 50%;
+ display: block;
+ height: 2px;
+ margin: auto;
+ content: "";
+ background: transparent;
+ opacity: 0.2;
+ -webkit-transition: all 0.2s ease, background-color 0.2s ease;
+ -o-transition: all 0.2s ease, background-color 0.2s ease;
+ transition: all 0.2s ease, background-color 0.2s ease;
+ }
+}
+
+.container-header .metismenu>li>a:active::after,
+.container-header .metismenu>li>button:active::before,
+.container-header .metismenu>li.active>a::after,
+.container-header .metismenu>li.active>button::before {
+ right: 0;
+ left: 0;
+ background: var(--navbar-color);
+}
+
+.container-header .metismenu>li>button.mm-toggler-link:active::before,
+.container-header .metismenu>li.active>button.mm-toggler-link::before {
+ right: 0;
+ left: 0.5em;
+}
+
+@media (min-width: 992px) {
+
+ .container-header .metismenu>li.level-1.active>a,
+ .container-header .metismenu>li.level-1.active>button,
+ .container-header .metismenu>li.level-1>a:active,
+ .container-header .metismenu>li.level-1>button:active {
+ text-decoration: none;
+ }
+}
+
+.container-header .metismenu>li.level-1>ul {
+ min-width: 12rem;
+}
+
+.container-header .navbar-toggler,
+.container-header .search-toggler {
+ color: var(--mainmenu-nav-link-color, #fff);
+ border-color: var(--mainmenu-nav-link-color, #fff);
+ font-size: 1.25rem;
+ cursor: pointer;
+}
+
+.container-header .search-toggler {
+ background: none;
+ border: none;
+ padding: 0.25rem 0.5rem;
+}
+
+.container-header .container-search {
+ margin-top: 0.75em;
+}
+
+.container-header .container-search .mod-finder,
+.container-header .container-search .mod-finder__form,
+.container-header .container-search .mod-finder__search {
+ width: 100%;
+}
+
+.container-header .mod-finder, .container-header .mod-finder a, .container-header .mod-finder form {
+ color: var(--mainmenu-nav-link-color, #e6ebf1);
+ margin-block-end: 0;
+}
+
+.container-header .mod-finder a:active,
+.container-header .mod-finder a:focus {
+ color: var(--mod-finder-link-hover, #5a6470);
+}
+
+.container-header .mod-finder .awesomplete {
+ color: var(--body-color, #e6ebf1);
+}
+
+.container-header .mod-finder .awesomplete>ul {
+ background: -webkit-gradient(linear, left top, right bottom, from(var(--body-color, #e6ebf1)), to(hsla(0, 0%, 100%, 0.9)));
+ background: -o-linear-gradient(top left, var(--body-color, #e6ebf1), hsla(0, 0%, 100%, 0.9));
+ background: linear-gradient(to bottom right, var(--body-color, #e6ebf1), hsla(0, 0%, 100%, 0.9));
+}
+
+.icon-white {
+ color: var(--body-bg, #0e1318);
+}
+
+.input-group-text::before {
+ min-width: 16px;
+}
+
+.tbody-icon {
+ padding: 0 0.1875rem;
+ text-align: center;
+ background-color: transparent;
+ border: 0;
+}
+
+.tbody-icon [class^=icon-],
+.tbody-icon [class*=" icon-"],
+.tbody-icon [class^=fa-],
+.tbody-icon [class*=" fa-"] {
+ width: 26px;
+ height: 26px;
+ font-size: 1.1rem;
+ line-height: 22px;
+ color: hsl(210, 14%, 83%);
+ border: 0;
+}
+
+.tbody-icon .icon-publish,
+.tbody-icon .icon-check,
+.tbody-icon .fa-check {
+ color: hsl(120, 32%, 39%);
+ border-color: hsl(120, 32%, 39%);
+}
+
+.tbody-icon .icon-checkedout,
+.tbody-icon .icon-lock,
+.tbody-icon .fa-lock {
+ width: auto;
+ height: auto;
+ font-size: 1.2rem;
+ line-height: 1rem;
+ color: hsl(210, 9%, 31%);
+ border: 0;
+}
+
+.tbody-icon.home-disabled,
+.tbody-icon.featured-disabled,
+.tbody-icon.color-featured-disabled,
+.tbody-icon.icon-star-disabled,
+.tbody-icon.fa-star-disabled {
+ cursor: not-allowed;
+ opacity: 1;
+}
+
+.tbody-icon .icon-delete,
+.tbody-icon .fa-delete,
+.tbody-icon .icon-times,
+.tbody-icon .fa-times {
+ color: hsl(3, 75%, 37%);
+ border-color: hsl(3, 75%, 37%);
+}
+
+.plg_system_webauthn_login_button svg {
+ -webkit-margin-end: 0.125rem;
+ margin-inline-end: 0.125rem;
+ max-height: 25px;
+ width: auto;
+}
+
+.plg_system_webauthn_login_button svg path {
+ fill: var(--black, #000);
+}
+
+iframe {
+ border: 0;
+}
+
+.modal iframe {
+ width: 100%;
+}
+
+.grid-child {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ margin-right: auto;
+ margin-left: auto;
+}
+
+.mod-custom {
+ position: relative;
+}
+
+/* ── MODULE TITLES ── */
+/* Shared styles for module titles rendered by MokoOnyx overrides */
+[class*="__title"] {
+ margin-top: 0;
+ margin-bottom: .75rem;
+ font-weight: 600;
+ color: var(--body-color, #212529);
+ line-height: 1.3;
+}
+
+/* Module title alignment — apply via module class suffix */
+.title-center [class*="__title"] { text-align: center; }
+.title-right [class*="__title"] { text-align: right; }
+
+/* ── MODULE: Statistics ── */
+.mod-stats__list {
+ margin: 0;
+ padding: 0;
+}
+
+.mod-stats__label {
+ font-weight: 600;
+ margin-bottom: 0;
+}
+
+.mod-stats__data {
+ margin-left: 0;
+ margin-bottom: .5rem;
+ color: var(--body-font-color, #666);
+}
+
+/* Article list modules */
+.mod-articles-latest__list,
+.mod-articles-popular__list,
+.mod-articles-category__list,
+.mod-related-items__list,
+.mod-tags-similar__list {
+ list-style: none;
+ padding-left: 0;
+ margin-bottom: 0;
+}
+
+.mod-articles-latest__item,
+.mod-articles-popular__item,
+.mod-articles-category__item,
+.mod-related-items__item,
+.mod-tags-similar__item {
+ padding: .4rem 0;
+ border-bottom: 1px solid var(--border-color, #dee2e6);
+}
+
+.mod-articles-latest__item:last-child,
+.mod-articles-popular__item:last-child,
+.mod-articles-category__item:last-child,
+.mod-related-items__item:last-child,
+.mod-tags-similar__item:last-child {
+ border-bottom: 0;
+}
+
+.mod-articles-latest__item a,
+.mod-articles-popular__item a,
+.mod-articles-category__link,
+.mod-related-items__item a,
+.mod-tags-similar__item a {
+ text-decoration: none;
+ color: var(--link-color, #0d6efd);
+}
+
+.mod-articles-latest__item a:hover,
+.mod-articles-popular__item a:hover,
+.mod-articles-category__link:hover,
+.mod-related-items__item a:hover,
+.mod-tags-similar__item a:hover {
+ color: var(--link-hover-color, #0a58ca);
+ text-decoration: underline;
+}
+
+/* Article category module extras */
+.mod-articles-category__date,
+.mod-related-items__date {
+ display: block;
+ font-size: .85em;
+ color: var(--secondary-color, #6c757d);
+}
+
+.mod-articles-category__author {
+ font-size: .85em;
+ color: var(--secondary-color, #6c757d);
+}
+
+.mod-articles-category__intro,
+.mod-articles-news__intro {
+ margin-top: .25rem;
+ font-size: .9em;
+ color: var(--body-color, #212529);
+}
+
+.mod-articles-category__readmore,
+.mod-articles-news__readmore {
+ display: inline-block;
+ margin-top: .25rem;
+ font-size: .85em;
+ font-weight: 600;
+}
+
+/* Newsflash module */
+.mod-articles-news__item {
+ padding: .75rem 0;
+ border-bottom: 1px solid var(--border-color, #dee2e6);
+}
+
+.mod-articles-news__item:last-child {
+ border-bottom: 0;
+}
+
+.mod-articles-news__item-title {
+ margin-bottom: .25rem;
+ font-size: 1.1em;
+}
+
+/* Tags module */
+.mod-tags-popular__tag {
+ font-size: .85rem;
+ transition: background-color .15s ease;
+}
+
+.mod-tags-popular__tag:hover {
+ filter: brightness(1.15);
+}
+
+/* Search / Finder module */
+.mod-finder__form .input-group {
+ border-radius: var(--border-radius, .25rem);
+}
+
+/* Login module */
+.mod-login__greeting {
+ margin-bottom: 1rem;
+ font-weight: 500;
+}
+
+.mod-login__options {
+ margin-top: .5rem;
+}
+
+.mod-login__options li + li {
+ margin-top: .25rem;
+}
+
+/* Breadcrumbs module */
+.mod-breadcrumbs {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.mod-breadcrumbs__here {
+ float: left;
+ font-weight: 600;
+ white-space: nowrap;
+ color: var(--body-font-color, #444);
+ padding-right: .15rem;
+}
+
+.mod-breadcrumbs .breadcrumb {
+ background: transparent;
+ padding: 0;
+ margin-bottom: 0;
+}
+
+/* Footer module */
+.mod-footer__content {
+ font-size: .9em;
+ color: var(--secondary-color, #6c757d);
+}
+
+/* HERO CONTAINER */
+.hero-overlay {
+ position: relative;
+ overflow: hidden;
+ isolation: isolate;
+}
+
+/* BACKGROUND IMAGE LAYER (inherits from parent hero section) */
+.hero-overlay::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ z-index: -2;
+
+ background-position: center;
+ background-size: cover;
+ background-repeat: no-repeat;
+
+ transform: scale(1.02);
+}
+
+/* CENTER SOFTENING LAYER */
+.hero-overlay::after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ z-index: -1;
+
+ -webkit-backdrop-filter: blur(8px) saturate(0.9) brightness(1.12);
+ backdrop-filter: blur(8px) saturate(0.9) brightness(1.12);
+
+ -webkit-mask-image: radial-gradient(
+ circle at 50% 45%,
+ rgba(0,0,0,1) 0%,
+ rgba(0,0,0,1) 38%,
+ rgba(0,0,0,0) 72%
+ );
+ mask-image: radial-gradient(
+ circle at 50% 45%,
+ rgba(0,0,0,1) 0%,
+ rgba(0,0,0,1) 38%,
+ rgba(0,0,0,0) 72%
+ );
+
+ pointer-events: none;
+}
+
+/* TEXT OVERLAY PANEL */
+.hero-overlay .overlay {
+ position: relative;
+ z-index: 0;
+
+ border-top: var(--border-width, 1px) var(--border-style, solid) var(--accent-color-primary, #3f8ff0);
+ border-bottom: var(--border-width, 1px) var(--border-style, solid) var(--accent-color-secondary, #6fb3ff);
+
+ background-color: rgba(111, 117, 123, 0.55);
+ background-image: linear-gradient(
+ 180deg,
+ rgba(255,255,255,0.12),
+ rgba(0,0,0,0.18)
+ );
+}
+
+.container-topbar {
+ color: var(--body-color, #e6ebf1);
+ background-color: var(--color-primary, #112855);
+}
+
+.container-topbar a {
+ color: var(--body-color, #e6ebf1) ;
+
+}
+
+.container-banner {
+ display: block;
+ margin: 0;
+}
+
+.container-top-a,
+.container-top-b,
+.container-bottom-a,
+.container-bottom-b,
+.mod-breadcrumbs {
+ position: relative;
+ clear: both;
+}
+
+.container-top-a>*,
+.container-top-b>*,
+.container-bottom-a>*,
+.container-bottom-b>* {
+ -webkit-box-flex: 1;
+ -ms-flex: 1;
+ flex: 1;
+ margin: 0.5em 0;
+}
+
+@media (max-width: 991.98px) {
+
+ .container-top-a,
+ .container-top-b,
+ .container-bottom-a,
+ .container-bottom-b {
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ }
+
+ .container-top-a>*,
+ .container-top-b>*,
+ .container-bottom-a>*,
+ .container-bottom-b>* {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 1 auto;
+ flex: 0 1 auto;
+ }
+}
+
+/* ── BLOCK COLOR SYSTEM (nth-child slot palette) ── */
+.container-top-a > .card:nth-child(1),
+.container-top-b > .card:nth-child(1),
+.container-bottom-a > .card:nth-child(1),
+.container-bottom-b > .card:nth-child(1) {
+ background-color: var(--block-color-1);
+ color: var(--block-text-1);
+}
+
+.container-top-a > .card:nth-child(2),
+.container-top-b > .card:nth-child(2),
+.container-bottom-a > .card:nth-child(2),
+.container-bottom-b > .card:nth-child(2) {
+ background-color: var(--block-color-2);
+ color: var(--block-text-2, #fff);
+}
+
+.container-top-a > .card:nth-child(3),
+.container-top-b > .card:nth-child(3),
+.container-bottom-a > .card:nth-child(3),
+.container-bottom-b > .card:nth-child(3) {
+ background-color: var(--block-color-3, rgba(238, 194, 52, .15));
+ color: var(--block-text-3);
+}
+
+.container-top-a > .card:nth-child(4),
+.container-top-b > .card:nth-child(4),
+.container-bottom-a > .card:nth-child(4),
+.container-bottom-b > .card:nth-child(4) {
+ background-color: var(--block-color-4, rgba(74, 166, 100, .15));
+ color: var(--block-text-4);
+}
+
+/* ── BLOCK COLOR — Named per-module overrides ── */
+.container-top-a #block-highlight,
+.container-top-b #block-highlight,
+.container-bottom-a #block-highlight,
+.container-bottom-b #block-highlight {
+ background-color: var(--block-highlight-bg);
+ color: var(--block-highlight-text, #fff);
+}
+
+.container-top-a #block-cta,
+.container-top-b #block-cta,
+.container-bottom-a #block-cta,
+.container-bottom-b #block-cta {
+ background-color: var(--block-cta-bg);
+ color: var(--block-cta-text, #f1f5f9);
+}
+
+.container-top-a #block-alert,
+.container-top-b #block-alert,
+.container-bottom-a #block-alert,
+.container-bottom-b #block-alert {
+ background-color: var(--block-alert-bg);
+ color: var(--block-alert-text, #fff);
+}
+
+.container-component nav {
+ position: relative;
+}
+
+.container-component,
+.container-sidebar-left,
+.container-sidebar-right {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-flex: 1;
+ -ms-flex: 1;
+ flex: 1;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+}
+
+.container-component>*,
+.container-sidebar-left>*,
+.container-sidebar-right>* {
+ margin-bottom: 0;
+}
+
+.container-component,
+.sidebar-left,
+.sidebar-right {
+ height: 100%;
+}
+
+.container-component>*:first-child,
+.container-sidebar-left>*:first-child,
+.container-sidebar-right>*:first-child {
+ margin-top: 1em;
+}
+
+.container-component>*+*,
+.container-sidebar-left>*+*,
+.container-sidebar-right>*+* {
+ margin-top: 1em;
+}
+
+.container-sidebar-left,
+.container-sidebar-right {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: calc(100% - 1em);
+ -webkit-box-ordinal-group: 2;
+ -ms-flex-order: 1;
+ order: 1;
+}
+
+@media (min-width: 768px) {
+
+ .container-sidebar-left,
+ .container-sidebar-right {
+ width: calc(25% - 1em);
+ -webkit-box-ordinal-group: 1;
+ -ms-flex-order: 0;
+ order: 0;
+ }
+}
+
+.container-sidebar-left .sidebar-left:first-child {
+ margin-top: 1em;
+}
+
+.container-sidebar-left .sidebar-left:last-child {
+ margin-bottom: 1em;
+}
+
+.container-sidebar-right .sidebar-right:first-child {
+ margin-top: 1em;
+}
+
+.container-sidebar-right .sidebar-right:last-child {
+ margin-bottom: 1em;
+}
+
+.system-debug {
+ display: block;
+}
+
+.options-form {
+ width: 100%;
+ padding: 1vw 2vw;
+ margin-bottom: 1rem;
+ color: var(--form-legend-color, #9fa6ad);
+ background-color: var(--body-color, #e6ebf1);
+ border: 1px solid var(--border-gray, #3a4250);
+}
+
+.options-form>legend {
+ float: none;
+ width: auto;
+ padding: 0 0.5rem;
+ font-weight: 700;
+ color: var(--form-legend-color, #9fa6ad);
+ background-color: var(--body-color, #e6ebf1);
+}
+
+.modal .btn {
+ margin-right: 0.5rem;
+}
+
+.modal .btn-primary:not([href]),
+.modal .btn-success:not([href]) {
+ color: var(--body-color, #e6ebf1);
+}
+
+.modal .btn-primary:not([href]):active,
+.modal .btn-success:not([href]):active {
+ color: var(--body-color, #e6ebf1);
+}
+
+.modal-header {
+ padding: 0 0.9375rem;
+}
+
+.modal-title {
+ font-weight: var(--font-weight-normal, 400);
+ line-height: 3rem;
+}
+
+.contentpane {
+ padding: 0.9375rem;
+}
+
+.contentpane .main-card {
+ margin: -0.625rem;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.error_site .page-header {
+ margin-top: 1em;
+}
+
+[class^=container-] .span-col-2,
+[class*=" container-"] .span-col-2 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 50%;
+ flex: 0 0 50%;
+ max-width: calc(50% - 1em);
+}
+
+[class^=container-] .span-col-3,
+[class*=" container-"] .span-col-3 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 33.333%;
+ flex: 0 0 33.333%;
+ max-width: calc(33.333% - 1em);
+}
+
+[class^=container-] .span-col-4,
+[class*=" container-"] .span-col-4 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 25%;
+ flex: 0 0 25%;
+ max-width: calc(25% - 1em);
+}
+
+@supports (display: grid) {
+
+ [class^=span-],
+ [class*=" span-"] {
+ grid-column-end: auto;
+ grid-row-end: auto;
+ }
+
+ @media (min-width: 768px) {
+
+ [class^=span-col],
+ [class*=" span-col"] {
+ grid-column-end: span 2;
+ }
+ }
+
+ @media (min-width: 992px) {
+ .span-col-2 {
+ grid-column-end: span 2;
+ }
+
+ .span-col-3 {
+ grid-column-end: span 3;
+ }
+
+ .span-col-4 {
+ grid-column-end: span 4;
+ }
+
+ .span-row-2 {
+ grid-row-end: span 2;
+ }
+
+ .span-row-3 {
+ grid-row-end: span 3;
+ }
+
+ .span-row-4 {
+ grid-row-end: span 4;
+ }
+ }
+
+ [class^=container-] [class^=span-],
+ [class^=container-] [class*=" span-"],
+ [class*=" container-"] [class^=span-],
+ [class*=" container-"] [class*=" span-"] {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 1 auto;
+ flex: 0 1 auto;
+ max-width: none;
+ }
+}
+
+/* Hide empty system message container */
+#system-message-container:empty {
+ display: none;
+}
+
+.blog-items {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ width: 100%;
+ padding: 0;
+ margin-right: -0.5em;
+ margin-bottom: 1em;
+ margin-left: -0.5em;
+}
+
+@media (min-width: 992px) {
+ .blog-items.columns-2>div {
+ width: 50%;
+ }
+
+ .blog-items.columns-3>div {
+ width: 33.33333%;
+ }
+
+ .blog-items.columns-4>div {
+ width: 25%;
+ }
+}
+
+.readmore {
+ text-align: right;
+}
+
+.blog-items .readmore a {
+ width: 100%;
+}
+
+.blog-item {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 0%;
+ flex: 1 1 0%;
+ height: 100%;
+ padding: 0 0.5em 1em;
+ overflow: hidden;
+}
+
+.blog-item .item-content {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+}
+
+.blog-item .readmore {
+ margin-top: auto;
+}
+
+.boxed .blog-item {
+ background-color: var(--bs-body-bg);
+}
+
+.boxed .blog-item figure.item-image {
+ border-top: solid 0.25em var(--accent-color-primary, #3f8ff0);
+ border-bottom: solid 0.25em var(--accent-color-secondary, #6fb3ff);
+}
+
+.boxed .blog-item .item-content {
+ padding: 1.5625rem;
+}
+
+.blog-item .item-image {
+ margin-top: 0.1875rem;
+ margin-bottom: 0.9375rem;
+ overflow: hidden;
+ max-height: 250px;
+}
+
+.blog-item .item-image img{
+ width: 100%;
+}
+
+.boxed .blog-item .item-image {
+ margin-bottom: 0;
+}
+
+@media (min-width: 992px) {
+ .image-right .blog-item .item-image {
+ -webkit-box-ordinal-group: 2;
+ -ms-flex-order: 1;
+ order: 1;
+ }
+}
+
+.image-bottom .blog-item .item-image {
+ margin-top: -0.9375rem;
+ -webkit-box-ordinal-group: 2;
+ -ms-flex-order: 1;
+ order: 1;
+}
+
+.image-left .blog-item .item-content {
+ padding-left: 1.5625rem;
+}
+
+.image-right .blog-item .item-content {
+ padding-right: 1.5625rem;
+}
+
+.image-left .blog-item,
+.image-right .blog-item {
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+}
+
+@media (min-width: 992px) {
+
+ .image-left .blog-item,
+ .image-right .blog-item {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ }
+
+ .image-left .blog-item .item-image,
+ .image-right .blog-item .item-image {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 40%;
+ flex: 1 0 40%;
+ max-width: 35%;
+ margin-right: 1em;
+ }
+
+ .image-left .blog-item .item-content,
+ .image-right .blog-item .item-content {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 60%;
+ flex: 1 0 60%;
+ }
+}
+
+.article-info {
+ margin-bottom: 0;
+}
+
+.article-info dd,
+.article-info dt {
+ padding: 0;
+ display: inline-block;
+ margin-bottom: 0em;
+}
+
+ul.tags {
+ margin-bottom: 0.25em;
+}
+
+.items-leading .item-image {
+ max-width: 100%;
+ width: 100% ;
+}
+
+@supports (display: grid) {
+ .blog-items {
+ display: grid;
+ margin: 0 0 1em;
+ grid-auto-flow: row;
+ grid-template-columns: 1fr;
+ grid-gap: 1em;
+ }
+
+ .blog-items .blog-item {
+ padding: 0;
+ }
+
+ .blog-items[class^=columns-]>div,
+ .blog-items[class*=" columns-"]>div {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 1 auto;
+ flex: 0 1 auto;
+ width: auto;
+ max-width: none;
+ }
+
+ @media (min-width: 992px) {
+ .blog-items.columns-2 {
+ grid-template-columns: 1fr 1fr;
+ }
+
+ .blog-items.columns-3 {
+ grid-template-columns: 1fr 1fr 1fr;
+ }
+
+ .blog-items.columns-4 {
+ grid-template-columns: 1fr 1fr 1fr 1fr;
+ }
+ }
+}
+
+.blog-items[class^=masonry-],
+.blog-items[class*=" masonry-"] {
+ display: block;
+ -webkit-column-gap: 1em;
+ -moz-column-gap: 1em;
+ column-gap: 1em;
+}
+
+.blog-items[class^=masonry-] .blog-item,
+.blog-items[class*=" masonry-"] .blog-item {
+ display: -webkit-inline-box;
+ display: -ms-inline-flexbox;
+ display: inline-flex;
+ margin-bottom: 1em;
+ page-break-inside: avoid;
+ -webkit-column-break-inside: avoid;
+ -moz-column-break-inside: avoid;
+ break-inside: avoid;
+}
+
+@media (min-width: 992px) {
+ .blog-items.masonry-2 {
+ -webkit-column-count: 2;
+ -moz-column-count: 2;
+ column-count: 2;
+ }
+
+ .blog-items.masonry-3 {
+ -webkit-column-count: 3;
+ -moz-column-count: 3;
+ column-count: 3;
+ }
+
+ .blog-items.masonry-4 {
+ -webkit-column-count: 4;
+ -moz-column-count: 4;
+ column-count: 4;
+ }
+}
+
+.image-alternate .blog-item:nth-of-type(2n+1) .item-image {
+ -webkit-box-ordinal-group: 1;
+ -ms-flex-order: 0;
+ order: 0;
+}
+
+.image-alternate.image-left .blog-item:nth-of-type(2n+1) .item-image {
+ margin-right: 0;
+ margin-left: 1.5625rem;
+ -webkit-box-ordinal-group: 2;
+ -ms-flex-order: 1;
+ order: 1;
+}
+
+.image-alternate.image-top .blog-item:nth-of-type(2n+1) .item-image {
+ -webkit-box-ordinal-group: 2;
+ -ms-flex-order: 1;
+ order: 1;
+}
+
+.breadcrumb {
+ margin-bottom: 0;
+ background-color: hsla(0, 0%, 0%, 0.03);
+}
+
+.no-card .newsflash-horiz li {
+ padding: 0 1rem 1rem;
+ border: 1px solid hsl(210, 14%, 89%);
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ border-bottom-left-radius: 0.25rem;
+ border-bottom-right-radius: 0.25rem;
+ -webkit-box-shadow: 1px 1px 4px hsla(0, 0%, 0%, 0.1);
+ box-shadow: 1px 1px 4px hsla(0, 0%, 0%, 0.1);
+}
+
+.no-card .newsflash-horiz li figure {
+ margin: 0 -1rem 1rem;
+}
+
+.mod-list {
+ -webkit-padding-start: 0;
+ padding-inline-start: 0;
+ list-style: none;
+}
+
+.mod-list li {
+ padding: 0.25em 0.5rem;
+}
+
+.mod-list li a {
+ text-decoration: none;
+}
+
+.mod-list li a:active {
+ text-decoration: underline;
+}
+
+.container-header .mod-list li a:active {
+ text-decoration: none;
+}
+
+.mod-list li.active>a {
+ text-decoration: underline;
+}
+
+.container-header .mod-list li.active>a {
+ text-decoration: none;
+}
+
+.mod-list li .mod-menu__sub {
+ padding-left: 1em;
+}
+
+.element-invisible {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ white-space: nowrap;
+ border: 0;
+ -webkit-clip-path: inset(50%);
+ clip-path: inset(50%);
+}
+
+.hidden {
+ display: none;
+ visibility: hidden;
+}
+
+.table-row {
+ display: table-row;
+}
+
+joomla-alert {
+ display: none;
+}
+
+.editor-xtd-buttons .btn {
+ margin-bottom: 0.3125rem;
+}
+
+.subhead {
+ position: sticky;
+ top: 0;
+ right: 0;
+ left: 0;
+ z-index: 1000;
+ width: auto;
+ min-height: 43px;
+ padding: 0.25rem;
+ color: var(--subhead-color, #9fa6ad);
+ background: var(--body-color, #e6ebf1);
+ -webkit-box-shadow: -3px -2px 22px var(--box-shadow-gray, #1a2027);
+ box-shadow: -3px -2px 22px var(--box-shadow-gray, #1a2027);
+}
+
+.subhead .row {
+ margin-right: 0;
+ margin-left: 0;
+}
+
+.subhead.noshadow {
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.subhead joomla-toolbar-button,
+.subhead .btn-group {
+ -webkit-margin-start: 0.75rem;
+ margin-inline-start: 0.75rem;
+}
+
+.subhead joomla-toolbar-button:first-child,
+.subhead .btn-group:first-child {
+ -webkit-margin-start: 0;
+ margin-inline-start: 0;
+}
+
+.subhead joomla-toolbar-button .btn>span,
+.subhead joomla-toolbar-button .dropdown-item>span {
+ -webkit-margin-end: 0.5rem;
+ margin-inline-end: 0.5rem;
+ width: 1.25em;
+ text-align: center;
+}
+
+.subhead .btn {
+ --subhead-btn-accent: var(--subhead-color, #9fa6ad);
+ padding: 0 1rem;
+ margin: 0.3125rem 0;
+ font-size: 1rem;
+ line-height: 2.45rem;
+ color: var(--subhead-color, #9fa6ad);
+ background: var(--body-color, #e6ebf1);
+ border-color: hsl(210, 11%, 71%);
+}
+
+.subhead .btn>span {
+ display: inline-block;
+ color: var(--subhead-btn-accent);
+}
+
+.subhead .btn:not([disabled]):active,
+.subhead .btn:not([disabled]):active,
+.subhead .btn:not([disabled]):focus {
+ color: rgba(255, 255, 255, 0.9);
+ background-color: var(--subhead-btn-accent);
+ border-color: var(--subhead-btn-accent);
+}
+
+.subhead .btn:not([disabled]):active>span,
+.subhead .btn:not([disabled]):active>span,
+.subhead .btn:not([disabled]):focus>span {
+ color: rgba(255, 255, 255, 0.9);
+}
+
+.subhead .btn.btn-success {
+ --subhead-btn-accent: var(--success, #4aa664);
+}
+
+.subhead .btn.btn-danger {
+ --subhead-btn-accent: var(--danger, #c23a31);
+}
+
+.subhead .btn.btn-primary {
+ --subhead-btn-accent: #2a69b8;
+}
+
+.subhead .btn.btn-secondary {
+ --subhead-btn-accent: #001b4c;
+}
+
+.subhead .btn.btn-info {
+ --subhead-btn-accent: #132f53;
+}
+
+.subhead .btn.btn-action {
+ --subhead-btn-accent: #132f53;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+
+.subhead .btn.btn-action::after {
+ width: 2.375rem;
+ font-family: "Font Awesome 5 Free";
+ font-weight: 900;
+ content: "\f078";
+ border: 0;
+}
+
+.subhead .btn[disabled],
+.subhead .btn.dropdown-toggle[disabled] {
+ --subhead-btn-accent: #132f53;
+ background: rgba(223, 227, 231, 0.8);
+ opacity: 0.5;
+}
+
+.subhead .btn[disabled]:active,
+.subhead .btn[disabled]:active,
+.subhead .btn[disabled]:focus,
+.subhead .btn.dropdown-toggle[disabled]:active,
+.subhead .btn.dropdown-toggle[disabled]:active,
+.subhead .btn.dropdown-toggle[disabled]:focus {
+ cursor: not-allowed;
+}
+
+.subhead .dropdown-toggle.btn {
+ -webkit-padding-end: 0;
+ padding-inline-end: 0;
+}
+
+.subhead .btn-group:not(:last-child)>.dropdown-toggle-split {
+ -webkit-box-ordinal-group: 2;
+ -ms-flex-order: 1;
+ order: 1;
+ -webkit-margin-start: -0.25rem;
+ margin-inline-start: -0.25rem;
+ border-radius: 0 0.25rem 0.25rem 0;
+}
+
+.subhead .dropdown-menu joomla-toolbar-button,
+.subhead .btn-group joomla-toolbar-button {
+ -webkit-margin-start: 0;
+ margin-inline-start: 0;
+}
+
+@media (max-width: 767.98px) {
+
+ joomla-tab[view=accordion] .col-md-9,
+ joomla-tab[view=accordion] .col-md-3 {
+ padding: 0.5rem 1rem ;
+ }
+
+ #myTab {
+ margin-top: 1rem;
+ margin-bottom: 1.5rem;
+ }
+
+ joomla-tab[view=accordion] ul li {
+ width: 100%;
+ }
+
+ .subhead joomla-toolbar-button,
+ .subhead .btn-group,
+ .subhead .btn {
+ width: 100%;
+ margin-left: 0;
+ text-align: left;
+ }
+
+ .subhead .btn-toolbar>.btn-group,
+ .subhead .btn-toolbar>joomla-toolbar-button {
+ margin-left: 0;
+ }
+
+ .subhead .btn.btn-action::after {
+ text-align: center;
+ -webkit-margin-start: auto;
+ margin-inline-start: auto;
+ }
+
+ .subhead .dropdown-toggle-split {
+ width: auto;
+ }
+}
+
+.left.item-image {
+ float: left;
+}
+
+.view-article .left.item-image {
+ max-width: 300px;
+}
+
+.hide-image .left.item-image {
+ display: none;
+}
+
+.right.item-image {
+ float: right;
+ width: 40%;
+ max-width: 300px;
+}
+
+.tags .list-inline-item {
+ margin: 0.25rem 0.25rem 0.25rem;
+}
+
+.tags a.btn {
+ font-weight: 700;
+}
+
+
+
+.tag {
+ display: inline-block;
+ padding: 0.5rem 0.5rem 0.5rem 0;
+}
+
+body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+}
+
+body.wrapper-fluid .site-grid {
+ grid-template-columns: [full-start] minmax(0, 1fr) [main-start] repeat(4, minmax(0, 25%)) [main-end] minmax(0, 1fr) [full-end];
+ grid-gap: 0 2em;
+}
+
+body.wrapper-fluid .grid-child {
+ max-width: none;
+}
+
+body.wrapper-fluid header>.grid-child,
+body.wrapper-fluid footer>.grid-child {
+ padding-right: var(--navbar-padding-x, 1rem);
+ padding-left: var(--navbar-padding-x, 1rem);
+ padding-top: 0;
+ padding-bottom: 0;
+}
+
+body.wrapper-fluid header>.grid-child {
+ margin: 0;
+}
+
+footer .grid-child>div {
+ padding: calc(var(--navbar-padding-y, 1rem) * 3)
+ calc(var(--navbar-padding-x, 1rem) * 1)
+ 0;
+}
+
+.mod-footer {
+ border-top: 1px solid var(--border-gray, #b2bfcds);
+}
+
+header .grid-child .navbar-brand {
+ padding-left: 0;
+ padding-right: 0;
+}
+
+body:not(.has-sidebar-left) .site-grid .container-component {
+ grid-column-start: main-start;
+}
+
+body:not(.has-sidebar-right) .site-grid .container-component {
+ grid-column-end: main-end;
+}
+
+.site-grid {
+ margin-bottom: auto;
+}
+
+@supports (display: grid) {
+ .site-grid {
+ display: grid;
+ grid-template-areas:
+ ". banner banner banner banner ."
+ ". top-a top-a top-a top-a ."
+ ". top-b top-b top-b top-b ."
+ ". comp comp comp comp ."
+ ". side-l side-l side-l side-l ."
+ ". side-r side-r side-r side-r ."
+ ". bot-a bot-a bot-a bot-a ."
+ ". bot-b bot-b bot-b bot-b .";
+ grid-template-columns: [full-start] minmax(0, 1fr) [main-start] repeat(4, minmax(0, 19.875rem)) [main-end] minmax(0, 1fr) [full-end];
+ grid-gap: 0 1em;
+ }
+
+ .site-grid>[class^=container-],
+ .site-grid>[class*=" container-"] {
+ width: 100%;
+ max-width: none;
+ -webkit-column-gap: 1em;
+ -moz-column-gap: 1em;
+ column-gap: 1em;
+ }
+
+ .site-grid>.full-width {
+ grid-column: full-start/full-end;
+ }
+
+ @media (min-width: 992px) {
+ .site-grid {
+ grid-template-areas: ". banner banner banner banner ."". top-a top-a top-a top-a ."". top-b top-b top-b top-b ."". side-l comp comp side-r ."". bot-a bot-a bot-a bot-a ."". bot-b bot-b bot-b bot-b .";
+ }
+ }
+}
+
+.container-banner {
+ grid-area: banner;
+}
+
+.container-top-a {
+ grid-area: top-a;
+}
+
+.container-top-b {
+ grid-area: top-b;
+}
+
+.container-component {
+ grid-area: comp;
+}
+
+.container-sidebar-left {
+ grid-area: side-l;
+}
+
+.container-sidebar-right {
+ grid-area: side-r;
+}
+
+/* Sidebar accordion */
+.container-sidebar-left.accordion .card,
+.container-sidebar-right.accordion .card {
+ border: none;
+ border-bottom: 1px solid var(--border-color, #dee2e6);
+ border-radius: 0;
+}
+
+.container-sidebar-left.accordion .card-header,
+.container-sidebar-right.accordion .card-header {
+ padding: 0;
+ background: none;
+ border: none;
+}
+
+.container-sidebar-left.accordion .accordion-button,
+.container-sidebar-right.accordion .accordion-button {
+ padding: .75rem 1rem;
+ font-weight: 600;
+ font-size: .95rem;
+ background: var(--bs-body-bg, #fff);
+ color: var(--body-font-color, #444);
+}
+
+.container-sidebar-left.accordion .accordion-button:not(.collapsed),
+.container-sidebar-right.accordion .accordion-button:not(.collapsed) {
+ background: var(--bs-body-bg, #fff);
+ color: var(--link-color, #3565e5);
+ box-shadow: none;
+}
+
+.container-main-top {
+ grid-area: main-t;
+}
+
+.container-main-bottom {
+ grid-area: main-b;
+}
+
+.container-breadcrumbs {
+ grid-area: bread;
+}
+
+.container-bottom-a {
+ grid-area: bot-a;
+}
+
+.container-bottom-b {
+ grid-area: bot-b;
+}
+
+.mod-finder__search.input-group {
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+}
+
+.mod-finder__search.input-group .awesomplete input {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+
+.mod-finder__search.input-group button {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+
+.mod-finder__search.input-group button .icon-search {
+ -webkit-margin-end: 0.2em;
+ margin-inline-end: 0.2em;
+}
+
+.awesomplete>input {
+ max-width: 200px;
+}
+
+@media (min-width: 992px) {
+ .awesomplete>input {
+ max-width: none;
+ }
+}
+
+.awesomplete>ul {
+ z-index: 1000 ;
+}
+
+.btn:focus,
+.btn.focus,
+.btn:active:focus,
+.btn.focus:active,
+.btn.active:focus,
+.btn.active.focus {
+ text-decoration: none;
+}
+
+.btn.group-move {
+ cursor: move;
+}
+
+.btn-secondary {
+ color: var(--btn-color);
+ background-color: var(--btn-bg, transparent);
+ border-color: var(--btn-border-color, transparent);
+}
+
+.btn-secondary:active {
+ color: var(--btn-active-color);
+ background-color: var(--btn-active-bg, hsl(210, 10%, 30%));
+ border-color: var(--btn-active-border-color, transparent);
+}
+
+.btn-secondary:focus,
+.btn-secondary:hover {
+ color: var(--btn-focus-color);
+ background-color: var(--btn-focus-bg);
+ border-color: var(--btn-focus-border-color);
+ box-shadow: 1px 5px 100px 1px var(--btn-focus-shadow-rgb, 84, 114, 255);
+}
+
+.btn-secondary:active {
+ color: var(--btn-active-color);
+ background-color: var(--btn-active-bg, hsl(210, 10%, 30%));
+ border-color: var(--btn-active-border-color, transparent);
+ box-shadow: 1px 5px 100px 1px var(--btn-active-shadow-rgb);
+}
+
+.article-info .association .btn-secondary,
+.cat-list-association .btn-secondary {
+ font-weight: 700;
+ color: var(--body-color, #e6ebf1);
+ background-color: hsl(210, 7%, 46%);
+ border-color: hsl(210, 14%, 83%);
+}
+
+.article-info .association .btn-secondary:active,
+.article-info .association .btn-secondary:focus,
+.cat-list-association .btn-secondary:active,
+.cat-list-association .btn-secondary:focus {
+ color: var(--body-color, #e6ebf1);
+ background-color: hsl(210, 10%, 23%);
+}
+
+.article-info .association .btn-sm,
+.article-info .association .btn-group-sm>.btn,
+.cat-list-association .btn-sm,
+.cat-list-association .btn-group-sm>.btn {
+ padding: 0 0.25rem;
+ font-size: 0.8rem;
+ border-radius: 0.2rem;
+}
+
+@media (max-width: 991.98px) {
+ .btn {
+ margin-bottom: 0.25rem;
+ }
+
+ .input-group .btn {
+ margin-bottom: 0;
+ }
+}
+
+.form-select,
+.custom-select {
+ max-width: 100%;
+ cursor: pointer;
+ background: url("../images/select-bg.svg") no-repeat right center/116rem
+ /* rtl: url("../images/select-bg-rtl.svg") no-repeat left center/116rem */
+ ;
+ background-color: hsl(210, 16%, 93%);
+ border: 1px solid hsl(210, 14%, 83%);
+}
+
+.form-select:focus,
+.custom-select:focus {
+ border-color: var(--black, #000);
+ -webkit-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+ box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+}
+
+.form-select[multiple],
+[multiple].custom-select {
+ padding: 0;
+ background-color: var(--body-color, #e6ebf1);
+}
+
+.form-select[multiple] option,
+[multiple].custom-select option {
+ padding: 0.3rem 1rem;
+ background-color: var(--body-color, #e6ebf1);
+}
+
+.form-select[multiple] option:checked,
+[multiple].custom-select option:checked {
+ color: var(--body-color, #e6ebf1);
+ background-color: var(--color-primary, #112855) ;
+}
+
+.form-select.form-select-success,
+.form-select-success.custom-select,
+.form-select.custom-select-success,
+.custom-select-success.custom-select {
+ color: hsl(120, 32%, 39%);
+ background-color: hsl(120, 32%, 39%);
+}
+
+.form-select.form-select-success option,
+.form-select-success.custom-select option,
+.form-select.custom-select-success option,
+.custom-select-success.custom-select option {
+ color: hsl(210, 11%, 15%);
+ background-color: var(--body-color, #e6ebf1);
+}
+
+.form-select.form-select-danger,
+.form-select-danger.custom-select,
+.form-select.custom-select-danger,
+.custom-select-danger.custom-select {
+ color: hsl(3, 75%, 37%);
+ background-color: hsl(3, 75%, 37%);
+}
+
+.form-select.form-select-danger option,
+.form-select-danger.custom-select option,
+.form-select.custom-select-danger option,
+.custom-select-danger.custom-select option {
+ color: hsl(210, 11%, 15%);
+ background-color: var(--body-color, #e6ebf1);
+}
+
+.form-select optgroup,
+.custom-select optgroup,
+.form-select option,
+.custom-select option {
+ color: var(--dark, #0f1318);
+ background-color: var(--body-color, #e6ebf1);
+}
+
+.accordion .card-header {
+ display: block;
+ font-size: 1.25rem;
+ font-weight: var(--font-weight-headings, 700);
+ line-height: 1.2;
+}
+
+.accordion .list-group-item {
+ color: var(--color-link, white);
+}
+
+.dropdown-menu {
+ padding: 0.2rem 0;
+ margin-top: 0.5rem;
+ background-color: var(--body-color, #e6ebf1);
+ border-color: hsl(210, 14%, 89%);
+}
+
+.dropdown-menu-end::after {
+ right: 0.9rem;
+ left: auto;
+}
+
+.field-media-wrapper {
+ display: block;
+ width: 100%;
+ max-width: calc(50vw - 5rem);
+}
+
+.field-media-wrapper .field-media-preview {
+ width: 100%;
+ max-width: none;
+}
+
+@media (max-width: 991.98px) {
+ .field-media-wrapper {
+ min-width: 100%;
+ }
+}
+
+.list-group-item {
+ background-color: var(--body-color, #e6ebf1);
+}
+
+.list-unstyled .list-unstyled {
+ padding-left: 1.25rem;
+}
+
+.jviewport-height10 {
+ height: 10vh;
+}
+
+.jviewport-height20 {
+ height: 20vh;
+}
+
+.jviewport-height30 {
+ height: 30vh;
+}
+
+.jviewport-height40 {
+ height: 40vh;
+}
+
+.jviewport-height50 {
+ height: 50vh;
+}
+
+.jviewport-height60 {
+ height: 60vh;
+}
+
+.jviewport-height70 {
+ height: 70vh;
+}
+
+.jviewport-height80 {
+ height: 80vh;
+}
+
+.jviewport-height90 {
+ height: 90vh;
+}
+
+.jviewport-height100 {
+ height: 100vh;
+}
+
+[class*=jviewport-height] iframe {
+ height: 100%;
+}
+
+.modal-dialog.jviewport-width10 {
+ width: 10vw;
+ max-width: none;
+}
+
+.modal-dialog.jviewport-width20 {
+ width: 20vw;
+ max-width: none;
+}
+
+.modal-dialog.jviewport-width30 {
+ width: 30vw;
+ max-width: none;
+}
+
+.modal-dialog.jviewport-width40 {
+ width: 40vw;
+ max-width: none;
+}
+
+.modal-dialog.jviewport-width50 {
+ width: 50vw;
+ max-width: none;
+}
+
+.modal-dialog.jviewport-width60 {
+ width: 60vw;
+ max-width: none;
+}
+
+.modal-dialog.jviewport-width70 {
+ width: 70vw;
+ max-width: none;
+}
+
+.modal-dialog.jviewport-width80 {
+ width: 80vw;
+ max-width: none;
+}
+
+.modal-dialog.jviewport-width90 {
+ width: 90vw;
+ max-width: none;
+}
+
+.modal-dialog.jviewport-width100 {
+ width: 100vw;
+ max-width: none;
+}
+
+.nav.nav-tabs {
+ padding: 0;
+ margin: 0;
+ background-color: hsl(0, 0%, 96%);
+ border: 1px solid hsl(210, 14%, 89%);
+ border-bottom: 0;
+ border-radius: 0.25rem 0.25rem 0 0;
+ -webkit-box-shadow: 0 1px var(--body-color, #e6ebf1) inset, 0 2px 3px -3px hsla(0, 0%, 0%, 0.15), 0 -4px 0 hsla(0, 0%, 0%, 0.05) inset, 1px 1px 4px hsla(0, 0%, 0%, 0.1);
+ box-shadow: 0 1px var(--body-color, #e6ebf1) inset, 0 2px 3px -3px hsla(0, 0%, 0%, 0.15), 0 -4px 0 hsla(0, 0%, 0%, 0.05) inset, 1px 1px 4px hsla(0, 0%, 0%, 0.1);
+}
+
+.nav.nav-tabs .nav-item {
+ margin-bottom: 0;
+ margin-left: 0;
+}
+
+.nav.nav-tabs .nav-item:first-of-type .nav-link.active {
+ border-radius: 0.25rem 0 0;
+ -webkit-box-shadow: -1px 0 1px -1px hsla(0, 0%, 0%, 0.06), inset -2px 0 1px -1px hsla(0, 0%, 0%, 0.08), inset 0 1px 0 hsla(0, 0%, 0%, 0.02);
+ box-shadow: -1px 0 1px -1px hsla(0, 0%, 0%, 0.06), inset -2px 0 1px -1px hsla(0, 0%, 0%, 0.08), inset 0 1px 0 hsla(0, 0%, 0%, 0.02);
+}
+
+.nav.nav-tabs .nav-item:last-of-type .nav-link {
+ -webkit-box-shadow: -1px 0 0 hsla(0, 0%, 0%, 0.05), 1px 0 0 hsla(0, 0%, 0%, 0.05);
+ box-shadow: -1px 0 0 hsla(0, 0%, 0%, 0.05), 1px 0 0 hsla(0, 0%, 0%, 0.05);
+}
+
+.nav.nav-tabs .nav-item:last-of-type .nav-link.active {
+ -webkit-box-shadow: inset 2px 0 1px -1px hsla(0, 0%, 0%, 0.08), inset -2px 0 1px -1px hsla(0, 0%, 0%, 0.08), inset 0 1px 0 hsla(0, 0%, 0%, 0.02);
+ box-shadow: inset 2px 0 1px -1px hsla(0, 0%, 0%, 0.08), inset -2px 0 1px -1px hsla(0, 0%, 0%, 0.08), inset 0 1px 0 hsla(0, 0%, 0%, 0.02);
+}
+
+.nav.nav-tabs .nav-link {
+ position: relative;
+ padding: 0.75em 1em;
+ color: var(--color-primary, #112855);
+ border: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ -webkit-box-shadow: -1px 0 0 hsla(0, 0%, 0%, 0.05);
+ box-shadow: -1px 0 0 hsla(0, 0%, 0%, 0.05);
+}
+
+.nav.nav-tabs .nav-link.active {
+ background-color: hsla(0, 0%, 0%, 0.3);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(hsla(0, 0%, 0%, 0)), to(hsla(0, 0%, 0%, 0.05)));
+ background-image: -o-linear-gradient(top, hsla(0, 0%, 0%, 0), hsla(0, 0%, 0%, 0.05) 100%);
+ background-image: linear-gradient(to bottom, hsla(0, 0%, 0%, 0), hsla(0, 0%, 0%, 0.05) 100%);
+ border-right: 0;
+ border-left: 0;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ -webkit-box-shadow: inset 2px 0 1px -1px hsla(0, 0%, 0%, 0.08), inset -2px 0 1px -1px hsla(0, 0%, 0%, 0.08), inset 0 1px 0 hsla(0, 0%, 0%, 0.02);
+ box-shadow: inset 2px 0 1px -1px hsla(0, 0%, 0%, 0.08), inset -2px 0 1px -1px hsla(0, 0%, 0%, 0.08), inset 0 1px 0 hsla(0, 0%, 0%, 0.02);
+}
+
+.nav.nav-tabs .nav-link.active::after {
+ position: absolute;
+ right: 0;
+ bottom: -1px;
+ left: 0;
+ height: 5px;
+ content: "";
+ background-color: var(--color-primary, #112855);
+ opacity: 0.8;
+}
+
+.nav-tabs+.tab-content {
+ padding: 0.9375rem;
+ background: var(--body-color, #e6ebf1);
+ border: 1px solid;
+ border-color: hsl(210, 14%, 89%);
+ border-radius: 0 0 0.25rem 0.25rem;
+ -webkit-box-shadow: 1px 1px 4px hsla(0, 0%, 0%, 0.1);
+ box-shadow: 1px 1px 4px hsla(0, 0%, 0%, 0.1);
+}
+
+.pagination {
+ margin: 1rem;
+}
+
+.table th {
+ font-weight: 500;
+}
+
+.table thead th {
+ white-space: nowrap;
+ border-bottom-width: 1px;
+}
+
+.table th,
+.table td {
+ vertical-align: middle;
+}
+
+.table th label,
+.table td label {
+ margin-bottom: 0;
+}
+
+.chosen-container.chosen-container-single {
+ max-width: 100%;
+ font-size: 1rem;
+}
+
+.chosen-container.chosen-container-single .chosen-single {
+ display: inline-block;
+ height: calc(1.5em + 1.2rem + 2px);
+ padding: 0.81rem 4rem 0.81rem 1rem;
+ line-height: 1.5;
+ color: hsl(210, 11%, 15%);
+ vertical-align: middle;
+ background: hsl(210, 16%, 93%) url("../images/select-bg.svg") no-repeat right .1rem center;
+ background-image: none;
+ background-size: 116rem;
+ border: 1px solid hsl(210, 14%, 83%);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ border-radius: 0.25rem;
+ width:100%;
+}
+
+.chosen-container.chosen-container-single .chosen-single abbr {
+ top: 10px;
+}
+
+.chosen-container.chosen-container-single .chosen-single:focus {
+ border-color: var(--input-focus-border-color, #5472ff);
+ outline: none;
+}
+
+.chosen-container.chosen-container-single .chosen-single:disabled {
+ cursor: not-allowed;
+ background-color: hsl(210, 16%, 93%);
+}
+
+.chosen-container.chosen-container-single .chosen-single div b {
+ background: none ;
+}
+
+.chosen-container.chosen-container-single .chosen-drop {
+ background: var(--body-color, #e6ebf1);
+ border: 1px solid hsl(210, 14%, 83%);
+}
+
+.chosen-container.chosen-container-single .chosen-results li {
+ line-height: calc(1rem + .3rem);
+}
+
+.chosen-container.chosen-container-single.chosen-container-active .chosen-single {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.chosen-container.chosen-container-multi .chosen-choices {
+ max-width: 100%;
+ min-height: calc(1.5em + 1.2rem + 2px);
+ font-size: 1rem;
+ line-height: 1.5;
+ background-image: var(--body-color, #e6ebf1);
+}
+
+.chosen-container.chosen-container-multi .chosen-choices li.search-choice {
+ padding: 0.3125rem 2.0625rem 0.3125rem 0.625rem;
+ color: var(--body-color, #e6ebf1);
+ background: var(--primary, #010156);
+ border: 0;
+ -webkit-box-shadow: 1px 1px 4px hsla(0, 0%, 0%, 0.1);
+ box-shadow: 1px 1px 4px hsla(0, 0%, 0%, 0.1);
+ border-radius: 0.25rem;
+}
+
+.chosen-container.chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
+ top: 0;
+ right: 0;
+ width: 20px;
+ height: 100%;
+ background: hsla(0, 0%, 0%, 0.2);
+ background-image: none ;
+}
+
+.chosen-container.chosen-container-multi .chosen-choices li.search-choice .search-choice-close::before {
+ position: absolute;
+ top: 6px;
+ right: 5px;
+ font-size: 1rem;
+ color: var(--body-color, #e6ebf1);
+ content: "×";
+}
+
+.chosen-container-active.chosen-with-drop .chosen-single {
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.chosen-container-single {
+ width: auto ;
+}
+
+.card .chosen-container.chosen-container-single {
+ width: 100% ;
+}
+
+.card .chosen-container.chosen-container-single .chosen-single {
+ width: 100% ;
+}
+
+.gu-mirror {
+ position: fixed ;
+ z-index: 9999 ;
+ margin: 0 ;
+ background-color: hsl(120, 73%, 75%);
+ opacity: 0.8;
+}
+
+.gu-mirror.table {
+ display: table;
+}
+
+.gu-mirror.table td {
+ display: table-cell;
+}
+
+.menu-horizontal {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 100%;
+ flex: 1 0 100%;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+@media (min-width: 992px) {
+ .menu-horizontal {
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 0%;
+ flex: 1 1 0%;
+ }
+}
+
+.menu-horizontal>li {
+ position: relative;
+}
+
+.metismenu.mod-menu {
+ margin: 0;
+}
+
+.metismenu.mod-menu .metismenu-item {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ padding: 0.5em 1em;
+ font-size: 1.1rem;
+ line-height: 1.5;
+}
+
+.metismenu.mod-menu .metismenu-item.parent {
+ position: relative;
+}
+
+.metismenu.mod-menu .metismenu-item>ul {
+ position: absolute;
+ top: 100%;
+ z-index: 1001;
+ display: block;
+ padding: 0;
+ list-style: none;
+ -webkit-box-shadow: 0 0 0.5em hsla(0, 0%, 0%, 0.1);
+ box-shadow: 0 0 0.5em hsla(0, 0%, 0%, 0.1);
+}
+
+.metismenu.mod-menu .metismenu-item>span,
+.metismenu.mod-menu .metismenu-item>a,
+.metismenu.mod-menu .metismenu-item>button {
+ overflow: hidden;
+ text-decoration: none;
+ -o-text-overflow: ellipsis;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.metismenu.mod-menu .metismenu-item>a:focus,
+.metismenu.mod-menu .metismenu-item>button:focus {
+ outline: 1px dotted hsl(210, 14%, 83%);
+ outline-offset: 2px;
+}
+
+.metismenu.mod-menu .metismenu-item.active>a,
+.metismenu.mod-menu .metismenu-item.active>button,
+.metismenu.mod-menu .metismenu-item>a:active,
+.metismenu.mod-menu .metismenu-item>button:active {
+ text-decoration: underline;
+}
+
+.metismenu.mod-menu .metismenu-item::after {
+ content: none;
+}
+
+.metismenu.mod-menu .metismenu-item:not(.level-1)>ul,
+.metismenu.mod-menu .metismenu-item:not(.level-2)>ul {
+ -webkit-margin-end: -1em;
+ margin-inline-end: -1em;
+}
+
+.metismenu.mod-menu .metismenu-item.divider:not(.parent) {
+ width: 1px;
+ padding: 0;
+ margin: 0.25em;
+ overflow: hidden;
+ border-right: 1px solid hsl(210, 14%, 83%);
+}
+
+@media (max-width: 991.98px) {
+ .metismenu.mod-menu .metismenu-item.divider:not(.parent) {
+ width: auto;
+ height: 1px;
+ border-bottom: 1px solid hsl(210, 14%, 83%);
+ }
+}
+
+.metismenu.mod-menu .mm-collapsing {
+ height: 0;
+ overflow: hidden;
+ -webkit-transition-timing-function: ease;
+ -o-transition-timing-function: ease;
+ transition-timing-function: ease;
+ -webkit-transition-duration: 0.35s;
+ -o-transition-duration: 0.35s;
+ transition-duration: 0.35s;
+ -webkit-transition-property: color, background-color, height, visibility;
+ -o-transition-property: color, background-color, height, visibility;
+ transition-property: color, background-color, height, visibility;
+}
+
+.metismenu.mod-menu .mm-collapse {
+ position: absolute;
+ background-color: var(--body-color, #e6ebf1);
+ -webkit-box-shadow: 1px 1px 4px hsla(0, 0%, 0%, 0.1);
+ box-shadow: 1px 1px 4px hsla(0, 0%, 0%, 0.1);
+}
+
+.metismenu.mod-menu .mm-collapse:not(.mm-show) {
+ display: none;
+}
+
+.metismenu.mod-menu .mm-collapse>li>a {
+ display: -webkit-inline-box;
+ display: -ms-inline-flexbox;
+ display: inline-flex;
+}
+
+.metismenu.mod-menu .mm-collapse>li.divider:not(.parent) {
+ width: auto;
+ height: 1px;
+ border-bottom: 1px solid hsl(210, 14%, 83%);
+}
+
+.metismenu.mod-menu .mm-collapse>li.parent .mm-toggler {
+ display: -webkit-inline-box;
+ display: -ms-inline-flexbox;
+ display: inline-flex;
+}
+
+.metismenu.mod-menu .mm-collapse>li.parent>ul {
+ position: relative;
+ top: 0;
+ -ms-flex-preferred-size: calc(100% + 1em);
+ flex-basis: calc(100% + 1em);
+ margin-top: 0.5em;
+ margin-bottom: -0.5em;
+ background-color: hsla(0, 0%, 0%, 0.03);
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.metismenu.mod-menu .mm-toggler {
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ height: 100%;
+ padding: 0;
+ color: currentColor;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ background: none;
+ border: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.metismenu.mod-menu .mm-toggler:after {
+ width: 0;
+ height: 0;
+ -webkit-margin-start: 0.5em;
+ margin-inline-start: 0.5em;
+ content: "";
+ border-top: 0.5em solid currentColor;
+ border-right: 0.5em solid transparent;
+ border-left: 0.5em solid transparent;
+ -webkit-transition: all 0.3s ease-out;
+ -o-transition: all 0.3s ease-out;
+ transition: all 0.3s ease-out;
+}
+
+.mm-active>.metismenu.mod-menu .mm-toggler:after {
+ -webkit-transform: rotateX(-180deg);
+ transform: rotateX(-180deg);
+}
+
+.metismenu.mod-menu .mm-toggler[aria-expanded=true]:after {
+ -webkit-transform: rotateX(-180deg);
+ transform: rotateX(-180deg);
+}
+
+.metismenu.mod-menu .parent>ul {
+ color: hsl(210, 11%, 15%);
+}
+
+.sidebar-right .metismenu .mm-collapse,
+.sidebar-left .metismenu .mm-collapse {
+ position: relative;
+ background-color: hsla(0, 0%, 0%, 0.03);
+}
+
+.sidebar-right .metismenu li.parent>ul,
+.sidebar-left .metismenu li.parent>ul {
+ position: relative;
+ top: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+@media (max-width: 1199.98px) {
+
+ .sidebar-right .metismenu li.parent>ul,
+ .sidebar-left .metismenu li.parent>ul {
+ width: 100%;
+ }
+}
+
+.sidebar-right .metismenu .metismenu-item>span,
+.sidebar-right .metismenu .metismenu-item>a,
+.sidebar-left .metismenu .metismenu-item>span,
+.sidebar-left .metismenu .metismenu-item>a {
+ white-space: inherit;
+}
+
+.sidebar-right .metismenu .metismenu-item.divider:not(.parent),
+.sidebar-left .metismenu .metismenu-item.divider:not(.parent) {
+ width: auto;
+ height: 1px;
+ border-bottom: 1px solid hsl(210, 14%, 83%);
+}
+
+.minicolors-theme-bootstrap .minicolors-input {
+ width: 120px;
+}
+
+.minicolors-theme-bootstrap .rgb {
+ width: 175px;
+}
+
+.minicolors-theme-bootstrap .rgba {
+ width: 220px;
+}
+
+.editor .toggle-editor {
+ margin-top: 1rem;
+}
+
+.editor .mce-tinymce {
+ border: 1px solid hsl(210, 14%, 89%);
+ border-radius: 0.25rem;
+}
+
+.editor .mce-btn,
+.editor .mce-panel {
+ background: hsl(210, 17%, 98%);
+}
+
+.tox {
+ white-space: nowrap ;
+}
+
+:root {
+ --template-sidebar-bg: var(--template-bg-dark-80);
+ --template-sidebar-font-color: var(--body-color, #e6ebf1);
+ --template-sidebar-link-color: var(--body-color, #e6ebf1);
+ --template-bg-light: #f0f4fb;
+ --template-text-light: var(--body-color, #e6ebf1);
+ --template-special-color: #132f53;
+ --template-link-color: #2a69b8;
+ --template-link-active-color: #173a65;
+ --template-contrast: #2a69b8;
+ --template-bg-dark: hsl(var(--hue), 40%, 20%);
+ --template-bg-dark-3: hsl(var(--hue), 40%, 97%);
+ --template-bg-dark-5: hsl(var(--hue), 40%, 95%);
+ --template-bg-dark-7: hsl(var(--hue), 40%, 93%);
+ --template-bg-dark-10: hsl(var(--hue), 40%, 90%);
+ --template-bg-dark-15: hsl(var(--hue), 40%, 85%);
+ --template-bg-dark-20: hsl(var(--hue), 40%, 80%);
+ --template-bg-dark-30: hsl(var(--hue), 40%, 70%);
+ --template-bg-dark-40: hsl(var(--hue), 40%, 60%);
+ --template-bg-dark-50: hsl(var(--hue), 40%, 50%);
+ --template-bg-dark-60: hsl(var(--hue), 40%, 40%);
+ --template-bg-dark-65: hsl(var(--hue), 40%, 35%);
+ --template-bg-dark-70: hsl(var(--hue), 40%, 30%);
+ --template-bg-dark-75: hsl(var(--hue), 40%, 25%);
+ --template-bg-dark-80: hsl(var(--hue), 40%, 20%);
+ --template-bg-dark-90: hsl(var(--hue), 40%, 10%);
+}
+
+.border-primary {
+ border-color: var(--primary, #010156) ;
+}
+
+.border-secondary {
+ border-color: var(--secondary, #48525d) ;
+}
+
+.border-success {
+ border-color: var(--success, #4aa664) ;
+}
+
+.border-info {
+ border-color: var(--info, #4f7aa0) ;
+}
+
+.border-warning {
+ border-color: var(--warning, #c77a00) ;
+}
+
+.border-danger {
+ border-color: var(--danger, #c23a31) ;
+}
+
+.border-light {
+ border-color: var(--light, #1b2027) ;
+}
+
+.border-dark {
+ border-color: var(--dark, #0f1318) ;
+}
+
+.border-white {
+ border-color: var(--white, #fff) ;
+}
+
+.text-primary {
+ color: var(--primary, #010156) ;
+}
+
+.text-secondary {
+ color: var(--secondary, #48525d) ;
+}
+
+.text-success {
+ color: var(--success, #4aa664) ;
+}
+
+.text-info {
+ color: var(--info, #4f7aa0) ;
+}
+
+.text-warning {
+ color: var(--warning, #c77a00) ;
+}
+
+.text-danger {
+ color: var(--danger, #c23a31) ;
+}
+
+.text-light {
+ color: var(--light, #1b2027) ;
+}
+
+.text-dark {
+ color: var(--dark, #0f1318) ;
+}
+
+.text-black {
+ color: var(--black, #000) ;
+}
+
+.text-white {
+ color: var(--white, #fff) ;
+}
+
+.text-body {
+ color: var(--body-color, #e6ebf1) ;
+}
+
+.bg-primary {
+ background-color: var(--primary, #010156) ;
+}
+
+.bg-secondary {
+ background-color: var(--secondary, #48525d) ;
+}
+
+.bg-success {
+ background-color: var(--success, #4aa664) ;
+}
+
+.bg-info {
+ background-color: var(--info, #4f7aa0) ;
+}
+
+.bg-warning {
+ background-color: var(--warning, #c77a00) ;
+}
+
+.bg-danger {
+ background-color: var(--danger, #c23a31) ;
+}
+
+.bg-light {
+ background-color: var(--light, #1b2027) ;
+}
+
+.bg-dark {
+ background-color: var(--dark, #0f1318) ;
+}
+
+.bg-black {
+ background-color: var(--black, #000) ;
+}
+
+.bg-white {
+ background-color: var(--white, #fff) ;
+}
+
+.bg-body {
+ background-color: var(--body-bg, #0e1318) ;
+}
+
+/*! VM BASIC */
+/* Bootstrap */
+.dropdown-menu {
+ border-radius: 0;
+ --bs-dropdown-zindex: 1030;
+}
+
+.dropdown-toggle {
+ display: flex;
+ align-items: center;
+}
+
+.dropdown-toggle::after {
+ font-family: "Font Awesome 6 Free", "Font Awesome 6 Pro", "FontAwesome";
+ font-weight: 900;
+ content: "\f078";
+ display: inline-block;
+ border: none;
+ font-size: 0.65em;
+ vertical-align: middle;
+}
+
+.btn {
+ border-radius: 0
+}
+
+.input-group .btn {
+ font-size: 14px;
+ border-radius: var(--bs-border-radius);
+}
+
+.btn-primary {
+ --bs-btn-bg: #333;
+ --bs-btn-border-color: #333;
+ --bs-btn-hover-bg: #555;
+ --bs-btn-hover-border-color: #555;
+ --bs-btn-focus-shadow-rgb: 49, 132, 253;
+ --bs-btn-active-bg: #555;
+ --bs-btn-active-border-color: #555;
+ --bs-btn-disabled-bg: #A0A0A0;
+ --bs-btn-disabled-border-color: #A0A0A0;
+}
+
+.btn-secondary {
+ --bs-btn-color: #333;
+ --bs-btn-bg: #EFEFEF;
+ --bs-btn-border-color: #EFEFEF;
+ --bs-btn-hover-bg: #333;
+ --bs-btn-hover-border-color: #333;
+ --bs-btn-active-bg: #333;
+ --bs-btn-active-border-color: #333;
+}
+
+.btn-check:checked+.btn,
+.btn.active,
+.btn.show,
+.btn:first-child:active,
+:not(.btn-check)+.btn:active {
+ color: var(--btn-active-text-gray, #7a8490);
+}
+
+.form-control,
+.form-select {
+ font-size: 14px
+}
+
+form .form-control,
+form .form-select {
+ border-color: var(--input-border-color, #3a4250);
+}
+
+.container-below-topbar {
+ padding: var(--padding-x, 0.15rem) var(--padding-y, 0.15rem);
+ background-image: var(--container-below-topbar-bg-image, none);
+ background-color: var(--container-below-topbar-bg-color, transparent);
+ background-size: var(--container-below-topbar-bg-size, cover);
+ -webkit-box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ background-repeat: var(--container-below-topbar-background-repeat);
+ -webkit-border-radius: var(--container-below-topbar-border-radius, 0);
+ -moz-border-radius: var(--container-below-topbar-border-radius, 0);
+ border-radius: var(--container-below-topbar-border-radius, 0);
+ border: var(--container-below-topbar-border, none);
+ color: var(--color-primary, #112855);
+}
+
+.container-top-a {
+ padding-left: var(--padding-x, 0.15rem);
+ padding-right: var(--padding-x, 0.15rem);
+ background-image: var(--container-top-a-bg-image, none);
+ background-color: var(--container-top-a-bg-color, transparent);
+ background-size: var(--container-top-a-bg-size, cover);
+ -webkit-box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ background-repeat: var(--container-top-a-background-repeat);
+ -webkit-border-radius: var(--container-top-a-border-radius, 0);
+ -moz-border-radius: var(--container-top-a-border-radius, 0);
+ border-radius: var(--container-top-a-border-radius, 0);
+ border: var(--container-top-a-border, none);
+}
+
+.container-top-b {
+ padding-left: var(--padding-x, 0.15rem);
+ padding-right: var(--padding-x, 0.15rem);
+ background-image: var(--container-top-b-bg-image, none);
+ background-color: var(--container-top-b-bg-color, transparent);
+ background-size: var(--container-top-b-bg-size, cover);
+ -webkit-box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ background-repeat: var(--container-top-b-background-repeat);
+ -webkit-border-radius: var(--container-top-b-border-radius, 0);
+ -moz-border-radius: var(--container-top-b-border-radius, 0);
+ border-radius: var(--container-top-b-border-radius, 0);
+ border: var(--container-top-b-border, none);
+}
+
+.container-sidebar-left,
+.container-sidebar-right {
+ padding-left: var(--padding-x, 0.15rem);
+ padding-right: var(--padding-x, 0.15rem);
+ background-image: var(--container-sidebar-bg-image, none);
+ background-color: var(--container-sidebar-bg-color, transparent);
+ background-size: var(--container-sidebar-bg-size, auto);
+ -webkit-box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ background-repeat: var(--container-sidebar-background-repeat);
+ -webkit-border-radius: var(--container-sidebar-border-radius, 0);
+ -moz-border-radius: var(--container-sidebar-border-radius, 0);
+ border-radius: var(--container-sidebar-border-radius, 0);
+ border: var(--container-sidebar-border, none);
+}
+
+.container-bottom-a {
+ padding-left: var(--padding-x, 0.15rem);
+ padding-right: var(--padding-x, 0.15rem);
+ background-image: var(--container-bottom-a-bg-image, none);
+ background-color: var(--container-bottom-a-bg-color, transparent);
+ background-size: var(--container-bottom-a-bg-size, cover);
+ -webkit-box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ background-repeat: var(--container-bottom-a-background-repeat);
+ -webkit-border-radius: var(--container-bottom-a-border-radius, 5px);
+ -moz-border-radius: var(--container-bottom-a-border-radius, 5px);
+ border-radius: var(--container-bottom-a-border-radius, 5px);
+ border: var(--container-bottom-a-border, none);
+}
+
+.container-bottom-b {
+ padding-left: var(--padding-x, 0.15rem);
+ padding-right: var(--padding-x, 0.15rem);
+ background-image: var(--container-bottom-b-bg-image, none);
+ background-color: var(--container-bottom-b-bg-color, transparent);
+ background-size: var(--container-bottom-b-bg-size, cover);
+ -webkit-box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ box-shadow: 0 5px 5px hsla(0, 0%, 0%, 0.03) inset;
+ background-repeat: var(--container-bottom-b-background-repeat);
+ -webkit-border-radius: var(--container-bottom-b-border-radius, 0);
+ -moz-border-radius: var(--container-bottom-b-border-radius, 0);
+ border-radius: var(--container-bottom-b-border-radius, 0);
+ border: var(--container-bottom-b-border, none);
+}
+
+/* Moko Theme FAB */
+#mokoThemeFab {
+ position: fixed;
+ z-index: 1200;
+ display: flex;
+ align-items: center;
+ gap: .5rem;
+ padding: .5rem .75rem;
+ border-radius: 999px;
+ border: 2px solid var(--theme-fab-border, rgba(255,255,255,.3));
+ background: var(--theme-fab-bg, var(--color-primary, #112855));
+ color: var(--theme-fab-color, #fff);
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.1);
+ font: inherit;
+ font-weight: 600;
+ transition: transform .15s, box-shadow .15s;
+}
+
+#mokoThemeFab:hover {
+ transform: scale(1.05);
+ box-shadow: 0 6px 28px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.15);
+}
+
+#mokoThemeFab.pos-br {
+ right: 2.5rem;
+ bottom: 1rem;
+}
+
+#mokoThemeFab.pos-bl {
+ left: 2.5rem;
+ bottom: 1rem;
+}
+
+#mokoThemeFab.pos-tr {
+ right: 2.5rem;
+ top: 1rem;
+}
+
+#mokoThemeFab.pos-tl {
+ left: 2.5rem;
+ top: 1rem;
+}
+
+/* Sun/Moon theme toggle button */
+.theme-icon-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 36px;
+ height: 36px;
+ border: none;
+ border-radius: 50%;
+ background: var(--theme-fab-btn-bg, rgba(255,255,255,.15));
+ color: inherit;
+ font-size: 1.25rem;
+ cursor: pointer;
+ padding: 0;
+ position: relative;
+}
+
+.theme-icon-btn .fa-sun,
+.theme-icon-btn .fa-moon {
+ position: absolute;
+ transition: opacity .2s, transform .2s;
+}
+
+/* Light mode: show sun, hide moon */
+.theme-icon-btn.is-light .fa-sun {
+ opacity: 1;
+ transform: rotate(0deg);
+}
+.theme-icon-btn.is-light .fa-moon {
+ opacity: 0;
+ transform: rotate(-90deg);
+}
+
+/* Dark mode: show moon, hide sun */
+.theme-icon-btn.is-dark .fa-moon {
+ opacity: 1;
+ transform: rotate(0deg);
+}
+.theme-icon-btn.is-dark .fa-sun {
+ opacity: 0;
+ transform: rotate(90deg);
+}
+
+/* Auto toggle switch (on/off style) */
+.auto-toggle-wrap {
+ display: flex;
+ align-items: center;
+ gap: .35rem;
+}
+
+.auto-label {
+ font-size: .75rem;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: .04em;
+ opacity: .7;
+ user-select: none;
+}
+
+.auto-switch {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ width: 32px;
+ height: 18px;
+ border: none;
+ border-radius: 999px;
+ background: var(--danger, #c23a31);
+ cursor: pointer;
+ padding: 0;
+ transition: background .2s;
+}
+
+.auto-switch.on {
+ background: var(--success, #4aa664);
+}
+
+.auto-track {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+.auto-knob {
+ position: absolute;
+ top: 2px;
+ left: 2px;
+ width: 14px;
+ height: 14px;
+ border-radius: 50%;
+ background: #fff;
+ box-shadow: 0 1px 3px rgba(0,0,0,.3);
+ transition: transform .2s ease;
+}
+
+.auto-switch.on .auto-knob {
+ transform: translateX(14px);
+}
+
+/* FAB divider between theme controls and a11y */
+.fab-divider {
+ display: block;
+ width: 1px;
+ height: 24px;
+ background: currentColor;
+ opacity: .25;
+ margin: 0 .15rem;
+}
+
+/* Inline a11y toggle inside theme FAB */
+/* Light mode: darker blue */
+:root[data-bs-theme="light"] .a11y-toggle-inline {
+ --a11y-btn-bg: #1565c0;
+}
+/* Dark mode: lighter blue */
+:root[data-bs-theme="dark"] .a11y-toggle-inline {
+ --a11y-btn-bg: #42a5f5;
+}
+
+.a11y-toggle-inline {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 28px;
+ height: 28px;
+ border-radius: 50%;
+ border: none;
+ background: var(--a11y-btn-bg, #1976d2);
+ color: #fff;
+ font-size: 1rem;
+ cursor: pointer;
+ padding: 0;
+}
+
+.a11y-toggle-inline.active {
+ box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--a11y-btn-bg, #1976d2);
+}
+
+/* Floating a11y panel when inline */
+.a11y-toolbar-floating {
+ position: fixed;
+ z-index: 1202;
+}
+
+body.site.error-page {
+ margin: 0;
+ padding: 0;
+}
+
+.error-wrap {
+ min-height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 2rem;
+}
+
+.error-card {
+ max-width: 820px;
+ width: 100%;
+ border: 1px solid color-mix(in srgb, currentColor 15%, transparent);
+ border-radius: 14px;
+ padding: 2rem;
+ background: var(--template-bg-light, #fff);
+}
+
+.error-brand {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ margin-bottom: 1rem;
+}
+
+.error-brand .brand-logo {
+ background-color: invert(var(--body-bg, #0e1318));
+ padding: var(--border-radius-sxl);
+ border-radius: var(--border-radius-2xl);
+}
+
+.error-brand .logo {
+ max-height: 48px;
+ width: auto;
+ display: block;
+}
+
+.error-title {
+ margin: 0.5rem 0 0;
+ font-size: clamp(1.5rem, 2vw + 1rem, 2.25rem);
+ font-weight: 700;
+}
+
+.error-code {
+ opacity: .75;
+ font-weight: 600;
+}
+
+.error-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: .75rem;
+ margin-top: 1.25rem;
+}
+
+.moko-offline-wrap {
+ min-height: 100vh;
+ display: grid;
+ grid-template-rows: auto 1fr auto;
+}
+
+.moko-offline-main {
+ display: grid;
+ place-items: center;
+ padding: 2rem 1rem;
+}
+
+.moko-card {
+ max-width: 720px;
+ width: 100%;
+}
+
+.moko-brand {
+ display: flex;
+ align-items: center;
+ gap: .75rem;
+ text-decoration: none;
+}
+
+.moko-brand .brand-tagline {
+ display: block;
+ opacity: .75;
+ font-size: .875rem;
+ line-height: 1.2;
+}
+
+.theme-switcher .dropdown-item.active {
+ font-weight: 600;
+}
+
+.skip-link {
+ position: absolute;
+ left: -9999px;
+ top: auto;
+ width: 1px;
+ height: 1px;
+ overflow: hidden;
+}
+
+.skip-l ink:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ padding: .5rem 1rem;
+}
+
+.btn {
+ display: inline-flex;
+ align-items: center;
+ gap: .5rem;
+ border: 1px solid color-mix(in srgb, currentColor 20%, transparent);
+ border-radius: 8px;
+ padding: .5rem .9rem;
+ text-decoration: none;
+}
+
+#mokoThemeFab.debug-outline {
+ outline: 2px dashed var(--pink, #ff8fc0);
+ outline-offset: 2px;
+}
+
+/* ================================================================
+ ACCESSIBILITY TOOLBAR
+ ================================================================ */
+
+/* Color inversion */
+html.a11y-inverted {
+ filter: invert(1) hue-rotate(180deg);
+}
+
+html.a11y-inverted img,
+html.a11y-inverted video,
+html.a11y-inverted picture,
+html.a11y-inverted svg,
+html.a11y-inverted [style*="background-image"],
+html.a11y-inverted .brand-logo img {
+ filter: invert(1) hue-rotate(180deg);
+}
+
+/* High contrast */
+html.a11y-high-contrast {
+ filter: contrast(1.4);
+}
+
+html.a11y-high-contrast img,
+html.a11y-high-contrast video,
+html.a11y-high-contrast picture {
+ filter: contrast(0.714);
+}
+
+/* Highlight links */
+html.a11y-highlight-links a {
+ outline: 2px solid currentColor !important;
+ outline-offset: 2px !important;
+ text-decoration: underline !important;
+}
+
+/* Readable font — system sans-serif stack for maximum clarity */
+html.a11y-readable-font,
+html.a11y-readable-font * {
+ font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important;
+ letter-spacing: 0.02em !important;
+ word-spacing: 0.05em !important;
+}
+
+/* Pause animations */
+html.a11y-pause-animations *,
+html.a11y-pause-animations *::before,
+html.a11y-pause-animations *::after {
+ animation-duration: 0s !important;
+ animation-delay: 0s !important;
+ transition-duration: 0s !important;
+ transition-delay: 0s !important;
+ scroll-behavior: auto !important;
+}
+
+/* Toolbar container */
+#mokoA11yToolbar {
+ position: fixed;
+ z-index: 1201;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+ gap: .25rem;
+ font-family: inherit;
+ bottom: 1rem;
+ right: 2.5rem;
+}
+
+/* When theme FAB is present, a11y toggle is inline — hide standalone toolbar positioning */
+body[data-theme-fab-enabled="1"] #mokoA11yToolbar {
+ position: static;
+}
+
+/* Toggle button */
+.a11y-toggle {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 42px;
+ height: 42px;
+ border-radius: 50%;
+ border: 2px solid var(--link-color, #3565e5);
+ background: var(--bs-body-bg, #fff);
+ color: var(--link-color, #3565e5);
+ font-size: 1.25rem;
+ cursor: pointer;
+ transition: background .2s, color .2s, box-shadow .2s;
+ box-shadow: var(--box-shadow, 0 .25rem .5rem rgba(0,0,0,.15));
+}
+
+.a11y-toggle:hover,
+.a11y-toggle:focus-visible {
+ background: var(--link-color, #3565e5);
+ color: #fff;
+}
+
+.a11y-toggle.active {
+ background: var(--link-color, #3565e5);
+ color: #fff;
+}
+
+/* Panel */
+.a11y-panel {
+ background: var(--body-bg, var(--bs-body-bg, #fff));
+ border: 1px solid var(--border-color, #dee2e6);
+ border-radius: var(--border-radius, .375rem);
+ padding: .75rem;
+ min-width: 200px;
+ box-shadow: var(--box-shadow-lg, 0 1rem 3rem rgba(0,0,0,.175));
+ color: var(--body-font-color, var(--body-color, #e6ebf1));
+}
+
+.a11y-group {
+ margin-bottom: .5rem;
+}
+
+.a11y-group:last-child {
+ margin-bottom: 0;
+}
+
+.a11y-group-label {
+ display: block;
+ font-size: .75rem;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: .05em;
+ margin-bottom: .35rem;
+ color: var(--body-font-color, #444);
+ opacity: .7;
+}
+
+.a11y-btn-row {
+ display: flex;
+ align-items: center;
+ gap: .35rem;
+}
+
+.a11y-btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 34px;
+ height: 34px;
+ border: 1px solid var(--border-color, #dee2e6);
+ border-radius: var(--border-radius, .375rem);
+ background: var(--secondary-bg, var(--bs-body-bg, #fff));
+ color: var(--body-font-color, var(--body-color, #e6ebf1));
+ font-size: .875rem;
+ cursor: pointer;
+ transition: background .15s, border-color .15s;
+}
+
+.a11y-btn:hover,
+.a11y-btn:focus-visible {
+ border-color: var(--link-color, #3565e5);
+ background: var(--link-color, #3565e5);
+ color: #fff;
+}
+
+.a11y-size-display {
+ font-size: .8rem;
+ font-weight: 600;
+ min-width: 3ch;
+ text-align: center;
+ color: var(--body-font-color, var(--body-color, #e6ebf1));
+}
+
+.a11y-btn-wide {
+ width: 100%;
+ gap: .5rem;
+ padding: .35rem .75rem;
+ justify-content: flex-start;
+}
+
+.a11y-btn-wide.active {
+ background: var(--link-color, #3565e5);
+ border-color: var(--link-color, #3565e5);
+ color: #fff;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .a11y-toggle,
+ .a11y-btn {
+ transition: none;
+ }
+}
+
+html.component body{
+ padding-top: 3.125rem;
+}
+
+#view_gabble {
+ background-color: var(--gab-blue, #4d9fff);
+ padding: 0.375rem;
+ border-radius: 6px;
+}
+
+#mod_gabble {
+ background-color: var(--gab-blue, #4d9fff);
+ padding: 0.1875rem;
+ border-radius: 6px;
+}
+
+#lists_gabble {
+ position: relative;
+ height: 100%;
+ border: 4px solid var(--gab-red, #ff6b6b);
+ background-color: var(--gab-green, #5cb85c);
+ padding: 0.25rem;
+ border-radius: 6px;
+}
+
+#select_list {
+ margin-left: 0;
+ width: 100%;
+ padding: 0.25rem;
+ border-radius: 6px 6px 0px 0px;
+}
+
+#options_list {
+ width: 100%;
+ padding: 0.25rem;
+}
+
+#frame_list {
+ width: 100%;
+ height: 484px;
+ padding: 0.25rem;
+ border-radius: 0px 0px 6px 6px;
+}
+
+#windows_list {
+ margin-left: 0;
+ width: 100%;
+ border: 4px solid var(--gab-red, #ff6b6b);
+ background-color: var(--gab-green, #5cb85c);
+ padding: 0.25rem;
+ border-radius: 6px;
+}
+
+#frame_window {
+ width: 100%;
+}
+
+#openai_btn {
+ position: absolute;
+ right: 10px;
+ bottom: 10px;
+ visibility: hidden;
+ width: 34px;
+ height: 34px;
+ cursor: pointer;
+ border: 3px solid var(--gab-gray3, #ced4da);
+ background-color: var(--white, #fff);
+ border-radius: 17px;
+}
+
+#openai_btn:hover {
+ width: 36px;
+ height: 36px;
+ border: 3px solid var(--gab-gray3, #ced4da);
+ border-radius: 18px;
+}
+
+#openai_logo_anim {
+ position: absolute;
+ top: 15px;
+ right: 15px;
+ width: 35px;
+ height: 35px;
+ padding: 0.125rem;
+ z-index: 1;
+ border-radius: 10px;
+}
+
+.openai_logo_sm {
+ width: 22px;
+ height: 22px;
+ background-color: var(--white, #fff);
+ border: 3px solid var(--white, #fff);
+ border-radius: 11px;
+}
+
+.openai_logo_md {
+ width: 34px;
+ height: 34px;
+ background-color: var(--white, #fff);
+ border: 4px solid var(--white, #fff);
+ border-radius: 17px;
+}
+
+.btn_on_com {
+ position: absolute;
+ bottom: -2px;
+ left: -2px;
+ width: 12px;
+ height: 12px;
+ background-color: var(--indicator-success-bg);
+ border-radius: 6px;
+}
+
+.btn_on_mod {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 12px;
+ height: 12px;
+ background-color: var(--indicator-success-bg);
+ border-radius: 6px;
+}
+
+.button_list {
+ border: none;
+ width:100%;
+ outline: none;
+ background-color: var(--gab-gray1, #868e96);
+ padding: 0.375rem;
+ border-radius: 6px;
+}
+
+.button_list:hover {
+ background-color: var(--gab-gray2, #adb5bd);
+}
+
+.button_list_s {
+ border: none;
+ width: 100%;
+ outline: none;
+ cursor: pointer;
+ color: var(--white, #fff);
+ background-color: var(--gab-red, #ff6b6b);
+ padding: 0.375rem;
+ border-radius: 6px;
+}
+
+.window_list {
+ position: relative;
+ margin: 0.25rem;
+ width: 100%;
+ border: none;
+ outline: none;
+ cursor: pointer;
+ text-align: left;
+ background-color: var(--gab-gray1, #868e96);
+ padding: 0.375rem;
+ border-radius: 6px;
+}
+
+.window_list:hover {
+ background-color: var(--gab-gray2, #adb5bd);
+}
+
+.window_list_s {
+ position: relative;
+ margin: 0.25rem;
+ width: 100%;
+ border: none;
+ outline: none;
+ cursor: pointer;
+ text-align: left;
+ color: var(--white, #fff);
+ background-color: var(--gab-red, #ff6b6b);
+ padding: 0.375rem;
+ border-radius: 6px;
+}
+
+.btn_close {
+ position: absolute;
+ right: 4px;
+ top: 10px;
+ padding-left: 0.0625rem;
+ width: 16px;
+ height: 16px;
+ color: var(--black, #000);
+ font-size: 10px;
+ text-align: center;
+ background-color: var(--gab-gray2, #adb5bd);
+ border-radius: 8px;
+}
+
+.btn_close:hover {
+ background-color: var(--gab-gray3, #ced4da);
+}
+
+.iframe_list {
+ width: 100%;
+ height: 100%;
+ background-color: var(--white, #fff);
+ border: 4px solid var(--gab-red, #ff6b6b);
+ border-radius: 6px;
+}
+
+.iframe_messages {
+ width: 100%;
+ height: 100%;
+ background-color: var(--white, #fff);
+ border: 4px solid var(--gab-red, #ff6b6b);
+ border-radius: 6px;
+}
+
+.input_box {
+ position: relative;
+}
+
+.input_emoji {
+ position: absolute;
+ right: 48px;
+ top: 11px;
+ cursor: pointer;
+ color: var(--gab-gray2, #adb5bd);
+}
+
+.input_emoji:hover {
+ color: var(--gab-gray3, #ced4da);
+}
+
+.emoji {
+ display: inline-block;
+ float: left;
+ cursor: pointer;
+ padding: 0.125rem;
+ background-color: var(--white, #fff);
+}
+
+.emoji:hover {
+ background-color: var(--gab-orange, #ff9f5a);
+}
+
+.emojis_div {
+ position: absolute;
+ top: -92px;
+ right: 0px;
+ width: 200px;
+ height: 92px;
+ border: 4px solid var(--gab-red, #ff6b6b);
+ background-color: var(--gab-gray1, #868e96);
+ border-radius: 6px;
+}
+
+.msg-button-on {
+ margin-left: 0.3125rem;
+ width: 30px;
+ height: 30px;
+ font-size: 20px;
+ text-align: center;
+ color: var(--white, #fff);
+ background-color: var(--gab-orange, #ff9f5a);
+ border-radius: 15px;
+}
+
+.msg-button-off {
+ margin-left: 0.3125rem;
+ width: 30px;
+ height: 30px;
+ font-size: 20px;
+ text-align: center;
+ color: var(--white, #fff);
+ background-color: var(--gab-gray2, #adb5bd);
+ border-radius: 15px;
+}
+
+.taba-content {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+
+.msg-input {
+ padding-left: 0.625rem;
+ padding-right: 1.625rem;
+ width: calc(100% - 35px);
+ height: 30px;
+ border-radius: 15px;
+}
+
+.main-windows {
+ position: fixed;
+ margin-bottom: 0.625rem;
+ bottom: 0px;
+ right: 90px;
+ z-index: 901;
+}
+
+.list-windows {
+ position: fixed;
+ bottom: 0px;
+ right: 0px;
+ width: 50px;
+ margin-bottom: 1.25rem;
+ margin-right: 1.25rem;
+ z-index: 901;
+}
+
+.item-list {
+ display: inline-block;
+ color: var(--item-list-color, #2a2f34);
+ margin-top: 0.3125rem;
+ width: 50px;
+ height: 50px;
+ font-size: 30px;
+ text-align: center;
+ border: 3px solid var(--gab-red, #ff6b6b);
+ background-color: var(--gab-blue, #4d9fff);
+ border-radius: 25px;
+}
+
+.button {
+ opacity: 1;
+}
+
+.button:hover {
+ cursor: pointer;
+ opacity: .6;
+}
+
+.notifications {
+ position: relative;
+}
+
+.n-notifications {
+ position: absolute;
+ bottom: -6px;
+ right: -2px;
+ width: 18px;
+ height: 18px;
+ color: var(--white, #fff);
+ font-size: 11px;
+ font-weight: bold;
+ text-align: center;
+ background-color: var(--notification-badge-bg);
+ border-radius: 9px;
+}
+
+.m-notifications {
+ position: absolute;
+ top: -6px;
+ right: -2px;
+ width: 18px;
+ height: 18px;
+ color: var(--white, #fff);
+ font-size: 11px;
+ font-weight: bold;
+ text-align: center;
+ background-color: var(--notification-badge-bg);
+ border-radius: 9px;
+}
+
+.window {
+ display: inline-block;
+ margin-left: 0.5rem;
+ width: 280px;
+ height: 420px;
+}
+
+.window-com {
+ margin-top: 0.375rem;
+ width: 100%;
+ height: 480px;
+}
+
+.window-title {
+ margin-left: 0.3125rem;
+ display: inline-block;
+ color: var(--white, #fff);
+}
+
+.window-title-com {
+ margin-left: 0.3125rem;
+ display: inline-block;
+ color: var(--black, #000);
+}
+
+.window-icon {
+ display: inline-block;
+ color: var(--white, #fff);
+}
+
+.window-header {
+ padding: 0.375rem;
+ width: 100%;
+ height: 40px;
+ background-color: var(--gab-blue, #4d9fff);
+ border-radius: 8px 8px 0px 0px;
+}
+
+.window-header-com {
+ padding: 0.25rem;
+ width: 100%;
+ height: 35px;
+ background-color: var(--gab-red, #ff6b6b);
+ border-radius: 8px 8px 0px 0px;
+}
+
+.window-content {
+ position: relative;
+ display: block;
+ width: 100%;
+ height: calc(100% - 80px);
+ background-color: var(--content-bg-gray, #2b323b);
+}
+
+.content-footer {
+ position: relative;
+ padding: 0.3125rem;
+ width: 100%;
+ height: 40px;
+ background-color: var(--content-bg-gray, #2b323b);
+ border-radius: 0px 0px 8px 8px;
+}
+
+.taba-btn {
+ text-align: center;
+ display: inline-block;
+ margin-left: 0.3125rem;
+ float: right;
+ width: 24px;
+ height: 24px;
+ background-color: var(--content-bg-gray, #2b323b);
+ border-radius: 12px;
+}
+
+.taba-hover {
+ cursor: pointer;
+ opacity: 1;
+}
+
+.taba-hover:hover {
+ opacity: 0.6;
+}
+
+.taba-self {
+ border: 1px solid var(--white, #fff);
+ background-color: var(--taba-btn-green, #5a9c2f);
+ padding: 0.375rem;
+ padding-top: 0.5625rem;
+ border-radius: 10px;
+}
+
+.taba-others {
+ border: 1px solid var(--white, #fff);
+ background-color: var(--taba-btn-blue, #3d75a8);
+ padding: 0.375rem;
+ padding-top: 0.5625rem;
+ border-radius: 10px;
+}
+
+
+
+.taba-bot {
+ border: 1px solid var(--white, #fff);
+ background-color: var(--gab-gray3, #ced4da);
+ padding: 0.375rem;
+ padding-top: 0.5625rem;
+ border-radius: 10px;
+}
+
+.taba-dice {
+ border: 1px solid var(--white, #fff);
+ background-color: var(--taba-btn-red, #c43620);
+ padding: 0.375rem;
+ border-radius: 10px;
+}
+
+.taba-emoji {
+ border: 1px solid var(--white, #fff);
+ background-color: var(--taba-btn-blue, #3d75a8);
+ padding: 0.375rem;
+ border-radius: 10px;
+}
+
+.taba-user {
+ border: 1px solid var(--white, #fff);
+ background-color: var(--white, #fff);
+ padding: 0.375rem;
+ border-radius: 6px;
+ word-wrap: break-word;
+}
+
+.taba-user-on {
+ border: 1px solid #FFF;
+ background-color: var(--gab-green, #5cb85c);
+ padding: 0.375rem;
+ border-radius: 8px;
+}
+
+.taba-feed {
+ border: 1px solid #FFF;
+ background-color: var(--gab-blue, #4d9fff);
+ padding: 0.375rem;
+ border-radius: 8px;
+}
+
+.openai_error {
+ border: 1px solid #FFF;
+ background-color: var(--gab-red, #ff6b6b);
+ padding: 0.375rem;
+ border-radius: 8px;
+}
+
+.taba-msgsystem {
+ border: 1px solid var(--white, #fff);
+ background-color: var(--taba-btn-gray, #6a7080);
+ padding: 0.375rem;
+ border-radius: 10px;
+}
+
+.taba-msghead {
+ background-color: var(--taba-msg-bg, #1e2430);
+ padding: 0.25rem;
+ padding-left: 0.625rem;
+ padding-right: 0.375rem;
+ border-radius: 6px 6px 0px 0px;
+}
+
+.taba-msg {
+ background-color: var(--taba-msg-bg, #1e2430);
+ padding: 0.5rem;
+ border-radius: 0px 8px 8px 8px;
+ word-wrap: break-word;
+}
+
+nav[data-toggle=toc] .nav>li>a{
+ display:block;
+ padding:0.25rem 1.25rem;
+ font-size:13px;
+ font-weight:500;
+ color: var(--toc-link-color, #9fa6ad);
+}
+nav[data-toggle=toc] .nav>li>a:focus,nav[data-toggle=toc] .nav>li>a:hover{
+ padding-left:1.1875rem;
+ color: var(--toc-link-active-color, #91a4ff);
+ text-decoration:none;
+ background-color:transparent;
+ border-left:1px solid var(--toc-link-active-color, #91a4ff);
+}
+nav[data-toggle=toc] .nav-link.active,nav[data-toggle=toc] .nav-link.active:focus,nav[data-toggle=toc] .nav-link.active:hover{
+ padding-left:1.125rem;
+ font-weight:700;
+ color: var(--toc-link-active-color, #91a4ff);
+ background-color:transparent;
+ border-left:2px solid var(--toc-link-active-color, #91a4ff);
+}
+nav[data-toggle=toc] .nav-link+ul{
+ display:none;
+ padding-bottom:0.625rem;
+}
+nav[data-toggle=toc] .nav .nav>li>a{
+ padding-top:0.0625rem;
+ padding-bottom:0.0625rem;
+ padding-left:1.875rem;
+ font-size:12px;
+ font-weight:400;
+}
+nav[data-toggle=toc] .nav .nav>li>a:focus,nav[data-toggle=toc] .nav .nav>li>a:hover{
+ padding-left:1.8125rem;
+}
+nav[data-toggle=toc] .nav .nav>li>.active,nav[data-toggle=toc] .nav .nav>li>.active:focus,nav[data-toggle=toc] .nav .nav>li>.active:hover{
+ padding-left:1.75rem;
+ font-weight:500;
+}
+nav[data-toggle=toc] .nav-link.active+ul{
+ display:block;
+}
+
+
+/* ===============================
+= Choices =
+=============================== */
+.choices {
+ position: relative;
+ overflow: hidden;
+ margin-bottom: 1.5rem;
+ font-size: 16px;
+}
+.choices:focus {
+ outline: none;
+}
+.choices:last-child {
+ margin-bottom: 0;
+}
+.choices.is-open {
+ overflow: initial;
+}
+.choices.is-disabled .choices__inner,
+.choices.is-disabled .choices__input {
+ background-color: var(--choices-disabled-bg, #2b323b);
+ cursor: not-allowed;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.choices.is-disabled .choices__item {
+ cursor: not-allowed;
+}
+.choices [hidden] {
+ display: none !important;
+}
+
+.choices[data-type*=select-one] {
+ cursor: pointer;
+}
+.choices[data-type*=select-one] .choices__inner {
+ padding-bottom: 0.46875rem;
+}
+.choices[data-type*=select-one] .choices__input {
+ display: block;
+ width: 100%;
+ padding: 0.625rem;
+ border-bottom: 1px solid var(--choices-border-light, #48525d);
+ background-color: var(--choices-input-bg);
+ margin: 0;
+}
+.choices[data-type*=select-one] .choices__button {
+ background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==");
+ padding: 0;
+ background-size: 8px;
+ position: absolute;
+ top: 50%;
+ right: 0;
+ margin-top: -0.625rem;
+ margin-right: 1.5625rem;
+ height: 20px;
+ width: 20px;
+ border-radius: 10em;
+ opacity: 0.25;
+}
+.choices[data-type*=select-one] .choices__button:hover, .choices[data-type*=select-one] .choices__button:focus {
+ opacity: 1;
+}
+.choices[data-type*=select-one] .choices__button:focus {
+ -webkit-box-shadow: 0 0 0 2px #00bcd4;
+ box-shadow: 0 0 0 2px #00bcd4;
+}
+.choices[data-type*=select-one] .choices__item[data-value=""] .choices__button {
+ display: none;
+}
+.choices[data-type*=select-one]::after {
+ content: "";
+ height: 0;
+ width: 0;
+ border-style: solid;
+ border-color: var(--choices-arrow-color, #9fa6ad) transparent transparent transparent;
+ border-width: 5px;
+ position: absolute;
+ right: 11.5px;
+ top: 50%;
+ margin-top: -0.15625rem;
+ pointer-events: none;
+}
+.choices[data-type*=select-one].is-open::after {
+ border-color: transparent transparent var(--choices-arrow-color, #9fa6ad) transparent;
+ margin-top: -0.46875rem;
+}
+.choices[data-type*=select-one][dir=rtl]::after {
+ left: 11.5px;
+ right: auto;
+}
+.choices[data-type*=select-one][dir=rtl] .choices__button {
+ right: auto;
+ left: 0;
+ margin-left: 1.5625rem;
+ margin-right: 0;
+}
+
+.choices[data-type*=select-multiple] .choices__inner,
+.choices[data-type*=text] .choices__inner {
+ cursor: text;
+}
+.choices[data-type*=select-multiple] .choices__button,
+.choices[data-type*=text] .choices__button {
+ position: relative;
+ display: inline-block;
+ margin-top: 0;
+ margin-right: -0.25rem;
+ margin-bottom: 0;
+ margin-left: 0.5rem;
+ padding-left: 1rem;
+ border-left: 1px solid #008fa1;
+ background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjRkZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==");
+ background-size: 8px;
+ width: 8px;
+ line-height: 1;
+ opacity: 0.75;
+ border-radius: 0;
+}
+.choices[data-type*=select-multiple] .choices__button:hover, .choices[data-type*=select-multiple] .choices__button:focus,
+.choices[data-type*=text] .choices__button:hover,
+.choices[data-type*=text] .choices__button:focus {
+ opacity: 1;
+}
+
+.choices__inner {
+ display: inline-block;
+ vertical-align: top;
+ width: 100%;
+ background-color: var(--choices-inner-bg, #1a2027);
+ padding: 0.46875rem 0.46875rem 0.234375rem;
+ border: 1px solid var(--choices-border-light, #48525d);
+ border-radius: 2.5px;
+ font-size: 14px;
+ min-height: 44px;
+ overflow: hidden;
+}
+.is-focused .choices__inner, .is-open .choices__inner {
+ border-color: var(--choices-focused-border, #5472ff);
+}
+.is-open .choices__inner {
+ border-radius: 2.5px 2.5px 0 0;
+}
+.is-flipped.is-open .choices__inner {
+ border-radius: 0 0 2.5px 2.5px;
+}
+
+.choices__list {
+ margin: 0;
+ padding-left: 0;
+ list-style: none;
+}
+
+.choices__list--single {
+ display: inline-block;
+ padding: 0.25rem 1rem 0.25rem 0.25rem;
+ width: 100%;
+}
+[dir=rtl] .choices__list--single {
+ padding-right: 0.25rem;
+ padding-left: 1rem;
+}
+.choices__list--single .choices__item {
+ width: 100%;
+}
+
+.choices__list--multiple {
+ display: inline;
+}
+.choices__list--multiple .choices__item {
+ display: inline-block;
+ vertical-align: middle;
+ border-radius: 20px;
+ padding: 0.25rem 0.625rem;
+ font-size: 12px;
+ font-weight: 500;
+ margin-right: 0.234375rem;
+ margin-bottom: 0.234375rem;
+ background-color: var(--choices-item-bg, #1a5f75);
+ border: 1px solid var(--choices-item-border, #1a748f);
+ color: var(--white, #fff);
+ word-break: break-all;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.choices__list--multiple .choices__item[data-deletable] {
+ padding-right: 0.3125rem;
+}
+[dir=rtl] .choices__list--multiple .choices__item {
+ margin-right: 0;
+ margin-left: 0.234375rem;
+}
+.choices__list--multiple .choices__item.is-highlighted {
+ background-color: var(--choices-item-hover-bg, #1a748f);
+ border: 1px solid var(--choices-item-hover-border, #1a8aa8);
+}
+.is-disabled .choices__list--multiple .choices__item {
+ background-color: var(--choices-item-disabled-bg, #48525d);
+ border: 1px solid var(--choices-item-disabled-border, #36404a);
+}
+
+.choices__list--dropdown {
+ visibility: hidden;
+ z-index: 1;
+ position: absolute;
+ width: 100%;
+ background-color: var(--choices-dropdown-bg);
+ border: 1px solid var(--choices-border-light, #48525d);
+ top: 100%;
+ margin-top: -0.0625rem;
+ border-bottom-left-radius: 2.5px;
+ border-bottom-right-radius: 2.5px;
+ overflow: hidden;
+ word-break: break-all;
+ will-change: visibility;
+}
+.choices__list--dropdown.is-active {
+ visibility: visible;
+}
+.is-open .choices__list--dropdown {
+ border-color: var(--choices-focused-border, #5472ff);
+}
+.is-flipped .choices__list--dropdown {
+ top: auto;
+ bottom: 100%;
+ margin-top: 0;
+ margin-bottom: -0.0625rem;
+ border-radius: 0.25rem 0.25rem 0 0;
+}
+.choices__list--dropdown .choices__list {
+ position: relative;
+ max-height: 300px;
+ overflow: auto;
+ -webkit-overflow-scrolling: touch;
+ will-change: scroll-position;
+}
+.choices__list--dropdown .choices__item {
+ position: relative;
+ padding: 0.625rem;
+ font-size: 14px;
+}
+[dir=rtl] .choices__list--dropdown .choices__item {
+ text-align: right;
+}
+@media (min-width: 640px) {
+ .choices__list--dropdown .choices__item--selectable {
+ padding-right: 6.25rem;
+ }
+ .choices__list--dropdown .choices__item--selectable::after {
+ content: attr(data-select-text);
+ font-size: 12px;
+ opacity: 0;
+ position: absolute;
+ right: 10px;
+ top: 50%;
+ -webkit-transform: translateY(-50%);
+ transform: translateY(-50%);
+ }
+ [dir=rtl] .choices__list--dropdown .choices__item--selectable {
+ text-align: right;
+ padding-left: 6.25rem;
+ padding-right: 0.625rem;
+ }
+ [dir=rtl] .choices__list--dropdown .choices__item--selectable::after {
+ right: auto;
+ left: 10px;
+ }
+}
+.choices__list--dropdown .choices__item--selectable.is-highlighted {
+ background-color: var(--choices-item-highlighted, #2b323b);
+}
+.choices__list--dropdown .choices__item--selectable.is-highlighted::after {
+ opacity: 0.5;
+}
+
+.choices__item {
+ cursor: default;
+}
+
+.choices__item--selectable {
+ cursor: pointer;
+}
+
+.choices__item--disabled {
+ cursor: not-allowed;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ opacity: 0.5;
+}
+
+.choices__heading {
+ font-weight: 600;
+ font-size: 12px;
+ padding: 0.625rem;
+ border-bottom: 1px solid #f7f7f7;
+ color: gray;
+}
+
+.choices__button {
+ text-indent: -9999px;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ border: 0;
+ background-color: transparent;
+ background-repeat: no-repeat;
+ background-position: center;
+ cursor: pointer;
+}
+.choices__button:focus {
+ outline: none;
+}
+
+.choices__input {
+ display: inline-block;
+ vertical-align: baseline;
+ background-color: var(--choices-input-inner-bg, #1a2027);
+ font-size: 14px;
+ margin-bottom: 0.3125rem;
+ border: 0;
+ border-radius: 0;
+ max-width: 100%;
+ padding: 0.25rem 0 0.25rem 0.125rem;
+}
+.choices__input:focus {
+ outline: 0;
+}
+[dir=rtl] .choices__input {
+ padding-right: 0.125rem;
+ padding-left: 0;
+}
+
+.choices__placeholder {
+ opacity: 0.5;
+}
+
+/* ===== End of Choices ====== */
+.choices {
+ border: 1px solid hsl(210, 14%, 83%);
+ border-radius: 0.25rem;
+}
+.choices.is-focused {
+ border-color: var(--input-focus-border-color, #5472ff);
+ -webkit-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+ box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+}
+
+.choices__inner {
+ padding: 0.4rem 1rem;
+ margin-bottom: 0;
+ font-size: 1rem;
+ border: none;
+ border-radius: 0;
+}
+
+.choices__input {
+ padding: 0;
+ margin-bottom: 0;
+ font-size: 1rem;
+ background-color: transparent;
+}
+.choices__input::-webkit-input-placeholder {
+ color: hsl(210, 9%, 31%);
+ opacity: 1;
+}
+.choices__input::-moz-placeholder {
+ color: hsl(210, 9%, 31%);
+ opacity: 1;
+}
+.choices__input:-ms-input-placeholder {
+ color: hsl(210, 9%, 31%);
+ opacity: 1;
+}
+.choices__input::-ms-input-placeholder {
+ color: hsl(210, 9%, 31%);
+ opacity: 1;
+}
+.choices__input::placeholder {
+ color: hsl(210, 9%, 31%);
+ opacity: 1;
+}
+
+.choices__list--dropdown {
+ z-index: 1060;
+}
+
+.choices__list--multiple .choices__item {
+ position: relative;
+ margin: 0.125rem;
+ background-color: var(--color-primary, #112855);
+ -webkit-margin-end: 0.125rem;
+ margin-inline-end: 0.125rem;
+ border: 0;
+ border-radius: 0.25rem;
+}
+.choices__list--multiple .choices__item.is-highlighted {
+ background-color: var(--color-primary, #112855);
+ opacity: 0.9;
+}
+
+.choices .choices__list--dropdown .choices__item {
+ -webkit-padding-end: 0.625rem;
+ padding-inline-end: 0.625rem;
+}
+.choices .choices__list--dropdown .choices__item--selectable::after {
+ display: none;
+}
+
+.choices__button_joomla {
+ position: relative;
+ padding: 0 0.625rem;
+ color: inherit;
+ text-indent: -9999px;
+ cursor: pointer;
+ background: none;
+ border: 0;
+ opacity: 0.5;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+}
+.choices__button_joomla::before {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ display: block;
+ text-align: center;
+ text-indent: 0;
+ content: "×";
+}
+.choices__button_joomla:hover, .choices__button_joomla:focus {
+ opacity: 1;
+}
+.choices__button_joomla:focus {
+ outline: none;
+}
+
+.choices[data-type*=select-one] .choices__inner,
+.choices[data-type*=select-multiple] .choices__inner {
+ -webkit-padding-end: 3rem;
+ padding-inline-end: 3rem;
+ cursor: pointer;
+ background: url("../../../images/select-bg.svg") no-repeat 100%/116rem;
+ background-color: hsl(210, 16%, 93%);
+}
+[dir=rtl] .choices[data-type*=select-one] .choices__inner,
+[dir=rtl] .choices[data-type*=select-multiple] .choices__inner {
+ background: url("../../../images/select-bg-rtl.svg") no-repeat 0/116rem;
+ background-color: hsl(210, 16%, 93%);
+}
+
+.choices[data-type*=select-one] .choices__item {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+}
+.choices[data-type*=select-one] .choices__button_joomla {
+ position: absolute;
+ top: 50%;
+ inset-inline-end: 0;
+ width: 20px;
+ height: 20px;
+ padding: 0;
+ -webkit-margin-before: -0.625rem;
+ margin-block-start: -0.625rem;
+ -webkit-margin-end: 3.125rem;
+ margin-inline-end: 3.125rem;
+ border-radius: 10em;
+ opacity: 0.5;
+}
+.choices[data-type*=select-one] .choices__button_joomla:hover, .choices[data-type*=select-one] .choices__button_joomla:focus {
+ opacity: 1;
+}
+.choices[data-type*=select-one] .choices__button_joomla:focus {
+ -webkit-box-shadow: 0 0 0 2px #00bcd4;
+ box-shadow: 0 0 0 2px #00bcd4;
+}
+.choices[data-type*=select-one]::after {
+ display: none;
+}
+
+.choices[data-type*=select-multiple] .choices__input,
+.choices[data-type*=text] .choices__input {
+ padding: 0.2rem 0;
+}
+
+.choices__heading {
+ font-size: 1.2rem;
+}
+
+
+.site-title {
+ color: var(--nav-bg-color);
+ font-family: 'Osaka', sans-serif;
+ font-weight: 600;
+ font-size: 1.5rem;
+ text-decoration: none;
+ margin-left: var(--padding-x, 0.15rem);
+}
+
+.container-header .navbar-brand .site-title {
+ color: var(--nav-bg-color);
+ text-decoration: none;
+}
+
+.container-header .navbar-brand a {
+ text-decoration: none;
+}
+
+.brand-logo {
+ text-decoration: none;
+}
+
+/* Enhanced search button styling */
+.mod-finder__search.input-group button,
+.container-search button[type="submit"] {
+ flex: 0 0 auto;
+ background-color: var(--color-primary, #112855);
+ color: var(--mainmenu-nav-link-color, #fff);
+ border: 1px solid var(--input-border-color, #3a4250);
+ padding: 0.6rem 1rem;
+ border-radius: 0 0.25rem 0.25rem 0;
+ transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
+}
+
+.mod-finder__search.input-group button:hover,
+.container-search button[type="submit"]:hover {
+ background-color: var(--color-hover, gray);
+ border-color: var(--input-border-color, #3a4250);
+}
+
+.mod-finder__search.input-group button:focus,
+.container-search button[type="submit"]:focus {
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb, 84, 114, 255), .5);
+}
+
+/* Enhanced container-search styling */
+.container-header .container-search {
+ position: relative;
+}
+
+.container-search .mod-finder__search.input-group {
+ display: flex;
+ align-items: stretch;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ border-radius: 0.25rem;
+ overflow: hidden;
+ transition: box-shadow 0.2s ease-in-out;
+}
+
+.container-search .mod-finder__search.input-group:focus-within {
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+}
+
+.container-search .form-control,
+.container-search .awesomplete,
+.container-search .awesomplete input {
+ flex: 1 1 0%;
+ min-width: 0;
+}
+
+.container-search .form-control,
+.container-search .awesomplete input {
+ border-right: none;
+ padding: 0.6rem 1rem;
+ font-size: 0.95rem;
+ border-radius: 0.25rem 0 0 0.25rem;
+}
+
+.container-search .form-control:focus,
+.container-search .awesomplete input:focus {
+ border-color: var(--input-focus-border-color, #5472ff);
+ box-shadow: none;
+}
+
+.container-search button[type="submit"],
+.container-search .input-group button {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 3rem;
+ font-weight: 500;
+}
+
+.container-search .icon-search {
+ font-size: 1rem;
+ color: var(--nav-text-color, gray);
+}
+
+/* Responsive header menu and search layout improvements */
+@media (max-width: 991.98px) {
+ .container-header .container-nav {
+ flex-direction: column;
+ }
+
+ .container-header .container-nav nav {
+ width: 100%;
+ }
+
+ .container-header .container-search {
+ width: 100%;
+ margin-top: 0.5rem;
+ }
+
+ .container-header .container-search {
+ display: none;
+ }
+
+ .container-header .container-search.show {
+ display: block;
+ }
+
+ .mod-finder__search.input-group {
+ max-width: 100%;
+ }
+}
+
+@media (min-width: 992px) {
+ .container-header .container-nav {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 2rem;
+ }
+
+ .container-header .container-nav nav {
+ flex: 1 1 0%;
+ }
+
+ .container-header .container-search {
+ flex: 0 0 15%;
+ max-width: 15%;
+ margin-top: 0;
+ }
+}
+
+
+/* Base renderer for Joomla icon-* using Font Awesome Free */
+[class^="icon-"]::before,
+[class*=" icon-"]::before {
+ --_fa-family: var(--fa-family, var(--fa-style-family, "Font Awesome 7 Free"));
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ display: var(--fa-display, inline-block);
+ font-family: var(--_fa-family);
+ font-feature-settings: normal;
+ font-style: normal;
+ font-synthesis: none;
+ font-variant: normal;
+ font-weight: var(--fa-style, 900);
+ line-height: 1;
+ text-align: center;
+ text-rendering: auto;
+ width: var(--fa-width, 1.25em);
+}
+
+/* Ensure the icon container can render */
+[class^="icon-"],
+[class*=" icon-"] {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+}
+
+/* IcoMoon → Font Awesome 7 compatibility layer.
+ Joomla core renders icon-* classes via IcoMoon; this maps them to
+ FA7 Free glyphs so icons render without loading a second icon font. */
+[class^="icon-"]::before,
+[class*=" icon-"]::before {
+ font-family: "Font Awesome 7 Free", "Font Awesome 6 Free", sans-serif;
+ font-weight: 900;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ display: inline-block;
+}
+
+.icon-fw { width: 1.25em; text-align: center; }
+
+/* Navigation & UI */
+.icon-menu::before { content: "\f0c9"; } /* bars */
+.icon-search::before { content: "\f002"; }
+.icon-home::before { content: "\f015"; }
+.icon-arrow-up::before { content: "\f062"; }
+.icon-arrow-down::before { content: "\f063"; }
+.icon-arrow-left::before { content: "\f060"; }
+.icon-arrow-right::before { content: "\f061"; }
+.icon-chevron-up::before { content: "\f077"; }
+.icon-chevron-down::before { content: "\f078"; }
+.icon-chevron-left::before { content: "\f053"; }
+.icon-chevron-right::before { content: "\f054"; }
+.icon-caret-up::before { content: "\f0d8"; }
+.icon-caret-down::before { content: "\f0d7"; }
+
+/* Actions */
+.icon-edit::before { content: "\f044"; }
+.icon-save::before { content: "\f0c7"; }
+.icon-trash::before { content: "\f1f8"; }
+.icon-delete::before { content: "\f1f8"; }
+.icon-cancel::before { content: "\f00d"; }
+.icon-remove::before { content: "\f00d"; }
+.icon-check::before { content: "\f00c"; }
+.icon-plus::before { content: "\f067"; }
+.icon-minus::before { content: "\f068"; }
+.icon-copy::before { content: "\f0c5"; }
+.icon-refresh::before { content: "\f021"; }
+.icon-undo::before { content: "\f0e2"; }
+.icon-download::before { content: "\f019"; }
+.icon-upload::before { content: "\f093"; }
+.icon-print::before { content: "\f02f"; }
+
+/* Objects */
+.icon-user::before { content: "\f007"; }
+.icon-users::before { content: "\f0c0"; }
+.icon-lock::before { content: "\f023"; }
+.icon-unlock::before { content: "\f09c"; }
+.icon-key::before { content: "\f084"; }
+.icon-envelope::before { content: "\f0e0"; }
+.icon-mail::before { content: "\f0e0"; }
+.icon-calendar::before { content: "\f073"; }
+.icon-clock::before { content: "\f017"; }
+.icon-eye::before { content: "\f06e"; }
+.icon-eye-close::before { content: "\f070"; }
+.icon-star::before { content: "\f005"; }
+.icon-star-empty::before { content: "\f005"; font-weight: 400; }
+.icon-heart::before { content: "\f004"; }
+.icon-comment::before { content: "\f075"; }
+.icon-comments::before { content: "\f086"; }
+.icon-folder::before { content: "\f07b"; }
+.icon-folder-open::before { content: "\f07c"; }
+.icon-file::before { content: "\f15b"; }
+.icon-image::before { content: "\f03e"; }
+.icon-camera::before { content: "\f030"; }
+.icon-tag::before { content: "\f02b"; }
+.icon-tags::before { content: "\f02c"; }
+.icon-link::before { content: "\f0c1"; }
+.icon-globe::before { content: "\f0ac"; }
+.icon-flag::before { content: "\f024"; }
+
+/* Status & info */
+.icon-info::before { content: "\f129"; }
+.icon-info-circle::before { content: "\f05a"; }
+.icon-warning::before { content: "\f071"; }
+.icon-exclamation-triangle::before { content: "\f071"; }
+.icon-question::before { content: "\f128"; }
+.icon-question-circle::before { content: "\f059"; }
+.icon-ban-circle::before { content: "\f05e"; }
+
+/* Media & layout */
+.icon-cog::before { content: "\f013"; }
+.icon-cogs::before { content: "\f085"; }
+.icon-wrench::before { content: "\f0ad"; }
+.icon-list::before { content: "\f03a"; }
+.icon-th::before { content: "\f00a"; }
+.icon-th-large::before { content: "\f009"; }
+.icon-grid::before { content: "\f00a"; }
+.icon-grid-2::before { content: "\f009"; }
+.icon-bars::before { content: "\f0c9"; }
+.icon-share::before { content: "\f064"; }
+.icon-share-alt::before { content: "\f1e0"; }
+.icon-rss::before { content: "\f09e"; }
+.icon-feed::before { content: "\f09e"; }
+.icon-external-link::before { content: "\f35d"; }
+.icon-signup::before { content: "\f234"; }
+
+/* Publishing */
+.icon-publish::before { content: "\f00c"; }
+.icon-unpublish::before { content: "\f00d"; }
+.icon-featured::before { content: "\f005"; }
+.icon-unfeatured::before { content: "\f005"; font-weight: 400; }
+.icon-archive::before { content: "\f187"; }
+.icon-unarchive::before { content: "\f187"; }
+
+/* ===== BOOTSTRAP & JOOMLA BUTTONS ===== */
+.btn-primary {
+ --btn-color: white;
+ --btn-bg: var(--color-primary, #112855);
+ --btn-border-color: var(--color-primary, #112855);
+ --btn-hover-bg: color-mix(in srgb, var(--color-primary, #112855) 85%, black);
+ --btn-hover-border-color: color-mix(in srgb, var(--color-primary, #112855) 85%, black);
+}
+
+.btn-secondary {
+ --btn-color: var(--body-bg, #0e1318);
+ --btn-bg: var(--secondary, #48525d);
+ --btn-border-color: var(--secondary, #48525d);
+ --btn-hover-bg: color-mix(in srgb, var(--secondary, #48525d) 85%, black);
+ --btn-hover-border-color: color-mix(in srgb, var(--secondary, #48525d) 85%, black);
+}
+
+.btn-success {
+ --btn-color: white;
+ --btn-bg: var(--success, #4aa664);
+ --btn-border-color: var(--success, #4aa664);
+ --btn-hover-bg: color-mix(in srgb, var(--success, #4aa664) 85%, black);
+ --btn-hover-border-color: color-mix(in srgb, var(--success, #4aa664) 85%, black);
+}
+
+.btn-info {
+ --btn-color: white;
+ --btn-bg: var(--info, #4f7aa0);
+ --btn-border-color: var(--info, #4f7aa0);
+ --btn-hover-bg: color-mix(in srgb, var(--info, #4f7aa0) 85%, black);
+ --btn-hover-border-color: color-mix(in srgb, var(--info, #4f7aa0) 85%, black);
+}
+
+.btn-warning {
+ --btn-color: white;
+ --btn-bg: var(--warning, #c77a00);
+ --btn-border-color: var(--warning, #c77a00);
+ --btn-hover-bg: color-mix(in srgb, var(--warning, #c77a00) 85%, black);
+ --btn-hover-border-color: color-mix(in srgb, var(--warning, #c77a00) 85%, black);
+}
+
+.btn-danger {
+ --btn-color: white;
+ --btn-bg: var(--danger, #c23a31);
+ --btn-border-color: var(--danger, #c23a31);
+ --btn-hover-bg: color-mix(in srgb, var(--danger, #c23a31) 85%, black);
+ --btn-hover-border-color: color-mix(in srgb, var(--danger, #c23a31) 85%, black);
+}
+
+.btn-light {
+ --btn-color: var(--body-color, #e6ebf1);
+ --btn-bg: var(--light, #1b2027);
+ --btn-border-color: var(--light, #1b2027);
+ --btn-hover-bg: color-mix(in srgb, var(--light, #1b2027) 90%, black);
+ --btn-hover-border-color: color-mix(in srgb, var(--light, #1b2027) 90%, black);
+}
+
+.btn-dark {
+ --btn-color: white;
+ --btn-bg: var(--dark, #0f1318);
+ --btn-border-color: var(--dark, #0f1318);
+ --btn-hover-bg: color-mix(in srgb, var(--dark, #0f1318) 85%, black);
+ --btn-hover-border-color: color-mix(in srgb, var(--dark, #0f1318) 85%, black);
+}
+
+/* Outline button variants */
+.btn-outline-primary {
+ --btn-color: var(--color-primary, #112855);
+ --btn-border-color: var(--color-primary, #112855);
+ --btn-hover-color: white;
+ --btn-hover-bg: var(--color-primary, #112855);
+ --btn-hover-border-color: var(--color-primary, #112855);
+}
+
+.btn-outline-secondary {
+ --btn-color: var(--secondary, #48525d);
+ --btn-border-color: var(--secondary, #48525d);
+ --btn-hover-color: white;
+ --btn-hover-bg: var(--secondary, #48525d);
+ --btn-hover-border-color: var(--secondary, #48525d);
+}
+
+.btn-outline-success {
+ --btn-color: var(--success, #4aa664);
+ --btn-border-color: var(--success, #4aa664);
+ --btn-hover-color: white;
+ --btn-hover-bg: var(--success, #4aa664);
+ --btn-hover-border-color: var(--success, #4aa664);
+}
+
+.btn-outline-info {
+ --btn-color: var(--info, #4f7aa0);
+ --btn-border-color: var(--info, #4f7aa0);
+ --btn-hover-color: white;
+ --btn-hover-bg: var(--info, #4f7aa0);
+ --btn-hover-border-color: var(--info, #4f7aa0);
+}
+
+.btn-outline-warning {
+ --btn-color: var(--warning, #c77a00);
+ --btn-border-color: var(--warning, #c77a00);
+ --btn-hover-color: white;
+ --btn-hover-bg: var(--warning, #c77a00);
+ --btn-hover-border-color: var(--warning, #c77a00);
+}
+
+.btn-outline-danger {
+ --btn-color: var(--danger, #c23a31);
+ --btn-border-color: var(--danger, #c23a31);
+ --btn-hover-color: white;
+ --btn-hover-bg: var(--danger, #c23a31);
+ --btn-hover-border-color: var(--danger, #c23a31);
+}
+
+.btn-outline-light {
+ --btn-color: var(--light, #1b2027);
+ --btn-border-color: var(--light, #1b2027);
+ --btn-hover-color: var(--body-color, #e6ebf1);
+ --btn-hover-bg: var(--light, #1b2027);
+ --btn-hover-border-color: var(--light, #1b2027);
+}
+
+.btn-outline-dark {
+ --btn-color: var(--dark, #0f1318);
+ --btn-border-color: var(--dark, #0f1318);
+ --btn-hover-color: white;
+ --btn-hover-bg: var(--dark, #0f1318);
+ --btn-hover-border-color: var(--dark, #0f1318);
+}
+
+/* ===== BOOTSTRAP & JOOMLA ALERTS ===== */
+.alert-primary {
+ --alert-bg: color-mix(in srgb, var(--primary, #010156) 10%, var(--body-bg, #0e1318));
+ --alert-color: color-mix(in srgb, var(--primary, #010156) 90%, black);
+ --alert-border-color: color-mix(in srgb, var(--primary, #010156) 20%, var(--body-bg, #0e1318));
+}
+
+.alert-secondary {
+ --alert-bg: color-mix(in srgb, var(--secondary, #48525d) 10%, var(--body-bg, #0e1318));
+ --alert-color: color-mix(in srgb, var(--secondary, #48525d) 90%, black);
+ --alert-border-color: color-mix(in srgb, var(--secondary, #48525d) 20%, var(--body-bg, #0e1318));
+}
+
+.alert-success {
+ --alert-bg: color-mix(in srgb, var(--success, #4aa664) 10%, var(--body-bg, #0e1318));
+ --alert-color: color-mix(in srgb, var(--success, #4aa664) 90%, black);
+ --alert-border-color: color-mix(in srgb, var(--success, #4aa664) 20%, var(--body-bg, #0e1318));
+}
+
+.alert-info {
+ --alert-bg: color-mix(in srgb, var(--info, #4f7aa0) 10%, var(--body-bg, #0e1318));
+ --alert-color: color-mix(in srgb, var(--info, #4f7aa0) 90%, black);
+ --alert-border-color: color-mix(in srgb, var(--info, #4f7aa0) 20%, var(--body-bg, #0e1318));
+}
+
+.alert-warning {
+ --alert-bg: color-mix(in srgb, var(--warning, #c77a00) 10%, var(--body-bg, #0e1318));
+ --alert-color: color-mix(in srgb, var(--warning, #c77a00) 90%, black);
+ --alert-border-color: color-mix(in srgb, var(--warning, #c77a00) 20%, var(--body-bg, #0e1318));
+}
+
+.alert-danger {
+ --alert-bg: color-mix(in srgb, var(--danger, #c23a31) 10%, var(--body-bg, #0e1318));
+ --alert-color: color-mix(in srgb, var(--danger, #c23a31) 90%, black);
+ --alert-border-color: color-mix(in srgb, var(--danger, #c23a31) 20%, var(--body-bg, #0e1318));
+}
+
+.alert-light {
+ --alert-bg: var(--light, #1b2027);
+ --alert-color: var(--body-color, #e6ebf1);
+ --alert-border-color: color-mix(in srgb, var(--light, #1b2027) 85%, black);
+}
+
+.alert-dark {
+ --alert-bg: var(--dark, #0f1318);
+ --alert-color: white;
+ --alert-border-color: var(--dark, #0f1318);
+}
+
+/* Joomla-specific alert mappings */
+.alert-message {
+ --alert-bg: var(--alert-info, color-mix(in srgb, var(--info, #4f7aa0) 10%, var(--body-bg, #0e1318)));
+ --alert-color: color-mix(in srgb, var(--info, #4f7aa0) 90%, black);
+ --alert-border-color: color-mix(in srgb, var(--info, #4f7aa0) 20%, var(--body-bg, #0e1318));
+}
+
+.alert-error {
+ --alert-bg: var(--alert-danger, color-mix(in srgb, var(--danger, #c23a31) 10%, var(--body-bg, #0e1318)));
+ --alert-color: color-mix(in srgb, var(--danger, #c23a31) 90%, black);
+ --alert-border-color: color-mix(in srgb, var(--danger, #c23a31) 20%, var(--body-bg, #0e1318));
+}
+
+.alert-notice {
+ --alert-bg: var(--alert-warning, color-mix(in srgb, var(--warning, #c77a00) 10%, var(--body-bg, #0e1318)));
+ --alert-color: color-mix(in srgb, var(--warning, #c77a00) 90%, black);
+ --alert-border-color: color-mix(in srgb, var(--warning, #c77a00) 20%, var(--body-bg, #0e1318));
+}
+
+/* ===== MOD_SEARCH MOBILE RESPONSIVE STYLES ===== */
+.mod-search-responsive {
+ width: 100%;
+}
+
+.mod-search__form {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ width: 100%;
+}
+
+.mod-search__input-wrapper {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ width: 100%;
+}
+
+.mod-search__input-wrapper--inline {
+ flex-direction: row;
+ align-items: stretch;
+}
+
+.mod-search__input {
+ flex: 1;
+ min-width: 0;
+ padding: 0.5rem 0.75rem;
+ font-size: 1rem;
+ line-height: 1.5;
+ border: 1px solid var(--input-border-color, #dee2e6);
+ border-radius: 0.375rem;
+ background-color: var(--input-bg, #fff);
+ color: var(--input-color, #212529);
+ -webkit-appearance: none;
+ appearance: none;
+}
+
+.mod-search__input:focus {
+ border-color: var(--color-primary, #0d6efd);
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+
+.mod-search__button-wrapper {
+ display: flex;
+}
+
+.mod-search__button-wrapper--left,
+.mod-search__button-wrapper--right {
+ flex-shrink: 0;
+}
+
+.mod-search__button {
+ padding: 0.5rem 1rem;
+ font-size: 1rem;
+ line-height: 1.5;
+ border-radius: 0.375rem;
+ white-space: nowrap;
+ min-height: 44px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+}
+
+.mod-search__button--icon {
+ padding: 0.5rem;
+ width: 44px;
+ height: 44px;
+}
+
+.mod-search__button--icon .icon-search {
+ font-size: 1.25rem;
+}
+
+/* Mobile-first responsive adjustments */
+@media (max-width: 575.98px) {
+ .mod-search__input {
+ font-size: 16px;
+ padding: 0.625rem 0.875rem;
+ }
+
+ .mod-search__button {
+ padding: 0.625rem 1.25rem;
+ font-size: 1rem;
+ min-height: 48px;
+ }
+
+ .mod-search__button--icon {
+ width: 48px;
+ height: 48px;
+ }
+
+ .mod-search__input-wrapper--inline {
+ flex-direction: column;
+ }
+
+ .mod-search__button-wrapper--left .mod-search__button,
+ .mod-search__button-wrapper--right .mod-search__button {
+ width: 100%;
+ }
+}
+
+/* Tablet improvements */
+@media (min-width: 576px) and (max-width: 767.98px) {
+ .mod-search__input-wrapper--inline {
+ flex-direction: row;
+ }
+}
+
+/* Desktop enhancements */
+@media (min-width: 768px) {
+ .mod-search__form {
+ flex-direction: row;
+ align-items: center;
+ }
+
+ .mod-search__input-wrapper--inline {
+ flex-direction: row;
+ }
+
+ .mod-search__button-wrapper--top,
+ .mod-search__button-wrapper--bottom {
+ flex: 0 0 auto;
+ }
+}
+
+/* ===== VIRTUEMART MODULE MOBILE RESPONSIVE STYLES ===== */
+
+/* === mod_virtuemart_cart === */
+.mod-vm-cart-responsive {
+ width: 100%;
+}
+
+.mod-vm-cart__header {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ padding: 1rem;
+ background: var(--vm-surface);
+ border: 1px solid var(--vm-border);
+ border-radius: var(--vm-block-radius);
+ margin-bottom: 1rem;
+}
+
+.mod-vm-cart__icon {
+ font-size: 1.5rem;
+ color: var(--vm-btn-primary-bg);
+ flex-shrink: 0;
+}
+
+.mod-vm-cart__summary {
+ flex: 1;
+ min-width: 0;
+}
+
+.mod-vm-cart__count {
+ font-weight: 600;
+ color: var(--vm-text-strong, #ffffff);
+ font-size: 1rem;
+}
+
+.mod-vm-cart__total {
+ color: var(--vm-price-color);
+ font-weight: 700;
+ font-size: var(--vm-price-size, 1.5rem);
+ margin-top: 0.25rem;
+}
+
+.mod-vm-cart__products {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ margin-bottom: 1rem;
+}
+
+.mod-vm-cart__product {
+ display: flex;
+ gap: 0.75rem;
+ padding: 0.75rem;
+ background: var(--vm-surface-2);
+ border: 1px solid var(--vm-border);
+ border-radius: var(--vm-block-radius);
+ align-items: flex-start;
+}
+
+.mod-vm-cart__product-image {
+ flex-shrink: 0;
+ width: 80px;
+}
+
+.mod-vm-cart__product-image img {
+ width: 100%;
+ height: auto;
+ border-radius: var(--vm-input-radius);
+}
+
+.mod-vm-cart__product-details {
+ flex: 1;
+ min-width: 0;
+}
+
+.mod-vm-cart__product-name {
+ font-weight: 600;
+ margin-bottom: 0.25rem;
+ line-height: 1.4;
+}
+
+.mod-vm-cart__product-name a {
+ color: var(--vm-text-strong, #ffffff);
+ text-decoration: none;
+}
+
+.mod-vm-cart__product-name a:hover {
+ color: var(--color-primary, #112855);
+ text-decoration: underline;
+}
+
+.mod-vm-cart__product-quantity {
+ font-size: 0.875rem;
+ color: var(--vm-text-muted);
+ margin-bottom: 0.25rem;
+}
+
+.mod-vm-cart__quantity-value {
+ font-weight: 600;
+ color: var(--vm-text);
+}
+
+.mod-vm-cart__product-price {
+ font-weight: 700;
+ color: var(--vm-price-color);
+ margin-top: 0.25rem;
+}
+
+.mod-vm-cart__product-remove {
+ flex-shrink: 0;
+}
+
+.mod-vm-cart__remove-btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ background: var(--vm-surface);
+ border: 1px solid var(--vm-border);
+ color: var(--danger, #c23a31);
+ text-decoration: none;
+ transition: all 0.2s;
+}
+
+.mod-vm-cart__remove-btn:hover {
+ background: var(--danger, #c23a31);
+ color: white;
+ border-color: var(--danger, #c23a31);
+}
+
+.mod-vm-cart__actions {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.mod-vm-cart__btn {
+ padding: var(--vm-btn-padding-y, 0.5rem) var(--vm-btn-padding-x, 1rem);
+ border-radius: var(--vm-btn-radius);
+ text-align: center;
+ text-decoration: none;
+ font-weight: 600;
+ min-height: 44px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.2s;
+}
+
+.mod-vm-cart__empty {
+ text-align: center;
+ padding: 2rem 1rem;
+ background: var(--vm-surface-2);
+ border: 1px solid var(--vm-border);
+ border-radius: var(--vm-block-radius);
+}
+
+.mod-vm-cart__empty-icon {
+ font-size: 3rem;
+ color: var(--vm-text-muted);
+ display: block;
+ margin-bottom: 1rem;
+}
+
+.mod-vm-cart__empty-text {
+ color: var(--vm-text-muted);
+ margin: 0;
+}
+
+/* === mod_virtuemart_product === */
+.mod-vm-product-responsive {
+ width: 100%;
+}
+
+.mod-vm-product__header {
+ margin-bottom: 1.5rem;
+}
+
+.mod-vm-product__list {
+ display: grid;
+ gap: 1.5rem;
+}
+
+.mod-vm-product__list--div {
+ grid-template-columns: 1fr;
+}
+
+.mod-vm-product__item {
+ background: var(--vm-surface);
+ border: 1px solid var(--vm-border);
+ border-radius: var(--vm-block-radius);
+ box-shadow: var(--vm-block-shadow);
+ overflow: hidden;
+ transition: transform 0.2s, box-shadow 0.2s;
+}
+
+.mod-vm-product__item:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+.mod-vm-product__image {
+ position: relative;
+ overflow: hidden;
+}
+
+.mod-vm-product__image img {
+ width: 100%;
+ height: auto;
+ display: block;
+}
+
+.mod-vm-product__availability {
+ position: absolute;
+ top: 0.5rem;
+ right: 0.5rem;
+ padding: 0.25rem 0.75rem;
+ background: var(--vm-availability-bg);
+ color: var(--vm-availability-text);
+ border-radius: var(--vm-alert-radius);
+ font-size: 0.875rem;
+ font-weight: 600;
+}
+
+.mod-vm-product__content {
+ padding: 1rem;
+}
+
+.mod-vm-product__title {
+ font-size: var(--vm-product-title-size, 1.125rem);
+ font-weight: var(--vm-product-title-weight, 500);
+ margin: 0 0 0.75rem 0;
+ line-height: 1.4;
+}
+
+.mod-vm-product__title a {
+ color: var(--vm-text-strong, #ffffff);
+ text-decoration: none;
+}
+
+.mod-vm-product__title a:hover {
+ color: var(--color-primary, #112855);
+ text-decoration: underline;
+}
+
+.mod-vm-product__description {
+ color: var(--vm-text-muted);
+ font-size: 0.875rem;
+ margin-bottom: 1rem;
+ line-height: 1.6;
+}
+
+.mod-vm-product__price {
+ font-size: var(--vm-price-detail-size, 1.125rem);
+ font-weight: 700;
+ color: var(--vm-price-color);
+ margin-bottom: 1rem;
+}
+
+.mod-vm-product__actions {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.mod-vm-product__btn {
+ padding: var(--vm-btn-padding-y, 0.5rem) var(--vm-btn-padding-x, 1rem);
+ border-radius: var(--vm-btn-radius);
+ text-align: center;
+ text-decoration: none;
+ font-weight: 600;
+ min-height: 44px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.mod-vm-product__empty {
+ text-align: center;
+ padding: 2rem 1rem;
+ background: var(--vm-surface-2);
+ border: 1px solid var(--vm-border);
+ border-radius: var(--vm-block-radius);
+ color: var(--vm-text-muted);
+}
+
+/* === mod_virtuemart_currencies === */
+.mod-vm-currencies-responsive {
+ width: 100%;
+}
+
+.mod-vm-currencies__form {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.mod-vm-currencies__label {
+ font-weight: 600;
+ color: var(--vm-text-strong, #ffffff);
+ font-size: 0.875rem;
+}
+
+.mod-vm-currencies__select-wrapper {
+ position: relative;
+ display: flex;
+ align-items: center;
+}
+
+.mod-vm-currencies__select {
+ flex: 1;
+ padding: 0.5rem 2.5rem 0.5rem 0.75rem;
+ font-size: 1rem;
+ line-height: 1.5;
+ border: 1px solid var(--vm-border);
+ border-radius: var(--vm-input-radius);
+ background: var(--vm-surface);
+ color: var(--vm-text);
+ min-height: 44px;
+ appearance: none;
+ -webkit-appearance: none;
+ cursor: pointer;
+}
+
+.mod-vm-currencies__select:focus {
+ border-color: var(--color-primary, #112855);
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+
+.mod-vm-currencies__icon {
+ position: absolute;
+ right: 0.75rem;
+ pointer-events: none;
+ color: var(--vm-text-muted);
+}
+
+.mod-vm-currencies__submit {
+ padding: var(--vm-btn-padding-y, 0.5rem) var(--vm-btn-padding-x, 1rem);
+ border-radius: var(--vm-btn-radius);
+ min-height: 44px;
+}
+
+.mod-vm-currencies__text-before,
+.mod-vm-currencies__text-after {
+ font-size: 0.875rem;
+ color: var(--vm-text-muted);
+}
+
+/* === mod_virtuemart_category === */
+.mod-vm-category-responsive {
+ width: 100%;
+}
+
+.mod-vm-category__list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.mod-vm-category__item {
+ margin-bottom: 0.5rem;
+}
+
+.mod-vm-category__link {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ padding: 0.75rem;
+ background: var(--vm-surface);
+ border: 1px solid var(--vm-border);
+ border-radius: var(--vm-input-radius);
+ color: var(--vm-text);
+ text-decoration: none;
+ transition: all 0.2s;
+ min-height: 44px;
+}
+
+.mod-vm-category__link:hover {
+ background: var(--vm-surface-2);
+ border-color: var(--color-primary, #112855);
+ color: var(--color-primary, #112855);
+}
+
+.mod-vm-category__link--active {
+ background: var(--vm-btn-primary-bg);
+ border-color: var(--vm-btn-primary-bg);
+ color: var(--vm-btn-primary-text, #ffffff);
+ font-weight: 600;
+}
+
+.mod-vm-category__image {
+ flex-shrink: 0;
+ width: 40px;
+ height: 40px;
+ overflow: hidden;
+ border-radius: var(--vm-input-radius);
+}
+
+.mod-vm-category__image img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.mod-vm-category__name {
+ flex: 1;
+ min-width: 0;
+}
+
+.mod-vm-category__count {
+ color: var(--vm-text-muted);
+ font-size: 0.875rem;
+ flex-shrink: 0;
+}
+
+.mod-vm-category__description {
+ padding: 0.5rem 0.75rem;
+ font-size: 0.875rem;
+ color: var(--vm-text-muted);
+ line-height: 1.6;
+}
+
+.mod-vm-category__sublist {
+ list-style: none;
+ padding: 0 0 0 1.5rem;
+ margin: 0.5rem 0 0 0;
+}
+
+.mod-vm-category__subitem {
+ margin-bottom: 0.25rem;
+}
+
+.mod-vm-category__sublink {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0.5rem 0.75rem;
+ background: var(--vm-surface-2);
+ border: 1px solid var(--vm-border);
+ border-radius: var(--vm-input-radius);
+ color: var(--vm-text);
+ text-decoration: none;
+ font-size: 0.875rem;
+ transition: all 0.2s;
+ min-height: 40px;
+}
+
+.mod-vm-category__sublink:hover {
+ background: var(--vm-surface);
+ border-color: var(--color-primary, #112855);
+ color: var(--color-primary, #112855);
+}
+
+.mod-vm-category__sublink--active {
+ background: var(--vm-btn-secondary-bg);
+ border-color: var(--vm-btn-secondary-bg);
+ color: var(--vm-btn-secondary-text, #ffffff);
+ font-weight: 600;
+}
+
+.mod-vm-category__empty {
+ text-align: center;
+ padding: 2rem 1rem;
+ background: var(--vm-surface-2);
+ border: 1px solid var(--vm-border);
+ border-radius: var(--vm-block-radius);
+ color: var(--vm-text-muted);
+}
+
+/* === mod_virtuemart_manufacturer === */
+.mod-vm-manufacturer-responsive {
+ width: 100%;
+}
+
+.mod-vm-manufacturer__container {
+ display: grid;
+ gap: 1rem;
+}
+
+.mod-vm-manufacturer__container--list {
+ grid-template-columns: 1fr;
+}
+
+.mod-vm-manufacturer__container--grid {
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
+}
+
+.mod-vm-manufacturer__item {
+ background: var(--vm-surface);
+ border: 1px solid var(--vm-border);
+ border-radius: var(--vm-block-radius);
+ overflow: hidden;
+ transition: transform 0.2s, box-shadow 0.2s;
+}
+
+.mod-vm-manufacturer__item:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--vm-block-shadow);
+}
+
+.mod-vm-manufacturer__link {
+ display: block;
+ text-decoration: none;
+ color: var(--vm-text);
+ min-height: 44px;
+}
+
+.mod-vm-manufacturer__image {
+ width: 100%;
+ aspect-ratio: 16/9;
+ overflow: hidden;
+ background: var(--vm-surface-2);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.mod-vm-manufacturer__image img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ padding: 1rem;
+}
+
+.mod-vm-manufacturer__content {
+ padding: 1rem;
+}
+
+.mod-vm-manufacturer__name {
+ font-weight: 600;
+ color: var(--vm-text-strong, #ffffff);
+ display: block;
+ margin-bottom: 0.5rem;
+}
+
+.mod-vm-manufacturer__link:hover .mod-vm-manufacturer__name {
+ color: var(--color-primary, #112855);
+}
+
+.mod-vm-manufacturer__description {
+ font-size: 0.875rem;
+ color: var(--vm-text-muted);
+ line-height: 1.6;
+}
+
+.mod-vm-manufacturer__empty {
+ text-align: center;
+ padding: 2rem 1rem;
+ background: var(--vm-surface-2);
+ border: 1px solid var(--vm-border);
+ border-radius: var(--vm-block-radius);
+ color: var(--vm-text-muted);
+}
+
+/* === Mobile Responsive Adjustments === */
+@media (max-width: 575.98px) {
+ /* Cart module */
+ .mod-vm-cart__header {
+ padding: 0.75rem;
+ }
+
+ .mod-vm-cart__product {
+ flex-direction: column;
+ }
+
+ .mod-vm-cart__product-image {
+ width: 100%;
+ max-width: 200px;
+ margin: 0 auto;
+ }
+
+ .mod-vm-cart__actions {
+ gap: 0.75rem;
+ }
+
+ .mod-vm-cart__btn {
+ min-height: 48px;
+ padding: 0.75rem 1rem;
+ font-size: 1rem;
+ }
+
+ /* Product module */
+ .mod-vm-product__actions {
+ gap: 0.75rem;
+ }
+
+ .mod-vm-product__btn {
+ min-height: 48px;
+ padding: 0.75rem 1rem;
+ }
+
+ /* Currencies module */
+ .mod-vm-currencies__select {
+ font-size: 16px;
+ min-height: 48px;
+ padding: 0.75rem 2.5rem 0.75rem 1rem;
+ }
+
+ .mod-vm-currencies__submit {
+ min-height: 48px;
+ padding: 0.75rem 1rem;
+ }
+
+ /* Category module */
+ .mod-vm-category__link {
+ min-height: 48px;
+ padding: 0.875rem;
+ }
+
+ .mod-vm-category__sublink {
+ min-height: 44px;
+ }
+
+ /* Manufacturer module */
+ .mod-vm-manufacturer__container--grid {
+ grid-template-columns: 1fr;
+ }
+}
+
+/* Tablet adjustments */
+@media (min-width: 576px) and (max-width: 767.98px) {
+ .mod-vm-product__list--div {
+ grid-template-columns: repeat(2, 1fr);
+ }
+
+ .mod-vm-manufacturer__container--grid {
+ grid-template-columns: repeat(2, 1fr);
+ }
+}
+
+/* Desktop enhancements */
+@media (min-width: 768px) {
+ .mod-vm-cart__actions {
+ flex-direction: row;
+ }
+
+ .mod-vm-product__list--div {
+ grid-template-columns: repeat(3, 1fr);
+ }
+
+ .mod-vm-product__actions {
+ flex-direction: row;
+ }
+
+ .mod-vm-manufacturer__container--grid {
+ grid-template-columns: repeat(3, 1fr);
+ }
+}
+
+@media (min-width: 992px) {
+ .mod-vm-product__list--div {
+ grid-template-columns: repeat(4, 1fr);
+ }
+
+ .mod-vm-manufacturer__container--grid {
+ grid-template-columns: repeat(4, 1fr);
+ }
+}
+
+/* ===== STANDARD JOOMLA & COMMUNITY BUILDER MODULE STYLES ===== */
+
+/* === mod_menu === */
+.mod-menu-responsive {
+ width: 100%;
+}
+
+.mod-menu__heading {
+ margin-bottom: 1rem;
+ font-weight: 600;
+}
+
+/* === Main Menu - Collapsible Dropdown Bootstrap Responsive === */
+.mod-menu-main {
+ padding: 0.5rem 0;
+}
+
+.mod-menu-main .navbar-toggler {
+ border-color: var(--border-color, #2b323b);
+ padding: 0.5rem 0.75rem;
+ font-size: 1.25rem;
+ min-height: 48px; /* WCAG 2.1 touch target */
+}
+
+.mod-menu-main .navbar-toggler:focus {
+ box-shadow: 0 0 0 0.25rem rgba(var(--link-color-rgb, 138, 180, 248), 0.25);
+ outline: 0;
+}
+
+.mod-menu-main .navbar-toggler-icon {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(0, 0, 0, 0.75)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
+ display: inline-block;
+ width: 1.5em;
+ height: 1.5em;
+ vertical-align: middle;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: 100%;
+}
+
+.mod-menu-main__list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.mod-menu-main__item {
+ position: relative;
+}
+
+.mod-menu-main__link,
+.mod-menu-main__heading {
+ display: block;
+ padding: 0.75rem 1rem;
+ color: var(--mainmenu-nav-link-color, #fff);
+ text-decoration: none;
+ transition: background-color 0.2s ease, color 0.2s ease;
+ min-height: 48px; /* WCAG 2.1 touch target on mobile */
+ display: flex;
+ align-items: center;
+ border-radius: var(--border-radius, .25rem);
+}
+
+.mod-menu-main__link:hover,
+.mod-menu-main__link:focus {
+ background-color: var(--secondary-bg, #151b22);
+ color: var(--link-hover-color, #c3d6ff);
+ text-decoration: none;
+}
+
+.mod-menu-main__item.active > .mod-menu-main__link,
+.mod-menu-main__item.current > .mod-menu-main__link {
+ color: var(--mainmenu-nav-link-color, #fff);
+ font-weight: 600;
+}
+
+/* Dropdown menu styles */
+.mod-menu-main__dropdown {
+ list-style: none;
+ padding: 0.5rem 0;
+ margin: 0;
+ background-color: var(--body-bg, #0e1318);
+ border: 1px solid var(--border-color, #2b323b);
+ border-radius: var(--border-radius, .25rem);
+ box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
+ display: none;
+}
+
+.mod-menu-main__item.dropdown.show > .mod-menu-main__dropdown {
+ display: block;
+}
+
+.mod-menu-main__dropdown .mod-menu-main__item {
+ padding: 0;
+}
+
+.mod-menu-main__dropdown .mod-menu-main__link {
+ padding: 0.5rem 1.5rem;
+ min-height: 44px; /* Slightly smaller for nested items */
+}
+
+.mod-menu-main__dropdown .mod-menu-main__link:hover,
+.mod-menu-main__dropdown .mod-menu-main__link:focus {
+ background-color: var(--secondary-bg, #151b22);
+}
+
+.mod-menu-main__separator {
+ border-top: 1px solid var(--border-color, #2b323b);
+ margin: 0.5rem 0;
+ padding: 0;
+}
+
+/* Dropdown toggle arrow — uses FontAwesome instead of CSS borders */
+.mod-menu-main__link.dropdown-toggle::after,
+.mod-menu-main__heading.dropdown-toggle::after {
+ font-family: "Font Awesome 6 Free", "Font Awesome 6 Pro", "FontAwesome";
+ font-weight: 900;
+ content: "\f078";
+ display: inline-block;
+ margin-left: auto;
+ padding-left: 0.5rem;
+ vertical-align: middle;
+ font-size: 0.65em;
+ border: none;
+}
+
+/* Desktop styles (≥768px) */
+@media (min-width: 768px) {
+ .mod-menu-main__list {
+ flex-direction: row;
+ flex-wrap: wrap;
+ gap: 0;
+ }
+
+ .mod-menu-main__link,
+ .mod-menu-main__heading {
+ min-height: 44px; /* WCAG 2.1 touch target on desktop */
+ padding: 0.5rem 1rem;
+ }
+
+ .mod-menu-main__item.dropdown {
+ position: relative;
+ }
+
+ .mod-menu-main__dropdown {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ min-width: 200px;
+ z-index: 1000;
+ margin-top: 0.125rem;
+ }
+
+ /* Hover dropdown on desktop */
+ .mod-menu-main__item.dropdown:hover > .mod-menu-main__dropdown {
+ display: block;
+ }
+
+ /* Nested dropdowns */
+ .mod-menu-main__dropdown .mod-menu-main__dropdown {
+ top: 0;
+ left: 100%;
+ margin-top: 0;
+ margin-left: 0.125rem;
+ }
+}
+
+/* Large desktop styles (≥992px) */
+@media (min-width: 992px) {
+ .mod-menu-main {
+ padding: 1rem 0;
+ }
+
+ .mod-menu-main__list {
+ gap: 0.25rem;
+ }
+}
+
+/* === mod_breadcrumbs === */
+.mod-breadcrumbs-responsive {
+ width: 100%;
+ padding: 0.75rem 0;
+}
+
+.mod-breadcrumbs__prefix {
+ font-weight: 600;
+ margin-right: 0.5rem;
+ color: var(--body-color, #e6ebf1);
+}
+
+.mod-breadcrumbs__list {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ align-items: center;
+}
+
+.mod-breadcrumbs__item {
+ display: flex;
+ align-items: center;
+}
+
+.mod-breadcrumbs__link {
+ color: var(--link-color, #8ab4f8);
+ text-decoration: none;
+ transition: color 0.2s;
+}
+
+.mod-breadcrumbs__link:hover {
+ color: var(--link-hover-color, #c3d6ff);
+ text-decoration: underline;
+}
+
+.mod-breadcrumbs__current {
+ color: var(--body-color, #e6ebf1);
+ font-weight: 600;
+}
+
+.mod-breadcrumbs__item--home .icon-home {
+ font-size: 1.25rem;
+}
+
+/* === mod_login === */
+.mod-login-responsive {
+ width: 100%;
+}
+
+.mod-login__form {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.mod-login__greeting {
+ padding: 1rem;
+ background: var(--secondary-bg, #151b22);
+ border-radius: var(--border-radius, .25rem);
+ margin-bottom: 1rem;
+ font-weight: 600;
+}
+
+.mod-login__pretext,
+.mod-login__posttext {
+ font-size: 0.875rem;
+ color: var(--gray-600, #48525d);
+ line-height: 1.6;
+}
+
+.mod-login__fields {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.mod-login__field {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.mod-login__label {
+ font-weight: 600;
+ font-size: 0.875rem;
+ color: var(--body-color, #e6ebf1);
+}
+
+.mod-login__input {
+ padding: 0.5rem 0.75rem;
+ font-size: 1rem;
+ line-height: 1.5;
+ border: 1px solid var(--input-border-color, #dee2e6);
+ border-radius: var(--border-radius, .25rem);
+ background: var(--input-bg, #fff);
+ color: var(--input-color, #212529);
+ min-height: 44px;
+}
+
+.mod-login__input:focus {
+ border-color: var(--color-primary, #112855);
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+
+.mod-login__remember {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.mod-login__checkbox {
+ width: 20px;
+ height: 20px;
+ cursor: pointer;
+}
+
+.mod-login__remember-label {
+ font-size: 0.875rem;
+ cursor: pointer;
+ margin: 0;
+}
+
+.mod-login__actions {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.mod-login__btn {
+ padding: 0.625rem 1rem;
+ font-size: 1rem;
+ font-weight: 600;
+ border-radius: var(--border-radius, .25rem);
+ min-height: 44px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ transition: all 0.2s;
+ border: none;
+ cursor: pointer;
+}
+
+.mod-login__links {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ margin-top: 0.5rem;
+}
+
+.mod-login__link {
+ color: var(--link-color, #8ab4f8);
+ text-decoration: none;
+ font-size: 0.875rem;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0.5rem;
+ border-radius: var(--border-radius, .25rem);
+ transition: background 0.2s;
+}
+
+.mod-login__link:hover {
+ background: var(--secondary-bg, #151b22);
+ color: var(--link-hover-color, #c3d6ff);
+}
+
+/* === mod_articles_latest === */
+.mod-articles-latest-responsive {
+ width: 100%;
+}
+
+.mod-articles-latest__list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
+}
+
+.mod-articles-latest__item {
+ padding-bottom: 1.5rem;
+ border-bottom: 1px solid var(--border-color, #2b323b);
+}
+
+.mod-articles-latest__item:last-child {
+ border-bottom: none;
+ padding-bottom: 0;
+}
+
+.mod-articles-latest__title {
+ margin: 0 0 0.75rem 0;
+ font-weight: 600;
+ line-height: 1.4;
+}
+
+.mod-articles-latest__link {
+ color: var(--body-color, #e6ebf1);
+ text-decoration: none;
+ transition: color 0.2s;
+}
+
+.mod-articles-latest__link:hover {
+ color: var(--color-primary, #112855);
+ text-decoration: underline;
+}
+
+.mod-articles-latest__meta {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 1rem;
+ font-size: 0.875rem;
+ color: var(--gray-600, #48525d);
+ margin-bottom: 0.75rem;
+}
+
+.mod-articles-latest__meta > span {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+}
+
+.mod-articles-latest__intro {
+ color: var(--body-color, #e6ebf1);
+ line-height: 1.6;
+ margin-bottom: 1rem;
+}
+
+.mod-articles-latest__readmore {
+ margin-top: 1rem;
+}
+
+.mod-articles-latest__readmore-link {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ min-height: 44px;
+}
+
+.mod-articles-latest__empty {
+ text-align: center;
+ padding: 2rem 1rem;
+ background: var(--secondary-bg, #151b22);
+ border-radius: var(--border-radius, .25rem);
+ color: var(--gray-600, #48525d);
+}
+
+/* === mod_cblogin (Community Builder) === */
+.mod-cblogin-responsive {
+ width: 100%;
+}
+
+.mod-cblogin__form {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.mod-cblogin__greeting {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ padding: 1rem;
+ background: var(--secondary-bg, #151b22);
+ border-radius: var(--border-radius, .25rem);
+ margin-bottom: 1rem;
+}
+
+.mod-cblogin__avatar {
+ flex-shrink: 0;
+ width: 60px;
+ height: 60px;
+ border-radius: 50%;
+ overflow: hidden;
+}
+
+.mod-cblogin__avatar img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.mod-cblogin__user-info {
+ flex: 1;
+}
+
+.mod-cblogin__username {
+ font-weight: 600;
+ font-size: 1.125rem;
+}
+
+.mod-cblogin__pretext,
+.mod-cblogin__posttext {
+ font-size: 0.875rem;
+ color: var(--gray-600, #48525d);
+ line-height: 1.6;
+}
+
+.mod-cblogin__fields {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.mod-cblogin__field {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.mod-cblogin__label {
+ font-weight: 600;
+ font-size: 0.875rem;
+ color: var(--body-color, #e6ebf1);
+}
+
+.mod-cblogin__input {
+ padding: 0.5rem 0.75rem;
+ font-size: 1rem;
+ line-height: 1.5;
+ border: 1px solid var(--input-border-color, #dee2e6);
+ border-radius: var(--border-radius, .25rem);
+ background: var(--input-bg, #fff);
+ color: var(--input-color, #212529);
+ min-height: 44px;
+}
+
+.mod-cblogin__input:focus {
+ border-color: var(--color-primary, #112855);
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+
+.mod-cblogin__remember {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.mod-cblogin__checkbox {
+ width: 20px;
+ height: 20px;
+ cursor: pointer;
+}
+
+.mod-cblogin__remember-label {
+ font-size: 0.875rem;
+ cursor: pointer;
+ margin: 0;
+}
+
+.mod-cblogin__actions {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.mod-cblogin__btn {
+ padding: 0.625rem 1rem;
+ font-size: 1rem;
+ font-weight: 600;
+ border-radius: var(--border-radius, .25rem);
+ min-height: 44px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ transition: all 0.2s;
+ border: none;
+ cursor: pointer;
+ text-decoration: none;
+}
+
+.mod-cblogin__links {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ margin-top: 0.5rem;
+}
+
+.mod-cblogin__link {
+ color: var(--link-color, #8ab4f8);
+ text-decoration: none;
+ font-size: 0.875rem;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0.5rem;
+ border-radius: var(--border-radius, .25rem);
+ transition: background 0.2s;
+}
+
+.mod-cblogin__link:hover {
+ background: var(--secondary-bg, #151b22);
+ color: var(--link-hover-color, #c3d6ff);
+}
+
+/* === mod_comprofilerOnline (Community Builder) === */
+.mod-cb-online-responsive {
+ width: 100%;
+}
+
+.mod-cb-online__stats {
+ padding: 1rem;
+ background: var(--secondary-bg, #151b22);
+ border-radius: var(--border-radius, .25rem);
+ margin-bottom: 1.5rem;
+}
+
+.mod-cb-online__count {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-bottom: 1rem;
+}
+
+.mod-cb-online__count-number {
+ font-size: 2.5rem;
+ font-weight: 700;
+ color: var(--color-primary, #112855);
+ line-height: 1;
+}
+
+.mod-cb-online__count-label {
+ font-size: 0.875rem;
+ color: var(--gray-600, #48525d);
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+.mod-cb-online__breakdown {
+ display: flex;
+ justify-content: center;
+ gap: 1.5rem;
+ flex-wrap: wrap;
+}
+
+.mod-cb-online__breakdown-item {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ font-size: 0.875rem;
+ color: var(--body-color, #e6ebf1);
+}
+
+.mod-cb-online__heading {
+ font-size: 1.125rem;
+ font-weight: 600;
+ margin: 0 0 1rem 0;
+}
+
+.mod-cb-online__list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+}
+
+.mod-cb-online__user {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ padding: 0.75rem;
+ background: var(--body-bg, #0e1318);
+ border: 1px solid var(--border-color, #2b323b);
+ border-radius: var(--border-radius, .25rem);
+ transition: all 0.2s;
+}
+
+.mod-cb-online__user:hover {
+ background: var(--secondary-bg, #151b22);
+ border-color: var(--color-primary, #112855);
+}
+
+.mod-cb-online__avatar {
+ flex-shrink: 0;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ overflow: hidden;
+}
+
+.mod-cb-online__avatar img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.mod-cb-online__info {
+ flex: 1;
+ min-width: 0;
+}
+
+.mod-cb-online__name {
+ font-weight: 600;
+ color: var(--body-color, #e6ebf1);
+ text-decoration: none;
+ display: block;
+ margin-bottom: 0.25rem;
+}
+
+.mod-cb-online__name:hover {
+ color: var(--color-primary, #112855);
+}
+
+.mod-cb-online__status {
+ font-size: 0.875rem;
+ color: var(--gray-600, #48525d);
+ display: block;
+}
+
+.mod-cb-online__indicator {
+ flex-shrink: 0;
+ color: var(--success, #4aa664);
+ font-size: 1.25rem;
+}
+
+.mod-cb-online__empty {
+ text-align: center;
+ padding: 2rem 1rem;
+ background: var(--secondary-bg, #151b22);
+ border-radius: var(--border-radius, .25rem);
+ color: var(--gray-600, #48525d);
+}
+
+/* === Mobile Responsive Adjustments === */
+@media (max-width: 575.98px) {
+ /* Login modules */
+ .mod-login__input,
+ .mod-cblogin__input {
+ font-size: 16px;
+ min-height: 48px;
+ padding: 0.75rem 1rem;
+ }
+
+ .mod-login__btn,
+ .mod-cblogin__btn {
+ min-height: 48px;
+ padding: 0.75rem 1rem;
+ }
+
+ .mod-articles-latest__meta {
+ flex-direction: column;
+ gap: 0.5rem;
+ }
+
+ .mod-cb-online__breakdown {
+ flex-direction: column;
+ gap: 0.75rem;
+ }
+}
+
+/* Tablet and desktop enhancements */
+@media (min-width: 768px) {
+ .mod-login__actions,
+ .mod-cblogin__actions {
+ flex-direction: row;
+ }
+
+ .mod-cb-online__stats {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .mod-cb-online__count {
+ margin-bottom: 0;
+ align-items: flex-start;
+ }
+}
+
+/* ===== INDUSTRY EXTENSION MODULE STYLES ===== */
+
+/* === mod_k2_content (K2) === */
+.mod-k2-content-responsive {
+ width: 100%;
+}
+
+.mod-k2-content__list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
+}
+
+.mod-k2-content__item {
+ display: flex;
+ gap: 1rem;
+ padding-bottom: 1.5rem;
+ border-bottom: 1px solid var(--border-color, #2b323b);
+}
+
+.mod-k2-content__item:last-child {
+ border-bottom: none;
+ padding-bottom: 0;
+}
+
+.mod-k2-content__image {
+ flex-shrink: 0;
+ width: 120px;
+ overflow: hidden;
+ border-radius: var(--border-radius, .25rem);
+}
+
+.mod-k2-content__image img {
+ width: 100%;
+ height: auto;
+ display: block;
+ transition: transform 0.3s;
+}
+
+.mod-k2-content__image:hover img {
+ transform: scale(1.05);
+}
+
+.mod-k2-content__content {
+ flex: 1;
+ min-width: 0;
+}
+
+.mod-k2-content__title {
+ margin: 0 0 0.75rem 0;
+ font-weight: 600;
+ line-height: 1.4;
+}
+
+.mod-k2-content__title a {
+ color: var(--body-color, #e6ebf1);
+ text-decoration: none;
+ transition: color 0.2s;
+}
+
+.mod-k2-content__title a:hover {
+ color: var(--color-primary, #112855);
+ text-decoration: underline;
+}
+
+.mod-k2-content__meta {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 1rem;
+ font-size: 0.875rem;
+ color: var(--gray-600, #48525d);
+ margin-bottom: 0.75rem;
+}
+
+.mod-k2-content__meta > span {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+}
+
+.mod-k2-content__intro {
+ color: var(--body-color, #e6ebf1);
+ line-height: 1.6;
+ margin-bottom: 1rem;
+}
+
+.mod-k2-content__readmore {
+ margin-top: 1rem;
+}
+
+.mod-k2-content__readmore-link {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ min-height: 44px;
+}
+
+.mod-k2-content__custom-link {
+ margin-top: 1.5rem;
+ text-align: center;
+}
+
+.mod-k2-content__empty {
+ text-align: center;
+ padding: 2rem 1rem;
+ background: var(--secondary-bg, #151b22);
+ border-radius: var(--border-radius, .25rem);
+ color: var(--gray-600, #48525d);
+}
+
+/* === mod_acymailing (AcyMailing) === */
+.mod-acymailing-responsive {
+ width: 100%;
+}
+
+.mod-acymailing__form-container {
+ background: var(--body-bg, #0e1318);
+ padding: 1.5rem;
+ border-radius: var(--border-radius, .25rem);
+ border: 1px solid var(--border-color, #2b323b);
+}
+
+.mod-acymailing__intro {
+ margin-bottom: 1.5rem;
+ line-height: 1.6;
+ color: var(--body-color, #e6ebf1);
+}
+
+.mod-acymailing__outro {
+ margin-top: 1.5rem;
+ font-size: 0.875rem;
+ color: var(--gray-600, #48525d);
+ line-height: 1.6;
+}
+
+.mod-acymailing__empty {
+ text-align: center;
+ padding: 2rem 1rem;
+ background: var(--secondary-bg, #151b22);
+ border-radius: var(--border-radius, .25rem);
+ color: var(--gray-600, #48525d);
+}
+
+/* === mod_hikashop_cart (HikaShop) === */
+.mod-hikashop-cart-responsive {
+ width: 100%;
+}
+
+.mod-hikashop-cart__header {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ padding: 1rem;
+ background: var(--secondary-bg, #151b22);
+ border: 1px solid var(--border-color, #2b323b);
+ border-radius: var(--border-radius, .25rem);
+ margin-bottom: 1rem;
+}
+
+.mod-hikashop-cart__icon {
+ font-size: 1.5rem;
+ color: var(--color-primary, #112855);
+ flex-shrink: 0;
+}
+
+.mod-hikashop-cart__summary {
+ flex: 1;
+ min-width: 0;
+}
+
+.mod-hikashop-cart__count {
+ font-weight: 600;
+ color: var(--body-color, #e6ebf1);
+ font-size: 1rem;
+}
+
+.mod-hikashop-cart__total {
+ color: var(--success, #4aa664);
+ font-weight: 700;
+ font-size: 1.25rem;
+ margin-top: 0.25rem;
+}
+
+.mod-hikashop-cart__products {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ margin-bottom: 1rem;
+}
+
+.mod-hikashop-cart__product {
+ display: flex;
+ gap: 0.75rem;
+ padding: 0.75rem;
+ background: var(--body-bg, #0e1318);
+ border: 1px solid var(--border-color, #2b323b);
+ border-radius: var(--border-radius, .25rem);
+ align-items: flex-start;
+}
+
+.mod-hikashop-cart__product-image {
+ flex-shrink: 0;
+ width: 80px;
+}
+
+.mod-hikashop-cart__product-image img {
+ width: 100%;
+ height: auto;
+ border-radius: var(--border-radius, .25rem);
+}
+
+.mod-hikashop-cart__product-details {
+ flex: 1;
+ min-width: 0;
+}
+
+.mod-hikashop-cart__product-name {
+ font-weight: 600;
+ margin-bottom: 0.25rem;
+ line-height: 1.4;
+ color: var(--body-color, #e6ebf1);
+}
+
+.mod-hikashop-cart__product-quantity {
+ font-size: 0.875rem;
+ color: var(--gray-600, #48525d);
+ margin-bottom: 0.25rem;
+}
+
+.mod-hikashop-cart__quantity-value {
+ font-weight: 600;
+ color: var(--body-color, #e6ebf1);
+}
+
+.mod-hikashop-cart__product-price {
+ font-weight: 700;
+ color: var(--success, #4aa664);
+ margin-top: 0.25rem;
+}
+
+.mod-hikashop-cart__product-remove {
+ flex-shrink: 0;
+}
+
+.mod-hikashop-cart__remove-btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ background: var(--body-bg, #0e1318);
+ border: 1px solid var(--border-color, #2b323b);
+ color: var(--danger, #c23a31);
+ text-decoration: none;
+ transition: all 0.2s;
+}
+
+.mod-hikashop-cart__remove-btn:hover {
+ background: var(--danger, #c23a31);
+ color: white;
+ border-color: var(--danger, #c23a31);
+}
+
+.mod-hikashop-cart__actions {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.mod-hikashop-cart__btn {
+ padding: 0.625rem 1rem;
+ border-radius: var(--border-radius, .25rem);
+ text-align: center;
+ text-decoration: none;
+ font-weight: 600;
+ min-height: 44px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.2s;
+}
+
+.mod-hikashop-cart__empty {
+ text-align: center;
+ padding: 2rem 1rem;
+ background: var(--secondary-bg, #151b22);
+ border: 1px solid var(--border-color, #2b323b);
+ border-radius: var(--border-radius, .25rem);
+}
+
+.mod-hikashop-cart__empty-icon {
+ font-size: 3rem;
+ color: var(--gray-600, #48525d);
+ display: block;
+ margin-bottom: 1rem;
+}
+
+.mod-hikashop-cart__empty-text {
+ color: var(--gray-600, #48525d);
+ margin: 0;
+}
+
+/* === mod_kunenalatest (Kunena Forum) === */
+.mod-kunena-latest-responsive {
+ width: 100%;
+}
+
+.mod-kunena-latest__list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.mod-kunena-latest__item {
+ display: flex;
+ gap: 0.75rem;
+ padding: 1rem;
+ background: var(--body-bg, #0e1318);
+ border: 1px solid var(--border-color, #2b323b);
+ border-radius: var(--border-radius, .25rem);
+ transition: all 0.2s;
+}
+
+.mod-kunena-latest__item:hover {
+ background: var(--secondary-bg, #151b22);
+ border-color: var(--color-primary, #112855);
+}
+
+.mod-kunena-latest__avatar {
+ flex-shrink: 0;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ overflow: hidden;
+}
+
+.mod-kunena-latest__avatar img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.mod-kunena-latest__content {
+ flex: 1;
+ min-width: 0;
+}
+
+.mod-kunena-latest__title {
+ margin: 0 0 0.5rem 0;
+ font-weight: 600;
+ font-size: 1rem;
+ line-height: 1.4;
+}
+
+.mod-kunena-latest__title a {
+ color: var(--body-color, #e6ebf1);
+ text-decoration: none;
+ transition: color 0.2s;
+}
+
+.mod-kunena-latest__title a:hover {
+ color: var(--color-primary, #112855);
+ text-decoration: underline;
+}
+
+.mod-kunena-latest__meta {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.75rem;
+ font-size: 0.875rem;
+ color: var(--gray-600, #48525d);
+ margin-bottom: 0.5rem;
+}
+
+.mod-kunena-latest__meta > span {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+}
+
+.mod-kunena-latest__meta a {
+ color: var(--gray-600, #48525d);
+ text-decoration: none;
+ transition: color 0.2s;
+}
+
+.mod-kunena-latest__meta a:hover {
+ color: var(--color-primary, #112855);
+}
+
+.mod-kunena-latest__excerpt {
+ font-size: 0.875rem;
+ color: var(--body-color, #e6ebf1);
+ line-height: 1.6;
+ margin-top: 0.5rem;
+}
+
+.mod-kunena-latest__more {
+ margin-top: 1.5rem;
+ text-align: center;
+}
+
+.mod-kunena-latest__more-link {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ min-height: 44px;
+}
+
+.mod-kunena-latest__empty {
+ text-align: center;
+ padding: 2rem 1rem;
+ background: var(--secondary-bg, #151b22);
+ border-radius: var(--border-radius, .25rem);
+ color: var(--gray-600, #48525d);
+}
+
+/* === Mobile Responsive Adjustments === */
+@media (max-width: 575.98px) {
+ .mod-k2-content__item {
+ flex-direction: column;
+ }
+
+ .mod-k2-content__image {
+ width: 100%;
+ max-width: 300px;
+ margin: 0 auto;
+ }
+
+ .mod-k2-content__meta {
+ flex-direction: column;
+ gap: 0.5rem;
+ }
+
+ .mod-hikashop-cart__product {
+ flex-direction: column;
+ }
+
+ .mod-hikashop-cart__product-image {
+ width: 100%;
+ max-width: 200px;
+ margin: 0 auto;
+ }
+
+ .mod-hikashop-cart__actions {
+ gap: 0.75rem;
+ }
+
+ .mod-hikashop-cart__btn {
+ min-height: 48px;
+ padding: 0.75rem 1rem;
+ font-size: 1rem;
+ }
+
+ .mod-kunena-latest__meta {
+ flex-direction: column;
+ gap: 0.5rem;
+ }
+}
+
+/* Tablet and desktop enhancements */
+@media (min-width: 768px) {
+ .mod-hikashop-cart__actions {
+ flex-direction: row;
+ }
+
+ .mod-k2-content__custom-link {
+ text-align: left;
+ }
+}
+
+/* ===== ADDITIONAL KUNENA & MEMBERSHIP PRO MODULE STYLES ===== */
+
+/* === mod_kunenalogin (Kunena Login) === */
+.mod-kunena-login-responsive {
+ width: 100%;
+}
+
+.mod-kunena-login__profile {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ padding: 1rem;
+ background: var(--secondary-bg, #151b22);
+ border-radius: var(--border-radius, .25rem);
+ margin-bottom: 1rem;
+}
+
+.mod-kunena-login__avatar {
+ flex-shrink: 0;
+ width: 60px;
+ height: 60px;
+ border-radius: 50%;
+ overflow: hidden;
+}
+
+.mod-kunena-login__avatar img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.mod-kunena-login__user-info {
+ flex: 1;
+}
+
+.mod-kunena-login__username {
+ font-weight: 600;
+ font-size: 1.125rem;
+ margin-bottom: 0.25rem;
+}
+
+.mod-kunena-login__username a {
+ color: var(--body-color, #e6ebf1);
+ text-decoration: none;
+}
+
+.mod-kunena-login__username a:hover {
+ color: var(--color-primary, #112855);
+}
+
+.mod-kunena-login__rank {
+ font-size: 0.875rem;
+ color: var(--gray-600, #48525d);
+}
+
+.mod-kunena-login__stats {
+ display: flex;
+ gap: 1.5rem;
+ padding: 1rem;
+ background: var(--body-bg, #0e1318);
+ border: 1px solid var(--border-color, #2b323b);
+ border-radius: var(--border-radius, .25rem);
+ margin-bottom: 1rem;
+}
+
+.mod-kunena-login__stat {
+ display: flex;
+ gap: 0.5rem;
+ align-items: center;
+}
+
+.mod-kunena-login__stat-label {
+ color: var(--gray-600, #48525d);
+ font-size: 0.875rem;
+}
+
+.mod-kunena-login__stat-value {
+ font-weight: 600;
+ color: var(--body-color, #e6ebf1);
+}
+
+.mod-kunena-login__form {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.mod-kunena-login__pretext,
+.mod-kunena-login__posttext {
+ font-size: 0.875rem;
+ color: var(--gray-600, #48525d);
+ line-height: 1.6;
+}
+
+.mod-kunena-login__fields {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.mod-kunena-login__field {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.mod-kunena-login__label {
+ font-weight: 600;
+ font-size: 0.875rem;
+ color: var(--body-color, #e6ebf1);
+}
+
+.mod-kunena-login__input {
+ padding: 0.5rem 0.75rem;
+ font-size: 1rem;
+ line-height: 1.5;
+ border: 1px solid var(--input-border-color, #dee2e6);
+ border-radius: var(--border-radius, .25rem);
+ background: var(--input-bg, #fff);
+ color: var(--input-color, #212529);
+ min-height: 44px;
+}
+
+.mod-kunena-login__input:focus {
+ border-color: var(--color-primary, #112855);
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+
+.mod-kunena-login__remember {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.mod-kunena-login__checkbox {
+ width: 20px;
+ height: 20px;
+ cursor: pointer;
+}
+
+.mod-kunena-login__remember-label {
+ font-size: 0.875rem;
+ cursor: pointer;
+ margin: 0;
+}
+
+.mod-kunena-login__actions {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+.mod-kunena-login__btn {
+ padding: 0.625rem 1rem;
+ font-size: 1rem;
+ font-weight: 600;
+ border-radius: var(--border-radius, .25rem);
+ min-height: 44px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ transition: all 0.2s;
+ border: none;
+ cursor: pointer;
+ text-decoration: none;
+ position: relative;
+}
+
+.mod-kunena-login__badge {
+ position: absolute;
+ top: -8px;
+ right: -8px;
+ background: var(--danger, #c23a31);
+ color: white;
+ border-radius: 50%;
+ width: 24px;
+ height: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 0.75rem;
+ font-weight: 700;
+}
+
+.mod-kunena-login__logout-form {
+ width: 100%;
+}
+
+.mod-kunena-login__links {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ margin-top: 0.5rem;
+}
+
+.mod-kunena-login__link {
+ color: var(--link-color, #8ab4f8);
+ text-decoration: none;
+ font-size: 0.875rem;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0.5rem;
+ border-radius: var(--border-radius, .25rem);
+ transition: background 0.2s;
+}
+
+.mod-kunena-login__link:hover {
+ background: var(--secondary-bg, #151b22);
+ color: var(--link-hover-color, #c3d6ff);
+}
+
+/* === mod_kunenasearch (Kunena Search) === */
+.mod-kunena-search-responsive {
+ width: 100%;
+}
+
+.mod-kunena-search__form {
+ display: flex;
+ gap: 0.5rem;
+ width: 100%;
+}
+
+.mod-kunena-search__form--button-top,
+.mod-kunena-search__form--button-bottom {
+ flex-direction: column;
+}
+
+.mod-kunena-search__form--button-left {
+ flex-direction: row-reverse;
+}
+
+.mod-kunena-search__form--button-right {
+ flex-direction: row;
+}
+
+.mod-kunena-search__input-wrapper {
+ flex: 1;
+}
+
+.mod-kunena-search__input {
+ width: 100%;
+ padding: 0.5rem 0.75rem;
+ font-size: 1rem;
+ line-height: 1.5;
+ border: 1px solid var(--input-border-color, #dee2e6);
+ border-radius: var(--border-radius, .25rem);
+ background: var(--input-bg, #fff);
+ color: var(--input-color, #212529);
+ min-height: 44px;
+}
+
+.mod-kunena-search__input:focus {
+ border-color: var(--color-primary, #112855);
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+
+.mod-kunena-search__button {
+ padding: 0.5rem 1rem;
+ min-height: 44px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+}
+
+.mod-kunena-search__form--button-top .mod-kunena-search__button,
+.mod-kunena-search__form--button-bottom .mod-kunena-search__button {
+ width: 100%;
+}
+
+/* === mod_kunenastats (Kunena Statistics) === */
+.mod-kunena-stats-responsive {
+ width: 100%;
+}
+
+.mod-kunena-stats__container {
+ display: grid;
+ gap: 1rem;
+ grid-template-columns: 1fr;
+}
+
+.mod-kunena-stats__stat {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ padding: 1rem;
+ background: var(--body-bg, #0e1318);
+ border: 1px solid var(--border-color, #2b323b);
+ border-radius: var(--border-radius, .25rem);
+ transition: all 0.2s;
+}
+
+.mod-kunena-stats__stat:hover {
+ background: var(--secondary-bg, #151b22);
+ border-color: var(--color-primary, #112855);
+}
+
+.mod-kunena-stats__icon {
+ font-size: 2rem;
+ color: var(--color-primary, #112855);
+ flex-shrink: 0;
+ width: 48px;
+ height: 48px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: var(--secondary-bg, #151b22);
+ border-radius: 50%;
+}
+
+.mod-kunena-stats__content {
+ flex: 1;
+}
+
+.mod-kunena-stats__value {
+ font-size: 1.75rem;
+ font-weight: 700;
+ color: var(--body-color, #e6ebf1);
+ line-height: 1;
+ margin-bottom: 0.25rem;
+}
+
+.mod-kunena-stats__value--link a {
+ color: var(--color-primary, #112855);
+ text-decoration: none;
+ font-size: 1.125rem;
+}
+
+.mod-kunena-stats__value--link a:hover {
+ text-decoration: underline;
+}
+
+.mod-kunena-stats__label {
+ font-size: 0.875rem;
+ color: var(--gray-600, #48525d);
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+.mod-kunena-stats__stat--latest-member .mod-kunena-stats__label {
+ margin-bottom: 0.25rem;
+}
+
+/* === mod_osmembership (OS Membership Pro) === */
+.mod-osmembership-responsive {
+ width: 100%;
+}
+
+.mod-osmembership__plans {
+ display: grid;
+ gap: 2rem;
+ grid-template-columns: 1fr;
+}
+
+.mod-osmembership__plan {
+ background: var(--body-bg, #0e1318);
+ border: 2px solid var(--border-color, #2b323b);
+ border-radius: var(--border-radius, .25rem);
+ overflow: hidden;
+ transition: all 0.3s;
+ display: flex;
+ flex-direction: column;
+}
+
+.mod-osmembership__plan:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
+ border-color: var(--color-primary, #112855);
+}
+
+.mod-osmembership__plan-image {
+ width: 100%;
+ overflow: hidden;
+}
+
+.mod-osmembership__plan-image img {
+ width: 100%;
+ height: auto;
+ display: block;
+}
+
+.mod-osmembership__plan-content {
+ padding: 2rem;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+}
+
+.mod-osmembership__plan-title {
+ margin: 0 0 1rem 0;
+ font-weight: 700;
+ font-size: 1.5rem;
+ line-height: 1.3;
+}
+
+.mod-osmembership__plan-description {
+ color: var(--gray-600, #48525d);
+ line-height: 1.6;
+ margin-bottom: 1.5rem;
+}
+
+.mod-osmembership__plan-pricing {
+ margin-bottom: 1.5rem;
+}
+
+.mod-osmembership__price {
+ display: flex;
+ align-items: baseline;
+ gap: 0.5rem;
+ flex-wrap: wrap;
+}
+
+.mod-osmembership__currency {
+ font-size: 1.5rem;
+ color: var(--color-primary, #112855);
+ font-weight: 600;
+}
+
+.mod-osmembership__amount {
+ font-size: 2.5rem;
+ font-weight: 700;
+ color: var(--color-primary, #112855);
+ line-height: 1;
+}
+
+.mod-osmembership__period {
+ color: var(--gray-600, #48525d);
+ font-size: 1rem;
+}
+
+.mod-osmembership__price--free {
+ font-size: 2rem;
+ font-weight: 700;
+ color: var(--success, #4aa664);
+}
+
+.mod-osmembership__features {
+ flex: 1;
+ margin-bottom: 1.5rem;
+}
+
+.mod-osmembership__features-list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.mod-osmembership__feature {
+ padding: 0.5rem 0;
+ display: flex;
+ align-items: flex-start;
+ gap: 0.5rem;
+}
+
+.mod-osmembership__feature .icon-check {
+ color: var(--success, #4aa664);
+ flex-shrink: 0;
+ margin-top: 0.25rem;
+}
+
+.mod-osmembership__actions {
+ margin-top: auto;
+}
+
+.mod-osmembership__btn {
+ width: 100%;
+ min-height: 48px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ text-decoration: none;
+}
+
+.mod-osmembership__all-plans {
+ margin-top: 2rem;
+ text-align: center;
+}
+
+.mod-osmembership__all-plans-link {
+ min-height: 44px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.mod-osmembership__empty {
+ text-align: center;
+ padding: 2rem 1rem;
+ background: var(--secondary-bg, #151b22);
+ border-radius: var(--border-radius, .25rem);
+ color: var(--gray-600, #48525d);
+}
+
+/* === mod_stats === */
+.mod_stats__table {
+ width: 100%;
+ border-collapse: collapse;
+}
+
+.mod_stats__table tr {
+ border-bottom: 1px solid var(--border-color, #2b323b);
+}
+
+.mod_stats__table tr:last-child {
+ border-bottom: none;
+}
+
+.mod_stats__label {
+ text-align: start;
+ font-weight: 600;
+ padding: 0.6rem 1rem 0.6rem 0;
+ color: var(--body-font-color, #e6ebf1);
+}
+
+.mod_stats__data {
+ text-align: end;
+ padding: 0.6rem 0;
+ color: var(--gray-600, #48525d);
+}
+
+/* === Mobile Responsive Adjustments === */
+@media (max-width: 575.98px) {
+ .mod-kunena-login__input {
+ font-size: 16px;
+ min-height: 48px;
+ padding: 0.75rem 1rem;
+ }
+
+ .mod-kunena-login__btn {
+ min-height: 48px;
+ }
+
+ .mod-kunena-login__stats {
+ flex-direction: column;
+ gap: 0.75rem;
+ }
+
+ .mod-kunena-search__input {
+ font-size: 16px;
+ min-height: 48px;
+ padding: 0.75rem 1rem;
+ }
+
+ .mod-kunena-search__button {
+ min-height: 48px;
+ }
+
+ .mod-kunena-stats__container {
+ grid-template-columns: 1fr;
+ }
+}
+
+/* Tablet adjustments */
+@media (min-width: 576px) {
+ .mod-kunena-stats__container {
+ grid-template-columns: repeat(2, 1fr);
+ }
+
+ .mod-osmembership__plans {
+ grid-template-columns: repeat(2, 1fr);
+ }
+}
+
+/* Desktop enhancements */
+@media (min-width: 768px) {
+ .mod-kunena-login__actions {
+ flex-direction: row;
+ }
+
+ .mod-kunena-stats__container {
+ grid-template-columns: repeat(3, 1fr);
+ }
+}
+
+@media (min-width: 992px) {
+ .mod-osmembership__plans {
+ grid-template-columns: repeat(3, 1fr);
+ }
+}
+
+/* ============================================================================
+ COMMUNITY BUILDER COMPONENT STYLES
+ Mobile-responsive styles for com_comprofiler component views
+ ============================================================================ */
+
+/* === Base Component Wrapper === */
+.cb-component {
+width: 100%;
+max-width: 100%;
+}
+
+/* === User Profile View === */
+.cb-profile-responsive {
+background: var(--body-bg, #0e1318);
+border-radius: var(--border-radius, .25rem);
+}
+
+.cb-profile__header {
+display: flex;
+flex-direction: column;
+align-items: center;
+gap: 1.5rem;
+padding: 2rem;
+background: var(--secondary-bg, #151b22);
+border-radius: var(--border-radius, .25rem);
+margin-bottom: 2rem;
+}
+
+.cb-profile__avatar {
+width: 150px;
+height: 150px;
+border-radius: 50%;
+overflow: hidden;
+border: 4px solid var(--body-bg, #0e1318);
+box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+.cb-profile__avatar img {
+width: 100%;
+height: 100%;
+object-fit: cover;
+}
+
+.cb-profile__header-info {
+text-align: center;
+}
+
+.cb-profile__name {
+font-size: 1.75rem;
+font-weight: 700;
+margin: 0 0 0.5rem;
+color: var(--heading-color, #f1f5f9);
+}
+
+.cb-profile__status {
+display: inline-flex;
+align-items: center;
+gap: 0.5rem;
+padding: 0.5rem 1rem;
+background: var(--success-bg);
+color: var(--success, #4aa664);
+border-radius: 2rem;
+font-size: 0.875rem;
+font-weight: 600;
+}
+
+/* Profile Tabs */
+.cb-profile__tabs {
+margin-top: 2rem;
+}
+
+.cb-profile__tabs-nav {
+display: flex;
+flex-wrap: wrap;
+gap: 0.5rem;
+margin: 0 0 2rem;
+padding: 0;
+list-style: none;
+border-bottom: 2px solid var(--border-color, #2b323b);
+}
+
+.cb-profile__tab-item {
+margin: 0;
+}
+
+.cb-profile__tab-link {
+display: block;
+padding: 0.75rem 1.5rem;
+color: var(--body-color, #e6ebf1);
+text-decoration: none;
+border-radius: var(--border-radius, .25rem) var(--border-radius, .25rem) 0 0;
+transition: all 0.2s;
+min-height: 44px;
+display: flex;
+align-items: center;
+}
+
+.cb-profile__tab-link:hover,
+.cb-profile__tab-link[aria-selected="true"] {
+background: var(--color-primary, #112855);
+color: white;
+}
+
+.cb-profile__tab-pane {
+display: none;
+padding: 1.5rem;
+background: var(--body-bg, #0e1318);
+border: 1px solid var(--border-color, #2b323b);
+border-radius: var(--border-radius, .25rem);
+}
+
+.cb-profile__tab-pane[aria-selected="true"] {
+display: block;
+}
+
+.cb-profile__tab-description {
+margin-bottom: 1.5rem;
+padding: 1rem;
+background: var(--secondary-bg, #151b22);
+border-radius: var(--border-radius, .25rem);
+}
+
+.cb-profile__fields {
+display: grid;
+gap: 1.5rem;
+}
+
+.cb-profile__field {
+display: grid;
+grid-template-columns: 1fr;
+gap: 0.5rem;
+}
+
+.cb-profile__field-label {
+font-weight: 600;
+color: var(--heading-color, #f1f5f9);
+}
+
+.cb-profile__field-value {
+color: var(--body-color, #e6ebf1);
+}
+
+/* === Users List View === */
+.cb-userslist-responsive {
+width: 100%;
+}
+
+.cb-userslist__header {
+margin-bottom: 2rem;
+}
+
+.cb-userslist__title {
+font-size: 2rem;
+font-weight: 700;
+margin: 0 0 1.5rem;
+color: var(--heading-color, #f1f5f9);
+}
+
+.cb-userslist__search-form {
+width: 100%;
+}
+
+.cb-userslist__search-wrapper {
+display: flex;
+gap: 0.5rem;
+width: 100%;
+}
+
+.cb-userslist__search-input {
+flex: 1;
+min-height: 48px;
+padding: 0.75rem 1rem;
+border: 1px solid var(--border-color, #2b323b);
+border-radius: var(--border-radius, .25rem);
+font-size: 16px;
+transition: all 0.2s;
+}
+
+.cb-userslist__search-input:focus {
+outline: none;
+border-color: var(--color-primary, #112855);
+box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb), 0.1);
+}
+
+.cb-userslist__search-btn {
+min-height: 48px;
+min-width: 48px;
+padding: 0.75rem 1.5rem;
+display: inline-flex;
+align-items: center;
+justify-content: center;
+gap: 0.5rem;
+flex-shrink: 0;
+}
+
+.cb-userslist__search-text {
+display: none;
+}
+
+.cb-userslist__grid {
+display: grid;
+grid-template-columns: 1fr;
+gap: 1.5rem;
+}
+
+.cb-userslist__user-card {
+background: var(--body-bg, #0e1318);
+border: 1px solid var(--border-color, #2b323b);
+border-radius: var(--border-radius, .25rem);
+padding: 1.5rem;
+transition: all 0.3s;
+display: flex;
+flex-direction: column;
+gap: 1rem;
+}
+
+.cb-userslist__user-card:hover {
+transform: translateY(-2px);
+box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+border-color: var(--color-primary, #112855);
+}
+
+.cb-userslist__avatar {
+width: 80px;
+height: 80px;
+border-radius: 50%;
+overflow: hidden;
+margin: 0 auto;
+}
+
+.cb-userslist__avatar img {
+width: 100%;
+height: 100%;
+object-fit: cover;
+}
+
+.cb-userslist__user-info {
+text-align: center;
+}
+
+.cb-userslist__username {
+font-size: 1.25rem;
+font-weight: 600;
+margin: 0 0 0.5rem;
+}
+
+.cb-userslist__username a {
+color: var(--heading-color, #f1f5f9);
+text-decoration: none;
+}
+
+.cb-userslist__username a:hover {
+color: var(--color-primary, #112855);
+}
+
+.cb-userslist__fields {
+display: grid;
+gap: 0.5rem;
+margin: 1rem 0;
+padding: 1rem;
+background: var(--secondary-bg, #151b22);
+border-radius: var(--border-radius, .25rem);
+}
+
+.cb-userslist__field {
+font-size: 0.875rem;
+}
+
+.cb-userslist__field-label {
+font-weight: 600;
+margin-right: 0.5rem;
+}
+
+.cb-userslist__actions {
+margin-top: 1rem;
+}
+
+.cb-userslist__btn {
+min-height: 44px;
+width: 100%;
+display: inline-flex;
+align-items: center;
+justify-content: center;
+gap: 0.5rem;
+text-decoration: none;
+}
+
+.cb-userslist__pagination {
+margin-top: 2rem;
+display: flex;
+justify-content: center;
+}
+
+/* === Registration View === */
+.cb-register-responsive {
+max-width: 800px;
+margin: 0 auto;
+}
+
+.cb-register__header {
+margin-bottom: 2rem;
+text-align: center;
+}
+
+.cb-register__title {
+font-size: 2rem;
+font-weight: 700;
+margin: 0 0 1rem;
+color: var(--heading-color, #f1f5f9);
+}
+
+.cb-register__intro {
+padding: 1rem;
+background: var(--secondary-bg, #151b22);
+border-radius: var(--border-radius, .25rem);
+margin-bottom: 1.5rem;
+}
+
+.cb-register__form {
+background: var(--body-bg, #0e1318);
+border: 1px solid var(--border-color, #2b323b);
+border-radius: var(--border-radius, .25rem);
+padding: 2rem;
+}
+
+.cb-register__fieldset {
+border: none;
+margin: 0 0 2rem;
+padding: 0;
+}
+
+.cb-register__legend {
+font-size: 1.5rem;
+font-weight: 700;
+color: var(--heading-color, #f1f5f9);
+margin: 0 0 1.5rem;
+padding: 0;
+width: 100%;
+border-bottom: 2px solid var(--border-color, #2b323b);
+padding-bottom: 0.75rem;
+}
+
+.cb-register__tab-description {
+margin-bottom: 1.5rem;
+padding: 1rem;
+background: var(--secondary-bg, #151b22);
+border-radius: var(--border-radius, .25rem);
+}
+
+.cb-register__fields {
+display: grid;
+gap: 1.5rem;
+}
+
+.cb-register__field {
+display: grid;
+gap: 0.5rem;
+}
+
+.cb-register__label {
+font-weight: 600;
+color: var(--heading-color, #f1f5f9);
+display: flex;
+align-items: center;
+gap: 0.25rem;
+}
+
+.cb-register__required {
+color: var(--danger, #c23a31);
+font-weight: 700;
+}
+
+.cb-register__field-description {
+font-size: 0.875rem;
+color: var(--gray-600, #48525d);
+margin-top: 0.25rem;
+}
+
+.cb-register__input-wrapper input[type="text"],
+.cb-register__input-wrapper input[type="email"],
+.cb-register__input-wrapper input[type="password"],
+.cb-register__input-wrapper input[type="tel"],
+.cb-register__input-wrapper input[type="url"],
+.cb-register__input-wrapper select,
+.cb-register__input-wrapper textarea {
+width: 100%;
+min-height: 48px;
+padding: 0.75rem 1rem;
+border: 1px solid var(--border-color, #2b323b);
+border-radius: var(--border-radius, .25rem);
+font-size: 16px;
+transition: all 0.2s;
+}
+
+.cb-register__input-wrapper input:focus,
+.cb-register__input-wrapper select:focus,
+.cb-register__input-wrapper textarea:focus {
+outline: none;
+border-color: var(--color-primary, #112855);
+box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb), 0.1);
+}
+
+.cb-register__field--required .cb-register__input-wrapper input,
+.cb-register__field--required .cb-register__input-wrapper select,
+.cb-register__field--required .cb-register__input-wrapper textarea {
+border-left: 3px solid var(--danger, #c23a31);
+}
+
+.cb-register__error {
+color: var(--danger, #c23a31);
+font-size: 0.875rem;
+margin-top: 0.25rem;
+padding: 0.5rem;
+background: var(--danger-bg);
+border-radius: var(--border-radius, .25rem);
+}
+
+.cb-register__captcha {
+margin: 1.5rem 0;
+padding: 1.5rem;
+background: var(--secondary-bg, #151b22);
+border-radius: var(--border-radius, .25rem);
+}
+
+.cb-register__terms {
+margin: 1.5rem 0;
+padding: 1rem;
+background: var(--secondary-bg, #151b22);
+border-radius: var(--border-radius, .25rem);
+}
+
+.cb-register__terms-checkbox {
+min-width: 20px;
+min-height: 20px;
+cursor: pointer;
+}
+
+.cb-register__terms-label {
+cursor: pointer;
+}
+
+.cb-register__actions {
+display: flex;
+flex-direction: column;
+gap: 1rem;
+margin-top: 2rem;
+}
+
+.cb-register__btn {
+min-height: 48px;
+padding: 0.75rem 1.5rem;
+display: inline-flex;
+align-items: center;
+justify-content: center;
+gap: 0.5rem;
+text-decoration: none;
+border: none;
+cursor: pointer;
+font-weight: 600;
+transition: all 0.2s;
+}
+
+/* === Login View === */
+.cb-login-responsive {
+display: flex;
+align-items: center;
+justify-content: center;
+min-height: 60vh;
+padding: 2rem 1rem;
+}
+
+.cb-login__container {
+width: 100%;
+max-width: 450px;
+background: var(--body-bg, #0e1318);
+border: 1px solid var(--border-color, #2b323b);
+border-radius: var(--border-radius, .25rem);
+padding: 2rem;
+box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+.cb-login__header {
+text-align: center;
+margin-bottom: 2rem;
+}
+
+.cb-login__title {
+font-size: 2rem;
+font-weight: 700;
+margin: 0;
+color: var(--heading-color, #f1f5f9);
+}
+
+.cb-login__form {
+display: grid;
+gap: 1.5rem;
+}
+
+.cb-login__field {
+display: grid;
+gap: 0.5rem;
+}
+
+.cb-login__label {
+font-weight: 600;
+color: var(--heading-color, #f1f5f9);
+display: flex;
+align-items: center;
+gap: 0.25rem;
+}
+
+.cb-login__required {
+color: var(--danger, #c23a31);
+font-weight: 700;
+}
+
+.cb-login__input {
+width: 100%;
+min-height: 48px;
+padding: 0.75rem 1rem;
+border: 1px solid var(--border-color, #2b323b);
+border-radius: var(--border-radius, .25rem);
+font-size: 16px;
+transition: all 0.2s;
+}
+
+.cb-login__input:focus {
+outline: none;
+border-color: var(--color-primary, #112855);
+box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb), 0.1);
+}
+
+.cb-login__remember {
+margin: 0.5rem 0;
+}
+
+.cb-login__remember-checkbox {
+min-width: 20px;
+min-height: 20px;
+cursor: pointer;
+}
+
+.cb-login__remember-label {
+cursor: pointer;
+}
+
+.cb-login__actions {
+margin-top: 1rem;
+}
+
+.cb-login__btn {
+width: 100%;
+min-height: 48px;
+padding: 0.75rem 1.5rem;
+display: inline-flex;
+align-items: center;
+justify-content: center;
+gap: 0.5rem;
+text-decoration: none;
+border: none;
+cursor: pointer;
+font-weight: 600;
+transition: all 0.2s;
+}
+
+.cb-login__links {
+margin-top: 2rem;
+padding-top: 2rem;
+border-top: 1px solid var(--border-color, #2b323b);
+display: flex;
+flex-direction: column;
+gap: 1rem;
+}
+
+.cb-login__link {
+text-align: center;
+}
+
+.cb-login__link-item {
+display: inline-flex;
+align-items: center;
+justify-content: center;
+gap: 0.5rem;
+color: var(--link-color, #8ab4f8);
+text-decoration: none;
+min-height: 44px;
+padding: 0.5rem;
+transition: all 0.2s;
+}
+
+.cb-login__link-item:hover {
+color: var(--color-primary, #112855);
+}
+
+/* === Responsive Design === */
+@media (min-width: 576px) {
+.cb-userslist__search-text {
+display: inline;
+}
+
+.cb-profile__field {
+grid-template-columns: 200px 1fr;
+}
+
+.cb-register__actions {
+flex-direction: row;
+justify-content: flex-end;
+}
+
+.cb-register__btn--cancel {
+order: -1;
+}
+}
+
+@media (min-width: 768px) {
+.cb-profile__header {
+flex-direction: row;
+text-align: left;
+}
+
+.cb-profile__header-info {
+text-align: left;
+}
+
+.cb-userslist__grid {
+grid-template-columns: repeat(2, 1fr);
+}
+
+.cb-userslist__user-card {
+flex-direction: row;
+align-items: center;
+}
+
+.cb-userslist__avatar {
+margin: 0;
+}
+
+.cb-userslist__user-info {
+text-align: left;
+flex: 1;
+}
+
+.cb-login__container {
+padding: 3rem;
+}
+}
+
+@media (min-width: 992px) {
+.cb-userslist__grid {
+grid-template-columns: repeat(3, 1fr);
+}
+
+.cb-userslist__user-card {
+flex-direction: column;
+text-align: center;
+}
+
+.cb-userslist__avatar {
+margin: 0 auto;
+}
+
+.cb-userslist__user-info {
+text-align: center;
+}
+
+.cb-profile__tabs-nav {
+flex-wrap: nowrap;
+}
+}
+
+@media (max-width: 575.98px) {
+.cb-login__input,
+.cb-register__input-wrapper input[type="text"],
+.cb-register__input-wrapper input[type="email"],
+.cb-register__input-wrapper input[type="password"],
+.cb-register__input-wrapper input[type="tel"],
+.cb-register__input-wrapper input[type="url"],
+.cb-register__input-wrapper select,
+.cb-userslist__search-input {
+font-size: 16px;
+min-height: 48px;
+}
+
+.cb-login__btn,
+.cb-register__btn,
+.cb-userslist__btn,
+.cb-userslist__search-btn {
+min-height: 48px;
+}
+
+.cb-profile__avatar {
+width: 120px;
+height: 120px;
+}
+
+.cb-register__form,
+.cb-login__container {
+padding: 1.5rem;
+}
+}
+
+/*
+ JEM (JOOMLA EVENT MANAGER) COMPONENT STYLES
+ Mobile-responsive overrides for JEM event management component
+ Includes: Events List, Event Details, Calendar, Venue, Categories
+*/
+
+/* ===========================
+ JEM Events List Styles
+ =========================== */
+
+.jem-eventslist-responsive {
+width: 100%;
+max-width: 100%;
+}
+
+.jem-eventslist__container {
+padding: 1rem;
+}
+
+.jem-eventslist__header {
+margin-bottom: 1.5rem;
+}
+
+.jem-eventslist__title {
+font-size: 1.75rem;
+font-weight: 700;
+margin: 0;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-eventslist__list {
+display: flex;
+flex-direction: column;
+gap: 1.5rem;
+}
+
+.jem-eventslist__item {
+background: var(--secondary-bg, #f8f9fa);
+border: 1px solid var(--border-color, #dee2e6);
+border-radius: var(--border-radius, 0.375rem);
+overflow: hidden;
+transition: box-shadow 0.3s ease;
+}
+
+.jem-eventslist__item:hover {
+box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+}
+
+.jem-eventslist__item-inner {
+padding: 1.25rem;
+}
+
+.jem-eventslist__date {
+font-size: 0.875rem;
+color: var(--secondary-color, #6c757d);
+margin-bottom: 0.5rem;
+display: flex;
+align-items: center;
+flex-wrap: wrap;
+gap: 0.25rem;
+}
+
+.jem-eventslist__datetime {
+font-weight: 500;
+}
+
+.jem-eventslist__date-separator {
+margin: 0 0.25rem;
+}
+
+.jem-eventslist__event-title {
+font-size: 1.25rem;
+font-weight: 600;
+margin: 0.5rem 0;
+}
+
+.jem-eventslist__link {
+color: var(--link-color, #8ab4f8);
+text-decoration: none;
+transition: color 0.2s ease;
+}
+
+.jem-eventslist__link:hover {
+color: var(--link-hover-color, #c3d6ff);
+text-decoration: underline;
+}
+
+.jem-eventslist__venue {
+display: flex;
+align-items: center;
+gap: 0.5rem;
+margin: 0.75rem 0;
+font-size: 0.9375rem;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-eventslist__venue-icon {
+font-size: 1rem;
+}
+
+.jem-eventslist__venue-link {
+color: var(--link-color, #8ab4f8);
+text-decoration: none;
+}
+
+.jem-eventslist__venue-link:hover {
+text-decoration: underline;
+}
+
+.jem-eventslist__description {
+margin: 1rem 0;
+color: var(--body-color, #e6ebf1);
+line-height: 1.6;
+}
+
+.jem-eventslist__categories {
+display: flex;
+flex-wrap: wrap;
+gap: 0.5rem;
+margin: 1rem 0;
+}
+
+.jem-eventslist__category-badge {
+display: inline-block;
+padding: 0.25rem 0.75rem;
+background: var(--primary-color, #007bff);
+color: var(--white, #fff);
+border-radius: 1rem;
+font-size: 0.8125rem;
+font-weight: 500;
+}
+
+.jem-eventslist__actions {
+margin-top: 1rem;
+}
+
+.jem-eventslist__button {
+display: inline-block;
+padding: 0.625rem 1.25rem;
+min-height: 44px;
+background: var(--btn-primary-bg, #007bff);
+color: var(--white, #fff);
+border: none;
+border-radius: var(--border-radius, 0.375rem);
+text-decoration: none;
+font-weight: 500;
+text-align: center;
+transition: background-color 0.2s ease;
+cursor: pointer;
+}
+
+.jem-eventslist__button:hover {
+background: var(--btn-primary-hover-bg, #0056b3);
+color: var(--white, #fff);
+text-decoration: none;
+}
+
+.jem-eventslist__pagination {
+margin-top: 2rem;
+text-align: center;
+}
+
+.jem-eventslist__empty {
+padding: 3rem 1rem;
+text-align: center;
+}
+
+.jem-eventslist__empty-message {
+font-size: 1.125rem;
+color: var(--secondary-color, #6c757d);
+}
+
+/* ===========================
+ JEM Event Details Styles
+ =========================== */
+
+.jem-event-responsive {
+width: 100%;
+max-width: 100%;
+}
+
+.jem-event__container {
+padding: 1rem;
+}
+
+.jem-event__header {
+margin-bottom: 1.5rem;
+}
+
+.jem-event__title {
+font-size: 2rem;
+font-weight: 700;
+margin: 0;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-event__image-wrapper {
+margin: 1.5rem 0;
+border-radius: var(--border-radius, 0.375rem);
+overflow: hidden;
+}
+
+.jem-event__image {
+width: 100%;
+height: auto;
+display: block;
+}
+
+.jem-event__meta {
+background: var(--secondary-bg, #f8f9fa);
+border: 1px solid var(--border-color, #dee2e6);
+border-radius: var(--border-radius, 0.375rem);
+padding: 1.5rem;
+margin: 1.5rem 0;
+}
+
+.jem-event__meta-item {
+display: flex;
+align-items: flex-start;
+gap: 0.75rem;
+margin-bottom: 1rem;
+}
+
+.jem-event__meta-item:last-child {
+margin-bottom: 0;
+}
+
+.jem-event__meta-icon {
+font-size: 1.25rem;
+flex-shrink: 0;
+margin-top: 0.125rem;
+}
+
+.jem-event__meta-content {
+flex: 1;
+}
+
+.jem-event__meta-label {
+display: block;
+margin-bottom: 0.25rem;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-event__datetime,
+.jem-event__time-value,
+.jem-event__venue-name {
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-event__venue-link {
+color: var(--link-color, #8ab4f8);
+text-decoration: none;
+font-weight: 500;
+}
+
+.jem-event__venue-link:hover {
+color: var(--link-hover-color, #c3d6ff);
+text-decoration: underline;
+}
+
+.jem-event__address {
+margin-top: 0.5rem;
+font-size: 0.9375rem;
+color: var(--secondary-color, #6c757d);
+}
+
+.jem-event__street,
+.jem-event__city {
+display: block;
+}
+
+.jem-event__category-list {
+display: flex;
+flex-wrap: wrap;
+gap: 0.5rem;
+margin-top: 0.5rem;
+}
+
+.jem-event__category-badge {
+display: inline-block;
+padding: 0.25rem 0.75rem;
+background: var(--primary-color, #007bff);
+color: var(--white, #fff);
+border-radius: 1rem;
+font-size: 0.8125rem;
+font-weight: 500;
+}
+
+.jem-event__description {
+margin: 2rem 0;
+}
+
+.jem-event__description-title {
+font-size: 1.5rem;
+font-weight: 600;
+margin-bottom: 1rem;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-event__description-content {
+line-height: 1.8;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-event__registration,
+.jem-event__contact {
+background: var(--secondary-bg, #f8f9fa);
+border: 1px solid var(--border-color, #dee2e6);
+border-radius: var(--border-radius, 0.375rem);
+padding: 1.5rem;
+margin: 1.5rem 0;
+}
+
+.jem-event__registration-title,
+.jem-event__contact-title {
+font-size: 1.25rem;
+font-weight: 600;
+margin-bottom: 1rem;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-event__contact-link {
+color: var(--link-color, #8ab4f8);
+text-decoration: none;
+}
+
+.jem-event__contact-link:hover {
+text-decoration: underline;
+}
+
+.jem-event__actions {
+margin-top: 2rem;
+}
+
+.jem-event__button {
+display: inline-block;
+padding: 0.625rem 1.25rem;
+min-height: 44px;
+background: var(--btn-secondary-bg, #6c757d);
+color: var(--white, #fff);
+border: none;
+border-radius: var(--border-radius, 0.375rem);
+text-decoration: none;
+font-weight: 500;
+text-align: center;
+transition: background-color 0.2s ease;
+cursor: pointer;
+}
+
+.jem-event__button:hover {
+background: var(--btn-secondary-hover-bg, #5a6268);
+color: var(--white, #fff);
+text-decoration: none;
+}
+
+/* ===========================
+ JEM Calendar Styles
+ =========================== */
+
+.jem-calendar-responsive {
+width: 100%;
+max-width: 100%;
+}
+
+.jem-calendar__container {
+padding: 1rem;
+}
+
+.jem-calendar__header {
+margin-bottom: 1.5rem;
+}
+
+.jem-calendar__title {
+font-size: 1.75rem;
+font-weight: 700;
+margin: 0;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-calendar__navigation {
+display: flex;
+justify-content: space-between;
+align-items: center;
+margin-bottom: 1.5rem;
+padding: 1rem;
+background: var(--secondary-bg, #f8f9fa);
+border-radius: var(--border-radius, 0.375rem);
+}
+
+.jem-calendar__nav-button {
+display: flex;
+align-items: center;
+justify-content: center;
+width: 44px;
+height: 44px;
+background: var(--btn-primary-bg, #007bff);
+color: var(--white, #fff);
+border: none;
+border-radius: 50%;
+text-decoration: none;
+font-size: 1.5rem;
+transition: background-color 0.2s ease;
+}
+
+.jem-calendar__nav-button:hover {
+background: var(--btn-primary-hover-bg, #0056b3);
+color: var(--white, #fff);
+}
+
+.jem-calendar__current-month {
+font-size: 1.25rem;
+font-weight: 600;
+margin: 0;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-calendar__grid {
+background: var(--secondary-bg, #f8f9fa);
+border: 1px solid var(--border-color, #dee2e6);
+border-radius: var(--border-radius, 0.375rem);
+padding: 1rem;
+margin-bottom: 2rem;
+}
+
+.jem-calendar__weekdays {
+display: grid;
+grid-template-columns: repeat(7, 1fr);
+gap: 0.5rem;
+margin-bottom: 0.5rem;
+}
+
+.jem-calendar__weekday {
+text-align: center;
+font-weight: 600;
+font-size: 0.875rem;
+color: var(--body-color, #e6ebf1);
+padding: 0.5rem 0;
+}
+
+.jem-calendar__days {
+display: grid;
+grid-template-columns: repeat(7, 1fr);
+gap: 0.5rem;
+}
+
+.jem-calendar__day {
+aspect-ratio: 1;
+display: flex;
+flex-direction: column;
+align-items: center;
+justify-content: center;
+padding: 0.5rem;
+background: var(--white, #fff);
+border: 1px solid var(--border-color, #dee2e6);
+border-radius: var(--border-radius, 0.375rem);
+cursor: pointer;
+transition: background-color 0.2s ease;
+}
+
+.jem-calendar__day:hover {
+background: var(--hover-bg, #e9ecef);
+}
+
+.jem-calendar__day--empty {
+background: transparent;
+border: none;
+cursor: default;
+}
+
+.jem-calendar__day--has-events {
+background: var(--primary-light, #cfe2ff);
+border-color: var(--primary-color, #007bff);
+}
+
+.jem-calendar__day--today {
+border: 2px solid var(--primary-color, #007bff);
+font-weight: 700;
+}
+
+.jem-calendar__day-number {
+font-size: 0.9375rem;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-calendar__event-indicator {
+display: inline-flex;
+align-items: center;
+justify-content: center;
+min-width: 1.25rem;
+height: 1.25rem;
+background: var(--primary-color, #007bff);
+color: var(--white, #fff);
+border-radius: 50%;
+font-size: 0.6875rem;
+font-weight: 600;
+margin-top: 0.25rem;
+}
+
+.jem-calendar__events-list {
+margin-top: 2rem;
+}
+
+.jem-calendar__events-title {
+font-size: 1.5rem;
+font-weight: 600;
+margin-bottom: 1rem;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-calendar__events {
+display: flex;
+flex-direction: column;
+gap: 1rem;
+}
+
+.jem-calendar__event-item {
+padding: 1rem;
+background: var(--secondary-bg, #f8f9fa);
+border: 1px solid var(--border-color, #dee2e6);
+border-radius: var(--border-radius, 0.375rem);
+}
+
+.jem-calendar__event-date {
+font-size: 0.875rem;
+color: var(--secondary-color, #6c757d);
+margin-bottom: 0.5rem;
+}
+
+.jem-calendar__event-title {
+font-size: 1.125rem;
+font-weight: 600;
+margin: 0.5rem 0;
+}
+
+.jem-calendar__event-link {
+color: var(--link-color, #8ab4f8);
+text-decoration: none;
+}
+
+.jem-calendar__event-link:hover {
+color: var(--link-hover-color, #c3d6ff);
+text-decoration: underline;
+}
+
+.jem-calendar__event-venue {
+font-size: 0.9375rem;
+color: var(--body-color, #e6ebf1);
+margin-top: 0.5rem;
+}
+
+/* ===========================
+ JEM Venue Styles
+ =========================== */
+
+.jem-venue-responsive {
+width: 100%;
+max-width: 100%;
+}
+
+.jem-venue__container {
+padding: 1rem;
+}
+
+.jem-venue__header {
+margin-bottom: 1.5rem;
+}
+
+.jem-venue__title {
+font-size: 2rem;
+font-weight: 700;
+margin: 0;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-venue__image-wrapper {
+margin: 1.5rem 0;
+border-radius: var(--border-radius, 0.375rem);
+overflow: hidden;
+}
+
+.jem-venue__image {
+width: 100%;
+height: auto;
+display: block;
+}
+
+.jem-venue__info {
+margin: 2rem 0;
+}
+
+.jem-venue__info-item {
+display: flex;
+align-items: flex-start;
+gap: 0.75rem;
+margin-bottom: 1.5rem;
+padding: 1.25rem;
+background: var(--secondary-bg, #f8f9fa);
+border: 1px solid var(--border-color, #dee2e6);
+border-radius: var(--border-radius, 0.375rem);
+}
+
+.jem-venue__info-item:last-child {
+margin-bottom: 0;
+}
+
+.jem-venue__info-icon {
+font-size: 1.25rem;
+flex-shrink: 0;
+margin-top: 0.125rem;
+}
+
+.jem-venue__info-content {
+flex: 1;
+}
+
+.jem-venue__info-label {
+display: block;
+margin-bottom: 0.5rem;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-venue__address-content {
+font-style: normal;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-venue__street,
+.jem-venue__city-line,
+.jem-venue__state,
+.jem-venue__country {
+display: block;
+margin-bottom: 0.25rem;
+}
+
+.jem-venue__link {
+color: var(--link-color, #8ab4f8);
+text-decoration: none;
+word-break: break-all;
+}
+
+.jem-venue__link:hover {
+text-decoration: underline;
+}
+
+.jem-venue__description {
+margin: 2rem 0;
+}
+
+.jem-venue__description-title {
+font-size: 1.5rem;
+font-weight: 600;
+margin-bottom: 1rem;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-venue__description-content {
+line-height: 1.8;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-venue__map {
+margin: 2rem 0;
+}
+
+.jem-venue__map-title {
+font-size: 1.5rem;
+font-weight: 600;
+margin-bottom: 1rem;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-venue__map-container {
+border-radius: var(--border-radius, 0.375rem);
+overflow: hidden;
+}
+
+.jem-venue__map-placeholder {
+padding: 3rem 1rem;
+background: var(--secondary-bg, #f8f9fa);
+border: 1px solid var(--border-color, #dee2e6);
+text-align: center;
+}
+
+.jem-venue__map-link {
+display: inline-block;
+padding: 0.625rem 1.25rem;
+min-height: 44px;
+background: var(--btn-primary-bg, #007bff);
+color: var(--white, #fff);
+border: none;
+border-radius: var(--border-radius, 0.375rem);
+text-decoration: none;
+font-weight: 500;
+margin-top: 1rem;
+transition: background-color 0.2s ease;
+}
+
+.jem-venue__map-link:hover {
+background: var(--btn-primary-hover-bg, #0056b3);
+color: var(--white, #fff);
+text-decoration: none;
+}
+
+.jem-venue__events {
+margin: 2rem 0;
+}
+
+.jem-venue__events-title {
+font-size: 1.5rem;
+font-weight: 600;
+margin-bottom: 1rem;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-venue__events-list {
+display: flex;
+flex-direction: column;
+gap: 1rem;
+}
+
+.jem-venue__event-item {
+padding: 1rem;
+background: var(--secondary-bg, #f8f9fa);
+border: 1px solid var(--border-color, #dee2e6);
+border-radius: var(--border-radius, 0.375rem);
+}
+
+.jem-venue__event-date {
+font-size: 0.875rem;
+color: var(--secondary-color, #6c757d);
+margin-bottom: 0.5rem;
+}
+
+.jem-venue__event-title {
+font-size: 1.125rem;
+font-weight: 600;
+margin: 0.5rem 0;
+}
+
+.jem-venue__event-link {
+color: var(--link-color, #8ab4f8);
+text-decoration: none;
+}
+
+.jem-venue__event-link:hover {
+color: var(--link-hover-color, #c3d6ff);
+text-decoration: underline;
+}
+
+.jem-venue__actions {
+margin-top: 2rem;
+}
+
+.jem-venue__button {
+display: inline-block;
+padding: 0.625rem 1.25rem;
+min-height: 44px;
+background: var(--btn-secondary-bg, #6c757d);
+color: var(--white, #fff);
+border: none;
+border-radius: var(--border-radius, 0.375rem);
+text-decoration: none;
+font-weight: 500;
+text-align: center;
+transition: background-color 0.2s ease;
+cursor: pointer;
+}
+
+.jem-venue__button:hover {
+background: var(--btn-secondary-hover-bg, #5a6268);
+color: var(--white, #fff);
+text-decoration: none;
+}
+
+/* ===========================
+ JEM Categories Styles
+ =========================== */
+
+.jem-categories-responsive {
+width: 100%;
+max-width: 100%;
+}
+
+.jem-categories__container {
+padding: 1rem;
+}
+
+.jem-categories__header {
+margin-bottom: 1.5rem;
+}
+
+.jem-categories__title {
+font-size: 1.75rem;
+font-weight: 700;
+margin: 0;
+color: var(--body-color, #e6ebf1);
+}
+
+.jem-categories__list {
+display: flex;
+flex-direction: column;
+gap: 1.5rem;
+}
+
+.jem-categories__item {
+background: var(--secondary-bg, #f8f9fa);
+border: 1px solid var(--border-color, #dee2e6);
+border-radius: var(--border-radius, 0.375rem);
+overflow: hidden;
+transition: box-shadow 0.3s ease;
+}
+
+.jem-categories__item:hover {
+box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+}
+
+.jem-categories__item-inner {
+padding: 1.25rem;
+}
+
+.jem-categories__image-wrapper {
+margin-bottom: 1rem;
+border-radius: var(--border-radius, 0.375rem);
+overflow: hidden;
+}
+
+.jem-categories__image {
+width: 100%;
+height: auto;
+display: block;
+}
+
+.jem-categories__category-title {
+font-size: 1.25rem;
+font-weight: 600;
+margin: 0.5rem 0;
+}
+
+.jem-categories__link {
+color: var(--link-color, #8ab4f8);
+text-decoration: none;
+transition: color 0.2s ease;
+}
+
+.jem-categories__link:hover {
+color: var(--link-hover-color, #c3d6ff);
+text-decoration: underline;
+}
+
+.jem-categories__description {
+margin: 1rem 0;
+color: var(--body-color, #e6ebf1);
+line-height: 1.6;
+}
+
+.jem-categories__meta {
+margin: 0.75rem 0;
+font-size: 0.875rem;
+color: var(--secondary-color, #6c757d);
+}
+
+.jem-categories__event-count {
+font-weight: 500;
+}
+
+.jem-categories__actions {
+margin-top: 1rem;
+}
+
+.jem-categories__button {
+display: inline-block;
+padding: 0.625rem 1.25rem;
+min-height: 44px;
+background: var(--btn-primary-bg, #007bff);
+color: var(--white, #fff);
+border: none;
+border-radius: var(--border-radius, 0.375rem);
+text-decoration: none;
+font-weight: 500;
+text-align: center;
+transition: background-color 0.2s ease;
+cursor: pointer;
+}
+
+.jem-categories__button:hover {
+background: var(--btn-primary-hover-bg, #0056b3);
+color: var(--white, #fff);
+text-decoration: none;
+}
+
+.jem-categories__pagination {
+margin-top: 2rem;
+text-align: center;
+}
+
+.jem-categories__empty {
+padding: 3rem 1rem;
+text-align: center;
+}
+
+.jem-categories__empty-message {
+font-size: 1.125rem;
+color: var(--secondary-color, #6c757d);
+}
+
+/* ===========================
+ JEM Responsive Styles
+ =========================== */
+
+@media (min-width: 768px) {
+.jem-eventslist__list,
+.jem-categories__list {
+display: grid;
+grid-template-columns: repeat(2, 1fr);
+gap: 1.5rem;
+}
+
+.jem-calendar__day-number {
+font-size: 1rem;
+}
+
+.jem-event__meta {
+padding: 2rem;
+}
+
+.jem-venue__info-item {
+padding: 1.5rem;
+}
+}
+
+@media (min-width: 992px) {
+.jem-eventslist__container,
+.jem-event__container,
+.jem-calendar__container,
+.jem-venue__container,
+.jem-categories__container {
+padding: 2rem;
+}
+
+.jem-eventslist__title,
+.jem-calendar__title,
+.jem-categories__title {
+font-size: 2rem;
+}
+
+.jem-event__title,
+.jem-venue__title {
+font-size: 2.5rem;
+}
+
+.jem-calendar__grid {
+padding: 1.5rem;
+}
+}
+
+@media (max-width: 575.98px) {
+.jem-eventslist__button,
+.jem-event__button,
+.jem-calendar__nav-button,
+.jem-venue__button,
+.jem-venue__map-link,
+.jem-categories__button {
+min-height: 48px;
+}
+
+.jem-eventslist__item-inner,
+.jem-event__meta,
+.jem-venue__info-item,
+.jem-categories__item-inner {
+padding: 1rem;
+}
+
+.jem-calendar__navigation {
+padding: 0.75rem;
+}
+
+.jem-calendar__current-month {
+font-size: 1rem;
+}
+
+.jem-calendar__weekday {
+font-size: 0.75rem;
+padding: 0.25rem 0;
+}
+
+.jem-calendar__day {
+padding: 0.25rem;
+}
+
+.jem-calendar__day-number {
+font-size: 0.8125rem;
+}
+}
diff --git a/src/media/css/template.min.css b/src/media/css/template.min.css
new file mode 100644
index 0000000..695e8c1
--- /dev/null
+++ b/src/media/css/template.min.css
@@ -0,0 +1 @@
+@charset "UTF-8";*,::after,::before{-webkit-box-sizing:border-box;box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}.container-main,.container-wrapper,:root,body,footer,header,nav{transition:background-color .3s,color .3s,border-color .3s}}@media print{#lhc_container_v2 *,#rssocial-133,.container-bottom-a,.container-bottom-b,.container-nav,.container-sidebar-left,.container-sidebar-right,.container-topbar,.fb-comments,footer,nav{display:none}}body{margin:0;font-family:var(--body-font-family);font-size:var(--body-font-size);font-weight:var(--body-font-weight);line-height:var(--body-line-height);color:var(--body-color);text-align:var(--body-text-align);background:var(--body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}form{margin-block-end:1em}.table-of-contents-ck-wrap{width:30%;float:right;border:1px solid var(--color-primary)}.table-of-contents-ck-toggler{font-size:2em;font-weight:700;background-color:var(--gray-500);padding:var(--btn-padding-y) var(--btn-padding-x);color:var(--color-link);text-align:center}.table-of-contents-ck-toggler a{font-size:.5em;font-weight:400;color:var(--color-link);display:block;text-align:center}.table-of-contents-ck,.table-of-contents-ck a{font-size:1.25em;color:var(--color-link)}.offcanvas-end,.offcanvas-start{width:280px}.drawer-toggle-left{position:fixed!important;top:250px!important;left:0!important;z-index:1050!important;background-color:var(--nav-bg-color)!important;color:var(--nav-text-color)!important;padding-left:.5rem!important;padding-right:.5rem!important}.drawer-toggle-right{position:fixed!important;top:250px!important;right:0!important;z-index:1050!important;background-color:var(--nav-bg-color)!important;color:var(--nav-text-color)!important;padding-left:.5rem!important;padding-right:.5rem!important}hr{margin:1rem 0;color:inherit;border:0;border-top:1px solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}dl,ol,p,ul{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.mark,mark{padding:.1875em;background-color:var(--highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:var(--link-color);text-decoration:underline;color:var(--color-link)}a:active{color:var(--link-active-color)}a:not([href]):not([class]),a:not([href]):not([class]):active{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--code-color);word-wrap:break-word;background-color:var(--gab-gray1)}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--body-bg);background-color:var(--body-color);border-radius:.2rem}kbd kbd{padding:0;font-size:1em}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6d757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border:0 solid;border-color:inherit}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button],[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0 0 2em;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none}.lead{font-size:1.25rem;font-weight:300}.display-1{font-weight:300;line-height:1.2}.display-2{font-weight:300;line-height:1.2}.display-3{font-weight:300;line-height:1.2}.display-4{font-weight:300;line-height:1.2}@media (min-width:1200px){legend{font-size:1.5rem}.display-1{font-size:5rem}.display-2{font-size:4.5rem}.display-3{font-size:4rem}.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-inline,.list-unstyled{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6d757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:var(--body-color);border:1px solid var(--border-color);border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6d757d}.container,.container-component,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--gutter-x:1em;--gutter-y:0;width:100%;padding-right:calc(var(--gutter-x) * .5);padding-left:calc(var(--gutter-x) * .5);margin-right:auto;margin-left:auto;padding-bottom:calc(var(--gutter-x) * .5)}.featured-view,.latest-view,.products-view,.recent-view,.topten-view{border-top:var(--accent-color-primary) 1px groove}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--gutter-x:1em;--gutter-y:0;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(-1 * var(--gutter-y));margin-right:calc(-.5 * var(--gutter-x));margin-left:calc(-.5 * var(--gutter-x))}.row>*{-ms-flex-negative:0;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(.25 * var(--gutter-x));padding-left:calc(.25 * var(--gutter-x))}.latest-view{margin-top:var(--gutter-x)}.col{-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%}.row-cols-auto>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.row-cols-1>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.row-cols-2>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.row-cols-3>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.row-cols-5>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:20%}.row-cols-6>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.col-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-1{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:8.33333333%}.col-2{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:16.66666667%}.col-3{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.col-4{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:33.33333333%}.col-5{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:41.66666667%}.col-6{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.col-7{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:58.33333333%}.col-8{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:66.66666667%}.col-9{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.col-10{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:83.33333333%}.col-11{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:91.66666667%}.col-12{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--gutter-x:0}.g-0,.gy-0{--gutter-y:0}.g-1,.gx-1{--gutter-x:0.25rem}.g-1,.gy-1{--gutter-y:0.25rem}.g-2,.gx-2{--gutter-x:0.5rem}.g-2,.gy-2{--gutter-y:0.5rem}.g-3,.gx-3{--gutter-x:1rem}.g-3,.gy-3{--gutter-y:1rem}.g-4,.gx-4{--gutter-x:1.5rem}.g-4,.gy-4{--gutter-y:1.5rem}.g-5,.gx-5{--gutter-x:3rem}.g-5,.gy-5{--gutter-y:3rem}@media (min-width:576px){.col-sm{-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%}.row-cols-sm-auto>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.row-cols-sm-1>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.row-cols-sm-2>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.row-cols-sm-3>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.row-cols-sm-5>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:20%}.row-cols-sm-6>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.col-sm-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-sm-1{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:8.33333333%}.col-sm-2{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:16.66666667%}.col-sm-3{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.col-sm-4{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:33.33333333%}.col-sm-5{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:41.66666667%}.col-sm-6{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.col-sm-7{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:58.33333333%}.col-sm-8{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:66.66666667%}.col-sm-9{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.col-sm-10{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:83.33333333%}.col-sm-11{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:91.66666667%}.col-sm-12{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--gutter-x:0}.g-sm-0,.gy-sm-0{--gutter-y:0}.g-sm-1,.gx-sm-1{--gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--gutter-x:1rem}.g-sm-3,.gy-sm-3{--gutter-y:1rem}.g-sm-4,.gx-sm-4{--gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--gutter-x:3rem}.g-sm-5,.gy-sm-5{--gutter-y:3rem}}@media (min-width:768px){.col-md{-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%}.row-cols-md-auto>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.row-cols-md-1>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.row-cols-md-2>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.row-cols-md-3>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.row-cols-md-5>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:20%}.row-cols-md-6>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.col-md-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-md-1{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:8.33333333%}.col-md-2{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:16.66666667%}.col-md-3{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.col-md-4{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:33.33333333%}.col-md-5{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:41.66666667%}.col-md-6{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.col-md-7{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:58.33333333%}.col-md-8{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:66.66666667%}.col-md-9{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.col-md-10{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:83.33333333%}.col-md-11{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:91.66666667%}.col-md-12{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--gutter-x:0}.g-md-0,.gy-md-0{--gutter-y:0}.g-md-1,.gx-md-1{--gutter-x:0.25rem}.g-md-1,.gy-md-1{--gutter-y:0.25rem}.g-md-2,.gx-md-2{--gutter-x:0.5rem}.g-md-2,.gy-md-2{--gutter-y:0.5rem}.g-md-3,.gx-md-3{--gutter-x:1rem}.g-md-3,.gy-md-3{--gutter-y:1rem}.g-md-4,.gx-md-4{--gutter-x:1.5rem}.g-md-4,.gy-md-4{--gutter-y:1.5rem}.g-md-5,.gx-md-5{--gutter-x:3rem}.g-md-5,.gy-md-5{--gutter-y:3rem}}@media (min-width:992px){.col-lg{-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%}.row-cols-lg-auto>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.row-cols-lg-1>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.row-cols-lg-2>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.row-cols-lg-3>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.row-cols-lg-5>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:20%}.row-cols-lg-6>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.col-lg-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-lg-1{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:8.33333333%}.col-lg-2{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:16.66666667%}.col-lg-3{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.col-lg-4{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:33.33333333%}.col-lg-5{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:41.66666667%}.col-lg-6{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.col-lg-7{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:58.33333333%}.col-lg-8{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:66.66666667%}.col-lg-9{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.col-lg-10{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:83.33333333%}.col-lg-11{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:91.66666667%}.col-lg-12{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--gutter-x:0}.g-lg-0,.gy-lg-0{--gutter-y:0}.g-lg-1,.gx-lg-1{--gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--gutter-x:1rem}.g-lg-3,.gy-lg-3{--gutter-y:1rem}.g-lg-4,.gx-lg-4{--gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--gutter-x:3rem}.g-lg-5,.gy-lg-5{--gutter-y:3rem}}@media (min-width:1200px){.col-xl{-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%}.row-cols-xl-auto>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.row-cols-xl-1>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.row-cols-xl-2>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.row-cols-xl-3>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.row-cols-xl-5>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:20%}.row-cols-xl-6>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.col-xl-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-xl-1{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:8.33333333%}.col-xl-2{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:16.66666667%}.col-xl-3{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.col-xl-4{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:33.33333333%}.col-xl-5{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:41.66666667%}.col-xl-6{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.col-xl-7{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:58.33333333%}.col-xl-8{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:66.66666667%}.col-xl-9{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.col-xl-10{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:83.33333333%}.col-xl-11{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:91.66666667%}.col-xl-12{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--gutter-x:0}.g-xl-0,.gy-xl-0{--gutter-y:0}.g-xl-1,.gx-xl-1{--gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--gutter-x:1rem}.g-xl-3,.gy-xl-3{--gutter-y:1rem}.g-xl-4,.gx-xl-4{--gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--gutter-x:3rem}.g-xl-5,.gy-xl-5{--gutter-y:3rem}}@media (min-width:1400px){.col-xxl{-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%}.row-cols-xxl-auto>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.row-cols-xxl-1>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.row-cols-xxl-2>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.row-cols-xxl-3>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.row-cols-xxl-5>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:20%}.row-cols-xxl-6>*{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.col-xxl-1{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:8.33333333%}.col-xxl-2{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:16.66666667%}.col-xxl-3{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.col-xxl-4{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:33.33333333%}.col-xxl-5{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:41.66666667%}.col-xxl-6{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.col-xxl-7{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:58.33333333%}.col-xxl-8{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:66.66666667%}.col-xxl-9{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.col-xxl-10{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:83.33333333%}.col-xxl-11{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:91.66666667%}.col-xxl-12{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--gutter-x:0}.g-xxl-0,.gy-xxl-0{--gutter-y:0}.g-xxl-1,.gx-xxl-1{--gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--gutter-y:3rem}}.table{width:100%;margin-bottom:1rem;color:var(--table-color);vertical-align:top;border-color:var(--table-border-color)}.table>:not(caption)>*>*{padding:.5rem;background-color:var(--table-bg);border-bottom-width:1px;-webkit-box-shadow:inset 0 0 0 9999px var(--table-accent-bg);box-shadow:inset 0 0 0 9999px var(--table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:2px solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped-columns>:not(caption)>tr>:nth-child(2n),.table-striped>tbody>tr:nth-of-type(odd)>*{--table-accent-bg:var(--table-striped-bg);color:var(--table-striped-color)}.table-active,.table-active>tbody>tr:active>*{--table-accent-bg:var(--table-active-bg);color:var(--table-active-color)}.table-primary{--table-color:hsl(0, 0%, 0%);--table-bg:#cfd4dd;--table-border-color:#babfc7;--table-striped-bg:#c5c9d2;--table-striped-color:hsl(0, 0%, 0%);--table-active-bg:#babfc7;--table-active-color:hsl(0, 0%, 0%);--table-active-bg:#bfc4cc;--table-active-color:hsl(0, 0%, 0%);color:var(--table-color);border-color:var(--table-border-color)}.table-secondary{--table-color:hsl(0, 0%, 0%);--table-bg:#e2e3e5;--table-border-color:#cbccce;--table-striped-bg:#d7d8da;--table-striped-color:hsl(0, 0%, 0%);--table-active-bg:#cbccce;--table-active-color:hsl(0, 0%, 0%);--table-active-bg:#d1d2d4;--table-active-color:hsl(0, 0%, 0%);color:var(--table-color);border-color:var(--table-border-color)}.table-success{--table-color:hsl(0, 0%, 0%);--table-bg:#dae6da;--table-border-color:#c4cfc4;--table-striped-bg:#cfdbcf;--table-striped-color:hsl(0, 0%, 0%);--table-active-bg:#c4cfc4;--table-active-color:hsl(0, 0%, 0%);--table-active-bg:#cad5ca;--table-active-color:hsl(0, 0%, 0%);color:var(--table-color);border-color:var(--table-border-color)}.table-info{--table-color:hsl(0, 0%, 0%);--table-bg:#d6e0e8;--table-border-color:#c1cad1;--table-striped-bg:#cbd5dc;--table-striped-color:hsl(0, 0%, 0%);--table-active-bg:#c1cad1;--table-active-color:hsl(0, 0%, 0%);--table-active-bg:#c6cfd7;--table-active-color:hsl(0, 0%, 0%);color:var(--table-color);border-color:var(--table-border-color)}.table-warning{--table-color:hsl(0, 0%, 0%);--table-bg:#efe0cc;--table-border-color:#d7cab8;--table-striped-bg:#e3d5c2;--table-striped-color:hsl(0, 0%, 0%);--table-active-bg:#d7cab8;--table-active-color:hsl(0, 0%, 0%);--table-active-bg:#ddcfbd;--table-active-color:hsl(0, 0%, 0%);color:var(--table-color);border-color:var(--table-border-color)}.table-danger{--table-color:hsl(0, 0%, 0%);--table-bg:#edd2d1;--table-border-color:#d5bdbc;--table-striped-bg:#e1c8c7;--table-striped-color:hsl(0, 0%, 0%);--table-active-bg:#d5bdbc;--table-active-color:hsl(0, 0%, 0%);--table-active-bg:#dbc2c1;--table-active-color:hsl(0, 0%, 0%);color:var(--table-color);border-color:var(--table-border-color)}.table-light{--table-color:hsl(0, 0%, 0%);--table-bg:hsl(210, 17%, 98%);--table-border-color:#e0e1e2;--table-striped-bg:#edeeee;--table-striped-color:hsl(0, 0%, 0%);--table-active-bg:#e0e1e2;--table-active-color:hsl(0, 0%, 0%);--table-active-bg:#e6e7e8;--table-active-color:hsl(0, 0%, 0%);color:var(--table-color);border-color:var(--table-border-color)}.table-dark{--table-color:var(--body-color);--table-bg:hsl(210, 10%, 23%);--table-border-color:#494f54;--table-striped-bg:#3f454b;--table-striped-color:var(--body-color);--table-active-bg:#494f54;--table-active-color:var(--body-color);--table-active-bg:#444a4f;--table-active-color:var(--body-color);color:var(--table-color);border-color:var(--table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.6rem + 1px);padding-bottom:calc(.6rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#6d757d}.form-control{display:block;width:100%;padding:.6rem 1rem;font-weight:400;line-height:1;color:var(--input-color);background-color:var(--input-bg);background-clip:padding-box;border:1px solid var(--input-border-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem;-webkit-transition:border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;-o-transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{-webkit-transition:none;-o-transition:none;transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--input-color);background-color:var(--input-bg);border-color:var(--input-focus-border-color);outline:0;-webkit-box-shadow:var(--input-focus-box-shadow);box-shadow:var(--input-focus-box-shadow)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-webkit-input-placeholder{color:var(--input-placeholder-color);opacity:1}.form-control::-moz-placeholder{color:var(--input-placeholder-color);opacity:1}.form-control:-ms-input-placeholder{color:var(--input-placeholder-color);opacity:1}.form-control::-ms-input-placeholder{color:var(--input-placeholder-color);opacity:1}.form-control::placeholder{color:var(--input-placeholder-color);opacity:1}.form-control:disabled{background-color:var(--input-disabled-bg);border-color:var(--input-disabled-border-color);opacity:1}.form-control::-webkit-file-upload-button{padding:.6rem 1rem;margin:-.6rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem;color:#22262a;background-color:#eaedf0;pointer-events:none;border:0 solid;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;border-color:inherit}.form-control::file-selector-button{padding:.6rem 1rem;margin:-.6rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem;color:#22262a;background-color:#eaedf0;pointer-events:none;border:0 solid;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;-o-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;border-color:inherit}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{-webkit-transition:none;-o-transition:none;transition:none}}.form-control:active:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:var(--input-file-button-active-bg)}.form-control:active:not(:disabled):not([readonly])::file-selector-button{background-color:var(--input-file-button-active-bg)}.form-control-plaintext{display:block;width:100%;padding:.6rem 0;margin-bottom:0;line-height:1.5;color:#22262a;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + 1.2rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:calc(1.5em + 1.2rem + 2px);padding:.6rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0;border-radius:.25rem}.form-control-color::-webkit-color-swatch{border-radius:.25rem}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + 2px)}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + 2px)}.custom-select,.form-select{display:block;width:100%;padding:.6rem 3rem .6rem 1rem;-moz-padding-start:calc(1rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#22262a;border-radius:.25rem;-webkit-transition:border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;-o-transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-select,.form-select{-webkit-transition:none;-o-transition:none;transition:none}}.custom-select:focus,.form-select:focus{border-color:var(--input-focus-border-color);outline:0}.form-select[multiple],.form-select[size]:not([size="1"]),[multiple].custom-select,[size].custom-select:not([size="1"]){padding-right:1rem;background-image:none}.custom-select:disabled,.form-select:disabled{background-color:#eaedf0}.custom-select:-moz-focusring,.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #22262a}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:.2rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.3rem}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:var(--body-color);background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,.25);-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{-webkit-filter:brightness(90%);filter:brightness(90%)}.form-check-input:focus{border-color:var(--input-focus-border-color);outline:0;-webkit-box-shadow:0 0 0 .25rem rgba(1,1,86,.25);box-shadow:0 0 0 .25rem rgba(1,1,86,.25)}.form-check-input:checked{background-color:#005;border-color:#005}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='hsl%280, 0, 100%%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='hsl%280, 0, 100%%29'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#005;border-color:#005;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='hsl%280, 0, 100%%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;-webkit-filter:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;-webkit-transition:background-position .15s ease-in-out;-o-transition:background-position .15s ease-in-out;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{-webkit-transition:none;-o-transition:none;transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%238894aa'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='hsl%280, 0, 100%%29'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;-webkit-filter:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{-webkit-box-shadow:0 0 0 1px var(--body-color),0 0 0 .25rem rgba(1,1,86,.25);box-shadow:0 0 0 1px var(--body-color),0 0 0 .25rem rgba(1,1,86,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px var(--body-color),0 0 0 .25rem rgba(1,1,86,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#005;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:var(--form-range-thumb-active-bg)}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dfe2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#005;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:var(--form-range-thumb-active-bg)}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dfe2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#acb5bd}.form-range:disabled::-moz-range-thumb{background-color:#acb5bd}.form-floating{position:relative}.form-floating>.custom-select,.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;width:100%;height:100%;padding:1rem;overflow:hidden;text-align:start;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:1px solid transparent;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transition:opacity .1s ease-in-out,-webkit-transform .1s ease-in-out;transition:opacity .1s ease-in-out,transform .1s ease-in-out,-webkit-transform .1s ease-in-out;-o-transition:opacity .1s ease-in-out,transform .1s ease-in-out}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem}.form-floating>.form-control-plaintext::-webkit-input-placeholder,.form-floating>.form-control::-webkit-input-placeholder{color:transparent}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext:-ms-input-placeholder,.form-floating>.form-control:-ms-input-placeholder{color:transparent}.form-floating>.form-control-plaintext::-ms-input-placeholder,.form-floating>.form-control::-ms-input-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:not(:-ms-input-placeholder),.form-floating>.form-control:not(:-ms-input-placeholder){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.custom-select,.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:not(:-ms-input-placeholder)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.custom-select~label,.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;-webkit-transform:scale(.85) translateY(-.5rem) translateX(.15rem);transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;-webkit-transform:scale(.85) translateY(-.5rem) translateX(.15rem);transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:1px 0}.input-group{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-select,.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0}.input-group>.custom-select:focus,.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:.6rem 1rem;font-size:1rem;font-weight:400;line-height:1.5;color:#22262a;text-align:center;white-space:nowrap;background-color:#eaedf0;border:1px solid #cdd3d9;border-radius:.25rem}.input-group-lg>.btn,.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.input-group-sm>.btn,.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-lg>.form-select,.input-group-sm>.custom-select,.input-group-sm>.form-select{padding-right:4rem}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.custom-select,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.custom-select,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-.0625rem;border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.custom-select,.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#438343}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:var(--body-color);background-color:rgba(68,131,68,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#438343;padding-right:calc(1.5em + 1.2rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='hsl%28120, 32%, 39%%29' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .3rem) center;background-size:calc(.75em + .6rem) calc(.75em + .6rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#438343;-webkit-box-shadow:0 0 0 .25rem rgba(68,131,68,.25);box-shadow:0 0 0 .25rem rgba(68,131,68,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + 1.2rem);background-position:top calc(.375em + .3rem) right calc(.375em + .3rem)}.form-select.is-valid,.is-valid.custom-select,.was-validated .custom-select:valid,.was-validated .form-select:valid{border-color:#438343}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.is-valid.custom-select:not([multiple]):not([size]),.is-valid.custom-select:not([multiple])[size="1"],.was-validated .custom-select:valid:not([multiple]):not([size]),.was-validated .custom-select:valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{padding-right:5.5rem;background-image:url("../images/select-bg.svg"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='hsl%28120, 32%, 39%%29' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right 1rem center,center right 3rem;background-size:116rem,calc(.75em + .6rem) calc(.75em + .6rem)}.form-select.is-valid:focus,.is-valid.custom-select:focus,.was-validated .custom-select:valid:focus,.was-validated .form-select:valid:focus{border-color:#438343;-webkit-box-shadow:0 0 0 .25rem rgba(68,131,68,.25);box-shadow:0 0 0 .25rem rgba(68,131,68,.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + 1.2rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#438343}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#438343}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{-webkit-box-shadow:0 0 0 .25rem rgba(68,131,68,.25);box-shadow:0 0 0 .25rem rgba(68,131,68,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#438343}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.custom-select:not(:focus).is-valid,.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.custom-select:not(:focus):valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#a51e17}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:var(--body-color);background-color:rgba(165,31,24,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#a51e17;padding-right:calc(1.5em + 1.2rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='hsl%283, 75%, 37%%29'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='hsl%283, 75%, 37%%29' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .3rem) center;background-size:calc(.75em + .6rem) calc(.75em + .6rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#a51e17;-webkit-box-shadow:0 0 0 .25rem rgba(165,31,24,.25);box-shadow:0 0 0 .25rem rgba(165,31,24,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + 1.2rem);background-position:top calc(.375em + .3rem) right calc(.375em + .3rem)}.form-select.is-invalid,.is-invalid.custom-select,.was-validated .custom-select:invalid,.was-validated .form-select:invalid{border-color:#a51e17}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.is-invalid.custom-select:not([multiple]):not([size]),.is-invalid.custom-select:not([multiple])[size="1"],.was-validated .custom-select:invalid:not([multiple]):not([size]),.was-validated .custom-select:invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{padding-right:5.5rem;background-image:url("../images/select-bg.svg"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='hsl%283, 75%, 37%%29'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='hsl%283, 75%, 37%%29' stroke='none'/%3e%3c/svg%3e");background-position:right 1rem center,center right 3rem;background-size:116rem,calc(.75em + .6rem) calc(.75em + .6rem)}.form-select.is-invalid:focus,.is-invalid.custom-select:focus,.was-validated .custom-select:invalid:focus,.was-validated .form-select:invalid:focus{border-color:#a51e17;-webkit-box-shadow:0 0 0 .25rem rgba(165,31,24,.25);box-shadow:0 0 0 .25rem rgba(165,31,24,.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + 1.2rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#a51e17}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#a51e17}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{-webkit-box-shadow:0 0 0 .25rem rgba(165,31,24,.25);box-shadow:0 0 0 .25rem rgba(165,31,24,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#a51e17}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.custom-select:not(:focus).is-invalid,.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.custom-select:not(:focus):invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}@media (prefers-reduced-motion:reduce){.btn,.form-floating>label{-webkit-transition:none;-o-transition:none;transition:none}}.btn:active{color:var(--btn-active-color);background-color:var(--btn-active-bg);border-color:var(--btn-active-border-color)}.btn-check+.btn:active{color:var(--btn-color);background-color:var(--btn-bg);border-color:var(--btn-border-color)}.btn:focus-visible{color:var(--btn-active-color);background-color:var(--btn-active-bg);border-color:var(--btn-active-border-color);outline:0;-webkit-box-shadow:var(--btn-focus-box-shadow);box-shadow:var(--btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--btn-active-border-color);outline:0;-webkit-box-shadow:var(--btn-focus-box-shadow);box-shadow:var(--btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--btn-active-color);background-color:var(--btn-active-bg);border-color:var(--btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{-webkit-box-shadow:var(--btn-focus-box-shadow);box-shadow:var(--btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--btn-disabled-color);pointer-events:none;background-color:var(--btn-disabled-bg);border-color:var(--btn-disabled-border-color);opacity:var(--btn-disabled-opacity)}.btn-link{--btn-font-weight:400;--btn-color:var(--link-color);--btn-bg:transparent;--btn-border-color:transparent;--btn-active-color:var(--link-active-color);--btn-active-border-color:transparent;--btn-active-color:var(--link-active-color);--btn-active-border-color:transparent;--btn-disabled-color:hsl(210, 7%, 46%);--btn-disabled-border-color:transparent;--btn-box-shadow:none;--btn-focus-shadow-rgb:39,39,111;text-decoration:underline}.btn-link:focus-visible{color:var(--btn-color)}.btn-link:active{color:var(--btn-active-color)}.btn-group-lg>.btn,.btn-lg{--btn-padding-y:0.5rem;--btn-padding-x:1rem;--btn-font-size:1.25rem;--btn-border-radius:0.3rem}.btn-group-sm>.btn,.btn-sm{--btn-padding-y:0.25rem;--btn-padding-x:0.5rem;--btn-font-size:0.875rem;--btn-border-radius:0.2rem}.fade{-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{-webkit-transition:none;-o-transition:none;transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;-webkit-transition:height .35s;-o-transition:height .35s;transition:height .35s}@media (prefers-reduced-motion:reduce){.collapsing{-webkit-transition:none;-o-transition:none;transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;-webkit-transition:width .35s;-o-transition:width .35s;transition:width .35s}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{-webkit-transition:none;-o-transition:none;transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:var(--dropdown-zindex);display:none;min-width:var(--dropdown-min-width);padding:var(--dropdown-padding-y) var(--dropdown-padding-x);margin:0;font-size:var(--dropdown-font-size);color:var(--dropdown-color);text-align:left;list-style:none;background-color:var(--dropdown-bg);background-clip:padding-box;border:var(--dropdown-border-width) solid var(--dropdown-border-color);border-radius:var(--dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid;vertical-align:0}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--dropdown-spacer)}.dropstart .dropdown-toggle::after{margin-left:.255em;vertical-align:.255em;content:"";display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent;vertical-align:0}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropdown-divider{height:0;margin:var(--dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--dropdown-item-padding-y) var(--dropdown-item-padding-x);clear:both;font-weight:400;color:var(--dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:active,.dropdown-item:focus{color:var(--dropdown-link-active-color);background-color:var(--dropdown-link-active-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--dropdown-link-active-color);text-decoration:none;background-color:var(--dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--dropdown-header-padding-y) var(--dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--dropdown-item-padding-y) var(--dropdown-item-padding-x);color:var(--dropdown-link-color)}.dropdown-menu-dark{--dropdown-color:hsl(210, 14%, 89%);--dropdown-bg:hsl(210, 10%, 23%);--dropdown-border-color:var(--border-color-translucent);--dropdown-box-shadow: ;--dropdown-link-color:hsl(210, 14%, 89%);--dropdown-link-active-color:var(--body-color);--dropdown-divider-bg:var(--border-color-translucent);--dropdown-link-active-bg:rgba(255, 255, 255, 0.15);--dropdown-link-active-color:var(--body-color);--dropdown-link-active-bg:hsl(240, 98%, 17%);--dropdown-link-disabled-color:hsl(210, 11%, 71%);--dropdown-header-color:hsl(210, 11%, 71%)}.btn-group,.btn-group-vertical{position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.25rem}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:-.0625rem}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-.0625rem}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--nav-link-padding-y) var(--nav-link-padding-x);font-size:var(--nav-link-font-size);font-weight:var(--nav-link-font-weight);color:var(--nav-link-color);text-decoration:none;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out;-o-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{-webkit-transition:none;-o-transition:none;transition:none}}.nav-link:active,.nav-link:focus{color:var(--nav-link-active-color)}.nav-link.disabled{color:var(--nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{border-bottom:var(--nav-tabs-border-width) solid var(--nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--nav-tabs-border-width));background:0 0;border:var(--nav-tabs-border-width) solid transparent;border-top-left-radius:var(--nav-tabs-border-radius);border-top-right-radius:var(--nav-tabs-border-radius)}.nav-tabs .nav-link:active,.nav-tabs .nav-link:focus{isolation:isolate;border-color:var(--nav-tabs-link-active-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--nav-tabs-link-active-color);background-color:var(--nav-tabs-link-active-bg);border-color:var(--nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--nav-pills-link-active-color);background-color:var(--nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:var(--navbar-padding-y) var(--navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:inherit;flex-wrap:inherit;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{padding-top:var(--navbar-brand-padding-y);padding-bottom:var(--navbar-brand-padding-y);margin-right:var(--navbar-brand-margin-end);font-size:var(--navbar-brand-font-size);color:var(--navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:active,.navbar-brand:focus{color:var(--navbar-brand-active-color)}.navbar-nav{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .show>.nav-link{color:var(--navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--navbar-color)}.navbar-text a,.navbar-text a:active,.navbar-text a:focus{color:var(--navbar-active-color)}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:var(--navbar-toggler-padding-y) var(--navbar-toggler-padding-x);font-size:var(--navbar-toggler-font-size);line-height:1;color:var(--navbar-color);background-color:transparent;border:0;-webkit-transition:var(--navbar-toggler-transition);-o-transition:var(--navbar-toggler-transition);transition:var(--navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{-webkit-transition:none;-o-transition:none;transition:none}}.navbar-toggler:active{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;color:var(--color-primary)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--navbar-nav-link-padding-x);padding-left:var(--navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;width:auto;height:auto;visibility:visible;background-color:transparent;border:0;-webkit-transform:none;transform:none;-webkit-transition:none;-o-transition:none;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--navbar-nav-link-padding-x);padding-left:var(--navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;width:auto;height:auto;visibility:visible;background-color:transparent;border:0;-webkit-transform:none;transform:none;-webkit-transition:none;-o-transition:none;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--navbar-nav-link-padding-x);padding-left:var(--navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;width:auto;height:auto;visibility:visible;background-color:transparent;border:0;-webkit-transform:none;transform:none;-webkit-transition:none;-o-transition:none;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--navbar-nav-link-padding-x);padding-left:var(--navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;width:auto;height:auto;visibility:visible;background-color:transparent;border:0;-webkit-transform:none;transform:none;-webkit-transition:none;-o-transition:none;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}.navbar-expand-xxl{-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--navbar-nav-link-padding-x);padding-left:var(--navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;width:auto;height:auto;visibility:visible;background-color:transparent;border:0;-webkit-transform:none;transform:none;-webkit-transition:none;-o-transition:none;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--navbar-nav-link-padding-x);padding-left:var(--navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;width:auto;height:auto;visibility:visible;background-color:transparent;border:0;-webkit-transform:none;transform:none;-webkit-transition:none;-o-transition:none;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;padding:0;overflow-y:visible}.card{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;min-width:0;height:var(--card-height);word-wrap:break-word;background-color:var(--card-bg);background-clip:border-box;border:var(--card-border-width) solid var(--card-border-color);border-radius:var(--card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--card-inner-border-radius);border-top-right-radius:var(--card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--card-inner-border-radius);border-bottom-left-radius:var(--card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;padding:var(--card-spacer-y) var(--card-spacer-x);color:var(--card-color)}.card-title{margin-bottom:var(--card-title-spacer-y)}.card-subtitle{margin-top:calc(-.5 * var(--card-title-spacer-y));margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--card-spacer-x)}.card-header{padding:var(--card-cap-padding-y) var(--card-cap-padding-x);margin-bottom:0;color:var(--card-cap-color);background-color:var(--card-cap-bg);border-bottom:var(--card-border-width) solid var(--card-border-color)}.card-header:first-child{border-radius:var(--card-inner-border-radius) var(--card-inner-border-radius) 0 0}.card-footer{padding:var(--card-cap-padding-y) var(--card-cap-padding-x);color:var(--card-cap-color);background-color:var(--card-cap-bg);border-top:var(--card-border-width) solid var(--card-border-color)}.card-footer:last-child{border-radius:0 0 var(--card-inner-border-radius) var(--card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--card-cap-padding-x));margin-bottom:calc(-1 * var(--card-cap-padding-y));margin-left:calc(-.5 * var(--card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--card-bg);border-bottom-color:var(--card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--card-cap-padding-x));margin-left:calc(-.5 * var(--card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--card-img-overlay-padding);border-radius:var(--card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--card-inner-border-radius);border-top-right-radius:var(--card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--card-inner-border-radius);border-bottom-left-radius:var(--card-inner-border-radius)}.card-group>.card{margin-bottom:var(--card-group-margin)}@media (min-width:576px){.card-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion-button{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;padding:var(--accordion-btn-padding-y) var(--accordion-btn-padding-x);font-size:1rem;color:var(--accordion-btn-color);text-align:left;background-color:var(--accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;-webkit-transition:var(--accordion-transition);-o-transition:var(--accordion-transition);transition:var(--accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{-webkit-transition:none;-o-transition:none;transition:none}}.accordion-button:not(.collapsed){color:var(--accordion-active-color);background-color:var(--accordion-active-bg);-webkit-box-shadow:inset 0 calc(-1 * var(--accordion-border-width)) 0 var(--accordion-border-color);box-shadow:inset 0 calc(-1 * var(--accordion-border-width)) 0 var(--accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--accordion-btn-active-icon);-webkit-transform:var(--accordion-btn-icon-transform);transform:var(--accordion-btn-icon-transform)}.accordion-button::after{-ms-flex-negative:0;flex-shrink:0;width:var(--accordion-btn-icon-width);height:var(--accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--accordion-btn-icon);background-repeat:no-repeat;background-size:var(--accordion-btn-icon-width);-webkit-transition:var(--accordion-btn-icon-transition);-o-transition:var(--accordion-btn-icon-transition);transition:var(--accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{-webkit-transition:none;-o-transition:none;transition:none}}.accordion-button:active{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--accordion-btn-focus-border-color);outline:0;-webkit-box-shadow:var(--accordion-btn-focus-box-shadow);box-shadow:var(--accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--accordion-color);background-color:var(--accordion-bg);border:var(--accordion-border-width) solid var(--accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--accordion-border-radius);border-top-right-radius:var(--accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--accordion-inner-border-radius);border-top-right-radius:var(--accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--accordion-border-radius);border-bottom-left-radius:var(--accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:var(--accordion-inner-border-radius);border-bottom-left-radius:var(--accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:var(--accordion-border-radius);border-bottom-left-radius:var(--accordion-border-radius)}.accordion-body{padding:var(--accordion-body-padding-y) var(--accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}.breadcrumb{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:var(--breadcrumb-padding-y) var(--breadcrumb-padding-x);margin-bottom:var(--breadcrumb-margin-bottom);font-size:var(--breadcrumb-font-size);list-style:none;background-color:var(--breadcrumb-bg);border-radius:var(--breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--breadcrumb-item-padding-x);color:var(--breadcrumb-divider-color);content:var(--breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--breadcrumb-item-active-color)}.pagination{display:-webkit-box;display:-ms-flexbox;display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--pagination-padding-y) var(--pagination-padding-x);font-size:var(--pagination-font-size);color:var(--pagination-color);text-decoration:none;background-color:var(--pagination-bg);border:var(--pagination-border-width) solid var(--pagination-border-color);-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;-o-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{-webkit-transition:none;-o-transition:none;transition:none}}.page-link:active{z-index:2;color:var(--pagination-active-color);background-color:var(--pagination-active-bg);border-color:var(--pagination-active-border-color)}.page-link:focus{z-index:3;color:var(--pagination-focus-color);background-color:var(--pagination-focus-bg);outline:0;-webkit-box-shadow:var(--pagination-focus-box-shadow);box-shadow:var(--pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--pagination-active-color);background-color:var(--pagination-active-bg);border-color:var(--pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--pagination-disabled-color);pointer-events:none;background-color:var(--pagination-disabled-bg);border-color:var(--pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:-.0625rem}.page-item:first-child .page-link{border-top-left-radius:var(--pagination-border-radius);border-bottom-left-radius:var(--pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--pagination-border-radius);border-bottom-right-radius:var(--pagination-border-radius)}.pagination-lg{--pagination-padding-x:1.5rem;--pagination-padding-y:0.75rem;--pagination-font-size:1.25rem;--pagination-border-radius:0.3rem}.pagination-sm{--pagination-padding-x:0.5rem;--pagination-padding-y:0.25rem;--pagination-font-size:0.875rem;--pagination-border-radius:0.2rem}.badge{display:inline-block;padding:var(--badge-padding-y) var(--badge-padding-x);font-size:var(--badge-font-size);font-weight:var(--badge-font-weight);line-height:1;color:var(--badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{position:relative;padding:var(--alert-padding-y) var(--alert-padding-x);margin-bottom:var(--alert-margin-bottom);color:var(--alert-color);background-color:var(--alert-bg);border:var(--alert-border);border-radius:var(--alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--alert-color:#010134;--alert-bg:#ccccdd;--alert-border-color:#b3b3cc}.alert-primary .alert-link{color:var(--alert-primary-link-color)}.alert-secondary{--alert-color:#41464c;--alert-bg:#e2e3e5;--alert-border-color:#d3d6d8}.alert-secondary .alert-link{color:var(--alert-secondary-link-color)}.alert-success{--alert-color:#294f29;--alert-bg:#dae6da;--alert-border-color:#c7dac7}.alert-success .alert-link{color:var(--alert-success-link-color)}.alert-info{--alert-color:#1d3b55;--alert-bg:#d6e0e8;--alert-border-color:#c1d0dd}.alert-info .alert-link{color:var(--alert-info-link-color)}.alert-warning{--alert-color:#683b00;--alert-bg:#efe0cc;--alert-border-color:#e6d0b3}.alert-warning .alert-link{color:var(--alert-warning-link-color)}.alert-danger{--alert-color:#63130e;--alert-bg:#edd2d1;--alert-border-color:#e4bcba}.alert-danger .alert-link{color:var(--alert-danger-link-color)}.alert-light{--alert-color:#646464;--alert-bg:#fefefe;--alert-border-color:#fdfefe}.alert-light .alert-link{color:var(--alert-light-link-color)}.alert-dark{--alert-color:#202327;--alert-bg:#d7d8d9;--alert-border-color:#c2c4c6}.alert-dark .alert-link{color:var(--alert-dark-link-color)}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{display:-webkit-box;display:-ms-flexbox;display:flex;height:var(--progress-height);overflow:hidden;font-size:var(--progress-font-size);background-color:var(--progress-bg);border-radius:var(--progress-border-radius)}.progress-bar{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:var(--progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--progress-bar-bg);-webkit-transition:var(--progress-bar-transition);-o-transition:var(--progress-bar-transition);transition:var(--progress-bar-transition)}.progress-bar-striped{background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--progress-height) var(--progress-height)}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar{-webkit-transition:none;-o-transition:none;transition:none}.progress-bar-animated{-webkit-animation:none;animation:none}}.list-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--list-group-action-color);text-align:inherit}.list-group-item-action:active,.list-group-item-action:focus{z-index:1;color:var(--list-group-action-active-color);text-decoration:none;background-color:var(--list-group-action-active-bg)}.list-group-item-action:active{color:var(--list-group-action-active-color);background-color:var(--list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--list-group-item-padding-y) var(--list-group-item-padding-x);color:var(--list-group-color);text-decoration:none;background-color:var(--list-group-bg);border:var(--list-group-border-width) solid var(--list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--list-group-disabled-color);pointer-events:none;background-color:var(--list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--list-group-active-color);background-color:var(--list-group-active-bg);border-color:var(--list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--list-group-border-width));border-top-width:var(--list-group-border-width)}.list-group-horizontal{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--list-group-border-width));border-left-width:var(--list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--list-group-border-width));border-left-width:var(--list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--list-group-border-width));border-left-width:var(--list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--list-group-border-width));border-left-width:var(--list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--list-group-border-width));border-left-width:var(--list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--list-group-border-width));border-left-width:var(--list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:var(--list-group-item-primary-color);background-color:var(--list-group-item-primary-bg)}.list-group-item-primary.list-group-item-action:active,.list-group-item-primary.list-group-item-action:focus{color:var(--list-group-item-primary-color);background-color:var(--list-group-item-primary-active-bg)}.list-group-item-primary.list-group-item-action.active{color:var(--body-color);background-color:var(--list-group-item-primary-color);border-color:var(--list-group-item-primary-color)}.list-group-item-secondary{color:var(--list-group-item-secondary-color);background-color:var(--list-group-item-secondary-bg)}.list-group-item-secondary.list-group-item-action:active,.list-group-item-secondary.list-group-item-action:focus{color:var(--list-group-item-secondary-color);background-color:var(--list-group-item-secondary-active-bg)}.list-group-item-secondary.list-group-item-action.active{color:var(--body-color);background-color:var(--list-group-item-secondary-color);border-color:var(--list-group-item-secondary-color)}.list-group-item-success{color:var(--list-group-item-success-color);background-color:var(--list-group-item-success-bg)}.list-group-item-success.list-group-item-action:active,.list-group-item-success.list-group-item-action:focus{color:var(--list-group-item-success-color);background-color:var(--list-group-item-success-active-bg)}.list-group-item-success.list-group-item-action.active{color:var(--body-color);background-color:var(--list-group-item-success-color);border-color:var(--list-group-item-success-color)}.list-group-item-info{color:var(--list-group-item-info-color);background-color:var(--list-group-item-info-bg)}.list-group-item-info.list-group-item-action:active,.list-group-item-info.list-group-item-action:focus{color:var(--list-group-item-info-color);background-color:var(--list-group-item-info-active-bg)}.list-group-item-info.list-group-item-action.active{color:var(--body-color);background-color:var(--list-group-item-info-color);border-color:var(--list-group-item-info-color)}.list-group-item-warning{color:var(--list-group-item-warning-color);background-color:var(--list-group-item-warning-bg)}.list-group-item-warning.list-group-item-action:active,.list-group-item-warning.list-group-item-action:focus{color:var(--list-group-item-warning-color);background-color:var(--list-group-item-warning-active-bg)}.list-group-item-warning.list-group-item-action.active{color:var(--body-color);background-color:var(--list-group-item-warning-color);border-color:var(--list-group-item-warning-color)}.list-group-item-danger{color:var(--list-group-item-danger-color);background-color:var(--list-group-item-danger-bg)}.list-group-item-danger.list-group-item-action:active,.list-group-item-danger.list-group-item-action:focus{color:var(--list-group-item-danger-color);background-color:var(--list-group-item-danger-active-bg)}.list-group-item-danger.list-group-item-action.active{color:var(--body-color);background-color:var(--list-group-item-danger-color);border-color:var(--list-group-item-danger-color)}.list-group-item-light{color:var(--list-group-item-light-color);background-color:var(--list-group-item-light-bg)}.list-group-item-light.list-group-item-action:active,.list-group-item-light.list-group-item-action:focus{color:var(--list-group-item-light-color);background-color:var(--list-group-item-light-active-bg)}.list-group-item-light.list-group-item-action.active{color:var(--body-color);background-color:var(--list-group-item-light-color);border-color:var(--list-group-item-light-color)}.list-group-item-dark{color:var(--list-group-item-dark-color);background-color:var(--list-group-item-dark-bg)}.list-group-item-dark.list-group-item-action:active,.list-group-item-dark.list-group-item-action:focus{color:var(--list-group-item-dark-color);background-color:var(--list-group-item-dark-active-bg)}.list-group-item-dark.list-group-item-action.active{color:var(--body-color);background-color:var(--list-group-item-dark-color);border-color:var(--list-group-item-dark-color)}.btn-close{-webkit-box-sizing:content-box;box-sizing:content-box;width:1em;height:1em;padding:.25em;color:#000;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='hsl%280, 0, 0%29'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.5}.btn-close:active{color:#000;text-decoration:none;opacity:.75}.btn-close:focus{outline:0;-webkit-box-shadow:0 0 0 .25rem rgba(1,1,86,.25);box-shadow:0 0 0 .25rem rgba(1,1,86,.25);opacity:1}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;opacity:.25}.btn-close-white{-webkit-filter:invert(1) grayscale(100%) brightness(200%);filter:invert(1) grayscale(100%) brightness(200%)}.toast{width:var(--toast-max-width);max-width:100%;font-size:var(--toast-font-size);color:var(--toast-color);pointer-events:auto;background-color:var(--toast-bg);background-clip:padding-box;border:var(--toast-border-width) solid var(--toast-border-color);-webkit-box-shadow:var(--toast-box-shadow);box-shadow:var(--toast-box-shadow);border-radius:var(--toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--toast-zindex:1090;position:absolute;z-index:var(--toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--toast-spacing)}.toast-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:var(--toast-padding-y) var(--toast-padding-x);color:var(--toast-header-color);background-color:var(--toast-header-bg);background-clip:padding-box;border-bottom:var(--toast-border-width) solid var(--toast-header-border-color);border-top-left-radius:calc(var(--toast-border-radius) - var(--toast-border-width));border-top-right-radius:calc(var(--toast-border-radius) - var(--toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--toast-padding-x));margin-left:var(--toast-padding-x)}.toast-body{padding:var(--toast-padding-x);word-wrap:break-word}.modal{position:fixed;top:0;left:0;z-index:var(--modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--modal-margin);pointer-events:none}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;-o-transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{-webkit-transition:none;-o-transition:none;transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;min-height:calc(100% - var(--modal-margin) * 2)}.modal-content{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:100%;color:var(--modal-color);pointer-events:auto;background-color:var(--modal-bg);background-clip:padding-box;border:var(--modal-border-width) solid var(--modal-border-color);border-radius:var(--modal-border-radius);outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:var(--backdrop-zindex);width:100vw;height:100vh;background-color:var(--backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--backdrop-opacity)}.modal-header{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-negative:0;flex-shrink:0;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:var(--modal-header-padding);border-bottom:var(--modal-header-border-width) solid var(--modal-header-border-color);border-top-left-radius:var(--modal-inner-border-radius);border-top-right-radius:var(--modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--modal-header-padding-y) * .5) calc(var(--modal-header-padding-x) * .5);margin:calc(-.5 * var(--modal-header-padding-y)) calc(-.5 * var(--modal-header-padding-x)) calc(-.5 * var(--modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--modal-title-line-height)}.modal-body{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;padding:var(--modal-padding)}.modal-footer{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-negative:0;flex-shrink:0;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;padding:calc(var(--modal-padding) - var(--modal-footer-gap) * .5);background-color:var(--modal-footer-bg);border-top:var(--modal-footer-border-width) solid var(--modal-footer-border-color);border-bottom-right-radius:var(--modal-inner-border-radius);border-bottom-left-radius:var(--modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--modal-footer-gap) * .5)}@media (min-width:576px){.modal{--modal-margin:1.75rem;--modal-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15)}.modal-dialog{max-width:var(--modal-width);margin-right:auto;margin-left:auto}.modal-sm{--modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--modal-width:800px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{z-index:var(--tooltip-zindex);display:block;padding:var(--tooltip-arrow-height);margin:var(--tooltip-margin);font-family:v-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--tooltip-arrow-width);height:var(--tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--tooltip-arrow-height) calc(var(--tooltip-arrow-width) * .5) 0;border-top-color:var(--tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:var(--tooltip-arrow-height);height:var(--tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--tooltip-arrow-width) * .5) var(--tooltip-arrow-height) calc(var(--tooltip-arrow-width) * .5) 0;border-right-color:var(--tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--tooltip-arrow-width) * .5) var(--tooltip-arrow-height);border-bottom-color:var(--tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:var(--tooltip-arrow-height);height:var(--tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--tooltip-arrow-width) * .5) 0 calc(var(--tooltip-arrow-width) * .5) var(--tooltip-arrow-height);border-left-color:var(--tooltip-bg)}.tooltip-inner{max-width:var(--tooltip-max-width);padding:var(--tooltip-padding-y) var(--tooltip-padding-x);color:var(--tooltip-color);text-align:center;background-color:var(--tooltip-bg);border-radius:var(--tooltip-border-radius)}.popover{z-index:var(--popover-zindex);display:block;max-width:var(--popover-max-width);font-family:var(--font-family-body, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--popover-font-size);word-wrap:break-word;background-color:var(--popover-bg);background-clip:padding-box;border:var(--popover-border-width) solid var(--popover-border-color);border-radius:var(--popover-border-radius)}.popover .popover-arrow{display:block;width:var(--popover-arrow-width);height:var(--popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border:0 solid transparent}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--popover-arrow-height)) - var(--popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--popover-arrow-height) calc(var(--popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--popover-border-width);border-top-color:var(--popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--popover-arrow-height)) - var(--popover-border-width));width:var(--popover-arrow-height);height:var(--popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--popover-arrow-width) * .5) var(--popover-arrow-height) calc(var(--popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--popover-border-width);border-right-color:var(--popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--popover-arrow-height)) - var(--popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--popover-arrow-width) * .5) var(--popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--popover-border-width);border-bottom-color:var(--popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--popover-arrow-width);margin-left:calc(-.5 * var(--popover-arrow-width));content:"";border-bottom:var(--popover-border-width) solid var(--popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--popover-arrow-height)) - var(--popover-border-width));width:var(--popover-arrow-height);height:var(--popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--popover-arrow-width) * .5) 0 calc(var(--popover-arrow-width) * .5) var(--popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--popover-border-width);border-left-color:var(--popover-bg)}.popover-header{padding:var(--popover-header-padding-y) var(--popover-header-padding-x);margin-bottom:0;font-size:var(--popover-header-font-size);color:var(--popover-header-color);background-color:var(--popover-header-bg);border-bottom:var(--popover-border-width) solid var(--popover-border-color);border-top-left-radius:var(--popover-inner-border-radius);border-top-right-radius:var(--popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--popover-body-padding-y) var(--popover-body-padding-x);color:var(--popover-body-color)}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;-o-transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{-webkit-transition:none;-o-transition:none;transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;-webkit-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;-webkit-transition:opacity 0s .6s;-o-transition:opacity 0s .6s;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{-webkit-transition:none;-o-transition:none;transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:15%;padding:0;color:var(--body-color);text-align:center;background:0 0;border:0;opacity:.5;-webkit-transition:opacity .15s;-o-transition:opacity .15s;transition:opacity .15s}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{-webkit-transition:none;-o-transition:none;transition:none}}.carousel-control-next:active,.carousel-control-next:focus,.carousel-control-prev:active,.carousel-control-prev:focus{color:var(--body-color);text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='hsl%280, 0, 100%%29'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='hsl%280, 0, 100%%29'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{-webkit-box-sizing:content-box;box-sizing:content-box;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:.1875rem;margin-left:.1875rem;text-indent:-999px;cursor:pointer;background-color:var(--body-color);background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;-webkit-transition:opacity .6s;-o-transition:opacity .6s;transition:opacity .6s}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:var(--body-color);text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{-webkit-filter:invert(1) grayscale(100);filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}.spinner-border,.spinner-grow{display:inline-block;width:var(--spinner-width);height:var(--spinner-height);vertical-align:var(--spinner-vertical-align);border-radius:50%;-webkit-animation:var(--spinner-animation-speed) linear infinite var(--spinner-animation-name);animation:var(--spinner-animation-speed) linear infinite var(--spinner-animation-name)}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{--spinner-animation-name:spinner-border;border:var(--spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--spinner-width:1rem;--spinner-height:1rem;--spinner-border-width:0.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{--spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--spinner-width:1rem;--spinner-height:1rem}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{-webkit-transition:none;-o-transition:none;transition:none}.spinner-border,.spinner-grow{--spinner-animation-speed:1.5s}}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--offcanvas-zindex);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-width:100%;color:var(--offcanvas-color);visibility:hidden;background-color:var(--offcanvas-bg);background-clip:padding-box;outline:0;-webkit-transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;-o-transition:transform .3s ease-in-out;transition:transform .3s ease-in-out,-webkit-transform .3s ease-in-out}.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--offcanvas-width);border-right:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{-webkit-transition:none;-o-transition:none;transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--offcanvas-width);border-left:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateX(100%);transform:translateX(100%)}.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--offcanvas-height);max-height:100%;border-bottom:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateY(-100%);transform:translateY(-100%)}.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--offcanvas-height);max-height:100%;border-top:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateY(100%);transform:translateY(100%)}.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{-webkit-transform:none;transform:none}.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--offcanvas-height:auto;--offcanvas-border-width:0;background-color:transparent}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--offcanvas-zindex);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-width:100%;color:var(--offcanvas-color);visibility:hidden;background-color:var(--offcanvas-bg);background-clip:padding-box;outline:0;-webkit-transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;-o-transition:transform .3s ease-in-out;transition:transform .3s ease-in-out,-webkit-transform .3s ease-in-out}.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--offcanvas-width);border-right:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{-webkit-transition:none;-o-transition:none;transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--offcanvas-width);border-left:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateX(100%);transform:translateX(100%)}.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--offcanvas-height);max-height:100%;border-bottom:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateY(-100%);transform:translateY(-100%)}.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--offcanvas-height);max-height:100%;border-top:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateY(100%);transform:translateY(100%)}.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{-webkit-transform:none;transform:none}.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}.container-header .container-nav nav{margin-top:.4rem}}@media (min-width:768px){.offcanvas-md{--offcanvas-height:auto;--offcanvas-border-width:0;background-color:transparent}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--offcanvas-zindex);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-width:100%;color:var(--offcanvas-color);visibility:hidden;background-color:var(--offcanvas-bg);background-clip:padding-box;outline:0;-webkit-transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;-o-transition:transform .3s ease-in-out;transition:transform .3s ease-in-out,-webkit-transform .3s ease-in-out}.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--offcanvas-width);border-right:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{-webkit-transition:none;-o-transition:none;transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--offcanvas-width);border-left:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateX(100%);transform:translateX(100%)}.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--offcanvas-height);max-height:100%;border-bottom:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateY(-100%);transform:translateY(-100%)}.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--offcanvas-height);max-height:100%;border-top:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateY(100%);transform:translateY(100%)}.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{-webkit-transform:none;transform:none}.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--offcanvas-height:auto;--offcanvas-border-width:0;background-color:transparent}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--offcanvas-zindex);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-width:100%;color:var(--offcanvas-color);visibility:hidden;background-color:var(--offcanvas-bg);background-clip:padding-box;outline:0;-webkit-transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;-o-transition:transform .3s ease-in-out;transition:transform .3s ease-in-out,-webkit-transform .3s ease-in-out}.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--offcanvas-width);border-right:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{-webkit-transition:none;-o-transition:none;transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--offcanvas-width);border-left:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateX(100%);transform:translateX(100%)}.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--offcanvas-height);max-height:100%;border-bottom:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateY(-100%);transform:translateY(-100%)}.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--offcanvas-height);max-height:100%;border-top:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateY(100%);transform:translateY(100%)}.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{-webkit-transform:none;transform:none}.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}.sidebar-left .metismenu li.parent>ul,.sidebar-right .metismenu li.parent>ul{width:100%}}@media (min-width:1200px){.modal-xl{--modal-width:1140px}.offcanvas-xl{--offcanvas-height:auto;--offcanvas-border-width:0;background-color:transparent}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--offcanvas-zindex);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-width:100%;color:var(--offcanvas-color);visibility:hidden;background-color:var(--offcanvas-bg);background-clip:padding-box;outline:0;-webkit-transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;-o-transition:transform .3s ease-in-out;transition:transform .3s ease-in-out,-webkit-transform .3s ease-in-out}.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--offcanvas-width);border-right:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateX(-100%);transform:translateX(-100%)}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{-webkit-transition:none;-o-transition:none;transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--offcanvas-width);border-left:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateX(100%);transform:translateX(100%)}.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--offcanvas-height);max-height:100%;border-bottom:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateY(-100%);transform:translateY(-100%)}.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--offcanvas-height);max-height:100%;border-top:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateY(100%);transform:translateY(100%)}.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{-webkit-transform:none;transform:none}.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--offcanvas-height:auto;--offcanvas-border-width:0;background-color:transparent}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent}}.offcanvas{position:fixed;bottom:0;z-index:var(--offcanvas-zindex);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-width:100%;color:var(--offcanvas-color);visibility:hidden;background-color:var(--offcanvas-bg);background-clip:padding-box;outline:0;-webkit-transition:-webkit-transform .3s ease-in-out;transition:transform .3s ease-in-out;-o-transition:transform .3s ease-in-out;transition:transform .3s ease-in-out,-webkit-transform .3s ease-in-out}@media (prefers-reduced-motion:reduce){.offcanvas{-webkit-transition:none;-o-transition:none;transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--offcanvas-width);border-right:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateX(-100%);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--offcanvas-width);border-left:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateX(100%);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--offcanvas-height);max-height:100%;border-bottom:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateY(-100%);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--offcanvas-height);max-height:100%;border-top:var(--offcanvas-border-width) solid var(--offcanvas-border-color);-webkit-transform:translateY(100%);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{-webkit-transform:none;transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:var(--offcanvas-padding-y) var(--offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--offcanvas-padding-y) * .5) calc(var(--offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--offcanvas-padding-y));margin-right:calc(-.5 * var(--offcanvas-padding-x));margin-bottom:calc(-.5 * var(--offcanvas-padding-y))}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;padding:var(--offcanvas-padding-y) var(--offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{-webkit-animation:2s ease-in-out infinite placeholder-glow;animation:2s ease-in-out infinite placeholder-glow}@-webkit-keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,hsl(0,0%,0%) 55%,rgba(0,0,0,0.8) 75%,hsl(0,0%,0%) 95%);mask-image:linear-gradient(130deg,hsl(0,0%,0%) 55%,rgba(0,0,0,0.8) 75%,hsl(0,0%,0%) 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;-webkit-animation:2s linear infinite placeholder-wave;animation:2s linear infinite placeholder-wave}@-webkit-keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:var(--body-color);background-color:var(--primary)}.text-bg-secondary{color:var(--body-color);background-color:RGBA(109,117,126,var(--bg-opacity,1))}.text-bg-success{color:var(--body-color);background-color:RGBA(68,131,68,var(--bg-opacity,1))}.text-bg-info{color:var(--body-color);background-color:RGBA(48,99,141,var(--bg-opacity,1))}.text-bg-warning{color:var(--body-color);background-color:RGBA(173,98,0,var(--bg-opacity,1))}.text-bg-danger{color:var(--body-color);background-color:RGBA(165,31,24,var(--bg-opacity,1))}.text-bg-light{color:#000;background-color:RGBA(249,250,251,var(--bg-opacity,1))}.text-bg-dark{color:var(--body-color);background-color:RGBA(53,59,65,var(--bg-opacity,1))}.link-primary{color:var(--link-primary-color)}.link-primary:active,.link-primary:focus{color:var(--link-primary-hover-color)}.link-secondary{color:var(--link-secondary-color)}.link-secondary:active,.link-secondary:focus{color:var(--link-secondary-hover-color)}.link-success{color:var(--link-success-color)}.link-success:active,.link-success:focus{color:var(--link-success-hover-color)}.link-info{color:var(--link-info-color)}.link-info:active,.link-info:focus{color:var(--link-info-hover-color)}.link-warning{color:var(--link-warning-color)}.link-warning:active,.link-warning:focus{color:var(--link-warning-hover-color)}.link-danger{color:var(--link-danger-color)}.link-danger:active,.link-danger:focus{color:var(--link-danger-hover-color)}.link-light{color:var(--link-light-color)}.link-light:active,.link-light:focus{color:var(--link-light-hover-color)}.link-dark{color:var(--link-dark-color)}.link-dark:active,.link-dark:focus{color:var(--link-dark-hover-color)}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--aspect-ratio:100%}.ratio-4x3{--aspect-ratio:75%}.ratio-16x9{--aspect-ratio:56.25%}.ratio-21x9{--aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}.sticky-bottom{position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:sticky;bottom:0;z-index:1020}}.hstack{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-item-align:stretch;align-self:stretch}.vstack{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-ms-flex-item-align:stretch;align-self:stretch}.sr-only,.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute;width:1px;height:1px;padding:0;margin:-.0625rem;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;-ms-flex-item-align:stretch;align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline}.align-top{vertical-align:top}.align-middle{vertical-align:middle}.align-bottom{vertical-align:bottom}.align-text-bottom{vertical-align:text-bottom}.align-text-top{vertical-align:text-top}.float-start{float:left}.float-end{float:right}.float-none{float:none}.opacity-0{opacity:0}.opacity-25{opacity:.25}.opacity-50{opacity:.5}.opacity-75{opacity:.75}.opacity-100{opacity:1}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-scroll{overflow:scroll}.d-inline{display:inline}.d-inline-block{display:inline-block}.d-block{display:block}.d-grid{display:grid}.d-table{display:table}.d-table-row{display:table-row}.d-table-cell{display:table-cell}.d-flex{display:-webkit-box;display:-ms-flexbox;display:flex}.d-inline-flex{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.d-none{display:none}.shadow{-webkit-box-shadow:0 .5rem 1rem rgba(0,0,0,.15);box-shadow:0 .5rem 1rem rgba(0,0,0,.15)}.shadow-sm{-webkit-box-shadow:0 .125rem .25rem rgba(0,0,0,.075);box-shadow:0 .125rem .25rem rgba(0,0,0,.075)}.shadow-lg{-webkit-box-shadow:0 1rem 3rem rgba(0,0,0,.175);box-shadow:0 1rem 3rem rgba(0,0,0,.175)}.shadow-none{-webkit-box-shadow:none;box-shadow:none}.position-static{position:static}.position-relative{position:relative}.position-absolute{position:absolute}.position-fixed{position:fixed}.position-sticky{position:sticky}.top-0{top:0}.top-50{top:50%}.top-100{top:100%}.bottom-0{bottom:0}.bottom-50{bottom:50%}.bottom-100{bottom:100%}.start-0{left:0}.start-50{left:50%}.start-100{left:100%}.end-0{right:0}.end-50{right:50%}.end-100{right:100%}.translate-middle{-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.translate-middle-x{-webkit-transform:translateX(-50%);transform:translateX(-50%)}.translate-middle-y{-webkit-transform:translateY(-50%);transform:translateY(-50%)}.border{border:var(--border-width) var(--border-style) var(--border-color)}.border-0{border:0}.border-top{border-top:var(--border-width) var(--border-style) var(--border-color)}.border-top-0{border-top:0}.border-end{border-right:var(--border-width) var(--border-style) var(--border-color)}.border-end-0{border-right:0}.border-bottom{border-bottom:var(--border-width) var(--border-style) var(--border-color)}.border-bottom-0{border-bottom:0}.border-start{border-left:var(--border-width) var(--border-style) var(--border-color)}.border-start-0{border-left:0}.border-primary{--border-opacity:1;border-color:rgba(var(--primary-rgb),var(--border-opacity))}.border-secondary{--border-opacity:1;border-color:rgba(var(--secondary-rgb),var(--border-opacity))}.border-success{--border-opacity:1;border-color:rgba(var(--success-rgb),var(--border-opacity))}.border-info{--border-opacity:1;border-color:rgba(var(--info-rgb),var(--border-opacity))}.border-warning{--border-opacity:1;border-color:rgba(var(--warning-rgb),var(--border-opacity))}.border-danger{--border-opacity:1;border-color:rgba(var(--danger-rgb),var(--border-opacity))}.border-light{--border-opacity:1;border-color:rgba(var(--light-rgb),var(--border-opacity))}.border-dark{--border-opacity:1;border-color:rgba(var(--dark-rgb),var(--border-opacity))}.border-white{--border-opacity:1;border-color:rgba(var(--white-rgb),var(--border-opacity))}.border-1{--border-width:1px}.border-2{--border-width:2px}.border-3{--border-width:3px}.border-4{--border-width:4px}.border-5{--border-width:5px}.border-opacity-10{--border-opacity:0.1}.border-opacity-25{--border-opacity:0.25}.border-opacity-50{--border-opacity:0.5}.border-opacity-75{--border-opacity:0.75}.border-opacity-100{--border-opacity:1}.w-25{width:25%}.w-50{width:50%}.w-75{width:75%}.w-100{width:100%}.w-auto{width:auto}.mw-100{max-width:100%}.vw-100{width:100vw}.min-vw-100{min-width:100vw}.h-25{height:25%}.h-50{height:50%}.h-75{height:75%}.h-100{height:100%}.h-auto{height:auto}.mh-100{max-height:100%}.vh-100{height:100vh}.min-vh-100{min-height:100vh}.flex-fill{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.flex-row{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.flex-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.flex-row-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.flex-column-reverse{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flex-grow-0{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.flex-grow-1{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.flex-shrink-0{-ms-flex-negative:0;flex-shrink:0}.flex-shrink-1{-ms-flex-negative:1;flex-shrink:1}.flex-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-nowrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse}.justify-content-start{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.justify-content-end{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.justify-content-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-content-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.justify-content-around{-ms-flex-pack:distribute;justify-content:space-around}.justify-content-evenly{-webkit-box-pack:space-evenly;-ms-flex-pack:space-evenly;justify-content:space-evenly}.align-items-start{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.align-items-end{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.align-items-center{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.align-items-baseline{-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.align-items-stretch{-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch}.align-content-start{-ms-flex-line-pack:start;align-content:flex-start}.align-content-end{-ms-flex-line-pack:end;align-content:flex-end}.align-content-center{-ms-flex-line-pack:center;align-content:center}.align-content-between{-ms-flex-line-pack:justify;align-content:space-between}.align-content-around{-ms-flex-line-pack:distribute;align-content:space-around}.align-content-stretch{-ms-flex-line-pack:stretch;align-content:stretch}.align-self-auto{-ms-flex-item-align:auto;align-self:auto}.align-self-start{-ms-flex-item-align:start;align-self:flex-start}.align-self-end{-ms-flex-item-align:end;align-self:flex-end}.align-self-center{-ms-flex-item-align:center;align-self:center}.align-self-baseline{-ms-flex-item-align:baseline;align-self:baseline}.align-self-stretch{-ms-flex-item-align:stretch;align-self:stretch}.order-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-last{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.m-0{margin:0}.m-1{margin:.25rem}.m-2{margin:.5rem}.m-3{margin:1rem}.m-4{margin:1.5rem}.m-5{margin:3rem}.m-auto{margin:auto}.mx-0{margin-right:0;margin-left:0}.mx-1{margin-right:.25rem;margin-left:.25rem}.mx-2{margin-right:.5rem;margin-left:.5rem}.mx-3{margin-right:1rem;margin-left:1rem}.mx-4{margin-right:1.5rem;margin-left:1.5rem}.mx-5{margin-right:3rem;margin-left:3rem}.mx-auto{margin-right:auto;margin-left:auto}.my-0{margin-top:0;margin-bottom:0}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-3{margin-top:1rem;margin-bottom:1rem}.my-4{margin-top:1.5rem;margin-bottom:1.5rem}.my-5{margin-top:3rem;margin-bottom:3rem}.my-auto{margin-top:auto;margin-bottom:auto}.mt-0{margin-top:0}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:1rem}.mt-4{margin-top:1.5rem}.mt-5{margin-top:3rem}.mt-auto{margin-top:auto}.me-0{margin-right:0}.me-1{margin-right:.25rem}.me-2{margin-right:.5rem}.me-3{margin-right:1rem}.me-4{margin-right:1.5rem}.me-5{margin-right:3rem}.me-auto{margin-right:auto}.mb-0{margin-bottom:0}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.form-group,.mb-3{margin-bottom:1rem}.mb-4{margin-bottom:1.5rem}.mb-5{margin-bottom:3rem}.mb-auto{margin-bottom:auto}.ms-0{margin-left:0}.ms-1{margin-left:.25rem}.ms-2{margin-left:.5rem}.ms-3{margin-left:1rem}.ms-4{margin-left:1.5rem}.ms-5{margin-left:3rem}.ms-auto{margin-left:auto}.p-0{padding:0}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:1rem}.p-4{padding:1.5rem}.p-5{padding:3rem}.px-0{padding-right:0;padding-left:0}.px-1{padding-right:.25rem;padding-left:.25rem}.px-2{padding-right:.5rem;padding-left:.5rem}.px-3{padding-right:1rem;padding-left:1rem}.px-4{padding-right:1.5rem;padding-left:1.5rem}.px-5{padding-right:3rem;padding-left:3rem}.py-0{padding-top:0;padding-bottom:0}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:1rem;padding-bottom:1rem}.py-4{padding-top:1.5rem;padding-bottom:1.5rem}.py-5{padding-top:3rem;padding-bottom:3rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:1rem}.pt-4{padding-top:1.5rem}.pt-5{padding-top:3rem}.pe-0{padding-right:0}.pe-1{padding-right:.25rem}.pe-2{padding-right:.5rem}.pe-3{padding-right:1rem}.pe-4{padding-right:1.5rem}.pe-5{padding-right:3rem}.pb-0{padding-bottom:0}.pb-1{padding-bottom:.25rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:1rem}.pb-4{padding-bottom:1.5rem}.pb-5{padding-bottom:3rem}.ps-0{padding-left:0}.ps-1{padding-left:.25rem}.ps-2{padding-left:.5rem}.ps-3{padding-left:1rem}.ps-4{padding-left:1.5rem}.ps-5{padding-left:3rem}.gap-0{gap:0}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:1rem}.gap-4{gap:1.5rem}.gap-5{gap:3rem}.font-monospace{font-family:var(--font-monospace)}.fs-1{font-size:calc(1.375rem + 1.5vw)}.fs-2{font-size:calc(1.325rem + .9vw)}.fs-3{font-size:calc(1.3rem + .6vw)}.fs-4{font-size:calc(1.275rem + .3vw)}.fs-5{font-size:1.25rem}.fs-6{font-size:1rem}.fst-italic{font-style:italic}.fst-normal{font-style:normal}.fw-light{font-weight:300}.fw-lighter{font-weight:lighter}.fw-normal{font-weight:400}.fw-bold{font-weight:700}.fw-semibold{font-weight:600}.fw-bolder{font-weight:bolder}.lh-1{line-height:1}.lh-sm{line-height:1.25}.lh-base{line-height:1.5}.lh-lg{line-height:2}.text-start{text-align:left}.text-end{text-align:right}.text-center{text-align:center}.text-decoration-none{text-decoration:none}.text-decoration-underline{text-decoration:underline}.text-decoration-line-through{text-decoration:line-through}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-wrap{white-space:normal}.text-nowrap{white-space:nowrap}.text-break{word-wrap:break-word;word-break:break-word}.text-primary{--text-opacity:1;color:rgba(var(--primary-rgb),var(--text-opacity))}.text-secondary{--text-opacity:1;color:rgba(var(--secondary-rgb),var(--text-opacity))}.text-success{--text-opacity:1;color:rgba(var(--success-rgb),var(--text-opacity))}.text-info{--text-opacity:1;color:rgba(var(--info-rgb),var(--text-opacity))}.text-warning{--text-opacity:1;color:rgba(var(--warning-rgb),var(--text-opacity))}.text-danger{--text-opacity:1;color:rgba(var(--danger-rgb),var(--text-opacity))}.text-light{--text-opacity:1;color:rgba(var(--light-rgb),var(--text-opacity))}.text-dark{--text-opacity:1;color:rgba(var(--dark-rgb),var(--text-opacity))}.text-black{--text-opacity:1;color:rgba(var(--black-rgb),var(--text-opacity))}.text-white{--text-opacity:1;color:rgba(var(--white-rgb),var(--text-opacity))}.text-body{--text-opacity:1;color:rgba(var(--body-color-rgb),var(--text-opacity))}.text-muted{--text-opacity:1;color:#6d757d}.text-black-50{--text-opacity:1;color:rgba(0,0,0,.5)}.text-white-50{--text-opacity:1;color:rgba(255,255,255,.5)}.text-reset{--text-opacity:1;color:inherit}.text-opacity-25{--text-opacity:0.25}.text-opacity-50{--text-opacity:0.5}.text-opacity-75{--text-opacity:0.75}.text-opacity-100{--text-opacity:1}.bg-primary{--bg-opacity:1;background-color:rgba(var(--primary-rgb),var(--bg-opacity))}.bg-secondary{--bg-opacity:1;background-color:rgba(var(--secondary-rgb),var(--bg-opacity))}.bg-success{--bg-opacity:1;background-color:rgba(var(--success-rgb),var(--bg-opacity))}.bg-info{--bg-opacity:1;background-color:rgba(var(--info-rgb),var(--bg-opacity))}.bg-warning{--bg-opacity:1;background-color:rgba(var(--warning-rgb),var(--bg-opacity))}.bg-danger{--bg-opacity:1;background-color:rgba(var(--danger-rgb),var(--bg-opacity))}.bg-light{--bg-opacity:1;background-color:rgba(var(--light-rgb),var(--bg-opacity))}.bg-dark{--bg-opacity:1;background-color:rgba(var(--dark-rgb),var(--bg-opacity))}.bg-black{--bg-opacity:1;background-color:rgba(var(--black-rgb),var(--bg-opacity))}.bg-white{--bg-opacity:1;background-color:rgba(var(--white-rgb),var(--bg-opacity))}.bg-body{--bg-opacity:1;background-color:rgba(var(--body-bg-rgb),var(--bg-opacity))}.bg-transparent{--bg-opacity:1;background-color:transparent}.bg-opacity-10{--bg-opacity:0.1}.bg-opacity-25{--bg-opacity:0.25}.bg-opacity-50{--bg-opacity:0.5}.bg-opacity-75{--bg-opacity:0.75}.bg-opacity-100{--bg-opacity:1}.bg-gradient{background-image:var(--gradient)}.user-select-all{-webkit-user-select:all;-moz-user-select:all;user-select:all}.user-select-auto{-webkit-user-select:auto;-moz-user-select:auto;-ms-user-select:auto;user-select:auto}.user-select-none{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.pe-none{pointer-events:none}.pe-auto{pointer-events:auto}.rounded{border-radius:var(--border-radius)}.rounded-0{border-radius:0}.rounded-1{border-radius:var(--border-radius-sm)}.rounded-2{border-radius:var(--border-radius)}.rounded-3{border-radius:var(--border-radius-lg)}.rounded-4{border-radius:var(--border-radius-xl)}.rounded-5{border-radius:var(--border-radius-2xl)}.rounded-circle{border-radius:50%}.rounded-pill{border-radius:var(--border-radius-pill)}.rounded-top{border-top-left-radius:var(--border-radius);border-top-right-radius:var(--border-radius)}.rounded-end{border-top-right-radius:var(--border-radius);border-bottom-right-radius:var(--border-radius)}.rounded-bottom{border-bottom-right-radius:var(--border-radius);border-bottom-left-radius:var(--border-radius)}.rounded-start{border-bottom-left-radius:var(--border-radius);border-top-left-radius:var(--border-radius)}.visible{visibility:visible}.invisible{visibility:hidden}@media (min-width:576px){.float-sm-start{float:left}.float-sm-end{float:right}.float-sm-none{float:none}.d-sm-inline{display:inline}.d-sm-inline-block{display:inline-block}.d-sm-block{display:block}.d-sm-grid{display:grid}.d-sm-table{display:table}.d-sm-table-row{display:table-row}.d-sm-table-cell{display:table-cell}.d-sm-flex{display:-webkit-box;display:-ms-flexbox;display:flex}.d-sm-inline-flex{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.d-sm-none{display:none}.flex-sm-fill{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.flex-sm-row{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.flex-sm-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.flex-sm-row-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.flex-sm-column-reverse{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flex-sm-grow-0{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.flex-sm-grow-1{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.flex-sm-shrink-0{-ms-flex-negative:0;flex-shrink:0}.flex-sm-shrink-1{-ms-flex-negative:1;flex-shrink:1}.flex-sm-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-sm-nowrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse}.justify-content-sm-start{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.justify-content-sm-end{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.justify-content-sm-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-content-sm-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.justify-content-sm-around{-ms-flex-pack:distribute;justify-content:space-around}.justify-content-sm-evenly{-webkit-box-pack:space-evenly;-ms-flex-pack:space-evenly;justify-content:space-evenly}.align-items-sm-start{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.align-items-sm-end{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.align-items-sm-center{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.align-items-sm-baseline{-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.align-items-sm-stretch{-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch}.align-content-sm-start{-ms-flex-line-pack:start;align-content:flex-start}.align-content-sm-end{-ms-flex-line-pack:end;align-content:flex-end}.align-content-sm-center{-ms-flex-line-pack:center;align-content:center}.align-content-sm-between{-ms-flex-line-pack:justify;align-content:space-between}.align-content-sm-around{-ms-flex-line-pack:distribute;align-content:space-around}.align-content-sm-stretch{-ms-flex-line-pack:stretch;align-content:stretch}.align-self-sm-auto{-ms-flex-item-align:auto;align-self:auto}.align-self-sm-start{-ms-flex-item-align:start;align-self:flex-start}.align-self-sm-end{-ms-flex-item-align:end;align-self:flex-end}.align-self-sm-center{-ms-flex-item-align:center;align-self:center}.align-self-sm-baseline{-ms-flex-item-align:baseline;align-self:baseline}.align-self-sm-stretch{-ms-flex-item-align:stretch;align-self:stretch}.order-sm-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-sm-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-sm-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-sm-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-sm-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-sm-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-sm-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-sm-last{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.m-sm-0{margin:0}.m-sm-1{margin:.25rem}.m-sm-2{margin:.5rem}.m-sm-3{margin:1rem}.m-sm-4{margin:1.5rem}.m-sm-5{margin:3rem}.m-sm-auto{margin:auto}.mx-sm-0{margin-right:0;margin-left:0}.mx-sm-1{margin-right:.25rem;margin-left:.25rem}.mx-sm-2{margin-right:.5rem;margin-left:.5rem}.mx-sm-3{margin-right:1rem;margin-left:1rem}.mx-sm-4{margin-right:1.5rem;margin-left:1.5rem}.mx-sm-5{margin-right:3rem;margin-left:3rem}.mx-sm-auto{margin-right:auto;margin-left:auto}.my-sm-0{margin-top:0;margin-bottom:0}.my-sm-1{margin-top:.25rem;margin-bottom:.25rem}.my-sm-2{margin-top:.5rem;margin-bottom:.5rem}.my-sm-3{margin-top:1rem;margin-bottom:1rem}.my-sm-4{margin-top:1.5rem;margin-bottom:1.5rem}.my-sm-5{margin-top:3rem;margin-bottom:3rem}.my-sm-auto{margin-top:auto;margin-bottom:auto}.mt-sm-0{margin-top:0}.mt-sm-1{margin-top:.25rem}.mt-sm-2{margin-top:.5rem}.mt-sm-3{margin-top:1rem}.mt-sm-4{margin-top:1.5rem}.mt-sm-5{margin-top:3rem}.mt-sm-auto{margin-top:auto}.me-sm-0{margin-right:0}.me-sm-1{margin-right:.25rem}.me-sm-2{margin-right:.5rem}.me-sm-3{margin-right:1rem}.me-sm-4{margin-right:1.5rem}.me-sm-5{margin-right:3rem}.me-sm-auto{margin-right:auto}.mb-sm-0{margin-bottom:0}.mb-sm-1{margin-bottom:.25rem}.mb-sm-2{margin-bottom:.5rem}.mb-sm-3{margin-bottom:1rem}.mb-sm-4{margin-bottom:1.5rem}.mb-sm-5{margin-bottom:3rem}.mb-sm-auto{margin-bottom:auto}.ms-sm-0{margin-left:0}.ms-sm-1{margin-left:.25rem}.ms-sm-2{margin-left:.5rem}.ms-sm-3{margin-left:1rem}.ms-sm-4{margin-left:1.5rem}.ms-sm-5{margin-left:3rem}.ms-sm-auto{margin-left:auto}.p-sm-0{padding:0}.p-sm-1{padding:.25rem}.p-sm-2{padding:.5rem}.p-sm-3{padding:1rem}.p-sm-4{padding:1.5rem}.p-sm-5{padding:3rem}.px-sm-0{padding-right:0;padding-left:0}.px-sm-1{padding-right:.25rem;padding-left:.25rem}.px-sm-2{padding-right:.5rem;padding-left:.5rem}.px-sm-3{padding-right:1rem;padding-left:1rem}.px-sm-4{padding-right:1.5rem;padding-left:1.5rem}.px-sm-5{padding-right:3rem;padding-left:3rem}.py-sm-0{padding-top:0;padding-bottom:0}.py-sm-1{padding-top:.25rem;padding-bottom:.25rem}.py-sm-2{padding-top:.5rem;padding-bottom:.5rem}.py-sm-3{padding-top:1rem;padding-bottom:1rem}.py-sm-4{padding-top:1.5rem;padding-bottom:1.5rem}.py-sm-5{padding-top:3rem;padding-bottom:3rem}.pt-sm-0{padding-top:0}.pt-sm-1{padding-top:.25rem}.pt-sm-2{padding-top:.5rem}.pt-sm-3{padding-top:1rem}.pt-sm-4{padding-top:1.5rem}.pt-sm-5{padding-top:3rem}.pe-sm-0{padding-right:0}.pe-sm-1{padding-right:.25rem}.pe-sm-2{padding-right:.5rem}.pe-sm-3{padding-right:1rem}.pe-sm-4{padding-right:1.5rem}.pe-sm-5{padding-right:3rem}.pb-sm-0{padding-bottom:0}.pb-sm-1{padding-bottom:.25rem}.pb-sm-2{padding-bottom:.5rem}.pb-sm-3{padding-bottom:1rem}.pb-sm-4{padding-bottom:1.5rem}.pb-sm-5{padding-bottom:3rem}.ps-sm-0{padding-left:0}.ps-sm-1{padding-left:.25rem}.ps-sm-2{padding-left:.5rem}.ps-sm-3{padding-left:1rem}.ps-sm-4{padding-left:1.5rem}.ps-sm-5{padding-left:3rem}.gap-sm-0{gap:0}.gap-sm-1{gap:.25rem}.gap-sm-2{gap:.5rem}.gap-sm-3{gap:1rem}.gap-sm-4{gap:1.5rem}.gap-sm-5{gap:3rem}.text-sm-start{text-align:left}.text-sm-end{text-align:right}.text-sm-center{text-align:center}}@media (min-width:768px){.float-md-start{float:left}.float-md-end{float:right}.float-md-none{float:none}.d-md-inline{display:inline}.d-md-inline-block{display:inline-block}.d-md-block{display:block}.d-md-grid{display:grid}.d-md-table{display:table}.d-md-table-row{display:table-row}.d-md-table-cell{display:table-cell}.d-md-flex{display:-webkit-box;display:-ms-flexbox;display:flex}.d-md-inline-flex{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.d-md-none{display:none}.flex-md-fill{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.flex-md-row{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.flex-md-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.flex-md-row-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.flex-md-column-reverse{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flex-md-grow-0{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.flex-md-grow-1{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.flex-md-shrink-0{-ms-flex-negative:0;flex-shrink:0}.flex-md-shrink-1{-ms-flex-negative:1;flex-shrink:1}.flex-md-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-md-nowrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse}.justify-content-md-start{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.justify-content-md-end{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.justify-content-md-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-content-md-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.justify-content-md-around{-ms-flex-pack:distribute;justify-content:space-around}.justify-content-md-evenly{-webkit-box-pack:space-evenly;-ms-flex-pack:space-evenly;justify-content:space-evenly}.align-items-md-start{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.align-items-md-end{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.align-items-md-center{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.align-items-md-baseline{-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.align-items-md-stretch{-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch}.align-content-md-start{-ms-flex-line-pack:start;align-content:flex-start}.align-content-md-end{-ms-flex-line-pack:end;align-content:flex-end}.align-content-md-center{-ms-flex-line-pack:center;align-content:center}.align-content-md-between{-ms-flex-line-pack:justify;align-content:space-between}.align-content-md-around{-ms-flex-line-pack:distribute;align-content:space-around}.align-content-md-stretch{-ms-flex-line-pack:stretch;align-content:stretch}.align-self-md-auto{-ms-flex-item-align:auto;align-self:auto}.align-self-md-start{-ms-flex-item-align:start;align-self:flex-start}.align-self-md-end{-ms-flex-item-align:end;align-self:flex-end}.align-self-md-center{-ms-flex-item-align:center;align-self:center}.align-self-md-baseline{-ms-flex-item-align:baseline;align-self:baseline}.align-self-md-stretch{-ms-flex-item-align:stretch;align-self:stretch}.order-md-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-md-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-md-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-md-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-md-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-md-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-md-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-md-last{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.m-md-0{margin:0}.m-md-1{margin:.25rem}.m-md-2{margin:.5rem}.m-md-3{margin:1rem}.m-md-4{margin:1.5rem}.m-md-5{margin:3rem}.m-md-auto{margin:auto}.mx-md-0{margin-right:0;margin-left:0}.mx-md-1{margin-right:.25rem;margin-left:.25rem}.mx-md-2{margin-right:.5rem;margin-left:.5rem}.mx-md-3{margin-right:1rem;margin-left:1rem}.mx-md-4{margin-right:1.5rem;margin-left:1.5rem}.mx-md-5{margin-right:3rem;margin-left:3rem}.mx-md-auto{margin-right:auto;margin-left:auto}.my-md-0{margin-top:0;margin-bottom:0}.my-md-1{margin-top:.25rem;margin-bottom:.25rem}.my-md-2{margin-top:.5rem;margin-bottom:.5rem}.my-md-3{margin-top:1rem;margin-bottom:1rem}.my-md-4{margin-top:1.5rem;margin-bottom:1.5rem}.my-md-5{margin-top:3rem;margin-bottom:3rem}.my-md-auto{margin-top:auto;margin-bottom:auto}.mt-md-0{margin-top:0}.mt-md-1{margin-top:.25rem}.mt-md-2{margin-top:.5rem}.mt-md-3{margin-top:1rem}.mt-md-4{margin-top:1.5rem}.mt-md-5{margin-top:3rem}.mt-md-auto{margin-top:auto}.me-md-0{margin-right:0}.me-md-1{margin-right:.25rem}.me-md-2{margin-right:.5rem}.me-md-3{margin-right:1rem}.me-md-4{margin-right:1.5rem}.me-md-5{margin-right:3rem}.me-md-auto{margin-right:auto}.mb-md-0{margin-bottom:0}.mb-md-1{margin-bottom:.25rem}.mb-md-2{margin-bottom:.5rem}.mb-md-3{margin-bottom:1rem}.mb-md-4{margin-bottom:1.5rem}.mb-md-5{margin-bottom:3rem}.mb-md-auto{margin-bottom:auto}.ms-md-0{margin-left:0}.ms-md-1{margin-left:.25rem}.ms-md-2{margin-left:.5rem}.ms-md-3{margin-left:1rem}.ms-md-4{margin-left:1.5rem}.ms-md-5{margin-left:3rem}.ms-md-auto{margin-left:auto}.p-md-0{padding:0}.p-md-1{padding:.25rem}.p-md-2{padding:.5rem}.p-md-3{padding:1rem}.p-md-4{padding:1.5rem}.p-md-5{padding:3rem}.px-md-0{padding-right:0;padding-left:0}.px-md-1{padding-right:.25rem;padding-left:.25rem}.px-md-2{padding-right:.5rem;padding-left:.5rem}.px-md-3{padding-right:1rem;padding-left:1rem}.px-md-4{padding-right:1.5rem;padding-left:1.5rem}.px-md-5{padding-right:3rem;padding-left:3rem}.py-md-0{padding-top:0;padding-bottom:0}.py-md-1{padding-top:.25rem;padding-bottom:.25rem}.py-md-2{padding-top:.5rem;padding-bottom:.5rem}.py-md-3{padding-top:1rem;padding-bottom:1rem}.py-md-4{padding-top:1.5rem;padding-bottom:1.5rem}.py-md-5{padding-top:3rem;padding-bottom:3rem}.pt-md-0{padding-top:0}.pt-md-1{padding-top:.25rem}.pt-md-2{padding-top:.5rem}.pt-md-3{padding-top:1rem}.pt-md-4{padding-top:1.5rem}.pt-md-5{padding-top:3rem}.pe-md-0{padding-right:0}.pe-md-1{padding-right:.25rem}.pe-md-2{padding-right:.5rem}.pe-md-3{padding-right:1rem}.pe-md-4{padding-right:1.5rem}.pe-md-5{padding-right:3rem}.pb-md-0{padding-bottom:0}.pb-md-1{padding-bottom:.25rem}.pb-md-2{padding-bottom:.5rem}.pb-md-3{padding-bottom:1rem}.pb-md-4{padding-bottom:1.5rem}.pb-md-5{padding-bottom:3rem}.ps-md-0{padding-left:0}.ps-md-1{padding-left:.25rem}.ps-md-2{padding-left:.5rem}.ps-md-3{padding-left:1rem}.ps-md-4{padding-left:1.5rem}.ps-md-5{padding-left:3rem}.gap-md-0{gap:0}.gap-md-1{gap:.25rem}.gap-md-2{gap:.5rem}.gap-md-3{gap:1rem}.gap-md-4{gap:1.5rem}.gap-md-5{gap:3rem}.text-md-start{text-align:left}.text-md-end{text-align:right}.text-md-center{text-align:center}}@media (min-width:992px){.float-lg-start{float:left}.float-lg-end{float:right}.float-lg-none{float:none}.d-lg-inline{display:inline}.d-lg-inline-block{display:inline-block}.d-lg-block{display:block}.d-lg-grid{display:grid}.d-lg-table{display:table}.d-lg-table-row{display:table-row}.d-lg-table-cell{display:table-cell}.d-lg-flex{display:-webkit-box;display:-ms-flexbox;display:flex}.d-lg-inline-flex{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.d-lg-none{display:none}.flex-lg-fill{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.flex-lg-row{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.flex-lg-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.flex-lg-row-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.flex-lg-column-reverse{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flex-lg-grow-0{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.flex-lg-grow-1{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.flex-lg-shrink-0{-ms-flex-negative:0;flex-shrink:0}.flex-lg-shrink-1{-ms-flex-negative:1;flex-shrink:1}.flex-lg-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-lg-nowrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse}.justify-content-lg-start{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.justify-content-lg-end{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.justify-content-lg-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-content-lg-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.justify-content-lg-around{-ms-flex-pack:distribute;justify-content:space-around}.justify-content-lg-evenly{-webkit-box-pack:space-evenly;-ms-flex-pack:space-evenly;justify-content:space-evenly}.align-items-lg-start{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.align-items-lg-end{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.align-items-lg-center{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.align-items-lg-baseline{-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.align-items-lg-stretch{-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch}.align-content-lg-start{-ms-flex-line-pack:start;align-content:flex-start}.align-content-lg-end{-ms-flex-line-pack:end;align-content:flex-end}.align-content-lg-center{-ms-flex-line-pack:center;align-content:center}.align-content-lg-between{-ms-flex-line-pack:justify;align-content:space-between}.align-content-lg-around{-ms-flex-line-pack:distribute;align-content:space-around}.align-content-lg-stretch{-ms-flex-line-pack:stretch;align-content:stretch}.align-self-lg-auto{-ms-flex-item-align:auto;align-self:auto}.align-self-lg-start{-ms-flex-item-align:start;align-self:flex-start}.align-self-lg-end{-ms-flex-item-align:end;align-self:flex-end}.align-self-lg-center{-ms-flex-item-align:center;align-self:center}.align-self-lg-baseline{-ms-flex-item-align:baseline;align-self:baseline}.align-self-lg-stretch{-ms-flex-item-align:stretch;align-self:stretch}.order-lg-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-lg-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-lg-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-lg-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-lg-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-lg-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-lg-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-lg-last{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.m-lg-0{margin:0}.m-lg-1{margin:.25rem}.m-lg-2{margin:.5rem}.m-lg-3{margin:1rem}.m-lg-4{margin:1.5rem}.m-lg-5{margin:3rem}.m-lg-auto{margin:auto}.mx-lg-0{margin-right:0;margin-left:0}.mx-lg-1{margin-right:.25rem;margin-left:.25rem}.mx-lg-2{margin-right:.5rem;margin-left:.5rem}.mx-lg-3{margin-right:1rem;margin-left:1rem}.mx-lg-4{margin-right:1.5rem;margin-left:1.5rem}.mx-lg-5{margin-right:3rem;margin-left:3rem}.mx-lg-auto{margin-right:auto;margin-left:auto}.my-lg-0{margin-top:0;margin-bottom:0}.my-lg-1{margin-top:.25rem;margin-bottom:.25rem}.my-lg-2{margin-top:.5rem;margin-bottom:.5rem}.my-lg-3{margin-top:1rem;margin-bottom:1rem}.my-lg-4{margin-top:1.5rem;margin-bottom:1.5rem}.my-lg-5{margin-top:3rem;margin-bottom:3rem}.my-lg-auto{margin-top:auto;margin-bottom:auto}.mt-lg-0{margin-top:0}.mt-lg-1{margin-top:.25rem}.mt-lg-2{margin-top:.5rem}.mt-lg-3{margin-top:1rem}.mt-lg-4{margin-top:1.5rem}.mt-lg-5{margin-top:3rem}.mt-lg-auto{margin-top:auto}.me-lg-0{margin-right:0}.me-lg-1{margin-right:.25rem}.me-lg-2{margin-right:.5rem}.me-lg-3{margin-right:1rem}.me-lg-4{margin-right:1.5rem}.me-lg-5{margin-right:3rem}.me-lg-auto{margin-right:auto}.mb-lg-0{margin-bottom:0}.mb-lg-1{margin-bottom:.25rem}.mb-lg-2{margin-bottom:.5rem}.mb-lg-3{margin-bottom:1rem}.mb-lg-4{margin-bottom:1.5rem}.mb-lg-5{margin-bottom:3rem}.mb-lg-auto{margin-bottom:auto}.ms-lg-0{margin-left:0}.ms-lg-1{margin-left:.25rem}.ms-lg-2{margin-left:.5rem}.ms-lg-3{margin-left:1rem}.ms-lg-4{margin-left:1.5rem}.ms-lg-5{margin-left:3rem}.ms-lg-auto{margin-left:auto}.p-lg-0{padding:0}.p-lg-1{padding:.25rem}.p-lg-2{padding:.5rem}.p-lg-3{padding:1rem}.p-lg-4{padding:1.5rem}.p-lg-5{padding:3rem}.px-lg-0{padding-right:0;padding-left:0}.px-lg-1{padding-right:.25rem;padding-left:.25rem}.px-lg-2{padding-right:.5rem;padding-left:.5rem}.px-lg-3{padding-right:1rem;padding-left:1rem}.px-lg-4{padding-right:1.5rem;padding-left:1.5rem}.px-lg-5{padding-right:3rem;padding-left:3rem}.py-lg-0{padding-top:0;padding-bottom:0}.py-lg-1{padding-top:.25rem;padding-bottom:.25rem}.py-lg-2{padding-top:.5rem;padding-bottom:.5rem}.py-lg-3{padding-top:1rem;padding-bottom:1rem}.py-lg-4{padding-top:1.5rem;padding-bottom:1.5rem}.py-lg-5{padding-top:3rem;padding-bottom:3rem}.pt-lg-0{padding-top:0}.pt-lg-1{padding-top:.25rem}.pt-lg-2{padding-top:.5rem}.pt-lg-3{padding-top:1rem}.pt-lg-4{padding-top:1.5rem}.pt-lg-5{padding-top:3rem}.pe-lg-0{padding-right:0}.pe-lg-1{padding-right:.25rem}.pe-lg-2{padding-right:.5rem}.pe-lg-3{padding-right:1rem}.pe-lg-4{padding-right:1.5rem}.pe-lg-5{padding-right:3rem}.pb-lg-0{padding-bottom:0}.pb-lg-1{padding-bottom:.25rem}.pb-lg-2{padding-bottom:.5rem}.pb-lg-3{padding-bottom:1rem}.pb-lg-4{padding-bottom:1.5rem}.pb-lg-5{padding-bottom:3rem}.ps-lg-0{padding-left:0}.ps-lg-1{padding-left:.25rem}.ps-lg-2{padding-left:.5rem}.ps-lg-3{padding-left:1rem}.ps-lg-4{padding-left:1.5rem}.ps-lg-5{padding-left:3rem}.gap-lg-0{gap:0}.gap-lg-1{gap:.25rem}.gap-lg-2{gap:.5rem}.gap-lg-3{gap:1rem}.gap-lg-4{gap:1.5rem}.gap-lg-5{gap:3rem}.text-lg-start{text-align:left}.text-lg-end{text-align:right}.text-lg-center{text-align:center}}@media (min-width:1200px){.float-xl-start{float:left}.float-xl-end{float:right}.float-xl-none{float:none}.d-xl-inline{display:inline}.d-xl-inline-block{display:inline-block}.d-xl-block{display:block}.d-xl-grid{display:grid}.d-xl-table{display:table}.d-xl-table-row{display:table-row}.d-xl-table-cell{display:table-cell}.d-xl-flex{display:-webkit-box;display:-ms-flexbox;display:flex}.d-xl-inline-flex{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.d-xl-none{display:none}.flex-xl-fill{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.flex-xl-row{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.flex-xl-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.flex-xl-row-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.flex-xl-column-reverse{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flex-xl-grow-0{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.flex-xl-grow-1{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.flex-xl-shrink-0{-ms-flex-negative:0;flex-shrink:0}.flex-xl-shrink-1{-ms-flex-negative:1;flex-shrink:1}.flex-xl-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-xl-nowrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse}.justify-content-xl-start{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.justify-content-xl-end{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.justify-content-xl-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-content-xl-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.justify-content-xl-around{-ms-flex-pack:distribute;justify-content:space-around}.justify-content-xl-evenly{-webkit-box-pack:space-evenly;-ms-flex-pack:space-evenly;justify-content:space-evenly}.align-items-xl-start{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.align-items-xl-end{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.align-items-xl-center{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.align-items-xl-baseline{-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.align-items-xl-stretch{-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch}.align-content-xl-start{-ms-flex-line-pack:start;align-content:flex-start}.align-content-xl-end{-ms-flex-line-pack:end;align-content:flex-end}.align-content-xl-center{-ms-flex-line-pack:center;align-content:center}.align-content-xl-between{-ms-flex-line-pack:justify;align-content:space-between}.align-content-xl-around{-ms-flex-line-pack:distribute;align-content:space-around}.align-content-xl-stretch{-ms-flex-line-pack:stretch;align-content:stretch}.align-self-xl-auto{-ms-flex-item-align:auto;align-self:auto}.align-self-xl-start{-ms-flex-item-align:start;align-self:flex-start}.align-self-xl-end{-ms-flex-item-align:end;align-self:flex-end}.align-self-xl-center{-ms-flex-item-align:center;align-self:center}.align-self-xl-baseline{-ms-flex-item-align:baseline;align-self:baseline}.align-self-xl-stretch{-ms-flex-item-align:stretch;align-self:stretch}.order-xl-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-xl-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-xl-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-xl-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-xl-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-xl-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-xl-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-xl-last{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.m-xl-0{margin:0}.m-xl-1{margin:.25rem}.m-xl-2{margin:.5rem}.m-xl-3{margin:1rem}.m-xl-4{margin:1.5rem}.m-xl-5{margin:3rem}.m-xl-auto{margin:auto}.mx-xl-0{margin-right:0;margin-left:0}.mx-xl-1{margin-right:.25rem;margin-left:.25rem}.mx-xl-2{margin-right:.5rem;margin-left:.5rem}.mx-xl-3{margin-right:1rem;margin-left:1rem}.mx-xl-4{margin-right:1.5rem;margin-left:1.5rem}.mx-xl-5{margin-right:3rem;margin-left:3rem}.mx-xl-auto{margin-right:auto;margin-left:auto}.my-xl-0{margin-top:0;margin-bottom:0}.my-xl-1{margin-top:.25rem;margin-bottom:.25rem}.my-xl-2{margin-top:.5rem;margin-bottom:.5rem}.my-xl-3{margin-top:1rem;margin-bottom:1rem}.my-xl-4{margin-top:1.5rem;margin-bottom:1.5rem}.my-xl-5{margin-top:3rem;margin-bottom:3rem}.my-xl-auto{margin-top:auto;margin-bottom:auto}.mt-xl-0{margin-top:0}.mt-xl-1{margin-top:.25rem}.mt-xl-2{margin-top:.5rem}.mt-xl-3{margin-top:1rem}.mt-xl-4{margin-top:1.5rem}.mt-xl-5{margin-top:3rem}.mt-xl-auto{margin-top:auto}.me-xl-0{margin-right:0}.me-xl-1{margin-right:.25rem}.me-xl-2{margin-right:.5rem}.me-xl-3{margin-right:1rem}.me-xl-4{margin-right:1.5rem}.me-xl-5{margin-right:3rem}.me-xl-auto{margin-right:auto}.mb-xl-0{margin-bottom:0}.mb-xl-1{margin-bottom:.25rem}.mb-xl-2{margin-bottom:.5rem}.mb-xl-3{margin-bottom:1rem}.mb-xl-4{margin-bottom:1.5rem}.mb-xl-5{margin-bottom:3rem}.mb-xl-auto{margin-bottom:auto}.ms-xl-0{margin-left:0}.ms-xl-1{margin-left:.25rem}.ms-xl-2{margin-left:.5rem}.ms-xl-3{margin-left:1rem}.ms-xl-4{margin-left:1.5rem}.ms-xl-5{margin-left:3rem}.ms-xl-auto{margin-left:auto}.p-xl-0{padding:0}.p-xl-1{padding:.25rem}.p-xl-2{padding:.5rem}.p-xl-3{padding:1rem}.p-xl-4{padding:1.5rem}.p-xl-5{padding:3rem}.px-xl-0{padding-right:0;padding-left:0}.px-xl-1{padding-right:.25rem;padding-left:.25rem}.px-xl-2{padding-right:.5rem;padding-left:.5rem}.px-xl-3{padding-right:1rem;padding-left:1rem}.px-xl-4{padding-right:1.5rem;padding-left:1.5rem}.px-xl-5{padding-right:3rem;padding-left:3rem}.py-xl-0{padding-top:0;padding-bottom:0}.py-xl-1{padding-top:.25rem;padding-bottom:.25rem}.py-xl-2{padding-top:.5rem;padding-bottom:.5rem}.py-xl-3{padding-top:1rem;padding-bottom:1rem}.py-xl-4{padding-top:1.5rem;padding-bottom:1.5rem}.py-xl-5{padding-top:3rem;padding-bottom:3rem}.pt-xl-0{padding-top:0}.pt-xl-1{padding-top:.25rem}.pt-xl-2{padding-top:.5rem}.pt-xl-3{padding-top:1rem}.pt-xl-4{padding-top:1.5rem}.pt-xl-5{padding-top:3rem}.pe-xl-0{padding-right:0}.pe-xl-1{padding-right:.25rem}.pe-xl-2{padding-right:.5rem}.pe-xl-3{padding-right:1rem}.pe-xl-4{padding-right:1.5rem}.pe-xl-5{padding-right:3rem}.pb-xl-0{padding-bottom:0}.pb-xl-1{padding-bottom:.25rem}.pb-xl-2{padding-bottom:.5rem}.pb-xl-3{padding-bottom:1rem}.pb-xl-4{padding-bottom:1.5rem}.pb-xl-5{padding-bottom:3rem}.ps-xl-0{padding-left:0}.ps-xl-1{padding-left:.25rem}.ps-xl-2{padding-left:.5rem}.ps-xl-3{padding-left:1rem}.ps-xl-4{padding-left:1.5rem}.ps-xl-5{padding-left:3rem}.gap-xl-0{gap:0}.gap-xl-1{gap:.25rem}.gap-xl-2{gap:.5rem}.gap-xl-3{gap:1rem}.gap-xl-4{gap:1.5rem}.gap-xl-5{gap:3rem}.text-xl-start{text-align:left}.text-xl-end{text-align:right}.text-xl-center{text-align:center}.fs-1{font-size:2.5rem}.fs-2{font-size:2rem}.fs-3{font-size:1.75rem}.fs-4{font-size:1.5rem}}@media (min-width:1400px){.float-xxl-start{float:left}.float-xxl-end{float:right}.float-xxl-none{float:none}.d-xxl-inline{display:inline}.d-xxl-inline-block{display:inline-block}.d-xxl-block{display:block}.d-xxl-grid{display:grid}.d-xxl-table{display:table}.d-xxl-table-row{display:table-row}.d-xxl-table-cell{display:table-cell}.d-xxl-flex{display:-webkit-box;display:-ms-flexbox;display:flex}.d-xxl-inline-flex{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.d-xxl-none{display:none}.flex-xxl-fill{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.flex-xxl-row{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.flex-xxl-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.flex-xxl-row-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.flex-xxl-column-reverse{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flex-xxl-grow-0{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.flex-xxl-grow-1{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.flex-xxl-shrink-0{-ms-flex-negative:0;flex-shrink:0}.flex-xxl-shrink-1{-ms-flex-negative:1;flex-shrink:1}.flex-xxl-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-xxl-nowrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-xxl-wrap-reverse{-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse}.justify-content-xxl-start{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.justify-content-xxl-end{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.justify-content-xxl-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-content-xxl-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.justify-content-xxl-around{-ms-flex-pack:distribute;justify-content:space-around}.justify-content-xxl-evenly{-webkit-box-pack:space-evenly;-ms-flex-pack:space-evenly;justify-content:space-evenly}.align-items-xxl-start{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.align-items-xxl-end{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.align-items-xxl-center{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.align-items-xxl-baseline{-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.align-items-xxl-stretch{-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch}.align-content-xxl-start{-ms-flex-line-pack:start;align-content:flex-start}.align-content-xxl-end{-ms-flex-line-pack:end;align-content:flex-end}.align-content-xxl-center{-ms-flex-line-pack:center;align-content:center}.align-content-xxl-between{-ms-flex-line-pack:justify;align-content:space-between}.align-content-xxl-around{-ms-flex-line-pack:distribute;align-content:space-around}.align-content-xxl-stretch{-ms-flex-line-pack:stretch;align-content:stretch}.align-self-xxl-auto{-ms-flex-item-align:auto;align-self:auto}.align-self-xxl-start{-ms-flex-item-align:start;align-self:flex-start}.align-self-xxl-end{-ms-flex-item-align:end;align-self:flex-end}.align-self-xxl-center{-ms-flex-item-align:center;align-self:center}.align-self-xxl-baseline{-ms-flex-item-align:baseline;align-self:baseline}.align-self-xxl-stretch{-ms-flex-item-align:stretch;align-self:stretch}.order-xxl-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-xxl-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-xxl-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-xxl-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-xxl-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-xxl-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-xxl-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-xxl-last{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.m-xxl-0{margin:0}.m-xxl-1{margin:.25rem}.m-xxl-2{margin:.5rem}.m-xxl-3{margin:1rem}.m-xxl-4{margin:1.5rem}.m-xxl-5{margin:3rem}.m-xxl-auto{margin:auto}.mx-xxl-0{margin-right:0;margin-left:0}.mx-xxl-1{margin-right:.25rem;margin-left:.25rem}.mx-xxl-2{margin-right:.5rem;margin-left:.5rem}.mx-xxl-3{margin-right:1rem;margin-left:1rem}.mx-xxl-4{margin-right:1.5rem;margin-left:1.5rem}.mx-xxl-5{margin-right:3rem;margin-left:3rem}.mx-xxl-auto{margin-right:auto;margin-left:auto}.my-xxl-0{margin-top:0;margin-bottom:0}.my-xxl-1{margin-top:.25rem;margin-bottom:.25rem}.my-xxl-2{margin-top:.5rem;margin-bottom:.5rem}.my-xxl-3{margin-top:1rem;margin-bottom:1rem}.my-xxl-4{margin-top:1.5rem;margin-bottom:1.5rem}.my-xxl-5{margin-top:3rem;margin-bottom:3rem}.my-xxl-auto{margin-top:auto;margin-bottom:auto}.mt-xxl-0{margin-top:0}.mt-xxl-1{margin-top:.25rem}.mt-xxl-2{margin-top:.5rem}.mt-xxl-3{margin-top:1rem}.mt-xxl-4{margin-top:1.5rem}.mt-xxl-5{margin-top:3rem}.mt-xxl-auto{margin-top:auto}.me-xxl-0{margin-right:0}.me-xxl-1{margin-right:.25rem}.me-xxl-2{margin-right:.5rem}.me-xxl-3{margin-right:1rem}.me-xxl-4{margin-right:1.5rem}.me-xxl-5{margin-right:3rem}.me-xxl-auto{margin-right:auto}.mb-xxl-0{margin-bottom:0}.mb-xxl-1{margin-bottom:.25rem}.mb-xxl-2{margin-bottom:.5rem}.mb-xxl-3{margin-bottom:1rem}.mb-xxl-4{margin-bottom:1.5rem}.mb-xxl-5{margin-bottom:3rem}.mb-xxl-auto{margin-bottom:auto}.ms-xxl-0{margin-left:0}.ms-xxl-1{margin-left:.25rem}.ms-xxl-2{margin-left:.5rem}.ms-xxl-3{margin-left:1rem}.ms-xxl-4{margin-left:1.5rem}.ms-xxl-5{margin-left:3rem}.ms-xxl-auto{margin-left:auto}.p-xxl-0{padding:0}.p-xxl-1{padding:.25rem}.p-xxl-2{padding:.5rem}.p-xxl-3{padding:1rem}.p-xxl-4{padding:1.5rem}.p-xxl-5{padding:3rem}.px-xxl-0{padding-right:0;padding-left:0}.px-xxl-1{padding-right:.25rem;padding-left:.25rem}.px-xxl-2{padding-right:.5rem;padding-left:.5rem}.px-xxl-3{padding-right:1rem;padding-left:1rem}.px-xxl-4{padding-right:1.5rem;padding-left:1.5rem}.px-xxl-5{padding-right:3rem;padding-left:3rem}.py-xxl-0{padding-top:0;padding-bottom:0}.py-xxl-1{padding-top:.25rem;padding-bottom:.25rem}.py-xxl-2{padding-top:.5rem;padding-bottom:.5rem}.py-xxl-3{padding-top:1rem;padding-bottom:1rem}.py-xxl-4{padding-top:1.5rem;padding-bottom:1.5rem}.py-xxl-5{padding-top:3rem;padding-bottom:3rem}.pt-xxl-0{padding-top:0}.pt-xxl-1{padding-top:.25rem}.pt-xxl-2{padding-top:.5rem}.pt-xxl-3{padding-top:1rem}.pt-xxl-4{padding-top:1.5rem}.pt-xxl-5{padding-top:3rem}.pe-xxl-0{padding-right:0}.pe-xxl-1{padding-right:.25rem}.pe-xxl-2{padding-right:.5rem}.pe-xxl-3{padding-right:1rem}.pe-xxl-4{padding-right:1.5rem}.pe-xxl-5{padding-right:3rem}.pb-xxl-0{padding-bottom:0}.pb-xxl-1{padding-bottom:.25rem}.pb-xxl-2{padding-bottom:.5rem}.pb-xxl-3{padding-bottom:1rem}.pb-xxl-4{padding-bottom:1.5rem}.pb-xxl-5{padding-bottom:3rem}.ps-xxl-0{padding-left:0}.ps-xxl-1{padding-left:.25rem}.ps-xxl-2{padding-left:.5rem}.ps-xxl-3{padding-left:1rem}.ps-xxl-4{padding-left:1.5rem}.ps-xxl-5{padding-left:3rem}.gap-xxl-0{gap:0}.gap-xxl-1{gap:.25rem}.gap-xxl-2{gap:.5rem}.gap-xxl-3{gap:1rem}.gap-xxl-4{gap:1.5rem}.gap-xxl-5{gap:3rem}.text-xxl-start{text-align:left}.text-xxl-end{text-align:right}.text-xxl-center{text-align:center}}@media print{.d-print-inline{display:inline}.d-print-inline-block{display:inline-block}.d-print-block{display:block}.d-print-grid{display:grid}.d-print-table{display:table}.d-print-table-row{display:table-row}.d-print-table-cell{display:table-cell}.d-print-flex{display:-webkit-box;display:-ms-flexbox;display:flex}.d-print-inline-flex{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.d-print-none{display:none}}.minicolors-theme-bootstrap .minicolors-swatch{width:36px;height:36px}.minicolors-theme-bootstrap .minicolors-swatch>.minicolors-sprite{top:50%;left:8px;border-radius:0;-webkit-transform:translateY(-50%);transform:translateY(-50%)}span.minicolors-swatch-color{cursor:pointer}:root{scroll-behavior:smooth;--template-sidebar-bg:var(--template-bg-dark-80);--template-sidebar-font-color:var(--body-color);--template-sidebar-link-color:var(--body-color);--template-bg-light:#f0f4fb;--template-text-light:var(--body-color);--template-special-color:#132f53;--template-link-color:#2a69b8;--template-link-active-color:#173a65;--template-contrast:#2a69b8;--template-bg-dark:hsl(var(--hue), 40%, 20%);--template-bg-dark-3:hsl(var(--hue), 40%, 97%);--template-bg-dark-5:hsl(var(--hue), 40%, 95%);--template-bg-dark-7:hsl(var(--hue), 40%, 93%);--template-bg-dark-10:hsl(var(--hue), 40%, 90%);--template-bg-dark-15:hsl(var(--hue), 40%, 85%);--template-bg-dark-20:hsl(var(--hue), 40%, 80%);--template-bg-dark-30:hsl(var(--hue), 40%, 70%);--template-bg-dark-40:hsl(var(--hue), 40%, 60%);--template-bg-dark-50:hsl(var(--hue), 40%, 50%);--template-bg-dark-60:hsl(var(--hue), 40%, 40%);--template-bg-dark-65:hsl(var(--hue), 40%, 35%);--template-bg-dark-70:hsl(var(--hue), 40%, 30%);--template-bg-dark-75:hsl(var(--hue), 40%, 25%);--template-bg-dark-80:hsl(var(--hue), 40%, 20%);--template-bg-dark-90:hsl(var(--hue), 40%, 10%)}@media screen and (prefers-reduced-motion:reduce){:root{scroll-behavior:auto}}html{background-color:var(--body-bg)}img{max-width:100%;height:auto}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:var(--font-family-headings, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-weight:var(--font-weight-headings,700)}.display-1{font-size:clamp(2.7rem, 8vw, 5.5rem)}.display-2{font-size:clamp(2.3rem, 7vw, 4.5rem)}.display-3{font-size:clamp(1.9rem, 6vw, 3.5rem)}.display-4{font-size:clamp(1.5rem, 5vw, 2.5rem)}.lead{font-size:clamp(1.1rem, 3vw, 1.25rem)}a:not([class]){text-decoration:underline}a:active,a:focus{color:var(--color-active)}a.navbar-brand{color:var(--color-brand)}.btn-primary{background-color:var(--color-primary);border-color:var(--color-primary);--bs-btn-bg:#333;--bs-btn-border-color:#333;--bs-btn-hover-bg:#555;--bs-btn-hover-border-color:#555;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-bg:#555;--bs-btn-active-border-color:#555;--bs-btn-disabled-bg:#A0A0A0;--bs-btn-disabled-border-color:#A0A0A0;--btn-color:white;--btn-bg:var(--color-primary);--btn-border-color:var(--color-primary);--btn-hover-bg:color-mix(in srgb, var(--color-primary) 85%, black);--btn-hover-border-color:color-mix(in srgb, var(--color-primary) 85%, black)}.btn-primary:active,.btn-primary:focus{background-color:var(--color-active);border-color:var(--color-active)}.btn-group{margin-bottom:1em}.btn-group>input{padding:.5em;border:1px solid #cdd3d9;border-radius:.25rem 0 0 .25rem}.btn-group>.btn-group{margin-bottom:0}.com-content-article ol,.com-content-article ul{overflow:hidden}.com-content-category__pagination{margin-bottom:1em}.small,small{font-size:.875rem}dd{margin-bottom:.5rem;margin-left:0;padding:0;word-wrap:break-word}th dd{font-weight:var(--font-weight-normal,400)}.com-contact__thumbnail{text-align:left;margin:2em;padding:1rem}[data-bs-theme=dark] .com-contact__thumbnail{background-color:var(--nav-text-color)}@media (min-width:1200px){dl.dl-horizontal{display:grid;grid-template-columns:auto 1fr}dl.dl-horizontal dt{grid-column-start:1;grid-column-end:2}dl.dl-horizontal dd{grid-column-start:2;grid-column-end:3;padding:0 0 0 1em;margin-bottom:0}.com-contact__container{display:grid;grid-template-columns:repeat(4,1fr);grid-template-rows:repeat(4,auto);grid-gap:1rem;margin-bottom:1em}.com-contact__container .h3,.com-contact__container h3{grid-column:1/5}.com-contact__container .com-contact__thumbnail{grid-column:1/5;grid-row:2/5;text-align:right}.com-contact__container .com-contact__position{grid-column:1/3;grid-row:2/3}.com-contact__container .com-contact__info{grid-column:1/3;grid-row:3/4}.com-users-profile dt{min-width:180px}}figure{margin:0 0 2em}figure.float-start{margin-right:1em}figure.float-end{margin-left:1em}figcaption{font-size:.9em;color:#6d757d}.mod-menu{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}meter{width:100%}.pagenavigation,.pager{clear:both}.pagenavigation .pagination,.pager .pagination{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:0;margin:1em 0}.pagenavigation .pagination .next:only-child,.pager .pagination .next:only-child{margin-left:auto}.page-link,.page-link:active{color:var(--color-link)}.pager .pagination{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}[dir=rtl] li.next .page-link{border-radius:.25rem 0 0 .25rem}[dir=rtl] li.previous .page-link{border-radius:0 .25rem .25rem 0}.j-main-container .alert{margin:.75rem}.alert-heading{font-size:1.5rem}@-webkit-keyframes fadeIn{from{opacity:0;-webkit-transform:translateY(-1rem);transform:translateY(-1rem)}to{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeIn{from{opacity:0;-webkit-transform:translateY(-1rem);transform:translateY(-1rem)}to{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}.back-to-top-link{position:absolute;inset-inline-end:1rem;bottom:1rem;z-index:10000;padding:.5em;color:var(--color-primary,#102755);pointer-events:all;background-color:var(--white,var(--body-color));border:1px solid var(--color-primary,#102755);border-radius:.25rem;opacity:0;-webkit-transition:opacity .2s ease-in;-o-transition:opacity .2s ease-in;transition:opacity .2s ease-in}.back-to-top-link.visible{opacity:1}.back-to-top-link:active,.back-to-top-link:focus{color:var(--white,var(--body-color));background-color:var(--color-active);border-color:var(--white,var(--body-color))}.container-banner img{display:block;margin:auto}.container-banner .banner-overlay{height:var(--hero-height,70vh);color:var(--hero-color,var(--body-color));background-repeat:var(--hero-bg-repeat,no-repeat);background-attachment:var(--hero-bg-attachment,fixed);background-position:var(--hero-bg-position,top center);background-size:var(--hero-bg-size,cover);border-bottom:var(--hero-border-bottom,solid var(--accent-color-secondary))}.container-banner .banner-overlay .overlay{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;height:100%;padding:var(--hero-overlay-padding,1em);text-align:var(--hero-overlay-text-align,center);color:var(--hero-overlay-text-color,var(--body-color));background-color:var(--hero-overlay-bg,hsla(0,0%,0%,.5))}.container-banner .banner-overlay .overlay .text-thin{font-weight:lighter}.container-banner .banner-overlay .overlay .text-thin::after{display:block;width:30%;height:4px;margin:1rem auto 2rem;content:"";background:var(--body-color)}.container-banner .banner-overlay .overlay .text-thin .lead{font-size:150vh}@media screen and (max-height:740px){.container-banner .banner-overlay{height:100vh}}.footer{margin-top:1em;color:var(--body-color);background:var(--color-primary)}.footer .grid-child{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:2.5rem .5em}.footer a{color:currentColor}.footer .mod-menu{position:relative}.footer .metismenu.mod-menu .mm-collapse{background:var(--color-primary)}.form-control{max-width:100%}.form-control.input-xlarge{max-width:21.875rem}.form-control.input-xxlarge{max-width:34.375rem}.form-control.input-full{max-width:100%}.spacer hr{width:23.75rem}.form-inline .custom-select,.form-inline .form-select{display:inline-block;width:auto}@media (max-width:991.98px){.footer .grid-child{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.footer .grid-child .mod-footer{margin:.375rem 0}.form-inline .custom-select,.form-inline .form-select{width:100%}.container-header{position:relative}}td .form-control{display:inline-block;width:auto}.checkboxes{padding-top:.3125rem}.checkboxes .checkbox input{position:static;margin-left:0}.modal label{width:100%}.invalid{color:#a51e17;border-color:#a51e17}.valid{border-color:#438343}.form-control-feedback{display:block}[role=tooltip]:not(.show){right:5em;z-index:1070;display:none;max-width:100%;padding:.5em;margin:.5em;color:#000;text-align:start;background:var(--body-color);border:1px solid #6d757d;border-radius:.25rem;-webkit-box-shadow:0 0 .5rem rgba(0,0,0,.8);box-shadow:0 0 .5rem rgba(0,0,0,.8)}[role=tooltip]:not(.show)[id^=editarticle-],[role=tooltip]:not(.show)[id^=editcontact-]{right:auto;-webkit-margin-start:-10em;margin-inline-start:-10em}[role=tooltip]:not(.show)[id^=cbunpublish],[role=tooltip]:not(.show)[id^=id-skip-]{right:auto}:active+[role=tooltip],:focus+[role=tooltip]{position:absolute;display:block}.filter-search-bar__description{bottom:100%}fieldset+fieldset{margin-top:2em}fieldset>*{margin-bottom:0}.control-group{margin:1em 0}.container-popup .filter-search-bar__description{top:100%;bottom:auto}.com-users-login__options{margin-top:2em}.com-users-logout__submit button{width:100%}.com-users-profile__edit #jform_privacyconsent_privacy .radio,.com-users-profile__edit #jform_profile_tos .radio,.com-users-profile__edit #jform_terms_terms .radio,.com-users-registration #jform_privacyconsent_privacy .radio,.com-users-registration #jform_profile_tos .radio,.com-users-registration #jform_terms_terms .radio{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;gap:1rem}.btn.jmodedit{position:absolute;top:0;right:0;left:auto;z-index:900;color:var(--color-link);background-color:rgba(255,255,255,.5);border:1px solid #58595a;border-radius:.25rem}.container-header{position:relative;z-index:100;background:var(--header-background-image);background-size:var(--header-background-size);-webkit-box-shadow:0 5px 5px hsla(0,0%,0%,.03) inset;box-shadow:0 5px 5px hsla(0,0%,0%,.03) inset;background-repeat:var(--header-background-repeat)}.container-header .grid-child{padding:var(--padding-x) var(--padding-y)}.container-header nav{padding:0 2rem}.container-header .site-description{font-size:1rem;color:var(--body-color);white-space:normal}.header-brand-wrap{display:flex;align-items:center;width:100%}.container-brand-aside{margin-inline-start:auto;display:flex;align-items:center}.container-header .navbar-brand{position:relative;display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;font-size:2rem;color:var(--nav-text-color);-webkit-margin-end:auto;margin-inline-end:auto}.container-header .navbar-brand a{color:var(--nav-text-color)}.navbar-brand img{max-width:250px;max-height:100px;width:auto;height:auto}.container-header .navbar-brand:active,.container-header .navbar-brand:focus{color:var(--nav-text-color)}.container-header .container-nav{-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;background-color:var(--nav-bg-color);border-width:var(--border-width);border-top:solid var(--accent-color-primary);border-bottom:solid var(--accent-color-secondary);border-left:none;border-right:none}.container-header .container-nav .container-search:only-child{margin-left:auto}.container-header .navbar-collapse.show{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.container-header .mod-menu{-webkit-box-flex:1;-ms-flex:1 0 100%;flex:1 0 100%;padding:0;margin:0;color:var(--mainmenu-nav-link-color);list-style:none;font-size:1.2em}.container-header .mod-menu>li{position:relative}li.active a,li.current a{font-weight:700}.container-header .mod-menu>li>a,.container-header .mod-menu>li>span{position:relative;color:var(--mainmenu-nav-link-color);text-decoration:none}@media (min-width:992px){.container-header .mod-menu{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1 1 0%;flex:1 1 0%;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.container-header .mod-menu>li+li{margin-left:1.55em}.container-header .metismenu>li>a::after,.container-header .metismenu>li>button::before,.container-header .mod-menu>li::after{position:absolute;right:50%;bottom:0;left:50%;display:block;height:2px;margin:auto;content:"";background:0 0;opacity:.2;-webkit-transition:.2s,background-color .2s;-o-transition:.2s,background-color .2s;transition:.2s,background-color .2s}}.container-header .mod-menu>li.active::after,.container-header .mod-menu>li:active::after{right:2px;left:0;background:var(--navbar-brand-color)}.container-header .mod-menu .parent>ul{display:none;color:#22262a}.container-header .metismenu>li+li{margin-left:0}.container-header .metismenu>li.active>a::after,.container-header .metismenu>li.active>button::before,.container-header .metismenu>li>a:active::after,.container-header .metismenu>li>button:active::before{right:0;left:0;background:var(--navbar-color)}.container-header .metismenu>li.active>button.mm-toggler-link::before,.container-header .metismenu>li>button.mm-toggler-link:active::before{right:0;left:.5em}.container-header .metismenu>li.level-1>ul{min-width:12rem}.container-header .navbar-toggler{color:var(--body-color);cursor:pointer}.container-header .container-search{margin-top:.75em}.container-header .mod-finder{color:var(--body-color);margin-block-end:0}.container-header .mod-finder a{color:var(--body-color)}.container-header .mod-finder a:active,.container-header .mod-finder a:focus{color:var(--mod-finder-link-hover)}.container-header .mod-finder .awesomplete{color:var(--body-color)}.container-header .mod-finder .awesomplete>ul{background:-webkit-gradient(linear,left top,right bottom,from(var(--body-color)),to(hsla(0,0%,100%,.9)));background:-o-linear-gradient(top left,var(--body-color),hsla(0,0%,100%,.9));background:linear-gradient(to bottom right,var(--body-color),hsla(0,0%,100%,.9))}.icon-white{color:var(--body-bg)}.input-group-text::before{min-width:16px}.tbody-icon{padding:0 .1875rem;text-align:center;background-color:transparent;border:0}.tbody-icon [class*=" fa-"],.tbody-icon [class*=" icon-"],.tbody-icon [class^=fa-],.tbody-icon [class^=icon-]{width:26px;height:26px;font-size:1.1rem;line-height:22px;color:#cdd3d9;border:0}.tbody-icon .fa-check,.tbody-icon .icon-check,.tbody-icon .icon-publish{color:#438343;border-color:#438343}.tbody-icon .fa-lock,.tbody-icon .icon-checkedout,.tbody-icon .icon-lock{width:auto;height:auto;font-size:1.2rem;line-height:1rem;color:#474f56;border:0}.tbody-icon.color-featured-disabled,.tbody-icon.fa-star-disabled,.tbody-icon.featured-disabled,.tbody-icon.home-disabled,.tbody-icon.icon-star-disabled{cursor:not-allowed;opacity:1}.tbody-icon .fa-delete,.tbody-icon .fa-times,.tbody-icon .icon-delete,.tbody-icon .icon-times{color:#a51e17;border-color:#a51e17}.plg_system_webauthn_login_button svg{-webkit-margin-end:.125rem;margin-inline-end:.125rem;max-height:25px;width:auto}.plg_system_webauthn_login_button svg path{fill:var(--black)}iframe{border:0}.modal iframe{width:100%}.grid-child{display:-webkit-box;display:-ms-flexbox;display:flex;margin-right:auto;margin-left:auto}.mod-custom{position:relative}.hero-overlay{position:relative;overflow:hidden;isolation:isolate}.hero-overlay::before{content:"";position:absolute;inset:0;z-index:-2;background-position:center;background-size:cover;background-repeat:no-repeat;transform:scale(1.02)}.hero-overlay::after{content:"";position:absolute;inset:0;z-index:-1;-webkit-backdrop-filter:blur(8px) saturate(0.9) brightness(1.12);backdrop-filter:blur(8px) saturate(0.9) brightness(1.12);-webkit-mask-image:radial-gradient(circle at 50% 45%,rgba(0,0,0,1) 0%,rgba(0,0,0,1) 38%,rgba(0,0,0,0) 72%);mask-image:radial-gradient(circle at 50% 45%,rgba(0,0,0,1) 0%,rgba(0,0,0,1) 38%,rgba(0,0,0,0) 72%);pointer-events:none}.hero-overlay .overlay{position:relative;z-index:0;border-top:var(--border-width) var(--border-style) var(--accent-color-primary);border-bottom:var(--border-width) var(--border-style) var(--accent-color-secondary);background-color:rgba(111,117,123,.55);background-image:linear-gradient(180deg,rgba(255,255,255,.12),rgba(0,0,0,.18))}.container-topbar{color:var(--body-color);background-color:var(--color-primary)}.container-topbar a{color:var(--body-color)}.container-banner{display:block;margin:0;grid-area:banner}.container-bottom-a,.container-bottom-b,.container-top-a,.container-top-b{position:relative}.container-bottom-a>*,.container-bottom-b>*,.container-top-a>*,.container-top-b>*{-webkit-box-flex:1;-ms-flex:1;flex:1;margin:.5em 0}@media (max-width:991.98px){.container-header .mod-menu>li.active>a,.container-header .mod-menu>li.active>span,.container-header .mod-menu>li>a:active{text-decoration:underline}.container-bottom-a,.container-bottom-b,.container-top-a,.container-top-b{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.container-bottom-a>*,.container-bottom-b>*,.container-top-a>*,.container-top-b>*{-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto}}.container-component nav{position:relative}.container-component,.container-sidebar-left,.container-sidebar-right{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1;flex:1;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.container-component>*,.container-sidebar-left>*,.container-sidebar-right>*{margin-bottom:0}.container-component,.sidebar-left,.sidebar-right{height:100%}.container-component>*+*,.container-component>:first-child,.container-sidebar-left>*+*,.container-sidebar-left>:first-child,.container-sidebar-right>*+*,.container-sidebar-right>:first-child{margin-top:1em}.container-sidebar-left,.container-sidebar-right{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:calc(100% - 1em);-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}@media (min-width:768px){.container-sidebar-left,.container-sidebar-right{width:calc(25% - 1em);-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}}.container-sidebar-left .sidebar-left:first-child{margin-top:1em}.container-sidebar-left .sidebar-left:last-child{margin-bottom:1em}.container-sidebar-right .sidebar-right:first-child{margin-top:1em}.container-sidebar-right .sidebar-right:last-child{margin-bottom:1em}.system-debug{display:block}.options-form{width:100%;padding:1vw 2vw;margin-bottom:1rem;color:var(--form-legend-color);background-color:var(--body-color);border:1px solid var(--border-gray)}.options-form>legend{float:none;width:auto;padding:0 .5rem;font-weight:700;color:var(--form-legend-color);background-color:var(--body-color)}.modal .btn{margin-right:.5rem}.modal .btn-primary:not([href]),.modal .btn-primary:not([href]):active,.modal .btn-success:not([href]),.modal .btn-success:not([href]):active{color:var(--body-color)}.modal-header{padding:0 .9375rem}.modal-title{font-weight:var(--font-weight-normal,400);line-height:3rem}.contentpane{padding:.9375rem}.contentpane .main-card{margin:-.625rem;-webkit-box-shadow:none;box-shadow:none}.error_site .page-header{margin-top:1em}[class*=" container-"] .span-col-2,[class^=container-] .span-col-2{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:calc(50% - 1em)}[class*=" container-"] .span-col-3,[class^=container-] .span-col-3{-webkit-box-flex:0;-ms-flex:0 0 33.333%;flex:0 0 33.333%;max-width:calc(33.333% - 1em)}[class*=" container-"] .span-col-4,[class^=container-] .span-col-4{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:calc(25% - 1em)}@supports (display:grid){[class*=" span-"],[class^=span-]{grid-column-end:auto;grid-row-end:auto}@media (min-width:768px){[class*=" span-col"],[class^=span-col]{grid-column-end:span 2}}@media (min-width:992px){.span-col-2{grid-column-end:span 2}.span-col-3{grid-column-end:span 3}.span-col-4{grid-column-end:span 4}.span-row-2{grid-row-end:span 2}.span-row-3{grid-row-end:span 3}.span-row-4{grid-row-end:span 4}}[class*=" container-"] [class*=" span-"],[class*=" container-"] [class^=span-],[class^=container-] [class*=" span-"],[class^=container-] [class^=span-]{-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;max-width:none}}.blog-items{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;width:100%;padding:0;margin-right:-.5em;margin-bottom:1em;margin-left:-.5em}.readmore{text-align:right}.blog-item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding:0 .5em 1em;overflow:hidden}.boxed .blog-item{background-color:var(--bs-body-bg)}.boxed .blog-item figure.item-image{border-top:solid .25em var(--accent-color-primary);border-bottom:solid .25em var(--accent-color-secondary)}.boxed .blog-item .item-content{padding:1.5625rem}.blog-item .item-image{margin-top:.1875rem;margin-bottom:.9375rem;overflow:hidden;max-height:500px}.boxed .blog-item .item-image{margin-bottom:0}@media (min-width:992px){.container-header .metismenu>li.level-1.active>a,.container-header .metismenu>li.level-1.active>button,.container-header .metismenu>li.level-1>a:active,.container-header .metismenu>li.level-1>button:active{text-decoration:none}.blog-items.columns-2>div{width:50%}.blog-items.columns-3>div{width:33.33333%}.blog-items.columns-4>div{width:25%}.image-right .blog-item .item-image{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}}.image-bottom .blog-item .item-image{margin-top:-.9375rem;-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.image-left .blog-item .item-content{padding-left:1.5625rem}.image-right .blog-item .item-content{padding-right:1.5625rem}.image-left .blog-item,.image-right .blog-item{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}@media (min-width:992px){.image-left .blog-item,.image-right .blog-item{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.image-left .blog-item .item-image,.image-right .blog-item .item-image{-webkit-box-flex:1;-ms-flex:1 0 40%;flex:1 0 40%;max-width:35%;margin-right:1em}.image-left .blog-item .item-content,.image-right .blog-item .item-content{-webkit-box-flex:1;-ms-flex:1 0 60%;flex:1 0 60%}.blog-items.masonry-2{-webkit-column-count:2;-moz-column-count:2;column-count:2}.blog-items.masonry-3{-webkit-column-count:3;-moz-column-count:3;column-count:3}.blog-items.masonry-4{-webkit-column-count:4;-moz-column-count:4;column-count:4}}.article-info{margin-bottom:0}.article-info dd,.article-info dt{padding:0;display:inline-block;margin-bottom:0}ul.tags{margin-bottom:.25em}.items-leading .item-image{max-width:100%;width:100%}@supports (display:grid){.blog-items{display:grid;margin:0 0 1em;grid-auto-flow:row;grid-template-columns:1fr;grid-gap:1em}.blog-items .blog-item{padding:0}.blog-items[class*=" columns-"]>div,.blog-items[class^=columns-]>div{-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;width:auto;max-width:none}@media (min-width:992px){.blog-items.columns-2{grid-template-columns:1fr 1fr}.blog-items.columns-3{grid-template-columns:1fr 1fr 1fr}.blog-items.columns-4{grid-template-columns:1fr 1fr 1fr 1fr}}}.blog-items[class*=" masonry-"],.blog-items[class^=masonry-]{display:block;-webkit-column-gap:1em;-moz-column-gap:1em;column-gap:1em}.blog-items[class*=" masonry-"] .blog-item,.blog-items[class^=masonry-] .blog-item{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;margin-bottom:1em;page-break-inside:avoid;-webkit-column-break-inside:avoid;-moz-column-break-inside:avoid;break-inside:avoid}.image-alternate .blog-item:nth-of-type(odd) .item-image{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.image-alternate.image-left .blog-item:nth-of-type(odd) .item-image{margin-right:0;margin-left:1.5625rem;-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.image-alternate.image-top .blog-item:nth-of-type(odd) .item-image{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.breadcrumb{margin-bottom:0;background-color:hsla(0,0%,0%,.03)}.no-card .newsflash-horiz li{padding:0 1rem 1rem;border:1px solid #dfe2e6;border-radius:0 0 .25rem .25rem;-webkit-box-shadow:1px 1px 4px hsla(0,0%,0%,.1);box-shadow:1px 1px 4px hsla(0,0%,0%,.1)}.no-card .newsflash-horiz li figure{margin:0 -1rem 1rem}.mod-list{-webkit-padding-start:0;padding-inline-start:0;list-style:none}.mod-list li{padding:.25em 0}.mod-list li a{text-decoration:none}.mod-list li a:active{text-decoration:underline}.container-header .mod-list li a:active{text-decoration:none}.mod-list li.active>a{text-decoration:underline}.container-header .mod-list li.active>a{text-decoration:none}.mod-list li .mod-menu__sub{padding-left:1em}.element-invisible{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;-webkit-clip-path:inset(50%);clip-path:inset(50%)}.hidden{display:none;visibility:hidden}.table-row{display:table-row}joomla-alert{display:none}.editor-xtd-buttons .btn{margin-bottom:.3125rem}.subhead{position:sticky;top:0;right:0;left:0;z-index:1000;width:auto;min-height:43px;padding:.25rem;color:var(--subhead-color);background:var(--body-color);-webkit-box-shadow:-3px -2px 22px var(--box-shadow-gray);box-shadow:-3px -2px 22px var(--box-shadow-gray)}.subhead .row{margin-right:0;margin-left:0}.subhead.noshadow{-webkit-box-shadow:none;box-shadow:none}.subhead .btn-group,.subhead joomla-toolbar-button{-webkit-margin-start:0.75rem;margin-inline-start:.75rem}.subhead .btn-group:first-child,.subhead joomla-toolbar-button:first-child{-webkit-margin-start:0;margin-inline-start:0}.subhead joomla-toolbar-button .btn>span,.subhead joomla-toolbar-button .dropdown-item>span{-webkit-margin-end:.5rem;margin-inline-end:.5rem;width:1.25em;text-align:center}.subhead .btn{--subhead-btn-accent:var(--subhead-color);padding:0 1rem;margin:.3125rem 0;font-size:1rem;line-height:2.45rem;color:var(--subhead-color);background:var(--body-color);border-color:#acb5bd}.subhead .btn>span{display:inline-block;color:var(--subhead-btn-accent)}.subhead .btn:not([disabled]):active,.subhead .btn:not([disabled]):focus{color:rgba(255,255,255,.9);background-color:var(--subhead-btn-accent);border-color:var(--subhead-btn-accent)}.subhead .btn:not([disabled]):active>span,.subhead .btn:not([disabled]):focus>span{color:rgba(255,255,255,.9)}.subhead .btn.btn-success{--subhead-btn-accent:var(--success)}.subhead .btn.btn-danger{--subhead-btn-accent:var(--danger)}.subhead .btn.btn-primary{--subhead-btn-accent:#2a69b8}.subhead .btn.btn-secondary{--subhead-btn-accent:#001b4c}.subhead .btn.btn-info{--subhead-btn-accent:#132f53}.subhead .btn.btn-action{--subhead-btn-accent:#132f53;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.subhead .btn.btn-action::after{width:2.375rem;font-family:"Font Awesome 5 Free";font-weight:900;content:"\f078";border:0}.subhead .btn.dropdown-toggle[disabled],.subhead .btn[disabled]{--subhead-btn-accent:#132f53;background:rgba(223,227,231,.8);opacity:.5}.subhead .btn.dropdown-toggle[disabled]:active,.subhead .btn.dropdown-toggle[disabled]:focus,.subhead .btn[disabled]:active,.subhead .btn[disabled]:focus{cursor:not-allowed}.subhead .dropdown-toggle.btn{-webkit-padding-end:0;padding-inline-end:0}.subhead .btn-group:not(:last-child)>.dropdown-toggle-split{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1;-webkit-margin-start:-0.25rem;margin-inline-start:-.25rem;border-radius:0 .25rem .25rem 0}.subhead .btn-group joomla-toolbar-button,.subhead .dropdown-menu joomla-toolbar-button{-webkit-margin-start:0;margin-inline-start:0}@media (max-width:767.98px){joomla-tab[view=accordion] .col-md-3,joomla-tab[view=accordion] .col-md-9{padding:.5rem 1rem}#myTab{margin-top:1rem;margin-bottom:1.5rem}joomla-tab[view=accordion] ul li{width:100%}.subhead .btn,.subhead .btn-group,.subhead joomla-toolbar-button{width:100%;margin-left:0;text-align:left}.subhead .btn-toolbar>.btn-group,.subhead .btn-toolbar>joomla-toolbar-button{margin-left:0}.subhead .btn.btn-action::after{text-align:center;-webkit-margin-start:auto;margin-inline-start:auto}.subhead .dropdown-toggle-split{width:auto}}.left.item-image{float:left}.view-article .left.item-image{max-width:300px}.hide-image .left.item-image{display:none}.right.item-image{float:right;width:40%;max-width:300px}.tags .list-inline-item{margin:.25rem}.tags a.btn{font-weight:700}.tag{display:inline-block;padding:.5rem .5rem .5rem 0}body{position:relative;min-height:100vh;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}body.wrapper-fluid .site-grid{grid-template-columns:[full-start] minmax(0,1fr) [main-start] repeat(4,minmax(0,25%)) [main-end] minmax(0,1fr) [full-end];grid-gap:0 2em}body.wrapper-fluid .grid-child{max-width:none}body.wrapper-fluid footer>.grid-child,body.wrapper-fluid header>.grid-child{padding:0 2em}body.wrapper-fluid header>.grid-child{margin:0}footer .grid-child>div{padding:1rem 4em}header .grid-child .navbar-brand{padding-left:0;padding-right:0}body:not(.has-sidebar-left) .site-grid .container-component{grid-column-start:main-start}body:not(.has-sidebar-right) .site-grid .container-component{grid-column-end:main-end}.site-grid{margin-bottom:auto}@supports (display:grid){.site-grid{display:grid;grid-template-areas:". banner banner banner banner ." ". top-a top-a top-a top-a ." ". top-b top-b top-b top-b ." ". comp comp comp comp ." ". side-l side-l side-l side-l ." ". side-r side-r side-r side-r ." ". bot-a bot-a bot-a bot-a ." ". bot-b bot-b bot-b bot-b .";grid-template-columns:[full-start] minmax(0,1fr) [main-start] repeat(4,minmax(0,19.875rem)) [main-end] minmax(0,1fr) [full-end];grid-gap:0 1em}.site-grid>[class*=" container-"],.site-grid>[class^=container-]{width:100%;max-width:none;-webkit-column-gap:1em;-moz-column-gap:1em;column-gap:1em}.site-grid>.full-width{grid-column:full-start/full-end}@media (min-width:992px){.site-grid{grid-template-areas:". banner banner banner banner ."". top-a top-a top-a top-a ."". top-b top-b top-b top-b ."". side-l comp comp side-r ."". bot-a bot-a bot-a bot-a ."". bot-b bot-b bot-b bot-b ."}}}.container-top-a{grid-area:top-a}.container-top-b{grid-area:top-b}.container-component{grid-area:comp}.container-sidebar-left{grid-area:side-l}.container-sidebar-right{grid-area:side-r}.container-main-top{grid-area:main-t}.container-main-bottom{grid-area:main-b}.container-breadcrumbs{grid-area:bread}.container-bottom-a{grid-area:bot-a}.mod-finder__search.input-group{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.mod-finder__search.input-group .awesomplete input{border-top-right-radius:0;border-bottom-right-radius:0}.mod-finder__search.input-group button{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.mod-finder__search.input-group button .icon-search{-webkit-margin-end:.2em;margin-inline-end:.2em}.awesomplete>input{max-width:200px}.awesomplete>ul{z-index:1000}.btn.active.focus,.btn.active:focus,.btn.focus,.btn.focus:active,.btn:active:focus,.btn:focus{text-decoration:none}.btn.group-move{cursor:move}.btn-secondary{color:var(--btn-color);background-color:var(--btn-bg);border-color:var(--btn-border-color);--bs-btn-color:#333;--bs-btn-bg:#EFEFEF;--bs-btn-border-color:#EFEFEF;--bs-btn-hover-bg:#333;--bs-btn-hover-border-color:#333;--bs-btn-active-bg:#333;--bs-btn-active-border-color:#333;--btn-color:var(--body-bg);--btn-bg:var(--secondary);--btn-border-color:var(--secondary);--btn-hover-bg:color-mix(in srgb, var(--secondary) 85%, black);--btn-hover-border-color:color-mix(in srgb, var(--secondary) 85%, black)}.btn-secondary:active{color:var(--btn-active-color);background-color:var(--btn-active-bg);border-color:var(--btn-active-border-color)}.btn-secondary:focus,.btn-secondary:hover{color:var(--btn-focus-color);background-color:var(--btn-focus-bg);border-color:var(--btn-focus-border-color);box-shadow:1px 5px 100px 1px var(--btn-focus-shadow-rgb)}.btn-secondary:active{color:var(--btn-active-color);background-color:var(--btn-active-bg);border-color:var(--btn-active-border-color);box-shadow:1px 5px 100px 1px var(--btn-active-shadow-rgb)}.article-info .association .btn-secondary,.cat-list-association .btn-secondary{font-weight:700;color:var(--body-color);background-color:#6d757d;border-color:#cdd3d9}.article-info .association .btn-secondary:active,.article-info .association .btn-secondary:focus,.cat-list-association .btn-secondary:active,.cat-list-association .btn-secondary:focus{color:var(--body-color);background-color:#343a40}.article-info .association .btn-group-sm>.btn,.article-info .association .btn-sm,.cat-list-association .btn-group-sm>.btn,.cat-list-association .btn-sm{padding:0 .25rem;font-size:.8rem;border-radius:.2rem}.custom-select,.form-select{max-width:100%;cursor:pointer;background:url("../images/select-bg.svg") right center/116rem no-repeat #eaedf0;border:1px solid #cdd3d9}.custom-select:focus,.form-select:focus{border-color:var(--black);-webkit-box-shadow:0 0 0 .25rem rgba(1,1,86,.25);box-shadow:0 0 0 .25rem rgba(1,1,86,.25)}.form-select[multiple],[multiple].custom-select{padding:0;background-color:var(--body-color)}.form-select[multiple] option,[multiple].custom-select option{padding:.3rem 1rem;background-color:var(--body-color)}.form-select[multiple] option:checked,[multiple].custom-select option:checked{color:var(--body-color);background-color:var(--color-primary)}.custom-select-success.custom-select,.form-select-success.custom-select,.form-select.custom-select-success,.form-select.form-select-success{color:#438343;background-color:#438343}.custom-select-success.custom-select option,.form-select-success.custom-select option,.form-select.custom-select-success option,.form-select.form-select-success option{color:#22262a;background-color:var(--body-color)}.custom-select-danger.custom-select,.form-select-danger.custom-select,.form-select.custom-select-danger,.form-select.form-select-danger{color:#a51e17;background-color:#a51e17}.custom-select-danger.custom-select option,.form-select-danger.custom-select option,.form-select.custom-select-danger option,.form-select.form-select-danger option{color:#22262a;background-color:var(--body-color)}.custom-select optgroup,.custom-select option,.form-select optgroup,.form-select option{color:var(--dark);background-color:var(--body-color)}.accordion .card-header{display:block;font-size:1.25rem;font-weight:var(--font-weight-headings,700);line-height:1.2}.accordion .list-group-item{color:var(--color-link)}.dropdown-menu{padding:.2rem 0;margin-top:.5rem;background-color:var(--body-color);border-color:#dfe2e6}.dropdown-menu-end::after{right:.9rem;left:auto}.field-media-wrapper{display:block;width:100%;max-width:calc(50vw - 5rem)}.field-media-wrapper .field-media-preview{width:100%;max-width:none}@media (max-width:991.98px){.btn{margin-bottom:.25rem}.input-group .btn{margin-bottom:0}.field-media-wrapper{min-width:100%}}.list-group-item{background-color:var(--body-color)}.list-unstyled .list-unstyled{padding-left:1.25rem}.jviewport-height10{height:10vh}.jviewport-height20{height:20vh}.jviewport-height30{height:30vh}.jviewport-height40{height:40vh}.jviewport-height50{height:50vh}.jviewport-height60{height:60vh}.jviewport-height70{height:70vh}.jviewport-height80{height:80vh}.jviewport-height90{height:90vh}.jviewport-height100{height:100vh}[class*=jviewport-height] iframe{height:100%}.modal-dialog.jviewport-width10{width:10vw;max-width:none}.modal-dialog.jviewport-width20{width:20vw;max-width:none}.modal-dialog.jviewport-width30{width:30vw;max-width:none}.modal-dialog.jviewport-width40{width:40vw;max-width:none}.modal-dialog.jviewport-width50{width:50vw;max-width:none}.modal-dialog.jviewport-width60{width:60vw;max-width:none}.modal-dialog.jviewport-width70{width:70vw;max-width:none}.modal-dialog.jviewport-width80{width:80vw;max-width:none}.modal-dialog.jviewport-width90{width:90vw;max-width:none}.modal-dialog.jviewport-width100{width:100vw;max-width:none}.nav.nav-tabs{padding:0;margin:0;background-color:#f4f4f4;border:1px solid #dfe2e6;border-bottom:0;border-radius:.25rem .25rem 0 0;-webkit-box-shadow:0 1px var(--body-color) inset,0 2px 3px -3px hsla(0,0%,0%,.15),0 -4px 0 hsla(0,0%,0%,.05) inset,1px 1px 4px hsla(0,0%,0%,.1);box-shadow:0 1px var(--body-color) inset,0 2px 3px -3px hsla(0,0%,0%,.15),0 -4px 0 hsla(0,0%,0%,.05) inset,1px 1px 4px hsla(0,0%,0%,.1)}.nav.nav-tabs .nav-item{margin-bottom:0;margin-left:0}.nav.nav-tabs .nav-item:first-of-type .nav-link.active{border-radius:.25rem 0 0;-webkit-box-shadow:-1px 0 1px -1px hsla(0,0%,0%,.06),inset -2px 0 1px -1px hsla(0,0%,0%,.08),inset 0 1px 0 hsla(0,0%,0%,.02);box-shadow:-1px 0 1px -1px hsla(0,0%,0%,.06),inset -2px 0 1px -1px hsla(0,0%,0%,.08),inset 0 1px 0 hsla(0,0%,0%,.02)}.nav.nav-tabs .nav-item:last-of-type .nav-link{-webkit-box-shadow:-1px 0 0 hsla(0,0%,0%,.05),1px 0 0 hsla(0,0%,0%,.05);box-shadow:-1px 0 0 hsla(0,0%,0%,.05),1px 0 0 hsla(0,0%,0%,.05)}.nav.nav-tabs .nav-item:last-of-type .nav-link.active{-webkit-box-shadow:inset 2px 0 1px -1px hsla(0,0%,0%,.08),inset -2px 0 1px -1px hsla(0,0%,0%,.08),inset 0 1px 0 hsla(0,0%,0%,.02);box-shadow:inset 2px 0 1px -1px hsla(0,0%,0%,.08),inset -2px 0 1px -1px hsla(0,0%,0%,.08),inset 0 1px 0 hsla(0,0%,0%,.02)}.nav.nav-tabs .nav-link{position:relative;padding:.75em 1em;color:var(--color-primary);border:0;border-top-left-radius:0;border-top-right-radius:0;-webkit-box-shadow:-1px 0 0 hsla(0,0%,0%,.05);box-shadow:-1px 0 0 hsla(0,0%,0%,.05)}.nav.nav-tabs .nav-link.active{background-color:hsla(0,0%,0%,.3);background-image:-webkit-gradient(linear,left top,left bottom,from(hsla(0,0%,0%,0)),to(hsla(0,0%,0%,.05)));background-image:-o-linear-gradient(top,hsla(0,0%,0%,0),hsla(0,0%,0%,.05) 100%);background-image:linear-gradient(to bottom,hsla(0,0%,0%,0),hsla(0,0%,0%,.05) 100%);border-right:0;border-left:0;border-top-left-radius:0;border-top-right-radius:0;-webkit-box-shadow:inset 2px 0 1px -1px hsla(0,0%,0%,.08),inset -2px 0 1px -1px hsla(0,0%,0%,.08),inset 0 1px 0 hsla(0,0%,0%,.02);box-shadow:inset 2px 0 1px -1px hsla(0,0%,0%,.08),inset -2px 0 1px -1px hsla(0,0%,0%,.08),inset 0 1px 0 hsla(0,0%,0%,.02)}.nav.nav-tabs .nav-link.active::after{position:absolute;right:0;bottom:-1px;left:0;height:5px;content:"";background-color:var(--color-primary);opacity:.8}.nav-tabs+.tab-content{padding:.9375rem;background:var(--body-color);border:1px solid #dfe2e6;border-radius:0 0 .25rem .25rem;-webkit-box-shadow:1px 1px 4px hsla(0,0%,0%,.1);box-shadow:1px 1px 4px hsla(0,0%,0%,.1)}.pagination{margin:1rem}.table th{font-weight:500}.table thead th{white-space:nowrap;border-bottom-width:1px}.table td,.table th{vertical-align:middle}.table td label,.table th label{margin-bottom:0}.chosen-container.chosen-container-single{max-width:100%;font-size:1rem}.chosen-container.chosen-container-single .chosen-single{display:inline-block;height:calc(1.5em + 1.2rem + 2px);padding:.81rem 4rem .81rem 1rem;line-height:1.5;color:#22262a;vertical-align:middle;background:right .1rem center/116rem no-repeat #eaedf0;border:1px solid #cdd3d9;-webkit-box-shadow:none;box-shadow:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem;width:100%}.chosen-container.chosen-container-single .chosen-single abbr{top:10px}.chosen-container.chosen-container-single .chosen-single:focus{border-color:var(--input-focus-border-color);outline:0}.chosen-container.chosen-container-single .chosen-single:disabled{cursor:not-allowed;background-color:#eaedf0}.chosen-container.chosen-container-single .chosen-single div b{background:0 0}.chosen-container.chosen-container-single .chosen-drop{background:var(--body-color);border:1px solid #cdd3d9}.chosen-container.chosen-container-single .chosen-results li{line-height:calc(1rem + .3rem)}.chosen-container.chosen-container-single.chosen-container-active .chosen-single{border-bottom-right-radius:0;border-bottom-left-radius:0}.chosen-container.chosen-container-multi .chosen-choices{max-width:100%;min-height:calc(1.5em + 1.2rem + 2px);font-size:1rem;line-height:1.5;background-image:var(--body-color)}.chosen-container.chosen-container-multi .chosen-choices li.search-choice{padding:.3125rem 2.0625rem .3125rem .625rem;color:var(--body-color);background:var(--primary);border:0;-webkit-box-shadow:1px 1px 4px hsla(0,0%,0%,.1);box-shadow:1px 1px 4px hsla(0,0%,0%,.1);border-radius:.25rem}.chosen-container.chosen-container-multi .chosen-choices li.search-choice .search-choice-close{top:0;right:0;width:20px;height:100%;background:hsla(0,0%,0%,.2);background-image:none}.chosen-container.chosen-container-multi .chosen-choices li.search-choice .search-choice-close::before{position:absolute;top:6px;right:5px;font-size:1rem;color:var(--body-color);content:"×"}.chosen-container-active.chosen-with-drop .chosen-single{-webkit-box-shadow:none;box-shadow:none}.chosen-container-single{width:auto}.card .chosen-container.chosen-container-single,.card .chosen-container.chosen-container-single .chosen-single{width:100%}.gu-mirror{position:fixed;z-index:9999;margin:0;background-color:#90ed90;opacity:.8}.gu-mirror.table{display:table}.gu-mirror.table td{display:table-cell}.metismenu.menu-horizontal{-webkit-box-flex:1;-ms-flex:1 0 100%;flex:1 0 100%;padding:0;margin:0;list-style:none}@media (min-width:992px){.awesomplete>input{max-width:none}.metismenu.menu-horizontal{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1 1 0%;flex:1 1 0%;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}}.metismenu.menu-horizontal>li{position:relative}.metismenu.menu-horizontal .level-1>ul{min-width:12rem}.metismenu.mod-menu{margin:0}.metismenu.mod-menu .metismenu-item{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:.5em 1em;font-size:1.1rem;line-height:1.5}.metismenu.mod-menu .metismenu-item.parent{position:relative}.metismenu.mod-menu .metismenu-item>ul{position:absolute;top:100%;z-index:1001;display:block;padding:0;list-style:none;-webkit-box-shadow:0 0 .5em hsla(0,0%,0%,.1);box-shadow:0 0 .5em hsla(0,0%,0%,.1)}.metismenu.mod-menu .metismenu-item>a,.metismenu.mod-menu .metismenu-item>button,.metismenu.mod-menu .metismenu-item>span{overflow:hidden;text-decoration:none;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap}.metismenu.mod-menu .metismenu-item>a:focus,.metismenu.mod-menu .metismenu-item>button:focus{outline:hsl(210,14%,83%) dotted 1px;outline-offset:2px}.metismenu.mod-menu .metismenu-item.active>a,.metismenu.mod-menu .metismenu-item.active>button,.metismenu.mod-menu .metismenu-item>a:active,.metismenu.mod-menu .metismenu-item>button:active{text-decoration:underline}.metismenu.mod-menu .metismenu-item::after{content:none}.metismenu.mod-menu .metismenu-item:not(.level-1)>ul,.metismenu.mod-menu .metismenu-item:not(.level-2)>ul{-webkit-margin-end:-1em;margin-inline-end:-1em}.metismenu.mod-menu .metismenu-item.divider:not(.parent){width:1px;padding:0;margin:.25em;overflow:hidden;border-right:1px solid #cdd3d9}@media (max-width:991.98px){.metismenu.mod-menu .metismenu-item.divider:not(.parent){width:auto;height:1px;border-bottom:1px solid #cdd3d9}}.metismenu.mod-menu .mm-collapsing{height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:color,background-color,height,visibility;-o-transition-property:color,background-color,height,visibility;transition-property:color,background-color,height,visibility}.metismenu.mod-menu .mm-collapse{position:absolute;background-color:var(--body-color);-webkit-box-shadow:1px 1px 4px hsla(0,0%,0%,.1);box-shadow:1px 1px 4px hsla(0,0%,0%,.1)}.metismenu.mod-menu .mm-collapse:not(.mm-show){display:none}.metismenu.mod-menu .mm-collapse>li>a{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.metismenu.mod-menu .mm-collapse>li.divider:not(.parent){width:auto;height:1px;border-bottom:1px solid #cdd3d9}.metismenu.mod-menu .mm-collapse>li.parent .mm-toggler{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.metismenu.mod-menu .mm-collapse>li.parent>ul{position:relative;top:0;-ms-flex-preferred-size:calc(100% + 1em);flex-basis:calc(100% + 1em);margin-top:.5em;margin-bottom:-.5em;background-color:hsla(0,0%,0%,.03);-webkit-box-shadow:none;box-shadow:none}.metismenu.mod-menu .mm-toggler{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:100%;padding:0;color:currentColor;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background:0 0;border:none;-webkit-box-shadow:none;box-shadow:none}.metismenu.mod-menu .mm-toggler:after{width:0;height:0;-webkit-margin-start:0.5em;margin-inline-start:.5em;content:"";border-top:.5em solid currentColor;border-right:.5em solid transparent;border-left:.5em solid transparent;-webkit-transition:.3s ease-out;-o-transition:.3s ease-out;transition:.3s ease-out}.metismenu.mod-menu .mm-toggler[aria-expanded=true]:after,.mm-active>.metismenu.mod-menu .mm-toggler:after{-webkit-transform:rotateX(-180deg);transform:rotateX(-180deg)}.metismenu.mod-menu .parent>ul{color:#22262a}.sidebar-left .metismenu .mm-collapse,.sidebar-right .metismenu .mm-collapse{position:relative;background-color:hsla(0,0%,0%,.03)}.sidebar-left .metismenu li.parent>ul,.sidebar-right .metismenu li.parent>ul{position:relative;top:0;-webkit-box-shadow:none;box-shadow:none}.sidebar-left .metismenu .metismenu-item>a,.sidebar-left .metismenu .metismenu-item>span,.sidebar-right .metismenu .metismenu-item>a,.sidebar-right .metismenu .metismenu-item>span{white-space:inherit}.sidebar-left .metismenu .metismenu-item.divider:not(.parent),.sidebar-right .metismenu .metismenu-item.divider:not(.parent){width:auto;height:1px;border-bottom:1px solid #cdd3d9}.minicolors-theme-bootstrap .minicolors-input{width:120px}.minicolors-theme-bootstrap .rgb{width:175px}.minicolors-theme-bootstrap .rgba{width:220px}.editor .toggle-editor{margin-top:1rem}.editor .mce-tinymce{border:1px solid #dfe2e6;border-radius:.25rem}.editor .mce-btn,.editor .mce-panel{background:#f9f9fa}.tox{white-space:nowrap}.border-primary{border-color:var(--primary)}.border-secondary{border-color:var(--secondary)}.border-success{border-color:var(--success)}.border-info{border-color:var(--info)}.border-warning{border-color:var(--warning)}.border-danger{border-color:var(--danger)}.border-light{border-color:var(--light)}.border-dark{border-color:var(--dark)}.border-white{border-color:var(--white)}.text-primary{color:var(--primary)}.text-secondary{color:var(--secondary)}.text-success{color:var(--success)}.text-info{color:var(--info)}.text-warning{color:var(--warning)}.text-danger{color:var(--danger)}.text-light{color:var(--light)}.text-dark{color:var(--dark)}.text-black{color:var(--black)}.text-white{color:var(--white)}.text-body{color:var(--body-color)}.bg-primary{background-color:var(--primary)}.bg-secondary{background-color:var(--secondary)}.bg-success{background-color:var(--success)}.bg-info{background-color:var(--info)}.bg-warning{background-color:var(--warning)}.bg-danger{background-color:var(--danger)}.bg-light{background-color:var(--light)}.bg-dark{background-color:var(--dark)}.bg-black{background-color:var(--black)}.bg-white{background-color:var(--white)}.bg-body{background-color:var(--body-bg)}/*! VM BASIC */.dropdown-menu{border-radius:0;--bs-dropdown-zindex:1030}.dropdown-toggle{display:flex;align-items:center}.dropdown-toggle::after{content:"";border:none;background-image:url('data:image/svg+xml, ');background-repeat:no-repeat;width:10px;height:10px}.input-group .btn{font-size:14px;border-radius:var(--bs-border-radius)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--btn-active-text-gray)}.form-control,.form-select{font-size:14px}form .form-control,form .form-select{border-color:var(--input-border-color)}.container-below-topbar{padding:var(--padding-x) var(--padding-y);background-image:var(--container-below-topbar-bg-image);background-color:var(--container-below-topbar-bg-color);background-size:var(--container-below-topbar-bg-size);-webkit-box-shadow:0 5px 5px hsla(0,0%,0%,.03) inset;box-shadow:0 5px 5px hsla(0,0%,0%,.03) inset;background-repeat:var(--container-below-topbar-background-repeat);-webkit-border-radius:var(--container-below-topbar-border-radius);-moz-border-radius:var(--container-below-topbar-border-radius);border-radius:var(--container-below-topbar-border-radius);border:var(--container-below-topbar-border);color:var(--color-primary)}.container-top-a{padding-left:var(--padding-x);padding-right:var(--padding-x);background-image:var(--container-top-a-bg-image);background-color:var(--container-top-a-bg-color);background-size:var(--container-top-a-bg-size);-webkit-box-shadow:0 5px 5px hsla(0,0%,0%,.03) inset;box-shadow:0 5px 5px hsla(0,0%,0%,.03) inset;background-repeat:var(--container-top-a-background-repeat);-webkit-border-radius:var(--container-top-a-border-radius);-moz-border-radius:var(--container-top-a-border-radius);border-radius:var(--container-top-a-border-radius);border:var(--container-top-a-border)}.container-top-b{padding-left:var(--padding-x);padding-right:var(--padding-x);background-image:var(--container-top-b-bg-image);background-color:var(--container-top-b-bg-color);background-size:var(--container-top-b-bg-size);-webkit-box-shadow:0 5px 5px hsla(0,0%,0%,.03) inset;box-shadow:0 5px 5px hsla(0,0%,0%,.03) inset;background-repeat:var(--container-top-b-background-repeat);-webkit-border-radius:var(--container-top-b-border-radius);-moz-border-radius:var(--container-top-b-border-radius);border-radius:var(--container-top-b-border-radius);border:var(--container-top-b-border)}.container-sidebar-left,.container-sidebar-right{padding-left:var(--padding-x);padding-right:var(--padding-x);background-image:var(--container-sidebar-bg-image);background-color:var(--container-sidebar-bg-color);background-size:var(--container-sidebar-bg-size);-webkit-box-shadow:0 5px 5px hsla(0,0%,0%,.03) inset;box-shadow:0 5px 5px hsla(0,0%,0%,.03) inset;background-repeat:var(--container-sidebar-background-repeat);-webkit-border-radius:var(--container-sidebar-border-radius);-moz-border-radius:var(--container-sidebar-border-radius);border-radius:var(--container-sidebar-border-radius);border:var(--container-sidebar-border)}.container-bottom-a{padding-left:var(--padding-x);padding-right:var(--padding-x);background-image:var(--container-bottom-a-bg-image);background-color:var(--container-bottom-a-bg-color);background-size:var(--container-bottom-a-bg-size);-webkit-box-shadow:0 5px 5px hsla(0,0%,0%,.03) inset;box-shadow:0 5px 5px hsla(0,0%,0%,.03) inset;background-repeat:var(--container-bottom-a-background-repeat);-webkit-border-radius:var(--container-bottom-a-border-radius);-moz-border-radius:var(--container-bottom-a-border-radius);border-radius:var(--container-bottom-a-border-radius);border:var(--container-bottom-a-border)}.container-bottom-b{grid-area:bot-b;padding-left:var(--padding-x);padding-right:var(--padding-x);background-image:var(--container-bottom-b-bg-image);background-color:var(--container-bottom-b-bg-color);background-size:var(--container-bottom-b-bg-size);-webkit-box-shadow:0 5px 5px hsla(0,0%,0%,.03) inset;box-shadow:0 5px 5px hsla(0,0%,0%,.03) inset;background-repeat:var(--container-bottom-b-background-repeat);-webkit-border-radius:var(--container-bottom-b-border-radius);-moz-border-radius:var(--container-bottom-b-border-radius);border-radius:var(--container-bottom-b-border-radius);border:var(--container-bottom-b-border)}#mokoThemeFab{position:fixed;z-index:1200;display:flex;align-items:center;gap:.5rem;padding:calc(var(--padding-x,.25rem) * 2) calc(var(--padding-y,.25rem) * 3) calc(var(--padding-x,.25rem) * 2) calc(var(--padding-y,.25rem) * 8);border-radius:999px;border:none;background:var(--muted-color);box-shadow:var(--box-shadow);font:inherit;color:var(--body-bg);font-weight:600px}#mokoThemeFab.pos-br{right:2.5rem;bottom:1rem}#mokoThemeFab.pos-bl{left:2.5rem;bottom:1rem}#mokoThemeFab.pos-tr{right:2.5rem;top:1rem}#mokoThemeFab.pos-tl{left:2.5rem;top:1rem}#mokoThemeFab .switch{display:inline-flex;align-items:center;position:relative;width:44px;height:24px;background:var(--secondary-color);transition:background .2s,border-color .2s;border-radius:var(--border-radius-xxl)}#mokoThemeFab button{color:var(--body-bg)}body.site.error-page{margin:0;padding:0}.error-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:2rem}.error-card{max-width:820px;width:100%;border:1px solid;border-radius:14px;padding:2rem;background:var(--template-bg-light,#fff)}.error-brand{display:flex;align-items:center;gap:1rem;margin-bottom:1rem}.error-brand .brand-logo{background-color:invert(var(--body-bg));padding:var(--border-radius-sxl);border-radius:var(--border-radius-2xl)}.error-brand .logo{max-height:48px;width:auto;display:block}.error-title{margin:.5rem 0 0;font-size:clamp(1.5rem, 2vw + 1rem, 2.25rem);font-weight:700}.error-code{opacity:.75;font-weight:600}.error-actions{display:flex;flex-wrap:wrap;gap:.75rem;margin-top:1.25rem}.moko-offline-wrap{min-height:100vh;display:grid;grid-template-rows:auto 1fr auto}.moko-offline-main{display:grid;place-items:center;padding:2rem 1rem}.moko-card{max-width:720px;width:100%}.moko-brand{display:flex;align-items:center;gap:.75rem;text-decoration:none}.moko-brand .brand-tagline{display:block;opacity:.75;font-size:.875rem;line-height:1.2}.theme-switcher .dropdown-item.active{font-weight:600}.skip-link{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden}.skip-l ink:focus{position:static;width:auto;height:auto;padding:.5rem 1rem}.btn{display:inline-flex;align-items:center;gap:.5rem;border:1px solid;border-radius:8px;padding:.5rem .9rem;text-decoration:none}#mokoThemeFab .knob{position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:var(--border-radius-xxl);background:var(--bs-body-bg,#fff);box-shadow:var(--box-shadow);transition:transform .2s}#mokoThemeFab [role=switch][aria-checked=true] .knob{transform:translateX(20px)}#mokoThemeFab [role=switch][aria-checked=true] .switch{background:rgba(var(--secondary-color),.15)}button#mokoThemeSwitch{border:unset;background-color:unset}#mokoThemeFab .label{user-select:none;font-size:.875rem}#mokoThemeFab.debug-outline{outline:2px dashed var(--pink);outline-offset:2px}html.component body{padding-top:3.125rem}#view_gabble{background-color:var(--gab-blue);padding:.375rem;border-radius:6px}#mod_gabble{background-color:var(--gab-blue);padding:.1875rem;border-radius:6px}#lists_gabble{position:relative;height:100%;border:4px solid var(--gab-red);background-color:var(--gab-green);padding:.25rem;border-radius:6px}#select_list{margin-left:0;width:100%;padding:.25rem;border-radius:6px 6px 0 0}#options_list{width:100%;padding:.25rem}#frame_list{width:100%;height:484px;padding:.25rem;border-radius:0 0 6px 6px}#windows_list{margin-left:0;width:100%;border:4px solid var(--gab-red);background-color:var(--gab-green);padding:.25rem;border-radius:6px}#frame_window{width:100%}#openai_btn{position:absolute;right:10px;bottom:10px;visibility:hidden;width:34px;height:34px;cursor:pointer;border:3px solid var(--gab-gray3);background-color:var(--white);border-radius:17px}#openai_btn:hover{width:36px;height:36px;border:3px solid var(--gab-gray3);border-radius:18px}#openai_logo_anim{position:absolute;top:15px;right:15px;width:35px;height:35px;padding:.125rem;z-index:1;border-radius:10px}.openai_logo_sm{width:22px;height:22px;background-color:var(--white);border:3px solid var(--white);border-radius:11px}.openai_logo_md{width:34px;height:34px;background-color:var(--white);border:4px solid var(--white);border-radius:17px}.btn_on_com{position:absolute;bottom:-2px;left:-2px;width:12px;height:12px;background-color:var(--indicator-success-bg);border-radius:6px}.btn_on_mod{position:absolute;top:0;left:0;width:12px;height:12px;background-color:var(--indicator-success-bg);border-radius:6px}.button_list{border:none;width:100%;outline:0;background-color:var(--gab-gray1);padding:.375rem;border-radius:6px}.button_list:hover{background-color:var(--gab-gray2)}.button_list_s{border:none;width:100%;outline:0;cursor:pointer;color:var(--white);background-color:var(--gab-red);padding:.375rem;border-radius:6px}.window_list{position:relative;margin:.25rem;width:100%;border:none;outline:0;cursor:pointer;text-align:left;background-color:var(--gab-gray1);padding:.375rem;border-radius:6px}.window_list:hover{background-color:var(--gab-gray2)}.window_list_s{position:relative;margin:.25rem;width:100%;border:none;outline:0;cursor:pointer;text-align:left;color:var(--white);background-color:var(--gab-red);padding:.375rem;border-radius:6px}.btn_close{position:absolute;right:4px;top:10px;padding-left:.0625rem;width:16px;height:16px;color:var(--black);font-size:10px;text-align:center;background-color:var(--gab-gray2);border-radius:8px}.btn_close:hover{background-color:var(--gab-gray3)}.iframe_list,.iframe_messages{width:100%;height:100%;background-color:var(--white);border:4px solid var(--gab-red);border-radius:6px}.input_box{position:relative}.input_emoji{position:absolute;right:48px;top:11px;cursor:pointer;color:var(--gab-gray2)}.input_emoji:hover{color:var(--gab-gray3)}.emoji{display:inline-block;float:left;cursor:pointer;padding:.125rem;background-color:var(--white)}.emoji:hover{background-color:var(--gab-orange)}.emojis_div{position:absolute;top:-92px;right:0;width:200px;height:92px;border:4px solid var(--gab-red);background-color:var(--gab-gray1);border-radius:6px}.msg-button-on{margin-left:.3125rem;width:30px;height:30px;font-size:20px;text-align:center;color:var(--white);background-color:var(--gab-orange);border-radius:15px}.msg-button-off{margin-left:.3125rem;width:30px;height:30px;font-size:20px;text-align:center;color:var(--white);background-color:var(--gab-gray2);border-radius:15px}.taba-content{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}.msg-input{padding-left:.625rem;padding-right:1.625rem;width:calc(100% - 35px);height:30px;border-radius:15px}.main-windows{position:fixed;margin-bottom:.625rem;bottom:0;right:90px;z-index:901}.list-windows{position:fixed;bottom:0;right:0;width:50px;margin-bottom:1.25rem;margin-right:1.25rem;z-index:901}.item-list{display:inline-block;color:var(--item-list-color);margin-top:.3125rem;width:50px;height:50px;font-size:30px;text-align:center;border:3px solid var(--gab-red);background-color:var(--gab-blue);border-radius:25px}.button{opacity:1}.button:hover{cursor:pointer;opacity:.6}.notifications{position:relative}.n-notifications{position:absolute;bottom:-6px;right:-2px;width:18px;height:18px;color:var(--white);font-size:11px;font-weight:700;text-align:center;background-color:var(--notification-badge-bg);border-radius:9px}.m-notifications{position:absolute;top:-6px;right:-2px;width:18px;height:18px;color:var(--white);font-size:11px;font-weight:700;text-align:center;background-color:var(--notification-badge-bg);border-radius:9px}.window{display:inline-block;margin-left:.5rem;width:280px;height:420px}.window-com{margin-top:.375rem;width:100%;height:480px}.window-title{margin-left:.3125rem;display:inline-block;color:var(--white)}.window-title-com{margin-left:.3125rem;display:inline-block;color:var(--black)}.window-icon{display:inline-block;color:var(--white)}.window-header{padding:.375rem;width:100%;height:40px;background-color:var(--gab-blue);border-radius:8px 8px 0 0}.window-header-com{padding:.25rem;width:100%;height:35px;background-color:var(--gab-red);border-radius:8px 8px 0 0}.window-content{position:relative;display:block;width:100%;height:calc(100% - 80px);background-color:var(--content-bg-gray)}.content-footer{position:relative;padding:.3125rem;width:100%;height:40px;background-color:var(--content-bg-gray);border-radius:0 0 8px 8px}.taba-btn{text-align:center;display:inline-block;margin-left:.3125rem;float:right;width:24px;height:24px;background-color:var(--content-bg-gray);border-radius:12px}.taba-hover{cursor:pointer;opacity:1}.taba-hover:hover{opacity:.6}.taba-self{border:1px solid var(--white);background-color:var(--taba-btn-green);padding:.5625rem .375rem .375rem;border-radius:10px}.taba-others{border:1px solid var(--white);background-color:var(--taba-btn-blue);padding:.5625rem .375rem .375rem;border-radius:10px}.taba-bot{border:1px solid var(--white);background-color:var(--gab-gray3);padding:.5625rem .375rem .375rem;border-radius:10px}.taba-dice{border:1px solid var(--white);background-color:var(--taba-btn-red);padding:.375rem;border-radius:10px}.taba-emoji{border:1px solid var(--white);background-color:var(--taba-btn-blue);padding:.375rem;border-radius:10px}.taba-user{border:1px solid var(--white);background-color:var(--white);padding:.375rem;border-radius:6px;word-wrap:break-word}.taba-user-on{border:1px solid #fff;background-color:var(--gab-green);padding:.375rem;border-radius:8px}.taba-feed{border:1px solid #fff;background-color:var(--gab-blue);padding:.375rem;border-radius:8px}.openai_error{border:1px solid #fff;background-color:var(--gab-red);padding:.375rem;border-radius:8px}.taba-msgsystem{border:1px solid var(--white);background-color:var(--taba-btn-gray);padding:.375rem;border-radius:10px}.taba-msghead{background-color:var(--taba-msg-bg);padding:.25rem .375rem .25rem .625rem;border-radius:6px 6px 0 0}.taba-msg{background-color:var(--taba-msg-bg);padding:.5rem;border-radius:0 8px 8px;word-wrap:break-word}nav[data-toggle=toc] .nav>li>a{display:block;padding:.25rem 1.25rem;font-size:13px;font-weight:500;color:var(--toc-link-color)}nav[data-toggle=toc] .nav>li>a:focus,nav[data-toggle=toc] .nav>li>a:hover{padding-left:1.1875rem;color:var(--toc-link-active-color);text-decoration:none;background-color:transparent;border-left:1px solid var(--toc-link-active-color)}nav[data-toggle=toc] .nav-link.active,nav[data-toggle=toc] .nav-link.active:focus,nav[data-toggle=toc] .nav-link.active:hover{padding-left:1.125rem;font-weight:700;color:var(--toc-link-active-color);background-color:transparent;border-left:2px solid var(--toc-link-active-color)}nav[data-toggle=toc] .nav-link+ul{display:none;padding-bottom:.625rem}nav[data-toggle=toc] .nav .nav>li>a{padding-top:.0625rem;padding-bottom:.0625rem;padding-left:1.875rem;font-size:12px;font-weight:400}nav[data-toggle=toc] .nav .nav>li>a:focus,nav[data-toggle=toc] .nav .nav>li>a:hover{padding-left:1.8125rem}nav[data-toggle=toc] .nav .nav>li>.active,nav[data-toggle=toc] .nav .nav>li>.active:focus,nav[data-toggle=toc] .nav .nav>li>.active:hover{padding-left:1.75rem;font-weight:500}nav[data-toggle=toc] .nav-link.active+ul{display:block}.choices{position:relative;overflow:hidden;margin-bottom:1.5rem;font-size:16px}.choices:focus{outline:0}.choices:last-child{margin-bottom:0}.choices.is-open{overflow:initial}.choices.is-disabled .choices__inner,.choices.is-disabled .choices__input{background-color:var(--choices-disabled-bg);cursor:not-allowed;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.choices.is-disabled .choices__item{cursor:not-allowed}.choices [hidden]{display:none!important}.choices[data-type*=select-one]{cursor:pointer}.choices[data-type*=select-one] .choices__inner{padding-bottom:.46875rem}.choices[data-type*=select-one] .choices__input{display:block;width:100%;padding:.625rem;border-bottom:1px solid var(--choices-border-light);background-color:var(--choices-input-bg);margin:0}.choices[data-type*=select-one] .choices__button{background-image:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==");padding:0;background-size:8px;position:absolute;top:50%;right:0;margin-top:-.625rem;margin-right:1.5625rem;height:20px;width:20px;border-radius:10em;opacity:.25}.choices[data-type*=select-one] .choices__button:focus,.choices[data-type*=select-one] .choices__button:hover{opacity:1}.choices[data-type*=select-one] .choices__button:focus{-webkit-box-shadow:0 0 0 2px #00bcd4;box-shadow:0 0 0 2px #00bcd4}.choices[data-type*=select-one] .choices__item[data-value=""] .choices__button{display:none}.choices[data-type*=select-one]::after{content:"";height:0;width:0;border-style:solid;border-color:var(--choices-arrow-color) transparent transparent transparent;border-width:5px;position:absolute;right:11.5px;top:50%;margin-top:-.15625rem;pointer-events:none}.choices[data-type*=select-one].is-open::after{border-color:transparent transparent var(--choices-arrow-color) transparent;margin-top:-.46875rem}.choices[data-type*=select-one][dir=rtl]::after{left:11.5px;right:auto}.choices[data-type*=select-one][dir=rtl] .choices__button{right:auto;left:0;margin-left:1.5625rem;margin-right:0}.choices[data-type*=select-multiple] .choices__inner,.choices[data-type*=text] .choices__inner{cursor:text}.choices[data-type*=select-multiple] .choices__button,.choices[data-type*=text] .choices__button{position:relative;display:inline-block;margin:0 -.25rem 0 .5rem;padding-left:1rem;border-left:1px solid #008fa1;background-image:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjRkZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==");background-size:8px;width:8px;line-height:1;opacity:.75;border-radius:0}.choices[data-type*=select-multiple] .choices__button:focus,.choices[data-type*=select-multiple] .choices__button:hover,.choices[data-type*=text] .choices__button:focus,.choices[data-type*=text] .choices__button:hover{opacity:1}.choices__inner{display:inline-block;vertical-align:top;width:100%;background-color:var(--choices-inner-bg);border:1px solid var(--choices-border-light);min-height:44px;overflow:hidden}.is-focused .choices__inner,.is-open .choices__inner{border-color:var(--choices-focused-border)}.is-open .choices__inner{border-radius:2.5px 2.5px 0 0}.is-flipped.is-open .choices__inner{border-radius:0 0 2.5px 2.5px}.choices__list{margin:0;padding-left:0;list-style:none}.choices__list--single{display:inline-block;padding:.25rem 1rem .25rem .25rem;width:100%}[dir=rtl] .choices__list--single{padding-right:.25rem;padding-left:1rem}.choices__list--single .choices__item{width:100%}.choices__list--multiple{display:inline}.choices__list--multiple .choices__item{display:inline-block;vertical-align:middle;padding:.25rem .625rem;font-size:12px;font-weight:500;background-color:var(--choices-item-bg);border:1px solid var(--choices-item-border);color:var(--white);word-break:break-all;-webkit-box-sizing:border-box;box-sizing:border-box}.choices__list--multiple .choices__item[data-deletable]{padding-right:.3125rem}[dir=rtl] .choices__list--multiple .choices__item{margin-right:0;margin-left:.234375rem}.choices__list--multiple .choices__item.is-highlighted{background-color:var(--choices-item-hover-bg);border:1px solid var(--choices-item-hover-border)}.is-disabled .choices__list--multiple .choices__item{background-color:var(--choices-item-disabled-bg);border:1px solid var(--choices-item-disabled-border)}.choices__list--dropdown{visibility:hidden;position:absolute;width:100%;background-color:var(--choices-dropdown-bg);border:1px solid var(--choices-border-light);top:100%;margin-top:-.0625rem;border-bottom-left-radius:2.5px;border-bottom-right-radius:2.5px;overflow:hidden;word-break:break-all;will-change:visibility;z-index:1060}.choices__list--dropdown.is-active{visibility:visible}.is-open .choices__list--dropdown{border-color:var(--choices-focused-border)}.is-flipped .choices__list--dropdown{top:auto;bottom:100%;margin-top:0;margin-bottom:-.0625rem;border-radius:.25rem .25rem 0 0}.choices__list--dropdown .choices__list{position:relative;max-height:300px;overflow:auto;-webkit-overflow-scrolling:touch;will-change:scroll-position}.choices__list--dropdown .choices__item{position:relative;padding:.625rem;font-size:14px}[dir=rtl] .choices__list--dropdown .choices__item{text-align:right}@media (min-width:640px){.choices__list--dropdown .choices__item--selectable{padding-right:6.25rem}.choices__list--dropdown .choices__item--selectable::after{content:attr(data-select-text);font-size:12px;opacity:0;position:absolute;right:10px;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}[dir=rtl] .choices__list--dropdown .choices__item--selectable{text-align:right;padding-left:6.25rem;padding-right:.625rem}[dir=rtl] .choices__list--dropdown .choices__item--selectable::after{right:auto;left:10px}}.choices__list--dropdown .choices__item--selectable.is-highlighted{background-color:var(--choices-item-highlighted)}.choices__list--dropdown .choices__item--selectable.is-highlighted::after{opacity:.5}.choices__item{cursor:default}.choices__item--selectable{cursor:pointer}.choices__item--disabled{cursor:not-allowed;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;opacity:.5}.choices__heading{font-weight:600;padding:.625rem;border-bottom:1px solid #f7f7f7;color:gray}.choices__button{text-indent:-9999px;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:0;background-color:transparent;background-repeat:no-repeat;background-position:center;cursor:pointer}.choices__button:focus{outline:0}.choices__input{display:inline-block;vertical-align:baseline;background-color:var(--choices-input-inner-bg);border:0;border-radius:0;max-width:100%}.choices__input:focus{outline:0}[dir=rtl] .choices__input{padding-right:.125rem;padding-left:0}.choices__placeholder{opacity:.5}.choices{border:1px solid #cdd3d9;border-radius:.25rem}.choices.is-focused{border-color:var(--input-focus-border-color);-webkit-box-shadow:0 0 0 .25rem rgba(1,1,86,.25);box-shadow:0 0 0 .25rem rgba(1,1,86,.25)}.choices__inner{padding:.4rem 1rem;margin-bottom:0;font-size:1rem;border:none;border-radius:0}.choices__input{padding:0;margin-bottom:0;font-size:1rem;background-color:transparent}.choices__input::-webkit-input-placeholder{color:#474f56;opacity:1}.choices__input::-moz-placeholder{color:#474f56;opacity:1}.choices__input:-ms-input-placeholder{color:#474f56;opacity:1}.choices__input::-ms-input-placeholder{color:#474f56;opacity:1}.choices__input::placeholder{color:#474f56;opacity:1}.choices__list--multiple .choices__item{position:relative;margin:.125rem;background-color:var(--color-primary);-webkit-margin-end:.125rem;margin-inline-end:.125rem;border:0;border-radius:.25rem}.choices__list--multiple .choices__item.is-highlighted{background-color:var(--color-primary);opacity:.9}.choices .choices__list--dropdown .choices__item{-webkit-padding-end:0.625rem;padding-inline-end:0.625rem}.choices .choices__list--dropdown .choices__item--selectable::after{display:none}.choices__button_joomla{position:relative;padding:0 .625rem;color:inherit;text-indent:-9999px;cursor:pointer;background:0 0;border:0;opacity:.5;-webkit-appearance:none;-moz-appearance:none;appearance:none}.choices__button_joomla::before{position:absolute;top:0;right:0;bottom:0;left:0;display:block;text-align:center;text-indent:0;content:"×"}.choices__button_joomla:focus,.choices__button_joomla:hover{opacity:1}.choices__button_joomla:focus{outline:0}.choices[data-type*=select-multiple] .choices__inner,.choices[data-type*=select-one] .choices__inner{-webkit-padding-end:3rem;padding-inline-end:3rem;cursor:pointer;background:url("../../../images/select-bg.svg") 100%/116rem no-repeat #eaedf0}[dir=rtl] .choices[data-type*=select-multiple] .choices__inner,[dir=rtl] .choices[data-type*=select-one] .choices__inner{background:url("../../../images/select-bg-rtl.svg") 0/116rem no-repeat #eaedf0}.choices[data-type*=select-one] .choices__item{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.choices[data-type*=select-one] .choices__button_joomla{position:absolute;top:50%;inset-inline-end:0;width:20px;height:20px;padding:0;-webkit-margin-before:-0.625rem;margin-block-start:-0.625rem;-webkit-margin-end:3.125rem;margin-inline-end:3.125rem;border-radius:10em;opacity:.5}.choices[data-type*=select-one] .choices__button_joomla:focus,.choices[data-type*=select-one] .choices__button_joomla:hover{opacity:1}.choices[data-type*=select-one] .choices__button_joomla:focus{-webkit-box-shadow:0 0 0 2px #00bcd4;box-shadow:0 0 0 2px #00bcd4}.choices[data-type*=select-one]::after{display:none}.choices[data-type*=select-multiple] .choices__input,.choices[data-type*=text] .choices__input{padding:.2rem 0}.choices__heading{font-size:1.2rem}.site-title{color:var(--nav-bg-color);font-family:Osaka,sans-serif;font-weight:600;font-size:1.5rem;text-decoration:none;margin-left:var(--padding-x)}.container-header .navbar-brand .site-title{color:var(--nav-bg-color);text-decoration:none}.brand-logo,.container-header .navbar-brand a{text-decoration:none}.container-search button[type=submit],.mod-finder__search.input-group button{background-color:var(--color-primary);color:var(--mainmenu-nav-link-color);border-color:var(--color-primary);padding:.6rem 1rem;border-radius:0 .25rem .25rem 0;transition:background-color .15s ease-in-out,border-color .15s ease-in-out}.container-search button[type=submit]:hover,.mod-finder__search.input-group button:hover{background-color:var(--color-hover);border-color:var(--color-hover)}.container-search button[type=submit]:focus,.mod-finder__search.input-group button:focus{outline:0;box-shadow:0 0 0 .25rem rgba(var(--btn-focus-shadow-rgb),.5)}.container-header .container-search{position:relative}.container-search .mod-finder__search.input-group{display:flex;align-items:stretch;box-shadow:0 2px 8px rgba(0,0,0,.1);border-radius:.25rem;overflow:hidden;transition:box-shadow .2s ease-in-out}.container-search .mod-finder__search.input-group:focus-within{box-shadow:0 4px 12px rgba(0,0,0,.15)}.container-search .awesomplete input,.container-search .form-control{border-right:none;padding:.6rem 1rem;font-size:.95rem;border-radius:.25rem 0 0 .25rem}.container-search .awesomplete input:focus,.container-search .form-control:focus{border-color:var(--input-focus-border-color);box-shadow:none}.container-search .input-group button,.container-search button[type=submit]{display:flex;align-items:center;justify-content:center;min-width:3rem;font-weight:500}.container-search .icon-search{font-size:1rem;color:var(--nav-bg-color)}@media (max-width:991.98px){.container-header .container-nav{flex-direction:column}.container-header .container-nav nav{width:100%;margin-bottom:1rem}.container-header .container-search{width:100%;margin-top:.5rem}.mod-finder__search.input-group{max-width:100%}}@media (min-width:992px){.container-header .container-nav{display:flex;flex-direction:row;align-items:center;gap:2rem}.container-header .container-nav nav{flex:1}.container-header .container-search{flex:0 0 auto;min-width:300px;margin-top:0}}[class*=" icon-"]::before,[class^=icon-]::before{--_fa-family:var(--fa-family, var(--fa-style-family, "Font Awesome 7 Free"));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:var(--fa-display,inline-block);font-family:var(--_fa-family);font-feature-settings:normal;font-style:normal;font-synthesis:none;font-variant:normal;font-weight:var(--fa-style,900);line-height:1;text-align:center;text-rendering:auto;width:var(--fa-width,1.25em)}[class*=" icon-"],[class^=icon-]{display:inline-flex;align-items:center;justify-content:center}.icon-menu::before{content:"\f0c9"}.icon-search::before{content:"\f002"}.icon-user::before{content:"\f007"}.icon-edit::before{content:"\f044"}.icon-save::before{content:"\f0c7"}.icon-trash::before{content:"\f1f8"}.icon-cancel::before{content:"\f00d"}.icon-check::before{content:"\f00c"}.icon-plus::before{content:"\f067"}.icon-minus::before{content:"\f068"}.btn-success{--btn-color:white;--btn-bg:var(--success);--btn-border-color:var(--success);--btn-hover-bg:color-mix(in srgb, var(--success) 85%, black);--btn-hover-border-color:color-mix(in srgb, var(--success) 85%, black)}.btn-info{--btn-color:white;--btn-bg:var(--info);--btn-border-color:var(--info);--btn-hover-bg:color-mix(in srgb, var(--info) 85%, black);--btn-hover-border-color:color-mix(in srgb, var(--info) 85%, black)}.btn-warning{--btn-color:white;--btn-bg:var(--warning);--btn-border-color:var(--warning);--btn-hover-bg:color-mix(in srgb, var(--warning) 85%, black);--btn-hover-border-color:color-mix(in srgb, var(--warning) 85%, black)}.btn-danger{--btn-color:white;--btn-bg:var(--danger);--btn-border-color:var(--danger);--btn-hover-bg:color-mix(in srgb, var(--danger) 85%, black);--btn-hover-border-color:color-mix(in srgb, var(--danger) 85%, black)}.btn-light{--btn-color:var(--body-color);--btn-bg:var(--light);--btn-border-color:var(--light);--btn-hover-bg:color-mix(in srgb, var(--light) 90%, black);--btn-hover-border-color:color-mix(in srgb, var(--light) 90%, black)}.btn-dark{--btn-color:white;--btn-bg:var(--dark);--btn-border-color:var(--dark);--btn-hover-bg:color-mix(in srgb, var(--dark) 85%, black);--btn-hover-border-color:color-mix(in srgb, var(--dark) 85%, black)}.btn-outline-primary{--btn-color:var(--color-primary);--btn-border-color:var(--color-primary);--btn-hover-color:white;--btn-hover-bg:var(--color-primary);--btn-hover-border-color:var(--color-primary)}.btn-outline-secondary{--btn-color:var(--secondary);--btn-border-color:var(--secondary);--btn-hover-color:white;--btn-hover-bg:var(--secondary);--btn-hover-border-color:var(--secondary)}.btn-outline-success{--btn-color:var(--success);--btn-border-color:var(--success);--btn-hover-color:white;--btn-hover-bg:var(--success);--btn-hover-border-color:var(--success)}.btn-outline-info{--btn-color:var(--info);--btn-border-color:var(--info);--btn-hover-color:white;--btn-hover-bg:var(--info);--btn-hover-border-color:var(--info)}.btn-outline-warning{--btn-color:var(--warning);--btn-border-color:var(--warning);--btn-hover-color:white;--btn-hover-bg:var(--warning);--btn-hover-border-color:var(--warning)}.btn-outline-danger{--btn-color:var(--danger);--btn-border-color:var(--danger);--btn-hover-color:white;--btn-hover-bg:var(--danger);--btn-hover-border-color:var(--danger)}.btn-outline-light{--btn-color:var(--light);--btn-border-color:var(--light);--btn-hover-color:var(--body-color);--btn-hover-bg:var(--light);--btn-hover-border-color:var(--light)}.btn-outline-dark{--btn-color:var(--dark);--btn-border-color:var(--dark);--btn-hover-color:white;--btn-hover-bg:var(--dark);--btn-hover-border-color:var(--dark)}.alert-primary{--alert-bg:color-mix(in srgb, var(--primary) 10%, var(--body-bg));--alert-color:color-mix(in srgb, var(--primary) 90%, black);--alert-border-color:color-mix(in srgb, var(--primary) 20%, var(--body-bg))}.alert-secondary{--alert-bg:color-mix(in srgb, var(--secondary) 10%, var(--body-bg));--alert-color:color-mix(in srgb, var(--secondary) 90%, black);--alert-border-color:color-mix(in srgb, var(--secondary) 20%, var(--body-bg))}.alert-success{--alert-bg:color-mix(in srgb, var(--success) 10%, var(--body-bg));--alert-color:color-mix(in srgb, var(--success) 90%, black);--alert-border-color:color-mix(in srgb, var(--success) 20%, var(--body-bg))}.alert-info{--alert-bg:color-mix(in srgb, var(--info) 10%, var(--body-bg));--alert-color:color-mix(in srgb, var(--info) 90%, black);--alert-border-color:color-mix(in srgb, var(--info) 20%, var(--body-bg))}.alert-warning{--alert-bg:color-mix(in srgb, var(--warning) 10%, var(--body-bg));--alert-color:color-mix(in srgb, var(--warning) 90%, black);--alert-border-color:color-mix(in srgb, var(--warning) 20%, var(--body-bg))}.alert-danger{--alert-bg:color-mix(in srgb, var(--danger) 10%, var(--body-bg));--alert-color:color-mix(in srgb, var(--danger) 90%, black);--alert-border-color:color-mix(in srgb, var(--danger) 20%, var(--body-bg))}.alert-light{--alert-bg:var(--light);--alert-color:var(--body-color);--alert-border-color:color-mix(in srgb, var(--light) 85%, black)}.alert-dark{--alert-bg:var(--dark);--alert-color:white;--alert-border-color:var(--dark)}.alert-message{--alert-bg:var(--alert-info, color-mix(in srgb, var(--info) 10%, var(--body-bg)));--alert-color:color-mix(in srgb, var(--info) 90%, black);--alert-border-color:color-mix(in srgb, var(--info) 20%, var(--body-bg))}.alert-error{--alert-bg:var(--alert-danger, color-mix(in srgb, var(--danger) 10%, var(--body-bg)));--alert-color:color-mix(in srgb, var(--danger) 90%, black);--alert-border-color:color-mix(in srgb, var(--danger) 20%, var(--body-bg))}.alert-notice{--alert-bg:var(--alert-warning, color-mix(in srgb, var(--warning) 10%, var(--body-bg)));--alert-color:color-mix(in srgb, var(--warning) 90%, black);--alert-border-color:color-mix(in srgb, var(--warning) 20%, var(--body-bg))}.mod-search-responsive{width:100%}.mod-search__form,.mod-search__input-wrapper{display:flex;flex-direction:column;gap:.5rem;width:100%}.mod-search__input-wrapper--inline{flex-direction:row;align-items:stretch}.mod-search__input{flex:1;min-width:0;padding:.5rem .75rem;font-size:1rem;line-height:1.5;border:1px solid var(--input-border-color,#dee2e6);border-radius:.375rem;background-color:var(--input-bg,#fff);color:var(--input-color,#212529);-webkit-appearance:none;appearance:none}.mod-search__input:focus{border-color:var(--color-primary,#0d6efd);outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.mod-search__button-wrapper{display:flex}.mod-search__button-wrapper--left,.mod-search__button-wrapper--right{flex-shrink:0}.mod-search__button{padding:.5rem 1rem;font-size:1rem;line-height:1.5;border-radius:.375rem;white-space:nowrap;min-height:44px;display:inline-flex;align-items:center;justify-content:center;gap:.5rem}.mod-search__button--icon{padding:.5rem;width:44px;height:44px}.mod-search__button--icon .icon-search{font-size:1.25rem}@media (max-width:575.98px){.mod-search__input{font-size:16px;padding:.625rem .875rem}.mod-search__button{padding:.625rem 1.25rem;font-size:1rem;min-height:48px}.mod-search__button--icon{width:48px;height:48px}.mod-search__input-wrapper--inline{flex-direction:column}.mod-search__button-wrapper--left .mod-search__button,.mod-search__button-wrapper--right .mod-search__button{width:100%}}@media (min-width:576px) and (max-width:767.98px){.mod-search__input-wrapper--inline{flex-direction:row}}@media (min-width:768px){.mod-search__form{flex-direction:row;align-items:center}.mod-search__input-wrapper--inline{flex-direction:row}.mod-search__button-wrapper--bottom,.mod-search__button-wrapper--top{flex:0 0 auto}}.mod-vm-cart-responsive{width:100%}.mod-vm-cart__header{display:flex;align-items:center;gap:.75rem;padding:1rem;background:var(--vm-surface);border:1px solid var(--vm-border);border-radius:var(--vm-block-radius);margin-bottom:1rem}.mod-vm-cart__icon{font-size:1.5rem;color:var(--vm-btn-primary-bg);flex-shrink:0}.mod-vm-cart__summary{flex:1;min-width:0}.mod-vm-cart__count{font-weight:600;color:var(--vm-text-strong);font-size:1rem}.mod-vm-cart__total{color:var(--vm-price-color);font-weight:700;font-size:var(--vm-price-size);margin-top:.25rem}.mod-vm-cart__products{display:flex;flex-direction:column;gap:1rem;margin-bottom:1rem}.mod-vm-cart__product{display:flex;gap:.75rem;padding:.75rem;background:var(--vm-surface-2);border:1px solid var(--vm-border);border-radius:var(--vm-block-radius);align-items:flex-start}.mod-vm-cart__product-image{flex-shrink:0;width:80px}.mod-vm-cart__product-image img{width:100%;height:auto;border-radius:var(--vm-input-radius)}.mod-vm-cart__product-details{flex:1;min-width:0}.mod-vm-cart__product-name{font-weight:600;margin-bottom:.25rem;line-height:1.4}.mod-vm-cart__product-name a{color:var(--vm-text-strong);text-decoration:none}.mod-vm-cart__product-name a:hover{color:var(--color-primary);text-decoration:underline}.mod-vm-cart__product-quantity{font-size:.875rem;color:var(--vm-text-muted);margin-bottom:.25rem}.mod-vm-cart__quantity-value{font-weight:600;color:var(--vm-text)}.mod-vm-cart__product-price{font-weight:700;color:var(--vm-price-color);margin-top:.25rem}.mod-vm-cart__product-remove{flex-shrink:0}.mod-vm-cart__remove-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background:var(--vm-surface);border:1px solid var(--vm-border);color:var(--danger);text-decoration:none;transition:.2s}.mod-vm-cart__remove-btn:hover{background:var(--danger);color:#fff;border-color:var(--danger)}.mod-vm-cart__actions{display:flex;flex-direction:column;gap:.5rem}.mod-vm-cart__btn{padding:var(--vm-btn-padding-y) var(--vm-btn-padding-x);border-radius:var(--vm-btn-radius);text-align:center;text-decoration:none;font-weight:600;min-height:44px;display:inline-flex;align-items:center;justify-content:center;transition:.2s}.mod-vm-cart__empty{text-align:center;padding:2rem 1rem;background:var(--vm-surface-2);border:1px solid var(--vm-border);border-radius:var(--vm-block-radius)}.mod-vm-cart__empty-icon{font-size:3rem;color:var(--vm-text-muted);display:block;margin-bottom:1rem}.mod-vm-cart__empty-text{color:var(--vm-text-muted);margin:0}.mod-vm-product-responsive{width:100%}.mod-vm-product__header{margin-bottom:1.5rem}.mod-vm-product__list{display:grid;gap:1.5rem}.mod-vm-product__list--div{grid-template-columns:1fr}.mod-vm-product__item{background:var(--vm-surface);border:1px solid var(--vm-border);border-radius:var(--vm-block-radius);box-shadow:var(--vm-block-shadow);overflow:hidden;transition:transform .2s,box-shadow .2s}.mod-vm-product__item:hover{transform:translateY(-2px);box-shadow:0 4px 12px rgba(0,0,0,.1)}.mod-vm-product__image{position:relative;overflow:hidden}.mod-vm-product__image img{width:100%;height:auto;display:block}.mod-vm-product__availability{position:absolute;top:.5rem;right:.5rem;padding:.25rem .75rem;background:var(--vm-availability-bg);color:var(--vm-availability-text);border-radius:var(--vm-alert-radius);font-size:.875rem;font-weight:600}.mod-vm-product__content{padding:1rem}.mod-vm-product__title{font-size:var(--vm-product-title-size);font-weight:var(--vm-product-title-weight);margin:0 0 .75rem;line-height:1.4}.mod-vm-product__title a{color:var(--vm-text-strong);text-decoration:none}.mod-vm-product__title a:hover{color:var(--color-primary);text-decoration:underline}.mod-vm-product__description{color:var(--vm-text-muted);font-size:.875rem;margin-bottom:1rem;line-height:1.6}.mod-vm-product__price{font-size:var(--vm-price-detail-size);font-weight:700;color:var(--vm-price-color);margin-bottom:1rem}.mod-vm-product__actions{display:flex;flex-direction:column;gap:.5rem}.mod-vm-product__btn{padding:var(--vm-btn-padding-y) var(--vm-btn-padding-x);border-radius:var(--vm-btn-radius);text-align:center;text-decoration:none;font-weight:600;min-height:44px;display:inline-flex;align-items:center;justify-content:center}.mod-vm-product__empty{text-align:center;padding:2rem 1rem;background:var(--vm-surface-2);border:1px solid var(--vm-border);border-radius:var(--vm-block-radius);color:var(--vm-text-muted)}.mod-vm-currencies-responsive{width:100%}.mod-vm-currencies__form{display:flex;flex-direction:column;gap:.5rem}.mod-vm-currencies__label{font-weight:600;color:var(--vm-text-strong);font-size:.875rem}.mod-vm-currencies__select-wrapper{position:relative;display:flex;align-items:center}.mod-vm-currencies__select{flex:1;padding:.5rem 2.5rem .5rem .75rem;font-size:1rem;line-height:1.5;border:1px solid var(--vm-border);border-radius:var(--vm-input-radius);background:var(--vm-surface);color:var(--vm-text);min-height:44px;appearance:none;-webkit-appearance:none;cursor:pointer}.mod-vm-currencies__select:focus{border-color:var(--color-primary);outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.mod-vm-currencies__icon{position:absolute;right:.75rem;pointer-events:none;color:var(--vm-text-muted)}.mod-vm-currencies__submit{padding:var(--vm-btn-padding-y) var(--vm-btn-padding-x);border-radius:var(--vm-btn-radius);min-height:44px}.mod-vm-currencies__text-after,.mod-vm-currencies__text-before{font-size:.875rem;color:var(--vm-text-muted)}.mod-vm-category-responsive{width:100%}.mod-vm-category__list{list-style:none;padding:0;margin:0}.mod-vm-category__item{margin-bottom:.5rem}.mod-vm-category__link{display:flex;align-items:center;gap:.75rem;padding:.75rem;background:var(--vm-surface);border:1px solid var(--vm-border);border-radius:var(--vm-input-radius);color:var(--vm-text);text-decoration:none;transition:.2s;min-height:44px}.mod-vm-category__link:hover{background:var(--vm-surface-2);border-color:var(--color-primary);color:var(--color-primary)}.mod-vm-category__link--active{background:var(--vm-btn-primary-bg);border-color:var(--vm-btn-primary-bg);color:var(--vm-btn-primary-text);font-weight:600}.mod-vm-category__image{flex-shrink:0;width:40px;height:40px;overflow:hidden;border-radius:var(--vm-input-radius)}.mod-vm-category__image img{width:100%;height:100%;object-fit:cover}.mod-vm-category__name{flex:1;min-width:0}.mod-vm-category__count{color:var(--vm-text-muted);font-size:.875rem;flex-shrink:0}.mod-vm-category__description{padding:.5rem .75rem;font-size:.875rem;color:var(--vm-text-muted);line-height:1.6}.mod-vm-category__sublist{list-style:none;padding:0 0 0 1.5rem;margin:.5rem 0 0}.mod-vm-category__subitem{margin-bottom:.25rem}.mod-vm-category__sublink{display:flex;align-items:center;justify-content:space-between;padding:.5rem .75rem;background:var(--vm-surface-2);border:1px solid var(--vm-border);border-radius:var(--vm-input-radius);color:var(--vm-text);text-decoration:none;font-size:.875rem;transition:.2s;min-height:40px}.mod-vm-category__sublink:hover{background:var(--vm-surface);border-color:var(--color-primary);color:var(--color-primary)}.mod-vm-category__sublink--active{background:var(--vm-btn-secondary-bg);border-color:var(--vm-btn-secondary-bg);color:var(--vm-btn-secondary-text);font-weight:600}.mod-vm-category__empty{text-align:center;padding:2rem 1rem;background:var(--vm-surface-2);border:1px solid var(--vm-border);border-radius:var(--vm-block-radius);color:var(--vm-text-muted)}.mod-vm-manufacturer-responsive{width:100%}.mod-vm-manufacturer__container{display:grid;gap:1rem}.mod-vm-manufacturer__container--list{grid-template-columns:1fr}.mod-vm-manufacturer__container--grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}.mod-vm-manufacturer__item{background:var(--vm-surface);border:1px solid var(--vm-border);border-radius:var(--vm-block-radius);overflow:hidden;transition:transform .2s,box-shadow .2s}.mod-vm-manufacturer__item:hover{transform:translateY(-2px);box-shadow:var(--vm-block-shadow)}.mod-vm-manufacturer__link{display:block;text-decoration:none;color:var(--vm-text);min-height:44px}.mod-vm-manufacturer__image{width:100%;aspect-ratio:16/9;overflow:hidden;background:var(--vm-surface-2);display:flex;align-items:center;justify-content:center}.mod-vm-manufacturer__image img{width:100%;height:100%;object-fit:contain;padding:1rem}.mod-vm-manufacturer__content{padding:1rem}.mod-vm-manufacturer__name{font-weight:600;color:var(--vm-text-strong);display:block;margin-bottom:.5rem}.mod-vm-manufacturer__link:hover .mod-vm-manufacturer__name{color:var(--color-primary)}.mod-vm-manufacturer__description{font-size:.875rem;color:var(--vm-text-muted);line-height:1.6}.mod-vm-manufacturer__empty{text-align:center;padding:2rem 1rem;background:var(--vm-surface-2);border:1px solid var(--vm-border);border-radius:var(--vm-block-radius);color:var(--vm-text-muted)}@media (max-width:575.98px){.mod-vm-cart__header{padding:.75rem}.mod-vm-cart__product{flex-direction:column}.mod-vm-cart__product-image{width:100%;max-width:200px;margin:0 auto}.mod-vm-cart__actions{gap:.75rem}.mod-vm-cart__btn{min-height:48px;padding:.75rem 1rem;font-size:1rem}.mod-vm-product__actions{gap:.75rem}.mod-vm-product__btn{min-height:48px;padding:.75rem 1rem}.mod-vm-currencies__select{font-size:16px;min-height:48px;padding:.75rem 2.5rem .75rem 1rem}.mod-vm-currencies__submit{min-height:48px;padding:.75rem 1rem}.mod-vm-category__link{min-height:48px;padding:.875rem}.mod-vm-category__sublink{min-height:44px}.mod-vm-manufacturer__container--grid{grid-template-columns:1fr}}@media (min-width:576px) and (max-width:767.98px){.mod-vm-manufacturer__container--grid,.mod-vm-product__list--div{grid-template-columns:repeat(2,1fr)}}@media (min-width:768px){.mod-vm-cart__actions{flex-direction:row}.mod-vm-product__list--div{grid-template-columns:repeat(3,1fr)}.mod-vm-product__actions{flex-direction:row}.mod-vm-manufacturer__container--grid{grid-template-columns:repeat(3,1fr)}}.mod-menu-responsive{width:100%}.mod-menu__heading{margin-bottom:1rem;font-weight:600}.mod-menu-main{background-color:var(--body-bg);padding:.5rem 0}.mod-menu-main .navbar-toggler{border-color:var(--border-color);padding:.5rem .75rem;font-size:1.25rem;min-height:48px}.mod-menu-main .navbar-toggler:focus{box-shadow:0 0 0 .25rem rgba(var(--link-color-rgb),.25);outline:0}.mod-menu-main .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(0, 0, 0, 0.75)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.mod-menu-main__list{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.5rem}.mod-menu-main__item{position:relative}.mod-menu-main__heading,.mod-menu-main__link{display:block;padding:.75rem 1rem;color:var(--link-color);text-decoration:none;transition:background-color .2s,color .2s;min-height:48px;display:flex;align-items:center;border-radius:var(--border-radius)}.mod-menu-main__link:focus,.mod-menu-main__link:hover{background-color:var(--secondary-bg);color:var(--link-hover-color);text-decoration:none}.mod-menu-main__item.active>.mod-menu-main__link,.mod-menu-main__item.current>.mod-menu-main__link{background-color:var(--primary-bg);color:var(--white);font-weight:600}.mod-menu-main__dropdown{list-style:none;padding:.5rem 0;margin:0;background-color:var(--body-bg);border:1px solid var(--border-color);border-radius:var(--border-radius);box-shadow:0 .5rem 1rem rgba(0,0,0,.15);display:none}.mod-menu-main__item.dropdown.show>.mod-menu-main__dropdown{display:block}.mod-menu-main__dropdown .mod-menu-main__item{padding:0}.mod-menu-main__dropdown .mod-menu-main__link{padding:.5rem 1.5rem;min-height:44px}.mod-menu-main__dropdown .mod-menu-main__link:focus,.mod-menu-main__dropdown .mod-menu-main__link:hover{background-color:var(--secondary-bg)}.mod-menu-main__separator{border-top:1px solid var(--border-color);margin:.5rem 0;padding:0}.mod-menu-main__heading.dropdown-toggle::after,.mod-menu-main__link.dropdown-toggle::after{content:"";display:inline-block;margin-left:auto;padding-left:.5rem;vertical-align:middle;border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}@media (min-width:768px){.mod-menu-main__list{flex-direction:row;flex-wrap:wrap;gap:0}.mod-menu-main__heading,.mod-menu-main__link{min-height:44px;padding:.5rem 1rem}.mod-menu-main__item.dropdown{position:relative}.mod-menu-main__dropdown{position:absolute;top:100%;left:0;min-width:200px;z-index:1000;margin-top:.125rem}.mod-menu-main__item.dropdown:hover>.mod-menu-main__dropdown{display:block}.mod-menu-main__dropdown .mod-menu-main__dropdown{top:0;left:100%;margin-top:0;margin-left:.125rem}}@media (min-width:992px){.mod-vm-manufacturer__container--grid,.mod-vm-product__list--div{grid-template-columns:repeat(4,1fr)}.mod-menu-main{padding:1rem 0}.mod-menu-main__list{gap:.25rem}}.mod-breadcrumbs-responsive{width:100%;padding:.75rem 0}.mod-breadcrumbs__prefix{font-weight:600;margin-right:.5rem;color:var(--body-color)}.mod-breadcrumbs__list{display:flex;flex-wrap:wrap;gap:.5rem;list-style:none;padding:0;margin:0;align-items:center}.mod-breadcrumbs__item{display:flex;align-items:center}.mod-breadcrumbs__item:not(:last-child)::after{content:"/";margin-left:.5rem;color:var(--gray-500)}.mod-breadcrumbs__link{color:var(--link-color);text-decoration:none;transition:color .2s}.mod-breadcrumbs__link:hover{color:var(--link-hover-color);text-decoration:underline}.mod-breadcrumbs__current{color:var(--body-color);font-weight:600}.mod-breadcrumbs__item--home .icon-home{font-size:1.25rem}.mod-login-responsive{width:100%}.mod-login__form{display:flex;flex-direction:column;gap:1rem}.mod-login__greeting{padding:1rem;background:var(--secondary-bg);border-radius:var(--border-radius);margin-bottom:1rem;font-weight:600}.mod-login__posttext,.mod-login__pretext{font-size:.875rem;color:var(--gray-600);line-height:1.6}.mod-login__fields{display:flex;flex-direction:column;gap:1rem}.mod-login__field{display:flex;flex-direction:column;gap:.5rem}.mod-login__label{font-weight:600;font-size:.875rem;color:var(--body-color)}.mod-login__input{padding:.5rem .75rem;font-size:1rem;line-height:1.5;border:1px solid var(--input-border-color,#dee2e6);border-radius:var(--border-radius);background:var(--input-bg,#fff);color:var(--input-color,#212529);min-height:44px}.mod-login__input:focus{border-color:var(--color-primary);outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.mod-login__remember{display:flex;align-items:center;gap:.5rem}.mod-login__checkbox{width:20px;height:20px;cursor:pointer}.mod-login__remember-label{font-size:.875rem;cursor:pointer;margin:0}.mod-login__actions{display:flex;flex-direction:column;gap:.5rem}.mod-login__btn{padding:.625rem 1rem;font-size:1rem;font-weight:600;border-radius:var(--border-radius);min-height:44px;display:inline-flex;align-items:center;justify-content:center;gap:.5rem;transition:.2s;border:none;cursor:pointer}.mod-login__links{display:flex;flex-direction:column;gap:.5rem;margin-top:.5rem}.mod-login__link{color:var(--link-color);text-decoration:none;font-size:.875rem;display:flex;align-items:center;justify-content:space-between;padding:.5rem;border-radius:var(--border-radius);transition:background .2s}.mod-login__link:hover{background:var(--secondary-bg);color:var(--link-hover-color)}.mod-articles-latest-responsive{width:100%}.mod-articles-latest__list{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:1.5rem}.mod-articles-latest__item{padding-bottom:1.5rem;border-bottom:1px solid var(--border-color)}.mod-articles-latest__item:last-child{border-bottom:none;padding-bottom:0}.mod-articles-latest__title{margin:0 0 .75rem;font-weight:600;line-height:1.4}.mod-articles-latest__link{color:var(--body-color);text-decoration:none;transition:color .2s}.mod-articles-latest__link:hover{color:var(--color-primary);text-decoration:underline}.mod-articles-latest__meta{display:flex;flex-wrap:wrap;gap:1rem;font-size:.875rem;color:var(--gray-600);margin-bottom:.75rem}.mod-articles-latest__meta>span{display:flex;align-items:center;gap:.25rem}.mod-articles-latest__intro{color:var(--body-color);line-height:1.6;margin-bottom:1rem}.mod-articles-latest__readmore{margin-top:1rem}.mod-articles-latest__readmore-link{display:inline-flex;align-items:center;gap:.5rem;min-height:44px}.mod-articles-latest__empty{text-align:center;padding:2rem 1rem;background:var(--secondary-bg);border-radius:var(--border-radius);color:var(--gray-600)}.mod-cblogin-responsive{width:100%}.mod-cblogin__form{display:flex;flex-direction:column;gap:1rem}.mod-cblogin__greeting{display:flex;align-items:center;gap:1rem;padding:1rem;background:var(--secondary-bg);border-radius:var(--border-radius);margin-bottom:1rem}.mod-cblogin__avatar{flex-shrink:0;width:60px;height:60px;border-radius:50%;overflow:hidden}.mod-cblogin__avatar img{width:100%;height:100%;object-fit:cover}.mod-cblogin__user-info{flex:1}.mod-cblogin__username{font-weight:600;font-size:1.125rem}.mod-cblogin__posttext,.mod-cblogin__pretext{font-size:.875rem;color:var(--gray-600);line-height:1.6}.mod-cblogin__fields{display:flex;flex-direction:column;gap:1rem}.mod-cblogin__field{display:flex;flex-direction:column;gap:.5rem}.mod-cblogin__label{font-weight:600;font-size:.875rem;color:var(--body-color)}.mod-cblogin__input{padding:.5rem .75rem;font-size:1rem;line-height:1.5;border:1px solid var(--input-border-color,#dee2e6);border-radius:var(--border-radius);background:var(--input-bg,#fff);color:var(--input-color,#212529);min-height:44px}.mod-cblogin__input:focus{border-color:var(--color-primary);outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.mod-cblogin__remember{display:flex;align-items:center;gap:.5rem}.mod-cblogin__checkbox{width:20px;height:20px;cursor:pointer}.mod-cblogin__remember-label{font-size:.875rem;cursor:pointer;margin:0}.mod-cblogin__actions{display:flex;flex-direction:column;gap:.5rem}.mod-cblogin__btn{padding:.625rem 1rem;font-size:1rem;font-weight:600;border-radius:var(--border-radius);min-height:44px;display:inline-flex;align-items:center;justify-content:center;gap:.5rem;transition:.2s;border:none;cursor:pointer;text-decoration:none}.mod-cblogin__links{display:flex;flex-direction:column;gap:.5rem;margin-top:.5rem}.mod-cblogin__link{color:var(--link-color);text-decoration:none;font-size:.875rem;display:flex;align-items:center;justify-content:space-between;padding:.5rem;border-radius:var(--border-radius);transition:background .2s}.mod-cblogin__link:hover{background:var(--secondary-bg);color:var(--link-hover-color)}.mod-cb-online-responsive{width:100%}.mod-cb-online__stats{padding:1rem;background:var(--secondary-bg);border-radius:var(--border-radius);margin-bottom:1.5rem}.mod-cb-online__count{display:flex;flex-direction:column;align-items:center;margin-bottom:1rem}.mod-cb-online__count-number{font-size:2.5rem;font-weight:700;color:var(--color-primary);line-height:1}.mod-cb-online__count-label{font-size:.875rem;color:var(--gray-600);text-transform:uppercase;letter-spacing:.5px}.mod-cb-online__breakdown{display:flex;justify-content:center;gap:1.5rem;flex-wrap:wrap}.mod-cb-online__breakdown-item{display:flex;align-items:center;gap:.5rem;font-size:.875rem;color:var(--body-color)}.mod-cb-online__heading{font-size:1.125rem;font-weight:600;margin:0 0 1rem}.mod-cb-online__list{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.75rem}.mod-cb-online__user{display:flex;align-items:center;gap:.75rem;padding:.75rem;background:var(--body-bg);border:1px solid var(--border-color);border-radius:var(--border-radius);transition:.2s}.mod-cb-online__user:hover{background:var(--secondary-bg);border-color:var(--color-primary)}.mod-cb-online__avatar{flex-shrink:0;width:40px;height:40px;border-radius:50%;overflow:hidden}.mod-cb-online__avatar img{width:100%;height:100%;object-fit:cover}.mod-cb-online__info{flex:1;min-width:0}.mod-cb-online__name{font-weight:600;color:var(--body-color);text-decoration:none;display:block;margin-bottom:.25rem}.mod-cb-online__name:hover{color:var(--color-primary)}.mod-cb-online__status{font-size:.875rem;color:var(--gray-600);display:block}.mod-cb-online__indicator{flex-shrink:0;color:var(--success);font-size:1.25rem}.mod-cb-online__empty{text-align:center;padding:2rem 1rem;background:var(--secondary-bg);border-radius:var(--border-radius);color:var(--gray-600)}@media (max-width:575.98px){.mod-cblogin__input,.mod-login__input{font-size:16px;min-height:48px;padding:.75rem 1rem}.mod-cblogin__btn,.mod-login__btn{min-height:48px;padding:.75rem 1rem}.mod-articles-latest__meta{flex-direction:column;gap:.5rem}.mod-cb-online__breakdown{flex-direction:column;gap:.75rem}}@media (min-width:768px){.mod-cblogin__actions,.mod-login__actions{flex-direction:row}.mod-cb-online__stats{display:flex;align-items:center;justify-content:space-between}.mod-cb-online__count{margin-bottom:0;align-items:flex-start}}.mod-k2-content-responsive{width:100%}.mod-k2-content__list{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:1.5rem}.mod-k2-content__item{display:flex;gap:1rem;padding-bottom:1.5rem;border-bottom:1px solid var(--border-color)}.mod-k2-content__item:last-child{border-bottom:none;padding-bottom:0}.mod-k2-content__image{flex-shrink:0;width:120px;overflow:hidden;border-radius:var(--border-radius)}.mod-k2-content__image img{width:100%;height:auto;display:block;transition:transform .3s}.mod-k2-content__image:hover img{transform:scale(1.05)}.mod-k2-content__content{flex:1;min-width:0}.mod-k2-content__title{margin:0 0 .75rem;font-weight:600;line-height:1.4}.mod-k2-content__title a{color:var(--body-color);text-decoration:none;transition:color .2s}.mod-k2-content__title a:hover{color:var(--color-primary);text-decoration:underline}.mod-k2-content__meta{display:flex;flex-wrap:wrap;gap:1rem;font-size:.875rem;color:var(--gray-600);margin-bottom:.75rem}.mod-k2-content__meta>span{display:flex;align-items:center;gap:.25rem}.mod-k2-content__intro{color:var(--body-color);line-height:1.6;margin-bottom:1rem}.mod-k2-content__readmore{margin-top:1rem}.mod-k2-content__readmore-link{display:inline-flex;align-items:center;gap:.5rem;min-height:44px}.mod-k2-content__custom-link{margin-top:1.5rem;text-align:center}.mod-k2-content__empty{text-align:center;padding:2rem 1rem;background:var(--secondary-bg);border-radius:var(--border-radius);color:var(--gray-600)}.mod-acymailing-responsive{width:100%}.mod-acymailing__form-container{background:var(--body-bg);padding:1.5rem;border-radius:var(--border-radius);border:1px solid var(--border-color)}.mod-acymailing__intro{margin-bottom:1.5rem;line-height:1.6;color:var(--body-color)}.mod-acymailing__outro{margin-top:1.5rem;font-size:.875rem;color:var(--gray-600);line-height:1.6}.mod-acymailing__empty{text-align:center;padding:2rem 1rem;background:var(--secondary-bg);border-radius:var(--border-radius);color:var(--gray-600)}.mod-hikashop-cart-responsive{width:100%}.mod-hikashop-cart__header{display:flex;align-items:center;gap:.75rem;padding:1rem;background:var(--secondary-bg);border:1px solid var(--border-color);border-radius:var(--border-radius);margin-bottom:1rem}.mod-hikashop-cart__icon{font-size:1.5rem;color:var(--color-primary);flex-shrink:0}.mod-hikashop-cart__summary{flex:1;min-width:0}.mod-hikashop-cart__count{font-weight:600;color:var(--body-color);font-size:1rem}.mod-hikashop-cart__total{color:var(--success);font-weight:700;font-size:1.25rem;margin-top:.25rem}.mod-hikashop-cart__products{display:flex;flex-direction:column;gap:1rem;margin-bottom:1rem}.mod-hikashop-cart__product{display:flex;gap:.75rem;padding:.75rem;background:var(--body-bg);border:1px solid var(--border-color);border-radius:var(--border-radius);align-items:flex-start}.mod-hikashop-cart__product-image{flex-shrink:0;width:80px}.mod-hikashop-cart__product-image img{width:100%;height:auto;border-radius:var(--border-radius)}.mod-hikashop-cart__product-details{flex:1;min-width:0}.mod-hikashop-cart__product-name{font-weight:600;margin-bottom:.25rem;line-height:1.4;color:var(--body-color)}.mod-hikashop-cart__product-quantity{font-size:.875rem;color:var(--gray-600);margin-bottom:.25rem}.mod-hikashop-cart__quantity-value{font-weight:600;color:var(--body-color)}.mod-hikashop-cart__product-price{font-weight:700;color:var(--success);margin-top:.25rem}.mod-hikashop-cart__product-remove{flex-shrink:0}.mod-hikashop-cart__remove-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background:var(--body-bg);border:1px solid var(--border-color);color:var(--danger);text-decoration:none;transition:.2s}.mod-hikashop-cart__remove-btn:hover{background:var(--danger);color:#fff;border-color:var(--danger)}.mod-hikashop-cart__actions{display:flex;flex-direction:column;gap:.5rem}.mod-hikashop-cart__btn{padding:.625rem 1rem;border-radius:var(--border-radius);text-align:center;text-decoration:none;font-weight:600;min-height:44px;display:inline-flex;align-items:center;justify-content:center;transition:.2s}.mod-hikashop-cart__empty{text-align:center;padding:2rem 1rem;background:var(--secondary-bg);border:1px solid var(--border-color);border-radius:var(--border-radius)}.mod-hikashop-cart__empty-icon{font-size:3rem;color:var(--gray-600);display:block;margin-bottom:1rem}.mod-hikashop-cart__empty-text{color:var(--gray-600);margin:0}.mod-kunena-latest-responsive{width:100%}.mod-kunena-latest__list{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:1rem}.mod-kunena-latest__item{display:flex;gap:.75rem;padding:1rem;background:var(--body-bg);border:1px solid var(--border-color);border-radius:var(--border-radius);transition:.2s}.mod-kunena-latest__item:hover{background:var(--secondary-bg);border-color:var(--color-primary)}.mod-kunena-latest__avatar{flex-shrink:0;width:40px;height:40px;border-radius:50%;overflow:hidden}.mod-kunena-latest__avatar img{width:100%;height:100%;object-fit:cover}.mod-kunena-latest__content{flex:1;min-width:0}.mod-kunena-latest__title{margin:0 0 .5rem;font-weight:600;font-size:1rem;line-height:1.4}.mod-kunena-latest__title a{color:var(--body-color);text-decoration:none;transition:color .2s}.mod-kunena-latest__title a:hover{color:var(--color-primary);text-decoration:underline}.mod-kunena-latest__meta{display:flex;flex-wrap:wrap;gap:.75rem;font-size:.875rem;color:var(--gray-600);margin-bottom:.5rem}.mod-kunena-latest__meta>span{display:flex;align-items:center;gap:.25rem}.mod-kunena-latest__meta a{color:var(--gray-600);text-decoration:none;transition:color .2s}.mod-kunena-latest__meta a:hover{color:var(--color-primary)}.mod-kunena-latest__excerpt{font-size:.875rem;color:var(--body-color);line-height:1.6;margin-top:.5rem}.mod-kunena-latest__more{margin-top:1.5rem;text-align:center}.mod-kunena-latest__more-link{display:inline-flex;align-items:center;gap:.5rem;min-height:44px}.mod-kunena-latest__empty{text-align:center;padding:2rem 1rem;background:var(--secondary-bg);border-radius:var(--border-radius);color:var(--gray-600)}@media (max-width:575.98px){.mod-k2-content__item{flex-direction:column}.mod-k2-content__image{width:100%;max-width:300px;margin:0 auto}.mod-k2-content__meta{flex-direction:column;gap:.5rem}.mod-hikashop-cart__product{flex-direction:column}.mod-hikashop-cart__product-image{width:100%;max-width:200px;margin:0 auto}.mod-hikashop-cart__actions{gap:.75rem}.mod-hikashop-cart__btn{min-height:48px;padding:.75rem 1rem;font-size:1rem}.mod-kunena-latest__meta{flex-direction:column;gap:.5rem}}@media (min-width:768px){.mod-hikashop-cart__actions{flex-direction:row}.mod-k2-content__custom-link{text-align:left}}.mod-kunena-login-responsive{width:100%}.mod-kunena-login__profile{display:flex;align-items:center;gap:1rem;padding:1rem;background:var(--secondary-bg);border-radius:var(--border-radius);margin-bottom:1rem}.mod-kunena-login__avatar{flex-shrink:0;width:60px;height:60px;border-radius:50%;overflow:hidden}.mod-kunena-login__avatar img{width:100%;height:100%;object-fit:cover}.mod-kunena-login__user-info{flex:1}.mod-kunena-login__username{font-weight:600;font-size:1.125rem;margin-bottom:.25rem}.mod-kunena-login__username a{color:var(--body-color);text-decoration:none}.mod-kunena-login__username a:hover{color:var(--color-primary)}.mod-kunena-login__rank{font-size:.875rem;color:var(--gray-600)}.mod-kunena-login__stats{display:flex;gap:1.5rem;padding:1rem;background:var(--body-bg);border:1px solid var(--border-color);border-radius:var(--border-radius);margin-bottom:1rem}.mod-kunena-login__stat{display:flex;gap:.5rem;align-items:center}.mod-kunena-login__stat-label{color:var(--gray-600);font-size:.875rem}.mod-kunena-login__stat-value{font-weight:600;color:var(--body-color)}.mod-kunena-login__form{display:flex;flex-direction:column;gap:1rem}.mod-kunena-login__posttext,.mod-kunena-login__pretext{font-size:.875rem;color:var(--gray-600);line-height:1.6}.mod-kunena-login__fields{display:flex;flex-direction:column;gap:1rem}.mod-kunena-login__field{display:flex;flex-direction:column;gap:.5rem}.mod-kunena-login__label{font-weight:600;font-size:.875rem;color:var(--body-color)}.mod-kunena-login__input{padding:.5rem .75rem;font-size:1rem;line-height:1.5;border:1px solid var(--input-border-color,#dee2e6);border-radius:var(--border-radius);background:var(--input-bg,#fff);color:var(--input-color,#212529);min-height:44px}.mod-kunena-login__input:focus{border-color:var(--color-primary);outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.mod-kunena-login__remember{display:flex;align-items:center;gap:.5rem}.mod-kunena-login__checkbox{width:20px;height:20px;cursor:pointer}.mod-kunena-login__remember-label{font-size:.875rem;cursor:pointer;margin:0}.mod-kunena-login__actions{display:flex;flex-direction:column;gap:.5rem}.mod-kunena-login__btn{padding:.625rem 1rem;font-size:1rem;font-weight:600;border-radius:var(--border-radius);min-height:44px;display:inline-flex;align-items:center;justify-content:center;gap:.5rem;transition:.2s;border:none;cursor:pointer;text-decoration:none;position:relative}.mod-kunena-login__badge{position:absolute;top:-8px;right:-8px;background:var(--danger);color:#fff;border-radius:50%;width:24px;height:24px;display:flex;align-items:center;justify-content:center;font-size:.75rem;font-weight:700}.mod-kunena-login__logout-form{width:100%}.mod-kunena-login__links{display:flex;flex-direction:column;gap:.5rem;margin-top:.5rem}.mod-kunena-login__link{color:var(--link-color);text-decoration:none;font-size:.875rem;display:flex;align-items:center;justify-content:space-between;padding:.5rem;border-radius:var(--border-radius);transition:background .2s}.mod-kunena-login__link:hover{background:var(--secondary-bg);color:var(--link-hover-color)}.mod-kunena-search-responsive{width:100%}.mod-kunena-search__form{display:flex;gap:.5rem;width:100%}.mod-kunena-search__form--button-bottom,.mod-kunena-search__form--button-top{flex-direction:column}.mod-kunena-search__form--button-left{flex-direction:row-reverse}.mod-kunena-search__form--button-right{flex-direction:row}.mod-kunena-search__input-wrapper{flex:1}.mod-kunena-search__input{width:100%;padding:.5rem .75rem;font-size:1rem;line-height:1.5;border:1px solid var(--input-border-color,#dee2e6);border-radius:var(--border-radius);background:var(--input-bg,#fff);color:var(--input-color,#212529);min-height:44px}.mod-kunena-search__input:focus{border-color:var(--color-primary);outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.mod-kunena-search__button{padding:.5rem 1rem;min-height:44px;display:inline-flex;align-items:center;justify-content:center;gap:.5rem}.mod-kunena-search__form--button-bottom .mod-kunena-search__button,.mod-kunena-search__form--button-top .mod-kunena-search__button,.mod-kunena-stats-responsive{width:100%}.mod-kunena-stats__container{display:grid;gap:1rem;grid-template-columns:1fr}.mod-kunena-stats__stat{display:flex;align-items:center;gap:1rem;padding:1rem;background:var(--body-bg);border:1px solid var(--border-color);border-radius:var(--border-radius);transition:.2s}.mod-kunena-stats__stat:hover{background:var(--secondary-bg);border-color:var(--color-primary)}.mod-kunena-stats__icon{font-size:2rem;color:var(--color-primary);flex-shrink:0;width:48px;height:48px;display:flex;align-items:center;justify-content:center;background:var(--secondary-bg);border-radius:50%}.mod-kunena-stats__content{flex:1}.mod-kunena-stats__value{font-size:1.75rem;font-weight:700;color:var(--body-color);line-height:1;margin-bottom:.25rem}.mod-kunena-stats__value--link a{color:var(--color-primary);text-decoration:none;font-size:1.125rem}.mod-kunena-stats__value--link a:hover{text-decoration:underline}.mod-kunena-stats__label{font-size:.875rem;color:var(--gray-600);text-transform:uppercase;letter-spacing:.5px}.mod-kunena-stats__stat--latest-member .mod-kunena-stats__label{margin-bottom:.25rem}.mod-osmembership-responsive{width:100%}.mod-osmembership__plans{display:grid;gap:2rem;grid-template-columns:1fr}.mod-osmembership__plan{background:var(--body-bg);border:2px solid var(--border-color);border-radius:var(--border-radius);overflow:hidden;transition:.3s;display:flex;flex-direction:column}.mod-osmembership__plan:hover{transform:translateY(-4px);box-shadow:0 8px 24px rgba(0,0,0,.1);border-color:var(--color-primary)}.mod-osmembership__plan-image{width:100%;overflow:hidden}.mod-osmembership__plan-image img{width:100%;height:auto;display:block}.mod-osmembership__plan-content{padding:2rem;flex:1;display:flex;flex-direction:column}.mod-osmembership__plan-title{margin:0 0 1rem;font-weight:700;font-size:1.5rem;line-height:1.3}.mod-osmembership__plan-description{color:var(--gray-600);line-height:1.6;margin-bottom:1.5rem}.mod-osmembership__plan-pricing{margin-bottom:1.5rem}.mod-osmembership__price{display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap}.mod-osmembership__currency{font-size:1.5rem;color:var(--color-primary);font-weight:600}.mod-osmembership__amount{font-size:2.5rem;font-weight:700;color:var(--color-primary);line-height:1}.mod-osmembership__period{color:var(--gray-600);font-size:1rem}.mod-osmembership__price--free{font-size:2rem;font-weight:700;color:var(--success)}.mod-osmembership__features{flex:1;margin-bottom:1.5rem}.mod-osmembership__features-list{list-style:none;padding:0;margin:0}.mod-osmembership__feature{padding:.5rem 0;display:flex;align-items:flex-start;gap:.5rem}.mod-osmembership__feature .icon-check{color:var(--success);flex-shrink:0;margin-top:.25rem}.mod-osmembership__actions{margin-top:auto}.mod-osmembership__btn{width:100%;min-height:48px;display:inline-flex;align-items:center;justify-content:center;gap:.5rem;text-decoration:none}.mod-osmembership__all-plans{margin-top:2rem;text-align:center}.mod-osmembership__all-plans-link{min-height:44px;display:inline-flex;align-items:center;justify-content:center}.mod-osmembership__empty{text-align:center;padding:2rem 1rem;background:var(--secondary-bg);border-radius:var(--border-radius);color:var(--gray-600)}@media (max-width:575.98px){.mod-kunena-login__input{font-size:16px;min-height:48px;padding:.75rem 1rem}.mod-kunena-login__btn{min-height:48px}.mod-kunena-login__stats{flex-direction:column;gap:.75rem}.mod-kunena-search__input{font-size:16px;min-height:48px;padding:.75rem 1rem}.mod-kunena-search__button{min-height:48px}.mod-kunena-stats__container{grid-template-columns:1fr}}@media (min-width:576px){.mod-kunena-stats__container,.mod-osmembership__plans{grid-template-columns:repeat(2,1fr)}}@media (min-width:768px){.mod-kunena-login__actions{flex-direction:row}.mod-kunena-stats__container{grid-template-columns:repeat(3,1fr)}}@media (min-width:992px){.mod-osmembership__plans{grid-template-columns:repeat(3,1fr)}}.cb-component{width:100%;max-width:100%}.cb-profile-responsive{background:var(--body-bg);border-radius:var(--border-radius)}.cb-profile__header{display:flex;flex-direction:column;align-items:center;gap:1.5rem;padding:2rem;background:var(--secondary-bg);border-radius:var(--border-radius);margin-bottom:2rem}.cb-profile__avatar{width:150px;height:150px;border-radius:50%;overflow:hidden;border:4px solid var(--body-bg);box-shadow:0 4px 12px rgba(0,0,0,.1)}.cb-profile__avatar img{width:100%;height:100%;object-fit:cover}.cb-profile__header-info{text-align:center}.cb-profile__name{font-size:1.75rem;font-weight:700;margin:0 0 .5rem;color:var(--heading-color)}.cb-profile__status{display:inline-flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:var(--success-bg);color:var(--success);border-radius:2rem;font-size:.875rem;font-weight:600}.cb-profile__tabs{margin-top:2rem}.cb-profile__tabs-nav{display:flex;flex-wrap:wrap;gap:.5rem;margin:0 0 2rem;padding:0;list-style:none;border-bottom:2px solid var(--border-color)}.cb-profile__tab-item{margin:0}.cb-profile__tab-link{display:block;padding:.75rem 1.5rem;color:var(--body-color);text-decoration:none;border-radius:var(--border-radius) var(--border-radius) 0 0;transition:.2s;min-height:44px;display:flex;align-items:center}.cb-profile__tab-link:hover,.cb-profile__tab-link[aria-selected=true]{background:var(--color-primary);color:#fff}.cb-profile__tab-pane{display:none;padding:1.5rem;background:var(--body-bg);border:1px solid var(--border-color);border-radius:var(--border-radius)}.cb-profile__tab-pane[aria-selected=true]{display:block}.cb-profile__tab-description{margin-bottom:1.5rem;padding:1rem;background:var(--secondary-bg);border-radius:var(--border-radius)}.cb-profile__fields{display:grid;gap:1.5rem}.cb-profile__field{display:grid;grid-template-columns:1fr;gap:.5rem}.cb-profile__field-label{font-weight:600;color:var(--heading-color)}.cb-profile__field-value{color:var(--body-color)}.cb-userslist-responsive{width:100%}.cb-userslist__header{margin-bottom:2rem}.cb-userslist__title{font-size:2rem;font-weight:700;margin:0 0 1.5rem;color:var(--heading-color)}.cb-userslist__search-form{width:100%}.cb-userslist__search-wrapper{display:flex;gap:.5rem;width:100%}.cb-userslist__search-input{flex:1;min-height:48px;padding:.75rem 1rem;border:1px solid var(--border-color);border-radius:var(--border-radius);font-size:16px;transition:.2s}.cb-userslist__search-input:focus{outline:0;border-color:var(--color-primary);box-shadow:0 0 0 3px rgba(var(--color-primary-rgb),.1)}.cb-userslist__search-btn{min-height:48px;min-width:48px;padding:.75rem 1.5rem;display:inline-flex;align-items:center;justify-content:center;gap:.5rem;flex-shrink:0}.cb-userslist__search-text{display:none}.cb-userslist__grid{display:grid;grid-template-columns:1fr;gap:1.5rem}.cb-userslist__user-card{background:var(--body-bg);border:1px solid var(--border-color);border-radius:var(--border-radius);padding:1.5rem;transition:.3s;display:flex;flex-direction:column;gap:1rem}.cb-userslist__user-card:hover{transform:translateY(-2px);box-shadow:0 4px 12px rgba(0,0,0,.1);border-color:var(--color-primary)}.cb-userslist__avatar{width:80px;height:80px;border-radius:50%;overflow:hidden;margin:0 auto}.cb-userslist__avatar img{width:100%;height:100%;object-fit:cover}.cb-userslist__user-info{text-align:center}.cb-userslist__username{font-size:1.25rem;font-weight:600;margin:0 0 .5rem}.cb-userslist__username a{color:var(--heading-color);text-decoration:none}.cb-userslist__username a:hover{color:var(--color-primary)}.cb-userslist__fields{display:grid;gap:.5rem;margin:1rem 0;padding:1rem;background:var(--secondary-bg);border-radius:var(--border-radius)}.cb-userslist__field{font-size:.875rem}.cb-userslist__field-label{font-weight:600;margin-right:.5rem}.cb-userslist__actions{margin-top:1rem}.cb-userslist__btn{min-height:44px;width:100%;display:inline-flex;align-items:center;justify-content:center;gap:.5rem;text-decoration:none}.cb-userslist__pagination{margin-top:2rem;display:flex;justify-content:center}.cb-register-responsive{max-width:800px;margin:0 auto}.cb-register__header{margin-bottom:2rem;text-align:center}.cb-register__title{font-size:2rem;font-weight:700;margin:0 0 1rem;color:var(--heading-color)}.cb-register__intro{padding:1rem;background:var(--secondary-bg);border-radius:var(--border-radius);margin-bottom:1.5rem}.cb-register__form{background:var(--body-bg);border:1px solid var(--border-color);border-radius:var(--border-radius);padding:2rem}.cb-register__fieldset{border:none;margin:0 0 2rem;padding:0}.cb-register__legend{font-size:1.5rem;font-weight:700;color:var(--heading-color);margin:0 0 1.5rem;padding:0 0 .75rem;width:100%;border-bottom:2px solid var(--border-color)}.cb-register__tab-description{margin-bottom:1.5rem;padding:1rem;background:var(--secondary-bg);border-radius:var(--border-radius)}.cb-register__fields{display:grid;gap:1.5rem}.cb-register__field{display:grid;gap:.5rem}.cb-register__label{font-weight:600;color:var(--heading-color);display:flex;align-items:center;gap:.25rem}.cb-register__required{color:var(--danger);font-weight:700}.cb-register__field-description{font-size:.875rem;color:var(--gray-600);margin-top:.25rem}.cb-register__input-wrapper input[type=email],.cb-register__input-wrapper input[type=password],.cb-register__input-wrapper input[type=tel],.cb-register__input-wrapper input[type=text],.cb-register__input-wrapper input[type=url],.cb-register__input-wrapper select,.cb-register__input-wrapper textarea{width:100%;min-height:48px;padding:.75rem 1rem;border:1px solid var(--border-color);border-radius:var(--border-radius);font-size:16px;transition:.2s}.cb-register__input-wrapper input:focus,.cb-register__input-wrapper select:focus,.cb-register__input-wrapper textarea:focus{outline:0;border-color:var(--color-primary);box-shadow:0 0 0 3px rgba(var(--color-primary-rgb),.1)}.cb-register__field--required .cb-register__input-wrapper input,.cb-register__field--required .cb-register__input-wrapper select,.cb-register__field--required .cb-register__input-wrapper textarea{border-left:3px solid var(--danger)}.cb-register__error{color:var(--danger);font-size:.875rem;margin-top:.25rem;padding:.5rem;background:var(--danger-bg);border-radius:var(--border-radius)}.cb-register__captcha{margin:1.5rem 0;padding:1.5rem;background:var(--secondary-bg);border-radius:var(--border-radius)}.cb-register__terms{margin:1.5rem 0;padding:1rem;background:var(--secondary-bg);border-radius:var(--border-radius)}.cb-register__terms-checkbox{min-width:20px;min-height:20px;cursor:pointer}.cb-register__terms-label{cursor:pointer}.cb-register__actions{display:flex;flex-direction:column;gap:1rem;margin-top:2rem}.cb-register__btn{min-height:48px;padding:.75rem 1.5rem;display:inline-flex;align-items:center;justify-content:center;gap:.5rem;text-decoration:none;border:none;cursor:pointer;font-weight:600;transition:.2s}.cb-login-responsive{display:flex;align-items:center;justify-content:center;min-height:60vh;padding:2rem 1rem}.cb-login__container{width:100%;max-width:450px;background:var(--body-bg);border:1px solid var(--border-color);border-radius:var(--border-radius);padding:2rem;box-shadow:0 4px 12px rgba(0,0,0,.1)}.cb-login__header{text-align:center;margin-bottom:2rem}.cb-login__title{font-size:2rem;font-weight:700;margin:0;color:var(--heading-color)}.cb-login__form{display:grid;gap:1.5rem}.cb-login__field{display:grid;gap:.5rem}.cb-login__label{font-weight:600;color:var(--heading-color);display:flex;align-items:center;gap:.25rem}.cb-login__required{color:var(--danger);font-weight:700}.cb-login__input{width:100%;min-height:48px;padding:.75rem 1rem;border:1px solid var(--border-color);border-radius:var(--border-radius);font-size:16px;transition:.2s}.cb-login__input:focus{outline:0;border-color:var(--color-primary);box-shadow:0 0 0 3px rgba(var(--color-primary-rgb),.1)}.cb-login__remember{margin:.5rem 0}.cb-login__remember-checkbox{min-width:20px;min-height:20px;cursor:pointer}.cb-login__remember-label{cursor:pointer}.cb-login__actions{margin-top:1rem}.cb-login__btn{width:100%;min-height:48px;padding:.75rem 1.5rem;display:inline-flex;align-items:center;justify-content:center;gap:.5rem;text-decoration:none;border:none;cursor:pointer;font-weight:600;transition:.2s}.cb-login__links{margin-top:2rem;padding-top:2rem;border-top:1px solid var(--border-color);display:flex;flex-direction:column;gap:1rem}.cb-login__link{text-align:center}.cb-login__link-item{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;color:var(--link-color);text-decoration:none;min-height:44px;padding:.5rem;transition:.2s}.cb-login__link-item:hover{color:var(--color-primary)}@media (min-width:576px){.cb-userslist__search-text{display:inline}.cb-profile__field{grid-template-columns:200px 1fr}.cb-register__actions{flex-direction:row;justify-content:flex-end}.cb-register__btn--cancel{order:-1}}@media (min-width:768px){.cb-profile__header{flex-direction:row;text-align:left}.cb-profile__header-info{text-align:left}.cb-userslist__grid{grid-template-columns:repeat(2,1fr)}.cb-userslist__user-card{flex-direction:row;align-items:center}.cb-userslist__avatar{margin:0}.cb-userslist__user-info{text-align:left;flex:1}.cb-login__container{padding:3rem}}@media (min-width:992px){.cb-userslist__grid{grid-template-columns:repeat(3,1fr)}.cb-userslist__user-card{flex-direction:column;text-align:center}.cb-userslist__avatar{margin:0 auto}.cb-userslist__user-info{text-align:center}.cb-profile__tabs-nav{flex-wrap:nowrap}}@media (max-width:575.98px){.cb-login__input,.cb-register__input-wrapper input[type=email],.cb-register__input-wrapper input[type=password],.cb-register__input-wrapper input[type=tel],.cb-register__input-wrapper input[type=text],.cb-register__input-wrapper input[type=url],.cb-register__input-wrapper select,.cb-userslist__search-input{font-size:16px;min-height:48px}.cb-login__btn,.cb-register__btn,.cb-userslist__btn,.cb-userslist__search-btn{min-height:48px}.cb-profile__avatar{width:120px;height:120px}.cb-login__container,.cb-register__form{padding:1.5rem}}.jem-eventslist-responsive{width:100%;max-width:100%}.jem-eventslist__container{padding:1rem}.jem-eventslist__header{margin-bottom:1.5rem}.jem-eventslist__title{font-size:1.75rem;font-weight:700;margin:0;color:var(--body-color)}.jem-eventslist__list{display:flex;flex-direction:column;gap:1.5rem}.jem-eventslist__item{background:var(--secondary-bg,#f8f9fa);border:1px solid var(--border-color,#dee2e6);border-radius:var(--border-radius,.375rem);overflow:hidden;transition:box-shadow .3s}.jem-eventslist__item:hover{box-shadow:0 4px 8px rgba(0,0,0,.1)}.jem-eventslist__item-inner{padding:1.25rem}.jem-eventslist__date{font-size:.875rem;color:var(--secondary-color,#6c757d);margin-bottom:.5rem;display:flex;align-items:center;flex-wrap:wrap;gap:.25rem}.jem-eventslist__datetime{font-weight:500}.jem-eventslist__date-separator{margin:0 .25rem}.jem-eventslist__event-title{font-size:1.25rem;font-weight:600;margin:.5rem 0}.jem-eventslist__link{color:var(--link-color);text-decoration:none;transition:color .2s}.jem-eventslist__link:hover{color:var(--link-hover-color);text-decoration:underline}.jem-eventslist__venue{display:flex;align-items:center;gap:.5rem;margin:.75rem 0;font-size:.9375rem;color:var(--body-color)}.jem-eventslist__venue-icon{font-size:1rem}.jem-eventslist__venue-link{color:var(--link-color);text-decoration:none}.jem-eventslist__venue-link:hover{text-decoration:underline}.jem-eventslist__description{margin:1rem 0;color:var(--body-color);line-height:1.6}.jem-eventslist__categories{display:flex;flex-wrap:wrap;gap:.5rem;margin:1rem 0}.jem-eventslist__category-badge{display:inline-block;padding:.25rem .75rem;background:var(--primary-color,#007bff);color:var(--white);border-radius:1rem;font-size:.8125rem;font-weight:500}.jem-eventslist__actions{margin-top:1rem}.jem-eventslist__button{display:inline-block;padding:.625rem 1.25rem;min-height:44px;background:var(--btn-primary-bg,#007bff);color:var(--white);border:none;border-radius:var(--border-radius,.375rem);text-decoration:none;font-weight:500;text-align:center;transition:background-color .2s;cursor:pointer}.jem-eventslist__button:hover{background:var(--btn-primary-hover-bg,#0056b3);color:var(--white);text-decoration:none}.jem-eventslist__pagination{margin-top:2rem;text-align:center}.jem-eventslist__empty{padding:3rem 1rem;text-align:center}.jem-eventslist__empty-message{font-size:1.125rem;color:var(--secondary-color,#6c757d)}.jem-event-responsive{width:100%;max-width:100%}.jem-event__container{padding:1rem}.jem-event__header{margin-bottom:1.5rem}.jem-event__title{font-size:2rem;font-weight:700;margin:0;color:var(--body-color)}.jem-event__image-wrapper{margin:1.5rem 0;border-radius:var(--border-radius,.375rem);overflow:hidden}.jem-event__image{width:100%;height:auto;display:block}.jem-event__meta{background:var(--secondary-bg,#f8f9fa);border:1px solid var(--border-color,#dee2e6);border-radius:var(--border-radius,.375rem);padding:1.5rem;margin:1.5rem 0}.jem-event__meta-item{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:1rem}.jem-event__meta-item:last-child{margin-bottom:0}.jem-event__meta-icon{font-size:1.25rem;flex-shrink:0;margin-top:.125rem}.jem-event__meta-content{flex:1}.jem-event__meta-label{display:block;margin-bottom:.25rem;color:var(--body-color)}.jem-event__datetime,.jem-event__time-value,.jem-event__venue-name{color:var(--body-color)}.jem-event__venue-link{color:var(--link-color);text-decoration:none;font-weight:500}.jem-event__venue-link:hover{color:var(--link-hover-color);text-decoration:underline}.jem-event__address{margin-top:.5rem;font-size:.9375rem;color:var(--secondary-color,#6c757d)}.jem-event__city,.jem-event__street{display:block}.jem-event__category-list{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:.5rem}.jem-event__category-badge{display:inline-block;padding:.25rem .75rem;background:var(--primary-color,#007bff);color:var(--white);border-radius:1rem;font-size:.8125rem;font-weight:500}.jem-event__description{margin:2rem 0}.jem-event__description-title{font-size:1.5rem;font-weight:600;margin-bottom:1rem;color:var(--body-color)}.jem-event__description-content{line-height:1.8;color:var(--body-color)}.jem-event__contact,.jem-event__registration{background:var(--secondary-bg,#f8f9fa);border:1px solid var(--border-color,#dee2e6);border-radius:var(--border-radius,.375rem);padding:1.5rem;margin:1.5rem 0}.jem-event__contact-title,.jem-event__registration-title{font-size:1.25rem;font-weight:600;margin-bottom:1rem;color:var(--body-color)}.jem-event__contact-link{color:var(--link-color);text-decoration:none}.jem-event__contact-link:hover{text-decoration:underline}.jem-event__actions{margin-top:2rem}.jem-event__button{display:inline-block;padding:.625rem 1.25rem;min-height:44px;background:var(--btn-secondary-bg,#6c757d);color:var(--white);border:none;border-radius:var(--border-radius,.375rem);text-decoration:none;font-weight:500;text-align:center;transition:background-color .2s;cursor:pointer}.jem-event__button:hover{background:var(--btn-secondary-hover-bg,#5a6268);color:var(--white);text-decoration:none}.jem-calendar-responsive{width:100%;max-width:100%}.jem-calendar__container{padding:1rem}.jem-calendar__header{margin-bottom:1.5rem}.jem-calendar__title{font-size:1.75rem;font-weight:700;margin:0;color:var(--body-color)}.jem-calendar__navigation{display:flex;justify-content:space-between;align-items:center;margin-bottom:1.5rem;padding:1rem;background:var(--secondary-bg,#f8f9fa);border-radius:var(--border-radius,.375rem)}.jem-calendar__nav-button{display:flex;align-items:center;justify-content:center;width:44px;height:44px;background:var(--btn-primary-bg,#007bff);color:var(--white);border:none;border-radius:50%;text-decoration:none;font-size:1.5rem;transition:background-color .2s}.jem-calendar__nav-button:hover{background:var(--btn-primary-hover-bg,#0056b3);color:var(--white)}.jem-calendar__current-month{font-size:1.25rem;font-weight:600;margin:0;color:var(--body-color)}.jem-calendar__grid{background:var(--secondary-bg,#f8f9fa);border:1px solid var(--border-color,#dee2e6);border-radius:var(--border-radius,.375rem);padding:1rem;margin-bottom:2rem}.jem-calendar__weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:.5rem;margin-bottom:.5rem}.jem-calendar__weekday{text-align:center;font-weight:600;font-size:.875rem;color:var(--body-color);padding:.5rem 0}.jem-calendar__days{display:grid;grid-template-columns:repeat(7,1fr);gap:.5rem}.jem-calendar__day{aspect-ratio:1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:.5rem;background:var(--white);border:1px solid var(--border-color,#dee2e6);border-radius:var(--border-radius,.375rem);cursor:pointer;transition:background-color .2s}.jem-calendar__day:hover{background:var(--hover-bg,#e9ecef)}.jem-calendar__day--empty{background:0 0;border:none;cursor:default}.jem-calendar__day--has-events{background:var(--primary-light,#cfe2ff);border-color:var(--primary-color,#007bff)}.jem-calendar__day--today{border:2px solid var(--primary-color,#007bff);font-weight:700}.jem-calendar__day-number{font-size:.9375rem;color:var(--body-color)}.jem-calendar__event-indicator{display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;background:var(--primary-color,#007bff);color:var(--white);border-radius:50%;font-size:.6875rem;font-weight:600;margin-top:.25rem}.jem-calendar__events-list{margin-top:2rem}.jem-calendar__events-title{font-size:1.5rem;font-weight:600;margin-bottom:1rem;color:var(--body-color)}.jem-calendar__events{display:flex;flex-direction:column;gap:1rem}.jem-calendar__event-item{padding:1rem;background:var(--secondary-bg,#f8f9fa);border:1px solid var(--border-color,#dee2e6);border-radius:var(--border-radius,.375rem)}.jem-calendar__event-date{font-size:.875rem;color:var(--secondary-color,#6c757d);margin-bottom:.5rem}.jem-calendar__event-title{font-size:1.125rem;font-weight:600;margin:.5rem 0}.jem-calendar__event-link{color:var(--link-color);text-decoration:none}.jem-calendar__event-link:hover{color:var(--link-hover-color);text-decoration:underline}.jem-calendar__event-venue{font-size:.9375rem;color:var(--body-color);margin-top:.5rem}.jem-venue-responsive{width:100%;max-width:100%}.jem-venue__container{padding:1rem}.jem-venue__header{margin-bottom:1.5rem}.jem-venue__title{font-size:2rem;font-weight:700;margin:0;color:var(--body-color)}.jem-venue__image-wrapper{margin:1.5rem 0;border-radius:var(--border-radius,.375rem);overflow:hidden}.jem-venue__image{width:100%;height:auto;display:block}.jem-venue__info{margin:2rem 0}.jem-venue__info-item{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:1.5rem;padding:1.25rem;background:var(--secondary-bg,#f8f9fa);border:1px solid var(--border-color,#dee2e6);border-radius:var(--border-radius,.375rem)}.jem-venue__info-item:last-child{margin-bottom:0}.jem-venue__info-icon{font-size:1.25rem;flex-shrink:0;margin-top:.125rem}.jem-venue__info-content{flex:1}.jem-venue__info-label{display:block;margin-bottom:.5rem;color:var(--body-color)}.jem-venue__address-content{font-style:normal;color:var(--body-color)}.jem-venue__city-line,.jem-venue__country,.jem-venue__state,.jem-venue__street{display:block;margin-bottom:.25rem}.jem-venue__link{color:var(--link-color);text-decoration:none;word-break:break-all}.jem-venue__link:hover{text-decoration:underline}.jem-venue__description{margin:2rem 0}.jem-venue__description-title{font-size:1.5rem;font-weight:600;margin-bottom:1rem;color:var(--body-color)}.jem-venue__description-content{line-height:1.8;color:var(--body-color)}.jem-venue__map{margin:2rem 0}.jem-venue__map-title{font-size:1.5rem;font-weight:600;margin-bottom:1rem;color:var(--body-color)}.jem-venue__map-container{border-radius:var(--border-radius,.375rem);overflow:hidden}.jem-venue__map-placeholder{padding:3rem 1rem;background:var(--secondary-bg,#f8f9fa);border:1px solid var(--border-color,#dee2e6);text-align:center}.jem-venue__map-link{display:inline-block;padding:.625rem 1.25rem;min-height:44px;background:var(--btn-primary-bg,#007bff);color:var(--white);border:none;border-radius:var(--border-radius,.375rem);text-decoration:none;font-weight:500;margin-top:1rem;transition:background-color .2s}.jem-venue__map-link:hover{background:var(--btn-primary-hover-bg,#0056b3);color:var(--white);text-decoration:none}.jem-venue__events{margin:2rem 0}.jem-venue__events-title{font-size:1.5rem;font-weight:600;margin-bottom:1rem;color:var(--body-color)}.jem-venue__events-list{display:flex;flex-direction:column;gap:1rem}.jem-venue__event-item{padding:1rem;background:var(--secondary-bg,#f8f9fa);border:1px solid var(--border-color,#dee2e6);border-radius:var(--border-radius,.375rem)}.jem-venue__event-date{font-size:.875rem;color:var(--secondary-color,#6c757d);margin-bottom:.5rem}.jem-venue__event-title{font-size:1.125rem;font-weight:600;margin:.5rem 0}.jem-venue__event-link{color:var(--link-color);text-decoration:none}.jem-venue__event-link:hover{color:var(--link-hover-color);text-decoration:underline}.jem-venue__actions{margin-top:2rem}.jem-venue__button{display:inline-block;padding:.625rem 1.25rem;min-height:44px;background:var(--btn-secondary-bg,#6c757d);color:var(--white);border:none;border-radius:var(--border-radius,.375rem);text-decoration:none;font-weight:500;text-align:center;transition:background-color .2s;cursor:pointer}.jem-venue__button:hover{background:var(--btn-secondary-hover-bg,#5a6268);color:var(--white);text-decoration:none}.jem-categories-responsive{width:100%;max-width:100%}.jem-categories__container{padding:1rem}.jem-categories__header{margin-bottom:1.5rem}.jem-categories__title{font-size:1.75rem;font-weight:700;margin:0;color:var(--body-color)}.jem-categories__list{display:flex;flex-direction:column;gap:1.5rem}.jem-categories__item{background:var(--secondary-bg,#f8f9fa);border:1px solid var(--border-color,#dee2e6);border-radius:var(--border-radius,.375rem);overflow:hidden;transition:box-shadow .3s}.jem-categories__item:hover{box-shadow:0 4px 8px rgba(0,0,0,.1)}.jem-categories__item-inner{padding:1.25rem}.jem-categories__image-wrapper{margin-bottom:1rem;border-radius:var(--border-radius,.375rem);overflow:hidden}.jem-categories__image{width:100%;height:auto;display:block}.jem-categories__category-title{font-size:1.25rem;font-weight:600;margin:.5rem 0}.jem-categories__link{color:var(--link-color);text-decoration:none;transition:color .2s}.jem-categories__link:hover{color:var(--link-hover-color);text-decoration:underline}.jem-categories__description{margin:1rem 0;color:var(--body-color);line-height:1.6}.jem-categories__meta{margin:.75rem 0;font-size:.875rem;color:var(--secondary-color,#6c757d)}.jem-categories__event-count{font-weight:500}.jem-categories__actions{margin-top:1rem}.jem-categories__button{display:inline-block;padding:.625rem 1.25rem;min-height:44px;background:var(--btn-primary-bg,#007bff);color:var(--white);border:none;border-radius:var(--border-radius,.375rem);text-decoration:none;font-weight:500;text-align:center;transition:background-color .2s;cursor:pointer}.jem-categories__button:hover{background:var(--btn-primary-hover-bg,#0056b3);color:var(--white);text-decoration:none}.jem-categories__pagination{margin-top:2rem;text-align:center}.jem-categories__empty{padding:3rem 1rem;text-align:center}.jem-categories__empty-message{font-size:1.125rem;color:var(--secondary-color,#6c757d)}@media (min-width:768px){.jem-categories__list,.jem-eventslist__list{display:grid;grid-template-columns:repeat(2,1fr);gap:1.5rem}.jem-calendar__day-number{font-size:1rem}.jem-event__meta{padding:2rem}.jem-venue__info-item{padding:1.5rem}}@media (min-width:992px){.jem-calendar__container,.jem-categories__container,.jem-event__container,.jem-eventslist__container,.jem-venue__container{padding:2rem}.jem-calendar__title,.jem-categories__title,.jem-eventslist__title{font-size:2rem}.jem-event__title,.jem-venue__title{font-size:2.5rem}.jem-calendar__grid{padding:1.5rem}}@media (max-width:575.98px){.jem-calendar__nav-button,.jem-categories__button,.jem-event__button,.jem-eventslist__button,.jem-venue__button,.jem-venue__map-link{min-height:48px}.jem-categories__item-inner,.jem-event__meta,.jem-eventslist__item-inner,.jem-venue__info-item{padding:1rem}.jem-calendar__navigation{padding:.75rem}.jem-calendar__current-month{font-size:1rem}.jem-calendar__weekday{font-size:.75rem;padding:.25rem 0}.jem-calendar__day{padding:.25rem}.jem-calendar__day-number{font-size:.8125rem}}
\ No newline at end of file
diff --git a/src/media/css/theme/dark.standard.css b/src/media/css/theme/dark.standard.css
new file mode 100644
index 0000000..7a255e3
--- /dev/null
+++ b/src/media/css/theme/dark.standard.css
@@ -0,0 +1,1210 @@
+@charset "UTF-8";
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+
+/* -----------------------------------------------
+ * DARK THEME
+ * --------------------------------------------- */
+
+:root[data-bs-theme='dark']{
+color-scheme: dark;
+
+
+/* ===== BRAND & THEME COLORS ===== */
+--color-primary: #112855;
+--accent-color-primary: #3f8ff0;
+--accent-color-secondary: #6fb3ff;
+
+
+/* ===== TYPOGRAPHY & BODY ===== */
+--font-sans-serif: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+--font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+--body-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+--body-font-size: 1rem;
+--body-font-weight: 400;
+--body-line-height: 1.5;
+--body-color: #e6ebf1;
+--body-color-rgb: 230, 235, 241;
+--body-bg: #0e1318;
+--body-bg-rgb: 14, 19, 24;
+--heading-color: #f1f5f9;
+--emphasis-color: #fff;
+--emphasis-color-rgb: 255, 255, 255;
+--secondary-color: #e6ebf1bf;
+--secondary-color-rgb: 230, 235, 241;
+--tertiary-color: #e6ebf180;
+--tertiary-color-rgb: 230, 235, 241;
+--muted-color: #6d757e;
+--code-color: black;
+--code-color-ink: var(--code-color, #e93f8e);
+--code-bg-color: lightgreen;
+--highlight-color: #111;
+--highlight-bg: #ffe28a1a;
+
+
+/* ===== STANDARD COLORS ===== */
+--blue: #91a4ff;
+--indigo: #b19cff;
+--purple: #c0a5ff;
+--pink: #ff8fc0;
+--red: #ff7a73;
+--orange: #ff9c4d;
+--yellow: #ffd166;
+--green: #78d694;
+--teal: #76e3ff;
+--cyan: #6fb7ff;
+--black: #000;
+--white: #fff;
+
+
+/* ===== GRAY SCALE ===== */
+--gray-100: #161a20;
+--gray-200: #1b2027;
+--gray-300: #222831;
+--gray-400: #2b323b;
+--gray-500: #36404a;
+--gray-600: #48525d;
+--gray-700: #5b6672;
+--gray-800: #cfd6de;
+--gray-900: #e6ebf1;
+--white-rgb: 255, 255, 255;
+--black-rgb: 0, 0, 0;
+
+
+/* ===== OPACITY UTILITIES ===== */
+--opacity-0: 0;
+--opacity-5: 0.05;
+--opacity-10: 0.1;
+--opacity-15: 0.15;
+--opacity-20: 0.2;
+--opacity-25: 0.25;
+--opacity-30: 0.3;
+--opacity-50: 0.5;
+--opacity-75: 0.75;
+--opacity-100: 1;
+
+
+/* ===== LAYOUT & SPACING ===== */
+--padding-x: 0.15rem;
+--padding-y: 0.15rem;
+--bg-opacity: 1;
+--nav-toggle-size: 3rem;
+--gradient: linear-gradient(180deg, #ffffff26, #fff0);
+--secondary-bg: #151b22;
+--secondary-bg-rgb: 21, 27, 34;
+--tertiary-bg: #10151b;
+--tertiary-bg-rgb: 16, 21, 27;
+--hr-color: var(--border-color, #dfe3e7);
+--border-color-soft: var(--border-color, #dfe3e7);
+--kbd-bg: var(--secondary-bg, #eaedf0);
+--kbd-ink: var(--body-bg, #fff);
+--toc-bg: var(--secondary-bg, #eaedf0);
+--toc-ink: var(--color-primary, #112855);
+--selection-bg: var(--highlight-bg, #fbeea8);
+--selection-ink: var(--body-color, #22262a);
+--border: 5px;
+
+
+/* ===== BREAKPOINTS ===== */
+--bp-xs: 0;
+--bp-sm: 576px;
+--bp-md: 768px;
+--bp-lg: 992px;
+--bp-xl: 1200px;
+
+
+/* ===== BORDERS ===== */
+--border-width: 1px;
+--border-style: solid;
+--border-color: #2b323b;
+--border-color-translucent: #ffffff26;
+--border-radius: .25rem;
+--border-radius-sm: .2rem;
+--border-radius-lg: .3rem;
+--border-radius-xl: .3rem;
+--border-radius-xxl: 2rem;
+--border-radius-2xl: var(--border-radius-xxl);
+--border-radius-pill: 50rem;
+
+
+/* ===== SHADOWS ===== */
+--box-shadow: 0 .5rem 1rem #00000066;
+--box-shadow-sm: 0 .125rem .25rem #00000040;
+--box-shadow-lg: 0 1rem 3rem #00000080;
+--box-shadow-inset: inset 0 1px 2px #00000040;
+
+
+/* ===== COMMON SHADOW COLORS ===== */
+--shadow-color-light: rgba(var(--black-rgb), var(--opacity-30));
+--shadow-color-medium: rgba(var(--black-rgb), var(--opacity-50));
+--shadow-color-dark: rgba(var(--black-rgb), var(--opacity-75));
+--border-color-translucent: rgba(var(--white-rgb), var(--opacity-10));
+--highlight-translucent: rgba(var(--white-rgb), var(--opacity-5));
+
+
+/* ===== NAVIGATION ===== */
+--mainmenu-nav-link-color: #fff;
+--nav-text-color: gray;
+--nav-bg-color: var(--color-primary);
+
+
+/* ===== NAVBAR ===== */
+--navbar-padding-x: 1rem;
+--navbar-padding-y: 0.5rem;
+--navbar-color: var(--nav-text-color);
+--navbar-active-color: var(--mainmenu-nav-link-color);
+--navbar-disabled-color: #6c757d;
+--navbar-brand-padding-y: 0.3125rem;
+--navbar-brand-margin-end: 1rem;
+--navbar-brand-font-size: 1.25rem;
+--navbar-brand-color: var(--nav-text-color);
+--navbar-brand-active-color: var(--mainmenu-nav-link-color);
+--navbar-nav-link-padding-x: 0.5rem;
+--navbar-toggler-padding-y: 0.25rem;
+--navbar-toggler-padding-x: 0.75rem;
+--navbar-toggler-font-size: 1.25rem;
+--navbar-toggler-border-color: rgba(255, 255, 255, 0.1);
+--navbar-toggler-border-radius: 0.25rem;
+--navbar-toggler-focus-width: 0.25rem;
+--navbar-toggler-transition: box-shadow 0.15s ease-in-out;
+--nav-link-padding-x: 1rem;
+--nav-link-padding-y: 0.5rem;
+--nav-link-font-weight: 400;
+--nav-link-color: var(--nav-text-color);
+--nav-link-active-color: var(--mainmenu-nav-link-color);
+--nav-link-disabled-color: #6c757d;
+
+
+/* ===== LINKS ===== */
+--color-link: white;
+--color-hover: gray;
+--color-active: var(--mainmenu-nav-link-color);
+--link-color: #8ab4f8;
+--link-color-rgb: 138, 180, 248;
+--link-decoration: underline;
+--link-hover-color: #c3d6ff;
+--link-hover-color-rgb: 195, 214, 255;
+--link-active-color: var(--link-color);
+
+
+/* ===== LINK UTILITY COLORS ===== */
+--link-primary-color: hsl(240, 98%, 50%);
+--link-primary-hover-color: hsl(240, 98%, 45%);
+--link-secondary-color: hsl(210, 15%, 70%);
+--link-secondary-hover-color: hsl(210, 15%, 65%);
+--link-success-color: hsl(120, 40%, 60%);
+--link-success-hover-color: hsl(120, 40%, 55%);
+--link-info-color: hsl(207, 60%, 65%);
+--link-info-hover-color: hsl(207, 60%, 60%);
+--link-warning-color: hsl(38, 100%, 65%);
+--link-warning-hover-color: hsl(38, 100%, 60%);
+--link-danger-color: hsl(3, 85%, 65%);
+--link-danger-hover-color: hsl(3, 85%, 60%);
+--link-light-color: hsl(210, 20%, 90%);
+--link-light-hover-color: hsl(210, 20%, 85%);
+--link-dark-color: hsl(210, 10%, 35%);
+--link-dark-hover-color: hsl(210, 10%, 30%);
+
+
+/* ===== HEADER BACKGROUND ===== */
+--header-background-image: url('../../../../../../media/templates/site/mokoonyx/images/bg.svg');
+--header-background-attachment: fixed;
+--header-background-repeat: repeat;
+--header-background-size: auto;
+
+
+/* ===== CONTAINER BACKGROUNDS ===== */
+/* Below Topbar Container */
+--container-below-topbar-bg-image: none;
+--container-below-topbar-bg-color: transparent;
+--container-below-topbar-bg-position: center;
+--container-below-topbar-bg-attachment: fixed;
+--container-below-topbar-bg-repeat: no-repeat;
+--container-below-topbar-bg-size: cover;
+--container-below-topbar-border: none;
+--container-below-topbar-border-radius: 0;
+
+/* Top A Container */
+--container-top-a-bg-image: none;
+--container-top-a-bg-color: transparent;
+--container-top-a-bg-position: center;
+--container-top-a-bg-attachment: fixed;
+--container-top-a-bg-repeat: no-repeat;
+--container-top-a-bg-size: cover;
+--container-top-a-border: none;
+--container-top-a-border-radius: 0;
+
+/* Top B Container */
+--container-top-b-bg-image: none;
+--container-top-b-bg-color: transparent;
+--container-top-b-bg-position: center;
+--container-top-b-bg-attachment: fixed;
+--container-top-b-bg-repeat: no-repeat;
+--container-top-b-bg-size: cover;
+--container-top-b-border: none;
+--container-top-b-border-radius: 0;
+
+/* TOC Container */
+--container-toc-bg: var(--secondary-bg);
+--container-toc-color: #dbe3ff;
+
+/* Sidebar Container */
+--container-sidebar-bg-image: none;
+--container-sidebar-bg-color: transparent;
+--container-sidebar-bg-position: center;
+--container-sidebar-bg-attachment: scroll;
+--container-sidebar-bg-repeat: repeat;
+--container-sidebar-bg-size: auto;
+--container-sidebar-border: none;
+--container-sidebar-border-radius: 0;
+
+/* Bottom A Container */
+--container-bottom-a-bg-image: none;
+--container-bottom-a-bg-color: transparent;
+--container-bottom-a-bg-position: center;
+--container-bottom-a-bg-attachment: fixed;
+--container-bottom-a-bg-repeat: no-repeat;
+--container-bottom-a-bg-size: cover;
+--container-bottom-a-border: none;
+--container-bottom-a-border-radius: 5px;
+
+/* Bottom B Container */
+--container-bottom-b-bg-image: none;
+--container-bottom-b-bg-color: transparent;
+--container-bottom-b-bg-position: center;
+--container-bottom-b-bg-attachment: fixed;
+--container-bottom-b-bg-repeat: no-repeat;
+--container-bottom-b-bg-size: cover;
+--container-bottom-b-border: none;
+--container-bottom-b-border-radius: 0;
+
+
+/* ===== FOCUS & FORMS ===== */
+--focus-ring-width: .25rem;
+--focus-ring-opacity: .6;
+--focus-ring-color: #5472ff66;
+--input-color: #e6ebf1;
+--input-bg: #1a2332;
+--input-border-color: #3a4250;
+--input-focus-border-color: #5472ff;
+--input-focus-box-shadow: 0 0 0 0.25rem rgba(84, 114, 255, 0.25);
+--input-placeholder-color: #8894aa;
+--input-disabled-bg: #0f1318;
+--input-disabled-border-color: #2b323b;
+--input-file-button-active-bg: #2b3441;
+--form-range-thumb-active-bg: #4a5766;
+--form-valid-color: #78d694;
+--form-valid-border-color: #78d694;
+--form-invalid-color: #ff8e86;
+--form-invalid-border-color: #ff8e86;
+
+
+/* ===== BUTTONS ===== */
+--btn-border-radius: var(--border-radius);
+--btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 1px 1px rgba(0, 0, 0, 0.3);
+
+
+/* ===== ACCORDION ===== */
+--accordion-color: var(--body-color);
+--accordion-bg: var(--body-bg);
+--accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;
+--accordion-border-color: var(--border-color);
+--accordion-border-width: 1px;
+--accordion-border-radius: 0.25rem;
+--accordion-inner-border-radius: calc(0.25rem - 1px);
+--accordion-btn-padding-x: 1.25rem;
+--accordion-btn-padding-y: 1rem;
+--accordion-btn-color: var(--body-color);
+--accordion-btn-bg: var(--accordion-bg);
+--accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23e6ebf1'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+--accordion-btn-icon-width: 1.25rem;
+--accordion-btn-icon-transform: rotate(-180deg);
+--accordion-btn-icon-transition: transform 0.2s ease-in-out;
+--accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%238ab4f8'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+--accordion-btn-focus-border-color: var(--input-focus-border-color);
+--accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(84, 114, 255, 0.25);
+--accordion-body-padding-x: 1.25rem;
+--accordion-body-padding-y: 1rem;
+--accordion-active-color: var(--link-color);
+--accordion-active-bg: var(--secondary-bg);
+
+
+/* ===== ALERT ===== */
+--alert-bg: transparent;
+--alert-padding-x: 1rem;
+--alert-padding-y: 1rem;
+--alert-margin-bottom: 1rem;
+--alert-color: #000;
+--alert-border-color: transparent;
+--alert-border: 1px solid var(--alert-border-color);
+--alert-border-radius: 0.25rem;
+
+
+/* ===== ALERT LINK COLORS ===== */
+--alert-primary-link-color: #b3c1ff;
+--alert-secondary-link-color: #9fa6ad;
+--alert-success-link-color: #a0e5b3;
+--alert-info-link-color: #8eccf2;
+--alert-warning-link-color: #ffe4a0;
+--alert-danger-link-color: #ffa8a3;
+--alert-light-link-color: #f0f4f8;
+--alert-dark-link-color: #9fa6ad;
+
+
+/* ===== BACKDROP ===== */
+--backdrop-zindex: 1040;
+--backdrop-bg: hsl(0, 0%, 0%);
+--backdrop-opacity: 0.5;
+
+
+/* ===== BADGE ===== */
+--badge-padding-x: 0.65em;
+--badge-padding-y: 0.35em;
+--badge-font-size: 0.75em;
+--badge-font-weight: 700;
+--badge-color: var(--body-color);
+--badge-border-radius: 0.25rem;
+
+
+/* ===== BREADCRUMB ===== */
+--breadcrumb-padding-x: 0;
+--breadcrumb-padding-y: 0;
+--breadcrumb-margin-bottom: 1rem;
+--breadcrumb-bg: ;
+--breadcrumb-border-radius: ;
+--breadcrumb-divider-color: var(--gray-600);
+--breadcrumb-item-padding-x: 0.5rem;
+--breadcrumb-item-active-color: var(--link-color);
+
+
+/* ===== CARDS ===== */
+--card-spacer-y: 1rem;
+--card-spacer-x: 1rem;
+--card-title-spacer-y: 0.5rem;
+--card-border-width: 1px;
+--card-border-color: var(--border-color);
+--card-border-radius: var(--border-radius);
+--card-box-shadow: none;
+--card-inner-border-radius: calc(var(--border-radius) - 1px);
+--card-cap-padding-y: 0.5rem;
+--card-cap-padding-x: 1rem;
+--card-cap-bg: rgba(255, 255, 255, 0.03);
+--card-cap-color: var(--body-color);
+--card-height: auto;
+--card-color: var(--body-color);
+--card-bg: var(--secondary-bg);
+--card-img-overlay-padding: 1rem;
+--card-group-margin: 0.75rem;
+
+
+/* ===== DROPDOWN ===== */
+--dropdown-zindex: 1000;
+--dropdown-min-width: 10rem;
+--dropdown-padding-x: 0;
+--dropdown-padding-y: 0.5rem;
+--dropdown-spacer: 0.125rem;
+--dropdown-font-size: 1rem;
+--dropdown-color: var(--body-color);
+--dropdown-bg: var(--secondary-bg);
+--dropdown-border-color: var(--border-color-translucent);
+--dropdown-border-radius: 0.25rem;
+--dropdown-border-width: 1px;
+--dropdown-inner-border-radius: calc(0.25rem - 1px);
+--dropdown-divider-bg: var(--border-color-translucent);
+--dropdown-divider-margin-y: 0.5rem;
+--dropdown-box-shadow: 0 0.5rem 1rem var(--shadow-color-medium);
+--dropdown-link-color: var(--body-color);
+--dropdown-link-active-color: var(--body-color);
+--dropdown-link-active-bg: hsl(240, 98%, 17%);
+--dropdown-link-disabled-color: var(--gray-600);
+--dropdown-item-padding-x: 1rem;
+--dropdown-item-padding-y: 0.25rem;
+--dropdown-header-color: var(--gray-600);
+--dropdown-header-padding-x: 1rem;
+--dropdown-header-padding-y: 0.5rem;
+
+
+/* ===== LIST GROUP ===== */
+--list-group-color: var(--body-color);
+--list-group-bg: var(--secondary-bg);
+--list-group-border-color: rgba(var(--white-rgb), 0.125);
+--list-group-border-width: 1px;
+--list-group-border-radius: 0.25rem;
+--list-group-item-padding-x: 1rem;
+--list-group-item-padding-y: 0.5rem;
+--list-group-action-color: var(--gray-800);
+--list-group-action-active-color: var(--body-color);
+--list-group-action-active-bg: var(--tertiary-bg);
+--list-group-disabled-color: var(--gray-600);
+--list-group-disabled-bg: var(--secondary-bg);
+--list-group-active-color: var(--body-color);
+--list-group-active-bg: hsl(240, 98%, 17%);
+--list-group-active-border-color: hsl(240, 98%, 17%);
+
+
+/* ===== LIST GROUP ITEM COLORS ===== */
+--list-group-item-primary-color: #8ca3ff;
+--list-group-item-primary-bg: #1a2550;
+--list-group-item-primary-active-bg: #223066;
+--list-group-item-secondary-color: #9fa6ad;
+--list-group-item-secondary-bg: #2b323b;
+--list-group-item-secondary-active-bg: #363d47;
+--list-group-item-success-color: #a0e5b3;
+--list-group-item-success-bg: #1e3d2d;
+--list-group-item-success-active-bg: #275538;
+--list-group-item-info-color: #8eccf2;
+--list-group-item-info-bg: #1a3448;
+--list-group-item-info-active-bg: #234459;
+--list-group-item-warning-color: #ffe4a0;
+--list-group-item-warning-bg: #4a3410;
+--list-group-item-warning-active-bg: #5c4216;
+--list-group-item-danger-color: #ffa8a3;
+--list-group-item-danger-bg: #4a1e1c;
+--list-group-item-danger-active-bg: #5c2823;
+--list-group-item-light-color: #e9ecef;
+--list-group-item-light-bg: #1e2430;
+--list-group-item-light-active-bg: #282f3d;
+--list-group-item-dark-color: #48525d;
+--list-group-item-dark-bg: #0e1318;
+--list-group-item-dark-active-bg: #161b22;
+
+
+/* ===== MODAL ===== */
+--modal-zindex: 1050;
+--modal-width: 500px;
+--modal-padding: 1rem;
+--modal-margin: 0.5rem;
+--modal-color: ;
+--modal-bg: var(--secondary-bg);
+--modal-border-color: var(--border-color-translucent);
+--modal-border-width: 1px;
+--modal-border-radius: 0.3rem;
+--modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.3);
+--modal-inner-border-radius: calc(0.3rem - 1px);
+--modal-header-padding-x: 1rem;
+--modal-header-padding-y: 1rem;
+--modal-header-padding: 1rem 1rem;
+--modal-header-border-color: var(--border-color);
+--modal-header-border-width: 1px;
+--modal-title-line-height: 1.5;
+--modal-footer-gap: 0.5rem;
+--modal-footer-bg: ;
+--modal-footer-border-color: var(--border-color);
+--modal-footer-border-width: 1px;
+
+
+/* ===== NAV TABS ===== */
+--nav-tabs-border-width: 1px;
+--nav-tabs-border-color: var(--border-color);
+--nav-tabs-border-radius: 0.25rem;
+--nav-tabs-link-active-color: var(--body-color);
+--nav-tabs-link-active-bg: var(--secondary-bg);
+--nav-tabs-link-active-border-color: var(--border-color) var(--border-color) var(--secondary-bg);
+
+
+/* ===== NAV PILLS ===== */
+--nav-pills-border-radius: 0.25rem;
+--nav-pills-link-active-color: var(--body-color);
+--nav-pills-link-active-bg: hsl(240, 98%, 17%);
+
+
+/* ===== OFFCANVAS ===== */
+--offcanvas-zindex: 1045;
+--offcanvas-width: 400px;
+--offcanvas-height: 30vh;
+--offcanvas-padding-x: 1rem;
+--offcanvas-padding-y: 1rem;
+--offcanvas-color: var(--body-color);
+--offcanvas-bg: var(--body-bg);
+--offcanvas-border-width: 1px;
+--offcanvas-border-color: var(--border-color-translucent);
+--offcanvas-box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.3);
+
+
+/* ===== PAGINATION ===== */
+--pagination-padding-x: 0.75rem;
+--pagination-padding-y: 0.375rem;
+--pagination-font-size: 1rem;
+--pagination-color: var(--link-color);
+--pagination-bg: var(--secondary-bg);
+--pagination-border-width: 1px;
+--pagination-border-color: var(--border-color);
+--pagination-border-radius: 0.25rem;
+--pagination-focus-color: var(--link-active-color);
+--pagination-focus-bg: var(--tertiary-bg);
+--pagination-focus-box-shadow: 0 0 0 0.25rem rgba(84, 114, 255, 0.25);
+--pagination-active-color: var(--body-color);
+--pagination-active-bg: hsl(240, 98%, 17%);
+--pagination-active-border-color: hsl(240, 98%, 17%);
+--pagination-disabled-color: var(--gray-600);
+--pagination-disabled-bg: var(--secondary-bg);
+--pagination-disabled-border-color: var(--border-color);
+
+
+/* ===== POPOVER ===== */
+--popover-zindex: 1060;
+--popover-max-width: 276px;
+--popover-font-size: 0.875rem;
+--popover-bg: var(--secondary-bg);
+--popover-border-width: 1px;
+--popover-border-color: var(--border-color-translucent);
+--popover-border-radius: 0.3rem;
+--popover-inner-border-radius: calc(0.3rem - 1px);
+--popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.4);
+--popover-header-padding-x: 1rem;
+--popover-header-padding-y: 0.5rem;
+--popover-header-font-size: 1rem;
+--popover-header-color: ;
+--popover-header-bg: var(--tertiary-bg);
+--popover-body-padding-x: 1rem;
+--popover-body-padding-y: 1rem;
+--popover-body-color: var(--body-color);
+--popover-arrow-width: 1rem;
+--popover-arrow-height: 0.5rem;
+--popover-arrow-border: var(--popover-border-color);
+
+
+/* ===== PROGRESS ===== */
+--progress-height: 1rem;
+--progress-font-size: 0.75rem;
+--progress-bg: var(--secondary-bg);
+--progress-border-radius: 0.25rem;
+--progress-box-shadow: inset 0 1px 2px rgba(var(--black-rgb), 0.3);
+--progress-bar-color: var(--body-color);
+--progress-bar-bg: hsl(240, 98%, 40%);
+--progress-bar-transition: width 0.6s ease;
+
+
+/* ===== SPINNER ===== */
+--spinner-width: 2rem;
+--spinner-height: 2rem;
+--spinner-vertical-align: -0.125em;
+--spinner-border-width: 0.25em;
+--spinner-animation-speed: 0.75s;
+
+
+/* ===== TABLE ===== */
+--table-color: var(--body-color);
+--table-bg: transparent;
+--table-border-color: var(--border-color);
+--table-accent-bg: transparent;
+--table-striped-color: var(--body-color);
+--table-striped-bg: rgba(var(--white-rgb), var(--opacity-5));
+--table-active-color: var(--body-color);
+--table-active-bg: rgba(var(--white-rgb), 0.1);
+
+
+/* ===== TOAST ===== */
+--toast-zindex: 1090;
+--toast-padding-x: 0.75rem;
+--toast-padding-y: 0.5rem;
+--toast-spacing: 1em;
+--toast-max-width: 350px;
+--toast-font-size: 0.875rem;
+--toast-color: ;
+--toast-bg: rgba(21, 27, 34, 0.9);
+--toast-border-width: 1px;
+--toast-border-color: var(--border-color-translucent);
+--toast-border-radius: 0.25rem;
+--toast-box-shadow: 0 0.5rem 1rem var(--shadow-color-medium);
+--toast-header-color: var(--gray-600);
+--toast-header-bg: rgba(21, 27, 34, 0.85);
+--toast-header-border-color: rgba(var(--white-rgb), var(--opacity-10));
+
+
+/* ===== TOOLTIP ===== */
+--tooltip-zindex: 1070;
+--tooltip-max-width: 200px;
+--tooltip-padding-x: 0.5rem;
+--tooltip-padding-y: 0.25rem;
+--tooltip-margin: ;
+--tooltip-font-size: 0.875rem;
+--tooltip-color: var(--body-color);
+--tooltip-bg: hsl(0, 0%, 0%);
+--tooltip-border-radius: 0.25rem;
+--tooltip-opacity: 0.9;
+--tooltip-arrow-width: 0.8rem;
+--tooltip-arrow-height: 0.4rem;
+
+
+/* ===== BOOTSTRAP PALETTE ===== */
+--primary: #010156;
+--secondary: #48525d;
+--success: #4aa664;
+--info: #4f7aa0;
+--warning: #c77a00;
+--danger: #c23a31;
+--light: #1b2027;
+--dark: #0f1318;
+--primary-rgb: 1,1,86;
+--secondary-rgb: 72,82,93;
+--success-rgb: 74,166,100;
+--info-rgb: 79,122,160;
+--warning-rgb: 199,122,0;
+--danger-rgb: 194,58,49;
+--light-rgb: 27,32,39;
+--dark-rgb: 15,19,24;
+--primary-text-emphasis: #c7ccff;
+--secondary-text-emphasis: #cfd6de;
+--success-text-emphasis: #bde8c9;
+--info-text-emphasis: #bcd6ee;
+--warning-text-emphasis: #ffd9a6;
+--danger-text-emphasis: #ffb7b2;
+--light-text-emphasis: #d2d8df;
+--dark-text-emphasis: #d2d8df;
+--primary-bg-subtle: #0b1030;
+--secondary-bg-subtle: #1e2430;
+--success-bg-subtle: #0f2a1b;
+--info-bg-subtle: #0d2232;
+--warning-bg-subtle: #2a1e06;
+--danger-bg-subtle: #2d1110;
+--light-bg-subtle: #12161d;
+--dark-bg-subtle: #1e2430;
+--primary-border-subtle: #2b3a7a;
+--secondary-border-subtle: #2b323b;
+--success-border-subtle: #2b5b40;
+--info-border-subtle: #254861;
+--warning-border-subtle: #5a3c0e;
+--danger-border-subtle: #5c2723;
+--light-border-subtle: #222831;
+--dark-border-subtle: #2b323b;
+
+
+/* ===== HERO / BANNER OVERLAY ===== */
+--hero-height: 70vh;
+--hero-color: var(--body-color);
+--hero-bg-repeat: no-repeat;
+--hero-bg-attachment: fixed;
+--hero-bg-position: top center;
+--hero-bg-size: cover;
+--hero-border-bottom: solid var(--accent-color-secondary);
+--hero-overlay-bg: hsla(0, 0%, 0%, 0.3);
+--hero-overlay-bg-position: center;
+--hero-overlay-bg-size: cover;
+--hero-overlay-padding: 1em;
+--hero-overlay-text-align: center;
+--hero-overlay-text-color: var(--body-color);
+
+
+/* ===== HERO VARIANTS ===== */
+/* Primary — deep navy, dark overlay */
+--hero-primary-bg-color: #0d1e3a;
+--hero-primary-overlay: linear-gradient(rgba(13, 30, 58, .65), rgba(13, 30, 58, .65));
+--hero-primary-color: #f1f5f9;
+
+/* Secondary — darker navy, heavier overlay */
+--hero-secondary-bg-color: #080f1e;
+--hero-secondary-overlay: linear-gradient(rgba(8, 15, 30, .80), rgba(8, 15, 30, .80));
+--hero-secondary-color: #f1f5f9;
+
+
+/* ===== HERO CARD (inner .hero element) ===== */
+/* Default card — uses primary variant values */
+--hero-card-bg: var(--hero-primary-bg-color);
+--hero-card-color: white;
+--hero-card-overlay: var(--hero-primary-overlay);
+--hero-card-border-radius: .5rem;
+--hero-card-padding-x: 2rem;
+--hero-card-padding-y: 3rem;
+--hero-card-max-width: 800px;
+
+/* Alternative card — uses secondary variant values */
+--hero-alt-card-bg: var(--hero-secondary-bg-color);
+--hero-alt-card-color: var(--hero-secondary-color);
+--hero-alt-card-overlay: var(--hero-secondary-overlay);
+--hero-alt-card-border-radius: .5rem;
+--hero-alt-card-padding-x: 2rem;
+--hero-alt-card-padding-y: 3rem;
+--hero-alt-card-max-width: 600px;
+
+
+/* ===== BLOCK COLORS (top-a / top-b / bottom-a / bottom-b) ===== */
+--block-color-1: var(--secondary-bg);
+--block-text-1: var(--body-color);
+
+--block-color-2: var(--accent-color-primary);
+--block-text-2: #fff;
+
+--block-color-3: rgba(238, 194, 52, .15);
+--block-text-3: var(--body-color);
+
+--block-color-4: rgba(74, 166, 100, .15);
+--block-text-4: var(--body-color);
+
+
+/* ===== BLOCK COLOR OVERRIDES ===== */
+--block-highlight-bg: var(--accent-color-primary);
+--block-highlight-text: #fff;
+
+--block-cta-bg: var(--color-primary);
+--block-cta-text: #f1f5f9;
+
+--block-alert-bg: var(--danger, #c23a31);
+--block-alert-text: #fff;
+
+
+/* ===== FOOTER ===== */
+--footer-padding-top: 1rem;
+--footer-padding-bottom: 80px;
+--footer-grid-padding-y: 2.5rem;
+--footer-grid-padding-x: 0.5em;
+
+
+/* ===== THEME FAB ===== */
+--theme-fab-bg: #e6ebf1;
+--theme-fab-color: #0e1318;
+--theme-fab-btn-bg: transparent;
+--theme-fab-border: rgba(0, 0, 0, 0.15);
+
+
+/* ===== OFFLINE PAGE ===== */
+--offline-card-bg: rgba(0, 0, 0, 0.6);
+
+
+/* ===== COMPONENT-SPECIFIC COLORS ===== */
+--mod-finder-link-hover: #5a6470;
+--form-legend-color: #9fa6ad;
+--border-gray: #3a4250;
+--subhead-color: #9fa6ad;
+--box-shadow-gray: #1a2027;
+--btn-active-text-gray: #7a8490;
+--indicator-success-bg: var(--success);
+--item-list-color: #2a2f34;
+--notification-badge-bg: var(--danger);
+--content-bg-gray: #2b323b;
+--taba-btn-green: #5a9c2f;
+--taba-btn-blue: #3d75a8;
+--taba-btn-red: #c43620;
+--taba-btn-gray: #6a7080;
+--taba-msg-bg: #1e2430;
+--toc-link-color: #9fa6ad;
+--toc-link-active-color: #91a4ff;
+--choices-disabled-bg: #2b323b;
+--choices-input-bg: var(--body-bg);
+--choices-border-light: #48525d;
+--choices-arrow-color: #9fa6ad;
+--choices-inner-bg: #1a2027;
+--choices-focused-border: #5472ff;
+--choices-dropdown-bg: var(--body-bg);
+--choices-item-bg: #1a5f75;
+--choices-item-border: #1a748f;
+--choices-item-hover-bg: #1a748f;
+--choices-item-hover-border: #1a8aa8;
+--choices-item-disabled-bg: #48525d;
+--choices-item-disabled-border: #36404a;
+--choices-item-highlighted: #2b323b;
+--choices-input-inner-bg: #1a2027;
+
+
+/* ===== VIRTUEMART (VM) ===== */
+/* VM Surfaces */
+--vm-surface: var(--secondary-bg);
+--vm-surface-2: var(--tertiary-bg);
+--vm-text: var(--body-color);
+--vm-text-strong: #ffffff;
+--vm-text-muted: var(--gray-700);
+--vm-border: var(--border-color);
+--vm-price-color: var(--success);
+
+/* VM Layout and Density */
+--vm-container-max-width: 1200px;
+--vm-section-gap: 2rem;
+--vm-block-radius: var(--border-radius);
+--vm-block-shadow: var(--box-shadow-sm);
+
+/* VM Typography */
+--vm-category-title-size: 2rem;
+--vm-subcategory-title-size: 1.5rem;
+--vm-page-title-size: 1.75rem;
+--vm-products-type-title-size: 1.25rem;
+--vm-product-title-size: 1.125rem;
+--vm-product-title-weight: 500;
+--vm-products-type-title-weight: 600;
+--vm-price-size: 1.5rem;
+--vm-price-detail-size: 1.125rem;
+--vm-price-desc-size: 0.875rem;
+
+/* VM Controls */
+--vm-input-radius: var(--border-radius);
+--vm-input-shadow: var(--box-shadow-sm);
+--vm-qty-width: 80px;
+--vm-cart-dropdown-min-width: 300px;
+
+/* VM Alerts */
+--vm-alert-radius: var(--border-radius);
+--vm-alert-shadow: var(--box-shadow-sm);
+--vm-availability-bg: var(--success-bg-subtle);
+--vm-availability-text: var(--success);
+
+/* VM Buttons */
+--vm-btn-padding-x: 1rem;
+--vm-btn-padding-y: 0.5rem;
+--vm-btn-radius: var(--border-radius);
+--vm-btn-shadow: var(--box-shadow-sm);
+--vm-btn-primary-bg: var(--primary);
+--vm-btn-primary-text: #ffffff;
+--vm-btn-primary-border: var(--primary);
+--vm-btn-secondary-bg: var(--secondary);
+--vm-btn-secondary-text: #ffffff;
+--vm-btn-secondary-border: var(--secondary);
+
+/* VM Image Overlay Controls */
+--vm-image-overlay-gap-x: 0.5rem;
+--vm-image-overlay-gap-y: 0.5rem;
+--vm-image-overlay-raise: 0.25rem;
+--vm-image-overlay-btn-size: 2.5rem;
+--vm-image-overlay-btn-radius: 50%;
+--vm-image-overlay-btn-bg: rgba(0, 0, 0, 0.7);
+--vm-image-overlay-btn-bg-hover: rgba(0, 0, 0, 0.85);
+--vm-image-overlay-btn-border-color: rgba(255, 255, 255, 0.2);
+--vm-image-overlay-btn-border-width: 1px;
+--vm-image-overlay-btn-color: var(--body-color);
+--vm-image-overlay-btn-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
+
+/* VM Vendor Menu */
+--vm-vendor-menu-bg: var(--secondary-bg);
+--vm-vendor-menu-border: var(--border-color);
+--vm-vendor-menu-radius: var(--border-radius);
+--vm-vendor-menu-shadow: var(--box-shadow-sm);
+--vm-vendor-menu-item-gap: 0.25rem;
+--vm-vendor-menu-item-padding-x: 1rem;
+--vm-vendor-menu-item-padding-y: 0.5rem;
+--vm-vendor-menu-pill-radius: 50rem;
+--vm-vendor-menu-link: var(--link-color);
+--vm-vendor-menu-link-hover: var(--link-hover-color);
+--vm-vendor-menu-link-active: var(--primary);
+--vm-vendor-menu-hover-bg: var(--tertiary-bg);
+
+
+/* ===== GABLE ===== */
+--gab-blue: #4d9fff;
+--gab-green: #5cb85c;
+--gab-red: #ff6b6b;
+--gab-orange: #ff9f5a;
+--gab-gray1: #868e96;
+--gab-gray2: #adb5bd;
+--gab-gray3: #ced4da;
+
+}
+
+.btn {
+ --btn-padding-x: 1rem;
+ --btn-padding-y: 0.6rem;
+ --btn-font-family: inherit;
+ --btn-font-size: 1rem;
+ --btn-font-weight: 400;
+ --btn-line-height: 1.5;
+ --btn-color: var(--white);
+ --btn-bg: var(--body-bg);
+ --btn-border-width: 1px;
+ --btn-border-color: transparent;
+ --btn-border-radius: 0.25rem;
+ --btn-active-border-color: transparent;
+ --btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
+ --btn-disabled-opacity: 0.65;
+ --btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb), .5);
+ display: inline-block;
+ padding: var(--btn-padding-y) var(--btn-padding-x);
+ font-family: var(--btn-font-family);
+ font-size: var(--btn-font-size);
+ font-weight: var(--btn-font-weight);
+ line-height: var(--btn-line-height);
+ color: var(--btn-color);
+ text-align: center;
+ text-decoration: none;
+ vertical-align: middle;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ border: var(--btn-border-width) solid var(--btn-border-color);
+ border-radius: var(--btn-border-radius);
+ background-color: var(--btn-bg);
+ -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ -o-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+}
+
+/* Buttons — inherit brand hues; ensure strong contrast on dark bg */
+.btn-primary {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(240, 98%, 17%);
+ --btn-border-color: hsl(240, 98%, 17%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #010149;
+ --btn-hover-border-color: #010145;
+ --btn-focus-shadow-rgb: 84, 114, 255;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #010145;
+ --btn-active-border-color: #010141;
+}
+
+.btn-secondary {
+ --btn-color: var(--nav-text-color);
+ --btn-bg: var(--nav-bg-color);
+ --btn-border-color: #3a4250;
+ --btn-hover-color: #fff;
+ --btn-hover-bg: #1b2a55;
+ --btn-hover-border-color: #162448;
+ --btn-focus-shadow-rgb: 84, 114, 255;
+ --btn-active-color: #fff;
+ --btn-active-bg: #162448;
+ --btn-active-border-color: #12203f;
+}
+
+.btn-success {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(120, 35%, 45%);
+ --btn-border-color: hsl(120, 35%, 45%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(120, 35%, 40%);
+ --btn-hover-border-color: hsl(120, 35%, 38%);
+ --btn-focus-shadow-rgb: 96, 180, 96;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(120, 35%, 38%);
+ --btn-active-border-color: hsl(120, 35%, 36%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(120, 35%, 45%);
+ --btn-disabled-border-color: hsl(120, 35%, 45%);
+}
+
+.btn-info {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(207, 55%, 55%);
+ --btn-border-color: hsl(207, 55%, 55%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(207, 55%, 50%);
+ --btn-hover-border-color: hsl(207, 55%, 48%);
+ --btn-focus-shadow-rgb: 100, 160, 210);
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(207, 55%, 48%);
+ --btn-active-border-color: hsl(207, 55%, 46%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(207, 55%, 55%);
+ --btn-disabled-border-color: hsl(207, 55%, 55%);
+}
+
+.btn-warning {
+ --btn-color: hsl(0, 0%, 0%);
+ --btn-bg: hsl(38, 100%, 50%);
+ --btn-border-color: hsl(38, 100%, 50%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(38, 100%, 45%);
+ --btn-hover-border-color: hsl(38, 100%, 43%);
+ --btn-focus-shadow-rgb: 220, 170, 40;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(38, 100%, 43%);
+ --btn-active-border-color: hsl(38, 100%, 41%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 0%);
+ --btn-disabled-bg: hsl(38, 100%, 50%);
+ --btn-disabled-border-color: hsl(38, 100%, 50%);
+}
+
+.btn-danger {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(3, 82%, 50%);
+ --btn-border-color: hsl(3, 82%, 50%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(3, 82%, 45%);
+ --btn-hover-border-color: hsl(3, 82%, 43%);
+ --btn-focus-shadow-rgb: 220, 80, 80;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(3, 82%, 43%);
+ --btn-active-border-color: hsl(3, 82%, 41%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(3, 82%, 50%);
+ --btn-disabled-border-color: hsl(3, 82%, 50%);
+}
+
+.btn-light {
+ --btn-color: hsl(0, 0%, 0%);
+ --btn-bg: hsl(210, 17%, 85%);
+ --btn-border-color: hsl(210, 17%, 85%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(210, 17%, 80%);
+ --btn-hover-border-color: hsl(210, 17%, 78%);
+ --btn-focus-shadow-rgb: 200, 205, 210;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(210, 17%, 78%);
+ --btn-active-border-color: hsl(210, 17%, 76%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 0%);
+ --btn-disabled-bg: hsl(210, 17%, 85%);
+ --btn-disabled-border-color: hsl(210, 17%, 85%);
+}
+
+.btn-dark {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(210, 10%, 20%);
+ --btn-border-color: hsl(210, 10%, 20%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(210, 10%, 18%);
+ --btn-hover-border-color: hsl(210, 10%, 16%);
+ --btn-focus-shadow-rgb: 60, 65, 70;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(210, 10%, 16%);
+ --btn-active-border-color: hsl(210, 10%, 14%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(210, 10%, 20%);
+ --btn-disabled-border-color: hsl(210, 10%, 20%);
+}
+
+.btn-outline-primary {
+ --btn-color: hsl(240, 98%, 40%);
+ --btn-border-color: hsl(240, 98%, 40%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(240, 98%, 40%);
+ --btn-hover-border-color: hsl(240, 98%, 40%);
+ --btn-focus-shadow-rgb: 80, 80, 180;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(240, 98%, 40%);
+ --btn-active-border-color: hsl(240, 98%, 40%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(240, 98%, 40%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(240, 98%, 40%);
+ --gradient: none;
+}
+
+.btn-outline-secondary {
+ --btn-color: hsl(210, 20%, 60%);
+ --btn-border-color: hsl(210, 20%, 60%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(210, 20%, 60%);
+ --btn-hover-border-color: hsl(210, 20%, 60%);
+ --btn-focus-shadow-rgb: 120, 140, 160;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(210, 20%, 60%);
+ --btn-active-border-color: hsl(210, 20%, 60%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(210, 20%, 60%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(210, 20%, 60%);
+ --gradient: none;
+}
+
+.btn-outline-success {
+ --btn-color: hsl(120, 35%, 55%);
+ --btn-border-color: hsl(120, 35%, 55%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(120, 35%, 55%);
+ --btn-hover-border-color: hsl(120, 35%, 55%);
+ --btn-focus-shadow-rgb: 100, 190, 100;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(120, 35%, 55%);
+ --btn-active-border-color: hsl(120, 35%, 55%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(120, 35%, 55%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(120, 35%, 55%);
+ --gradient: none;
+}
+
+.btn-outline-info {
+ --btn-color: hsl(207, 55%, 65%);
+ --btn-border-color: hsl(207, 55%, 65%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(207, 55%, 65%);
+ --btn-hover-border-color: hsl(207, 55%, 65%);
+ --btn-focus-shadow-rgb: 110, 170, 220;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(207, 55%, 65%);
+ --btn-active-border-color: hsl(207, 55%, 65%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(207, 55%, 65%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(207, 55%, 65%);
+ --gradient: none;
+}
+
+.btn-outline-warning {
+ --btn-color: hsl(38, 100%, 60%);
+ --btn-border-color: hsl(38, 100%, 60%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(38, 100%, 60%);
+ --btn-hover-border-color: hsl(38, 100%, 60%);
+ --btn-focus-shadow-rgb: 240, 190, 70;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(38, 100%, 60%);
+ --btn-active-border-color: hsl(38, 100%, 60%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(38, 100%, 60%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(38, 100%, 60%);
+ --gradient: none;
+}
+
+.btn-outline-danger {
+ --btn-color: hsl(3, 82%, 60%);
+ --btn-border-color: hsl(3, 82%, 60%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(3, 82%, 60%);
+ --btn-hover-border-color: hsl(3, 82%, 60%);
+ --btn-focus-shadow-rgb: 240, 100, 100;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(3, 82%, 60%);
+ --btn-active-border-color: hsl(3, 82%, 60%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(3, 82%, 60%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(3, 82%, 60%);
+ --gradient: none;
+}
+
+/* Outline buttons on dark: keep readable borders */
+.btn-outline-light {
+ --btn-color: #e6ebf1;
+ --btn-border-color: #e6ebf1;
+ --btn-hover-color: #111;
+ --btn-hover-bg: #e6ebf1;
+ --btn-hover-border-color: #e6ebf1;
+ --btn-active-color: #111;
+ --btn-active-bg: #d7dce2;
+ --btn-active-border-color: #d7dce2;
+ --gradient: none;
+}
+
+.btn-outline-dark {
+ --btn-color: hsl(210, 10%, 30%);
+ --btn-border-color: hsl(210, 10%, 30%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(210, 10%, 30%);
+ --btn-hover-border-color: hsl(210, 10%, 30%);
+ --btn-focus-shadow-rgb: 70, 75, 80;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(210, 10%, 30%);
+ --btn-active-border-color: hsl(210, 10%, 30%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(210, 10%, 30%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(210, 10%, 30%);
+ --gradient: none;
+}
+
+/* Links as buttons */
+.btn-link {
+ --btn-font-weight: 400;
+ --btn-color: var(--color-link);
+ --btn-bg: transparent;
+ --btn-border-color: transparent;
+ --btn-hover-color: var(--link-hover-color);
+ --btn-hover-border-color: transparent;
+ --btn-active-color: var(--link-hover-color);
+ --btn-active-border-color: transparent;
+ --btn-disabled-color: #6d7781;
+ --btn-disabled-border-color: transparent;
+ --btn-box-shadow: none;
+ --btn-focus-shadow-rgb: 84, 114, 255;
+ text-decoration: underline;
+}
diff --git a/src/media/css/theme/dark.standard.min.css b/src/media/css/theme/dark.standard.min.css
new file mode 100644
index 0000000..8a74e5e
--- /dev/null
+++ b/src/media/css/theme/dark.standard.min.css
@@ -0,0 +1 @@
+@charset "UTF-8";:root[data-bs-theme=dark]{color-scheme:dark;--color-primary:#112855;--accent-color-primary:#3f8ff0;--accent-color-secondary:#6fb3ff;--mainmenu-nav-link-color:#fff;--nav-text-color:gray;--nav-bg-color:var(--color-primary);--color-link:white;--color-hover:gray;--color-active:var(--mainmenu-nav-link-color);--link-color:#8ab4f8;--link-color-rgb:138,180,248;--link-decoration:underline;--link-hover-color:#c3d6ff;--link-hover-color-rgb:195,214,255;--link-active-color:var(--link-color);--offcanvas-color:var(--body-color);--offcanvas-padding-x:1rem;--offcanvas-padding-y:1rem;--navbar-padding-x:1rem;--navbar-padding-y:0.5rem;--navbar-color:var(--nav-text-color);--navbar-active-color:var(--mainmenu-nav-link-color);--navbar-disabled-color:#6c757d;--navbar-brand-padding-y:0.3125rem;--navbar-brand-margin-end:1rem;--navbar-brand-font-size:1.25rem;--navbar-brand-color:var(--nav-text-color);--navbar-brand-active-color:var(--mainmenu-nav-link-color);--navbar-nav-link-padding-x:0.5rem;--navbar-toggler-padding-y:0.25rem;--navbar-toggler-padding-x:0.75rem;--navbar-toggler-font-size:1.25rem;--navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--navbar-toggler-border-radius:0.25rem;--navbar-toggler-focus-width:0.25rem;--navbar-toggler-transition:box-shadow 0.15s ease-in-out;--nav-link-padding-x:1rem;--nav-link-padding-y:0.5rem;--nav-link-font-weight:400;--nav-link-color:var(--nav-text-color);--nav-link-active-color:var(--mainmenu-nav-link-color);--nav-link-disabled-color:#6c757d;--font-sans-serif:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji';--font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--body-font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji';--body-font-size:1rem;--body-font-weight:400;--body-line-height:1.5;--body-color:#e6ebf1;--body-color-rgb:230,235,241;--body-bg:#0e1318;--body-bg-rgb:14,19,24;--heading-color:#f1f5f9;--emphasis-color:#fff;--emphasis-color-rgb:255,255,255;--secondary-color:#e6ebf1bf;--secondary-color-rgb:230,235,241;--tertiary-color:#e6ebf180;--tertiary-color-rgb:230,235,241;--muted-color:#6d757e;--code-color:#ff7abd;--code-color-ink:var(--code-color, #e93f8e);--highlight-color:#111;--highlight-bg:#ffe28a1a;--padding-x:0.15rem;--padding-y:0.15rem;--bg-opacity:1;--nav-toggle-size:3rem;--gradient:linear-gradient(180deg, #ffffff26, #fff0);--secondary-bg:#151b22;--secondary-bg-rgb:21,27,34;--tertiary-bg:#10151b;--tertiary-bg-rgb:16,21,27;--hr-color:var(--border-color, #dfe3e7);--border-color-soft:var(--border-color, #dfe3e7);--kbd-bg:var(--secondary-bg, #eaedf0);--kbd-ink:var(--body-bg, #fff);--toc-bg:var(--secondary-bg, #eaedf0);--toc-ink:var(--color-primary, #112855);--selection-bg:var(--highlight-bg, #fbeea8);--selection-ink:var(--body-color, #22262a);--border:5px;--bp-xs:0;--bp-sm:576px;--bp-md:768px;--bp-lg:992px;--bp-xl:1200px;--primary:#010156;--secondary:#48525d;--success:#4aa664;--info:#4f7aa0;--warning:#c77a00;--danger:#c23a31;--light:#1b2027;--dark:#0f1318;--primary-rgb:1,1,86;--secondary-rgb:72,82,93;--success-rgb:74,166,100;--info-rgb:79,122,160;--warning-rgb:199,122,0;--danger-rgb:194,58,49;--light-rgb:27,32,39;--dark-rgb:15,19,24;--primary-text-emphasis:#c7ccff;--secondary-text-emphasis:#cfd6de;--success-text-emphasis:#bde8c9;--info-text-emphasis:#bcd6ee;--warning-text-emphasis:#ffd9a6;--danger-text-emphasis:#ffb7b2;--light-text-emphasis:#d2d8df;--dark-text-emphasis:#d2d8df;--primary-bg-subtle:#0b1030;--secondary-bg-subtle:#1e2430;--success-bg-subtle:#0f2a1b;--info-bg-subtle:#0d2232;--warning-bg-subtle:#2a1e06;--danger-bg-subtle:#2d1110;--light-bg-subtle:#12161d;--dark-bg-subtle:#1e2430;--primary-border-subtle:#2b3a7a;--secondary-border-subtle:#2b323b;--success-border-subtle:#2b5b40;--info-border-subtle:#254861;--warning-border-subtle:#5a3c0e;--danger-border-subtle:#5c2723;--light-border-subtle:#222831;--dark-border-subtle:#2b323b;--alert-primary-link-color:#b3c1ff;--alert-secondary-link-color:#9fa6ad;--alert-success-link-color:#a0e5b3;--alert-info-link-color:#8eccf2;--alert-warning-link-color:#ffe4a0;--alert-danger-link-color:#ffa8a3;--alert-light-link-color:#f0f4f8;--alert-dark-link-color:#9fa6ad;--list-group-item-primary-color:#8ca3ff;--list-group-item-primary-bg:#1a2550;--list-group-item-primary-active-bg:#223066;--list-group-item-secondary-color:#9fa6ad;--list-group-item-secondary-bg:#2b323b;--list-group-item-secondary-active-bg:#363d47;--list-group-item-success-color:#a0e5b3;--list-group-item-success-bg:#1e3d2d;--list-group-item-success-active-bg:#275538;--list-group-item-info-color:#8eccf2;--list-group-item-info-bg:#1a3448;--list-group-item-info-active-bg:#234459;--list-group-item-warning-color:#ffe4a0;--list-group-item-warning-bg:#4a3410;--list-group-item-warning-active-bg:#5c4216;--list-group-item-danger-color:#ffa8a3;--list-group-item-danger-bg:#4a1e1c;--list-group-item-danger-active-bg:#5c2823;--list-group-item-light-color:#e9ecef;--list-group-item-light-bg:#1e2430;--list-group-item-light-active-bg:#282f3d;--list-group-item-dark-color:#48525d;--list-group-item-dark-bg:#0e1318;--list-group-item-dark-active-bg:#161b22;--link-primary-color:hsl(240, 98%, 50%);--link-primary-hover-color:hsl(240, 98%, 45%);--link-secondary-color:hsl(210, 15%, 70%);--link-secondary-hover-color:hsl(210, 15%, 65%);--link-success-color:hsl(120, 40%, 60%);--link-success-hover-color:hsl(120, 40%, 55%);--link-info-color:hsl(207, 60%, 65%);--link-info-hover-color:hsl(207, 60%, 60%);--link-warning-color:hsl(38, 100%, 65%);--link-warning-hover-color:hsl(38, 100%, 60%);--link-danger-color:hsl(3, 85%, 65%);--link-danger-hover-color:hsl(3, 85%, 60%);--link-light-color:hsl(210, 20%, 90%);--link-light-hover-color:hsl(210, 20%, 85%);--link-dark-color:hsl(210, 10%, 35%);--link-dark-hover-color:hsl(210, 10%, 30%);--mod-finder-link-hover:#5a6470;--form-legend-color:#9fa6ad;--border-gray:#3a4250;--subhead-color:#9fa6ad;--box-shadow-gray:#1a2027;--btn-active-text-gray:#7a8490;--indicator-success-bg:var(--success);--item-list-color:#2a2f34;--notification-badge-bg:var(--danger);--content-bg-gray:#2b323b;--taba-btn-green:#5a9c2f;--taba-btn-blue:#3d75a8;--taba-btn-red:#c43620;--taba-btn-gray:#6a7080;--taba-msg-bg:#1e2430;--toc-link-color:#9fa6ad;--toc-link-active-color:#91a4ff;--choices-disabled-bg:#2b323b;--choices-input-bg:var(--body-bg);--choices-border-light:#48525d;--choices-arrow-color:#9fa6ad;--choices-inner-bg:#1a2027;--choices-focused-border:#5472ff;--choices-dropdown-bg:var(--body-bg);--choices-item-bg:#1a5f75;--choices-item-border:#1a748f;--choices-item-hover-bg:#1a748f;--choices-item-hover-border:#1a8aa8;--choices-item-disabled-bg:#48525d;--choices-item-disabled-border:#36404a;--choices-item-highlighted:#2b323b;--choices-input-inner-bg:#1a2027;--blue:#91a4ff;--indigo:#b19cff;--purple:#c0a5ff;--pink:#ff8fc0;--red:#ff7a73;--orange:#ff9c4d;--yellow:#ffd166;--green:#78d694;--teal:#76e3ff;--cyan:#6fb7ff;--black:#000;--white:#fff;--gray-100:#161a20;--gray-200:#1b2027;--gray-300:#222831;--gray-400:#2b323b;--gray-500:#36404a;--gray-600:#48525d;--gray-700:#5b6672;--gray-800:#cfd6de;--gray-900:#e6ebf1;--white-rgb:255,255,255;--black-rgb:0,0,0;--opacity-0:0;--opacity-5:0.05;--opacity-10:0.1;--opacity-15:0.15;--opacity-20:0.2;--opacity-25:0.25;--opacity-30:0.3;--opacity-50:0.5;--opacity-75:0.75;--opacity-100:1;--shadow-color-light:rgba(var(--black-rgb), var(--opacity-30));--shadow-color-medium:rgba(var(--black-rgb), var(--opacity-50));--shadow-color-dark:rgba(var(--black-rgb), var(--opacity-75));--border-color-translucent:rgba(var(--white-rgb), var(--opacity-10));--highlight-translucent:rgba(var(--white-rgb), var(--opacity-5));--header-background-image:url('../../../../../../media/templates/site/mokoonyx/images/bg.svg');--header-background-attachment:fixed;--header-background-repeat:repeat;--header-background-size:auto;--container-below-topbar-bg-image:none;--container-below-topbar-bg-color:transparent;--container-below-topbar-bg-position:center;--container-below-topbar-bg-attachment:fixed;--container-below-topbar-bg-repeat:no-repeat;--container-below-topbar-bg-size:cover;--container-below-topbar-border:none;--container-below-topbar-border-radius:0;--container-top-a-bg-image:none;--container-top-a-bg-color:transparent;--container-top-a-bg-position:center;--container-top-a-bg-attachment:fixed;--container-top-a-bg-repeat:no-repeat;--container-top-a-bg-size:cover;--container-top-a-border:none;--container-top-a-border-radius:0;--container-top-b-bg-image:none;--container-top-b-bg-color:transparent;--container-top-b-bg-position:center;--container-top-b-bg-attachment:fixed;--container-top-b-bg-repeat:no-repeat;--container-top-b-bg-size:cover;--container-top-b-border:none;--container-top-b-border-radius:0;--container-toc-bg:var(--secondary-bg);--container-toc-color:#dbe3ff;--container-sidebar-bg-image:none;--container-sidebar-bg-color:transparent;--container-sidebar-bg-position:center;--container-sidebar-bg-attachment:scroll;--container-sidebar-bg-repeat:repeat;--container-sidebar-bg-size:auto;--container-sidebar-border:none;--container-sidebar-border-radius:0;--container-bottom-a-bg-image:none;--container-bottom-a-bg-color:transparent;--container-bottom-a-bg-position:center;--container-bottom-a-bg-attachment:fixed;--container-bottom-a-bg-repeat:no-repeat;--container-bottom-a-bg-size:cover;--container-bottom-a-border:none;--container-bottom-a-border-radius:5px;--container-bottom-b-bg-image:none;--container-bottom-b-bg-color:transparent;--container-bottom-b-bg-position:center;--container-bottom-b-bg-attachment:fixed;--container-bottom-b-bg-repeat:no-repeat;--container-bottom-b-bg-size:cover;--container-bottom-b-border:none;--container-bottom-b-border-radius:0;--border-width:1px;--border-style:solid;--border-color:#2b323b;--border-color-translucent:#ffffff26;--border-radius:.25rem;--border-radius-sm:.2rem;--border-radius-lg:.3rem;--border-radius-xl:.3rem;--border-radius-xxl:2rem;--border-radius-2xl:var(--border-radius-xxl);--border-radius-pill:50rem;--box-shadow:0 .5rem 1rem #00000066;--box-shadow-sm:0 .125rem .25rem #00000040;--box-shadow-lg:0 1rem 3rem #00000080;--box-shadow-inset:inset 0 1px 2px #00000040;--focus-ring-width:.25rem;--focus-ring-opacity:.6;--focus-ring-color:#5472ff66;--input-color:#e6ebf1;--input-bg:#1a2332;--input-border-color:#3a4250;--input-focus-border-color:#5472ff;--input-focus-box-shadow:0 0 0 0.25rem rgba(84, 114, 255, 0.25);--input-placeholder-color:#8894aa;--input-disabled-bg:#0f1318;--input-disabled-border-color:#2b323b;--input-file-button-active-bg:#2b3441;--form-range-thumb-active-bg:#4a5766;--form-valid-color:#78d694;--form-valid-border-color:#78d694;--form-invalid-color:#ff8e86;--form-invalid-border-color:#ff8e86;--btn-border-radius:var(--border-radius);--btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.05),0 1px 1px rgba(0, 0, 0, 0.3);--card-spacer-y:1rem;--card-spacer-x:1rem;--card-title-spacer-y:0.5rem;--card-border-width:1px;--card-border-color:var(--border-color);--card-border-radius:var(--border-radius);--card-box-shadow:none;--card-inner-border-radius:calc(var(--border-radius) - 1px);--card-cap-padding-y:0.5rem;--card-cap-padding-x:1rem;--card-cap-bg:rgba(255, 255, 255, 0.03);--card-cap-color:var(--body-color);--card-height:auto;--card-color:var(--body-color);--card-bg:var(--secondary-bg);--card-img-overlay-padding:1rem;--card-group-margin:0.75rem;--vm-surface:var(--secondary-bg);--vm-surface-2:var(--tertiary-bg);--vm-text:var(--body-color);--vm-text-strong:#ffffff;--vm-text-muted:var(--gray-700);--vm-border:var(--border-color);--vm-price-color:var(--success);--vm-container-max-width:1200px;--vm-section-gap:2rem;--vm-block-radius:var(--border-radius);--vm-block-shadow:var(--box-shadow-sm);--vm-category-title-size:2rem;--vm-subcategory-title-size:1.5rem;--vm-page-title-size:1.75rem;--vm-products-type-title-size:1.25rem;--vm-product-title-size:1.125rem;--vm-product-title-weight:500;--vm-products-type-title-weight:600;--vm-price-size:1.5rem;--vm-price-detail-size:1.125rem;--vm-price-desc-size:0.875rem;--vm-input-radius:var(--border-radius);--vm-input-shadow:var(--box-shadow-sm);--vm-qty-width:80px;--vm-cart-dropdown-min-width:300px;--vm-alert-radius:var(--border-radius);--vm-alert-shadow:var(--box-shadow-sm);--vm-availability-bg:var(--success-bg-subtle);--vm-availability-text:var(--success);--vm-btn-padding-x:1rem;--vm-btn-padding-y:0.5rem;--vm-btn-radius:var(--border-radius);--vm-btn-shadow:var(--box-shadow-sm);--vm-btn-primary-bg:var(--primary);--vm-btn-primary-text:#ffffff;--vm-btn-primary-border:var(--primary);--vm-btn-secondary-bg:var(--secondary);--vm-btn-secondary-text:#ffffff;--vm-btn-secondary-border:var(--secondary);--vm-image-overlay-gap-x:0.5rem;--vm-image-overlay-gap-y:0.5rem;--vm-image-overlay-raise:0.25rem;--vm-image-overlay-btn-size:2.5rem;--vm-image-overlay-btn-radius:50%;--vm-image-overlay-btn-bg:rgba(0, 0, 0, 0.7);--vm-image-overlay-btn-bg-hover:rgba(0, 0, 0, 0.85);--vm-image-overlay-btn-border-color:rgba(255, 255, 255, 0.2);--vm-image-overlay-btn-border-width:1px;--vm-image-overlay-btn-color:var(--body-color);--vm-image-overlay-btn-shadow:0 2px 4px rgba(0, 0, 0, 0.3);--vm-vendor-menu-bg:var(--secondary-bg);--vm-vendor-menu-border:var(--border-color);--vm-vendor-menu-radius:var(--border-radius);--vm-vendor-menu-shadow:var(--box-shadow-sm);--vm-vendor-menu-item-gap:0.25rem;--vm-vendor-menu-item-padding-x:1rem;--vm-vendor-menu-item-padding-y:0.5rem;--vm-vendor-menu-pill-radius:50rem;--vm-vendor-menu-link:var(--link-color);--vm-vendor-menu-link-hover:var(--link-hover-color);--vm-vendor-menu-link-active:var(--primary);--vm-vendor-menu-hover-bg:var(--tertiary-bg);--gab-blue:#4d9fff;--gab-green:#5cb85c;--gab-red:#ff6b6b;--gab-orange:#ff9f5a;--gab-gray1:#868e96;--gab-gray2:#adb5bd;--gab-gray3:#ced4da;--hero-height:70vh;--hero-color:var(--body-color);--hero-bg-repeat:no-repeat;--hero-bg-attachment:fixed;--hero-bg-position:top center;--hero-bg-size:cover;--hero-border-bottom:solid var(--accent-color-secondary);--hero-overlay-bg:hsla(0, 0%, 0%, 0.3);--hero-overlay-padding:1em;--hero-overlay-text-align:center;--hero-overlay-text-color:var(--body-color);--offcanvas-zindex:1045;--offcanvas-width:400px;--offcanvas-height:30vh;--offcanvas-padding-x:1rem;--offcanvas-padding-y:1rem;--offcanvas-color:var(--body-color);--offcanvas-bg:var(--body-bg);--offcanvas-border-width:1px;--offcanvas-border-color:var(--border-color-translucent);--offcanvas-box-shadow:0 0.25rem 0.75rem rgba(0, 0, 0, 0.3);--accordion-color:var(--body-color);--accordion-bg:var(--body-bg);--accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--accordion-border-color:var(--border-color);--accordion-border-width:1px;--accordion-border-radius:0.25rem;--accordion-inner-border-radius:calc(0.25rem - 1px);--accordion-btn-padding-x:1.25rem;--accordion-btn-padding-y:1rem;--accordion-btn-color:var(--body-color);--accordion-btn-bg:var(--accordion-bg);--accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23e6ebf1'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--accordion-btn-icon-width:1.25rem;--accordion-btn-icon-transform:rotate(-180deg);--accordion-btn-icon-transition:transform 0.2s ease-in-out;--accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%238ab4f8'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--accordion-btn-focus-border-color:var(--input-focus-border-color);--accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(84, 114, 255, 0.25);--accordion-body-padding-x:1.25rem;--accordion-body-padding-y:1rem;--accordion-active-color:var(--link-color);--accordion-active-bg:var(--secondary-bg);--breadcrumb-padding-x:0;--breadcrumb-padding-y:0;--breadcrumb-margin-bottom:1rem;--breadcrumb-bg: ;--breadcrumb-border-radius: ;--breadcrumb-divider-color:var(--gray-600);--breadcrumb-item-padding-x:0.5rem;--breadcrumb-item-active-color:var(--link-color);--pagination-padding-x:0.75rem;--pagination-padding-y:0.375rem;--pagination-font-size:1rem;--pagination-color:var(--link-color);--pagination-bg:var(--secondary-bg);--pagination-border-width:1px;--pagination-border-color:var(--border-color);--pagination-border-radius:0.25rem;--pagination-focus-color:var(--link-active-color);--pagination-focus-bg:var(--tertiary-bg);--pagination-focus-box-shadow:0 0 0 0.25rem rgba(84, 114, 255, 0.25);--pagination-active-color:var(--body-color);--pagination-active-bg:hsl(240, 98%, 17%);--pagination-active-border-color:hsl(240, 98%, 17%);--pagination-disabled-color:var(--gray-600);--pagination-disabled-bg:var(--secondary-bg);--pagination-disabled-border-color:var(--border-color);--badge-padding-x:0.65em;--badge-padding-y:0.35em;--badge-font-size:0.75em;--badge-font-weight:700;--badge-color:var(--body-color);--badge-border-radius:0.25rem;--alert-bg:transparent;--alert-padding-x:1rem;--alert-padding-y:1rem;--alert-margin-bottom:1rem;--alert-color:inherit;--alert-border-color:transparent;--alert-border:1px solid var(--alert-border-color);--alert-border-radius:0.25rem;--progress-height:1rem;--progress-font-size:0.75rem;--progress-bg:var(--secondary-bg);--progress-border-radius:0.25rem;--progress-box-shadow:inset 0 1px 2px rgba(var(--black-rgb), 0.3);--progress-bar-color:var(--body-color);--progress-bar-bg:hsl(240, 98%, 40%);--progress-bar-transition:width 0.6s ease;--list-group-color:var(--body-color);--list-group-bg:var(--secondary-bg);--list-group-border-color:rgba(var(--white-rgb), 0.125);--list-group-border-width:1px;--list-group-border-radius:0.25rem;--list-group-item-padding-x:1rem;--list-group-item-padding-y:0.5rem;--list-group-action-color:var(--gray-800);--list-group-action-active-color:var(--body-color);--list-group-action-active-bg:var(--tertiary-bg);--list-group-disabled-color:var(--gray-600);--list-group-disabled-bg:var(--secondary-bg);--list-group-active-color:var(--body-color);--list-group-active-bg:hsl(240, 98%, 17%);--list-group-active-border-color:hsl(240, 98%, 17%);--dropdown-zindex:1000;--dropdown-min-width:10rem;--dropdown-padding-x:0;--dropdown-padding-y:0.5rem;--dropdown-spacer:0.125rem;--dropdown-font-size:1rem;--dropdown-color:var(--body-color);--dropdown-bg:var(--secondary-bg);--dropdown-border-color:var(--border-color-translucent);--dropdown-border-radius:0.25rem;--dropdown-border-width:1px;--dropdown-inner-border-radius:calc(0.25rem - 1px);--dropdown-divider-bg:var(--border-color-translucent);--dropdown-divider-margin-y:0.5rem;--dropdown-box-shadow:0 0.5rem 1rem var(--shadow-color-medium);--dropdown-link-color:var(--body-color);--dropdown-link-active-color:var(--body-color);--dropdown-link-active-bg:hsl(240, 98%, 17%);--dropdown-link-disabled-color:var(--gray-600);--dropdown-item-padding-x:1rem;--dropdown-item-padding-y:0.25rem;--dropdown-header-color:var(--gray-600);--dropdown-header-padding-x:1rem;--dropdown-header-padding-y:0.5rem;--toast-zindex:1090;--toast-padding-x:0.75rem;--toast-padding-y:0.5rem;--toast-spacing:1em;--toast-max-width:350px;--toast-font-size:0.875rem;--toast-color: ;--toast-bg:rgba(21, 27, 34, 0.9);--toast-border-width:1px;--toast-border-color:var(--border-color-translucent);--toast-border-radius:0.25rem;--toast-box-shadow:0 0.5rem 1rem var(--shadow-color-medium);--toast-header-color:var(--gray-600);--toast-header-bg:rgba(21, 27, 34, 0.85);--toast-header-border-color:rgba(var(--white-rgb), var(--opacity-10));--modal-zindex:1050;--modal-width:500px;--modal-padding:1rem;--modal-margin:0.5rem;--modal-color: ;--modal-bg:var(--secondary-bg);--modal-border-color:var(--border-color-translucent);--modal-border-width:1px;--modal-border-radius:0.3rem;--modal-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.3);--modal-inner-border-radius:calc(0.3rem - 1px);--modal-header-padding-x:1rem;--modal-header-padding-y:1rem;--modal-header-padding:1rem 1rem;--modal-header-border-color:var(--border-color);--modal-header-border-width:1px;--modal-title-line-height:1.5;--modal-footer-gap:0.5rem;--modal-footer-bg: ;--modal-footer-border-color:var(--border-color);--modal-footer-border-width:1px;--tooltip-zindex:1070;--tooltip-max-width:200px;--tooltip-padding-x:0.5rem;--tooltip-padding-y:0.25rem;--tooltip-margin: ;--tooltip-font-size:0.875rem;--tooltip-color:var(--body-color);--tooltip-bg:hsl(0, 0%, 0%);--tooltip-border-radius:0.25rem;--tooltip-opacity:0.9;--tooltip-arrow-width:0.8rem;--tooltip-arrow-height:0.4rem;--popover-zindex:1060;--popover-max-width:276px;--popover-font-size:0.875rem;--popover-bg:var(--secondary-bg);--popover-border-width:1px;--popover-border-color:var(--border-color-translucent);--popover-border-radius:0.3rem;--popover-inner-border-radius:calc(0.3rem - 1px);--popover-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.4);--popover-header-padding-x:1rem;--popover-header-padding-y:0.5rem;--popover-header-font-size:1rem;--popover-header-color: ;--popover-header-bg:var(--tertiary-bg);--popover-body-padding-x:1rem;--popover-body-padding-y:1rem;--popover-body-color:var(--body-color);--popover-arrow-width:1rem;--popover-arrow-height:0.5rem;--popover-arrow-border:var(--popover-border-color);--spinner-width:2rem;--spinner-height:2rem;--spinner-vertical-align:-0.125em;--spinner-border-width:0.25em;--spinner-animation-speed:0.75s;--nav-tabs-border-width:1px;--nav-tabs-border-color:var(--border-color);--nav-tabs-border-radius:0.25rem;--nav-tabs-link-active-color:var(--body-color);--nav-tabs-link-active-bg:var(--secondary-bg);--nav-tabs-link-active-border-color:var(--border-color) var(--border-color) var(--secondary-bg);--nav-pills-border-radius:0.25rem;--nav-pills-link-active-color:var(--body-color);--nav-pills-link-active-bg:hsl(240, 98%, 17%);--table-color:var(--body-color);--table-bg:transparent;--table-border-color:var(--border-color);--table-accent-bg:transparent;--table-striped-color:var(--body-color);--table-striped-bg:rgba(var(--white-rgb), var(--opacity-5));--table-active-color:var(--body-color);--table-active-bg:rgba(var(--white-rgb), 0.1);--backdrop-zindex:1040;--backdrop-bg:hsl(0, 0%, 0%);--backdrop-opacity:0.5}.btn{--btn-padding-x:1rem;--btn-padding-y:0.6rem;--btn-font-family:inherit;--btn-font-size:1rem;--btn-font-weight:400;--btn-line-height:1.5;--btn-color:var(--white);--btn-bg:transparent;--btn-border-width:1px;--btn-border-color:transparent;--btn-border-radius:0.25rem;--btn-active-border-color:transparent;--btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--btn-disabled-opacity:0.65;--btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--btn-padding-y) var(--btn-padding-x);font-family:var(--btn-font-family);font-size:var(--btn-font-size);font-weight:var(--btn-font-weight);line-height:var(--btn-line-height);color:var(--btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:var(--btn-border-width) solid var(--btn-border-color);border-radius:var(--btn-border-radius);background-color:var(--btn-bg);-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;-o-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.btn-primary{--btn-color:hsl(0, 0%, 100%);--btn-bg:hsl(240, 98%, 17%);--btn-border-color:hsl(240, 98%, 17%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:#010149;--btn-hover-border-color:#010145;--btn-focus-shadow-rgb:84,114,255;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:#010145;--btn-active-border-color:#010141}.btn-secondary{--btn-color:var(--nav-text-color);--btn-bg:var(--nav-bg-color);--btn-border-color:#3a4250;--btn-hover-color:#fff;--btn-hover-bg:#1b2a55;--btn-hover-border-color:#162448;--btn-focus-shadow-rgb:84,114,255;--btn-active-color:#fff;--btn-active-bg:#162448;--btn-active-border-color:#12203f}.btn-success{--btn-color:hsl(0, 0%, 100%);--btn-bg:hsl(120, 35%, 45%);--btn-border-color:hsl(120, 35%, 45%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:hsl(120, 35%, 40%);--btn-hover-border-color:hsl(120, 35%, 38%);--btn-focus-shadow-rgb:96,180,96;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:hsl(120, 35%, 38%);--btn-active-border-color:hsl(120, 35%, 36%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(0, 0%, 100%);--btn-disabled-bg:hsl(120, 35%, 45%);--btn-disabled-border-color:hsl(120, 35%, 45%)}.btn-info{--btn-color:hsl(0, 0%, 100%);--btn-bg:hsl(207, 55%, 55%);--btn-border-color:hsl(207, 55%, 55%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:hsl(207, 55%, 50%);--btn-hover-border-color:hsl(207, 55%, 48%);--btn-focus-shadow-rgb:100,160,210);--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:hsl(207, 55%, 48%);--btn-active-border-color:hsl(207, 55%, 46%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(0, 0%, 100%);--btn-disabled-bg:hsl(207, 55%, 55%);--btn-disabled-border-color:hsl(207, 55%, 55%)}.btn-warning{--btn-color:hsl(0, 0%, 0%);--btn-bg:hsl(38, 100%, 50%);--btn-border-color:hsl(38, 100%, 50%);--btn-hover-color:hsl(0, 0%, 0%);--btn-hover-bg:hsl(38, 100%, 45%);--btn-hover-border-color:hsl(38, 100%, 43%);--btn-focus-shadow-rgb:220,170,40;--btn-active-color:hsl(0, 0%, 0%);--btn-active-bg:hsl(38, 100%, 43%);--btn-active-border-color:hsl(38, 100%, 41%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(0, 0%, 0%);--btn-disabled-bg:hsl(38, 100%, 50%);--btn-disabled-border-color:hsl(38, 100%, 50%)}.btn-danger{--btn-color:hsl(0, 0%, 100%);--btn-bg:hsl(3, 82%, 50%);--btn-border-color:hsl(3, 82%, 50%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:hsl(3, 82%, 45%);--btn-hover-border-color:hsl(3, 82%, 43%);--btn-focus-shadow-rgb:220,80,80;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:hsl(3, 82%, 43%);--btn-active-border-color:hsl(3, 82%, 41%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(0, 0%, 100%);--btn-disabled-bg:hsl(3, 82%, 50%);--btn-disabled-border-color:hsl(3, 82%, 50%)}.btn-light{--btn-color:hsl(0, 0%, 0%);--btn-bg:hsl(210, 17%, 85%);--btn-border-color:hsl(210, 17%, 85%);--btn-hover-color:hsl(0, 0%, 0%);--btn-hover-bg:hsl(210, 17%, 80%);--btn-hover-border-color:hsl(210, 17%, 78%);--btn-focus-shadow-rgb:200,205,210;--btn-active-color:hsl(0, 0%, 0%);--btn-active-bg:hsl(210, 17%, 78%);--btn-active-border-color:hsl(210, 17%, 76%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(0, 0%, 0%);--btn-disabled-bg:hsl(210, 17%, 85%);--btn-disabled-border-color:hsl(210, 17%, 85%)}.btn-dark{--btn-color:hsl(0, 0%, 100%);--btn-bg:hsl(210, 10%, 20%);--btn-border-color:hsl(210, 10%, 20%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:hsl(210, 10%, 18%);--btn-hover-border-color:hsl(210, 10%, 16%);--btn-focus-shadow-rgb:60,65,70;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:hsl(210, 10%, 16%);--btn-active-border-color:hsl(210, 10%, 14%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(0, 0%, 100%);--btn-disabled-bg:hsl(210, 10%, 20%);--btn-disabled-border-color:hsl(210, 10%, 20%)}.btn-outline-primary{--btn-color:hsl(240, 98%, 40%);--btn-border-color:hsl(240, 98%, 40%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:hsl(240, 98%, 40%);--btn-hover-border-color:hsl(240, 98%, 40%);--btn-focus-shadow-rgb:80,80,180;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:hsl(240, 98%, 40%);--btn-active-border-color:hsl(240, 98%, 40%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(240, 98%, 40%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(240, 98%, 40%);--gradient:none}.btn-outline-secondary{--btn-color:hsl(210, 20%, 60%);--btn-border-color:hsl(210, 20%, 60%);--btn-hover-color:hsl(0, 0%, 0%);--btn-hover-bg:hsl(210, 20%, 60%);--btn-hover-border-color:hsl(210, 20%, 60%);--btn-focus-shadow-rgb:120,140,160;--btn-active-color:hsl(0, 0%, 0%);--btn-active-bg:hsl(210, 20%, 60%);--btn-active-border-color:hsl(210, 20%, 60%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(210, 20%, 60%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(210, 20%, 60%);--gradient:none}.btn-outline-success{--btn-color:hsl(120, 35%, 55%);--btn-border-color:hsl(120, 35%, 55%);--btn-hover-color:hsl(0, 0%, 0%);--btn-hover-bg:hsl(120, 35%, 55%);--btn-hover-border-color:hsl(120, 35%, 55%);--btn-focus-shadow-rgb:100,190,100;--btn-active-color:hsl(0, 0%, 0%);--btn-active-bg:hsl(120, 35%, 55%);--btn-active-border-color:hsl(120, 35%, 55%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(120, 35%, 55%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(120, 35%, 55%);--gradient:none}.btn-outline-info{--btn-color:hsl(207, 55%, 65%);--btn-border-color:hsl(207, 55%, 65%);--btn-hover-color:hsl(0, 0%, 0%);--btn-hover-bg:hsl(207, 55%, 65%);--btn-hover-border-color:hsl(207, 55%, 65%);--btn-focus-shadow-rgb:110,170,220;--btn-active-color:hsl(0, 0%, 0%);--btn-active-bg:hsl(207, 55%, 65%);--btn-active-border-color:hsl(207, 55%, 65%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(207, 55%, 65%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(207, 55%, 65%);--gradient:none}.btn-outline-warning{--btn-color:hsl(38, 100%, 60%);--btn-border-color:hsl(38, 100%, 60%);--btn-hover-color:hsl(0, 0%, 0%);--btn-hover-bg:hsl(38, 100%, 60%);--btn-hover-border-color:hsl(38, 100%, 60%);--btn-focus-shadow-rgb:240,190,70;--btn-active-color:hsl(0, 0%, 0%);--btn-active-bg:hsl(38, 100%, 60%);--btn-active-border-color:hsl(38, 100%, 60%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(38, 100%, 60%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(38, 100%, 60%);--gradient:none}.btn-outline-danger{--btn-color:hsl(3, 82%, 60%);--btn-border-color:hsl(3, 82%, 60%);--btn-hover-color:hsl(0, 0%, 0%);--btn-hover-bg:hsl(3, 82%, 60%);--btn-hover-border-color:hsl(3, 82%, 60%);--btn-focus-shadow-rgb:240,100,100;--btn-active-color:hsl(0, 0%, 0%);--btn-active-bg:hsl(3, 82%, 60%);--btn-active-border-color:hsl(3, 82%, 60%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(3, 82%, 60%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(3, 82%, 60%);--gradient:none}.btn-outline-light{--btn-color:#e6ebf1;--btn-border-color:#e6ebf1;--btn-hover-color:#111;--btn-hover-bg:#e6ebf1;--btn-hover-border-color:#e6ebf1;--btn-active-color:#111;--btn-active-bg:#d7dce2;--btn-active-border-color:#d7dce2;--gradient:none}.btn-outline-dark{--btn-color:hsl(210, 10%, 30%);--btn-border-color:hsl(210, 10%, 30%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:hsl(210, 10%, 30%);--btn-hover-border-color:hsl(210, 10%, 30%);--btn-focus-shadow-rgb:70,75,80;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:hsl(210, 10%, 30%);--btn-active-border-color:hsl(210, 10%, 30%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(210, 10%, 30%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(210, 10%, 30%);--gradient:none}.btn-link{--btn-font-weight:400;--btn-color:var(--color-link);--btn-bg:transparent;--btn-border-color:transparent;--btn-hover-color:var(--link-hover-color);--btn-hover-border-color:transparent;--btn-active-color:var(--link-hover-color);--btn-active-border-color:transparent;--btn-disabled-color:#6d7781;--btn-disabled-border-color:transparent;--btn-box-shadow:none;--btn-focus-shadow-rgb:84,114,255;text-decoration:underline}
\ No newline at end of file
diff --git a/src/media/css/theme/index.html b/src/media/css/theme/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/media/css/theme/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/media/css/theme/light.standard.css b/src/media/css/theme/light.standard.css
new file mode 100644
index 0000000..2f9a224
--- /dev/null
+++ b/src/media/css/theme/light.standard.css
@@ -0,0 +1,1219 @@
+@charset "UTF-8";
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+
+/* -----------------------------------------------
+ * LIGHT THEME
+ * --------------------------------------------- */
+
+:root[data-bs-theme="light"] {
+color-scheme: light;
+
+
+/* ===== BRAND & THEME COLORS ===== */
+--color-primary: #112855;
+--accent-color-primary: #3f8ff0;
+--accent-color-secondary: #6fb3ff;
+
+
+/* ===== TYPOGRAPHY & BODY ===== */
+--font-sans-serif: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+--font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+--body-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+--body-font-size: 1rem;
+--body-font-weight: 400;
+--body-line-height: 1.5;
+--body-color: #22262a;
+--body-color-rgb: 34, 38, 42;
+--body-bg: #fff;
+--body-bg-rgb: 255, 255, 255;
+--heading-color: inherit;
+--emphasis-color: #000;
+--emphasis-color-rgb: 0, 0, 0;
+--secondary-color: #22262abf;
+--secondary-color-rgb: 34, 38, 42;
+--tertiary-color: #22262a80;
+--tertiary-color-rgb: 34, 38, 42;
+--muted-color: #6d757e;
+--code-color: black;
+--code-color-ink: var(--code-color, #e93f8e);
+--code-bg-color: lightgreen;
+--highlight-color: #22262a;
+--highlight-bg: #fbeea8;
+
+
+/* ===== STANDARD COLORS ===== */
+--blue: #010156;
+--indigo: #6812f3;
+--purple: #6f42c2;
+--pink: #e93f8e;
+--red: #a51f18;
+--orange: #fd7e17;
+--yellow: #ad6200;
+--green: #448344;
+--teal: #5abfdd;
+--cyan: #30638d;
+--black: #000;
+--white: #fff;
+
+
+/* ===== GRAY SCALE ===== */
+--gray-100: #f9fafb;
+--gray-200: #eaedf0;
+--gray-300: #dfe3e7;
+--gray-400: #ced4da;
+--gray-500: #adb5bd;
+--gray-600: #6d757e;
+--gray-700: #484f56;
+--gray-800: #353b41;
+--gray-900: #22262a;
+--white-rgb: 255, 255, 255;
+--black-rgb: 0, 0, 0;
+
+
+/* ===== OPACITY UTILITIES ===== */
+--opacity-0: 0;
+--opacity-5: 0.05;
+--opacity-10: 0.1;
+--opacity-15: 0.15;
+--opacity-20: 0.2;
+--opacity-25: 0.25;
+--opacity-30: 0.3;
+--opacity-50: 0.5;
+--opacity-75: 0.75;
+--opacity-100: 1;
+
+
+/* ===== LAYOUT & SPACING ===== */
+--padding-x: 0.15rem;
+--padding-y: 0.15rem;
+--bg-opacity: 1;
+--nav-toggle-size: 3rem;
+--gradient: linear-gradient(180deg, #ffffff26, #fff0);
+--secondary-bg: #eaedf0;
+--secondary-bg-rgb: 234, 237, 240;
+--tertiary-bg: #f9fafb;
+--tertiary-bg-rgb: 249, 250, 251;
+--hr-color: var(--border-color, #dfe3e7);
+--border-color-soft: var(--border-color, #dfe3e7);
+--kbd-bg: var(--secondary-bg, #eaedf0);
+--kbd-ink: var(--body-bg, #fff);
+--toc-bg: var(--secondary-bg, #eaedf0);
+--toc-ink: var(--color-primary, #112855);
+--selection-bg: var(--highlight-bg, #fbeea8);
+--selection-ink: var(--body-color, #22262a);
+--border: 5px;
+
+
+/* ===== BREAKPOINTS ===== */
+--bp-xs: 0;
+--bp-sm: 576px;
+--bp-md: 768px;
+--bp-lg: 992px;
+--bp-xl: 1200px;
+
+
+/* ===== BORDERS ===== */
+--border-width: 1px;
+--border-style: solid;
+--border-color: #dfe3e7;
+--border-color-translucent: #0000002d;
+--border-radius: .25rem;
+--border-radius-sm: .2rem;
+--border-radius-lg: .3rem;
+--border-radius-xl: .3rem;
+--border-radius-xxl: 2rem;
+--border-radius-2xl: var(--border-radius-xxl)*2;
+--border-radius-pill: 50rem;
+
+
+/* ===== SHADOWS ===== */
+--box-shadow: 0 .5rem 1rem #00000026;
+--box-shadow-sm: 0 .125rem .25rem #00000013;
+--box-shadow-lg: 0 1rem 3rem #0000002d;
+--box-shadow-inset: inset 0 1px 2px #00000013;
+
+
+/* ===== COMMON SHADOW COLORS ===== */
+--shadow-color-light: rgba(var(--black-rgb), var(--opacity-15));
+--shadow-color-medium: rgba(var(--black-rgb), var(--opacity-25));
+--shadow-color-dark: rgba(var(--black-rgb), var(--opacity-30));
+--border-color-translucent: rgba(var(--black-rgb), var(--opacity-10));
+--highlight-translucent: rgba(var(--white-rgb), var(--opacity-15));
+
+
+/* ===== NAVIGATION ===== */
+--mainmenu-nav-link-color: white;
+--nav-text-color: white;
+--nav-bg-color: var(--color-link);
+
+
+/* ===== NAVBAR ===== */
+--navbar-padding-x: 1rem;
+--navbar-padding-y: 0.5rem;
+--navbar-color: var(--nav-text-color);
+--navbar-active-color: var(--mainmenu-nav-link-color);
+--navbar-disabled-color: #6c757d;
+--navbar-brand-padding-y: 0.3125rem;
+--navbar-brand-margin-end: 1rem;
+--navbar-brand-font-size: 1.25rem;
+--navbar-brand-color: var(--nav-text-color);
+--navbar-brand-active-color: var(--mainmenu-nav-link-color);
+--navbar-nav-link-padding-x: 0.5rem;
+--navbar-toggler-padding-y: 0.25rem;
+--navbar-toggler-padding-x: 0.75rem;
+--navbar-toggler-font-size: 1.25rem;
+--navbar-toggler-border-color: rgba(0, 0, 0, 0.1);
+--navbar-toggler-border-radius: 0.25rem;
+--navbar-toggler-focus-width: 0.25rem;
+--navbar-toggler-transition: box-shadow 0.15s ease-in-out;
+--nav-link-padding-x: 1rem;
+--nav-link-padding-y: 0.5rem;
+--nav-link-font-weight: 400;
+--nav-link-color: var(--nav-text-color);
+--nav-link-active-color: var(--mainmenu-nav-link-color);
+--nav-link-disabled-color: #6c757d;
+
+
+/* ===== LINKS ===== */
+--color-link: #224FAA;
+--color-hover: var(--accent-color-primary);
+--link-color: #224faa;
+--link-color-rgb: 34, 79, 170;
+--link-decoration: underline;
+--link-hover-color: #424077;
+--link-hover-color-rgb: 66, 64, 119;
+--link-active-color: var(--link-color);
+
+
+/* ===== LINK UTILITY COLORS ===== */
+--link-primary-color: hsl(240, 98%, 17%);
+--link-primary-hover-color: #010145;
+--link-secondary-color: hsl(210, 7%, 46%);
+--link-secondary-hover-color: #575e65;
+--link-success-color: hsl(120, 32%, 39%);
+--link-success-hover-color: #366936;
+--link-info-color: hsl(207, 49%, 37%);
+--link-info-hover-color: #264f71;
+--link-warning-color: hsl(34, 100%, 34%);
+--link-warning-hover-color: #8a4e00;
+--link-danger-color: hsl(3, 75%, 37%);
+--link-danger-hover-color: #841913;
+--link-light-color: hsl(210, 17%, 98%);
+--link-light-hover-color: #fafbfc;
+--link-dark-color: hsl(210, 10%, 23%);
+--link-dark-hover-color: #2a2f34;
+
+
+/* ===== HEADER BACKGROUND ===== */
+--header-background-image: url('../../../../../../media/templates/site/mokoonyx/images/bg.svg');
+--header-background-attachment: fixed;
+--header-background-repeat: repeat;
+--header-background-size: auto;
+
+
+/* ===== CONTAINER BACKGROUNDS ===== */
+/* Below Topbar Container */
+--container-below-topbar-bg-image: none;
+--container-below-topbar-bg-color: transparent;
+--container-below-topbar-bg-position: auto;
+--container-below-topbar-bg-attachment: fixed;
+--container-below-topbar-bg-repeat: repeat;
+--container-below-topbar-bg-size: auto;
+--container-below-topbar-border: none;
+--container-below-topbar-border-radius: 0;
+
+/* Top A Container */
+--container-top-a-bg-image: none;
+--container-top-a-bg-color: transparent;
+--container-top-a-bg-position: auto;
+--container-top-a-bg-attachment: fixed;
+--container-top-a-bg-repeat: repeat;
+--container-top-a-bg-size: auto;
+--container-top-a-border: none;
+--container-top-a-border-radius: 0;
+
+/* Top B Container */
+--container-top-b-bg-image: none;
+--container-top-b-bg-color: transparent;
+--container-top-b-bg-position: auto;
+--container-top-b-bg-attachment: fixed;
+--container-top-b-bg-repeat: repeat;
+--container-top-b-bg-size: auto;
+--container-top-b-border: none;
+--container-top-b-border-radius: 0;
+
+/* TOC Container */
+--container-toc-bg: var(--mainmenu-nav-link-color);
+--container-toc-color: var(--color-primary);
+
+/* Sidebar Container */
+--container-sidebar-bg-image: none;
+--container-sidebar-bg-color: transparent;
+--container-sidebar-bg-position: auto;
+--container-sidebar-bg-attachment: scroll;
+--container-sidebar-bg-repeat: repeat;
+--container-sidebar-bg-size: auto;
+--container-sidebar-border: none;
+--container-sidebar-border-radius: 0;
+
+/* Bottom A Container */
+--container-bottom-a-bg-image: none;
+--container-bottom-a-bg-color: transparent;
+--container-bottom-a-bg-position: auto;
+--container-bottom-a-bg-attachment: fixed;
+--container-bottom-a-bg-repeat: repeat;
+--container-bottom-a-bg-size: auto;
+--container-bottom-a-border: none;
+--container-bottom-a-border-radius: 0;
+
+/* Bottom B Container */
+--container-bottom-b-bg-image: none;
+--container-bottom-b-bg-color: transparent;
+--container-bottom-b-bg-position: auto;
+--container-bottom-b-bg-attachment: fixed;
+--container-bottom-b-bg-repeat: repeat;
+--container-bottom-b-bg-size: auto;
+--container-bottom-b-border: none;
+--container-bottom-b-border-radius: 0;
+
+
+/* ===== FOCUS & FORMS ===== */
+--focus-ring-width: .25rem;
+--focus-ring-opacity: .25;
+--focus-ring-color: #01015640;
+--input-color: hsl(210, 11%, 15%);
+--input-bg: hsl(210, 20%, 98%);
+--input-border-color: hsl(210, 14%, 83%);
+--input-focus-border-color: #8894aa;
+--input-focus-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+--input-placeholder-color: hsl(210, 7%, 46%);
+--input-disabled-bg: hsl(210, 16%, 93%);
+--input-disabled-border-color: hsl(210, 14%, 83%);
+--input-file-button-active-bg: #dee1e4;
+--form-range-thumb-active-bg: #b8bfcc;
+--form-valid-color: #448344;
+--form-valid-border-color: #448344;
+--form-invalid-color: #a51f18;
+--form-invalid-border-color: #a51f18;
+
+
+/* ===== BUTTONS ===== */
+--btn-border-radius: var(--border-radius);
+--btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
+
+
+/* ===== ACCORDION ===== */
+--accordion-color: hsl(210, 11%, 15%);
+--accordion-bg: var(--body-bg);
+--accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;
+--accordion-border-color: var(--border-color);
+--accordion-border-width: 1px;
+--accordion-border-radius: 0.25rem;
+--accordion-inner-border-radius: calc(0.25rem - 1px);
+--accordion-btn-padding-x: 1.25rem;
+--accordion-btn-padding-y: 1rem;
+--accordion-btn-color: hsl(210, 11%, 15%);
+--accordion-btn-bg: var(--accordion-bg);
+--accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='hsl%28210, 11%25, 15%25%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+--accordion-btn-icon-width: 1.25rem;
+--accordion-btn-icon-transform: rotate(-180deg);
+--accordion-btn-icon-transition: transform 0.2s ease-in-out;
+--accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230f244d'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+--accordion-btn-focus-border-color: var(--input-focus-border-color);
+--accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+--accordion-body-padding-x: 1.25rem;
+--accordion-body-padding-y: 1rem;
+--accordion-active-color: #0f244d;
+--accordion-active-bg: #e7eaee;
+
+
+/* ===== ALERT ===== */
+--alert-bg: transparent;
+--alert-padding-x: 1rem;
+--alert-padding-y: 1rem;
+--alert-margin-bottom: 1rem;
+--alert-color: #000;
+--alert-border-color: transparent;
+--alert-border: 1px solid var(--alert-border-color);
+--alert-border-radius: 0.25rem;
+
+
+/* ===== ALERT LINK COLORS ===== */
+--alert-primary-link-color: #01012a;
+--alert-secondary-link-color: #34383d;
+--alert-success-link-color: #213f21;
+--alert-info-link-color: #172f44;
+--alert-warning-link-color: #532f00;
+--alert-danger-link-color: #4f0f0b;
+--alert-light-link-color: #505050;
+--alert-dark-link-color: #1a1c1f;
+
+
+/* ===== BACKDROP ===== */
+--backdrop-zindex: 1040;
+--backdrop-bg: hsl(0, 0%, 0%);
+--backdrop-opacity: 0.5;
+
+
+/* ===== BADGE ===== */
+--badge-padding-x: 0.65em;
+--badge-padding-y: 0.35em;
+--badge-font-size: 0.75em;
+--badge-font-weight: 700;
+--badge-color: var(--body-bg);
+--badge-border-radius: 0.25rem;
+
+
+/* ===== BREADCRUMB ===== */
+--breadcrumb-padding-x: 0;
+--breadcrumb-padding-y: 0;
+--breadcrumb-margin-bottom: 1rem;
+--breadcrumb-bg: ;
+--breadcrumb-border-radius: ;
+--breadcrumb-divider-color: hsl(210, 7%, 46%);
+--breadcrumb-item-padding-x: 0.5rem;
+--breadcrumb-item-active-color: var(--link-color);
+
+
+/* ===== CARDS ===== */
+--card-spacer-y: 1rem;
+--card-spacer-x: 1rem;
+--card-title-spacer-y: 0.5rem;
+--card-border-width: 1px;
+--card-border-color: var(--border-color);
+--card-border-radius: var(--border-radius);
+--card-box-shadow: none;
+--card-inner-border-radius: calc(var(--border-radius) - 1px);
+--card-cap-padding-y: 0.5rem;
+--card-cap-padding-x: 1rem;
+--card-cap-bg: rgba(0, 0, 0, 0.03);
+--card-cap-color: var(--body-color);
+--card-height: auto;
+--card-color: var(--body-color);
+--card-bg: var(--body-bg);
+--card-img-overlay-padding: 1rem;
+--card-group-margin: 0.75rem;
+
+
+/* ===== DROPDOWN ===== */
+--dropdown-zindex: 1000;
+--dropdown-min-width: 10rem;
+--dropdown-padding-x: 0;
+--dropdown-padding-y: 0.5rem;
+--dropdown-spacer: 0.125rem;
+--dropdown-font-size: 1rem;
+--dropdown-color: hsl(210, 11%, 15%);
+--dropdown-bg: var(--body-bg);
+--dropdown-border-color: var(--border-color-translucent);
+--dropdown-border-radius: 0.25rem;
+--dropdown-border-width: 1px;
+--dropdown-inner-border-radius: calc(0.25rem - 1px);
+--dropdown-divider-bg: var(--border-color-translucent);
+--dropdown-divider-margin-y: 0.5rem;
+--dropdown-box-shadow: 0 0.5rem 1rem var(--shadow-color-light);
+--dropdown-link-color: hsl(210, 11%, 15%);
+--dropdown-link-active-color: var(--body-bg);
+--dropdown-link-active-bg: hsl(240, 98%, 17%);
+--dropdown-link-disabled-color: hsl(210, 11%, 71%);
+--dropdown-item-padding-x: 1rem;
+--dropdown-item-padding-y: 0.25rem;
+--dropdown-header-color: hsl(210, 7%, 46%);
+--dropdown-header-padding-x: 1rem;
+--dropdown-header-padding-y: 0.5rem;
+
+
+/* ===== LIST GROUP ===== */
+--list-group-color: hsl(210, 11%, 15%);
+--list-group-bg: var(--body-bg);
+--list-group-border-color: rgba(var(--black-rgb), 0.125);
+--list-group-border-width: 1px;
+--list-group-border-radius: 0.25rem;
+--list-group-item-padding-x: 1rem;
+--list-group-item-padding-y: 0.5rem;
+--list-group-action-color: hsl(210, 9%, 31%);
+--list-group-action-active-color: hsl(210, 11%, 15%);
+--list-group-action-active-bg: hsl(210, 16%, 93%);
+--list-group-disabled-color: hsl(210, 7%, 46%);
+--list-group-disabled-bg: var(--body-bg);
+--list-group-active-color: var(--body-bg);
+--list-group-active-bg: hsl(240, 98%, 17%);
+--list-group-active-border-color: hsl(240, 98%, 17%);
+
+
+/* ===== LIST GROUP ITEM COLORS ===== */
+--list-group-item-primary-color: #010134;
+--list-group-item-primary-bg: #ccccdd;
+--list-group-item-primary-active-bg: #b8b8c7;
+--list-group-item-secondary-color: #41464c;
+--list-group-item-secondary-bg: #e2e3e5;
+--list-group-item-secondary-active-bg: #cbccce;
+--list-group-item-success-color: #294f29;
+--list-group-item-success-bg: #dae6da;
+--list-group-item-success-active-bg: #c4cfc4;
+--list-group-item-info-color: #1d3b55;
+--list-group-item-info-bg: #d6e0e8;
+--list-group-item-info-active-bg: #c1cad1;
+--list-group-item-warning-color: #683b00;
+--list-group-item-warning-bg: #efe0cc;
+--list-group-item-warning-active-bg: #d7cab8;
+--list-group-item-danger-color: #63130e;
+--list-group-item-danger-bg: #edd2d1;
+--list-group-item-danger-active-bg: #d5bdbc;
+--list-group-item-light-color: #646464;
+--list-group-item-light-bg: #fefefe;
+--list-group-item-light-active-bg: #e5e5e5;
+--list-group-item-dark-color: #202327;
+--list-group-item-dark-bg: #d7d8d9;
+--list-group-item-dark-active-bg: #c2c2c3;
+
+
+/* ===== MODAL ===== */
+--modal-zindex: 1050;
+--modal-width: 500px;
+--modal-padding: 1rem;
+--modal-margin: 0.5rem;
+--modal-color: ;
+--modal-bg: var(--body-bg);
+--modal-border-color: var(--border-color-translucent);
+--modal-border-width: 1px;
+--modal-border-radius: 0.3rem;
+--modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
+--modal-inner-border-radius: calc(0.3rem - 1px);
+--modal-header-padding-x: 1rem;
+--modal-header-padding-y: 1rem;
+--modal-header-padding: 1rem 1rem;
+--modal-header-border-color: var(--border-color);
+--modal-header-border-width: 1px;
+--modal-title-line-height: 1.5;
+--modal-footer-gap: 0.5rem;
+--modal-footer-bg: ;
+--modal-footer-border-color: var(--border-color);
+--modal-footer-border-width: 1px;
+
+
+/* ===== NAV TABS ===== */
+--nav-tabs-border-width: 1px;
+--nav-tabs-border-color: hsl(210, 14%, 89%);
+--nav-tabs-border-radius: 0.25rem;
+--nav-tabs-link-active-color: hsl(210, 9%, 31%);
+--nav-tabs-link-active-bg: var(--body-bg);
+--nav-tabs-link-active-border-color: hsl(210, 14%, 89%) hsl(210, 14%, 89%) var(--body-bg);
+
+
+/* ===== NAV PILLS ===== */
+--nav-pills-border-radius: 0.25rem;
+--nav-pills-link-active-color: var(--body-bg);
+--nav-pills-link-active-bg: hsl(240, 98%, 17%);
+
+
+/* ===== OFFCANVAS ===== */
+--offcanvas-zindex: 1045;
+--offcanvas-width: 400px;
+--offcanvas-height: 30vh;
+--offcanvas-padding-x: 1rem;
+--offcanvas-padding-y: 1rem;
+--offcanvas-color: var(--body-color);
+--offcanvas-bg: var(--body-bg);
+--offcanvas-border-width: 1px;
+--offcanvas-border-color: var(--border-color-translucent);
+--offcanvas-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
+
+
+/* ===== PAGINATION ===== */
+--pagination-padding-x: 0.75rem;
+--pagination-padding-y: 0.375rem;
+--pagination-font-size: 1rem;
+--pagination-color: var(--link-color);
+--pagination-bg: var(--body-bg);
+--pagination-border-width: 1px;
+--pagination-border-color: hsl(210, 14%, 89%);
+--pagination-border-radius: 0.25rem;
+--pagination-focus-color: var(--link-active-color);
+--pagination-focus-bg: hsl(210, 16%, 93%);
+--pagination-focus-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+--pagination-active-color: var(--body-bg);
+--pagination-active-bg: hsl(240, 98%, 17%);
+--pagination-active-border-color: hsl(240, 98%, 17%);
+--pagination-disabled-color: hsl(210, 7%, 46%);
+--pagination-disabled-bg: var(--body-bg);
+--pagination-disabled-border-color: hsl(210, 14%, 89%);
+
+
+/* ===== POPOVER ===== */
+--popover-zindex: 1060;
+--popover-max-width: 276px;
+--popover-font-size: 0.875rem;
+--popover-bg: var(--body-bg);
+--popover-border-width: 1px;
+--popover-border-color: var(--border-color-translucent);
+--popover-border-radius: 0.3rem;
+--popover-inner-border-radius: calc(0.3rem - 1px);
+--popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
+--popover-header-padding-x: 1rem;
+--popover-header-padding-y: 0.5rem;
+--popover-header-font-size: 1rem;
+--popover-header-color: ;
+--popover-header-bg: #f0f0f0;
+--popover-body-padding-x: 1rem;
+--popover-body-padding-y: 1rem;
+--popover-body-color: hsl(210, 11%, 15%);
+--popover-arrow-width: 1rem;
+--popover-arrow-height: 0.5rem;
+--popover-arrow-border: var(--popover-border-color);
+
+
+/* ===== PROGRESS ===== */
+--progress-height: 1rem;
+--progress-font-size: 0.75rem;
+--progress-bg: hsl(210, 16%, 93%);
+--progress-border-radius: 0.25rem;
+--progress-box-shadow: inset 0 1px 2px rgba(var(--black-rgb), 0.075);
+--progress-bar-color: var(--body-bg);
+--progress-bar-bg: hsl(240, 98%, 17%);
+--progress-bar-transition: width 0.6s ease;
+
+
+/* ===== SPINNER ===== */
+--spinner-width: 2rem;
+--spinner-height: 2rem;
+--spinner-vertical-align: -0.125em;
+--spinner-border-width: 0.25em;
+--spinner-animation-speed: 0.75s;
+
+
+/* ===== TABLE ===== */
+--table-color: var(--body-color);
+--table-bg: transparent;
+--table-border-color: var(--border-color);
+--table-accent-bg: transparent;
+--table-striped-color: var(--body-color);
+--table-striped-bg: rgba(var(--black-rgb), var(--opacity-5));
+--table-active-color: var(--body-color);
+--table-active-bg: rgba(var(--black-rgb), 0.075);
+
+
+/* ===== TOAST ===== */
+--toast-zindex: 1090;
+--toast-padding-x: 0.75rem;
+--toast-padding-y: 0.5rem;
+--toast-spacing: 1em;
+--toast-max-width: 350px;
+--toast-font-size: 0.875rem;
+--toast-color: ;
+--toast-bg: rgba(255, 255, 255, 0.85);
+--toast-border-width: 1px;
+--toast-border-color: var(--border-color-translucent);
+--toast-border-radius: 0.25rem;
+--toast-box-shadow: 0 0.5rem 1rem var(--shadow-color-light);
+--toast-header-color: hsl(210, 7%, 46%);
+--toast-header-bg: rgba(var(--white-rgb), 0.85);
+--toast-header-border-color: rgba(var(--black-rgb), var(--opacity-5));
+
+
+/* ===== TOOLTIP ===== */
+--tooltip-zindex: 1070;
+--tooltip-max-width: 200px;
+--tooltip-padding-x: 0.5rem;
+--tooltip-padding-y: 0.25rem;
+--tooltip-margin: ;
+--tooltip-font-size: 0.875rem;
+--tooltip-color: var(--body-bg);
+--tooltip-bg: hsl(0, 0%, 0%);
+--tooltip-border-radius: 0.25rem;
+--tooltip-opacity: 0.9;
+--tooltip-arrow-width: 0.8rem;
+--tooltip-arrow-height: 0.4rem;
+
+
+/* ===== BOOTSTRAP PALETTE ===== */
+--primary: #010156;
+--secondary: #6d757e;
+--success: #448344;
+--info: #30638d;
+--warning: #ad6200;
+--danger: #a51f18;
+--light: #f9fafb;
+--dark: #353b41;
+--primary-rgb: 1, 1, 86;
+--secondary-rgb: 109, 117, 126;
+--success-rgb: 68, 131, 68;
+--info-rgb: 48, 99, 141;
+--warning-rgb: 173, 98, 0;
+--danger-rgb: 165, 31, 24;
+--light-rgb: 249, 250, 251;
+--dark-rgb: 53, 59, 65;
+--primary-text-emphasis: #002;
+--secondary-text-emphasis: #2c2f32;
+--success-text-emphasis: #1b351b;
+--info-text-emphasis: #132838;
+--warning-text-emphasis: #452700;
+--danger-text-emphasis: #420c09;
+--light-text-emphasis: #484f56;
+--dark-text-emphasis: #484f56;
+--primary-bg-subtle: #ccd;
+--secondary-bg-subtle: #e2e3e5;
+--success-bg-subtle: #dae6da;
+--info-bg-subtle: #d6e0e8;
+--warning-bg-subtle: #efe0cc;
+--danger-bg-subtle: #edd2d1;
+--light-bg-subtle: #fcfcfd;
+--dark-bg-subtle: #ced4da;
+--primary-border-subtle: #99b;
+--secondary-border-subtle: #c5c8cb;
+--success-border-subtle: #b4ceb4;
+--info-border-subtle: #acc1d1;
+--warning-border-subtle: #dec099;
+--danger-border-subtle: #dba5a2;
+--light-border-subtle: #eaedf0;
+--dark-border-subtle: #adb5bd;
+
+
+/* ===== HERO / BANNER OVERLAY ===== */
+--hero-height: 70vh;
+--hero-color: var(--body-color);
+--hero-bg-repeat: no-repeat;
+--hero-bg-attachment: fixed;
+--hero-bg-position: top center;
+--hero-bg-size: cover;
+--hero-border-bottom: solid var(--accent-color-secondary);
+--hero-overlay-bg: hsla(0, 0%, 0%, 0.1);
+--hero-overlay-bg-position: center;
+--hero-overlay-bg-size: cover;
+--hero-overlay-padding: 1em;
+--hero-overlay-text-align: center;
+--hero-overlay-text-color: var(--body-color);
+
+
+/* ===== HERO VARIANTS ===== */
+/* Primary — sky blue, light overlay */
+--hero-primary-bg-color: var(--color-primary);
+--hero-primary-overlay: linear-gradient(rgba(163, 205, 226, .45), rgba(163, 205, 226, .45));
+--hero-primary-color: var(--color-primary);
+
+/* Secondary — navy, stronger overlay */
+--hero-secondary-bg-color: var(--color-primary);
+--hero-secondary-overlay: linear-gradient(rgba(17, 40, 85, .75), rgba(17, 40, 85, .75));
+--hero-secondary-color: #f1f5f9;
+
+
+/* ===== HERO CARD (inner .hero element) ===== */
+/* Default card — uses primary variant values */
+--hero-card-bg: var(--hero-primary-bg-color);
+--hero-card-color: white;
+--hero-card-overlay: var(--hero-primary-overlay);
+--hero-card-border-radius: .5rem;
+--hero-card-padding-x: 2rem;
+--hero-card-padding-y: 3rem;
+--hero-card-max-width: 800px;
+
+/* Alternative card — uses secondary variant values */
+--hero-alt-card-bg: var(--hero-secondary-bg-color);
+--hero-alt-card-color: var(--hero-secondary-color);
+--hero-alt-card-overlay: var(--hero-secondary-overlay);
+--hero-alt-card-border-radius: .5rem;
+--hero-alt-card-padding-x: 2rem;
+--hero-alt-card-padding-y: 3rem;
+--hero-alt-card-max-width: 600px;
+
+
+/* ===== BLOCK COLORS (top-a / top-b / bottom-a / bottom-b) ===== */
+--block-color-1: var(--color-primary);
+--block-text-1: var(--body-color);
+
+--block-color-2: var(--accent-color-primary);
+--block-text-2: #fff;
+
+--block-color-3: var(--warning, #eec234);
+--block-text-3: var(--body-color);
+
+--block-color-4: var(--success-bg-subtle, #eef7f0);
+--block-text-4: var(--body-color);
+
+
+/* ===== BLOCK COLOR OVERRIDES ===== */
+--block-highlight-bg: var(--accent-color-primary);
+--block-highlight-text: #fff;
+
+--block-cta-bg: var(--color-primary);
+--block-cta-text: #fff;
+
+--block-alert-bg: var(--danger, #a51f18);
+--block-alert-text: #fff;
+
+
+/* ===== FOOTER ===== */
+--footer-padding-top: 1rem;
+--footer-padding-bottom: 80px;
+--footer-grid-padding-y: 2.5rem;
+--footer-grid-padding-x: 0.5em;
+
+
+/* ===== THEME FAB ===== */
+--theme-fab-bg: var(--color-primary, #112855);
+--theme-fab-color: #fff;
+--theme-fab-btn-bg: rgba(255,255,255,.15);
+--theme-fab-border: rgba(255, 255, 255, 0.3);
+
+
+/* ===== OFFLINE PAGE ===== */
+--offline-card-bg: rgba(0, 0, 0, 0.55);
+
+
+/* ===== COMPONENT-SPECIFIC COLORS ===== */
+--mod-finder-link-hover: #e6e6e6;
+--form-legend-color: #495057;
+--border-gray: #b2bfcd;
+--subhead-color: #495057;
+--box-shadow-gray: #ddd;
+--btn-active-text-gray: #A0A0A0;
+--indicator-success-bg: var(--success);
+--item-list-color: #F5F5F5;
+--notification-badge-bg: var(--danger);
+--content-bg-gray: #DDD;
+--taba-btn-green: #7ac143;
+--taba-btn-blue: #5091cd;
+--taba-btn-red: #f44321;
+--taba-btn-gray: #AAA;
+--taba-msg-bg: #f5f5f5;
+--toc-link-color: #767676;
+--toc-link-active-color: #563d7c;
+--choices-disabled-bg: #eaeaea;
+--choices-input-bg: var(--white);
+--choices-border-light: #ddd;
+--choices-arrow-color: #333;
+--choices-inner-bg: #f9f9f9;
+--choices-focused-border: #b7b7b7;
+--choices-dropdown-bg: var(--white);
+--choices-item-bg: #00bcd4;
+--choices-item-border: #00a5bb;
+--choices-item-hover-bg: #00a5bb;
+--choices-item-hover-border: #008fa1;
+--choices-item-disabled-bg: #aaaaaa;
+--choices-item-disabled-border: #919191;
+--choices-item-highlighted: #f2f2f2;
+--choices-input-inner-bg: #f9f9f9;
+
+
+/* ===== VIRTUEMART (VM) ===== */
+/* VM Surfaces */
+--vm-surface: #ffffff;
+--vm-surface-2: #f8f9fa;
+--vm-text: var(--body-color);
+--vm-text-strong: #000000;
+--vm-text-muted: #6c757d;
+--vm-border: var(--border-color);
+--vm-price-color: var(--success);
+
+/* VM Layout and Density */
+--vm-container-max-width: 1200px;
+--vm-section-gap: 2rem;
+--vm-block-radius: var(--border-radius);
+--vm-block-shadow: var(--box-shadow-sm);
+
+/* VM Typography */
+--vm-category-title-size: 2rem;
+--vm-subcategory-title-size: 1.5rem;
+--vm-page-title-size: 1.75rem;
+--vm-products-type-title-size: 1.25rem;
+--vm-product-title-size: 1.125rem;
+--vm-product-title-weight: 500;
+--vm-products-type-title-weight: 600;
+--vm-price-size: 1.5rem;
+--vm-price-detail-size: 1.125rem;
+--vm-price-desc-size: 0.875rem;
+
+/* VM Controls */
+--vm-input-radius: var(--border-radius);
+--vm-input-shadow: var(--box-shadow-sm);
+--vm-qty-width: 80px;
+--vm-cart-dropdown-min-width: 300px;
+
+/* VM Alerts */
+--vm-alert-radius: var(--border-radius);
+--vm-alert-shadow: var(--box-shadow-sm);
+--vm-availability-bg: var(--success-bg-subtle);
+--vm-availability-text: var(--success);
+
+/* VM Buttons */
+--vm-btn-padding-x: 1rem;
+--vm-btn-padding-y: 0.5rem;
+--vm-btn-radius: var(--border-radius);
+--vm-btn-shadow: var(--box-shadow-sm);
+--vm-btn-primary-bg: var(--primary);
+--vm-btn-primary-text: #ffffff;
+--vm-btn-primary-border: var(--primary);
+--vm-btn-secondary-bg: var(--secondary);
+--vm-btn-secondary-text: #ffffff;
+--vm-btn-secondary-border: var(--secondary);
+
+/* VM Image Overlay Controls */
+--vm-image-overlay-gap-x: 0.5rem;
+--vm-image-overlay-gap-y: 0.5rem;
+--vm-image-overlay-raise: 0.25rem;
+--vm-image-overlay-btn-size: 2.5rem;
+--vm-image-overlay-btn-radius: 50%;
+--vm-image-overlay-btn-bg: rgba(255, 255, 255, 0.9);
+--vm-image-overlay-btn-bg-hover: rgba(255, 255, 255, 1);
+--vm-image-overlay-btn-border-color: rgba(0, 0, 0, 0.1);
+--vm-image-overlay-btn-border-width: 1px;
+--vm-image-overlay-btn-color: var(--body-color);
+--vm-image-overlay-btn-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+
+/* VM Vendor Menu */
+--vm-vendor-menu-bg: var(--body-bg);
+--vm-vendor-menu-border: var(--border-color);
+--vm-vendor-menu-radius: var(--border-radius);
+--vm-vendor-menu-shadow: var(--box-shadow-sm);
+--vm-vendor-menu-item-gap: 0.25rem;
+--vm-vendor-menu-item-padding-x: 1rem;
+--vm-vendor-menu-item-padding-y: 0.5rem;
+--vm-vendor-menu-pill-radius: 50rem;
+--vm-vendor-menu-link: var(--link-color);
+--vm-vendor-menu-link-hover: var(--link-hover-color);
+--vm-vendor-menu-link-active: var(--primary);
+--vm-vendor-menu-hover-bg: var(--secondary-bg);
+
+
+/* ===== GABLE ===== */
+--gab-blue: #0066cc;
+--gab-green: #28a745;
+--gab-red: #dc3545;
+--gab-orange: #fd7e14;
+--gab-gray1: #495057;
+--gab-gray2: #6c757d;
+--gab-gray3: #adb5bd;
+
+}
+
+.btn {
+--btn-padding-x: 1rem;
+--btn-padding-y: 0.6rem;
+--btn-font-family: inherit;
+--btn-font-size: 1rem;
+--btn-font-weight: 400;
+--btn-line-height: 1.5;
+--btn-color: hsl(210, 11%, 15%);
+--btn-bg: var(--body-bg);
+--btn-border-width: 1px;
+--btn-border-color: transparent;
+--btn-border-radius: 0.25rem;
+--btn-active-border-color: transparent;
+--btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
+--btn-disabled-opacity: 0.65;
+--btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb), .5);
+display: inline-block;
+padding: var(--btn-padding-y) var(--btn-padding-x);
+font-family: var(--btn-font-family);
+font-size: var(--btn-font-size);
+font-weight: var(--btn-font-weight);
+line-height: var(--btn-line-height);
+color: var(--btn-color);
+text-align: center;
+text-decoration: none;
+vertical-align: middle;
+cursor: pointer;
+-webkit-user-select: none;
+-moz-user-select: none;
+-ms-user-select: none;
+user-select: none;
+border: var(--btn-border-width) solid var(--btn-border-color);
+border-radius: var(--btn-border-radius);
+background-color: var(--btn-bg);
+-webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+-o-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+}
+
+.btn-primary {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(240, 98%, 17%);
+--btn-border-color: hsl(240, 98%, 17%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #010149;
+--btn-hover-border-color: #010145;
+--btn-focus-shadow-rgb: 39, 39, 111;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #010145;
+--btn-active-border-color: #010141;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(240, 98%, 17%);
+--btn-disabled-border-color: hsl(240, 98%, 17%);
+}
+
+.btn-secondary {
+--btn-color: var(--body-bg);
+--btn-bg: var(--nav-bg-color);
+--btn-border-color: hsl(210, 7%, 46%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #5d636b;
+--btn-hover-border-color: #575e65;
+--btn-focus-shadow-rgb: gray;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #575e65;
+--btn-active-border-color: #52585f;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(210, 7%, 46%);
+--btn-disabled-border-color: hsl(210, 7%, 46%);
+}
+
+.btn-success {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(120, 32%, 39%);
+--btn-border-color: hsl(120, 32%, 39%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #3a6f3a;
+--btn-hover-border-color: #366936;
+--btn-focus-shadow-rgb: 96, 150, 96;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #366936;
+--btn-active-border-color: #336233;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(120, 32%, 39%);
+--btn-disabled-border-color: hsl(120, 32%, 39%);
+}
+
+.btn-info {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(207, 49%, 37%);
+--btn-border-color: hsl(207, 49%, 37%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #295478;
+--btn-hover-border-color: #264f71;
+--btn-focus-shadow-rgb: 79, 122, 158;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #264f71;
+--btn-active-border-color: #244a6a;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(207, 49%, 37%);
+--btn-disabled-border-color: hsl(207, 49%, 37%);
+}
+
+.btn-warning {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(34, 100%, 34%);
+--btn-border-color: hsl(34, 100%, 34%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #935300;
+--btn-hover-border-color: #8a4e00;
+--btn-focus-shadow-rgb: 185, 122, 38;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #8a4e00;
+--btn-active-border-color: #824a00;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(34, 100%, 34%);
+--btn-disabled-border-color: hsl(34, 100%, 34%);
+}
+
+.btn-danger {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(3, 75%, 37%);
+--btn-border-color: hsl(3, 75%, 37%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #8c1a14;
+--btn-hover-border-color: #841913;
+--btn-focus-shadow-rgb: 179, 65, 59;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #841913;
+--btn-active-border-color: #7c1712;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(3, 75%, 37%);
+--btn-disabled-border-color: hsl(3, 75%, 37%);
+}
+
+.btn-light {
+--btn-color: hsl(0, 0%, 0%);
+--btn-bg: hsl(210, 17%, 98%);
+--btn-border-color: hsl(210, 17%, 98%);
+--btn-hover-color: hsl(0, 0%, 0%);
+--btn-hover-bg: #d4d5d5;
+--btn-hover-border-color: #c7c8c9;
+--btn-focus-shadow-rgb: 212, 213, 213;
+--btn-active-color: hsl(0, 0%, 0%);
+--btn-active-bg: #c7c8c9;
+--btn-active-border-color: #bbbcbc;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 0%);
+--btn-disabled-bg: hsl(210, 17%, 98%);
+--btn-disabled-border-color: hsl(210, 17%, 98%);
+}
+
+.btn-dark {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(210, 10%, 23%);
+--btn-border-color: hsl(210, 10%, 23%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #53585e;
+--btn-hover-border-color: #494f54;
+--btn-focus-shadow-rgb: 83, 88, 94;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #5d6267;
+--btn-active-border-color: #494f54;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(210, 10%, 23%);
+--btn-disabled-border-color: hsl(210, 10%, 23%);
+}
+
+.btn-outline-primary {
+--btn-color: hsl(240, 98%, 17%);
+--btn-border-color: hsl(240, 98%, 17%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(240, 98%, 17%);
+--btn-hover-border-color: hsl(240, 98%, 17%);
+--btn-focus-shadow-rgb: 1, 1, 86;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(240, 98%, 17%);
+--btn-active-border-color: hsl(240, 98%, 17%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(240, 98%, 17%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(240, 98%, 17%);
+--gradient: none;
+}
+
+.btn-outline-secondary {
+--btn-color: hsl(210, 7%, 46%);
+--btn-border-color: hsl(210, 7%, 46%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(210, 7%, 46%);
+--btn-hover-border-color: hsl(210, 7%, 46%);
+--btn-focus-shadow-rgb: 109, 117, 126;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(210, 7%, 46%);
+--btn-active-border-color: hsl(210, 7%, 46%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(210, 7%, 46%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(210, 7%, 46%);
+--gradient: none;
+}
+
+.btn-outline-success {
+--btn-color: hsl(120, 32%, 39%);
+--btn-border-color: hsl(120, 32%, 39%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(120, 32%, 39%);
+--btn-hover-border-color: hsl(120, 32%, 39%);
+--btn-focus-shadow-rgb: 68, 131, 68;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(120, 32%, 39%);
+--btn-active-border-color: hsl(120, 32%, 39%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(120, 32%, 39%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(120, 32%, 39%);
+--gradient: none;
+}
+
+.btn-outline-info {
+--btn-color: hsl(207, 49%, 37%);
+--btn-border-color: hsl(207, 49%, 37%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(207, 49%, 37%);
+--btn-hover-border-color: hsl(207, 49%, 37%);
+--btn-focus-shadow-rgb: 48, 99, 141;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(207, 49%, 37%);
+--btn-active-border-color: hsl(207, 49%, 37%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(207, 49%, 37%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(207, 49%, 37%);
+--gradient: none;
+}
+
+.btn-outline-warning {
+--btn-color: hsl(34, 100%, 34%);
+--btn-border-color: hsl(34, 100%, 34%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(34, 100%, 34%);
+--btn-hover-border-color: hsl(34, 100%, 34%);
+--btn-focus-shadow-rgb: 173, 98, 0;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(34, 100%, 34%);
+--btn-active-border-color: hsl(34, 100%, 34%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(34, 100%, 34%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(34, 100%, 34%);
+--gradient: none;
+}
+
+.btn-outline-danger {
+--btn-color: hsl(3, 75%, 37%);
+--btn-border-color: hsl(3, 75%, 37%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(3, 75%, 37%);
+--btn-hover-border-color: hsl(3, 75%, 37%);
+--btn-focus-shadow-rgb: 165, 31, 24;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(3, 75%, 37%);
+--btn-active-border-color: hsl(3, 75%, 37%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(3, 75%, 37%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(3, 75%, 37%);
+--gradient: none;
+}
+
+.btn-outline-light {
+--btn-color: hsl(210, 17%, 98%);
+--btn-border-color: hsl(210, 17%, 98%);
+--btn-hover-color: hsl(0, 0%, 0%);
+--btn-hover-bg: hsl(210, 17%, 98%);
+--btn-hover-border-color: hsl(210, 17%, 98%);
+--btn-focus-shadow-rgb: 249, 250, 251;
+--btn-active-color: hsl(0, 0%, 0%);
+--btn-active-bg: hsl(210, 17%, 98%);
+--btn-active-border-color: hsl(210, 17%, 98%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(210, 17%, 98%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(210, 17%, 98%);
+--gradient: none;
+}
+
+.btn-outline-dark {
+--btn-color: hsl(210, 10%, 23%);
+--btn-border-color: hsl(210, 10%, 23%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(210, 10%, 23%);
+--btn-hover-border-color: hsl(210, 10%, 23%);
+--btn-focus-shadow-rgb: 53, 59, 65;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(210, 10%, 23%);
+--btn-active-border-color: hsl(210, 10%, 23%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(210, 10%, 23%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(210, 10%, 23%);
+--gradient: none;
+}
+
+.btn-link {
+--btn-font-weight: 400;
+--btn-color: var(--link-color);
+--btn-bg: transparent;
+--btn-border-color: transparent;
+--btn-hover-color: var(--link-hover-color);
+--btn-hover-border-color: transparent;
+--btn-active-color: var(--link-hover-color);
+--btn-active-border-color: transparent;
+--btn-disabled-color: hsl(210, 7%, 46%);
+--btn-disabled-border-color: transparent;
+--btn-box-shadow: none;
+--btn-focus-shadow-rgb: 39, 39, 111;
+text-decoration: underline;
+}
diff --git a/src/media/css/theme/light.standard.min.css b/src/media/css/theme/light.standard.min.css
new file mode 100644
index 0000000..8fbcfac
--- /dev/null
+++ b/src/media/css/theme/light.standard.min.css
@@ -0,0 +1 @@
+@charset "UTF-8";:root[data-bs-theme=light]{color-scheme:light;--color-primary:#112855;--accent-color-primary:#3f8ff0;--accent-color-secondary:#3f8ff0;--mainmenu-nav-link-color:white;--nav-text-color:white;--nav-bg-color:var(--color-link);--color-link:#224FAA;--color-hover:var(--accent-color-primary);--link-color:#224faa;--link-color-rgb:34,79,170;--link-decoration:underline;--link-hover-color:#424077;--link-hover-color-rgb:66,64,119;--link-active-color:var(--link-color);--offcanvas-color:var(--body-color);--offcanvas-padding-x:1rem;--offcanvas-padding-y:1rem;--navbar-padding-x:1rem;--navbar-padding-y:0.5rem;--navbar-color:var(--nav-text-color);--navbar-active-color:var(--mainmenu-nav-link-color);--navbar-disabled-color:#6c757d;--navbar-brand-padding-y:0.3125rem;--navbar-brand-margin-end:1rem;--navbar-brand-font-size:1.25rem;--navbar-brand-color:var(--nav-text-color);--navbar-brand-active-color:var(--mainmenu-nav-link-color);--navbar-nav-link-padding-x:0.5rem;--navbar-toggler-padding-y:0.25rem;--navbar-toggler-padding-x:0.75rem;--navbar-toggler-font-size:1.25rem;--navbar-toggler-border-color:rgba(0, 0, 0, 0.1);--navbar-toggler-border-radius:0.25rem;--navbar-toggler-focus-width:0.25rem;--navbar-toggler-transition:box-shadow 0.15s ease-in-out;--nav-link-padding-x:1rem;--nav-link-padding-y:0.5rem;--nav-link-font-weight:400;--nav-link-color:var(--nav-text-color);--nav-link-active-color:var(--mainmenu-nav-link-color);--nav-link-disabled-color:#6c757d;--font-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--body-font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");--body-font-size:1rem;--body-font-weight:400;--body-line-height:1.5;--body-color:#22262a;--body-color-rgb:34,38,42;--body-bg:#fff;--body-bg-rgb:255,255,255;--heading-color:inherit;--emphasis-color:#000;--emphasis-color-rgb:0,0,0;--secondary-color:#22262abf;--secondary-color-rgb:34,38,42;--tertiary-color:#22262a80;--tertiary-color-rgb:34,38,42;--muted-color:#6d757e;--code-color:#e93f8e;--code-color-ink:var(--code-color, #e93f8e);--highlight-color:#22262a;--highlight-bg:#fbeea8;--padding-x:0.15rem;--padding-y:0.15rem;--bg-opacity:1;--nav-toggle-size:3rem;--gradient:linear-gradient(180deg, #ffffff26, #fff0);--secondary-bg:#eaedf0;--secondary-bg-rgb:234,237,240;--tertiary-bg:#f9fafb;--tertiary-bg-rgb:249,250,251;--hr-color:var(--border-color, #dfe3e7);--border-color-soft:var(--border-color, #dfe3e7);--kbd-bg:var(--secondary-bg, #eaedf0);--kbd-ink:var(--body-bg, #fff);--toc-bg:var(--secondary-bg, #eaedf0);--toc-ink:var(--color-primary, #112855);--selection-bg:var(--highlight-bg, #fbeea8);--selection-ink:var(--body-color, #22262a);--border:5px;--bp-xs:0;--bp-sm:576px;--bp-md:768px;--bp-lg:992px;--bp-xl:1200px;--primary:#010156;--secondary:#6d757e;--success:#448344;--info:#30638d;--warning:#ad6200;--danger:#a51f18;--light:#f9fafb;--dark:#353b41;--primary-rgb:1,1,86;--secondary-rgb:109,117,126;--success-rgb:68,131,68;--info-rgb:48,99,141;--warning-rgb:173,98,0;--danger-rgb:165,31,24;--light-rgb:249,250,251;--dark-rgb:53,59,65;--primary-text-emphasis:#002;--secondary-text-emphasis:#2c2f32;--success-text-emphasis:#1b351b;--info-text-emphasis:#132838;--warning-text-emphasis:#452700;--danger-text-emphasis:#420c09;--light-text-emphasis:#484f56;--dark-text-emphasis:#484f56;--primary-bg-subtle:#ccd;--secondary-bg-subtle:#e2e3e5;--success-bg-subtle:#dae6da;--info-bg-subtle:#d6e0e8;--warning-bg-subtle:#efe0cc;--danger-bg-subtle:#edd2d1;--light-bg-subtle:#fcfcfd;--dark-bg-subtle:#ced4da;--primary-border-subtle:#99b;--secondary-border-subtle:#c5c8cb;--success-border-subtle:#b4ceb4;--info-border-subtle:#acc1d1;--warning-border-subtle:#dec099;--danger-border-subtle:#dba5a2;--light-border-subtle:#eaedf0;--dark-border-subtle:#adb5bd;--alert-primary-link-color:#01012a;--alert-secondary-link-color:#34383d;--alert-success-link-color:#213f21;--alert-info-link-color:#172f44;--alert-warning-link-color:#532f00;--alert-danger-link-color:#4f0f0b;--alert-light-link-color:#505050;--alert-dark-link-color:#1a1c1f;--list-group-item-primary-color:#010134;--list-group-item-primary-bg:#ccccdd;--list-group-item-primary-active-bg:#b8b8c7;--list-group-item-secondary-color:#41464c;--list-group-item-secondary-bg:#e2e3e5;--list-group-item-secondary-active-bg:#cbccce;--list-group-item-success-color:#294f29;--list-group-item-success-bg:#dae6da;--list-group-item-success-active-bg:#c4cfc4;--list-group-item-info-color:#1d3b55;--list-group-item-info-bg:#d6e0e8;--list-group-item-info-active-bg:#c1cad1;--list-group-item-warning-color:#683b00;--list-group-item-warning-bg:#efe0cc;--list-group-item-warning-active-bg:#d7cab8;--list-group-item-danger-color:#63130e;--list-group-item-danger-bg:#edd2d1;--list-group-item-danger-active-bg:#d5bdbc;--list-group-item-light-color:#646464;--list-group-item-light-bg:#fefefe;--list-group-item-light-active-bg:#e5e5e5;--list-group-item-dark-color:#202327;--list-group-item-dark-bg:#d7d8d9;--list-group-item-dark-active-bg:#c2c2c3;--link-primary-color:hsl(240, 98%, 17%);--link-primary-hover-color:#010145;--link-secondary-color:hsl(210, 7%, 46%);--link-secondary-hover-color:#575e65;--link-success-color:hsl(120, 32%, 39%);--link-success-hover-color:#366936;--link-info-color:hsl(207, 49%, 37%);--link-info-hover-color:#264f71;--link-warning-color:hsl(34, 100%, 34%);--link-warning-hover-color:#8a4e00;--link-danger-color:hsl(3, 75%, 37%);--link-danger-hover-color:#841913;--link-light-color:hsl(210, 17%, 98%);--link-light-hover-color:#fafbfc;--link-dark-color:hsl(210, 10%, 23%);--link-dark-hover-color:#2a2f34;--mod-finder-link-hover:#e6e6e6;--form-legend-color:#495057;--border-gray:#b2bfcd;--subhead-color:#495057;--box-shadow-gray:#ddd;--btn-active-text-gray:#A0A0A0;--indicator-success-bg:var(--success);--item-list-color:#F5F5F5;--notification-badge-bg:var(--danger);--content-bg-gray:#DDD;--taba-btn-green:#7ac143;--taba-btn-blue:#5091cd;--taba-btn-red:#f44321;--taba-btn-gray:#AAA;--taba-msg-bg:#f5f5f5;--toc-link-color:#767676;--toc-link-active-color:#563d7c;--choices-disabled-bg:#eaeaea;--choices-input-bg:var(--white);--choices-border-light:#ddd;--choices-arrow-color:#333;--choices-inner-bg:#f9f9f9;--choices-focused-border:#b7b7b7;--choices-dropdown-bg:var(--white);--choices-item-bg:#00bcd4;--choices-item-border:#00a5bb;--choices-item-hover-bg:#00a5bb;--choices-item-hover-border:#008fa1;--choices-item-disabled-bg:#aaaaaa;--choices-item-disabled-border:#919191;--choices-item-highlighted:#f2f2f2;--choices-input-inner-bg:#f9f9f9;--blue:#010156;--indigo:#6812f3;--purple:#6f42c2;--pink:#e93f8e;--red:#a51f18;--orange:#fd7e17;--yellow:#ad6200;--green:#448344;--teal:#5abfdd;--cyan:#30638d;--black:#000;--white:#fff;--gray-100:#f9fafb;--gray-200:#eaedf0;--gray-300:#dfe3e7;--gray-400:#ced4da;--gray-500:#adb5bd;--gray-600:#6d757e;--gray-700:#484f56;--gray-800:#353b41;--gray-900:#22262a;--white-rgb:255,255,255;--black-rgb:0,0,0;--opacity-0:0;--opacity-5:0.05;--opacity-10:0.1;--opacity-15:0.15;--opacity-20:0.2;--opacity-25:0.25;--opacity-30:0.3;--opacity-50:0.5;--opacity-75:0.75;--opacity-100:1;--shadow-color-light:rgba(var(--black-rgb), var(--opacity-15));--shadow-color-medium:rgba(var(--black-rgb), var(--opacity-25));--shadow-color-dark:rgba(var(--black-rgb), var(--opacity-30));--border-color-translucent:rgba(var(--black-rgb), var(--opacity-10));--highlight-translucent:rgba(var(--white-rgb), var(--opacity-15));--header-background-image:url('../../../../../../media/templates/site/mokoonyx/images/bg.svg');--header-background-attachment:fixed;--header-background-repeat:repeat;--header-background-size:auto;--container-below-topbar-bg-image:none;--container-below-topbar-bg-color:transparent;--container-below-topbar-bg-position:auto;--container-below-topbar-bg-attachment:fixed;--container-below-topbar-bg-repeat:repeat;--container-below-topbar-bg-size:auto;--container-below-topbar-border:none;--container-below-topbar-border-radius:0;--container-top-a-bg-image:none;--container-top-a-bg-color:transparent;--container-top-a-bg-position:auto;--container-top-a-bg-attachment:fixed;--container-top-a-bg-repeat:repeat;--container-top-a-bg-size:auto;--container-top-a-border:none;--container-top-a-border-radius:0;--container-top-b-bg-image:none;--container-top-b-bg-color:transparent;--container-top-b-bg-position:auto;--container-top-b-bg-attachment:fixed;--container-top-b-bg-repeat:repeat;--container-top-b-bg-size:auto;--container-top-b-border:none;--container-top-b-border-radius:0;--container-toc-bg:var(--mainmenu-nav-link-color);--container-toc-color:var(--color-primary);--container-sidebar-bg-image:none;--container-sidebar-bg-color:transparent;--container-sidebar-bg-position:auto;--container-sidebar-bg-attachment:scroll;--container-sidebar-bg-repeat:repeat;--container-sidebar-bg-size:auto;--container-sidebar-border:none;--container-sidebar-border-radius:0;--container-bottom-a-bg-image:none;--container-bottom-a-bg-color:transparent;--container-bottom-a-bg-position:auto;--container-bottom-a-bg-attachment:fixed;--container-bottom-a-bg-repeat:repeat;--container-bottom-a-bg-size:auto;--container-bottom-a-border:none;--container-bottom-a-border-radius:0;--container-bottom-b-bg-image:none;--container-bottom-b-bg-color:transparent;--container-bottom-b-bg-position:auto;--container-bottom-b-bg-attachment:fixed;--container-bottom-b-bg-repeat:repeat;--container-bottom-b-bg-size:auto;--container-bottom-b-border:none;--container-bottom-b-border-radius:0;--border-width:1px;--border-style:solid;--border-color:#dfe3e7;--border-color-translucent:#0000002d;--border-radius:.25rem;--border-radius-sm:.2rem;--border-radius-lg:.3rem;--border-radius-xl:.3rem;--border-radius-xxl:2rem;--border-radius-2xl:var(--border-radius-xxl) *2;--border-radius-pill:50rem;--box-shadow:0 .5rem 1rem #00000026;--box-shadow-sm:0 .125rem .25rem #00000013;--box-shadow-lg:0 1rem 3rem #0000002d;--box-shadow-inset:inset 0 1px 2px #00000013;--focus-ring-width:.25rem;--focus-ring-opacity:.25;--focus-ring-color:#01015640;--input-color:hsl(210, 11%, 15%);--input-bg:hsl(210, 20%, 98%);--input-border-color:hsl(210, 14%, 83%);--input-focus-border-color:#8894aa;--input-focus-box-shadow:0 0 0 0.25rem rgba(1, 1, 86, 0.25);--input-placeholder-color:hsl(210, 7%, 46%);--input-disabled-bg:hsl(210, 16%, 93%);--input-disabled-border-color:hsl(210, 14%, 83%);--input-file-button-active-bg:#dee1e4;--form-range-thumb-active-bg:#b8bfcc;--form-valid-color:#448344;--form-valid-border-color:#448344;--form-invalid-color:#a51f18;--form-invalid-border-color:#a51f18;--btn-border-radius:var(--border-radius);--btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--card-spacer-y:1rem;--card-spacer-x:1rem;--card-title-spacer-y:0.5rem;--card-border-width:1px;--card-border-color:var(--border-color);--card-border-radius:var(--border-radius);--card-box-shadow:none;--card-inner-border-radius:calc(var(--border-radius) - 1px);--card-cap-padding-y:0.5rem;--card-cap-padding-x:1rem;--card-cap-bg:rgba(0, 0, 0, 0.03);--card-cap-color:var(--body-color);--card-height:auto;--card-color:var(--body-color);--card-bg:var(--body-bg);--card-img-overlay-padding:1rem;--card-group-margin:0.75rem;--vm-surface:#ffffff;--vm-surface-2:#f8f9fa;--vm-text:var(--body-color);--vm-text-strong:#000000;--vm-text-muted:#6c757d;--vm-border:var(--border-color);--vm-price-color:var(--success);--vm-container-max-width:1200px;--vm-section-gap:2rem;--vm-block-radius:var(--border-radius);--vm-block-shadow:var(--box-shadow-sm);--vm-category-title-size:2rem;--vm-subcategory-title-size:1.5rem;--vm-page-title-size:1.75rem;--vm-products-type-title-size:1.25rem;--vm-product-title-size:1.125rem;--vm-product-title-weight:500;--vm-products-type-title-weight:600;--vm-price-size:1.5rem;--vm-price-detail-size:1.125rem;--vm-price-desc-size:0.875rem;--vm-input-radius:var(--border-radius);--vm-input-shadow:var(--box-shadow-sm);--vm-qty-width:80px;--vm-cart-dropdown-min-width:300px;--vm-alert-radius:var(--border-radius);--vm-alert-shadow:var(--box-shadow-sm);--vm-availability-bg:var(--success-bg-subtle);--vm-availability-text:var(--success);--vm-btn-padding-x:1rem;--vm-btn-padding-y:0.5rem;--vm-btn-radius:var(--border-radius);--vm-btn-shadow:var(--box-shadow-sm);--vm-btn-primary-bg:var(--primary);--vm-btn-primary-text:#ffffff;--vm-btn-primary-border:var(--primary);--vm-btn-secondary-bg:var(--secondary);--vm-btn-secondary-text:#ffffff;--vm-btn-secondary-border:var(--secondary);--vm-image-overlay-gap-x:0.5rem;--vm-image-overlay-gap-y:0.5rem;--vm-image-overlay-raise:0.25rem;--vm-image-overlay-btn-size:2.5rem;--vm-image-overlay-btn-radius:50%;--vm-image-overlay-btn-bg:rgba(255, 255, 255, 0.9);--vm-image-overlay-btn-bg-hover:rgba(255, 255, 255, 1);--vm-image-overlay-btn-border-color:rgba(0, 0, 0, 0.1);--vm-image-overlay-btn-border-width:1px;--vm-image-overlay-btn-color:var(--body-color);--vm-image-overlay-btn-shadow:0 2px 4px rgba(0, 0, 0, 0.1);--vm-vendor-menu-bg:var(--body-bg);--vm-vendor-menu-border:var(--border-color);--vm-vendor-menu-radius:var(--border-radius);--vm-vendor-menu-shadow:var(--box-shadow-sm);--vm-vendor-menu-item-gap:0.25rem;--vm-vendor-menu-item-padding-x:1rem;--vm-vendor-menu-item-padding-y:0.5rem;--vm-vendor-menu-pill-radius:50rem;--vm-vendor-menu-link:var(--link-color);--vm-vendor-menu-link-hover:var(--link-hover-color);--vm-vendor-menu-link-active:var(--primary);--vm-vendor-menu-hover-bg:var(--secondary-bg);--gab-blue:#0066cc;--gab-green:#28a745;--gab-red:#dc3545;--gab-orange:#fd7e14;--gab-gray1:#495057;--gab-gray2:#6c757d;--gab-gray3:#adb5bd;--hero-height:70vh;--hero-color:var(--body-color);--hero-bg-repeat:no-repeat;--hero-bg-attachment:fixed;--hero-bg-position:top center;--hero-bg-size:cover;--hero-border-bottom:solid var(--accent-color-secondary);--hero-overlay-bg:hsla(0, 0%, 0%, 0.1);--hero-overlay-padding:1em;--hero-overlay-text-align:center;--hero-overlay-text-color:var(--body-color);--offcanvas-zindex:1045;--offcanvas-width:400px;--offcanvas-height:30vh;--offcanvas-padding-x:1rem;--offcanvas-padding-y:1rem;--offcanvas-color:var(--body-color);--offcanvas-bg:var(--body-bg);--offcanvas-border-width:1px;--offcanvas-border-color:var(--border-color-translucent);--offcanvas-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--accordion-color:hsl(210, 11%, 15%);--accordion-bg:var(--body-bg);--accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--accordion-border-color:var(--border-color);--accordion-border-width:1px;--accordion-border-radius:0.25rem;--accordion-inner-border-radius:calc(0.25rem - 1px);--accordion-btn-padding-x:1.25rem;--accordion-btn-padding-y:1rem;--accordion-btn-color:hsl(210, 11%, 15%);--accordion-btn-bg:var(--accordion-bg);--accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='hsl%28210, 11%25, 15%25%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--accordion-btn-icon-width:1.25rem;--accordion-btn-icon-transform:rotate(-180deg);--accordion-btn-icon-transition:transform 0.2s ease-in-out;--accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230f244d'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--accordion-btn-focus-border-color:var(--input-focus-border-color);--accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(1, 1, 86, 0.25);--accordion-body-padding-x:1.25rem;--accordion-body-padding-y:1rem;--accordion-active-color:#0f244d;--accordion-active-bg:#e7eaee;--breadcrumb-padding-x:0;--breadcrumb-padding-y:0;--breadcrumb-margin-bottom:1rem;--breadcrumb-bg: ;--breadcrumb-border-radius: ;--breadcrumb-divider-color:hsl(210, 7%, 46%);--breadcrumb-item-padding-x:0.5rem;--breadcrumb-item-active-color:var(--link-color);--pagination-padding-x:0.75rem;--pagination-padding-y:0.375rem;--pagination-font-size:1rem;--pagination-color:var(--link-color);--pagination-bg:var(--body-bg);--pagination-border-width:1px;--pagination-border-color:hsl(210, 14%, 89%);--pagination-border-radius:0.25rem;--pagination-focus-color:var(--link-active-color);--pagination-focus-bg:hsl(210, 16%, 93%);--pagination-focus-box-shadow:0 0 0 0.25rem rgba(1, 1, 86, 0.25);--pagination-active-color:var(--body-bg);--pagination-active-bg:hsl(240, 98%, 17%);--pagination-active-border-color:hsl(240, 98%, 17%);--pagination-disabled-color:hsl(210, 7%, 46%);--pagination-disabled-bg:var(--body-bg);--pagination-disabled-border-color:hsl(210, 14%, 89%);--badge-padding-x:0.65em;--badge-padding-y:0.35em;--badge-font-size:0.75em;--badge-font-weight:700;--badge-color:var(--body-bg);--badge-border-radius:0.25rem;--alert-bg:transparent;--alert-padding-x:1rem;--alert-padding-y:1rem;--alert-margin-bottom:1rem;--alert-color:inherit;--alert-border-color:transparent;--alert-border:1px solid var(--alert-border-color);--alert-border-radius:0.25rem;--progress-height:1rem;--progress-font-size:0.75rem;--progress-bg:hsl(210, 16%, 93%);--progress-border-radius:0.25rem;--progress-box-shadow:inset 0 1px 2px rgba(var(--black-rgb), 0.075);--progress-bar-color:var(--body-bg);--progress-bar-bg:hsl(240, 98%, 17%);--progress-bar-transition:width 0.6s ease;--list-group-color:hsl(210, 11%, 15%);--list-group-bg:var(--body-bg);--list-group-border-color:rgba(var(--black-rgb), 0.125);--list-group-border-width:1px;--list-group-border-radius:0.25rem;--list-group-item-padding-x:1rem;--list-group-item-padding-y:0.5rem;--list-group-action-color:hsl(210, 9%, 31%);--list-group-action-active-color:hsl(210, 11%, 15%);--list-group-action-active-bg:hsl(210, 16%, 93%);--list-group-disabled-color:hsl(210, 7%, 46%);--list-group-disabled-bg:var(--body-bg);--list-group-active-color:var(--body-bg);--list-group-active-bg:hsl(240, 98%, 17%);--list-group-active-border-color:hsl(240, 98%, 17%);--dropdown-zindex:1000;--dropdown-min-width:10rem;--dropdown-padding-x:0;--dropdown-padding-y:0.5rem;--dropdown-spacer:0.125rem;--dropdown-font-size:1rem;--dropdown-color:hsl(210, 11%, 15%);--dropdown-bg:var(--body-bg);--dropdown-border-color:var(--border-color-translucent);--dropdown-border-radius:0.25rem;--dropdown-border-width:1px;--dropdown-inner-border-radius:calc(0.25rem - 1px);--dropdown-divider-bg:var(--border-color-translucent);--dropdown-divider-margin-y:0.5rem;--dropdown-box-shadow:0 0.5rem 1rem var(--shadow-color-light);--dropdown-link-color:hsl(210, 11%, 15%);--dropdown-link-active-color:var(--body-bg);--dropdown-link-active-bg:hsl(240, 98%, 17%);--dropdown-link-disabled-color:hsl(210, 11%, 71%);--dropdown-item-padding-x:1rem;--dropdown-item-padding-y:0.25rem;--dropdown-header-color:hsl(210, 7%, 46%);--dropdown-header-padding-x:1rem;--dropdown-header-padding-y:0.5rem;--toast-zindex:1090;--toast-padding-x:0.75rem;--toast-padding-y:0.5rem;--toast-spacing:1em;--toast-max-width:350px;--toast-font-size:0.875rem;--toast-color: ;--toast-bg:rgba(255, 255, 255, 0.85);--toast-border-width:1px;--toast-border-color:var(--border-color-translucent);--toast-border-radius:0.25rem;--toast-box-shadow:0 0.5rem 1rem var(--shadow-color-light);--toast-header-color:hsl(210, 7%, 46%);--toast-header-bg:rgba(var(--white-rgb), 0.85);--toast-header-border-color:rgba(var(--black-rgb), var(--opacity-5));--modal-zindex:1050;--modal-width:500px;--modal-padding:1rem;--modal-margin:0.5rem;--modal-color: ;--modal-bg:var(--body-bg);--modal-border-color:var(--border-color-translucent);--modal-border-width:1px;--modal-border-radius:0.3rem;--modal-box-shadow:0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);--modal-inner-border-radius:calc(0.3rem - 1px);--modal-header-padding-x:1rem;--modal-header-padding-y:1rem;--modal-header-padding:1rem 1rem;--modal-header-border-color:var(--border-color);--modal-header-border-width:1px;--modal-title-line-height:1.5;--modal-footer-gap:0.5rem;--modal-footer-bg: ;--modal-footer-border-color:var(--border-color);--modal-footer-border-width:1px;--tooltip-zindex:1070;--tooltip-max-width:200px;--tooltip-padding-x:0.5rem;--tooltip-padding-y:0.25rem;--tooltip-margin: ;--tooltip-font-size:0.875rem;--tooltip-color:var(--body-bg);--tooltip-bg:hsl(0, 0%, 0%);--tooltip-border-radius:0.25rem;--tooltip-opacity:0.9;--tooltip-arrow-width:0.8rem;--tooltip-arrow-height:0.4rem;--popover-zindex:1060;--popover-max-width:276px;--popover-font-size:0.875rem;--popover-bg:var(--body-bg);--popover-border-width:1px;--popover-border-color:var(--border-color-translucent);--popover-border-radius:0.3rem;--popover-inner-border-radius:calc(0.3rem - 1px);--popover-box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.15);--popover-header-padding-x:1rem;--popover-header-padding-y:0.5rem;--popover-header-font-size:1rem;--popover-header-color: ;--popover-header-bg:#f0f0f0;--popover-body-padding-x:1rem;--popover-body-padding-y:1rem;--popover-body-color:hsl(210, 11%, 15%);--popover-arrow-width:1rem;--popover-arrow-height:0.5rem;--popover-arrow-border:var(--popover-border-color);--spinner-width:2rem;--spinner-height:2rem;--spinner-vertical-align:-0.125em;--spinner-border-width:0.25em;--spinner-animation-speed:0.75s;--nav-tabs-border-width:1px;--nav-tabs-border-color:hsl(210, 14%, 89%);--nav-tabs-border-radius:0.25rem;--nav-tabs-link-active-color:hsl(210, 9%, 31%);--nav-tabs-link-active-bg:var(--body-bg);--nav-tabs-link-active-border-color:hsl(210, 14%, 89%) hsl(210, 14%, 89%) var(--body-bg);--nav-pills-border-radius:0.25rem;--nav-pills-link-active-color:var(--body-bg);--nav-pills-link-active-bg:hsl(240, 98%, 17%);--table-color:var(--body-color);--table-bg:transparent;--table-border-color:var(--border-color);--table-accent-bg:transparent;--table-striped-color:var(--body-color);--table-striped-bg:rgba(var(--black-rgb), var(--opacity-5));--table-active-color:var(--body-color);--table-active-bg:rgba(var(--black-rgb), 0.075);--backdrop-zindex:1040;--backdrop-bg:hsl(0, 0%, 0%);--backdrop-opacity:0.5}.btn{--btn-padding-x:1rem;--btn-padding-y:0.6rem;--btn-font-family:inherit;--btn-font-size:1rem;--btn-font-weight:400;--btn-line-height:1.5;--btn-color:hsl(210, 11%, 15%);--btn-bg:transparent;--btn-border-width:1px;--btn-border-color:transparent;--btn-border-radius:0.25rem;--btn-active-border-color:transparent;--btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--btn-disabled-opacity:0.65;--btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--btn-padding-y) var(--btn-padding-x);font-family:var(--btn-font-family);font-size:var(--btn-font-size);font-weight:var(--btn-font-weight);line-height:var(--btn-line-height);color:var(--btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:var(--btn-border-width) solid var(--btn-border-color);border-radius:var(--btn-border-radius);background-color:var(--btn-bg);-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-box-shadow .15s ease-in-out;-o-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.btn-primary{--btn-color:hsl(0, 0%, 100%);--btn-bg:hsl(240, 98%, 17%);--btn-border-color:hsl(240, 98%, 17%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:#010149;--btn-hover-border-color:#010145;--btn-focus-shadow-rgb:39,39,111;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:#010145;--btn-active-border-color:#010141;--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(0, 0%, 100%);--btn-disabled-bg:hsl(240, 98%, 17%);--btn-disabled-border-color:hsl(240, 98%, 17%)}.btn-secondary{--btn-color:var(--body-bg);--btn-bg:var(--nav-bg-color);--btn-border-color:hsl(210, 7%, 46%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:#5d636b;--btn-hover-border-color:#575e65;--btn-focus-shadow-rgb:gray;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:#575e65;--btn-active-border-color:#52585f;--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(0, 0%, 100%);--btn-disabled-bg:hsl(210, 7%, 46%);--btn-disabled-border-color:hsl(210, 7%, 46%)}.btn-success{--btn-color:hsl(0, 0%, 100%);--btn-bg:hsl(120, 32%, 39%);--btn-border-color:hsl(120, 32%, 39%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:#3a6f3a;--btn-hover-border-color:#366936;--btn-focus-shadow-rgb:96,150,96;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:#366936;--btn-active-border-color:#336233;--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(0, 0%, 100%);--btn-disabled-bg:hsl(120, 32%, 39%);--btn-disabled-border-color:hsl(120, 32%, 39%)}.btn-info{--btn-color:hsl(0, 0%, 100%);--btn-bg:hsl(207, 49%, 37%);--btn-border-color:hsl(207, 49%, 37%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:#295478;--btn-hover-border-color:#264f71;--btn-focus-shadow-rgb:79,122,158;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:#264f71;--btn-active-border-color:#244a6a;--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(0, 0%, 100%);--btn-disabled-bg:hsl(207, 49%, 37%);--btn-disabled-border-color:hsl(207, 49%, 37%)}.btn-warning{--btn-color:hsl(0, 0%, 100%);--btn-bg:hsl(34, 100%, 34%);--btn-border-color:hsl(34, 100%, 34%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:#935300;--btn-hover-border-color:#8a4e00;--btn-focus-shadow-rgb:185,122,38;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:#8a4e00;--btn-active-border-color:#824a00;--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(0, 0%, 100%);--btn-disabled-bg:hsl(34, 100%, 34%);--btn-disabled-border-color:hsl(34, 100%, 34%)}.btn-danger{--btn-color:hsl(0, 0%, 100%);--btn-bg:hsl(3, 75%, 37%);--btn-border-color:hsl(3, 75%, 37%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:#8c1a14;--btn-hover-border-color:#841913;--btn-focus-shadow-rgb:179,65,59;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:#841913;--btn-active-border-color:#7c1712;--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(0, 0%, 100%);--btn-disabled-bg:hsl(3, 75%, 37%);--btn-disabled-border-color:hsl(3, 75%, 37%)}.btn-light{--btn-color:hsl(0, 0%, 0%);--btn-bg:hsl(210, 17%, 98%);--btn-border-color:hsl(210, 17%, 98%);--btn-hover-color:hsl(0, 0%, 0%);--btn-hover-bg:#d4d5d5;--btn-hover-border-color:#c7c8c9;--btn-focus-shadow-rgb:212,213,213;--btn-active-color:hsl(0, 0%, 0%);--btn-active-bg:#c7c8c9;--btn-active-border-color:#bbbcbc;--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(0, 0%, 0%);--btn-disabled-bg:hsl(210, 17%, 98%);--btn-disabled-border-color:hsl(210, 17%, 98%)}.btn-dark{--btn-color:hsl(0, 0%, 100%);--btn-bg:hsl(210, 10%, 23%);--btn-border-color:hsl(210, 10%, 23%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:#53585e;--btn-hover-border-color:#494f54;--btn-focus-shadow-rgb:83,88,94;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:#5d6267;--btn-active-border-color:#494f54;--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(0, 0%, 100%);--btn-disabled-bg:hsl(210, 10%, 23%);--btn-disabled-border-color:hsl(210, 10%, 23%)}.btn-outline-primary{--btn-color:hsl(240, 98%, 17%);--btn-border-color:hsl(240, 98%, 17%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:hsl(240, 98%, 17%);--btn-hover-border-color:hsl(240, 98%, 17%);--btn-focus-shadow-rgb:1,1,86;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:hsl(240, 98%, 17%);--btn-active-border-color:hsl(240, 98%, 17%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(240, 98%, 17%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(240, 98%, 17%);--gradient:none}.btn-outline-secondary{--btn-color:hsl(210, 7%, 46%);--btn-border-color:hsl(210, 7%, 46%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:hsl(210, 7%, 46%);--btn-hover-border-color:hsl(210, 7%, 46%);--btn-focus-shadow-rgb:109,117,126;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:hsl(210, 7%, 46%);--btn-active-border-color:hsl(210, 7%, 46%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(210, 7%, 46%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(210, 7%, 46%);--gradient:none}.btn-outline-success{--btn-color:hsl(120, 32%, 39%);--btn-border-color:hsl(120, 32%, 39%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:hsl(120, 32%, 39%);--btn-hover-border-color:hsl(120, 32%, 39%);--btn-focus-shadow-rgb:68,131,68;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:hsl(120, 32%, 39%);--btn-active-border-color:hsl(120, 32%, 39%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(120, 32%, 39%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(120, 32%, 39%);--gradient:none}.btn-outline-info{--btn-color:hsl(207, 49%, 37%);--btn-border-color:hsl(207, 49%, 37%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:hsl(207, 49%, 37%);--btn-hover-border-color:hsl(207, 49%, 37%);--btn-focus-shadow-rgb:48,99,141;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:hsl(207, 49%, 37%);--btn-active-border-color:hsl(207, 49%, 37%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(207, 49%, 37%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(207, 49%, 37%);--gradient:none}.btn-outline-warning{--btn-color:hsl(34, 100%, 34%);--btn-border-color:hsl(34, 100%, 34%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:hsl(34, 100%, 34%);--btn-hover-border-color:hsl(34, 100%, 34%);--btn-focus-shadow-rgb:173,98,0;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:hsl(34, 100%, 34%);--btn-active-border-color:hsl(34, 100%, 34%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(34, 100%, 34%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(34, 100%, 34%);--gradient:none}.btn-outline-danger{--btn-color:hsl(3, 75%, 37%);--btn-border-color:hsl(3, 75%, 37%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:hsl(3, 75%, 37%);--btn-hover-border-color:hsl(3, 75%, 37%);--btn-focus-shadow-rgb:165,31,24;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:hsl(3, 75%, 37%);--btn-active-border-color:hsl(3, 75%, 37%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(3, 75%, 37%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(3, 75%, 37%);--gradient:none}.btn-outline-light{--btn-color:hsl(210, 17%, 98%);--btn-border-color:hsl(210, 17%, 98%);--btn-hover-color:hsl(0, 0%, 0%);--btn-hover-bg:hsl(210, 17%, 98%);--btn-hover-border-color:hsl(210, 17%, 98%);--btn-focus-shadow-rgb:249,250,251;--btn-active-color:hsl(0, 0%, 0%);--btn-active-bg:hsl(210, 17%, 98%);--btn-active-border-color:hsl(210, 17%, 98%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(210, 17%, 98%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(210, 17%, 98%);--gradient:none}.btn-outline-dark{--btn-color:hsl(210, 10%, 23%);--btn-border-color:hsl(210, 10%, 23%);--btn-hover-color:hsl(0, 0%, 100%);--btn-hover-bg:hsl(210, 10%, 23%);--btn-hover-border-color:hsl(210, 10%, 23%);--btn-focus-shadow-rgb:53,59,65;--btn-active-color:hsl(0, 0%, 100%);--btn-active-bg:hsl(210, 10%, 23%);--btn-active-border-color:hsl(210, 10%, 23%);--btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--btn-disabled-color:hsl(210, 10%, 23%);--btn-disabled-bg:transparent;--btn-disabled-border-color:hsl(210, 10%, 23%);--gradient:none}.btn-link{--btn-font-weight:400;--btn-color:var(--link-color);--btn-bg:transparent;--btn-border-color:transparent;--btn-hover-color:var(--link-hover-color);--btn-hover-border-color:transparent;--btn-active-color:var(--link-hover-color);--btn-active-border-color:transparent;--btn-disabled-color:hsl(210, 7%, 46%);--btn-disabled-border-color:transparent;--btn-box-shadow:none;--btn-focus-shadow-rgb:39,39,111;text-decoration:underline}
\ No newline at end of file
diff --git a/src/media/fonts/GOOGLE_FONTS_README.md b/src/media/fonts/GOOGLE_FONTS_README.md
new file mode 100644
index 0000000..878cca2
--- /dev/null
+++ b/src/media/fonts/GOOGLE_FONTS_README.md
@@ -0,0 +1,31 @@
+
+
+# Self-Hosted Google Fonts
+
+Fonts are served locally to avoid external CDN dependencies and improve privacy/performance.
+
+## Available Fonts
+
+| Font | Weights | Styles | CSS File |
+|------|---------|--------|----------|
+| Roboto | 100–900 | Normal + Italic | `css/fonts/roboto.css` |
+| Fredoka | 300–700 | Normal | `css/fonts/fredoka.css` |
+| Pacifico | 400 | Normal | `css/fonts/pacifico.css` |
+| Osaka | — | — | `css/fonts/osaka.css` |
+
+## Adding New Fonts
+
+1. Run `php scripts/download-google-fonts.php` or manually download woff2 files
+2. Place files in `src/media/fonts/`
+3. Create a CSS file in `src/media/css/fonts/` with `@font-face` declarations
+4. Register the CSS in `joomla.asset.json`
+5. Add the font as an option in `templateDetails.xml` font selector
+
+## File Naming Convention
+
+`{font-name}-v{version}-latin-{weight}.woff2`
+
+Examples: `roboto-v51-latin-regular.woff2`, `fredoka-v17-latin-700.woff2`
diff --git a/src/media/fonts/fredoka-v17-latin-300.woff2 b/src/media/fonts/fredoka-v17-latin-300.woff2
new file mode 100644
index 0000000..a75b997
Binary files /dev/null and b/src/media/fonts/fredoka-v17-latin-300.woff2 differ
diff --git a/src/media/fonts/fredoka-v17-latin-500.woff2 b/src/media/fonts/fredoka-v17-latin-500.woff2
new file mode 100644
index 0000000..1bde60b
Binary files /dev/null and b/src/media/fonts/fredoka-v17-latin-500.woff2 differ
diff --git a/src/media/fonts/fredoka-v17-latin-600.woff2 b/src/media/fonts/fredoka-v17-latin-600.woff2
new file mode 100644
index 0000000..ffc60e8
Binary files /dev/null and b/src/media/fonts/fredoka-v17-latin-600.woff2 differ
diff --git a/src/media/fonts/fredoka-v17-latin-700.woff2 b/src/media/fonts/fredoka-v17-latin-700.woff2
new file mode 100644
index 0000000..47139ea
Binary files /dev/null and b/src/media/fonts/fredoka-v17-latin-700.woff2 differ
diff --git a/src/media/fonts/fredoka-v17-latin-regular.woff2 b/src/media/fonts/fredoka-v17-latin-regular.woff2
new file mode 100644
index 0000000..8d91972
Binary files /dev/null and b/src/media/fonts/fredoka-v17-latin-regular.woff2 differ
diff --git a/src/media/fonts/index.html b/src/media/fonts/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/media/fonts/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/media/fonts/osaka-re.woff b/src/media/fonts/osaka-re.woff
new file mode 100644
index 0000000..9d06db2
Binary files /dev/null and b/src/media/fonts/osaka-re.woff differ
diff --git a/src/media/fonts/pacifico-v23-latin-regular.woff2 b/src/media/fonts/pacifico-v23-latin-regular.woff2
new file mode 100644
index 0000000..4bffc9c
Binary files /dev/null and b/src/media/fonts/pacifico-v23-latin-regular.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-100.woff2 b/src/media/fonts/roboto-v51-latin-100.woff2
new file mode 100644
index 0000000..33d05d9
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-100.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-100italic.woff2 b/src/media/fonts/roboto-v51-latin-100italic.woff2
new file mode 100644
index 0000000..fa142b4
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-100italic.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-200.woff2 b/src/media/fonts/roboto-v51-latin-200.woff2
new file mode 100644
index 0000000..b183681
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-200.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-200italic.woff2 b/src/media/fonts/roboto-v51-latin-200italic.woff2
new file mode 100644
index 0000000..e74da8f
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-200italic.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-300.woff2 b/src/media/fonts/roboto-v51-latin-300.woff2
new file mode 100644
index 0000000..fb6526f
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-300.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-300italic.woff2 b/src/media/fonts/roboto-v51-latin-300italic.woff2
new file mode 100644
index 0000000..421abe0
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-300italic.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-500.woff2 b/src/media/fonts/roboto-v51-latin-500.woff2
new file mode 100644
index 0000000..171a2f6
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-500.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-500italic.woff2 b/src/media/fonts/roboto-v51-latin-500italic.woff2
new file mode 100644
index 0000000..18756c1
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-500italic.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-600.woff2 b/src/media/fonts/roboto-v51-latin-600.woff2
new file mode 100644
index 0000000..e89f875
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-600.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-600italic.woff2 b/src/media/fonts/roboto-v51-latin-600italic.woff2
new file mode 100644
index 0000000..0bbd1d2
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-600italic.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-700.woff2 b/src/media/fonts/roboto-v51-latin-700.woff2
new file mode 100644
index 0000000..85b8ace
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-700.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-700italic.woff2 b/src/media/fonts/roboto-v51-latin-700italic.woff2
new file mode 100644
index 0000000..859feb5
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-700italic.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-800.woff2 b/src/media/fonts/roboto-v51-latin-800.woff2
new file mode 100644
index 0000000..ec92330
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-800.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-800italic.woff2 b/src/media/fonts/roboto-v51-latin-800italic.woff2
new file mode 100644
index 0000000..81db4cc
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-800italic.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-900.woff2 b/src/media/fonts/roboto-v51-latin-900.woff2
new file mode 100644
index 0000000..412c9ac
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-900.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-900italic.woff2 b/src/media/fonts/roboto-v51-latin-900italic.woff2
new file mode 100644
index 0000000..47cdb3e
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-900italic.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-italic.woff2 b/src/media/fonts/roboto-v51-latin-italic.woff2
new file mode 100644
index 0000000..04367ca
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-italic.woff2 differ
diff --git a/src/media/fonts/roboto-v51-latin-regular.woff2 b/src/media/fonts/roboto-v51-latin-regular.woff2
new file mode 100644
index 0000000..77e4259
Binary files /dev/null and b/src/media/fonts/roboto-v51-latin-regular.woff2 differ
diff --git a/src/media/images/bg.svg b/src/media/images/bg.svg
new file mode 100644
index 0000000..f49e1d9
--- /dev/null
+++ b/src/media/images/bg.svg
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
diff --git a/src/media/images/index.html b/src/media/images/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/media/images/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/media/images/select-bg-active-rtl.svg b/src/media/images/select-bg-active-rtl.svg
new file mode 100644
index 0000000..eae47aa
--- /dev/null
+++ b/src/media/images/select-bg-active-rtl.svg
@@ -0,0 +1 @@
+
diff --git a/src/media/images/select-bg-active.svg b/src/media/images/select-bg-active.svg
new file mode 100644
index 0000000..19cd786
--- /dev/null
+++ b/src/media/images/select-bg-active.svg
@@ -0,0 +1 @@
+
diff --git a/src/media/images/select-bg-rtl.svg b/src/media/images/select-bg-rtl.svg
new file mode 100644
index 0000000..a1ae9a3
--- /dev/null
+++ b/src/media/images/select-bg-rtl.svg
@@ -0,0 +1 @@
+
diff --git a/src/media/images/select-bg.svg b/src/media/images/select-bg.svg
new file mode 100644
index 0000000..e2fefcc
--- /dev/null
+++ b/src/media/images/select-bg.svg
@@ -0,0 +1 @@
+
diff --git a/src/media/images/template_thumbnail.png b/src/media/images/template_thumbnail.png
new file mode 100644
index 0000000..1a05a0e
Binary files /dev/null and b/src/media/images/template_thumbnail.png differ
diff --git a/src/media/index.html b/src/media/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/media/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/media/js/gtm.js b/src/media/js/gtm.js
new file mode 100644
index 0000000..b2cbeec
--- /dev/null
+++ b/src/media/js/gtm.js
@@ -0,0 +1,315 @@
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/* global window, document, navigator */
+(() => {
+ "use strict";
+
+ /**
+ * @typedef {Object} MokoGtmOptions
+ * @property {string} [id] GTM container ID (e.g., "GTM-XXXXXXX")
+ * @property {string} [dataLayerName] Custom dataLayer name (default: "dataLayer")
+ * @property {boolean} [debug] Log debug messages to console (default: false)
+ * @property {boolean} [ignoreDNT] Ignore Do Not Track and always load (default: false)
+ * @property {boolean} [blockOnDev] Block loading on localhost/*.test/127.0.0.1 (default: true)
+ * @property {string} [envAuth] GTM Environment auth string (optional)
+ * @property {string} [envPreview] GTM Environment preview name (optional)
+ * @property {Record} [consentDefault]
+ * Default Consent Mode v2 map. Keys like:
+ * analytics_storage, ad_storage, ad_user_data, ad_personalization, functionality_storage, security_storage
+ * (default: {analytics_storage:'granted', functionality_storage:'granted', security_storage:'granted'})
+ * @property {() => (Record|void)} [pageVars]
+ * Function returning extra page variables to push on init (optional)
+ */
+
+ const PKG = "moko-gtm";
+ const PREFIX = `[${PKG}]`;
+ const WIN = window;
+
+ // Public API placeholder (attached to window at the end)
+ /** @type {{
+ * init: (opts?: Partial) => void,
+ * setConsent: (updates: Record) => void,
+ * push: (...args:any[]) => void,
+ * isLoaded: () => boolean,
+ * config: () => Required
+ * }} */
+ const API = {};
+
+ // ---- Utilities ---------------------------------------------------------
+
+ const isDevHost = () => {
+ const h = WIN.location && WIN.location.hostname || "";
+ return (
+ h === "localhost" ||
+ h === "127.0.0.1" ||
+ h.endsWith(".local") ||
+ h.endsWith(".test")
+ );
+ };
+
+ const dntEnabled = () => {
+ // Different browsers expose DNT differently; treat "1" or "yes" as enabled.
+ const n = navigator;
+ const v = (n.doNotTrack || n.msDoNotTrack || (n.navigator && n.navigator.doNotTrack) || "").toString().toLowerCase();
+ return v === "1" || v === "yes";
+ };
+
+ const getCurrentScript = () => {
+ // document.currentScript is best; fallback to last
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/media/js/mod_menu/index.html b/src/media/js/mod_menu/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/media/js/mod_menu/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/media/js/mod_menu/menu-metismenu-es5.js b/src/media/js/mod_menu/menu-metismenu-es5.js
new file mode 100644
index 0000000..de2c1e9
--- /dev/null
+++ b/src/media/js/mod_menu/menu-metismenu-es5.js
@@ -0,0 +1,37 @@
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+(function () {
+ 'use strict';
+
+ /**
+ * @package Joomla.Site
+ * @subpackage Templates.MokoOnyx
+ * @copyright (C) 2020 Open Source Matters, Inc.
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ * @since 4.0.0
+ */
+
+ document.addEventListener('DOMContentLoaded', function () {
+ var allMenus = document.querySelectorAll('ul.mod-menu_dropdown-metismenu');
+ allMenus.forEach(function (menu) {
+ // eslint-disable-next-line no-new, no-undef
+ var mm = new MetisMenu(menu, {
+ triggerElement: 'button.mm-toggler'
+ }).on('shown.metisMenu', function (event) {
+ window.addEventListener('click', function mmClick(e) {
+ if (!event.target.contains(e.target)) {
+ mm.hide(event.detail.shownElement);
+ window.removeEventListener('click', mmClick);
+ }
+ });
+ });
+ });
+ });
+
+})();
+
diff --git a/src/media/js/mod_menu/menu-metismenu.js b/src/media/js/mod_menu/menu-metismenu.js
new file mode 100644
index 0000000..ce2877a
--- /dev/null
+++ b/src/media/js/mod_menu/menu-metismenu.js
@@ -0,0 +1,24 @@
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+document.addEventListener('DOMContentLoaded', () => {
+ const allMenus = document.querySelectorAll('ul.mod-menu_dropdown-metismenu');
+ allMenus.forEach(menu => {
+ // eslint-disable-next-line no-new, no-undef
+ const mm = new MetisMenu(menu, {
+ triggerElement: 'button.mm-toggler'
+ }).on('shown.metisMenu', event => {
+ window.addEventListener('click', function mmClick(e) {
+ if (!event.target.contains(e.target)) {
+ mm.hide(event.detail.shownElement);
+ window.removeEventListener('click', mmClick);
+ }
+ });
+ });
+ });
+});
+
diff --git a/src/media/js/template.js b/src/media/js/template.js
new file mode 100644
index 0000000..70a2f6a
--- /dev/null
+++ b/src/media/js/template.js
@@ -0,0 +1,826 @@
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+(function (win, doc) {
+ "use strict";
+
+ // ========================================================================
+ // THEME INITIALIZATION (Early theme application)
+ // ========================================================================
+ var storageKey = "theme";
+ var mql = win.matchMedia("(prefers-color-scheme: dark)");
+ var root = doc.documentElement;
+
+ /**
+ * Apply theme to , syncing both data-bs-theme and data-aria-theme.
+ * @param {"light"|"dark"} theme
+ */
+ function applyTheme(theme) {
+ root.setAttribute("data-bs-theme", theme);
+ root.setAttribute("data-aria-theme", theme);
+ try { localStorage.setItem(storageKey, theme); } catch (e) {}
+ }
+
+ /**
+ * Clear stored preference so system preference is followed.
+ */
+ function clearStored() {
+ try { localStorage.removeItem(storageKey); } catch (e) {}
+ }
+
+ /**
+ * Determine system theme.
+ */
+ function systemTheme() {
+ return mql.matches ? "dark" : "light";
+ }
+
+ /**
+ * Get stored theme preference.
+ */
+ function getStored() {
+ try { return localStorage.getItem(storageKey); } catch (e) { return null; }
+ }
+
+ // ========================================================================
+ // FLOATING THEME TOGGLE (FAB)
+ // ========================================================================
+ function posClassFromBody() {
+ var pos = (doc.body.getAttribute('data-theme-fab-pos') || 'br').toLowerCase();
+ if (!/^(br|bl|tr|tl)$/.test(pos)) pos = 'br';
+ return 'pos-' + pos;
+ }
+
+ function buildThemeToggle() {
+ if (doc.getElementById('mokoThemeFab')) return;
+
+ var wrap = doc.createElement('div');
+ wrap.id = 'mokoThemeFab';
+ wrap.className = posClassFromBody();
+
+ // Sun/Moon toggle button
+ var switchWrap = doc.createElement('button');
+ switchWrap.id = 'mokoThemeSwitch';
+ switchWrap.type = 'button';
+ switchWrap.className = 'theme-icon-btn';
+ switchWrap.setAttribute('aria-label', 'Toggle dark mode');
+
+ var sunIcon = doc.createElement('i');
+ sunIcon.className = 'fa-solid fa-sun';
+ sunIcon.setAttribute('aria-hidden', 'true');
+
+ var moonIcon = doc.createElement('i');
+ moonIcon.className = 'fa-solid fa-moon';
+ moonIcon.setAttribute('aria-hidden', 'true');
+
+ switchWrap.appendChild(sunIcon);
+ switchWrap.appendChild(moonIcon);
+
+ function updateThemeIcon(theme) {
+ if (theme === 'dark') {
+ switchWrap.classList.add('is-dark');
+ switchWrap.classList.remove('is-light');
+ } else {
+ switchWrap.classList.add('is-light');
+ switchWrap.classList.remove('is-dark');
+ }
+ }
+
+ // Auto toggle (on/off switch style)
+ var autoWrap = doc.createElement('div');
+ autoWrap.className = 'auto-toggle-wrap';
+
+ var autoLabel = doc.createElement('span');
+ autoLabel.className = 'auto-label';
+ autoLabel.textContent = 'Auto';
+
+ var auto = doc.createElement('button');
+ auto.id = 'mokoThemeAuto';
+ auto.type = 'button';
+ auto.className = 'auto-switch';
+ auto.setAttribute('role', 'switch');
+ auto.setAttribute('aria-label', 'Automatic theme (follow system)');
+ auto.setAttribute('aria-checked', getStored() ? 'false' : 'true');
+
+ var autoTrack = doc.createElement('span');
+ autoTrack.className = 'auto-track';
+ var autoKnob = doc.createElement('span');
+ autoKnob.className = 'auto-knob';
+ autoTrack.appendChild(autoKnob);
+ auto.appendChild(autoTrack);
+ if (!getStored()) auto.classList.add('on');
+
+ autoWrap.appendChild(autoLabel);
+ autoWrap.appendChild(auto);
+
+ // Divider before a11y slot
+ var divider = doc.createElement('span');
+ divider.className = 'fab-divider';
+
+ // A11y slot — buildA11yToolbar will inject its toggle here
+ var a11ySlot = doc.createElement('span');
+ a11ySlot.id = 'mokoA11ySlot';
+
+ // Behavior
+ switchWrap.addEventListener('click', function () {
+ var current = (root.getAttribute('data-bs-theme') || 'light').toLowerCase();
+ var next = current === 'dark' ? 'light' : 'dark';
+ applyTheme(next);
+ updateThemeIcon(next);
+ // Turn off auto when manually switching
+ auto.classList.remove('on');
+ auto.setAttribute('aria-checked', 'false');
+ // Update meta theme color
+ var meta = doc.querySelector('meta[name="theme-color"]');
+ if (meta) {
+ meta.setAttribute('content', next === 'dark' ? '#0f1115' : '#ffffff');
+ }
+ });
+
+ auto.addEventListener('click', function () {
+ var isAuto = auto.classList.toggle('on');
+ auto.setAttribute('aria-checked', isAuto ? 'true' : 'false');
+ if (isAuto) {
+ clearStored();
+ var sys = systemTheme();
+ applyTheme(sys);
+ updateThemeIcon(sys);
+ }
+ });
+
+ // Respond to OS changes only when not user-forced
+ var onMql = function () {
+ if (!getStored()) {
+ var sys = systemTheme();
+ applyTheme(sys);
+ updateThemeIcon(sys);
+ }
+ };
+ if (typeof mql.addEventListener === 'function') mql.addEventListener('change', onMql);
+ else if (typeof mql.addListener === 'function') mql.addListener(onMql);
+
+ // Initial state
+ var initial = getStored() || systemTheme();
+ updateThemeIcon(initial);
+
+ // Mount
+ wrap.appendChild(switchWrap);
+ wrap.appendChild(autoWrap);
+ wrap.appendChild(divider);
+ wrap.appendChild(a11ySlot);
+ doc.body.appendChild(wrap);
+
+ // Debug helper
+ win.mokoThemeFabStatus = function () {
+ var el = doc.getElementById('mokoThemeFab');
+ if (!el) return { mounted: false };
+ var r = el.getBoundingClientRect();
+ return {
+ mounted: true,
+ rect: { top: r.top, left: r.left, width: r.width, height: r.height },
+ zIndex: win.getComputedStyle(el).zIndex,
+ posClass: el.className
+ };
+ };
+
+ // Outline if invisible
+ setTimeout(function () {
+ var r = wrap.getBoundingClientRect();
+ if (r.width < 10 || r.height < 10) {
+ wrap.classList.add('debug-outline');
+ console.warn('[moko] Theme FAB mounted but appears too small — check CSS collisions.');
+ }
+ }, 50);
+ }
+
+ // ========================================================================
+ // ACCESSIBILITY TOOLBAR
+ // ========================================================================
+ var a11yStorageKey = "moko-a11y";
+ var fontSizeSteps = [85, 90, 100, 110, 120, 130];
+ var defaultStep = 2; // index of 100
+
+ function getA11yPrefs() {
+ try {
+ var raw = localStorage.getItem(a11yStorageKey);
+ if (raw) return JSON.parse(raw);
+ } catch (e) {}
+ return { fontStep: defaultStep, inverted: false, contrast: false, links: false, font: false, paused: false };
+ }
+
+ function saveA11yPrefs(prefs) {
+ try { localStorage.setItem(a11yStorageKey, JSON.stringify(prefs)); } catch (e) {}
+ }
+
+ function applyFontSize(step) {
+ root.style.fontSize = fontSizeSteps[step] + "%";
+ }
+
+ function applyInversion(on) {
+ if (on) {
+ root.classList.add("a11y-inverted");
+ } else {
+ root.classList.remove("a11y-inverted");
+ }
+ }
+
+ function applyContrast(on) {
+ root.classList.toggle("a11y-high-contrast", on);
+ // Lazy-load the high-contrast stylesheet
+ var hcId = "mokoA11yHcSheet";
+ var existing = doc.getElementById(hcId);
+ if (on && !existing) {
+ var link = doc.createElement("link");
+ link.id = hcId;
+ link.rel = "stylesheet";
+ link.href = (doc.querySelector('link[href*="mokoonyx/css/template"]') || {}).href
+ ? (doc.querySelector('link[href*="mokoonyx/css/template"]').href.replace(/\/css\/template[^/]*$/, "/css/a11y-high-contrast.css"))
+ : "media/templates/site/mokoonyx/css/a11y-high-contrast.css";
+ doc.head.appendChild(link);
+ }
+ }
+
+ function applyLinks(on) {
+ root.classList.toggle("a11y-highlight-links", on);
+ }
+
+ function applyFont(on) {
+ root.classList.toggle("a11y-readable-font", on);
+ }
+
+ function applyPaused(on) {
+ root.classList.toggle("a11y-pause-animations", on);
+ }
+
+ /** Create a Font Awesome icon element (safe DOM, no innerHTML). */
+ function faIcon(classes) {
+ var i = doc.createElement("i");
+ i.className = classes;
+ i.setAttribute("aria-hidden", "true");
+ return i;
+ }
+
+ function buildA11yToolbar() {
+ if (doc.getElementById("mokoA11yToolbar")) return;
+
+ var body = doc.body;
+ var showResize = body.getAttribute("data-a11y-resize") === "1";
+ var showInvert = body.getAttribute("data-a11y-invert") === "1";
+ var showContrast = body.getAttribute("data-a11y-contrast") === "1";
+ var showLinks = body.getAttribute("data-a11y-links") === "1";
+ var showFont = body.getAttribute("data-a11y-font") === "1";
+ var showAnimations = body.getAttribute("data-a11y-animations") === "1";
+ var pos = (body.getAttribute("data-a11y-pos") || "tl").toLowerCase();
+ if (!/^(br|bl|tr|tl)$/.test(pos)) pos = "tl";
+
+ var prefs = getA11yPrefs();
+
+ // Container
+ var toolbar = doc.createElement("div");
+ toolbar.id = "mokoA11yToolbar";
+ toolbar.className = "a11y-pos-" + pos;
+ toolbar.setAttribute("role", "toolbar");
+ toolbar.setAttribute("aria-label", "Accessibility options");
+
+ // Toggle button (accessibility icon)
+ var toggle = doc.createElement("button");
+ toggle.type = "button";
+ toggle.id = "mokoA11yToggle";
+ toggle.className = "a11y-toggle";
+ toggle.setAttribute("aria-label", "Accessibility options");
+ toggle.setAttribute("aria-expanded", "false");
+ var a11yIcon = faIcon("fa-solid fa-universal-access");
+ // Unicode fallback if FA7 glyph doesn't render (e.g. FA6/FA7 conflict)
+ setTimeout(function () {
+ var cs = win.getComputedStyle(a11yIcon, "::before");
+ if (!cs.content || cs.content === "none" || cs.content === '""' || cs.content === '"" / ""') {
+ a11yIcon.className = "";
+ a11yIcon.textContent = "\u267F";
+ a11yIcon.style.fontSize = "1.1rem";
+ }
+ }, 500);
+ toggle.appendChild(a11yIcon);
+
+ // Panel
+ var panel = doc.createElement("div");
+ panel.id = "mokoA11yPanel";
+ panel.className = "a11y-panel";
+ panel.hidden = true;
+
+ // --- Text resize controls ---
+ if (showResize) {
+ var resizeGroup = doc.createElement("div");
+ resizeGroup.className = "a11y-group";
+ resizeGroup.setAttribute("role", "group");
+ resizeGroup.setAttribute("aria-label", "Text size");
+
+ var sizeLabel = doc.createElement("span");
+ sizeLabel.className = "a11y-group-label";
+ sizeLabel.textContent = "Text size";
+ resizeGroup.appendChild(sizeLabel);
+
+ var btnRow = doc.createElement("div");
+ btnRow.className = "a11y-btn-row";
+
+ var btnMinus = doc.createElement("button");
+ btnMinus.type = "button";
+ btnMinus.className = "a11y-btn";
+ btnMinus.setAttribute("aria-label", "Decrease text size");
+ btnMinus.appendChild(faIcon("fa-solid fa-minus"));
+
+ var sizeDisplay = doc.createElement("span");
+ sizeDisplay.className = "a11y-size-display";
+ sizeDisplay.setAttribute("aria-live", "polite");
+ sizeDisplay.textContent = fontSizeSteps[prefs.fontStep] + "%";
+
+ var btnPlus = doc.createElement("button");
+ btnPlus.type = "button";
+ btnPlus.className = "a11y-btn";
+ btnPlus.setAttribute("aria-label", "Increase text size");
+ btnPlus.appendChild(faIcon("fa-solid fa-plus"));
+
+ var btnReset = doc.createElement("button");
+ btnReset.type = "button";
+ btnReset.className = "a11y-btn a11y-btn-reset";
+ btnReset.setAttribute("aria-label", "Reset text size");
+ btnReset.appendChild(faIcon("fa-solid fa-rotate-left"));
+
+ btnMinus.addEventListener("click", function () {
+ if (prefs.fontStep > 0) {
+ prefs.fontStep--;
+ applyFontSize(prefs.fontStep);
+ sizeDisplay.textContent = fontSizeSteps[prefs.fontStep] + "%";
+ saveA11yPrefs(prefs);
+ }
+ });
+
+ btnPlus.addEventListener("click", function () {
+ if (prefs.fontStep < fontSizeSteps.length - 1) {
+ prefs.fontStep++;
+ applyFontSize(prefs.fontStep);
+ sizeDisplay.textContent = fontSizeSteps[prefs.fontStep] + "%";
+ saveA11yPrefs(prefs);
+ }
+ });
+
+ btnReset.addEventListener("click", function () {
+ prefs.fontStep = defaultStep;
+ applyFontSize(prefs.fontStep);
+ sizeDisplay.textContent = fontSizeSteps[prefs.fontStep] + "%";
+ saveA11yPrefs(prefs);
+ });
+
+ btnRow.appendChild(btnMinus);
+ btnRow.appendChild(sizeDisplay);
+ btnRow.appendChild(btnPlus);
+ btnRow.appendChild(btnReset);
+ resizeGroup.appendChild(btnRow);
+ panel.appendChild(resizeGroup);
+ }
+
+ // --- Helper: build a switch-style toggle button ---
+ function addSwitchOption(show, prefKey, icon, label, applyFn) {
+ if (!show) return;
+ var group = doc.createElement("div");
+ group.className = "a11y-group";
+
+ var btn = doc.createElement("button");
+ btn.type = "button";
+ btn.className = "a11y-btn a11y-btn-wide";
+ btn.setAttribute("role", "switch");
+ btn.setAttribute("aria-checked", prefs[prefKey] ? "true" : "false");
+ btn.setAttribute("aria-label", label);
+ btn.appendChild(faIcon(icon));
+ btn.appendChild(doc.createTextNode(" " + label));
+
+ if (prefs[prefKey]) btn.classList.add("active");
+
+ btn.addEventListener("click", function () {
+ prefs[prefKey] = !prefs[prefKey];
+ applyFn(prefs[prefKey]);
+ btn.setAttribute("aria-checked", prefs[prefKey] ? "true" : "false");
+ btn.classList.toggle("active", prefs[prefKey]);
+ saveA11yPrefs(prefs);
+ });
+
+ group.appendChild(btn);
+ panel.appendChild(group);
+ }
+
+ // --- Toggle options ---
+ addSwitchOption(showInvert, "inverted", "fa-solid fa-circle-half-stroke", "Invert colors", applyInversion);
+ addSwitchOption(showContrast, "contrast", "fa-solid fa-adjust", "High contrast", applyContrast);
+ addSwitchOption(showLinks, "links", "fa-solid fa-link", "Highlight links", applyLinks);
+ addSwitchOption(showFont, "font", "fa-solid fa-font", "Readable font", applyFont);
+ addSwitchOption(showAnimations, "paused", "fa-solid fa-pause", "Pause animations", applyPaused);
+
+ // Apply saved preferences on load
+ if (prefs.fontStep !== defaultStep) applyFontSize(prefs.fontStep);
+ if (prefs.inverted) applyInversion(true);
+ if (prefs.contrast) applyContrast(true);
+ if (prefs.links) applyLinks(true);
+ if (prefs.font) applyFont(true);
+ if (prefs.paused) applyPaused(true);
+
+ // If theme FAB is present, mount a11y toggle inside it; otherwise standalone
+ var fabSlot = doc.getElementById("mokoA11ySlot");
+ if (fabSlot) {
+ toggle.className = "a11y-toggle a11y-toggle-inline";
+ fabSlot.appendChild(toggle);
+ toolbar.className = "a11y-toolbar-floating";
+ toolbar.appendChild(panel);
+ body.appendChild(toolbar);
+ // Position panel near the FAB
+ toggle.addEventListener("click", function () {
+ var isOpen = !panel.hidden;
+ panel.hidden = isOpen;
+ toggle.setAttribute("aria-expanded", isOpen ? "false" : "true");
+ toggle.classList.toggle("active", !isOpen);
+ if (!isOpen) {
+ var rect = toggle.getBoundingClientRect();
+ toolbar.style.position = "fixed";
+ toolbar.style.bottom = (win.innerHeight - rect.top + 8) + "px";
+ toolbar.style.right = (win.innerWidth - rect.right) + "px";
+ toolbar.style.zIndex = "1202";
+ }
+ });
+ // Close on outside click for inline mode
+ doc.addEventListener("click", function (e) {
+ if (!toggle.contains(e.target) && !toolbar.contains(e.target) && !panel.hidden) {
+ panel.hidden = true;
+ toggle.setAttribute("aria-expanded", "false");
+ toggle.classList.remove("active");
+ }
+ });
+ } else {
+ // Standalone mode — toggle and close handlers
+ toggle.addEventListener("click", function () {
+ var isOpen = !panel.hidden;
+ panel.hidden = isOpen;
+ toggle.setAttribute("aria-expanded", isOpen ? "false" : "true");
+ toggle.classList.toggle("active", !isOpen);
+ });
+ doc.addEventListener("click", function (e) {
+ if (!toolbar.contains(e.target) && !panel.hidden) {
+ panel.hidden = true;
+ toggle.setAttribute("aria-expanded", "false");
+ toggle.classList.remove("active");
+ }
+ });
+ toolbar.appendChild(toggle);
+ toolbar.appendChild(panel);
+ body.appendChild(toolbar);
+ }
+ }
+
+ // ========================================================================
+ // TEMPLATE UTILITIES
+ // ========================================================================
+
+ /**
+ * Utility: smooth scroll to top
+ */
+ function backToTop() {
+ win.scrollTo({ top: 0, behavior: "smooth" });
+ }
+
+ /**
+ * Utility: toggle body class on scroll for sticky header styling
+ */
+ function handleScroll() {
+ if (win.scrollY > 50) {
+ doc.body.classList.add("scrolled");
+ } else {
+ doc.body.classList.remove("scrolled");
+ }
+ }
+
+ /**
+ * Initialize offcanvas drawer buttons for left/right drawers.
+ * Bootstrap handles drawers automatically via data-bs-toggle="offcanvas"
+ * This function is kept for backwards compatibility but only runs if drawers exist.
+ */
+ function initDrawers() {
+ // Check if any drawer buttons exist before initializing
+ var hasDrawers = doc.querySelector(".drawer-toggle-left") || doc.querySelector(".drawer-toggle-right");
+ if (!hasDrawers) {
+ return; // No drawers, skip initialization
+ }
+
+ // Bootstrap 5 handles offcanvas automatically via data-bs-toggle attribute
+ // No manual initialization needed if Bootstrap is loaded correctly
+ // The buttons already have data-bs-toggle="offcanvas" and data-bs-target="#drawer-*"
+ }
+
+ /**
+ * Initialize back-to-top link if present
+ */
+ function initBackTop() {
+ var backTop = doc.getElementById("back-top");
+ if (backTop) {
+ backTop.addEventListener("click", function (e) {
+ e.preventDefault();
+ backToTop();
+ });
+ }
+ }
+
+ /**
+ * Initialize theme based on stored preference or system setting
+ */
+ function initTheme() {
+ var stored = getStored();
+ var theme = stored ? stored : systemTheme();
+ applyTheme(theme);
+
+ // Listen for system changes only if Auto mode (no stored)
+ var onChange = function () {
+ if (!getStored()) {
+ applyTheme(systemTheme());
+ }
+ };
+ if (typeof mql.addEventListener === "function") {
+ mql.addEventListener("change", onChange);
+ } else if (typeof mql.addListener === "function") {
+ mql.addListener(onChange);
+ }
+
+ // Hook toggle UI if present (for inline switch, not FAB)
+ var switchEl = doc.getElementById("themeSwitch");
+ var autoBtn = doc.getElementById("themeAuto");
+
+ if (switchEl) {
+ switchEl.checked = (theme === "dark");
+ switchEl.addEventListener("change", function () {
+ var choice = switchEl.checked ? "dark" : "light";
+ applyTheme(choice);
+ });
+ }
+
+ if (autoBtn) {
+ autoBtn.addEventListener("click", function () {
+ clearStored();
+ applyTheme(systemTheme());
+ });
+ }
+ }
+
+ /**
+ * Check if theme FAB should be enabled based on body data attribute
+ */
+ function shouldEnableThemeFab() {
+ return doc.body.getAttribute('data-theme-fab-enabled') === '1';
+ }
+
+ /**
+ * Convert sidebar card modules into accordion on mobile.
+ * On screens <= 991px each card collapses; on desktop they revert.
+ */
+ function initSidebarAccordion() {
+ var BREAKPOINT = 992;
+ var sidebars = doc.querySelectorAll(".container-sidebar-left, .container-sidebar-right");
+ if (!sidebars.length) return;
+
+ // Build accordion structure once — works at all breakpoints
+ sidebars.forEach(function (sidebar, si) {
+ var accId = "sidebarAcc-" + si;
+ sidebar.setAttribute("id", accId);
+ sidebar.classList.add("accordion");
+
+ var isMobile = win.innerWidth < BREAKPOINT;
+ var cards = sidebar.querySelectorAll(":scope > .card");
+
+ cards.forEach(function (card, ci) {
+ var collapseId = accId + "-c" + ci;
+ card.classList.add("accordion-item");
+
+ var header = card.querySelector(".card-header");
+ var body = card.querySelector(".card-body");
+ if (!header || !body) return;
+
+ // Turn header into accordion button
+ header.classList.add("accordion-header");
+ var btn = doc.createElement("button");
+ btn.className = isMobile ? "accordion-button collapsed" : "accordion-button";
+ btn.type = "button";
+ btn.setAttribute("data-bs-toggle", "collapse");
+ btn.setAttribute("data-bs-target", "#" + collapseId);
+ btn.setAttribute("aria-expanded", isMobile ? "false" : "true");
+ btn.setAttribute("aria-controls", collapseId);
+ btn.textContent = header.textContent;
+ header.textContent = "";
+ header.appendChild(btn);
+
+ // Wrap body in collapse
+ var wrapper = doc.createElement("div");
+ wrapper.id = collapseId;
+ wrapper.className = isMobile ? "accordion-collapse collapse" : "accordion-collapse collapse show";
+ wrapper.setAttribute("data-bs-parent", "#" + accId);
+ card.insertBefore(wrapper, body);
+ wrapper.appendChild(body);
+ body.classList.add("accordion-body");
+ });
+ });
+ }
+
+ /**
+ * Toggle search on mobile via .show class
+ */
+ function initSearchToggle() {
+ var btn = doc.querySelector(".search-toggler");
+ var target = doc.getElementById("headerSearchCollapse");
+ if (!btn || !target) return;
+
+ btn.addEventListener("click", function () {
+ var isOpen = target.classList.toggle("show");
+ btn.setAttribute("aria-expanded", isOpen ? "true" : "false");
+ });
+ }
+
+ // ========================================================================
+ // CSS VARIABLE CLICK-TO-COPY
+ // ========================================================================
+
+ /**
+ * Inject toast + variable-chip styles once.
+ */
+ function injectVarCopyStyles() {
+ if (doc.getElementById("moko-var-copy-styles")) return;
+ var style = doc.createElement("style");
+ style.id = "moko-var-copy-styles";
+ style.textContent =
+ ".moko-var-chip{cursor:pointer;font-family:var(--font-monospace,monospace);font-size:.875em;" +
+ "background:var(--secondary-bg,#151b22);color:var(--link-color,#8ab4f8);" +
+ "border:1px solid var(--border-color,#2b323b);border-radius:.25rem;padding:.1em .4em;" +
+ "transition:background .15s,border-color .15s;white-space:nowrap;display:inline}" +
+ ".moko-var-chip:hover{background:var(--color-primary,#112855);color:#fff;border-color:var(--color-primary,#112855)}" +
+ ".moko-toast{position:fixed;bottom:1.5rem;left:50%;transform:translateX(-50%);z-index:10000;" +
+ "background:var(--color-primary,#112855);color:#fff;padding:.6rem 1.25rem;" +
+ "border-radius:.375rem;font-size:.875rem;box-shadow:0 4px 12px rgba(0,0,0,.25);" +
+ "opacity:0;transition:opacity .2s;pointer-events:none}" +
+ ".moko-toast--show{opacity:1}";
+ doc.head.appendChild(style);
+ }
+
+ /**
+ * Show a brief "Copied to clipboard" toast.
+ * @param {string} text - The variable name that was copied
+ */
+ function showCopyToast(text) {
+ var existing = doc.querySelector(".moko-toast");
+ if (existing) existing.remove();
+
+ var toast = doc.createElement("div");
+ toast.className = "moko-toast";
+ toast.textContent = "Copied to clipboard: " + text;
+ doc.body.appendChild(toast);
+
+ // Trigger reflow then show
+ void toast.offsetWidth;
+ toast.classList.add("moko-toast--show");
+
+ setTimeout(function () {
+ toast.classList.remove("moko-toast--show");
+ setTimeout(function () { toast.remove(); }, 200);
+ }, 2000);
+ }
+
+ /**
+ * Copy text to clipboard and show toast.
+ * @param {string} text
+ */
+ function copyVariable(text) {
+ if (navigator.clipboard && navigator.clipboard.writeText) {
+ navigator.clipboard.writeText(text).then(function () {
+ showCopyToast(text);
+ });
+ } else {
+ // Fallback for older browsers using deprecated API
+ var ta = doc.createElement("textarea");
+ ta.value = text;
+ ta.style.cssText = "position:fixed;left:-9999px";
+ doc.body.appendChild(ta);
+ ta.select();
+ try { doc.execCommand("copy"); } catch (e) { /* noop */ }
+ ta.remove();
+ showCopyToast(text);
+ }
+ }
+
+ /**
+ * Scan text nodes for CSS variable patterns (--variable-name) and wrap
+ * each match in a clickable chip that copies the variable to clipboard.
+ */
+ function initVarCopy() {
+ injectVarCopyStyles();
+
+ // Pattern: --[a-zA-Z] followed by word/hyphen chars
+ var varPattern = /--[a-zA-Z][\w-]*/g;
+
+ // Elements to skip (inputs, scripts, styles, already-processed, code editors)
+ var SKIP_TAGS = { SCRIPT: 1, STYLE: 1, TEXTAREA: 1, INPUT: 1, SELECT: 1, NOSCRIPT: 1 };
+
+ var walker = doc.createTreeWalker(
+ doc.body,
+ NodeFilter.SHOW_TEXT,
+ {
+ acceptNode: function (node) {
+ if (SKIP_TAGS[node.parentNode.tagName]) return NodeFilter.FILTER_REJECT;
+ if (node.parentNode.classList && node.parentNode.classList.contains("moko-var-chip")) return NodeFilter.FILTER_REJECT;
+ if (!varPattern.test(node.nodeValue)) return NodeFilter.FILTER_REJECT;
+ varPattern.lastIndex = 0;
+ return NodeFilter.FILTER_ACCEPT;
+ }
+ }
+ );
+
+ var textNodes = [];
+ while (walker.nextNode()) textNodes.push(walker.currentNode);
+
+ textNodes.forEach(function (node) {
+ var text = node.nodeValue;
+ var frag = doc.createDocumentFragment();
+ var lastIndex = 0;
+ var match;
+
+ varPattern.lastIndex = 0;
+ while ((match = varPattern.exec(text)) !== null) {
+ // Text before the match
+ if (match.index > lastIndex) {
+ frag.appendChild(doc.createTextNode(text.slice(lastIndex, match.index)));
+ }
+
+ // Clickable chip
+ var chip = doc.createElement("span");
+ chip.className = "moko-var-chip";
+ chip.textContent = match[0];
+ chip.setAttribute("role", "button");
+ chip.setAttribute("tabindex", "0");
+ chip.setAttribute("title", "Click to copy " + match[0]);
+ chip.addEventListener("click", (function (varName) {
+ return function (e) {
+ e.preventDefault();
+ copyVariable(varName);
+ };
+ })(match[0]));
+ chip.addEventListener("keydown", (function (varName) {
+ return function (e) {
+ if (e.key === "Enter" || e.key === " ") {
+ e.preventDefault();
+ copyVariable(varName);
+ }
+ };
+ })(match[0]));
+ frag.appendChild(chip);
+
+ lastIndex = match.index + match[0].length;
+ }
+
+ // Remaining text after last match
+ if (lastIndex < text.length) {
+ frag.appendChild(doc.createTextNode(text.slice(lastIndex)));
+ }
+
+ node.parentNode.replaceChild(frag, node);
+ });
+ }
+
+ /**
+ * Run all template JS initializations
+ */
+ function init() {
+ // Initialize theme first
+ initTheme();
+
+ // Build floating theme toggle if enabled
+ if (shouldEnableThemeFab()) {
+ buildThemeToggle();
+ }
+
+ // Build accessibility toolbar if enabled
+ if (doc.body.getAttribute("data-a11y-toolbar") === "1") {
+ buildA11yToolbar();
+ }
+
+ // Sticky header behavior
+ handleScroll();
+ win.addEventListener("scroll", handleScroll);
+
+ // Init features
+ initDrawers();
+ initBackTop();
+ initSearchToggle();
+ initSidebarAccordion();
+ initVarCopy();
+ }
+
+ if (doc.readyState === "loading") {
+ doc.addEventListener("DOMContentLoaded", init);
+ } else {
+ init();
+ }
+})(window, document);
diff --git a/src/media/js/template.min.js b/src/media/js/template.min.js
new file mode 100644
index 0000000..ae137d7
--- /dev/null
+++ b/src/media/js/template.min.js
@@ -0,0 +1 @@
+!function(e,t){"use strict";var a="theme",n=e.matchMedia("(prefers-color-scheme: dark)"),r=t.documentElement;function o(e){r.setAttribute("data-bs-theme",e),r.setAttribute("data-aria-theme",e);try{localStorage.setItem(a,e)}catch(e){}}function d(){try{localStorage.removeItem(a)}catch(e){}}function i(){return n.matches?"dark":"light"}function c(){try{return localStorage.getItem(a)}catch(e){return null}}function l(){if(!t.getElementById("mokoThemeFab")){var a,l=t.createElement("div");l.id="mokoThemeFab",l.className=(a=(t.body.getAttribute("data-theme-fab-pos")||"br").toLowerCase(),/^(br|bl|tr|tl)$/.test(a)||(a="br"),"pos-"+a);var s=t.createElement("span");s.className="label",s.textContent="Light";var u=t.createElement("button");u.id="mokoThemeSwitch",u.type="button",u.setAttribute("role","switch"),u.setAttribute("aria-label","Toggle dark mode"),u.setAttribute("aria-checked","false");var m=t.createElement("span");m.className="switch";var h=t.createElement("span");h.className="knob",m.appendChild(h),u.appendChild(m);var f=t.createElement("span");f.className="label",f.textContent="Dark";var b=t.createElement("button");b.id="mokoThemeAuto",b.type="button",b.className="btn btn-sm btn-link text-decoration-none px-2",b.setAttribute("aria-label","Follow system theme"),b.textContent="Auto",u.addEventListener("click",function(){var e="dark"===(r.getAttribute("data-bs-theme")||"light").toLowerCase()?"light":"dark";o(e),u.setAttribute("aria-checked","dark"===e?"true":"false");var a=t.querySelector('meta[name="theme-color"]');a&&a.setAttribute("content","dark"===e?"#0f1115":"#ffffff")}),b.addEventListener("click",function(){d();var e=i();o(e),u.setAttribute("aria-checked","dark"===e?"true":"false")});var g=function(){if(!c()){var e=i();o(e),u.setAttribute("aria-checked","dark"===e?"true":"false")}};"function"==typeof n.addEventListener?n.addEventListener("change",g):"function"==typeof n.addListener&&n.addListener(g);var p=c()||i();u.setAttribute("aria-checked","dark"===p?"true":"false"),l.appendChild(s),l.appendChild(u),l.appendChild(f),l.appendChild(b),t.body.appendChild(l),e.mokoThemeFabStatus=function(){var a=t.getElementById("mokoThemeFab");if(!a)return{mounted:!1};var n=a.getBoundingClientRect();return{mounted:!0,rect:{top:n.top,left:n.left,width:n.width,height:n.height},zIndex:e.getComputedStyle(a).zIndex,posClass:a.className}},setTimeout(function(){var e=l.getBoundingClientRect();(e.width<10||e.height<10)&&(l.classList.add("debug-outline"),console.warn("[moko] Theme FAB mounted but appears too small — check CSS collisions."))},50)}}function s(){e.scrollY>50?t.body.classList.add("scrolled"):t.body.classList.remove("scrolled")}function u(){var a=t.getElementById("back-top");a&&a.addEventListener("click",function(t){t.preventDefault(),e.scrollTo({top:0,behavior:"smooth"})})}function m(){!function(){var e=c()||i();o(e);var a=function(){c()||o(i())};"function"==typeof n.addEventListener?n.addEventListener("change",a):"function"==typeof n.addListener&&n.addListener(a);var r=t.getElementById("themeSwitch"),l=t.getElementById("themeAuto");r&&(r.checked="dark"===e,r.addEventListener("change",function(){o(r.checked?"dark":"light")})),l&&l.addEventListener("click",function(){d(),o(i())})}(),"1"===t.body.getAttribute("data-theme-fab-enabled")&&l(),s(),e.addEventListener("scroll",s),t.querySelector(".drawer-toggle-left")||t.querySelector(".drawer-toggle-right"),u()}"loading"===t.readyState?t.addEventListener("DOMContentLoaded",m):m()}(window,document);
\ No newline at end of file
diff --git a/src/media/vendor/bootstrap-toc/bootstrap-toc.css b/src/media/vendor/bootstrap-toc/bootstrap-toc.css
new file mode 100644
index 0000000..67cf784
--- /dev/null
+++ b/src/media/vendor/bootstrap-toc/bootstrap-toc.css
@@ -0,0 +1,48 @@
+/*!
+ * Bootstrap Table of Contents v1.0.1 (https://afeld.github.io/bootstrap-toc/)
+ * Copyright 2015 Aidan Feldman
+ * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md)
+ *
+ * Modified for MokoCassiopeia to use template color variables for theme integration
+ */
+
+/* All levels of nav */
+nav[data-toggle='toc'] .nav > li > a {
+ display: block;
+ padding: 4px 20px;
+ font-size: 13px;
+ font-weight: 500;
+ color: var(--link-color, var(--color-link, #0d6efd));
+}
+nav[data-toggle='toc'] .nav > li > a:hover,
+nav[data-toggle='toc'] .nav > li > a:focus {
+ padding-left: 19px;
+ color: var(--link-hover-color, var(--color-hover, #0a58ca));
+ text-decoration: none;
+ background-color: transparent;
+ border-left: 1px solid var(--link-color, var(--color-link, #0d6efd));
+}
+nav[data-toggle='toc'] .nav > .active > a,
+nav[data-toggle='toc'] .nav > .active:hover > a,
+nav[data-toggle='toc'] .nav > .active:focus > a {
+ padding-left: 18px;
+ font-weight: bold;
+ color: var(--link-color, var(--color-link, #0d6efd));
+ background-color: transparent;
+ border-left: 2px solid var(--link-color, var(--color-link, #0d6efd));
+}
+
+/* Nav: second level (shown on .active) */
+nav[data-toggle='toc'] .nav .nav {
+ display: none; /* Hide by default, but at >768px, show it */
+ padding-bottom: 10px;
+}
+nav[data-toggle='toc'] .nav > .active > ul {
+ display: block;
+}
+
+@media (min-width: 768px) {
+ nav[data-toggle='toc'] .nav .nav {
+ display: block;
+ }
+}
diff --git a/src/media/vendor/bootstrap-toc/bootstrap-toc.js b/src/media/vendor/bootstrap-toc/bootstrap-toc.js
new file mode 100644
index 0000000..746f109
--- /dev/null
+++ b/src/media/vendor/bootstrap-toc/bootstrap-toc.js
@@ -0,0 +1,185 @@
+/*!
+ * Bootstrap Table of Contents v1.0.1 (https://afeld.github.io/bootstrap-toc/)
+ * Copyright 2015 Aidan Feldman
+ * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md)
+ */
+(function($) {
+ 'use strict';
+
+ window.Toc = {
+ helpers: {
+ // return all matching elements in the set, or their descendants
+ findOrFilter: function($el, selector) {
+ // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/
+ // http://stackoverflow.com/a/12731439/358804
+ var $descendants = $el.find(selector);
+ return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])');
+ },
+
+ generateUniqueIdBase: function(el) {
+ var text = $(el).text();
+
+ // adapted from
+ // https://github.com/bryanbraun/anchorjs/blob/5a7f01cbd56f8aa8413084a64e7d1cbb1d4b0e56/anchor.js#L237-L257
+ // and
+ // https://github.com/twbs/bootstrap/blob/b8a84c3e48ce62e5d1954c52d3796b3fcbeab8a9/site/docs/4.1/assets/js/src/application.js#L47-L53
+ // Remove punctuation and spaces
+ var base = text
+ .toLowerCase()
+ .replace(/[^\w\s-]/g, '')
+ .replace(/[\s]+/g, '-');
+
+ return base || el.tagName.toLowerCase();
+ },
+
+ generateUniqueId: function(el) {
+ var anchorBase = this.generateUniqueIdBase(el);
+ for (var i = 0; ; i++) {
+ var anchor = anchorBase;
+ if (i > 0) {
+ // add suffix
+ anchor += '-' + i;
+ }
+ // check if ID already exists
+ if (!document.getElementById(anchor)) {
+ return anchor;
+ }
+ }
+ },
+
+ generateAnchor: function(el) {
+ if (el.id) {
+ return el.id;
+ } else {
+ var anchor = this.generateUniqueId(el);
+ el.id = anchor;
+ return anchor;
+ }
+ },
+
+ createNavList: function() {
+ return $('');
+ },
+
+ createChildNavList: function($parent) {
+ var $childList = this.createNavList();
+ $parent.append($childList);
+ return $childList;
+ },
+
+ generateNavEl: function(anchor, text) {
+ var $a = $(' ');
+ $a.attr('href', '#' + anchor);
+ $a.text(text);
+ var $li = $(' ');
+ $li.append($a);
+ return $li;
+ },
+
+ generateNavItem: function(headingEl) {
+ var anchor = this.generateAnchor(headingEl);
+ var $heading = $(headingEl);
+ var text = $heading.data('toc-text') || $heading.text();
+ return this.generateNavEl(anchor, text);
+ },
+
+ // Find the highest (lowest-numbered) heading level present in the scope.
+ // Returns the tag number of the first heading found (e.g. 2 for ).
+ getTopLevel: function($scope) {
+ for (var i = 1; i <= 6; i++) {
+ var $headings = this.findOrFilter($scope, 'h' + i);
+ if ($headings.length >= 1) {
+ return i;
+ }
+ }
+
+ return 1;
+ },
+
+ // Returns elements for the top level and up to two levels below it.
+ // e.g. if topLevel is 2 → h2, h3, h4
+ getHeadings: function($scope, topLevel) {
+ var selectors = [];
+ for (var i = topLevel; i <= Math.min(topLevel + 2, 6); i++) {
+ selectors.push('h' + i);
+ }
+
+ return this.findOrFilter($scope, selectors.join(','));
+ },
+
+ getNavLevel: function(el) {
+ return parseInt(el.tagName.charAt(1), 10);
+ },
+
+ populateNav: function($topContext, topLevel, $headings) {
+ var $contexts = {};
+ $contexts[topLevel] = $topContext;
+ var $prevNavByLevel = {};
+
+ var helpers = this;
+ $headings.each(function(i, el) {
+ var $newNav = helpers.generateNavItem(el);
+ var navLevel = helpers.getNavLevel(el);
+
+ if (navLevel === topLevel) {
+ // Top level — append directly
+ $topContext.append($newNav);
+ $prevNavByLevel = {};
+ $prevNavByLevel[topLevel] = $newNav;
+ // Reset deeper contexts so next child creates a fresh sublist
+ $contexts = {};
+ $contexts[topLevel] = $topContext;
+ } else {
+ // Child level — ensure parent context exists
+ var parentLevel = navLevel - 1;
+ if (!$contexts[navLevel] && $prevNavByLevel[parentLevel]) {
+ $contexts[navLevel] = helpers.createChildNavList($prevNavByLevel[parentLevel]);
+ }
+ var $ctx = $contexts[navLevel] || $topContext;
+ $ctx.append($newNav);
+ $prevNavByLevel[navLevel] = $newNav;
+ // Reset deeper contexts
+ for (var l = navLevel + 1; l <= 6; l++) {
+ delete $contexts[l];
+ delete $prevNavByLevel[l];
+ }
+ }
+ });
+ },
+
+ parseOps: function(arg) {
+ var opts;
+ if (arg.jquery) {
+ opts = {
+ $nav: arg
+ };
+ } else {
+ opts = arg;
+ }
+ opts.$scope = opts.$scope || $(document.body);
+ return opts;
+ }
+ },
+
+ // accepts a jQuery object, or an options object
+ init: function(opts) {
+ opts = this.helpers.parseOps(opts);
+
+ // ensure that the data attribute is in place for styling
+ opts.$nav.attr('data-toggle', 'toc');
+
+ var $topContext = this.helpers.createChildNavList(opts.$nav);
+ var topLevel = this.helpers.getTopLevel(opts.$scope);
+ var $headings = this.helpers.getHeadings(opts.$scope, topLevel);
+ this.helpers.populateNav($topContext, topLevel, $headings);
+ }
+ };
+
+ $(function() {
+ $('nav[data-toggle="toc"]').each(function(i, el) {
+ var $nav = $(el);
+ var $scope = $('[data-toc-scope]');
+ Toc.init({ $nav: $nav, $scope: $scope.length ? $scope : $(document.body) });
+ });
+ });
+})(jQuery);
diff --git a/src/media/vendor/bootstrap-toc/index.html b/src/media/vendor/bootstrap-toc/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/media/vendor/bootstrap-toc/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/media/vendor/fa7free/css/all.css b/src/media/vendor/fa7free/css/all.css
new file mode 100644
index 0000000..70bbfcc
--- /dev/null
+++ b/src/media/vendor/fa7free/css/all.css
@@ -0,0 +1,10663 @@
+/*!
+ * Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ * Copyright 2025 Fonticons, Inc.
+ */
+.fa-solid,
+.fa-regular,
+.fa-brands,
+.fa-classic,
+.fas,
+.far,
+.fab,
+.fa {
+ --_fa-family: var(--fa-family, var(--fa-style-family, "Font Awesome 7 Free"));
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ display: var(--fa-display, inline-block);
+ font-family: var(--_fa-family);
+ font-feature-settings: normal;
+ font-style: normal;
+ font-synthesis: none;
+ font-variant: normal;
+ font-weight: var(--fa-style, 900);
+ line-height: 1;
+ text-align: center;
+ text-rendering: auto;
+ width: var(--fa-width, 1.25em);
+}
+
+:is(.fas,
+.far,
+.fab,
+.fa-solid,
+.fa-regular,
+.fa-brands,
+.fa-classic,
+.fa)::before {
+ content: var(--fa)/"";
+}
+
+@supports not (content: ""/"") {
+ :is(.fas,
+ .far,
+ .fab,
+ .fa-solid,
+ .fa-regular,
+ .fa-brands,
+ .fa-classic,
+ .fa)::before {
+ content: var(--fa);
+ }
+}
+.fa-1x {
+ font-size: 1em;
+}
+
+.fa-2x {
+ font-size: 2em;
+}
+
+.fa-3x {
+ font-size: 3em;
+}
+
+.fa-4x {
+ font-size: 4em;
+}
+
+.fa-5x {
+ font-size: 5em;
+}
+
+.fa-6x {
+ font-size: 6em;
+}
+
+.fa-7x {
+ font-size: 7em;
+}
+
+.fa-8x {
+ font-size: 8em;
+}
+
+.fa-9x {
+ font-size: 9em;
+}
+
+.fa-10x {
+ font-size: 10em;
+}
+
+.fa-2xs {
+ font-size: calc(10 / 16 * 1em); /* converts a 10px size into an em-based value that's relative to the scale's 16px base */
+ line-height: calc(1 / 10 * 1em); /* sets the line-height of the icon back to that of it's parent */
+ vertical-align: calc((6 / 10 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
+}
+
+.fa-xs {
+ font-size: calc(12 / 16 * 1em); /* converts a 12px size into an em-based value that's relative to the scale's 16px base */
+ line-height: calc(1 / 12 * 1em); /* sets the line-height of the icon back to that of it's parent */
+ vertical-align: calc((6 / 12 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
+}
+
+.fa-sm {
+ font-size: calc(14 / 16 * 1em); /* converts a 14px size into an em-based value that's relative to the scale's 16px base */
+ line-height: calc(1 / 14 * 1em); /* sets the line-height of the icon back to that of it's parent */
+ vertical-align: calc((6 / 14 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
+}
+
+.fa-lg {
+ font-size: calc(20 / 16 * 1em); /* converts a 20px size into an em-based value that's relative to the scale's 16px base */
+ line-height: calc(1 / 20 * 1em); /* sets the line-height of the icon back to that of it's parent */
+ vertical-align: calc((6 / 20 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
+}
+
+.fa-xl {
+ font-size: calc(24 / 16 * 1em); /* converts a 24px size into an em-based value that's relative to the scale's 16px base */
+ line-height: calc(1 / 24 * 1em); /* sets the line-height of the icon back to that of it's parent */
+ vertical-align: calc((6 / 24 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
+}
+
+.fa-2xl {
+ font-size: calc(32 / 16 * 1em); /* converts a 32px size into an em-based value that's relative to the scale's 16px base */
+ line-height: calc(1 / 32 * 1em); /* sets the line-height of the icon back to that of it's parent */
+ vertical-align: calc((6 / 32 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
+}
+
+.fa-width-auto {
+ --fa-width: auto;
+}
+
+.fa-fw,
+.fa-width-fixed {
+ --fa-width: 1.25em;
+}
+
+.fa-ul {
+ list-style-type: none;
+ margin-inline-start: var(--fa-li-margin, 2.5em);
+ padding-inline-start: 0;
+}
+.fa-ul > li {
+ position: relative;
+}
+
+.fa-li {
+ inset-inline-start: calc(-1 * var(--fa-li-width, 2em));
+ position: absolute;
+ text-align: center;
+ width: var(--fa-li-width, 2em);
+ line-height: inherit;
+}
+
+/* Heads Up: Bordered Icons will not be supported in the future!
+ - This feature will be deprecated in the next major release of Font Awesome (v8)!
+ - You may continue to use it in this version *v7), but it will not be supported in Font Awesome v8.
+*/
+/* Notes:
+* --@{v.$css-prefix}-border-width = 1/16 by default (to render as ~1px based on a 16px default font-size)
+* --@{v.$css-prefix}-border-padding =
+ ** 3/16 for vertical padding (to give ~2px of vertical whitespace around an icon considering it's vertical alignment)
+ ** 4/16 for horizontal padding (to give ~4px of horizontal whitespace around an icon)
+*/
+.fa-border {
+ border-color: var(--fa-border-color, #eee);
+ border-radius: var(--fa-border-radius, 0.1em);
+ border-style: var(--fa-border-style, solid);
+ border-width: var(--fa-border-width, 0.0625em);
+ box-sizing: var(--fa-border-box-sizing, content-box);
+ padding: var(--fa-border-padding, 0.1875em 0.25em);
+}
+
+.fa-pull-left,
+.fa-pull-start {
+ float: inline-start;
+ margin-inline-end: var(--fa-pull-margin, 0.3em);
+}
+
+.fa-pull-right,
+.fa-pull-end {
+ float: inline-end;
+ margin-inline-start: var(--fa-pull-margin, 0.3em);
+}
+
+.fa-beat {
+ animation-name: fa-beat;
+ animation-delay: var(--fa-animation-delay, 0s);
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 1s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, ease-in-out);
+}
+
+.fa-bounce {
+ animation-name: fa-bounce;
+ animation-delay: var(--fa-animation-delay, 0s);
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 1s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1));
+}
+
+.fa-fade {
+ animation-name: fa-fade;
+ animation-delay: var(--fa-animation-delay, 0s);
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 1s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));
+}
+
+.fa-beat-fade {
+ animation-name: fa-beat-fade;
+ animation-delay: var(--fa-animation-delay, 0s);
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 1s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));
+}
+
+.fa-flip {
+ animation-name: fa-flip;
+ animation-delay: var(--fa-animation-delay, 0s);
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 1s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, ease-in-out);
+}
+
+.fa-shake {
+ animation-name: fa-shake;
+ animation-delay: var(--fa-animation-delay, 0s);
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 1s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, linear);
+}
+
+.fa-spin {
+ animation-name: fa-spin;
+ animation-delay: var(--fa-animation-delay, 0s);
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 2s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, linear);
+}
+
+.fa-spin-reverse {
+ --fa-animation-direction: reverse;
+}
+
+.fa-pulse,
+.fa-spin-pulse {
+ animation-name: fa-spin;
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 1s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, steps(8));
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .fa-beat,
+ .fa-bounce,
+ .fa-fade,
+ .fa-beat-fade,
+ .fa-flip,
+ .fa-pulse,
+ .fa-shake,
+ .fa-spin,
+ .fa-spin-pulse {
+ animation: none !important;
+ transition: none !important;
+ }
+}
+@keyframes fa-beat {
+ 0%, 90% {
+ transform: scale(1);
+ }
+ 45% {
+ transform: scale(var(--fa-beat-scale, 1.25));
+ }
+}
+@keyframes fa-bounce {
+ 0% {
+ transform: scale(1, 1) translateY(0);
+ }
+ 10% {
+ transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);
+ }
+ 30% {
+ transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));
+ }
+ 50% {
+ transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);
+ }
+ 57% {
+ transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));
+ }
+ 64% {
+ transform: scale(1, 1) translateY(0);
+ }
+ 100% {
+ transform: scale(1, 1) translateY(0);
+ }
+}
+@keyframes fa-fade {
+ 50% {
+ opacity: var(--fa-fade-opacity, 0.4);
+ }
+}
+@keyframes fa-beat-fade {
+ 0%, 100% {
+ opacity: var(--fa-beat-fade-opacity, 0.4);
+ transform: scale(1);
+ }
+ 50% {
+ opacity: 1;
+ transform: scale(var(--fa-beat-fade-scale, 1.125));
+ }
+}
+@keyframes fa-flip {
+ 50% {
+ transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));
+ }
+}
+@keyframes fa-shake {
+ 0% {
+ transform: rotate(-15deg);
+ }
+ 4% {
+ transform: rotate(15deg);
+ }
+ 8%, 24% {
+ transform: rotate(-18deg);
+ }
+ 12%, 28% {
+ transform: rotate(18deg);
+ }
+ 16% {
+ transform: rotate(-22deg);
+ }
+ 20% {
+ transform: rotate(22deg);
+ }
+ 32% {
+ transform: rotate(-12deg);
+ }
+ 36% {
+ transform: rotate(12deg);
+ }
+ 40%, 100% {
+ transform: rotate(0deg);
+ }
+}
+@keyframes fa-spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+.fa-rotate-90 {
+ transform: rotate(90deg);
+}
+
+.fa-rotate-180 {
+ transform: rotate(180deg);
+}
+
+.fa-rotate-270 {
+ transform: rotate(270deg);
+}
+
+.fa-flip-horizontal {
+ transform: scale(-1, 1);
+}
+
+.fa-flip-vertical {
+ transform: scale(1, -1);
+}
+
+.fa-flip-both,
+.fa-flip-horizontal.fa-flip-vertical {
+ transform: scale(-1, -1);
+}
+
+.fa-rotate-by {
+ transform: rotate(var(--fa-rotate-angle, 0));
+}
+
+.fa-stack {
+ display: inline-block;
+ height: 2em;
+ line-height: 2em;
+ position: relative;
+ vertical-align: middle;
+ width: 2.5em;
+}
+
+.fa-stack-1x,
+.fa-stack-2x {
+ --fa-width: 100%;
+ inset: 0;
+ position: absolute;
+ text-align: center;
+ width: var(--fa-width);
+ z-index: var(--fa-stack-z-index, auto);
+}
+
+.fa-stack-1x {
+ line-height: inherit;
+}
+
+.fa-stack-2x {
+ font-size: 2em;
+}
+
+.fa-inverse {
+ color: var(--fa-inverse, #fff);
+}
+
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+ readers do not read off random characters that represent icons */
+
+.fa-0 {
+ --fa: "\30 ";
+}
+
+.fa-1 {
+ --fa: "\31 ";
+}
+
+.fa-2 {
+ --fa: "\32 ";
+}
+
+.fa-3 {
+ --fa: "\33 ";
+}
+
+.fa-4 {
+ --fa: "\34 ";
+}
+
+.fa-5 {
+ --fa: "\35 ";
+}
+
+.fa-6 {
+ --fa: "\36 ";
+}
+
+.fa-7 {
+ --fa: "\37 ";
+}
+
+.fa-8 {
+ --fa: "\38 ";
+}
+
+.fa-9 {
+ --fa: "\39 ";
+}
+
+.fa-exclamation {
+ --fa: "\!";
+}
+
+.fa-hashtag {
+ --fa: "\#";
+}
+
+.fa-dollar-sign {
+ --fa: "\$";
+}
+
+.fa-dollar {
+ --fa: "\$";
+}
+
+.fa-usd {
+ --fa: "\$";
+}
+
+.fa-percent {
+ --fa: "\%";
+}
+
+.fa-percentage {
+ --fa: "\%";
+}
+
+.fa-asterisk {
+ --fa: "\*";
+}
+
+.fa-plus {
+ --fa: "\+";
+}
+
+.fa-add {
+ --fa: "\+";
+}
+
+.fa-less-than {
+ --fa: "\<";
+}
+
+.fa-equals {
+ --fa: "\=";
+}
+
+.fa-greater-than {
+ --fa: "\>";
+}
+
+.fa-question {
+ --fa: "\?";
+}
+
+.fa-at {
+ --fa: "\@";
+}
+
+.fa-a {
+ --fa: "A";
+}
+
+.fa-b {
+ --fa: "B";
+}
+
+.fa-c {
+ --fa: "C";
+}
+
+.fa-d {
+ --fa: "D";
+}
+
+.fa-e {
+ --fa: "E";
+}
+
+.fa-f {
+ --fa: "F";
+}
+
+.fa-g {
+ --fa: "G";
+}
+
+.fa-h {
+ --fa: "H";
+}
+
+.fa-i {
+ --fa: "I";
+}
+
+.fa-j {
+ --fa: "J";
+}
+
+.fa-k {
+ --fa: "K";
+}
+
+.fa-l {
+ --fa: "L";
+}
+
+.fa-m {
+ --fa: "M";
+}
+
+.fa-n {
+ --fa: "N";
+}
+
+.fa-o {
+ --fa: "O";
+}
+
+.fa-p {
+ --fa: "P";
+}
+
+.fa-q {
+ --fa: "Q";
+}
+
+.fa-r {
+ --fa: "R";
+}
+
+.fa-s {
+ --fa: "S";
+}
+
+.fa-t {
+ --fa: "T";
+}
+
+.fa-u {
+ --fa: "U";
+}
+
+.fa-v {
+ --fa: "V";
+}
+
+.fa-w {
+ --fa: "W";
+}
+
+.fa-x {
+ --fa: "X";
+}
+
+.fa-y {
+ --fa: "Y";
+}
+
+.fa-z {
+ --fa: "Z";
+}
+
+.fa-faucet {
+ --fa: "\e005";
+}
+
+.fa-faucet-drip {
+ --fa: "\e006";
+}
+
+.fa-house-chimney-window {
+ --fa: "\e00d";
+}
+
+.fa-house-signal {
+ --fa: "\e012";
+}
+
+.fa-temperature-arrow-down {
+ --fa: "\e03f";
+}
+
+.fa-temperature-down {
+ --fa: "\e03f";
+}
+
+.fa-temperature-arrow-up {
+ --fa: "\e040";
+}
+
+.fa-temperature-up {
+ --fa: "\e040";
+}
+
+.fa-trailer {
+ --fa: "\e041";
+}
+
+.fa-bacteria {
+ --fa: "\e059";
+}
+
+.fa-bacterium {
+ --fa: "\e05a";
+}
+
+.fa-box-tissue {
+ --fa: "\e05b";
+}
+
+.fa-hand-holding-medical {
+ --fa: "\e05c";
+}
+
+.fa-hand-sparkles {
+ --fa: "\e05d";
+}
+
+.fa-hands-bubbles {
+ --fa: "\e05e";
+}
+
+.fa-hands-wash {
+ --fa: "\e05e";
+}
+
+.fa-handshake-slash {
+ --fa: "\e060";
+}
+
+.fa-handshake-alt-slash {
+ --fa: "\e060";
+}
+
+.fa-handshake-simple-slash {
+ --fa: "\e060";
+}
+
+.fa-head-side-cough {
+ --fa: "\e061";
+}
+
+.fa-head-side-cough-slash {
+ --fa: "\e062";
+}
+
+.fa-head-side-mask {
+ --fa: "\e063";
+}
+
+.fa-head-side-virus {
+ --fa: "\e064";
+}
+
+.fa-house-chimney-user {
+ --fa: "\e065";
+}
+
+.fa-house-laptop {
+ --fa: "\e066";
+}
+
+.fa-laptop-house {
+ --fa: "\e066";
+}
+
+.fa-lungs-virus {
+ --fa: "\e067";
+}
+
+.fa-people-arrows {
+ --fa: "\e068";
+}
+
+.fa-people-arrows-left-right {
+ --fa: "\e068";
+}
+
+.fa-plane-slash {
+ --fa: "\e069";
+}
+
+.fa-pump-medical {
+ --fa: "\e06a";
+}
+
+.fa-pump-soap {
+ --fa: "\e06b";
+}
+
+.fa-shield-virus {
+ --fa: "\e06c";
+}
+
+.fa-sink {
+ --fa: "\e06d";
+}
+
+.fa-soap {
+ --fa: "\e06e";
+}
+
+.fa-stopwatch-20 {
+ --fa: "\e06f";
+}
+
+.fa-shop-slash {
+ --fa: "\e070";
+}
+
+.fa-store-alt-slash {
+ --fa: "\e070";
+}
+
+.fa-store-slash {
+ --fa: "\e071";
+}
+
+.fa-toilet-paper-slash {
+ --fa: "\e072";
+}
+
+.fa-users-slash {
+ --fa: "\e073";
+}
+
+.fa-virus {
+ --fa: "\e074";
+}
+
+.fa-virus-slash {
+ --fa: "\e075";
+}
+
+.fa-viruses {
+ --fa: "\e076";
+}
+
+.fa-vest {
+ --fa: "\e085";
+}
+
+.fa-vest-patches {
+ --fa: "\e086";
+}
+
+.fa-arrow-trend-down {
+ --fa: "\e097";
+}
+
+.fa-arrow-trend-up {
+ --fa: "\e098";
+}
+
+.fa-arrow-up-from-bracket {
+ --fa: "\e09a";
+}
+
+.fa-austral-sign {
+ --fa: "\e0a9";
+}
+
+.fa-baht-sign {
+ --fa: "\e0ac";
+}
+
+.fa-bitcoin-sign {
+ --fa: "\e0b4";
+}
+
+.fa-bolt-lightning {
+ --fa: "\e0b7";
+}
+
+.fa-book-bookmark {
+ --fa: "\e0bb";
+}
+
+.fa-camera-rotate {
+ --fa: "\e0d8";
+}
+
+.fa-cedi-sign {
+ --fa: "\e0df";
+}
+
+.fa-chart-column {
+ --fa: "\e0e3";
+}
+
+.fa-chart-gantt {
+ --fa: "\e0e4";
+}
+
+.fa-clapperboard {
+ --fa: "\e131";
+}
+
+.fa-clover {
+ --fa: "\e139";
+}
+
+.fa-code-compare {
+ --fa: "\e13a";
+}
+
+.fa-code-fork {
+ --fa: "\e13b";
+}
+
+.fa-code-pull-request {
+ --fa: "\e13c";
+}
+
+.fa-colon-sign {
+ --fa: "\e140";
+}
+
+.fa-cruzeiro-sign {
+ --fa: "\e152";
+}
+
+.fa-display {
+ --fa: "\e163";
+}
+
+.fa-dong-sign {
+ --fa: "\e169";
+}
+
+.fa-elevator {
+ --fa: "\e16d";
+}
+
+.fa-filter-circle-xmark {
+ --fa: "\e17b";
+}
+
+.fa-florin-sign {
+ --fa: "\e184";
+}
+
+.fa-folder-closed {
+ --fa: "\e185";
+}
+
+.fa-franc-sign {
+ --fa: "\e18f";
+}
+
+.fa-guarani-sign {
+ --fa: "\e19a";
+}
+
+.fa-gun {
+ --fa: "\e19b";
+}
+
+.fa-hands-clapping {
+ --fa: "\e1a8";
+}
+
+.fa-house-user {
+ --fa: "\e1b0";
+}
+
+.fa-home-user {
+ --fa: "\e1b0";
+}
+
+.fa-indian-rupee-sign {
+ --fa: "\e1bc";
+}
+
+.fa-indian-rupee {
+ --fa: "\e1bc";
+}
+
+.fa-inr {
+ --fa: "\e1bc";
+}
+
+.fa-kip-sign {
+ --fa: "\e1c4";
+}
+
+.fa-lari-sign {
+ --fa: "\e1c8";
+}
+
+.fa-litecoin-sign {
+ --fa: "\e1d3";
+}
+
+.fa-manat-sign {
+ --fa: "\e1d5";
+}
+
+.fa-mask-face {
+ --fa: "\e1d7";
+}
+
+.fa-mill-sign {
+ --fa: "\e1ed";
+}
+
+.fa-money-bills {
+ --fa: "\e1f3";
+}
+
+.fa-naira-sign {
+ --fa: "\e1f6";
+}
+
+.fa-notdef {
+ --fa: "\e1fe";
+}
+
+.fa-panorama {
+ --fa: "\e209";
+}
+
+.fa-peseta-sign {
+ --fa: "\e221";
+}
+
+.fa-peso-sign {
+ --fa: "\e222";
+}
+
+.fa-plane-up {
+ --fa: "\e22d";
+}
+
+.fa-rupiah-sign {
+ --fa: "\e23d";
+}
+
+.fa-stairs {
+ --fa: "\e289";
+}
+
+.fa-timeline {
+ --fa: "\e29c";
+}
+
+.fa-truck-front {
+ --fa: "\e2b7";
+}
+
+.fa-turkish-lira-sign {
+ --fa: "\e2bb";
+}
+
+.fa-try {
+ --fa: "\e2bb";
+}
+
+.fa-turkish-lira {
+ --fa: "\e2bb";
+}
+
+.fa-vault {
+ --fa: "\e2c5";
+}
+
+.fa-wand-magic-sparkles {
+ --fa: "\e2ca";
+}
+
+.fa-magic-wand-sparkles {
+ --fa: "\e2ca";
+}
+
+.fa-wheat-awn {
+ --fa: "\e2cd";
+}
+
+.fa-wheat-alt {
+ --fa: "\e2cd";
+}
+
+.fa-wheelchair-move {
+ --fa: "\e2ce";
+}
+
+.fa-wheelchair-alt {
+ --fa: "\e2ce";
+}
+
+.fa-bangladeshi-taka-sign {
+ --fa: "\e2e6";
+}
+
+.fa-bowl-rice {
+ --fa: "\e2eb";
+}
+
+.fa-person-pregnant {
+ --fa: "\e31e";
+}
+
+.fa-house-chimney {
+ --fa: "\e3af";
+}
+
+.fa-home-lg {
+ --fa: "\e3af";
+}
+
+.fa-house-crack {
+ --fa: "\e3b1";
+}
+
+.fa-house-medical {
+ --fa: "\e3b2";
+}
+
+.fa-cent-sign {
+ --fa: "\e3f5";
+}
+
+.fa-plus-minus {
+ --fa: "\e43c";
+}
+
+.fa-sailboat {
+ --fa: "\e445";
+}
+
+.fa-section {
+ --fa: "\e447";
+}
+
+.fa-shrimp {
+ --fa: "\e448";
+}
+
+.fa-brazilian-real-sign {
+ --fa: "\e46c";
+}
+
+.fa-chart-simple {
+ --fa: "\e473";
+}
+
+.fa-diagram-next {
+ --fa: "\e476";
+}
+
+.fa-diagram-predecessor {
+ --fa: "\e477";
+}
+
+.fa-diagram-successor {
+ --fa: "\e47a";
+}
+
+.fa-earth-oceania {
+ --fa: "\e47b";
+}
+
+.fa-globe-oceania {
+ --fa: "\e47b";
+}
+
+.fa-bug-slash {
+ --fa: "\e490";
+}
+
+.fa-file-circle-plus {
+ --fa: "\e494";
+}
+
+.fa-shop-lock {
+ --fa: "\e4a5";
+}
+
+.fa-virus-covid {
+ --fa: "\e4a8";
+}
+
+.fa-virus-covid-slash {
+ --fa: "\e4a9";
+}
+
+.fa-anchor-circle-check {
+ --fa: "\e4aa";
+}
+
+.fa-anchor-circle-exclamation {
+ --fa: "\e4ab";
+}
+
+.fa-anchor-circle-xmark {
+ --fa: "\e4ac";
+}
+
+.fa-anchor-lock {
+ --fa: "\e4ad";
+}
+
+.fa-arrow-down-up-across-line {
+ --fa: "\e4af";
+}
+
+.fa-arrow-down-up-lock {
+ --fa: "\e4b0";
+}
+
+.fa-arrow-right-to-city {
+ --fa: "\e4b3";
+}
+
+.fa-arrow-up-from-ground-water {
+ --fa: "\e4b5";
+}
+
+.fa-arrow-up-from-water-pump {
+ --fa: "\e4b6";
+}
+
+.fa-arrow-up-right-dots {
+ --fa: "\e4b7";
+}
+
+.fa-arrows-down-to-line {
+ --fa: "\e4b8";
+}
+
+.fa-arrows-down-to-people {
+ --fa: "\e4b9";
+}
+
+.fa-arrows-left-right-to-line {
+ --fa: "\e4ba";
+}
+
+.fa-arrows-spin {
+ --fa: "\e4bb";
+}
+
+.fa-arrows-split-up-and-left {
+ --fa: "\e4bc";
+}
+
+.fa-arrows-to-circle {
+ --fa: "\e4bd";
+}
+
+.fa-arrows-to-dot {
+ --fa: "\e4be";
+}
+
+.fa-arrows-to-eye {
+ --fa: "\e4bf";
+}
+
+.fa-arrows-turn-right {
+ --fa: "\e4c0";
+}
+
+.fa-arrows-turn-to-dots {
+ --fa: "\e4c1";
+}
+
+.fa-arrows-up-to-line {
+ --fa: "\e4c2";
+}
+
+.fa-bore-hole {
+ --fa: "\e4c3";
+}
+
+.fa-bottle-droplet {
+ --fa: "\e4c4";
+}
+
+.fa-bottle-water {
+ --fa: "\e4c5";
+}
+
+.fa-bowl-food {
+ --fa: "\e4c6";
+}
+
+.fa-boxes-packing {
+ --fa: "\e4c7";
+}
+
+.fa-bridge {
+ --fa: "\e4c8";
+}
+
+.fa-bridge-circle-check {
+ --fa: "\e4c9";
+}
+
+.fa-bridge-circle-exclamation {
+ --fa: "\e4ca";
+}
+
+.fa-bridge-circle-xmark {
+ --fa: "\e4cb";
+}
+
+.fa-bridge-lock {
+ --fa: "\e4cc";
+}
+
+.fa-bridge-water {
+ --fa: "\e4ce";
+}
+
+.fa-bucket {
+ --fa: "\e4cf";
+}
+
+.fa-bugs {
+ --fa: "\e4d0";
+}
+
+.fa-building-circle-arrow-right {
+ --fa: "\e4d1";
+}
+
+.fa-building-circle-check {
+ --fa: "\e4d2";
+}
+
+.fa-building-circle-exclamation {
+ --fa: "\e4d3";
+}
+
+.fa-building-circle-xmark {
+ --fa: "\e4d4";
+}
+
+.fa-building-flag {
+ --fa: "\e4d5";
+}
+
+.fa-building-lock {
+ --fa: "\e4d6";
+}
+
+.fa-building-ngo {
+ --fa: "\e4d7";
+}
+
+.fa-building-shield {
+ --fa: "\e4d8";
+}
+
+.fa-building-un {
+ --fa: "\e4d9";
+}
+
+.fa-building-user {
+ --fa: "\e4da";
+}
+
+.fa-building-wheat {
+ --fa: "\e4db";
+}
+
+.fa-burst {
+ --fa: "\e4dc";
+}
+
+.fa-car-on {
+ --fa: "\e4dd";
+}
+
+.fa-car-tunnel {
+ --fa: "\e4de";
+}
+
+.fa-child-combatant {
+ --fa: "\e4e0";
+}
+
+.fa-child-rifle {
+ --fa: "\e4e0";
+}
+
+.fa-children {
+ --fa: "\e4e1";
+}
+
+.fa-circle-nodes {
+ --fa: "\e4e2";
+}
+
+.fa-clipboard-question {
+ --fa: "\e4e3";
+}
+
+.fa-cloud-showers-water {
+ --fa: "\e4e4";
+}
+
+.fa-computer {
+ --fa: "\e4e5";
+}
+
+.fa-cubes-stacked {
+ --fa: "\e4e6";
+}
+
+.fa-envelope-circle-check {
+ --fa: "\e4e8";
+}
+
+.fa-explosion {
+ --fa: "\e4e9";
+}
+
+.fa-ferry {
+ --fa: "\e4ea";
+}
+
+.fa-file-circle-exclamation {
+ --fa: "\e4eb";
+}
+
+.fa-file-circle-minus {
+ --fa: "\e4ed";
+}
+
+.fa-file-circle-question {
+ --fa: "\e4ef";
+}
+
+.fa-file-shield {
+ --fa: "\e4f0";
+}
+
+.fa-fire-burner {
+ --fa: "\e4f1";
+}
+
+.fa-fish-fins {
+ --fa: "\e4f2";
+}
+
+.fa-flask-vial {
+ --fa: "\e4f3";
+}
+
+.fa-glass-water {
+ --fa: "\e4f4";
+}
+
+.fa-glass-water-droplet {
+ --fa: "\e4f5";
+}
+
+.fa-group-arrows-rotate {
+ --fa: "\e4f6";
+}
+
+.fa-hand-holding-hand {
+ --fa: "\e4f7";
+}
+
+.fa-handcuffs {
+ --fa: "\e4f8";
+}
+
+.fa-hands-bound {
+ --fa: "\e4f9";
+}
+
+.fa-hands-holding-child {
+ --fa: "\e4fa";
+}
+
+.fa-hands-holding-circle {
+ --fa: "\e4fb";
+}
+
+.fa-heart-circle-bolt {
+ --fa: "\e4fc";
+}
+
+.fa-heart-circle-check {
+ --fa: "\e4fd";
+}
+
+.fa-heart-circle-exclamation {
+ --fa: "\e4fe";
+}
+
+.fa-heart-circle-minus {
+ --fa: "\e4ff";
+}
+
+.fa-heart-circle-plus {
+ --fa: "\e500";
+}
+
+.fa-heart-circle-xmark {
+ --fa: "\e501";
+}
+
+.fa-helicopter-symbol {
+ --fa: "\e502";
+}
+
+.fa-helmet-un {
+ --fa: "\e503";
+}
+
+.fa-hill-avalanche {
+ --fa: "\e507";
+}
+
+.fa-hill-rockslide {
+ --fa: "\e508";
+}
+
+.fa-house-circle-check {
+ --fa: "\e509";
+}
+
+.fa-house-circle-exclamation {
+ --fa: "\e50a";
+}
+
+.fa-house-circle-xmark {
+ --fa: "\e50b";
+}
+
+.fa-house-fire {
+ --fa: "\e50c";
+}
+
+.fa-house-flag {
+ --fa: "\e50d";
+}
+
+.fa-house-flood-water {
+ --fa: "\e50e";
+}
+
+.fa-house-flood-water-circle-arrow-right {
+ --fa: "\e50f";
+}
+
+.fa-house-lock {
+ --fa: "\e510";
+}
+
+.fa-house-medical-circle-check {
+ --fa: "\e511";
+}
+
+.fa-house-medical-circle-exclamation {
+ --fa: "\e512";
+}
+
+.fa-house-medical-circle-xmark {
+ --fa: "\e513";
+}
+
+.fa-house-medical-flag {
+ --fa: "\e514";
+}
+
+.fa-house-tsunami {
+ --fa: "\e515";
+}
+
+.fa-jar {
+ --fa: "\e516";
+}
+
+.fa-jar-wheat {
+ --fa: "\e517";
+}
+
+.fa-jet-fighter-up {
+ --fa: "\e518";
+}
+
+.fa-jug-detergent {
+ --fa: "\e519";
+}
+
+.fa-kitchen-set {
+ --fa: "\e51a";
+}
+
+.fa-land-mine-on {
+ --fa: "\e51b";
+}
+
+.fa-landmark-flag {
+ --fa: "\e51c";
+}
+
+.fa-laptop-file {
+ --fa: "\e51d";
+}
+
+.fa-lines-leaning {
+ --fa: "\e51e";
+}
+
+.fa-location-pin-lock {
+ --fa: "\e51f";
+}
+
+.fa-locust {
+ --fa: "\e520";
+}
+
+.fa-magnifying-glass-arrow-right {
+ --fa: "\e521";
+}
+
+.fa-magnifying-glass-chart {
+ --fa: "\e522";
+}
+
+.fa-mars-and-venus-burst {
+ --fa: "\e523";
+}
+
+.fa-mask-ventilator {
+ --fa: "\e524";
+}
+
+.fa-mattress-pillow {
+ --fa: "\e525";
+}
+
+.fa-mobile-retro {
+ --fa: "\e527";
+}
+
+.fa-money-bill-transfer {
+ --fa: "\e528";
+}
+
+.fa-money-bill-trend-up {
+ --fa: "\e529";
+}
+
+.fa-money-bill-wheat {
+ --fa: "\e52a";
+}
+
+.fa-mosquito {
+ --fa: "\e52b";
+}
+
+.fa-mosquito-net {
+ --fa: "\e52c";
+}
+
+.fa-mound {
+ --fa: "\e52d";
+}
+
+.fa-mountain-city {
+ --fa: "\e52e";
+}
+
+.fa-mountain-sun {
+ --fa: "\e52f";
+}
+
+.fa-oil-well {
+ --fa: "\e532";
+}
+
+.fa-people-group {
+ --fa: "\e533";
+}
+
+.fa-people-line {
+ --fa: "\e534";
+}
+
+.fa-people-pulling {
+ --fa: "\e535";
+}
+
+.fa-people-robbery {
+ --fa: "\e536";
+}
+
+.fa-people-roof {
+ --fa: "\e537";
+}
+
+.fa-person-arrow-down-to-line {
+ --fa: "\e538";
+}
+
+.fa-person-arrow-up-from-line {
+ --fa: "\e539";
+}
+
+.fa-person-breastfeeding {
+ --fa: "\e53a";
+}
+
+.fa-person-burst {
+ --fa: "\e53b";
+}
+
+.fa-person-cane {
+ --fa: "\e53c";
+}
+
+.fa-person-chalkboard {
+ --fa: "\e53d";
+}
+
+.fa-person-circle-check {
+ --fa: "\e53e";
+}
+
+.fa-person-circle-exclamation {
+ --fa: "\e53f";
+}
+
+.fa-person-circle-minus {
+ --fa: "\e540";
+}
+
+.fa-person-circle-plus {
+ --fa: "\e541";
+}
+
+.fa-person-circle-question {
+ --fa: "\e542";
+}
+
+.fa-person-circle-xmark {
+ --fa: "\e543";
+}
+
+.fa-person-dress-burst {
+ --fa: "\e544";
+}
+
+.fa-person-drowning {
+ --fa: "\e545";
+}
+
+.fa-person-falling {
+ --fa: "\e546";
+}
+
+.fa-person-falling-burst {
+ --fa: "\e547";
+}
+
+.fa-person-half-dress {
+ --fa: "\e548";
+}
+
+.fa-person-harassing {
+ --fa: "\e549";
+}
+
+.fa-person-military-pointing {
+ --fa: "\e54a";
+}
+
+.fa-person-military-rifle {
+ --fa: "\e54b";
+}
+
+.fa-person-military-to-person {
+ --fa: "\e54c";
+}
+
+.fa-person-rays {
+ --fa: "\e54d";
+}
+
+.fa-person-rifle {
+ --fa: "\e54e";
+}
+
+.fa-person-shelter {
+ --fa: "\e54f";
+}
+
+.fa-person-walking-arrow-loop-left {
+ --fa: "\e551";
+}
+
+.fa-person-walking-arrow-right {
+ --fa: "\e552";
+}
+
+.fa-person-walking-dashed-line-arrow-right {
+ --fa: "\e553";
+}
+
+.fa-person-walking-luggage {
+ --fa: "\e554";
+}
+
+.fa-plane-circle-check {
+ --fa: "\e555";
+}
+
+.fa-plane-circle-exclamation {
+ --fa: "\e556";
+}
+
+.fa-plane-circle-xmark {
+ --fa: "\e557";
+}
+
+.fa-plane-lock {
+ --fa: "\e558";
+}
+
+.fa-plate-wheat {
+ --fa: "\e55a";
+}
+
+.fa-plug-circle-bolt {
+ --fa: "\e55b";
+}
+
+.fa-plug-circle-check {
+ --fa: "\e55c";
+}
+
+.fa-plug-circle-exclamation {
+ --fa: "\e55d";
+}
+
+.fa-plug-circle-minus {
+ --fa: "\e55e";
+}
+
+.fa-plug-circle-plus {
+ --fa: "\e55f";
+}
+
+.fa-plug-circle-xmark {
+ --fa: "\e560";
+}
+
+.fa-ranking-star {
+ --fa: "\e561";
+}
+
+.fa-road-barrier {
+ --fa: "\e562";
+}
+
+.fa-road-bridge {
+ --fa: "\e563";
+}
+
+.fa-road-circle-check {
+ --fa: "\e564";
+}
+
+.fa-road-circle-exclamation {
+ --fa: "\e565";
+}
+
+.fa-road-circle-xmark {
+ --fa: "\e566";
+}
+
+.fa-road-lock {
+ --fa: "\e567";
+}
+
+.fa-road-spikes {
+ --fa: "\e568";
+}
+
+.fa-rug {
+ --fa: "\e569";
+}
+
+.fa-sack-xmark {
+ --fa: "\e56a";
+}
+
+.fa-school-circle-check {
+ --fa: "\e56b";
+}
+
+.fa-school-circle-exclamation {
+ --fa: "\e56c";
+}
+
+.fa-school-circle-xmark {
+ --fa: "\e56d";
+}
+
+.fa-school-flag {
+ --fa: "\e56e";
+}
+
+.fa-school-lock {
+ --fa: "\e56f";
+}
+
+.fa-sheet-plastic {
+ --fa: "\e571";
+}
+
+.fa-shield-cat {
+ --fa: "\e572";
+}
+
+.fa-shield-dog {
+ --fa: "\e573";
+}
+
+.fa-shield-heart {
+ --fa: "\e574";
+}
+
+.fa-square-nfi {
+ --fa: "\e576";
+}
+
+.fa-square-person-confined {
+ --fa: "\e577";
+}
+
+.fa-square-virus {
+ --fa: "\e578";
+}
+
+.fa-staff-snake {
+ --fa: "\e579";
+}
+
+.fa-rod-asclepius {
+ --fa: "\e579";
+}
+
+.fa-rod-snake {
+ --fa: "\e579";
+}
+
+.fa-staff-aesculapius {
+ --fa: "\e579";
+}
+
+.fa-sun-plant-wilt {
+ --fa: "\e57a";
+}
+
+.fa-tarp {
+ --fa: "\e57b";
+}
+
+.fa-tarp-droplet {
+ --fa: "\e57c";
+}
+
+.fa-tent {
+ --fa: "\e57d";
+}
+
+.fa-tent-arrow-down-to-line {
+ --fa: "\e57e";
+}
+
+.fa-tent-arrow-left-right {
+ --fa: "\e57f";
+}
+
+.fa-tent-arrow-turn-left {
+ --fa: "\e580";
+}
+
+.fa-tent-arrows-down {
+ --fa: "\e581";
+}
+
+.fa-tents {
+ --fa: "\e582";
+}
+
+.fa-toilet-portable {
+ --fa: "\e583";
+}
+
+.fa-toilets-portable {
+ --fa: "\e584";
+}
+
+.fa-tower-cell {
+ --fa: "\e585";
+}
+
+.fa-tower-observation {
+ --fa: "\e586";
+}
+
+.fa-tree-city {
+ --fa: "\e587";
+}
+
+.fa-trowel {
+ --fa: "\e589";
+}
+
+.fa-trowel-bricks {
+ --fa: "\e58a";
+}
+
+.fa-truck-arrow-right {
+ --fa: "\e58b";
+}
+
+.fa-truck-droplet {
+ --fa: "\e58c";
+}
+
+.fa-truck-field {
+ --fa: "\e58d";
+}
+
+.fa-truck-field-un {
+ --fa: "\e58e";
+}
+
+.fa-truck-plane {
+ --fa: "\e58f";
+}
+
+.fa-users-between-lines {
+ --fa: "\e591";
+}
+
+.fa-users-line {
+ --fa: "\e592";
+}
+
+.fa-users-rays {
+ --fa: "\e593";
+}
+
+.fa-users-rectangle {
+ --fa: "\e594";
+}
+
+.fa-users-viewfinder {
+ --fa: "\e595";
+}
+
+.fa-vial-circle-check {
+ --fa: "\e596";
+}
+
+.fa-vial-virus {
+ --fa: "\e597";
+}
+
+.fa-wheat-awn-circle-exclamation {
+ --fa: "\e598";
+}
+
+.fa-worm {
+ --fa: "\e599";
+}
+
+.fa-xmarks-lines {
+ --fa: "\e59a";
+}
+
+.fa-child-dress {
+ --fa: "\e59c";
+}
+
+.fa-child-reaching {
+ --fa: "\e59d";
+}
+
+.fa-file-circle-check {
+ --fa: "\e5a0";
+}
+
+.fa-file-circle-xmark {
+ --fa: "\e5a1";
+}
+
+.fa-person-through-window {
+ --fa: "\e5a9";
+}
+
+.fa-plant-wilt {
+ --fa: "\e5aa";
+}
+
+.fa-stapler {
+ --fa: "\e5af";
+}
+
+.fa-train-tram {
+ --fa: "\e5b4";
+}
+
+.fa-table-cells-column-lock {
+ --fa: "\e678";
+}
+
+.fa-table-cells-row-lock {
+ --fa: "\e67a";
+}
+
+.fa-web-awesome {
+ --fa: "\e682";
+}
+
+.fa-thumbtack-slash {
+ --fa: "\e68f";
+}
+
+.fa-thumb-tack-slash {
+ --fa: "\e68f";
+}
+
+.fa-table-cells-row-unlock {
+ --fa: "\e691";
+}
+
+.fa-chart-diagram {
+ --fa: "\e695";
+}
+
+.fa-comment-nodes {
+ --fa: "\e696";
+}
+
+.fa-file-fragment {
+ --fa: "\e697";
+}
+
+.fa-file-half-dashed {
+ --fa: "\e698";
+}
+
+.fa-hexagon-nodes {
+ --fa: "\e699";
+}
+
+.fa-hexagon-nodes-bolt {
+ --fa: "\e69a";
+}
+
+.fa-square-binary {
+ --fa: "\e69b";
+}
+
+.fa-pentagon {
+ --fa: "\e790";
+}
+
+.fa-non-binary {
+ --fa: "\e807";
+}
+
+.fa-spiral {
+ --fa: "\e80a";
+}
+
+.fa-mobile-vibrate {
+ --fa: "\e816";
+}
+
+.fa-single-quote-left {
+ --fa: "\e81b";
+}
+
+.fa-single-quote-right {
+ --fa: "\e81c";
+}
+
+.fa-bus-side {
+ --fa: "\e81d";
+}
+
+.fa-septagon {
+ --fa: "\e820";
+}
+
+.fa-heptagon {
+ --fa: "\e820";
+}
+
+.fa-martini-glass-empty {
+ --fa: "\f000";
+}
+
+.fa-glass-martini {
+ --fa: "\f000";
+}
+
+.fa-music {
+ --fa: "\f001";
+}
+
+.fa-magnifying-glass {
+ --fa: "\f002";
+}
+
+.fa-search {
+ --fa: "\f002";
+}
+
+.fa-heart {
+ --fa: "\f004";
+}
+
+.fa-star {
+ --fa: "\f005";
+}
+
+.fa-user {
+ --fa: "\f007";
+}
+
+.fa-user-alt {
+ --fa: "\f007";
+}
+
+.fa-user-large {
+ --fa: "\f007";
+}
+
+.fa-film {
+ --fa: "\f008";
+}
+
+.fa-film-alt {
+ --fa: "\f008";
+}
+
+.fa-film-simple {
+ --fa: "\f008";
+}
+
+.fa-table-cells-large {
+ --fa: "\f009";
+}
+
+.fa-th-large {
+ --fa: "\f009";
+}
+
+.fa-table-cells {
+ --fa: "\f00a";
+}
+
+.fa-th {
+ --fa: "\f00a";
+}
+
+.fa-table-list {
+ --fa: "\f00b";
+}
+
+.fa-th-list {
+ --fa: "\f00b";
+}
+
+.fa-check {
+ --fa: "\f00c";
+}
+
+.fa-xmark {
+ --fa: "\f00d";
+}
+
+.fa-close {
+ --fa: "\f00d";
+}
+
+.fa-multiply {
+ --fa: "\f00d";
+}
+
+.fa-remove {
+ --fa: "\f00d";
+}
+
+.fa-times {
+ --fa: "\f00d";
+}
+
+.fa-magnifying-glass-plus {
+ --fa: "\f00e";
+}
+
+.fa-search-plus {
+ --fa: "\f00e";
+}
+
+.fa-magnifying-glass-minus {
+ --fa: "\f010";
+}
+
+.fa-search-minus {
+ --fa: "\f010";
+}
+
+.fa-power-off {
+ --fa: "\f011";
+}
+
+.fa-signal {
+ --fa: "\f012";
+}
+
+.fa-signal-5 {
+ --fa: "\f012";
+}
+
+.fa-signal-perfect {
+ --fa: "\f012";
+}
+
+.fa-gear {
+ --fa: "\f013";
+}
+
+.fa-cog {
+ --fa: "\f013";
+}
+
+.fa-house {
+ --fa: "\f015";
+}
+
+.fa-home {
+ --fa: "\f015";
+}
+
+.fa-home-alt {
+ --fa: "\f015";
+}
+
+.fa-home-lg-alt {
+ --fa: "\f015";
+}
+
+.fa-clock {
+ --fa: "\f017";
+}
+
+.fa-clock-four {
+ --fa: "\f017";
+}
+
+.fa-road {
+ --fa: "\f018";
+}
+
+.fa-download {
+ --fa: "\f019";
+}
+
+.fa-inbox {
+ --fa: "\f01c";
+}
+
+.fa-arrow-rotate-right {
+ --fa: "\f01e";
+}
+
+.fa-arrow-right-rotate {
+ --fa: "\f01e";
+}
+
+.fa-arrow-rotate-forward {
+ --fa: "\f01e";
+}
+
+.fa-redo {
+ --fa: "\f01e";
+}
+
+.fa-arrows-rotate {
+ --fa: "\f021";
+}
+
+.fa-refresh {
+ --fa: "\f021";
+}
+
+.fa-sync {
+ --fa: "\f021";
+}
+
+.fa-rectangle-list {
+ --fa: "\f022";
+}
+
+.fa-list-alt {
+ --fa: "\f022";
+}
+
+.fa-lock {
+ --fa: "\f023";
+}
+
+.fa-flag {
+ --fa: "\f024";
+}
+
+.fa-headphones {
+ --fa: "\f025";
+}
+
+.fa-headphones-alt {
+ --fa: "\f025";
+}
+
+.fa-headphones-simple {
+ --fa: "\f025";
+}
+
+.fa-volume-off {
+ --fa: "\f026";
+}
+
+.fa-volume-low {
+ --fa: "\f027";
+}
+
+.fa-volume-down {
+ --fa: "\f027";
+}
+
+.fa-volume-high {
+ --fa: "\f028";
+}
+
+.fa-volume-up {
+ --fa: "\f028";
+}
+
+.fa-qrcode {
+ --fa: "\f029";
+}
+
+.fa-barcode {
+ --fa: "\f02a";
+}
+
+.fa-tag {
+ --fa: "\f02b";
+}
+
+.fa-tags {
+ --fa: "\f02c";
+}
+
+.fa-book {
+ --fa: "\f02d";
+}
+
+.fa-bookmark {
+ --fa: "\f02e";
+}
+
+.fa-print {
+ --fa: "\f02f";
+}
+
+.fa-camera {
+ --fa: "\f030";
+}
+
+.fa-camera-alt {
+ --fa: "\f030";
+}
+
+.fa-font {
+ --fa: "\f031";
+}
+
+.fa-bold {
+ --fa: "\f032";
+}
+
+.fa-italic {
+ --fa: "\f033";
+}
+
+.fa-text-height {
+ --fa: "\f034";
+}
+
+.fa-text-width {
+ --fa: "\f035";
+}
+
+.fa-align-left {
+ --fa: "\f036";
+}
+
+.fa-align-center {
+ --fa: "\f037";
+}
+
+.fa-align-right {
+ --fa: "\f038";
+}
+
+.fa-align-justify {
+ --fa: "\f039";
+}
+
+.fa-list {
+ --fa: "\f03a";
+}
+
+.fa-list-squares {
+ --fa: "\f03a";
+}
+
+.fa-outdent {
+ --fa: "\f03b";
+}
+
+.fa-dedent {
+ --fa: "\f03b";
+}
+
+.fa-indent {
+ --fa: "\f03c";
+}
+
+.fa-video {
+ --fa: "\f03d";
+}
+
+.fa-video-camera {
+ --fa: "\f03d";
+}
+
+.fa-image {
+ --fa: "\f03e";
+}
+
+.fa-location-pin {
+ --fa: "\f041";
+}
+
+.fa-map-marker {
+ --fa: "\f041";
+}
+
+.fa-circle-half-stroke {
+ --fa: "\f042";
+}
+
+.fa-adjust {
+ --fa: "\f042";
+}
+
+.fa-droplet {
+ --fa: "\f043";
+}
+
+.fa-tint {
+ --fa: "\f043";
+}
+
+.fa-pen-to-square {
+ --fa: "\f044";
+}
+
+.fa-edit {
+ --fa: "\f044";
+}
+
+.fa-arrows-up-down-left-right {
+ --fa: "\f047";
+}
+
+.fa-arrows {
+ --fa: "\f047";
+}
+
+.fa-backward-step {
+ --fa: "\f048";
+}
+
+.fa-step-backward {
+ --fa: "\f048";
+}
+
+.fa-backward-fast {
+ --fa: "\f049";
+}
+
+.fa-fast-backward {
+ --fa: "\f049";
+}
+
+.fa-backward {
+ --fa: "\f04a";
+}
+
+.fa-play {
+ --fa: "\f04b";
+}
+
+.fa-pause {
+ --fa: "\f04c";
+}
+
+.fa-stop {
+ --fa: "\f04d";
+}
+
+.fa-forward {
+ --fa: "\f04e";
+}
+
+.fa-forward-fast {
+ --fa: "\f050";
+}
+
+.fa-fast-forward {
+ --fa: "\f050";
+}
+
+.fa-forward-step {
+ --fa: "\f051";
+}
+
+.fa-step-forward {
+ --fa: "\f051";
+}
+
+.fa-eject {
+ --fa: "\f052";
+}
+
+.fa-chevron-left {
+ --fa: "\f053";
+}
+
+.fa-chevron-right {
+ --fa: "\f054";
+}
+
+.fa-circle-plus {
+ --fa: "\f055";
+}
+
+.fa-plus-circle {
+ --fa: "\f055";
+}
+
+.fa-circle-minus {
+ --fa: "\f056";
+}
+
+.fa-minus-circle {
+ --fa: "\f056";
+}
+
+.fa-circle-xmark {
+ --fa: "\f057";
+}
+
+.fa-times-circle {
+ --fa: "\f057";
+}
+
+.fa-xmark-circle {
+ --fa: "\f057";
+}
+
+.fa-circle-check {
+ --fa: "\f058";
+}
+
+.fa-check-circle {
+ --fa: "\f058";
+}
+
+.fa-circle-question {
+ --fa: "\f059";
+}
+
+.fa-question-circle {
+ --fa: "\f059";
+}
+
+.fa-circle-info {
+ --fa: "\f05a";
+}
+
+.fa-info-circle {
+ --fa: "\f05a";
+}
+
+.fa-crosshairs {
+ --fa: "\f05b";
+}
+
+.fa-ban {
+ --fa: "\f05e";
+}
+
+.fa-cancel {
+ --fa: "\f05e";
+}
+
+.fa-arrow-left {
+ --fa: "\f060";
+}
+
+.fa-arrow-right {
+ --fa: "\f061";
+}
+
+.fa-arrow-up {
+ --fa: "\f062";
+}
+
+.fa-arrow-down {
+ --fa: "\f063";
+}
+
+.fa-share {
+ --fa: "\f064";
+}
+
+.fa-mail-forward {
+ --fa: "\f064";
+}
+
+.fa-expand {
+ --fa: "\f065";
+}
+
+.fa-compress {
+ --fa: "\f066";
+}
+
+.fa-minus {
+ --fa: "\f068";
+}
+
+.fa-subtract {
+ --fa: "\f068";
+}
+
+.fa-circle-exclamation {
+ --fa: "\f06a";
+}
+
+.fa-exclamation-circle {
+ --fa: "\f06a";
+}
+
+.fa-gift {
+ --fa: "\f06b";
+}
+
+.fa-leaf {
+ --fa: "\f06c";
+}
+
+.fa-fire {
+ --fa: "\f06d";
+}
+
+.fa-eye {
+ --fa: "\f06e";
+}
+
+.fa-eye-slash {
+ --fa: "\f070";
+}
+
+.fa-triangle-exclamation {
+ --fa: "\f071";
+}
+
+.fa-exclamation-triangle {
+ --fa: "\f071";
+}
+
+.fa-warning {
+ --fa: "\f071";
+}
+
+.fa-plane {
+ --fa: "\f072";
+}
+
+.fa-calendar-days {
+ --fa: "\f073";
+}
+
+.fa-calendar-alt {
+ --fa: "\f073";
+}
+
+.fa-shuffle {
+ --fa: "\f074";
+}
+
+.fa-random {
+ --fa: "\f074";
+}
+
+.fa-comment {
+ --fa: "\f075";
+}
+
+.fa-magnet {
+ --fa: "\f076";
+}
+
+.fa-chevron-up {
+ --fa: "\f077";
+}
+
+.fa-chevron-down {
+ --fa: "\f078";
+}
+
+.fa-retweet {
+ --fa: "\f079";
+}
+
+.fa-cart-shopping {
+ --fa: "\f07a";
+}
+
+.fa-shopping-cart {
+ --fa: "\f07a";
+}
+
+.fa-folder {
+ --fa: "\f07b";
+}
+
+.fa-folder-blank {
+ --fa: "\f07b";
+}
+
+.fa-folder-open {
+ --fa: "\f07c";
+}
+
+.fa-arrows-up-down {
+ --fa: "\f07d";
+}
+
+.fa-arrows-v {
+ --fa: "\f07d";
+}
+
+.fa-arrows-left-right {
+ --fa: "\f07e";
+}
+
+.fa-arrows-h {
+ --fa: "\f07e";
+}
+
+.fa-chart-bar {
+ --fa: "\f080";
+}
+
+.fa-bar-chart {
+ --fa: "\f080";
+}
+
+.fa-camera-retro {
+ --fa: "\f083";
+}
+
+.fa-key {
+ --fa: "\f084";
+}
+
+.fa-gears {
+ --fa: "\f085";
+}
+
+.fa-cogs {
+ --fa: "\f085";
+}
+
+.fa-comments {
+ --fa: "\f086";
+}
+
+.fa-star-half {
+ --fa: "\f089";
+}
+
+.fa-arrow-right-from-bracket {
+ --fa: "\f08b";
+}
+
+.fa-sign-out {
+ --fa: "\f08b";
+}
+
+.fa-thumbtack {
+ --fa: "\f08d";
+}
+
+.fa-thumb-tack {
+ --fa: "\f08d";
+}
+
+.fa-arrow-up-right-from-square {
+ --fa: "\f08e";
+}
+
+.fa-external-link {
+ --fa: "\f08e";
+}
+
+.fa-arrow-right-to-bracket {
+ --fa: "\f090";
+}
+
+.fa-sign-in {
+ --fa: "\f090";
+}
+
+.fa-trophy {
+ --fa: "\f091";
+}
+
+.fa-upload {
+ --fa: "\f093";
+}
+
+.fa-lemon {
+ --fa: "\f094";
+}
+
+.fa-phone {
+ --fa: "\f095";
+}
+
+.fa-square-phone {
+ --fa: "\f098";
+}
+
+.fa-phone-square {
+ --fa: "\f098";
+}
+
+.fa-unlock {
+ --fa: "\f09c";
+}
+
+.fa-credit-card {
+ --fa: "\f09d";
+}
+
+.fa-credit-card-alt {
+ --fa: "\f09d";
+}
+
+.fa-rss {
+ --fa: "\f09e";
+}
+
+.fa-feed {
+ --fa: "\f09e";
+}
+
+.fa-hard-drive {
+ --fa: "\f0a0";
+}
+
+.fa-hdd {
+ --fa: "\f0a0";
+}
+
+.fa-bullhorn {
+ --fa: "\f0a1";
+}
+
+.fa-certificate {
+ --fa: "\f0a3";
+}
+
+.fa-hand-point-right {
+ --fa: "\f0a4";
+}
+
+.fa-hand-point-left {
+ --fa: "\f0a5";
+}
+
+.fa-hand-point-up {
+ --fa: "\f0a6";
+}
+
+.fa-hand-point-down {
+ --fa: "\f0a7";
+}
+
+.fa-circle-arrow-left {
+ --fa: "\f0a8";
+}
+
+.fa-arrow-circle-left {
+ --fa: "\f0a8";
+}
+
+.fa-circle-arrow-right {
+ --fa: "\f0a9";
+}
+
+.fa-arrow-circle-right {
+ --fa: "\f0a9";
+}
+
+.fa-circle-arrow-up {
+ --fa: "\f0aa";
+}
+
+.fa-arrow-circle-up {
+ --fa: "\f0aa";
+}
+
+.fa-circle-arrow-down {
+ --fa: "\f0ab";
+}
+
+.fa-arrow-circle-down {
+ --fa: "\f0ab";
+}
+
+.fa-globe {
+ --fa: "\f0ac";
+}
+
+.fa-wrench {
+ --fa: "\f0ad";
+}
+
+.fa-list-check {
+ --fa: "\f0ae";
+}
+
+.fa-tasks {
+ --fa: "\f0ae";
+}
+
+.fa-filter {
+ --fa: "\f0b0";
+}
+
+.fa-briefcase {
+ --fa: "\f0b1";
+}
+
+.fa-up-down-left-right {
+ --fa: "\f0b2";
+}
+
+.fa-arrows-alt {
+ --fa: "\f0b2";
+}
+
+.fa-users {
+ --fa: "\f0c0";
+}
+
+.fa-link {
+ --fa: "\f0c1";
+}
+
+.fa-chain {
+ --fa: "\f0c1";
+}
+
+.fa-cloud {
+ --fa: "\f0c2";
+}
+
+.fa-flask {
+ --fa: "\f0c3";
+}
+
+.fa-scissors {
+ --fa: "\f0c4";
+}
+
+.fa-cut {
+ --fa: "\f0c4";
+}
+
+.fa-copy {
+ --fa: "\f0c5";
+}
+
+.fa-paperclip {
+ --fa: "\f0c6";
+}
+
+.fa-floppy-disk {
+ --fa: "\f0c7";
+}
+
+.fa-save {
+ --fa: "\f0c7";
+}
+
+.fa-square {
+ --fa: "\f0c8";
+}
+
+.fa-bars {
+ --fa: "\f0c9";
+}
+
+.fa-navicon {
+ --fa: "\f0c9";
+}
+
+.fa-list-ul {
+ --fa: "\f0ca";
+}
+
+.fa-list-dots {
+ --fa: "\f0ca";
+}
+
+.fa-list-ol {
+ --fa: "\f0cb";
+}
+
+.fa-list-1-2 {
+ --fa: "\f0cb";
+}
+
+.fa-list-numeric {
+ --fa: "\f0cb";
+}
+
+.fa-strikethrough {
+ --fa: "\f0cc";
+}
+
+.fa-underline {
+ --fa: "\f0cd";
+}
+
+.fa-table {
+ --fa: "\f0ce";
+}
+
+.fa-wand-magic {
+ --fa: "\f0d0";
+}
+
+.fa-magic {
+ --fa: "\f0d0";
+}
+
+.fa-truck {
+ --fa: "\f0d1";
+}
+
+.fa-money-bill {
+ --fa: "\f0d6";
+}
+
+.fa-caret-down {
+ --fa: "\f0d7";
+}
+
+.fa-caret-up {
+ --fa: "\f0d8";
+}
+
+.fa-caret-left {
+ --fa: "\f0d9";
+}
+
+.fa-caret-right {
+ --fa: "\f0da";
+}
+
+.fa-table-columns {
+ --fa: "\f0db";
+}
+
+.fa-columns {
+ --fa: "\f0db";
+}
+
+.fa-sort {
+ --fa: "\f0dc";
+}
+
+.fa-unsorted {
+ --fa: "\f0dc";
+}
+
+.fa-sort-down {
+ --fa: "\f0dd";
+}
+
+.fa-sort-desc {
+ --fa: "\f0dd";
+}
+
+.fa-sort-up {
+ --fa: "\f0de";
+}
+
+.fa-sort-asc {
+ --fa: "\f0de";
+}
+
+.fa-envelope {
+ --fa: "\f0e0";
+}
+
+.fa-arrow-rotate-left {
+ --fa: "\f0e2";
+}
+
+.fa-arrow-left-rotate {
+ --fa: "\f0e2";
+}
+
+.fa-arrow-rotate-back {
+ --fa: "\f0e2";
+}
+
+.fa-arrow-rotate-backward {
+ --fa: "\f0e2";
+}
+
+.fa-undo {
+ --fa: "\f0e2";
+}
+
+.fa-gavel {
+ --fa: "\f0e3";
+}
+
+.fa-legal {
+ --fa: "\f0e3";
+}
+
+.fa-bolt {
+ --fa: "\f0e7";
+}
+
+.fa-zap {
+ --fa: "\f0e7";
+}
+
+.fa-sitemap {
+ --fa: "\f0e8";
+}
+
+.fa-umbrella {
+ --fa: "\f0e9";
+}
+
+.fa-paste {
+ --fa: "\f0ea";
+}
+
+.fa-file-clipboard {
+ --fa: "\f0ea";
+}
+
+.fa-lightbulb {
+ --fa: "\f0eb";
+}
+
+.fa-arrow-right-arrow-left {
+ --fa: "\f0ec";
+}
+
+.fa-exchange {
+ --fa: "\f0ec";
+}
+
+.fa-cloud-arrow-down {
+ --fa: "\f0ed";
+}
+
+.fa-cloud-download {
+ --fa: "\f0ed";
+}
+
+.fa-cloud-download-alt {
+ --fa: "\f0ed";
+}
+
+.fa-cloud-arrow-up {
+ --fa: "\f0ee";
+}
+
+.fa-cloud-upload {
+ --fa: "\f0ee";
+}
+
+.fa-cloud-upload-alt {
+ --fa: "\f0ee";
+}
+
+.fa-user-doctor {
+ --fa: "\f0f0";
+}
+
+.fa-user-md {
+ --fa: "\f0f0";
+}
+
+.fa-stethoscope {
+ --fa: "\f0f1";
+}
+
+.fa-suitcase {
+ --fa: "\f0f2";
+}
+
+.fa-bell {
+ --fa: "\f0f3";
+}
+
+.fa-mug-saucer {
+ --fa: "\f0f4";
+}
+
+.fa-coffee {
+ --fa: "\f0f4";
+}
+
+.fa-hospital {
+ --fa: "\f0f8";
+}
+
+.fa-hospital-alt {
+ --fa: "\f0f8";
+}
+
+.fa-hospital-wide {
+ --fa: "\f0f8";
+}
+
+.fa-truck-medical {
+ --fa: "\f0f9";
+}
+
+.fa-ambulance {
+ --fa: "\f0f9";
+}
+
+.fa-suitcase-medical {
+ --fa: "\f0fa";
+}
+
+.fa-medkit {
+ --fa: "\f0fa";
+}
+
+.fa-jet-fighter {
+ --fa: "\f0fb";
+}
+
+.fa-fighter-jet {
+ --fa: "\f0fb";
+}
+
+.fa-beer-mug-empty {
+ --fa: "\f0fc";
+}
+
+.fa-beer {
+ --fa: "\f0fc";
+}
+
+.fa-square-h {
+ --fa: "\f0fd";
+}
+
+.fa-h-square {
+ --fa: "\f0fd";
+}
+
+.fa-square-plus {
+ --fa: "\f0fe";
+}
+
+.fa-plus-square {
+ --fa: "\f0fe";
+}
+
+.fa-angles-left {
+ --fa: "\f100";
+}
+
+.fa-angle-double-left {
+ --fa: "\f100";
+}
+
+.fa-angles-right {
+ --fa: "\f101";
+}
+
+.fa-angle-double-right {
+ --fa: "\f101";
+}
+
+.fa-angles-up {
+ --fa: "\f102";
+}
+
+.fa-angle-double-up {
+ --fa: "\f102";
+}
+
+.fa-angles-down {
+ --fa: "\f103";
+}
+
+.fa-angle-double-down {
+ --fa: "\f103";
+}
+
+.fa-angle-left {
+ --fa: "\f104";
+}
+
+.fa-angle-right {
+ --fa: "\f105";
+}
+
+.fa-angle-up {
+ --fa: "\f106";
+}
+
+.fa-angle-down {
+ --fa: "\f107";
+}
+
+.fa-laptop {
+ --fa: "\f109";
+}
+
+.fa-tablet-button {
+ --fa: "\f10a";
+}
+
+.fa-mobile-button {
+ --fa: "\f10b";
+}
+
+.fa-quote-left {
+ --fa: "\f10d";
+}
+
+.fa-quote-left-alt {
+ --fa: "\f10d";
+}
+
+.fa-quote-right {
+ --fa: "\f10e";
+}
+
+.fa-quote-right-alt {
+ --fa: "\f10e";
+}
+
+.fa-spinner {
+ --fa: "\f110";
+}
+
+.fa-circle {
+ --fa: "\f111";
+}
+
+.fa-face-smile {
+ --fa: "\f118";
+}
+
+.fa-smile {
+ --fa: "\f118";
+}
+
+.fa-face-frown {
+ --fa: "\f119";
+}
+
+.fa-frown {
+ --fa: "\f119";
+}
+
+.fa-face-meh {
+ --fa: "\f11a";
+}
+
+.fa-meh {
+ --fa: "\f11a";
+}
+
+.fa-gamepad {
+ --fa: "\f11b";
+}
+
+.fa-keyboard {
+ --fa: "\f11c";
+}
+
+.fa-flag-checkered {
+ --fa: "\f11e";
+}
+
+.fa-terminal {
+ --fa: "\f120";
+}
+
+.fa-code {
+ --fa: "\f121";
+}
+
+.fa-reply-all {
+ --fa: "\f122";
+}
+
+.fa-mail-reply-all {
+ --fa: "\f122";
+}
+
+.fa-location-arrow {
+ --fa: "\f124";
+}
+
+.fa-crop {
+ --fa: "\f125";
+}
+
+.fa-code-branch {
+ --fa: "\f126";
+}
+
+.fa-link-slash {
+ --fa: "\f127";
+}
+
+.fa-chain-broken {
+ --fa: "\f127";
+}
+
+.fa-chain-slash {
+ --fa: "\f127";
+}
+
+.fa-unlink {
+ --fa: "\f127";
+}
+
+.fa-info {
+ --fa: "\f129";
+}
+
+.fa-superscript {
+ --fa: "\f12b";
+}
+
+.fa-subscript {
+ --fa: "\f12c";
+}
+
+.fa-eraser {
+ --fa: "\f12d";
+}
+
+.fa-puzzle-piece {
+ --fa: "\f12e";
+}
+
+.fa-microphone {
+ --fa: "\f130";
+}
+
+.fa-microphone-slash {
+ --fa: "\f131";
+}
+
+.fa-shield {
+ --fa: "\f132";
+}
+
+.fa-shield-blank {
+ --fa: "\f132";
+}
+
+.fa-calendar {
+ --fa: "\f133";
+}
+
+.fa-fire-extinguisher {
+ --fa: "\f134";
+}
+
+.fa-rocket {
+ --fa: "\f135";
+}
+
+.fa-circle-chevron-left {
+ --fa: "\f137";
+}
+
+.fa-chevron-circle-left {
+ --fa: "\f137";
+}
+
+.fa-circle-chevron-right {
+ --fa: "\f138";
+}
+
+.fa-chevron-circle-right {
+ --fa: "\f138";
+}
+
+.fa-circle-chevron-up {
+ --fa: "\f139";
+}
+
+.fa-chevron-circle-up {
+ --fa: "\f139";
+}
+
+.fa-circle-chevron-down {
+ --fa: "\f13a";
+}
+
+.fa-chevron-circle-down {
+ --fa: "\f13a";
+}
+
+.fa-anchor {
+ --fa: "\f13d";
+}
+
+.fa-unlock-keyhole {
+ --fa: "\f13e";
+}
+
+.fa-unlock-alt {
+ --fa: "\f13e";
+}
+
+.fa-bullseye {
+ --fa: "\f140";
+}
+
+.fa-ellipsis {
+ --fa: "\f141";
+}
+
+.fa-ellipsis-h {
+ --fa: "\f141";
+}
+
+.fa-ellipsis-vertical {
+ --fa: "\f142";
+}
+
+.fa-ellipsis-v {
+ --fa: "\f142";
+}
+
+.fa-square-rss {
+ --fa: "\f143";
+}
+
+.fa-rss-square {
+ --fa: "\f143";
+}
+
+.fa-circle-play {
+ --fa: "\f144";
+}
+
+.fa-play-circle {
+ --fa: "\f144";
+}
+
+.fa-ticket {
+ --fa: "\f145";
+}
+
+.fa-square-minus {
+ --fa: "\f146";
+}
+
+.fa-minus-square {
+ --fa: "\f146";
+}
+
+.fa-arrow-turn-up {
+ --fa: "\f148";
+}
+
+.fa-level-up {
+ --fa: "\f148";
+}
+
+.fa-arrow-turn-down {
+ --fa: "\f149";
+}
+
+.fa-level-down {
+ --fa: "\f149";
+}
+
+.fa-square-check {
+ --fa: "\f14a";
+}
+
+.fa-check-square {
+ --fa: "\f14a";
+}
+
+.fa-square-pen {
+ --fa: "\f14b";
+}
+
+.fa-pen-square {
+ --fa: "\f14b";
+}
+
+.fa-pencil-square {
+ --fa: "\f14b";
+}
+
+.fa-square-arrow-up-right {
+ --fa: "\f14c";
+}
+
+.fa-external-link-square {
+ --fa: "\f14c";
+}
+
+.fa-share-from-square {
+ --fa: "\f14d";
+}
+
+.fa-share-square {
+ --fa: "\f14d";
+}
+
+.fa-compass {
+ --fa: "\f14e";
+}
+
+.fa-square-caret-down {
+ --fa: "\f150";
+}
+
+.fa-caret-square-down {
+ --fa: "\f150";
+}
+
+.fa-square-caret-up {
+ --fa: "\f151";
+}
+
+.fa-caret-square-up {
+ --fa: "\f151";
+}
+
+.fa-square-caret-right {
+ --fa: "\f152";
+}
+
+.fa-caret-square-right {
+ --fa: "\f152";
+}
+
+.fa-euro-sign {
+ --fa: "\f153";
+}
+
+.fa-eur {
+ --fa: "\f153";
+}
+
+.fa-euro {
+ --fa: "\f153";
+}
+
+.fa-sterling-sign {
+ --fa: "\f154";
+}
+
+.fa-gbp {
+ --fa: "\f154";
+}
+
+.fa-pound-sign {
+ --fa: "\f154";
+}
+
+.fa-rupee-sign {
+ --fa: "\f156";
+}
+
+.fa-rupee {
+ --fa: "\f156";
+}
+
+.fa-yen-sign {
+ --fa: "\f157";
+}
+
+.fa-cny {
+ --fa: "\f157";
+}
+
+.fa-jpy {
+ --fa: "\f157";
+}
+
+.fa-rmb {
+ --fa: "\f157";
+}
+
+.fa-yen {
+ --fa: "\f157";
+}
+
+.fa-ruble-sign {
+ --fa: "\f158";
+}
+
+.fa-rouble {
+ --fa: "\f158";
+}
+
+.fa-rub {
+ --fa: "\f158";
+}
+
+.fa-ruble {
+ --fa: "\f158";
+}
+
+.fa-won-sign {
+ --fa: "\f159";
+}
+
+.fa-krw {
+ --fa: "\f159";
+}
+
+.fa-won {
+ --fa: "\f159";
+}
+
+.fa-file {
+ --fa: "\f15b";
+}
+
+.fa-file-lines {
+ --fa: "\f15c";
+}
+
+.fa-file-alt {
+ --fa: "\f15c";
+}
+
+.fa-file-text {
+ --fa: "\f15c";
+}
+
+.fa-arrow-down-a-z {
+ --fa: "\f15d";
+}
+
+.fa-sort-alpha-asc {
+ --fa: "\f15d";
+}
+
+.fa-sort-alpha-down {
+ --fa: "\f15d";
+}
+
+.fa-arrow-up-a-z {
+ --fa: "\f15e";
+}
+
+.fa-sort-alpha-up {
+ --fa: "\f15e";
+}
+
+.fa-arrow-down-wide-short {
+ --fa: "\f160";
+}
+
+.fa-sort-amount-asc {
+ --fa: "\f160";
+}
+
+.fa-sort-amount-down {
+ --fa: "\f160";
+}
+
+.fa-arrow-up-wide-short {
+ --fa: "\f161";
+}
+
+.fa-sort-amount-up {
+ --fa: "\f161";
+}
+
+.fa-arrow-down-1-9 {
+ --fa: "\f162";
+}
+
+.fa-sort-numeric-asc {
+ --fa: "\f162";
+}
+
+.fa-sort-numeric-down {
+ --fa: "\f162";
+}
+
+.fa-arrow-up-1-9 {
+ --fa: "\f163";
+}
+
+.fa-sort-numeric-up {
+ --fa: "\f163";
+}
+
+.fa-thumbs-up {
+ --fa: "\f164";
+}
+
+.fa-thumbs-down {
+ --fa: "\f165";
+}
+
+.fa-arrow-down-long {
+ --fa: "\f175";
+}
+
+.fa-long-arrow-down {
+ --fa: "\f175";
+}
+
+.fa-arrow-up-long {
+ --fa: "\f176";
+}
+
+.fa-long-arrow-up {
+ --fa: "\f176";
+}
+
+.fa-arrow-left-long {
+ --fa: "\f177";
+}
+
+.fa-long-arrow-left {
+ --fa: "\f177";
+}
+
+.fa-arrow-right-long {
+ --fa: "\f178";
+}
+
+.fa-long-arrow-right {
+ --fa: "\f178";
+}
+
+.fa-person-dress {
+ --fa: "\f182";
+}
+
+.fa-female {
+ --fa: "\f182";
+}
+
+.fa-person {
+ --fa: "\f183";
+}
+
+.fa-male {
+ --fa: "\f183";
+}
+
+.fa-sun {
+ --fa: "\f185";
+}
+
+.fa-moon {
+ --fa: "\f186";
+}
+
+.fa-box-archive {
+ --fa: "\f187";
+}
+
+.fa-archive {
+ --fa: "\f187";
+}
+
+.fa-bug {
+ --fa: "\f188";
+}
+
+.fa-square-caret-left {
+ --fa: "\f191";
+}
+
+.fa-caret-square-left {
+ --fa: "\f191";
+}
+
+.fa-circle-dot {
+ --fa: "\f192";
+}
+
+.fa-dot-circle {
+ --fa: "\f192";
+}
+
+.fa-wheelchair {
+ --fa: "\f193";
+}
+
+.fa-lira-sign {
+ --fa: "\f195";
+}
+
+.fa-shuttle-space {
+ --fa: "\f197";
+}
+
+.fa-space-shuttle {
+ --fa: "\f197";
+}
+
+.fa-square-envelope {
+ --fa: "\f199";
+}
+
+.fa-envelope-square {
+ --fa: "\f199";
+}
+
+.fa-building-columns {
+ --fa: "\f19c";
+}
+
+.fa-bank {
+ --fa: "\f19c";
+}
+
+.fa-institution {
+ --fa: "\f19c";
+}
+
+.fa-museum {
+ --fa: "\f19c";
+}
+
+.fa-university {
+ --fa: "\f19c";
+}
+
+.fa-graduation-cap {
+ --fa: "\f19d";
+}
+
+.fa-mortar-board {
+ --fa: "\f19d";
+}
+
+.fa-language {
+ --fa: "\f1ab";
+}
+
+.fa-fax {
+ --fa: "\f1ac";
+}
+
+.fa-building {
+ --fa: "\f1ad";
+}
+
+.fa-child {
+ --fa: "\f1ae";
+}
+
+.fa-paw {
+ --fa: "\f1b0";
+}
+
+.fa-cube {
+ --fa: "\f1b2";
+}
+
+.fa-cubes {
+ --fa: "\f1b3";
+}
+
+.fa-recycle {
+ --fa: "\f1b8";
+}
+
+.fa-car {
+ --fa: "\f1b9";
+}
+
+.fa-automobile {
+ --fa: "\f1b9";
+}
+
+.fa-taxi {
+ --fa: "\f1ba";
+}
+
+.fa-cab {
+ --fa: "\f1ba";
+}
+
+.fa-tree {
+ --fa: "\f1bb";
+}
+
+.fa-database {
+ --fa: "\f1c0";
+}
+
+.fa-file-pdf {
+ --fa: "\f1c1";
+}
+
+.fa-file-word {
+ --fa: "\f1c2";
+}
+
+.fa-file-excel {
+ --fa: "\f1c3";
+}
+
+.fa-file-powerpoint {
+ --fa: "\f1c4";
+}
+
+.fa-file-image {
+ --fa: "\f1c5";
+}
+
+.fa-file-zipper {
+ --fa: "\f1c6";
+}
+
+.fa-file-archive {
+ --fa: "\f1c6";
+}
+
+.fa-file-audio {
+ --fa: "\f1c7";
+}
+
+.fa-file-video {
+ --fa: "\f1c8";
+}
+
+.fa-file-code {
+ --fa: "\f1c9";
+}
+
+.fa-life-ring {
+ --fa: "\f1cd";
+}
+
+.fa-circle-notch {
+ --fa: "\f1ce";
+}
+
+.fa-paper-plane {
+ --fa: "\f1d8";
+}
+
+.fa-clock-rotate-left {
+ --fa: "\f1da";
+}
+
+.fa-history {
+ --fa: "\f1da";
+}
+
+.fa-heading {
+ --fa: "\f1dc";
+}
+
+.fa-header {
+ --fa: "\f1dc";
+}
+
+.fa-paragraph {
+ --fa: "\f1dd";
+}
+
+.fa-sliders {
+ --fa: "\f1de";
+}
+
+.fa-sliders-h {
+ --fa: "\f1de";
+}
+
+.fa-share-nodes {
+ --fa: "\f1e0";
+}
+
+.fa-share-alt {
+ --fa: "\f1e0";
+}
+
+.fa-square-share-nodes {
+ --fa: "\f1e1";
+}
+
+.fa-share-alt-square {
+ --fa: "\f1e1";
+}
+
+.fa-bomb {
+ --fa: "\f1e2";
+}
+
+.fa-futbol {
+ --fa: "\f1e3";
+}
+
+.fa-futbol-ball {
+ --fa: "\f1e3";
+}
+
+.fa-soccer-ball {
+ --fa: "\f1e3";
+}
+
+.fa-tty {
+ --fa: "\f1e4";
+}
+
+.fa-teletype {
+ --fa: "\f1e4";
+}
+
+.fa-binoculars {
+ --fa: "\f1e5";
+}
+
+.fa-plug {
+ --fa: "\f1e6";
+}
+
+.fa-newspaper {
+ --fa: "\f1ea";
+}
+
+.fa-wifi {
+ --fa: "\f1eb";
+}
+
+.fa-wifi-3 {
+ --fa: "\f1eb";
+}
+
+.fa-wifi-strong {
+ --fa: "\f1eb";
+}
+
+.fa-calculator {
+ --fa: "\f1ec";
+}
+
+.fa-bell-slash {
+ --fa: "\f1f6";
+}
+
+.fa-trash {
+ --fa: "\f1f8";
+}
+
+.fa-copyright {
+ --fa: "\f1f9";
+}
+
+.fa-eye-dropper {
+ --fa: "\f1fb";
+}
+
+.fa-eye-dropper-empty {
+ --fa: "\f1fb";
+}
+
+.fa-eyedropper {
+ --fa: "\f1fb";
+}
+
+.fa-paintbrush {
+ --fa: "\f1fc";
+}
+
+.fa-paint-brush {
+ --fa: "\f1fc";
+}
+
+.fa-cake-candles {
+ --fa: "\f1fd";
+}
+
+.fa-birthday-cake {
+ --fa: "\f1fd";
+}
+
+.fa-cake {
+ --fa: "\f1fd";
+}
+
+.fa-chart-area {
+ --fa: "\f1fe";
+}
+
+.fa-area-chart {
+ --fa: "\f1fe";
+}
+
+.fa-chart-pie {
+ --fa: "\f200";
+}
+
+.fa-pie-chart {
+ --fa: "\f200";
+}
+
+.fa-chart-line {
+ --fa: "\f201";
+}
+
+.fa-line-chart {
+ --fa: "\f201";
+}
+
+.fa-toggle-off {
+ --fa: "\f204";
+}
+
+.fa-toggle-on {
+ --fa: "\f205";
+}
+
+.fa-bicycle {
+ --fa: "\f206";
+}
+
+.fa-bus {
+ --fa: "\f207";
+}
+
+.fa-closed-captioning {
+ --fa: "\f20a";
+}
+
+.fa-shekel-sign {
+ --fa: "\f20b";
+}
+
+.fa-ils {
+ --fa: "\f20b";
+}
+
+.fa-shekel {
+ --fa: "\f20b";
+}
+
+.fa-sheqel {
+ --fa: "\f20b";
+}
+
+.fa-sheqel-sign {
+ --fa: "\f20b";
+}
+
+.fa-cart-plus {
+ --fa: "\f217";
+}
+
+.fa-cart-arrow-down {
+ --fa: "\f218";
+}
+
+.fa-diamond {
+ --fa: "\f219";
+}
+
+.fa-ship {
+ --fa: "\f21a";
+}
+
+.fa-user-secret {
+ --fa: "\f21b";
+}
+
+.fa-motorcycle {
+ --fa: "\f21c";
+}
+
+.fa-street-view {
+ --fa: "\f21d";
+}
+
+.fa-heart-pulse {
+ --fa: "\f21e";
+}
+
+.fa-heartbeat {
+ --fa: "\f21e";
+}
+
+.fa-venus {
+ --fa: "\f221";
+}
+
+.fa-mars {
+ --fa: "\f222";
+}
+
+.fa-mercury {
+ --fa: "\f223";
+}
+
+.fa-mars-and-venus {
+ --fa: "\f224";
+}
+
+.fa-transgender {
+ --fa: "\f225";
+}
+
+.fa-transgender-alt {
+ --fa: "\f225";
+}
+
+.fa-venus-double {
+ --fa: "\f226";
+}
+
+.fa-mars-double {
+ --fa: "\f227";
+}
+
+.fa-venus-mars {
+ --fa: "\f228";
+}
+
+.fa-mars-stroke {
+ --fa: "\f229";
+}
+
+.fa-mars-stroke-up {
+ --fa: "\f22a";
+}
+
+.fa-mars-stroke-v {
+ --fa: "\f22a";
+}
+
+.fa-mars-stroke-right {
+ --fa: "\f22b";
+}
+
+.fa-mars-stroke-h {
+ --fa: "\f22b";
+}
+
+.fa-neuter {
+ --fa: "\f22c";
+}
+
+.fa-genderless {
+ --fa: "\f22d";
+}
+
+.fa-server {
+ --fa: "\f233";
+}
+
+.fa-user-plus {
+ --fa: "\f234";
+}
+
+.fa-user-xmark {
+ --fa: "\f235";
+}
+
+.fa-user-times {
+ --fa: "\f235";
+}
+
+.fa-bed {
+ --fa: "\f236";
+}
+
+.fa-train {
+ --fa: "\f238";
+}
+
+.fa-train-subway {
+ --fa: "\f239";
+}
+
+.fa-subway {
+ --fa: "\f239";
+}
+
+.fa-battery-full {
+ --fa: "\f240";
+}
+
+.fa-battery {
+ --fa: "\f240";
+}
+
+.fa-battery-5 {
+ --fa: "\f240";
+}
+
+.fa-battery-three-quarters {
+ --fa: "\f241";
+}
+
+.fa-battery-4 {
+ --fa: "\f241";
+}
+
+.fa-battery-half {
+ --fa: "\f242";
+}
+
+.fa-battery-3 {
+ --fa: "\f242";
+}
+
+.fa-battery-quarter {
+ --fa: "\f243";
+}
+
+.fa-battery-2 {
+ --fa: "\f243";
+}
+
+.fa-battery-empty {
+ --fa: "\f244";
+}
+
+.fa-battery-0 {
+ --fa: "\f244";
+}
+
+.fa-arrow-pointer {
+ --fa: "\f245";
+}
+
+.fa-mouse-pointer {
+ --fa: "\f245";
+}
+
+.fa-i-cursor {
+ --fa: "\f246";
+}
+
+.fa-object-group {
+ --fa: "\f247";
+}
+
+.fa-object-ungroup {
+ --fa: "\f248";
+}
+
+.fa-note-sticky {
+ --fa: "\f249";
+}
+
+.fa-sticky-note {
+ --fa: "\f249";
+}
+
+.fa-clone {
+ --fa: "\f24d";
+}
+
+.fa-scale-balanced {
+ --fa: "\f24e";
+}
+
+.fa-balance-scale {
+ --fa: "\f24e";
+}
+
+.fa-hourglass-start {
+ --fa: "\f251";
+}
+
+.fa-hourglass-1 {
+ --fa: "\f251";
+}
+
+.fa-hourglass-half {
+ --fa: "\f252";
+}
+
+.fa-hourglass-2 {
+ --fa: "\f252";
+}
+
+.fa-hourglass-end {
+ --fa: "\f253";
+}
+
+.fa-hourglass-3 {
+ --fa: "\f253";
+}
+
+.fa-hourglass {
+ --fa: "\f254";
+}
+
+.fa-hourglass-empty {
+ --fa: "\f254";
+}
+
+.fa-hand-back-fist {
+ --fa: "\f255";
+}
+
+.fa-hand-rock {
+ --fa: "\f255";
+}
+
+.fa-hand {
+ --fa: "\f256";
+}
+
+.fa-hand-paper {
+ --fa: "\f256";
+}
+
+.fa-hand-scissors {
+ --fa: "\f257";
+}
+
+.fa-hand-lizard {
+ --fa: "\f258";
+}
+
+.fa-hand-spock {
+ --fa: "\f259";
+}
+
+.fa-hand-pointer {
+ --fa: "\f25a";
+}
+
+.fa-hand-peace {
+ --fa: "\f25b";
+}
+
+.fa-trademark {
+ --fa: "\f25c";
+}
+
+.fa-registered {
+ --fa: "\f25d";
+}
+
+.fa-tv {
+ --fa: "\f26c";
+}
+
+.fa-television {
+ --fa: "\f26c";
+}
+
+.fa-tv-alt {
+ --fa: "\f26c";
+}
+
+.fa-calendar-plus {
+ --fa: "\f271";
+}
+
+.fa-calendar-minus {
+ --fa: "\f272";
+}
+
+.fa-calendar-xmark {
+ --fa: "\f273";
+}
+
+.fa-calendar-times {
+ --fa: "\f273";
+}
+
+.fa-calendar-check {
+ --fa: "\f274";
+}
+
+.fa-industry {
+ --fa: "\f275";
+}
+
+.fa-map-pin {
+ --fa: "\f276";
+}
+
+.fa-signs-post {
+ --fa: "\f277";
+}
+
+.fa-map-signs {
+ --fa: "\f277";
+}
+
+.fa-map {
+ --fa: "\f279";
+}
+
+.fa-message {
+ --fa: "\f27a";
+}
+
+.fa-comment-alt {
+ --fa: "\f27a";
+}
+
+.fa-circle-pause {
+ --fa: "\f28b";
+}
+
+.fa-pause-circle {
+ --fa: "\f28b";
+}
+
+.fa-circle-stop {
+ --fa: "\f28d";
+}
+
+.fa-stop-circle {
+ --fa: "\f28d";
+}
+
+.fa-bag-shopping {
+ --fa: "\f290";
+}
+
+.fa-shopping-bag {
+ --fa: "\f290";
+}
+
+.fa-basket-shopping {
+ --fa: "\f291";
+}
+
+.fa-shopping-basket {
+ --fa: "\f291";
+}
+
+.fa-universal-access {
+ --fa: "\f29a";
+}
+
+.fa-person-walking-with-cane {
+ --fa: "\f29d";
+}
+
+.fa-blind {
+ --fa: "\f29d";
+}
+
+.fa-audio-description {
+ --fa: "\f29e";
+}
+
+.fa-phone-volume {
+ --fa: "\f2a0";
+}
+
+.fa-volume-control-phone {
+ --fa: "\f2a0";
+}
+
+.fa-braille {
+ --fa: "\f2a1";
+}
+
+.fa-ear-listen {
+ --fa: "\f2a2";
+}
+
+.fa-assistive-listening-systems {
+ --fa: "\f2a2";
+}
+
+.fa-hands-asl-interpreting {
+ --fa: "\f2a3";
+}
+
+.fa-american-sign-language-interpreting {
+ --fa: "\f2a3";
+}
+
+.fa-asl-interpreting {
+ --fa: "\f2a3";
+}
+
+.fa-hands-american-sign-language-interpreting {
+ --fa: "\f2a3";
+}
+
+.fa-ear-deaf {
+ --fa: "\f2a4";
+}
+
+.fa-deaf {
+ --fa: "\f2a4";
+}
+
+.fa-deafness {
+ --fa: "\f2a4";
+}
+
+.fa-hard-of-hearing {
+ --fa: "\f2a4";
+}
+
+.fa-hands {
+ --fa: "\f2a7";
+}
+
+.fa-sign-language {
+ --fa: "\f2a7";
+}
+
+.fa-signing {
+ --fa: "\f2a7";
+}
+
+.fa-eye-low-vision {
+ --fa: "\f2a8";
+}
+
+.fa-low-vision {
+ --fa: "\f2a8";
+}
+
+.fa-font-awesome {
+ --fa: "\f2b4";
+}
+
+.fa-font-awesome-flag {
+ --fa: "\f2b4";
+}
+
+.fa-font-awesome-logo-full {
+ --fa: "\f2b4";
+}
+
+.fa-handshake {
+ --fa: "\f2b5";
+}
+
+.fa-handshake-alt {
+ --fa: "\f2b5";
+}
+
+.fa-handshake-simple {
+ --fa: "\f2b5";
+}
+
+.fa-envelope-open {
+ --fa: "\f2b6";
+}
+
+.fa-address-book {
+ --fa: "\f2b9";
+}
+
+.fa-contact-book {
+ --fa: "\f2b9";
+}
+
+.fa-address-card {
+ --fa: "\f2bb";
+}
+
+.fa-contact-card {
+ --fa: "\f2bb";
+}
+
+.fa-vcard {
+ --fa: "\f2bb";
+}
+
+.fa-circle-user {
+ --fa: "\f2bd";
+}
+
+.fa-user-circle {
+ --fa: "\f2bd";
+}
+
+.fa-id-badge {
+ --fa: "\f2c1";
+}
+
+.fa-id-card {
+ --fa: "\f2c2";
+}
+
+.fa-drivers-license {
+ --fa: "\f2c2";
+}
+
+.fa-temperature-full {
+ --fa: "\f2c7";
+}
+
+.fa-temperature-4 {
+ --fa: "\f2c7";
+}
+
+.fa-thermometer-4 {
+ --fa: "\f2c7";
+}
+
+.fa-thermometer-full {
+ --fa: "\f2c7";
+}
+
+.fa-temperature-three-quarters {
+ --fa: "\f2c8";
+}
+
+.fa-temperature-3 {
+ --fa: "\f2c8";
+}
+
+.fa-thermometer-3 {
+ --fa: "\f2c8";
+}
+
+.fa-thermometer-three-quarters {
+ --fa: "\f2c8";
+}
+
+.fa-temperature-half {
+ --fa: "\f2c9";
+}
+
+.fa-temperature-2 {
+ --fa: "\f2c9";
+}
+
+.fa-thermometer-2 {
+ --fa: "\f2c9";
+}
+
+.fa-thermometer-half {
+ --fa: "\f2c9";
+}
+
+.fa-temperature-quarter {
+ --fa: "\f2ca";
+}
+
+.fa-temperature-1 {
+ --fa: "\f2ca";
+}
+
+.fa-thermometer-1 {
+ --fa: "\f2ca";
+}
+
+.fa-thermometer-quarter {
+ --fa: "\f2ca";
+}
+
+.fa-temperature-empty {
+ --fa: "\f2cb";
+}
+
+.fa-temperature-0 {
+ --fa: "\f2cb";
+}
+
+.fa-thermometer-0 {
+ --fa: "\f2cb";
+}
+
+.fa-thermometer-empty {
+ --fa: "\f2cb";
+}
+
+.fa-shower {
+ --fa: "\f2cc";
+}
+
+.fa-bath {
+ --fa: "\f2cd";
+}
+
+.fa-bathtub {
+ --fa: "\f2cd";
+}
+
+.fa-podcast {
+ --fa: "\f2ce";
+}
+
+.fa-window-maximize {
+ --fa: "\f2d0";
+}
+
+.fa-window-minimize {
+ --fa: "\f2d1";
+}
+
+.fa-window-restore {
+ --fa: "\f2d2";
+}
+
+.fa-square-xmark {
+ --fa: "\f2d3";
+}
+
+.fa-times-square {
+ --fa: "\f2d3";
+}
+
+.fa-xmark-square {
+ --fa: "\f2d3";
+}
+
+.fa-microchip {
+ --fa: "\f2db";
+}
+
+.fa-snowflake {
+ --fa: "\f2dc";
+}
+
+.fa-spoon {
+ --fa: "\f2e5";
+}
+
+.fa-utensil-spoon {
+ --fa: "\f2e5";
+}
+
+.fa-utensils {
+ --fa: "\f2e7";
+}
+
+.fa-cutlery {
+ --fa: "\f2e7";
+}
+
+.fa-rotate-left {
+ --fa: "\f2ea";
+}
+
+.fa-rotate-back {
+ --fa: "\f2ea";
+}
+
+.fa-rotate-backward {
+ --fa: "\f2ea";
+}
+
+.fa-undo-alt {
+ --fa: "\f2ea";
+}
+
+.fa-trash-can {
+ --fa: "\f2ed";
+}
+
+.fa-trash-alt {
+ --fa: "\f2ed";
+}
+
+.fa-rotate {
+ --fa: "\f2f1";
+}
+
+.fa-sync-alt {
+ --fa: "\f2f1";
+}
+
+.fa-stopwatch {
+ --fa: "\f2f2";
+}
+
+.fa-right-from-bracket {
+ --fa: "\f2f5";
+}
+
+.fa-sign-out-alt {
+ --fa: "\f2f5";
+}
+
+.fa-right-to-bracket {
+ --fa: "\f2f6";
+}
+
+.fa-sign-in-alt {
+ --fa: "\f2f6";
+}
+
+.fa-rotate-right {
+ --fa: "\f2f9";
+}
+
+.fa-redo-alt {
+ --fa: "\f2f9";
+}
+
+.fa-rotate-forward {
+ --fa: "\f2f9";
+}
+
+.fa-poo {
+ --fa: "\f2fe";
+}
+
+.fa-images {
+ --fa: "\f302";
+}
+
+.fa-pencil {
+ --fa: "\f303";
+}
+
+.fa-pencil-alt {
+ --fa: "\f303";
+}
+
+.fa-pen {
+ --fa: "\f304";
+}
+
+.fa-pen-clip {
+ --fa: "\f305";
+}
+
+.fa-pen-alt {
+ --fa: "\f305";
+}
+
+.fa-octagon {
+ --fa: "\f306";
+}
+
+.fa-down-long {
+ --fa: "\f309";
+}
+
+.fa-long-arrow-alt-down {
+ --fa: "\f309";
+}
+
+.fa-left-long {
+ --fa: "\f30a";
+}
+
+.fa-long-arrow-alt-left {
+ --fa: "\f30a";
+}
+
+.fa-right-long {
+ --fa: "\f30b";
+}
+
+.fa-long-arrow-alt-right {
+ --fa: "\f30b";
+}
+
+.fa-up-long {
+ --fa: "\f30c";
+}
+
+.fa-long-arrow-alt-up {
+ --fa: "\f30c";
+}
+
+.fa-hexagon {
+ --fa: "\f312";
+}
+
+.fa-file-pen {
+ --fa: "\f31c";
+}
+
+.fa-file-edit {
+ --fa: "\f31c";
+}
+
+.fa-maximize {
+ --fa: "\f31e";
+}
+
+.fa-expand-arrows-alt {
+ --fa: "\f31e";
+}
+
+.fa-clipboard {
+ --fa: "\f328";
+}
+
+.fa-left-right {
+ --fa: "\f337";
+}
+
+.fa-arrows-alt-h {
+ --fa: "\f337";
+}
+
+.fa-up-down {
+ --fa: "\f338";
+}
+
+.fa-arrows-alt-v {
+ --fa: "\f338";
+}
+
+.fa-alarm-clock {
+ --fa: "\f34e";
+}
+
+.fa-circle-down {
+ --fa: "\f358";
+}
+
+.fa-arrow-alt-circle-down {
+ --fa: "\f358";
+}
+
+.fa-circle-left {
+ --fa: "\f359";
+}
+
+.fa-arrow-alt-circle-left {
+ --fa: "\f359";
+}
+
+.fa-circle-right {
+ --fa: "\f35a";
+}
+
+.fa-arrow-alt-circle-right {
+ --fa: "\f35a";
+}
+
+.fa-circle-up {
+ --fa: "\f35b";
+}
+
+.fa-arrow-alt-circle-up {
+ --fa: "\f35b";
+}
+
+.fa-up-right-from-square {
+ --fa: "\f35d";
+}
+
+.fa-external-link-alt {
+ --fa: "\f35d";
+}
+
+.fa-square-up-right {
+ --fa: "\f360";
+}
+
+.fa-external-link-square-alt {
+ --fa: "\f360";
+}
+
+.fa-right-left {
+ --fa: "\f362";
+}
+
+.fa-exchange-alt {
+ --fa: "\f362";
+}
+
+.fa-repeat {
+ --fa: "\f363";
+}
+
+.fa-code-commit {
+ --fa: "\f386";
+}
+
+.fa-code-merge {
+ --fa: "\f387";
+}
+
+.fa-desktop {
+ --fa: "\f390";
+}
+
+.fa-desktop-alt {
+ --fa: "\f390";
+}
+
+.fa-gem {
+ --fa: "\f3a5";
+}
+
+.fa-turn-down {
+ --fa: "\f3be";
+}
+
+.fa-level-down-alt {
+ --fa: "\f3be";
+}
+
+.fa-turn-up {
+ --fa: "\f3bf";
+}
+
+.fa-level-up-alt {
+ --fa: "\f3bf";
+}
+
+.fa-lock-open {
+ --fa: "\f3c1";
+}
+
+.fa-location-dot {
+ --fa: "\f3c5";
+}
+
+.fa-map-marker-alt {
+ --fa: "\f3c5";
+}
+
+.fa-microphone-lines {
+ --fa: "\f3c9";
+}
+
+.fa-microphone-alt {
+ --fa: "\f3c9";
+}
+
+.fa-mobile-screen-button {
+ --fa: "\f3cd";
+}
+
+.fa-mobile-alt {
+ --fa: "\f3cd";
+}
+
+.fa-mobile {
+ --fa: "\f3ce";
+}
+
+.fa-mobile-android {
+ --fa: "\f3ce";
+}
+
+.fa-mobile-phone {
+ --fa: "\f3ce";
+}
+
+.fa-mobile-screen {
+ --fa: "\f3cf";
+}
+
+.fa-mobile-android-alt {
+ --fa: "\f3cf";
+}
+
+.fa-money-bill-1 {
+ --fa: "\f3d1";
+}
+
+.fa-money-bill-alt {
+ --fa: "\f3d1";
+}
+
+.fa-phone-slash {
+ --fa: "\f3dd";
+}
+
+.fa-image-portrait {
+ --fa: "\f3e0";
+}
+
+.fa-portrait {
+ --fa: "\f3e0";
+}
+
+.fa-reply {
+ --fa: "\f3e5";
+}
+
+.fa-mail-reply {
+ --fa: "\f3e5";
+}
+
+.fa-shield-halved {
+ --fa: "\f3ed";
+}
+
+.fa-shield-alt {
+ --fa: "\f3ed";
+}
+
+.fa-tablet-screen-button {
+ --fa: "\f3fa";
+}
+
+.fa-tablet-alt {
+ --fa: "\f3fa";
+}
+
+.fa-tablet {
+ --fa: "\f3fb";
+}
+
+.fa-tablet-android {
+ --fa: "\f3fb";
+}
+
+.fa-ticket-simple {
+ --fa: "\f3ff";
+}
+
+.fa-ticket-alt {
+ --fa: "\f3ff";
+}
+
+.fa-rectangle-xmark {
+ --fa: "\f410";
+}
+
+.fa-rectangle-times {
+ --fa: "\f410";
+}
+
+.fa-times-rectangle {
+ --fa: "\f410";
+}
+
+.fa-window-close {
+ --fa: "\f410";
+}
+
+.fa-down-left-and-up-right-to-center {
+ --fa: "\f422";
+}
+
+.fa-compress-alt {
+ --fa: "\f422";
+}
+
+.fa-up-right-and-down-left-from-center {
+ --fa: "\f424";
+}
+
+.fa-expand-alt {
+ --fa: "\f424";
+}
+
+.fa-baseball-bat-ball {
+ --fa: "\f432";
+}
+
+.fa-baseball {
+ --fa: "\f433";
+}
+
+.fa-baseball-ball {
+ --fa: "\f433";
+}
+
+.fa-basketball {
+ --fa: "\f434";
+}
+
+.fa-basketball-ball {
+ --fa: "\f434";
+}
+
+.fa-bowling-ball {
+ --fa: "\f436";
+}
+
+.fa-chess {
+ --fa: "\f439";
+}
+
+.fa-chess-bishop {
+ --fa: "\f43a";
+}
+
+.fa-chess-board {
+ --fa: "\f43c";
+}
+
+.fa-chess-king {
+ --fa: "\f43f";
+}
+
+.fa-chess-knight {
+ --fa: "\f441";
+}
+
+.fa-chess-pawn {
+ --fa: "\f443";
+}
+
+.fa-chess-queen {
+ --fa: "\f445";
+}
+
+.fa-chess-rook {
+ --fa: "\f447";
+}
+
+.fa-dumbbell {
+ --fa: "\f44b";
+}
+
+.fa-football {
+ --fa: "\f44e";
+}
+
+.fa-football-ball {
+ --fa: "\f44e";
+}
+
+.fa-golf-ball-tee {
+ --fa: "\f450";
+}
+
+.fa-golf-ball {
+ --fa: "\f450";
+}
+
+.fa-hockey-puck {
+ --fa: "\f453";
+}
+
+.fa-broom-ball {
+ --fa: "\f458";
+}
+
+.fa-quidditch {
+ --fa: "\f458";
+}
+
+.fa-quidditch-broom-ball {
+ --fa: "\f458";
+}
+
+.fa-square-full {
+ --fa: "\f45c";
+}
+
+.fa-table-tennis-paddle-ball {
+ --fa: "\f45d";
+}
+
+.fa-ping-pong-paddle-ball {
+ --fa: "\f45d";
+}
+
+.fa-table-tennis {
+ --fa: "\f45d";
+}
+
+.fa-volleyball {
+ --fa: "\f45f";
+}
+
+.fa-volleyball-ball {
+ --fa: "\f45f";
+}
+
+.fa-hand-dots {
+ --fa: "\f461";
+}
+
+.fa-allergies {
+ --fa: "\f461";
+}
+
+.fa-bandage {
+ --fa: "\f462";
+}
+
+.fa-band-aid {
+ --fa: "\f462";
+}
+
+.fa-box {
+ --fa: "\f466";
+}
+
+.fa-boxes-stacked {
+ --fa: "\f468";
+}
+
+.fa-boxes {
+ --fa: "\f468";
+}
+
+.fa-boxes-alt {
+ --fa: "\f468";
+}
+
+.fa-briefcase-medical {
+ --fa: "\f469";
+}
+
+.fa-fire-flame-simple {
+ --fa: "\f46a";
+}
+
+.fa-burn {
+ --fa: "\f46a";
+}
+
+.fa-capsules {
+ --fa: "\f46b";
+}
+
+.fa-clipboard-check {
+ --fa: "\f46c";
+}
+
+.fa-clipboard-list {
+ --fa: "\f46d";
+}
+
+.fa-person-dots-from-line {
+ --fa: "\f470";
+}
+
+.fa-diagnoses {
+ --fa: "\f470";
+}
+
+.fa-dna {
+ --fa: "\f471";
+}
+
+.fa-dolly {
+ --fa: "\f472";
+}
+
+.fa-dolly-box {
+ --fa: "\f472";
+}
+
+.fa-cart-flatbed {
+ --fa: "\f474";
+}
+
+.fa-dolly-flatbed {
+ --fa: "\f474";
+}
+
+.fa-file-medical {
+ --fa: "\f477";
+}
+
+.fa-file-waveform {
+ --fa: "\f478";
+}
+
+.fa-file-medical-alt {
+ --fa: "\f478";
+}
+
+.fa-kit-medical {
+ --fa: "\f479";
+}
+
+.fa-first-aid {
+ --fa: "\f479";
+}
+
+.fa-circle-h {
+ --fa: "\f47e";
+}
+
+.fa-hospital-symbol {
+ --fa: "\f47e";
+}
+
+.fa-id-card-clip {
+ --fa: "\f47f";
+}
+
+.fa-id-card-alt {
+ --fa: "\f47f";
+}
+
+.fa-notes-medical {
+ --fa: "\f481";
+}
+
+.fa-pallet {
+ --fa: "\f482";
+}
+
+.fa-pills {
+ --fa: "\f484";
+}
+
+.fa-prescription-bottle {
+ --fa: "\f485";
+}
+
+.fa-prescription-bottle-medical {
+ --fa: "\f486";
+}
+
+.fa-prescription-bottle-alt {
+ --fa: "\f486";
+}
+
+.fa-bed-pulse {
+ --fa: "\f487";
+}
+
+.fa-procedures {
+ --fa: "\f487";
+}
+
+.fa-truck-fast {
+ --fa: "\f48b";
+}
+
+.fa-shipping-fast {
+ --fa: "\f48b";
+}
+
+.fa-smoking {
+ --fa: "\f48d";
+}
+
+.fa-syringe {
+ --fa: "\f48e";
+}
+
+.fa-tablets {
+ --fa: "\f490";
+}
+
+.fa-thermometer {
+ --fa: "\f491";
+}
+
+.fa-vial {
+ --fa: "\f492";
+}
+
+.fa-vials {
+ --fa: "\f493";
+}
+
+.fa-warehouse {
+ --fa: "\f494";
+}
+
+.fa-weight-scale {
+ --fa: "\f496";
+}
+
+.fa-weight {
+ --fa: "\f496";
+}
+
+.fa-x-ray {
+ --fa: "\f497";
+}
+
+.fa-box-open {
+ --fa: "\f49e";
+}
+
+.fa-comment-dots {
+ --fa: "\f4ad";
+}
+
+.fa-commenting {
+ --fa: "\f4ad";
+}
+
+.fa-comment-slash {
+ --fa: "\f4b3";
+}
+
+.fa-couch {
+ --fa: "\f4b8";
+}
+
+.fa-circle-dollar-to-slot {
+ --fa: "\f4b9";
+}
+
+.fa-donate {
+ --fa: "\f4b9";
+}
+
+.fa-dove {
+ --fa: "\f4ba";
+}
+
+.fa-hand-holding {
+ --fa: "\f4bd";
+}
+
+.fa-hand-holding-heart {
+ --fa: "\f4be";
+}
+
+.fa-hand-holding-dollar {
+ --fa: "\f4c0";
+}
+
+.fa-hand-holding-usd {
+ --fa: "\f4c0";
+}
+
+.fa-hand-holding-droplet {
+ --fa: "\f4c1";
+}
+
+.fa-hand-holding-water {
+ --fa: "\f4c1";
+}
+
+.fa-hands-holding {
+ --fa: "\f4c2";
+}
+
+.fa-handshake-angle {
+ --fa: "\f4c4";
+}
+
+.fa-hands-helping {
+ --fa: "\f4c4";
+}
+
+.fa-parachute-box {
+ --fa: "\f4cd";
+}
+
+.fa-people-carry-box {
+ --fa: "\f4ce";
+}
+
+.fa-people-carry {
+ --fa: "\f4ce";
+}
+
+.fa-piggy-bank {
+ --fa: "\f4d3";
+}
+
+.fa-ribbon {
+ --fa: "\f4d6";
+}
+
+.fa-route {
+ --fa: "\f4d7";
+}
+
+.fa-seedling {
+ --fa: "\f4d8";
+}
+
+.fa-sprout {
+ --fa: "\f4d8";
+}
+
+.fa-sign-hanging {
+ --fa: "\f4d9";
+}
+
+.fa-sign {
+ --fa: "\f4d9";
+}
+
+.fa-face-smile-wink {
+ --fa: "\f4da";
+}
+
+.fa-smile-wink {
+ --fa: "\f4da";
+}
+
+.fa-tape {
+ --fa: "\f4db";
+}
+
+.fa-truck-ramp-box {
+ --fa: "\f4de";
+}
+
+.fa-truck-loading {
+ --fa: "\f4de";
+}
+
+.fa-truck-moving {
+ --fa: "\f4df";
+}
+
+.fa-video-slash {
+ --fa: "\f4e2";
+}
+
+.fa-wine-glass {
+ --fa: "\f4e3";
+}
+
+.fa-user-astronaut {
+ --fa: "\f4fb";
+}
+
+.fa-user-check {
+ --fa: "\f4fc";
+}
+
+.fa-user-clock {
+ --fa: "\f4fd";
+}
+
+.fa-user-gear {
+ --fa: "\f4fe";
+}
+
+.fa-user-cog {
+ --fa: "\f4fe";
+}
+
+.fa-user-pen {
+ --fa: "\f4ff";
+}
+
+.fa-user-edit {
+ --fa: "\f4ff";
+}
+
+.fa-user-group {
+ --fa: "\f500";
+}
+
+.fa-user-friends {
+ --fa: "\f500";
+}
+
+.fa-user-graduate {
+ --fa: "\f501";
+}
+
+.fa-user-lock {
+ --fa: "\f502";
+}
+
+.fa-user-minus {
+ --fa: "\f503";
+}
+
+.fa-user-ninja {
+ --fa: "\f504";
+}
+
+.fa-user-shield {
+ --fa: "\f505";
+}
+
+.fa-user-slash {
+ --fa: "\f506";
+}
+
+.fa-user-alt-slash {
+ --fa: "\f506";
+}
+
+.fa-user-large-slash {
+ --fa: "\f506";
+}
+
+.fa-user-tag {
+ --fa: "\f507";
+}
+
+.fa-user-tie {
+ --fa: "\f508";
+}
+
+.fa-users-gear {
+ --fa: "\f509";
+}
+
+.fa-users-cog {
+ --fa: "\f509";
+}
+
+.fa-scale-unbalanced {
+ --fa: "\f515";
+}
+
+.fa-balance-scale-left {
+ --fa: "\f515";
+}
+
+.fa-scale-unbalanced-flip {
+ --fa: "\f516";
+}
+
+.fa-balance-scale-right {
+ --fa: "\f516";
+}
+
+.fa-blender {
+ --fa: "\f517";
+}
+
+.fa-book-open {
+ --fa: "\f518";
+}
+
+.fa-tower-broadcast {
+ --fa: "\f519";
+}
+
+.fa-broadcast-tower {
+ --fa: "\f519";
+}
+
+.fa-broom {
+ --fa: "\f51a";
+}
+
+.fa-chalkboard {
+ --fa: "\f51b";
+}
+
+.fa-blackboard {
+ --fa: "\f51b";
+}
+
+.fa-chalkboard-user {
+ --fa: "\f51c";
+}
+
+.fa-chalkboard-teacher {
+ --fa: "\f51c";
+}
+
+.fa-church {
+ --fa: "\f51d";
+}
+
+.fa-coins {
+ --fa: "\f51e";
+}
+
+.fa-compact-disc {
+ --fa: "\f51f";
+}
+
+.fa-crow {
+ --fa: "\f520";
+}
+
+.fa-crown {
+ --fa: "\f521";
+}
+
+.fa-dice {
+ --fa: "\f522";
+}
+
+.fa-dice-five {
+ --fa: "\f523";
+}
+
+.fa-dice-four {
+ --fa: "\f524";
+}
+
+.fa-dice-one {
+ --fa: "\f525";
+}
+
+.fa-dice-six {
+ --fa: "\f526";
+}
+
+.fa-dice-three {
+ --fa: "\f527";
+}
+
+.fa-dice-two {
+ --fa: "\f528";
+}
+
+.fa-divide {
+ --fa: "\f529";
+}
+
+.fa-door-closed {
+ --fa: "\f52a";
+}
+
+.fa-door-open {
+ --fa: "\f52b";
+}
+
+.fa-feather {
+ --fa: "\f52d";
+}
+
+.fa-frog {
+ --fa: "\f52e";
+}
+
+.fa-gas-pump {
+ --fa: "\f52f";
+}
+
+.fa-glasses {
+ --fa: "\f530";
+}
+
+.fa-greater-than-equal {
+ --fa: "\f532";
+}
+
+.fa-helicopter {
+ --fa: "\f533";
+}
+
+.fa-infinity {
+ --fa: "\f534";
+}
+
+.fa-kiwi-bird {
+ --fa: "\f535";
+}
+
+.fa-less-than-equal {
+ --fa: "\f537";
+}
+
+.fa-memory {
+ --fa: "\f538";
+}
+
+.fa-microphone-lines-slash {
+ --fa: "\f539";
+}
+
+.fa-microphone-alt-slash {
+ --fa: "\f539";
+}
+
+.fa-money-bill-wave {
+ --fa: "\f53a";
+}
+
+.fa-money-bill-1-wave {
+ --fa: "\f53b";
+}
+
+.fa-money-bill-wave-alt {
+ --fa: "\f53b";
+}
+
+.fa-money-check {
+ --fa: "\f53c";
+}
+
+.fa-money-check-dollar {
+ --fa: "\f53d";
+}
+
+.fa-money-check-alt {
+ --fa: "\f53d";
+}
+
+.fa-not-equal {
+ --fa: "\f53e";
+}
+
+.fa-palette {
+ --fa: "\f53f";
+}
+
+.fa-square-parking {
+ --fa: "\f540";
+}
+
+.fa-parking {
+ --fa: "\f540";
+}
+
+.fa-diagram-project {
+ --fa: "\f542";
+}
+
+.fa-project-diagram {
+ --fa: "\f542";
+}
+
+.fa-receipt {
+ --fa: "\f543";
+}
+
+.fa-robot {
+ --fa: "\f544";
+}
+
+.fa-ruler {
+ --fa: "\f545";
+}
+
+.fa-ruler-combined {
+ --fa: "\f546";
+}
+
+.fa-ruler-horizontal {
+ --fa: "\f547";
+}
+
+.fa-ruler-vertical {
+ --fa: "\f548";
+}
+
+.fa-school {
+ --fa: "\f549";
+}
+
+.fa-screwdriver {
+ --fa: "\f54a";
+}
+
+.fa-shoe-prints {
+ --fa: "\f54b";
+}
+
+.fa-skull {
+ --fa: "\f54c";
+}
+
+.fa-ban-smoking {
+ --fa: "\f54d";
+}
+
+.fa-smoking-ban {
+ --fa: "\f54d";
+}
+
+.fa-store {
+ --fa: "\f54e";
+}
+
+.fa-shop {
+ --fa: "\f54f";
+}
+
+.fa-store-alt {
+ --fa: "\f54f";
+}
+
+.fa-bars-staggered {
+ --fa: "\f550";
+}
+
+.fa-reorder {
+ --fa: "\f550";
+}
+
+.fa-stream {
+ --fa: "\f550";
+}
+
+.fa-stroopwafel {
+ --fa: "\f551";
+}
+
+.fa-toolbox {
+ --fa: "\f552";
+}
+
+.fa-shirt {
+ --fa: "\f553";
+}
+
+.fa-t-shirt {
+ --fa: "\f553";
+}
+
+.fa-tshirt {
+ --fa: "\f553";
+}
+
+.fa-person-walking {
+ --fa: "\f554";
+}
+
+.fa-walking {
+ --fa: "\f554";
+}
+
+.fa-wallet {
+ --fa: "\f555";
+}
+
+.fa-face-angry {
+ --fa: "\f556";
+}
+
+.fa-angry {
+ --fa: "\f556";
+}
+
+.fa-archway {
+ --fa: "\f557";
+}
+
+.fa-book-atlas {
+ --fa: "\f558";
+}
+
+.fa-atlas {
+ --fa: "\f558";
+}
+
+.fa-award {
+ --fa: "\f559";
+}
+
+.fa-delete-left {
+ --fa: "\f55a";
+}
+
+.fa-backspace {
+ --fa: "\f55a";
+}
+
+.fa-bezier-curve {
+ --fa: "\f55b";
+}
+
+.fa-bong {
+ --fa: "\f55c";
+}
+
+.fa-brush {
+ --fa: "\f55d";
+}
+
+.fa-bus-simple {
+ --fa: "\f55e";
+}
+
+.fa-bus-alt {
+ --fa: "\f55e";
+}
+
+.fa-cannabis {
+ --fa: "\f55f";
+}
+
+.fa-check-double {
+ --fa: "\f560";
+}
+
+.fa-martini-glass-citrus {
+ --fa: "\f561";
+}
+
+.fa-cocktail {
+ --fa: "\f561";
+}
+
+.fa-bell-concierge {
+ --fa: "\f562";
+}
+
+.fa-concierge-bell {
+ --fa: "\f562";
+}
+
+.fa-cookie {
+ --fa: "\f563";
+}
+
+.fa-cookie-bite {
+ --fa: "\f564";
+}
+
+.fa-crop-simple {
+ --fa: "\f565";
+}
+
+.fa-crop-alt {
+ --fa: "\f565";
+}
+
+.fa-tachograph-digital {
+ --fa: "\f566";
+}
+
+.fa-digital-tachograph {
+ --fa: "\f566";
+}
+
+.fa-face-dizzy {
+ --fa: "\f567";
+}
+
+.fa-dizzy {
+ --fa: "\f567";
+}
+
+.fa-compass-drafting {
+ --fa: "\f568";
+}
+
+.fa-drafting-compass {
+ --fa: "\f568";
+}
+
+.fa-drum {
+ --fa: "\f569";
+}
+
+.fa-drum-steelpan {
+ --fa: "\f56a";
+}
+
+.fa-feather-pointed {
+ --fa: "\f56b";
+}
+
+.fa-feather-alt {
+ --fa: "\f56b";
+}
+
+.fa-file-contract {
+ --fa: "\f56c";
+}
+
+.fa-file-arrow-down {
+ --fa: "\f56d";
+}
+
+.fa-file-download {
+ --fa: "\f56d";
+}
+
+.fa-file-export {
+ --fa: "\f56e";
+}
+
+.fa-arrow-right-from-file {
+ --fa: "\f56e";
+}
+
+.fa-file-import {
+ --fa: "\f56f";
+}
+
+.fa-arrow-right-to-file {
+ --fa: "\f56f";
+}
+
+.fa-file-invoice {
+ --fa: "\f570";
+}
+
+.fa-file-invoice-dollar {
+ --fa: "\f571";
+}
+
+.fa-file-prescription {
+ --fa: "\f572";
+}
+
+.fa-file-signature {
+ --fa: "\f573";
+}
+
+.fa-file-arrow-up {
+ --fa: "\f574";
+}
+
+.fa-file-upload {
+ --fa: "\f574";
+}
+
+.fa-fill {
+ --fa: "\f575";
+}
+
+.fa-fill-drip {
+ --fa: "\f576";
+}
+
+.fa-fingerprint {
+ --fa: "\f577";
+}
+
+.fa-fish {
+ --fa: "\f578";
+}
+
+.fa-face-flushed {
+ --fa: "\f579";
+}
+
+.fa-flushed {
+ --fa: "\f579";
+}
+
+.fa-face-frown-open {
+ --fa: "\f57a";
+}
+
+.fa-frown-open {
+ --fa: "\f57a";
+}
+
+.fa-martini-glass {
+ --fa: "\f57b";
+}
+
+.fa-glass-martini-alt {
+ --fa: "\f57b";
+}
+
+.fa-earth-africa {
+ --fa: "\f57c";
+}
+
+.fa-globe-africa {
+ --fa: "\f57c";
+}
+
+.fa-earth-americas {
+ --fa: "\f57d";
+}
+
+.fa-earth {
+ --fa: "\f57d";
+}
+
+.fa-earth-america {
+ --fa: "\f57d";
+}
+
+.fa-globe-americas {
+ --fa: "\f57d";
+}
+
+.fa-earth-asia {
+ --fa: "\f57e";
+}
+
+.fa-globe-asia {
+ --fa: "\f57e";
+}
+
+.fa-face-grimace {
+ --fa: "\f57f";
+}
+
+.fa-grimace {
+ --fa: "\f57f";
+}
+
+.fa-face-grin {
+ --fa: "\f580";
+}
+
+.fa-grin {
+ --fa: "\f580";
+}
+
+.fa-face-grin-wide {
+ --fa: "\f581";
+}
+
+.fa-grin-alt {
+ --fa: "\f581";
+}
+
+.fa-face-grin-beam {
+ --fa: "\f582";
+}
+
+.fa-grin-beam {
+ --fa: "\f582";
+}
+
+.fa-face-grin-beam-sweat {
+ --fa: "\f583";
+}
+
+.fa-grin-beam-sweat {
+ --fa: "\f583";
+}
+
+.fa-face-grin-hearts {
+ --fa: "\f584";
+}
+
+.fa-grin-hearts {
+ --fa: "\f584";
+}
+
+.fa-face-grin-squint {
+ --fa: "\f585";
+}
+
+.fa-grin-squint {
+ --fa: "\f585";
+}
+
+.fa-face-grin-squint-tears {
+ --fa: "\f586";
+}
+
+.fa-grin-squint-tears {
+ --fa: "\f586";
+}
+
+.fa-face-grin-stars {
+ --fa: "\f587";
+}
+
+.fa-grin-stars {
+ --fa: "\f587";
+}
+
+.fa-face-grin-tears {
+ --fa: "\f588";
+}
+
+.fa-grin-tears {
+ --fa: "\f588";
+}
+
+.fa-face-grin-tongue {
+ --fa: "\f589";
+}
+
+.fa-grin-tongue {
+ --fa: "\f589";
+}
+
+.fa-face-grin-tongue-squint {
+ --fa: "\f58a";
+}
+
+.fa-grin-tongue-squint {
+ --fa: "\f58a";
+}
+
+.fa-face-grin-tongue-wink {
+ --fa: "\f58b";
+}
+
+.fa-grin-tongue-wink {
+ --fa: "\f58b";
+}
+
+.fa-face-grin-wink {
+ --fa: "\f58c";
+}
+
+.fa-grin-wink {
+ --fa: "\f58c";
+}
+
+.fa-grip {
+ --fa: "\f58d";
+}
+
+.fa-grid-horizontal {
+ --fa: "\f58d";
+}
+
+.fa-grip-horizontal {
+ --fa: "\f58d";
+}
+
+.fa-grip-vertical {
+ --fa: "\f58e";
+}
+
+.fa-grid-vertical {
+ --fa: "\f58e";
+}
+
+.fa-headset {
+ --fa: "\f590";
+}
+
+.fa-highlighter {
+ --fa: "\f591";
+}
+
+.fa-hot-tub-person {
+ --fa: "\f593";
+}
+
+.fa-hot-tub {
+ --fa: "\f593";
+}
+
+.fa-hotel {
+ --fa: "\f594";
+}
+
+.fa-joint {
+ --fa: "\f595";
+}
+
+.fa-face-kiss {
+ --fa: "\f596";
+}
+
+.fa-kiss {
+ --fa: "\f596";
+}
+
+.fa-face-kiss-beam {
+ --fa: "\f597";
+}
+
+.fa-kiss-beam {
+ --fa: "\f597";
+}
+
+.fa-face-kiss-wink-heart {
+ --fa: "\f598";
+}
+
+.fa-kiss-wink-heart {
+ --fa: "\f598";
+}
+
+.fa-face-laugh {
+ --fa: "\f599";
+}
+
+.fa-laugh {
+ --fa: "\f599";
+}
+
+.fa-face-laugh-beam {
+ --fa: "\f59a";
+}
+
+.fa-laugh-beam {
+ --fa: "\f59a";
+}
+
+.fa-face-laugh-squint {
+ --fa: "\f59b";
+}
+
+.fa-laugh-squint {
+ --fa: "\f59b";
+}
+
+.fa-face-laugh-wink {
+ --fa: "\f59c";
+}
+
+.fa-laugh-wink {
+ --fa: "\f59c";
+}
+
+.fa-cart-flatbed-suitcase {
+ --fa: "\f59d";
+}
+
+.fa-luggage-cart {
+ --fa: "\f59d";
+}
+
+.fa-map-location {
+ --fa: "\f59f";
+}
+
+.fa-map-marked {
+ --fa: "\f59f";
+}
+
+.fa-map-location-dot {
+ --fa: "\f5a0";
+}
+
+.fa-map-marked-alt {
+ --fa: "\f5a0";
+}
+
+.fa-marker {
+ --fa: "\f5a1";
+}
+
+.fa-medal {
+ --fa: "\f5a2";
+}
+
+.fa-face-meh-blank {
+ --fa: "\f5a4";
+}
+
+.fa-meh-blank {
+ --fa: "\f5a4";
+}
+
+.fa-face-rolling-eyes {
+ --fa: "\f5a5";
+}
+
+.fa-meh-rolling-eyes {
+ --fa: "\f5a5";
+}
+
+.fa-monument {
+ --fa: "\f5a6";
+}
+
+.fa-mortar-pestle {
+ --fa: "\f5a7";
+}
+
+.fa-paint-roller {
+ --fa: "\f5aa";
+}
+
+.fa-passport {
+ --fa: "\f5ab";
+}
+
+.fa-pen-fancy {
+ --fa: "\f5ac";
+}
+
+.fa-pen-nib {
+ --fa: "\f5ad";
+}
+
+.fa-pen-ruler {
+ --fa: "\f5ae";
+}
+
+.fa-pencil-ruler {
+ --fa: "\f5ae";
+}
+
+.fa-plane-arrival {
+ --fa: "\f5af";
+}
+
+.fa-plane-departure {
+ --fa: "\f5b0";
+}
+
+.fa-prescription {
+ --fa: "\f5b1";
+}
+
+.fa-face-sad-cry {
+ --fa: "\f5b3";
+}
+
+.fa-sad-cry {
+ --fa: "\f5b3";
+}
+
+.fa-face-sad-tear {
+ --fa: "\f5b4";
+}
+
+.fa-sad-tear {
+ --fa: "\f5b4";
+}
+
+.fa-van-shuttle {
+ --fa: "\f5b6";
+}
+
+.fa-shuttle-van {
+ --fa: "\f5b6";
+}
+
+.fa-signature {
+ --fa: "\f5b7";
+}
+
+.fa-face-smile-beam {
+ --fa: "\f5b8";
+}
+
+.fa-smile-beam {
+ --fa: "\f5b8";
+}
+
+.fa-solar-panel {
+ --fa: "\f5ba";
+}
+
+.fa-spa {
+ --fa: "\f5bb";
+}
+
+.fa-splotch {
+ --fa: "\f5bc";
+}
+
+.fa-spray-can {
+ --fa: "\f5bd";
+}
+
+.fa-stamp {
+ --fa: "\f5bf";
+}
+
+.fa-star-half-stroke {
+ --fa: "\f5c0";
+}
+
+.fa-star-half-alt {
+ --fa: "\f5c0";
+}
+
+.fa-suitcase-rolling {
+ --fa: "\f5c1";
+}
+
+.fa-face-surprise {
+ --fa: "\f5c2";
+}
+
+.fa-surprise {
+ --fa: "\f5c2";
+}
+
+.fa-swatchbook {
+ --fa: "\f5c3";
+}
+
+.fa-person-swimming {
+ --fa: "\f5c4";
+}
+
+.fa-swimmer {
+ --fa: "\f5c4";
+}
+
+.fa-water-ladder {
+ --fa: "\f5c5";
+}
+
+.fa-ladder-water {
+ --fa: "\f5c5";
+}
+
+.fa-swimming-pool {
+ --fa: "\f5c5";
+}
+
+.fa-droplet-slash {
+ --fa: "\f5c7";
+}
+
+.fa-tint-slash {
+ --fa: "\f5c7";
+}
+
+.fa-face-tired {
+ --fa: "\f5c8";
+}
+
+.fa-tired {
+ --fa: "\f5c8";
+}
+
+.fa-tooth {
+ --fa: "\f5c9";
+}
+
+.fa-umbrella-beach {
+ --fa: "\f5ca";
+}
+
+.fa-weight-hanging {
+ --fa: "\f5cd";
+}
+
+.fa-wine-glass-empty {
+ --fa: "\f5ce";
+}
+
+.fa-wine-glass-alt {
+ --fa: "\f5ce";
+}
+
+.fa-spray-can-sparkles {
+ --fa: "\f5d0";
+}
+
+.fa-air-freshener {
+ --fa: "\f5d0";
+}
+
+.fa-apple-whole {
+ --fa: "\f5d1";
+}
+
+.fa-apple-alt {
+ --fa: "\f5d1";
+}
+
+.fa-atom {
+ --fa: "\f5d2";
+}
+
+.fa-bone {
+ --fa: "\f5d7";
+}
+
+.fa-book-open-reader {
+ --fa: "\f5da";
+}
+
+.fa-book-reader {
+ --fa: "\f5da";
+}
+
+.fa-brain {
+ --fa: "\f5dc";
+}
+
+.fa-car-rear {
+ --fa: "\f5de";
+}
+
+.fa-car-alt {
+ --fa: "\f5de";
+}
+
+.fa-car-battery {
+ --fa: "\f5df";
+}
+
+.fa-battery-car {
+ --fa: "\f5df";
+}
+
+.fa-car-burst {
+ --fa: "\f5e1";
+}
+
+.fa-car-crash {
+ --fa: "\f5e1";
+}
+
+.fa-car-side {
+ --fa: "\f5e4";
+}
+
+.fa-charging-station {
+ --fa: "\f5e7";
+}
+
+.fa-diamond-turn-right {
+ --fa: "\f5eb";
+}
+
+.fa-directions {
+ --fa: "\f5eb";
+}
+
+.fa-draw-polygon {
+ --fa: "\f5ee";
+}
+
+.fa-vector-polygon {
+ --fa: "\f5ee";
+}
+
+.fa-laptop-code {
+ --fa: "\f5fc";
+}
+
+.fa-layer-group {
+ --fa: "\f5fd";
+}
+
+.fa-location-crosshairs {
+ --fa: "\f601";
+}
+
+.fa-location {
+ --fa: "\f601";
+}
+
+.fa-lungs {
+ --fa: "\f604";
+}
+
+.fa-microscope {
+ --fa: "\f610";
+}
+
+.fa-oil-can {
+ --fa: "\f613";
+}
+
+.fa-poop {
+ --fa: "\f619";
+}
+
+.fa-shapes {
+ --fa: "\f61f";
+}
+
+.fa-triangle-circle-square {
+ --fa: "\f61f";
+}
+
+.fa-star-of-life {
+ --fa: "\f621";
+}
+
+.fa-gauge {
+ --fa: "\f624";
+}
+
+.fa-dashboard {
+ --fa: "\f624";
+}
+
+.fa-gauge-med {
+ --fa: "\f624";
+}
+
+.fa-tachometer-alt-average {
+ --fa: "\f624";
+}
+
+.fa-gauge-high {
+ --fa: "\f625";
+}
+
+.fa-tachometer-alt {
+ --fa: "\f625";
+}
+
+.fa-tachometer-alt-fast {
+ --fa: "\f625";
+}
+
+.fa-gauge-simple {
+ --fa: "\f629";
+}
+
+.fa-gauge-simple-med {
+ --fa: "\f629";
+}
+
+.fa-tachometer-average {
+ --fa: "\f629";
+}
+
+.fa-gauge-simple-high {
+ --fa: "\f62a";
+}
+
+.fa-tachometer {
+ --fa: "\f62a";
+}
+
+.fa-tachometer-fast {
+ --fa: "\f62a";
+}
+
+.fa-teeth {
+ --fa: "\f62e";
+}
+
+.fa-teeth-open {
+ --fa: "\f62f";
+}
+
+.fa-masks-theater {
+ --fa: "\f630";
+}
+
+.fa-theater-masks {
+ --fa: "\f630";
+}
+
+.fa-traffic-light {
+ --fa: "\f637";
+}
+
+.fa-truck-monster {
+ --fa: "\f63b";
+}
+
+.fa-truck-pickup {
+ --fa: "\f63c";
+}
+
+.fa-rectangle-ad {
+ --fa: "\f641";
+}
+
+.fa-ad {
+ --fa: "\f641";
+}
+
+.fa-ankh {
+ --fa: "\f644";
+}
+
+.fa-book-bible {
+ --fa: "\f647";
+}
+
+.fa-bible {
+ --fa: "\f647";
+}
+
+.fa-business-time {
+ --fa: "\f64a";
+}
+
+.fa-briefcase-clock {
+ --fa: "\f64a";
+}
+
+.fa-city {
+ --fa: "\f64f";
+}
+
+.fa-comment-dollar {
+ --fa: "\f651";
+}
+
+.fa-comments-dollar {
+ --fa: "\f653";
+}
+
+.fa-cross {
+ --fa: "\f654";
+}
+
+.fa-dharmachakra {
+ --fa: "\f655";
+}
+
+.fa-envelope-open-text {
+ --fa: "\f658";
+}
+
+.fa-folder-minus {
+ --fa: "\f65d";
+}
+
+.fa-folder-plus {
+ --fa: "\f65e";
+}
+
+.fa-filter-circle-dollar {
+ --fa: "\f662";
+}
+
+.fa-funnel-dollar {
+ --fa: "\f662";
+}
+
+.fa-gopuram {
+ --fa: "\f664";
+}
+
+.fa-hamsa {
+ --fa: "\f665";
+}
+
+.fa-bahai {
+ --fa: "\f666";
+}
+
+.fa-haykal {
+ --fa: "\f666";
+}
+
+.fa-jedi {
+ --fa: "\f669";
+}
+
+.fa-book-journal-whills {
+ --fa: "\f66a";
+}
+
+.fa-journal-whills {
+ --fa: "\f66a";
+}
+
+.fa-kaaba {
+ --fa: "\f66b";
+}
+
+.fa-khanda {
+ --fa: "\f66d";
+}
+
+.fa-landmark {
+ --fa: "\f66f";
+}
+
+.fa-envelopes-bulk {
+ --fa: "\f674";
+}
+
+.fa-mail-bulk {
+ --fa: "\f674";
+}
+
+.fa-menorah {
+ --fa: "\f676";
+}
+
+.fa-mosque {
+ --fa: "\f678";
+}
+
+.fa-om {
+ --fa: "\f679";
+}
+
+.fa-spaghetti-monster-flying {
+ --fa: "\f67b";
+}
+
+.fa-pastafarianism {
+ --fa: "\f67b";
+}
+
+.fa-peace {
+ --fa: "\f67c";
+}
+
+.fa-place-of-worship {
+ --fa: "\f67f";
+}
+
+.fa-square-poll-vertical {
+ --fa: "\f681";
+}
+
+.fa-poll {
+ --fa: "\f681";
+}
+
+.fa-square-poll-horizontal {
+ --fa: "\f682";
+}
+
+.fa-poll-h {
+ --fa: "\f682";
+}
+
+.fa-person-praying {
+ --fa: "\f683";
+}
+
+.fa-pray {
+ --fa: "\f683";
+}
+
+.fa-hands-praying {
+ --fa: "\f684";
+}
+
+.fa-praying-hands {
+ --fa: "\f684";
+}
+
+.fa-book-quran {
+ --fa: "\f687";
+}
+
+.fa-quran {
+ --fa: "\f687";
+}
+
+.fa-magnifying-glass-dollar {
+ --fa: "\f688";
+}
+
+.fa-search-dollar {
+ --fa: "\f688";
+}
+
+.fa-magnifying-glass-location {
+ --fa: "\f689";
+}
+
+.fa-search-location {
+ --fa: "\f689";
+}
+
+.fa-socks {
+ --fa: "\f696";
+}
+
+.fa-square-root-variable {
+ --fa: "\f698";
+}
+
+.fa-square-root-alt {
+ --fa: "\f698";
+}
+
+.fa-star-and-crescent {
+ --fa: "\f699";
+}
+
+.fa-star-of-david {
+ --fa: "\f69a";
+}
+
+.fa-synagogue {
+ --fa: "\f69b";
+}
+
+.fa-scroll-torah {
+ --fa: "\f6a0";
+}
+
+.fa-torah {
+ --fa: "\f6a0";
+}
+
+.fa-torii-gate {
+ --fa: "\f6a1";
+}
+
+.fa-vihara {
+ --fa: "\f6a7";
+}
+
+.fa-volume-xmark {
+ --fa: "\f6a9";
+}
+
+.fa-volume-mute {
+ --fa: "\f6a9";
+}
+
+.fa-volume-times {
+ --fa: "\f6a9";
+}
+
+.fa-yin-yang {
+ --fa: "\f6ad";
+}
+
+.fa-blender-phone {
+ --fa: "\f6b6";
+}
+
+.fa-book-skull {
+ --fa: "\f6b7";
+}
+
+.fa-book-dead {
+ --fa: "\f6b7";
+}
+
+.fa-campground {
+ --fa: "\f6bb";
+}
+
+.fa-cat {
+ --fa: "\f6be";
+}
+
+.fa-chair {
+ --fa: "\f6c0";
+}
+
+.fa-cloud-moon {
+ --fa: "\f6c3";
+}
+
+.fa-cloud-sun {
+ --fa: "\f6c4";
+}
+
+.fa-cow {
+ --fa: "\f6c8";
+}
+
+.fa-dice-d20 {
+ --fa: "\f6cf";
+}
+
+.fa-dice-d6 {
+ --fa: "\f6d1";
+}
+
+.fa-dog {
+ --fa: "\f6d3";
+}
+
+.fa-dragon {
+ --fa: "\f6d5";
+}
+
+.fa-drumstick-bite {
+ --fa: "\f6d7";
+}
+
+.fa-dungeon {
+ --fa: "\f6d9";
+}
+
+.fa-file-csv {
+ --fa: "\f6dd";
+}
+
+.fa-hand-fist {
+ --fa: "\f6de";
+}
+
+.fa-fist-raised {
+ --fa: "\f6de";
+}
+
+.fa-ghost {
+ --fa: "\f6e2";
+}
+
+.fa-hammer {
+ --fa: "\f6e3";
+}
+
+.fa-hanukiah {
+ --fa: "\f6e6";
+}
+
+.fa-hat-wizard {
+ --fa: "\f6e8";
+}
+
+.fa-person-hiking {
+ --fa: "\f6ec";
+}
+
+.fa-hiking {
+ --fa: "\f6ec";
+}
+
+.fa-hippo {
+ --fa: "\f6ed";
+}
+
+.fa-horse {
+ --fa: "\f6f0";
+}
+
+.fa-house-chimney-crack {
+ --fa: "\f6f1";
+}
+
+.fa-house-damage {
+ --fa: "\f6f1";
+}
+
+.fa-hryvnia-sign {
+ --fa: "\f6f2";
+}
+
+.fa-hryvnia {
+ --fa: "\f6f2";
+}
+
+.fa-mask {
+ --fa: "\f6fa";
+}
+
+.fa-mountain {
+ --fa: "\f6fc";
+}
+
+.fa-network-wired {
+ --fa: "\f6ff";
+}
+
+.fa-otter {
+ --fa: "\f700";
+}
+
+.fa-ring {
+ --fa: "\f70b";
+}
+
+.fa-person-running {
+ --fa: "\f70c";
+}
+
+.fa-running {
+ --fa: "\f70c";
+}
+
+.fa-scroll {
+ --fa: "\f70e";
+}
+
+.fa-skull-crossbones {
+ --fa: "\f714";
+}
+
+.fa-slash {
+ --fa: "\f715";
+}
+
+.fa-spider {
+ --fa: "\f717";
+}
+
+.fa-toilet-paper {
+ --fa: "\f71e";
+}
+
+.fa-toilet-paper-alt {
+ --fa: "\f71e";
+}
+
+.fa-toilet-paper-blank {
+ --fa: "\f71e";
+}
+
+.fa-tractor {
+ --fa: "\f722";
+}
+
+.fa-user-injured {
+ --fa: "\f728";
+}
+
+.fa-vr-cardboard {
+ --fa: "\f729";
+}
+
+.fa-wand-sparkles {
+ --fa: "\f72b";
+}
+
+.fa-wind {
+ --fa: "\f72e";
+}
+
+.fa-wine-bottle {
+ --fa: "\f72f";
+}
+
+.fa-cloud-meatball {
+ --fa: "\f73b";
+}
+
+.fa-cloud-moon-rain {
+ --fa: "\f73c";
+}
+
+.fa-cloud-rain {
+ --fa: "\f73d";
+}
+
+.fa-cloud-showers-heavy {
+ --fa: "\f740";
+}
+
+.fa-cloud-sun-rain {
+ --fa: "\f743";
+}
+
+.fa-democrat {
+ --fa: "\f747";
+}
+
+.fa-flag-usa {
+ --fa: "\f74d";
+}
+
+.fa-hurricane {
+ --fa: "\f751";
+}
+
+.fa-landmark-dome {
+ --fa: "\f752";
+}
+
+.fa-landmark-alt {
+ --fa: "\f752";
+}
+
+.fa-meteor {
+ --fa: "\f753";
+}
+
+.fa-person-booth {
+ --fa: "\f756";
+}
+
+.fa-poo-storm {
+ --fa: "\f75a";
+}
+
+.fa-poo-bolt {
+ --fa: "\f75a";
+}
+
+.fa-rainbow {
+ --fa: "\f75b";
+}
+
+.fa-republican {
+ --fa: "\f75e";
+}
+
+.fa-smog {
+ --fa: "\f75f";
+}
+
+.fa-temperature-high {
+ --fa: "\f769";
+}
+
+.fa-temperature-low {
+ --fa: "\f76b";
+}
+
+.fa-cloud-bolt {
+ --fa: "\f76c";
+}
+
+.fa-thunderstorm {
+ --fa: "\f76c";
+}
+
+.fa-tornado {
+ --fa: "\f76f";
+}
+
+.fa-volcano {
+ --fa: "\f770";
+}
+
+.fa-check-to-slot {
+ --fa: "\f772";
+}
+
+.fa-vote-yea {
+ --fa: "\f772";
+}
+
+.fa-water {
+ --fa: "\f773";
+}
+
+.fa-baby {
+ --fa: "\f77c";
+}
+
+.fa-baby-carriage {
+ --fa: "\f77d";
+}
+
+.fa-carriage-baby {
+ --fa: "\f77d";
+}
+
+.fa-biohazard {
+ --fa: "\f780";
+}
+
+.fa-blog {
+ --fa: "\f781";
+}
+
+.fa-calendar-day {
+ --fa: "\f783";
+}
+
+.fa-calendar-week {
+ --fa: "\f784";
+}
+
+.fa-candy-cane {
+ --fa: "\f786";
+}
+
+.fa-carrot {
+ --fa: "\f787";
+}
+
+.fa-cash-register {
+ --fa: "\f788";
+}
+
+.fa-minimize {
+ --fa: "\f78c";
+}
+
+.fa-compress-arrows-alt {
+ --fa: "\f78c";
+}
+
+.fa-dumpster {
+ --fa: "\f793";
+}
+
+.fa-dumpster-fire {
+ --fa: "\f794";
+}
+
+.fa-ethernet {
+ --fa: "\f796";
+}
+
+.fa-gifts {
+ --fa: "\f79c";
+}
+
+.fa-champagne-glasses {
+ --fa: "\f79f";
+}
+
+.fa-glass-cheers {
+ --fa: "\f79f";
+}
+
+.fa-whiskey-glass {
+ --fa: "\f7a0";
+}
+
+.fa-glass-whiskey {
+ --fa: "\f7a0";
+}
+
+.fa-earth-europe {
+ --fa: "\f7a2";
+}
+
+.fa-globe-europe {
+ --fa: "\f7a2";
+}
+
+.fa-grip-lines {
+ --fa: "\f7a4";
+}
+
+.fa-grip-lines-vertical {
+ --fa: "\f7a5";
+}
+
+.fa-guitar {
+ --fa: "\f7a6";
+}
+
+.fa-heart-crack {
+ --fa: "\f7a9";
+}
+
+.fa-heart-broken {
+ --fa: "\f7a9";
+}
+
+.fa-holly-berry {
+ --fa: "\f7aa";
+}
+
+.fa-horse-head {
+ --fa: "\f7ab";
+}
+
+.fa-icicles {
+ --fa: "\f7ad";
+}
+
+.fa-igloo {
+ --fa: "\f7ae";
+}
+
+.fa-mitten {
+ --fa: "\f7b5";
+}
+
+.fa-mug-hot {
+ --fa: "\f7b6";
+}
+
+.fa-radiation {
+ --fa: "\f7b9";
+}
+
+.fa-circle-radiation {
+ --fa: "\f7ba";
+}
+
+.fa-radiation-alt {
+ --fa: "\f7ba";
+}
+
+.fa-restroom {
+ --fa: "\f7bd";
+}
+
+.fa-satellite {
+ --fa: "\f7bf";
+}
+
+.fa-satellite-dish {
+ --fa: "\f7c0";
+}
+
+.fa-sd-card {
+ --fa: "\f7c2";
+}
+
+.fa-sim-card {
+ --fa: "\f7c4";
+}
+
+.fa-person-skating {
+ --fa: "\f7c5";
+}
+
+.fa-skating {
+ --fa: "\f7c5";
+}
+
+.fa-person-skiing {
+ --fa: "\f7c9";
+}
+
+.fa-skiing {
+ --fa: "\f7c9";
+}
+
+.fa-person-skiing-nordic {
+ --fa: "\f7ca";
+}
+
+.fa-skiing-nordic {
+ --fa: "\f7ca";
+}
+
+.fa-sleigh {
+ --fa: "\f7cc";
+}
+
+.fa-comment-sms {
+ --fa: "\f7cd";
+}
+
+.fa-sms {
+ --fa: "\f7cd";
+}
+
+.fa-person-snowboarding {
+ --fa: "\f7ce";
+}
+
+.fa-snowboarding {
+ --fa: "\f7ce";
+}
+
+.fa-snowman {
+ --fa: "\f7d0";
+}
+
+.fa-snowplow {
+ --fa: "\f7d2";
+}
+
+.fa-tenge-sign {
+ --fa: "\f7d7";
+}
+
+.fa-tenge {
+ --fa: "\f7d7";
+}
+
+.fa-toilet {
+ --fa: "\f7d8";
+}
+
+.fa-screwdriver-wrench {
+ --fa: "\f7d9";
+}
+
+.fa-tools {
+ --fa: "\f7d9";
+}
+
+.fa-cable-car {
+ --fa: "\f7da";
+}
+
+.fa-tram {
+ --fa: "\f7da";
+}
+
+.fa-fire-flame-curved {
+ --fa: "\f7e4";
+}
+
+.fa-fire-alt {
+ --fa: "\f7e4";
+}
+
+.fa-bacon {
+ --fa: "\f7e5";
+}
+
+.fa-book-medical {
+ --fa: "\f7e6";
+}
+
+.fa-bread-slice {
+ --fa: "\f7ec";
+}
+
+.fa-cheese {
+ --fa: "\f7ef";
+}
+
+.fa-house-chimney-medical {
+ --fa: "\f7f2";
+}
+
+.fa-clinic-medical {
+ --fa: "\f7f2";
+}
+
+.fa-clipboard-user {
+ --fa: "\f7f3";
+}
+
+.fa-comment-medical {
+ --fa: "\f7f5";
+}
+
+.fa-crutch {
+ --fa: "\f7f7";
+}
+
+.fa-disease {
+ --fa: "\f7fa";
+}
+
+.fa-egg {
+ --fa: "\f7fb";
+}
+
+.fa-folder-tree {
+ --fa: "\f802";
+}
+
+.fa-burger {
+ --fa: "\f805";
+}
+
+.fa-hamburger {
+ --fa: "\f805";
+}
+
+.fa-hand-middle-finger {
+ --fa: "\f806";
+}
+
+.fa-helmet-safety {
+ --fa: "\f807";
+}
+
+.fa-hard-hat {
+ --fa: "\f807";
+}
+
+.fa-hat-hard {
+ --fa: "\f807";
+}
+
+.fa-hospital-user {
+ --fa: "\f80d";
+}
+
+.fa-hotdog {
+ --fa: "\f80f";
+}
+
+.fa-ice-cream {
+ --fa: "\f810";
+}
+
+.fa-laptop-medical {
+ --fa: "\f812";
+}
+
+.fa-pager {
+ --fa: "\f815";
+}
+
+.fa-pepper-hot {
+ --fa: "\f816";
+}
+
+.fa-pizza-slice {
+ --fa: "\f818";
+}
+
+.fa-sack-dollar {
+ --fa: "\f81d";
+}
+
+.fa-book-tanakh {
+ --fa: "\f827";
+}
+
+.fa-tanakh {
+ --fa: "\f827";
+}
+
+.fa-bars-progress {
+ --fa: "\f828";
+}
+
+.fa-tasks-alt {
+ --fa: "\f828";
+}
+
+.fa-trash-arrow-up {
+ --fa: "\f829";
+}
+
+.fa-trash-restore {
+ --fa: "\f829";
+}
+
+.fa-trash-can-arrow-up {
+ --fa: "\f82a";
+}
+
+.fa-trash-restore-alt {
+ --fa: "\f82a";
+}
+
+.fa-user-nurse {
+ --fa: "\f82f";
+}
+
+.fa-wave-square {
+ --fa: "\f83e";
+}
+
+.fa-person-biking {
+ --fa: "\f84a";
+}
+
+.fa-biking {
+ --fa: "\f84a";
+}
+
+.fa-border-all {
+ --fa: "\f84c";
+}
+
+.fa-border-none {
+ --fa: "\f850";
+}
+
+.fa-border-top-left {
+ --fa: "\f853";
+}
+
+.fa-border-style {
+ --fa: "\f853";
+}
+
+.fa-person-digging {
+ --fa: "\f85e";
+}
+
+.fa-digging {
+ --fa: "\f85e";
+}
+
+.fa-fan {
+ --fa: "\f863";
+}
+
+.fa-icons {
+ --fa: "\f86d";
+}
+
+.fa-heart-music-camera-bolt {
+ --fa: "\f86d";
+}
+
+.fa-phone-flip {
+ --fa: "\f879";
+}
+
+.fa-phone-alt {
+ --fa: "\f879";
+}
+
+.fa-square-phone-flip {
+ --fa: "\f87b";
+}
+
+.fa-phone-square-alt {
+ --fa: "\f87b";
+}
+
+.fa-photo-film {
+ --fa: "\f87c";
+}
+
+.fa-photo-video {
+ --fa: "\f87c";
+}
+
+.fa-text-slash {
+ --fa: "\f87d";
+}
+
+.fa-remove-format {
+ --fa: "\f87d";
+}
+
+.fa-arrow-down-z-a {
+ --fa: "\f881";
+}
+
+.fa-sort-alpha-desc {
+ --fa: "\f881";
+}
+
+.fa-sort-alpha-down-alt {
+ --fa: "\f881";
+}
+
+.fa-arrow-up-z-a {
+ --fa: "\f882";
+}
+
+.fa-sort-alpha-up-alt {
+ --fa: "\f882";
+}
+
+.fa-arrow-down-short-wide {
+ --fa: "\f884";
+}
+
+.fa-sort-amount-desc {
+ --fa: "\f884";
+}
+
+.fa-sort-amount-down-alt {
+ --fa: "\f884";
+}
+
+.fa-arrow-up-short-wide {
+ --fa: "\f885";
+}
+
+.fa-sort-amount-up-alt {
+ --fa: "\f885";
+}
+
+.fa-arrow-down-9-1 {
+ --fa: "\f886";
+}
+
+.fa-sort-numeric-desc {
+ --fa: "\f886";
+}
+
+.fa-sort-numeric-down-alt {
+ --fa: "\f886";
+}
+
+.fa-arrow-up-9-1 {
+ --fa: "\f887";
+}
+
+.fa-sort-numeric-up-alt {
+ --fa: "\f887";
+}
+
+.fa-spell-check {
+ --fa: "\f891";
+}
+
+.fa-voicemail {
+ --fa: "\f897";
+}
+
+.fa-hat-cowboy {
+ --fa: "\f8c0";
+}
+
+.fa-hat-cowboy-side {
+ --fa: "\f8c1";
+}
+
+.fa-computer-mouse {
+ --fa: "\f8cc";
+}
+
+.fa-mouse {
+ --fa: "\f8cc";
+}
+
+.fa-radio {
+ --fa: "\f8d7";
+}
+
+.fa-record-vinyl {
+ --fa: "\f8d9";
+}
+
+.fa-walkie-talkie {
+ --fa: "\f8ef";
+}
+
+.fa-caravan {
+ --fa: "\f8ff";
+}
+:root, :host {
+ --fa-family-brands: "Font Awesome 7 Brands";
+ --fa-font-brands: normal 400 1em/1 var(--fa-family-brands);
+}
+
+@font-face {
+ font-family: "Font Awesome 7 Brands";
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src: url("../webfonts/fa-brands-400.woff2");
+}
+.fab,
+.fa-brands,
+.fa-classic.fa-brands {
+ --fa-family: var(--fa-family-brands);
+ --fa-style: 400;
+}
+
+.fa-firefox-browser {
+ --fa: "\e007";
+}
+
+.fa-ideal {
+ --fa: "\e013";
+}
+
+.fa-microblog {
+ --fa: "\e01a";
+}
+
+.fa-square-pied-piper {
+ --fa: "\e01e";
+}
+
+.fa-pied-piper-square {
+ --fa: "\e01e";
+}
+
+.fa-unity {
+ --fa: "\e049";
+}
+
+.fa-dailymotion {
+ --fa: "\e052";
+}
+
+.fa-square-instagram {
+ --fa: "\e055";
+}
+
+.fa-instagram-square {
+ --fa: "\e055";
+}
+
+.fa-mixer {
+ --fa: "\e056";
+}
+
+.fa-shopify {
+ --fa: "\e057";
+}
+
+.fa-deezer {
+ --fa: "\e077";
+}
+
+.fa-edge-legacy {
+ --fa: "\e078";
+}
+
+.fa-google-pay {
+ --fa: "\e079";
+}
+
+.fa-rust {
+ --fa: "\e07a";
+}
+
+.fa-tiktok {
+ --fa: "\e07b";
+}
+
+.fa-unsplash {
+ --fa: "\e07c";
+}
+
+.fa-cloudflare {
+ --fa: "\e07d";
+}
+
+.fa-guilded {
+ --fa: "\e07e";
+}
+
+.fa-hive {
+ --fa: "\e07f";
+}
+
+.fa-42-group {
+ --fa: "\e080";
+}
+
+.fa-innosoft {
+ --fa: "\e080";
+}
+
+.fa-instalod {
+ --fa: "\e081";
+}
+
+.fa-octopus-deploy {
+ --fa: "\e082";
+}
+
+.fa-perbyte {
+ --fa: "\e083";
+}
+
+.fa-uncharted {
+ --fa: "\e084";
+}
+
+.fa-watchman-monitoring {
+ --fa: "\e087";
+}
+
+.fa-wodu {
+ --fa: "\e088";
+}
+
+.fa-wirsindhandwerk {
+ --fa: "\e2d0";
+}
+
+.fa-wsh {
+ --fa: "\e2d0";
+}
+
+.fa-bots {
+ --fa: "\e340";
+}
+
+.fa-cmplid {
+ --fa: "\e360";
+}
+
+.fa-bilibili {
+ --fa: "\e3d9";
+}
+
+.fa-golang {
+ --fa: "\e40f";
+}
+
+.fa-pix {
+ --fa: "\e43a";
+}
+
+.fa-sitrox {
+ --fa: "\e44a";
+}
+
+.fa-hashnode {
+ --fa: "\e499";
+}
+
+.fa-meta {
+ --fa: "\e49b";
+}
+
+.fa-padlet {
+ --fa: "\e4a0";
+}
+
+.fa-nfc-directional {
+ --fa: "\e530";
+}
+
+.fa-nfc-symbol {
+ --fa: "\e531";
+}
+
+.fa-screenpal {
+ --fa: "\e570";
+}
+
+.fa-space-awesome {
+ --fa: "\e5ac";
+}
+
+.fa-square-font-awesome {
+ --fa: "\e5ad";
+}
+
+.fa-square-gitlab {
+ --fa: "\e5ae";
+}
+
+.fa-gitlab-square {
+ --fa: "\e5ae";
+}
+
+.fa-odysee {
+ --fa: "\e5c6";
+}
+
+.fa-stubber {
+ --fa: "\e5c7";
+}
+
+.fa-debian {
+ --fa: "\e60b";
+}
+
+.fa-shoelace {
+ --fa: "\e60c";
+}
+
+.fa-threads {
+ --fa: "\e618";
+}
+
+.fa-square-threads {
+ --fa: "\e619";
+}
+
+.fa-square-x-twitter {
+ --fa: "\e61a";
+}
+
+.fa-x-twitter {
+ --fa: "\e61b";
+}
+
+.fa-opensuse {
+ --fa: "\e62b";
+}
+
+.fa-letterboxd {
+ --fa: "\e62d";
+}
+
+.fa-square-letterboxd {
+ --fa: "\e62e";
+}
+
+.fa-mintbit {
+ --fa: "\e62f";
+}
+
+.fa-google-scholar {
+ --fa: "\e63b";
+}
+
+.fa-brave {
+ --fa: "\e63c";
+}
+
+.fa-brave-reverse {
+ --fa: "\e63d";
+}
+
+.fa-pixiv {
+ --fa: "\e640";
+}
+
+.fa-upwork {
+ --fa: "\e641";
+}
+
+.fa-webflow {
+ --fa: "\e65c";
+}
+
+.fa-signal-messenger {
+ --fa: "\e663";
+}
+
+.fa-bluesky {
+ --fa: "\e671";
+}
+
+.fa-jxl {
+ --fa: "\e67b";
+}
+
+.fa-square-upwork {
+ --fa: "\e67c";
+}
+
+.fa-web-awesome {
+ --fa: "\e682";
+}
+
+.fa-square-web-awesome {
+ --fa: "\e683";
+}
+
+.fa-square-web-awesome-stroke {
+ --fa: "\e684";
+}
+
+.fa-dart-lang {
+ --fa: "\e693";
+}
+
+.fa-flutter {
+ --fa: "\e694";
+}
+
+.fa-files-pinwheel {
+ --fa: "\e69f";
+}
+
+.fa-css {
+ --fa: "\e6a2";
+}
+
+.fa-square-bluesky {
+ --fa: "\e6a3";
+}
+
+.fa-openai {
+ --fa: "\e7cf";
+}
+
+.fa-square-linkedin {
+ --fa: "\e7d0";
+}
+
+.fa-cash-app {
+ --fa: "\e7d4";
+}
+
+.fa-disqus {
+ --fa: "\e7d5";
+}
+
+.fa-eleventy {
+ --fa: "\e7d6";
+}
+
+.fa-11ty {
+ --fa: "\e7d6";
+}
+
+.fa-kakao-talk {
+ --fa: "\e7d7";
+}
+
+.fa-linktree {
+ --fa: "\e7d8";
+}
+
+.fa-notion {
+ --fa: "\e7d9";
+}
+
+.fa-pandora {
+ --fa: "\e7da";
+}
+
+.fa-pixelfed {
+ --fa: "\e7db";
+}
+
+.fa-tidal {
+ --fa: "\e7dc";
+}
+
+.fa-vsco {
+ --fa: "\e7dd";
+}
+
+.fa-w3c {
+ --fa: "\e7de";
+}
+
+.fa-lumon {
+ --fa: "\e7e2";
+}
+
+.fa-lumon-drop {
+ --fa: "\e7e3";
+}
+
+.fa-square-figma {
+ --fa: "\e7e4";
+}
+
+.fa-tex {
+ --fa: "\e7ff";
+}
+
+.fa-duolingo {
+ --fa: "\e812";
+}
+
+.fa-square-twitter {
+ --fa: "\f081";
+}
+
+.fa-twitter-square {
+ --fa: "\f081";
+}
+
+.fa-square-facebook {
+ --fa: "\f082";
+}
+
+.fa-facebook-square {
+ --fa: "\f082";
+}
+
+.fa-linkedin {
+ --fa: "\f08c";
+}
+
+.fa-square-github {
+ --fa: "\f092";
+}
+
+.fa-github-square {
+ --fa: "\f092";
+}
+
+.fa-twitter {
+ --fa: "\f099";
+}
+
+.fa-facebook {
+ --fa: "\f09a";
+}
+
+.fa-github {
+ --fa: "\f09b";
+}
+
+.fa-pinterest {
+ --fa: "\f0d2";
+}
+
+.fa-square-pinterest {
+ --fa: "\f0d3";
+}
+
+.fa-pinterest-square {
+ --fa: "\f0d3";
+}
+
+.fa-square-google-plus {
+ --fa: "\f0d4";
+}
+
+.fa-google-plus-square {
+ --fa: "\f0d4";
+}
+
+.fa-google-plus-g {
+ --fa: "\f0d5";
+}
+
+.fa-linkedin-in {
+ --fa: "\f0e1";
+}
+
+.fa-github-alt {
+ --fa: "\f113";
+}
+
+.fa-maxcdn {
+ --fa: "\f136";
+}
+
+.fa-html5 {
+ --fa: "\f13b";
+}
+
+.fa-css3 {
+ --fa: "\f13c";
+}
+
+.fa-btc {
+ --fa: "\f15a";
+}
+
+.fa-youtube {
+ --fa: "\f167";
+}
+
+.fa-xing {
+ --fa: "\f168";
+}
+
+.fa-square-xing {
+ --fa: "\f169";
+}
+
+.fa-xing-square {
+ --fa: "\f169";
+}
+
+.fa-dropbox {
+ --fa: "\f16b";
+}
+
+.fa-stack-overflow {
+ --fa: "\f16c";
+}
+
+.fa-instagram {
+ --fa: "\f16d";
+}
+
+.fa-flickr {
+ --fa: "\f16e";
+}
+
+.fa-adn {
+ --fa: "\f170";
+}
+
+.fa-bitbucket {
+ --fa: "\f171";
+}
+
+.fa-tumblr {
+ --fa: "\f173";
+}
+
+.fa-square-tumblr {
+ --fa: "\f174";
+}
+
+.fa-tumblr-square {
+ --fa: "\f174";
+}
+
+.fa-apple {
+ --fa: "\f179";
+}
+
+.fa-windows {
+ --fa: "\f17a";
+}
+
+.fa-android {
+ --fa: "\f17b";
+}
+
+.fa-linux {
+ --fa: "\f17c";
+}
+
+.fa-dribbble {
+ --fa: "\f17d";
+}
+
+.fa-skype {
+ --fa: "\f17e";
+}
+
+.fa-foursquare {
+ --fa: "\f180";
+}
+
+.fa-trello {
+ --fa: "\f181";
+}
+
+.fa-gratipay {
+ --fa: "\f184";
+}
+
+.fa-vk {
+ --fa: "\f189";
+}
+
+.fa-weibo {
+ --fa: "\f18a";
+}
+
+.fa-renren {
+ --fa: "\f18b";
+}
+
+.fa-pagelines {
+ --fa: "\f18c";
+}
+
+.fa-stack-exchange {
+ --fa: "\f18d";
+}
+
+.fa-square-vimeo {
+ --fa: "\f194";
+}
+
+.fa-vimeo-square {
+ --fa: "\f194";
+}
+
+.fa-slack {
+ --fa: "\f198";
+}
+
+.fa-slack-hash {
+ --fa: "\f198";
+}
+
+.fa-wordpress {
+ --fa: "\f19a";
+}
+
+.fa-openid {
+ --fa: "\f19b";
+}
+
+.fa-yahoo {
+ --fa: "\f19e";
+}
+
+.fa-google {
+ --fa: "\f1a0";
+}
+
+.fa-reddit {
+ --fa: "\f1a1";
+}
+
+.fa-square-reddit {
+ --fa: "\f1a2";
+}
+
+.fa-reddit-square {
+ --fa: "\f1a2";
+}
+
+.fa-stumbleupon-circle {
+ --fa: "\f1a3";
+}
+
+.fa-stumbleupon {
+ --fa: "\f1a4";
+}
+
+.fa-delicious {
+ --fa: "\f1a5";
+}
+
+.fa-digg {
+ --fa: "\f1a6";
+}
+
+.fa-pied-piper-pp {
+ --fa: "\f1a7";
+}
+
+.fa-pied-piper-alt {
+ --fa: "\f1a8";
+}
+
+.fa-drupal {
+ --fa: "\f1a9";
+}
+
+.fa-joomla {
+ --fa: "\f1aa";
+}
+
+.fa-behance {
+ --fa: "\f1b4";
+}
+
+.fa-square-behance {
+ --fa: "\f1b5";
+}
+
+.fa-behance-square {
+ --fa: "\f1b5";
+}
+
+.fa-steam {
+ --fa: "\f1b6";
+}
+
+.fa-square-steam {
+ --fa: "\f1b7";
+}
+
+.fa-steam-square {
+ --fa: "\f1b7";
+}
+
+.fa-spotify {
+ --fa: "\f1bc";
+}
+
+.fa-deviantart {
+ --fa: "\f1bd";
+}
+
+.fa-soundcloud {
+ --fa: "\f1be";
+}
+
+.fa-vine {
+ --fa: "\f1ca";
+}
+
+.fa-codepen {
+ --fa: "\f1cb";
+}
+
+.fa-jsfiddle {
+ --fa: "\f1cc";
+}
+
+.fa-rebel {
+ --fa: "\f1d0";
+}
+
+.fa-empire {
+ --fa: "\f1d1";
+}
+
+.fa-square-git {
+ --fa: "\f1d2";
+}
+
+.fa-git-square {
+ --fa: "\f1d2";
+}
+
+.fa-git {
+ --fa: "\f1d3";
+}
+
+.fa-hacker-news {
+ --fa: "\f1d4";
+}
+
+.fa-tencent-weibo {
+ --fa: "\f1d5";
+}
+
+.fa-qq {
+ --fa: "\f1d6";
+}
+
+.fa-weixin {
+ --fa: "\f1d7";
+}
+
+.fa-slideshare {
+ --fa: "\f1e7";
+}
+
+.fa-twitch {
+ --fa: "\f1e8";
+}
+
+.fa-yelp {
+ --fa: "\f1e9";
+}
+
+.fa-paypal {
+ --fa: "\f1ed";
+}
+
+.fa-google-wallet {
+ --fa: "\f1ee";
+}
+
+.fa-cc-visa {
+ --fa: "\f1f0";
+}
+
+.fa-cc-mastercard {
+ --fa: "\f1f1";
+}
+
+.fa-cc-discover {
+ --fa: "\f1f2";
+}
+
+.fa-cc-amex {
+ --fa: "\f1f3";
+}
+
+.fa-cc-paypal {
+ --fa: "\f1f4";
+}
+
+.fa-cc-stripe {
+ --fa: "\f1f5";
+}
+
+.fa-lastfm {
+ --fa: "\f202";
+}
+
+.fa-square-lastfm {
+ --fa: "\f203";
+}
+
+.fa-lastfm-square {
+ --fa: "\f203";
+}
+
+.fa-ioxhost {
+ --fa: "\f208";
+}
+
+.fa-angellist {
+ --fa: "\f209";
+}
+
+.fa-buysellads {
+ --fa: "\f20d";
+}
+
+.fa-connectdevelop {
+ --fa: "\f20e";
+}
+
+.fa-dashcube {
+ --fa: "\f210";
+}
+
+.fa-forumbee {
+ --fa: "\f211";
+}
+
+.fa-leanpub {
+ --fa: "\f212";
+}
+
+.fa-sellsy {
+ --fa: "\f213";
+}
+
+.fa-shirtsinbulk {
+ --fa: "\f214";
+}
+
+.fa-simplybuilt {
+ --fa: "\f215";
+}
+
+.fa-skyatlas {
+ --fa: "\f216";
+}
+
+.fa-pinterest-p {
+ --fa: "\f231";
+}
+
+.fa-whatsapp {
+ --fa: "\f232";
+}
+
+.fa-viacoin {
+ --fa: "\f237";
+}
+
+.fa-medium {
+ --fa: "\f23a";
+}
+
+.fa-medium-m {
+ --fa: "\f23a";
+}
+
+.fa-y-combinator {
+ --fa: "\f23b";
+}
+
+.fa-optin-monster {
+ --fa: "\f23c";
+}
+
+.fa-opencart {
+ --fa: "\f23d";
+}
+
+.fa-expeditedssl {
+ --fa: "\f23e";
+}
+
+.fa-cc-jcb {
+ --fa: "\f24b";
+}
+
+.fa-cc-diners-club {
+ --fa: "\f24c";
+}
+
+.fa-creative-commons {
+ --fa: "\f25e";
+}
+
+.fa-gg {
+ --fa: "\f260";
+}
+
+.fa-gg-circle {
+ --fa: "\f261";
+}
+
+.fa-odnoklassniki {
+ --fa: "\f263";
+}
+
+.fa-square-odnoklassniki {
+ --fa: "\f264";
+}
+
+.fa-odnoklassniki-square {
+ --fa: "\f264";
+}
+
+.fa-get-pocket {
+ --fa: "\f265";
+}
+
+.fa-wikipedia-w {
+ --fa: "\f266";
+}
+
+.fa-safari {
+ --fa: "\f267";
+}
+
+.fa-chrome {
+ --fa: "\f268";
+}
+
+.fa-firefox {
+ --fa: "\f269";
+}
+
+.fa-opera {
+ --fa: "\f26a";
+}
+
+.fa-internet-explorer {
+ --fa: "\f26b";
+}
+
+.fa-contao {
+ --fa: "\f26d";
+}
+
+.fa-500px {
+ --fa: "\f26e";
+}
+
+.fa-amazon {
+ --fa: "\f270";
+}
+
+.fa-houzz {
+ --fa: "\f27c";
+}
+
+.fa-vimeo-v {
+ --fa: "\f27d";
+}
+
+.fa-black-tie {
+ --fa: "\f27e";
+}
+
+.fa-fonticons {
+ --fa: "\f280";
+}
+
+.fa-reddit-alien {
+ --fa: "\f281";
+}
+
+.fa-edge {
+ --fa: "\f282";
+}
+
+.fa-codiepie {
+ --fa: "\f284";
+}
+
+.fa-modx {
+ --fa: "\f285";
+}
+
+.fa-fort-awesome {
+ --fa: "\f286";
+}
+
+.fa-usb {
+ --fa: "\f287";
+}
+
+.fa-product-hunt {
+ --fa: "\f288";
+}
+
+.fa-mixcloud {
+ --fa: "\f289";
+}
+
+.fa-scribd {
+ --fa: "\f28a";
+}
+
+.fa-bluetooth {
+ --fa: "\f293";
+}
+
+.fa-bluetooth-b {
+ --fa: "\f294";
+}
+
+.fa-gitlab {
+ --fa: "\f296";
+}
+
+.fa-wpbeginner {
+ --fa: "\f297";
+}
+
+.fa-wpforms {
+ --fa: "\f298";
+}
+
+.fa-envira {
+ --fa: "\f299";
+}
+
+.fa-glide {
+ --fa: "\f2a5";
+}
+
+.fa-glide-g {
+ --fa: "\f2a6";
+}
+
+.fa-viadeo {
+ --fa: "\f2a9";
+}
+
+.fa-square-viadeo {
+ --fa: "\f2aa";
+}
+
+.fa-viadeo-square {
+ --fa: "\f2aa";
+}
+
+.fa-snapchat {
+ --fa: "\f2ab";
+}
+
+.fa-snapchat-ghost {
+ --fa: "\f2ab";
+}
+
+.fa-square-snapchat {
+ --fa: "\f2ad";
+}
+
+.fa-snapchat-square {
+ --fa: "\f2ad";
+}
+
+.fa-pied-piper {
+ --fa: "\f2ae";
+}
+
+.fa-first-order {
+ --fa: "\f2b0";
+}
+
+.fa-yoast {
+ --fa: "\f2b1";
+}
+
+.fa-themeisle {
+ --fa: "\f2b2";
+}
+
+.fa-google-plus {
+ --fa: "\f2b3";
+}
+
+.fa-font-awesome {
+ --fa: "\f2b4";
+}
+
+.fa-font-awesome-flag {
+ --fa: "\f2b4";
+}
+
+.fa-font-awesome-logo-full {
+ --fa: "\f2b4";
+}
+
+.fa-linode {
+ --fa: "\f2b8";
+}
+
+.fa-quora {
+ --fa: "\f2c4";
+}
+
+.fa-free-code-camp {
+ --fa: "\f2c5";
+}
+
+.fa-telegram {
+ --fa: "\f2c6";
+}
+
+.fa-telegram-plane {
+ --fa: "\f2c6";
+}
+
+.fa-bandcamp {
+ --fa: "\f2d5";
+}
+
+.fa-grav {
+ --fa: "\f2d6";
+}
+
+.fa-etsy {
+ --fa: "\f2d7";
+}
+
+.fa-imdb {
+ --fa: "\f2d8";
+}
+
+.fa-ravelry {
+ --fa: "\f2d9";
+}
+
+.fa-sellcast {
+ --fa: "\f2da";
+}
+
+.fa-superpowers {
+ --fa: "\f2dd";
+}
+
+.fa-wpexplorer {
+ --fa: "\f2de";
+}
+
+.fa-meetup {
+ --fa: "\f2e0";
+}
+
+.fa-square-font-awesome-stroke {
+ --fa: "\f35c";
+}
+
+.fa-font-awesome-alt {
+ --fa: "\f35c";
+}
+
+.fa-accessible-icon {
+ --fa: "\f368";
+}
+
+.fa-accusoft {
+ --fa: "\f369";
+}
+
+.fa-adversal {
+ --fa: "\f36a";
+}
+
+.fa-affiliatetheme {
+ --fa: "\f36b";
+}
+
+.fa-algolia {
+ --fa: "\f36c";
+}
+
+.fa-amilia {
+ --fa: "\f36d";
+}
+
+.fa-angrycreative {
+ --fa: "\f36e";
+}
+
+.fa-app-store {
+ --fa: "\f36f";
+}
+
+.fa-app-store-ios {
+ --fa: "\f370";
+}
+
+.fa-apper {
+ --fa: "\f371";
+}
+
+.fa-asymmetrik {
+ --fa: "\f372";
+}
+
+.fa-audible {
+ --fa: "\f373";
+}
+
+.fa-avianex {
+ --fa: "\f374";
+}
+
+.fa-aws {
+ --fa: "\f375";
+}
+
+.fa-bimobject {
+ --fa: "\f378";
+}
+
+.fa-bitcoin {
+ --fa: "\f379";
+}
+
+.fa-bity {
+ --fa: "\f37a";
+}
+
+.fa-blackberry {
+ --fa: "\f37b";
+}
+
+.fa-blogger {
+ --fa: "\f37c";
+}
+
+.fa-blogger-b {
+ --fa: "\f37d";
+}
+
+.fa-buromobelexperte {
+ --fa: "\f37f";
+}
+
+.fa-centercode {
+ --fa: "\f380";
+}
+
+.fa-cloudscale {
+ --fa: "\f383";
+}
+
+.fa-cloudsmith {
+ --fa: "\f384";
+}
+
+.fa-cloudversify {
+ --fa: "\f385";
+}
+
+.fa-cpanel {
+ --fa: "\f388";
+}
+
+.fa-css3-alt {
+ --fa: "\f38b";
+}
+
+.fa-cuttlefish {
+ --fa: "\f38c";
+}
+
+.fa-d-and-d {
+ --fa: "\f38d";
+}
+
+.fa-deploydog {
+ --fa: "\f38e";
+}
+
+.fa-deskpro {
+ --fa: "\f38f";
+}
+
+.fa-digital-ocean {
+ --fa: "\f391";
+}
+
+.fa-discord {
+ --fa: "\f392";
+}
+
+.fa-discourse {
+ --fa: "\f393";
+}
+
+.fa-dochub {
+ --fa: "\f394";
+}
+
+.fa-docker {
+ --fa: "\f395";
+}
+
+.fa-draft2digital {
+ --fa: "\f396";
+}
+
+.fa-square-dribbble {
+ --fa: "\f397";
+}
+
+.fa-dribbble-square {
+ --fa: "\f397";
+}
+
+.fa-dyalog {
+ --fa: "\f399";
+}
+
+.fa-earlybirds {
+ --fa: "\f39a";
+}
+
+.fa-erlang {
+ --fa: "\f39d";
+}
+
+.fa-facebook-f {
+ --fa: "\f39e";
+}
+
+.fa-facebook-messenger {
+ --fa: "\f39f";
+}
+
+.fa-firstdraft {
+ --fa: "\f3a1";
+}
+
+.fa-fonticons-fi {
+ --fa: "\f3a2";
+}
+
+.fa-fort-awesome-alt {
+ --fa: "\f3a3";
+}
+
+.fa-freebsd {
+ --fa: "\f3a4";
+}
+
+.fa-gitkraken {
+ --fa: "\f3a6";
+}
+
+.fa-gofore {
+ --fa: "\f3a7";
+}
+
+.fa-goodreads {
+ --fa: "\f3a8";
+}
+
+.fa-goodreads-g {
+ --fa: "\f3a9";
+}
+
+.fa-google-drive {
+ --fa: "\f3aa";
+}
+
+.fa-google-play {
+ --fa: "\f3ab";
+}
+
+.fa-gripfire {
+ --fa: "\f3ac";
+}
+
+.fa-grunt {
+ --fa: "\f3ad";
+}
+
+.fa-gulp {
+ --fa: "\f3ae";
+}
+
+.fa-square-hacker-news {
+ --fa: "\f3af";
+}
+
+.fa-hacker-news-square {
+ --fa: "\f3af";
+}
+
+.fa-hire-a-helper {
+ --fa: "\f3b0";
+}
+
+.fa-hotjar {
+ --fa: "\f3b1";
+}
+
+.fa-hubspot {
+ --fa: "\f3b2";
+}
+
+.fa-itunes {
+ --fa: "\f3b4";
+}
+
+.fa-itunes-note {
+ --fa: "\f3b5";
+}
+
+.fa-jenkins {
+ --fa: "\f3b6";
+}
+
+.fa-joget {
+ --fa: "\f3b7";
+}
+
+.fa-js {
+ --fa: "\f3b8";
+}
+
+.fa-square-js {
+ --fa: "\f3b9";
+}
+
+.fa-js-square {
+ --fa: "\f3b9";
+}
+
+.fa-keycdn {
+ --fa: "\f3ba";
+}
+
+.fa-kickstarter {
+ --fa: "\f3bb";
+}
+
+.fa-square-kickstarter {
+ --fa: "\f3bb";
+}
+
+.fa-kickstarter-k {
+ --fa: "\f3bc";
+}
+
+.fa-laravel {
+ --fa: "\f3bd";
+}
+
+.fa-line {
+ --fa: "\f3c0";
+}
+
+.fa-lyft {
+ --fa: "\f3c3";
+}
+
+.fa-magento {
+ --fa: "\f3c4";
+}
+
+.fa-medapps {
+ --fa: "\f3c6";
+}
+
+.fa-medrt {
+ --fa: "\f3c8";
+}
+
+.fa-microsoft {
+ --fa: "\f3ca";
+}
+
+.fa-mix {
+ --fa: "\f3cb";
+}
+
+.fa-mizuni {
+ --fa: "\f3cc";
+}
+
+.fa-monero {
+ --fa: "\f3d0";
+}
+
+.fa-napster {
+ --fa: "\f3d2";
+}
+
+.fa-node-js {
+ --fa: "\f3d3";
+}
+
+.fa-npm {
+ --fa: "\f3d4";
+}
+
+.fa-ns8 {
+ --fa: "\f3d5";
+}
+
+.fa-nutritionix {
+ --fa: "\f3d6";
+}
+
+.fa-page4 {
+ --fa: "\f3d7";
+}
+
+.fa-palfed {
+ --fa: "\f3d8";
+}
+
+.fa-patreon {
+ --fa: "\f3d9";
+}
+
+.fa-periscope {
+ --fa: "\f3da";
+}
+
+.fa-phabricator {
+ --fa: "\f3db";
+}
+
+.fa-phoenix-framework {
+ --fa: "\f3dc";
+}
+
+.fa-playstation {
+ --fa: "\f3df";
+}
+
+.fa-pushed {
+ --fa: "\f3e1";
+}
+
+.fa-python {
+ --fa: "\f3e2";
+}
+
+.fa-red-river {
+ --fa: "\f3e3";
+}
+
+.fa-wpressr {
+ --fa: "\f3e4";
+}
+
+.fa-rendact {
+ --fa: "\f3e4";
+}
+
+.fa-replyd {
+ --fa: "\f3e6";
+}
+
+.fa-resolving {
+ --fa: "\f3e7";
+}
+
+.fa-rocketchat {
+ --fa: "\f3e8";
+}
+
+.fa-rockrms {
+ --fa: "\f3e9";
+}
+
+.fa-schlix {
+ --fa: "\f3ea";
+}
+
+.fa-searchengin {
+ --fa: "\f3eb";
+}
+
+.fa-servicestack {
+ --fa: "\f3ec";
+}
+
+.fa-sistrix {
+ --fa: "\f3ee";
+}
+
+.fa-speakap {
+ --fa: "\f3f3";
+}
+
+.fa-staylinked {
+ --fa: "\f3f5";
+}
+
+.fa-steam-symbol {
+ --fa: "\f3f6";
+}
+
+.fa-sticker-mule {
+ --fa: "\f3f7";
+}
+
+.fa-studiovinari {
+ --fa: "\f3f8";
+}
+
+.fa-supple {
+ --fa: "\f3f9";
+}
+
+.fa-uber {
+ --fa: "\f402";
+}
+
+.fa-uikit {
+ --fa: "\f403";
+}
+
+.fa-uniregistry {
+ --fa: "\f404";
+}
+
+.fa-untappd {
+ --fa: "\f405";
+}
+
+.fa-ussunnah {
+ --fa: "\f407";
+}
+
+.fa-vaadin {
+ --fa: "\f408";
+}
+
+.fa-viber {
+ --fa: "\f409";
+}
+
+.fa-vimeo {
+ --fa: "\f40a";
+}
+
+.fa-vnv {
+ --fa: "\f40b";
+}
+
+.fa-square-whatsapp {
+ --fa: "\f40c";
+}
+
+.fa-whatsapp-square {
+ --fa: "\f40c";
+}
+
+.fa-whmcs {
+ --fa: "\f40d";
+}
+
+.fa-wordpress-simple {
+ --fa: "\f411";
+}
+
+.fa-xbox {
+ --fa: "\f412";
+}
+
+.fa-yandex {
+ --fa: "\f413";
+}
+
+.fa-yandex-international {
+ --fa: "\f414";
+}
+
+.fa-apple-pay {
+ --fa: "\f415";
+}
+
+.fa-cc-apple-pay {
+ --fa: "\f416";
+}
+
+.fa-fly {
+ --fa: "\f417";
+}
+
+.fa-node {
+ --fa: "\f419";
+}
+
+.fa-osi {
+ --fa: "\f41a";
+}
+
+.fa-react {
+ --fa: "\f41b";
+}
+
+.fa-autoprefixer {
+ --fa: "\f41c";
+}
+
+.fa-less {
+ --fa: "\f41d";
+}
+
+.fa-sass {
+ --fa: "\f41e";
+}
+
+.fa-vuejs {
+ --fa: "\f41f";
+}
+
+.fa-angular {
+ --fa: "\f420";
+}
+
+.fa-aviato {
+ --fa: "\f421";
+}
+
+.fa-ember {
+ --fa: "\f423";
+}
+
+.fa-gitter {
+ --fa: "\f426";
+}
+
+.fa-hooli {
+ --fa: "\f427";
+}
+
+.fa-strava {
+ --fa: "\f428";
+}
+
+.fa-stripe {
+ --fa: "\f429";
+}
+
+.fa-stripe-s {
+ --fa: "\f42a";
+}
+
+.fa-typo3 {
+ --fa: "\f42b";
+}
+
+.fa-amazon-pay {
+ --fa: "\f42c";
+}
+
+.fa-cc-amazon-pay {
+ --fa: "\f42d";
+}
+
+.fa-ethereum {
+ --fa: "\f42e";
+}
+
+.fa-korvue {
+ --fa: "\f42f";
+}
+
+.fa-elementor {
+ --fa: "\f430";
+}
+
+.fa-square-youtube {
+ --fa: "\f431";
+}
+
+.fa-youtube-square {
+ --fa: "\f431";
+}
+
+.fa-flipboard {
+ --fa: "\f44d";
+}
+
+.fa-hips {
+ --fa: "\f452";
+}
+
+.fa-php {
+ --fa: "\f457";
+}
+
+.fa-quinscape {
+ --fa: "\f459";
+}
+
+.fa-readme {
+ --fa: "\f4d5";
+}
+
+.fa-java {
+ --fa: "\f4e4";
+}
+
+.fa-pied-piper-hat {
+ --fa: "\f4e5";
+}
+
+.fa-creative-commons-by {
+ --fa: "\f4e7";
+}
+
+.fa-creative-commons-nc {
+ --fa: "\f4e8";
+}
+
+.fa-creative-commons-nc-eu {
+ --fa: "\f4e9";
+}
+
+.fa-creative-commons-nc-jp {
+ --fa: "\f4ea";
+}
+
+.fa-creative-commons-nd {
+ --fa: "\f4eb";
+}
+
+.fa-creative-commons-pd {
+ --fa: "\f4ec";
+}
+
+.fa-creative-commons-pd-alt {
+ --fa: "\f4ed";
+}
+
+.fa-creative-commons-remix {
+ --fa: "\f4ee";
+}
+
+.fa-creative-commons-sa {
+ --fa: "\f4ef";
+}
+
+.fa-creative-commons-sampling {
+ --fa: "\f4f0";
+}
+
+.fa-creative-commons-sampling-plus {
+ --fa: "\f4f1";
+}
+
+.fa-creative-commons-share {
+ --fa: "\f4f2";
+}
+
+.fa-creative-commons-zero {
+ --fa: "\f4f3";
+}
+
+.fa-ebay {
+ --fa: "\f4f4";
+}
+
+.fa-keybase {
+ --fa: "\f4f5";
+}
+
+.fa-mastodon {
+ --fa: "\f4f6";
+}
+
+.fa-r-project {
+ --fa: "\f4f7";
+}
+
+.fa-researchgate {
+ --fa: "\f4f8";
+}
+
+.fa-teamspeak {
+ --fa: "\f4f9";
+}
+
+.fa-first-order-alt {
+ --fa: "\f50a";
+}
+
+.fa-fulcrum {
+ --fa: "\f50b";
+}
+
+.fa-galactic-republic {
+ --fa: "\f50c";
+}
+
+.fa-galactic-senate {
+ --fa: "\f50d";
+}
+
+.fa-jedi-order {
+ --fa: "\f50e";
+}
+
+.fa-mandalorian {
+ --fa: "\f50f";
+}
+
+.fa-old-republic {
+ --fa: "\f510";
+}
+
+.fa-phoenix-squadron {
+ --fa: "\f511";
+}
+
+.fa-sith {
+ --fa: "\f512";
+}
+
+.fa-trade-federation {
+ --fa: "\f513";
+}
+
+.fa-wolf-pack-battalion {
+ --fa: "\f514";
+}
+
+.fa-hornbill {
+ --fa: "\f592";
+}
+
+.fa-mailchimp {
+ --fa: "\f59e";
+}
+
+.fa-megaport {
+ --fa: "\f5a3";
+}
+
+.fa-nimblr {
+ --fa: "\f5a8";
+}
+
+.fa-rev {
+ --fa: "\f5b2";
+}
+
+.fa-shopware {
+ --fa: "\f5b5";
+}
+
+.fa-squarespace {
+ --fa: "\f5be";
+}
+
+.fa-themeco {
+ --fa: "\f5c6";
+}
+
+.fa-weebly {
+ --fa: "\f5cc";
+}
+
+.fa-wix {
+ --fa: "\f5cf";
+}
+
+.fa-ello {
+ --fa: "\f5f1";
+}
+
+.fa-hackerrank {
+ --fa: "\f5f7";
+}
+
+.fa-kaggle {
+ --fa: "\f5fa";
+}
+
+.fa-markdown {
+ --fa: "\f60f";
+}
+
+.fa-neos {
+ --fa: "\f612";
+}
+
+.fa-zhihu {
+ --fa: "\f63f";
+}
+
+.fa-alipay {
+ --fa: "\f642";
+}
+
+.fa-the-red-yeti {
+ --fa: "\f69d";
+}
+
+.fa-critical-role {
+ --fa: "\f6c9";
+}
+
+.fa-d-and-d-beyond {
+ --fa: "\f6ca";
+}
+
+.fa-dev {
+ --fa: "\f6cc";
+}
+
+.fa-fantasy-flight-games {
+ --fa: "\f6dc";
+}
+
+.fa-wizards-of-the-coast {
+ --fa: "\f730";
+}
+
+.fa-think-peaks {
+ --fa: "\f731";
+}
+
+.fa-reacteurope {
+ --fa: "\f75d";
+}
+
+.fa-artstation {
+ --fa: "\f77a";
+}
+
+.fa-atlassian {
+ --fa: "\f77b";
+}
+
+.fa-canadian-maple-leaf {
+ --fa: "\f785";
+}
+
+.fa-centos {
+ --fa: "\f789";
+}
+
+.fa-confluence {
+ --fa: "\f78d";
+}
+
+.fa-dhl {
+ --fa: "\f790";
+}
+
+.fa-diaspora {
+ --fa: "\f791";
+}
+
+.fa-fedex {
+ --fa: "\f797";
+}
+
+.fa-fedora {
+ --fa: "\f798";
+}
+
+.fa-figma {
+ --fa: "\f799";
+}
+
+.fa-intercom {
+ --fa: "\f7af";
+}
+
+.fa-invision {
+ --fa: "\f7b0";
+}
+
+.fa-jira {
+ --fa: "\f7b1";
+}
+
+.fa-mendeley {
+ --fa: "\f7b3";
+}
+
+.fa-raspberry-pi {
+ --fa: "\f7bb";
+}
+
+.fa-redhat {
+ --fa: "\f7bc";
+}
+
+.fa-sketch {
+ --fa: "\f7c6";
+}
+
+.fa-sourcetree {
+ --fa: "\f7d3";
+}
+
+.fa-suse {
+ --fa: "\f7d6";
+}
+
+.fa-ubuntu {
+ --fa: "\f7df";
+}
+
+.fa-ups {
+ --fa: "\f7e0";
+}
+
+.fa-usps {
+ --fa: "\f7e1";
+}
+
+.fa-yarn {
+ --fa: "\f7e3";
+}
+
+.fa-airbnb {
+ --fa: "\f834";
+}
+
+.fa-battle-net {
+ --fa: "\f835";
+}
+
+.fa-bootstrap {
+ --fa: "\f836";
+}
+
+.fa-buffer {
+ --fa: "\f837";
+}
+
+.fa-chromecast {
+ --fa: "\f838";
+}
+
+.fa-evernote {
+ --fa: "\f839";
+}
+
+.fa-itch-io {
+ --fa: "\f83a";
+}
+
+.fa-salesforce {
+ --fa: "\f83b";
+}
+
+.fa-speaker-deck {
+ --fa: "\f83c";
+}
+
+.fa-symfony {
+ --fa: "\f83d";
+}
+
+.fa-waze {
+ --fa: "\f83f";
+}
+
+.fa-yammer {
+ --fa: "\f840";
+}
+
+.fa-git-alt {
+ --fa: "\f841";
+}
+
+.fa-stackpath {
+ --fa: "\f842";
+}
+
+.fa-cotton-bureau {
+ --fa: "\f89e";
+}
+
+.fa-buy-n-large {
+ --fa: "\f8a6";
+}
+
+.fa-mdb {
+ --fa: "\f8ca";
+}
+
+.fa-orcid {
+ --fa: "\f8d2";
+}
+
+.fa-swift {
+ --fa: "\f8e1";
+}
+
+.fa-umbraco {
+ --fa: "\f8e8";
+}:root, :host {
+ --fa-family-classic: "Font Awesome 7 Free";
+ --fa-font-regular: normal 400 1em/1 var(--fa-family-classic);
+ /* deprecated: this older custom property will be removed next major release */
+ --fa-style-family-classic: var(--fa-family-classic);
+}
+
+@font-face {
+ font-family: "Font Awesome 7 Free";
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src: url("../webfonts/fa-regular-400.woff2");
+}
+.far {
+ --fa-family: var(--fa-family-classic);
+ --fa-style: 400;
+}
+
+.fa-classic {
+ --fa-family: var(--fa-family-classic);
+}
+
+.fa-regular {
+ --fa-style: 400;
+}:root, :host {
+ --fa-family-classic: "Font Awesome 7 Free";
+ --fa-font-solid: normal 900 1em/1 var(--fa-family-classic);
+ /* deprecated: this older custom property will be removed next major release */
+ --fa-style-family-classic: var(--fa-family-classic);
+}
+
+@font-face {
+ font-family: "Font Awesome 7 Free";
+ font-style: normal;
+ font-weight: 900;
+ font-display: block;
+ src: url("../webfonts/fa-solid-900.woff2");
+}
+.fas {
+ --fa-family: var(--fa-family-classic);
+ --fa-style: 900;
+}
+
+.fa-classic {
+ --fa-family: var(--fa-family-classic);
+}
+
+.fa-solid {
+ --fa-style: 900;
+}@font-face {
+ font-family: "Font Awesome 5 Brands";
+ font-display: block;
+ font-weight: 400;
+ src: url("../webfonts/fa-brands-400.woff2") format("woff2");
+}
+@font-face {
+ font-family: "Font Awesome 5 Free";
+ font-display: block;
+ font-weight: 900;
+ src: url("../webfonts/fa-solid-900.woff2") format("woff2");
+}
+@font-face {
+ font-family: "Font Awesome 5 Free";
+ font-display: block;
+ font-weight: 400;
+ src: url("../webfonts/fa-regular-400.woff2") format("woff2");
+}@font-face {
+ font-family: "FontAwesome";
+ font-display: block;
+ src: url("../webfonts/fa-solid-900.woff2") format("woff2");
+}
+@font-face {
+ font-family: "FontAwesome";
+ font-display: block;
+ src: url("../webfonts/fa-brands-400.woff2") format("woff2");
+}
+@font-face {
+ font-family: "FontAwesome";
+ font-display: block;
+ src: url("../webfonts/fa-regular-400.woff2") format("woff2");
+ unicode-range: U+F003, U+F006, U+F014, U+F016-F017, U+F01A-F01B, U+F01D, U+F022, U+F03E, U+F044, U+F046, U+F05C-F05D, U+F06E, U+F070, U+F087-F088, U+F08A, U+F094, U+F096-F097, U+F09D, U+F0A0, U+F0A2, U+F0A4-F0A7, U+F0C5, U+F0C7, U+F0E5-F0E6, U+F0EB, U+F0F6-F0F8, U+F10C, U+F114-F115, U+F118-F11A, U+F11C-F11D, U+F133, U+F147, U+F14E, U+F150-F152, U+F185-F186, U+F18E, U+F190-F192, U+F196, U+F1C1-F1C9, U+F1D9, U+F1DB, U+F1E3, U+F1EA, U+F1F7, U+F1F9, U+F20A, U+F247-F248, U+F24A, U+F24D, U+F255-F25B, U+F25D, U+F271-F274, U+F278, U+F27B, U+F28C, U+F28E, U+F29C, U+F2B5, U+F2B7, U+F2BA, U+F2BC, U+F2BE, U+F2C0-F2C1, U+F2C3, U+F2D0, U+F2D2, U+F2D4, U+F2DC;
+}
+@font-face {
+ font-family: "FontAwesome";
+ font-display: block;
+ src: url("../webfonts/fa-v4compatibility.woff2") format("woff2");
+ unicode-range: U+F041, U+F047, U+F065-F066, U+F07D-F07E, U+F080, U+F08B, U+F08E, U+F090, U+F09A, U+F0AC, U+F0AE, U+F0B2, U+F0D0, U+F0D6, U+F0E4, U+F0EC, U+F10A-F10B, U+F123, U+F13E, U+F148-F149, U+F14C, U+F156, U+F15E, U+F160-F161, U+F163, U+F175-F178, U+F195, U+F1F8, U+F219, U+F27A;
+}
\ No newline at end of file
diff --git a/src/media/vendor/fa7free/css/all.min.css b/src/media/vendor/fa7free/css/all.min.css
new file mode 100644
index 0000000..b568f8d
--- /dev/null
+++ b/src/media/vendor/fa7free/css/all.min.css
@@ -0,0 +1,9 @@
+/*!
+ * Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ * Copyright 2025 Fonticons, Inc.
+ */
+.fa,.fa-brands,.fa-classic,.fa-regular,.fa-solid,.fab,.far,.fas{--_fa-family:var(--fa-family,var(--fa-style-family,"Font Awesome 7 Free"));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:var(--fa-display,inline-block);font-family:var(--_fa-family);font-feature-settings:normal;font-style:normal;font-synthesis:none;font-variant:normal;font-weight:var(--fa-style,900);line-height:1;text-align:center;text-rendering:auto;width:var(--fa-width,1.25em)}:is(.fas,.far,.fab,.fa-solid,.fa-regular,.fa-brands,.fa-classic,.fa):before{content:var(--fa)/""}@supports not (content:""/""){:is(.fas,.far,.fab,.fa-solid,.fa-regular,.fa-brands,.fa-classic,.fa):before{content:var(--fa)}}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.08333em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.07143em;vertical-align:.05357em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.04167em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-width-auto{--fa-width:auto}.fa-fw,.fa-width-fixed{--fa-width:1.25em}.fa-ul{list-style-type:none;margin-inline-start:var(--fa-li-margin,2.5em);padding-inline-start:0}.fa-ul>li{position:relative}.fa-li{inset-inline-start:calc(var(--fa-li-width, 2em)*-1);position:absolute;text-align:center;width:var(--fa-li-width,2em);line-height:inherit}.fa-border{border-radius:var(--fa-border-radius,.1em);border:var(--fa-border-width,.0625em) var(--fa-border-style,solid) var(--fa-border-color,#eee);box-sizing:var(--fa-border-box-sizing,content-box);padding:var(--fa-border-padding,.1875em .25em)}.fa-pull-left,.fa-pull-start{float:inline-start;margin-inline-end:var(--fa-pull-margin,.3em)}.fa-pull-end,.fa-pull-right{float:inline-end;margin-inline-start:var(--fa-pull-margin,.3em)}.fa-beat{animation-name:fa-beat;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{animation-name:fa-bounce;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{animation-name:fa-fade;animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade,.fa-fade{animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s)}.fa-beat-fade{animation-name:fa-beat-fade;animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{animation-name:fa-flip;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{animation-name:fa-shake;animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,linear)}.fa-shake,.fa-spin{animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal)}.fa-spin{animation-name:fa-spin;animation-duration:var(--fa-animation-duration,2s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{animation-name:fa-spin;animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,steps(8))}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{animation:none!important;transition:none!important}}@keyframes fa-beat{0%,90%{transform:scale(1)}45%{transform:scale(var(--fa-beat-scale,1.25))}}@keyframes fa-bounce{0%{transform:scale(1) translateY(0)}10%{transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em))}64%{transform:scale(1) translateY(0)}to{transform:scale(1) translateY(0)}}@keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@keyframes fa-beat-fade{0%,to{opacity:var(--fa-beat-fade-opacity,.4);transform:scale(1)}50%{opacity:1;transform:scale(var(--fa-beat-fade-scale,1.125))}}@keyframes fa-flip{50%{transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@keyframes fa-shake{0%{transform:rotate(-15deg)}4%{transform:rotate(15deg)}8%,24%{transform:rotate(-18deg)}12%,28%{transform:rotate(18deg)}16%{transform:rotate(-22deg)}20%{transform:rotate(22deg)}32%{transform:rotate(-12deg)}36%{transform:rotate(12deg)}40%,to{transform:rotate(0deg)}}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{transform:rotate(90deg)}.fa-rotate-180{transform:rotate(180deg)}.fa-rotate-270{transform:rotate(270deg)}.fa-flip-horizontal{transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}.fa-rotate-by{transform:rotate(var(--fa-rotate-angle,0))}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{--fa-width:100%;inset:0;position:absolute;text-align:center;width:var(--fa-width);z-index:var(--fa-stack-z-index,auto)}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:var(--fa-inverse,#fff)}
+
+.fa-0{--fa:"\30 "}.fa-1{--fa:"\31 "}.fa-2{--fa:"\32 "}.fa-3{--fa:"\33 "}.fa-4{--fa:"\34 "}.fa-5{--fa:"\35 "}.fa-6{--fa:"\36 "}.fa-7{--fa:"\37 "}.fa-8{--fa:"\38 "}.fa-9{--fa:"\39 "}.fa-exclamation{--fa:"\!"}.fa-hashtag{--fa:"\#"}.fa-dollar,.fa-dollar-sign,.fa-usd{--fa:"\$"}.fa-percent,.fa-percentage{--fa:"\%"}.fa-asterisk{--fa:"\*"}.fa-add,.fa-plus{--fa:"\+"}.fa-less-than{--fa:"\<"}.fa-equals{--fa:"\="}.fa-greater-than{--fa:"\>"}.fa-question{--fa:"\?"}.fa-at{--fa:"\@"}.fa-a{--fa:"A"}.fa-b{--fa:"B"}.fa-c{--fa:"C"}.fa-d{--fa:"D"}.fa-e{--fa:"E"}.fa-f{--fa:"F"}.fa-g{--fa:"G"}.fa-h{--fa:"H"}.fa-i{--fa:"I"}.fa-j{--fa:"J"}.fa-k{--fa:"K"}.fa-l{--fa:"L"}.fa-m{--fa:"M"}.fa-n{--fa:"N"}.fa-o{--fa:"O"}.fa-p{--fa:"P"}.fa-q{--fa:"Q"}.fa-r{--fa:"R"}.fa-s{--fa:"S"}.fa-t{--fa:"T"}.fa-u{--fa:"U"}.fa-v{--fa:"V"}.fa-w{--fa:"W"}.fa-x{--fa:"X"}.fa-y{--fa:"Y"}.fa-z{--fa:"Z"}.fa-faucet{--fa:"\e005"}.fa-faucet-drip{--fa:"\e006"}.fa-house-chimney-window{--fa:"\e00d"}.fa-house-signal{--fa:"\e012"}.fa-temperature-arrow-down,.fa-temperature-down{--fa:"\e03f"}.fa-temperature-arrow-up,.fa-temperature-up{--fa:"\e040"}.fa-trailer{--fa:"\e041"}.fa-bacteria{--fa:"\e059"}.fa-bacterium{--fa:"\e05a"}.fa-box-tissue{--fa:"\e05b"}.fa-hand-holding-medical{--fa:"\e05c"}.fa-hand-sparkles{--fa:"\e05d"}.fa-hands-bubbles,.fa-hands-wash{--fa:"\e05e"}.fa-handshake-alt-slash,.fa-handshake-simple-slash,.fa-handshake-slash{--fa:"\e060"}.fa-head-side-cough{--fa:"\e061"}.fa-head-side-cough-slash{--fa:"\e062"}.fa-head-side-mask{--fa:"\e063"}.fa-head-side-virus{--fa:"\e064"}.fa-house-chimney-user{--fa:"\e065"}.fa-house-laptop,.fa-laptop-house{--fa:"\e066"}.fa-lungs-virus{--fa:"\e067"}.fa-people-arrows,.fa-people-arrows-left-right{--fa:"\e068"}.fa-plane-slash{--fa:"\e069"}.fa-pump-medical{--fa:"\e06a"}.fa-pump-soap{--fa:"\e06b"}.fa-shield-virus{--fa:"\e06c"}.fa-sink{--fa:"\e06d"}.fa-soap{--fa:"\e06e"}.fa-stopwatch-20{--fa:"\e06f"}.fa-shop-slash,.fa-store-alt-slash{--fa:"\e070"}.fa-store-slash{--fa:"\e071"}.fa-toilet-paper-slash{--fa:"\e072"}.fa-users-slash{--fa:"\e073"}.fa-virus{--fa:"\e074"}.fa-virus-slash{--fa:"\e075"}.fa-viruses{--fa:"\e076"}.fa-vest{--fa:"\e085"}.fa-vest-patches{--fa:"\e086"}.fa-arrow-trend-down{--fa:"\e097"}.fa-arrow-trend-up{--fa:"\e098"}.fa-arrow-up-from-bracket{--fa:"\e09a"}.fa-austral-sign{--fa:"\e0a9"}.fa-baht-sign{--fa:"\e0ac"}.fa-bitcoin-sign{--fa:"\e0b4"}.fa-bolt-lightning{--fa:"\e0b7"}.fa-book-bookmark{--fa:"\e0bb"}.fa-camera-rotate{--fa:"\e0d8"}.fa-cedi-sign{--fa:"\e0df"}.fa-chart-column{--fa:"\e0e3"}.fa-chart-gantt{--fa:"\e0e4"}.fa-clapperboard{--fa:"\e131"}.fa-clover{--fa:"\e139"}.fa-code-compare{--fa:"\e13a"}.fa-code-fork{--fa:"\e13b"}.fa-code-pull-request{--fa:"\e13c"}.fa-colon-sign{--fa:"\e140"}.fa-cruzeiro-sign{--fa:"\e152"}.fa-display{--fa:"\e163"}.fa-dong-sign{--fa:"\e169"}.fa-elevator{--fa:"\e16d"}.fa-filter-circle-xmark{--fa:"\e17b"}.fa-florin-sign{--fa:"\e184"}.fa-folder-closed{--fa:"\e185"}.fa-franc-sign{--fa:"\e18f"}.fa-guarani-sign{--fa:"\e19a"}.fa-gun{--fa:"\e19b"}.fa-hands-clapping{--fa:"\e1a8"}.fa-home-user,.fa-house-user{--fa:"\e1b0"}.fa-indian-rupee,.fa-indian-rupee-sign,.fa-inr{--fa:"\e1bc"}.fa-kip-sign{--fa:"\e1c4"}.fa-lari-sign{--fa:"\e1c8"}.fa-litecoin-sign{--fa:"\e1d3"}.fa-manat-sign{--fa:"\e1d5"}.fa-mask-face{--fa:"\e1d7"}.fa-mill-sign{--fa:"\e1ed"}.fa-money-bills{--fa:"\e1f3"}.fa-naira-sign{--fa:"\e1f6"}.fa-notdef{--fa:"\e1fe"}.fa-panorama{--fa:"\e209"}.fa-peseta-sign{--fa:"\e221"}.fa-peso-sign{--fa:"\e222"}.fa-plane-up{--fa:"\e22d"}.fa-rupiah-sign{--fa:"\e23d"}.fa-stairs{--fa:"\e289"}.fa-timeline{--fa:"\e29c"}.fa-truck-front{--fa:"\e2b7"}.fa-try,.fa-turkish-lira,.fa-turkish-lira-sign{--fa:"\e2bb"}.fa-vault{--fa:"\e2c5"}.fa-magic-wand-sparkles,.fa-wand-magic-sparkles{--fa:"\e2ca"}.fa-wheat-alt,.fa-wheat-awn{--fa:"\e2cd"}.fa-wheelchair-alt,.fa-wheelchair-move{--fa:"\e2ce"}.fa-bangladeshi-taka-sign{--fa:"\e2e6"}.fa-bowl-rice{--fa:"\e2eb"}.fa-person-pregnant{--fa:"\e31e"}.fa-home-lg,.fa-house-chimney{--fa:"\e3af"}.fa-house-crack{--fa:"\e3b1"}.fa-house-medical{--fa:"\e3b2"}.fa-cent-sign{--fa:"\e3f5"}.fa-plus-minus{--fa:"\e43c"}.fa-sailboat{--fa:"\e445"}.fa-section{--fa:"\e447"}.fa-shrimp{--fa:"\e448"}.fa-brazilian-real-sign{--fa:"\e46c"}.fa-chart-simple{--fa:"\e473"}.fa-diagram-next{--fa:"\e476"}.fa-diagram-predecessor{--fa:"\e477"}.fa-diagram-successor{--fa:"\e47a"}.fa-earth-oceania,.fa-globe-oceania{--fa:"\e47b"}.fa-bug-slash{--fa:"\e490"}.fa-file-circle-plus{--fa:"\e494"}.fa-shop-lock{--fa:"\e4a5"}.fa-virus-covid{--fa:"\e4a8"}.fa-virus-covid-slash{--fa:"\e4a9"}.fa-anchor-circle-check{--fa:"\e4aa"}.fa-anchor-circle-exclamation{--fa:"\e4ab"}.fa-anchor-circle-xmark{--fa:"\e4ac"}.fa-anchor-lock{--fa:"\e4ad"}.fa-arrow-down-up-across-line{--fa:"\e4af"}.fa-arrow-down-up-lock{--fa:"\e4b0"}.fa-arrow-right-to-city{--fa:"\e4b3"}.fa-arrow-up-from-ground-water{--fa:"\e4b5"}.fa-arrow-up-from-water-pump{--fa:"\e4b6"}.fa-arrow-up-right-dots{--fa:"\e4b7"}.fa-arrows-down-to-line{--fa:"\e4b8"}.fa-arrows-down-to-people{--fa:"\e4b9"}.fa-arrows-left-right-to-line{--fa:"\e4ba"}.fa-arrows-spin{--fa:"\e4bb"}.fa-arrows-split-up-and-left{--fa:"\e4bc"}.fa-arrows-to-circle{--fa:"\e4bd"}.fa-arrows-to-dot{--fa:"\e4be"}.fa-arrows-to-eye{--fa:"\e4bf"}.fa-arrows-turn-right{--fa:"\e4c0"}.fa-arrows-turn-to-dots{--fa:"\e4c1"}.fa-arrows-up-to-line{--fa:"\e4c2"}.fa-bore-hole{--fa:"\e4c3"}.fa-bottle-droplet{--fa:"\e4c4"}.fa-bottle-water{--fa:"\e4c5"}.fa-bowl-food{--fa:"\e4c6"}.fa-boxes-packing{--fa:"\e4c7"}.fa-bridge{--fa:"\e4c8"}.fa-bridge-circle-check{--fa:"\e4c9"}.fa-bridge-circle-exclamation{--fa:"\e4ca"}.fa-bridge-circle-xmark{--fa:"\e4cb"}.fa-bridge-lock{--fa:"\e4cc"}.fa-bridge-water{--fa:"\e4ce"}.fa-bucket{--fa:"\e4cf"}.fa-bugs{--fa:"\e4d0"}.fa-building-circle-arrow-right{--fa:"\e4d1"}.fa-building-circle-check{--fa:"\e4d2"}.fa-building-circle-exclamation{--fa:"\e4d3"}.fa-building-circle-xmark{--fa:"\e4d4"}.fa-building-flag{--fa:"\e4d5"}.fa-building-lock{--fa:"\e4d6"}.fa-building-ngo{--fa:"\e4d7"}.fa-building-shield{--fa:"\e4d8"}.fa-building-un{--fa:"\e4d9"}.fa-building-user{--fa:"\e4da"}.fa-building-wheat{--fa:"\e4db"}.fa-burst{--fa:"\e4dc"}.fa-car-on{--fa:"\e4dd"}.fa-car-tunnel{--fa:"\e4de"}.fa-child-combatant,.fa-child-rifle{--fa:"\e4e0"}.fa-children{--fa:"\e4e1"}.fa-circle-nodes{--fa:"\e4e2"}.fa-clipboard-question{--fa:"\e4e3"}.fa-cloud-showers-water{--fa:"\e4e4"}.fa-computer{--fa:"\e4e5"}.fa-cubes-stacked{--fa:"\e4e6"}.fa-envelope-circle-check{--fa:"\e4e8"}.fa-explosion{--fa:"\e4e9"}.fa-ferry{--fa:"\e4ea"}.fa-file-circle-exclamation{--fa:"\e4eb"}.fa-file-circle-minus{--fa:"\e4ed"}.fa-file-circle-question{--fa:"\e4ef"}.fa-file-shield{--fa:"\e4f0"}.fa-fire-burner{--fa:"\e4f1"}.fa-fish-fins{--fa:"\e4f2"}.fa-flask-vial{--fa:"\e4f3"}.fa-glass-water{--fa:"\e4f4"}.fa-glass-water-droplet{--fa:"\e4f5"}.fa-group-arrows-rotate{--fa:"\e4f6"}.fa-hand-holding-hand{--fa:"\e4f7"}.fa-handcuffs{--fa:"\e4f8"}.fa-hands-bound{--fa:"\e4f9"}.fa-hands-holding-child{--fa:"\e4fa"}.fa-hands-holding-circle{--fa:"\e4fb"}.fa-heart-circle-bolt{--fa:"\e4fc"}.fa-heart-circle-check{--fa:"\e4fd"}.fa-heart-circle-exclamation{--fa:"\e4fe"}.fa-heart-circle-minus{--fa:"\e4ff"}.fa-heart-circle-plus{--fa:"\e500"}.fa-heart-circle-xmark{--fa:"\e501"}.fa-helicopter-symbol{--fa:"\e502"}.fa-helmet-un{--fa:"\e503"}.fa-hill-avalanche{--fa:"\e507"}.fa-hill-rockslide{--fa:"\e508"}.fa-house-circle-check{--fa:"\e509"}.fa-house-circle-exclamation{--fa:"\e50a"}.fa-house-circle-xmark{--fa:"\e50b"}.fa-house-fire{--fa:"\e50c"}.fa-house-flag{--fa:"\e50d"}.fa-house-flood-water{--fa:"\e50e"}.fa-house-flood-water-circle-arrow-right{--fa:"\e50f"}.fa-house-lock{--fa:"\e510"}.fa-house-medical-circle-check{--fa:"\e511"}.fa-house-medical-circle-exclamation{--fa:"\e512"}.fa-house-medical-circle-xmark{--fa:"\e513"}.fa-house-medical-flag{--fa:"\e514"}.fa-house-tsunami{--fa:"\e515"}.fa-jar{--fa:"\e516"}.fa-jar-wheat{--fa:"\e517"}.fa-jet-fighter-up{--fa:"\e518"}.fa-jug-detergent{--fa:"\e519"}.fa-kitchen-set{--fa:"\e51a"}.fa-land-mine-on{--fa:"\e51b"}.fa-landmark-flag{--fa:"\e51c"}.fa-laptop-file{--fa:"\e51d"}.fa-lines-leaning{--fa:"\e51e"}.fa-location-pin-lock{--fa:"\e51f"}.fa-locust{--fa:"\e520"}.fa-magnifying-glass-arrow-right{--fa:"\e521"}.fa-magnifying-glass-chart{--fa:"\e522"}.fa-mars-and-venus-burst{--fa:"\e523"}.fa-mask-ventilator{--fa:"\e524"}.fa-mattress-pillow{--fa:"\e525"}.fa-mobile-retro{--fa:"\e527"}.fa-money-bill-transfer{--fa:"\e528"}.fa-money-bill-trend-up{--fa:"\e529"}.fa-money-bill-wheat{--fa:"\e52a"}.fa-mosquito{--fa:"\e52b"}.fa-mosquito-net{--fa:"\e52c"}.fa-mound{--fa:"\e52d"}.fa-mountain-city{--fa:"\e52e"}.fa-mountain-sun{--fa:"\e52f"}.fa-oil-well{--fa:"\e532"}.fa-people-group{--fa:"\e533"}.fa-people-line{--fa:"\e534"}.fa-people-pulling{--fa:"\e535"}.fa-people-robbery{--fa:"\e536"}.fa-people-roof{--fa:"\e537"}.fa-person-arrow-down-to-line{--fa:"\e538"}.fa-person-arrow-up-from-line{--fa:"\e539"}.fa-person-breastfeeding{--fa:"\e53a"}.fa-person-burst{--fa:"\e53b"}.fa-person-cane{--fa:"\e53c"}.fa-person-chalkboard{--fa:"\e53d"}.fa-person-circle-check{--fa:"\e53e"}.fa-person-circle-exclamation{--fa:"\e53f"}.fa-person-circle-minus{--fa:"\e540"}.fa-person-circle-plus{--fa:"\e541"}.fa-person-circle-question{--fa:"\e542"}.fa-person-circle-xmark{--fa:"\e543"}.fa-person-dress-burst{--fa:"\e544"}.fa-person-drowning{--fa:"\e545"}.fa-person-falling{--fa:"\e546"}.fa-person-falling-burst{--fa:"\e547"}.fa-person-half-dress{--fa:"\e548"}.fa-person-harassing{--fa:"\e549"}.fa-person-military-pointing{--fa:"\e54a"}.fa-person-military-rifle{--fa:"\e54b"}.fa-person-military-to-person{--fa:"\e54c"}.fa-person-rays{--fa:"\e54d"}.fa-person-rifle{--fa:"\e54e"}.fa-person-shelter{--fa:"\e54f"}.fa-person-walking-arrow-loop-left{--fa:"\e551"}.fa-person-walking-arrow-right{--fa:"\e552"}.fa-person-walking-dashed-line-arrow-right{--fa:"\e553"}.fa-person-walking-luggage{--fa:"\e554"}.fa-plane-circle-check{--fa:"\e555"}.fa-plane-circle-exclamation{--fa:"\e556"}.fa-plane-circle-xmark{--fa:"\e557"}.fa-plane-lock{--fa:"\e558"}.fa-plate-wheat{--fa:"\e55a"}.fa-plug-circle-bolt{--fa:"\e55b"}.fa-plug-circle-check{--fa:"\e55c"}.fa-plug-circle-exclamation{--fa:"\e55d"}.fa-plug-circle-minus{--fa:"\e55e"}.fa-plug-circle-plus{--fa:"\e55f"}.fa-plug-circle-xmark{--fa:"\e560"}.fa-ranking-star{--fa:"\e561"}.fa-road-barrier{--fa:"\e562"}.fa-road-bridge{--fa:"\e563"}.fa-road-circle-check{--fa:"\e564"}.fa-road-circle-exclamation{--fa:"\e565"}.fa-road-circle-xmark{--fa:"\e566"}.fa-road-lock{--fa:"\e567"}.fa-road-spikes{--fa:"\e568"}.fa-rug{--fa:"\e569"}.fa-sack-xmark{--fa:"\e56a"}.fa-school-circle-check{--fa:"\e56b"}.fa-school-circle-exclamation{--fa:"\e56c"}.fa-school-circle-xmark{--fa:"\e56d"}.fa-school-flag{--fa:"\e56e"}.fa-school-lock{--fa:"\e56f"}.fa-sheet-plastic{--fa:"\e571"}.fa-shield-cat{--fa:"\e572"}.fa-shield-dog{--fa:"\e573"}.fa-shield-heart{--fa:"\e574"}.fa-square-nfi{--fa:"\e576"}.fa-square-person-confined{--fa:"\e577"}.fa-square-virus{--fa:"\e578"}.fa-rod-asclepius,.fa-rod-snake,.fa-staff-aesculapius,.fa-staff-snake{--fa:"\e579"}.fa-sun-plant-wilt{--fa:"\e57a"}.fa-tarp{--fa:"\e57b"}.fa-tarp-droplet{--fa:"\e57c"}.fa-tent{--fa:"\e57d"}.fa-tent-arrow-down-to-line{--fa:"\e57e"}.fa-tent-arrow-left-right{--fa:"\e57f"}.fa-tent-arrow-turn-left{--fa:"\e580"}.fa-tent-arrows-down{--fa:"\e581"}.fa-tents{--fa:"\e582"}.fa-toilet-portable{--fa:"\e583"}.fa-toilets-portable{--fa:"\e584"}.fa-tower-cell{--fa:"\e585"}.fa-tower-observation{--fa:"\e586"}.fa-tree-city{--fa:"\e587"}.fa-trowel{--fa:"\e589"}.fa-trowel-bricks{--fa:"\e58a"}.fa-truck-arrow-right{--fa:"\e58b"}.fa-truck-droplet{--fa:"\e58c"}.fa-truck-field{--fa:"\e58d"}.fa-truck-field-un{--fa:"\e58e"}.fa-truck-plane{--fa:"\e58f"}.fa-users-between-lines{--fa:"\e591"}.fa-users-line{--fa:"\e592"}.fa-users-rays{--fa:"\e593"}.fa-users-rectangle{--fa:"\e594"}.fa-users-viewfinder{--fa:"\e595"}.fa-vial-circle-check{--fa:"\e596"}.fa-vial-virus{--fa:"\e597"}.fa-wheat-awn-circle-exclamation{--fa:"\e598"}.fa-worm{--fa:"\e599"}.fa-xmarks-lines{--fa:"\e59a"}.fa-child-dress{--fa:"\e59c"}.fa-child-reaching{--fa:"\e59d"}.fa-file-circle-check{--fa:"\e5a0"}.fa-file-circle-xmark{--fa:"\e5a1"}.fa-person-through-window{--fa:"\e5a9"}.fa-plant-wilt{--fa:"\e5aa"}.fa-stapler{--fa:"\e5af"}.fa-train-tram{--fa:"\e5b4"}.fa-table-cells-column-lock{--fa:"\e678"}.fa-table-cells-row-lock{--fa:"\e67a"}.fa-thumb-tack-slash,.fa-thumbtack-slash{--fa:"\e68f"}.fa-table-cells-row-unlock{--fa:"\e691"}.fa-chart-diagram{--fa:"\e695"}.fa-comment-nodes{--fa:"\e696"}.fa-file-fragment{--fa:"\e697"}.fa-file-half-dashed{--fa:"\e698"}.fa-hexagon-nodes{--fa:"\e699"}.fa-hexagon-nodes-bolt{--fa:"\e69a"}.fa-square-binary{--fa:"\e69b"}.fa-pentagon{--fa:"\e790"}.fa-non-binary{--fa:"\e807"}.fa-spiral{--fa:"\e80a"}.fa-mobile-vibrate{--fa:"\e816"}.fa-single-quote-left{--fa:"\e81b"}.fa-single-quote-right{--fa:"\e81c"}.fa-bus-side{--fa:"\e81d"}.fa-heptagon,.fa-septagon{--fa:"\e820"}.fa-glass-martini,.fa-martini-glass-empty{--fa:"\f000"}.fa-music{--fa:"\f001"}.fa-magnifying-glass,.fa-search{--fa:"\f002"}.fa-heart{--fa:"\f004"}.fa-star{--fa:"\f005"}.fa-user,.fa-user-alt,.fa-user-large{--fa:"\f007"}.fa-film,.fa-film-alt,.fa-film-simple{--fa:"\f008"}.fa-table-cells-large,.fa-th-large{--fa:"\f009"}.fa-table-cells,.fa-th{--fa:"\f00a"}.fa-table-list,.fa-th-list{--fa:"\f00b"}.fa-check{--fa:"\f00c"}.fa-close,.fa-multiply,.fa-remove,.fa-times,.fa-xmark{--fa:"\f00d"}.fa-magnifying-glass-plus,.fa-search-plus{--fa:"\f00e"}.fa-magnifying-glass-minus,.fa-search-minus{--fa:"\f010"}.fa-power-off{--fa:"\f011"}.fa-signal,.fa-signal-5,.fa-signal-perfect{--fa:"\f012"}.fa-cog,.fa-gear{--fa:"\f013"}.fa-home,.fa-home-alt,.fa-home-lg-alt,.fa-house{--fa:"\f015"}.fa-clock,.fa-clock-four{--fa:"\f017"}.fa-road{--fa:"\f018"}.fa-download{--fa:"\f019"}.fa-inbox{--fa:"\f01c"}.fa-arrow-right-rotate,.fa-arrow-rotate-forward,.fa-arrow-rotate-right,.fa-redo{--fa:"\f01e"}.fa-arrows-rotate,.fa-refresh,.fa-sync{--fa:"\f021"}.fa-list-alt,.fa-rectangle-list{--fa:"\f022"}.fa-lock{--fa:"\f023"}.fa-flag{--fa:"\f024"}.fa-headphones,.fa-headphones-alt,.fa-headphones-simple{--fa:"\f025"}.fa-volume-off{--fa:"\f026"}.fa-volume-down,.fa-volume-low{--fa:"\f027"}.fa-volume-high,.fa-volume-up{--fa:"\f028"}.fa-qrcode{--fa:"\f029"}.fa-barcode{--fa:"\f02a"}.fa-tag{--fa:"\f02b"}.fa-tags{--fa:"\f02c"}.fa-book{--fa:"\f02d"}.fa-bookmark{--fa:"\f02e"}.fa-print{--fa:"\f02f"}.fa-camera,.fa-camera-alt{--fa:"\f030"}.fa-font{--fa:"\f031"}.fa-bold{--fa:"\f032"}.fa-italic{--fa:"\f033"}.fa-text-height{--fa:"\f034"}.fa-text-width{--fa:"\f035"}.fa-align-left{--fa:"\f036"}.fa-align-center{--fa:"\f037"}.fa-align-right{--fa:"\f038"}.fa-align-justify{--fa:"\f039"}.fa-list,.fa-list-squares{--fa:"\f03a"}.fa-dedent,.fa-outdent{--fa:"\f03b"}.fa-indent{--fa:"\f03c"}.fa-video,.fa-video-camera{--fa:"\f03d"}.fa-image{--fa:"\f03e"}.fa-location-pin,.fa-map-marker{--fa:"\f041"}.fa-adjust,.fa-circle-half-stroke{--fa:"\f042"}.fa-droplet,.fa-tint{--fa:"\f043"}.fa-edit,.fa-pen-to-square{--fa:"\f044"}.fa-arrows,.fa-arrows-up-down-left-right{--fa:"\f047"}.fa-backward-step,.fa-step-backward{--fa:"\f048"}.fa-backward-fast,.fa-fast-backward{--fa:"\f049"}.fa-backward{--fa:"\f04a"}.fa-play{--fa:"\f04b"}.fa-pause{--fa:"\f04c"}.fa-stop{--fa:"\f04d"}.fa-forward{--fa:"\f04e"}.fa-fast-forward,.fa-forward-fast{--fa:"\f050"}.fa-forward-step,.fa-step-forward{--fa:"\f051"}.fa-eject{--fa:"\f052"}.fa-chevron-left{--fa:"\f053"}.fa-chevron-right{--fa:"\f054"}.fa-circle-plus,.fa-plus-circle{--fa:"\f055"}.fa-circle-minus,.fa-minus-circle{--fa:"\f056"}.fa-circle-xmark,.fa-times-circle,.fa-xmark-circle{--fa:"\f057"}.fa-check-circle,.fa-circle-check{--fa:"\f058"}.fa-circle-question,.fa-question-circle{--fa:"\f059"}.fa-circle-info,.fa-info-circle{--fa:"\f05a"}.fa-crosshairs{--fa:"\f05b"}.fa-ban,.fa-cancel{--fa:"\f05e"}.fa-arrow-left{--fa:"\f060"}.fa-arrow-right{--fa:"\f061"}.fa-arrow-up{--fa:"\f062"}.fa-arrow-down{--fa:"\f063"}.fa-mail-forward,.fa-share{--fa:"\f064"}.fa-expand{--fa:"\f065"}.fa-compress{--fa:"\f066"}.fa-minus,.fa-subtract{--fa:"\f068"}.fa-circle-exclamation,.fa-exclamation-circle{--fa:"\f06a"}.fa-gift{--fa:"\f06b"}.fa-leaf{--fa:"\f06c"}.fa-fire{--fa:"\f06d"}.fa-eye{--fa:"\f06e"}.fa-eye-slash{--fa:"\f070"}.fa-exclamation-triangle,.fa-triangle-exclamation,.fa-warning{--fa:"\f071"}.fa-plane{--fa:"\f072"}.fa-calendar-alt,.fa-calendar-days{--fa:"\f073"}.fa-random,.fa-shuffle{--fa:"\f074"}.fa-comment{--fa:"\f075"}.fa-magnet{--fa:"\f076"}.fa-chevron-up{--fa:"\f077"}.fa-chevron-down{--fa:"\f078"}.fa-retweet{--fa:"\f079"}.fa-cart-shopping,.fa-shopping-cart{--fa:"\f07a"}.fa-folder,.fa-folder-blank{--fa:"\f07b"}.fa-folder-open{--fa:"\f07c"}.fa-arrows-up-down,.fa-arrows-v{--fa:"\f07d"}.fa-arrows-h,.fa-arrows-left-right{--fa:"\f07e"}.fa-bar-chart,.fa-chart-bar{--fa:"\f080"}.fa-camera-retro{--fa:"\f083"}.fa-key{--fa:"\f084"}.fa-cogs,.fa-gears{--fa:"\f085"}.fa-comments{--fa:"\f086"}.fa-star-half{--fa:"\f089"}.fa-arrow-right-from-bracket,.fa-sign-out{--fa:"\f08b"}.fa-thumb-tack,.fa-thumbtack{--fa:"\f08d"}.fa-arrow-up-right-from-square,.fa-external-link{--fa:"\f08e"}.fa-arrow-right-to-bracket,.fa-sign-in{--fa:"\f090"}.fa-trophy{--fa:"\f091"}.fa-upload{--fa:"\f093"}.fa-lemon{--fa:"\f094"}.fa-phone{--fa:"\f095"}.fa-phone-square,.fa-square-phone{--fa:"\f098"}.fa-unlock{--fa:"\f09c"}.fa-credit-card,.fa-credit-card-alt{--fa:"\f09d"}.fa-feed,.fa-rss{--fa:"\f09e"}.fa-hard-drive,.fa-hdd{--fa:"\f0a0"}.fa-bullhorn{--fa:"\f0a1"}.fa-certificate{--fa:"\f0a3"}.fa-hand-point-right{--fa:"\f0a4"}.fa-hand-point-left{--fa:"\f0a5"}.fa-hand-point-up{--fa:"\f0a6"}.fa-hand-point-down{--fa:"\f0a7"}.fa-arrow-circle-left,.fa-circle-arrow-left{--fa:"\f0a8"}.fa-arrow-circle-right,.fa-circle-arrow-right{--fa:"\f0a9"}.fa-arrow-circle-up,.fa-circle-arrow-up{--fa:"\f0aa"}.fa-arrow-circle-down,.fa-circle-arrow-down{--fa:"\f0ab"}.fa-globe{--fa:"\f0ac"}.fa-wrench{--fa:"\f0ad"}.fa-list-check,.fa-tasks{--fa:"\f0ae"}.fa-filter{--fa:"\f0b0"}.fa-briefcase{--fa:"\f0b1"}.fa-arrows-alt,.fa-up-down-left-right{--fa:"\f0b2"}.fa-users{--fa:"\f0c0"}.fa-chain,.fa-link{--fa:"\f0c1"}.fa-cloud{--fa:"\f0c2"}.fa-flask{--fa:"\f0c3"}.fa-cut,.fa-scissors{--fa:"\f0c4"}.fa-copy{--fa:"\f0c5"}.fa-paperclip{--fa:"\f0c6"}.fa-floppy-disk,.fa-save{--fa:"\f0c7"}.fa-square{--fa:"\f0c8"}.fa-bars,.fa-navicon{--fa:"\f0c9"}.fa-list-dots,.fa-list-ul{--fa:"\f0ca"}.fa-list-1-2,.fa-list-numeric,.fa-list-ol{--fa:"\f0cb"}.fa-strikethrough{--fa:"\f0cc"}.fa-underline{--fa:"\f0cd"}.fa-table{--fa:"\f0ce"}.fa-magic,.fa-wand-magic{--fa:"\f0d0"}.fa-truck{--fa:"\f0d1"}.fa-money-bill{--fa:"\f0d6"}.fa-caret-down{--fa:"\f0d7"}.fa-caret-up{--fa:"\f0d8"}.fa-caret-left{--fa:"\f0d9"}.fa-caret-right{--fa:"\f0da"}.fa-columns,.fa-table-columns{--fa:"\f0db"}.fa-sort,.fa-unsorted{--fa:"\f0dc"}.fa-sort-desc,.fa-sort-down{--fa:"\f0dd"}.fa-sort-asc,.fa-sort-up{--fa:"\f0de"}.fa-envelope{--fa:"\f0e0"}.fa-arrow-left-rotate,.fa-arrow-rotate-back,.fa-arrow-rotate-backward,.fa-arrow-rotate-left,.fa-undo{--fa:"\f0e2"}.fa-gavel,.fa-legal{--fa:"\f0e3"}.fa-bolt,.fa-zap{--fa:"\f0e7"}.fa-sitemap{--fa:"\f0e8"}.fa-umbrella{--fa:"\f0e9"}.fa-file-clipboard,.fa-paste{--fa:"\f0ea"}.fa-lightbulb{--fa:"\f0eb"}.fa-arrow-right-arrow-left,.fa-exchange{--fa:"\f0ec"}.fa-cloud-arrow-down,.fa-cloud-download,.fa-cloud-download-alt{--fa:"\f0ed"}.fa-cloud-arrow-up,.fa-cloud-upload,.fa-cloud-upload-alt{--fa:"\f0ee"}.fa-user-doctor,.fa-user-md{--fa:"\f0f0"}.fa-stethoscope{--fa:"\f0f1"}.fa-suitcase{--fa:"\f0f2"}.fa-bell{--fa:"\f0f3"}.fa-coffee,.fa-mug-saucer{--fa:"\f0f4"}.fa-hospital,.fa-hospital-alt,.fa-hospital-wide{--fa:"\f0f8"}.fa-ambulance,.fa-truck-medical{--fa:"\f0f9"}.fa-medkit,.fa-suitcase-medical{--fa:"\f0fa"}.fa-fighter-jet,.fa-jet-fighter{--fa:"\f0fb"}.fa-beer,.fa-beer-mug-empty{--fa:"\f0fc"}.fa-h-square,.fa-square-h{--fa:"\f0fd"}.fa-plus-square,.fa-square-plus{--fa:"\f0fe"}.fa-angle-double-left,.fa-angles-left{--fa:"\f100"}.fa-angle-double-right,.fa-angles-right{--fa:"\f101"}.fa-angle-double-up,.fa-angles-up{--fa:"\f102"}.fa-angle-double-down,.fa-angles-down{--fa:"\f103"}.fa-angle-left{--fa:"\f104"}.fa-angle-right{--fa:"\f105"}.fa-angle-up{--fa:"\f106"}.fa-angle-down{--fa:"\f107"}.fa-laptop{--fa:"\f109"}.fa-tablet-button{--fa:"\f10a"}.fa-mobile-button{--fa:"\f10b"}.fa-quote-left,.fa-quote-left-alt{--fa:"\f10d"}.fa-quote-right,.fa-quote-right-alt{--fa:"\f10e"}.fa-spinner{--fa:"\f110"}.fa-circle{--fa:"\f111"}.fa-face-smile,.fa-smile{--fa:"\f118"}.fa-face-frown,.fa-frown{--fa:"\f119"}.fa-face-meh,.fa-meh{--fa:"\f11a"}.fa-gamepad{--fa:"\f11b"}.fa-keyboard{--fa:"\f11c"}.fa-flag-checkered{--fa:"\f11e"}.fa-terminal{--fa:"\f120"}.fa-code{--fa:"\f121"}.fa-mail-reply-all,.fa-reply-all{--fa:"\f122"}.fa-location-arrow{--fa:"\f124"}.fa-crop{--fa:"\f125"}.fa-code-branch{--fa:"\f126"}.fa-chain-broken,.fa-chain-slash,.fa-link-slash,.fa-unlink{--fa:"\f127"}.fa-info{--fa:"\f129"}.fa-superscript{--fa:"\f12b"}.fa-subscript{--fa:"\f12c"}.fa-eraser{--fa:"\f12d"}.fa-puzzle-piece{--fa:"\f12e"}.fa-microphone{--fa:"\f130"}.fa-microphone-slash{--fa:"\f131"}.fa-shield,.fa-shield-blank{--fa:"\f132"}.fa-calendar{--fa:"\f133"}.fa-fire-extinguisher{--fa:"\f134"}.fa-rocket{--fa:"\f135"}.fa-chevron-circle-left,.fa-circle-chevron-left{--fa:"\f137"}.fa-chevron-circle-right,.fa-circle-chevron-right{--fa:"\f138"}.fa-chevron-circle-up,.fa-circle-chevron-up{--fa:"\f139"}.fa-chevron-circle-down,.fa-circle-chevron-down{--fa:"\f13a"}.fa-anchor{--fa:"\f13d"}.fa-unlock-alt,.fa-unlock-keyhole{--fa:"\f13e"}.fa-bullseye{--fa:"\f140"}.fa-ellipsis,.fa-ellipsis-h{--fa:"\f141"}.fa-ellipsis-v,.fa-ellipsis-vertical{--fa:"\f142"}.fa-rss-square,.fa-square-rss{--fa:"\f143"}.fa-circle-play,.fa-play-circle{--fa:"\f144"}.fa-ticket{--fa:"\f145"}.fa-minus-square,.fa-square-minus{--fa:"\f146"}.fa-arrow-turn-up,.fa-level-up{--fa:"\f148"}.fa-arrow-turn-down,.fa-level-down{--fa:"\f149"}.fa-check-square,.fa-square-check{--fa:"\f14a"}.fa-pen-square,.fa-pencil-square,.fa-square-pen{--fa:"\f14b"}.fa-external-link-square,.fa-square-arrow-up-right{--fa:"\f14c"}.fa-share-from-square,.fa-share-square{--fa:"\f14d"}.fa-compass{--fa:"\f14e"}.fa-caret-square-down,.fa-square-caret-down{--fa:"\f150"}.fa-caret-square-up,.fa-square-caret-up{--fa:"\f151"}.fa-caret-square-right,.fa-square-caret-right{--fa:"\f152"}.fa-eur,.fa-euro,.fa-euro-sign{--fa:"\f153"}.fa-gbp,.fa-pound-sign,.fa-sterling-sign{--fa:"\f154"}.fa-rupee,.fa-rupee-sign{--fa:"\f156"}.fa-cny,.fa-jpy,.fa-rmb,.fa-yen,.fa-yen-sign{--fa:"\f157"}.fa-rouble,.fa-rub,.fa-ruble,.fa-ruble-sign{--fa:"\f158"}.fa-krw,.fa-won,.fa-won-sign{--fa:"\f159"}.fa-file{--fa:"\f15b"}.fa-file-alt,.fa-file-lines,.fa-file-text{--fa:"\f15c"}.fa-arrow-down-a-z,.fa-sort-alpha-asc,.fa-sort-alpha-down{--fa:"\f15d"}.fa-arrow-up-a-z,.fa-sort-alpha-up{--fa:"\f15e"}.fa-arrow-down-wide-short,.fa-sort-amount-asc,.fa-sort-amount-down{--fa:"\f160"}.fa-arrow-up-wide-short,.fa-sort-amount-up{--fa:"\f161"}.fa-arrow-down-1-9,.fa-sort-numeric-asc,.fa-sort-numeric-down{--fa:"\f162"}.fa-arrow-up-1-9,.fa-sort-numeric-up{--fa:"\f163"}.fa-thumbs-up{--fa:"\f164"}.fa-thumbs-down{--fa:"\f165"}.fa-arrow-down-long,.fa-long-arrow-down{--fa:"\f175"}.fa-arrow-up-long,.fa-long-arrow-up{--fa:"\f176"}.fa-arrow-left-long,.fa-long-arrow-left{--fa:"\f177"}.fa-arrow-right-long,.fa-long-arrow-right{--fa:"\f178"}.fa-female,.fa-person-dress{--fa:"\f182"}.fa-male,.fa-person{--fa:"\f183"}.fa-sun{--fa:"\f185"}.fa-moon{--fa:"\f186"}.fa-archive,.fa-box-archive{--fa:"\f187"}.fa-bug{--fa:"\f188"}.fa-caret-square-left,.fa-square-caret-left{--fa:"\f191"}.fa-circle-dot,.fa-dot-circle{--fa:"\f192"}.fa-wheelchair{--fa:"\f193"}.fa-lira-sign{--fa:"\f195"}.fa-shuttle-space,.fa-space-shuttle{--fa:"\f197"}.fa-envelope-square,.fa-square-envelope{--fa:"\f199"}.fa-bank,.fa-building-columns,.fa-institution,.fa-museum,.fa-university{--fa:"\f19c"}.fa-graduation-cap,.fa-mortar-board{--fa:"\f19d"}.fa-language{--fa:"\f1ab"}.fa-fax{--fa:"\f1ac"}.fa-building{--fa:"\f1ad"}.fa-child{--fa:"\f1ae"}.fa-paw{--fa:"\f1b0"}.fa-cube{--fa:"\f1b2"}.fa-cubes{--fa:"\f1b3"}.fa-recycle{--fa:"\f1b8"}.fa-automobile,.fa-car{--fa:"\f1b9"}.fa-cab,.fa-taxi{--fa:"\f1ba"}.fa-tree{--fa:"\f1bb"}.fa-database{--fa:"\f1c0"}.fa-file-pdf{--fa:"\f1c1"}.fa-file-word{--fa:"\f1c2"}.fa-file-excel{--fa:"\f1c3"}.fa-file-powerpoint{--fa:"\f1c4"}.fa-file-image{--fa:"\f1c5"}.fa-file-archive,.fa-file-zipper{--fa:"\f1c6"}.fa-file-audio{--fa:"\f1c7"}.fa-file-video{--fa:"\f1c8"}.fa-file-code{--fa:"\f1c9"}.fa-life-ring{--fa:"\f1cd"}.fa-circle-notch{--fa:"\f1ce"}.fa-paper-plane{--fa:"\f1d8"}.fa-clock-rotate-left,.fa-history{--fa:"\f1da"}.fa-header,.fa-heading{--fa:"\f1dc"}.fa-paragraph{--fa:"\f1dd"}.fa-sliders,.fa-sliders-h{--fa:"\f1de"}.fa-share-alt,.fa-share-nodes{--fa:"\f1e0"}.fa-share-alt-square,.fa-square-share-nodes{--fa:"\f1e1"}.fa-bomb{--fa:"\f1e2"}.fa-futbol,.fa-futbol-ball,.fa-soccer-ball{--fa:"\f1e3"}.fa-teletype,.fa-tty{--fa:"\f1e4"}.fa-binoculars{--fa:"\f1e5"}.fa-plug{--fa:"\f1e6"}.fa-newspaper{--fa:"\f1ea"}.fa-wifi,.fa-wifi-3,.fa-wifi-strong{--fa:"\f1eb"}.fa-calculator{--fa:"\f1ec"}.fa-bell-slash{--fa:"\f1f6"}.fa-trash{--fa:"\f1f8"}.fa-copyright{--fa:"\f1f9"}.fa-eye-dropper,.fa-eye-dropper-empty,.fa-eyedropper{--fa:"\f1fb"}.fa-paint-brush,.fa-paintbrush{--fa:"\f1fc"}.fa-birthday-cake,.fa-cake,.fa-cake-candles{--fa:"\f1fd"}.fa-area-chart,.fa-chart-area{--fa:"\f1fe"}.fa-chart-pie,.fa-pie-chart{--fa:"\f200"}.fa-chart-line,.fa-line-chart{--fa:"\f201"}.fa-toggle-off{--fa:"\f204"}.fa-toggle-on{--fa:"\f205"}.fa-bicycle{--fa:"\f206"}.fa-bus{--fa:"\f207"}.fa-closed-captioning{--fa:"\f20a"}.fa-ils,.fa-shekel,.fa-shekel-sign,.fa-sheqel,.fa-sheqel-sign{--fa:"\f20b"}.fa-cart-plus{--fa:"\f217"}.fa-cart-arrow-down{--fa:"\f218"}.fa-diamond{--fa:"\f219"}.fa-ship{--fa:"\f21a"}.fa-user-secret{--fa:"\f21b"}.fa-motorcycle{--fa:"\f21c"}.fa-street-view{--fa:"\f21d"}.fa-heart-pulse,.fa-heartbeat{--fa:"\f21e"}.fa-venus{--fa:"\f221"}.fa-mars{--fa:"\f222"}.fa-mercury{--fa:"\f223"}.fa-mars-and-venus{--fa:"\f224"}.fa-transgender,.fa-transgender-alt{--fa:"\f225"}.fa-venus-double{--fa:"\f226"}.fa-mars-double{--fa:"\f227"}.fa-venus-mars{--fa:"\f228"}.fa-mars-stroke{--fa:"\f229"}.fa-mars-stroke-up,.fa-mars-stroke-v{--fa:"\f22a"}.fa-mars-stroke-h,.fa-mars-stroke-right{--fa:"\f22b"}.fa-neuter{--fa:"\f22c"}.fa-genderless{--fa:"\f22d"}.fa-server{--fa:"\f233"}.fa-user-plus{--fa:"\f234"}.fa-user-times,.fa-user-xmark{--fa:"\f235"}.fa-bed{--fa:"\f236"}.fa-train{--fa:"\f238"}.fa-subway,.fa-train-subway{--fa:"\f239"}.fa-battery,.fa-battery-5,.fa-battery-full{--fa:"\f240"}.fa-battery-4,.fa-battery-three-quarters{--fa:"\f241"}.fa-battery-3,.fa-battery-half{--fa:"\f242"}.fa-battery-2,.fa-battery-quarter{--fa:"\f243"}.fa-battery-0,.fa-battery-empty{--fa:"\f244"}.fa-arrow-pointer,.fa-mouse-pointer{--fa:"\f245"}.fa-i-cursor{--fa:"\f246"}.fa-object-group{--fa:"\f247"}.fa-object-ungroup{--fa:"\f248"}.fa-note-sticky,.fa-sticky-note{--fa:"\f249"}.fa-clone{--fa:"\f24d"}.fa-balance-scale,.fa-scale-balanced{--fa:"\f24e"}.fa-hourglass-1,.fa-hourglass-start{--fa:"\f251"}.fa-hourglass-2,.fa-hourglass-half{--fa:"\f252"}.fa-hourglass-3,.fa-hourglass-end{--fa:"\f253"}.fa-hourglass,.fa-hourglass-empty{--fa:"\f254"}.fa-hand-back-fist,.fa-hand-rock{--fa:"\f255"}.fa-hand,.fa-hand-paper{--fa:"\f256"}.fa-hand-scissors{--fa:"\f257"}.fa-hand-lizard{--fa:"\f258"}.fa-hand-spock{--fa:"\f259"}.fa-hand-pointer{--fa:"\f25a"}.fa-hand-peace{--fa:"\f25b"}.fa-trademark{--fa:"\f25c"}.fa-registered{--fa:"\f25d"}.fa-television,.fa-tv,.fa-tv-alt{--fa:"\f26c"}.fa-calendar-plus{--fa:"\f271"}.fa-calendar-minus{--fa:"\f272"}.fa-calendar-times,.fa-calendar-xmark{--fa:"\f273"}.fa-calendar-check{--fa:"\f274"}.fa-industry{--fa:"\f275"}.fa-map-pin{--fa:"\f276"}.fa-map-signs,.fa-signs-post{--fa:"\f277"}.fa-map{--fa:"\f279"}.fa-comment-alt,.fa-message{--fa:"\f27a"}.fa-circle-pause,.fa-pause-circle{--fa:"\f28b"}.fa-circle-stop,.fa-stop-circle{--fa:"\f28d"}.fa-bag-shopping,.fa-shopping-bag{--fa:"\f290"}.fa-basket-shopping,.fa-shopping-basket{--fa:"\f291"}.fa-universal-access{--fa:"\f29a"}.fa-blind,.fa-person-walking-with-cane{--fa:"\f29d"}.fa-audio-description{--fa:"\f29e"}.fa-phone-volume,.fa-volume-control-phone{--fa:"\f2a0"}.fa-braille{--fa:"\f2a1"}.fa-assistive-listening-systems,.fa-ear-listen{--fa:"\f2a2"}.fa-american-sign-language-interpreting,.fa-asl-interpreting,.fa-hands-american-sign-language-interpreting,.fa-hands-asl-interpreting{--fa:"\f2a3"}.fa-deaf,.fa-deafness,.fa-ear-deaf,.fa-hard-of-hearing{--fa:"\f2a4"}.fa-hands,.fa-sign-language,.fa-signing{--fa:"\f2a7"}.fa-eye-low-vision,.fa-low-vision{--fa:"\f2a8"}.fa-handshake,.fa-handshake-alt,.fa-handshake-simple{--fa:"\f2b5"}.fa-envelope-open{--fa:"\f2b6"}.fa-address-book,.fa-contact-book{--fa:"\f2b9"}.fa-address-card,.fa-contact-card,.fa-vcard{--fa:"\f2bb"}.fa-circle-user,.fa-user-circle{--fa:"\f2bd"}.fa-id-badge{--fa:"\f2c1"}.fa-drivers-license,.fa-id-card{--fa:"\f2c2"}.fa-temperature-4,.fa-temperature-full,.fa-thermometer-4,.fa-thermometer-full{--fa:"\f2c7"}.fa-temperature-3,.fa-temperature-three-quarters,.fa-thermometer-3,.fa-thermometer-three-quarters{--fa:"\f2c8"}.fa-temperature-2,.fa-temperature-half,.fa-thermometer-2,.fa-thermometer-half{--fa:"\f2c9"}.fa-temperature-1,.fa-temperature-quarter,.fa-thermometer-1,.fa-thermometer-quarter{--fa:"\f2ca"}.fa-temperature-0,.fa-temperature-empty,.fa-thermometer-0,.fa-thermometer-empty{--fa:"\f2cb"}.fa-shower{--fa:"\f2cc"}.fa-bath,.fa-bathtub{--fa:"\f2cd"}.fa-podcast{--fa:"\f2ce"}.fa-window-maximize{--fa:"\f2d0"}.fa-window-minimize{--fa:"\f2d1"}.fa-window-restore{--fa:"\f2d2"}.fa-square-xmark,.fa-times-square,.fa-xmark-square{--fa:"\f2d3"}.fa-microchip{--fa:"\f2db"}.fa-snowflake{--fa:"\f2dc"}.fa-spoon,.fa-utensil-spoon{--fa:"\f2e5"}.fa-cutlery,.fa-utensils{--fa:"\f2e7"}.fa-rotate-back,.fa-rotate-backward,.fa-rotate-left,.fa-undo-alt{--fa:"\f2ea"}.fa-trash-alt,.fa-trash-can{--fa:"\f2ed"}.fa-rotate,.fa-sync-alt{--fa:"\f2f1"}.fa-stopwatch{--fa:"\f2f2"}.fa-right-from-bracket,.fa-sign-out-alt{--fa:"\f2f5"}.fa-right-to-bracket,.fa-sign-in-alt{--fa:"\f2f6"}.fa-redo-alt,.fa-rotate-forward,.fa-rotate-right{--fa:"\f2f9"}.fa-poo{--fa:"\f2fe"}.fa-images{--fa:"\f302"}.fa-pencil,.fa-pencil-alt{--fa:"\f303"}.fa-pen{--fa:"\f304"}.fa-pen-alt,.fa-pen-clip{--fa:"\f305"}.fa-octagon{--fa:"\f306"}.fa-down-long,.fa-long-arrow-alt-down{--fa:"\f309"}.fa-left-long,.fa-long-arrow-alt-left{--fa:"\f30a"}.fa-long-arrow-alt-right,.fa-right-long{--fa:"\f30b"}.fa-long-arrow-alt-up,.fa-up-long{--fa:"\f30c"}.fa-hexagon{--fa:"\f312"}.fa-file-edit,.fa-file-pen{--fa:"\f31c"}.fa-expand-arrows-alt,.fa-maximize{--fa:"\f31e"}.fa-clipboard{--fa:"\f328"}.fa-arrows-alt-h,.fa-left-right{--fa:"\f337"}.fa-arrows-alt-v,.fa-up-down{--fa:"\f338"}.fa-alarm-clock{--fa:"\f34e"}.fa-arrow-alt-circle-down,.fa-circle-down{--fa:"\f358"}.fa-arrow-alt-circle-left,.fa-circle-left{--fa:"\f359"}.fa-arrow-alt-circle-right,.fa-circle-right{--fa:"\f35a"}.fa-arrow-alt-circle-up,.fa-circle-up{--fa:"\f35b"}.fa-external-link-alt,.fa-up-right-from-square{--fa:"\f35d"}.fa-external-link-square-alt,.fa-square-up-right{--fa:"\f360"}.fa-exchange-alt,.fa-right-left{--fa:"\f362"}.fa-repeat{--fa:"\f363"}.fa-code-commit{--fa:"\f386"}.fa-code-merge{--fa:"\f387"}.fa-desktop,.fa-desktop-alt{--fa:"\f390"}.fa-gem{--fa:"\f3a5"}.fa-level-down-alt,.fa-turn-down{--fa:"\f3be"}.fa-level-up-alt,.fa-turn-up{--fa:"\f3bf"}.fa-lock-open{--fa:"\f3c1"}.fa-location-dot,.fa-map-marker-alt{--fa:"\f3c5"}.fa-microphone-alt,.fa-microphone-lines{--fa:"\f3c9"}.fa-mobile-alt,.fa-mobile-screen-button{--fa:"\f3cd"}.fa-mobile,.fa-mobile-android,.fa-mobile-phone{--fa:"\f3ce"}.fa-mobile-android-alt,.fa-mobile-screen{--fa:"\f3cf"}.fa-money-bill-1,.fa-money-bill-alt{--fa:"\f3d1"}.fa-phone-slash{--fa:"\f3dd"}.fa-image-portrait,.fa-portrait{--fa:"\f3e0"}.fa-mail-reply,.fa-reply{--fa:"\f3e5"}.fa-shield-alt,.fa-shield-halved{--fa:"\f3ed"}.fa-tablet-alt,.fa-tablet-screen-button{--fa:"\f3fa"}.fa-tablet,.fa-tablet-android{--fa:"\f3fb"}.fa-ticket-alt,.fa-ticket-simple{--fa:"\f3ff"}.fa-rectangle-times,.fa-rectangle-xmark,.fa-times-rectangle,.fa-window-close{--fa:"\f410"}.fa-compress-alt,.fa-down-left-and-up-right-to-center{--fa:"\f422"}.fa-expand-alt,.fa-up-right-and-down-left-from-center{--fa:"\f424"}.fa-baseball-bat-ball{--fa:"\f432"}.fa-baseball,.fa-baseball-ball{--fa:"\f433"}.fa-basketball,.fa-basketball-ball{--fa:"\f434"}.fa-bowling-ball{--fa:"\f436"}.fa-chess{--fa:"\f439"}.fa-chess-bishop{--fa:"\f43a"}.fa-chess-board{--fa:"\f43c"}.fa-chess-king{--fa:"\f43f"}.fa-chess-knight{--fa:"\f441"}.fa-chess-pawn{--fa:"\f443"}.fa-chess-queen{--fa:"\f445"}.fa-chess-rook{--fa:"\f447"}.fa-dumbbell{--fa:"\f44b"}.fa-football,.fa-football-ball{--fa:"\f44e"}.fa-golf-ball,.fa-golf-ball-tee{--fa:"\f450"}.fa-hockey-puck{--fa:"\f453"}.fa-broom-ball,.fa-quidditch,.fa-quidditch-broom-ball{--fa:"\f458"}.fa-square-full{--fa:"\f45c"}.fa-ping-pong-paddle-ball,.fa-table-tennis,.fa-table-tennis-paddle-ball{--fa:"\f45d"}.fa-volleyball,.fa-volleyball-ball{--fa:"\f45f"}.fa-allergies,.fa-hand-dots{--fa:"\f461"}.fa-band-aid,.fa-bandage{--fa:"\f462"}.fa-box{--fa:"\f466"}.fa-boxes,.fa-boxes-alt,.fa-boxes-stacked{--fa:"\f468"}.fa-briefcase-medical{--fa:"\f469"}.fa-burn,.fa-fire-flame-simple{--fa:"\f46a"}.fa-capsules{--fa:"\f46b"}.fa-clipboard-check{--fa:"\f46c"}.fa-clipboard-list{--fa:"\f46d"}.fa-diagnoses,.fa-person-dots-from-line{--fa:"\f470"}.fa-dna{--fa:"\f471"}.fa-dolly,.fa-dolly-box{--fa:"\f472"}.fa-cart-flatbed,.fa-dolly-flatbed{--fa:"\f474"}.fa-file-medical{--fa:"\f477"}.fa-file-medical-alt,.fa-file-waveform{--fa:"\f478"}.fa-first-aid,.fa-kit-medical{--fa:"\f479"}.fa-circle-h,.fa-hospital-symbol{--fa:"\f47e"}.fa-id-card-alt,.fa-id-card-clip{--fa:"\f47f"}.fa-notes-medical{--fa:"\f481"}.fa-pallet{--fa:"\f482"}.fa-pills{--fa:"\f484"}.fa-prescription-bottle{--fa:"\f485"}.fa-prescription-bottle-alt,.fa-prescription-bottle-medical{--fa:"\f486"}.fa-bed-pulse,.fa-procedures{--fa:"\f487"}.fa-shipping-fast,.fa-truck-fast{--fa:"\f48b"}.fa-smoking{--fa:"\f48d"}.fa-syringe{--fa:"\f48e"}.fa-tablets{--fa:"\f490"}.fa-thermometer{--fa:"\f491"}.fa-vial{--fa:"\f492"}.fa-vials{--fa:"\f493"}.fa-warehouse{--fa:"\f494"}.fa-weight,.fa-weight-scale{--fa:"\f496"}.fa-x-ray{--fa:"\f497"}.fa-box-open{--fa:"\f49e"}.fa-comment-dots,.fa-commenting{--fa:"\f4ad"}.fa-comment-slash{--fa:"\f4b3"}.fa-couch{--fa:"\f4b8"}.fa-circle-dollar-to-slot,.fa-donate{--fa:"\f4b9"}.fa-dove{--fa:"\f4ba"}.fa-hand-holding{--fa:"\f4bd"}.fa-hand-holding-heart{--fa:"\f4be"}.fa-hand-holding-dollar,.fa-hand-holding-usd{--fa:"\f4c0"}.fa-hand-holding-droplet,.fa-hand-holding-water{--fa:"\f4c1"}.fa-hands-holding{--fa:"\f4c2"}.fa-hands-helping,.fa-handshake-angle{--fa:"\f4c4"}.fa-parachute-box{--fa:"\f4cd"}.fa-people-carry,.fa-people-carry-box{--fa:"\f4ce"}.fa-piggy-bank{--fa:"\f4d3"}.fa-ribbon{--fa:"\f4d6"}.fa-route{--fa:"\f4d7"}.fa-seedling,.fa-sprout{--fa:"\f4d8"}.fa-sign,.fa-sign-hanging{--fa:"\f4d9"}.fa-face-smile-wink,.fa-smile-wink{--fa:"\f4da"}.fa-tape{--fa:"\f4db"}.fa-truck-loading,.fa-truck-ramp-box{--fa:"\f4de"}.fa-truck-moving{--fa:"\f4df"}.fa-video-slash{--fa:"\f4e2"}.fa-wine-glass{--fa:"\f4e3"}.fa-user-astronaut{--fa:"\f4fb"}.fa-user-check{--fa:"\f4fc"}.fa-user-clock{--fa:"\f4fd"}.fa-user-cog,.fa-user-gear{--fa:"\f4fe"}.fa-user-edit,.fa-user-pen{--fa:"\f4ff"}.fa-user-friends,.fa-user-group{--fa:"\f500"}.fa-user-graduate{--fa:"\f501"}.fa-user-lock{--fa:"\f502"}.fa-user-minus{--fa:"\f503"}.fa-user-ninja{--fa:"\f504"}.fa-user-shield{--fa:"\f505"}.fa-user-alt-slash,.fa-user-large-slash,.fa-user-slash{--fa:"\f506"}.fa-user-tag{--fa:"\f507"}.fa-user-tie{--fa:"\f508"}.fa-users-cog,.fa-users-gear{--fa:"\f509"}.fa-balance-scale-left,.fa-scale-unbalanced{--fa:"\f515"}.fa-balance-scale-right,.fa-scale-unbalanced-flip{--fa:"\f516"}.fa-blender{--fa:"\f517"}.fa-book-open{--fa:"\f518"}.fa-broadcast-tower,.fa-tower-broadcast{--fa:"\f519"}.fa-broom{--fa:"\f51a"}.fa-blackboard,.fa-chalkboard{--fa:"\f51b"}.fa-chalkboard-teacher,.fa-chalkboard-user{--fa:"\f51c"}.fa-church{--fa:"\f51d"}.fa-coins{--fa:"\f51e"}.fa-compact-disc{--fa:"\f51f"}.fa-crow{--fa:"\f520"}.fa-crown{--fa:"\f521"}.fa-dice{--fa:"\f522"}.fa-dice-five{--fa:"\f523"}.fa-dice-four{--fa:"\f524"}.fa-dice-one{--fa:"\f525"}.fa-dice-six{--fa:"\f526"}.fa-dice-three{--fa:"\f527"}.fa-dice-two{--fa:"\f528"}.fa-divide{--fa:"\f529"}.fa-door-closed{--fa:"\f52a"}.fa-door-open{--fa:"\f52b"}.fa-feather{--fa:"\f52d"}.fa-frog{--fa:"\f52e"}.fa-gas-pump{--fa:"\f52f"}.fa-glasses{--fa:"\f530"}.fa-greater-than-equal{--fa:"\f532"}.fa-helicopter{--fa:"\f533"}.fa-infinity{--fa:"\f534"}.fa-kiwi-bird{--fa:"\f535"}.fa-less-than-equal{--fa:"\f537"}.fa-memory{--fa:"\f538"}.fa-microphone-alt-slash,.fa-microphone-lines-slash{--fa:"\f539"}.fa-money-bill-wave{--fa:"\f53a"}.fa-money-bill-1-wave,.fa-money-bill-wave-alt{--fa:"\f53b"}.fa-money-check{--fa:"\f53c"}.fa-money-check-alt,.fa-money-check-dollar{--fa:"\f53d"}.fa-not-equal{--fa:"\f53e"}.fa-palette{--fa:"\f53f"}.fa-parking,.fa-square-parking{--fa:"\f540"}.fa-diagram-project,.fa-project-diagram{--fa:"\f542"}.fa-receipt{--fa:"\f543"}.fa-robot{--fa:"\f544"}.fa-ruler{--fa:"\f545"}.fa-ruler-combined{--fa:"\f546"}.fa-ruler-horizontal{--fa:"\f547"}.fa-ruler-vertical{--fa:"\f548"}.fa-school{--fa:"\f549"}.fa-screwdriver{--fa:"\f54a"}.fa-shoe-prints{--fa:"\f54b"}.fa-skull{--fa:"\f54c"}.fa-ban-smoking,.fa-smoking-ban{--fa:"\f54d"}.fa-store{--fa:"\f54e"}.fa-shop,.fa-store-alt{--fa:"\f54f"}.fa-bars-staggered,.fa-reorder,.fa-stream{--fa:"\f550"}.fa-stroopwafel{--fa:"\f551"}.fa-toolbox{--fa:"\f552"}.fa-shirt,.fa-t-shirt,.fa-tshirt{--fa:"\f553"}.fa-person-walking,.fa-walking{--fa:"\f554"}.fa-wallet{--fa:"\f555"}.fa-angry,.fa-face-angry{--fa:"\f556"}.fa-archway{--fa:"\f557"}.fa-atlas,.fa-book-atlas{--fa:"\f558"}.fa-award{--fa:"\f559"}.fa-backspace,.fa-delete-left{--fa:"\f55a"}.fa-bezier-curve{--fa:"\f55b"}.fa-bong{--fa:"\f55c"}.fa-brush{--fa:"\f55d"}.fa-bus-alt,.fa-bus-simple{--fa:"\f55e"}.fa-cannabis{--fa:"\f55f"}.fa-check-double{--fa:"\f560"}.fa-cocktail,.fa-martini-glass-citrus{--fa:"\f561"}.fa-bell-concierge,.fa-concierge-bell{--fa:"\f562"}.fa-cookie{--fa:"\f563"}.fa-cookie-bite{--fa:"\f564"}.fa-crop-alt,.fa-crop-simple{--fa:"\f565"}.fa-digital-tachograph,.fa-tachograph-digital{--fa:"\f566"}.fa-dizzy,.fa-face-dizzy{--fa:"\f567"}.fa-compass-drafting,.fa-drafting-compass{--fa:"\f568"}.fa-drum{--fa:"\f569"}.fa-drum-steelpan{--fa:"\f56a"}.fa-feather-alt,.fa-feather-pointed{--fa:"\f56b"}.fa-file-contract{--fa:"\f56c"}.fa-file-arrow-down,.fa-file-download{--fa:"\f56d"}.fa-arrow-right-from-file,.fa-file-export{--fa:"\f56e"}.fa-arrow-right-to-file,.fa-file-import{--fa:"\f56f"}.fa-file-invoice{--fa:"\f570"}.fa-file-invoice-dollar{--fa:"\f571"}.fa-file-prescription{--fa:"\f572"}.fa-file-signature{--fa:"\f573"}.fa-file-arrow-up,.fa-file-upload{--fa:"\f574"}.fa-fill{--fa:"\f575"}.fa-fill-drip{--fa:"\f576"}.fa-fingerprint{--fa:"\f577"}.fa-fish{--fa:"\f578"}.fa-face-flushed,.fa-flushed{--fa:"\f579"}.fa-face-frown-open,.fa-frown-open{--fa:"\f57a"}.fa-glass-martini-alt,.fa-martini-glass{--fa:"\f57b"}.fa-earth-africa,.fa-globe-africa{--fa:"\f57c"}.fa-earth,.fa-earth-america,.fa-earth-americas,.fa-globe-americas{--fa:"\f57d"}.fa-earth-asia,.fa-globe-asia{--fa:"\f57e"}.fa-face-grimace,.fa-grimace{--fa:"\f57f"}.fa-face-grin,.fa-grin{--fa:"\f580"}.fa-face-grin-wide,.fa-grin-alt{--fa:"\f581"}.fa-face-grin-beam,.fa-grin-beam{--fa:"\f582"}.fa-face-grin-beam-sweat,.fa-grin-beam-sweat{--fa:"\f583"}.fa-face-grin-hearts,.fa-grin-hearts{--fa:"\f584"}.fa-face-grin-squint,.fa-grin-squint{--fa:"\f585"}.fa-face-grin-squint-tears,.fa-grin-squint-tears{--fa:"\f586"}.fa-face-grin-stars,.fa-grin-stars{--fa:"\f587"}.fa-face-grin-tears,.fa-grin-tears{--fa:"\f588"}.fa-face-grin-tongue,.fa-grin-tongue{--fa:"\f589"}.fa-face-grin-tongue-squint,.fa-grin-tongue-squint{--fa:"\f58a"}.fa-face-grin-tongue-wink,.fa-grin-tongue-wink{--fa:"\f58b"}.fa-face-grin-wink,.fa-grin-wink{--fa:"\f58c"}.fa-grid-horizontal,.fa-grip,.fa-grip-horizontal{--fa:"\f58d"}.fa-grid-vertical,.fa-grip-vertical{--fa:"\f58e"}.fa-headset{--fa:"\f590"}.fa-highlighter{--fa:"\f591"}.fa-hot-tub,.fa-hot-tub-person{--fa:"\f593"}.fa-hotel{--fa:"\f594"}.fa-joint{--fa:"\f595"}.fa-face-kiss,.fa-kiss{--fa:"\f596"}.fa-face-kiss-beam,.fa-kiss-beam{--fa:"\f597"}.fa-face-kiss-wink-heart,.fa-kiss-wink-heart{--fa:"\f598"}.fa-face-laugh,.fa-laugh{--fa:"\f599"}.fa-face-laugh-beam,.fa-laugh-beam{--fa:"\f59a"}.fa-face-laugh-squint,.fa-laugh-squint{--fa:"\f59b"}.fa-face-laugh-wink,.fa-laugh-wink{--fa:"\f59c"}.fa-cart-flatbed-suitcase,.fa-luggage-cart{--fa:"\f59d"}.fa-map-location,.fa-map-marked{--fa:"\f59f"}.fa-map-location-dot,.fa-map-marked-alt{--fa:"\f5a0"}.fa-marker{--fa:"\f5a1"}.fa-medal{--fa:"\f5a2"}.fa-face-meh-blank,.fa-meh-blank{--fa:"\f5a4"}.fa-face-rolling-eyes,.fa-meh-rolling-eyes{--fa:"\f5a5"}.fa-monument{--fa:"\f5a6"}.fa-mortar-pestle{--fa:"\f5a7"}.fa-paint-roller{--fa:"\f5aa"}.fa-passport{--fa:"\f5ab"}.fa-pen-fancy{--fa:"\f5ac"}.fa-pen-nib{--fa:"\f5ad"}.fa-pen-ruler,.fa-pencil-ruler{--fa:"\f5ae"}.fa-plane-arrival{--fa:"\f5af"}.fa-plane-departure{--fa:"\f5b0"}.fa-prescription{--fa:"\f5b1"}.fa-face-sad-cry,.fa-sad-cry{--fa:"\f5b3"}.fa-face-sad-tear,.fa-sad-tear{--fa:"\f5b4"}.fa-shuttle-van,.fa-van-shuttle{--fa:"\f5b6"}.fa-signature{--fa:"\f5b7"}.fa-face-smile-beam,.fa-smile-beam{--fa:"\f5b8"}.fa-solar-panel{--fa:"\f5ba"}.fa-spa{--fa:"\f5bb"}.fa-splotch{--fa:"\f5bc"}.fa-spray-can{--fa:"\f5bd"}.fa-stamp{--fa:"\f5bf"}.fa-star-half-alt,.fa-star-half-stroke{--fa:"\f5c0"}.fa-suitcase-rolling{--fa:"\f5c1"}.fa-face-surprise,.fa-surprise{--fa:"\f5c2"}.fa-swatchbook{--fa:"\f5c3"}.fa-person-swimming,.fa-swimmer{--fa:"\f5c4"}.fa-ladder-water,.fa-swimming-pool,.fa-water-ladder{--fa:"\f5c5"}.fa-droplet-slash,.fa-tint-slash{--fa:"\f5c7"}.fa-face-tired,.fa-tired{--fa:"\f5c8"}.fa-tooth{--fa:"\f5c9"}.fa-umbrella-beach{--fa:"\f5ca"}.fa-weight-hanging{--fa:"\f5cd"}.fa-wine-glass-alt,.fa-wine-glass-empty{--fa:"\f5ce"}.fa-air-freshener,.fa-spray-can-sparkles{--fa:"\f5d0"}.fa-apple-alt,.fa-apple-whole{--fa:"\f5d1"}.fa-atom{--fa:"\f5d2"}.fa-bone{--fa:"\f5d7"}.fa-book-open-reader,.fa-book-reader{--fa:"\f5da"}.fa-brain{--fa:"\f5dc"}.fa-car-alt,.fa-car-rear{--fa:"\f5de"}.fa-battery-car,.fa-car-battery{--fa:"\f5df"}.fa-car-burst,.fa-car-crash{--fa:"\f5e1"}.fa-car-side{--fa:"\f5e4"}.fa-charging-station{--fa:"\f5e7"}.fa-diamond-turn-right,.fa-directions{--fa:"\f5eb"}.fa-draw-polygon,.fa-vector-polygon{--fa:"\f5ee"}.fa-laptop-code{--fa:"\f5fc"}.fa-layer-group{--fa:"\f5fd"}.fa-location,.fa-location-crosshairs{--fa:"\f601"}.fa-lungs{--fa:"\f604"}.fa-microscope{--fa:"\f610"}.fa-oil-can{--fa:"\f613"}.fa-poop{--fa:"\f619"}.fa-shapes,.fa-triangle-circle-square{--fa:"\f61f"}.fa-star-of-life{--fa:"\f621"}.fa-dashboard,.fa-gauge,.fa-gauge-med,.fa-tachometer-alt-average{--fa:"\f624"}.fa-gauge-high,.fa-tachometer-alt,.fa-tachometer-alt-fast{--fa:"\f625"}.fa-gauge-simple,.fa-gauge-simple-med,.fa-tachometer-average{--fa:"\f629"}.fa-gauge-simple-high,.fa-tachometer,.fa-tachometer-fast{--fa:"\f62a"}.fa-teeth{--fa:"\f62e"}.fa-teeth-open{--fa:"\f62f"}.fa-masks-theater,.fa-theater-masks{--fa:"\f630"}.fa-traffic-light{--fa:"\f637"}.fa-truck-monster{--fa:"\f63b"}.fa-truck-pickup{--fa:"\f63c"}.fa-ad,.fa-rectangle-ad{--fa:"\f641"}.fa-ankh{--fa:"\f644"}.fa-bible,.fa-book-bible{--fa:"\f647"}.fa-briefcase-clock,.fa-business-time{--fa:"\f64a"}.fa-city{--fa:"\f64f"}.fa-comment-dollar{--fa:"\f651"}.fa-comments-dollar{--fa:"\f653"}.fa-cross{--fa:"\f654"}.fa-dharmachakra{--fa:"\f655"}.fa-envelope-open-text{--fa:"\f658"}.fa-folder-minus{--fa:"\f65d"}.fa-folder-plus{--fa:"\f65e"}.fa-filter-circle-dollar,.fa-funnel-dollar{--fa:"\f662"}.fa-gopuram{--fa:"\f664"}.fa-hamsa{--fa:"\f665"}.fa-bahai,.fa-haykal{--fa:"\f666"}.fa-jedi{--fa:"\f669"}.fa-book-journal-whills,.fa-journal-whills{--fa:"\f66a"}.fa-kaaba{--fa:"\f66b"}.fa-khanda{--fa:"\f66d"}.fa-landmark{--fa:"\f66f"}.fa-envelopes-bulk,.fa-mail-bulk{--fa:"\f674"}.fa-menorah{--fa:"\f676"}.fa-mosque{--fa:"\f678"}.fa-om{--fa:"\f679"}.fa-pastafarianism,.fa-spaghetti-monster-flying{--fa:"\f67b"}.fa-peace{--fa:"\f67c"}.fa-place-of-worship{--fa:"\f67f"}.fa-poll,.fa-square-poll-vertical{--fa:"\f681"}.fa-poll-h,.fa-square-poll-horizontal{--fa:"\f682"}.fa-person-praying,.fa-pray{--fa:"\f683"}.fa-hands-praying,.fa-praying-hands{--fa:"\f684"}.fa-book-quran,.fa-quran{--fa:"\f687"}.fa-magnifying-glass-dollar,.fa-search-dollar{--fa:"\f688"}.fa-magnifying-glass-location,.fa-search-location{--fa:"\f689"}.fa-socks{--fa:"\f696"}.fa-square-root-alt,.fa-square-root-variable{--fa:"\f698"}.fa-star-and-crescent{--fa:"\f699"}.fa-star-of-david{--fa:"\f69a"}.fa-synagogue{--fa:"\f69b"}.fa-scroll-torah,.fa-torah{--fa:"\f6a0"}.fa-torii-gate{--fa:"\f6a1"}.fa-vihara{--fa:"\f6a7"}.fa-volume-mute,.fa-volume-times,.fa-volume-xmark{--fa:"\f6a9"}.fa-yin-yang{--fa:"\f6ad"}.fa-blender-phone{--fa:"\f6b6"}.fa-book-dead,.fa-book-skull{--fa:"\f6b7"}.fa-campground{--fa:"\f6bb"}.fa-cat{--fa:"\f6be"}.fa-chair{--fa:"\f6c0"}.fa-cloud-moon{--fa:"\f6c3"}.fa-cloud-sun{--fa:"\f6c4"}.fa-cow{--fa:"\f6c8"}.fa-dice-d20{--fa:"\f6cf"}.fa-dice-d6{--fa:"\f6d1"}.fa-dog{--fa:"\f6d3"}.fa-dragon{--fa:"\f6d5"}.fa-drumstick-bite{--fa:"\f6d7"}.fa-dungeon{--fa:"\f6d9"}.fa-file-csv{--fa:"\f6dd"}.fa-fist-raised,.fa-hand-fist{--fa:"\f6de"}.fa-ghost{--fa:"\f6e2"}.fa-hammer{--fa:"\f6e3"}.fa-hanukiah{--fa:"\f6e6"}.fa-hat-wizard{--fa:"\f6e8"}.fa-hiking,.fa-person-hiking{--fa:"\f6ec"}.fa-hippo{--fa:"\f6ed"}.fa-horse{--fa:"\f6f0"}.fa-house-chimney-crack,.fa-house-damage{--fa:"\f6f1"}.fa-hryvnia,.fa-hryvnia-sign{--fa:"\f6f2"}.fa-mask{--fa:"\f6fa"}.fa-mountain{--fa:"\f6fc"}.fa-network-wired{--fa:"\f6ff"}.fa-otter{--fa:"\f700"}.fa-ring{--fa:"\f70b"}.fa-person-running,.fa-running{--fa:"\f70c"}.fa-scroll{--fa:"\f70e"}.fa-skull-crossbones{--fa:"\f714"}.fa-slash{--fa:"\f715"}.fa-spider{--fa:"\f717"}.fa-toilet-paper,.fa-toilet-paper-alt,.fa-toilet-paper-blank{--fa:"\f71e"}.fa-tractor{--fa:"\f722"}.fa-user-injured{--fa:"\f728"}.fa-vr-cardboard{--fa:"\f729"}.fa-wand-sparkles{--fa:"\f72b"}.fa-wind{--fa:"\f72e"}.fa-wine-bottle{--fa:"\f72f"}.fa-cloud-meatball{--fa:"\f73b"}.fa-cloud-moon-rain{--fa:"\f73c"}.fa-cloud-rain{--fa:"\f73d"}.fa-cloud-showers-heavy{--fa:"\f740"}.fa-cloud-sun-rain{--fa:"\f743"}.fa-democrat{--fa:"\f747"}.fa-flag-usa{--fa:"\f74d"}.fa-hurricane{--fa:"\f751"}.fa-landmark-alt,.fa-landmark-dome{--fa:"\f752"}.fa-meteor{--fa:"\f753"}.fa-person-booth{--fa:"\f756"}.fa-poo-bolt,.fa-poo-storm{--fa:"\f75a"}.fa-rainbow{--fa:"\f75b"}.fa-republican{--fa:"\f75e"}.fa-smog{--fa:"\f75f"}.fa-temperature-high{--fa:"\f769"}.fa-temperature-low{--fa:"\f76b"}.fa-cloud-bolt,.fa-thunderstorm{--fa:"\f76c"}.fa-tornado{--fa:"\f76f"}.fa-volcano{--fa:"\f770"}.fa-check-to-slot,.fa-vote-yea{--fa:"\f772"}.fa-water{--fa:"\f773"}.fa-baby{--fa:"\f77c"}.fa-baby-carriage,.fa-carriage-baby{--fa:"\f77d"}.fa-biohazard{--fa:"\f780"}.fa-blog{--fa:"\f781"}.fa-calendar-day{--fa:"\f783"}.fa-calendar-week{--fa:"\f784"}.fa-candy-cane{--fa:"\f786"}.fa-carrot{--fa:"\f787"}.fa-cash-register{--fa:"\f788"}.fa-compress-arrows-alt,.fa-minimize{--fa:"\f78c"}.fa-dumpster{--fa:"\f793"}.fa-dumpster-fire{--fa:"\f794"}.fa-ethernet{--fa:"\f796"}.fa-gifts{--fa:"\f79c"}.fa-champagne-glasses,.fa-glass-cheers{--fa:"\f79f"}.fa-glass-whiskey,.fa-whiskey-glass{--fa:"\f7a0"}.fa-earth-europe,.fa-globe-europe{--fa:"\f7a2"}.fa-grip-lines{--fa:"\f7a4"}.fa-grip-lines-vertical{--fa:"\f7a5"}.fa-guitar{--fa:"\f7a6"}.fa-heart-broken,.fa-heart-crack{--fa:"\f7a9"}.fa-holly-berry{--fa:"\f7aa"}.fa-horse-head{--fa:"\f7ab"}.fa-icicles{--fa:"\f7ad"}.fa-igloo{--fa:"\f7ae"}.fa-mitten{--fa:"\f7b5"}.fa-mug-hot{--fa:"\f7b6"}.fa-radiation{--fa:"\f7b9"}.fa-circle-radiation,.fa-radiation-alt{--fa:"\f7ba"}.fa-restroom{--fa:"\f7bd"}.fa-satellite{--fa:"\f7bf"}.fa-satellite-dish{--fa:"\f7c0"}.fa-sd-card{--fa:"\f7c2"}.fa-sim-card{--fa:"\f7c4"}.fa-person-skating,.fa-skating{--fa:"\f7c5"}.fa-person-skiing,.fa-skiing{--fa:"\f7c9"}.fa-person-skiing-nordic,.fa-skiing-nordic{--fa:"\f7ca"}.fa-sleigh{--fa:"\f7cc"}.fa-comment-sms,.fa-sms{--fa:"\f7cd"}.fa-person-snowboarding,.fa-snowboarding{--fa:"\f7ce"}.fa-snowman{--fa:"\f7d0"}.fa-snowplow{--fa:"\f7d2"}.fa-tenge,.fa-tenge-sign{--fa:"\f7d7"}.fa-toilet{--fa:"\f7d8"}.fa-screwdriver-wrench,.fa-tools{--fa:"\f7d9"}.fa-cable-car,.fa-tram{--fa:"\f7da"}.fa-fire-alt,.fa-fire-flame-curved{--fa:"\f7e4"}.fa-bacon{--fa:"\f7e5"}.fa-book-medical{--fa:"\f7e6"}.fa-bread-slice{--fa:"\f7ec"}.fa-cheese{--fa:"\f7ef"}.fa-clinic-medical,.fa-house-chimney-medical{--fa:"\f7f2"}.fa-clipboard-user{--fa:"\f7f3"}.fa-comment-medical{--fa:"\f7f5"}.fa-crutch{--fa:"\f7f7"}.fa-disease{--fa:"\f7fa"}.fa-egg{--fa:"\f7fb"}.fa-folder-tree{--fa:"\f802"}.fa-burger,.fa-hamburger{--fa:"\f805"}.fa-hand-middle-finger{--fa:"\f806"}.fa-hard-hat,.fa-hat-hard,.fa-helmet-safety{--fa:"\f807"}.fa-hospital-user{--fa:"\f80d"}.fa-hotdog{--fa:"\f80f"}.fa-ice-cream{--fa:"\f810"}.fa-laptop-medical{--fa:"\f812"}.fa-pager{--fa:"\f815"}.fa-pepper-hot{--fa:"\f816"}.fa-pizza-slice{--fa:"\f818"}.fa-sack-dollar{--fa:"\f81d"}.fa-book-tanakh,.fa-tanakh{--fa:"\f827"}.fa-bars-progress,.fa-tasks-alt{--fa:"\f828"}.fa-trash-arrow-up,.fa-trash-restore{--fa:"\f829"}.fa-trash-can-arrow-up,.fa-trash-restore-alt{--fa:"\f82a"}.fa-user-nurse{--fa:"\f82f"}.fa-wave-square{--fa:"\f83e"}.fa-biking,.fa-person-biking{--fa:"\f84a"}.fa-border-all{--fa:"\f84c"}.fa-border-none{--fa:"\f850"}.fa-border-style,.fa-border-top-left{--fa:"\f853"}.fa-digging,.fa-person-digging{--fa:"\f85e"}.fa-fan{--fa:"\f863"}.fa-heart-music-camera-bolt,.fa-icons{--fa:"\f86d"}.fa-phone-alt,.fa-phone-flip{--fa:"\f879"}.fa-phone-square-alt,.fa-square-phone-flip{--fa:"\f87b"}.fa-photo-film,.fa-photo-video{--fa:"\f87c"}.fa-remove-format,.fa-text-slash{--fa:"\f87d"}.fa-arrow-down-z-a,.fa-sort-alpha-desc,.fa-sort-alpha-down-alt{--fa:"\f881"}.fa-arrow-up-z-a,.fa-sort-alpha-up-alt{--fa:"\f882"}.fa-arrow-down-short-wide,.fa-sort-amount-desc,.fa-sort-amount-down-alt{--fa:"\f884"}.fa-arrow-up-short-wide,.fa-sort-amount-up-alt{--fa:"\f885"}.fa-arrow-down-9-1,.fa-sort-numeric-desc,.fa-sort-numeric-down-alt{--fa:"\f886"}.fa-arrow-up-9-1,.fa-sort-numeric-up-alt{--fa:"\f887"}.fa-spell-check{--fa:"\f891"}.fa-voicemail{--fa:"\f897"}.fa-hat-cowboy{--fa:"\f8c0"}.fa-hat-cowboy-side{--fa:"\f8c1"}.fa-computer-mouse,.fa-mouse{--fa:"\f8cc"}.fa-radio{--fa:"\f8d7"}.fa-record-vinyl{--fa:"\f8d9"}.fa-walkie-talkie{--fa:"\f8ef"}.fa-caravan{--fa:"\f8ff"}
+:host,:root{--fa-family-brands:"Font Awesome 7 Brands";--fa-font-brands:normal 400 1em/1 var(--fa-family-brands)}@font-face{font-family:"Font Awesome 7 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.woff2)}.fa-brands,.fa-classic.fa-brands,.fab{--fa-family:var(--fa-family-brands);--fa-style:400}.fa-firefox-browser{--fa:"\e007"}.fa-ideal{--fa:"\e013"}.fa-microblog{--fa:"\e01a"}.fa-pied-piper-square,.fa-square-pied-piper{--fa:"\e01e"}.fa-unity{--fa:"\e049"}.fa-dailymotion{--fa:"\e052"}.fa-instagram-square,.fa-square-instagram{--fa:"\e055"}.fa-mixer{--fa:"\e056"}.fa-shopify{--fa:"\e057"}.fa-deezer{--fa:"\e077"}.fa-edge-legacy{--fa:"\e078"}.fa-google-pay{--fa:"\e079"}.fa-rust{--fa:"\e07a"}.fa-tiktok{--fa:"\e07b"}.fa-unsplash{--fa:"\e07c"}.fa-cloudflare{--fa:"\e07d"}.fa-guilded{--fa:"\e07e"}.fa-hive{--fa:"\e07f"}.fa-42-group,.fa-innosoft{--fa:"\e080"}.fa-instalod{--fa:"\e081"}.fa-octopus-deploy{--fa:"\e082"}.fa-perbyte{--fa:"\e083"}.fa-uncharted{--fa:"\e084"}.fa-watchman-monitoring{--fa:"\e087"}.fa-wodu{--fa:"\e088"}.fa-wirsindhandwerk,.fa-wsh{--fa:"\e2d0"}.fa-bots{--fa:"\e340"}.fa-cmplid{--fa:"\e360"}.fa-bilibili{--fa:"\e3d9"}.fa-golang{--fa:"\e40f"}.fa-pix{--fa:"\e43a"}.fa-sitrox{--fa:"\e44a"}.fa-hashnode{--fa:"\e499"}.fa-meta{--fa:"\e49b"}.fa-padlet{--fa:"\e4a0"}.fa-nfc-directional{--fa:"\e530"}.fa-nfc-symbol{--fa:"\e531"}.fa-screenpal{--fa:"\e570"}.fa-space-awesome{--fa:"\e5ac"}.fa-square-font-awesome{--fa:"\e5ad"}.fa-gitlab-square,.fa-square-gitlab{--fa:"\e5ae"}.fa-odysee{--fa:"\e5c6"}.fa-stubber{--fa:"\e5c7"}.fa-debian{--fa:"\e60b"}.fa-shoelace{--fa:"\e60c"}.fa-threads{--fa:"\e618"}.fa-square-threads{--fa:"\e619"}.fa-square-x-twitter{--fa:"\e61a"}.fa-x-twitter{--fa:"\e61b"}.fa-opensuse{--fa:"\e62b"}.fa-letterboxd{--fa:"\e62d"}.fa-square-letterboxd{--fa:"\e62e"}.fa-mintbit{--fa:"\e62f"}.fa-google-scholar{--fa:"\e63b"}.fa-brave{--fa:"\e63c"}.fa-brave-reverse{--fa:"\e63d"}.fa-pixiv{--fa:"\e640"}.fa-upwork{--fa:"\e641"}.fa-webflow{--fa:"\e65c"}.fa-signal-messenger{--fa:"\e663"}.fa-bluesky{--fa:"\e671"}.fa-jxl{--fa:"\e67b"}.fa-square-upwork{--fa:"\e67c"}.fa-web-awesome{--fa:"\e682"}.fa-square-web-awesome{--fa:"\e683"}.fa-square-web-awesome-stroke{--fa:"\e684"}.fa-dart-lang{--fa:"\e693"}.fa-flutter{--fa:"\e694"}.fa-files-pinwheel{--fa:"\e69f"}.fa-css{--fa:"\e6a2"}.fa-square-bluesky{--fa:"\e6a3"}.fa-openai{--fa:"\e7cf"}.fa-square-linkedin{--fa:"\e7d0"}.fa-cash-app{--fa:"\e7d4"}.fa-disqus{--fa:"\e7d5"}.fa-11ty,.fa-eleventy{--fa:"\e7d6"}.fa-kakao-talk{--fa:"\e7d7"}.fa-linktree{--fa:"\e7d8"}.fa-notion{--fa:"\e7d9"}.fa-pandora{--fa:"\e7da"}.fa-pixelfed{--fa:"\e7db"}.fa-tidal{--fa:"\e7dc"}.fa-vsco{--fa:"\e7dd"}.fa-w3c{--fa:"\e7de"}.fa-lumon{--fa:"\e7e2"}.fa-lumon-drop{--fa:"\e7e3"}.fa-square-figma{--fa:"\e7e4"}.fa-tex{--fa:"\e7ff"}.fa-duolingo{--fa:"\e812"}.fa-square-twitter,.fa-twitter-square{--fa:"\f081"}.fa-facebook-square,.fa-square-facebook{--fa:"\f082"}.fa-linkedin{--fa:"\f08c"}.fa-github-square,.fa-square-github{--fa:"\f092"}.fa-twitter{--fa:"\f099"}.fa-facebook{--fa:"\f09a"}.fa-github{--fa:"\f09b"}.fa-pinterest{--fa:"\f0d2"}.fa-pinterest-square,.fa-square-pinterest{--fa:"\f0d3"}.fa-google-plus-square,.fa-square-google-plus{--fa:"\f0d4"}.fa-google-plus-g{--fa:"\f0d5"}.fa-linkedin-in{--fa:"\f0e1"}.fa-github-alt{--fa:"\f113"}.fa-maxcdn{--fa:"\f136"}.fa-html5{--fa:"\f13b"}.fa-css3{--fa:"\f13c"}.fa-btc{--fa:"\f15a"}.fa-youtube{--fa:"\f167"}.fa-xing{--fa:"\f168"}.fa-square-xing,.fa-xing-square{--fa:"\f169"}.fa-dropbox{--fa:"\f16b"}.fa-stack-overflow{--fa:"\f16c"}.fa-instagram{--fa:"\f16d"}.fa-flickr{--fa:"\f16e"}.fa-adn{--fa:"\f170"}.fa-bitbucket{--fa:"\f171"}.fa-tumblr{--fa:"\f173"}.fa-square-tumblr,.fa-tumblr-square{--fa:"\f174"}.fa-apple{--fa:"\f179"}.fa-windows{--fa:"\f17a"}.fa-android{--fa:"\f17b"}.fa-linux{--fa:"\f17c"}.fa-dribbble{--fa:"\f17d"}.fa-skype{--fa:"\f17e"}.fa-foursquare{--fa:"\f180"}.fa-trello{--fa:"\f181"}.fa-gratipay{--fa:"\f184"}.fa-vk{--fa:"\f189"}.fa-weibo{--fa:"\f18a"}.fa-renren{--fa:"\f18b"}.fa-pagelines{--fa:"\f18c"}.fa-stack-exchange{--fa:"\f18d"}.fa-square-vimeo,.fa-vimeo-square{--fa:"\f194"}.fa-slack,.fa-slack-hash{--fa:"\f198"}.fa-wordpress{--fa:"\f19a"}.fa-openid{--fa:"\f19b"}.fa-yahoo{--fa:"\f19e"}.fa-google{--fa:"\f1a0"}.fa-reddit{--fa:"\f1a1"}.fa-reddit-square,.fa-square-reddit{--fa:"\f1a2"}.fa-stumbleupon-circle{--fa:"\f1a3"}.fa-stumbleupon{--fa:"\f1a4"}.fa-delicious{--fa:"\f1a5"}.fa-digg{--fa:"\f1a6"}.fa-pied-piper-pp{--fa:"\f1a7"}.fa-pied-piper-alt{--fa:"\f1a8"}.fa-drupal{--fa:"\f1a9"}.fa-joomla{--fa:"\f1aa"}.fa-behance{--fa:"\f1b4"}.fa-behance-square,.fa-square-behance{--fa:"\f1b5"}.fa-steam{--fa:"\f1b6"}.fa-square-steam,.fa-steam-square{--fa:"\f1b7"}.fa-spotify{--fa:"\f1bc"}.fa-deviantart{--fa:"\f1bd"}.fa-soundcloud{--fa:"\f1be"}.fa-vine{--fa:"\f1ca"}.fa-codepen{--fa:"\f1cb"}.fa-jsfiddle{--fa:"\f1cc"}.fa-rebel{--fa:"\f1d0"}.fa-empire{--fa:"\f1d1"}.fa-git-square,.fa-square-git{--fa:"\f1d2"}.fa-git{--fa:"\f1d3"}.fa-hacker-news{--fa:"\f1d4"}.fa-tencent-weibo{--fa:"\f1d5"}.fa-qq{--fa:"\f1d6"}.fa-weixin{--fa:"\f1d7"}.fa-slideshare{--fa:"\f1e7"}.fa-twitch{--fa:"\f1e8"}.fa-yelp{--fa:"\f1e9"}.fa-paypal{--fa:"\f1ed"}.fa-google-wallet{--fa:"\f1ee"}.fa-cc-visa{--fa:"\f1f0"}.fa-cc-mastercard{--fa:"\f1f1"}.fa-cc-discover{--fa:"\f1f2"}.fa-cc-amex{--fa:"\f1f3"}.fa-cc-paypal{--fa:"\f1f4"}.fa-cc-stripe{--fa:"\f1f5"}.fa-lastfm{--fa:"\f202"}.fa-lastfm-square,.fa-square-lastfm{--fa:"\f203"}.fa-ioxhost{--fa:"\f208"}.fa-angellist{--fa:"\f209"}.fa-buysellads{--fa:"\f20d"}.fa-connectdevelop{--fa:"\f20e"}.fa-dashcube{--fa:"\f210"}.fa-forumbee{--fa:"\f211"}.fa-leanpub{--fa:"\f212"}.fa-sellsy{--fa:"\f213"}.fa-shirtsinbulk{--fa:"\f214"}.fa-simplybuilt{--fa:"\f215"}.fa-skyatlas{--fa:"\f216"}.fa-pinterest-p{--fa:"\f231"}.fa-whatsapp{--fa:"\f232"}.fa-viacoin{--fa:"\f237"}.fa-medium,.fa-medium-m{--fa:"\f23a"}.fa-y-combinator{--fa:"\f23b"}.fa-optin-monster{--fa:"\f23c"}.fa-opencart{--fa:"\f23d"}.fa-expeditedssl{--fa:"\f23e"}.fa-cc-jcb{--fa:"\f24b"}.fa-cc-diners-club{--fa:"\f24c"}.fa-creative-commons{--fa:"\f25e"}.fa-gg{--fa:"\f260"}.fa-gg-circle{--fa:"\f261"}.fa-odnoklassniki{--fa:"\f263"}.fa-odnoklassniki-square,.fa-square-odnoklassniki{--fa:"\f264"}.fa-get-pocket{--fa:"\f265"}.fa-wikipedia-w{--fa:"\f266"}.fa-safari{--fa:"\f267"}.fa-chrome{--fa:"\f268"}.fa-firefox{--fa:"\f269"}.fa-opera{--fa:"\f26a"}.fa-internet-explorer{--fa:"\f26b"}.fa-contao{--fa:"\f26d"}.fa-500px{--fa:"\f26e"}.fa-amazon{--fa:"\f270"}.fa-houzz{--fa:"\f27c"}.fa-vimeo-v{--fa:"\f27d"}.fa-black-tie{--fa:"\f27e"}.fa-fonticons{--fa:"\f280"}.fa-reddit-alien{--fa:"\f281"}.fa-edge{--fa:"\f282"}.fa-codiepie{--fa:"\f284"}.fa-modx{--fa:"\f285"}.fa-fort-awesome{--fa:"\f286"}.fa-usb{--fa:"\f287"}.fa-product-hunt{--fa:"\f288"}.fa-mixcloud{--fa:"\f289"}.fa-scribd{--fa:"\f28a"}.fa-bluetooth{--fa:"\f293"}.fa-bluetooth-b{--fa:"\f294"}.fa-gitlab{--fa:"\f296"}.fa-wpbeginner{--fa:"\f297"}.fa-wpforms{--fa:"\f298"}.fa-envira{--fa:"\f299"}.fa-glide{--fa:"\f2a5"}.fa-glide-g{--fa:"\f2a6"}.fa-viadeo{--fa:"\f2a9"}.fa-square-viadeo,.fa-viadeo-square{--fa:"\f2aa"}.fa-snapchat,.fa-snapchat-ghost{--fa:"\f2ab"}.fa-snapchat-square,.fa-square-snapchat{--fa:"\f2ad"}.fa-pied-piper{--fa:"\f2ae"}.fa-first-order{--fa:"\f2b0"}.fa-yoast{--fa:"\f2b1"}.fa-themeisle{--fa:"\f2b2"}.fa-google-plus{--fa:"\f2b3"}.fa-font-awesome,.fa-font-awesome-flag,.fa-font-awesome-logo-full{--fa:"\f2b4"}.fa-linode{--fa:"\f2b8"}.fa-quora{--fa:"\f2c4"}.fa-free-code-camp{--fa:"\f2c5"}.fa-telegram,.fa-telegram-plane{--fa:"\f2c6"}.fa-bandcamp{--fa:"\f2d5"}.fa-grav{--fa:"\f2d6"}.fa-etsy{--fa:"\f2d7"}.fa-imdb{--fa:"\f2d8"}.fa-ravelry{--fa:"\f2d9"}.fa-sellcast{--fa:"\f2da"}.fa-superpowers{--fa:"\f2dd"}.fa-wpexplorer{--fa:"\f2de"}.fa-meetup{--fa:"\f2e0"}.fa-font-awesome-alt,.fa-square-font-awesome-stroke{--fa:"\f35c"}.fa-accessible-icon{--fa:"\f368"}.fa-accusoft{--fa:"\f369"}.fa-adversal{--fa:"\f36a"}.fa-affiliatetheme{--fa:"\f36b"}.fa-algolia{--fa:"\f36c"}.fa-amilia{--fa:"\f36d"}.fa-angrycreative{--fa:"\f36e"}.fa-app-store{--fa:"\f36f"}.fa-app-store-ios{--fa:"\f370"}.fa-apper{--fa:"\f371"}.fa-asymmetrik{--fa:"\f372"}.fa-audible{--fa:"\f373"}.fa-avianex{--fa:"\f374"}.fa-aws{--fa:"\f375"}.fa-bimobject{--fa:"\f378"}.fa-bitcoin{--fa:"\f379"}.fa-bity{--fa:"\f37a"}.fa-blackberry{--fa:"\f37b"}.fa-blogger{--fa:"\f37c"}.fa-blogger-b{--fa:"\f37d"}.fa-buromobelexperte{--fa:"\f37f"}.fa-centercode{--fa:"\f380"}.fa-cloudscale{--fa:"\f383"}.fa-cloudsmith{--fa:"\f384"}.fa-cloudversify{--fa:"\f385"}.fa-cpanel{--fa:"\f388"}.fa-css3-alt{--fa:"\f38b"}.fa-cuttlefish{--fa:"\f38c"}.fa-d-and-d{--fa:"\f38d"}.fa-deploydog{--fa:"\f38e"}.fa-deskpro{--fa:"\f38f"}.fa-digital-ocean{--fa:"\f391"}.fa-discord{--fa:"\f392"}.fa-discourse{--fa:"\f393"}.fa-dochub{--fa:"\f394"}.fa-docker{--fa:"\f395"}.fa-draft2digital{--fa:"\f396"}.fa-dribbble-square,.fa-square-dribbble{--fa:"\f397"}.fa-dyalog{--fa:"\f399"}.fa-earlybirds{--fa:"\f39a"}.fa-erlang{--fa:"\f39d"}.fa-facebook-f{--fa:"\f39e"}.fa-facebook-messenger{--fa:"\f39f"}.fa-firstdraft{--fa:"\f3a1"}.fa-fonticons-fi{--fa:"\f3a2"}.fa-fort-awesome-alt{--fa:"\f3a3"}.fa-freebsd{--fa:"\f3a4"}.fa-gitkraken{--fa:"\f3a6"}.fa-gofore{--fa:"\f3a7"}.fa-goodreads{--fa:"\f3a8"}.fa-goodreads-g{--fa:"\f3a9"}.fa-google-drive{--fa:"\f3aa"}.fa-google-play{--fa:"\f3ab"}.fa-gripfire{--fa:"\f3ac"}.fa-grunt{--fa:"\f3ad"}.fa-gulp{--fa:"\f3ae"}.fa-hacker-news-square,.fa-square-hacker-news{--fa:"\f3af"}.fa-hire-a-helper{--fa:"\f3b0"}.fa-hotjar{--fa:"\f3b1"}.fa-hubspot{--fa:"\f3b2"}.fa-itunes{--fa:"\f3b4"}.fa-itunes-note{--fa:"\f3b5"}.fa-jenkins{--fa:"\f3b6"}.fa-joget{--fa:"\f3b7"}.fa-js{--fa:"\f3b8"}.fa-js-square,.fa-square-js{--fa:"\f3b9"}.fa-keycdn{--fa:"\f3ba"}.fa-kickstarter,.fa-square-kickstarter{--fa:"\f3bb"}.fa-kickstarter-k{--fa:"\f3bc"}.fa-laravel{--fa:"\f3bd"}.fa-line{--fa:"\f3c0"}.fa-lyft{--fa:"\f3c3"}.fa-magento{--fa:"\f3c4"}.fa-medapps{--fa:"\f3c6"}.fa-medrt{--fa:"\f3c8"}.fa-microsoft{--fa:"\f3ca"}.fa-mix{--fa:"\f3cb"}.fa-mizuni{--fa:"\f3cc"}.fa-monero{--fa:"\f3d0"}.fa-napster{--fa:"\f3d2"}.fa-node-js{--fa:"\f3d3"}.fa-npm{--fa:"\f3d4"}.fa-ns8{--fa:"\f3d5"}.fa-nutritionix{--fa:"\f3d6"}.fa-page4{--fa:"\f3d7"}.fa-palfed{--fa:"\f3d8"}.fa-patreon{--fa:"\f3d9"}.fa-periscope{--fa:"\f3da"}.fa-phabricator{--fa:"\f3db"}.fa-phoenix-framework{--fa:"\f3dc"}.fa-playstation{--fa:"\f3df"}.fa-pushed{--fa:"\f3e1"}.fa-python{--fa:"\f3e2"}.fa-red-river{--fa:"\f3e3"}.fa-rendact,.fa-wpressr{--fa:"\f3e4"}.fa-replyd{--fa:"\f3e6"}.fa-resolving{--fa:"\f3e7"}.fa-rocketchat{--fa:"\f3e8"}.fa-rockrms{--fa:"\f3e9"}.fa-schlix{--fa:"\f3ea"}.fa-searchengin{--fa:"\f3eb"}.fa-servicestack{--fa:"\f3ec"}.fa-sistrix{--fa:"\f3ee"}.fa-speakap{--fa:"\f3f3"}.fa-staylinked{--fa:"\f3f5"}.fa-steam-symbol{--fa:"\f3f6"}.fa-sticker-mule{--fa:"\f3f7"}.fa-studiovinari{--fa:"\f3f8"}.fa-supple{--fa:"\f3f9"}.fa-uber{--fa:"\f402"}.fa-uikit{--fa:"\f403"}.fa-uniregistry{--fa:"\f404"}.fa-untappd{--fa:"\f405"}.fa-ussunnah{--fa:"\f407"}.fa-vaadin{--fa:"\f408"}.fa-viber{--fa:"\f409"}.fa-vimeo{--fa:"\f40a"}.fa-vnv{--fa:"\f40b"}.fa-square-whatsapp,.fa-whatsapp-square{--fa:"\f40c"}.fa-whmcs{--fa:"\f40d"}.fa-wordpress-simple{--fa:"\f411"}.fa-xbox{--fa:"\f412"}.fa-yandex{--fa:"\f413"}.fa-yandex-international{--fa:"\f414"}.fa-apple-pay{--fa:"\f415"}.fa-cc-apple-pay{--fa:"\f416"}.fa-fly{--fa:"\f417"}.fa-node{--fa:"\f419"}.fa-osi{--fa:"\f41a"}.fa-react{--fa:"\f41b"}.fa-autoprefixer{--fa:"\f41c"}.fa-less{--fa:"\f41d"}.fa-sass{--fa:"\f41e"}.fa-vuejs{--fa:"\f41f"}.fa-angular{--fa:"\f420"}.fa-aviato{--fa:"\f421"}.fa-ember{--fa:"\f423"}.fa-gitter{--fa:"\f426"}.fa-hooli{--fa:"\f427"}.fa-strava{--fa:"\f428"}.fa-stripe{--fa:"\f429"}.fa-stripe-s{--fa:"\f42a"}.fa-typo3{--fa:"\f42b"}.fa-amazon-pay{--fa:"\f42c"}.fa-cc-amazon-pay{--fa:"\f42d"}.fa-ethereum{--fa:"\f42e"}.fa-korvue{--fa:"\f42f"}.fa-elementor{--fa:"\f430"}.fa-square-youtube,.fa-youtube-square{--fa:"\f431"}.fa-flipboard{--fa:"\f44d"}.fa-hips{--fa:"\f452"}.fa-php{--fa:"\f457"}.fa-quinscape{--fa:"\f459"}.fa-readme{--fa:"\f4d5"}.fa-java{--fa:"\f4e4"}.fa-pied-piper-hat{--fa:"\f4e5"}.fa-creative-commons-by{--fa:"\f4e7"}.fa-creative-commons-nc{--fa:"\f4e8"}.fa-creative-commons-nc-eu{--fa:"\f4e9"}.fa-creative-commons-nc-jp{--fa:"\f4ea"}.fa-creative-commons-nd{--fa:"\f4eb"}.fa-creative-commons-pd{--fa:"\f4ec"}.fa-creative-commons-pd-alt{--fa:"\f4ed"}.fa-creative-commons-remix{--fa:"\f4ee"}.fa-creative-commons-sa{--fa:"\f4ef"}.fa-creative-commons-sampling{--fa:"\f4f0"}.fa-creative-commons-sampling-plus{--fa:"\f4f1"}.fa-creative-commons-share{--fa:"\f4f2"}.fa-creative-commons-zero{--fa:"\f4f3"}.fa-ebay{--fa:"\f4f4"}.fa-keybase{--fa:"\f4f5"}.fa-mastodon{--fa:"\f4f6"}.fa-r-project{--fa:"\f4f7"}.fa-researchgate{--fa:"\f4f8"}.fa-teamspeak{--fa:"\f4f9"}.fa-first-order-alt{--fa:"\f50a"}.fa-fulcrum{--fa:"\f50b"}.fa-galactic-republic{--fa:"\f50c"}.fa-galactic-senate{--fa:"\f50d"}.fa-jedi-order{--fa:"\f50e"}.fa-mandalorian{--fa:"\f50f"}.fa-old-republic{--fa:"\f510"}.fa-phoenix-squadron{--fa:"\f511"}.fa-sith{--fa:"\f512"}.fa-trade-federation{--fa:"\f513"}.fa-wolf-pack-battalion{--fa:"\f514"}.fa-hornbill{--fa:"\f592"}.fa-mailchimp{--fa:"\f59e"}.fa-megaport{--fa:"\f5a3"}.fa-nimblr{--fa:"\f5a8"}.fa-rev{--fa:"\f5b2"}.fa-shopware{--fa:"\f5b5"}.fa-squarespace{--fa:"\f5be"}.fa-themeco{--fa:"\f5c6"}.fa-weebly{--fa:"\f5cc"}.fa-wix{--fa:"\f5cf"}.fa-ello{--fa:"\f5f1"}.fa-hackerrank{--fa:"\f5f7"}.fa-kaggle{--fa:"\f5fa"}.fa-markdown{--fa:"\f60f"}.fa-neos{--fa:"\f612"}.fa-zhihu{--fa:"\f63f"}.fa-alipay{--fa:"\f642"}.fa-the-red-yeti{--fa:"\f69d"}.fa-critical-role{--fa:"\f6c9"}.fa-d-and-d-beyond{--fa:"\f6ca"}.fa-dev{--fa:"\f6cc"}.fa-fantasy-flight-games{--fa:"\f6dc"}.fa-wizards-of-the-coast{--fa:"\f730"}.fa-think-peaks{--fa:"\f731"}.fa-reacteurope{--fa:"\f75d"}.fa-artstation{--fa:"\f77a"}.fa-atlassian{--fa:"\f77b"}.fa-canadian-maple-leaf{--fa:"\f785"}.fa-centos{--fa:"\f789"}.fa-confluence{--fa:"\f78d"}.fa-dhl{--fa:"\f790"}.fa-diaspora{--fa:"\f791"}.fa-fedex{--fa:"\f797"}.fa-fedora{--fa:"\f798"}.fa-figma{--fa:"\f799"}.fa-intercom{--fa:"\f7af"}.fa-invision{--fa:"\f7b0"}.fa-jira{--fa:"\f7b1"}.fa-mendeley{--fa:"\f7b3"}.fa-raspberry-pi{--fa:"\f7bb"}.fa-redhat{--fa:"\f7bc"}.fa-sketch{--fa:"\f7c6"}.fa-sourcetree{--fa:"\f7d3"}.fa-suse{--fa:"\f7d6"}.fa-ubuntu{--fa:"\f7df"}.fa-ups{--fa:"\f7e0"}.fa-usps{--fa:"\f7e1"}.fa-yarn{--fa:"\f7e3"}.fa-airbnb{--fa:"\f834"}.fa-battle-net{--fa:"\f835"}.fa-bootstrap{--fa:"\f836"}.fa-buffer{--fa:"\f837"}.fa-chromecast{--fa:"\f838"}.fa-evernote{--fa:"\f839"}.fa-itch-io{--fa:"\f83a"}.fa-salesforce{--fa:"\f83b"}.fa-speaker-deck{--fa:"\f83c"}.fa-symfony{--fa:"\f83d"}.fa-waze{--fa:"\f83f"}.fa-yammer{--fa:"\f840"}.fa-git-alt{--fa:"\f841"}.fa-stackpath{--fa:"\f842"}.fa-cotton-bureau{--fa:"\f89e"}.fa-buy-n-large{--fa:"\f8a6"}.fa-mdb{--fa:"\f8ca"}.fa-orcid{--fa:"\f8d2"}.fa-swift{--fa:"\f8e1"}.fa-umbraco{--fa:"\f8e8"}:host,:root{--fa-font-regular:normal 400 1em/1 var(--fa-family-classic)}@font-face{font-family:"Font Awesome 7 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2)}.far{--fa-family:var(--fa-family-classic)}.fa-regular,.far{--fa-style:400}:host,:root{--fa-family-classic:"Font Awesome 7 Free";--fa-font-solid:normal 900 1em/1 var(--fa-family-classic);--fa-style-family-classic:var(--fa-family-classic)}@font-face{font-family:"Font Awesome 7 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2)}.fas{--fa-style:900}.fa-classic,.fas{--fa-family:var(--fa-family-classic)}.fa-solid{--fa-style:900}@font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a}
\ No newline at end of file
diff --git a/src/media/vendor/fa7free/css/brands.css b/src/media/vendor/fa7free/css/brands.css
new file mode 100644
index 0000000..389e32b
--- /dev/null
+++ b/src/media/vendor/fa7free/css/brands.css
@@ -0,0 +1,2219 @@
+/*!
+ * Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ * Copyright 2025 Fonticons, Inc.
+ */
+:root, :host {
+ --fa-family-brands: "Font Awesome 7 Brands";
+ --fa-font-brands: normal 400 1em/1 var(--fa-family-brands);
+}
+
+@font-face {
+ font-family: "Font Awesome 7 Brands";
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src: url("../webfonts/fa-brands-400.woff2");
+}
+.fab,
+.fa-brands,
+.fa-classic.fa-brands {
+ --fa-family: var(--fa-family-brands);
+ --fa-style: 400;
+}
+
+.fa-firefox-browser {
+ --fa: "\e007";
+}
+
+.fa-ideal {
+ --fa: "\e013";
+}
+
+.fa-microblog {
+ --fa: "\e01a";
+}
+
+.fa-square-pied-piper {
+ --fa: "\e01e";
+}
+
+.fa-pied-piper-square {
+ --fa: "\e01e";
+}
+
+.fa-unity {
+ --fa: "\e049";
+}
+
+.fa-dailymotion {
+ --fa: "\e052";
+}
+
+.fa-square-instagram {
+ --fa: "\e055";
+}
+
+.fa-instagram-square {
+ --fa: "\e055";
+}
+
+.fa-mixer {
+ --fa: "\e056";
+}
+
+.fa-shopify {
+ --fa: "\e057";
+}
+
+.fa-deezer {
+ --fa: "\e077";
+}
+
+.fa-edge-legacy {
+ --fa: "\e078";
+}
+
+.fa-google-pay {
+ --fa: "\e079";
+}
+
+.fa-rust {
+ --fa: "\e07a";
+}
+
+.fa-tiktok {
+ --fa: "\e07b";
+}
+
+.fa-unsplash {
+ --fa: "\e07c";
+}
+
+.fa-cloudflare {
+ --fa: "\e07d";
+}
+
+.fa-guilded {
+ --fa: "\e07e";
+}
+
+.fa-hive {
+ --fa: "\e07f";
+}
+
+.fa-42-group {
+ --fa: "\e080";
+}
+
+.fa-innosoft {
+ --fa: "\e080";
+}
+
+.fa-instalod {
+ --fa: "\e081";
+}
+
+.fa-octopus-deploy {
+ --fa: "\e082";
+}
+
+.fa-perbyte {
+ --fa: "\e083";
+}
+
+.fa-uncharted {
+ --fa: "\e084";
+}
+
+.fa-watchman-monitoring {
+ --fa: "\e087";
+}
+
+.fa-wodu {
+ --fa: "\e088";
+}
+
+.fa-wirsindhandwerk {
+ --fa: "\e2d0";
+}
+
+.fa-wsh {
+ --fa: "\e2d0";
+}
+
+.fa-bots {
+ --fa: "\e340";
+}
+
+.fa-cmplid {
+ --fa: "\e360";
+}
+
+.fa-bilibili {
+ --fa: "\e3d9";
+}
+
+.fa-golang {
+ --fa: "\e40f";
+}
+
+.fa-pix {
+ --fa: "\e43a";
+}
+
+.fa-sitrox {
+ --fa: "\e44a";
+}
+
+.fa-hashnode {
+ --fa: "\e499";
+}
+
+.fa-meta {
+ --fa: "\e49b";
+}
+
+.fa-padlet {
+ --fa: "\e4a0";
+}
+
+.fa-nfc-directional {
+ --fa: "\e530";
+}
+
+.fa-nfc-symbol {
+ --fa: "\e531";
+}
+
+.fa-screenpal {
+ --fa: "\e570";
+}
+
+.fa-space-awesome {
+ --fa: "\e5ac";
+}
+
+.fa-square-font-awesome {
+ --fa: "\e5ad";
+}
+
+.fa-square-gitlab {
+ --fa: "\e5ae";
+}
+
+.fa-gitlab-square {
+ --fa: "\e5ae";
+}
+
+.fa-odysee {
+ --fa: "\e5c6";
+}
+
+.fa-stubber {
+ --fa: "\e5c7";
+}
+
+.fa-debian {
+ --fa: "\e60b";
+}
+
+.fa-shoelace {
+ --fa: "\e60c";
+}
+
+.fa-threads {
+ --fa: "\e618";
+}
+
+.fa-square-threads {
+ --fa: "\e619";
+}
+
+.fa-square-x-twitter {
+ --fa: "\e61a";
+}
+
+.fa-x-twitter {
+ --fa: "\e61b";
+}
+
+.fa-opensuse {
+ --fa: "\e62b";
+}
+
+.fa-letterboxd {
+ --fa: "\e62d";
+}
+
+.fa-square-letterboxd {
+ --fa: "\e62e";
+}
+
+.fa-mintbit {
+ --fa: "\e62f";
+}
+
+.fa-google-scholar {
+ --fa: "\e63b";
+}
+
+.fa-brave {
+ --fa: "\e63c";
+}
+
+.fa-brave-reverse {
+ --fa: "\e63d";
+}
+
+.fa-pixiv {
+ --fa: "\e640";
+}
+
+.fa-upwork {
+ --fa: "\e641";
+}
+
+.fa-webflow {
+ --fa: "\e65c";
+}
+
+.fa-signal-messenger {
+ --fa: "\e663";
+}
+
+.fa-bluesky {
+ --fa: "\e671";
+}
+
+.fa-jxl {
+ --fa: "\e67b";
+}
+
+.fa-square-upwork {
+ --fa: "\e67c";
+}
+
+.fa-web-awesome {
+ --fa: "\e682";
+}
+
+.fa-square-web-awesome {
+ --fa: "\e683";
+}
+
+.fa-square-web-awesome-stroke {
+ --fa: "\e684";
+}
+
+.fa-dart-lang {
+ --fa: "\e693";
+}
+
+.fa-flutter {
+ --fa: "\e694";
+}
+
+.fa-files-pinwheel {
+ --fa: "\e69f";
+}
+
+.fa-css {
+ --fa: "\e6a2";
+}
+
+.fa-square-bluesky {
+ --fa: "\e6a3";
+}
+
+.fa-openai {
+ --fa: "\e7cf";
+}
+
+.fa-square-linkedin {
+ --fa: "\e7d0";
+}
+
+.fa-cash-app {
+ --fa: "\e7d4";
+}
+
+.fa-disqus {
+ --fa: "\e7d5";
+}
+
+.fa-eleventy {
+ --fa: "\e7d6";
+}
+
+.fa-11ty {
+ --fa: "\e7d6";
+}
+
+.fa-kakao-talk {
+ --fa: "\e7d7";
+}
+
+.fa-linktree {
+ --fa: "\e7d8";
+}
+
+.fa-notion {
+ --fa: "\e7d9";
+}
+
+.fa-pandora {
+ --fa: "\e7da";
+}
+
+.fa-pixelfed {
+ --fa: "\e7db";
+}
+
+.fa-tidal {
+ --fa: "\e7dc";
+}
+
+.fa-vsco {
+ --fa: "\e7dd";
+}
+
+.fa-w3c {
+ --fa: "\e7de";
+}
+
+.fa-lumon {
+ --fa: "\e7e2";
+}
+
+.fa-lumon-drop {
+ --fa: "\e7e3";
+}
+
+.fa-square-figma {
+ --fa: "\e7e4";
+}
+
+.fa-tex {
+ --fa: "\e7ff";
+}
+
+.fa-duolingo {
+ --fa: "\e812";
+}
+
+.fa-square-twitter {
+ --fa: "\f081";
+}
+
+.fa-twitter-square {
+ --fa: "\f081";
+}
+
+.fa-square-facebook {
+ --fa: "\f082";
+}
+
+.fa-facebook-square {
+ --fa: "\f082";
+}
+
+.fa-linkedin {
+ --fa: "\f08c";
+}
+
+.fa-square-github {
+ --fa: "\f092";
+}
+
+.fa-github-square {
+ --fa: "\f092";
+}
+
+.fa-twitter {
+ --fa: "\f099";
+}
+
+.fa-facebook {
+ --fa: "\f09a";
+}
+
+.fa-github {
+ --fa: "\f09b";
+}
+
+.fa-pinterest {
+ --fa: "\f0d2";
+}
+
+.fa-square-pinterest {
+ --fa: "\f0d3";
+}
+
+.fa-pinterest-square {
+ --fa: "\f0d3";
+}
+
+.fa-square-google-plus {
+ --fa: "\f0d4";
+}
+
+.fa-google-plus-square {
+ --fa: "\f0d4";
+}
+
+.fa-google-plus-g {
+ --fa: "\f0d5";
+}
+
+.fa-linkedin-in {
+ --fa: "\f0e1";
+}
+
+.fa-github-alt {
+ --fa: "\f113";
+}
+
+.fa-maxcdn {
+ --fa: "\f136";
+}
+
+.fa-html5 {
+ --fa: "\f13b";
+}
+
+.fa-css3 {
+ --fa: "\f13c";
+}
+
+.fa-btc {
+ --fa: "\f15a";
+}
+
+.fa-youtube {
+ --fa: "\f167";
+}
+
+.fa-xing {
+ --fa: "\f168";
+}
+
+.fa-square-xing {
+ --fa: "\f169";
+}
+
+.fa-xing-square {
+ --fa: "\f169";
+}
+
+.fa-dropbox {
+ --fa: "\f16b";
+}
+
+.fa-stack-overflow {
+ --fa: "\f16c";
+}
+
+.fa-instagram {
+ --fa: "\f16d";
+}
+
+.fa-flickr {
+ --fa: "\f16e";
+}
+
+.fa-adn {
+ --fa: "\f170";
+}
+
+.fa-bitbucket {
+ --fa: "\f171";
+}
+
+.fa-tumblr {
+ --fa: "\f173";
+}
+
+.fa-square-tumblr {
+ --fa: "\f174";
+}
+
+.fa-tumblr-square {
+ --fa: "\f174";
+}
+
+.fa-apple {
+ --fa: "\f179";
+}
+
+.fa-windows {
+ --fa: "\f17a";
+}
+
+.fa-android {
+ --fa: "\f17b";
+}
+
+.fa-linux {
+ --fa: "\f17c";
+}
+
+.fa-dribbble {
+ --fa: "\f17d";
+}
+
+.fa-skype {
+ --fa: "\f17e";
+}
+
+.fa-foursquare {
+ --fa: "\f180";
+}
+
+.fa-trello {
+ --fa: "\f181";
+}
+
+.fa-gratipay {
+ --fa: "\f184";
+}
+
+.fa-vk {
+ --fa: "\f189";
+}
+
+.fa-weibo {
+ --fa: "\f18a";
+}
+
+.fa-renren {
+ --fa: "\f18b";
+}
+
+.fa-pagelines {
+ --fa: "\f18c";
+}
+
+.fa-stack-exchange {
+ --fa: "\f18d";
+}
+
+.fa-square-vimeo {
+ --fa: "\f194";
+}
+
+.fa-vimeo-square {
+ --fa: "\f194";
+}
+
+.fa-slack {
+ --fa: "\f198";
+}
+
+.fa-slack-hash {
+ --fa: "\f198";
+}
+
+.fa-wordpress {
+ --fa: "\f19a";
+}
+
+.fa-openid {
+ --fa: "\f19b";
+}
+
+.fa-yahoo {
+ --fa: "\f19e";
+}
+
+.fa-google {
+ --fa: "\f1a0";
+}
+
+.fa-reddit {
+ --fa: "\f1a1";
+}
+
+.fa-square-reddit {
+ --fa: "\f1a2";
+}
+
+.fa-reddit-square {
+ --fa: "\f1a2";
+}
+
+.fa-stumbleupon-circle {
+ --fa: "\f1a3";
+}
+
+.fa-stumbleupon {
+ --fa: "\f1a4";
+}
+
+.fa-delicious {
+ --fa: "\f1a5";
+}
+
+.fa-digg {
+ --fa: "\f1a6";
+}
+
+.fa-pied-piper-pp {
+ --fa: "\f1a7";
+}
+
+.fa-pied-piper-alt {
+ --fa: "\f1a8";
+}
+
+.fa-drupal {
+ --fa: "\f1a9";
+}
+
+.fa-joomla {
+ --fa: "\f1aa";
+}
+
+.fa-behance {
+ --fa: "\f1b4";
+}
+
+.fa-square-behance {
+ --fa: "\f1b5";
+}
+
+.fa-behance-square {
+ --fa: "\f1b5";
+}
+
+.fa-steam {
+ --fa: "\f1b6";
+}
+
+.fa-square-steam {
+ --fa: "\f1b7";
+}
+
+.fa-steam-square {
+ --fa: "\f1b7";
+}
+
+.fa-spotify {
+ --fa: "\f1bc";
+}
+
+.fa-deviantart {
+ --fa: "\f1bd";
+}
+
+.fa-soundcloud {
+ --fa: "\f1be";
+}
+
+.fa-vine {
+ --fa: "\f1ca";
+}
+
+.fa-codepen {
+ --fa: "\f1cb";
+}
+
+.fa-jsfiddle {
+ --fa: "\f1cc";
+}
+
+.fa-rebel {
+ --fa: "\f1d0";
+}
+
+.fa-empire {
+ --fa: "\f1d1";
+}
+
+.fa-square-git {
+ --fa: "\f1d2";
+}
+
+.fa-git-square {
+ --fa: "\f1d2";
+}
+
+.fa-git {
+ --fa: "\f1d3";
+}
+
+.fa-hacker-news {
+ --fa: "\f1d4";
+}
+
+.fa-tencent-weibo {
+ --fa: "\f1d5";
+}
+
+.fa-qq {
+ --fa: "\f1d6";
+}
+
+.fa-weixin {
+ --fa: "\f1d7";
+}
+
+.fa-slideshare {
+ --fa: "\f1e7";
+}
+
+.fa-twitch {
+ --fa: "\f1e8";
+}
+
+.fa-yelp {
+ --fa: "\f1e9";
+}
+
+.fa-paypal {
+ --fa: "\f1ed";
+}
+
+.fa-google-wallet {
+ --fa: "\f1ee";
+}
+
+.fa-cc-visa {
+ --fa: "\f1f0";
+}
+
+.fa-cc-mastercard {
+ --fa: "\f1f1";
+}
+
+.fa-cc-discover {
+ --fa: "\f1f2";
+}
+
+.fa-cc-amex {
+ --fa: "\f1f3";
+}
+
+.fa-cc-paypal {
+ --fa: "\f1f4";
+}
+
+.fa-cc-stripe {
+ --fa: "\f1f5";
+}
+
+.fa-lastfm {
+ --fa: "\f202";
+}
+
+.fa-square-lastfm {
+ --fa: "\f203";
+}
+
+.fa-lastfm-square {
+ --fa: "\f203";
+}
+
+.fa-ioxhost {
+ --fa: "\f208";
+}
+
+.fa-angellist {
+ --fa: "\f209";
+}
+
+.fa-buysellads {
+ --fa: "\f20d";
+}
+
+.fa-connectdevelop {
+ --fa: "\f20e";
+}
+
+.fa-dashcube {
+ --fa: "\f210";
+}
+
+.fa-forumbee {
+ --fa: "\f211";
+}
+
+.fa-leanpub {
+ --fa: "\f212";
+}
+
+.fa-sellsy {
+ --fa: "\f213";
+}
+
+.fa-shirtsinbulk {
+ --fa: "\f214";
+}
+
+.fa-simplybuilt {
+ --fa: "\f215";
+}
+
+.fa-skyatlas {
+ --fa: "\f216";
+}
+
+.fa-pinterest-p {
+ --fa: "\f231";
+}
+
+.fa-whatsapp {
+ --fa: "\f232";
+}
+
+.fa-viacoin {
+ --fa: "\f237";
+}
+
+.fa-medium {
+ --fa: "\f23a";
+}
+
+.fa-medium-m {
+ --fa: "\f23a";
+}
+
+.fa-y-combinator {
+ --fa: "\f23b";
+}
+
+.fa-optin-monster {
+ --fa: "\f23c";
+}
+
+.fa-opencart {
+ --fa: "\f23d";
+}
+
+.fa-expeditedssl {
+ --fa: "\f23e";
+}
+
+.fa-cc-jcb {
+ --fa: "\f24b";
+}
+
+.fa-cc-diners-club {
+ --fa: "\f24c";
+}
+
+.fa-creative-commons {
+ --fa: "\f25e";
+}
+
+.fa-gg {
+ --fa: "\f260";
+}
+
+.fa-gg-circle {
+ --fa: "\f261";
+}
+
+.fa-odnoklassniki {
+ --fa: "\f263";
+}
+
+.fa-square-odnoklassniki {
+ --fa: "\f264";
+}
+
+.fa-odnoklassniki-square {
+ --fa: "\f264";
+}
+
+.fa-get-pocket {
+ --fa: "\f265";
+}
+
+.fa-wikipedia-w {
+ --fa: "\f266";
+}
+
+.fa-safari {
+ --fa: "\f267";
+}
+
+.fa-chrome {
+ --fa: "\f268";
+}
+
+.fa-firefox {
+ --fa: "\f269";
+}
+
+.fa-opera {
+ --fa: "\f26a";
+}
+
+.fa-internet-explorer {
+ --fa: "\f26b";
+}
+
+.fa-contao {
+ --fa: "\f26d";
+}
+
+.fa-500px {
+ --fa: "\f26e";
+}
+
+.fa-amazon {
+ --fa: "\f270";
+}
+
+.fa-houzz {
+ --fa: "\f27c";
+}
+
+.fa-vimeo-v {
+ --fa: "\f27d";
+}
+
+.fa-black-tie {
+ --fa: "\f27e";
+}
+
+.fa-fonticons {
+ --fa: "\f280";
+}
+
+.fa-reddit-alien {
+ --fa: "\f281";
+}
+
+.fa-edge {
+ --fa: "\f282";
+}
+
+.fa-codiepie {
+ --fa: "\f284";
+}
+
+.fa-modx {
+ --fa: "\f285";
+}
+
+.fa-fort-awesome {
+ --fa: "\f286";
+}
+
+.fa-usb {
+ --fa: "\f287";
+}
+
+.fa-product-hunt {
+ --fa: "\f288";
+}
+
+.fa-mixcloud {
+ --fa: "\f289";
+}
+
+.fa-scribd {
+ --fa: "\f28a";
+}
+
+.fa-bluetooth {
+ --fa: "\f293";
+}
+
+.fa-bluetooth-b {
+ --fa: "\f294";
+}
+
+.fa-gitlab {
+ --fa: "\f296";
+}
+
+.fa-wpbeginner {
+ --fa: "\f297";
+}
+
+.fa-wpforms {
+ --fa: "\f298";
+}
+
+.fa-envira {
+ --fa: "\f299";
+}
+
+.fa-glide {
+ --fa: "\f2a5";
+}
+
+.fa-glide-g {
+ --fa: "\f2a6";
+}
+
+.fa-viadeo {
+ --fa: "\f2a9";
+}
+
+.fa-square-viadeo {
+ --fa: "\f2aa";
+}
+
+.fa-viadeo-square {
+ --fa: "\f2aa";
+}
+
+.fa-snapchat {
+ --fa: "\f2ab";
+}
+
+.fa-snapchat-ghost {
+ --fa: "\f2ab";
+}
+
+.fa-square-snapchat {
+ --fa: "\f2ad";
+}
+
+.fa-snapchat-square {
+ --fa: "\f2ad";
+}
+
+.fa-pied-piper {
+ --fa: "\f2ae";
+}
+
+.fa-first-order {
+ --fa: "\f2b0";
+}
+
+.fa-yoast {
+ --fa: "\f2b1";
+}
+
+.fa-themeisle {
+ --fa: "\f2b2";
+}
+
+.fa-google-plus {
+ --fa: "\f2b3";
+}
+
+.fa-font-awesome {
+ --fa: "\f2b4";
+}
+
+.fa-font-awesome-flag {
+ --fa: "\f2b4";
+}
+
+.fa-font-awesome-logo-full {
+ --fa: "\f2b4";
+}
+
+.fa-linode {
+ --fa: "\f2b8";
+}
+
+.fa-quora {
+ --fa: "\f2c4";
+}
+
+.fa-free-code-camp {
+ --fa: "\f2c5";
+}
+
+.fa-telegram {
+ --fa: "\f2c6";
+}
+
+.fa-telegram-plane {
+ --fa: "\f2c6";
+}
+
+.fa-bandcamp {
+ --fa: "\f2d5";
+}
+
+.fa-grav {
+ --fa: "\f2d6";
+}
+
+.fa-etsy {
+ --fa: "\f2d7";
+}
+
+.fa-imdb {
+ --fa: "\f2d8";
+}
+
+.fa-ravelry {
+ --fa: "\f2d9";
+}
+
+.fa-sellcast {
+ --fa: "\f2da";
+}
+
+.fa-superpowers {
+ --fa: "\f2dd";
+}
+
+.fa-wpexplorer {
+ --fa: "\f2de";
+}
+
+.fa-meetup {
+ --fa: "\f2e0";
+}
+
+.fa-square-font-awesome-stroke {
+ --fa: "\f35c";
+}
+
+.fa-font-awesome-alt {
+ --fa: "\f35c";
+}
+
+.fa-accessible-icon {
+ --fa: "\f368";
+}
+
+.fa-accusoft {
+ --fa: "\f369";
+}
+
+.fa-adversal {
+ --fa: "\f36a";
+}
+
+.fa-affiliatetheme {
+ --fa: "\f36b";
+}
+
+.fa-algolia {
+ --fa: "\f36c";
+}
+
+.fa-amilia {
+ --fa: "\f36d";
+}
+
+.fa-angrycreative {
+ --fa: "\f36e";
+}
+
+.fa-app-store {
+ --fa: "\f36f";
+}
+
+.fa-app-store-ios {
+ --fa: "\f370";
+}
+
+.fa-apper {
+ --fa: "\f371";
+}
+
+.fa-asymmetrik {
+ --fa: "\f372";
+}
+
+.fa-audible {
+ --fa: "\f373";
+}
+
+.fa-avianex {
+ --fa: "\f374";
+}
+
+.fa-aws {
+ --fa: "\f375";
+}
+
+.fa-bimobject {
+ --fa: "\f378";
+}
+
+.fa-bitcoin {
+ --fa: "\f379";
+}
+
+.fa-bity {
+ --fa: "\f37a";
+}
+
+.fa-blackberry {
+ --fa: "\f37b";
+}
+
+.fa-blogger {
+ --fa: "\f37c";
+}
+
+.fa-blogger-b {
+ --fa: "\f37d";
+}
+
+.fa-buromobelexperte {
+ --fa: "\f37f";
+}
+
+.fa-centercode {
+ --fa: "\f380";
+}
+
+.fa-cloudscale {
+ --fa: "\f383";
+}
+
+.fa-cloudsmith {
+ --fa: "\f384";
+}
+
+.fa-cloudversify {
+ --fa: "\f385";
+}
+
+.fa-cpanel {
+ --fa: "\f388";
+}
+
+.fa-css3-alt {
+ --fa: "\f38b";
+}
+
+.fa-cuttlefish {
+ --fa: "\f38c";
+}
+
+.fa-d-and-d {
+ --fa: "\f38d";
+}
+
+.fa-deploydog {
+ --fa: "\f38e";
+}
+
+.fa-deskpro {
+ --fa: "\f38f";
+}
+
+.fa-digital-ocean {
+ --fa: "\f391";
+}
+
+.fa-discord {
+ --fa: "\f392";
+}
+
+.fa-discourse {
+ --fa: "\f393";
+}
+
+.fa-dochub {
+ --fa: "\f394";
+}
+
+.fa-docker {
+ --fa: "\f395";
+}
+
+.fa-draft2digital {
+ --fa: "\f396";
+}
+
+.fa-square-dribbble {
+ --fa: "\f397";
+}
+
+.fa-dribbble-square {
+ --fa: "\f397";
+}
+
+.fa-dyalog {
+ --fa: "\f399";
+}
+
+.fa-earlybirds {
+ --fa: "\f39a";
+}
+
+.fa-erlang {
+ --fa: "\f39d";
+}
+
+.fa-facebook-f {
+ --fa: "\f39e";
+}
+
+.fa-facebook-messenger {
+ --fa: "\f39f";
+}
+
+.fa-firstdraft {
+ --fa: "\f3a1";
+}
+
+.fa-fonticons-fi {
+ --fa: "\f3a2";
+}
+
+.fa-fort-awesome-alt {
+ --fa: "\f3a3";
+}
+
+.fa-freebsd {
+ --fa: "\f3a4";
+}
+
+.fa-gitkraken {
+ --fa: "\f3a6";
+}
+
+.fa-gofore {
+ --fa: "\f3a7";
+}
+
+.fa-goodreads {
+ --fa: "\f3a8";
+}
+
+.fa-goodreads-g {
+ --fa: "\f3a9";
+}
+
+.fa-google-drive {
+ --fa: "\f3aa";
+}
+
+.fa-google-play {
+ --fa: "\f3ab";
+}
+
+.fa-gripfire {
+ --fa: "\f3ac";
+}
+
+.fa-grunt {
+ --fa: "\f3ad";
+}
+
+.fa-gulp {
+ --fa: "\f3ae";
+}
+
+.fa-square-hacker-news {
+ --fa: "\f3af";
+}
+
+.fa-hacker-news-square {
+ --fa: "\f3af";
+}
+
+.fa-hire-a-helper {
+ --fa: "\f3b0";
+}
+
+.fa-hotjar {
+ --fa: "\f3b1";
+}
+
+.fa-hubspot {
+ --fa: "\f3b2";
+}
+
+.fa-itunes {
+ --fa: "\f3b4";
+}
+
+.fa-itunes-note {
+ --fa: "\f3b5";
+}
+
+.fa-jenkins {
+ --fa: "\f3b6";
+}
+
+.fa-joget {
+ --fa: "\f3b7";
+}
+
+.fa-js {
+ --fa: "\f3b8";
+}
+
+.fa-square-js {
+ --fa: "\f3b9";
+}
+
+.fa-js-square {
+ --fa: "\f3b9";
+}
+
+.fa-keycdn {
+ --fa: "\f3ba";
+}
+
+.fa-kickstarter {
+ --fa: "\f3bb";
+}
+
+.fa-square-kickstarter {
+ --fa: "\f3bb";
+}
+
+.fa-kickstarter-k {
+ --fa: "\f3bc";
+}
+
+.fa-laravel {
+ --fa: "\f3bd";
+}
+
+.fa-line {
+ --fa: "\f3c0";
+}
+
+.fa-lyft {
+ --fa: "\f3c3";
+}
+
+.fa-magento {
+ --fa: "\f3c4";
+}
+
+.fa-medapps {
+ --fa: "\f3c6";
+}
+
+.fa-medrt {
+ --fa: "\f3c8";
+}
+
+.fa-microsoft {
+ --fa: "\f3ca";
+}
+
+.fa-mix {
+ --fa: "\f3cb";
+}
+
+.fa-mizuni {
+ --fa: "\f3cc";
+}
+
+.fa-monero {
+ --fa: "\f3d0";
+}
+
+.fa-napster {
+ --fa: "\f3d2";
+}
+
+.fa-node-js {
+ --fa: "\f3d3";
+}
+
+.fa-npm {
+ --fa: "\f3d4";
+}
+
+.fa-ns8 {
+ --fa: "\f3d5";
+}
+
+.fa-nutritionix {
+ --fa: "\f3d6";
+}
+
+.fa-page4 {
+ --fa: "\f3d7";
+}
+
+.fa-palfed {
+ --fa: "\f3d8";
+}
+
+.fa-patreon {
+ --fa: "\f3d9";
+}
+
+.fa-periscope {
+ --fa: "\f3da";
+}
+
+.fa-phabricator {
+ --fa: "\f3db";
+}
+
+.fa-phoenix-framework {
+ --fa: "\f3dc";
+}
+
+.fa-playstation {
+ --fa: "\f3df";
+}
+
+.fa-pushed {
+ --fa: "\f3e1";
+}
+
+.fa-python {
+ --fa: "\f3e2";
+}
+
+.fa-red-river {
+ --fa: "\f3e3";
+}
+
+.fa-wpressr {
+ --fa: "\f3e4";
+}
+
+.fa-rendact {
+ --fa: "\f3e4";
+}
+
+.fa-replyd {
+ --fa: "\f3e6";
+}
+
+.fa-resolving {
+ --fa: "\f3e7";
+}
+
+.fa-rocketchat {
+ --fa: "\f3e8";
+}
+
+.fa-rockrms {
+ --fa: "\f3e9";
+}
+
+.fa-schlix {
+ --fa: "\f3ea";
+}
+
+.fa-searchengin {
+ --fa: "\f3eb";
+}
+
+.fa-servicestack {
+ --fa: "\f3ec";
+}
+
+.fa-sistrix {
+ --fa: "\f3ee";
+}
+
+.fa-speakap {
+ --fa: "\f3f3";
+}
+
+.fa-staylinked {
+ --fa: "\f3f5";
+}
+
+.fa-steam-symbol {
+ --fa: "\f3f6";
+}
+
+.fa-sticker-mule {
+ --fa: "\f3f7";
+}
+
+.fa-studiovinari {
+ --fa: "\f3f8";
+}
+
+.fa-supple {
+ --fa: "\f3f9";
+}
+
+.fa-uber {
+ --fa: "\f402";
+}
+
+.fa-uikit {
+ --fa: "\f403";
+}
+
+.fa-uniregistry {
+ --fa: "\f404";
+}
+
+.fa-untappd {
+ --fa: "\f405";
+}
+
+.fa-ussunnah {
+ --fa: "\f407";
+}
+
+.fa-vaadin {
+ --fa: "\f408";
+}
+
+.fa-viber {
+ --fa: "\f409";
+}
+
+.fa-vimeo {
+ --fa: "\f40a";
+}
+
+.fa-vnv {
+ --fa: "\f40b";
+}
+
+.fa-square-whatsapp {
+ --fa: "\f40c";
+}
+
+.fa-whatsapp-square {
+ --fa: "\f40c";
+}
+
+.fa-whmcs {
+ --fa: "\f40d";
+}
+
+.fa-wordpress-simple {
+ --fa: "\f411";
+}
+
+.fa-xbox {
+ --fa: "\f412";
+}
+
+.fa-yandex {
+ --fa: "\f413";
+}
+
+.fa-yandex-international {
+ --fa: "\f414";
+}
+
+.fa-apple-pay {
+ --fa: "\f415";
+}
+
+.fa-cc-apple-pay {
+ --fa: "\f416";
+}
+
+.fa-fly {
+ --fa: "\f417";
+}
+
+.fa-node {
+ --fa: "\f419";
+}
+
+.fa-osi {
+ --fa: "\f41a";
+}
+
+.fa-react {
+ --fa: "\f41b";
+}
+
+.fa-autoprefixer {
+ --fa: "\f41c";
+}
+
+.fa-less {
+ --fa: "\f41d";
+}
+
+.fa-sass {
+ --fa: "\f41e";
+}
+
+.fa-vuejs {
+ --fa: "\f41f";
+}
+
+.fa-angular {
+ --fa: "\f420";
+}
+
+.fa-aviato {
+ --fa: "\f421";
+}
+
+.fa-ember {
+ --fa: "\f423";
+}
+
+.fa-gitter {
+ --fa: "\f426";
+}
+
+.fa-hooli {
+ --fa: "\f427";
+}
+
+.fa-strava {
+ --fa: "\f428";
+}
+
+.fa-stripe {
+ --fa: "\f429";
+}
+
+.fa-stripe-s {
+ --fa: "\f42a";
+}
+
+.fa-typo3 {
+ --fa: "\f42b";
+}
+
+.fa-amazon-pay {
+ --fa: "\f42c";
+}
+
+.fa-cc-amazon-pay {
+ --fa: "\f42d";
+}
+
+.fa-ethereum {
+ --fa: "\f42e";
+}
+
+.fa-korvue {
+ --fa: "\f42f";
+}
+
+.fa-elementor {
+ --fa: "\f430";
+}
+
+.fa-square-youtube {
+ --fa: "\f431";
+}
+
+.fa-youtube-square {
+ --fa: "\f431";
+}
+
+.fa-flipboard {
+ --fa: "\f44d";
+}
+
+.fa-hips {
+ --fa: "\f452";
+}
+
+.fa-php {
+ --fa: "\f457";
+}
+
+.fa-quinscape {
+ --fa: "\f459";
+}
+
+.fa-readme {
+ --fa: "\f4d5";
+}
+
+.fa-java {
+ --fa: "\f4e4";
+}
+
+.fa-pied-piper-hat {
+ --fa: "\f4e5";
+}
+
+.fa-creative-commons-by {
+ --fa: "\f4e7";
+}
+
+.fa-creative-commons-nc {
+ --fa: "\f4e8";
+}
+
+.fa-creative-commons-nc-eu {
+ --fa: "\f4e9";
+}
+
+.fa-creative-commons-nc-jp {
+ --fa: "\f4ea";
+}
+
+.fa-creative-commons-nd {
+ --fa: "\f4eb";
+}
+
+.fa-creative-commons-pd {
+ --fa: "\f4ec";
+}
+
+.fa-creative-commons-pd-alt {
+ --fa: "\f4ed";
+}
+
+.fa-creative-commons-remix {
+ --fa: "\f4ee";
+}
+
+.fa-creative-commons-sa {
+ --fa: "\f4ef";
+}
+
+.fa-creative-commons-sampling {
+ --fa: "\f4f0";
+}
+
+.fa-creative-commons-sampling-plus {
+ --fa: "\f4f1";
+}
+
+.fa-creative-commons-share {
+ --fa: "\f4f2";
+}
+
+.fa-creative-commons-zero {
+ --fa: "\f4f3";
+}
+
+.fa-ebay {
+ --fa: "\f4f4";
+}
+
+.fa-keybase {
+ --fa: "\f4f5";
+}
+
+.fa-mastodon {
+ --fa: "\f4f6";
+}
+
+.fa-r-project {
+ --fa: "\f4f7";
+}
+
+.fa-researchgate {
+ --fa: "\f4f8";
+}
+
+.fa-teamspeak {
+ --fa: "\f4f9";
+}
+
+.fa-first-order-alt {
+ --fa: "\f50a";
+}
+
+.fa-fulcrum {
+ --fa: "\f50b";
+}
+
+.fa-galactic-republic {
+ --fa: "\f50c";
+}
+
+.fa-galactic-senate {
+ --fa: "\f50d";
+}
+
+.fa-jedi-order {
+ --fa: "\f50e";
+}
+
+.fa-mandalorian {
+ --fa: "\f50f";
+}
+
+.fa-old-republic {
+ --fa: "\f510";
+}
+
+.fa-phoenix-squadron {
+ --fa: "\f511";
+}
+
+.fa-sith {
+ --fa: "\f512";
+}
+
+.fa-trade-federation {
+ --fa: "\f513";
+}
+
+.fa-wolf-pack-battalion {
+ --fa: "\f514";
+}
+
+.fa-hornbill {
+ --fa: "\f592";
+}
+
+.fa-mailchimp {
+ --fa: "\f59e";
+}
+
+.fa-megaport {
+ --fa: "\f5a3";
+}
+
+.fa-nimblr {
+ --fa: "\f5a8";
+}
+
+.fa-rev {
+ --fa: "\f5b2";
+}
+
+.fa-shopware {
+ --fa: "\f5b5";
+}
+
+.fa-squarespace {
+ --fa: "\f5be";
+}
+
+.fa-themeco {
+ --fa: "\f5c6";
+}
+
+.fa-weebly {
+ --fa: "\f5cc";
+}
+
+.fa-wix {
+ --fa: "\f5cf";
+}
+
+.fa-ello {
+ --fa: "\f5f1";
+}
+
+.fa-hackerrank {
+ --fa: "\f5f7";
+}
+
+.fa-kaggle {
+ --fa: "\f5fa";
+}
+
+.fa-markdown {
+ --fa: "\f60f";
+}
+
+.fa-neos {
+ --fa: "\f612";
+}
+
+.fa-zhihu {
+ --fa: "\f63f";
+}
+
+.fa-alipay {
+ --fa: "\f642";
+}
+
+.fa-the-red-yeti {
+ --fa: "\f69d";
+}
+
+.fa-critical-role {
+ --fa: "\f6c9";
+}
+
+.fa-d-and-d-beyond {
+ --fa: "\f6ca";
+}
+
+.fa-dev {
+ --fa: "\f6cc";
+}
+
+.fa-fantasy-flight-games {
+ --fa: "\f6dc";
+}
+
+.fa-wizards-of-the-coast {
+ --fa: "\f730";
+}
+
+.fa-think-peaks {
+ --fa: "\f731";
+}
+
+.fa-reacteurope {
+ --fa: "\f75d";
+}
+
+.fa-artstation {
+ --fa: "\f77a";
+}
+
+.fa-atlassian {
+ --fa: "\f77b";
+}
+
+.fa-canadian-maple-leaf {
+ --fa: "\f785";
+}
+
+.fa-centos {
+ --fa: "\f789";
+}
+
+.fa-confluence {
+ --fa: "\f78d";
+}
+
+.fa-dhl {
+ --fa: "\f790";
+}
+
+.fa-diaspora {
+ --fa: "\f791";
+}
+
+.fa-fedex {
+ --fa: "\f797";
+}
+
+.fa-fedora {
+ --fa: "\f798";
+}
+
+.fa-figma {
+ --fa: "\f799";
+}
+
+.fa-intercom {
+ --fa: "\f7af";
+}
+
+.fa-invision {
+ --fa: "\f7b0";
+}
+
+.fa-jira {
+ --fa: "\f7b1";
+}
+
+.fa-mendeley {
+ --fa: "\f7b3";
+}
+
+.fa-raspberry-pi {
+ --fa: "\f7bb";
+}
+
+.fa-redhat {
+ --fa: "\f7bc";
+}
+
+.fa-sketch {
+ --fa: "\f7c6";
+}
+
+.fa-sourcetree {
+ --fa: "\f7d3";
+}
+
+.fa-suse {
+ --fa: "\f7d6";
+}
+
+.fa-ubuntu {
+ --fa: "\f7df";
+}
+
+.fa-ups {
+ --fa: "\f7e0";
+}
+
+.fa-usps {
+ --fa: "\f7e1";
+}
+
+.fa-yarn {
+ --fa: "\f7e3";
+}
+
+.fa-airbnb {
+ --fa: "\f834";
+}
+
+.fa-battle-net {
+ --fa: "\f835";
+}
+
+.fa-bootstrap {
+ --fa: "\f836";
+}
+
+.fa-buffer {
+ --fa: "\f837";
+}
+
+.fa-chromecast {
+ --fa: "\f838";
+}
+
+.fa-evernote {
+ --fa: "\f839";
+}
+
+.fa-itch-io {
+ --fa: "\f83a";
+}
+
+.fa-salesforce {
+ --fa: "\f83b";
+}
+
+.fa-speaker-deck {
+ --fa: "\f83c";
+}
+
+.fa-symfony {
+ --fa: "\f83d";
+}
+
+.fa-waze {
+ --fa: "\f83f";
+}
+
+.fa-yammer {
+ --fa: "\f840";
+}
+
+.fa-git-alt {
+ --fa: "\f841";
+}
+
+.fa-stackpath {
+ --fa: "\f842";
+}
+
+.fa-cotton-bureau {
+ --fa: "\f89e";
+}
+
+.fa-buy-n-large {
+ --fa: "\f8a6";
+}
+
+.fa-mdb {
+ --fa: "\f8ca";
+}
+
+.fa-orcid {
+ --fa: "\f8d2";
+}
+
+.fa-swift {
+ --fa: "\f8e1";
+}
+
+.fa-umbraco {
+ --fa: "\f8e8";
+}
\ No newline at end of file
diff --git a/src/media/vendor/fa7free/css/brands.min.css b/src/media/vendor/fa7free/css/brands.min.css
new file mode 100644
index 0000000..e08fcda
--- /dev/null
+++ b/src/media/vendor/fa7free/css/brands.min.css
@@ -0,0 +1,6 @@
+/*!
+ * Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ * Copyright 2025 Fonticons, Inc.
+ */
+:host,:root{--fa-family-brands:"Font Awesome 7 Brands";--fa-font-brands:normal 400 1em/1 var(--fa-family-brands)}@font-face{font-family:"Font Awesome 7 Brands";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-brands-400.woff2)}.fa-brands,.fa-classic.fa-brands,.fab{--fa-family:var(--fa-family-brands);--fa-style:400}.fa-firefox-browser{--fa:"\e007"}.fa-ideal{--fa:"\e013"}.fa-microblog{--fa:"\e01a"}.fa-pied-piper-square,.fa-square-pied-piper{--fa:"\e01e"}.fa-unity{--fa:"\e049"}.fa-dailymotion{--fa:"\e052"}.fa-instagram-square,.fa-square-instagram{--fa:"\e055"}.fa-mixer{--fa:"\e056"}.fa-shopify{--fa:"\e057"}.fa-deezer{--fa:"\e077"}.fa-edge-legacy{--fa:"\e078"}.fa-google-pay{--fa:"\e079"}.fa-rust{--fa:"\e07a"}.fa-tiktok{--fa:"\e07b"}.fa-unsplash{--fa:"\e07c"}.fa-cloudflare{--fa:"\e07d"}.fa-guilded{--fa:"\e07e"}.fa-hive{--fa:"\e07f"}.fa-42-group,.fa-innosoft{--fa:"\e080"}.fa-instalod{--fa:"\e081"}.fa-octopus-deploy{--fa:"\e082"}.fa-perbyte{--fa:"\e083"}.fa-uncharted{--fa:"\e084"}.fa-watchman-monitoring{--fa:"\e087"}.fa-wodu{--fa:"\e088"}.fa-wirsindhandwerk,.fa-wsh{--fa:"\e2d0"}.fa-bots{--fa:"\e340"}.fa-cmplid{--fa:"\e360"}.fa-bilibili{--fa:"\e3d9"}.fa-golang{--fa:"\e40f"}.fa-pix{--fa:"\e43a"}.fa-sitrox{--fa:"\e44a"}.fa-hashnode{--fa:"\e499"}.fa-meta{--fa:"\e49b"}.fa-padlet{--fa:"\e4a0"}.fa-nfc-directional{--fa:"\e530"}.fa-nfc-symbol{--fa:"\e531"}.fa-screenpal{--fa:"\e570"}.fa-space-awesome{--fa:"\e5ac"}.fa-square-font-awesome{--fa:"\e5ad"}.fa-gitlab-square,.fa-square-gitlab{--fa:"\e5ae"}.fa-odysee{--fa:"\e5c6"}.fa-stubber{--fa:"\e5c7"}.fa-debian{--fa:"\e60b"}.fa-shoelace{--fa:"\e60c"}.fa-threads{--fa:"\e618"}.fa-square-threads{--fa:"\e619"}.fa-square-x-twitter{--fa:"\e61a"}.fa-x-twitter{--fa:"\e61b"}.fa-opensuse{--fa:"\e62b"}.fa-letterboxd{--fa:"\e62d"}.fa-square-letterboxd{--fa:"\e62e"}.fa-mintbit{--fa:"\e62f"}.fa-google-scholar{--fa:"\e63b"}.fa-brave{--fa:"\e63c"}.fa-brave-reverse{--fa:"\e63d"}.fa-pixiv{--fa:"\e640"}.fa-upwork{--fa:"\e641"}.fa-webflow{--fa:"\e65c"}.fa-signal-messenger{--fa:"\e663"}.fa-bluesky{--fa:"\e671"}.fa-jxl{--fa:"\e67b"}.fa-square-upwork{--fa:"\e67c"}.fa-web-awesome{--fa:"\e682"}.fa-square-web-awesome{--fa:"\e683"}.fa-square-web-awesome-stroke{--fa:"\e684"}.fa-dart-lang{--fa:"\e693"}.fa-flutter{--fa:"\e694"}.fa-files-pinwheel{--fa:"\e69f"}.fa-css{--fa:"\e6a2"}.fa-square-bluesky{--fa:"\e6a3"}.fa-openai{--fa:"\e7cf"}.fa-square-linkedin{--fa:"\e7d0"}.fa-cash-app{--fa:"\e7d4"}.fa-disqus{--fa:"\e7d5"}.fa-11ty,.fa-eleventy{--fa:"\e7d6"}.fa-kakao-talk{--fa:"\e7d7"}.fa-linktree{--fa:"\e7d8"}.fa-notion{--fa:"\e7d9"}.fa-pandora{--fa:"\e7da"}.fa-pixelfed{--fa:"\e7db"}.fa-tidal{--fa:"\e7dc"}.fa-vsco{--fa:"\e7dd"}.fa-w3c{--fa:"\e7de"}.fa-lumon{--fa:"\e7e2"}.fa-lumon-drop{--fa:"\e7e3"}.fa-square-figma{--fa:"\e7e4"}.fa-tex{--fa:"\e7ff"}.fa-duolingo{--fa:"\e812"}.fa-square-twitter,.fa-twitter-square{--fa:"\f081"}.fa-facebook-square,.fa-square-facebook{--fa:"\f082"}.fa-linkedin{--fa:"\f08c"}.fa-github-square,.fa-square-github{--fa:"\f092"}.fa-twitter{--fa:"\f099"}.fa-facebook{--fa:"\f09a"}.fa-github{--fa:"\f09b"}.fa-pinterest{--fa:"\f0d2"}.fa-pinterest-square,.fa-square-pinterest{--fa:"\f0d3"}.fa-google-plus-square,.fa-square-google-plus{--fa:"\f0d4"}.fa-google-plus-g{--fa:"\f0d5"}.fa-linkedin-in{--fa:"\f0e1"}.fa-github-alt{--fa:"\f113"}.fa-maxcdn{--fa:"\f136"}.fa-html5{--fa:"\f13b"}.fa-css3{--fa:"\f13c"}.fa-btc{--fa:"\f15a"}.fa-youtube{--fa:"\f167"}.fa-xing{--fa:"\f168"}.fa-square-xing,.fa-xing-square{--fa:"\f169"}.fa-dropbox{--fa:"\f16b"}.fa-stack-overflow{--fa:"\f16c"}.fa-instagram{--fa:"\f16d"}.fa-flickr{--fa:"\f16e"}.fa-adn{--fa:"\f170"}.fa-bitbucket{--fa:"\f171"}.fa-tumblr{--fa:"\f173"}.fa-square-tumblr,.fa-tumblr-square{--fa:"\f174"}.fa-apple{--fa:"\f179"}.fa-windows{--fa:"\f17a"}.fa-android{--fa:"\f17b"}.fa-linux{--fa:"\f17c"}.fa-dribbble{--fa:"\f17d"}.fa-skype{--fa:"\f17e"}.fa-foursquare{--fa:"\f180"}.fa-trello{--fa:"\f181"}.fa-gratipay{--fa:"\f184"}.fa-vk{--fa:"\f189"}.fa-weibo{--fa:"\f18a"}.fa-renren{--fa:"\f18b"}.fa-pagelines{--fa:"\f18c"}.fa-stack-exchange{--fa:"\f18d"}.fa-square-vimeo,.fa-vimeo-square{--fa:"\f194"}.fa-slack,.fa-slack-hash{--fa:"\f198"}.fa-wordpress{--fa:"\f19a"}.fa-openid{--fa:"\f19b"}.fa-yahoo{--fa:"\f19e"}.fa-google{--fa:"\f1a0"}.fa-reddit{--fa:"\f1a1"}.fa-reddit-square,.fa-square-reddit{--fa:"\f1a2"}.fa-stumbleupon-circle{--fa:"\f1a3"}.fa-stumbleupon{--fa:"\f1a4"}.fa-delicious{--fa:"\f1a5"}.fa-digg{--fa:"\f1a6"}.fa-pied-piper-pp{--fa:"\f1a7"}.fa-pied-piper-alt{--fa:"\f1a8"}.fa-drupal{--fa:"\f1a9"}.fa-joomla{--fa:"\f1aa"}.fa-behance{--fa:"\f1b4"}.fa-behance-square,.fa-square-behance{--fa:"\f1b5"}.fa-steam{--fa:"\f1b6"}.fa-square-steam,.fa-steam-square{--fa:"\f1b7"}.fa-spotify{--fa:"\f1bc"}.fa-deviantart{--fa:"\f1bd"}.fa-soundcloud{--fa:"\f1be"}.fa-vine{--fa:"\f1ca"}.fa-codepen{--fa:"\f1cb"}.fa-jsfiddle{--fa:"\f1cc"}.fa-rebel{--fa:"\f1d0"}.fa-empire{--fa:"\f1d1"}.fa-git-square,.fa-square-git{--fa:"\f1d2"}.fa-git{--fa:"\f1d3"}.fa-hacker-news{--fa:"\f1d4"}.fa-tencent-weibo{--fa:"\f1d5"}.fa-qq{--fa:"\f1d6"}.fa-weixin{--fa:"\f1d7"}.fa-slideshare{--fa:"\f1e7"}.fa-twitch{--fa:"\f1e8"}.fa-yelp{--fa:"\f1e9"}.fa-paypal{--fa:"\f1ed"}.fa-google-wallet{--fa:"\f1ee"}.fa-cc-visa{--fa:"\f1f0"}.fa-cc-mastercard{--fa:"\f1f1"}.fa-cc-discover{--fa:"\f1f2"}.fa-cc-amex{--fa:"\f1f3"}.fa-cc-paypal{--fa:"\f1f4"}.fa-cc-stripe{--fa:"\f1f5"}.fa-lastfm{--fa:"\f202"}.fa-lastfm-square,.fa-square-lastfm{--fa:"\f203"}.fa-ioxhost{--fa:"\f208"}.fa-angellist{--fa:"\f209"}.fa-buysellads{--fa:"\f20d"}.fa-connectdevelop{--fa:"\f20e"}.fa-dashcube{--fa:"\f210"}.fa-forumbee{--fa:"\f211"}.fa-leanpub{--fa:"\f212"}.fa-sellsy{--fa:"\f213"}.fa-shirtsinbulk{--fa:"\f214"}.fa-simplybuilt{--fa:"\f215"}.fa-skyatlas{--fa:"\f216"}.fa-pinterest-p{--fa:"\f231"}.fa-whatsapp{--fa:"\f232"}.fa-viacoin{--fa:"\f237"}.fa-medium,.fa-medium-m{--fa:"\f23a"}.fa-y-combinator{--fa:"\f23b"}.fa-optin-monster{--fa:"\f23c"}.fa-opencart{--fa:"\f23d"}.fa-expeditedssl{--fa:"\f23e"}.fa-cc-jcb{--fa:"\f24b"}.fa-cc-diners-club{--fa:"\f24c"}.fa-creative-commons{--fa:"\f25e"}.fa-gg{--fa:"\f260"}.fa-gg-circle{--fa:"\f261"}.fa-odnoklassniki{--fa:"\f263"}.fa-odnoklassniki-square,.fa-square-odnoklassniki{--fa:"\f264"}.fa-get-pocket{--fa:"\f265"}.fa-wikipedia-w{--fa:"\f266"}.fa-safari{--fa:"\f267"}.fa-chrome{--fa:"\f268"}.fa-firefox{--fa:"\f269"}.fa-opera{--fa:"\f26a"}.fa-internet-explorer{--fa:"\f26b"}.fa-contao{--fa:"\f26d"}.fa-500px{--fa:"\f26e"}.fa-amazon{--fa:"\f270"}.fa-houzz{--fa:"\f27c"}.fa-vimeo-v{--fa:"\f27d"}.fa-black-tie{--fa:"\f27e"}.fa-fonticons{--fa:"\f280"}.fa-reddit-alien{--fa:"\f281"}.fa-edge{--fa:"\f282"}.fa-codiepie{--fa:"\f284"}.fa-modx{--fa:"\f285"}.fa-fort-awesome{--fa:"\f286"}.fa-usb{--fa:"\f287"}.fa-product-hunt{--fa:"\f288"}.fa-mixcloud{--fa:"\f289"}.fa-scribd{--fa:"\f28a"}.fa-bluetooth{--fa:"\f293"}.fa-bluetooth-b{--fa:"\f294"}.fa-gitlab{--fa:"\f296"}.fa-wpbeginner{--fa:"\f297"}.fa-wpforms{--fa:"\f298"}.fa-envira{--fa:"\f299"}.fa-glide{--fa:"\f2a5"}.fa-glide-g{--fa:"\f2a6"}.fa-viadeo{--fa:"\f2a9"}.fa-square-viadeo,.fa-viadeo-square{--fa:"\f2aa"}.fa-snapchat,.fa-snapchat-ghost{--fa:"\f2ab"}.fa-snapchat-square,.fa-square-snapchat{--fa:"\f2ad"}.fa-pied-piper{--fa:"\f2ae"}.fa-first-order{--fa:"\f2b0"}.fa-yoast{--fa:"\f2b1"}.fa-themeisle{--fa:"\f2b2"}.fa-google-plus{--fa:"\f2b3"}.fa-font-awesome,.fa-font-awesome-flag,.fa-font-awesome-logo-full{--fa:"\f2b4"}.fa-linode{--fa:"\f2b8"}.fa-quora{--fa:"\f2c4"}.fa-free-code-camp{--fa:"\f2c5"}.fa-telegram,.fa-telegram-plane{--fa:"\f2c6"}.fa-bandcamp{--fa:"\f2d5"}.fa-grav{--fa:"\f2d6"}.fa-etsy{--fa:"\f2d7"}.fa-imdb{--fa:"\f2d8"}.fa-ravelry{--fa:"\f2d9"}.fa-sellcast{--fa:"\f2da"}.fa-superpowers{--fa:"\f2dd"}.fa-wpexplorer{--fa:"\f2de"}.fa-meetup{--fa:"\f2e0"}.fa-font-awesome-alt,.fa-square-font-awesome-stroke{--fa:"\f35c"}.fa-accessible-icon{--fa:"\f368"}.fa-accusoft{--fa:"\f369"}.fa-adversal{--fa:"\f36a"}.fa-affiliatetheme{--fa:"\f36b"}.fa-algolia{--fa:"\f36c"}.fa-amilia{--fa:"\f36d"}.fa-angrycreative{--fa:"\f36e"}.fa-app-store{--fa:"\f36f"}.fa-app-store-ios{--fa:"\f370"}.fa-apper{--fa:"\f371"}.fa-asymmetrik{--fa:"\f372"}.fa-audible{--fa:"\f373"}.fa-avianex{--fa:"\f374"}.fa-aws{--fa:"\f375"}.fa-bimobject{--fa:"\f378"}.fa-bitcoin{--fa:"\f379"}.fa-bity{--fa:"\f37a"}.fa-blackberry{--fa:"\f37b"}.fa-blogger{--fa:"\f37c"}.fa-blogger-b{--fa:"\f37d"}.fa-buromobelexperte{--fa:"\f37f"}.fa-centercode{--fa:"\f380"}.fa-cloudscale{--fa:"\f383"}.fa-cloudsmith{--fa:"\f384"}.fa-cloudversify{--fa:"\f385"}.fa-cpanel{--fa:"\f388"}.fa-css3-alt{--fa:"\f38b"}.fa-cuttlefish{--fa:"\f38c"}.fa-d-and-d{--fa:"\f38d"}.fa-deploydog{--fa:"\f38e"}.fa-deskpro{--fa:"\f38f"}.fa-digital-ocean{--fa:"\f391"}.fa-discord{--fa:"\f392"}.fa-discourse{--fa:"\f393"}.fa-dochub{--fa:"\f394"}.fa-docker{--fa:"\f395"}.fa-draft2digital{--fa:"\f396"}.fa-dribbble-square,.fa-square-dribbble{--fa:"\f397"}.fa-dyalog{--fa:"\f399"}.fa-earlybirds{--fa:"\f39a"}.fa-erlang{--fa:"\f39d"}.fa-facebook-f{--fa:"\f39e"}.fa-facebook-messenger{--fa:"\f39f"}.fa-firstdraft{--fa:"\f3a1"}.fa-fonticons-fi{--fa:"\f3a2"}.fa-fort-awesome-alt{--fa:"\f3a3"}.fa-freebsd{--fa:"\f3a4"}.fa-gitkraken{--fa:"\f3a6"}.fa-gofore{--fa:"\f3a7"}.fa-goodreads{--fa:"\f3a8"}.fa-goodreads-g{--fa:"\f3a9"}.fa-google-drive{--fa:"\f3aa"}.fa-google-play{--fa:"\f3ab"}.fa-gripfire{--fa:"\f3ac"}.fa-grunt{--fa:"\f3ad"}.fa-gulp{--fa:"\f3ae"}.fa-hacker-news-square,.fa-square-hacker-news{--fa:"\f3af"}.fa-hire-a-helper{--fa:"\f3b0"}.fa-hotjar{--fa:"\f3b1"}.fa-hubspot{--fa:"\f3b2"}.fa-itunes{--fa:"\f3b4"}.fa-itunes-note{--fa:"\f3b5"}.fa-jenkins{--fa:"\f3b6"}.fa-joget{--fa:"\f3b7"}.fa-js{--fa:"\f3b8"}.fa-js-square,.fa-square-js{--fa:"\f3b9"}.fa-keycdn{--fa:"\f3ba"}.fa-kickstarter,.fa-square-kickstarter{--fa:"\f3bb"}.fa-kickstarter-k{--fa:"\f3bc"}.fa-laravel{--fa:"\f3bd"}.fa-line{--fa:"\f3c0"}.fa-lyft{--fa:"\f3c3"}.fa-magento{--fa:"\f3c4"}.fa-medapps{--fa:"\f3c6"}.fa-medrt{--fa:"\f3c8"}.fa-microsoft{--fa:"\f3ca"}.fa-mix{--fa:"\f3cb"}.fa-mizuni{--fa:"\f3cc"}.fa-monero{--fa:"\f3d0"}.fa-napster{--fa:"\f3d2"}.fa-node-js{--fa:"\f3d3"}.fa-npm{--fa:"\f3d4"}.fa-ns8{--fa:"\f3d5"}.fa-nutritionix{--fa:"\f3d6"}.fa-page4{--fa:"\f3d7"}.fa-palfed{--fa:"\f3d8"}.fa-patreon{--fa:"\f3d9"}.fa-periscope{--fa:"\f3da"}.fa-phabricator{--fa:"\f3db"}.fa-phoenix-framework{--fa:"\f3dc"}.fa-playstation{--fa:"\f3df"}.fa-pushed{--fa:"\f3e1"}.fa-python{--fa:"\f3e2"}.fa-red-river{--fa:"\f3e3"}.fa-rendact,.fa-wpressr{--fa:"\f3e4"}.fa-replyd{--fa:"\f3e6"}.fa-resolving{--fa:"\f3e7"}.fa-rocketchat{--fa:"\f3e8"}.fa-rockrms{--fa:"\f3e9"}.fa-schlix{--fa:"\f3ea"}.fa-searchengin{--fa:"\f3eb"}.fa-servicestack{--fa:"\f3ec"}.fa-sistrix{--fa:"\f3ee"}.fa-speakap{--fa:"\f3f3"}.fa-staylinked{--fa:"\f3f5"}.fa-steam-symbol{--fa:"\f3f6"}.fa-sticker-mule{--fa:"\f3f7"}.fa-studiovinari{--fa:"\f3f8"}.fa-supple{--fa:"\f3f9"}.fa-uber{--fa:"\f402"}.fa-uikit{--fa:"\f403"}.fa-uniregistry{--fa:"\f404"}.fa-untappd{--fa:"\f405"}.fa-ussunnah{--fa:"\f407"}.fa-vaadin{--fa:"\f408"}.fa-viber{--fa:"\f409"}.fa-vimeo{--fa:"\f40a"}.fa-vnv{--fa:"\f40b"}.fa-square-whatsapp,.fa-whatsapp-square{--fa:"\f40c"}.fa-whmcs{--fa:"\f40d"}.fa-wordpress-simple{--fa:"\f411"}.fa-xbox{--fa:"\f412"}.fa-yandex{--fa:"\f413"}.fa-yandex-international{--fa:"\f414"}.fa-apple-pay{--fa:"\f415"}.fa-cc-apple-pay{--fa:"\f416"}.fa-fly{--fa:"\f417"}.fa-node{--fa:"\f419"}.fa-osi{--fa:"\f41a"}.fa-react{--fa:"\f41b"}.fa-autoprefixer{--fa:"\f41c"}.fa-less{--fa:"\f41d"}.fa-sass{--fa:"\f41e"}.fa-vuejs{--fa:"\f41f"}.fa-angular{--fa:"\f420"}.fa-aviato{--fa:"\f421"}.fa-ember{--fa:"\f423"}.fa-gitter{--fa:"\f426"}.fa-hooli{--fa:"\f427"}.fa-strava{--fa:"\f428"}.fa-stripe{--fa:"\f429"}.fa-stripe-s{--fa:"\f42a"}.fa-typo3{--fa:"\f42b"}.fa-amazon-pay{--fa:"\f42c"}.fa-cc-amazon-pay{--fa:"\f42d"}.fa-ethereum{--fa:"\f42e"}.fa-korvue{--fa:"\f42f"}.fa-elementor{--fa:"\f430"}.fa-square-youtube,.fa-youtube-square{--fa:"\f431"}.fa-flipboard{--fa:"\f44d"}.fa-hips{--fa:"\f452"}.fa-php{--fa:"\f457"}.fa-quinscape{--fa:"\f459"}.fa-readme{--fa:"\f4d5"}.fa-java{--fa:"\f4e4"}.fa-pied-piper-hat{--fa:"\f4e5"}.fa-creative-commons-by{--fa:"\f4e7"}.fa-creative-commons-nc{--fa:"\f4e8"}.fa-creative-commons-nc-eu{--fa:"\f4e9"}.fa-creative-commons-nc-jp{--fa:"\f4ea"}.fa-creative-commons-nd{--fa:"\f4eb"}.fa-creative-commons-pd{--fa:"\f4ec"}.fa-creative-commons-pd-alt{--fa:"\f4ed"}.fa-creative-commons-remix{--fa:"\f4ee"}.fa-creative-commons-sa{--fa:"\f4ef"}.fa-creative-commons-sampling{--fa:"\f4f0"}.fa-creative-commons-sampling-plus{--fa:"\f4f1"}.fa-creative-commons-share{--fa:"\f4f2"}.fa-creative-commons-zero{--fa:"\f4f3"}.fa-ebay{--fa:"\f4f4"}.fa-keybase{--fa:"\f4f5"}.fa-mastodon{--fa:"\f4f6"}.fa-r-project{--fa:"\f4f7"}.fa-researchgate{--fa:"\f4f8"}.fa-teamspeak{--fa:"\f4f9"}.fa-first-order-alt{--fa:"\f50a"}.fa-fulcrum{--fa:"\f50b"}.fa-galactic-republic{--fa:"\f50c"}.fa-galactic-senate{--fa:"\f50d"}.fa-jedi-order{--fa:"\f50e"}.fa-mandalorian{--fa:"\f50f"}.fa-old-republic{--fa:"\f510"}.fa-phoenix-squadron{--fa:"\f511"}.fa-sith{--fa:"\f512"}.fa-trade-federation{--fa:"\f513"}.fa-wolf-pack-battalion{--fa:"\f514"}.fa-hornbill{--fa:"\f592"}.fa-mailchimp{--fa:"\f59e"}.fa-megaport{--fa:"\f5a3"}.fa-nimblr{--fa:"\f5a8"}.fa-rev{--fa:"\f5b2"}.fa-shopware{--fa:"\f5b5"}.fa-squarespace{--fa:"\f5be"}.fa-themeco{--fa:"\f5c6"}.fa-weebly{--fa:"\f5cc"}.fa-wix{--fa:"\f5cf"}.fa-ello{--fa:"\f5f1"}.fa-hackerrank{--fa:"\f5f7"}.fa-kaggle{--fa:"\f5fa"}.fa-markdown{--fa:"\f60f"}.fa-neos{--fa:"\f612"}.fa-zhihu{--fa:"\f63f"}.fa-alipay{--fa:"\f642"}.fa-the-red-yeti{--fa:"\f69d"}.fa-critical-role{--fa:"\f6c9"}.fa-d-and-d-beyond{--fa:"\f6ca"}.fa-dev{--fa:"\f6cc"}.fa-fantasy-flight-games{--fa:"\f6dc"}.fa-wizards-of-the-coast{--fa:"\f730"}.fa-think-peaks{--fa:"\f731"}.fa-reacteurope{--fa:"\f75d"}.fa-artstation{--fa:"\f77a"}.fa-atlassian{--fa:"\f77b"}.fa-canadian-maple-leaf{--fa:"\f785"}.fa-centos{--fa:"\f789"}.fa-confluence{--fa:"\f78d"}.fa-dhl{--fa:"\f790"}.fa-diaspora{--fa:"\f791"}.fa-fedex{--fa:"\f797"}.fa-fedora{--fa:"\f798"}.fa-figma{--fa:"\f799"}.fa-intercom{--fa:"\f7af"}.fa-invision{--fa:"\f7b0"}.fa-jira{--fa:"\f7b1"}.fa-mendeley{--fa:"\f7b3"}.fa-raspberry-pi{--fa:"\f7bb"}.fa-redhat{--fa:"\f7bc"}.fa-sketch{--fa:"\f7c6"}.fa-sourcetree{--fa:"\f7d3"}.fa-suse{--fa:"\f7d6"}.fa-ubuntu{--fa:"\f7df"}.fa-ups{--fa:"\f7e0"}.fa-usps{--fa:"\f7e1"}.fa-yarn{--fa:"\f7e3"}.fa-airbnb{--fa:"\f834"}.fa-battle-net{--fa:"\f835"}.fa-bootstrap{--fa:"\f836"}.fa-buffer{--fa:"\f837"}.fa-chromecast{--fa:"\f838"}.fa-evernote{--fa:"\f839"}.fa-itch-io{--fa:"\f83a"}.fa-salesforce{--fa:"\f83b"}.fa-speaker-deck{--fa:"\f83c"}.fa-symfony{--fa:"\f83d"}.fa-waze{--fa:"\f83f"}.fa-yammer{--fa:"\f840"}.fa-git-alt{--fa:"\f841"}.fa-stackpath{--fa:"\f842"}.fa-cotton-bureau{--fa:"\f89e"}.fa-buy-n-large{--fa:"\f8a6"}.fa-mdb{--fa:"\f8ca"}.fa-orcid{--fa:"\f8d2"}.fa-swift{--fa:"\f8e1"}.fa-umbraco{--fa:"\f8e8"}
\ No newline at end of file
diff --git a/src/media/vendor/fa7free/css/fontawesome.css b/src/media/vendor/fa7free/css/fontawesome.css
new file mode 100644
index 0000000..9e736b5
--- /dev/null
+++ b/src/media/vendor/fa7free/css/fontawesome.css
@@ -0,0 +1,8361 @@
+/*!
+ * Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ * Copyright 2025 Fonticons, Inc.
+ */
+.fa-solid,
+.fa-regular,
+.fa-brands,
+.fa-classic,
+.fas,
+.far,
+.fab,
+.fa {
+ --_fa-family: var(--fa-family, var(--fa-style-family, "Font Awesome 7 Free"));
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ display: var(--fa-display, inline-block);
+ font-family: var(--_fa-family);
+ font-feature-settings: normal;
+ font-style: normal;
+ font-synthesis: none;
+ font-variant: normal;
+ font-weight: var(--fa-style, 900);
+ line-height: 1;
+ text-align: center;
+ text-rendering: auto;
+ width: var(--fa-width, 1.25em);
+}
+
+:is(.fas,
+.far,
+.fab,
+.fa-solid,
+.fa-regular,
+.fa-brands,
+.fa-classic,
+.fa)::before {
+ content: var(--fa)/"";
+}
+
+@supports not (content: ""/"") {
+ :is(.fas,
+ .far,
+ .fab,
+ .fa-solid,
+ .fa-regular,
+ .fa-brands,
+ .fa-classic,
+ .fa)::before {
+ content: var(--fa);
+ }
+}
+.fa-1x {
+ font-size: 1em;
+}
+
+.fa-2x {
+ font-size: 2em;
+}
+
+.fa-3x {
+ font-size: 3em;
+}
+
+.fa-4x {
+ font-size: 4em;
+}
+
+.fa-5x {
+ font-size: 5em;
+}
+
+.fa-6x {
+ font-size: 6em;
+}
+
+.fa-7x {
+ font-size: 7em;
+}
+
+.fa-8x {
+ font-size: 8em;
+}
+
+.fa-9x {
+ font-size: 9em;
+}
+
+.fa-10x {
+ font-size: 10em;
+}
+
+.fa-2xs {
+ font-size: calc(10 / 16 * 1em); /* converts a 10px size into an em-based value that's relative to the scale's 16px base */
+ line-height: calc(1 / 10 * 1em); /* sets the line-height of the icon back to that of it's parent */
+ vertical-align: calc((6 / 10 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
+}
+
+.fa-xs {
+ font-size: calc(12 / 16 * 1em); /* converts a 12px size into an em-based value that's relative to the scale's 16px base */
+ line-height: calc(1 / 12 * 1em); /* sets the line-height of the icon back to that of it's parent */
+ vertical-align: calc((6 / 12 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
+}
+
+.fa-sm {
+ font-size: calc(14 / 16 * 1em); /* converts a 14px size into an em-based value that's relative to the scale's 16px base */
+ line-height: calc(1 / 14 * 1em); /* sets the line-height of the icon back to that of it's parent */
+ vertical-align: calc((6 / 14 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
+}
+
+.fa-lg {
+ font-size: calc(20 / 16 * 1em); /* converts a 20px size into an em-based value that's relative to the scale's 16px base */
+ line-height: calc(1 / 20 * 1em); /* sets the line-height of the icon back to that of it's parent */
+ vertical-align: calc((6 / 20 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
+}
+
+.fa-xl {
+ font-size: calc(24 / 16 * 1em); /* converts a 24px size into an em-based value that's relative to the scale's 16px base */
+ line-height: calc(1 / 24 * 1em); /* sets the line-height of the icon back to that of it's parent */
+ vertical-align: calc((6 / 24 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
+}
+
+.fa-2xl {
+ font-size: calc(32 / 16 * 1em); /* converts a 32px size into an em-based value that's relative to the scale's 16px base */
+ line-height: calc(1 / 32 * 1em); /* sets the line-height of the icon back to that of it's parent */
+ vertical-align: calc((6 / 32 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
+}
+
+.fa-width-auto {
+ --fa-width: auto;
+}
+
+.fa-fw,
+.fa-width-fixed {
+ --fa-width: 1.25em;
+}
+
+.fa-ul {
+ list-style-type: none;
+ margin-inline-start: var(--fa-li-margin, 2.5em);
+ padding-inline-start: 0;
+}
+.fa-ul > li {
+ position: relative;
+}
+
+.fa-li {
+ inset-inline-start: calc(-1 * var(--fa-li-width, 2em));
+ position: absolute;
+ text-align: center;
+ width: var(--fa-li-width, 2em);
+ line-height: inherit;
+}
+
+/* Heads Up: Bordered Icons will not be supported in the future!
+ - This feature will be deprecated in the next major release of Font Awesome (v8)!
+ - You may continue to use it in this version *v7), but it will not be supported in Font Awesome v8.
+*/
+/* Notes:
+* --@{v.$css-prefix}-border-width = 1/16 by default (to render as ~1px based on a 16px default font-size)
+* --@{v.$css-prefix}-border-padding =
+ ** 3/16 for vertical padding (to give ~2px of vertical whitespace around an icon considering it's vertical alignment)
+ ** 4/16 for horizontal padding (to give ~4px of horizontal whitespace around an icon)
+*/
+.fa-border {
+ border-color: var(--fa-border-color, #eee);
+ border-radius: var(--fa-border-radius, 0.1em);
+ border-style: var(--fa-border-style, solid);
+ border-width: var(--fa-border-width, 0.0625em);
+ box-sizing: var(--fa-border-box-sizing, content-box);
+ padding: var(--fa-border-padding, 0.1875em 0.25em);
+}
+
+.fa-pull-left,
+.fa-pull-start {
+ float: inline-start;
+ margin-inline-end: var(--fa-pull-margin, 0.3em);
+}
+
+.fa-pull-right,
+.fa-pull-end {
+ float: inline-end;
+ margin-inline-start: var(--fa-pull-margin, 0.3em);
+}
+
+.fa-beat {
+ animation-name: fa-beat;
+ animation-delay: var(--fa-animation-delay, 0s);
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 1s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, ease-in-out);
+}
+
+.fa-bounce {
+ animation-name: fa-bounce;
+ animation-delay: var(--fa-animation-delay, 0s);
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 1s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1));
+}
+
+.fa-fade {
+ animation-name: fa-fade;
+ animation-delay: var(--fa-animation-delay, 0s);
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 1s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));
+}
+
+.fa-beat-fade {
+ animation-name: fa-beat-fade;
+ animation-delay: var(--fa-animation-delay, 0s);
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 1s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));
+}
+
+.fa-flip {
+ animation-name: fa-flip;
+ animation-delay: var(--fa-animation-delay, 0s);
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 1s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, ease-in-out);
+}
+
+.fa-shake {
+ animation-name: fa-shake;
+ animation-delay: var(--fa-animation-delay, 0s);
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 1s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, linear);
+}
+
+.fa-spin {
+ animation-name: fa-spin;
+ animation-delay: var(--fa-animation-delay, 0s);
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 2s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, linear);
+}
+
+.fa-spin-reverse {
+ --fa-animation-direction: reverse;
+}
+
+.fa-pulse,
+.fa-spin-pulse {
+ animation-name: fa-spin;
+ animation-direction: var(--fa-animation-direction, normal);
+ animation-duration: var(--fa-animation-duration, 1s);
+ animation-iteration-count: var(--fa-animation-iteration-count, infinite);
+ animation-timing-function: var(--fa-animation-timing, steps(8));
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .fa-beat,
+ .fa-bounce,
+ .fa-fade,
+ .fa-beat-fade,
+ .fa-flip,
+ .fa-pulse,
+ .fa-shake,
+ .fa-spin,
+ .fa-spin-pulse {
+ animation: none !important;
+ transition: none !important;
+ }
+}
+@keyframes fa-beat {
+ 0%, 90% {
+ transform: scale(1);
+ }
+ 45% {
+ transform: scale(var(--fa-beat-scale, 1.25));
+ }
+}
+@keyframes fa-bounce {
+ 0% {
+ transform: scale(1, 1) translateY(0);
+ }
+ 10% {
+ transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);
+ }
+ 30% {
+ transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));
+ }
+ 50% {
+ transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);
+ }
+ 57% {
+ transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));
+ }
+ 64% {
+ transform: scale(1, 1) translateY(0);
+ }
+ 100% {
+ transform: scale(1, 1) translateY(0);
+ }
+}
+@keyframes fa-fade {
+ 50% {
+ opacity: var(--fa-fade-opacity, 0.4);
+ }
+}
+@keyframes fa-beat-fade {
+ 0%, 100% {
+ opacity: var(--fa-beat-fade-opacity, 0.4);
+ transform: scale(1);
+ }
+ 50% {
+ opacity: 1;
+ transform: scale(var(--fa-beat-fade-scale, 1.125));
+ }
+}
+@keyframes fa-flip {
+ 50% {
+ transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));
+ }
+}
+@keyframes fa-shake {
+ 0% {
+ transform: rotate(-15deg);
+ }
+ 4% {
+ transform: rotate(15deg);
+ }
+ 8%, 24% {
+ transform: rotate(-18deg);
+ }
+ 12%, 28% {
+ transform: rotate(18deg);
+ }
+ 16% {
+ transform: rotate(-22deg);
+ }
+ 20% {
+ transform: rotate(22deg);
+ }
+ 32% {
+ transform: rotate(-12deg);
+ }
+ 36% {
+ transform: rotate(12deg);
+ }
+ 40%, 100% {
+ transform: rotate(0deg);
+ }
+}
+@keyframes fa-spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+.fa-rotate-90 {
+ transform: rotate(90deg);
+}
+
+.fa-rotate-180 {
+ transform: rotate(180deg);
+}
+
+.fa-rotate-270 {
+ transform: rotate(270deg);
+}
+
+.fa-flip-horizontal {
+ transform: scale(-1, 1);
+}
+
+.fa-flip-vertical {
+ transform: scale(1, -1);
+}
+
+.fa-flip-both,
+.fa-flip-horizontal.fa-flip-vertical {
+ transform: scale(-1, -1);
+}
+
+.fa-rotate-by {
+ transform: rotate(var(--fa-rotate-angle, 0));
+}
+
+.fa-stack {
+ display: inline-block;
+ height: 2em;
+ line-height: 2em;
+ position: relative;
+ vertical-align: middle;
+ width: 2.5em;
+}
+
+.fa-stack-1x,
+.fa-stack-2x {
+ --fa-width: 100%;
+ inset: 0;
+ position: absolute;
+ text-align: center;
+ width: var(--fa-width);
+ z-index: var(--fa-stack-z-index, auto);
+}
+
+.fa-stack-1x {
+ line-height: inherit;
+}
+
+.fa-stack-2x {
+ font-size: 2em;
+}
+
+.fa-inverse {
+ color: var(--fa-inverse, #fff);
+}
+
+/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
+ readers do not read off random characters that represent icons */
+
+.fa-0 {
+ --fa: "\30 ";
+}
+
+.fa-1 {
+ --fa: "\31 ";
+}
+
+.fa-2 {
+ --fa: "\32 ";
+}
+
+.fa-3 {
+ --fa: "\33 ";
+}
+
+.fa-4 {
+ --fa: "\34 ";
+}
+
+.fa-5 {
+ --fa: "\35 ";
+}
+
+.fa-6 {
+ --fa: "\36 ";
+}
+
+.fa-7 {
+ --fa: "\37 ";
+}
+
+.fa-8 {
+ --fa: "\38 ";
+}
+
+.fa-9 {
+ --fa: "\39 ";
+}
+
+.fa-exclamation {
+ --fa: "\!";
+}
+
+.fa-hashtag {
+ --fa: "\#";
+}
+
+.fa-dollar-sign {
+ --fa: "\$";
+}
+
+.fa-dollar {
+ --fa: "\$";
+}
+
+.fa-usd {
+ --fa: "\$";
+}
+
+.fa-percent {
+ --fa: "\%";
+}
+
+.fa-percentage {
+ --fa: "\%";
+}
+
+.fa-asterisk {
+ --fa: "\*";
+}
+
+.fa-plus {
+ --fa: "\+";
+}
+
+.fa-add {
+ --fa: "\+";
+}
+
+.fa-less-than {
+ --fa: "\<";
+}
+
+.fa-equals {
+ --fa: "\=";
+}
+
+.fa-greater-than {
+ --fa: "\>";
+}
+
+.fa-question {
+ --fa: "\?";
+}
+
+.fa-at {
+ --fa: "\@";
+}
+
+.fa-a {
+ --fa: "A";
+}
+
+.fa-b {
+ --fa: "B";
+}
+
+.fa-c {
+ --fa: "C";
+}
+
+.fa-d {
+ --fa: "D";
+}
+
+.fa-e {
+ --fa: "E";
+}
+
+.fa-f {
+ --fa: "F";
+}
+
+.fa-g {
+ --fa: "G";
+}
+
+.fa-h {
+ --fa: "H";
+}
+
+.fa-i {
+ --fa: "I";
+}
+
+.fa-j {
+ --fa: "J";
+}
+
+.fa-k {
+ --fa: "K";
+}
+
+.fa-l {
+ --fa: "L";
+}
+
+.fa-m {
+ --fa: "M";
+}
+
+.fa-n {
+ --fa: "N";
+}
+
+.fa-o {
+ --fa: "O";
+}
+
+.fa-p {
+ --fa: "P";
+}
+
+.fa-q {
+ --fa: "Q";
+}
+
+.fa-r {
+ --fa: "R";
+}
+
+.fa-s {
+ --fa: "S";
+}
+
+.fa-t {
+ --fa: "T";
+}
+
+.fa-u {
+ --fa: "U";
+}
+
+.fa-v {
+ --fa: "V";
+}
+
+.fa-w {
+ --fa: "W";
+}
+
+.fa-x {
+ --fa: "X";
+}
+
+.fa-y {
+ --fa: "Y";
+}
+
+.fa-z {
+ --fa: "Z";
+}
+
+.fa-faucet {
+ --fa: "\e005";
+}
+
+.fa-faucet-drip {
+ --fa: "\e006";
+}
+
+.fa-house-chimney-window {
+ --fa: "\e00d";
+}
+
+.fa-house-signal {
+ --fa: "\e012";
+}
+
+.fa-temperature-arrow-down {
+ --fa: "\e03f";
+}
+
+.fa-temperature-down {
+ --fa: "\e03f";
+}
+
+.fa-temperature-arrow-up {
+ --fa: "\e040";
+}
+
+.fa-temperature-up {
+ --fa: "\e040";
+}
+
+.fa-trailer {
+ --fa: "\e041";
+}
+
+.fa-bacteria {
+ --fa: "\e059";
+}
+
+.fa-bacterium {
+ --fa: "\e05a";
+}
+
+.fa-box-tissue {
+ --fa: "\e05b";
+}
+
+.fa-hand-holding-medical {
+ --fa: "\e05c";
+}
+
+.fa-hand-sparkles {
+ --fa: "\e05d";
+}
+
+.fa-hands-bubbles {
+ --fa: "\e05e";
+}
+
+.fa-hands-wash {
+ --fa: "\e05e";
+}
+
+.fa-handshake-slash {
+ --fa: "\e060";
+}
+
+.fa-handshake-alt-slash {
+ --fa: "\e060";
+}
+
+.fa-handshake-simple-slash {
+ --fa: "\e060";
+}
+
+.fa-head-side-cough {
+ --fa: "\e061";
+}
+
+.fa-head-side-cough-slash {
+ --fa: "\e062";
+}
+
+.fa-head-side-mask {
+ --fa: "\e063";
+}
+
+.fa-head-side-virus {
+ --fa: "\e064";
+}
+
+.fa-house-chimney-user {
+ --fa: "\e065";
+}
+
+.fa-house-laptop {
+ --fa: "\e066";
+}
+
+.fa-laptop-house {
+ --fa: "\e066";
+}
+
+.fa-lungs-virus {
+ --fa: "\e067";
+}
+
+.fa-people-arrows {
+ --fa: "\e068";
+}
+
+.fa-people-arrows-left-right {
+ --fa: "\e068";
+}
+
+.fa-plane-slash {
+ --fa: "\e069";
+}
+
+.fa-pump-medical {
+ --fa: "\e06a";
+}
+
+.fa-pump-soap {
+ --fa: "\e06b";
+}
+
+.fa-shield-virus {
+ --fa: "\e06c";
+}
+
+.fa-sink {
+ --fa: "\e06d";
+}
+
+.fa-soap {
+ --fa: "\e06e";
+}
+
+.fa-stopwatch-20 {
+ --fa: "\e06f";
+}
+
+.fa-shop-slash {
+ --fa: "\e070";
+}
+
+.fa-store-alt-slash {
+ --fa: "\e070";
+}
+
+.fa-store-slash {
+ --fa: "\e071";
+}
+
+.fa-toilet-paper-slash {
+ --fa: "\e072";
+}
+
+.fa-users-slash {
+ --fa: "\e073";
+}
+
+.fa-virus {
+ --fa: "\e074";
+}
+
+.fa-virus-slash {
+ --fa: "\e075";
+}
+
+.fa-viruses {
+ --fa: "\e076";
+}
+
+.fa-vest {
+ --fa: "\e085";
+}
+
+.fa-vest-patches {
+ --fa: "\e086";
+}
+
+.fa-arrow-trend-down {
+ --fa: "\e097";
+}
+
+.fa-arrow-trend-up {
+ --fa: "\e098";
+}
+
+.fa-arrow-up-from-bracket {
+ --fa: "\e09a";
+}
+
+.fa-austral-sign {
+ --fa: "\e0a9";
+}
+
+.fa-baht-sign {
+ --fa: "\e0ac";
+}
+
+.fa-bitcoin-sign {
+ --fa: "\e0b4";
+}
+
+.fa-bolt-lightning {
+ --fa: "\e0b7";
+}
+
+.fa-book-bookmark {
+ --fa: "\e0bb";
+}
+
+.fa-camera-rotate {
+ --fa: "\e0d8";
+}
+
+.fa-cedi-sign {
+ --fa: "\e0df";
+}
+
+.fa-chart-column {
+ --fa: "\e0e3";
+}
+
+.fa-chart-gantt {
+ --fa: "\e0e4";
+}
+
+.fa-clapperboard {
+ --fa: "\e131";
+}
+
+.fa-clover {
+ --fa: "\e139";
+}
+
+.fa-code-compare {
+ --fa: "\e13a";
+}
+
+.fa-code-fork {
+ --fa: "\e13b";
+}
+
+.fa-code-pull-request {
+ --fa: "\e13c";
+}
+
+.fa-colon-sign {
+ --fa: "\e140";
+}
+
+.fa-cruzeiro-sign {
+ --fa: "\e152";
+}
+
+.fa-display {
+ --fa: "\e163";
+}
+
+.fa-dong-sign {
+ --fa: "\e169";
+}
+
+.fa-elevator {
+ --fa: "\e16d";
+}
+
+.fa-filter-circle-xmark {
+ --fa: "\e17b";
+}
+
+.fa-florin-sign {
+ --fa: "\e184";
+}
+
+.fa-folder-closed {
+ --fa: "\e185";
+}
+
+.fa-franc-sign {
+ --fa: "\e18f";
+}
+
+.fa-guarani-sign {
+ --fa: "\e19a";
+}
+
+.fa-gun {
+ --fa: "\e19b";
+}
+
+.fa-hands-clapping {
+ --fa: "\e1a8";
+}
+
+.fa-house-user {
+ --fa: "\e1b0";
+}
+
+.fa-home-user {
+ --fa: "\e1b0";
+}
+
+.fa-indian-rupee-sign {
+ --fa: "\e1bc";
+}
+
+.fa-indian-rupee {
+ --fa: "\e1bc";
+}
+
+.fa-inr {
+ --fa: "\e1bc";
+}
+
+.fa-kip-sign {
+ --fa: "\e1c4";
+}
+
+.fa-lari-sign {
+ --fa: "\e1c8";
+}
+
+.fa-litecoin-sign {
+ --fa: "\e1d3";
+}
+
+.fa-manat-sign {
+ --fa: "\e1d5";
+}
+
+.fa-mask-face {
+ --fa: "\e1d7";
+}
+
+.fa-mill-sign {
+ --fa: "\e1ed";
+}
+
+.fa-money-bills {
+ --fa: "\e1f3";
+}
+
+.fa-naira-sign {
+ --fa: "\e1f6";
+}
+
+.fa-notdef {
+ --fa: "\e1fe";
+}
+
+.fa-panorama {
+ --fa: "\e209";
+}
+
+.fa-peseta-sign {
+ --fa: "\e221";
+}
+
+.fa-peso-sign {
+ --fa: "\e222";
+}
+
+.fa-plane-up {
+ --fa: "\e22d";
+}
+
+.fa-rupiah-sign {
+ --fa: "\e23d";
+}
+
+.fa-stairs {
+ --fa: "\e289";
+}
+
+.fa-timeline {
+ --fa: "\e29c";
+}
+
+.fa-truck-front {
+ --fa: "\e2b7";
+}
+
+.fa-turkish-lira-sign {
+ --fa: "\e2bb";
+}
+
+.fa-try {
+ --fa: "\e2bb";
+}
+
+.fa-turkish-lira {
+ --fa: "\e2bb";
+}
+
+.fa-vault {
+ --fa: "\e2c5";
+}
+
+.fa-wand-magic-sparkles {
+ --fa: "\e2ca";
+}
+
+.fa-magic-wand-sparkles {
+ --fa: "\e2ca";
+}
+
+.fa-wheat-awn {
+ --fa: "\e2cd";
+}
+
+.fa-wheat-alt {
+ --fa: "\e2cd";
+}
+
+.fa-wheelchair-move {
+ --fa: "\e2ce";
+}
+
+.fa-wheelchair-alt {
+ --fa: "\e2ce";
+}
+
+.fa-bangladeshi-taka-sign {
+ --fa: "\e2e6";
+}
+
+.fa-bowl-rice {
+ --fa: "\e2eb";
+}
+
+.fa-person-pregnant {
+ --fa: "\e31e";
+}
+
+.fa-house-chimney {
+ --fa: "\e3af";
+}
+
+.fa-home-lg {
+ --fa: "\e3af";
+}
+
+.fa-house-crack {
+ --fa: "\e3b1";
+}
+
+.fa-house-medical {
+ --fa: "\e3b2";
+}
+
+.fa-cent-sign {
+ --fa: "\e3f5";
+}
+
+.fa-plus-minus {
+ --fa: "\e43c";
+}
+
+.fa-sailboat {
+ --fa: "\e445";
+}
+
+.fa-section {
+ --fa: "\e447";
+}
+
+.fa-shrimp {
+ --fa: "\e448";
+}
+
+.fa-brazilian-real-sign {
+ --fa: "\e46c";
+}
+
+.fa-chart-simple {
+ --fa: "\e473";
+}
+
+.fa-diagram-next {
+ --fa: "\e476";
+}
+
+.fa-diagram-predecessor {
+ --fa: "\e477";
+}
+
+.fa-diagram-successor {
+ --fa: "\e47a";
+}
+
+.fa-earth-oceania {
+ --fa: "\e47b";
+}
+
+.fa-globe-oceania {
+ --fa: "\e47b";
+}
+
+.fa-bug-slash {
+ --fa: "\e490";
+}
+
+.fa-file-circle-plus {
+ --fa: "\e494";
+}
+
+.fa-shop-lock {
+ --fa: "\e4a5";
+}
+
+.fa-virus-covid {
+ --fa: "\e4a8";
+}
+
+.fa-virus-covid-slash {
+ --fa: "\e4a9";
+}
+
+.fa-anchor-circle-check {
+ --fa: "\e4aa";
+}
+
+.fa-anchor-circle-exclamation {
+ --fa: "\e4ab";
+}
+
+.fa-anchor-circle-xmark {
+ --fa: "\e4ac";
+}
+
+.fa-anchor-lock {
+ --fa: "\e4ad";
+}
+
+.fa-arrow-down-up-across-line {
+ --fa: "\e4af";
+}
+
+.fa-arrow-down-up-lock {
+ --fa: "\e4b0";
+}
+
+.fa-arrow-right-to-city {
+ --fa: "\e4b3";
+}
+
+.fa-arrow-up-from-ground-water {
+ --fa: "\e4b5";
+}
+
+.fa-arrow-up-from-water-pump {
+ --fa: "\e4b6";
+}
+
+.fa-arrow-up-right-dots {
+ --fa: "\e4b7";
+}
+
+.fa-arrows-down-to-line {
+ --fa: "\e4b8";
+}
+
+.fa-arrows-down-to-people {
+ --fa: "\e4b9";
+}
+
+.fa-arrows-left-right-to-line {
+ --fa: "\e4ba";
+}
+
+.fa-arrows-spin {
+ --fa: "\e4bb";
+}
+
+.fa-arrows-split-up-and-left {
+ --fa: "\e4bc";
+}
+
+.fa-arrows-to-circle {
+ --fa: "\e4bd";
+}
+
+.fa-arrows-to-dot {
+ --fa: "\e4be";
+}
+
+.fa-arrows-to-eye {
+ --fa: "\e4bf";
+}
+
+.fa-arrows-turn-right {
+ --fa: "\e4c0";
+}
+
+.fa-arrows-turn-to-dots {
+ --fa: "\e4c1";
+}
+
+.fa-arrows-up-to-line {
+ --fa: "\e4c2";
+}
+
+.fa-bore-hole {
+ --fa: "\e4c3";
+}
+
+.fa-bottle-droplet {
+ --fa: "\e4c4";
+}
+
+.fa-bottle-water {
+ --fa: "\e4c5";
+}
+
+.fa-bowl-food {
+ --fa: "\e4c6";
+}
+
+.fa-boxes-packing {
+ --fa: "\e4c7";
+}
+
+.fa-bridge {
+ --fa: "\e4c8";
+}
+
+.fa-bridge-circle-check {
+ --fa: "\e4c9";
+}
+
+.fa-bridge-circle-exclamation {
+ --fa: "\e4ca";
+}
+
+.fa-bridge-circle-xmark {
+ --fa: "\e4cb";
+}
+
+.fa-bridge-lock {
+ --fa: "\e4cc";
+}
+
+.fa-bridge-water {
+ --fa: "\e4ce";
+}
+
+.fa-bucket {
+ --fa: "\e4cf";
+}
+
+.fa-bugs {
+ --fa: "\e4d0";
+}
+
+.fa-building-circle-arrow-right {
+ --fa: "\e4d1";
+}
+
+.fa-building-circle-check {
+ --fa: "\e4d2";
+}
+
+.fa-building-circle-exclamation {
+ --fa: "\e4d3";
+}
+
+.fa-building-circle-xmark {
+ --fa: "\e4d4";
+}
+
+.fa-building-flag {
+ --fa: "\e4d5";
+}
+
+.fa-building-lock {
+ --fa: "\e4d6";
+}
+
+.fa-building-ngo {
+ --fa: "\e4d7";
+}
+
+.fa-building-shield {
+ --fa: "\e4d8";
+}
+
+.fa-building-un {
+ --fa: "\e4d9";
+}
+
+.fa-building-user {
+ --fa: "\e4da";
+}
+
+.fa-building-wheat {
+ --fa: "\e4db";
+}
+
+.fa-burst {
+ --fa: "\e4dc";
+}
+
+.fa-car-on {
+ --fa: "\e4dd";
+}
+
+.fa-car-tunnel {
+ --fa: "\e4de";
+}
+
+.fa-child-combatant {
+ --fa: "\e4e0";
+}
+
+.fa-child-rifle {
+ --fa: "\e4e0";
+}
+
+.fa-children {
+ --fa: "\e4e1";
+}
+
+.fa-circle-nodes {
+ --fa: "\e4e2";
+}
+
+.fa-clipboard-question {
+ --fa: "\e4e3";
+}
+
+.fa-cloud-showers-water {
+ --fa: "\e4e4";
+}
+
+.fa-computer {
+ --fa: "\e4e5";
+}
+
+.fa-cubes-stacked {
+ --fa: "\e4e6";
+}
+
+.fa-envelope-circle-check {
+ --fa: "\e4e8";
+}
+
+.fa-explosion {
+ --fa: "\e4e9";
+}
+
+.fa-ferry {
+ --fa: "\e4ea";
+}
+
+.fa-file-circle-exclamation {
+ --fa: "\e4eb";
+}
+
+.fa-file-circle-minus {
+ --fa: "\e4ed";
+}
+
+.fa-file-circle-question {
+ --fa: "\e4ef";
+}
+
+.fa-file-shield {
+ --fa: "\e4f0";
+}
+
+.fa-fire-burner {
+ --fa: "\e4f1";
+}
+
+.fa-fish-fins {
+ --fa: "\e4f2";
+}
+
+.fa-flask-vial {
+ --fa: "\e4f3";
+}
+
+.fa-glass-water {
+ --fa: "\e4f4";
+}
+
+.fa-glass-water-droplet {
+ --fa: "\e4f5";
+}
+
+.fa-group-arrows-rotate {
+ --fa: "\e4f6";
+}
+
+.fa-hand-holding-hand {
+ --fa: "\e4f7";
+}
+
+.fa-handcuffs {
+ --fa: "\e4f8";
+}
+
+.fa-hands-bound {
+ --fa: "\e4f9";
+}
+
+.fa-hands-holding-child {
+ --fa: "\e4fa";
+}
+
+.fa-hands-holding-circle {
+ --fa: "\e4fb";
+}
+
+.fa-heart-circle-bolt {
+ --fa: "\e4fc";
+}
+
+.fa-heart-circle-check {
+ --fa: "\e4fd";
+}
+
+.fa-heart-circle-exclamation {
+ --fa: "\e4fe";
+}
+
+.fa-heart-circle-minus {
+ --fa: "\e4ff";
+}
+
+.fa-heart-circle-plus {
+ --fa: "\e500";
+}
+
+.fa-heart-circle-xmark {
+ --fa: "\e501";
+}
+
+.fa-helicopter-symbol {
+ --fa: "\e502";
+}
+
+.fa-helmet-un {
+ --fa: "\e503";
+}
+
+.fa-hill-avalanche {
+ --fa: "\e507";
+}
+
+.fa-hill-rockslide {
+ --fa: "\e508";
+}
+
+.fa-house-circle-check {
+ --fa: "\e509";
+}
+
+.fa-house-circle-exclamation {
+ --fa: "\e50a";
+}
+
+.fa-house-circle-xmark {
+ --fa: "\e50b";
+}
+
+.fa-house-fire {
+ --fa: "\e50c";
+}
+
+.fa-house-flag {
+ --fa: "\e50d";
+}
+
+.fa-house-flood-water {
+ --fa: "\e50e";
+}
+
+.fa-house-flood-water-circle-arrow-right {
+ --fa: "\e50f";
+}
+
+.fa-house-lock {
+ --fa: "\e510";
+}
+
+.fa-house-medical-circle-check {
+ --fa: "\e511";
+}
+
+.fa-house-medical-circle-exclamation {
+ --fa: "\e512";
+}
+
+.fa-house-medical-circle-xmark {
+ --fa: "\e513";
+}
+
+.fa-house-medical-flag {
+ --fa: "\e514";
+}
+
+.fa-house-tsunami {
+ --fa: "\e515";
+}
+
+.fa-jar {
+ --fa: "\e516";
+}
+
+.fa-jar-wheat {
+ --fa: "\e517";
+}
+
+.fa-jet-fighter-up {
+ --fa: "\e518";
+}
+
+.fa-jug-detergent {
+ --fa: "\e519";
+}
+
+.fa-kitchen-set {
+ --fa: "\e51a";
+}
+
+.fa-land-mine-on {
+ --fa: "\e51b";
+}
+
+.fa-landmark-flag {
+ --fa: "\e51c";
+}
+
+.fa-laptop-file {
+ --fa: "\e51d";
+}
+
+.fa-lines-leaning {
+ --fa: "\e51e";
+}
+
+.fa-location-pin-lock {
+ --fa: "\e51f";
+}
+
+.fa-locust {
+ --fa: "\e520";
+}
+
+.fa-magnifying-glass-arrow-right {
+ --fa: "\e521";
+}
+
+.fa-magnifying-glass-chart {
+ --fa: "\e522";
+}
+
+.fa-mars-and-venus-burst {
+ --fa: "\e523";
+}
+
+.fa-mask-ventilator {
+ --fa: "\e524";
+}
+
+.fa-mattress-pillow {
+ --fa: "\e525";
+}
+
+.fa-mobile-retro {
+ --fa: "\e527";
+}
+
+.fa-money-bill-transfer {
+ --fa: "\e528";
+}
+
+.fa-money-bill-trend-up {
+ --fa: "\e529";
+}
+
+.fa-money-bill-wheat {
+ --fa: "\e52a";
+}
+
+.fa-mosquito {
+ --fa: "\e52b";
+}
+
+.fa-mosquito-net {
+ --fa: "\e52c";
+}
+
+.fa-mound {
+ --fa: "\e52d";
+}
+
+.fa-mountain-city {
+ --fa: "\e52e";
+}
+
+.fa-mountain-sun {
+ --fa: "\e52f";
+}
+
+.fa-oil-well {
+ --fa: "\e532";
+}
+
+.fa-people-group {
+ --fa: "\e533";
+}
+
+.fa-people-line {
+ --fa: "\e534";
+}
+
+.fa-people-pulling {
+ --fa: "\e535";
+}
+
+.fa-people-robbery {
+ --fa: "\e536";
+}
+
+.fa-people-roof {
+ --fa: "\e537";
+}
+
+.fa-person-arrow-down-to-line {
+ --fa: "\e538";
+}
+
+.fa-person-arrow-up-from-line {
+ --fa: "\e539";
+}
+
+.fa-person-breastfeeding {
+ --fa: "\e53a";
+}
+
+.fa-person-burst {
+ --fa: "\e53b";
+}
+
+.fa-person-cane {
+ --fa: "\e53c";
+}
+
+.fa-person-chalkboard {
+ --fa: "\e53d";
+}
+
+.fa-person-circle-check {
+ --fa: "\e53e";
+}
+
+.fa-person-circle-exclamation {
+ --fa: "\e53f";
+}
+
+.fa-person-circle-minus {
+ --fa: "\e540";
+}
+
+.fa-person-circle-plus {
+ --fa: "\e541";
+}
+
+.fa-person-circle-question {
+ --fa: "\e542";
+}
+
+.fa-person-circle-xmark {
+ --fa: "\e543";
+}
+
+.fa-person-dress-burst {
+ --fa: "\e544";
+}
+
+.fa-person-drowning {
+ --fa: "\e545";
+}
+
+.fa-person-falling {
+ --fa: "\e546";
+}
+
+.fa-person-falling-burst {
+ --fa: "\e547";
+}
+
+.fa-person-half-dress {
+ --fa: "\e548";
+}
+
+.fa-person-harassing {
+ --fa: "\e549";
+}
+
+.fa-person-military-pointing {
+ --fa: "\e54a";
+}
+
+.fa-person-military-rifle {
+ --fa: "\e54b";
+}
+
+.fa-person-military-to-person {
+ --fa: "\e54c";
+}
+
+.fa-person-rays {
+ --fa: "\e54d";
+}
+
+.fa-person-rifle {
+ --fa: "\e54e";
+}
+
+.fa-person-shelter {
+ --fa: "\e54f";
+}
+
+.fa-person-walking-arrow-loop-left {
+ --fa: "\e551";
+}
+
+.fa-person-walking-arrow-right {
+ --fa: "\e552";
+}
+
+.fa-person-walking-dashed-line-arrow-right {
+ --fa: "\e553";
+}
+
+.fa-person-walking-luggage {
+ --fa: "\e554";
+}
+
+.fa-plane-circle-check {
+ --fa: "\e555";
+}
+
+.fa-plane-circle-exclamation {
+ --fa: "\e556";
+}
+
+.fa-plane-circle-xmark {
+ --fa: "\e557";
+}
+
+.fa-plane-lock {
+ --fa: "\e558";
+}
+
+.fa-plate-wheat {
+ --fa: "\e55a";
+}
+
+.fa-plug-circle-bolt {
+ --fa: "\e55b";
+}
+
+.fa-plug-circle-check {
+ --fa: "\e55c";
+}
+
+.fa-plug-circle-exclamation {
+ --fa: "\e55d";
+}
+
+.fa-plug-circle-minus {
+ --fa: "\e55e";
+}
+
+.fa-plug-circle-plus {
+ --fa: "\e55f";
+}
+
+.fa-plug-circle-xmark {
+ --fa: "\e560";
+}
+
+.fa-ranking-star {
+ --fa: "\e561";
+}
+
+.fa-road-barrier {
+ --fa: "\e562";
+}
+
+.fa-road-bridge {
+ --fa: "\e563";
+}
+
+.fa-road-circle-check {
+ --fa: "\e564";
+}
+
+.fa-road-circle-exclamation {
+ --fa: "\e565";
+}
+
+.fa-road-circle-xmark {
+ --fa: "\e566";
+}
+
+.fa-road-lock {
+ --fa: "\e567";
+}
+
+.fa-road-spikes {
+ --fa: "\e568";
+}
+
+.fa-rug {
+ --fa: "\e569";
+}
+
+.fa-sack-xmark {
+ --fa: "\e56a";
+}
+
+.fa-school-circle-check {
+ --fa: "\e56b";
+}
+
+.fa-school-circle-exclamation {
+ --fa: "\e56c";
+}
+
+.fa-school-circle-xmark {
+ --fa: "\e56d";
+}
+
+.fa-school-flag {
+ --fa: "\e56e";
+}
+
+.fa-school-lock {
+ --fa: "\e56f";
+}
+
+.fa-sheet-plastic {
+ --fa: "\e571";
+}
+
+.fa-shield-cat {
+ --fa: "\e572";
+}
+
+.fa-shield-dog {
+ --fa: "\e573";
+}
+
+.fa-shield-heart {
+ --fa: "\e574";
+}
+
+.fa-square-nfi {
+ --fa: "\e576";
+}
+
+.fa-square-person-confined {
+ --fa: "\e577";
+}
+
+.fa-square-virus {
+ --fa: "\e578";
+}
+
+.fa-staff-snake {
+ --fa: "\e579";
+}
+
+.fa-rod-asclepius {
+ --fa: "\e579";
+}
+
+.fa-rod-snake {
+ --fa: "\e579";
+}
+
+.fa-staff-aesculapius {
+ --fa: "\e579";
+}
+
+.fa-sun-plant-wilt {
+ --fa: "\e57a";
+}
+
+.fa-tarp {
+ --fa: "\e57b";
+}
+
+.fa-tarp-droplet {
+ --fa: "\e57c";
+}
+
+.fa-tent {
+ --fa: "\e57d";
+}
+
+.fa-tent-arrow-down-to-line {
+ --fa: "\e57e";
+}
+
+.fa-tent-arrow-left-right {
+ --fa: "\e57f";
+}
+
+.fa-tent-arrow-turn-left {
+ --fa: "\e580";
+}
+
+.fa-tent-arrows-down {
+ --fa: "\e581";
+}
+
+.fa-tents {
+ --fa: "\e582";
+}
+
+.fa-toilet-portable {
+ --fa: "\e583";
+}
+
+.fa-toilets-portable {
+ --fa: "\e584";
+}
+
+.fa-tower-cell {
+ --fa: "\e585";
+}
+
+.fa-tower-observation {
+ --fa: "\e586";
+}
+
+.fa-tree-city {
+ --fa: "\e587";
+}
+
+.fa-trowel {
+ --fa: "\e589";
+}
+
+.fa-trowel-bricks {
+ --fa: "\e58a";
+}
+
+.fa-truck-arrow-right {
+ --fa: "\e58b";
+}
+
+.fa-truck-droplet {
+ --fa: "\e58c";
+}
+
+.fa-truck-field {
+ --fa: "\e58d";
+}
+
+.fa-truck-field-un {
+ --fa: "\e58e";
+}
+
+.fa-truck-plane {
+ --fa: "\e58f";
+}
+
+.fa-users-between-lines {
+ --fa: "\e591";
+}
+
+.fa-users-line {
+ --fa: "\e592";
+}
+
+.fa-users-rays {
+ --fa: "\e593";
+}
+
+.fa-users-rectangle {
+ --fa: "\e594";
+}
+
+.fa-users-viewfinder {
+ --fa: "\e595";
+}
+
+.fa-vial-circle-check {
+ --fa: "\e596";
+}
+
+.fa-vial-virus {
+ --fa: "\e597";
+}
+
+.fa-wheat-awn-circle-exclamation {
+ --fa: "\e598";
+}
+
+.fa-worm {
+ --fa: "\e599";
+}
+
+.fa-xmarks-lines {
+ --fa: "\e59a";
+}
+
+.fa-child-dress {
+ --fa: "\e59c";
+}
+
+.fa-child-reaching {
+ --fa: "\e59d";
+}
+
+.fa-file-circle-check {
+ --fa: "\e5a0";
+}
+
+.fa-file-circle-xmark {
+ --fa: "\e5a1";
+}
+
+.fa-person-through-window {
+ --fa: "\e5a9";
+}
+
+.fa-plant-wilt {
+ --fa: "\e5aa";
+}
+
+.fa-stapler {
+ --fa: "\e5af";
+}
+
+.fa-train-tram {
+ --fa: "\e5b4";
+}
+
+.fa-table-cells-column-lock {
+ --fa: "\e678";
+}
+
+.fa-table-cells-row-lock {
+ --fa: "\e67a";
+}
+
+.fa-web-awesome {
+ --fa: "\e682";
+}
+
+.fa-thumbtack-slash {
+ --fa: "\e68f";
+}
+
+.fa-thumb-tack-slash {
+ --fa: "\e68f";
+}
+
+.fa-table-cells-row-unlock {
+ --fa: "\e691";
+}
+
+.fa-chart-diagram {
+ --fa: "\e695";
+}
+
+.fa-comment-nodes {
+ --fa: "\e696";
+}
+
+.fa-file-fragment {
+ --fa: "\e697";
+}
+
+.fa-file-half-dashed {
+ --fa: "\e698";
+}
+
+.fa-hexagon-nodes {
+ --fa: "\e699";
+}
+
+.fa-hexagon-nodes-bolt {
+ --fa: "\e69a";
+}
+
+.fa-square-binary {
+ --fa: "\e69b";
+}
+
+.fa-pentagon {
+ --fa: "\e790";
+}
+
+.fa-non-binary {
+ --fa: "\e807";
+}
+
+.fa-spiral {
+ --fa: "\e80a";
+}
+
+.fa-mobile-vibrate {
+ --fa: "\e816";
+}
+
+.fa-single-quote-left {
+ --fa: "\e81b";
+}
+
+.fa-single-quote-right {
+ --fa: "\e81c";
+}
+
+.fa-bus-side {
+ --fa: "\e81d";
+}
+
+.fa-septagon {
+ --fa: "\e820";
+}
+
+.fa-heptagon {
+ --fa: "\e820";
+}
+
+.fa-martini-glass-empty {
+ --fa: "\f000";
+}
+
+.fa-glass-martini {
+ --fa: "\f000";
+}
+
+.fa-music {
+ --fa: "\f001";
+}
+
+.fa-magnifying-glass {
+ --fa: "\f002";
+}
+
+.fa-search {
+ --fa: "\f002";
+}
+
+.fa-heart {
+ --fa: "\f004";
+}
+
+.fa-star {
+ --fa: "\f005";
+}
+
+.fa-user {
+ --fa: "\f007";
+}
+
+.fa-user-alt {
+ --fa: "\f007";
+}
+
+.fa-user-large {
+ --fa: "\f007";
+}
+
+.fa-film {
+ --fa: "\f008";
+}
+
+.fa-film-alt {
+ --fa: "\f008";
+}
+
+.fa-film-simple {
+ --fa: "\f008";
+}
+
+.fa-table-cells-large {
+ --fa: "\f009";
+}
+
+.fa-th-large {
+ --fa: "\f009";
+}
+
+.fa-table-cells {
+ --fa: "\f00a";
+}
+
+.fa-th {
+ --fa: "\f00a";
+}
+
+.fa-table-list {
+ --fa: "\f00b";
+}
+
+.fa-th-list {
+ --fa: "\f00b";
+}
+
+.fa-check {
+ --fa: "\f00c";
+}
+
+.fa-xmark {
+ --fa: "\f00d";
+}
+
+.fa-close {
+ --fa: "\f00d";
+}
+
+.fa-multiply {
+ --fa: "\f00d";
+}
+
+.fa-remove {
+ --fa: "\f00d";
+}
+
+.fa-times {
+ --fa: "\f00d";
+}
+
+.fa-magnifying-glass-plus {
+ --fa: "\f00e";
+}
+
+.fa-search-plus {
+ --fa: "\f00e";
+}
+
+.fa-magnifying-glass-minus {
+ --fa: "\f010";
+}
+
+.fa-search-minus {
+ --fa: "\f010";
+}
+
+.fa-power-off {
+ --fa: "\f011";
+}
+
+.fa-signal {
+ --fa: "\f012";
+}
+
+.fa-signal-5 {
+ --fa: "\f012";
+}
+
+.fa-signal-perfect {
+ --fa: "\f012";
+}
+
+.fa-gear {
+ --fa: "\f013";
+}
+
+.fa-cog {
+ --fa: "\f013";
+}
+
+.fa-house {
+ --fa: "\f015";
+}
+
+.fa-home {
+ --fa: "\f015";
+}
+
+.fa-home-alt {
+ --fa: "\f015";
+}
+
+.fa-home-lg-alt {
+ --fa: "\f015";
+}
+
+.fa-clock {
+ --fa: "\f017";
+}
+
+.fa-clock-four {
+ --fa: "\f017";
+}
+
+.fa-road {
+ --fa: "\f018";
+}
+
+.fa-download {
+ --fa: "\f019";
+}
+
+.fa-inbox {
+ --fa: "\f01c";
+}
+
+.fa-arrow-rotate-right {
+ --fa: "\f01e";
+}
+
+.fa-arrow-right-rotate {
+ --fa: "\f01e";
+}
+
+.fa-arrow-rotate-forward {
+ --fa: "\f01e";
+}
+
+.fa-redo {
+ --fa: "\f01e";
+}
+
+.fa-arrows-rotate {
+ --fa: "\f021";
+}
+
+.fa-refresh {
+ --fa: "\f021";
+}
+
+.fa-sync {
+ --fa: "\f021";
+}
+
+.fa-rectangle-list {
+ --fa: "\f022";
+}
+
+.fa-list-alt {
+ --fa: "\f022";
+}
+
+.fa-lock {
+ --fa: "\f023";
+}
+
+.fa-flag {
+ --fa: "\f024";
+}
+
+.fa-headphones {
+ --fa: "\f025";
+}
+
+.fa-headphones-alt {
+ --fa: "\f025";
+}
+
+.fa-headphones-simple {
+ --fa: "\f025";
+}
+
+.fa-volume-off {
+ --fa: "\f026";
+}
+
+.fa-volume-low {
+ --fa: "\f027";
+}
+
+.fa-volume-down {
+ --fa: "\f027";
+}
+
+.fa-volume-high {
+ --fa: "\f028";
+}
+
+.fa-volume-up {
+ --fa: "\f028";
+}
+
+.fa-qrcode {
+ --fa: "\f029";
+}
+
+.fa-barcode {
+ --fa: "\f02a";
+}
+
+.fa-tag {
+ --fa: "\f02b";
+}
+
+.fa-tags {
+ --fa: "\f02c";
+}
+
+.fa-book {
+ --fa: "\f02d";
+}
+
+.fa-bookmark {
+ --fa: "\f02e";
+}
+
+.fa-print {
+ --fa: "\f02f";
+}
+
+.fa-camera {
+ --fa: "\f030";
+}
+
+.fa-camera-alt {
+ --fa: "\f030";
+}
+
+.fa-font {
+ --fa: "\f031";
+}
+
+.fa-bold {
+ --fa: "\f032";
+}
+
+.fa-italic {
+ --fa: "\f033";
+}
+
+.fa-text-height {
+ --fa: "\f034";
+}
+
+.fa-text-width {
+ --fa: "\f035";
+}
+
+.fa-align-left {
+ --fa: "\f036";
+}
+
+.fa-align-center {
+ --fa: "\f037";
+}
+
+.fa-align-right {
+ --fa: "\f038";
+}
+
+.fa-align-justify {
+ --fa: "\f039";
+}
+
+.fa-list {
+ --fa: "\f03a";
+}
+
+.fa-list-squares {
+ --fa: "\f03a";
+}
+
+.fa-outdent {
+ --fa: "\f03b";
+}
+
+.fa-dedent {
+ --fa: "\f03b";
+}
+
+.fa-indent {
+ --fa: "\f03c";
+}
+
+.fa-video {
+ --fa: "\f03d";
+}
+
+.fa-video-camera {
+ --fa: "\f03d";
+}
+
+.fa-image {
+ --fa: "\f03e";
+}
+
+.fa-location-pin {
+ --fa: "\f041";
+}
+
+.fa-map-marker {
+ --fa: "\f041";
+}
+
+.fa-circle-half-stroke {
+ --fa: "\f042";
+}
+
+.fa-adjust {
+ --fa: "\f042";
+}
+
+.fa-droplet {
+ --fa: "\f043";
+}
+
+.fa-tint {
+ --fa: "\f043";
+}
+
+.fa-pen-to-square {
+ --fa: "\f044";
+}
+
+.fa-edit {
+ --fa: "\f044";
+}
+
+.fa-arrows-up-down-left-right {
+ --fa: "\f047";
+}
+
+.fa-arrows {
+ --fa: "\f047";
+}
+
+.fa-backward-step {
+ --fa: "\f048";
+}
+
+.fa-step-backward {
+ --fa: "\f048";
+}
+
+.fa-backward-fast {
+ --fa: "\f049";
+}
+
+.fa-fast-backward {
+ --fa: "\f049";
+}
+
+.fa-backward {
+ --fa: "\f04a";
+}
+
+.fa-play {
+ --fa: "\f04b";
+}
+
+.fa-pause {
+ --fa: "\f04c";
+}
+
+.fa-stop {
+ --fa: "\f04d";
+}
+
+.fa-forward {
+ --fa: "\f04e";
+}
+
+.fa-forward-fast {
+ --fa: "\f050";
+}
+
+.fa-fast-forward {
+ --fa: "\f050";
+}
+
+.fa-forward-step {
+ --fa: "\f051";
+}
+
+.fa-step-forward {
+ --fa: "\f051";
+}
+
+.fa-eject {
+ --fa: "\f052";
+}
+
+.fa-chevron-left {
+ --fa: "\f053";
+}
+
+.fa-chevron-right {
+ --fa: "\f054";
+}
+
+.fa-circle-plus {
+ --fa: "\f055";
+}
+
+.fa-plus-circle {
+ --fa: "\f055";
+}
+
+.fa-circle-minus {
+ --fa: "\f056";
+}
+
+.fa-minus-circle {
+ --fa: "\f056";
+}
+
+.fa-circle-xmark {
+ --fa: "\f057";
+}
+
+.fa-times-circle {
+ --fa: "\f057";
+}
+
+.fa-xmark-circle {
+ --fa: "\f057";
+}
+
+.fa-circle-check {
+ --fa: "\f058";
+}
+
+.fa-check-circle {
+ --fa: "\f058";
+}
+
+.fa-circle-question {
+ --fa: "\f059";
+}
+
+.fa-question-circle {
+ --fa: "\f059";
+}
+
+.fa-circle-info {
+ --fa: "\f05a";
+}
+
+.fa-info-circle {
+ --fa: "\f05a";
+}
+
+.fa-crosshairs {
+ --fa: "\f05b";
+}
+
+.fa-ban {
+ --fa: "\f05e";
+}
+
+.fa-cancel {
+ --fa: "\f05e";
+}
+
+.fa-arrow-left {
+ --fa: "\f060";
+}
+
+.fa-arrow-right {
+ --fa: "\f061";
+}
+
+.fa-arrow-up {
+ --fa: "\f062";
+}
+
+.fa-arrow-down {
+ --fa: "\f063";
+}
+
+.fa-share {
+ --fa: "\f064";
+}
+
+.fa-mail-forward {
+ --fa: "\f064";
+}
+
+.fa-expand {
+ --fa: "\f065";
+}
+
+.fa-compress {
+ --fa: "\f066";
+}
+
+.fa-minus {
+ --fa: "\f068";
+}
+
+.fa-subtract {
+ --fa: "\f068";
+}
+
+.fa-circle-exclamation {
+ --fa: "\f06a";
+}
+
+.fa-exclamation-circle {
+ --fa: "\f06a";
+}
+
+.fa-gift {
+ --fa: "\f06b";
+}
+
+.fa-leaf {
+ --fa: "\f06c";
+}
+
+.fa-fire {
+ --fa: "\f06d";
+}
+
+.fa-eye {
+ --fa: "\f06e";
+}
+
+.fa-eye-slash {
+ --fa: "\f070";
+}
+
+.fa-triangle-exclamation {
+ --fa: "\f071";
+}
+
+.fa-exclamation-triangle {
+ --fa: "\f071";
+}
+
+.fa-warning {
+ --fa: "\f071";
+}
+
+.fa-plane {
+ --fa: "\f072";
+}
+
+.fa-calendar-days {
+ --fa: "\f073";
+}
+
+.fa-calendar-alt {
+ --fa: "\f073";
+}
+
+.fa-shuffle {
+ --fa: "\f074";
+}
+
+.fa-random {
+ --fa: "\f074";
+}
+
+.fa-comment {
+ --fa: "\f075";
+}
+
+.fa-magnet {
+ --fa: "\f076";
+}
+
+.fa-chevron-up {
+ --fa: "\f077";
+}
+
+.fa-chevron-down {
+ --fa: "\f078";
+}
+
+.fa-retweet {
+ --fa: "\f079";
+}
+
+.fa-cart-shopping {
+ --fa: "\f07a";
+}
+
+.fa-shopping-cart {
+ --fa: "\f07a";
+}
+
+.fa-folder {
+ --fa: "\f07b";
+}
+
+.fa-folder-blank {
+ --fa: "\f07b";
+}
+
+.fa-folder-open {
+ --fa: "\f07c";
+}
+
+.fa-arrows-up-down {
+ --fa: "\f07d";
+}
+
+.fa-arrows-v {
+ --fa: "\f07d";
+}
+
+.fa-arrows-left-right {
+ --fa: "\f07e";
+}
+
+.fa-arrows-h {
+ --fa: "\f07e";
+}
+
+.fa-chart-bar {
+ --fa: "\f080";
+}
+
+.fa-bar-chart {
+ --fa: "\f080";
+}
+
+.fa-camera-retro {
+ --fa: "\f083";
+}
+
+.fa-key {
+ --fa: "\f084";
+}
+
+.fa-gears {
+ --fa: "\f085";
+}
+
+.fa-cogs {
+ --fa: "\f085";
+}
+
+.fa-comments {
+ --fa: "\f086";
+}
+
+.fa-star-half {
+ --fa: "\f089";
+}
+
+.fa-arrow-right-from-bracket {
+ --fa: "\f08b";
+}
+
+.fa-sign-out {
+ --fa: "\f08b";
+}
+
+.fa-thumbtack {
+ --fa: "\f08d";
+}
+
+.fa-thumb-tack {
+ --fa: "\f08d";
+}
+
+.fa-arrow-up-right-from-square {
+ --fa: "\f08e";
+}
+
+.fa-external-link {
+ --fa: "\f08e";
+}
+
+.fa-arrow-right-to-bracket {
+ --fa: "\f090";
+}
+
+.fa-sign-in {
+ --fa: "\f090";
+}
+
+.fa-trophy {
+ --fa: "\f091";
+}
+
+.fa-upload {
+ --fa: "\f093";
+}
+
+.fa-lemon {
+ --fa: "\f094";
+}
+
+.fa-phone {
+ --fa: "\f095";
+}
+
+.fa-square-phone {
+ --fa: "\f098";
+}
+
+.fa-phone-square {
+ --fa: "\f098";
+}
+
+.fa-unlock {
+ --fa: "\f09c";
+}
+
+.fa-credit-card {
+ --fa: "\f09d";
+}
+
+.fa-credit-card-alt {
+ --fa: "\f09d";
+}
+
+.fa-rss {
+ --fa: "\f09e";
+}
+
+.fa-feed {
+ --fa: "\f09e";
+}
+
+.fa-hard-drive {
+ --fa: "\f0a0";
+}
+
+.fa-hdd {
+ --fa: "\f0a0";
+}
+
+.fa-bullhorn {
+ --fa: "\f0a1";
+}
+
+.fa-certificate {
+ --fa: "\f0a3";
+}
+
+.fa-hand-point-right {
+ --fa: "\f0a4";
+}
+
+.fa-hand-point-left {
+ --fa: "\f0a5";
+}
+
+.fa-hand-point-up {
+ --fa: "\f0a6";
+}
+
+.fa-hand-point-down {
+ --fa: "\f0a7";
+}
+
+.fa-circle-arrow-left {
+ --fa: "\f0a8";
+}
+
+.fa-arrow-circle-left {
+ --fa: "\f0a8";
+}
+
+.fa-circle-arrow-right {
+ --fa: "\f0a9";
+}
+
+.fa-arrow-circle-right {
+ --fa: "\f0a9";
+}
+
+.fa-circle-arrow-up {
+ --fa: "\f0aa";
+}
+
+.fa-arrow-circle-up {
+ --fa: "\f0aa";
+}
+
+.fa-circle-arrow-down {
+ --fa: "\f0ab";
+}
+
+.fa-arrow-circle-down {
+ --fa: "\f0ab";
+}
+
+.fa-globe {
+ --fa: "\f0ac";
+}
+
+.fa-wrench {
+ --fa: "\f0ad";
+}
+
+.fa-list-check {
+ --fa: "\f0ae";
+}
+
+.fa-tasks {
+ --fa: "\f0ae";
+}
+
+.fa-filter {
+ --fa: "\f0b0";
+}
+
+.fa-briefcase {
+ --fa: "\f0b1";
+}
+
+.fa-up-down-left-right {
+ --fa: "\f0b2";
+}
+
+.fa-arrows-alt {
+ --fa: "\f0b2";
+}
+
+.fa-users {
+ --fa: "\f0c0";
+}
+
+.fa-link {
+ --fa: "\f0c1";
+}
+
+.fa-chain {
+ --fa: "\f0c1";
+}
+
+.fa-cloud {
+ --fa: "\f0c2";
+}
+
+.fa-flask {
+ --fa: "\f0c3";
+}
+
+.fa-scissors {
+ --fa: "\f0c4";
+}
+
+.fa-cut {
+ --fa: "\f0c4";
+}
+
+.fa-copy {
+ --fa: "\f0c5";
+}
+
+.fa-paperclip {
+ --fa: "\f0c6";
+}
+
+.fa-floppy-disk {
+ --fa: "\f0c7";
+}
+
+.fa-save {
+ --fa: "\f0c7";
+}
+
+.fa-square {
+ --fa: "\f0c8";
+}
+
+.fa-bars {
+ --fa: "\f0c9";
+}
+
+.fa-navicon {
+ --fa: "\f0c9";
+}
+
+.fa-list-ul {
+ --fa: "\f0ca";
+}
+
+.fa-list-dots {
+ --fa: "\f0ca";
+}
+
+.fa-list-ol {
+ --fa: "\f0cb";
+}
+
+.fa-list-1-2 {
+ --fa: "\f0cb";
+}
+
+.fa-list-numeric {
+ --fa: "\f0cb";
+}
+
+.fa-strikethrough {
+ --fa: "\f0cc";
+}
+
+.fa-underline {
+ --fa: "\f0cd";
+}
+
+.fa-table {
+ --fa: "\f0ce";
+}
+
+.fa-wand-magic {
+ --fa: "\f0d0";
+}
+
+.fa-magic {
+ --fa: "\f0d0";
+}
+
+.fa-truck {
+ --fa: "\f0d1";
+}
+
+.fa-money-bill {
+ --fa: "\f0d6";
+}
+
+.fa-caret-down {
+ --fa: "\f0d7";
+}
+
+.fa-caret-up {
+ --fa: "\f0d8";
+}
+
+.fa-caret-left {
+ --fa: "\f0d9";
+}
+
+.fa-caret-right {
+ --fa: "\f0da";
+}
+
+.fa-table-columns {
+ --fa: "\f0db";
+}
+
+.fa-columns {
+ --fa: "\f0db";
+}
+
+.fa-sort {
+ --fa: "\f0dc";
+}
+
+.fa-unsorted {
+ --fa: "\f0dc";
+}
+
+.fa-sort-down {
+ --fa: "\f0dd";
+}
+
+.fa-sort-desc {
+ --fa: "\f0dd";
+}
+
+.fa-sort-up {
+ --fa: "\f0de";
+}
+
+.fa-sort-asc {
+ --fa: "\f0de";
+}
+
+.fa-envelope {
+ --fa: "\f0e0";
+}
+
+.fa-arrow-rotate-left {
+ --fa: "\f0e2";
+}
+
+.fa-arrow-left-rotate {
+ --fa: "\f0e2";
+}
+
+.fa-arrow-rotate-back {
+ --fa: "\f0e2";
+}
+
+.fa-arrow-rotate-backward {
+ --fa: "\f0e2";
+}
+
+.fa-undo {
+ --fa: "\f0e2";
+}
+
+.fa-gavel {
+ --fa: "\f0e3";
+}
+
+.fa-legal {
+ --fa: "\f0e3";
+}
+
+.fa-bolt {
+ --fa: "\f0e7";
+}
+
+.fa-zap {
+ --fa: "\f0e7";
+}
+
+.fa-sitemap {
+ --fa: "\f0e8";
+}
+
+.fa-umbrella {
+ --fa: "\f0e9";
+}
+
+.fa-paste {
+ --fa: "\f0ea";
+}
+
+.fa-file-clipboard {
+ --fa: "\f0ea";
+}
+
+.fa-lightbulb {
+ --fa: "\f0eb";
+}
+
+.fa-arrow-right-arrow-left {
+ --fa: "\f0ec";
+}
+
+.fa-exchange {
+ --fa: "\f0ec";
+}
+
+.fa-cloud-arrow-down {
+ --fa: "\f0ed";
+}
+
+.fa-cloud-download {
+ --fa: "\f0ed";
+}
+
+.fa-cloud-download-alt {
+ --fa: "\f0ed";
+}
+
+.fa-cloud-arrow-up {
+ --fa: "\f0ee";
+}
+
+.fa-cloud-upload {
+ --fa: "\f0ee";
+}
+
+.fa-cloud-upload-alt {
+ --fa: "\f0ee";
+}
+
+.fa-user-doctor {
+ --fa: "\f0f0";
+}
+
+.fa-user-md {
+ --fa: "\f0f0";
+}
+
+.fa-stethoscope {
+ --fa: "\f0f1";
+}
+
+.fa-suitcase {
+ --fa: "\f0f2";
+}
+
+.fa-bell {
+ --fa: "\f0f3";
+}
+
+.fa-mug-saucer {
+ --fa: "\f0f4";
+}
+
+.fa-coffee {
+ --fa: "\f0f4";
+}
+
+.fa-hospital {
+ --fa: "\f0f8";
+}
+
+.fa-hospital-alt {
+ --fa: "\f0f8";
+}
+
+.fa-hospital-wide {
+ --fa: "\f0f8";
+}
+
+.fa-truck-medical {
+ --fa: "\f0f9";
+}
+
+.fa-ambulance {
+ --fa: "\f0f9";
+}
+
+.fa-suitcase-medical {
+ --fa: "\f0fa";
+}
+
+.fa-medkit {
+ --fa: "\f0fa";
+}
+
+.fa-jet-fighter {
+ --fa: "\f0fb";
+}
+
+.fa-fighter-jet {
+ --fa: "\f0fb";
+}
+
+.fa-beer-mug-empty {
+ --fa: "\f0fc";
+}
+
+.fa-beer {
+ --fa: "\f0fc";
+}
+
+.fa-square-h {
+ --fa: "\f0fd";
+}
+
+.fa-h-square {
+ --fa: "\f0fd";
+}
+
+.fa-square-plus {
+ --fa: "\f0fe";
+}
+
+.fa-plus-square {
+ --fa: "\f0fe";
+}
+
+.fa-angles-left {
+ --fa: "\f100";
+}
+
+.fa-angle-double-left {
+ --fa: "\f100";
+}
+
+.fa-angles-right {
+ --fa: "\f101";
+}
+
+.fa-angle-double-right {
+ --fa: "\f101";
+}
+
+.fa-angles-up {
+ --fa: "\f102";
+}
+
+.fa-angle-double-up {
+ --fa: "\f102";
+}
+
+.fa-angles-down {
+ --fa: "\f103";
+}
+
+.fa-angle-double-down {
+ --fa: "\f103";
+}
+
+.fa-angle-left {
+ --fa: "\f104";
+}
+
+.fa-angle-right {
+ --fa: "\f105";
+}
+
+.fa-angle-up {
+ --fa: "\f106";
+}
+
+.fa-angle-down {
+ --fa: "\f107";
+}
+
+.fa-laptop {
+ --fa: "\f109";
+}
+
+.fa-tablet-button {
+ --fa: "\f10a";
+}
+
+.fa-mobile-button {
+ --fa: "\f10b";
+}
+
+.fa-quote-left {
+ --fa: "\f10d";
+}
+
+.fa-quote-left-alt {
+ --fa: "\f10d";
+}
+
+.fa-quote-right {
+ --fa: "\f10e";
+}
+
+.fa-quote-right-alt {
+ --fa: "\f10e";
+}
+
+.fa-spinner {
+ --fa: "\f110";
+}
+
+.fa-circle {
+ --fa: "\f111";
+}
+
+.fa-face-smile {
+ --fa: "\f118";
+}
+
+.fa-smile {
+ --fa: "\f118";
+}
+
+.fa-face-frown {
+ --fa: "\f119";
+}
+
+.fa-frown {
+ --fa: "\f119";
+}
+
+.fa-face-meh {
+ --fa: "\f11a";
+}
+
+.fa-meh {
+ --fa: "\f11a";
+}
+
+.fa-gamepad {
+ --fa: "\f11b";
+}
+
+.fa-keyboard {
+ --fa: "\f11c";
+}
+
+.fa-flag-checkered {
+ --fa: "\f11e";
+}
+
+.fa-terminal {
+ --fa: "\f120";
+}
+
+.fa-code {
+ --fa: "\f121";
+}
+
+.fa-reply-all {
+ --fa: "\f122";
+}
+
+.fa-mail-reply-all {
+ --fa: "\f122";
+}
+
+.fa-location-arrow {
+ --fa: "\f124";
+}
+
+.fa-crop {
+ --fa: "\f125";
+}
+
+.fa-code-branch {
+ --fa: "\f126";
+}
+
+.fa-link-slash {
+ --fa: "\f127";
+}
+
+.fa-chain-broken {
+ --fa: "\f127";
+}
+
+.fa-chain-slash {
+ --fa: "\f127";
+}
+
+.fa-unlink {
+ --fa: "\f127";
+}
+
+.fa-info {
+ --fa: "\f129";
+}
+
+.fa-superscript {
+ --fa: "\f12b";
+}
+
+.fa-subscript {
+ --fa: "\f12c";
+}
+
+.fa-eraser {
+ --fa: "\f12d";
+}
+
+.fa-puzzle-piece {
+ --fa: "\f12e";
+}
+
+.fa-microphone {
+ --fa: "\f130";
+}
+
+.fa-microphone-slash {
+ --fa: "\f131";
+}
+
+.fa-shield {
+ --fa: "\f132";
+}
+
+.fa-shield-blank {
+ --fa: "\f132";
+}
+
+.fa-calendar {
+ --fa: "\f133";
+}
+
+.fa-fire-extinguisher {
+ --fa: "\f134";
+}
+
+.fa-rocket {
+ --fa: "\f135";
+}
+
+.fa-circle-chevron-left {
+ --fa: "\f137";
+}
+
+.fa-chevron-circle-left {
+ --fa: "\f137";
+}
+
+.fa-circle-chevron-right {
+ --fa: "\f138";
+}
+
+.fa-chevron-circle-right {
+ --fa: "\f138";
+}
+
+.fa-circle-chevron-up {
+ --fa: "\f139";
+}
+
+.fa-chevron-circle-up {
+ --fa: "\f139";
+}
+
+.fa-circle-chevron-down {
+ --fa: "\f13a";
+}
+
+.fa-chevron-circle-down {
+ --fa: "\f13a";
+}
+
+.fa-anchor {
+ --fa: "\f13d";
+}
+
+.fa-unlock-keyhole {
+ --fa: "\f13e";
+}
+
+.fa-unlock-alt {
+ --fa: "\f13e";
+}
+
+.fa-bullseye {
+ --fa: "\f140";
+}
+
+.fa-ellipsis {
+ --fa: "\f141";
+}
+
+.fa-ellipsis-h {
+ --fa: "\f141";
+}
+
+.fa-ellipsis-vertical {
+ --fa: "\f142";
+}
+
+.fa-ellipsis-v {
+ --fa: "\f142";
+}
+
+.fa-square-rss {
+ --fa: "\f143";
+}
+
+.fa-rss-square {
+ --fa: "\f143";
+}
+
+.fa-circle-play {
+ --fa: "\f144";
+}
+
+.fa-play-circle {
+ --fa: "\f144";
+}
+
+.fa-ticket {
+ --fa: "\f145";
+}
+
+.fa-square-minus {
+ --fa: "\f146";
+}
+
+.fa-minus-square {
+ --fa: "\f146";
+}
+
+.fa-arrow-turn-up {
+ --fa: "\f148";
+}
+
+.fa-level-up {
+ --fa: "\f148";
+}
+
+.fa-arrow-turn-down {
+ --fa: "\f149";
+}
+
+.fa-level-down {
+ --fa: "\f149";
+}
+
+.fa-square-check {
+ --fa: "\f14a";
+}
+
+.fa-check-square {
+ --fa: "\f14a";
+}
+
+.fa-square-pen {
+ --fa: "\f14b";
+}
+
+.fa-pen-square {
+ --fa: "\f14b";
+}
+
+.fa-pencil-square {
+ --fa: "\f14b";
+}
+
+.fa-square-arrow-up-right {
+ --fa: "\f14c";
+}
+
+.fa-external-link-square {
+ --fa: "\f14c";
+}
+
+.fa-share-from-square {
+ --fa: "\f14d";
+}
+
+.fa-share-square {
+ --fa: "\f14d";
+}
+
+.fa-compass {
+ --fa: "\f14e";
+}
+
+.fa-square-caret-down {
+ --fa: "\f150";
+}
+
+.fa-caret-square-down {
+ --fa: "\f150";
+}
+
+.fa-square-caret-up {
+ --fa: "\f151";
+}
+
+.fa-caret-square-up {
+ --fa: "\f151";
+}
+
+.fa-square-caret-right {
+ --fa: "\f152";
+}
+
+.fa-caret-square-right {
+ --fa: "\f152";
+}
+
+.fa-euro-sign {
+ --fa: "\f153";
+}
+
+.fa-eur {
+ --fa: "\f153";
+}
+
+.fa-euro {
+ --fa: "\f153";
+}
+
+.fa-sterling-sign {
+ --fa: "\f154";
+}
+
+.fa-gbp {
+ --fa: "\f154";
+}
+
+.fa-pound-sign {
+ --fa: "\f154";
+}
+
+.fa-rupee-sign {
+ --fa: "\f156";
+}
+
+.fa-rupee {
+ --fa: "\f156";
+}
+
+.fa-yen-sign {
+ --fa: "\f157";
+}
+
+.fa-cny {
+ --fa: "\f157";
+}
+
+.fa-jpy {
+ --fa: "\f157";
+}
+
+.fa-rmb {
+ --fa: "\f157";
+}
+
+.fa-yen {
+ --fa: "\f157";
+}
+
+.fa-ruble-sign {
+ --fa: "\f158";
+}
+
+.fa-rouble {
+ --fa: "\f158";
+}
+
+.fa-rub {
+ --fa: "\f158";
+}
+
+.fa-ruble {
+ --fa: "\f158";
+}
+
+.fa-won-sign {
+ --fa: "\f159";
+}
+
+.fa-krw {
+ --fa: "\f159";
+}
+
+.fa-won {
+ --fa: "\f159";
+}
+
+.fa-file {
+ --fa: "\f15b";
+}
+
+.fa-file-lines {
+ --fa: "\f15c";
+}
+
+.fa-file-alt {
+ --fa: "\f15c";
+}
+
+.fa-file-text {
+ --fa: "\f15c";
+}
+
+.fa-arrow-down-a-z {
+ --fa: "\f15d";
+}
+
+.fa-sort-alpha-asc {
+ --fa: "\f15d";
+}
+
+.fa-sort-alpha-down {
+ --fa: "\f15d";
+}
+
+.fa-arrow-up-a-z {
+ --fa: "\f15e";
+}
+
+.fa-sort-alpha-up {
+ --fa: "\f15e";
+}
+
+.fa-arrow-down-wide-short {
+ --fa: "\f160";
+}
+
+.fa-sort-amount-asc {
+ --fa: "\f160";
+}
+
+.fa-sort-amount-down {
+ --fa: "\f160";
+}
+
+.fa-arrow-up-wide-short {
+ --fa: "\f161";
+}
+
+.fa-sort-amount-up {
+ --fa: "\f161";
+}
+
+.fa-arrow-down-1-9 {
+ --fa: "\f162";
+}
+
+.fa-sort-numeric-asc {
+ --fa: "\f162";
+}
+
+.fa-sort-numeric-down {
+ --fa: "\f162";
+}
+
+.fa-arrow-up-1-9 {
+ --fa: "\f163";
+}
+
+.fa-sort-numeric-up {
+ --fa: "\f163";
+}
+
+.fa-thumbs-up {
+ --fa: "\f164";
+}
+
+.fa-thumbs-down {
+ --fa: "\f165";
+}
+
+.fa-arrow-down-long {
+ --fa: "\f175";
+}
+
+.fa-long-arrow-down {
+ --fa: "\f175";
+}
+
+.fa-arrow-up-long {
+ --fa: "\f176";
+}
+
+.fa-long-arrow-up {
+ --fa: "\f176";
+}
+
+.fa-arrow-left-long {
+ --fa: "\f177";
+}
+
+.fa-long-arrow-left {
+ --fa: "\f177";
+}
+
+.fa-arrow-right-long {
+ --fa: "\f178";
+}
+
+.fa-long-arrow-right {
+ --fa: "\f178";
+}
+
+.fa-person-dress {
+ --fa: "\f182";
+}
+
+.fa-female {
+ --fa: "\f182";
+}
+
+.fa-person {
+ --fa: "\f183";
+}
+
+.fa-male {
+ --fa: "\f183";
+}
+
+.fa-sun {
+ --fa: "\f185";
+}
+
+.fa-moon {
+ --fa: "\f186";
+}
+
+.fa-box-archive {
+ --fa: "\f187";
+}
+
+.fa-archive {
+ --fa: "\f187";
+}
+
+.fa-bug {
+ --fa: "\f188";
+}
+
+.fa-square-caret-left {
+ --fa: "\f191";
+}
+
+.fa-caret-square-left {
+ --fa: "\f191";
+}
+
+.fa-circle-dot {
+ --fa: "\f192";
+}
+
+.fa-dot-circle {
+ --fa: "\f192";
+}
+
+.fa-wheelchair {
+ --fa: "\f193";
+}
+
+.fa-lira-sign {
+ --fa: "\f195";
+}
+
+.fa-shuttle-space {
+ --fa: "\f197";
+}
+
+.fa-space-shuttle {
+ --fa: "\f197";
+}
+
+.fa-square-envelope {
+ --fa: "\f199";
+}
+
+.fa-envelope-square {
+ --fa: "\f199";
+}
+
+.fa-building-columns {
+ --fa: "\f19c";
+}
+
+.fa-bank {
+ --fa: "\f19c";
+}
+
+.fa-institution {
+ --fa: "\f19c";
+}
+
+.fa-museum {
+ --fa: "\f19c";
+}
+
+.fa-university {
+ --fa: "\f19c";
+}
+
+.fa-graduation-cap {
+ --fa: "\f19d";
+}
+
+.fa-mortar-board {
+ --fa: "\f19d";
+}
+
+.fa-language {
+ --fa: "\f1ab";
+}
+
+.fa-fax {
+ --fa: "\f1ac";
+}
+
+.fa-building {
+ --fa: "\f1ad";
+}
+
+.fa-child {
+ --fa: "\f1ae";
+}
+
+.fa-paw {
+ --fa: "\f1b0";
+}
+
+.fa-cube {
+ --fa: "\f1b2";
+}
+
+.fa-cubes {
+ --fa: "\f1b3";
+}
+
+.fa-recycle {
+ --fa: "\f1b8";
+}
+
+.fa-car {
+ --fa: "\f1b9";
+}
+
+.fa-automobile {
+ --fa: "\f1b9";
+}
+
+.fa-taxi {
+ --fa: "\f1ba";
+}
+
+.fa-cab {
+ --fa: "\f1ba";
+}
+
+.fa-tree {
+ --fa: "\f1bb";
+}
+
+.fa-database {
+ --fa: "\f1c0";
+}
+
+.fa-file-pdf {
+ --fa: "\f1c1";
+}
+
+.fa-file-word {
+ --fa: "\f1c2";
+}
+
+.fa-file-excel {
+ --fa: "\f1c3";
+}
+
+.fa-file-powerpoint {
+ --fa: "\f1c4";
+}
+
+.fa-file-image {
+ --fa: "\f1c5";
+}
+
+.fa-file-zipper {
+ --fa: "\f1c6";
+}
+
+.fa-file-archive {
+ --fa: "\f1c6";
+}
+
+.fa-file-audio {
+ --fa: "\f1c7";
+}
+
+.fa-file-video {
+ --fa: "\f1c8";
+}
+
+.fa-file-code {
+ --fa: "\f1c9";
+}
+
+.fa-life-ring {
+ --fa: "\f1cd";
+}
+
+.fa-circle-notch {
+ --fa: "\f1ce";
+}
+
+.fa-paper-plane {
+ --fa: "\f1d8";
+}
+
+.fa-clock-rotate-left {
+ --fa: "\f1da";
+}
+
+.fa-history {
+ --fa: "\f1da";
+}
+
+.fa-heading {
+ --fa: "\f1dc";
+}
+
+.fa-header {
+ --fa: "\f1dc";
+}
+
+.fa-paragraph {
+ --fa: "\f1dd";
+}
+
+.fa-sliders {
+ --fa: "\f1de";
+}
+
+.fa-sliders-h {
+ --fa: "\f1de";
+}
+
+.fa-share-nodes {
+ --fa: "\f1e0";
+}
+
+.fa-share-alt {
+ --fa: "\f1e0";
+}
+
+.fa-square-share-nodes {
+ --fa: "\f1e1";
+}
+
+.fa-share-alt-square {
+ --fa: "\f1e1";
+}
+
+.fa-bomb {
+ --fa: "\f1e2";
+}
+
+.fa-futbol {
+ --fa: "\f1e3";
+}
+
+.fa-futbol-ball {
+ --fa: "\f1e3";
+}
+
+.fa-soccer-ball {
+ --fa: "\f1e3";
+}
+
+.fa-tty {
+ --fa: "\f1e4";
+}
+
+.fa-teletype {
+ --fa: "\f1e4";
+}
+
+.fa-binoculars {
+ --fa: "\f1e5";
+}
+
+.fa-plug {
+ --fa: "\f1e6";
+}
+
+.fa-newspaper {
+ --fa: "\f1ea";
+}
+
+.fa-wifi {
+ --fa: "\f1eb";
+}
+
+.fa-wifi-3 {
+ --fa: "\f1eb";
+}
+
+.fa-wifi-strong {
+ --fa: "\f1eb";
+}
+
+.fa-calculator {
+ --fa: "\f1ec";
+}
+
+.fa-bell-slash {
+ --fa: "\f1f6";
+}
+
+.fa-trash {
+ --fa: "\f1f8";
+}
+
+.fa-copyright {
+ --fa: "\f1f9";
+}
+
+.fa-eye-dropper {
+ --fa: "\f1fb";
+}
+
+.fa-eye-dropper-empty {
+ --fa: "\f1fb";
+}
+
+.fa-eyedropper {
+ --fa: "\f1fb";
+}
+
+.fa-paintbrush {
+ --fa: "\f1fc";
+}
+
+.fa-paint-brush {
+ --fa: "\f1fc";
+}
+
+.fa-cake-candles {
+ --fa: "\f1fd";
+}
+
+.fa-birthday-cake {
+ --fa: "\f1fd";
+}
+
+.fa-cake {
+ --fa: "\f1fd";
+}
+
+.fa-chart-area {
+ --fa: "\f1fe";
+}
+
+.fa-area-chart {
+ --fa: "\f1fe";
+}
+
+.fa-chart-pie {
+ --fa: "\f200";
+}
+
+.fa-pie-chart {
+ --fa: "\f200";
+}
+
+.fa-chart-line {
+ --fa: "\f201";
+}
+
+.fa-line-chart {
+ --fa: "\f201";
+}
+
+.fa-toggle-off {
+ --fa: "\f204";
+}
+
+.fa-toggle-on {
+ --fa: "\f205";
+}
+
+.fa-bicycle {
+ --fa: "\f206";
+}
+
+.fa-bus {
+ --fa: "\f207";
+}
+
+.fa-closed-captioning {
+ --fa: "\f20a";
+}
+
+.fa-shekel-sign {
+ --fa: "\f20b";
+}
+
+.fa-ils {
+ --fa: "\f20b";
+}
+
+.fa-shekel {
+ --fa: "\f20b";
+}
+
+.fa-sheqel {
+ --fa: "\f20b";
+}
+
+.fa-sheqel-sign {
+ --fa: "\f20b";
+}
+
+.fa-cart-plus {
+ --fa: "\f217";
+}
+
+.fa-cart-arrow-down {
+ --fa: "\f218";
+}
+
+.fa-diamond {
+ --fa: "\f219";
+}
+
+.fa-ship {
+ --fa: "\f21a";
+}
+
+.fa-user-secret {
+ --fa: "\f21b";
+}
+
+.fa-motorcycle {
+ --fa: "\f21c";
+}
+
+.fa-street-view {
+ --fa: "\f21d";
+}
+
+.fa-heart-pulse {
+ --fa: "\f21e";
+}
+
+.fa-heartbeat {
+ --fa: "\f21e";
+}
+
+.fa-venus {
+ --fa: "\f221";
+}
+
+.fa-mars {
+ --fa: "\f222";
+}
+
+.fa-mercury {
+ --fa: "\f223";
+}
+
+.fa-mars-and-venus {
+ --fa: "\f224";
+}
+
+.fa-transgender {
+ --fa: "\f225";
+}
+
+.fa-transgender-alt {
+ --fa: "\f225";
+}
+
+.fa-venus-double {
+ --fa: "\f226";
+}
+
+.fa-mars-double {
+ --fa: "\f227";
+}
+
+.fa-venus-mars {
+ --fa: "\f228";
+}
+
+.fa-mars-stroke {
+ --fa: "\f229";
+}
+
+.fa-mars-stroke-up {
+ --fa: "\f22a";
+}
+
+.fa-mars-stroke-v {
+ --fa: "\f22a";
+}
+
+.fa-mars-stroke-right {
+ --fa: "\f22b";
+}
+
+.fa-mars-stroke-h {
+ --fa: "\f22b";
+}
+
+.fa-neuter {
+ --fa: "\f22c";
+}
+
+.fa-genderless {
+ --fa: "\f22d";
+}
+
+.fa-server {
+ --fa: "\f233";
+}
+
+.fa-user-plus {
+ --fa: "\f234";
+}
+
+.fa-user-xmark {
+ --fa: "\f235";
+}
+
+.fa-user-times {
+ --fa: "\f235";
+}
+
+.fa-bed {
+ --fa: "\f236";
+}
+
+.fa-train {
+ --fa: "\f238";
+}
+
+.fa-train-subway {
+ --fa: "\f239";
+}
+
+.fa-subway {
+ --fa: "\f239";
+}
+
+.fa-battery-full {
+ --fa: "\f240";
+}
+
+.fa-battery {
+ --fa: "\f240";
+}
+
+.fa-battery-5 {
+ --fa: "\f240";
+}
+
+.fa-battery-three-quarters {
+ --fa: "\f241";
+}
+
+.fa-battery-4 {
+ --fa: "\f241";
+}
+
+.fa-battery-half {
+ --fa: "\f242";
+}
+
+.fa-battery-3 {
+ --fa: "\f242";
+}
+
+.fa-battery-quarter {
+ --fa: "\f243";
+}
+
+.fa-battery-2 {
+ --fa: "\f243";
+}
+
+.fa-battery-empty {
+ --fa: "\f244";
+}
+
+.fa-battery-0 {
+ --fa: "\f244";
+}
+
+.fa-arrow-pointer {
+ --fa: "\f245";
+}
+
+.fa-mouse-pointer {
+ --fa: "\f245";
+}
+
+.fa-i-cursor {
+ --fa: "\f246";
+}
+
+.fa-object-group {
+ --fa: "\f247";
+}
+
+.fa-object-ungroup {
+ --fa: "\f248";
+}
+
+.fa-note-sticky {
+ --fa: "\f249";
+}
+
+.fa-sticky-note {
+ --fa: "\f249";
+}
+
+.fa-clone {
+ --fa: "\f24d";
+}
+
+.fa-scale-balanced {
+ --fa: "\f24e";
+}
+
+.fa-balance-scale {
+ --fa: "\f24e";
+}
+
+.fa-hourglass-start {
+ --fa: "\f251";
+}
+
+.fa-hourglass-1 {
+ --fa: "\f251";
+}
+
+.fa-hourglass-half {
+ --fa: "\f252";
+}
+
+.fa-hourglass-2 {
+ --fa: "\f252";
+}
+
+.fa-hourglass-end {
+ --fa: "\f253";
+}
+
+.fa-hourglass-3 {
+ --fa: "\f253";
+}
+
+.fa-hourglass {
+ --fa: "\f254";
+}
+
+.fa-hourglass-empty {
+ --fa: "\f254";
+}
+
+.fa-hand-back-fist {
+ --fa: "\f255";
+}
+
+.fa-hand-rock {
+ --fa: "\f255";
+}
+
+.fa-hand {
+ --fa: "\f256";
+}
+
+.fa-hand-paper {
+ --fa: "\f256";
+}
+
+.fa-hand-scissors {
+ --fa: "\f257";
+}
+
+.fa-hand-lizard {
+ --fa: "\f258";
+}
+
+.fa-hand-spock {
+ --fa: "\f259";
+}
+
+.fa-hand-pointer {
+ --fa: "\f25a";
+}
+
+.fa-hand-peace {
+ --fa: "\f25b";
+}
+
+.fa-trademark {
+ --fa: "\f25c";
+}
+
+.fa-registered {
+ --fa: "\f25d";
+}
+
+.fa-tv {
+ --fa: "\f26c";
+}
+
+.fa-television {
+ --fa: "\f26c";
+}
+
+.fa-tv-alt {
+ --fa: "\f26c";
+}
+
+.fa-calendar-plus {
+ --fa: "\f271";
+}
+
+.fa-calendar-minus {
+ --fa: "\f272";
+}
+
+.fa-calendar-xmark {
+ --fa: "\f273";
+}
+
+.fa-calendar-times {
+ --fa: "\f273";
+}
+
+.fa-calendar-check {
+ --fa: "\f274";
+}
+
+.fa-industry {
+ --fa: "\f275";
+}
+
+.fa-map-pin {
+ --fa: "\f276";
+}
+
+.fa-signs-post {
+ --fa: "\f277";
+}
+
+.fa-map-signs {
+ --fa: "\f277";
+}
+
+.fa-map {
+ --fa: "\f279";
+}
+
+.fa-message {
+ --fa: "\f27a";
+}
+
+.fa-comment-alt {
+ --fa: "\f27a";
+}
+
+.fa-circle-pause {
+ --fa: "\f28b";
+}
+
+.fa-pause-circle {
+ --fa: "\f28b";
+}
+
+.fa-circle-stop {
+ --fa: "\f28d";
+}
+
+.fa-stop-circle {
+ --fa: "\f28d";
+}
+
+.fa-bag-shopping {
+ --fa: "\f290";
+}
+
+.fa-shopping-bag {
+ --fa: "\f290";
+}
+
+.fa-basket-shopping {
+ --fa: "\f291";
+}
+
+.fa-shopping-basket {
+ --fa: "\f291";
+}
+
+.fa-universal-access {
+ --fa: "\f29a";
+}
+
+.fa-person-walking-with-cane {
+ --fa: "\f29d";
+}
+
+.fa-blind {
+ --fa: "\f29d";
+}
+
+.fa-audio-description {
+ --fa: "\f29e";
+}
+
+.fa-phone-volume {
+ --fa: "\f2a0";
+}
+
+.fa-volume-control-phone {
+ --fa: "\f2a0";
+}
+
+.fa-braille {
+ --fa: "\f2a1";
+}
+
+.fa-ear-listen {
+ --fa: "\f2a2";
+}
+
+.fa-assistive-listening-systems {
+ --fa: "\f2a2";
+}
+
+.fa-hands-asl-interpreting {
+ --fa: "\f2a3";
+}
+
+.fa-american-sign-language-interpreting {
+ --fa: "\f2a3";
+}
+
+.fa-asl-interpreting {
+ --fa: "\f2a3";
+}
+
+.fa-hands-american-sign-language-interpreting {
+ --fa: "\f2a3";
+}
+
+.fa-ear-deaf {
+ --fa: "\f2a4";
+}
+
+.fa-deaf {
+ --fa: "\f2a4";
+}
+
+.fa-deafness {
+ --fa: "\f2a4";
+}
+
+.fa-hard-of-hearing {
+ --fa: "\f2a4";
+}
+
+.fa-hands {
+ --fa: "\f2a7";
+}
+
+.fa-sign-language {
+ --fa: "\f2a7";
+}
+
+.fa-signing {
+ --fa: "\f2a7";
+}
+
+.fa-eye-low-vision {
+ --fa: "\f2a8";
+}
+
+.fa-low-vision {
+ --fa: "\f2a8";
+}
+
+.fa-font-awesome {
+ --fa: "\f2b4";
+}
+
+.fa-font-awesome-flag {
+ --fa: "\f2b4";
+}
+
+.fa-font-awesome-logo-full {
+ --fa: "\f2b4";
+}
+
+.fa-handshake {
+ --fa: "\f2b5";
+}
+
+.fa-handshake-alt {
+ --fa: "\f2b5";
+}
+
+.fa-handshake-simple {
+ --fa: "\f2b5";
+}
+
+.fa-envelope-open {
+ --fa: "\f2b6";
+}
+
+.fa-address-book {
+ --fa: "\f2b9";
+}
+
+.fa-contact-book {
+ --fa: "\f2b9";
+}
+
+.fa-address-card {
+ --fa: "\f2bb";
+}
+
+.fa-contact-card {
+ --fa: "\f2bb";
+}
+
+.fa-vcard {
+ --fa: "\f2bb";
+}
+
+.fa-circle-user {
+ --fa: "\f2bd";
+}
+
+.fa-user-circle {
+ --fa: "\f2bd";
+}
+
+.fa-id-badge {
+ --fa: "\f2c1";
+}
+
+.fa-id-card {
+ --fa: "\f2c2";
+}
+
+.fa-drivers-license {
+ --fa: "\f2c2";
+}
+
+.fa-temperature-full {
+ --fa: "\f2c7";
+}
+
+.fa-temperature-4 {
+ --fa: "\f2c7";
+}
+
+.fa-thermometer-4 {
+ --fa: "\f2c7";
+}
+
+.fa-thermometer-full {
+ --fa: "\f2c7";
+}
+
+.fa-temperature-three-quarters {
+ --fa: "\f2c8";
+}
+
+.fa-temperature-3 {
+ --fa: "\f2c8";
+}
+
+.fa-thermometer-3 {
+ --fa: "\f2c8";
+}
+
+.fa-thermometer-three-quarters {
+ --fa: "\f2c8";
+}
+
+.fa-temperature-half {
+ --fa: "\f2c9";
+}
+
+.fa-temperature-2 {
+ --fa: "\f2c9";
+}
+
+.fa-thermometer-2 {
+ --fa: "\f2c9";
+}
+
+.fa-thermometer-half {
+ --fa: "\f2c9";
+}
+
+.fa-temperature-quarter {
+ --fa: "\f2ca";
+}
+
+.fa-temperature-1 {
+ --fa: "\f2ca";
+}
+
+.fa-thermometer-1 {
+ --fa: "\f2ca";
+}
+
+.fa-thermometer-quarter {
+ --fa: "\f2ca";
+}
+
+.fa-temperature-empty {
+ --fa: "\f2cb";
+}
+
+.fa-temperature-0 {
+ --fa: "\f2cb";
+}
+
+.fa-thermometer-0 {
+ --fa: "\f2cb";
+}
+
+.fa-thermometer-empty {
+ --fa: "\f2cb";
+}
+
+.fa-shower {
+ --fa: "\f2cc";
+}
+
+.fa-bath {
+ --fa: "\f2cd";
+}
+
+.fa-bathtub {
+ --fa: "\f2cd";
+}
+
+.fa-podcast {
+ --fa: "\f2ce";
+}
+
+.fa-window-maximize {
+ --fa: "\f2d0";
+}
+
+.fa-window-minimize {
+ --fa: "\f2d1";
+}
+
+.fa-window-restore {
+ --fa: "\f2d2";
+}
+
+.fa-square-xmark {
+ --fa: "\f2d3";
+}
+
+.fa-times-square {
+ --fa: "\f2d3";
+}
+
+.fa-xmark-square {
+ --fa: "\f2d3";
+}
+
+.fa-microchip {
+ --fa: "\f2db";
+}
+
+.fa-snowflake {
+ --fa: "\f2dc";
+}
+
+.fa-spoon {
+ --fa: "\f2e5";
+}
+
+.fa-utensil-spoon {
+ --fa: "\f2e5";
+}
+
+.fa-utensils {
+ --fa: "\f2e7";
+}
+
+.fa-cutlery {
+ --fa: "\f2e7";
+}
+
+.fa-rotate-left {
+ --fa: "\f2ea";
+}
+
+.fa-rotate-back {
+ --fa: "\f2ea";
+}
+
+.fa-rotate-backward {
+ --fa: "\f2ea";
+}
+
+.fa-undo-alt {
+ --fa: "\f2ea";
+}
+
+.fa-trash-can {
+ --fa: "\f2ed";
+}
+
+.fa-trash-alt {
+ --fa: "\f2ed";
+}
+
+.fa-rotate {
+ --fa: "\f2f1";
+}
+
+.fa-sync-alt {
+ --fa: "\f2f1";
+}
+
+.fa-stopwatch {
+ --fa: "\f2f2";
+}
+
+.fa-right-from-bracket {
+ --fa: "\f2f5";
+}
+
+.fa-sign-out-alt {
+ --fa: "\f2f5";
+}
+
+.fa-right-to-bracket {
+ --fa: "\f2f6";
+}
+
+.fa-sign-in-alt {
+ --fa: "\f2f6";
+}
+
+.fa-rotate-right {
+ --fa: "\f2f9";
+}
+
+.fa-redo-alt {
+ --fa: "\f2f9";
+}
+
+.fa-rotate-forward {
+ --fa: "\f2f9";
+}
+
+.fa-poo {
+ --fa: "\f2fe";
+}
+
+.fa-images {
+ --fa: "\f302";
+}
+
+.fa-pencil {
+ --fa: "\f303";
+}
+
+.fa-pencil-alt {
+ --fa: "\f303";
+}
+
+.fa-pen {
+ --fa: "\f304";
+}
+
+.fa-pen-clip {
+ --fa: "\f305";
+}
+
+.fa-pen-alt {
+ --fa: "\f305";
+}
+
+.fa-octagon {
+ --fa: "\f306";
+}
+
+.fa-down-long {
+ --fa: "\f309";
+}
+
+.fa-long-arrow-alt-down {
+ --fa: "\f309";
+}
+
+.fa-left-long {
+ --fa: "\f30a";
+}
+
+.fa-long-arrow-alt-left {
+ --fa: "\f30a";
+}
+
+.fa-right-long {
+ --fa: "\f30b";
+}
+
+.fa-long-arrow-alt-right {
+ --fa: "\f30b";
+}
+
+.fa-up-long {
+ --fa: "\f30c";
+}
+
+.fa-long-arrow-alt-up {
+ --fa: "\f30c";
+}
+
+.fa-hexagon {
+ --fa: "\f312";
+}
+
+.fa-file-pen {
+ --fa: "\f31c";
+}
+
+.fa-file-edit {
+ --fa: "\f31c";
+}
+
+.fa-maximize {
+ --fa: "\f31e";
+}
+
+.fa-expand-arrows-alt {
+ --fa: "\f31e";
+}
+
+.fa-clipboard {
+ --fa: "\f328";
+}
+
+.fa-left-right {
+ --fa: "\f337";
+}
+
+.fa-arrows-alt-h {
+ --fa: "\f337";
+}
+
+.fa-up-down {
+ --fa: "\f338";
+}
+
+.fa-arrows-alt-v {
+ --fa: "\f338";
+}
+
+.fa-alarm-clock {
+ --fa: "\f34e";
+}
+
+.fa-circle-down {
+ --fa: "\f358";
+}
+
+.fa-arrow-alt-circle-down {
+ --fa: "\f358";
+}
+
+.fa-circle-left {
+ --fa: "\f359";
+}
+
+.fa-arrow-alt-circle-left {
+ --fa: "\f359";
+}
+
+.fa-circle-right {
+ --fa: "\f35a";
+}
+
+.fa-arrow-alt-circle-right {
+ --fa: "\f35a";
+}
+
+.fa-circle-up {
+ --fa: "\f35b";
+}
+
+.fa-arrow-alt-circle-up {
+ --fa: "\f35b";
+}
+
+.fa-up-right-from-square {
+ --fa: "\f35d";
+}
+
+.fa-external-link-alt {
+ --fa: "\f35d";
+}
+
+.fa-square-up-right {
+ --fa: "\f360";
+}
+
+.fa-external-link-square-alt {
+ --fa: "\f360";
+}
+
+.fa-right-left {
+ --fa: "\f362";
+}
+
+.fa-exchange-alt {
+ --fa: "\f362";
+}
+
+.fa-repeat {
+ --fa: "\f363";
+}
+
+.fa-code-commit {
+ --fa: "\f386";
+}
+
+.fa-code-merge {
+ --fa: "\f387";
+}
+
+.fa-desktop {
+ --fa: "\f390";
+}
+
+.fa-desktop-alt {
+ --fa: "\f390";
+}
+
+.fa-gem {
+ --fa: "\f3a5";
+}
+
+.fa-turn-down {
+ --fa: "\f3be";
+}
+
+.fa-level-down-alt {
+ --fa: "\f3be";
+}
+
+.fa-turn-up {
+ --fa: "\f3bf";
+}
+
+.fa-level-up-alt {
+ --fa: "\f3bf";
+}
+
+.fa-lock-open {
+ --fa: "\f3c1";
+}
+
+.fa-location-dot {
+ --fa: "\f3c5";
+}
+
+.fa-map-marker-alt {
+ --fa: "\f3c5";
+}
+
+.fa-microphone-lines {
+ --fa: "\f3c9";
+}
+
+.fa-microphone-alt {
+ --fa: "\f3c9";
+}
+
+.fa-mobile-screen-button {
+ --fa: "\f3cd";
+}
+
+.fa-mobile-alt {
+ --fa: "\f3cd";
+}
+
+.fa-mobile {
+ --fa: "\f3ce";
+}
+
+.fa-mobile-android {
+ --fa: "\f3ce";
+}
+
+.fa-mobile-phone {
+ --fa: "\f3ce";
+}
+
+.fa-mobile-screen {
+ --fa: "\f3cf";
+}
+
+.fa-mobile-android-alt {
+ --fa: "\f3cf";
+}
+
+.fa-money-bill-1 {
+ --fa: "\f3d1";
+}
+
+.fa-money-bill-alt {
+ --fa: "\f3d1";
+}
+
+.fa-phone-slash {
+ --fa: "\f3dd";
+}
+
+.fa-image-portrait {
+ --fa: "\f3e0";
+}
+
+.fa-portrait {
+ --fa: "\f3e0";
+}
+
+.fa-reply {
+ --fa: "\f3e5";
+}
+
+.fa-mail-reply {
+ --fa: "\f3e5";
+}
+
+.fa-shield-halved {
+ --fa: "\f3ed";
+}
+
+.fa-shield-alt {
+ --fa: "\f3ed";
+}
+
+.fa-tablet-screen-button {
+ --fa: "\f3fa";
+}
+
+.fa-tablet-alt {
+ --fa: "\f3fa";
+}
+
+.fa-tablet {
+ --fa: "\f3fb";
+}
+
+.fa-tablet-android {
+ --fa: "\f3fb";
+}
+
+.fa-ticket-simple {
+ --fa: "\f3ff";
+}
+
+.fa-ticket-alt {
+ --fa: "\f3ff";
+}
+
+.fa-rectangle-xmark {
+ --fa: "\f410";
+}
+
+.fa-rectangle-times {
+ --fa: "\f410";
+}
+
+.fa-times-rectangle {
+ --fa: "\f410";
+}
+
+.fa-window-close {
+ --fa: "\f410";
+}
+
+.fa-down-left-and-up-right-to-center {
+ --fa: "\f422";
+}
+
+.fa-compress-alt {
+ --fa: "\f422";
+}
+
+.fa-up-right-and-down-left-from-center {
+ --fa: "\f424";
+}
+
+.fa-expand-alt {
+ --fa: "\f424";
+}
+
+.fa-baseball-bat-ball {
+ --fa: "\f432";
+}
+
+.fa-baseball {
+ --fa: "\f433";
+}
+
+.fa-baseball-ball {
+ --fa: "\f433";
+}
+
+.fa-basketball {
+ --fa: "\f434";
+}
+
+.fa-basketball-ball {
+ --fa: "\f434";
+}
+
+.fa-bowling-ball {
+ --fa: "\f436";
+}
+
+.fa-chess {
+ --fa: "\f439";
+}
+
+.fa-chess-bishop {
+ --fa: "\f43a";
+}
+
+.fa-chess-board {
+ --fa: "\f43c";
+}
+
+.fa-chess-king {
+ --fa: "\f43f";
+}
+
+.fa-chess-knight {
+ --fa: "\f441";
+}
+
+.fa-chess-pawn {
+ --fa: "\f443";
+}
+
+.fa-chess-queen {
+ --fa: "\f445";
+}
+
+.fa-chess-rook {
+ --fa: "\f447";
+}
+
+.fa-dumbbell {
+ --fa: "\f44b";
+}
+
+.fa-football {
+ --fa: "\f44e";
+}
+
+.fa-football-ball {
+ --fa: "\f44e";
+}
+
+.fa-golf-ball-tee {
+ --fa: "\f450";
+}
+
+.fa-golf-ball {
+ --fa: "\f450";
+}
+
+.fa-hockey-puck {
+ --fa: "\f453";
+}
+
+.fa-broom-ball {
+ --fa: "\f458";
+}
+
+.fa-quidditch {
+ --fa: "\f458";
+}
+
+.fa-quidditch-broom-ball {
+ --fa: "\f458";
+}
+
+.fa-square-full {
+ --fa: "\f45c";
+}
+
+.fa-table-tennis-paddle-ball {
+ --fa: "\f45d";
+}
+
+.fa-ping-pong-paddle-ball {
+ --fa: "\f45d";
+}
+
+.fa-table-tennis {
+ --fa: "\f45d";
+}
+
+.fa-volleyball {
+ --fa: "\f45f";
+}
+
+.fa-volleyball-ball {
+ --fa: "\f45f";
+}
+
+.fa-hand-dots {
+ --fa: "\f461";
+}
+
+.fa-allergies {
+ --fa: "\f461";
+}
+
+.fa-bandage {
+ --fa: "\f462";
+}
+
+.fa-band-aid {
+ --fa: "\f462";
+}
+
+.fa-box {
+ --fa: "\f466";
+}
+
+.fa-boxes-stacked {
+ --fa: "\f468";
+}
+
+.fa-boxes {
+ --fa: "\f468";
+}
+
+.fa-boxes-alt {
+ --fa: "\f468";
+}
+
+.fa-briefcase-medical {
+ --fa: "\f469";
+}
+
+.fa-fire-flame-simple {
+ --fa: "\f46a";
+}
+
+.fa-burn {
+ --fa: "\f46a";
+}
+
+.fa-capsules {
+ --fa: "\f46b";
+}
+
+.fa-clipboard-check {
+ --fa: "\f46c";
+}
+
+.fa-clipboard-list {
+ --fa: "\f46d";
+}
+
+.fa-person-dots-from-line {
+ --fa: "\f470";
+}
+
+.fa-diagnoses {
+ --fa: "\f470";
+}
+
+.fa-dna {
+ --fa: "\f471";
+}
+
+.fa-dolly {
+ --fa: "\f472";
+}
+
+.fa-dolly-box {
+ --fa: "\f472";
+}
+
+.fa-cart-flatbed {
+ --fa: "\f474";
+}
+
+.fa-dolly-flatbed {
+ --fa: "\f474";
+}
+
+.fa-file-medical {
+ --fa: "\f477";
+}
+
+.fa-file-waveform {
+ --fa: "\f478";
+}
+
+.fa-file-medical-alt {
+ --fa: "\f478";
+}
+
+.fa-kit-medical {
+ --fa: "\f479";
+}
+
+.fa-first-aid {
+ --fa: "\f479";
+}
+
+.fa-circle-h {
+ --fa: "\f47e";
+}
+
+.fa-hospital-symbol {
+ --fa: "\f47e";
+}
+
+.fa-id-card-clip {
+ --fa: "\f47f";
+}
+
+.fa-id-card-alt {
+ --fa: "\f47f";
+}
+
+.fa-notes-medical {
+ --fa: "\f481";
+}
+
+.fa-pallet {
+ --fa: "\f482";
+}
+
+.fa-pills {
+ --fa: "\f484";
+}
+
+.fa-prescription-bottle {
+ --fa: "\f485";
+}
+
+.fa-prescription-bottle-medical {
+ --fa: "\f486";
+}
+
+.fa-prescription-bottle-alt {
+ --fa: "\f486";
+}
+
+.fa-bed-pulse {
+ --fa: "\f487";
+}
+
+.fa-procedures {
+ --fa: "\f487";
+}
+
+.fa-truck-fast {
+ --fa: "\f48b";
+}
+
+.fa-shipping-fast {
+ --fa: "\f48b";
+}
+
+.fa-smoking {
+ --fa: "\f48d";
+}
+
+.fa-syringe {
+ --fa: "\f48e";
+}
+
+.fa-tablets {
+ --fa: "\f490";
+}
+
+.fa-thermometer {
+ --fa: "\f491";
+}
+
+.fa-vial {
+ --fa: "\f492";
+}
+
+.fa-vials {
+ --fa: "\f493";
+}
+
+.fa-warehouse {
+ --fa: "\f494";
+}
+
+.fa-weight-scale {
+ --fa: "\f496";
+}
+
+.fa-weight {
+ --fa: "\f496";
+}
+
+.fa-x-ray {
+ --fa: "\f497";
+}
+
+.fa-box-open {
+ --fa: "\f49e";
+}
+
+.fa-comment-dots {
+ --fa: "\f4ad";
+}
+
+.fa-commenting {
+ --fa: "\f4ad";
+}
+
+.fa-comment-slash {
+ --fa: "\f4b3";
+}
+
+.fa-couch {
+ --fa: "\f4b8";
+}
+
+.fa-circle-dollar-to-slot {
+ --fa: "\f4b9";
+}
+
+.fa-donate {
+ --fa: "\f4b9";
+}
+
+.fa-dove {
+ --fa: "\f4ba";
+}
+
+.fa-hand-holding {
+ --fa: "\f4bd";
+}
+
+.fa-hand-holding-heart {
+ --fa: "\f4be";
+}
+
+.fa-hand-holding-dollar {
+ --fa: "\f4c0";
+}
+
+.fa-hand-holding-usd {
+ --fa: "\f4c0";
+}
+
+.fa-hand-holding-droplet {
+ --fa: "\f4c1";
+}
+
+.fa-hand-holding-water {
+ --fa: "\f4c1";
+}
+
+.fa-hands-holding {
+ --fa: "\f4c2";
+}
+
+.fa-handshake-angle {
+ --fa: "\f4c4";
+}
+
+.fa-hands-helping {
+ --fa: "\f4c4";
+}
+
+.fa-parachute-box {
+ --fa: "\f4cd";
+}
+
+.fa-people-carry-box {
+ --fa: "\f4ce";
+}
+
+.fa-people-carry {
+ --fa: "\f4ce";
+}
+
+.fa-piggy-bank {
+ --fa: "\f4d3";
+}
+
+.fa-ribbon {
+ --fa: "\f4d6";
+}
+
+.fa-route {
+ --fa: "\f4d7";
+}
+
+.fa-seedling {
+ --fa: "\f4d8";
+}
+
+.fa-sprout {
+ --fa: "\f4d8";
+}
+
+.fa-sign-hanging {
+ --fa: "\f4d9";
+}
+
+.fa-sign {
+ --fa: "\f4d9";
+}
+
+.fa-face-smile-wink {
+ --fa: "\f4da";
+}
+
+.fa-smile-wink {
+ --fa: "\f4da";
+}
+
+.fa-tape {
+ --fa: "\f4db";
+}
+
+.fa-truck-ramp-box {
+ --fa: "\f4de";
+}
+
+.fa-truck-loading {
+ --fa: "\f4de";
+}
+
+.fa-truck-moving {
+ --fa: "\f4df";
+}
+
+.fa-video-slash {
+ --fa: "\f4e2";
+}
+
+.fa-wine-glass {
+ --fa: "\f4e3";
+}
+
+.fa-user-astronaut {
+ --fa: "\f4fb";
+}
+
+.fa-user-check {
+ --fa: "\f4fc";
+}
+
+.fa-user-clock {
+ --fa: "\f4fd";
+}
+
+.fa-user-gear {
+ --fa: "\f4fe";
+}
+
+.fa-user-cog {
+ --fa: "\f4fe";
+}
+
+.fa-user-pen {
+ --fa: "\f4ff";
+}
+
+.fa-user-edit {
+ --fa: "\f4ff";
+}
+
+.fa-user-group {
+ --fa: "\f500";
+}
+
+.fa-user-friends {
+ --fa: "\f500";
+}
+
+.fa-user-graduate {
+ --fa: "\f501";
+}
+
+.fa-user-lock {
+ --fa: "\f502";
+}
+
+.fa-user-minus {
+ --fa: "\f503";
+}
+
+.fa-user-ninja {
+ --fa: "\f504";
+}
+
+.fa-user-shield {
+ --fa: "\f505";
+}
+
+.fa-user-slash {
+ --fa: "\f506";
+}
+
+.fa-user-alt-slash {
+ --fa: "\f506";
+}
+
+.fa-user-large-slash {
+ --fa: "\f506";
+}
+
+.fa-user-tag {
+ --fa: "\f507";
+}
+
+.fa-user-tie {
+ --fa: "\f508";
+}
+
+.fa-users-gear {
+ --fa: "\f509";
+}
+
+.fa-users-cog {
+ --fa: "\f509";
+}
+
+.fa-scale-unbalanced {
+ --fa: "\f515";
+}
+
+.fa-balance-scale-left {
+ --fa: "\f515";
+}
+
+.fa-scale-unbalanced-flip {
+ --fa: "\f516";
+}
+
+.fa-balance-scale-right {
+ --fa: "\f516";
+}
+
+.fa-blender {
+ --fa: "\f517";
+}
+
+.fa-book-open {
+ --fa: "\f518";
+}
+
+.fa-tower-broadcast {
+ --fa: "\f519";
+}
+
+.fa-broadcast-tower {
+ --fa: "\f519";
+}
+
+.fa-broom {
+ --fa: "\f51a";
+}
+
+.fa-chalkboard {
+ --fa: "\f51b";
+}
+
+.fa-blackboard {
+ --fa: "\f51b";
+}
+
+.fa-chalkboard-user {
+ --fa: "\f51c";
+}
+
+.fa-chalkboard-teacher {
+ --fa: "\f51c";
+}
+
+.fa-church {
+ --fa: "\f51d";
+}
+
+.fa-coins {
+ --fa: "\f51e";
+}
+
+.fa-compact-disc {
+ --fa: "\f51f";
+}
+
+.fa-crow {
+ --fa: "\f520";
+}
+
+.fa-crown {
+ --fa: "\f521";
+}
+
+.fa-dice {
+ --fa: "\f522";
+}
+
+.fa-dice-five {
+ --fa: "\f523";
+}
+
+.fa-dice-four {
+ --fa: "\f524";
+}
+
+.fa-dice-one {
+ --fa: "\f525";
+}
+
+.fa-dice-six {
+ --fa: "\f526";
+}
+
+.fa-dice-three {
+ --fa: "\f527";
+}
+
+.fa-dice-two {
+ --fa: "\f528";
+}
+
+.fa-divide {
+ --fa: "\f529";
+}
+
+.fa-door-closed {
+ --fa: "\f52a";
+}
+
+.fa-door-open {
+ --fa: "\f52b";
+}
+
+.fa-feather {
+ --fa: "\f52d";
+}
+
+.fa-frog {
+ --fa: "\f52e";
+}
+
+.fa-gas-pump {
+ --fa: "\f52f";
+}
+
+.fa-glasses {
+ --fa: "\f530";
+}
+
+.fa-greater-than-equal {
+ --fa: "\f532";
+}
+
+.fa-helicopter {
+ --fa: "\f533";
+}
+
+.fa-infinity {
+ --fa: "\f534";
+}
+
+.fa-kiwi-bird {
+ --fa: "\f535";
+}
+
+.fa-less-than-equal {
+ --fa: "\f537";
+}
+
+.fa-memory {
+ --fa: "\f538";
+}
+
+.fa-microphone-lines-slash {
+ --fa: "\f539";
+}
+
+.fa-microphone-alt-slash {
+ --fa: "\f539";
+}
+
+.fa-money-bill-wave {
+ --fa: "\f53a";
+}
+
+.fa-money-bill-1-wave {
+ --fa: "\f53b";
+}
+
+.fa-money-bill-wave-alt {
+ --fa: "\f53b";
+}
+
+.fa-money-check {
+ --fa: "\f53c";
+}
+
+.fa-money-check-dollar {
+ --fa: "\f53d";
+}
+
+.fa-money-check-alt {
+ --fa: "\f53d";
+}
+
+.fa-not-equal {
+ --fa: "\f53e";
+}
+
+.fa-palette {
+ --fa: "\f53f";
+}
+
+.fa-square-parking {
+ --fa: "\f540";
+}
+
+.fa-parking {
+ --fa: "\f540";
+}
+
+.fa-diagram-project {
+ --fa: "\f542";
+}
+
+.fa-project-diagram {
+ --fa: "\f542";
+}
+
+.fa-receipt {
+ --fa: "\f543";
+}
+
+.fa-robot {
+ --fa: "\f544";
+}
+
+.fa-ruler {
+ --fa: "\f545";
+}
+
+.fa-ruler-combined {
+ --fa: "\f546";
+}
+
+.fa-ruler-horizontal {
+ --fa: "\f547";
+}
+
+.fa-ruler-vertical {
+ --fa: "\f548";
+}
+
+.fa-school {
+ --fa: "\f549";
+}
+
+.fa-screwdriver {
+ --fa: "\f54a";
+}
+
+.fa-shoe-prints {
+ --fa: "\f54b";
+}
+
+.fa-skull {
+ --fa: "\f54c";
+}
+
+.fa-ban-smoking {
+ --fa: "\f54d";
+}
+
+.fa-smoking-ban {
+ --fa: "\f54d";
+}
+
+.fa-store {
+ --fa: "\f54e";
+}
+
+.fa-shop {
+ --fa: "\f54f";
+}
+
+.fa-store-alt {
+ --fa: "\f54f";
+}
+
+.fa-bars-staggered {
+ --fa: "\f550";
+}
+
+.fa-reorder {
+ --fa: "\f550";
+}
+
+.fa-stream {
+ --fa: "\f550";
+}
+
+.fa-stroopwafel {
+ --fa: "\f551";
+}
+
+.fa-toolbox {
+ --fa: "\f552";
+}
+
+.fa-shirt {
+ --fa: "\f553";
+}
+
+.fa-t-shirt {
+ --fa: "\f553";
+}
+
+.fa-tshirt {
+ --fa: "\f553";
+}
+
+.fa-person-walking {
+ --fa: "\f554";
+}
+
+.fa-walking {
+ --fa: "\f554";
+}
+
+.fa-wallet {
+ --fa: "\f555";
+}
+
+.fa-face-angry {
+ --fa: "\f556";
+}
+
+.fa-angry {
+ --fa: "\f556";
+}
+
+.fa-archway {
+ --fa: "\f557";
+}
+
+.fa-book-atlas {
+ --fa: "\f558";
+}
+
+.fa-atlas {
+ --fa: "\f558";
+}
+
+.fa-award {
+ --fa: "\f559";
+}
+
+.fa-delete-left {
+ --fa: "\f55a";
+}
+
+.fa-backspace {
+ --fa: "\f55a";
+}
+
+.fa-bezier-curve {
+ --fa: "\f55b";
+}
+
+.fa-bong {
+ --fa: "\f55c";
+}
+
+.fa-brush {
+ --fa: "\f55d";
+}
+
+.fa-bus-simple {
+ --fa: "\f55e";
+}
+
+.fa-bus-alt {
+ --fa: "\f55e";
+}
+
+.fa-cannabis {
+ --fa: "\f55f";
+}
+
+.fa-check-double {
+ --fa: "\f560";
+}
+
+.fa-martini-glass-citrus {
+ --fa: "\f561";
+}
+
+.fa-cocktail {
+ --fa: "\f561";
+}
+
+.fa-bell-concierge {
+ --fa: "\f562";
+}
+
+.fa-concierge-bell {
+ --fa: "\f562";
+}
+
+.fa-cookie {
+ --fa: "\f563";
+}
+
+.fa-cookie-bite {
+ --fa: "\f564";
+}
+
+.fa-crop-simple {
+ --fa: "\f565";
+}
+
+.fa-crop-alt {
+ --fa: "\f565";
+}
+
+.fa-tachograph-digital {
+ --fa: "\f566";
+}
+
+.fa-digital-tachograph {
+ --fa: "\f566";
+}
+
+.fa-face-dizzy {
+ --fa: "\f567";
+}
+
+.fa-dizzy {
+ --fa: "\f567";
+}
+
+.fa-compass-drafting {
+ --fa: "\f568";
+}
+
+.fa-drafting-compass {
+ --fa: "\f568";
+}
+
+.fa-drum {
+ --fa: "\f569";
+}
+
+.fa-drum-steelpan {
+ --fa: "\f56a";
+}
+
+.fa-feather-pointed {
+ --fa: "\f56b";
+}
+
+.fa-feather-alt {
+ --fa: "\f56b";
+}
+
+.fa-file-contract {
+ --fa: "\f56c";
+}
+
+.fa-file-arrow-down {
+ --fa: "\f56d";
+}
+
+.fa-file-download {
+ --fa: "\f56d";
+}
+
+.fa-file-export {
+ --fa: "\f56e";
+}
+
+.fa-arrow-right-from-file {
+ --fa: "\f56e";
+}
+
+.fa-file-import {
+ --fa: "\f56f";
+}
+
+.fa-arrow-right-to-file {
+ --fa: "\f56f";
+}
+
+.fa-file-invoice {
+ --fa: "\f570";
+}
+
+.fa-file-invoice-dollar {
+ --fa: "\f571";
+}
+
+.fa-file-prescription {
+ --fa: "\f572";
+}
+
+.fa-file-signature {
+ --fa: "\f573";
+}
+
+.fa-file-arrow-up {
+ --fa: "\f574";
+}
+
+.fa-file-upload {
+ --fa: "\f574";
+}
+
+.fa-fill {
+ --fa: "\f575";
+}
+
+.fa-fill-drip {
+ --fa: "\f576";
+}
+
+.fa-fingerprint {
+ --fa: "\f577";
+}
+
+.fa-fish {
+ --fa: "\f578";
+}
+
+.fa-face-flushed {
+ --fa: "\f579";
+}
+
+.fa-flushed {
+ --fa: "\f579";
+}
+
+.fa-face-frown-open {
+ --fa: "\f57a";
+}
+
+.fa-frown-open {
+ --fa: "\f57a";
+}
+
+.fa-martini-glass {
+ --fa: "\f57b";
+}
+
+.fa-glass-martini-alt {
+ --fa: "\f57b";
+}
+
+.fa-earth-africa {
+ --fa: "\f57c";
+}
+
+.fa-globe-africa {
+ --fa: "\f57c";
+}
+
+.fa-earth-americas {
+ --fa: "\f57d";
+}
+
+.fa-earth {
+ --fa: "\f57d";
+}
+
+.fa-earth-america {
+ --fa: "\f57d";
+}
+
+.fa-globe-americas {
+ --fa: "\f57d";
+}
+
+.fa-earth-asia {
+ --fa: "\f57e";
+}
+
+.fa-globe-asia {
+ --fa: "\f57e";
+}
+
+.fa-face-grimace {
+ --fa: "\f57f";
+}
+
+.fa-grimace {
+ --fa: "\f57f";
+}
+
+.fa-face-grin {
+ --fa: "\f580";
+}
+
+.fa-grin {
+ --fa: "\f580";
+}
+
+.fa-face-grin-wide {
+ --fa: "\f581";
+}
+
+.fa-grin-alt {
+ --fa: "\f581";
+}
+
+.fa-face-grin-beam {
+ --fa: "\f582";
+}
+
+.fa-grin-beam {
+ --fa: "\f582";
+}
+
+.fa-face-grin-beam-sweat {
+ --fa: "\f583";
+}
+
+.fa-grin-beam-sweat {
+ --fa: "\f583";
+}
+
+.fa-face-grin-hearts {
+ --fa: "\f584";
+}
+
+.fa-grin-hearts {
+ --fa: "\f584";
+}
+
+.fa-face-grin-squint {
+ --fa: "\f585";
+}
+
+.fa-grin-squint {
+ --fa: "\f585";
+}
+
+.fa-face-grin-squint-tears {
+ --fa: "\f586";
+}
+
+.fa-grin-squint-tears {
+ --fa: "\f586";
+}
+
+.fa-face-grin-stars {
+ --fa: "\f587";
+}
+
+.fa-grin-stars {
+ --fa: "\f587";
+}
+
+.fa-face-grin-tears {
+ --fa: "\f588";
+}
+
+.fa-grin-tears {
+ --fa: "\f588";
+}
+
+.fa-face-grin-tongue {
+ --fa: "\f589";
+}
+
+.fa-grin-tongue {
+ --fa: "\f589";
+}
+
+.fa-face-grin-tongue-squint {
+ --fa: "\f58a";
+}
+
+.fa-grin-tongue-squint {
+ --fa: "\f58a";
+}
+
+.fa-face-grin-tongue-wink {
+ --fa: "\f58b";
+}
+
+.fa-grin-tongue-wink {
+ --fa: "\f58b";
+}
+
+.fa-face-grin-wink {
+ --fa: "\f58c";
+}
+
+.fa-grin-wink {
+ --fa: "\f58c";
+}
+
+.fa-grip {
+ --fa: "\f58d";
+}
+
+.fa-grid-horizontal {
+ --fa: "\f58d";
+}
+
+.fa-grip-horizontal {
+ --fa: "\f58d";
+}
+
+.fa-grip-vertical {
+ --fa: "\f58e";
+}
+
+.fa-grid-vertical {
+ --fa: "\f58e";
+}
+
+.fa-headset {
+ --fa: "\f590";
+}
+
+.fa-highlighter {
+ --fa: "\f591";
+}
+
+.fa-hot-tub-person {
+ --fa: "\f593";
+}
+
+.fa-hot-tub {
+ --fa: "\f593";
+}
+
+.fa-hotel {
+ --fa: "\f594";
+}
+
+.fa-joint {
+ --fa: "\f595";
+}
+
+.fa-face-kiss {
+ --fa: "\f596";
+}
+
+.fa-kiss {
+ --fa: "\f596";
+}
+
+.fa-face-kiss-beam {
+ --fa: "\f597";
+}
+
+.fa-kiss-beam {
+ --fa: "\f597";
+}
+
+.fa-face-kiss-wink-heart {
+ --fa: "\f598";
+}
+
+.fa-kiss-wink-heart {
+ --fa: "\f598";
+}
+
+.fa-face-laugh {
+ --fa: "\f599";
+}
+
+.fa-laugh {
+ --fa: "\f599";
+}
+
+.fa-face-laugh-beam {
+ --fa: "\f59a";
+}
+
+.fa-laugh-beam {
+ --fa: "\f59a";
+}
+
+.fa-face-laugh-squint {
+ --fa: "\f59b";
+}
+
+.fa-laugh-squint {
+ --fa: "\f59b";
+}
+
+.fa-face-laugh-wink {
+ --fa: "\f59c";
+}
+
+.fa-laugh-wink {
+ --fa: "\f59c";
+}
+
+.fa-cart-flatbed-suitcase {
+ --fa: "\f59d";
+}
+
+.fa-luggage-cart {
+ --fa: "\f59d";
+}
+
+.fa-map-location {
+ --fa: "\f59f";
+}
+
+.fa-map-marked {
+ --fa: "\f59f";
+}
+
+.fa-map-location-dot {
+ --fa: "\f5a0";
+}
+
+.fa-map-marked-alt {
+ --fa: "\f5a0";
+}
+
+.fa-marker {
+ --fa: "\f5a1";
+}
+
+.fa-medal {
+ --fa: "\f5a2";
+}
+
+.fa-face-meh-blank {
+ --fa: "\f5a4";
+}
+
+.fa-meh-blank {
+ --fa: "\f5a4";
+}
+
+.fa-face-rolling-eyes {
+ --fa: "\f5a5";
+}
+
+.fa-meh-rolling-eyes {
+ --fa: "\f5a5";
+}
+
+.fa-monument {
+ --fa: "\f5a6";
+}
+
+.fa-mortar-pestle {
+ --fa: "\f5a7";
+}
+
+.fa-paint-roller {
+ --fa: "\f5aa";
+}
+
+.fa-passport {
+ --fa: "\f5ab";
+}
+
+.fa-pen-fancy {
+ --fa: "\f5ac";
+}
+
+.fa-pen-nib {
+ --fa: "\f5ad";
+}
+
+.fa-pen-ruler {
+ --fa: "\f5ae";
+}
+
+.fa-pencil-ruler {
+ --fa: "\f5ae";
+}
+
+.fa-plane-arrival {
+ --fa: "\f5af";
+}
+
+.fa-plane-departure {
+ --fa: "\f5b0";
+}
+
+.fa-prescription {
+ --fa: "\f5b1";
+}
+
+.fa-face-sad-cry {
+ --fa: "\f5b3";
+}
+
+.fa-sad-cry {
+ --fa: "\f5b3";
+}
+
+.fa-face-sad-tear {
+ --fa: "\f5b4";
+}
+
+.fa-sad-tear {
+ --fa: "\f5b4";
+}
+
+.fa-van-shuttle {
+ --fa: "\f5b6";
+}
+
+.fa-shuttle-van {
+ --fa: "\f5b6";
+}
+
+.fa-signature {
+ --fa: "\f5b7";
+}
+
+.fa-face-smile-beam {
+ --fa: "\f5b8";
+}
+
+.fa-smile-beam {
+ --fa: "\f5b8";
+}
+
+.fa-solar-panel {
+ --fa: "\f5ba";
+}
+
+.fa-spa {
+ --fa: "\f5bb";
+}
+
+.fa-splotch {
+ --fa: "\f5bc";
+}
+
+.fa-spray-can {
+ --fa: "\f5bd";
+}
+
+.fa-stamp {
+ --fa: "\f5bf";
+}
+
+.fa-star-half-stroke {
+ --fa: "\f5c0";
+}
+
+.fa-star-half-alt {
+ --fa: "\f5c0";
+}
+
+.fa-suitcase-rolling {
+ --fa: "\f5c1";
+}
+
+.fa-face-surprise {
+ --fa: "\f5c2";
+}
+
+.fa-surprise {
+ --fa: "\f5c2";
+}
+
+.fa-swatchbook {
+ --fa: "\f5c3";
+}
+
+.fa-person-swimming {
+ --fa: "\f5c4";
+}
+
+.fa-swimmer {
+ --fa: "\f5c4";
+}
+
+.fa-water-ladder {
+ --fa: "\f5c5";
+}
+
+.fa-ladder-water {
+ --fa: "\f5c5";
+}
+
+.fa-swimming-pool {
+ --fa: "\f5c5";
+}
+
+.fa-droplet-slash {
+ --fa: "\f5c7";
+}
+
+.fa-tint-slash {
+ --fa: "\f5c7";
+}
+
+.fa-face-tired {
+ --fa: "\f5c8";
+}
+
+.fa-tired {
+ --fa: "\f5c8";
+}
+
+.fa-tooth {
+ --fa: "\f5c9";
+}
+
+.fa-umbrella-beach {
+ --fa: "\f5ca";
+}
+
+.fa-weight-hanging {
+ --fa: "\f5cd";
+}
+
+.fa-wine-glass-empty {
+ --fa: "\f5ce";
+}
+
+.fa-wine-glass-alt {
+ --fa: "\f5ce";
+}
+
+.fa-spray-can-sparkles {
+ --fa: "\f5d0";
+}
+
+.fa-air-freshener {
+ --fa: "\f5d0";
+}
+
+.fa-apple-whole {
+ --fa: "\f5d1";
+}
+
+.fa-apple-alt {
+ --fa: "\f5d1";
+}
+
+.fa-atom {
+ --fa: "\f5d2";
+}
+
+.fa-bone {
+ --fa: "\f5d7";
+}
+
+.fa-book-open-reader {
+ --fa: "\f5da";
+}
+
+.fa-book-reader {
+ --fa: "\f5da";
+}
+
+.fa-brain {
+ --fa: "\f5dc";
+}
+
+.fa-car-rear {
+ --fa: "\f5de";
+}
+
+.fa-car-alt {
+ --fa: "\f5de";
+}
+
+.fa-car-battery {
+ --fa: "\f5df";
+}
+
+.fa-battery-car {
+ --fa: "\f5df";
+}
+
+.fa-car-burst {
+ --fa: "\f5e1";
+}
+
+.fa-car-crash {
+ --fa: "\f5e1";
+}
+
+.fa-car-side {
+ --fa: "\f5e4";
+}
+
+.fa-charging-station {
+ --fa: "\f5e7";
+}
+
+.fa-diamond-turn-right {
+ --fa: "\f5eb";
+}
+
+.fa-directions {
+ --fa: "\f5eb";
+}
+
+.fa-draw-polygon {
+ --fa: "\f5ee";
+}
+
+.fa-vector-polygon {
+ --fa: "\f5ee";
+}
+
+.fa-laptop-code {
+ --fa: "\f5fc";
+}
+
+.fa-layer-group {
+ --fa: "\f5fd";
+}
+
+.fa-location-crosshairs {
+ --fa: "\f601";
+}
+
+.fa-location {
+ --fa: "\f601";
+}
+
+.fa-lungs {
+ --fa: "\f604";
+}
+
+.fa-microscope {
+ --fa: "\f610";
+}
+
+.fa-oil-can {
+ --fa: "\f613";
+}
+
+.fa-poop {
+ --fa: "\f619";
+}
+
+.fa-shapes {
+ --fa: "\f61f";
+}
+
+.fa-triangle-circle-square {
+ --fa: "\f61f";
+}
+
+.fa-star-of-life {
+ --fa: "\f621";
+}
+
+.fa-gauge {
+ --fa: "\f624";
+}
+
+.fa-dashboard {
+ --fa: "\f624";
+}
+
+.fa-gauge-med {
+ --fa: "\f624";
+}
+
+.fa-tachometer-alt-average {
+ --fa: "\f624";
+}
+
+.fa-gauge-high {
+ --fa: "\f625";
+}
+
+.fa-tachometer-alt {
+ --fa: "\f625";
+}
+
+.fa-tachometer-alt-fast {
+ --fa: "\f625";
+}
+
+.fa-gauge-simple {
+ --fa: "\f629";
+}
+
+.fa-gauge-simple-med {
+ --fa: "\f629";
+}
+
+.fa-tachometer-average {
+ --fa: "\f629";
+}
+
+.fa-gauge-simple-high {
+ --fa: "\f62a";
+}
+
+.fa-tachometer {
+ --fa: "\f62a";
+}
+
+.fa-tachometer-fast {
+ --fa: "\f62a";
+}
+
+.fa-teeth {
+ --fa: "\f62e";
+}
+
+.fa-teeth-open {
+ --fa: "\f62f";
+}
+
+.fa-masks-theater {
+ --fa: "\f630";
+}
+
+.fa-theater-masks {
+ --fa: "\f630";
+}
+
+.fa-traffic-light {
+ --fa: "\f637";
+}
+
+.fa-truck-monster {
+ --fa: "\f63b";
+}
+
+.fa-truck-pickup {
+ --fa: "\f63c";
+}
+
+.fa-rectangle-ad {
+ --fa: "\f641";
+}
+
+.fa-ad {
+ --fa: "\f641";
+}
+
+.fa-ankh {
+ --fa: "\f644";
+}
+
+.fa-book-bible {
+ --fa: "\f647";
+}
+
+.fa-bible {
+ --fa: "\f647";
+}
+
+.fa-business-time {
+ --fa: "\f64a";
+}
+
+.fa-briefcase-clock {
+ --fa: "\f64a";
+}
+
+.fa-city {
+ --fa: "\f64f";
+}
+
+.fa-comment-dollar {
+ --fa: "\f651";
+}
+
+.fa-comments-dollar {
+ --fa: "\f653";
+}
+
+.fa-cross {
+ --fa: "\f654";
+}
+
+.fa-dharmachakra {
+ --fa: "\f655";
+}
+
+.fa-envelope-open-text {
+ --fa: "\f658";
+}
+
+.fa-folder-minus {
+ --fa: "\f65d";
+}
+
+.fa-folder-plus {
+ --fa: "\f65e";
+}
+
+.fa-filter-circle-dollar {
+ --fa: "\f662";
+}
+
+.fa-funnel-dollar {
+ --fa: "\f662";
+}
+
+.fa-gopuram {
+ --fa: "\f664";
+}
+
+.fa-hamsa {
+ --fa: "\f665";
+}
+
+.fa-bahai {
+ --fa: "\f666";
+}
+
+.fa-haykal {
+ --fa: "\f666";
+}
+
+.fa-jedi {
+ --fa: "\f669";
+}
+
+.fa-book-journal-whills {
+ --fa: "\f66a";
+}
+
+.fa-journal-whills {
+ --fa: "\f66a";
+}
+
+.fa-kaaba {
+ --fa: "\f66b";
+}
+
+.fa-khanda {
+ --fa: "\f66d";
+}
+
+.fa-landmark {
+ --fa: "\f66f";
+}
+
+.fa-envelopes-bulk {
+ --fa: "\f674";
+}
+
+.fa-mail-bulk {
+ --fa: "\f674";
+}
+
+.fa-menorah {
+ --fa: "\f676";
+}
+
+.fa-mosque {
+ --fa: "\f678";
+}
+
+.fa-om {
+ --fa: "\f679";
+}
+
+.fa-spaghetti-monster-flying {
+ --fa: "\f67b";
+}
+
+.fa-pastafarianism {
+ --fa: "\f67b";
+}
+
+.fa-peace {
+ --fa: "\f67c";
+}
+
+.fa-place-of-worship {
+ --fa: "\f67f";
+}
+
+.fa-square-poll-vertical {
+ --fa: "\f681";
+}
+
+.fa-poll {
+ --fa: "\f681";
+}
+
+.fa-square-poll-horizontal {
+ --fa: "\f682";
+}
+
+.fa-poll-h {
+ --fa: "\f682";
+}
+
+.fa-person-praying {
+ --fa: "\f683";
+}
+
+.fa-pray {
+ --fa: "\f683";
+}
+
+.fa-hands-praying {
+ --fa: "\f684";
+}
+
+.fa-praying-hands {
+ --fa: "\f684";
+}
+
+.fa-book-quran {
+ --fa: "\f687";
+}
+
+.fa-quran {
+ --fa: "\f687";
+}
+
+.fa-magnifying-glass-dollar {
+ --fa: "\f688";
+}
+
+.fa-search-dollar {
+ --fa: "\f688";
+}
+
+.fa-magnifying-glass-location {
+ --fa: "\f689";
+}
+
+.fa-search-location {
+ --fa: "\f689";
+}
+
+.fa-socks {
+ --fa: "\f696";
+}
+
+.fa-square-root-variable {
+ --fa: "\f698";
+}
+
+.fa-square-root-alt {
+ --fa: "\f698";
+}
+
+.fa-star-and-crescent {
+ --fa: "\f699";
+}
+
+.fa-star-of-david {
+ --fa: "\f69a";
+}
+
+.fa-synagogue {
+ --fa: "\f69b";
+}
+
+.fa-scroll-torah {
+ --fa: "\f6a0";
+}
+
+.fa-torah {
+ --fa: "\f6a0";
+}
+
+.fa-torii-gate {
+ --fa: "\f6a1";
+}
+
+.fa-vihara {
+ --fa: "\f6a7";
+}
+
+.fa-volume-xmark {
+ --fa: "\f6a9";
+}
+
+.fa-volume-mute {
+ --fa: "\f6a9";
+}
+
+.fa-volume-times {
+ --fa: "\f6a9";
+}
+
+.fa-yin-yang {
+ --fa: "\f6ad";
+}
+
+.fa-blender-phone {
+ --fa: "\f6b6";
+}
+
+.fa-book-skull {
+ --fa: "\f6b7";
+}
+
+.fa-book-dead {
+ --fa: "\f6b7";
+}
+
+.fa-campground {
+ --fa: "\f6bb";
+}
+
+.fa-cat {
+ --fa: "\f6be";
+}
+
+.fa-chair {
+ --fa: "\f6c0";
+}
+
+.fa-cloud-moon {
+ --fa: "\f6c3";
+}
+
+.fa-cloud-sun {
+ --fa: "\f6c4";
+}
+
+.fa-cow {
+ --fa: "\f6c8";
+}
+
+.fa-dice-d20 {
+ --fa: "\f6cf";
+}
+
+.fa-dice-d6 {
+ --fa: "\f6d1";
+}
+
+.fa-dog {
+ --fa: "\f6d3";
+}
+
+.fa-dragon {
+ --fa: "\f6d5";
+}
+
+.fa-drumstick-bite {
+ --fa: "\f6d7";
+}
+
+.fa-dungeon {
+ --fa: "\f6d9";
+}
+
+.fa-file-csv {
+ --fa: "\f6dd";
+}
+
+.fa-hand-fist {
+ --fa: "\f6de";
+}
+
+.fa-fist-raised {
+ --fa: "\f6de";
+}
+
+.fa-ghost {
+ --fa: "\f6e2";
+}
+
+.fa-hammer {
+ --fa: "\f6e3";
+}
+
+.fa-hanukiah {
+ --fa: "\f6e6";
+}
+
+.fa-hat-wizard {
+ --fa: "\f6e8";
+}
+
+.fa-person-hiking {
+ --fa: "\f6ec";
+}
+
+.fa-hiking {
+ --fa: "\f6ec";
+}
+
+.fa-hippo {
+ --fa: "\f6ed";
+}
+
+.fa-horse {
+ --fa: "\f6f0";
+}
+
+.fa-house-chimney-crack {
+ --fa: "\f6f1";
+}
+
+.fa-house-damage {
+ --fa: "\f6f1";
+}
+
+.fa-hryvnia-sign {
+ --fa: "\f6f2";
+}
+
+.fa-hryvnia {
+ --fa: "\f6f2";
+}
+
+.fa-mask {
+ --fa: "\f6fa";
+}
+
+.fa-mountain {
+ --fa: "\f6fc";
+}
+
+.fa-network-wired {
+ --fa: "\f6ff";
+}
+
+.fa-otter {
+ --fa: "\f700";
+}
+
+.fa-ring {
+ --fa: "\f70b";
+}
+
+.fa-person-running {
+ --fa: "\f70c";
+}
+
+.fa-running {
+ --fa: "\f70c";
+}
+
+.fa-scroll {
+ --fa: "\f70e";
+}
+
+.fa-skull-crossbones {
+ --fa: "\f714";
+}
+
+.fa-slash {
+ --fa: "\f715";
+}
+
+.fa-spider {
+ --fa: "\f717";
+}
+
+.fa-toilet-paper {
+ --fa: "\f71e";
+}
+
+.fa-toilet-paper-alt {
+ --fa: "\f71e";
+}
+
+.fa-toilet-paper-blank {
+ --fa: "\f71e";
+}
+
+.fa-tractor {
+ --fa: "\f722";
+}
+
+.fa-user-injured {
+ --fa: "\f728";
+}
+
+.fa-vr-cardboard {
+ --fa: "\f729";
+}
+
+.fa-wand-sparkles {
+ --fa: "\f72b";
+}
+
+.fa-wind {
+ --fa: "\f72e";
+}
+
+.fa-wine-bottle {
+ --fa: "\f72f";
+}
+
+.fa-cloud-meatball {
+ --fa: "\f73b";
+}
+
+.fa-cloud-moon-rain {
+ --fa: "\f73c";
+}
+
+.fa-cloud-rain {
+ --fa: "\f73d";
+}
+
+.fa-cloud-showers-heavy {
+ --fa: "\f740";
+}
+
+.fa-cloud-sun-rain {
+ --fa: "\f743";
+}
+
+.fa-democrat {
+ --fa: "\f747";
+}
+
+.fa-flag-usa {
+ --fa: "\f74d";
+}
+
+.fa-hurricane {
+ --fa: "\f751";
+}
+
+.fa-landmark-dome {
+ --fa: "\f752";
+}
+
+.fa-landmark-alt {
+ --fa: "\f752";
+}
+
+.fa-meteor {
+ --fa: "\f753";
+}
+
+.fa-person-booth {
+ --fa: "\f756";
+}
+
+.fa-poo-storm {
+ --fa: "\f75a";
+}
+
+.fa-poo-bolt {
+ --fa: "\f75a";
+}
+
+.fa-rainbow {
+ --fa: "\f75b";
+}
+
+.fa-republican {
+ --fa: "\f75e";
+}
+
+.fa-smog {
+ --fa: "\f75f";
+}
+
+.fa-temperature-high {
+ --fa: "\f769";
+}
+
+.fa-temperature-low {
+ --fa: "\f76b";
+}
+
+.fa-cloud-bolt {
+ --fa: "\f76c";
+}
+
+.fa-thunderstorm {
+ --fa: "\f76c";
+}
+
+.fa-tornado {
+ --fa: "\f76f";
+}
+
+.fa-volcano {
+ --fa: "\f770";
+}
+
+.fa-check-to-slot {
+ --fa: "\f772";
+}
+
+.fa-vote-yea {
+ --fa: "\f772";
+}
+
+.fa-water {
+ --fa: "\f773";
+}
+
+.fa-baby {
+ --fa: "\f77c";
+}
+
+.fa-baby-carriage {
+ --fa: "\f77d";
+}
+
+.fa-carriage-baby {
+ --fa: "\f77d";
+}
+
+.fa-biohazard {
+ --fa: "\f780";
+}
+
+.fa-blog {
+ --fa: "\f781";
+}
+
+.fa-calendar-day {
+ --fa: "\f783";
+}
+
+.fa-calendar-week {
+ --fa: "\f784";
+}
+
+.fa-candy-cane {
+ --fa: "\f786";
+}
+
+.fa-carrot {
+ --fa: "\f787";
+}
+
+.fa-cash-register {
+ --fa: "\f788";
+}
+
+.fa-minimize {
+ --fa: "\f78c";
+}
+
+.fa-compress-arrows-alt {
+ --fa: "\f78c";
+}
+
+.fa-dumpster {
+ --fa: "\f793";
+}
+
+.fa-dumpster-fire {
+ --fa: "\f794";
+}
+
+.fa-ethernet {
+ --fa: "\f796";
+}
+
+.fa-gifts {
+ --fa: "\f79c";
+}
+
+.fa-champagne-glasses {
+ --fa: "\f79f";
+}
+
+.fa-glass-cheers {
+ --fa: "\f79f";
+}
+
+.fa-whiskey-glass {
+ --fa: "\f7a0";
+}
+
+.fa-glass-whiskey {
+ --fa: "\f7a0";
+}
+
+.fa-earth-europe {
+ --fa: "\f7a2";
+}
+
+.fa-globe-europe {
+ --fa: "\f7a2";
+}
+
+.fa-grip-lines {
+ --fa: "\f7a4";
+}
+
+.fa-grip-lines-vertical {
+ --fa: "\f7a5";
+}
+
+.fa-guitar {
+ --fa: "\f7a6";
+}
+
+.fa-heart-crack {
+ --fa: "\f7a9";
+}
+
+.fa-heart-broken {
+ --fa: "\f7a9";
+}
+
+.fa-holly-berry {
+ --fa: "\f7aa";
+}
+
+.fa-horse-head {
+ --fa: "\f7ab";
+}
+
+.fa-icicles {
+ --fa: "\f7ad";
+}
+
+.fa-igloo {
+ --fa: "\f7ae";
+}
+
+.fa-mitten {
+ --fa: "\f7b5";
+}
+
+.fa-mug-hot {
+ --fa: "\f7b6";
+}
+
+.fa-radiation {
+ --fa: "\f7b9";
+}
+
+.fa-circle-radiation {
+ --fa: "\f7ba";
+}
+
+.fa-radiation-alt {
+ --fa: "\f7ba";
+}
+
+.fa-restroom {
+ --fa: "\f7bd";
+}
+
+.fa-satellite {
+ --fa: "\f7bf";
+}
+
+.fa-satellite-dish {
+ --fa: "\f7c0";
+}
+
+.fa-sd-card {
+ --fa: "\f7c2";
+}
+
+.fa-sim-card {
+ --fa: "\f7c4";
+}
+
+.fa-person-skating {
+ --fa: "\f7c5";
+}
+
+.fa-skating {
+ --fa: "\f7c5";
+}
+
+.fa-person-skiing {
+ --fa: "\f7c9";
+}
+
+.fa-skiing {
+ --fa: "\f7c9";
+}
+
+.fa-person-skiing-nordic {
+ --fa: "\f7ca";
+}
+
+.fa-skiing-nordic {
+ --fa: "\f7ca";
+}
+
+.fa-sleigh {
+ --fa: "\f7cc";
+}
+
+.fa-comment-sms {
+ --fa: "\f7cd";
+}
+
+.fa-sms {
+ --fa: "\f7cd";
+}
+
+.fa-person-snowboarding {
+ --fa: "\f7ce";
+}
+
+.fa-snowboarding {
+ --fa: "\f7ce";
+}
+
+.fa-snowman {
+ --fa: "\f7d0";
+}
+
+.fa-snowplow {
+ --fa: "\f7d2";
+}
+
+.fa-tenge-sign {
+ --fa: "\f7d7";
+}
+
+.fa-tenge {
+ --fa: "\f7d7";
+}
+
+.fa-toilet {
+ --fa: "\f7d8";
+}
+
+.fa-screwdriver-wrench {
+ --fa: "\f7d9";
+}
+
+.fa-tools {
+ --fa: "\f7d9";
+}
+
+.fa-cable-car {
+ --fa: "\f7da";
+}
+
+.fa-tram {
+ --fa: "\f7da";
+}
+
+.fa-fire-flame-curved {
+ --fa: "\f7e4";
+}
+
+.fa-fire-alt {
+ --fa: "\f7e4";
+}
+
+.fa-bacon {
+ --fa: "\f7e5";
+}
+
+.fa-book-medical {
+ --fa: "\f7e6";
+}
+
+.fa-bread-slice {
+ --fa: "\f7ec";
+}
+
+.fa-cheese {
+ --fa: "\f7ef";
+}
+
+.fa-house-chimney-medical {
+ --fa: "\f7f2";
+}
+
+.fa-clinic-medical {
+ --fa: "\f7f2";
+}
+
+.fa-clipboard-user {
+ --fa: "\f7f3";
+}
+
+.fa-comment-medical {
+ --fa: "\f7f5";
+}
+
+.fa-crutch {
+ --fa: "\f7f7";
+}
+
+.fa-disease {
+ --fa: "\f7fa";
+}
+
+.fa-egg {
+ --fa: "\f7fb";
+}
+
+.fa-folder-tree {
+ --fa: "\f802";
+}
+
+.fa-burger {
+ --fa: "\f805";
+}
+
+.fa-hamburger {
+ --fa: "\f805";
+}
+
+.fa-hand-middle-finger {
+ --fa: "\f806";
+}
+
+.fa-helmet-safety {
+ --fa: "\f807";
+}
+
+.fa-hard-hat {
+ --fa: "\f807";
+}
+
+.fa-hat-hard {
+ --fa: "\f807";
+}
+
+.fa-hospital-user {
+ --fa: "\f80d";
+}
+
+.fa-hotdog {
+ --fa: "\f80f";
+}
+
+.fa-ice-cream {
+ --fa: "\f810";
+}
+
+.fa-laptop-medical {
+ --fa: "\f812";
+}
+
+.fa-pager {
+ --fa: "\f815";
+}
+
+.fa-pepper-hot {
+ --fa: "\f816";
+}
+
+.fa-pizza-slice {
+ --fa: "\f818";
+}
+
+.fa-sack-dollar {
+ --fa: "\f81d";
+}
+
+.fa-book-tanakh {
+ --fa: "\f827";
+}
+
+.fa-tanakh {
+ --fa: "\f827";
+}
+
+.fa-bars-progress {
+ --fa: "\f828";
+}
+
+.fa-tasks-alt {
+ --fa: "\f828";
+}
+
+.fa-trash-arrow-up {
+ --fa: "\f829";
+}
+
+.fa-trash-restore {
+ --fa: "\f829";
+}
+
+.fa-trash-can-arrow-up {
+ --fa: "\f82a";
+}
+
+.fa-trash-restore-alt {
+ --fa: "\f82a";
+}
+
+.fa-user-nurse {
+ --fa: "\f82f";
+}
+
+.fa-wave-square {
+ --fa: "\f83e";
+}
+
+.fa-person-biking {
+ --fa: "\f84a";
+}
+
+.fa-biking {
+ --fa: "\f84a";
+}
+
+.fa-border-all {
+ --fa: "\f84c";
+}
+
+.fa-border-none {
+ --fa: "\f850";
+}
+
+.fa-border-top-left {
+ --fa: "\f853";
+}
+
+.fa-border-style {
+ --fa: "\f853";
+}
+
+.fa-person-digging {
+ --fa: "\f85e";
+}
+
+.fa-digging {
+ --fa: "\f85e";
+}
+
+.fa-fan {
+ --fa: "\f863";
+}
+
+.fa-icons {
+ --fa: "\f86d";
+}
+
+.fa-heart-music-camera-bolt {
+ --fa: "\f86d";
+}
+
+.fa-phone-flip {
+ --fa: "\f879";
+}
+
+.fa-phone-alt {
+ --fa: "\f879";
+}
+
+.fa-square-phone-flip {
+ --fa: "\f87b";
+}
+
+.fa-phone-square-alt {
+ --fa: "\f87b";
+}
+
+.fa-photo-film {
+ --fa: "\f87c";
+}
+
+.fa-photo-video {
+ --fa: "\f87c";
+}
+
+.fa-text-slash {
+ --fa: "\f87d";
+}
+
+.fa-remove-format {
+ --fa: "\f87d";
+}
+
+.fa-arrow-down-z-a {
+ --fa: "\f881";
+}
+
+.fa-sort-alpha-desc {
+ --fa: "\f881";
+}
+
+.fa-sort-alpha-down-alt {
+ --fa: "\f881";
+}
+
+.fa-arrow-up-z-a {
+ --fa: "\f882";
+}
+
+.fa-sort-alpha-up-alt {
+ --fa: "\f882";
+}
+
+.fa-arrow-down-short-wide {
+ --fa: "\f884";
+}
+
+.fa-sort-amount-desc {
+ --fa: "\f884";
+}
+
+.fa-sort-amount-down-alt {
+ --fa: "\f884";
+}
+
+.fa-arrow-up-short-wide {
+ --fa: "\f885";
+}
+
+.fa-sort-amount-up-alt {
+ --fa: "\f885";
+}
+
+.fa-arrow-down-9-1 {
+ --fa: "\f886";
+}
+
+.fa-sort-numeric-desc {
+ --fa: "\f886";
+}
+
+.fa-sort-numeric-down-alt {
+ --fa: "\f886";
+}
+
+.fa-arrow-up-9-1 {
+ --fa: "\f887";
+}
+
+.fa-sort-numeric-up-alt {
+ --fa: "\f887";
+}
+
+.fa-spell-check {
+ --fa: "\f891";
+}
+
+.fa-voicemail {
+ --fa: "\f897";
+}
+
+.fa-hat-cowboy {
+ --fa: "\f8c0";
+}
+
+.fa-hat-cowboy-side {
+ --fa: "\f8c1";
+}
+
+.fa-computer-mouse {
+ --fa: "\f8cc";
+}
+
+.fa-mouse {
+ --fa: "\f8cc";
+}
+
+.fa-radio {
+ --fa: "\f8d7";
+}
+
+.fa-record-vinyl {
+ --fa: "\f8d9";
+}
+
+.fa-walkie-talkie {
+ --fa: "\f8ef";
+}
+
+.fa-caravan {
+ --fa: "\f8ff";
+}
diff --git a/src/media/vendor/fa7free/css/fontawesome.min.css b/src/media/vendor/fa7free/css/fontawesome.min.css
new file mode 100644
index 0000000..c7924a7
--- /dev/null
+++ b/src/media/vendor/fa7free/css/fontawesome.min.css
@@ -0,0 +1,8 @@
+/*!
+ * Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ * Copyright 2025 Fonticons, Inc.
+ */
+.fa,.fa-brands,.fa-classic,.fa-regular,.fa-solid,.fab,.far,.fas{--_fa-family:var(--fa-family,var(--fa-style-family,"Font Awesome 7 Free"));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:var(--fa-display,inline-block);font-family:var(--_fa-family);font-feature-settings:normal;font-style:normal;font-synthesis:none;font-variant:normal;font-weight:var(--fa-style,900);line-height:1;text-align:center;text-rendering:auto;width:var(--fa-width,1.25em)}:is(.fas,.far,.fab,.fa-solid,.fa-regular,.fa-brands,.fa-classic,.fa):before{content:var(--fa)/""}@supports not (content:""/""){:is(.fas,.far,.fab,.fa-solid,.fa-regular,.fa-brands,.fa-classic,.fa):before{content:var(--fa)}}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.08333em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.07143em;vertical-align:.05357em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.04167em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-width-auto{--fa-width:auto}.fa-fw,.fa-width-fixed{--fa-width:1.25em}.fa-ul{list-style-type:none;margin-inline-start:var(--fa-li-margin,2.5em);padding-inline-start:0}.fa-ul>li{position:relative}.fa-li{inset-inline-start:calc(var(--fa-li-width, 2em)*-1);position:absolute;text-align:center;width:var(--fa-li-width,2em);line-height:inherit}.fa-border{border-radius:var(--fa-border-radius,.1em);border:var(--fa-border-width,.0625em) var(--fa-border-style,solid) var(--fa-border-color,#eee);box-sizing:var(--fa-border-box-sizing,content-box);padding:var(--fa-border-padding,.1875em .25em)}.fa-pull-left,.fa-pull-start{float:inline-start;margin-inline-end:var(--fa-pull-margin,.3em)}.fa-pull-end,.fa-pull-right{float:inline-end;margin-inline-start:var(--fa-pull-margin,.3em)}.fa-beat{animation-name:fa-beat;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{animation-name:fa-bounce;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{animation-name:fa-fade;animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade,.fa-fade{animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s)}.fa-beat-fade{animation-name:fa-beat-fade;animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{animation-name:fa-flip;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{animation-name:fa-shake;animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,linear)}.fa-shake,.fa-spin{animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal)}.fa-spin{animation-name:fa-spin;animation-duration:var(--fa-animation-duration,2s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{animation-name:fa-spin;animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,steps(8))}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{animation:none!important;transition:none!important}}@keyframes fa-beat{0%,90%{transform:scale(1)}45%{transform:scale(var(--fa-beat-scale,1.25))}}@keyframes fa-bounce{0%{transform:scale(1) translateY(0)}10%{transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em))}64%{transform:scale(1) translateY(0)}to{transform:scale(1) translateY(0)}}@keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@keyframes fa-beat-fade{0%,to{opacity:var(--fa-beat-fade-opacity,.4);transform:scale(1)}50%{opacity:1;transform:scale(var(--fa-beat-fade-scale,1.125))}}@keyframes fa-flip{50%{transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@keyframes fa-shake{0%{transform:rotate(-15deg)}4%{transform:rotate(15deg)}8%,24%{transform:rotate(-18deg)}12%,28%{transform:rotate(18deg)}16%{transform:rotate(-22deg)}20%{transform:rotate(22deg)}32%{transform:rotate(-12deg)}36%{transform:rotate(12deg)}40%,to{transform:rotate(0deg)}}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{transform:rotate(90deg)}.fa-rotate-180{transform:rotate(180deg)}.fa-rotate-270{transform:rotate(270deg)}.fa-flip-horizontal{transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}.fa-rotate-by{transform:rotate(var(--fa-rotate-angle,0))}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{--fa-width:100%;inset:0;position:absolute;text-align:center;width:var(--fa-width);z-index:var(--fa-stack-z-index,auto)}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:var(--fa-inverse,#fff)}
+
+.fa-0{--fa:"\30 "}.fa-1{--fa:"\31 "}.fa-2{--fa:"\32 "}.fa-3{--fa:"\33 "}.fa-4{--fa:"\34 "}.fa-5{--fa:"\35 "}.fa-6{--fa:"\36 "}.fa-7{--fa:"\37 "}.fa-8{--fa:"\38 "}.fa-9{--fa:"\39 "}.fa-exclamation{--fa:"\!"}.fa-hashtag{--fa:"\#"}.fa-dollar,.fa-dollar-sign,.fa-usd{--fa:"\$"}.fa-percent,.fa-percentage{--fa:"\%"}.fa-asterisk{--fa:"\*"}.fa-add,.fa-plus{--fa:"\+"}.fa-less-than{--fa:"\<"}.fa-equals{--fa:"\="}.fa-greater-than{--fa:"\>"}.fa-question{--fa:"\?"}.fa-at{--fa:"\@"}.fa-a{--fa:"A"}.fa-b{--fa:"B"}.fa-c{--fa:"C"}.fa-d{--fa:"D"}.fa-e{--fa:"E"}.fa-f{--fa:"F"}.fa-g{--fa:"G"}.fa-h{--fa:"H"}.fa-i{--fa:"I"}.fa-j{--fa:"J"}.fa-k{--fa:"K"}.fa-l{--fa:"L"}.fa-m{--fa:"M"}.fa-n{--fa:"N"}.fa-o{--fa:"O"}.fa-p{--fa:"P"}.fa-q{--fa:"Q"}.fa-r{--fa:"R"}.fa-s{--fa:"S"}.fa-t{--fa:"T"}.fa-u{--fa:"U"}.fa-v{--fa:"V"}.fa-w{--fa:"W"}.fa-x{--fa:"X"}.fa-y{--fa:"Y"}.fa-z{--fa:"Z"}.fa-faucet{--fa:"\e005"}.fa-faucet-drip{--fa:"\e006"}.fa-house-chimney-window{--fa:"\e00d"}.fa-house-signal{--fa:"\e012"}.fa-temperature-arrow-down,.fa-temperature-down{--fa:"\e03f"}.fa-temperature-arrow-up,.fa-temperature-up{--fa:"\e040"}.fa-trailer{--fa:"\e041"}.fa-bacteria{--fa:"\e059"}.fa-bacterium{--fa:"\e05a"}.fa-box-tissue{--fa:"\e05b"}.fa-hand-holding-medical{--fa:"\e05c"}.fa-hand-sparkles{--fa:"\e05d"}.fa-hands-bubbles,.fa-hands-wash{--fa:"\e05e"}.fa-handshake-alt-slash,.fa-handshake-simple-slash,.fa-handshake-slash{--fa:"\e060"}.fa-head-side-cough{--fa:"\e061"}.fa-head-side-cough-slash{--fa:"\e062"}.fa-head-side-mask{--fa:"\e063"}.fa-head-side-virus{--fa:"\e064"}.fa-house-chimney-user{--fa:"\e065"}.fa-house-laptop,.fa-laptop-house{--fa:"\e066"}.fa-lungs-virus{--fa:"\e067"}.fa-people-arrows,.fa-people-arrows-left-right{--fa:"\e068"}.fa-plane-slash{--fa:"\e069"}.fa-pump-medical{--fa:"\e06a"}.fa-pump-soap{--fa:"\e06b"}.fa-shield-virus{--fa:"\e06c"}.fa-sink{--fa:"\e06d"}.fa-soap{--fa:"\e06e"}.fa-stopwatch-20{--fa:"\e06f"}.fa-shop-slash,.fa-store-alt-slash{--fa:"\e070"}.fa-store-slash{--fa:"\e071"}.fa-toilet-paper-slash{--fa:"\e072"}.fa-users-slash{--fa:"\e073"}.fa-virus{--fa:"\e074"}.fa-virus-slash{--fa:"\e075"}.fa-viruses{--fa:"\e076"}.fa-vest{--fa:"\e085"}.fa-vest-patches{--fa:"\e086"}.fa-arrow-trend-down{--fa:"\e097"}.fa-arrow-trend-up{--fa:"\e098"}.fa-arrow-up-from-bracket{--fa:"\e09a"}.fa-austral-sign{--fa:"\e0a9"}.fa-baht-sign{--fa:"\e0ac"}.fa-bitcoin-sign{--fa:"\e0b4"}.fa-bolt-lightning{--fa:"\e0b7"}.fa-book-bookmark{--fa:"\e0bb"}.fa-camera-rotate{--fa:"\e0d8"}.fa-cedi-sign{--fa:"\e0df"}.fa-chart-column{--fa:"\e0e3"}.fa-chart-gantt{--fa:"\e0e4"}.fa-clapperboard{--fa:"\e131"}.fa-clover{--fa:"\e139"}.fa-code-compare{--fa:"\e13a"}.fa-code-fork{--fa:"\e13b"}.fa-code-pull-request{--fa:"\e13c"}.fa-colon-sign{--fa:"\e140"}.fa-cruzeiro-sign{--fa:"\e152"}.fa-display{--fa:"\e163"}.fa-dong-sign{--fa:"\e169"}.fa-elevator{--fa:"\e16d"}.fa-filter-circle-xmark{--fa:"\e17b"}.fa-florin-sign{--fa:"\e184"}.fa-folder-closed{--fa:"\e185"}.fa-franc-sign{--fa:"\e18f"}.fa-guarani-sign{--fa:"\e19a"}.fa-gun{--fa:"\e19b"}.fa-hands-clapping{--fa:"\e1a8"}.fa-home-user,.fa-house-user{--fa:"\e1b0"}.fa-indian-rupee,.fa-indian-rupee-sign,.fa-inr{--fa:"\e1bc"}.fa-kip-sign{--fa:"\e1c4"}.fa-lari-sign{--fa:"\e1c8"}.fa-litecoin-sign{--fa:"\e1d3"}.fa-manat-sign{--fa:"\e1d5"}.fa-mask-face{--fa:"\e1d7"}.fa-mill-sign{--fa:"\e1ed"}.fa-money-bills{--fa:"\e1f3"}.fa-naira-sign{--fa:"\e1f6"}.fa-notdef{--fa:"\e1fe"}.fa-panorama{--fa:"\e209"}.fa-peseta-sign{--fa:"\e221"}.fa-peso-sign{--fa:"\e222"}.fa-plane-up{--fa:"\e22d"}.fa-rupiah-sign{--fa:"\e23d"}.fa-stairs{--fa:"\e289"}.fa-timeline{--fa:"\e29c"}.fa-truck-front{--fa:"\e2b7"}.fa-try,.fa-turkish-lira,.fa-turkish-lira-sign{--fa:"\e2bb"}.fa-vault{--fa:"\e2c5"}.fa-magic-wand-sparkles,.fa-wand-magic-sparkles{--fa:"\e2ca"}.fa-wheat-alt,.fa-wheat-awn{--fa:"\e2cd"}.fa-wheelchair-alt,.fa-wheelchair-move{--fa:"\e2ce"}.fa-bangladeshi-taka-sign{--fa:"\e2e6"}.fa-bowl-rice{--fa:"\e2eb"}.fa-person-pregnant{--fa:"\e31e"}.fa-home-lg,.fa-house-chimney{--fa:"\e3af"}.fa-house-crack{--fa:"\e3b1"}.fa-house-medical{--fa:"\e3b2"}.fa-cent-sign{--fa:"\e3f5"}.fa-plus-minus{--fa:"\e43c"}.fa-sailboat{--fa:"\e445"}.fa-section{--fa:"\e447"}.fa-shrimp{--fa:"\e448"}.fa-brazilian-real-sign{--fa:"\e46c"}.fa-chart-simple{--fa:"\e473"}.fa-diagram-next{--fa:"\e476"}.fa-diagram-predecessor{--fa:"\e477"}.fa-diagram-successor{--fa:"\e47a"}.fa-earth-oceania,.fa-globe-oceania{--fa:"\e47b"}.fa-bug-slash{--fa:"\e490"}.fa-file-circle-plus{--fa:"\e494"}.fa-shop-lock{--fa:"\e4a5"}.fa-virus-covid{--fa:"\e4a8"}.fa-virus-covid-slash{--fa:"\e4a9"}.fa-anchor-circle-check{--fa:"\e4aa"}.fa-anchor-circle-exclamation{--fa:"\e4ab"}.fa-anchor-circle-xmark{--fa:"\e4ac"}.fa-anchor-lock{--fa:"\e4ad"}.fa-arrow-down-up-across-line{--fa:"\e4af"}.fa-arrow-down-up-lock{--fa:"\e4b0"}.fa-arrow-right-to-city{--fa:"\e4b3"}.fa-arrow-up-from-ground-water{--fa:"\e4b5"}.fa-arrow-up-from-water-pump{--fa:"\e4b6"}.fa-arrow-up-right-dots{--fa:"\e4b7"}.fa-arrows-down-to-line{--fa:"\e4b8"}.fa-arrows-down-to-people{--fa:"\e4b9"}.fa-arrows-left-right-to-line{--fa:"\e4ba"}.fa-arrows-spin{--fa:"\e4bb"}.fa-arrows-split-up-and-left{--fa:"\e4bc"}.fa-arrows-to-circle{--fa:"\e4bd"}.fa-arrows-to-dot{--fa:"\e4be"}.fa-arrows-to-eye{--fa:"\e4bf"}.fa-arrows-turn-right{--fa:"\e4c0"}.fa-arrows-turn-to-dots{--fa:"\e4c1"}.fa-arrows-up-to-line{--fa:"\e4c2"}.fa-bore-hole{--fa:"\e4c3"}.fa-bottle-droplet{--fa:"\e4c4"}.fa-bottle-water{--fa:"\e4c5"}.fa-bowl-food{--fa:"\e4c6"}.fa-boxes-packing{--fa:"\e4c7"}.fa-bridge{--fa:"\e4c8"}.fa-bridge-circle-check{--fa:"\e4c9"}.fa-bridge-circle-exclamation{--fa:"\e4ca"}.fa-bridge-circle-xmark{--fa:"\e4cb"}.fa-bridge-lock{--fa:"\e4cc"}.fa-bridge-water{--fa:"\e4ce"}.fa-bucket{--fa:"\e4cf"}.fa-bugs{--fa:"\e4d0"}.fa-building-circle-arrow-right{--fa:"\e4d1"}.fa-building-circle-check{--fa:"\e4d2"}.fa-building-circle-exclamation{--fa:"\e4d3"}.fa-building-circle-xmark{--fa:"\e4d4"}.fa-building-flag{--fa:"\e4d5"}.fa-building-lock{--fa:"\e4d6"}.fa-building-ngo{--fa:"\e4d7"}.fa-building-shield{--fa:"\e4d8"}.fa-building-un{--fa:"\e4d9"}.fa-building-user{--fa:"\e4da"}.fa-building-wheat{--fa:"\e4db"}.fa-burst{--fa:"\e4dc"}.fa-car-on{--fa:"\e4dd"}.fa-car-tunnel{--fa:"\e4de"}.fa-child-combatant,.fa-child-rifle{--fa:"\e4e0"}.fa-children{--fa:"\e4e1"}.fa-circle-nodes{--fa:"\e4e2"}.fa-clipboard-question{--fa:"\e4e3"}.fa-cloud-showers-water{--fa:"\e4e4"}.fa-computer{--fa:"\e4e5"}.fa-cubes-stacked{--fa:"\e4e6"}.fa-envelope-circle-check{--fa:"\e4e8"}.fa-explosion{--fa:"\e4e9"}.fa-ferry{--fa:"\e4ea"}.fa-file-circle-exclamation{--fa:"\e4eb"}.fa-file-circle-minus{--fa:"\e4ed"}.fa-file-circle-question{--fa:"\e4ef"}.fa-file-shield{--fa:"\e4f0"}.fa-fire-burner{--fa:"\e4f1"}.fa-fish-fins{--fa:"\e4f2"}.fa-flask-vial{--fa:"\e4f3"}.fa-glass-water{--fa:"\e4f4"}.fa-glass-water-droplet{--fa:"\e4f5"}.fa-group-arrows-rotate{--fa:"\e4f6"}.fa-hand-holding-hand{--fa:"\e4f7"}.fa-handcuffs{--fa:"\e4f8"}.fa-hands-bound{--fa:"\e4f9"}.fa-hands-holding-child{--fa:"\e4fa"}.fa-hands-holding-circle{--fa:"\e4fb"}.fa-heart-circle-bolt{--fa:"\e4fc"}.fa-heart-circle-check{--fa:"\e4fd"}.fa-heart-circle-exclamation{--fa:"\e4fe"}.fa-heart-circle-minus{--fa:"\e4ff"}.fa-heart-circle-plus{--fa:"\e500"}.fa-heart-circle-xmark{--fa:"\e501"}.fa-helicopter-symbol{--fa:"\e502"}.fa-helmet-un{--fa:"\e503"}.fa-hill-avalanche{--fa:"\e507"}.fa-hill-rockslide{--fa:"\e508"}.fa-house-circle-check{--fa:"\e509"}.fa-house-circle-exclamation{--fa:"\e50a"}.fa-house-circle-xmark{--fa:"\e50b"}.fa-house-fire{--fa:"\e50c"}.fa-house-flag{--fa:"\e50d"}.fa-house-flood-water{--fa:"\e50e"}.fa-house-flood-water-circle-arrow-right{--fa:"\e50f"}.fa-house-lock{--fa:"\e510"}.fa-house-medical-circle-check{--fa:"\e511"}.fa-house-medical-circle-exclamation{--fa:"\e512"}.fa-house-medical-circle-xmark{--fa:"\e513"}.fa-house-medical-flag{--fa:"\e514"}.fa-house-tsunami{--fa:"\e515"}.fa-jar{--fa:"\e516"}.fa-jar-wheat{--fa:"\e517"}.fa-jet-fighter-up{--fa:"\e518"}.fa-jug-detergent{--fa:"\e519"}.fa-kitchen-set{--fa:"\e51a"}.fa-land-mine-on{--fa:"\e51b"}.fa-landmark-flag{--fa:"\e51c"}.fa-laptop-file{--fa:"\e51d"}.fa-lines-leaning{--fa:"\e51e"}.fa-location-pin-lock{--fa:"\e51f"}.fa-locust{--fa:"\e520"}.fa-magnifying-glass-arrow-right{--fa:"\e521"}.fa-magnifying-glass-chart{--fa:"\e522"}.fa-mars-and-venus-burst{--fa:"\e523"}.fa-mask-ventilator{--fa:"\e524"}.fa-mattress-pillow{--fa:"\e525"}.fa-mobile-retro{--fa:"\e527"}.fa-money-bill-transfer{--fa:"\e528"}.fa-money-bill-trend-up{--fa:"\e529"}.fa-money-bill-wheat{--fa:"\e52a"}.fa-mosquito{--fa:"\e52b"}.fa-mosquito-net{--fa:"\e52c"}.fa-mound{--fa:"\e52d"}.fa-mountain-city{--fa:"\e52e"}.fa-mountain-sun{--fa:"\e52f"}.fa-oil-well{--fa:"\e532"}.fa-people-group{--fa:"\e533"}.fa-people-line{--fa:"\e534"}.fa-people-pulling{--fa:"\e535"}.fa-people-robbery{--fa:"\e536"}.fa-people-roof{--fa:"\e537"}.fa-person-arrow-down-to-line{--fa:"\e538"}.fa-person-arrow-up-from-line{--fa:"\e539"}.fa-person-breastfeeding{--fa:"\e53a"}.fa-person-burst{--fa:"\e53b"}.fa-person-cane{--fa:"\e53c"}.fa-person-chalkboard{--fa:"\e53d"}.fa-person-circle-check{--fa:"\e53e"}.fa-person-circle-exclamation{--fa:"\e53f"}.fa-person-circle-minus{--fa:"\e540"}.fa-person-circle-plus{--fa:"\e541"}.fa-person-circle-question{--fa:"\e542"}.fa-person-circle-xmark{--fa:"\e543"}.fa-person-dress-burst{--fa:"\e544"}.fa-person-drowning{--fa:"\e545"}.fa-person-falling{--fa:"\e546"}.fa-person-falling-burst{--fa:"\e547"}.fa-person-half-dress{--fa:"\e548"}.fa-person-harassing{--fa:"\e549"}.fa-person-military-pointing{--fa:"\e54a"}.fa-person-military-rifle{--fa:"\e54b"}.fa-person-military-to-person{--fa:"\e54c"}.fa-person-rays{--fa:"\e54d"}.fa-person-rifle{--fa:"\e54e"}.fa-person-shelter{--fa:"\e54f"}.fa-person-walking-arrow-loop-left{--fa:"\e551"}.fa-person-walking-arrow-right{--fa:"\e552"}.fa-person-walking-dashed-line-arrow-right{--fa:"\e553"}.fa-person-walking-luggage{--fa:"\e554"}.fa-plane-circle-check{--fa:"\e555"}.fa-plane-circle-exclamation{--fa:"\e556"}.fa-plane-circle-xmark{--fa:"\e557"}.fa-plane-lock{--fa:"\e558"}.fa-plate-wheat{--fa:"\e55a"}.fa-plug-circle-bolt{--fa:"\e55b"}.fa-plug-circle-check{--fa:"\e55c"}.fa-plug-circle-exclamation{--fa:"\e55d"}.fa-plug-circle-minus{--fa:"\e55e"}.fa-plug-circle-plus{--fa:"\e55f"}.fa-plug-circle-xmark{--fa:"\e560"}.fa-ranking-star{--fa:"\e561"}.fa-road-barrier{--fa:"\e562"}.fa-road-bridge{--fa:"\e563"}.fa-road-circle-check{--fa:"\e564"}.fa-road-circle-exclamation{--fa:"\e565"}.fa-road-circle-xmark{--fa:"\e566"}.fa-road-lock{--fa:"\e567"}.fa-road-spikes{--fa:"\e568"}.fa-rug{--fa:"\e569"}.fa-sack-xmark{--fa:"\e56a"}.fa-school-circle-check{--fa:"\e56b"}.fa-school-circle-exclamation{--fa:"\e56c"}.fa-school-circle-xmark{--fa:"\e56d"}.fa-school-flag{--fa:"\e56e"}.fa-school-lock{--fa:"\e56f"}.fa-sheet-plastic{--fa:"\e571"}.fa-shield-cat{--fa:"\e572"}.fa-shield-dog{--fa:"\e573"}.fa-shield-heart{--fa:"\e574"}.fa-square-nfi{--fa:"\e576"}.fa-square-person-confined{--fa:"\e577"}.fa-square-virus{--fa:"\e578"}.fa-rod-asclepius,.fa-rod-snake,.fa-staff-aesculapius,.fa-staff-snake{--fa:"\e579"}.fa-sun-plant-wilt{--fa:"\e57a"}.fa-tarp{--fa:"\e57b"}.fa-tarp-droplet{--fa:"\e57c"}.fa-tent{--fa:"\e57d"}.fa-tent-arrow-down-to-line{--fa:"\e57e"}.fa-tent-arrow-left-right{--fa:"\e57f"}.fa-tent-arrow-turn-left{--fa:"\e580"}.fa-tent-arrows-down{--fa:"\e581"}.fa-tents{--fa:"\e582"}.fa-toilet-portable{--fa:"\e583"}.fa-toilets-portable{--fa:"\e584"}.fa-tower-cell{--fa:"\e585"}.fa-tower-observation{--fa:"\e586"}.fa-tree-city{--fa:"\e587"}.fa-trowel{--fa:"\e589"}.fa-trowel-bricks{--fa:"\e58a"}.fa-truck-arrow-right{--fa:"\e58b"}.fa-truck-droplet{--fa:"\e58c"}.fa-truck-field{--fa:"\e58d"}.fa-truck-field-un{--fa:"\e58e"}.fa-truck-plane{--fa:"\e58f"}.fa-users-between-lines{--fa:"\e591"}.fa-users-line{--fa:"\e592"}.fa-users-rays{--fa:"\e593"}.fa-users-rectangle{--fa:"\e594"}.fa-users-viewfinder{--fa:"\e595"}.fa-vial-circle-check{--fa:"\e596"}.fa-vial-virus{--fa:"\e597"}.fa-wheat-awn-circle-exclamation{--fa:"\e598"}.fa-worm{--fa:"\e599"}.fa-xmarks-lines{--fa:"\e59a"}.fa-child-dress{--fa:"\e59c"}.fa-child-reaching{--fa:"\e59d"}.fa-file-circle-check{--fa:"\e5a0"}.fa-file-circle-xmark{--fa:"\e5a1"}.fa-person-through-window{--fa:"\e5a9"}.fa-plant-wilt{--fa:"\e5aa"}.fa-stapler{--fa:"\e5af"}.fa-train-tram{--fa:"\e5b4"}.fa-table-cells-column-lock{--fa:"\e678"}.fa-table-cells-row-lock{--fa:"\e67a"}.fa-web-awesome{--fa:"\e682"}.fa-thumb-tack-slash,.fa-thumbtack-slash{--fa:"\e68f"}.fa-table-cells-row-unlock{--fa:"\e691"}.fa-chart-diagram{--fa:"\e695"}.fa-comment-nodes{--fa:"\e696"}.fa-file-fragment{--fa:"\e697"}.fa-file-half-dashed{--fa:"\e698"}.fa-hexagon-nodes{--fa:"\e699"}.fa-hexagon-nodes-bolt{--fa:"\e69a"}.fa-square-binary{--fa:"\e69b"}.fa-pentagon{--fa:"\e790"}.fa-non-binary{--fa:"\e807"}.fa-spiral{--fa:"\e80a"}.fa-mobile-vibrate{--fa:"\e816"}.fa-single-quote-left{--fa:"\e81b"}.fa-single-quote-right{--fa:"\e81c"}.fa-bus-side{--fa:"\e81d"}.fa-heptagon,.fa-septagon{--fa:"\e820"}.fa-glass-martini,.fa-martini-glass-empty{--fa:"\f000"}.fa-music{--fa:"\f001"}.fa-magnifying-glass,.fa-search{--fa:"\f002"}.fa-heart{--fa:"\f004"}.fa-star{--fa:"\f005"}.fa-user,.fa-user-alt,.fa-user-large{--fa:"\f007"}.fa-film,.fa-film-alt,.fa-film-simple{--fa:"\f008"}.fa-table-cells-large,.fa-th-large{--fa:"\f009"}.fa-table-cells,.fa-th{--fa:"\f00a"}.fa-table-list,.fa-th-list{--fa:"\f00b"}.fa-check{--fa:"\f00c"}.fa-close,.fa-multiply,.fa-remove,.fa-times,.fa-xmark{--fa:"\f00d"}.fa-magnifying-glass-plus,.fa-search-plus{--fa:"\f00e"}.fa-magnifying-glass-minus,.fa-search-minus{--fa:"\f010"}.fa-power-off{--fa:"\f011"}.fa-signal,.fa-signal-5,.fa-signal-perfect{--fa:"\f012"}.fa-cog,.fa-gear{--fa:"\f013"}.fa-home,.fa-home-alt,.fa-home-lg-alt,.fa-house{--fa:"\f015"}.fa-clock,.fa-clock-four{--fa:"\f017"}.fa-road{--fa:"\f018"}.fa-download{--fa:"\f019"}.fa-inbox{--fa:"\f01c"}.fa-arrow-right-rotate,.fa-arrow-rotate-forward,.fa-arrow-rotate-right,.fa-redo{--fa:"\f01e"}.fa-arrows-rotate,.fa-refresh,.fa-sync{--fa:"\f021"}.fa-list-alt,.fa-rectangle-list{--fa:"\f022"}.fa-lock{--fa:"\f023"}.fa-flag{--fa:"\f024"}.fa-headphones,.fa-headphones-alt,.fa-headphones-simple{--fa:"\f025"}.fa-volume-off{--fa:"\f026"}.fa-volume-down,.fa-volume-low{--fa:"\f027"}.fa-volume-high,.fa-volume-up{--fa:"\f028"}.fa-qrcode{--fa:"\f029"}.fa-barcode{--fa:"\f02a"}.fa-tag{--fa:"\f02b"}.fa-tags{--fa:"\f02c"}.fa-book{--fa:"\f02d"}.fa-bookmark{--fa:"\f02e"}.fa-print{--fa:"\f02f"}.fa-camera,.fa-camera-alt{--fa:"\f030"}.fa-font{--fa:"\f031"}.fa-bold{--fa:"\f032"}.fa-italic{--fa:"\f033"}.fa-text-height{--fa:"\f034"}.fa-text-width{--fa:"\f035"}.fa-align-left{--fa:"\f036"}.fa-align-center{--fa:"\f037"}.fa-align-right{--fa:"\f038"}.fa-align-justify{--fa:"\f039"}.fa-list,.fa-list-squares{--fa:"\f03a"}.fa-dedent,.fa-outdent{--fa:"\f03b"}.fa-indent{--fa:"\f03c"}.fa-video,.fa-video-camera{--fa:"\f03d"}.fa-image{--fa:"\f03e"}.fa-location-pin,.fa-map-marker{--fa:"\f041"}.fa-adjust,.fa-circle-half-stroke{--fa:"\f042"}.fa-droplet,.fa-tint{--fa:"\f043"}.fa-edit,.fa-pen-to-square{--fa:"\f044"}.fa-arrows,.fa-arrows-up-down-left-right{--fa:"\f047"}.fa-backward-step,.fa-step-backward{--fa:"\f048"}.fa-backward-fast,.fa-fast-backward{--fa:"\f049"}.fa-backward{--fa:"\f04a"}.fa-play{--fa:"\f04b"}.fa-pause{--fa:"\f04c"}.fa-stop{--fa:"\f04d"}.fa-forward{--fa:"\f04e"}.fa-fast-forward,.fa-forward-fast{--fa:"\f050"}.fa-forward-step,.fa-step-forward{--fa:"\f051"}.fa-eject{--fa:"\f052"}.fa-chevron-left{--fa:"\f053"}.fa-chevron-right{--fa:"\f054"}.fa-circle-plus,.fa-plus-circle{--fa:"\f055"}.fa-circle-minus,.fa-minus-circle{--fa:"\f056"}.fa-circle-xmark,.fa-times-circle,.fa-xmark-circle{--fa:"\f057"}.fa-check-circle,.fa-circle-check{--fa:"\f058"}.fa-circle-question,.fa-question-circle{--fa:"\f059"}.fa-circle-info,.fa-info-circle{--fa:"\f05a"}.fa-crosshairs{--fa:"\f05b"}.fa-ban,.fa-cancel{--fa:"\f05e"}.fa-arrow-left{--fa:"\f060"}.fa-arrow-right{--fa:"\f061"}.fa-arrow-up{--fa:"\f062"}.fa-arrow-down{--fa:"\f063"}.fa-mail-forward,.fa-share{--fa:"\f064"}.fa-expand{--fa:"\f065"}.fa-compress{--fa:"\f066"}.fa-minus,.fa-subtract{--fa:"\f068"}.fa-circle-exclamation,.fa-exclamation-circle{--fa:"\f06a"}.fa-gift{--fa:"\f06b"}.fa-leaf{--fa:"\f06c"}.fa-fire{--fa:"\f06d"}.fa-eye{--fa:"\f06e"}.fa-eye-slash{--fa:"\f070"}.fa-exclamation-triangle,.fa-triangle-exclamation,.fa-warning{--fa:"\f071"}.fa-plane{--fa:"\f072"}.fa-calendar-alt,.fa-calendar-days{--fa:"\f073"}.fa-random,.fa-shuffle{--fa:"\f074"}.fa-comment{--fa:"\f075"}.fa-magnet{--fa:"\f076"}.fa-chevron-up{--fa:"\f077"}.fa-chevron-down{--fa:"\f078"}.fa-retweet{--fa:"\f079"}.fa-cart-shopping,.fa-shopping-cart{--fa:"\f07a"}.fa-folder,.fa-folder-blank{--fa:"\f07b"}.fa-folder-open{--fa:"\f07c"}.fa-arrows-up-down,.fa-arrows-v{--fa:"\f07d"}.fa-arrows-h,.fa-arrows-left-right{--fa:"\f07e"}.fa-bar-chart,.fa-chart-bar{--fa:"\f080"}.fa-camera-retro{--fa:"\f083"}.fa-key{--fa:"\f084"}.fa-cogs,.fa-gears{--fa:"\f085"}.fa-comments{--fa:"\f086"}.fa-star-half{--fa:"\f089"}.fa-arrow-right-from-bracket,.fa-sign-out{--fa:"\f08b"}.fa-thumb-tack,.fa-thumbtack{--fa:"\f08d"}.fa-arrow-up-right-from-square,.fa-external-link{--fa:"\f08e"}.fa-arrow-right-to-bracket,.fa-sign-in{--fa:"\f090"}.fa-trophy{--fa:"\f091"}.fa-upload{--fa:"\f093"}.fa-lemon{--fa:"\f094"}.fa-phone{--fa:"\f095"}.fa-phone-square,.fa-square-phone{--fa:"\f098"}.fa-unlock{--fa:"\f09c"}.fa-credit-card,.fa-credit-card-alt{--fa:"\f09d"}.fa-feed,.fa-rss{--fa:"\f09e"}.fa-hard-drive,.fa-hdd{--fa:"\f0a0"}.fa-bullhorn{--fa:"\f0a1"}.fa-certificate{--fa:"\f0a3"}.fa-hand-point-right{--fa:"\f0a4"}.fa-hand-point-left{--fa:"\f0a5"}.fa-hand-point-up{--fa:"\f0a6"}.fa-hand-point-down{--fa:"\f0a7"}.fa-arrow-circle-left,.fa-circle-arrow-left{--fa:"\f0a8"}.fa-arrow-circle-right,.fa-circle-arrow-right{--fa:"\f0a9"}.fa-arrow-circle-up,.fa-circle-arrow-up{--fa:"\f0aa"}.fa-arrow-circle-down,.fa-circle-arrow-down{--fa:"\f0ab"}.fa-globe{--fa:"\f0ac"}.fa-wrench{--fa:"\f0ad"}.fa-list-check,.fa-tasks{--fa:"\f0ae"}.fa-filter{--fa:"\f0b0"}.fa-briefcase{--fa:"\f0b1"}.fa-arrows-alt,.fa-up-down-left-right{--fa:"\f0b2"}.fa-users{--fa:"\f0c0"}.fa-chain,.fa-link{--fa:"\f0c1"}.fa-cloud{--fa:"\f0c2"}.fa-flask{--fa:"\f0c3"}.fa-cut,.fa-scissors{--fa:"\f0c4"}.fa-copy{--fa:"\f0c5"}.fa-paperclip{--fa:"\f0c6"}.fa-floppy-disk,.fa-save{--fa:"\f0c7"}.fa-square{--fa:"\f0c8"}.fa-bars,.fa-navicon{--fa:"\f0c9"}.fa-list-dots,.fa-list-ul{--fa:"\f0ca"}.fa-list-1-2,.fa-list-numeric,.fa-list-ol{--fa:"\f0cb"}.fa-strikethrough{--fa:"\f0cc"}.fa-underline{--fa:"\f0cd"}.fa-table{--fa:"\f0ce"}.fa-magic,.fa-wand-magic{--fa:"\f0d0"}.fa-truck{--fa:"\f0d1"}.fa-money-bill{--fa:"\f0d6"}.fa-caret-down{--fa:"\f0d7"}.fa-caret-up{--fa:"\f0d8"}.fa-caret-left{--fa:"\f0d9"}.fa-caret-right{--fa:"\f0da"}.fa-columns,.fa-table-columns{--fa:"\f0db"}.fa-sort,.fa-unsorted{--fa:"\f0dc"}.fa-sort-desc,.fa-sort-down{--fa:"\f0dd"}.fa-sort-asc,.fa-sort-up{--fa:"\f0de"}.fa-envelope{--fa:"\f0e0"}.fa-arrow-left-rotate,.fa-arrow-rotate-back,.fa-arrow-rotate-backward,.fa-arrow-rotate-left,.fa-undo{--fa:"\f0e2"}.fa-gavel,.fa-legal{--fa:"\f0e3"}.fa-bolt,.fa-zap{--fa:"\f0e7"}.fa-sitemap{--fa:"\f0e8"}.fa-umbrella{--fa:"\f0e9"}.fa-file-clipboard,.fa-paste{--fa:"\f0ea"}.fa-lightbulb{--fa:"\f0eb"}.fa-arrow-right-arrow-left,.fa-exchange{--fa:"\f0ec"}.fa-cloud-arrow-down,.fa-cloud-download,.fa-cloud-download-alt{--fa:"\f0ed"}.fa-cloud-arrow-up,.fa-cloud-upload,.fa-cloud-upload-alt{--fa:"\f0ee"}.fa-user-doctor,.fa-user-md{--fa:"\f0f0"}.fa-stethoscope{--fa:"\f0f1"}.fa-suitcase{--fa:"\f0f2"}.fa-bell{--fa:"\f0f3"}.fa-coffee,.fa-mug-saucer{--fa:"\f0f4"}.fa-hospital,.fa-hospital-alt,.fa-hospital-wide{--fa:"\f0f8"}.fa-ambulance,.fa-truck-medical{--fa:"\f0f9"}.fa-medkit,.fa-suitcase-medical{--fa:"\f0fa"}.fa-fighter-jet,.fa-jet-fighter{--fa:"\f0fb"}.fa-beer,.fa-beer-mug-empty{--fa:"\f0fc"}.fa-h-square,.fa-square-h{--fa:"\f0fd"}.fa-plus-square,.fa-square-plus{--fa:"\f0fe"}.fa-angle-double-left,.fa-angles-left{--fa:"\f100"}.fa-angle-double-right,.fa-angles-right{--fa:"\f101"}.fa-angle-double-up,.fa-angles-up{--fa:"\f102"}.fa-angle-double-down,.fa-angles-down{--fa:"\f103"}.fa-angle-left{--fa:"\f104"}.fa-angle-right{--fa:"\f105"}.fa-angle-up{--fa:"\f106"}.fa-angle-down{--fa:"\f107"}.fa-laptop{--fa:"\f109"}.fa-tablet-button{--fa:"\f10a"}.fa-mobile-button{--fa:"\f10b"}.fa-quote-left,.fa-quote-left-alt{--fa:"\f10d"}.fa-quote-right,.fa-quote-right-alt{--fa:"\f10e"}.fa-spinner{--fa:"\f110"}.fa-circle{--fa:"\f111"}.fa-face-smile,.fa-smile{--fa:"\f118"}.fa-face-frown,.fa-frown{--fa:"\f119"}.fa-face-meh,.fa-meh{--fa:"\f11a"}.fa-gamepad{--fa:"\f11b"}.fa-keyboard{--fa:"\f11c"}.fa-flag-checkered{--fa:"\f11e"}.fa-terminal{--fa:"\f120"}.fa-code{--fa:"\f121"}.fa-mail-reply-all,.fa-reply-all{--fa:"\f122"}.fa-location-arrow{--fa:"\f124"}.fa-crop{--fa:"\f125"}.fa-code-branch{--fa:"\f126"}.fa-chain-broken,.fa-chain-slash,.fa-link-slash,.fa-unlink{--fa:"\f127"}.fa-info{--fa:"\f129"}.fa-superscript{--fa:"\f12b"}.fa-subscript{--fa:"\f12c"}.fa-eraser{--fa:"\f12d"}.fa-puzzle-piece{--fa:"\f12e"}.fa-microphone{--fa:"\f130"}.fa-microphone-slash{--fa:"\f131"}.fa-shield,.fa-shield-blank{--fa:"\f132"}.fa-calendar{--fa:"\f133"}.fa-fire-extinguisher{--fa:"\f134"}.fa-rocket{--fa:"\f135"}.fa-chevron-circle-left,.fa-circle-chevron-left{--fa:"\f137"}.fa-chevron-circle-right,.fa-circle-chevron-right{--fa:"\f138"}.fa-chevron-circle-up,.fa-circle-chevron-up{--fa:"\f139"}.fa-chevron-circle-down,.fa-circle-chevron-down{--fa:"\f13a"}.fa-anchor{--fa:"\f13d"}.fa-unlock-alt,.fa-unlock-keyhole{--fa:"\f13e"}.fa-bullseye{--fa:"\f140"}.fa-ellipsis,.fa-ellipsis-h{--fa:"\f141"}.fa-ellipsis-v,.fa-ellipsis-vertical{--fa:"\f142"}.fa-rss-square,.fa-square-rss{--fa:"\f143"}.fa-circle-play,.fa-play-circle{--fa:"\f144"}.fa-ticket{--fa:"\f145"}.fa-minus-square,.fa-square-minus{--fa:"\f146"}.fa-arrow-turn-up,.fa-level-up{--fa:"\f148"}.fa-arrow-turn-down,.fa-level-down{--fa:"\f149"}.fa-check-square,.fa-square-check{--fa:"\f14a"}.fa-pen-square,.fa-pencil-square,.fa-square-pen{--fa:"\f14b"}.fa-external-link-square,.fa-square-arrow-up-right{--fa:"\f14c"}.fa-share-from-square,.fa-share-square{--fa:"\f14d"}.fa-compass{--fa:"\f14e"}.fa-caret-square-down,.fa-square-caret-down{--fa:"\f150"}.fa-caret-square-up,.fa-square-caret-up{--fa:"\f151"}.fa-caret-square-right,.fa-square-caret-right{--fa:"\f152"}.fa-eur,.fa-euro,.fa-euro-sign{--fa:"\f153"}.fa-gbp,.fa-pound-sign,.fa-sterling-sign{--fa:"\f154"}.fa-rupee,.fa-rupee-sign{--fa:"\f156"}.fa-cny,.fa-jpy,.fa-rmb,.fa-yen,.fa-yen-sign{--fa:"\f157"}.fa-rouble,.fa-rub,.fa-ruble,.fa-ruble-sign{--fa:"\f158"}.fa-krw,.fa-won,.fa-won-sign{--fa:"\f159"}.fa-file{--fa:"\f15b"}.fa-file-alt,.fa-file-lines,.fa-file-text{--fa:"\f15c"}.fa-arrow-down-a-z,.fa-sort-alpha-asc,.fa-sort-alpha-down{--fa:"\f15d"}.fa-arrow-up-a-z,.fa-sort-alpha-up{--fa:"\f15e"}.fa-arrow-down-wide-short,.fa-sort-amount-asc,.fa-sort-amount-down{--fa:"\f160"}.fa-arrow-up-wide-short,.fa-sort-amount-up{--fa:"\f161"}.fa-arrow-down-1-9,.fa-sort-numeric-asc,.fa-sort-numeric-down{--fa:"\f162"}.fa-arrow-up-1-9,.fa-sort-numeric-up{--fa:"\f163"}.fa-thumbs-up{--fa:"\f164"}.fa-thumbs-down{--fa:"\f165"}.fa-arrow-down-long,.fa-long-arrow-down{--fa:"\f175"}.fa-arrow-up-long,.fa-long-arrow-up{--fa:"\f176"}.fa-arrow-left-long,.fa-long-arrow-left{--fa:"\f177"}.fa-arrow-right-long,.fa-long-arrow-right{--fa:"\f178"}.fa-female,.fa-person-dress{--fa:"\f182"}.fa-male,.fa-person{--fa:"\f183"}.fa-sun{--fa:"\f185"}.fa-moon{--fa:"\f186"}.fa-archive,.fa-box-archive{--fa:"\f187"}.fa-bug{--fa:"\f188"}.fa-caret-square-left,.fa-square-caret-left{--fa:"\f191"}.fa-circle-dot,.fa-dot-circle{--fa:"\f192"}.fa-wheelchair{--fa:"\f193"}.fa-lira-sign{--fa:"\f195"}.fa-shuttle-space,.fa-space-shuttle{--fa:"\f197"}.fa-envelope-square,.fa-square-envelope{--fa:"\f199"}.fa-bank,.fa-building-columns,.fa-institution,.fa-museum,.fa-university{--fa:"\f19c"}.fa-graduation-cap,.fa-mortar-board{--fa:"\f19d"}.fa-language{--fa:"\f1ab"}.fa-fax{--fa:"\f1ac"}.fa-building{--fa:"\f1ad"}.fa-child{--fa:"\f1ae"}.fa-paw{--fa:"\f1b0"}.fa-cube{--fa:"\f1b2"}.fa-cubes{--fa:"\f1b3"}.fa-recycle{--fa:"\f1b8"}.fa-automobile,.fa-car{--fa:"\f1b9"}.fa-cab,.fa-taxi{--fa:"\f1ba"}.fa-tree{--fa:"\f1bb"}.fa-database{--fa:"\f1c0"}.fa-file-pdf{--fa:"\f1c1"}.fa-file-word{--fa:"\f1c2"}.fa-file-excel{--fa:"\f1c3"}.fa-file-powerpoint{--fa:"\f1c4"}.fa-file-image{--fa:"\f1c5"}.fa-file-archive,.fa-file-zipper{--fa:"\f1c6"}.fa-file-audio{--fa:"\f1c7"}.fa-file-video{--fa:"\f1c8"}.fa-file-code{--fa:"\f1c9"}.fa-life-ring{--fa:"\f1cd"}.fa-circle-notch{--fa:"\f1ce"}.fa-paper-plane{--fa:"\f1d8"}.fa-clock-rotate-left,.fa-history{--fa:"\f1da"}.fa-header,.fa-heading{--fa:"\f1dc"}.fa-paragraph{--fa:"\f1dd"}.fa-sliders,.fa-sliders-h{--fa:"\f1de"}.fa-share-alt,.fa-share-nodes{--fa:"\f1e0"}.fa-share-alt-square,.fa-square-share-nodes{--fa:"\f1e1"}.fa-bomb{--fa:"\f1e2"}.fa-futbol,.fa-futbol-ball,.fa-soccer-ball{--fa:"\f1e3"}.fa-teletype,.fa-tty{--fa:"\f1e4"}.fa-binoculars{--fa:"\f1e5"}.fa-plug{--fa:"\f1e6"}.fa-newspaper{--fa:"\f1ea"}.fa-wifi,.fa-wifi-3,.fa-wifi-strong{--fa:"\f1eb"}.fa-calculator{--fa:"\f1ec"}.fa-bell-slash{--fa:"\f1f6"}.fa-trash{--fa:"\f1f8"}.fa-copyright{--fa:"\f1f9"}.fa-eye-dropper,.fa-eye-dropper-empty,.fa-eyedropper{--fa:"\f1fb"}.fa-paint-brush,.fa-paintbrush{--fa:"\f1fc"}.fa-birthday-cake,.fa-cake,.fa-cake-candles{--fa:"\f1fd"}.fa-area-chart,.fa-chart-area{--fa:"\f1fe"}.fa-chart-pie,.fa-pie-chart{--fa:"\f200"}.fa-chart-line,.fa-line-chart{--fa:"\f201"}.fa-toggle-off{--fa:"\f204"}.fa-toggle-on{--fa:"\f205"}.fa-bicycle{--fa:"\f206"}.fa-bus{--fa:"\f207"}.fa-closed-captioning{--fa:"\f20a"}.fa-ils,.fa-shekel,.fa-shekel-sign,.fa-sheqel,.fa-sheqel-sign{--fa:"\f20b"}.fa-cart-plus{--fa:"\f217"}.fa-cart-arrow-down{--fa:"\f218"}.fa-diamond{--fa:"\f219"}.fa-ship{--fa:"\f21a"}.fa-user-secret{--fa:"\f21b"}.fa-motorcycle{--fa:"\f21c"}.fa-street-view{--fa:"\f21d"}.fa-heart-pulse,.fa-heartbeat{--fa:"\f21e"}.fa-venus{--fa:"\f221"}.fa-mars{--fa:"\f222"}.fa-mercury{--fa:"\f223"}.fa-mars-and-venus{--fa:"\f224"}.fa-transgender,.fa-transgender-alt{--fa:"\f225"}.fa-venus-double{--fa:"\f226"}.fa-mars-double{--fa:"\f227"}.fa-venus-mars{--fa:"\f228"}.fa-mars-stroke{--fa:"\f229"}.fa-mars-stroke-up,.fa-mars-stroke-v{--fa:"\f22a"}.fa-mars-stroke-h,.fa-mars-stroke-right{--fa:"\f22b"}.fa-neuter{--fa:"\f22c"}.fa-genderless{--fa:"\f22d"}.fa-server{--fa:"\f233"}.fa-user-plus{--fa:"\f234"}.fa-user-times,.fa-user-xmark{--fa:"\f235"}.fa-bed{--fa:"\f236"}.fa-train{--fa:"\f238"}.fa-subway,.fa-train-subway{--fa:"\f239"}.fa-battery,.fa-battery-5,.fa-battery-full{--fa:"\f240"}.fa-battery-4,.fa-battery-three-quarters{--fa:"\f241"}.fa-battery-3,.fa-battery-half{--fa:"\f242"}.fa-battery-2,.fa-battery-quarter{--fa:"\f243"}.fa-battery-0,.fa-battery-empty{--fa:"\f244"}.fa-arrow-pointer,.fa-mouse-pointer{--fa:"\f245"}.fa-i-cursor{--fa:"\f246"}.fa-object-group{--fa:"\f247"}.fa-object-ungroup{--fa:"\f248"}.fa-note-sticky,.fa-sticky-note{--fa:"\f249"}.fa-clone{--fa:"\f24d"}.fa-balance-scale,.fa-scale-balanced{--fa:"\f24e"}.fa-hourglass-1,.fa-hourglass-start{--fa:"\f251"}.fa-hourglass-2,.fa-hourglass-half{--fa:"\f252"}.fa-hourglass-3,.fa-hourglass-end{--fa:"\f253"}.fa-hourglass,.fa-hourglass-empty{--fa:"\f254"}.fa-hand-back-fist,.fa-hand-rock{--fa:"\f255"}.fa-hand,.fa-hand-paper{--fa:"\f256"}.fa-hand-scissors{--fa:"\f257"}.fa-hand-lizard{--fa:"\f258"}.fa-hand-spock{--fa:"\f259"}.fa-hand-pointer{--fa:"\f25a"}.fa-hand-peace{--fa:"\f25b"}.fa-trademark{--fa:"\f25c"}.fa-registered{--fa:"\f25d"}.fa-television,.fa-tv,.fa-tv-alt{--fa:"\f26c"}.fa-calendar-plus{--fa:"\f271"}.fa-calendar-minus{--fa:"\f272"}.fa-calendar-times,.fa-calendar-xmark{--fa:"\f273"}.fa-calendar-check{--fa:"\f274"}.fa-industry{--fa:"\f275"}.fa-map-pin{--fa:"\f276"}.fa-map-signs,.fa-signs-post{--fa:"\f277"}.fa-map{--fa:"\f279"}.fa-comment-alt,.fa-message{--fa:"\f27a"}.fa-circle-pause,.fa-pause-circle{--fa:"\f28b"}.fa-circle-stop,.fa-stop-circle{--fa:"\f28d"}.fa-bag-shopping,.fa-shopping-bag{--fa:"\f290"}.fa-basket-shopping,.fa-shopping-basket{--fa:"\f291"}.fa-universal-access{--fa:"\f29a"}.fa-blind,.fa-person-walking-with-cane{--fa:"\f29d"}.fa-audio-description{--fa:"\f29e"}.fa-phone-volume,.fa-volume-control-phone{--fa:"\f2a0"}.fa-braille{--fa:"\f2a1"}.fa-assistive-listening-systems,.fa-ear-listen{--fa:"\f2a2"}.fa-american-sign-language-interpreting,.fa-asl-interpreting,.fa-hands-american-sign-language-interpreting,.fa-hands-asl-interpreting{--fa:"\f2a3"}.fa-deaf,.fa-deafness,.fa-ear-deaf,.fa-hard-of-hearing{--fa:"\f2a4"}.fa-hands,.fa-sign-language,.fa-signing{--fa:"\f2a7"}.fa-eye-low-vision,.fa-low-vision{--fa:"\f2a8"}.fa-font-awesome,.fa-font-awesome-flag,.fa-font-awesome-logo-full{--fa:"\f2b4"}.fa-handshake,.fa-handshake-alt,.fa-handshake-simple{--fa:"\f2b5"}.fa-envelope-open{--fa:"\f2b6"}.fa-address-book,.fa-contact-book{--fa:"\f2b9"}.fa-address-card,.fa-contact-card,.fa-vcard{--fa:"\f2bb"}.fa-circle-user,.fa-user-circle{--fa:"\f2bd"}.fa-id-badge{--fa:"\f2c1"}.fa-drivers-license,.fa-id-card{--fa:"\f2c2"}.fa-temperature-4,.fa-temperature-full,.fa-thermometer-4,.fa-thermometer-full{--fa:"\f2c7"}.fa-temperature-3,.fa-temperature-three-quarters,.fa-thermometer-3,.fa-thermometer-three-quarters{--fa:"\f2c8"}.fa-temperature-2,.fa-temperature-half,.fa-thermometer-2,.fa-thermometer-half{--fa:"\f2c9"}.fa-temperature-1,.fa-temperature-quarter,.fa-thermometer-1,.fa-thermometer-quarter{--fa:"\f2ca"}.fa-temperature-0,.fa-temperature-empty,.fa-thermometer-0,.fa-thermometer-empty{--fa:"\f2cb"}.fa-shower{--fa:"\f2cc"}.fa-bath,.fa-bathtub{--fa:"\f2cd"}.fa-podcast{--fa:"\f2ce"}.fa-window-maximize{--fa:"\f2d0"}.fa-window-minimize{--fa:"\f2d1"}.fa-window-restore{--fa:"\f2d2"}.fa-square-xmark,.fa-times-square,.fa-xmark-square{--fa:"\f2d3"}.fa-microchip{--fa:"\f2db"}.fa-snowflake{--fa:"\f2dc"}.fa-spoon,.fa-utensil-spoon{--fa:"\f2e5"}.fa-cutlery,.fa-utensils{--fa:"\f2e7"}.fa-rotate-back,.fa-rotate-backward,.fa-rotate-left,.fa-undo-alt{--fa:"\f2ea"}.fa-trash-alt,.fa-trash-can{--fa:"\f2ed"}.fa-rotate,.fa-sync-alt{--fa:"\f2f1"}.fa-stopwatch{--fa:"\f2f2"}.fa-right-from-bracket,.fa-sign-out-alt{--fa:"\f2f5"}.fa-right-to-bracket,.fa-sign-in-alt{--fa:"\f2f6"}.fa-redo-alt,.fa-rotate-forward,.fa-rotate-right{--fa:"\f2f9"}.fa-poo{--fa:"\f2fe"}.fa-images{--fa:"\f302"}.fa-pencil,.fa-pencil-alt{--fa:"\f303"}.fa-pen{--fa:"\f304"}.fa-pen-alt,.fa-pen-clip{--fa:"\f305"}.fa-octagon{--fa:"\f306"}.fa-down-long,.fa-long-arrow-alt-down{--fa:"\f309"}.fa-left-long,.fa-long-arrow-alt-left{--fa:"\f30a"}.fa-long-arrow-alt-right,.fa-right-long{--fa:"\f30b"}.fa-long-arrow-alt-up,.fa-up-long{--fa:"\f30c"}.fa-hexagon{--fa:"\f312"}.fa-file-edit,.fa-file-pen{--fa:"\f31c"}.fa-expand-arrows-alt,.fa-maximize{--fa:"\f31e"}.fa-clipboard{--fa:"\f328"}.fa-arrows-alt-h,.fa-left-right{--fa:"\f337"}.fa-arrows-alt-v,.fa-up-down{--fa:"\f338"}.fa-alarm-clock{--fa:"\f34e"}.fa-arrow-alt-circle-down,.fa-circle-down{--fa:"\f358"}.fa-arrow-alt-circle-left,.fa-circle-left{--fa:"\f359"}.fa-arrow-alt-circle-right,.fa-circle-right{--fa:"\f35a"}.fa-arrow-alt-circle-up,.fa-circle-up{--fa:"\f35b"}.fa-external-link-alt,.fa-up-right-from-square{--fa:"\f35d"}.fa-external-link-square-alt,.fa-square-up-right{--fa:"\f360"}.fa-exchange-alt,.fa-right-left{--fa:"\f362"}.fa-repeat{--fa:"\f363"}.fa-code-commit{--fa:"\f386"}.fa-code-merge{--fa:"\f387"}.fa-desktop,.fa-desktop-alt{--fa:"\f390"}.fa-gem{--fa:"\f3a5"}.fa-level-down-alt,.fa-turn-down{--fa:"\f3be"}.fa-level-up-alt,.fa-turn-up{--fa:"\f3bf"}.fa-lock-open{--fa:"\f3c1"}.fa-location-dot,.fa-map-marker-alt{--fa:"\f3c5"}.fa-microphone-alt,.fa-microphone-lines{--fa:"\f3c9"}.fa-mobile-alt,.fa-mobile-screen-button{--fa:"\f3cd"}.fa-mobile,.fa-mobile-android,.fa-mobile-phone{--fa:"\f3ce"}.fa-mobile-android-alt,.fa-mobile-screen{--fa:"\f3cf"}.fa-money-bill-1,.fa-money-bill-alt{--fa:"\f3d1"}.fa-phone-slash{--fa:"\f3dd"}.fa-image-portrait,.fa-portrait{--fa:"\f3e0"}.fa-mail-reply,.fa-reply{--fa:"\f3e5"}.fa-shield-alt,.fa-shield-halved{--fa:"\f3ed"}.fa-tablet-alt,.fa-tablet-screen-button{--fa:"\f3fa"}.fa-tablet,.fa-tablet-android{--fa:"\f3fb"}.fa-ticket-alt,.fa-ticket-simple{--fa:"\f3ff"}.fa-rectangle-times,.fa-rectangle-xmark,.fa-times-rectangle,.fa-window-close{--fa:"\f410"}.fa-compress-alt,.fa-down-left-and-up-right-to-center{--fa:"\f422"}.fa-expand-alt,.fa-up-right-and-down-left-from-center{--fa:"\f424"}.fa-baseball-bat-ball{--fa:"\f432"}.fa-baseball,.fa-baseball-ball{--fa:"\f433"}.fa-basketball,.fa-basketball-ball{--fa:"\f434"}.fa-bowling-ball{--fa:"\f436"}.fa-chess{--fa:"\f439"}.fa-chess-bishop{--fa:"\f43a"}.fa-chess-board{--fa:"\f43c"}.fa-chess-king{--fa:"\f43f"}.fa-chess-knight{--fa:"\f441"}.fa-chess-pawn{--fa:"\f443"}.fa-chess-queen{--fa:"\f445"}.fa-chess-rook{--fa:"\f447"}.fa-dumbbell{--fa:"\f44b"}.fa-football,.fa-football-ball{--fa:"\f44e"}.fa-golf-ball,.fa-golf-ball-tee{--fa:"\f450"}.fa-hockey-puck{--fa:"\f453"}.fa-broom-ball,.fa-quidditch,.fa-quidditch-broom-ball{--fa:"\f458"}.fa-square-full{--fa:"\f45c"}.fa-ping-pong-paddle-ball,.fa-table-tennis,.fa-table-tennis-paddle-ball{--fa:"\f45d"}.fa-volleyball,.fa-volleyball-ball{--fa:"\f45f"}.fa-allergies,.fa-hand-dots{--fa:"\f461"}.fa-band-aid,.fa-bandage{--fa:"\f462"}.fa-box{--fa:"\f466"}.fa-boxes,.fa-boxes-alt,.fa-boxes-stacked{--fa:"\f468"}.fa-briefcase-medical{--fa:"\f469"}.fa-burn,.fa-fire-flame-simple{--fa:"\f46a"}.fa-capsules{--fa:"\f46b"}.fa-clipboard-check{--fa:"\f46c"}.fa-clipboard-list{--fa:"\f46d"}.fa-diagnoses,.fa-person-dots-from-line{--fa:"\f470"}.fa-dna{--fa:"\f471"}.fa-dolly,.fa-dolly-box{--fa:"\f472"}.fa-cart-flatbed,.fa-dolly-flatbed{--fa:"\f474"}.fa-file-medical{--fa:"\f477"}.fa-file-medical-alt,.fa-file-waveform{--fa:"\f478"}.fa-first-aid,.fa-kit-medical{--fa:"\f479"}.fa-circle-h,.fa-hospital-symbol{--fa:"\f47e"}.fa-id-card-alt,.fa-id-card-clip{--fa:"\f47f"}.fa-notes-medical{--fa:"\f481"}.fa-pallet{--fa:"\f482"}.fa-pills{--fa:"\f484"}.fa-prescription-bottle{--fa:"\f485"}.fa-prescription-bottle-alt,.fa-prescription-bottle-medical{--fa:"\f486"}.fa-bed-pulse,.fa-procedures{--fa:"\f487"}.fa-shipping-fast,.fa-truck-fast{--fa:"\f48b"}.fa-smoking{--fa:"\f48d"}.fa-syringe{--fa:"\f48e"}.fa-tablets{--fa:"\f490"}.fa-thermometer{--fa:"\f491"}.fa-vial{--fa:"\f492"}.fa-vials{--fa:"\f493"}.fa-warehouse{--fa:"\f494"}.fa-weight,.fa-weight-scale{--fa:"\f496"}.fa-x-ray{--fa:"\f497"}.fa-box-open{--fa:"\f49e"}.fa-comment-dots,.fa-commenting{--fa:"\f4ad"}.fa-comment-slash{--fa:"\f4b3"}.fa-couch{--fa:"\f4b8"}.fa-circle-dollar-to-slot,.fa-donate{--fa:"\f4b9"}.fa-dove{--fa:"\f4ba"}.fa-hand-holding{--fa:"\f4bd"}.fa-hand-holding-heart{--fa:"\f4be"}.fa-hand-holding-dollar,.fa-hand-holding-usd{--fa:"\f4c0"}.fa-hand-holding-droplet,.fa-hand-holding-water{--fa:"\f4c1"}.fa-hands-holding{--fa:"\f4c2"}.fa-hands-helping,.fa-handshake-angle{--fa:"\f4c4"}.fa-parachute-box{--fa:"\f4cd"}.fa-people-carry,.fa-people-carry-box{--fa:"\f4ce"}.fa-piggy-bank{--fa:"\f4d3"}.fa-ribbon{--fa:"\f4d6"}.fa-route{--fa:"\f4d7"}.fa-seedling,.fa-sprout{--fa:"\f4d8"}.fa-sign,.fa-sign-hanging{--fa:"\f4d9"}.fa-face-smile-wink,.fa-smile-wink{--fa:"\f4da"}.fa-tape{--fa:"\f4db"}.fa-truck-loading,.fa-truck-ramp-box{--fa:"\f4de"}.fa-truck-moving{--fa:"\f4df"}.fa-video-slash{--fa:"\f4e2"}.fa-wine-glass{--fa:"\f4e3"}.fa-user-astronaut{--fa:"\f4fb"}.fa-user-check{--fa:"\f4fc"}.fa-user-clock{--fa:"\f4fd"}.fa-user-cog,.fa-user-gear{--fa:"\f4fe"}.fa-user-edit,.fa-user-pen{--fa:"\f4ff"}.fa-user-friends,.fa-user-group{--fa:"\f500"}.fa-user-graduate{--fa:"\f501"}.fa-user-lock{--fa:"\f502"}.fa-user-minus{--fa:"\f503"}.fa-user-ninja{--fa:"\f504"}.fa-user-shield{--fa:"\f505"}.fa-user-alt-slash,.fa-user-large-slash,.fa-user-slash{--fa:"\f506"}.fa-user-tag{--fa:"\f507"}.fa-user-tie{--fa:"\f508"}.fa-users-cog,.fa-users-gear{--fa:"\f509"}.fa-balance-scale-left,.fa-scale-unbalanced{--fa:"\f515"}.fa-balance-scale-right,.fa-scale-unbalanced-flip{--fa:"\f516"}.fa-blender{--fa:"\f517"}.fa-book-open{--fa:"\f518"}.fa-broadcast-tower,.fa-tower-broadcast{--fa:"\f519"}.fa-broom{--fa:"\f51a"}.fa-blackboard,.fa-chalkboard{--fa:"\f51b"}.fa-chalkboard-teacher,.fa-chalkboard-user{--fa:"\f51c"}.fa-church{--fa:"\f51d"}.fa-coins{--fa:"\f51e"}.fa-compact-disc{--fa:"\f51f"}.fa-crow{--fa:"\f520"}.fa-crown{--fa:"\f521"}.fa-dice{--fa:"\f522"}.fa-dice-five{--fa:"\f523"}.fa-dice-four{--fa:"\f524"}.fa-dice-one{--fa:"\f525"}.fa-dice-six{--fa:"\f526"}.fa-dice-three{--fa:"\f527"}.fa-dice-two{--fa:"\f528"}.fa-divide{--fa:"\f529"}.fa-door-closed{--fa:"\f52a"}.fa-door-open{--fa:"\f52b"}.fa-feather{--fa:"\f52d"}.fa-frog{--fa:"\f52e"}.fa-gas-pump{--fa:"\f52f"}.fa-glasses{--fa:"\f530"}.fa-greater-than-equal{--fa:"\f532"}.fa-helicopter{--fa:"\f533"}.fa-infinity{--fa:"\f534"}.fa-kiwi-bird{--fa:"\f535"}.fa-less-than-equal{--fa:"\f537"}.fa-memory{--fa:"\f538"}.fa-microphone-alt-slash,.fa-microphone-lines-slash{--fa:"\f539"}.fa-money-bill-wave{--fa:"\f53a"}.fa-money-bill-1-wave,.fa-money-bill-wave-alt{--fa:"\f53b"}.fa-money-check{--fa:"\f53c"}.fa-money-check-alt,.fa-money-check-dollar{--fa:"\f53d"}.fa-not-equal{--fa:"\f53e"}.fa-palette{--fa:"\f53f"}.fa-parking,.fa-square-parking{--fa:"\f540"}.fa-diagram-project,.fa-project-diagram{--fa:"\f542"}.fa-receipt{--fa:"\f543"}.fa-robot{--fa:"\f544"}.fa-ruler{--fa:"\f545"}.fa-ruler-combined{--fa:"\f546"}.fa-ruler-horizontal{--fa:"\f547"}.fa-ruler-vertical{--fa:"\f548"}.fa-school{--fa:"\f549"}.fa-screwdriver{--fa:"\f54a"}.fa-shoe-prints{--fa:"\f54b"}.fa-skull{--fa:"\f54c"}.fa-ban-smoking,.fa-smoking-ban{--fa:"\f54d"}.fa-store{--fa:"\f54e"}.fa-shop,.fa-store-alt{--fa:"\f54f"}.fa-bars-staggered,.fa-reorder,.fa-stream{--fa:"\f550"}.fa-stroopwafel{--fa:"\f551"}.fa-toolbox{--fa:"\f552"}.fa-shirt,.fa-t-shirt,.fa-tshirt{--fa:"\f553"}.fa-person-walking,.fa-walking{--fa:"\f554"}.fa-wallet{--fa:"\f555"}.fa-angry,.fa-face-angry{--fa:"\f556"}.fa-archway{--fa:"\f557"}.fa-atlas,.fa-book-atlas{--fa:"\f558"}.fa-award{--fa:"\f559"}.fa-backspace,.fa-delete-left{--fa:"\f55a"}.fa-bezier-curve{--fa:"\f55b"}.fa-bong{--fa:"\f55c"}.fa-brush{--fa:"\f55d"}.fa-bus-alt,.fa-bus-simple{--fa:"\f55e"}.fa-cannabis{--fa:"\f55f"}.fa-check-double{--fa:"\f560"}.fa-cocktail,.fa-martini-glass-citrus{--fa:"\f561"}.fa-bell-concierge,.fa-concierge-bell{--fa:"\f562"}.fa-cookie{--fa:"\f563"}.fa-cookie-bite{--fa:"\f564"}.fa-crop-alt,.fa-crop-simple{--fa:"\f565"}.fa-digital-tachograph,.fa-tachograph-digital{--fa:"\f566"}.fa-dizzy,.fa-face-dizzy{--fa:"\f567"}.fa-compass-drafting,.fa-drafting-compass{--fa:"\f568"}.fa-drum{--fa:"\f569"}.fa-drum-steelpan{--fa:"\f56a"}.fa-feather-alt,.fa-feather-pointed{--fa:"\f56b"}.fa-file-contract{--fa:"\f56c"}.fa-file-arrow-down,.fa-file-download{--fa:"\f56d"}.fa-arrow-right-from-file,.fa-file-export{--fa:"\f56e"}.fa-arrow-right-to-file,.fa-file-import{--fa:"\f56f"}.fa-file-invoice{--fa:"\f570"}.fa-file-invoice-dollar{--fa:"\f571"}.fa-file-prescription{--fa:"\f572"}.fa-file-signature{--fa:"\f573"}.fa-file-arrow-up,.fa-file-upload{--fa:"\f574"}.fa-fill{--fa:"\f575"}.fa-fill-drip{--fa:"\f576"}.fa-fingerprint{--fa:"\f577"}.fa-fish{--fa:"\f578"}.fa-face-flushed,.fa-flushed{--fa:"\f579"}.fa-face-frown-open,.fa-frown-open{--fa:"\f57a"}.fa-glass-martini-alt,.fa-martini-glass{--fa:"\f57b"}.fa-earth-africa,.fa-globe-africa{--fa:"\f57c"}.fa-earth,.fa-earth-america,.fa-earth-americas,.fa-globe-americas{--fa:"\f57d"}.fa-earth-asia,.fa-globe-asia{--fa:"\f57e"}.fa-face-grimace,.fa-grimace{--fa:"\f57f"}.fa-face-grin,.fa-grin{--fa:"\f580"}.fa-face-grin-wide,.fa-grin-alt{--fa:"\f581"}.fa-face-grin-beam,.fa-grin-beam{--fa:"\f582"}.fa-face-grin-beam-sweat,.fa-grin-beam-sweat{--fa:"\f583"}.fa-face-grin-hearts,.fa-grin-hearts{--fa:"\f584"}.fa-face-grin-squint,.fa-grin-squint{--fa:"\f585"}.fa-face-grin-squint-tears,.fa-grin-squint-tears{--fa:"\f586"}.fa-face-grin-stars,.fa-grin-stars{--fa:"\f587"}.fa-face-grin-tears,.fa-grin-tears{--fa:"\f588"}.fa-face-grin-tongue,.fa-grin-tongue{--fa:"\f589"}.fa-face-grin-tongue-squint,.fa-grin-tongue-squint{--fa:"\f58a"}.fa-face-grin-tongue-wink,.fa-grin-tongue-wink{--fa:"\f58b"}.fa-face-grin-wink,.fa-grin-wink{--fa:"\f58c"}.fa-grid-horizontal,.fa-grip,.fa-grip-horizontal{--fa:"\f58d"}.fa-grid-vertical,.fa-grip-vertical{--fa:"\f58e"}.fa-headset{--fa:"\f590"}.fa-highlighter{--fa:"\f591"}.fa-hot-tub,.fa-hot-tub-person{--fa:"\f593"}.fa-hotel{--fa:"\f594"}.fa-joint{--fa:"\f595"}.fa-face-kiss,.fa-kiss{--fa:"\f596"}.fa-face-kiss-beam,.fa-kiss-beam{--fa:"\f597"}.fa-face-kiss-wink-heart,.fa-kiss-wink-heart{--fa:"\f598"}.fa-face-laugh,.fa-laugh{--fa:"\f599"}.fa-face-laugh-beam,.fa-laugh-beam{--fa:"\f59a"}.fa-face-laugh-squint,.fa-laugh-squint{--fa:"\f59b"}.fa-face-laugh-wink,.fa-laugh-wink{--fa:"\f59c"}.fa-cart-flatbed-suitcase,.fa-luggage-cart{--fa:"\f59d"}.fa-map-location,.fa-map-marked{--fa:"\f59f"}.fa-map-location-dot,.fa-map-marked-alt{--fa:"\f5a0"}.fa-marker{--fa:"\f5a1"}.fa-medal{--fa:"\f5a2"}.fa-face-meh-blank,.fa-meh-blank{--fa:"\f5a4"}.fa-face-rolling-eyes,.fa-meh-rolling-eyes{--fa:"\f5a5"}.fa-monument{--fa:"\f5a6"}.fa-mortar-pestle{--fa:"\f5a7"}.fa-paint-roller{--fa:"\f5aa"}.fa-passport{--fa:"\f5ab"}.fa-pen-fancy{--fa:"\f5ac"}.fa-pen-nib{--fa:"\f5ad"}.fa-pen-ruler,.fa-pencil-ruler{--fa:"\f5ae"}.fa-plane-arrival{--fa:"\f5af"}.fa-plane-departure{--fa:"\f5b0"}.fa-prescription{--fa:"\f5b1"}.fa-face-sad-cry,.fa-sad-cry{--fa:"\f5b3"}.fa-face-sad-tear,.fa-sad-tear{--fa:"\f5b4"}.fa-shuttle-van,.fa-van-shuttle{--fa:"\f5b6"}.fa-signature{--fa:"\f5b7"}.fa-face-smile-beam,.fa-smile-beam{--fa:"\f5b8"}.fa-solar-panel{--fa:"\f5ba"}.fa-spa{--fa:"\f5bb"}.fa-splotch{--fa:"\f5bc"}.fa-spray-can{--fa:"\f5bd"}.fa-stamp{--fa:"\f5bf"}.fa-star-half-alt,.fa-star-half-stroke{--fa:"\f5c0"}.fa-suitcase-rolling{--fa:"\f5c1"}.fa-face-surprise,.fa-surprise{--fa:"\f5c2"}.fa-swatchbook{--fa:"\f5c3"}.fa-person-swimming,.fa-swimmer{--fa:"\f5c4"}.fa-ladder-water,.fa-swimming-pool,.fa-water-ladder{--fa:"\f5c5"}.fa-droplet-slash,.fa-tint-slash{--fa:"\f5c7"}.fa-face-tired,.fa-tired{--fa:"\f5c8"}.fa-tooth{--fa:"\f5c9"}.fa-umbrella-beach{--fa:"\f5ca"}.fa-weight-hanging{--fa:"\f5cd"}.fa-wine-glass-alt,.fa-wine-glass-empty{--fa:"\f5ce"}.fa-air-freshener,.fa-spray-can-sparkles{--fa:"\f5d0"}.fa-apple-alt,.fa-apple-whole{--fa:"\f5d1"}.fa-atom{--fa:"\f5d2"}.fa-bone{--fa:"\f5d7"}.fa-book-open-reader,.fa-book-reader{--fa:"\f5da"}.fa-brain{--fa:"\f5dc"}.fa-car-alt,.fa-car-rear{--fa:"\f5de"}.fa-battery-car,.fa-car-battery{--fa:"\f5df"}.fa-car-burst,.fa-car-crash{--fa:"\f5e1"}.fa-car-side{--fa:"\f5e4"}.fa-charging-station{--fa:"\f5e7"}.fa-diamond-turn-right,.fa-directions{--fa:"\f5eb"}.fa-draw-polygon,.fa-vector-polygon{--fa:"\f5ee"}.fa-laptop-code{--fa:"\f5fc"}.fa-layer-group{--fa:"\f5fd"}.fa-location,.fa-location-crosshairs{--fa:"\f601"}.fa-lungs{--fa:"\f604"}.fa-microscope{--fa:"\f610"}.fa-oil-can{--fa:"\f613"}.fa-poop{--fa:"\f619"}.fa-shapes,.fa-triangle-circle-square{--fa:"\f61f"}.fa-star-of-life{--fa:"\f621"}.fa-dashboard,.fa-gauge,.fa-gauge-med,.fa-tachometer-alt-average{--fa:"\f624"}.fa-gauge-high,.fa-tachometer-alt,.fa-tachometer-alt-fast{--fa:"\f625"}.fa-gauge-simple,.fa-gauge-simple-med,.fa-tachometer-average{--fa:"\f629"}.fa-gauge-simple-high,.fa-tachometer,.fa-tachometer-fast{--fa:"\f62a"}.fa-teeth{--fa:"\f62e"}.fa-teeth-open{--fa:"\f62f"}.fa-masks-theater,.fa-theater-masks{--fa:"\f630"}.fa-traffic-light{--fa:"\f637"}.fa-truck-monster{--fa:"\f63b"}.fa-truck-pickup{--fa:"\f63c"}.fa-ad,.fa-rectangle-ad{--fa:"\f641"}.fa-ankh{--fa:"\f644"}.fa-bible,.fa-book-bible{--fa:"\f647"}.fa-briefcase-clock,.fa-business-time{--fa:"\f64a"}.fa-city{--fa:"\f64f"}.fa-comment-dollar{--fa:"\f651"}.fa-comments-dollar{--fa:"\f653"}.fa-cross{--fa:"\f654"}.fa-dharmachakra{--fa:"\f655"}.fa-envelope-open-text{--fa:"\f658"}.fa-folder-minus{--fa:"\f65d"}.fa-folder-plus{--fa:"\f65e"}.fa-filter-circle-dollar,.fa-funnel-dollar{--fa:"\f662"}.fa-gopuram{--fa:"\f664"}.fa-hamsa{--fa:"\f665"}.fa-bahai,.fa-haykal{--fa:"\f666"}.fa-jedi{--fa:"\f669"}.fa-book-journal-whills,.fa-journal-whills{--fa:"\f66a"}.fa-kaaba{--fa:"\f66b"}.fa-khanda{--fa:"\f66d"}.fa-landmark{--fa:"\f66f"}.fa-envelopes-bulk,.fa-mail-bulk{--fa:"\f674"}.fa-menorah{--fa:"\f676"}.fa-mosque{--fa:"\f678"}.fa-om{--fa:"\f679"}.fa-pastafarianism,.fa-spaghetti-monster-flying{--fa:"\f67b"}.fa-peace{--fa:"\f67c"}.fa-place-of-worship{--fa:"\f67f"}.fa-poll,.fa-square-poll-vertical{--fa:"\f681"}.fa-poll-h,.fa-square-poll-horizontal{--fa:"\f682"}.fa-person-praying,.fa-pray{--fa:"\f683"}.fa-hands-praying,.fa-praying-hands{--fa:"\f684"}.fa-book-quran,.fa-quran{--fa:"\f687"}.fa-magnifying-glass-dollar,.fa-search-dollar{--fa:"\f688"}.fa-magnifying-glass-location,.fa-search-location{--fa:"\f689"}.fa-socks{--fa:"\f696"}.fa-square-root-alt,.fa-square-root-variable{--fa:"\f698"}.fa-star-and-crescent{--fa:"\f699"}.fa-star-of-david{--fa:"\f69a"}.fa-synagogue{--fa:"\f69b"}.fa-scroll-torah,.fa-torah{--fa:"\f6a0"}.fa-torii-gate{--fa:"\f6a1"}.fa-vihara{--fa:"\f6a7"}.fa-volume-mute,.fa-volume-times,.fa-volume-xmark{--fa:"\f6a9"}.fa-yin-yang{--fa:"\f6ad"}.fa-blender-phone{--fa:"\f6b6"}.fa-book-dead,.fa-book-skull{--fa:"\f6b7"}.fa-campground{--fa:"\f6bb"}.fa-cat{--fa:"\f6be"}.fa-chair{--fa:"\f6c0"}.fa-cloud-moon{--fa:"\f6c3"}.fa-cloud-sun{--fa:"\f6c4"}.fa-cow{--fa:"\f6c8"}.fa-dice-d20{--fa:"\f6cf"}.fa-dice-d6{--fa:"\f6d1"}.fa-dog{--fa:"\f6d3"}.fa-dragon{--fa:"\f6d5"}.fa-drumstick-bite{--fa:"\f6d7"}.fa-dungeon{--fa:"\f6d9"}.fa-file-csv{--fa:"\f6dd"}.fa-fist-raised,.fa-hand-fist{--fa:"\f6de"}.fa-ghost{--fa:"\f6e2"}.fa-hammer{--fa:"\f6e3"}.fa-hanukiah{--fa:"\f6e6"}.fa-hat-wizard{--fa:"\f6e8"}.fa-hiking,.fa-person-hiking{--fa:"\f6ec"}.fa-hippo{--fa:"\f6ed"}.fa-horse{--fa:"\f6f0"}.fa-house-chimney-crack,.fa-house-damage{--fa:"\f6f1"}.fa-hryvnia,.fa-hryvnia-sign{--fa:"\f6f2"}.fa-mask{--fa:"\f6fa"}.fa-mountain{--fa:"\f6fc"}.fa-network-wired{--fa:"\f6ff"}.fa-otter{--fa:"\f700"}.fa-ring{--fa:"\f70b"}.fa-person-running,.fa-running{--fa:"\f70c"}.fa-scroll{--fa:"\f70e"}.fa-skull-crossbones{--fa:"\f714"}.fa-slash{--fa:"\f715"}.fa-spider{--fa:"\f717"}.fa-toilet-paper,.fa-toilet-paper-alt,.fa-toilet-paper-blank{--fa:"\f71e"}.fa-tractor{--fa:"\f722"}.fa-user-injured{--fa:"\f728"}.fa-vr-cardboard{--fa:"\f729"}.fa-wand-sparkles{--fa:"\f72b"}.fa-wind{--fa:"\f72e"}.fa-wine-bottle{--fa:"\f72f"}.fa-cloud-meatball{--fa:"\f73b"}.fa-cloud-moon-rain{--fa:"\f73c"}.fa-cloud-rain{--fa:"\f73d"}.fa-cloud-showers-heavy{--fa:"\f740"}.fa-cloud-sun-rain{--fa:"\f743"}.fa-democrat{--fa:"\f747"}.fa-flag-usa{--fa:"\f74d"}.fa-hurricane{--fa:"\f751"}.fa-landmark-alt,.fa-landmark-dome{--fa:"\f752"}.fa-meteor{--fa:"\f753"}.fa-person-booth{--fa:"\f756"}.fa-poo-bolt,.fa-poo-storm{--fa:"\f75a"}.fa-rainbow{--fa:"\f75b"}.fa-republican{--fa:"\f75e"}.fa-smog{--fa:"\f75f"}.fa-temperature-high{--fa:"\f769"}.fa-temperature-low{--fa:"\f76b"}.fa-cloud-bolt,.fa-thunderstorm{--fa:"\f76c"}.fa-tornado{--fa:"\f76f"}.fa-volcano{--fa:"\f770"}.fa-check-to-slot,.fa-vote-yea{--fa:"\f772"}.fa-water{--fa:"\f773"}.fa-baby{--fa:"\f77c"}.fa-baby-carriage,.fa-carriage-baby{--fa:"\f77d"}.fa-biohazard{--fa:"\f780"}.fa-blog{--fa:"\f781"}.fa-calendar-day{--fa:"\f783"}.fa-calendar-week{--fa:"\f784"}.fa-candy-cane{--fa:"\f786"}.fa-carrot{--fa:"\f787"}.fa-cash-register{--fa:"\f788"}.fa-compress-arrows-alt,.fa-minimize{--fa:"\f78c"}.fa-dumpster{--fa:"\f793"}.fa-dumpster-fire{--fa:"\f794"}.fa-ethernet{--fa:"\f796"}.fa-gifts{--fa:"\f79c"}.fa-champagne-glasses,.fa-glass-cheers{--fa:"\f79f"}.fa-glass-whiskey,.fa-whiskey-glass{--fa:"\f7a0"}.fa-earth-europe,.fa-globe-europe{--fa:"\f7a2"}.fa-grip-lines{--fa:"\f7a4"}.fa-grip-lines-vertical{--fa:"\f7a5"}.fa-guitar{--fa:"\f7a6"}.fa-heart-broken,.fa-heart-crack{--fa:"\f7a9"}.fa-holly-berry{--fa:"\f7aa"}.fa-horse-head{--fa:"\f7ab"}.fa-icicles{--fa:"\f7ad"}.fa-igloo{--fa:"\f7ae"}.fa-mitten{--fa:"\f7b5"}.fa-mug-hot{--fa:"\f7b6"}.fa-radiation{--fa:"\f7b9"}.fa-circle-radiation,.fa-radiation-alt{--fa:"\f7ba"}.fa-restroom{--fa:"\f7bd"}.fa-satellite{--fa:"\f7bf"}.fa-satellite-dish{--fa:"\f7c0"}.fa-sd-card{--fa:"\f7c2"}.fa-sim-card{--fa:"\f7c4"}.fa-person-skating,.fa-skating{--fa:"\f7c5"}.fa-person-skiing,.fa-skiing{--fa:"\f7c9"}.fa-person-skiing-nordic,.fa-skiing-nordic{--fa:"\f7ca"}.fa-sleigh{--fa:"\f7cc"}.fa-comment-sms,.fa-sms{--fa:"\f7cd"}.fa-person-snowboarding,.fa-snowboarding{--fa:"\f7ce"}.fa-snowman{--fa:"\f7d0"}.fa-snowplow{--fa:"\f7d2"}.fa-tenge,.fa-tenge-sign{--fa:"\f7d7"}.fa-toilet{--fa:"\f7d8"}.fa-screwdriver-wrench,.fa-tools{--fa:"\f7d9"}.fa-cable-car,.fa-tram{--fa:"\f7da"}.fa-fire-alt,.fa-fire-flame-curved{--fa:"\f7e4"}.fa-bacon{--fa:"\f7e5"}.fa-book-medical{--fa:"\f7e6"}.fa-bread-slice{--fa:"\f7ec"}.fa-cheese{--fa:"\f7ef"}.fa-clinic-medical,.fa-house-chimney-medical{--fa:"\f7f2"}.fa-clipboard-user{--fa:"\f7f3"}.fa-comment-medical{--fa:"\f7f5"}.fa-crutch{--fa:"\f7f7"}.fa-disease{--fa:"\f7fa"}.fa-egg{--fa:"\f7fb"}.fa-folder-tree{--fa:"\f802"}.fa-burger,.fa-hamburger{--fa:"\f805"}.fa-hand-middle-finger{--fa:"\f806"}.fa-hard-hat,.fa-hat-hard,.fa-helmet-safety{--fa:"\f807"}.fa-hospital-user{--fa:"\f80d"}.fa-hotdog{--fa:"\f80f"}.fa-ice-cream{--fa:"\f810"}.fa-laptop-medical{--fa:"\f812"}.fa-pager{--fa:"\f815"}.fa-pepper-hot{--fa:"\f816"}.fa-pizza-slice{--fa:"\f818"}.fa-sack-dollar{--fa:"\f81d"}.fa-book-tanakh,.fa-tanakh{--fa:"\f827"}.fa-bars-progress,.fa-tasks-alt{--fa:"\f828"}.fa-trash-arrow-up,.fa-trash-restore{--fa:"\f829"}.fa-trash-can-arrow-up,.fa-trash-restore-alt{--fa:"\f82a"}.fa-user-nurse{--fa:"\f82f"}.fa-wave-square{--fa:"\f83e"}.fa-biking,.fa-person-biking{--fa:"\f84a"}.fa-border-all{--fa:"\f84c"}.fa-border-none{--fa:"\f850"}.fa-border-style,.fa-border-top-left{--fa:"\f853"}.fa-digging,.fa-person-digging{--fa:"\f85e"}.fa-fan{--fa:"\f863"}.fa-heart-music-camera-bolt,.fa-icons{--fa:"\f86d"}.fa-phone-alt,.fa-phone-flip{--fa:"\f879"}.fa-phone-square-alt,.fa-square-phone-flip{--fa:"\f87b"}.fa-photo-film,.fa-photo-video{--fa:"\f87c"}.fa-remove-format,.fa-text-slash{--fa:"\f87d"}.fa-arrow-down-z-a,.fa-sort-alpha-desc,.fa-sort-alpha-down-alt{--fa:"\f881"}.fa-arrow-up-z-a,.fa-sort-alpha-up-alt{--fa:"\f882"}.fa-arrow-down-short-wide,.fa-sort-amount-desc,.fa-sort-amount-down-alt{--fa:"\f884"}.fa-arrow-up-short-wide,.fa-sort-amount-up-alt{--fa:"\f885"}.fa-arrow-down-9-1,.fa-sort-numeric-desc,.fa-sort-numeric-down-alt{--fa:"\f886"}.fa-arrow-up-9-1,.fa-sort-numeric-up-alt{--fa:"\f887"}.fa-spell-check{--fa:"\f891"}.fa-voicemail{--fa:"\f897"}.fa-hat-cowboy{--fa:"\f8c0"}.fa-hat-cowboy-side{--fa:"\f8c1"}.fa-computer-mouse,.fa-mouse{--fa:"\f8cc"}.fa-radio{--fa:"\f8d7"}.fa-record-vinyl{--fa:"\f8d9"}.fa-walkie-talkie{--fa:"\f8ef"}.fa-caravan{--fa:"\f8ff"}
diff --git a/src/media/vendor/fa7free/css/regular.css b/src/media/vendor/fa7free/css/regular.css
new file mode 100644
index 0000000..0715c62
--- /dev/null
+++ b/src/media/vendor/fa7free/css/regular.css
@@ -0,0 +1,31 @@
+/*!
+ * Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ * Copyright 2025 Fonticons, Inc.
+ */
+:root, :host {
+ --fa-family-classic: "Font Awesome 7 Free";
+ --fa-font-regular: normal 400 1em/1 var(--fa-family-classic);
+ /* deprecated: this older custom property will be removed next major release */
+ --fa-style-family-classic: var(--fa-family-classic);
+}
+
+@font-face {
+ font-family: "Font Awesome 7 Free";
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src: url("../webfonts/fa-regular-400.woff2");
+}
+.far {
+ --fa-family: var(--fa-family-classic);
+ --fa-style: 400;
+}
+
+.fa-classic {
+ --fa-family: var(--fa-family-classic);
+}
+
+.fa-regular {
+ --fa-style: 400;
+}
\ No newline at end of file
diff --git a/src/media/vendor/fa7free/css/regular.min.css b/src/media/vendor/fa7free/css/regular.min.css
new file mode 100644
index 0000000..97f7b13
--- /dev/null
+++ b/src/media/vendor/fa7free/css/regular.min.css
@@ -0,0 +1,6 @@
+/*!
+ * Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ * Copyright 2025 Fonticons, Inc.
+ */
+:host,:root{--fa-family-classic:"Font Awesome 7 Free";--fa-font-regular:normal 400 1em/1 var(--fa-family-classic);--fa-style-family-classic:var(--fa-family-classic)}@font-face{font-family:"Font Awesome 7 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2)}.far{--fa-style:400}.fa-classic,.far{--fa-family:var(--fa-family-classic)}.fa-regular{--fa-style:400}
\ No newline at end of file
diff --git a/src/media/vendor/fa7free/css/solid.css b/src/media/vendor/fa7free/css/solid.css
new file mode 100644
index 0000000..a70ad2e
--- /dev/null
+++ b/src/media/vendor/fa7free/css/solid.css
@@ -0,0 +1,31 @@
+/*!
+ * Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ * Copyright 2025 Fonticons, Inc.
+ */
+:root, :host {
+ --fa-family-classic: "Font Awesome 7 Free";
+ --fa-font-solid: normal 900 1em/1 var(--fa-family-classic);
+ /* deprecated: this older custom property will be removed next major release */
+ --fa-style-family-classic: var(--fa-family-classic);
+}
+
+@font-face {
+ font-family: "Font Awesome 7 Free";
+ font-style: normal;
+ font-weight: 900;
+ font-display: block;
+ src: url("../webfonts/fa-solid-900.woff2");
+}
+.fas {
+ --fa-family: var(--fa-family-classic);
+ --fa-style: 900;
+}
+
+.fa-classic {
+ --fa-family: var(--fa-family-classic);
+}
+
+.fa-solid {
+ --fa-style: 900;
+}
\ No newline at end of file
diff --git a/src/media/vendor/fa7free/css/solid.min.css b/src/media/vendor/fa7free/css/solid.min.css
new file mode 100644
index 0000000..db1cd68
--- /dev/null
+++ b/src/media/vendor/fa7free/css/solid.min.css
@@ -0,0 +1,6 @@
+/*!
+ * Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ * Copyright 2025 Fonticons, Inc.
+ */
+:host,:root{--fa-family-classic:"Font Awesome 7 Free";--fa-font-solid:normal 900 1em/1 var(--fa-family-classic);--fa-style-family-classic:var(--fa-family-classic)}@font-face{font-family:"Font Awesome 7 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2)}.fas{--fa-style:900}.fa-classic,.fas{--fa-family:var(--fa-family-classic)}.fa-solid{--fa-style:900}
\ No newline at end of file
diff --git a/src/media/vendor/fa7free/webfonts/fa-brands-400.woff2 b/src/media/vendor/fa7free/webfonts/fa-brands-400.woff2
new file mode 100644
index 0000000..d0b8f69
Binary files /dev/null and b/src/media/vendor/fa7free/webfonts/fa-brands-400.woff2 differ
diff --git a/src/media/vendor/fa7free/webfonts/fa-regular-400.woff2 b/src/media/vendor/fa7free/webfonts/fa-regular-400.woff2
new file mode 100644
index 0000000..2eca12b
Binary files /dev/null and b/src/media/vendor/fa7free/webfonts/fa-regular-400.woff2 differ
diff --git a/src/media/vendor/fa7free/webfonts/fa-solid-900.woff2 b/src/media/vendor/fa7free/webfonts/fa-solid-900.woff2
new file mode 100644
index 0000000..c20c7f4
Binary files /dev/null and b/src/media/vendor/fa7free/webfonts/fa-solid-900.woff2 differ
diff --git a/src/media/vendor/fa7free/webfonts/fa-v4compatibility.woff2 b/src/media/vendor/fa7free/webfonts/fa-v4compatibility.woff2
new file mode 100644
index 0000000..275e92f
Binary files /dev/null and b/src/media/vendor/fa7free/webfonts/fa-v4compatibility.woff2 differ
diff --git a/src/media/vendor/index.html b/src/media/vendor/index.html
new file mode 100644
index 0000000..1a6c6cf
--- /dev/null
+++ b/src/media/vendor/index.html
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+ Redirecting…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Redirecting to the site root… If you are not redirected,
click here .
+
+
diff --git a/src/offline.php b/src/offline.php
new file mode 100644
index 0000000..32b789b
--- /dev/null
+++ b/src/offline.php
@@ -0,0 +1,414 @@
+
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+declare(strict_types=1);
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Component\ComponentHelper;
+use Joomla\CMS\Factory;
+use Joomla\CMS\HTML\HTMLHelper;
+use Joomla\CMS\Language\Text;
+use Joomla\CMS\Router\Route;
+use Joomla\CMS\Uri\Uri;
+
+/**
+ * @var \Joomla\CMS\Document\HtmlDocument $this
+ * @var \Joomla\Registry\Registry $this->params
+ * @var string $this->language
+ * @var string $this->direction
+ */
+
+$app = Factory::getApplication();
+$doc = Factory::getDocument();
+$wa = $doc->getWebAssetManager();
+$params = $this->params ?: $app->getTemplate(true)->params;
+$direction = $this->direction ?: 'ltr';
+
+// Register the template's asset manifest (not auto-loaded in offline context)
+$manifestPath = JPATH_ROOT . '/media/templates/site/' . $this->template . '/joomla.asset.json';
+if (is_file($manifestPath)) {
+ $wa->getRegistry()->addRegistryFile($manifestPath);
+}
+
+// Load language files (not auto-loaded in offline context)
+$lang = Factory::getLanguage();
+$lang->load('tpl_' . $this->template, JPATH_ROOT . '/templates/' . $this->template);
+$lang->load('tpl_' . $this->template, JPATH_ROOT);
+$lang->load('com_users', JPATH_ROOT);
+$lang->load('com_users', JPATH_ROOT . '/components/com_users');
+$lang->load('', JPATH_ROOT);
+
+/* -----------------------
+ Load assets via WebAssetManager (matches index.php pattern)
+------------------------ */
+$params_developmentmode = (bool) $params->get('developmentmode', false) || (bool) $app->get('debug', false);
+$suffix = $params_developmentmode ? '' : '.min';
+
+// Core template CSS + offline overlay CSS
+$wa->useStyle('template.base' . $suffix);
+$wa->useStyle('template.offline' . $suffix);
+
+// Osaka font
+$wa->useStyle('template.font.osaka');
+
+// Font Awesome 7 Free
+$wa->useStyle('vendor.fa7free.all' . $suffix);
+
+// Theme palettes
+$wa->useStyle('template.light.standard' . $suffix);
+$wa->useStyle('template.dark.standard' . $suffix);
+
+// Custom palettes (if selected and files exist)
+$params_LightColorName = (string) $params->get('colorLightName', 'standard');
+$params_DarkColorName = (string) $params->get('colorDarkName', 'standard');
+if ($params_LightColorName === 'custom' && file_exists(JPATH_ROOT . '/media/templates/site/mokoonyx/css/theme/light.custom.css'))
+{
+ $wa->useStyle('template.light.custom' . $suffix);
+}
+if ($params_DarkColorName === 'custom' && file_exists(JPATH_ROOT . '/media/templates/site/mokoonyx/css/theme/dark.custom.css'))
+{
+ $wa->useStyle('template.dark.custom' . $suffix);
+}
+
+// User overrides (loaded last)
+$wa->useStyle('template.user');
+
+// Accessibility high-contrast stylesheet
+$wa->useStyle('template.a11y-high-contrast');
+
+// Template JS (theme switcher, a11y toolbar, var-copy, etc.)
+if ($params_developmentmode) {
+ $wa->useScript('template.js');
+} else {
+ $wa->useScript('template.js.min');
+}
+$wa->useScript('user.js');
+
+// Bootstrap CSS + JS (accordion, responsive grid, utilities)
+try {
+ $wa->useStyle('bootstrap.css');
+} catch (\Exception $e) {
+ // Fallback: load via HTMLHelper
+ HTMLHelper::_('bootstrap.loadCss', true, $doc);
+}
+HTMLHelper::_('bootstrap.framework');
+
+/* -----------------------
+ Title + Meta
+------------------------ */
+$sitename = (string) $app->get('sitename');
+$baseTitle = Text::_('JGLOBAL_OFFLINE') ?: 'Offline';
+$snSetting = (int) $app->get('sitename_pagetitles', 0);
+
+if ($snSetting === 1) {
+ $doc->setTitle(Text::sprintf('JPAGETITLE', $sitename, $baseTitle));
+} elseif ($snSetting === 2) {
+ $doc->setTitle(Text::sprintf('JPAGETITLE', $baseTitle, $sitename));
+} else {
+ $doc->setTitle($baseTitle);
+}
+$doc->setMetaData('robots', 'noindex, nofollow');
+
+/* -----------------------
+ Offline content from Global Config
+------------------------ */
+$displayOfflineMessage = (int) $app->get('display_offline_message', 1);
+$offlineMessage = trim((string) $app->get('offline_message', ''));
+
+/* -----------------------
+ Offline image from Joomla Global Config (System > Global Configuration > Site > Offline Image)
+ Used as the full-viewport background image.
+------------------------ */
+$offlineImage = trim((string) $app->get('offline_image', ''));
+$bgStyle = '';
+if ($offlineImage !== '') {
+ $bgStyle = 'background-image: url(\'' . htmlspecialchars(Uri::root(false) . $offlineImage, ENT_QUOTES, 'UTF-8') . '\');';
+}
+
+/* -----------------------
+ Brand: logo from template params OR siteTitle
+------------------------ */
+$brandHtml = '';
+$logoFile = (string) $params->get('logoFile');
+
+if ($logoFile !== '') {
+ $brandHtml = HTMLHelper::_(
+ 'image',
+ Uri::root(false) . htmlspecialchars($logoFile, ENT_QUOTES, 'UTF-8'),
+ $sitename,
+ ['class' => 'logo d-inline-block', 'loading' => 'eager', 'decoding' => 'async'],
+ false,
+ 0
+ );
+} else {
+ $siteTitle = $params->get('siteTitle', 'MokoOnyx');
+ $brandHtml = ''
+ . htmlspecialchars($siteTitle, ENT_COMPAT, 'UTF-8')
+ . ' ';
+}
+
+$brandTagline = (string) ($params->get('brand_tagline') ?: $params->get('siteDescription') ?: '');
+$showTagline = (int) $params->get('show_brand_tagline', 0);
+
+// Favicon
+$params_favicon_source = (string) $params->get('favicon_source', '');
+$faviconHeadTags = '';
+if ($params_favicon_source) {
+ require_once JPATH_ROOT . '/templates/' . $this->template . '/helper/favicon.php';
+ $faviconSourceAbs = JPATH_ROOT . '/' . ltrim($params_favicon_source, '/');
+ $faviconOutputDir = JPATH_ROOT . '/images/favicons';
+ $faviconUrlBase = Uri::root(true) . '/images/favicons';
+
+ if (MokoFaviconHelper::generate($faviconSourceAbs, $faviconOutputDir)) {
+ $faviconHeadTags = MokoFaviconHelper::getHeadTags($faviconUrlBase);
+ }
+}
+
+// Theme params
+$params_theme_enabled = (int) $params->get('theme_enabled', 1);
+$params_theme_fab_enabled = (int) $params->get('theme_fab_enabled', 1);
+$params_theme_fab_pos = 'br';
+
+// Accessibility params
+$params_a11y_toolbar = (int) $params->get('a11y_toolbar_enabled', 1);
+$params_a11y_resize = (int) $params->get('a11y_text_resize', 1);
+$params_a11y_invert = (int) $params->get('a11y_color_inversion', 1);
+$params_a11y_contrast = (int) $params->get('a11y_high_contrast', 1);
+$params_a11y_links = (int) $params->get('a11y_highlight_links', 1);
+$params_a11y_font = (int) $params->get('a11y_readable_font', 1);
+$params_a11y_animations = (int) $params->get('a11y_pause_animations', 1);
+$params_a11y_pos = 'br';
+
+// Analytics params
+$params_googletagmanager = $params->get('googletagmanager', false);
+$params_googletagmanagerid = $params->get('googletagmanagerid', null);
+$params_googleanalytics = $params->get('googleanalytics', false);
+$params_googleanalyticsid = $params->get('googleanalyticsid', null);
+$params_googlesitekey = $params->get('googlesitekey', null);
+
+if (!empty($params_googlesitekey)) {
+ $doc->setMetaData('google-site-verification', htmlspecialchars($params_googlesitekey, ENT_QUOTES, 'UTF-8'));
+}
+
+/* -----------------------
+ Login routes
+------------------------ */
+$action = Route::_('index.php', true);
+$return = base64_encode(Uri::base());
+$allowRegistration = (bool) ComponentHelper::getParams('com_users')->get('allowUserRegistration', 0);
+
+if (class_exists('\Joomla\Component\Users\Site\Helper\RouteHelper')) {
+ $resetUrl = \Joomla\Component\Users\Site\Helper\RouteHelper::getResetRoute();
+ $remindUrl = \Joomla\Component\Users\Site\Helper\RouteHelper::getRemindRoute();
+ $registrationUrl = \Joomla\Component\Users\Site\Helper\RouteHelper::getRegistrationRoute();
+} else {
+ $resetUrl = Route::_('index.php?option=com_users&view=reset');
+ $remindUrl = Route::_('index.php?option=com_users&view=remind');
+ $registrationUrl = Route::_('index.php?option=com_users&view=registration');
+}
+?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+style="">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ countModules('offline')) : ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ countModules('offline-footer')) : ?>
+
+
+
+
+
+
+
+
diff --git a/src/script.php b/src/script.php
new file mode 100644
index 0000000..8fcfb36
--- /dev/null
+++ b/src/script.php
@@ -0,0 +1,221 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * Template install/update/uninstall script.
+ * Joomla calls the methods in this class automatically during template
+ * install, update, and uninstall via the element in
+ * templateDetails.xml.
+ * Joomla 5 and 6 compatible — uses the InstallerScriptInterface when
+ * available, falls back to the legacy class-based approach otherwise.
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Factory;
+use Joomla\CMS\Installer\InstallerAdapter;
+use Joomla\CMS\Log\Log;
+
+class Tpl_MokoonyxInstallerScript
+{
+ /**
+ * Minimum PHP version required by this template.
+ */
+ private const MIN_PHP = '8.1.0';
+
+ /**
+ * Minimum Joomla version required by this template.
+ */
+ private const MIN_JOOMLA = '4.4.0';
+
+ /**
+ * Called before install/update/uninstall.
+ *
+ * @param string $type install, update, discover_install, or uninstall.
+ * @param InstallerAdapter $parent The adapter calling this method.
+ *
+ * @return bool True to proceed, false to abort.
+ */
+ public function preflight(string $type, InstallerAdapter $parent): bool
+ {
+ if (version_compare(PHP_VERSION, self::MIN_PHP, '<')) {
+ Factory::getApplication()->enqueueMessage(
+ sprintf(
+ 'MokoOnyx requires PHP %s or later. You are running PHP %s.',
+ self::MIN_PHP,
+ PHP_VERSION
+ ),
+ 'error'
+ );
+ return false;
+ }
+
+ if (version_compare(JVERSION, self::MIN_JOOMLA, '<')) {
+ Factory::getApplication()->enqueueMessage(
+ sprintf(
+ 'MokoOnyx requires Joomla %s or later. You are running Joomla %s.',
+ self::MIN_JOOMLA,
+ JVERSION
+ ),
+ 'error'
+ );
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Called after a successful install.
+ *
+ * @param InstallerAdapter $parent The adapter calling this method.
+ *
+ * @return bool
+ */
+ public function install(InstallerAdapter $parent): bool
+ {
+ $this->logMessage('MokoOnyx template installed.');
+ return true;
+ }
+
+ /**
+ * Called after a successful update.
+ *
+ * This is where the CSS variable sync runs — it detects variables that
+ * were added in the new version and injects them into the user's custom
+ * palette files without overwriting existing values.
+ *
+ * @param InstallerAdapter $parent The adapter calling this method.
+ *
+ * @return bool
+ */
+ public function update(InstallerAdapter $parent): bool
+ {
+ $this->logMessage('MokoOnyx template updated.');
+
+ // Run CSS variable sync to inject any new variables into user's custom palettes.
+ $synced = $this->syncCustomVariables($parent);
+
+ if ($synced > 0) {
+ Factory::getApplication()->enqueueMessage(
+ sprintf(
+ 'MokoOnyx: %d new CSS variable(s) were added to your custom palette files. '
+ . 'Review them in your light.custom.css and/or dark.custom.css to customise the new defaults.',
+ $synced
+ ),
+ 'notice'
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * Called after a successful uninstall.
+ *
+ * @param InstallerAdapter $parent The adapter calling this method.
+ *
+ * @return bool
+ */
+ public function uninstall(InstallerAdapter $parent): bool
+ {
+ $this->logMessage('MokoOnyx template uninstalled.');
+ return true;
+ }
+
+ /**
+ * Called after install/update completes (regardless of type).
+ *
+ * @param string $type install, update, or discover_install.
+ * @param InstallerAdapter $parent The adapter calling this method.
+ *
+ * @return bool
+ */
+ public function postflight(string $type, InstallerAdapter $parent): bool
+ {
+ return true;
+ }
+
+ /**
+ * Run the CSS variable sync utility.
+ *
+ * Loads sync_custom_vars.php from the template directory and calls
+ * MokoCssVarSync::run() to detect and inject missing variables.
+ *
+ * @param InstallerAdapter $parent The adapter calling this method.
+ *
+ * @return int Number of variables added across all files.
+ */
+ private function syncCustomVariables(InstallerAdapter $parent): int
+ {
+ $templateDir = $parent->getParent()->getPath('source');
+
+ // The sync script lives alongside this script in the template root.
+ $syncScript = $templateDir . '/sync_custom_vars.php';
+
+ if (!is_file($syncScript)) {
+ $this->logMessage('CSS variable sync script not found at: ' . $syncScript, 'warning');
+ return 0;
+ }
+
+ require_once $syncScript;
+
+ if (!class_exists('MokoCssVarSync')) {
+ $this->logMessage('MokoCssVarSync class not found after loading script.', 'warning');
+ return 0;
+ }
+
+ try {
+ $joomlaRoot = JPATH_ROOT;
+ $results = MokoCssVarSync::run($joomlaRoot);
+
+ $totalAdded = 0;
+ foreach ($results as $filePath => $result) {
+ $totalAdded += count($result['added']);
+ if (!empty($result['added'])) {
+ $this->logMessage(
+ sprintf(
+ 'CSS sync: added %d variable(s) to %s',
+ count($result['added']),
+ basename($filePath)
+ )
+ );
+ }
+ }
+
+ return $totalAdded;
+ } catch (\Throwable $e) {
+ $this->logMessage('CSS variable sync failed: ' . $e->getMessage(), 'error');
+ return 0;
+ }
+ }
+
+ /**
+ * Log a message to Joomla's log system.
+ *
+ * @param string $message The log message.
+ * @param string $priority Log priority (info, warning, error).
+ */
+ private function logMessage(string $message, string $priority = 'info'): void
+ {
+ $priorities = [
+ 'info' => Log::INFO,
+ 'warning' => Log::WARNING,
+ 'error' => Log::ERROR,
+ ];
+
+ Log::addLogger(
+ ['text_file' => 'mokoonyx.log.php'],
+ Log::ALL,
+ ['mokoonyx']
+ );
+
+ Log::add($message, $priorities[$priority] ?? Log::INFO, 'mokoonyx');
+ }
+}
diff --git a/src/sync_custom_vars.php b/src/sync_custom_vars.php
new file mode 100644
index 0000000..b6a8459
--- /dev/null
+++ b/src/sync_custom_vars.php
@@ -0,0 +1,494 @@
+
+ *
+ * This file is part of a Moko Consulting project.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+/**
+ * CSS Variable Sync Utility
+ * Compares a user's custom palette file against the template starter file and
+ * injects any missing CSS variable declarations. Existing user values are
+ * never overwritten — only genuinely new variables are added.
+ * Usage (CLI):
+ * php sync_custom_vars.php
+ * Usage (from Joomla script.php or plugin):
+ * require_once __DIR__ . '/sync_custom_vars.php';
+ * MokoCssVarSync::run();
+ * The script auto-detects Joomla's root by walking up from __DIR__.
+ */
+
+defined('_JEXEC') or define('MOKO_CLI', true);
+
+final class MokoCssVarSync
+{
+ /**
+ * Template name used in Joomla's media path.
+ */
+ private const TPL = 'mokoonyx';
+
+ /**
+ * Palette pairs: [starter template path relative to this file, user file relative to Joomla root].
+ */
+ private const PALETTES = [
+ [
+ 'starter' => 'media/css/theme/light.standard.css',
+ 'user' => 'media/templates/site/%s/css/theme/light.custom.css',
+ ],
+ [
+ 'starter' => 'media/css/theme/dark.standard.css',
+ 'user' => 'media/templates/site/%s/css/theme/dark.custom.css',
+ ],
+ ];
+
+ /**
+ * Run the sync for all palette pairs.
+ *
+ * @param string|null $joomlaRoot Absolute path to Joomla root (auto-detected if null).
+ * @return array Results keyed by file path.
+ */
+ public static function run(?string $joomlaRoot = null): array
+ {
+ $tplDir = self::resolveTemplateDir();
+ $root = $joomlaRoot ?? self::detectJoomlaRoot();
+
+ $results = [];
+
+ foreach (self::PALETTES as $pair) {
+ $starterPath = $tplDir . '/' . $pair['starter'];
+ $userPath = $root . '/' . sprintf($pair['user'], self::TPL);
+
+ if (!is_file($starterPath)) {
+ self::log("SKIP starter not found: {$starterPath}");
+ continue;
+ }
+
+ if (!is_file($userPath)) {
+ self::log("SKIP user file not found (custom palette not deployed): {$userPath}");
+ continue;
+ }
+
+ $result = self::syncFile($starterPath, $userPath);
+ $results[$userPath] = $result;
+
+ $addedCount = count($result['added']);
+ if ($addedCount > 0) {
+ self::log("ADDED {$addedCount} variable(s) to {$userPath}");
+ foreach ($result['added'] as $var) {
+ self::log(" + {$var}");
+ }
+ } else {
+ self::log("OK {$userPath} — all variables present");
+ }
+ }
+
+ return $results;
+ }
+
+ /**
+ * Compare a starter file against a user file and inject missing variables.
+ *
+ * @param string $starterPath Absolute path to the starter template CSS.
+ * @param string $userPath Absolute path to the user's custom CSS.
+ * @return array{added: string[], skipped: string[]}
+ */
+ private static function syncFile(string $starterPath, string $userPath): array
+ {
+ $starterVars = self::extractVarsWithContext($starterPath);
+ $userVarsMap = self::extractVarsWithContext($userPath);
+ $userNames = self::extractVarNames($userPath);
+
+ // Find missing variables
+ $missing = [];
+ foreach ($starterVars as $name => $declaration) {
+ if (!isset($userNames[$name])) {
+ $missing[$name] = $declaration;
+ }
+ }
+
+ // Rebuild the entire :root block in starter file order.
+ // User's custom values are preserved; missing vars get starter defaults.
+ $reordered = self::rebuildInStarterOrder($starterPath, $userVarsMap, $missing);
+
+ // Replace the :root block in the user file with the reordered version.
+ $userCss = file_get_contents($userPath);
+ $userCss = self::replaceRootBlock($userCss, $reordered);
+
+ // Write back (atomic: write to .tmp then rename).
+ $tmpPath = $userPath . '.tmp';
+ file_put_contents($tmpPath, $userCss);
+ rename($tmpPath, $userPath);
+
+ return ['added' => array_keys($missing), 'skipped' => []];
+ }
+
+ /**
+ * Rebuild all variables in the order they appear in the starter file.
+ * User values are preserved; missing vars use starter defaults.
+ *
+ * @param string $starterPath Path to starter file.
+ * @param array $userVars User's variable name => declaration.
+ * @param array $missing Missing variable name => starter declaration.
+ * @return string Complete CSS content for inside :root { }.
+ */
+ private static function rebuildInStarterOrder(string $starterPath, array $userVars, array $missing): string
+ {
+ $lines = file($starterPath, FILE_IGNORE_NEW_LINES);
+ $output = [];
+ $inRoot = false;
+ $depth = 0;
+
+ foreach ($lines as $line) {
+ // Track when we enter :root (brace may be on same line)
+ if (!$inRoot && preg_match('/:root/', $line)) {
+ $inRoot = true;
+ // If { is on this same line, don't skip it — just continue processing
+ if (strpos($line, '{') === false) {
+ continue;
+ }
+ // Fall through to process the rest of this line
+ }
+
+ if (!$inRoot) {
+ continue;
+ }
+
+ // Track braces (skip lines that are ONLY a brace)
+ $trimmed = trim($line);
+ if ($trimmed === '{') {
+ continue;
+ }
+ if ($trimmed === '}') {
+ break; // End of :root
+ }
+
+ // Section comment headers — always include
+ if (preg_match('/\/\*\s*=+\s*.+?\s*=+\s*\*\//', $line)) {
+ $output[] = $line;
+ continue;
+ }
+
+ // Regular comments — include
+ if (preg_match('/^\s*\/\*/', $line) || preg_match('/^\s*\*/', $line)) {
+ $output[] = $line;
+ continue;
+ }
+
+ // Blank lines — include
+ if (trim($line) === '') {
+ $output[] = '';
+ continue;
+ }
+
+ // Variable declaration
+ if (preg_match('/^\s*(--[\w-]+)\s*:/', $line, $m)) {
+ $name = trim($m[1]);
+ if (isset($userVars[$name])) {
+ // Use the user's custom value
+ $output[] = $userVars[$name];
+ } elseif (isset($missing[$name])) {
+ // New variable — use starter default
+ $output[] = $missing[$name];
+ }
+ continue;
+ }
+
+ // Other lines (e.g. color-scheme) — include as-is
+ $output[] = $line;
+ }
+
+ return implode("\n", $output);
+ }
+
+ /**
+ * Replace the content inside :root { ... } with new content.
+ */
+ private static function replaceRootBlock(string $css, string $newContent): string
+ {
+ $rootStart = preg_match('/:root[^{]*\{/', $css, $m, PREG_OFFSET_CAPTURE);
+ if (!$rootStart) {
+ return $css;
+ }
+
+ $openBrace = $m[0][1] + strlen($m[0][0]);
+ $closeBrace = self::findRootClosingBrace($css);
+
+ if ($closeBrace === false) {
+ return $css;
+ }
+
+ return substr($css, 0, $openBrace) . "\n" . $newContent . "\n" . substr($css, $closeBrace);
+ }
+
+ /**
+ * Extract CSS custom property declarations with their full text (name: value).
+ * Only extracts from the first :root block.
+ *
+ * @return array Variable name => full declaration line.
+ */
+ private static function extractVarsWithContext(string $filePath): array
+ {
+ $css = file_get_contents($filePath);
+ $vars = [];
+
+ // Match --variable-name: value (possibly spanning multiple lines until ;)
+ if (preg_match_all('/^\s*(--[\w-]+)\s*:\s*([^;]+);/m', $css, $matches, PREG_SET_ORDER)) {
+ foreach ($matches as $m) {
+ $name = trim($m[1]);
+ $value = trim($m[2]);
+ $vars[$name] = "{$name}: {$value};";
+ }
+ }
+
+ return $vars;
+ }
+
+ /**
+ * Extract just the variable names present in a CSS file.
+ *
+ * @return array
+ */
+ private static function extractVarNames(string $filePath): array
+ {
+ $css = file_get_contents($filePath);
+ $vars = [];
+
+ if (preg_match_all('/^\s*(--[\w-]+)\s*:/m', $css, $matches)) {
+ foreach ($matches[1] as $name) {
+ $vars[trim($name)] = true;
+ }
+ }
+
+ return $vars;
+ }
+
+ /**
+ * Group missing variables by the section comment they appear under in the starter file.
+ *
+ * @param array $missing Variable name => declaration.
+ * @param string $starterPath Path to starter file.
+ * @return array Section header => list of declarations.
+ */
+ private static function groupBySection(array $missing, string $starterPath): array
+ {
+ $lines = file($starterPath, FILE_IGNORE_NEW_LINES);
+ $section = 'Uncategorised';
+
+ // Walk the starter file in order — this preserves the original
+ // variable ordering so injected variables match the standard theme layout.
+ $sections = [];
+
+ foreach ($lines as $line) {
+ // Detect section comment headers like /* ===== HERO VARIANTS ===== */
+ if (preg_match('/\/\*\s*=+\s*(.+?)\s*=+\s*\*\//', $line, $m)) {
+ $section = trim($m[1]);
+ }
+ // Detect variable declaration — only include if it's missing from user file
+ if (preg_match('/^\s*(--[\w-]+)\s*:/', $line, $m)) {
+ $name = trim($m[1]);
+ if (isset($missing[$name])) {
+ $sections[$section][] = $missing[$name];
+ }
+ }
+ }
+
+ return $sections;
+ }
+
+ /**
+ * Build a CSS block from grouped sections ready for injection.
+ */
+ private static function buildInjectionBlock(array $sections): string
+ {
+ $lines = [];
+ $lines[] = '';
+ $lines[] = '/* ===== VARIABLES ADDED BY SYNC (' . date('Y-m-d') . ') ===== */';
+
+ foreach ($sections as $sectionName => $declarations) {
+ $lines[] = '';
+ $lines[] = "/* -- {$sectionName} -- */";
+ foreach ($declarations as $decl) {
+ $lines[] = $decl;
+ }
+ }
+
+ $lines[] = '';
+
+ return implode("\n", $lines);
+ }
+
+ /**
+ * Inject a block of CSS just before the closing } of the :root[data-bs-theme] rule.
+ */
+ private static function injectBeforeRootClose(string $css, string $block): string
+ {
+ // Find the :root block's closing brace. The :root rule is the first major
+ // rule in the file; its closing } is on its own line.
+ // Strategy: find the LAST } that is preceded only by CSS variable content.
+ // More robustly: find the first } that appears on its own line (possibly
+ // with whitespace), which closes the :root block.
+
+ // Walk backwards from each } to see if it's inside the :root block.
+ // Simple approach: the :root closing } is the first bare } on its own line.
+ $pos = self::findRootClosingBrace($css);
+
+ if ($pos === false) {
+ // Fallback: append before last }
+ $pos = strrpos($css, '}');
+ }
+
+ if ($pos === false) {
+ // Last resort: append to end
+ return $css . $block;
+ }
+
+ return substr($css, 0, $pos) . $block . substr($css, $pos);
+ }
+
+ /**
+ * Find the byte position of the closing } for the :root rule.
+ */
+ private static function findRootClosingBrace(string $css): int|false
+ {
+ // Find where :root starts
+ $rootStart = preg_match('/:root\b/', $css, $m, PREG_OFFSET_CAPTURE);
+ if (!$rootStart) {
+ return false;
+ }
+
+ $offset = $m[0][1];
+ $depth = 0;
+ $len = strlen($css);
+
+ for ($i = $offset; $i < $len; $i++) {
+ if ($css[$i] === '{') {
+ $depth++;
+ } elseif ($css[$i] === '}') {
+ $depth--;
+ if ($depth === 0) {
+ return $i;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Resolve the template source directory (where this file lives).
+ */
+ private static function resolveTemplateDir(): string
+ {
+ return dirname(__FILE__);
+ }
+
+ /**
+ * Auto-detect Joomla root by walking up from template dir looking for
+ * configuration.php or the media/templates directory structure.
+ */
+ private static function detectJoomlaRoot(): string
+ {
+ $dir = dirname(__FILE__);
+
+ // Walk up max 10 levels
+ for ($i = 0; $i < 10; $i++) {
+ if (is_file($dir . '/configuration.php')) {
+ return $dir;
+ }
+ // Also check for the media/templates structure (works in dev too)
+ if (is_dir($dir . '/media/templates')) {
+ return $dir;
+ }
+ $parent = dirname($dir);
+ if ($parent === $dir) {
+ break;
+ }
+ $dir = $parent;
+ }
+
+ // Fallback for dev: if JPATH_ROOT is defined, use it
+ if (defined('JPATH_ROOT')) {
+ return JPATH_ROOT;
+ }
+
+ self::log('WARNING: Could not auto-detect Joomla root. Pass it explicitly.');
+ return dirname(__FILE__);
+ }
+
+ /**
+ * Log a message (CLI: stdout, web: Joomla enqueueMessage if available).
+ */
+ private static function log(string $message): void
+ {
+ if (defined('MOKO_CLI') || PHP_SAPI === 'cli') {
+ echo $message . PHP_EOL;
+ }
+ }
+
+ /**
+ * Dry-run mode: report what would be added without writing.
+ *
+ * @return array File path => list of missing variable names.
+ */
+ public static function dryRun(?string $joomlaRoot = null): array
+ {
+ $tplDir = self::resolveTemplateDir();
+ $root = $joomlaRoot ?? self::detectJoomlaRoot();
+ $report = [];
+
+ foreach (self::PALETTES as $pair) {
+ $starterPath = $tplDir . '/' . $pair['starter'];
+ $userPath = $root . '/' . sprintf($pair['user'], self::TPL);
+
+ if (!is_file($starterPath) || !is_file($userPath)) {
+ continue;
+ }
+
+ $starterVars = self::extractVarsWithContext($starterPath);
+ $userVars = self::extractVarNames($userPath);
+
+ $missing = [];
+ foreach ($starterVars as $name => $declaration) {
+ if (!isset($userVars[$name])) {
+ $missing[] = $name;
+ }
+ }
+
+ if (!empty($missing)) {
+ $report[$userPath] = $missing;
+ }
+ }
+
+ return $report;
+ }
+}
+
+// CLI entry point
+if (PHP_SAPI === 'cli' && realpath($argv[0] ?? '') === realpath(__FILE__)) {
+ $dryRun = in_array('--dry-run', $argv, true);
+
+ echo "MokoOnyx CSS Variable Sync\n";
+ echo str_repeat('─', 40) . "\n\n";
+
+ if ($dryRun) {
+ echo "DRY RUN — no files will be modified\n\n";
+ $report = MokoCssVarSync::dryRun();
+ if (empty($report)) {
+ echo "All custom palettes are up to date.\n";
+ } else {
+ foreach ($report as $file => $vars) {
+ echo "MISSING in {$file}:\n";
+ foreach ($vars as $var) {
+ echo " - {$var}\n";
+ }
+ echo "\n";
+ }
+ }
+ } else {
+ MokoCssVarSync::run();
+ }
+
+ echo "\nDone.\n";
+}
diff --git a/src/templateDetails.xml b/src/templateDetails.xml
new file mode 100644
index 0000000..30bb26d
--- /dev/null
+++ b/src/templateDetails.xml
@@ -0,0 +1,380 @@
+
+
+
+
+
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/raw/branch/main/updates.xml
+
+
+ https://raw.githubusercontent.com/mokoconsulting-tech/MokoOnyx/main/updates.xml
+
+
+ MokoOnyx
+ 01.00.00
+ script.php
+ 2026-04-15
+ Jonathan Miller || Moko Consulting
+ hello@mokoconsulting.tech
+ (C)GNU General Public License Version 3 - 2026 Moko Consulting
+
MokoOnyx Template Description MokoOnyx continues Joomla's tradition of space-themed default templates— building on the legacy of Solarflare (Joomla 1.0), Milkyway (Joomla 1.5), and Protostar (Joomla 3.0).
This template is a customized fork of the Cassiopeia template introduced in Joomla 4, preserving its modern, accessible, and mobile-first foundation while introducing new stylistic enhancements and structural refinements specifically tailored for use by Moko Consulting.
Custom Colour Themes Starter palette files are included with the template. To create a custom colour scheme, copy templates/mokoonyx/templates/light.custom.css to media/templates/site/mokoonyx/css/theme/light.custom.css, or templates/mokoonyx/templates/dark.custom.css to media/templates/site/mokoonyx/css/theme/dark.custom.css. Customise the CSS variables to match your brand, then activate your palette in System → Site Templates → MokoOnyx → Theme tab by selecting "Custom" for the Light or Dark Mode Palette. A full variable reference is available in the CSS Variables tab in template options.
Custom CSS & JavaScript For site-specific styles and scripts that should survive template updates, create the following files:
media/templates/site/mokoonyx/css/user.css — loaded on every page for custom CSS overrides. media/templates/site/mokoonyx/js/user.js — loaded on every page for custom JavaScript. These files are gitignored and will not be overwritten by template updates.
Code Attribution This template is based on the original Cassiopeia template developed by the Joomla! Project and released under the GNU General Public License.
Modifications and enhancements have been made by Moko Consulting in accordance with open-source licensing standards.
It includes integration with Bootstrap TOC , an open-source table of contents generator by A. Feld, licensed under the MIT License.
All third-party libraries and assets remain the property of their respective authors and are credited within their source files where applicable.
]]>
+ 1
+
+ component.php
+ error.php
+ index.php
+ joomla.asset.json
+ offline.php
+ script.php
+ sync_custom_vars.php
+ templateDetails.xml
+ helper
+ html
+ language
+ templates
+
+
+ media/templates/site/mokoonyx/css/editor.css
+
+
+ js
+ css
+ images
+ fonts
+ vendor
+
+
+ topbar
+ below-topbar
+ below-logo
+ brand-aside
+ menu
+ search
+ banner
+ top-a
+ top-b
+ main-top
+ main-bottom
+ breadcrumbs
+ sidebar-left
+ sidebar-right
+ bottom-a
+ bottom-b
+ footer-menu
+ footer
+ debug
+ offline-header
+ offline
+ offline-footer
+ drawer-left
+ drawer-right
+
+
+ language/en-GB/tpl_mokoonyx.ini
+ language/en-GB/tpl_mokoonyx.sys.ini
+ language/en-US/tpl_mokoonyx.ini
+ language/en-US/tpl_mokoonyx.sys.ini
+
+
+
+
+
+
+
+
+ JNO
+ JYES
+
+
+ TPL_MOKOONYX_STATIC
+ TPL_MOKOONYX_FLUID
+
+
+
+
+
+
+
+
+
+
+
+
+ JNO
+ JYES
+
+
+
+ JNO
+ JYES
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ JNO
+ JYES
+
+
+ Switch (Light↔Dark)
+ Radios (Light/Dark/System)
+ No visible control
+
+
+ System
+ Light
+ Dark
+
+
+ JNO
+ JYES
+
+
+ JNO
+ JYES
+
+
+ JNO
+ JYES
+
+
+ JNO
+ JYES
+
+
+
+
+
+ TPL_MOKOONYX_COLOR_NAME_STANDARD
+ TPL_MOKOONYX_COLOR_NAME_CUSTOM
+
+
+ TPL_MOKOONYX_COLOR_NAME_STANDARD
+ TPL_MOKOONYX_COLOR_NAME_CUSTOM
+
+
+
+
+
+ JNONE
+
+ Roboto (local)
+ Noto Sans (local)
+ Fira Sans (local)
+
+
+
+
+
+
+
+ JNO
+ JYES
+
+
+
+
+
+
+
+
+
+ JNO
+ JYES
+
+
+ JNO
+ JYES
+
+
+
+
+
+ JNO
+ JYES
+
+
+ JNO
+ JYES
+
+
+ JNO
+ JYES
+
+
+ JNO
+ JYES
+
+
+ JNO
+ JYES
+
+
+ JNO
+ JYES
+
+
+ JNO
+ JYES
+
+
+
+ Bottom-right
+ Bottom-left
+ Top-right
+ Top-left
+
+
+
+
+
+ JNO
+ JYES
+
+
+
+ Bottom-right
+ Bottom-left
+ Top-right
+ Top-left
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/templates/brand-showcase.html b/src/templates/brand-showcase.html
new file mode 100644
index 0000000..520ae5c
--- /dev/null
+++ b/src/templates/brand-showcase.html
@@ -0,0 +1,273 @@
+
+
+
+
+
+
+MokoOnyx — Brand + Bootstrap Showcase
+
+
+
+
+
+
+
+ Toggle Light / Dark
+
+
+
+
+
+
+
Brand + Bootstrap Showcase
+
Bootstrap 5 powers the responsive, mobile-first foundation of MOKO-CASSIOPEIA, delivering a scalable grid system, standardized components, and utility classes. This implementation integrates Moko Consulting brand variables to ensure consistency, accessibility, and performance across all interfaces.
+
+
Full variable system, gradients, and Bootstrap components
+
+
Hover gradients to sample exact pixel color
+
+
+
Color System
+
+
+
+
+
+
+
+
--accent-color-primary
+
+
+
+
+
+
--accent-color-secondary
+
+
+
+
+
+
+
+
+
+
+
+
RGB Gradient
+
+
+
Black to White Gradient
+
+
+
+
+Brand Nav
+Home
+About
+Contact
+
+
+
+
+
+
Typography
+
Heading 1
+
Heading 2
+
Heading 3
+
Lead paragraph
+
Body text with link and inline code
+
+
+
Buttons
+
+Primary
+Secondary
+Success
+Danger
+Warning
+Info
+Outline
+
+
+
+
Badges
+
+Primary
+Success
+Danger
+
+
+
+
Alerts
+
Primary alert
+
Success alert
+
Warning alert
+
Danger alert
+
+
+
Table
+
+
+# Name Status
+
+
+1 Item Active
+2 Item Inactive
+
+
+
+
+
Forms
+
+
+
+
Cards
+
+
Card Title
+
Example content
+
Action
+
+
+
+
Accordion
+
+
+
+
Tabs
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/templates/dark.custom.css b/src/templates/dark.custom.css
new file mode 100644
index 0000000..e07ad66
--- /dev/null
+++ b/src/templates/dark.custom.css
@@ -0,0 +1,1210 @@
+@charset "UTF-8";
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+
+/* -----------------------------------------------
+ * DARK THEME (CUSTOM)
+ * --------------------------------------------- */
+
+:root[data-bs-theme='dark']{
+color-scheme: dark;
+
+
+/* ===== BRAND & THEME COLORS ===== */
+--color-primary: #112855;
+--accent-color-primary: #3f8ff0;
+--accent-color-secondary: #6fb3ff;
+
+
+/* ===== TYPOGRAPHY & BODY ===== */
+--font-sans-serif: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+--font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+--body-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+--body-font-size: 1rem;
+--body-font-weight: 400;
+--body-line-height: 1.5;
+--body-color: #e6ebf1;
+--body-color-rgb: 230, 235, 241;
+--body-bg: #0e1318;
+--body-bg-rgb: 14, 19, 24;
+--heading-color: #f1f5f9;
+--emphasis-color: #fff;
+--emphasis-color-rgb: 255, 255, 255;
+--secondary-color: #e6ebf1bf;
+--secondary-color-rgb: 230, 235, 241;
+--tertiary-color: #e6ebf180;
+--tertiary-color-rgb: 230, 235, 241;
+--muted-color: #6d757e;
+--code-color: black;
+--code-color-ink: var(--code-color, #e93f8e);
+--code-bg-color: lightgreen;
+--highlight-color: #111;
+--highlight-bg: #ffe28a1a;
+
+
+/* ===== STANDARD COLORS ===== */
+--blue: #91a4ff;
+--indigo: #b19cff;
+--purple: #c0a5ff;
+--pink: #ff8fc0;
+--red: #ff7a73;
+--orange: #ff9c4d;
+--yellow: #ffd166;
+--green: #78d694;
+--teal: #76e3ff;
+--cyan: #6fb7ff;
+--black: #000;
+--white: #fff;
+
+
+/* ===== GRAY SCALE ===== */
+--gray-100: #161a20;
+--gray-200: #1b2027;
+--gray-300: #222831;
+--gray-400: #2b323b;
+--gray-500: #36404a;
+--gray-600: #48525d;
+--gray-700: #5b6672;
+--gray-800: #cfd6de;
+--gray-900: #e6ebf1;
+--white-rgb: 255, 255, 255;
+--black-rgb: 0, 0, 0;
+
+
+/* ===== OPACITY UTILITIES ===== */
+--opacity-0: 0;
+--opacity-5: 0.05;
+--opacity-10: 0.1;
+--opacity-15: 0.15;
+--opacity-20: 0.2;
+--opacity-25: 0.25;
+--opacity-30: 0.3;
+--opacity-50: 0.5;
+--opacity-75: 0.75;
+--opacity-100: 1;
+
+
+/* ===== LAYOUT & SPACING ===== */
+--padding-x: 0.15rem;
+--padding-y: 0.15rem;
+--bg-opacity: 1;
+--nav-toggle-size: 3rem;
+--gradient: linear-gradient(180deg, #ffffff26, #fff0);
+--secondary-bg: #151b22;
+--secondary-bg-rgb: 21, 27, 34;
+--tertiary-bg: #10151b;
+--tertiary-bg-rgb: 16, 21, 27;
+--hr-color: var(--border-color, #dfe3e7);
+--border-color-soft: var(--border-color, #dfe3e7);
+--kbd-bg: var(--secondary-bg, #eaedf0);
+--kbd-ink: var(--body-bg, #fff);
+--toc-bg: var(--secondary-bg, #eaedf0);
+--toc-ink: var(--color-primary, #112855);
+--selection-bg: var(--highlight-bg, #fbeea8);
+--selection-ink: var(--body-color, #22262a);
+--border: 5px;
+
+
+/* ===== BREAKPOINTS ===== */
+--bp-xs: 0;
+--bp-sm: 576px;
+--bp-md: 768px;
+--bp-lg: 992px;
+--bp-xl: 1200px;
+
+
+/* ===== BORDERS ===== */
+--border-width: 1px;
+--border-style: solid;
+--border-color: #2b323b;
+--border-color-translucent: #ffffff26;
+--border-radius: .25rem;
+--border-radius-sm: .2rem;
+--border-radius-lg: .3rem;
+--border-radius-xl: .3rem;
+--border-radius-xxl: 2rem;
+--border-radius-2xl: var(--border-radius-xxl);
+--border-radius-pill: 50rem;
+
+
+/* ===== SHADOWS ===== */
+--box-shadow: 0 .5rem 1rem #00000066;
+--box-shadow-sm: 0 .125rem .25rem #00000040;
+--box-shadow-lg: 0 1rem 3rem #00000080;
+--box-shadow-inset: inset 0 1px 2px #00000040;
+
+
+/* ===== COMMON SHADOW COLORS ===== */
+--shadow-color-light: rgba(var(--black-rgb), var(--opacity-30));
+--shadow-color-medium: rgba(var(--black-rgb), var(--opacity-50));
+--shadow-color-dark: rgba(var(--black-rgb), var(--opacity-75));
+--border-color-translucent: rgba(var(--white-rgb), var(--opacity-10));
+--highlight-translucent: rgba(var(--white-rgb), var(--opacity-5));
+
+
+/* ===== NAVIGATION ===== */
+--mainmenu-nav-link-color: #fff;
+--nav-text-color: gray;
+--nav-bg-color: var(--color-primary);
+
+
+/* ===== NAVBAR ===== */
+--navbar-padding-x: 1rem;
+--navbar-padding-y: 0.5rem;
+--navbar-color: var(--nav-text-color);
+--navbar-active-color: var(--mainmenu-nav-link-color);
+--navbar-disabled-color: #6c757d;
+--navbar-brand-padding-y: 0.3125rem;
+--navbar-brand-margin-end: 1rem;
+--navbar-brand-font-size: 1.25rem;
+--navbar-brand-color: var(--nav-text-color);
+--navbar-brand-active-color: var(--mainmenu-nav-link-color);
+--navbar-nav-link-padding-x: 0.5rem;
+--navbar-toggler-padding-y: 0.25rem;
+--navbar-toggler-padding-x: 0.75rem;
+--navbar-toggler-font-size: 1.25rem;
+--navbar-toggler-border-color: rgba(255, 255, 255, 0.1);
+--navbar-toggler-border-radius: 0.25rem;
+--navbar-toggler-focus-width: 0.25rem;
+--navbar-toggler-transition: box-shadow 0.15s ease-in-out;
+--nav-link-padding-x: 1rem;
+--nav-link-padding-y: 0.5rem;
+--nav-link-font-weight: 400;
+--nav-link-color: var(--nav-text-color);
+--nav-link-active-color: var(--mainmenu-nav-link-color);
+--nav-link-disabled-color: #6c757d;
+
+
+/* ===== LINKS ===== */
+--color-link: white;
+--color-hover: gray;
+--color-active: var(--mainmenu-nav-link-color);
+--link-color: #8ab4f8;
+--link-color-rgb: 138, 180, 248;
+--link-decoration: underline;
+--link-hover-color: #c3d6ff;
+--link-hover-color-rgb: 195, 214, 255;
+--link-active-color: var(--link-color);
+
+
+/* ===== LINK UTILITY COLORS ===== */
+--link-primary-color: hsl(240, 98%, 50%);
+--link-primary-hover-color: hsl(240, 98%, 45%);
+--link-secondary-color: hsl(210, 15%, 70%);
+--link-secondary-hover-color: hsl(210, 15%, 65%);
+--link-success-color: hsl(120, 40%, 60%);
+--link-success-hover-color: hsl(120, 40%, 55%);
+--link-info-color: hsl(207, 60%, 65%);
+--link-info-hover-color: hsl(207, 60%, 60%);
+--link-warning-color: hsl(38, 100%, 65%);
+--link-warning-hover-color: hsl(38, 100%, 60%);
+--link-danger-color: hsl(3, 85%, 65%);
+--link-danger-hover-color: hsl(3, 85%, 60%);
+--link-light-color: hsl(210, 20%, 90%);
+--link-light-hover-color: hsl(210, 20%, 85%);
+--link-dark-color: hsl(210, 10%, 35%);
+--link-dark-hover-color: hsl(210, 10%, 30%);
+
+
+/* ===== HEADER BACKGROUND ===== */
+--header-background-image: url('../../../../../../media/templates/site/mokoonyx/images/bg.svg');
+--header-background-attachment: fixed;
+--header-background-repeat: repeat;
+--header-background-size: auto;
+
+
+/* ===== CONTAINER BACKGROUNDS ===== */
+/* Below Topbar Container */
+--container-below-topbar-bg-image: none;
+--container-below-topbar-bg-color: transparent;
+--container-below-topbar-bg-position: center;
+--container-below-topbar-bg-attachment: fixed;
+--container-below-topbar-bg-repeat: no-repeat;
+--container-below-topbar-bg-size: cover;
+--container-below-topbar-border: none;
+--container-below-topbar-border-radius: 0;
+
+/* Top A Container */
+--container-top-a-bg-image: none;
+--container-top-a-bg-color: transparent;
+--container-top-a-bg-position: center;
+--container-top-a-bg-attachment: fixed;
+--container-top-a-bg-repeat: no-repeat;
+--container-top-a-bg-size: cover;
+--container-top-a-border: none;
+--container-top-a-border-radius: 0;
+
+/* Top B Container */
+--container-top-b-bg-image: none;
+--container-top-b-bg-color: transparent;
+--container-top-b-bg-position: center;
+--container-top-b-bg-attachment: fixed;
+--container-top-b-bg-repeat: no-repeat;
+--container-top-b-bg-size: cover;
+--container-top-b-border: none;
+--container-top-b-border-radius: 0;
+
+/* TOC Container */
+--container-toc-bg: var(--secondary-bg);
+--container-toc-color: #dbe3ff;
+
+/* Sidebar Container */
+--container-sidebar-bg-image: none;
+--container-sidebar-bg-color: transparent;
+--container-sidebar-bg-position: center;
+--container-sidebar-bg-attachment: scroll;
+--container-sidebar-bg-repeat: repeat;
+--container-sidebar-bg-size: auto;
+--container-sidebar-border: none;
+--container-sidebar-border-radius: 0;
+
+/* Bottom A Container */
+--container-bottom-a-bg-image: none;
+--container-bottom-a-bg-color: transparent;
+--container-bottom-a-bg-position: center;
+--container-bottom-a-bg-attachment: fixed;
+--container-bottom-a-bg-repeat: no-repeat;
+--container-bottom-a-bg-size: cover;
+--container-bottom-a-border: none;
+--container-bottom-a-border-radius: 5px;
+
+/* Bottom B Container */
+--container-bottom-b-bg-image: none;
+--container-bottom-b-bg-color: transparent;
+--container-bottom-b-bg-position: center;
+--container-bottom-b-bg-attachment: fixed;
+--container-bottom-b-bg-repeat: no-repeat;
+--container-bottom-b-bg-size: cover;
+--container-bottom-b-border: none;
+--container-bottom-b-border-radius: 0;
+
+
+/* ===== FOCUS & FORMS ===== */
+--focus-ring-width: .25rem;
+--focus-ring-opacity: .6;
+--focus-ring-color: #5472ff66;
+--input-color: #e6ebf1;
+--input-bg: #1a2332;
+--input-border-color: #3a4250;
+--input-focus-border-color: #5472ff;
+--input-focus-box-shadow: 0 0 0 0.25rem rgba(84, 114, 255, 0.25);
+--input-placeholder-color: #8894aa;
+--input-disabled-bg: #0f1318;
+--input-disabled-border-color: #2b323b;
+--input-file-button-active-bg: #2b3441;
+--form-range-thumb-active-bg: #4a5766;
+--form-valid-color: #78d694;
+--form-valid-border-color: #78d694;
+--form-invalid-color: #ff8e86;
+--form-invalid-border-color: #ff8e86;
+
+
+/* ===== BUTTONS ===== */
+--btn-border-radius: var(--border-radius);
+--btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 1px 1px rgba(0, 0, 0, 0.3);
+
+
+/* ===== ACCORDION ===== */
+--accordion-color: var(--body-color);
+--accordion-bg: var(--body-bg);
+--accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;
+--accordion-border-color: var(--border-color);
+--accordion-border-width: 1px;
+--accordion-border-radius: 0.25rem;
+--accordion-inner-border-radius: calc(0.25rem - 1px);
+--accordion-btn-padding-x: 1.25rem;
+--accordion-btn-padding-y: 1rem;
+--accordion-btn-color: var(--body-color);
+--accordion-btn-bg: var(--accordion-bg);
+--accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23e6ebf1'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+--accordion-btn-icon-width: 1.25rem;
+--accordion-btn-icon-transform: rotate(-180deg);
+--accordion-btn-icon-transition: transform 0.2s ease-in-out;
+--accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%238ab4f8'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+--accordion-btn-focus-border-color: var(--input-focus-border-color);
+--accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(84, 114, 255, 0.25);
+--accordion-body-padding-x: 1.25rem;
+--accordion-body-padding-y: 1rem;
+--accordion-active-color: var(--link-color);
+--accordion-active-bg: var(--secondary-bg);
+
+
+/* ===== ALERT ===== */
+--alert-bg: transparent;
+--alert-padding-x: 1rem;
+--alert-padding-y: 1rem;
+--alert-margin-bottom: 1rem;
+--alert-color: #000;
+--alert-border-color: transparent;
+--alert-border: 1px solid var(--alert-border-color);
+--alert-border-radius: 0.25rem;
+
+
+/* ===== ALERT LINK COLORS ===== */
+--alert-primary-link-color: #b3c1ff;
+--alert-secondary-link-color: #9fa6ad;
+--alert-success-link-color: #a0e5b3;
+--alert-info-link-color: #8eccf2;
+--alert-warning-link-color: #ffe4a0;
+--alert-danger-link-color: #ffa8a3;
+--alert-light-link-color: #f0f4f8;
+--alert-dark-link-color: #9fa6ad;
+
+
+/* ===== BACKDROP ===== */
+--backdrop-zindex: 1040;
+--backdrop-bg: hsl(0, 0%, 0%);
+--backdrop-opacity: 0.5;
+
+
+/* ===== BADGE ===== */
+--badge-padding-x: 0.65em;
+--badge-padding-y: 0.35em;
+--badge-font-size: 0.75em;
+--badge-font-weight: 700;
+--badge-color: var(--body-color);
+--badge-border-radius: 0.25rem;
+
+
+/* ===== BREADCRUMB ===== */
+--breadcrumb-padding-x: 0;
+--breadcrumb-padding-y: 0;
+--breadcrumb-margin-bottom: 1rem;
+--breadcrumb-bg: ;
+--breadcrumb-border-radius: ;
+--breadcrumb-divider-color: var(--gray-600);
+--breadcrumb-item-padding-x: 0.5rem;
+--breadcrumb-item-active-color: var(--link-color);
+
+
+/* ===== CARDS ===== */
+--card-spacer-y: 1rem;
+--card-spacer-x: 1rem;
+--card-title-spacer-y: 0.5rem;
+--card-border-width: 1px;
+--card-border-color: var(--border-color);
+--card-border-radius: var(--border-radius);
+--card-box-shadow: none;
+--card-inner-border-radius: calc(var(--border-radius) - 1px);
+--card-cap-padding-y: 0.5rem;
+--card-cap-padding-x: 1rem;
+--card-cap-bg: rgba(255, 255, 255, 0.03);
+--card-cap-color: var(--body-color);
+--card-height: auto;
+--card-color: var(--body-color);
+--card-bg: var(--secondary-bg);
+--card-img-overlay-padding: 1rem;
+--card-group-margin: 0.75rem;
+
+
+/* ===== DROPDOWN ===== */
+--dropdown-zindex: 1000;
+--dropdown-min-width: 10rem;
+--dropdown-padding-x: 0;
+--dropdown-padding-y: 0.5rem;
+--dropdown-spacer: 0.125rem;
+--dropdown-font-size: 1rem;
+--dropdown-color: var(--body-color);
+--dropdown-bg: var(--secondary-bg);
+--dropdown-border-color: var(--border-color-translucent);
+--dropdown-border-radius: 0.25rem;
+--dropdown-border-width: 1px;
+--dropdown-inner-border-radius: calc(0.25rem - 1px);
+--dropdown-divider-bg: var(--border-color-translucent);
+--dropdown-divider-margin-y: 0.5rem;
+--dropdown-box-shadow: 0 0.5rem 1rem var(--shadow-color-medium);
+--dropdown-link-color: var(--body-color);
+--dropdown-link-active-color: var(--body-color);
+--dropdown-link-active-bg: hsl(240, 98%, 17%);
+--dropdown-link-disabled-color: var(--gray-600);
+--dropdown-item-padding-x: 1rem;
+--dropdown-item-padding-y: 0.25rem;
+--dropdown-header-color: var(--gray-600);
+--dropdown-header-padding-x: 1rem;
+--dropdown-header-padding-y: 0.5rem;
+
+
+/* ===== LIST GROUP ===== */
+--list-group-color: var(--body-color);
+--list-group-bg: var(--secondary-bg);
+--list-group-border-color: rgba(var(--white-rgb), 0.125);
+--list-group-border-width: 1px;
+--list-group-border-radius: 0.25rem;
+--list-group-item-padding-x: 1rem;
+--list-group-item-padding-y: 0.5rem;
+--list-group-action-color: var(--gray-800);
+--list-group-action-active-color: var(--body-color);
+--list-group-action-active-bg: var(--tertiary-bg);
+--list-group-disabled-color: var(--gray-600);
+--list-group-disabled-bg: var(--secondary-bg);
+--list-group-active-color: var(--body-color);
+--list-group-active-bg: hsl(240, 98%, 17%);
+--list-group-active-border-color: hsl(240, 98%, 17%);
+
+
+/* ===== LIST GROUP ITEM COLORS ===== */
+--list-group-item-primary-color: #8ca3ff;
+--list-group-item-primary-bg: #1a2550;
+--list-group-item-primary-active-bg: #223066;
+--list-group-item-secondary-color: #9fa6ad;
+--list-group-item-secondary-bg: #2b323b;
+--list-group-item-secondary-active-bg: #363d47;
+--list-group-item-success-color: #a0e5b3;
+--list-group-item-success-bg: #1e3d2d;
+--list-group-item-success-active-bg: #275538;
+--list-group-item-info-color: #8eccf2;
+--list-group-item-info-bg: #1a3448;
+--list-group-item-info-active-bg: #234459;
+--list-group-item-warning-color: #ffe4a0;
+--list-group-item-warning-bg: #4a3410;
+--list-group-item-warning-active-bg: #5c4216;
+--list-group-item-danger-color: #ffa8a3;
+--list-group-item-danger-bg: #4a1e1c;
+--list-group-item-danger-active-bg: #5c2823;
+--list-group-item-light-color: #e9ecef;
+--list-group-item-light-bg: #1e2430;
+--list-group-item-light-active-bg: #282f3d;
+--list-group-item-dark-color: #48525d;
+--list-group-item-dark-bg: #0e1318;
+--list-group-item-dark-active-bg: #161b22;
+
+
+/* ===== MODAL ===== */
+--modal-zindex: 1050;
+--modal-width: 500px;
+--modal-padding: 1rem;
+--modal-margin: 0.5rem;
+--modal-color: ;
+--modal-bg: var(--secondary-bg);
+--modal-border-color: var(--border-color-translucent);
+--modal-border-width: 1px;
+--modal-border-radius: 0.3rem;
+--modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.3);
+--modal-inner-border-radius: calc(0.3rem - 1px);
+--modal-header-padding-x: 1rem;
+--modal-header-padding-y: 1rem;
+--modal-header-padding: 1rem 1rem;
+--modal-header-border-color: var(--border-color);
+--modal-header-border-width: 1px;
+--modal-title-line-height: 1.5;
+--modal-footer-gap: 0.5rem;
+--modal-footer-bg: ;
+--modal-footer-border-color: var(--border-color);
+--modal-footer-border-width: 1px;
+
+
+/* ===== NAV TABS ===== */
+--nav-tabs-border-width: 1px;
+--nav-tabs-border-color: var(--border-color);
+--nav-tabs-border-radius: 0.25rem;
+--nav-tabs-link-active-color: var(--body-color);
+--nav-tabs-link-active-bg: var(--secondary-bg);
+--nav-tabs-link-active-border-color: var(--border-color) var(--border-color) var(--secondary-bg);
+
+
+/* ===== NAV PILLS ===== */
+--nav-pills-border-radius: 0.25rem;
+--nav-pills-link-active-color: var(--body-color);
+--nav-pills-link-active-bg: hsl(240, 98%, 17%);
+
+
+/* ===== OFFCANVAS ===== */
+--offcanvas-zindex: 1045;
+--offcanvas-width: 400px;
+--offcanvas-height: 30vh;
+--offcanvas-padding-x: 1rem;
+--offcanvas-padding-y: 1rem;
+--offcanvas-color: var(--body-color);
+--offcanvas-bg: var(--body-bg);
+--offcanvas-border-width: 1px;
+--offcanvas-border-color: var(--border-color-translucent);
+--offcanvas-box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.3);
+
+
+/* ===== PAGINATION ===== */
+--pagination-padding-x: 0.75rem;
+--pagination-padding-y: 0.375rem;
+--pagination-font-size: 1rem;
+--pagination-color: var(--link-color);
+--pagination-bg: var(--secondary-bg);
+--pagination-border-width: 1px;
+--pagination-border-color: var(--border-color);
+--pagination-border-radius: 0.25rem;
+--pagination-focus-color: var(--link-active-color);
+--pagination-focus-bg: var(--tertiary-bg);
+--pagination-focus-box-shadow: 0 0 0 0.25rem rgba(84, 114, 255, 0.25);
+--pagination-active-color: var(--body-color);
+--pagination-active-bg: hsl(240, 98%, 17%);
+--pagination-active-border-color: hsl(240, 98%, 17%);
+--pagination-disabled-color: var(--gray-600);
+--pagination-disabled-bg: var(--secondary-bg);
+--pagination-disabled-border-color: var(--border-color);
+
+
+/* ===== POPOVER ===== */
+--popover-zindex: 1060;
+--popover-max-width: 276px;
+--popover-font-size: 0.875rem;
+--popover-bg: var(--secondary-bg);
+--popover-border-width: 1px;
+--popover-border-color: var(--border-color-translucent);
+--popover-border-radius: 0.3rem;
+--popover-inner-border-radius: calc(0.3rem - 1px);
+--popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.4);
+--popover-header-padding-x: 1rem;
+--popover-header-padding-y: 0.5rem;
+--popover-header-font-size: 1rem;
+--popover-header-color: ;
+--popover-header-bg: var(--tertiary-bg);
+--popover-body-padding-x: 1rem;
+--popover-body-padding-y: 1rem;
+--popover-body-color: var(--body-color);
+--popover-arrow-width: 1rem;
+--popover-arrow-height: 0.5rem;
+--popover-arrow-border: var(--popover-border-color);
+
+
+/* ===== PROGRESS ===== */
+--progress-height: 1rem;
+--progress-font-size: 0.75rem;
+--progress-bg: var(--secondary-bg);
+--progress-border-radius: 0.25rem;
+--progress-box-shadow: inset 0 1px 2px rgba(var(--black-rgb), 0.3);
+--progress-bar-color: var(--body-color);
+--progress-bar-bg: hsl(240, 98%, 40%);
+--progress-bar-transition: width 0.6s ease;
+
+
+/* ===== SPINNER ===== */
+--spinner-width: 2rem;
+--spinner-height: 2rem;
+--spinner-vertical-align: -0.125em;
+--spinner-border-width: 0.25em;
+--spinner-animation-speed: 0.75s;
+
+
+/* ===== TABLE ===== */
+--table-color: var(--body-color);
+--table-bg: transparent;
+--table-border-color: var(--border-color);
+--table-accent-bg: transparent;
+--table-striped-color: var(--body-color);
+--table-striped-bg: rgba(var(--white-rgb), var(--opacity-5));
+--table-active-color: var(--body-color);
+--table-active-bg: rgba(var(--white-rgb), 0.1);
+
+
+/* ===== TOAST ===== */
+--toast-zindex: 1090;
+--toast-padding-x: 0.75rem;
+--toast-padding-y: 0.5rem;
+--toast-spacing: 1em;
+--toast-max-width: 350px;
+--toast-font-size: 0.875rem;
+--toast-color: ;
+--toast-bg: rgba(21, 27, 34, 0.9);
+--toast-border-width: 1px;
+--toast-border-color: var(--border-color-translucent);
+--toast-border-radius: 0.25rem;
+--toast-box-shadow: 0 0.5rem 1rem var(--shadow-color-medium);
+--toast-header-color: var(--gray-600);
+--toast-header-bg: rgba(21, 27, 34, 0.85);
+--toast-header-border-color: rgba(var(--white-rgb), var(--opacity-10));
+
+
+/* ===== TOOLTIP ===== */
+--tooltip-zindex: 1070;
+--tooltip-max-width: 200px;
+--tooltip-padding-x: 0.5rem;
+--tooltip-padding-y: 0.25rem;
+--tooltip-margin: ;
+--tooltip-font-size: 0.875rem;
+--tooltip-color: var(--body-color);
+--tooltip-bg: hsl(0, 0%, 0%);
+--tooltip-border-radius: 0.25rem;
+--tooltip-opacity: 0.9;
+--tooltip-arrow-width: 0.8rem;
+--tooltip-arrow-height: 0.4rem;
+
+
+/* ===== BOOTSTRAP PALETTE ===== */
+--primary: #010156;
+--secondary: #48525d;
+--success: #4aa664;
+--info: #4f7aa0;
+--warning: #c77a00;
+--danger: #c23a31;
+--light: #1b2027;
+--dark: #0f1318;
+--primary-rgb: 1,1,86;
+--secondary-rgb: 72,82,93;
+--success-rgb: 74,166,100;
+--info-rgb: 79,122,160;
+--warning-rgb: 199,122,0;
+--danger-rgb: 194,58,49;
+--light-rgb: 27,32,39;
+--dark-rgb: 15,19,24;
+--primary-text-emphasis: #c7ccff;
+--secondary-text-emphasis: #cfd6de;
+--success-text-emphasis: #bde8c9;
+--info-text-emphasis: #bcd6ee;
+--warning-text-emphasis: #ffd9a6;
+--danger-text-emphasis: #ffb7b2;
+--light-text-emphasis: #d2d8df;
+--dark-text-emphasis: #d2d8df;
+--primary-bg-subtle: #0b1030;
+--secondary-bg-subtle: #1e2430;
+--success-bg-subtle: #0f2a1b;
+--info-bg-subtle: #0d2232;
+--warning-bg-subtle: #2a1e06;
+--danger-bg-subtle: #2d1110;
+--light-bg-subtle: #12161d;
+--dark-bg-subtle: #1e2430;
+--primary-border-subtle: #2b3a7a;
+--secondary-border-subtle: #2b323b;
+--success-border-subtle: #2b5b40;
+--info-border-subtle: #254861;
+--warning-border-subtle: #5a3c0e;
+--danger-border-subtle: #5c2723;
+--light-border-subtle: #222831;
+--dark-border-subtle: #2b323b;
+
+
+/* ===== HERO / BANNER OVERLAY ===== */
+--hero-height: 70vh;
+--hero-color: var(--body-color);
+--hero-bg-repeat: no-repeat;
+--hero-bg-attachment: fixed;
+--hero-bg-position: top center;
+--hero-bg-size: cover;
+--hero-border-bottom: solid var(--accent-color-secondary);
+--hero-overlay-bg: hsla(0, 0%, 0%, 0.3);
+--hero-overlay-bg-position: center;
+--hero-overlay-bg-size: cover;
+--hero-overlay-padding: 1em;
+--hero-overlay-text-align: center;
+--hero-overlay-text-color: var(--body-color);
+
+
+/* ===== HERO VARIANTS ===== */
+/* Primary — deep navy, dark overlay */
+--hero-primary-bg-color: #0d1e3a;
+--hero-primary-overlay: linear-gradient(rgba(13, 30, 58, .65), rgba(13, 30, 58, .65));
+--hero-primary-color: #f1f5f9;
+
+/* Secondary — darker navy, heavier overlay */
+--hero-secondary-bg-color: #080f1e;
+--hero-secondary-overlay: linear-gradient(rgba(8, 15, 30, .80), rgba(8, 15, 30, .80));
+--hero-secondary-color: #f1f5f9;
+
+
+/* ===== HERO CARD (inner .hero element) ===== */
+/* Default card — uses primary variant values */
+--hero-card-bg: var(--hero-primary-bg-color);
+--hero-card-color: white;
+--hero-card-overlay: var(--hero-primary-overlay);
+--hero-card-border-radius: .5rem;
+--hero-card-padding-x: 2rem;
+--hero-card-padding-y: 3rem;
+--hero-card-max-width: 800px;
+
+/* Alternative card — uses secondary variant values */
+--hero-alt-card-bg: var(--hero-secondary-bg-color);
+--hero-alt-card-color: var(--hero-secondary-color);
+--hero-alt-card-overlay: var(--hero-secondary-overlay);
+--hero-alt-card-border-radius: .5rem;
+--hero-alt-card-padding-x: 2rem;
+--hero-alt-card-padding-y: 3rem;
+--hero-alt-card-max-width: 600px;
+
+
+/* ===== BLOCK COLORS (top-a / top-b / bottom-a / bottom-b) ===== */
+--block-color-1: var(--secondary-bg);
+--block-text-1: var(--body-color);
+
+--block-color-2: var(--accent-color-primary);
+--block-text-2: #fff;
+
+--block-color-3: rgba(238, 194, 52, .15);
+--block-text-3: var(--body-color);
+
+--block-color-4: rgba(74, 166, 100, .15);
+--block-text-4: var(--body-color);
+
+
+/* ===== BLOCK COLOR OVERRIDES ===== */
+--block-highlight-bg: var(--accent-color-primary);
+--block-highlight-text: #fff;
+
+--block-cta-bg: var(--color-primary);
+--block-cta-text: #f1f5f9;
+
+--block-alert-bg: var(--danger, #c23a31);
+--block-alert-text: #fff;
+
+
+/* ===== FOOTER ===== */
+--footer-padding-top: 1rem;
+--footer-padding-bottom: 80px;
+--footer-grid-padding-y: 2.5rem;
+--footer-grid-padding-x: 0.5em;
+
+
+/* ===== THEME FAB ===== */
+--theme-fab-bg: #e6ebf1;
+--theme-fab-color: #0e1318;
+--theme-fab-btn-bg: transparent;
+--theme-fab-border: rgba(0, 0, 0, 0.15);
+
+
+/* ===== OFFLINE PAGE ===== */
+--offline-card-bg: rgba(0, 0, 0, 0.6);
+
+
+/* ===== COMPONENT-SPECIFIC COLORS ===== */
+--mod-finder-link-hover: #5a6470;
+--form-legend-color: #9fa6ad;
+--border-gray: #3a4250;
+--subhead-color: #9fa6ad;
+--box-shadow-gray: #1a2027;
+--btn-active-text-gray: #7a8490;
+--indicator-success-bg: var(--success);
+--item-list-color: #2a2f34;
+--notification-badge-bg: var(--danger);
+--content-bg-gray: #2b323b;
+--taba-btn-green: #5a9c2f;
+--taba-btn-blue: #3d75a8;
+--taba-btn-red: #c43620;
+--taba-btn-gray: #6a7080;
+--taba-msg-bg: #1e2430;
+--toc-link-color: #9fa6ad;
+--toc-link-active-color: #91a4ff;
+--choices-disabled-bg: #2b323b;
+--choices-input-bg: var(--body-bg);
+--choices-border-light: #48525d;
+--choices-arrow-color: #9fa6ad;
+--choices-inner-bg: #1a2027;
+--choices-focused-border: #5472ff;
+--choices-dropdown-bg: var(--body-bg);
+--choices-item-bg: #1a5f75;
+--choices-item-border: #1a748f;
+--choices-item-hover-bg: #1a748f;
+--choices-item-hover-border: #1a8aa8;
+--choices-item-disabled-bg: #48525d;
+--choices-item-disabled-border: #36404a;
+--choices-item-highlighted: #2b323b;
+--choices-input-inner-bg: #1a2027;
+
+
+/* ===== VIRTUEMART (VM) ===== */
+/* VM Surfaces */
+--vm-surface: var(--secondary-bg);
+--vm-surface-2: var(--tertiary-bg);
+--vm-text: var(--body-color);
+--vm-text-strong: #ffffff;
+--vm-text-muted: var(--gray-700);
+--vm-border: var(--border-color);
+--vm-price-color: var(--success);
+
+/* VM Layout and Density */
+--vm-container-max-width: 1200px;
+--vm-section-gap: 2rem;
+--vm-block-radius: var(--border-radius);
+--vm-block-shadow: var(--box-shadow-sm);
+
+/* VM Typography */
+--vm-category-title-size: 2rem;
+--vm-subcategory-title-size: 1.5rem;
+--vm-page-title-size: 1.75rem;
+--vm-products-type-title-size: 1.25rem;
+--vm-product-title-size: 1.125rem;
+--vm-product-title-weight: 500;
+--vm-products-type-title-weight: 600;
+--vm-price-size: 1.5rem;
+--vm-price-detail-size: 1.125rem;
+--vm-price-desc-size: 0.875rem;
+
+/* VM Controls */
+--vm-input-radius: var(--border-radius);
+--vm-input-shadow: var(--box-shadow-sm);
+--vm-qty-width: 80px;
+--vm-cart-dropdown-min-width: 300px;
+
+/* VM Alerts */
+--vm-alert-radius: var(--border-radius);
+--vm-alert-shadow: var(--box-shadow-sm);
+--vm-availability-bg: var(--success-bg-subtle);
+--vm-availability-text: var(--success);
+
+/* VM Buttons */
+--vm-btn-padding-x: 1rem;
+--vm-btn-padding-y: 0.5rem;
+--vm-btn-radius: var(--border-radius);
+--vm-btn-shadow: var(--box-shadow-sm);
+--vm-btn-primary-bg: var(--primary);
+--vm-btn-primary-text: #ffffff;
+--vm-btn-primary-border: var(--primary);
+--vm-btn-secondary-bg: var(--secondary);
+--vm-btn-secondary-text: #ffffff;
+--vm-btn-secondary-border: var(--secondary);
+
+/* VM Image Overlay Controls */
+--vm-image-overlay-gap-x: 0.5rem;
+--vm-image-overlay-gap-y: 0.5rem;
+--vm-image-overlay-raise: 0.25rem;
+--vm-image-overlay-btn-size: 2.5rem;
+--vm-image-overlay-btn-radius: 50%;
+--vm-image-overlay-btn-bg: rgba(0, 0, 0, 0.7);
+--vm-image-overlay-btn-bg-hover: rgba(0, 0, 0, 0.85);
+--vm-image-overlay-btn-border-color: rgba(255, 255, 255, 0.2);
+--vm-image-overlay-btn-border-width: 1px;
+--vm-image-overlay-btn-color: var(--body-color);
+--vm-image-overlay-btn-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
+
+/* VM Vendor Menu */
+--vm-vendor-menu-bg: var(--secondary-bg);
+--vm-vendor-menu-border: var(--border-color);
+--vm-vendor-menu-radius: var(--border-radius);
+--vm-vendor-menu-shadow: var(--box-shadow-sm);
+--vm-vendor-menu-item-gap: 0.25rem;
+--vm-vendor-menu-item-padding-x: 1rem;
+--vm-vendor-menu-item-padding-y: 0.5rem;
+--vm-vendor-menu-pill-radius: 50rem;
+--vm-vendor-menu-link: var(--link-color);
+--vm-vendor-menu-link-hover: var(--link-hover-color);
+--vm-vendor-menu-link-active: var(--primary);
+--vm-vendor-menu-hover-bg: var(--tertiary-bg);
+
+
+/* ===== GABLE ===== */
+--gab-blue: #4d9fff;
+--gab-green: #5cb85c;
+--gab-red: #ff6b6b;
+--gab-orange: #ff9f5a;
+--gab-gray1: #868e96;
+--gab-gray2: #adb5bd;
+--gab-gray3: #ced4da;
+
+}
+
+.btn {
+ --btn-padding-x: 1rem;
+ --btn-padding-y: 0.6rem;
+ --btn-font-family: inherit;
+ --btn-font-size: 1rem;
+ --btn-font-weight: 400;
+ --btn-line-height: 1.5;
+ --btn-color: var(--white);
+ --btn-bg: var(--body-bg);
+ --btn-border-width: 1px;
+ --btn-border-color: transparent;
+ --btn-border-radius: 0.25rem;
+ --btn-active-border-color: transparent;
+ --btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
+ --btn-disabled-opacity: 0.65;
+ --btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb), .5);
+ display: inline-block;
+ padding: var(--btn-padding-y) var(--btn-padding-x);
+ font-family: var(--btn-font-family);
+ font-size: var(--btn-font-size);
+ font-weight: var(--btn-font-weight);
+ line-height: var(--btn-line-height);
+ color: var(--btn-color);
+ text-align: center;
+ text-decoration: none;
+ vertical-align: middle;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ border: var(--btn-border-width) solid var(--btn-border-color);
+ border-radius: var(--btn-border-radius);
+ background-color: var(--btn-bg);
+ -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+ -o-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+}
+
+/* Buttons — inherit brand hues; ensure strong contrast on dark bg */
+.btn-primary {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(240, 98%, 17%);
+ --btn-border-color: hsl(240, 98%, 17%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: #010149;
+ --btn-hover-border-color: #010145;
+ --btn-focus-shadow-rgb: 84, 114, 255;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: #010145;
+ --btn-active-border-color: #010141;
+}
+
+.btn-secondary {
+ --btn-color: var(--nav-text-color);
+ --btn-bg: var(--nav-bg-color);
+ --btn-border-color: #3a4250;
+ --btn-hover-color: #fff;
+ --btn-hover-bg: #1b2a55;
+ --btn-hover-border-color: #162448;
+ --btn-focus-shadow-rgb: 84, 114, 255;
+ --btn-active-color: #fff;
+ --btn-active-bg: #162448;
+ --btn-active-border-color: #12203f;
+}
+
+.btn-success {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(120, 35%, 45%);
+ --btn-border-color: hsl(120, 35%, 45%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(120, 35%, 40%);
+ --btn-hover-border-color: hsl(120, 35%, 38%);
+ --btn-focus-shadow-rgb: 96, 180, 96;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(120, 35%, 38%);
+ --btn-active-border-color: hsl(120, 35%, 36%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(120, 35%, 45%);
+ --btn-disabled-border-color: hsl(120, 35%, 45%);
+}
+
+.btn-info {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(207, 55%, 55%);
+ --btn-border-color: hsl(207, 55%, 55%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(207, 55%, 50%);
+ --btn-hover-border-color: hsl(207, 55%, 48%);
+ --btn-focus-shadow-rgb: 100, 160, 210);
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(207, 55%, 48%);
+ --btn-active-border-color: hsl(207, 55%, 46%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(207, 55%, 55%);
+ --btn-disabled-border-color: hsl(207, 55%, 55%);
+}
+
+.btn-warning {
+ --btn-color: hsl(0, 0%, 0%);
+ --btn-bg: hsl(38, 100%, 50%);
+ --btn-border-color: hsl(38, 100%, 50%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(38, 100%, 45%);
+ --btn-hover-border-color: hsl(38, 100%, 43%);
+ --btn-focus-shadow-rgb: 220, 170, 40;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(38, 100%, 43%);
+ --btn-active-border-color: hsl(38, 100%, 41%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 0%);
+ --btn-disabled-bg: hsl(38, 100%, 50%);
+ --btn-disabled-border-color: hsl(38, 100%, 50%);
+}
+
+.btn-danger {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(3, 82%, 50%);
+ --btn-border-color: hsl(3, 82%, 50%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(3, 82%, 45%);
+ --btn-hover-border-color: hsl(3, 82%, 43%);
+ --btn-focus-shadow-rgb: 220, 80, 80;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(3, 82%, 43%);
+ --btn-active-border-color: hsl(3, 82%, 41%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(3, 82%, 50%);
+ --btn-disabled-border-color: hsl(3, 82%, 50%);
+}
+
+.btn-light {
+ --btn-color: hsl(0, 0%, 0%);
+ --btn-bg: hsl(210, 17%, 85%);
+ --btn-border-color: hsl(210, 17%, 85%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(210, 17%, 80%);
+ --btn-hover-border-color: hsl(210, 17%, 78%);
+ --btn-focus-shadow-rgb: 200, 205, 210;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(210, 17%, 78%);
+ --btn-active-border-color: hsl(210, 17%, 76%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 0%);
+ --btn-disabled-bg: hsl(210, 17%, 85%);
+ --btn-disabled-border-color: hsl(210, 17%, 85%);
+}
+
+.btn-dark {
+ --btn-color: hsl(0, 0%, 100%);
+ --btn-bg: hsl(210, 10%, 20%);
+ --btn-border-color: hsl(210, 10%, 20%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(210, 10%, 18%);
+ --btn-hover-border-color: hsl(210, 10%, 16%);
+ --btn-focus-shadow-rgb: 60, 65, 70;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(210, 10%, 16%);
+ --btn-active-border-color: hsl(210, 10%, 14%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(0, 0%, 100%);
+ --btn-disabled-bg: hsl(210, 10%, 20%);
+ --btn-disabled-border-color: hsl(210, 10%, 20%);
+}
+
+.btn-outline-primary {
+ --btn-color: hsl(240, 98%, 40%);
+ --btn-border-color: hsl(240, 98%, 40%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(240, 98%, 40%);
+ --btn-hover-border-color: hsl(240, 98%, 40%);
+ --btn-focus-shadow-rgb: 80, 80, 180;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(240, 98%, 40%);
+ --btn-active-border-color: hsl(240, 98%, 40%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(240, 98%, 40%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(240, 98%, 40%);
+ --gradient: none;
+}
+
+.btn-outline-secondary {
+ --btn-color: hsl(210, 20%, 60%);
+ --btn-border-color: hsl(210, 20%, 60%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(210, 20%, 60%);
+ --btn-hover-border-color: hsl(210, 20%, 60%);
+ --btn-focus-shadow-rgb: 120, 140, 160;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(210, 20%, 60%);
+ --btn-active-border-color: hsl(210, 20%, 60%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(210, 20%, 60%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(210, 20%, 60%);
+ --gradient: none;
+}
+
+.btn-outline-success {
+ --btn-color: hsl(120, 35%, 55%);
+ --btn-border-color: hsl(120, 35%, 55%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(120, 35%, 55%);
+ --btn-hover-border-color: hsl(120, 35%, 55%);
+ --btn-focus-shadow-rgb: 100, 190, 100;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(120, 35%, 55%);
+ --btn-active-border-color: hsl(120, 35%, 55%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(120, 35%, 55%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(120, 35%, 55%);
+ --gradient: none;
+}
+
+.btn-outline-info {
+ --btn-color: hsl(207, 55%, 65%);
+ --btn-border-color: hsl(207, 55%, 65%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(207, 55%, 65%);
+ --btn-hover-border-color: hsl(207, 55%, 65%);
+ --btn-focus-shadow-rgb: 110, 170, 220;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(207, 55%, 65%);
+ --btn-active-border-color: hsl(207, 55%, 65%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(207, 55%, 65%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(207, 55%, 65%);
+ --gradient: none;
+}
+
+.btn-outline-warning {
+ --btn-color: hsl(38, 100%, 60%);
+ --btn-border-color: hsl(38, 100%, 60%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(38, 100%, 60%);
+ --btn-hover-border-color: hsl(38, 100%, 60%);
+ --btn-focus-shadow-rgb: 240, 190, 70;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(38, 100%, 60%);
+ --btn-active-border-color: hsl(38, 100%, 60%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(38, 100%, 60%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(38, 100%, 60%);
+ --gradient: none;
+}
+
+.btn-outline-danger {
+ --btn-color: hsl(3, 82%, 60%);
+ --btn-border-color: hsl(3, 82%, 60%);
+ --btn-hover-color: hsl(0, 0%, 0%);
+ --btn-hover-bg: hsl(3, 82%, 60%);
+ --btn-hover-border-color: hsl(3, 82%, 60%);
+ --btn-focus-shadow-rgb: 240, 100, 100;
+ --btn-active-color: hsl(0, 0%, 0%);
+ --btn-active-bg: hsl(3, 82%, 60%);
+ --btn-active-border-color: hsl(3, 82%, 60%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(3, 82%, 60%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(3, 82%, 60%);
+ --gradient: none;
+}
+
+/* Outline buttons on dark: keep readable borders */
+.btn-outline-light {
+ --btn-color: #e6ebf1;
+ --btn-border-color: #e6ebf1;
+ --btn-hover-color: #111;
+ --btn-hover-bg: #e6ebf1;
+ --btn-hover-border-color: #e6ebf1;
+ --btn-active-color: #111;
+ --btn-active-bg: #d7dce2;
+ --btn-active-border-color: #d7dce2;
+ --gradient: none;
+}
+
+.btn-outline-dark {
+ --btn-color: hsl(210, 10%, 30%);
+ --btn-border-color: hsl(210, 10%, 30%);
+ --btn-hover-color: hsl(0, 0%, 100%);
+ --btn-hover-bg: hsl(210, 10%, 30%);
+ --btn-hover-border-color: hsl(210, 10%, 30%);
+ --btn-focus-shadow-rgb: 70, 75, 80;
+ --btn-active-color: hsl(0, 0%, 100%);
+ --btn-active-bg: hsl(210, 10%, 30%);
+ --btn-active-border-color: hsl(210, 10%, 30%);
+ --btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+ --btn-disabled-color: hsl(210, 10%, 30%);
+ --btn-disabled-bg: transparent;
+ --btn-disabled-border-color: hsl(210, 10%, 30%);
+ --gradient: none;
+}
+
+/* Links as buttons */
+.btn-link {
+ --btn-font-weight: 400;
+ --btn-color: var(--color-link);
+ --btn-bg: transparent;
+ --btn-border-color: transparent;
+ --btn-hover-color: var(--link-hover-color);
+ --btn-hover-border-color: transparent;
+ --btn-active-color: var(--link-hover-color);
+ --btn-active-border-color: transparent;
+ --btn-disabled-color: #6d7781;
+ --btn-disabled-border-color: transparent;
+ --btn-box-shadow: none;
+ --btn-focus-shadow-rgb: 84, 114, 255;
+ text-decoration: underline;
+}
diff --git a/src/templates/light.custom.css b/src/templates/light.custom.css
new file mode 100644
index 0000000..a6b7379
--- /dev/null
+++ b/src/templates/light.custom.css
@@ -0,0 +1,1219 @@
+@charset "UTF-8";
+/* Copyright (C) 2025 Moko Consulting
+
+ This file is part of a Moko Consulting project.
+
+ SPDX-License-Identifier: GPL-3.0-or-later
+
+/* -----------------------------------------------
+ * LIGHT THEME (CUSTOM)
+ * --------------------------------------------- */
+
+:root[data-bs-theme="light"] {
+color-scheme: light;
+
+
+/* ===== BRAND & THEME COLORS ===== */
+--color-primary: #112855;
+--accent-color-primary: #3f8ff0;
+--accent-color-secondary: #6fb3ff;
+
+
+/* ===== TYPOGRAPHY & BODY ===== */
+--font-sans-serif: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+--font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+--body-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+--body-font-size: 1rem;
+--body-font-weight: 400;
+--body-line-height: 1.5;
+--body-color: #22262a;
+--body-color-rgb: 34, 38, 42;
+--body-bg: #fff;
+--body-bg-rgb: 255, 255, 255;
+--heading-color: inherit;
+--emphasis-color: #000;
+--emphasis-color-rgb: 0, 0, 0;
+--secondary-color: #22262abf;
+--secondary-color-rgb: 34, 38, 42;
+--tertiary-color: #22262a80;
+--tertiary-color-rgb: 34, 38, 42;
+--muted-color: #6d757e;
+--code-color: black;
+--code-color-ink: var(--code-color, #e93f8e);
+--code-bg-color: lightgreen;
+--highlight-color: #22262a;
+--highlight-bg: #fbeea8;
+
+
+/* ===== STANDARD COLORS ===== */
+--blue: #010156;
+--indigo: #6812f3;
+--purple: #6f42c2;
+--pink: #e93f8e;
+--red: #a51f18;
+--orange: #fd7e17;
+--yellow: #ad6200;
+--green: #448344;
+--teal: #5abfdd;
+--cyan: #30638d;
+--black: #000;
+--white: #fff;
+
+
+/* ===== GRAY SCALE ===== */
+--gray-100: #f9fafb;
+--gray-200: #eaedf0;
+--gray-300: #dfe3e7;
+--gray-400: #ced4da;
+--gray-500: #adb5bd;
+--gray-600: #6d757e;
+--gray-700: #484f56;
+--gray-800: #353b41;
+--gray-900: #22262a;
+--white-rgb: 255, 255, 255;
+--black-rgb: 0, 0, 0;
+
+
+/* ===== OPACITY UTILITIES ===== */
+--opacity-0: 0;
+--opacity-5: 0.05;
+--opacity-10: 0.1;
+--opacity-15: 0.15;
+--opacity-20: 0.2;
+--opacity-25: 0.25;
+--opacity-30: 0.3;
+--opacity-50: 0.5;
+--opacity-75: 0.75;
+--opacity-100: 1;
+
+
+/* ===== LAYOUT & SPACING ===== */
+--padding-x: 0.15rem;
+--padding-y: 0.15rem;
+--bg-opacity: 1;
+--nav-toggle-size: 3rem;
+--gradient: linear-gradient(180deg, #ffffff26, #fff0);
+--secondary-bg: #eaedf0;
+--secondary-bg-rgb: 234, 237, 240;
+--tertiary-bg: #f9fafb;
+--tertiary-bg-rgb: 249, 250, 251;
+--hr-color: var(--border-color, #dfe3e7);
+--border-color-soft: var(--border-color, #dfe3e7);
+--kbd-bg: var(--secondary-bg, #eaedf0);
+--kbd-ink: var(--body-bg, #fff);
+--toc-bg: var(--secondary-bg, #eaedf0);
+--toc-ink: var(--color-primary, #112855);
+--selection-bg: var(--highlight-bg, #fbeea8);
+--selection-ink: var(--body-color, #22262a);
+--border: 5px;
+
+
+/* ===== BREAKPOINTS ===== */
+--bp-xs: 0;
+--bp-sm: 576px;
+--bp-md: 768px;
+--bp-lg: 992px;
+--bp-xl: 1200px;
+
+
+/* ===== BORDERS ===== */
+--border-width: 1px;
+--border-style: solid;
+--border-color: #dfe3e7;
+--border-color-translucent: #0000002d;
+--border-radius: .25rem;
+--border-radius-sm: .2rem;
+--border-radius-lg: .3rem;
+--border-radius-xl: .3rem;
+--border-radius-xxl: 2rem;
+--border-radius-2xl: var(--border-radius-xxl)*2;
+--border-radius-pill: 50rem;
+
+
+/* ===== SHADOWS ===== */
+--box-shadow: 0 .5rem 1rem #00000026;
+--box-shadow-sm: 0 .125rem .25rem #00000013;
+--box-shadow-lg: 0 1rem 3rem #0000002d;
+--box-shadow-inset: inset 0 1px 2px #00000013;
+
+
+/* ===== COMMON SHADOW COLORS ===== */
+--shadow-color-light: rgba(var(--black-rgb), var(--opacity-15));
+--shadow-color-medium: rgba(var(--black-rgb), var(--opacity-25));
+--shadow-color-dark: rgba(var(--black-rgb), var(--opacity-30));
+--border-color-translucent: rgba(var(--black-rgb), var(--opacity-10));
+--highlight-translucent: rgba(var(--white-rgb), var(--opacity-15));
+
+
+/* ===== NAVIGATION ===== */
+--mainmenu-nav-link-color: white;
+--nav-text-color: white;
+--nav-bg-color: var(--color-link);
+
+
+/* ===== NAVBAR ===== */
+--navbar-padding-x: 1rem;
+--navbar-padding-y: 0.5rem;
+--navbar-color: var(--nav-text-color);
+--navbar-active-color: var(--mainmenu-nav-link-color);
+--navbar-disabled-color: #6c757d;
+--navbar-brand-padding-y: 0.3125rem;
+--navbar-brand-margin-end: 1rem;
+--navbar-brand-font-size: 1.25rem;
+--navbar-brand-color: var(--nav-text-color);
+--navbar-brand-active-color: var(--mainmenu-nav-link-color);
+--navbar-nav-link-padding-x: 0.5rem;
+--navbar-toggler-padding-y: 0.25rem;
+--navbar-toggler-padding-x: 0.75rem;
+--navbar-toggler-font-size: 1.25rem;
+--navbar-toggler-border-color: rgba(0, 0, 0, 0.1);
+--navbar-toggler-border-radius: 0.25rem;
+--navbar-toggler-focus-width: 0.25rem;
+--navbar-toggler-transition: box-shadow 0.15s ease-in-out;
+--nav-link-padding-x: 1rem;
+--nav-link-padding-y: 0.5rem;
+--nav-link-font-weight: 400;
+--nav-link-color: var(--nav-text-color);
+--nav-link-active-color: var(--mainmenu-nav-link-color);
+--nav-link-disabled-color: #6c757d;
+
+
+/* ===== LINKS ===== */
+--color-link: #224FAA;
+--color-hover: var(--accent-color-primary);
+--link-color: #224faa;
+--link-color-rgb: 34, 79, 170;
+--link-decoration: underline;
+--link-hover-color: #424077;
+--link-hover-color-rgb: 66, 64, 119;
+--link-active-color: var(--link-color);
+
+
+/* ===== LINK UTILITY COLORS ===== */
+--link-primary-color: hsl(240, 98%, 17%);
+--link-primary-hover-color: #010145;
+--link-secondary-color: hsl(210, 7%, 46%);
+--link-secondary-hover-color: #575e65;
+--link-success-color: hsl(120, 32%, 39%);
+--link-success-hover-color: #366936;
+--link-info-color: hsl(207, 49%, 37%);
+--link-info-hover-color: #264f71;
+--link-warning-color: hsl(34, 100%, 34%);
+--link-warning-hover-color: #8a4e00;
+--link-danger-color: hsl(3, 75%, 37%);
+--link-danger-hover-color: #841913;
+--link-light-color: hsl(210, 17%, 98%);
+--link-light-hover-color: #fafbfc;
+--link-dark-color: hsl(210, 10%, 23%);
+--link-dark-hover-color: #2a2f34;
+
+
+/* ===== HEADER BACKGROUND ===== */
+--header-background-image: url('../../../../../../media/templates/site/mokoonyx/images/bg.svg');
+--header-background-attachment: fixed;
+--header-background-repeat: repeat;
+--header-background-size: auto;
+
+
+/* ===== CONTAINER BACKGROUNDS ===== */
+/* Below Topbar Container */
+--container-below-topbar-bg-image: none;
+--container-below-topbar-bg-color: transparent;
+--container-below-topbar-bg-position: auto;
+--container-below-topbar-bg-attachment: fixed;
+--container-below-topbar-bg-repeat: repeat;
+--container-below-topbar-bg-size: auto;
+--container-below-topbar-border: none;
+--container-below-topbar-border-radius: 0;
+
+/* Top A Container */
+--container-top-a-bg-image: none;
+--container-top-a-bg-color: transparent;
+--container-top-a-bg-position: auto;
+--container-top-a-bg-attachment: fixed;
+--container-top-a-bg-repeat: repeat;
+--container-top-a-bg-size: auto;
+--container-top-a-border: none;
+--container-top-a-border-radius: 0;
+
+/* Top B Container */
+--container-top-b-bg-image: none;
+--container-top-b-bg-color: transparent;
+--container-top-b-bg-position: auto;
+--container-top-b-bg-attachment: fixed;
+--container-top-b-bg-repeat: repeat;
+--container-top-b-bg-size: auto;
+--container-top-b-border: none;
+--container-top-b-border-radius: 0;
+
+/* TOC Container */
+--container-toc-bg: var(--mainmenu-nav-link-color);
+--container-toc-color: var(--color-primary);
+
+/* Sidebar Container */
+--container-sidebar-bg-image: none;
+--container-sidebar-bg-color: transparent;
+--container-sidebar-bg-position: auto;
+--container-sidebar-bg-attachment: scroll;
+--container-sidebar-bg-repeat: repeat;
+--container-sidebar-bg-size: auto;
+--container-sidebar-border: none;
+--container-sidebar-border-radius: 0;
+
+/* Bottom A Container */
+--container-bottom-a-bg-image: none;
+--container-bottom-a-bg-color: transparent;
+--container-bottom-a-bg-position: auto;
+--container-bottom-a-bg-attachment: fixed;
+--container-bottom-a-bg-repeat: repeat;
+--container-bottom-a-bg-size: auto;
+--container-bottom-a-border: none;
+--container-bottom-a-border-radius: 0;
+
+/* Bottom B Container */
+--container-bottom-b-bg-image: none;
+--container-bottom-b-bg-color: transparent;
+--container-bottom-b-bg-position: auto;
+--container-bottom-b-bg-attachment: fixed;
+--container-bottom-b-bg-repeat: repeat;
+--container-bottom-b-bg-size: auto;
+--container-bottom-b-border: none;
+--container-bottom-b-border-radius: 0;
+
+
+/* ===== FOCUS & FORMS ===== */
+--focus-ring-width: .25rem;
+--focus-ring-opacity: .25;
+--focus-ring-color: #01015640;
+--input-color: hsl(210, 11%, 15%);
+--input-bg: hsl(210, 20%, 98%);
+--input-border-color: hsl(210, 14%, 83%);
+--input-focus-border-color: #8894aa;
+--input-focus-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+--input-placeholder-color: hsl(210, 7%, 46%);
+--input-disabled-bg: hsl(210, 16%, 93%);
+--input-disabled-border-color: hsl(210, 14%, 83%);
+--input-file-button-active-bg: #dee1e4;
+--form-range-thumb-active-bg: #b8bfcc;
+--form-valid-color: #448344;
+--form-valid-border-color: #448344;
+--form-invalid-color: #a51f18;
+--form-invalid-border-color: #a51f18;
+
+
+/* ===== BUTTONS ===== */
+--btn-border-radius: var(--border-radius);
+--btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
+
+
+/* ===== ACCORDION ===== */
+--accordion-color: hsl(210, 11%, 15%);
+--accordion-bg: var(--body-bg);
+--accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;
+--accordion-border-color: var(--border-color);
+--accordion-border-width: 1px;
+--accordion-border-radius: 0.25rem;
+--accordion-inner-border-radius: calc(0.25rem - 1px);
+--accordion-btn-padding-x: 1.25rem;
+--accordion-btn-padding-y: 1rem;
+--accordion-btn-color: hsl(210, 11%, 15%);
+--accordion-btn-bg: var(--accordion-bg);
+--accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='hsl%28210, 11%25, 15%25%29'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+--accordion-btn-icon-width: 1.25rem;
+--accordion-btn-icon-transform: rotate(-180deg);
+--accordion-btn-icon-transition: transform 0.2s ease-in-out;
+--accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230f244d'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+--accordion-btn-focus-border-color: var(--input-focus-border-color);
+--accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+--accordion-body-padding-x: 1.25rem;
+--accordion-body-padding-y: 1rem;
+--accordion-active-color: #0f244d;
+--accordion-active-bg: #e7eaee;
+
+
+/* ===== ALERT ===== */
+--alert-bg: transparent;
+--alert-padding-x: 1rem;
+--alert-padding-y: 1rem;
+--alert-margin-bottom: 1rem;
+--alert-color: #000;
+--alert-border-color: transparent;
+--alert-border: 1px solid var(--alert-border-color);
+--alert-border-radius: 0.25rem;
+
+
+/* ===== ALERT LINK COLORS ===== */
+--alert-primary-link-color: #01012a;
+--alert-secondary-link-color: #34383d;
+--alert-success-link-color: #213f21;
+--alert-info-link-color: #172f44;
+--alert-warning-link-color: #532f00;
+--alert-danger-link-color: #4f0f0b;
+--alert-light-link-color: #505050;
+--alert-dark-link-color: #1a1c1f;
+
+
+/* ===== BACKDROP ===== */
+--backdrop-zindex: 1040;
+--backdrop-bg: hsl(0, 0%, 0%);
+--backdrop-opacity: 0.5;
+
+
+/* ===== BADGE ===== */
+--badge-padding-x: 0.65em;
+--badge-padding-y: 0.35em;
+--badge-font-size: 0.75em;
+--badge-font-weight: 700;
+--badge-color: var(--body-bg);
+--badge-border-radius: 0.25rem;
+
+
+/* ===== BREADCRUMB ===== */
+--breadcrumb-padding-x: 0;
+--breadcrumb-padding-y: 0;
+--breadcrumb-margin-bottom: 1rem;
+--breadcrumb-bg: ;
+--breadcrumb-border-radius: ;
+--breadcrumb-divider-color: hsl(210, 7%, 46%);
+--breadcrumb-item-padding-x: 0.5rem;
+--breadcrumb-item-active-color: var(--link-color);
+
+
+/* ===== CARDS ===== */
+--card-spacer-y: 1rem;
+--card-spacer-x: 1rem;
+--card-title-spacer-y: 0.5rem;
+--card-border-width: 1px;
+--card-border-color: var(--border-color);
+--card-border-radius: var(--border-radius);
+--card-box-shadow: none;
+--card-inner-border-radius: calc(var(--border-radius) - 1px);
+--card-cap-padding-y: 0.5rem;
+--card-cap-padding-x: 1rem;
+--card-cap-bg: rgba(0, 0, 0, 0.03);
+--card-cap-color: var(--body-color);
+--card-height: auto;
+--card-color: var(--body-color);
+--card-bg: var(--body-bg);
+--card-img-overlay-padding: 1rem;
+--card-group-margin: 0.75rem;
+
+
+/* ===== DROPDOWN ===== */
+--dropdown-zindex: 1000;
+--dropdown-min-width: 10rem;
+--dropdown-padding-x: 0;
+--dropdown-padding-y: 0.5rem;
+--dropdown-spacer: 0.125rem;
+--dropdown-font-size: 1rem;
+--dropdown-color: hsl(210, 11%, 15%);
+--dropdown-bg: var(--body-bg);
+--dropdown-border-color: var(--border-color-translucent);
+--dropdown-border-radius: 0.25rem;
+--dropdown-border-width: 1px;
+--dropdown-inner-border-radius: calc(0.25rem - 1px);
+--dropdown-divider-bg: var(--border-color-translucent);
+--dropdown-divider-margin-y: 0.5rem;
+--dropdown-box-shadow: 0 0.5rem 1rem var(--shadow-color-light);
+--dropdown-link-color: hsl(210, 11%, 15%);
+--dropdown-link-active-color: var(--body-bg);
+--dropdown-link-active-bg: hsl(240, 98%, 17%);
+--dropdown-link-disabled-color: hsl(210, 11%, 71%);
+--dropdown-item-padding-x: 1rem;
+--dropdown-item-padding-y: 0.25rem;
+--dropdown-header-color: hsl(210, 7%, 46%);
+--dropdown-header-padding-x: 1rem;
+--dropdown-header-padding-y: 0.5rem;
+
+
+/* ===== LIST GROUP ===== */
+--list-group-color: hsl(210, 11%, 15%);
+--list-group-bg: var(--body-bg);
+--list-group-border-color: rgba(var(--black-rgb), 0.125);
+--list-group-border-width: 1px;
+--list-group-border-radius: 0.25rem;
+--list-group-item-padding-x: 1rem;
+--list-group-item-padding-y: 0.5rem;
+--list-group-action-color: hsl(210, 9%, 31%);
+--list-group-action-active-color: hsl(210, 11%, 15%);
+--list-group-action-active-bg: hsl(210, 16%, 93%);
+--list-group-disabled-color: hsl(210, 7%, 46%);
+--list-group-disabled-bg: var(--body-bg);
+--list-group-active-color: var(--body-bg);
+--list-group-active-bg: hsl(240, 98%, 17%);
+--list-group-active-border-color: hsl(240, 98%, 17%);
+
+
+/* ===== LIST GROUP ITEM COLORS ===== */
+--list-group-item-primary-color: #010134;
+--list-group-item-primary-bg: #ccccdd;
+--list-group-item-primary-active-bg: #b8b8c7;
+--list-group-item-secondary-color: #41464c;
+--list-group-item-secondary-bg: #e2e3e5;
+--list-group-item-secondary-active-bg: #cbccce;
+--list-group-item-success-color: #294f29;
+--list-group-item-success-bg: #dae6da;
+--list-group-item-success-active-bg: #c4cfc4;
+--list-group-item-info-color: #1d3b55;
+--list-group-item-info-bg: #d6e0e8;
+--list-group-item-info-active-bg: #c1cad1;
+--list-group-item-warning-color: #683b00;
+--list-group-item-warning-bg: #efe0cc;
+--list-group-item-warning-active-bg: #d7cab8;
+--list-group-item-danger-color: #63130e;
+--list-group-item-danger-bg: #edd2d1;
+--list-group-item-danger-active-bg: #d5bdbc;
+--list-group-item-light-color: #646464;
+--list-group-item-light-bg: #fefefe;
+--list-group-item-light-active-bg: #e5e5e5;
+--list-group-item-dark-color: #202327;
+--list-group-item-dark-bg: #d7d8d9;
+--list-group-item-dark-active-bg: #c2c2c3;
+
+
+/* ===== MODAL ===== */
+--modal-zindex: 1050;
+--modal-width: 500px;
+--modal-padding: 1rem;
+--modal-margin: 0.5rem;
+--modal-color: ;
+--modal-bg: var(--body-bg);
+--modal-border-color: var(--border-color-translucent);
+--modal-border-width: 1px;
+--modal-border-radius: 0.3rem;
+--modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
+--modal-inner-border-radius: calc(0.3rem - 1px);
+--modal-header-padding-x: 1rem;
+--modal-header-padding-y: 1rem;
+--modal-header-padding: 1rem 1rem;
+--modal-header-border-color: var(--border-color);
+--modal-header-border-width: 1px;
+--modal-title-line-height: 1.5;
+--modal-footer-gap: 0.5rem;
+--modal-footer-bg: ;
+--modal-footer-border-color: var(--border-color);
+--modal-footer-border-width: 1px;
+
+
+/* ===== NAV TABS ===== */
+--nav-tabs-border-width: 1px;
+--nav-tabs-border-color: hsl(210, 14%, 89%);
+--nav-tabs-border-radius: 0.25rem;
+--nav-tabs-link-active-color: hsl(210, 9%, 31%);
+--nav-tabs-link-active-bg: var(--body-bg);
+--nav-tabs-link-active-border-color: hsl(210, 14%, 89%) hsl(210, 14%, 89%) var(--body-bg);
+
+
+/* ===== NAV PILLS ===== */
+--nav-pills-border-radius: 0.25rem;
+--nav-pills-link-active-color: var(--body-bg);
+--nav-pills-link-active-bg: hsl(240, 98%, 17%);
+
+
+/* ===== OFFCANVAS ===== */
+--offcanvas-zindex: 1045;
+--offcanvas-width: 400px;
+--offcanvas-height: 30vh;
+--offcanvas-padding-x: 1rem;
+--offcanvas-padding-y: 1rem;
+--offcanvas-color: var(--body-color);
+--offcanvas-bg: var(--body-bg);
+--offcanvas-border-width: 1px;
+--offcanvas-border-color: var(--border-color-translucent);
+--offcanvas-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
+
+
+/* ===== PAGINATION ===== */
+--pagination-padding-x: 0.75rem;
+--pagination-padding-y: 0.375rem;
+--pagination-font-size: 1rem;
+--pagination-color: var(--link-color);
+--pagination-bg: var(--body-bg);
+--pagination-border-width: 1px;
+--pagination-border-color: hsl(210, 14%, 89%);
+--pagination-border-radius: 0.25rem;
+--pagination-focus-color: var(--link-active-color);
+--pagination-focus-bg: hsl(210, 16%, 93%);
+--pagination-focus-box-shadow: 0 0 0 0.25rem rgba(1, 1, 86, 0.25);
+--pagination-active-color: var(--body-bg);
+--pagination-active-bg: hsl(240, 98%, 17%);
+--pagination-active-border-color: hsl(240, 98%, 17%);
+--pagination-disabled-color: hsl(210, 7%, 46%);
+--pagination-disabled-bg: var(--body-bg);
+--pagination-disabled-border-color: hsl(210, 14%, 89%);
+
+
+/* ===== POPOVER ===== */
+--popover-zindex: 1060;
+--popover-max-width: 276px;
+--popover-font-size: 0.875rem;
+--popover-bg: var(--body-bg);
+--popover-border-width: 1px;
+--popover-border-color: var(--border-color-translucent);
+--popover-border-radius: 0.3rem;
+--popover-inner-border-radius: calc(0.3rem - 1px);
+--popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
+--popover-header-padding-x: 1rem;
+--popover-header-padding-y: 0.5rem;
+--popover-header-font-size: 1rem;
+--popover-header-color: ;
+--popover-header-bg: #f0f0f0;
+--popover-body-padding-x: 1rem;
+--popover-body-padding-y: 1rem;
+--popover-body-color: hsl(210, 11%, 15%);
+--popover-arrow-width: 1rem;
+--popover-arrow-height: 0.5rem;
+--popover-arrow-border: var(--popover-border-color);
+
+
+/* ===== PROGRESS ===== */
+--progress-height: 1rem;
+--progress-font-size: 0.75rem;
+--progress-bg: hsl(210, 16%, 93%);
+--progress-border-radius: 0.25rem;
+--progress-box-shadow: inset 0 1px 2px rgba(var(--black-rgb), 0.075);
+--progress-bar-color: var(--body-bg);
+--progress-bar-bg: hsl(240, 98%, 17%);
+--progress-bar-transition: width 0.6s ease;
+
+
+/* ===== SPINNER ===== */
+--spinner-width: 2rem;
+--spinner-height: 2rem;
+--spinner-vertical-align: -0.125em;
+--spinner-border-width: 0.25em;
+--spinner-animation-speed: 0.75s;
+
+
+/* ===== TABLE ===== */
+--table-color: var(--body-color);
+--table-bg: transparent;
+--table-border-color: var(--border-color);
+--table-accent-bg: transparent;
+--table-striped-color: var(--body-color);
+--table-striped-bg: rgba(var(--black-rgb), var(--opacity-5));
+--table-active-color: var(--body-color);
+--table-active-bg: rgba(var(--black-rgb), 0.075);
+
+
+/* ===== TOAST ===== */
+--toast-zindex: 1090;
+--toast-padding-x: 0.75rem;
+--toast-padding-y: 0.5rem;
+--toast-spacing: 1em;
+--toast-max-width: 350px;
+--toast-font-size: 0.875rem;
+--toast-color: ;
+--toast-bg: rgba(255, 255, 255, 0.85);
+--toast-border-width: 1px;
+--toast-border-color: var(--border-color-translucent);
+--toast-border-radius: 0.25rem;
+--toast-box-shadow: 0 0.5rem 1rem var(--shadow-color-light);
+--toast-header-color: hsl(210, 7%, 46%);
+--toast-header-bg: rgba(var(--white-rgb), 0.85);
+--toast-header-border-color: rgba(var(--black-rgb), var(--opacity-5));
+
+
+/* ===== TOOLTIP ===== */
+--tooltip-zindex: 1070;
+--tooltip-max-width: 200px;
+--tooltip-padding-x: 0.5rem;
+--tooltip-padding-y: 0.25rem;
+--tooltip-margin: ;
+--tooltip-font-size: 0.875rem;
+--tooltip-color: var(--body-bg);
+--tooltip-bg: hsl(0, 0%, 0%);
+--tooltip-border-radius: 0.25rem;
+--tooltip-opacity: 0.9;
+--tooltip-arrow-width: 0.8rem;
+--tooltip-arrow-height: 0.4rem;
+
+
+/* ===== BOOTSTRAP PALETTE ===== */
+--primary: #010156;
+--secondary: #6d757e;
+--success: #448344;
+--info: #30638d;
+--warning: #ad6200;
+--danger: #a51f18;
+--light: #f9fafb;
+--dark: #353b41;
+--primary-rgb: 1, 1, 86;
+--secondary-rgb: 109, 117, 126;
+--success-rgb: 68, 131, 68;
+--info-rgb: 48, 99, 141;
+--warning-rgb: 173, 98, 0;
+--danger-rgb: 165, 31, 24;
+--light-rgb: 249, 250, 251;
+--dark-rgb: 53, 59, 65;
+--primary-text-emphasis: #002;
+--secondary-text-emphasis: #2c2f32;
+--success-text-emphasis: #1b351b;
+--info-text-emphasis: #132838;
+--warning-text-emphasis: #452700;
+--danger-text-emphasis: #420c09;
+--light-text-emphasis: #484f56;
+--dark-text-emphasis: #484f56;
+--primary-bg-subtle: #ccd;
+--secondary-bg-subtle: #e2e3e5;
+--success-bg-subtle: #dae6da;
+--info-bg-subtle: #d6e0e8;
+--warning-bg-subtle: #efe0cc;
+--danger-bg-subtle: #edd2d1;
+--light-bg-subtle: #fcfcfd;
+--dark-bg-subtle: #ced4da;
+--primary-border-subtle: #99b;
+--secondary-border-subtle: #c5c8cb;
+--success-border-subtle: #b4ceb4;
+--info-border-subtle: #acc1d1;
+--warning-border-subtle: #dec099;
+--danger-border-subtle: #dba5a2;
+--light-border-subtle: #eaedf0;
+--dark-border-subtle: #adb5bd;
+
+
+/* ===== HERO / BANNER OVERLAY ===== */
+--hero-height: 70vh;
+--hero-color: var(--body-color);
+--hero-bg-repeat: no-repeat;
+--hero-bg-attachment: fixed;
+--hero-bg-position: top center;
+--hero-bg-size: cover;
+--hero-border-bottom: solid var(--accent-color-secondary);
+--hero-overlay-bg: hsla(0, 0%, 0%, 0.1);
+--hero-overlay-bg-position: center;
+--hero-overlay-bg-size: cover;
+--hero-overlay-padding: 1em;
+--hero-overlay-text-align: center;
+--hero-overlay-text-color: var(--body-color);
+
+
+/* ===== HERO VARIANTS ===== */
+/* Primary — sky blue, light overlay */
+--hero-primary-bg-color: var(--color-primary);
+--hero-primary-overlay: linear-gradient(rgba(163, 205, 226, .45), rgba(163, 205, 226, .45));
+--hero-primary-color: var(--color-primary);
+
+/* Secondary — navy, stronger overlay */
+--hero-secondary-bg-color: var(--color-primary);
+--hero-secondary-overlay: linear-gradient(rgba(17, 40, 85, .75), rgba(17, 40, 85, .75));
+--hero-secondary-color: #f1f5f9;
+
+
+/* ===== HERO CARD (inner .hero element) ===== */
+/* Default card — uses primary variant values */
+--hero-card-bg: var(--hero-primary-bg-color);
+--hero-card-color: white;
+--hero-card-overlay: var(--hero-primary-overlay);
+--hero-card-border-radius: .5rem;
+--hero-card-padding-x: 2rem;
+--hero-card-padding-y: 3rem;
+--hero-card-max-width: 800px;
+
+/* Alternative card — uses secondary variant values */
+--hero-alt-card-bg: var(--hero-secondary-bg-color);
+--hero-alt-card-color: var(--hero-secondary-color);
+--hero-alt-card-overlay: var(--hero-secondary-overlay);
+--hero-alt-card-border-radius: .5rem;
+--hero-alt-card-padding-x: 2rem;
+--hero-alt-card-padding-y: 3rem;
+--hero-alt-card-max-width: 600px;
+
+
+/* ===== BLOCK COLORS (top-a / top-b / bottom-a / bottom-b) ===== */
+--block-color-1: var(--color-primary);
+--block-text-1: var(--body-color);
+
+--block-color-2: var(--accent-color-primary);
+--block-text-2: #fff;
+
+--block-color-3: var(--warning, #eec234);
+--block-text-3: var(--body-color);
+
+--block-color-4: var(--success-bg-subtle, #eef7f0);
+--block-text-4: var(--body-color);
+
+
+/* ===== BLOCK COLOR OVERRIDES ===== */
+--block-highlight-bg: var(--accent-color-primary);
+--block-highlight-text: #fff;
+
+--block-cta-bg: var(--color-primary);
+--block-cta-text: #fff;
+
+--block-alert-bg: var(--danger, #a51f18);
+--block-alert-text: #fff;
+
+
+/* ===== FOOTER ===== */
+--footer-padding-top: 1rem;
+--footer-padding-bottom: 80px;
+--footer-grid-padding-y: 2.5rem;
+--footer-grid-padding-x: 0.5em;
+
+
+/* ===== THEME FAB ===== */
+--theme-fab-bg: var(--color-primary, #112855);
+--theme-fab-color: #fff;
+--theme-fab-btn-bg: rgba(255,255,255,.15);
+--theme-fab-border: rgba(255, 255, 255, 0.3);
+
+
+/* ===== OFFLINE PAGE ===== */
+--offline-card-bg: rgba(0, 0, 0, 0.55);
+
+
+/* ===== COMPONENT-SPECIFIC COLORS ===== */
+--mod-finder-link-hover: #e6e6e6;
+--form-legend-color: #495057;
+--border-gray: #b2bfcd;
+--subhead-color: #495057;
+--box-shadow-gray: #ddd;
+--btn-active-text-gray: #A0A0A0;
+--indicator-success-bg: var(--success);
+--item-list-color: #F5F5F5;
+--notification-badge-bg: var(--danger);
+--content-bg-gray: #DDD;
+--taba-btn-green: #7ac143;
+--taba-btn-blue: #5091cd;
+--taba-btn-red: #f44321;
+--taba-btn-gray: #AAA;
+--taba-msg-bg: #f5f5f5;
+--toc-link-color: #767676;
+--toc-link-active-color: #563d7c;
+--choices-disabled-bg: #eaeaea;
+--choices-input-bg: var(--white);
+--choices-border-light: #ddd;
+--choices-arrow-color: #333;
+--choices-inner-bg: #f9f9f9;
+--choices-focused-border: #b7b7b7;
+--choices-dropdown-bg: var(--white);
+--choices-item-bg: #00bcd4;
+--choices-item-border: #00a5bb;
+--choices-item-hover-bg: #00a5bb;
+--choices-item-hover-border: #008fa1;
+--choices-item-disabled-bg: #aaaaaa;
+--choices-item-disabled-border: #919191;
+--choices-item-highlighted: #f2f2f2;
+--choices-input-inner-bg: #f9f9f9;
+
+
+/* ===== VIRTUEMART (VM) ===== */
+/* VM Surfaces */
+--vm-surface: #ffffff;
+--vm-surface-2: #f8f9fa;
+--vm-text: var(--body-color);
+--vm-text-strong: #000000;
+--vm-text-muted: #6c757d;
+--vm-border: var(--border-color);
+--vm-price-color: var(--success);
+
+/* VM Layout and Density */
+--vm-container-max-width: 1200px;
+--vm-section-gap: 2rem;
+--vm-block-radius: var(--border-radius);
+--vm-block-shadow: var(--box-shadow-sm);
+
+/* VM Typography */
+--vm-category-title-size: 2rem;
+--vm-subcategory-title-size: 1.5rem;
+--vm-page-title-size: 1.75rem;
+--vm-products-type-title-size: 1.25rem;
+--vm-product-title-size: 1.125rem;
+--vm-product-title-weight: 500;
+--vm-products-type-title-weight: 600;
+--vm-price-size: 1.5rem;
+--vm-price-detail-size: 1.125rem;
+--vm-price-desc-size: 0.875rem;
+
+/* VM Controls */
+--vm-input-radius: var(--border-radius);
+--vm-input-shadow: var(--box-shadow-sm);
+--vm-qty-width: 80px;
+--vm-cart-dropdown-min-width: 300px;
+
+/* VM Alerts */
+--vm-alert-radius: var(--border-radius);
+--vm-alert-shadow: var(--box-shadow-sm);
+--vm-availability-bg: var(--success-bg-subtle);
+--vm-availability-text: var(--success);
+
+/* VM Buttons */
+--vm-btn-padding-x: 1rem;
+--vm-btn-padding-y: 0.5rem;
+--vm-btn-radius: var(--border-radius);
+--vm-btn-shadow: var(--box-shadow-sm);
+--vm-btn-primary-bg: var(--primary);
+--vm-btn-primary-text: #ffffff;
+--vm-btn-primary-border: var(--primary);
+--vm-btn-secondary-bg: var(--secondary);
+--vm-btn-secondary-text: #ffffff;
+--vm-btn-secondary-border: var(--secondary);
+
+/* VM Image Overlay Controls */
+--vm-image-overlay-gap-x: 0.5rem;
+--vm-image-overlay-gap-y: 0.5rem;
+--vm-image-overlay-raise: 0.25rem;
+--vm-image-overlay-btn-size: 2.5rem;
+--vm-image-overlay-btn-radius: 50%;
+--vm-image-overlay-btn-bg: rgba(255, 255, 255, 0.9);
+--vm-image-overlay-btn-bg-hover: rgba(255, 255, 255, 1);
+--vm-image-overlay-btn-border-color: rgba(0, 0, 0, 0.1);
+--vm-image-overlay-btn-border-width: 1px;
+--vm-image-overlay-btn-color: var(--body-color);
+--vm-image-overlay-btn-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+
+/* VM Vendor Menu */
+--vm-vendor-menu-bg: var(--body-bg);
+--vm-vendor-menu-border: var(--border-color);
+--vm-vendor-menu-radius: var(--border-radius);
+--vm-vendor-menu-shadow: var(--box-shadow-sm);
+--vm-vendor-menu-item-gap: 0.25rem;
+--vm-vendor-menu-item-padding-x: 1rem;
+--vm-vendor-menu-item-padding-y: 0.5rem;
+--vm-vendor-menu-pill-radius: 50rem;
+--vm-vendor-menu-link: var(--link-color);
+--vm-vendor-menu-link-hover: var(--link-hover-color);
+--vm-vendor-menu-link-active: var(--primary);
+--vm-vendor-menu-hover-bg: var(--secondary-bg);
+
+
+/* ===== GABLE ===== */
+--gab-blue: #0066cc;
+--gab-green: #28a745;
+--gab-red: #dc3545;
+--gab-orange: #fd7e14;
+--gab-gray1: #495057;
+--gab-gray2: #6c757d;
+--gab-gray3: #adb5bd;
+
+}
+
+.btn {
+--btn-padding-x: 1rem;
+--btn-padding-y: 0.6rem;
+--btn-font-family: inherit;
+--btn-font-size: 1rem;
+--btn-font-weight: 400;
+--btn-line-height: 1.5;
+--btn-color: hsl(210, 11%, 15%);
+--btn-bg: var(--body-bg);
+--btn-border-width: 1px;
+--btn-border-color: transparent;
+--btn-border-radius: 0.25rem;
+--btn-active-border-color: transparent;
+--btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
+--btn-disabled-opacity: 0.65;
+--btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--btn-focus-shadow-rgb), .5);
+display: inline-block;
+padding: var(--btn-padding-y) var(--btn-padding-x);
+font-family: var(--btn-font-family);
+font-size: var(--btn-font-size);
+font-weight: var(--btn-font-weight);
+line-height: var(--btn-line-height);
+color: var(--btn-color);
+text-align: center;
+text-decoration: none;
+vertical-align: middle;
+cursor: pointer;
+-webkit-user-select: none;
+-moz-user-select: none;
+-ms-user-select: none;
+user-select: none;
+border: var(--btn-border-width) solid var(--btn-border-color);
+border-radius: var(--btn-border-radius);
+background-color: var(--btn-bg);
+-webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+-o-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, -webkit-box-shadow 0.15s ease-in-out;
+}
+
+.btn-primary {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(240, 98%, 17%);
+--btn-border-color: hsl(240, 98%, 17%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #010149;
+--btn-hover-border-color: #010145;
+--btn-focus-shadow-rgb: 39, 39, 111;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #010145;
+--btn-active-border-color: #010141;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(240, 98%, 17%);
+--btn-disabled-border-color: hsl(240, 98%, 17%);
+}
+
+.btn-secondary {
+--btn-color: var(--body-bg);
+--btn-bg: var(--nav-bg-color);
+--btn-border-color: hsl(210, 7%, 46%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #5d636b;
+--btn-hover-border-color: #575e65;
+--btn-focus-shadow-rgb: gray;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #575e65;
+--btn-active-border-color: #52585f;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(210, 7%, 46%);
+--btn-disabled-border-color: hsl(210, 7%, 46%);
+}
+
+.btn-success {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(120, 32%, 39%);
+--btn-border-color: hsl(120, 32%, 39%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #3a6f3a;
+--btn-hover-border-color: #366936;
+--btn-focus-shadow-rgb: 96, 150, 96;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #366936;
+--btn-active-border-color: #336233;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(120, 32%, 39%);
+--btn-disabled-border-color: hsl(120, 32%, 39%);
+}
+
+.btn-info {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(207, 49%, 37%);
+--btn-border-color: hsl(207, 49%, 37%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #295478;
+--btn-hover-border-color: #264f71;
+--btn-focus-shadow-rgb: 79, 122, 158;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #264f71;
+--btn-active-border-color: #244a6a;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(207, 49%, 37%);
+--btn-disabled-border-color: hsl(207, 49%, 37%);
+}
+
+.btn-warning {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(34, 100%, 34%);
+--btn-border-color: hsl(34, 100%, 34%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #935300;
+--btn-hover-border-color: #8a4e00;
+--btn-focus-shadow-rgb: 185, 122, 38;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #8a4e00;
+--btn-active-border-color: #824a00;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(34, 100%, 34%);
+--btn-disabled-border-color: hsl(34, 100%, 34%);
+}
+
+.btn-danger {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(3, 75%, 37%);
+--btn-border-color: hsl(3, 75%, 37%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #8c1a14;
+--btn-hover-border-color: #841913;
+--btn-focus-shadow-rgb: 179, 65, 59;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #841913;
+--btn-active-border-color: #7c1712;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(3, 75%, 37%);
+--btn-disabled-border-color: hsl(3, 75%, 37%);
+}
+
+.btn-light {
+--btn-color: hsl(0, 0%, 0%);
+--btn-bg: hsl(210, 17%, 98%);
+--btn-border-color: hsl(210, 17%, 98%);
+--btn-hover-color: hsl(0, 0%, 0%);
+--btn-hover-bg: #d4d5d5;
+--btn-hover-border-color: #c7c8c9;
+--btn-focus-shadow-rgb: 212, 213, 213;
+--btn-active-color: hsl(0, 0%, 0%);
+--btn-active-bg: #c7c8c9;
+--btn-active-border-color: #bbbcbc;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 0%);
+--btn-disabled-bg: hsl(210, 17%, 98%);
+--btn-disabled-border-color: hsl(210, 17%, 98%);
+}
+
+.btn-dark {
+--btn-color: hsl(0, 0%, 100%);
+--btn-bg: hsl(210, 10%, 23%);
+--btn-border-color: hsl(210, 10%, 23%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: #53585e;
+--btn-hover-border-color: #494f54;
+--btn-focus-shadow-rgb: 83, 88, 94;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: #5d6267;
+--btn-active-border-color: #494f54;
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(0, 0%, 100%);
+--btn-disabled-bg: hsl(210, 10%, 23%);
+--btn-disabled-border-color: hsl(210, 10%, 23%);
+}
+
+.btn-outline-primary {
+--btn-color: hsl(240, 98%, 17%);
+--btn-border-color: hsl(240, 98%, 17%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(240, 98%, 17%);
+--btn-hover-border-color: hsl(240, 98%, 17%);
+--btn-focus-shadow-rgb: 1, 1, 86;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(240, 98%, 17%);
+--btn-active-border-color: hsl(240, 98%, 17%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(240, 98%, 17%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(240, 98%, 17%);
+--gradient: none;
+}
+
+.btn-outline-secondary {
+--btn-color: hsl(210, 7%, 46%);
+--btn-border-color: hsl(210, 7%, 46%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(210, 7%, 46%);
+--btn-hover-border-color: hsl(210, 7%, 46%);
+--btn-focus-shadow-rgb: 109, 117, 126;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(210, 7%, 46%);
+--btn-active-border-color: hsl(210, 7%, 46%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(210, 7%, 46%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(210, 7%, 46%);
+--gradient: none;
+}
+
+.btn-outline-success {
+--btn-color: hsl(120, 32%, 39%);
+--btn-border-color: hsl(120, 32%, 39%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(120, 32%, 39%);
+--btn-hover-border-color: hsl(120, 32%, 39%);
+--btn-focus-shadow-rgb: 68, 131, 68;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(120, 32%, 39%);
+--btn-active-border-color: hsl(120, 32%, 39%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(120, 32%, 39%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(120, 32%, 39%);
+--gradient: none;
+}
+
+.btn-outline-info {
+--btn-color: hsl(207, 49%, 37%);
+--btn-border-color: hsl(207, 49%, 37%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(207, 49%, 37%);
+--btn-hover-border-color: hsl(207, 49%, 37%);
+--btn-focus-shadow-rgb: 48, 99, 141;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(207, 49%, 37%);
+--btn-active-border-color: hsl(207, 49%, 37%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(207, 49%, 37%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(207, 49%, 37%);
+--gradient: none;
+}
+
+.btn-outline-warning {
+--btn-color: hsl(34, 100%, 34%);
+--btn-border-color: hsl(34, 100%, 34%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(34, 100%, 34%);
+--btn-hover-border-color: hsl(34, 100%, 34%);
+--btn-focus-shadow-rgb: 173, 98, 0;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(34, 100%, 34%);
+--btn-active-border-color: hsl(34, 100%, 34%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(34, 100%, 34%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(34, 100%, 34%);
+--gradient: none;
+}
+
+.btn-outline-danger {
+--btn-color: hsl(3, 75%, 37%);
+--btn-border-color: hsl(3, 75%, 37%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(3, 75%, 37%);
+--btn-hover-border-color: hsl(3, 75%, 37%);
+--btn-focus-shadow-rgb: 165, 31, 24;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(3, 75%, 37%);
+--btn-active-border-color: hsl(3, 75%, 37%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(3, 75%, 37%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(3, 75%, 37%);
+--gradient: none;
+}
+
+.btn-outline-light {
+--btn-color: hsl(210, 17%, 98%);
+--btn-border-color: hsl(210, 17%, 98%);
+--btn-hover-color: hsl(0, 0%, 0%);
+--btn-hover-bg: hsl(210, 17%, 98%);
+--btn-hover-border-color: hsl(210, 17%, 98%);
+--btn-focus-shadow-rgb: 249, 250, 251;
+--btn-active-color: hsl(0, 0%, 0%);
+--btn-active-bg: hsl(210, 17%, 98%);
+--btn-active-border-color: hsl(210, 17%, 98%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(210, 17%, 98%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(210, 17%, 98%);
+--gradient: none;
+}
+
+.btn-outline-dark {
+--btn-color: hsl(210, 10%, 23%);
+--btn-border-color: hsl(210, 10%, 23%);
+--btn-hover-color: hsl(0, 0%, 100%);
+--btn-hover-bg: hsl(210, 10%, 23%);
+--btn-hover-border-color: hsl(210, 10%, 23%);
+--btn-focus-shadow-rgb: 53, 59, 65;
+--btn-active-color: hsl(0, 0%, 100%);
+--btn-active-bg: hsl(210, 10%, 23%);
+--btn-active-border-color: hsl(210, 10%, 23%);
+--btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+--btn-disabled-color: hsl(210, 10%, 23%);
+--btn-disabled-bg: transparent;
+--btn-disabled-border-color: hsl(210, 10%, 23%);
+--gradient: none;
+}
+
+.btn-link {
+--btn-font-weight: 400;
+--btn-color: var(--link-color);
+--btn-bg: transparent;
+--btn-border-color: transparent;
+--btn-hover-color: var(--link-hover-color);
+--btn-hover-border-color: transparent;
+--btn-active-color: var(--link-hover-color);
+--btn-active-border-color: transparent;
+--btn-disabled-color: hsl(210, 7%, 46%);
+--btn-disabled-border-color: transparent;
+--btn-box-shadow: none;
+--btn-focus-shadow-rgb: 39, 39, 111;
+text-decoration: underline;
+}
diff --git a/src/templates/theme-test.html b/src/templates/theme-test.html
new file mode 100644
index 0000000..07a9f45
--- /dev/null
+++ b/src/templates/theme-test.html
@@ -0,0 +1,836 @@
+
+
+
+
+
+
+MokoOnyx — Theme Test Sheet
+
+
+
+
+
+
+
+
+
+ Toggle Light / Dark
+
+
+
+
+
+
MokoOnyx Theme Test Sheet
+
Visual reference for CSS variables, Bootstrap components, hero variants, and block color system. Toggle light/dark mode with the button in the top-right corner.
+
+
+
+
+
1. Brand & Theme Colors
+
+
+
+
+
--accent-color-primary
+
+
+
+
--accent-color-secondary
+
+
+
+
+
+
+
+
+
+
2. Bootstrap Color Palette
+
+
+
+
3. Gray Scale
+
+
+
+
4. Standard Colors
+
+
+
+
5. Typography
+
+
Heading 1 h1
+ Heading 2 h2
+ Heading 3 h3
+ Heading 4 h4
+ Heading 5 h5
+ Heading 6 h6
+
+
This is regular body text using --body-color on --body-bg. Font family: --body-font-family. Size: --body-font-size (1rem).
+
Bold text. Italic text. This is a link . Inline code. Highlighted text .
+
This is lead text styled with --muted-color.
+
+
+
6. Link Colors
+
+ Variable Preview
+ --link-colorSample link
+ --link-hover-colorHover state
+ --color-linkcolor-link value
+ --color-hovercolor-hover value
+
+
+
+
7. Buttons
+
+ Primary
+ Secondary
+ Success
+ Danger
+ Warning
+ Info
+ Light
+ Dark
+
+
+ Outline Primary
+ Outline Secondary
+ Outline Success
+ Outline Danger
+
+
+
+
8. Cards
+
+
+
+
Card Header
+
+
Card Title
+
Card body using --card-bg, --card-color, and --card-border-color.
+
Action
+
+
+
+
+
+
Simple Card
+
No header, just body content. Uses the same card variables.
+
+
+
+
+
+
9. Form Elements
+
+
+ Text Input
+
+
+
+ Select
+
+ Option 1
+ Option 2
+ Option 3
+
+
+
+ Textarea
+
+
+
+
+
+
10. Alerts
+
+ Primary alert. Uses --primary-bg-subtle and --primary-text-emphasis.
+
+
+ Success alert. Uses --success-bg-subtle and --success-text-emphasis.
+
+
+ Warning alert. Uses --warning-bg-subtle and --warning-text-emphasis.
+
+
+ Danger alert. Uses --danger-bg-subtle and --danger-text-emphasis.
+
+
+ Info alert. Uses --info-bg-subtle and --info-text-emphasis.
+
+
+
+
11. Borders & Shadows
+
+
+ Default border: --border-width / --border-color / --border-radius
+
+
+ --box-shadow-sm
+
+
+ --box-shadow
+
+
+ --box-shadow-lg
+
+
+
+
+
12. Navigation Colors
+
+
+
+
+
+
--mainmenu-nav-link-color
+
+
+
+
+
13. Container Background Variables
+
+ Container BG Color BG Image Border
+ below-topbar --container-below-topbar-bg-color--container-below-topbar-bg-image--container-below-topbar-border
+ top-a --container-top-a-bg-color--container-top-a-bg-image--container-top-a-border
+ top-b --container-top-b-bg-color--container-top-b-bg-image--container-top-b-border
+ bottom-a --container-bottom-a-bg-color--container-bottom-a-bg-image--container-bottom-a-border
+ bottom-b --container-bottom-b-bg-color--container-bottom-b-bg-image--container-bottom-b-border
+ sidebar --container-sidebar-bg-color--container-sidebar-bg-image--container-sidebar-border
+
+
+
+
14. Hero Variants NEW
+
The .hero#primary and .hero#secondary variants use CSS variables for background color, overlay gradient, and text color. Each adapts automatically with the active theme.
+
+
Primary Variant — .hero#primary
+
+
+
Primary Hero
+
Homepage & main landing pages — sky blue tint, softer overlay
+
+
+
+
Secondary Variant — .hero#secondary
+
+
+
Secondary Hero
+
Inner pages, events, about — navy overlay, lighter text
+
+
+
+
Hero Variable Reference
+
+ Variable Variant Purpose
+ --hero-primary-bg-colorPrimary Fallback background color
+ --hero-primary-overlayPrimary Gradient overlay tint
+ --hero-primary-colorPrimary Text color
+ --hero-secondary-bg-colorSecondary Fallback background color
+ --hero-secondary-overlaySecondary Gradient overlay tint
+ --hero-secondary-colorSecondary Text color
+
+
+
+
15. Block Color System NEW
+
Modules in top-a, top-b, bottom-a, and bottom-b positions automatically receive brand colors based on their order. No classes needed — :nth-child() handles assignment.
+
+
Slot Palette Preview
+
+
+ Slot 1
+ --block-color-1
+
+
+ Slot 2
+ --block-color-2
+
+
+ Slot 3
+ --block-color-3
+
+
+ Slot 4
+ --block-color-4
+
+
+
+
Named Override Preview
+
+
+ #block-highlight
+ --block-highlight-bg
+
+
+ #block-cta
+ --block-cta-bg
+
+
+ #block-alert
+ --block-alert-bg
+
+
+
+
Block Variable Reference
+
+ Variable Purpose
+ --block-color-1 / --block-text-11st module in position (automatic)
+ --block-color-2 / --block-text-22nd module in position (automatic)
+ --block-color-3 / --block-text-33rd module in position (automatic)
+ --block-color-4 / --block-text-44th module in position (automatic)
+ --block-highlight-bg / --block-highlight-textNamed override for #block-highlight
+ --block-cta-bg / --block-cta-textNamed override for #block-cta
+ --block-alert-bg / --block-alert-textNamed override for #block-alert
+
+
+
Override Priority
+
+ Priority Method How Applied
+ 1 (highest) Named module ID (#block-highlight) ID in module HTML + named variable
+ 2 (default) Slot color (--block-color-N) Automatic by :nth-child() order
+
+
+
+
16. VirtueMart Surface Colors
+
+
+
+
17. Gable Colors
+
+
+
+
18. Code & Preformatted Text
+
Inline code: var(--color-primary)
+
/* Example: overriding block slot 1 in colors_custom.css */
+--block-color-1: var(--accent-color-primary);
+--block-text-1: #fff;
+
+/* Hero variant usage in module HTML */
+<div class="hero" id="primary"
+ style="background-image:url('/images/hero/main.jpg')">
+ <div class="col-12 py-5 px-4 text-center">
+ ...content...
+ </div>
+</div>
+
+
+
19. Opacity Scale
+
+
5%
+
10%
+
15%
+
25%
+
50%
+
75%
+
100%
+
+
+
+
21. Branded Bootstrap 5 Showcase
+
Comprehensive component demos using MokoOnyx's brand variables. Mirrors the live Joomla article at /style/branded-bootstrap5.
+
+
+
+
Brand + Bootstrap Showcase
+
Comprehensive components with toggleable code samples
+
+
+
+
+Brand Nav
+Home
+About
+Contact
+
+
+
+
+
+Home
+Style
+Branded Bootstrap5
+
+
+
+
+
Typography
+
+
+
H1 Heading
+
H2 Heading
+
H3 Heading
+
H4 Heading
+
H5 Heading
+
H6 Heading
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.
+
Curabitur ullamcorper nec nisi a themed link . Nulla vitae <section> purus.
+
+"Design is intelligence made visible."
+
+
+
+
+
+
+
Buttons & Button Groups
+
+Primary
+Secondary
+Success
+Info
+Warning
+Danger
+Light
+Dark
+Accent
+
+
+Left
+Middle
+Right
+
+
+
+
Badges & Alerts
+
+Primary
+Secondary
+Success
+Warning
+Danger
+Accent
+
+
+Primary: Vivamus sagittis lacus vel augue.
+
+
+Cras mattis consectetur purus sit amet fermentum.
+
+
+Brand alert — Aenean lacinia bibendum nulla sed consectetur.
+
+
+
+
Tables
+
+
+# Name Status Notes
+
+1 Alpha Active Lorem ipsum dolor sit amet.
+2 Beta Pending Integer posuere erat a ante.
+3 Gamma Blocked Donec id elit non mi porta.
+
+
+
+
+
+
Branded Forms
+
+
+
+
Input Group
+
+@
+
+Search
+
+
+
Submit
+
+
+
+
Branded Cards & List Groups
+
+
+
+
Featured
+
+
Card title
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.
+
Go somewhere
+
+
+
+
+
+
Active item
+
Second item
+
With badge 4
+
+
+
+
+
+
Breadcrumb & Pagination
+
+
+Home /
+Library /
+Data
+
+
+
+
+
+
+
+
Progress Bars
+
+
+
+
CSS Variable Swatches (Computed)
+
Visual preview of key variables with their resolved values displayed via JavaScript.
+
+
+
+
+
+
+
--accent-color-primary
+
+
+
+
--accent-color-secondary
+
+
+
+
+
+
+
+
+
+ MokoOnyx Theme Test Sheet — v03.09.02 — © 2026 Moko Consulting
+
+
+
+
+
+
+
diff --git a/templates/README.md b/templates/README.md
new file mode 100644
index 0000000..93490f0
--- /dev/null
+++ b/templates/README.md
@@ -0,0 +1,117 @@
+
+
+# MokoOnyx Templates Directory
+
+This directory contains template files for custom color schemes that can be copied to your template installation.
+
+## Custom Theme Palette Templates
+
+Template files are provided for both light and dark themes with complete Bootstrap button definitions:
+
+### Available Templates
+
+| File | Theme | Description |
+|------|-------|-------------|
+| `light.custom.css` | Light | Custom light theme with all Bootstrap button variants |
+| `dark.custom.css` | Dark | Custom dark theme with all Bootstrap button variants |
+
+### Using Custom Theme Templates
+
+1. **Copy** the template file to your template's CSS theme directory:
+ ```bash
+ # For light theme
+ cp templates/light.custom.css src/media/css/theme/light.custom.css
+
+ # For dark theme
+ cp templates/dark.custom.css src/media/css/theme/dark.custom.css
+ ```
+
+2. **Customize** the CSS variables in your copied file:
+ - Modify `--color-primary`, `--accent-color-primary`, etc. to match your brand
+ - Adjust Bootstrap state colors (`--success`, `--info`, `--warning`, `--danger`)
+ - Update button variants if needed
+
+3. **Register** in `src/joomla.asset.json`:
+ - Ensure `template.light.custom` and `template.dark.custom` assets are defined
+ - Already configured by default in the asset manifest
+
+4. **Activate** via Joomla admin:
+ - Go to System → Site Templates → MokoOnyx
+ - Select "Custom" in the Theme Palette dropdown
+ - Save and check your site
+
+### Bootstrap Button Variants Included
+
+All template files include complete definitions for:
+
+**Solid Buttons:**
+- `.btn-primary`, `.btn-secondary`, `.btn-success`, `.btn-info`, `.btn-warning`, `.btn-danger`, `.btn-light`, `.btn-dark`
+
+**Outline Buttons:**
+- `.btn-outline-primary`, `.btn-outline-secondary`, `.btn-outline-success`, `.btn-outline-info`, `.btn-outline-warning`, `.btn-outline-danger`, `.btn-outline-light`, `.btn-outline-dark`
+
+Each button variant includes hover, active, focus, and disabled states using CSS variables.
+
+## Theme System Features
+
+### CSS Variable Structure
+
+Colors are defined as CSS variables allowing easy customization:
+
+```css
+:root[data-bs-theme="light"] {
+ --color-primary: #0066cc;
+ --accent-color-primary: #3399ff;
+ --success: #28a745;
+ --danger: #dc3545;
+ /* ...and many more */
+}
+```
+
+### Opacity Utilities
+
+Template includes opacity utility variables for creating translucent colors:
+
+```css
+--opacity-5: 0.05;
+--opacity-10: 0.1;
+--opacity-15: 0.15;
+--opacity-25: 0.25;
+--opacity-50: 0.5;
+--opacity-75: 0.75;
+--opacity-100: 1;
+```
+
+Use with rgba():
+```css
+background-color: rgba(var(--black-rgb), var(--opacity-10));
+```
+
+### Shadow Color Utilities
+
+Pre-defined shadow color variables:
+
+```css
+--shadow-color-light: rgba(var(--black-rgb), var(--opacity-15));
+--shadow-color-medium: rgba(var(--black-rgb), var(--opacity-25));
+--shadow-color-dark: rgba(var(--black-rgb), var(--opacity-30));
+```
+
+---
+
+## 📚 Additional Resources
+
+- **[Main README](../README.md)** - MokoOnyx features and installation
+- **[CSS Variables Reference](../docs/CSS_VARIABLES.md)** - All available CSS variables
+- **[Development Guide](../docs/JOOMLA_DEVELOPMENT.md)** - Development workflows
+
+---
+
+**Template Directory**: `/templates/`
+**Version**: 03.08.04
+**Maintained by**: Moko Consulting
diff --git a/templates/configs/pa11yci.json b/templates/configs/pa11yci.json
new file mode 100644
index 0000000..c08219a
--- /dev/null
+++ b/templates/configs/pa11yci.json
@@ -0,0 +1,22 @@
+{
+ "defaults": {
+ "standard": "WCAG2AA",
+ "timeout": 30000,
+ "wait": 1000,
+ "ignore": [],
+ "chromeLaunchConfig": {
+ "args": [
+ "--no-sandbox",
+ "--disable-setuid-sandbox"
+ ]
+ }
+ },
+ "urls": [
+ {
+ "url": "http://localhost:8080/",
+ "actions": []
+ }
+ ],
+ "concurrency": 2,
+ "useIncognitoBrowserContext": true
+}
\ No newline at end of file
diff --git a/tests/_data/.gitkeep b/tests/_data/.gitkeep
new file mode 100644
index 0000000..9061987
--- /dev/null
+++ b/tests/_data/.gitkeep
@@ -0,0 +1,5 @@
+# Test Data Directory
+
+This directory contains test data files such as database dumps and fixtures.
+
+Add your test data files here as needed.
diff --git a/tests/_support/AcceptanceHelper.php b/tests/_support/AcceptanceHelper.php
new file mode 100644
index 0000000..b031743
--- /dev/null
+++ b/tests/_support/AcceptanceHelper.php
@@ -0,0 +1,15 @@
+wantTo('verify template files are present');
+
+ // This is a placeholder test
+ // Actual tests should be implemented based on your Joomla installation
+ $I->assertTrue(true, 'Template structure test placeholder');
+ }
+}
diff --git a/tests/unit.suite.yml b/tests/unit.suite.yml
new file mode 100644
index 0000000..62d9f36
--- /dev/null
+++ b/tests/unit.suite.yml
@@ -0,0 +1,8 @@
+# Codeception Test Suite Configuration
+
+actor: UnitTester
+modules:
+ enabled:
+ - Asserts
+ - \Tests\Support\UnitHelper
+step_decorators: ~
diff --git a/tests/unit/TemplateConfigurationTest.php b/tests/unit/TemplateConfigurationTest.php
new file mode 100644
index 0000000..44b23b4
--- /dev/null
+++ b/tests/unit/TemplateConfigurationTest.php
@@ -0,0 +1,66 @@
+assertFileExists(
+ $manifestPath,
+ 'Template manifest file should exist'
+ );
+ }
+
+ /**
+ * Test that manifest is valid XML
+ */
+ public function testManifestIsValidXml()
+ {
+ $manifestPath = __DIR__ . '/../../src/templates/templateDetails.xml';
+
+ if (!file_exists($manifestPath)) {
+ $this->markTestSkipped('Manifest file not found');
+ }
+
+ $xml = @simplexml_load_file($manifestPath);
+
+ $this->assertNotFalse(
+ $xml,
+ 'Template manifest should be valid XML'
+ );
+ }
+
+ /**
+ * Test that template has required fields in manifest
+ */
+ public function testManifestHasRequiredFields()
+ {
+ $manifestPath = __DIR__ . '/../../src/templates/templateDetails.xml';
+
+ if (!file_exists($manifestPath)) {
+ $this->markTestSkipped('Manifest file not found');
+ }
+
+ $xml = simplexml_load_file($manifestPath);
+
+ // Check for required elements
+ $this->assertNotEmpty((string)$xml->name, 'Template should have a name');
+ $this->assertNotEmpty((string)$xml->version, 'Template should have a version');
+ $this->assertNotEmpty((string)$xml->author, 'Template should have an author');
+ }
+}
diff --git a/updates.xml b/updates.xml
new file mode 100644
index 0000000..2ff825a
--- /dev/null
+++ b/updates.xml
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
+ MokoOnyx
+ MokoOnyx development build — unstable.
+ mokoonyx
+ template
+ site
+ 01.00.00
+ 2026-04-19
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/tag/development
+
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/development/mokoonyx-01.00.00-dev.zip
+
+
+ development
+ Moko Consulting
+ https://mokoconsulting.tech
+
+ 8.1
+
+
+
+
+ MokoOnyx
+ MokoOnyx alpha build — early testing.
+ mokoonyx
+ template
+ site
+ 01.00.00
+ 2026-04-19
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/tag/alpha
+
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/alpha/mokoonyx-01.00.00-alpha.zip
+
+
+ alpha
+ Moko Consulting
+ https://mokoconsulting.tech
+
+ 8.1
+
+
+
+
+ MokoOnyx
+ MokoOnyx beta build — feature complete, stability testing.
+ mokoonyx
+ template
+ site
+ 01.00.00
+ 2026-04-19
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/tag/beta
+
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/beta/mokoonyx-01.00.00-beta.zip
+
+
+ beta
+ Moko Consulting
+ https://mokoconsulting.tech
+
+ 8.1
+
+
+
+
+ MokoOnyx
+ MokoOnyx release candidate — testing only.
+ mokoonyx
+ template
+ site
+ 01.00.00
+ 2026-04-19
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/tag/release-candidate
+
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/release-candidate/mokoonyx-01.00.00-rc.zip
+ https://github.com/mokoconsulting-tech/MokoOnyx/releases/download/release-candidate/mokoonyx-01.00.00-rc.zip
+
+
+ rc
+ Moko Consulting
+ https://mokoconsulting.tech
+
+ 8.1
+
+
+
+
+ MokoOnyx
+ MokoOnyx — Moko Consulting's site template.
+ mokoonyx
+ template
+ site
+ 01.00.00
+ 2026-04-19
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/tag/v01
+
+ https://git.mokoconsulting.tech/MokoConsulting/MokoOnyx/releases/download/v01/mokoonyx-01.00.00.zip
+ https://github.com/mokoconsulting-tech/MokoOnyx/releases/download/v01/mokoonyx-01.00.00.zip
+
+
+ stable
+ Moko Consulting
+ https://mokoconsulting.tech
+
+ 8.1
+
+
+