/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * ---------------------------------------------------------------------------
 * WHY THIS FILE EXISTS — we are otherwise a utility-first Tailwind codebase.
 *
 * Every rule below is here because it CANNOT be written as a Tailwind utility.
 * Design tokens (colours, fonts, shadows) live in `app/assets/tailwind/application.css`
 * under `@theme` — never add one here. Before adding anything to this file, check
 * it is one of the five accepted exceptions:
 *
 *   1. @keyframes — Tailwind can play them, it cannot declare them.
 *   2. Vendor pseudo-elements — ::-webkit-scrollbar, ::-webkit-calendar-picker-indicator,
 *      ::-webkit-datetime-edit-*, ::backdrop. No utilities exist for these.
 *   3. Custom elements — <turbo-frame> has no sensible default display.
 *   4. Global resets — prefers-reduced-motion across *, ::before and ::after.
 *   5. Progressive enhancement — rules that must apply only once a Stimulus
 *      controller has connected (scroll reveal, booking panel). A utility cannot
 *      say "…but only if JavaScript is alive".
 *
 * If your rule is not one of those five, it belongs in a Tailwind class.
 * ---------------------------------------------------------------------------
 */

/* Smooth font rendering */
body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Ensure touch targets are large enough on mobile (44px minimum) */
@media (max-width: 767px) {
  button,
  a[role="button"],
  input[type="submit"],
  input[type="button"] {
    min-height: 44px;
  }
}

/* Turbo Frame defaults — custom element is inline without this, which breaks layout.
   Kept in @layer base so Tailwind utilities (e.g. `flex`, which lives in the later
   `utilities` layer) can override `display` on frames that need to be flex containers —
   notably the chat widget panel, which scrolls inside a fixed-height frame. */
@layer base {
  turbo-frame {
    display: block;
  }

  /* Native <dialog> backdrop — Tailwind has no ::backdrop utility; kept transparent so the
     modal's own overlay div (data-modal-target="backdrop") handles the dim effect. */
  dialog::backdrop { background: transparent; }
}

/* `busy` is set by Turbo itself during frame navigation — it never appears in our markup. */
turbo-frame[busy] {
  opacity: 0.6;
  pointer-events: none;
  transition: opacity 0.2s ease-in-out;
}

/* Hide scrollbar but keep functionality */
.hide-scrollbar::-webkit-scrollbar {
  display: none;
}
.hide-scrollbar {
  -ms-overflow-style: none;
  scrollbar-width: none;
}

/* Public website header dropdown — click-to-open (web--dropdown controller).
   Hover and focus-within already reveal the menu via the group-hover / focus
   utilities on the element; this pairs the click path so keyboard/touch users
   get the same reveal. The controller toggles `.web--dropdown-open` on the
   menu element. We only set the *open* state here — the closed state is the
   Tailwind base (`opacity-0 invisible translate-y-2`). Specificity matches
   the utilities so order wins; !important avoids losing to `invisible`. */
.web--dropdown-open {
  opacity: 1 !important;
  visibility: visible !important;
  transform: translate(-50%, 0) !important;
}

/* Body scroll lock when the Start Hub panel or the mobile menu is open */
body.menu-open {
  overflow: hidden;
}

/* IBM Plex Mono for code blocks only — tabular-nums must remain a font-variant utility */
.font-mono, code, pre {
  font-family: 'IBM Plex Mono', monospace;
}

/*
 * Native date/time/datetime picker styling
 *
 * The browser's default picker indicator and placeholder are pale and unstyled,
 * reading as "broken field" against Calm & Clear. Tone the indicator down and
 * unify the placeholder colour with our other inputs.
 */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator {
  opacity: 0.55;
  cursor: pointer;
  filter: invert(35%) sepia(8%) saturate(0%) hue-rotate(0deg) brightness(95%);
  transition: opacity 120ms ease;
}
input[type="date"]:hover::-webkit-calendar-picker-indicator,
input[type="time"]:hover::-webkit-calendar-picker-indicator,
input[type="datetime-local"]:hover::-webkit-calendar-picker-indicator {
  opacity: 0.85;
}
input[type="date"]::-webkit-datetime-edit-text,
input[type="date"]::-webkit-datetime-edit-month-field,
input[type="date"]::-webkit-datetime-edit-day-field,
input[type="date"]::-webkit-datetime-edit-year-field,
input[type="time"]::-webkit-datetime-edit-text,
input[type="time"]::-webkit-datetime-edit-hour-field,
input[type="time"]::-webkit-datetime-edit-minute-field,
input[type="time"]::-webkit-datetime-edit-ampm-field,
input[type="datetime-local"]::-webkit-datetime-edit-text,
input[type="datetime-local"]::-webkit-datetime-edit-month-field,
input[type="datetime-local"]::-webkit-datetime-edit-day-field,
input[type="datetime-local"]::-webkit-datetime-edit-year-field,
input[type="datetime-local"]::-webkit-datetime-edit-hour-field,
input[type="datetime-local"]::-webkit-datetime-edit-minute-field {
  color: var(--color-ink, #161614);
}
input[type="date"]:not(:focus):placeholder-shown::-webkit-datetime-edit,
input[type="time"]:not(:focus):placeholder-shown::-webkit-datetime-edit,
input[type="datetime-local"]:not(:focus):placeholder-shown::-webkit-datetime-edit {
  color: var(--color-ink3, #7A7770);
}

/*
 * Keyframes
 *
 * Tailwind can reference an animation but cannot declare one, so every @keyframes
 * the app plays lives here. Each is paired with the utility class that plays it.
 * Delete a keyframe only when its class has no callers left.
 */

/* Slide down from the top — flash toasts (shared/hub/_toast) */
@keyframes slide-down {
  from {
    opacity: 0;
    transform: translateY(-16px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.animate-slide-down {
  animation: slide-down 0.3s ease-out forwards;
}

/* Subtle pulse for pending status badges (shared/hub/_status_badge) */
@keyframes pulse-subtle {
  0%, 100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.85;
    transform: scale(1.02);
  }
}

.animate-pulse-subtle {
  animation: pulse-subtle 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

/* Glow for confirmed/success states (shared/hub/_status_badge) */
@keyframes glow-success {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(34, 197, 94, 0);
  }
  50% {
    box-shadow: 0 0 8px 2px rgba(34, 197, 94, 0.3);
  }
}

.animate-glow-success {
  animation: glow-success 2s ease-in-out infinite;
}

/* Punch in/out toast — slide in, pop the checkmark, slide out.
   Played by hub/toast_controller and the attendance punch turbo streams. */
@keyframes toast-in {
  0% {
    opacity: 0;
    transform: translateY(-20px) scale(0.95);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.animate-toast-in {
  animation: toast-in 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

@keyframes check-pop {
  0% {
    opacity: 0;
    transform: scale(0) rotate(-45deg);
  }
  50% {
    transform: scale(1.2) rotate(0deg);
  }
  100% {
    opacity: 1;
    transform: scale(1) rotate(0deg);
  }
}

.animate-check-pop {
  animation: check-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.15s forwards;
  opacity: 0;
}

@keyframes toast-out {
  0% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
  100% {
    opacity: 0;
    transform: translateY(-20px) scale(0.95);
  }
}

.animate-toast-out {
  animation: toast-out 0.3s ease-in forwards;
}

/* Reduced-motion: neutralise every animation/transition site-wide for motion-
   sensitive visitors. Animations that use `forwards` still land on their visible
   end state instead of being left at opacity:0, because we collapse the duration
   rather than cancel the animation. Decorative autoplay videos are paused
   separately by the web--ambient-video controller. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* Scroll reveal animations
   Progressive enhancement: content is visible by default. Only when the
   web--scroll-reveal Stimulus controller connects (it adds .js-scroll-reveal-ready
   to its scope) do we hide elements until they intersect the viewport.
   prefers-reduced-motion and the no-JS fallback leave content fully visible. */
[data-reveal] {
  opacity: 1;
  transform: none;
}

.js-scroll-reveal-ready [data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s ease-out, transform 0.7s ease-out;
}

.js-scroll-reveal-ready [data-reveal].revealed,
.js-scroll-reveal-reduced [data-reveal] {
  opacity: 1;
  transform: translateY(0);
}

/* Stagger children with delay — only applies when JS has primed the reveal */
.js-scroll-reveal-ready [data-reveal-delay="1"] { transition-delay: 0.1s; }
.js-scroll-reveal-ready [data-reveal-delay="2"] { transition-delay: 0.2s; }
.js-scroll-reveal-ready [data-reveal-delay="3"] { transition-delay: 0.3s; }
.js-scroll-reveal-ready [data-reveal-delay="4"] { transition-delay: 0.4s; }

noscript ~ [data-reveal] {
  opacity: 1;
  transform: none;
}

/* Mobile booking panel reveal
   Progressive enhancement: the direct-book form is visible by default. Only
   when web--booking-panel connects (it primes its scope with
   .js-booking-panel-ready) do we collapse the form on mobile behind the
   "Check Availability" toggle. Desktop (lg+) always shows the form, and the
   no-JS fallback leaves it fully visible. */
@media (max-width: 1023px) {
  .js-booking-panel-ready .booking-panel-form {
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    transition: max-height 0.45s ease, opacity 0.3s ease;
  }
  .js-booking-panel-ready.booking-panel-open .booking-panel-form {
    max-height: 1400px;
    opacity: 1;
    overflow: visible;
  }
  .js-booking-panel-ready .booking-panel-toggle-open [data-lucide],
  .js-booking-panel-ready .booking-panel-toggle-open svg {
    transform: rotate(180deg);
  }
}
