/**
 * ╔══════════════════════════════════════════════════════════════════════════════╗
 * ║  style.css — AlbumDrop Visual Design System                               ║
 * ╠══════════════════════════════════════════════════════════════════════════════╣
 * ║                                                                            ║
 * ║  An Apple-inspired design system with:                                    ║
 * ║    • CSS custom properties (variables) for consistent theming             ║
 * ║    • Automatic dark mode via prefers-color-scheme media query             ║
 * ║    • Responsive layout that adapts to mobile screens                      ║
 * ║    • Reduced motion support for accessibility                             ║
 * ║    • Smooth animations (fade in, spin, pulse)                             ║
 * ║                                                                            ║
 * ║  ── Section Overview ──────────────────────────────────────────────────    ║
 * ║                                                                            ║
 * ║    1. Reset & Base        — Box-sizing reset, typography, body styles     ║
 * ║    2. Layout              — Container, header, footer, app area           ║
 * ║    3. Legal Links         — Privacy Policy / Terms links in header        ║
 * ║    4. Card                — Main content card with shadow and radius      ║
 * ║    5. Buttons             — Primary, secondary, danger, Google styles     ║
 * ║    6. Drop Zone           — File drag-and-drop area (WELCOME screen)     ║
 * ║    7. Validation          — Checklist items with animated icons           ║
 * ║    8. Summary             — Stats grid, folder options, limitations       ║
 * ║    9. Upload Progress     — Progress bar, speed, current file display     ║
 * ║   10. Results             — Statistics rows, failed/album lists           ║
 * ║   11. Animations          — Keyframe definitions (fadeIn, spin, pulse)    ║
 * ║   12. Re-auth Banner      — Token expiry warning during upload            ║
 * ║   13. Modal Overlay       — Legal document modal (Privacy, Terms)         ║
 * ║   14. Responsive          — Mobile breakpoint adjustments (≤480px)        ║
 * ║   15. Accessibility       — Reduced motion, screen reader utilities       ║
 * ╚══════════════════════════════════════════════════════════════════════════════╝
 */


/* ═══════════════════════════════════════════════════════════════════════════════
   1. RESET & BASE
   Universal box-sizing, margin/padding reset, and root CSS custom properties.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Universal reset — ensures consistent sizing across all elements */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/*
 * CSS Custom Properties (Design Tokens)
 * These variables define the entire color scheme, spacing, and typography.
 * Changing these values updates the entire app's appearance.
 */
:root {
  /* ── Background colors ── */
  --bg: #f5f5f7;                    /* Page background (light grey, Apple-style) */
  --bg-card: #ffffff;               /* Card/panel background */

  /* ── Text colors (three levels of emphasis) ── */
  --text: #1d1d1f;                  /* Primary text (headings, important content) */
  --text-secondary: #6e6e73;        /* Secondary text (labels, descriptions) */
  --text-tertiary: #86868b;         /* Tertiary text (hints, footnotes) */

  /* ── Accent and semantic colors ── */
  --accent: #0071e3;                /* Primary brand color (Apple blue) */
  --accent-hover: #0077ed;          /* Accent color on hover (slightly brighter) */
  --success: #34c759;               /* Success green (iOS system green) */
  --success-bg: #e8f5e9;           /* Success background tint */
  --warning: #ff9f0a;               /* Warning amber (iOS system orange) */
  --warning-bg: #fff8e1;           /* Warning background tint */
  --error: #ff3b30;                 /* Error red (iOS system red) */
  --error-bg: #fce4ec;             /* Error background tint */

  /* ── Borders and shadows ── */
  --border: rgba(0, 0, 0, 0.06);   /* Subtle divider lines */
  --radius: 14px;                   /* Large border radius (cards, modals) */
  --radius-sm: 10px;                /* Small border radius (buttons, tags) */
  --shadow: 0 1px 4px rgba(0, 0, 0, 0.06);     /* Subtle card shadow */
  --shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.08); /* Elevated shadow (modals) */

  /* ── Typography ── */
  --font: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', system-ui, sans-serif;
  --font-mono: 'SF Mono', Menlo, Consolas, monospace;

  /* ── Animation ── */
  --transition: 0.2s ease;          /* Default transition duration and easing */
}

/*
 * Dark Mode Overrides
 * Automatically activates when the user's OS is in dark mode.
 * Only color-related variables are overridden; layout variables stay the same.
 */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000000;                  /* True black background (OLED-friendly) */
    --bg-card: #1c1c1e;            /* Dark card background (iOS dark mode grey) */
    --text: #f5f5f7;               /* Light text on dark background */
    --text-secondary: #a1a1a6;     /* Muted secondary text */
    --text-tertiary: #6e6e73;      /* Subtle tertiary text */
    --border: rgba(255, 255, 255, 0.08); /* Light borders on dark background */
    --shadow: 0 1px 4px rgba(0, 0, 0, 0.3);      /* Stronger shadow for depth */
    --shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.4);  /* Stronger elevated shadow */
    --success-bg: #1b3a1b;         /* Dark success tint */
    --warning-bg: #3a2e10;         /* Dark warning tint */
    --error-bg: #3a1515;           /* Dark error tint */
  }
}

/* Apply the background color to the root element */
html { background: var(--bg); }

/* Base body typography and smoothing */
body {
  font-family: var(--font);
  color: var(--text);
  line-height: 1.5;
  min-height: 100vh;                /* Ensure body fills the viewport */
  -webkit-font-smoothing: antialiased; /* Smoother font rendering on macOS */
}


/* ═══════════════════════════════════════════════════════════════════════════════
   2. LAYOUT
   Page-level container, header, main area, and footer.
   Uses flexbox column to push footer to the bottom.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Centered column container — constrains content to 640px max width */
.container {
  max-width: 640px;
  margin: 0 auto;
  padding: 2rem 1.5rem 3rem;
  min-height: 100vh;
  display: flex;
  flex-direction: column;          /* Vertical stacking: header → main → footer */
}

/* App header — centered text above the dynamic content area */
.app-header { text-align: center; margin-bottom: 2rem; }
.app-title {
  font-size: 1.5rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;                     /* Space between icon and "AlbumDrop" text */
}
.app-icon { flex-shrink: 0; border-radius: 6px; } /* App icon with blue gradient background */
.app-subtitle { color: var(--text); font-size: 1.3rem; font-weight: 700; margin-top: 0.3rem; letter-spacing: -0.015em; }


/* ═══════════════════════════════════════════════════════════════════════════════
   3. LEGAL LINKS
   Small Privacy Policy / Terms & Conditions links below the subtitle.
   Open modal overlays when clicked (handled by app.js).
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Help link — stands alone above the legal links for prominence */
.help-link-row {
  text-align: center;
  margin-top: 0.6rem;
}
a.help-link,
a.help-link:visited,
a.help-link:link {
  color: #34c759;
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 500;
  transition: color var(--transition);
}
a.help-link:hover { color: #2da44e; text-decoration: underline; }

.legal-links {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;                     /* Space between link, dot separator, link */
  margin-top: 0.35rem;
  font-size: 0.75rem;              /* Small, unobtrusive text */
}
.legal-link {
  color: var(--text-tertiary);     /* Subtle grey color */
  text-decoration: none;
  transition: color var(--transition);
}
.legal-link:hover { color: var(--accent); text-decoration: underline; }
.legal-sep { color: var(--text-tertiary); } /* "·" separator between links */


/* ═══════════════════════════════════════════════════════════════════════════════
   Main content area and footer
   ═══════════════════════════════════════════════════════════════════════════════ */

/* The <main id="app"> element fills available vertical space */
#app { flex: 1; }

/* Footer — privacy reassurance text with a top border separator */
.app-footer {
  text-align: center;
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}
.app-footer p {
  font-size: 0.8rem;
  color: var(--text-tertiary);
  max-width: 400px;
  margin: 0 auto;
}


/* ═══════════════════════════════════════════════════════════════════════════════
   4. CARD
   The primary content container used on every screen.
   White background with rounded corners, shadow, and fade-in animation.
   ═══════════════════════════════════════════════════════════════════════════════ */

.card {
  background: var(--bg-card);
  border-radius: var(--radius);    /* 14px rounded corners */
  padding: 2rem;
  box-shadow: var(--shadow);
  animation: fadeIn 0.3s ease;     /* Subtle slide-up fade on screen transitions */
}


/* ═══════════════════════════════════════════════════════════════════════════════
   5. BUTTONS
   Button system with variants: primary, secondary, danger, Google, full-width.
   Each variant has distinct background, text color, and hover states.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Base button styles shared by all variants */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;                     /* Space between icon and text */
  padding: 0.75rem 1.5rem;
  border-radius: var(--radius-sm); /* 10px rounded corners */
  font-size: 0.95rem;
  font-weight: 600;
  font-family: var(--font);
  cursor: pointer;
  border: none;
  transition: all var(--transition);
  text-decoration: none;
  line-height: 1.3;
}

/* Focus ring for keyboard navigation (accessibility) */
.btn:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

/* Primary button — solid blue background (main CTA) */
.btn-primary {
  background: var(--accent);
  color: #fff;
}
.btn-primary:hover { background: var(--accent-hover); }
.btn-primary:disabled { background: #999; cursor: not-allowed; opacity: 0.7; }

/* Secondary button — outlined with blue border (alternative action) */
.btn-secondary {
  background: transparent;
  color: var(--accent);
  border: 1.5px solid var(--accent);
}
.btn-secondary:hover { background: rgba(0, 113, 227, 0.06); }

/* Danger button — outlined with red border (destructive action like cancel) */
.btn-danger {
  background: transparent;
  color: var(--error);
  border: 1.5px solid var(--error);
}
.btn-danger:hover { background: rgba(255, 59, 48, 0.06); }

/* Full-width modifier — stretches button to fill its container */
.btn-full { width: 100%; }

/* Google sign-in button — white/grey background matching Google's brand guidelines */
.btn-google {
  background: #fff;
  color: #3c4043;
  border: 1px solid #dadce0;
  font-weight: 500;
}
.btn-google:hover { background: #f7f8f8; box-shadow: 0 1px 3px rgba(0,0,0,0.12); }

/* Dark mode overrides for the Google button */
@media (prefers-color-scheme: dark) {
  .btn-google { background: #2c2c2e; color: #f5f5f7; border-color: #444; }
  .btn-google:hover { background: #3a3a3c; }
}


/* ═══════════════════════════════════════════════════════════════════════════════
   6. WELCOME-SCREEN HERO BUTTONS + DROP ZONE
   Two big gold-gradient cards side-by-side mirror the Swift app's
   HomeView.  Left card = Read from Google Photos, right card =
   Write to Google Photos.  The Write card doubles as the
   .albumdrop drop zone (drag a file or click for the native
   picker).  On narrow viewports the cards stack.
   ═══════════════════════════════════════════════════════════════════════════════ */

.hero-buttons {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  margin-bottom: 24px;
}
@media (max-width: 720px) {
  .hero-buttons { grid-template-columns: 1fr; }
}

.hero-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 28px 26px;
  border-radius: 16px;
  cursor: pointer;
  position: relative;
  border: 2px solid transparent;
  color: #fff;
  min-height: 220px;
  transition: transform 120ms ease, box-shadow 120ms ease, border-color 120ms ease;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
  /* Same darker-gold gradient on both cards.  Originally Read had
     a lighter gradient than Write but the user reported the
     lighter version made white text low-contrast in dark mode
     (2026-04-25), and there's no real reason to colour-code the
     two directions differently — they're a matched pair. */
  background: linear-gradient(180deg, #B89E2E 0%, #99801E 100%);
}
.hero-card:hover,
.hero-card:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.24);
  border-color: rgba(255, 255, 255, 0.35);
  outline: none;
}

/* Top icon — "Google →" or "→ Google" rendered as large text
   matching Swift HomeView's `ActionCardView` icon @ViewBuilder
   sized at 48pt.  The arrow uses the same big size so the
   direction of data flow reads instantly. */
.hero-card-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-size: 2.4rem;
  font-weight: 600;
  line-height: 1;
  color: #fff;
  margin-bottom: 18px;
}
.hero-card-icon-word { letter-spacing: -0.01em; }
.hero-card-arrow {
  font-size: 2.6rem;
  font-weight: 500;
  line-height: 1;
}
.hero-card-title {
  margin: 0 0 10px 0;
  font-size: 1.3rem;
  font-weight: 700;
  color: #fff;
  line-height: 1.25;
}
.hero-card-subtitle {
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.95);
}
.hero-card-subtitle code {
  background: rgba(0, 0, 0, 0.22);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 0.85em;
}

/* The Write card also functions as a drop zone — use a 2px solid
   border in the dragging state for clear feedback (no need for
   the dashed look the old single-zone used).  The card already
   has a transparent 2px border in its base state to keep
   geometry stable. */
.hero-card.drag-over {
  border-color: #fff;
  transform: scale(1.01);
}

/* Hide the native file input — the whole Write card is already a
   click-target (setupWelcome wires `card.click → input.click`), so
   the native "Choose File" button would just be visual noise.
   Drag-and-drop and keyboard activation also flow through the card
   handlers, not the input itself. */
.hero-card.drop-zone input[type="file"] { display: none; }

/* Error message area within the Write card (wrong file type, etc.). */
.drop-zone-error {
  margin-top: 12px;
  padding: 8px 12px;
  background: rgba(0, 0, 0, 0.25);
  color: #fff;
  border-radius: 8px;
  font-size: 0.85rem;
  display: none;
}
.drop-zone-error.visible { display: block; }

/* Back-compat selectors for the few tests / external pages that
   still reference the old `.drop-zone-*` class names. */
.drop-zone { /* applied alongside .hero-card on the Write card */ }


/* ═══════════════════════════════════════════════════════════════════════════════
   6b. APP STORE PROMO SECTION
   Promotional section below the drop zone on the WELCOME screen.
   Encourages users to download the AlbumDrop native app for Apple platforms.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Container — sits below the drop zone card with top margin */
.promo-section {
  margin-top: 2rem;
  text-align: center;
  padding: 0 0.5rem;
}

/* Decorative icon above the promo text */
.promo-icon {
  color: var(--text-tertiary);
  margin-bottom: 0.5rem;
}

/* "Get the AlbumDrop App" heading */
.promo-title {
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

/* Descriptive blurb about what the app does */
.promo-blurb {
  font-size: 0.82rem;
  color: var(--text-secondary);
  line-height: 1.6;
  max-width: 440px;
  margin: 0 auto 1.25rem;
}

/* Container for the two store badges — side by side */
.promo-badges {
  display: flex;
  justify-content: center;
  gap: 0.75rem;
  flex-wrap: wrap;                 /* Stack vertically on very narrow screens */
}

/*
 * App Store badge button — styled to resemble Apple's official badges.
 * Dark background with white text, rounded corners, Apple logo icon.
 */
.store-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 1rem 0.55rem 0.75rem;
  background: #000;
  color: #fff;
  border-radius: 8px;
  text-decoration: none;
  transition: opacity var(--transition);
  border: 1px solid rgba(255, 255, 255, 0.15);
}
.store-badge:hover { opacity: 0.85; }

/* Apple logo icon within the badge */
.store-badge-icon {
  flex-shrink: 0;
  color: #fff;
}

/* Text stack within the badge (two lines) */
.store-badge-text {
  display: flex;
  flex-direction: column;
  text-align: left;
  line-height: 1.1;
}
/* "Download on the" — small top line */
.store-badge-small {
  font-size: 0.55rem;
  font-weight: 400;
  letter-spacing: 0.01em;
  opacity: 0.9;
}
/* "App Store" / "Mac App Store" — larger bottom line */
.store-badge-large {
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* Dark mode — invert badge to light background */
@media (prefers-color-scheme: dark) {
  .store-badge {
    background: #fff;
    color: #000;
    border-color: rgba(0, 0, 0, 0.1);
  }
  .store-badge-icon { color: #000; }
}


/* ═══════════════════════════════════════════════════════════════════════════════
   7. VALIDATION CHECKLIST
   The 7-step validation checklist on the VALIDATING screen.
   Each item transitions through visual states: pending → running → pass/fail/warn.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Title above the checklist */
.validation-title { font-size: 1.15rem; font-weight: 600; margin-bottom: 1.25rem; }

/* Remove default list styling (no bullets) */
.check-list { list-style: none; }

/* Individual checklist item — icon + label in a row with a bottom border */
.check-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0;
  font-size: 0.9rem;
  color: var(--text-secondary);    /* Default: grey text (pending state) */
  border-bottom: 1px solid var(--border);
}
.check-item:last-child { border-bottom: none; } /* No border on the last item */

/* State-specific text colors */
.check-item.active { color: var(--text); }       /* Currently running — dark text */
.check-item.passed { color: var(--success); }    /* Passed — green text */
.check-item.failed { color: var(--error); }      /* Failed — red text */

/* Icon container — fixed width to align all labels consistently */
.check-icon {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Spinning animation for the "running" state icon */
.check-icon .spinner {
  width: 18px;
  height: 18px;
  border: 2px solid var(--border);
  border-top-color: var(--accent); /* Blue top segment creates the spinning effect */
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}

/* SVG icon color overrides for pass/fail states */
.check-icon .checkmark { color: var(--success); } /* Green checkmark */
.check-icon .xmark { color: var(--error); }       /* Red X mark */

/* Error message box (shown below checklist on validation failure) */
.validation-error {
  margin-top: 1.25rem;
  padding: 0.75rem 1rem;
  background: var(--error-bg);
  color: var(--error);
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
  line-height: 1.5;
}


/* ═══════════════════════════════════════════════════════════════════════════════
   8. SUMMARY SCREEN
   File statistics grid, folder handling options, and important notes.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Metadata line (e.g. "From Brian's iPhone · Feb 24, 2026") */
.summary-meta {
  font-size: 0.85rem;
  color: var(--text-secondary);
  margin-bottom: 1.5rem;
}

/* Stats grid — 2×2 grid of stat cards (photos, videos, albums, size) */
.stats-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;  /* Two equal columns */
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}
.stat-card {
  background: var(--bg);           /* Slightly different from card background */
  border-radius: var(--radius-sm);
  padding: 1rem;
  text-align: center;
}
.stat-value { font-size: 1.5rem; font-weight: 700; }           /* Big number */
.stat-label { font-size: 0.8rem; color: var(--text-secondary); margin-top: 0.15rem; } /* Label below */

/* Horizontal divider between stats and folder options */
.section-divider {
  border: none;
  border-top: 1px solid var(--border);
  margin: 1.5rem 0;
}

/* Folder handling section (radio buttons for prepend/ignore) */
.folder-section h3 { font-size: 1.05rem; font-weight: 600; margin-bottom: 0.75rem; }
.radio-group { display: flex; flex-direction: column; gap: 0.75rem; }
.radio-option {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  cursor: pointer;
  font-size: 1rem;
  padding: 0.5rem 0.6rem;
  border-radius: var(--radius-sm);
  transition: background var(--transition);
}
.radio-option:hover { background: rgba(0, 0, 0, 0.03); }
@media (prefers-color-scheme: dark) {
  .radio-option:hover { background: rgba(255, 255, 255, 0.04); }
}
.radio-option input[type="radio"] {
  margin-top: 0.25rem;
  width: 18px;
  height: 18px;
  accent-color: var(--accent);     /* Blue radio button color */
}
/* Monospace example text below each radio option */
.radio-example {
  display: block;
  font-size: 0.85rem;
  color: var(--text-tertiary);
  font-family: var(--font-mono);
  margin-top: 0.25rem;
}

/* "Important notes" section — prominent warning box on the SUMMARY screen */
.important-notes {
  margin-top: 1.25rem;
  padding: 1rem 1.15rem;
  background: var(--warning-bg);
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
  color: var(--text);
  line-height: 1.6;
}
.important-notes h3 {
  color: var(--text);
  font-weight: 600;
  font-size: 0.9rem;
  margin-bottom: 0.6rem;
}
.important-notes ul {
  padding-left: 1.1rem;
  list-style: disc;
}
.important-notes li {
  margin-bottom: 0.35rem;
}
.important-notes li:last-child {
  margin-bottom: 0;
}

/* Action buttons container (Sign in + Choose Different File) */
.summary-actions { margin-top: 1.5rem; }


/* ═══════════════════════════════════════════════════════════════════════════════
   9. UPLOAD PROGRESS
   Progress bar, speed/ETA display, current file indicator, and warning banner.
   All elements are updated via direct DOM manipulation (not re-rendering).
   ═══════════════════════════════════════════════════════════════════════════════ */

/* "Uploading to Google Photos" title */
.upload-title { font-size: 1.15rem; font-weight: 600; margin-bottom: 0.25rem; }

/* Phase label (e.g. "Uploading… 12 of 156 files") */
.upload-phase {
  font-size: 0.8rem;
  color: var(--text-secondary);
  margin-bottom: 1.25rem;
  font-weight: 500;
}

/* Progress bar container — grey rounded track */
.progress-bar-container {
  background: var(--bg);
  border-radius: 6px;
  height: 10px;
  overflow: hidden;
  margin-bottom: 0.75rem;
}
/* Progress bar fill — blue bar that grows from left to right */
.progress-bar-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 6px;
  transition: width 0.3s ease;     /* Smooth width animation on each update */
  min-width: 0;
}

/* Progress bar legend (Upload / Verify colour key) */
.progress-legend {
  display: flex;
  justify-content: center;
  gap: 1.25rem;
  font-size: 0.7rem;
  color: var(--text-tertiary);
  margin-bottom: 0.75rem;
}
.legend-item {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}
.legend-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 3px;
}
.legend-upload { background: var(--accent); }              /* Blue — upload phase */
.legend-verify { background: #34C759; }                    /* Green — verify phase */

/* Advisory note below the current-file indicator */
.upload-advisory {
  font-size: 0.8rem;
  color: var(--text);
  line-height: 1.5;
  margin-bottom: 0.75rem;
  padding: 0.75rem 1rem 0.75rem 1.15rem;
  background: var(--warning-bg);
  border-radius: var(--radius-sm);
}
.upload-advisory ul {
  padding-left: 1.1rem;
  list-style: disc;
}
.upload-advisory li {
  margin-bottom: 0.3rem;
}
.upload-advisory li:last-child {
  margin-bottom: 0;
}

/* Stats line below progress bar (percentage on left, speed/ETA on right) */
.progress-stats {
  display: flex;
  justify-content: space-between;
  font-size: 0.8rem;
  color: var(--text-secondary);
  margin-bottom: 1.25rem;
}

/* Current file name display — shows which file is being uploaded */
.current-file {
  font-size: 0.85rem;
  color: var(--text);
  padding: 0.75rem 1rem;
  background: var(--bg);
  border-radius: var(--radius-sm);
  margin-bottom: 0.75rem;
  word-break: break-all;           /* Break long filenames without spaces */
  min-height: 2.5rem;
  display: flex;
  align-items: center;
}

/* Warning banner (shown for missing files, etc.) */
.upload-warning {
  padding: 0.6rem 0.85rem;
  background: var(--warning-bg);
  color: var(--warning);
  border-radius: var(--radius-sm);
  font-size: 0.8rem;
  margin-bottom: 0.75rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
/* Optional spinner variant for the warning banner */
.upload-warning .spinner {
  width: 14px;
  height: 14px;
  border: 2px solid rgba(255, 159, 10, 0.3);
  border-top-color: var(--warning);
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
  flex-shrink: 0;
}

/* Cancel button container — centered below the progress area */
.upload-actions {
  margin-top: 1.25rem;
  display: flex;
  justify-content: center;
}


/* ═══════════════════════════════════════════════════════════════════════════════
   10. RESULTS SCREEN (COMPLETE)
   Upload results display with statistics rows, failed/album lists.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Large emoji icon at the top (✅, ⚠️, or 🚫) */
.results-icon {
  text-align: center;
  font-size: 3rem;
  margin-bottom: 0.75rem;
}

/* Result title (e.g. "Import to Google Photos Complete") */
.results-title {
  text-align: center;
  font-size: 1.2rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

/* Subtitle below title (e.g. "156 files uploaded successfully.") */
.results-subtitle {
  text-align: center;
  font-size: 0.9rem;
  color: var(--text-secondary);
  margin-bottom: 1.5rem;
}

/* Statistics rows container */
.results-stats {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}

/* Individual stat row (label on left, value on right) */
.result-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.5rem 0;
  font-size: 0.9rem;
  border-bottom: 1px solid var(--border);
}
.result-row:last-child { border-bottom: none; }
.result-value { font-weight: 600; }
.result-value.success { color: var(--success); } /* Green for successful counts */
.result-value.error { color: var(--error); }     /* Red for failed counts */

/* Expandable section for failed files (click "X failed file(s)" to expand) */
.failed-details {
  margin-top: 1rem;
}
.failed-details summary {
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--error);
  font-weight: 500;
  padding: 0.5rem 0;
}
.failed-list {
  list-style: none;
  margin-top: 0.5rem;
}
.failed-item {
  font-size: 0.8rem;
  padding: 0.4rem 0;
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border);
}
.failed-item:last-child { border-bottom: none; }

/* Expandable section for verification details (albums with pending items) */
.verify-details {
  margin-top: 1rem;
}
.verify-details summary {
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--warning, #f0a030);
  font-weight: 500;
  padding: 0.5rem 0;
}
.verify-note {
  font-size: 0.75rem;
  color: var(--text-secondary);
  margin: 0.25rem 0 0.5rem;
  font-style: italic;
}
.verify-list {
  list-style: none;
  margin-top: 0.5rem;
}
.verify-list li {
  font-size: 0.8rem;
  padding: 0.35rem 0;
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border);
}
.verify-list li:last-child { border-bottom: none; }

/* Expandable section for created albums (click "X album(s) created" to expand) */
.results-albums {
  margin-top: 1rem;
}
.results-albums summary {
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--text-secondary);
  font-weight: 500;
  padding: 0.5rem 0;
}
.album-list {
  list-style: none;
  margin-top: 0.5rem;
}
.album-list li {
  font-size: 0.8rem;
  padding: 0.35rem 0;
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border);
}
.album-list li:last-child { border-bottom: none; }

/* Action buttons (Open Google Photos + Import Another File) */
.results-actions {
  margin-top: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}


/* ═══════════════════════════════════════════════════════════════════════════════
   11. ANIMATIONS
   Keyframe definitions for reusable animations.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Fade-in with subtle upward slide — used for screen transitions */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Continuous rotation — used for spinner icons */
@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Pulsing opacity — available for loading states (currently unused) */
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}


/* ═══════════════════════════════════════════════════════════════════════════════
   12. RE-AUTH BANNER
   Warning banner shown when the OAuth token expires during an active upload.
   Contains a message and "Re-authenticate with Google" button.
   ═══════════════════════════════════════════════════════════════════════════════ */

.reauth-banner {
  padding: 1.15rem 1.25rem;
  background: var(--error-bg);
  border: 2px solid var(--error);
  border-radius: var(--radius-sm);
  text-align: center;
  margin-bottom: 1rem;
  animation: fadeIn 0.3s ease;     /* Fades in when token expires */
}
.reauth-banner p {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 0.75rem;
}


/* ═══════════════════════════════════════════════════════════════════════════════
   13. MODAL OVERLAY
   Full-screen modal for displaying legal documents (Privacy Policy, Terms).
   Consists of a semi-transparent backdrop, a centered card, and scrollable body.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Full-screen semi-transparent backdrop */
.modal-overlay {
  position: fixed;
  inset: 0;                        /* Shorthand for top/right/bottom/left: 0 */
  background: rgba(0, 0, 0, 0.5); /* 50% black overlay */
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;                   /* Above all other content */
  padding: 1.5rem;
  animation: fadeIn 0.2s ease;
}

/* Modal card — the white/dark panel containing the content */
.modal-card {
  background: var(--bg-card);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  max-width: 600px;
  width: 100%;
  max-height: 80vh;                /* Limit height to 80% of viewport */
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Modal header — title and close button in a row */
.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.25rem 1.5rem;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;                  /* Don't shrink when body scrolls */
}
.modal-header h2 {
  font-size: 1.1rem;
  font-weight: 600;
}

/* Close button (×) — minimal styling for an unstyled button */
.modal-close {
  background: none;
  border: none;
  font-size: 1.5rem;
  cursor: pointer;
  color: var(--text-secondary);
  padding: 0.25rem;
  line-height: 1;
  transition: color var(--transition);
}
.modal-close:hover { color: var(--text); }

/* Modal body — scrollable content area for the legal document */
.modal-body {
  padding: 1.5rem;
  overflow-y: auto;                /* Scrollbar for long documents */
  font-size: 0.9rem;
  line-height: 1.7;
  color: var(--text-secondary);
}
/* Paragraph spacing within the legal document */
.modal-body p { margin-bottom: 1rem; }
.modal-body p:last-child { margin-bottom: 0; }
/* Subheading styles */
.modal-body h3 { color: var(--text); margin: 1.25rem 0 0.5rem; font-size: 0.95rem; }
/* List styles */
.modal-body ul { padding-left: 1.25rem; margin-bottom: 1rem; }
.modal-body li { margin-bottom: 0.35rem; }

/* Loading/error placeholder text (centered) */
.modal-placeholder {
  text-align: center;
  padding: 2rem 1rem;
  color: var(--text-tertiary);
}


/* ═══════════════════════════════════════════════════════════════════════════════
   14a. HELP MODAL
   Extends the base modal with help-specific styles: search bar, TOC,
   section/subsection headings, and search highlighting.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* Search input at the top of the help modal */
.help-search {
  width: 100%;
  padding: 0.6rem 0.9rem;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  outline: none;
  transition: border-color var(--transition);
  margin-bottom: 1rem;
  box-sizing: border-box;
}
.help-search:focus { border-color: var(--accent); }
.help-search::placeholder { color: var(--text-tertiary); }

/* Table of contents */
.help-toc { margin-bottom: 1.25rem; }
.help-toc-title {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 0.6rem;
}

/* Group wrapper — adds spacing between major section blocks */
.help-toc-group {
  margin-bottom: 0.35rem;
}

/* Major section TOC link */
.help-toc-section {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--accent);
  text-decoration: none;
  padding: 0.3rem 0;
  cursor: pointer;
}
.help-toc-section:hover { text-decoration: underline; }

/* Subsection TOC link — indented and slightly smaller */
.help-toc-sub {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-left: 1.1rem;
  font-size: 0.84rem;
  color: var(--accent);
  text-decoration: none;
  padding-top: 0.15rem;
  padding-bottom: 0.15rem;
  cursor: pointer;
}
.help-toc-sub:hover { text-decoration: underline; }

/* Chevron indicator on TOC links */
.help-toc-chevron {
  color: var(--text-tertiary);
  font-size: 0.85rem;
  margin-left: 0.5rem;
  flex-shrink: 0;
}

/* Section headings */
.help-section-title {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--text);
  margin: 1.5rem 0 0.5rem;
  padding-top: 0.5rem;
}
.help-section-title:first-child { margin-top: 0; }

/* Subsection headings */
.help-subsection-title {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
  margin: 1rem 0 0.35rem;
}

/* Body paragraphs in help */
.help-body {
  font-size: 0.9rem;
  line-height: 1.7;
  color: var(--text-secondary);
  margin-bottom: 0.75rem;
}
.help-body:last-child { margin-bottom: 0; }

/* Section divider */
.help-divider {
  border: none;
  border-top: 1px solid var(--border);
  margin: 1.25rem 0;
}

/* Search match highlight */
.help-highlight {
  background: rgba(255, 204, 0, 0.35);
  color: var(--text);
  border-radius: 2px;
  padding: 0 1px;
}

/* Search result count */
.help-result-count {
  font-size: 0.82rem;
  color: var(--text-tertiary);
  margin-bottom: 0.75rem;
}

/* No results */
.help-no-results {
  text-align: center;
  padding: 2rem 1rem;
  color: var(--text-tertiary);
  font-size: 0.9rem;
}

/* Context note */
.help-context-note {
  font-size: 0.85rem;
  color: var(--text-tertiary);
  font-style: italic;
  margin-bottom: 1rem;
  padding: 0.75rem;
  background: var(--bg);
  border-radius: var(--radius-sm);
}


/* ═══════════════════════════════════════════════════════════════════════════════
   14. RESPONSIVE BREAKPOINTS
   Adjustments for mobile screens (≤480px viewport width).
   Reduces padding, font sizes, and simplifies layouts.
   ═══════════════════════════════════════════════════════════════════════════════ */

@media (max-width: 480px) {
  .container { padding: 1.5rem 1rem 2rem; }        /* Reduce side padding */
  .card { padding: 1.5rem; }                        /* Tighter card padding */
  .hero-card { padding: 22px 18px; min-height: 200px; } /* Tighter hero cards on narrow */
  .stats-grid { grid-template-columns: 1fr 1fr; gap: 0.5rem; } /* Tighter grid */
  .stat-card { padding: 0.75rem; }                  /* Smaller stat cards */
  .stat-value { font-size: 1.25rem; }               /* Slightly smaller numbers */
  .progress-stats { flex-direction: column; gap: 0.25rem; } /* Stack speed/ETA */
  .promo-badges { flex-direction: column; align-items: center; } /* Stack badges */
  .store-badge { width: 100%; max-width: 200px; justify-content: center; }
}


/* ═══════════════════════════════════════════════════════════════════════════════
   15. ACCESSIBILITY
   Reduced motion support and screen reader utilities.
   ═══════════════════════════════════════════════════════════════════════════════ */

/*
 * Reduced Motion
 * When the user has "prefers-reduced-motion" enabled in their OS settings,
 * all animations and transitions are effectively disabled. This prevents
 * motion-sensitive users from experiencing discomfort.
 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;     /* Near-zero, not zero (avoids bugs) */
    transition-duration: 0.01ms !important;
  }
}

/*
 * Screen Reader Only
 * Visually hides an element while keeping it accessible to screen readers.
 * Used for adding descriptive text that sighted users don't need to see
 * but screen reader users benefit from.
 */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}


/* ═══════════════════════════════════════════════════════════════════════════
   Read-from-Google-Photos — Home-screen card + the full picker-driven screen.
   Ported from the Swift app's gold "Read from Google Photos" card layout; kept
   visually distinct from the primary blue Write-to-Google flow so users don't
   confuse direction.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Home-screen entry point ──────────────────────────────────────────── */
.rfg-home-card {
  display: flex;
  align-items: center;
  gap: 14px;
  background: linear-gradient(180deg, #FFF6E0 0%, #FFEFC7 100%);
  border: 1px solid #F0C966;
  border-radius: 14px;
  padding: 14px 16px;
  margin-top: 14px;
  cursor: pointer;
  transition: transform 0.08s ease, box-shadow 0.15s ease;
}
.rfg-home-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(240, 160, 20, 0.20);
}
.rfg-home-card:focus-visible {
  outline: 2px solid #F59E0B;
  outline-offset: 2px;
}
.rfg-home-icon { flex: 0 0 auto; }
.rfg-home-text { flex: 1 1 auto; }
.rfg-home-title {
  margin: 0 0 4px 0;
  font-size: 1rem;
  font-weight: 600;
  color: #78350F;
}
.rfg-home-blurb {
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.35;
  color: #6b5b2f;
}
.rfg-home-chevron {
  flex: 0 0 auto;
  font-size: 1.3rem;
  color: #92400E;
}
@media (prefers-color-scheme: dark) {
  .rfg-home-card {
    background: linear-gradient(180deg, #3B2C0E 0%, #2A1F07 100%);
    border-color: #8B6A1C;
  }
  .rfg-home-title  { color: #FBDF9E; }
  .rfg-home-blurb  { color: #E8CE92; }
  .rfg-home-chevron { color: #FBDF9E; }
}

/* ── The Read-from-Google screen itself ───────────────────────────────── */
.rfg-card { padding: 24px 20px; }
.rfg-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.rfg-title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
}
.btn-link {
  background: transparent;
  border: none;
  color: #286EF0;
  cursor: pointer;
  font-size: 0.9rem;
  padding: 4px 8px;
}
.btn-link:hover { text-decoration: underline; }

/* Warning banners.  Two banners stack at the top of the screen —
   one for album/selection limitations, one for download
   limitations.  Each banner has its own bold title at the top
   (the `.rfg-warning-title` class) so the limitation it describes
   is unambiguous even before reading the bullets. */
.rfg-warning {
  background: #FEF3C7;
  border: 1px solid #F0C966;
  border-radius: 10px;
  padding: 12px 14px;
  margin-bottom: 14px;
  font-size: 0.85rem;
  line-height: 1.4;
  color: #5A3F06;
}
.rfg-warning + .rfg-warning { margin-top: 0; }
.rfg-warning + .rfg-section { margin-top: 18px; }
.rfg-warning-title {
  display: block;
  margin: 0 0 6px 0 !important;
  font-size: 0.95rem;
  font-weight: 700;
}
.rfg-warning strong { display: block; margin-top: 6px; }
.rfg-warning ul { margin: 4px 0 8px 18px; padding: 0; }
.rfg-warning li { margin: 2px 0; }
@media (prefers-color-scheme: dark) {
  .rfg-warning { background: #3B2C0E; border-color: #8B6A1C; color: #F0D89A; }
}

/* Form-section cards.  The Read-from-Google screen has three:
   "Album being captured", "Folder path for albums", and "Draft of
   albumdrop file (N)".  All three share the `.rfg-section` class
   so they read as visually distinct cards in both light and dark
   mode.
   ── Why <section> + <h3> instead of <fieldset> + <legend> ──
   The fieldset/legend pattern renders the title bisecting the
   border (legend "punches through" the top edge by browser
   default).  Users reported this read as "half in / half out"
   on 2026-04-25.  Switched to a plain <section> with a styled
   <h3.rfg-section-title> sitting cleanly inside the box —
   semantically correct heading, full visual control. */
.rfg-section {
  border: 1px solid var(--border, #c8c8d0);
  border-radius: 12px;
  padding: 16px 18px;
  margin-bottom: 16px;
  background: rgba(0, 0, 0, 0.06);
}
.rfg-section-title {
  margin: 0 0 12px 0;
  font-weight: 700;
  font-size: 1rem;
  color: var(--text, #111);
  line-height: 1.3;
}
@media (prefers-color-scheme: dark) {
  .rfg-section {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.22);
  }
  .rfg-section-title {
    color: var(--text, #f5f5f7);
  }
}
/* Back-compat for callers still using .rfg-capture / .rfg-draft —
   they get the same prominent treatment. */
.rfg-capture, .rfg-draft {
  border: 1px solid var(--border, #c8c8d0);
  border-radius: 12px;
  padding: 16px 18px;
  margin-bottom: 16px;
}

/* Folder-path section header — depth note on the left, optional
   Delete-all link, then the N/5 counter on the right. */
.rfg-folder-header {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 10px;
  font-size: 0.85rem;
}
.rfg-folder-note {
  color: var(--text-secondary, #6e6e73);
  flex: 1 1 auto;
}
.rfg-folder-counter {
  color: var(--text-secondary, #6e6e73);
  font-variant-numeric: tabular-nums;
  font-size: 0.8rem;
}

/* Subtle text-only destructive button used for the Delete-all
   link in the folder-path header.  Keeps the visual weight low
   (it's a recovery action, not the primary thing to do) but the
   red colour makes it unmistakable when present. */
.btn-link-destructive {
  background: transparent;
  border: none;
  color: #B91C1C;
  cursor: pointer;
  font-size: 0.8rem;
  padding: 2px 4px;
  font-family: inherit;
}
.btn-link-destructive:hover { text-decoration: underline; }
@media (prefers-color-scheme: dark) {
  .btn-link-destructive { color: #FCA5A5; }
}

/* "Browse Google Photos albums" call-to-action — opens the user's
   regular browser at photos.google.com/albums so they can find
   album names that the Picker API doesn't expose.  Bordered-blue
   so it reads as a real button (the prior plain-text version
   blended into the form labels). */
.btn-browse-google {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: #286EF0;
  color: #fff;
  border: 1px solid #1d57c4;
  border-radius: 8px;
  padding: 8px 14px;
  font-size: 0.9rem;
  font-weight: 500;
  text-decoration: none;
  margin: 8px 0 12px 0;
  transition: background-color 120ms ease;
}
.btn-browse-google:hover {
  background: #1d57c4;
  text-decoration: none;
}
.rfg-browse-btn { display: inline-flex; }

/* Form bits. */
.rfg-label {
  display: block;
  margin-bottom: 12px;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-secondary, #6e6e73);
}
.rfg-label input {
  display: block;
  width: 100%;
  margin-top: 4px;
  padding: 8px 10px;
  border: 1px solid var(--border, #e5e5ea);
  border-radius: 8px;
  font-size: 0.95rem;
  font-family: inherit;
}
.rfg-label-static {
  display: block;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-secondary, #6e6e73);
  margin-bottom: 4px;
}
.rfg-folder-row { margin-bottom: 12px; }
.rfg-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  min-height: 32px;
  padding: 6px 0;
}
.rfg-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px;
  background: #EFF6FF;
  border: 1px solid #BFDBFE;
  border-radius: 12px;
  font-size: 0.82rem;
  color: #1E3A8A;
}
.rfg-chip-remove {
  background: transparent;
  border: none;
  color: #1E3A8A;
  cursor: pointer;
  padding: 0 4px;
  font-size: 1rem;
  line-height: 1;
}
.rfg-chip-sep { color: var(--text-secondary, #6e6e73); }
.rfg-chips-empty {
  font-size: 0.82rem;
  color: var(--text-secondary, #6e6e73);
  font-style: italic;
}
.rfg-folder-add {
  display: flex;
  gap: 6px;
  margin-top: 4px;
}
.rfg-folder-add input {
  flex: 1 1 auto;
  padding: 6px 8px;
  border: 1px solid var(--border, #e5e5ea);
  border-radius: 8px;
  font-size: 0.85rem;
  font-family: inherit;
}
.btn-small {
  padding: 4px 12px;
  border: 1px solid var(--border, #e5e5ea);
  background: #F3F4F6;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.9rem;
}

/* Buttons. */
.btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px 18px;
  background: #F59E0B;
  color: white;
  border: none;
  border-radius: 10px;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
}
.btn-primary:hover:not(:disabled) { background: #D97706; }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-secondary {
  padding: 8px 14px;
  background: #F3F4F6;
  border: 1px solid var(--border, #e5e5ea);
  border-radius: 10px;
  font-size: 0.9rem;
  cursor: pointer;
}
.btn-secondary:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-destructive {
  padding: 8px 14px;
  background: transparent;
  color: #B91C1C;
  border: 1px solid #FECACA;
  border-radius: 10px;
  font-size: 0.9rem;
  cursor: pointer;
}
.btn-destructive:disabled { opacity: 0.5; cursor: not-allowed; }

.rfg-pick-btn { flex: 1 1 auto; margin: 8px 0; }
/* Pick + Cancel row — Cancel button appears only while isPicking=true
   (render-time conditional in read-from-google-view.js).  We lay them
   out with flexbox so the Pick button grows to fill the row and
   Cancel hugs its content. */
.rfg-pick-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
}
.rfg-pick-row > #rfg-pick-cancel {
  flex: 0 0 auto;
  margin: 8px 0;
}
.rfg-status {
  font-size: 0.85rem;
  min-height: 1.3em;
  color: var(--text-secondary, #6e6e73);
  margin-top: 6px;
  /* `white-space: pre-line` so multi-line error hints (the
     "Couldn't add photos" recovery bullets) render the literal
     `\n` characters as real line breaks without forcing us to
     emit <br> tags from JS. */
  white-space: pre-line;
  line-height: 1.4;
}
.rfg-status-ok  { color: #047857; }
.rfg-status-err { color: #B91C1C; }
.rfg-status-warn { color: #A16207; }

/* Pending-batch block (inside the capture fieldset). */
.rfg-pending {
  margin-top: 12px;
  padding: 10px 12px;
  background: #F9FAFB;
  border: 1px dashed #D1D5DB;
  border-radius: 8px;
}
.rfg-pending h4 {
  margin: 0 0 4px 0;
  font-size: 0.9rem;
  font-weight: 600;
}
.rfg-pending-stats {
  margin: 0 0 8px 0;
  font-size: 0.82rem;
  color: var(--text-secondary, #6e6e73);
}
.rfg-pending-list {
  margin: 0 0 6px 0;
  padding-left: 18px;
  font-size: 0.82rem;
  color: var(--text-primary);
  max-height: 120px;
  overflow-y: auto;
}
.rfg-pending-more {
  margin: 0 0 6px 0;
  font-size: 0.8rem;
  font-style: italic;
  color: var(--text-secondary, #6e6e73);
}
.rfg-pending-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 8px;
}

/* Draft (committed albums) list. */
.rfg-draft-empty {
  font-size: 0.85rem;
  color: var(--text-secondary, #6e6e73);
  font-style: italic;
  margin: 0;
}
.rfg-draft-list {
  list-style: none;
  padding: 0;
  margin: 0 0 10px 0;
}
.rfg-draft-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  background: #F9FAFB;
  color: var(--text-primary, #1d1d1f);
  margin-bottom: 6px;
}
.rfg-draft-meta { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.rfg-draft-path {
  color: var(--text-secondary, #6e6e73);
  font-size: 0.82rem;
  margin-right: 6px;
}
.rfg-draft-title { font-weight: 500; font-size: 0.92rem; }
.rfg-draft-count {
  color: var(--text-secondary, #6e6e73);
  font-size: 0.8rem;
  margin-left: 6px;
}

/* Dark-mode override — the light `#F9FAFB` background swallowed the
   default body text color, hiding the album title (the count rendered
   because `.rfg-draft-count` set its own gray which read OK on the
   light strip but was the only visible text overall).  Use a darker
   row tint and an explicit primary-text color so all three spans
   read clearly. */
@media (prefers-color-scheme: dark) {
  .rfg-draft-item {
    background: rgba(255, 255, 255, 0.06);
    color: #f5f5f7;
  }
  .rfg-draft-title { color: #f5f5f7; }
  .rfg-draft-path,
  .rfg-draft-count { color: rgba(245, 245, 247, 0.65); }
}

/* Draft-size notice — appears between the heading and the album
   list when the running total approaches (yellow) or exceeds (red)
   the browser-memory cap.  See SIZE_WARN_BYTES / SIZE_HARD_BYTES
   in read-from-google-view.js for thresholds. */
.rfg-size-notice {
  margin: 8px 0 12px 0;
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 0.88rem;
  line-height: 1.4;
  border: 1px solid;
}
.rfg-size-notice-warn {
  background: #FEF6E0;
  border-color: #F2C94C;
  color: #6B4F00;
}
.rfg-size-notice-error {
  background: #FEF2F2;
  border-color: #FCA5A5;
  color: #7F1D1D;
}
@media (prefers-color-scheme: dark) {
  .rfg-size-notice-warn {
    background: #3B2C0E;
    border-color: #8B6A1C;
    color: #F0D89A;
  }
  .rfg-size-notice-error {
    background: #3F1A1A;
    border-color: #8E3535;
    color: #FBBABA;
  }
}
.rfg-draft-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 8px;
}
.rfg-save-row { margin-top: 8px; text-align: center; }
.rfg-save-btn { padding: 12px 28px; font-size: 1rem; }


/* ═══════════════════════════════════════════════════════════════════════════
   Settings modal — Diagnostics section (Run Self-Tests)
   Mirrors the Swift app's Settings → Diagnostics → Self-Tests pattern.
   Results render inline so a beta tester can screenshot a failure list
   without leaving the modal.
   ═══════════════════════════════════════════════════════════════════════════ */

.settings-section {
  padding: 4px 0;
}
.settings-section + .settings-section {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--border, #e5e5ea);
}
.settings-section h3 {
  margin: 0 0 6px 0;
  font-size: 0.95rem;
  font-weight: 600;
}
.settings-section p {
  font-size: 0.85rem;
  color: var(--text-secondary, #6e6e73);
  margin: 0 0 12px 0;
  line-height: 1.45;
}

/* Yellow warning panel embedded in a Settings section — used for
   the "Live Google Photos integration tests" warning so the
   destructive nature of running them is visible before the user
   clicks the Open button.  Same colour palette as the main
   .rfg-warning banner so the visual language is consistent. */
.settings-warning-box {
  background: #FEF3C7;
  border: 1px solid #F0C966;
  border-radius: 10px;
  padding: 10px 14px;
  margin-bottom: 12px;
  font-size: 0.85rem;
  color: #5A3F06;
  line-height: 1.45;
}
.settings-warning-box strong {
  display: block;
  margin-bottom: 6px;
}
.settings-warning-box ul {
  margin: 4px 0 0 18px;
  padding: 0;
}
.settings-warning-box li {
  margin: 2px 0;
}
@media (prefers-color-scheme: dark) {
  .settings-warning-box {
    background: #3B2C0E;
    border-color: #8B6A1C;
    color: #F0D89A;
  }
}

/* The Open Live Integration Tests button is an <a> styled like
   .btn-primary so it reads as a real action, not a footnote
   link.  No JS click handler — target=_blank does the work. */
#settings-open-integration-tests {
  display: inline-block;
  text-decoration: none;
  text-align: center;
}
#settings-open-integration-tests:hover {
  text-decoration: none;
}

.settings-test-status {
  margin-top: 12px;
  font-size: 0.9rem;
  color: var(--text-secondary, #6e6e73);
  min-height: 1.2em;
}

.settings-test-summary {
  padding: 10px 12px;
  border-radius: 8px;
  font-weight: 600;
  font-size: 0.9rem;
}
.settings-test-summary.passed {
  background: #ECFDF5;
  color: #047857;
  border: 1px solid #A7F3D0;
}
.settings-test-summary.failed {
  background: #FEF2F2;
  color: #B91C1C;
  border: 1px solid #FECACA;
}

.settings-test-results {
  margin-top: 10px;
}
.settings-test-suite {
  padding: 8px 12px;
  border-radius: 8px;
  margin-bottom: 6px;
  background: #F9FAFB;
  border: 1px solid transparent;
}
.settings-test-suite.passed {
  background: #ECFDF5;
  border-color: #A7F3D0;
}
.settings-test-suite.failed {
  background: #FEF2F2;
  border-color: #FECACA;
}
.settings-test-suite-header {
  display: flex;
  gap: 10px;
  align-items: center;
}
.settings-test-icon {
  font-weight: 700;
  font-size: 0.95rem;
  width: 14px;
}
.settings-test-suite.passed .settings-test-icon { color: #047857; }
.settings-test-suite.failed .settings-test-icon { color: #B91C1C; }
.settings-test-suite-name {
  flex: 1 1 auto;
  font-weight: 500;
  font-size: 0.9rem;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
}
.settings-test-suite-count {
  font-size: 0.82rem;
  color: var(--text-secondary, #6e6e73);
  font-variant-numeric: tabular-nums;
}
.settings-test-suite-time {
  font-size: 0.8rem;
  color: var(--text-tertiary, #8e8e93);
  font-variant-numeric: tabular-nums;
  min-width: 56px;
  text-align: right;
}

.settings-test-detail {
  margin-top: 8px;
  font-size: 0.85rem;
}
.settings-test-detail summary {
  cursor: pointer;
  color: #B91C1C;
  font-weight: 500;
  user-select: none;
}
.settings-test-failures {
  margin: 6px 0 0 18px;
  padding: 0;
}
.settings-test-failures > li {
  margin-bottom: 6px;
}
.settings-test-failures ul {
  margin: 2px 0 0 16px;
  padding: 0;
}
.settings-test-failures code {
  background: rgba(0, 0, 0, 0.05);
  padding: 1px 5px;
  border-radius: 3px;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.82rem;
}

@media (prefers-color-scheme: dark) {
  .settings-test-summary.passed {
    background: #052e22;
    color: #A7F3D0;
    border-color: #065F46;
  }
  .settings-test-summary.failed {
    background: #3B0E0E;
    color: #FECACA;
    border-color: #991B1B;
  }
  .settings-test-suite { background: #1F2937; border-color: #374151; }
  .settings-test-suite.passed { background: #052e22; border-color: #065F46; }
  .settings-test-suite.failed { background: #3B0E0E; border-color: #991B1B; }
  .settings-test-failures code { background: rgba(255, 255, 255, 0.08); }
}
