/* ==========================================================================
   RL Page Shell — 페이지 컨테이너 768 카드 + 카드 시각 효과 PC 한정 (§2.8.1 v0.9)
   docs/design/design-system.md v0.9 기반.

   원칙:
   1) **사이트의 최대 폭(카드 boundary) = 768px** → 페이지 컨테이너 자체(.wrapper)에 한 번 적용.
      App Bar/BottomTab/본문 등 내부 요소에 별도 boundary 두지 않음 — "하나의 디바이스" 외관.
   2) **카드 폭 정책**: max-width 768은 모든 viewport에 적용. viewport ≤768은 자연 풀폭과 시각적으로 동일하고
      가운데 정렬 + 외측 여백. 본문 콘텐츠는 카드 안에서 자연 풀폭(좌우 14 padding 안 — v1.14.19).
   3) **카드 시각 효과(border/shadow) viewport ≥769 한정** — viewport ≤768은 카드가 화면 가장자리에 붙어
      border가 어색하므로 미적용. min-width: 769px 미디어 쿼리로 발화.
   4) BottomTab은 fixed지만 카드와 정확히 정렬되도록 max-width 768 + left:50% + translateX(-50%).
   5) 외측 여백은 body.rl-mnav-page 배경(raw hex 라이트/다크). head.sub.php가 rl_shell_show() 시 클래스 부여.
   6) 페이지 셸 레벨 잔재(colorset/bootstrap/apms) 명시 reset — 디자인 시스템 토큰만 사용.

   스코프: .rl-mnav-enabled 안에서만 발화. kill switch off → 본 CSS 전부 무효.
   로드 순서: mobile-nav.css 다음 priority. head.php에서 보장.

   토큰 정책: 전역 디자인 시스템 토큰이 아니라, .rl-mnav-enabled 스코프 안에서만 쓰는
              page-shell 전용 로컬 변수. 시스템 표준 토큰 신설 아님.
   ========================================================================== */

.rl-mnav-enabled {
  --rl-page-container: 768px;
  --rl-page-padding-x: 14px;
}

/* ==========================================================================
   1. 외측 여백 — body 배경. 카드 boundary 외측 색.
   body.rl-mnav-page 클래스는 head.sub.php에서 rl_shell_show() true일 때만 부여 —
   :has() 미지원 브라우저(iOS Safari <15.4 등)에서도 안전하게 동작.
   raw hex 직접 사용. design-system §2.1.4 "페이지 배경" 변경 시 라이트는 본 파일 + learn-tokens.css `--rl-bg` 동기화. 다크 두 값은 본 파일 단독 출처.
   ========================================================================== */
body.rl-mnav-page {
  background: #ECEEF1;
}
/* data-theme은 <html>에 부여 — :root 위치에서 매칭 (design-system §2.10.1). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body.rl-mnav-page {
    background: #0B1220;
  }
}
:root[data-theme="dark"] body.rl-mnav-page {
  background: #0B1220;
}

/* ==========================================================================
   2. 페이지 셸 잔재 reset — 우리 스코프 안에서 colorset/bootstrap/apms 잔재 무효화
   ========================================================================== */
.rl-mnav-enabled .at-body,
.rl-mnav-enabled .at-content {
  background: transparent;
}
.rl-mnav-enabled .at-container {
  box-shadow: none;
  border: 0;
  background: transparent;
}

/* ==========================================================================
   2-b. 페이지 콘텐츠 호흡 — sticky 앱바와 본문 첫 요소 간격을 6px 단일 출처로 일관화.
   (design-system.md §2.8.4)
   colorset 기본 `.at-content { padding: 20px 0 }`을 override해 padding-top만 6px로.
   더불어 페이지 콘텐츠 wrapper의 첫 자식 체인은 mt 0으로 강제 — 자체 외측 마진을 가진
   컴포넌트(예: .rl-banner)가 첫 자식으로 들어와도 padding과 합쳐져 호흡이 부풀지 않게.
   3단계 깊이까지 적용(.at-content > * > * > * 까지). 일반 페이지는 2~3단계로 충분하며,
   더 깊은 nesting은 의도된 외측 마진을 가질 수 있어 무한 적용은 회피.
   홈(Full Wide $col_name='') 페이지도 동일 wrapper 구조(.at-container > .at-content)로 통일해
   (thema/Basic/main/rlcnf.php) 단일 셀렉터로 회수.
   ========================================================================== */
.rl-mnav-enabled .at-content {
  padding-top: 6px;
  padding-bottom: var(--rl-sp-6);
}
.rl-mnav-enabled .at-content > *:first-child,
.rl-mnav-enabled .at-content > *:first-child > *:first-child,
.rl-mnav-enabled .at-content > *:first-child > *:first-child > *:first-child {
  margin-top: 0;
}

/* ==========================================================================
   3. 카드 = 페이지 컨테이너 자체 (#thema_wrapper / .wrapper.rl-mnav-enabled)
   wrapper가 한 통(디바이스 화면)이고 그 안에 모든 내부 요소가 들어감.
   기본 룰: max-width 768 + 가운데 정렬 + surface 배경 + min-height 100dvh + box-sizing border-box.
   카드 시각 효과(border + shadow)는 PC/태블릿(viewport ≥769) 한정 별도 미디어 쿼리에 분리.
   box-sizing: border-box — border가 max-width 안에 포함돼 가로 스크롤 방지.
   min-height 100dvh — 모바일 브라우저 주소창/내비바 노출 시 100vh가 가시영역을 초과해
   잉여 스크롤이 발생하던 결함 회수. dvh는 가시 viewport를 추적한다. */
.rl-mnav-enabled.wrapper {
  max-width: var(--rl-page-container);
  margin-inline: auto;
  background: var(--rl-surface);
  min-height: 100dvh;
  position: relative;
  box-sizing: border-box;
}
/* 키보드 열림 시 wrapper min-height를 가시 viewport(--rl-visible-vh, keyboard-state 단일 게시)로 —
   iOS dvh는 키보드를 반영하지 않아 100dvh가 키보드 뒤까지 유지되면 짧은 페이지(홈 등) 콘텐츠 아래에
   큰 잉여 공간이 생기고, 그 큰 페이지를 iOS가 스크롤하며 sticky 앱바가 밀려 사라진다. 미게시 시 100dvh(현행). */
#thema_wrapper.rl-mnav-enabled.rl-mnav-kb-open.wrapper {
  min-height: var(--rl-visible-vh, 100dvh);
}
/* App Shell 한정 — at-body가 position:fixed라 wrapper는 흐름 콘텐츠 없이 surface 배경판 역할만 한다.
   위 visible-vh 축소(비-App Shell 문서스크롤 방지용)는 surface를 layout-top 기준 키보드 위까지만 덮어,
   iOS 패닝(vvTop>0) 시 wrapper-bottom과 키보드 top 사이 ~vvTop만큼 body 배경(다른 색)이 샌다.
   body가 fixed+overflow:hidden이라 100dvh wrapper는 문서 스크롤(앱바 밀림)을 못 일으키므로, base와
   동일하게 가시영역 전체를 surface로 덮어 색 누수를 막는다(at-body 투명 뒤를 surface가 받친다). */
body.rl-app-shell #thema_wrapper.rl-mnav-enabled.rl-mnav-kb-open.wrapper {
  min-height: 100dvh;
}

/* ==========================================================================
   3-b. 내부 스크롤 셸 — 비 App Shell 페이지의 스크롤 주체를 window(문서)에서 #thema_wrapper
   내부 컨테이너로 이전. window 문서 스크롤은 모바일 브라우저(특히 iOS 크롬)에서 터치 스크롤이
   먹통이 되는 회귀가 있다(WKWebView 앱·데스크탑은 정상) — 탭은 되는데 스크롤만 죽음. 스크롤을 항상
   내부 overflow 컨테이너가 받게 해 차단한다. App Bar는 wrapper 안 sticky라 스크롤포트 상단에 고정 유지.
   - App Shell(.rl-app-shell)은 body fixed + .at-body 내부 스크롤로 같은 목적을 이미 달성 → :not()로 제외.
   - 학습 surface 스크롤 모델 단일화: 비 App Shell(exam 등)은 본 §3-b가, App Shell(note 등)은 §8 .at-body가
     모델을 맡는다. exam.css/note.css가 갖고 있던 중복 규칙(html,body overflow:hidden + #thema_wrapper
     overflow scroll)은 본 단일 출처로 일원화하며 제거됨(ae7e0019) — 더는 자체 적용 없음.
   height:100dvh — 가시 viewport 추적. §3 min-height:100dvh 및 kb-open visible-vh는 같거나 작아 본 height가
   유효값을 결정(키보드 열림 시 잉여 문서 스크롤 자체가 없어 앱바 밀림도 비발생). */
body.rl-mnav-page:not(.rl-app-shell) {
  height: 100dvh;
  overflow: hidden;
}
body.rl-mnav-page:not(.rl-app-shell) #thema_wrapper.rl-mnav-enabled {
  height: 100dvh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* viewport ≥769 한정 카드 시각 효과 — border + shadow.
   viewport ≤768은 카드가 viewport 풀폭이라 border가 가장자리에 붙어 어색하므로 적용 X.
   기기 무관 viewport 폭 기준. */
@media (min-width: 769px) {
  .rl-mnav-enabled.wrapper {
    border-left: 1px solid var(--rl-line-2);
    border-right: 1px solid var(--rl-line-2);
    box-shadow: var(--rl-shadow-md);
  }
}

/* ==========================================================================
   4. 페이지 본문 — wrapper 안 자연 768 cap, padding 14 (v1.14.19, 24→16→14)
   .at-container는 wrapper 안이라 자연 768 cap. padding-inline 14 (v1.14.19 컴팩트 정합).
   본문 콘텐츠는 .at-container 안에서 자연 풀폭 (별도 cap 없음, §2.8.1).

   cascade — colorset의 `.responsive .at-body .at-container { padding: 0 10px }`는
   §2.11 `legacy` layer 안에 갇혀 있고(head.sub.php @import) 본 룰은 unlayered.
   normal 선언은 unlayered가 layered를 이기는 spec 그대로 발화.
   !important는 같은 selector specificity(0,3,0)에서 동일 unlayered 다른 사용처
   (scoring.css/result.css/learn.css의 padding-inline:0)와의 다툼 방지용 — 본 룰이
   먼저 등록되고 페이지별 override는 후순 priority(>=25)로 등록되어 source order로 이긴다.
   ========================================================================== */
.rl-mnav-enabled .at-container {
  margin-inline: auto;
}
.rl-mnav-enabled .at-body .at-container,
.rl-mnav-enabled .at-title .at-container,
.rl-mnav-enabled .at-footer .at-container {
  padding-inline: var(--rl-page-padding-x);
}

/* 페이지 본문 마지막 가시 자식 margin-bottom 0 — 모든 탭이 동일한 하단 spacing 패턴을 갖도록 강제.
   페이지 끝 spacer는 페이지 셸(.at-content padding-bottom) 단일 출처.
   :nth-last-child(1 of :not(script):not([hidden])) 로 비가시 요소(SCRIPT·[hidden] 토글 카드,
   예: 시험일 설정 시 hidden으로 남는 D-day 넛지)가 마지막에 있어도 가시 last 정확 선택.
   - .at-content 직속: 홈처럼 .at-content 직속에 자식들이 펼쳐진 마크업
   - .at-content .board-list 직속: section.board-list로 감싸는 마크업(오답노트/모의시험 등)
   - 마지막 가시 자식이 surface인 경우 그 안의 마지막 tile margin도 함께 0 — 직속 reset은 surface
     자신만 닿고 내부 tile margin(예: .rl-quick-recent-tile.is-accuracy sp-6)은 잔존하므로
     홈 빠른학습 '최근 흐름'이 페이지 끝이면 정답률/안정도 tile 하단에 24px 잔존. 한 단계 더 내려 회수. */
.rl-mnav-enabled .at-content > :nth-last-child(1 of :not(script):not([hidden])),
.rl-mnav-enabled .at-content .board-list > :nth-last-child(1 of :not(script):not([hidden])),
.rl-mnav-enabled .at-content .board-list > .rl-quick-recent-surface:nth-last-child(1 of :not(script):not([hidden])) > .rl-quick-recent-tile.is-accuracy:nth-last-child(1 of :not(script):not([hidden])) {
  margin-bottom: 0;
}

/* ── 랜딩 진입 스태거 — 일차 탭 랜딩(홈·모의시험·오답노트)의 콘텐츠가 진입 시 위→아래로
   순차 등장. 한 번의 page load 오케스트레이션. 모션 프리미티브는 토큰(--rl-dur-base/--rl-ease/--rl-space-2).
   적용: 세 페이지 공통 카드 wrapper(.board-list)에 .rl-stagger-in 부여 → 직계 가시 자식이 staggered 등장.

   세션당 1회만 — <html>.rl-stagger-arm 게이트. head.php가 페이지 진입 시 sessionStorage로 첫 1회만
   arm 클래스를 부여(고빈도 도구 반복 피로·지연 회피). arm 없으면(재진입) 룰 미발화 → 카드 즉시 표시.

   제외 자식 — `of :not(script):not([hidden]):not(.rl-stagger-skip)` (애니메이션·카운트 모두 제외):
     · script 등 비가시 자식(상단 last-child 룰과 동일 패턴)
     · [hidden] — 진입 시 숨김 요소(확인 모달·검색 펼침 패널 등 비콘텐츠 오버레이). 슬롯만 먹고
       안 보여 카드 cadence를 어긋나게 하므로 자동 제외(toggle로 보이게 되는 시점엔 stagger 종료).
     · .rl-stagger-skip = 광고 슬롯. "광고는 가산 레이어, 콘텐츠 모션과 분리"(CLAUDE.md) — 광고
       컨테이너에 opacity:0→1을 걸면 애드센스 viewability/서빙과 얽힐 수 있어 제외, 즉시 풀 opacity 노출.
       (CSS [hidden]로 안 잡히는 class-hidden 요소의 수동 escape hatch로도 사용)
   prefers-reduced-motion에서 미발화. ── */
.rl-stagger-arm .rl-mnav-enabled .rl-stagger-in > :not(script):not([hidden]):not(.rl-stagger-skip) {
  animation: rl-stagger-rise var(--rl-dur-base) var(--rl-ease) both;
}
.rl-stagger-arm .rl-mnav-enabled .rl-stagger-in > :nth-child(1 of :not(script):not([hidden]):not(.rl-stagger-skip)) { animation-delay: 40ms; }
.rl-stagger-arm .rl-mnav-enabled .rl-stagger-in > :nth-child(2 of :not(script):not([hidden]):not(.rl-stagger-skip)) { animation-delay: 90ms; }
.rl-stagger-arm .rl-mnav-enabled .rl-stagger-in > :nth-child(3 of :not(script):not([hidden]):not(.rl-stagger-skip)) { animation-delay: 140ms; }
.rl-stagger-arm .rl-mnav-enabled .rl-stagger-in > :nth-child(4 of :not(script):not([hidden]):not(.rl-stagger-skip)) { animation-delay: 190ms; }
.rl-stagger-arm .rl-mnav-enabled .rl-stagger-in > :nth-child(5 of :not(script):not([hidden]):not(.rl-stagger-skip)) { animation-delay: 240ms; }
.rl-stagger-arm .rl-mnav-enabled .rl-stagger-in > :nth-child(n+6 of :not(script):not([hidden]):not(.rl-stagger-skip)) { animation-delay: 290ms; }
@keyframes rl-stagger-rise {
  from { opacity: 0; transform: translateY(var(--rl-space-2)); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .rl-stagger-arm .rl-mnav-enabled .rl-stagger-in > :not(script):not([hidden]):not(.rl-stagger-skip) { animation: none; }
}

/* ==========================================================================
   5. BottomTab — fixed 위치를 카드와 정렬
   mobile-nav.css의 left:0 right:0 풀폭을 카드 cap(768)으로 정정.
   배경/border 등 자체 시각은 mobile-nav.css 정의 그대로(카드 line과 정합되는 --rl-line-2 사용).
   ========================================================================== */
.rl-mnav-enabled .rl-mnav-bottomtab {
  left: 50%;
  right: auto;
  transform: translateX(-50%);
  width: 100%;
  max-width: var(--rl-page-container);
}

/* ==========================================================================
   6. 오버레이 백드롭 cap — 페이지 컨테이너 안에만 dim (design-system §3.7.0 단일 출처)
   셸 자체가 "768 박스 안에서만 화면이 존재한다"는 시각 약속(§2.8.1) — 데스크탑에서
   컨테이너 밖 좌우 영역까지 scrim이 깔리면 차단할 배경 페이지가 없는데 dim만 깔린 빈
   상태가 되어 셸 위계가 깨진다. `#thema_wrapper` filter는 이미 컨테이너 안에서만
   작동하므로 backdrop만 cap을 맞추면 됨.

   대상 두 종 (둘 다 body 직속·fixed 풀폭이라 동일 패턴):
   - `.rl-overlay` — design-system §3.7.1 본 모달 백드롭(modal.css 정의). inprogress·
     unsaved·reminder·sheet-modal·guest-signup 등 .rl-modal 컴포넌트가 떠 있을 때
     배경 dim+자식 flex center.
   - `.modal-backdrop` — Bootstrap legacy 모달(`#confirmModal` 등)의 scrim.

   body 직속이라 `.rl-mnav-enabled` 스코프 밖이지만 셸이 켜진 페이지(`body.rl-mnav-page`)
   에서만 적용. `--rl-page-container` 토큰은 wrapper 스코프 안에 정의되어 cascade로
   닿지 않으므로 fallback 768px 필수. page-shell `--rl-page-container` 변경 시
   fallback도 동기화. modal panel(`.rl-modal` / `.modal-dialog`)은 자체 max-width로
   cap 안에 들어가므로 별도 처방 없음.

   `.rl-sheet`(시트 컨테이너)은 학습 페이지 전용 컴포넌트라 learn.css가 단일 출처.
   ========================================================================== */
body.rl-mnav-page .rl-overlay,
body.rl-mnav-page .modal-backdrop {
  right: auto;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  max-width: var(--rl-page-container, 768px);
}

/* ==========================================================================
   7. ≥992px col-md → col-sm 동등 폭 무력화 — 카드 768 안에서 그리드 점프 방지
   ========================================================================== */
@media (min-width: 992px) {
  .rl-mnav-enabled .col-md-1 { width: 16.66666667%; }
  .rl-mnav-enabled .col-md-2 { width: 33.33333333%; }
  .rl-mnav-enabled .col-md-3 { width: 50%; }
  .rl-mnav-enabled .col-md-4 { width: 50%; }
  .rl-mnav-enabled .col-md-5 { width: 66.66666667%; }
  .rl-mnav-enabled .col-md-6 { width: 100%; }
  .rl-mnav-enabled .col-md-7 { width: 100%; }
  .rl-mnav-enabled .col-md-8 { width: 100%; }
  .rl-mnav-enabled .col-md-9 { width: 100%; }
  .rl-mnav-enabled .col-md-10 { width: 100%; }
  .rl-mnav-enabled .col-md-11 { width: 100%; }
  .rl-mnav-enabled .col-md-12 { width: 100%; }
  .rl-mnav-enabled [class*="col-md-pull-"],
  .rl-mnav-enabled [class*="col-md-push-"],
  .rl-mnav-enabled [class*="col-md-offset-"] { left: auto; right: auto; margin-left: 0; }
}

/* ==========================================================================
   8. App Shell 모드 (입력 화면 opt-in) — 페이지가 $rl_app_shell=true 설정 시
   theme/basic/head.sub.php가 body.rl-app-shell 부여. (킬스위치: 미설정 페이지는 본 룰 미발화)

   목적: document(body) 스크롤을 차단해 iOS가 입력 포커스 시 문서를 스크롤하며 고정 앱바·
   컴포저 바를 밀어 올리는 것(focus-scroll)과 키보드+스크롤 떨림을 제거. 본문은 페이지의
   내부 스크롤 영역(.rl-composer-scroll-area 등, position:fixed + overflow-y:auto)만 스크롤한다.

   body를 viewport에 고정(position:fixed). 모달 스크롤락(modal-util.js)도 body를 fixed로
   잠그므로 충돌 없음(시트 열림/닫힘 시 inline override→복원, 클래스 룰로 회귀). 페이지 내
   고정 요소(.rl-composer-scroll-area·앱바·바)는 viewport 기준이라 그대로 동작.
   ========================================================================== */
body.rl-app-shell {
  position: fixed;
  inset: 0;
  overflow: hidden;
}

/* App Shell 콘텐츠 스크롤 영역(탭/콘텐츠 페이지) — body 고정 페이지의 본문(.at-body)을 고정 앱바↔
   하단 탭바 "사이"만 내부 스크롤시킨다. 문서 루트가 안 스크롤되므로 iOS 키보드 패닝/오버스크롤
   (앱바 밀림·하단 잉여 여백)이 사라진다. 컴포저(.rl-composer-scroll-area, $hide_mobile_bottomtab)와
   달리 하단 탭바가 있는 페이지용 — bottom이 탭바 높이 기준, 키보드 열림 시 탭바 숨김에 맞춰 키보드까지.
   광고 안전: transform 미사용 — 고정 광고(앵커/오버레이)의 containing block을 만들지 않아 위치가
   보존된다. cap(768) 정렬은 left/right + margin으로(translateX 회피). #thema_wrapper로 specificity 확보
   (기존 .at-body bottom-tab padding 룰 override). */
body.rl-app-shell #thema_wrapper.rl-mnav-enabled .at-body {
  position: fixed;
  /* viewportShift 보정(transform 회피, 광고 안전) — iOS가 입력 포커스로 visual viewport를 패닝하면
     (vvTop>0) fixed인 본 영역이 가시영역 위로 밀려 하단에 키보드 위 회색 갭이 생긴다. 컴포저는
     translateY(--rl-vv-shift)로 되돌리지만 광고 페이지는 transform 금지라 top/bottom 오프셋으로 등가
     보정: top에 +vvShift(아래로 이동), bottom에서 −vvShift(box 높이 보존하며 함께 하강) → 앱바↔키보드
     사이에 정확히 맞물린다. 키보드 닫힘 시 --rl-vv-shift=0(JS 리셋)이라 base는 불변. */
  top: calc(var(--rl-h-appbar) + var(--rl-safe-top, 0px) + var(--rl-vv-shift, 0px));
  bottom: calc(var(--rl-h-bottomtab) + var(--rl-safe-bottom-capped, 0px));
  left: 0;
  right: 0;
  margin-inline: auto;
  width: 100%;
  max-width: var(--rl-page-container);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  box-sizing: border-box;
  /* 탭바 예약 padding-bottom(문서스크롤용)은 불요 — bottom이 탭 위에서 영역을 끝낸다. */
  padding-bottom: 0;
  /* 하단 탭/CTA·인플로우 광고가 마지막 콘텐츠/캐럿을 가리지 않게 끝 여백 확보. */
  scroll-padding-bottom: var(--rl-sp-4);
}
/* 키보드 열림 → 하단 탭바 슬라이드다운(숨김) → 스크롤영역 하단을 키보드 위까지 확장.
   −vvShift: 위 top의 +vvShift와 짝 — 패닝으로 위로 밀린 박스를 도로 내려 bottom edge를 키보드 top에
   정확히 맞춘다(키보드 위 회색 갭 제거). vvShift>kbInset 시 0 클램프(box가 키보드 밑으로 안 내려감). */
body.rl-app-shell #thema_wrapper.rl-mnav-enabled.rl-mnav-kb-open .at-body {
  bottom: max(0px, calc(var(--rl-kb-inset, 0px) - var(--rl-vv-shift, 0px)));
}

/* App Shell plain 변형 — 하단탭·컴포저 바가 둘 다 없는 입력 폼(로그인·회원가입·계정수정).
   .at-body는 위 §8 공용 규칙으로 fixed 내부 스크롤이 되지만 기본 bottom이 하단탭(--rl-h-bottomtab)을
   예약한다 — 탭 없는 페이지는 하단에 탭 크기만큼 빈 띠가 생기므로 safe만 비운다(non-kb-open).
   컴포저/댓글은 본문이 별도 .rl-composer-scroll-area라 이 변형 대상 아님 — 전용 클래스(.rl-app-shell-plain,
   $rl_app_shell_plain=true)로 명시 구분해 그쪽 .at-body(빈 래퍼)는 건드리지 않는다.
   키보드 열림 bottom(max(0, kbInset−vvShift))·top·wrapper surface는 §8 공용 규칙이 그대로 처리.
   :not(.rl-mnav-kb-open) 필수 — 이 규칙과 kb-open 규칙은 동일 specificity라, 게이트 없으면 소스 순서상
   이 규칙이 뒤라 키보드 열림에도 bottom:safe로 이겨 SA가 키보드 뒤까지 늘어난다(입력이 키보드에 가림). */
body.rl-app-shell.rl-app-shell-plain #thema_wrapper.rl-mnav-enabled:not(.rl-mnav-kb-open) .at-body {
  bottom: var(--rl-safe-bottom-capped, 0px);
}
