huge rewrite

This commit is contained in:
2026-11-14 18:21:12 -08:00
parent f465d1ec0d
commit 2cec85a8f3
69 changed files with 11479 additions and 1576 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 901 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1016 KiB

After

Width:  |  Height:  |  Size: 762 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 441 KiB

After

Width:  |  Height:  |  Size: 356 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 698 KiB

After

Width:  |  Height:  |  Size: 291 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 MiB

After

Width:  |  Height:  |  Size: 882 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 MiB

After

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 KiB

3804
src/css/bundle.css Normal file

File diff suppressed because it is too large Load Diff

1
src/css/bundle.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -179,7 +179,7 @@
#main-wrap {
flex: 1;
min-width: 0;
max-width: 720px;
max-width: 1000px;
margin-top: 120px;
border-radius: 12px;
width: 100%;
@@ -206,7 +206,7 @@ footer#site-footer {
gap: 16px;
width: 100%;
min-height: 22px;
margin: 0 0 36px;
margin: 0 0 200px;
}
.footer-link {
@@ -231,11 +231,149 @@ footer#site-footer {
margin-left: auto;
}
.footer-grid {
display: grid;
grid-template-columns: 2fr 1fr 1fr 1fr;
gap: 36px;
padding-bottom: 36px;
border-bottom: 1px solid var(--footer-border);
margin-bottom: 28px;
}
.footer-brand-col {
display: flex;
flex-direction: column;
}
.footer-brand-link {
display: inline-flex;
align-items: center;
gap: 10px;
text-decoration: none;
color: var(--text);
margin-bottom: 12px;
}
.footer-brand-name {
font-size: 18px;
font-weight: 700;
letter-spacing: -0.02em;
}
.footer-brand-desc {
font-size: 13.5px;
line-height: 1.6;
color: var(--muted);
margin: 0 0 18px;
max-width: 320px;
}
.footer-col-title {
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--muted);
margin-bottom: 14px;
}
.footer-col-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 10px;
}
.footer-col-list a {
font-size: 13.5px;
color: var(--muted);
text-decoration: none;
transition: color 0.15s ease;
display: inline-block;
}
.footer-col-list a:hover {
color: var(--text);
}
.footer-bottom {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 20px;
width: 100%;
border-top: 1px solid var(--footer-border);
padding-top: 28px;
padding-left: 7px;
border-top: none;
padding: 0;
}
.footer-bottom-info p {
margin: 0;
font-size: 13px;
color: var(--muted);
}
.footer-bottom-info .footer-subtext {
margin-top: 4px;
font-size: 12px;
color: var(--muted);
}
.footer-badges {
display: flex;
align-items: center;
gap: 16px;
flex-wrap: wrap;
}
.footer-green-badge {
display: inline-block;
opacity: 0.85;
transition: opacity 0.2s ease;
}
.footer-green-badge:hover {
opacity: 1;
}
.footer-green-badge img {
display: block;
min-height: 100px;
width: auto;
border-radius: 6px;
}
@media (max-width: 900px) {
.footer-grid {
grid-template-columns: 1fr 1fr;
gap: 28px;
}
.footer-brand-col {
grid-column: span 2;
}
}
@media (max-width: 550px) {
.footer-grid {
grid-template-columns: 1fr;
gap: 24px;
}
.footer-brand-col {
grid-column: span 1;
}
.footer-card {
max-width: 100%;
}
.footer-bottom {
flex-direction: column;
align-items: flex-start;
}
}
.footer-socials {
@@ -246,8 +384,11 @@ footer#site-footer {
.footer-socials a {
display: flex;
align-items: center;
justify-content: center;
color: var(--muted);
transition: color 0.15s ease;
min-width: 36px;
min-height: 36px;
}
.footer-socials a:hover {
@@ -267,8 +408,10 @@ footer#site-footer {
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
width: 44px;
height: 44px;
min-width: 44px;
min-height: 44px;
border: none;
border-radius: 10px;
background: none;

View File

@@ -1,5 +1,4 @@
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap");
/* Google fonts loaded in head */
:root,
:root[data-theme="dark"] {
--bg: #000000;

View File

@@ -40,102 +40,256 @@ var THEMES_GENERAL = [
];
var THEME_MEDIA = {
dark: "/src/assets/images/wallpaper-media/tree.png",
light: "https://www.pexels.com/download/video//",
midnight: "https://www.pexels.com/download/video//",
nord: "https://www.pexels.com/download/video//",
dracula: "https://www.pexels.com/download/video//",
forest: "https://www.pexels.com/download/video//",
sunset: "https://www.pexels.com/download/video//",
cyberpunk: "https://www.pexels.com/download/video//"
dark: "/src/assets/images/wallpaper-media/tree.webp",
light: "/src/assets/images/wallpaper-media/tree.webp",
midnight: "/src/assets/images/wallpaper-media/tree.webp",
nord: "/src/assets/images/wallpaper-media/tree.webp",
dracula: "/src/assets/images/wallpaper-media/tree.webp",
forest: "/src/assets/images/wallpaper-media/tree.webp",
sunset: "/src/assets/images/wallpaper-media/tree.webp",
cyberpunk: "/src/assets/images/wallpaper-media/tree.webp"
};
var SITE_TREE = [
{
id: "vyla",
title: "Vyla",
path: "/start-here/introduction",
groups: [
"id": "vyla",
"title": "Ecosystem",
"path": "/start-here/introduction",
"groups": [
{
title: "Start here",
items: [
{ title: "Introduction", file: "/start-here/introduction.md", path: "/start-here/introduction", hasMedia: true },
{ title: "Architecture", file: "/start-here/architecture.md", path: "/start-here/architecture" }
"title": "Start here",
"items": [
{
"title": "Introduction",
"file": "/start-here/introduction.md",
"path": "/start-here/introduction",
"hasMedia": true
},
{
"title": "Architecture",
"file": "/start-here/architecture.md",
"path": "/start-here/architecture"
}
]
},
{
title: "Products",
items: [
{ title: "Home", file: "/products/home.md", path: "/products/home", hasMedia: true },
{ title: "Go", file: "/products/go.md", path: "/products/go", hasMedia: true },
{ title: "TV", file: "/products/tv.md", path: "/products/tv", hasMedia: true },
{ title: "Player", file: "/products/player.md", path: "/products/player" }
"title": "Products",
"items": [
{
"title": "Vyla Home",
"file": "/products/home.md",
"path": "/products/home",
"hasMedia": true
},
{
"title": "Vyla Go",
"file": "/products/go.md",
"path": "/products/go",
"hasMedia": true
},
{
"title": "Vyla TV",
"file": "/products/tv.md",
"path": "/products/tv",
"hasMedia": true
},
{
"title": "Build a Player",
"file": "/products/player.md",
"path": "/products/player"
}
]
},
{
title: "Concepts",
items: [
{ title: "Providers", file: "/concepts/providers.md", path: "/concepts/providers" }
"title": "Concepts",
"items": [
{
"title": "Providers",
"file": "/concepts/providers.md",
"path": "/concepts/providers"
}
]
}
]
},
{
id: "sdk",
title: "SDK",
path: "/sdk",
groups: [
"id": "sdk",
"title": "SDK",
"path": "/sdk",
"groups": [
{
title: "Vyla SDK",
items: [
{ title: "SDK", file: "/sdk/vyla-sdk/index.md", path: "/sdk", hasMedia: true },
{ title: "SDK Quickstart", file: "/sdk/vyla-sdk/quickstart.md", path: "/sdk/vyla-sdk/quickstart" },
{ title: "Manga", file: "/sdk/vyla-sdk/manga.md", path: "/sdk/vyla-sdk/manga", hasMedia: true },
{ title: "Contributing", file: "/sdk/vyla-sdk/contributing.md", path: "/sdk/vyla-sdk/contributing", hasMedia: true }
"title": "Getting Started",
"items": [
{
"title": "SDK Overview",
"file": "/sdk/vyla-sdk/index.md",
"path": "/sdk",
"hasMedia": true
},
{
"title": "SDK Quickstart",
"file": "/sdk/vyla-sdk/quickstart.md",
"path": "/sdk/vyla-sdk/quickstart"
}
]
},
{
"title": "Reference",
"items": [
{
"title": "API Reference",
"file": "/sdk/vyla-sdk/reference.md",
"path": "/sdk/vyla-sdk/reference"
},
{
"title": "Manga Module",
"file": "/sdk/vyla-sdk/manga.md",
"path": "/sdk/vyla-sdk/manga",
"hasMedia": true
}
]
},
{
"title": "Development",
"items": [
{
"title": "Contributing Sources",
"file": "/sdk/vyla-sdk/contributing.md",
"path": "/sdk/vyla-sdk/contributing",
"hasMedia": true
}
]
}
]
},
{
id: "stream-api",
title: "Stream API",
path: "/stream-api/overview",
groups: [
"id": "stream-api",
"title": "Stream API",
"path": "/stream-api/overview",
"groups": [
{
title: "Overview",
items: [
{ title: "Overview", file: "/stream-api/overview/index.md", path: "/stream-api/overview" }
"title": "Overview",
"items": [
{
"title": "Stream API Overview",
"file": "/stream-api/overview/index.md",
"path": "/stream-api/overview"
},
{
"title": "Authentication & Keys",
"file": "/stream-api/authentication/index.md",
"path": "/stream-api/authentication"
}
]
},
{
title: "Reference",
items: [
{ title: "Paths", file: "/stream-api/reference/paths.md", path: "/stream-api/reference/paths" },
{ title: "Media Data", file: "/stream-api/reference/media-data.md", path: "/stream-api/reference/media-data", hasMedia: true },
{ title: "Operations", file: "/stream-api/reference/operations.md", path: "/stream-api/reference/operations" }
"title": "Reference",
"items": [
{
"title": "Paths & Playback",
"file": "/stream-api/reference/paths.md",
"path": "/stream-api/reference/paths"
},
{
"title": "Media Data",
"file": "/stream-api/reference/media-data.md",
"path": "/stream-api/reference/media-data",
"hasMedia": true
},
{
"title": "Operations & Health",
"file": "/stream-api/reference/operations.md",
"path": "/stream-api/reference/operations"
}
]
},
{
title: "Deployment",
items: [
{ title: "Self Hosting", file: "/stream-api/deployment/self-hosting.md", path: "/stream-api/deployment/self-hosting" }
"title": "Deployment",
"items": [
{
"title": "Self Hosting",
"file": "/stream-api/deployment/self-hosting.md",
"path": "/stream-api/deployment/self-hosting"
}
]
}
]
},
{
id: "misc",
title: "Misc",
path: "/misc/project/credit",
groups: [
"id": "guides",
"title": "Guides",
"path": "/guides/integrations",
"groups": [
{
title: "Project",
items: [
{ title: "Story", file: "/misc/project/story.md", path: "/misc/project/story" },
{ title: "Changelog", file: "/misc/project/changelog.md", path: "/misc/project/changelog" },
{ title: "Credit", file: "/misc/project/credit.md", path: "/misc/project/credit" },
{ title: "Support Us", file: "/misc/project/support-us.md", path: "/misc/project/support-us" },
{ title: "DMCA", file: "/misc/project/DMCA.md", path: "/misc/project/DMCA" }
"title": "Player Guides",
"items": [
{
"title": "Client Integration",
"file": "/guides/integrations.md",
"path": "/guides/integrations"
},
{
"title": "Error Handling",
"file": "/guides/error-handling.md",
"path": "/guides/error-handling"
}
]
}
]
},
{
"id": "resources",
"title": "Resources",
"path": "/resources/faq",
"groups": [
{
"title": "Reference & Help",
"items": [
{
"title": "FAQ",
"file": "/resources/faq.md",
"path": "/resources/faq"
},
{
"title": "Troubleshooting",
"file": "/resources/troubleshooting.md",
"path": "/resources/troubleshooting"
},
{
"title": "Glossary",
"file": "/resources/glossary.md",
"path": "/resources/glossary"
}
]
},
{
"title": "Project",
"items": [
{
"title": "Project Story",
"file": "/misc/project/story.md",
"path": "/misc/project/story"
},
{
"title": "Changelog",
"file": "/misc/project/changelog.md",
"path": "/misc/project/changelog"
},
{
"title": "Credits",
"file": "/misc/project/credit.md",
"path": "/misc/project/credit"
},
{
"title": "Support Us",
"file": "/misc/project/support-us.md",
"path": "/misc/project/support-us"
},
{
"title": "DMCA Policy",
"file": "/misc/project/DMCA.md",
"path": "/misc/project/dmca"
}
]
}
]
@@ -173,6 +327,9 @@ function applyTheme() {
var targetSrc = THEME_MEDIA[theme] || THEME_MEDIA.dark;
if (typeof window !== "undefined" && window.innerWidth <= 768 && targetSrc && targetSrc.indexOf("tree.webp") !== -1) {
targetSrc = "/src/assets/images/wallpaper-media/tree-mobile.webp";
}
var videosOff = getPref("video", "on") === "off";
var isImageSource = /\.(jpe?g|png|gif|webp|avif|svg)(\?.*)?$/i.test(targetSrc || "");
@@ -226,6 +383,9 @@ function updateThemeAmbient(src, isImage, videosOff) {
media.className = "theme-ambient-media";
if (isImage) {
media.alt = "";
media.setAttribute("width", "1920");
media.setAttribute("height", "1080");
media.setAttribute("aria-hidden", "true");
} else {
media.muted = true;
media.loop = true;
@@ -1297,6 +1457,119 @@ function mountGreeting(root) {
}
}
function updatePageSEO(route, mdContent) {
var isHome = !route || !route.item || route.item.path === "/";
var canonicalLink = document.querySelector('link[rel="canonical"]');
var metaDesc = document.querySelector('meta[name="description"]');
var ogTitle = document.querySelector('meta[property="og:title"]');
var ogDesc = document.querySelector('meta[property="og:description"]');
var ogUrl = document.querySelector('meta[property="og:url"]');
var twTitle = document.querySelector('meta[name="twitter:title"]');
var twDesc = document.querySelector('meta[name="twitter:description"]');
if (isHome) {
var homeTitle = "Vyla Entertainment - Free & Decentralized Media Platform";
var homeDesc = "Vyla Entertainment is a community-built, decentralized media platform and developer ecosystem. Featuring native client apps for Desktop, Mobile, and Android TV, a scraping SDK, and a self-hosted Stream API.";
var homeUrl = "https://vyla.cc/";
document.title = homeTitle;
if (canonicalLink) canonicalLink.setAttribute("href", homeUrl);
if (metaDesc) metaDesc.setAttribute("content", homeDesc);
if (ogTitle) ogTitle.setAttribute("content", homeTitle);
if (ogDesc) ogDesc.setAttribute("content", homeDesc);
if (ogUrl) ogUrl.setAttribute("content", homeUrl);
if (twTitle) twTitle.setAttribute("content", homeTitle);
if (twDesc) twDesc.setAttribute("content", homeDesc);
var dynJson = document.getElementById("dynamic-jsonld");
if (dynJson) dynJson.remove();
return;
}
var pageTitle = route.item.title + " - Vyla Docs";
document.title = pageTitle;
var pageUrl = "https://vyla.cc" + route.item.path;
if (canonicalLink) canonicalLink.setAttribute("href", pageUrl);
if (ogUrl) ogUrl.setAttribute("content", pageUrl);
if (ogTitle) ogTitle.setAttribute("content", pageTitle);
if (twTitle) twTitle.setAttribute("content", pageTitle);
var desc = "";
if (mdContent) {
var descMatch = mdContent.match(/<p class="page-description">([\s\S]*?)<\/p>/i);
if (descMatch) {
desc = descMatch[1].replace(/<[^>]+>/g, "").trim();
} else {
var pMatch = mdContent.match(/^(?:#+[^\n]*\n+)+([^\n#<][^\n]+)/m);
if (pMatch) {
desc = pMatch[1].replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").trim();
}
}
}
if (!desc) {
desc = route.item.title + " guide and developer documentation for the Vyla Ecosystem.";
}
if (metaDesc) metaDesc.setAttribute("content", desc);
if (ogDesc) ogDesc.setAttribute("content", desc);
if (twDesc) twDesc.setAttribute("content", desc);
var dynScript = document.getElementById("dynamic-jsonld");
if (!dynScript) {
dynScript = document.createElement("script");
dynScript.id = "dynamic-jsonld";
dynScript.type = "application/ld+json";
document.head.appendChild(dynScript);
}
var graph = [
{
"@type": "TechArticle",
"@id": pageUrl + "#article",
"url": pageUrl,
"headline": route.item.title,
"description": desc,
"inLanguage": "en-US",
"isPartOf": {
"@id": "https://vyla.cc/#website"
},
"publisher": {
"@id": "https://vyla.cc/#organization"
}
},
{
"@type": "BreadcrumbList",
"@id": pageUrl + "#breadcrumb",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://vyla.cc/"
},
{
"@type": "ListItem",
"position": 2,
"name": route.tab.title,
"item": "https://vyla.cc" + route.tab.path
},
{
"@type": "ListItem",
"position": 3,
"name": route.item.title,
"item": pageUrl
}
]
}
];
dynScript.textContent = JSON.stringify({
"@context": "https://schema.org",
"@graph": graph
});
}
function loadPage() {
var path = window.location.pathname.replace(/\/+$/, "") || "/";
var isHome = path === "/";
@@ -1305,26 +1578,31 @@ function loadPage() {
var contentEl = document.getElementById("main-content");
if (isHome) {
document.title = "Vyla Entertainment - Vyla";
updatePageSEO(null, null);
renderNavTabs(SITE_TREE[0]);
renderSidebar(SITE_TREE[0], { title: "Home", path: "/" });
if (contentEl) {
contentEl.classList.remove("content-animate", "caught-up");
fetch("/home.txt")
.then(function (res) {
if (!res.ok) throw new Error();
return res.text();
})
.then(function (html) {
contentEl.innerHTML = html;
mountGreeting(contentEl);
applyTheme();
window.scrollTo(0, 0);
})
.catch(function () {
contentEl.innerHTML = "<h1>Home</h1><p>Create /home.txt to customize this page.</p>";
});
if (contentEl.querySelector(".home-container")) {
mountGreeting(contentEl);
applyTheme();
} else {
contentEl.classList.remove("content-animate", "caught-up");
fetch("/home.txt")
.then(function (res) {
if (!res.ok) throw new Error();
return res.text();
})
.then(function (html) {
contentEl.innerHTML = html;
mountGreeting(contentEl);
applyTheme();
window.scrollTo(0, 0);
})
.catch(function () {
contentEl.innerHTML = "<h1>Home</h1><p>Create /home.txt to customize this page.</p>";
});
}
}
var tocList = document.getElementById("toc-list");
@@ -1346,19 +1624,8 @@ function loadPage() {
var route = resolveRoute(window.location.pathname);
renderNavTabs(route.tab);
renderSidebar(route.tab, route.item);
document.title = route.item.title + " - Vyla";
var contentEl = document.getElementById("main-content");
document.body.classList.remove("is-404");
var route = resolveRoute(window.location.pathname);
renderNavTabs(route.tab);
renderSidebar(route.tab, route.item);
document.title = route.item.title + " - Vyla";
var contentEl = document.getElementById("main-content");
if (route.is404) {
@@ -1414,6 +1681,7 @@ function loadPage() {
})
.then(function (md) {
if (contentEl) {
updatePageSEO(route, md);
var hasApiToken = md.indexOf("YOUR_API_URL") !== -1;
contentEl.innerHTML = parseMarkdown(personalize(md));
@@ -1629,7 +1897,10 @@ function onSearchKey(e) {
function buildSearch() {
var trigger = document.getElementById("search-trigger");
if (trigger) trigger.innerHTML = icon("search") + "<span>Search...</span><kbd>Ctrl K</kbd>";
if (trigger) {
trigger.innerHTML = icon("search") + "<span>Search...</span><kbd>Ctrl K</kbd>";
trigger.setAttribute("aria-label", "Search... (Ctrl+K)");
}
var modal = document.createElement("div");
modal.id = "search-modal";
modal.innerHTML =