/*
 * tip-loading.css
 *
 * Site-wide "no blank screen" loading states. Pairs with tip-loading.js.
 *
 *   1. Top progress bar   - #tip-progress-bar, shown while a same-page
 *      navigation (link click / form submit) is in flight.
 *   2. Page fade-in       - html.tip-js .tip-page-enter, applied by JS to
 *      whichever content wrapper exists on the page (#kt_content / #kt_post
 *      / .app-main / main). Scoped to html.tip-js so that if the JS never
 *      runs, the rule never matches and content stays at its default,
 *      fully-visible state - nothing is ever hidden by CSS alone.
 *   3. DataTables skeleton - shimmering placeholder rows shown between
 *      preXhr.dt and xhr.dt/draw.dt/error.dt for ajax/serverSide tables,
 *      including the tip-mcards phone card layout.
 *
 * All motion is disabled under prefers-reduced-motion; the progress bar can
 * still appear (just without the trickle animation) and the fade-in is
 * skipped outright.
 */

/* ------------------------------------------------------------------ *
 * 1. Top progress bar
 * ------------------------------------------------------------------ */

#tip-progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  width: 0%;
  height: 3px;
  background: var(--bs-primary, #E8546B);
  box-shadow: 0 0 8px 0 rgba(var(--bs-primary-rgb, 232, 84, 107), .55);
  /* Above Metronic's fixed header/aside (z-index up to ~2200) and the
     drawer overlay (1090/1091), but below nothing that matters day to day. */
  z-index: 10050;
  opacity: 0;
  pointer-events: none;
  transition: width .4s ease, opacity .25s ease;
}

#tip-progress-bar.tip-progress-active {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  /* Keep the show/hide fade but drop the width "trickle" transition -
     tip-loading.js also skips the stepped trickle loop in this mode and
     jumps the bar straight to its resting width. */
  #tip-progress-bar {
    transition: opacity .2s ease;
  }
}

/* ------------------------------------------------------------------ *
 * 2. Page fade-in
 * ------------------------------------------------------------------ */

@keyframes tip-page-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Scoped to html.tip-js (set synchronously at the very top of
   tip-loading.js) so this only ever fires once the script is confirmed to
   be running. animation-fill-mode is "backwards", NOT "both": once the
   animation ends the element returns to its own styles with no transform.
   A lingering transform (even translateY(0)) makes the wrapper the
   containing block for position:fixed children, which pins slide-out
   drawers (document comment drawers live inside #kt_content) to the page
   content instead of the viewport. */
html.tip-js .tip-page-enter {
  animation: tip-page-in .18s ease-out backwards;
}

@media (prefers-reduced-motion: reduce) {
  html.tip-js .tip-page-enter {
    animation: none;
  }
}

/* ------------------------------------------------------------------ *
 * 3. DataTables skeleton rows
 * ------------------------------------------------------------------ */

.tip-skel {
  display: block;
  width: 100%;
  max-width: 140px;
  height: 13px;
  border-radius: .5rem;
  background: linear-gradient(90deg,
    var(--bs-gray-200, #e4e6ef) 25%,
    var(--bs-gray-100, #f5f8fa) 50%,
    var(--bs-gray-200, #e4e6ef) 75%);
  background-size: 200% 100%;
  animation: tip-skel-shimmer 1.4s ease-in-out infinite;
}

/* A little width variety so a skeleton row doesn't read as a solid grey
   block - purely cosmetic, keyed off column position. */
tr.tip-skel-row td:nth-child(3n+1) .tip-skel { max-width: 90px; }
tr.tip-skel-row td:nth-child(3n+2) .tip-skel { max-width: 150px; }
tr.tip-skel-row td:first-child .tip-skel { max-width: 24px; }

@keyframes tip-skel-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .tip-skel {
    animation: none;
    background: var(--bs-gray-200, #e4e6ef);
  }
}

/* First-load / reload flash: hide the default "Processing..." indicator
   while our skeleton rows are standing in for it. Only ever added to a
   table's DataTables wrapper while tip-loading.js has just shown skeleton
   rows for that table, so tables that never go through preXhr.dt (plain
   client-side DataTables, e.g. Pending Documents) are unaffected. */
.dt-container.tip-skel-on .dataTables_processing,
.dataTables_wrapper.tip-skel-on .dataTables_processing {
  display: none !important;
}

/* Phone card layout (tip-mobile-cards.js / tip-mobile-cards.css): skeleton
   rows are excluded from that script's column-role pass (they carry no
   data-mcard attributes), so they fall back to the generic "unattributed
   row" block styling. The card chrome itself (border/radius/shadow/padding)
   already applies to every <tr>, so this just stacks the bars inside it
   with breathing room instead of them touching edge-to-edge. */
@media (max-width: 575.98px) {
  table.tip-mcards tbody tr.tip-skel-row td {
    margin-bottom: .5rem;
  }
  table.tip-mcards tbody tr.tip-skel-row td:last-child {
    margin-bottom: 0;
  }
  table.tip-mcards tbody tr.tip-skel-row .tip-skel {
    max-width: none;
  }
}

/* ------------------------------------------------------------------ *
 * 4. Generic skeleton primitives - for cards/widgets whose content is
 *    filled by a JS fetch/ajax call rather than a DataTable (dashboard
 *    stat cards, list widgets, chat threads, chart areas). Reuses the
 *    shimmer keyframe above. Size a placeholder with inline style
 *    (height/width); these classes only set shape + shimmer.
 * ------------------------------------------------------------------ */

.tip-skel-block,
.tip-skel-line,
.tip-skel-circle {
  display: block;
  background: linear-gradient(90deg,
    var(--bs-gray-200, #e4e6ef) 25%,
    var(--bs-gray-100, #f5f8fa) 50%,
    var(--bs-gray-200, #e4e6ef) 75%);
  background-size: 200% 100%;
  animation: tip-skel-shimmer 1.4s ease-in-out infinite;
  flex-shrink: 0;
}

/* Generic block - a chart area, an avatar-sized tile, etc. Fill its size
   with inline height/width (or let it stretch via flex/grid). */
.tip-skel-block {
  width: 100%;
  height: 100%;
  border-radius: .6rem;
}

/* A single text-line placeholder. Default width suits a short label; pass
   an inline max-width/width to match the real content's shape. */
.tip-skel-line {
  width: 100%;
  max-width: 220px;
  height: 12px;
  border-radius: .5rem;
}

/* Avatar / icon circle placeholder. Default size matches a 40px avatar;
   override with inline width/height for other symbol sizes. */
.tip-skel-circle {
  width: 40px;
  height: 40px;
  border-radius: 50%;
}

/* Vertical stack of skeleton rows (list widgets, chat bubbles) - just
   adds even spacing between whatever skeleton pieces are placed inside. */
.tip-skel-stack > * + * {
  margin-top: 1rem;
}

@media (prefers-reduced-motion: reduce) {
  .tip-skel-block,
  .tip-skel-line,
  .tip-skel-circle {
    animation: none;
    background: var(--bs-gray-200, #e4e6ef);
  }
}
