/* ═══════════════════════════════════════════════════════════
   BOTTOM SHEET — Premium spring physics
   ═══════════════════════════════════════════════════════════ */

.bs-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.65);
  z-index: 300;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--motion-normal, 0.26s) var(--ease, cubic-bezier(0.32, 0.72, 0, 1)), visibility var(--motion-normal, 0.26s);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.bs-overlay.visible {
  opacity: 1;
  visibility: visible;
}

[data-theme="light"] .bs-overlay {
  background: rgba(0, 0, 0, 0.3);
}

.bs-sheet {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  /* Open at a consistent "large detent" every time (iOS pattern). Previously
     the sheet sized to content, so the ticker view appeared halfway when a
     loading skeleton was briefly shown and the full way once data arrived;
     and the portfolio dropdown opened as a tiny 150px sliver at the bottom
     of the screen, easy to mistake for "blur only, no sheet." Fixing the
     height means translateY(100%) -> translateY(0) travels the same distance
     every time, and #bs-content scrolls inside when it overflows. */
  /* 100dvh is known to lie inside WKWebView when the software keyboard
     opens (see CLAUDE.md). `frontend/js/ui/bottom-sheet.js`'s
     _attachKeyboardHandler() overrides max-height and bottom via the
     visualViewport API whenever the sheet is open, so the stale dvh
     value is masked at runtime. These calc()s only define the resting
     size before a keyboard is involved — do not "fix" by switching to
     vh; the JS guard is what makes this correct. */
  height: calc(100dvh - var(--safe-top, 44px) - 8px);
  max-height: calc(100dvh - var(--safe-top, 44px) - 8px);
  background: var(--glass-bg);
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  border-top: 1px solid var(--glass-border);
  border-radius: 32px 32px 0 0;
  z-index: 301;
  box-shadow: 0 -10px 60px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255,255,255,0.15);
  transform: translateY(100%);
  transition: transform 0.42s var(--ease, cubic-bezier(0.32, 0.72, 0, 1)),
              max-height 0.38s var(--ease, cubic-bezier(0.32, 0.72, 0, 1)),
              border-radius 0.38s var(--ease, cubic-bezier(0.32, 0.72, 0, 1)),
              bottom 0.3s var(--ease, cubic-bezier(0.32, 0.72, 0, 1));
  overflow: hidden;
  display: flex;
  flex-direction: column;
  will-change: transform;
}

.bs-sheet.visible {
  transform: translateY(0);
}

.bs-sheet.bs-fullscreen {
  /* In fullscreen, extend to the very top but push interior content below
     the Dynamic Island via padding, not margin, so the glass backdrop
     still reaches the top edge. */
  max-height: 100dvh;
  border-radius: 0;
  padding-top: var(--safe-top, 44px);
}

.bs-handle-area {
  padding: 12px 0 8px;
  display: flex;
  justify-content: center;
  cursor: grab;
  flex-shrink: 0;
}

.bs-handle {
  width: 36px;
  height: 4px;
  border-radius: 2px;
  background: var(--text-tertiary);
  transition: width var(--motion-normal, 0.26s) var(--ease, cubic-bezier(0.32, 0.72, 0, 1)), background var(--motion-normal, 0.26s) var(--ease, cubic-bezier(0.32, 0.72, 0, 1));
}

.bs-handle-area:active .bs-handle {
  width: 44px;
  background: var(--text-secondary);
}

#bs-content {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 0 var(--page-px, 28px) 32px;
  scrollbar-width: none;
}

#bs-content::-webkit-scrollbar {
  display: none;
}

/* Bottom fade overlay to mask keyboard cutoff */
.bs-sheet::after {
  content: '';
  position: absolute;
  bottom: 0; left: 0; right: 0;
  height: 48px;
  background: linear-gradient(to top, var(--glass-bg, rgba(10,16,20,0.95)), transparent);
  pointer-events: none;
  z-index: 10;
  border-radius: 0 0 32px 32px;
}

/* ─ Content entrance animation when sheet opens ─ */
.bs-sheet.visible #bs-content > * {
  animation: sheetContentIn 0.34s var(--ease, cubic-bezier(0.32, 0.72, 0, 1)) both;
}
.bs-sheet.visible #bs-content > *:nth-child(1) { animation-delay: 0.04s; }
.bs-sheet.visible #bs-content > *:nth-child(2) { animation-delay: 0.07s; }
.bs-sheet.visible #bs-content > *:nth-child(3) { animation-delay: 0.10s; }
.bs-sheet.visible #bs-content > *:nth-child(4) { animation-delay: 0.13s; }
.bs-sheet.visible #bs-content > *:nth-child(5) { animation-delay: 0.16s; }

@keyframes sheetContentIn {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: translateY(0); }
}

@media (min-width: 768px) {
  .bs-sheet {
    max-width: 520px;
    left: 50%;
    transform: translateX(-50%) translateY(100%);
  }

  .bs-sheet.visible {
    transform: translateX(-50%) translateY(0);
  }
}

/* ── Light mode overrides ── */
[data-theme="light"] .bs-overlay {
  background: rgba(0, 0, 0, 0.3);
}

[data-theme="light"] .bs-sheet {
  background: var(--surface-elevated);
  border-top-color: var(--border);
  box-shadow: 0 -10px 50px rgba(0, 0, 0, 0.18), inset 0 1px 0 rgba(0, 0, 0, 0.04);
}

[data-theme="light"] .bs-handle {
  background: var(--text-tertiary);
}

[data-theme="light"] .bs-handle-area:active .bs-handle {
  background: var(--text-secondary);
}

[data-theme="light"] .bs-header {
  background: var(--surface-elevated);
  border-bottom-color: var(--border);
  color: var(--text);
}

[data-theme="light"] .bs-title {
  color: var(--text);
}

[data-theme="light"] .bs-subtitle {
  color: var(--text-secondary);
}

[data-theme="light"] .bs-sheet::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 48px;
  background: linear-gradient(to bottom, var(--surface-elevated), transparent);
  pointer-events: none;
  z-index: 10;
  border-radius: 32px 32px 0 0;
}

[data-theme="light"] .bs-sheet::after {
  background: linear-gradient(to top, var(--surface-elevated), transparent);
}
