/* ==========================================================================
   WEDDING ATTENDANCE & GUEST PORTAL - LUXURY DESIGN SYSTEM
   ========================================================================== */

html {
  font-size: 17.5px;
  color-scheme: light;
  scrollbar-gutter: stable;
  scrollbar-width: auto;
  scrollbar-color: rgba(197, 160, 89, 0.72) rgba(255, 255, 255, 0.06);
}

:root {
  --bg-light: #FAF8F5;
  --bg-champagne: #FDF8EC;
  --card-bg-light: rgba(255, 255, 255, 0.88);
  --card-bg-cream: rgba(253, 248, 236, 0.82);
  --border-light: rgba(212, 175, 55, 0.25);
  --border-gold-subtle: rgba(191, 149, 63, 0.28);
  --gold-primary: #BF953F;
  --gold-light: #FCF6BA;
  --gold-dark: #AA771C;
  --wine-accent: #8B263E;
  --shadow-luxury: 0 12px 36px -6px rgba(44, 30, 10, 0.06), 0 4px 12px -2px rgba(44, 30, 10, 0.03);
  --shadow-luxe-hover: 0 20px 45px -8px rgba(44, 30, 10, 0.12), 0 8px 16px -3px rgba(44, 30, 10, 0.05);

  /* Branding accent. Defaults to the stock amber, so an event that never sets
     one looks exactly as it always has. App.applyBranding overrides these two
     properties at boot from settings.branding.accent — hand-written CSS on
     purpose, because a Tailwind utility class cannot take a runtime value and
     this way branding never triggers a tailwind.css rebuild. */
  --accent: #d97706;
  --accent-strong: #b45309;
}

/* Applied to four surfaces only (portal header, primary CTA, highlighted seat
   pin, e-ticket header) — a full recolour would mean touching ~80 amber-600
   literals across index.html and eight modules. */
.accent-text { color: var(--accent-strong); }
.accent-ring { --tw-ring-color: var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 45%, transparent); }
/* background-image is cleared because these buttons carry a Tailwind gradient,
   which would otherwise paint straight over the accent colour. */
.accent-bg {
  background-image: none;
  background-color: var(--accent);
  color: #fff;
}
.accent-bg:hover { background-color: var(--accent-strong); }

.dark {
  --bg-dark: #0B1120;
  --card-bg-dark: rgba(15, 23, 42, 0.85);
  --card-bg-darker: rgba(11, 17, 32, 0.92);
  --border-dark: rgba(212, 175, 55, 0.3);
  --border-gold-subtle: rgba(212, 175, 55, 0.35);
  --shadow-luxury: 0 14px 40px -6px rgba(0, 0, 0, 0.55), 0 4px 14px -2px rgba(0, 0, 0, 0.35);
  --shadow-luxe-hover: 0 22px 50px -8px rgba(0, 0, 0, 0.7), 0 8px 20px -3px rgba(0, 0, 0, 0.45);
  color-scheme: dark;
}

body {
  font-family: 'Outfit', sans-serif;
  transition: background-color 0.3s ease, color 0.3s ease;
  background-color: var(--bg-light);
}

.dark body {
  background-color: var(--bg-dark);
}

/* ==========================================================================
   GLASSMORPHISM & LUXURY CONTAINERS
   ========================================================================== */

.glass-card {
  background: var(--card-bg-light);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid var(--border-light);
  box-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.04), 0 4px 6px -2px rgba(0, 0, 0, 0.02);
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.25s cubic-bezier(0.4, 0, 0.2, 1), border-color 0.25s ease;
}

.glass-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-luxe-hover);
  border-color: var(--border-gold-subtle);
}

.dark .glass-card {
  background: var(--card-bg-dark);
  border-color: var(--border-dark);
  box-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.4), 0 4px 6px -2px rgba(0, 0, 0, 0.2);
}

.dark .glass-card:hover {
  box-shadow: var(--shadow-luxe-hover);
  border-color: rgba(212, 175, 55, 0.45);
}

/* Luxury keepsakes / invitations */
.invitation-frame {
  position: relative;
  border: 1px solid rgba(212, 175, 55, 0.4);
  box-shadow: inset 0 0 0 4px rgba(212, 175, 55, 0.08), 0 15px 40px -10px rgba(0, 0, 0, 0.08);
}
.invitation-frame::before {
  content: '';
  position: absolute;
  inset: 6px;
  border: 1px solid rgba(212, 175, 55, 0.25);
  pointer-events: none;
  border-radius: calc(1rem - 6px);
}
.dark .invitation-frame {
  border-color: rgba(212, 175, 55, 0.45);
  box-shadow: inset 0 0 0 4px rgba(212, 175, 55, 0.12), 0 15px 40px -10px rgba(0, 0, 0, 0.5);
}

/* ==========================================================================
   GOLD FOIL & METALLIC GRADIENTS
   ========================================================================== */

.gold-gradient-text {
  background: linear-gradient(135deg, #BF953F 0%, #FCF6BA 30%, #B38728 60%, #FBF5B7 80%, #AA771C 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.gold-foil-badge {
  background: linear-gradient(135deg, #9E7B3B 0%, #D4AF37 50%, #735828 100%);
  color: #FFFFFF;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

.champagne-pill {
  background: linear-gradient(135deg, rgba(253, 248, 236, 0.95) 0%, rgba(248, 233, 199, 0.8) 100%);
  border: 1px solid rgba(212, 175, 55, 0.35);
  color: #735828;
}
.dark .champagne-pill {
  background: linear-gradient(135deg, rgba(72, 53, 21, 0.4) 0%, rgba(30, 25, 15, 0.6) 100%);
  border-color: rgba(212, 175, 55, 0.4);
  color: #F8E9C7;
}

/* ==========================================================================
   ANIMATIONS & KEYFRAMES
   ========================================================================== */

@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}
.animate-shimmer {
  background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.4) 50%, rgba(255,255,255,0) 100%);
  background-size: 200% 100%;
  animation: shimmer 3s infinite;
}

.loading-dots { display: inline-flex; gap: 3px; align-items: center; margin-left: 4px; }
.loading-dots span {
  width: 5px; height: 5px; border-radius: 50%;
  background: currentColor;
  animation: dot-bounce 1.4s ease-in-out infinite both;
}
.loading-dots span:nth-child(1) { animation-delay: -0.32s; }
.loading-dots span:nth-child(2) { animation-delay: -0.16s; }
.loading-dots span:nth-child(3) { animation-delay: 0s; }
@keyframes dot-bounce {
  0%, 80%, 100% { transform: scale(0); }
  40% { transform: scale(1); }
}

@keyframes spin-slow {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
.animate-spin-slow { animation: spin-slow 4s linear infinite; }

@keyframes toastSlideIn {
  from { transform: translate(-50%, 100%); opacity: 0; }
  to { transform: translate(-50%, 0); opacity: 1; }
}
@keyframes toastFadeOut {
  from { transform: translate(-50%, 0); opacity: 1; }
  to { transform: translate(-50%, 20px) scale(0.96); opacity: 0; }
}
.toast-enter { animation: toastSlideIn 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards; }
.toast-exit { animation: toastFadeOut 0.2s ease forwards; }

@keyframes modalScaleIn {
  from { transform: scale(0.94) translateY(12px); opacity: 0; }
  to { transform: scale(1) translateY(0); opacity: 1; }
}
@keyframes modalScaleOut {
  from { transform: scale(1) translateY(0); opacity: 1; }
  to { transform: scale(0.94) translateY(-12px); opacity: 0; }
}
.modal-enter { animation: modalScaleIn 0.28s cubic-bezier(0.34, 1.56, 0.64, 1) forwards; }
.modal-exit { animation: modalScaleOut 0.18s ease forwards; }

@keyframes checkinFlash {
  0% { background-color: rgba(212, 175, 55, 0.35); }
  50% { background-color: rgba(16, 185, 129, 0.25); }
  100% { background-color: transparent; }
}
.row-checkin-flash { animation: checkinFlash 1.2s ease; }

@keyframes live-pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.15); opacity: 0.75; }
}
.live-pulse { animation: live-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; }

@keyframes toast-progress {
  from { width: 100%; }
  to { width: 0%; }
}
.toast-progress {
  animation: toast-progress 3.2s linear forwards;
}

/* Themed replacement for browser-default title tooltips. */
#appTooltip {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 100000;
  max-width: min(320px, calc(100vw - 24px));
  padding: 8px 11px;
  border: 1px solid rgba(217, 119, 6, 0.55);
  border-radius: 10px;
  background: rgba(41, 37, 36, 0.97);
  color: #fef3c7;
  box-shadow: 0 12px 28px rgba(28, 25, 23, 0.28), 0 2px 8px rgba(28, 25, 23, 0.18);
  font-family: Outfit, ui-sans-serif, system-ui, sans-serif;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.4;
  text-align: center;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s ease;
}
#appTooltip.is-visible {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
html.dark #appTooltip {
  border-color: rgba(251, 191, 36, 0.6);
  background: rgba(28, 25, 23, 0.98);
  color: #fde68a;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.48), 0 2px 8px rgba(0, 0, 0, 0.3);
}
@media (prefers-reduced-motion: reduce) {
  #appTooltip { transition: none; }
}

/* Keep native selects visually aligned with the rounded site controls. The
   option popup remains OS/browser-owned, but the closed control is consistent
   across the admin, portal, and modal surfaces. */
select:not([multiple]) {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.5rem !important;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23b45309' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 14px 14px;
}
html.dark select:not([multiple]) {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23fbbf24' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
select:not([multiple]):focus {
  border-color: rgb(245 158 11 / 0.9);
  outline: none;
  box-shadow: 0 0 0 3px rgb(245 158 11 / 0.16);
}
select option {
  background: #ffffff;
  color: #292524;
}
html.dark select option {
  background: #1c1917;
  color: #f5f5f4;
}

/* ==========================================================================
   INTERACTIVE SEATING MAP & FLOOR PLAN
   ========================================================================== */

#planWrap, #gcPlanWrap { position: relative; }

.plan-pin {
  position: absolute;
  transform: translate(-50%, -50%);
  white-space: nowrap;
  transition: transform 0.15s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.plan-pin:hover {
  transform: translate(-50%, -50%) scale(1.1);
}

@keyframes plan-pin-highlight {
  0%, 100% {
    filter: brightness(1);
    box-shadow: 0 0 0 0 rgba(245, 158, 11, 0);
  }
  50% {
    filter: brightness(1.28);
    box-shadow: 0 0 0 5px rgba(245, 158, 11, 0.42), 0 0 18px 6px rgba(245, 158, 11, 0.32);
  }
}
.plan-pin-highlight {
  animation: plan-pin-highlight 1.2s ease-in-out infinite;
}

/* OCR engine selector card */
.ocr-card input[type="radio"]:checked ~ .ocr-card-indicator { display: flex; }
.ocr-card:has(input:checked) {
  border-color: #6366f1;
  background-color: rgba(99, 102, 241, 0.06);
}
.dark .ocr-card:has(input:checked) { background-color: rgba(99, 102, 241, 0.12); }

/* ==========================================================================
   COUNTDOWN FLIP TILES & WIDGETS
   ========================================================================== */

.countdown-tile {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(248, 233, 199, 0.4) 100%);
  border: 1px solid rgba(212, 175, 55, 0.3);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.8);
}
.dark .countdown-tile {
  background: linear-gradient(180deg, rgba(30, 41, 59, 0.9) 0%, rgba(15, 23, 42, 0.95) 100%);
  border-color: rgba(212, 175, 55, 0.35);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.08);
}

/* ==========================================================================
   UI UTILITIES & MICRO-INTERACTIONS
   ========================================================================== */

.btn-press {
  transition: transform 0.1s ease, box-shadow 0.1s ease;
}
.btn-press:active {
  transform: scale(0.96);
  box-shadow: none;
}

.filter-pill {
  transition: background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1),
              border-color 0.2s cubic-bezier(0.4, 0, 0.2, 1),
              color 0.2s cubic-bezier(0.4, 0, 0.2, 1),
              box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1),
              transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
.filter-pill:hover {
  transform: translateY(-1px);
}

.stat-number {
  transition: color 0.3s ease, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.card-stagger {
  opacity: 0;
  animation: fadeUpStagger 0.45s ease forwards;
  animation-delay: calc(var(--stagger-index, 0) * 0.04s);
}
@keyframes fadeUpStagger {
  from { transform: translateY(16px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

.progress-shimmer {
  position: relative;
  overflow: hidden;
}
.progress-shimmer::after {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 50%; height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.45), transparent);
  animation: sweep 2.2s infinite;
  will-change: transform;
}
@keyframes sweep {
  0% { transform: translateX(-200%); }
  100% { transform: translateX(400%); }
}

.space-x-0 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-x-reverse: 0;
  margin-right: calc(0px * var(--tw-space-x-reverse));
  margin-left: calc(0px * calc(1 - var(--tw-space-x-reverse)));
}

.text-stone-950 {
  color: #0c0a09;
}

/* Custom Scrollbars: the larger track makes the bar easier to see and grab,
   while scrollbar-gutter prevents content from sliding underneath it. */
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: rgba(255, 255, 255, 0.06); }
::-webkit-scrollbar-thumb {
  background: rgba(197, 160, 89, 0.72);
  border: 2px solid transparent;
  background-clip: padding-box;
  border-radius: 999px;
}
::-webkit-scrollbar-thumb:hover { background: rgba(197, 160, 89, 0.95); }

/* ==========================================================================
   PRINT STYLES
   ========================================================================== */

@media print {
  body > *:not(#printArea) { display: none !important; }
  #printArea { display: block !important; position: absolute; left: 0; top: 0; width: 100%; }
  .no-print { display: none !important; }
}

/* Tap on the theme button must deliver a click immediately — without
   touch-action, mobile browsers hold the first tap to detect a double-tap
   zoom, which reads as a dead click. */
#themeToggle {
  touch-action: manipulation;
}

/* Copy-to-clipboard confirmation: the button itself answers the press.
   !important because the buttons carry Tailwind background utilities including
   a hover variant, and a hover variant outranks a plain class. (Do not write
   the utility names with a star-slash in them here: that closes the comment
   early and CSS error recovery then swallows the rule below it.) */
.copied-flash {
  background: #059669 !important;
  border-color: #047857 !important;
  color: #fff !important;
  transform: scale(1.02);
  transition: background-color .15s ease, transform .15s ease;
}

/* ==========================================================================
   INLINE MINI SEARCH (panel headers)
   ==========================================================================
   The check-in tab owns the big search box; the panel headers (unassigned
   guests, still-to-arrive, e-tickets) each carried their own hand-rolled pill
   — different border colours, paddings and font sizes on what is the same
   control. One class so they cannot drift again. */
.mini-search {
  width: 11rem;
  /* A panel header that has to wrap on a phone shrinks this pill with it
     rather than pushing it past the right edge of the viewport. */
  max-width: 100%;
  padding: 0.4rem 0.75rem 0.4rem 1.9rem;
  font-size: 0.7rem;
  line-height: 1.25rem;
  border-radius: 9999px;
  border: 1px solid rgba(168, 162, 158, 0.55);
  background-color: rgba(255, 255, 255, 0.9);
  color: #44403c;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.mini-search::placeholder { color: #a8a29e; }
@media (min-width: 640px) { .mini-search { width: 13rem; } }
.mini-search:focus {
  outline: none;
  border-color: rgb(245 158 11 / 0.9);
  box-shadow: 0 0 0 3px rgb(245 158 11 / 0.16);
}
html.dark .mini-search {
  border-color: rgba(87, 83, 78, 0.9);
  background-color: rgba(28, 25, 23, 0.9);
  color: #e7e5e4;
}
html.dark .mini-search::placeholder { color: #78716c; }

/* The native option popup is OS-owned, but it follows color-scheme — without
   this an `appearance: none` select can still drop a bright white list over a
   dark page. */
select:not([multiple]) { color-scheme: light; }
html.dark select:not([multiple]) { color-scheme: dark; }

/* Honeypot field (App.checkFormGuard). Moved off-screen rather than
   display:none or type="hidden": a script skips a field the browser would not
   render either, so the trap has to look reachable in the markup and be
   unreachable in practice. aria-hidden + tabindex="-1" keep it away from
   screen readers and the tab order. */
.hp-field {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* Check-in control bar (#checkinControls). The pills, the action buttons and
   the search box follow the roster down the page: a helper works one guest at
   a time, and without this every arrival ended in a scroll back to the top to
   reach the search box again.

   Hand-written rather than Tailwind utilities on purpose. css/tailwind.css is
   precompiled, so `sticky top-0 z-30` would silently render as nothing until
   somebody remembered to rebuild it — a bar that quietly stops sticking is
   exactly the failure nobody notices until the reception desk is busy.

   z-index stays below the z-50 modals, or this would sit on top of the QR
   scanner and every confirm dialog. The negative side margins let the blurred
   background span the full width of the card's padding instead of leaving two
   sharp strips of scrolling roster down the sides. */
.checkin-sticky {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin: 0 -1rem;
  padding: 0.75rem 1rem;
  background: var(--card-bg-light);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border-light);
}

html.dark .checkin-sticky {
  background: var(--card-bg-dark);
  border-bottom-color: var(--border-dark);
}

@media (min-width: 640px) {
  .checkin-sticky { margin: 0 -1.5rem; padding: 0.75rem 1.5rem; }
}

@media (min-width: 1024px) {
  .checkin-sticky { margin: 0 -2rem; padding: 0.75rem 2rem; }
}
