/* ── Global: CSS reset, custom properties, typography, layout primitives ──
 * No class prefix — defines :root variables and base element styles
 */

*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  --color-bg: #080B14;
  --color-bg-2: #0D1117;
  --color-surface: rgba(255, 255, 255, 0.06);
  --color-border: rgba(255, 255, 255, 0.10);
  --color-border-bright: rgba(255, 255, 255, 0.20);
  --color-text-primary: #F8FAFC;
  /* Lifted from #94A3B8 (~4.8:1) to #A8B5C5 (~5.6:1) so secondary text
     keeps a comfortable margin above WCAG AA at 100% zoom and stays legible
     at 200% zoom. Used widely for labels, captions, section headers. */
  --color-text-secondary: #A8B5C5;
  /* Lifted from #8492A6 (~4.0:1, fails AA) to #98A4B6 (~4.8:1, passes AA). */
  --color-text-muted: #98A4B6;
  --color-accent: #6C3BEE;
  --color-success: #059669;
  --color-error: #EF4444;
  --color-warning: #F59E0B;
  --font-sans: 'Inter', system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', monospace;
  --radius-sm: 8px;
  --radius-md: 16px;
  --radius-lg: 24px;
  --radius-full: 9999px;
  --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.2);
  --shadow-md: 0 8px 32px rgba(0, 0, 0, 0.3);
  --shadow-lg: 0 16px 64px rgba(0, 0, 0, 0.4);
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --touch-min: 44px;
  --keyboard-offset: 0px;

  /* Spacing scale (4px base) */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;

  /* Type scale */
  --text-xs: 11px;
  --text-sm: 12px;
  --text-base: 14px;
  --text-md: 16px;
  --text-lg: 18px;
  --text-xl: 22px;
  --text-2xl: 28px;
  --text-3xl: 36px;

  /* Motion tokens — single source of truth so reduced-motion can disable globally */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast: 0.15s;
  --dur-base: 0.25s;
  --dur-slow: 0.4s;

  /* Z-index scale (kept low so prior fixed values still win where intended) */
  --z-drawer-backdrop: 55;
  --z-drawer: 60;
  --z-modal-backdrop: 90;
  --z-modal: 100;
  --z-toast: 200;

  /*
   * Canonical breakpoints (informational — CSS @media can't reference vars).
   * Always use these when adding new responsive rules:
   *   sm: max-width 600px   (phones)
   *   md: max-width 900px   (tablets / small laptops, where Avatar panel collapses)
   *   lg: min-width 1200px  (large desktop)
   */
}

html, body {
  height: 100%;
  background: var(--color-bg);
  color: var(--color-text-primary);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

#app {
  min-height: 100vh;
  min-height: 100dvh;
  position: relative;
  overflow-x: hidden;
}

button {
  cursor: pointer;
  border: none;
  background: none;
  font-family: inherit;
  font-size: inherit;
}

a { color: inherit; text-decoration: none; }

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

/* ── Mobile touch foundations ── */
/* iOS Safari zooms the viewport on focus when an input's font-size is below
   16px. Enforce 16px globally so no component can opt into the bug, even
   when a designer wants 14px text in a small form field. */
input, textarea, select {
  font-size: max(16px, 1em);
  -webkit-appearance: none;
  appearance: none;
}

input[type="checkbox"], input[type="radio"] {
  -webkit-appearance: auto;
  appearance: auto;
}

@media (hover: none) and (pointer: coarse) {
  * { -webkit-tap-highlight-color: transparent; }
  body { overscroll-behavior-y: none; }
  button:active, [role="button"]:active, a:active {
    transform: scale(0.97);
  }

  /* Global touch-target floor: any interactive element should be tappable.
     Components opt out via .no-touch-min if they intentionally want smaller. */
  button:not(.no-touch-min):not([class*="-icon"]):not([class*="rename"]),
  [role="button"]:not(.no-touch-min),
  a.btn, a.button, a[class*="-btn"] {
    min-height: var(--touch-min);
  }
}

/* ── Dynamic viewport height custom property ── */
@supports (height: 100dvh) {
  :root { --dvh: 1dvh; }
}

/* ── Touch momentum scrolling for scroll containers ── */
@media (hover: none) and (pointer: coarse) {
  .sv-messages, .thread-body, .launch-modal-body, .review-modal-body,
  .tools-modal-body, .trading-modal-body, .stg-main,
  .sched-panel-list, .rpt-body, .contacts-body, .gal-body,
  .wfp-flow-viz, .ta-panel-scroll, .ta-picker-scroll {
    -webkit-overflow-scrolling: touch;
  }
}

/* ── Accessible focus ring for keyboard navigation ──
 * The base :focus-visible covers text links and most elements, but several
 * components define their own outline:none or set background changes that
 * defeat the ring. Force a visible ring on all interactive elements when
 * navigating by keyboard so workspace buttons (hamburger items, action
 * buttons) are reachable. */
:focus-visible {
  outline: 2px solid #a78bfa;
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
button:focus-visible,
a:focus-visible,
[role="button"]:focus-visible,
[tabindex]:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: 2px solid #a78bfa;
  outline-offset: 2px;
}

/* ── Safe-area helpers for fixed elements (toasts, FABs, sheets) ── */
.safe-bottom { padding-bottom: var(--safe-bottom, 0px); }
.safe-top { padding-top: var(--safe-top, 0px); }
/* Toast / floating elements that anchor to the viewport bottom must clear
   the iPhone home indicator. Use this instead of a hard-coded bottom value. */
.toast-anchor {
  bottom: calc(16px + var(--safe-bottom, 0px)) !important;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ── Sheet primitive ──
 * Shared base for any bottom-sheet-style modal. Components opt in by
 * adding `.sheet` to the dialog element, plus `.sheet-backdrop` to the
 * overlay. Centers as a card on desktop, slides up from the bottom on
 * mobile. Existing modals continue to work; this is for new components.
 */
.sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: var(--z-modal-backdrop);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}
.sheet-backdrop.is-open { opacity: 1; }

.sheet {
  position: fixed;
  z-index: var(--z-modal);
  background: rgba(15, 15, 25, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.08);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  box-shadow: 0 -8px 40px rgba(0, 0, 0, 0.4);
  display: flex;
  flex-direction: column;
  /* Desktop: centered card */
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.96);
  width: min(640px, calc(100% - 32px));
  max-height: min(720px, calc(100dvh - 64px));
  border-radius: var(--radius-lg);
  opacity: 0;
  transition: transform var(--dur-base) var(--ease-out),
              opacity var(--dur-base) var(--ease-out);
}
.sheet.is-open {
  transform: translate(-50%, -50%) scale(1);
  opacity: 1;
}

.sheet-handle { display: none; }
.sheet-body { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 24px; }
.sheet-header { padding: 20px 24px; border-bottom: 1px solid rgba(255, 255, 255, 0.06); }
.sheet-footer { padding: 16px 24px; border-top: 1px solid rgba(255, 255, 255, 0.06); display: flex; gap: 12px; justify-content: flex-end; }

@media (max-width: 600px) {
  .sheet {
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    transform: translateY(100%);
    width: 100%;
    max-height: 92dvh;
    border-radius: 20px 20px 0 0;
    padding-bottom: var(--safe-bottom, 0px);
  }
  .sheet.is-open {
    transform: translateY(0);
  }
  .sheet-handle {
    display: block;
    width: 40px;
    height: 4px;
    border-radius: 2px;
    background: rgba(255, 255, 255, 0.25);
    margin: 8px auto 0;
    flex-shrink: 0;
  }
  .sheet-body { padding: 16px; }
  .sheet-header { padding: 12px 16px; }
  .sheet-footer { padding: 12px 16px calc(12px + var(--safe-bottom, 0px)); }
}

/* Lock body scroll when any sheet/drawer is open. Components add this
   class on body when opening, remove on close. */
body.is-modal-open {
  overflow: hidden;
  touch-action: none;
}

/* ── Loading spinner primitive ──
 * Drop-in inline spinner: <span class="spinner"></span> Loading…
 * Sized via font-size or inline width/height. Color via currentColor. */
.spinner {
  display: inline-block;
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  vertical-align: -0.18em;
  animation: spinner-rot 0.7s linear infinite;
}
.spinner--lg { width: 24px; height: 24px; border-width: 3px; }
@keyframes spinner-rot { to { transform: rotate(360deg); } }

/* Animated dots: "Loading<span class="loading-dots"></span>" */
.loading-dots::after {
  content: '';
  display: inline-block;
  width: 1ch;
  text-align: left;
  animation: loading-dots-anim 1.4s steps(4, end) infinite;
}
@keyframes loading-dots-anim {
  0%   { content: ''; }
  25%  { content: '.'; }
  50%  { content: '..'; }
  75%  { content: '...'; }
  100% { content: ''; }
}
