fd4753905e
Removes decorative route-label h1s across fitness, recipe and cospend pages — replaced with sr-only h1s for assistive tech and a shared .sr-only utility in app.css. On the measure page, the tucked-away profile chip becomes a dismissible setup banner that only appears when sex/height/birth year are missing, with a permanent "Edit profile" link at the foot of the page.
535 lines
13 KiB
CSS
535 lines
13 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;
|
|
|
|
/* Shopping icon filter — white PNGs need invert in light mode */
|
|
--shopping-icon-filter: invert(1);
|
|
|
|
/* LinksGrid icon fills — colorful in light */
|
|
--grid-fill-base: var(--nord10);
|
|
--grid-fill-pop-a: var(--nord11);
|
|
--grid-fill-pop-b: var(--nord12);
|
|
--grid-fill-pop-c: var(--nord14);
|
|
}
|
|
|
|
/* ============================================
|
|
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);
|
|
|
|
--shopping-icon-filter: none;
|
|
|
|
/* LinksGrid icon fills — cool blues/whites in dark */
|
|
--grid-fill-base: var(--nord8);
|
|
--grid-fill-pop-a: var(--nord9);
|
|
--grid-fill-pop-b: var(--nord7);
|
|
--grid-fill-pop-c: var(--nord4);
|
|
}
|
|
}
|
|
|
|
/* 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);
|
|
|
|
--shopping-icon-filter: none;
|
|
|
|
--grid-fill-base: var(--nord8);
|
|
--grid-fill-pop-a: var(--nord9);
|
|
--grid-fill-pop-b: var(--nord7);
|
|
--grid-fill-pop-c: var(--nord4);
|
|
}
|
|
|
|
/* ============================================
|
|
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.
|
|
Covers the status-bar area; the bottom third fades out
|
|
to create a soft shadow at the boundary. */
|
|
body::before {
|
|
content: '';
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: calc(env(safe-area-inset-top, 0px) * 1.2);
|
|
background: linear-gradient(to bottom,
|
|
rgba(0, 0, 0, 0.4) 50%,
|
|
rgba(0, 0, 0, 0.32) 62%,
|
|
rgba(0, 0, 0, 0.2) 75%,
|
|
rgba(0, 0, 0, 0.1) 87%,
|
|
transparent);
|
|
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);
|
|
}
|
|
|
|
/* Visually hidden but accessible to screen readers */
|
|
.sr-only {
|
|
position: absolute;
|
|
width: 1px;
|
|
height: 1px;
|
|
padding: 0;
|
|
margin: -1px;
|
|
overflow: hidden;
|
|
clip: rect(0, 0, 0, 0);
|
|
white-space: nowrap;
|
|
border: 0;
|
|
}
|
|
|
|
/* 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;
|
|
}
|
|
}
|