/* Easton - BS5 · Christmas window extravaganza
   Night-sky page, a terrace of 24 windows, one swinging open per day. Mobile first. */

@font-face {
  font-family: "Mountains of Christmas";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("assets/fonts/mountains-of-christmas-700.woff2") format("woff2");
}
@font-face {
  font-family: "Nunito";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("assets/fonts/nunito-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Nunito";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("assets/fonts/nunito-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --sky-top: #060b1f;
  --sky-mid: #0b1b3a;
  --sky-low: #1a2f5e;
  --cream: #fff6e0;
  --gold: #ffd23f;
  --gold-deep: #e0a010;
  --red: #d8232a;
  --red-deep: #8e0f16;
  --green: #1f8a3a;
  --green-deep: #0e5a23;
  --frame: #f6efe3;
  --frame-shadow: #c9bfae;
  --glow: #ffcf6a;
  --ink: #2a1b12;
  --paper: #fff8ea;
  --door-dur: 1.5s;
  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  font-family: "Nunito", system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--cream);
  background: linear-gradient(180deg, var(--sky-top) 0%, var(--sky-mid) 45%, var(--sky-low) 100%) fixed;
  background-color: var(--sky-mid);
  overflow-x: hidden;
  position: relative;
}
button { font: inherit; }

/* ---------- Sky ---------- */
.sky {
  position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden;
}
.stars, .stars-2 {
  position: absolute; inset: -10% 0 0 0;
  background-image:
    radial-gradient(1.5px 1.5px at 12% 18%, #fff 60%, transparent),
    radial-gradient(1px 1px at 28% 42%, #fff 60%, transparent),
    radial-gradient(1.5px 1.5px at 45% 9%, #fff 60%, transparent),
    radial-gradient(1px 1px at 63% 31%, #fff 60%, transparent),
    radial-gradient(2px 2px at 78% 14%, #fff 60%, transparent),
    radial-gradient(1px 1px at 88% 48%, #fff 60%, transparent),
    radial-gradient(1.5px 1.5px at 7% 62%, #fff 60%, transparent),
    radial-gradient(1px 1px at 36% 70%, #fff 60%, transparent),
    radial-gradient(1.5px 1.5px at 56% 56%, #fff 60%, transparent),
    radial-gradient(1px 1px at 71% 78%, #fff 60%, transparent),
    radial-gradient(1px 1px at 94% 84%, #fff 60%, transparent),
    radial-gradient(1.5px 1.5px at 19% 88%, #fff 60%, transparent);
  background-size: 420px 420px;
  opacity: .75;
  animation: twinkle 4s ease-in-out infinite alternate;
}
.stars-2 {
  background-position: 180px 110px;
  background-size: 560px 560px;
  opacity: .45;
  animation-duration: 6.5s;
  animation-delay: -2s;
}
@keyframes twinkle { from { opacity: .35; } to { opacity: .9; } }

.moon {
  position: absolute; top: calc(4px + var(--sat)); right: 4%;
  width: 46px; height: 46px; border-radius: 50%;
  background: transparent;
  box-shadow: -12px 7px 0 0 #fff4c8, 0 0 40px 10px rgba(255, 244, 200, .18);
  transform: rotate(-20deg);
}
@media (min-width: 760px) { .moon { top: calc(90px + var(--sat)); right: 8%; width: 60px; height: 60px; } }

.sleigh {
  position: absolute; top: calc(28px + var(--sat)); left: -300px;
  width: 260px; opacity: .85;
  animation: fly 48s linear infinite;
  animation-delay: 6s;
}
.sleigh svg { display: block; width: 100%; height: auto; }
@keyframes fly {
  0%   { transform: translate(0, 0) scale(.75); }
  2%   { transform: translate(0, 0) scale(.75); }
  30%  { transform: translate(calc(100vw + 320px), 40px) scale(.75); }
  100% { transform: translate(calc(100vw + 320px), 40px) scale(.75); }
}

#snow {
  position: fixed; inset: 0; z-index: 5; pointer-events: none; width: 100%; height: 100%;
}

/* ---------- Masthead ---------- */
.masthead {
  position: relative; z-index: 2;
  padding: calc(44px + var(--sat)) 16px 10px;
  text-align: center;
}
.lights {
  position: absolute; left: 0; right: 0; top: calc(var(--sat) - 2px); height: 70px;
}
.lights .wire {
  position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible;
}
.lights .wire path { fill: none; stroke: #1c2b14; stroke-width: 2.5; }
.bulb {
  position: absolute; width: 10px; height: 16px; margin-left: -5px;
  border-radius: 45% 45% 50% 50% / 35% 35% 65% 65%;
  background: var(--c);
  box-shadow: 0 0 8px 2px var(--c), 0 0 18px 4px color-mix(in srgb, var(--c) 45%, transparent);
  transform-origin: 50% 0;
  animation: glow 1.8s ease-in-out infinite alternate, sway 3.6s ease-in-out infinite alternate;
}
.bulb::before {
  content: ""; position: absolute; left: 2px; right: 2px; top: -5px; height: 6px;
  background: #2c3f21; border-radius: 2px 2px 0 0;
}
@keyframes glow {
  from { filter: brightness(.55); box-shadow: 0 0 3px 1px var(--c); }
  to   { filter: brightness(1.25); box-shadow: 0 0 10px 3px var(--c), 0 0 22px 6px color-mix(in srgb, var(--c) 45%, transparent); }
}
@keyframes sway { from { transform: rotate(-6deg); } to { transform: rotate(6deg); } }

.title {
  margin: 0; font-family: "Mountains of Christmas", "Nunito", cursive; font-weight: 700;
  font-size: clamp(2.6rem, 11vw, 4.6rem); line-height: 1.05; letter-spacing: .01em;
  display: inline-flex; align-items: center; justify-content: center; gap: .15em;
  color: var(--cream);
  text-shadow: 0 2px 0 #7a0e14, 0 4px 0 #5b0a0f, 0 8px 18px rgba(0,0,0,.55), 0 0 28px rgba(255, 210, 63, .35);
  animation: title-glow 3.2s ease-in-out infinite alternate;
}
.title-text { white-space: nowrap; }
.title .dash { color: var(--gold); text-shadow: 0 2px 0 #7a4b06, 0 0 18px rgba(255, 210, 63, .8); }
@keyframes title-glow {
  from { text-shadow: 0 2px 0 #7a0e14, 0 4px 0 #5b0a0f, 0 8px 18px rgba(0,0,0,.55), 0 0 18px rgba(255, 210, 63, .2); }
  to   { text-shadow: 0 2px 0 #7a0e14, 0 4px 0 #5b0a0f, 0 8px 18px rgba(0,0,0,.55), 0 0 36px rgba(255, 210, 63, .55); }
}
.holly { width: clamp(44px, 12vw, 76px); height: auto; flex: none; filter: drop-shadow(0 3px 4px rgba(0,0,0,.5)); }
.holly-l { animation: bob 3s ease-in-out infinite alternate; transform-origin: 100% 100%; }
.holly-r { transform: scaleX(-1); animation: bob-r 3s ease-in-out infinite alternate; animation-delay: -1.5s; transform-origin: 50% 100%; }
@keyframes bob { from { transform: rotate(-5deg) translateY(0); } to { transform: rotate(4deg) translateY(-3px); } }
@keyframes bob-r { from { transform: scaleX(-1) rotate(-5deg) translateY(0); } to { transform: scaleX(-1) rotate(4deg) translateY(-3px); } }

.subtitle {
  margin: 10px auto 0; font-size: clamp(.95rem, 3.6vw, 1.2rem); font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: #ffe9a8;
}
.subtitle span { display: inline-block; padding-bottom: 8px; position: relative; }
.subtitle span::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 5px; border-radius: 3px;
  background: repeating-linear-gradient(135deg, #fff 0 8px, var(--red) 8px 16px);
  box-shadow: 0 1px 3px rgba(0,0,0,.5);
  background-size: 200% 100%;
  animation: candy 2.4s linear infinite;
}
@keyframes candy { to { background-position: 22.6px 0; } }

/* ---------- Main ---------- */
main { position: relative; z-index: 2; max-width: 1080px; margin: 0 auto; padding: 8px 16px 24px; }

.status {
  text-align: center; margin: 10px auto 18px; padding: 12px 16px; max-width: 560px;
  background: rgba(255, 255, 255, .07); border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 16px; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.status p { margin: 0; }
.status-big { font-size: 1.15rem; font-weight: 800; }
.status-small { font-size: .95rem; opacity: .85; margin-top: 2px !important; }
.status-big .count { display: inline-block; color: var(--gold); animation: pop 1s cubic-bezier(.3, 1.6, .5, 1) both; }
@keyframes pop { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* The terrace: a brick wall holding 24 windows */
.calendar {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;
  padding: 16px 14px 18px; border-radius: 18px;
  background:
    linear-gradient(rgba(0,0,0,.18), rgba(0,0,0,.18)),
    repeating-linear-gradient(0deg, #7a3326 0 18px, #5a2219 18px 20px),
    #7a3326;
  background-blend-mode: normal;
  box-shadow: inset 0 0 0 2px rgba(0,0,0,.25), 0 20px 50px rgba(0,0,0,.45);
  position: relative;
}
.calendar::before {
  /* mortar: offset brick courses */
  content: ""; position: absolute; inset: 0; border-radius: 18px; pointer-events: none;
  background:
    repeating-linear-gradient(90deg, transparent 0 46px, rgba(70, 25, 18, .9) 46px 48px);
  background-size: 96px 40px;
  -webkit-mask: repeating-linear-gradient(0deg, #000 0 18px, transparent 18px 20px, transparent 20px 20px, #000 20px 20px);
  mask: repeating-linear-gradient(0deg, #000 0 18px, transparent 18px 20px);
  opacity: .5;
}
.calendar::after {
  /* snow along the top of the wall */
  content: ""; position: absolute; left: 6px; right: 6px; top: -6px; height: 12px; border-radius: 10px;
  background: #fff; box-shadow: 0 2px 2px rgba(0,0,0,.2);
  -webkit-mask: radial-gradient(10px 8px at 10px 10px, #000 70%, transparent 72%) 0 0/20px 12px repeat-x;
  mask: radial-gradient(10px 8px at 10px 10px, #000 70%, transparent 72%) 0 0/20px 12px repeat-x;
}
@media (min-width: 480px) { .calendar { grid-template-columns: repeat(4, 1fr); gap: 14px; padding: 18px; } }
@media (min-width: 760px) { .calendar { grid-template-columns: repeat(6, 1fr); gap: 16px; padding: 22px; } }

.door {
  all: unset; display: block; position: relative; cursor: pointer; -webkit-tap-highlight-color: transparent;
  /* earlier windows paint above later ones, so an opened panel tucks behind its left-hand neighbour */
  z-index: calc(30 - var(--i));
  animation: arrive .6s cubic-bezier(.2, 1.2, .4, 1) both;
  animation-delay: calc(var(--i) * 35ms);
}
@keyframes arrive { from { opacity: 0; transform: translateY(14px) scale(.92); } to { opacity: 1; transform: none; } }
.door:focus-visible .frame { outline: 3px solid var(--gold); outline-offset: 3px; }
.door:active .frame { transform: scale(.97); }

.frame {
  position: relative; aspect-ratio: 4 / 5; border-radius: 42% 42% 8px 8px / 26% 26% 8px 8px;
  border: 6px solid var(--frame);
  background: #2a1a12;
  box-shadow: 0 0 0 2px var(--frame-shadow), 0 8px 18px rgba(0,0,0,.45), inset 0 0 0 1px rgba(0,0,0,.4);
  perspective: 700px; transform-style: preserve-3d;
  transition: transform .15s ease, box-shadow .6s ease;
  overflow: visible;
}
.frame::after {
  /* window sill */
  content: ""; position: absolute; left: -12px; right: -12px; bottom: -14px; height: 9px;
  background: var(--frame); border-radius: 3px; box-shadow: 0 3px 4px rgba(0,0,0,.4);
}

/* inside the window: warm light + address */
.inside {
  position: absolute; inset: 0; overflow: hidden; border-radius: inherit;
  background: radial-gradient(ellipse at 50% 35%, #fff2c2 0%, #ffd56b 40%, #f29a1c 78%, #b55e07 100%);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  padding: 8px 6px 8px; text-align: center; color: var(--ink);
}
.inside::before {
  /* glazing bars */
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(90deg, transparent calc(50% - 2px), rgba(120, 70, 20, .35) calc(50% - 2px), rgba(120, 70, 20, .35) calc(50% + 2px), transparent calc(50% + 2px)),
    linear-gradient(0deg, transparent calc(50% - 2px), rgba(120, 70, 20, .35) calc(50% - 2px), rgba(120, 70, 20, .35) calc(50% + 2px), transparent calc(50% + 2px));
}
.inside-n {
  font-family: "Mountains of Christmas", cursive; font-weight: 700; font-size: 1.5rem; line-height: 1;
  color: var(--red-deep); text-shadow: 0 1px 0 #fff;
}
.addr {
  font-size: .72rem; font-weight: 800; line-height: 1.2; position: relative; z-index: 1;
  background: rgba(255, 252, 240, .88); border-radius: 6px; padding: 4px 5px;
  box-shadow: 0 1px 2px rgba(0,0,0,.25); max-width: 100%;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.addr.tbc { font-weight: 600; font-style: italic; opacity: .8; }
@media (min-width: 480px) { .addr { font-size: .78rem; } .inside-n { font-size: 1.7rem; } }
@media (min-width: 760px) { .addr { font-size: .86rem; } }

/* the shutter/door that swings open */
.panel {
  position: absolute; inset: 0; border-radius: inherit;
  transform-origin: 0% 50%; transform-style: preserve-3d;
  transition: transform var(--door-dur) cubic-bezier(.55, -.15, .3, 1.1);
  will-change: transform;
}
.door.open .panel { transform: rotateY(-104deg); }
.no-anim .panel { transition: none !important; }
.face {
  position: absolute; inset: 0; border-radius: inherit; backface-visibility: hidden; -webkit-backface-visibility: hidden;
}
.face.front {
  background: linear-gradient(145deg, var(--c1) 0%, var(--c2) 100%);
  box-shadow: inset 0 0 0 3px rgba(255,255,255,.12), inset 0 -8px 16px rgba(0,0,0,.25);
  display: flex; align-items: center; justify-content: center;
}
.face.front::before {
  /* raised door panels */
  content: ""; position: absolute; inset: 14% 16% 10%; border-radius: 6px;
  border: 2px solid rgba(0,0,0,.22); box-shadow: inset 0 0 0 2px rgba(255,255,255,.1);
}
.face.back {
  transform: rotateY(180deg);
  background: linear-gradient(145deg, color-mix(in srgb, var(--c2) 70%, black) 0%, color-mix(in srgb, var(--c1) 60%, black) 100%);
}
.wreath {
  position: relative; width: 58%; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle, var(--gold) 0 52%, var(--gold-deep) 53% 60%, transparent 61%);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 3px 6px rgba(0,0,0,.35);
}
.wreath::before {
  content: ""; position: absolute; inset: -9%; border-radius: 50%;
  border: 6px solid var(--green);
  box-shadow: inset 0 0 0 2px var(--green-deep);
}
.wreath::after {
  /* bow */
  content: ""; position: absolute; top: -16%; left: 50%; width: 30%; height: 18%; transform: translateX(-50%);
  background: var(--red); border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
  box-shadow: inset 0 0 0 2px var(--red-deep);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 60%, 0 100%);
}
.num {
  font-family: "Mountains of Christmas", cursive; font-weight: 700; font-size: clamp(1.6rem, 7vw, 2.3rem); line-height: 1;
  color: var(--red-deep); text-shadow: 0 1px 0 #fff3c0;
}
@media (min-width: 480px) { .num { font-size: 2.1rem; } }

/* colour themes for shut doors */
.theme-0 { --c1: #e53a3f; --c2: #9b1118; }
.theme-1 { --c1: #2f9d4e; --c2: #0f5a26; }
.theme-2 { --c1: #3f7fd6; --c2: #163e86; }
.theme-3 { --c1: #c73a7b; --c2: #6b123f; }

/* opened: the window glows out onto the street */
.door.open .frame { box-shadow: 0 0 0 2px var(--frame-shadow), 0 8px 18px rgba(0,0,0,.45), 0 0 26px 6px rgba(255, 207, 106, .45); }
.door.open .inside::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(circle at 50% 40%, rgba(255,255,255,.35), transparent 60%);
  animation: flicker 2.8s ease-in-out infinite alternate;
}
@keyframes flicker { from { opacity: .5; } 60% { opacity: .9; } to { opacity: .65; } }

/* today */
.door.today .frame { animation: today-pulse 2.2s ease-in-out infinite; }
@keyframes today-pulse {
  0%, 100% { box-shadow: 0 0 0 2px var(--frame-shadow), 0 8px 18px rgba(0,0,0,.45), 0 0 0 3px rgba(255, 210, 63, .25), 0 0 18px 4px rgba(255, 210, 63, .35); }
  50%      { box-shadow: 0 0 0 2px var(--frame-shadow), 0 8px 18px rgba(0,0,0,.45), 0 0 0 5px rgba(255, 210, 63, .5), 0 0 34px 10px rgba(255, 210, 63, .55); }
}
.ribbon {
  position: absolute; top: -8px; right: -8px; z-index: 3;
  background: var(--red); color: #fff; font-size: .62rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  padding: 4px 8px; border-radius: 999px; box-shadow: 0 2px 6px rgba(0,0,0,.4);
  transform: rotate(8deg); animation: ribbon-bounce 1.6s ease-in-out infinite alternate;
}
@keyframes ribbon-bounce { from { transform: rotate(8deg) translateY(0); } to { transform: rotate(10deg) translateY(-3px); } }

/* a shut window being knocked on */
.door.wobble .frame { animation: wobble .55s ease-in-out; }
@keyframes wobble {
  0%, 100% { transform: translateX(0) rotate(0); }
  20% { transform: translateX(-5px) rotate(-2deg); }
  40% { transform: translateX(5px) rotate(2deg); }
  60% { transform: translateX(-4px) rotate(-1.5deg); }
  80% { transform: translateX(3px) rotate(1deg); }
}

.hint { text-align: center; font-size: .9rem; opacity: .8; margin: 18px auto 0; max-width: 460px; }

.install { text-align: center; margin: 18px 0 0; }
.btn {
  all: unset; cursor: pointer; display: inline-block; padding: 10px 18px; border-radius: 999px;
  background: var(--red); color: #fff; font-weight: 800; box-shadow: 0 4px 12px rgba(0,0,0,.4), inset 0 0 0 2px rgba(255,255,255,.2);
}
.btn:active { transform: translateY(1px); }
.btn-small { padding: 4px 10px; font-size: .8rem; }
.ios-hint { font-size: .85rem; opacity: .85; margin: 8px auto 0; max-width: 360px; }

.foot { position: relative; z-index: 2; text-align: center; font-size: .8rem; padding: 10px 16px 0; }
.foot p { opacity: .7; margin: 0 0 12px; }
.powered {
  display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px 6px 8px; border-radius: 999px;
  color: var(--cream); text-decoration: none; font-size: .82rem; letter-spacing: .02em;
  background: rgba(255, 255, 255, .07); border: 1px solid rgba(255, 255, 255, .16);
  transition: background .2s ease, border-color .2s ease;
}
.powered:hover, .powered:focus-visible { background: rgba(255, 255, 255, .13); border-color: rgba(242, 183, 5, .6); }
.powered img { width: 28px; height: 28px; filter: drop-shadow(0 0 6px rgba(242, 183, 5, .55)); animation: star-glow 3s ease-in-out infinite alternate; }
.powered strong { font-weight: 800; color: #ffe9a8; }
@keyframes star-glow { from { filter: drop-shadow(0 0 3px rgba(242, 183, 5, .3)); } to { filter: drop-shadow(0 0 9px rgba(242, 183, 5, .8)); } }

/* ---------- Skyline ---------- */
.skyline {
  position: relative; z-index: 1; display: block; width: 100%; height: 150px; margin-top: 10px;
  padding-bottom: var(--sab);
}
.skyline .win { fill: #ffd56b; opacity: .1; }
.skyline .win.lit { opacity: .95; animation: win-flicker 4s ease-in-out infinite alternate; animation-delay: var(--d); }
@keyframes win-flicker { 0%, 70% { opacity: .95; } 80% { opacity: .55; } 100% { opacity: .9; } }
.skyline .puff { fill: rgba(255,255,255,.35); animation: puff 5s ease-out infinite; animation-delay: var(--d); transform-box: fill-box; transform-origin: center bottom; }
@keyframes puff {
  0% { opacity: 0; transform: translateY(0) scale(.4); }
  20% { opacity: .5; }
  100% { opacity: 0; transform: translateY(-50px) scale(1.8); }
}

/* ---------- Sparkles ---------- */
.fx { position: fixed; inset: 0; z-index: 30; pointer-events: none; overflow: hidden; }
.spark {
  position: absolute; width: 8px; height: 8px; border-radius: 50%; background: var(--c, var(--gold));
  box-shadow: 0 0 8px 2px var(--c, var(--gold));
  animation: spark .95s cubic-bezier(.2, .8, .3, 1) forwards;
}
.spark.star {
  border-radius: 0; background: var(--c, #fff); box-shadow: none;
  clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
  width: 12px; height: 12px;
}
@keyframes spark {
  0%   { transform: translate(-50%, -50%) scale(.3); opacity: 1; }
  60%  { opacity: 1; }
  100% { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1.1) rotate(160deg); opacity: 0; }
}

/* ---------- Detail sheet ---------- */
.sheet-backdrop {
  position: fixed; inset: 0; z-index: 40; background: rgba(3, 6, 18, .6);
  opacity: 0; transition: opacity .3s ease; backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
}
.sheet-backdrop.show { opacity: 1; }
.sheet {
  position: fixed; left: 50%; bottom: 0; z-index: 41; width: min(100%, 560px);
  transform: translate(-50%, 110%);
  transition: transform .45s cubic-bezier(.2, 1.1, .3, 1);
  background: var(--paper); color: var(--ink); border-radius: 22px 22px 0 0;
  padding: 18px 20px calc(22px + var(--sab)); box-shadow: 0 -10px 40px rgba(0,0,0,.5);
  max-height: 88vh; max-height: 88dvh; overflow: auto;
}
.sheet.show { transform: translate(-50%, 0); }
.sheet-stripe {
  position: absolute; left: 0; right: 0; top: 0; height: 10px; border-radius: 22px 22px 0 0;
  background: repeating-linear-gradient(135deg, #fff 0 10px, var(--red) 10px 20px, #fff 20px 30px, var(--green) 30px 40px);
}
.sheet-close {
  all: unset; cursor: pointer; position: absolute; top: 16px; right: 16px; width: 36px; height: 36px;
  border-radius: 50%; background: rgba(0,0,0,.07); text-align: center; line-height: 36px; font-size: 1.5rem; color: #6b5a4a;
}
.sheet-head { display: flex; align-items: center; gap: 14px; margin-top: 8px; }
.sheet-num {
  flex: none; width: 56px; height: 56px; border-radius: 50%;
  background: radial-gradient(circle, var(--gold) 0 60%, var(--gold-deep) 61% 70%, var(--green) 71%);
  display: grid; place-items: center; font-family: "Mountains of Christmas", cursive; font-weight: 700; font-size: 1.9rem; color: var(--red-deep);
  box-shadow: 0 3px 8px rgba(0,0,0,.25);
}
.sheet-title { margin: 0; font-family: "Mountains of Christmas", cursive; font-size: 2rem; line-height: 1; color: var(--red-deep); }
.sheet-date { margin: 2px 0 0; font-weight: 700; color: #7a6a58; }
.sheet-label { margin: 18px 0 2px; font-size: .8rem; letter-spacing: .12em; text-transform: uppercase; color: #7a6a58; font-weight: 800; }
.sheet-address { margin: 0; font-size: 1.5rem; font-weight: 800; line-height: 1.2; }
.sheet-address.tbc { font-size: 1.1rem; font-weight: 600; font-style: italic; color: #7a6a58; }
.sheet-map { display: inline-block; margin-top: 8px; color: #0f5a26; font-weight: 800; text-decoration: none; border-bottom: 2px solid #2aa84a; }
.sheet-fact {
  margin-top: 18px; padding: 14px 16px; border-radius: 14px;
  background: #fff0d6; border: 1px dashed #e0a010;
}
.sheet-fact-title { margin: 0 0 4px; font-family: "Mountains of Christmas", cursive; font-size: 1.4rem; color: #0f5a26; }
.sheet-fact-text { margin: 0; line-height: 1.5; }

/* ---------- Daily full-screen scenes (scenes.js) ---------- */
.scene {
  position: fixed; inset: 0; z-index: 38; overflow: hidden; cursor: pointer;
  background: radial-gradient(ellipse at 50% 30%, #1a2f5e, #060b1f 70%);
  opacity: 0; transition: opacity .4s ease;
}
.scene.show { opacity: 1; }
.scene canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.scene-layer { position: absolute; inset: 0; overflow: hidden; }
.sp {
  position: absolute; transform: translate(-50%, -50%); line-height: 1; white-space: nowrap;
  user-select: none; -webkit-user-select: none; will-change: transform;
  animation-fill-mode: both; animation-timing-function: ease-in-out;
  animation-delay: var(--d, 0ms); animation-duration: var(--dur, 2000ms);
}
.scene-text {
  position: absolute; left: 16px; right: 16px; bottom: 16%; margin: 0; text-align: center;
  font-family: "Mountains of Christmas", cursive; font-weight: 700; font-size: clamp(2rem, 8.5vw, 3.8rem); line-height: 1.1;
  color: var(--cream); text-shadow: 0 2px 0 #7a0e14, 0 6px 18px rgba(0,0,0,.6), 0 0 30px rgba(255, 210, 63, .5);
  opacity: 0; transform: scale(.6); transition: opacity .5s ease, transform .6s cubic-bezier(.2, 1.4, .4, 1);
  pointer-events: none;
}
.scene-text.show { opacity: 1; transform: scale(1); }
.scene-text.small { font-size: clamp(1.5rem, 6.5vw, 2.8rem); }
.scene-text.dark { color: #1e2a4a; text-shadow: 0 2px 0 #fff, 0 6px 18px rgba(0,0,0,.25); }
.scene-text.soft { font-weight: 400; color: #dfe9ff; text-shadow: 0 0 24px rgba(191, 233, 255, .7); }
.scene-skip { position: absolute; left: 0; right: 0; bottom: calc(14px + var(--sab)); margin: 0; text-align: center; font-size: .8rem; color: rgba(255,255,255,.6); pointer-events: none; }

/* sprite movements */
.a-flyLR { animation-name: flyLR; animation-timing-function: linear; }
@keyframes flyLR {
  0%   { transform: translate(calc(-50% - 62vw), -50%); }
  25%  { transform: translate(calc(-50% - 31vw), calc(-50% - 3vh)); }
  50%  { transform: translate(-50%, -50%); }
  75%  { transform: translate(calc(-50% + 31vw), calc(-50% - 3vh)); }
  100% { transform: translate(calc(-50% + 62vw), -50%); }
}
.a-flyRL { animation-name: flyRL; animation-timing-function: linear; }
@keyframes flyRL {
  0%   { transform: translate(calc(-50% + 62vw), -50%); }
  25%  { transform: translate(calc(-50% + 31vw), calc(-50% - 3vh)); }
  50%  { transform: translate(-50%, -50%); }
  75%  { transform: translate(calc(-50% - 31vw), calc(-50% - 3vh)); }
  100% { transform: translate(calc(-50% - 62vw), -50%); }
}
.a-walk { animation-name: flyRL; animation-timing-function: steps(30); }
.a-roll { animation-name: roll; animation-timing-function: linear; }
@keyframes roll { 0% { transform: translate(calc(-50% - 62vw), -50%) rotate(0); } 100% { transform: translate(calc(-50% + 62vw), -50%) rotate(1080deg); } }
.a-rise { animation-name: rise; animation-timing-function: linear; }
@keyframes rise {
  0%   { transform: translate(-50%, -50%); opacity: 0; }
  12%  { opacity: 1; }
  100% { transform: translate(calc(-50% + var(--sx, 0px)), calc(-50% - 90vh)) rotate(12deg); opacity: 0; }
}
.a-fall { animation-name: fall; animation-timing-function: ease-in; }
@keyframes fall { 0% { transform: translate(-50%, -50%) rotate(0); } 100% { transform: translate(-50%, calc(-50% + var(--dy, 120vh))) rotate(300deg); } }
.a-spinfall { animation-name: spinfall; animation-timing-function: linear; }
@keyframes spinfall { 0% { transform: translate(-50%, calc(-50% - 20vh)) rotate(0); } 100% { transform: translate(calc(-50% - 10vw), calc(-50% + 80vh)) rotate(540deg); } }
.a-drop { animation-name: drop; animation-timing-function: cubic-bezier(.3, .9, .5, 1); }
@keyframes drop {
  0%   { transform: translate(-50%, calc(-50% - 120vh)); }
  55%  { transform: translate(-50%, -50%); }
  70%  { transform: translate(-50%, calc(-50% - 7vh)); }
  85%  { transform: translate(-50%, -50%); }
  93%  { transform: translate(-50%, calc(-50% - 2vh)); }
  100% { transform: translate(-50%, -50%); }
}
.a-pop { animation-name: popin; animation-duration: 700ms; animation-timing-function: cubic-bezier(.2, 1.4, .4, 1); }
@keyframes popin { 0% { transform: translate(-50%, -50%) scale(0) rotate(-12deg); opacity: 0; } 100% { transform: translate(-50%, -50%) scale(1); opacity: 1; } }
.a-pulse { animation-name: pulse; animation-duration: 1.4s; animation-iteration-count: infinite; animation-direction: alternate; }
@keyframes pulse { from { transform: translate(-50%, -50%) scale(.85); opacity: .8; } to { transform: translate(-50%, -50%) scale(1.15); opacity: 1; } }
.a-swing { animation-name: swing; animation-iteration-count: infinite; animation-direction: alternate; transform-origin: 50% 0; }
@keyframes swing { from { transform: translate(-50%, -50%) rotate(-24deg); } to { transform: translate(-50%, -50%) rotate(24deg); } }
.a-float { animation-name: floaty; animation-duration: 2.2s; animation-iteration-count: infinite; animation-direction: alternate; }
@keyframes floaty { from { transform: translate(-50%, -50%); } to { transform: translate(-50%, calc(-50% - 12px)); } }
.a-bounce { animation-name: bouncy; animation-duration: .7s; animation-iteration-count: infinite; animation-direction: alternate; animation-timing-function: ease-out; }
@keyframes bouncy { from { transform: translate(-50%, -50%) scale(1, 1); } to { transform: translate(-50%, calc(-50% - 50px)) scale(.96, 1.04); } }
.a-launch { animation-name: launch; animation-timing-function: ease-in; }
@keyframes launch { 0% { transform: translate(calc(-50% - 60vw), calc(-50% + 42vh)); } 100% { transform: translate(calc(-50% + 65vw), calc(-50% - 55vh)); } }
.a-blip { animation-name: blip; animation-timing-function: linear; }
@keyframes blip { 0% { transform: translate(calc(-50% - 105px), calc(-50% + 20px)); } 100% { transform: translate(calc(-50% + 105px), calc(-50% - 30px)); } }
.a-arc { animation-name: arc; animation-timing-function: linear; }
@keyframes arc {
  0%   { transform: translate(calc(-50% - 46vw), calc(-50% + 12vh)); }
  50%  { transform: translate(-50%, calc(-50% - 34vh)); }
  100% { transform: translate(calc(-50% + 46vw), calc(-50% + 12vh)); }
}
.a-fadeout { animation-name: fadeout; animation-timing-function: linear; }
@keyframes fadeout { from { opacity: 1; } to { opacity: 0; } }
.a-lighton { animation-name: lighton, blinkx; animation-duration: .35s, 1.6s; animation-iteration-count: 1, infinite; animation-direction: normal, alternate; animation-delay: var(--d), calc(var(--d) + .35s); }
@keyframes lighton { from { transform: translate(-50%, -50%) scale(.6); filter: brightness(.2); } to { transform: translate(-50%, -50%) scale(1); filter: brightness(1.2); } }
@keyframes blinkx { from { filter: brightness(.7); } to { filter: brightness(1.4); } }

/* CSS-drawn props (sized by the sprite's font-size: 1em = sprite size) */
.candle { display: block; position: relative; width: .22em; height: .6em; margin-top: .3em; border-radius: .04em; background: linear-gradient(90deg, #e9d7b8, #fff5e1 40%, #d9c3a0); box-shadow: inset 0 -.1em .1em rgba(0,0,0,.15), 0 .05em .1em rgba(0,0,0,.4); }
.candle::after { content: ""; position: absolute; left: 50%; top: -.06em; width: .03em; height: .08em; background: #333; transform: translateX(-50%); }
.candle b { position: absolute; left: 50%; top: -.26em; width: .16em; height: .26em; border-radius: 50% 50% 45% 45% / 70% 70% 30% 30%; background: radial-gradient(ellipse at 50% 80%, #fff 0, #ffd23f 35%, #ff7a1a 75%, transparent 78%); transform: translateX(-50%) scale(0); transform-origin: 50% 100%; opacity: 0; transition: transform .4s cubic-bezier(.2, 1.4, .4, 1), opacity .3s; }
.candle.lit b { opacity: 1; transform: translateX(-50%) scale(1); animation: flame .25s ease-in-out infinite alternate; box-shadow: 0 0 .3em .1em rgba(255, 190, 60, .6), 0 0 .8em .3em rgba(255, 150, 30, .3); }
@keyframes flame { from { transform: translateX(-50%) scale(1, 1) rotate(-3deg); } to { transform: translateX(-50%) scale(.9, 1.12) rotate(4deg); } }

.ring { display: block; width: 1em; height: 1em; border-radius: 50%; border: .15em solid; border-color: #ffe9a8 #c58a06 #ffd23f #e0a010; box-shadow: 0 0 .3em rgba(255,210,63,.8), inset 0 0 .08em rgba(0,0,0,.3); animation: ringspin 1.1s ease-in-out infinite alternate; animation-delay: calc(var(--d) * -1); }
@keyframes ringspin { from { transform: rotateY(-55deg); } to { transform: rotateY(55deg); } }

.bauble { display: block; width: 1em; height: 1em; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff 0, var(--c) 20%, color-mix(in srgb, var(--c) 55%, black) 100%); box-shadow: 0 .1em .25em rgba(0,0,0,.5); position: relative; }
.bauble::before { content: ""; position: absolute; left: 50%; bottom: 100%; width: .06em; height: 200vh; background: #cfcfcf; transform: translateX(-50%); }
.bauble::after { content: ""; position: absolute; left: 50%; top: -.12em; width: .24em; height: .14em; background: #d9b24c; border-radius: .03em; transform: translateX(-50%); }

.card { display: block; position: relative; width: 1.5em; height: 1.1em; perspective: 800px; }
.card b { position: absolute; inset: 0; border-radius: .05em; }
.card .inner { background: #fff8ea; color: #8e0f16; font-family: "Mountains of Christmas", cursive; font-size: .22em; line-height: 1.1; display: grid; place-items: center; text-align: center; box-shadow: 0 .1em .4em rgba(0,0,0,.5); border: .04em solid #e0a010; }
.card .cover { background: linear-gradient(135deg, #d8232a, #8e0f16); display: grid; place-items: center; font-size: .5em; transform-origin: left center; animation: cardopen 1.4s cubic-bezier(.4, 0, .3, 1) .9s both; backface-visibility: hidden; box-shadow: 0 .05em .3em rgba(0,0,0,.5); border: .04em solid #ffd23f; }
@keyframes cardopen { from { transform: rotateY(0); } to { transform: rotateY(-165deg); } }

.pud { display: block; position: relative; width: 1em; height: .78em; border-radius: 50% 50% 46% 46% / 55% 55% 45% 45%; background: radial-gradient(ellipse at 40% 35%, #7a4a2a, #3d2214 70%); box-shadow: 0 .1em .3em rgba(0,0,0,.5); }
.pud::before { content: ""; position: absolute; left: 8%; right: 8%; top: 0; height: .4em; background: radial-gradient(ellipse at 50% 0, #fff 0 60%, #f0e6d8 100%); border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%; clip-path: polygon(0 0, 100% 0, 100% 55%, 88% 85%, 76% 60%, 62% 95%, 50% 65%, 38% 90%, 24% 60%, 12% 80%, 0 55%); }
.pud u { position: absolute; left: 50%; top: -.1em; transform: translateX(-50%); font-size: .3em; text-decoration: none; }
.pud .fl { position: absolute; bottom: 70%; width: .18em; height: .42em; border-radius: 50% 50% 30% 30% / 70% 70% 30% 30%; background: linear-gradient(180deg, transparent 0, #5ac8ff 35%, #d7f2ff 100%); opacity: .85; transform-origin: 50% 100%; animation: flame .22s ease-in-out infinite alternate; filter: blur(.5px); }
.pud .fl:nth-child(1) { left: 18%; animation-delay: -.1s; } .pud .fl:nth-child(2) { left: 38%; height: .55em; } .pud .fl:nth-child(3) { left: 58%; animation-delay: -.15s; } .pud .fl:nth-child(4) { left: 74%; height: .36em; animation-delay: -.05s; }

.tree { display: block; position: relative; width: 1em; height: 1em; }
.tree b { position: absolute; left: 50%; width: 1em; transform: translateX(-50%) scaleY(0); transform-origin: 50% 100%; background: linear-gradient(180deg, #2f9d4e, #0f5a26); clip-path: polygon(50% 0, 100% 100%, 0 100%); animation: grow .6s cubic-bezier(.2, 1.2, .4, 1) both; }
.tree b:nth-child(1) { top: 42%; height: .58em; animation-delay: .1s; }
.tree b:nth-child(2) { top: 22%; height: .5em; width: .82em; animation-delay: .45s; }
.tree b:nth-child(3) { top: 4%; height: .42em; width: .62em; animation-delay: .8s; }
.tree s { position: absolute; left: 50%; bottom: -.08em; width: .14em; height: .14em; background: #5a3a1e; transform: translateX(-50%); }
.tree.tall { width: .7em; } .tree.tall b { width: .7em; } .tree.tall b:nth-child(2) { width: .56em; } .tree.tall b:nth-child(3) { width: .42em; }
.tree u { position: absolute; width: .07em; height: .07em; border-radius: 50%; background: var(--c); box-shadow: 0 0 .08em .02em var(--c); animation: blinkx 1.2s ease-in-out infinite alternate; animation-delay: var(--d); }
@keyframes grow { from { transform: translateX(-50%) scaleY(0); } to { transform: translateX(-50%) scaleY(1); } }

.cracker { display: block; position: relative; width: 2.2em; height: .6em; }
.cracker b { position: absolute; top: 0; width: 1.1em; height: .6em; background: repeating-linear-gradient(90deg, #d8232a 0 .12em, #b0161c .12em .16em); animation: crack-shake .15s ease-in-out 6 alternate .6s; }
.cracker .l { left: 0; border-radius: .1em 0 0 .1em; clip-path: polygon(0 0, 85% 0, 100% 20%, 85% 40%, 100% 60%, 85% 80%, 100% 100%, 0 100%); animation: crack-shake .15s ease-in-out 6 alternate .6s, crack-l .6s cubic-bezier(.3, 1.3, .5, 1) 1.5s both; }
.cracker .r { right: 0; border-radius: 0 .1em .1em 0; clip-path: polygon(15% 0, 100% 0, 100% 100%, 15% 100%, 0 80%, 15% 60%, 0 40%, 15% 20%); animation: crack-shake .15s ease-in-out 6 alternate-reverse .6s, crack-r .6s cubic-bezier(.3, 1.3, .5, 1) 1.5s both; }
.cracker b::before { content: ""; position: absolute; top: 0; bottom: 0; width: .3em; background: linear-gradient(90deg, #ffd23f, #e0a010); }
.cracker .l::before { left: 0; } .cracker .r::before { right: 0; }
@keyframes crack-shake { from { transform: translate(-.03em, 0) rotate(-2deg); } to { transform: translate(.03em, 0) rotate(2deg); } }
@keyframes crack-l { to { transform: translate(-.9em, .1em) rotate(-25deg); } }
@keyframes crack-r { to { transform: translate(.9em, .1em) rotate(25deg); } }
.bang { font-family: "Mountains of Christmas", cursive; font-weight: 700; color: #ffd23f; text-shadow: 0 3px 0 #8e0f16, 0 0 30px #ff5a5f; letter-spacing: .04em; }
.ho { font-family: "Mountains of Christmas", cursive; font-weight: 700; color: #fff; text-shadow: 0 3px 0 #8e0f16, 0 0 20px rgba(255,255,255,.6); }

.daysky { display: block; width: 100vw; height: 100vh; background: linear-gradient(180deg, #ff9a3c 0%, #ffd27a 45%, #8ec5ff 100%); }
.hills { display: block; width: 140vw; height: 26vh; background: #0a1b12; border-radius: 50% 50% 0 0 / 100% 100% 0 0; transform: translateY(-30%); }
.sun { display: block; width: 1em; height: 1em; border-radius: 50%; background: radial-gradient(circle, #fff6c0, #ffb627 60%, #ff7a1a); box-shadow: 0 0 .4em .15em rgba(255, 182, 39, .7), 0 0 1.2em .4em rgba(255, 150, 60, .35); }

.bulbx { display: block; width: .55em; height: 1em; border-radius: 45% 45% 50% 50% / 35% 35% 65% 65%; background: var(--c); box-shadow: 0 0 .4em .1em var(--c), 0 0 1em .3em color-mix(in srgb, var(--c) 40%, transparent); position: relative; }
.bulbx::before { content: ""; position: absolute; left: .1em; right: .1em; top: -.22em; height: .25em; background: #2c3f21; border-radius: .08em .08em 0 0; }

.radar { display: block; position: relative; width: 1em; height: 1em; border-radius: 50%; border: .02em solid rgba(126, 231, 135, .7); background: radial-gradient(circle, transparent 0 24%, rgba(126,231,135,.5) 24.5% 25%, transparent 25.5% 49%, rgba(126,231,135,.5) 49.5% 50%, transparent 50.5% 74%, rgba(126,231,135,.5) 74.5% 75%, transparent 75.5%), linear-gradient(90deg, transparent 49.6%, rgba(126,231,135,.35) 49.6% 50.4%, transparent 50.4%), linear-gradient(0deg, transparent 49.6%, rgba(126,231,135,.35) 49.6% 50.4%, transparent 50.4%), rgba(4, 38, 26, .9); box-shadow: 0 0 .2em rgba(126, 231, 135, .5), inset 0 0 .3em rgba(126, 231, 135, .25); overflow: hidden; }
.radar::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: conic-gradient(from 0deg, rgba(126,231,135,.65) 0deg, rgba(126,231,135,.15) 50deg, transparent 90deg); animation: sweep 2.2s linear infinite; }
@keyframes sweep { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) { .scene { display: none !important; } }

/* ---------- Toast ---------- */
.toast {
  position: fixed; left: 50%; bottom: calc(24px + var(--sab)); z-index: 50; transform: translate(-50%, 20px);
  background: var(--paper); color: var(--ink); padding: 10px 16px; border-radius: 999px; font-weight: 700; font-size: .95rem;
  box-shadow: 0 6px 20px rgba(0,0,0,.45); opacity: 0; pointer-events: none; transition: opacity .25s ease, transform .25s ease;
  max-width: calc(100% - 32px); text-align: center;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ---------- Test mode ---------- */
.testbar {
  position: fixed; left: 8px; right: 8px; bottom: calc(8px + var(--sab)); z-index: 35;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px 14px;
  background: rgba(255, 210, 63, .96); color: #3a2a00; font-size: .85rem; font-weight: 700;
  padding: 6px 12px; border-radius: 12px; box-shadow: 0 4px 14px rgba(0,0,0,.4);
}
.testbar select { font: inherit; border-radius: 6px; border: 1px solid #9c7b16; padding: 2px 6px; background: #fff; }
.testbar .btn-small { background: var(--red-deep); }
body.testing .skyline { margin-bottom: 70px; }
body.testing .toast { bottom: calc(90px + var(--sab)); }

/* ---------- Motion preferences ---------- */
@media (prefers-reduced-motion: reduce) {
  .stars, .stars-2, .sleigh, .bulb, .title, .holly, .subtitle span::after, .door, .ribbon,
  .door.today .frame, .door.open .inside::after, .skyline .win.lit, .skyline .puff { animation: none !important; }
  .door { opacity: 1; }
  .panel { transition-duration: .5s; }
}
