/* ============================================================
   미장과 국장 — 스타일
   색 = 기분(한국 증시 관습: 좋음=따뜻한 붉은 / 나쁨=차가운 파랑 / 중립=회색).
   각성 = 형태와 모션(진동 속도·진폭)이 담당하고, 색은 각성을 표현하지 않는다.
   UI 자체는 채도를 낮게 유지해 캐릭터 색만 튀게 한다.
   ============================================================ */

/* ============================================================
   밝은 컨셉 하나로 간다 ('26-08-15 확정). 레퍼런스(마음정원·콰블·무디)는
   전부 다크 모드가 없다 — 분위기 자체가 정체성이라 OS 설정을 따라 얼굴이
   바뀌지 않는다. 우리도 같은 선택을 한다.

   배경은 하늘→크림→지면으로 색을 갖고, **캐릭터는 흰 카드 위에 앉는다.**
   카드가 무대 역할을 하므로 배경이 채도를 가져도 감정 색(좋음=붉은/나쁨=파랑)의
   신호가 죽지 않는다. 배경 하늘빛은 밝고 옅어서 '나쁨'의 진한 파랑과 섞이지 않는다.
   ============================================================ */
:root {
  --bg: #F6EEE2;

  /* 화면에 고정되는 풍경 (위 → 아래) */
  --sky-1: #C6DEEE;            /* 하늘 */
  --sky-2: #DFEAEC;
  --sky-3: #FAF0E1;            /* 크림 */
  --sky-4: #F7E4CE;            /* 노을빛 */
  --ground: #CFDFBC;           /* 지면 — 초록은 우리 색 체계에서 비어 있어 안전하다
                                  (한국 증시는 상승=빨강/하락=파랑, 초록은 쓰지 않는다) */

  --surface: #FFFDF9;          /* 무대가 되는 흰 카드 */
  --surface-2: #F3EDE3;
  --ink: #2A2723;
  --muted: #79706A;
  --line: #EBE3D6;
  --shadow: 0 1px 2px rgba(72,60,44,.05), 0 10px 26px -14px rgba(72,60,44,.22);

  /* 감정 색은 3단 램프다 — soft(옅음) → 본색 → deep(짙음). 극단 감정(도취·패닉)일수록
     램프 위쪽을 쓴다. 3색만으로는 22개 감정이 한 덩어리로 뭉개진다 */
  --good: #6FA3DC;
  --good-soft: #B2D0EB;
  --good-deep: #3D6FA8;
  --bad: #8B82C0;
  --bad-soft: #ABA6CB;
  --bad-deep: #5F5590;
  /* 중립은 배경과 같은 계열로 두면 탁해 보인다. 맑은 돌빛으로 —
     무덤덤·심심함이 전체의 30%라 가장 자주 보이는 얼굴이다 */
  --neutral: #86B5AC;
  --neutral-soft: #B8D4D0;
  --neutral-deep: #5E8B82;
  /* 물방울을 칠하기 좋은 밝기와, 글자로 읽히는 밝기는 다르다.
     중립 감정이 카드 헤드라인으로 나올 때 흰 카드 위에서 묻혀 버린다 */
  --neutral-ink: #4F7A72;

  /* ★ 등락률 색은 감정과 **축이 다른 정보**다. 감정 색이 에셋(파랑·민트·보라)을 따라가도
     여기는 한국 증시 관습(상승=빨강, 하락=파랑)을 그대로 지킨다 — 참조로 묶어 두면
     감정 팔레트를 바꾼 순간 '+3.5%'가 파랗게 나온다 */
  --up: #E8574A;
  --down: #4A73D6;

  --r-lg: 22px;
  --r-md: 14px;
  --tap: 44px;
}

* { box-sizing: border-box; }

/* display를 지정한 요소는 hidden 속성이 무시된다 (.sheet=grid, .handoff-strip=flex).
   화면이 통째로 덮이는 사고가 나므로 전역으로 못 박는다. */
[hidden] { display: none !important; }

/* ★ html 배경 = iOS 홈화면 웹앱의 **상태바 뒤 색** ('26-09-01). 하늘 그라디언트는
   body::before(뷰포트 고정)라 상태바 영역까지 못 올라가고, iOS는 그 뒤를 문서 캔버스
   (html 배경)로 칠한다 — 크림이면 하늘색 화면 위가 잘려 보인다. manifest theme_color로는
   안 먹히는 걸 실기기로 확인했다. 위쪽 러버밴드(당겨서 늘어나는 영역)도 같이 하늘색이 된다 */
html { -webkit-text-size-adjust: 100%; background: var(--sky-1); }

body {
  margin: 0;
  /* ★ 배경 없음 ('26-09-01) — html에 캔버스 색을 준 순간 body 배경은 캔버스로 승격되지
     않고 자기 자리에 남아 ::before 그라디언트(z-index:-1, 루트 문맥이라 body보다 뒤)를
     통째로 덮는다. 실제로 전체 화면이 크림색이 되는 사고가 났다 */
  background: transparent;
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", Pretendard,
               "Noto Sans KR", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  word-break: keep-all;          /* 한국어 줄바꿈이 단어 중간에서 끊기지 않게 */
}

/* 풍경 층 — 화면에 고정해서 콘텐츠가 그 위를 지나가게 한다.
   평평한 단색 바탕이 "차갑다"는 인상의 대부분을 만들고 있었다.
   지면은 위쪽 경계를 흐려서 띠가 아니라 지평선처럼 보이게 한다. */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(155% 36% at 50% 101%, var(--ground) 0%,
                    var(--ground) 42%, transparent 72%),
    linear-gradient(180deg,
      var(--sky-1) 0%, var(--sky-2) 26%, var(--sky-3) 58%, var(--sky-4) 100%);
}

/* iOS 사파리의 기본 탭 하이라이트(어두운 덮개)를 끈다 ('26-09-02 "검은 박스 잔상" 신고).
   눌림 반응은 각 요소의 :active(scale·색)가 담당하므로 기본 덮개는 이중 신호다 */
button { font: inherit; color: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; }
a, .cd, .friend { -webkit-tap-highlight-color: transparent; }

.app {
  max-width: 520px;
  margin: 0 auto;
  padding: max(20px, env(safe-area-inset-top)) 20px
           calc(84px + env(safe-area-inset-bottom));
}
/* 홈 화면 추가 배너는 탭바 위에 겹쳐 뜬다 — 떠 있는 동안은 마지막 요소가
   배너에 가리지 않도록 바닥을 더 비운다 (상세의 공유 버튼이 실제로 가렸다) */
body.has-a2hs .app { padding-bottom: calc(184px + env(safe-area-inset-bottom)); }

/* ── 헤더 ─────────────────────────────────────────────────── */
.head { padding: 16px 2px 20px; }
.head-eyebrow {
  margin: 0 0 6px; font-size: 13px; letter-spacing: .06em;
  color: var(--muted); font-weight: 600;
}
.head-title { margin: 0; font-size: 25px; line-height: 1.35; letter-spacing: -.02em; font-weight: 800; text-wrap: balance; }
/* 화면이 무엇을 하자는 것인지 말하는 줄. 카드마다 반복하지 않고 제목 아래 한 번만 선다 */
.head-sub { margin: 8px 0 0; font-size: 15px; font-weight: 700; color: var(--muted); }
.head-detail { display: flex; align-items: center; gap: 12px; padding-bottom: 8px; }
.back {
  background: var(--surface); border: 1px solid var(--line); border-radius: 50%;
  width: var(--tap); height: var(--tap); font-size: 19px; line-height: 1;
  display: grid; place-items: center; flex: none;
}
.head-detail .head-eyebrow { margin: 0; }

/* ── 친구 목록 ────────────────────────────────────────────── */
.friends { display: flex; flex-direction: column; gap: 14px; }

/* 홈은 영원히 카드 두 장 + 인수인계뿐이다 — 긴 폰에서 아래가 텅 비지 않게
   뷰를 화면 높이까지 늘리고 두 카드가 남는 높이를 나눠 갖는다 ('26-08-31 사용자 제안).
   ★ min-height라서 내용이 더 길면(가로 모드·A2HS 배너) 그냥 스크롤로 넘어간다.
   104px = .app 상단 패딩 20 + 탭바 몫 84 (env는 iOS 노치 대응) */
@media (max-width: 899px) {
  #view-home {
    display: flex; flex-direction: column;
    min-height: calc(100vh - 104px);
    min-height: calc(100dvh - 104px - env(safe-area-inset-top) - env(safe-area-inset-bottom));
  }
  #view-home .friends { flex: 1; }
  /* 카드는 .friend-wrap 래퍼 안에 있다 — 래퍼가 높이를 받아 카드에 넘겨야 한다 */
  #view-home .friend-wrap { flex: 1; display: flex; flex-direction: column; }

  #view-home .friend, #view-home .skeleton-card { flex: 1; min-height: 132px; }

  /* ★ 늘어난 카드는 **큰 캐릭터**로 채운다 ('26-08-31 확정) — 이야기·칩·공유를 카드에
     인라인하는 안은 시도했다가 회귀: "첫 화면부터 정신없다, 미니멀하고 귀엽지 않다".
     홈은 요약(얼굴·기분·문구·등락)만, 이야기와 공유는 눌러서 상세에서 본다.
     빈 인상은 캐릭터 크기(92→128)가 해결한다 */
  #view-home .friend { grid-template-columns: 128px 1fr; gap: 18px; }
  #view-home .friend .avatar { width: 128px; height: 128px; }
  /* 물방울은 아바타 박스의 78% — 커질수록 모티프를 어깨 쪽으로 당긴다 (아래 900px+ 주석 참고) */
  #view-home .friend .avatar .motif { top: 8px; right: 8px; width: 30px; height: 30px; font-size: 15px; }
  #view-home .friend-emotion { font-size: 26px; }
  #view-home .friend-phrase { font-size: 15.5px; }

  /* 탭 가능 신호 — 셰브론만 ('26-09-03 확정). 이력: 원형 칩("너무 보편적") →
     사이드 레일(구분선+꺾쇠) → **레일 제거, 꺾쇠 단독**. 스택·접힘 은유 실험의 결론
     (예쁘지만 신호로 약함)대로 관습 기호(›)는 유지하되 그릇 없이 맨몸으로 —
     iOS 설정 앱의 리스트 행과 같은 문법이라 가장 조용하면서 오독이 없다.
     눌리면 꺾쇠가 진해져 "이걸 누른 게 맞다"를 확인해 준다 */
  #view-home .friend { position: relative; padding-right: 34px; }
  #view-home .go-chip {
    position: absolute; right: 10px; top: 0; bottom: 0; width: 20px;
    display: grid; place-items: center;
  }
  #view-home .go-chip svg {
    width: 14px; height: 14px; fill: none;
    stroke: var(--muted); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
  }
  #view-home .friend:active .go-chip svg { stroke: var(--ink); }
}

.friend {
  display: grid;
  grid-template-columns: 92px 1fr;
  gap: 16px;
  align-items: center;
  width: 100%;
  text-align: left;
  padding: 18px 18px 18px 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  transition: transform .18s ease;
}
.friend:active { transform: scale(.985); }

/* 좁은 화면에서는 카드가 요약만 보여주고 이야기는 상세로 넘긴다.
   넓어지면(900px+) .friend-wrap이 카드가 되고 이야기가 그 안에 펼쳐진다 */
.friend-story { display: none; }

/* 이름까지 muted로 두면 카드에서 가장 약한 요소가 된다 — 캐릭터 이름은 ink로 세우고
   지수·날짜만 muted로 뺀다 */
.friend-name {
  margin: 0 0 1px; font-size: 14px; display: flex; align-items: baseline;
  gap: 7px; flex-wrap: wrap;
}
.friend-name b { font-size: 15px; font-weight: 800; color: var(--ink); letter-spacing: -.01em; }
.friend-name span { font-weight: 500; color: var(--muted); }
.friend-emotion { margin: 2px 0 4px; font-size: 22px; font-weight: 800; letter-spacing: -.02em; color: var(--tone-ink, var(--tone)); }
.friend-phrase { margin: 0 0 12px; font-size: 15px; color: var(--ink); opacity: .82; }

/* '강도'(내부 합성 점수) 미니게이지는 폐기 — 무엇을 뜻하는지 화면만 보고 알 수 없었고,
   설명하려면 산식을 드러내야 한다. 세기는 감정 어휘와 물방울의 움직임이 이미 말한다.
   ★ 등락률 색은 감정이 아니라 **부호**를 따른다 (app.js retHTML 주석 참고) */
.ret {
  margin: 0; font-size: 19px; font-weight: 800; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}
.ret i { font-style: normal; font-size: .62em; margin-right: 5px; vertical-align: .12em; }
.ret-up   { color: var(--up); }
.ret-down { color: var(--down); }
.ret-flat { color: var(--muted); }

/* ── 캐릭터 (일러스트 에셋) ───────────────────────────────── */
/* 그림은 public/art/01~22.svg. 여기서는 크기·색 보정·움직임만 맡는다 */
.avatar { position: relative; width: 92px; height: 92px; }
.avatar-lg { width: 168px; height: 168px; margin: 8px auto 4px; }

.fimg { display: block; width: 100%; height: 100%; object-fit: contain; user-select: none; }


/* ★ 색은 에셋 그대로 쓴다 ('26-08-15 사용자 결정). 색조를 돌려 우리 관습(좋음=붉은)에
   맞추던 필터를 걷어냈다 — 필터는 원화가 의도한 색을 통째로 밀어버린다.
   텍스트에 쓰는 감정 색(--good/--neutral/--bad)도 아래 :root에서 에셋에 맞췄다. */

/* ── 움직임 ───────────────────────────────────────────────────
   ★ 두 겹이다. **호흡(.fwrap)은 모든 감정이 갖고**, 그 위에 기분별 몸짓(.fimg)이 얹힌다.
     무기력·지침처럼 몸짓이 거의 없는 감정도 숨은 쉬어야 살아 있다.
     한 요소에 애니메이션 둘을 걸면 뒤엣것의 transform이 앞엣것을 덮으므로 레이어를 나눈다.
   ★ 각성(a)이 속도·진폭을, 기분(tone)이 몸짓의 성격과 주기 배율을 정한다.
   ★ transform-origin은 바닥이어야 한다. 가운데면 착지가 공중에서 일어난다 */
.fwrap { display: block; width: 100%; height: 100%; transform-origin: 50% 88%; }

.avatar .fwrap {
  animation: breathe var(--bdur, 4s) ease-in-out infinite;
}
.avatar .fimg {
  animation: var(--motion, floatIdle) var(--dur, 7s) var(--ease, ease-in-out) infinite;
  transform-origin: 50% 88%;
}

/* ★ '또잉'의 정체는 **구간마다 다른 속도**다. 올라갈 때와 내려올 때가 같은 곡선이면
   아무리 진폭을 키워도 밋밋하다. 키프레임 안의 animation-timing-function이 그 구간에만
   걸리므로, 솟을 땐 확 튀고 떨어질 땐 가속하고 반동은 사뿐하게 나눠 준다. */

/* 호흡 — 모든 감정 공통. 들숨은 짧고 날숨은 길다.
   ★ 가로·세로를 **같은 방향**으로 움직인다. 세로만 늘리면 몸짓과 곱해져 '늘어난' 것으로
     보인다 — 부피가 부푸는 것으로 읽혀야 숨이지, 늘어나면 고무줄이다 */
@keyframes breathe {
  0%   { transform: scale(1, 1);
         animation-timing-function: cubic-bezier(.32,.72,.4,1); }      /* 들숨: 빠르게 */
  38%  { transform: scale(calc(1 + var(--breath, .02) * .55), calc(1 + var(--breath, .02) * .8));
         animation-timing-function: cubic-bezier(.45,0,.55,1); }       /* 날숨: 천천히 */
  100% { transform: scale(1, 1); }
}

/* 좋음: 눌렀다 튀어 오르고, 떨어지며 눌리고, 반동으로 한 번 더 — 또잉 */
@keyframes bobUp {
  0%   { transform: translateY(0) scale(1, 1);
         animation-timing-function: cubic-bezier(.5,0,.75,.5); }
  9%   { transform: translateY(0) scale(1.013, .987);               /* 예비 동작: 웅크린다 */
         animation-timing-function: cubic-bezier(.1,.85,.3,1); }    /* 확 솟는다 */
  34%  { transform: translateY(calc(var(--wob, 2px) * -1.25)) scale(.987, 1.016);
         animation-timing-function: cubic-bezier(.55,.06,.9,.55); } /* 가속하며 떨어진다 */
  56%  { transform: translateY(0) scale(1.016, .984);
         animation-timing-function: cubic-bezier(.15,.8,.35,1); }   /* 반동 */
  74%  { transform: translateY(calc(var(--wob, 2px) * -.34)) scale(.995, 1.006);
         animation-timing-function: cubic-bezier(.5,.05,.6,1); }
  88%  { transform: translateY(0) scale(1.006, .995);
         animation-timing-function: ease-out; }
  100% { transform: translateY(0) scale(1, 1); }
}

/* 중립: 잔잔히 뜬다. 오를 땐 느긋하고 내릴 땐 조금 빠르게 */
@keyframes floatIdle {
  0%   { transform: translateY(0) scale(1, 1);
         animation-timing-function: cubic-bezier(.35,.5,.4,1); }
  46%  { transform: translateY(calc(var(--wob, 2px) * -.85)) scale(.991, 1.009);
         animation-timing-function: cubic-bezier(.6,.04,.7,.6); }
  82%  { transform: translateY(0) scale(1.008, .993);
         animation-timing-function: ease-out; }
  100% { transform: translateY(0) scale(1, 1); }
}

/* 나쁨: 뜨지 않는다. 툭 떨어지고 힘겹게 올라온다 */
@keyframes sagDown {
  0%   { transform: translateY(0) scale(1, 1);
         animation-timing-function: cubic-bezier(.62,.05,.9,.45); }  /* 무겁게 툭 */
  36%  { transform: translateY(calc(var(--wob, 2px) * .62))
                    scale(calc(1 + var(--pulse, .015) * 1.0), calc(1 - var(--pulse, .015) * .8));
         animation-timing-function: cubic-bezier(.2,.35,.45,1); }    /* 힘겹게 되돌아온다 */
  100% { transform: translateY(0) scale(1, 1); }
}
@media (prefers-reduced-motion: reduce) {
  .avatar .fimg, .avatar .fwrap { animation: none; }
  .dtrack .fill { transition: none; }
  .dnum.bump { animation: none; }
}

.motif {
  position: absolute; top: -2px; right: -2px;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--surface); border: 1px solid var(--line);
  display: grid; place-items: center; font-size: 13px;
  transition: opacity .5s ease, border-color .5s ease;
}
.avatar-lg .motif { width: 36px; height: 36px; font-size: 18px; }

/* 크기는 각 자리의 font-size가 정해 왔다 — em으로 받으면 그 규칙이 그대로 산다 */
.motif svg { width: 1.32em; height: 1.32em; display: block; }
.mf { fill: var(--motif); stroke: none; }
.mr { fill: none; stroke: var(--motif); stroke-width: 2.1; stroke-linecap: round; }
.motif[data-mk="us"] { --motif: #D9A63F; }      /* 달 */
.motif[data-mk="kr"] { --motif: #EFA236; }      /* 해 */
/* 자는 쪽 — 색을 빼고 가라앉힌다. 지우지는 않는다(밤/낮 세계관은 계속 보여야 한다) */
.motif.asleep { --motif: #ABA294; opacity: .62; border-color: transparent; }

/* ── 화면 ─────────────────────────────────────────────────── */
.view { animation: fadeUp .3s ease both; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ── 카드 · 공통 조각 ─────────────────────────────────────── */
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 20px; margin-top: 16px; box-shadow: var(--shadow);
}
.card-label { margin: 0 0 10px; font-size: 12px; font-weight: 700; letter-spacing: .08em; color: var(--muted); }
.story { margin: 0; font-size: 16px; line-height: 1.75; white-space: pre-wrap; }
.story-wait { margin: 0; font-size: 14px; color: var(--muted); }
.empty { margin: 22px 0; text-align: center; font-size: 14px; color: var(--muted); }

.chips { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 14px; }
.chip {
  font-size: 12.5px; font-weight: 600; color: var(--muted);
  background: var(--surface-2); border-radius: 99px; padding: 6px 11px;
}

.btn {
  border: 0; border-radius: 99px; font: inherit; font-weight: 700;
  height: 46px; padding: 0 20px; cursor: pointer;
}
/* 상세의 공유 버튼 — 이야기 카드에 붙어 있으면 답답하다 ('26-08-31 사용자 지적).
   카드 사이 간격(14px)보다 한 단 더 띄워 '다른 층위의 행동'임을 보인다 */
.btn-block { display: block; width: 100%; margin-top: 24px; }
.btn-primary { background: var(--ink); color: #fff; }
.btn-ghost { background: var(--surface-2); color: var(--ink); }
.btn-share { margin-top: 16px; }

/* 로딩 자리 — 내용이 늦게 와도 화면이 덜컥이지 않게 높이를 잡아 둔다 */
.skeleton-card {
  height: 132px; border-radius: var(--r-lg); margin-top: 16px;
  background: linear-gradient(90deg, var(--surface) 0%, var(--surface-2) 50%, var(--surface) 100%);
  background-size: 220% 100%; animation: shimmer 1.5s ease-in-out infinite;
}
@keyframes shimmer { 0% { background-position: 120% 0; } 100% { background-position: -20% 0; } }

/* ── 인수인계 스트립 ──────────────────────────────────────── */
.handoff-strip {
  display: flex; gap: 12px; align-items: flex-start;
  margin-top: 18px; padding: 15px 17px;
  background: var(--surface-2); border-radius: var(--r-md);
}
.handoff-strip p { margin: 0; font-size: 14px; color: var(--muted); line-height: 1.55; }
/* 인수인계 띠도 배지와 같은 달·해를 쓴다 (app.js가 MOTIF로 채운다) */
.handoff-icon { display: inline-flex; align-items: center; gap: 2px; flex: none; }
.handoff-icon svg { width: 15px; height: 15px; display: block; }
.handoff-icon .hi-us { --motif: #D9A63F; }
.handoff-icon .hi-kr { --motif: #EFA236; }
.handoff-icon i { font-style: normal; font-size: 11px; color: var(--muted); }

/* ── 상세 ─────────────────────────────────────────────────── */
.detail-hero { text-align: center; padding: 4px 0 8px; }
.detail-name { margin: 6px 0 0; font-size: 15px; font-weight: 700; color: var(--muted); }
.detail-emotion { margin: 4px 0 6px; font-size: 34px; font-weight: 800; letter-spacing: -.03em; }
.detail-phrase { margin: 0 0 10px; font-size: 16px; color: var(--muted); }

/* ── 세그먼트 ─────────────────────────────────────────────── */
.seg {
  display: flex; gap: 4px; padding: 4px; margin-top: 4px;
  background: var(--surface-2); border-radius: 99px;
}
.seg button {
  flex: 1; border: 0; background: transparent; color: var(--muted);
  height: 38px; border-radius: 99px; font-size: 14px; font-weight: 700; cursor: pointer;
}
.seg button.on { background: var(--surface); color: var(--ink); box-shadow: var(--shadow); }

/* ── 달력 한 칸의 얼굴 ────────────────────────────────────── */
/* 홈 아바타와 같은 에셋. 움직임만 멈춘다 — 칸마다 70개를 흔들 수는 없다 */
.face { display: block; }
.face .fwrap { transform: scale(var(--s, 1)); }

/* ── 기분 달력 ────────────────────────────────────────────── */
.months { display: grid; gap: 26px; }
/* 좁은 화면(달력이 세로로 쌓이는 구간)은 **이번 달만** — 지난달이 위에 있으면
   이번 달을 보러 매번 스크롤해야 한다 ('26-08-31 사용자 지적). DOM은 두 달을 다
   렌더하고 지난달(first-child)만 숨긴다 — 1180px부터는 2열이라 둘 다 보인다 */
@media (max-width: 1179.9px) { .months .month:first-child { display: none; } }
/* 달력만 카드 안쪽 여백을 줄인다 — 한 칸이 곧 캐릭터라 폭 4px이 얼굴 크기를 가른다 */
.months, .cal-hint { margin-left: -6px; margin-right: -6px; }
.month { min-width: 0; }
.month-t { margin: 0 0 8px; font-size: 17px; font-weight: 800; letter-spacing: -.02em; }
.wd, .grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.wd { gap: 2px; margin-bottom: 3px; }
.wd span { text-align: center; font-size: 10.5px; color: var(--muted); font-weight: 600; }
.grid { gap: 2px; }

.cd {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  border: 0; background: transparent; padding: 5px 0 6px; border-radius: 13px;
  font: inherit; cursor: pointer;
}
.cd > b { font-size: 11.5px; font-weight: 600; color: var(--muted); }
/* 얼굴 자리를 빈 칸에도 남겨야 줄 높이가 흔들리지 않는다 (padding 해킹 금지) */
.cd .face, .cd .face-void { width: 42px; height: 42px; }
.cd.pad { visibility: hidden; }
.cd.off { cursor: default; }
.cd.off > b { opacity: .34; }
/* 아직 오지 않은 날 — 숫자만, 휴장일(.34)보다 옅게. face-void 스페이서는 여기도 필수다 */
.cd.future { cursor: default; }
.cd.future > b { opacity: .18; }
.cd.today > b { color: var(--ink); font-weight: 800; }
.cd.on { background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line); }
.cd.on > b { color: var(--ink); font-weight: 800; }
.cal-hint { margin: 18px 0 0; font-size: 12px; color: var(--muted); text-align: center; }

/* ── 고른 날 ──────────────────────────────────────────────── */
/* ('26-08-31) 상단 블록을 달력 아래로 내리는 재배치를 넣었다가 **사용자 요청으로 회귀** —
   이 블록은 오늘 상태이자 '날짜 클릭 → 그날 표정' 뷰어를 겸한다는 걸 확인하고
   재고하기로 했다. 다시 시도하려면 git 없는 저장소이므로 README '남은 일' 참고 */
/* 아바타 + 말풍선 한 장면 ('26-08-31 통합). 말풍선이 요즘 컨디션과 '고른 날' 뷰어를
   겸한다 — 블록이 하나라 상단이 절반 높이가 됐다. 캐릭터가 말하는 화법은 그대로 */
.pick-scene {
  display: flex; align-items: center; gap: 16px;
  padding: 2px 0 20px; margin-bottom: 20px; border-bottom: 1px solid var(--line);
}
.pick-face { flex: none; }
.pick-scene .avatar-lg { margin: 0; width: 108px; height: 108px; }
.pick-scene .motif { top: 2px; right: 2px; width: 26px; height: 26px; font-size: 13px; }

/* 근황/그날 이야기는 캐릭터가 '하는 말'이다 — 라벨·표가 아니라 말풍선 */
.cond {
  flex: 1; min-width: 0; position: relative;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 20px; padding: 15px 18px;
}
.cond p { margin: 0; font-size: 15px; line-height: 1.65; letter-spacing: -.01em; }
/* 꼬리는 45° 돌린 네모 — 왼쪽(아바타)을 가리키므로 왼쪽 꼭짓점의 두 변에만 선 */
.cond::before {
  content: ""; position: absolute; width: 13px; height: 13px;
  background: var(--surface-2); border-radius: 0 0 0 4px;
  left: -7px; top: 50%; transform: translateY(-50%) rotate(45deg);
  border-left: 1px solid var(--line); border-bottom: 1px solid var(--line);
}

/* ── 맞히기 ───────────────────────────────────────────────── */
/* 캐릭터 하나당 카드 두 장(일간·주간). 좁으면 세로, 넓으면 나란히 */
.guess-cols { display: grid; gap: 0; }
.guess-cols > section:first-child .guess { margin-top: 16px; }
.guess-cols > section { min-width: 0; }

.guess { margin-top: 10px; }
/* ★ 헤더는 가로 배치 — 캐릭터 옆에 글자가 선다 ('26-08-17 사용자 결정).
   ★ 행 얼굴(32px)과 같은 22종 에셋이라 **크기 비를 좁히면** 카드가 "얼굴 넷 중 하나를
   고르는 중"으로 읽힌다. 줄이는 쪽만 막고 키우는 쪽으로 간다 (지금 4:1) */
.guess-head { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
/* ★ 에셋은 캔버스를 꽉 채우지 않는다 — 256 viewBox 안에서 그림이 y=30.94부터 194px,
   즉 **위아래로 각 12.1%, 좌우로 각 8.6%가 빈다**. 아바타를 키울수록 그 여백도 같이
   커져 캐릭터와 글자 사이가 휑해지므로 음수 마진으로 상쇄한다.
   호흡 애니메이션이 살짝 부풀므로 실측치보다 조금 덜 당긴다 */
.guess-head .avatar { flex: none; width: 128px; height: 128px; margin: -10px -10px -12px -8px; }
.guess-head .motif { top: 16px; right: 24px; width: 34px; height: 34px; font-size: 17px; }
.guess-meta { flex: 1; min-width: 0; }
.guess-title { margin: 0 0 4px; font-size: 18px; font-weight: 800; letter-spacing: -.02em; }
.guess-ask { margin: 0; font-size: 13.5px; line-height: 1.45; color: var(--muted); }
/* 쿡 찌르기 — 폴짝(축하 팝업의 hop 재사용)과 말풍선 */
.avatar.poked .fwrap { animation: cheerHop .75s cubic-bezier(.36, 0, .3, 1) 1; }
.poke-bubble {
  position: absolute; z-index: 73; margin: 0; max-width: min(240px, 72vw);
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  padding: 9px 14px; font-size: 13.5px; font-weight: 700; line-height: 1.45;
  box-shadow: var(--shadow); pointer-events: none;
  animation: fadeUp .18s ease both; transition: opacity .35s ease;
}
.poke-bubble.bye { opacity: 0; }

/* 적중 축하 — 색종이는 팝업 위에도 흩날리게 캔버스를 더 위층에 둔다 */
.confetti { position: fixed; inset: 0; pointer-events: none; z-index: 72; }
.cheer {
  position: fixed; inset: 0; z-index: 71; display: grid; place-items: center;
  background: rgba(42, 39, 35, .16); transition: opacity .35s ease;
}
.cheer.bye { opacity: 0; }
.cheer-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: 28px;
  padding: 26px 40px 26px; text-align: center; box-shadow: var(--shadow);
  animation: cheerPop .32s cubic-bezier(.34, 1.45, .55, 1) both;
}
/* 팝업의 주인공 — 맞힌 그날의 얼굴이 폴짝인다 */
.cheer-face { display: block; width: 88px; height: 88px; margin: 0 auto 8px; }
.cheer-face .fwrap { display: block; width: 100%; height: 100%; animation: cheerHop .9s cubic-bezier(.36, 0, .3, 1) .25s 2; transform-origin: 50% 92%; }
.cheer-title { margin: 0; font-size: 26px; font-weight: 800; letter-spacing: -.02em; }
.cheer-sub { margin: 7px 0 0; font-size: 14.5px; font-weight: 700; color: var(--muted); }
.cheer-streak {
  display: inline-block; margin: 12px 0 0; padding: 7px 16px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 999px;
  font-size: 13px; font-weight: 800; color: var(--ink);
}
@keyframes cheerPop { from { transform: scale(.7); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes cheerHop {
  0%, 100% { transform: translateY(0) scale(1, 1); }
  28% { transform: translateY(-14px) scale(.96, 1.05); }
  56% { transform: translateY(0) scale(1.05, .94); }
  74% { transform: translateY(-4px) scale(1, 1.01); }
}

/* 주간 접기 — 일간이 주인공이고 주간은 원할 때만 편다 ('26-08-31 B안).
   접힌 채로도 '주간이 있다'는 건 보여야 해서 summary를 카드 결로 만든다 */
.week-fold { margin-top: 16px; }
.week-fold > summary {
  list-style: none; cursor: pointer; user-select: none;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 13px 18px; font-size: 14px; font-weight: 700; color: var(--muted);
}
.week-fold > summary::-webkit-details-marker { display: none; }
.week-fold > summary::after { content: ' ▾'; font-size: 11px; }
.week-fold[open] > summary { color: var(--ink); margin-bottom: 14px; }
.week-fold[open] > summary::after { content: ' ▴'; }

/* 마감 시각은 투표 버튼 아래로 내려갔다 — 고르는 자리에서 읽혀야 하는 정보다 */
.guess-when {
  margin: 10px 0 0; font-size: 11.5px; font-weight: 700; color: var(--muted);
  text-align: center; font-variant-numeric: tabular-nums;
}
/* 의견이 갈리는 문항 표시. ★ 반드시 카드별 독립 판정 — 4장 중 한 장에만 붙이면
   넓은 화면에서 배지가 순위표가 되고 두 캐릭터를 견주는 장치가 된다 */
.dsplit {
  margin-left: 6px; padding: 2px 7px; border-radius: 99px;
  background: var(--surface-2); color: var(--muted);
  font-size: 11px; font-weight: 700; vertical-align: 2px;
}

/* ── 분포 = 카드의 주인공 ─────────────────────────────────────
   ★ 여기엔 버튼이 없다 ('26-08-16 사용자 판단). 행이 곧 버튼이면 **선택이 1순위,
     비중이 2순위로 읽힌다** — 이 화면에 들어와 가장 먼저 얻어야 하는 건 "사람들이
     어느 쪽에 몰렸구나"이고 투표는 그 다음이다. 읽는 블록과 누르는 블록을 나눈다.
   ★ 표 수가 적어도 퍼센트로 쓴다. '3명'은 정직하지만 유입이 적은 초기에 화면을
     빈약해 보이게 만든다. 분모는 아래 푸터에 작게 남겨 감추지 않는다. */
/* 블록의 주어 — 위는 사람들, 아래는 나. 같은 선택지 이름이 두 번 나오는데 주어가 없으면
   "같은 게 왜 두 번 있지"가 되고 위가 집계라는 게 전달되지 않는다 ('26-08-17) */
.blab { margin: 0 0 9px; font-size: 12px; font-weight: 700; letter-spacing: .02em; color: var(--muted); }
.dist { display: grid; gap: 11px; }
.drow { display: block; }
.dhead { display: flex; align-items: center; gap: 10px; }
/* 행 얼굴에는 크기만 준다 — 움직임은 .avatar 스코프에만 걸려 있어 여기선 멈춘다.
   32px이 하한이다: 만족·무덤덤·시무룩은 방울 안 눈·입 몇 픽셀로만 갈린다 */
.drow .fwrap { flex: none; width: 32px; height: 32px; }
.dlab { flex: 1; min-width: 0; font-size: 14px; font-weight: 700; letter-spacing: -.01em; }
.drow.me .dlab { color: var(--ci); }
/* 내 선택은 **약하게만** 표시한다 — 강조는 아래 투표 블록이 맡는다.
   여기서 세게 칠하면 다시 "내 선택"이 분포를 눌러 버린다 */
.dlab em {
  margin-left: 6px; padding: 1px 6px; border-radius: 99px;
  background: var(--surface-2); color: var(--ci);
  font-style: normal; font-size: 10.5px; font-weight: 700; vertical-align: 1px;
}
/* 카드에서 가장 큰 활자 — 비중이 주인공이라는 선언이다 */
.dnum {
  flex: none; font-size: 27px; font-weight: 800; letter-spacing: -.03em;
  line-height: 1.1; color: var(--ink); font-variant-numeric: tabular-nums;
}
.dnum i { font-style: normal; font-size: .52em; font-weight: 700; color: var(--muted); margin-left: 1px; }
.dnum .dz { font-size: .74em; color: var(--muted); font-weight: 700; }

.dtrack {
  display: block; margin-top: 6px; height: 8px; border-radius: 99px;
  background: var(--surface-2); overflow: hidden;
}
/* ★ 면적 채움(opacity .18)을 쓰지 않는 이유: 흰 카드 위 합성값의 채널 차이가 5~6이라
   세 색이 사실상 같은 흰색이 된다. 막대를 남기는 유일한 정당화가 거기서 무너진다 */
.dtrack .fill {
  display: block; height: 100%; border-radius: 99px;
  background: var(--c); transition: width .42s cubic-bezier(.2,.8,.2,1);
}
.drow.me .fill { background: var(--ci); }

/* ── 투표 = 내 자리 ──────────────────────────────────────────
   분포와 선을 그어 분리한다. 얼굴은 위 분포 행이 이미 보여줬으므로 여기선 글자만 쓴다 */
.vote { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.vbtns { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; }
.vbtn {
  min-height: var(--tap); padding: 8px 4px;
  border: 1.5px solid var(--line); border-radius: var(--r-md);
  background: var(--surface); color: var(--muted);
  font: inherit; font-size: 12.5px; font-weight: 700; line-height: 1.3;
  word-break: keep-all; cursor: pointer;
  transition: border-color .16s ease, color .16s ease, background .16s ease;
}
.vbtn:hover { border-color: var(--ci); color: var(--ci); }
.vbtn.on { border-color: var(--ci); color: #fff; background: var(--ci); }
/* 마감된 문항 — 분포는 그대로 두고 투표 자리만 안내로 바뀐다.
   ★ 작은 회색 한 줄이면 "왜 버튼이 없지"가 안 풀린다 ('26-08-31 사용자 지적) —
   버튼이 서 있던 자리인 만큼 버튼만 한 존재감으로, 잠긴 상태임이 한눈에 보이게 */
.vwait {
  margin: 16px 0 0; padding: 14px 16px; border-radius: var(--r-md);
  background: var(--surface-2); border: 1px dashed var(--line);
  font-size: 14px; line-height: 1.55; font-weight: 700; color: var(--muted);
  text-align: center;
}

/* 지난번 결과 — 이 화면에서 결과를 보여주는 유일한 자리 (별도 카드를 만들지 않는다) */
.dprev { display: flex; align-items: center; gap: 8px; margin-top: 12px; font-size: 11.5px; }
.dprev .face { flex: none; width: 20px; height: 20px; }
.dprev-t { min-width: 0; color: var(--muted); }
.dprev-t b { color: var(--ink); font-weight: 700; }
.dprev-t em { font-style: normal; font-weight: 700; }
.dprev .rec-mark { margin-left: auto; }

/* 모션은 둘뿐이고 전부 작다 — 우울·무기력일 때 캐릭터가 거의 안 움직이도록 설계돼 있는데
   그 옆에서 숫자가 슬롯머신처럼 구르면 톤이 통째로 깨진다 */
.dnum.bump { animation: numBump .28s ease-out; }
@keyframes numBump { from { transform: translateY(5px); opacity: 0; } to { transform: none; opacity: 1; } }

/* ── 내 기록 ──────────────────────────────────────────────── */
.rec-nums { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; text-align: center; }
.rec-nums div { background: var(--surface-2); border-radius: var(--r-md); padding: 13px 4px; }
.rec-nums b { display: block; font-size: 24px; font-weight: 800; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.rec-nums em { font-style: normal; font-size: 15px; font-weight: 700; color: var(--muted); }
.rec-nums span { display: block; margin-top: 3px; font-size: 11.5px; font-weight: 600; color: var(--muted); }

.rec-list { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 2px; }
.rec-list li { display: flex; align-items: center; gap: 11px; padding: 9px 0; border-top: 1px solid var(--line); }
.rec-list li:first-child { border-top: 0; }
.rec-list .face, .rec-list .face-void { flex: none; width: 38px; height: 38px; }
/* 채점 대기 행 — 얼굴 자리는 비운다. 정답이 아직 없으니 세울 표정도 없다 */
.rec-list .pend { opacity: .68; }
.rec-list div { min-width: 0; flex: 1; }
.rec-when { margin: 0 0 2px; font-size: 11.5px; font-weight: 600; color: var(--muted); }
.rec-what { margin: 0; font-size: 14.5px; font-weight: 700; letter-spacing: -.01em; }
.rec-what em { font-style: normal; font-weight: 600; color: var(--muted); }
.rec-mark { flex: none; font-size: 12px; font-weight: 700; color: var(--muted); }
.hit .rec-mark { color: var(--good-deep); }
.rec-empty { margin: 14px 0 0; font-size: 13px; color: var(--muted); text-align: center; }

.disclaim { margin: 18px 0 0; font-size: 11.5px; line-height: 1.6; color: var(--muted); text-align: center; }

/* ── 탭바 ─────────────────────────────────────────────────── */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  display: flex; justify-content: center; gap: 8px;
  padding: 8px 12px calc(8px + env(safe-area-inset-bottom));
  background: rgba(255,253,249,.92); backdrop-filter: blur(12px);
  border-top: 1px solid var(--line);
}
.tabbar button {
  border: 0; background: transparent; color: var(--muted);
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  font: inherit; font-size: 11px; font-weight: 700; cursor: pointer;
  /* ★ 좌우 여백을 18px로 고정하면 '알아맞히기'(5자)가 320px 기기에서 줄바꿈된다.
     셋을 같은 폭으로 나눠 갖고 여백은 안쪽에서 준다 — 라벨 길이가 달라도 안 깨진다 */
  flex: 1 1 0; min-width: 0; max-width: 132px; padding: 4px 6px;
  white-space: nowrap;
}
/* 아이콘은 텍스트 색을 그대로 물려받아 on 상태에서 라벨과 함께 진해진다 */
.tabbar button svg {
  width: 22px; height: 22px; display: block;
  fill: none; stroke: currentColor; stroke-width: 1.85;
  stroke-linecap: round; stroke-linejoin: round;
}
.tabbar button svg .fill { fill: currentColor; stroke: none; }
.tabbar button.on { color: var(--ink); }
.rail-brand, .rail-foot { display: none; }

/* ── 공유 시트 ────────────────────────────────────────────── */
.sheet {
  position: fixed; inset: 0; z-index: 30;
  display: grid; place-items: center; padding: 20px;
  background: rgba(42,39,35,.42); backdrop-filter: blur(3px);
}
.sheet-panel {
  background: var(--surface); border-radius: var(--r-lg); padding: 16px;
  max-width: 340px; width: 100%; box-shadow: 0 18px 50px rgba(0,0,0,.22);
}
.sheet-panel canvas { display: block; width: 100%; height: auto; border-radius: var(--r-md); }
.sheet-actions { display: flex; gap: 8px; margin-top: 14px; }
.sheet-actions .btn { flex: 1; }

/* ── 새로 고침 토스트 ('26-09-02) — 화면이 스스로 새 기분으로 바뀌었을 때만 뜬다 */
.toast {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(96px + env(safe-area-inset-bottom));
  margin: 0; padding: 10px 18px; border-radius: 999px;
  background: var(--surface); color: var(--ink); border: 1px solid var(--line);
  font-size: 13.5px; font-weight: 600; white-space: nowrap;
  /* 공유 시트(30)보다는 아래 — 모달 흐름에 끼어들지 않는다. 배너(25)·탭바(20)보다는 위 */
  box-shadow: var(--shadow); z-index: 26;
  animation: toast-in .28s ease;
  transition: opacity .35s ease;
}
.toast.bye { opacity: 0; }
/* 홈 화면 추가 배너가 떠 있으면 그 위로 비킨다 (배너 높이 몫은 .app padding과 같은 기준) */
body.has-a2hs .toast { bottom: calc(196px + env(safe-area-inset-bottom)); }
/* 넓은 화면은 좌측 레일(248px)만큼 콘텐츠 기둥이 밀려 있다 — 토스트도 기둥 중앙으로 */
@media (min-width: 900px) { .toast { left: calc(50% + 124px); } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, 8px); } }

/* ── 홈 화면 추가 안내 ────────────────────────────────────── */
.a2hs {
  position: fixed; left: 12px; right: 12px; z-index: 25;
  bottom: calc(74px + env(safe-area-inset-bottom));
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow); padding: 14px 16px;
}
.a2hs p { margin: 0; font-size: 14px; line-height: 1.55; }
.a2hs-how { margin-top: 6px !important; font-size: 13px !important; color: var(--muted); }
.a2hs-x {
  position: absolute; top: 10px; right: 10px; width: 28px; height: 28px;
  border: 0; border-radius: 50%; background: var(--surface-2);
  color: var(--muted); font-size: 15px; cursor: pointer;
}


/* ── 넓은 화면: 레일 + 이야기 펼침 ─────────────────────────── */
@media (min-width: 900px) {
  /* ── 하단 탭바를 좌측 레일로 ──
     앱 소개 페이지 대신 레일 하단에 '홈 화면 추가 QR'을 둔다. 데스크톱에서
     "브라우저 메뉴 → 홈 화면에 추가"는 틀린 안내라 모바일 배너는 여기서 숨긴다 */
  /* ★ 레일 공간은 body가 잡고, .app은 남은 영역에서 가운데 정렬을 유지한다.
     .app에 margin-left를 주면 레일에 딱 붙어 왼쪽 정렬이 된다 (실제로 그렇게 깨졌다) */
  body { padding-left: 248px; }
  .app { max-width: 900px; padding-bottom: 40px; }
  body.has-a2hs .app { padding-bottom: 40px; }
  .a2hs { display: none; }
  .tabbar {
    top: 0; bottom: 0; right: auto; width: 248px;
    flex-direction: column; justify-content: flex-start; align-items: stretch; gap: 2px;
    padding: 22px 14px calc(14px + env(safe-area-inset-bottom));
    border-top: 0; border-right: 1px solid var(--line);
  }
  .tabbar button {
    flex: 0 0 auto; max-width: none;
    flex-direction: row; justify-content: flex-start; gap: 12px;
    padding: 11px 14px; border-radius: 12px; font-size: 14.5px;
  }
  .tabbar button svg { width: 20px; height: 20px; }
  .tabbar button.on { background: var(--surface-2); }
  .rail-brand {
    display: flex; align-items: center; gap: 10px;
    padding: 4px 14px 20px; color: var(--ink);
  }
  .rail-brand img { border-radius: 9px; }
  .rail-brand b { font-size: 14.5px; letter-spacing: -.02em; }
  .rail-foot {
    display: block; margin-top: auto; padding: 16px 14px 4px;
    border-top: 1px solid var(--line);
  }
  .rail-foot img { display: block; border-radius: 8px; }
  .rail-foot p { margin: 9px 0 0; font-size: 11px; line-height: 1.55; color: var(--muted); }

  /* ── 헤더 ── */
  .head { padding: 2px 2px 26px; }
  .head-title { font-size: 34px; }

  /* ── 홈: 이야기까지 펼쳐서 (나란히 놓는 건 더 넓어진 다음) ── */
  .friends { gap: 22px; }
  .friend-wrap {
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--r-lg); box-shadow: var(--shadow); overflow: hidden;
  }
  /* 이야기가 이미 카드 안에 있으므로 상세로 넘어갈 이유가 없다 (JS도 이 폭에서 이동을 막는다) */
  .go-chip { display: none; }   /* 탭 대상이 아닌 곳에 '들어가기' 신호를 달면 거짓말이다 */
  .friend {
    grid-template-columns: 150px 1fr; gap: 22px; padding: 26px 26px 20px;
    background: transparent; border: 0; border-radius: 0; box-shadow: none; cursor: default;
  }
  .friend:active { transform: none; }
  .friend .avatar { width: 150px; height: 150px; }
  /* 물방울은 아바타 박스의 78%다 — 모티프를 박스 모서리에 두면 캐릭터에서 떨어져 뜬다.
     아바타가 커질수록 그 간격이 픽셀로 벌어지므로 단계마다 어깨 위치로 당긴다 */
  .friend .avatar .motif { top: 14px; right: 14px; width: 34px; height: 34px; font-size: 17px; }
  .friend-name b { font-size: 17px; }
  .friend-emotion { font-size: 28px; }
  .friend-phrase { font-size: 16px; }
  .friend-story { display: block; padding: 0 26px 24px; }
  .friend-story .story { font-size: 15px; line-height: 1.72; }
  .friend-story .card-label { margin-top: 4px; }
  .btn-share { width: 100%; margin-top: 18px; height: 42px; font-size: 14px; }
  .story-wait { margin: 0; font-size: 14px; color: var(--muted); }

  .handoff-strip { margin-top: 22px; padding: 18px 22px; }
  .handoff-strip p { font-size: 15px; }

  /* ── 상세: 리사이즈로 들어왔을 때를 위해 가로 히어로로 ── */
  .detail-hero {
    display: grid; grid-template-columns: 200px 1fr; gap: 30px;
    text-align: left; align-items: center; padding: 8px 0 4px;
  }
  .avatar-lg { width: 200px; height: 200px; margin: 0; }
  .detail-emotion { font-size: 40px; }

  .seg { max-width: 330px; }
  .pick-scene .avatar-lg { width: 132px; height: 132px; }
  .pick-scene .motif { top: 6px; right: 6px; width: 30px; height: 30px; font-size: 15px; }
  .cond { max-width: 30em; padding: 20px 24px; }
  .cond p { font-size: 16px; }
  .cond::before {
    left: -8px; top: 50%; margin-top: -7px; border-radius: 0 0 0 4px;
    border-top: 0; border-bottom: 1px solid var(--line);
  }
  .cd .face, .cd .face-void { width: 56px; height: 56px; }
  .cd > b { font-size: 12px; }
  .guess-head .avatar { width: 152px; height: 152px; margin: -12px -12px -14px -10px; }
  .guess-head .motif { top: 19px; right: 28px; width: 40px; height: 40px; font-size: 20px; }
  .guess-title { font-size: 20px; }
}

/* ── 2단은 여기서부터 ──────────────────────────────────────────
   레일 248px를 빼고 카드 하나에 420px는 줘야 아바타(128)+본문이 눌리지 않는다.
   1024에서 2단을 켰더니 "미장 / 씨 · S&P500 /  8/12"로 줄이 깨졌다. */
@media (min-width: 1180px) {
  .friends { display: grid; grid-template-columns: 1fr 1fr; align-items: start; }
  /* 세로로 남는 공간을 캐릭터에게 준다 — 가로 배치에서는 아바타가 카드 폭의 3분의 1에
     묶이지만, 세로로 세우면 주인공이 된다. 본문(이야기)은 계속 왼쪽 정렬이다 */
  .friend {
    grid-template-columns: 1fr; justify-items: center; text-align: center;
    gap: 12px; padding: 30px 26px 22px;
  }
  .friend .avatar { width: 208px; height: 208px; }
  .friend .avatar .motif { top: 22px; right: 22px; width: 42px; height: 42px; font-size: 21px; }
  .friend-name { justify-content: center; }
  .friend-name b { font-size: 18px; }
  .friend-emotion { font-size: 36px; margin: 4px 0 6px; }
  .friend-phrase { font-size: 17px; margin-bottom: 14px; }
  .ret { font-size: 22px; }
  /* justify-items:center는 자식을 '내용 크기'로 줄인다 — 텍스트 블록이 자기 안의
     가장 긴 줄(문구)에 맞춰지면서 카드마다 폭이 달라졌다. 폭을 카드에 고정한다 */
  .friend-info { width: 100%; }
  /* 일간·주간을 나란히 — 카드가 캐릭터당 두 장뿐이라 세로 길이가 절반이 된다 */
  .guess-cols { grid-template-columns: 1fr 1fr; gap: 22px; align-items: start; }
  /* 균일 높이는 **격자**의 속성이다. 1열에서는 카드마다 빈 공간만 사므로 여기서만 건다 */
  .guess { min-height: 500px; }
  /* 두 달을 나란히 — 오른쪽을 설명으로 채우지 않고 달력이 다 쓴다 */
  .months { grid-template-columns: 1fr 1fr; gap: 30px 34px; }
  }

/* 아주 넓은 화면에서도 본문이 계속 늘어나면 한 줄이 너무 길어진다 */
@media (min-width: 1500px) {
  .app { max-width: 1120px; }
}
