diff options
Diffstat (limited to 'src/static')
-rw-r--r-- | src/static/client.js | 638 | ||||
-rw-r--r-- | src/static/lazy-loading.js | 62 | ||||
-rw-r--r-- | src/static/site-basic.css | 12 | ||||
-rw-r--r-- | src/static/site.css | 966 |
4 files changed, 873 insertions, 805 deletions
diff --git a/src/static/client.js b/src/static/client.js index 7397735c..72fa9cc2 100644 --- a/src/static/client.js +++ b/src/static/client.js @@ -5,13 +5,9 @@ // // Upd8: As of 04/02/2021, it's now used for info cards too! Nice. -import { - getColors -} from '../util/colors.js'; +import { getColors } from "../util/colors.js"; -import { - getArtistNumContributions -} from '../util/wiki-data.js'; +import { getArtistNumContributions } from "../util/wiki-data.js"; let albumData, artistData, flashData; let officialAlbumData, fandomAlbumData, artistNames; @@ -20,190 +16,235 @@ let ready = false; // Localiz8tion nonsense ---------------------------------- -const language = document.documentElement.getAttribute('lang'); +const language = document.documentElement.getAttribute("lang"); let list; -if ( - typeof Intl === 'object' && - typeof Intl.ListFormat === 'function' -) { - const getFormat = type => { - const formatter = new Intl.ListFormat(language, {type}); - return formatter.format.bind(formatter); - }; - - list = { - conjunction: getFormat('conjunction'), - disjunction: getFormat('disjunction'), - unit: getFormat('unit') - }; +if (typeof Intl === "object" && typeof Intl.ListFormat === "function") { + const getFormat = (type) => { + const formatter = new Intl.ListFormat(language, { type }); + return formatter.format.bind(formatter); + }; + + list = { + conjunction: getFormat("conjunction"), + disjunction: getFormat("disjunction"), + unit: getFormat("unit"), + }; } else { - // Not a gr8 mock we've got going here, 8ut it's *mostly* language-free. - // We use the same mock for every list 'cuz we don't have any of the - // necessary CLDR info to appropri8tely distinguish 8etween them. - const arbitraryMock = array => array.join(', '); - - list = { - conjunction: arbitraryMock, - disjunction: arbitraryMock, - unit: arbitraryMock - }; + // Not a gr8 mock we've got going here, 8ut it's *mostly* language-free. + // We use the same mock for every list 'cuz we don't have any of the + // necessary CLDR info to appropri8tely distinguish 8etween them. + const arbitraryMock = (array) => array.join(", "); + + list = { + conjunction: arbitraryMock, + disjunction: arbitraryMock, + unit: arbitraryMock, + }; } // Miscellaneous helpers ---------------------------------- -function rebase(href, rebaseKey = 'rebaseLocalized') { - const relative = (document.documentElement.dataset[rebaseKey] || '.') + '/'; - if (relative) { - return relative + href; - } else { - return href; - } +function rebase(href, rebaseKey = "rebaseLocalized") { + const relative = (document.documentElement.dataset[rebaseKey] || ".") + "/"; + if (relative) { + return relative + href; + } else { + return href; + } } function pick(array) { - return array[Math.floor(Math.random() * array.length)]; + return array[Math.floor(Math.random() * array.length)]; } function cssProp(el, key) { - return getComputedStyle(el).getPropertyValue(key).trim(); + return getComputedStyle(el).getPropertyValue(key).trim(); } function getRefDirectory(ref) { - return ref.split(':')[1]; + return ref.split(":")[1]; } function getAlbum(el) { - const directory = cssProp(el, '--album-directory'); - return albumData.find(album => album.directory === directory); + const directory = cssProp(el, "--album-directory"); + return albumData.find((album) => album.directory === directory); } function getFlash(el) { - const directory = cssProp(el, '--flash-directory'); - return flashData.find(flash => flash.directory === directory); + const directory = cssProp(el, "--flash-directory"); + return flashData.find((flash) => flash.directory === directory); } // TODO: These should pro8a8ly access some shared urlSpec path. We'd need to // separ8te the tooling around that into common-shared code too. const getLinkHref = (type, directory) => rebase(`${type}/${directory}`); -const openAlbum = d => rebase(`album/${d}`); -const openTrack = d => rebase(`track/${d}`); -const openArtist = d => rebase(`artist/${d}`); -const openFlash = d => rebase(`flash/${d}`); +const openAlbum = (d) => rebase(`album/${d}`); +const openTrack = (d) => rebase(`track/${d}`); +const openArtist = (d) => rebase(`artist/${d}`); +const openFlash = (d) => rebase(`flash/${d}`); function getTrackListAndIndex() { - const album = getAlbum(document.body); - const directory = cssProp(document.body, '--track-directory'); - if (!directory && !album) return {}; - if (!directory) return {list: album.tracks}; - const trackIndex = album.tracks.findIndex(track => track.directory === directory); - return {list: album.tracks, index: trackIndex}; + const album = getAlbum(document.body); + const directory = cssProp(document.body, "--track-directory"); + if (!directory && !album) return {}; + if (!directory) return { list: album.tracks }; + const trackIndex = album.tracks.findIndex( + (track) => track.directory === directory + ); + return { list: album.tracks, index: trackIndex }; } function openRandomTrack() { - const { list } = getTrackListAndIndex(); - if (!list) return; - return openTrack(pick(list)); + const { list } = getTrackListAndIndex(); + if (!list) return; + return openTrack(pick(list)); } function getFlashListAndIndex() { - const list = flashData.filter(flash => !flash.act8r8k) - const flash = getFlash(document.body); - if (!flash) return {list}; - const flashIndex = list.indexOf(flash); - return {list, index: flashIndex}; + const list = flashData.filter((flash) => !flash.act8r8k); + const flash = getFlash(document.body); + if (!flash) return { list }; + const flashIndex = list.indexOf(flash); + return { list, index: flashIndex }; } // TODO: This should also use urlSpec. function fetchData(type, directory) { - return fetch(rebase(`${type}/${directory}/data.json`, 'rebaseData')) - .then(res => res.json()); + return fetch(rebase(`${type}/${directory}/data.json`, "rebaseData")).then( + (res) => res.json() + ); } // JS-based links ----------------------------------------- -for (const a of document.body.querySelectorAll('[data-random]')) { - a.addEventListener('click', evt => { - if (!ready) { - evt.preventDefault(); - return; - } - - setTimeout(() => { - a.href = rebase('js-disabled'); - }); - switch (a.dataset.random) { - case 'album': return a.href = openAlbum(pick(albumData).directory); - case 'album-in-fandom': return a.href = openAlbum(pick(fandomAlbumData).directory); - case 'album-in-official': return a.href = openAlbum(pick(officialAlbumData).directory); - case 'track': return a.href = openTrack(getRefDirectory(pick(albumData.map(a => a.tracks).reduce((a, b) => a.concat(b), [])))); - case 'track-in-album': return a.href = openTrack(getRefDirectory(pick(getAlbum(a).tracks))); - case 'track-in-fandom': return a.href = openTrack(getRefDirectory(pick(fandomAlbumData.reduce((acc, album) => acc.concat(album.tracks), [])))); - case 'track-in-official': return a.href = openTrack(getRefDirectory(pick(officialAlbumData.reduce((acc, album) => acc.concat(album.tracks), [])))); - case 'artist': return a.href = openArtist(pick(artistData).directory); - case 'artist-more-than-one-contrib': return a.href = openArtist(pick(artistData.filter(artist => getArtistNumContributions(artist) > 1)).directory); - } +for (const a of document.body.querySelectorAll("[data-random]")) { + a.addEventListener("click", (evt) => { + if (!ready) { + evt.preventDefault(); + return; + } + + setTimeout(() => { + a.href = rebase("js-disabled"); }); + switch (a.dataset.random) { + case "album": + return (a.href = openAlbum(pick(albumData).directory)); + case "album-in-fandom": + return (a.href = openAlbum(pick(fandomAlbumData).directory)); + case "album-in-official": + return (a.href = openAlbum(pick(officialAlbumData).directory)); + case "track": + return (a.href = openTrack( + getRefDirectory( + pick( + albumData.map((a) => a.tracks).reduce((a, b) => a.concat(b), []) + ) + ) + )); + case "track-in-album": + return (a.href = openTrack(getRefDirectory(pick(getAlbum(a).tracks)))); + case "track-in-fandom": + return (a.href = openTrack( + getRefDirectory( + pick( + fandomAlbumData.reduce( + (acc, album) => acc.concat(album.tracks), + [] + ) + ) + ) + )); + case "track-in-official": + return (a.href = openTrack( + getRefDirectory( + pick( + officialAlbumData.reduce( + (acc, album) => acc.concat(album.tracks), + [] + ) + ) + ) + )); + case "artist": + return (a.href = openArtist(pick(artistData).directory)); + case "artist-more-than-one-contrib": + return (a.href = openArtist( + pick( + artistData.filter((artist) => getArtistNumContributions(artist) > 1) + ).directory + )); + } + }); } -const next = document.getElementById('next-button'); -const previous = document.getElementById('previous-button'); -const random = document.getElementById('random-button'); +const next = document.getElementById("next-button"); +const previous = document.getElementById("previous-button"); +const random = document.getElementById("random-button"); const prependTitle = (el, prepend) => { - const existing = el.getAttribute('title'); - if (existing) { - el.setAttribute('title', prepend + ' ' + existing); - } else { - el.setAttribute('title', prepend); - } + const existing = el.getAttribute("title"); + if (existing) { + el.setAttribute("title", prepend + " " + existing); + } else { + el.setAttribute("title", prepend); + } }; -if (next) prependTitle(next, '(Shift+N)'); -if (previous) prependTitle(previous, '(Shift+P)'); -if (random) prependTitle(random, '(Shift+R)'); - -document.addEventListener('keypress', event => { - if (event.shiftKey) { - if (event.charCode === 'N'.charCodeAt(0)) { - if (next) next.click(); - } else if (event.charCode === 'P'.charCodeAt(0)) { - if (previous) previous.click(); - } else if (event.charCode === 'R'.charCodeAt(0)) { - if (random && ready) random.click(); - } +if (next) prependTitle(next, "(Shift+N)"); +if (previous) prependTitle(previous, "(Shift+P)"); +if (random) prependTitle(random, "(Shift+R)"); + +document.addEventListener("keypress", (event) => { + if (event.shiftKey) { + if (event.charCode === "N".charCodeAt(0)) { + if (next) next.click(); + } else if (event.charCode === "P".charCodeAt(0)) { + if (previous) previous.click(); + } else if (event.charCode === "R".charCodeAt(0)) { + if (random && ready) random.click(); } + } }); -for (const reveal of document.querySelectorAll('.reveal')) { - reveal.addEventListener('click', event => { - if (!reveal.classList.contains('revealed')) { - reveal.classList.add('revealed'); - event.preventDefault(); - event.stopPropagation(); - } - }); +for (const reveal of document.querySelectorAll(".reveal")) { + reveal.addEventListener("click", (event) => { + if (!reveal.classList.contains("revealed")) { + reveal.classList.add("revealed"); + event.preventDefault(); + event.stopPropagation(); + } + }); } -const elements1 = document.getElementsByClassName('js-hide-once-data'); -const elements2 = document.getElementsByClassName('js-show-once-data'); +const elements1 = document.getElementsByClassName("js-hide-once-data"); +const elements2 = document.getElementsByClassName("js-show-once-data"); -for (const element of elements1) element.style.display = 'block'; +for (const element of elements1) element.style.display = "block"; -fetch(rebase('data.json', 'rebaseShared')).then(data => data.json()).then(data => { +fetch(rebase("data.json", "rebaseShared")) + .then((data) => data.json()) + .then((data) => { albumData = data.albumData; artistData = data.artistData; flashData = data.flashData; - officialAlbumData = albumData.filter(album => album.groups.includes('group:official')); - fandomAlbumData = albumData.filter(album => !album.groups.includes('group:official')); - artistNames = artistData.filter(artist => !artist.alias).map(artist => artist.name); + officialAlbumData = albumData.filter((album) => + album.groups.includes("group:official") + ); + fandomAlbumData = albumData.filter( + (album) => !album.groups.includes("group:official") + ); + artistNames = artistData + .filter((artist) => !artist.alias) + .map((artist) => artist.name); - for (const element of elements1) element.style.display = 'none'; - for (const element of elements2) element.style.display = 'block'; + for (const element of elements1) element.style.display = "none"; + for (const element of elements2) element.style.display = "block"; ready = true; -}); + }); // Data & info card --------------------------------------- @@ -216,197 +257,210 @@ let fastHover = false; let endFastHoverTimeout = null; function colorLink(a, color) { - if (color) { - const { primary, dim } = getColors(color); - a.style.setProperty('--primary-color', primary); - a.style.setProperty('--dim-color', dim); - } + if (color) { + const { primary, dim } = getColors(color); + a.style.setProperty("--primary-color", primary); + a.style.setProperty("--dim-color", dim); + } } -function link(a, type, {name, directory, color}) { - colorLink(a, color); - a.innerText = name - a.href = getLinkHref(type, directory); +function link(a, type, { name, directory, color }) { + colorLink(a, color); + a.innerText = name; + a.href = getLinkHref(type, directory); } function joinElements(type, elements) { - // We can't use the Intl APIs with elements, 8ecuase it only oper8tes on - // strings. So instead, we'll pass the element's outer HTML's (which means - // the entire HTML of that element). - // - // That does mean this function returns a string, so always 8e sure to - // set innerHTML when using it (not appendChild). - - return list[type](elements.map(el => el.outerHTML)); + // We can't use the Intl APIs with elements, 8ecuase it only oper8tes on + // strings. So instead, we'll pass the element's outer HTML's (which means + // the entire HTML of that element). + // + // That does mean this function returns a string, so always 8e sure to + // set innerHTML when using it (not appendChild). + + return list[type](elements.map((el) => el.outerHTML)); } const infoCard = (() => { - const container = document.getElementById('info-card-container'); - - let cancelShow = false; - let hideTimeout = null; - let showing = false; - - container.addEventListener('mouseenter', cancelHide); - container.addEventListener('mouseleave', readyHide); - - function show(type, target) { - cancelShow = false; - - fetchData(type, target.dataset[type]).then(data => { - // Manual DOM 'cuz we're laaaazy. - - if (cancelShow) { - return; - } - - showing = true; - - const rect = target.getBoundingClientRect(); - - container.style.setProperty('--primary-color', data.color); - - container.style.top = window.scrollY + rect.bottom + 'px'; - container.style.left = window.scrollX + rect.left + 'px'; - - // Use a short timeout to let a currently hidden (or not yet shown) - // info card teleport to the position set a8ove. (If it's currently - // shown, it'll transition to that position.) - setTimeout(() => { - container.classList.remove('hide'); - container.classList.add('show'); - }, 50); - - // 8asic details. - - const nameLink = container.querySelector('.info-card-name a'); - link(nameLink, 'track', data); - - const albumLink = container.querySelector('.info-card-album a'); - link(albumLink, 'album', data.album); - - const artistSpan = container.querySelector('.info-card-artists span'); - artistSpan.innerHTML = joinElements('conjunction', data.artists.map(({ artist }) => { - const a = document.createElement('a'); - a.href = getLinkHref('artist', artist.directory); - a.innerText = artist.name; - return a; - })); - - const coverArtistParagraph = container.querySelector('.info-card-cover-artists'); - const coverArtistSpan = coverArtistParagraph.querySelector('span'); - if (data.coverArtists.length) { - coverArtistParagraph.style.display = 'block'; - coverArtistSpan.innerHTML = joinElements('conjunction', data.coverArtists.map(({ artist }) => { - const a = document.createElement('a'); - a.href = getLinkHref('artist', artist.directory); - a.innerText = artist.name; - return a; - })); - } else { - coverArtistParagraph.style.display = 'none'; - } - - // Cover art. - - const [ containerNoReveal, containerReveal ] = [ - container.querySelector('.info-card-art-container.no-reveal'), - container.querySelector('.info-card-art-container.reveal') - ]; - - const [ containerShow, containerHide ] = (data.cover.warnings.length - ? [containerReveal, containerNoReveal] - : [containerNoReveal, containerReveal]); - - containerHide.style.display = 'none'; - containerShow.style.display = 'block'; - - const img = containerShow.querySelector('.info-card-art'); - img.src = rebase(data.cover.paths.small, 'rebaseMedia'); - - const imgLink = containerShow.querySelector('a'); - colorLink(imgLink, data.color); - imgLink.href = rebase(data.cover.paths.original, 'rebaseMedia'); - - if (containerShow === containerReveal) { - const cw = containerShow.querySelector('.info-card-art-warnings'); - cw.innerText = list.unit(data.cover.warnings); - - const reveal = containerShow.querySelector('.reveal'); - reveal.classList.remove('revealed'); - } - }); - } - - function hide() { - container.classList.remove('show'); - container.classList.add('hide'); - cancelShow = true; - showing = false; - } - - function readyHide() { - if (!hideTimeout && showing) { - hideTimeout = setTimeout(hide, HIDE_HOVER_DELAY); - } + const container = document.getElementById("info-card-container"); + + let cancelShow = false; + let hideTimeout = null; + let showing = false; + + container.addEventListener("mouseenter", cancelHide); + container.addEventListener("mouseleave", readyHide); + + function show(type, target) { + cancelShow = false; + + fetchData(type, target.dataset[type]).then((data) => { + // Manual DOM 'cuz we're laaaazy. + + if (cancelShow) { + return; + } + + showing = true; + + const rect = target.getBoundingClientRect(); + + container.style.setProperty("--primary-color", data.color); + + container.style.top = window.scrollY + rect.bottom + "px"; + container.style.left = window.scrollX + rect.left + "px"; + + // Use a short timeout to let a currently hidden (or not yet shown) + // info card teleport to the position set a8ove. (If it's currently + // shown, it'll transition to that position.) + setTimeout(() => { + container.classList.remove("hide"); + container.classList.add("show"); + }, 50); + + // 8asic details. + + const nameLink = container.querySelector(".info-card-name a"); + link(nameLink, "track", data); + + const albumLink = container.querySelector(".info-card-album a"); + link(albumLink, "album", data.album); + + const artistSpan = container.querySelector(".info-card-artists span"); + artistSpan.innerHTML = joinElements( + "conjunction", + data.artists.map(({ artist }) => { + const a = document.createElement("a"); + a.href = getLinkHref("artist", artist.directory); + a.innerText = artist.name; + return a; + }) + ); + + const coverArtistParagraph = container.querySelector( + ".info-card-cover-artists" + ); + const coverArtistSpan = coverArtistParagraph.querySelector("span"); + if (data.coverArtists.length) { + coverArtistParagraph.style.display = "block"; + coverArtistSpan.innerHTML = joinElements( + "conjunction", + data.coverArtists.map(({ artist }) => { + const a = document.createElement("a"); + a.href = getLinkHref("artist", artist.directory); + a.innerText = artist.name; + return a; + }) + ); + } else { + coverArtistParagraph.style.display = "none"; + } + + // Cover art. + + const [containerNoReveal, containerReveal] = [ + container.querySelector(".info-card-art-container.no-reveal"), + container.querySelector(".info-card-art-container.reveal"), + ]; + + const [containerShow, containerHide] = data.cover.warnings.length + ? [containerReveal, containerNoReveal] + : [containerNoReveal, containerReveal]; + + containerHide.style.display = "none"; + containerShow.style.display = "block"; + + const img = containerShow.querySelector(".info-card-art"); + img.src = rebase(data.cover.paths.small, "rebaseMedia"); + + const imgLink = containerShow.querySelector("a"); + colorLink(imgLink, data.color); + imgLink.href = rebase(data.cover.paths.original, "rebaseMedia"); + + if (containerShow === containerReveal) { + const cw = containerShow.querySelector(".info-card-art-warnings"); + cw.innerText = list.unit(data.cover.warnings); + + const reveal = containerShow.querySelector(".reveal"); + reveal.classList.remove("revealed"); + } + }); + } + + function hide() { + container.classList.remove("show"); + container.classList.add("hide"); + cancelShow = true; + showing = false; + } + + function readyHide() { + if (!hideTimeout && showing) { + hideTimeout = setTimeout(hide, HIDE_HOVER_DELAY); } + } - function cancelHide() { - if (hideTimeout) { - clearTimeout(hideTimeout); - hideTimeout = null; - } + function cancelHide() { + if (hideTimeout) { + clearTimeout(hideTimeout); + hideTimeout = null; } - - return { - show, - hide, - readyHide, - cancelHide - }; + } + + return { + show, + hide, + readyHide, + cancelHide, + }; })(); function makeInfoCardLinkHandlers(type) { - let hoverTimeout = null; - - return { - mouseenter(evt) { - hoverTimeout = setTimeout(() => { - fastHover = true; - infoCard.show(type, evt.target); - }, fastHover ? FAST_HOVER_INFO_DELAY : NORMAL_HOVER_INFO_DELAY); + let hoverTimeout = null; + + return { + mouseenter(evt) { + hoverTimeout = setTimeout( + () => { + fastHover = true; + infoCard.show(type, evt.target); + }, + fastHover ? FAST_HOVER_INFO_DELAY : NORMAL_HOVER_INFO_DELAY + ); - clearTimeout(endFastHoverTimeout); - endFastHoverTimeout = null; + clearTimeout(endFastHoverTimeout); + endFastHoverTimeout = null; - infoCard.cancelHide(); - }, + infoCard.cancelHide(); + }, - mouseleave(evt) { - clearTimeout(hoverTimeout); + mouseleave(evt) { + clearTimeout(hoverTimeout); - if (fastHover && !endFastHoverTimeout) { - endFastHoverTimeout = setTimeout(() => { - endFastHoverTimeout = null; - fastHover = false; - }, END_FAST_HOVER_DELAY); - } + if (fastHover && !endFastHoverTimeout) { + endFastHoverTimeout = setTimeout(() => { + endFastHoverTimeout = null; + fastHover = false; + }, END_FAST_HOVER_DELAY); + } - infoCard.readyHide(); - } - }; + infoCard.readyHide(); + }, + }; } const infoCardLinkHandlers = { - track: makeInfoCardLinkHandlers('track') + track: makeInfoCardLinkHandlers("track"), }; function addInfoCardLinkHandlers(type) { - for (const a of document.querySelectorAll(`a[data-${type}]`)) { - for (const [ eventName, handler ] of Object.entries(infoCardLinkHandlers[type])) { - a.addEventListener(eventName, handler); - } + for (const a of document.querySelectorAll(`a[data-${type}]`)) { + for (const [eventName, handler] of Object.entries( + infoCardLinkHandlers[type] + )) { + a.addEventListener(eventName, handler); } + } } // Info cards are disa8led for now since they aren't quite ready for release, @@ -415,5 +469,5 @@ function addInfoCardLinkHandlers(type) { // localStorage.tryInfoCards = true; // if (localStorage.tryInfoCards) { - addInfoCardLinkHandlers('track'); + addInfoCardLinkHandlers("track"); } diff --git a/src/static/lazy-loading.js b/src/static/lazy-loading.js index a403d7ca..230dad21 100644 --- a/src/static/lazy-loading.js +++ b/src/static/lazy-loading.js @@ -7,45 +7,45 @@ var observer; function loadImage(image) { - image.src = image.dataset.original; + image.src = image.dataset.original; } function lazyLoad(elements) { - for (var i = 0; i < elements.length; i++) { - var item = elements[i]; - if (item.intersectionRatio > 0) { - observer.unobserve(item.target); - loadImage(item.target); - } + for (var i = 0; i < elements.length; i++) { + var item = elements[i]; + if (item.intersectionRatio > 0) { + observer.unobserve(item.target); + loadImage(item.target); } + } } function lazyLoadMain() { - // This is a live HTMLCollection! We can't iter8te over it normally 'cuz - // we'd 8e mutating its value just 8y interacting with the DOM elements it - // contains. A while loop works just fine, even though you'd think reading - // over this code that this would 8e an infinitely hanging loop. It isn't! - var elements = document.getElementsByClassName('js-hide'); - while (elements.length) { - elements[0].classList.remove('js-hide'); - } + // This is a live HTMLCollection! We can't iter8te over it normally 'cuz + // we'd 8e mutating its value just 8y interacting with the DOM elements it + // contains. A while loop works just fine, even though you'd think reading + // over this code that this would 8e an infinitely hanging loop. It isn't! + var elements = document.getElementsByClassName("js-hide"); + while (elements.length) { + elements[0].classList.remove("js-hide"); + } - var lazyElements = document.getElementsByClassName('lazy'); - if (window.IntersectionObserver) { - observer = new IntersectionObserver(lazyLoad, { - rootMargin: '200px', - threshold: 1.0 - }); - for (var i = 0; i < lazyElements.length; i++) { - observer.observe(lazyElements[i]); - } - } else { - for (var i = 0; i < lazyElements.length; i++) { - var element = lazyElements[i]; - var original = element.getAttribute('data-original'); - element.setAttribute('src', original); - } + var lazyElements = document.getElementsByClassName("lazy"); + if (window.IntersectionObserver) { + observer = new IntersectionObserver(lazyLoad, { + rootMargin: "200px", + threshold: 1.0, + }); + for (var i = 0; i < lazyElements.length; i++) { + observer.observe(lazyElements[i]); + } + } else { + for (var i = 0; i < lazyElements.length; i++) { + var element = lazyElements[i]; + var original = element.getAttribute("data-original"); + element.setAttribute("src", original); } + } } -document.addEventListener('DOMContentLoaded', lazyLoadMain); +document.addEventListener("DOMContentLoaded", lazyLoadMain); diff --git a/src/static/site-basic.css b/src/static/site-basic.css index d26584ae..586f37b5 100644 --- a/src/static/site-basic.css +++ b/src/static/site-basic.css @@ -4,16 +4,16 @@ */ html { - background-color: #222222; - color: white; + background-color: #222222; + color: white; } body { - padding: 15px; + padding: 15px; } main { - background-color: rgba(0, 0, 0, 0.6); - border: 1px dotted white; - padding: 20px; + background-color: rgba(0, 0, 0, 0.6); + border: 1px dotted white; + padding: 20px; } diff --git a/src/static/site.css b/src/static/site.css index e0031351..d80c57c5 100644 --- a/src/static/site.css +++ b/src/static/site.css @@ -4,492 +4,503 @@ */ :root { - --primary-color: #0088ff; + --primary-color: #0088ff; } body { - background: black; - margin: 10px; - overflow-y: scroll; + background: black; + margin: 10px; + overflow-y: scroll; } body::before { - content: ""; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: -1; + content: ""; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: -1; - background-image: url("../media/bg.jpg"); - background-position: center; - background-size: cover; - opacity: 0.5; + background-image: url("../media/bg.jpg"); + background-position: center; + background-size: cover; + opacity: 0.5; } #page-container { - background-color: var(--bg-color, rgba(35, 35, 35, 0.80)); - color: #ffffff; + background-color: var(--bg-color, rgba(35, 35, 35, 0.8)); + color: #ffffff; - max-width: 1100px; - margin: 10px auto 50px; - padding: 15px 0; + max-width: 1100px; + margin: 10px auto 50px; + padding: 15px 0; - box-shadow: 0 0 40px rgba(0, 0, 0, 0.5); + box-shadow: 0 0 40px rgba(0, 0, 0, 0.5); } #page-container > * { - margin-left: 15px; - margin-right: 15px; + margin-left: 15px; + margin-right: 15px; } #banner { - margin: 10px 0; - width: 100%; - background: black; - background-color: var(--dim-color); - border-bottom: 1px solid var(--primary-color); - position: relative; + margin: 10px 0; + width: 100%; + background: black; + background-color: var(--dim-color); + border-bottom: 1px solid var(--primary-color); + position: relative; } #banner::after { - content: ""; - box-shadow: inset 0 -2px 3px rgba(0, 0, 0, 0.35); - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - pointer-events: none; + content: ""; + box-shadow: inset 0 -2px 3px rgba(0, 0, 0, 0.35); + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + pointer-events: none; } #banner.dim img { - opacity: 0.8; + opacity: 0.8; } #banner img { - display: block; - width: 100%; - height: auto; + display: block; + width: 100%; + height: auto; } a { - color: var(--primary-color); - text-decoration: none; + color: var(--primary-color); + text-decoration: none; } a:hover { - text-decoration: underline; + text-decoration: underline; } #skippers { - position: absolute; - left: -10000px; - top: auto; - width: 1px; - height: 1px; + position: absolute; + left: -10000px; + top: auto; + width: 1px; + height: 1px; } #skippers:focus-within { - position: static; - width: unset; - height: unset; + position: static; + width: unset; + height: unset; } #skippers > .skipper:not(:last-child)::after { - content: " \00b7 "; - font-weight: 800; + content: " \00b7 "; + font-weight: 800; } .layout-columns { - display: flex; + display: flex; } -#header, #secondary-nav, #skippers, #footer { - padding: 5px; - font-size: 0.85em; +#header, +#secondary-nav, +#skippers, +#footer { + padding: 5px; + font-size: 0.85em; } -#header, #secondary-nav, #skippers { - margin-bottom: 10px; +#header, +#secondary-nav, +#skippers { + margin-bottom: 10px; } #footer { - margin-top: 10px; + margin-top: 10px; } #header { - display: grid; + display: grid; } #header.nav-has-main-links.nav-has-content { - grid-template-columns: 2.5fr 3fr; - grid-template-rows: min-content 1fr; - grid-template-areas: - "main-links content" - "bottom-row content"; + grid-template-columns: 2.5fr 3fr; + grid-template-rows: min-content 1fr; + grid-template-areas: + "main-links content" + "bottom-row content"; } #header.nav-has-main-links:not(.nav-has-content) { - grid-template-columns: 1fr; - grid-template-areas: - "main-links" - "bottom-row"; + grid-template-columns: 1fr; + grid-template-areas: + "main-links" + "bottom-row"; } .nav-main-links { - grid-area: main-links; - margin-right: 20px; + grid-area: main-links; + margin-right: 20px; } .nav-content { - grid-area: content; + grid-area: content; } .nav-bottom-row { - grid-area: bottom-row; - align-self: start; + grid-area: bottom-row; + align-self: start; } .nav-main-links > span { - white-space: nowrap; + white-space: nowrap; } .nav-main-links > span > a.current { - font-weight: 800; + font-weight: 800; } .nav-links-index > span:not(:first-child):not(.no-divider)::before { - content: "\0020\00b7\0020"; - font-weight: 800; + content: "\0020\00b7\0020"; + font-weight: 800; } .nav-links-hierarchy > span:not(:first-child):not(.no-divider)::before { - content: "\0020/\0020"; + content: "\0020/\0020"; } #header .chronology { - display: block; + display: block; } #header .chronology .heading, #header .chronology .buttons { - display: inline-block; + display: inline-block; } #secondary-nav { - text-align: center; + text-align: center; } #secondary-nav:not(.no-hide) { - display: none; + display: none; } footer { - text-align: center; - font-style: oblique; + text-align: center; + font-style: oblique; } footer > :first-child { - margin-top: 0; + margin-top: 0; } footer > :last-child { - margin-bottom: 0; + margin-bottom: 0; } .footer-localization-links > span:not(:last-child)::after { - content: " \00b7 "; - font-weight: 800; + content: " \00b7 "; + font-weight: 800; } .nowrap { - white-space: nowrap; + white-space: nowrap; } .icons { - font-style: normal; - white-space: nowrap; + font-style: normal; + white-space: nowrap; } .icon { - display: inline-block; - width: 24px; - height: 1em; - position: relative; + display: inline-block; + width: 24px; + height: 1em; + position: relative; } .icon > svg { - width: 24px; - height: 24px; - top: -0.25em; - position: absolute; - fill: var(--primary-color); + width: 24px; + height: 24px; + top: -0.25em; + position: absolute; + fill: var(--primary-color); } .rerelease, .other-group-accent { - opacity: 0.7; - font-style: oblique; + opacity: 0.7; + font-style: oblique; } .other-group-accent { - white-space: nowrap; + white-space: nowrap; } .content-columns { - columns: 2; + columns: 2; } .content-columns .column { - break-inside: avoid; + break-inside: avoid; } .content-columns .column h2 { - margin-top: 0; - font-size: 1em; + margin-top: 0; + font-size: 1em; } -.sidebar, #content, #header, #secondary-nav, #skippers, #footer { - background-color: rgba(0, 0, 0, 0.6); - border: 1px dotted var(--primary-color); - border-radius: 3px; +.sidebar, +#content, +#header, +#secondary-nav, +#skippers, +#footer { + background-color: rgba(0, 0, 0, 0.6); + border: 1px dotted var(--primary-color); + border-radius: 3px; } .sidebar-column { - flex: 1 1 20%; - min-width: 150px; - max-width: 250px; - flex-basis: 250px; - height: 100%; + flex: 1 1 20%; + min-width: 150px; + max-width: 250px; + flex-basis: 250px; + height: 100%; } .sidebar-multiple { - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; } .sidebar-multiple .sidebar:not(:first-child) { - margin-top: 10px; + margin-top: 10px; } .sidebar { - padding: 5px; - font-size: 0.85em; + padding: 5px; + font-size: 0.85em; } #sidebar-left { - margin-right: 10px; + margin-right: 10px; } #sidebar-right { - margin-left: 10px; + margin-left: 10px; } .sidebar.wide { - max-width: 350px; - flex-basis: 300px; - flex-shrink: 0; - flex-grow: 1; + max-width: 350px; + flex-basis: 300px; + flex-shrink: 0; + flex-grow: 1; } #content { - box-sizing: border-box; - padding: 20px; - flex-grow: 1; - flex-shrink: 3; - overflow-wrap: anywhere; + box-sizing: border-box; + padding: 20px; + flex-grow: 1; + flex-shrink: 3; + overflow-wrap: anywhere; } .sidebar > h1, .sidebar > h2, .sidebar > h3, .sidebar > p { - text-align: center; + text-align: center; } .sidebar h1 { - font-size: 1.25em; + font-size: 1.25em; } .sidebar h2 { - font-size: 1.1em; - margin: 0; + font-size: 1.1em; + margin: 0; } .sidebar h3 { - font-size: 1.1em; - font-style: oblique; - font-variant: small-caps; - margin-top: 0.3em; - margin-bottom: 0em; + font-size: 1.1em; + font-style: oblique; + font-variant: small-caps; + margin-top: 0.3em; + margin-bottom: 0em; } .sidebar > p { - margin: 0.5em 0; - padding: 0 5px; + margin: 0.5em 0; + padding: 0 5px; } .sidebar hr { - color: #555; - margin: 10px 5px; + color: #555; + margin: 10px 5px; } -.sidebar > ol, .sidebar > ul { - padding-left: 30px; - padding-right: 15px; +.sidebar > ol, +.sidebar > ul { + padding-left: 30px; + padding-right: 15px; } .sidebar > dl { - padding-right: 15px; - padding-left: 0; + padding-right: 15px; + padding-left: 0; } .sidebar > dl dt { - padding-left: 10px; - margin-top: 0.5em; + padding-left: 10px; + margin-top: 0.5em; } .sidebar > dl dt.current { - font-weight: 800; + font-weight: 800; } .sidebar > dl dd { - margin-left: 0; + margin-left: 0; } .sidebar > dl dd ul { - padding-left: 30px; - margin-left: 0; + padding-left: 30px; + margin-left: 0; } .sidebar > dl .side { - padding-left: 10px; + padding-left: 10px; } .sidebar li.current { - font-weight: 800; + font-weight: 800; } .sidebar li { - overflow-wrap: break-word; + overflow-wrap: break-word; } .sidebar > details.current summary { - font-weight: 800; + font-weight: 800; } .sidebar > details summary { - margin-top: 0.5em; - padding-left: 5px; - user-select: none; + margin-top: 0.5em; + padding-left: 5px; + user-select: none; } .sidebar > details summary .group-name { - color: var(--primary-color); + color: var(--primary-color); } .sidebar > details summary:hover { - cursor: pointer; - text-decoration: underline; - text-decoration-color: var(--primary-color); + cursor: pointer; + text-decoration: underline; + text-decoration-color: var(--primary-color); } .sidebar > details ul, .sidebar > details ol { - margin-top: 0; - margin-bottom: 0; + margin-top: 0; + margin-bottom: 0; } .sidebar > details:last-child { - margin-bottom: 10px; + margin-bottom: 10px; } .sidebar > details[open] { - margin-bottom: 1em; + margin-bottom: 1em; } .sidebar article { - text-align: left; - margin: 5px 5px 15px 5px; + text-align: left; + margin: 5px 5px 15px 5px; } .sidebar article:last-child { - margin-bottom: 5px; + margin-bottom: 5px; } .sidebar article h2, .news-index h2 { - border-bottom: 1px dotted; + border-bottom: 1px dotted; } .sidebar article h2 time, .news-index time { - float: right; - font-weight: normal; + float: right; + font-weight: normal; } #cover-art-container { - float: right; - width: 40%; - max-width: 400px; - margin: 0 0 10px 10px; - font-size: 0.8em; + float: right; + width: 40%; + max-width: 400px; + margin: 0 0 10px 10px; + font-size: 0.8em; } #cover-art img { - display: block; - width: 100%; - height: 100%; + display: block; + width: 100%; + height: 100%; } #cover-art-container p { - margin-top: 5px; + margin-top: 5px; } .image-container { - border: 2px solid var(--primary-color); - box-sizing: border-box; - position: relative; - padding: 5px; - text-align: left; - background-color: var(--dim-color); - color: white; - display: inline-block; - width: 100%; - height: 100%; + border: 2px solid var(--primary-color); + box-sizing: border-box; + position: relative; + padding: 5px; + text-align: left; + background-color: var(--dim-color); + color: white; + display: inline-block; + width: 100%; + height: 100%; } .image-inner-area { - overflow: hidden; - width: 100%; - height: 100%; - position: relative; + overflow: hidden; + width: 100%; + height: 100%; + position: relative; } .image-text-area { - position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - display: flex; - align-items: center; - justify-content: center; - text-align: center; - padding: 5px 15px; - background: rgba(0, 0, 0, 0.65); - box-shadow: 0 0 5px rgba(0, 0, 0, 0.5) inset; - line-height: 1.35em; - color: var(--primary-color); - font-style: oblique; - text-shadow: 0 2px 5px rgba(0, 0, 0, 0.75); + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + padding: 5px 15px; + background: rgba(0, 0, 0, 0.65); + box-shadow: 0 0 5px rgba(0, 0, 0, 0.5) inset; + line-height: 1.35em; + color: var(--primary-color); + font-style: oblique; + text-shadow: 0 2px 5px rgba(0, 0, 0, 0.75); } img { - object-fit: cover; - /* these unfortunately dont take effect while loading, so... + object-fit: cover; + /* these unfortunately dont take effect while loading, so... text-align: center; line-height: 2em; text-shadow: 0 0 5px black; @@ -500,525 +511,528 @@ img { .js-hide, .js-show-once-data, .js-hide-once-data { - display: none; + display: none; } a.box:focus { - outline: 3px double var(--primary-color); + outline: 3px double var(--primary-color); } a.box:focus:not(:focus-visible) { - outline: none; + outline: none; } a.box img { - display: block; - width: 100%; - height: 100%; + display: block; + width: 100%; + height: 100%; } h1 { - font-size: 1.5em; + font-size: 1.5em; } #content li { - margin-bottom: 4px; + margin-bottom: 4px; } #content li i { - white-space: nowrap; + white-space: nowrap; } .grid-listing { - display: flex; - flex-wrap: wrap; - justify-content: center; - align-items: flex-start; + display: flex; + flex-wrap: wrap; + justify-content: center; + align-items: flex-start; } .grid-item { - display: inline-block; - margin: 15px; - text-align: center; - background-color: #111111; - border: 1px dotted var(--primary-color); - border-radius: 2px; - padding: 5px; + display: inline-block; + margin: 15px; + text-align: center; + background-color: #111111; + border: 1px dotted var(--primary-color); + border-radius: 2px; + padding: 5px; } .grid-item img { - width: 100%; - height: 100%; - margin-top: auto; - margin-bottom: auto; + width: 100%; + height: 100%; + margin-top: auto; + margin-bottom: auto; } .grid-item span { - overflow-wrap: break-word; - hyphens: auto; + overflow-wrap: break-word; + hyphens: auto; } .grid-item:hover { - text-decoration: none; + text-decoration: none; } .grid-actions .grid-item:hover { - text-decoration: underline; + text-decoration: underline; } .grid-item > span { - display: block; + display: block; } .grid-item > span:not(:first-child) { - margin-top: 2px; + margin-top: 2px; } .grid-item > span:first-of-type { - margin-top: 6px; + margin-top: 6px; } .grid-item:hover > span:first-of-type { - text-decoration: underline; + text-decoration: underline; } .grid-listing > .grid-item { - flex: 1 1 26%; + flex: 1 1 26%; } .grid-actions { - display: flex; - flex-direction: column; - margin: 15px; - align-self: center; + display: flex; + flex-direction: column; + margin: 15px; + align-self: center; } .grid-actions > .grid-item { - flex-basis: unset !important; - margin: 5px; - --primary-color: inherit !important; - --dim-color: inherit !important; + flex-basis: unset !important; + margin: 5px; + --primary-color: inherit !important; + --dim-color: inherit !important; } .grid-item { - flex-basis: 240px; - min-width: 200px; - max-width: 240px; + flex-basis: 240px; + min-width: 200px; + max-width: 240px; } .grid-item:not(.large-grid-item) { - flex-basis: 180px; - min-width: 120px; - max-width: 180px; - font-size: 0.9em; + flex-basis: 180px; + min-width: 120px; + max-width: 180px; + font-size: 0.9em; } .square { - position: relative; - width: 100%; + position: relative; + width: 100%; } .square::after { - content: ""; - display: block; - padding-bottom: 100%; + content: ""; + display: block; + padding-bottom: 100%; } .square-content { - position: absolute; - width: 100%; - height: 100%; + position: absolute; + width: 100%; + height: 100%; } .vertical-square { - position: relative; - height: 100%; + position: relative; + height: 100%; } .vertical-square::after { - content: ""; - display: block; - padding-right: 100%; + content: ""; + display: block; + padding-right: 100%; } .reveal { - position: relative; - width: 100%; - height: 100%; + position: relative; + width: 100%; + height: 100%; } .reveal img { - filter: blur(20px); - opacity: 0.4; + filter: blur(20px); + opacity: 0.4; } .reveal-text { - color: white; - position: absolute; - top: 15px; - left: 10px; - right: 10px; - text-align: center; - font-weight: bold; + color: white; + position: absolute; + top: 15px; + left: 10px; + right: 10px; + text-align: center; + font-weight: bold; } .reveal-interaction { - opacity: 0.8; + opacity: 0.8; } .reveal.revealed img { - filter: none; - opacity: 1; + filter: none; + opacity: 1; } .reveal.revealed .reveal-text { - display: none; + display: none; } #content.top-index h1, #content.flash-index h1 { - text-align: center; - font-size: 2em; + text-align: center; + font-size: 2em; } #content.flash-index h2 { - text-align: center; - font-size: 2.5em; - font-variant: small-caps; - font-style: oblique; - margin-bottom: 0; - text-align: center; - width: 100%; + text-align: center; + font-size: 2.5em; + font-variant: small-caps; + font-style: oblique; + margin-bottom: 0; + text-align: center; + width: 100%; } #content.top-index h2 { - text-align: center; - font-size: 2em; - font-weight: normal; - margin-bottom: 0.25em; + text-align: center; + font-size: 2em; + font-weight: normal; + margin-bottom: 0.25em; } .quick-info { - text-align: center; + text-align: center; } ul.quick-info { - list-style: none; - padding-left: 0; + list-style: none; + padding-left: 0; } ul.quick-info li { - display: inline-block; + display: inline-block; } ul.quick-info li:not(:last-child)::after { - content: " \00b7 "; - font-weight: 800; + content: " \00b7 "; + font-weight: 800; } #intro-menu { - margin: 24px 0; - padding: 10px; - background-color: #222222; - text-align: center; - border: 1px dotted var(--primary-color); - border-radius: 2px; + margin: 24px 0; + padding: 10px; + background-color: #222222; + text-align: center; + border: 1px dotted var(--primary-color); + border-radius: 2px; } #intro-menu p { - margin: 12px 0; + margin: 12px 0; } #intro-menu a { - margin: 0 6px; + margin: 0 6px; } li .by { - display: inline-block; - font-style: oblique; + display: inline-block; + font-style: oblique; } li .by a { - display: inline-block; + display: inline-block; } p code { - font-size: 1em; - font-family: 'courier new'; - font-weight: 800; + font-size: 1em; + font-family: "courier new"; + font-weight: 800; } blockquote { - margin-left: 40px; - max-width: 600px; - margin-right: 0; + margin-left: 40px; + max-width: 600px; + margin-right: 0; } .long-content { - margin-left: 12%; - margin-right: 12%; + margin-left: 12%; + margin-right: 12%; } p img { - max-width: 100%; - height: auto; + max-width: 100%; + height: auto; } dl dt { - padding-left: 40px; - max-width: 600px; + padding-left: 40px; + max-width: 600px; } dl dt { - margin-bottom: 2px; + margin-bottom: 2px; } dl dd { - margin-bottom: 1em; + margin-bottom: 1em; } -dl ul, dl ol { - margin-top: 0; - margin-bottom: 0; +dl ul, +dl ol { + margin-top: 0; + margin-bottom: 0; } .album-group-list dt { - font-style: oblique; - padding-left: 0; + font-style: oblique; + padding-left: 0; } .album-group-list dd { - margin-left: 0; + margin-left: 0; } .group-chronology-link { - font-style: oblique; + font-style: oblique; } hr.split::before { - content: "(split)"; - color: #808080; + content: "(split)"; + color: #808080; } hr.split { - position: relative; - overflow: hidden; - border: none; + position: relative; + overflow: hidden; + border: none; } hr.split::after { - display: inline-block; - content: ""; - border: 1px inset #808080; - width: 100%; - position: absolute; - top: 50%; - margin-top: -2px; - margin-left: 10px; + display: inline-block; + content: ""; + border: 1px inset #808080; + width: 100%; + position: absolute; + top: 50%; + margin-top: -2px; + margin-left: 10px; } li > ul { - margin-top: 5px; + margin-top: 5px; } #info-card-container { - position: absolute; + position: absolute; - left: 0; - right: 10px; + left: 0; + right: 10px; - pointer-events: none; /* Padding area shouldn't 8e interactive. */ - display: none; + pointer-events: none; /* Padding area shouldn't 8e interactive. */ + display: none; } #info-card-container.show, #info-card-container.hide { - display: flex; + display: flex; } #info-card-container > * { - flex-basis: 400px; + flex-basis: 400px; } #info-card-container.show { - animation: 0.2s linear forwards info-card-show; - transition: top 0.1s, left 0.1s; + animation: 0.2s linear forwards info-card-show; + transition: top 0.1s, left 0.1s; } #info-card-container.hide { - animation: 0.2s linear forwards info-card-hide; + animation: 0.2s linear forwards info-card-hide; } @keyframes info-card-show { - 0% { - opacity: 0; - margin-top: -5px; - } + 0% { + opacity: 0; + margin-top: -5px; + } - 100% { - opacity: 1; - margin-top: 0; - } + 100% { + opacity: 1; + margin-top: 0; + } } @keyframes info-card-hide { - 0% { - opacity: 1; - margin-top: 0; - } + 0% { + opacity: 1; + margin-top: 0; + } - 100% { - opacity: 0; - margin-top: 5px; - display: none !important; - } + 100% { + opacity: 0; + margin-top: 5px; + display: none !important; + } } .info-card-decor { - padding-left: 3ch; - border-top: 1px solid white; + padding-left: 3ch; + border-top: 1px solid white; } .info-card { - background-color: black; - color: white; + background-color: black; + color: white; - border: 1px dotted var(--primary-color); - border-radius: 3px; - box-shadow: 0 5px 5px black; + border: 1px dotted var(--primary-color); + border-radius: 3px; + box-shadow: 0 5px 5px black; - padding: 5px; - font-size: 0.9em; + padding: 5px; + font-size: 0.9em; - pointer-events: none; + pointer-events: none; } .info-card::after { - content: ""; - display: block; - clear: both; + content: ""; + display: block; + clear: both; } #info-card-container.show .info-card { - animation: 0.01s linear 0.2s forwards info-card-become-interactive; + animation: 0.01s linear 0.2s forwards info-card-become-interactive; } @keyframes info-card-become-interactive { - to { - pointer-events: auto; - } + to { + pointer-events: auto; + } } .info-card-art-container { - float: right; + float: right; - width: 40%; - margin: 5px; - font-size: 0.8em; + width: 40%; + margin: 5px; + font-size: 0.8em; - /* Dynamically shown. */ - display: none; + /* Dynamically shown. */ + display: none; } .info-card-art-container .image-container { - padding: 2px; + padding: 2px; } .info-card-art { - display: block; - width: 100%; - height: 100%; + display: block; + width: 100%; + height: 100%; } .info-card-name { - font-size: 1em; - border-bottom: 1px dotted; - margin: 0; + font-size: 1em; + border-bottom: 1px dotted; + margin: 0; } .info-card p { - margin-top: 0.25em; - margin-bottom: 0.25em; + margin-top: 0.25em; + margin-bottom: 0.25em; } .info-card p:last-child { - margin-bottom: 0; + margin-bottom: 0; } @media (max-width: 900px) { - .sidebar-column:not(.no-hide) { - display: none; - } + .sidebar-column:not(.no-hide) { + display: none; + } - #secondary-nav:not(.no-hide) { - display: block; - } + #secondary-nav:not(.no-hide) { + display: block; + } - .layout-columns.vertical-when-thin { - flex-direction: column; - } + .layout-columns.vertical-when-thin { + flex-direction: column; + } - .layout-columns.vertical-when-thin > *:not(:last-child) { - margin-bottom: 10px; - } + .layout-columns.vertical-when-thin > *:not(:last-child) { + margin-bottom: 10px; + } - .sidebar-column.no-hide { - max-width: unset !important; - flex-basis: unset !important; - margin-right: 0 !important; - margin-left: 0 !important; - } + .sidebar-column.no-hide { + max-width: unset !important; + flex-basis: unset !important; + margin-right: 0 !important; + margin-left: 0 !important; + } - .sidebar .news-entry:not(.first-news-entry) { - display: none; - } + .sidebar .news-entry:not(.first-news-entry) { + display: none; + } } @media (max-width: 600px) { - .content-columns { - columns: 1; - } + .content-columns { + columns: 1; + } - #cover-art-container { - float: none; - margin: 0 10px 10px 10px; - margin: 0; - width: 100%; - max-width: unset; - } + #cover-art-container { + float: none; + margin: 0 10px 10px 10px; + margin: 0; + width: 100%; + max-width: unset; + } - #header { - display: block; - } + #header { + display: block; + } - #header > div:not(:first-child) { - margin-top: 0.5em; - } + #header > div:not(:first-child) { + margin-top: 0.5em; + } } /* important easter egg mode */ -html[data-language-code=preview-en][data-url-key="localized.home"] #content h1::after { - font-family: cursive; - display: block; - content: "(Preview Build)"; +html[data-language-code="preview-en"][data-url-key="localized.home"] + #content + h1::after { + font-family: cursive; + display: block; + content: "(Preview Build)"; } -html[data-language-code=preview-en] #header h2 > :first-child::before { - content: "(Preview Build! ✨) "; - animation: preview-notice 4s infinite; +html[data-language-code="preview-en"] #header h2 > :first-child::before { + content: "(Preview Build! ✨) "; + animation: preview-notice 4s infinite; } @keyframes preview-notice { - 0% { - color: #cc5500; - } + 0% { + color: #cc5500; + } - 50% { - color: #ffaa00; - } + 50% { + color: #ffaa00; + } - 100% { - color: #cc5500; - } + 100% { + color: #cc5500; + } } |