/* 학생용 앱 — 교수 화면과 결이 반대입니다
 *
 * 이 파일은 app.css 뒤에 실립니다. app.css 가 이미 임자인 이름
 * (.find .pick .room .page .back) 은 쓰지 않습니다 — 뒤에 온다고 다 이기는 것이 아니라,
 * 저쪽이 정하고 이쪽이 안 정한 속성(width · max-height · background)은 그대로 흘러듭니다.
 *
 * 교수는 한 화면에 많이 훑어야 하므로 촘촘합니다.
 * 학생은 10분 제한 속에서 한 번에 하나만 봐야 하므로 성깁니다 —
 * 활자는 한 단계 크고, 표적은 44px 이상이며, 색을 갖는 것은 시간뿐입니다.
 */

.stu { background: var(--paper); color: var(--ink); }

/* ── 상단바 ─────────────────────────────────────────────── */
.sbar {
  position: sticky; top: 0; z-index: 20; height: var(--bar);
  display: flex; align-items: center; gap: var(--s4);
  padding: 0 var(--s5);
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(12px); border-bottom: 1px solid var(--line);
}
.sbar__mark { display: flex; align-items: center; flex: none; }
.sbar__logo { height: 30px; width: auto; }
.sbar__logo--dark { display: none; }
:root[data-theme="dark"] .sbar__logo--light { display: none; }
:root[data-theme="dark"] .sbar__logo--dark  { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .sbar__logo--light { display: none; }
  :root:not([data-theme="light"]) .sbar__logo--dark  { display: block; }
}
.sbar__who { font: var(--t-ui); color: var(--ink-2); }
.sbar__tools { display: flex; align-items: center; gap: var(--s1); margin-left: auto; }

/* ── 지면 ───────────────────────────────────────────────── */
.spage { max-width: 62rem; margin: 0 auto; padding: var(--s6) var(--s5) var(--s8); }
.spage--narrow { max-width: 42rem; }
.spage--wide { max-width: 60rem; }

.shead { margin-bottom: var(--s6); }
.shead__t { margin: 0; font: var(--t-display); letter-spacing: var(--tk-display); }
.shead__l { margin: var(--s2) 0 0; font: var(--t-body); color: var(--ink-2); }

.blank {
  display: grid; gap: var(--s2); justify-items: center; text-align: center;
  padding: var(--s8) var(--s5); border: 1px dashed var(--line-2); border-radius: var(--r-lg);
  color: var(--ink-3);
}
.blank b { font: var(--t-h2); letter-spacing: var(--tk-h2); color: var(--ink-2); }
.blank span { font: var(--t-small); }

.sback {
  display: inline-flex; align-items: center; gap: var(--s2);
  margin-bottom: var(--s5); font: var(--t-ui); color: var(--ink-3);
}
.sback:hover { color: var(--brand-ink); }

/* ── 1 · 오늘의 실습 ────────────────────────────────────── */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: var(--s4); }
.pcard {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s3) var(--s4);
  padding: var(--s5); border-radius: var(--r-lg);
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--band-line);
  color: inherit;
  transition: box-shadow var(--base) var(--ease), transform var(--base) var(--ease);
}
.pcard:hover { box-shadow: inset 0 0 0 1px var(--brand-line), var(--shadow-2); transform: translateY(-2px); }
.pcard__body { display: grid; gap: var(--s1); align-content: start; min-width: 0; }
.pcard__n { font: var(--t-name); letter-spacing: var(--tk-name); }
.pcard__m { font: var(--t-small); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.pcard__cp {
  justify-self: start; display: inline-flex; align-items: baseline; gap: var(--s2);
  margin-top: var(--s1); padding: var(--s-hair) var(--s2); border-radius: var(--r-full);
  background: var(--brand-soft); color: var(--brand-ink); font: var(--t-label); letter-spacing: var(--tk-chart);
}
.pcard__cp .num { font: var(--t-num-s); font-variant-numeric: tabular-nums; }
.pcard__p {
  margin: var(--s2) 0 0; font: var(--t-small); color: var(--ink-2); line-height: 1.6;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.pcard__foot {
  grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s4);
  padding-top: var(--s3); border-top: 1px solid var(--rule);
}
.pcard__t { display: inline-flex; align-items: baseline; gap: var(--s1); font: var(--t-small); color: var(--ink-2); }
.pcard__t .num { font: var(--t-num); font-variant-numeric: tabular-nums; color: var(--ink); }
.pcard__seat { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3); }

.past { margin-top: var(--s8); }
.past__t {
  display: flex; align-items: baseline; gap: var(--s3); margin: 0 0 var(--s3);
  font: var(--t-h2); letter-spacing: var(--tk-h2);
}
.past__avg { margin-left: auto; font: var(--t-small); color: var(--ink-3); }
.past__avg .num { font: var(--t-num); font-variant-numeric: tabular-nums; color: var(--ink); }
.past__rows { display: grid; }
.prow {
  display: grid; grid-template-columns: 3.4rem minmax(0, 1fr) minmax(0, 1fr) auto;
  align-items: baseline; gap: var(--s3);
  padding: var(--s3) 0; border-top: 1px solid var(--rule);
}
.prow__d  { font: var(--t-num-s); font-variant-numeric: tabular-nums; color: var(--ink-3); }
.prow__n  { font: var(--t-ui); }
.prow__cp { font: var(--t-small); color: var(--ink-3); }
.prow__s  { font: var(--t-small); color: var(--ink-3); }
.prow__s .num { font: var(--t-num); font-variant-numeric: tabular-nums; color: var(--ink); }

/* ── 2 · 브리핑 ─────────────────────────────────────────── */
.brief__id { display: flex; align-items: center; gap: var(--s4); margin-bottom: var(--s5); }
.brief__n { margin: 0; font: var(--t-display); letter-spacing: var(--tk-display); }
.brief__m { margin: var(--s1) 0 0; font: var(--t-body); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.brief__p {
  margin: 0 0 var(--s5); padding: var(--s5); border-radius: var(--r-lg);
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--band-line);
  font: var(--t-h3); letter-spacing: var(--tk-h3); line-height: 1.7; color: var(--ink);
}
.facts {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s2) var(--s5);
  margin: 0 0 var(--s6);
}
.facts dt { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3); align-self: baseline; }
.facts dd { margin: 0; font: var(--t-body); color: var(--ink); }
.tasks { margin-bottom: var(--s6); }
.tasks__t { margin: 0 0 var(--s3); font: var(--t-h2); letter-spacing: var(--tk-h2); }
.tasks__l { margin: 0; padding-left: var(--s5); display: grid; gap: var(--s2); }
.tasks__l li { font: var(--t-body); color: var(--ink); }
.go { justify-content: center; width: 100%; height: 52px; font: var(--t-h3); }
.gonote { margin: var(--s3) 0 0; font: var(--t-small); color: var(--ink-3); text-align: center; }

/* ── 3 · 진료실 ─────────────────────────────────────────── */
.clinic { min-height: calc(100dvh - var(--bar)); }

/* 시간 띠 — 이 화면에서 색을 갖는 것은 시간뿐입니다 */
.clockbar { height: 3px; background: var(--line); }
.clockbar__fill { display: block; height: 100%; background: var(--brand); transition: width 1s linear, background var(--base) var(--ease); }
.clockbar__fill.is-warn   { background: var(--warn); }
.clockbar__fill.is-danger { background: var(--danger); }

.roomtop {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3) var(--s5);
  padding: var(--s3) var(--s5); border-bottom: 1px solid var(--line);
  background: var(--surface);
}
.roomtop__who { display: flex; align-items: baseline; gap: var(--s3); }
.roomtop__who b { font: var(--t-h3); letter-spacing: var(--tk-h3); }
.roomtop__who span { font: var(--t-small); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.clock { display: inline-flex; align-items: baseline; gap: var(--s2); margin-left: auto; }
.clock__n { font: var(--t-num-l); font-variant-numeric: tabular-nums; color: var(--ink); }
.clock__n.is-warn   { color: var(--warn); }
.clock__n.is-danger { color: var(--danger); }
.clock__k { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3); }
.clock__note { font: var(--t-small); color: var(--warn); }
/* 좁아지면 단추가 먼저 눌립니다 — 글자가 사라지므로 줄이지 않습니다 */
.roomtop .btn { flex: none; }
.clock__note:empty { display: none; }

.clinic__body {
  display: grid; grid-template-columns: 14rem minmax(0, 1fr) 20rem; gap: var(--s5);
  max-width: 80rem; margin: 0 auto; padding: var(--s5);
}

/* ── 메모지 · EMR 경과기록 ────────────────────────────────
   칸과 확인 목록은 평가목표집이 정하고, S/O/A/P 라는 이름만 EMR 관례에서 빌립니다.
   시스템이 아는 것(계기 · 진찰)은 미리 올라와 있고, 학생은 해석만 씁니다. */
.note {
  align-self: start; position: sticky; top: calc(var(--bar) + var(--s4));
  display: grid; gap: var(--s4);
  padding: var(--s4); border-radius: var(--r-lg);
  background: var(--band); box-shadow: inset 0 0 0 1px var(--band-line);
  max-height: calc(100dvh - var(--bar) - var(--s6)); overflow-y: auto;
}
.note__head { display: flex; align-items: baseline; gap: var(--s3); }
.note__t { margin: 0; font: var(--t-h2); letter-spacing: var(--tk-h2); }
.note__saved { margin-left: auto; font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ok); }

.note__s { display: grid; gap: var(--s2); }
.note__k { display: flex; align-items: baseline; gap: var(--s2); }
.note__key {
  width: 18px; height: 18px; flex: none; display: grid; place-items: center;
  border-radius: var(--r-sm); background: var(--brand); color: var(--on-brand);
  font: var(--t-num-s); font-style: normal;
}
.note__k b { font: var(--t-h3); letter-spacing: var(--tk-h3); }

/* 장비에서 올라온 것 — 학생이 다시 치지 않습니다 */
.note__auto { display: grid; gap: var(--s-hair); }
.note__a {
  display: flex; align-items: baseline; gap: var(--s2);
  padding: var(--s1) var(--s2); border-radius: var(--r-sm); background: var(--paper-2);
}
.note__av { font: var(--t-small); color: var(--ink); min-width: 0; }
.note__av.num { font: var(--t-num); font-variant-numeric: tabular-nums; }
.note__src { margin-left: auto; flex: none; font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3); font-style: normal; }

.note__dx { display: flex; flex-wrap: wrap; gap: var(--s1); }

.note__in {
  width: 100%; overflow-wrap: anywhere; min-height: 2.4em; padding: var(--s2); resize: none; overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink); font: var(--t-body); line-height: 1.6;
  transition: border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.note__in:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }

/* 평가목표집이 이 임상표현에 쓴 성과 문장 — 자르지 않습니다 */
.note__chk { margin: 0; padding-left: var(--s4); display: grid; gap: var(--s-hair); }
.note__chk li { font: var(--t-micro); color: var(--ink-3); line-height: 1.5; }

@media (max-width: 1180px) {
  .clinic__body { grid-template-columns: 14rem minmax(0, 1fr); }
  .note { grid-column: 1 / -1; position: static; max-height: none; }
  .note__s { grid-template-columns: minmax(0, 1fr); }
}
.side { display: grid; gap: var(--s4); align-content: start; position: sticky; top: calc(var(--bar) + var(--s4)); }
.side__who {
  display: grid; gap: var(--s3);
  padding: var(--s4); border-radius: var(--r-lg);
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--band-line);
}
/* 사진은 안여백 안쪽을 가득 채웁니다. 학생이 마주 보는 얼굴이라 작게 둘 이유가 없습니다. */
.side__who .avatar { width: 100%; height: auto; aspect-ratio: 1 / 1; }
/* 이름 · 나이 · 성별을 한 줄에 밑선 맞춰 둡니다 */
.side__id { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--s1) var(--s2); }
.side__n { font: var(--t-name); letter-spacing: var(--tk-name); }
.side__m { font: var(--t-small); color: var(--ink-2); font-variant-numeric: tabular-nums; }

/* 계기 — 어두운 것은 이 화면에서도 여기 하나뿐입니다 */
.svit { display: grid; gap: 1px; padding: 1px; border-radius: var(--r-md); background: var(--mon-bg); overflow: hidden; }
.svit__r {
  display: flex; align-items: baseline; gap: var(--s2);
  padding: var(--s2) var(--s3); background: var(--mon-cell);
}
.svit__k { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--mon-key); width: 2.6rem; flex: none; }
.svit__v { margin-left: auto; font: var(--t-num-l); font-variant-numeric: tabular-nums; color: var(--mon-val); }
.svit__u { font: var(--t-micro); color: var(--mon-mute); width: 3.2rem; text-align: right; flex: none; }
.svit__r.is-out .svit__v { color: var(--mon-out); }

.tally { display: grid; gap: var(--s-hair); }
.tally__r {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s2);
  padding: var(--s2) 0; border-top: 1px solid var(--rule);
}
.tally__k { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3); }
.tally__v { font: var(--t-num); font-variant-numeric: tabular-nums; color: var(--ink); }

.work { display: grid; gap: var(--s6); align-content: start; min-width: 0; }
.work__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s3); margin-bottom: var(--s3); }
.work__head h2 { margin: 0; font: var(--t-h2); letter-spacing: var(--tk-h2); }
.work__src { font: var(--t-micro); color: var(--ink-3); }

/* 문진 */
.chat__log {
  display: grid; gap: var(--s3); align-content: start;
  min-height: 16rem; max-height: 26rem; overflow-y: auto;
  padding: var(--s4); border-radius: var(--r-lg);
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--band-line);
}
.bub { display: grid; gap: var(--s1); max-width: 42ch; }
.bub--me { justify-self: end; text-align: right; }
.bub__k { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3); }
.bub__t {
  margin: 0; overflow-wrap: anywhere; padding: var(--s3) var(--s4); border-radius: var(--r-lg);
  font: var(--t-h3); letter-spacing: var(--tk-h3); line-height: 1.65;
  background: var(--paper-2); color: var(--ink);
  animation: bubIn 220ms var(--ease) both;
}
.bub--me .bub__t { background: var(--brand); color: var(--on-brand); }
.bub--must .bub__t { box-shadow: inset 3px 0 0 var(--warn); }
@keyframes bubIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

.chat__bar { display: flex; gap: var(--s2); margin-top: var(--s3); }
.chat__in {
  flex: 1 1 auto; min-width: 0; height: 46px; padding: 0 var(--s4);
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface); color: var(--ink); font: var(--t-body);
  transition: border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.chat__in:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.chat__bar .btn { height: 46px; padding-inline: var(--s5); }

/* 진찰 — 화면이 진찰을 하는 것이 아니라, 마네킹이 보낸 것을 적는 기록판입니다 */
.live {
  width: 6px; height: 6px; border-radius: 50%; background: var(--ok); flex: none;
  animation: livePulse 2.4s var(--ease) infinite;
}
@keyframes livePulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }
@media (prefers-reduced-motion: reduce) { .live { animation: none; } }
.work__src { display: inline-flex; align-items: center; gap: var(--s2); }
.exam__lead { margin: 0 0 var(--s3); font: var(--t-small); color: var(--ink-3); }

/* 자리 단추 — 계통·진찰법마다 한 줄입니다. 줄 이름이 있어야 어느 계통인지 압니다. */
.sites { display: grid; gap: var(--s3); }
.sites__row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }
.sites__k {
  flex: 0 0 100%; font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3);
}
.site {
  min-height: 44px; padding: 0 var(--s4);
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface); color: var(--ink); font: var(--t-ui); cursor: pointer;
  transition: border-color var(--fast) var(--ease), background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.site:hover { border-color: var(--brand); background: var(--brand-soft); }
/* 이미 만진 자리 — 다시 만질 수 있습니다. 여러 번 만졌다고 점수가 늘지는 않습니다. */
.site.is-done { color: var(--ink-3); border-style: dashed; }
/* 장비가 판정해 주지 못하는 것 — 해 볼 수는 있고 채점은 사람이 합니다 */
.site--hand { border-style: dotted; color: var(--ink-2); }
.site--hand::after {
  content: '사람'; margin-left: var(--s2);
  font: var(--t-micro); letter-spacing: var(--tk-chart); color: var(--ink-3);
}

.obs__log { display: grid; gap: var(--s-hair); margin-top: var(--s4); }
.obs {
  display: grid; grid-template-columns: 3.4rem 7rem minmax(0, 1fr); gap: var(--s3);
  align-items: baseline; padding: var(--s3) 0; border-top: 1px solid var(--rule);
  animation: bubIn 220ms var(--ease) both;
}
.obs__t { font: var(--t-num-s); font-variant-numeric: tabular-nums; color: var(--ink-3); }
.obs__k { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3); }
.obs__v { font: var(--t-h3); letter-spacing: var(--tk-h3); color: var(--ink); }
.obs__v--none { font: var(--t-body); color: var(--ink-3); }
.obs.is-hit { border-top-color: var(--brand-line); }

/* ── 소견 보고표 ─────────────────────────────────────────────
   학생이 스스로 적는 곳입니다. 위의 기록판은 만진 사실만 적습니다. */
.rep { margin-top: var(--s5); padding-top: var(--s4); border-top: 1px solid var(--line); }
.rep__head { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); }
.rep__t { margin: 0; font: var(--t-h3); letter-spacing: var(--tk-h3); color: var(--ink); }
.rep__lead { margin: var(--s2) 0 var(--s3); font: var(--t-small); color: var(--ink-3); }
.rep__body { display: grid; }
.rep__r {
  display: grid; gap: var(--s2); align-items: center;
  grid-template-columns: 3.6rem minmax(0, 1.4fr) 5rem minmax(0, 1.2fr) 2rem;
  padding: var(--s2) 0; border-top: 1px solid var(--rule);
}
.rep__r--h > span {
  font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3);
  border-top: 0;
}
.rep__r--h { border-top: 0; padding-top: 0; }
.rep__m { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3); }
.rep__s, .rep__v, .rep__f {
  min-width: 0; min-height: 40px; padding: 0 var(--s2);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); color: var(--ink); font: var(--t-ui);
}
.rep__none { font: var(--t-body); color: var(--ink-3); }
.rep__x {
  min-height: 32px; border: 0; background: none; color: var(--ink-3);
  font: var(--t-ui); cursor: pointer;
}
.rep__x:hover { color: var(--danger); }
@media (max-width: 700px) {
  .rep__r { grid-template-columns: minmax(0, 1fr) 5rem 2rem; }
  .rep__r > .rep__m { display: none; }
  .rep__r--h > span:first-child { display: none; }
  .rep__r > .rep__f, .rep__r > .rep__none { grid-column: 1 / -1; }
  .rep__r--h > span:nth-child(4) { display: none; }
}

/* 읽기만 되는 메모 — 사이시험 옆, 결과 위 */
.noteview {
  display: grid; gap: var(--s3); align-self: start;
  padding: var(--s4); border-radius: var(--r-lg);
  background: var(--band); box-shadow: inset 0 0 0 1px var(--band-line);
}
.noteview__t { margin: 0; font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3); }
.noteview__s { display: grid; gap: var(--s1); }
/* 학생이 적은 글은 띄어쓰기가 없을 수 있습니다 — 끊을 곳이 없으면 칸을 밀어냅니다 */
.noteview__p { margin: 0; font: var(--t-body); color: var(--ink); line-height: 1.65; white-space: pre-wrap; overflow-wrap: anywhere; }
.noteview__dx { display: flex; flex-wrap: wrap; gap: var(--s1); }
.withnote { display: grid; grid-template-columns: 17rem minmax(0, 1fr); gap: var(--s5); align-items: start; }
@media (max-width: 860px) { .withnote { grid-template-columns: minmax(0, 1fr); } }

/* ── 4 · 사이시험 ───────────────────────────────────────── */
.iqs { display: grid; gap: var(--s5); margin-bottom: var(--s6); }
.iq { display: grid; gap: var(--s2); }
.iq__q { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s3); }
.iq__q b { font: var(--t-h3); letter-spacing: var(--tk-h3); }
.iq__lim { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3); }
.iq__max { margin-left: auto; font: var(--t-num-s); font-variant-numeric: tabular-nums; color: var(--ink-3); }
.iq__in {
  width: 100%; overflow-wrap: anywhere; padding: var(--s3) var(--s4); resize: vertical;
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface); color: var(--ink); font: var(--t-body); line-height: 1.7;
  transition: border-color var(--fast) var(--ease), box-shadow var(--fast) var(--ease);
}
.iq__in:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }

/* ── 5 · 결과 ───────────────────────────────────────────── */
.total {
  padding: var(--s5); margin-bottom: var(--s6); border-radius: var(--r-lg);
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--band-line);
}
.total__top { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s3); margin-bottom: var(--s3); }
.total__n { font: 700 2.75rem/1 var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.total__of { font: var(--t-num-l); font-variant-numeric: tabular-nums; color: var(--ink-3); }
.total__pass { margin-left: auto; font: var(--t-small); color: var(--ink-3); }
.total__note { margin: var(--s3) 0 0; font: var(--t-micro); color: var(--ink-3); }
/* 합격선에 못 미친 막대는 빨강입니다.
   ⚠ base.css 가 이미 `--danger` 로 정해 둔 것을 여기서 `--warn`(주황)으로 덮고 있었습니다.
      student.css 가 base.css 뒤에 실려서 이쪽이 이깁니다 — 두 파일이 같은 선택자를 두면
      나중 것만 보이고 앞의 의도는 조용히 사라집니다. */
.meter__fill.is-low { background: var(--danger); }

.dom { display: grid; margin-bottom: var(--s6); }
.dom__r {
  display: grid; grid-template-columns: 8rem 6rem auto minmax(0, 1fr);
  align-items: baseline; gap: var(--s3);
  padding: var(--s3) 0; border-top: 1px solid var(--rule);
}
.dom__k { font: var(--t-h3); letter-spacing: var(--tk-h3); }
.dom__v { font: var(--t-num); font-variant-numeric: tabular-nums; }
.dom__e { display: inline-flex; align-items: center; gap: var(--s2); font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ok); }
.dom__e.is-wait { color: var(--ink-3); }
.dom__dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.dom__e.is-wait .dom__dot { background: none; box-shadow: inset 0 0 0 1.5px currentColor; }
.dom__d { font: var(--t-small); color: var(--ink-3); text-align: right; }

/* 몸 그림 두 장 — 놓친 것이 문장이 아니라 자리로 남습니다 */
.bodies { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s5); margin-bottom: var(--s6); }
.bmap { margin: 0; display: grid; gap: var(--s2); justify-items: center; }
.bmap__stage { position: relative; width: 100%; max-width: 15rem; }
.bmap__img { width: 100%; height: auto; opacity: .5; }
.bdot {
  position: absolute; width: 12px; height: 12px; margin: -6px 0 0 -6px;
  border-radius: 50%; background: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft);
}
.bdot.is-miss { background: var(--danger); box-shadow: 0 0 0 3px var(--warn-soft); }
.bmap__c { display: grid; gap: var(--s1); justify-items: center; text-align: center; }
.bmap__c b { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-2); }
.bmap__c span { font: var(--t-small); color: var(--ink-3); }

/* 자리가 적히지 않은 소견 — 그림에 찍을 수 없으므로 글로 적습니다 */
.fl { margin-bottom: var(--s6); }
.fl__t { margin: 0 0 var(--s3); font: var(--t-h2); letter-spacing: var(--tk-h2); }
.fl__rows { display: grid; }
.fl__r {
  display: grid; grid-template-columns: 1.4rem minmax(0, 1fr) auto;
  align-items: baseline; gap: var(--s3);
  padding: var(--s3) 0; border-top: 1px solid var(--rule);
}
.fl__m { font: var(--t-num); color: var(--ink-3); }
.fl__r.is-got .fl__m { color: var(--ok); }
.fl__v { font: var(--t-body); color: var(--ink-2); }
.fl__r.is-got .fl__v { color: var(--ink); }
.fl__s { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--danger); }
/* 채점하지 않은 것 — 틀렸다는 뜻이 아니라 아직 안 봤다는 뜻입니다 */
.fl__s.is-wait { color: var(--ink-3); }
.fl__r.is-got .fl__s { color: var(--ok); }

/* 총점과 무관하게 떨어지는 것 — 조용히 지나가면 안 됩니다 */
.hardfail {
  display: grid; gap: var(--s2); margin: var(--s4) 0 0;
  padding: var(--s3) var(--s4); border-radius: var(--r-md);
  background: var(--warn-soft); border-left: 3px solid var(--danger);
}
.hardfail b { font: var(--t-h3); letter-spacing: var(--tk-h3); color: var(--danger); }
.hardfail ul { margin: 0; padding-left: var(--s5); display: grid; gap: var(--s1); }
.hardfail li { font: var(--t-body); color: var(--ink); }
.hardfail > span { font: var(--t-small); color: var(--ink-2); }
/* 사람이 확인할 것 — 떨어뜨리는 것이 아니라 기다리는 것이라 색이 다릅니다 */
.hardfail--wait { background: var(--paper-2); border-left-color: var(--line-2); }
.hardfail--wait b { color: var(--ink); }
.total__warn { margin: var(--s3) 0 0; font: var(--t-small); color: var(--danger); }
.pcard__lv { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3); }

/* ── 신체진찰 결과 — 수행과 보고를 갈라 봅니다 ─────────────── */
.peres { margin: var(--s6) 0; }
.peres__t { margin: 0 0 var(--s3); font: var(--t-h2); letter-spacing: var(--tk-h2); }
.peres__h {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s3);
  margin-top: var(--s4); padding-bottom: var(--s2); border-bottom: 1px solid var(--line);
}
.peres__h b { font: var(--t-h3); letter-spacing: var(--tk-h3); color: var(--ink); }
.peres__h .num { font: var(--t-num-s); font-variant-numeric: tabular-nums; color: var(--ink-2); }
.peres__l { margin: 0; padding: 0; list-style: none; display: grid; }
.peres__r {
  display: grid; gap: var(--s3); align-items: baseline;
  grid-template-columns: 1.2rem minmax(0, 1fr) minmax(0, 12rem);
  padding: var(--s3) 0; border-top: 1px solid var(--rule);
}
.peres__r:first-child { border-top: 0; }
.peres__m { font: var(--t-num-s); color: var(--danger); }
.peres__r.is-ok .peres__m { color: var(--ok); }
.peres__r.is-wait .peres__m { color: var(--ink-3); }
.peres__k { font: var(--t-body); color: var(--ink); }
.peres__r.is-wait .peres__k { color: var(--ink-2); }
.peres__d { font: var(--t-small); color: var(--ink-3); }
@media (max-width: 640px) {
  .peres__r { grid-template-columns: 1.2rem minmax(0, 1fr); }
  .peres__d { grid-column: 2; }
}

/* 결과에 붙는 묶음 — 대화 스크립트 · 평가 목표 */
.sblock { margin-bottom: var(--s6); }
.sblock__t { margin: 0 0 var(--s2); font: var(--t-h2); letter-spacing: var(--tk-h2); }
.sblock__n { margin: 0 0 var(--s3); font: var(--t-small); color: var(--ink-3); }
.sealed {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s3);
  margin: 0 0 var(--s6); padding: var(--s3) var(--s4);
  border-radius: var(--r-md); background: var(--paper-2); border-left: 3px solid var(--ink-3);
  font: var(--t-small); color: var(--ink-2);
}
.sealed b { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink); }

.tutor {
  padding: var(--s5); margin-bottom: var(--s5); border-radius: var(--r-lg);
  background: var(--brand-soft); border-left: 3px solid var(--brand);
}
.tutor__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s3); margin-bottom: var(--s3); }
.tutor__head b { font: var(--t-h3); letter-spacing: var(--tk-h3); color: var(--brand-ink); }
.tutor__head span { font: var(--t-micro); color: var(--ink-3); }
.tutor__body { display: grid; gap: var(--s2); }
.tutor__body p { margin: 0; font: var(--t-body); color: var(--ink); line-height: 1.75; }

.reveal { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s3); margin: 0 0 var(--s6); }
.reveal__k { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3); }
.reveal b { font: var(--t-h2); letter-spacing: var(--tk-h2); }

.ends { display: flex; flex-wrap: wrap; gap: var(--s3); }
.ends .btn { height: 46px; padding-inline: var(--s5); }

/* ── 좁은 화면 ──────────────────────────────────────────── */
@media (max-width: 860px) {
  .clinic__body { grid-template-columns: minmax(0, 1fr); }
  .side { position: static; }
  /* 한 열로 접히면 카드가 가로로 눕습니다 — 사진은 이름 옆에 서므로 폭을 다 쓰면 안 됩니다 */
  .side__who { display: flex; align-items: center; gap: var(--s4); }
  .side__who .avatar { margin: 0; width: 96px; height: 96px; flex: none; }
  .side__id { flex-direction: column; align-items: flex-start; gap: var(--s-hair); }
  .svit { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bodies { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .spage { padding: var(--s5) var(--s4) var(--s7); }
  .dom__r { grid-template-columns: minmax(0, 1fr) auto; row-gap: var(--s1); }
  .dom__e, .dom__d { grid-column: 1 / -1; text-align: left; }
  .obs { grid-template-columns: 3.4rem minmax(0, 1fr); }
  .obs__v { grid-column: 2; }
  .prow { grid-template-columns: 3.4rem minmax(0, 1fr) auto; }
  .prow__cp { grid-column: 2 / -1; }
}

/* ── 인쇄 — 상단바·단추·움직임을 빼고 내용만 종이에 앉힙니다 ── */
@media print {
  .sbar, .ends, .chat__bar, .sites, .go, .gonote { display: none !important; }
  .stu { background: #fff; }
  .spage { max-width: none; padding: 0; }
  .total, .pcard, .brief__p { box-shadow: none; border: 1px solid #ccc; }
  .rdb__t { background: #f4f4f4 !important; color: #000 !important; }
  .obs__log, .chat__log { max-height: none; overflow: visible; }
}

/* ── 상태창 ───────────────────────────────────────────────
   진료 중에 제시문을 다시 보는 곳. 시간은 계속 흐릅니다. */
.sheet--peek { max-width: 46rem; }
.peek { display: grid; gap: var(--s4); padding: var(--s5); }
.peek__head { display: flex; align-items: center; gap: var(--s3); }
.peek__tabs { display: flex; gap: var(--s1); }
.peek__tab {
  min-height: 36px; padding: 0 var(--s4); border-radius: var(--r-md);
  border: 1px solid transparent; background: none; color: var(--ink-3); font: var(--t-ui); cursor: pointer;
}
.peek__tab:hover { color: var(--ink); }
.peek__tab.is-on { background: var(--ink); color: var(--on-ink); }
.peek__head .btn { margin-left: auto; }

.peek__facts { display: grid; grid-template-columns: 5rem minmax(0, 1fr); gap: var(--s3) var(--s4); margin: 0; }
.peek__facts dt { font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3); }
.peek__facts dd { margin: 0; font: var(--t-body); color: var(--ink); line-height: 1.7; }
.peek__tasks h3 { margin: 0 0 var(--s2); font: var(--t-label); letter-spacing: var(--tk-chart); color: var(--ink-3); }
.peek__tasks ol { margin: 0; padding-left: var(--s5); display: grid; gap: var(--s1); }
.peek__tasks li { font: var(--t-body); color: var(--ink); }

/* ── 영상 — DICOM 뷰어의 관례대로 네 귀에 정보를 얹습니다 ── */
.peek__films { display: grid; gap: var(--s4); }
.film { margin: 0; display: grid; gap: var(--s2); }
.film--locked {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s4);
  padding: var(--s4); border: 1px dashed var(--line-2); border-radius: var(--r-lg);
}
.film__name { font: var(--t-h3); letter-spacing: var(--tk-h3); }
.film__note { font: var(--t-small); color: var(--ink-3); }
.film--locked .btn { margin-left: auto; }
.film__stage { position: relative; border-radius: var(--r-md); background: #06090c; overflow: hidden; }
.film__svg { display: block; width: 100%; height: auto; }
.film__grid  { stroke: #1d2a33; stroke-width: .5; }
.film__trace { fill: none; stroke: #5fe08a; stroke-width: 2; }
.film__shape { fill: none; stroke: #7f9aab; stroke-width: 1.5; }
.film__shape2 { fill: none; stroke: #4a616f; stroke-width: 1; }
.film__ph { fill: #4a616f; font: 11px var(--font-sans); }
.film__c {
  position: absolute; font: var(--t-num-s); font-variant-numeric: tabular-nums;
  color: #a9c4d6; letter-spacing: .04em;
}
.film__c--tl { top: var(--s2); left: var(--s3); }
.film__c--tr { top: var(--s2); right: var(--s3); }
.film__c--bl { bottom: var(--s2); left: var(--s3); }
.film__c--br { bottom: var(--s2); right: var(--s3); }
.film__cap { font: var(--t-small); color: var(--ink-2); }

/* ═══ 관리자 설정 ═══════════════════════════════ */
.admform { display: flex; flex-direction: column; gap: var(--s3); max-width: 32rem; }
.admform__row { display: flex; flex-direction: column; gap: var(--s-tight); font: var(--t-ui); }
.admform__k { color: var(--ink-2); }

.admcheck { display: flex; flex-direction: column; gap: var(--s3); margin-top: var(--s5); max-width: 32rem; }
.admstatus { display: flex; flex-direction: column; gap: var(--s-tight); }
.admstatus__row { display: flex; align-items: center; gap: var(--s-tight); font: var(--t-body); }
.admstatus__dot { width: 8px; height: 8px; border-radius: var(--r-full); background: var(--danger); flex: none; }
.admstatus__dot.is-ok { background: var(--ok); }
.admstatus__label { min-width: 6rem; color: var(--ink-2); }
.admstatus__detail { color: var(--ink-3); font: var(--t-small); }

/* ═══ 장비 · AI 상태 패널 (오늘의 실습) ═══════════════════════════
   이 제품에서 "장비가 지금 살아 있다"를 말하는 자리는 계기(.svit, 진료실의 활력징후
   판)뿐이었습니다 — 어두운 판에 셀을 나눠 값을 얹는 그 문법을 여기로 그대로 가져옵니다.
   같은 이유로 이 패널도 라이트·다크 테마와 무관하게 늘 어둡습니다(.svit과 동일).

   상태는 셋(모름·정상·이상)입니다. 모름을 이상으로 잘못 그리면, 화면을 막 연 순간
   전부 빨갛게 보이는 거짓 경보가 뜹니다 — 그래서 세 번째 색(파랑, 확인 중)을 둡니다.
   색만으로 뜻을 전하지 않는다는 원칙은 그대로 지킵니다 — 아이콘 자체의 흑백/컬러
   전환과 라벨 글자색이 늘 색과 함께 갑니다. */
.devstatus {
  --ds-ok: #58BE90;        /* 다크 테마 --ok 와 같은 값. 이 패널 전용 — 늘 어두우므로
                              라이트 테마의 --ok(문서 배경용, 더 짙음)를 쓰면 묻힙니다 */
  --ds-alert: #E5776B;     /* 다크 테마 --danger 와 같은 값 */
  --ds-checking: var(--mon-dev);
  margin: var(--s5) 0 var(--s6);
  border-radius: var(--r-lg);
  background: var(--mon-bg);
  box-shadow: var(--shadow-2), inset 0 0 0 1px var(--mon-line);
  overflow: hidden;
}
.devstatus__head {
  display: flex; align-items: baseline; gap: var(--s3);
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--mon-line);
}
.devstatus__title {
  font: var(--t-label); letter-spacing: var(--tk-label); text-transform: uppercase;
  color: var(--mon-key);
}
.devstatus__tally {
  margin-left: auto; font: var(--t-num-s); font-variant-numeric: tabular-nums; color: var(--mon-val);
}
.devstatus__time { font: var(--t-micro); font-variant-numeric: tabular-nums; color: var(--mon-mute); }

.devstatus__grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr));
  gap: 1px; background: var(--mon-line);
}
.devstatus__item {
  display: flex; flex-direction: column; align-items: center; gap: var(--s2);
  padding: var(--s4) var(--s2); background: var(--mon-cell);
  animation: dsIn var(--slow) var(--ease) both;
  animation-delay: calc(var(--i, 0) * 60ms);
}

/* 아이콘 자리 — 계기판의 '포트홀' 하나. 링(의사 상태등)이 이 위에 겹칩니다 */
.devstatus__ring {
  position: relative; display: grid; place-items: center;
  width: 64px; height: 64px; border-radius: 50%; flex: none;
  background: radial-gradient(circle at 35% 30%, rgb(255 255 255 / .06), transparent 60%), var(--mon-focus);
  box-shadow: inset 0 0 0 1px var(--mon-line);
}
.devstatus__icon {
  width: 40px; height: 40px; object-fit: contain;
  filter: grayscale(1); opacity: .45;
  transition: filter var(--base) var(--ease), opacity var(--base) var(--ease);
}
.devstatus__label { font: var(--t-small); color: var(--mon-mute); text-align: center; }

/* ── 정상 — 느리게 숨 쉬듯 번지는 링. 계기의 심박처럼, 급하지 않게 ── */
.devstatus__item.is-ok .devstatus__icon { filter: none; opacity: 1; }
.devstatus__item.is-ok .devstatus__label { color: var(--mon-key); }
.devstatus__item.is-ok .devstatus__ring { box-shadow: inset 0 0 0 1px var(--ds-ok), 0 0 0 3px rgb(88 190 144 / .12); }
.devstatus__item.is-ok .devstatus__ring::before,
.devstatus__item.is-ok .devstatus__ring::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  border: 1px solid var(--ds-ok); animation: dsPulse 2.4s var(--ease) infinite;
}
.devstatus__item.is-ok .devstatus__ring::after { animation-delay: 1.2s; }

/* ── 이상 — 신호를 놓친 화면처럼 옅게 깜빡이고, 링은 더 자주 뜁니다 ── */
.devstatus__item.is-off .devstatus__icon { opacity: .8; animation: dsFlicker 2.6s ease-in-out infinite; }
.devstatus__item.is-off .devstatus__label { color: var(--ds-alert); }
.devstatus__item.is-off .devstatus__ring { box-shadow: inset 0 0 0 1px var(--ds-alert), 0 0 0 3px rgb(229 119 107 / .14); }
.devstatus__item.is-off .devstatus__ring::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  border: 1px solid var(--ds-alert); animation: dsPulse 1.3s var(--ease) infinite;
}

/* ── 확인 중 — 천천히 숨 쉬는 파랑. 정상도 이상도 아니라고 분명히 다르게 보입니다 ── */
.devstatus__item.is-unknown .devstatus__ring {
  box-shadow: inset 0 0 0 1px var(--ds-checking);
  animation: dsBreathe 1.8s ease-in-out infinite;
}

@keyframes dsIn { from { opacity: 0; transform: translateY(6px); } }
@keyframes dsPulse {
  from { opacity: .55; transform: scale(1); }
  to   { opacity: 0;   transform: scale(1.55); }
}
@keyframes dsFlicker {
  0%, 92%, 100% { opacity: 1; }
  94% { opacity: .5; }
  96% { opacity: .9; }
}
@keyframes dsBreathe {
  0%, 100% { opacity: .55; }
  50%      { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .devstatus__item { animation: none; }
  .devstatus__ring::before, .devstatus__ring::after { animation: none; opacity: .5; }
  .devstatus__icon { animation: none; }
}

/* ── 채점표 항목 전부 ────────────────────────────────────────
   영역 하나마다 그 영역의 채점 항목을 **빠짐없이** 폅니다.
   놓친 것만 보여 주면 학생이 「내가 한 것」을 확인할 수 없고,
   채점표에 무엇이 더 있었는지도 모릅니다.

   항목이 많은 영역(병력청취 15개)은 접어 두되, 접힌 동안에는
   놓친 항목이 order:-1 로 위에 올라옵니다 — 목록을 다시 만들지 않고
   보이는 순서만 바꾸는 방식이라, 펼치면 채점표 원래 순서로 돌아옵니다. */
.dmi { margin: 0 0 var(--s4); padding: 0 0 var(--s4); border-bottom: 1px solid var(--rule); }
.dmi__sum {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2);
  margin: 0 0 var(--s2);
}
.dmi__c {
  font: var(--t-label); letter-spacing: var(--tk-chart);
  padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line);
  color: var(--ink-3); white-space: nowrap;
}
.dmi__c.is-got  { color: var(--ok);     border-color: var(--ok); }
.dmi__c.is-miss { color: var(--danger); border-color: var(--danger); }
.dmi__more {
  margin-left: auto; padding: 3px 12px;
  border: 1px solid var(--line-2); border-radius: var(--r-md);
  background: var(--surface); color: var(--ink-2);
  font: var(--t-label); letter-spacing: var(--tk-chart); cursor: pointer;
}
.dmi__more:hover { border-color: var(--ink-3); color: var(--ink); }

.dmi__l { display: flex; flex-direction: column; }
/* 접힌 상태 — 채점표 순서 그대로 여덟 줄쯤 보입니다.
   놓친 것을 위로 끌어올려 봤더니 접힌 화면이 ✕ 로만 채워져서,
   「내가 한 것」이 하나도 안 보였습니다. 순서를 바꾸지 않습니다 —
   몇 개를 했고 몇 개를 놓쳤는지는 위의 칩이 이미 말해 줍니다. */
.dmi__l.is-clamped { max-height: 19rem; overflow: hidden;
  -webkit-mask-image: linear-gradient(#000 82%, transparent);
          mask-image: linear-gradient(#000 82%, transparent); }

.dmi__r {
  display: grid; grid-template-columns: 1.4rem minmax(0, 1fr) 4.2rem;
  align-items: baseline; gap: var(--s3);
  padding: var(--s2) 0; border-top: 1px solid var(--rule);
}
.dmi__m { font: var(--t-num-s); color: var(--danger); text-align: center; }
.dmi__r[data-s="PASS"] .dmi__m { color: var(--ok); }
.dmi__r[data-s="NOT_SCORABLE"] .dmi__m { color: var(--ink-3); }

.dmi__t { display: grid; gap: 2px; min-width: 0; }
.dmi__x { font: var(--t-body); color: var(--ink-2); overflow-wrap: anywhere; }
.dmi__r[data-s="PASS"] .dmi__x { color: var(--ink); }
.dmi__r[data-s="NOT_SCORABLE"] .dmi__x { color: var(--ink-3); }
.dmi__d { font: var(--t-small); color: var(--ink-3); font-style: normal; overflow-wrap: anywhere; }
.dmi__must {
  justify-self: start; font: var(--t-label); letter-spacing: var(--tk-chart);
  font-style: normal; color: var(--danger);
  border: 1px solid var(--danger); border-radius: 999px; padding: 0 6px;
}
/* 통과한 필수 항목에도 배지를 답니다. 거기서는 경고가 아니라 표시이므로 빨강을 쓰지 않습니다 —
   초록 줄에 빨간 배지가 붙으면 놓친 것으로 읽힙니다. */
.dmi__r[data-s="PASS"] .dmi__must { color: var(--ink-3); border-color: var(--line-2); }

.dmi__p {
  font: var(--t-num-s); font-variant-numeric: tabular-nums;
  text-align: right; color: var(--danger); white-space: nowrap;
}
.dmi__r[data-s="PASS"] .dmi__p { color: var(--ok); }
.dmi__r[data-s="NOT_SCORABLE"] .dmi__p { color: var(--ink-3); }

@media (max-width: 640px) {
  .dmi__r { grid-template-columns: 1.2rem minmax(0, 1fr) 3.6rem; gap: var(--s2); }
}

/* 영역별 채점 — 칸 이름 줄
   「0 / 45」(채점표 배점)와 「40」(총점 비중)이 서로 다른 것을 가리키는데
   둘 다 「점」으로 보여 읽히지 않았습니다. 머리글로 무엇이 무엇인지 밝힙니다. */
.dom__head { border-top: 0; padding-bottom: var(--s1); }
.dom__head .dom__k,
.dom__head .dom__v,
.dom__head .dom__e,
.dom__head .dom__d {
  font: var(--t-label); letter-spacing: var(--tk-chart);
  color: var(--ink-3); text-transform: none;
}
.dom__head .dom__e { color: var(--ink-3); }
/* 영역에 붙는 설명 — 예전에는 비중 칸을 밀어내고 그 자리에 들어갔습니다 */
.dom__n { padding: 0 0 var(--s2) 2px; font: var(--t-small); color: var(--ink-3); }
/* 좁은 화면에서는 칸이 접히므로 머리글 대신 값 옆에 이름을 답니다 */
.dom__lb { display: none; font-style: normal; color: var(--ink-3); }
@media (max-width: 640px) {
  .dom__head { display: none; }
  .dom__lb { display: inline; }
  .dom__e .dom__dot { display: none; }
}

/* ── 증례 제작 (authoring.js) ──────────────────────────────────────────
   교수 전용 화면. 색·간격은 전부 토큰으로 — 리터럴 색을 적지 않는다(CONVENTIONS). */
.auth__row { display: flex; align-items: baseline; gap: var(--s3); padding: var(--s3) 0;
  border-bottom: 1px solid var(--line); text-decoration: none; color: var(--ink); }
.auth__row:hover { background: var(--paper-2); }
.auth__meta { font: var(--t-micro); color: var(--ink-3); }
.auth__dxlist { display: flex; flex-wrap: wrap; gap: var(--s2); margin: var(--s3) 0; }
.auth__field { margin: var(--s3) 0; }
.auth__k { display: block; font: var(--t-label); color: var(--ink-3); margin-bottom: var(--s1); }
.auth__v { white-space: pre-wrap; }
.auth__ta { width: 100%; resize: vertical; font: inherit; }
/* 자동 높이 칸(정답 진단·검사·치료) — JS 가 scrollHeight 로 높이를 맞추므로
   스크롤바와 손 리사이즈를 끈다. 켜 두면 조절할 때마다 막대가 깜빡인다 */
.auth__ta--grow { resize: none; overflow: hidden; }
.auth__hint { font: var(--t-micro); color: var(--ink-3); margin-top: var(--s1); }
.auth__pegroup { margin: var(--s3) 0; }
.auth__pemethod { font: var(--t-label); color: var(--ink-3); margin: var(--s2) 0; }
.auth__peopt { display: flex; align-items: center; gap: var(--s2); padding: 2px 0; }
.auth__danger { color: var(--danger); border-color: var(--danger); }
.auth__danger:hover { background: var(--warn-soft); }

/* ── 증례 제작 단일창 개편 (2026-09-21) — 몸 그림 진찰 선택 · 로딩 표시 ──
   그림·좌표계는 실습 화면(vmr.css .bm__stage)과 같은 401:480 비율이다. */
.auth__body { position: relative; width: 100%; max-width: 26rem; aspect-ratio: 401 / 480;
  background: var(--paper-2); border-radius: var(--r-lg); overflow: hidden; margin: var(--s3) 0; }
.auth__body img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; opacity: .55; }
.auth__bp { position: absolute; transform: translate(-50%, -50%); width: 18px; height: 18px;
  border-radius: 50%; border: 1px solid var(--line-2); background: var(--paper);
  color: var(--ink-3); font-size: 9px; line-height: 1; padding: 0; cursor: pointer; }
.auth__bp:hover { border-color: var(--ink); color: var(--ink); }
.auth__bp[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.auth__bplab { position: absolute; font: var(--t-micro); color: var(--ink-3);
  white-space: nowrap; pointer-events: none;
  background: var(--paper); border-radius: 3px; padding: 0 3px; }
.auth__bplab[data-on="1"] { color: var(--ink); font-weight: 600; }
.auth__bplab[data-pos="b"] { transform: translate(-50%, 11px); }
.auth__bplab[data-pos="t"] { transform: translate(-50%, calc(-100% - 11px)); }
.auth__bplab[data-pos="l"] { transform: translate(calc(-100% - 13px), -50%); }
.auth__bplab[data-pos="r"] { transform: translate(13px, -50%); }
.auth__loading { display: flex; align-items: center; gap: var(--s2); margin: var(--s3) 0; color: var(--ink-3); }
.auth__spin { width: 16px; height: 16px; flex: none; border: 2px solid var(--line-2);
  border-top-color: var(--ink); border-radius: 50%; animation: authspin .8s linear infinite; }
@keyframes authspin { to { transform: rotate(360deg); } }

/* ── 증례 제작 진료소견서 형식 (2026-09-21 2차) ─────────────────────────
   확대 100% 기준 화면 가로의 90% 를 쓴다 — 소견서를 옆으로 넓게 편다. */
.spage--author { max-width: none; width: 90%; }
/* 소견서 시트 — 한 장의 문서처럼 섹션이 줄로 이어진다.
   ⚠ 이름이 adoc 인 이유: base.css 에 사용설명서용 .doc { max-width: 52rem } 이 이미 있다 —
   같은 이름을 쓰면 나중 파일이 못 덮은 속성(max-width)이 조용히 살아남는다(실측으로 걸림). */
.adoc { border: 1px solid var(--line-2); border-radius: var(--r-lg); background: var(--paper); overflow: hidden; }
.adoc__sec { padding: var(--s4) var(--s5); border-top: 1px solid var(--line); }
.adoc__sec:first-child { border-top: 0; }
.adoc__t { font: var(--t-label); font-weight: 700; color: var(--ink); margin: 0 0 var(--s2); }
.auth__grid2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--s6); }
.auth__grid3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 var(--s6); }
/* 촉진·타진 두 그림을 나란히 */
.auth__bodies { display: flex; gap: var(--s6); flex-wrap: wrap; align-items: flex-start; }
.auth__bodywrap { flex: 1 1 300px; max-width: 26rem; }
@media (max-width: 900px) {
  .spage--author { width: auto; }
  .auth__grid2, .auth__grid3 { grid-template-columns: 1fr; }
}

/* ── 녹화 다시 보기(replay.js · VMR-MEMORA) — 결과와 기록 상세 공용 ──
   영상 칸(.mv-grid)은 memora 재생기가 인라인으로 그린다. 여기서는 둘레만 맞춘다. */
.replay__grid { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: var(--s4); align-items: start; }
@media (max-width: 960px) { .replay__grid { grid-template-columns: minmax(0, 1fr); } }
.replay__stage { min-height: 120px; }
.replay__stage video { border-radius: var(--r-md) !important; }
.replay__ctl { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); margin-top: var(--s2); }
.replay__time { font: var(--t-num); color: var(--ink-2); font-variant-numeric: tabular-nums; min-width: 7.5em; }
.replay__bar { flex: 1 1 200px; accent-color: var(--brand); }
.replay__sel { height: 28px; padding: 0 var(--s2); border: 1px solid var(--line-2); border-radius: var(--r-md); background: var(--surface); color: var(--ink); font: var(--t-micro); }
.replay__side { border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); }
.replay__h { margin: 0; padding: var(--s2) var(--s3); font: var(--t-label); letter-spacing: var(--tk-label); color: var(--ink-3); border-bottom: 1px solid var(--rule); }
.replay__list { list-style: none; margin: 0; padding: var(--s1); max-height: 420px; overflow-y: auto; }
.replay__go { display: grid; grid-template-columns: 3.2em 2.6em minmax(0, 1fr); gap: var(--s2); width: 100%; padding: var(--s-tight) var(--s2);
  border: 0; border-radius: var(--r-md); background: none; color: var(--ink); text-align: left; font: var(--t-small); cursor: pointer; }
.replay__go:hover { background: var(--paper-2); }
.replay__u.is-now .replay__go { background: var(--brand-soft); box-shadow: inset 3px 0 0 var(--brand); }
.replay__at { font: var(--t-num-s); color: var(--ink-3); padding-top: 3px; }
.replay__who { font-weight: 600; color: var(--ink-2); }
.replay__u--me .replay__who { color: var(--brand); }
.replay__u--est .replay__at::after { content: '~'; }
/* memora 기본(칸 최소 320px)이면 대화 목록 옆 칸에서 두 화면이 위아래로 쌓인다 — 나란히 보이게 */
.replay__stage .mv-grid { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)) !important; }
/* 대체 동기 재생기(replay.js syncPlayer) — memora 재생기를 못 받았을 때 */
.replay__vgrid { display: grid; gap: var(--s2); grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); align-items: start; }
.replay__cell { margin: 0; }
.replay__screen { position: relative; }
.replay__screen video { display: block; width: 100%; aspect-ratio: 16 / 9; background: #000; border-radius: var(--r-md); }
.replay__cover { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; border-radius: var(--r-md);
  background: rgba(0, 0, 0, .55); color: #fff; font: var(--t-label); letter-spacing: var(--tk-label); }
.replay__cover[hidden] { display: none; }
.replay__cap { font: var(--t-micro); color: var(--ink-3); padding-top: 2px; }
/* 녹화 화면 배열 — 위: Unity | 웹캠, 아래: PTZ(실습실 카메라 axis) 전체 폭. 칸 자리를 고정해 녹화마다 같은 곳에 같은 화면이 온다.
   memora 재생기는 grid 를 인라인 style 로 깔기 때문에 !important 로 덮는다 */
.replay__stage .replay__layout { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) !important; }
.replay__layout > [data-kind="unity"]  { grid-column: 1; grid-row: 1; }
.replay__layout > [data-kind="webcam"] { grid-column: 2; grid-row: 1; }
.replay__layout > [data-kind="axis"]   { grid-column: 1 / -1; grid-row: 2; }   /* PTZ 는 두 열에 걸쳐 넓게 */
.replay__layout > :only-child { grid-column: 1 / -1; }   /* 한 트랙뿐이면 넓게 */
/* 칸 크게 보기(replay.js bigScreen) — 전체 화면 칸은 검은 바탕에 영상을 비율 그대로 꽉 채운다 */
.replay__layout > [data-kind] { cursor: zoom-in; }
.replay__layout > :fullscreen { cursor: zoom-out; position: relative; display: flex; align-items: center; justify-content: center; background: #000; }
.replay__layout > :fullscreen .replay__screen { width: 100%; height: 100%; }
.replay__layout > :fullscreen video { width: 100% !important; height: 100% !important; aspect-ratio: auto; object-fit: contain; border-radius: 0 !important; }
.replay__layout > :fullscreen figcaption { position: absolute; top: 12px; left: 16px; color: #fff; opacity: .8; }
@media (max-width: 640px) {
  .replay__stage .replay__layout { grid-template-columns: minmax(0, 1fr) !important; }
  .replay__layout > [data-kind] { grid-column: 1; grid-row: auto; }
}
