/* ==========================================================================
   responsive.css — iPad / iPhone / touch-device adjustments.

   Loaded LAST so it overrides earlier shells (sidebar.css, chat.css, etc.).
   Breakpoints:
     <=1180px   tablet-landscape (iPad Pro 11" landscape; iPad Air 10.9"; etc.)
     <=1024px   tablet-portrait + small laptop (iPad Pro portrait, iPad 9.7")
     <=820px    iPad mini portrait, large phones landscape
     <=480px    phones portrait
   ========================================================================== */

/* ---------- iOS Safari 100vh fix + safe areas + smooth scroll ---------- */
:root {
  --vh: 1vh;
}
@supports (height: 100dvh) {
  /* Only the outermost shells get a min-height floor. .main-content and
     .content-wrapper deliberately use the topbar-aware height calc from
     sidebar.css; giving them min-height: 100dvh forced content-wrapper
     past the viewport (because its parent already has the 56px topbar
     above), which caused the body to scroll and dragged the docked chat
     panel header off-screen. */
  .app-layout,
  .sidebar { min-height: 100dvh; }
}

html, body {
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}

/* Desktop / tablet-landscape: pin the chrome to the viewport.
   The page itself never scrolls — only internal regions
   (.content-left, .chat-log, .sidebar-nav) do. This guarantees the
   chat-drawer header (top) and input row (bottom) stay docked to the
   browser window edges no matter how long the left-pane content is.
   Below 820px the layout collapses to a single column and page-scroll
   is expected again, so this guard only applies on wider viewports. */
@media (min-width: 821px) {
  html, body {
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
  }
}

.content-left,
.sidebar-nav,
.chat-log {
  -webkit-overflow-scrolling: touch;
}

/* Hamburger button — visible only on small screens (CSS-only toggle).
   The button itself lives in base.html. */
.sidebar-mobile-trigger {
  display: none;
  background: transparent;
  border: 1px solid var(--border-default, #30363d);
  color: var(--text-primary, #e6edf3);
  width: 36px;
  height: 36px;
  border-radius: var(--r-sm, 6px);
  font-size: 18px;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}
.sidebar-mobile-trigger:active { background: var(--bg-elevated-2, #21262d); }

/* Backdrop that appears behind the off-canvas sidebar on small screens. */
.sidebar-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  z-index: 998;
  opacity: 0;
  transition: opacity 180ms ease-out;
}
.sidebar-backdrop.visible {
  display: block;
  opacity: 1;
}

/* ============================================================
   Universal viewport-bounding for the chat panel.
   Applies at every breakpoint above the bottom-sheet handover (>820px).
   Solves the "panel extends beyond screen and gets cut off" bug when:
     - the user resized the panel wide on a big monitor, then narrowed
       the browser window (--chat-width-user > viewport),
     - mode-mini's hardcoded 380×480 is wider than a narrow laptop split,
     - a saved --chat-fx/--chat-fy positions the float off-screen.
   We never let the panel exceed viewport - 32px and we clamp its
   right/left offsets so it stays fully on-screen.
   ============================================================ */
.content-right.mode-dock {
  /* In-flow dock: cap width by viewport so it never overflows the
     flex row even if --chat-width-user is bigger than the screen. */
  max-width: calc(100vw - 64px);
}
.content-right.mode-float {
  /* Detached overlay: cap width AND height, and clamp the right + top
     offsets with BOTH a lower and an upper bound so the panel can never
     slide off any edge — even if a saved --chat-fx/--chat-fy came from a
     larger window. The upper bounds keep at least ~64px reachable from
     each edge; JS (clampFloatPosition) then refines to fully on-screen. */
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 48px);
  right: clamp(8px, var(--chat-fx, 24px), calc(100vw - 64px));
  top:   clamp(8px, var(--chat-fy, 80px), calc(100vh - 64px));
  bottom: 16px;
}
.content-right.mode-mini {
  /* Compact picture-in-picture: shrink to viewport on narrow screens. */
  width: min(380px, calc(100vw - 24px));
  height: min(480px, calc(100vh - 80px));
  right:  clamp(8px, var(--chat-fx, 16px), calc(100vw - 64px));
  bottom: clamp(8px, var(--chat-fy-bottom, 16px), calc(100vh - 64px));
}
/* Constrain the resizer grip so it can't pull the panel wider than vw. */
.chat-resizer { max-width: 100vw; }

/* ============================================================
   Tablet landscape (iPad Pro 11" landscape ~1180px)
   Auto-collapse sidebar to icon rail; keep chat dock visible but
   slightly narrower. Touch-friendly tap targets.
   ============================================================ */
@media (max-width: 1180px) and (min-width: 821px) {
  .nav-item,
  .user-menu-item {
    min-height: 44px;       /* iOS HIG minimum */
  }
  .top-bar-actions { gap: var(--sp-2, 8px); }
  .content-right { width: clamp(320px, 32vw, 480px); }
}

/* ============================================================
   Tablet portrait + iPad mini (<=1024px down to 821px)
   Off-canvas sidebar; chat-drawer overlays content; topbar gets hamburger.
   ============================================================ */
@media (max-width: 1024px) {
  /* Sidebar slides off-screen by default; opens via hamburger. */
  .sidebar {
    transform: translateX(-100%);
    width: 280px;
    box-shadow: var(--shadow-lg, 0 8px 24px rgba(0,0,0,0.4));
  }
  body.sidebar-open .sidebar {
    transform: translateX(0);
  }
  /* Disregard the "collapsed" rail mode at this size — full overlay is clearer. */
  .sidebar.collapsed {
    width: 280px;
    transform: translateX(-100%);
  }
  body.sidebar-open .sidebar.collapsed {
    transform: translateX(0);
  }
  .main-content,
  .sidebar.collapsed ~ .main-content { margin-left: 0; }

  body.sidebar-open .sidebar-backdrop { display: block; opacity: 1; }

  .sidebar-mobile-trigger { display: inline-flex; }
  /* The desktop sidebar internal toggle (☰ inside the sidebar header)
     is now redundant on small screens; hide it. */
  .sidebar .sidebar-toggle { display: none; }

  /* Chat dock: keep behavior but slightly narrower in dock mode. */
  .content-right { width: min(420px, 60vw); }
}

/* ============================================================
   iPad mini portrait + large phones landscape (<=820px)
   Stack chat below content; chat-fab becomes the primary entry.
   ============================================================ */
@media (max-width: 820px) {
  .top-bar { padding: 0 var(--sp-3, 12px); }
  .top-bar-title {
    font-size: var(--fs-md, 14px);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 50vw;
  }
  /* Hide the "current-theme" pill on phones to save space. */
  .theme-indicator { display: none; }

  /* Content padding shrinks. */
  .content-left { padding: var(--sp-3, 12px); }

  /* Chat drawer becomes a bottom sheet by default (mode-dock). */
  .content-wrapper { flex-direction: column; overflow: visible; height: auto; min-height: calc(100vh - var(--topbar-height, 56px)); }
  .content-left { width: 100%; height: auto; max-height: none; }

  .content-right.mode-dock {
    position: fixed;
    left: 0; right: 0; bottom: 0; top: auto;
    width: 100%;
    height: 65dvh;
    height: 65vh;
    max-height: 80vh;
    border-left: none;
    border-top: 1px solid var(--border-default, #30363d);
    border-top-left-radius: 14px;
    border-top-right-radius: 14px;
    box-shadow: 0 -12px 28px rgba(0,0,0,0.45);
    z-index: 950;
    transform: translateY(0);
    transition: transform var(--tr-base, 200ms) ease-out;
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
  .content-right.mode-dock.collapsed {
    transform: translateY(100%);
    border-top: none;
    box-shadow: none;
  }

  /* The .chat-resizer doesn't make sense on touch; hide it. */
  .chat-resizer { display: none; }

  /* Tap targets for chat header buttons. */
  .chat-panel-btn,
  .chat-win-btn {
    min-height: 36px;
    padding-left: 10px;
    padding-right: 10px;
  }
  .chat-window-controls { display: none; }

  /* The iridescent "Thinking…" activity bar must always be visible on
     mobile when the AI is processing. Belt-and-suspenders override —
     keeps display:flex + min-height locked in regardless of cascade. */
  #chat-activity-bar.chat-activity-bar.active,
  .chat-activity-bar.active {
    display: flex !important;
    flex-shrink: 0 !important;
    min-height: 36px !important;
    opacity: 1 !important;
  }

  /* Composer: single-row [+] [textarea] [→]. The previous "column +
     full-width buttons" layout stacked the +, textarea and Send on
     separate lines on iPhone — replaced with the modern ChatGPT/
     WhatsApp pattern. */
  .chat-input-row {
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    align-items: flex-end !important;
    gap: 6px !important;
    padding: 8px !important;
    position: relative;
  }
  .chat-input-wrap {
    flex: 1 1 auto !important;
    min-width: 0 !important;
    min-height: 40px !important;
  }
  #chat-input {
    font-size: 16px;          /* prevents iOS zoom-on-focus */
    min-height: 40px !important;
    padding: 9px 10px !important;
    line-height: 1.3 !important;
  }
  .chat-input-wrap:has(.chat-toolbar:not(.hidden)) #chat-input {
    min-height: 36px !important;
  }
  /* Show the "+" toggle on mobile, hide the inline 3-button column. */
  .chat-attach-toggle {
    display: inline-flex !important;
    align-self: flex-end !important;
    flex: 0 0 auto !important;
    width: 36px !important;
    height: 36px !important;
    padding: 0 !important;
    border-radius: 50% !important;
    background: transparent;
    border: 1px solid var(--border-default);
    color: var(--text-secondary);
    align-items: center;
    justify-content: center;
    cursor: pointer;
  }
  .content-right.attach-open .chat-attach-toggle {
    transform: rotate(45deg);
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
  }
  .chat-input-row > .chat-action-buttons {
    display: none !important;
  }
  /* When user taps "+", the file/voice/image become a popover ABOVE the row. */
  .content-right.attach-open .chat-input-row > .chat-action-buttons {
    display: flex !important;
    flex-direction: column !important;
    gap: 4px !important;
    position: absolute !important;
    left: 8px !important;
    bottom: calc(100% + 6px) !important;
    background: var(--bg-elevated);
    border: 1px solid var(--border-default);
    border-radius: 12px;
    padding: 6px;
    box-shadow: 0 8px 22px rgba(0,0,0,0.18);
    z-index: 120;
  }
  .content-right.attach-open .chat-input-row .chat-action-buttons .chat-action-btn,
  .content-right.attach-open .chat-input-row button.chat-action-btn {
    width: 40px !important;
    height: 40px !important;
    border-radius: 10px !important;
  }
  /* Send: compact 36×36 circle, icon-only. NOT full-width. */
  .chat-input-row > button#chat-send,
  #chat-send {
    flex: 0 0 auto !important;
    align-self: flex-end !important;
    width: 36px !important;
    height: 36px !important;
    min-width: 36px !important;
    min-height: 36px !important;
    max-height: 36px !important;
    padding: 0 !important;
    border-radius: 50% !important;
    gap: 0 !important;
  }
  #chat-send .send-label { display: none !important; }
  #chat-send .send-ico   { display: inline-flex !important; }
  #chat-send .send-ico svg { width: 16px !important; height: 16px !important; }

  /* Sessions popover spans the screen on phones. */
  .chat-sessions-pop {
    left: 4px !important;
    right: 4px !important;
    width: auto !important;
    max-width: none !important;
  }

  /* FAB sized for thumbs. */
  .chat-toggle-fab,
  #chat-fab {
    bottom: max(env(safe-area-inset-bottom), var(--sp-3, 12px));
    right: var(--sp-3, 12px);
    min-width: 56px;
    min-height: 56px;
    border-radius: 50%;
    box-shadow: var(--shadow-lg, 0 6px 18px rgba(0,0,0,0.35));
  }
}

/* ============================================================
   Phones portrait (<=480px)
   ============================================================ */
@media (max-width: 480px) {
  :root {
    --topbar-height: 52px;
  }
  .sidebar { width: 86vw; }
  body.sidebar-open .sidebar.collapsed,
  body.sidebar-open .sidebar { width: 86vw; }

  .lang-switcher { display: none; }   /* keep theme + ava dot only */
  .ava-status-dot { display: none; }
  .top-bar-actions { gap: 8px; }
  /* Keep font zoom compact: hide the % label; A− / A+ remain. */
  .font-scale-pct { display: none; }
  .font-scale-ctrl { border-radius: var(--r-full, 999px); }

  .content-left { padding: var(--sp-2, 8px); }

  /* Header keeps single row + horizontal-scroll behavior (defined in
   * chat.css). Just tighten typography for phone widths. */
  .chat-panel-title { font-size: var(--fs-md, 14px); }
  .chat-panel-actions { gap: 4px; }
  .chat-panel-btn { font-size: 12px; padding: 4px 8px; }

  /* ---- Phone fullscreen: any chat mode fills the entire viewport ----
   * Float/mini already become 70vh sheets at 768px; on phones we expand
   * every mode (dock/float/mini) to the full screen so the user always
   * gets a usable, full-width chat. The × button still closes it. */
  .content-right,
  .content-right.mode-dock,
  .content-right.mode-float,
  .content-right.mode-mini {
    position: fixed !important;
    inset: 0 !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    /* Defeat any ancestor `max-width` / `width: X%` constraints.
     * sidebar.css sets `.content-right { max-width: 100% }` which, when
     * the parent .content-wrapper is narrower than the viewport, would
     * pin the chat to that narrower box. Force the actual viewport size. */
    width: 100vw !important;
    min-width: 100vw !important;
    max-width: 100vw !important;
    height: 100vh !important;
    height: 100dvh !important;
    min-height: 100vh !important;
    min-height: 100dvh !important;
    max-height: 100vh !important;
    max-height: 100dvh !important;
    margin: 0 !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    border-radius: 0 !important;
    border: none !important;
    box-shadow: none !important;
    z-index: 9500 !important;
    padding-bottom: env(safe-area-inset-bottom, 0);
    /* Some browsers respect transform creating a containing block; reset */
    transform: none;
  }
  /* The chat-fab/close FAB sits on top — keep it tappable above chat. */
  .chat-toggle-fab, #chat-fab { z-index: 9600 !important; }
  /* Slide-down close when collapsed (preserve the dock animation). */
  .content-right.collapsed,
  .content-right.mode-dock.collapsed,
  .content-right.mode-float.collapsed,
  .content-right.mode-mini.collapsed {
    transform: translateY(100%);
  }
  /* Resizer/drag-grip make no sense at fullscreen. */
  .chat-resizer,
  .chat-drag-grip { display: none !important; }

  /* Research view sidebar collapses below */
  .research-shell,
  .research-layout {
    grid-template-columns: 1fr !important;
  }
  /* Board: 1 column at this size (research.css already does 1 col @640) — keep parity. */

  /* Tables in markets/portfolios — let them scroll horizontally instead of breaking layout. */
  .markets-table-wrap,
  .table-wrap,
  .scroll-x {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Forms (login/signup/settings) full-width inputs. */
  input, select, textarea, button {
    max-width: 100%;
  }
}

/* ============================================================
   Touch-only: kill hover effects that get "stuck" on tap.
   ============================================================ */
@media (hover: none) and (pointer: coarse) {
  .nav-item:hover,
  .card:hover,
  .board-card:hover {
    background: inherit;
  }
  .theme-toggle-btn:hover {
    transform: none;
  }
}

/* ============================================================
   Modal sizing on phones — make any dialog full-screen.
   ============================================================ */
@media (max-width: 640px) {
  .chat-modal-box,
  .mem-box {
    width: 100% !important;
    max-width: 100% !important;
    height: 100%;
    max-height: 100dvh;
    border-radius: 0 !important;
  }
}

/* ============================================================
   MOBILE-FIRST CHAT REDESIGN (phones / touch devices only)
   Larger tap targets, iconified header, bottom-sheet dropdowns.
   ============================================================ */
@media (max-width: 480px) {

  /* --- Header: stack title on top, actions below in a wrap row -- */
  .chat-panel-header {
    padding: 8px 10px !important;
    row-gap: 6px !important;
    min-height: auto !important;
  }
  .chat-panel-title {
    font-size: 15px !important;
    flex: 1 1 auto;
  }

  /* --- Action buttons: 44x44 touch targets, icon-only --- */
  .chat-panel-actions {
    gap: 6px !important;
    row-gap: 6px !important;
    justify-content: flex-start !important;
  }
  .chat-panel-actions > button,
  .chat-panel-actions > .chat-model-wrap > button,
  .chat-panel-actions > .chat-tier-wrap > button {
    min-width: 40px !important;
    min-height: 40px !important;
    height: 40px !important;
    padding: 0 10px !important;
    font-size: 18px !important;
    border-radius: 10px !important;
    border: 1px solid var(--border-default) !important;
    background: var(--bg-elevated) !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    line-height: 1 !important;
  }
  .chat-panel-actions > button:active,
  .chat-panel-actions > .chat-model-wrap > button:active,
  .chat-panel-actions > .chat-tier-wrap > button:active {
    background: var(--bg-active, rgba(0,0,0,0.08)) !important;
    transform: scale(0.96);
  }

  /* Replace text labels with emoji glyphs for the main actions */
  #chat-sessions-btn,
  button#chat-sessions-btn { font-size: 0 !important; }
  #chat-sessions-btn::before { content: "\1F4CB"; font-size: 20px; }

  #chat-memory-btn,
  button#chat-memory-btn { font-size: 0 !important; }
  #chat-memory-btn::before { content: "\1F4BE"; font-size: 20px; }

  #chat-plan-btn,
  button#chat-plan-btn { font-size: 0 !important; }
  #chat-plan-btn::before { content: "\1F4DD"; font-size: 20px; }

  #chat-export-btn,
  button#chat-export-btn { font-size: 0 !important; }
  #chat-export-btn::before { content: "\2913"; font-size: 22px; font-weight: bold; }

  #chat-reset-btn,
  button#chat-reset-btn { font-size: 0 !important; }
  #chat-reset-btn::before { content: "\27F2"; font-size: 22px; }

  #chat-cancel-btn,
  button#chat-cancel-btn { font-size: 0 !important; }
  #chat-cancel-btn::before { content: "\26D4"; font-size: 20px; }

  /* Tier & model: keep a small caret hint */
  .chat-tier-wrap > button { font-size: 0 !important; position: relative; }
  .chat-tier-wrap > button::before { content: "\26A1"; font-size: 20px; }

  .chat-model-wrap > button { font-size: 0 !important; position: relative; }
  .chat-model-wrap > button::before { content: "\1F9E0"; font-size: 20px; }

  /* Close button: bigger X */
  #chat-close {
    min-width: 44px !important;
    min-height: 44px !important;
    font-size: 24px !important;
    border-radius: 10px !important;
    margin-left: 4px !important;
  }

  /* Hide the 5-button window-controls cluster on phone (always fullscreen) */
  .chat-window-controls { display: none !important; }

  /* --- Dropdowns become bottom action-sheets --- */
  .chat-model-pop,
  .chat-tier-pop,
  .chat-sessions-pop {
    position: fixed !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    top: auto !important;
    width: 100vw !important;
    max-width: 100vw !important;
    min-width: 0 !important;
    max-height: 70vh !important;
    border-radius: 16px 16px 0 0 !important;
    border: 1px solid var(--border-default) !important;
    border-bottom: none !important;
    box-shadow: 0 -8px 32px rgba(0,0,0,0.25) !important;
    background: var(--bg-elevated) !important;
    z-index: 9700 !important;
    overflow-y: auto !important;
    padding: 8px 0 calc(env(safe-area-inset-bottom, 0) + 8px) 0 !important;
    transform: none !important;
    animation: chatSheetUp 180ms ease-out;
  }

  /* Drag-handle visual at top of sheet */
  .chat-model-pop::before,
  .chat-tier-pop::before,
  .chat-sessions-pop::before {
    content: "";
    display: block;
    width: 40px;
    height: 4px;
    background: var(--border-default);
    border-radius: 999px;
    margin: 6px auto 8px auto;
  }

  @keyframes chatSheetUp {
    from { transform: translateY(100%); }
    to   { transform: translateY(0); }
  }

  /* Bigger rows inside the sheets */
  .chat-model-pop > div,
  .chat-model-pop > button,
  .chat-model-pop li,
  .chat-tier-pop > div,
  .chat-tier-pop > button,
  .chat-tier-pop li,
  .chat-sessions-pop li {
    min-height: 56px !important;
    padding: 12px 16px !important;
    font-size: 16px !important;
    line-height: 1.3 !important;
    border-bottom: 1px solid var(--border-subtle, rgba(0,0,0,0.06)) !important;
  }
  .chat-sessions-pop .s-when {
    font-size: 13px !important;
    min-width: 64px !important;
  }
  .chat-sessions-pop .s-rename,
  .chat-sessions-pop .s-del {
    min-width: 40px !important;
    min-height: 40px !important;
    font-size: 18px !important;
  }
  .chat-sessions-pop .sess-head,
  .chat-sessions-pop .sess-foot {
    padding: 12px 16px !important;
    font-size: 15px !important;
  }
  .chat-sessions-pop .sess-head button {
    min-height: 40px !important;
    padding: 0 14px !important;
    font-size: 15px !important;
  }

  /* Backdrop dimmer when any sheet is open (popovers use .open class) */
  body:has(.chat-model-pop.open),
  body:has(.chat-tier-pop.open),
  body:has(.chat-sessions-pop.open) {
    overflow: hidden;
  }
  body:has(.chat-model-pop.open)::before,
  body:has(.chat-tier-pop.open)::before,
  body:has(.chat-sessions-pop.open)::before {
    content: "";
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.45);
    z-index: 9650;
    pointer-events: none;
    animation: chatBackdropIn 180ms ease-out;
  }
  @keyframes chatBackdropIn {
    from { opacity: 0; }
    to   { opacity: 1; }
  }

  /* Drag-handle only visible when sheet is open (avoid stray pseudo) */
  .chat-model-pop:not(.open)::before,
  .chat-tier-pop:not(.open)::before,
  .chat-sessions-pop:not(.open)::before {
    display: none;
  }

  /* --- Composer: bigger input padding + compact circular send.
       Send stays a 36×36 round icon button (NOT the old 52×52 block)
       so it lines up cleanly with the [+] toggle on the same row. */
  .chat-composer,
  .chat-input-row {
    padding: 10px !important;
    gap: 8px !important;
  }
  .chat-composer textarea,
  #chat-input,
  textarea.chat-input {
    font-size: 16px !important;   /* prevents iOS auto-zoom */
    min-height: 44px !important;
    padding: 11px 14px !important;
    border-radius: 12px !important;
    line-height: 1.3 !important;
  }
  .chat-input-wrap {
    min-height: 44px !important;
  }
  /* + toggle: a bit larger on a phone (40×40) for thumb-tap comfort. */
  .chat-attach-toggle {
    width: 40px !important;
    height: 40px !important;
  }
  /* Send: 40×40 round icon button at phone widths — matches the +
     toggle so the row looks balanced. */
  #chat-send,
  button.chat-send,
  .chat-composer button[type="submit"] {
    width: 40px !important;
    min-width: 40px !important;
    height: 40px !important;
    min-height: 40px !important;
    max-height: 40px !important;
    font-size: 0 !important;
    border-radius: 50% !important;
    padding: 0 !important;
  }
  #chat-send .send-ico svg { width: 18px !important; height: 18px !important; }
}

/* ============================================================
   iOS Safari bottom cutoff fix — covers iPhone + iPad Safari.
   - Use dynamic viewport height (100dvh) so retracting URL bar
     does not push content off-screen.
   - Honor safe-area-inset-bottom so the user-profile / composer
     clear the home-indicator and bottom toolbar.
   ============================================================ */
@media (max-width: 1024px) {
  /* Outer shell: use dvh where available so layout shrinks with
     iOS Safari toolbar. Fall back to vh. */
  .app-layout {
    min-height: 100vh;
    min-height: 100dvh;
  }
  .sidebar {
    height: 100vh;
    height: 100dvh;
  }
  /* Pad sidebar footer so the user-profile row clears the home
     indicator / Safari bottom toolbar on iOS. */
  .sidebar-footer {
    padding-bottom: calc(var(--sp-3, 12px) + env(safe-area-inset-bottom, 0)) !important;
  }
  /* Ensure the sidebar nav itself can scroll if content + footer
     exceed the visible viewport. */
  .sidebar-nav {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* Phone fullscreen chat: composer needs safe-area padding so the
   input row & send button are not hidden behind the iOS toolbar. */
@media (max-width: 480px) {
  .content-right .chat-panel,
  .content-right > .chat-panel,
  .chat-panel {
    /* If the chat panel is the root flex column inside content-right,
       reserve space at the bottom for the home indicator. */
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
  /* The composer is the bottom-most child; lift it above the
     home-indicator strip. */
  .chat-composer,
  .chat-input-row {
    padding-bottom: calc(10px + env(safe-area-inset-bottom, 0)) !important;
  }
}

/* iPad portrait / landscape Safari: sidebar is hidden behind the
   hamburger drawer at narrow widths, but at 768–1024 it may still
   render — give its footer the same safe-area treatment. */
@media (min-width: 481px) and (max-width: 1024px) {
  .content-right.mode-float,
  .content-right.mode-dock {
    /* Don't let docked/floating chat overflow off the bottom on iPad. */
    max-height: calc(100dvh - var(--topbar-height, 56px));
  }
  .content-right .chat-composer,
  .content-right .chat-input-row {
    padding-bottom: calc(10px + env(safe-area-inset-bottom, 0)) !important;
  }
}

/* ============================================================
   iOS Safari / iPadOS Chrome bottom cutoff — universal fix
   Applies to ALL touch devices regardless of viewport width.
   iPadOS landscape can be 1366px+ so width queries miss them.
   ============================================================ */
@media (hover: none) and (pointer: coarse) {
  /* Force every viewport-height-relative chat surface to use the
     *dynamic* viewport height (shrinks with browser toolbar). */
  .content-right.mode-dock {
    height: calc(100dvh - var(--topbar-height, 56px)) !important;
    max-height: calc(100dvh - var(--topbar-height, 56px)) !important;
  }
  .content-right.mode-float {
    /* Float panel: keep top offset, but constrain bottom to visible
       viewport accounting for safe-area inset. */
    max-height: calc(100dvh - 104px - env(safe-area-inset-bottom, 0)) !important;
    bottom: calc(24px + env(safe-area-inset-bottom, 0)) !important;
  }
  .content-right.mode-mini {
    max-height: calc(100dvh - 80px - env(safe-area-inset-bottom, 0)) !important;
    bottom: calc(16px + env(safe-area-inset-bottom, 0)) !important;
  }

  /* Make .content-right a proper flex column so the input row stays
     pinned to the bottom of the visible area, and #chat-log scrolls. */
  .content-right {
    display: flex !important;
    flex-direction: column !important;
  }
  #chat-log,
  .chat-log {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
  }
  /* Pin input row at bottom with safe-area padding (home indicator). */
  .content-right > .chat-input-row,
  .chat-input-row {
    flex-shrink: 0 !important;
    padding-bottom: calc(8px + env(safe-area-inset-bottom, 0)) !important;
    background: var(--bg-elevated);
  }

  /* Outer shell: use dvh so the entire page doesn't extend behind
     the browser toolbar (which would also push the sidebar footer
     off-screen). */
  .app-layout {
    min-height: 100dvh !important;
  }
  .sidebar {
    height: 100dvh !important;
  }
  .sidebar-footer {
    padding-bottom: calc(var(--sp-3, 12px) + env(safe-area-inset-bottom, 0)) !important;
  }
}

/* Phone-specific fullscreen chat already uses 100dvh — also force
   its inner column structure for input pinning. */
@media (max-width: 480px) {
  .content-right,
  .content-right.mode-dock,
  .content-right.mode-float,
  .content-right.mode-mini {
    display: flex !important;
    flex-direction: column !important;
  }
  .content-right > #chat-log,
  .content-right > .chat-log {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    overflow-y: auto !important;
  }
}

/* ============================================================
   Lock the page itself on touch devices — no body rubber-band /
   no whitespace strip appearing when the iOS toolbar retracts.
   The page is now a fixed frame; only inner panes scroll.
   ============================================================ */
@media (hover: none) and (pointer: coarse) {
  html, body {
    height: 100vh;
    height: 100dvh;
    max-height: 100vh;
    max-height: 100dvh;
    overflow: hidden !important;
    overscroll-behavior: none;
    position: fixed;
    width: 100%;
    top: 0;
    left: 0;
  }
  /* The main app shell must fit exactly within the viewport. */
  .app-layout {
    height: 100vh;
    height: 100dvh;
    max-height: 100vh;
    max-height: 100dvh;
    overflow: hidden;
  }
  /* The main content area scrolls internally instead. */
  .main-content,
  .content-wrapper {
    height: 100%;
    max-height: 100%;
    overflow: hidden;
  }
  .content-left {
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }
}

/* ==========================================================================
   Phase 2 — forms / shell / admin mobile hardening (ADDITIVE).
   Scoped to touch devices and small widths only, so the gated desktop /
   tablet-landscape viewports are never affected.
   ========================================================================== */

/* iOS Safari zooms the whole page when a focused input has font-size < 16px.
   Apply 16px to every form field on small / touch viewports — never on the
   gated desktop + tablet-landscape (>=1180px) widths. The width clause makes
   it verifiable in emulation; the touch clause also covers landscape phones
   (>820px wide but still touch). Extends the chat composer's existing fix to
   login / signup / settings / account / admin / search and every other form. */
@media (max-width: 820px), (hover: none) and (pointer: coarse) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select,
  textarea {
    /* !important: many components (.cal-select, .tr-select, .an-input,
       .research-select, #th-chat-input, #im-input, …) set their own smaller
       font-size with higher specificity, which would still trigger iOS zoom.
       The override is mobile-scoped so desktop is unaffected. */
    font-size: 16px !important;
  }
}

/* Comfortable tap targets (Apple HIG >= 44px) for the shared shell controls
   (sidebar nav + top bar) that were undersized. Width-scoped so it's
   verifiable and desktop-safe. */
@media (max-width: 820px) {
  .sidebar-mobile-trigger {
    width: 44px;
    height: 44px;
  }
  /* Primary navigation: each nav row a full 44px tap target. */
  .sidebar .nav-item {
    min-height: 44px;
  }
  /* Shell icon/text controls (top bar + sidebar footer menu): 44px hit area.
     These classes exist only in the shell, so bare selectors are safe and the
     whole block is mobile-scoped. */
  .theme-toggle-btn,
  .user-menu-toggle,
  .lang-pop-btn,
  .feedback-btn-minimal {
    min-height: 44px;
    min-width: 44px;
  }
  .font-scale-ctrl {
    height: 44px;
  }
  .font-scale-btn {
    min-width: 40px;
    min-height: 44px;
  }
  .font-scale-pct {
    min-height: 44px;
    min-width: 44px;
  }
  /* Brand/home link in the sidebar header — a real nav target. */
  .sidebar-brand {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
}

/* Admin tables are dense and wide; on phones let each one scroll horizontally
   inside its own box instead of pushing the page sideways. (Admins normally
   work on desktop, so this is a safety net; verify on-device when an admin
   account is available.) */
@media (max-width: 640px) {
  table.ab-tbl, table.ac-tbl, table.ao-tbl, table.ar-tbl,
  table.au-tbl, table.fb-tbl, table.hb-tbl {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
  }
  /* Admin "new team" inline form: stack its inputs/button so the row doesn't
     overflow the phone width. */
  .admin-new-team {
    flex-wrap: wrap;
  }
  .admin-new-team input,
  .admin-new-team select {
    flex: 1 1 100%;
    min-width: 0;
    max-width: 100%;
  }
}
