Files
homepage/src/app.css
T
Alexander 4bbd733968 feat: inline custom meals, calorie ring overflow animation, theme fixes
Add custom meals tab to inline food add section with search/meals toggle.
Animate calorie ring overflow (red) after primary fill completes, with
separate glow elements so red overflow glows red independently. Apply same
delayed overflow animation to macro progress bars. Replace hardcoded nord8
with --color-primary throughout nutrition page (today badge, ring, tabs,
buttons). Add custom clear button to FoodSearch, hide number input spinners
globally.
2026-04-08 13:15:48 +02:00

493 lines
12 KiB
CSS

/* ============================================
BOCKEN.ORG CENTRALIZED STYLES
============================================ */
/* ============================================
FONT DEFINITIONS
============================================ */
@font-face {
font-family: 'crosses';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(/fonts/crosses.woff2) format('woff2'),
url(/fonts/crosses.ttf) format('truetype');
}
@font-face {
font-family: 'Noto Color Emoji Subset';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(/fonts/NotoColorEmoji.woff2) format('woff2'),
url(/fonts/NotoColorEmoji.ttf) format('truetype');
}
/* ============================================
COLOR SYSTEM
Based on Nord Theme with semantic naming
============================================ */
:root {
/* ============================================
BASE NORD COLORS
Keep original Nord colors for reference
============================================ */
--nord0: #2E3440;
--nord1: #3B4252;
--nord2: #434C5E;
--nord3: #4C566A;
--nord4: #D8DEE9;
--nord5: #E5E9F0;
--nord6: #ECEFF4;
--nord7: #8FBCBB;
--nord8: #88C0D0;
--nord9: #81A1C1;
--nord10: #5E81AC;
--nord11: #BF616A;
--nord12: #D08770;
--nord13: #EBCB8B;
--nord14: #A3BE8C;
--nord15: #B48EAD;
/* Named color aliases (backward compatibility) */
--lightblue: var(--nord9);
--blue: var(--nord10);
--red: var(--nord11);
--orange: var(--nord12);
--yellow: var(--nord13);
--green: var(--nord14);
--purple: var(--nord15);
/* ============================================
SEMANTIC COLOR SYSTEM - LIGHT MODE
Warm, easy-on-the-eyes palette
Two accents only: blue (interactive) + red (emphasis)
============================================ */
/* Primary Color - Main interactive elements */
--color-primary: var(--nord10);
--color-primary-hover: var(--nord9);
--color-primary-active: var(--nord8);
/* Accent Color - Call-to-action, emphasis */
--color-accent: var(--nord11);
--color-accent-hover: #d07179;
--color-accent-active: #a04e56;
/* Secondary Accent - demoted to match primary for consistency */
--color-secondary: var(--nord10);
--color-secondary-hover: var(--nord9);
--color-secondary-active: var(--nord8);
/* Background Colors */
--color-bg-primary: #f8f6f1;
--color-bg-secondary: #efecea;
--color-bg-tertiary: #e8e5e1;
--color-bg-elevated: #dfdcd8;
/* Surface Colors (cards, panels, etc.) */
--color-surface: #efecea;
--color-surface-hover: #e8e5e1;
/* Text Colors */
--color-text-primary: #2a2a2a;
--color-text-secondary: #555;
--color-text-tertiary: #777;
--color-text-inverse: white;
--color-text-on-primary: white;
--color-text-on-accent: white;
--color-text-muted: #aaa;
/* UI Element Colors */
--color-ui-dark: #2a2a2a;
--color-ui-mid: #777;
--color-ui-light: #bbb;
--color-ui-hover: #555;
/* Border Colors */
--color-border: #ddd;
--color-border-hover: #bbb;
/* Link Colors */
--color-link: var(--nord10);
--color-link-visited: var(--nord15);
--color-link-hover: var(--nord9);
/* Status Colors */
--color-success: var(--nord14);
--color-warning: var(--nord13);
--color-error: var(--nord11);
--color-info: var(--nord10);
/* Shared transitions & shadows */
--transition-fast: 100ms;
--transition-normal: 200ms;
--shadow-sm: 0 0 0.4em 0.05em rgba(0,0,0,0.2);
--shadow-md: 0 0 0.5em 0.1em rgba(0,0,0,0.3);
--shadow-lg: 0 0 1em 0.1em rgba(0,0,0,0.4);
--shadow-hover: 0.1em 0.1em 0.5em 0.1em rgba(0,0,0,0.3);
--radius-pill: 1000px;
--radius-card: 20px;
--radius-sm: 0.3rem;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
/* Spacing scale */
--space-xs: 0.25rem;
--space-sm: 0.5rem;
--space-md: 1rem;
--space-lg: 1.5rem;
--space-xl: 2rem;
--space-2xl: 3rem;
/* Font size scale */
--text-sm: 0.85rem;
--text-base: 1rem;
--text-lg: 1.1rem;
--text-xl: 1.5rem;
--text-2xl: 2rem;
--text-3xl: 3rem;
}
/* ============================================
DARK MODE COLOR OVERRIDES
============================================ */
/* System prefers dark, but user hasn't forced light */
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
/* Dark mode primitives - true black base */
--nord6-dark: #1a1a1a;
--accent-dark: #1a1a1a;
--background-dark: #000;
--font-default-dark: #e5e5e5;
/* Primary Color - frost blue, the single interactive accent */
--color-primary: var(--nord8);
--color-primary-hover: var(--nord7);
--color-primary-active: var(--nord9);
/* Accent Color - red, for emphasis and actions */
--color-accent: var(--nord11);
--color-accent-hover: #d07179;
--color-accent-active: #a04e56;
/* Secondary Accent - same as primary for consistency */
--color-secondary: var(--nord8);
--color-secondary-hover: var(--nord7);
--color-secondary-active: var(--nord9);
/* Background Colors - true black hierarchy */
--color-bg-primary: #000;
--color-bg-secondary: #111;
--color-bg-tertiary: #1a1a1a;
--color-bg-elevated: #222;
/* Surface Colors - subtle lift from black */
--color-surface: #1a1a1a;
--color-surface-hover: #222;
/* Text Colors - soft white, not blinding */
--color-text-primary: #e5e5e5;
--color-text-secondary: #aaa;
--color-text-tertiary: #888;
--color-text-inverse: #111;
--color-text-on-primary: #000;
--color-text-on-accent: white;
--color-text-muted: #555;
/* UI Element Colors */
--color-ui-dark: #e5e5e5;
--color-ui-mid: #888;
--color-ui-light: #444;
--color-ui-hover: #666;
/* Border Colors */
--color-border: #333;
--color-border-hover: #444;
/* Link Colors - frost blue */
--color-link: var(--nord8);
--color-link-visited: #c89fb6;
--color-link-hover: var(--nord7);
}
}
/* User forced dark mode */
:root[data-theme="dark"] {
--nord6-dark: #1a1a1a;
--accent-dark: #1a1a1a;
--background-dark: #000;
--font-default-dark: #e5e5e5;
--color-primary: var(--nord8);
--color-primary-hover: var(--nord7);
--color-primary-active: var(--nord9);
--color-accent: var(--nord11);
--color-accent-hover: #d07179;
--color-accent-active: #a04e56;
--color-secondary: var(--nord8);
--color-secondary-hover: var(--nord7);
--color-secondary-active: var(--nord9);
--color-bg-primary: #000;
--color-bg-secondary: #111;
--color-bg-tertiary: #1a1a1a;
--color-bg-elevated: #222;
--color-surface: #1a1a1a;
--color-surface-hover: #222;
--color-text-primary: #e5e5e5;
--color-text-secondary: #aaa;
--color-text-tertiary: #888;
--color-text-inverse: #111;
--color-text-on-primary: #000;
--color-text-on-accent: white;
--color-text-muted: #555;
--color-ui-dark: #e5e5e5;
--color-ui-mid: #888;
--color-ui-light: #444;
--color-ui-hover: #666;
--color-border: #333;
--color-border-hover: #444;
--color-link: var(--nord8);
--color-link-visited: #c89fb6;
--color-link-hover: var(--nord7);
}
/* ============================================
BASE STYLES
============================================ */
* {
box-sizing: border-box;
font-family: Helvetica, Arial, "Noto Sans", sans-serif;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
appearance: textfield;
}
body {
margin: 0;
padding: 0;
background-color: var(--color-bg-primary);
color: var(--color-text-primary);
overflow-x: hidden;
}
/* Status bar drop shadow for edge-to-edge Android/Tauri.
Sits flush at the top; the downward shadow marks the
boundary between status bar and page content. */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
right: 0;
height: env(safe-area-inset-top, 0px);
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4);
z-index: 9999;
pointer-events: none;
}
/* ============================================
LINK STYLES
============================================ */
a:not(:visited) {
color: var(--color-link);
}
a:visited {
color: var(--color-link-visited);
}
a:hover,
a:focus-visible {
color: var(--color-link-hover);
}
/* ============================================
GLOBAL UTILITY CLASSES
============================================ */
/* Pill-shaped element base */
.g-pill {
border-radius: var(--radius-pill);
border: none;
cursor: pointer;
display: inline-block;
text-decoration: none;
transition: var(--transition-fast);
}
/* Interactive hover/focus effects */
.g-interactive {
transition: var(--transition-fast);
}
.g-interactive:hover,
.g-interactive:focus-visible {
transform: scale(1.05);
box-shadow: var(--shadow-hover);
}
.g-interactive:focus {
scale: 0.9;
}
/* Light background button (with dark mode) */
.g-btn-light {
background-color: var(--color-surface);
color: var(--color-text-primary);
box-shadow: var(--shadow-sm);
}
/* Dark background button - stays dark in both modes */
.g-btn-dark,
.g-btn-dark:visited,
.g-btn-dark:link {
background-color: var(--nord0);
color: var(--nord6);
box-shadow: var(--shadow-lg);
}
.g-btn-dark:hover,
.g-btn-dark:focus-visible {
background-color: var(--nord1);
color: var(--nord6);
}
/* Icon badge (circular icon container) */
.g-icon-badge {
font-family: "Noto Color Emoji", "Noto Color Emoji Subset", emoji, sans-serif;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
text-decoration: none;
transition: var(--transition-fast);
box-shadow: var(--shadow-lg);
}
.g-icon-badge:hover,
.g-icon-badge:focus-visible {
transform: scale(1.1);
box-shadow: var(--shadow-hover);
}
/* Tag/chip styling */
.g-tag,
.g-tag:visited,
.g-tag:link {
padding: 0.25em 1em;
border-radius: var(--radius-pill);
background-color: var(--color-surface);
color: var(--color-text-primary);
text-decoration: none;
cursor: pointer;
transition: transform var(--transition-fast), background-color var(--transition-fast), box-shadow var(--transition-fast), color var(--transition-fast);
box-shadow: var(--shadow-sm);
border: none;
display: inline-block;
}
.g-tag:hover,
.g-tag:focus-visible {
transform: scale(1.05);
background-color: var(--color-primary);
box-shadow: var(--shadow-hover);
color: var(--color-text-on-primary);
}
/* ============================================
VIEW TRANSITIONS
Disable default crossfade on page content;
only named elements (header, logo, etc.) animate.
============================================ */
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
}
/* ============================================
RECIPE GRID
Responsive card grid used across recipe pages
============================================ */
.recipe-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 0.8em;
padding: 0 0.8em;
max-width: 1400px;
margin: 0 auto 2em;
}
@media (max-width: 250px) {
.recipe-grid {
grid-template-columns: 1fr;
}
}
@media (min-width: 600px) {
.recipe-grid {
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1.5em;
padding: 0 1.5em;
}
}
@media (min-width: 1024px) {
.recipe-grid {
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 1.8em;
}
}
/*
Scrollbar
*/
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background-color: var(--color-font-primary);
border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
background-color: var(--color-font-primary);
}
/*Firefox*/
* {
scrollbar-width: thin; /* auto | thin | none */
scrollbar-color: rgba(0, 0,0,0.3) transparent;
}
html {
scrollbar-gutter: stable;
}
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-thumb {
background: rgba(0,0,0,0.3);
border-radius: 10px;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]){
scrollbar-color: rgba(255, 255,255,0.3) transparent;
}
}