/*
 * Application-specific styles
 *
 * 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.
 *
 * Note: Tailwind CSS is loaded separately via stylesheet_link_tag "tailwind" in the layout.
 * This file is for custom application styles that override or extend Tailwind.
 *
 * Consider organizing styles into separate files for maintainability.
 */

html,
body {
  max-width: 100%;
  /* `clip` prevents horizontal scroll WITHOUT creating a scroll container, so
     `position: sticky` (e.g. the admin sidebar) still works. `hidden` here
     silently broke all sticky positioning site-wide. */
  overflow-x: clip;
}

body {
  font-family: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
}

#main_content_area {
  min-width: 0;
}

/* Hamburger override for the admin sidebar. daisyUI's `lg:drawer-open`
   makes .drawer a 2-column CSS grid with drawer-side in col 1 and
   drawer-content placed in col 2 — so hiding drawer-side alone leaves
   drawer-content stuck in the right column. Flipping the whole drawer
   to display: block when collapsed dissolves the grid; drawer-content
   then naturally takes 100% width. The container inside re-centers
   itself via its own `mx-auto`. */
/* Desktop only: `.drawer-collapsed` exists solely to override `lg:drawer-open`,
   which only applies at >=1024px. On mobile the sidebar is driven by daisyUI's
   checkbox slide-out, and an unscoped `display:none !important` here would
   force-hide the sidebar and cancel the hamburger's checkbox open. */
@media (min-width: 1024px) {
  .drawer.drawer-collapsed {
    display: block !important;
  }
  .drawer.drawer-collapsed > .drawer-side {
    display: none !important;
  }
  .drawer.drawer-collapsed > .drawer-content {
    width: 100% !important;
    max-width: 100% !important;
    margin-left: 0 !important;
    grid-column: 1 / -1 !important;
  }

  /* The admin views pin their inner .container to the left with `lg:ml-0`
     (so it sits flush against the sidebar when the sidebar is visible).
     When the sidebar is hidden, that `ml-0` strands the content on the
     left and leaves the right half blank. Force mx-auto here so the
     container re-centers in the now-full-width drawer-content. */
  .drawer.drawer-collapsed > .drawer-content .container {
    margin-left: auto !important;
    margin-right: auto !important;
  }

  /* Inner narrow columns (e.g. <div class="max-w-3xl"> on the eXPRS auth
     page) sit at the LEFT of their parent container by default. With the
     sidebar hidden the user expects them centered on the page, not
     leaning against the parent's left edge. Center any max-w-* descendant
     horizontally when the drawer is collapsed. */
  /* Only genuinely-narrow columns should re-center; full-width caps (max-w-full
     / max-w-none) must stay put. Centering them is a no-op EXCEPT on w-fit
     elements (e.g. the billing `w-fit max-w-full` tab bar), where auto margins
     would wrongly center a left-aligned control when the sidebar collapses. */
  .drawer.drawer-collapsed [class*="max-w-"]:not([class*="max-w-full"]):not([class*="max-w-none"]) {
    margin-left: auto !important;
    margin-right: auto !important;
  }
}

/* Mobile: bypass daisyUI's drawer grid (which leaks column-1 width to viewport)
   so drawer-content takes full width and stays aligned to the viewport. */
@media (max-width: 1023px) {
  .drawer.lg\:drawer-open {
    display: block;
    max-width: 100vw;
    overflow-x: hidden;
  }
  .drawer.lg\:drawer-open > .drawer-content {
    width: 100%;
    max-width: 100vw;
    min-width: 0;
    overflow-x: hidden;
  }
  .drawer.lg\:drawer-open > .drawer-side {
    position: fixed;
    inset: 0;
    width: 100vw;
    max-width: 100vw;
  }
  /* The sticky header (navbar + sandbox banner) sits above the fixed mobile
     drawer, so pad the sidebar's content down by the header height to keep
     its top items from hiding underneath. --app-header-h is measured live by
     the header-height controller so it tracks the real height even when the
     banner or navbar wraps. */
  .drawer.lg\:drawer-open > .drawer-side .admin-sidebar {
    padding-top: var(--app-header-h, 4rem);
  }
}

/* The sticky header (navbar + sandbox banner) sits above the admin drawer, so
   trim the drawer's min-height by that amount. Without this the drawer's
   `min-h-screen` (100vh) stacks under the header → the page is 100vh + header
   and short admin pages get that much dead scroll. Applies at all widths (the
   single-col/mobile layout needs it too, not just desktop); --app-header-h is
   measured live so the trim matches the real header height even when it wraps.
   Scoped to the admin drawer via :has(.admin-sidebar) so other pages are
   untouched, and only the drawer wrapper/content — never the fixed sidebar. */
.drawer.lg\:drawer-open:has(.admin-sidebar),
.drawer.lg\:drawer-open:has(.admin-sidebar) > .drawer-content {
  min-height: calc(100dvh - var(--app-header-h, 4rem));
}

/* Desktop (lg:drawer-open makes .drawer-side sticky): daisyUI's default keeps
   the sidebar at top:0 + height:100dvh, so it's a full-viewport grid item that
   forces .drawer to a full 100dvh — defeating the header-height trim above and
   leaving ~header-height of phantom scroll on short admin pages. Pin the sticky
   sidebar below the header and shrink it to the same trimmed height, so the
   grid row matches the drawer and the dead-scroll disappears. */
@media (min-width: 1024px) {
  .drawer.lg\:drawer-open:has(.admin-sidebar) > .drawer-side {
    top: var(--app-header-h, 4rem);
    height: calc(100dvh - var(--app-header-h, 4rem));
  }
}

/* Turbo-frame loading state. The Sessions table swaps in place when filtering by
   DSP / scope / paging; Turbo sets [busy] on the frame during the fetch. Dim it
   and run a thin indeterminate bar across the top so the swap reads as "working"
   instead of a dead click. */
#billing-table-area {
  position: relative;
}
#billing-table-area[busy] {
  opacity: 0.6;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
#billing-table-area[busy]::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 2px;
  background: var(--color-primary, #2e7d52);
  transform-origin: left;
}
@media (prefers-reduced-motion: no-preference) {
  #billing-table-area[busy]::after {
    animation: billing-frame-load 1s ease-in-out infinite;
  }
}
@keyframes billing-frame-load {
  0%   { transform: scaleX(0); opacity: 1; }
  50%  { transform: scaleX(1); opacity: 1; }
  100% { transform: scaleX(1); opacity: 0; }
}

.section-eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.75rem;
  font-weight: 600;
  color: color-mix(in oklab, var(--color-base-content) 65%, transparent);
}

/* Tom Select styling to match daisyUI input-bordered */
.ts-wrapper.single .ts-control,
.ts-wrapper.multi .ts-control {
  border-radius: 3rem !important;
  border: 2px solid color-mix(in oklab, var(--color-base-content) 20%, transparent) !important;
  background-color: transparent !important;
  min-height: 2.5rem !important;
  box-shadow: 0 1px color-mix(in oklab, color-mix(in oklab, var(--color-base-content) 20%, transparent) calc(var(--depth, 1) * 10%), transparent) inset, 0 -1px oklch(100% 0 0 / calc(var(--depth, 1) * 0.1)) inset !important;
}

.ts-wrapper.single .ts-control:focus,
.ts-wrapper.multi .ts-control:focus,
.ts-wrapper.single.focus .ts-control,
.ts-wrapper.multi.focus .ts-control {
  outline: 2px solid transparent !important;
  outline-offset: 2px !important;
  border-color: var(--color-primary) !important;
  box-shadow: 0 1px color-mix(in oklab, var(--color-primary) calc(var(--depth, 1) * 10%), transparent) inset, 0 -1px oklch(100% 0 0 / calc(var(--depth, 1) * 0.1)) inset !important;
}

.ts-wrapper.single .ts-control input,
.ts-wrapper.multi .ts-control input {
  color: var(--color-base-content) !important;
}

.ts-wrapper.multi .ts-control > div {
  background-color: var(--color-primary) !important;
  color: var(--color-primary-content) !important;
  border-radius: 3rem !important;
  padding: 0.125rem 0.5rem !important;
  margin: 0 0.125rem 0.125rem 0 !important;
  border: 0 solid transparent !important;
}

/* Hide spinner arrows on number inputs */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Firefox */
input[type="number"] {
  -moz-appearance: textfield;
}

/* Smooth scrolling for anchor links */
html {
  scroll-behavior: smooth;
}

/* Enhanced spacing for markdown prose content */
.prose h3 {
  margin-top: 1.5rem;
  margin-bottom: 1rem;
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.75rem;
}

.prose h4 {
  margin-top: 1.25rem;
  margin-bottom: 0.75rem;
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.75rem;
}

.prose h5 {
  margin-top: 1rem;
  margin-bottom: 0.5rem;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.5rem;
}

.prose h6 {
  margin-top: 0.75rem;
  margin-bottom: 0.5rem;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.5rem;
}

.prose p {
  margin-top: 1rem;
  margin-bottom: 1rem;
}

.prose ul,
.prose ol {
  margin-top: 1rem;
  margin-bottom: 1rem;
  padding-left: 1.5rem;
}

.prose li {
  margin-top: 0.5rem;
  margin-bottom: 0.5rem;
}

.prose strong {
  font-weight: 600;
}

.prose > *:first-child {
  margin-top: 0;
}

.prose > *:last-child {
  margin-bottom: 0;
}

/* Better spacing for lists */
.prose ul + p,
.prose ol + p,
.prose p + ul,
.prose p + ol {
  margin-top: 1rem;
}

/* Line breaks should create visual separation */
.prose br {
  margin-bottom: 0.5rem;
}

/* Flatpickr styling to match daisyUI theme */
.flatpickr-calendar {
  background: var(--color-base-100) !important;
  border: 1px solid var(--color-base-300) !important;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06) !important;
}

.flatpickr-months {
  background: var(--color-base-200) !important;
  border-bottom: 1px solid var(--color-base-300) !important;
}

.flatpickr-month {
  color: var(--color-base-content) !important;
}

.flatpickr-current-month {
  color: var(--color-base-content) !important;
}

.flatpickr-weekdays {
  background: var(--color-base-200) !important;
}

.flatpickr-weekday {
  color: var(--color-base-content) !important;
}

.flatpickr-day {
  color: var(--color-base-content) !important;
}

.flatpickr-day:hover {
  background: var(--color-primary) !important;
  color: var(--color-primary-content) !important;
}

.flatpickr-day.selected {
  background: var(--color-primary) !important;
  color: var(--color-primary-content) !important;
  border-color: var(--color-primary) !important;
}

.flatpickr-day.today {
  border-color: var(--color-primary) !important;
}

.flatpickr-time {
  border-top: 1px solid var(--color-base-300) !important;
}

.flatpickr-time input {
  color: var(--color-base-content) !important;
}

.flatpickr-time .flatpickr-time-separator {
  color: var(--color-base-content) !important;
}

/* Toggle field visibility - JavaScript will handle this, but this ensures fields show when checkbox is checked on page load */
.toggle-field-container input[type="checkbox"]:checked ~ .toggle-field-target.hidden {
  display: block !important;
}

/* PWA install banner — safe area padding for iOS home indicator */
.safe-bottom {
  padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
}

/* Simple Calendar styling to work with daisyUI */
.simple-calendar {
  width: 100%;
}

.simple-calendar table {
  width: 100%;
  border-collapse: collapse;
}

.simple-calendar td {
  vertical-align: top;
  position: relative;
}
