/* ── Cross-browser compatibility baseline ──
   Addresses: iOS landscape text inflation, iOS tap flash, form font inheritance,
   Chrome autofill background, number input spinners.
   Sources: Normalize.css, modern-normalize, CSS Remedy. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

*,
*::before,
*::after {
  -webkit-tap-highlight-color: transparent;
}

button,
input,
select,
textarea {
  font: inherit;
  letter-spacing: inherit;
}

/* Chrome/Edge autofill: override the default yellow/blue background that
   clashes with our slate-50 input backgrounds. Uses inset box-shadow trick
   because Chrome ignores background-color on autofilled inputs. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
select:-webkit-autofill {
  -webkit-box-shadow: 0 0 0 1000px #f8fafc inset; /* slate-50 */
  -webkit-text-fill-color: #1e293b; /* slate-800 */
  transition: background-color 5000s ease-in-out 0s;
}

/* Hide number input spinners for consistent appearance across browsers.
   Chrome/Edge show up/down arrows; Firefox/Safari do not. */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
input[type="number"] {
  -moz-appearance: textfield;
}

/* ── iPetitions Design System: Color Palette ──
   Source: Figma Design System → Palette
   Convention: --color-{family}-{shade}
   Usage:  var(--color-blue-gray-800)  or  Tailwind: text-blue-gray-800 */
:root {
  /* Blue Gray */
  --color-blue-gray-50: #f8fafc;
  --color-blue-gray-100: #f1f5f9;
  --color-blue-gray-200: #e2e8f0;
  --color-blue-gray-300: #cbd5e1;
  --color-blue-gray-400: #94a3b8;
  --color-blue-gray-500: #64748b;
  --color-blue-gray-600: #475569;
  --color-blue-gray-700: #334155;
  --color-blue-gray-800: #1e293b;
  --color-blue-gray-900: #0f172a;

  /* Orange */
  --color-orange-50: #fff7ed;
  --color-orange-100: #ffedd5;
  --color-orange-200: #fed7aa;
  --color-orange-300: #fdba74;
  --color-orange-400: #fb923c;
  --color-orange-500: #f97316;
  --color-orange-600: #ea580c;
  --color-orange-700: #c2410c;
  --color-orange-800: #9a3412;
  --color-orange-900: #7c2d12;

  /* Yellow */
  --color-yellow-50: #fffbeb;
  --color-yellow-100: #fef3c7;
  --color-yellow-200: #fde68a;
  --color-yellow-300: #fcd34d;
  --color-yellow-400: #fbbf24;
  --color-yellow-500: #f59e0b;
  --color-yellow-600: #d97706;
  --color-yellow-700: #b45309;
  --color-yellow-800: #92400e;
  --color-yellow-900: #78350f;

  /* Red */
  --color-red-50: #fef2f2;
  --color-red-100: #fee2e2;
  --color-red-200: #fecaca;
  --color-red-300: #fca5a5;
  --color-red-400: #f87171;
  --color-red-500: #ef4444;
  --color-red-600: #dc2626;
  --color-red-700: #b91c1c;
  --color-red-800: #991b1b;
  --color-red-900: #7f1d1d;

  /* Green */
  --color-green-50: #ecfdf5;
  --color-green-100: #d1fae5;
  --color-green-200: #a7f3d0;
  --color-green-300: #6ee7b7;
  --color-green-400: #34d399;
  --color-green-500: #10b981;
  --color-green-600: #059669;
  --color-green-700: #047857;
  --color-green-800: #065f46;
  --color-green-900: #064e3b;

  /* Teal — stored as space-separated RGB triples (not hex) so Tailwind's
     `bg-teal-N/<alpha>` slash-opacity modifier can wrap them as
     `rgb(<r> <g> <b> / <alpha>)`. Direct usages outside Tailwind classes
     must wrap with `rgb(var(--color-teal-N))` — see styles.css gradient
     and _donation_card.html. */
  --color-teal-50: 240 253 250;
  --color-teal-100: 204 251 241;
  --color-teal-200: 153 246 228;
  --color-teal-300: 94 234 212;
  --color-teal-400: 45 212 191;
  --color-teal-500: 20 184 166;
  --color-teal-600: 13 148 136;
  --color-teal-700: 15 118 110;
  --color-teal-800: 17 94 89;
  --color-teal-900: 19 78 74;

  /* Blue */
  --color-blue-50: #eff6ff;
  --color-blue-100: #dbeafe;
  --color-blue-200: #bfdbfe;
  --color-blue-300: #93c5fd;
  --color-blue-400: #60a5fa;
  --color-blue-500: #3b82f6;
  --color-blue-600: #2563eb;
  --color-blue-700: #1d4ed8;
  --color-blue-800: #1e40af;
  --color-blue-900: #1e3a8a;

  /* Indigo — RGB triples for the same slash-opacity reason as teal above. */
  --color-indigo-50: 238 242 255;
  --color-indigo-100: 224 231 255;
  --color-indigo-200: 199 210 254;
  --color-indigo-300: 165 180 252;
  --color-indigo-400: 129 140 248;
  --color-indigo-500: 99 102 241;
  --color-indigo-600: 79 70 229;
  --color-indigo-700: 67 56 202;
  --color-indigo-800: 55 48 163;
  --color-indigo-900: 49 46 129;


  /* Navbar clearance - padding-top needed to push content below the
     fixed glassmorphic navbar.  Use in Tailwind as:
       * pt-[var(--pt-main-navbar-m)]
       * lg:pt-[var(--pt-main-navbar-d)] */
  --pt-main-navbar-m: 98px; /* Mobile */
  --pt-main-navbar-d: 122px; /* Desktop */
}


/* 3D Gradient CTA Button
   Note: Hover changes background-image (gradients), which CSS cannot
   transition smoothly. The color shift is intentionally instant. */
.btn-cta-3d {
  background:
    radial-gradient(
      ellipse at 86% 88%,
      rgba(124, 45, 18, 0.2) 0%,
      rgba(124, 45, 18, 0) 86%
    ),
    radial-gradient(
      ellipse at 26% 21%,
      rgba(255, 247, 237, 0.35) 0%,
      rgba(255, 255, 255, 0) 77%
    ),
    linear-gradient(90deg, var(--color-orange-500) 0%, var(--color-orange-500) 100%);
  box-shadow:
    3px 3px 5px 0px rgba(124, 45, 18, 0.15), /* orange-900 base / 15% */
    inset -2px -4px 7px 0px rgba(255, 247, 237, 0.24); /* orange-50 base / 24% */
}

.btn-cta-3d:hover {
  background:
    radial-gradient(
      ellipse at 86% 88%,
      rgba(124, 45, 18, 0.25) 0%,
      rgba(124, 45, 18, 0) 86%
    ),
    radial-gradient(
      ellipse at 26% 21%,
      rgba(255, 247, 237, 0.4) 0%,
      rgba(255, 255, 255, 0) 77%
    ),
    linear-gradient(90deg, var(--color-orange-600) 0%, var(--color-orange-600) 100%);
}

/* 3D Gradient CTA Button — Teal variant */
.btn-cta-3d-teal {
  background:
    radial-gradient(
      ellipse at 86% 88%,
      rgba(17, 94, 89, 0.2) 0%,
      rgba(17, 94, 89, 0) 86%
    ),
    radial-gradient(
      ellipse at 26% 21%,
      rgba(255, 247, 237, 0.5) 0%,
      rgba(255, 255, 255, 0) 77%
    ),
    linear-gradient(90deg, rgb(var(--color-teal-700)) 0%, rgb(var(--color-teal-700)) 100%);
  box-shadow:
    3px 3px 5px 0px rgba(17, 94, 89, 0.15), /* teal-800 base / 15% */
    inset -2px -4px 7px 0px rgba(255, 247, 237, 0.24); /* orange-50 base / 24% */
}

.btn-cta-3d-teal:hover {
  background:
    radial-gradient(
      ellipse at 86% 88%,
      rgba(17, 94, 89, 0.25) 0%,
      rgba(17, 94, 89, 0) 86%
    ),
    radial-gradient(
      ellipse at 26% 21%,
      rgba(255, 247, 237, 0.55) 0%,
      rgba(255, 255, 255, 0) 77%
    ),
    linear-gradient(90deg, #0d6963 0%, #0d6963 100%);
}

/* 3D Gradient CTA Button — Green variant (constructive secondary, e.g. Edit) */
.btn-cta-3d-green {
  background:
    radial-gradient(
      ellipse at 86% 88%,
      rgba(6, 78, 59, 0.2) 0%,
      rgba(6, 78, 59, 0) 86%
    ),
    radial-gradient(
      ellipse at 26% 21%,
      rgba(236, 253, 245, 0.4) 0%,
      rgba(255, 255, 255, 0) 77%
    ),
    linear-gradient(90deg, var(--color-green-600) 0%, var(--color-green-600) 100%);
  box-shadow:
    3px 3px 5px 0px rgba(6, 78, 59, 0.15), /* green-900 base / 15% */
    inset -2px -4px 7px 0px rgba(236, 253, 245, 0.24); /* green-50 base / 24% */
}

.btn-cta-3d-green:hover {
  background:
    radial-gradient(
      ellipse at 86% 88%,
      rgba(6, 78, 59, 0.25) 0%,
      rgba(6, 78, 59, 0) 86%
    ),
    radial-gradient(
      ellipse at 26% 21%,
      rgba(236, 253, 245, 0.45) 0%,
      rgba(255, 255, 255, 0) 77%
    ),
    linear-gradient(90deg, var(--color-green-700) 0%, var(--color-green-700) 100%);
}

/* 3D Gradient CTA Button — Red variant (destructive, e.g. Delete) */
.btn-cta-3d-red {
  background:
    radial-gradient(
      ellipse at 86% 88%,
      rgba(127, 29, 29, 0.2) 0%,
      rgba(127, 29, 29, 0) 86%
    ),
    radial-gradient(
      ellipse at 26% 21%,
      rgba(254, 242, 242, 0.4) 0%,
      rgba(255, 255, 255, 0) 77%
    ),
    linear-gradient(90deg, var(--color-red-600) 0%, var(--color-red-600) 100%);
  box-shadow:
    3px 3px 5px 0px rgba(127, 29, 29, 0.15), /* red-900 base / 15% */
    inset -2px -4px 7px 0px rgba(254, 242, 242, 0.24); /* red-50 base / 24% */
}

.btn-cta-3d-red:hover {
  background:
    radial-gradient(
      ellipse at 86% 88%,
      rgba(127, 29, 29, 0.25) 0%,
      rgba(127, 29, 29, 0) 86%
    ),
    radial-gradient(
      ellipse at 26% 21%,
      rgba(254, 242, 242, 0.45) 0%,
      rgba(255, 255, 255, 0) 77%
    ),
    linear-gradient(90deg, var(--color-red-700) 0%, var(--color-red-700) 100%);
}

@media (max-width: 1023px) {
  .btn-cta-3d-sm,
  .btn-cta-3d-green-sm,
  .btn-cta-3d-red-sm {
    min-height: 30px;
    padding: 0 12px;
    border-radius: 9999px;
    font-size: 12px;
    line-height: 1;
    white-space: nowrap;
    box-shadow:
      1px 1px 3px 0px rgba(71, 85, 105, 0.14),
      inset -1px -2px 4px 0px rgba(255, 247, 237, 0.24);
  }

  .btn-cta-3d-sm:hover,
  .btn-cta-3d-green-sm:hover,
  .btn-cta-3d-red-sm:hover {
    box-shadow:
      1px 1px 3px 0px rgba(71, 85, 105, 0.18),
      inset -1px -2px 4px 0px rgba(255, 247, 237, 0.3);
  }
}

/* Glass-effect preview button */
.btn-preview:hover:not(:disabled),
.btn-preview:active:not(:disabled) {
  background:
    radial-gradient(ellipse at 30% 20%, rgba(255, 255, 255, 0.7) 0%, transparent 60%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.5) 0%, rgba(241, 245, 249, 0.3) 100%); /* blue-gray-100 base / 30% */
  box-shadow:
    2px 2px 6px 0px rgba(0, 0, 0, 0.06),
    -1px -1px 4px 0px rgba(0, 0, 0, 0.04),
    inset -1px -2px 5px 0px rgba(255, 255, 255, 0.4);
}

/* Design System: card shadow — reusable drop shadow for card containers.
   Figma token: "card shadow" = 1px 1px 10px rgba(71,85,105,0.1) */
.shadow-card {
  box-shadow: 1px 1px 10px 0px rgba(71, 85, 105, 0.1); /* blue-gray-600 / 10% */
}

/* "Improve My Draft" shimmer animation — uses a pseudo-element so the
   gradient fades in via opacity instead of snapping (CSS can't transition
   between a solid bg and a gradient background-image). */
.improve-draft-shimmer {
  position: relative;
  overflow: hidden;
}

.improve-draft-shimmer > * {
  position: relative;
  z-index: 1;
}

.improve-draft-shimmer::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(
    82deg,
    rgba(255, 237, 213, 0.4) 0%,  /* orange-100 / 40% */
    rgba(254, 215, 170, 0.8) 50%, /* orange-200 / 80% */
    rgba(255, 237, 213, 0.4) 100% /* orange-100 / 40% */
  );
  background-size: 200% 100%;
  background-position: 100% 0;
  opacity: 0;
  animation: draft-shimmer-in 0.4s ease-out forwards,
             draft-shimmer 3s ease-in-out 0.4s infinite;
}

@keyframes draft-shimmer-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes draft-shimmer {
  0% { background-position: 100% 0; }
  50% { background-position: 0% 0; }
  100% { background-position: 100% 0; }
}

/* IMD button activation glow ring */
.imd-activate {
  animation: imd-glow 0.6s ease-out;
}

@keyframes imd-glow {
  0%   { outline: 2px solid rgba(249, 115, 22, 0.5); outline-offset: 0px; } /* orange-500 / 50% */
  100% { outline: 2px solid rgba(249, 115, 22, 0);   outline-offset: 8px; } /* orange-500 / 0% */
}

/* AI suggestion loading skeleton */
.ai-skeleton-line {
  height: 14px;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--color-blue-gray-200) 25%, var(--color-blue-gray-100) 50%, var(--color-blue-gray-200) 75%);
  background-size: 200% 100%;
  animation: skeleton-pulse 1.5s ease-in-out infinite;
}

@keyframes skeleton-pulse {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .improve-draft-shimmer::before { animation: none; opacity: 1; }
  .imd-activate { animation: none; }
  .ai-skeleton-line { animation: none; }
}


/* Donation marquee — animate the wrapper so all copies move as one unit.
   3 copies in the track; translateX(-33.33%) shifts by exactly one copy's width
   for a seamless loop with buffer to prevent gap flashes. */
@keyframes donation-marquee {
  0% { transform: translateX(0); }
  100% { transform: translateX(-33.33%); }
}
.donation-marquee-track {
  animation: donation-marquee 60s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .donation-marquee-track { animation: none; }
}



/* Alpine.js cloak — hide elements until Alpine initializes */
[x-cloak] { display: none !important; }


/* Mobile petition progress bar — inset shadow matching Figma */
.progress-bar-inset {
  box-shadow: inset 0px 1px 5px 0px rgba(198, 96, 0, 0.19); /* ~orange-700 / 19% */
}

/* Gradient text fade for collapsed/truncated text blocks.
   Apply .text-gradient-fade when collapsed; remove when expanded.
   Set --fade-color on the element to control the top color.
   Uses background-clip:text so the text itself fades out toward the bottom. */
.text-gradient-fade {
  color: transparent !important;
  background: linear-gradient(to bottom, var(--fade-color, var(--color-blue-gray-800)) 0%, rgba(0, 0, 0, 0.15) 90%);
  -webkit-background-clip: text;
  background-clip: text;
}
.text-gradient-fade > * {
  color: inherit !important;
}

/* Sticky bar frosted glass */
.sticky-bar-glass {
  backdrop-filter: blur(7.5px);
  -webkit-backdrop-filter: blur(7.5px);
  background: rgba(250, 250, 250, 0.7);
  box-shadow: 0px -2px 4px 0px rgba(71, 85, 105, 0.05), /* blue-gray-600 / 5% */
              0px -10px 15px 0px rgba(71, 85, 105, 0.05); /* blue-gray-600 / 5% */
}



/* Hide scrollbar while preserving scroll — used by horizontal scroll strips
   (trending carousel on home, category chips on browse). */
.scrollbar-hide {
  scrollbar-width: none;       /* Firefox */
  -ms-overflow-style: none;    /* IE/Edge */
}
.scrollbar-hide::-webkit-scrollbar {
  display: none;                /* Chrome/Safari */
}


/* Progressive blur overlay for petition card image — from petition_editor.html */
.preview-progressive-blur {
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
  -webkit-mask: linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,0.2) 20%, rgba(0,0,0,0.5) 40%, rgba(0,0,0,1) 100%);
  mask: linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,0.2) 20%, rgba(0,0,0,0.5) 40%, rgba(0,0,0,1) 100%);
}


/* ── Trix editor content (IPE-127) ──
   Trix 2.1.8's trix.css ships no list/link styling for editor content, so
   bullet/numbered lists render markerless and links render as plain text
   *inside* the <trix-editor> — Tailwind Preflight's resets (`ul, ol {
   list-style: none }` and `a { color: inherit; text-decoration: inherit }`)
   win unopposed. Restore them for the editor, mirroring the .rich-text body. */
.trix-content ul,
.trix-content ol { padding-left: 1.5rem; }
.trix-content ul { list-style-type: disc; }
.trix-content ol { list-style-type: decimal; }
.trix-content a {
  color: var(--color-orange-600);
  text-decoration: underline;
}
/* Headings inside the editor (mirrors .rich-text sizing). h1 kept so pasted
   <h1> renders before the sanitizer drops it on save. */
.trix-content h1,
.trix-content h2,
.trix-content h3,
.trix-content h4 {
  font-weight: 600;
  line-height: 1.3;
  margin: 1.5rem 0 0.5rem;
}
.trix-content h1 { font-size: 1.5rem; }
.trix-content h2 { font-size: 1.25rem; }
.trix-content h3 { font-size: 1.125rem; }
.trix-content h4 { font-size: 1rem; }
.trix-content u { text-decoration: underline; }
.trix-content blockquote {
  margin: 0 0 1rem;
  padding-left: 1rem;
  border-left: 3px solid var(--color-blue-gray-200);
  color: var(--color-blue-gray-600);
}
.trix-content pre {
  margin: 0 0 1rem;
  padding: 0.75rem 1rem;
  background: var(--color-blue-gray-100);
  border-radius: 0.375rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.875rem;
  white-space: pre-wrap;
}
.trix-content hr {
  margin: 1.5rem 0;
  border: 0;
  border-top: 1px solid var(--color-blue-gray-200);
}
/* Trix renders the HR content attachment as a <figure> — make it visible
   inside the editor. The sanitizer drops the <figure> wrapper on save. */
.trix-content figure[data-trix-content-type="application/vnd.trix.horizontal-rule.html"] {
  display: block;
  margin: 1.5rem 0;
}

/* ── Unified 5-state input field (IPE-233) ──────────────────────────
   Pseudo-class driven, zero JS. Compose with sizing/padding utilities
   (h-12, rounded-2xl, bg-slate-50, px-4, etc.) in templates — this class
   only owns the state-dependent border + ring colors.

     State                                         Border + ring
     1. Default (empty + unfocused)                slate (grey)
     2. Typed but not validated yet                slate (same as default)
     3. Focused / active                           orange (always wins)
     4. Filled + validation passed (post-blur)     green
     5. Filled + validation failed                 red
        - :user-invalid → client-side HTML5 failure (post-interaction)
        - [aria-invalid="true"] → Django server-side form error

   :user-valid / :user-invalid (CSS spec; not :valid / :invalid) fire only
   after the user has interacted, so empty required fields don't turn red
   on page load. Safari 16+ floor per project policy; Safari 16.0–16.4
   gracefully degrade to states 1 + 3 (no green / red without focus). */
.input-field {
  border-color: var(--color-blue-gray-300);
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.input-field:not(:focus):user-valid {
  border-color: var(--color-green-500);
  box-shadow: 0 0 0 1px var(--color-green-500);
}
.input-field:not(:focus):user-invalid,
.input-field:not(:focus)[aria-invalid="true"] {
  border-color: var(--color-red-500);
  box-shadow: 0 0 0 1px var(--color-red-500);
}
.input-field:focus {
  border-color: var(--color-orange-500);
  box-shadow: 0 0 0 1px var(--color-orange-500);
}

/* QR share code — make_qr_svg() emits a viewBox (omitsize) and no fixed
   width/height, so the SVG scales to its bounded container instead of
   overflowing the narrow share/success modal and clipping on the right
   (IPE-255). The wrapping element caps the max width. */
.qr-code svg {
  display: block;
  width: 100%;
  height: auto;
}
