/* Components — Harry Potter 특별전
   출처: Figma HarryPotter_UI 컴포넌트 시트 (components.md와 1:1 대응)
   tokens.css를 먼저 로드할 것. 색상은 토큰만 사용 — 비토큰 값은 ⚠️ 주석으로 표기(Figma 원본값). */

/* ⚠️ 2026-10-07: Button(구 1140:25470 · .btn/.btn--popup QR 시뮬레이션 데모) · ResultButton(1168:38149) ·
   ResultCard(1168:37955) · ResultContent(1173:9833) · InputField 밑줄형(1173:10152)은 실사용 0건이라 삭제 —
   쓰던 옛 결과 카드(app.js qrCardHtml · resultCardHtml)가 도달할 수 없는 분기였다. */

/* ============ Field (알약 입력) — Figma "Field" 3085:5578/5579/5585 (Empty/Focus/Filled) ============
   온보딩 이메일 · 인증 코드 · 닉네임이 쓴다(앱 쪽 크기 · 색 덮어쓰기는 app.css .form-row .input-field--pill).
   2026-10-07: 밑줄형 기본 규칙(.input-field · .input-field__control)을 지우면서, 알약형이 거기서 물려받던
   배치 · 글꼴 · 색을 여기로 옮겼다 — 이름은 마크업 그대로 두고 모양은 --pill 이 전부 정한다.
   <div class="input-field input-field--pill"><input class="input-field__control"></div> */
.input-field--pill {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 335px;
  /* 보더는 칸(<input>)이 아니라 이 틀의 고리(아래 「고리 테두리」)가 그린다 — <input> 에는 가상 요소를 못 단다 */
  position: relative;
  border-radius: var(--radius-full);
  --ring: linear-gradient(#4c4968, #4c4968); /* ⚠️ non-token: Figma Field Empty 보더 */
}
.input-field--pill .input-field__control {
  width: 100%;
  padding: 12px 10px;
  border: 1px solid transparent;   /* 두께만 — 색은 틀의 고리 */
  border-radius: var(--radius-full);
  background: rgba(20, 27, 30, 0.4); /* ⚠️ non-token: Figma Field 표면 */
  /* base/body1/M-16 (Figma 3085-5557/5560/5563) */
  font-family: var(--font-base);
  font-weight: 500;
  font-size: 16px;
  line-height: 1.5;
  letter-spacing: 0.005em;
  text-align: center;
  color: var(--text-primary);
  outline: none;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
/* 피그마 플레이스홀더는 흰색 54% → purple 계열로 흐르는 클립텍스트다.
   ::placeholder에는 그라디언트를 입힐 수 없어 중간값 한 색으로 근사했다. */
.input-field--pill .input-field__control::placeholder { color: rgba(255, 255, 255, 0.44); }
.input-field--pill:focus-within,
.input-field--pill.is-filled { --ring: var(--paint-ice-200); }   /* 보더 text/accent(ice/200) — 2026-10-06 네이비(전: purple_300) */
.input-field--pill .input-field__control:focus,
.input-field--pill.is-filled .input-field__control {
  box-shadow: 0 0 6px 0 color-mix(in srgb, var(--text-accent) 45%, transparent);   /* 보더와 같은 색 @ 45% */
}

/* ============ Header (상단 바) — 1178:10982 ============
   ⚠️ 2026-08-25: header--content·header--test는 실사용 0건이라 삭제.
   ⚠️ 2026-10-07: header__logo-row·__logo(전체보기 화면 삭제)·__wordmark·__actions(홈 헤더가 마름모 하나로)·
      __title·__trailing-row·__icon--28(학생증 화면 삭제)도 실사용 0건이라 삭제.
   header--acset(계정설정)은 여기 없고 app.css에 있다 — 실사용 헤더 변형이 이제
   login·home·acset 3개 + 결과 화면 전용 .hreveal__header로 나뉘어 있다는 뜻이다
   (피그마 새 Header 컴포넌트의 default/onboarding/home/setting/result 5variant와 매핑:
   onboarding→header--login, setting→header--acset, result→.hreveal__header). */
.header {
  display: flex;
  align-items: center;
  width: 375px;
  box-sizing: border-box;
}
.header--login {
  justify-content: space-between;
  padding: 4px 20px;
  overflow: hidden;
}
/* home — Figma Header(home) 3923:16539 (2026-09-16 홈 리프레시 · 2026-10-06 네이비).
   지금은 마름모 버튼 하나(계정관리 모자)만 선다 — 오른쪽 정렬 · 여백은 app.css .header--home 이 덮는다.
   마름모 svg 는 37.477 정사각형이라 -45° 돌려 53 칸 한가운데에 둔다. */
.header--home {
  justify-content: space-between;
  padding: 2px 20px;
}
.header__diamond {
  display: grid;
  place-items: center;
  width: 53px;
  height: 53px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.header__diamond img {
  display: block;
  width: 37.477px;
  height: 37.477px;
  transform: rotate(-45deg);
  transition: transform 0.16s ease;
}
.header__diamond:active img { transform: rotate(-45deg) scale(0.92); }
.header__icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  padding: 0;
  color: var(--text-primary);
  cursor: pointer;
}
.header__icon--24 { width: 24px; height: 24px; }

/* ⚠️ 2026-08-25: ProgressBar(1178:10791)·ProgressSummary(1178:10860)는 실사용 0건이라 삭제. */
/* ⚠️ 2026-10-07: IconCircleButton(2270:4859)·SealingWax(3883:22813)·Q1~Q3Select(3938:29991·3091:7693·3102:21447)도
   실사용 0건이라 삭제 — 학생증 삭제 · 사전 테스트 폐지(10-03)로 쓰던 화면이 없어졌다. Toggle(2991:20946)은 09-16 에 이미 삭제. */

/* ══════════════════════════════════════════════════════════════════════
   2026-08-25 신규 — Figma "component" 시트(3085:5553) 최신화분.
   출처: https://www.figma.com/design/T6atU6SmDzk76CfyougYrC/HarryPotter_UI?node-id=3085-5553
   ══════════════════════════════════════════════════════════════════════ */

/* ============ Logo — 3102:22511 ============
   스플래시 · 로그인(.splash-logo 234×100)과 홈(.home-logo 200×85)이 같은 그림(assets/home/logo-hp-gold.webp, 702×299)을
   크기만 바꿔 쓴다 — 클래스는 쓰는 화면(app.css)에 있다. 새 크기가 필요해도 새 이미지를 따로 만들지 않는다. */


/* ============ Button — 3938:14271 (component set · 2026-09-17 최신화 · primary/disabled 2026-10-06 네이비) ============
   ⚠️ 옛 .btn-pill-glow 를 흡수했다. variant 는 일곱이고 **둘로 갈린다**:

     primary / disabled — 폭 335 · 네 변 2px ice/200(#C2E2FF) 보더 · 완전 알약 · 글로우 178×56(시안 svg) ·
       라벨 navy_700 → black. 공유 버튼이 없는 화면(스플래시·온보딩·계정·동의)이 쓴다.
       2026-10-06 네이비로 바뀌었다(전: blue_100 보더 · 보라 글로우 · purple_700 라벨).
     blue / red / green / yellow / gray — 폭 273 · **아래 변 4px + 40% 투명** ·
       라운드 999/40/160/999 · 글로우 249. **공유 버튼(.btn-share, 50)과 한 줄로 묶어 쓴다**
       (50 + 12 + 273 = 335 로 primary 와 같은 폭이 된다). 결과 화면이 쓴다.

   ⚠️ 라운드는 시안값(999/40/160/999)을 그대로 쓸 수 없다 — CSS 는 한 변의 라운드 합이 그 변보다
      크면 네 모서리를 같은 비율로 한꺼번에 줄인다. 왼쪽 변이 1998 인데 높이가 55 라 비율이
      0.0275 까지 떨어져 오른쪽이 1px·4px 로 뭉개진다. Figma 는 모서리마다 따로 깎는다.
      그래서 시안 렌더 윤곽을 재서 얻은 실제 값(27.5 / 11 / 44 / 27.5)을 넣는다.
   ⚠️ 글로우 색은 보더색과 **따로다**(green 보더 rgba(7,97,14,.4) ↔ 글로우 #28AB3C). export 실측값이다.

   <button class="btn-cta"><span class="btn-cta__label">다음</span></button>
   <button class="btn-cta btn-cta--green"><span class="btn-cta__label">저장하기</span></button> */
.btn-cta {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  box-sizing: border-box;
  max-width: 100%;
  overflow: hidden;
  /* 면 gray_100 · 보더 2px ice/200(시안은 변수 없이 #C2E2FF — 같은 값인 원색). 2026-10-27 색 대신 단색 그림으로 칠한다 —
     삼성 인터넷 강제 다크 모드가 밝은 CSS 바탕 · 보더를 어둡게 바꿔 버튼이 바탕에 묻혔다(UT 10-27 · tokens.css --paint-*).
     보더 칸은 투명하게 두고 그 아래로 ice 그림(border-box)을, 안쪽에 gray 그림(padding-box)을 깐다 — 둥근 모서리를 따른다. */
  background: var(--paint-gray-100) padding-box, var(--paint-ice-200) border-box;
  cursor: pointer;
  /* primary 가 기본 모양이다 — 색 variant 가 아래에서 덮어쓴다 */
  width: 335px;
  /* 시안은 오른쪽 안쪽 여백만 10 이라 라벨이 5 왼쪽에 앉는다(글로우도 −5.5) — 그대로 둔다 */
  padding: 12px 10px 12px 0;
  border: 2px solid transparent;
  border-radius: var(--radius-full);
}
/* 글로우 — 시안 svg(Ellipse 1582: slate #9DAFC8 60% · 번짐 20). 타원 178 × 56 을 블러 여백 40 씩 품어 258 × 136.
   버튼이 overflow:hidden 이라 타원의 위쪽 일부만 보인다(시안과 같다) */
.btn-cta::before {
  content: "";
  position: absolute;
  left: calc(50% - 5.5px);
  top: -18px;                 /* 시안 타원 top 22 − 블러 여백 40 */
  width: 258px;
  height: 136px;
  transform: translateX(-50%);
  background: url('../assets/shared/btn-glow-primary.svg') center / 100% 100% no-repeat;
  pointer-events: none;
}
/* 라벨 — 시안은 navy_700 → black 세로 그라디언트를 글자에 클립한다(색 variant 는 아래에서 purple_700 으로).
   버튼 면색(gray_100)과 같은 요소에는 못 걸어서 라벨을 따로 둔다.
   어두운 그라디언트는 삼성 인터넷 강제 다크 모드에서도 그대로라 면(단색 그림)과 함께 시안대로 남는다 —
   단색 글자로 바꾸면 안 된다(어두운 단색 글자는 밝게 뒤집혀 밝은 면 위에서 사라진다). */
.btn-cta__label {
  position: relative;
  background-image: linear-gradient(180deg, var(--navy-700) 0%, #000 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-family: var(--font-base);
  font-weight: 500;
  font-size: 18px;
  line-height: 1.5;
  letter-spacing: 0.09px;
  white-space: nowrap;
}
.btn-cta:active { transform: translateY(1px); }
.btn-cta:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
/* disabled 글로우는 같은 타원을 불투명하게(Ellipse 1581) — 40% 로 흐려진 면 위에서 primary 와 비슷하게 보인다 */
.btn-cta:disabled::before { background-image: url('../assets/shared/btn-glow-disabled.svg'); }
.btn-cta:disabled:active { transform: none; }

/* ── 색 variant — 공유 버튼과 한 줄로 쓰는 쪽 ── */
.btn-cta--blue,
.btn-cta--red,
.btn-cta--green,
.btn-cta--yellow,
.btn-cta--gray {
  width: 273px;
  padding: 12px 40px;
  border: 0;
  border-bottom: 4px solid var(--btn-cta-edge);
  border-radius: 27.5px 11px 44px 27.5px;
  background: var(--paint-gray-100) border-box;   /* 면이 아래 변(반투명) 밑까지 깔린다 — 위 primary 와 같은 그림 */
}
.btn-cta--blue::before,
.btn-cta--red::before,
.btn-cta--green::before,
.btn-cta--yellow::before,
.btn-cta--gray::before {
  top: -155px;
  left: 50%;
  width: 249px;
  height: 249px;
  margin-left: -124.5px;
  transform: none;
  background: radial-gradient(circle,
    var(--btn-cta-glow) 0%,
    color-mix(in srgb, var(--btn-cta-glow) 30%, transparent) 60.35%,
    transparent 100%);
  opacity: 0.4;
  filter: blur(27px);
}
/* 색 variant 의 라벨은 그대로 purple_700 → black (시안 3846-27498 등) */
.btn-cta--blue .btn-cta__label,
.btn-cta--red .btn-cta__label,
.btn-cta--green .btn-cta__label,
.btn-cta--yellow .btn-cta__label,
.btn-cta--gray .btn-cta__label { background-image: linear-gradient(180deg, var(--purple-700) 0%, #000 100%); }
.btn-cta--blue   { --btn-cta-edge: rgba(78, 143, 255, 0.4);  --btn-cta-glow: #2C8EFD; }
.btn-cta--red    { --btn-cta-edge: rgba(255, 108, 108, 0.4); --btn-cta-glow: #FF6565; }
.btn-cta--green  { --btn-cta-edge: rgba(7, 97, 14, 0.4);     --btn-cta-glow: #28AB3C; }
.btn-cta--yellow { --btn-cta-edge: rgba(129, 116, 17, 0.4);  --btn-cta-glow: #D4CC39; }
.btn-cta--gray   { --btn-cta-edge: rgba(53, 58, 130, 0.4);   --btn-cta-glow: #7A7C98; }

/* ============ 결과 머리말 (content/title) ============
   Figma 3102-17762 (component set) · 색 variant 6종. 결과 화면들이 **다 같이 쓴다** —
   완드 lightblue · 그리핀도르 red · 슬리데린 green · 후플푸프 yellow · 래번클로 blue ·
   나머지(gray 포함)는 물약 몫이다.
   + pink — 컴포넌트 variant 가 아니라 물약 시안(2026-10-07 아모텐시아 · 스켈레그로)이 blue 를 분홍으로 덮어쓴
     인스턴스다. 그림(assets/design-system/content-title/pink.svg)만 더했고 짜임새는 다섯과 같아 CSS 가 따로 없다.

   ⚠️ **red 만 컴포넌트 안에서 짜임새가 다르다.** 나머지 다섯은 가로줄까지 한 장(312.496)에
      구워져 있는데, red 는 가운데 장식(33.865)만 그림이고 가로줄은 테두리로 그린다.
      그래서 red 일 때만 줄을 여기서 그린다 — export 가 잘려 나온 게 아니라 원래 그렇다.
   ⚠️ red 의 줄 색 #FEA4A4 는 **6종 중 유일한 실측값**이다. Tailwind export 에 투명한
      테두리(border-b rgba(255,255,255,0))로만 나와서 컴포넌트 렌더의 1px 을 직접 집었다.
      나머지는 제 svg 안에 있다(green #8DFFB1 · blue #C5CCF8 · yellow #FFF5DA ·
      lightblue #99E4FF · gray #3C3E60) — 장식 색에서 유추할 수 없다.

   등장 — 줄이 가운데에서 좌우로 펼쳐진다(완드 결과에서 쓰던 연출이다).
   ⚠️ **닫힌 모습이 기본이다.** 뿌리에 is-in 이 없으면 데코가 접힌 채로 안 보인다 —
      결과 화면들은 이미 그 클래스를 쓰고 있어서(.wres.is-in · .hres.is-in) 새 화면은
      뿌리에 붙이기만 하면 된다.
   <div class="content-title content-title--lightblue">
     <span class="content-title__deco" aria-hidden="true"><img src="…/lightblue.svg" alt=""></span>
     <div class="content-title__text"><p class="content-title__kicker">…</p>
                                      <p class="content-title__name">…</p></div>
   </div> */
.content-title {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: 312.496px;
  max-width: 100%;
}
.content-title__deco {
  position: relative;
  display: flex;
  justify-content: center;
  width: 100%;
  height: 22px;
}
.content-title__deco img { display: block; width: 100%; height: 22px; }
/* red — 장식만 그림이라 폭을 제 크기로 두고 줄을 여기서 그린다(위 ⚠️ 참고) */
.content-title--red .content-title__deco img { width: 33.865px; }
.content-title--red .content-title__deco::after {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 1px;
  /* 시안 linear-gradient(90deg, transparent, #FEA4A4 50%, transparent) 를 단색 + 투명도로 다시 쓴 그림 —
     CSS 그라디언트는 삼성 인터넷 강제 다크 모드에서 어두워진다(tokens.css --paint-* 머리말) */
  background: url('../assets/shared/grad/title-red-rule.svg') 0 0 / 100% 100% no-repeat;
}
.content-title__text {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
}
.content-title__kicker {
  width: 302px;
  margin: 0;
  opacity: 0.7;
  /* accent/body4/R-12 */
  font-family: var(--font-accent);
  font-weight: 400;
  font-size: 12px;
  line-height: 1.5;
  letter-spacing: -0.01em;
  text-align: center;
  color: var(--blue-50);
}
.content-title__name {
  margin: 0;
  /* Nimbus Roman 40 — 2026-10-14 기본값으로(전: HarryBeast/R-36). Harry Beast 를 쓸 수 없게 되면서 결과 화면 넷이
     모두 이 값으로 덮어쓰고 있었다. 시안 행간은 normal 이다. */
  font-family: var(--font-serif-title);
  font-size: 40px;
  line-height: normal;
  letter-spacing: -0.5px;
  /* 줄바꿈은 이름 안의 \n 에서만 한다(살아있는 죽음의 물약 "DRAUGHT OF / LIVING DEATH") — 폭으로는 안 접는다 */
  white-space: pre;
  text-align: center;
  text-transform: none;   /* 대소문자는 문안 그대로 — 결과 이름은 대문자로 적어 둔다 */
  color: var(--white);
}
/* gray — 이름이 위에서 아래로 흐려진다(시안 컴포넌트 3102-17854, 흰색 → rgba(146,138,160,0.6)).
   다른 색 variant 의 이름은 흰색 단색이다. */
.content-title--gray .content-title__name {
  /* 시안 linear-gradient(180deg, #FFFFFF, rgba(146,138,160,.6)) 를 단색 + 투명도로 다시 쓴 그림(강제 다크 대비) */
  background: url('../assets/shared/grad/text-title-gray.svg') 0 0 / 100% 100% no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* 등장 — 줄이 가운데에서 좌우로 펼쳐진다(완드 결과에서 쓰던 연출을 컴포넌트로 옮겼다).
   ⚠️ 뿌리의 is-in 에 걸어 둔다 — 쓰는 화면마다 그 클래스를 이미 쓰고 있어서
      (.wres.is-in · .hres.is-in) 새 화면은 뿌리에 is-in 만 붙이면 그대로 돈다. */
.content-title__deco { clip-path: inset(0 50% 0 50%); }
.is-in .content-title__deco {
  transition: clip-path 1.15s cubic-bezier(0.22, 1, 0.36, 1) 0.1s;
  clip-path: inset(0 0 0 0);
}
@media (prefers-reduced-motion: reduce) {
  .content-title__deco { clip-path: none; }
  .is-in .content-title__deco { transition: none; }
}

/* ============ 저장 줄 (공유 + 저장) ============
   색 variant 버튼은 **공유 버튼과 한 줄로** 쓴다(50 + 12 + 273 = 335 로 primary 와 같은 폭).
   결과 화면들이 같이 쓴다 — 자리(위치·등장 애니메이션)는 쓰는 화면이 정한다.
   <div class="save-row"><button class="btn-share">…</button><button class="btn-cta btn-cta--green">…</button></div> */
.save-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 335px;
  max-width: 100%;
}

/* ============ btn/share — 3893:27308 (2026-09-17 신규) ============
   50 원에 공유 아이콘 하나.
   ⚠️ 시안 트리에는 아이콘에 -scale-y-100 이 걸려 있지만 **CSS 로 뒤집으면 안 된다** — Figma 가
      내보낸 svg 에 그 변환이 이미 구워져 있다(path 가 M12 15V2, 화살표가 위를 향한다).
      한 번 더 뒤집으면 공유가 아니라 내려받기 모양이 된다.
   <button class="btn-share"><img src="assets/shared/icon-share.svg" alt=""></button> */
.btn-share {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 50px;
  height: 50px;
  box-sizing: border-box;
  padding: 12px 16px;
  border: 0;
  border-radius: var(--radius-full);
  /* ⚠️ non-token: 시안 gray_100 20% — 색 대신 단색 그림(밝은 CSS 바탕은 강제 다크에서 어두워진다 · tokens.css --paint-*) */
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='100%25' height='100%25' fill='%23D7D7D7' fill-opacity='0.2'/%3E%3C/svg%3E");
  cursor: pointer;
}
.btn-share img { width: 24px; height: 24px; }
.btn-share:active { transform: scale(0.94); }

/* ============ 홈 콘텐츠 아이콘 레일 (btn) ============
   2026-10-14 app.css 에서 옮겨 왔다 — 홈 한 곳에서만 쓰지만 디자인시스템 페이지에서도 같은 규칙으로 그린다.
   자리(캡션 아래 27)는 쓰는 화면(app.css)이 정한다. */
/* ── btn — 홈 콘텐츠 아이콘 레일 (Figma btn 4981-54884 · 2026-10-14 색 1차 3873-60746) — 6칸 · 폭 49 · 간격 8 · 아래 정렬 ──
   2026-10-14: 꺼진 아이콘 lavender #7A7C98 → 무채색 #63636E, 비활성 필 아래 색 → slate/300, 활성 필 면 → #101121 16% ·
   밑줄 → lavender/600(border/card), 활성 빛 → 하늘빛 #D5E3FF 48%. 같은 날 기숙사 · 물약 · 패트로누스 아이콘 새 그림. */
.home-rail {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 8px;
  flex-shrink: 0;
  width: 335px;
}
.home-rail__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  width: 49px;
  height: 86px;               /* 활성 칸 높이로 고정 — 비활성은 위 여백 14 로 72 칸(필 45 + 아래 16)에 앉는다 */
  padding: 14px 0 0;
  border: 0;
  background: none;
  cursor: pointer;
  /* ⚠️ 높이·display 를 바꾸면 활성 칸이 튀어 오른다 — 위 여백·필 높이·라벨 투명도만 전환해 자연스럽게 올라오게 한다 */
  transition: padding-top 0.28s cubic-bezier(0.2, 0.7, 0.2, 1);
}
/* 비활성 필 — 45px, 위 rgba(8,9,24,.25) → 아래 slate/300 25%, 전체 60% */
.home-rail__pill {
  position: relative;
  display: grid;
  place-items: center;
  width: 49.167px;
  height: 45px;
  border-radius: 20px;
  overflow: hidden;
  background: linear-gradient(180deg, rgba(8, 9, 24, 0.25) 0%, color-mix(in srgb, var(--slate-300) 25%, transparent) 100%); /* ⚠️ non-token(위 색): Figma 비활성 필 */
  border-bottom: 1px solid transparent;
  opacity: 0.6;
  /* 둥근 자르기를 clip-path 로도 건다 — 아이폰 사파리는 필터가 걸린 안쪽 요소(빛)를 overflow 만으로는 둥근 모서리에서
     자르지 못할 때가 있다(2026-10-20 "상단이 깨져 보임"). */
  isolation: isolate;
  clip-path: inset(0 round 20px);
  transition: height 0.28s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.28s ease, background 0.28s ease, border-color 0.28s ease;
}
.home-rail__icon { grid-area: 1 / 1; display: block; width: 32px; height: 32px; transition: opacity 0.2s ease; }
.home-rail__icon--on { opacity: 0; }
/* 활성 필 안의 빛(Figma Vector 788 — 2026-10-14 하늘빛 #D5E3FF 48%, 전: 네이비) — 필 (30, −34) 의 64 × 134 도형 ·
   레이어 블러 20(CSS 10). 필 밖으로 넘치는 만큼 잘린다.
   2026-10-20 svg 그림(<img>, 블러 필터를 품은 104 × 174)에서 CSS 로 바꿨다 — 필터를 품은 svg 를 <img> 로 넣으면 확대된 화면
   (휴대폰)에서 낮은 해상도로 구워져 위쪽이 깨져 보였다(잠금 원 .home-slide__lock-icon 과 같은 까닭).
   도형은 ::before 가 clip-path 로 오리고, 블러는 바깥 상자가 건다(블러가 오린 뒤에 걸리게). */
.home-rail__glow {
  position: absolute;
  top: -34px;
  left: 30px;
  width: 64px;
  height: 134px;
  opacity: 0;
  filter: blur(10px);
  transition: opacity 0.28s ease;
  pointer-events: none;
}
.home-rail__glow::before {
  content: '';
  position: absolute;
  inset: 0;
  /* ⚠️ non-token: Figma Vector 788 #D5E3FF 48% — 색 대신 단색 그림(강제 다크 대비 · tokens.css --paint-*) */
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='100%25' height='100%25' fill='%23D5E3FF' fill-opacity='0.48'/%3E%3C/svg%3E");
  clip-path: path('M6.6462 117.438C68.0862 96.962 29.9487 49.1835 3.2 27.8539L0 3.0112L58.5846 0L64 134H6.6462V117.438Z');
}
/* 라벨 — base/body2/R-14, 흰색 → 금빛 그라디언트 글자. 활성 항목에서 아래에서 떠오른다.
   그라디언트(Figma 197.4°, #FFFEFA 17.8% → #F9E5AF 131.35%)는 단색 + 투명도로 다시 쓴 그림이다 — CSS 그라디언트는
   삼성 인터넷 강제 다크 모드에서 어두워져 라벨이 사라졌다(UT 10-27 · tokens.css --paint-* 머리말) */
.home-rail__label {
  font-family: var(--font-base);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: 0.01em;
  white-space: nowrap;
  background: url('../assets/shared/grad/text-rail-label.svg') 0 0 / 100% 100% no-repeat; /* ⚠️ non-token: Figma 라벨 그라디언트 */
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.28s ease, transform 0.28s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.home-rail__item:active .home-rail__pill { transform: scale(0.94); }
.home-rail__item.is-active { padding-top: 0; }
.home-rail__item.is-active .home-rail__pill {
  height: 50px;
  opacity: 1;
  background: rgba(16, 17, 33, 0.16);              /* ⚠️ non-token: Figma 활성 필 #101121 16%(2026-10-14, 전: navy-selected #202248 16%) */
  border-bottom-color: var(--lavender-600);         /* Figma border/card → lavender/600 (전: slate/300) */
}
.home-rail__item.is-active .home-rail__glow { opacity: 1; }
.home-rail__item.is-active .home-rail__icon--off { opacity: 0; }
.home-rail__item.is-active .home-rail__icon--on { opacity: 1; }
.home-rail__item.is-active .home-rail__label { opacity: 1; transform: none; }

/* ============ 콘텐츠 프레임 (contentframe) — Figma 컴포넌트 4981-55577 ============
   2026-10-23 app.css 에서 옮겨 왔다 — 홈 한 곳에서만 쓰지만 디자인시스템 페이지에서도 같은 규칙으로 그린다.
   아트 줄(230) + 12 + 캡션 자리(72) = 314. 상태 셋:
     · locked   (6088:48192) — 새까만 실루엣 + 자물쇠 "체험 완료 시 해제" · 콘텐츠 이름 / "4. THE GREAT HALL"
     · Unlocked (4981:55597) — 결과 그림 · 보조줄(흐린 글씨) / 결과 이름
     · add      (6086:25722) — 결과 그림 · 보조줄이 흰 글씨 + 꺾쇠인 링크 / 결과 이름(퀴디치 "오늘의 순위 보러가기",
                               기숙사 "내 기숙사 사진")
   자리(로고 아래)와 칸 넘김 · 떠다니기 연출은 쓰는 화면(app.css)이 정한다. */
.home-frame {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
  width: 100%;
}
/* 스테이지 — 230 줄 한가운데에 262 칸이 놓여 위아래로 16씩 넘친다(시안 그대로). 칸은 자르지 않는다 —
   그림자와 칸보다 큰 아트(패트로누스 후)가 그대로 밖으로 나온다. 콘텐츠는 칸을 옆으로 끌어 넘긴다(app.js). */
.home-stage {
  position: relative;
  width: 100%;
  height: 230px;
}
.home-box {
  position: relative;
  width: 262px;
  height: 262px;
  margin: -16px auto 0;
}
.home-slide {
  position: absolute;
  inset: 0;
}

/* 아트·안내를 감싸는 안쪽 상자 — 칸 전체를 덮는 버튼(.home-slide__open) 위에 얹히고 클릭은 아래로 떨어진다 */
.home-slide__inner {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
/* 아트 — 262 칸 안의 자리(--art-w/--art-h/--art-top, 가로는 기본 가운데)는 app.js homeSlide 가 넣는다.
   그림자: 체험 후 컷은 Figma object_shadow(0 4 24 #CBF1FF 20%)가 **그림에 구워져 있다**(컴포넌트째 내보낸 컷,
   2026-10-06 하늘빛으로 다시 받음) — 여기서 또 걸면 번짐이 두 겹이 된다. 체험 전은 아래에서 0 6 20 #EFEEFF 10%. */
.home-slide__art {
  position: absolute;
  top: var(--art-top, 0);
  left: var(--art-left, 50%);
  width: var(--art-w);
  height: var(--art-h);
  transform: translateX(var(--art-tx, -50%));
  object-fit: contain;
  pointer-events: none;
}
/* 체험 전 컷은 **새까만 실루엣**이다(시안은 color-burn 으로 눌러 검게 만든다 — 같은 결과를 brightness(0) 으로 낸다).
   그림자는 컷에서 빼고 내보냈다(app.js HOME_META 주석) — 검게 누른 뒤에 시안 그림자를 건다(2026-10-20 컴포넌트 4981:49882).
     · 기본 — 0 4 24 #CBF1FF 20% (지팡이 · 기숙사 · 초상화 · 퀴디치)
     · 물약 — 0 0 24 #EAD8FF 20% */
.home-slide.is-locked .home-slide__art {
  filter: brightness(0) drop-shadow(0 4px 24px rgba(203, 241, 255, 0.2)); /* ⚠️ non-token: Figma 체험 전 그림자 */
}
.home-slide.is-locked[data-content="potion"] .home-slide__art {
  filter: brightness(0) drop-shadow(0 0 24px rgba(234, 216, 255, 0.2));   /* ⚠️ non-token: Figma 물약 체험 전 그림자 */
}
/* 패트로누스만 예외 — 체험 전 컷이 스스로 빛나는 구체라 검게 누르면 형태 없는 검은 원이 된다(디자이너 확인 2026-09-17).
   시안 컴포넌트에도 그림자가 없다. */
.home-slide.is-locked[data-content="patronus"] .home-slide__art { filter: none; }


/* 아트가 없는 콘텐츠 — 아트가 준비될 때까지 자리만 지킨다 (⚠️ asset 필요) */
.home-slide__art--empty {
  border-radius: 50% 50% 46% 46% / 60% 60% 40% 40%;
  background: radial-gradient(60% 60% at 50% 40%, var(--navy-800) 0%, var(--navy-950) 100%);
}

/* 체험 전 안내 — 자물쇠 + "체험 완료 시 해제" (Figma contentframe locked 6088:48192 — 줄 y 69 = 칸 y 85). 누르는 건 칸 전체다. */
.home-slide__lock {
  position: absolute;
  top: 85px;
  left: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: 131px;
  transform: translateX(-50%);
}
/* 자물쇠 원 — 60 원 + 테두리 바깥 1 = 62(시안 Group 1189 inset −1.67%). 2026-10-14 시안부터 푸른빛이다 —
   안쪽 빛 ice #4288C0 20%(전: purple_200 40%) · 면 가운데 slate/300(전: #DACFF0).
   2026-10-20 원은 CSS 로 그린다 — 시안 export svg(배경 흐림 foreignObject · 안쪽 그림자 필터)를 <img> 로 넣으면 브라우저가
   낮은 해상도로 굽고 화면 확대(--app-scale)에 늘려 테두리가 흐릿했다(디자이너 지적). 자물쇠 모양만 svg 로 남겼다.
     면 흰 → slate/300 → 흰 10% · 테두리 #FEFDFC 32% · 안쪽 빛 블러 8(시안 stdDeviation 4) · 배경 흐림 10(시안 20) */
.home-slide__lock-icon {
  display: grid;
  place-items: center;
  box-sizing: border-box;
  width: 62px;
  height: 62px;
  margin: -1px;
  border: 1px solid transparent;
  border-radius: 50%;
  /* ⚠️ non-token: 시안 면 그라데이션(흰 → slate/300 #9DAFC8 → 흰) · 10% + 테두리 #FEFDFC 32% — 둘 다 한 장의 그림으로
     (단색 + 투명도로 다시 쓴 벡터라 확대해도 또렷하다). 색으로 칠하면 삼성 인터넷 강제 다크 모드에서 어두워진다 */
  background: url('../assets/shared/grad/lock-icon.svg') border-box 0 0 / 100% 100% no-repeat;
  box-shadow: inset 0 0 8px rgba(66, 136, 192, 0.2);   /* ⚠️ non-token: 시안 안쪽 빛 ice #4288C0 20% */
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.home-slide__lock-icon img { display: block; width: 15.768px; height: 21.4px; }
.home-slide__lock-label {
  /* base/body1/R-16 */
  font-family: var(--font-base);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: 0.01em;
  white-space: nowrap;
  color: color-mix(in srgb, var(--text-primary) 90%, transparent); /* ⚠️ non-token alpha: Figma 90% */
}

/* ── 캡션 — 자리 72, 두 상태 모두 위에서부터 쌓는다(프레임 314 고정 — 그래서 레일 자리가 상태와 상관없다) ──
     · locked — 콘텐츠 이름(accent/head1/SB-24) 위 · "4. THE GREAT HALL"(base/body2/L-14) 아래, 간격 4 · 67 칸 안 가운데
                (.home-caption__link--static) — 72 자리 아래 5 는 비어 있다
     · Unlocked · add — 보조줄 위 · 결과 이름(세리프 36 · 줄 43) 아래, 간격 4 → 72
       (2026-10-23 컴포넌트 수정 — 전: 간격 8 · 자리 67 에서 5 넘침) ── */
.home-caption {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  flex-shrink: 0;
  height: 72px;
  text-align: center;
  white-space: nowrap;
}
.home-caption__link {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.home-caption__link--static { justify-content: center; height: 67px; cursor: default; }
/* 보조줄이 따로 누르는 링크인 콘텐츠(기숙사 "내 기숙사 사진") — 캡션이 버튼 둘로 갈린다: 보조줄 · 결과 이름(결과 화면) */
.home-caption__link--split { cursor: default; }
.home-caption__open {
  display: block;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.home-caption__name {
  font-family: var(--font-accent);
  font-weight: 600;
  font-size: 24px;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--text-primary);
}
.home-caption__sub {
  font-family: var(--font-base);
  font-size: 14px;
  font-weight: 300;
  line-height: 1.5;
  letter-spacing: 0.01em;
  color: var(--text-secondary);
}
/* add — 보조줄이 링크다: 흰 base/body2/R-14 + 꺾쇠 16(간격 2) (Figma contentframe add 6086:25715).
   퀴디치 "오늘의 순위 보러가기"(캡션 전체가 결과 화면으로) · 기숙사 "내 기숙사 사진"(따로 누르는 버튼 — 키오스크 사진 자리). */
.home-caption__sub--link {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 0;
  border: 0;
  background: none;
  font-weight: 400;
  color: var(--text-primary);
}
button.home-caption__sub--link { cursor: pointer; }
.home-caption__sub--link img { display: block; width: 16px; height: 16px; }
/* 결과 이름 — Figma Nimbus Roman No9 L Regular 36 · 자간 −0.5 (2026-10-06, 예전 Harry Beast 자리). 폰트는 tokens.css */
.home-caption__result {
  font-family: var(--font-serif-title);
  font-weight: 400;
  font-size: 36px;
  line-height: normal;
  letter-spacing: -0.5px;
  text-transform: uppercase;
  color: var(--text-primary);
}

/* ============ 나의 QR (myqr) — Figma 컴포넌트 5743-52170 ============
   2026-10-14 app.css 에서 옮겨 왔다 — 홈 한 곳에서만 쓰지만 디자인시스템 페이지에서도 같은 규칙으로 그린다.
   자리(화살표 아래 33)는 쓰는 화면(app.css)이 정한다. QR 그림은 화면이 qrcode.js 로 그려 .home-myqr__img 로 넣는다.
   장식 22 + 판(8 · 제목 24 · 4 · 본문 297 · 8) = 363, 폭 334.
   10-14 색: 장식 #99E4FF → #CBF1FF(myqr-deco.svg) · 테두리 가운데 #BBD9FE → 흰색(myqr-frame.svg).
   <section class="home-myqr">
     <img class="home-myqr__deco" src="assets/home/myqr-deco.svg" alt="">
     <div class="home-myqr__panel">
       <h2 class="home-myqr__title">나의 QR</h2>
       <div class="home-myqr__body">
         <div class="home-myqr__code"><span class="home-myqr__glow"></span><svg class="home-myqr__img">…</svg>
           <img class="home-myqr__frame" src="assets/home/myqr-frame.svg" alt=""></div>
         <p class="home-myqr__number">1234 5678</p>          ← 값이 없으면 <p class="home-myqr__empty">…</p> 하나만
       </div>
     </div>
   </section> */
.home-myqr {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 334px;
}
.home-myqr__deco { display: block; width: 337px; height: 22px; max-width: none; }
.home-myqr__panel {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 100%;
  padding: 8px 0;
  box-sizing: border-box;
  /* 가로로 가운데만 옅게 밝은 띠 — rgba(153,228,255,.1). 단색 + 투명도로 다시 쓴 그림(강제 다크 대비) */
  background: url('../assets/shared/grad/myqr-panel.svg') 0 0 / 100% 100% no-repeat; /* ⚠️ non-token: Figma 판 */
}
.home-myqr__title {
  margin: 0;
  /* accent/body1/R-18 */
  font-family: var(--font-accent);
  font-weight: 400;
  font-size: 18px;
  line-height: 24px;
  letter-spacing: -0.01em;
  text-align: center;
  color: var(--text-primary);
}
.home-myqr__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 297px;
}
/* QR 상자 213 — 뒤에 푸른 빛(#29638D · blur 30, 5 아래로), 가운데 QR 180.53, 맨 위에 빛나는 테두리(svg 는 여백 18.78% 를 품어 293).
   테두리 svg 의 보랏빛 그림자(번짐 20)는 선 모양에서만 나오게 고쳐 두었다 — 피그마 내보내기 그대로면 선의 하늘빛 글로우까지
   불투명하게 쳐서 그림자를 만들어, 피그마 화면과 달리 짙은 보랏빛 네모가 생긴다. */
.home-myqr__code {
  position: relative;
  width: 213px;
  height: 213px;
  margin: 10px;
  cursor: default;
}
.home-myqr__glow {
  position: absolute;
  top: 5px;
  left: 0;
  width: 213px;
  height: 213px;
  background: #525C63; /* ⚠️ non-token: Figma QR 뒤 빛 — 2026-10-06 섹션 배경 시안부터 회청색(전: #29638D) */
  filter: blur(30px);   /* Figma layer blur 30 — 그대로 (시안 렌더와 픽셀로 맞춰 봄) */
}
.home-myqr__img {
  position: absolute;
  top: 16.88px;
  left: 16.23px;
  width: 180.53px;
  height: 180.53px;
}
/* 생성 QR — 라이브러리가 흰 배경 rect + 검은 모듈 path 로 그린다. 시안은 흰 모듈만 있는 투명 그림(b8d17)이라 여기서 뒤집고
   바탕은 비운다 — 뒤의 회청색 빛(.home-myqr__glow)이 바탕이 된다(2026-10-06 섹션 배경 시안).
   반전 QR 은 스캐너가 읽는다(개발팀 41d7f46 에서 attemptBoth 추가). */
.home-myqr__img rect { fill: transparent; }
.home-myqr__img path { fill: var(--icon-primary); }
.home-myqr__frame {
  position: absolute;
  top: -40px;
  left: -40px;
  width: 293px;
  height: 293px;
  max-width: none;
  pointer-events: none;
}
/* 조회 번호 — base/body1/R-16 · 신분증 번호색 80% (Figma 4981-56106) */
.home-myqr__number {
  margin: 0;
  font-family: var(--font-base);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: 0.01em;
  color: var(--text-id-number);
  opacity: 0.8;
}
/* QR 값(pairingId)이 없을 때 — QR 대신 안내만 (정상 흐름에서는 안 나온다: 로그인 전이거나 서버를 못 읽은 경우) */
.home-myqr__empty {
  margin: 0;
  font-family: var(--font-base);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.5;
  text-align: center;
  color: var(--text-secondary);
}

/* ══════════════════════════════════════════════════════════════════════
   동의 · 약관 컴포넌트 — 2026-10-19
   출처: Figma HarryPotter_UI 「ㄴ 디컴 미팅 이후 UI」 component 섹션
     check 5818:53747 · tag 5818:53754 · consent all 5818:53799 · consent item 5818:53787 ·
     sheet header 5819:6231 · callout 5819:6239 · btn/secondary 5819:6242 · btn/small 5819:6244 · link/legal 5819:6248
   쓰는 곳: 동의 시트 · 나이 확인 시트 · 보호자 동의 · 동의서 상세 · 로그인 아래 약관 시트 · 약관 페이지(app.css).
   ⚠️ 컴포넌트 설명에는 테두리가 흰 24%(전체 동의) · 40%(체크 · 보조 버튼)로 적혀 있지만 10-19 시안의 칠은
      흰 100%다 — 칠을 따랐다. 콜아웃 면도 설명(surface/glass 30%)이 아니라 칠(neutral/950)을 따랐다.
   ══════════════════════════════════════════════════════════════════════ */

/* ============ check — 22 원형. 꺼짐 흰 테두리 1.5 / 켜짐 text/accent 면 + 체크(surface/card 2) ============
   진짜 checkbox(.check-input)는 보조기기 · 키보드용으로 남기고 눈에서만 감춘다 — 바로 뒤의 .check 가 모양이다.
   <input class="check-input" type="checkbox"><span class="check" aria-hidden="true"></span> */
.check-input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}
.check {
  display: block;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  background: url('../assets/shared/check-off.svg') center / 100% 100% no-repeat;
}
.check-input:checked + .check { background-image: url('../assets/shared/check-on.svg'); }
.check-input:focus-visible + .check { border-radius: 50%; outline: 2px solid var(--focus-ring); outline-offset: 2px; }

/* ============ tag — 문서 머리 · 화면 머리 표시. 위아래 2(예외) · 좌우 8 · 모서리 4 · base/body3/M-12 ============
   accent = 필수 · 만 14세 미만(#414F70 40% · 흰 글자) / neutral = 선택(흰 면 · 검은 글자) */
.tag {
  display: inline-flex;
  align-items: flex-start;
  padding: 2px 8px;
  border-radius: 4px;
  font-family: var(--font-base);
  font-weight: 500;
  font-size: 12px;
  line-height: 1.5;
  letter-spacing: 0.005em;
  white-space: nowrap;
}
.tag--accent {
  background: rgba(65, 79, 112, 0.4); /* ⚠️ non-token: Figma tag accent 면 #414F70 40% */
  color: var(--text-primary);
}
.tag--neutral {
  background: var(--white);
  color: var(--text-on-light);
}

/* ============ consent all — 전체 동의 상자. 테두리 1 · 모서리 12 · 여백 16 · 간격 12 · base/body1/B-16 ============
   <label class="consent-all"><input class="check-input" type="checkbox"><span class="check" aria-hidden="true"></span>
     <span class="consent-all__label">전체 동의</span></label> */
.consent-all {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  position: relative;
  border: 1px solid transparent;   /* 흰 보더 — 아래 「고리 테두리」 */
  --ring: var(--paint-white);
  border-radius: 12px;
  cursor: pointer;
}
.consent-all__label {
  font-family: var(--font-base);
  font-weight: 700;
  font-size: 16px;
  line-height: 1.5;
  letter-spacing: 0.005em;
  color: var(--text-primary);
}

/* ============ consent item — 체크 + [필수]/[선택] + 항목 + 보기 · 간격 12 ============
   두 줄 항목은 시안에서 체크 · 보기가 첫 줄에 붙는다(위 정렬) — 한 줄 항목도 같은 규칙으로 두고, 보기만 첫 줄 가운데로
   내린다(21 줄 높이 − 14 밑줄 칸 = 3.5). 항목 글은 [필수] 오른쪽에서 줄을 바꾼다(시안 두 글 상자).
   <div class="consent-item">
     <label class="consent-item__pick"><input class="check-input" type="checkbox"><span class="check" aria-hidden="true"></span>
       <span class="consent-item__label"><em class="consent-item__kind">[필수]</em><span class="consent-item__text">항목 이름</span></span></label>
     <button class="consent-item__more" type="button">보기</button></div> */
.consent-item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
.consent-item__pick {
  display: flex;
  flex: 1;
  align-items: flex-start;
  gap: 12px;
  min-width: 0;
  cursor: pointer;
}
.consent-item__label {
  display: flex;
  flex: 1;
  gap: 4px;
  min-width: 0;
  padding-top: 0.5px;   /* 체크 22 · 글줄 21 — 시안처럼 첫 줄을 체크 가운데에 */
  font-family: var(--font-base);
  font-weight: 500;
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: 0.005em;
  color: var(--text-primary);
}
.consent-item__kind {
  flex-shrink: 0;
  font-style: normal;
  color: var(--text-accent);
}
.consent-item__kind--optional { color: var(--gray-200); }
.consent-item__text { word-break: keep-all; }
/* 보기 — base/body3/R-12 gray_200 · 밑줄 0.4(시안은 14 높이 칸의 아래 테두리) */
.consent-item__more {
  flex-shrink: 0;
  height: 14px;
  margin-top: 4px;
  padding: 0;
  border: 0;
  border-bottom: 0.4px solid var(--gray-200);
  background: none;
  font-family: var(--font-base);
  font-weight: 400;
  font-size: 12px;
  line-height: 14px;
  letter-spacing: 0.01em;
  white-space: nowrap;
  color: var(--gray-200);
  cursor: pointer;
}

/* ============ sheet header — 바텀시트 머리 ============
   action   제목(base/head2/M-18) + 취소(base/body2/R-14 gray_200) · 설명(base/body2/R-14 gray_200) · 간격 4
   document 손잡이(36 × 4) + 제목(base/head1/M-20) · 시행일(base/body3/R-12 text/secondary) + 닫기(32 surface/control) */
.sheet-header {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.sheet-header__row {
  display: flex;
  align-items: center;
  gap: 12px;
}
.sheet-header__title {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-family: var(--font-base);
  font-weight: 500;
  font-size: 18px;
  line-height: 1.5;
  letter-spacing: 0.005em;
  color: var(--text-primary);
}
.sheet-header__cancel {
  flex-shrink: 0;
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--font-base);
  font-weight: 400;
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: 0.01em;
  color: var(--gray-200);
  cursor: pointer;
}
.sheet-header__lead {
  margin: 0;
  word-break: keep-all;
  font-family: var(--font-base);
  font-weight: 400;
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: 0.01em;
  color: var(--gray-200);
}
.sheet-header--document { gap: 8px; }
.sheet-header__grip {
  display: block;
  width: 36px;
  height: 4px;
  margin: 8px auto 4px;
  border-radius: 2px;
  background: var(--paint-white);   /* 흰 면 — 단색 그림(강제 다크 대비 · tokens.css --paint-*) */
}
.sheet-header__head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 20px 16px;
}
.sheet-header__titles {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.sheet-header--document .sheet-header__title { font-size: 20px; }
.sheet-header__meta {
  margin: 0;
  font-family: var(--font-base);
  font-weight: 400;
  font-size: 12px;
  line-height: 1.5;
  letter-spacing: 0.01em;
  color: var(--text-secondary);
}
.sheet-header__close {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 16px;
  background: var(--surface-control);
  cursor: pointer;
}
.sheet-header__close img { display: block; width: 12px; height: 12px; }

/* ============ callout — 중요 내용 · 어린이 안내. neutral/950 면 · 모서리 12 · 여백 16 ============
   emphasis 글 하나(base/body2/R-14 흰 글자) / note 제목(base/body2/M-14) + 글(base/body2/R-14 gray_200) · 간격 8 */
.callout {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  padding: 16px;
  border-radius: 12px;
  background: var(--neutral-950);
  word-break: keep-all;
  font-family: var(--font-base);
  font-weight: 400;
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: 0.01em;
  color: var(--text-primary);
}
.callout--note { gap: 8px; }
.callout__title {
  margin: 0;
  font-weight: 500;
  letter-spacing: 0.005em;
  color: var(--text-primary);
}
.callout__text { margin: 0; color: var(--gray-200); }

/* ============ btn/secondary — 외곽선 알약 335 × 55 · 라벨 base/head2/M-18 ============ */
.btn-secondary {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 335px;
  max-width: 100%;
  height: 55px;
  box-sizing: border-box;
  padding: 0;
  position: relative;
  border: 1px solid transparent;   /* 흰 보더 — 아래 「고리 테두리」 */
  --ring: var(--paint-white);
  border-radius: var(--radius-full);
  background: none;
  font-family: var(--font-base);
  font-weight: 500;
  font-size: 18px;
  line-height: 1.5;
  letter-spacing: 0.005em;
  white-space: nowrap;
  color: var(--text-primary);
  cursor: pointer;
}
.btn-secondary:active { transform: translateY(1px); }

/* ============ btn/small — 입력 칸 옆 52 높이 외곽선 알약 · 좌우 16 · 라벨 base/body2/M-14 ============ */
.btn-small {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  height: 52px;
  box-sizing: border-box;
  padding: 0 16px;
  position: relative;
  border: 1px solid transparent;   /* 흰 보더 — 아래 「고리 테두리」 */
  --ring: var(--paint-white);
  border-radius: var(--radius-full);
  background: none;
  font-family: var(--font-base);
  font-weight: 500;
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: 0.005em;
  white-space: nowrap;
  color: var(--text-primary);
  cursor: pointer;
}
.btn-small:disabled { opacity: 0.4; cursor: default; }

/* ============ link/legal — 로그인 아래 약관 링크. 이용약관 · 개인정보처리방침 · 간격 8 · base/body3/R-12 text/id-number ============ */
.link-legal {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-base);
  font-weight: 400;
  font-size: 12px;
  line-height: 1.5;
  letter-spacing: 0.01em;
  color: var(--text-id-number);
}
.link-legal__item {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  letter-spacing: inherit;
  color: inherit;
  cursor: pointer;
}

/* ══════════════════════════════════════════════════════════════════════
   피드백 컴포넌트 — 2026-10-21
   출처: Figma HarryPotter_UI 「ㄴ 디컴 미팅 이후 UI」 component 섹션 Feedback
     toast 3903:27089(property1 = success · fail) · dialog(확인 팝업 — 코치마크 coach 6064:25290 의 무드를 따름)
   쓰는 곳: 화면 아래 토스트(app.js showToast · app.css .scope-toast) · 로그아웃 · 회원탈퇴 · 동의 거부 확인 팝업(.acdialog).
   ══════════════════════════════════════════════════════════════════════ */

/* ============ toast — 반투명 알약 + 양끝 반짝이 · 점. 성공은 초록, 실패는 빨강 ============
   알약은 글자 폭만큼(시안 글자 칸 148 → 알약 182 × 39, 테두리 1 안쪽), 긴 문구는 두 줄로 감긴다.
   반짝이 · 점은 알약 가장자리에 시안 자리 그대로 붙는다(시안 틀 214 에 알약 x16) — 반짝이는 양쪽 다 테두리
   안쪽 끝에서 9 바깥(16 칸 가운데쯤이 테두리에 걸친다), 점은 14 바깥. 위아래는 알약 가운데(시안 반짝이 top 12 · 점 18).
   <div class="toast toast--success">
     <img class="toast__dot toast__dot--l" src="assets/shared/toast-dot-success.svg" alt="">
     <img class="toast__spark toast__spark--l" src="assets/shared/toast-spark-success-l.svg" alt="">
     <p class="toast__text">이미지가 저장되었어요</p>
     <img class="toast__spark toast__spark--r" src="assets/shared/toast-spark-success-r.svg" alt="">
     <img class="toast__dot toast__dot--r" src="assets/shared/toast-dot-success.svg" alt="">
   </div> */
.toast {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  max-width: 303px;   /* 화면 375 에서 양끝 장식(14 · 14)과 여백 20 을 뺀 폭 */
  padding: 8px 16px;
  box-sizing: border-box;
  border: 1px solid transparent;   /* green_500 보더 — 아래 「고리 테두리」 */
  --ring: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='100%25' height='100%25' fill='%2392FA9B'/%3E%3C/svg%3E");
  border-radius: 12px;
  background: rgba(32, 33, 37, 0.6);   /* ⚠️ non-token: 시안 토스트 면(#202125 60%) */
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);           /* 배경 흐림 2(시안 4 — 이 프로젝트는 시안 배경 흐림의 반을 쓴다, 2026-10-21) */
}
.toast--fail { --ring: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='100%25' height='100%25' fill='%23FF8484'/%3E%3C/svg%3E"); }   /* red_500 */
.toast__text {
  min-width: 148px;   /* 시안 글자 칸 — 짧은 문구도 알약이 182 아래로 줄지 않는다 */
  margin: 0;
  word-break: keep-all;
  text-wrap: balance;   /* 두 줄이 되면 줄 길이를 고르게(끝 단어 하나만 내려가지 않게) */
  /* base/body2/M-14 */
  font-family: var(--font-base);
  font-weight: 500;
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: 0.005em;
  text-align: center;
  color: var(--white);
}
.toast__spark,
.toast__dot { position: absolute; display: block; max-width: none; pointer-events: none; }
.toast__spark { top: calc(50% - 7.5px); width: 16px; height: 16px; }
.toast__dot { top: calc(50% - 1.5px); width: 3px; height: 3px; }
.toast__spark--l { left: -9px; }     /* 테두리 안쪽에서 잰다 — 시안 x8(알약 테두리 안쪽 17) */
.toast__dot--l { left: -14px; }      /* 시안 x3 */
.toast__spark--r { right: -9px; }    /* 시안 x190(16 칸 끝 206 · 테두리 안쪽 197) */
.toast__dot--r { right: -14px; }     /* 시안 x208 */

/* ============ dialog — 확인 팝업. 코치마크 말풍선(.coach__card)과 같은 글자 · 버튼, 판은 빛이 더 넓고 옅다 ============
   폭 335(화면 여백 20) · 안쪽 여백 16 · 20(테두리 1 은 여백에서 뺀다) · 제목 B-16 → 본문 R-14(4) → (16) 버튼 줄(양 끝).
   테두리는 판 안쪽 1(neutral_950 — 바탕과 같은 색) + 판 바깥 1(slate_600 24% — 시안 border 칸이 inset −1), 빛은 흰 10% · 12.
   본문에서 짚을 구절은 <b> — 굵기는 그대로, 색만 text/accent. 왼쪽 [취소]는 글자만, 오른쪽 실행 버튼은 코치마크 [다음]과
   같은 알약. 자리(가운데) · 딤은 쓰는 화면(app.css .acdialog)이 정한다.
   <div class="dialog" role="alertdialog" aria-modal="true" aria-labelledby="…">
     <p class="dialog__title">로그아웃할까요?</p>
     <p class="dialog__body">다시 로그인하면<br><b>체험 내역을 그대로</b> 볼 수 있어요</p>
     <div class="dialog__actions">
       <button class="dialog__btn" type="button">취소</button>
       <button class="dialog__btn dialog__btn--go" type="button"><span class="dialog__btn-label">로그아웃</span></button>
     </div>
   </div> */
.dialog {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 335px;
  padding: 15px 19px;
  box-sizing: border-box;
  /* 안쪽 선 neutral_950 은 판 면(surface/card)과 같은 색이라 투명으로 두고 면이 그 밑까지 깔리게 한다 — 보기는 같고,
     어두운 테두리 색은 삼성 인터넷 강제 다크 모드에서 밝게 뒤집혀 판 둘레에 흰 선이 생겼다(2026-10-27) */
  border: 1px solid transparent;
  border-radius: 12px;
  background: var(--surface-card);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--slate-600) 24%, transparent);   /* 바깥 선 */
  filter: drop-shadow(0 0 12px rgba(255, 255, 255, 0.1));   /* ⚠️ non-token: 시안 팝업 빛(흰 10% · 12) */
  text-align: left;
}
.dialog__title {
  margin: 0;
  word-break: keep-all;
  /* base/body1/B-16 */
  font-family: var(--font-base);
  font-weight: 700;
  font-size: 16px;
  line-height: 1.5;
  letter-spacing: 0.005em;
  color: var(--text-primary);
}
.dialog__body {
  margin: 4px 0 0;
  word-break: keep-all;
  /* base/body2/R-14 */
  font-family: var(--font-base);
  font-weight: 400;
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: 0.01em;
  color: var(--gray-200);
}
.dialog__body b { font-weight: 400; color: var(--text-accent); }
.dialog__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 16px;
}
.dialog__btn {
  height: 36px;
  padding: 0 14px;
  border: 0;
  border-radius: var(--radius-full);
  background: none;
  /* base/body2/M-14 */
  font-family: var(--font-base);
  font-weight: 500;
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: 0.005em;
  color: var(--gray-200);
  cursor: pointer;
}
/* 실행 — 코치마크 [다음]과 같은 알약. 면은 #EEF1FE 단색 그림, 글자(<span class="dialog__btn-label">)는 navy_700 을
   그라디언트로 클립한다 — 밝은 CSS 면 · 어두운 단색 글자는 삼성 인터넷 강제 다크 모드에서 뒤집힌다(tokens.css --paint-*) */
.dialog__btn--go {
  padding: 0 18px;
  background: var(--paint-purple-100);   /* ⚠️ non-token: 시안 다음 버튼 면(Figma scanner/token/purple-100 — 관람객 토큰에 없다) */
  color: var(--navy-700);
}
.dialog__btn--go .dialog__btn-label {
  background: linear-gradient(var(--navy-700), var(--navy-700));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.dialog__btn:active:not(:disabled) { transform: translateY(1px); }
.dialog__btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.dialog__btn:disabled { cursor: default; }

/* ============ 고리 테두리 — 삼성 인터넷 강제 다크 모드 대비 (2026-10-27) ============
   강제 다크 모드는 CSS 테두리 색을 뒤집는다 — 밝은 테두리는 어둡게, 어두운 테두리는 밝게(사용성 테스트 10-27 ·
   tokens.css --paint-* 머리말). 그래서 테두리 칸은 투명하게(두께는 그대로) 두고 그 자리에 가상 요소로 고리를 그린다.
     --ring    고리 칠 — 밝은 색은 단색 그림(var(--paint-*) · 단색 SVG), 어두운 색은 같은 색 linear-gradient
     --ring-w  고리 두께 = 투명하게 둔 테두리 두께(기본 1px)
   고리는 테두리 칸만 칠한다(content-box 를 빼는 투명도 마스크 — 강제 다크가 건드리지 않는다). 둥근 모서리를 따른다.
   부드러운 빛(box-shadow)은 그대로 둔다 — 일반 화면을 바꾸지 않으려고(강제 다크에서는 옅어진다).
   쓰는 요소는 position 이 static 이 아니어야 하고 ::before 를 이 규칙에 내준다. 화면 요소는 app.css 「고리 테두리」. */
.consent-all::before,
.btn-secondary::before,
.btn-small::before,
.toast::before,
.input-field--pill::before {
  content: "";
  position: absolute;
  inset: calc(-1 * var(--ring-w, 1px));
  padding: var(--ring-w, 1px);
  border-radius: inherit;
  background: var(--ring);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  pointer-events: none;
}
/* 입력칸 — 고리는 틀에 단다(<input> 에는 가상 요소를 못 단다). 틀이 곧 칸의 바깥 테두리 상자라 안쪽으로 당기지 않는다 */
.input-field--pill::before { inset: 0; }
