release nouri 0.4.0 templates suggestions and mobile sheet

This commit is contained in:
2026-04-12 16:00:00 +02:00
parent b68ed62887
commit d8b56e6b67
28 changed files with 2651 additions and 492 deletions
+192 -2
View File
@@ -67,6 +67,10 @@ body.has-mobile-nav {
padding-bottom: 6rem;
}
body.sheet-open {
overflow: hidden;
}
a {
color: inherit;
text-decoration: none;
@@ -256,6 +260,11 @@ h3,
display: none;
}
.mobile-sheet-backdrop[hidden],
.mobile-more-sheet[hidden] {
display: none;
}
.content {
display: grid;
gap: 1.2rem;
@@ -576,6 +585,12 @@ h3 {
gap: 1rem;
}
.template-library-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1rem;
}
.stack-form label,
.planner-entry-form label,
.filter-form label,
@@ -640,6 +655,37 @@ legend {
border: 1px solid var(--line);
}
.check-option[hidden],
.quick-select-card[hidden] {
display: none;
}
.quick-select-card {
display: flex;
align-items: flex-start;
gap: 0.7rem;
padding: 0.85rem 0.95rem;
min-width: 220px;
border-radius: 18px;
border: 1px solid var(--line);
background: color-mix(in srgb, var(--surface-strong) 82%, #fff 18%);
}
.quick-select-card strong,
.template-list-card strong {
display: block;
}
.quick-select-card small,
.template-list-card p,
.template-list-card small,
.hint-chip,
.suggestion-card p,
.suggestion-card small,
.week-template-row p {
color: var(--muted);
}
.inline-photo img {
width: min(220px, 100%);
border-radius: 18px;
@@ -739,6 +785,10 @@ legend {
margin-bottom: 1rem;
}
.template-search-row {
margin-bottom: 0.9rem;
}
.quick-add-row form {
margin: 0;
}
@@ -769,6 +819,49 @@ legend {
background: color-mix(in srgb, var(--surface) 88%, #fff 12%);
}
.template-card,
.template-list-card,
.suggestion-card {
padding: 0.95rem 1rem;
border-radius: 18px;
border: 1px solid var(--line);
background: color-mix(in srgb, var(--surface-strong) 84%, #fff 16%);
}
.template-list-card,
.week-template-row {
display: grid;
gap: 0.9rem;
}
.week-template-row {
padding: 1rem;
border-radius: 18px;
border: 1px solid var(--line);
background: rgba(255, 255, 255, 0.34);
}
.hint-list {
display: flex;
flex-wrap: wrap;
gap: 0.7rem;
}
.hint-chip {
margin: 0;
padding: 0.85rem 1rem;
border-radius: 16px;
background: color-mix(in srgb, var(--surface-strong) 80%, #fff 20%);
border: 1px solid var(--line);
}
.suggestion-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 0.8rem;
margin-bottom: 1rem;
}
.planner-entry-top {
align-items: flex-start;
}
@@ -915,6 +1008,71 @@ legend {
mask-image: url("../icons/fa/sparkles.svg");
}
.icon-layer-group {
-webkit-mask-image: url("../icons/fa/layer-group.svg");
mask-image: url("../icons/fa/layer-group.svg");
}
.icon-ellipsis {
-webkit-mask-image: url("../icons/fa/ellipsis.svg");
mask-image: url("../icons/fa/ellipsis.svg");
}
.mobile-sheet-backdrop {
position: fixed;
inset: 0;
z-index: 24;
background: rgba(33, 29, 28, 0.22);
backdrop-filter: blur(6px);
}
.mobile-more-sheet {
position: fixed;
left: 0.75rem;
right: 0.75rem;
bottom: 5.9rem;
z-index: 25;
padding: 1rem;
border-radius: 24px;
border: 1px solid var(--line);
background: var(--bg-elevated);
box-shadow: var(--shadow);
backdrop-filter: blur(24px) saturate(1.1);
}
.mobile-sheet-head,
.mobile-sheet-actions {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.8rem;
}
.mobile-sheet-head small {
color: var(--muted);
}
.mobile-sheet-links {
display: grid;
gap: 0.45rem;
margin: 1rem 0;
}
.mobile-sheet-links a {
padding: 0.9rem 1rem;
border-radius: 16px;
border: 1px solid var(--line);
background: color-mix(in srgb, var(--surface-strong) 86%, #fff 14%);
}
.mobile-sheet-actions {
flex-wrap: wrap;
}
.mobile-sheet-actions > * {
flex: 1 1 180px;
}
@media (max-width: 1080px) {
.site-header,
.hero,
@@ -932,6 +1090,7 @@ legend {
.stats-grid,
.two-column,
.template-library-grid,
.inline-form,
.planner-entry-form,
.planner-entry-form-wide,
@@ -1014,7 +1173,8 @@ legend {
.mini-card-grid,
.week-mini-grid,
.week-overview-grid,
.more-link-grid {
.more-link-grid,
.template-library-grid {
grid-template-columns: 1fr;
}
@@ -1079,7 +1239,20 @@ legend {
font-size: 0.78rem;
}
.mobile-bottom-nav a.active {
.mobile-nav-button {
display: grid;
justify-items: center;
gap: 0.28rem;
padding: 0.55rem 0.35rem;
border-radius: 16px;
border: 0;
background: transparent;
color: var(--muted);
font-size: 0.78rem;
}
.mobile-bottom-nav a.active,
.mobile-nav-button.is-open {
background: var(--accent-soft);
color: var(--text);
}
@@ -1088,4 +1261,21 @@ legend {
width: 1rem;
height: 1rem;
}
.mobile-profile-link {
display: inline-flex;
padding: 0.35rem;
background: transparent;
}
.mobile-profile-link .mobile-profile-avatar {
width: 2.15rem;
height: 2.15rem;
}
.mobile-sheet-head,
.mobile-sheet-actions,
.week-template-row {
align-items: flex-start;
}
}
+5
View File
@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<circle cx="5" cy="12" r="2"/>
<circle cx="12" cy="12" r="2"/>
<circle cx="19" cy="12" r="2"/>
</svg>

After

Width:  |  Height:  |  Size: 189 B

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2.6 2 8l10 5.4L22 8 12 2.6Zm-7.9 8.6L2 12.4l10 5.4 10-5.4-2.1-1.2L12 15.4 4.1 11.2Zm0 4.4L2 16.8l10 5.4 10-5.4-2.1-1.2L12 19.8 4.1 15.6Z"/>
</svg>

After

Width:  |  Height:  |  Size: 243 B

+67
View File
@@ -0,0 +1,67 @@
(() => {
const initMobileSheet = () => {
const sheet = document.querySelector("[data-mobile-sheet]");
const backdrop = document.querySelector("[data-mobile-sheet-backdrop]");
const openButtons = document.querySelectorAll("[data-mobile-sheet-open]");
const closeButtons = document.querySelectorAll("[data-mobile-sheet-close]");
if (!sheet || !backdrop || !openButtons.length) return;
const closeSheet = () => {
sheet.hidden = true;
backdrop.hidden = true;
document.body.classList.remove("sheet-open");
openButtons.forEach((button) => button.classList.remove("is-open"));
};
const openSheet = () => {
sheet.hidden = false;
backdrop.hidden = false;
document.body.classList.add("sheet-open");
openButtons.forEach((button) => button.classList.add("is-open"));
};
openButtons.forEach((button) => {
button.addEventListener("click", openSheet);
});
closeButtons.forEach((button) => {
button.addEventListener("click", closeSheet);
});
backdrop.addEventListener("click", closeSheet);
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") {
closeSheet();
}
});
sheet.querySelectorAll("a").forEach((link) => {
link.addEventListener("click", closeSheet);
});
};
const initFilterInputs = () => {
document.querySelectorAll("[data-filter-input]").forEach((input) => {
const listSelector = input.getAttribute("data-filter-target");
if (!listSelector) return;
const container = document.querySelector(listSelector);
if (!container) return;
const items = Array.from(container.querySelectorAll("[data-filter-label]"));
const applyFilter = () => {
const term = input.value.trim().toLowerCase();
items.forEach((item) => {
const haystack = (item.getAttribute("data-filter-label") || "").toLowerCase();
item.hidden = Boolean(term) && !haystack.includes(term);
});
};
input.addEventListener("input", applyFilter);
applyFilter();
});
};
document.addEventListener("DOMContentLoaded", () => {
initMobileSheet();
initFilterInputs();
});
})();