/* ---------- Base ---------- */
* { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  --flame-1: #fff6d8;
  --flame-2: #ffd56b;
  --flame-3: #ff9d2e;

  --ink: #dfe1e4;        /* main text */
  --ink-dim: #9aa0a8;    /* secondary text */
  --ink-faint: #6f747b;  /* tertiary text */
  --line: rgba(255, 255, 255, 0.14);
  --line-strong: rgba(255, 255, 255, 0.3);

  --paper: #eceae4;
  --paper-ink: #33343a;
}

html, body { height: 100%; }

body {
  font-family: Georgia, 'Times New Roman', serif;
  color: var(--ink);
  overflow: hidden;
  background:
    radial-gradient(130% 100% at 50% 0%, rgba(60, 64, 72, 0.25) 0%, rgba(60, 64, 72, 0) 55%),
    linear-gradient(to bottom, #0e0f12 0%, #15161a 55%, #1a1b20 100%);
}

/* ---------- Private-page gate ---------- */
#gate {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  background:
    radial-gradient(130% 100% at 50% 0%, rgba(60, 64, 72, 0.25) 0%, rgba(60, 64, 72, 0) 55%),
    linear-gradient(to bottom, #0e0f12 0%, #15161a 55%, #1a1b20 100%);
  transition: opacity 0.7s ease;
}

#gate.unlocking { opacity: 0; pointer-events: none; }

.gate-card {
  width: min(340px, 92vw);
  text-align: center;
}

.gate-candle {
  position: relative;
  width: 30px;
  margin: 0 auto 2.2rem;
}

.gate-title {
  font-size: 1.15rem;
  letter-spacing: 0.08em;
  color: var(--ink);
  margin-bottom: 0.35rem;
}

.gate-sub {
  font-size: 0.85rem;
  font-style: italic;
  color: var(--ink-dim);
  margin-bottom: 1.3rem;
}

#gate-input {
  width: 100%;
  font-family: inherit;
  font-size: 1rem;
  text-align: center;
  letter-spacing: 0.12em;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.7rem 0.85rem;
  margin-bottom: 0.7rem;
}

#gate-input:focus {
  outline: none;
  border-color: #b9bcc0;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.08);
}

#gate-input.gate-shake { animation: shake 0.32s ease; }

.gate-err {
  margin-top: 0.9rem;
  font-size: 0.82rem;
  font-style: italic;
  color: #c98a7a;
}

/* ---------- Center stack: name, portrait, verse ---------- */
.center-stack {
  position: fixed;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(0.9rem, 2.4vh, 1.6rem);
  /* bottom padding clears the action buttons even on short windows */
  padding: 2vh 1rem max(16vh, 122px);
  pointer-events: none;
}

.masthead {
  flex-shrink: 0;
  text-align: center;
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.9), 0 0 6px rgba(0, 0, 0, 0.8);
}

.masthead .pre {
  font-style: italic;
  font-size: 0.9rem;
  letter-spacing: 0.18em;
  color: var(--ink-dim);
}

.masthead h1 {
  font-size: clamp(1.5rem, 4.5vw, 2.5rem);
  font-weight: normal;
  letter-spacing: 0.06em;
  color: #eceef0;
  margin: 0.3rem 0 0.35rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.45em;
}

.rank {
  height: 1.3em;
  width: auto;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.7));
}

.rank[hidden] { display: none; }

.masthead .dates {
  font-size: 0.95rem;
  letter-spacing: 0.25em;
  color: var(--ink-dim);
}

.masthead .unit {
  margin-top: 0.25rem;
  font-size: 0.82rem;
  letter-spacing: 0.12em;
  color: var(--ink-faint);
}

/* Portrait — the flexible element: on short windows the photo shrinks (never
   the buttons' clearance), so it can't collide with the actions bar. */
.portrait {
  pointer-events: auto;
  cursor: pointer;
  flex: 0 1 clamp(220px, 42vh, 480px);
  min-height: 130px;
  display: flex;
  justify-content: center;
}

.frame {
  position: relative;
  height: 100%;
  aspect-ratio: 4 / 5;
  max-width: 82vw;
  padding: 9px;
  background: linear-gradient(160deg, #33353a 0%, #232529 55%, #2c2e33 100%);
  border: 1px solid var(--line-strong);
  border-radius: 3px;
  box-shadow:
    0 10px 40px rgba(0, 0, 0, 0.7),
    inset 0 1px 0 rgba(255, 255, 255, 0.12);
}

.frame img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* crop anchored near the top: portraits keep the head, whatever the photo's shape */
  object-position: 50% 12%;
  display: block;
  background: #101114;
  border: 1px solid rgba(0, 0, 0, 0.6);
  /* fade in once the portrait has decoded, rather than popping in */
  opacity: 0;
  transition: opacity 0.7s ease;
}

.frame img.loaded { opacity: 1; }

.portrait-fallback {
  position: absolute;
  inset: 9px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  background: linear-gradient(to bottom, #1d1f24, #141519);
  border: 1px solid rgba(0, 0, 0, 0.6);
}

.portrait-fallback[hidden] { display: none; }

.fallback-cross { font-size: 3rem; color: #8b8f96; opacity: 0.9; }

.fallback-note {
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
  text-align: center;
  line-height: 1.5;
}

.frame-hint {
  position: absolute;
  left: 9px; right: 9px; bottom: 9px;
  padding: 0.5rem 0;
  text-align: center;
  font-size: 0.74rem;
  font-style: italic;
  letter-spacing: 0.1em;
  color: var(--ink);
  background: linear-gradient(to top, rgba(8, 9, 11, 0.85), rgba(8, 9, 11, 0));
  opacity: 0;
  transition: opacity 0.2s ease;
  pointer-events: none;
}

.portrait:hover .frame-hint, .portrait:focus-visible .frame-hint { opacity: 1; }

.verse {
  flex-shrink: 0;
  max-width: min(560px, 88vw);
  text-align: center;
  font-style: italic;
  font-size: clamp(0.74rem, 1.7vw, 0.9rem);
  line-height: 1.6;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.95), 0 0 4px rgba(0, 0, 0, 0.85), 0 0 14px rgba(0, 0, 0, 0.6);
}

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

.candle {
  position: absolute;
  transform: translate(-50%, -50%) 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; }

.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)); }

/* 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;
  transform: translate(-50%, -50%) 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 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; }

/* 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)); }
}

/* ---------- Actions ---------- */
.actions {
  position: fixed;
  bottom: max(16px, env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%);
  z-index: 6;
  width: min(94vw, 640px);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.5rem 0.6rem;
}

.btn {
  font-family: inherit;
  font-size: 0.92rem;
  letter-spacing: 0.04em;
  padding: 0.65rem 1.2rem;
  border-radius: 999px;
  cursor: pointer;
  /* keep the fill inside the border so it can't bleed past the curve */
  background-clip: padding-box;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

.btn.primary {
  background: linear-gradient(to bottom, #e8e9eb, #c6c8cc);
  border: 2px solid #85888d;
  color: #1b1c1e;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
}

.btn.primary:hover { transform: translateY(-1px); box-shadow: 0 6px 22px rgba(0, 0, 0, 0.6); }

.btn.secondary {
  background: rgba(255, 255, 255, 0.07);
  border: 2px solid var(--line-strong);
  color: var(--ink);
  backdrop-filter: blur(3px);
}

.btn.secondary:hover { background: rgba(255, 255, 255, 0.12); transform: translateY(-1px); }

.btn.ghost {
  background: rgba(255, 255, 255, 0.03);
  border: 2px solid var(--line);
  color: var(--ink-dim);
  backdrop-filter: blur(3px);
}

.btn.ghost:hover { background: rgba(255, 255, 255, 0.08); color: var(--ink); }

.count {
  width: 100%;
  text-align: center;
  font-size: 0.78rem;
  font-style: italic;
  color: var(--ink-faint);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.95), 0 0 3px rgba(0, 0, 0, 0.85);
}

/* ---------- Modals ---------- */
.overlay {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(6, 7, 9, 0.74);
  backdrop-filter: blur(4px);
  padding: 1rem;
}

.overlay[hidden] { display: none; }

.modal {
  position: relative;
  width: min(480px, 94vw);
  max-height: 88vh;
  overflow-y: auto;
  background: linear-gradient(to bottom, #202226, #17181c);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 1.6rem 1.7rem 1.7rem;
  box-shadow: 0 12px 60px rgba(0, 0, 0, 0.8);
  animation: modal-in 0.3s ease;
}

@keyframes modal-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

.modal h2 {
  font-weight: normal;
  color: #e6e8ea;
  letter-spacing: 0.04em;
  margin-bottom: 0.3rem;
}

.modal-sub { font-size: 0.88rem; color: var(--ink-dim); margin-bottom: 1rem; }

.close {
  position: absolute;
  top: 0.7rem; right: 0.9rem;
  background: none;
  border: none;
  font-size: 1.5rem;
  color: var(--ink-dim);
  cursor: pointer;
  line-height: 1;
}

.close:hover { color: var(--ink); }

/* Shared form fields */
.compose textarea, .compose input,
.memory textarea, .memory input[type="text"] {
  width: 100%;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.7rem 0.85rem;
  margin-bottom: 0.7rem;
  resize: vertical;
}

.compose textarea:focus, .compose input:focus,
.memory textarea:focus, .memory input[type="text"]:focus {
  outline: none;
  border-color: #b9bcc0;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.08);
}

.btn.wide { width: 100%; }

/* Occupies the same slot as the button it replaces, so the modal's layout
   (and the candle above it) doesn't jump at the moment of lighting. */
.ignite-note {
  margin-top: 0;
  min-height: 2.8rem;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-style: italic;
  font-size: 0.9rem;
  color: var(--ink);
}

.ignite-note[hidden] { display: none; }

.field-error { border-color: #c25b4a !important; }

/* Big candle in compose modal */
.big-candle {
  position: relative;
  height: 130px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  margin-bottom: 1.1rem;
}

.big-tealight { position: relative; width: 84px; height: 58px; }

.big-cup {
  position: absolute;
  top: 16px; left: 0;
  width: 84px; height: 42px;
  z-index: 1;
  border-radius: 4px 4px 34px 34px / 4px 4px 16px 16px;
  background:
    linear-gradient(to bottom, rgba(255, 200, 120, 0.5) 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 6px 18px rgba(0, 0, 0, 0.55);
}

.big-cup::before {
  content: '';
  position: absolute;
  top: -16px; left: 0;
  width: 84px; height: 32px;
  box-sizing: border-box;
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 62%, #96682f 0%, #6b4820 55%, #462f14 100%);
  border: 1.5px solid rgba(255, 228, 170, 0.7);
  box-shadow: inset 0 2px 4px rgba(255, 230, 180, 0.3);
}

.big-wax {
  position: absolute;
  top: 4px; left: 7px;
  width: 70px; height: 24px;
  z-index: 2;
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 40%,
    #fffce9 0%, #ffeeb2 30%, #ffd97e 55%, #edb457 78%, #cf9143 94%);
  transition: box-shadow 1.3s ease;
}

/* unlit: a dark veil over the pool until the flame wakes it — opacity fade
   is GPU-cheap, unlike animating filter (which can flash on laptops) */
.big-wax::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: rgba(38, 26, 12, 0.5);
  opacity: 1;
  transition: opacity 1.3s ease;
}

.big-candle.lit .big-wax { box-shadow: 0 0 30px rgba(255, 205, 110, 0.5); }

.big-candle.lit .big-wax::after { opacity: 0; }

.wick {
  position: absolute;
  top: 9px; left: 50%;
  width: 3px; height: 10px;
  z-index: 3;
  transform: translateX(-50%) rotate(6deg);
  background: #241809;
  border-radius: 2px;
}

.big-flame {
  position: absolute;
  bottom: 42px; left: 50%;              /* base on the wick, in the pool */
  width: 26px; height: 44px;
  transform: translateX(-50%) scale(0);
  transform-origin: 50% 100%;
  border-radius: 50% 50% 50% 50% / 62% 62% 38% 38%;
  background: radial-gradient(circle at 50% 80%,
    var(--flame-1) 0%, var(--flame-2) 36%, var(--flame-3) 66%, rgba(255, 110, 20, 0) 100%);
  filter: blur(0.6px);
  opacity: 0;
  will-change: transform, opacity;
  z-index: 4;
}

/* Ignition and flicker are one chained animation (no transition→animation
   handoff, which desktop compositors can glitch into an invisible flame). */
@keyframes ignite {
  from { transform: translateX(-50%) scale(0); opacity: 0; }
  30%  { opacity: 1; }
  to   { transform: translateX(-50%) scale(1); opacity: 1; }
}

@keyframes glow-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.flame-core {
  position: absolute;
  bottom: 5px; left: 50%;
  width: 10px; height: 18px;
  transform: translateX(-50%);
  border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
  background: radial-gradient(circle at 50% 70%, #ffffff 0%, #fff2c0 60%, rgba(255, 240, 180, 0) 100%);
}

.big-glow {
  position: absolute;
  top: -10px; left: 50%;
  width: 260px; height: 260px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 190, 90, 0.34) 0%, rgba(255, 170, 60, 0.1) 45%, rgba(255, 150, 40, 0) 70%);
  opacity: 0;
  transition: opacity 1s ease;   /* finishes before the pulse animation begins */
  pointer-events: none;
}

.big-candle.lit .big-flame {
  animation:
    ignite 1.1s cubic-bezier(0.2, 1.4, 0.4, 1) forwards,
    flicker 2s ease-in-out 1.1s infinite;
}

.big-candle.lit .big-glow {
  animation:
    glow-in 1s ease forwards,
    glowpulse 2s ease-in-out 1.1s infinite;
}

/* ---------- The match ---------- */
.strike-area {
  position: relative;
  height: 74px;
  margin: 0.1rem 0 0.1rem;
}

.strike-area.done { opacity: 0.25; pointer-events: none; transition: opacity 0.6s ease; }

/* matchbox strike strip: white card covered in a honeycomb of dark-red dots */
.strike-strip {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: min(250px, 72%);
  height: 22px;
  border-radius: 6px;
  border: 3px solid #eeebe2;             /* clean white margin around the dots */
  box-sizing: border-box;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='7'%3E%3Cg fill='%237c2a20'%3E%3Cpolygon points='4,1.2 5.99,2.35 5.99,4.65 4,5.8 2.01,4.65 2.01,2.35'/%3E%3Cpolygon points='0,-2.3 1.99,-1.15 1.99,1.15 0,2.3 -1.99,1.15 -1.99,-1.15'/%3E%3Cpolygon points='8,-2.3 9.99,-1.15 9.99,1.15 8,2.3 6.01,1.15 6.01,-1.15'/%3E%3Cpolygon points='0,4.7 1.99,5.85 1.99,8.15 0,9.3 -1.99,8.15 -1.99,5.85'/%3E%3Cpolygon points='8,4.7 9.99,5.85 9.99,8.15 8,9.3 6.01,8.15 6.01,5.85'/%3E%3C/g%3E%3C/svg%3E") 0 0 / 6px 5.25px,
    #eeebe2;
  box-shadow:
    inset 0 0 3px rgba(0, 0, 0, 0.25),
    0 1px 3px rgba(0, 0, 0, 0.45);
}

.match {
  position: absolute;
  left: 18px; top: 22px;
  width: 12px; height: 64px;
  transform: rotate(-35deg);
  transform-origin: 50% 70%;
  cursor: grab;
  touch-action: none;
  z-index: 6;
}

/* in hand: pinned to the screen, outside the modal's scroll world, so
   carrying it can never stretch or scroll the box */
.match.held {
  position: fixed;
  z-index: 120;
}

.match:active { cursor: grabbing; }

.match.returning { transition: left 0.5s ease, top 0.5s ease; }

.match-stick {
  position: absolute;
  left: 50%; top: 11px;
  width: 4px; height: 50px;
  transform: translateX(-50%);
  background: linear-gradient(90deg, #caa165, #ecd0a0 45%, #b98d55);
  border-radius: 2px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}

.match-head {
  position: absolute;
  left: 50%; top: 2px;
  width: 8px; height: 13px;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at 45% 35%, #b0503c, #7c2d1f 70%);
  border-radius: 50% 50% 45% 45%;
}

.match.lit .match-head { background: radial-gradient(ellipse at 45% 35%, #4a3327, #2b1d14 70%); }

.match-tip {
  position: absolute;
  left: 50%; top: 8px;
  width: 2px; height: 2px;
  transform: translateX(-50%);
  pointer-events: none;
}

/* the anchor counter-rotates the match's tilt, so the flame stands upright
   (like the candles') centered on the red tip */
.match-flame-anchor {
  position: absolute;
  left: 50%; top: 8px;
  width: 0; height: 0;
  transform: rotate(35deg);
  pointer-events: none;
  z-index: 2;
}

.match-flame {
  position: absolute;
  left: 0; bottom: 2px;
  width: 10px; height: 17px;
  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%);
  opacity: 0;
  transition: opacity 0.2s ease;
  pointer-events: none;
}

.match.lit .match-flame { opacity: 1; animation: flicker 1.6s ease-in-out infinite; }
.match.burnout .match-flame { opacity: 0; transition: opacity 0.7s ease; }

/* quick flash where the match catches */
.spark {
  position: fixed;
  width: 30px; height: 30px;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, #fff8dc 0%, #ffd56b 40%, rgba(255, 150, 40, 0) 70%);
  pointer-events: none;
  z-index: 60;
  animation: spark-pop 0.3s ease-out forwards;
}

@keyframes spark-pop {
  from { opacity: 1; transform: translate(-50%, -50%) scale(0.5); }
  to   { opacity: 0; transform: translate(-50%, -50%) scale(2); }
}

/* friction sparks thrown off while scrubbing the strip */
.strike-spark {
  position: fixed;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: radial-gradient(circle, #fff3c0 0%, #ffb84d 55%, rgba(255, 120, 20, 0) 100%);
  pointer-events: none;
  z-index: 120;
  animation: spark-fly 0.45s ease-out forwards;
}

@keyframes spark-fly {
  from { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  70%  { opacity: 0.9; }
  to   {
    opacity: 0;
    transform: translate(calc(-50% + var(--dx, 8px)), calc(-50% + var(--dy, -14px))) scale(0.35);
  }
}

.strike-hint {
  text-align: center;
  font-size: 0.8rem;
  font-style: italic;
  color: var(--ink-dim);
  margin-bottom: 0.35rem;
}

.linklike {
  display: block;
  margin: 0 auto;
  background: none;
  border: none;
  font-family: inherit;
  font-size: 0.78rem;
  font-style: italic;
  color: var(--ink-faint);
  text-decoration: underline dotted;
  cursor: pointer;
}

.linklike:hover { color: var(--ink-dim); }

.linklike[hidden] { display: none; }

/* compact optional attachment inside compose */
.compose .dropzone { padding: 0.7rem 1rem; }
.compose .dropzone-hint small { font-style: italic; opacity: 0.75; }

/* media attached to a letter, shown above its text */
#viewer-media { margin-bottom: 1rem; text-align: center; }

#viewer-media[hidden] { display: none; }

#viewer-media img, #viewer-media video {
  max-width: 100%;
  max-height: 45vh;
  border-radius: 6px;
  border: 1px solid #b9a274;
}

/* Letter viewer */
.viewer { background: linear-gradient(to bottom, var(--paper), #dfddd5); border-color: #a9a8a1; }
.viewer .close { color: #85837b; }
.viewer .close:hover { color: var(--paper-ink); }

.letter { color: var(--paper-ink); }

.letter p:first-child {
  font-size: 1.02rem;
  line-height: 1.75;
  white-space: pre-wrap;
  overflow-wrap: anywhere;   /* unbroken pasted text wraps instead of one long line */
}

.letter-from {
  margin-top: 1.2rem;
  text-align: right;
  font-style: italic;
  font-size: 0.98rem;
}

.letter-date {
  margin-top: 0.2rem;
  text-align: right;
  font-size: 0.78rem;
  color: #85837b;
}

/* All-letters list */
.letters { width: min(560px, 94vw); }

.letter-card {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.9rem 1rem;
  margin-bottom: 0.7rem;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.letter-card:hover { background: rgba(255, 255, 255, 0.08); border-color: var(--line-strong); }

.letter-card .excerpt {
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--ink);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}

.letter-card .meta {
  margin-top: 0.45rem;
  font-size: 0.78rem;
  font-style: italic;
  color: var(--ink-dim);
}

.letters-empty { color: var(--ink-dim); font-style: italic; }

/* ---------- Share a memory ---------- */
.dropzone {
  display: block;
  border: 1.5px dashed var(--line-strong);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.03);
  text-align: center;
  padding: 1.4rem 1rem;
  margin-bottom: 0.8rem;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.dropzone:hover, .dropzone.dragover {
  border-color: #b9bcc0;
  background: rgba(255, 255, 255, 0.06);
}

.dropzone-hint { color: var(--ink-dim); font-size: 0.92rem; line-height: 1.7; }
.dropzone-hint small { font-size: 0.78rem; opacity: 0.8; }

#media-preview img, #media-preview video {
  max-width: 100%;
  max-height: 220px;
  border-radius: 6px;
  display: block;
  margin: 0 auto;
}

#media-preview .change-hint {
  margin-top: 0.5rem;
  font-size: 0.75rem;
  font-style: italic;
  color: var(--ink-dim);
}

/* ---------- Album ---------- */
.album { width: min(680px, 94vw); }

#album-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 10px;
}

.album-item {
  position: relative;
  aspect-ratio: 1;
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
  border: 1px solid var(--line);
  background: #000;
  padding: 0;
  transition: border-color 0.15s ease, transform 0.15s ease;
}

.album-item:hover { border-color: var(--line-strong); transform: scale(1.02); }

.album-item img, .album-item video {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 25%;   /* favor faces in the square thumbnails */
  display: block;
}

.album-item .play-badge {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.7rem;
  color: rgba(240, 242, 245, 0.92);
  background: rgba(0, 0, 0, 0.28);
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
  pointer-events: none;
}

.album-item .item-from {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 0.35rem 0.5rem 0.3rem;
  font-size: 0.68rem;
  font-style: italic;
  color: var(--ink);
  background: linear-gradient(to top, rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0));
  text-align: left;
  pointer-events: none;
}

/* ---------- Lightbox ---------- */
.lightbox { width: min(760px, 94vw); }

#lightbox-media { text-align: center; }

#lightbox-media img, #lightbox-media video {
  max-width: 100%;
  max-height: 62vh;
  border-radius: 8px;
}

.lightbox-caption {
  margin-top: 0.9rem;
  font-size: 0.98rem;
  line-height: 1.65;
  color: var(--ink);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.lightbox-meta {
  margin-top: 0.4rem;
  text-align: right;
  font-style: italic;
  font-size: 0.85rem;
  color: var(--ink-dim);
}

/* ---------- Small screens ---------- */
@media (max-width: 560px) {
  .center-stack { padding-bottom: 21vh; }

  /* insignia above the name, memorial-card style */
  .masthead h1 { flex-direction: column; gap: 0.3em; }
  .rank { height: 1.15em; }

  .portrait { flex-basis: clamp(200px, 36vh, 380px); }

  .actions { gap: 0.45rem 0.5rem; }
  #btn-light { flex: 1 1 100%; }
  .btn.secondary, .btn.ghost { flex: 1 1 40%; padding: 0.6rem 0.6rem; font-size: 0.86rem; }
}

/* ---------- Short windows (small laptops, half-height windows) ---------- */
@media (max-height: 740px) {
  .center-stack { gap: clamp(0.5rem, 1.6vh, 1rem); }
  .portrait { flex-basis: clamp(150px, 34vh, 360px); }
  .masthead .pre { font-size: 0.8rem; }
  .masthead h1 { font-size: clamp(1.2rem, 3.6vw, 2rem); }
  .masthead .dates { font-size: 0.85rem; }
  .masthead .unit { font-size: 0.75rem; }
}

@media (max-height: 520px) {
  .masthead .unit, .verse { display: none; }
  .portrait { flex-basis: clamp(120px, 30vh, 300px); min-height: 100px; }
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .flame, .glow, .ripple, #place-candle.setting-down, #place-candle.fresh, .strike-spark {
    animation: none;
  }
  .big-candle.lit .big-flame { animation: ignite 0.01s forwards; }
  .big-candle.lit .big-glow { animation: glow-in 0.01s forwards; }
  .candle { transition: none; }
}
