/* 서브셋 웹폰트. 기기 글꼴에 기대면 iOS와 안드로이드가 서로 달라지므로 직접 포함한다.
   원본·라이선스·재생성 방법은 assets/fonts/OFL.txt 참고. */
@font-face {
  font-family: "Gaegu";
  src: url("./assets/fonts/gaegu-subset.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "GowunDodum";
  src: url("./assets/fonts/gowundodum-subset.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
/* ============================================================================
   글자 크기 — 크기를 바꾸고 싶으면 여기 숫자만 고치면 된다.
   왼쪽 이름은 content.js 의 항목 이름과 짝이 맞는다.

   clamp(A, B, C) 는 "작은 화면에선 A, 큰 화면에선 C, 그 사이는 화면 폭 비례"
   라는 뜻이다. 그냥 26px 처럼 숫자 하나로 바꿔 써도 된다.

   고치고 나면 브라우저에서 Ctrl+Shift+R (강력 새로고침) 을 해야 보인다.
   문구(content.js)와 달리 이 파일은 캐시되기 때문이다.
   ========================================================================== */
:root {
  --size-title:        clamp(33px, 9.2vw, 46px);  /* candle.message         첫 화면 큰 제목 */
  --size-subtitle:     18px;                      /* candle.subtitle        제목 아래 안내 */
  --size-success:      clamp(34px, 11.5vw, 34px); /* candle.successMessage  촛불 끈 직후 큰 글씨 */
  --size-success-sub:  36px;                      /* candle.successSubtitle 그 아래 한 줄 */
  --size-continue:     25px;                      /* candle.continueMessage 내려가라는 안내 */
  --size-scroll-hint:  14px;                      /* scrollHint             화살표 옆 글씨 */

  --size-eyebrow:      15px;                      /* memoriesEyebrow, candle.eyebrow  제목 위 작은 글씨 */
  --size-section:      28px;                      /* memoriesTitle          사진 섹션 제목 */
  --size-photo:        26px;                      /* memories[].message     사진 아래 한 줄 */
  --size-note:         17px;                      /* memories[].note        사진 사이 글귀 */
  --size-date:         18px;                      /* memories[].date        사진 위 날짜 */

  --size-letter:       22px;                      /* letter[]               편지 본문 */
  --size-signature:    18px;                      /* letterSignature        편지 서명 */

  --size-gift-title:   27px;                      /* gift.title             선물 제목 */
  --size-gift-message: clamp(21px, 7.2vw, 26px);  /* gift.message           선물 문구 */
  --size-closing:      17px;                      /* gift.closingMessage    선물 아래 마무리 */
  --size-footer:       15px;                      /* footerMessage          페이지 맨 끝 */

  /* 아래는 버튼과 안내 문구. 손글씨가 아니라 고딕으로 나온다. */
  --size-guide:        17px;                      /* readyMessage 등 마이크·터치 안내 */
  --size-button:       13px;                      /* 촛불 화면의 작은 버튼들 */
  --size-gift-button:  15px;                      /* gift.buttonText        열어보기 버튼 */
}

:root {
  --night: #101623;
  --candle: #F0B45C;
  --glow: #FFD79A;
  --paper: #F8F6F2;
  --ink: #131518;
  --ink-soft: #51545B;
  /* 사진 사이 글귀 전용. 본문보다 살짝 연하다. 더 연하게 하려면 #41444C,
     더 진하게 하려면 #26282E. #6B6F78 보다 연해지면 작은 글씨가 흐려진다. */
  --ink-note: #33363D;
  --accent: #C2703F;
  /* 서브셋(KS X 1001 2350자) 밖의 글자와 이모지는 뒤쪽 시스템 글꼴이 받는다. */
  --font-ui: "GowunDodum", -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Malgun Gothic", sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
  /* 편지 글꼴(손글씨). 제목·편지·사진 문구 등 읽는 글에 쓴다. 여기서 한 번에 바꾼다. */
  --font-letter: "Gaegu", "Apple SD Gothic Neo", "Malgun Gothic", sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
  color-scheme: only light;
  font-family: var(--font-ui);
  background: var(--night);
  color: var(--ink);
  -webkit-text-size-adjust: 100%;
}
* { box-sizing: border-box; }
html { overscroll-behavior: none; }
/* content.js 의 문구가 들어가기 전에는 제목을 감춘다. index.html 의 임시
   제목이 잠깐 보였다 바뀌는 것을 막는다. 자리는 그대로 두어 밀리지 않는다. */
body.is-booting .stage-message, body.is-booting .candle-actions { visibility: hidden; }
body { margin: 0; background: var(--night); overscroll-behavior: none; transition: background-color 1.1s ease; isolation: isolate; }
/* 장식은 화면 뒤에 고정해 긴 페이지에서도 질감이 일정하게 이어진다. */
body::before, body::after { content: ""; position: fixed; inset: 0; z-index: 0; pointer-events: none; transition: opacity 1.1s ease; }
body::before {
  background:
    radial-gradient(circle at 12% 16%, rgba(255,215,154,.72) 0 1px, transparent 2px),
    radial-gradient(circle at 79% 12%, rgba(248,246,242,.6) 0 1px, transparent 2px),
    radial-gradient(circle at 88% 31%, rgba(255,215,154,.58) 0 1.5px, transparent 3px),
    radial-gradient(circle at 20% 39%, rgba(248,246,242,.38) 0 .8px, transparent 1.8px),
    radial-gradient(circle at 64% 23%, rgba(248,246,242,.36) 0 .7px, transparent 1.7px),
    radial-gradient(circle at 8% 68%, rgba(255,215,154,.5) 0 1px, transparent 2px),
    radial-gradient(circle at 92% 76%, rgba(248,246,242,.4) 0 .8px, transparent 2px),
    radial-gradient(circle at 26% 86%, rgba(255,215,154,.6) 0 1px, transparent 2.2px),
    radial-gradient(circle at 72% 92%, rgba(248,246,242,.42) 0 .8px, transparent 1.8px),
    radial-gradient(ellipse at 0% 5%, rgba(104,146,171,.28), transparent 48%),
    radial-gradient(ellipse at 100% 94%, rgba(194,112,63,.24), transparent 48%),
    radial-gradient(ellipse at 50% 48%, rgba(240,180,92,.08), transparent 42%);
}
body::after {
  opacity: 0;
  background:
    radial-gradient(circle at 105% -2%, transparent 0 170px, rgba(194,112,63,.09) 171px 172px, transparent 173px 196px, rgba(194,112,63,.05) 197px 198px, transparent 199px),
    radial-gradient(ellipse at 100% 0%, rgba(240,180,92,.18), transparent 48%),
    radial-gradient(ellipse at 0% 70%, rgba(134,155,151,.14), transparent 45%),
    radial-gradient(ellipse at 100% 100%, rgba(194,112,63,.08), transparent 40%),
    repeating-linear-gradient(115deg, rgba(93,73,52,.018) 0 1px, transparent 1px 5px);
}
#page { position: relative; z-index: 1; }
body.candle-pending { position: fixed; inset: 0; overflow: hidden; }
body.candle-pending #page { height: 100%; }
body.is-open { background: var(--paper); }
body.is-open::before { opacity: 0; }
body.is-open::after { opacity: 1; }
body.sheet-open { overflow: hidden; }
[hidden] { display: none !important; }
/* 문구를 비우거나 지우면 그 자리도 함께 사라진다. 빈 요소의 여백만 남아
   설명 없는 틈이 생기는 것을 막는다. content.js 에서 값을 지우기만 하면 된다. */
#candle-eyebrow:empty, #memories-eyebrow:empty, #memories-title:empty,
#letter-title:empty, #letter-signature:empty, #closing-message:empty,
#footer-message:empty, #continue-note:empty, #gift-title:empty,
.photo-message:empty, .memory-note:empty, .photo-date:empty { display: none; }
/* 부제는 모드가 바뀔 때 흔들리지 않도록 높이를 잡아두지만, 아예 비면 접는다. */
.stage-subtitle:empty { min-height: 0; margin-top: 0; }
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
button, input { font: inherit; }
button { cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
button:disabled { cursor: default; }
button, a, input { outline-offset: 5px; }
button:focus-visible, a:focus-visible, input:focus-visible, .sheet:focus-visible { outline: 2px solid var(--accent); outline-offset: 5px; }
button { -webkit-appearance: none; appearance: none; }
p, h1, h2, figure { margin: 0; }
h1, h2 { font-weight: 500; word-break: keep-all; overflow-wrap: break-word; }
p { word-break: keep-all; overflow-wrap: break-word; }
.eyebrow { font-family: var(--font-ui); font-size: var(--size-eyebrow); font-weight: 400; letter-spacing: .2em; line-height: 1.8; }
.utilities { position: absolute; top: 0; left: 0; right: 0; z-index: 5; display: flex; justify-content: flex-end; gap: 8px; padding: 12px 18px; padding: calc(12px + env(safe-area-inset-top, 0px)) max(18px, env(safe-area-inset-right, 0px)) 12px max(18px, env(safe-area-inset-left, 0px)); }
.utility-button { min-height: 44px; border: 1px solid rgba(248,246,242,.2); border-radius: 30px; padding: 0 14px; background: rgba(16,22,35,.8); color: var(--paper); font-size: 11px; }
.is-open .utility-button { background: var(--paper); color: var(--ink-soft); border-color: #dfdad2; }
.candle-stage { position: relative; min-height: 100vh; min-height: 100svh; min-height: 100dvh; padding: 82px 24px 70px; padding: calc(82px + env(safe-area-inset-top, 0px)) max(24px, env(safe-area-inset-right, 0px)) calc(70px + env(safe-area-inset-bottom, 0px)) max(24px, env(safe-area-inset-left, 0px)); display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; color: var(--paper); transition: color 1.1s ease; }
.candle-pending .candle-stage { height: 100%; overflow-x: hidden; overflow-y: auto; }
.candle-stage > .eyebrow { color: #b7aa94; margin-bottom: 34px; }
.stage-message { z-index: 1; }
/* 제목 타이핑. DOM 은 한 번에 만들고 글자마다 animation-delay 만 다르게 준다.
   그래서 글자가 늘어나도 줄바꿈이 흔들리지 않는다. */
.type-word { white-space: nowrap; }
.type-char { display: inline-block; opacity: 0; transform: translateY(.16em); animation: type-in .34s cubic-bezier(.2,.72,.3,1) both; }
/* 애니메이션이 취소된 채 인트로가 끝나도 글자가 사라지지 않게 완성 상태를 못박는다. */
.is-typed .type-char { opacity: 1; transform: none; animation: none; }
/* 다 써지기 전에는 아래 안내와 버튼을 감추고 촛불도 못 누르게 한다. */
.stage-subtitle, .candle-actions { transition: opacity .55s ease .15s; }
.is-typing .stage-subtitle, .is-typing .candle-actions { opacity: 0; pointer-events: none; }
.is-typing .cake-button { pointer-events: none; }
h1 { font-family: var(--font-letter); font-size: var(--size-title); font-weight: 400; line-height: 1.7; letter-spacing: .01em; white-space: pre-line; }
/* 촛불이 꺼지면 부제 글자가 커진다. 자리를 큰 쪽에 맞춰 두어야 칸이 자라면서
   위에 있는 케이크를 밀어내지 않는다. */
.stage-subtitle { min-height: 62px; color: #c8c9d0; margin-top: 14px; font-family: var(--font-letter); font-size: var(--size-subtitle); line-height: 1.95; letter-spacing: .01em; white-space: pre-line; }
.cake-button { position: relative; display: block; width: 256px; height: 236px; max-width: 100%; margin: 16px 0 0; border: 0; border-radius: 24px; background: transparent; flex-shrink: 0; }
.cake-art { display: block; position: relative; width: 200px; max-width: 100%; aspect-ratio: 843 / 878; margin: 26px auto 0; }
@supports not (aspect-ratio: 1 / 1) { .cake-art { height: 208px; } }
.candle-halo { position: absolute; width: 210px; height: 200px; left: -5px; top: -46px; background: radial-gradient(ellipse, rgba(240,180,92,.23), transparent 68%); transition: opacity .8s; pointer-events: none; }
.cake-art { isolation: isolate; }
/* 케이크 본체는 그림 파일이다. 심지 끝이 그림의 (50.2%, 0.1%) 지점이라
   아래 불꽃/연기 좌표를 그 자리에 맞춰 두었다. 그림을 바꾸면 이 값도 함께 고친다.
   그림을 자를 때 알파가 1~10 인 투명 여백까지 내용으로 세면 케이크가 한쪽으로
   밀린다. design/fonts 가 아니라 이 값이 기준이므로 바꾸면 검증도 함께 고친다. */
.cake-photo { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
/* 그림을 끝내 못 받았을 때. 촛불 화면이 텅 비지 않도록 같은 자리에 케이크를 그린다.
   불꽃 좌표는 그대로 두므로 초도 함께 그려야 불꽃이 허공에 뜨지 않는다.
   ::before 가 초, ::after 가 케이크다. */
.cake-art.is-fallback .cake-photo { display: none; }
.cake-art.is-fallback::before { content: ""; position: absolute; left: 50.2%; width: 3.6%; margin-left: -1.8%; top: 1%; height: 45%; border-radius: 40%/2%; background: repeating-linear-gradient(150deg, #f4d9a8 0 6px, #e8bd78 6px 12px); }
.cake-art.is-fallback::after { content: ""; position: absolute; left: 6%; right: 6%; top: 46%; bottom: 7%; border-radius: 10% 10% 22% 22% / 16% 16% 34% 34%; background: linear-gradient(168deg, #fdf8ee, #f3e7d3 58%, #e4d4bb); box-shadow: inset 0 7px 16px rgba(255,255,255,.5), 0 6px 14px rgba(0,0,0,.18); }
.flame { position: absolute; z-index: 2; width: 4.5%; height: 10.1%; left: 50.2%; margin-left: -2.25%; top: -8.65%; border-radius: 50% 50% 46% 46% / 68% 68% 32% 32%; transform-origin: 50% 100%; background: radial-gradient(ellipse at 50% 75%,#fff7df 0 20%,#ffd79a 45%,#f0b45c 75%); box-shadow: 0 0 13px 4px rgba(255,215,154,.4); animation: flicker 1.5s ease-in-out infinite; transition: opacity .45s ease; }
/* 불꽃은 본체·심지불빛 두 겹이 서로 다른 주기로 움직인다. 주기가 어긋나야 반복되는 티가 안 난다. */
.flame::after { content: ""; position: absolute; left: 50%; bottom: 2px; width: 4px; height: 9px; margin-left: -2px; border-radius: 60% 60% 50% 50%; background: radial-gradient(ellipse at 50% 70%, #fffdf4 0 45%, rgba(255,246,214,.3) 100%); transform-origin: 50% 100%; animation: flame-core 1.1s ease-in-out infinite; }
.smoke { position: absolute; z-index: 2; width: 5.5%; height: 12.5%; left: 50.2%; margin-left: -2.75%; top: -7.7%; opacity: 0; border-left: 2px solid rgba(236,230,219,.35); border-radius: 50%; pointer-events: none; }
.is-extinguished .flame, .is-extinguished .candle-halo, .is-extinguished .flame::after { opacity: 0; animation: none; }
.is-extinguished .smoke { animation: smoke 1.2s ease-out both; }
.is-open .candle-stage { color: var(--ink); }
.is-open .stage-subtitle, .is-open .candle-stage > .eyebrow { color: var(--ink-soft); }
.is-open .cake-button { opacity: .72; }
/* 권한 안내 상자가 떴다 사라지는 동안 칸 높이가 변하면 위에 있는 케이크가
   따라 움직인다. 가장 큰 상태에 맞춰 자리를 미리 잡아 둔다. */
.candle-actions { display: flex; flex-direction: column; align-items: center; width: 100%; max-width: 300px; min-height: 196px; }
.mic-button, .tap-button { max-width: 100%; border-radius: 6px; line-height: 1.7; }
/* 권한을 자동으로 요청하므로 마이크 버튼은 끄기/재시도용 보조 버튼이다. */
.mic-button { min-height: 44px; padding: 9px 16px; border: 1px solid rgba(255,215,154,.26); background: rgba(240,180,92,.06); color: var(--glow); font-size: var(--size-button); }
.tap-button { min-height: 44px; padding: 9px 16px; border: 1px solid transparent; background: transparent; color: #d3d2d8; font-size: var(--size-button); }
/* 별도 버튼 대신 케이크 자체가 눌러야 할 곳임을 표시한다. */
/* 안내를 강조하는 색이므로 촛불이 꺼진 뒤에는 쓰지 않는다. 밝은 배경에서 거의 보이지 않는다. */
.is-tap-fallback:not(.is-extinguished) .stage-subtitle { color: var(--glow); font-size: 20px; }
.is-celebrating .stage-subtitle { font-size: var(--size-success-sub); }
/* 축하 문구는 크게 보여준다. 촛불이 꺼진 순간이 아니라 문구가 바뀌는 순간에
   적용해야 한다. 먼저 키우면 아직 남아 있는 두 줄짜리 제목이 부풀어 밀린다. */
.is-celebrating h1 { font-size: var(--size-success); }
/* 청취 중에는 안내 > 터치 > 마이크 끄기 순으로 눈에 들어와야 한다. */
.is-mic-active .mic-button { border-color: transparent; background: transparent; color: #938f88; font-size: 11px; }
.is-mic-active .mic-button::before { content: ""; display: inline-block; width: 6px; height: 6px; margin-right: 8px; border-radius: 50%; background: var(--candle); vertical-align: middle; animation: listening 1.8s ease-in-out infinite; }
.mic-status { color: #d3d2d8; max-width: 310px; min-height: 26px; margin: 30px 0 14px; font-size: var(--size-guide); line-height: 1.75; transition: opacity .3s ease; }
.mic-status:empty { min-height: 0; margin: 0; }
/* 권한 안내는 케이크 바로 아래에 둔다. 작은 화면에서도 다른 버튼을 덮지 않는다. */
.is-priming .mic-status, .is-requesting .mic-status { width: 100%; margin: 30px 0 16px; padding: 14px 18px; border: 1px solid #ffe7c0; border-radius: 12px; background: var(--glow); color: #342819; font-size: 20px; font-weight: 600; line-height: 1.6; box-shadow: 0 6px 28px rgba(240,180,92,.2); }
.is-priming .mic-status { font-size: 17px; }
.is-tap-fallback .mic-status { max-width: 100%; }
/* 권한창이 뜨기 직전, 이유를 읽을 수 있도록 안내만 남긴다. */
.is-priming .tap-button { opacity: .45; }
.candle-stage.is-listening .candle-halo { animation: halo 2.6s ease-in-out infinite; }
/* 촛불 화면의 버튼칸(.candle-actions)이 사라진 자리를 그대로 채운다.
   높이가 다르면 본문이 열릴 때 케이크가 한 번 더 밀린다. */
.continue-note { color: var(--ink); font-family: var(--font-letter); font-size: var(--size-continue); min-height: 196px; padding-top: 42px; line-height: 1.8; }
.scroll-hint { position: absolute; bottom: 22px; bottom: calc(22px + env(safe-area-inset-bottom, 0px)); left: 0; right: 0; display: flex; flex-direction: column; align-items: center; color: var(--ink-soft); font-family: var(--font-letter); font-size: var(--size-scroll-hint); letter-spacing: .04em; opacity: 1; transition: opacity .4s; pointer-events: none; }
.scroll-hint.is-faded { opacity: 0; }
.scroll-arrow { display: block; font-size: 24px; line-height: 1.25; animation: scroll-hint 1.6s ease-in-out infinite; }
.story { max-width: 640px; margin: auto; padding: 0 24px; padding-left: max(24px, env(safe-area-inset-left, 0px)); padding-right: max(24px, env(safe-area-inset-right, 0px)); }
.memories { padding-top: 70px; }
.section-heading { text-align: center; margin-bottom: 56px; }
.section-heading .eyebrow { color: var(--accent); margin-bottom: 16px; }
h2 { font-size: var(--size-section); line-height: 1.65; letter-spacing: -.04em; }
.section-heading h2, .gift h2 { font-family: var(--font-letter); font-weight: 400; letter-spacing: .01em; }
.small-rule { display: block; width: 28px; height: 1px; background: #d6c7b7; margin: 26px auto 0; }
/* 기울기는 .photo-frame 에만 준다. .photo-card 의 transform 은 reveal 애니메이션이 쓴다.
   각도가 커지면 가로 스크롤이 생기므로 2도 안팎으로 제한한다. */
.photo-card { width: 78%; max-width: 280px; margin: 0 auto 58px; }
.photo-frame { border: 8px solid #fff; box-shadow: 0 12px 30px rgba(78,52,30,.15); transform: rotate(-1.9deg); }
.photo-card:nth-of-type(even) .photo-frame { transform: rotate(1.7deg); }
.photo-frame { position: relative; aspect-ratio: 4 / 5; border-radius: 3px; overflow: hidden; background: linear-gradient(140deg,#eddbcb,#dcc2ab 55%,#e9d8c6); }
.photo-frame { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.photo-frame::before { content: ""; display: block; padding-top: 125%; }
@supports (aspect-ratio: 4 / 5) { .photo-frame::before { display: none; } }
.photo-card:nth-child(2) .photo-frame { background: linear-gradient(140deg,#dce4e6,#a6bac7,#d8d7d0); }
.photo-card:nth-child(3) .photo-frame { background: linear-gradient(140deg,#f0dbbf,#dbad94,#e2c5b8); }
.photo-frame img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; pointer-events: none; -webkit-user-drag: none; }
.photo-fallback { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 13px; padding: 25px; color: #554b42; font-size: 13px; text-align: center; line-height: 1.8; }
.photo-fallback::before { content: "♡"; font-size: 28px; }
/* 사진이 좁아졌으므로 캡션도 가운데로 맞춘다. 왼쪽 정렬은 기울어진 사진 밑에서 어긋나 보인다. */
.photo-caption { padding: 20px 4px 0; text-align: center; }
/* 사진 사이에 들어가는 짧은 글. 위쪽 가는 선이 사진과 글의 리듬을 끊어준다. */
.memory-note { max-width: 320px; margin: 0 auto 58px; font-family: var(--font-letter); font-size: var(--size-note); line-height: 2.05; letter-spacing: .015em; text-align: center; color: var(--ink-note); white-space: pre-line; }
.memory-note::before { content: ""; display: block; width: 20px; height: 1px; margin: 0 auto 26px; background: #d9cbba; }
.photo-date { font-size: var(--size-date); letter-spacing: .1em; color: var(--ink-soft); margin-bottom: 9px; }
.photo-message { font-family: var(--font-letter); font-size: var(--size-photo); line-height: 2; letter-spacing: .005em; white-space: pre-line; }
.reveal { opacity: 1; transform: none; }
.reveal.is-waiting { opacity: 0; transform: translateY(18px) scale(.99); }
.reveal.is-visible { opacity: 1; transform: none; transition: opacity .8s ease, transform .8s ease; }
.letter { padding: 32px 8px 56px; text-align: center; }
.letter-mark { display: block; color: var(--accent); font-size: 26px; margin-bottom: 28px; }
.letter h2 { font-family: var(--font-letter); font-size: 22px; font-weight: 400; letter-spacing: .015em; margin-bottom: 38px; }
.letter-body { font-family: var(--font-letter); font-size: var(--size-letter); line-height: 2.2; letter-spacing: .015em; }
.letter-body p { margin-bottom: 26px; white-space: pre-line; }
.letter-signature { font-family: var(--font-letter); font-size: var(--size-signature); letter-spacing: .03em; margin-top: 40px; color: var(--ink-soft); }
.gift { text-align: center; padding: 80px 0 60px; }
.gift h2 { font-size: var(--size-gift-title); margin-bottom: 28px; }
.gift-art { width: 90px; height: 104px; margin: 0 auto 32px; position: relative; }
.gift-box { position: absolute; bottom: 0; left: 9px; right: 9px; height: 56px; border-radius: 0 0 4px 4px; background: linear-gradient(90deg,#dec6aa 43%,#b87750 43% 57%,#dec6aa 57%); }
/* 뚜껑이 날아간 뒤 상자 윗면이 그대로면 납작한 사각형으로만 보인다. 안쪽을 열어 보여준다. */
.gift-box::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 11px; border-radius: 50%; background: #7c5133; opacity: 0; transition: opacity .5s ease .25s; }
.gift-box::after { content: ""; position: absolute; left: 2px; right: 2px; top: 4px; height: 9px; border-radius: 50%; background: linear-gradient(180deg,#f7ead6,#e6cdb0); opacity: 0; transition: opacity .5s ease .3s; }
.gift.is-opened .gift-box::before, .gift.is-opened .gift-box::after { opacity: 1; }
.gift-lid { position: absolute; z-index: 1; left: 4px; right: 4px; bottom: 48px; height: 19px; border-radius: 3px; background: linear-gradient(90deg,#e8d3b8 43%,#c58a62 43% 57%,#e8d3b8 57%); transition: transform .6s ease, opacity .6s; }
.gift-bow { position: absolute; z-index: 2; top: 16px; left: 24px; width: 27px; height: 22px; border: 4px solid #c58a62; border-radius: 60% 70% 0 70%; transform: rotate(10deg); transition: transform .6s ease, opacity .6s; }
.gift-bow::after { content: ""; position: absolute; width: 21px; height: 14px; border: 4px solid #c58a62; border-radius: 70% 60% 70% 0; left: 13px; top: -9px; transform: rotate(-18deg); }
.gift.is-opened .gift-lid { transform: translate(12px,-35px) rotate(12deg); opacity: 0; }
.gift.is-opened .gift-bow { transform: translate(12px,-35px) rotate(22deg); opacity: 0; }
.primary-button { min-height: 48px; border: 1px solid var(--ink); border-radius: 5px; background: var(--ink); color: var(--paper); padding: 13px 34px; font-size: var(--size-gift-button); line-height: 1.5; }
.primary-button:disabled { opacity: .65; }
.gift-result p { color: var(--ink); font-family: var(--font-letter); font-size: var(--size-gift-message); font-weight: 400; line-height: 1.95; letter-spacing: .01em; white-space: pre-line; animation: arrive .7s ease both; }
.closing-message { margin-top: 22px; color: var(--ink-soft); font-family: var(--font-letter); font-size: var(--size-closing); line-height: 2; }
footer { padding: 28px 0 38px; padding-bottom: calc(38px + env(safe-area-inset-bottom, 0px)); text-align: center; color: var(--ink-soft); font-size: 10px; line-height: 1.8; }
footer span { display: block; margin-top: 20px; color: var(--accent); }
footer p { color: var(--ink); font-family: var(--font-letter); font-size: var(--size-footer); line-height: 1.9; }
.confetti { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 10; pointer-events: none; }
.sheet-overlay { position: fixed; z-index: 20; inset: 0; background: rgba(16,22,35,.55); display: flex; align-items: flex-end; justify-content: center; padding-top: max(20px, env(safe-area-inset-top, 0px)); }
.sheet { position: relative; width: 100%; max-width: 540px; max-height: 90vh; max-height: 90dvh; overflow: auto; overscroll-behavior: contain; padding: 28px 28px 24px; padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px)); padding-left: max(28px, env(safe-area-inset-left, 0px)); padding-right: max(28px, env(safe-area-inset-right, 0px)); border-radius: 20px 20px 0 0; background: var(--paper); color: var(--ink); }
.sheet-handle { width: 32px; height: 3px; border-radius: 3px; background: #d3cdc4; margin: -15px auto 25px; }
.sheet-close { position: absolute; right: 10px; top: 17px; min-width: 44px; min-height: 44px; border: 0; background: transparent; color: var(--ink-soft); font-size: 26px; }
.sheet h2 { font-size: 20px; margin: 0 25px 16px 0; }
#sheet-description { white-space: pre-line; font-size: 14px; color: var(--ink-soft); line-height: 1.9; }
#copy-controls { margin-top: 24px; }
#manual-copy { margin-top: 16px; }
#manual-copy label { display: block; font-size: 12px; line-height: 1.8; margin-bottom: 8px; }
#copy-address { width: 100%; border: 1px solid #ccc3b8; border-radius: 4px; background: #fff; color: var(--ink); font-size: 16px; padding: 10px; }
.sheet-status { font-size: 12px; color: var(--ink-soft); line-height: 1.8; margin-top: 14px; }
.noscript { padding: 14px; font-size: 13px; line-height: 1.8; color: var(--glow); }
@keyframes flicker {
  0%   { transform: rotate(-5deg) translateX(-.6px) scale(.93,1.04); box-shadow: 0 0 14px 4px rgba(255,215,154,.26); }
  17%  { transform: rotate(4deg) translateX(.9px) scale(1.06,.94); box-shadow: 0 0 25px 7px rgba(255,215,154,.46); }
  33%  { transform: rotate(-2deg) translateX(-.2px) scale(.96,1.09); box-shadow: 0 0 17px 5px rgba(255,215,154,.32); }
  51%  { transform: rotate(6deg) translateX(1.1px) scale(1.04,.95); box-shadow: 0 0 27px 8px rgba(255,215,154,.5); }
  68%  { transform: rotate(-4deg) translateX(-1px) scale(.94,1.06); box-shadow: 0 0 15px 4px rgba(255,215,154,.28); }
  85%  { transform: rotate(2deg) translateX(.3px) scale(1.05,.98); box-shadow: 0 0 22px 6px rgba(255,215,154,.42); }
  100% { transform: rotate(-5deg) translateX(-.6px) scale(.93,1.04); box-shadow: 0 0 14px 4px rgba(255,215,154,.26); }
}
@keyframes flame-core { 0%,100% { opacity: .95; transform: scaleY(1) scaleX(1); } 38% { opacity: .55; transform: scaleY(.78) scaleX(1.12); } 71% { opacity: 1; transform: scaleY(1.15) scaleX(.9); } }
@keyframes smoke { 0% { opacity: 0; transform: translateY(0) scale(.7); } 25% { opacity: .6; } 100% { opacity: 0; transform: translate(8px,-34px) scale(1.4); } }
@keyframes scroll-hint { 0%,100% { transform: translateY(0); } 50% { transform: translateY(5px); } }
@keyframes listening { 0%,100% { opacity: 1; } 50% { opacity: .25; } }
@keyframes halo { 0%,100% { opacity: 1; } 50% { opacity: .5; } }
@keyframes arrive { from { opacity: 0; } to { opacity: 1; } }
@keyframes type-in { to { opacity: 1; transform: none; } }
/* 넓은 화면에서는 여백만 넓힌다. 글자 크기를 여기서 따로 정하면 맨 위 크기표와
   어긋나, 폰에서는 맞던 크기 관계가 넓은 화면에서만 뒤집힌다. */
@media (min-width: 700px) { .story { padding-inline: 36px; } .photo-card { max-width: 320px; margin-bottom: 78px; } .memory-note { margin-bottom: 78px; } .letter { padding-top: 60px; } }
@media (max-height: 650px) { .candle-stage { padding-top: calc(68px + env(safe-area-inset-top, 0px)); padding-bottom: calc(55px + env(safe-area-inset-bottom, 0px)); justify-content: flex-start; } .candle-stage > .eyebrow { margin-bottom: 15px; } .cake-button { height: 170px; margin: 0; } .cake-art { transform: scale(.78); transform-origin: 50% 0; } .stage-subtitle { margin-top: 6px; } .candle-actions { min-height: 128px; } h1 { font-size: 32px; } }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; } .reveal.is-waiting { opacity: 1; transform: none; } .confetti { display: none; } }
