304 lines
8.3 KiB
HTML
304 lines
8.3 KiB
HTML
<!DOCTYPE html>
|
||
<html lang='en'>
|
||
<head>
|
||
<title>gomepage</title>
|
||
<meta charset='utf-8'/>
|
||
<meta name='theme-color' content='#efe5d7'>
|
||
<meta name='viewport' content='width=device-width, initial-scale=1.0, shrink-to-fit=no'/>
|
||
<link rel='icon' type='image/x-icon' href='./favicon.ico'>
|
||
<link rel='preconnect' href='https://fonts.googleapis.com'>
|
||
<link rel='preconnect' href='https://fonts.gstatic.com' crossorigin>
|
||
<link rel='preload' href='https://fonts.googleapis.com/css2?family=Lora:ital@0;1&display=swap' as='style' onload='this.onload=null;this.rel="stylesheet"'>
|
||
<noscript><link rel='stylesheet' href='https://fonts.googleapis.com/css2?family=Lora:ital@0;1&display=swap'></noscript>
|
||
<style>
|
||
html {
|
||
color: #323a42;
|
||
background-color: #efe5d7;
|
||
height: 100%;
|
||
font-family: 'Palatino Linotype', Lora, serif;
|
||
font-size: 1.25em;
|
||
}
|
||
body {
|
||
margin: 0;
|
||
min-height: 100%;
|
||
display: grid;
|
||
grid-template-columns: 1fr min-content;
|
||
grid-template-rows: 1fr auto min-content;
|
||
line-height: 1.2;
|
||
}
|
||
*::selection {
|
||
background: #ebdcc97f;
|
||
}
|
||
header {
|
||
grid-column: 2;
|
||
grid-row: 1 / span 2;
|
||
width: min-content;
|
||
overflow: hidden;
|
||
}
|
||
main {
|
||
grid-column: 1;
|
||
grid-row: 1;
|
||
padding: 1em;
|
||
}
|
||
footer {
|
||
display: flex;
|
||
grid-column: 1 / span 2;
|
||
grid-row: 2 / span 2;
|
||
}
|
||
.title-box, h1, h2, h3, h4, h5, h6 {
|
||
font-weight: normal;
|
||
}
|
||
.title-box {
|
||
position: relative;
|
||
border: 2px solid #323a42;
|
||
border-top: none;
|
||
border-right: none;
|
||
font-size: 48px;
|
||
height: 3em;
|
||
width: 10em;
|
||
background-color: #efe5d7;
|
||
}
|
||
.title-box .title {
|
||
background-color: inherit;
|
||
position: absolute;
|
||
bottom: -13px;
|
||
padding: 0 0.25em 0 0.25em;
|
||
user-select: none;
|
||
}
|
||
nav {
|
||
font-size: 18px;
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
/* this counters the left offset, but adds no real padding */
|
||
padding-right: 1rem;
|
||
left: 1rem;
|
||
right: 0;
|
||
border-bottom: 2px solid #323a42;
|
||
transition: opacity 50ms;
|
||
opacity: 0;
|
||
pointer-events: none;
|
||
}
|
||
nav a {
|
||
margin: 0.25em 0.75em 0.25em 0;
|
||
padding: 0.25em;
|
||
position: relative;
|
||
left: -0.25em;
|
||
color: #323a42;
|
||
text-decoration: none;
|
||
line-height: 1.2;
|
||
border-radius: 2px;
|
||
}
|
||
nav a:first-child {
|
||
margin-top: 1em;
|
||
}
|
||
nav a:last-child {
|
||
margin-bottom: 1em;
|
||
}
|
||
a:hover, a:focus {
|
||
color: #6d747a;
|
||
outline: 0;
|
||
}
|
||
a:focus-visible {
|
||
outline: 1px dashed #beb0b1;
|
||
}
|
||
nav a .link-title {
|
||
font-weight: bold;
|
||
}
|
||
nav a .link-description::before {
|
||
font-weight: normal;
|
||
content: '— ';
|
||
}
|
||
nav a.new .link-title::after {
|
||
content: '*';
|
||
color: #984624;
|
||
}
|
||
nav a.new:hover .link-title::after, nav a.new:focus .link-title::after {
|
||
color: #BF8E7C;
|
||
}
|
||
nav.show, nav:focus-within {
|
||
opacity: 1;
|
||
pointer-events: all;
|
||
}
|
||
.gome-img {
|
||
user-select: none;
|
||
}
|
||
.gome-img[src^='./img/desktop'] {
|
||
width: auto;
|
||
max-width: min(1280px, 100%);
|
||
}
|
||
.gome-img[src^='./img/tablet'] {
|
||
display: none;
|
||
max-width: 100%;
|
||
}
|
||
.gome-img[src^='./img/mobile'] {
|
||
display: none;
|
||
max-width: 100%;
|
||
}
|
||
#wotd {
|
||
font-size: 18px;
|
||
}
|
||
#wotd h3 {
|
||
font-family: Optima, 'Palatino Linotype', Lora, serif;
|
||
font-size: 1.2em;
|
||
margin: 0 0 0.5em 0;
|
||
}
|
||
#wotd .definiendum {
|
||
font-size: 1.5em;
|
||
font-weight: bold;
|
||
margin-bottom: 0.5em;
|
||
}
|
||
#wotd time, #wotd .pronunciation {
|
||
display: block;
|
||
margin-bottom: 1em;
|
||
}
|
||
.pronunciation:not(:empty)::before, .pronunciation:not(:empty)::after {
|
||
content: '⧸';
|
||
}
|
||
#wotd ul {
|
||
margin: 0 0 1em 0;
|
||
padding-left: 0.5em;
|
||
list-style: none;
|
||
}
|
||
#wotd li {
|
||
margin-bottom: 0.25em;
|
||
}
|
||
@media only screen and (max-width: 960px) {
|
||
body {
|
||
grid-template-rows: min-content auto min-content;
|
||
}
|
||
header {
|
||
grid-column: 1 / span 2;
|
||
grid-row: 1;
|
||
width: 100%;
|
||
}
|
||
main {
|
||
grid-row: 2;
|
||
}
|
||
footer {
|
||
grid-row: 3;
|
||
}
|
||
.title-box {
|
||
border-left: none;
|
||
height: 1em;
|
||
width: 100%;
|
||
}
|
||
nav {
|
||
opacity: 1;
|
||
pointer-events: all;
|
||
}
|
||
.gome-img[src^='./img/desktop'] {
|
||
display: none;
|
||
}
|
||
.gome-img[src^='./img/tablet'] {
|
||
display: initial;
|
||
}
|
||
}
|
||
@media only screen and (max-width: 640px) {
|
||
footer {
|
||
align-items: flex-end;
|
||
}
|
||
.gome-img[src^='./img/tablet'] {
|
||
display: none;
|
||
}
|
||
.gome-img[src^='./img/mobile'] {
|
||
display: initial;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<header id='header'>
|
||
<div class='title-box'>
|
||
<span class='title'>gomepage</span>
|
||
</div>
|
||
<nav>
|
||
<a href='journal'><span class='link-title'>Journal</span> <span class='link-description'>a collection of articles, essays, and posts authored by me.</span></a>
|
||
<a href='bookmarks'><span class='link-title'>Bookmarks</span> <span class='link-description'>some curated lists of web pages I want to keep track of and share with others.</span></a>
|
||
<a href='socials' class='new'><span class='link-title'>Socials</span> <span class='link-description'>other accounts of mine around the web.</span></a>
|
||
</nav>
|
||
</header>
|
||
<main>
|
||
<article id='wotd'>
|
||
<h3 class='title'>Word of the day</h3>
|
||
<time class='date'></time>
|
||
<div class='definiendum'></div>
|
||
<div class='pronunciation'></div>
|
||
</article>
|
||
</main>
|
||
<footer>
|
||
<img src='./img/desktop_gomes.webp' class='gome-img' alt='Kabouters at work' />
|
||
<img src='./img/tablet_gomes.webp' class='gome-img' alt='Kabouters at work' />
|
||
<img src='./img/mobile_gome.webp' class='gome-img' alt='Lone kabouter' />
|
||
</footer>
|
||
<script>
|
||
const header = document.querySelector('#header');
|
||
const nav = header.querySelector('nav');
|
||
|
||
const revealNav = () => {
|
||
nav.classList.add('show');
|
||
}
|
||
|
||
const hideNav = () => {
|
||
nav.classList.remove('show');
|
||
}
|
||
|
||
header.addEventListener('click', e => {
|
||
if (!nav.contains(e.target) && nav !== e.target) {
|
||
if (nav.classList.contains('show')) {
|
||
hideNav();
|
||
}
|
||
else if (!nav.classList.contains('show')) {
|
||
revealNav();
|
||
}
|
||
}
|
||
});
|
||
window.addEventListener('click', e => {
|
||
if (!header.contains(e.target) && header !== e.target) {
|
||
hideNav();
|
||
}
|
||
});
|
||
</script>
|
||
<script type='module'>
|
||
const months = ['January','February','March','April','June','July','August','September','October','November','December'];
|
||
const wotd = document.querySelector('#wotd');
|
||
const today = new Date();
|
||
let entry;
|
||
try {
|
||
let day = today.getDate().toString();
|
||
if (day.length === 1) {
|
||
day = '0' + day;
|
||
}
|
||
let month = (today.getMonth() + 1).toString();
|
||
if (month.length === 1) {
|
||
month = '0' + month;
|
||
}
|
||
const response = await fetch(`./wotd/${today.getFullYear()}.${month}.${day}.json`);
|
||
if (!response.ok) {
|
||
throw new Error(`HTTP response ${response.status} ${response.statusText}`);
|
||
}
|
||
entry = await response.json();
|
||
} catch (e) {
|
||
console.error('Word of the Day error:', e);
|
||
}
|
||
if (!entry) {
|
||
document.querySelector('#wotd').remove();
|
||
} else {
|
||
wotd.querySelector('.date').textContent = today.getDate() + ' ' + months[today.getMonth()] + ' ' + today.getFullYear();
|
||
wotd.querySelector('.definiendum').textContent = entry.word;
|
||
wotd.querySelector('.pronunciation').textContent = entry.pronunciation;
|
||
let definitionHTML = '';
|
||
for (const definitionEntry of entry.definitions) {
|
||
definitionHTML += `<h3 class='part-of-speech'>${definitionEntry.part}</h4>`;
|
||
definitionHTML += `<ul class='definitions'>`;
|
||
for (const definition of definitionEntry.definitions) {
|
||
definitionHTML += `<li class='definition'>${definition}</li>`
|
||
}
|
||
definitionHTML += `</ul>`;
|
||
}
|
||
wotd.innerHTML += definitionHTML;
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|