diff --git a/package-lock.json b/package-lock.json index dda9813..4ae9e5f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "": { "dependencies": { "@weborigami/dropbox": "0.0.10", - "@weborigami/origami": "0.1.0", + "@weborigami/origami": "0.2.9", "dotenv": "^16.4.5", "html": "github:jimniels/html", "html-minifier": "^4.0.0", @@ -395,54 +395,55 @@ } }, "node_modules/@weborigami/origami": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@weborigami/origami/-/origami-0.1.0.tgz", - "integrity": "sha512-qtQC1ZOIbQb9XGqNFG93nBUmbJBYeA2A5ExWlG8JYbPudAcmw6JHSKGwjb+oLWpMSckTrHIcxHi4SLJs73WFNg==", + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@weborigami/origami/-/origami-0.2.9.tgz", + "integrity": "sha512-qaKayAV13fCn7Gle9+euTy7mtioTnmLeo59a6OFDSpAppzADJqPfGaGalJfnKznMY9svYRnI2RMCAdxKTF7+tw==", "dependencies": { - "@weborigami/async-tree": "0.1.0", - "@weborigami/language": "0.1.0", - "@weborigami/types": "0.1.0", + "@weborigami/async-tree": "0.2.9", + "@weborigami/language": "0.2.9", + "@weborigami/types": "0.2.9", "exif-parser": "0.1.12", "graphviz-wasm": "3.0.2", - "highlight.js": "11.10.0", - "marked": "14.1.2", - "marked-gfm-heading-id": "4.1.0", - "marked-highlight": "2.1.4", - "marked-smartypants": "1.1.8", + "highlight.js": "11.11.1", + "marked": "15.0.7", + "marked-gfm-heading-id": "4.1.1", + "marked-highlight": "2.2.1", + "marked-smartypants": "1.1.9", "sharp": "0.33.5", - "yaml": "2.5.1" + "yaml": "2.7.0" }, "bin": { "ori": "src/cli/cli.js" } }, "node_modules/@weborigami/origami/node_modules/@weborigami/async-tree": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@weborigami/async-tree/-/async-tree-0.1.0.tgz", - "integrity": "sha512-r83v09iBfMMvCafVKOjGmVWGzthDxeL86YARqlSvDeUgUrID0uBJN6qiDUNrLSa6VlD96u9pbBd4C1t80fPBrA==", + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@weborigami/async-tree/-/async-tree-0.2.9.tgz", + "integrity": "sha512-B3M5pEYXDVYm1Y2RhQlcjEGRHF+dFaKxS3VNLKq1icMTs6uIzrmnx2emDmxDGFK2ULVLJACn4fgytUfPnC9JWg==", "dependencies": { - "@weborigami/types": "0.1.0" + "@weborigami/types": "0.2.9" } }, "node_modules/@weborigami/origami/node_modules/@weborigami/language": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@weborigami/language/-/language-0.1.0.tgz", - "integrity": "sha512-okR9ev9nfDdly6oaEUYsBIrJwwkuoqxt/kypJSkp1Tmlj3T77qwmGFGkYRa8riBWygkeRVNzLmKgQ2CmiGGryA==", + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@weborigami/language/-/language-0.2.9.tgz", + "integrity": "sha512-JxPu690a+9qEvSNwO6fpYZX+cg2ZYx6rlgC0Lopdn48ysA56IttaT01eDNeMuY79VRWJINZDM2Dl3Xi1EaIJ7Q==", "dependencies": { - "@weborigami/async-tree": "0.1.0", - "@weborigami/types": "0.1.0", + "@weborigami/async-tree": "0.2.9", + "@weborigami/types": "0.2.9", "watcher": "2.3.1" } }, "node_modules/@weborigami/origami/node_modules/@weborigami/types": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@weborigami/types/-/types-0.1.0.tgz", - "integrity": "sha512-InGRVeVOFiKI/qPEpW6FdyxMNgeOYeqXZHDW5/3NUazZJvMq+p8wB+OBY4t1ykIgArJlk/Zab0Hy8j9GwjVgXQ==" + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@weborigami/types/-/types-0.2.9.tgz", + "integrity": "sha512-VdV8TvRJQ1BLj2385tesMfXtpF4pYeeuGBjfhNALK9vP8av6/a/j2mwbfIGx2v2dUZ1vXI/XdFv6Q0oEeEwo4g==" }, "node_modules/@weborigami/origami/node_modules/marked": { - "version": "14.1.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-14.1.2.tgz", - "integrity": "sha512-f3r0yqpz31VXiDB/wj9GaOB0a2PRLQl6vJmXiFrniNwjkKdvakqJRULhjFKJpxOchlCRiG5fcacoUZY5Xa6PEQ==", + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.7.tgz", + "integrity": "sha512-dgLIeKGLx5FwziAnsk4ONoGwHwGPJzselimvlVskE9XLN4Orv9u2VA3GWw/lYUqjfA0rUT/6fqKwfZJapP9BEg==", + "license": "MIT", "bin": { "marked": "bin/marked.js" }, @@ -451,14 +452,15 @@ } }, "node_modules/@weborigami/origami/node_modules/marked-gfm-heading-id": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/marked-gfm-heading-id/-/marked-gfm-heading-id-4.1.0.tgz", - "integrity": "sha512-xRvV65Fnpq1krNspnyGsBvP0Y6h7/FrJ6U6y4e6zCWffiC1KxFFxFUKVu8ufMHop2xdvpwyWj5jPeA5W5x/6Zw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/marked-gfm-heading-id/-/marked-gfm-heading-id-4.1.1.tgz", + "integrity": "sha512-EeQZieAQmsI6c2tWLx0ETd0VjPwLV8qi+HT0dIsfVMERm0rCIuXfRvZXJbo1SgUi++lmuR1LVY+QzgNiLNvVpw==", + "license": "MIT", "dependencies": { "github-slugger": "^2.0.0" }, "peerDependencies": { - "marked": ">=13 <15" + "marked": ">=13 <16" } }, "node_modules/@weborigami/types": { @@ -573,7 +575,8 @@ "node_modules/github-slugger": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==" + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" }, "node_modules/graphviz-wasm": { "version": "3.0.2", @@ -593,9 +596,10 @@ } }, "node_modules/highlight.js": { - "version": "11.10.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.10.0.tgz", - "integrity": "sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==", + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "license": "BSD-3-Clause", "engines": { "node": ">=12.0.0" } @@ -646,22 +650,24 @@ } }, "node_modules/marked-highlight": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/marked-highlight/-/marked-highlight-2.1.4.tgz", - "integrity": "sha512-D1GOkcdzP+1dzjoColL7umojefFrASDuLeyaHS0Zr/Uo9jkr1V6vpLRCzfi1djmEaWyK0SYMFtHnpkZ+cwFT1w==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/marked-highlight/-/marked-highlight-2.2.1.tgz", + "integrity": "sha512-SiCIeEiQbs9TxGwle9/OwbOejHCZsohQRaNTY2u8euEXYt2rYUFoiImUirThU3Gd/o6Q1gHGtH9qloHlbJpNIA==", + "license": "MIT", "peerDependencies": { - "marked": ">=4 <15" + "marked": ">=4 <16" } }, "node_modules/marked-smartypants": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/marked-smartypants/-/marked-smartypants-1.1.8.tgz", - "integrity": "sha512-2n8oSjL2gSkH6M0dSdRIyLgqqky03iKQkdmoaylmIzwIhYTW204S7ry6zP2iqwSl0zSlJH2xmWgxlZ/4XB1CdQ==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/marked-smartypants/-/marked-smartypants-1.1.9.tgz", + "integrity": "sha512-VPeuaUr5IWptI7nJdgQ9ugrLWYGv13NdzEXTtKY3cmB4aRWOI2RzhLlf+xQp6Wnob9SAPO2sNVlfSJr+nflk/A==", + "license": "MIT", "dependencies": { "smartypants": "^0.2.2" }, "peerDependencies": { - "marked": ">=4 <15" + "marked": ">=4 <16" } }, "node_modules/no-case": { @@ -786,6 +792,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/smartypants/-/smartypants-0.2.2.tgz", "integrity": "sha512-TzobUYoEft/xBtb2voRPryAUIvYguG0V7Tt3de79I1WfXgCwelqVsGuZSnu3GFGRZhXR90AeEYIM+icuB/S06Q==", + "license": "BSD-3-Clause", "bin": { "smartypants": "bin/smartypants.js", "smartypantsu": "bin/smartypantsu.js" @@ -861,9 +868,10 @@ } }, "node_modules/yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "license": "ISC", "bin": { "yaml": "bin.mjs" }, diff --git a/package.json b/package.json index 15f3ede..f2b6152 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ }, "dependencies": { "@weborigami/dropbox": "0.0.10", - "@weborigami/origami": "0.1.0", + "@weborigami/origami": "0.2.9", "dotenv": "^16.4.5", "html": "github:jimniels/html", "html-minifier": "^4.0.0", diff --git a/src/components/Document.js b/src/components/Document.js new file mode 100644 index 0000000..2ec97c0 --- /dev/null +++ b/src/components/Document.js @@ -0,0 +1,192 @@ +import fs from "fs"; +import html from "html"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { themes } from "../routes/Theme.js"; + +const srcPath = path.dirname(fileURLToPath(import.meta.url)); + +const normalize = fs + .readFileSync( + path.resolve(srcPath, "../../node_modules/normalize.css/normalize.css") + ) + .toString(); + +const importSvg = (file, label) => + fs.readFileSync(path.resolve(srcPath, "../svgs", file)).toString(); + +/** + * + * @param {{ + * site: import("../../types").Site, + * children: string, + * breadcrumbs?: Array<{label: string, href: string}>, + * }} args + * @returns + */ +export default function Document({ site, children, breadcrumbs }) { + const { items } = site; + const activeThemeName = Object.keys(themes)[0]; + const randomNoteId = + site.items[Math.floor(Math.random() * site.items.length)].id; + + return html` + + + + Jim Nielsen’s Notes + + + + + + + + + + + + + + + + + + +
${children}
+ + + + + `; +} + +function Theme({ activeThemeName }) { + return html` + + `; +} diff --git a/src/index.dev.js b/src/index.dev.js deleted file mode 100644 index 0c9dcc0..0000000 --- a/src/index.dev.js +++ /dev/null @@ -1,10 +0,0 @@ -export default async function Index(data) { - // Path to the module with a timestamp to force reload - const modulePath = `./index.js?t=${Date.now()}`; - - // Dynamically import the module - const module = await import(modulePath); - const result = module.default(data); - - return result; -} diff --git a/src/index.js b/src/index.js index 02131be..1c2b440 100644 --- a/src/index.js +++ b/src/index.js @@ -2,6 +2,8 @@ import fs from "fs"; import html from "html"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { themes } from "./routes/Theme.js"; +import Document from "./components/Document.js"; const srcPath = path.dirname(fileURLToPath(import.meta.url)); @@ -14,416 +16,67 @@ const normalize = fs const importSvg = (file, label) => fs.readFileSync(path.resolve(srcPath, "svgs", file)).toString(); -const themes = { - Yamble: { - bg: "#00171f", - text: "#ffffff", - "text-secondary": "#007ea7", - highlight: "#00a8e8", - }, - Halloween: { - bg: "#252422", - text: "#fffcf2", - "text-secondary": "#ccc5b9", - highlight: "#eb5e28", - }, - Cadete: { - bg: "#2b2d42", - text: "#edf2f4", - "text-secondary": "#8d99ae", - highlight: "#ef233c", - }, - Zizzoo: { - bg: "#000000", - text: "#ffffff", - "text-secondary": "#999", - highlight: "#fca311", - }, - Valentines: { - bg: "#590d22", - text: "#fff0f3", - "text-secondary": "#ff8fa3", - highlight: "#ff4d6d", - }, - WWW: { - bg: "#fff", - text: "#000", - "text-secondary": "#999", - highlight: "#0000EE", - }, - Woods: { - bg: "#fefae0", - text: "#283618", - "text-secondary": "#606c38", - highlight: "#bc6c25", - }, - Jazz: { - bg: "#03071e", - text: "#fff9e8", - "text-secondary": "#f48c06", - highlight: "#dc2f02", - }, -}; - -export default function template(items) { +export default function template(items, args = {}) { const activeThemeName = Object.keys(themes)[0]; - return html` - - - - Jim Nielsen’s Notes - - - - - - - - - - - - - - - -
-

Notes

-

- Note-icing the words of others. Fodder for - my blog. -

- ${importSvg("signature.svg")} -
- - - ${ - /* - */ "" - } -
- ${items - .map( - ({ - id, - content_html, - content_text, - date_published, - title, - url, - external_url, - _external_url_domain, - tags, - }) => html` -
-
-

${title}

- -
- ${content_html} - -
- ` - ) - .join("")} -
- +
+

${title}

+

+ + ${_external_url_domain} + +

+
+ ${content_html} + + + ` + ) + .join("")} + `; - - - `; + return Document({ + site: { items }, + children, + breadcrumbs, + }); } function Search(items) { diff --git a/src/postsByDomain.js b/src/postsByDomain.js new file mode 100644 index 0000000..3b05e22 --- /dev/null +++ b/src/postsByDomain.js @@ -0,0 +1,13 @@ +export default function postsByDomain(posts) { + const out = posts.reduce((acc, item) => { + if (acc[item._external_url_domain]) { + acc[item._external_url_domain].push(item); + // acc[item._external_url_domain]++; + } else { + acc[item._external_url_domain] = [item]; + // acc[item._external_url_domain] = 1; + } + return acc; + }, {}); + return out; +} diff --git a/src/routes/Theme.js b/src/routes/Theme.js new file mode 100644 index 0000000..090062f --- /dev/null +++ b/src/routes/Theme.js @@ -0,0 +1,179 @@ +export const themes = { + Yamble: { + bg: "#00171f", + text: "#ffffff", + "text-secondary": "#007ea7", + highlight: "#00a8e8", + }, + Halloween: { + bg: "#252422", + text: "#fffcf2", + "text-secondary": "#ccc5b9", + highlight: "#eb5e28", + }, + Cadete: { + bg: "#2b2d42", + text: "#edf2f4", + "text-secondary": "#8d99ae", + highlight: "#ef233c", + }, + Zizzoo: { + bg: "#000000", + text: "#ffffff", + "text-secondary": "#999", + highlight: "#fca311", + }, + Valentines: { + bg: "#590d22", + text: "#fff0f3", + "text-secondary": "#ff8fa3", + highlight: "#ff4d6d", + }, + WWW: { + bg: "#fff", + text: "#000", + "text-secondary": "#999", + highlight: "#0000EE", + }, + Woods: { + bg: "#fefae0", + text: "#283618", + "text-secondary": "#606c38", + highlight: "#bc6c25", + }, + Jazz: { + bg: "#03071e", + text: "#fff9e8", + "text-secondary": "#f48c06", + highlight: "#dc2f02", + }, +}; + +function Theme({ activeThemeName }) { + return html` + +
+ ${Object.entries(themes) + .map( + ([name, colors]) => html`` + ) + .join("")} +
+ + + `; +} diff --git a/src/site.ori b/src/site.ori index 6b58a64..3650d75 100644 --- a/src/site.ori +++ b/src/site.ori @@ -1,10 +1,186 @@ { - _postData = postData.ori/ - _truncatedPostData = { ..._postData, items: tree:take(_postData/items, 20) } - public = { - index.html = index.dev.js(_postData/items) - favicon.ico - feed.json = origami:json(_truncatedPostData) - feed.xml = site:rss(_truncatedPostData) + (postData) = postData.ori/ + (truncatedPostData) = { ...postData, items: tree:take(postData/items, 20) } + + ...static/ + index.html = index.js(postData/items) + favicon.ico + feed.json = origami:json(truncatedPostData) + feed.xml = site:rss(truncatedPostData) + + id = tree:map(postData/items, { + key: (post) => post/id + value: (post) => { + index.html: index.js([post], { + breadcrumbs: [ + { + label: post/id, + href: "/id/" + post/id + } + ] + }) + } + }) + + // /by/tag|link|year + by = { + index.html = components/Document.js({ + site: { items: postData/items }, + breadcrumbs: [ + { + label: "By", + href: "/by/" + } + ], + children:`

By

+ `}) + + (postsByYear) = tree:reverse(tree:sort(tree:group(postData/items, (post) => post/date_published/slice(0, 4)))) + year = { + index.html: components/Document.js({ + site: { items: postData/items }, + breadcrumbs: [ + { + label: "By", + href: "/by/" + }, + { + label: "Year", + href: "/by/year/" + } + ], + children: ` + + ` + }), + + ...tree:map(postsByYear, { + key: (posts, year) => year + value: (posts, year) => { + index.html: index.js(posts, { + breadcrumbs: [ + { + label: "By", + href: "/by/" + }, + { + label: "Year", + href: "/by/year/" + }, + { + label: `${origami:slash/remove(year)} (${posts/length})`, + href: "/by/year/" + year + } + ] + }) + } + }) + } + + link = { + index.html: components/Document.js({ + site: { items: postData/items }, + breadcrumbs: [ + { + label: "By", + href: "/by/" + }, + { + label: "Link", + href: "/by/link/" + } + ], + children: ` + + + + + + + + + ${tree:map( + tree:reverse(tree:sort(postsByDomain.js(postData/items), (posts) => posts/length),) + (posts, domain) => ` + + + `, + )} + +
LinkCount
${domain}${posts/length}
+ `}), + ...tree:map(postsByDomain.js(postData/items), { + key: (posts, domain) => domain, + value: (posts, domain) => { + index.html: index.js(posts, { + breadcrumbs: [ + { + label: "By", + href: "/by/" + }, + { + label: "Link", + href: "/by/link/" + }, + { + label: `${origami:slash/remove(domain)} (${posts/length})`, + href: "/by/link/" + domain + } + ] + }) + } + }) + } + + (postsByTag) = tree:reverse(tree:sort(tree:group(postData/items, (post) => post/tags), (tags) => tags/length)) + tag = { + index.html: components/Document.js({ + site: { items: postData/items }, + breadcrumbs: [ + { + label: "By", + href: "/by/" + }, + { + label: "Tag", + href: "/by/tag/" + }, + ], + children: ` + + ` + }) + ...tree:map(postsByTag, { + key: (posts, tag) => tag, + value: (posts, tag) => { + index.html: index.js(posts, { + breadcrumbs: [ + { + label: "By", + href: "/by/" + }, + { + label: "Tag", + href: "/by/tag/" + }, + { + label: `${origami:slash/remove(tag)} (${posts/length})`, + href: "/by/tag/" + tag + } + ] + }) + } + }) + } } -}/public +} diff --git a/src/static/styles.css b/src/static/styles.css new file mode 100644 index 0000000..4388ccb --- /dev/null +++ b/src/static/styles.css @@ -0,0 +1,269 @@ +html { + background: var(--c-bg); + scroll-behavior: smooth; +} + +html, +body { + font-size: 1em; +} +body { + font-family: Verdana, "Helvetica Neue", sans-serif; + line-height: 1.5; + width: 90%; + margin: 0 auto; + color: var(--c-text); +} + +main { + max-width: 30rem; +} + +a { + color: inherit; + text-decoration: none; + border-bottom: 1px solid; + transition: 0.1s ease color; +} +a:hover { + color: var(--c-highlight); + border-bottom: 2px solid var(--c-highlight); +} + +pre { + overflow: scroll; +} + +body > header { + margin: 4rem 0 0; + position: relative; +} +body > header h1 { + line-height: 1; + text-indent: 11rem; +} +body > header h1:after { + content: ""; + width: 0.25rem; + height: 1.25em; + background-color: var(--c-highlight); + display: inline-block; + position: relative; + top: 0.2em; + animation: 1s blink step-end infinite; +} +body > header > :is(h1, p) { + margin: 0.5rem 0; + position: relative; + z-index: 1; +} +body > header p { + color: var(--c-text-secondary); + padding-left: 3rem; + line-height: 1.3; +} +body > header svg { + position: absolute; + left: -20px; + top: -30px; + fill: var(--c-highlight); + z-index: 0; +} +@keyframes blink { + from, + to { + opacity: 1; + } + 50% { + opacity: 0; + } +} + +article > header > p { + color: var(--c-text-secondary); + font-size: 0.8125rem; + text-transform: uppercase; + letter-spacing: 0.05rem; + margin-bottom: 0; +} +article > footer { + color: var(--c-text-secondary); + font-size: 0.8125rem; + margin-bottom: 0; +} +article > footer > ul { + display: flex; + list-style-type: none; + gap: 0.5rem; + padding: 0; +} +article > footer > ul li:not(:last-child):after { + content: " · "; + padding: 0 0.25rem; +} + +article header { + display: flex; + flex-direction: column; +} +article header h1 { + order: 2; +} +article h1 { + text-transform: uppercase; + letter-spacing: 0.0125rem; +} +article :is(h1, h2, h3, h4) { + font-size: 1rem; +} +blockquote { + border-left: 1px solid var(--c-highlight); + margin: 0; + padding-left: calc(1.618rem / 2); +} +article { + margin-bottom: 5rem; + padding-top: 5rem; /* enough space when anchoring to a thing */ + overflow-wrap: break-word; +} + +body > footer { + margin: calc(100vh - 6rem) 0 2rem; + color: var(--c-text-secondary); + font-size: 0.75rem; +} + +.highlight { + color: var(--c-highlight); +} + +nav { + display: flex; + flex-direction: column; + gap: 2rem; + z-index: 10; + background: var(--c-bg); + padding: 1rem 0 0.25rem 0; +} +@media screen and (min-width: 800px) { + nav { + gap: 3rem; + flex-direction: row; + align-items: center; + } +} +nav:after { + content: ""; + position: absolute; + width: 100%; + top: 100%; + left: 0; + height: 3rem; + background: linear-gradient(0deg, transparent, var(--c-bg)); + pointer-events: none; +} + +@media screen and (min-width: 600px) { + body { + margin: 0 0 0 2rem; + } +} + +.nav-links { + display: flex; + flex-direction: row; + gap: 0.5rem; + margin: 0; + list-style-type: none; + padding: 0; +} + +.nav-icon { + border: none !important; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + box-shadow: 0 0 0 10px var(--c-bg); + background: var(--c-bg); + transition: 0.3s ease transform; +} +.nav-icon:active { + transform: scale(0.9); +} +.nav-icon:first-child { + z-index: 100; +} + +.nav-icon { + width: 2.75rem; + height: 2.75rem; + display: flex; + align-items: center; + justify-content: center; + + color: var(--c-text-secondary); +} +.nav-icon svg { + transition: 0.3s ease fill; + /* fill: var(--c-bg); */ +} +.nav-icon:hover svg { + fill: var(--c-highlight); +} +.domain a { + color: var(--c-highlight); + border: none; +} +.domain a:hover { + border-bottom: 1px solid var(--c-highlight); +} + +.breadcrumbs { + display: flex; + flex-direction: column; + gap: 0.5rem; + list-style-type: none; + padding: 0; + margin: 0; + color: var(--c-text-secondary); + order: 1; + + /* font-weight: 700; */ +} +.nav-links { + order: 2; +} + +@media screen and (min-width: 800px) { + .breadcrumbs { + flex-direction: row; + flex-wrap: wrap; + } +} + +.breadcrumbs li:last-child { + color: var(--c-text); + font-weight: bold; +} +.breadcrumbs li:not(:last-child):after { + content: " › "; + padding: 0 0.25rem; + font-weight: 400; + opacity: 0.5; +} +.breadcrumbs [aria-current="page"] { + border-bottom: none; + pointer-events: none; +} + +li:has([aria-current="page"]) + li [href="/by/"] { + font-weight: 400; + opacity: 0.5; + text-decoration: none; + border-bottom: none; + + &:hover { + opacity: 1; + } +} diff --git a/src/svgs/heroicon-about.svg b/src/svgs/heroicon-about.svg new file mode 100644 index 0000000..e856f8a --- /dev/null +++ b/src/svgs/heroicon-about.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/svgs/heroicon-home.svg b/src/svgs/heroicon-home.svg new file mode 100644 index 0000000..1332414 --- /dev/null +++ b/src/svgs/heroicon-home.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/svgs/heroicon-shuffle.svg b/src/svgs/heroicon-shuffle.svg new file mode 100644 index 0000000..a86b20e --- /dev/null +++ b/src/svgs/heroicon-shuffle.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/svgs/icon-about.svg b/src/svgs/icon-about.svg new file mode 100644 index 0000000..96a1251 --- /dev/null +++ b/src/svgs/icon-about.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/svgs/icon-home.svg b/src/svgs/icon-home.svg new file mode 100644 index 0000000..34e30f9 --- /dev/null +++ b/src/svgs/icon-home.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/svgs/icon-rss.svg b/src/svgs/icon-rss.svg index 250334a..376cc32 100644 --- a/src/svgs/icon-rss.svg +++ b/src/svgs/icon-rss.svg @@ -1,3 +1 @@ - - - + \ No newline at end of file diff --git a/src/svgs/icon-shuffle.svg b/src/svgs/icon-shuffle.svg index fd6f0dd..e15b864 100644 --- a/src/svgs/icon-shuffle.svg +++ b/src/svgs/icon-shuffle.svg @@ -1,3 +1 @@ - - - + \ No newline at end of file diff --git a/src/svgs/icon-theme.svg b/src/svgs/icon-theme.svg index 1c375bd..088ae12 100644 --- a/src/svgs/icon-theme.svg +++ b/src/svgs/icon-theme.svg @@ -1,3 +1 @@ - - - + \ No newline at end of file diff --git a/types.d.ts b/types.d.ts index 1a65240..fc0d696 100644 --- a/types.d.ts +++ b/types.d.ts @@ -6,6 +6,16 @@ export type Site = { home_page_url: string; feed_url: string; items: Array; + + notesById: Record; + noteIds: Array; + tagsById: Record< + string, + { + postIds: Array; + } + >; + tagIds: Array; }; export type Note = {