/* CHIQUE Store Portal — Diwali decoration.
   Lives in its own file behind the FESTIVE_MODE flag so the season comes down with
   one setting and leaves no trace in app.css.

   A greeting ribbon under the top bar and two lamps hanging from the top of the
   window. The portal is a white, data-dense page, so the colour goes INTO the
   ribbon — a Diwali-night gradient carrying bright gold/rose/mint text — rather
   than onto the surfaces people read.

   Rules it follows:
     - ornamental only: aria-hidden, pointer-events:none, never intercepts a click
     - cannot widen the page (the ribbon clips its own overflow)
     - animates opacity/transform only, so it stays on the compositor
     - sits above the sticky topbar (50) but below the export menu (60), modals
       (100) and toasts (200) — a decoration must never cover a dialog
     - honours prefers-reduced-motion: the greeting stays, the motion stops
*/

:root {
  --diwali-gold: #ffd978;
  --diwali-rose: #ffc0db;
  --diwali-mint: #8ff0d2;
  --diwali-wire: rgba(255, 217, 120, .38);
  --diwali-thread: rgba(146, 64, 14, .5);
}

/* ── Greeting ribbon, directly under the top bar ─────────────────────── */
.festive-bar {
  position: relative;
  overflow: hidden;                 /* the marquee must never widen the page */
  isolation: isolate;
  /* A Diwali night: indigo at the edges through magenta to a deep ember in the
     middle. The ember stop is as hot as it can go and still carry the greeting
     at 4.5:1 — the text scrolls across every stop, so the darkest-text/lightest-
     background pair (rose on the ember, under the shine) is what sets it. */
  background: linear-gradient(
    90deg,
    #2d0b4e 0%, #4a1066 18%, #78124e 40%, #8a2214 58%, #78124e 78%, #2d0b4e 100%
  );
  border-bottom: 1px solid var(--diwali-wire);
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .28), 0 1px 12px rgba(45, 11, 78, .18);
}

/* A slow diagonal shine crossing the ribbon — the one "sparkle" in the design.
   It passes BEHIND the greeting (z-index 1, under .festive-marquee's 2): over the
   top it would veil the text as much as the background and cost more contrast
   than it costs here, where it only lifts the background. */
.festive-bar::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    105deg,
    transparent 38%,
    rgba(255, 255, 255, .05) 47%,
    rgba(255, 214, 138, .07) 52%,
    transparent 62%
  );
  transform: translate3d(-120%, 0, 0);
  animation: festive-sweep 9s ease-in-out infinite;
}
@keyframes festive-sweep {
  0% { transform: translate3d(-120%, 0, 0); }
  55%, 100% { transform: translate3d(120%, 0, 0); }
}

/* The fade at both ends lives on this static wrapper, NOT on the track: a mask on
   the track would travel with it and the fade would slide away. */
.festive-marquee {
  position: relative;
  z-index: 2;
  overflow: hidden;
  padding-top: 7px;                 /* clear the light string */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 80px, #000 calc(100% - 80px), transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 80px, #000 calc(100% - 80px), transparent 100%);
}

.festive-track {
  display: flex;
  width: max-content;
  animation: festive-roll 54s linear infinite;
}

/* Each group is at least a full viewport wide. That is what makes the -50%
   translate seamless: the track is exactly two groups, so when the first scrolls
   off, the second is already covering the screen. Without the min-width the track
   is only as wide as its text and leaves a blank gap on any desktop. */
.festive-group {
  flex: none;
  min-width: 100vw;
  display: flex;
  align-items: center;
  justify-content: space-around;
}

@keyframes festive-roll {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(-50%, 0, 0); }   /* -50% == exactly one group */
}

.festive-item {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  padding: 9px 26px 11px;
  white-space: nowrap;
  font-family: "Outfit", "Inter", system-ui, sans-serif;
  font-weight: 700;
  font-size: .9rem;
  letter-spacing: .02em;
  color: var(--diwali-gold);
  text-shadow: 0 0 14px rgba(255, 190, 90, .45), 0 1px 0 rgba(0, 0, 0, .35);
}
.festive-item svg { flex: none; }

/* Contrast against the ribbon, measured at every gradient stop: gold 6.66-12.17,
   rose 5.96-10.59, mint 6.71-12.26, and 4.68 at the very worst (rose on the ember
   stop with the shine crossing it). AA throughout. */
.festive-item.rose {
  color: var(--diwali-rose);
  text-shadow: 0 0 14px rgba(255, 120, 180, .45), 0 1px 0 rgba(0, 0, 0, .35);
}
.festive-item.mint {
  color: var(--diwali-mint);
  text-shadow: 0 0 14px rgba(80, 230, 190, .4), 0 1px 0 rgba(0, 0, 0, .35);
}

/* Devanagari: Outfit/Inter carry no glyphs, so name real fallbacks rather than
   leaving it to chance. Zero tracking — letter-spacing detaches matras. */
.festive-item.hi {
  font-family: "Noto Sans Devanagari", "Nirmala UI", "Mangal", "Inter", system-ui, sans-serif;
  letter-spacing: 0;
  font-size: 1rem;
}

/* ── String of lights along the top of the ribbon ────────────────────── */
.lightstring {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 11px;
  display: flex;
  justify-content: space-around;
  align-items: flex-start;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(180deg, var(--diwali-wire) 0 1px, transparent 1px);
}
.lightstring span {
  width: 6px;
  height: 6px;
  margin-top: 3px;
  border-radius: 50%;
  background: var(--c, #ffd166);
  /* static glow in the bulb's OWN colour; animating box-shadow would drop the
     whole string off the compositor and repaint every frame on a cheap phone */
  box-shadow: 0 0 7px 1.5px var(--c, #ffd166);
  opacity: .32;
  animation-name: bulb;
  animation-duration: 3.4s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  animation-delay: var(--d, 0s);     /* staggered: the string ripples, never blinks */
}
@keyframes bulb {
  0%, 100% { opacity: .28; }
  50% { opacity: .95; }
}

/* ── Two lamps hanging from the top of the window ────────────────────── */
/* FIXED, not absolute: they stay at the top of the screen and do not scroll away.
   This is a deliberate instruction from Aayush, not an oversight — an earlier
   version let them scroll off and he asked for them stationary.
   z-index 55: above the sticky topbar (50), below the export menu (60), the
   modal backdrop (100) and the toast (200). pointer-events:none throughout. */
.hangers {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 300px;
  z-index: 55;
  pointer-events: none;
  overflow: hidden;
}

.hanger {
  position: absolute;
  top: 0;
  pointer-events: none;              /* belt and braces over the inherited value */
  transform-origin: 50% 0;           /* swings from the thread, like a pendulum */
  animation: swing 7.6s ease-in-out infinite;
  filter: drop-shadow(0 6px 10px rgba(45, 11, 78, .18));
}
.hanger svg { display: block; margin: 0 auto; }

/* VERIFY (§6). Compact tier — every width from 1024px to 1559px. The portal's
   topbar padding is max(20px, (100vw - 1320px) / 2), so below 1560px the content
   starts at x=20 and there is no side margin to hang in at all. The geometry is
   therefore forced rather than chosen:
     - the box is 56px wide, so `left: -12` puts the 1px thread at x=16, just clear
       of the .logo box at x=20 — the only thing it would otherwise cross;
     - the lamp is scaled about its own top centre. It hangs CENTRED on that
       thread, so half of it sits left of the thread and the window edge clips it
       unless  scale*28 + swing  <=  threadX - 2.
       MEASURED in Chrome (left:-10 puts the thread at x=18, and the tightest
       .logo is x=20 at 1280/1024): the swing is +/-2.2deg about y=0, which moves
       the lamp's bottom by (84 + 72*scale) * sin(2.2) ~= 4.3px. Solving gives
       scale <= 0.415, so .40 is used. The 0.571 figure quoted in the original
       brief omitted the swing and clipped both lamps by ~1px at one extreme;
     - it hangs from y=84 to y≈126: over the ribbon band (72-122, decoration
       anyway) and the gutter above .container's first child (~148). The marquee
       is masked to transparent within 80px of each edge, so it covers no text.
   Scrolled, the lamps stay put, and their inner edge overlaps the outer padding
   of whatever card has scrolled under them. They never take a click. */
.hanger .thread {
  display: block;
  width: 1px;
  height: 84px;
  margin: 0 auto;
  background: linear-gradient(180deg, rgba(146, 64, 14, .06), var(--diwali-thread));
}
.hanger svg { transform: scale(.40); transform-origin: 50% 0; }
.hanger.l { left: -10px; }
.hanger.r { right: -10px; animation-duration: 8.4s; animation-delay: -2.2s; }

/* VERIFY (§6). Wide tier — past 1560px the topbar padding is (100vw-1320)/2 >= 120px,
   so the lamps come up to full size and hang their whole length in open margin. */
@media (min-width: 1560px) {
  .hanger .thread { height: 148px; }
  .hanger svg { transform: scale(1.28); }
  .hanger.l { left: 26px; }
  .hanger.r { right: 26px; }
}

/* Tablets and phones run the content edge to edge — nothing would fit. */
@media (max-width: 1023px) {
  .hangers { display: none; }
}

/* A slow pendulum — hanging, not spinning. The amplitude is small on purpose: the
   swing pivots at the TOP of the thread, so on the wide tier's 240px drop even
   2.2deg moves the lamp 9px, and anything livelier swings the compact lamps
   straight off the left edge of the window. */
@keyframes swing {
  0%, 100% { transform: rotate(-2.2deg); }
  50% { transform: rotate(2.2deg); }
}

/* the lamp's inner light breathes gently */
.lamp-glow { animation: lampglow 4.2s ease-in-out infinite; }
@keyframes lampglow {
  0%, 100% { opacity: .5; }
  50% { opacity: .95; }
}

/* diya flame flicker. transform-box: fill-box so the origin is the flame's own
   base — against the default view-box the flame lifts off the wick as it scales. */
.flame {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: flicker 2.6s ease-in-out infinite;
}
@keyframes flicker {
  0%, 100% { transform: scaleY(1); opacity: 1; }
  40% { transform: scaleY(1.12); opacity: .92; }
  70% { transform: scaleY(.95); opacity: 1; }
}

/* ── Let the existing starfield glow gently ──────────────────────────── */
/* opacity only — animating `filter` forces the topbar's backdrop-blur to
   recompute on every frame. */
.stars svg { animation: twinkle 5s ease-in-out infinite; }
.stars svg:nth-child(2) { animation-duration: 6.2s; animation-delay: -1.6s; }
.stars svg:nth-child(3) { animation-duration: 7s;   animation-delay: -3.1s; }
.stars svg:nth-child(4) { animation-duration: 5.6s; animation-delay: -.9s; }
.stars svg:nth-child(5) { animation-duration: 7.8s; animation-delay: -4.2s; }

@keyframes twinkle {
  0%, 100% { opacity: .3; }
  50% { opacity: .62; }
}

/* ── Login pages: the ribbon is in flow above a 100vh card, which would push the
      page into a scrollbar. Give the wrap the ribbon's height back. ────────
   MEASURED in Chrome at 1440/1024px on /login and /admin/login: the ribbon is
   52px, not the 50px the brief estimated. At 50px the login page gained a 2px
   scrollbar. */
.festive-bar + .hangers + .auth-wrap,
.festive-bar ~ .auth-wrap { min-height: calc(100vh - 52px); }

/* ── Accessibility / low-power ───────────────────────────────────────── */
/* app.css line ~345 blanket-kills animation globally under reduced motion with
   !important; these override it (higher specificity) to leave a readable,
   completely still ribbon rather than a marquee frozen mid-scroll. */
@media (prefers-reduced-motion: reduce) {
  .festive-track { animation: none !important; width: 100% !important; }
  .festive-group { min-width: 0 !important; flex: 1 !important; }
  .festive-group + .festive-group { display: none !important; }
  .festive-bar::after { display: none !important; }
  .hanger, .flame, .lamp-glow, .lightstring span, .stars svg { animation: none !important; }
  .lightstring span { opacity: .62 !important; }
  .stars svg { opacity: .45 !important; }
}

/* ── Small screens ───────────────────────────────────────────────────── */
@media (max-width: 640px) {
  .festive-item { font-size: .8rem; padding: 8px 16px 10px; gap: 8px; }
  .festive-item.hi { font-size: .9rem; }
  .festive-marquee {
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 32px, #000 calc(100% - 32px), transparent 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 32px, #000 calc(100% - 32px), transparent 100%);
  }
  .lightstring { height: 9px; }
}
