/*
 * 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.
 *
 * Consider organizing styles into separate files for maintainability.
 */

@keyframes fade-out {
  0% { opacity: 1; transform: translateY(0); }
  70% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-5px); }
}

.animate-fade-out {
  animation: fade-out 3s forwards;
}

@keyframes pulse-subtle {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

.animate-pulse-subtle {
  animation: pulse-subtle 1.5s infinite;
}

/* Ocean atmosphere — ultra-subtle floating animation for gradient orbs */
@keyframes float-slow {
  0%, 100% { transform: translate(0, 0) scale(1); }
  33% { transform: translate(30px, -20px) scale(1.05); }
  66% { transform: translate(-20px, 15px) scale(0.95); }
}

@keyframes float-slower {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-40px, 25px) scale(1.03); }
}

@media (prefers-reduced-motion: no-preference) {
  .animate-float-slow {
    animation: float-slow 20s ease-in-out infinite;
    will-change: transform;
  }

  .animate-float-slower {
    animation: float-slower 25s ease-in-out infinite;
    will-change: transform;
  }
}

/* ========================================
   SIDEBAR REDESIGN: Modern Professional SaaS
   ======================================== */

/* Color Variables */
:root {
  --sidebar-bg: #1a2332;
  --sidebar-border: #2d3e52;
  --text-primary: #ffffff;
  --text-secondary: #a0aac0;
  --text-muted: #687a99;
  --hover-bg: #253447;
  --active-bg: #1f3a52;
  --accent: #10b981;
  --accent-light: #34d399;
}

/* Business Branding Section */
.sidebar-brand-section {
  padding: 1.5rem 1rem;
  background: linear-gradient(135deg, transparent, rgba(16, 185, 129, 0.05));
  border-bottom: 1px solid var(--sidebar-border);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.sidebar-brand-section:hover {
  background: linear-gradient(135deg, transparent, rgba(16, 185, 129, 0.1));
}

.brand-link {
  display: flex;
  align-items: center;
  gap: 1rem;
  text-decoration: none;
  transition: transform 0.2s ease;
}

.brand-link:hover {
  transform: translateX(2px);
}

.brand-avatar {
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 0.75rem;
  background: linear-gradient(135deg, #10b981, #059669);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: 700;
  font-size: 0.875rem;
  flex-shrink: 0;
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
  transition: box-shadow 0.3s ease;
}

.brand-link:hover .brand-avatar {
  box-shadow: 0 6px 16px rgba(16, 185, 129, 0.4);
}

.avatar-initials {
  letter-spacing: 0.05em;
}

.brand-info {
  flex: 1;
  min-width: 0;
}

.brand-label {
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 0.25rem;
}

.brand-name {
  font-size: 1rem;
  font-weight: 700;
  color: var(--text-primary);
  word-break: break-word;
  line-height: 1.2;
}

/* Navigation Section Labels */
.nav-section-label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 0.25rem 0.75rem 0.25rem;
  margin-top: 0;
  margin-bottom: 0;
  transition: color 0.2s ease;
}

.nav-section-label:first-of-type {
  margin-top: 0;
}

/* Navigation Links */
.nav-link {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.625rem 0.75rem;
  border-radius: 0.5rem;
  color: var(--text-secondary);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
}

.nav-link i {
  transition: color 0.2s ease;
}

.nav-link:hover {
  color: var(--text-primary);
  background-color: var(--hover-bg);
}

.nav-link:hover i {
  color: var(--text-primary);
}

.nav-link.active {
  background-color: var(--active-bg);
  color: var(--accent-light);
  font-weight: 700;
}

.nav-link.active i {
  color: var(--accent);
}

.nav-link.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: linear-gradient(to bottom, var(--accent), var(--accent-light));
  border-radius: 0 3px 3px 0;
}

/* User Profile Section */
.sidebar-user-profile {
  border-bottom: 1px solid var(--sidebar-border);
  margin-bottom: 0.5rem;
}

.user-avatar {
  width: 2rem;
  height: 2rem;
  border-radius: 0.5rem;
  background: linear-gradient(135deg, #3b82f6, #2563eb);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: 600;
  font-size: 0.75rem;
  flex-shrink: 0;
  letter-spacing: 0.05em;
}

.user-info {
  flex: 1;
  min-width: 0;
}

.user-name {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-primary);
  word-break: break-word;
}

.user-role {
  font-size: 0.75rem;
  color: var(--text-muted);
  text-transform: capitalize;
  margin-top: 0.125rem;
}

/* Smooth sidebar scrolling */
.sidebar-brand-section + nav {
  overflow-y: auto;
  scroll-behavior: smooth;
}

/* Divider styling */
.sidebar-divider {
  border-color: var(--sidebar-border);
}

/* ========================================
   EVENT CONSOLE: Nautical-Industrial Theme
   ======================================== */

/* Dark navy header with subtle gradient */
.event-console-header {
  background: linear-gradient(135deg, #102a43 0%, #1a3a56 50%, #243b53 100%);
  position: relative;
  font-family: 'DM Sans', sans-serif;
}
.event-console-header::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(32,201,151,0.3), transparent);
}

/* Boat pills — teal gradient */
.console-boat-pill {
  background: linear-gradient(135deg, #e6fcf5, #c3fae8);
  border: 1px solid #96f2d7;
  transition: all 0.15s ease;
}
.console-boat-pill:hover {
  box-shadow: 0 2px 8px rgba(32,201,151,0.2);
}

/* Participant row hover with left accent */
.console-participant-row {
  position: relative;
  transition: background 0.1s ease;
}
.console-participant-row::before {
  content: '';
  position: absolute;
  left: 0;
  top: 4px;
  bottom: 4px;
  width: 2px;
  border-radius: 1px;
  background: transparent;
  transition: background 0.15s ease;
}
.console-participant-row:hover::before {
  background: #20c997;
}
.console-participant-row:hover {
  background: #f0f4f8;
}

/* Sidebar scrollbar */
.console-sidebar::-webkit-scrollbar { width: 3px; }
.console-sidebar::-webkit-scrollbar-track { background: transparent; }
.console-sidebar::-webkit-scrollbar-thumb { background: #bcccdc; border-radius: 3px; }

/* Always-visible scrollbar used by overflowing dropdowns (customer search,
   etc). macOS hides scrollbars by default; this opts a specific element
   in to a persistent, visible scrollbar so operators know more rows
   exist below the fold. */
.fb-scroll-visible::-webkit-scrollbar { width: 10px; }
.fb-scroll-visible::-webkit-scrollbar-track { background: #f1f5f9; border-radius: 8px; }
.fb-scroll-visible::-webkit-scrollbar-thumb { background: #94a3b8; border-radius: 8px; border: 2px solid #f1f5f9; }
.fb-scroll-visible::-webkit-scrollbar-thumb:hover { background: #64748b; }
.fb-scroll-visible { scrollbar-color: #94a3b8 #f1f5f9; scrollbar-width: auto; }

/* Tab underline */
.console-tab {
  position: relative;
  transition: color 0.15s ease;
}
.console-tab::after {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 0;
  right: 0;
  height: 2px;
  background: transparent;
  border-radius: 1px 1px 0 0;
  transition: background 0.15s ease;
}
.console-tab.active::after {
  background: #20c997;
}
.console-tab.active {
  color: #087f5b;
}

/* Gap badge pulse for critical items */
@keyframes subtlePulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.7; }
}
.gap-badge-critical {
  animation: subtlePulse 2s ease-in-out infinite;
}

/* Compact select for boat dropdowns */
.console-compact-select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23829ab1'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 6px center;
  background-size: 8px;
}

/* ========================================
   PRINT STYLES: Manifest
   ======================================== */
@media print {
  /* Page setup: landscape for wide equipment columns */
  @page {
    size: A4 landscape;
    margin: 1cm 1.5cm;
  }

  /* Hide non-essential UI elements */
  .manifest-edit-trigger,
  .no-print,
  nav,
  aside,
  [data-testid="manifest-edit-mode"] select,
  [data-testid="manifest-edit-mode"] form,
  [data-testid="manifest-staff-edit"] button,
  .manifest-edit-mode,
  .flash-messages,
  [data-controller="flash"],
  .date-nav-arrows,
  button,
  [type="submit"] {
    display: none !important;
  }

  /* Force read-only mode in print */
  .manifest-read-mode {
    display: block !important;
  }

  /* Reset edit-mode border highlighting */
  [data-testid="manifest-event-section"] {
    border-left: 1px solid #e2e8f0 !important;
    background: white !important;
  }

  /* Remove background colors (save ink) */
  * {
    background: transparent !important;
    box-shadow: none !important;
  }

  /* Restore table borders for readability */
  table, th, td {
    border: 1px solid #d1d5db !important;
  }

  /* Repeat table headers on every page */
  thead {
    display: table-header-group;
  }

  /* Prevent splitting rows across pages */
  .manifest-participant-row,
  .manifest-event-section,
  tr {
    break-inside: avoid;
  }

  /* Compact font sizes */
  body {
    font-size: 11px !important;
    line-height: 1.3 !important;
  }

  th, td {
    padding: 4px 6px !important;
    font-size: 10px !important;
  }

  /* Unfulfilled equipment: bold + underline for B&W printers */
  .rental-pending {
    font-weight: bold !important;
    text-decoration: underline !important;
  }

  /* Continuous flow between events */
  .manifest-event-section {
    break-before: avoid;
  }
}

/* Stagger animation for rows */
@keyframes consoleSlideUp {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: no-preference) {
  .console-animate-row {
    animation: consoleSlideUp 0.25s ease forwards;
    opacity: 0;
  }
  .console-animate-row:nth-child(1) { animation-delay: 0.03s; }
  .console-animate-row:nth-child(2) { animation-delay: 0.06s; }
  .console-animate-row:nth-child(3) { animation-delay: 0.09s; }
  .console-animate-row:nth-child(4) { animation-delay: 0.12s; }
  .console-animate-row:nth-child(5) { animation-delay: 0.15s; }
  .console-animate-row:nth-child(6) { animation-delay: 0.18s; }
  .console-animate-row:nth-child(7) { animation-delay: 0.21s; }
  .console-animate-row:nth-child(8) { animation-delay: 0.24s; }
}

/* Cursive "handwritten" signature font — used for rendering typed-name
 * signatures on the customer signing screen live-preview and in the printable
 * signed-document view. Font loaded via Google Fonts link in application.html.erb.
 * Purely presentational — stored data stays as plain typed_name text. */
.signature-cursive {
  font-family: "Dancing Script", "Brush Script MT", cursive;
  font-size: 1.875rem;
  line-height: 1.3;
  color: #0f172a;
  font-weight: 600;
  letter-spacing: 0.01em;
  min-height: 2.5rem;
}


/* ========================================
   Native <dialog> confirmation modal — themed replacement for
   window.confirm(). Used by schedule_cell_controller.js when a user
   tries to change a staff member's session state with active
   assignments. Class names are not pulled from ERB so we keep the
   styling here (Tailwind JIT only scans Ruby/ERB by default).
   ======================================== */
.fb-confirm-dialog {
  padding: 0;
  margin: auto;
  border: none;
  border-radius: 0.5rem;
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
  outline: 1px solid rgba(0, 0, 0, 0.1);
  background: #fff;
  max-width: min(24rem, 90vw);
}
.fb-confirm-dialog::backdrop {
  background: rgba(0, 0, 0, 0.4);
}
.fb-confirm-dialog__body { padding: 1.25rem; }
.fb-confirm-dialog__title {
  font-size: 0.875rem;
  font-weight: 500;
  color: #111827;
  margin: 0;
}
.fb-confirm-dialog__actions {
  margin-top: 1.25rem;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
}
.fb-confirm-dialog__btn {
  display: inline-flex;
  align-items: center;
  border-radius: 0.375rem;
  padding: 0.5rem 0.75rem;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
}
.fb-confirm-dialog__btn--cancel {
  background: #fff;
  color: #374151;
  box-shadow: inset 0 0 0 1px #d1d5db;
}
.fb-confirm-dialog__btn--cancel:hover { background: #f9fafb; }
.fb-confirm-dialog__btn--confirm {
  background: #e11d48;
  color: #fff;
  border: none;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.fb-confirm-dialog__btn--confirm:hover { background: #f43f5e; }
.fb-confirm-dialog__btn:focus-visible {
  outline: 2px solid #e11d48;
  outline-offset: 2px;
}

/* ========================================
   Shared toast tokens — the single source of truth for entry/exit
   animation, dismiss-button affordance, and reduced-motion handling
   used by both Ui::FlashComponent (top-of-viewport, transient) and
   Ui::UndoToastComponent (bottom-right, reversible action).

   Tokens (not utility classes) so each component composes only what
   it needs — Flash uses the chrome + animation, UndoToast uses only
   the animation tokens. Without a single source these would drift.
   ======================================== */

@keyframes fb-toast-in {
  from { transform: translateY(-8px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}

@keyframes fb-toast-out {
  from { transform: translateY(0);    opacity: 1; }
  to   { transform: translateY(-8px); opacity: 0; }
}

/* Cards apply this class to inherit the entry animation on insertion
   into #flash via Turbo Stream. Reduced-motion users get an instant
   appear (no transform, no fade). */
.fb-toast-card {
  animation: fb-toast-in 0.18s ease-out;
}

/* When the notification controller marks a card as dismissing
   (data-dismissing="true"), play the exit animation. The Stimulus
   controller waits the animation duration before removing the
   element from the DOM. */
.fb-toast-card[data-dismissing="true"] {
  animation: fb-toast-out 0.18s ease-in forwards;
}

@media (prefers-reduced-motion: reduce) {
  .fb-toast-card,
  .fb-toast-card[data-dismissing="true"] {
    animation: none;
  }
}

/* ========================================
   Calendar cross-lane selection highlights — Round 1 Unit 18.

   When a card expands, the selection bus broadcasts a payload of related
   entity ids. Each lane's subscriber marks chips whose
   data-selection-key + data-selection-id match the payload with
   data-lane-related="true". The visual treatment is a subtle sky-blue
   1px ring + tint — distinct from the 2px dashed/solid drag-drop ring
   from Unit 17 so the two affordances never read the same.

   Drag-drop precedence: when a drag is active (body.calendar-dragging-*),
   suppress the relation ring on chips that ALSO happen to be drop
   targets. The drop-target ring is the more urgent affordance during a
   drag; the relation ring resumes on drag-end.
   ======================================== */

[data-lane-related="true"] {
  outline: 1px solid rgba(14, 165, 233, 0.55); /* sky-500 @ 55% */
  outline-offset: 1px;
  background-color: rgba(14, 165, 233, 0.08);  /* sky-500 @ 8% */
  transition: outline-color 120ms ease-out, background-color 120ms ease-out;
}

body.calendar-dragging-staff [data-lane-related="true"][data-drop-target],
body.calendar-dragging-boat  [data-lane-related="true"][data-drop-target] {
  outline: none;
  background-color: transparent;
}

/* Calendar trip-card accordion — height transition driven by JS
   measurement. The JS controller captures the current rendered
   height before flipping the state, then transitions to the measured
   target height. Explicit pixel heights keep the wrapper from
   collapsing to 0 during the swap (the source of an earlier blink).
   320ms with a gentler ease-out so expand + collapse feel deliberate
   rather than abrupt (220ms was too snappy per visual review). */
.calendar-card-accordion {
  transition: height 320ms cubic-bezier(0.22, 1, 0.36, 1);
}
@media (prefers-reduced-motion: reduce) {
  .calendar-card-accordion {
    transition: none;
  }
}

/* Calendar Unit 17 — drag-drop visual affordances.
   When a chip is being dragged, body gets `calendar-dragging-staff` or
   `calendar-dragging-boat`; valid drop targets pulse subtly so the
   operator sees where they can land. Invalid targets stay neutral —
   no dimming (the valid-target pulse is the affordance). */
body.calendar-dragging-staff [data-drop-target~="staff"][data-drop-eligible="true"],
body.calendar-dragging-staff [data-drop-target*="staff"][data-drop-eligible="true"],
body.calendar-dragging-boat  [data-drop-target~="boat"][data-drop-eligible="true"] {
  outline: 2px dashed rgba(99, 102, 241, 0.45);
  outline-offset: 2px;
  transition: outline-color 120ms ease-out;
}

[data-drop-target][data-drag-over="true"] {
  outline: 2px solid rgb(99, 102, 241) !important;
  background: rgba(99, 102, 241, 0.08);
}

[data-drop-target][data-drop-rejected="true"] {
  animation: calendar-drop-rejected 220ms ease-in-out;
}

@keyframes calendar-drop-rejected {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-3px); }
  40%      { transform: translateX(3px); }
  60%      { transform: translateX(-2px); }
  80%      { transform: translateX(2px); }
}

/* ========================================
   Calendar mobile responsive — Round 1 Unit 28.

   At narrow viewports (`<= 767px`) the multi-day grid stacks vertically so
   each visible date renders full-width as a single column. Tablet
   (`>= 768px`) keeps the desktop grid + drag-drop. The plan's R21 trims
   mobile to the read-mostly shape: lanes stack, drag-drop is suppressed,
   and the view-length toggle is hidden so operators don't try to widen
   the grid below the column threshold.

   The label rail (28px session-name column) collapses to 0 so day
   columns get the full viewport width; session names render inline in
   the per-(day, session) Resources block instead.
   ======================================== */

@media (max-width: 767px) {
  /* Stack the grid vertically: replace `28px <Ncols>` with a single
     full-width column. The header bar (sticky date headers) inherits
     this rule so its inline-style `grid-template-columns` is overridden
     by the cascade. The day-column-stack and its child date-header /
     session subgrids all carry the `grid` display + inline
     `grid-template-columns` style — target both via testid. */
  [data-testid="calendar-day-header-bar"],
  [data-testid="calendar-day-column-stack"] > .grid {
    grid-template-columns: 1fr !important;
  }

  /* Hide the session-rail corner cell (the empty 28px gutter above the
     header bar) and the session-label spacer at row 1 of each session
     subgrid; they're meaningless when columns stack. */
  [data-testid="calendar-day-column-stack-corner"],
  [data-testid="calendar-session-rail-label"] {
    display: none !important;
  }

  /* Trip cards span the single column. */
  [data-testid="calendar-trip-card-cell"] {
    grid-column: 1 !important;
  }

  /* Force the view-length toggle hidden — the grid can only render one
     column at this width, so the 3d / 7d options would lie about the
     surface. Tailwind already hides this at `< 640px` via `sm:`; this
     rule tightens to `<= 767px` so tablets in landscape (~768px) still
     see the toggle. */
  [data-testid="calendar-page-header-view-toggle"] {
    display: none !important;
  }

  /* Drag-drop affordance suppression — `data-drop-target` rings + body-
     class dragging-source pulses are visual noise on touch where the
     drag is disabled by the controller (see lane_drag_drop_controller's
     `connect()` short-circuit). The relation ring from Unit 18 stays —
     tap-to-expand still works. */
  body.calendar-dragging-staff [data-drop-target][data-drop-eligible="true"],
  body.calendar-dragging-boat  [data-drop-target][data-drop-eligible="true"],
  [data-drop-target][data-drag-over="true"] {
    outline: none !important;
    background: transparent !important;
  }
}

/* Touch-device drag-drop disable hint — shown when a touch user tries
   to drag a chip. The controller toggles `body.calendar-touch-blocked`
   on `pointerdown` of a chip; CSS reveals an inline message. */
body.calendar-touch-blocked [data-testid="calendar-touch-drag-notice"] {
  display: flex !important;
}
