/* ---------- Candle field ---------- */
#candle-field {
  position: fixed;
  inset: 0;
  z-index: 2;
}

.candle {
  position: absolute;
  /* --dx/--dy carry the live drag offset on the GPU; left/top only change
     when the candle is set down, so dragging never repaints the field */
  transform: translate(calc(-50% + var(--dx, 0px)), calc(-50% + var(--dy, 0px))) scale(var(--s, 1));
  background: none;
  border: none;
  cursor: grab;
  padding: 14px;
  touch-action: none;   /* finger drags move the candle, not the page */
}

.candle.arriving {
  transition: left 2.4s cubic-bezier(0.25, 0.6, 0.3, 1), top 2.4s cubic-bezier(0.25, 0.6, 0.3, 1);
}

.candle.dragging { cursor: grabbing; will-change: transform; }

.candle.snapback { transition: left 0.45s ease, top 0.45s ease; }

.candle:focus-visible { outline: 1px solid var(--line-strong); border-radius: 50%; }

/* Tealight seen slightly from above: a wide glowing wax pool with a thin
   metal rim, over a dark cup wall that falls away into shadow. */
.tealight { position: relative; width: 30px; height: 22px; }

/* dark cup wall; warm light from the pool bleeds onto its top edge */
.cup {
  position: absolute;
  top: 6px; left: 0;
  width: 30px; height: 16px;
  z-index: 1;
  border-radius: 2px 2px 15px 15px / 2px 2px 8px 8px;
  background:
    linear-gradient(to bottom, rgba(255, 200, 120, 0.55) 0%, rgba(255, 190, 105, 0) 60%),
    linear-gradient(to bottom, rgba(40, 24, 8, 0) 65%, rgba(40, 24, 8, 0.35) 100%),
    linear-gradient(90deg, #55401f 0%, #a8874e 15%, #ecd096 50%, #a8874e 85%, #55401f 100%);
  box-shadow: 0 2px 5px rgba(15, 8, 3, 0.55);   /* grounds the cup in bright washes */
}

/* cup mouth: thin bright rim over a warm shadowed interior */
.cup::before {
  content: '';
  position: absolute;
  top: -6px; left: 0;
  width: 30px; height: 12px;
  box-sizing: border-box;
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 62%, #96682f 0%, #6b4820 55%, #462f14 100%);
  border: 1px solid rgba(255, 228, 170, 0.7);
  box-shadow: inset 0 1px 2px rgba(255, 230, 180, 0.35);
}

/* molten pool, lit from within — brightest around the wick */
.wax {
  position: absolute;
  top: 1.5px; left: 3px;
  width: 24px; height: 9px;
  z-index: 2;
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 40%,
    #fffce9 0%, #ffeeb2 30%, #ffd97e 55%, #edb457 78%, #cf9143 94%);
  box-shadow: 0 0 10px rgba(255, 205, 110, 0.6);
}

.wax::after {
  content: '';
  position: absolute;
  top: 18%; left: 50%;
  width: 2px; height: 5px;
  background: #241809;
  border-radius: 1px;
  transform: translateX(-50%) rotate(8deg);
}

.flame {
  position: absolute;
  bottom: 15px; left: 50%;              /* base sits on the wick, in the pool */
  width: 9px; height: 15px;
  z-index: 3;
  transform: translateX(-50%);
  transform-origin: 50% 100%;
  border-radius: 50% 50% 50% 50% / 62% 62% 38% 38%;
  background: radial-gradient(circle at 50% 78%,
    var(--flame-1) 0%, var(--flame-2) 38%, var(--flame-3) 68%, rgba(255, 110, 20, 0) 100%);
  filter: blur(0.4px);
  animation: flicker var(--fd, 1.9s) ease-in-out infinite;
  animation-delay: var(--fdel, 0s);
}

@keyframes flicker {
  0%, 100% { transform: translateX(-50%) scale(1, 1)    skewX(0deg);  opacity: 1; }
  22%      { transform: translateX(-50%) scale(0.92, 1.08) skewX(2deg);  opacity: 0.93; }
  45%      { transform: translateX(-50%) scale(1.04, 0.94) skewX(-3deg); opacity: 1; }
  70%      { transform: translateX(-50%) scale(0.96, 1.05) skewX(1.5deg); opacity: 0.9; }
}

.glow {
  position: absolute;
  top: -30px; left: 50%;
  width: 84px; height: 84px;
  transform: translateX(-50%) scale(var(--amp, 1));
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 190, 90, 0.38) 0%, rgba(255, 170, 60, 0.13) 42%, rgba(255, 150, 40, 0) 70%);
  pointer-events: none;
  animation: glowpulse var(--fd, 1.9s) ease-in-out infinite;
  animation-delay: var(--fdel, 0s);
  transition: transform 0.8s ease;
}

@keyframes glowpulse {
  0%, 100% { opacity: calc(0.95 * var(--dim, 1)); }
  50%      { opacity: calc(0.7 * var(--dim, 1)); }
}

.candle:hover .glow { transform: translateX(-50%) scale(calc(var(--amp, 1) * 1.25)); }

/* steady burners: past ~55 candles most flames hold still (see renderField) —
   still lit, just no animation layer each */
.candle.still .flame { animation: none; }
.candle.still .glow { animation: none; opacity: calc(0.85 * var(--dim, 1)); }

/* Wide, faint ambient pool in its own layer BELOW every candle, so clusters
   light the ground without washing out the cups. recomputeGlow() scales each
   halo up and fades it as neighbors crowd in, so total light saturates. */
.halo {
  position: absolute;
  width: 180px; height: 150px;
  z-index: 1;
  /* the halo shares the candle's drag offset; its 0.8s transition means the
     pooled light drifts after the candle instead of repainting each frame */
  transform: translate(calc(-50% + var(--dx, 0px)), calc(-50% + var(--dy, 0px))) scale(var(--amp, 1));
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(255, 185, 95, 0.13) 0%, rgba(255, 165, 75, 0.05) 45%, rgba(255, 150, 60, 0) 70%);
  pointer-events: none;
  transition: transform 0.8s ease, opacity 0.8s ease;
}

.halo.halo-in { opacity: 0; }

/* ---------- Candle placement ---------- */
#place-layer {
  position: fixed;
  inset: 0;
  z-index: 15;
  touch-action: none;   /* so finger drags move the candle, not the page */
  cursor: crosshair;
}

#place-layer[hidden] { display: none; }

.place-hint {
  position: fixed;
  top: max(16px, env(safe-area-inset-top));
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: 90vw;
  text-align: center;
  font-style: italic;
  font-size: 0.92rem;
  color: var(--ink);
  background: rgba(10, 11, 14, 0.82);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.55rem 1.2rem;
  pointer-events: none;
  transition: opacity 0.5s ease;
}

#place-layer.placing-done .place-hint { opacity: 0; }

/* The moment after the candle arrives — two quiet beats, in the masthead's
   voice: the fact first, the invitation a breath later. The container holds,
   then everything exhales together. */
.place-announce {
  position: fixed;
  left: 50%; top: 58%;
  transform: translate(-50%, -50%);
  width: max-content; max-width: 84vw;
  text-align: center;
  /* legible even across the bright portrait: a crisp edge shadow to carve the
     letters, then widening halos */
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.95),
    0 0 6px rgba(0, 0, 0, 0.9),
    0 0 16px rgba(0, 0, 0, 0.85),
    0 2px 30px rgba(0, 0, 0, 0.8);
  /* and a soft breath of darkness behind the words — no hard box */
  padding: 1.3rem 2.4rem;
  background: radial-gradient(ellipse closest-side, rgba(8, 9, 11, 0.55), rgba(8, 9, 11, 0));
  opacity: 0;
  pointer-events: none;
  z-index: 20;
}

.place-announce span { display: block; opacity: 0; }

.announce-lit {
  font-size: clamp(1.25rem, 4.2vw, 1.7rem);
  letter-spacing: 0.06em;      /* the masthead's h1 tracking */
  color: #eceef0;
}

.announce-rest {
  margin-top: 0.5rem;
  font-style: italic;
  font-size: clamp(0.95rem, 3vw, 1.15rem);
  letter-spacing: 0.08em;
  color: rgba(236, 238, 240, 0.82);
}

.place-announce.run { animation: announce-hold 5s ease forwards; }
.place-announce.run .announce-lit  { animation: announce-line 1.2s ease 0.2s forwards; }
.place-announce.run .announce-rest { animation: announce-line 1.2s ease 1.3s forwards; }

/* container: visible through both beats, then a slow shared exhale */
@keyframes announce-hold {
  0%, 82% { opacity: 1; }
  100%    { opacity: 0; }
}

/* each line drifts up into place */
@keyframes announce-line {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: none; }
}

/* the candle is lowered gently onto its spot */
#place-candle.setting-down {
  animation: set-down 0.95s cubic-bezier(0.3, 0.7, 0.3, 1) forwards;
}

@keyframes set-down {
  from { transform: translate(-50%, calc(-50% - 8px)) scale(calc(var(--s, 1) * 1.06)); }
  to   { transform: translate(-50%, -50%) scale(var(--s, 1)); }
}

/* soft pool of light blooming outward where a candle is set down */
.ripple {
  position: absolute;
  width: 130px; height: 95px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(ellipse,
    rgba(255, 205, 120, 0.32) 0%, rgba(255, 180, 90, 0.12) 45%, rgba(255, 160, 70, 0) 70%);
  pointer-events: none;
  z-index: 2;
  animation: ripple-out 1.6s ease-out forwards;
}

@keyframes ripple-out {
  from { opacity: 0.9; transform: translate(-50%, -50%) scale(0.3); }
  to   { opacity: 0;   transform: translate(-50%, -50%) scale(1.8); }
}

#place-candle {
  position: absolute;
  transform: translate(-50%, -50%) scale(var(--s, 1));
  pointer-events: none;
  transition: opacity 0.15s ease;
}

#place-candle.invalid { opacity: 0.4; }

/* your candle glows a little stronger while it's being carried and placed —
   the same intensity as the compose glow, so the handoff doesn't dim */
#place-candle .glow {
  background: radial-gradient(circle, rgba(255, 190, 90, 0.5) 0%, rgba(255, 170, 60, 0.18) 42%, rgba(255, 150, 40, 0) 70%);
}

/* the lit candle carried to the photo — one slow, deliberate glide, shrinking
   to the size it will live at (JS drives left / top / --s) */
#place-candle.carrying {
  transition:
    left 1.6s cubic-bezier(0.5, 0, 0.15, 1),
    top 1.6s cubic-bezier(0.5, 0, 0.15, 1),
    transform 1.6s cubic-bezier(0.5, 0, 0.15, 1),
    opacity 0.15s ease;
}

/* while the candle is in flight, the hint pill waits its turn */
#place-layer.arriving .place-hint { opacity: 0; }

/* just-lit candle hovering over the photo, breathing until you move it */
#place-candle.fresh { animation: fresh-pulse 1.8s ease-in-out infinite; }

@keyframes fresh-pulse {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(1.4); }
}

#place-candle.place-shake { animation: shake 0.32s ease; }

@keyframes shake {
  25% { margin-left: -7px; }
  75% { margin-left: 7px; }
}

.candle.settling { animation: settle 0.55s cubic-bezier(0.2, 1.6, 0.4, 1); }

@keyframes settle {
  from { transform: translate(-50%, -50%) scale(calc(var(--s, 1) * 1.7)); }
  to   { transform: translate(-50%, -50%) scale(var(--s, 1)); }
}

