/* 01-basis.css — Design-Tokens (Farben, Abstände, Schriften) + Reset/Grundlagen. Teil der geordneten Kaskade: in index.html in Nummern-Reihenfolge geladen; Regeln NICHT zwischen Dateien verschieben, ohne die Reihenfolge zu bedenken. */
/* ════════════════════════════════════════════════════════════════════════════
   ESSENSPLANER – Design System v2
   Inspiriert von iOS 26 Liquid Glass · Linear 2025 · Things 3 · Apple Notes
   ──────────────────────────────────────────────────────────────────────────
   Token-Diet: 6 Radii · 3 Shadows · 4er-Spacing · iOS-Type-Scale
   Hairline-Borders statt Drop-Shadows · Capsule-Buttons · Floating Tab-Bar
   ════════════════════════════════════════════════════════════════════════════ */

/* ─── DESIGN TOKENS ─────────────────────────────────────────────────────── */
:root {
  /* Glas-Stärke: globaler Multiplikator für alle backdrop-filter blur() (1 = Standard).
     Der Regler im Design-Sheet (nur Dev-Modus) setzt diesen Wert geräte-lokal. */
  --glass-mult: 1;
  /* Spacing – striktes 4er System */
  --sp-1: 4px;   --sp-2: 8px;   --sp-3: 12px;  --sp-4: 16px;
  --sp-5: 20px;  --sp-6: 24px;  --sp-8: 32px;  --sp-12: 48px;

  /* Border-Radii – 6 Stufen total */
  --r-xs: 8px;       /* Tags, Chips, kleine Icons */
  --r-sm: 12px;      /* Inputs, kleine Cards */
  --r-md: 16px;      /* Standard-Cards, Buttons */
  --r-lg: 20px;      /* Hero-Cards, Bottom-Sheets */
  --r-xl: 24px;      /* Modal-Top, Lightbox */
  --r-pill: 999px;   /* Capsule-Buttons, Pills, Nav-Pills */

  /* Typography – iOS-Type-Scale */
  --fs-cap:     11px;
  --fs-foot:    13px;
  --fs-body:    15px;
  --fs-callout: 16px;
  --fs-head:    17px;
  --fs-t3:      20px;
  --fs-t2:      22px;
  --fs-t1:      28px;

  /* Font-Weights – reduziert, kein 900 mehr */
  --fw-reg:   500;
  --fw-med:   600;
  --fw-bold:  700;
  --fw-heavy: 800;

  /* Letter-Spacing */
  --ls-tight: -0.02em;
  --ls-snug:  -0.01em;
  --ls-wide:   0.06em;

  /* Shadows – subtle */
  --shadow-sm:  0 1px 2px rgba(0,0,0,0.18);
  --shadow-md:  0 4px 20px rgba(0,0,0,0.22);
  --shadow-lg:  0 8px 32px rgba(0,0,0,0.32);
  --shadow-xl:  0 16px 60px rgba(0,0,0,0.45);
  --ring:       inset 0 0 0 1px rgba(255,255,255,0.08);

  /* Z-Index */
  --z-base:    1;
  --z-sticky:  50;
  --z-nav:     100;
  --z-modal:   200;
  --z-popover: 300;
  /* Toast über ALLEN Modalen/Sheets (cookidoo 4100, lightbox 4300, shop-photo
     9200, voice 9300) — sonst sind Bestätigungs-/Fehler-Toasts unsichtbar, wenn
     eines dieser Overlays offen ist (z.B. „✓ hinzugefügt" beim Voice-/Cookidoo-Import). */
  --z-toast:   10000;

  /* Theme-Vars (werden von theme.js überschrieben) */
  --blue: #0284C7;
  --blue-rgb: 2,132,199;
  --blue-light: #38BDF8;
  --teal: #0D9488;
  --teal-light: #2DD4BF;
  --bg: #080C14;
  --card: #1B1B1E;
  --card2: #232326;
  --text: #F0F6FF;
  --text-muted: rgba(255,255,255,0.55);
  --text-accent: #F0F6FF;
  --border: rgba(255,255,255,0.10);
  --shadow: var(--shadow-md);
  --header-glow: rgba(2,132,199,0.18);
  --modal-bg: #1B1B1E;
  --input-bg: rgba(255,255,255,0.06);
  --nav-bg: rgba(20,20,22,0.72);
  --cell-bg: rgba(255,255,255,0.05);
  --cell-border: rgba(255,255,255,0.08);
  --cell-glow: rgba(56,189,248,0.20);
  --cell-add: rgba(255,255,255,0.40);
  --card-tint: rgba(255,255,255,0.04);
  --card-border-tint: rgba(255,255,255,0.08);
  --bg-tint: rgba(56,189,248,0.04);
  --cell-glow-rgb: 56,189,248;
  --header-bg: linear-gradient(160deg, #0F172A 0%, #1E3A5F 45%, #0F2D40 100%);
  --page-bg: #080C14;
  --btn-grad: var(--blue);

  /* ── Motion-System (premium / „NVIDIA"-Feel) — gemeinsamer Rhythmus für alle
     Einstellungs-Animationen. Nur transform/opacity/grid-rows werden animiert. */
  --mo-1: 110ms;   /* Press/Tap-Down, Mikro-Feedback */
  --mo-2: 180ms;   /* Tints, Switch-Track-Farbe, Chip-Hintergrund */
  --mo-3: 260ms;   /* Knob-Slide, Chevron, Stagger-Kind */
  --mo-4: 340ms;   /* Cluster Auf/Zu (Höhe + Fade) */
  --mo-5: 460ms;   /* Sheet-Slide, große Auftritte */
  --mo-stagger: 42ms;
  --ease-out-quint:   cubic-bezier(0.22, 1, 0.36, 1);     /* Ausklingen ohne Overshoot */
  --ease-smooth:      cubic-bezier(0.32, 0.72, 0, 1);     /* iOS-Decel */
  --ease-spring:      cubic-bezier(0.34, 1.56, 0.64, 1);  /* federnder Overshoot */
  --ease-spring-soft: cubic-bezier(0.34, 1.32, 0.64, 1);  /* dezenter Overshoot */

  /* Semantic */
  --danger: #F87171;
  --danger-bg: rgba(248,113,113,0.12);
  --success: #34D399;
}

/* ─── RESET & BASE ──────────────────────────────────────────────────────── */
* {
  box-sizing: border-box;
  margin: 0; padding: 0;
  -webkit-tap-highlight-color: transparent;
}
html, body {
  height: 100%;
  font-family: 'Nunito', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: var(--page-bg);
  color: var(--text);
  overflow-x: hidden;
  touch-action: pan-x pan-y;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-weight: var(--fw-reg);
  font-size: var(--fs-body);
  line-height: 1.4;
}
/* body ist ein ELEMENT-Scroller (overflow-y:auto): sein Scrollbalken erschien nur
   auf scrollenden Seiten (Einkauf/Profil) und drückte #app samt Nav-Leiste 15px
   schmaler — beim Tab-Wechsel „sprang" die Leiste. stable reserviert den Platz
   dauerhaft. NUR auf body (im html,body-Block würde doppelt reserviert); am
   Handy (Overlay-Scrollbars) ändert sich gar nichts. */
body { scrollbar-gutter: stable; }
#app {
  height: 100vh;
  /* dvh = tatsächlich SICHTBARER Viewport am Handy (Safari-/PWA-Leisten,
     Home-Indicator). Mit reinem 100vh ragte die Bottom-Nav unten leicht aus
     dem Bild → Tab-Beschriftung wirkte abgeschnitten. Fallback oben bleibt. */
  height: 100dvh;
  flex-direction: column;
  width: 100%;
  display: flex;
}
/* Anti-Flicker beim Start (siehe Inline-Script im <head>): eine vor dem ersten
   Paint gesetzte <html>-Klasse blendet den falschen Screen sofort aus, damit
   beim Öffnen nicht kurz das Login aufblitzt. Ohne Klasse (Fallback) bleibt das
   bisherige Verhalten. Inline-style.display aus showLogin()/initApp() übersteuert
   diese Regeln vollständig (höhere Spezifität durch inline). */
html.boot-authed #loginScreen { display: none; }
html.boot-guest #app { display: none; }
#calendarPage, #statsPage, #shopPage, #profilePage, #monthCalPage {
  background: var(--page-bg);
  flex: 1;
  min-height: 0;
  width: 100%;
}
.stats-body, .profile-body { background: var(--page-bg); }

/* Calendar-Page: kein Scroll — Cards flexen auf verfügbare Höhe.
   #app ist height:100vh + flex column. Page flext im verbleibenden Raum
   nach Bottom-Nav, der eigene flex-Block sorgt für Cards-Stretch. */
#calendarPage {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* Kein vertikales Scrollen im Kalender — Cards flexen ohnehin auf
     verfügbare Höhe. touch-action:none blockt nativen Browser-Scroll
     (inkl. iOS-Bounce) und überlässt alle Gesten unserem Swipe-Handler. */
  touch-action: none;
  overscroll-behavior: none;
}
#calendarPage .calendar-wrap { touch-action: none; overscroll-behavior: none; }
#calendarPage .header { flex-shrink: 0; }
.calendar-wrap {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  /* WICHTIG: kein Padding hier — sonst sliden Grids in den Padding-Bereich
     hinein und werden NICHT geclippt. Padding wird stattdessen pro .calendar-grid
     gesetzt, damit der Slide über die volle Wrap-Breite läuft. */
  padding: 0;
  position: relative;
}
/* Two-Container-Track für Wochen-Wechsel-Animation. Während der Animation
   sitzen alte und neue Woche als zwei Flex-Children innerhalb dieses Tracks,
   der wiederum innerhalb der .calendar-wrap mit overflow:hidden steckt.
   Damit ist Edge-Bleed unmöglich. */
.calendar-track {
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 100%;
  will-change: transform;
  backface-visibility: hidden;
}
.calendar-track > .calendar-grid {
  flex: 0 0 100%;
  min-width: 0;
  height: 100%;
}
.calendar-grid {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  /* Padding direkt am Grid (statt am .calendar-wrap), damit der Carousel-Slide
     über die volle Wrap-Breite läuft ohne in transparente Padding-Bereiche
     zu ragen. box-sizing:border-box sorgt dafür dass width/height inkl.
     Padding bleiben, damit das Flex-Layout konsistent bleibt. */
  padding: var(--sp-3) var(--sp-4) var(--sp-3);
  box-sizing: border-box;
}
.week-row {
  flex: 1;
  min-height: 56px;
}
button { font-family: inherit; }

