/* The cover: the palace's mirror-work doors, which open onto the card.

   The doors (assets/cover/doors*.webp, a picture per screen shape) are cut in
   the page, not in the pictures: each leaf is the whole picture clipped to its
   half and hinged at its outer edge (--hinge), and on tablets the frame either
   side of the leaves is the same picture clipped the other way, and stays
   still. geometry.css (generated) sets which picture, the hinge, where the
   medallion sits, where the mirrors are and a few sparkles.

   Before they open, the mirrors catch the light: a glint (--gx, --gy, moved by
   js/cover.js with the tilt of the phone or a finger) lights only the mirror
   pieces, a slow sweep crosses them, and a few mirrors flash now and then.

   Sizes: on phones and tablets the doors cover the screen, drawn for its
   shape. On a laptop or desktop they fill the card's 3:4 column, with the room
   dark either side.
*/

html.is-shut,
html.is-shut body {
  overflow: hidden;
  overscroll-behavior: none;
}

html.is-shut .card {
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}

/* ------------------------------------------------------------ the gate */

.gate {
  --d-h: max(100vh, calc(100vw / var(--doors-r)));
  --d-w: max(100vw, calc(100vh * var(--doors-r)));
  position: fixed;
  inset: 0;
  z-index: 50;
  overflow: hidden;
  background: var(--emerald-night);
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
}

@supports (height: 100svh) {
  .gate {
    --d-h: max(100svh, calc(100vw / var(--doors-r)));
    --d-w: max(100vw, calc(100svh * var(--doors-r)));
  }
}

@media (min-aspect-ratio: 751/1000) {
  html:not(.is-tablet) .gate {
    --d-h: 100vh;
    --d-w: calc(100vh * var(--doors-r));
  }
  @supports (height: 100svh) {
    html:not(.is-tablet) .gate { --d-h: 100svh; --d-w: calc(100svh * var(--doors-r)); }
  }
}

.gate[hidden] { display: none; }

/* Once the doors are opening, the card behind shows through as they give way. */
.gate.is-opening { background: none; }

/* The first frame, before the real doors have decoded: a 24px copy, blown up. */
html.is-loading .gate,
html.is-arriving .gate { background: var(--emerald-night) var(--doors-tiny) center / cover no-repeat; }

.gate-backdrop {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 50%, #0a3a2e 0%, #05211a 62%, #020f0b 100%);
}

.gate-backdrop::after {
  /* The doors themselves, huge and out of focus: the room around them. */
  content: "";
  position: absolute;
  inset: -10%;
  background: center / cover no-repeat;
  filter: blur(40px) brightness(.4) saturate(1.1);
  opacity: .6;
}

.gate-inner {
  position: absolute;
  inset: 0;
}

.doors {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--d-w);
  height: var(--d-h);
  transform: translate(-50%, -50%);
  --gx: 50%;
  --gy: 42%;
}

.stage {
  position: absolute;
  inset: 0;
  perspective: calc(var(--d-w) * 1.4);
  perspective-origin: 50% 50%;
}

.d-art {
  position: absolute;
  inset: 0;
  background-position: 0 0;
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

/* ------------------------------------------------------------ behind the doors */

.d-light {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: radial-gradient(ellipse 50% 42% at 50% 48%, #fffbea 0%, #ffe7aa 20%, #e9b863 42%, #8a6424 68%, #231a0a 100%);
}

.d-rays {
  position: absolute;
  left: 50%;
  top: 48%;
  width: 260%;
  aspect-ratio: 1;
  translate: -50% -50%;
  /* soft shafts of light, not a starburst */
  background: repeating-conic-gradient(from 0deg, rgba(255, 248, 220, .2) 0deg, rgba(255, 248, 220, 0) 5deg, rgba(255, 248, 220, 0) 12deg, rgba(255, 248, 220, .2) 17deg);
  -webkit-mask: radial-gradient(closest-side, #000 5%, rgba(0, 0, 0, .5) 30%, transparent 62%);
          mask: radial-gradient(closest-side, #000 5%, rgba(0, 0, 0, .5) 30%, transparent 62%);
  filter: blur(calc(var(--d-w) * .006));
  animation: d-rays 40s linear infinite;
}

.d-core {
  position: absolute;
  left: 50%;
  top: 48%;
  width: 70%;
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  background: radial-gradient(closest-side, #fffef6, rgba(255, 244, 205, .7) 40%, rgba(255, 230, 160, 0));
  opacity: .7;
}

@keyframes d-rays { to { rotate: 1turn; } }

/* ------------------------------------------------------------ the frame and the leaves */

.d-frame-l { clip-path: inset(0 calc(100% - var(--hinge)) 0 0); }
.d-frame-r { clip-path: inset(0 0 0 calc(100% - var(--hinge))); }

.d-leaf {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.d-leaf-l { clip-path: inset(0 50% 0 var(--hinge)); transform-origin: var(--hinge) 50%; }
.d-leaf-r { clip-path: inset(0 var(--hinge) 0 50%); transform-origin: calc(100% - var(--hinge)) 50%; }

/* The glint: a pool of light and a slow sweep, on the mirror pieces only. */
.d-glint {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle calc(var(--d-w) * .26) at var(--gx) var(--gy), rgba(255, 255, 255, .95), rgba(255, 252, 236, .5) 30%, rgba(255, 248, 225, 0) 100%);
  -webkit-mask-size: 100% 100%;
          mask-size: 100% 100%;
  mix-blend-mode: screen;
}

.d-glint::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(112deg, transparent 42%, rgba(255, 255, 255, .6) 50%, transparent 58%) 0 0 / 300% 100% no-repeat;
  animation: d-sweep 7s cubic-bezier(.45, 0, .55, 1) 1.2s infinite;
}

@keyframes d-sweep {
  0%       { background-position: 100% 0; }
  55%, 100% { background-position: 0 0; }
}

/* Now and then a single mirror flashes. */
.spark {
  position: absolute;
  width: calc(var(--d-w) * .06 * var(--k, 1));
  aspect-ratio: 1;
  translate: -50% -50%;
  background:
    radial-gradient(closest-side, #fff, rgba(255, 255, 255, 0)) center / 100% 9% no-repeat,
    radial-gradient(closest-side, #fff, rgba(255, 255, 255, 0)) center / 9% 100% no-repeat,
    radial-gradient(closest-side, rgba(255, 253, 240, .95), rgba(255, 253, 240, 0)) center / 34% 34% no-repeat;
  mix-blend-mode: screen;
  opacity: 0;
  animation: d-twinkle 4.4s ease-in-out var(--d, 0s) infinite;
  pointer-events: none;
}

@keyframes d-twinkle {
  0%, 68%, 100% { opacity: 0; transform: rotate(10deg) scale(.2); }
  78%           { opacity: 1; transform: rotate(35deg) scale(1); }
  88%           { opacity: .4; transform: rotate(55deg) scale(.45); }
}

.d-shade {
  position: absolute;
  inset: 0;
  background: #010a07;
  opacity: 0;
}

/* Light through the crack when the latch gives. */
.d-seam {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: calc(var(--d-w) * .006);
  translate: -50% 0;
  background: linear-gradient(transparent, #fff6d6 10%, #fffdf2 50%, #fff6d6 90%, transparent);
  box-shadow: 0 0 calc(var(--d-w) * .03) calc(var(--d-w) * .012) rgba(255, 214, 130, .75);
  opacity: 0;
}

.d-vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 85% 75% at 50% 48%, transparent 58%, rgba(0, 10, 6, .5) 100%);
  pointer-events: none;
}

/* ------------------------------------------------------------ the medallion */

.medallion {
  position: absolute;
  left: var(--med-x);
  top: var(--med-y);
  width: var(--med-d);
  aspect-ratio: 1;
  translate: -50% -50%;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  outline: none;
  -webkit-tap-highlight-color: transparent;
}

.m-body {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: 50%;
  transition: transform 160ms cubic-bezier(.3, .7, .4, 1);
}

.gate.is-pressed .m-body { transform: scale(.96); }

.medallion-img {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

/* Light catching the gold now and then. */
.m-sheen {
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 38%, rgba(255, 250, 230, .65) 50%, transparent 62%) -150% 0 / 250% 100% no-repeat;
  mix-blend-mode: soft-light;
  animation: m-sheen 5.2s ease-in-out 1.6s infinite;
}

@keyframes m-sheen {
  0%, 62% { background-position: -150% 0; }
  100%    { background-position: 250% 0; }
}

/* An invitation to touch: a thin gold ring leaving the medallion. */
.m-ring {
  position: absolute;
  inset: 2%;
  border-radius: 50%;
  border: 1.5px solid rgba(240, 214, 150, .75);
  opacity: 0;
  animation: m-ring 2.8s cubic-bezier(.2, .6, .3, 1) 1.2s infinite;
}

@keyframes m-ring {
  0%   { opacity: .9; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.5); }
}

.medallion:focus-visible .m-ring { opacity: 1; animation: none; transform: scale(1.12); border-color: #fff4d6; }

/* Tapping the doors anywhere but the medallion points to it. */
.gate.is-nudged .m-ring { animation: m-ring 900ms cubic-bezier(.2, .6, .3, 1) 2; }
.gate.is-nudged .gate-hint { animation: hint-flash 900ms ease; }

/* ------------------------------------------------------------ words and buttons */

.gate-hint {
  position: absolute;
  left: 50%;
  top: calc(50% + var(--d-w) * var(--med-k) + max(18px, 2.4vh));
  width: max-content;
  max-width: 86vw;
  margin: 0;
  padding: 9px 18px 9px calc(18px + .26em);
  translate: -50% 0;
  border: 1px solid rgba(201, 164, 92, .5);
  border-radius: 999px;
  background: rgba(3, 23, 15, .58);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  color: var(--gold-soft);
  font: 600 12px/1 "Cormorant Garamond", Georgia, serif;
  letter-spacing: .26em;
  text-transform: uppercase;
  animation: hint-pulse 3.2s ease-in-out 1.4s infinite;
  pointer-events: none;
}

@keyframes hint-pulse {
  0%, 100% { opacity: .85; }
  50%      { opacity: .55; }
}

@keyframes hint-flash {
  0%, 100% { opacity: .85; }
  30%      { opacity: 1; background: rgba(12, 60, 46, .8); }
}

/* The last of the light, as the view passes through the doorway. */
.d-flood {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 48%, #fffef9, #fff8e4 45%, #f6e2b0 90%);
  opacity: 0;
  pointer-events: none;
}

.sound-toggle {
  position: absolute;
  top: max(14px, env(safe-area-inset-top));
  right: max(14px, env(safe-area-inset-right));
  z-index: 3;
  width: 40px;
  height: 40px;
  padding: 9px;
  border: 1px solid rgba(230, 207, 152, .4);
  border-radius: 50%;
  background: rgba(3, 23, 15, .45);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  color: var(--gold-soft);
  cursor: pointer;
}

.sound-toggle svg { width: 100%; height: 100%; display: block; }
.sound-toggle path { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.sound-toggle .spk { fill: currentColor; }
.sound-toggle[aria-pressed="true"] .mute,
.sound-toggle[aria-pressed="false"] .wave { display: none; }
.sound-toggle:focus-visible { outline: 2px solid var(--gold-soft); outline-offset: 2px; }

/* ------------------------------------------------------------ arriving */

html.is-loading .stage,
html.is-loading .medallion,
html.is-loading .gate-hint,
html.is-loading .sound-toggle { opacity: 0; }

html.is-arriving .stage        { animation: arrive-doors 1200ms cubic-bezier(.2, .7, .2, 1) both; }
html.is-arriving .medallion    { animation: arrive-med 900ms cubic-bezier(.2, 1.35, .35, 1) 380ms both; }
html.is-arriving .gate-hint    { animation: arrive-fade 900ms ease 950ms both, hint-pulse 3.2s ease-in-out 1.9s infinite; }
html.is-arriving .sound-toggle { animation: arrive-fade 700ms ease 1100ms both; }

@keyframes arrive-doors {
  from { opacity: 0; transform: scale(1.05); filter: brightness(.5); }
  to   { opacity: 1; transform: none; filter: none; }
}

@keyframes arrive-med {
  from { opacity: 0; transform: scale(.7) rotate(-40deg); }
  to   { opacity: 1; transform: none; }
}

@keyframes arrive-fade { from { opacity: 0; } to { opacity: 1; } }

.gate.is-opening .gate-hint,
.gate.is-opening .m-ring { animation: none; opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .d-rays, .d-glint::after, .spark, .m-sheen, .m-ring, .gate-hint { animation: none !important; }
  .spark { display: none; }
}
