/* ==========================================================================
   Dimau UI - shared design tokens and primitives
   One file, loaded by every Dimau app. Change a value here and every app
   moves together. No framework, no build step, no font downloads.

   Fonts: set --dui-font-display and --dui-font-body per app.
   Theme: automatic from the OS. Force with <html data-theme="dark"> or "light".
   ========================================================================== */

:root {
  --dui-font-display: var(--dui-font-body);
  --dui-font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, sans-serif;
  --dui-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --dui-text-xs: 0.75rem;
  --dui-text-sm: 0.875rem;
  --dui-text-md: 1rem;
  --dui-text-lg: 1.125rem;
  --dui-text-xl: 1.375rem;
  --dui-text-2xl: 1.75rem;
  --dui-text-3xl: 2.125rem;
  --dui-text-4xl: 2.75rem;

  --dui-leading-tight: 1.15;
  --dui-leading-snug: 1.35;
  --dui-leading-normal: 1.6;

  --dui-track-tight: -0.02em;
  --dui-track-snug: -0.01em;
  --dui-track-normal: 0;
  --dui-track-wide: 0.02em;

  --dui-weight-normal: 400;
  --dui-weight-medium: 500;
  --dui-weight-semibold: 600;

  /* Space - everything sits on a 4px grid, with no exceptions */
  --dui-s1: 4px;  --dui-s2: 8px;  --dui-s3: 12px; --dui-s4: 16px;
  --dui-s5: 24px; --dui-s6: 32px; --dui-s7: 48px; --dui-s8: 64px;

  --dui-r-sm: 8px; --dui-r-md: 12px; --dui-r-lg: 16px;
  --dui-r-xl: 24px; --dui-r-full: 999px;

  /* Motion - ONE curve and three durations for the whole portfolio.
     Consistency here is what reads as expensive. Do not add new curves. */
  --dui-ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --dui-ease-in: cubic-bezier(0.4, 0, 1, 1);
  --dui-t-fast: 140ms; --dui-t-base: 240ms; --dui-t-slow: 400ms;

  --dui-lift: -4px;
  --dui-hover-scale: 1.015;
  --dui-press-scale: 0.985;

  /* Light theme (the default) */
  --dui-bg: #f6f7f9;
  --dui-surface: #ffffff;
  --dui-surface-2: #f1f3f6;
  --dui-surface-hover: #ffffff;
  --dui-border: rgba(16, 24, 40, 0.09);
  --dui-border-strong: rgba(16, 24, 40, 0.16);

  --dui-text: #101828;
  --dui-text-2: #51607a;
  --dui-text-3: #8a95a8;

  --dui-accent: #5b46d6;
  --dui-accent-hover: #4a37bd;
  --dui-accent-on: #ffffff;
  --dui-accent-soft: rgba(91, 70, 214, 0.08);

  --dui-danger: #b42318;
  --dui-success: #067647;

  --dui-ring: rgba(91, 70, 214, 0.45);
  --dui-glow: radial-gradient(120% 120% at 80% 0%, rgba(91,70,214,0.10) 0%, rgba(91,70,214,0) 60%);

  --dui-e1: 0 1px 2px rgba(16,24,40,0.05), 0 1px 3px rgba(16,24,40,0.06);
  --dui-e2: 0 4px 8px -2px rgba(16,24,40,0.07), 0 12px 24px -6px rgba(16,24,40,0.08);
  --dui-e3: 0 12px 20px -6px rgba(16,24,40,0.09), 0 28px 48px -12px rgba(16,24,40,0.14);

  /* Light cards are solid. Glass over a light page looks washed out, not
     premium, so the frosted treatment is reserved for the dark theme. */
  --dui-card-bg: var(--dui-surface);
  --dui-card-blur: none;

  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --dui-bg: #0a0b0f;
    --dui-surface: rgba(255,255,255,0.045);
    --dui-surface-2: rgba(255,255,255,0.025);
    --dui-surface-hover: rgba(255,255,255,0.07);
    --dui-border: rgba(255,255,255,0.09);
    --dui-border-strong: rgba(255,255,255,0.16);
    --dui-text: rgba(255,255,255,0.92);
    --dui-text-2: rgba(255,255,255,0.58);
    --dui-text-3: rgba(255,255,255,0.40);
    --dui-accent: #9b8cff;
    --dui-accent-hover: #aea2ff;
    --dui-accent-on: #14102b;
    --dui-accent-soft: rgba(155,140,255,0.14);
    --dui-danger: #ff9b92;
    --dui-success: #6fd6a3;
    --dui-ring: rgba(155,140,255,0.55);
    --dui-glow: radial-gradient(120% 120% at 80% 0%, rgba(155,140,255,0.16) 0%, rgba(155,140,255,0) 60%);
    --dui-e1: 0 1px 2px rgba(0,0,0,0.4);
    --dui-e2: 0 12px 28px -10px rgba(0,0,0,0.55);
    --dui-e3: 0 24px 50px -12px rgba(0,0,0,0.65);
    --dui-card-bg: linear-gradient(to bottom, rgba(255,255,255,0.07), rgba(255,255,255,0.02));
    --dui-card-blur: blur(24px);
  }
}

:root[data-theme="dark"] {
  --dui-bg: #0a0b0f;
  --dui-surface: rgba(255,255,255,0.045);
  --dui-surface-2: rgba(255,255,255,0.025);
  --dui-surface-hover: rgba(255,255,255,0.07);
  --dui-border: rgba(255,255,255,0.09);
  --dui-border-strong: rgba(255,255,255,0.16);
  --dui-text: rgba(255,255,255,0.92);
  --dui-text-2: rgba(255,255,255,0.58);
  --dui-text-3: rgba(255,255,255,0.40);
  --dui-accent: #9b8cff;
  --dui-accent-hover: #aea2ff;
  --dui-accent-on: #14102b;
  --dui-accent-soft: rgba(155,140,255,0.14);
  --dui-danger: #ff9b92;
  --dui-success: #6fd6a3;
  --dui-ring: rgba(155,140,255,0.55);
  --dui-glow: radial-gradient(120% 120% at 80% 0%, rgba(155,140,255,0.16) 0%, rgba(155,140,255,0) 60%);
  --dui-e1: 0 1px 2px rgba(0,0,0,0.4);
  --dui-e2: 0 12px 28px -10px rgba(0,0,0,0.55);
  --dui-e3: 0 24px 50px -12px rgba(0,0,0,0.65);
  --dui-card-bg: linear-gradient(to bottom, rgba(255,255,255,0.07), rgba(255,255,255,0.02));
  --dui-card-blur: blur(24px);
}

/* Border-box on these components only, never a global reset. Dropping this
   file into an app that already has its own layout must not move anything
   it did not create. Without this, padding is ADDED to width:100% and every
   card overflows a phone screen by the width of its padding. */
.dui-grid, .dui-stack, .dui-row, .dui-card, .dui-card *,
.dui-btn, .dui-stat, .dui-skeleton, .dui-empty, .dui-empty * {
  box-sizing: border-box;
}

.dui {
  margin: 0;
  background: var(--dui-bg);
  color: var(--dui-text);
  font-family: var(--dui-font-body);
  font-size: var(--dui-text-md);
  line-height: var(--dui-leading-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

.dui h1, .dui h2, .dui h3, .dui h4 {
  font-family: var(--dui-font-display);
  font-weight: var(--dui-weight-semibold);
  letter-spacing: var(--dui-track-tight);
  line-height: var(--dui-leading-tight);
  margin: 0;
  text-wrap: balance;
}
.dui h1 { font-size: var(--dui-text-4xl); }
.dui h2 { font-size: var(--dui-text-3xl); }
.dui h3 { font-size: var(--dui-text-2xl); }
.dui h4 { font-size: var(--dui-text-xl); }
.dui p { margin: 0; max-width: 68ch; }

/* Tabular figures everywhere a number can change. Digits that shift width
   make a live figure jitter, which instantly reads as unfinished. */
.dui-num, .dui-stat__value {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.dui-grid {
  display: grid;
  gap: var(--dui-s4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 264px), 1fr));
}
@media (min-width: 720px) {
  .dui-grid > .dui-span-2 { grid-column: span 2; }
  .dui-grid > .dui-span-3 { grid-column: span 3; }
  .dui-grid > .dui-tall   { grid-row: span 2; }
}
.dui-stack { display: flex; flex-direction: column; gap: var(--dui-s3); }
.dui-row { display: flex; align-items: center; gap: var(--dui-s3); flex-wrap: wrap; }

.dui-card {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: var(--dui-s5);
  border-radius: var(--dui-r-xl);
  border: 1px solid var(--dui-border);
  background: var(--dui-card-bg);
  -webkit-backdrop-filter: var(--dui-card-blur);
  backdrop-filter: var(--dui-card-blur);
  box-shadow: var(--dui-e2);
  color: var(--dui-text-2);
  transition: box-shadow var(--dui-t-base) var(--dui-ease),
              border-color var(--dui-t-base) var(--dui-ease),
              transform var(--dui-t-base) var(--dui-ease);
}

/* The ambient glow sits at z-index 0 - ABOVE the card background and BELOW
   the content at z-index 1. A negative z-index here would paint it behind
   the card background and it would never be visible at all. */
.dui-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: var(--dui-glow);
  opacity: 0;
  transition: opacity var(--dui-t-slow) var(--dui-ease);
}
.dui-card > * { position: relative; z-index: 1; }

.dui-card__head { display: flex; flex-direction: column; gap: var(--dui-s1); margin-bottom: var(--dui-s4); }
.dui-card__title {
  font-family: var(--dui-font-display);
  font-size: var(--dui-text-lg);
  font-weight: var(--dui-weight-medium);
  letter-spacing: var(--dui-track-tight);
  line-height: var(--dui-leading-snug);
  color: var(--dui-text);
  margin: 0;
}
.dui-card__subtitle {
  font-size: var(--dui-text-sm);
  letter-spacing: var(--dui-track-wide);
  color: var(--dui-text-3);
  margin: 0;
}
.dui-card__body { flex: 1 1 auto; min-width: 0; }
.dui-card__foot {
  margin-top: var(--dui-s4);
  padding-top: var(--dui-s3);
  border-top: 1px solid var(--dui-border);
  font-size: var(--dui-text-sm);
  color: var(--dui-text-3);
}

.dui-card.is-interactive {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  text-align: left;
  text-decoration: none;
  width: 100%;
  font: inherit;
  color: var(--dui-text-2);
}
@media (hover: hover) {
  .dui-card.is-interactive:hover {
    transform: translateY(var(--dui-lift)) scale(var(--dui-hover-scale));
    box-shadow: var(--dui-e3);
    border-color: var(--dui-border-strong);
  }
  .dui-card.is-interactive:hover::before { opacity: 1; }
}
.dui-card.is-interactive:active {
  transform: scale(var(--dui-press-scale));
  transition-duration: var(--dui-t-fast);
}
.dui-card.is-interactive:focus-visible {
  outline: none;
  box-shadow: var(--dui-e3), 0 0 0 2px var(--dui-bg), 0 0 0 4px var(--dui-ring);
}
.dui-card.is-interactive:focus-visible::before { opacity: 1; }
.dui-card.is-pressed { transform: scale(var(--dui-press-scale)); }

.dui-stat { display: flex; flex-direction: column; gap: var(--dui-s1); }
.dui-stat__label {
  font-size: var(--dui-text-xs);
  letter-spacing: var(--dui-track-wide);
  text-transform: uppercase;
  color: var(--dui-text-3);
}
.dui-stat__value {
  font-family: var(--dui-font-display);
  font-size: var(--dui-text-3xl);
  font-weight: var(--dui-weight-semibold);
  letter-spacing: var(--dui-track-tight);
  line-height: var(--dui-leading-tight);
  color: var(--dui-text);
}
.dui-stat__delta { font-size: var(--dui-text-sm); color: var(--dui-text-2); }
.dui-stat__delta[data-dir="up"] { color: var(--dui-success); }
.dui-stat__delta[data-dir="down"] { color: var(--dui-danger); }

.dui-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--dui-s2);
  min-height: 44px;
  padding: 0 var(--dui-s4);
  border: 1px solid transparent;
  border-radius: var(--dui-r-md);
  background: var(--dui-accent);
  color: var(--dui-accent-on);
  font-family: var(--dui-font-body);
  font-size: var(--dui-text-sm);
  font-weight: var(--dui-weight-medium);
  letter-spacing: var(--dui-track-snug);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--dui-t-fast) var(--dui-ease),
              transform var(--dui-t-fast) var(--dui-ease),
              box-shadow var(--dui-t-fast) var(--dui-ease);
}
.dui-btn:hover { background: var(--dui-accent-hover); }
.dui-btn:active { transform: scale(var(--dui-press-scale)); }
.dui-btn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--dui-bg), 0 0 0 4px var(--dui-ring); }
.dui-btn[disabled], .dui-btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; transform: none; }
.dui-btn--quiet { background: transparent; border-color: var(--dui-border); color: var(--dui-text); }
.dui-btn--quiet:hover { background: var(--dui-accent-soft); border-color: var(--dui-border-strong); }

/* Loading, empty and error are where an app stops feeling finished.
   Every app gets the same three, so none can ship a blank screen. */
.dui-skeleton {
  position: relative;
  overflow: hidden;
  border-radius: var(--dui-r-sm);
  background: var(--dui-surface-2);
  min-height: 1em;
}
.dui-skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--dui-surface-hover), transparent);
  animation: dui-shimmer 1.4s var(--dui-ease) infinite;
}
.dui-skeleton--text { height: .8em; margin: .2em 0; }
.dui-skeleton--title { height: 1.4em; width: 55%; }
.dui-skeleton--line { height: .8em; width: 100%; }
.dui-skeleton--line-short { height: .8em; width: 70%; }
.dui-skeleton--block { height: 96px; border-radius: var(--dui-r-md); }
@keyframes dui-shimmer { to { transform: translateX(100%); } }

.dui-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--dui-s2);
  padding: var(--dui-s6) var(--dui-s4);
  text-align: center;
}
.dui-empty__icon { width: 40px; height: 40px; margin-bottom: var(--dui-s1); color: var(--dui-text-3); }
.dui-empty__title {
  font-family: var(--dui-font-display);
  font-size: var(--dui-text-md);
  font-weight: var(--dui-weight-medium);
  letter-spacing: var(--dui-track-snug);
  color: var(--dui-text);
}
.dui-empty__hint { font-size: var(--dui-text-sm); color: var(--dui-text-3); max-width: 42ch; }
.dui-empty__action { margin-top: var(--dui-s3); }
.dui-error { color: var(--dui-danger); }

.dui-spinner {
  width: 1em; height: 1em; flex: none;
  border-radius: var(--dui-r-full);
  border: 2px solid currentColor;
  border-top-color: transparent;
  animation: dui-spin 600ms linear infinite;
}
@keyframes dui-spin { to { transform: rotate(360deg); } }

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

@media (prefers-reduced-motion: reduce) {
  .dui-card, .dui-card.is-interactive:hover, .dui-card.is-interactive:active,
  .dui-card.is-pressed, .dui-btn, .dui-btn:active { transform: none !important; }
  .dui-skeleton::after, .dui-spinner { animation: none; }
  .dui-skeleton::after { transform: none; opacity: .6; background: var(--dui-surface-hover); }
  .dui * { transition-duration: 1ms !important; }
}

@media print {
  .dui { background: #fff; color: #000; }
  .dui-card {
    box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none;
    background: #fff; border: 1px solid #ccc; break-inside: avoid;
  }
  .dui-card::before { display: none; }
}
