/* RLCNF Learn — exam·note 공통 컴포넌트
 * 시안 _mockups/exam-note-redesign.html 기반
 * 부트스트랩/스킨 view.css 위에 덧입혀짐
 */

/* Container scope — font-family는 base-interaction.css의 글로벌 body 단일 출처. */
.rl-learn{
  font-feature-settings:"ss01","ss02";
  letter-spacing:var(--rl-ls-body);
  /* default body color #333 → 시안 body color var(--text)=#1F2937 로 톤 정렬. */
  color:var(--rl-text);
}
.rl-learn,
.rl-learn p,
.rl-learn span,
.rl-learn b,
.rl-learn strong{
  word-break:keep-all;
  overflow-wrap:break-word;
}

/* panel-default 기본 폭 유지 (728px), 패널 외곽 톤만 정돈 */
.rl-learn .panel-default{
  background:transparent;
  border:0;
  box-shadow:none;
}

/* 학습 페이지 본문 컨테이너는 panel과 같은 728 max-width로 정렬 — CTA·광고가 panel과 같은 폭 */
.rl-learn .at-content{
  max-width:728px;
  margin-left:auto;
  margin-right:auto;
}

/* === App Bar (메타바) === */
.rl-learn .panel-heading{
  background:transparent;
  border:0;
  border-radius:0;
  padding:0;
}
.rl-appbar{
  height:var(--rl-h-appbar);
  padding:0 12px 0 8px;
  display:flex; align-items:center; justify-content:space-between;
  gap:8px;
}
.rl-appbar .rl-ctx{
  flex:1; text-align:center; min-width:0; overflow:hidden;
  white-space:nowrap; text-overflow:ellipsis;
  font-size:var(--rl-fs-body-sm); font-weight:600;
  color:var(--rl-text-2); letter-spacing:var(--rl-ls-body);
}
.rl-appbar .rl-right{ display:inline-flex; align-items:center; gap:4px; }

/* === Icon Button === */
.rl-iconbtn{
  width:var(--rl-h-iconbtn); height:var(--rl-h-iconbtn);
  border-radius:var(--rl-r-btn);
  display:inline-flex; align-items:center; justify-content:center;
  border:0; background:transparent; cursor:pointer;
  color:var(--rl-text);
  transition:background var(--rl-dur-micro);
  padding:0;
}
@media (hover: hover) {
  .rl-iconbtn:hover{ background:var(--rl-surface-2); }
}
.rl-iconbtn:active{ background:var(--rl-surface-2); }
.rl-iconbtn svg{ width:22px; height:22px; stroke-width:1.6; }
/* §3.6.1 v1.57 — chevron 보정. mobile-nav.css `.rl-mnav-appbar__btn--chevron`과 동일 정신·동일 토큰(26/2).
   chevron-left/right는 viewBox 가로 ~25%만 차지하는 좁은 V형이라 박스형 outline(22/1.6) 대비 시각 매스가
   절반 이하로 작아 보이는 회귀를 보정. sub-page 헤더 back 버튼 등에서 modifier 부여로 발화. */
.rl-iconbtn--chevron svg{ width:26px; height:26px; stroke-width:2; }

/* === Meta Block (큰 문제번호 + 시간/정답률 한 줄) === */
.rl-meta{
  padding:4px var(--rl-sp-5) 12px;
}
.rl-meta .rl-qcount{
  display:flex; align-items:center; justify-content:space-between;
  gap:10px;
  font-weight:800; letter-spacing:-0.03em; color:var(--rl-ink);
}
.rl-meta .rl-num{ display:inline-flex; align-items:baseline; gap:6px; }
.rl-meta .rl-num b{
  font-size:var(--rl-fs-num-display); line-height:1;
  font-variant-numeric:tabular-nums;
}
.rl-meta .rl-num .rl-of,
.rl-meta .rl-num .rl-num-suffix{
  font-size:var(--rl-fs-label); color:var(--rl-text-3); font-weight:600;
  font-variant-numeric:tabular-nums;
}


/* num-btn — 답안지 입구를 큰 문제번호 칩으로 (exam 정식 모드 전용) */
button.rl-num-btn{
  appearance:none; border:0; background:transparent; cursor:pointer;
  padding:0; color:inherit; font:inherit; letter-spacing:inherit;
  display:inline-flex; align-items:center; gap:8px;
}
.rl-num-cta{
  font-size:var(--rl-fs-caption-sm); font-weight:700; color:var(--rl-text-2);
  background:var(--rl-surface); border:1px solid var(--rl-line-2);
  padding:3px 8px 3px 9px; border-radius:var(--rl-r-full);
  display:inline-flex; align-items:center; gap:3px;
  letter-spacing:0;
  transition:background var(--rl-dur-micro), color var(--rl-dur-micro), border-color var(--rl-dur-micro);
}
.rl-num-cta .rl-chev{ color:var(--rl-text-4); font-weight:500; margin-left:1px; }
@media (hover: hover) {
  button.rl-num-btn:hover .rl-num-cta{
    background:var(--rl-primary-soft); border-color:var(--rl-primary-edge); color:var(--rl-primary);
  }
  button.rl-num-btn:hover .rl-num-cta .rl-chev{ color:var(--rl-primary); }
}
button.rl-num-btn:active .rl-num-cta{
  background:var(--rl-primary-soft); border-color:var(--rl-primary-edge); color:var(--rl-primary);
}
button.rl-num-btn:active .rl-num-cta .rl-chev{ color:var(--rl-primary); }

/* timer / rate 한 줄 우측. 타이머는 "필요할 때 보이는 보조 정보" 톤 —
   파랑(primary)은 답안/진행/선택 상태 전용이라 타이머는 중립 색조(text-2 + 아이콘 text-3)로 후퇴. */
.rl-timer{
  display:inline-flex; align-items:center; gap:6px;
  font-variant-numeric:tabular-nums;
  font-weight:700; font-size:var(--rl-fs-num-meta); color:var(--rl-text-2);
  letter-spacing:var(--rl-ls-num); line-height:1;
}
.rl-timer svg{ width:14px; height:14px; color:var(--rl-text-3); }
.rl-rate{
  display:inline-flex; align-items:baseline; gap:6px; line-height:1;
}
.rl-rate .rl-l{ font-size:var(--rl-fs-caption); color:var(--rl-text-3); font-weight:600; }
.rl-rate .rl-v{
  font-size:var(--rl-fs-num-meta); font-weight:800;
  color:var(--rl-ink); letter-spacing:var(--rl-ls-num);
  font-variant-numeric:tabular-nums;
}

/* === Spinner === design system §3.1.1 Button loading state.
   SVG circle + transform rotate 애니메이션. currentColor 상속이라 부모 텍스트 색과 정합 — primary 버튼 위에서는 on-primary. */
.rl-spinner{
  display:inline-block;
  width:1em; height:1em;
  vertical-align:-0.15em;
  animation:rlSpin 0.9s linear infinite;
}
.rl-spinner circle{
  fill:none;
  stroke:currentColor;
  stroke-width:2.5;
  stroke-linecap:round;
  stroke-dasharray:44 60;
}
@keyframes rlSpin{
  to{ transform:rotate(360deg); }
}

/* 문제 질문/오류 제보 컴포즈 시트(#rl-compose-modal, .rl-sheet-modal) — 셸은 modal.css .rl-sheet-container 재사용.
   내부는 rl_study_write.php?embed=1 iframe이 컨테이너를 가득 채움(자체 앱바·완료 버튼 포함 = 작성 페이지와 동일 UI). */
/* 키보드 리프트는 iframe 내부 컴포저가 처리(rl-keyboard-state.js가 iframe에 kb 변수·kb-open 전파) —
   부모 .rl-sheet-modal의 padding-bottom(컨테이너 통째 리프트)을 무효화해 시트 상단·배경이 안 밀리게 한다.
   id 셀렉터(1,0,0)가 modal.css .rl-sheet-modal(0,1,0)을 이김. */
#rl-compose-modal.rl-sheet-modal{
  padding-bottom:0;
}
/* 컴포즈 시트 = 전체화면 모달 — 다른 .rl-sheet-modal(해설·아카이브 등 바텀시트 peek 유지)과 달리 컨테이너가
   화면 전체를 채운다. 바텀시트 peek(safe-top+sp-3 Safari / +sp-6 ios-app)를 폐기해 상단 갭 제거.
   컨테이너 surface가 상태바 영역까지 덮고(padding-top=safe-area로 내부 iframe 앱바는 상태바 아래), 풀스크린이라
   상단 라운드 코너도 제거. 등장은 .rl-sheet-container의 translateY(100%)→0(하단 슬라이드업) 그대로 유지.
   id 셀렉터로 modal.css 기본 height·radius·ios-app sp-6 처방을 모두 override(전체화면 단일 동작). */
#rl-compose-modal .rl-sheet-container{
  height: 100%;
  padding-top: env(safe-area-inset-top, 0px);
  border-radius: 0;
  box-sizing: border-box;
  /* safe-top 패딩으로 노출되는 상태바 strip이 바로 아래 iframe 앱바(평탄=surface)와 같은 톤이도록
     컨테이너 배경을 surface로(기본 modal.css surface-elev=흰색이면 상태바만 더 밝게 떠 보임).
     iframe 본문은 자체 surface-elev 배경이 덮으므로 영향 영역은 strip뿐. 다크도 토큰으로 정합. */
  background: var(--rl-surface);
}
/* embed iframe(rl_study_write.php?embed=1) 내부 앱바 safe-top 무효화 — 위 컨테이너 padding-top이
   상태바 인셋을 단일 적용하므로 iframe 앱바가 또 적용하면 이중. 웹/구앱은 iframe env()=0이라 무해했으나
   신애플 앱(transparentStatusBar+autoAdjustSafeAreaInsets=false)은 iframe에도 실측 인셋이 채워져
   상단이 2배로 밀려 깨졌다. body.rl-compose-embed(rl_study_write.php embed 마커) 한정으로 끈다 —
   standalone 작성 페이지는 자체 safe-top 유지. (0,2,1)로 mobile-nav.css 베이스(.rl-mnav-enabled .rl-mnav-appbar, 0,2,0) override. */
body.rl-compose-embed .rl-mnav-appbar{
  padding-top: 0;
}
/* 같은 이중 인셋이 컴포저 스크롤 영역에도 있다 — mobile-nav.css의 top:calc(앱바높이 + env(safe-top))이
   embed에선 앱바가 이미 safe-top=0(위 룰)이라 env()만큼 본문이 앱바 아래로 또 밀린다. embed 한정으로
   env()를 빼고 앱바 높이만 비운다(컨테이너 padding-top이 상태바 인셋 단일 적용). standalone은 mobile-nav.css 기본값 유지.
   (0,2,1)로 mobile-nav.css .rl-composer-scroll-area(0,1,0) override. */
body.rl-compose-embed .rl-composer-scroll-area{
  top: var(--rl-h-appbar);
}
.rl-compose-frame{
  flex:1 1 auto;
  width:100%;
  border:0;
  display:block;
  background:var(--rl-surface-elev);
}
/* 로딩 오버레이 — 진입(폼 로드 전)·제출 직후(상세페이지가 iframe에 잠깐 비치는 플래시 차단)에 덮음. */
.rl-compose-loader{
  position:absolute;
  inset:0;
  display:none;
  align-items:center;
  justify-content:center;
  background:var(--rl-surface-elev);
  color:var(--rl-text-3);
  font-size:var(--rl-fs-h2);
}
.rl-compose-loader.is-on{ display:flex; }
/* 로드 실패/타임아웃 폴백 오버레이 — loader와 동일하게 컨테이너를 덮는다. iframe load가 끝내 발화 안 하는
   경우의 유일한 탈출구(다시 시도·닫기). 경보형 카드가 아니라 오버레이 위 조용한 안내(담백 보이스). */
.rl-compose-error{
  position:absolute;
  inset:0;
  display:none;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:var(--rl-sp-5);
  padding:var(--rl-sp-6) var(--rl-sp-5);
  background:var(--rl-surface-elev);
  text-align:center;
}
.rl-compose-error.is-on{ display:flex; }
.rl-compose-error__msg{
  margin:0;
  font-size:var(--rl-fs-body-sm);
  line-height:var(--rl-lh-relaxed);
  color:var(--rl-text-3);
  word-break:keep-all;
  overflow-wrap:break-word;
}
.rl-compose-error__actions{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:var(--rl-sp-2);
}
/* 폴백 한정 — 조용한 안내 톤에 맞춰 ghost 라벨도 한 단계 약한 회색으로(표준 ghost는 --rl-text 유지). */
.rl-compose-error .rl-cta-ghost{ color:var(--rl-text-2); }

/* === 답안 제출 진행 표시 — "답안 제출 중 ···" 점진 점등 ===
   spinner 대안: 버튼 폭 흔들리지 않도록 dots 자리(각 0.5em × 3 = 1.5em) 고정, opacity만 순차 변화로
   진행감 전달. 사용처: exam.php submitExam() — sync XHR + 페이지 navigation 직전 #scoring 콘텐츠 교체. */
.rl-exam-submitting{
  display:inline-flex;
  align-items:center;
  gap:0.35em;
  /* 부모 버튼 폰트 대비 한 단계 축소(85%) — 진행 상태 표시는 정적 라벨보다 시각 무게 한 단계 후퇴. */
  font-size:0.85em;
  font-weight:600;
}
.rl-exam-submitting__dots{
  display:inline-block;
  line-height:1;
}
.rl-exam-submitting__dot{
  display:inline-block;
  width:0.5em;
  text-align:center;
  opacity:0.25;
  animation:rl-exam-submitting-dot 1.2s ease-in-out infinite;
}
.rl-exam-submitting__dot:nth-child(2){ animation-delay:0.16s; }
.rl-exam-submitting__dot:nth-child(3){ animation-delay:0.32s; }
@keyframes rl-exam-submitting-dot{
  0%, 60%, 100% { opacity:0.25; }
  30%           { opacity:1; }
}
@media (prefers-reduced-motion: reduce){
  .rl-exam-submitting__dot{ animation:none; opacity:0.7; }
}

/* === Error State (§3.5.9, v1.54.1) — operational ===
   실패 영역 자체를 교체하는 인라인 카드. exam.php 문제 로딩 실패 시 .question-container 안에 노출.
   다크 자동 매핑 — 페이지 안 컴포넌트라 .rl-mnav-enabled 스코프 다크 토큰 자동 상속. */
.rl-error-state{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:var(--rl-sp-3);
  /* 시험 흐름 중간의 복구 상태이지 결과 화면처럼 웅장하지 않음. min-height/padding 균형으로 컴팩트한 안정감.
     min-height 320(사용자 명세 300~340 중간) + padding 40(sp-7=32보다 한 단계 컴팩트, sp-6=24 + sp-2=8). */
  min-height:320px;
  padding:var(--rl-sp-6) var(--rl-sp-5);
  background:var(--rl-surface-2);
  /* border-color는 한 톤 약하게(--line-2 → --line) — 외측 페이지 frame과의 이중 보더 시각 무게 완화. */
  border:1px solid var(--rl-line);
  border-radius:var(--rl-r-md);
  text-align:center;
  word-break:keep-all;
  overflow-wrap:break-word;
}
.rl-error-state__icon{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:48px;
  height:48px;
  border-radius:var(--rl-r-full);
  background:var(--rl-warn-soft);
  color:var(--rl-warn);
  flex-shrink:0;
}
.rl-error-state__icon svg{ width:24px; height:24px; }
.rl-error-state__heading{
  margin:0;
  font-size:var(--rl-fs-h4);
  font-weight:700;
  color:var(--rl-ink);
  letter-spacing:var(--rl-ls-tight);
  line-height:var(--rl-lh-snug);
}
.rl-error-state__body{
  margin:0;
  font-size:var(--rl-fs-body-sm);
  color:var(--rl-text-2);
  line-height:var(--rl-lh-snug);
}
/* CTA — .rl-cta-primary(§3.1.1) 재활용. 본 컴포넌트 스코프에서만 min-width 정합. */
.rl-error-state__cta{ min-width:140px; }
/* retry 진행 중 disabled 상태 — 시각 후퇴 + 클릭 차단 */
.rl-error-state__cta[disabled]{ opacity:0.7; cursor:wait; }

/* 오류 카드 표시 중 외부 CTA 숨김 — exam-only scope (.rl-learn 안), 형제 페이지 영향 0. */
body.is-exam-error-state .rl-learn .rl-actions{ display:none; }
/* 오류 카드 표시 중 .question-container 안 다른 자식(`.question`/`.answer-container` 등) 숨김.
   body.is-exam-error-state는 exam.php 전용이라 note.php의 .question-container는 영향 없음.
   [hidden] attribute는 author CSS의 display: flex/grid 등에 specificity로 밀리므로 본 룰이 단일 출처. */
body.is-exam-error-state .question-container > :not(.rl-error-state){ display:none; }

/* === Progress Bar === */
.rl-bar{
  margin:0 var(--rl-sp-5);
  height:4px; background:var(--rl-surface-2);
  border-radius:var(--rl-r-full); overflow:hidden;
}
.rl-bar i{ display:block; height:100%; border-radius:var(--rl-r-full); transition:width var(--rl-dur-base); }
.rl-bar.is-exam i{ background:linear-gradient(90deg, var(--rl-primary-light), var(--rl-primary)); }
.rl-bar.is-note i{ background:linear-gradient(90deg, var(--rl-accent-light), var(--rl-accent)); }

/* === 본문 톤 정렬 (panel 내부) === */
/* view-padding은 자체 padding-top 0 — 카드 상단 외부 여백은 글로벌 룰(.at-content padding-top 6 §2.8.4)에 위임. */
.rl-learn .view-padding{ padding-top:0; }
/* .question-container = 문제+보기를 묶는 외곽 frame. surface-elev 채움 없이 line-2 border만으로 묶음 표시 —
   답 셀(sub-card)이 실제 인터랙션 위계 담당, 외곽은 "한 문제 단위" 정도로만 후퇴(중첩 카드 무거움 경감). */
.rl-learn .question-container{
  max-width:728px; margin:auto;
  background:transparent;
  border:1px solid var(--rl-line-2);
  border-radius:var(--rl-r-lg);
  padding:var(--rl-sp-2) !important;
  overflow:visible;
}
.rl-learn .question{
  font-size:var(--rl-fs-quiz-q); line-height:var(--rl-lh-relaxed);
  font-weight:500; color:var(--rl-ink); letter-spacing:var(--rl-ls-tight);
}
/* view.css가 .view-content .question::before로 "[문제]" 프리픽스를 강제한다 — 시안에는 없으므로 무력화.
   "N. " prefix는 ::before 대신 JS가 첫 <p> 안에 inline span(.rl-question-num)으로 inject —
   PHP echo가 <p> block으로 시작하면 ::before가 별도 line으로 떠 본문과 baseline 어긋나는 회귀 차단. */
.rl-learn .view-content .question::before{ content:none !important; }
.rl-learn .view-content .rl-question-num{
  font-weight:700;
  color:var(--rl-ink);
  letter-spacing:var(--rl-ls-tight);
  margin-right:0.15em;
}
/* view.css의 .view-content{font-size:16px !important}와 .view-content .question{margin-bottom:25px}가
   시안 본문 톤(17px / margin:14px 0 0)을 침범. 명시적으로 토큰값으로 복원한다.
   문제 본문은 카드 톤 없이 텍스트 흐름 — 답안 셀(카드)만 명확한 위계. 카드화 시 풀이 흐름 무거워지고
   세로 공간 손실(긴 지문/이미지 문제에서 보기까지 밀림)로 모의시험 풀이 도구성 저하. */
.rl-learn .view-content{ font-size:var(--rl-fs-body) !important; line-height:var(--rl-lh-normal); }
.rl-learn .view-content .question{
  margin:0 !important;
  padding:0 var(--rl-sp-2);
  font-size:var(--rl-fs-quiz-q);
  line-height:var(--rl-lh-relaxed);
  font-weight:500;
  color:var(--rl-ink);
  letter-spacing:var(--rl-ls-tight);
}
/* 원본에 있는 빈 <p>(에디터에서 의도된 단락 호흡)는 PHP에서 .rl-q-spacer 클래스로 변환.
   시각 높이를 sp-4 토큰으로 일관 — 단락 간격은 spacer 갯수가 결정. 이미지·텍스트 강제 정렬 X(원본 흐름 그대로). */
.rl-learn .view-content .question .rl-q-spacer{
  height:var(--rl-sp-3);
  margin:0;
  padding:0;
}
.rl-learn .view-content .question img{
  max-width:100%;
  height:auto;
}
/* p 안에 img가 단독(텍스트·다른 요소 없음)일 때만 가운데 정렬. 텍스트+이미지 혼합 p는 원본 흐름 유지. */
.rl-learn .view-content .question p:has(> img:only-child){
  text-align:center;
}

/* MathJax 수식 오버플로우 안전망(B) — 기본 줄바꿈은 MathJax v4 displayOverflow:linebreak(cf_add_script,
   설정 단일 출처)가 처리. 여기선 코드 단일 출처로 ① 컨테이너 폭 fit ② 안 끊기는 긴 토큰/행렬/특수식은
   가로 스크롤 폴백(잘림 방지) ③ white-space:normal로 끊긴 줄이 흐르게(전역 nowrap 잔재 대비).
   cf_add_script 전역 스타일과 독립 — 설정 미반영 환경에서도 수식이 가로로 잘리지 않게. raw px/hex 없음. */
.rl-learn mjx-container,
.rl-qzview-explain mjx-container,
#explanation-section mjx-container{
  max-width:100%;
  overflow-x:auto;
  overflow-y:hidden;
  white-space:normal;
}

/* 문제 본문 안 학습 콘텐츠 컴포넌트 — view.css 베이스(raw #ccc/10px)를 디자인 시스템 토큰으로 정합.
   - .ex  : 예시 박스(보기·기호·조건 등을 묶는 영역). line-2 border + r-md + 세로 sp-2·가로 sp-4 padding + surface 배경.
   - .et  : 표 wrapper. 모바일에서 가로 스크롤(폭 초과 표 회피).
   - .ex 안 ul.giyuk/.ga/.a/.roman/.num — list-style만이라 베이스 view.css 룰 그대로 사용.
   - .ex 안 table은 아래 table 룰이 자동 적용. */
.rl-learn .view-content .question .ex{
  border:1px solid var(--rl-line-2);
  border-radius:var(--rl-r-md);
  padding:var(--rl-sp-2) var(--rl-sp-4);
  background:var(--rl-surface);
  color:var(--rl-text);
}
.rl-learn .view-content .question .ex > ul,
.rl-learn .view-content .question .ex > ol{
  margin:0 !important;
  padding-inline-start:var(--rl-sp-6);
}
/* bullet 항목 간 호흡 — 줄바꿈 많은 li에서 읽기 편하도록 sp-2 간격. 첫 li는 영향 없음(+ 인접 형제). */
.rl-learn .view-content .question .ex > ul > li + li,
.rl-learn .view-content .question .ex > ol > li + li{
  margin-top:var(--rl-sp-2);
}
/* list-style 마커(ㄱㄴㄷ/가나다/abc/로마/숫자) — 정의는 보드 스킨 view.css에만 있어 view.css 미로드 컨텍스트
   (연결 문제 카드 등)에서 마커가 사라졌다. learn.css에도 단일 출처로 둬서 exam/quick/note/카드 모두 동일 적용.
   (exam/quick/note는 view.css도 로드 — 동일 값이라 무해.) */
.rl-learn .view-content .question .ex ul.giyuk > li{ list-style: hangul-consonant; }
.rl-learn .view-content .question .ex ul.ga > li{ list-style: hangul; }
.rl-learn .view-content .question .ex ul.a > li{ list-style: lower-alpha; }
.rl-learn .view-content .question .ex ul.roman > li{ list-style: upper-roman; }
.rl-learn .view-content .question .ex ul.num > li{ list-style: decimal; }
.rl-learn .view-content .question .et,
.rl-learn .view-content .question .rl-table-wrap{
  width:100%;
  overflow:hidden;
  position:relative;
}
/* 표가 폭 초과 시 JS가 .is-scaled 부여 + table에 transform:scale(X) inline 적용. cursor:zoom-in 힌트. */
.rl-learn .view-content .question .rl-table-wrap.is-scaled,
.rl-learn .view-content .question .et.is-scaled{
  cursor:zoom-in;
}
.rl-learn .view-content .question .rl-table-wrap.is-zoomed,
.rl-learn .view-content .question .et.is-zoomed{
  overflow:auto;
  -webkit-overflow-scrolling:touch;
  cursor:zoom-out;
}
.rl-learn .view-content .question table{
  transform-origin:top left;
}
/* 문제 본문 안 <table> — 학습 UI 톤 정합. surface-2 헤더 / line-2 hairline / sp-2~3 padding / fs-body-sm.
   모바일에서 .question 자체 overflow-x:auto로 가로 스크롤 안전망(폭 초과 표 회피). 토큰만 사용. */
.rl-learn .view-content .question{
  overflow-x:auto;
  /* 가로 안전망의 짝 — 없으면 overflow-x:auto가 BFC를 만들어 자식 trailing margin/sub-px이 scrollHeight에
     잡혀 phantom 세로 스크롤바가 뜬다(콘텐츠 높이 무제약이라 실제 클립 0). mjx-container 안전망과 동일 패턴. */
  overflow-y:hidden;
}
.rl-learn .view-content .question table{
  width:100%;
  max-width:100%;
  border-collapse:collapse;
  margin:0;
  font-size:var(--rl-fs-body-sm);
  line-height:var(--rl-lh-normal);
  color:var(--rl-text);
}
.rl-learn .view-content .question th,
.rl-learn .view-content .question td{
  border:1px solid var(--rl-line-2);
  padding:var(--rl-sp-2) var(--rl-sp-3);
  text-align:center;
  vertical-align:middle;
}
.rl-learn .view-content .question th{
  background:var(--rl-surface-2);
  font-weight:700;
  color:var(--rl-ink);
}
.rl-learn .view-content .question td{
  background:transparent;
}

/* note.php의 본문 안 problem-meta(풀이 제공 / 라운드 m/n / 정답률) 행은 시안에 없다.
   라운드 진척은 상단 메타블록(.rl-meta .rl-num)이, 정답률은 .rl-rate가 대체.
   이 영역 자체를 숨겨 본문 톤이 question→choices로 바로 흐르게 한다. */
.rl-learn .problem-meta{ display:none !important; }

/* === Inline CTA — 답 선택 후 등장. === */
.rl-learn .rl-actions{
  margin:var(--rl-sp-5) var(--rl-sp-5) 0;
  max-width:728px;
}
.rl-learn .rl-actions{ /* 중앙 정렬 — panel-default가 728 max-width라 자연 정렬 */
  margin-left:auto; margin-right:auto;
}
/* #scoring 시안 톤 — 답 선택 전 비노출, .can-scoring 활성 시 풀폭 CTA 등장.
   apms.css/.trans-bg-crimson + view.css/#scoring 가 !important로 잠겨 있어 토큰 덮어쓰기 위해 !important 사용 — 외부 cascade 충돌 한정. */
.rl-learn #scoring{
  display:none;
  width:100%;
  min-width:0 !important;
  height:var(--rl-h-btn-lg);
  border-radius:var(--rl-r-md) !important;
  align-items:center; justify-content:center; gap:var(--rl-sp-2);
  font-size:var(--rl-fs-quiz-cta); font-weight:700; letter-spacing:var(--rl-ls-body);
  background:var(--rl-primary) !important;
  color:var(--rl-on-primary) !important;
  opacity:1 !important;
  cursor:pointer !important;
  border:0; padding:0 !important;
  font-family:inherit;
  transition:background var(--rl-dur-micro), transform 120ms;
  text-transform:none;
}
.rl-learn #scoring.can-scoring,
.rl-learn #scoring.trans-bg-crimson{
  display:flex;
  animation:rlCtaIn var(--rl-dur-base) ease both;
  background:var(--rl-primary) !important;
  color:var(--rl-on-primary) !important;
  opacity:1 !important;
}
@media (hover: hover) {
  .rl-learn #scoring:hover,
  .rl-learn #scoring.can-scoring:hover,
  .rl-learn #scoring.trans-bg-crimson:hover{ background:var(--rl-primary-hover) !important; }
}
.rl-learn #scoring:active,
.rl-learn #scoring.can-scoring:active,
.rl-learn #scoring.trans-bg-crimson:active{ background:var(--rl-primary-hover) !important; transform:scale(.99); }

@keyframes rlCtaIn{
  from{ opacity:0; transform:translateY(6px); }
  to{ opacity:1; transform:translateY(0); }
}

/* === Note 풀이 카드 (#explanation-block) — 정답 설명은 카드 없이 본문 흐름.
   사용자 명세: "정답 설명은 카드 없이 본문" → bg/border/radius/padding 모두 제거, 본문 텍스트만.
   #explanation-section-parents는 view.css가 좌우 마진을 부여할 수 있어 명시 0으로 reset. */
.rl-learn #explanation-block{ margin-top:12px; }
.rl-learn #explanation-section-parents{ margin:0 !important; }
.rl-learn #explanation-section{
  background:transparent;
  border:0;
  border-radius:0;
  padding:0;
  max-width:728px; margin:0 auto;
  /* 문제 카드 .question 톤 정합 — view.css가 16/180% 강제 → 토큰값으로 명시 reset. */
  font-size:var(--rl-fs-body);
  line-height:var(--rl-lh-relaxed);
  letter-spacing:var(--rl-ls-tight);
}
/* #explanation-section 직속 자식 section(.rl-explain-answer, 정답 요약, review-warning)에 좌우 패딩 sp3 — 사용자 명세.
   view.css의 #explanation-section > section{padding:0} 룰(specificity 1,1,1)이 우리 0,2,1을 이기므로 !important로 잠금. */
.rl-learn #explanation-section > section{
  padding-left:var(--rl-sp-3) !important;
  padding-right:var(--rl-sp-3) !important;
}

/* 정답 위 식별 메타(시행일 · 과목 · 정답률 · 풀이 수) — rl_study_view 연결 문제 카드와 동일 토큰.
   직속 자식 div이라 위 `> section` 좌우 패딩(sp3)을 못 받으므로 정답 섹션과 좌우 정렬 맞춰 직접 부여.
   해설 시트에선 항상 한 줄(nowrap·overflow hidden). 한 줄 넘침 시 과목명(__subject)을
   rl_explain_meta_fit.js가 드롭해 시행일·정답률·풀이 수만 남긴다. */
.rl-learn #explanation-section .rl-qcard-meta{
  padding-left:var(--rl-sp-3);
  padding-right:var(--rl-sp-3);
  /* 정답과의 간격을 약간 좁힘 — 기본 gap sp-2(8px)에서 sp-1만큼 끌어올려 net sp-1(4px). */
  margin-top:calc(-1 * var(--rl-sp-1));
  margin-bottom:var(--rl-sp-2);
  font-size:var(--rl-fs-caption);
  color:var(--rl-text-4);
  white-space:nowrap;
  overflow:hidden;
}
.rl-learn #explanation-section .rl-qcard-meta__attempts{ white-space:nowrap; }

/* 풀이 참고 라벨 + 검수 칩 + 업데이트 시각 헤더.
   view.css의 #explanation-section .badge-note (specificity 1,1,0)가 font-size:16/margin/color/padding-bottom:12/border-bottom 을 강제 →
   selector를 #explanation-section 까지 확장해 1,2,0으로 specificity 우위 확보. */
.rl-learn .badge-note,
.rl-learn #explanation-section .badge-note{
  display:flex; align-items:center; flex-wrap:wrap; gap:8px;
  margin:0 0 10px;
  padding:0;
  background:transparent !important;
  border:0 !important;
  font-size:var(--rl-fs-caption); font-weight:700; color:var(--rl-ink);
  letter-spacing:var(--rl-ls-body); line-height:1.3;
}
/* 시안: "📝" 이모지 제거 — 첫 자식이 빈 텍스트 노드일 때 다음 span만 보임 */
.rl-learn .badge-note > span:first-of-type,
.rl-learn #explanation-section .badge-note > span:first-of-type{
  font-size:var(--rl-fs-label); font-weight:700; color:var(--rl-ink);
}

/* 검수 칩 (manual / auto / pending) — 작은 닷 + 차분한 회색 톤 */
.rl-learn .badge-note .badge{
  display:inline-flex; align-items:center; gap:5px;
  font-size:var(--rl-fs-micro); font-weight:600;
  color:var(--rl-text-2);
  background:var(--rl-surface-2);
  border:1px solid var(--rl-line-2);
  padding:3px 8px;
  border-radius:var(--rl-r-full);
  letter-spacing:0;
  text-transform:none;
}
/* view.css .badge[data-tip]::before 의 tooltip-arrow 정의(border:6px solid transparent;
   border-top-color:#2c3e50; position:absolute; right:18px; bottom:calc(100% - 6px); opacity:0;)
   가 우리 dot 표시에 부분 cascade 되어 5px dot가 0 opacity 상태로 깨진다.
   충돌 프로퍼티(position/border/right/bottom/opacity)를 모두 명시적으로 reset. */
.rl-learn .badge-note .badge::before{
  content:""; width:5px; height:5px; border-radius:50%;
  background:var(--rl-text-4); flex-shrink:0;
  position:static !important;
  border:0 !important;
  right:auto !important;
  bottom:auto !important;
  opacity:1 !important;
  box-sizing:border-box;
}
.rl-learn .badge-note .badge.manual::before{ background:var(--rl-good) !important; }
.rl-learn .badge-note .badge.auto::before{ background:var(--rl-info) !important; }
.rl-learn .badge-note .badge.pending::before{ background:var(--rl-warn) !important; }
/* tooltip ::after(텍스트 박스)는 hover 트리거에만 나타나므로 그대로 두되, 위치 컨텍스트만 잠가
   hover 시 우상단으로 정상 표시되도록 .badge에 position:relative 보장. */
.rl-learn .badge-note .badge{ position:relative; }

/* update_at — 시안 .explain-head .update-time 우상단 정렬 톤.
   PHP가 <p.badge-note>와 <section.update_at>를 형제 노드로 배치하므로 absolute로 끌어 올린다. */
.rl-learn #explanation-section{ position:relative; }
.rl-learn .update_at{
  position:absolute;
  top:14px;
  right:16px;
  margin:0; padding:0;
  background:none; border:0;
}
.rl-learn .update_at time{
  font-size:var(--rl-fs-caption-sm); color:var(--rl-text-3);
  font-variant-numeric:tabular-nums; font-weight:500;
}

/* 정답 칩 — "정답 ④" 보라 원형.
   view.css의 #explanation-section section .title{padding:10px 0 8px} 가 시안에 없는 위아래 여백을
   추가하므로 padding:0으로 reset. specificity 1,2,1로 1,1,1 view.css를 이긴다. */
.rl-learn #explanation-section section .title{
  display:inline-flex; align-items:center; gap:6px;
  font-size:var(--rl-fs-label); font-weight:700; color:var(--rl-text-3);
  margin:0 0 6px;
  padding:0;
}
/* 상단 "정답 N번" — 사용자 명세상 네 헤더 모두 fs-body로 통일.
   강조는 ink + 700 weight + ans-num-text primary color로. */
.rl-learn #explanation-section section.rl-explain-answer .title{
  font-size:var(--rl-fs-body);
  color:var(--rl-ink);
  margin:0 0 var(--rl-sp-3);
}
.rl-learn #explanation-section section.rl-explain-answer .ans-num-text{
  font-size:var(--rl-fs-body);
}
.rl-learn #explanation-section section:first-of-type > .title{
  margin:0 0 8px;
}
/* skin view.css의 #explanation-section section .title .answer-chip{background:#d6f5e3} 가
   같은 specificity(1,2,1)로 우리 토큰 룰을 덮어쓴다 → section .title 까지 공유해 specificity 동등 후
   import 순서로 이기게 하고, 그래도 고정 16진수 backgound가 남아 있을 수 있어 !important로 잠근다. */
.rl-learn #explanation-section section .title .answer-chip{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:24px; height:24px; padding:0 8px !important;
  border-radius:var(--rl-r-full) !important;
  background:var(--rl-primary) !important; color:var(--rl-on-primary) !important;
  font-size:13px; font-weight:800; line-height:1;
  font-feature-settings:"ss01";
  margin-left:6px;
  letter-spacing:0;
}
/* 옵션 B — 텍스트 강조형 정답 표기 (칩 미사용 비교용) */
.rl-learn #explanation-section section .title .ans-num-text{
  font-size:15px; font-weight:800;
  color:var(--rl-primary);
  letter-spacing:-0.01em;
  font-variant-numeric:tabular-nums;
  margin-left:4px;
}

/* section 내부 여백 정리 — 정답 요약 (첫 section), 그 외 section은 .blk 카드 */
.rl-learn #explanation-section > section{
  margin:0;
  padding:0;
  background:transparent;
}
.rl-learn #explanation-section > section + section{ margin-top:10px; }

/* 정답 요약 — 시안에는 별도 "정답 요약" 라벨 없이 chip 바로 아래 본문이 흐른다.
   #explanation-section > section h2.title (정답 chip section 다음의 정답 요약 section의 헤더)는 숨김.
   #more-explanation 내부 section의 h2.title은 살려둔다(선택지별 해설/관련 개념/오답 함정). */
.rl-learn #explanation-section > section h2.title{ display:none; }

/* #more-explanation section h2.title (선택지별 해설) — 정답 강조(primary)보다 한 단계 약한 파랑.
   사용자 명세: 색 한 단계 연하게(primary-light) + weight 약간 낮춤(600).
   view.css의 margin 룰이 specificity로 이기는 케이스 → margin만 !important로 잠금. */
.rl-learn #more-explanation section h2.title{
  font-size:var(--rl-fs-body); font-weight:600; color:var(--rl-primary-light);
  margin:0 0 var(--rl-sp-3) !important;
  letter-spacing:var(--rl-ls-tight);
  text-transform:none;
  display:inline-flex; align-items:center; gap:5px;
}
.rl-learn #more-explanation section h2.title .blk{ display:none; }

.rl-learn #explanation-section section .description{
  /* 해설 본문 — 학습 본문 사이즈 그룹 quiz-e 토큰(기본 16). data-quiz-scale 분기 시 자동 스케일. */
  font-size:var(--rl-fs-quiz-e); line-height:var(--rl-lh-relaxed);
  color:var(--rl-ink); letter-spacing:var(--rl-ls-tight);
  word-break:keep-all;
  overflow-wrap:break-word;
  /* view.css #explanation-section section .description{margin-top:15px} 가 시안 ans-summary
     hugged 톤을 깨므로 selector specificity로 reset. */
  margin-top:0;
}
/* 정답 요약 클램프 폐기(사용자 명세) — 해설 화면에서 본문 잘림은 "왜 다 안 보여주지" 인지 유발.
   길면 자연스럽게 아래로 흐르게 둠. line-clamp/overflow:hidden 룰 모두 제거. */

/* 해설 모달 인라인 사각형(note_explain_below / quick_explain_below) — 해설 본문 끝(#more-explanation 뒤),
   #explanation-section 직속에 주입(rl-explain-modal-ad.js). 인페이지 하단 광고(exam·quick·note)와 동일한
   push-to-bottom: 콘텐츠가 시트보다 짧으면 광고를 시트 바닥으로 정렬(margin-top:auto), 길면 콘텐츠 뒤
   인플로우 + 스크롤(.rl-sheet-body가 flex:1·overflow-y:auto). :has 게이트로 광고가 실제 점유할 때만 ON
   (no-fill/off는 baseline 자연 높이, §4.12.D). 광고↔윗 콘텐츠 간격 sp-5는 #more-explanation margin-bottom으로
   보존(오버플로 시 margin-top:auto=0이어도 유지). rl-ad.css question variant 기본 sp-7 대체.
   .rl-sheet-body는 공유 클래스라 :has(> #explain-modal-body ...)로 해설 모달에만 스코프(타 시트 무영향). */
.rl-sheet-body:has(> #explain-modal-body .rl-ad-slot--display:not([data-rl-ad-collapsed])){
  display:flex;
  flex-direction:column;
}
.rl-sheet-body:has(> #explain-modal-body .rl-ad-slot--display:not([data-rl-ad-collapsed])) > #explain-modal-body{
  flex:1 1 auto;
  display:flex;
  flex-direction:column;
  min-height:0;
}
/* 클론 래퍼 #explanation-section-parents > #explanation-section 까지 flex 높이 전달(광고 margin-top:auto 작동). */
#explain-modal-body:has(.rl-ad-slot--display:not([data-rl-ad-collapsed])) > #explanation-section-parents{
  flex:1 1 auto;
  display:flex;
  flex-direction:column;
}
#explanation-section-parents:has(> #explanation-section > .rl-ad-slot--display:not([data-rl-ad-collapsed])) > #explanation-section{
  flex:1 1 auto;
  display:flex;
  flex-direction:column;
  /* 하단 호흡은 .rl-sheet-body의 기존 padding-bottom(sp-5) 단일 출처 — 여기 별도 padding-bottom을 주면
     push(미스크롤) 시 시트 패딩과 스택돼 32px로 커짐(overflow는 겹쳐 16px → 불일치). 그래서 추가 안 함. */
}
#explanation-section:has(> .rl-ad-slot--display:not([data-rl-ad-collapsed])) > #more-explanation{
  /* push-to-bottom 담당: 자유 공간을 흡수해 아래 광고를 시트 바닥으로(짧을 때). 오버플로 시 0이 되어
     광고는 자기 margin-top(sp-5)만큼만 윗 콘텐츠와 띄움 — 광고 '자체'의 상단 여백이 항상 sp-5(pre-push 동일). */
  margin-bottom:auto;
}
#explanation-section > .rl-ad-slot--display{
  /* 광고 자체 상단 여백 sp-5(인플로우/오버플로 동일). push는 위 #more-explanation margin-bottom:auto가 담당. */
  margin-top:var(--rl-sp-5);
  /* flex cross축에서 margin-inline:auto가 빈 슬롯 너비를 0으로 줄여 _verifySize가 suppress→collapse하는 것 방지(인페이지 동일). */
  width:100%;
}
/* 아코디언 펼침/오버플로로 스크롤바가 생길 때 데스크탑 클래식 스크롤바가 콘텐츠 폭을 줄여 좌우가 튀는 것 방지.
   gutter 사전 예약(모바일 오버레이 스크롤바는 gutter 미사용이라 무영향). 해설 모달 스크롤러 한정. */
#explain-modal .rl-sheet-body{
  scrollbar-gutter:stable;
  /* 하단 간격(sp-5)+safe-area(홈인디케이터) 모두 콘텐츠(#explanation-section padding-bottom)로 이관 —
     스크롤 컨테이너 자체 padding-bottom은 오버플로 시 클립되어 '바닥까지 스크롤'하면 safe-area가 사라짐
     (신iOS 앱: 광고가 홈인디케이터에 근접·여백 낮음). 시트 자체 하단 패딩은 0. */
  padding-bottom:0;
}
/* 광고/콘텐츠 하단 호흡 sp-5 + safe-area(홈인디케이터) — 스크롤 콘텐츠 '내부'라 오버플로(바닥 스크롤)서도 클립 없이
   유지(short·overflow 동일). 시트 컨테이너 padding-bottom은 클립되므로 safe-area까지 여기서 단일 처리.
   광고 유무 무관(no-ad 시 해설 본문 하단 호흡). */
#explain-modal-body #explanation-section{
  padding-bottom:calc(var(--rl-sp-5) + var(--rl-safe-bottom, env(safe-area-inset-bottom, 0px)));
  /* 넓은 화면에서 시트 폭을 채우도록 — 기존 max-width:728 + margin-inline:auto 조합이 폭을 제한:
     ① 오버레이 스크롤바로 content폭>728이면 728로 cap(우측 빈 8~12px), ② flex 컨텍스트에선 auto margin이
     stretch까지 무력화해 content 폭으로 축소+가운데정렬. 모달 시트는 ≤768로 이미 좁아 readability cap 불필요
     → cap 해제(max-width:none) + auto margin 제거(margin-inline:0)로 항상 부모(시트) 폭 채움. 좁은 화면 무영향. */
  margin-inline:0;
  max-width:none;
}

/* 상세 풀이 영역 #more-explanation — 3섹션을 흰 카드로 분리. 카드 간 gap sp-4로 시각적 호흡 확보.
   외부 cascade(view.css 등)가 display:block으로 덮어 gap이 무시되던 회귀 차단 — !important로 flex 잠금. */
.rl-learn #more-explanation{
  margin-top:var(--rl-sp-4);
  display:flex !important; flex-direction:column; gap:var(--rl-sp-4);
}
.rl-learn #more-explanation > section{
  background:var(--rl-surface);
  border:1px solid var(--rl-accent-edge);
  border-radius:var(--rl-r-btn);
  /* 상하 sp-2(8) — 카드 내부 밀도 ~15% 증가(사용자 명세 "선택지별 해설 카드 압축"). */
  padding:var(--rl-sp-2) var(--rl-sp-4);
  margin:0 !important;
}
/* 아코디언 카드(.rl-collapsible) — 관련 개념 요약·오답 함정. 카드 외형 유지(접힘/펼침 동일), 카드 안에서 본문만 펼침.
   사용자 명세: 얇은 아웃라인 카드 + 펼침은 body padding으로 자연 확장 + chevron 회전.
   테두리는 accent-edge보다 한 단계 더 연한 보라(~15% 약화) — 보조 섹션 톤. 배경은 surface-elev로 흰색 가깝게. */
.rl-learn #more-explanation > section.rl-collapsible{
  background:var(--rl-surface-elev);
  border:1px solid var(--rl-accent-edge-soft);
  border-radius:var(--rl-r-btn);
  padding:0 !important;
  overflow:hidden;
}
/* 시트 컨텍스트 한정 — 모달 본문(.rl-sheet-container background:surface-elev)과 .rl-collapsible 카드 배경이
   동일색이라 카드 경계가 border-soft alpha에만 의존 → 라이트/다크 모두 카드 미시각. 첫 카드(.rl-surface)와
   같은 톤으로 통일하고 위계는 border 강도(accent-edge vs accent-edge-soft)로 유지.
   페이지 본문 컨텍스트(.at-content surface 위)는 변경 없음 — surface-elev 카드가 떠 보이는 게 디자인 의도. */
:is(#sheet-modal, #explain-modal) .rl-learn #more-explanation > section.rl-collapsible{
  background:var(--rl-surface);
}
.rl-learn .rl-collapsible-toggle{
  appearance:none;
  cursor:pointer;
  background:transparent;
  border:0;
  width:100%;
  /* 세로 padding 축소 — 접힌 상태가 "부가 정보"처럼 가볍게 보이도록(사용자 명세). */
  padding:var(--rl-sp-2) var(--rl-sp-4);
  font-family:inherit;
  font-size:var(--rl-fs-quiz-e);
  font-weight:600;
  /* 중립색(ink) — 사용자 명세: "관련 개념·오답 함정은 본문색/회색 추천, 파랑 강조 회수".
     카드 테두리(accent-edge)만 보라 톤 유지해 "누를 수 있는 카드" 시각은 보존. */
  color:var(--rl-ink);
  display:flex; align-items:center; justify-content:space-between; gap:var(--rl-sp-2);
  letter-spacing:var(--rl-ls-tight);
  transition:background var(--rl-dur-micro) var(--ease-out);
  text-align:left;
}
@media (hover: hover){
  .rl-learn .rl-collapsible-toggle:hover{ background:var(--rl-accent-bg); }
}
.rl-learn .rl-collapsible-toggle:focus-visible{
  outline:2px solid var(--rl-primary);
  outline-offset:-2px;
}
/* chevron SVG — design-system 기본 stroke 아이콘(stroke-width 1.6). text-3 톤으로 보조 시각, 펼침 시 180° 회전. */
.rl-learn .rl-collapsible-chev{
  display:inline-block;
  color:var(--rl-text-3);
  transition:transform 200ms var(--ease-out);
  flex-shrink:0;
}
.rl-learn .rl-collapsible.is-open .rl-collapsible-chev{ transform:rotate(180deg); }
.rl-learn .rl-collapsible-body[hidden]{ display:none; }
.rl-learn .rl-collapsible-body{
  padding:0 var(--rl-sp-4) var(--rl-sp-3);
}
.rl-learn #more-explanation > section .description{
  /* 카드 안 본문 — 학습 본문 사이즈 그룹 quiz-e 토큰(기본 16). 줄 높이는 lh-normal로 압축. */
  font-size:var(--rl-fs-quiz-e); line-height:var(--rl-lh-normal);
  color:var(--rl-ink); letter-spacing:var(--rl-ls-tight);
  word-break:keep-all;
  overflow-wrap:break-word;
  display:block; -webkit-line-clamp:unset;
  overflow:visible;
}

/* disclaimer — 짧고 연한 톤(사용자 명세). PHP에서 <p class="disclaimer">로 단일 문장 직속, ul/li 제거.
   view.css 룰 specificity 정합 위해 #explanation-section 셀렉터 포함. */
.rl-learn .disclaimer,
.rl-learn #explanation-section .disclaimer{
  margin:var(--rl-sp-3) 0 0;
  padding:0;
  background:transparent; border:0;
  font-size:var(--rl-fs-caption-sm);
  color:var(--rl-text-3);
  line-height:var(--rl-lh-snug);
  letter-spacing:var(--rl-ls-tight);
  text-align:center;
}

/* 상세 풀이 토글 #more-explanation-btn — 시안 explain-toggle.
   view.css에 #more-explanation-btn{background:rgba(220,20,60,.75); border:1px solid; color:#fff; min-width:80; padding:6px 24; ...}
   + :hover/:active{background:#dc143c} 가 시안 톤(투명 배경 + 보라 텍스트)을 침범하므로 specificity 1,1,0 → 1,2,0/2,2 로 끌어 올려 모든 상태에서 reset. */
.rl-learn #more-explanation-btn{
  display:flex; align-items:center; justify-content:center; gap:6px;
  width:100%; margin:8px 0 0; padding:12px 0;
  min-height:44px;
  border:0; border-top:1px solid var(--rl-accent-edge);
  background:transparent;
  font-family:inherit; font-size:var(--rl-fs-label); font-weight:600;
  color:var(--rl-primary);
  cursor:pointer;
  transition:color var(--rl-dur-micro);
  min-width:0;
}
.rl-learn #more-explanation-btn:hover,
.rl-learn #more-explanation-btn:focus,
.rl-learn #more-explanation-btn:active{
  color:var(--rl-primary-hover);
  background:transparent;
  border:0; border-top:1px solid var(--rl-accent-edge);
  transform:none;
}

/* 보조 하단 접기 버튼 — 시안 .explain-toggle.is-bottom */
.rl-learn .rl-more-collapse{
  display:flex; align-items:center; justify-content:center; gap:6px;
  width:100%; margin:6px 0 0; padding:11px 0;
  min-height:44px;
  border:0; border-top:1px dashed var(--rl-accent-edge);
  background:transparent;
  font-family:inherit; font-size:var(--rl-fs-caption); font-weight:600;
  color:var(--rl-text-3);
  cursor:pointer;
  transition:color var(--rl-dur-micro);
}
@media (hover: hover) {
  .rl-learn .rl-more-collapse:hover{ color:var(--rl-primary); }
}
.rl-learn .rl-more-collapse:active{ color:var(--rl-primary); }

/* 비회원 가입 유도 카드 */
.rl-learn .cta-wrap{
  margin:10px 0 4px; padding:14px;
  background:var(--rl-surface);
  border:1px solid var(--rl-accent-edge);
  border-radius:var(--rl-r-btn);
  text-align:center;
}
.rl-learn .cta-wrap .login-lock{
  display:inline-flex; align-items:center; justify-content:center; gap:4px;
  height:var(--rl-h-btn-md); padding:0 18px;
  background:var(--rl-primary); color:var(--rl-on-primary);
  font-size:var(--rl-fs-label); font-weight:700;
  border-radius:var(--rl-r-md);
  text-decoration:none;
  letter-spacing:var(--rl-ls-body);
}
@media (hover: hover) {
  .rl-learn .cta-wrap .login-lock:hover{ background:var(--rl-primary-hover); color:var(--rl-on-primary); }
}
.rl-learn .cta-wrap .login-lock:active{ background:var(--rl-primary-hover); color:var(--rl-on-primary); }
.rl-learn .cta-wrap .login-lock strong{ color:inherit; font-weight:700; }
.rl-learn .cta-wrap .cta-sub{
  margin:10px 0 0;
  font-size:var(--rl-fs-caption); color:var(--rl-text-3);
  line-height:var(--rl-lh-snug);
}

/* 검토 중 안내 — 강한 경고 박스에서 본문 흐름에 묻히는 보조 안내 바로 톤 다운(사용자 명세).
   배경 warn-soft 유지(노랑/베이지), 테두리·왼쪽 4px strap·아이콘 제거, 굵기 낮춤. */
.rl-learn .review-warning{
  margin:0 0 var(--rl-sp-3);
  padding:var(--rl-sp-2) var(--rl-sp-3);
  background:var(--rl-warn-soft);
  border:0;
  border-radius:var(--rl-r-btn);
  color:var(--rl-warn-text);
  font-size:var(--rl-fs-caption-sm);
  font-weight:500;
  line-height:var(--rl-lh-normal);
  letter-spacing:var(--rl-ls-tight);
  word-break:keep-all;
  overflow-wrap:break-word;
}

/* === 보기 카드 (.answer) — 시안 .choice 톤 ===
   원 view.css의 ::before(①②③④) + 내부 div left margin 20 구조를 grid(28 / 1fr / 22)로 변환.
   번호는 ::before content를 1·2·3·4로 덮어쓰고, 오른쪽 선택 marker는 ::after로 그린다.
   raw px는 컴포넌트 sub-scale(28/22)만 잔존 — spacing/border는 시스템 토큰 사용. */
.rl-learn .answer-container{
  display:flex; flex-direction:column; gap:var(--rl-sp-1);
  margin:var(--rl-sp-5) 0 0; padding:0;
}
.rl-learn .answer-container .answer{
  display:grid !important;
  grid-template-columns:28px 1fr 22px;
  align-items:center; gap:var(--rl-sp-3);
  margin:0 !important;
  padding:var(--rl-sp-2) !important;
  background:var(--rl-surface);
  border:1px solid var(--rl-line-2) !important;
  border-radius:var(--rl-r-md);
  cursor:pointer;
  transition:border-color var(--rl-dur-micro), background var(--rl-dur-micro), transform 120ms;
  min-height:var(--rl-h-btn-md);
  position:relative;
  font-size:var(--rl-fs-quiz-a); color:var(--rl-text);
  line-height:var(--rl-lh-relaxed);
  word-break:keep-all;
  /* grid 1fr 셀: 어절 단위 줄바꿈 유지하되 띄어쓰기 없는 긴 토큰은 폭 초과 시 강제 분리(min-content 축소 필요 → anywhere) */
  overflow-wrap:anywhere;
}
@media (hover: hover) {
  .rl-learn .answer-container .answer:hover{ background:var(--rl-surface-2); }
}
.rl-learn .answer-container .answer:active{ background:var(--rl-surface-2); transform:scale(.997); }

/* 번호 ::before — view.css의 ①②③④ + float:left 룰을 시안 plain Arabic으로 덮어씀 (specificity 0,4,1+pseudo).
   보조 톤(text-2)으로 — 보기 텍스트보다 한 단계 약하지만 너무 흐리지 않게 위계 유지. */
.rl-learn .view-content .answer-container > .answer::before{
  float:none !important;
  margin:0 !important;
  grid-column:1; grid-row:1;
  align-self:center; justify-self:center;
  font-weight:700; font-size:var(--rl-fs-label);
  color:var(--rl-text-2);
  font-variant-numeric:tabular-nums;
  line-height:1;
}
.rl-learn .view-content .answer-container > .answer:nth-child(1)::before{ content:"1" !important; }
.rl-learn .view-content .answer-container > .answer:nth-child(2)::before{ content:"2" !important; }
.rl-learn .view-content .answer-container > .answer:nth-child(3)::before{ content:"3" !important; }
.rl-learn .view-content .answer-container > .answer:nth-child(4)::before{ content:"4" !important; }
.rl-learn .view-content .answer-container > .answer:nth-child(5)::before{ content:"5" !important; }
/* 선택(checked) 상태에서 view.css가 content:"●" !important로 바꾸는 것을 다시 원래 숫자로 복원 — 시안은 ●가 아니라 .mark 원이 표시 역할 */
.rl-learn .view-content .answer-container > .checked:nth-child(1)::before{ content:"1" !important; }
.rl-learn .view-content .answer-container > .checked:nth-child(2)::before{ content:"2" !important; }
.rl-learn .view-content .answer-container > .checked:nth-child(3)::before{ content:"3" !important; }
.rl-learn .view-content .answer-container > .checked:nth-child(4)::before{ content:"4" !important; }
.rl-learn .view-content .answer-container > .checked:nth-child(5)::before{ content:"5" !important; }

/* answer 내부 텍스트 div — view.css가 margin-left:20 강제. grid 환경에선 0으로.
   답안 실 텍스트는 이 자식 div에 들어감 — 외곽 .answer 토큰을 거치지 않고 자식이 직접 cascade를 잡아야
   하므로 quiz-a 토큰을 자식 div selector에 직접 적용 (외곽 .answer와 동일 토큰 단일 출처). */
.rl-learn .view-content .answer-container .answer > div{
  margin-left:0 !important;
  grid-column:2; grid-row:1;
  font-size:var(--rl-fs-quiz-a);
  line-height:var(--rl-lh-relaxed);
  color:var(--rl-text);
  font-weight:500;
}
.rl-learn .view-content .answer-container .answer > div p,
.rl-learn .view-content .answer-container .answer > div span{
  margin:0; line-height:var(--rl-lh-relaxed);
  /* 텍스트 말단까지 anywhere 강제: grid 1fr 트랙이 좁아지려면 말단 min-content 축소 필요.
     글로벌 .rl-learn p의 break-word(min-content 미축소)를 더 높은 specificity로 덮어씀 */
  overflow-wrap:anywhere;
}

/* 우측 선택 mark (::after) — 시안 .mark 22px 원 (sub-component scale 유지). */
.rl-learn .answer-container .answer::after{
  content:"";
  grid-column:3; grid-row:1;
  width:22px; height:22px; border-radius:50%;
  border:1px solid var(--rl-line-2);
  background:var(--rl-surface);
  display:flex; align-items:center; justify-content:center;
  /* background-color/border-color 0.15s — 사용자 명세 "흰→연한 색 부드러운 전환". transform pop은 ::after 자체 애니메이션이 담당. */
  transition:border-color 150ms var(--ease-out), background 150ms var(--ease-out);
  align-self:center; justify-self:center;
}

/* 셀 본체 색상 transition — checked/correct/incorrect 클래스 부착 시 부드러운 fill 전환(0.15s). */
.rl-learn .answer-container .answer{
  transition:background-color 150ms var(--ease-out), border-color 150ms var(--ease-out), color 150ms var(--ease-out);
}

/* selected 상태 — 디자인 시스템 §2.1.1: background primary-soft + border primary-edge.
   강조는 ::after mark(primary solid + 흰 점) + ::before 번호 색(primary)가 담당. */
.rl-learn .answer-container .answer.checked{
  border-color:var(--rl-primary-edge) !important;
  background:var(--rl-primary-soft) !important;
}
.rl-learn .view-content .answer-container > .checked::before{
  color:var(--rl-primary);
}
.rl-learn .answer-container .answer.checked::after{
  border-color:var(--rl-primary);
  background:var(--rl-primary);
  /* 안쪽 dot — radial gradient 4px 반지름 흰 점(on-primary 토큰). */
  background-image:radial-gradient(circle, var(--rl-on-primary) 0 4px, transparent 4.5px);
}

/* graded — 정답 / 오답 색 + ✓/× 아이콘.
   사용자 명세: 배경 tint·번호·아이콘은 그대로, 본문 텍스트만 기본색(ink)로 톤 다운 — 장시간 반복 풀이 시 시각 부담 감소.
   "경고/실패" 톤이 아닌 "학습 피드백" 톤으로. */
.rl-learn .answer-container .answer.correct{
  border-color:var(--rl-grade-correct-edge) !important;
  background:var(--rl-grade-correct-bg) !important;
  color:var(--rl-ink);
  font-weight:600;
}
.rl-learn .view-content .answer-container > .correct::before{ color:var(--rl-grade-correct-accent); }
.rl-learn .view-content .answer-container .answer.correct > div{
  color:var(--rl-ink); font-weight:600;
}
.rl-learn .answer-container .answer.correct::after{
  content:"✓";
  border-color:var(--rl-grade-correct-accent); background:var(--rl-grade-correct-accent);
  background-image:none;
  /* SVG 체크 — 인라인 mask 처리 대신 단순 텍스트 ✓ 사용 */
  font-size:var(--rl-fs-label); font-weight:800; color:var(--rl-on-primary);
  line-height:1;
  /* 아이콘 pop — 1→1.18→1, 120ms. 셀 색상 전환(0.15s) 직후 발화하도록 0.08s 지연. */
  animation:rl-icon-pop 120ms 80ms var(--ease-out) both;
}
/* "정답" chip 폐기 — 채점 후 정/오답은 ::after 아이콘(✓/×) + border/background 색으로 충분 인지.
   chip은 중복 위계로 시각 노이즈. 라벨 면적 회복 시 본문 가독성·세로 공간 효율 향상. */

/* view.css의 .incorrect{ font-weight:normal !important; opacity:0.5; color:#888 } 가
   본문 wrong choice를 50% 투명·400 weight로 만들어버림. 시안은 .is-wrong .txt color:var(--bad)
   font-weight:500 (choice .txt 기본 weight 유지) → opacity 복원 + inner div font-weight 500 강제. */
.rl-learn .answer-container .answer.incorrect{
  border-color:var(--rl-grade-wrong-edge) !important;
  background:var(--rl-grade-wrong-bg) !important;
  color:var(--rl-ink);
  opacity:1 !important;
  filter:none !important;
}
.rl-learn .view-content .answer-container > .incorrect::before{ color:var(--rl-grade-wrong-accent); }
.rl-learn .view-content .answer-container .answer.incorrect > div{
  color:var(--rl-ink);
  font-weight:500 !important;
}
.rl-learn .answer-container .answer.incorrect::after{
  content:"×";
  border-color:var(--rl-grade-wrong-accent-soft); background:var(--rl-grade-wrong-accent-soft);
  background-image:none;
  font-size:var(--rl-fs-label); font-weight:800; color:var(--rl-on-primary);
  line-height:1;
  /* 아이콘 pop — correct와 동일 keyframe·duration. 오답은 정답 표시 80ms 지연이라 자연스럽게 시각 우선 노출. */
  animation:rl-icon-pop 120ms var(--ease-out) both;
}

/* 공용 keyframe — 셀의 ::after(✓/×) pop. 1→1.18→1 짧고 가벼운 강조. */
@keyframes rl-icon-pop {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.18); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .rl-learn .answer-container .answer.correct::after,
  .rl-learn .answer-container .answer.incorrect::after { animation: none; }
}
/* "내 답" chip 폐기 — "정답" chip과 동일 사유. ::after × 아이콘 + bad-soft 배경으로 오답 명확. */

/* 본문 .question — 시안 qtext 톤 */
.rl-learn .question{
  font-size:var(--rl-fs-bodylg);
  line-height:var(--rl-lh-relaxed);
  font-weight:500;
  color:var(--rl-ink);
  letter-spacing:var(--rl-ls-tight);
  word-break:keep-all;
  overflow-wrap:break-word;
  margin:14px 0 0;
}

/* === 채점 후 상태 행 (.rl-grade-status) — 문제 본문↔보기 사이 3 chip 자리 ===
   [정답률 N%] [정답·내 답 X번/정답 Y번] [풀이 보기]
   초기 hidden 속성으로 미노출 → evaluateAnswers/restoreAnsweredState가 hidden 제거 + result chip 텍스트 채움.
   renderQuestionFromHtml(fresh swap)에서 hidden 재부여 + result 비움.
   등장 애니메이션: fade-in + 6px slide-down(0.2s) — "새 정보가 열렸다" 신호. */
.rl-grade-status {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--rl-sp-3);
  margin: var(--rl-sp-4) 0;
  padding: 0 var(--rl-sp-3);
  /* 한 덩어리 등장 — opacity + 작은 translateY + max-height reveal. stagger·scale pop 없음(사용자 명세).
     overflow:hidden + max-height 0→충분히 큰 값(60px) 트랜지션으로 보기 목록이 함께 내려가는 시각. */
  overflow: hidden;
  animation: rl-status-enter 260ms var(--ease-out) both;
}
/* 3-column 영역 정렬 — 정답률(좌측 col 좌측), 결과(중앙 col 중앙), 풀이(우측 col 우측). 좌-중-우 위계 분리. */
.rl-grade-status .rl-gs-accuracy { justify-self: start; }
.rl-grade-status .rl-gs-result { justify-self: center; }
.rl-grade-status .rl-gs-explain { justify-self: end; }
.rl-grade-status[hidden] { display: none; }
@keyframes rl-status-enter {
  from {
    opacity: 0;
    transform: translateY(-4px);
    max-height: 0;
    margin-top: 0;
    margin-bottom: 0;
  }
  to {
    opacity: 1;
    transform: translateY(0);
    max-height: 60px;
    margin-top: var(--rl-sp-4);
    margin-bottom: var(--rl-sp-4);
  }
}
@media (prefers-reduced-motion: reduce) {
  .rl-grade-status { animation: none; }
}
.rl-gs-chip {
  display: inline-flex;
  align-items: center;
  padding: var(--rl-sp-1) var(--rl-sp-3);
  font-size: var(--rl-fs-caption);
  font-weight: 600;
  line-height: 1.4;
  border-radius: var(--rl-r-full);
  border: 1px solid var(--rl-line-2);
  background: var(--rl-surface);
  color: var(--rl-text-2);
  letter-spacing: var(--rl-ls-tight);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* 정답률 — 가장 낮은 위계(정보 톤). pill 외형 제거: 무배경/무border + 회색 텍스트.
   결과 pill·풀이 버튼과 같은 부류로 오인되지 않도록 가벼운 라벨. */
.rl-gs-accuracy {
  padding: var(--rl-sp-1) 0;
  font-weight: 500;
  color: var(--rl-text-3);
  background: transparent;
  border-color: transparent;
}
/* 결과 chip — 색상·마킹 없이 .rl-gs-chip 중립 톤 그대로(사용자 명세).
   보기 셀이 이미 빨강/초록으로 정/오답 시각 충분 — 결과 pill은 요약 텍스트만 담당, 색 분기·라벨 강조 없음.
   scale pop 폐기 — 결과줄 전체가 한 덩어리로 height reveal로 등장, 개별 강조 없음. */
/* 마스터 상태 — 문항 마스터(3연속 정답) 시 '마스터'를 먼저 노출. 시험지 정답 마커(.answer.correct::after ✓)와
   동일 초록(--rl-grade-correct-accent) + 흰 글씨. 일정 시간 뒤 .is-flipping 세로 플립으로 '정답' 평문 톤 복귀(JS). */
.rl-gs-result.is-master {
  background: var(--rl-grade-correct-accent);
  border-color: var(--rl-grade-correct-accent);
  color: var(--rl-on-primary);
}
/* 세로 플립 — 모서리로 서는 중간 지점(50%)에서 JS가 텍스트·톤 교체. backface 숨김 불필요(텍스트 1줄 교체형). */
.rl-gs-result.is-flipping { animation: rl-gs-flip var(--rl-dur-sheet) var(--rl-ease-out); }
@keyframes rl-gs-flip {
  0%   { transform: perspective(360px) rotateX(0deg); }
  50%  { transform: perspective(360px) rotateX(90deg); }
  100% { transform: perspective(360px) rotateX(0deg); }
}
/* 풀이 보기 — 텍스트 버튼(pill 외형 제거). 하단 #scoring "다음 문제" 메인 CTA 대비 한 톤 낮춤 — 보조 액션 위계.
   primary-light + weight 500 + underline 없음으로 "누를 수 있되 강조는 아님" 시각. chevron으로 액션 신호 유지. */
.rl-gs-explain {
  appearance: none;
  cursor: pointer;
  font-family: inherit;
  padding: var(--rl-sp-1) 0;
  background: transparent;
  border-color: transparent;
  color: var(--rl-primary-light);
  font-weight: 500;
  gap: 2px;
  transition: color var(--rl-dur-micro) var(--ease-out);
}
@media (hover: hover) {
  .rl-gs-explain:hover { color: var(--rl-primary); }
}
.rl-gs-explain:focus-visible {
  outline: 2px solid var(--rl-primary);
  outline-offset: 2px;
  border-radius: var(--rl-r-sm);
}
.rl-gs-explain.is-open {
  color: var(--rl-primary);
}

/* === 다크 모드 — 채점 후 카드 영역 한정 토큰 재정의 ===
   라이트 톤은 사용자 명세상 보존(--rl-grade-correct-accent / --rl-grade-wrong-accent-soft 등
   ✓/× 아이콘 채움은 다크에서도 동일 채도 유지). 텍스트·border·tint만 다크 캔버스에 맞춰 반전.
   스코프: .rl-learn .answer-container (정/오답 셀) + .rl-grade-status (정답률·결과·풀이 chip).
   tint(grade-correct-bg / grade-wrong-bg / 각 edge)는 라이트 hex 그대로 두면 다크 surface 위
   거의 흰 면 → alpha 기반으로 재정의해 어두운 surface 위 약한 색감 tint로 동등 효과.
   modal.css §다크 토큰 재정의(L672-709) 동일 패턴 — design-system §7.2.3 1차 점진 승격
   마이그레이션 종료 전까지 컴포넌트 단위 패치. learn-tokens.css 전역 다크 추가는 학습 페이지
   전반 회귀 위험이라 보류, 사용자 보고 범위(채점 카드)만 한정. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) :is(.rl-learn .answer-container, .rl-grade-status) {
    --rl-ink: #F8FAFC;
    --rl-text: #E2E8F0;
    --rl-text-2: #A8B3C7;
    --rl-text-3: #7E8AA0;
    --rl-line-2: #2A3450;
    --rl-surface: #131A2B;
    --rl-primary: #3B82F6;
    --rl-primary-light: #93C5FD;
    --rl-grade-correct-bg: rgba(34,197,94,.10);
    --rl-grade-correct-edge: rgba(34,197,94,.32);
    --rl-grade-wrong-bg: rgba(239,68,68,.10);
    --rl-grade-wrong-edge: rgba(239,68,68,.32);
  }
}
:root[data-theme="dark"] :is(.rl-learn .answer-container, .rl-grade-status) {
  --rl-ink: #F8FAFC;
  --rl-text: #E2E8F0;
  --rl-text-2: #A8B3C7;
  --rl-text-3: #7E8AA0;
  --rl-line-2: #2A3450;
  --rl-surface: #131A2B;
  --rl-primary: #3B82F6;
  --rl-primary-light: #93C5FD;
  --rl-grade-correct-bg: rgba(34,197,94,.10);
  --rl-grade-correct-edge: rgba(34,197,94,.32);
  --rl-grade-wrong-bg: rgba(239,68,68,.10);
  --rl-grade-wrong-edge: rgba(239,68,68,.32);
}

/* === Round Result Card — showRoundResult 결과(라운드 완료) ===
   목적: "라운드 종료 → 보상 확인 → 완료" 흐름. 다음 행동 다수 제시 X, 보상 + 단일 CTA 단일 surface.
   page/scoring.php의 카드(.rl-scoring) UI/애니메이션과 정합 — brand → title → reward → meta → CTA → notice.
   body.is-round-result 활성 시 chrome(appbar/bottomtab) 가림 + at-content 중앙 정렬 (수직/수평). */

/* Chrome 가림 — body.is-round-result 활성 시 상단 App Bar / 하단 Bottom Tab + APMS 자동 chrome + 페이지 본문 형제 비노출.
   .amina-header / .view-wrap / .rl-actions는 note.php가 .at-content 직속에 두는 형제들 — 미가림 시
   카드가 .at-content 직속이라도 형제 높이만큼 위로 밀리고, 특히 .rl-actions(#scoring "완료" 라벨)이
   라운드 마지막 채점 후 활성 상태(.can-scoring)로 viewport 상단에 노출되어 결과 카드와 중복 CTA가 됨.
   selector specificity (0,2,1) > mobile-nav.css의 .rl-mnav-enabled .rl-mnav-appbar (0,2,0). */
body.is-round-result .rl-mnav-appbar,
body.is-round-result .rl-mnav-bottomtab,
body.is-round-result .at-title,
body.is-round-result .at-links,
body.is-round-result .amina-header,
body.is-round-result .view-wrap,
body.is-round-result .rl-actions {
  display: none;
}
/* scoring(page/scoring.php)과 정합 — .at-content 상하 패딩과 .at-container 좌우 패딩을 0으로 회수해
   .rl-round-page 래퍼가 viewport 풀폭/풀높이를 단독 점유하게 한다. raw px X — page-shell.css가 14px 정의한
   .at-container padding-inline을 명시 override(!important). */
body.is-round-result .at-content {
  padding-top: 0;
  padding-bottom: 0;
}
body.is-round-result .at-body .at-container {
  padding-inline: 0 !important;
}

/* 페이지 래퍼 — 카드 단독 viewport 수직 중앙 정렬.
   position:fixed로 부모 .at-content의 오프셋(top:40px 등)을 우회. 가로는 page-shell 컨테이너(--rl-page-container, fallback 768px)
   폭에 맞춰 중앙 정렬 — 데스크탑(≥769)에서 풀폭 점유로 wrapper card 메타포 깨짐 방지(body #ECEEF1 좌우 노출).
   chrome(border/shadow)은 부착 X — page-shell wrapper가 이미 ≥769에서 chrome을 가지고 있고 round-page가
   wrapper와 정확히 동일 폭으로 정렬되므로 wrapper의 shadow가 round-page 외곽에 자연 노출(중첩 방지).
   iOS 동적 chrome 대비 vh→svh→dvh 단계 fallback은 height에 적용. */
.rl-round-page {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  max-width: var(--rl-page-container, 768px);
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100vh;
  height: 100svh;
  height: 100dvh;
  padding: var(--rl-sp-5);
  box-sizing: border-box;
  background: var(--rl-surface);
}

/* 카드 밖 하단 광고(가산 레이어, §4.12.D) — quick/note 라운드 결과. 슬롯 자체의 그룹 간격(24px)·중앙정렬은
   rl-ad.css 단일 출처가 담당. .rl-round-page는 flex column(align-items:center)이라 빈 슬롯이 교차축 0폭으로
   측정돼 width-floor 위반(suppress)되므로 카드(.rl-round-result)와 동일 폭으로 명시 — 0폭 붕괴 방지 + 카드 정렬. */
.rl-round-page > .rl-ad-slot--display {
  width: 100%;
  max-width: 480px;
}
/* 광고가 더해져 카드+광고 그룹이 작은 화면에서 viewport를 초과할 때만 대응: 중앙정렬 유지하되 넘치면
   스크롤(고정 컨테이너 상단 클립 방지). 광고 off/collapse면 :has 비매치 → 단독 카드 동작 그대로(scoring.php 무영향). */
.rl-round-page:has(> .rl-ad-slot--display:not([data-rl-ad-collapsed])) {
  justify-content: safe center;
  overflow-y: auto;
}

/* 라운드 결과 슬롯 — 로더/결과 카드를 감싸 로더↔카드 교체를 한 자리에서 처리한다.
   flex:0 0 auto = 슬롯 높이를 카드 실제 콘텐츠 높이에 맞춤(고정/풀높이 예약 금지, 문구에 따라 가변).
   슬롯+광고는 .rl-round-page의 group 중앙정렬을 그대로 받아 24px 간격(광고 margin-top sp-6, rl-ad.css
   단일 출처) 묶음으로 화면 수직 중앙 배치. 카드+광고가 viewport 초과 시 round-page가 스크롤(:has overflow).
   note/scoring 직접 카드와 동일한 group 중앙정렬 — 카드 높이만큼만 점유. */
.rl-round-page__slot {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  /* 최소 카드 영역 — 로딩(로더 ~99px) 단계부터 결과 카드의 최소 높이만큼 자리를 잡아, 카드 등장 시
     슬롯 성장폭(=묶음 재중앙정렬에 따른 광고 이동폭)을 최소화한다. 측정된 최소 결과 카드
     (brand+title+subject+bonus+CTA ≈ 224)보다 약간 보수적 — 실 카드는 전부 이 값 이상이라 빈 예약공간
     없이 '카드 높이에 맞춤'을 유지하면서 로더 자리만 미리 확보. 값은 root-tokens.css 단일 출처(§3.8.8,
     매직 넘버 금지/§8.5.3 P1). 잔여 이동은 JS FLIP으로 부드럽게(§8.5.3 동적 레이아웃). */
  min-height: var(--h-round-result-slot-floor);
}

/* 카드 — scoring(.rl-scoring) chrome 정합. surface-elev로 wrapper(--rl-surface) 위 lift. */
.rl-round-result {
  width: 100%;
  max-width: 480px;
  margin: 0;
  padding: var(--rl-sp-6) var(--rl-sp-5);
  background: var(--rl-surface-elev);
  border: 1px solid var(--rl-line-2);
  border-radius: var(--rl-r-lg);
  box-shadow: var(--rl-shadow-md);
  text-align: center;
  box-sizing: border-box;
}
@media (max-width: 480px) {
  .rl-round-result {
    padding: var(--rl-sp-5) var(--rl-sp-4);
    border-radius: var(--rl-r-md);
  }
}

/* 상단 라벨 — caption 톤, 보조 위계. 카드 정체성 신호. scoring.css와 동일 룰. */
.rl-round-result .rl-rr-brand {
  margin: 0 0 var(--rl-sp-2);
  font-size: var(--rl-fs-caption);
  font-weight: 500;
  color: var(--rl-text-3);
}

/* 핵심 타이틀 — h2 토큰. "이번 라운드가 끝났어요" 첫 시선 전달. */
.rl-round-result .rl-rr-title {
  margin: 0 0 var(--rl-sp-3);
  font-size: var(--rl-fs-h2);
  font-weight: 700;
  color: var(--rl-ink);
  letter-spacing: var(--rl-ls-h2);
  line-height: var(--rl-lh-tight);
}

/* 보상 stack — note.php는 subject/bonus를 .rl-rr-reward <p> 안에 inline span으로 묶어 렌더.
   flex column으로 자식 span을 별도 라인으로 잡아야 .rl-rr-subject/.rl-rr-bonus의 margin-bottom이 실효(span은 inline → margin-bottom 무효 회피).
   특히 score=0(전부 숨김) 케이스에서 subject + "이번 라운드 기록이 반영됐어요"가 한 줄로 붙던 회귀 차단. */
.rl-round-result .rl-rr-reward {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 0;
}

/* 과목명 — title 직후 보조 라인. caption 톤 (보조 위계). */
.rl-round-result .rl-rr-subject {
  margin: 0 0 var(--rl-sp-5);
  font-size: var(--rl-fs-caption);
  font-weight: 400;
  color: var(--rl-text-3);
  line-height: var(--rl-lh-snug);
}
/* reward 묶음 안 subject↔bonus는 같은 성격(라운드 정체성 + 결과 안내) → 호흡 좁힘.
   외부(quick.php) 컨텍스트의 sp-5(=16px)는 다음 그룹 separator라 유지, reward 안에서만 override. */
.rl-round-result .rl-rr-reward .rl-rr-subject {
  margin-bottom: var(--rl-sp-1);
}
/* reward→mastery group separator — 외부(quick.php) bonus→action 24px는 CTA 직전 호흡이라 유지,
   reward 안 bonus는 카드 전체 group rhythm(title→reward 12 / mastery→meta 14 / meta→action 12)에
   맞춰 16으로 정렬. chrome 호흡(card padding sp-6)은 미변경 — 사용자 "고급스러움" 유지. */
.rl-round-result .rl-rr-reward .rl-rr-bonus {
  margin-bottom: var(--rl-sp-5);
}

/* 정답 카운트 라인 — "5문항 중 3문항 정답". 결과의 핵심 정보라 body / 600 / ink로 강조. */
.rl-round-result .rl-rr-meta {
  margin: 0 0 var(--rl-sp-3);
  font-size: var(--rl-fs-body);
  font-weight: 600;
  color: var(--rl-ink);
  line-height: var(--rl-lh-normal);
  font-variant-numeric: tabular-nums;
}

/* "마스터" 단어 X — feedback_quick_learning_metric_policy. */
.rl-round-result .rl-rr-familiar {
  width: fit-content;
  max-width: 100%;
  margin: 0 auto var(--rl-sp-4);
  padding: var(--rl-sp-2) var(--rl-sp-3);
  background: var(--rl-primary-soft);
  color: var(--rl-primary);
  border-radius: var(--rl-r-md);
  font-size: var(--rl-fs-body);
  line-height: var(--rl-lh-snug);
}
.rl-round-result .rl-rr-familiar strong {
  font-weight: 800;
}

.rl-round-result .rl-rr-mastery {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 0 0 var(--rl-sp-4);
}
.rl-round-result .rl-rr-mastery-label {
  margin: 0;
  font-size: var(--rl-fs-caption);
  font-weight: 500;
  color: var(--rl-text-3);
  line-height: var(--rl-lh-snug);
}
.rl-round-result .rl-rr-mastery-value {
  margin: 0;
  font-size: var(--rl-fs-num-display);
  font-weight: 800;
  color: var(--rl-ink);
  line-height: var(--rl-lh-tight);
  letter-spacing: var(--rl-ls-display);
  font-variant-numeric: tabular-nums;
}

/* 보상 라인 — 3종 사용: (a) note.php score>0 = label+value 한 줄 reward 수치 / (b) note.php score=0 (`--zero`) 단일 안내 카피 / (c) quick.php 단일 안내 카피.
   inline-flex + baseline + gap은 (a)에서 label↔value 호흡, (b)(c)는 단일 자식이라 시각 무영향(단일 flex item은 자연 렌더).
   기존 base 톤(body/500/text-2)은 (b)(c)에 그대로 상속, (a)는 자식 label/score가 override. .rl-rate 패턴과 동일 토큰 사용. */
.rl-round-result .rl-rr-bonus {
  display: inline-flex;
  align-items: baseline;
  gap: var(--rl-sp-2);
  margin: 0 0 var(--rl-sp-6);
  font-size: var(--rl-fs-body);
  font-weight: 500;
  color: var(--rl-text-2);
  line-height: var(--rl-lh-snug);
}
.rl-round-result .rl-rr-bonus-label {
  font-size: var(--rl-fs-caption);
  font-weight: 500;
  color: var(--rl-text-3);
  line-height: var(--rl-lh-snug);
}
.rl-round-result .rl-rr-score {
  font-size: var(--rl-fs-num-meta);
  font-weight: 800;
  color: var(--rl-primary);
  line-height: var(--rl-lh-snug);
  letter-spacing: var(--rl-ls-num);
  font-variant-numeric: tabular-nums;
}

/* CTA 슬롯 — 단일 primary, scoring.css와 동일 메트릭.
   하단 마진 제거(v1.52.2) — 보조 문구 ".rl-rr-notice" 폐기 이후 카드 마지막 element라 외측 호흡 0. */
.rl-round-result .rl-rr-action {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--rl-h-btn-lg);
  margin: 0;
}
.rl-round-result .rl-rr-cta {
  appearance: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: var(--rl-h-btn-lg);
  padding: 0 var(--rl-sp-5);
  background: var(--rl-primary);
  color: var(--rl-on-primary);
  border: 0;
  border-radius: var(--rl-r-btn);
  font-family: inherit;
  font-size: var(--rl-fs-body);
  font-weight: 700;
  letter-spacing: var(--rl-ls-body);
  transition: background var(--rl-dur-micro) var(--ease-out);
}
@media (hover: hover) {
  .rl-round-result .rl-rr-cta:hover { background: var(--rl-primary-hover); }
}
.rl-round-result .rl-rr-cta:active { background: var(--rl-primary-hover); }
.rl-round-result .rl-rr-cta:focus-visible {
  outline: 2px solid var(--rl-primary);
  outline-offset: 2px;
}

/* 진입 stagger — brand/title은 즉시, 정보 라인은 호흡 두고 순차.
   bonus 직전 familiar(있을 때) 라인 자연 도입. 자세 시퀀스는 quick.php applyRoundResultStagger와 정합. */
.rl-round-result {
  animation: rl-round-card-enter 650ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.rl-round-result .rl-rr-brand    { animation: rl-rr-fade   500ms 150ms  cubic-bezier(0.22, 1, 0.36, 1) both; }
.rl-round-result .rl-rr-title    { animation: rl-rr-up     550ms 200ms  cubic-bezier(0.22, 1, 0.36, 1) both; }
.rl-round-result .rl-rr-subject  { animation: rl-rr-fade   500ms 250ms  cubic-bezier(0.22, 1, 0.36, 1) both; }
.rl-round-result .rl-rr-meta     { animation: rl-rr-presolved 800ms 700ms cubic-bezier(0.22, 1, 0.36, 1) both; }
.rl-round-result .rl-rr-familiar { animation: rl-rr-up     600ms 1200ms cubic-bezier(0.22, 1, 0.36, 1) both; }
.rl-round-result .rl-rr-bonus    { animation: rl-rr-fade   500ms 1700ms cubic-bezier(0.22, 1, 0.36, 1) both; }
.rl-round-result .rl-rr-mastery  { animation: rl-rr-up     600ms 1100ms cubic-bezier(0.22, 1, 0.36, 1) both; }
.rl-round-result .rl-rr-action   { animation: rl-rr-activate 600ms 2300ms cubic-bezier(0.22, 1, 0.36, 1) both; }
/* CTA 1회 ring pulse — 점수 카운트업·액션 활성화가 모두 끝난 직후(2900ms~) 한 번만, 반복 없음.
   scoring.css의 .rl-scoring__cta 패턴과 동일 — box-shadow 반경 0→12 transparent로 외곽 ring 확산. */
.rl-round-result .rl-rr-cta {
  animation: rl-rr-cta-pulse 720ms 2900ms var(--ease-out) both;
}

@keyframes rl-round-card-enter {
  from { opacity: 0; transform: translateY(18px) scale(0.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes rl-rr-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes rl-rr-up {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* "처음부터 자리만 있다가 선명해짐" — 메타·안내·버튼 활성화에 사용. opacity 시작값을 0이 아닌 부분 노출로 둠. */
@keyframes rl-rr-presolved {
  from { opacity: 0.4; }
  to   { opacity: 1; }
}
@keyframes rl-rr-presolved-soft {
  from { opacity: 0.45; }
  to   { opacity: 1; }
}
@keyframes rl-rr-activate {
  from { opacity: 0.4; }
  to   { opacity: 1; }
}
@keyframes rl-rr-cta-pulse {
  0%   { box-shadow: 0 0 0 0 var(--rl-primary-edge); }
  100% { box-shadow: 0 0 0 12px transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .rl-round-result,
  .rl-round-result .rl-rr-brand,
  .rl-round-result .rl-rr-title,
  .rl-round-result .rl-rr-subject,
  .rl-round-result .rl-rr-meta,
  .rl-round-result .rl-rr-familiar,
  .rl-round-result .rl-rr-bonus,
  .rl-round-result .rl-rr-mastery,
  .rl-round-result .rl-rr-action,
  .rl-round-result .rl-rr-cta {
    animation: none !important;
  }
}

/* === Settings Sheet (⋯ 설정) — 시안 .sheet 톤. 모바일 viewport 기준 fixed bottom sheet ===
   컨테이너 자체를 페이지 컨테이너 폭(--rl-page-container, 768)에 cap → 자식 overlay·panel이
   모두 cap 안에서 그려져 데스크탑 좌우 빈 영역에 백드롭이 새지 않음(design-system §3.7.0
   "백드롭 폭 cap"). body 직속이라 .rl-mnav-enabled 토큰 미상속 → fallback 768px. */
.rl-sheet{
  position:fixed;
  top:0; bottom:0; left:50%;
  width:100%; max-width: var(--rl-page-container, 768px);
  transform:translateX(-50%);
  z-index:30;
  pointer-events:none; visibility:hidden;
}
.rl-sheet.is-open{ pointer-events:auto; visibility:visible; }
.rl-sheet-overlay{
  position:absolute; inset:0;
  background:var(--rl-overlay);
  opacity:0; transition:opacity var(--rl-dur-base) ease;
}
.rl-sheet.is-open .rl-sheet-overlay{ opacity:1; }
.rl-sheet-panel{
  position:absolute; left:0; right:0;
  /* 키보드 노출 시 패널을 --rl-kb-inset(rl-keyboard-state.js 단일 게시)만큼 들어올림 — iOS는 레이아웃
     뷰포트가 안 줄어 bottom:0 패널이 키보드 뒤에 가리므로 bottom 오프셋으로 보정. 닫힘 시 변수=0(기본 하단).
     하단 padding은 safe-area만 담당(중복 방지) — 키보드 회피는 bottom 오프셋 + max-height 축소로 흡수.
     −vv-top: iOS가 시트 입력 포커스로 visual viewport를 패닝(vvTop>0)하면 fixed 시트 컨테이너가 그만큼
     위로 밀리므로, 패닝량만큼 bottom을 낮춰 시트가 가시 키보드 top 위 실제 위치에 정렬되고 재패닝 추격
     (흔들림)이 감쇠된다. (kbInset−vvTop = stableVh−vvH−vvTop = 키보드 top의 기하학적 위치.) 시트는
     body-fixed라 scrollY 성분 없는 순수 패닝 오프셋 --rl-vv-top(전역 게시)이 정답 — App Shell 아닌 페이지
     (rl_study 필터 시트 등)에서도 작동(App Shell 전용 --rl-vv-shift는 미게시라 보정 0→갭 발생했음).
     App Shell 페이지에선 vv-top==vv-shift(내부 스크롤이라 scrollY≈0)라 동작 불변. */
  bottom:max(0px, calc(var(--rl-kb-inset, 0px) - var(--rl-vv-top, 0px)));
  background:var(--rl-surface-elev);
  border-radius:var(--rl-r-xl) var(--rl-r-xl) 0 0;
  padding:var(--rl-sp-2) 0 calc(22px + var(--rl-safe-bottom, env(safe-area-inset-bottom, 0px)));
  transform:translateY(100%);
  transition:transform var(--rl-dur-sheet) var(--rl-ease-sheet);
  box-shadow:var(--rl-shadow-sheet);
  /* vh→svh→dvh 3단 fallback(주소창) → 마지막에 --rl-visible-vh(키보드 노출 시 가시 viewport, JS 게시).
     키보드 열림 시 패널이 들어올려진 만큼 가시영역 안에 들어오도록 max-height도 함께 축소. */
  max-height:calc(100vh - 40px);
  max-height:calc(100svh - 40px);
  max-height:calc(100dvh - 40px);
  max-height:calc(var(--rl-visible-vh, 100dvh) - 40px);
  overflow:hidden;
}
.rl-sheet.is-open .rl-sheet-panel{ transform:translateY(0); }
/* 스와이프 닫기 옵트아웃 변형(data-rl-no-swipe) — 드래그 핸들 비표시 + 핸들 없는 만큼 상단 여백 확보.
   learn-sheet.js가 이 시트엔 스와이프를 미바인딩(overlay 클릭·Esc로만 닫힘). */
.rl-sheet[data-rl-no-swipe] .rl-sheet-handle{ display:none; }
.rl-sheet[data-rl-no-swipe] .rl-sheet-panel{ padding-top:var(--rl-sp-5); }

/* 핸들 — 시각 pill(36×4)은 ::before로, hit area는 X 버튼 높이(--rl-h-iconbtn 40)와 정합.
   드래그 시작 zone을 탭 가능한 충분한 높이로 확보(엄지 한 손 조작에서 정확한 hit 가능).
   touch-action:none — native vertical pan 차단해 pointermove가 우리 핸들러에 안정 전달. */
.rl-sheet-handle{
  position: relative;
  width: 100%;
  height: var(--rl-h-iconbtn);
  margin: 0;
  background: transparent;
  border-radius: 0;
  cursor: grab;
  touch-action: none;
}
.rl-sheet-handle::before{
  content: '';
  position: absolute;
  top: var(--rl-sp-2);
  left: 50%;
  transform: translateX(-50%);
  width: 36px;
  height: 4px;
  border-radius: var(--rl-r-full);
  background: var(--rl-line-2);
}
.rl-sheet-page{ display:none; }
.rl-sheet-page.is-active{ display:block; animation:rlPageIn var(--rl-dur-base) ease both; }
@keyframes rlPageIn{
  from{ opacity:0; transform:translateX(14px); }
  to{ opacity:1; transform:translateX(0); }
}
.rl-sheet-head{
  display:flex; align-items:center; justify-content:space-between;
  padding:2px 14px 10px;
}
.rl-sheet-head h4{
  margin:0; font-size:var(--rl-fs-h3); font-weight:800; color:var(--rl-ink);
  letter-spacing:var(--rl-ls-tight);
  flex:1; text-align:center;
}
.rl-sheet-head .rl-head-spacer{ width:40px; height:40px; flex-shrink:0; }
.rl-sheet-list{
  list-style:none; padding:4px 8px; margin:0;
}
.rl-sheet-item{
  display:flex; align-items:center; gap:12px;
  padding:11px 12px; border-radius:var(--rl-r-btn);
  cursor:pointer; transition:background var(--rl-dur-micro);
  user-select:none;
  min-height:var(--rl-h-btn-md);
}
@media (hover: hover) {
  .rl-sheet-item:hover{ background:var(--rl-surface-2); }
}
.rl-sheet-item:active{ background:var(--rl-surface-2); }
/* 읽기전용 행 — 값이 다른 설정(시험일)에 의해 잠긴 경우. 진입 불가(no chevron) + 톤 후퇴. */
.rl-sheet-item.is-static{ cursor:default; }
@media (hover: hover) { .rl-sheet-item.is-static:hover{ background:transparent; } }
.rl-sheet-item.is-static:active{ background:transparent; }
.rl-sheet-item.is-static .rl-ic{ opacity:0.55; }
.rl-sheet-item.is-static .rl-lbl{ color:var(--rl-text-2); }
.rl-sheet-item.is-static .rl-val .rl-chevron-right{ display:none; }
.rl-sheet-item .rl-ic{
  width:32px; height:32px; flex-shrink:0; border-radius:var(--rl-r-sm);
  background:var(--rl-surface-2);
  display:flex; align-items:center; justify-content:center;
  color:var(--rl-text-2);
}
.rl-sheet-item .rl-ic svg{ width:18px; height:18px; }
.rl-sheet-item .rl-lbl{
  flex:1; min-width:0;
  font-size:var(--rl-fs-body-sm); font-weight:600; color:var(--rl-ink);
  letter-spacing:var(--rl-ls-body); line-height:1.3;
}
.rl-sheet-item .rl-lbl small{
  display:block; font-weight:500; color:var(--rl-text-3);
  font-size:var(--rl-fs-caption-sm); margin-top:2px; letter-spacing:0;
}
.rl-sheet-item .rl-val{
  font-size:var(--rl-fs-caption); color:var(--rl-text-3); font-weight:600;
  display:inline-flex; align-items:center; gap:4px;
}
/* §3.1.5 sub-rule — chevron은 SVG 단일 출처(rl_icon_chevron_right). 색은 sheet-val 위계상 한 단계 후퇴(--text-4),
   margin-left는 .rl-val의 flex gap(4px)이 단일 출처 담당 — helper 기본 margin-left:4px를 0으로 회수해 이중 누적 회피. */
.rl-sheet-item .rl-val .rl-chevron-right{ color:var(--rl-text-4); margin-left:0; }

/* iOS-style switch */
.rl-swt{
  width:38px; height:22px; border-radius:var(--rl-r-full);
  background:var(--rl-line-2); position:relative;
  transition:background var(--rl-dur-base);
  flex-shrink:0;
}
.rl-swt::after{
  content:""; position:absolute; top:2px; left:2px;
  width:18px; height:18px; border-radius:50%; background:var(--rl-on-primary);
  box-shadow:var(--rl-shadow-knob);
  transition:transform var(--rl-dur-base);
}
.rl-sheet-item.is-on .rl-swt{ background:var(--rl-primary); }
.rl-sheet-item.is-on .rl-swt::after{ transform:translateX(16px); }

/* radio 옵션 카드 (학습 모드 / 출제 순서) */
.rl-sheet-options{
  list-style:none; padding:0 14px 6px; margin:0;
  display:flex; flex-direction:column; gap:8px;
}
.rl-opt{
  display:flex; align-items:flex-start; gap:10px;
  padding:13px 14px;
  border:1.5px solid var(--rl-line-2); border-radius:var(--rl-r-md);
  cursor:pointer; transition:border-color var(--rl-dur-micro), background var(--rl-dur-micro);
  background:var(--rl-surface);
  min-height:var(--rl-h-btn-md);
}
.rl-opt > .rl-opt-body{ flex:1; min-width:0; }
.rl-opt strong{
  display:block; font-size:var(--rl-fs-body-sm); font-weight:700;
  color:var(--rl-ink); letter-spacing:var(--rl-ls-body);
}
.rl-opt small{
  display:block; font-size:var(--rl-fs-caption); color:var(--rl-text-3);
  margin-top:3px; line-height:var(--rl-lh-snug); word-break:keep-all; overflow-wrap:break-word;
}
.rl-opt .rl-check{
  width:22px; height:22px; border-radius:50%;
  border:1.5px solid var(--rl-line-2); background:var(--rl-surface);
  display:inline-flex; align-items:center; justify-content:center;
  flex-shrink:0; color:transparent;
  font-size:13px; font-weight:800; line-height:1;
  margin-top:1px;
}
.rl-opt.is-selected{
  border-color:var(--rl-primary);
  background:var(--rl-primary-soft);
}
.rl-opt.is-selected .rl-check{
  border-color:var(--rl-primary);
  background:var(--rl-primary);
  color:var(--rl-on-primary);
}

.rl-sheet-hint{
  margin:8px 18px 0;
  font-size:var(--rl-fs-caption); color:var(--rl-text-3);
  line-height:var(--rl-lh-snug);
  display:flex; align-items:flex-start; gap:6px;
}
.rl-sheet-hint::before{ content:"\2139"; color:var(--rl-text-4); flex-shrink:0; font-style:normal; }

/* confirm sub-page (이 문제 안 보기) */
.rl-sheet-confirm{ padding:6px 18px 10px; text-align:center; }
.rl-confirm-icon{
  width:56px; height:56px; margin:6px auto 12px;
  border-radius:var(--rl-r-lg);
  background:var(--rl-accent-soft); color:var(--rl-accent);
  display:flex; align-items:center; justify-content:center;
}
.rl-confirm-icon svg{ width:28px; height:28px; }
.rl-sheet-confirm h3{
  margin:0 0 10px; font-size:var(--rl-fs-h3); font-weight:800;
  color:var(--rl-ink); letter-spacing:var(--rl-ls-tight);
  word-break:keep-all; overflow-wrap:break-word; line-height:var(--rl-lh-snug);
}
.rl-confirm-meta{
  background:var(--rl-surface-2); border-radius:var(--rl-r-btn);
  padding:10px 14px; margin:0 auto 12px;
  display:flex; flex-direction:column; gap:2px;
}
.rl-confirm-meta b{
  font-size:var(--rl-fs-caption-sm); font-weight:700;
  color:var(--rl-ink); letter-spacing:var(--rl-ls-body);
}
.rl-confirm-meta span{ font-size:var(--rl-fs-caption); color:var(--rl-text-3); font-weight:500; }
.rl-confirm-note{
  margin:0 0 14px; font-size:var(--rl-fs-caption); color:var(--rl-text-3);
  line-height:var(--rl-lh-snug); word-break:keep-all; overflow-wrap:break-word;
}
.rl-confirm-actions{ display:flex; gap:10px; }
.rl-confirm-actions button{ flex:1; }

/* confirm 버튼 — primary / ghost */
.rl-cta-primary, .rl-cta-ghost{
  appearance:none; cursor:pointer;
  height:var(--rl-h-btn-md);
  border-radius:var(--rl-r-md);
  font-size:var(--rl-fs-body-sm); font-weight:700;
  letter-spacing:var(--rl-ls-body);
  font-family:inherit;
  transition:background var(--rl-dur-micro), color var(--rl-dur-micro), border-color var(--rl-dur-micro);
}
.rl-cta-primary{
  background:var(--rl-primary); color:var(--rl-on-primary); border:0;
}
@media (hover: hover) {
  .rl-cta-primary:hover:not(:disabled){ background:var(--rl-primary-hover); }
}
.rl-cta-primary:active:not(:disabled){ background:var(--rl-primary-hover); }
/* 비활성 — 조건 미충족 상태(예: 시험일 미입력). 회색 톤·hover 무반응. */
.rl-cta-primary:disabled{
  background:var(--rl-surface-2); color:var(--rl-text-3); cursor:default;
}
.rl-cta-ghost{
  background:var(--rl-surface); color:var(--rl-text);
  border:1px solid var(--rl-line-2);
}
@media (hover: hover) {
  .rl-cta-ghost:hover{ background:var(--rl-surface-2); }
}
.rl-cta-ghost:active{ background:var(--rl-surface-2); }

/* === 시험일(D-day) 설정 시트 — 입력 페이지(독립 컴포넌트 + 학습설정 공용) === */
.rl-exam-date-body{ padding:var(--rl-sp-4) var(--rl-sp-5) var(--rl-sp-5); }
.rl-exam-date-subject{
  margin:0 0 var(--rl-sp-1);
  font-size:var(--rl-fs-body); font-weight:700;
  color:var(--rl-ink); letter-spacing:var(--rl-ls-tight);
}
.rl-exam-date-desc{
  margin:0 0 var(--rl-sp-4);
  font-size:var(--rl-fs-label); line-height:var(--rl-lh-snug);
  color:var(--rl-text-2);
}
.rl-exam-date-field{ display:block; margin-bottom:var(--rl-sp-4); }
.rl-exam-date-input{
  width:100%; height:var(--rl-h-btn-md);
  padding:0 var(--rl-sp-3);
  border:1px solid var(--rl-line-2); border-radius:var(--rl-r-md);
  background:var(--rl-surface-elev); color:var(--rl-text);
  font-size:var(--rl-fs-body); font-family:inherit;
  box-sizing:border-box;
}
.rl-exam-date-input:focus-visible{ outline:2px solid var(--rl-primary); outline-offset:1px; }
/* err/hint 공용 슬롯 — 둘 다 숨김이어도 1행 높이(gap 포함) 고정 확보해 메시지 토글 시 버튼 점프(흔들림) 방지.
   좌우는 sp-1 들여 입력창 테두리와 시각 정렬. min-height = 1행(caption×lh-snug). */
.rl-exam-date-msg{
  margin-top:var(--rl-sp-1);
  min-height:calc(var(--rl-fs-caption) * var(--rl-lh-snug));
  padding-inline:var(--rl-sp-1);
}
/* 입력 전 기본 안내 — 중립 톤(보조). err/hint와 상호배타. */
.rl-exam-date-guide{
  margin:0;
  font-size:var(--rl-fs-caption); line-height:var(--rl-lh-snug);
  color:var(--rl-text-3);
}
.rl-exam-date-guide[hidden]{ display:none; }
.rl-exam-date-err{
  margin:0;
  font-size:var(--rl-fs-caption); line-height:var(--rl-lh-snug);
  color:var(--rl-bad);
}
/* 해석값 hint('2026년 7월 10일 시험') — err와 상호배타. 유효 입력 확인용 약한 강조(primary). */
.rl-exam-date-hint{
  margin:0;
  font-size:var(--rl-fs-caption); line-height:var(--rl-lh-snug);
  font-weight:600; color:var(--rl-primary);
}
.rl-exam-date-hint[hidden]{ display:none; }
.rl-exam-date-body .rl-cta-primary{ width:100%; }
/* 삭제는 보조 행동 — full-width 박스 X, 약한 텍스트 버튼(중앙·하단 여백). 회색 기본, hover 시 약한 위험색. */
.rl-exam-date-clear{
  display:block;
  margin:var(--rl-sp-3) auto 0;
  padding:var(--rl-sp-1) var(--rl-sp-2);
  background:none; border:0;
  font-family:inherit; font-size:var(--rl-fs-label); font-weight:500;
  color:var(--rl-text-3);
  cursor:pointer;
}
/* display:block가 동일 명시도로 UA [hidden]{display:none}를 덮어쓰므로, 미설정 시 숨김을 명시 보강. */
.rl-exam-date-clear[hidden]{ display:none; }
@media (hover:hover){ .rl-exam-date-clear:hover{ color:var(--rl-bad); } }

/* ===========================================================================
 * 문제풀이 하단 광고 — 짧은 화면 바텀-앵커 / 긴 화면 인-플로우 (exam·note·quick)
 * 콘텐츠+광고가 화면보다 짧으면(스크롤 0) 광고만 기기 바닥으로 내려 정렬, 길면 지금 위치
 * (버튼 아래 sp-7=32px)로 흐름에 따라 스크롤. flex 컬럼 + margin-top:auto의 조건부 앵커.
 * 문제 카드는 화면 높이와 무관하게 항상 baseline 상단 위치 고정 — 움직이는 건 광고 슬롯 하나뿐.
 *
 * [구조 차이] 광고 슬롯 위치가 페이지마다 다름:
 *   - exam·quick: .at-content > .view-wrap > .rl-ad-slot--display  (광고가 view-wrap 안)
 *   - note:       .at-content > .rl-ad-slot--display               (광고가 at-content 직속, view-wrap 형제)
 *   광고의 flex 부모(exam·quick=view-wrap, note=at-content)에 margin-top:auto를 걸어야 하므로
 *   두 구조 셀렉터를 병기한다.
 *
 * [게이트] :has(... .rl-ad-slot--display:not([data-rl-ad-collapsed])):
 *   광고가 "실제로 자리를 차지할 때만" 앵커 ON(§4.12.D 광고 없는 UI=baseline).
 *   no-fill/failed/blocked 시 rl-ad-runtime.js의 _collapseFully()가 슬롯에
 *   data-rl-ad-collapsed="1"을 부여(rl-ad-runtime.js:356)하므로 :not()으로 제외 →
 *   앵커 OFF → baseline 자연 높이 복원(하단 빈 화면 방지). ineligible(슬롯 미렌더)도 동일.
 *   ※ 이 게이트는 세 슬롯의 unfilled_policy='collapse'(rl_ad_system.php:296/323/346 →
 *      no-fill 시 마커 발생)를 전제로 동작. 마커 속성명/부착 대상/정책 변경 시 동반 수정 필요
 *      (rl-ad-runtime.js:355 동반 주석 참조).
 *
 * [calc 자기일관성] 스크롤 주체 #thema_wrapper가 min-height:100dvh(page-shell.css:93),
 *   흐름 점유는 sticky 앱바(--rl-h-appbar 52 + --rl-safe-top) 단 하나(상단 크롬·하단 바 없음).
 *   at-content min-height = 100dvh - 앱바 - safetop → (앱바 + at-content) 합 = 100dvh = wrapper.
 *
 * [width:100%] flex cross축(너비)에서 .rl-ad-slot/.rl-actions의 margin-inline:auto(rl-ad.css/
 *   learn.css)가 stretch를 무력화해 빈 슬롯 너비가 0이 되면, rl-ad-runtime _verifySize가
 *   rowW<규격으로 판단해 슬롯을 suppress→collapse(광고 미출력)·버튼이 좁아짐. 행 폭을 강제.
 *
 * [버튼 자리 예약 없음] 바닥 앵커 시엔 margin-top:auto가 광고를 바닥에 고정하므로 답 선택으로
 *   버튼이 등장해도 광고 불변. 오버플로(스크롤) 시엔 작업 이전(baseline)과 동일하게 버튼이
 *   흐름을 민다 — min-height로 버튼 자리를 미리 예약하지 않는다.
 * 토큰만 사용. min-height/flex/height:0/width는 광고 유무에 따른 동적 레이아웃 보정값. */

/* 1) flex 컨테이너 = at-content (높이 전달). exam·quick은 광고가 view-wrap 안이라 view-wrap도 flex:1 필요(아래). */
.rl-learn .at-content:has(> .rl-ad-slot--display:not([data-rl-ad-collapsed])),
.rl-learn .at-content:has(> .view-wrap > .rl-ad-slot--display:not([data-rl-ad-collapsed])){
  display:flex;
  flex-direction:column;
  /* min-height에서 safe-top·safe-bottom 모두 차감. iOS 앱(viewport-fit=cover, env 동작)에선
     100dvh가 노치·홈인디케이터 영역까지 포함하지만 스크롤 컨테이너 가시 높이는 그만큼 작다.
     safe-bottom 미차감 시 콘텐츠가 100dvh를 채워 가시영역을 초과→스크롤+광고 아래 군더더기 여백.
     차감하면 at-content 바닥이 홈인디케이터 위에 맞춰져 스크롤 0. web/non-notch는 safe-bottom=0이라 불변. */
  min-height:calc(100dvh - var(--rl-h-appbar) - var(--rl-safe-top, 0px) - var(--rl-safe-bottom, 0px));
  box-sizing:border-box;
  /* 광고 아래 .h40을 접고 하단 breathing만 floor(sp-4)로 제공 — 홈인디케이터 클리어런스는
     위 min-height의 safe-bottom 차감이 담당하므로 여기서 safe-bottom을 또 더하지 않는다. */
  padding-bottom:var(--rl-sp-4);
}
/* exam·quick: 광고가 view-wrap 안 → view-wrap이 at-content를 채우는 flex 컬럼이어야 광고
   margin-top:auto가 viewport 바닥까지 민다. note는 view-wrap=문제카드뿐이라 flex:1 부여 안 함(상단 고정). */
.rl-learn .at-content:has(> .view-wrap > .rl-ad-slot--display:not([data-rl-ad-collapsed])) > .view-wrap{
  flex:1 1 auto;
  display:flex;
  flex-direction:column;
}
/* exam·quick: view-wrap flex 컬럼에서 빈 .view-head 패널의 collapse 마진(block flow에선
   사라지나 flex에선 노출)이 문제 카드를 아래로 밀어내는 것 방지(상단 고정). note는 view-wrap이 block이라 불필요. */
.rl-learn .at-content:has(> .view-wrap > .rl-ad-slot--display:not([data-rl-ad-collapsed])) > .view-wrap > .view-head{
  margin:0;
}
/* 2) 광고 = 직속 flex 자식에 margin-top:auto + width:100% (exam·quick=view-wrap 자식 / note=at-content 자식). */
.rl-learn .view-wrap:has(> .rl-ad-slot--display:not([data-rl-ad-collapsed])) > .rl-ad-slot--display,
.rl-learn .at-content:has(> .rl-ad-slot--display:not([data-rl-ad-collapsed])) > .rl-ad-slot--display{
  margin-top:auto;
  width:100%;
}
/* 3) 버튼↔광고 32px 간격은 actions margin-bottom으로(오버플로 시 ad margin-top:auto=0이어도 보존).
   width:100%로 flex 컬럼에서 버튼 폭 유지. 버튼 자리 예약(min-height)은 없음(위 주석 참조). */
.rl-learn .view-wrap:has(> .rl-ad-slot--display:not([data-rl-ad-collapsed])) > .rl-actions,
.rl-learn .at-content:has(> .rl-ad-slot--display:not([data-rl-ad-collapsed])) > .rl-actions{
  margin-bottom:var(--rl-sp-7);
  width:100%;
}
/* 버튼(#scoring) 미표시(답 선택 전) 상태에선 빈 .rl-actions의 상단 마진(sp-5)이 baseline(block flow)
   에선 collapse돼 사라지나 flex 컨텍스트에선 노출돼 문제 카드 아래 군더더기 갭을 만든다. 버튼이
   보이지 않을 때(.can-scoring/.trans-bg-crimson 부재) margin-top을 0으로 회수 → 작업 이전과 정합
   (버튼 표시 시엔 base 룰의 sp-5 유지). margin-bottom(32 gap)은 유지해 question↔광고 간격은 동일. */
.rl-learn .view-wrap:has(> .rl-ad-slot--display:not([data-rl-ad-collapsed])) > .rl-actions:not(:has(#scoring.can-scoring, #scoring.trans-bg-crimson)),
.rl-learn .at-content:has(> .rl-ad-slot--display:not([data-rl-ad-collapsed])) > .rl-actions:not(:has(#scoring.can-scoring, #scoring.trans-bg-crimson)){
  margin-top:0;
}
/* 4) 광고 아래 스페이서는 접음 — 하단 여백은 at-content padding-bottom 단일 출처. */
.rl-learn .view-wrap:has(> .rl-ad-slot--display:not([data-rl-ad-collapsed])) > .h40,
.rl-learn .at-content:has(> .rl-ad-slot--display:not([data-rl-ad-collapsed])) > .h40{
  height:0;
}


