/* dlstack — distilled
* Loads data/links.json and renders sections, cards, YouTube facades.
* No search, no filter, no clock, no theme toggle. The page is the index.
*/
(() => {
"use strict";
const $ = (s, el = document) => el.querySelector(s);
const $$ = (s, el = document) => Array.from(el.querySelectorAll(s));
const esc = (s) => String(s ?? "").replace(/[&<>"']/g, (c) => ({
"&": "&", "<": "<", ">": ">", '"': """, "'": "'"
}[c]));
const frag = (html) => document.createRange().createContextualFragment(html);
const hostOf = (url) => {
try { return new URL(url, location.href).hostname.replace(/^www\./, ""); }
catch { return ""; }
};
const faviconFor = (url) => {
const h = hostOf(url);
return h ? `https://www.google.com/s2/favicons?domain=${encodeURIComponent(h)}&sz=128` : "";
};
const ytThumb = (id) => `https://i.ytimg.com/vi/${encodeURIComponent(id)}/hqdefault.jpg`;
function renderLink(it) {
const host = hostOf(it.url);
const custom = it.image || it.icon;
const src = custom || faviconFor(it.url);
const isFavicon = !custom;
const initial = (it.title || host || "·").trim().charAt(0).toUpperCase();
return `
${src
? `
`
: esc(initial)}
${esc(it.title)}
${it.description ? `${esc(it.description)}` : ""}
${host ? `${esc(host)}` : ""}
${dateMarkup(it)}
`;
}
function renderProject(it) {
const featured = it.featured ? " card--featured" : "";
const tag = it.url ? "a" : "div";
const attrs = it.url ? `href="${esc(it.url)}" target="_blank" rel="noopener noreferrer"` : "";
const tags = (it.tags || []).map(t => `${esc(t)}`).join("");
return `
<${tag} class="card card--project${featured} reveal" ${attrs}>
${esc(it.title)}
${it.description ? `
${esc(it.description)}
` : ""}
${(tags || it.date) ? `${tags}${dateMarkup(it)}
` : ""}
${tag}>`;
}
function renderYouTube(it) {
return `
${esc(it.title)}${it.date ? ` ${esc(fmtDate(it.date))}` : ""}
`;
}
function renderPortfolio(it) {
const src = it.image || it.url;
const tag = it.url ? "a" : "div";
const attrs = it.url ? `href="${esc(it.url)}" target="_blank" rel="noopener noreferrer"` : "";
const ratio = it.ratio ? ` style="--portfolio-ratio:${esc(String(it.ratio).replace(":", " / "))}"` : "";
return `
<${tag} class="card card--portfolio reveal" ${attrs}>
${(it.title || it.description || it.date) ? `
${it.title ? `${esc(it.title)}` : ""}
${it.description ? `${esc(it.description)}` : ""}
${dateMarkup(it)}
` : ""}
${tag}>`;
}
function renderClient(it) {
const host = hostOf(it.url);
const custom = it.image || it.icon;
const src = custom || faviconFor(it.url);
const isFavicon = !custom;
const initial = (it.title || host || "·").trim().charAt(0).toUpperCase();
const tag = it.url ? "a" : "div";
const attrs = it.url ? `href="${esc(it.url)}" target="_blank" rel="noopener noreferrer"` : "";
return `
<${tag} class="card card--client reveal" ${attrs} title="${esc(it.title || host || "")}">
${src
? `
`
: esc(initial)}
${it.title ? `${esc(it.title)}` : ""}
${dateMarkup(it)}
${tag}>`;
}
function renderTestimonial(it) {
const tag = it.url ? "a" : "div";
const attrs = it.url ? `href="${esc(it.url)}" target="_blank" rel="noopener noreferrer"` : "";
const avatar = it.image || it.icon || (it.url ? faviconFor(it.url) : "");
const isFavicon = !(it.image || it.icon);
const initial = (it.name || it.org || "·").trim().charAt(0).toUpperCase();
const meta = [it.role, it.org].filter(Boolean).join(", ");
const len = [...String(it.quote || "")].length;
const lengthClass =
len <= 90 ? " is-xshort" :
len <= 180 ? " is-short" :
len <= 320 ? " is-medium" :
len <= 520 ? " is-long" :
" is-xlong";
return `
<${tag} class="card card--testimonial reveal${lengthClass}" ${attrs}>
“
${esc(it.quote)}
${avatar ? `
` : ""}
${it.name ? `${esc(it.name)}` : ""}
${meta ? `${esc(meta)}` : ""}
${dateMarkup(it)}
${tag}>`;
}
const renderItem = (it) =>
it.type === "youtube" ? renderYouTube(it) :
it.type === "card" ? renderProject(it) :
it.type === "client" ? renderClient(it) :
it.type === "portfolio" ? renderPortfolio(it) :
it.type === "testimonial" ? renderTestimonial(it) :
renderLink(it);
function renderSection(sec, n) {
const items = (sec.items || []).map(renderItem).join("");
const num = String(n).padStart(2, "0");
const isClients = sec.layout === "clients" || sec.items?.[0]?.type === "client";
const isTestimonials = sec.layout === "testimonials" || sec.items?.[0]?.type === "testimonial";
let body;
if (isTestimonials) {
const count = (sec.items || []).length;
body = `
${count > 1 ? `
` : ""}
${count > 1 ? `
` : ""}
`;
} else {
const gridClass = isClients ? "grid--clients" : "grid";
body = `${items}
`;
}
const headless = sec.headless === true;
const cls = `section${headless ? " section--headless" : ""}`;
const head = headless ? "" : `
`;
return `
`;
}
const SOCIAL_ICONS = {
github: '',
linkedin: '',
mail: '',
rss: '',
link: '',
calendar: '',
bluesky: '',
lastfm: ''
};
function renderSocial(items) {
return items.map(s =>
`${SOCIAL_ICONS[s.icon] || SOCIAL_ICONS.link}${esc(s.label)}`
).join("");
}
function nameMarkup(name) {
if (!name) return "";
const parts = String(name).trim().split(/\s+/);
if (parts.length < 2) return `${esc(name)}`;
const last = parts.pop();
return `${esc(parts.join(" "))} ${esc(last)}`;
}
function fmtDate(d) {
if (!d) return "";
const m = String(d).match(/^(\d{4})(?:-(\d{2}))?(?:-(\d{2}))?$/);
if (!m) return String(d);
const [, y, mo, dd] = m;
const months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
if (dd && mo) return `${months[+mo - 1]} ${+dd}, ${y}`;
if (mo) return `${months[+mo - 1]} ${y}`;
return y;
}
const dateMarkup = (it) =>
it.date ? `` : "";
function attachFaviconFallback(root) {
$$("img[data-fallback-initial]", root).forEach(img => {
img.addEventListener("error", () => {
const initial = img.dataset.fallbackInitial || "·";
const parent = img.parentElement;
if (parent) { parent.setAttribute("data-fallback", ""); parent.textContent = initial; }
}, { once: true });
});
}
function attachYouTube(root) {
const open = (fac) => {
const id = fac.dataset.yt;
if (!id) return;
const iframe = document.createElement("iframe");
iframe.src = `https://www.youtube-nocookie.com/embed/${encodeURIComponent(id)}?autoplay=1&rel=0&controls=1`;
iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share";
iframe.allowFullscreen = true;
iframe.title = fac.getAttribute("aria-label") || "YouTube video";
fac.replaceChildren(iframe);
fac.classList.add("yt--playing");
fac.removeAttribute("data-yt");
fac.removeAttribute("role");
fac.removeAttribute("tabindex");
fac.style.cursor = "default";
};
root.addEventListener("click", (e) => {
const fac = e.target.closest("[data-yt]");
if (fac) { e.preventDefault(); open(fac); }
});
root.addEventListener("keydown", (e) => {
if (e.key !== "Enter" && e.key !== " ") return;
const fac = e.target.closest("[data-yt]");
if (fac) { e.preventDefault(); open(fac); }
});
}
function attachTheme() {
const root = document.documentElement;
const btn = $("#theme");
if (!btn) return;
const order = ["auto", "light", "dark"];
const label = { auto: "Auto", light: "Light", dark: "Dark" };
const stored = localStorage.getItem("dlstack-theme");
if (!order.includes(root.dataset.theme)) root.dataset.theme = "auto";
if (order.includes(stored)) root.dataset.theme = stored;
const sync = () => {
btn.textContent = label[root.dataset.theme];
btn.setAttribute("aria-label", `Theme: ${label[root.dataset.theme]}. Click to change.`);
};
sync();
btn.addEventListener("click", () => {
const i = order.indexOf(root.dataset.theme);
root.dataset.theme = order[(i + 1) % order.length];
localStorage.setItem("dlstack-theme", root.dataset.theme);
sync();
});
}
function bootCosmos() {
const root = document.documentElement;
const reducedMotion = matchMedia("(prefers-reduced-motion: reduce)").matches;
if (reducedMotion) { root.classList.add("cosmos-static"); return; }
attachCosmosCursor();
attachCosmosComets();
attachCosmosParallax();
attachCosmosCardTilt();
const canvas = document.createElement("canvas");
canvas.className = "cosmos-bg";
canvas.setAttribute("aria-hidden", "true");
const gl = canvas.getContext("webgl", { antialias: false, alpha: false, premultipliedAlpha: false }) ||
canvas.getContext("experimental-webgl");
if (!gl) { root.classList.add("cosmos-static"); return; }
const vsSrc = `
attribute vec2 a;
void main() { gl_Position = vec4(a, 0.0, 1.0); }
`;
const fsSrc = `
precision highp float;
uniform vec2 u_res;
uniform float u_time;
uniform vec2 u_mouse;
uniform vec2 u_ripple_pos;
uniform float u_ripple_age;
float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); }
float noise(vec2 p) {
vec2 i = floor(p), f = fract(p);
vec2 u = f * f * (3.0 - 2.0 * f);
return mix(mix(hash(i), hash(i + vec2(1.0, 0.0)), u.x),
mix(hash(i + vec2(0.0, 1.0)), hash(i + vec2(1.0, 1.0)), u.x), u.y);
}
float fbm(vec2 p) {
float v = 0.0, a = 0.55;
for (int i = 0; i < 5; i++) {
v += a * noise(p);
p *= 2.04; a *= 0.5;
}
return v;
}
void main() {
vec2 frag = gl_FragCoord.xy;
vec2 uv = frag / u_res;
vec2 p = (frag - 0.5 * u_res) / u_res.y;
// gravity well: pull sampling toward cursor — stronger now
vec2 m = (u_mouse - 0.5 * u_res) / u_res.y;
vec2 toM = p - m;
float md = length(toM) + 0.001;
p -= (toM / md) * 0.06 * exp(-md * 1.2);
// click ripple — propagating ring of displacement and brightness
vec2 rp = (u_ripple_pos - 0.5 * u_res) / u_res.y;
float rd = length(p - rp);
float rt = u_ripple_age;
float ringR = rt * 1.4;
float ringW = 0.16 + rt * 0.05;
float ring = exp(-pow((rd - ringR) / ringW, 2.0)) * exp(-rt * 0.7);
p -= normalize(p - rp + vec2(0.0001)) * ring * 0.10;
// nebula via warped fbm
vec2 q = p * 1.25 + vec2(u_time * 0.015, u_time * 0.010);
vec2 r = q + vec2(fbm(q + u_time * 0.04), fbm(q - u_time * 0.03));
float n = fbm(r);
// palette: deep indigo -> magenta -> violet -> cyan ridges
vec3 deep = vec3(0.020, 0.012, 0.055);
vec3 violet = vec3(0.350, 0.150, 0.620);
vec3 magenta = vec3(0.950, 0.220, 0.700);
vec3 cyan = vec3(0.290, 0.940, 1.000);
vec3 col = deep;
col = mix(col, violet, smoothstep(0.25, 0.70, n));
col = mix(col, magenta, smoothstep(0.55, 0.92, n) * 0.85);
col += cyan * smoothstep(0.78, 0.98, n) * 0.45;
// ripple adds a luminous cyan ring
col += cyan * ring * 0.85;
col += vec3(1.0, 0.6, 0.95) * ring * 0.35;
// soft vignette
float vig = smoothstep(1.25, 0.30, length(p));
col *= mix(0.55, 1.05, vig);
// ───── starfield — two layers ─────
// layer 1 — small dense
float starDensity = 90.0;
vec2 sc = uv * starDensity * vec2(u_res.x / u_res.y, 1.0);
vec2 si = floor(sc);
vec2 sf = fract(sc) - 0.5;
float sh = hash(si);
if (sh > 0.986) {
float d = length(sf);
float tw = 0.55 + 0.45 * sin(u_time * 2.4 + sh * 88.0);
col += vec3(smoothstep(0.05, 0.0, d) * tw);
}
// layer 2 — bright sparse blue-white
starDensity = 28.0;
sc = uv * starDensity * vec2(u_res.x / u_res.y, 1.0);
si = floor(sc);
sf = fract(sc) - 0.5;
sh = hash(si + 13.7);
if (sh > 0.993) {
float d = length(sf);
float tw = 0.3 + 0.7 * sin(u_time * 1.7 + sh * 200.0);
float s = smoothstep(0.09, 0.0, d) * tw;
col += vec3(0.72, 0.86, 1.0) * s * 1.8;
// soft halo
col += vec3(0.45, 0.55, 0.95) * smoothstep(0.28, 0.0, d) * tw * 0.18;
}
gl_FragColor = vec4(col, 1.0);
}
`;
const compile = (type, src) => {
const s = gl.createShader(type);
gl.shaderSource(s, src); gl.compileShader(s);
if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) {
console.warn("[cosmos]", gl.getShaderInfoLog(s));
return null;
}
return s;
};
const vs = compile(gl.VERTEX_SHADER, vsSrc);
const fs = compile(gl.FRAGMENT_SHADER, fsSrc);
if (!vs || !fs) { root.classList.add("cosmos-static"); return; }
const prog = gl.createProgram();
gl.attachShader(prog, vs); gl.attachShader(prog, fs);
gl.linkProgram(prog);
if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
console.warn("[cosmos]", gl.getProgramInfoLog(prog));
root.classList.add("cosmos-static"); return;
}
gl.useProgram(prog);
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-1,-1, 1,-1, -1, 1,
-1, 1, 1,-1, 1, 1
]), gl.STATIC_DRAW);
const aLoc = gl.getAttribLocation(prog, "a");
gl.enableVertexAttribArray(aLoc);
gl.vertexAttribPointer(aLoc, 2, gl.FLOAT, false, 0, 0);
const uRes = gl.getUniformLocation(prog, "u_res");
const uTime = gl.getUniformLocation(prog, "u_time");
const uMouse = gl.getUniformLocation(prog, "u_mouse");
const uRipplePos = gl.getUniformLocation(prog, "u_ripple_pos");
const uRippleAge = gl.getUniformLocation(prog, "u_ripple_age");
document.body.prepend(canvas);
const dpr = Math.min(window.devicePixelRatio || 1, 1.5);
let w = 0, h = 0;
const resize = () => {
w = Math.floor(window.innerWidth * dpr);
h = Math.floor(window.innerHeight * dpr);
canvas.width = w; canvas.height = h;
gl.viewport(0, 0, w, h);
};
resize();
window.addEventListener("resize", resize, { passive: true });
const mouse = { x: 0.5, y: 0.5 };
const target = { x: 0.5, y: 0.5 };
window.addEventListener("pointermove", (e) => {
target.x = e.clientX / window.innerWidth;
target.y = 1 - e.clientY / window.innerHeight;
}, { passive: true });
const t0 = performance.now();
const ripple = { x: 0, y: 0, t0: -1e6 };
window.addEventListener("pointerdown", (e) => {
const dpr2 = Math.min(window.devicePixelRatio || 1, 1.5);
ripple.x = e.clientX * dpr2;
ripple.y = (window.innerHeight - e.clientY) * dpr2;
ripple.t0 = (performance.now() - t0) / 1000;
}, { passive: true });
let running = true;
document.addEventListener("visibilitychange", () => {
const wasPaused = !running;
running = !document.hidden;
if (running && wasPaused) requestAnimationFrame(loop);
});
function loop(now) {
if (!running) return;
mouse.x += (target.x - mouse.x) * 0.05;
mouse.y += (target.y - mouse.y) * 0.05;
const tNow = (now - t0) / 1000;
gl.uniform2f(uRes, w, h);
gl.uniform1f(uTime, tNow);
gl.uniform2f(uMouse, mouse.x * w, mouse.y * h);
gl.uniform2f(uRipplePos, ripple.x, ripple.y);
gl.uniform1f(uRippleAge, tNow - ripple.t0);
gl.drawArrays(gl.TRIANGLES, 0, 6);
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
}
/* ───── cosmos overlays + interactions ───── */
function attachCosmosCursor() {
const root = document.documentElement;
const halo = document.createElement("div");
halo.className = "cosmos-halo";
halo.setAttribute("aria-hidden", "true");
document.body.appendChild(halo);
let x = window.innerWidth / 2, y = window.innerHeight / 2;
let tx = x, ty = y;
let active = false;
const wakeUp = () => { if (!active) { active = true; root.classList.add("cosmos-cursor"); } };
window.addEventListener("pointermove", (e) => {
tx = e.clientX; ty = e.clientY; wakeUp();
const nx = (e.clientX / window.innerWidth) - 0.5;
const ny = (e.clientY / window.innerHeight) - 0.5;
root.style.setProperty("--cm-x", nx.toFixed(3));
root.style.setProperty("--cm-y", ny.toFixed(3));
}, { passive: true });
window.addEventListener("pointerleave", () => root.classList.remove("cosmos-cursor"));
(function tick() {
x += (tx - x) * 0.14;
y += (ty - y) * 0.14;
halo.style.transform = `translate3d(${x - 300}px, ${y - 300}px, 0)`;
requestAnimationFrame(tick);
})();
}
function attachCosmosComets() {
const frag = document.createDocumentFragment();
for (let i = 1; i <= 3; i++) {
const c = document.createElement("div");
c.className = `cosmos-comet cosmos-comet--${i}`;
c.setAttribute("aria-hidden", "true");
frag.appendChild(c);
}
document.body.appendChild(frag);
}
function attachCosmosParallax() {
/* CSS reads --cm-x / --cm-y set in attachCosmosCursor */
}
function attachCosmosCardTilt() {
document.querySelectorAll(".card").forEach((card) => {
if (card.classList.contains("card--testimonial")) return;
if (card.classList.contains("card--client")) return;
const sh = document.createElement("span");
sh.className = "card__shimmer";
sh.setAttribute("aria-hidden", "true");
card.prepend(sh);
let raf = 0;
card.addEventListener("pointermove", (e) => {
if (raf) return;
raf = requestAnimationFrame(() => {
const rect = card.getBoundingClientRect();
const x = (e.clientX - rect.left) / rect.width;
const y = (e.clientY - rect.top) / rect.height;
card.style.setProperty("--tx", (x - 0.5).toFixed(3));
card.style.setProperty("--ty", (y - 0.5).toFixed(3));
card.style.setProperty("--sx", `${(x * 100).toFixed(1)}%`);
card.style.setProperty("--sy", `${(y * 100).toFixed(1)}%`);
raf = 0;
});
});
card.addEventListener("pointerleave", () => {
card.style.setProperty("--tx", "0");
card.style.setProperty("--ty", "0");
});
});
}
function attachWarpEgg() {
const order = ["editorial", "swiss", "cosmos"];
let buf = "";
const KEY = "warp";
document.addEventListener("keydown", (e) => {
const tgt = e.target;
if (tgt && tgt.matches && tgt.matches("input, textarea, [contenteditable]")) return;
if (!e.key || e.key.length !== 1) return;
buf = (buf + e.key.toLowerCase()).slice(-KEY.length);
if (buf !== KEY) return;
buf = "";
const cur = document.documentElement.dataset.template || "editorial";
const next = order[(order.indexOf(cur) + 1) % order.length];
try { sessionStorage.setItem("dlstack-warp-toast", next); } catch (err) {}
const url = new URL(location.href);
url.searchParams.set("template", next);
location.replace(url.toString());
});
let pending = null;
try { pending = sessionStorage.getItem("dlstack-warp-toast"); } catch (err) {}
if (!pending) return;
try { sessionStorage.removeItem("dlstack-warp-toast"); } catch (err) {}
const toast = document.createElement("div");
toast.className = "warp-toast";
toast.setAttribute("role", "status");
const arrow = document.createElement("span");
arrow.className = "warp-toast__arrow";
arrow.setAttribute("aria-hidden", "true");
arrow.textContent = "↯";
const label = document.createElement("span");
label.className = "warp-toast__label";
label.textContent = pending;
toast.append(arrow, label);
document.body.appendChild(toast);
setTimeout(() => toast.classList.add("warp-toast--out"), 1600);
setTimeout(() => toast.remove(), 2500);
}
function attachCarousels(root) {
const reduced = matchMedia("(prefers-reduced-motion: reduce)").matches;
$$("[data-carousel]", root).forEach((car) => {
const slides = $$(".carousel__track > *", car);
const dots = $$(".carousel__dot", car);
if (slides.length <= 1) { slides.forEach((s) => s.classList.add("is-active")); return; }
if (reduced) { car.classList.add("carousel--stacked"); slides.forEach((s) => s.classList.add("is-active")); return; }
let i = 0;
const show = (n) => {
i = (n + slides.length) % slides.length;
slides.forEach((s, k) => s.classList.toggle("is-active", k === i));
dots.forEach((d, k) => d.classList.toggle("is-active", k === i));
car.setAttribute("aria-label", `Testimonial ${i + 1} of ${slides.length}`);
};
show(0);
let timer = 0;
const ADVANCE_MS = 7000;
const play = () => { stop(); timer = setInterval(() => show(i + 1), ADVANCE_MS); };
const stop = () => { if (timer) { clearInterval(timer); timer = 0; } };
car.addEventListener("pointerenter", stop);
car.addEventListener("pointerleave", play);
car.addEventListener("focusin", stop);
car.addEventListener("focusout", play);
document.addEventListener("visibilitychange", () => { document.hidden ? stop() : play(); });
$(".carousel__nav--prev", car)?.addEventListener("click", () => { show(i - 1); play(); });
$(".carousel__nav--next", car)?.addEventListener("click", () => { show(i + 1); play(); });
dots.forEach((d) => d.addEventListener("click", () => { show(Number(d.dataset.slide)); play(); }));
car.tabIndex = 0;
car.addEventListener("keydown", (e) => {
if (e.key === "ArrowLeft") { e.preventDefault(); show(i - 1); play(); }
if (e.key === "ArrowRight") { e.preventDefault(); show(i + 1); play(); }
});
let touchX = null;
car.addEventListener("touchstart", (e) => { touchX = e.changedTouches[0].clientX; }, { passive: true });
car.addEventListener("touchend", (e) => {
if (touchX === null) return;
const dx = e.changedTouches[0].clientX - touchX;
if (Math.abs(dx) > 40) show(dx < 0 ? i + 1 : i - 1);
touchX = null;
play();
});
play();
});
}
function attachReveal(root) {
if (!("IntersectionObserver" in window)) {
$$(".reveal", root).forEach(el => el.classList.add("in"));
return;
}
const io = new IntersectionObserver((entries) => {
entries.forEach(en => {
if (en.isIntersecting) { en.target.classList.add("in"); io.unobserve(en.target); }
});
}, { threshold: 0.08, rootMargin: "0px 0px -40px 0px" });
$$(".reveal", root).forEach(el => io.observe(el));
}
async function loadData() {
const sources = ["data/links.json", "data/links.example.json"];
let lastErr;
for (const src of sources) {
try {
const res = await fetch(src, { cache: "no-cache" });
if (!res.ok) { lastErr = new Error(`${src}: HTTP ${res.status}`); continue; }
return await res.json();
} catch (err) { lastErr = err; }
}
throw lastErr || new Error("No data file found.");
}
async function main() {
const app = $("#app");
let data;
try {
data = await loadData();
} catch (err) {
const p = document.createElement("p");
p.style.cssText = "color:var(--accent);font-family:var(--mono);padding:2rem;max-width:48ch";
p.textContent = `Couldn't load data/links.json or data/links.example.json. Check that one exists and is valid JSON. Details: ${err.message}`;
app.replaceChildren(p);
return;
}
if (data.theme?.accent) {
document.documentElement.style.setProperty("--accent", data.theme.accent);
}
const validTpl = new Set(["editorial", "swiss", "cosmos"]);
let urlTpl = null;
try { urlTpl = new URL(location.href).searchParams.get("template"); } catch (e) {}
const tpl = validTpl.has(urlTpl) ? urlTpl
: validTpl.has(data.theme?.template) ? data.theme.template
: "editorial";
document.documentElement.dataset.template = tpl;
try { localStorage.setItem("dlstack-template", tpl); } catch (e) {}
if (tpl === "cosmos") bootCosmos();
const p = data.profile || {};
const sections = data.sections || [];
const social = data.social || [];
document.title = `${p.name || "Links"}`;
const taglineMarkup = (t) =>
esc(t).replace(/\s*[·•|]\s*/g, '·');
const html = `
✱ Index №01
MMXXVI
${sections.map((s, i) => renderSection(s, i + 1)).join("")}
`;
app.replaceChildren(frag(html));
attachFaviconFallback(app);
attachYouTube(app);
attachCarousels(app);
attachReveal(app);
attachTheme();
attachWarpEgg();
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", main);
} else {
main();
}
})();