/* 고등 7종의 껍데기를 3열 대시보드에서 단일 작업면 + 서랍으로 바꾸는 레이아웃 계층 */

/* ═══════════════════════════════════════════════════════════════
   이 파일이 대체하는 것 — 각 페이지 인라인 <style> 에서 지운 규칙들이다.
     header · .logo · .logo-mark · .logo-sub · .rag-badge · .rag-dot
     .hstats · .hpill · .layout · .lsb · .sb-head · .xp-strip · .xp-row
     .xpbar · .xpfill · .rpanel · .rpc · .rpt · #radarCvs · .center
     그리고 720px/1120px 미디어쿼리

   덮어쓰지 않는 것 — 밝기(다크/라이트)는 appearance.css 가 이미 한다.
   토큰을 여기서 또 정의하면 두 벌이 갈린다. 여기는 배치만 한다.

   설계 문서 — Dreamer AI 고등 수학 학습 UI 전면 개편 설계(26.08.08) §5
   ═══════════════════════════════════════════════════════════════ */

:root{
  --cbar-h:52px;
  --tabs-h:58px;
  --drawer-w:320px;
  --ws-ease:cubic-bezier(.22,.61,.36,1);
}

/* ── 셸 ──────────────────────────────────────────────────────── */
.shell{position:relative;z-index:1;display:flex;flex-direction:column;min-height:100vh;}

/* ═══ C-1 컨텍스트 바 — 요소 4개, 52px 한 줄 (설계 §5-2) ═══════
   게임 칩 6개가 있던 자리다. 남는 것은 위치 하나와 진도 막대 하나뿐이다. */
header.cbar{
  position:sticky;top:0;z-index:300;
  display:flex;align-items:center;gap:12px;
  height:var(--cbar-h);padding:0 clamp(.6rem,2.2vw,1.3rem);
  background:var(--bg1);border-bottom:1px solid var(--border);
  box-shadow:var(--shadow);
}
.cbar-back{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:34px;height:34px;padding:0 8px;border-radius:999px;
  border:1.5px solid var(--border);background:var(--bg2);
  color:var(--muted);text-decoration:none;font-size:14px;flex:none;
  transition:all .18s var(--ws-ease);
}
.cbar-back:hover{border-color:var(--forest-text);color:var(--forest-text);}

.cbar-where{
  display:flex;align-items:baseline;gap:6px;min-width:0;
  font-size:14px;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.cbar-where b{font-family:"Do Hyeon",sans-serif;font-weight:400;color:var(--forest-text);}
.cbar-where span{font-size:12px;color:var(--muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.cbar-spacer{flex:1;}

/* 진도 — 숫자 하나 + 막대 하나. 그 이상 올리지 않는다.
   XP·연속일수·정답률은 서랍으로 내려갔다 (설계 P-4) */
.wk{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--muted);flex:none;}
.wk-track{width:clamp(64px,11vw,132px);height:7px;border-radius:999px;
  background:var(--bg2);overflow:hidden;border:1px solid var(--border);}
.wk-fill{display:block;height:100%;border-radius:999px;width:0;
  background:linear-gradient(90deg,var(--star),var(--aurora));transition:width .6s var(--ws-ease);}
.wk b{color:var(--text);font-family:"Do Hyeon",sans-serif;font-weight:400;}

.cbar-btn{
  display:inline-flex;align-items:center;justify-content:center;gap:4px;
  height:34px;padding:0 12px;border-radius:999px;flex:none;
  border:1.5px solid var(--border);background:var(--bg2);
  color:var(--text);font-size:12px;font-family:inherit;cursor:pointer;
  transition:all .18s var(--ws-ease);
}
.cbar-btn:hover{border-color:var(--aurora);}
.cbar-btn[aria-pressed="true"]{background:var(--bg0);border-color:var(--aurora);color:var(--aurora);}

/* ═══ 레이아웃 — 고정 사이드바 없음 (설계 §5-1) ═══════════════ */
.layout{
  display:grid;grid-template-columns:1fr;
  min-height:calc(100vh - var(--cbar-h));
  max-width:none;margin:0 auto;width:100%;
  align-items:start;
}
.layout.drawer-open{grid-template-columns:1fr var(--drawer-w);}

/* ═══ 작업면 — 수식 한 줄이 안 넘치는 최대 폭 ═════════════════ */
.center{
  padding:clamp(.7rem,2vw,1.15rem);
  display:flex;flex-direction:column;gap:12px;background:transparent;
  width:min(940px,100%);margin-inline:auto;min-width:0;
}
.layout.drawer-open .center{margin-inline:auto;}

/* ═══ 서랍 — 1024px 이하에서 사라지지 않고 오버레이가 된다 ═════
   현행 결함 D-9 대응. .rpanel 은 display:none 으로 데이터를 없앴다. */
.drawer{
  display:none;flex-direction:column;gap:12px;
  position:sticky;top:calc(var(--cbar-h) + 10px);
  max-height:calc(100vh - var(--cbar-h) - 20px);
  overflow-y:auto;padding:0 12px 16px 0;
}
.layout.drawer-open .drawer{display:flex;}
@media(max-width:1024px){
  .layout.drawer-open{grid-template-columns:1fr;}
  .layout.drawer-open .drawer{
    position:fixed;inset:var(--cbar-h) 0 0;z-index:290;
    max-height:none;padding:12px;overflow-y:auto;
    background:var(--bg0);
  }
}
.dcard{
  background:var(--bg1);border:1.5px solid var(--border);
  border-radius:var(--r14);padding:12px 12px;
}
.dtitle{
  font-family:"Do Hyeon",sans-serif;font-size:12px;
  color:var(--forest-text);margin-bottom:8px;letter-spacing:.02em;
}
.dnote{font-size:12px;color:var(--muted);margin-top:6px;line-height:1.6;}

/* 서랍으로 내려온 게임 칩 — 가로 나열에서 세로 목록으로 바꾼다 */
.drawer .hstats{display:flex;flex-direction:column;gap:6px;}
.drawer .hpill{
  display:flex;align-items:center;gap:6px;
  background:var(--bg2);border:1px solid var(--border);
  border-radius:var(--r9);padding:6px 12px;
  font-size:12px;font-weight:600;white-space:nowrap;
  color:var(--text);cursor:default;
}
.drawer .hpill .v{color:var(--forest-text);font-family:"Do Hyeon",sans-serif;font-weight:400;
  margin-left:auto;}
.drawer .hpill[id]{cursor:pointer;}
.drawer .hpill[id]:hover{border-color:var(--aurora);}

/* ═══ 모바일 하단 탭 — 목적지 4개 (설계 §5-5) ════════════════ */
.htabs{
  position:fixed;left:0;right:0;bottom:0;z-index:295;display:none;
  background:var(--bg1);border-top:1.5px solid var(--border);
  padding-bottom:env(safe-area-inset-bottom);
}
.htabs .row{display:grid;grid-template-columns:repeat(4,1fr);}
.htab{
  display:flex;flex-direction:column;align-items:center;gap:2px;
  padding:6px 0 8px;border:none;background:none;cursor:pointer;
  font-size:12px;color:var(--muted);font-family:inherit;
}
.htab .ic{font-size:16px;line-height:1;}
.htab[aria-selected="true"]{color:var(--forest-text);}

/* ═══ C-3 문항 — 20px / 1.75 (설계 §6-3) ═════════════════════ */
.prob-q{
  background:var(--bg2);
  border-radius:var(--r14);padding:16px 16px;margin-bottom:12px;
  font-size:var(--fs-body-xl,20px);line-height:1.75;font-weight:600;
  border-left:4px solid var(--forest-text);position:relative;
  word-break:keep-all;overflow-x:auto;
}

/* ═══ C-4 5지선다 — 1행 5열 (수능 답지와 동형, 설계 §5-3) ═════
   기존 1fr 1fr 2열은 선택지를 세로로 쌓아 한눈 비교를 막았다.
   선택지 비교는 5지선다 풀이의 핵심 동작이라 방해하면 안 된다. */
.mcq{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;margin-bottom:12px;}
.mcq:has(> .mopt:nth-child(4):last-child){grid-template-columns:repeat(4,1fr);}
.mcq:has(> .mopt:nth-child(3):last-child){grid-template-columns:repeat(3,1fr);}
.mcq:has(> .mopt:nth-child(2):last-child){grid-template-columns:repeat(2,1fr);}
/* 값은 전부 척도에서 온다 (26.08.08). 종전 12px/6px/66px/r14/2px 은 척도 밖이었고,
   실측 높이가 86px 로 --h-opt(64px)보다 22px 높았다. 여백을 척도로 줄이면 맞는다.
   높이를 못 박지 않고 «최소»로 두는 것은, 보기 글이 길면 늘어나야 하기 때문이다. */
.mopt{
  padding:var(--sp-4);border-radius:var(--r-12);border:1px solid var(--border);
  background:var(--panel);color:var(--text);font-size:14px;font-weight:600;
  cursor:pointer;transition:all .18s var(--ws-ease);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--sp-2);
  text-align:center;font-family:inherit;min-height:var(--h-opt);
}
.mopt:hover:not(:disabled){border-color:var(--forest-text);transform:translateY(-2px);}
/* 번호 뱃지. **크기는 여기서 안 정한다** — starlight.css 가 나중에 실려서 이긴다.
   두 파일이 같은 값을 각자 갖고 있으면, 고쳐도 안 바뀌는 일이 생긴다.
   실제로 여기서 24→20px 로 줄였는데 화면은 28px 그대로였다 (26.08.08).
   크기·모서리는 starlight.css 한 곳이 갖는다. 여기는 색과 배치만 갖는다. */
.mmk{
  background:var(--border);
  display:flex;align-items:center;justify-content:center;
  font-weight:700;line-height:1;flex-shrink:0;transition:all .2s;
}
/* 보기 글이 길면 5열이 무너진다 — 그때만 세로 배치로 되돌린다 */
.mcq.mcq-long{grid-template-columns:1fr 1fr;}
/* 52px 은 척도 밖 값이었다. 긴 보기라고 낮을 까닭이 없다 — 같은 --h-opt 를 쓴다 */
.mcq.mcq-long .mopt{flex-direction:row;justify-content:flex-start;text-align:left;min-height:var(--h-opt);}
@media(max-width:560px){
  .mcq{grid-template-columns:repeat(2,1fr);}
  .mcq.mcq-long{grid-template-columns:1fr;}
}

/* ═══ 한 화면 한 가지 일 (설계 P-1 · §4-1) ═══════════════════
   현행의 진짜 문제는 3열이 아니라 「중앙 열에 마운트 8개가 세로로 쌓인다」였다.
   문제를 푸는 화면인데 별탑 지도와 동료 패널이 문제 위를 덮고 있었다.

   그래서 단계(S.phase)로 화면을 가른다. worksurface.js 가 body[data-phase] 를 붙인다.
     0 개념   — 지도 · 동료 · 이어서 풀기를 보여준다 (여기가 그것들의 자리다)
     1~6      — 도구와 문제만 남긴다
   DeltaMath · Dr Frost · Math Academy 의 풀이 화면에 사이드바가 없는 것과 같은 규칙이다. */
body[data-phase]:not([data-phase="0"]) #starMap,
body[data-phase]:not([data-phase="0"]) #starCompanion,
body[data-phase]:not([data-phase="0"]) #starResume,
body[data-phase]:not([data-phase="0"]) .focus-toggle{display:none !important;}

/* ═══ 내부 파이프라인 노출 제거 (설계 §4-3 · P-5) ═════════════
   K-Tree → Retrieve → Augment → Generate 는 우리 RAG 구조지 학습 내용이 아니다.
   마크업은 남긴다 — animRagStep() 이 이 id 들을 토글하기 때문이다.
   화면에서만 걷어낸다. */
.rag-pipeline,
.ret-nodes,
.rag-badge{display:none !important;}

/* ═══ 접근성 · 반응형 ════════════════════════════════════════ */
@media(max-width:640px){
  .htabs{display:block;}
  .shell{padding-bottom:calc(var(--tabs-h) + env(safe-area-inset-bottom));}
  .center{padding:8px 8px 16px;gap:12px;}

  /* 컨텍스트 바 — 52px 한 줄을 지킨다. 라벨은 아이콘으로 접는다 */
  header.cbar{gap:6px;padding:0 8px;}
  .cbar-where span{display:none;}
  .wk-lab{display:none;}
  .wk-track{width:52px;}
  .cbar-btn{font-size:0;padding:0 8px;}
  .cbar-btn::before{content:"☰";font-size:16px;}

  .prob-q{font-size:18px;padding:16px 16px;}
}

/* 큰 화면에서 서랍이 열려도 작업면이 찌그러지지 않게 */
@media(min-width:1025px){
  .layout.drawer-open .center{width:min(880px,100%);}
}

/* ═══ 라이트(종이)에서의 별빛 표면 ════════════════════════════
   starlight.css 는 색을 거의 토큰으로 쓰지만, 패널 표면만은 어두운
   남색 rgba 가 13곳에 박혀 있었다. 그대로 두면 흰 배경 위에 회색 판이
   깔리고 그 위의 var(--muted) 글자가 안 읽힌다 — 탐색 3탭과
   관문 점등판이 실제로 그랬다.

   그래서 starlight.css 쪽 리터럴을 --sl-* 토큰으로 빼고(기본값은 옛 값
   그대로라 다크는 회귀 0), 라이트 값만 여기서 덮는다. */
html[data-appearance="light"]{
  --sl-panel-a:#FFFFFF;
  --sl-panel-b:#FBFCFE;
  --sl-inset:  #F4F7FB;
  --sl-fade-0: rgba(251,252,254,0);
  --sl-fade-1: rgba(251,252,254,.96);
  --sl-ring:   rgba(255,255,255,.95);
}
/* 토큰으로 못 빼는 나머지 — 채우기·글자색 리터럴 4곳 */
html[data-appearance="light"] .story-tab.on{color:#fff;}
html[data-appearance="light"] .cst-node .wm-core{fill:#C7D0EA;}
html[data-appearance="light"] .cst-node:hover .wm-core{fill:#9FB0DC;}
html[data-appearance="light"] .dialogue{background:var(--bg2);}
/* 별밭 배경은 검은 하늘 위 흰 점이다. 종이 위에서는 먼지로 보인다. */
html[data-appearance="light"] #starfield,
html[data-appearance="light"] .leaf-bg{display:none;}

/* `--core` 가 h3 에만 없다 (26.08.08). 다른 6종은 `:root` 에 `--core:var(--ember)`
   를 두는데 h3 만 빠져서, 그것을 쓰는 자리가 통째로 죽었다 —
   「관문 이야기」 탭의 고른 쪽 배경이 판 색으로 떨어져 대비 1.15:1 이었다.

   **`html` 로 적는다.** 특이도가 `:root`(0,0,1,0)보다 낮은 (0,0,0,1) 이라
   정의한 6종은 자기 값을 그대로 쓰고, 빠진 h3 만 이 값을 받는다.
   빠진 곳만 채우는 것이지 덮어쓰는 것이 아니다.
   (h3 의 `.leaf-bg{position:fixed}` 누락과 같은 갈래다.) */
html{--core:var(--ember);}

/* 별밭은 **배경**이다 — 흐름에서 빠져 있어야 한다 (26.08.08).
   h3 만 인라인에 `position:fixed` 가 빠져 있어서, 이모지 507px 가 흐름 안에
   서서 화면 전체를 아래로 밀었다. 개념이 294px 대신 818px 에 있었다.
   라이트에서는 위 규칙이 숨겨서 안 보이던 결함이다 — 기본을 다크로 되돌리자
   드러났다. 인라인 7벌을 고치는 대신 여기서 못 박는다. */
#starfield,.leaf-bg{position:fixed;inset:0;z-index:0;pointer-events:none;}

/* ── 스크롤바 ── */
.drawer::-webkit-scrollbar{width:4px;}
.drawer::-webkit-scrollbar-thumb{background:var(--border);border-radius:4px;}

/* ═══ 오답 이유 6분류 (설계 §10 · wrongnote.js) ═══════════════
   난이도 집계는 「무엇을」까지만 말한다. 「왜」는 학생만 안다. */
.wn-top{margin-bottom:12px;}
.wn-dist{display:flex;height:12px;border-radius:999px;overflow:hidden;
  background:var(--bg2);border:1px solid var(--border);}
.wn-dist i{display:block;height:100%;}
.wn-leg{display:flex;gap:12px;flex-wrap:wrap;margin-top:6px;
  font-size:12px;color:var(--muted);}
.wn-leg b{display:inline-block;width:9px;height:9px;border-radius:4px;margin-right:4px;vertical-align:middle;}
.wn-hint{margin-top:6px;font-size:12px;color:var(--muted);line-height:1.6;}
.wn-hint b{color:var(--forest-text);}

.wn-row{margin-top:12px;padding-top:12px;border-top:1px dashed var(--border);}
.wn-tags{display:flex;gap:4px;flex-wrap:wrap;margin-bottom:8px;}
.wn-tag{
  padding:4px 8px;border-radius:999px;cursor:pointer;
  border:1.5px solid var(--border);background:var(--bg2);color:var(--muted);
  font-size:12px;font-family:inherit;transition:all .15s var(--ws-ease);
}
.wn-tag:hover{border-color:var(--forest-text);color:var(--text);}
.wn-tag[aria-pressed="true"]{background:var(--flt);font-weight:700;}
.wn-foot{display:flex;align-items:center;gap:12px;flex-wrap:wrap;font-size:12px;color:var(--muted);}
.wn-reps{white-space:nowrap;}
.wn-none{margin-left:auto;opacity:.75;}
.wn-go{
  margin-left:auto;padding:4px 12px;border-radius:999px;cursor:pointer;
  border:1.5px solid var(--aurora);background:transparent;color:var(--aurora);
  font-size:12px;font-family:inherit;white-space:nowrap;
}
.wn-go:hover{background:var(--flt);}
@media(max-width:560px){
  .wn-foot{font-size:12px;}
  .wn-go,.wn-none{margin-left:0;}
}

/* ═══ 트랙 선택기 (설계 §11 · track.js) ══════════════════════
   기제는 이미 돌고 있었다. 없던 것은 학생이 «고르는 자리»다. */
.tkcard .dtitle{margin-bottom:6px;}
#trackPick{display:flex;flex-direction:column;gap:6px;}
.tk{
  display:grid;grid-template-columns:auto 1fr auto;align-items:baseline;gap:8px;
  width:100%;text-align:left;cursor:pointer;
  padding:8px 12px;border-radius:var(--r9);
  border:1.5px solid var(--border);background:var(--bg2);color:var(--text);
  font-family:inherit;transition:all .15s var(--ws-ease);
}
.tk:hover:not(:disabled){border-color:var(--forest-text);}
.tk[aria-pressed="true"]{border-color:var(--aurora);background:var(--flt);}
.tk b{font-family:"Do Hyeon",sans-serif;font-weight:400;font-size:14px;}
.tk[aria-pressed="true"] b{color:var(--aurora);}
.tk span{grid-column:1/-1;font-size:12px;color:var(--muted);line-height:1.5;}
.tk i{font-style:normal;font-size:12px;color:var(--muted);white-space:nowrap;}
.tk:disabled{opacity:.45;cursor:default;}
.tk:disabled span{color:var(--hint,var(--muted));}

/* ═══ 개념·오개념 카드 (cards.js) ════════════════════════════
   파일에 있는데 화면에 안 닿던 35개를 잇는다. 감사가 「배선 0/7」로 세던 것이다. */
.cardset{margin-top:2px;}
.ccard,.mcard{padding:12px 12px;border-radius:var(--r9);background:var(--bg2);
  border:1px solid var(--border);margin-bottom:8px;}
.ccard:last-child,.mcard:last-child{margin-bottom:0;}
.ccard b,.mcard b{font-family:"Do Hyeon",sans-serif;font-weight:400;font-size:16px;
  color:var(--text);margin-right:6px;}
.ccard .dm{font-size:12px;color:var(--muted);}
.ccard p,.mcard p{font-size:14px;line-height:1.7;color:var(--muted);margin-top:6px;}
.ccard .key{color:var(--text);border-left:3px solid var(--forest-text);
  padding-left:8px;margin-top:8px;}
.ccard ul{margin:6px 0 0 16px;font-size:12px;color:var(--muted);line-height:1.8;}
.mcard{border-left:3px solid var(--hp-red,var(--coral));}
.mcard .ex{font-family:"Cambria Math","Times New Roman",serif;color:var(--text);}
.mcard .fix{color:var(--text);}

/* ═══════════════════════════════════════════════════════════════
   타이포그래피 고도화 (26.08.08) — 한국 에듀테크 관행에 맞춘다

   ## 잰 것 (h1 배우기 화면, 1280px)
     body            Gowun Dodum · 16px · line-height **normal(≈1.2)** · 자간 normal
     .sc-lead        18.56px · 한 줄 46자
     .sc-why-in      15.04px · 한 줄 **57자**
     .lcard-title    weight **900** (고운돋움엔 900 자체가 없다 → 가짜 굵기)

   ## 결함 셋
   1. **본문에 행간이 없다.** `body` 가 line-height 를 안 정해 브라우저 기본 1.2 로 간다.
      한글 장문은 1.7~1.8 이 필요하다. 지금은 줄이 서로 붙어 있다.
   2. **본문 글꼴이 고운돋움이다.** 감성·전시용 서체지 장문 읽기용이 아니다.
      한국 에듀테크는 Pretendard 계열이 사실상 표준이고, 2024.04 부터 범정부
      UI/UX 디자인 시스템도 Pretendard GOV 를 기본 서체로 쓴다.
   3. **한 줄이 46~57자다.** 한글 최적은 35~45자다. 눈이 줄을 놓친다.

   ## 무엇을 바꾸고 무엇을 안 바꾸나
   바꾼다   — «읽는 글»의 글꼴·행간·줄길이·자간
   안 바꾼다 — 제목·버튼·숫자의 Do Hyeon, 드리미 대사의 Gowun Batang.
              브랜드 목소리는 그대로 둔다. 바꾸는 것은 «오래 읽는 자리»뿐이다.

   Pretendard 를 자체 호스팅하지 않는다 — vendor/fonts 에 없고, 넣으려면 배포 용량과
   라이선스 확인이 따로 필요하다. 대신 **설치돼 있으면 쓰고, 없으면 OS 기본 한글 고딕**
   으로 내려가는 스택을 쓴다. Malgun Gothic·Apple SD Gothic Neo 둘 다 고운돋움보다
   장문 가독성이 낫다. 자체 호스팅은 후속 과제로 남긴다.
   ═══════════════════════════════════════════════════════════════ */

:root{
  --read: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont,
          "Apple SD Gothic Neo", "Malgun Gothic", "맑은 고딕",
          "Noto Sans KR", system-ui, sans-serif;
  --read-lh: 1.75;
  --read-ls: -.01em;
  --read-w: 38em;      /* 한글 한 줄 35~45자 */
}

body{
  font-family:var(--read);
  line-height:var(--read-lh);
  letter-spacing:var(--read-ls);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

/* 오래 읽는 자리 — 줄 길이를 묶는다. 수식 블록은 이 제한을 안 받는다 */
.sc-why-in, .sc-def, .prose,
.adapt-bar, .st-why, .err-why, .rag-hint-text, .dnote{
  max-width:var(--read-w);
  line-height:var(--read-lh);
}
.sc-lead{max-width:26em;line-height:1.55;}

/* 가짜 굵기 금지 — 고운돋움·Pretendard 모두 900 을 합성으로 만든다.
   합성 굵기는 획이 뭉개져서 오히려 안 읽힌다. 700 까지만 쓴다. */
.lcard-title, .rpt, .sb-head, .st-tag, .redo-lbl, .err-ok, .fc-lbl,
.mring-pct, .rag-out-label, .rag-hint-label{font-weight:700;}

/* 문항 본문 — 가장 오래 보는 글이다 */
.prob-q{
  font-family:var(--read);
  line-height:1.8;
  letter-spacing:-.005em;   /* 수식이 섞이므로 자간을 덜 좁힌다 */
}
.mopt{font-family:var(--read);line-height:1.6;}

/* 제목·버튼·숫자는 그대로 Do Hyeon. 드리미 목소리는 그대로 Gowun Batang */
h1,h2,h3,h4,.lcard-title,.sc-title,.dtitle,.cbar-where b{font-family:"Do Hyeon",var(--read);}
.voice,.dialogue p{font-family:"Gowun Batang",serif;line-height:1.8;}

/* ── 글자 뒤 배경을 줄인다 ────────────────────────────────────
   지금은 문단마다 채워진 상자가 깔려 있다. 상자가 많으면 «어디를 읽어야 하는지»가
   사라진다 — 강조가 전부면 강조가 없는 것과 같다.
   채우기를 걷고 왼쪽 선 하나로 바꾼다. 위계는 선과 여백이 만든다. */
html .sc .sc-facts li{
  background:transparent;
  border-left:3px solid var(--aurora);
  border-radius:0 var(--r9) var(--r9) 0;
  padding-left:12px;
}
/* 이 선은 **열렸을 때 머리와 본문을 가르는** 선이다. 닫혀 있으면 가를 것이 없어서
   뜻 없는 밑줄만 남는다 — 개념 예제가 「답 확인」·「풀이 보기」로 접히면서
   한 화면에 그 선이 여럿 생겼고, 사용자가 「불필요한 밑줄」로 신고했다 (26.08.18). */
html .sc .sc-why-box > summary{background:transparent;}
html .sc .sc-why-box[open] > summary{border-bottom:1px solid var(--border);}
.adapt-bar{background:transparent;border:none;border-left:3px solid var(--forest-text);
  border-radius:0;padding-left:12px;}
html .cardset .ccard,html .cardset .mcard{background:transparent;border-width:0 0 0 3px;border-radius:0;padding-left:12px;}
.mcard{border-left-color:var(--hp-red,var(--coral));}
.ccard{border-left-color:var(--forest-text);}

/* 라이트에서 본문 배경은 한 겹만 — 종이 위에 종이를 겹치지 않는다 */
html[data-appearance="light"] .lcard,
html[data-appearance="light"] .rag-panel{background:var(--bg1);}
html[data-appearance="light"] .st-expr,
html[data-appearance="light"] .nlp-sent{background:transparent;border-left:3px solid var(--gold);}

/* ═══ 학습 로드맵 (설계 R-2 · roadmap.js) ═════════════════════
   실측에서 배운 것 — 상용 서비스는 진도를 «막대»가 아니라 «상태 이름»과
   «관문»으로 센다 (8곳 중 7곳이 role="progressbar" 0개).
   그래서 상태 이름이 앞이고 막대는 뒤에 얇게 깐다. */
/* 접힌 상태가 기본이다 (26.08.08). 시제품의 첫 카드가 «한 줄 + 막대»라서,
   여기도 접히면 ~120px 다. 펼치면 종전 그대로 전부 나온다. */
.rm{display:block;}
.rm[open]{display:flex;flex-direction:column;gap:var(--sp-4,8px);}
.rm-head{
  display:grid;grid-template-columns:auto 1fr auto;align-items:baseline;
  gap:var(--sp-5,12px);cursor:pointer;list-style:none;
  padding:var(--sp-5,12px) var(--sp-6,16px);
  background:var(--panel);border:1px solid var(--border);border-radius:var(--r-12);
}
.rm[open] .rm-head{margin-bottom:var(--sp-2,4px);}
.rm-head::-webkit-details-marker{display:none;}
.rm-head::after{content:'펼치기';font-size:var(--fs-label,12px);color:var(--muted);}
.rm[open] .rm-head::after{content:'접기';}
.rm-at{font-size:var(--fs-body-s,14px);color:var(--muted);text-align:right;}
/* 접혔을 때의 막대 — 한 줄 아래에 얇게 깔린다 */
.rm-bar.rm-top{grid-column:1/-1;position:static;height:4px;margin-top:var(--sp-3,6px);
  background:var(--border);border-radius:var(--r-full);overflow:hidden;}
.rm-bar.rm-top > i{display:block;height:100%;background:var(--aurora);border-radius:var(--r-full);}
.rm-eyebrow{font-size:12px;letter-spacing:.1em;color:var(--muted);}
.rm-unit{font-family:"Do Hyeon",sans-serif;font-size:16px;color:var(--forest-text);}

.rm-row{
  position:relative;display:grid;
  grid-template-columns:auto 1fr auto;align-items:center;gap:var(--sp-5,12px);
  width:100%;text-align:left;cursor:pointer;
  padding:var(--sp-5,12px) var(--sp-6,16px) calc(var(--sp-5,12px) + 4px);
  border:1px solid var(--border);border-radius:var(--r-12,12px);
  background:var(--bg1);color:var(--text);font-family:inherit;
  transition:border-color .15s,transform .15s;
}
.rm-row:hover{border-color:var(--aurora);transform:translateX(2px);}
.rm-row.rm-cur{border-color:var(--aurora);background:var(--flt);}
/* 관문은 차시와 다른 무게다 — «하는 것»이지 «읽는 것»이 아니다 */
.rm-gate{border-style:dashed;border-color:var(--gold);}
.rm-gate:hover{border-color:var(--gold);}

.rm-mark{
  width:26px;height:26px;flex:none;display:inline-flex;align-items:center;justify-content:center;
  border-radius:999px;background:var(--bg2);color:var(--muted);
  font-family:"Do Hyeon",sans-serif;font-size:12px;
}
.rm-gate .rm-mark{background:transparent;color:var(--gold);font-size:14px;}
.rm-main{min-width:0;}
.rm-nm{display:block;font-family:"Do Hyeon",sans-serif;font-size:14px;color:var(--text);}
.rm-why{display:block;font-size:12px;color:var(--muted);line-height:1.5;}
.rm-side{display:flex;align-items:center;gap:var(--sp-5,12px);flex:none;}

/* 상태 이름이 주인공이다 */
.rm-lv{font-family:"Do Hyeon",sans-serif;font-size:12px;white-space:nowrap;}
.rm-none{color:var(--muted);}
.rm-weak{color:var(--hp-red,var(--coral));}
.rm-practicing{color:var(--gold);}
.rm-familiar{color:var(--aurora);}
.rm-solid{color:var(--aurora);font-weight:700;}
.rm-next{font-size:12px;color:var(--aurora);white-space:nowrap;}

/* 막대는 보조 — 줄 아래 4px 띠로 깐다 */
.rm-bar{position:absolute;left:var(--sp-6,16px);right:var(--sp-6,16px);bottom:6px;
  height:3px;border-radius:999px;background:var(--bg2);overflow:hidden;}
.rm-bar i{display:block;height:100%;border-radius:999px;background:var(--aurora);}
.rm-note{font-size:12px;color:var(--muted);margin-top:var(--sp-2,4px);}
@media(max-width:640px){
  .rm-row{grid-template-columns:auto 1fr;}
  .rm-side{grid-column:2;justify-content:flex-start;}
}

/* ═══ 서랍 요약 (R-4·R-5) ══════════════════════════════════════
   상태 이름이 앞이고 숫자는 근거로 뒤에 붙는다. 막대는 없다. */
.ds-row{display:grid;grid-template-columns:4.2em 1fr;gap:var(--sp-5,12px);
  align-items:baseline;font-size:12px;margin-bottom:var(--sp-4,8px);}
.ds-k{font-size:12px;color:var(--muted);}
.ds-row b{font-family:"Do Hyeon",sans-serif;font-weight:400;color:var(--text);}
.ds-none{color:var(--muted);font-size:12px;}
.ds-go{padding:4px 12px;border-radius:999px;border:1px solid var(--aurora);
  background:transparent;color:var(--aurora);font-size:12px;cursor:pointer;font-family:inherit;}
.ds-go:hover{background:var(--flt);}

.ds-lvs{margin-top:var(--sp-5,12px);padding-top:var(--sp-5,12px);border-top:1px solid var(--border);}
.ds-lv{display:grid;grid-template-columns:1fr auto;gap:0 var(--sp-5,12px);margin-bottom:var(--sp-4,8px);}
.ds-nm{font-size:12px;color:var(--text);}
.ds-state{font-family:"Do Hyeon",sans-serif;font-size:12px;white-space:nowrap;}
.ds-why{grid-column:1/-1;font-size:12px;color:var(--muted);line-height:1.5;}

.ds-links{display:flex;gap:var(--sp-5,12px);margin-top:var(--sp-5,12px);
  padding-top:var(--sp-5,12px);border-top:1px solid var(--border);}
.ds-links a{font-size:12px;color:var(--aurora);text-decoration:none;}
.ds-links a:hover{text-decoration:underline;}

/* ═══ R-6 컨텍스트 바 breadcrumb ══════════════════════════════
   진도 막대를 상단에서 뺀다. 실측에서 8곳 중 7곳이 상단 바에 진도를 안 둔다.
   상단은 «어디에 있는지»만 말한다. 진도는 로드맵과 서랍이 맡는다. */
.crumb{display:flex;align-items:baseline;gap:6px;min-width:0;font-size:12px;
  color:var(--muted);white-space:nowrap;overflow:hidden;}
.crumb b{font-family:"Do Hyeon",sans-serif;font-weight:400;color:var(--forest-text);}
.crumb .sep{opacity:.5;}
.crumb .now{color:var(--text);overflow:hidden;text-overflow:ellipsis;}
@media(max-width:640px){
  .crumb .lv1,.crumb .sep1{display:none;}   /* 좁으면 과목을 접는다 */
}

/* 기계 스냅이 떨어뜨린 두 곳을 토큰으로 고정한다 (V-3 뒤처리).
   자동 정리는 «값을 줄이는» 일은 잘하지만 «무엇이 중요한지»는 모른다. */
html .prob-q{font-size:var(--fs-body-xl,20px);line-height:1.8;}
html #axonSummary .ds-state{font-size:var(--fs-body-s,14px);}
html #axonSummary .ds-why{font-size:var(--fs-label,12px);}

/* ═══ CLS — 늦게 채워지는 자리를 미리 잡는다 (P4-9) ══════════
   실측 — #axonRoadmap 이 94px → 823px 로 **729px 내려갔다**.
   그 위의 #starMap(509) + #starCompanion(219) = 728px 이 첫 그리기에는
   비어 있다가 435ms 에 채워지면서 아래 전부를 밀어낸 것이다.
   CLS 0.32 로 문턱(0.1)의 3.2배였다 — 학생이 읽으려는데 화면이 튄다.

   높이를 미리 잡으면 «밀어내기»가 «채우기»로 바뀐다.
   값은 지어낸 것이 아니라 실측한 완성 높이다.

   두 곳 다 개념 화면(phase 0)에서만 뜨므로, 그 밖에서는 예약도 안 한다
   — body[data-phase]:not([data-phase="0"]) 규칙이 display:none 으로 덮는다. */
#starMap:empty{min-height:509px;}
#starCompanion:empty{min-height:219px;}
/* 채워진 뒤에는 예약을 놓는다. 내용이 더 길면 늘어나야 한다. */
#starMap,#starCompanion{contain:layout;}

/* ═══════════════════════════════════════════════════════════════════
   시제품을 실제로 앉힌다 (26.08.08 · checklist-high-proto-apply)

   무엇이 문제였나 — 시제품(/high-prototype-4)과 라이브를 나란히 열어 쟀다.
   만든 것은 다 있었다. **자리가 틀렸다.**

     0px    #starMap        「변화의 회랑」 별지도      509px
     509px  #starCompanion  드리미 게임 패널          219px
     728px  #axonRoadmap    학습 로드맵               361px
     1089px #starNav        배우기·풀기·다시 보기       55px
     1615px ← 개념 4분할 카드가 여기 있다
     2982px 핵심 정리                                584px
     ────── 전체 3,785px

   시제품은 같은 화면이 ~1,000px 이고 순서가 «개념 먼저»다.
   학생이 개념을 만나려면 1,600px 을 내려야 했다. 그래서 안 고친 것으로 보인다.
   ═══════════════════════════════════════════════════════════════════ */

/* ── W-1 순서 — 개념을 맨 위로 ─────────────────────────────────
   **지우지 않는다. 내린다.** 학생이 쌓은 별빛·연속 밤이 뜻을 잃으면 안 된다.
   #centerMain 은 이미 display:flex 라 order 만으로 옮겨진다 —
   DOM 을 안 건드리므로 되돌리기가 이 블록을 지우는 것으로 끝난다. */
   시제품의 차례를 그대로 따른다 —
     ① 어디까지 왔나 (차시 진행)  ② 개념  ③ 문제
   로드맵이 ①의 자리다. 그래서 개념 «위»에 둔다. 아래로 밀면 시제품과 달라진다.

   덤으로 CLS 도 여기서 풀린다. 로드맵은 body 끝에서 동기로 그려지고(P4-9),
   개념(#phContent)은 문항을 받아 온 뒤 window.load 에서 그려진다.
   늦게 그려지는 것을 늦게 그려지는 것 «위»에 두면 아래가 통째로 밀린다. */
#centerMain{display:flex;flex-direction:column;}
#centerMain > #starNav      {order:1;}   /* 여기가 어디인지 */
#centerMain > #axonRoadmap  {order:2;}   /* 어디까지 왔나 — 시제품의 진행 카드 */
#centerMain > #phContent    {order:3;}   /* 주인공 — 개념과 문제 */
#centerMain > #starMap      {order:4;}   /* 지도는 «둘러보는» 것이다 */
#centerMain > #starCompanion{order:5;}   /* 응원도 마찬가지 */
/* #starGate 는 맨 끝이다. 532ms 에 746px 자리에서 사라지며 화면을 튀게 했다
   (실측 CLS 0.103). 접힌 자리로 내리면 같은 일이 일어나도 안 보인다. */
#centerMain > #starGate     {order:6;}

/* 순서를 바꾸면 #starMap 이 맨 아래로 간다 — 늦게 채워져도 위를 안 민다.
   그래도 예약은 남긴다. 아래에 #starCompanion 이 있어서 그건 밀린다.

   #phContent 는 `:empty` 로 예약할 수 없다. 재 보니 150ms 에 이미 474px 로
   차 있고 300ms 에 2,368px 로 «자란다» — 비어 있다 채워지는 게 아니라 커진다.
   대신 «한 화면분»을 바닥으로 깐다. 그러면 아래의 지도·응원·점등이
   접힌 자리에서 시작해, 그것들이 사라지거나 나타나도 학생 눈에 안 보인다.
   (실측 — 465ms 에 #starMap 이 756px 자리에서 사라지며 CLS 를 0.033 올렸다.) */
#phContent{min-height:70vh;}
/* 문제 화면에서는 바닥을 걷는다. 거기서는 지도·응원이 이미 display:none 이라
   밀 것이 없고, 바닥만 남으면 문제 카드 아래에 빈 땅이 생긴다. */
body[data-phase]:not([data-phase="0"]) #phContent{min-height:0;}

/* ── W-2 카드를 바탕에서 떼어 놓는다 ──────────────────────────
   카드(.lcard)는 있었다. 바탕(#FBFCFE)이 카드(#FFFFFF)와 거의 같아서
   떨어져 보이지 않았을 뿐이다. 시제품은 바탕을 한 단 내려(#F1F3F6)
   흰 카드가 뜨게 한다. 「배경과 개념과 문제를 시각적으로 분리」가 이것이다.

   **라이트일 때만이다.** 처음엔 `html:not([data-appearance="dark"])` 로 적었는데,
   기본이 별빛(다크)으로 돌아오면 «속성 없음 = 다크»라서 이 규칙이 다크에도 걸린다.
   그러면 어두운 화면에 회색 바탕이 깔린다. 조건을 라이트 하나로 좁힌다. */
html[data-appearance="light"] body{background:var(--page-2,#F1F3F6);}

/* 테두리 2px 는 카드가 여럿일 때 화면이 «선»으로 가득 찬다.
   바탕이 갈리면 굵은 선이 필요 없다 — 시제품이 1px 인 까닭이다. */
/* 모서리만 여기가 갖는다. **테두리 굵기는 surfaces.css 가 갖는다** (26.08.08 S-2).
   여기서 `border-width:1px` 로 네 변을 한꺼번에 정하고 있었는데, 그것이
   surfaces.css 의 «읽는 것» 왼쪽 3px 띠를 죽였다 — 특이도가 `html .lcard`(0,0,1,1)
   대 `.lcard`(0,0,1,0) 이라 순서를 바꿔도 이쪽이 이긴다.
   한 값의 주인은 하나여야 한다. 굵기는 넘긴다. */
html .lcard{border-radius:var(--r-16);}

/* ── W-3 읽는 폭 ──────────────────────────────────────────────
   실측 817px. 한글은 한 줄 35~45자를 넘으면 눈이 다음 줄 첫 글자를 못 찾는다.

   **--measure 를 글 하나하나에 걸면 안 된다.** 단위가 em 이라 22px 짜리
   리드 문장에서는 38em = 836px 가 되어 제한이 아니라 허가가 된다.
   실제로 걸어 봤더니 .sc-lead 가 684px 로 그대로였다.

   그래서 «기둥»을 좁힌다. 시제품의 .wrap 이 min(720px,100%) 인 것과 같다.
   여기서 좁히면 안의 글은 저절로 따라온다 — 재는 자리가 한 곳이라 어긋나지 않는다. */
html #centerMain{max-width:720px;margin-inline:auto;}
