From db90e9f452c38f0ebb9a23b51dfe33e1f35c89e0 Mon Sep 17 00:00:00 2001 From: gitea-actions Date: Tue, 21 Jul 2026 12:08:21 +0100 Subject: [PATCH] 21 --- assets/content/comment-pages.json | 30 ++ assets/scripts/pages/house.js | 356 ++++++++++++++ assets/styles/pages/house.css | 601 +++++++++++++++++++++++ blogs/2026/06-june/07-06-week-review.org | 0 blogs/2026/06-june/14-06-week-review.org | 0 blogs/2026/06-june/21-06-week-review.org | 0 blogs/2026/06-june/28-06-week-review.org | 0 blogs/2026/07-july/05-07-week-review.org | 0 blogs/2026/07-july/12-07-week-review.org | 0 blogs/blogs-list.org | 8 + build-logs/gitea-build-monitor.log | 43 ++ home/categories.org | 2 +- lisp/build-assets.el | 2 + play/house.org | 125 +++++ play/play.org | 2 + posts/posts-list.org | 2 +- recently-updated.org | 14 +- sitemap.org | 340 ++++++------- tags/review.org | 6 + 19 files changed, 1354 insertions(+), 177 deletions(-) create mode 100755 assets/scripts/pages/house.js create mode 100755 assets/styles/pages/house.css mode change 100644 => 100755 blogs/2026/06-june/07-06-week-review.org mode change 100644 => 100755 blogs/2026/06-june/14-06-week-review.org mode change 100644 => 100755 blogs/2026/06-june/21-06-week-review.org mode change 100644 => 100755 blogs/2026/06-june/28-06-week-review.org mode change 100644 => 100755 blogs/2026/07-july/05-07-week-review.org mode change 100644 => 100755 blogs/2026/07-july/12-07-week-review.org create mode 100755 play/house.org diff --git a/assets/content/comment-pages.json b/assets/content/comment-pages.json index a13aaa6..b46ed92 100755 --- a/assets/content/comment-pages.json +++ b/assets/content/comment-pages.json @@ -379,11 +379,41 @@ "title": "Working on Eid day", "url": "/blogs/2026/05-may/working-on-eid-day-27-05-26.html" }, + { + "slug": "07-06-26-week-review", + "title": "[07-06-2026] - Weekly Review", + "url": "/blogs/2026/06-june/07-06-week-review.html" + }, + { + "slug": "14-06-26-week-review", + "title": "[14-06-2026] - Weekly Review", + "url": "/blogs/2026/06-june/14-06-week-review.html" + }, + { + "slug": "21-06-26-week-review", + "title": "[21-06-2026] - Weekly Review", + "url": "/blogs/2026/06-june/21-06-week-review.html" + }, + { + "slug": "28-06-26-week-review", + "title": "[28-06-2026] - Weekly Review", + "url": "/blogs/2026/06-june/28-06-week-review.html" + }, { "slug": "cleaning-up-the-repos", "title": "Cleaning up the repos", "url": "/blogs/2026/06-june/cleaning-up-the-repos.html" }, + { + "slug": "05-07-26-week-review", + "title": "[05-07-2026] - Weekly Review", + "url": "/blogs/2026/07-july/05-07-week-review.html" + }, + { + "slug": "12-07-26-week-review", + "title": "[12-07-2026] - Weekly Review", + "url": "/blogs/2026/07-july/12-07-week-review.html" + }, { "slug": "publish-pages", "title": "How to publish pages using Org Publish", diff --git a/assets/scripts/pages/house.js b/assets/scripts/pages/house.js new file mode 100755 index 0000000..8ef6e0b --- /dev/null +++ b/assets/scripts/pages/house.js @@ -0,0 +1,356 @@ +(function () { + "use strict"; + + const STORAGE_KEY = "zxh_house_of_pages_v1"; + const MAIN_ROOM_IDS = Object.freeze([ + "foyer", "library", "study", "kitchen", "workshop", "playroom", "attic", "garden" + ]); + + const ROOMS = Object.freeze({ + foyer: room({ + title: "Foyer", + eyebrow: "Arrivals", + description: "The front door opens onto the newest corners of the site.", + caption: "A brass key waits in a blue bowl beside the door.", + curated: [ + ["Home", "/"], + ["Recently updated", "/recently-updated.html"], + ["Contact", "/home/contact.html"] + ], + include: ["/recently-updated.html", "/home/contact.html"] + }), + library: room({ + title: "Library", + eyebrow: "Knowledge", + description: "Notes and lasting ideas gather here, arranged less strictly than the shelves suggest.", + caption: "One book has been returned with a pressed leaf instead of a bookmark.", + curated: [ + ["All posts", "/posts/posts-list.html"], + ["Categories", "/home/categories.html"], + ["Posts introduction", "/posts/posts-intro.html"] + ], + include: ["/posts/"], + exclude: ["/posts/career/"] + }), + study: room({ + title: "Study", + eyebrow: "Work", + description: "Engineering notes, professional lessons, and active competencies cover the desk.", + caption: "The lamp is still warm; somebody meant to come back after tea.", + curated: [ + ["Career library", "/posts/career/career-list.html"], + ["Competency status", "/home/status.html"], + ["Probation objectives", "/posts/career/probation-objectives.html"] + ], + include: ["/posts/career/"] + }), + kitchen: room({ + title: "Kitchen", + eyebrow: "Daily life", + description: "Weekly reviews and ordinary days stay close to the kettle.", + caption: "A shopping list shares the table with a thought worth keeping.", + curated: [ + ["All blogs", "/blogs/blogs-list.html"], + ["Weekly reviews", "/tags/review.html"], + ["Blog introduction", "/blogs/blogs-intro.html"] + ], + include: ["/blogs/"] + }), + workshop: room({ + title: "Workshop", + eyebrow: "Living systems", + description: "Trackers, services, plans, and practical machinery keep the house running.", + caption: "Every drawer is labelled except the one containing all the labels.", + curated: [ + ["Services", "/home/services.html"], + ["Wird tracker", "/home/wird-tracker.html"], + ["Countdowns", "/home/countdown.html"], + ["Backlog", "/home/backlog.html"] + ], + include: ["/home/services.html", "/home/wird-tracker.html", "/home/countdown.html", "/home/backlog.html"] + }), + playroom: room({ + title: "Playroom", + eyebrow: "Experiments", + description: "Games, generators, puzzles, and stranger little mechanisms wait on the floor.", + caption: "A wooden moon rolls beneath the cabinet whenever nobody is looking.", + curated: [ + ["Play hub", "/play/play.html"], + ["Ash Below the Lake", "/play/rpg.html"], + ["The Rain Index", "/play/the-rain-index.html"] + ], + include: ["/play/"], + exclude: ["/play/house.html", "/play/play.html"] + }), + attic: room({ + title: "Attic", + eyebrow: "Keepsakes", + description: "Personal fragments and older writing rest beneath the roof beams.", + caption: "The smallest box is labelled: things that became important later.", + curated: [ + ["Lima archive", "/lima/index.html"], + ["Blog archive", "/blogs/blogs-list.html"], + ["Memory Cabinet", "/play/memory.html"] + ], + include: ["/lima/", "/blogs/2025/"] + }), + garden: room({ + title: "Garden", + eyebrow: "Notes left outside", + description: "Loose notes, paths between topics, and recently tended pages grow beyond the back step.", + caption: "Someone has tied a question to the pear tree with green thread.", + curated: [ + ["Notes wall", "/home/notes.html"], + ["Categories", "/home/categories.html"], + ["Recently updated", "/recently-updated.html"], + ["Sitemap", "/sitemap.html"] + ], + include: ["/tags/", "/home/notes.html", "/home/categories.html"] + }), + archive: room({ + title: "Archive Room", + eyebrow: "The Ninth Door", + description: "The house keeps one room for the shape of itself: maps, labels, plans, and unfinished intentions.", + caption: "On the inside of the door: A house is an index that learned how to wait.", + curated: [ + ["Sitemap", "/sitemap.html"], + ["Categories", "/home/categories.html"], + ["Backlog", "/home/backlog.html"] + ], + include: ["/sitemap.html", "/home/categories.html", "/home/backlog.html"] + }) + }); + + function room(config) { + return Object.freeze(Object.assign({ exclude: [] }, config, { + curated: Object.freeze(config.curated.map((link) => Object.freeze(link.slice()))), + include: Object.freeze(config.include.slice()), + exclude: Object.freeze((config.exclude || []).slice()) + })); + } + + document.addEventListener("DOMContentLoaded", () => { + const root = document.querySelector('.house-root[data-play-page="house"]'); + if (!root) return; + initHouse(root); + }); + + function initHouse(root) { + const roomButtons = Array.from(root.querySelectorAll("[data-house-room]")); + const mainButtons = roomButtons.filter((button) => MAIN_ROOM_IDS.includes(button.dataset.houseRoom)); + const secretButton = root.querySelector(".house-secret-door"); + const panel = root.querySelector("[data-house-panel]"); + const status = root.querySelector("[data-house-status]"); + const reset = root.querySelector("[data-house-reset]"); + const state = loadState(); + let pages = []; + let indexStatus = "loading"; + + root.classList.add("is-enhanced"); + state.visited = state.visited.filter((id) => MAIN_ROOM_IDS.includes(id)); + if (state.visited.length === MAIN_ROOM_IDS.length) state.secretUnlocked = true; + renderSecret(); + + roomButtons.forEach((button) => { + button.addEventListener("click", () => selectRoom(button.dataset.houseRoom, true)); + button.addEventListener("keydown", (event) => moveRoomFocus(event, button)); + }); + + reset.addEventListener("click", () => { + state.visited = []; + state.secretUnlocked = false; + saveState(state); + roomButtons.forEach((button) => button.classList.remove("is-visited")); + renderSecret(); + selectRoom("foyer", false); + status.textContent = "The house has forgotten this visit. Choose a room to begin again."; + }); + + fetch("/search-index.json", { credentials: "same-origin" }) + .then((response) => { + if (!response.ok) throw new Error(`Search index returned ${response.status}`); + return response.json(); + }) + .then((index) => { + pages = flattenIndex(index); + indexStatus = "ready"; + renderRoom(root.querySelector("[data-house-room][aria-selected='true']")?.dataset.houseRoom || "foyer"); + }) + .catch((error) => { + console.warn("House shelves could not be catalogued", error); + indexStatus = "failed"; + renderRoom(root.querySelector("[data-house-room][aria-selected='true']")?.dataset.houseRoom || "foyer"); + }); + + function selectRoom(id, countVisit) { + const config = ROOMS[id]; + const selected = roomButtons.find((button) => button.dataset.houseRoom === id); + if (!config || !selected) return; + + roomButtons.forEach((button) => { + const active = button === selected; + button.classList.toggle("is-selected", active); + button.setAttribute("aria-selected", String(active)); + button.tabIndex = active ? 0 : -1; + }); + + if (countVisit && MAIN_ROOM_IDS.includes(id) && !state.visited.includes(id)) { + state.visited.push(id); + selected.classList.add("is-visited"); + if (state.visited.length === MAIN_ROOM_IDS.length) state.secretUnlocked = true; + saveState(state); + renderSecret(); + } + + panel.setAttribute("aria-labelledby", selected.id); + root.dataset.houseActive = id; + renderRoom(id); + updateStatus(); + } + + function renderRoom(id) { + const config = ROOMS[id]; + if (!config) return; + root.querySelector("[data-house-eyebrow]").textContent = config.eyebrow; + root.querySelector("[data-house-title]").textContent = config.title; + root.querySelector("[data-house-description]").textContent = config.description; + root.querySelector("[data-house-caption]").textContent = config.caption; + renderLinks(root.querySelector("[data-house-curated]"), config.curated.map(([title, href]) => ({ title, href }))); + + const dynamicList = root.querySelector("[data-house-dynamic]"); + if (indexStatus === "loading") { + renderEmpty(dynamicList, "The shelves are being catalogued…"); + return; + } + if (indexStatus === "failed") { + renderEmpty(dynamicList, "The shelves could not be catalogued today."); + return; + } + + const curatedPaths = new Set(config.curated.map((link) => normalizePath(link[1]))); + const matches = pages + .filter((page) => matchesRoom(page.path, config)) + .filter((page) => !curatedPaths.has(page.path)) + .filter((page) => !isGeneratedListing(page.path)) + .sort((a, b) => a.path.localeCompare(b.path)) + .slice(0, 4); + + if (matches.length === 0) renderEmpty(dynamicList, "Nothing else is resting here yet."); + else renderLinks(dynamicList, matches.map((page) => ({ title: humanizeFilename(page.name), href: page.path }))); + } + + function renderSecret() { + secretButton.hidden = !state.secretUnlocked; + mainButtons.forEach((button) => button.classList.toggle("is-visited", state.visited.includes(button.dataset.houseRoom))); + root.classList.toggle("has-secret", state.secretUnlocked); + } + + function updateStatus() { + if (state.secretUnlocked) { + status.textContent = "All eight rooms remember you. Somewhere nearby, a ninth door has appeared."; + } else { + const remaining = MAIN_ROOM_IDS.length - state.visited.length; + status.textContent = `${state.visited.length} of ${MAIN_ROOM_IDS.length} rooms visited · ${remaining} ${remaining === 1 ? "room" : "rooms"} still unlit.`; + } + } + + function moveRoomFocus(event, current) { + if (!MAIN_ROOM_IDS.includes(current.dataset.houseRoom)) return; + const movement = { ArrowRight: 1, ArrowDown: 1, ArrowLeft: -1, ArrowUp: -1 }[event.key]; + if (!movement) return; + event.preventDefault(); + const index = mainButtons.indexOf(current); + const next = mainButtons[(index + movement + mainButtons.length) % mainButtons.length]; + next.focus(); + selectRoom(next.dataset.houseRoom, true); + } + + selectRoom("foyer", true); + } + + function flattenIndex(root) { + const found = []; + const seen = new Set(); + + function visit(node) { + if (!node || typeof node !== "object") return; + if (node.type === "file" && typeof node.url === "string") { + const path = normalizePath(node.url); + if (path.endsWith(".html") && !seen.has(path)) { + seen.add(path); + found.push({ name: node.name || path.split("/").pop(), path }); + } + } + if (Array.isArray(node.children)) node.children.forEach(visit); + } + + visit(root); + return found; + } + + function matchesRoom(path, config) { + const included = config.include.some((prefix) => path.startsWith(normalizePath(prefix))); + const excluded = config.exclude.some((prefix) => path.startsWith(normalizePath(prefix))); + return included && !excluded && path !== "/play/house.html"; + } + + function isGeneratedListing(path) { + const filename = path.split("/").pop() || ""; + return filename === "index.html" || filename.endsWith("-list.html") || filename.endsWith("-intro.html"); + } + + function humanizeFilename(name) { + return String(name || "Untitled page") + .replace(/\.html$/i, "") + .replace(/^\d{2}-\d{2}-/, "") + .replace(/[._-]+/g, " ") + .replace(/\b\w/g, (letter) => letter.toUpperCase()) + .trim(); + } + + function normalizePath(path) { + const clean = String(path || "").replace(/\\/g, "/").split(/[?#]/)[0]; + return clean.startsWith("/") ? clean : `/${clean}`; + } + + function renderLinks(list, links) { + list.replaceChildren(...links.map(({ title, href }) => { + const item = document.createElement("li"); + const anchor = document.createElement("a"); + anchor.href = href; + anchor.textContent = title; + item.appendChild(anchor); + return item; + })); + } + + function renderEmpty(list, message) { + const item = document.createElement("li"); + item.className = "house-empty"; + item.textContent = message; + list.replaceChildren(item); + } + + function loadState() { + try { + const saved = JSON.parse(localStorage.getItem(STORAGE_KEY) || "{}"); + return { + visited: Array.isArray(saved.visited) ? saved.visited.slice() : [], + secretUnlocked: saved.secretUnlocked === true + }; + } catch (_error) { + return { visited: [], secretUnlocked: false }; + } + } + + function saveState(state) { + try { + localStorage.setItem(STORAGE_KEY, JSON.stringify({ + visited: state.visited, + secretUnlocked: state.secretUnlocked + })); + } catch (_error) { + // The house remains navigable when storage is unavailable. + } + } +})(); diff --git a/assets/styles/pages/house.css b/assets/styles/pages/house.css new file mode 100755 index 0000000..dc17a42 --- /dev/null +++ b/assets/styles/pages/house.css @@ -0,0 +1,601 @@ +.house-root { + --house-ink: #34271e; + --house-wood: #744a2d; + --house-wood-dark: #4a2e20; + --house-plaster: #eadcbf; + --house-lamp: #e7b85a; + --house-green: #607451; + --house-blue: #617789; + --house-rug: #914d3f; + --house-shadow: rgba(43, 29, 18, 0.18); + max-width: 1180px; +} + +.house-heading { + max-width: 760px; +} + +.house-visually-hidden { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +.house-statusbar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 1rem; + margin: 1rem 0; + padding: 0.75rem 1rem; + border: 1px solid color-mix(in oklab, var(--border) 72%, var(--house-wood)); + border-radius: 8px; + background: color-mix(in oklab, var(--surface) 92%, var(--house-lamp) 8%); + box-shadow: 0 8px 24px var(--house-shadow); +} + +.house-statusbar p { + margin: 0; + color: var(--muted); + font-size: 0.92rem; +} + +.house-statusbar button { + flex: 0 0 auto; + min-height: 36px; + padding: 0.4rem 0.7rem; + font-size: 0.84rem; +} + +.house-experience { + display: grid; + grid-template-columns: minmax(0, 1.45fr) minmax(300px, 0.8fr); + gap: 1rem; + align-items: stretch; +} + +.house-illustration, +.house-panel, +.house-directory { + border: 1px solid var(--border); + border-radius: 10px; + background: color-mix(in oklab, var(--surface) 84%, var(--house-plaster) 16%); + box-shadow: 0 20px 50px var(--house-shadow); +} + +.house-illustration { + position: relative; + min-width: 0; + padding: clamp(1rem, 3vw, 2rem); + overflow: hidden; + background: + radial-gradient(circle at 14% 14%, rgba(255, 255, 255, 0.42) 0 2px, transparent 3px), + linear-gradient(to bottom, color-mix(in oklab, var(--surface) 68%, var(--house-blue) 32%) 0 34%, color-mix(in oklab, var(--surface) 76%, var(--house-green) 24%) 34% 100%); +} + +.house-illustration::after { + content: ""; + position: absolute; + right: -8%; + bottom: -10%; + width: 42%; + aspect-ratio: 1; + border-radius: 50% 50% 8% 8%; + background: color-mix(in oklab, var(--house-green) 78%, transparent); + opacity: 0.45; + pointer-events: none; +} + +.house-roof { + position: relative; + z-index: 2; + width: 82%; + height: 85px; + margin: 0 auto -2px; + clip-path: polygon(50% 0, 100% 100%, 0 100%); + background: + repeating-linear-gradient(115deg, transparent 0 17px, rgba(255, 255, 255, 0.06) 18px 19px), + linear-gradient(145deg, #5b3427, #351f1b); + filter: drop-shadow(0 10px 10px rgba(30, 18, 12, 0.2)); +} + +.house-chimney { + position: absolute; + right: 19%; + top: 28px; + width: 32px; + height: 45px; + background: #513127; +} + +.house-moon { + position: absolute; + top: 12px; + left: 50%; + color: #f6d98f; + font-size: 1.25rem; + transform: translateX(-50%); + text-shadow: 0 0 14px rgba(246, 217, 143, 0.7); +} + +.house-shell { + position: relative; + z-index: 3; + max-width: 680px; + margin: 0 auto; + border: 8px solid var(--house-wood-dark); + border-bottom-width: 12px; + background: var(--house-wood-dark); + box-shadow: 0 20px 35px rgba(35, 22, 14, 0.3); +} + +.house-floorplan { + display: grid; + grid-template-columns: repeat(6, minmax(0, 1fr)); + grid-template-rows: minmax(105px, 0.75fr) repeat(2, minmax(128px, 1fr)); + gap: 5px; + background: var(--house-wood-dark); +} + +.house-room { + position: relative; + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: flex-end; + min-width: 0; + min-height: 108px; + overflow: hidden; + border: 0; + border-radius: 2px; + padding: 0.75rem; + background: + linear-gradient(90deg, transparent 49%, rgba(82, 53, 33, 0.15) 50%, transparent 51%), + repeating-linear-gradient(0deg, transparent 0 23px, rgba(82, 53, 33, 0.11) 24px 25px), + var(--house-plaster); + color: var(--house-ink); + text-align: left; + isolation: isolate; + transition: filter 180ms ease, transform 180ms ease, box-shadow 180ms ease; +} + +.house-room::before { + content: ""; + position: absolute; + z-index: -1; + top: 14px; + right: 14px; + width: 34px; + height: 46px; + border: 4px solid color-mix(in oklab, var(--house-wood) 80%, transparent); + border-bottom-width: 7px; + background: + linear-gradient(90deg, transparent 44%, rgba(67, 55, 44, 0.25) 45% 55%, transparent 56%), + linear-gradient(0deg, transparent 44%, rgba(67, 55, 44, 0.25) 45% 55%, transparent 56%), + color-mix(in oklab, var(--house-blue) 68%, #fff 32%); + box-shadow: 0 0 18px rgba(244, 207, 125, 0.18); +} + +.house-room::after { + content: ""; + position: absolute; + z-index: -1; + inset: 0; + background: radial-gradient(circle at 70% 25%, rgba(239, 190, 88, 0.55), transparent 42%); + opacity: 0; + transition: opacity 180ms ease; +} + +.house-room:hover, +.house-room.is-selected { + z-index: 2; + background-color: #f1e2c1; + color: var(--house-ink); + transform: translateY(-2px); + box-shadow: inset 0 0 0 3px var(--house-lamp), 0 5px 15px rgba(42, 27, 17, 0.28); +} + +.house-room:hover::after, +.house-room.is-selected::after, +.house-room.is-visited::after { + opacity: 1; +} + +.house-room.is-visited:not(.is-selected) { + box-shadow: inset 0 0 0 2px color-mix(in oklab, var(--house-green) 70%, transparent); +} + +.house-room.is-visited .house-room__name::after { + content: " · lit"; + color: var(--house-green); + font-size: 0.68rem; + letter-spacing: 0.04em; + text-transform: uppercase; +} + +.house-room:focus-visible, +.house-secret-door:focus-visible { + z-index: 4; + outline: 4px solid color-mix(in oklab, var(--house-lamp) 82%, #fff); + outline-offset: -5px; +} + +.house-room__object { + position: absolute; + left: 0.7rem; + top: 0.55rem; + color: color-mix(in oklab, var(--house-wood) 85%, var(--house-ink)); + font-size: clamp(1.35rem, 3vw, 2.1rem); + line-height: 1; + opacity: 0.88; +} + +.house-room__name, +.house-room__hint { + position: relative; + z-index: 1; +} + +.house-room__name { + font-weight: 900; +} + +.house-room__hint { + margin-top: 0.15rem; + font-size: 0.72rem; + opacity: 0.72; +} + +.house-room--attic { + grid-column: 1 / -1; + grid-row: 1; + justify-content: center; + padding-left: 2rem; + background-color: #d7c39d; +} + +.house-room--attic::before { + width: 54px; + height: 32px; + border-radius: 50% 50% 0 0; +} + +.house-room--study { grid-column: 1 / 3; grid-row: 2; } +.house-room--library { grid-column: 3 / 5; grid-row: 2; } +.house-room--foyer { grid-column: 5 / 7; grid-row: 2; background-color: #e5d3ae; } +.house-room--kitchen { grid-column: 1 / 3; grid-row: 3; background-color: #dfcda9; } +.house-room--workshop { grid-column: 3 / 5; grid-row: 3; background-color: #c8c3a5; } +.house-room--playroom { grid-column: 5 / 7; grid-row: 3; background-color: #dbc3ac; } +.house-room--garden { + grid-column: 1 / -1; + grid-row: 4; + min-height: 105px; + background: + radial-gradient(circle at 15% 65%, #bd846f 0 5px, transparent 6px), + radial-gradient(circle at 74% 50%, #dfb36d 0 4px, transparent 5px), + linear-gradient(to bottom, #a9c3be 0 40%, #829260 41% 100%); +} + +.house-room--garden::before { + top: 12px; + right: 12%; + width: 15px; + height: 62px; + border: 0; + border-radius: 50% 50% 10% 10%; + background: #4c633e; + box-shadow: 10px -15px 0 8px #72835a, -9px -7px 0 6px #61784f; +} + +.house-foundation { + display: grid; + grid-template-columns: repeat(4, 1fr); + height: 18px; + gap: 2px; + margin: 0 -8px -12px; + background: #7d6d5c; +} + +.house-foundation span { + border: 1px solid rgba(54, 39, 29, 0.32); +} + +.house-secret-wrap { + position: relative; + z-index: 4; + min-height: 88px; + display: grid; + place-items: center; +} + +.house-secret-door[hidden] { + display: none; +} + +.house-secret-door { + display: grid; + grid-template-columns: auto 1fr; + grid-template-rows: auto auto; + align-items: center; + column-gap: 0.65rem; + width: min(310px, 90%); + min-height: 68px; + border: 1px solid #2c2019; + padding: 0.6rem 0.85rem; + background: + repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.04) 0 2px, transparent 2px 15px), + #3d2920; + color: #f0d8ab; + box-shadow: 0 9px 20px rgba(31, 20, 14, 0.35); + animation: house-door-appears 700ms ease both; +} + +.house-secret-door > span { + grid-row: 1 / 3; + color: var(--house-lamp); + font-size: 1.6rem; +} + +.house-secret-door strong, +.house-secret-door small { + text-align: left; +} + +.house-secret-door small { + opacity: 0.72; +} + +.house-secret-door.is-selected, +.house-secret-door:hover { + background-color: #221813; + color: #fff3d6; + box-shadow: 0 0 0 2px var(--house-lamp), 0 9px 25px rgba(31, 20, 14, 0.5); +} + +.house-panel { + position: relative; + align-self: stretch; + min-height: 610px; + padding: clamp(1.2rem, 3vw, 2rem); + overflow: hidden; + background: + repeating-linear-gradient(0deg, rgba(75, 52, 34, 0.025) 0 1px, transparent 1px 7px), + color-mix(in oklab, var(--surface) 89%, var(--house-plaster) 11%); +} + +.house-panel::after { + content: ""; + position: absolute; + right: -28px; + bottom: -36px; + width: 125px; + height: 125px; + border: 14px solid color-mix(in oklab, var(--house-rug) 58%, transparent); + border-radius: 50%; + opacity: 0.15; + pointer-events: none; +} + +.house-panel__window { + display: grid; + grid-template-columns: repeat(2, 1fr); + grid-template-rows: repeat(2, 1fr); + gap: 3px; + width: 72px; + height: 82px; + margin: 0 0 1.5rem auto; + border: 6px solid var(--house-wood); + background: var(--house-wood); + box-shadow: 0 8px 0 -4px var(--house-wood-dark), 0 0 30px rgba(231, 184, 90, 0.18); +} + +.house-panel__window span { + background: linear-gradient(145deg, #9cb3b7, #f0cf89); +} + +.house-panel__eyebrow { + margin: 0; + color: var(--house-green); + font-size: 0.76rem; + font-weight: 900; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +.house-panel h2 { + margin: 0.2rem 0 0.65rem; + font-size: clamp(1.6rem, 4vw, 2.25rem); +} + +.house-panel__description { + color: var(--fg); +} + +.house-panel__caption { + margin: 1rem 0 1.5rem; + padding-left: 0.8rem; + border-left: 3px solid var(--house-lamp); + color: var(--muted); + font-size: 0.9rem; + font-style: italic; +} + +.house-shelves { + display: grid; + gap: 1.25rem; +} + +.house-shelves h3 { + margin: 0 0 0.5rem; + color: var(--house-wood); + font-size: 0.72rem; + letter-spacing: 0.1em; + text-transform: uppercase; +} + +.house-link-list { + display: grid; + gap: 0.35rem; + margin: 0; + padding: 0; + list-style: none; +} + +.house-link-list li { + border-bottom: 1px solid color-mix(in oklab, var(--border) 65%, transparent); +} + +.house-link-list a, +.house-empty { + display: block; + padding: 0.48rem 0.15rem; +} + +.house-link-list a::after { + content: " ↗"; + color: var(--house-lamp); + opacity: 0; + transition: opacity 130ms ease; +} + +.house-link-list a:hover::after, +.house-link-list a:focus-visible::after { + opacity: 1; +} + +.house-empty { + border-bottom: 0; + color: var(--muted); + font-size: 0.88rem; + font-style: italic; +} + +.house-directory { + margin-top: 1rem; + padding: 0.85rem 1rem; +} + +.house-directory summary { + color: var(--muted); + font-weight: 800; + cursor: pointer; +} + +.house-directory__grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: 0.75rem; + margin-top: 1rem; +} + +.house-directory__grid section { + padding: 0.75rem; + border: 1px solid var(--border); + border-radius: 6px; +} + +.house-directory__grid h2 { + margin: 0 0 0.35rem; + font-size: 1rem; +} + +.house-noscript { + color: var(--muted); + font-style: italic; +} + +@keyframes house-door-appears { + from { opacity: 0; transform: translateY(10px) scale(0.96); } + to { opacity: 1; transform: translateY(0) scale(1); } +} + +@media (max-width: 880px) { + .house-experience { + grid-template-columns: 1fr; + } + + .house-panel { + min-height: auto; + } + + .house-panel__window { + position: absolute; + top: 1.25rem; + right: 1.25rem; + width: 54px; + height: 62px; + } +} + +@media (max-width: 620px) { + .house-statusbar { + align-items: flex-start; + flex-direction: column; + } + + .house-roof, + .house-foundation { + display: none; + } + + .house-shell { + border-width: 5px; + } + + .house-floorplan { + display: grid; + grid-template-columns: 1fr; + grid-template-rows: none; + gap: 4px; + } + + .house-room, + .house-room--attic, + .house-room--study, + .house-room--library, + .house-room--foyer, + .house-room--kitchen, + .house-room--workshop, + .house-room--playroom, + .house-room--garden { + grid-column: 1; + grid-row: auto; + min-height: 92px; + padding-left: 4rem; + justify-content: center; + } + + .house-room__object { + left: 1rem; + top: 50%; + transform: translateY(-50%); + } + + .house-room::before { + top: 20px; + } + + .house-room--garden::before { + right: 18%; + } + + .house-panel__window { + opacity: 0.45; + } +} + +@media (prefers-reduced-motion: reduce) { + .house-room, + .house-room::after, + .house-link-list a::after, + .house-secret-door { + animation: none; + transition: none; + } +} diff --git a/blogs/2026/06-june/07-06-week-review.org b/blogs/2026/06-june/07-06-week-review.org old mode 100644 new mode 100755 diff --git a/blogs/2026/06-june/14-06-week-review.org b/blogs/2026/06-june/14-06-week-review.org old mode 100644 new mode 100755 diff --git a/blogs/2026/06-june/21-06-week-review.org b/blogs/2026/06-june/21-06-week-review.org old mode 100644 new mode 100755 diff --git a/blogs/2026/06-june/28-06-week-review.org b/blogs/2026/06-june/28-06-week-review.org old mode 100644 new mode 100755 diff --git a/blogs/2026/07-july/05-07-week-review.org b/blogs/2026/07-july/05-07-week-review.org old mode 100644 new mode 100755 diff --git a/blogs/2026/07-july/12-07-week-review.org b/blogs/2026/07-july/12-07-week-review.org old mode 100644 new mode 100755 diff --git a/blogs/blogs-list.org b/blogs/blogs-list.org index 583e33c..abfb9b6 100755 --- a/blogs/blogs-list.org +++ b/blogs/blogs-list.org @@ -5,7 +5,15 @@ See the categories: @@html:Categories@@ * 2026 +** July 2026 +- [[file:2026/07-july/12-07-week-review.org][[12-07-2026] - Weekly Review]] @@html:12-07-2026 12:00@@ @@html:@@ +- [[file:2026/07-july/05-07-week-review.org][[05-07-2026] - Weekly Review]] @@html:05-07-2026 12:00@@ @@html:@@ + ** June 2026 +- [[file:2026/06-june/28-06-week-review.org][[28-06-2026] - Weekly Review]] @@html:28-06-2026 12:00@@ @@html:@@ +- [[file:2026/06-june/21-06-week-review.org][[21-06-2026] - Weekly Review]] @@html:21-06-2026 12:00@@ @@html:@@ +- [[file:2026/06-june/14-06-week-review.org][[14-06-2026] - Weekly Review]] @@html:14-06-2026 12:00@@ @@html:@@ +- [[file:2026/06-june/07-06-week-review.org][[07-06-2026] - Weekly Review]] @@html:07-06-2026 12:00@@ @@html:@@ - [[file:2026/06-june/cleaning-up-the-repos.org][Cleaning up the repos]] @@html:04-06-2026 14:37@@ @@html:@@ @@html:@@ ** May 2026 diff --git a/build-logs/gitea-build-monitor.log b/build-logs/gitea-build-monitor.log index 16c53ee..d35a3ef 100755 --- a/build-logs/gitea-build-monitor.log +++ b/build-logs/gitea-build-monitor.log @@ -658,3 +658,46 @@ at , /home/zaine/master-folder/org-platform/org_web/gitea-build-mon 2026-07-15T18:36:42.7249225+01:00 [INFO] Running authoring server tests with /home/zaine/master-folder/org-platform/authoring-service/.venv/bin/python. 2026-07-15T18:36:42.7979760+01:00 [INFO] Authoring server tests passed: ran=0, failures=0, errors=0, skipped=0, exit=0 2026-07-15T18:36:43.2347459+01:00 [INFO] Sent authoring server test notification. +2026-07-15T18:54:15.3923585+01:00 [INFO] Prepared current build status for zaine/org_web: severity=Info, status=success +2026-07-15T18:54:15.3998022+01:00 [INFO] Fetching recent Gitea Actions runs for zaine/org_web. +2026-07-15T18:54:15.7556694+01:00 [ERROR] Failed to analyze job 697: Cannot bind argument to parameter 'LogText' because it is an empty string. +2026-07-15T18:54:16.3562824+01:00 [INFO] Sent build status notification with 1 embed(s). +2026-07-15T18:54:16.3752052+01:00 [INFO] Running authoring server tests with /home/zaine/master-folder/org-platform/authoring-service/.venv/bin/python. +2026-07-15T18:54:16.4405664+01:00 [INFO] Authoring server tests passed: ran=0, failures=0, errors=0, skipped=0, exit=0 +2026-07-15T18:54:16.7593806+01:00 [INFO] Sent authoring server test notification. +2026-07-16T01:00:54.5208678+01:00 [INFO] Prepared current build status for zaine/org_web: severity=Info, status=success +2026-07-16T01:00:54.5294817+01:00 [INFO] Fetching recent Gitea Actions runs for zaine/org_web. +2026-07-16T01:00:55.3375315+01:00 [INFO] Sent build status notification with 1 embed(s). +2026-07-16T01:00:55.3575166+01:00 [INFO] Running authoring server tests with /home/zaine/master-folder/org-platform/authoring-service/.venv/bin/python. +2026-07-16T01:00:55.4333610+01:00 [INFO] Authoring server tests passed: ran=0, failures=0, errors=0, skipped=0, exit=0 +2026-07-16T01:00:56.1645200+01:00 [INFO] Sent authoring server test notification. +2026-07-17T01:00:59.4317782+01:00 [INFO] Prepared current build status for zaine/org_web: severity=Info, status=success +2026-07-17T01:00:59.4393708+01:00 [INFO] Fetching recent Gitea Actions runs for zaine/org_web. +2026-07-17T01:01:00.2781029+01:00 [INFO] Sent build status notification with 1 embed(s). +2026-07-17T01:01:00.2993333+01:00 [INFO] Running authoring server tests with /home/zaine/master-folder/org-platform/authoring-service/.venv/bin/python. +2026-07-17T01:01:00.3733723+01:00 [INFO] Authoring server tests passed: ran=0, failures=0, errors=0, skipped=0, exit=0 +2026-07-17T01:01:00.8044419+01:00 [INFO] Sent authoring server test notification. +2026-07-18T01:01:01.0970239+01:00 [INFO] Prepared current build status for zaine/org_web: severity=Info, status=success +2026-07-18T01:01:01.1048282+01:00 [INFO] Fetching recent Gitea Actions runs for zaine/org_web. +2026-07-18T01:01:01.9544143+01:00 [INFO] Sent build status notification with 1 embed(s). +2026-07-18T01:01:01.9784205+01:00 [INFO] Running authoring server tests with /home/zaine/master-folder/org-platform/authoring-service/.venv/bin/python. +2026-07-18T01:01:02.0568176+01:00 [INFO] Authoring server tests passed: ran=0, failures=0, errors=0, skipped=0, exit=0 +2026-07-18T01:01:02.5166641+01:00 [INFO] Sent authoring server test notification. +2026-07-19T01:01:02.6664532+01:00 [INFO] Prepared current build status for zaine/org_web: severity=Info, status=success +2026-07-19T01:01:02.6739216+01:00 [INFO] Fetching recent Gitea Actions runs for zaine/org_web. +2026-07-19T01:01:03.8312092+01:00 [INFO] Sent build status notification with 1 embed(s). +2026-07-19T01:01:03.8508624+01:00 [INFO] Running authoring server tests with /home/zaine/master-folder/org-platform/authoring-service/.venv/bin/python. +2026-07-19T01:01:03.9270354+01:00 [INFO] Authoring server tests passed: ran=0, failures=0, errors=0, skipped=0, exit=0 +2026-07-19T01:01:04.2481047+01:00 [INFO] Sent authoring server test notification. +2026-07-20T01:01:04.5492804+01:00 [INFO] Prepared current build status for zaine/org_web: severity=Info, status=success +2026-07-20T01:01:04.5579103+01:00 [INFO] Fetching recent Gitea Actions runs for zaine/org_web. +2026-07-20T01:01:05.7835332+01:00 [INFO] Sent build status notification with 1 embed(s). +2026-07-20T01:01:05.8046810+01:00 [INFO] Running authoring server tests with /home/zaine/master-folder/org-platform/authoring-service/.venv/bin/python. +2026-07-20T01:01:05.8827333+01:00 [INFO] Authoring server tests passed: ran=0, failures=0, errors=0, skipped=0, exit=0 +2026-07-20T01:01:06.4329261+01:00 [INFO] Sent authoring server test notification. +2026-07-21T01:00:58.4720051+01:00 [INFO] Prepared current build status for zaine/org_web: severity=Info, status=success +2026-07-21T01:00:58.4798174+01:00 [INFO] Fetching recent Gitea Actions runs for zaine/org_web. +2026-07-21T01:00:59.4390738+01:00 [INFO] Sent build status notification with 1 embed(s). +2026-07-21T01:00:59.4587832+01:00 [INFO] Running authoring server tests with /home/zaine/master-folder/org-platform/authoring-service/.venv/bin/python. +2026-07-21T01:00:59.5350433+01:00 [INFO] Authoring server tests passed: ran=0, failures=0, errors=0, skipped=0, exit=0 +2026-07-21T01:00:59.9886800+01:00 [INFO] Sent authoring server test notification. diff --git a/home/categories.org b/home/categories.org index bd5e677..7d1e74d 100755 --- a/home/categories.org +++ b/home/categories.org @@ -11,6 +11,6 @@ - [[file:../tags/maths.org][@@html:@@]] (1) - [[file:../tags/notes.org][@@html:@@]] (18) - [[file:../tags/reading.org][@@html:@@]] (1) -- [[file:../tags/review.org][@@html:@@]] (35) +- [[file:../tags/review.org][@@html:@@]] (41) - [[file:../tags/update.org][@@html:@@]] (2) - [[file:../tags/website.org][@@html:@@]] (5) \ No newline at end of file diff --git a/lisp/build-assets.el b/lisp/build-assets.el index 2d0e0d9..2889ce7 100755 --- a/lisp/build-assets.el +++ b/lisp/build-assets.el @@ -34,6 +34,7 @@ "wird-tracker.css" "zhd.css" "play.css" + "pages/house.css" "hidden-details.css") "\n") "\n" @@ -59,6 +60,7 @@ "pages/wird-tracker.js" "pages/home-dashboard.js" "pages/play.js" + "pages/house.js" "pages/ash-below-lake.js" "features/hidden-details.js") "\n") diff --git a/play/house.org b/play/house.org new file mode 100755 index 0000000..bb61f1d --- /dev/null +++ b/play/house.org @@ -0,0 +1,125 @@ +#+TITLE: The House of Pages +#+OPTIONS: num:nil title:nil toc:nil +#+NO_SIDENOTES: t +#+DATE: <2026-07-15 Wed> + +#+BEGIN_EXPORT html +
+ Back to Play + +
+

13 / Living archive

+

The House of Pages

+

Every part of the site has found a room. Choose a lit window, follow a familiar passage, and notice the door that is not there yet.

+
+ +
+

Choose a room to begin.

+ +
+ +
+
+ +
+

House floor plan

+
+ + + + + + + + +
+ +
+ +
+ +
+
+ +
+ +

Arrivals

+

Foyer

+

The front door opens onto the newest corners of the site.

+

A brass key waits in a blue bowl beside the door.

+ +
+
+

Kept in this room

+ +
+
+

Found on the shelves

+ +
+
+
+
+ +
+ Plain directory of the house + +
+ + +
+#+END_EXPORT diff --git a/play/play.org b/play/play.org index 7c3899f..40793f5 100755 --- a/play/play.org +++ b/play/play.org @@ -24,6 +24,7 @@ + @@ -54,6 +55,7 @@ 10Sigil Press 11Ash Below the Lake 12The Rain Index + 13The House of Pages #+END_EXPORT diff --git a/posts/posts-list.org b/posts/posts-list.org index 0c7eda0..d9e52cd 100755 --- a/posts/posts-list.org +++ b/posts/posts-list.org @@ -4,7 +4,7 @@ See the categories: @@html:Categories@@ * Posts: -- [[file:career/career-list.org][Career List]] @@html:@@ +- [[file:career/career-list.org][Career List]] @@html:@@ - [[file:career/cross-site-scripting-xss.org][Cross-Site Scripting (XSS)]] @@html:@@ @@html:@@ @@html:@@ - [[file:career/ha-dr.org][High Availability, Disaster Recovery and Business Continuity]] @@html:@@ @@html:@@ @@html:@@ - [[file:career/javascript.org][Understands the Javascript language]] @@html:@@ @@html:@@ @@html:@@ diff --git a/recently-updated.org b/recently-updated.org index 816382d..8c29fb4 100755 --- a/recently-updated.org +++ b/recently-updated.org @@ -2,6 +2,8 @@ #+OPTIONS: toc:nil num:nil * Recently Updated (top 26 files) +- [[file:play/house.org][The House of Pages]] @@html:@@ +- [[file:blogs/2026/07-july/12-07-week-review.org][[12-07-2026] - Weekly Review]] @@html:@@ - [[file:home/wird-tracker.org][Wird Tracker]] @@html:@@ - [[file:home/status.org][Competency Status Board]] @@html:@@ - [[file:home/services.org][Service]] @@html:@@ @@ -10,6 +12,11 @@ - [[file:home/contact.org][Contact]] @@html:@@ - [[file:home/guide/wird-tracker-guide.org][Wird Tracker — Technical Guide]] @@html:@@ - [[file:home/guide/setup.org][Setup]] @@html:@@ +- [[file:blogs/2026/07-july/05-07-week-review.org][[05-07-2026] - Weekly Review]] @@html:@@ +- [[file:blogs/2026/06-june/28-06-week-review.org][[28-06-2026] - Weekly Review]] @@html:@@ +- [[file:blogs/2026/06-june/21-06-week-review.org][[21-06-2026] - Weekly Review]] @@html:@@ +- [[file:blogs/2026/06-june/14-06-week-review.org][[14-06-2026] - Weekly Review]] @@html:@@ +- [[file:blogs/2026/06-june/07-06-week-review.org][[07-06-2026] - Weekly Review]] @@html:@@ - [[file:blogs/2026/06-june/cleaning-up-the-repos.org][Cleaning up the repos]] @@html:@@ - [[file:posts/career/cross-site-scripting-xss.org][Cross-Site Scripting (XSS)]] @@html:@@ - [[file:blogs/2026/05-may/31-05-week-review.org][[31-05-2026] - Weekly Review]] @@html:@@ @@ -21,10 +28,3 @@ - [[file:blogs/2026/05-may/using-gifs-13-05.org][Sans spins for us!]] @@html:@@ - [[file:blogs/2026/05-may/back-to-back-meetings-13-05.org][Back to back meetings]] @@html:@@ - [[file:blogs/2026/05-may/memory-observatory-12-05.org][Memory Observatory]] @@html:@@ -- [[file:blogs/2026/05-may/having-a-daily-checkpoint-s-12-05.org][Having a daily checkpoint(s)]] @@html:@@ -- [[file:blogs/2026/05-may/characters-12-05.org][Meet the characters!]] @@html:@@ -- [[file:blogs/2026/05-may/10-05-week-review.org][[10-05-2026] - Weekly Review]] @@html:@@ -- [[file:blogs/2026/05-may/authoring-service-09-05-26.org][Authoring Service]] @@html:@@ -- [[file:play/timeline.org][Timeline Tangle]] @@html:@@ -- [[file:play/terminal.org][Archive Terminal]] @@html:@@ -- [[file:play/study.org][Study Lamp]] @@html:@@ diff --git a/sitemap.org b/sitemap.org index 8328629..ab031c5 100755 --- a/sitemap.org +++ b/sitemap.org @@ -46,112 +46,114 @@ flowchart TD root --> n20 n21["Lima"] n20 --> n21 - n22{{"play"}} + n22{{"posts"}} root --> n22 - n23["Sigil Press"] + n23["Posts Introduction"] n22 --> n23 - n24["Ash Below the Lake"] + n24["Posts List"] n22 --> n24 - n25["Timeline Tangle"] + n25{{"career"}} n22 --> n25 - n26["Ink Pond"] - n22 --> n26 - n27["Supper Wheel"] - n22 --> n27 - n28["Bookshelf Sort"] - n22 --> n28 - n29["Constellation Desk"] - n22 --> n29 - n30["Memory Cabinet"] - n22 --> n30 - n31["Play"] - n22 --> n31 - n32["Archive Terminal"] - n22 --> n32 - n33["Study Lamp"] - n22 --> n33 - n34["Marginalia Machine"] - n22 --> n34 - n35["The Rain Index"] - n22 --> n35 - n36{{"posts"}} - root --> n36 - n37["Posts Introduction"] - n36 --> n37 - n38["Posts List"] - n36 --> n38 - n39{{"career"}} - n36 --> n39 - n40["SOLID Principles"] - n39 --> n40 - n41["OWASP Top Ten"] - n39 --> n41 - n42["Retrospectives"] - n39 --> n42 - n43["Lean"] - n39 --> n43 - n44["Invest Principles"] - n39 --> n44 - n45["Career Introduction"] - n39 --> n45 - n46["Management of self training"] - n39 --> n46 - n47["Wireframe Designs"] - n39 --> n47 - n48["Requirements, features, user stories, tasks, walking skeletons"] - n39 --> n48 - n49["Benefits of Normalisation"] - n39 --> n49 - n50["Datamarts, Airflow and DAG's"] - n39 --> n50 - n51["Probation Objectives:"] - n39 --> n51 - n52["Database Permissions, Roles, and Accounts"] - n39 --> n52 - n53["Monitoring and Logging"] - n39 --> n53 - n54["Pipelines and how they work (as well as CI/CD)"] - n39 --> n54 - n55["Restful API"] - n39 --> n55 - n56["Understands the Javascript language"] - n39 --> n56 - n57["High Availability, Disaster Recovery and Business Continuity"] - n39 --> n57 - n58["Cross-Site Scripting (XSS)"] - n39 --> n58 - n59["Career List"] - n39 --> n59 - n60{{"tags"}} - root --> n60 - n61["Tag: review"] - n60 --> n61 - n62["Tag: life"] - n60 --> n62 - n63["Tag: introduction"] - n60 --> n63 - n64["Tag: learning"] - n60 --> n64 - n65["Tag: notes"] - n60 --> n65 - n66["Tag: review"] - n60 --> n66 - n67["Tag: website"] - n60 --> n67 - n68["Tag: update"] - n60 --> n68 - n69["Tag: life"] - n60 --> n69 - n70["Tag: education"] - n60 --> n70 - n71["Tag: insights"] - n60 --> n71 - n72["Tag: reading"] - n60 --> n72 - n73["Tag: emacs"] - n60 --> n73 - n74["Tag: maths"] - n60 --> n74 + n26["SOLID Principles"] + n25 --> n26 + n27["OWASP Top Ten"] + n25 --> n27 + n28["Retrospectives"] + n25 --> n28 + n29["Lean"] + n25 --> n29 + n30["Invest Principles"] + n25 --> n30 + n31["Career Introduction"] + n25 --> n31 + n32["Management of self training"] + n25 --> n32 + n33["Wireframe Designs"] + n25 --> n33 + n34["Requirements, features, user stories, tasks, walking skeletons"] + n25 --> n34 + n35["Benefits of Normalisation"] + n25 --> n35 + n36["Datamarts, Airflow and DAG's"] + n25 --> n36 + n37["Probation Objectives:"] + n25 --> n37 + n38["Database Permissions, Roles, and Accounts"] + n25 --> n38 + n39["Monitoring and Logging"] + n25 --> n39 + n40["Pipelines and how they work (as well as CI/CD)"] + n25 --> n40 + n41["Restful API"] + n25 --> n41 + n42["Understands the Javascript language"] + n25 --> n42 + n43["High Availability, Disaster Recovery and Business Continuity"] + n25 --> n43 + n44["Cross-Site Scripting (XSS)"] + n25 --> n44 + n45["Career List"] + n25 --> n45 + n46{{"tags"}} + root --> n46 + n47["Tag: review"] + n46 --> n47 + n48["Tag: life"] + n46 --> n48 + n49["Tag: introduction"] + n46 --> n49 + n50["Tag: learning"] + n46 --> n50 + n51["Tag: notes"] + n46 --> n51 + n52["Tag: review"] + n46 --> n52 + n53["Tag: website"] + n46 --> n53 + n54["Tag: life"] + n46 --> n54 + n55["Tag: update"] + n46 --> n55 + n56["Tag: insights"] + n46 --> n56 + n57["Tag: education"] + n46 --> n57 + n58["Tag: reading"] + n46 --> n58 + n59["Tag: emacs"] + n46 --> n59 + n60["Tag: maths"] + n46 --> n60 + n61{{"play"}} + root --> n61 + n62["Sigil Press"] + n61 --> n62 + n63["Ash Below the Lake"] + n61 --> n63 + n64["Timeline Tangle"] + n61 --> n64 + n65["Ink Pond"] + n61 --> n65 + n66["Supper Wheel"] + n61 --> n66 + n67["Bookshelf Sort"] + n61 --> n67 + n68["Constellation Desk"] + n61 --> n68 + n69["Memory Cabinet"] + n61 --> n69 + n70["Play"] + n61 --> n70 + n71["Archive Terminal"] + n61 --> n71 + n72["Study Lamp"] + n61 --> n72 + n73["Marginalia Machine"] + n61 --> n73 + n74["The Rain Index"] + n61 --> n74 + n75["The House of Pages"] + n61 --> n75 click n1 "index.html" "Home" click n2 "recently-updated.html" "Recently Updated" click n4 "blogs/blogs-intro.html" "Blogs Introduction" @@ -169,55 +171,56 @@ flowchart TD click n18 "home/guide/setup.html" "Setup" click n19 "home/guide/wird-tracker-guide.html" "Wird Tracker — Technical Guide" click n21 "lima/lima-list.html" "Lima" - click n23 "play/sigil.html" "Sigil Press" - click n24 "play/rpg.html" "Ash Below the Lake" - click n25 "play/timeline.html" "Timeline Tangle" - click n26 "play/ink.html" "Ink Pond" - click n27 "play/recipe.html" "Supper Wheel" - click n28 "play/bookshelf.html" "Bookshelf Sort" - click n29 "play/constellation.html" "Constellation Desk" - click n30 "play/memory.html" "Memory Cabinet" - click n31 "play/play.html" "Play" - click n32 "play/terminal.html" "Archive Terminal" - click n33 "play/study.html" "Study Lamp" - click n34 "play/poem.html" "Marginalia Machine" - click n35 "play/the-rain-index.html" "The Rain Index" - click n37 "posts/posts-intro.html" "Posts Introduction" - click n38 "posts/posts-list.html" "Posts List" - click n40 "posts/career/solid-principles.html" "SOLID Principles" - click n41 "posts/career/owasp.html" "OWASP Top Ten" - click n42 "posts/career/retrospectives.html" "Retrospectives" - click n43 "posts/career/lean.html" "Lean" - click n44 "posts/career/invest-principles.html" "Invest Principles" - click n45 "posts/career/career-intro.html" "Career Introduction" - click n46 "posts/career/management-of-self.html" "Management of self training" - click n47 "posts/career/wireframe-designs.html" "Wireframe Designs" - click n48 "posts/career/requirements-features.html" "Requirements, features, user stories, tasks, walking skeletons" - click n49 "posts/career/normalisation.html" "Benefits of Normalisation" - click n50 "posts/career/airflow.html" "Datamarts, Airflow and DAG's" - click n51 "posts/career/probation-objectives.html" "Probation Objectives:" - click n52 "posts/career/database-permissions.html" "Database Permissions, Roles, and Accounts" - click n53 "posts/career/monitoring-and-logging.html" "Monitoring and Logging" - click n54 "posts/career/pipelines.html" "Pipelines and how they work (as well as CI/CD)" - click n55 "posts/career/restful-api.html" "Restful API" - click n56 "posts/career/javascript.html" "Understands the Javascript language" - click n57 "posts/career/ha-dr.html" "High Availability, Disaster Recovery and Business Continuity" - click n58 "posts/career/cross-site-scripting-xss.html" "Cross-Site Scripting (XSS)" - click n59 "posts/career/career-list.html" "Career List" - click n61 "tags/review.sync-conflict-20260328-203248-VT6366A.html" "Tag: review" - click n62 "tags/life.sync-conflict-20260417-233423-VT6366A.html" "Tag: life" - click n63 "tags/introduction.html" "Tag: introduction" - click n64 "tags/learning.html" "Tag: learning" - click n65 "tags/notes.html" "Tag: notes" - click n66 "tags/review.html" "Tag: review" - click n67 "tags/website.html" "Tag: website" - click n68 "tags/update.html" "Tag: update" - click n69 "tags/life.html" "Tag: life" - click n70 "tags/education.html" "Tag: education" - click n71 "tags/insights.html" "Tag: insights" - click n72 "tags/reading.html" "Tag: reading" - click n73 "tags/emacs.html" "Tag: emacs" - click n74 "tags/maths.html" "Tag: maths" + click n23 "posts/posts-intro.html" "Posts Introduction" + click n24 "posts/posts-list.html" "Posts List" + click n26 "posts/career/solid-principles.html" "SOLID Principles" + click n27 "posts/career/owasp.html" "OWASP Top Ten" + click n28 "posts/career/retrospectives.html" "Retrospectives" + click n29 "posts/career/lean.html" "Lean" + click n30 "posts/career/invest-principles.html" "Invest Principles" + click n31 "posts/career/career-intro.html" "Career Introduction" + click n32 "posts/career/management-of-self.html" "Management of self training" + click n33 "posts/career/wireframe-designs.html" "Wireframe Designs" + click n34 "posts/career/requirements-features.html" "Requirements, features, user stories, tasks, walking skeletons" + click n35 "posts/career/normalisation.html" "Benefits of Normalisation" + click n36 "posts/career/airflow.html" "Datamarts, Airflow and DAG's" + click n37 "posts/career/probation-objectives.html" "Probation Objectives:" + click n38 "posts/career/database-permissions.html" "Database Permissions, Roles, and Accounts" + click n39 "posts/career/monitoring-and-logging.html" "Monitoring and Logging" + click n40 "posts/career/pipelines.html" "Pipelines and how they work (as well as CI/CD)" + click n41 "posts/career/restful-api.html" "Restful API" + click n42 "posts/career/javascript.html" "Understands the Javascript language" + click n43 "posts/career/ha-dr.html" "High Availability, Disaster Recovery and Business Continuity" + click n44 "posts/career/cross-site-scripting-xss.html" "Cross-Site Scripting (XSS)" + click n45 "posts/career/career-list.html" "Career List" + click n47 "tags/review.sync-conflict-20260328-203248-VT6366A.html" "Tag: review" + click n48 "tags/life.sync-conflict-20260417-233423-VT6366A.html" "Tag: life" + click n49 "tags/introduction.html" "Tag: introduction" + click n50 "tags/learning.html" "Tag: learning" + click n51 "tags/notes.html" "Tag: notes" + click n52 "tags/review.html" "Tag: review" + click n53 "tags/website.html" "Tag: website" + click n54 "tags/life.html" "Tag: life" + click n55 "tags/update.html" "Tag: update" + click n56 "tags/insights.html" "Tag: insights" + click n57 "tags/education.html" "Tag: education" + click n58 "tags/reading.html" "Tag: reading" + click n59 "tags/emacs.html" "Tag: emacs" + click n60 "tags/maths.html" "Tag: maths" + click n62 "play/sigil.html" "Sigil Press" + click n63 "play/rpg.html" "Ash Below the Lake" + click n64 "play/timeline.html" "Timeline Tangle" + click n65 "play/ink.html" "Ink Pond" + click n66 "play/recipe.html" "Supper Wheel" + click n67 "play/bookshelf.html" "Bookshelf Sort" + click n68 "play/constellation.html" "Constellation Desk" + click n69 "play/memory.html" "Memory Cabinet" + click n70 "play/play.html" "Play" + click n71 "play/terminal.html" "Archive Terminal" + click n72 "play/study.html" "Study Lamp" + click n73 "play/poem.html" "Marginalia Machine" + click n74 "play/the-rain-index.html" "The Rain Index" + click n75 "play/house.html" "The House of Pages" #+end_src * Pages @@ -242,20 +245,6 @@ flowchart TD - [[file:home/guide/wird-tracker-guide.org][Wird Tracker — Technical Guide]] - lima - [[file:lima/lima-list.org][Lima]] -- play - - [[file:play/sigil.org][Sigil Press]] - - [[file:play/rpg.org][Ash Below the Lake]] - - [[file:play/timeline.org][Timeline Tangle]] - - [[file:play/ink.org][Ink Pond]] - - [[file:play/recipe.org][Supper Wheel]] - - [[file:play/bookshelf.org][Bookshelf Sort]] - - [[file:play/constellation.org][Constellation Desk]] - - [[file:play/memory.org][Memory Cabinet]] - - [[file:play/play.org][Play]] - - [[file:play/terminal.org][Archive Terminal]] - - [[file:play/study.org][Study Lamp]] - - [[file:play/poem.org][Marginalia Machine]] - - [[file:play/the-rain-index.org][The Rain Index]] - posts - [[file:posts/posts-intro.org][Posts Introduction]] - [[file:posts/posts-list.org][Posts List]] @@ -288,10 +277,25 @@ flowchart TD - [[file:tags/notes.org][Tag: notes]] - [[file:tags/review.org][Tag: review]] - [[file:tags/website.org][Tag: website]] - - [[file:tags/update.org][Tag: update]] - [[file:tags/life.org][Tag: life]] - - [[file:tags/education.org][Tag: education]] + - [[file:tags/update.org][Tag: update]] - [[file:tags/insights.org][Tag: insights]] + - [[file:tags/education.org][Tag: education]] - [[file:tags/reading.org][Tag: reading]] - [[file:tags/emacs.org][Tag: emacs]] - - [[file:tags/maths.org][Tag: maths]] \ No newline at end of file + - [[file:tags/maths.org][Tag: maths]] +- play + - [[file:play/sigil.org][Sigil Press]] + - [[file:play/rpg.org][Ash Below the Lake]] + - [[file:play/timeline.org][Timeline Tangle]] + - [[file:play/ink.org][Ink Pond]] + - [[file:play/recipe.org][Supper Wheel]] + - [[file:play/bookshelf.org][Bookshelf Sort]] + - [[file:play/constellation.org][Constellation Desk]] + - [[file:play/memory.org][Memory Cabinet]] + - [[file:play/play.org][Play]] + - [[file:play/terminal.org][Archive Terminal]] + - [[file:play/study.org][Study Lamp]] + - [[file:play/poem.org][Marginalia Machine]] + - [[file:play/the-rain-index.org][The Rain Index]] + - [[file:play/house.org][The House of Pages]] \ No newline at end of file diff --git a/tags/review.org b/tags/review.org index e40a6c4..9107f3a 100755 --- a/tags/review.org +++ b/tags/review.org @@ -2,6 +2,12 @@ #+OPTIONS: toc:nil num:nil title:nil * Posts tagged review +- [[file:../blogs/2026/07-july/12-07-week-review.org][[12-07-2026] - Weekly Review]] +- [[file:../blogs/2026/07-july/05-07-week-review.org][[05-07-2026] - Weekly Review]] +- [[file:../blogs/2026/06-june/28-06-week-review.org][[28-06-2026] - Weekly Review]] +- [[file:../blogs/2026/06-june/21-06-week-review.org][[21-06-2026] - Weekly Review]] +- [[file:../blogs/2026/06-june/14-06-week-review.org][[14-06-2026] - Weekly Review]] +- [[file:../blogs/2026/06-june/07-06-week-review.org][[07-06-2026] - Weekly Review]] - [[file:../blogs/2026/06-june/cleaning-up-the-repos.org][Cleaning up the repos]] - [[file:../blogs/2026/05-may/31-05-week-review.org][[31-05-2026] - Weekly Review]] - [[file:../blogs/2026/05-may/24-05-week-review.org][[24-05-2026] - Weekly Review]]