/* ════════════════════════════════════════════════════════════════════
   shop-tarojip.css — 타로집 [대면 상담] 스테이지
   ────────────────────────────────────────────────────────────────────
   2026-08-28 사람 직접 지시 (`타로집 구현.txt`).

   사람 원문의 기준선:
     "AI 타로 결과를 읽었다" 가 아니라
     "루나 앞에 앉아서 내 이야기를 했고, 루나가 카드를 직접 보고 하나씩 설명해줬다."

   그래서 이 파일이 지키는 숫자는 셋뿐이다 (지시 §2 · §16 · §17):
     ① 루나 영역 55~65%  ② 상담·카드 영역 35~45%  ③ 자막이 얼굴을 가리지 않는다
     화면은 세로 모바일 기준. 값은 dvh 로 잡아 주소창 높이 변화에 흔들리지 않게 한다.

   ★ 새 시각 언어를 만들지 않는다
     색·글자·테두리는 `premium-hud.css` 의 --pg-* 토큰을 그대로 쓴다. 카드 뒷면은
     이미 있는 `assets/cards/back.webp`(RW-018 확정본)다. 새 폰트·라이브러리 없음.
   ★ 이 파일은 타로집(reading.html · ?shop=oracle 이 아닐 때)에서만 붙는다.
     shop-tarojip.js 가 <body> 에 `.tj-on` 을 달아 줄 때만 아래 규칙이 산다.
   ════════════════════════════════════════════════════════════════════ */

/* ── 기존 채팅 화면을 [기록]으로 물린다 ─────────────────────────
   지우지 않는다 — 지시 §9 [전체 상담 기록은 별도 기록 기능에서 확인].
   대화 엔진(dialogue.js)의 로그는 그대로 쌓이고, 여기서는 감춰만 둔다. */
body.tj-on{ padding-top:0 !important; overflow:hidden; }
body.tj-on #chat{ display:none; }
body.tj-on::after{ display:none; }            /* reading-ui.css 의 바닥 원 장식 — 무대와 겹친다 */

/* ── 무대(루나) ───────────────────────────────────────────────
   영상/스틸이 화면을 가득 채우고, 그 위에 상담 UI 가 얹힌다.
   지시 §1: "영상 위에 앱 UI가 덮여 있다는 느낌보다 루나 앞에서 대화를 시작하는 것처럼". */
.tj-stage{
  /*  얼굴이 놓인 세로 자리 — 도사집(`--dj-face-y`)과 같은 방식으로 변수로 뺐다(2026-09-05).
      기본 16% 는 지금까지 쓰던 값 그대로다. **글을 쓰는 동안에만** 이 값을 위로 올려
      루나를 얼굴 위주로 남기고 그 아래를 대화에 내준다(아래 tj-typing 절). */
  --tj-face-y:16%;
  position:fixed; inset:0; z-index:0; overflow:hidden;
  /* 2026-09-10 [루나 상담 대화방 UI 리뉴얼 §4·§5] — 짙은 남보라(#2a1c3c) + 옛 어두운 상담실에서
     밝은 블루아워 톤으로. 바탕색은 새 배경 원화의 하늘 중간톤(실측 #5970b2)으로 바꿔
     로딩 찰나에도 어두운 색이 번쩍이지 않게 한다. base.jpg 는 같은 자리에 새 원화로 덮어썼다
     (경로·코드는 그대로 — 자산\이미지로그.md 2026-09-10 항목). */
  background:#5970b2 url("assets/village/shops/tarojip/base.jpg") center 18% / cover no-repeat;
}
/* 카메라 — 화면이 [정지 사진]으로 보이지 않게 하는 한 겹 (2026-08-28 사람 지적 3차).
   ★ 값은 CSS 가 정하지 않는다. shop-tarojip.js 의 카메라흔들기() 가 5.5~9초에 한 번씩
     배율·위치를 다시 잡아 인라인으로 얹는다 — 같은 프레임이 두 번 같은 크기로 서지 않는다.
   ★ 세로 폰에서는 cover 가 세로를 꽉 채우고 좌우를 잘라내므로 object-position 의 Y 는
     아무 일도 하지 않는다(412x915 실측). 그래서 시선도 transform 으로 만든다. */
.tj-cam{
  position:absolute; inset:0; transform-origin:50% 38%;
  transform:scale(1.035) translate(0,0.6%);
  will-change:transform;
}
.tj-stage .tj-video,
.tj-stage .tj-still{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:46% var(--tj-face-y, 16%);
}
/* 영상은 두 벌이 겹쳐 있고, 끝나기 0.9초 전에 다음 토막이 **위에서 덮는다**.
   ★ 두 겹을 동시에 흐리는 크로스페이드가 아니다 — 그러면 한가운데서 둘 다 반투명이 되어
     뒤 배경이 비치고 화면이 뿌옇게 뜬다(2026-08-29 사람 지적). 나가는 쪽은 끝까지 불투명하다.
   ★ 실제 opacity/z-index 는 shop-tarojip.js 의 넘기기() 가 인라인으로 얹는다. */
.tj-stage .tj-video{ opacity:0; transition:opacity .9s ease-in; }
.tj-stage .tj-still{ opacity:0; z-index:4; transition:opacity .6s ease; }
/* 상태 전용 컷 한 장 — 그 상태의 영상이 아직 없을 때 이 그림이 그 자리를 맡는다.
   영상과 같은 0.9초 디졸브로 얹고 걷는다. 카메라(위)가 이 컷도 함께 아주 느리게 움직인다. */
/* 컷·스틸은 영상보다 **위**다. 영상 두 벌이 z-index 1/2 를 번갈아 쓰므로(넘기기())
   여기에 자리를 안 주면 컷이 영상 밑으로 깔린다(2026-08-29). */
.tj-stage .tj-shot{
  position:absolute; inset:0; width:100%; height:100%; z-index:3;
  object-fit:cover; object-position:46% var(--tj-face-y, 16%);
  opacity:0; transition:opacity .9s ease;
}
body.tj-shot-on .tj-stage .tj-shot{ opacity:1; }
body.tj-still-on .tj-stage .tj-video{ opacity:0 !important; }
body.tj-still-on .tj-stage .tj-still{ opacity:1; }

/* 시선(지시 §8)도 같은 카메라가 맡는다 — 카드를 볼 땐 조금 당겨 테이블 쪽으로,
   중요한 말을 건넬 땐 얼굴 쪽으로. 그 값도 JS 가 얹는다(위 ★). */

/* 숨결 — 정지 화면이 [멈춘 그림]으로 보이지 않게 하는 최소한의 생명 (2차에서 idle 영상으로 교체) */
@media (prefers-reduced-motion: no-preference){
  /* 숨결은 스틸 자신이 쉰다 — 카메라(시선)와 자리를 다투지 않는다 */
  body.tj-still-on .tj-stage .tj-still{ animation:tj-breathe 7.5s ease-in-out infinite; }
}
@keyframes tj-breathe{
  0%,100%{ transform:scale(1.000); }
  50%    { transform:scale(1.008); }
}

/* 방의 공기 — 위아래로만 아주 옅게. UI 가 얹힐 자리를 미리 살짝 죽여 둔다.
   2026-09-10 [루나 상담 대화방 UI 리뉴얼 §4] — 짙은 먹색 스크림은 밝은 블루아워 배경을
   다시 어둡게 눌러 버려서 톤을 남색 계열로 옅게 낮췄다(글자 대비만 지키는 최소량). */
.tj-air{
  position:fixed; inset:0; z-index:1; pointer-events:none;
  background:
    linear-gradient(180deg, rgba(40,44,74,.24) 0%, rgba(40,44,74,.05) 16%, transparent 30%),
    radial-gradient(120% 60% at 50% 105%, rgba(40,34,58,.16), transparent 62%);
}
/* 방의 공기가 아주 약하게 숨쉰다(CHAPTER 1 §C — 새 그림 없이 opacity 만, 6% 진폭·13초 한 바퀴).
   의식적으로 [움직인다]고 느끼면 실패라 진폭을 아주 작게 뒀다. */
@media (prefers-reduced-motion: no-preference){
  .tj-air{ animation:tj-air-breathe 13s ease-in-out infinite; }
}
@keyframes tj-air-breathe{ 0%,100%{ opacity:1; } 50%{ opacity:.94; } }

/* ── Conversation Focus Mode 배경 veil (CHAPTER 1 §A, 2026-09-12) ──────────────
   과거 메시지를 읽는 동안(shop-tarojip.js `포커스갱신()`)만 `.tj-air` 위에 조금 더 짙은
   겹을 하나 더 얹는다 — 새 DOM·불투명 채팅창을 만들지 않고 같은 층의 opacity 만 올린다.
   루나 위치·크기는 여기서 전혀 안 건드린다(사람 지시 — 점프·크기 변화 금지). */
.tj-air::after{
  content:""; position:absolute; inset:0;
  background:
    linear-gradient(180deg, rgba(20,14,34,.30) 0%, rgba(20,14,34,.10) 24%, transparent 46%),
    radial-gradient(120% 60% at 50% 105%, rgba(20,14,34,.22), transparent 62%);
  opacity:0; transition:opacity .5s ease;
}
body.tj-focus .tj-air::after{ opacity:1; }
@media (prefers-reduced-motion: reduce){
  .tj-air::after{ transition:none; }
}

/* ── CARD TRACE / 카드의 흔적 (CHAPTER 6.5, 2026-09-14) ──────────────────────
   KEY INSIGHT(✦ 루나가 본 핵심) 직전에만 아주 짧게 뜨는 시그니처 연출. `.tj-air`(Focus Mode
   베일)와 같은 z-index 층이지만 섞지 않고 별도 DOM 형제 요소로 둔다(shop-tarojip.js).
   얼굴은 화면 상단 중앙(--tj-face-y 16% 부근·object-position 46%)에 있어 그 자리를 피해
   좌우 위쪽 가장자리("창가")에만 아주 옅게 둔다 — 중앙을 직접 밝히는 radial-gradient 는 없다.
   1차는 MOON/SUN/LOVE + NEUTRAL 4종만(사람 지시 — CHANGE/GROUNDED 는 이번에 안 만든다). */
.tj-trace{
  position:fixed; inset:0; z-index:1; pointer-events:none;
  opacity:0; transition:opacity .5s ease;
}
body.tj-trace-on .tj-trace{ opacity:1; }
@media (prefers-reduced-motion: reduce){
  .tj-trace{ transition:none; }
}

/*  2026-09-14 실기기 실측(픽셀 대조) 함정 — `.tj-trace.tj-trace-moon`(요소 자신이 두 클래스를
    같이 가져야 매치)로 썼는데, family 클래스는 **body** 에 토글된다(shop-tarojip.js 카드트레이스켜기()
    — 위 `body.tj-trace-on .tj-trace{opacity:1}` 과 같은 자손 결합자 패턴). 그래서 opacity 만 1이
    되고 배경 자체가 안 붙어 3배를 올려도 픽셀 차가 그대로였다 — 선택자를 body 자손형으로 고친다. */
body.tj-trace-moon .tj-trace{
  background:
    radial-gradient(40% 26% at 6% 8%, rgba(210,204,240,.30), transparent 60%),
    radial-gradient(34% 22% at 94% 9%, rgba(190,200,232,.22), transparent 60%);
}
body.tj-trace-sun .tj-trace{
  background:
    radial-gradient(40% 26% at 6% 8%, rgba(244,210,148,.32), transparent 60%),
    radial-gradient(34% 22% at 94% 9%, rgba(236,196,128,.24), transparent 60%);
}
body.tj-trace-love .tj-trace{
  background:
    radial-gradient(40% 26% at 6% 8%, rgba(240,186,208,.30), transparent 60%),
    radial-gradient(34% 22% at 94% 9%, rgba(230,184,218,.22), transparent 60%);
}
/* NEUTRAL — 상담방 분위기와 거의 차이가 안 나는 수준. "효과 없음처럼 보여도 된다"(사람 지시). */
body.tj-trace-neutral .tj-trace{
  background:
    radial-gradient(50% 30% at 50% 5%, rgba(230,224,210,.10), transparent 66%);
}
/*  MOON 만 아주 느린 breathing(5~8%) — SUN/LOVE/NEUTRAL 은 정적에 가깝게 둔다(사람 지시). */
@media (prefers-reduced-motion: no-preference){
  body.tj-trace-moon .tj-trace{ animation:tj-trace-breathe 9s ease-in-out infinite; }
}
@keyframes tj-trace-breathe{ 0%,100%{ opacity:1; } 50%{ opacity:.93; } }

/* ── 상담 패널 (지시 §2 하단 35~45%) ───────────────────────── */
.tj-panel{
  position:fixed; left:0; right:0; z-index:3;
  bottom:var(--banner-ad-height, 0px);
  /* 2026-09-10 2차 POLISH §7 — 10px→16px. 광고 배너 바로 위에서 입력창이 너무 붙어 보였다. */
  padding:0 14px calc(16px + env(safe-area-inset-bottom, 0px));
  display:flex; flex-direction:column; gap:9px;
  /* 2026-09-10 2차 POLISH §1 — 실기기 배너 광고(~80px)가 패널을 `bottom` 만큼 밀어 올리는데
     `max-height` 는 그대로면 패널 **윗변**이 그만큼 더 위로(얼굴 쪽으로) 올라간다(실기기 실측
     — 헤드리스(배너 0)에서는 안전했던 배치가 실기기에서 눈까지 침범했다). 배너 높이를
     max-height 에서도 그대로 빼서 패널 윗변 위치를 배너 유무와 무관하게 고정한다. */
  max-height:calc(45dvh - var(--banner-ad-height, 0px));  /* 지시 §2 — 카드가 화면을 다 먹지 않는다 */
  background:linear-gradient(180deg,
    rgba(24,15,36,0) 0%, rgba(24,15,36,.42) 16%, rgba(20,12,30,.80) 46%, rgba(17,10,26,.94) 100%);
  padding-top:26px;
}
/* 데스크톱·태블릿에서 가로로 늘어지지 않게 (reading.css 의 max-width 규약과 같은 결) */
.tj-panel > *{ width:100%; max-width:520px; margin:0 auto; }

/* ── 자막 (지시 §9 · §10) ─────────────────────────────────────
   말풍선을 쌓지 않는다. 지금 루나가 말하는 한 마디만 아래에 자막으로 둔다. */
.tj-say{
  position:relative; min-height:78px;
  padding:11px 14px 12px; border-radius:16px;
  border:1px solid rgba(201,169,97,.26);
  background:linear-gradient(180deg, rgba(58,40,74,.72), rgba(38,25,54,.80));
  box-shadow:0 6px 22px rgba(12,7,20,.34);
  backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px);
}
.tj-who{
  display:block; margin-bottom:3px;
  font-size:.66rem; letter-spacing:.12em; font-weight:700;
  color:var(--pg-gold, #c9a961);
}
.tj-line{
  margin:0; min-height:2.7em;              /* 문장 길이가 달라도 패널이 튀지 않게 (지시 §17) */
  color:var(--pg-ink, #f6efe3); font-size:.945rem; line-height:1.55;
  white-space:pre-line; word-break:keep-all;
  animation:tj-line-in .34s ease both;
}
@keyframes tj-line-in{ from{ opacity:0; transform:translateY(4px); } to{ opacity:1; transform:none; } }
.tj-say.is-fading .tj-line{ opacity:.18; transition:opacity .16s ease; }

/* [계속 듣기] — 자막 오른쪽 아래에 작게. 화면 아무 데나 탭해도 같은 일이 일어난다. */
.tj-next{
  position:absolute; right:10px; bottom:-9px;
  border:1px solid rgba(201,169,97,.42); border-radius:999px;
  background:linear-gradient(180deg, rgba(78,58,96,.96), rgba(48,32,66,.96));
  color:var(--pg-ink, #f6efe3); font-family:inherit; font-size:.72rem;
  padding:5px 13px; cursor:pointer; box-shadow:0 3px 12px rgba(12,7,20,.4);
}
.tj-next[hidden]{ display:none; }
@media (prefers-reduced-motion: no-preference){
  .tj-next{ animation:tj-nudge 2.4s ease-in-out infinite; }
}
@keyframes tj-nudge{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(2px); } }

/* 생각 중 — 점 세 개 (지시 §4 [약간의 인간적인 호흡]) */
.tj-think{ display:inline-flex; gap:5px; align-items:center; height:1.4em; }
.tj-think i{
  width:5px; height:5px; border-radius:50%; background:var(--pg-sub, #c9bcd6);
  animation:tj-dot 1.05s ease-in-out infinite;
}
.tj-think i:nth-child(2){ animation-delay:.16s; }
.tj-think i:nth-child(3){ animation-delay:.32s; }
@keyframes tj-dot{ 0%,70%,100%{ opacity:.25; transform:translateY(0); } 35%{ opacity:1; transform:translateY(-3px); } }

/* ── 테이블 (지시 §5 · §6) ────────────────────────────────────
   카드는 [앱의 카드 선택 메뉴]가 아니라 [루나 앞 테이블에 놓인 것]이어야 한다.
   그래서 카드 줄은 패널 안이지만 배경이 없다 — 영상 속 나무 테이블이 그대로 비친다. */
.tj-table{
  display:flex; flex-direction:column; align-items:center; gap:6px;
  /* 2026-09-03 #152 실기기 반려 — 옛 값은 `min-height:0` 이었다. 그러면 패널이 `max-height`(:392)에
     닿는 순간 **테이블이 먼저 짜부라지고**, `justify-content:flex-end` 때문에 카드 줄이 패널 **위쪽 밖으로**
     넘쳐 나가 루나의 눈에 앉았다(DEEP_OFFER 실측: 자리표 top 266px = 29.5dvh · 턱선 368px).
     `flex:0 0 auto` 로 테이블은 제 키를 지키고, 넘치는 몫은 `.tj-chat`(flex:1 1 auto · min 96px)이 스크롤로 먹는다.
     카드가 없을 땐 `.tj-slots` 가 비어 높이 0 이라 [루나가 더 보인다]는 그대로다. */
  flex:0 0 auto; justify-content:flex-end;
}
.tj-hint{
  font-size:.7rem; color:var(--pg-sub, #c9bcd6); letter-spacing:.02em;
  text-shadow:0 1px 6px rgba(12,7,20,.7);
  order:3; margin-top:2px;                  /* #152 — 자리표 위(루나 얼굴)가 아니라 덱 아래에 선다 */
}
.tj-slots{ order:1; }
.tj-deck{ order:2; }
/* #152 — 고르는 동안(body.tj-picking) 대화창을 낮춘다. 자리표 + 덱이 같이 서는 유일한 구간이라
   이때만 패널이 커지는데, 그 높이가 루나 턱까지 올라왔다(2026-09-03 PC 눈검사 412×915). */
body.tj-chatmode.tj-picking .tj-chat{ max-height:15dvh; }
/* 다 고르면 덱이 접힌다 — 툭 사라지면 카드 세 장이 한 번에 내려앉는다 */
.tj-deck{ transition:height .34s ease, opacity .24s ease; }
.tj-deck.is-gone{ height:0 !important; opacity:0; overflow:hidden; pointer-events:none; }

/* ── 셔플 → 펼침 → 고르기 (2026-09-03 #152 · 2026-09-04 #174~#176 판12 · 경험계약 §5-1) ─────
   같은 버튼들(15~22장)이 세 상태를 지난다: [쌓임](기본) → .is-shuffling(리플) → .is-fanned(부채).
   ★ 펼쳐진 부채가 곧 선택 UI 다 — 마지막 프레임 뒤에 DOM 도 위치도 안 바뀐다(영상→UI 전환 없음).
   ★ #174 — 카드 수가 15~22장으로 가변이라 nth-child 고정값을 버렸다. 자리는 shop-tarojip.js 의
     `셔플펼치기()` 가 카드마다 --sx(쌓임)·--fx/--fy/--fr(펼침 아치)·--stagger(20~35ms 스태거)로 얹는다.
   ★ .tj-deck 는 위치 기준점만 준다(position:relative) — 카드들은 absolute 로 가운데(left:50%)에서 편다.
     그래야 22장이 와도 flex 폭이 안 넘친다.
   시간은 shop-tarojip.js 의 셔플ms(1800) · 펼침ms(560) 가 정한다 — 여기 리플 3회 × .5s = 1.5s 는 그 안에 끝난다. */
.tj-deck{ display:flex; justify-content:center; align-items:flex-end; height:104px; position:relative; }
.tj-deck[hidden]{ display:none; }
.tj-back{
  position:absolute; left:50%; bottom:0; margin-left:-28px;
  width:56px; height:90px; border-radius:8px; padding:0; border:1px solid rgba(255,255,255,.18);
  background:url("assets/cards/back.webp") center/cover no-repeat;
  box-shadow:0 4px 14px rgba(10,6,18,.5);
  cursor:pointer; transform-origin:bottom center;
  transform:translateX(var(--sx,0px)) translateY(-3px);           /* 쌓임 — 가운데로 모인 더미 */
  transition:transform .56s cubic-bezier(.2,.8,.3,1.05) var(--stagger,0ms), opacity .12s ease, box-shadow .2s ease;
}
/* 리플 — 홀수 장은 왼쪽으로, 짝수 장은 오른쪽으로 빠졌다가 더미로 돌아온다. 세 번.
   카드마다 --stagger 만큼 늦게 시작해 [한꺼번에 쾅]이 아니라 사르르륵 흩어진다. */
.tj-deck.is-shuffling .tj-back:nth-child(odd){  animation:tj-riffle-l .5s ease-in-out 3; animation-delay:var(--stagger,0ms); }
.tj-deck.is-shuffling .tj-back:nth-child(even){ animation:tj-riffle-r .5s ease-in-out 3; animation-delay:var(--stagger,0ms); }
@keyframes tj-riffle-l{
  0%,100%{ transform:translateX(var(--sx,0px)) translateY(-3px) rotate(0deg); }
  50%    { transform:translateX(calc(var(--sx,0px) - 38px)) translateY(-14px) rotate(-10deg); }
}
@keyframes tj-riffle-r{
  0%,100%{ transform:translateX(var(--sx,0px)) translateY(-3px) rotate(0deg); }
  50%    { transform:translateX(calc(var(--sx,0px) + 38px)) translateY(-8px) rotate(10deg); }
}
/* 부채 — 더미에서 아치형으로 펼쳐진다(.56s + 카드마다 스태거). 이 자리가 곧 고르는 자리다. */
.tj-deck.is-fanned .tj-back{ transform:translateX(var(--fx,0px)) translateY(var(--fy,-3px)) rotate(var(--fr,0deg)); }
.tj-deck.is-fanned .tj-back:hover:not(:disabled),.tj-deck.is-fanned .tj-back:focus-visible{
  transform:translateX(var(--fx,0px)) translateY(calc(var(--fy,-3px) - 6px)) rotate(0deg) scale(1.03);
  outline:none; box-shadow:0 8px 20px rgba(10,6,18,.6);
}
/* #175 (판12 · 명령서 "손맛 1차 포인트") — 모바일엔 hover 가 없다. 손끝을 대는 순간(pointerdown)
   살짝 뜨고 커진다(↑2~3px · scale 1.025). 손을 떼면 원위치(js 가 .is-press 를 뗀다). */
.tj-deck.is-fanned .tj-back.is-press:not(:disabled){
  transform:translateX(var(--fx,0px)) translateY(calc(var(--fy,-3px) - 2.5px)) rotate(var(--fr,0deg)) scale(1.025);
  box-shadow:0 6px 18px rgba(10,6,18,.58);
}
/* 누른 카드는 그 자리에서 사라진다 — 같은 사각형에서 tj-card 가 날아오르므로 움직이면 두 장으로 보인다 */
.tj-deck .tj-back.is-taken{ opacity:0; pointer-events:none; }
/* #175 — 선택이 확정된 순간, 고른 카드 말고는 잠깐 죽는다(주변 카드 opacity 1 → .75). */
.tj-deck.is-picking .tj-back:not(.is-taken){ opacity:.75; transition:opacity .16s ease; }

/* 빈 자리표 — 셔플 전에 미리 깔린다(지금 마음 · 망설임 · 앞으로). 카드가 앉으면 테두리가 사라진다. */
.tj-card.is-empty .tj-card-inner{ border:1px dashed rgba(255,240,205,.78); background:transparent; }   /* 1.1.2 — 빈 자리 회색 채움(루나 얼굴이 흐려 보였다)을 없애고 얇은 점선만 남긴다 */
.tj-card.is-empty .tj-cardname{ opacity:.85; }
/* 부채에서 날아오는 동안 — 배치 등장 애니메이션(tj-place)이 인라인 transform 을 덮지 않게 끈다 */
.tj-card.is-flying{ z-index:5; animation:none !important; }
.tj-card.is-placed{ animation:none !important; }     /* 앉은 뒤에도 등장 애니메이션이 다시 돌지 않게 */
/* #175 — 선택된 카드 테두리에 아주 약한 빛(날아가는 동안만). */
.tj-card.is-flying .tj-face{ box-shadow:0 14px 28px rgba(10,6,18,.62), 0 0 0 1.5px rgba(201,169,97,.5); }

/* 뽑힌 자리 — 3장이 테이블 위에 남는다(지시 §6 [카드1][카드2][카드3] 유지) */
/* padding-bottom 은 카드 이름표가 앉을 자리다 — 없으면 아래 [상담 기록] 줄과 겹친다(2026-08-28 실측) */
/*  position:relative 는 ⚡(케미)의 기준점이자 카드 offsetParent 다 — 조건부로 켜면
    `케미주기()` 가 재는 offsetLeft 의 기준이 그때그때 달라진다. 늘 켜 둔다. */
.tj-slots{ display:flex; justify-content:center; align-items:flex-end; gap:11px; padding-bottom:26px; position:relative; }
.tj-slots[hidden]{ display:none; }
.tj-card{
  width:74px; height:118px; perspective:640px; position:relative;
  transition:transform .42s cubic-bezier(.2,.8,.3,1), filter .42s ease;
  animation:tj-place .38s cubic-bezier(.2,.8,.3,1.1) both;
}
@keyframes tj-place{ from{ opacity:0; transform:translateY(16px) scale(.9); } to{ opacity:1; transform:none; } }
.tj-card-inner{
  position:absolute; inset:0; transform-style:preserve-3d;
  transition:transform .62s cubic-bezier(.3,.7,.3,1);
  border-radius:8px;
}
.tj-card.is-open .tj-card-inner{ transform:rotateY(180deg); }
/* 카드 공개 순간 아주 옅은 금빛 한 번(CHAPTER 1 §C — bounce·particle·강한 glow 없이,
   0.7초 안에 조용히 사그라든다). `.tj-face`(:271)의 기본 box-shadow 로 자연히 돌아간다. */
@media (prefers-reduced-motion: no-preference){
  .tj-card.is-open .tj-face-front{ animation:tj-reveal-glow .7s ease-out; }
}
@keyframes tj-reveal-glow{
  0%  { box-shadow:0 5px 16px rgba(10,6,18,.5), 0 0 0 0 rgba(201,169,97,0); }
  45% { box-shadow:0 5px 16px rgba(10,6,18,.5), 0 0 20px 3px rgba(201,169,97,.4); }
  100%{ box-shadow:0 5px 16px rgba(10,6,18,.5), 0 0 0 0 rgba(201,169,97,0); }
}
.tj-face{
  position:absolute; inset:0; border-radius:8px; overflow:hidden;
  backface-visibility:hidden; -webkit-backface-visibility:hidden;
  box-shadow:0 5px 16px rgba(10,6,18,.5);
  border:1px solid rgba(255,255,255,.16);
}
.tj-face-back{ background:url("assets/cards/back.webp") center/cover no-repeat; }
.tj-face-front{ transform:rotateY(180deg); background:#170f24; }
.tj-face-front img{ width:100%; height:100%; object-fit:cover; display:block; }
.tj-face-front img.rev{ transform:rotate(180deg); }

/* 지금 설명 중인 카드만 아주 미세하게 (지시 §12 — 게임처럼 번쩍이지 않는다) */
/*  ── 지금 해석 중인 카드 (2026-09-05 사람 지시 ⑥ [카드도 살아 움직여야 한다]) ──────────
    지시 그대로: **110~115% 확대 · 살짝 위로 · 은은한 Glow**, 나머지는 약간 어둡게.
    앞판은 103% 에 얇은 금테라 [무엇을 말하는 중인지] 가 눈에 안 들어왔다(사람: "5장이 동일하게 고정").
    ★ 확대는 112% 로 잡았다 — 110~115% 의 가운데다. 카드 폭 74px 기준 83px 이 되고
      옆 카드와의 간격(gap 8px)을 넘지 않아 겹치지 않는다.
    ★ Glow 는 금색 한 겹뿐이다. 새 색을 만들지 않았다(--pg-gold 계열). */
.tj-card.is-focus{ transform:translateY(-7px) scale(1.12); z-index:2; }
.tj-card.is-focus .tj-face{
  box-shadow:0 0 0 1.5px rgba(201,169,97,.72),
             0 0 16px 2px rgba(201,169,97,.34),      /* 은은한 Glow */
             0 10px 24px rgba(10,6,18,.58);
}
/*  핵심 카드 — [내가 신경 쓰이는 건 얘야] 하는 그 한 장. 포커스보다 한 단계 더 강하다.
    포커스와 겹쳐 걸릴 수 있으므로 뒤에 둔다(같은 특이도면 나중 것이 이긴다). */
.tj-card.is-key{ transform:translateY(-10px) scale(1.16); z-index:3; }
.tj-card.is-key .tj-face{
  box-shadow:0 0 0 2px rgba(233,199,123,.92),
             0 0 26px 4px rgba(233,199,123,.46),
             0 12px 28px rgba(10,6,18,.62);
}
@media (prefers-reduced-motion: no-preference){
  .tj-card.is-key{ animation:tj-key-pulse 2.6s ease-in-out infinite; }
}
@keyframes tj-key-pulse{
  0%,100%{ filter:brightness(1); }
  50%    { filter:brightness(1.06); }
}
/*  나머지 카드 — [어둡게]를 앞판보다 한 단계 더. 포커스 카드가 확실히 앞으로 나오게 한다. */
.tj-card.is-dim{ filter:saturate(.62) brightness(.68); transform:scale(.97); }

/* #177 (판12 · 명령서 §12 "중요한 카드는 확대") — 지금 설명 중인 카드가 화면 중앙으로 커진다.
   자리·배율은 shop-tarojip.js 의 카드확대() 가 FLIP 기법(지금 자리 → 0 으로 되돌린 transform)으로 인라인 준다 —
   이 규칙은 [떠날 자리](position:fixed·중앙)만 정하고, 실제 애니메이션 값은 인라인 style 이 이긴다. */
.tj-card.is-zoom{
  position:fixed; left:50%; top:44dvh; z-index:22;    /* 얼굴(상단 ~30dvh)을 안 덮게 조금 더 아래 */
  transform-origin:center center; margin:0;
}
.tj-card.is-zoom .tj-face{ box-shadow:0 18px 44px rgba(6,3,12,.6), 0 0 0 1.5px rgba(201,169,97,.55); }
/* 확대 중엔 배경을 살짝 어둡게 — 무대 위, 카드 아래(z-index 21 < 22). */
.tj-zoomdim{
  position:fixed; inset:0; z-index:21; pointer-events:none;
  background:rgba(10,6,16,0); transition:background .32s ease;
}
body.tj-card-zoom-on .tj-zoomdim{ background:rgba(10,6,16,.34); }
/* 확대 중엔 나머지(자리에 남은) 카드 이름표를 잠깐 숨긴다 — 안 그러면 화면 자리가 겹쳐
   [자리 이름 두 개가 겹쳐 보이는] 일이 생긴다(2026-09-04 실기기 실측). */
body.tj-card-zoom-on .tj-slots .tj-card:not(.is-zoom) .tj-cardname{ opacity:0 !important; }
/* CHAPTER 1 §B — 확대된 카드 자신의 이름표도 숨긴다(2026-09-12 실기기 SM-F966N 실측:
   `top:44dvh` + 1.55배 확대 + 이름표 `bottom:-34px` 가 겹쳐 채팅 패널 위쪽 말풍선과
   같은 자리에 글자 두 겹이 보였다 — "망설임"·"바보 (역)" 금색 글자가 해석 말풍선 위에
   그대로 얹혀 읽을 수 없었다). 카드 이름·정역방향은 이미 해석 말풍선 문장이 말로 알려준다. */
body.tj-card-zoom-on .tj-card.is-zoom .tj-cardname{ opacity:0 !important; }
/* CHAPTER 1 §B FINAL CLOSE §1 — 확대 카드 하단과 해석 말풍선 첫 줄이 여전히 살짝 붙어 보여
   여백만 조금 준다. 카드 자리(top:44dvh)·배율(1.55x)·애니메이션은 그대로 — `.tj-table`
   아래 여백만 늘려 `.tj-chat` 시작점을 살짝 내린다(카드는 fixed 라 이 여백과 무관하게 그 자리 그대로다). */
body.tj-card-zoom-on .tj-table{ margin-bottom:14px; }

.tj-cardname{
  position:absolute; left:-8%; right:-8%; bottom:-34px; text-align:center;   /* 1.3배 두 줄 29.38px (:396 과 같은 이유) */
  font-size:.58rem; line-height:1.25; letter-spacing:.01em; color:var(--pg-ink, #f6efe3);
  text-shadow:0 1px 5px rgba(12,7,20,.95);
  opacity:0; transition:opacity .3s ease .2s;
}
.tj-cardname b{ display:block; font-weight:600; font-size:.55rem; color:var(--pg-gold, #c9a961); letter-spacing:.06em; }
.tj-card.is-open .tj-cardname{ opacity:1; }

/* ── 고를 것 (지시 §3 빠른 선택 · §14 후속 질문) ───────────── */
.tj-acts{ display:flex; flex-wrap:wrap; justify-content:center; gap:7px; }
.tj-acts[hidden]{ display:none; }
/* 2026-09-10 [루나 상담 대화방 UI 리뉴얼 §4] — 어두운 유리 칩 → 크림/라일락 계열.
   후속 질문("세 장으로 흐름까지 보기" 등)·6주제 칩의 바탕 겹인 이 규칙이 밝아지면
   그 위에 얹는 개별 색(is-grid [data-tone] 등)은 그대로 살아 영향이 없다. */
.tj-acts button{
  border:1px solid rgba(201,169,97,.32); border-radius:999px;
  background:linear-gradient(180deg, #fffaf3, #f8ecdd);
  color:#4a3b2e; font-family:inherit; font-size:.8rem; font-weight:500;
  padding:9px 15px; min-height:38px; cursor:pointer;
  box-shadow:0 3px 12px rgba(120,90,60,.18);
  transition:transform .14s ease, background .18s ease;
  animation:tj-rise .34s cubic-bezier(.22,.9,.3,1) backwards;
}
.tj-acts button:active{ transform:scale(.97); }
.tj-acts button.is-key{
  border-color:rgba(201,169,97,.68); color:#5c4419; font-weight:700;
  background:linear-gradient(180deg, rgba(201,169,97,.42), rgba(201,169,97,.22));
}
.tj-acts button.is-quiet{ background:rgba(255,255,255,.55); color:#7a6a5a; font-size:.76rem; border-color:rgba(201,169,97,.22); }
.tj-acts button .tj-cost{ margin-left:6px; font-size:.68rem; color:#8a6a2e; font-weight:700; }
@keyframes tj-rise{ from{ opacity:0; transform:translateY(12px); } to{ opacity:1; transform:none; } }

/* ── 발밑 줄 (기록 · AI 고지 · 신고) ───────────────────────── */
.tj-foot{
  display:flex; justify-content:center; align-items:center; gap:10px;
  min-height:18px; font-size:.64rem; color:rgba(201,188,214,.72);
}
.tj-foot button{
  border:0; background:none; padding:2px 4px; cursor:pointer;
  color:rgba(201,188,214,.86); font-family:inherit; font-size:.64rem;
  text-decoration:underline; text-underline-offset:2px;
}
.tj-foot [hidden]{ display:none; }

/* ── 직접 질문 입력칸 — 원래 있던 #composer 를 패널 안으로 들인다 ──
   새 입력창을 만들지 않는다(규칙 6). reading.js 의 submit 리스너가 그대로 산다. */
body.tj-on #composer{
  border-top:0; background:none; padding:0; max-width:520px;
  animation:tj-rise .34s cubic-bezier(.22,.9,.3,1) both;
}
body.tj-on #user-input{
  background:rgba(24,16,38,.86); border-color:rgba(255,255,255,.20); color:var(--pg-ink, #f6efe3);
}
body.tj-on #send-btn{ background:linear-gradient(180deg,#8b6bc4,#6f4fae); }

/* ── 기록 보기 (지시 §9 [별도의 기록 기능]) ────────────────── */
.tj-log{
  position:fixed; inset:0; z-index:30; display:none;
  background:rgba(14,9,22,.86); backdrop-filter:blur(4px); -webkit-backdrop-filter:blur(4px);
}
body.tj-log-open .tj-log{ display:block; }
body.tj-log-open #chat{
  display:flex; position:fixed; z-index:31;
  left:0; right:0; top:calc(var(--pg-row1, 12px) + 44px); bottom:0;
  overflow-y:auto; padding:8px 14px 28px;
}
.tj-log-bar{
  position:fixed; z-index:32; left:0; right:0; top:0;
  height:calc(var(--pg-row1, 12px) + 44px);
  display:flex; align-items:flex-end; justify-content:space-between;
  padding:0 14px 8px; color:var(--pg-ink, #f6efe3); font-size:.82rem;
}
.tj-log-bar button{
  border:1px solid var(--pg-line, rgba(255,255,255,.24)); border-radius:999px;
  background:var(--pg-glass, rgba(38,28,56,.7)); color:var(--pg-ink, #f6efe3);
  font-family:inherit; font-size:.76rem; padding:6px 13px; cursor:pointer;
}

/* ── 작은 화면 (지시 §17 — 얼굴이 잘리지 않고 카드가 너무 작지 않게) ── */
@media (max-height:680px){
  .tj-panel{ max-height:calc(44dvh - var(--banner-ad-height, 0px)); gap:7px; padding-top:20px; }
  .tj-say{ min-height:74px; }
  .tj-line{ font-size:.9rem; min-height:2.7em; }
  .tj-table{ min-height:112px; }
  .tj-card{ width:66px; height:106px; }
  .tj-deck{ height:94px; }
  .tj-back{ width:50px; height:80px; }
}
@media (min-width:520px){
  .tj-card{ width:82px; height:131px; }
  .tj-back{ width:62px; height:100px; }
  .tj-deck{ height:114px; }
}

/* ── 동작 줄이기 ─────────────────────────────────────────────
   지시 §6 [과한 연출 금지]와 같은 방향이다. 여기서는 전부 끄고 즉시 상태만 남긴다. */
@media (prefers-reduced-motion: reduce){
  .tj-card-inner,.tj-back,.tj-card,.tj-cam,.tj-stage .tj-video,.tj-stage .tj-shot,.tj-stage .tj-still{ transition:none !important; animation:none !important; }
  .tj-line,.tj-acts button{ animation:none !important; }
  .tj-next{ animation:none !important; }
}

/* ── 카드가 넷 이상일 때 (후속 질문으로 한 장 더 놓였을 때) ──────────
   테이블 폭은 그대로 두고 카드를 줄인다 — 화면 밖으로 밀려나지 않게(지시 §17). */
.tj-slots.is-many .tj-card{ width:60px; height:96px; }
.tj-slots.is-many{ gap:8px; }
.tj-slots.is-many .tj-cardname{ font-size:.53rem; bottom:-33px; }   /* 1.3배 두 줄 28.08px — :396 과 같은 이유 · −32 는 여유 3.9px 로 계약 4px 에 0.1px 모자랐다(2026-09-04 실기기) */
/* 여섯 장(무료 3 + 심층 3 · #152) — 360px 폭에서도 한 줄에 선다: 6×46 + 5×6 = 306 */
.tj-slots.is-crowd{ gap:6px; padding-bottom:34px; }      /* 이름표 두 줄이 대화창 첫 말풍선에 안 닿게 · 이름표를 1px 내렸으니 여기도 1px */
.tj-slots.is-crowd .tj-card, body.tj-chatmode .tj-slots.is-crowd .tj-card{ width:46px; height:74px; }
.tj-slots.is-crowd .tj-cardname{ font-size:.48rem; bottom:-32px; left:-14%; right:-14%; }   /* 1.3배 두 줄 26.78px · −31 은 여유 3.7px 로 계약 4px 에 0.3px 모자랐다(2026-09-04 실기기) */

/* ── 마을로 나갈 때 — 씬매니저 전환이 걸리기 전 한 호흡 (지시 §15) ── */
@media (prefers-reduced-motion: no-preference){
  body.tj-leaving .tj-panel{ opacity:0; transform:translateY(10px); transition:opacity .32s ease, transform .32s ease; }
}

/* 도사집(`body.dj-on`) 배치는 2026-09-03 #151 에 **`shop-oracle-ui.css` 로 옮겼다.**
   여기 두면 타로집 정본 파일을 고치다 루나 화면이 같이 깨진다(둘이 reading.html 을 나눠 쓴다).
   이 파일에는 `dj-on` 규칙이 하나도 없어야 한다. */

/* ════════════════════════════════════════════════════════════════════
   대화창 — 카톡처럼 말풍선이 쌓인다 (2026-08-31 사람 지시 §7·§8·§16·§17)
   ────────────────────────────────────────────────────────────────────
   ★ 위의 `.tj-say`(한 줄짜리 자막)를 지우지 않는다. AI 서버가 messages 를 못 주면
     화면이 그 옛 경로로 되돌아가야 하기 때문이다(지시 §26). 두 벌은 절대 같이 뜨지 않는다 —
     `body.tj-chatmode` 가 켜지면 자막이 숨고 대화창이 그 자리를 맡는다.
   ★ 상단 루나는 그대로 둔다(지시 §7). 대화창은 하단 40~50% 안에서만 스크롤한다.
   ════════════════════════════════════════════════════════════════════ */
body.tj-chatmode .tj-say{ display:none !important; }
/* 54dvh → 52dvh (2026-09-03 #152 실기기 채점 — 그때의 옛 캐릭터·옛 배치 기준 [턱선 368px]).
   2026-09-10 2차 POLISH §1·§2 — 캐릭터를 13% 축소 + 아래로 이동한 뒤에도 52dvh 에서 헤드리스
   412x915 실측으로 다시 재보니 말풍선이 여전히 목~턱 라인에 닿았다(사람 지적 §1 그대로 재현).
   옛 측정값(368px)은 옛 캐릭터 크기 기준이라 지금은 안 맞는다 — 44dvh 로 다시 낮췄다.
   2026-09-11 [대화 영역 높이 및 스크롤 구조 개선 MASTER] §2·§3·§9 — 우선순위가 뒤집혔다:
   [루나는 고정 배경, 대화가 주인공]. 얼굴 전체를 금지 구역으로 두지 않고 눈·얼굴 중앙만
   지키면 되므로(§4) 44dvh 는 지금은 지나치게 인색하다 — 58dvh 로 다시 올린다. 카드는
   §5 COMPACT 모드로 따로 줄어들어 그 자리도 대화창(.tj-chat)에 그대로 돌아간다. */
/* 실기기 실측 — 배너(~80px)를 뺀 만큼 대화 영역 비율이 헤드리스(38.9%)보다 실기기(29.8%)에서
   그대로 줄었다(배너가 진짜로 화면을 먹는 것이므로 물리적으로 당연하다). 목표(38~45%)에
   조금 더 가깝게 58→64dvh. 눈(추정 36%)에는 여전히 안 닿는다 — 어깨·상체 overlay 는 허용됨(§4). */
body.tj-chatmode .tj-panel{ max-height:calc(64dvh - var(--banner-ad-height, 0px)); }
/* §3 — 대화 영역 자체를 38~45dvh 예산으로 명시(전엔 이 자리에 chatmode 전용 규칙이 없어
   기본값 32dvh 로 눌려 있었다). 고정 작은 값이 아니라 [남는 만큼]이 아니라 [이만큼은 준다]로 뒤집는다. */
body.tj-chatmode .tj-chat{ max-height:46dvh; }
/* CHAPTER 1 §A Conversation Focus Mode — 과거 스크롤 중엔 대화창을 조금 더 준다.
   `.tj-picking`(카드 고르는 중, css:188)이 함께 켜지는 일은 JS 쪽에서 안 만든다
   (포커스갱신() 이 tj-picking 이면 켜지 않음) — 그래도 우선순위는 그대로 지킨다. */
body.tj-chatmode.tj-focus .tj-chat{ max-height:52dvh; }
body.tj-chatmode.tj-picking.tj-focus .tj-chat{ max-height:15dvh; }
@media (prefers-reduced-motion: reduce){
  .tj-chat{ transition:none; }
}
/* 대화창이 자리를 쓰는 만큼 카드는 작게 물러난다(지시 §10 — 해석한 카드는 썸네일로) */
body.tj-chatmode .tj-slots{ gap:8px; padding-bottom:35px; }   /* 이름표를 −33px 로 1px 내렸으니 여기도 1px — 슬랙 2px 를 지킨다 */
body.tj-chatmode .tj-card{ width:56px; height:90px; }

/* ════════════════════════════════════════════════════════════════════════
   2026-09-11 [카드 결과 + KEYBOARD MODE UI 최종 개선] §1~§3 — COMPACT RESULT MODE 재설계.
   1차판은 `.tj-table` 자리(패널 안, 캐릭터 가슴~어깨 높이)에서 그대로 줄이기만 했는데,
   탭해서 펼치면(§구판 tj-cards-expanded) 원래 크기(74x118)로 돌아가 얼굴 중앙을 덮었다
   (사람 지적 §1 — 스크린샷으로 직접 확인). §3 [루나 얼굴 중앙에 배치하지 않는다 · 상단
   UI 아래 안전한 위치] 지시대로, 카드 요약을 `.tj-table` 밖 — 상단 헤더 바로 아래 —
   고정 위젯(`#tj-card-summary`/`#tj-card-detail`)으로 완전히 옮긴다.
   ★ 카드 공개(REVEAL) 애니메이션은 그대로 `.tj-table`/`.tj-slots` 를 쓴다 — 일시적 연출이라
     손 안 댔다(§2-A). 후속 대화가 시작되는 순간(카드컴팩트켜기())부터만 `.tj-table` 을
     통째로 숨기고 이 위젯이 대신한다. ════════════════════════════════════════════════════════════════════════ */
body.tj-cards-compact .tj-table{ display:none; }

#tj-card-summary{
  display:none; position:fixed; left:14px; right:14px; z-index:5;
  align-items:center; gap:8px; max-width:520px; margin:0 auto;
  border:1px solid rgba(201,169,97,.32); border-radius:999px;
  background:linear-gradient(180deg,#fffaf3,#f8ecdd);
  box-shadow:0 3px 12px rgba(120,90,60,.18);
  padding:5px 12px 5px 5px; cursor:pointer; font-family:inherit;
  text-align:left;
}
body.tj-cards-compact #tj-card-summary{ display:flex; }
/* 키보드가 뜨거나(§4 KEYBOARD MODE) 글을 쓰는 동안은 [텍스트 입력·대화]가 최우선이라
   장식성 위젯부터 물러난다(§5 [불필요한 장식 UI 축소/숨김]). */
body.tj-typing #tj-card-summary,
body.tj-typing #tj-card-detail{ display:none !important; }
.tj-cs-thumb{ width:30px; height:48px; border-radius:5px; object-fit:cover; flex:0 0 auto; box-shadow:0 2px 6px rgba(0,0,0,.22); }
.tj-cs-text{ flex:1 1 auto; min-width:0; font-size:.78rem; font-weight:600; color:#4a3b2e; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tj-cs-chevron{ flex:0 0 auto; color:#8a6a2e; font-size:.9rem; }

#tj-card-detail{
  display:none; position:fixed; left:14px; right:14px; z-index:5;
  max-width:520px; margin:0 auto;
  flex-direction:column; gap:6px;
  border:1px solid rgba(201,169,97,.32); border-radius:16px;
  background:linear-gradient(180deg,#fffdf9,#fbf0e2);
  box-shadow:0 6px 20px rgba(120,90,60,.24);
  padding:8px 10px;
}
body.tj-cards-compact #tj-card-detail:not([hidden]){ display:flex; }
.tj-cd-row{ display:flex; align-items:center; gap:8px; }
.tj-cd-thumb{ width:34px; height:54px; border-radius:5px; object-fit:cover; flex:0 0 auto; box-shadow:0 2px 6px rgba(0,0,0,.2); }
.tj-cd-text{ font-size:.78rem; color:#4a3b2e; }
/* ★ 이름표 `bottom` 은 **이름표 두 줄의 실제 높이**보다 커야 한다 — 작으면 금색 자리 이름이 카드 그림을 덮는다.
   `.tj-cardname b`(:270)의 `font-size` 가 **rem**(루트 기준)이라 부모의 `.53rem` 축소를 안 따라간다.
   기기 글꼴 1.3배(루트 20.8px)에서 두 줄 = 13.78 + 14.30 = **28.08px** 인데 옛 값은 21px 이라 7.1px 겹쳤다.
   1.0배(루트 16px)에서는 21.6px 라 −0.6px — 그래서 PC 눈검사에서 안 잡혔다(2026-09-03 실기기 채점). */
/*  −32px 이면 여유(이름표 top − 카드 bottom)가 **3.9px** 로 계약 4px 에 0.1px 모자란다
    (2026-09-04 실기기 SM-F966N 실측 · 폰 글꼴 1.3배 · ④ 심층제안 [3.9,3.9,3.9]).
    두 줄 높이 28.08px + 여유 4px = 32.08px → **−33px**. */
body.tj-chatmode .tj-cardname{ bottom:-33px; font-size:.53rem; }
/*  ★ 2026-09-05 — 이 줄이 위 `.tj-card.is-focus`(112%)를 **이기고 있었다**(선택자가 더 세다).
    실측: 컴퓨트된 transform 이 scale(1.06)·translateY(-4) 로 나왔다 — 지시 ⑥ 의 110~115% 에 못 미친다.
    대화형은 카드가 56x90 으로 작아지므로(:444) 오히려 더 키워야 [지금 이 카드 얘기 중]이 읽힌다.
    112% → 62.7px 로, 카드 사이 간격(gap 8px)을 넘지 않아 옆 장과 겹치지 않는다. */
body.tj-chatmode .tj-card.is-focus{ transform:translateY(-7px) scale(1.12); }
body.tj-chatmode .tj-card.is-key{ transform:translateY(-10px) scale(1.16); }

/* ── 루나의 리딩 노트 (CHAPTER 3 §10) ────────────────────────────────────
   새 시각 언어를 만들지 않는다 — #tj-card-detail(:557) 과 같은 크림/골드 시트 톤을 그대로 쓴다.
   배경 dim 은 새로 만들지 않고 카드 확대용 `.tj-zoomdim`(:319)을 그대로 빌려 쓴다. */
body.tj-note-on .tj-zoomdim{ background:rgba(10,6,16,.34); }
#tj-note{
  display:none; position:fixed; left:14px; right:14px; top:12%; z-index:23;   /* 확대 카드(22)보다 위 — 노트를 보는 동안은 그것이 최우선 */
  max-width:520px; margin:0 auto; max-height:76dvh; overflow-y:auto;
  flex-direction:column; gap:8px;
  border:1px solid rgba(201,169,97,.34); border-radius:16px;
  background:linear-gradient(180deg,#fffdf9,#fbf0e2);
  box-shadow:0 10px 32px rgba(60,40,20,.34);
  padding:12px 14px 14px;
}
body.tj-note-on #tj-note:not([hidden]){ display:flex; }
.tj-note-head{
  display:flex; align-items:center; justify-content:space-between;
  font-weight:700; font-size:.9rem; color:#4a3b2e;
}
.tj-note-close{
  border:1px solid rgba(201,169,97,.4); border-radius:999px; background:#fff;
  color:#8a6a2e; font-size:.72rem; padding:4px 11px; font-family:inherit; cursor:pointer;
}
.tj-note-body{ display:flex; flex-direction:column; gap:8px; }
.tj-note-date{ font-size:.74rem; color:#8a6a2e; }
.tj-note-cards{ display:flex; gap:10px; flex-wrap:wrap; }
.tj-note-card{ display:flex; flex-direction:column; align-items:center; width:64px; gap:2px; }
.tj-note-card img{ width:52px; height:84px; object-fit:cover; border-radius:6px; box-shadow:0 3px 10px rgba(0,0,0,.22); }
.tj-note-card-name{ font-size:.66rem; color:#4a3b2e; text-align:center; line-height:1.2; }
.tj-note-card-pos{ font-size:.6rem; color:#a08650; }
.tj-note-label{ font-size:.72rem; font-weight:700; color:var(--pg-gold,#c9a961); }
.tj-note-text{ font-size:.86rem; line-height:1.5; color:#4a3b2e; }
.tj-note-text.is-key{ font-weight:600; }
.tj-note-status{ font-size:.72rem; color:#a08650; text-align:right; }

.tj-chat{
  position:relative;
  display:flex; flex-direction:column; gap:6px;
  flex:1 1 auto; min-height:96px; max-height:32dvh;
  /* CHAPTER 1 §A — Focus Mode 로 드나들 때 대화창 키가 툭 끊기지 않게. reduced-motion 은 즉시 전환. */
  transition:max-height .4s ease;
  overflow-y:auto; overscroll-behavior:contain;
  /* 2026-09-10 2차 POLISH §5 — 오른쪽 2px 는 사용자 말풍선이 화면 끝에 거의 붙어 보였다
     (사람 지적 §5 [안전 여백 통일]). 좌우를 8px 로 맞춰 루나·사용자 말풍선 모두 같은 여백을 쓴다. */
  padding:2px 8px 4px;
  scrollbar-width:none;
}
.tj-chat::-webkit-scrollbar{ width:0; height:0; }
.tj-chat[hidden]{ display:none; }

/* 한 줄 = 프로필 + 말풍선. 같은 사람이 이어 말하면 프로필을 반복하지 않는다(지시 §8) */
.tj-msg{ display:flex; align-items:flex-end; gap:6px; animation:tj-msg-in .26s cubic-bezier(.2,.8,.3,1) both; }
@keyframes tj-msg-in{ from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:none; } }
/* .tj-newmsg 는 left:50% + translateX(-50%) 로 가운데 선다 — 위 키프레임의 `transform:none`
   이 fill-mode:both 로 남아 그 정렬을 덮는다(entry-scene.css 와 같은 함정). 제 것을 쓴다. */
@keyframes tj-msg-in-cx{ from{ opacity:0; transform:translateX(-50%) translateY(6px); } to{ opacity:1; transform:translateX(-50%); } }
.tj-msg.is-me{ justify-content:flex-end; }
.tj-ava{
  width:26px; height:26px; border-radius:50%; flex:0 0 26px;
  object-fit:cover; object-position:50% 22%;
  border:1px solid rgba(201,169,97,.42); background:#2a1c3c;
}
.tj-ava.is-blank{ visibility:hidden; }        /* 이어지는 말풍선 — 자리만 남기고 얼굴은 안 그린다 */
.tj-msg-col{ display:flex; flex-direction:column; gap:3px; min-width:0; max-width:78%; }
.tj-msg-name{
  font-size:.6rem; letter-spacing:.1em; font-weight:700;
  color:var(--pg-gold, #c9a961); padding-left:2px;
}

.tj-bubble{
  padding:8px 11px 9px; border-radius:14px 14px 14px 4px;
  border:1px solid rgba(201,169,97,.24);
  background:linear-gradient(180deg, rgba(58,40,74,.86), rgba(40,26,58,.92));
  color:var(--pg-ink, #f6efe3);
  font-size:.9rem; line-height:1.5; word-break:keep-all;
  box-shadow:0 3px 12px rgba(12,7,20,.32);
}
.tj-msg.is-me .tj-bubble{
  border-radius:14px 14px 4px 14px;
  border-color:rgba(201,169,97,.5);
  background:linear-gradient(180deg, rgba(201,169,97,.30), rgba(150,120,60,.34));
}
/* 강조 말풍선(지시 §19) — 카드형 리포트가 아니라 [대화 안의 한 마디]로 보여야 한다 */
.tj-bubble.is-key{
  border-color:rgba(201,169,97,.72);
  background:linear-gradient(180deg, rgba(78,56,32,.80), rgba(56,38,24,.88));
  box-shadow:0 0 0 1px rgba(201,169,97,.28), 0 5px 18px rgba(12,7,20,.42);
  font-weight:600;
}

/* "루나가 카드를 보고 있어요…" (지시 §6) — 가볍게, 매 메시지마다 쓰지 않는다 */
.tj-typing{ display:flex; align-items:center; gap:7px; }
.tj-typing .tj-bubble{ display:flex; align-items:center; gap:7px; padding:9px 12px; }
.tj-typing-label{ font-size:.72rem; color:var(--pg-sub, #c9bcd6); }
.tj-dots{ display:inline-flex; gap:3px; }
.tj-dots i{
  width:4px; height:4px; border-radius:50%; background:var(--pg-gold, #c9a961);
  animation:tj-dot 1.05s infinite ease-in-out;
}
.tj-dots i:nth-child(2){ animation-delay:.16s; }
.tj-dots i:nth-child(3){ animation-delay:.32s; }
@keyframes tj-dot{ 0%,60%,100%{ opacity:.28; transform:translateY(0); } 30%{ opacity:1; transform:translateY(-2.5px); } }

/* 위로 올려 읽는 중이면 끌어내리지 않는다 — 대신 이 버튼을 띄운다(지시 §17) */
.tj-newmsg{
  position:absolute; left:50%; transform:translateX(-50%);
  bottom:6px; z-index:5;
  padding:5px 12px; border-radius:999px;
  border:1px solid rgba(201,169,97,.5);
  background:rgba(34,22,50,.94); color:var(--pg-gold, #c9a961);
  font-size:.72rem; font-weight:600; cursor:pointer;
  box-shadow:0 4px 14px rgba(10,6,18,.5);
  animation:tj-msg-in-cx .2s ease both;
}
.tj-newmsg[hidden]{ display:none; }

@media (prefers-reduced-motion: reduce){
  .tj-msg,.tj-newmsg{ animation:none !important; }
  .tj-dots i{ animation:none !important; opacity:.7 !important; }
}

/* ════════════════════════════════════════════════════════════════════════
   2026-09-04 사람 지시 [루나 타로상담 메인 입장 화면 최종 수정]
   ────────────────────────────────────────────────────────────────────────
   방향 — [고급 타로숍]이 아니라 **[루나와 메신저로 대화하는 화면]**.
   10~30대가 부담 없이 열 수 있게: 두꺼운 테두리·무거운 장식·금색 면을 걷고,
   딥퍼플 / 라벤더 / 연핑크 / 블루퍼플 넷으로만 간다. 금색은 **재화 아이콘에만** 남는다.

   ★ 여기 있는 규칙은 전부 `body.tj-on` 으로 시작한다 — 그 클래스는 `shop-tarojip.js` 가
     타로집일 때만 붙인다. `reading.html` 을 함께 쓰는 **도사집(body.dj-on)에는 한 줄도 안 닿는다**.
     같은 이유로 `premium-hud.css`(놀이터·사주집이 함께 쓴다)를 고치지 않고 여기서 덮는다.
   ★ 원화(무대 사진·루나)는 한 픽셀도 안 건드렸다 — 이 파일은 UI 층만 그린다.
   ════════════════════════════════════════════════════════════════════════ */

/* ── §2 색 (이 화면에서만) ─────────────────────────────────────────────── */
body.tj-on{
  --tj-lav:#b9a6ee;               /* 라벤더 — 테두리·아이콘 */
  --tj-pink:#f0a8c8;              /* 연핑크 */
  --tj-blue:#8fa6f0;              /* 블루퍼플 */
  --tj-deep:rgba(38,26,60,.72);   /* 반투명 딥퍼플 — UI 바탕 */
  --tj-deep-2:rgba(48,33,74,.80);
  --tj-edge:rgba(185,166,238,.34);/* 얇은 라벤더 테두리(1px) */
}

/* ── §3 상단 ──────────────────────────────────────────────────────────── */
/* 뒤로가기 — 조금 작고 가볍게(36 → 32px). 누를 자리는 44px 을 지킨다(::after 로 넓힌다). */
body.tj-on.premium-hud .backhome,
body.tj-on.premium-hud .backhome.jelly{
  min-height:32px; height:32px; padding:0 12px;
  border:1px solid var(--tj-edge);
  background:var(--tj-deep);
  font-size:.74rem; font-weight:600;
  box-shadow:0 3px 12px rgba(18,11,32,.22);   /* [무거운 장식 금지] — 그림자를 얕게 */
}
body.tj-on.premium-hud .backhome::after{ inset:-7px -8px; }   /* 32 + 14 = 46px 터치 */

/* 제목 아래 상태 문구 — [지금 이야기할 수 있어 ✦].
   부제(직함)보다 한 톤 밝고, 앞에 아주 작은 라벤더 점이 하나 붙는다(온라인 표시의 결). */
body.tj-on.premium-hud .char-name span{
  display:inline-flex; align-items:center; gap:5px;
  color:#d9cbf2; font-size:.68rem; font-weight:500; letter-spacing:0;
  transition:opacity .2s ease;                /* CHAPTER 01 §1 — 상태 문구 전환은 글자만 fade, 레이아웃 불변 */
}
body.tj-on.premium-hud .char-name span::before{
  content:""; width:5px; height:5px; border-radius:50%;
  background:var(--tj-lav); box-shadow:0 0 6px rgba(185,166,238,.8);
}
body.tj-on.premium-hud .char-name span.tj-stage-fade{ opacity:0; }
@media (prefers-reduced-motion: reduce){
  body.tj-on.premium-hud .char-name span{ transition:none; }
}

/* ⓘ — 뒤로가기와 같은 규격으로 내린다(§3 [상단 요소끼리 높이와 여백을 정렬]). */
body.tj-on.premium-hud .hud-info{
  width:32px; height:32px; min-height:32px;
  border-color:var(--tj-edge); background:var(--tj-deep);
  font-size:.86rem; box-shadow:0 3px 12px rgba(18,11,32,.22);
}

/* 재화(은화 · 🔥) — 10% 축소(34 → 31px · .7 → .63rem). 금색은 여기 아이콘에만 남는다. */
body.tj-on.premium-hud .tarot-coin-widget{
  height:31px; min-height:31px; padding:0 9px; gap:5px; font-size:.63rem;
  border-color:var(--tj-edge); background:var(--tj-deep);
}

/* 영어 장소명(음악 칩) — §3 [완전히 삭제].
   ★ 음악 기능은 안 없앴다: 좌하단 `.tarot-audio-widget`(소리 조절)이 그대로 있고,
     곡 선택 패널(.bgm-panel)도 그대로다. 화면에서 **영어 곡 이름만** 내린다. */
body.tj-on.premium-hud .bgm-chip,
body.tj-on.premium-hud.bgm-chip-on .bgm-chip{ display:none !important; }

/* 칩이 빠진 만큼 본문을 끌어올린다 — 상단 때문에 화면이 비어 보이지 않게. */
body.tj-on.premium-hud{ padding-top:calc(var(--pg-row1) + 32px + 16px + 8px); }

/*  소리 위젯을 **음악 칩이 비운 자리**로 올린다 (2026-09-04 실측으로 고침).
    `.tarot-audio-widget`(audio.js:1076)은 전 화면 공통으로 좌하단(배너 위 14px · left 12px)에 있다.
    §6 으로 입력줄이 그 자리에 서면서 **시계 아이콘을 통째로 덮었다**
    (412x915 실측: 위젯 x12~55·y865~901 · 시계 x14~52·y843~881 — 겹침 36x16px).
    도사집은 같은 문제를 `#composer{padding-left:64px}` 로 피했지만(shop-oracle-ui.css:229),
    여기는 그 왼쪽 칸에 시계·마이크가 서야 해서 그 처방을 못 쓴다.
    대신 위쪽 둘째 줄 **왼쪽 — 영어 곡 이름 칩이 있던 그 자리**로 올린다. 은화 위젯과 같은 줄이 된다.
    ★ 위젯을 지우거나 새로 만들지 않았다. 자리와 옷만 이 화면 규격으로 갈아입힌다. */
body.tj-on .tarot-audio-widget{
  top:calc(var(--pg-row1) + 36px + 16px + 8px); bottom:auto; left:12px;
  height:31px; min-height:31px; padding:0 11px; border-radius:999px;
  border:1px solid var(--tj-edge); background:var(--tj-deep);
  color:var(--pg-ink,#f6efe3); font-size:.8rem;
  box-shadow:none;
}

/* ── §4 인사 영역 ─────────────────────────────────────────────────────── */
/* 하단 그라데이션 — 캐릭터 아래에서 화면 끝으로만. 얼굴·상반신을 덮지 않는다.
   위끝(0%)은 완전 투명이고 48% 지점부터 진해진다 — 패널 위끝은 화면의 약 62% 자리다. */
/*  패널 바탕도 시안 값으로 옮겼다 — 버튼 사이 틈 #362546 · 버튼줄 아래 #312340 실측.
    앞판(#180e28 계열)보다 한 단계 밝고 보라 쪽이다. 위끝은 여전히 완전 투명이라
    루나의 얼굴·상반신에는 닿지 않는다. */
/* 2026-09-10 [루나 상담 대화방 UI 리뉴얼 §4] — 짙은 보라 스크림 → 크림 스크림.
   말풍선·칩이 이제 밝은 색이라 짙은 보라 바탕 위에서는 뜨지 않고 배경과도 어긋난다. */
/* 2026-09-10 2차 POLISH §3 — 그 크림 스크림이 다시 문제가 됐다: 말풍선·칩·입력창이
   전부 자기 배경(불투명 그라데이션)을 이미 가지고 있어 가독성은 그것만으로 충분한데,
   패널 스크림까지 겹쳐 배경 원화·루나 색감이 washed-out 되어 보였다(사람 지적 §3).
   그래서 스크림을 [고지 한 줄만 살짝 딛는] 정도로 확 낮췄다 — 나머지 대비는
   각 말풍선의 background/border/shadow(§9·§10)가 낸다. */
body.tj-on .tj-panel{
  background:linear-gradient(180deg,
    rgba(255,248,238,0) 0%, rgba(255,248,238,0) 60%, rgba(255,248,238,.16) 84%, rgba(250,236,218,.28) 100%);
  gap:8px;
}
/*  이름표 — 2026-09-10 [루나 상담 대화방 UI 리뉴얼 §9] 밝은 크림 알약 + 샴페인 골드.
    짙은 보라 알약은 새 블루아워 배경 위에서 너무 무거워 보여 크림/골드로 바꿨다. */
body.tj-on .tj-msg-name{
  align-self:flex-start;
  padding:2px 9px 3px; border-radius:999px;
  border:1px solid rgba(201,169,97,.45);
  background:rgba(255,251,244,.92);
  color:#8a6a2e; font-size:.62rem; font-weight:700; letter-spacing:.02em;
}
body.tj-on .tj-msg-name::after{ content:" ✦"; opacity:.8; }
/*  말풍선 — §9 루나: 밝은 크림/아이보리(새 [루나 말풍선 MASTER] 실측 중앙값 #fef6f0) + 진한 글자.
    §10 손님: 연라일락(새 [사용자 말풍선 MASTER] 실측 중앙값 #e0defc) + 진한 남보라 글자.
    두 값 모두 새로 만든 색이 아니라 사람이 준 말풍선 원화에서 실측했다. */
body.tj-on .tj-bubble{
  border:1px solid rgba(255,255,255,.7); border-radius:18px 18px 18px 6px;
  background:linear-gradient(180deg,#fef8f2,#f7ebdd);
  color:#3a2e28;
  box-shadow:0 3px 12px rgba(120,90,60,.18);
  padding:8px 13px 9px; font-size:.9rem; line-height:1.45;
}
/*  손님 말풍선 — 연라일락. 두 사람이 한눈에 갈린다(§10 [루나 말풍선과 같은 디자인 시스템]). */
body.tj-on .tj-msg.is-me .tj-bubble{
  border-radius:18px 18px 6px 18px;
  border-color:rgba(255,255,255,.6);
  background:linear-gradient(180deg,#ece9fd,#dcd7f7);
  color:#332b55;
}
body.tj-on .tj-ava{ border-color:rgba(255,255,255,.6); }
/* 말풍선 옆 작은 별빛 **하나**. 화면 곳곳에 반짝이를 뿌리지 않는다(§4). */
body.tj-on .tj-chat{ position:relative; }
body.tj-on .tj-chat::after{
  content:"✦"; position:absolute; right:6px; top:2px;
  font-size:.6rem; color:var(--pg-gold, #c9a961); opacity:.5; pointer-events:none;
}

/*  입장 화면에서만 패널 예산을 좁힌다 (2026-09-04 실측으로 고침).
    여섯 칸(3줄 × 46px) + 입력줄 + 고지 줄이 함께 서는 구간이라, 지시 §2 의 [하단 35~45%] 를
    374x826(폴드 커버)에서 **46.3%** 로 넘겼다. 캐릭터를 자르거나 버튼을 줄이지 않고
    [여백을 줄이는 것]으로 맞춘다(§8 우선순위 그대로):
      패널 위 여백 26 → 16px · 대화창 최소 높이 96 → 84px  → 실측 383 → 361px(43.7%).
    주제 격자가 사라지는 순간(카드로 가는 흐름) 이 클래스도 같이 빠져 예전 값으로 돌아간다. */
body.tj-on.tj-topics .tj-panel{ padding-top:16px; }
body.tj-on.tj-topics .tj-chat{ min-height:84px; max-height:24dvh; }
/*  ★ 입장 화면에는 **카드가 없다** — 그런데 :366 이 낮은 화면(≤680px)에서 카드 자리로
    `.tj-table{min-height:112px}` 를 미리 비워 둔다. 그 112px 이 여섯 칸 + 입력줄을 밀어
    360x640 에서 **입력줄이 화면 밖으로 77px 나갔다**(2026-09-04 실측).
    카드로 가는 흐름은 그 자리가 여전히 필요하므로 :366 을 고치지 않고,
    **주제 격자가 서 있는 동안만** 그 예약을 푼다. */
body.tj-on.tj-topics .tj-table{ min-height:0; }

/* ── §5 상담 주제 — 반드시 2열 × 3행 ──────────────────────────────────── */
/* flex-wrap 은 글자 수만큼 폭이 달라진다. 격자로 놓아야 여섯 칸이 **완전히 같아진다**. */
.tj-acts.is-grid{
  display:grid; grid-template-columns:1fr 1fr;
  gap:8px; justify-content:stretch;
}
/*  ── 여섯 칸의 색 (2026-09-04 2차 · 사람이 준 시안 PNG 실측) ─────────────────
    감으로 고른 값이 하나도 없다. 시안(847x1857 · 칸 313x95px)에서 칸마다 네 모서리를
    14x12px 평균으로 재고, [윗변이 밝고 아랫변이 어두운 세로 그라데이션]인 것을 확인해
    ↗(위) → ↙(아래) 두 값을 그대로 옮겼다. 테두리는 윗선 1~3px 을 잰 값이다.

      칸          위        아래      테두리
      연애·썸     #805c98   #61437d   #9e7bb3
      친구·관계   #9279bd   #755da0   #a187cc
      학교·직장   #c47fa0   #a6607a   #d2869d
      돈·금전운   #7d7abd   #6868a9   #8288c1
      마음 고민   #7672b6   #625c9d   #8686c3
      선택 고민   #a96e9c   #915e8b   #b37ba6

    ★ 앞판과 달라진 것 셋 — 시안이 그렇게 되어 있다:
      ① **여섯이 전부 다른 색**이다(앞판은 셋을 둘씩 나눠 썼다)
      ② **불투명**이다(앞판은 알파 .5로 원화가 비쳤고, 그래서 다 비슷한 보라로 뭉갰다)
      ③ **알약(완전 둥근 모서리)**이다(앞판 16px 라운드 사각)
    ★ 글자·아이콘은 흰색이다 — 시안 실측 #ffffff. 여섯 칸의 대비가 4.5:1 을 넘는다
      (가장 밝은 학교·직장 #c47fa0 위 흰 글자 = 3.6:1 이라 그 칸만 아랫값을 써서 3.9:1 → 아래 ★★). */
.tj-acts.is-grid button{
  display:flex; align-items:center; justify-content:center; gap:7px;
  width:100%; min-height:46px; padding:0 10px;   /* §5 [충분히 누를 수 있는 터치 영역] */
  border-radius:999px;                            /* 시안 = 알약 (높이 95px 에 반지름 47) */
  font-size:.84rem; font-weight:600; letter-spacing:-.01em;
  white-space:nowrap;                             /* §8 [두 줄로 어색하게 내려가지 않게] */
  box-shadow:0 2px 8px rgba(12,7,20,.26);
}
.tj-acts.is-grid .tj-ic{ flex:0 0 auto; opacity:.95; }  /* §5 아이콘 20% 축소 = 20 → 16px */
.tj-acts.is-grid .tj-act-label{ min-width:0; }
body.tj-on .tj-acts.is-grid button{
  color:#fff; border:1px solid rgba(255,255,255,.22);
  text-shadow:0 1px 3px rgba(30,14,46,.45);       /* 밝은 칸에서도 흰 글자가 뜬다 */
}
body.tj-on .tj-acts.is-grid button[data-tone="v1"]{
  background:linear-gradient(180deg,#805c98,#61437d); border-color:#9e7bb3;
}
body.tj-on .tj-acts.is-grid button[data-tone="v2"]{
  background:linear-gradient(180deg,#8b73b4,#6f5898); border-color:#a187cc;
}
/*  ★★ 대비 보정 (§5 [명도 대비 확보]) — **색상(hue)은 시안 그대로고 명도만 몇 % 눅였다.**
    흰 글자가 실제로 앉는 자리는 알약의 **세로 30~70% 구간**이라, 그 30% 지점에서
    4.5:1 을 넘게 칸마다 계수를 따로 구했다(계산 근거를 숫자로 남긴다):
      v1     1.00 배  #805c98 → #61437d   30% 대비 6.02  (시안 값 그대로)
      v2     0.95 배  #8b73b4 → #6f5898   30% 대비 4.50
      rose   0.89 배  #a66a86 → #94556d   30% 대비 4.52
      blue   0.96 배  #7875b5 → #6464a2   30% 대비 4.51
      indigo 1.00 배  #7672b6 → #625c9d   30% 대비 4.76  (시안 값 그대로)
      mauve  0.96 배  #a26a96 → #8b5a85   30% 대비 4.50
    둘은 손 안 댔고 넷은 4~11% 차이라 나란히 놓아도 같은 색으로 읽힌다.
    테두리는 시안 실측값 그대로 두었다 — 그 1px 이 [원래 밝기]를 기억한다. */
body.tj-on .tj-acts.is-grid button[data-tone="rose"]{
  background:linear-gradient(180deg,#a66a86,#94556d); border-color:#d2869d;
}
body.tj-on .tj-acts.is-grid button[data-tone="blue"]{
  background:linear-gradient(180deg,#7875b5,#6464a2); border-color:#8288c1;
}
body.tj-on .tj-acts.is-grid button[data-tone="indigo"]{
  background:linear-gradient(180deg,#7672b6,#625c9d); border-color:#8686c3;
}
body.tj-on .tj-acts.is-grid button[data-tone="mauve"]{
  background:linear-gradient(180deg,#a26a96,#8b5a85); border-color:#b37ba6;
}
/* 누름 — 2~3% 작아졌다가 돌아오고, 색만 조금 밝아진다(§9). 진동·불꽃·큰 반짝임 없음. */
body.tj-on .tj-acts.is-grid button:active{ transform:scale(.975); filter:brightness(1.14); }

/* ── [오늘의 카드] 칩 — 2026-09-17 [타로집 HOME 통합] ────────────────────────
   옛 1차 랜딩(#tj-landing · 지금은 걷혔다)의 [🔮 무료 카드 뽑기]가 이 자리로 옮겨왔다.
   인사말풍선 아래·6그리드(위 §5) 위, 한 줄짜리 유리 칩 하나 — 루나 자신·여섯 칸의 진한
   보석색(위 v1/v2/rose/blue/indigo/mauve)보다 또렷하지 않게 채도를 낮춘 --tj-deep/--tj-edge
   톤을 쓴다(사람 지시 [시각적으로 종속적]). 배지 색은 옛 tarot-landing.css 의
   .tj-landing-freebadge 그라데이션을 그대로 옮겼다 — 같은 기능이니 같은 색으로 남긴다. */
body.tj-on .tj-todaycard{
  display:flex; align-items:center; gap:8px;
  width:100%; margin:0 0 8px; padding:9px 14px;
  border-radius:999px; border:1px solid var(--tj-edge);
  background:var(--tj-deep);
  color:#e8ddf5; font-family:inherit; font-size:.8rem; font-weight:600;
  cursor:pointer; box-shadow:0 2px 8px rgba(12,7,20,.22);
  transition:transform .14s ease, filter .18s ease;
}
body.tj-on .tj-todaycard[hidden]{ display:none; }
body.tj-on .tj-todaycard:active{ transform:scale(.98); filter:brightness(1.08); }
body.tj-on .tj-todaycard-ico{ width:22px; height:22px; object-fit:contain; flex:0 0 auto; opacity:.95; }
body.tj-on .tj-todaycard-label{ flex:1 1 auto; text-align:left; }
body.tj-on .tj-todaycard-badge{
  flex:0 0 auto; padding:3px 10px; border-radius:999px;
  background:linear-gradient(120deg, rgba(201,168,239,.28), rgba(255,233,163,.22));
  border:1px solid rgba(255,233,163,.35);
  color:#fff3d6; font-size:.64rem; font-weight:600; letter-spacing:.02em;
}
/* 오늘 이미 무료를 썼으면 배지만 무채색으로 눅인다 — 칩 자체를 숨기지 않는다
   (§8 [삭제가 아니라 이식] — 랜딩판도 같은 상태에서 문구만 갈아 끼웠지 버튼을 지우지 않았다). */
body.tj-on .tj-todaycard.is-done .tj-todaycard-badge{
  background:rgba(255,255,255,.12); border-color:rgba(255,255,255,.2); color:rgba(232,221,245,.72);
}
@media (max-width:360px){
  body.tj-on .tj-todaycard{ padding:8px 12px; font-size:.76rem; }
  body.tj-on .tj-todaycard-badge{ font-size:.6rem; padding:3px 8px; }
}

/* ════════════════════════════════════════════════════════════════════════
   2026-09-10 [루나 상담 대화방 UI 리뉴얼 §11·§12] — 추천 질문 4종(연애·재회·속마음·직장금전)
   전용 아이콘 칩. `카드질문받기()` 가 `액션보이기(목록,{격자:true,빠름:true})` 로 켠다.
   `.is-grid` 의 2열 grid 는 그대로 물려 쓰고, 색·아이콘 크기만 이 절이 새로 정한다 —
   6주제([data-tone])와 같은 자리를 다투지 않는다(그 칩엔 `이미지`가 없어 여기 셀렉터가 안 걸린다).
   ════════════════════════════════════════════════════════════════════════ */
body.tj-on .tj-acts.is-quick.is-grid{ grid-template-columns:1fr 1fr; gap:9px; }
body.tj-on .tj-acts.is-quick button{
  flex-direction:column; gap:5px; min-height:82px; padding:10px 6px 9px;
  border-radius:20px; white-space:normal; line-height:1.2;
  background:linear-gradient(180deg,#fffbf5,#fbeee0);
  border:1.5px solid rgba(201,169,97,.30);
  color:#4a3b2e; text-shadow:none;
  box-shadow:0 3px 10px rgba(120,90,60,.16);
}
body.tj-on .tj-acts.is-quick .tj-quick-ico{ width:34px; height:34px; object-fit:contain; flex:0 0 auto; }
body.tj-on .tj-acts.is-quick .tj-act-label{ font-size:.8rem; font-weight:700; }
/* [직접 질문하기] — §12 추천 질문보다 시각적 우선순위를 낮춘 넓은 보조 캡슐.
   격자 2칸을 그대로 가로질러 셋째 줄에 홀로 선다. */
body.tj-on .tj-acts.is-quick button.is-quiet{
  grid-column:1 / -1; flex-direction:row; justify-content:center;
  min-height:42px; padding:0 14px; border-radius:999px;
  background:rgba(255,255,255,.55); border:1px solid rgba(201,169,97,.22);
  color:#7a6a5a; font-size:.78rem; font-weight:500;
}
body.tj-on .tj-acts.is-quick button:active{ transform:scale(.975); filter:brightness(1.05); }

/* ── §6 입력줄 — [시계 · 마이크 · 입력칸 · 전송] 한 줄 ───────────────── */
body.tj-on #composer{
  display:flex; align-items:center; gap:7px;
  border-top:0; background:none; padding:0; max-width:520px;
  /*  0.2초 늦게 뜬다 — §9 등장 순서에서 입력창이 **마지막**이기 때문이다.
      주제 격자의 마지막 칸이 0.175s(6칸 × 35ms)에 시작하므로 그 뒤에 선다.
      실측(412x915): 루나 0 → 말풍선 0.33/0.85 → 격자 1.42 → 입력창 1.62 → 끝 1.96초. */
  animation:tj-rise .34s cubic-bezier(.22,.9,.3,1) .2s both;
}
/*  입력바 — 2026-09-10 [루나 상담 대화방 UI 리뉴얼 §13] 짙은 회보라 → 밝은 크림 캡슐.
    글자도 흰색에서 진한 잉크색으로(크림 바탕에 흰 글자는 대비가 안 나온다). */
body.tj-on #user-input{
  flex:1 1 auto; min-width:0;
  height:42px; padding:0 14px; border-radius:999px;
  border:1px solid rgba(201,169,97,.30); background:#fffaf3;
  color:#4a3b2e; font-size:.86rem;
}
body.tj-on #user-input::placeholder{ color:rgba(90,74,60,.52); }
/* 시계 · 마이크 — 입력바와 같은 바탕의 조용한 아이콘 버튼. 글자를 쓰지 않는다. */
body.tj-on .tj-io{
  flex:0 0 auto; width:38px; height:38px; padding:0;
  display:inline-flex; align-items:center; justify-content:center;
  border:1px solid rgba(201,169,97,.30); border-radius:50%;
  background:#fffaf3; color:rgba(90,74,60,.82); cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  transition:transform .14s ease, background .18s ease;
}
body.tj-on .tj-io:active{ transform:scale(.94); }
body.tj-on .tj-io.is-on{ color:#a8386a; background:rgba(244,156,181,.28); border-color:rgba(244,156,181,.6); }
body.tj-on .tj-io:focus-visible{ outline:2px solid var(--pg-gold, #c9a961); outline-offset:2px; }
/*  전송 — §14 뮤트 핑크/로즈핑크. 새 [추천질문 아이콘] 하트에서 실측한 색이다(#fc9fb8 계열).
    네온·빛번짐 없음. 흰 화살표만 그대로 남긴다. */
body.tj-on #send-btn{
  flex:0 0 auto; width:38px; height:38px; min-height:38px; padding:0;
  display:inline-flex; align-items:center; justify-content:center;
  border:0; border-radius:50%;
  background:linear-gradient(160deg,#f7b6c8 0%,#f18aa6 55%,#e0678f 100%);
  color:#fff; box-shadow:0 3px 10px rgba(200,90,120,.32);
  font-size:0;                                   /* 글자를 지운다 — 안은 SVG 화살표 하나다 */
}
body.tj-on #send-btn:active{ transform:scale(.94); }
/* §14 [사용 가능/불가능 상태가 시각적으로 구분] — 빈 입력창에서는 흐리게(기존 disabled 속성은
   reading.js 가 관리 — 여기는 그 상태의 모양만 정한다). */
body.tj-on #send-btn:disabled{ background:linear-gradient(160deg,#e7d9dc,#d8c8cc); box-shadow:none; opacity:.6; }

/* ── §7 AI 안내 한 줄 — 입력창 아래, 작고 은은하게 ──────────────────── */
body.tj-on .tj-foot{ min-height:14px; gap:8px; }
body.tj-on .tj-foot .sg-disclaimer{
  width:auto; margin:0; padding:0; background:none;
  font-size:.64rem; line-height:1.3; color:rgba(201,188,214,.62);
}

/*  ── 글을 쓰는 동안 (2026-09-05 사람 지시 [내용 입력시 불편]) ─────────────────
    실기기 실측(411x903) — 키보드가 뜨면 창이 **903 → 543** 으로 줄고, 그 좁은 화면에서
    주제 여섯 칸이 132px 을 그대로 먹어 **대화창에 60px** 밖에 안 남았다.
    루나가 한 말 두 마디 중 첫 줄만, 그것도 아래가 잘린 채 보였다.

    글을 쓰는 사람에게 지금 필요한 것은 [고를 주제]가 아니라 [지금까지 무슨 얘기를 했나] 다.
      · 주제 격자는 접는다 — 커서를 빼면 그대로 돌아온다(없애는 게 아니다)
      · 대화창을 넓힌다 — 60px → 38dvh(543px 화면에서 206px)
      · 고지 한 줄도 접는다 — 키보드 위 한 줄이 아깝다. 내용은 ⓘ 에 그대로 있다.
    ★ `body.tj-typing` 은 입력칸에 커서가 있을 때만 붙는다(shop-tarojip.js 쓰는중표시).
      키보드 높이를 재는 방식(--tj-kb)으로는 이 기기를 못 잡는다 — 창이 통째로 줄어 그 값이 0 이다. */
/*  ── 카드가 없는 동안은 대화를 넓게 (2026-09-05 사람 지시 B안) ────────────────────
    사람 지적: *"대화하는 화면이 너무 답답하게 보임"*.
    실측(411x903 · 주제 고르기) — 루나가 **501px = 55%**, 대화창은 131px 이었다.
    카드가 테이블에 없는 구간에서는 그 자리가 필요 없다. 그래서 그때만 화면을 다시 나눈다:
      · 얼굴 자리 16% → 6% — 루나는 **얼굴 위주로** 남는다(잘리는 게 아니라 당겨진다)
      · 패널 45 → 60% — 늘어난 몫은 전부 대화창이 먹는다(주제 격자·입력줄 높이는 그대로다)
    ★ 카드가 깔리는 순간 `shop-tarojip.js 자리판깔기()` 가 이 클래스를 뗀다 —
      카드 석 장과 자리 이름표가 설 자리를 다시 돌려준다. 되돌리는 코드가 따로 없다.
    ★ 글을 쓰는 동안(tj-typing)은 이 값보다 한 단계 더 간다(아래 절) — 두 클래스가 겹치면 뒤엣것이 이긴다. */
/* 2026-09-10 2차 POLISH §1 [캐릭터 얼굴 보호 영역] — 60dvh 까지 열던 패널이 루나 턱 밑까지
   말풍선을 밀어 올렸다(사람 지적 §1 [채팅 말풍선이 얼굴·턱 바로 아래까지 침범]). 대화가
   쌓여도 패널 자체는 더 안 커지고 `.tj-chat` 내부 스크롤로만 흡수하도록 상한을 다시 낮췄다.
   face-y 도 6%→11% 로 완화 — 패널이 작아진 만큼 얼굴을 억지로 더 당길 필요가 없다. */
/* 2026-09-10 2차 POLISH §1 재수정 — 실기기 광고 배너(~80px)가 패널을 위로 밀어 올려
   같은 42dvh 라도 실기기에서는 눈까지 침범했다(헤드리스 대조로 확인). 배너 높이를
   height/max-height 양쪽에서 빼서 패널 윗변 위치를 배너 유무와 무관하게 고정한다.
   2026-09-11 MASTER §3·§9 — [대화가 주인공] 으로 우선순위가 바뀌어 42dvh → 56dvh. */
body.tj-on.tj-wide .tj-stage{ --tj-face-y:11%; }
body.tj-on.tj-wide .tj-panel{
  height:calc(62dvh - var(--banner-ad-height, 0px));
  max-height:calc(62dvh - var(--banner-ad-height, 0px));
}
body.tj-on.tj-wide .tj-chat{
  min-height:120px; max-height:none; flex:1 1 auto;
  -webkit-mask-image:linear-gradient(180deg, transparent 0, #000 16px);
          mask-image:linear-gradient(180deg, transparent 0, #000 16px);
}

body.tj-on.tj-typing .tj-acts.is-grid{ display:none; }
body.tj-on.tj-typing .tj-foot{ display:none; }
/* 2026-09-11 [카드 결과 + KEYBOARD MODE UI 최종 개선] §9 — Quick Reply 와 키보드를
   같은 세로 공간에 동시에 넣지 않는다. 키보드를 닫으면(포커스를 떼면) 다시 뜬다
   (기능 삭제 아님 — `반응줄맞추기()` 가 그대로 켜고 끈다). */
body.tj-on.tj-typing .tj-reacts{ display:none !important; }
/* §5 [큰 타로 카드 숨김 · 카드 공개 애니메이션 중단/완료 처리] — 셔플·펼침 도중에 입력창을
   눌러도(드문 경로) 키보드가 뜨는 동안은 카드 자리를 아예 안 그린다. 데이터는 안 지운다 —
   `.tj-table` 은 DOM 에 그대로 있고 화면에만 안 보인다. 키보드를 닫으면 그대로 돌아온다. */
body.tj-on.tj-typing .tj-table{ display:none !important; }

/*  ★ 2026-09-05 2차 — 격자만 접어서는 부족했다(사람: "대화하는 화면이 너무 답답").
    실측(키보드 위 411x543): 격자를 접어도 **루나가 339px = 화면의 62%** 를 그대로 먹어
    대화창은 131px, 말풍선 두 마디가 끝이었다.

    그래서 글을 쓰는 동안에는 **화면을 다시 나눈다** — 도사집이 이미 쓰는 처방이다
    (`shop-oracle-ui.css` 의 --dj-stage-h / --dj-face-y · 상단 38% 상담사 · 하단 62% 대화).
      · 무대의 얼굴 자리를 16% → 4% 로 올린다 — 루나는 **얼굴 위주로** 남는다(잘리는 게 아니라 당겨진다)
      · 패널을 64dvh 까지 연다 — 대화창이 131 → 약 270px 로 두 배가 된다
      · 대화창 위끝을 페이드로 흐린다 — [위에 더 있다]가 눈에 보인다(스크롤바를 안 쓰는 화면이라 이것이 유일한 단서였다)
    커서를 빼면 값이 전부 원래대로 돌아간다. 카드가 놓인 자리(.tj-slots)는 건드리지 않는다. */
/* 2026-09-10 2차 POLISH §1 — 64dvh → 46dvh 로 한 번 낮췄는데도 헤드리스 412x915 실측에서
   말풍선 위끝이 턱에 닿았다(§1 재현 확인 — 스크린샷 확대로 직접 봄). 42dvh · face-y 14% 로
   한 단계 더 낮춘다 — tj-wide 와 같은 예산이다.
   2026-09-11 MASTER §8·§9 — 키보드가 열린 동안은 [대화+입력창을 상단 캐릭터보다 우선 확보]
   가 명시적 지시다. 42dvh → 58dvh. */
body.tj-on.tj-typing .tj-stage{ --tj-face-y:14%; }
body.tj-on.tj-typing .tj-panel{
  height:calc(64dvh - var(--banner-ad-height, 0px));
  max-height:calc(64dvh - var(--banner-ad-height, 0px));
}
body.tj-on.tj-typing .tj-chat{
  min-height:120px; max-height:none; flex:1 1 auto;
  -webkit-mask-image:linear-gradient(180deg, transparent 0, #000 16px);
          mask-image:linear-gradient(180deg, transparent 0, #000 16px);
}
/*  말풍선 사이를 아주 조금 조인다 — 같은 높이에 한 마디가 더 들어온다. 글자 크기는 그대로다. */
body.tj-on.tj-typing .tj-chat{ gap:5px; }
body.tj-on.tj-typing .tj-bubble{ padding:7px 12px 8px; }
/* 2026-10-10 B 1.1.2 [상담 겹침 정리 (b) — 치비 그림 유지] 키보드가 창을 통째로 줄인 낮은 화면(실측 360x440)에서는
   64dvh 패널이 루나 눈·입을 덮었다(말풍선 위끝 158px · 눈 ≈ 190px). 그림 파일·무대 구조는 그대로 두고 두 값만 바꾼다:
   패널 64 → 52dvh(말풍선 한 마디 반은 그대로 보인다) · 얼굴 자리 14% → 50%(그림을 위로 당겨 눈·입이 패널 윗변 위에 남는다).
   커서를 빼면(tj-typing 해제) 위 절 값으로 돌아간다. 화면이 높으면(>600px) 이 절은 켜지지 않는다. */
@media (max-height:600px){
  body.tj-on.tj-typing .tj-stage{ --tj-face-y:50%; }
  body.tj-on.tj-typing .tj-panel{
    height:calc(52dvh - var(--banner-ad-height, 0px));
    max-height:calc(52dvh - var(--banner-ad-height, 0px));
  }
}

/* ── §8 반응형 ────────────────────────────────────────────────────────── */
/* 화면이 낮으면 **캐릭터를 자르지 않고 UI 간격부터 줄인다**(§8 우선순위 그대로). */
@media (max-height:720px){
  body.tj-on .tj-panel{ gap:6px; }
  .tj-acts.is-grid{ gap:6px; }
  .tj-acts.is-grid button{ min-height:42px; font-size:.8rem; }
  body.tj-on .tj-chat{ max-height:22dvh; }
  /*  입장 화면의 대화창 최소 높이도 같이 줄인다 — 위 tj-topics 규칙(84px)이
      선택자 순위에서 이기므로 여기서 **같은 순위로** 다시 적어 준다. */
  body.tj-on.tj-topics .tj-chat{ min-height:76px; }
}
@media (max-height:620px){
  .tj-acts.is-grid button{ min-height:40px; font-size:.78rem; }
  body.tj-on .tj-chat{ min-height:64px; max-height:17dvh; }
  /*  320x568 실측 — 대화창을 84 로 둔 채로는 고지 줄이 화면 밖으로 11px 나갔다.
      캐릭터를 자르거나 버튼을 줄이지 않고 [지난 말이 보이는 칸]을 먼저 줄인다(§8 우선순위). */
  body.tj-on.tj-topics .tj-chat{ min-height:60px; }
  body.tj-on #user-input{ height:36px; }
  body.tj-on #send-btn,body.tj-on .tj-io{ width:36px; height:36px; min-height:36px; }
}
/* 아주 좁은 폰(320~350px)에서도 두 칸을 지킨다 — 글자만 한 단계 줄인다. */
@media (max-width:350px){
  .tj-acts.is-grid button{ font-size:.76rem; gap:5px; padding:0 6px; }
}
/* 키보드가 올라오면 — 입력줄은 키보드 위로 따라 오르고(shop-tarojip.js 가 --tj-kb 를 잰다),
   주제 격자는 그동안 **스크롤되는 칸**이 된다(§8). 캐릭터를 자르지 않는다. */
body.tj-on.tj-kb .tj-panel{ bottom:calc(var(--tj-kb, 0px) + var(--banner-ad-height, 0px)); }
body.tj-on.tj-kb .tj-chat{ max-height:14dvh; }
body.tj-on.tj-kb .tj-acts.is-grid{
  /*  키보드가 올라온 동안에는 **두 줄만** 보이고 나머지는 스크롤이다(46 + 8 + 46 = 100px).
      26dvh 로 뒀더니 세 줄이 다 서서 패널이 [키보드 위 남은 높이]의 63% 를 먹었고
      루나 얼굴을 파고들었다(412x915 · 키보드 320px 흉내 실측: 패널 top 222px).
      두 줄로 줄이면 top 이 278px 로 내려가 얼굴이 다시 산다. 버튼이 사라지는 것이 아니라
      **굴려서 다 닿는다** — §8 [키보드 표시 중에는 주제 버튼 영역을 스크롤] 그대로다. */
  max-height:100px; overflow-y:auto; overscroll-behavior:contain;
  padding-right:2px; scrollbar-width:none;
}
body.tj-on.tj-kb .tj-acts.is-grid::-webkit-scrollbar{ width:0; }

@media (prefers-reduced-motion: reduce){
  body.tj-on #composer{ animation:none; }
  body.tj-on .tj-acts.is-grid button:active{ transform:none; }
}

/* ════════════════════════════════════════════════════════════════════════
   2026-09-05 사람 지시 [주 타겟층 10·20대 — 대화창을 좀 더 아기자기하게] ①②④
   ────────────────────────────────────────────────────────────────────────
   ① 말풍선 꼬리 + 통통 튀는 등장
   ② 생각하는 동안 루나 얼굴 + 점이 더 튄다
   ④ 이모지·ㅋㅋ 만 있는 말은 말풍선을 벗고 크게

   ★ 새 색을 만들지 않았다 — 꼬리 색은 말풍선 그라데이션의 **아래끝 값 그대로**다
     (루나 #d9cfe2 · 손님 #74599c · shop-tarojip.css 의 §4 인사 영역 절에서 왔다).
     값이 두 곳에 있으면 한쪽이 낡으므로, 말풍선 색을 고치면 여기 두 줄도 같이 고친다.
   ★ 꼬리는 **테두리 삼각형**으로 만든다(clip-path·회전 사각형이 아니다) —
     회전 사각형은 말풍선 테두리(1px)와 만나는 자리에 이음매가 보이고,
     clip-path 는 실기기 WebView 에서 마스크와 같은 사고를 낸 적이 있다(entry-scene.css 주석).
   ════════════════════════════════════════════════════════════════════════ */

/* ── ① 꼬리 ─────────────────────────────────────────────────────────────
   말풍선 아래쪽 바깥으로 6px 짜리 삼각형 하나. 이름표·아바타 쪽을 가리킨다. */
body.tj-on .tj-bubble{ position:relative; }
body.tj-on .tj-msg:not(.is-me) .tj-bubble::after{
  content:""; position:absolute; left:-6px; bottom:9px;
  width:0; height:0;
  border:6px solid transparent; border-left:0;
  border-right-color:#f7ebdd;                 /* 루나 말풍선 아래끝 색(§9 크림) */
  pointer-events:none;
}
body.tj-on .tj-msg.is-me .tj-bubble::after{
  content:""; position:absolute; right:-6px; left:auto; bottom:9px;
  width:0; height:0;
  border:6px solid transparent; border-right:0;
  border-left-color:#dcd7f7;                  /* 손님 말풍선 아래끝 색(§10 연라일락) */
  pointer-events:none;
}
/*  강조 말풍선(결론)은 색이 달라 꼬리도 그 색으로. */
body.tj-on .tj-msg:not(.is-me) .tj-bubble.is-key::after{ border-right-color:#f3ecf9; }

/* ════════════════════════════════════════════════════════════════════════
   CHAPTER 01 §3 — KEY INSIGHT (루나가 본 핵심)
   ────────────────────────────────────────────────────────────────────────
   기존 `.is-key`/`.is-verdict`(강조·결론 말풍선) 컴포넌트를 그대로 재사용한다 — 새
   DOM·클래스를 만들지 않았다. 여기서 바꾸는 것은 **색과 라벨뿐**이다.
   ★ 위 582행의 어두운(구판 남보라) `.tj-bubble.is-key` 값은 블루아워 리뉴얼 때 지나쳐
     남아 있던 것이다 — 지금까지 `body.tj-on` 화면에서는 이 자리만 옛 색으로 떴다.
   ★ 크림/아이보리 + 아주 연한 라일락 + 얇은 샴페인 골드 테두리. 팝업처럼 안 보이게
     그림자·테두리 굵기는 일반 말풍선과 같은 값을 쓴다 — 진하게 새로 만들지 않는다. */
body.tj-on .tj-bubble.is-key,
body.tj-on .tj-bubble.is-verdict{
  background:linear-gradient(160deg,#fffaf0 0%,#f7f0fb 58%,#f2ecf9 100%);
  border-color:rgba(214,181,110,.55);
  box-shadow:0 3px 12px rgba(120,90,60,.16);
  color:#3a3350;
  font-weight:500;
}

/* ── ① 통통 튀는 등장 ───────────────────────────────────────────────────
   앞판은 [아래에서 6px 올라오며 페이드]였다. 살짝 작았다가 한 번 넘겨 커지는 스프링으로 바꾼다.
   ★ 0.34초를 넘기지 않는다 — 말이 여러 마디 이어질 때 튀는 시간이 길면 산만해진다. */
body.tj-on .tj-msg{ animation:tj-msg-pop .34s cubic-bezier(.2,.9,.3,1.25) both; }
@keyframes tj-msg-pop{
  0%  { opacity:0; transform:translateY(8px) scale(.94); }
  62% { opacity:1; transform:translateY(0)   scale(1.03); }
  100%{ opacity:1; transform:none; }
}

/* ── ② 생각하는 동안 ────────────────────────────────────────────────────
   얼굴은 `shop-tarojip.js 타이핑()` 이 이제 그대로 보인다(is-blank 를 뗐다).
   점은 조금 더 튀고, 셋이 파도처럼 이어진다. */
body.tj-on .tj-typing .tj-ava{ visibility:visible; }
body.tj-on .tj-typing .tj-bubble{ border-radius:16px 16px 16px 6px; }
body.tj-on .tj-dots i{ width:5px; height:5px; animation:tj-dot-bounce .95s ease-in-out infinite; }
@keyframes tj-dot-bounce{
  0%,60%,100%{ opacity:.3; transform:translateY(0) scale(1); }
  30%        { opacity:1;  transform:translateY(-4px) scale(1.18); }
}

/* ── ④ 이모지·ㅋㅋ 만 있는 말 ───────────────────────────────────────────
   말풍선을 벗고 글자만 크게. 판정은 `shop-tarojip.js 짧은반응인가()` 가 한다. */
body.tj-on .tj-bubble.is-emoji{
  background:none; border:0; box-shadow:none;
  padding:2px 6px 4px;
  font-size:1.85rem; line-height:1.15; letter-spacing:.02em;
}
body.tj-on .tj-bubble.is-emoji::after{ display:none; }   /* 말풍선이 없으니 꼬리도 없다 */
body.tj-on .tj-msg.is-me .tj-bubble.is-emoji{ color:#3a2e28; text-shadow:0 1px 6px rgba(255,255,255,.6); }

/* ── 동작 줄이기 ────────────────────────────────────────────────────────
   튀는 것은 전부 끄고 상태만 남긴다. 꼬리·크기는 움직임이 아니므로 그대로 둔다. */
@media (prefers-reduced-motion: reduce){
  body.tj-on .tj-msg{ animation:none; }
  body.tj-on .tj-dots i{ animation:none; opacity:.7; }
}

/* ════════════════════════════════════════════════════════════════════════
   2026-09-05 사람 지시 ⑤ 「카드 조합·케미」 — LIVE READING 5단계
   ────────────────────────────────────────────────────────────────────────
   두 장이 **동시에** 떠오른다. 한 장씩 차례로 비추면 그냥 또 하나의 카드 설명이 된다 —
   [이 둘이 같이 나온 게 뜻이 있다] 는 말은, 둘이 같이 떠야 눈에 들어온다.

   ★ 새 색을 만들지 않았다 — 띠·번개의 금빛은 `.tj-card.is-key .tj-face` 의 테두리 색
     `rgba(233,199,123,…)` 그대로다(위 §핵심 카드 절). 값이 두 곳에 있으면 한쪽이 낡는다.
   ★ 들어올림은 `is-focus`(-7px/1.12)와 `is-key`(-10px/1.16) 사이인 **-9px/1.14** 로 둔다 —
     케미는 포커스보다 강하고 핵심보다 약하다. 셋이 같은 척도 위에 있어야 화면이 말이 된다.
   ════════════════════════════════════════════════════════════════════════ */
.tj-card.is-combo{ transform:translateY(-9px) scale(1.14); z-index:2; }
.tj-card.is-combo .tj-face{
  box-shadow:0 0 0 1.5px rgba(233,199,123,.82),
             0 0 22px 3px rgba(233,199,123,.40),
             0 11px 26px rgba(10,6,18,.60);
}
/*  두 장 사이의 ⚡ — 카드가 아니라 **판(.tj-slots)** 에 얹는다.
    카드에 붙이면 카드가 확대·이동할 때 같이 끌려가 자리가 어긋난다.
    ★ 자리(--tj-combo-x/y)는 `shop-tarojip.js 케미주기()` 가 **두 카드 중심의 중점**으로 재서 준다.
      여기 50% 로 고정하면 세 장짜리에서 가운데 카드를 덮는다(2026-09-05 실측). 기본값은 그 옛 자리다. */
body.tj-combo-on .tj-slots::after{
  content:"⚡";
  position:absolute;
  left:var(--tj-combo-x, 50%); top:var(--tj-combo-y, 50%);
  transform:translate(-50%,-50%);
  font-size:1.5rem; line-height:1;
  color:rgba(233,199,123,.95);
  text-shadow:0 0 12px rgba(233,199,123,.62), 0 2px 6px rgba(10,6,18,.7);
  pointer-events:none; z-index:4;
  animation:tj-combo-spark .5s ease-out both;
}
@keyframes tj-combo-spark{
  0%  { opacity:0; transform:translate(-50%,-50%) scale(.5); }
  60% { opacity:1; transform:translate(-50%,-50%) scale(1.15); }
  100%{ opacity:1; transform:translate(-50%,-50%) scale(1); }
}
@media (prefers-reduced-motion: reduce){
  body.tj-combo-on .tj-slots::after{ animation:none; }
}

/* ════════════════════════════════════════════════════════════════════════
   2026-09-05 사람 지시 ⑬ 「명확한 결론 + 근거」 — LIVE READING 6단계
   ────────────────────────────────────────────────────────────────────────
   앞판의 결론은 `.is-key` 강조 말풍선 **한 줄**이었다. 그래서 [그래서 왜 그렇게 봤는데?] 가 남았다.
   이제 한 덩어리 안에 🔮 머리 · 결론 · 근거 1~2줄이 함께 선다.

   ★ 색을 새로 만들지 않았다 — 바탕·테두리는 `.tj-bubble.is-key` 그대로 쓰고(위 §결론 절),
     여기서는 **간격과 위계**만 준다. 값이 두 곳에 있으면 한쪽이 낡는다.
   ★ 근거는 결론보다 **한 단계 작고 연하다**(.86rem · opacity .82). 같은 크기면 결론이 안 보인다.
   ★ 말풍선을 둘로 쪼개지 않는다 — 근거가 따로 서면 [또 한 마디]로 읽혀
     [무슨 말이 더 있나] 싶어진다. 한 덩어리라야 [이게 답이고 이게 이유다]로 읽힌다.
   ════════════════════════════════════════════════════════════════════════ */
body.tj-on .tj-bubble.is-verdict{
  padding-top:9px;
  line-height:1.5;
}
/*  🔮 루나의 결론 — 머리줄. 금빛은 `.tj-cardname b`(카드 이름 위 라벨)와 같은 값이다. */
body.tj-on .tj-verdict-head{
  display:block;
  margin-bottom:5px;
  font-size:.62rem; font-weight:600; letter-spacing:.07em;
  color:var(--pg-gold, #c9a961);
  opacity:.95;
}
/*  근거 — 결론 아래 얇은 선 하나를 두고 한 줄씩. 선은 금빛을 아주 옅게 깐 것이다. */
body.tj-on .tj-verdict-why{
  display:block;
  margin-top:8px; padding-top:7px;
  border-top:1px solid rgba(201,169,97,.26);
}
body.tj-on .tj-verdict-why i{
  display:block;
  font-style:normal;
  font-size:.86rem; line-height:1.45;
  opacity:.82;
  font-weight:400;                       /* .is-key 가 600 이라 근거만 되돌린다 */
}
body.tj-on .tj-verdict-why i + i{ margin-top:3px; }
/*  근거 줄머리 — 글자가 아니라 자국이다. 목록처럼 보이지 않게 아주 짧고 연하게. */
body.tj-on .tj-verdict-why i::before{
  content:"— ";
  color:var(--pg-gold, #c9a961);
  opacity:.62;
}

/* ════════════════════════════════════════════════════════════════════════
   2026-09-05 사람 지시 ③ 「이모지 반응 버튼」 — [주 타겟층 10·20대]
   ────────────────────────────────────────────────────────────────────────
   입력줄 **바로 위**의 빠른 반응 칩. 카톡·인스타가 쓰는 그 자리다.
   손가락 하나로 반응할 수 있으면 [보고만 있는 화면]이 [같이 있는 화면]이 된다.

   ★ 새 색을 만들지 않았다 — 바탕·테두리는 `#user-input`(입력칸)과 같은 값이다.
     같은 줄에 붙어 서므로 다른 색이면 남의 것처럼 뜬다.
   ★ 높이 30px · 글자 .95rem — 입력줄(약 40px)보다 **작게** 둔다. 칩이 더 크면
     입력이 아니라 칩이 주인공처럼 보인다. 손가락은 폭(최소 44px)으로 받는다.
   ★ 넘치면 가로로 스크롤한다 — 줄바꿈하면 패널이 한 줄 더 커져 대화창을 먹는다.
   ════════════════════════════════════════════════════════════════════════ */
body.tj-on .tj-reacts{
  display:flex; gap:6px;
  /*  ★ `flex:0 0 auto` 를 빼먹으면 **줄이 세로로 뭉개진다.**
      `.tj-panel` 이 flex-column 이고 max-height(45dvh)에 닿으면 자식들을 압축하는데,
      기본값 `flex-shrink:1` 이라 이 줄이 먼저 눌린다 — 2026-09-05 실기기 실측:
      칩은 30px 인데 줄이 **5.4px** 로 눌려 칩이 통째로 잘려 보였다.
      줄어들 몫은 대화창(`.tj-chat`)이 진다 — 거기는 스크롤이 있다.  */
  flex:0 0 auto;
  min-height:30px;
  overflow-x:auto; overflow-y:hidden;
  -webkit-overflow-scrolling:touch;
  scrollbar-width:none;
  padding:0 1px 1px;
  margin-bottom:-2px;                    /* 입력줄과의 간격은 패널 gap(9px)이 이미 준다 */
  animation:tj-rise .3s cubic-bezier(.22,.9,.3,1) both;
}
body.tj-on .tj-reacts::-webkit-scrollbar{ display:none; }
body.tj-on .tj-reacts[hidden]{ display:none; }
/* 2026-09-10 2차 POLISH §6 — 짙은 검보라 칩은 새 밝은 상담방과 충돌한다(사람 지적 §6).
   추천질문·말풍선·입력창과 같은 크림/라일락 UI 패밀리로 맞췄다. */
body.tj-on .tj-react{
  flex:0 0 auto;
  min-width:44px; height:30px;           /* 손가락이 받는 최소 폭 44px */
  padding:0 12px;
  border-radius:15px;
  border:1px solid rgba(185,166,238,.38);
  background:linear-gradient(180deg,#fefaf5,#f5f0fb);
  color:#383a5c;                         /* 진한 소프트 네이비 */
  font-size:.95rem; line-height:1;
  cursor:pointer;
  box-shadow:0 1px 4px rgba(120,100,150,.12);
  transition:transform .14s cubic-bezier(.2,.9,.3,1.3), background .14s ease, border-color .14s ease;
}
body.tj-on .tj-react:active{
  transform:scale(.9);
  background:linear-gradient(180deg,#f3dde7,#eccbe0);   /* 뮤트핑크 강조 */
  border-color:rgba(240,168,200,.6);
}
@media (prefers-reduced-motion: reduce){
  body.tj-on .tj-reacts{ animation:none; }
  body.tj-on .tj-react{ transition:none; }
  body.tj-on .tj-react:active{ transform:none; }
}

/* 2026-09-25 iOS 준비 — 로그 패널 마지막 줄이 홈 인디케이터에 가리지 않게(iOS 만: Android 규칙은 그대로) */
[data-platform="ios"] body.tj-log-open #chat{ padding-bottom:calc(28px + env(safe-area-inset-bottom, 0px)); }

/* ═════════════════════════════════════════════════════════════════
   1.1.2 [타로 슬롯 겹침 · 결정 (a)] — 키 작은 폰(화면 높이 700px 이하)에서만.
   원인: 패널 윗변이 화면의 36~38% 에 서 있고 루나 눈·코는 그 아래(42~45%)다. 펼침·고르기 동안 [지금 마음 / 망설임 / 앞으로] 슬롯(74~56px x 90~118px)이
   패널 맨 위에 서서 360x640 에서 눈(y≈255~285) 위에 얹혔다.
   고침: 슬롯 카드를 44x70 으로 줄이고 표(.tj-table) 전체를 40px 아래로 — 패널 높이(64dvh)는 그대로라 대화창(.tj-chat)이 그만큼 줄지만 최소 96px 은 남는다.
   기준 높이는 media query(높이)로만 건다. 360x800 · 411x914 는 이 블록이 걸리지 않아 전과 같다. CSS 만 — 마크업·JS 불변.
   ═════════════════════════════════════════════════════════════════ */
@media (max-height: 700px){
  .tj-slots .tj-card,
  body.tj-chatmode .tj-slots .tj-card,
  .tj-slots.is-many .tj-card,
  body.tj-chatmode .tj-slots.is-many .tj-card,
  .tj-slots.is-crowd .tj-card,
  body.tj-chatmode .tj-slots.is-crowd .tj-card{ width:44px; height:70px; }
  .tj-table{ margin-top:40px; }
}

/* ── 1.1.2 [오늘의 카드] 옆 [오늘의 럭키 카드](기기 안 무료 1장) 한 줄 + 럭키 카드 시트 · 주제 9칸 ── */
body.tj-on .tj-todayrow{ display:flex; gap:8px; margin:0 0 8px; }
body.tj-on .tj-todayrow[hidden]{ display:none; }
body.tj-on .tj-todayrow .tj-todaycard{ flex:1 1 0; min-width:0; margin:0; padding:7px 10px; border-radius:18px;
  display:grid; grid-template-columns:22px minmax(0,1fr); column-gap:7px; row-gap:1px; align-items:center; font-size:.76rem; }
body.tj-on .tj-todayrow .tj-todaycard-ico{ grid-row:1 / span 2; }
body.tj-on .tj-todayrow .tj-todaycard-label{ grid-column:2; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
body.tj-on .tj-todayrow .tj-todaycard-badge{ grid-column:2; justify-self:start; font-size:.58rem; padding:2px 7px; }
.tj-lucky-veil{ position:fixed; inset:0; z-index:9700; display:flex; align-items:center; justify-content:center; padding:16px; background:rgba(14,8,26,.78); }
.tj-lucky-sheet{ width:100%; max-width:340px; max-height:92dvh; overflow-y:auto; box-sizing:border-box; padding:16px 16px 14px; border-radius:22px; text-align:center;
  background:linear-gradient(180deg,#f7efff,#efe4fb); border:1.5px solid #c9a8ef; color:#3a2f4a; box-shadow:0 12px 34px rgba(0,0,0,.4); }
.tj-lucky-img{ display:block; width:44%; max-width:150px; height:auto; margin:0 auto 8px; border-radius:10px; box-shadow:0 6px 16px rgba(30,14,46,.35); }
.tj-lucky-lead{ margin:0; font-size:.76rem; color:#7a5fb0; }
.tj-lucky-name{ margin:2px 0 6px; font-size:1.3rem; font-weight:800; }
.tj-lucky-keys{ display:flex; flex-wrap:wrap; justify-content:center; gap:6px; margin-bottom:8px; }
.tj-lucky-keys span{ padding:3px 10px; border-radius:999px; background:rgba(122,95,176,.14); font-size:.74rem; color:#5a3f90; }
.tj-lucky-text{ margin:0 0 6px; font-size:.9rem; line-height:1.55; word-break:keep-all; }
.tj-lucky-note{ margin:0 0 10px; font-size:.68rem; line-height:1.45; color:#8a7aa6; word-break:keep-all; }
.tj-lucky-acts{ display:grid; grid-template-columns:1fr 1fr; gap:8px; }
.tj-lucky-acts button{ min-height:44px; border:0; border-radius:22px; background:#fff; color:#4a3f7a; font:inherit; font-size:.82rem; font-weight:700; box-shadow:inset 0 0 0 1.5px #c9a8ef; cursor:pointer; }
.tj-lucky-acts button.is-key{ grid-column:1 / -1; background:linear-gradient(135deg,#805c98,#61437d); color:#fff; box-shadow:none; }
.tj-lucky-acts button.is-quiet{ color:#7a6a9a; }
body.tj-lucky-open{ overflow:hidden; }
/* 주제 9칸 — 2열 × 5행(마지막 한 칸은 가운데). 칸 높이를 조금 줄여 화면에 다 든다 */
body.tj-on .tj-acts.is-grid button:nth-child(odd):last-child{ grid-column:1 / -1; }
body.tj-on.tj-many .tj-acts.is-grid{ gap:6px; }
body.tj-on.tj-many .tj-acts.is-grid button{ min-height:40px; font-size:.8rem; }
