/* Custom styles beyond Tailwind defaults */

/* Tab underline transition */
.tab-btn {
  transition: color 0.15s, border-color 0.15s;
}

/* Spinner for "AI 处理中..." */
@keyframes spin {
  to { transform: rotate(360deg); }
}
.spinner {
  display: inline-block;
  width: 12px;
  height: 12px;
  border: 2px solid #e5e7eb;
  border-top-color: #6366f1;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  vertical-align: middle;
}

/* Animated dots for "批改中" */
@keyframes pending-dots {
  0%   { content: ''; }
  25%  { content: '.'; }
  50%  { content: '..'; }
  75%  { content: '...'; }
  100% { content: ''; }
}
.pending-dots::after {
  content: '';
  animation: pending-dots 1.4s steps(4, end) infinite;
}

/* ===========================================================================
 * Mobile (≤ 768px) fixes for iPhone Safari
 * =========================================================================== */

/* Blocker 1: prevent iOS Safari from auto-zooming when an input/textarea
 * with font-size < 16px gains focus. !important overrides Tailwind's
 * text-sm/text-base classes. Desktop typography is unaffected. */
@media (max-width: 768px) {
  input, textarea, select {
    font-size: 16px !important;
  }
}

/* Blocker 2: tag cloud single-row horizontal scroll on phones.
 * Hide the scrollbar but keep scroll behavior. The pills get
 * `flex-shrink-0 whitespace-nowrap` via renderTagBar in app.js so
 * they don't collapse / wrap mid-text. */
@media (max-width: 768px) {
  .tag-cloud-scroll {
    scrollbar-width: none;          /* Firefox */
    -ms-overflow-style: none;       /* IE/Edge legacy */
    -webkit-overflow-scrolling: touch;
    scroll-behavior: smooth;
  }
  .tag-cloud-scroll::-webkit-scrollbar {
    display: none;                  /* WebKit (Safari + Chrome) */
  }
  /* Right-edge gradient mask. MUST anchor to the non-scrolling parent
   * (.tag-cloud-wrapper) — placing ::after on .tag-cloud-scroll itself
   * would make the gradient scroll with the content (it'd appear to be
   * "carried" by a specific pill as the user swipes). The wrapper's right
   * edge coincides with .tag-cloud-scroll's right edge because #tag-tabs
   * uses flex-1, so the absolute positioning works the same.
   *
   * pointer-events: none so taps still hit the underlying tag pills.
   * z-index 4: above pills, below menu button (z-index: 5). */
  .tag-cloud-wrapper {
    position: relative;
  }
  .tag-cloud-wrapper::after {
    content: '';
    position: absolute;
    top: 0;
    /* Right offset = menu-wrap width (34px) + flex gap-3 between #tag-tabs
     * and the menu (12px) = 46px. The gradient's white-end aligns with the
     * RIGHT edge of #tag-tabs — exactly where scrolling tag pills disappear.
     * The 12px gap + 34px menu cell are part of the white wrapper background,
     * so no pill can appear in that range. */
    right: 46px;
    bottom: 0;
    width: 60px;
    background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));
    pointer-events: none;
    z-index: 4;
  }
  /* Pin the [≡] menu button to the right edge of the scroll viewport
   * so it stays reachable on phones with many tags. The wider padding-left
   * + negative margin creates an invisible buffer zone, and the stronger
   * box-shadow fades tag pills to white before they reach the button. */
  /* (.tag-menu-sticky-wrap no longer needs special CSS — the menu button
   * now lives as a sibling of #tag-tabs in .tag-cloud-wrapper, occupying
   * its own flex slot at the right. No sticky / background / z-index
   * required. The class is retained as a stable selector + create-once
   * marker in renderTagBar.) */
}

/* Blocker 3: bottom clearance for iPhone Safari toolbar + home-indicator.
 * 80px covers the collapsed Safari URL bar; env(safe-area-inset-bottom)
 * adds the gesture-bar inset on notched devices. */
@media (max-width: 768px) {
  body {
    padding-bottom: calc(80px + env(safe-area-inset-bottom));
  }
}

/* Feedback floating action button: positioned via fixed in HTML; this rule
 * adds bottom/right offsets with safe-area inset support so the button
 * doesn't get clipped by the iPhone Safari toolbar/home indicator.
 * z-index 40 keeps it ABOVE page content but BELOW the z-50 modals (tag
 * manager, feedback modal), so opening a modal cleanly hides the FAB.
 *
 * The two-layer box-shadow is a Material Design "elevation 4" recipe —
 * one soft wide shadow for ambient depth, one tighter shadow under the
 * pill for the contact line. Together they read as "floating above the
 * page" instead of "flat sticker". */
#feedback-fab {
  bottom: calc(20px + env(safe-area-inset-bottom));
  right:  calc(20px + env(safe-area-inset-right));
  /* Stronger two-layer drop shadow so the button reads clearly as
   * "floating above the page" — the previous lighter shadow was too
   * subtle on white backgrounds. Outer layer for ambient depth, inner
   * layer for the contact line under the pill. */
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.28), 0 3px 6px rgba(0, 0, 0, 0.22);
}
#feedback-fab:hover {
  /* Hover lifts the button — bigger, softer shadow. */
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.32), 0 4px 8px rgba(0, 0, 0, 0.24);
}
#feedback-fab:active {
  /* Press pushes the button DOWN — tighter shadow gives a "pressed in"
   * tactile feel, paired with the Tailwind active:scale-95 transform. */
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.24), 0 1px 2px rgba(0, 0, 0, 0.20);
}
@media (max-width: 768px) {
  /* Bottom-right CORNER on phones — just above the iOS home-indicator /
   * gesture-bar (handled by safe-area-inset-bottom). The earlier 100px
   * value lifted the FAB visibly off the corner. 24px keeps it firmly
   * anchored to the corner; if the auto-hiding Safari toolbar slides up
   * over scroll, it covers the FAB momentarily — that's standard mobile
   * web behavior and resolves on next scroll. */
  #feedback-fab {
    bottom: calc(24px + env(safe-area-inset-bottom));
  }
}
