Wiki — Encyclopedia Landing (Wikipedia-style)
A Wikipedia-style main page for the fictional Compendia encyclopedia, built in HTML, CSS, and vanilla JS. A welcome banner with an animated article-count stat, a central search bar with a live preview dropdown, a two-column Featured article plus Did you know and In the news layout, an On this day list, a CSS-drawn featured picture, a colour-coded portals grid, sister-project tiles, and a languages footer band. Shuffle buttons rotate the featured article and facts, with toasts and a slash keyboard shortcut.
MCP
الكود
/* =========================================================
Compendia — Encyclopedia Landing (Wikipedia-style)
Palette override: white + ink + classic wiki blue (#3366cc)
========================================================= */
:root {
--bg: #ffffff;
--bg-2: #f6f7f9;
--panel: #ffffff;
--ink: #1a1a1f;
--ink-2: #3a3a42;
--muted: #6b7280;
--line: rgba(20, 20, 30, 0.10);
--line-2: rgba(20, 20, 30, 0.18);
--link: #3366cc;
--link-hover: #2249a8;
--link-visited: #6a4fa3;
--accent: #3366cc;
--note: #3366cc;
--tip: #16a34a;
--warn: #d97706;
--danger: #dc2626;
--code-bg: #f4f4f6;
--kbd-bg: #eceef2;
/* tinted section panels (Wikipedia main-page feel) */
--tint-fa: #f5fbfd; /* featured article */
--tint-fa-border: #c6dbef;
--tint-dyk: #f5fffa; /* did you know */
--tint-dyk-border: #b9deca;
--tint-news: #fdfdf4; /* in the news */
--tint-news-border: #e2dfb8;
--tint-otd: #fbf5fb; /* on this day */
--tint-otd-border: #ddc6df;
--serif: "Source Serif 4", Georgia, "Times New Roman", serif;
--ui: "Inter", system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
--mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
--r-sm: 6px;
--r-md: 10px;
--r-lg: 14px;
}
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
margin: 0;
background: var(--bg);
color: var(--ink);
font-family: var(--ui);
font-size: 15px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); text-decoration: underline; }
a:focus-visible,
button:focus-visible,
input:focus-visible {
outline: 2px solid var(--link);
outline-offset: 2px;
border-radius: 3px;
}
.sr-only {
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
position: absolute; left: 8px; top: -48px; z-index: 60;
background: var(--ink); color: #fff; padding: 8px 14px;
border-radius: var(--r-sm); transition: top .15s ease;
}
.skip-link:focus { top: 8px; color: #fff; text-decoration: none; }
/* ============ TOP BAR ============ */
.topbar {
position: sticky; top: 0; z-index: 40;
background: var(--panel);
border-bottom: 1px solid var(--line);
box-shadow: 0 1px 0 rgba(20,20,30,0.02);
}
.topbar__inner {
max-width: 1180px; margin: 0 auto; padding: 10px 20px;
display: flex; align-items: center; gap: 18px;
}
.brand { display: flex; align-items: center; gap: 11px; color: var(--ink); flex: 0 0 auto; }
.brand:hover { text-decoration: none; }
.brand__mark {
width: 38px; height: 38px; border-radius: 50%;
display: grid; place-items: center;
font-family: var(--serif); font-weight: 700; font-size: 22px;
color: var(--ink);
background:
radial-gradient(circle at 50% 38%, #ffffff 0 30%, transparent 31%),
conic-gradient(from 0deg, #e9eef7, #d6e0f0, #e9eef7, #d6e0f0, #e9eef7);
border: 1px solid var(--line-2);
}
.brand__text { display: flex; flex-direction: column; line-height: 1.05; }
.brand__text strong { font-family: var(--serif); font-size: 19px; font-weight: 700; letter-spacing: .2px; }
.brand__text em { font-style: italic; font-size: 11.5px; color: var(--muted); }
.topsearch { position: relative; flex: 1 1 auto; max-width: 560px; }
.topsearch__field {
display: flex; align-items: center;
border: 1px solid var(--line-2); border-radius: var(--r-sm);
background: var(--bg); overflow: hidden;
transition: border-color .15s ease, box-shadow .15s ease;
}
.topsearch__field:focus-within { border-color: var(--link); box-shadow: 0 0 0 3px rgba(51,102,204,.14); }
.topsearch__icon { width: 18px; height: 18px; color: var(--muted); margin: 0 6px 0 10px; flex: 0 0 auto; }
#searchInput {
flex: 1 1 auto; border: 0; background: transparent; padding: 9px 6px;
font-family: var(--ui); font-size: 14.5px; color: var(--ink);
}
#searchInput:focus { outline: none; }
.topsearch__btn {
border: 0; border-left: 1px solid var(--line);
background: var(--bg-2); color: var(--ink-2);
font-family: var(--ui); font-weight: 600; font-size: 13.5px;
padding: 0 16px; align-self: stretch; cursor: pointer;
transition: background .15s ease, color .15s ease;
}
.topsearch__btn:hover { background: var(--link); color: #fff; }
.search-preview {
position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 50;
background: var(--panel); border: 1px solid var(--line-2);
border-radius: var(--r-md); box-shadow: 0 12px 34px rgba(20,20,30,.14);
overflow: hidden; padding: 4px;
}
.search-preview__item {
display: block; padding: 8px 11px; border-radius: var(--r-sm);
color: var(--ink); cursor: pointer;
}
.search-preview__item:hover,
.search-preview__item.is-active { background: var(--bg-2); text-decoration: none; }
.search-preview__item b { color: var(--link); font-weight: 600; }
.search-preview__item .sp-snip { display: block; color: var(--muted); font-size: 12.5px; margin-top: 1px; }
.search-preview__empty { padding: 12px; color: var(--muted); font-size: 13.5px; }
.search-preview__hint {
padding: 7px 11px; color: var(--muted); font-size: 12px;
border-top: 1px solid var(--line); margin-top: 2px;
display: flex; gap: 6px; align-items: center; flex-wrap: wrap;
}
kbd {
font-family: var(--mono); font-size: 11px; color: var(--ink-2);
background: var(--kbd-bg); border: 1px solid var(--line-2);
border-bottom-width: 2px; border-radius: 4px; padding: 1px 5px;
}
.topnav { display: flex; gap: 14px; flex: 0 0 auto; font-size: 13.5px; }
.topnav a { color: var(--link); }
/* ============ PAGE ============ */
.page { max-width: 1180px; margin: 0 auto; padding: 22px 20px 40px; }
/* Welcome banner */
.welcome {
text-align: center; padding: 26px 20px 22px; margin-bottom: 22px;
background:
radial-gradient(120% 140% at 50% -20%, #eef3fb 0%, transparent 60%),
var(--bg);
border: 1px solid var(--line); border-radius: var(--r-lg);
}
.welcome h1 {
font-family: var(--serif); font-weight: 700; font-size: clamp(28px, 4vw, 40px);
margin: 0 0 6px; letter-spacing: -.3px; color: var(--ink);
}
.welcome h1 span { color: var(--accent); }
.welcome__lede {
font-family: var(--serif); font-size: 17px; color: var(--ink-2);
max-width: 640px; margin: 0 auto 18px; line-height: 1.6;
}
.welcome__stats {
display: flex; flex-wrap: wrap; justify-content: center; gap: 12px 28px;
}
.stat { display: flex; flex-direction: column; line-height: 1.1; min-width: 84px; }
.stat strong {
font-family: var(--serif); font-size: 22px; font-weight: 700; color: var(--ink);
font-variant-numeric: tabular-nums;
}
.stat span { font-size: 11.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .6px; margin-top: 2px; }
/* Grid */
.grid {
display: grid; grid-template-columns: 1.35fr 1fr; gap: 20px; margin-bottom: 20px;
}
.grid--2 { grid-template-columns: 1fr 1fr; }
/* Cards */
.card {
background: var(--panel); border: 1px solid var(--line);
border-radius: var(--r-md); overflow: hidden;
}
.card__head {
display: flex; align-items: center; justify-content: space-between; gap: 10px;
padding: 11px 16px; border-bottom: 1px solid var(--line);
background: var(--bg-2);
}
.card__head--sub { border-top: 1px solid var(--line); }
.card__head h2 { font-family: var(--serif); font-weight: 700; font-size: 17px; margin: 0; color: var(--ink); }
.card__date { font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.card__body { padding: 16px; }
/* tinted variants */
.card--featured { border-color: var(--tint-fa-border); }
.card--featured .card__head { background: var(--tint-fa); }
.card--dyk { border-color: var(--tint-dyk-border); }
.card--dyk .card__head:first-of-type { background: var(--tint-dyk); }
.card--dyk #itnTitle { }
.card--dyk .card__head--sub { background: var(--tint-news); }
/* rotor button */
.rotor {
border: 1px solid var(--line-2); background: var(--panel); color: var(--ink-2);
font-family: var(--ui); font-weight: 600; font-size: 12px;
padding: 4px 9px; border-radius: 999px; cursor: pointer;
transition: background .15s ease, color .15s ease, border-color .15s ease, transform .15s ease;
}
.rotor:hover { background: var(--link); color: #fff; border-color: var(--link); }
.rotor:active { transform: translateY(1px); }
.rotor.is-spin { animation: spin .5s ease; }
@keyframes spin { to { transform: rotate(360deg); } }
/* Featured article */
.fa { font-family: var(--serif); }
.fa__thumb {
float: right; width: 188px; margin: 2px 0 12px 16px;
}
.fa__thumb figcaption { font-size: 12px; color: var(--muted); margin-top: 5px; line-height: 1.4; font-style: italic; }
.thumb-art {
width: 100%; aspect-ratio: 4/3; border-radius: var(--r-sm);
border: 1px solid var(--line-2);
}
.thumb-art--aurora {
background:
linear-gradient(180deg, #14213d 0%, #1f3a5f 38%, #2f6f3e 39%, #245a32 100%),
radial-gradient(70% 40% at 30% 18%, rgba(120,220,180,.55), transparent 60%);
position: relative; overflow: hidden;
}
.thumb-art--aurora::after {
content: ""; position: absolute; left: -10%; top: 10%; width: 120%; height: 30%;
background: linear-gradient(90deg, transparent, rgba(140,240,190,.6), rgba(120,180,255,.5), transparent);
filter: blur(6px); transform: rotate(-8deg);
}
.thumb-art--news {
background: linear-gradient(135deg, #34507a, #1f6f86);
position: relative;
}
.thumb-art--news::after {
content: ""; position: absolute; inset: 24% 18%;
border: 3px solid rgba(255,255,255,.85); border-radius: 50%;
box-shadow: 0 0 0 8px rgba(255,255,255,.15);
}
.fa__title { font-size: 19px; margin: 0 0 6px; font-weight: 700; }
.fa__text { font-size: 15.5px; line-height: 1.65; color: var(--ink-2); margin: 0 0 12px; }
.fa__more { display: none; }
.fa.is-expanded .fa__more { display: inline; }
.fa__meta { font-size: 13px; color: var(--muted); margin: 0; clear: both; padding-top: 6px; border-top: 1px dotted var(--line-2); }
/* Did you know / news */
.dyk-list, .itn-list, .otd-list { margin: 0; padding-left: 18px; font-family: var(--serif); }
.dyk-list li, .itn-list li, .otd-list li { margin: 0 0 9px; line-height: 1.6; font-size: 15px; color: var(--ink-2); }
.dyk-list li:last-child, .itn-list li:last-child, .otd-list li:last-child { margin-bottom: 0; }
.itn__thumb { float: right; width: 110px; margin: 0 0 8px 14px; }
.itn__thumb .thumb-art { aspect-ratio: 1/1; }
.itn__more { font-size: 13px; color: var(--muted); margin: 12px 0 0; clear: both; }
/* Featured picture */
.featpic figcaption { font-family: var(--serif); font-size: 13.5px; color: var(--ink-2); margin-top: 10px; line-height: 1.55; }
.featpic__art {
position: relative; width: 100%; aspect-ratio: 16/9; overflow: hidden;
border-radius: var(--r-sm); border: 1px solid var(--line-2);
background: #0f1830;
}
.featpic__sky { position: absolute; inset: 0; background: linear-gradient(180deg, #0d1b3a 0%, #233a63 45%, #6b4a6f 78%, #b5805e 100%); }
.featpic__aurora {
position: absolute; left: -10%; top: 8%; width: 120%; height: 34%;
background: linear-gradient(90deg, transparent, rgba(120,240,180,.55), rgba(110,170,255,.5), rgba(190,140,255,.4), transparent);
filter: blur(9px); transform: rotate(-6deg);
animation: drift 9s ease-in-out infinite alternate;
}
@keyframes drift { from { transform: rotate(-6deg) translateX(-3%);} to { transform: rotate(-3deg) translateX(4%);} }
.featpic__sun {
position: absolute; right: 16%; top: 52%; width: 54px; height: 54px; border-radius: 50%;
background: radial-gradient(circle, #ffe7b0 0 40%, #ffb85c 70%, transparent 72%);
filter: blur(.4px);
}
.featpic__hills { position: absolute; inset: 0; }
.hill { position: absolute; bottom: 26%; border-radius: 50% 50% 0 0; opacity: .9; }
.hill--a { left: -8%; width: 55%; height: 38%; background: #2a4a36; }
.hill--b { right: -6%; width: 60%; height: 46%; background: #1f3a2c; }
.hill--c { left: 28%; width: 48%; height: 32%; background: #345a40; }
.featpic__terraces {
position: absolute; left: 0; right: 0; bottom: 0; height: 30%;
background:
repeating-linear-gradient(180deg, #2f6f3e 0 6px, #27592f 6px 12px),
#245a32;
box-shadow: inset 0 6px 14px rgba(0,0,0,.25);
}
/* Portals */
.portals { margin: 28px 0 20px; }
.portals > h2, .sisters > h2 {
font-family: var(--serif); font-weight: 700; font-size: 20px; margin: 0 0 14px;
padding-bottom: 8px; border-bottom: 1px solid var(--line); color: var(--ink);
}
.portals__grid {
display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px;
}
.portal {
display: flex; flex-direction: column; gap: 4px;
padding: 14px 14px 13px; border-radius: var(--r-md);
border: 1px solid var(--line); background: var(--panel); color: var(--ink);
position: relative; overflow: hidden;
transition: transform .14s ease, box-shadow .14s ease, border-color .14s ease;
}
.portal::before {
content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
background: var(--p, var(--accent)); opacity: .85;
}
.portal:hover {
text-decoration: none; transform: translateY(-2px);
border-color: color-mix(in srgb, var(--p, var(--accent)) 45%, var(--line-2));
box-shadow: 0 8px 22px rgba(20,20,30,.10);
}
.portal__icon {
font-size: 22px; line-height: 1; color: var(--p, var(--accent));
transition: transform .2s ease;
}
.portal:hover .portal__icon { transform: scale(1.16) rotate(-4deg); }
.portal__name { font-family: var(--serif); font-weight: 700; font-size: 16px; }
.portal__count { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
/* Sisters */
.sisters { margin-top: 26px; }
.sisters__grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px; }
.sister {
display: flex; flex-direction: column; align-items: center; text-align: center;
gap: 2px; padding: 12px 8px; border: 1px solid var(--line); border-radius: var(--r-md);
background: var(--bg-2); color: var(--ink);
transition: background .14s ease, border-color .14s ease;
}
.sister:hover { text-decoration: none; background: var(--panel); border-color: var(--link); }
.sister b { font-family: var(--serif); font-size: 14.5px; }
.sister span { font-size: 11px; color: var(--muted); }
/* Languages footer */
.langfoot { border-top: 1px solid var(--line); background: var(--bg-2); margin-top: 8px; }
.langfoot__inner { max-width: 1180px; margin: 0 auto; padding: 28px 20px 36px; }
.langfoot h2 { font-family: var(--serif); font-weight: 700; font-size: 19px; margin: 0 0 6px; }
.langfoot__lede { font-family: var(--serif); color: var(--ink-2); max-width: 720px; margin: 0 0 16px; line-height: 1.6; }
.langfoot__list {
list-style: none; margin: 0 0 18px; padding: 0;
display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px 18px;
}
.langfoot__list a { color: var(--link); font-size: 13.5px; }
.langfoot__list b { font-weight: 600; color: var(--ink); margin-right: 4px; }
.langfoot__legal { font-size: 12px; color: var(--muted); border-top: 1px solid var(--line); padding-top: 14px; margin: 0; line-height: 1.55; }
/* Toast */
.toast {
position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%) translateY(16px);
background: var(--ink); color: #fff; font-size: 13.5px; font-weight: 500;
padding: 10px 16px; border-radius: 999px; box-shadow: 0 10px 30px rgba(20,20,30,.28);
opacity: 0; pointer-events: none; transition: opacity .2s ease, transform .2s ease;
z-index: 70; max-width: 90vw;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
/* ============ RESPONSIVE ============ */
@media (max-width: 820px) {
.topbar__inner { flex-wrap: wrap; }
.topsearch { order: 3; flex: 1 1 100%; max-width: none; }
.topnav { order: 2; margin-left: auto; }
.grid, .grid--2 { grid-template-columns: 1fr; }
.portals__grid { grid-template-columns: repeat(2, 1fr); }
.sisters__grid { grid-template-columns: repeat(3, 1fr); }
.langfoot__list { grid-template-columns: repeat(3, 1fr); }
.fa__thumb { width: 150px; }
}
@media (max-width: 520px) {
body { font-size: 14.5px; }
.topbar__inner { padding: 9px 14px; gap: 12px; }
.brand__text em { display: none; }
.page { padding: 16px 14px 30px; }
.welcome { padding: 20px 14px; }
.welcome__stats { gap: 10px 18px; }
.stat strong { font-size: 19px; }
.portals__grid { grid-template-columns: 1fr 1fr; }
.sisters__grid { grid-template-columns: repeat(2, 1fr); }
.langfoot__list { grid-template-columns: 1fr 1fr; }
.fa__thumb { float: none; width: 100%; margin: 0 0 12px; }
.itn__thumb { float: none; width: 100%; margin: 0 0 12px; }
.topnav { font-size: 12.5px; gap: 10px; }
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation: none !important; transition: none !important; }
}/* =========================================================
Compendia — Encyclopedia Landing
Vanilla JS: toast, date stamp, search preview dropdown,
rotating featured article + did-you-know facts.
========================================================= */
(function () {
"use strict";
/* ---------- toast helper ---------- */
var toastEl = document.getElementById("toast");
var toastTimer = null;
function toast(msg) {
if (!toastEl) return;
toastEl.textContent = msg;
toastEl.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("show");
}, 2200);
}
/* Wire any element with data-toast */
document.addEventListener("click", function (e) {
var t = e.target.closest("[data-toast]");
if (t) {
e.preventDefault();
toast(t.getAttribute("data-toast"));
}
});
/* ---------- date stamp ---------- */
var now = new Date();
var longDate = now.toLocaleDateString("en-US", {
weekday: "long", year: "numeric", month: "long", day: "numeric",
});
var shortDate = now.toLocaleDateString("en-US", { month: "long", day: "numeric" });
var otdDate = document.getElementById("otdDate");
if (otdDate) otdDate.textContent = shortDate;
/* "today" stat — deterministic-ish edits count from the date */
var statToday = document.getElementById("statToday");
if (statToday) {
var base = 9000 + (now.getDate() * 137 + now.getHours() * 53) % 4000;
statToday.textContent = base.toLocaleString("en-US");
}
/* ---------- search preview ---------- */
var INDEX = [
{ title: "The Verdant Empire", snip: "Confederated agrarian state, fl. 412–1089." },
{ title: "Aurora DB", snip: "Early column-store ledger system." },
{ title: "Project Nimbus", snip: "Sub-orbital relay programme." },
{ title: "Lumen Observatory", snip: "High-altitude astronomical station." },
{ title: "The Marble Concordat", snip: "Multilateral trade treaty of the seven leagues." },
{ title: "Codex Viridis", snip: "Foundational agronomic manuscript." },
{ title: "Glass Aqueduct of Lethe", snip: "Gravity-fed meltwater channel, 180 km." },
{ title: "Halcyon-IX", snip: "Ringed gas giant of the outer system." },
{ title: "Library of Saltmarsh", snip: "Rediscovered estuarine archive." },
{ title: "Mira Solveig", snip: "Cartographer of the Inner Sea atlas." },
{ title: "Great Silt Drought", snip: "Climatic event preceding the empire's decline." },
{ title: "Council of Stewards", snip: "Governing assembly of the Verdant Empire." },
{ title: "Verdant Assembly", snip: "First chartered parliament of the river basins." },
{ title: "Terraced hydro-gardens", snip: "Signature irrigation architecture." },
{ title: "Inner Sea", snip: "Enclosed body of water at the continental core." },
];
var input = document.getElementById("searchInput");
var preview = document.getElementById("searchPreview");
var form = document.getElementById("topSearch");
var activeIdx = -1;
var currentMatches = [];
function escapeHtml(s) {
return s.replace(/[&<>"]/g, function (c) {
return { "&": "&", "<": "<", ">": ">", '"': """ }[c];
});
}
function highlight(text, q) {
var i = text.toLowerCase().indexOf(q.toLowerCase());
if (i < 0) return escapeHtml(text);
return (
escapeHtml(text.slice(0, i)) +
"<b>" + escapeHtml(text.slice(i, i + q.length)) + "</b>" +
escapeHtml(text.slice(i + q.length))
);
}
function openPreview() {
preview.hidden = false;
input.setAttribute("aria-expanded", "true");
}
function closePreview() {
preview.hidden = true;
input.setAttribute("aria-expanded", "false");
activeIdx = -1;
}
function renderPreview() {
var q = input.value.trim();
if (q.length < 1) { closePreview(); return; }
currentMatches = INDEX.filter(function (a) {
return (a.title + " " + a.snip).toLowerCase().indexOf(q.toLowerCase()) !== -1;
}).slice(0, 7);
activeIdx = -1;
var html = "";
if (currentMatches.length === 0) {
html =
'<div class="search-preview__empty">No articles match “' +
escapeHtml(q) + '”. Try a different term.</div>';
} else {
currentMatches.forEach(function (a, idx) {
html +=
'<a class="search-preview__item" role="option" data-idx="' + idx + '" href="#">' +
highlight(a.title, q) +
'<span class="sp-snip">' + escapeHtml(a.snip) + "</span></a>";
});
html +=
'<div class="search-preview__hint"><kbd>↑</kbd><kbd>↓</kbd> navigate · ' +
"<kbd>Enter</kbd> open · <kbd>Esc</kbd> close</div>";
}
preview.innerHTML = html;
openPreview();
}
function setActive(idx) {
var items = preview.querySelectorAll(".search-preview__item");
if (!items.length) return;
activeIdx = (idx + items.length) % items.length;
items.forEach(function (el, i) {
el.classList.toggle("is-active", i === activeIdx);
});
items[activeIdx].scrollIntoView({ block: "nearest" });
}
if (input) {
input.addEventListener("input", renderPreview);
input.addEventListener("focus", function () {
if (input.value.trim()) renderPreview();
});
input.addEventListener("keydown", function (e) {
var items = preview.querySelectorAll(".search-preview__item");
if (e.key === "ArrowDown") { e.preventDefault(); if (items.length) setActive(activeIdx + 1); }
else if (e.key === "ArrowUp") { e.preventDefault(); if (items.length) setActive(activeIdx - 1); }
else if (e.key === "Escape") { closePreview(); }
else if (e.key === "Enter") {
if (activeIdx >= 0 && currentMatches[activeIdx]) {
e.preventDefault();
toast("Opening “" + currentMatches[activeIdx].title + "” (illustrative).");
closePreview();
}
}
});
preview.addEventListener("click", function (e) {
var item = e.target.closest(".search-preview__item");
if (!item) return;
e.preventDefault();
var idx = parseInt(item.getAttribute("data-idx"), 10);
toast("Opening “" + currentMatches[idx].title + "” (illustrative).");
closePreview();
});
}
if (form) {
form.addEventListener("submit", function (e) {
e.preventDefault();
var q = input.value.trim();
if (!q) { toast("Type something to search."); return; }
toast("Searching for “" + q + "” (illustrative).");
closePreview();
});
}
document.addEventListener("click", function (e) {
if (form && !form.contains(e.target)) closePreview();
});
/* Keyboard shortcut: "/" focuses search */
document.addEventListener("keydown", function (e) {
if (e.key === "/" && document.activeElement !== input &&
!/^(INPUT|TEXTAREA)$/.test((document.activeElement || {}).tagName || "")) {
e.preventDefault();
input && input.focus();
}
});
/* ---------- rotating featured article ---------- */
var FEATURED = [
{
art: "thumb-art--aurora",
cap: "Aurora over the Verdant Empire's northern reach",
title: "The Verdant Empire",
body:
"The <b>Verdant Empire</b> (fl. 412–1089) was a confederated agrarian state spanning the river basins of the central continent. Renowned for its terraced hydro-gardens and the <a href=\"#\" data-toast=\"Illustrative link.\">Codex Viridis</a>, the empire pioneered a system of canal-borne courier networks that linked over four hundred chartered townships. Its decline followed the <a href=\"#\" data-toast=\"Illustrative link.\">Great Silt Drought</a>, after which the ruling Council of Stewards dissolved into rival city-leagues. ",
more:
"At its height the empire's <a href=\"#\" data-toast=\"Illustrative link.\">grain reserves</a> were said to feed a population of nine million across three climatic zones. <em>(Full article…)</em>",
},
{
art: "thumb-art--news",
cap: "Schematic of an Aurora DB column segment",
title: "Aurora DB",
body:
"<b>Aurora DB</b> was an early column-store ledger system first demonstrated in 1969. By storing each attribute contiguously rather than by row, it allowed analysts to scan a single field across millions of records without reading whole entries. The design influenced a generation of <a href=\"#\" data-toast=\"Illustrative link.\">analytic engines</a> and remains a touchstone in the study of storage layouts. ",
more:
"Surviving documentation suggests Aurora DB could compress repetitive columns by a factor of forty, a figure not matched commercially for two decades. <em>(Full article…)</em>",
},
{
art: "thumb-art--aurora",
cap: "Idealised view of a Project Nimbus relay craft",
title: "Project Nimbus",
body:
"<b>Project Nimbus</b> is a civilian programme to establish a constellation of sub-orbital relay craft providing low-latency links between remote townships. Each craft loiters at the edge of the mesosphere, handing off signals as it drifts. The first relay completed a successful demonstration flight this season, carried aloft by a reusable lifting body. ",
more:
"Engineers estimate a full constellation of <a href=\"#\" data-toast=\"Illustrative link.\">two hundred craft</a> would blanket the inhabited continent. <em>(Full article…)</em>",
},
];
var faContainer = document.getElementById("featuredArticle");
var faRotor = document.getElementById("faRotor");
var faIdx = 0;
function renderFeatured(i) {
var f = FEATURED[i];
faContainer.innerHTML =
'<figure class="fa__thumb" aria-hidden="true">' +
'<div class="thumb-art ' + f.art + '"></div>' +
"<figcaption>" + f.cap + "</figcaption>" +
"</figure>" +
'<h3 class="fa__title"><a href="#" data-toast="Article view is illustrative.">' + f.title + "</a></h3>" +
'<p class="fa__text">' + f.body +
'<span class="fa__more">' + f.more + "</span></p>" +
'<p class="fa__meta">Recently featured: ' +
'<a href="#" data-toast="Illustrative link.">Project Nimbus</a> · ' +
'<a href="#" data-toast="Illustrative link.">Aurora DB</a> · ' +
'<a href="#" data-toast="Illustrative link.">The Marble Concordat</a></p>';
// reveal-more on title click
var titleLink = faContainer.querySelector(".fa__title a");
titleLink.addEventListener("click", function (e) {
e.preventDefault();
faContainer.classList.toggle("is-expanded");
toast(faContainer.classList.contains("is-expanded") ? "Expanded article preview." : "Collapsed article preview.");
});
}
if (faContainer && faRotor) {
renderFeatured(faIdx);
faRotor.addEventListener("click", function () {
faIdx = (faIdx + 1) % FEATURED.length;
renderFeatured(faIdx);
faRotor.classList.remove("is-spin");
void faRotor.offsetWidth;
faRotor.classList.add("is-spin");
});
}
/* ---------- rotating "did you know" facts ---------- */
var DYK = [
"… that the <a href=\"#\" data-toast=\"Illustrative link.\">Glass Aqueduct of Lethe</a> carried meltwater for over <b>180 kilometres</b> without a single pump?",
"… that scribes of the <a href=\"#\" data-toast=\"Illustrative link.\">Codex Viridis</a> used a colour-coded ink to denote crop rotations across <b>twelve seasons</b>?",
"… that <a href=\"#\" data-toast=\"Illustrative link.\">Aurora DB</a> could compress a repetitive column by a factor of <b>forty</b>, decades before commercial systems matched it?",
"… that the ringed giant <a href=\"#\" data-toast=\"Illustrative link.\">Halcyon-IX</a> hosts a sixth ring made almost entirely of water ice?",
"… that the <a href=\"#\" data-toast=\"Illustrative link.\">Library of Saltmarsh</a> was preserved because the estuary that flooded it also sealed it in airless silt?",
"… that cartographer <a href=\"#\" data-toast=\"Illustrative link.\">Mira Solveig</a> mapped the entire Inner Sea using only a sun-staff and a knotted line?",
];
var dykList = document.getElementById("dykList");
var dykRotor = document.getElementById("dykRotor");
var dykIdx = 0;
function renderDyk(i) {
if (!dykList) return;
dykList.innerHTML = "<li>" + DYK[i] + "</li>";
}
if (dykList && dykRotor) {
renderDyk(dykIdx);
dykRotor.addEventListener("click", function () {
dykIdx = (dykIdx + 1) % DYK.length;
renderDyk(dykIdx);
dykRotor.classList.remove("is-spin");
void dykRotor.offsetWidth;
dykRotor.classList.add("is-spin");
});
/* auto-rotate gently */
setInterval(function () {
dykIdx = (dykIdx + 1) % DYK.length;
renderDyk(dykIdx);
}, 9000);
}
/* ---------- animated article-count tick on load ---------- */
var statArticles = document.getElementById("statArticles");
if (statArticles) {
var target = 6481003;
var startVal = target - 1400;
var dur = 900;
var t0 = performance.now();
function tick(t) {
var p = Math.min(1, (t - t0) / dur);
var eased = 1 - Math.pow(1 - p, 3);
var val = Math.round(startVal + (target - startVal) * eased);
statArticles.textContent = val.toLocaleString("en-US");
if (p < 1) requestAnimationFrame(tick);
}
if (!window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
requestAnimationFrame(tick);
} else {
statArticles.textContent = target.toLocaleString("en-US");
}
}
/* friendly first-load nudge */
setTimeout(function () { toast("Welcome to Compendia — press “/” to search."); }, 700);
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Compendia — The Free Encyclopedia</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Source+Serif+4:opsz,[email protected],400;8..60,500;8..60,600;8..60,700&family=JetBrains+Mono:wght@400;500&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<!-- ============ TOP BAR ============ -->
<header class="topbar">
<div class="topbar__inner">
<a class="brand" href="#main" aria-label="Compendia home">
<span class="brand__mark" aria-hidden="true">C</span>
<span class="brand__text">
<strong>Compendia</strong>
<em>The Free Encyclopedia</em>
</span>
</a>
<form class="topsearch" role="search" id="topSearch" autocomplete="off">
<label class="sr-only" for="searchInput">Search Compendia</label>
<div class="topsearch__field">
<svg class="topsearch__icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M21 21l-4.3-4.3M11 18a7 7 0 1 0 0-14 7 7 0 0 0 0 14Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
<input id="searchInput" type="search" placeholder="Search 6,481,003 articles…" aria-expanded="false" aria-controls="searchPreview" aria-autocomplete="list" />
<button class="topsearch__btn" type="submit">Search</button>
</div>
<div class="search-preview" id="searchPreview" role="listbox" hidden></div>
</form>
<nav class="topnav" aria-label="Account">
<a href="#" data-toast="Account creation is illustrative only.">Create account</a>
<a href="#" data-toast="Sign-in is illustrative only.">Log in</a>
</nav>
</div>
</header>
<!-- ============ MAIN ============ -->
<main id="main" class="page">
<!-- Welcome banner -->
<section class="welcome" aria-labelledby="welcomeTitle">
<h1 id="welcomeTitle">Welcome to <span>Compendia</span></h1>
<p class="welcome__lede">
the free encyclopedia that anyone can edit. Currently maintaining
<a href="#" data-toast="Article index is illustrative.">6,481,003</a> articles
in <a href="#" data-toast="Language list is illustrative.">altered English</a>.
</p>
<div class="welcome__stats">
<div class="stat"><strong id="statArticles">6,481,003</strong><span>articles</span></div>
<div class="stat"><strong>74,902</strong><span>active editors</span></div>
<div class="stat"><strong>312</strong><span>languages</span></div>
<div class="stat"><strong id="statToday">—</strong><span>today</span></div>
</div>
</section>
<!-- Two-column featured / DYK -->
<div class="grid">
<!-- Featured article -->
<section class="card card--featured" aria-labelledby="faTitle">
<header class="card__head">
<h2 id="faTitle">From today's featured article</h2>
<button class="rotor" id="faRotor" type="button" title="Show another featured article">↻ Shuffle</button>
</header>
<div class="card__body fa" id="featuredArticle">
<figure class="fa__thumb" aria-hidden="true">
<div class="thumb-art thumb-art--aurora"></div>
<figcaption>Aurora over the Verdant Empire's northern reach</figcaption>
</figure>
<h3 class="fa__title"><a href="#" data-toast="Article view is illustrative.">The Verdant Empire</a></h3>
<p class="fa__text">
The <b>Verdant Empire</b> (fl. 412–1089) was a confederated agrarian state spanning the
river basins of the central continent. Renowned for its terraced hydro-gardens and the
<a href="#" data-toast="Illustrative link.">Codex Viridis</a>, the empire pioneered a system
of canal-borne courier networks that linked over four hundred chartered townships. Its decline
followed the <a href="#" data-toast="Illustrative link.">Great Silt Drought</a>, after which the
ruling Council of Stewards dissolved into rival city-leagues.
<span class="fa__more">At its height the empire's <a href="#" data-toast="Illustrative link.">grain reserves</a>
were said to feed a population of nine million across three climatic zones. <em>(Full article…)</em></span>
</p>
<p class="fa__meta">
Recently featured:
<a href="#" data-toast="Illustrative link.">Project Nimbus</a> ·
<a href="#" data-toast="Illustrative link.">Aurora DB</a> ·
<a href="#" data-toast="Illustrative link.">The Marble Concordat</a>
</p>
</div>
</section>
<!-- Did you know + In the news -->
<section class="card card--dyk" aria-labelledby="dykTitle">
<header class="card__head">
<h2 id="dykTitle">Did you know…</h2>
<button class="rotor" id="dykRotor" type="button" title="Show another fact">↻ New fact</button>
</header>
<div class="card__body">
<ul class="dyk-list" id="dykList" aria-live="polite">
<li>… that the <a href="#" data-toast="Illustrative link.">Glass Aqueduct of Lethe</a> carried meltwater for over <b>180 kilometres</b> without a single pump?</li>
</ul>
</div>
<header class="card__head card__head--sub">
<h2 id="itnTitle">In the news</h2>
</header>
<div class="card__body">
<figure class="itn__thumb" aria-hidden="true"><div class="thumb-art thumb-art--news"></div></figure>
<ul class="itn-list" aria-labelledby="itnTitle">
<li>The <a href="#" data-toast="Illustrative link.">Lumen Observatory</a> confirms a sixth ring around the gas giant <b>Halcyon-IX</b>.</li>
<li>Delegates ratify the <a href="#" data-toast="Illustrative link.">Marble Concordat</a>, ending the seven-league trade embargo.</li>
<li>Archaeologists uncover the lost <a href="#" data-toast="Illustrative link.">Library of Saltmarsh</a> beneath a drained estuary.</li>
<li><a href="#" data-toast="Illustrative link.">Project Nimbus</a> launches its first sub-orbital relay craft.</li>
</ul>
<p class="itn__more"><a href="#" data-toast="Illustrative link.">Ongoing</a> · <a href="#" data-toast="Illustrative link.">Recent deaths</a> · <a href="#" data-toast="Illustrative link.">Nominate an item</a></p>
</div>
</section>
</div>
<!-- On this day + Featured picture -->
<div class="grid grid--2">
<section class="card" aria-labelledby="otdTitle">
<header class="card__head">
<h2 id="otdTitle">On this day</h2>
<span class="card__date" id="otdDate">—</span>
</header>
<div class="card__body">
<ul class="otd-list">
<li><b>709</b> — The Council of Stewards convenes the first <a href="#" data-toast="Illustrative link.">Verdant Assembly</a>.</li>
<li><b>1412</b> — Cartographer <a href="#" data-toast="Illustrative link.">Mira Solveig</a> completes the first full atlas of the Inner Sea.</li>
<li><b>1887</b> — The <a href="#" data-toast="Illustrative link.">Lumen Observatory</a> records the transit of Halcyon-IX.</li>
<li><b>1969</b> — <a href="#" data-toast="Illustrative link.">Aurora DB</a>, the first column-store ledger, is demonstrated publicly.</li>
</ul>
</div>
</section>
<section class="card card--pic" aria-labelledby="picTitle">
<header class="card__head">
<h2 id="picTitle">Today's featured picture</h2>
</header>
<div class="card__body">
<figure class="featpic">
<div class="featpic__art" role="img" aria-label="Stylised landscape of terraced hydro-gardens beneath an aurora">
<div class="featpic__sky"></div>
<div class="featpic__aurora"></div>
<div class="featpic__sun"></div>
<div class="featpic__hills">
<span class="hill hill--a"></span>
<span class="hill hill--b"></span>
<span class="hill hill--c"></span>
</div>
<div class="featpic__terraces"></div>
</div>
<figcaption>
<b>Terraced hydro-gardens of the Verdant Empire</b> at dusk, an idealised reconstruction
based on the <a href="#" data-toast="Illustrative link.">Codex Viridis</a>.
</figcaption>
</figure>
</div>
</section>
</div>
<!-- Portals -->
<section class="portals" aria-labelledby="portalsTitle">
<h2 id="portalsTitle">Browse by portal</h2>
<div class="portals__grid">
<a class="portal" href="#" data-toast="Science portal is illustrative." style="--p:#2f6f3e">
<span class="portal__icon" aria-hidden="true">⚛</span>
<span class="portal__name">Science</span>
<span class="portal__count">812,406 articles</span>
</a>
<a class="portal" href="#" data-toast="History portal is illustrative." style="--p:#8a5a1a">
<span class="portal__icon" aria-hidden="true">𓂀</span>
<span class="portal__name">History</span>
<span class="portal__count">643,118 articles</span>
</a>
<a class="portal" href="#" data-toast="Geography portal is illustrative." style="--p:#1f6f86">
<span class="portal__icon" aria-hidden="true">🜨</span>
<span class="portal__name">Geography</span>
<span class="portal__count">529,774 articles</span>
</a>
<a class="portal" href="#" data-toast="Arts portal is illustrative." style="--p:#8a2f6a">
<span class="portal__icon" aria-hidden="true">✦</span>
<span class="portal__name">Arts</span>
<span class="portal__count">471,902 articles</span>
</a>
<a class="portal" href="#" data-toast="Technology portal is illustrative." style="--p:#34507a">
<span class="portal__icon" aria-hidden="true">⚙</span>
<span class="portal__name">Technology</span>
<span class="portal__count">388,560 articles</span>
</a>
<a class="portal" href="#" data-toast="Society portal is illustrative." style="--p:#7a3a34">
<span class="portal__icon" aria-hidden="true">☯</span>
<span class="portal__name">Society</span>
<span class="portal__count">355,219 articles</span>
</a>
<a class="portal" href="#" data-toast="Mathematics portal is illustrative." style="--p:#403a7a">
<span class="portal__icon" aria-hidden="true">∑</span>
<span class="portal__name">Mathematics</span>
<span class="portal__count">214,083 articles</span>
</a>
<a class="portal" href="#" data-toast="Philosophy portal is illustrative." style="--p:#5a5a3a">
<span class="portal__icon" aria-hidden="true">Φ</span>
<span class="portal__name">Philosophy</span>
<span class="portal__count">142,667 articles</span>
</a>
</div>
</section>
<!-- Sister projects -->
<section class="sisters" aria-labelledby="sistersTitle">
<h2 id="sistersTitle">Compendia's sister projects</h2>
<div class="sisters__grid">
<a href="#" data-toast="Illustrative project." class="sister"><b>Lexica</b><span>free dictionary</span></a>
<a href="#" data-toast="Illustrative project." class="sister"><b>Quotaria</b><span>quotation library</span></a>
<a href="#" data-toast="Illustrative project." class="sister"><b>Sourcebook</b><span>primary documents</span></a>
<a href="#" data-toast="Illustrative project." class="sister"><b>Vaultmedia</b><span>shared media</span></a>
<a href="#" data-toast="Illustrative project." class="sister"><b>Datastore</b><span>structured data</span></a>
<a href="#" data-toast="Illustrative project." class="sister"><b>Tutoria</b><span>open textbooks</span></a>
</div>
</section>
</main>
<!-- ============ LANGUAGES FOOTER ============ -->
<footer class="langfoot" aria-labelledby="langTitle">
<div class="langfoot__inner">
<h2 id="langTitle">Compendia languages</h2>
<p class="langfoot__lede">This encyclopedia is written in altered English. Many other versions are available; some of the largest are listed below.</p>
<ul class="langfoot__list">
<li><a href="#" data-toast="Illustrative language edition."><b>Español</b> 1,948,221+</a></li>
<li><a href="#" data-toast="Illustrative language edition."><b>Deutsch</b> 2,902,114+</a></li>
<li><a href="#" data-toast="Illustrative language edition."><b>Français</b> 2,611,008+</a></li>
<li><a href="#" data-toast="Illustrative language edition."><b>日本語</b> 1,402,776+</a></li>
<li><a href="#" data-toast="Illustrative language edition."><b>Русский</b> 1,990,512+</a></li>
<li><a href="#" data-toast="Illustrative language edition."><b>中文</b> 1,388,940+</a></li>
<li><a href="#" data-toast="Illustrative language edition."><b>Italiano</b> 1,844,330+</a></li>
<li><a href="#" data-toast="Illustrative language edition."><b>Português</b> 1,122,651+</a></li>
<li><a href="#" data-toast="Illustrative language edition."><b>العربية</b> 1,233,419+</a></li>
<li><a href="#" data-toast="Illustrative language edition."><b>Nederlands</b> 2,140,005+</a></li>
</ul>
<p class="langfoot__legal">
Text is available under an open content license. Compendia is a fictional, illustrative
encyclopedia — all articles, statistics, and projects shown here are invented.
</p>
</div>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Encyclopedia Landing (Wikipedia-style)
A scholarly main page for Compendia, a fictional free encyclopedia, dressed in the classic Wikipedia-style trade: a serif body in Source Serif 4 for the dense, authoritative article prose, Inter for the chrome and navigation, and JetBrains Mono for keyboard hints, all over a clean white ground with classic wiki-blue links. A sticky top bar carries the logo mark, a central search field, and account links, while a welcome banner counts up to 6,481,003 articles and stamps the day’s edit total. Below it, tinted main-page panels lay out a Featured article beside Did you know and In the news, with a separate row for On this day and a CSS-drawn featured picture of terraced hydro-gardens beneath a drifting aurora.
The search field powers a live preview dropdown over a small in-page article index: it filters and
highlights matches as you type, supports arrow-key navigation with Enter to open and Esc to
close, and a / shortcut focuses it from anywhere. Two Shuffle controls rotate through several
featured articles and Did you know facts — the facts also auto-advance gently — and clicking a
featured headline expands or collapses its full preview. A colour-coded portals grid (Science,
History, Geography, Arts, and more) lifts and tints on hover, sister-project tiles and a ten-language
footer band round out the page, and every illustrative link fires a small toast() confirmation.
The layout collapses cleanly from a two-column desktop main page to a single stacked column on narrow
screens, floats unwrap below ~520px, and all motion respects prefers-reduced-motion. Landmarks,
visible focus rings, aria-live regions, and AA-contrast link blue keep it keyboard- and
screen-reader-friendly.
Illustrative UI only — fictional articles, products, and data.