/* ══════════════════════════════════════════════════════════════════════
   Collrd — utilities.css
   Utility-Klassen für Phase F1 (Inline-Style-Audit)
   Naming: Tailwind-ähnlich, ohne Prefix
   Stand: 30. März 2026
   ══════════════════════════════════════════════════════════════════════ */


/* ── Display ──────────────────────────────────────────────────────── */

.d-none          { display: none; }
.d-block         { display: block; }
.d-inline        { display: inline; }
.d-inline-block  { display: inline-block; }
.d-flex          { display: flex; }
.d-inline-flex   { display: inline-flex; }
.d-grid          { display: grid; }


/* ── Flexbox ──────────────────────────────────────────────────────── */

.flex-row        { flex-direction: row; }
.flex-col        { flex-direction: column; }
.flex-wrap       { flex-wrap: wrap; }
.flex-nowrap     { flex-wrap: nowrap; }
.flex-1          { flex: 1; }
.shrink-0        { flex-shrink: 0; }
.grow-0          { flex-grow: 0; }

.items-center    { align-items: center; }
.items-start     { align-items: flex-start; }
.items-end       { align-items: flex-end; }
.items-stretch   { align-items: stretch; }

.justify-start   { justify-content: flex-start; }
.justify-center  { justify-content: center; }
.justify-end     { justify-content: flex-end; }
.justify-between { justify-content: space-between; }
.justify-around  { justify-content: space-around; }


/* ── Gap (8px base scale) ─────────────────────────────────────────── */

.gap-1           { gap: var(--space-1); }   /*  4px */
.gap-2           { gap: var(--space-2); }   /*  8px */
.gap-3           { gap: var(--space-3); }   /* 12px */
.gap-4           { gap: var(--space-4); }   /* 16px */
.gap-5           { gap: var(--space-5); }   /* 20px */
.gap-6           { gap: var(--space-6); }   /* 24px */
.gap-8           { gap: var(--space-8); }   /* 32px */

/* Named gap aliases for common inline patterns */
.gap-6px         { gap: 6px; }
.gap-10px        { gap: 10px; }


/* ── Margin Top ───────────────────────────────────────────────────── */

.mt-0            { margin-top: 0; }
.mt-1            { margin-top: var(--space-1); }   /*  4px */
.mt-2            { margin-top: var(--space-2); }   /*  8px */
.mt-3            { margin-top: var(--space-3); }   /* 12px */
.mt-4            { margin-top: var(--space-4); }   /* 16px */
.mt-5            { margin-top: var(--space-5); }   /* 20px */
.mt-6            { margin-top: var(--space-6); }   /* 24px */
.mt-8            { margin-top: var(--space-8); }   /* 32px */
.mt-10           { margin-top: var(--space-10); }  /* 40px */

/* Pixel-specific (for patterns that don't fit 8px scale) */
.mt-6px          { margin-top: 6px; }
.mt-14px         { margin-top: 14px; }
.mt-18px         { margin-top: 18px; }


/* ── Margin Bottom ────────────────────────────────────────────────── */

.mb-0            { margin-bottom: 0; }
.mb-1            { margin-bottom: var(--space-1); }   /*  4px */
.mb-2            { margin-bottom: var(--space-2); }   /*  8px */
.mb-3            { margin-bottom: var(--space-3); }   /* 12px */
.mb-4            { margin-bottom: var(--space-4); }   /* 16px */
.mb-5            { margin-bottom: var(--space-5); }   /* 20px */
.mb-6            { margin-bottom: var(--space-6); }   /* 24px */
.mb-8            { margin-bottom: var(--space-8); }   /* 32px */

/* Pixel-specific */
.mb-6px          { margin-bottom: 6px; }
.mb-10px         { margin-bottom: 10px; }
.mb-14px         { margin-bottom: 14px; }
.mb-18px         { margin-bottom: 18px; }


/* ── Margin Left / Right / Auto ───────────────────────────────────── */

.ml-auto         { margin-left: auto; }
.mr-auto         { margin-right: auto; }
.mx-auto         { margin-left: auto; margin-right: auto; }
.ml-2            { margin-left: var(--space-2); }
.mr-2            { margin-right: var(--space-2); }
.mx-3            { margin-left: var(--space-3); margin-right: var(--space-3); }

/* Reset */
.m-0             { margin: 0; }


/* ── Padding ──────────────────────────────────────────────────────── */

.p-0             { padding: 0; }
.p-1             { padding: var(--space-1); }
.p-2             { padding: var(--space-2); }
.p-3             { padding: var(--space-3); }
.p-4             { padding: var(--space-4); }
.p-6             { padding: var(--space-6); }
.p-8             { padding: var(--space-8); }

.px-2            { padding-left: var(--space-2); padding-right: var(--space-2); }
.px-4            { padding-left: var(--space-4); padding-right: var(--space-4); }
.py-2            { padding-top: var(--space-2); padding-bottom: var(--space-2); }
.py-3            { padding-top: var(--space-3); padding-bottom: var(--space-3); }
.py-8            { padding-top: var(--space-8); padding-bottom: var(--space-8); }
.pb-3            { padding-bottom: var(--space-3); }
.ml-auto         { margin-left: auto; }


/* ── Width / Height ───────────────────────────────────────────────── */

.w-full          { width: 100%; }
.w-auto          { width: auto; }
.min-w-0         { min-width: 0; }
.max-w-200       { max-width: 200px; }
.max-w-300       { max-width: 300px; }
.max-w-440       { max-width: 440px; }
.max-w-480       { max-width: 480px; }
.max-w-520       { max-width: 520px; }

.max-h-200       { max-height: 200px; }


/* ── Text Alignment ───────────────────────────────────────────────── */

.text-left       { text-align: left; }
.text-center     { text-align: center; }
.text-right      { text-align: right; }


/* ── Text Colors (Design-System Tokens) ───────────────────────────── */

.text-primary    { color: var(--text-primary); }
.text-secondary  { color: var(--text-secondary); }
.text-tertiary   { color: var(--text-tertiary); }
.text-disabled   { color: var(--text-disabled); }
.text-gold       { color: var(--gold); }
.text-gold-light { color: var(--gold-light); }
.text-magenta    { color: var(--neon-magenta); }
.text-cyan       { color: var(--neon-cyan); }
.text-violet     { color: var(--neon-violet); }
.text-error      { color: var(--status-error); }
.text-success    { color: var(--status-success); }
.text-warning    { color: var(--status-warning); }
.text-white      { color: #fff; }


/* ── Font Size (Design-System v2.1 Scale) ────────────────────────────── */

.text-2xs        { font-size: 11px; }   /* --type-micro */
.text-xs         { font-size: 12px; }   /* --type-caption */
.text-sm         { font-size: 14px; }   /* --type-body-sm */
.text-base       { font-size: 16px; }   /* --type-body */
.text-md         { font-size: 16px; }   /* --type-heading-md */
.text-lg         { font-size: 20px; }   /* --type-heading-lg */
.text-xl         { font-size: 24px; }   /* --type-display-md */
.text-2xl        { font-size: 32px; }   /* --type-display-lg */
.text-3xl        { font-size: 48px; }   /* --type-display-xl */


/* ── Font Weight ──────────────────────────────────────────────────── */

.font-normal     { font-weight: 400; }
.font-medium     { font-weight: 500; }
.font-semibold   { font-weight: 600; }
.font-bold       { font-weight: 700; }
.font-extrabold  { font-weight: 800; }


/* ── Font Family ──────────────────────────────────────────────────── */

.font-display    { font-family: var(--font-display); }
.font-body       { font-family: var(--font-body); }
.font-mono       { font-family: var(--font-mono); }


/* ── Font Style ───────────────────────────────────────────────────── */

.italic          { font-style: italic; }
.not-italic      { font-style: normal; }
.uppercase       { text-transform: uppercase; }
.lowercase       { text-transform: lowercase; }
.capitalize      { text-transform: capitalize; }
.no-underline    { text-decoration: none; }
.line-through    { text-decoration: line-through; }


/* ── Line Height ──────────────────────────────────────────────────── */

.leading-tight   { line-height: 1.1; }
.leading-snug    { line-height: 1.3; }
.leading-normal  { line-height: 1.6; }
.leading-relaxed { line-height: 1.8; }


/* ── Whitespace / Overflow / Truncation ────────────────────────────── */

.whitespace-nowrap  { white-space: nowrap; }
.whitespace-pre     { white-space: pre-wrap; }
.overflow-hidden    { overflow: hidden; }
.overflow-y-auto    { overflow-y: auto; }
.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* ── Opacity ──────────────────────────────────────────────────────── */

.opacity-30      { opacity: 0.3; }
.opacity-40      { opacity: 0.4; }
.opacity-50      { opacity: 0.5; }
.opacity-60      { opacity: 0.6; }
.opacity-70      { opacity: 0.7; }


/* ── Cursor ───────────────────────────────────────────────────────── */

.cursor-pointer  { cursor: pointer; }
.cursor-default  { cursor: default; }
.pointer-events-none { pointer-events: none; }


/* ── Borders ──────────────────────────────────────────────────────── */

.border          { border: 1px solid var(--border-default); }
.border-subtle   { border: 1px solid var(--border-subtle); }
.border-strong   { border: 1px solid var(--border-strong); }
.border-t        { border-top: 1px solid var(--border-default); }
.border-b        { border-bottom: 1px solid var(--border-default); }
.border-l-3      { border-left: 3px solid var(--border-default); }
.border-violet   { border-color: var(--neon-violet); }
.border-gold     { border-color: var(--gold); }

.rounded-sm      { border-radius: var(--radius-sm); }
.rounded-md      { border-radius: var(--radius-md); }
.rounded-lg      { border-radius: var(--radius-lg); }
.rounded-full    { border-radius: 9999px; }
.rounded-circle  { border-radius: 50%; }


/* ── Background Colors ────────────────────────────────────────────── */

.bg-void         { background: var(--bg-void); }
.bg-surface      { background: var(--bg-surface); }
.bg-card         { background: var(--bg-card); }
.bg-elevated     { background: var(--bg-elevated); }
.bg-hover        { background: var(--bg-hover); }


/* ── Positioning ──────────────────────────────────────────────────── */

.relative        { position: relative; }
.absolute        { position: absolute; }
.sticky          { position: sticky; }


/* ── Grid Shortcuts ───────────────────────────────────────────────── */

.grid-2          { display: grid; grid-template-columns: 1fr 1fr; }
.grid-3          { display: grid; grid-template-columns: 1fr 1fr 1fr; }
.grid-4          { display: grid; grid-template-columns: repeat(4, 1fr); }

/* F6b: Phone — alle Grids auf Single-Column */
@media (max-width: 480px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
}


/* ── Interaction States ───────────────────────────────────────────── */

.disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}


/* ── Screen Reader Only ───────────────────────────────────────────── */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}


/* ── Letter Spacing ───────────────────────────────────────────────── */

.tracking-wide   { letter-spacing: 1.5px; }
.tracking-wider  { letter-spacing: 3px; }
.my-4            { margin-top: var(--space-4); margin-bottom: var(--space-4); }
.grid-3-col      { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; }

/* F6b: Phone — grid-3-col Single-Column */
@media (max-width: 480px) {
  .grid-3-col { grid-template-columns: 1fr; }
}


/* ── K.5 / CSP: Initial-State-Hide Classes ───────────────────────── */
/* Ersatz fuer style="display:none" / style="display:inline" Inline-Styles
   ohne JS-Bruch. JS-Toggling via element.style.display = '...' überschreibt
   diese Klassen weiterhin (Spezifität: inline-style > class).

   Doppelte Klassen-Selektoren (.X.X) erhöhen die Spezifität auf 0,2,0,
   ohne !important zu brauchen. Das überschreibt single-class CSS-Regeln
   wie .modal-overlay { display: flex } aus modules.css. Ohne diesen Trick
   würde z.B. .deletion-modal-overlay { display: flex } (modules.css)
   die spätere .is-init-hidden { display: none } (utilities.css) bei
   gleicher Spezifität overrullen, da modules.css NACH utilities.css lädt.

   Nicht verwenden, wenn das Element via .d-none-Toggling gesteuert wird
   (Memory-Lesson: d-none und style.display sind mutually exclusive). */
.is-init-hidden.is-init-hidden { display: none; }
.is-init-inline.is-init-inline { display: inline; }
.is-init-flex.is-init-flex     { display: flex; }

/* ── K.5 / CSP: Weitere Inline-Style-Replacements ─────────────────── */
.mx-1            { margin-left: var(--space-1); margin-right: var(--space-1); }   /* 4px */
.my-3            { margin-top: var(--space-3); margin-bottom: var(--space-3); }   /* 12px */
/* Neon-Magenta Drop-Shadow (Hero-Ring, Crown-Icons) */
.glow-magenta-sm { filter: drop-shadow(0 0 6px rgba(255,45,123,0.4)); }
.glow-magenta-md { filter: drop-shadow(0 0 8px rgba(255,45,123,0.4)); }

/* Border-Left-Tinting für Karten (Mantras, Tasks, Punishments etc.) */
.bl-violet       { border-left: 3px solid var(--neon-violet); }
.bl-magenta      { border-left: 3px solid var(--neon-magenta); }
.bl-cyan         { border-left: 3px solid var(--neon-cyan); }
.bl-gold         { border-left: 3px solid var(--gold); }
.bl-border       { border-left: 3px solid var(--border-default); }
.bl-success      { border-left: 3px solid var(--status-success); }
.bl-error        { border-left: 3px solid var(--status-error); }

/* Modal-Stack: Inner-Modal über Parent (Edit-Modals von Dom-FAB-Modals) */
.modal-overlay--top { z-index: 1100; }

/* Generische 1px Border (für Card-Banner etc.) */
.bordered           { border: 1px solid var(--border-default); }

/* Badge-Icon-Image (18×18, contain) */
.badge-icon-img     { width: 18px; height: 18px; object-fit: contain; }

/* Profil-Role-Tag (Default-Variante ohne Server-Color) */
.profil-role-tag--default {
  color: var(--text-secondary);
  border-color: var(--border-default);
}

/* Profil-Card-Placeholder (Dashed, halb transparent) */
.profil-card--placeholder {
  border-style: dashed;
  opacity: 0.4;
}


/* ═══════════════════════════════════════════════════════════════════════════
   K.6.2 — JS-Inline-Style-Sweep: Utility-Klassen für JS-injizierte Markup
   ═══════════════════════════════════════════════════════════════════════════
   Diese Klassen ersetzen Inline-`style="..."`-Strings in JS-Templates
   (innerHTML/template-literals). CSP `style-src 'self'` (ab K.6.3) blockiert
   Inline-Styles regardless of source — also auch in JS-erzeugtem Markup.

   Verhaltens-/Design-Lock: Werte 1:1 aus Originalen übernommen.
   --------------------------------------------------------------------------- */

/* ─── Chart-Tooltips (mood/streak/xp/donut) ──────────────────────────────── */
.chart-tt-label  { color: #9898aa; font-size: 0.75rem; }
.chart-tt-value  { color: #f4f4f8; font-weight: 600; margin-top: 2px; }
.chart-tt-meta   { color: #f0ece4; margin-top: 2px; }
.chart-tt-meta-sm { color: #7a7a8a; font-size: 0.75rem; }
.chart-tt-emoji  { font-size: 1.1rem; margin-top: 2px; }
.chart-tt-mood   { color: #f4f4f8; font-size: 0.82rem; }
.chart-tt-date   { color: #7a7a8a; font-size: 0.75rem; }
.chart-tt-val-bold { color: #f0ece4; font-weight: 600; margin-top: 2px; }

/* ─── Chart-Empty-States ─────────────────────────────────────────────────── */
.chart-empty-msg     { font-size: 0.82rem; color: #5a5a6a; padding-top: 8px; }
.chart-empty-msg-md  { font-size: 0.85rem; color: #5e5e72; padding: 16px 0; }
.chart-empty-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
  color: #9898aa;
  text-align: center;
  gap: 8px;
}
.chart-empty-block__icon { font-size: 2rem; }
.chart-empty-block__text { font-size: 0.85rem; }

/* ─── Chart-Wrapper (Donut) ──────────────────────────────────────────────── */
.donut-wrapper {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
}
.donut-svg-wrap {
  position: relative;
  flex-shrink: 0;
  /* width + height kommen per JS via .style.width/.height (dynamisch, size-Param) */
}
.donut-legend {
  /* Legend-Container — dynamische Properties bei Bedarf via .style.X = */
}
.donut-legend-item {
  /* Einzelnes Legend-Item — Color-Dot + Label */
}

/* ─── Skeleton-Bars (Dashboard) ──────────────────────────────────────────── */
/* Ergänzung zu bestehenden data-skel-h: für statische heights direkt als
   Klasse, wenn die Höhe nicht vom Server kommt. */
.skel-bar-40 { height: 40%; }
.skel-bar-65 { height: 65%; }
.skel-bar-30 { height: 30%; }
.skel-bar-80 { height: 80%; }
.skel-bar-55 { height: 55%; }
.skel-bar-70 { height: 70%; }
.skel-bar-45 { height: 45%; }

/* Mood-Chart-Container Default-Height (Dashboard) */
.db-chart-mood-container { height: 160px; }

/* ─── FAB-Core-Helpers (Routine-Checklist im Bottom-Sheet) ───────────────── */
.fab-checklist-label--done {
  opacity: 0.45;
  text-decoration: line-through;
}
.fab-checklist-label--pending {
  opacity: 0.4;
}
.fab-xp-badge--done {
  color: var(--status-success);
}
.fab-xp-badge--pending {
  color: var(--text-secondary);
  border-color: var(--border-default);
}

/* ─── Reschedule-Dot in fab-punishments.js ───────────────────────────────── */
/* Color kommt dynamisch via .style.background = nach Insert (severity_color) */
.reschedule-dot {
  /* Visual-Anchor — Color via JS gesetzt, sonst keine Default-Styles */
}

/* ─── Punishments-Catalog Severity-Badge ─────────────────────────────────── */
/* Color + border-color dynamisch via .style.X = nach Insert */

/* ─── Tasks-Index Conditional-Border (newEntry) ──────────────────────────── */
/* Pattern: bestehende .cat-border + data-cat-color nutzen */
.tasks-newentry-default {
  /* fallback wenn kein data-cat-color: nutze --border-default */
}

/* ─── Mantras-Dom-View Punishment-Card-Border ────────────────────────────── */
/* Statisch violet — eigene Klasse statt Inline */
.mantras-pcard--violet {
  border-left: 3px solid var(--neon-violet);
}

/* ─── Routines-Index Archived-Actions (Always-visible) ───────────────────── */
.cat-actions--archived {
  opacity: 1;
  position: static;
}

/* ─── Mantras-Index Custom-Badge (violet-tint) ───────────────────────────── */
.mantra-badge--custom {
  background: rgba(168, 85, 247, 0.15);
  color: var(--neon-violet);
  border-color: rgba(168, 85, 247, 0.3);
}

/* ═══════════════════════════════════════════════════════════════════════════
   K.6.2 — Achievement / Level Toast-Cards (achievement.js, level.js)
   ═══════════════════════════════════════════════════════════════════════════
   Vorher: p.style.cssText = `...50 Zeilen Inline-CSS...` direkt in JS.
   Jetzt: Komponenten-Klassen, JS injiziert nur die Klasse.
   Verhaltens-/Design-Lock: 1:1 die Werte aus den ursprünglichen cssText-Strings. */

.toast-popup {
  position: fixed;
  top: 24px;
  right: 24px;
  background: linear-gradient(135deg, #2a1a3e 0%, #1c1424 100%);
  color: #f4f4f8;
  padding: 14px 18px;
  border-radius: 12px;
  border: 1px solid rgba(255, 215, 0, 0.4);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5), 0 0 20px rgba(255, 215, 0, 0.2);
  z-index: 99999;
  font-size: 0.92rem;
  font-weight: 500;
  max-width: 320px;
  animation: toastSlideIn 0.3s ease-out;
}
.toast-popup--level {
  /* Level-spezifische Variante (war p.style.cssText in level.js) — visuell
     identisch zur achievement-Variante; Container für künftige Differenzierung */
}
.toast-popup-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 6px;
  background: var(--gold);
}

@keyframes toastSlideIn {
  from { transform: translateX(120%); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}


/* ─── Donut-Legend Sub-Components (donut_chart.js) ───────────────────────── */
.donut-legend {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  min-width: 100px;
}
.donut-legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.8rem;
}
.donut-legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  display: inline-block;
  /* background kommt via data-bg-color (Bridge) */
}
.donut-legend-label {
  color: #d4d0c8;
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.donut-legend-pct {
  color: #7a7a8a;
  flex-shrink: 0;
}

/* ─── Donut Tooltip-Inhalt (3-zeilig: Label/Wert/Prozent) ───────────────── */
/* color des Labels kommt dynamisch via .style.color = nach Insert (d.data.color) */
.donut-tt-label  { font-weight: 600; }
.donut-tt-value  { color: #f0ece4; margin-top: 2px; }
.donut-tt-pct    { color: #7a7a8a; font-size: 0.75rem; }


/* ─── cat-border Default-Variante (tasks_index.js) ───────────────────────── */
/* Bestehende .cat-border nutzt var(--cat-color, var(--gold)) — diese Variante
   überschreibt --cat-color auf border-default, identisches Visual zu vorher
   `style="--cat-color: var(--border-default)"` Inline. */
.cat-border--default {
  --cat-color: var(--border-default);
}
