/* ── Backdrop ──────────────────────────────────────── */

.drawer-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition-duration-basic, 220ms) var(--cubic-exit, ease);
}

.drawer-overlay--visible {
  opacity: 1;
  pointer-events: auto;
}

/* ── Panel ─────────────────────────────────────────── */

.drawer {
  position: fixed;
  top: calc(58px + env(safe-area-inset-top));
  left: 0;
  bottom: 0;
  z-index: 95;
  width: min(360px, 90vw);
  background: var(--bg);
  border-right: 1px solid var(--border-light);
  display: flex;
  flex-direction: column;
  transform: translateX(-100%);
  /* Use the apps-sdk-ui motion tokens so all platform transitions
     read as part of the same design system. --cubic-move is the
     ease curve the SDK uses for sliding panels. */
  transition: transform var(--transition-duration-basic, 250ms) var(--cubic-move, cubic-bezier(0.4, 0, 0.2, 1));
}

.drawer--open {
  transform: translateX(0);
  box-shadow: 8px 0 48px rgba(0, 0, 0, 0.5);
}

/* Disable the transition while the user is mid-drag so the panel
   follows the finger 1:1; restored on touchend regardless of close. */
.drawer--dragging { transition: none; }

.drawer__body {
  flex: 1;
  overflow: hidden;
  padding: 10px 8px max(8px, env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* Wrapper around New chat + Chats + Apps. Holds the layout for
   the per-section scroll model: New chat stays at the top, Chats
   and Apps share the remaining space proportionally to their
   content, and each scrolls INTERNALLY when its share is smaller
   than its content. This means both sections are always visible
   with roughly equal spacing — if you have 100 chats, you don't
   have to scroll past all of them to reach Apps. A single
   parent-scroll would force that. */
.drawer__scroll-wrap {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* ── New chat ──────────────────────────────────────── */

/* Outlined pill — visually distinct from the chat/app rows below
   so a tap-friendly "start fresh" affordance reads as a primary
   action, not just another list item. The hairline border sets it
   apart; no horizontal margin so its left/right edges align with
   the chat rows + Settings row (all at the drawer's 12px gutter).
   Earlier the pill had `margin: 0 4px` which pushed its content
   16px from the drawer edge while every other row was at 12px —
   the misalignment read as a layout bug to the eye. Margin-bottom
   tightened 12 → 4 so the "Chats" header sits close to the pill
   (the header's own padding provides the visual gap). */
.drawer__item--new {
  color: var(--text);
  font-weight: 500;
  margin: 0 0 4px;
  padding: 11px 12px;
  border: 1px solid var(--border);
}

.drawer__item--new:hover {
  color: var(--text);
  background: var(--surface);
  border-color: var(--border-light);
}

/* ── Groups (History, Apps) ───────────────────────── */

/* Default group: size-to-content, can shrink. The two sections
   that share space (chats + apps) get more specific rules below
   so the chats-heavy / apps-heavy lopsidedness self-corrects. */
.drawer__group {
  flex: 0 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  margin-top: 4px;
}

/* Chats + Apps: symmetric split. Both sections grow to share
   available space proportionally (`flex: 1 1 0`), and both scroll
   internally when their share is smaller than their content. With
   the previous asymmetric rule (chats `flex: 1 1 0`, apps `flex: 0
   1 auto` capped at 50%), apps' content size often won the layout
   when you had a handful of chats and many apps — chats shrank to
   its 80px floor and apps ballooned up to the 50% cap, so apps
   visually took more space than chats. Symmetric grow keeps both
   at the same vertical share regardless of content count. A small
   min-height on each guarantees neither section disappears even
   when one has many more rows. */
.drawer__group--chats,
.drawer__group--apps {
  flex: 1 1 0;
  min-height: 80px;
}


/* Section labels: sentence case, plain muted color, no tracking.
   The earlier uppercase-tracked-accent treatment read as ornament,
   not structure. The leading icon already tells you which section
   you're in; the label is just the readable hook.

   Now an <h2> rather than a <p> — sighted users see the same
   typography (the SDK reset + `margin: 0` here mean default heading
   styles don't apply) but screen-reader users get a section-level
   heading they can jump to via rotor / heading navigation. Size
   bumped 12 → 13 to match `settings__section-title` so the platform
   reads as one design system; stays quieter than the 14px rows
   above so the action-vs-structure hierarchy still reads. */
.drawer__label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
  /* Top padding tightened from 18 → 8 so the gap between
     "New chat" and the "Chats" section header reads as a
     subtle separation, not a vertical chasm. The 6px bottom
     keeps the label visually attached to the rows below. */
  padding: 8px 12px 6px;
  margin: 0;
}
.drawer__label svg { flex-shrink: 0; opacity: 0.85; color: var(--muted); }
.drawer__label span { line-height: 1; }

/* Per-section row container — scrolls internally when its group
   has been shrunk below its content size. Fade-mask at the bottom
   so a partial row at the scroll boundary doesn't read as cut. */
.drawer__scroll {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  scrollbar-width: thin;
  mask-image: linear-gradient(
    to bottom,
    black calc(100% - 16px),
    transparent
  );
  -webkit-mask-image: linear-gradient(
    to bottom,
    black calc(100% - 16px),
    transparent
  );
  /* Bottom overscroll room equal to the 16px fade-mask, so the last row
     (e.g. the selected app) can scroll clear of the dimmed band instead of
     reading as pinned under the Settings divider. scroll-padding-bottom keeps
     scroll-into-view from re-tucking it under the mask. */
  padding-bottom: 16px;
  scroll-padding-bottom: 16px;
}

/* ── Items ─────────────────────────────────────────── */

.drawer__item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  background: none;
  border: none;
  border-radius: 10px;
  color: var(--text);
  font-size: 14px;
  font-family: var(--font);
  font-weight: 400;
  text-align: left;
  cursor: pointer;
  transition: color 0.12s, background 0.12s;
  -webkit-tap-highlight-color: transparent;
  /* Pairs with .drawer__scroll's scroll-padding-bottom so a row revealed via
     scroll-into-view never lands inside the bottom fade / against the divider. */
  scroll-margin-bottom: 16px;
}

/* Hover gated to real pointers (mouse / trackpad). On touch
   devices :hover lingers on the last-tapped row until the user
   taps elsewhere — sticking a highlight on rows the user just
   navigated AWAY from. Matches the @openai/apps-sdk-ui convention
   used across their components. */
@media (hover: hover) and (pointer: fine) {
  .drawer__item:hover {
    color: var(--text);
    background: var(--surface);
  }
}

.drawer__item--active {
  color: var(--accent);
  background: var(--accent-dim);
}

/* Keyboard focus ring — applies to all interactive drawer rows.
   Without this, tab navigation lands on rows with no visual cue
   for screen-reader / keyboard users. The accent ring matches
   the composer pill's focus halo so the platform reads as a
   single design system. */
.drawer__item:focus-visible,
.drawer__more:focus-visible,
.drawer__menu-item:focus-visible,
.drawer__menu-confirm-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.drawer__item-icon {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  display: grid;
  place-items: center;
  color: inherit;
  opacity: 0.85;
}

.drawer__item-text {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}


/* Trailing pin badge on pinned rows — small, muted, sits flush to
   the row's right edge. Doesn't compete with the chat title; just
   signals the row is in the pinned group. */
.drawer__item-pin {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  margin-left: 6px;
  color: var(--muted);
  opacity: 0.85;
}
.drawer__item--active .drawer__item-pin { color: inherit; opacity: 1; }

/* ── Row + three-dots menu ─────────────────────────── */

/* The row stacks two siblings (button + menu trigger) horizontally so
 * the trigger isn't nested inside the row button (nested <button>
 * elements are invalid HTML and Chrome silently hoists the inner one
 * out, breaking layout). The menu floats below the row absolutely. */
.drawer__row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 2px;
}

.drawer__row .drawer__item {
  flex: 1;
  min-width: 0;
}

/* The ⋮ button matches the row height so its hit area aligns
   with the row's vertical bounds. Width bumped 32 → 40 for a
   compliant touch target (44 is the strict guideline but the
   button stretches vertically so the full hit area is the row
   height ≈ 40px). align-self: stretch makes it grow to the row's
   full height set by the .drawer__item padding. */
.drawer__more {
  flex-shrink: 0;
  align-self: stretch;
  width: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  border-radius: 8px;
  color: var(--muted);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s, color 0.12s, background 0.12s, transform 0.08s;
  -webkit-tap-highlight-color: transparent;
}

/* Pressed — the load-bearing feedback fix. tap-highlight is transparent
   above, so without an explicit :active the kebab reads as dead on touch
   until the menu portal paints. Scale + tint acknowledges the tap instantly. */
.drawer__more:active {
  color: var(--text);
  background: var(--surface);
  transform: scale(0.92);
}

/* Open trigger — Radix stamps data-state="open" on the trigger; keep it lit
   and accent-tinted (and fully opaque, overriding the touch opacity:0 reveal)
   so the open menu visibly belongs to this row's kebab. */
.drawer__more[data-state="open"] {
  opacity: 1;
  color: var(--accent);
  background: var(--accent-dim);
}

.drawer__row:focus-within .drawer__more { opacity: 1; }

/* Hover-only desktop reveal — keeps the trigger hidden until the
   user actually hovers a row with a mouse. */
@media (hover: hover) and (pointer: fine) {
  .drawer__row:hover .drawer__more { opacity: 1; }
  .drawer__more:hover {
    color: var(--text);
    background: var(--surface);
  }
}

/* Always show on touch devices — :hover never fires there, and the
 * menu trigger has to be reachable without a hover state. */
@media (hover: none) {
  .drawer__more { opacity: 0.5; }
}

/* Menu roundness — outer 12px so the floating popover reads as a
   softer surface than the underlying 8px rows; inner items match
   row radius (8px) so a hovered menu item visually rhymes with
   the row's selected/active background. */
.drawer__menu {
  position: absolute;
  right: 4px;
  top: calc(100% - 4px);
  z-index: 2;
  min-width: 200px;
  padding: 6px;
  background: var(--bg);
  border: 1px solid var(--border-light);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}

/* Flip the menu upward when the parent .drawer__row has the
   --flip-up modifier (set by DrawerRow when there's not enough
   space below — last row in the scroll area). */
.drawer__row--flip-up .drawer__menu {
  top: auto;
  bottom: calc(100% - 4px);
}

.drawer__menu-item {
  width: 100%;
  display: block;
  padding: 8px 10px;
  background: none;
  border: none;
  border-radius: 8px;
  color: var(--text);
  font-size: 13px;
  font-family: var(--font);
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Icon-bearing menu items (Pin to top / Unpin) get a flex row so
   the leading icon stays aligned with the row's text baseline. */
.drawer__menu-item--icon {
  display: flex;
  align-items: center;
  gap: 8px;
}
.drawer__menu-item--icon svg { flex-shrink: 0; opacity: 0.85; }

@media (hover: hover) and (pointer: fine) {
  .drawer__menu-item:hover {
    background: var(--surface);
  }
}

.drawer__menu-item--danger {
  color: var(--danger);
}

.drawer__menu-confirm {
  padding: 6px 10px 8px;
}

.drawer__menu-confirm-label {
  display: block;
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 6px;
}

.drawer__menu-confirm-actions {
  display: flex;
  gap: 6px;
}

.drawer__menu-confirm-btn {
  flex: 1;
  padding: 6px 8px;
  background: var(--surface);
  border: 1px solid var(--border-light);
  border-radius: 6px;
  color: var(--text);
  font-size: 12px;
  font-family: var(--font);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.drawer__menu-confirm-btn--yes {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
}

.drawer__menu-note {
  margin: 6px 4px 0;
  padding: 4px 6px;
  border-top: 1px solid var(--border-light);
  padding-top: 8px;
  font-size: 11px;
  font-style: italic;
  color: var(--muted);
  line-height: 1.35;
}

/* ── Inline rename ─────────────────────────────────── */

.drawer__item--editing {
  padding: 4px 6px;
}

.drawer__rename-input {
  flex: 1;
  width: 100%;
  padding: 5px 8px;
  background: var(--surface);
  border: 1px solid var(--accent);
  border-radius: 6px;
  color: var(--text);
  font-size: 13px;
  font-family: var(--font);
  outline: none;
  -webkit-tap-highlight-color: transparent;
}

/* ── Empty state ──────────────────────────────────── */

/* SDK EmptyMessage carries its own internal padding + typography.
   We only tighten the surrounding scope (keep it left-aligned and
   not centred-block) so the empty hint sits flush with the rest
   of the list. */
.drawer__empty {
  padding: 4px 10px 8px;
  text-align: left;
  align-items: flex-start;
}

/* ── Bottom group (Settings) ───────────────────────── */

.drawer__group--bottom {
  margin-top: auto;
  padding-top: 8px;
  border-top: 1px solid var(--border-light);
}

/* ── Streaming pulse dot ───────────────────────────── */

/* 6px accent dot in front of a row label. Marks chats whose agent
   is mid-turn so a user switching to another chat still sees the
   background build progressing in the drawer. Pulse via opacity so
   the dot reads as alive but doesn't shimmer aggressively — the
   slow 1.5s loop keeps it ambient. */
.drawer__streaming-dot {
  flex-shrink: 0;
  width: 6px;
  height: 6px;
  margin-right: 2px;
  border-radius: 50%;
  background: var(--accent);
  animation: drawer-streaming-pulse 1.5s ease-in-out infinite;
}

.drawer__attention-dot {
  flex-shrink: 0;
  width: 6px;
  height: 6px;
  margin-right: 2px;
  border-radius: 50%;
  background: var(--accent);
}

@keyframes drawer-streaming-pulse {
  0%   { opacity: 1; }
  50%  { opacity: 0.4; }
  100% { opacity: 1; }
}

/* Respect prefers-reduced-motion — for users who turn off animations
   the pulse becomes a steady dot rather than a flashing one. The
   information ("streaming") still surfaces via aria-label + presence. */
@media (prefers-reduced-motion: reduce) {
  .drawer__streaming-dot { animation: none; }
  .drawer__more:active { transform: none; }
}

/* ── Settings warning dot ──────────────────────────── */

/* Tiny accent ring at the right edge of the Settings row when any
   provider's refresh token has expired. Passive nudge — no banner,
   no modal, no text. The user sees the dot, opens Settings, and
   the existing ProviderRow reconnect button handles the rest. */
.drawer__settings-warning-dot {
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  margin-left: 6px;
  border-radius: 50%;
  background: var(--accent);
  /* Faint outer ring so the dot reads as deliberate UI rather than
     a stray pixel — uses accent-dim which is already tuned for
     accent halos elsewhere (composer focus, --pwa-btn--install). */
  box-shadow: 0 0 0 2px var(--accent-dim);
}
