/* J-1003-TYPING-WIN-ESCAPE (v2026.10.03.6-dev)
   1. On a win the sunlight vista (assets/win-sunlight-vista.webp) is the whole
      page background: fixed + cover behind everything, with a soft dark grade
      so the results card and score box stay readable. Fullscreen: the same
      layer on the fullscreen .app, which scrolls on the win screen.
   2. "You escaped the Dungeon!" winner banner, and the Fallen ribbon on
      Game Over: fixed to the viewport top so the results scroll under it.
      Reuses the
      treasure ribbon art and Cinzel lettering. Sparks (game.js winSparks),
      a light burst, glow pulses (<= 1.7 per second, banner area only, never
      full-screen) and a shine sweep. Reduced motion: static calm glow.
      pointer-events: none, so it never blocks a click.
   The old framed .win-vista panel becomes a clear window onto the background. */

/* ---- 1. full-page background ------------------------------------------- */
body[data-screen="win"]::before,
.app:fullscreen:has(#screen-win.active)::before {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(7,9,18,.30) 0%, rgba(7,9,18,.06) 22%, rgba(7,9,18,.16) 48%, rgba(7,9,18,.58) 78%, rgba(7,9,18,.74) 100%),
    radial-gradient(ellipse 125% 95% at 50% 32%, transparent 58%, rgba(0,0,0,.42) 100%),
    url("../assets/win-sunlight-vista.webp") center 38% / cover no-repeat,
    #2a2a24;
  animation: web-bg-reveal 2.2s ease-out both;
}
body[data-screen="win"] { background-color: #1a1b1c; }
.app:fullscreen:has(#screen-win.active) { overflow-x: hidden; overflow-y: auto; background: #1a1b1c; }
@keyframes web-bg-reveal { from { opacity: 0; transform: scale(1.05); } to { opacity: 1; transform: none; } }

/* the old framed picture becomes a clear window onto the sunlight */
body[data-screen="win"] .screen-win .win-vista {
  min-height: clamp(150px, 24vh, 340px);
  background: transparent; border-color: transparent; box-shadow: none; overflow: visible;
}
body[data-screen="win"] .screen-win .win-vista::before,
body[data-screen="win"] .screen-win .win-vista::after { display: none; }
/* glass results card: the sunlight still shows through behind the stats and the score box */
body[data-screen="win"] .screen-win .win-card {
  margin-top: -40px;
  background: linear-gradient(160deg, rgba(48,38,26,.50), rgba(16,24,38,.62) 54%, rgba(14,20,34,.76));
  -webkit-backdrop-filter: blur(7px) saturate(1.2); backdrop-filter: blur(7px) saturate(1.2);
}
#win-score-entry .score-entry, #win-score-entry input { scroll-margin-top: 220px; scroll-margin-bottom: 32px; }   /* header + pinned banner */

/* ---- 2. winner banner ---------------------------------------------------- */
.win-escape-banner {
  --web-h: clamp(70px, min(6.4vw, 12vh), 140px);
  --web-tail: calc(var(--web-h) * 1.48);
  --web-fs: calc(var(--web-h) * .31);
  position: fixed; top: 0; left: 0; right: 0; z-index: 80;
  display: flex; justify-content: center; align-items: center;
  height: calc(var(--web-h) + 18px); margin: 0; padding: 9px 0;
  pointer-events: none; user-select: none;
}
/* --web-h lives on the screen so the page padding matches the ribbon. */
body[data-screen="win"],
body[data-screen="over"] { --web-h: clamp(70px, min(6.4vw, 12vh), 140px); --end-banner-h: calc(var(--web-h) + 18px); }
body[data-screen="win"] .app,
body[data-screen="over"] .app { padding-top: calc(var(--end-banner-h) + 0.35rem); }
.win-escape-banner * { pointer-events: none; }
/* soft shade so the banner reads over the card once the page scrolls under it */
.win-escape-banner::before {
  content: ""; position: absolute; left: 50%; top: 0; width: 100vw; height: 100%; translate: -50% 0;
  background: linear-gradient(180deg, rgba(6,8,16,.72), rgba(6,8,16,.38) 70%, transparent);
  opacity: 1;
}

.web-ribbon { position: relative; z-index: 2; display: flex; justify-content: center; }
.web-plate {
  position: relative; z-index: 1; height: var(--web-h);
  display: flex; align-items: center; justify-content: center;
  border-style: solid; border-width: 0 var(--web-tail);
  border-image: url("../assets/treasure/reward/tr-ribbon.webp?v=2026.10.04.12") 0 222 fill / 0 var(--web-tail) stretch;
  filter: drop-shadow(0 10px 14px rgba(0,0,0,.55));
}
/* gold glow pulse behind the ribbon (opacity only) */
.web-glow {
  position: absolute; z-index: 0; inset: -46% calc(var(--web-tail) * .25);
  background: radial-gradient(ellipse 50% 50% at 50% 50%, rgba(255,226,140,.95), rgba(255,180,60,.5) 42%, rgba(255,160,40,0) 72%);
  opacity: .45; will-change: opacity;
}
.web-text {
  position: relative; display: block; white-space: nowrap;
  margin-top: calc(var(--web-h) * -.07); padding: 0 .35em;
  font: 600 var(--web-fs)/1.1 "Cinzel Lore", Georgia, serif; letter-spacing: .05em;
  color: #ffe39a;
  background: linear-gradient(180deg, #fffbe6 0%, #ffe7a0 38%, #f6bd4a 62%, #ffe8a8 100%);
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 2px 0 #3b0a05) drop-shadow(0 0 7px rgba(255,196,90,.75));
}
/* shine sweep across the lettering */
.web-text::after {
  content: attr(data-text); position: absolute; inset: 0; padding: 0 .35em;
  background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.95) 48%, rgba(255,255,240,.0) 58%) -120% 0 / 220% 100% no-repeat;
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  opacity: 0;
}
/* light burst behind the ribbon: existing reward rays, breathing */
.web-burst {
  position: absolute; z-index: 1; left: 50%; top: 50%; width: calc(var(--web-h) * 4.4); aspect-ratio: 1;
  translate: -50% -50%; opacity: 0; will-change: opacity;
  background: radial-gradient(circle, #fff6cf 0, #ffd36a 30%, rgba(255,190,70,.6) 55%, transparent 72%);
  -webkit-mask: url("../assets/treasure/reward/tr-rays.webp?v=2026.10.04.12") center / contain no-repeat;
  mask: url("../assets/treasure/reward/tr-rays.webp?v=2026.10.04.12") center / contain no-repeat;
}
.web-sparks { position: absolute; z-index: 3; left: 50%; top: 9px; height: var(--web-h); width: calc(100% - 0px); max-width: calc(var(--web-tail) * 2 + 24em); translate: -50% 0; }
.web-sparks i {
  position: absolute; left: var(--x); top: var(--y); width: var(--sz); height: var(--sz); opacity: 0;
  background: radial-gradient(circle, #fff 0 16%, #ffe48a 34%, #ffb83c 56%, transparent 72%);
  -webkit-mask: url("../assets/treasure/reward/tr-spark.webp?v=2026.10.04.12") center / contain no-repeat;
  mask: url("../assets/treasure/reward/tr-spark.webp?v=2026.10.04.12") center / contain no-repeat;
  will-change: transform, opacity;
}

/* on: entrance drop, two light flashes (0.6 s apart), then steady glow pulses */
.win-escape-banner.web-on .web-ribbon { animation: web-drop .75s cubic-bezier(.34,1.5,.64,1) both; }
.win-escape-banner.web-on .web-glow { animation: web-flash-in 1.25s ease-out both, web-glow 1.3s ease-in-out 1.25s infinite; }
.win-escape-banner.web-on .web-text::after { animation: web-shine 2.6s ease-in-out .9s infinite; }
.win-escape-banner.web-on .web-burst { animation: web-burst-in 1.1s ease-out both, web-rays 2.6s ease-in-out 1.1s infinite; }
.win-escape-banner.web-on .web-sparks i { animation: web-spark var(--dur) ease-out var(--del) infinite; }
/* after ~30 s (with the crowd gone quiet) keep a gentler idle */
.win-escape-banner.web-calm .web-glow { animation: web-glow 3.2s ease-in-out infinite; }
.win-escape-banner.web-calm .web-text::after { animation-duration: 6s; }
.win-escape-banner.web-calm .web-sparks i:nth-child(3n), .win-escape-banner.web-calm .web-sparks i:nth-child(3n+1) { display: none; }

@keyframes web-drop {
  0% { opacity: 0; transform: translateY(-70%) scale(.62); }
  60% { opacity: 1; }
  100% { opacity: 1; transform: none; }
}
@keyframes web-flash-in {        /* two flashes, 0.6 s apart: under 2 per second */
  0% { opacity: 0; }
  12% { opacity: 1; }
  34% { opacity: .35; }
  58% { opacity: 1; }
  100% { opacity: .5; }
}
@keyframes web-glow { 0%, 100% { opacity: .38; } 50% { opacity: .95; } }   /* ~0.8 per second */
@keyframes web-shine { 0% { opacity: 1; background-position: -120% 0; } 55%, 100% { opacity: 1; background-position: 220% 0; } }
@keyframes web-burst-in { 0% { opacity: 0; scale: .3; } 35% { opacity: .95; } 100% { opacity: .55; scale: 1; } }
@keyframes web-rays { 0%, 100% { opacity: .55; } 50% { opacity: .8; } }   /* rays breathe (opacity only; cheap on slow machines) */
@keyframes web-spark {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.2) rotate(0deg); }
  14% { opacity: 1; transform: translate(-50%, -50%) scale(1.05) rotate(calc(var(--rot) * .2)); }
  100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(.35) rotate(var(--rot)); }
}

@media (max-width: 700px) {
  body[data-screen="win"],
  body[data-screen="over"] { --web-h: 54px; }
  .win-escape-banner { --web-h: 54px; --web-tail: 66px; --web-fs: min(17px, 4.1vw); }
}
/* Reduced motion: no movement, no flashes, no sparks -- a calm, steady glow. */
@media (prefers-reduced-motion: reduce) {
  body[data-screen="win"]::before, .app:fullscreen:has(#screen-win.active)::before { animation: none; }
  .win-escape-banner, .win-escape-banner *, .win-escape-banner *::before, .win-escape-banner *::after { animation: none !important; transition: none !important; }
  .win-escape-banner .web-sparks { display: none; }
  .win-escape-banner.web-on .web-glow { opacity: .62; }
  .win-escape-banner.web-on .web-burst { opacity: .4; }
  .web-text::after { display: none; }
}
