More claude-d changes
This commit is contained in:
@@ -1,5 +1,112 @@
|
|||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:ID: b31d6c3f-9bc3-4006-aaaf-d56168249e3a
|
:ID: b31d6c3f-9bc3-4006-aaaf-d56168249e3a
|
||||||
:END:
|
:END:
|
||||||
#+title: Recipes Cookbook
|
|
||||||
|
|
||||||
|
#+title: Recipes Cookbook
|
||||||
|
#+AUTHOR: Auto-generated
|
||||||
|
#+filetags: :recipes:cooking:org:index:
|
||||||
|
#+STARTUP: content
|
||||||
|
#+PROPERTY: GENERATED_AT 2026-03-08T14:43:28.313070
|
||||||
|
|
||||||
|
# How to add notes: under any recipe heading, add :COOKED: <date> to record when you made it, and :TIPS: your tip text to add notes.
|
||||||
|
# Multiple :COOKED: lines are supported. These are preserved across regenerations.
|
||||||
|
|
||||||
|
* Lunch
|
||||||
|
|
||||||
|
** Chicken Rice Meal Prep :Chicken:Chicken_and_Rice:Lunch:Rice:
|
||||||
|
:PROPERTIES:
|
||||||
|
:RECIPE_ID: 23153
|
||||||
|
:CATEGORY: Lunch
|
||||||
|
:KEYWORDS: Chicken,Chicken and Rice,Lunch,Rice
|
||||||
|
:CREATED: 2026-03-08T00:03:56+0000
|
||||||
|
:MODIFIED: 2026-03-08T00:12:24+0000
|
||||||
|
:URL: https://nextcloud.zainezq.com/apps/cookbook/webapp/recipes/23153
|
||||||
|
:COOKED: <2026-03-08 Sun>
|
||||||
|
:END:
|
||||||
|
#+ATTR_HTML: :class recipe-meta
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| *Category* | Lunch |
|
||||||
|
| *Keywords* | Chicken,Chicken and Rice,Lunch,Rice |
|
||||||
|
| *Created* | 2026-03-08 |
|
||||||
|
| *Modified* | 2026-03-08 |
|
||||||
|
| *Cooked* | <2026-03-08 Sun> |
|
||||||
|
| *Link* | [[https://nextcloud.zainezq.com/apps/cookbook/webapp/recipes/23153][Open in Nextcloud]] |
|
||||||
|
|
||||||
|
** Healthy CREAMY Tuna Wraps :Lunch:Tuna:
|
||||||
|
:PROPERTIES:
|
||||||
|
:RECIPE_ID: 23133
|
||||||
|
:CATEGORY: Lunch
|
||||||
|
:KEYWORDS: Lunch,Tuna
|
||||||
|
:CREATED: 2026-03-07T23:02:59+0000
|
||||||
|
:MODIFIED: 2026-03-08T00:12:38+0000
|
||||||
|
:URL: https://nextcloud.zainezq.com/apps/cookbook/webapp/recipes/23133
|
||||||
|
:COOKED: <2025-07-17 Thu>
|
||||||
|
:END:
|
||||||
|
#+ATTR_HTML: :class recipe-meta
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| *Category* | Lunch |
|
||||||
|
| *Keywords* | Lunch,Tuna |
|
||||||
|
| *Created* | 2026-03-07 |
|
||||||
|
| *Modified* | 2026-03-08 |
|
||||||
|
| *Cooked* | <2025-07-17 Thu> |
|
||||||
|
| *Link* | [[https://nextcloud.zainezq.com/apps/cookbook/webapp/recipes/23133][Open in Nextcloud]] |
|
||||||
|
|
||||||
|
** High Protein Tuna Salad :Lunch:Tuna:
|
||||||
|
:PROPERTIES:
|
||||||
|
:RECIPE_ID: 21929
|
||||||
|
:CATEGORY: Lunch
|
||||||
|
:KEYWORDS: Lunch,Tuna
|
||||||
|
:CREATED: 2026-02-23T16:49:56+0000
|
||||||
|
:MODIFIED: 2026-03-08T00:12:47+0000
|
||||||
|
:URL: https://nextcloud.zainezq.com/apps/cookbook/webapp/recipes/21929
|
||||||
|
:END:
|
||||||
|
#+ATTR_HTML: :class recipe-meta
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| *Category* | Lunch |
|
||||||
|
| *Keywords* | Lunch,Tuna |
|
||||||
|
| *Created* | 2026-02-23 |
|
||||||
|
| *Modified* | 2026-03-08 |
|
||||||
|
| *Cooked* | /not yet made/ |
|
||||||
|
| *Link* | [[https://nextcloud.zainezq.com/apps/cookbook/webapp/recipes/21929][Open in Nextcloud]] |
|
||||||
|
|
||||||
|
** One Pot Chicken and Rice Recipe :Chicken:Chicken_and_Rice:Lunch:One_Pot:Rice:
|
||||||
|
:PROPERTIES:
|
||||||
|
:RECIPE_ID: 23167
|
||||||
|
:CATEGORY: Lunch
|
||||||
|
:KEYWORDS: Chicken,Chicken and Rice,Lunch,One Pot,Rice
|
||||||
|
:CREATED: 2026-03-08T00:10:27+0000
|
||||||
|
:MODIFIED: 2026-03-08T00:13:23+0000
|
||||||
|
:URL: https://nextcloud.zainezq.com/apps/cookbook/webapp/recipes/23167
|
||||||
|
:END:
|
||||||
|
#+ATTR_HTML: :class recipe-meta
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| *Category* | Lunch |
|
||||||
|
| *Keywords* | Chicken,Chicken and Rice,Lunch,One Pot,Rice |
|
||||||
|
| *Created* | 2026-03-08 |
|
||||||
|
| *Modified* | 2026-03-08 |
|
||||||
|
| *Cooked* | /not yet made/ |
|
||||||
|
| *Link* | [[https://nextcloud.zainezq.com/apps/cookbook/webapp/recipes/23167][Open in Nextcloud]] |
|
||||||
|
|
||||||
|
** Potato Peas Quesadilla :Lunch:Peas:Potato:Quesadilla:
|
||||||
|
:PROPERTIES:
|
||||||
|
:RECIPE_ID: 23144
|
||||||
|
:CATEGORY: Lunch
|
||||||
|
:KEYWORDS: Lunch,Peas,Potato,Quesadilla
|
||||||
|
:CREATED: 2026-03-07T23:07:31+0000
|
||||||
|
:MODIFIED: 2026-03-08T00:13:49+0000
|
||||||
|
:URL: https://nextcloud.zainezq.com/apps/cookbook/webapp/recipes/23144
|
||||||
|
:COOKED: <2025-07-18 Fri>
|
||||||
|
:END:
|
||||||
|
#+ATTR_HTML: :class recipe-meta
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| *Category* | Lunch |
|
||||||
|
| *Keywords* | Lunch,Peas,Potato,Quesadilla |
|
||||||
|
| *Created* | 2026-03-07 |
|
||||||
|
| *Modified* | 2026-03-08 |
|
||||||
|
| *Cooked* | <2025-07-18 Fri> |
|
||||||
|
| *Link* | [[https://nextcloud.zainezq.com/apps/cookbook/webapp/recipes/23144][Open in Nextcloud]] |
|
||||||
|
|||||||
232
assets/scripts/cookbook.js
Normal file
232
assets/scripts/cookbook.js
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
/**
|
||||||
|
* cookbook.js
|
||||||
|
* Works both as a direct page load AND when injected as a stacked pane
|
||||||
|
* by script.js (which fetches pages and injects only #content).
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// ── Core init — scoped to a content root ──────────────────────────────────
|
||||||
|
|
||||||
|
function initCookbook(root) {
|
||||||
|
// Already initialised on this root?
|
||||||
|
if (root.dataset.cbInit) return;
|
||||||
|
root.dataset.cbInit = "1";
|
||||||
|
|
||||||
|
const recipes = Array.from(root.querySelectorAll(".outline-3"))
|
||||||
|
.filter(el => el.querySelector("table.recipe-meta"));
|
||||||
|
|
||||||
|
if (!recipes.length) return;
|
||||||
|
|
||||||
|
// ── Helpers ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
function cellValue(table, label) {
|
||||||
|
for (const row of table.querySelectorAll("tbody tr")) {
|
||||||
|
const cells = row.querySelectorAll("td");
|
||||||
|
if (cells.length >= 2 && cells[0].textContent.trim() === label)
|
||||||
|
return cells[1].textContent.trim();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function isCooked(table) {
|
||||||
|
const v = cellValue(table, "Cooked");
|
||||||
|
return Boolean(v && v !== "not yet made");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Collect keywords ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
const allKeywords = new Set();
|
||||||
|
recipes.forEach(block => {
|
||||||
|
const kw = cellValue(block.querySelector("table.recipe-meta"), "Keywords");
|
||||||
|
if (kw) kw.split(",").forEach(k => allKeywords.add(k.trim()));
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── Build toolbar ────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
const toolbar = document.createElement("div");
|
||||||
|
toolbar.className = "cb-toolbar";
|
||||||
|
toolbar.setAttribute("role", "search");
|
||||||
|
toolbar.innerHTML = `
|
||||||
|
<div class="cb-toolbar-inner">
|
||||||
|
<input class="cb-search" type="search" placeholder="filter recipes…"
|
||||||
|
aria-label="Filter recipes" autocomplete="off" spellcheck="false" />
|
||||||
|
<div class="cb-filters" role="group" aria-label="Cook status">
|
||||||
|
<button class="cb-filter-btn active" data-filter="all">all</button>
|
||||||
|
<button class="cb-filter-btn" data-filter="cooked">✓ made</button>
|
||||||
|
<button class="cb-filter-btn" data-filter="uncooked">✗ not yet</button>
|
||||||
|
</div>
|
||||||
|
<div class="cb-tags" role="group" aria-label="Filter by keyword"></div>
|
||||||
|
<span class="cb-count" aria-live="polite"></span>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
const firstSection = root.querySelector(".outline-2");
|
||||||
|
if (firstSection) firstSection.parentNode.insertBefore(toolbar, firstSection);
|
||||||
|
|
||||||
|
const searchInput = toolbar.querySelector(".cb-search");
|
||||||
|
const filterBtns = toolbar.querySelectorAll(".cb-filter-btn");
|
||||||
|
const tagsWrap = toolbar.querySelector(".cb-tags");
|
||||||
|
const countEl = toolbar.querySelector(".cb-count");
|
||||||
|
|
||||||
|
// Keyword pills
|
||||||
|
Array.from(allKeywords).sort().forEach(kw => {
|
||||||
|
const btn = document.createElement("button");
|
||||||
|
btn.className = "cb-tag";
|
||||||
|
btn.textContent = kw;
|
||||||
|
btn.dataset.tag = kw;
|
||||||
|
btn.setAttribute("aria-pressed", "false");
|
||||||
|
tagsWrap.appendChild(btn);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── State ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
let activeFilter = "all";
|
||||||
|
let activeTags = new Set();
|
||||||
|
let query = "";
|
||||||
|
|
||||||
|
// ── Filter engine ────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
function applyFilters() {
|
||||||
|
let shown = 0;
|
||||||
|
|
||||||
|
recipes.forEach(block => {
|
||||||
|
const table = block.querySelector("table.recipe-meta");
|
||||||
|
const cooked = isCooked(table);
|
||||||
|
const title = (block.querySelector("h3")?.textContent ?? "").toLowerCase();
|
||||||
|
const kwRaw = cellValue(table, "Keywords");
|
||||||
|
const kwLow = kwRaw.toLowerCase();
|
||||||
|
|
||||||
|
if (activeFilter === "cooked" && !cooked) { hide(block); return; }
|
||||||
|
if (activeFilter === "uncooked" && cooked) { hide(block); return; }
|
||||||
|
|
||||||
|
if (activeTags.size) {
|
||||||
|
const recipeKws = kwRaw.split(",").map(k => k.trim());
|
||||||
|
if ([...activeTags].some(t => !recipeKws.includes(t))) { hide(block); return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query && !title.includes(query) && !kwLow.includes(query)) {
|
||||||
|
hide(block); return;
|
||||||
|
}
|
||||||
|
|
||||||
|
show(block);
|
||||||
|
shown++;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Hide category headings with no visible recipes
|
||||||
|
root.querySelectorAll(".outline-2").forEach(section => {
|
||||||
|
const hasVisible = Array.from(section.querySelectorAll(".outline-3"))
|
||||||
|
.some(b => b.style.display !== "none");
|
||||||
|
section.style.display = hasVisible ? "" : "none";
|
||||||
|
});
|
||||||
|
|
||||||
|
countEl.textContent =
|
||||||
|
shown === recipes.length
|
||||||
|
? `${shown} recipe${shown !== 1 ? "s" : ""}`
|
||||||
|
: `${shown} / ${recipes.length}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hide(el) { el.style.display = "none"; }
|
||||||
|
function show(el) { el.style.display = ""; }
|
||||||
|
|
||||||
|
// ── Events ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
searchInput.addEventListener("input", () => {
|
||||||
|
query = searchInput.value.trim().toLowerCase();
|
||||||
|
applyFilters();
|
||||||
|
});
|
||||||
|
|
||||||
|
filterBtns.forEach(btn => {
|
||||||
|
btn.addEventListener("click", () => {
|
||||||
|
filterBtns.forEach(b => b.classList.remove("active"));
|
||||||
|
btn.classList.add("active");
|
||||||
|
activeFilter = btn.dataset.filter;
|
||||||
|
applyFilters();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
tagsWrap.addEventListener("click", e => {
|
||||||
|
const btn = e.target.closest(".cb-tag");
|
||||||
|
if (!btn) return;
|
||||||
|
const tag = btn.dataset.tag;
|
||||||
|
if (activeTags.has(tag)) {
|
||||||
|
activeTags.delete(tag);
|
||||||
|
btn.classList.remove("active");
|
||||||
|
btn.setAttribute("aria-pressed", "false");
|
||||||
|
} else {
|
||||||
|
activeTags.add(tag);
|
||||||
|
btn.classList.add("active");
|
||||||
|
btn.setAttribute("aria-pressed", "true");
|
||||||
|
}
|
||||||
|
applyFilters();
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── Badges ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
recipes.forEach(block => {
|
||||||
|
const table = block.querySelector("table.recipe-meta");
|
||||||
|
const h3 = block.querySelector("h3");
|
||||||
|
const cooked = isCooked(table);
|
||||||
|
|
||||||
|
block.classList.add(cooked ? "cb-cooked" : "cb-uncooked");
|
||||||
|
|
||||||
|
const badge = document.createElement("span");
|
||||||
|
badge.className = "cb-badge " + (cooked ? "cb-badge-cooked" : "cb-badge-uncooked");
|
||||||
|
badge.textContent = cooked ? "made" : "not yet";
|
||||||
|
|
||||||
|
const tagSpan = h3.querySelector(".tag");
|
||||||
|
if (tagSpan) h3.insertBefore(badge, tagSpan);
|
||||||
|
else h3.appendChild(badge);
|
||||||
|
});
|
||||||
|
|
||||||
|
applyFilters();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Entry points ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
// 1. Direct page load — #content is already in the DOM
|
||||||
|
function tryInitOnContent() {
|
||||||
|
const content = document.getElementById("content");
|
||||||
|
if (content && content.querySelector("table.recipe-meta")) {
|
||||||
|
initCookbook(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Stacked pane — script.js fetches a page and appends a new <article>
|
||||||
|
// with the #content inside it. Watch for that.
|
||||||
|
function watchForPanes() {
|
||||||
|
const track = document.querySelector(".stack-track");
|
||||||
|
if (!track) return;
|
||||||
|
|
||||||
|
const observer = new MutationObserver(mutations => {
|
||||||
|
mutations.forEach(m => {
|
||||||
|
m.addedNodes.forEach(node => {
|
||||||
|
if (node.nodeType !== 1) return;
|
||||||
|
// script.js appends an <article class="stack-pane">
|
||||||
|
// containing a div#content
|
||||||
|
const content = node.id === "content"
|
||||||
|
? node
|
||||||
|
: node.querySelector("#content, .content");
|
||||||
|
if (content && content.querySelector("table.recipe-meta")) {
|
||||||
|
initCookbook(content);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
observer.observe(track, { childList: true, subtree: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run both
|
||||||
|
if (document.readyState === "loading") {
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
tryInitOnContent();
|
||||||
|
watchForPanes();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Already parsed (script has `defer` but DOM may already be ready)
|
||||||
|
tryInitOnContent();
|
||||||
|
watchForPanes();
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
||||||
214
assets/styles/cookbook.css
Normal file
214
assets/styles/cookbook.css
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
/* cookbook.css — minimal, breathes with the page */
|
||||||
|
|
||||||
|
/* ── Recipe meta table ───────────────────────────────────────────────────── */
|
||||||
|
|
||||||
|
table.recipe-meta {
|
||||||
|
border-collapse: collapse;
|
||||||
|
//font-size: 0.82em;
|
||||||
|
opacity: 1;
|
||||||
|
margin: 0.3em 0 1em;
|
||||||
|
width: auto;
|
||||||
|
//border: none;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.recipe-meta thead { display: none; }
|
||||||
|
|
||||||
|
table.recipe-meta td {
|
||||||
|
padding: 0.15em 1em 0.15em 0;
|
||||||
|
border: none !important;
|
||||||
|
vertical-align: top;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.recipe-meta td:first-child {
|
||||||
|
//font-family: var(--font-mono);
|
||||||
|
//font-size: 0.75em;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
//color: var(--fg-faint);
|
||||||
|
white-space: nowrap;
|
||||||
|
min-width: 5em;
|
||||||
|
padding-top: 0.28em;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.recipe-meta td a {
|
||||||
|
color: var(--accent);
|
||||||
|
border-bottom: 1px solid var(--accent-dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
table.recipe-meta td a:hover {
|
||||||
|
color: var(--fg);
|
||||||
|
border-bottom-color: var(--fg-faint);
|
||||||
|
}
|
||||||
|
|
||||||
|
table.recipe-meta .timestamp {
|
||||||
|
color: var(--accent);
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Toolbar — no box, just spacing and a faint separator ───────────────── */
|
||||||
|
|
||||||
|
.cb-toolbar {
|
||||||
|
margin: 0 0 1.8em;
|
||||||
|
padding: 0;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
padding-bottom: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cb-toolbar-inner {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.4em 0.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Search ──────────────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.cb-search {
|
||||||
|
flex: 1 1 140px;
|
||||||
|
min-width: 0;
|
||||||
|
padding: 0.3em 0;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--fg);
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
border-radius: 0;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-family: var(--font-body);
|
||||||
|
font-weight: 300;
|
||||||
|
outline: none;
|
||||||
|
transition: border-color var(--dur-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cb-search::placeholder {
|
||||||
|
color: var(--fg-faint);
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cb-search:focus {
|
||||||
|
border-bottom-color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Status filters ──────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.cb-filters {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.15em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cb-filter-btn {
|
||||||
|
padding: 0.2em 0.55em;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--fg-faint);
|
||||||
|
border: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color var(--dur-fast), background var(--dur-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cb-filter-btn:hover {
|
||||||
|
color: var(--fg);
|
||||||
|
background: var(--chip-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cb-filter-btn.active {
|
||||||
|
color: var(--accent);
|
||||||
|
background: var(--accent-subtle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Keyword pills ───────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.cb-tags {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.2em;
|
||||||
|
flex: 1 1 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cb-tag {
|
||||||
|
padding: 0.12em 0.5em;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--fg-faint);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 99px;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color var(--dur-fast), border-color var(--dur-fast), background var(--dur-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cb-tag:hover {
|
||||||
|
color: var(--accent);
|
||||||
|
border-color: var(--accent-dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cb-tag.active {
|
||||||
|
color: var(--accent);
|
||||||
|
border-color: var(--accent-dim);
|
||||||
|
background: var(--accent-subtle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Count ───────────────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.cb-count {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
color: var(--fg-faint);
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Badges ──────────────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.cb-badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.1em 0.4em;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 0.62em;
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-weight: 400;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 0.3em;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
text-transform: lowercase;
|
||||||
|
border: 1px solid;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cb-badge-cooked {
|
||||||
|
color: #6fcf97 !important;
|
||||||
|
border-color: #2d6a4f !important;
|
||||||
|
background: color-mix(in oklab, #2d6a4f 15%, transparent) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cb-badge-uncooked {
|
||||||
|
color: var(--fg-faint) !important;
|
||||||
|
border-color: var(--border) !important;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Recipe block hover ──────────────────────────────────────────────────── */
|
||||||
|
|
||||||
|
.outline-3 {
|
||||||
|
border-left: 2px solid transparent;
|
||||||
|
padding-left: 0.6em;
|
||||||
|
transition: border-color var(--dur-mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
.outline-3:hover {
|
||||||
|
border-left-color: var(--accent-dim);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Responsive ──────────────────────────────────────────────────────────── */
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.cb-count { margin-left: 0; }
|
||||||
|
}
|
||||||
@@ -984,7 +984,8 @@ body.pane-fullscreen #content.content { max-width: 860px; }
|
|||||||
========================================================= */
|
========================================================= */
|
||||||
|
|
||||||
.hidden { display: none !important; }
|
.hidden { display: none !important; }
|
||||||
|
.recipe-meta td:first-child { font-weight: 600; white-space: nowrap; }
|
||||||
|
.recipe-meta { font-size: 0.9em; opacity: 0.85; }
|
||||||
/* =========================================================
|
/* =========================================================
|
||||||
RESPONSIVE
|
RESPONSIVE
|
||||||
========================================================= */
|
========================================================= */
|
||||||
|
|||||||
@@ -145,12 +145,14 @@
|
|||||||
<link rel=\"stylesheet\" href=\"/assets/styles/style.css\" />
|
<link rel=\"stylesheet\" href=\"/assets/styles/style.css\" />
|
||||||
<link rel=\"stylesheet\" href=\"/assets/styles/bigger-picture.min.css\" />
|
<link rel=\"stylesheet\" href=\"/assets/styles/bigger-picture.min.css\" />
|
||||||
<link rel=\"stylesheet\" href=\"/assets/styles/media.css\" />
|
<link rel=\"stylesheet\" href=\"/assets/styles/media.css\" />
|
||||||
|
<link rel=\"stylesheet\" href=\"/assets/styles/cookbook.css\" />
|
||||||
|
|
||||||
<script src=\"/assets/scripts/script.js\" defer></script>
|
<script src=\"/assets/scripts/script.js\" defer></script>
|
||||||
<script src=\"/assets/scripts/search.js\" defer></script>
|
<script src=\"/assets/scripts/search.js\" defer></script>
|
||||||
<script src=\"/assets/scripts/bigger-picture.min.js\" defer></script>
|
<script src=\"/assets/scripts/bigger-picture.min.js\" defer></script>
|
||||||
<script src=\"/assets/scripts/svg-pan-zoom.min.js\" defer></script>
|
<script src=\"/assets/scripts/svg-pan-zoom.min.js\" defer></script>
|
||||||
<script src=\"/assets/scripts/gallery-init.js\" defer></script>
|
<script src=\"/assets/scripts/gallery-init.js\" defer></script>
|
||||||
|
<script src=\"/assets/scripts/cookbook.js\" defer></script>
|
||||||
"
|
"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ Generating the JSON output...
|
|||||||
Building project (full rebuild with search index)...
|
Building project (full rebuild with search index)...
|
||||||
emacs -Q --script lisp/build.el
|
emacs -Q --script lisp/build.el
|
||||||
Loading /home/zaine/master-folder/org_files/org_roam/lisp/macros.el (source)...
|
Loading /home/zaine/master-folder/org_files/org_roam/lisp/macros.el (source)...
|
||||||
Starting full rebuild at 2026-03-08 13:37:37
|
Starting full rebuild at 2026-03-08 14:53:23
|
||||||
✅ Full rebuild complete in 6.37 seconds
|
✅ Full rebuild complete in 6.40 seconds
|
||||||
|
|||||||
Reference in New Issue
Block a user