From 572047cddb3ac300cf02e5df3167f6942f9e291a Mon Sep 17 00:00:00 2001 From: Kirk Scheibelhut Date: Wed, 8 Nov 2023 21:04:15 -0800 Subject: [PATCH] Overhaul CSS from first principles - empty elements get pruned by the minifier - add CSS reset for improved sanity - switch links to require opt-in .subtle instead of opt-out .default --- package.json | 5 +- src/static/build.ts | 9 +- src/static/index.css | 293 ++++++++++++++---------------------- src/static/layout.html.tmpl | 10 +- src/static/projects.ts | 19 ++- src/static/research.ts | 6 +- 6 files changed, 140 insertions(+), 202 deletions(-) diff --git a/package.json b/package.json index 01bae89..50fa40c 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,9 @@ "extends": [ "stylelint-config-standard", "stylelint-config-clean-order" - ] + ], + "rules": { + "rule-empty-line-before": null + } } } \ No newline at end of file diff --git a/src/static/build.ts b/src/static/build.ts index 649a6c2..574cf6f 100644 --- a/src/static/build.ts +++ b/src/static/build.ts @@ -90,8 +90,7 @@ const make = (name: string, page: Page) => { write(path.join(PUBLIC, name, 'index.html'), render(name, page)); }; -export const topbar = - '
Under Construction: planned completion date January 2024
'; +export const topbar = 'Under Construction: planned completion date January 2024'; interface AstNode {attributes?: {[key: string]: string}} @@ -230,7 +229,7 @@ const build = async (rebuild?: boolean) => { path: `/${page}/`, topbar, title: `${title} | pkmn.ai`, - header: `

${title}

`, + header: title, content: `${toHTML(path.join(STATIC, `${page}.dj`))}`, edit: `${EDIT}/static/${page}.dj`, }); @@ -240,7 +239,7 @@ const build = async (rebuild?: boolean) => { path: '/concepts/', title: 'Concepts | pkmn.ai', topbar, - header: '

Concepts

', + header: 'Concepts', content: `${toHTML(path.join(STATIC, 'concepts', 'index.dj'))}`, edit: `${EDIT}/static/concepts/index.dj`, }); @@ -261,7 +260,7 @@ const build = async (rebuild?: boolean) => { path: `/concepts/${page}/`, title: `Concepts — ${title} | pkmn.ai`, topbar, - header: `

${title}

`, + header: title, content: toHTML(path.join(STATIC, 'concepts', `${page}.dj`)), edit: `${EDIT}/static/concepts/${page}.dj`, }); diff --git a/src/static/index.css b/src/static/index.css index bacda05..4a77474 100644 --- a/src/static/index.css +++ b/src/static/index.css @@ -1,146 +1,101 @@ +/* https://www.joshwcomeau.com/css/custom-css-reset/ */ +*, *::before, *::after { box-sizing: border-box; } +* { margin: 0; } +input, button, textarea, select { font: inherit; } +p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; } +img, picture, video, canvas, svg { + display: block; + max-width: 100%; + height: auto; +} + +html { + font-family: Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 16px; +} + body { display: flex; flex-direction: column; - height: 100dvh; - margin: 0; - - font-family: Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif; + line-height: 1.5; } -.topbar { - font-weight: normal; - font-style: italic; - line-height: 2em; - color: white; - - background-color: black; +p { + margin: 1rem 0; } -h1 { - font-size: calc(var(--header-size) * 3); +a { text-decoration: none; } +a.subtle, a.subtle:visited { color: unset; } +a.subtle:hover, a.subtle:focus, a.subtle:active { + color: unset; + text-decoration: underline; } -h2 { - margin-top: 0; - font-size: calc(var(--header-size) * 1.5); - text-transform: uppercase; +dt { + font-weight: bold; } -h3 { - font-size: calc(var(--header-size) * 1.25); +ul { + margin: 1em 0; } -table, p, .topbar { - font-size: var(--body-size); -} +#topbar { + position: fixed; + top: 0; -nav, footer { - font-size: calc(var(--body-size) * 1.1); -} + width: 100%; -h1, h2 { - margin-bottom: 0.33em; -} + font-weight: normal; + font-style: italic; + line-height: 2; + color: white; -header, header h1 { - font-weight: 900; - text-align: center; + background-color: black; } main { - max-width: var(--max-width); + max-width: 80ch; margin: 0 auto; - padding: 0.5em 8px 0; + padding: 2ch; } -table { - border-spacing: 0; - border-collapse: collapse; - - min-width: 100%; - margin: 0 auto; - - line-height: 1.15em; - text-align: left; -} - -td, th { - padding: 0.33em; -} - -td { - border-top: 1px solid #CDCDCD; -} - -tr:first-child { - border-top: 1px solid black; -} - -td:first-child { - width: 15%; -} - -tr:first-child td { - border: none; +header { + margin: 2.5rem 0 0; + font-weight: 900; + text-align: center; } - -a { - color: unset; - text-decoration: none; +h1 { + font-size: 4em; + font-weight: 900; } - -footer a { - display: inline-flex; - gap: 5px; - padding: 1em 0; - vertical-align: top; +h2 { + margin: 0.33em 0; + font-size: 2em; + text-transform: uppercase; } - -a:visited { - color: unset; - text-decoration: none; +h3 { + margin: 1em 0; + font-size: 1.75em; } -a:hover, a:focus, a:active { +h1 > a, h3 > a, +h1 > a:hover, h3 > a:hover, +h1 > a:focus, h3 > a:focus, +h1 > a:active, h3 > a:active, +h1 > a:visited, h3 > a:visited { color: unset; - text-decoration: underline; -} - -h1 a:hover, h1 a:focus, h1 a:active { text-decoration: none; } -a.default, -a.default:hover, -a.default:visited, -a.default:focus, -a.default:active { - color: revert; -} - -.description { - margin: 2em 0; -} - -p { - line-height: 1.4em; -} - -nav { - text-align: center; -} - nav ul { - margin: 0; padding: 0; list-style: none; } - -nav li { - display: inline-block; -} - +nav { text-align: center; } +nav li { display: inline-block; } +nav label { cursor: pointer; } +nav input:checked + label { font-weight: bold; } nav input { position: absolute; @@ -155,114 +110,94 @@ nav input { clip-path: inset(100%); } -nav label { - cursor: pointer; -} - -nav input:checked + label { - font-weight: bold; +nav, footer { + font-size: 1.1em; } footer { margin-top: auto; - line-height: var(--svg); text-align: center; } - footer img { - width: var(--svg); - height: var(--svg); + display: inline-block; + width: 1.5rem; + height: 1.5rem; +} +footer > *:first-child { + display: inline-flex; + gap: 5px; + padding: 2rem 0; + vertical-align: top; } -#concepts li { - margin-bottom: 0.5em; +table { + border-spacing: 0; + border-collapse: collapse; + + min-width: 100%; + margin: 0 auto; + + line-height: 1.15; + text-align: left; +} +td, th { padding: 0.33rem; } +td { border-top: 1px solid #CDCDCD; } +tr:first-child { border-top: 1px solid black; } +td:first-child { width: 15%; } +tr:first-child td { border: none; } + +.description { + margin: 2em 0; } #research main { max-width: min(900px, 90%); + margin: 1rem auto; + line-height: 1.15; } - #research dl { display: flex; flex-wrap: wrap; } - -.hide { - display: none; -} - -/* Mobile - Small */ -:root { - --max-width: 100%; - --body-size: 10px; - --header-size: 12px; - --svg: var(--header-size); -} - #research dt { - display: none; + display: block; + width: 20%; + padding-right: 2ch; + font-weight: normal; } - #research dd { - width: 100%; - margin-bottom: 1em; + width: 80%; + margin-bottom: 1rem; margin-left: auto; } -#research header, #glossary header { - margin-bottom: 1em; +#concepts li { + margin-bottom: 0.5rem; + line-height: 1.15; } -#glossary dt { - font-weight: bold; +.hide { + display: none; } -#glossary dd { - margin: 0; -} +/* Mobile - Small @media(width < 375px) {} */ /* Mobile - Medium */ -@media(width >= 375px) { - :root { - --max-width: 400px; - --body-size: 12px; - --header-size: 16px; +@media(width < 425px) { + html { + font-size: 0.75em; } } /* Mobile - Large */ -@media(width >= 425px) { - :root { - --max-width: 500px; - --body-size: 13px; - --header-size: 18px; - } -} - -/* Tablet */ -@media(width >= 768px) { - :root { - --max-width: 600px; - --body-size: 15px; - --header-size: 20px; - } -} - -/* Laptop */ -@media(width >= 1024px) { - :root { - --max-width: 700px; - --body-size: 16px; - --header-size: 22px; - --svg: 24px; - } - +@media(width < 768px) { #research dt { - display: block; - width: 20%; + display: none; } #research dd { - width: 80%; + width: 100%; } -} \ No newline at end of file +} + +/* Tablet @media(width < 1024px) {} */ diff --git a/src/static/layout.html.tmpl b/src/static/layout.html.tmpl index e56f66f..62dbd06 100644 --- a/src/static/layout.html.tmpl +++ b/src/static/layout.html.tmpl @@ -23,20 +23,22 @@
- {{{ topbar }}} +
{{{ topbar }}}

pkmn.ai

- {{{ header }}} +

{{{ header }}}

{{{ content }}}
- + + \ No newline at end of file diff --git a/src/static/projects.ts b/src/static/projects.ts index a43419e..97b3e03 100644 --- a/src/static/projects.ts +++ b/src/static/projects.ts @@ -97,13 +97,13 @@ export function page(dir: string) { { const name = project.name ?? `${identifier ?? project.identifier}`; buf.push(project.site - ? `

${name}

` + ? `

${name}

` : `

${name}

`); } buf.push(''); if (project.paper) { const p = bibliography[project.paper]; - const paper = `${p.fields.title[0]}`; + const paper = `${p.fields.title[0]}`; buf.push(``); } buf.push(``); @@ -119,7 +119,7 @@ export function page(dir: string) { if (project.engine) { const engine = Array.isArray(project.engine) ? project.engine.map(({name, url}) => - `${name}`).join(', ') + `${name}`).join(', ') : project.engine as string; buf.push(``); } @@ -130,12 +130,12 @@ export function page(dir: string) { if (project.platform) { const platform = Array.isArray(project.platform) ? project.platform.map(({name, url}) => - `${name}`).join(', ') + `${name}`).join(', ') : project.platform; buf.push(``); } if (project.release) { - const release = `${project.release.name}`; + const release = `${project.release.name}`; buf.push(``); } buf.push('
Paper${paper}
Active${active}
Engine${engine}
Platform${platform}
Latest Release${release}
'); @@ -147,11 +147,11 @@ export function page(dir: string) { return { path: '/projects/', title: 'Projects | pkmn.ai', - header: '

Projects

', + header: 'Projects', content: buf.join(''), edit: 'https://github.com/pkmn/ai/edit/main/src/static/projects.yml', - script: ``, + });`, }; } diff --git a/src/static/research.ts b/src/static/research.ts index 2119146..03e8951 100644 --- a/src/static/research.ts +++ b/src/static/research.ts @@ -48,7 +48,7 @@ function format(e: bibtex.Entry) { parts.push(` (${e.fields.year[0]}) `); parts.push(TYPES[e.type](e)); - const definition = `${parts.join('')}`; + const definition = `${parts.join('')}`; return `
[${id}]
${definition}
`; } @@ -77,8 +77,8 @@ export function page(dir: string) { return { path: '/research/', title: 'Research | pkmn.ai', - header: '

Research

', - content: `
${buf.join('')}
`, + header: 'Research', + content: buf.join(''), edit: 'https://github.com/pkmn/ai/edit/main/src/static/research.bib', }; }