/* ============================================================
   moodlog Design System, tokens + base + brand primitives
   Single stylesheet consumed by the Django templates. Font
   @font-face lives inline in base.djhtml (needs {% static %}).
   Governance: emotion hues come ONLY from the 8-color palette;
   ink for emotion text/links, raw fill for fills/marks; slate
   is the one neutral. Color is the content, the UI stays
   slate-neutral so feeling is the only vivid thing.
   ============================================================ */

:root {
  /* ---- Plutchik emotion fills (identity colors) ---- */
  --emo-joy: #F7E761;
  --emo-trust: #A4E57E;
  --emo-fear: #4DA35A;
  --emo-surprise: #7FC8F5;
  --emo-sadness: #4F75D2;
  --emo-disgust: #D66BF2;
  --emo-anger: #E04242;
  --emo-anticipation: #F9A84D;
  --emo-default: #E2E8F0;

  /* ---- Emotion ink (text-safe, darkened, hue-matched) ---- */
  --ink-joy: #9A7B00;
  --ink-trust: #3F8B2E;
  --ink-fear: #2E6E3B;
  --ink-surprise: #1E7FC4;
  --ink-sadness: #3A57A8;
  --ink-disgust: #A03FC0;
  --ink-anger: #C12B2B;
  --ink-anticipation: #C77A1E;

  /* ---- Slate (the one neutral UI ramp) ---- */
  --slate-50: #F8FAFC;
  --slate-100: #F1F5F9;
  --slate-200: #E2E8F0;
  --slate-300: #CBD5E1;
  --slate-400: #94A3B8;
  --slate-500: #64748B;
  --slate-600: #475569;
  --slate-700: #334155;
  --slate-800: #1E293B;
  --slate-900: #0F172A;
  --white: #FFFFFF;

  /* ---- Semantic neutral aliases ---- */
  --bg-page: var(--slate-50);
  --surface-card: var(--white);
  --border-default: var(--slate-200);
  --border-strong: var(--slate-300);
  --text-body: var(--slate-900);
  --text-secondary: var(--slate-600);
  --text-muted: var(--slate-500);
  --text-placeholder: var(--slate-400);

  /* ---- Action (the only "loud" non-emotion color) ---- */
  --action-bg: var(--slate-900);
  --action-bg-hover: var(--slate-800);
  --action-fg: var(--white);

  /* ---- Semantic accents (banners / status) ---- */
  --success-bg: #ECFDF5;
  --success-fg: #064E3B;
  --success-border: #A7F3D0;
  --error-bg: #FFF1F2;
  --error-fg: #881337;
  --error-border: #FECDD3;
  --info-bg: #EFF6FF;
  --info-fg: #3B82F6;
  --feature-bg: #FAF5FF;
  --feature-fg: #A855F7;
  --warning-bg: #FEF3C7;
  --warning-fg: #D97706;

  /* ---- Opacity scale for emotion-tinted surfaces ---- */
  --opacity-chip-bg: 0.15;
  --opacity-dyad-bg: 0.13;
  --opacity-dyad-border: 0.30;
  --opacity-chart-bar: 0.50;
  --opacity-overlay: 0.30;
  --opacity-disabled: 0.50;

  /* ---- Families ---- */
  --font-ui: "DM Sans", ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-display: var(--font-ui);
  --font-mono: "DM Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* ---- Type scale (xs is the floor, never smaller) ---- */
  --text-3xl: 1.875rem;
  --text-2xl: 1.5rem;
  --text-xl: 1.25rem;
  --text-lg: 1.125rem;
  --text-base: 1rem;
  --text-sm: 0.875rem;
  --text-xs: 0.75rem;
  --text-chip: 0.6875rem;
  --text-dyad: 0.625rem;

  /* ---- Weights ---- */
  --weight-normal: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  /* ---- Line heights ---- */
  --leading-tight: 1.2;
  --leading-normal: 1.5;
  --leading-relaxed: 1.625;

  /* ---- Wordmark ---- */
  --wordmark-weight: 700;
  --wordmark-tracking: -0.03em;

  /* ---- Spacing (4px grid) ---- */
  --s1: 0.25rem;
  --s2: 0.5rem;
  --s3: 0.75rem;
  --s4: 1rem;
  --s5: 1.25rem;
  --s6: 1.5rem;
  --s8: 2rem;

  /* ---- Radius ---- */
  --r-md: 0.375rem;
  --r-lg: 0.5rem;
  --r-xl: 0.75rem;
  --r-full: 9999px;

  /* ---- Elevation (soft, low shadows only) ---- */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.10);
  --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.15);
}

/* ============================================================
   Base, DM Sans is the product face; mono is the lab signal.
   Root is nudged to 17px so the whole rem-based UI (Tailwind
   type + spacing) reads a touch larger and calmer by default.
   ============================================================ */
html {
  font-size: 17px;
}
body {
  font-family: var(--font-ui);
  color: var(--text-body);
  background-color: var(--bg-page);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Mono is opt-in: timestamps, counts, tokens, metadata. Tabular figures
   keep data honest. Apply via .font-mono / [data-mono] or the elements below. */
.font-mono,
code,
kbd,
samp,
time,
[data-mono] {
  font-family: var(--font-mono);
  font-feature-settings: "tnum" 1;
}

::selection {
  background-color: var(--emo-surprise);
  color: var(--slate-900);
}

/* ============================================================
   Wordmark, lowercase `moodlog` (no trailing period).
   ============================================================ */
.wordmark {
  font-family: var(--font-ui);
  font-weight: var(--wordmark-weight);
  letter-spacing: var(--wordmark-tracking);
  color: var(--text-body);
  line-height: 1;
}

/* ============================================================
   Nav pill, header navigation (migrated from base.djhtml).
   ============================================================ */
.nav-pill {
  display: inline-flex;
  align-items: center;
  border-radius: var(--r-full);
  padding: 0.35rem 1rem;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  border: 1px solid transparent;
  color: var(--text-secondary);
  transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease;
}
.nav-pill.is-active {
  background-color: var(--action-bg);
  border-color: var(--action-bg);
  color: var(--action-fg);
}
.nav-pill:not(.is-active):hover {
  background-color: var(--slate-50);
  border-color: var(--border-default);
  color: var(--slate-900);
}

/* ============================================================
   Emotion chip, the signature primitive. fill @15% background,
   fill border, slate-900 text. Untagged is dashed slate, not an
   emotion. Per-emotion fill/ink set inline (server computes it).
   The × correction affordance is always one click away.
   ============================================================ */
.ml-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  padding: 2px 8px;
  border-radius: var(--r-full);
  font-family: var(--font-ui);
  font-size: var(--text-chip);
  font-weight: var(--weight-medium);
  line-height: 1.4;
  white-space: nowrap;
  color: var(--slate-900);
  border: 1px solid var(--emo-default);
}
.ml-chip--untagged {
  background: var(--slate-50);
  color: var(--text-muted);
  border: 1px dashed var(--border-default);
}
.ml-chip__remove {
  border: none;
  background: transparent;
  cursor: pointer;
  padding: 0;
  margin-left: 2px;
  font-size: var(--text-xs);
  line-height: 1;
  color: var(--slate-400);
  transition: color 120ms ease;
}
.ml-chip__remove:hover {
  color: var(--ink-anger);
}

/* ============================================================
   Dyad pill, Plutchik primary dyad. color = a.ink,
   bg = a.fill @13%, border = a.fill @30% (set inline).
   ============================================================ */
.ml-dyad {
  display: inline-flex;
  align-items: center;
  padding: 4px 8px;
  border-radius: var(--r-full);
  font-family: var(--font-ui);
  font-size: var(--text-dyad);
  font-weight: var(--weight-medium);
  line-height: 1.3;
  white-space: nowrap;
}

/* ============================================================
   Ring save dial (the iOS RingCTADial on the web): Plutchik ring
   around an ink hub; the ring spins while saving.
   ============================================================ */
.ring-save-dial .ring-save-ring {
  transform-origin: 50% 50%;
  transform-box: view-box;
}
.ring-save-dial.is-saving .ring-save-ring {
  animation: ml-ring-spin 0.9s linear infinite;
}
.ring-save-dial.is-saving .ring-save-arrow { opacity: 0.3; }
@keyframes ml-ring-spin {
  to { transform: rotate(360deg); }
}

/* Spotify-style pop for identity marks: grow on hover, snap back while
   pressed. Timing lifted from Spotify's Encore system (150ms, productive
   ease). .ml-pop scales the element itself; .ml-pop-within scales only the
   .ml-pop-target descendant so text beside an icon stays still. */
.ml-pop,
.ml-pop-within .ml-pop-target {
    transition: transform .15s cubic-bezier(.3, 0, 0, 1);
    will-change: transform;
}
.ml-pop:hover,
.ml-pop-within:hover .ml-pop-target {
    transform: scale(1.1);
}
.ml-pop:active,
.ml-pop-within:active .ml-pop-target {
    transform: scale(1);
}

/* Click the mark and it turns once, the same toy as the iOS login wheel
   (AnimatedEmotionWheel). The rotation sits on the inner svg rather than the
   link, because .ml-pop already animates the link's transform and the two
   would overwrite each other. The curve overshoots slightly and settles,
   standing in for SwiftUI's spring(response: 0.9, dampingFraction: 0.65). */
.dial-spin svg,
.dial-spin img {
    /* An explicit start value: transitioning out of `transform: none` is not
       reliably interpolated, and the first click is the one that matters. */
    transform: rotate(0deg);
    transition: transform .9s cubic-bezier(.34, 1.28, .5, 1);
    will-change: transform;
}
/* A bare mark (no link around it) is a toy, so say so on hover. */
.dial-spin:not(a) {
    cursor: pointer;
}
@media (prefers-reduced-motion: reduce) {
    .dial-spin svg,
    .dial-spin img {
        transition: none;
    }
}
