Replace the hello-world shell with the elevated design system, bilingual screens, recipe/extras data, and the interactive Mein Teller view. Co-authored-by: Cursor <cursoragent@cursor.com>
193 lines
6.9 KiB
CSS
193 lines
6.9 KiB
CSS
/**
|
|
* Pocket Pascal — Elevated Surface Design Tokens
|
|
*
|
|
* Pivoted from heavy glassmorphism to a low-transparency, tactile system:
|
|
* cards read as solid raised surfaces (elevation shadow + faint top/bottom
|
|
* bevel), buttons visibly depress on press (inset shadow + 1px downward
|
|
* shift) instead of just scaling. `--glass-*` names kept for minimal diff
|
|
* across components — they now mean "surface fill / surface blur", not
|
|
* "see-through glass". Blur is low (8px) and opacity high (~88%): it softens
|
|
* whatever sits behind a card without reading as transparent.
|
|
*
|
|
* Toggle dark mode by adding/removing the `dark` class on <html>
|
|
* (matches Tailwind `darkMode: 'class'` — see README).
|
|
*
|
|
* Brand hues (protein/obstgem/fett/kh + ink) come from the WCAG-audited
|
|
* Pocket Pascal palette, not generic placeholders — see /docs/CONCEPT.html
|
|
* section 05/08 for the full rationale and contrast numbers.
|
|
*/
|
|
|
|
:root {
|
|
/* ---------- Elevated surface (formerly "glass") ---------- */
|
|
--glass-fill: rgba(255, 255, 255, 0.9);
|
|
--glass-blur: 8px;
|
|
/* top-light / bottom-shadow bevel instead of an even glass edge — reads as raised, not see-through */
|
|
--glass-border-from: rgba(255, 255, 255, 0.9);
|
|
--glass-border-to: rgba(0, 0, 0, 0.06);
|
|
|
|
/* ---------- Shadows (three states: resting, elevated/lifted, pressed-in) ---------- */
|
|
--shadow-resting: 0 1px 2px rgba(0, 0, 0, 0.06), 0 2px 6px rgba(0, 0, 0, 0.06);
|
|
--shadow-elevated: 0 4px 10px rgba(0, 0, 0, 0.10), 0 14px 28px rgba(0, 0, 0, 0.10);
|
|
--shadow-pressed: inset 0 2px 5px rgba(0, 0, 0, 0.28), inset 0 1px 1px rgba(0, 0, 0, 0.15);
|
|
/* kept for anything still referencing the old name */
|
|
--shadow-ambient: var(--shadow-elevated);
|
|
|
|
/* ---------- Brand ink / neutrals ---------- */
|
|
--ink: #191800;
|
|
--ink-soft: #5c5b48;
|
|
--ink-faint: #6b6a56;
|
|
--border: #e2e8f0;
|
|
|
|
/* ---------- Brand category colors (bright primary + dark accent pairs) ---------- */
|
|
--color-protein: #d9f227;
|
|
--color-protein-dk: #2e3200;
|
|
--color-obstgem: #ff6a3d;
|
|
--color-obstgem-dk: #3d1508;
|
|
--color-fett: #ffb300;
|
|
--color-fett-dk: #3d2900;
|
|
--color-kh: #1fd9c4;
|
|
--color-kh-dk: #04302b;
|
|
--color-pick: #0f7a37;
|
|
--color-caution: #c81e1e;
|
|
|
|
/* ---------- Surface gradients (subtle, sit UNDER glass layers) ---------- */
|
|
--surface-gradient: linear-gradient(160deg, #fafaf7 0%, #f0f0ea 100%);
|
|
--page-gradient: radial-gradient(120% 100% at 0% 0%, #fff9e0 0%, #ffffff 45%),
|
|
radial-gradient(120% 100% at 100% 100%, #e2fbf6 0%, #ffffff 45%);
|
|
|
|
/* ---------- Action gradients (vibrant, multi-stop) ---------- */
|
|
/* NOTE: brand hues are light/high-luminance by design (see contrast audit),
|
|
so action gradients pair with --ink text, not white — this keeps every
|
|
button at AA contrast without text-shadow hacks. Do not swap to white
|
|
text on these without re-checking contrast. */
|
|
--gradient-primary: linear-gradient(135deg, #d9f227 0%, #1fd9c4 100%);
|
|
--gradient-accent: linear-gradient(135deg, #ff6a3d 0%, #ffb300 100%);
|
|
--gradient-caution: linear-gradient(135deg, #ff6a3d 0%, #c81e1e 100%);
|
|
|
|
/* ---------- Dining Plate chart tokens ---------- */
|
|
--plate-rim-light: #ffffff;
|
|
--plate-rim-shadow: #d8d8d0;
|
|
--plate-well-center: #f7f7f2;
|
|
--plate-well-edge: #e6e6dd;
|
|
}
|
|
|
|
.dark {
|
|
--glass-fill: rgba(28, 28, 21, 0.88);
|
|
--glass-blur: 8px;
|
|
--glass-border-from: rgba(255, 255, 255, 0.10);
|
|
--glass-border-to: rgba(0, 0, 0, 0.35);
|
|
|
|
--shadow-resting: 0 1px 2px rgba(0, 0, 0, 0.4), 0 2px 6px rgba(0, 0, 0, 0.3);
|
|
--shadow-elevated: 0 4px 10px rgba(0, 0, 0, 0.45), 0 16px 32px rgba(0, 0, 0, 0.4);
|
|
--shadow-pressed: inset 0 2px 5px rgba(0, 0, 0, 0.6), inset 0 1px 1px rgba(0, 0, 0, 0.3);
|
|
--shadow-ambient: var(--shadow-elevated);
|
|
|
|
--ink: #f3f2e6;
|
|
--ink-soft: #c2c1ac;
|
|
--ink-faint: #8f8e7a;
|
|
--border: #33342a;
|
|
|
|
/* category primaries stay identical (they're the brand, not a theme) */
|
|
--color-protein: #d9f227;
|
|
--color-protein-dk: #2e3200;
|
|
--color-obstgem: #ff6a3d;
|
|
--color-obstgem-dk: #3d1508;
|
|
--color-fett: #ffb300;
|
|
--color-fett-dk: #3d2900;
|
|
--color-kh: #1fd9c4;
|
|
--color-kh-dk: #04302b;
|
|
--color-pick: #4ade80;
|
|
--color-caution: #ff6b60;
|
|
|
|
--surface-gradient: linear-gradient(160deg, #1c1c15 0%, #14140f 100%);
|
|
--page-gradient: radial-gradient(120% 100% at 0% 0%, #2a2a12 0%, #14140f 45%),
|
|
radial-gradient(120% 100% at 100% 100%, #0f2a26 0%, #14140f 45%);
|
|
|
|
--gradient-primary: linear-gradient(135deg, #d9f227 0%, #1fd9c4 100%);
|
|
--gradient-accent: linear-gradient(135deg, #ff6a3d 0%, #ffb300 100%);
|
|
--gradient-caution: linear-gradient(135deg, #ff6a3d 0%, #ff6b60 100%);
|
|
|
|
--plate-rim-light: #2a2a22;
|
|
--plate-rim-shadow: #0c0c09;
|
|
--plate-well-center: #1c1c15;
|
|
--plate-well-edge: #111109;
|
|
}
|
|
|
|
/* ---------- Fonts ---------- */
|
|
/* Download the two static woff2 files listed in README into /public/fonts,
|
|
then this block just works. Using local @font-face (not next/font) keeps
|
|
this file framework-agnostic for Cursor. */
|
|
@font-face {
|
|
font-family: "Unbounded";
|
|
font-weight: 700;
|
|
font-style: normal;
|
|
font-display: swap;
|
|
src: url("/fonts/unbounded-700.woff2") format("woff2");
|
|
}
|
|
@font-face {
|
|
font-family: "Unbounded";
|
|
font-weight: 900;
|
|
font-style: normal;
|
|
font-display: swap;
|
|
src: url("/fonts/unbounded-900.woff2") format("woff2");
|
|
}
|
|
@font-face {
|
|
font-family: "Albert Sans";
|
|
font-weight: 400;
|
|
font-style: normal;
|
|
font-display: swap;
|
|
src: url("/fonts/albert-sans-400.woff2") format("woff2");
|
|
}
|
|
@font-face {
|
|
font-family: "Albert Sans";
|
|
font-weight: 500;
|
|
font-style: normal;
|
|
font-display: swap;
|
|
src: url("/fonts/albert-sans-500.woff2") format("woff2");
|
|
}
|
|
@font-face {
|
|
font-family: "Albert Sans";
|
|
font-weight: 700;
|
|
font-style: normal;
|
|
font-display: swap;
|
|
src: url("/fonts/albert-sans-700.woff2") format("woff2");
|
|
}
|
|
|
|
.font-display {
|
|
font-family: "Unbounded", ui-sans-serif, sans-serif;
|
|
letter-spacing: -0.01em;
|
|
}
|
|
.font-body {
|
|
font-family: "Albert Sans", ui-sans-serif, "Segoe UI", Arial, sans-serif;
|
|
}
|
|
|
|
/* ---------- Glass border (gradient 1px border that respects border-radius) ---------- */
|
|
/* border-image ignores border-radius, so we use a masked pseudo-element instead.
|
|
Apply `.glass-border` to a `relative` container with `overflow-hidden` off
|
|
(the pseudo-element is inset:0 and radius:inherit). */
|
|
.glass-border {
|
|
border-radius: inherit;
|
|
padding: 1px;
|
|
/* top-light, bottom-shadow — reads as a raised bevel, not a glass sheen */
|
|
background: linear-gradient(180deg, var(--glass-border-from), var(--glass-border-to));
|
|
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
|
-webkit-mask-composite: xor;
|
|
mask-composite: exclude;
|
|
}
|
|
|
|
/* Applied on top of --shadow-elevated/--shadow-resting to animate between them. */
|
|
.elevation-transition {
|
|
transition: box-shadow 120ms ease-out, transform 120ms ease-out, filter 120ms ease-out;
|
|
}
|
|
|
|
/* ---------- PWA polish ---------- */
|
|
html,
|
|
body {
|
|
-webkit-tap-highlight-color: transparent;
|
|
overscroll-behavior-y: contain;
|
|
}
|
|
.no-select {
|
|
-webkit-user-select: none;
|
|
user-select: none;
|
|
}
|