/* 塔罗 · a sky full of floating cards */
:root {
  --bg: #05061a;
  --bg-2: #141b5c;
  --aura: rgba(110, 130, 255, 0.3);
  --panel: #12163a;
}

/* ------------------------------------------------------------------ */
/* Full-screen layout: the 3D space sits behind the whole page         */
/* ------------------------------------------------------------------ */

body.immersive {
  height: 100dvh;
  overflow: hidden;
}

.immersive .page {
  position: relative;
  z-index: 3;
  height: 100dvh;
  min-height: 0;
  pointer-events: none; /* clicks fall through to the cards… */
}

.immersive .top,
.immersive .ask,
.immersive .cta-row {
  pointer-events: auto; /* …except on the controls */
}

.immersive .hero {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 0 16px;
  text-align: center;
}

.immersive .copy {
  margin: 0 auto;
  max-width: 640px;
  transition: opacity 0.6s, transform 0.8s var(--ease-out);
}

.immersive .sub {
  margin: 0 auto;
}

.immersive .bottom {
  width: min(440px, 100%);
  margin: 0 auto;
  padding-bottom: calc(18px + env(safe-area-inset-bottom));
  display: grid;
  gap: 12px;
  transition: opacity 0.5s, transform 0.8s var(--ease-out);
}

/* base.css places these in named grid areas; here they just stack */
.immersive .bottom > * {
  grid-area: auto;
}

.immersive .ask {
  margin: 0;
}

.immersive .cta-row {
  padding: 4px 0 6px;
}

.immersive .hint {
  margin: 0;
  font-size: 14px;
}

/* while a card is being drawn the page steps aside */
body.is-drawing .copy,
body.is-drawn .copy {
  opacity: 0;
  transform: translateY(-24px);
}

body.is-drawing .bottom,
body.is-drawn .bottom {
  opacity: 0;
  transform: translateY(30px);
  pointer-events: none;
}

body.is-drawing .bottom *,
body.is-drawn .bottom * {
  pointer-events: none;
}

/* dark bands behind the headline and the controls so text stays readable over the cards */
.scrim {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(4, 5, 20, 0.92) 0%, rgba(4, 5, 20, 0.55) 18%, rgba(4, 5, 20, 0) 34%),
    linear-gradient(0deg, rgba(4, 5, 20, 0.95) 0%, rgba(4, 5, 20, 0.6) 17%, rgba(4, 5, 20, 0) 34%);
  transition: opacity 0.8s;
}

body.is-drawn .scrim {
  opacity: 0.55;
}

/* ------------------------------------------------------------------ */
/* 3D space                                                            */
/* ------------------------------------------------------------------ */

.space {
  position: fixed;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  perspective: 1000px;
  perspective-origin: 50% 50%;
  outline: none;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
}

/* the tabletop and the deck: same camera as .space, but always painted underneath it */
.tablespace {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  perspective: 1000px;
  perspective-origin: 50% 50%;
}

.tablespace[hidden] {
  display: none;
}

/* empty parts of the card space let clicks through to the deck below */
.space {
  pointer-events: none;
}

.space .card {
  pointer-events: auto;
}

.world,
.tableworld {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
  transform-style: preserve-3d;
  will-change: transform;
}

.card {
  position: absolute;
  transform-style: preserve-3d;
  will-change: transform;
  cursor: pointer;
}

/* Opacity and blur live on the two faces (leaves), never on .card itself:
   on a preserve-3d element they would flatten the card and break the flip. */
.card > .back,
.card > .face {
  position: absolute;
  inset: 0;
  border-radius: 6.3% / 4.45%;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  background: var(--card-back) center / 100% 100% no-repeat;
  box-shadow: 0 18px 40px -10px rgba(0, 0, 0, 0.6);
  opacity: var(--fade, 1);
  filter: blur(var(--blur, 0px)) brightness(var(--dim, 1));
  transition: opacity 0.7s, filter 0.7s, box-shadow 0.3s;
}

.card > .face {
  transform: rotateY(180deg);
}

/* once drawn, the face is the rendered answer card (it carries its own frame and rounded corners) */
.card > .face.has-img {
  background: none;
  box-shadow: none;
  border-radius: 0;
}

.card > .face img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.card.is-drawn > .back {
  box-shadow:
    0 0 0 2px rgba(255, 226, 160, 0.9),
    0 0 60px 10px rgba(255, 200, 110, 0.55);
}

@media (hover: hover) {
  .space.is-float .card:hover > .back {
    box-shadow:
      0 0 0 2px rgba(255, 226, 160, 0.85),
      0 0 34px 6px rgba(255, 200, 110, 0.5),
      0 18px 40px -10px rgba(0, 0, 0, 0.6);
    filter: blur(var(--blur, 0px)) brightness(calc(var(--dim, 1) * 1.15));
  }
}

/* the tabletop: a velvet cloth lit by a pool of light, with a gold ring embroidered under the deck */
.table {
  position: absolute;
  pointer-events: none;
  will-change: transform, opacity;
  background:
    radial-gradient(circle at 50% 50%, rgba(255, 216, 150, 0.26) 0%, rgba(255, 216, 150, 0.08) 6%, transparent 13%),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='1.25' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 .1 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"),
    repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.022) 0 2px, transparent 2px 7px),
    radial-gradient(circle at 50% 50%, #2a3690 0%, #18206a 8%, #0b0f38 19%, #05061a 32%);
}

.table-ring {
  position: absolute;
  border-radius: 50%;
  background: var(--ring) center / 100% 100% no-repeat;
  pointer-events: auto;
  cursor: pointer;
  animation: ring-breathe 3.2s ease-in-out infinite;
}

@keyframes ring-breathe {
  50% {
    filter: drop-shadow(0 0 18px rgba(255, 210, 120, 0.55)) brightness(1.25);
  }
}

/* gold dust drifting in front of the cards */
.dust {
  position: fixed;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ------------------------------------------------------------------ */
/* The drawn card                                                      */
/* ------------------------------------------------------------------ */

/* while a card is put back, the rays (which sit above the 3D layer) go at once instead of fading over it */
body.is-returning .drawn-rays {
  transition: none;
  opacity: 0;
}

.card.no-glow-fade > .back {
  transition: opacity 0.7s, filter 0.7s;
}

/* the turning layers themselves are styled in base.css (shared with the other pages' result rays) */
.drawn-rays {
  --rays-mask: radial-gradient(closest-side, #000 6%, transparent 55%);
  position: fixed;
  z-index: 2;
  left: 50%;
  top: var(--drawn-cy, 45%);
  width: 160vmax;
  height: 160vmax;
  margin: -80vmax 0 0 -80vmax;
  pointer-events: none;
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.9s, transform 1.2s var(--ease-out);
}

/* nothing turns while the rays are hidden */
body:not(.is-drawn) .drawn-rays > i {
  animation-play-state: paused;
}

body.is-drawn .drawn-rays {
  opacity: 1;
  transform: scale(1);
}

/* a crisp 2D copy of the card once it has arrived (3D-scaled layers can rasterise soft).
   tarot.js tilts it toward the pointer, or keeps it facing you as the phone turns. */
.drawn {
  position: fixed;
  z-index: 4;
  transform-origin: 50% 50%;
  will-change: transform;
  filter: drop-shadow(0 30px 40px rgba(0, 0, 0, 0.6)) drop-shadow(0 0 40px rgba(255, 200, 110, 0.35));
  -webkit-touch-callout: default;
  touch-action: none;
}

.drawn[hidden] {
  display: none;
}

.drawn img {
  display: block;
  width: 100%;
  height: 100%;
  -webkit-touch-callout: default;
}

/* the light catching the card face as it turns */
.drawn .glare {
  position: absolute;
  inset: 0;
  border-radius: 5.1% / 3.6%;
  pointer-events: none;
  mix-blend-mode: screen;
  background:
    radial-gradient(circle at var(--gx, 50%) var(--gy, 40%), rgba(255, 248, 225, 0.34), rgba(255, 248, 225, 0.08) 28%, transparent 52%),
    linear-gradient(115deg, transparent calc(var(--gx, 50%) - 22%), rgba(255, 255, 255, 0.1) var(--gx, 50%), transparent calc(var(--gx, 50%) + 22%));
}

.draw-actions {
  position: fixed;
  z-index: 5;
  left: 50%;
  bottom: calc(16px + env(safe-area-inset-bottom));
  width: min(420px, calc(100% - 32px));
  display: grid;
  gap: 12px;
  transform: translateX(-50%);
  animation: actions-in 0.6s var(--ease-out) both;
}

.draw-actions[hidden] {
  display: none;
}

.draw-actions .save-tip {
  margin: 0;
  text-align: center;
}

@keyframes actions-in {
  from {
    opacity: 0;
    transform: translate(-50%, 24px);
  }
}

@media (min-width: 960px) {
  .immersive .hero {
    padding: 0 48px;
  }

  .immersive .copy {
    max-width: 760px;
  }

  .immersive .bottom {
    padding-bottom: 28px;
  }

  .immersive .cta-row .cta {
    width: 100%;
  }
}

/* the chosen card waits at the front while its answer is being drawn */
.card.is-charging > .back {
  animation: charging 0.9s ease-in-out infinite alternate;
}

@keyframes charging {
  to {
    box-shadow:
      0 0 0 3px rgba(255, 236, 190, 1),
      0 0 90px 24px rgba(255, 210, 120, 0.75);
  }
}
