/* ============================================================
   ix-modals-v1.0.1.css
   INBXIFY — Canonical modal + banner design system
   Single source of truth for overlay, modal shell, and banner
   strip patterns across T-A.

   PARALLEL TO ix-buttons. Same philosophy: one module owns one
   visual domain, consumed additively, migrate legacy at leisure.

   THREE PRIMITIVES:
     ix-overlay           Full-page backdrop (centers child modal)
     ix-modal             Modal card shell (head / body / footer)
     ix-modal-banner      Alert strip pattern (--alert / --info / --success)
                          + --compact size modifier (added v1.0.1)

   v1.0.1 CHANGELOG (April 29, 2026 — S14 Step 1):
     Adds ix-modal-banner--compact size variant. Renders the
     banner as a chip-sized inline pill (~32px tall) suitable
     for placement inside chrome header rows. Used by Studio
     header for the PDF triage banner — sits right-justified
     beside the title block, doesn't push tagline down.

     Standard banner (v1.0.0 default) remains unchanged. The
     --compact modifier is opt-in and cleanly composes with
     the existing --alert / --info / --success variants.

     No breaking changes. v1.0.0 consumers (uploads-processor
     v1.0.11 banner, future modals) keep working as-is.

   STRUCTURE:
     <div class="ix-overlay">
       <div class="ix-modal">
         <div class="ix-modal-bar"></div>          (gold accent strip, decorative)
         <div class="ix-modal-head">
           <div class="ix-modal-title-block">
             <div class="ix-modal-title">Title</div>
             <div class="ix-modal-sub">Subtitle</div>
           </div>
           <button class="ix-btn ix-btn--ghost ix-btn--icon">×</button>
         </div>
         <div class="ix-modal-body">…</div>
         <div class="ix-modal-footer">
           <button class="ix-btn ix-btn--ghost">Cancel</button>
           <div class="ix-modal-footer-right">
             <span class="ix-modal-footer-info">3 of 5 decided</span>
             <button class="ix-btn ix-btn--primary">Apply</button>
           </div>
         </div>
       </div>
     </div>

   STANDALONE BANNER (page-level, not inside modal):
     <div class="ix-modal-banner ix-modal-banner--alert">
       <span class="ix-modal-banner-icon">📕</span>
       <span class="ix-modal-banner-text">3 PDFs awaiting decision</span>
       <button class="ix-btn ix-btn--primary">Triage PDFs →</button>
     </div>

   The banner is named ix-modal-banner because conceptually it's
   the same alert-strip pattern modals use internally. Page-level
   banners and modal-internal banners share the same visual
   language and the same class set. The "modal" in the name
   describes the pattern's lineage, not where it's allowed to
   render — banners can sit anywhere on the page.

   LOAD ORDER (Webflow <head>):
     1. webflow.css
     2. title-admin-page-design-v1.4.x.css (design tokens)
     3. ta-studio-components-v1.0.x.css (component-specific)
     4. ix-buttons-v1.0.x.css
     5. ix-modals-v1.0.0.css   ← THIS FILE
     6. (page-specific overrides)

   This file MUST load after the design tokens (it consumes
   --ix-* CSS vars) AND after ix-buttons (so any button styling
   it uses internally is already defined).

   Authored 2026-04-29 as Sub-session B / S14 Step 2.
   New module — no prior versions.

   COEXISTENCE WITH cm-modal/cm-overlay:
     ta-studio + uploads-processor v1.0.10 still emit cm-modal /
     cm-overlay. Those classes are NOT touched by this module.
     New consumers (uploads-processor v1.0.11 triage modal,
     Sub-session C conflict modal, TD-161 Save-as-Component)
     emit ix-* classes. cm-* migrations are tech debt, deferred.
   ============================================================ */


/* ─────────────────────────────────────────────
   §1  ix-overlay — full-page backdrop
   Centers a single child .ix-modal.
   Mount target convention: appended to <body> with
   id="ix-modal-root" by the consuming JS.
   ───────────────────────────────────────────── */

.ix-overlay {
  position: fixed !important;
  inset: 0 !important;
  z-index: var(--ix-z-modal, 10000) !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 24px !important;
  background: rgba(26, 58, 58, 0.55) !important;
  backdrop-filter: blur(2px) !important;
  -webkit-backdrop-filter: blur(2px) !important;
  animation: ix-overlay-in 0.18s ease-out !important;
}

@keyframes ix-overlay-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}


/* ─────────────────────────────────────────────
   §2  ix-modal — modal card shell
   ───────────────────────────────────────────── */

.ix-modal {
  position: relative !important;
  width: 100% !important;
  max-width: 720px !important;
  max-height: calc(100vh - 48px) !important;
  display: flex !important;
  flex-direction: column !important;
  background: var(--ix-white, #ffffff) !important;
  border-radius: var(--ix-radius, 12px) !important;
  box-shadow: 0 20px 60px rgba(26, 58, 58, 0.25) !important;
  overflow: hidden !important;
  animation: ix-modal-in 0.22s cubic-bezier(0.2, 0.9, 0.3, 1.05) !important;
}

@keyframes ix-modal-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0)   scale(1); }
}

/* Decorative gold accent strip at top of modal */
.ix-modal-bar {
  height: 3px !important;
  background: linear-gradient(90deg, var(--ix-gold, #C4A35A) 0%, var(--ix-gold-light, #E8C172) 100%) !important;
  flex: 0 0 auto !important;
}

.ix-modal-head {
  display: flex !important;
  align-items: flex-start !important;
  justify-content: space-between !important;
  gap: 16px !important;
  padding: 18px 22px 14px !important;
  border-bottom: 1px solid var(--ix-border-soft, #eee9dc) !important;
  flex: 0 0 auto !important;
}

.ix-modal-title-block {
  flex: 1 1 auto !important;
  min-width: 0 !important;
}

.ix-modal-title {
  font-family: var(--ix-font-display, 'Fraunces', serif) !important;
  font-size: 20px !important;
  font-weight: 600 !important;
  color: var(--ix-text-dark, #1e2a3a) !important;
  line-height: 1.2 !important;
  margin: 0 !important;
}

.ix-modal-sub {
  font-family: var(--ix-font-mono, 'DM Mono', monospace) !important;
  font-size: 10px !important;
  font-weight: 500 !important;
  color: var(--ix-text-light, #8a8e9a) !important;
  letter-spacing: 0.04em !important;
  text-transform: uppercase !important;
  margin-top: 4px !important;
}

.ix-modal-body {
  padding: 18px 22px !important;
  overflow-y: auto !important;
  flex: 1 1 auto !important;
  min-height: 0 !important;
}

.ix-modal-footer {
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  gap: 12px !important;
  padding: 14px 22px !important;
  background: var(--ix-cream, #FAF9F5) !important;
  border-top: 1px solid var(--ix-border-soft, #eee9dc) !important;
  flex: 0 0 auto !important;
}

.ix-modal-footer-right {
  display: flex !important;
  align-items: center !important;
  gap: 12px !important;
}

.ix-modal-footer-info {
  font-family: var(--ix-font-mono, 'DM Mono', monospace) !important;
  font-size: 11px !important;
  color: var(--ix-text-mid, #5a6478) !important;
  letter-spacing: 0.04em !important;
}

/* Locked state — applied during async commit (apply / save).
   Body dims, footer disables. Consuming JS toggles .is-locked. */
.ix-modal.is-locked .ix-modal-body {
  opacity: 0.55 !important;
  pointer-events: none !important;
}
.ix-modal.is-locked .ix-modal-footer button {
  pointer-events: none !important;
}


/* ─────────────────────────────────────────────
   §3  ix-modal-banner — alert strip pattern
   Used both inside modals (e.g., warning at top of body)
   and at page level (e.g., the PDF triage banner in UP).

   Variants:
     --alert    Red — needs attention NOW (PDFs awaiting triage,
                save failures)
     --info     Blue — informational, not blocking
     --success  Green — confirmation after action

   Default (no variant) is neutral cream.
   ───────────────────────────────────────────── */

.ix-modal-banner {
  display: flex !important;
  align-items: center !important;
  gap: 12px !important;
  padding: 12px 16px !important;
  border-radius: var(--ix-radius-sm, 8px) !important;
  border: 1.5px solid var(--ix-border, #e4e0d4) !important;
  background: var(--ix-cream, #FAF9F5) !important;
  font-family: var(--ix-font-body, 'DM Sans', sans-serif) !important;
  font-size: 13px !important;
  color: var(--ix-text-dark, #1e2a3a) !important;
  margin-bottom: 14px !important;
}

.ix-modal-banner-icon {
  flex: 0 0 auto !important;
  font-size: 18px !important;
  line-height: 1 !important;
}

.ix-modal-banner-text {
  flex: 1 1 auto !important;
  font-weight: 500 !important;
  line-height: 1.35 !important;
}

.ix-modal-banner-text strong {
  font-weight: 700 !important;
  color: var(--ix-text-dark, #1e2a3a) !important;
}

.ix-modal-banner button.ix-btn,
.ix-modal-banner .ix-btn {
  flex: 0 0 auto !important;
}

/* ── Variant: --alert (red, attention-needed) ── */
.ix-modal-banner.ix-modal-banner--alert {
  background: linear-gradient(135deg, #fef3f2 0%, #fde9e7 100%) !important;
  border-color: #f5b9b4 !important;
  color: #8b2418 !important;
  box-shadow: 0 1px 3px rgba(192, 57, 43, 0.08) !important;
}
.ix-modal-banner.ix-modal-banner--alert .ix-modal-banner-text strong {
  color: #6f1c12 !important;
}

/* Subtle pulse to draw the eye on first appearance.
   Animation runs once and stops — not a constant attention-grab. */
.ix-modal-banner.ix-modal-banner--alert.is-fresh {
  animation: ix-banner-pulse 1.6s ease-out 1 !important;
}
@keyframes ix-banner-pulse {
  0%   { box-shadow: 0 1px 3px rgba(192, 57, 43, 0.08); }
  35%  { box-shadow: 0 0 0 6px rgba(192, 57, 43, 0.14), 0 1px 3px rgba(192, 57, 43, 0.08); }
  100% { box-shadow: 0 1px 3px rgba(192, 57, 43, 0.08); }
}

/* ── Variant: --info (blue, informational) ── */
.ix-modal-banner.ix-modal-banner--info {
  background: linear-gradient(135deg, #eef3ff 0%, #e3ebff 100%) !important;
  border-color: #b8c8ff !important;
  color: #1f3a8a !important;
}
.ix-modal-banner.ix-modal-banner--info .ix-modal-banner-text strong {
  color: #142a6b !important;
}

/* ── Variant: --success (green, confirmation) ── */
.ix-modal-banner.ix-modal-banner--success {
  background: linear-gradient(135deg, #effbf2 0%, #e0f5e6 100%) !important;
  border-color: #a8d8b4 !important;
  color: #1c5a30 !important;
}
.ix-modal-banner.ix-modal-banner--success .ix-modal-banner-text strong {
  color: #0e3e1d !important;
}


/* ─────────────────────────────────────────────
   §4  ix-modal-row — shared row pattern
   Used in modals that present a list of items each
   needing a per-row decision (triage, conflict-resolve,
   pre-flight check). Optional. Consumers can roll their
   own row layout if this doesn't fit.

   Sets up the .has-pending convention for dirty rows
   (Universal Rule 2 — gold border on dirty fields).
   ───────────────────────────────────────────── */

.ix-modal-row {
  display: grid !important;
  grid-template-columns: 28px 1fr auto !important;
  gap: 10px !important;
  align-items: center !important;
  padding: 10px 12px !important;
  border: 1.5px solid var(--ix-border, #e4e0d4) !important;
  border-radius: var(--ix-radius-sm, 8px) !important;
  background: var(--ix-white, #ffffff) !important;
  margin-bottom: 6px !important;
  transition: border-color 0.15s, background 0.15s, box-shadow 0.15s !important;
}

.ix-modal-row.has-pending {
  border-color: var(--ix-gold, #C4A35A) !important;
  background: #fdfcf8 !important;
  box-shadow: 0 0 0 3px var(--ix-changed-shadow, rgba(196,163,90,0.20)) !important;
}

.ix-modal-row.is-running {
  background: linear-gradient(90deg, #fdfcf8, #fffaee, #fdfcf8) !important;
  background-size: 200% 100% !important;
  animation: ix-row-shimmer 1.4s linear infinite !important;
}
@keyframes ix-row-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.ix-modal-row.is-done {
  opacity: 0.55 !important;
  background: #f4fbf4 !important;
  border-color: #c8e6c8 !important;
}

.ix-modal-row.is-failed {
  background: #fef3f2 !important;
  border-color: #f5b9b4 !important;
}

.ix-modal-row-icon {
  font-size: 18px !important;
  text-align: center !important;
  line-height: 1 !important;
}

.ix-modal-row-info {
  min-width: 0 !important;
}

.ix-modal-row-title {
  font-family: var(--ix-font-body, 'DM Sans', sans-serif) !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  color: var(--ix-text-dark, #1e2a3a) !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
}

.ix-modal-row-meta {
  font-family: var(--ix-font-mono, 'DM Mono', monospace) !important;
  font-size: 10px !important;
  color: var(--ix-text-light, #8a8e9a) !important;
  letter-spacing: 0.02em !important;
  margin-top: 2px !important;
  display: flex !important;
  gap: 8px !important;
  align-items: center !important;
  flex-wrap: wrap !important;
}

.ix-modal-row-controls {
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
}

/* Action select inside a row — receives gold border via
   .has-pending on the parent row, so the select itself
   doesn't need its own dirty-state styling.
   Sized for native cross-browser <select>. */
.ix-modal-row-select {
  font-family: var(--ix-font-body, 'DM Sans', sans-serif) !important;
  font-size: 12px !important;
  padding: 6px 10px !important;
  border: 1.5px solid var(--ix-border-input, #ddd9c8) !important;
  border-radius: 4px !important;
  background: var(--ix-white, #ffffff) !important;
  color: var(--ix-text-dark, #1e2a3a) !important;
  cursor: pointer !important;
  min-width: 180px !important;
}
.ix-modal-row-select:focus {
  outline: none !important;
  border-color: var(--ix-blue, #5B7FFF) !important;
  box-shadow: 0 0 0 3px var(--ix-blue-shadow, rgba(91,127,255,0.15)) !important;
}
.ix-modal-row.has-pending .ix-modal-row-select {
  border-color: var(--ix-gold, #C4A35A) !important;
}

/* Per-row revert link — appears only when row is dirty.
   Renders as ix-btn--ghost, but tighter padding for inline use. */
.ix-modal-row-revert {
  /* sized via ix-btn--ghost; nothing extra needed */
}

/* Status pill rendered inside row during apply — replaces
   the action select once the row is committed. */
.ix-modal-row-status {
  font-family: var(--ix-font-mono, 'DM Mono', monospace) !important;
  font-size: 10px !important;
  font-weight: 600 !important;
  letter-spacing: 0.04em !important;
  text-transform: uppercase !important;
  padding: 4px 10px !important;
  border-radius: var(--ix-radius-pill, 20px) !important;
  white-space: nowrap !important;
}
.ix-modal-row-status.is-pending  { background: #f3eee0; color: #8a6f35; }
.ix-modal-row-status.is-running  { background: #fff4d4; color: #6f4f0a; }
.ix-modal-row-status.is-done     { background: #d4eed4; color: #1c5a30; }
.ix-modal-row-status.is-failed   { background: #f8dad6; color: #8b2418; }


/* ─────────────────────────────────────────────
   §5  ix-modal-empty — empty/loading state inside body
   ───────────────────────────────────────────── */

.ix-modal-empty {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 48px 24px !important;
  text-align: center !important;
  color: var(--ix-text-light, #8a8e9a) !important;
}

.ix-modal-empty-icon {
  font-size: 32px !important;
  margin-bottom: 8px !important;
  opacity: 0.6 !important;
}

.ix-modal-empty-text {
  font-family: var(--ix-font-body, 'DM Sans', sans-serif) !important;
  font-size: 13px !important;
  color: var(--ix-text-mid, #5a6478) !important;
}

.ix-modal-loading {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 10px !important;
  padding: 32px !important;
  color: var(--ix-text-mid, #5a6478) !important;
  font-size: 13px !important;
}

.ix-modal-loading-spin {
  display: inline-block !important;
  animation: ix-spin 1s linear infinite !important;
  font-size: 16px !important;
}
@keyframes ix-spin {
  to { transform: rotate(360deg); }
}


/* ─────────────────────────────────────────────
   §3b ix-modal-banner--compact — chip-sized inline pill
   Added v1.0.1 (S14 Step 1) for inline placement in chrome
   header rows. Reduces padding, tightens layout, and drops
   the icon/text/button into a single 32px-tall row.

   Composes cleanly with --alert / --info / --success.
   The --compact modifier ONLY changes size; semantic
   coloring still comes from the variant class.
   ───────────────────────────────────────────── */

.ix-modal-banner.ix-modal-banner--compact {
  display: inline-flex !important;
  align-items: center !important;
  gap: 8px !important;
  padding: 4px 4px 4px 12px !important;
  margin-bottom: 0 !important;
  font-size: 12px !important;
  border-radius: var(--ix-radius-pill, 20px) !important;
  border-width: 1.5px !important;
  /* Keep total height bounded so it fits in chrome rows */
  min-height: 32px !important;
  max-height: 36px !important;
}

.ix-modal-banner.ix-modal-banner--compact .ix-modal-banner-icon {
  font-size: 14px !important;
  line-height: 1 !important;
}

.ix-modal-banner.ix-modal-banner--compact .ix-modal-banner-text {
  font-size: 12px !important;
  font-weight: 500 !important;
  line-height: 1.2 !important;
  white-space: nowrap !important;
}

.ix-modal-banner.ix-modal-banner--compact .ix-modal-banner-text strong {
  font-weight: 700 !important;
}

/* Compact-internal button — slightly smaller than standard
   so it fits the pill height without dominating it.
   Override happens via descendant selector to win specificity
   against ix-buttons base styling. */
.ix-modal-banner.ix-modal-banner--compact button.ix-btn,
.ix-modal-banner.ix-modal-banner--compact .ix-btn {
  padding: 4px 12px !important;
  min-height: 24px !important;
  font-size: 10px !important;
  letter-spacing: 0.04em !important;
}

/* Pulse on first appearance — same animation as standard,
   but the box-shadow values are tuned for the compact's
   smaller footprint so the pulse doesn't overflow. */
.ix-modal-banner.ix-modal-banner--compact.is-fresh {
  animation: ix-banner-pulse-compact 1.6s ease-out 1 !important;
}
@keyframes ix-banner-pulse-compact {
  0%   { box-shadow: 0 1px 3px rgba(192, 57, 43, 0.08); }
  35%  { box-shadow: 0 0 0 4px rgba(192, 57, 43, 0.18), 0 1px 3px rgba(192, 57, 43, 0.08); }
  100% { box-shadow: 0 1px 3px rgba(192, 57, 43, 0.08); }
}


/* ─────────────────────────────────────────────
   §3c ix-hdr-right — header-row right-alignment helper
   Added v1.0.1 alongside --compact banner. Lets a chrome
   header row hold the version badge + a banner slot in a
   single right-justified flex container.

   Used by Studio header (ta-studio-v1.2.11):
     <div class="ix-hdr">
       <div class="ix-hdr-left">…title block…</div>
       <div class="ix-hdr-right">
         <div id="std-triage-banner"></div>
         <span class="ix-badge">vX.Y.Z</span>
       </div>
     </div>

   The .ix-hdr container should already have flex layout from
   title-admin-page-design (`.ix-hdr { display:flex; justify-
   content: space-between; align-items: flex-start; }`). This
   module just adds the right-side grouping container.
   ───────────────────────────────────────────── */

.ix-hdr-right {
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
  flex: 0 0 auto !important;
}

/* Banner slot — empty by default (no reserved space).
   Renders as inline-flex when populated so the banner pill
   sits inline with the version badge. When the slot is
   empty, the gap between left and badge collapses. */
.std-triage-banner-slot:empty {
  display: none !important;
}


/* ─────────────────────────────────────────────
   §6  RESPONSIVE
   Modal narrows on small viewports. Footer stacks.
   ───────────────────────────────────────────── */

@media (max-width: 640px) {
  .ix-overlay { padding: 12px !important; }
  .ix-modal { max-width: 100% !important; }
  .ix-modal-head { padding: 14px 16px 12px !important; }
  .ix-modal-body { padding: 14px 16px !important; }
  .ix-modal-footer {
    flex-direction: column !important;
    align-items: stretch !important;
    gap: 8px !important;
    padding: 12px 16px !important;
  }
  .ix-modal-footer-right {
    justify-content: space-between !important;
  }
  .ix-modal-row {
    grid-template-columns: 28px 1fr !important;
  }
  .ix-modal-row-controls {
    grid-column: 1 / -1 !important;
    justify-content: flex-end !important;
    padding-top: 4px !important;
    border-top: 1px dashed var(--ix-border, #e4e0d4) !important;
  }
}

/* End of ix-modals-v1.0.1.css */
