/* =====================================================================
   dreams-fx.css : 꿈해몽 페이지의 몽글몽글한 효과
   ---------------------------------------------------------------------
   · 검색할 때 검색창 둘레로 피어오르는 구름과 작은 별
   · 결과 카드가 안개 속에서 떠오르는 모습 + 카드 모서리의 구름 테두리
   · 꿈 상세 보기가 구름 속에서 피어나는 전환 + 제목 옆 초승달
   · 찾는 꿈이 없을 때 졸린 구름 그림
   · 분류 탭을 고르면 작은 구름이 톡 튀어 올라요
   움직임은 transform 과 opacity 위주로만 써요. (움직임 줄이기 설정이면 멈춰요)
   ===================================================================== */
:root {
  --fx-cream: 255, 241, 216;
  --fx-lilac: 216, 202, 255;
  --fx-good: #f3d58e;   /* 길몽: 따뜻한 금빛 */
  --fx-mixed: #c6b5f4;  /* 상황 따라: 라일락 */
  --fx-care: #93b9e8;   /* 마음 살피기: 차분한 파랑 */
  --fx-cloud-line: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 26'%3E%3Cpath d='M10 23h20.5a6.5 6.5 0 0 0 .6-12.97A9 9 0 0 0 13.7 8.6 7.2 7.2 0 0 0 10 23z' fill='none' stroke='%23000' stroke-width='1.6' stroke-linejoin='round'/%3E%3C/svg%3E");
  --fx-cloud-fill: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 26'%3E%3Cpath d='M10 24h20.5a7 7 0 0 0 .7-13.97A9.5 9.5 0 0 0 13.4 8 8 8 0 0 0 10 24z'/%3E%3C/svg%3E");
}

/* ── 1. 검색창 둘레의 구름과 별 ── */
.tools { position: relative; }
.tools > :not(.fx-sky):not(.fx-seek) { position: relative; z-index: 1; }
.fx-sky {
  position: absolute; left: 0; right: 0; top: -64px; bottom: -6px; z-index: 0;
  overflow: hidden; pointer-events: none;
  -webkit-mask-image: linear-gradient(to top, #000 55%, transparent);
          mask-image: linear-gradient(to top, #000 55%, transparent);
}
.fx-puff {
  position: absolute; left: 0; top: 0; width: var(--w, 60px); height: calc(var(--w, 60px) * .56);
  --c: var(--fx-cream);
  background:
    radial-gradient(ellipse 28% 34% at 32% 62%, rgba(var(--c), .7), rgba(var(--c), .3) 50%, rgba(var(--c), 0)),
    radial-gradient(ellipse 32% 44% at 54% 46%, rgba(var(--c), .75), rgba(var(--c), .32) 50%, rgba(var(--c), 0)),
    radial-gradient(ellipse 24% 32% at 74% 64%, rgba(var(--c), .65), rgba(var(--c), .28) 50%, rgba(var(--c), 0)),
    radial-gradient(ellipse 44% 26% at 52% 72%, rgba(var(--c), .55), rgba(var(--c), 0));
  opacity: 0; will-change: transform, opacity;
  animation: fxRise var(--d, 2.8s) cubic-bezier(.25, .6, .35, 1) forwards;
}
.fx-puff.lilac { --c: var(--fx-lilac); }
@keyframes fxRise {
  0%   { opacity: 0; transform: translate(var(--x), var(--y)) scale(.65); }
  22%  { opacity: .95; }
  100% { opacity: 0; transform: translate(calc(var(--x) + var(--dx, 0px)), calc(var(--y) - 58px)) scale(1.18); }
}
.fx-star {
  position: absolute; left: 0; top: 0; width: 7px; height: 7px;
  background: #fff3cf; clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
  opacity: 0; transform: translate(var(--x), var(--y)) scale(.2);
  animation: fxTwinkle 1.5s ease-in-out forwards;
}
@keyframes fxTwinkle {
  0%   { opacity: 0;  transform: translate(var(--x), var(--y)) scale(.2) rotate(0deg); }
  45%  { opacity: 1;  transform: translate(var(--x), var(--y)) scale(1) rotate(25deg); }
  100% { opacity: 0;  transform: translate(var(--x), calc(var(--y) - 8px)) scale(.3) rotate(45deg); }
}

/* '꿈을 찾는 중…' 반짝임 (검색이 늦을 때만) */
.fx-seek {
  position: absolute; z-index: 2; left: 0; top: 0; pointer-events: none;
  font-size: .72rem; line-height: 1; padding: 2px 9px; border-radius: 999px; white-space: nowrap;
  color: #f4e6c8; background: rgba(27, 30, 60, .72); border: 1px solid rgba(var(--fx-lilac), .28);
  overflow: hidden; opacity: 0; transform: translateY(-3px); transition: opacity .25s, transform .25s;
}
.fx-seek.on { opacity: 1; transform: none; }
.fx-seek::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 20%, rgba(var(--fx-cream), .35) 50%, transparent 80%);
  transform: translateX(-100%); animation: fxSheen 1.4s ease-in-out infinite;
}
@keyframes fxSheen { to { transform: translateX(100%); } }

/* 단문형 카드: 긴 이름 옆으로 꼬리표가 밀려 화면 밖으로 나가지 않게 한 줄로 쌓아요 */
.dream.short { grid-template-columns: minmax(0, 1fr); }

/* ── 2. 결과 카드: 안개 속에서 떠오르기 + 모서리 구름 ── */
.dream { position: relative; }
.dream::after {
  content: ''; position: absolute; right: 7px; bottom: 6px; width: 26px; height: 17px; pointer-events: none;
  background: var(--fx-mixed); opacity: .5;
  -webkit-mask: var(--fx-cloud-line) center / contain no-repeat; mask: var(--fx-cloud-line) center / contain no-repeat;
  transition: opacity .25s;
}
.dream:has(.tone.good)::after { background: var(--fx-good); }
.dream:has(.tone.care)::after { background: var(--fx-care); }
.dream:hover::after, .dream:focus-visible::after { opacity: .7; }
.dream.fx-in { animation: fxMist .55s cubic-bezier(.2, .7, .3, 1) backwards; animation-delay: calc(var(--i, 0) * 40ms); }
@keyframes fxMist {
  from { opacity: 0; transform: translateY(8px); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}

/* ── 3. 꿈 상세: 구름 속에서 피어나기 + 초승달 ── */
.sheet.fx-bubble { animation: fxBubble .5s cubic-bezier(.2, .75, .3, 1) backwards; }
.sheet.fx-bubble > :not(.fx-veil) { animation: fxEmerge .5s ease-out .12s backwards; }
@keyframes fxBubble { from { opacity: 0; transform: translateY(10px) scale(.95); } }
@keyframes fxEmerge { from { opacity: 0; } }
.fx-veil {
  position: absolute; inset: 0; z-index: 3; border-radius: inherit; overflow: hidden; pointer-events: none;
  --t: var(--fx-mixed);
  animation: fxVeil .52s ease-out forwards;
}
@keyframes fxVeil { 0%, 30% { opacity: 1; } 100% { opacity: 0; } }
.fx-veil i {
  position: absolute; width: 70%; aspect-ratio: 1; border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--fx-cream), .9) 0 30%, color-mix(in srgb, var(--t) 55%, transparent) 52%, transparent 70%);
  transform: translate(-50%, -50%) scale(1); animation: fxPuffOut .52s cubic-bezier(.3, .6, .3, 1) forwards;
}
.fx-veil i:nth-child(1) { left: 22%; top: 26%; }
.fx-veil i:nth-child(2) { left: 70%; top: 20%; }
.fx-veil i:nth-child(3) { left: 50%; top: 52%; width: 90%; }
.fx-veil i:nth-child(4) { left: 18%; top: 80%; }
.fx-veil i:nth-child(5) { left: 80%; top: 78%; }
@keyframes fxPuffOut { to { transform: translate(-50%, -50%) translate(var(--ox, 0), var(--oy, 0)) scale(1.55); opacity: 0; } }
.fx-veil i:nth-child(1) { --ox: -14%; --oy: -10%; }
.fx-veil i:nth-child(2) { --ox: 14%;  --oy: -12%; }
.fx-veil i:nth-child(4) { --ox: -14%; --oy: 12%; }
.fx-veil i:nth-child(5) { --ox: 14%;  --oy: 12%; }

.fx-moon {
  position: relative; display: inline-block; width: .62em; height: .62em; margin-left: .38em; vertical-align: .42em;
  border-radius: 50%; box-shadow: inset -.17em -.05em 0 0 #f2d48c; transform: rotate(-18deg);
  filter: drop-shadow(0 0 4px rgba(242, 212, 140, .55));
  animation: fxMoonIn .7s cubic-bezier(.3, 1.4, .5, 1) .28s backwards;
}
.fx-moon::after {
  content: ''; position: absolute; width: .34em; height: .34em; right: -.36em; top: -.22em;
  background: #fff6da; clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
  animation: fxSpark 2.6s ease-in-out .9s infinite;
}
@keyframes fxMoonIn { from { opacity: 0; transform: rotate(-60deg) scale(.4); } }
@keyframes fxSpark { 0%, 100% { opacity: .35; transform: scale(.6); } 50% { opacity: 1; transform: scale(1.1) rotate(30deg); } }

/* ── 4. 찾는 꿈이 없을 때 ── */
.fx-empty {
  grid-column: 1 / -1; display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center;
  padding: 18px 16px 20px; color: var(--mist); min-width: 0;
  background: color-mix(in srgb, var(--night-2) 88%, transparent); border: 1px solid var(--line); border-radius: 18px;
}
.fx-empty svg { width: 150px; height: auto; display: block; overflow: visible; }
.fx-empty .fx-sleep { animation: fxDoze 4.5s ease-in-out infinite; transform-origin: 50% 60%; }
.fx-empty .fx-z { animation: fxZ 3s ease-in-out infinite; opacity: 0; }
.fx-empty .fx-z.b { animation-delay: 1.2s; }
@keyframes fxDoze { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
@keyframes fxZ { 0% { opacity: 0; transform: translate(0, 4px); } 30% { opacity: .9; } 100% { opacity: 0; transform: translate(6px, -10px); } }
.fx-empty p { margin: 0; }
.fx-empty .fx-say { color: var(--ink); font-family: var(--font-display); }
.fx-empty .fx-small { font-size: .82rem; }
.fx-sugg { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
.fx-sugg button {
  font: inherit; font-size: .85rem; cursor: pointer; color: var(--ink);
  background: rgba(var(--fx-lilac), .08); border: 1px solid rgba(var(--fx-lilac), .3); border-radius: 999px; padding: 4px 12px;
}
.fx-sugg button:hover, .fx-sugg button:focus-visible { color: var(--gilt); border-color: var(--gilt); }

/* ── 5. 분류 탭: 고르면 작은 구름이 톡 ── */
.tab { position: relative; }
.tab[aria-pressed="true"]::after {
  content: ''; position: absolute; top: -8px; right: -3px; width: 17px; height: 11px; pointer-events: none;
  background: #fff1d4; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .35));
  -webkit-mask: var(--fx-cloud-fill) center / contain no-repeat; mask: var(--fx-cloud-fill) center / contain no-repeat;
  animation: fxHop .6s cubic-bezier(.3, 1.6, .5, 1) backwards;
}
@keyframes fxHop {
  0%   { opacity: 0; transform: translateY(7px) scale(.4); }
  60%  { opacity: 1; transform: translateY(-3px) scale(1.08); }
  100% { transform: none; }
}

/* 움직임 줄이기: 움직임은 멈추고 모양만 남겨요 */
@media (prefers-reduced-motion: reduce) {
  .fx-sky, .fx-veil { display: none !important; }
  .dream.fx-in, .sheet.fx-bubble, .sheet.fx-bubble > *, .fx-moon, .fx-moon::after,
  .fx-empty .fx-sleep, .tab[aria-pressed="true"]::after, .fx-seek::after { animation: none !important; }
  .fx-empty .fx-z { animation: none !important; opacity: .7; }
  .fx-moon::after { opacity: .8; }
}
