summaryrefslogtreecommitdiff
path: root/static/style.css
diff options
context:
space:
mode:
authorTyler Hoang <tyler@tylerhoang.xyz>2026-05-08 03:24:36 -0700
committerTyler Hoang <tyler@tylerhoang.xyz>2026-05-08 03:24:36 -0700
commit3de7c5eed5ba262abf0d746211e33800db6d66df (patch)
tree6fddb5381fb178423eac34894add5b611babe300 /static/style.css
parentf361e7599d9a11ad3397b7b6bffee151ab9bdde9 (diff)
Add recipe suggestions, chat tab, and major workflow improvements
- Replace 7-day grid menu with browsable recipe suggestion cards (swap, remove, make this) - Add Chat tab: conversational AI with full pantry/menu/grocery context - Grocery list works without a menu (pantry-only mode) - Individual grocery checkboxes auto-add items to pantry - Swap modal with optional preference input - User notes textarea on menu and grocery generation - Clear button for menu and grocery list - LLM notes/summary displayed after generation, persisted to DB - Favicon linked in HTML - Category dropdown styled for dark theme - System prompt configurable via SYSTEM_PROMPT in .env - Fix startup error (ollama_timeout default), DB migration for menu_plans.notes - Simplify: batch N+1 queries, extract _current_monday(), merge chat sync fns, asyncio.get_running_loop(), fix currentGroceryId bug, cap chat history Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'static/style.css')
-rw-r--r--static/style.css286
1 files changed, 223 insertions, 63 deletions
diff --git a/static/style.css b/static/style.css
index 9d90898..4cc033b 100644
--- a/static/style.css
+++ b/static/style.css
@@ -270,6 +270,16 @@ main {
border-color: #16a34a;
}
+.btn-secondary {
+ background-color: var(--surface2);
+ color: var(--text);
+ border: 1px solid var(--border);
+}
+
+.btn-secondary:hover {
+ border-color: var(--text-muted);
+}
+
.btn-sm {
padding: 0.5rem 1rem;
font-size: 0.8rem;
@@ -354,97 +364,87 @@ tbody tr.expiry-warn {
font-size: 0.9rem;
}
-/* ── Menu Grid ──────────────────────────────────────────────────────────── */
-.menu-grid {
+/* ── Recipe List ───────────────────────────────────────────────────────── */
+.recipe-list {
display: grid;
- grid-template-columns: repeat(8, 1fr);
- gap: 0.5rem;
- margin-bottom: 2rem;
+ grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
+ gap: 1rem;
+ padding: 1rem 0;
}
-.menu-grid-cell {
+.recipe-card {
background-color: var(--surface);
border: 1px solid var(--border);
border-radius: 0.5rem;
- padding: 1rem;
- min-height: 120px;
+ padding: 1.25rem;
display: flex;
flex-direction: column;
- justify-content: space-between;
- transition: all 0.2s ease;
+ gap: 0.5rem;
+ transition: border-color 0.2s ease;
}
-.menu-grid-cell:hover {
+.recipe-card:hover {
border-color: var(--accent);
}
-.menu-grid-cell.repeat-warning {
- border: 2px solid var(--warning);
+.recipe-card-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: 0.5rem;
}
-.menu-grid-header {
- background-color: var(--surface2);
+.recipe-card-title {
font-weight: 600;
- text-align: center;
- padding: 1rem;
- border-radius: 0.5rem;
- border: 1px solid var(--border);
+ font-size: 1rem;
+ color: var(--text);
}
-.menu-meal-type {
- font-size: 0.75rem;
- font-weight: 600;
- text-transform: uppercase;
- color: var(--text-muted);
- margin-bottom: 0.5rem;
+.recipe-type-badge {
+ font-size: 0.7rem;
+ padding: 0.2rem 0.6rem;
+ border-radius: 9999px;
+ font-weight: 500;
+ white-space: nowrap;
+ flex-shrink: 0;
}
-.menu-meal-name {
- font-weight: 600;
- margin-bottom: 0.5rem;
- word-break: break-word;
-}
+.recipe-type-badge.breakfast { background-color: rgba(251, 191, 36, 0.2); color: #fbbf24; }
+.recipe-type-badge.lunch { background-color: rgba(52, 211, 153, 0.2); color: #34d399; }
+.recipe-type-badge.dinner { background-color: rgba(139, 92, 246, 0.2); color: #8b5cf6; }
+.recipe-type-badge.snack { background-color: rgba(251, 146, 60, 0.2); color: #fb923c; }
-.menu-time {
- display: inline-block;
- font-size: 0.75rem;
- background-color: var(--surface2);
- padding: 0.25rem 0.5rem;
- border-radius: 0.25rem;
- margin-bottom: 0.75rem;
+.recipe-card-meta {
+ font-size: 0.8rem;
color: var(--text-muted);
}
-.menu-actions {
- display: flex;
- gap: 0.5rem;
- flex-wrap: wrap;
+.recipe-card-ingredients {
+ font-size: 0.85rem;
+ color: var(--text-muted);
+ line-height: 1.5;
}
-@media (max-width: 768px) {
- .menu-grid {
- grid-template-columns: 1fr;
- }
-
- .menu-grid-header {
- display: none;
- }
+.recipe-card-instructions {
+ font-size: 0.85rem;
+ color: var(--text);
+ line-height: 1.6;
+ border-top: 1px solid var(--border);
+ padding-top: 0.5rem;
+ margin-top: 0.25rem;
+ white-space: pre-line;
+}
- .menu-grid-cell {
- position: relative;
- }
+.recipe-card .btn {
+ align-self: flex-start;
+ margin-top: 0.5rem;
+}
- .menu-grid-cell::before {
- content: attr(data-day);
- position: absolute;
- top: 0.5rem;
- right: 0.5rem;
- font-size: 0.75rem;
- color: var(--text-muted);
- background-color: var(--surface2);
- padding: 0.25rem 0.5rem;
- border-radius: 0.25rem;
- }
+.recipe-card-actions {
+ display: flex;
+ gap: 0.5rem;
+ flex-wrap: wrap;
+ margin-top: 0.5rem;
}
/* ── Grocery List ───────────────────────────────────────────────────────── */
@@ -826,3 +826,163 @@ tbody tr.expiry-warn {
min-width: unset;
}
}
+
+.ai-notes-input {
+ width: 100%;
+ padding: 0.6rem 0.75rem;
+ background-color: var(--surface2);
+ border: 1px solid var(--border);
+ border-radius: 0.375rem;
+ color: var(--text);
+ font-size: 0.85rem;
+ resize: vertical;
+ font-family: inherit;
+ margin-bottom: 0.5rem;
+}
+
+.ai-notes-input:focus {
+ outline: none;
+ border-color: var(--accent);
+}
+
+.ai-notes-input::placeholder {
+ color: var(--text-muted);
+}
+
+.grocery-item-checked {
+ opacity: 0.45;
+}
+
+.grocery-item-checked .grocery-item-name {
+ text-decoration: line-through;
+}
+
+.modal-overlay {
+ position: fixed;
+ inset: 0;
+ background-color: rgba(0, 0, 0, 0.6);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 1000;
+}
+
+.modal {
+ background-color: var(--surface);
+ border: 1px solid var(--border);
+ border-radius: 0.75rem;
+ padding: 1.5rem;
+ width: 100%;
+ max-width: 420px;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.modal-title {
+ font-size: 1.1rem;
+ font-weight: 600;
+ color: var(--text);
+}
+
+.modal-subtitle {
+ font-size: 0.85rem;
+ color: var(--text-muted);
+ margin-top: -0.5rem;
+}
+
+.modal-actions {
+ display: flex;
+ justify-content: flex-end;
+ gap: 0.75rem;
+}
+
+.chat-container {
+ display: flex;
+ flex-direction: column;
+ height: calc(100vh - 180px);
+}
+
+.chat-messages {
+ flex: 1;
+ overflow-y: auto;
+ padding: 1rem 0;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.chat-welcome {
+ color: var(--text-muted);
+ font-style: italic;
+ text-align: center;
+ padding: 2rem;
+}
+
+.chat-message {
+ display: flex;
+}
+
+.chat-message-user {
+ justify-content: flex-end;
+}
+
+.chat-message-assistant {
+ justify-content: flex-start;
+}
+
+.chat-bubble {
+ max-width: 75%;
+ padding: 0.75rem 1rem;
+ border-radius: 1rem;
+ font-size: 0.9rem;
+ line-height: 1.6;
+ word-break: break-word;
+}
+
+.chat-message-user .chat-bubble {
+ background-color: var(--accent);
+ color: white;
+ border-bottom-right-radius: 0.25rem;
+}
+
+.chat-message-assistant .chat-bubble {
+ background-color: var(--surface2);
+ color: var(--text);
+ border-bottom-left-radius: 0.25rem;
+}
+
+.chat-typing-indicator {
+ color: var(--text-muted);
+ font-style: italic;
+}
+
+.chat-input-area {
+ display: flex;
+ gap: 0.75rem;
+ align-items: flex-end;
+ padding-top: 1rem;
+ border-top: 1px solid var(--border);
+}
+
+.chat-input {
+ flex: 1;
+ padding: 0.75rem;
+ background-color: var(--surface2);
+ border: 1px solid var(--border);
+ border-radius: 0.5rem;
+ color: var(--text);
+ font-size: 0.9rem;
+ resize: none;
+ font-family: inherit;
+ line-height: 1.5;
+}
+
+.chat-input:focus {
+ outline: none;
+ border-color: var(--accent);
+}
+
+.chat-input::placeholder {
+ color: var(--text-muted);
+}