<template>
  <div class="review">
    <HintChip
      v-if="config.isDemo"
      view-key="review"
      message="Swipe right to approve, left to skip. One of these jobs is a ghost post — can you spot it?"
    />
    <!-- Header -->
    <header class="review__header">
      <div class="review__title-row">
        <h1 class="review__title">Review Jobs</h1>
        <button class="help-btn" :aria-expanded="showHelp" @click="showHelp = !showHelp">
          <span aria-hidden="true">?</span>
          <span class="sr-only">Keyboard shortcuts</span>
        </button>
      </div>

      <!-- Status filter tabs (segmented control) -->
      <div class="review__tabs" role="tablist" aria-label="Filter by status">
        <button
          v-for="tab in TABS"
          :key="tab.status"
          role="tab"
          class="review__tab"
          :class="{ 'review__tab--active': activeTab === tab.status }"
          :aria-selected="activeTab === tab.status"
          @click="setTab(tab.status)"
        >
          {{ tab.label }}
          <span v-if="tab.status === 'pending' && store.remaining > 0" class="tab-badge">
            {{ store.remaining }}
          </span>
        </button>
      </div>
    </header>

    <!-- ── PENDING: card stack ──────────────────────────────────────────── -->
    <div v-if="activeTab === 'pending'" class="review__body">
      <!-- Loading -->
      <div v-if="store.loading" class="review__loading" aria-live="polite" aria-label="Loading jobs…">
        <span class="spinner" aria-hidden="true" />
        <span>Loading queue…</span>
      </div>

      <!-- Empty state — falcon stoop animation (easter egg 9.3) -->
      <div v-else-if="store.remaining === 0 && !store.loading" class="review__empty" role="status">
        <span class="empty-falcon" aria-hidden="true">🦅</span>
        <h2 class="empty-title">Queue cleared.</h2>
        <p class="empty-desc">Nothing to review right now. Run discovery to find new listings.</p>
      </div>

      <!-- Card stack -->
      <template v-else-if="store.currentJob">
        <!-- Keyboard hint bar -->
        <div class="hint-bar" aria-hidden="true">
          <span class="hint"><kbd>←</kbd><kbd>J</kbd> Reject</span>
          <span class="hint-counter">{{ store.remaining }} remaining</span>
          <span class="hint"><kbd>→</kbd><kbd>L</kbd> Approve</span>
        </div>

        <JobCardStack
          ref="stackRef"
          :job="store.currentJob"
          :remaining="store.remaining"
          @approve="onApprove"
          @reject="onReject"
          @skip="onSkip"
        />

        <!-- Action buttons (non-swipe path) -->
        <div class="review__actions" aria-label="Review actions">
          <button
            class="action-btn action-btn--reject"
            aria-label="Reject this job"
            @click="stackRef?.dismissReject()"
          >
            <span aria-hidden="true">✗</span> Reject
          </button>
          <button
            class="action-btn action-btn--skip"
            aria-label="Skip — come back later"
            @click="stackRef?.dismissSkip()"
          >
            <span aria-hidden="true">→↓</span> Skip
          </button>
          <button
            class="action-btn action-btn--approve"
            aria-label="Approve this job"
            @click="stackRef?.dismissApprove()"
          >
            <span aria-hidden="true">✓</span> Approve
          </button>
        </div>

        <!-- Undo hint -->
        <p class="review__undo-hint" aria-hidden="true">Press <kbd>Z</kbd> to undo</p>
      </template>
    </div>

    <!-- ── OTHER STATUS: list view ──────────────────────────────────────── -->
    <div v-else class="review__body">
      <div v-if="store.loading" class="review__loading" aria-live="polite">
        <span class="spinner" aria-hidden="true" />
        <span>Loading…</span>
      </div>
      <template v-else>
        <!-- Sort + filter bar -->
        <div class="list-controls" aria-label="Sort and filter">
          <select v-model="sortBy" class="list-sort" aria-label="Sort by">
            <option value="match_score">Best match</option>
            <option value="date_found">Newest first</option>
            <option value="company">Company A–Z</option>
          </select>
          <label class="list-filter-remote">
            <input type="checkbox" v-model="filterRemote" />
            Remote only
          </label>
          <span class="list-count">{{ sortedFilteredJobs.length }} job{{ sortedFilteredJobs.length !== 1 ? 's' : '' }}</span>
        </div>

        <div v-if="sortedFilteredJobs.length === 0" class="review__empty" role="status">
          <p class="empty-desc">No {{ activeTab }} jobs{{ filterRemote ? ' (remote only)' : '' }}.</p>
        </div>
        <ul v-else class="job-list" role="list">
          <li v-for="job in sortedFilteredJobs" :key="job.id" class="job-list__item">
            <div class="job-list__info">
              <span class="job-list__title">{{ job.title }}</span>
              <span class="job-list__company">
                {{ job.company }}
                <span v-if="job.is_remote" class="remote-tag">Remote</span>
              </span>
            </div>
            <div class="job-list__meta">
              <span v-if="job.match_score !== null" class="score-pill" :class="scorePillClass(job.match_score)">
                {{ job.match_score }}%
              </span>
              <button
                v-if="activeTab === 'approved'"
                class="job-list__action"
                @click="router.push(`/apply/${job.id}`)"
                :aria-label="`Draft cover letter for ${job.title}`"
              >✨ Draft</button>
              <a :href="job.url" target="_blank" rel="noopener noreferrer" class="job-list__link">
                View ↗
              </a>
            </div>
          </li>
        </ul>
      </template>
    </div>

    <!-- ── Help overlay ─────────────────────────────────────────────────── -->
    <Transition name="overlay">
      <div
        v-if="showHelp"
        class="help-overlay"
        role="dialog"
        aria-modal="true"
        aria-labelledby="help-title"
        @click.self="showHelp = false"
      >
        <div class="help-modal">
          <h2 id="help-title" class="help-modal__title">Keyboard Shortcuts</h2>
          <dl class="help-keys">
            <div class="help-keys__row">
              <dt><kbd>→</kbd> / <kbd>L</kbd></dt>
              <dd>Approve</dd>
            </div>
            <div class="help-keys__row">
              <dt><kbd>←</kbd> / <kbd>J</kbd></dt>
              <dd>Reject</dd>
            </div>
            <div class="help-keys__row">
              <dt><kbd>S</kbd></dt>
              <dd>Skip (come back later)</dd>
            </div>
            <div class="help-keys__row">
              <dt><kbd>Enter</kbd></dt>
              <dd>Expand / collapse description</dd>
            </div>
            <div class="help-keys__row">
              <dt><kbd>Z</kbd></dt>
              <dd>Undo last action</dd>
            </div>
            <div class="help-keys__row">
              <dt><kbd>?</kbd></dt>
              <dd>Toggle this help</dd>
            </div>
          </dl>
          <button class="help-modal__close" @click="showHelp = false" aria-label="Close help">✕</button>
        </div>
      </div>
    </Transition>

    <!-- ── Undo toast ────────────────────────────────────────────────────── -->
    <Transition name="toast">
      <div
        v-if="undoToast"
        class="undo-toast"
        role="status"
        aria-live="polite"
      >
        <span>{{ undoToast.message }}</span>
        <button class="undo-toast__btn" @click="doUndo">Undo</button>
      </div>
    </Transition>

    <!-- ── Stoop speed toast — easter egg 9.2 ───────────────────────────── -->
    <Transition name="toast">
      <div v-if="stoopToastVisible" class="stoop-toast" role="status" aria-live="polite">
        🦅 Stoop speed.
      </div>
    </Transition>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useReviewStore } from '../stores/review'
import JobCardStack from '../components/JobCardStack.vue'
import HintChip from '../components/HintChip.vue'
import { useAppConfigStore } from '../stores/appConfig'

const config = useAppConfigStore()

const store    = useReviewStore()
const route    = useRoute()
const router   = useRouter()
const stackRef = ref<InstanceType<typeof JobCardStack> | null>(null)

// ─── Tabs ──────────────────────────────────────────────────────────────────────

const TABS = [
  { status: 'pending',  label: 'Pending'  },
  { status: 'approved', label: 'Approved' },
  { status: 'rejected', label: 'Rejected' },
  { status: 'applied',  label: 'Applied'  },
  { status: 'synced',   label: 'Synced'   },
]

const activeTab = ref((route.query.status as string) ?? 'pending')

async function setTab(status: string) {
  activeTab.value = status
  if (status === 'pending') {
    await store.fetchQueue()
  } else {
    await store.fetchList(status)
  }
}

// ─── Undo toast ────────────────────────────────────────────────────────────────

const undoToast  = ref<{ message: string } | null>(null)
let   toastTimer = 0

function showUndoToast(action: 'approved' | 'rejected' | 'skipped') {
  clearTimeout(toastTimer)
  undoToast.value = { message: `${capitalize(action)}` }
  toastTimer = window.setTimeout(() => { undoToast.value = null }, 5000)
}

async function doUndo() {
  clearTimeout(toastTimer)
  undoToast.value = null
  await store.undo()
}

function capitalize(s: string) { return s.charAt(0).toUpperCase() + s.slice(1) }

// ─── Action handlers ───────────────────────────────────────────────────────────

async function onApprove() {
  const job = store.currentJob
  if (!job) return
  const ok = await store.approve(job)
  if (!ok) { stackRef.value?.resetCard(); return }
  showUndoToast('approved')
  checkStoopSpeed()
}

async function onReject() {
  const job = store.currentJob
  if (!job) return
  const ok = await store.reject(job)
  if (!ok) { stackRef.value?.resetCard(); return }
  showUndoToast('rejected')
  checkStoopSpeed()
}

function onSkip() {
  const job = store.currentJob
  if (!job) return
  store.skip(job)
  showUndoToast('skipped')
}

// ─── Stoop speed — easter egg 9.2 ─────────────────────────────────────────────

const stoopToastVisible = ref(false)

function checkStoopSpeed() {
  if (!store.stoopAchieved && store.isStoopSpeed) {
    store.markStoopAchieved()
    stoopToastVisible.value = true
    setTimeout(() => { stoopToastVisible.value = false }, 3500)
  }
}

// ─── Keyboard shortcuts ────────────────────────────────────────────────────────

const showHelp = ref(false)

function onKeyDown(e: KeyboardEvent) {
  // Don't steal keys when typing in an input
  if ((e.target as Element).closest('input, textarea, select, [contenteditable]')) return
  if (activeTab.value !== 'pending') return

  switch (e.key) {
    case 'ArrowRight':
    case 'l':
    case 'L':
      e.preventDefault()
      stackRef.value?.dismissApprove()
      break
    case 'ArrowLeft':
    case 'j':
    case 'J':
      e.preventDefault()
      stackRef.value?.dismissReject()
      break
    case 's':
    case 'S':
      e.preventDefault()
      stackRef.value?.dismissSkip()
      break
    case 'z':
    case 'Z':
      e.preventDefault()
      doUndo()
      break
    case 'Enter':
      // Expand/collapse — bubble to the card's button naturally; no action needed here
      break
    case '?':
      showHelp.value = !showHelp.value
      break
    case 'Escape':
      showHelp.value = false
      break
  }
}

// ─── List view: sort + filter ─────────────────────────────────────────────────

type SortKey = 'match_score' | 'date_found' | 'company'
const sortBy       = ref<SortKey>('match_score')
const filterRemote = ref(false)

const sortedFilteredJobs = computed(() => {
  let jobs = [...store.listJobs]
  if (filterRemote.value) jobs = jobs.filter(j => j.is_remote)
  jobs.sort((a, b) => {
    if (sortBy.value === 'match_score') return (b.match_score ?? -1) - (a.match_score ?? -1)
    if (sortBy.value === 'date_found')  return new Date(b.date_found).getTime() - new Date(a.date_found).getTime()
    if (sortBy.value === 'company')     return (a.company ?? '').localeCompare(b.company ?? '')
    return 0
  })
  return jobs
})

// Reset filters when switching tabs
watch(activeTab, () => {
  filterRemote.value = false
  sortBy.value = 'match_score'
})

// ─── List view score pill ─────────────────────────────────────────────────────

function scorePillClass(score: number) {
  if (score >= 80) return 'score-pill--high'
  if (score >= 60) return 'score-pill--mid'
  return 'score-pill--low'
}

// ─── Lifecycle ────────────────────────────────────────────────────────────────

onMounted(async () => {
  document.addEventListener('keydown', onKeyDown)
  await store.fetchQueue()
})

onUnmounted(() => {
  document.removeEventListener('keydown', onKeyDown)
  clearTimeout(toastTimer)
})
</script>

<style scoped>
.review {
  max-width: 680px;
  margin: 0 auto;
  padding: var(--space-8) var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  min-height: 100dvh;
}

/* ── Header ─────────────────────────────────────────────────────────── */

.review__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.review__title-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.review__title {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  color: var(--app-primary);
  flex: 1;
}

.help-btn {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--color-border);
  background: var(--color-surface-raised);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  font-weight: 700;
  cursor: pointer;
  flex-shrink: 0;
  transition: background 150ms ease, border-color 150ms ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.help-btn:hover { background: var(--app-primary-light); border-color: var(--app-primary); }

/* ── Tabs ────────────────────────────────────────────────────────────── */

.review__tabs {
  display: flex;
  background: var(--color-surface-raised);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border-light);
  padding: 3px;
  gap: 2px;
  overflow-x: auto;
  scrollbar-width: none;
}

.review__tabs::-webkit-scrollbar { display: none; }

.review__tab {
  flex: 1;
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  border: none;
  border-radius: calc(var(--radius-lg) - 3px);
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  transition: background 150ms ease, color 150ms ease;
  min-height: 32px;
}

.review__tab--active {
  background: var(--app-primary);
  color: white;
  box-shadow: var(--shadow-sm);
}

.review__tab:not(.review__tab--active):hover {
  background: var(--color-surface-alt);
  color: var(--color-text);
}

.tab-badge {
  background: var(--color-warning);
  color: white;
  font-size: 0.65rem;
  font-weight: 700;
  border-radius: 999px;
  padding: 1px 5px;
  line-height: 1.4;
}

.review__tab--active .tab-badge { background: rgba(255,255,255,0.3); }

/* ── Body ────────────────────────────────────────────────────────────── */

.review__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  flex: 1;
}

/* ── Loading ─────────────────────────────────────────────────────────── */

.review__loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: var(--space-12);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

/* ── Empty state — falcon stoop (easter egg 9.3) ────────────────────── */

.review__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-16) var(--space-8);
  text-align: center;
}

.empty-falcon {
  font-size: 4rem;
  animation: falcon-stoop 1.2s cubic-bezier(0.4, 0, 0.2, 1) forwards;
  display: block;
}

@keyframes falcon-stoop {
  0%   { transform: translateY(-60px) rotate(-30deg); opacity: 0; }
  60%  { transform: translateY(6px) rotate(0deg); opacity: 1; }
  80%  { transform: translateY(-4px); }
  100% { transform: translateY(0); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .empty-falcon { animation: none; }
}

.empty-title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  color: var(--color-text);
}

.empty-desc {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  max-width: 32ch;
}

/* ── Hint bar ────────────────────────────────────────────────────────── */

.hint-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-2) var(--space-1);
}

.hint {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  display: flex;
  align-items: center;
  gap: 4px;
}

.hint-counter {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-text-muted);
  font-family: var(--font-mono);
}

kbd {
  display: inline-flex;
  align-items: center;
  padding: 1px 5px;
  border-radius: 4px;
  border: 1px solid var(--color-border);
  background: var(--color-surface-alt);
  font-size: 0.7rem;
  font-family: var(--font-mono);
  color: var(--color-text);
  line-height: 1.5;
}

/* ── Action buttons ──────────────────────────────────────────────────── */

.review__actions {
  display: flex;
  gap: var(--space-3);
  justify-content: center;
  margin-top: var(--space-2);
}

.action-btn {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-6);
  border-radius: var(--radius-lg);
  font-size: var(--text-sm);
  font-weight: 700;
  cursor: pointer;
  border: 2px solid transparent;
  min-height: 44px;
  transition: background 150ms ease, border-color 150ms ease, transform 100ms ease;
}

.action-btn:active { transform: scale(0.96); }

.action-btn--reject {
  background: rgba(192, 57, 43, 0.08);
  border-color: var(--color-error);
  color: var(--color-error);
}
.action-btn--reject:hover { background: rgba(192, 57, 43, 0.16); }

.action-btn--skip {
  background: var(--color-surface-raised);
  border-color: var(--color-border);
  color: var(--color-text-muted);
}
.action-btn--skip:hover { background: var(--color-surface-alt); }

.action-btn--approve {
  background: rgba(39, 174, 96, 0.08);
  border-color: var(--color-success);
  color: var(--color-success);
}
.action-btn--approve:hover { background: rgba(39, 174, 96, 0.16); }

.review__undo-hint {
  text-align: center;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

/* ── Job list (non-pending tabs) ─────────────────────────────────────── */

.job-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.job-list__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md);
  min-height: 44px;
  transition: box-shadow 150ms ease;
}

.job-list__item:hover { box-shadow: var(--shadow-sm); }

.job-list__info { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }

.job-list__title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.job-list__company {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.job-list__meta { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }

.score-pill {
  padding: 2px var(--space-2);
  border-radius: 999px;
  font-size: var(--text-xs);
  font-weight: 700;
  font-family: var(--font-mono);
}

.score-pill--high { background: rgba(39, 174, 96, 0.15);  color: var(--score-high); }
.score-pill--mid  { background: rgba(212, 137, 26, 0.15); color: var(--score-mid);  }
.score-pill--low  { background: rgba(192, 57, 43, 0.15);  color: var(--score-low);  }

.job-list__link {
  font-size: var(--text-xs);
  color: var(--app-primary);
  text-decoration: none;
  font-weight: 600;
}

.job-list__action {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--app-primary);
  background: color-mix(in srgb, var(--app-primary) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--app-primary) 25%, transparent);
  border-radius: var(--radius-sm);
  padding: 2px 8px;
  cursor: pointer;
  transition: background 150ms;
  white-space: nowrap;
}

.job-list__action:hover {
  background: color-mix(in srgb, var(--app-primary) 18%, transparent);
}

.remote-tag {
  font-size: 0.65rem;
  font-weight: 700;
  color: var(--color-info);
  background: color-mix(in srgb, var(--color-info) 12%, transparent);
  border-radius: var(--radius-full);
  padding: 1px 5px;
  margin-left: 4px;
}

/* ── List controls (sort + filter) ──────────────────────────────────── */

.list-controls {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}

.list-sort {
  font-size: var(--text-xs);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-raised);
  color: var(--color-text);
  padding: 3px 8px;
  cursor: pointer;
}

.list-filter-remote {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  cursor: pointer;
  user-select: none;
}

.list-count {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  margin-left: auto;
}

/* ── Help overlay ────────────────────────────────────────────────────── */

.help-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(2px);
  z-index: 400;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
}

.help-modal {
  background: var(--color-surface-raised);
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
  padding: var(--space-6);
  width: 100%;
  max-width: 360px;
  position: relative;
  box-shadow: var(--shadow-xl, 0 16px 48px rgba(0,0,0,0.2));
}

.help-modal__title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  color: var(--color-text);
  margin-bottom: var(--space-4);
}

.help-keys { display: flex; flex-direction: column; gap: var(--space-3); }

.help-keys__row {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  font-size: var(--text-sm);
}

.help-keys__row dt { width: 6rem; flex-shrink: 0; display: flex; align-items: center; gap: 4px; }
.help-keys__row dd { color: var(--color-text-muted); }

.help-modal__close {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--color-border-light);
  background: transparent;
  color: var(--color-text-muted);
  font-size: var(--text-base);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 150ms ease;
}

.help-modal__close:hover { background: var(--color-surface-alt); }

/* ── Toasts ──────────────────────────────────────────────────────────── */

.undo-toast {
  position: fixed;
  bottom: var(--space-6);
  left: 50%;
  transform: translateX(-50%);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-4);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-text);
  box-shadow: var(--shadow-lg);
  z-index: 300;
  white-space: nowrap;
}

.undo-toast__btn {
  background: var(--app-primary);
  color: white;
  border: none;
  border-radius: var(--radius-md);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs);
  font-weight: 700;
  cursor: pointer;
  transition: background 150ms ease;
}

.undo-toast__btn:hover { background: var(--app-primary-hover); }

.stoop-toast {
  position: fixed;
  bottom: calc(var(--space-6) + 56px);
  right: var(--space-6);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  box-shadow: var(--shadow-lg);
  z-index: 300;
}

/* ── Toast transitions ───────────────────────────────────────────────── */

.toast-enter-active, .toast-leave-active  { transition: opacity 280ms ease, transform 280ms ease; }
.toast-enter-from,  .toast-leave-to       { opacity: 0; transform: translateY(8px) translateX(-50%); }
.stoop-toast.toast-enter-from,
.stoop-toast.toast-leave-to               { transform: translateY(8px); }

.overlay-enter-active, .overlay-leave-active { transition: opacity 200ms ease; }
.overlay-enter-from,   .overlay-leave-to     { opacity: 0; }

/* ── Spinner ─────────────────────────────────────────────────────────── */

.spinner {
  width: 1.2rem;
  height: 1.2rem;
  border: 2px solid var(--color-border);
  border-top-color: var(--app-primary);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

/* ── Screen reader only ──────────────────────────────────────────────── */

.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;
}

/* ── Responsive ──────────────────────────────────────────────────────── */

@media (max-width: 767px) {
  .review { padding: var(--space-4); gap: var(--space-4); }
  .review__title { font-size: var(--text-xl); }

  .review__tab {
    font-size: 0.65rem;
    padding: var(--space-2);
  }

  .hint-bar { display: none; }  /* mobile: no room — swipe speaks for itself */

  .review__actions { gap: var(--space-2); }
  .action-btn      { padding: var(--space-3) var(--space-4); font-size: var(--text-xs); }

  .undo-toast {
    left:  var(--space-4);
    right: var(--space-4);
    transform: none;
    bottom: calc(56px + env(safe-area-inset-bottom) + var(--space-4));
  }
  .toast-enter-from, .toast-leave-to { transform: translateY(8px); }
}
</style>
