This commit is contained in:
2026-11-14 16:42:38 -08:00
parent 285f3d512e
commit 65bf9409d9
7 changed files with 199 additions and 343 deletions

134
home.txt
View File

@@ -23,7 +23,8 @@
box-sizing: border-box;
}
.header-video {
.header-video,
.header-image {
position: absolute;
inset: 0;
width: 100%;
@@ -32,6 +33,9 @@
background-size: cover;
background-repeat: no-repeat;
z-index: 0;
margin-top: 130px !important;
border-top-left-radius: 50px !important;
border-top-right-radius: 50px !important;
will-change: transform, opacity;
backface-visibility: hidden;
transform-origin: center top;
@@ -87,70 +91,31 @@
gap: 10px;
}
.btn-primary,
.btn-secondary {
position: relative;
.btn-primary {
display: inline-flex;
align-items: center;
justify-content: center;
overflow: hidden;
gap: 6px;
padding: 10px 22px;
border-radius: 100px;
background: var(--btn-primary-bg);
color: var(--btn-primary-text) !important;
font-size: 13.5px;
font-weight: 600;
text-decoration: none !important;
transition: transform 0.2s ease, opacity 0.26s ease-out;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1) !important;
}
.btn-primary {
color: light-dark(#000000, #ffffff) !important;
transition: transform 0.15s ease;
}
.btn-secondary {
color: var(--text) !important;
}
.glass-surface__filter {
width: 100%;
height: 100%;
pointer-events: none;
position: absolute;
inset: 0;
opacity: 0;
z-index: -1;
}
.glass-surface__content {
width: 100%;
height: 100%;
display: flex;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
padding: 10px 22px;
border-radius: inherit;
position: relative;
z-index: 1;
padding: 10px 20px;
border-radius: 100px;
font-size: 13.5px;
font-weight: 600;
}
.btn-secondary .glass-surface__content {
padding: 10px 20px;
}
.glass-surface--svg {
background: transparent !important;
border: none !important;
box-shadow: none;
backdrop-filter: var(--filter-id, url(#glass-filter)) saturate(var(--glass-saturation, 1)) !important;
-webkit-backdrop-filter: var(--filter-id, url(#glass-filter)) saturate(var(--glass-saturation, 1)) !important;
}
.glass-surface--fallback {
background: transparent!important;
-webkit-backdrop-filter: blur(12px);
backdrop-filter: blur(12px);
border: transparent !important;
box-shadow: none;
text-decoration: none !important;
backdrop-filter: blur(25px) saturate(2);
-webkit-backdrop-filter: blur(25px) saturate(2);
transition: transform 0.15s ease;
}
@keyframes fadeVideoBg {
@@ -173,11 +138,24 @@
will-change: opacity;
}
.body-blurred-video {
.body-blurred-video,
.body-blurred-image {
width: 100%;
height: 100%;
object-fit: cover;
filter: blur(25px);
display: block;
}
.body-blurred-video:not([src]),
.body-blurred-video[src=""],
.body-blurred-image:not([src]),
.body-blurred-image[src=""],
.header-video:not([src]),
.header-video[src=""],
.header-image:not([src]),
.header-image[src=""] {
display: none;
}
.content-section {
@@ -236,20 +214,6 @@
transition: border-color 0.2s ease, transform 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}
.feature-box .glass-surface__content {
flex-direction: column;
align-items: stretch;
justify-content: flex-start;
gap: 0;
padding: 24px;
}
.feature-box.glass-surface--svg,
.feature-box.glass-surface--fallback {
background: transparent !important;
border: none !important;
}
.feature-box::after {
content: "";
position: absolute;
@@ -328,20 +292,13 @@
letter-spacing: 0.01em;
}
.hero-greeting .glass-surface__content {
padding: 6px 16px;
font-size: 13px;
font-weight: 600;
letter-spacing: 0.01em;
}
.hero-resume {
width: min(100vw, 200px);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
color: var(--text);
margin-top: 30px;
text-align: center;
}
@media (max-width: 900px) {
@@ -350,6 +307,16 @@
top: max(6px, env(safe-area-inset-top));
width: 90%;
}
.header-video,
.header-image {
margin-top: 80px !important;
border-top-left-radius: 55px !important;
border-top-right-radius: 55px !important;
width: 97% !important;
margin-left: auto !important;
margin-right: auto !important;
}
}
@media (orientation: landscape) and (max-height: 550px) {
@@ -385,11 +352,6 @@
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 12px;
}
.feature-box,
.feature-box .glass-surface__content {
padding: 18px;
}
}
</style>
@@ -397,6 +359,7 @@
<div class="body-blurred-backdrop">
<video class="body-blurred-video" autoplay muted loop playsinline
src=""></video>
<img class="body-blurred-image" alt="" />
</div>
<link rel="preload" href="" as="video" type="video/mp4"
@@ -405,6 +368,7 @@
<header class="home-header">
<video class="header-video" autoplay muted loop playsinline preload="auto"
src=""></video>
<img class="header-image" alt="" />
<div class="header-tint"></div>
@@ -416,9 +380,9 @@
<p class="header-desc">A community-built media project focused on freedom, privacy, and giving people
control over their own experience.</p>
<div class="header-actions">
<div class="header-actions">
<div class="header-actions-row">
<a href="/start-here/introduction" class="btn-secondary">
<a href="/start-here/introduction" class="btn-primary">
Get Started
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">

View File

@@ -183,7 +183,6 @@
</aside>
</div>
</div>
<script src="/src/js/glass.js"></script>
<script src="/src/js/main.js"></script>
<script src="/src/js/api/contribute.js"></script>
<script src="/src/js/api/donations.js"></script>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 MiB

View File

@@ -220,6 +220,56 @@ main.prose blockquote p {
width: 75%;
}
.theme-ambient {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 520px;
z-index: -1;
pointer-events: none;
overflow: hidden;
opacity: 0;
}
.theme-ambient.is-in {
animation: themeAmbientIn 1s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.theme-ambient-media {
position: absolute;
inset: -12% 0;
width: 100%;
height: 124%;
object-fit: cover;
filter: blur(70px) saturate(1.4) brightness(0.8);
transform: scale(1.15);
-webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 85%);
mask-image: linear-gradient(to bottom, #000 0%, transparent 85%);
}
@keyframes themeAmbientIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.theme-ambient.is-in {
animation: none;
opacity: 1;
}
}
body.is-home .theme-ambient,
body.is-404 .theme-ambient {
display: none;
}
.content-animate>* {
animation: smoothBlurReveal 0.44s cubic-bezier(0.22, 1, 0.36, 1) both;
will-change: filter, opacity, transform;

View File

@@ -375,12 +375,10 @@
align-items: center;
gap: 3px;
z-index: 2003;
background: var(--bg-menu);
border-radius: 100px;
padding: 3px 6px;
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
backdrop-filter: blur(16px) saturate(5);
-webkit-backdrop-filter: blur(16px) saturate(5);
opacity: 0;
transform: translateY(-8px) scale(0.96);
transition: opacity 0.3s cubic-bezier(0.16, 1, 0.3, 1) 0.08s,

View File

@@ -1,133 +0,0 @@
var GLASS_TARGETS = [
{
selector: ".btn-primary",
options: {
distortionScale: -300,
displace: 0,
backgroundOpacity: 0.1
}
},
{
selector: ".btn-secondary",
options: {
distortionScale: -300,
displace: 0,
backgroundOpacity: 0.1
}
},
{
selector: ".hero-greeting",
options: {
distortionScale: -200,
displace: 0,
backgroundOpacity: 0.08
}
},
{
selector: ".feature-box",
options: {
distortionScale: -220,
displace: 0,
backgroundOpacity: 0.12,
saturation: 1.3,
cornerRadius: 30
}
}
];
function initGlassSurface(el, opts) {
if (!el || el.getAttribute("data-glass")) return;
el.setAttribute("data-glass", "true");
opts = opts || {};
var distortionScale = opts.distortionScale !== undefined ? opts.distortionScale : -180;
var displace = opts.displace !== undefined ? opts.displace : 0;
var backgroundOpacity = opts.backgroundOpacity !== undefined ? opts.backgroundOpacity : 0;
var saturation = opts.saturation !== undefined ? opts.saturation : 1;
var redOffset = opts.redOffset !== undefined ? opts.redOffset : 0;
var greenOffset = opts.greenOffset !== undefined ? opts.greenOffset : 10;
var blueOffset = opts.blueOffset !== undefined ? opts.blueOffset : 20;
var borderWidth = opts.borderWidth !== undefined ? opts.borderWidth : 0.07;
var brightness = opts.brightness !== undefined ? opts.brightness : 50;
var opacity = opts.opacity !== undefined ? opts.opacity : 0.93;
var blur = opts.blur !== undefined ? opts.blur : 11;
var mixBlendMode = opts.mixBlendMode || "difference";
var uid = Math.random().toString(36).slice(2, 9);
var filterId = "glass-filter-" + uid;
var redGradId = "red-grad-" + uid;
var blueGradId = "blue-grad-" + uid;
var softId = "soft-" + uid;
var isWebkit = /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
var isFirefox = /Firefox/.test(navigator.userAgent);
var div = document.createElement("div");
div.style.backdropFilter = "url(#" + filterId + ")";
var svgSupported = !isWebkit && !isFirefox && div.style.backdropFilter !== "";
var rect = el.getBoundingClientRect();
var w = Math.round(rect.width) || 160;
var h = Math.round(rect.height) || 40;
var r = opts.cornerRadius !== undefined ? opts.cornerRadius : Math.round(h / 2);
var edge = Math.min(w, h) * (borderWidth * 0.5);
var mapSvg = '<svg width="' + w + '" height="' + h + '" viewBox="0 0 ' + w + ' ' + h + '" xmlns="http://www.w3.org/2000/svg">' +
'<defs>' +
'<linearGradient id="' + redGradId + '" x1="100%" y1="0%" x2="0%" y2="0%"><stop offset="0%" stop-color="#0000"/><stop offset="100%" stop-color="red"/></linearGradient>' +
'<linearGradient id="' + blueGradId + '" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" stop-color="#0000"/><stop offset="100%" stop-color="blue"/></linearGradient>' +
'<filter id="' + softId + '" filterUnits="userSpaceOnUse" x="0" y="0" width="' + w + '" height="' + h + '" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="' + blur + '"/></filter>' +
'</defs>' +
'<rect x="0" y="0" width="' + w + '" height="' + h + '" fill="black"/>' +
'<rect x="0" y="0" width="' + w + '" height="' + h + '" rx="' + r + '" fill="url(#' + redGradId + ')"/>' +
'<rect x="0" y="0" width="' + w + '" height="' + h + '" rx="' + r + '" fill="url(#' + blueGradId + ')" style="mix-blend-mode:' + mixBlendMode + '"/>' +
'<rect x="' + edge + '" y="' + edge + '" width="' + (w - edge * 2) + '" height="' + (h - edge * 2) + '" rx="' + r + '" fill="hsl(0 0% ' + brightness + '% / ' + opacity + ')" filter="url(#' + softId + ')"/>' +
'</svg>';
var mapUrl = "data:image/svg+xml," + encodeURIComponent(mapSvg);
el.style.setProperty("--glass-frost", backgroundOpacity);
el.style.setProperty("--glass-saturation", saturation);
el.style.setProperty("--filter-id", "url(#" + filterId + ")");
el.classList.add(svgSupported ? "glass-surface--svg" : "glass-surface--fallback");
var filterSvg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
filterSvg.setAttribute("class", "glass-surface__filter");
filterSvg.innerHTML = '<defs>' +
'<filter id="' + filterId + '" color-interpolation-filters="sRGB" x="0%" y="0%" width="100%" height="100%">' +
'<feImage href="' + mapUrl + '" x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" result="map"/>' +
'<feDisplacementMap in="SourceGraphic" in2="map" scale="' + (distortionScale + redOffset) + '" xChannelSelector="R" yChannelSelector="G" result="dispRed"/>' +
'<feColorMatrix in="dispRed" type="matrix" values="1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" result="red"/>' +
'<feDisplacementMap in="SourceGraphic" in2="map" scale="' + (distortionScale + greenOffset) + '" xChannelSelector="R" yChannelSelector="G" result="dispGreen"/>' +
'<feColorMatrix in="dispGreen" type="matrix" values="0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0" result="green"/>' +
'<feDisplacementMap in="SourceGraphic" in2="map" scale="' + (distortionScale + blueOffset) + '" xChannelSelector="R" yChannelSelector="G" result="dispBlue"/>' +
'<feColorMatrix in="dispBlue" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0" result="blue"/>' +
'<feBlend in="red" in2="green" mode="screen" result="rg"/>' +
'<feBlend in="rg" in2="blue" mode="screen" result="output"/>' +
'<feGaussianBlur in="output" stdDeviation="' + (displace || 0.7) + '"/>' +
'</filter></defs>';
var childNodes = Array.prototype.slice.call(el.childNodes);
var wrap = document.createElement("div");
wrap.className = "glass-surface__content";
childNodes.forEach(function (n) { wrap.appendChild(n); });
el.appendChild(filterSvg);
if (!svgSupported) {
var sheen = document.createElement("span");
sheen.className = "glass-surface__sheen";
sheen.setAttribute("aria-hidden", "true");
var rim = document.createElement("span");
rim.className = "glass-surface__rim";
rim.setAttribute("aria-hidden", "true");
el.appendChild(sheen);
el.appendChild(rim);
}
el.appendChild(wrap);
}
function applyGlassSurfaces(root) {
var base = root || document;
GLASS_TARGETS.forEach(function (target) {
base.querySelectorAll(target.selector).forEach(function (el) {
initGlassSurface(el, target.options);
});
});
}

View File

@@ -39,15 +39,15 @@ var THEMES_GENERAL = [
{ id: "cyberpunk", label: "Cyberpunk" }
];
var THEME_VIDEOS = {
dark: "https://www.pexels.com/download/video/39880903/",
light: "https://www.pexels.com/download/video/36600568/",
midnight: "https://www.pexels.com/download/video/15860507/",
nord: "https://www.pexels.com/download/video/31468607/",
dracula: "https://www.pexels.com/download/video/8116002/",
forest: "https://www.pexels.com/download/video/11265968/",
sunset: "https://www.pexels.com/download/video/855437/",
cyberpunk: "https://www.pexels.com/download/video/32336464/"
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//"
};
var SITE_TREE = [
@@ -59,16 +59,16 @@ var SITE_TREE = [
{
title: "Start here",
items: [
{ title: "Introduction", file: "/start-here/introduction.md", path: "/start-here/introduction" },
{ 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" },
{ title: "Go", file: "/products/go.md", path: "/products/go" },
{ title: "TV", file: "/products/tv.md", path: "/products/tv" },
{ 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" }
]
},
@@ -88,10 +88,10 @@ var SITE_TREE = [
{
title: "Vyla SDK",
items: [
{ title: "SDK", file: "/sdk/vyla-sdk/index.md", path: "/sdk" },
{ 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" },
{ title: "Contributing", file: "/sdk/vyla-sdk/contributing.md", path: "/sdk/vyla-sdk/contributing" }
{ 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 }
]
}
]
@@ -111,7 +111,7 @@ var SITE_TREE = [
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" },
{ 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" }
]
},
@@ -160,33 +160,100 @@ function getThemeMode() {
return localStorage.getItem(THEME_KEY) || "auto";
}
function applyTheme() {
var mode = getThemeMode();
var theme = resolveTheme(mode);
document.documentElement.setAttribute("data-theme", theme);
var logo = document.getElementById("brand-logo");
if (logo) logo.src = theme === "light" ? "/src/assets/images/dark_logo.png" : "/src/assets/images/logo.png";
applyPreferences();
var targetSrc = THEME_VIDEOS[theme] || THEME_VIDEOS.halloween;
var targetSrc = THEME_MEDIA[theme] || THEME_MEDIA.dark;
var videosOff = getPref("video", "on") === "off";
document.querySelectorAll(".body-blurred-video, .header-video").forEach(function (v) {
if (videosOff) {
v.pause();
if (v.getAttribute("src")) {
v.removeAttribute("src");
v.load();
var isImageSource = /\.(jpe?g|png|gif|webp|avif|svg)(\?.*)?$/i.test(targetSrc || "");
document.querySelectorAll(".body-blurred-video, .header-video, .body-blurred-image, .header-image").forEach(function (element) {
var isVideo = element.tagName === "VIDEO";
var isImage = element.tagName === "IMG";
if ((isVideo && (videosOff || isImageSource)) || (isImage && !isImageSource)) {
if (isVideo) {
element.pause();
element.load();
}
element.removeAttribute("src");
return;
}
if (v.getAttribute("src") !== targetSrc) {
v.src = targetSrc;
v.load();
v.play().catch(function () { });
if (element.getAttribute("src") !== targetSrc) {
element.src = targetSrc;
if (isVideo) {
element.load();
element.play().catch(function () { });
}
}
});
updateThemeAmbient(targetSrc, isImageSource, videosOff);
applyThemeCopy(theme);
}
function updateThemeAmbient(src, isImage, videosOff) {
var el = document.getElementById("theme-ambient");
if (!el) {
el = document.createElement("div");
el.id = "theme-ambient";
el.className = "theme-ambient";
el.setAttribute("aria-hidden", "true");
document.body.appendChild(el);
}
var blocked = !src || (!isImage && videosOff);
el.hidden = blocked;
if (blocked) return;
var want = isImage ? "img" : "video";
var media = el.querySelector(".theme-ambient-media");
if (!media || media.tagName.toLowerCase() !== want) {
el.innerHTML = "";
media = document.createElement(want);
media.className = "theme-ambient-media";
if (isImage) {
media.alt = "";
} else {
media.muted = true;
media.loop = true;
media.autoplay = true;
media.playsInline = true;
media.setAttribute("muted", "");
media.setAttribute("playsinline", "");
}
el.appendChild(media);
}
if (media.getAttribute("src") !== src) {
media.src = src;
if (!isImage) {
media.load();
media.play().catch(function () { });
}
}
}
function revealThemeAmbient() {
var el = document.getElementById("theme-ambient");
if (!el || el.hidden) return;
el.classList.remove("is-in");
void el.offsetWidth;
el.classList.add("is-in");
}
function setTheme(mode) {
localStorage.setItem(THEME_KEY, mode);
applyTheme();
@@ -466,6 +533,7 @@ function detectPlatform() {
var ua = navigator.userAgent || "";
if (/Android.*(TV|AFT|BRAVIA|SHIELD)|AndroidTV|GoogleTV|SmartTV/i.test(ua)) return "tv";
if (/Android/i.test(ua)) return "android";
if (/iPhone|iPad|iPod/i.test(ua)) return "ios";
if (/Windows/i.test(ua)) return "windows";
if (/Mac OS X|Macintosh/i.test(ua)) return "mac";
if (/Linux|X11/i.test(ua)) return "linux";
@@ -1207,94 +1275,6 @@ function navigateTo(path) {
loadPage();
}
function initGlassSurface(el, opts) {
if (!el || el.getAttribute("data-glass")) return;
el.setAttribute("data-glass", "true");
opts = opts || {};
var distortionScale = opts.distortionScale !== undefined ? opts.distortionScale : -300;
var displace = opts.displace !== undefined ? opts.displace : 0;
var backgroundOpacity = opts.backgroundOpacity !== undefined ? opts.backgroundOpacity : 0.1;
var saturation = opts.saturation !== undefined ? opts.saturation : 1;
var redOffset = opts.redOffset !== undefined ? opts.redOffset : 0;
var greenOffset = opts.greenOffset !== undefined ? opts.greenOffset : 10;
var blueOffset = opts.blueOffset !== undefined ? opts.blueOffset : 20;
var borderWidth = opts.borderWidth !== undefined ? opts.borderWidth : 0.07;
var brightness = opts.brightness !== undefined ? opts.brightness : 50;
var opacity = opts.opacity !== undefined ? opts.opacity : 0.93;
var blur = opts.blur !== undefined ? opts.blur : 11;
var mixBlendMode = opts.mixBlendMode || "difference";
var uid = Math.random().toString(36).slice(2, 9);
var filterId = "glass-filter-" + uid;
var redGradId = "red-grad-" + uid;
var blueGradId = "blue-grad-" + uid;
var softId = "soft-" + uid;
var isWebkit = /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
var isFirefox = /Firefox/.test(navigator.userAgent);
var div = document.createElement("div");
div.style.backdropFilter = "url(#" + filterId + ")";
var svgSupported = !isWebkit && !isFirefox && div.style.backdropFilter !== "";
var rect = el.getBoundingClientRect();
var w = Math.round(rect.width) || 160;
var h = Math.round(rect.height) || 44;
var r = opts.cornerRadius !== undefined ? opts.cornerRadius : Math.round(h / 2);
var edge = Math.min(w, h) * (borderWidth * 0.5);
var mapSvg = '<svg width="' + w + '" height="' + h + '" viewBox="0 0 ' + w + ' ' + h + '" xmlns="http://www.w3.org/2000/svg">' +
'<defs>' +
'<linearGradient id="' + redGradId + '" x1="100%" y1="0%" x2="0%" y2="0%"><stop offset="0%" stop-color="#0000"/><stop offset="100%" stop-color="red"/></linearGradient>' +
'<linearGradient id="' + blueGradId + '" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" stop-color="#0000"/><stop offset="100%" stop-color="blue"/></linearGradient>' +
'<filter id="' + softId + '" filterUnits="userSpaceOnUse" x="0" y="0" width="' + w + '" height="' + h + '" color-interpolation-filters="sRGB"><feGaussianBlur stdDeviation="' + blur + '"/></filter>' +
'</defs>' +
'<rect x="0" y="0" width="' + w + '" height="' + h + '" fill="black"/>' +
'<rect x="0" y="0" width="' + w + '" height="' + h + '" rx="' + r + '" fill="url(#' + redGradId + ')"/>' +
'<rect x="0" y="0" width="' + w + '" height="' + h + '" rx="' + r + '" fill="url(#' + blueGradId + ')" style="mix-blend-mode:' + mixBlendMode + '"/>' +
'<rect x="' + edge + '" y="' + edge + '" width="' + (w - edge * 2) + '" height="' + (h - edge * 2) + '" rx="' + r + '" fill="hsl(0 0% ' + brightness + '% / ' + opacity + ')" filter="url(#' + softId + ')"/>' +
'</svg>';
var mapUrl = "data:image/svg+xml," + encodeURIComponent(mapSvg);
el.style.setProperty("--glass-frost", backgroundOpacity);
el.style.setProperty("--glass-saturation", saturation);
el.style.setProperty("--filter-id", "url(#" + filterId + ")");
el.classList.add(svgSupported ? "glass-surface--svg" : "glass-surface--fallback");
var filterSvg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
filterSvg.setAttribute("class", "glass-surface__filter");
filterSvg.innerHTML = '<defs>' +
'<filter id="' + filterId + '" color-interpolation-filters="sRGB" x="0%" y="0%" width="100%" height="100%">' +
'<feImage href="' + mapUrl + '" x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" result="map"/>' +
'<feDisplacementMap in="SourceGraphic" in2="map" scale="' + (distortionScale + redOffset) + '" xChannelSelector="R" yChannelSelector="G" result="dispRed"/>' +
'<feColorMatrix in="dispRed" type="matrix" values="1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" result="red"/>' +
'<feDisplacementMap in="SourceGraphic" in2="map" scale="' + (distortionScale + greenOffset) + '" xChannelSelector="R" yChannelSelector="G" result="dispGreen"/>' +
'<feColorMatrix in="dispGreen" type="matrix" values="0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0" result="green"/>' +
'<feDisplacementMap in="SourceGraphic" in2="map" scale="' + (distortionScale + blueOffset) + '" xChannelSelector="R" yChannelSelector="G" result="dispBlue"/>' +
'<feColorMatrix in="dispBlue" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0" result="blue"/>' +
'<feBlend in="red" in2="green" mode="screen" result="rg"/>' +
'<feBlend in="rg" in2="blue" mode="screen" result="output"/>' +
'<feGaussianBlur in="output" stdDeviation="' + (displace || 0.7) + '"/>' +
'</filter></defs>';
var childNodes = Array.prototype.slice.call(el.childNodes);
var wrap = document.createElement("div");
wrap.className = "glass-surface__content";
childNodes.forEach(function (n) { wrap.appendChild(n); });
el.appendChild(filterSvg);
if (!svgSupported) {
var sheen = document.createElement("span");
sheen.className = "glass-surface__sheen";
sheen.setAttribute("aria-hidden", "true");
var rim = document.createElement("span");
rim.className = "glass-surface__rim";
rim.setAttribute("aria-hidden", "true");
el.appendChild(sheen);
el.appendChild(rim);
}
el.appendChild(wrap);
}
function mountGreeting(root) {
var content = root.querySelector(".header-content");
var title = root.querySelector(".header-title");
@@ -1315,9 +1295,6 @@ function mountGreeting(root) {
resume.textContent = "Continue: " + (last.title || last.path);
actions.appendChild(resume);
}
if (typeof applyGlassSurfaces === "function") {
applyGlassSurfaces(root);
}
}
function loadPage() {
@@ -1421,7 +1398,7 @@ function loadPage() {
'<div class="skeleton-line skeleton-eyebrow"></div>' +
'<div class="skeleton-line skeleton-title"></div>' +
'<div class="skeleton-line skeleton-desc"></div>' +
'<div class="skeleton-media"></div>' +
(route.item.hasMedia ? '<div class="skeleton-media"></div>' : '') +
'<div class="skeleton-line skeleton-text w-90"></div>' +
'<div class="skeleton-line skeleton-text w-100"></div>' +
'<div class="skeleton-line skeleton-text w-75"></div>' +
@@ -1455,6 +1432,7 @@ function loadPage() {
contentEl.classList.remove("caught-up");
contentEl.classList.add("content-animate");
revealThemeAmbient();
var catchUpOnScroll = function () {
if (contentEl.classList.contains("content-animate")) {