/* ==========================================================================
   loadperf.css - perceived speed, skeletons and image loading
   --------------------------------------------------------------------------
   Loaded after style.css. Everything here is ADDITIVE: no layout, grid,
   breakpoint or sizing rule is changed, so the site stays exactly as
   responsive as it was before.

   1. Skeleton placeholders for grids that fill themselves from the API.
   2. Fade + blur-up for content images.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Skeleton system
   The design language (soft orange fill + a light sweep) is taken from the
   existing mobile categories skeleton. Names are prefixed lp- so nothing
   collides with, or disturbs, the mc-* rules already in categories-mobile.css.
   -------------------------------------------------------------------------- */
.lp-skel {
  position: relative;
  overflow: hidden;
  background: var(--orange-100, #fdeada);
}
.lp-skel::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .65), transparent);
  transform: translateX(-100%);
  animation: lpSweep 1.4s ease-in-out infinite;
}
@keyframes lpSweep {
  100% { transform: translateX(100%); }
}

/* Dish-shaped placeholder: mirrors .dish-card (square art + body + price row)
   so the real cards land at the same height and nothing jumps. */
.lp-skel-card {
  background: #fff;
  border: 1px solid var(--orange-100, #fdeada);
  border-radius: 10px;
  overflow: hidden;
}
.lp-skel-art {
  aspect-ratio: 1 / 1;
  background: var(--orange-100, #fdeada);
}
.lp-skel-body {
  padding: .7rem .8rem .8rem;
  display: flex;
  flex-direction: column;
  gap: .5rem;
}
.lp-skel-line {
  display: block;
  height: .72rem;
  border-radius: 999px;
  background: var(--orange-100, #fdeada);
}
.lp-skel-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: .4rem;
  margin-top: .15rem;
}
.lp-skel-pill {
  flex: 0 0 auto;
  width: 62px;
  height: 1.55rem;
  border-radius: 999px;
  background: var(--orange-100, #fdeada);
}
.lp-skel-btn {
  flex: 0 0 auto;
  width: 58px;
  height: 1.9rem;
  border-radius: 999px;
  background: var(--orange-100, #fdeada);
}

/* Store-shaped placeholder: mirrors .hotel-card (avatar + stacked info). */
.lp-skel-hotel {
  background: #fff;
  border: 2px solid var(--orange-100, #fdeada);
  border-radius: 18px;
  padding: 1rem .9rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .65rem;
  text-align: center;
}
.lp-skel-avatar {
  width: 72px;
  height: 72px;
  flex-shrink: 0;
  border-radius: 14px;
  background: var(--orange-100, #fdeada);
}
.lp-skel-hotel .lp-skel-line { width: 70%; }
.lp-skel-hotel .lp-skel-line.short { width: 45%; }

/* Generic row placeholder for list-style tables (admin, vendor, rider). */
.lp-skel-row {
  height: 1.1rem;
  border-radius: 999px;
  background: var(--orange-100, #fdeada);
}

/* No min-height or sizing of any kind here on purpose: the placeholder cards
   already occupy exactly the space the real cards will take, so adding a
   viewport-based height would cause a shift the moment it is removed. Loading
   state is tracked purely by the data-skel attribute and aria-busy. */

/* --------------------------------------------------------------------------
   2. Image loading animation
   --------------------------------------------------------------------------
   The overlay is FULLY OPAQUE on purpose. A browser paints a progressive JPEG
   as it decodes - horizontal bands sweeping down the picture - and that
   banding is what people see as the ugly "default" loading effect. Nothing
   translucent can hide it, so this covers the image completely until the
   load has genuinely finished, then fades away to reveal the sharp photo.
   -------------------------------------------------------------------------- */

/* The wrapper becomes the positioning context for the overlay. It is added by
   script only, so nothing about the existing layout changes. */
.perf-media { position: relative; }

/* ::before was free on every one of these wrappers (.dish-art and .mart-art
   already use ::after for a gradient), and pointer-events:none keeps the card
   fully clickable underneath. */
.perf-loading::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-color: var(--orange-100, #fdeada);
  background-image: linear-gradient(90deg, transparent, rgba(255, 255, 255, .62), transparent);
  background-size: 200% 100%;
  background-repeat: no-repeat;
  animation: lpImgSweep 1.35s linear infinite;
  transition: opacity .45s ease;
}
/* Released on load: the cover fades and the photograph appears beneath it. */
.perf-loading.perf-releasing::before { opacity: 0; }

@keyframes lpImgSweep {
  from { background-position: 200% 0; }
  to   { background-position: -200% 0; }
}

/* Blur-up, revealed as the cover fades. Deliberately NOT opacity:0 on the
   image itself - the cover hides it instead, so a missed load event can never
   leave a blank hole in a card. */
.perf-img {
  filter: blur(12px);
  transform: scale(1.06);
  transition: filter .55s ease .1s, transform .6s cubic-bezier(.2, .7, .2, 1) .1s;
}
.perf-img.perf-done {
  filter: none;
  transform: none;
}



/* --------------------------------------------------------------------------
   3. Reduced motion / safety
   style.css already neutralises transitions globally, but the second rule
   matters more: a user who asked for less motion must never be left with an
   invisible image, so they simply render with no effect at all.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .lp-skel::after { animation: none; }
  .perf-loading::before { animation: none; }
  .perf-img {
    transition: none !important;
    filter: none;
    transform: none;
  }
}
