/* ===== Base ===== */
:root {
  --bg: #b4336c;
  --gutter: 16px;
  --gap: 10px;
  --cols: 4;
  --rows: 6;
  --radius: 14px;
  --header-h: min(12vw, 64px);
  --pad-top: calc(env(safe-area-inset-top, 0px) + 22px);
  --pad-bottom: calc(env(safe-area-inset-bottom, 0px) + 24px);
  --grid-top: clamp(14px, 3.5vh, 36px);
  --vh: 100vh;
}
@supports (height: 100svh) { :root { --vh: 100svh; } }
:root {
  --stage-w: min(calc(100vw - 2 * var(--gutter)), 640px);
  --stage-h: min(calc(var(--vh) - 140px), 820px);
}

@media (min-width: 640px) {
  :root { --cols: 6; --rows: 4; --gap: 14px; --radius: 16px; }
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  min-height: 100%;
  background: var(--bg);
}

body {
  overflow-x: hidden;
  overscroll-behavior-y: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
  touch-action: manipulation;
}

img {
  display: block;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}

button {
  font: inherit;
  color: inherit;
  border: 0;
  padding: 0;
  margin: 0;
  background: none;
  cursor: pointer;
}
button:focus { outline: none; }
button:focus-visible { outline: 2px solid rgba(255, 255, 255, .7); outline-offset: 3px; }
.door:focus-visible { outline: none; }

body.intro-active { overflow: hidden; }

/* ===== Intro ===== */
.intro {
  position: fixed;
  inset: 0;
  z-index: 10;
  background: #000;
}
.intro-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

.press {
  position: fixed;
  left: 50%;
  top: 50%;
  z-index: 15;
  width: min(64vw, 360px);
  padding: 24px;            /* bigger tap target */
  transform: translate(-50%, -50%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 1.4s ease;
}
.press.show { opacity: 1; pointer-events: auto; }
.press.gone { opacity: 0; pointer-events: none; transition-duration: .35s; }
.press img {
  width: 100%;
  height: auto;
  filter: drop-shadow(0 2px 10px rgba(0, 0, 0, .45));
  animation: breathe 2.8s ease-in-out infinite;
}
.press:active img { transform: scale(.96); }

@keyframes breathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.045); }
}

/* ===== Flash: light burst -> white-out -> pink background ===== */
/* The video over-exposes as the light builds */
.intro-video { transition: filter .55s cubic-bezier(.6, 0, .9, .4); }
.flashing .intro-video { filter: brightness(2.4) saturate(1.4) contrast(1.1); }

.flash {
  position: fixed;
  inset: 0;
  z-index: 20;
  pointer-events: none;
  overflow: hidden;
}
/* Ball of light, positioned by JS between the dancers */
.flash-core {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 360px;               /* small texture, scaled up by JS (--s) */
  height: 360px;
  border-radius: 50%;
  background: radial-gradient(circle,
    #fff 0%, #fffaf3 14%, rgba(255, 238, 236, .92) 28%,
    rgba(255, 205, 225, .55) 44%, rgba(255, 170, 205, .18) 58%, rgba(255, 160, 200, 0) 70%);
  transform: translate(-50%, -50%) scale(0);
  opacity: 0;
  will-change: transform, opacity;
}
.flashing .flash-core {
  opacity: 1;
  transform: translate(-50%, -50%) scale(var(--s, 4));
  transition: transform .6s cubic-bezier(.75, 0, .9, .3), opacity .12s ease-out;
}
/* Whole-screen white-out */
.flash-white {
  position: absolute;
  inset: 0;
  background: #fff9f4;
  opacity: 0;
}
.flashing .flash-white {
  opacity: 1;
  transition: opacity .28s ease-in .34s;
}
/* ...then dissolve into the pink background */
.flash-out .flash-core,
.flash-out .flash-white {
  opacity: 0;
  transition: opacity 1.5s cubic-bezier(.25, .6, .3, 1);
}

/* ===== Animated grainy background ===== */
.bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: #b4336c;
  pointer-events: none;
}
/* The picture is flipped upside down so its big cream area sits at the
   bottom (keeping the header readable), and it slowly "breathes". */
.bg-layer {
  position: absolute;
  inset: 0;
  background: url("assets/pinkbg.webp") center / cover no-repeat;
  will-change: transform;
  animation: breathe-bg 9s ease-in-out infinite alternate;
  animation-play-state: paused;
}
.bg-live .bg-layer { animation-play-state: running; }

@keyframes breathe-bg {
  0%   { transform: scaleY(-1) scale(1.06) translate3d(-1%, 0, 0); }
  100% { transform: scaleY(-1) scale(1.11) translate3d(1%, -1.5%, 0); }
}

/* slightly darker so the white handwriting stands out */
.bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(70, 0, 30, .28);
}

/* Film grain: a noise tile that jumps around ~11 times a second */
.grain {
  position: fixed;
  inset: -40px;               /* small overhang so the jumps never show an edge */
  z-index: 30;
  background: url("assets/grain.png") 0 0 / 200px 200px repeat;
  opacity: 0;
  pointer-events: none;
  transition: opacity .4s ease;
  animation: grain .9s steps(1) infinite;
  animation-play-state: paused;
}
.flashing .grain { opacity: .75; animation-play-state: running; }
.bg-live .grain { opacity: .3; transition-duration: 1.8s; animation-play-state: running; }

@keyframes grain {
  0%   { transform: translate3d(0, 0, 0); }
  11%  { transform: translate3d(-17px, -29px, 0); }
  22%  { transform: translate3d(23px, 11px, 0); }
  33%  { transform: translate3d(-31px, 19px, 0); }
  44%  { transform: translate3d(9px, -33px, 0); }
  55%  { transform: translate3d(-13px, 31px, 0); }
  66%  { transform: translate3d(33px, -7px, 0); }
  77%  { transform: translate3d(-27px, -3px, 0); }
  88%  { transform: translate3d(15px, 27px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

/* ===== Calendar ===== */
.calendar {
  position: relative;
  z-index: 1;
  display: none;
  min-height: var(--vh);
  padding: var(--pad-top) var(--gutter) var(--pad-bottom);
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.show-calendar .calendar { display: flex; }

.site-header img {
  height: var(--header-h);
  width: auto;
  max-width: calc(100vw - 2 * var(--gutter));
  object-fit: contain;
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity 1.3s ease, transform 1.3s cubic-bezier(.2, .8, .2, 1);
}
.header-in .site-header img { opacity: 1; transform: none; }

/* Cell size: fits the width AND (where possible) the height of the screen */
.grid {
  --cell: max(58px, min(
    calc((100vw - 2 * var(--gutter) - (var(--cols) - 1) * var(--gap)) / var(--cols)),
    calc((var(--vh) - var(--header-h) - var(--pad-top) - var(--pad-bottom) - var(--grid-top) - (var(--rows) - 1) * var(--gap)) / var(--rows)),
    132px
  ));
  display: grid;
  grid-template-columns: repeat(var(--cols), var(--cell));
  gap: var(--gap);
  justify-content: center;
  margin-top: var(--grid-top);
}

/* ===== Door ===== */
.door {
  position: relative;
  width: var(--cell);
  height: var(--cell);
  perspective: 700px;
  opacity: 0;
  transform: translateY(18px) scale(.9);
}
.doors-in .door {
  animation: doorIn .7s cubic-bezier(.2, .85, .25, 1) forwards;
  animation-delay: calc(var(--i) * 60ms);
}
.door.ready { opacity: 1; transform: none; animation: none; }

@keyframes doorIn {
  to { opacity: 1; transform: none; }
}

.door-frame {
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
  transition: opacity .5s ease;
  transform-style: preserve-3d;
}

.door-leaf {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transform-origin: left center;
  transition: transform .65s cubic-bezier(.55, 0, .25, 1), opacity .65s ease;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.door-leaf img {
  width: 58%;
  height: 58%;
  object-fit: contain;
  pointer-events: none;
}
.door[data-day="24"] .door-leaf img { width: 74%; height: 74%; }

/* Opening: the number swings away on its left edge */
.door.swing .door-leaf { transform: rotateY(-108deg); opacity: 0; }

/* Locked: subtle and dim */
.door.locked .door-frame { opacity: .4; }

/* Today's number gently glows */
.door.today:not(.opened) .door-leaf img { animation: glow 2.6s ease-in-out infinite; }
@keyframes glow {
  0%, 100% { filter: drop-shadow(0 0 0 rgba(255, 235, 240, 0)); }
  50%      { filter: drop-shadow(0 0 9px rgba(255, 235, 240, .9)); }
}

/* Locked tap: little shake */
.door-frame.shake { animation: shake .48s cubic-bezier(.36, .07, .19, .97); }
@keyframes shake {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(3px) rotate(1deg); }
  30%, 50%, 70% { transform: translateX(-5px) rotate(-1.5deg); }
  40%, 60% { transform: translateX(5px) rotate(1.5deg); }
}

/* ===== Opened door (modal) ===== */
.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  visibility: hidden;
  pointer-events: none;
}
.modal.open { visibility: visible; pointer-events: auto; }
body.modal-open { overflow: hidden; }

.modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(38, 0, 15, .74);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  opacity: 0;
  transition: opacity .45s ease;
}
.modal.visible .modal-backdrop { opacity: 1; }

.modal-stage {
  position: relative;
  width: var(--stage-w);
  height: var(--stage-h);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 26px;
  will-change: transform, opacity;
}

.modal-close {
  position: absolute;
  top: calc(env(safe-area-inset-top, 0px) + 10px);
  right: calc(env(safe-area-inset-right, 0px) + 10px);
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  opacity: 0;
  transform: scale(.7);
  transition: opacity .35s ease, transform .35s ease, background .2s;
}
.modal.visible .modal-close { opacity: 1; transform: none; transition-delay: .2s; }
.modal-close:active { background: rgba(255, 255, 255, .12); }
.modal-close svg {
  width: 26px;
  height: 26px;
  fill: none;
  stroke: #fff;
  stroke-width: 2.2;
  stroke-linecap: round;
}

/* Media inside the opened door */
.media {
  display: block;
  max-width: var(--stage-w);
  max-height: var(--stage-h);
  min-height: 0;
  width: auto;
  height: auto;
  border-radius: 16px;
  box-shadow: 0 22px 60px rgba(20, 0, 8, .5);
  object-fit: contain;
  opacity: 0;
  transition: opacity .35s ease;
}
.media.loaded { opacity: 1; }

.note-paper {
  --pad: clamp(14px, 4vw, 28px);
  display: flex;
  padding: var(--pad);
  background: #fbf6ee;
  border-radius: 10px;
  box-shadow: 0 22px 60px rgba(20, 0, 8, .5);
  transform: rotate(-1.2deg);
}
.note-paper .media {
  max-width: calc(var(--stage-w) - 2 * var(--pad));
  max-height: calc(var(--stage-h) - 2 * var(--pad));
  box-shadow: none;
  border-radius: 0;
}

.video-wrap {
  position: relative;
  display: flex;
}
.play-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity .25s ease;
}
.video-wrap.playing .play-overlay { opacity: 0; }

.play-btn {
  position: relative;
  width: 84px;
  height: 84px;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, .16);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  transition: transform .2s ease;
}
.play-btn:active { transform: scale(.94); }
.play-btn svg.icon { width: 34px; height: 34px; fill: #fff; }
.play-btn .i-pause { display: none; }
.play-btn.is-playing .i-play { display: none; }
.play-btn.is-playing .i-pause { display: block; }

.audio-cover {
  max-height: calc(var(--stage-h) - 120px);
}
.ring {
  position: absolute;
  inset: -6px;
  width: calc(100% + 12px);
  height: calc(100% + 12px);
  transform: rotate(-90deg);
  pointer-events: none;
}
.ring circle { fill: none; stroke-width: 3; }
.ring .track { stroke: rgba(255, 255, 255, .18); }
.ring .bar { stroke: #fff; stroke-linecap: round; transition: stroke-dashoffset .25s linear; }

@media (prefers-reduced-motion: reduce) {
  .press img, .door.today .door-leaf img { animation: none !important; }
}

/* ===== Locked door: photo shown for 2 seconds ===== */
.peek {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(38, 0, 15, .45);
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s ease, visibility 0s linear .3s;
}
.peek.show {
  opacity: 1;
  visibility: visible;
  transition: opacity .25s ease, visibility 0s;
}
.peek img {
  max-width: min(calc(100vw - 48px), 420px);
  max-height: calc(var(--vh) - 120px);
  width: auto;
  height: auto;
  border-radius: 18px;
  box-shadow: 0 22px 60px rgba(20, 0, 8, .55);
  transform: scale(.88) rotate(-2deg);
  transition: transform .35s cubic-bezier(.2, .9, .3, 1.2);
}
.peek.show img { transform: scale(1) rotate(-1deg); }
