/*
 * 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.
 */

@import "https://cdn.jsdelivr.net/npm/tom-select@2.3.1/dist/css/tom-select.css";
@import "https://cdn.jsdelivr.net/npm/tom-select@2.3.1/dist/css/tom-select.default.css";
@import "https://cdn.jsdelivr.net/npm/trix@2.1.16/dist/trix.css";

html {
  scroll-behavior: smooth;
  scroll-padding-top: 70px;
}

/* Trix editor styling */
trix-editor {
  min-height: 12rem;
  border: 1px solid #d1d5db;
  border-radius: 0.375rem;
  padding: 0.75rem;
}

trix-editor:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 1px #3b82f6;
}

/* Hide file attachment button - not needed for email templates */
trix-toolbar .trix-button-group--file-tools {
  display: none;
}

/* Disabled form controls are greyed out and show the "unavailable" cursor.
   Single source of truth — don't add per-field disabled: utilities. */
input:disabled,
select:disabled,
textarea:disabled {
  cursor: not-allowed;
  background-color: #e5e7eb; /* gray-200 */
  color: #6b7280; /* gray-500 */
}

.ts-wrapper.plugin-remove_button:not(.rtl) .item .remove {
  border-left: none;
  color: red;
}

/* Cap width so long option names don't blow out layout. The cap is a fixed
   length on purpose: auto-layout tables size columns ignoring percentage
   max-widths, so min(14rem, 100%) let a w-full select's longest option widen
   its line-item column while the wrapper still rendered at 14rem. */
.ts-wrapper:not(.global-search-ts) {
  max-width: 14rem;
}

/* Lock select width to the native select's width so it doesn't shift.
   tom_select_controller sets --ts-min-width to the native select's width
   plus 10px of headroom for the control's caret/padding. The 14rem cap
   lives in the width itself so table columns size to it; max-width: 100%
   then only matters at layout, keeping a full-width select inside a column
   narrower than that. */
.ts-wrapper.single:not(.global-search-ts) {
  width: min(var(--ts-min-width), 14rem);
  max-width: 100%;
}

/* min-width beats max-width, so cap the lock itself for multi selects. */
.ts-wrapper.multi {
  min-width: min(var(--ts-min-width), 100%);
}

/* Truncate long option text in the dropdown */
.ts-dropdown .option {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* While a query is being typed into a single select (ts-searching, toggled
   by tom_select_controller), hide the current selection so the query is
   readable instead of overlapping the old value. Keyed off typed text, not
   focus — a just-selected item must stay visible while the input still has
   focus. display (not visibility) so the item also gives up its space and
   the query starts at the left edge of the control. */
.ts-wrapper.single.ts-searching .item {
  display: none;
}

/* While a morph update is in flight (body.morph-pending, toggled by
   dynamic_form_controller), server-computed values pulse gently to show
   they're being recalculated. The animation-delay keeps typical sub-200ms
   round-trips from flickering — the pulse only becomes visible when the
   server is genuinely slow. Inputs are never dimmed; they're user-owned. */
body.morph-pending [data-morph-dim] {
  animation: morph-dim-pulse 1.2s ease-in-out 0.15s infinite;
}

body.morph-pending form[data-morph-form] {
  cursor: progress;
}

@keyframes morph-dim-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

/* Allow the dropdown panel to grow wider than the (narrow) control so
   long option names are fully visible. The dropdown is absolutely
   positioned, so it overlays adjacent content without shifting layout. */
.ts-wrapper:not(.global-search-ts) .ts-dropdown {
  width: max-content;
  min-width: 100%;
  max-width: 32rem;
}

/* A dropdown floated on <body> (tom_select_controller does this for selects
   inside a scrolling container, e.g. line-item tables) so the container
   can't clip it. Tom Select sets its width to the control's inline; the
   controller copies that to min-width, and this lets long names widen it.
   z-index clears modals (z-50) so line items inside a modal still work. */
.ts-dropdown.ts-dropdown-floating {
  width: max-content !important;
  max-width: 32rem;
  z-index: 60;
}

.print-color-adjust {
  -webkit-print-color-adjust:exact !important;
  print-color-adjust:exact !important;
}

.ts-wrapper.ts-large .ts-control,
.ts-wrapper.ts-large .ts-control input {
  font-size: 1.75rem;
  line-height: 2rem;
  min-height: 4rem;
  padding: 0.75rem 1rem;
}

.ts-wrapper.ts-large .ts-control {
  display: flex;
  align-items: center;
}

.ts-wrapper.ts-large .ts-dropdown .option,
.ts-dropdown-floating.ts-large .option {
  font-size: 1.5rem;
  line-height: 1.75rem;
  padding: 1rem;
}

/* ts-large is used in station mode for touch-friendly full-width selects.
   Opt out of the 14rem cap and the native-select width lock applied to
   regular wrappers. */
.ts-wrapper.ts-large {
  max-width: none;
}
.ts-wrapper.ts-large.single:not(.global-search-ts) {
  width: 100%;
}

/* ts-wide is the width-only escape hatch: fill the container without the
   touch-friendly sizing ts-large applies. Use it on regular desktop forms
   where the 14rem cap is too narrow. */
.ts-wrapper.ts-wide {
  max-width: none;
}
.ts-wrapper.ts-wide.single:not(.global-search-ts) {
  width: 100%;
}


/* Named for the busy overlay alone: Tailwind's animate-spin defines its own
   `spin` (a bare rotate), and whichever stylesheet loads last would win both,
   leaving this centred spinner sliding diagonally instead of turning. */
@keyframes busy-spin {
  to {
    transform: translate(-50%, -50%) rotate(360deg);
  }
}

[busy] {
  position: relative;
  &::before {
    content: '';
    display: block;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.15);
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1000;
  }
  &::after {
    content: '';
    display: block;
    width: 20px;
    height: 20px;
    background-color: white;
    position: fixed;
    top: 50vh;
    left: 50vw;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    border: 4px solid rgba(0, 0, 0, 0.5);
    border-top-color: white;
    animation: busy-spin 1s linear infinite;
    z-index: 1001;
  }
}

/* Navigation layers (app/javascript/system_wise/layers.js): a page shown
   inside a layer drops the sidebar and the global header buttons; the
   layer's own frame supplies close/back controls. */
html.in-layer [data-app-chrome] {
  display: none !important;
}

html.in-layer .app-content {
  padding-left: 0 !important;
}

/* The row or link whose page is open in a layer. */
[data-layer-active] {
  outline: 2px solid #2563eb;
  outline-offset: -2px;
}
