@charset "utf-8";
/* ============================================================
   문제지 — 스크롤 연속형 (원본 기초_15.html 포맷 준용)
   ============================================================ */

/* 상단 진행 — 헤더 아래 모서리에 붙인다.
   레일 배경은 두지 않는다. 아직 푼 문항이 없을 때 의미 없는 회색 선만 남기 때문이다.
   채워진 만큼만 파란 선으로 보인다. */
.appbar .progress{
  position:absolute;left:0;right:0;bottom:0;
  height:3px;background:transparent;
}
.progress i{display:block;height:100%;width:0;border-radius:0 3px 3px 0;
  background:var(--grad-blue);transition:width .5s var(--ease-out)}
/* 문항 카운터 — 게임 점수판처럼 숫자를 크게, 이름을 작게.
   이미 화면에 고정된 하단 독 안에 두어 세로 공간을 쓰지 않는다.
   (태블릿 가로는 높이가 810px 안팎이라 상단 줄을 하나라도 줄여야 한다) */
.qstat{
  flex:0 0 auto;
  display:flex;align-items:stretch;
  border-radius:var(--r-md);overflow:hidden;
  background:var(--ink-800);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.09);
}
.qs{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  min-width:78px;padding:6px 10px;
}
.qs-num{
  font-size:calc(24px * var(--fs-k));font-weight:800;line-height:1.08;
  letter-spacing:-.04em;color:#fff;font-variant-numeric:tabular-nums;
}
/* 풀 때마다 늘어나는 값이라 눈에 띄게 */
.qs.done .qs-num{color:#5FE3BC}
/* 글자 크기 배율이 커지면 「전체 문항」이 두 줄로 접힌다 — 한 줄로 고정한다 */
.qs-cap{
  margin-top:1px;white-space:nowrap;
  font-size:calc(12px * var(--fs-k));font-weight:600;
  letter-spacing:-.02em;color:rgba(255,255,255,.58);
}
.qs-sep{flex:0 0 1px;margin:9px 0;background:rgba(255,255,255,.15)}

/* 한 문항 풀 때마다 숫자가 튀어 오른다 */
@keyframes qsPop{
  0%  {transform:scale(1)}
  45% {transform:scale(1.32)}
  100%{transform:scale(1)}
}
.qs-num.pop{animation:qsPop .45s var(--ease-out)}
@media (prefers-reduced-motion:reduce){
  .qs-num.pop{animation:none}
}

/* 청각장애인 대상은 음성 관련 조작부를 노출하지 않는다.
   JS 에서 생성 자체를 막지만, 정적 마크업까지 확실히 가리도록 함께 둔다. */
[data-skin="deaf"] .ttsbtn,
[data-skin="deaf"] .scene-play,
[data-skin="deaf"] .ex-play{display:none !important}

/* 음성 토글 */
.ttsbtn{margin-left:auto;color:var(--signal-blue)}
.ttsbtn .i-off{display:none}
.ttsbtn.off{color:var(--text-dim)}
.ttsbtn.off .i-on{display:none}
.ttsbtn.off .i-off{display:block}
.ttsbtn:disabled{opacity:.4;cursor:not-allowed}
/* 쓸 수 있는 한국어 음성이 없는 기기 — 잠그지 않고 흐리게만 둔다.
   음성 목록은 늦게 도착할 수 있어 잠가 버리면 되살릴 방법이 없다. */
.ttsbtn.novoice{opacity:.45}

/* 상태 */
.state{display:flex;flex-direction:column;align-items:center;gap:14px;
  padding:80px 24px;text-align:center;color:var(--text-sub);font-size:var(--fs-body)}
.state .btn{width:auto;padding:0 26px;margin-top:4px}
.spinner{width:34px;height:34px;border-radius:50%;
  border:3px solid var(--line);border-top-color:var(--signal-blue);animation:spin .9s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.state-ico{display:grid;place-items:center;width:52px;height:52px;border-radius:50%;
  background:#FEECEC;color:var(--signal-red)}
.state-ico svg{width:26px;height:26px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round}

/* ── 응시자 정보 모달 ────────────────────────────────
   문항을 먼저 불러 두고 그 위에 덮는다.
   폰(기본)은 아래에서 올라오는 시트, 태블릿 가로부터는 가운데 대화상자. */
.pmodal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--z-modal);display:flex;align-items:flex-end}
.pm-dim{
  position:absolute;top:0;right:0;bottom:0;left:0;
  background:rgba(7,12,22,.5);backdrop-filter:blur(10px);
  opacity:0;transition:opacity .3s var(--ease);
}
/* 모달이 떠 있는 동안 뒤 내용을 비운다.
   흐리게만 하면 문항이 어렴풋이 비쳐 시선을 뺏는다. */
body.gate-open .sheet,
body.gate-open .dock,
body.gate-open .pchip,
body.gate-open .rail,
body.gate-open .state{visibility:hidden}
.pmodal.show .pm-dim{opacity:1}
/* 구형 브라우저가 못 읽는 값은 먼저 안전한 값을 쓰고 최신 값을 덮어쓴다.
   한 줄만 쓰면 그 선언 전체가 무효가 되어 여백·높이가 통째로 사라진다. */
.pm-panel{
  position:relative;width:100%;
  max-height:88vh;
  max-height:88dvh;
  overflow-y:auto;
  padding:10px 20px 24px;
  padding-bottom:calc(24px + var(--safe-bottom));
  border-radius:var(--r-xl) var(--r-xl) 0 0;
  background:var(--card);
  box-shadow:0 -18px 50px -20px rgba(7,12,22,.5);
  transform:translateY(100%);
  transition:transform .34s var(--ease-out);
}
.pmodal.show .pm-panel{transform:none}
/* 시트 손잡이 — 아래에서 올라온 판이라는 신호 */
.pm-grip{
  display:block;width:44px;height:5px;margin:0 auto 16px;
  border-radius:999px;background:#DDE5EF;
}

@media (min-width:768px){
  .pmodal{align-items:center;justify-content:center;padding:24px}
  .pm-panel{
    /* min() 을 못 읽는 브라우저에서는 width 선언이 통째로 무효가 되어
       바텀시트의 width:100% 가 남고 가운데 정렬이 풀린다.
       max-width 는 어디서나 통하므로 이쪽으로 잡는다. */
    width:100%;max-width:520px;
    max-height:86vh;
    max-height:86dvh;
    padding:28px 30px 30px;border-radius:var(--r-xl);
    box-shadow:var(--shadow-lg);
    transform:translateY(16px) scale(.97);
    transition:transform .3s var(--ease-out), opacity .3s var(--ease);
    opacity:0;
  }
  .pmodal.show .pm-panel{transform:none;opacity:1}
  .pm-grip{display:none}
}
@media (prefers-reduced-motion:reduce){
  .pm-panel,.pm-dim{transition:none}
}

.pg-title{font-size:var(--fs-h2);font-weight:800;letter-spacing:-.035em}
.pg-desc{margin-top:9px;font-size:var(--fs-body);color:var(--text-sub)}
.pg-field{margin-top:24px}
.pg-label{
  display:block;margin-bottom:10px;
  font-size:var(--fs-sub);font-weight:800;color:var(--text);
}
.pg-select{
  width:100%;min-height:56px;padding:0 44px 0 16px;
  border-radius:var(--r-md);border:1.5px solid var(--line);background:var(--card);
  font-family:inherit;font-size:var(--fs-choice);font-weight:600;color:var(--text);
  /* 화살표를 직접 그려 브라우저마다 다른 기본 모양을 없앤다 */
  appearance:none;-webkit-appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%235A6779' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 14px center;background-size:22px;
}
.pg-select:disabled{background-color:#F4F7FB;color:var(--text-sub)}
.pg-fixed{margin-top:8px;font-size:var(--fs-sub);color:var(--text-dim)}
.pg-ages{display:flex;flex-wrap:wrap;gap:9px}
.pg-hint{font-size:var(--fs-sub);color:var(--text-dim)}
.pg-age{
  min-height:56px;padding:0 20px;border-radius:var(--r-md);
  background:var(--card);border:1.5px solid var(--line);
  font-size:var(--fs-choice);font-weight:700;color:var(--text);
  transition:border-color .25s var(--ease), background .25s var(--ease), transform .25s var(--ease);
}
.pg-age:hover{border-color:#C9D5E6;background:#FBFDFF}
.pg-age:active{transform:scale(.97)}
.pg-age.on{
  border-color:var(--signal-blue);background:#EAF1FE;color:var(--signal-blue);
  box-shadow:0 0 0 1.5px var(--signal-blue) inset;
}
.pm-panel .btn{margin-top:28px}

/* ── 응시자 표시 칩 ──────────────────────────────── */
/* 좌우 여백은 .sheet 와 같은 값이라 문항 카드와 폭이 정확히 맞는다 */
.pchip{
  display:flex;align-items:center;gap:10px;
  margin:12px 8px 0;padding:9px 16px;min-height:58px;
  border-radius:var(--r-pill);
  background:#EEF3FA;border:1px solid #E0E8F3;
  font-size:var(--fs-sub);font-weight:700;color:var(--text-sub);
}
/* 글은 칩 가운데에 둔다. 「바꾸기」가 다시 나오면 그 버튼이 오른쪽 끝을 차지하고
   글은 남은 칸의 가운데에 놓인다. */
.pchip-txt{flex:1 1 0;min-width:0;text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 다른 사람이 이어받았을 때 가장 먼저 눌러야 할 버튼이라 붉게 세운다 */
.pchip-edit{
  margin-left:auto;flex-shrink:0;
  min-height:40px;padding:0 24px;border-radius:var(--r-pill);
  background:#FEF0F0;border:1.5px solid #F5C4C4;
  font-size:var(--fs-sub);font-weight:800;color:#B02121;
  transition:background .25s var(--ease), border-color .25s var(--ease), transform .25s var(--ease);
}
.pchip-edit:hover{background:#FDE2E2;border-color:#EDA6A6}
.pchip-edit:active{transform:scale(.96)}
/* 키오스크는 줄을 서서 이어 쓰므로, 스크롤해도 늘 보이게 붙여 둔다 */
[data-kiosk="1"] .pchip{
  position:sticky;top:calc(var(--appbar-h, 94px));z-index:var(--z-header);
  margin:0;border-radius:0;border-left:0;border-right:0;
}

/* ── 문항 ───────────────────────────────────────── */
.sheet{padding:18px 8px 8px;display:grid;gap:16px}

/* 정적 폴백(지침 11) — 스크립트가 없으면 로딩·독을 감추고
   마크업에 구워 둔 샘플 문항을 그대로 보여 준다.
   html.js 클래스는 <head> 인라인 스크립트가 붙인다. */
html:not(.js) .state{display:none !important}
html:not(.js) .sheet[hidden]{display:grid !important}
html:not(.js) .dock[hidden]{display:block !important}
.qitem{
  position:relative;padding:20px 18px;border-radius:var(--r-lg);
  background:var(--card);border:1px solid var(--line);box-shadow:var(--shadow-sm);
  /* 다음 문항으로 이동할 때 고정 헤더에 가리지 않도록 딱 1px 만 여유를 둔다.
     --appbar-h 는 quiz.js 가 헤더 실제 높이를 재서 넣는다(글자 크기·스킨에 따라 달라짐). */
  scroll-margin-top:calc(var(--appbar-h, 94px) + 8px);
  transition:border-color .4s var(--ease), box-shadow .4s var(--ease);
}
.qitem.answered.correct{border-color:#BEE9D8}
.qitem.answered.wrong{border-color:#FBD5D5}

/* 지침 2 — 배지와 지문은 같은 줄에.
   다만 폰 폭에서는 배지가 112px을 먹어 지문 폭이 284px로 줄고,
   정답 축하 이미지(80px)가 붙으면 204px까지 좁아져 글이 다시 흐른다.
   그래서 기본은 지문을 아랫줄로 내리고(flex-basis 100%),
   폭이 넉넉한 태블릿 가로부터 같은 줄에 놓는다. */
.qi-head{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-bottom:14px;min-height:40px}
.qi-no,.qi-area{flex-shrink:0}
/* 채점 표시(O·X) — 머리줄 오른쪽 끝. 작게 놓는다.
   위쪽 음수 여백으로 카드 안쪽 여백까지만 넘겨 그린다.
   아래로는 넘기지 않아 지문 글자와 겹칠 일이 없다.
   .mark-img 의 퍼센트 폭 규칙이 여기서는 맞지 않으므로 되돌린다. */
.qi-cheer{margin-left:auto;flex-shrink:0;display:flex;align-items:center}
.qi-cheer .mark-img,
.qi-cheer .mark-img.mark-o,
.qi-cheer .mark-img.mark-x{
  width:auto;height:80px;max-width:none;display:block;margin-top:-14px;
  animation:cheerIn .55s var(--ease-out) both;
}
@keyframes cheerIn{
  0%  {opacity:0;transform:scale(.4) rotate(-14deg)}
  60% {opacity:1;transform:scale(1.1) rotate(5deg)}
  100%{opacity:1;transform:scale(1) rotate(0)}
}
@media (prefers-reduced-motion:reduce){
  .qi-cheer .mark-img{animation:none}
}
.qi-no{display:grid;place-items:center;width:26px;height:26px;border-radius:9px;
  background:var(--ink-800);color:#fff;font-size:var(--fs-label);font-weight:800}
.qi-area{font-size:var(--fs-label);font-weight:700;color:var(--signal-blue);
  background:#EAF1FE;padding:5px 10px;border-radius:var(--r-pill)}

.qi-stem{flex:1 1 100%;min-width:0;margin:0;
  font-size:var(--fs-stem);font-weight:700;letter-spacing:-.03em;line-height:1.56;
  text-wrap:balance}

/* 정답 축하 이미지 — 상황 그림 위에 크게 얹는다 */
.qi-figure{position:relative}
.grade-mark{position:absolute;top:0;right:0;bottom:0;left:0;z-index:2;display:grid;place-items:center;pointer-events:none}
/* 그림 위에 바로 얹으면 배경에 묻히므로 흰 원 안에 넣는다.
   원(cheer-wrap)은 등장할 때만 움직이고 그 뒤로는 가만히 있는다.
   반복해서 커졌다 작아지는 것은 안쪽 캐릭터(cheer-img)뿐이다.
   aspect-ratio:1 로 가로·세로를 같게 잡아야 정확한 원이 된다. */
.grade-mark .cheer-wrap{
  box-sizing:content-box;
  display:grid;place-items:center;
  /* aspect-ratio 를 못 읽는 브라우저를 위해 높이를 먼저 지정해 둔다 */
  /* 원의 지름 = 폭 + 좌우 여백 60px. 2지선다에서 너무 커 보여 지름을 10px 줄였다(250 → 240) */
  width:calc(46% - 10px);max-width:180px;height:140px;
  height:auto;aspect-ratio:1;
  padding:30px;border-radius:50%;
  background:#fff;
  box-shadow:0 14px 34px -14px rgba(14,23,38,.45);
  animation:cheerIn .55s var(--ease-out) both;
}
.grade-mark .cheer-img{
  width:100%;height:100%;object-fit:contain;
  animation:cheerBeat 1.5s var(--ease) .55s infinite;
}
@keyframes cheerBeat{
  0%,100%{transform:scale(1)}
  50%    {transform:scale(1.1)}
}
/* 정답 — 왼쪽에서 날아와 통통 튀며 자리를 잡은 뒤, 캐릭터가 두근거린다(cheerBeat).
   그림 상자가 overflow:hidden 이라 그림 왼쪽 끝에서 튀어나오는 것처럼 보인다.
   오답(.is-oops)은 아래에서 animation 을 다시 정해 이 동작을 쓰지 않는다. */
.grade-mark .cheer-wrap:not(.is-oops){animation:cheerFly 1.7s linear both}
.grade-mark .cheer-wrap:not(.is-oops) > .cheer-img{animation-delay:1.7s}
@keyframes cheerFly{
  0%  {opacity:0;transform:translate(-260%,-40%) rotate(-40deg) scale(.7);animation-timing-function:cubic-bezier(.3,0,.7,1)}
  10% {opacity:1}
  28% {transform:translate(0,0) rotate(0) scale(1.14,.84);animation-timing-function:cubic-bezier(.2,.7,.4,1)}
  42% {transform:translate(0,-60%) rotate(6deg) scale(.95,1.08);animation-timing-function:cubic-bezier(.6,0,.8,.4)}
  55% {transform:translate(0,0) rotate(0) scale(1.1,.88);animation-timing-function:cubic-bezier(.2,.7,.4,1)}
  66% {transform:translate(0,-36%) rotate(-4deg) scale(.97,1.05);animation-timing-function:cubic-bezier(.6,0,.8,.4)}
  77% {transform:translate(0,0) rotate(0) scale(1.06,.93);animation-timing-function:cubic-bezier(.2,.7,.4,1)}
  86% {transform:translate(0,-16%) scale(1);animation-timing-function:cubic-bezier(.6,0,.8,.4)}
  94% {transform:translate(0,0) scale(1.03,.97)}
  100%{opacity:1;transform:none}
}
/* 오답 — 그림에 바탕색이 깔려 있어 원도 같은 색으로 칠하고,
   그림은 자르지 않고 통째로 넣어 정답처럼 둘레에 여백을 둔다.
   등장은 정답과 같되 한 번 움찔한 뒤, 고개를 갸웃거리듯 좌우로 천천히 흔들린다. */
.grade-mark .cheer-wrap.is-oops{
  padding:6px;overflow:hidden;
  width:calc(46% + 48px);max-width:238px;
  background:#FC818F;
  border:4px solid #fff;
  animation:cheerIn .55s var(--ease-out) both, oopsShake .5s var(--ease) .55s;
}
.grade-mark .cheer-wrap.is-oops > .cheer-img{
  object-fit:contain;
  transform-origin:50% 85%;
  animation:oopsSway 2.2s var(--ease) 1.05s infinite;
}
@keyframes oopsShake{
  0%,100%{transform:translateX(0)}
  20%{transform:translateX(-10px)}
  40%{transform:translateX(9px)}
  60%{transform:translateX(-6px)}
  80%{transform:translateX(4px)}
}
@keyframes oopsSway{
  0%,100%{transform:scale(1) rotate(0)}
  25%    {transform:scale(1) rotate(-4deg)}
  75%    {transform:scale(1) rotate(4deg)}
}
/* 4지선다 — 캐릭터를 2/3 크기로 줄이고, 캡션을 뺀 그림의 세로 정중앙에 둔다.
   .scene-box 를 기준으로 삼아야 캡션 높이만큼 아래로 처지지 않는다. */
.qitem.is-quad .scene-box{position:relative}
.qitem.is-quad .grade-mark .cheer-wrap{width:30.7%;max-width:127px;padding:20px}
.qitem.is-quad .grade-mark .cheer-wrap.is-oops{width:calc(30.7% + 32px);max-width:159px;padding:4px}
@media (prefers-reduced-motion:reduce){
  .grade-mark .cheer-wrap,
  .grade-mark .cheer-img,
  .grade-mark .cheer-wrap:not(.is-oops),
  .grade-mark .cheer-wrap.is-oops,
  .grade-mark .cheer-wrap.is-oops > .cheer-img{animation:none}
}

/* 채점 표시 기본형 — 결과지 등 다른 곳에서도 쓴다 */
.mark-img{width:76%;max-width:300px;height:auto;
  mix-blend-mode:multiply;
  animation:markIn .5s cubic-bezier(.2,1.3,.4,1) both;
  filter:drop-shadow(0 2px 5px rgba(200,30,20,.18))}
.mark-img.mark-o{transform:rotate(-3deg)}
.mark-img.mark-x{width:58%;max-width:232px;transform:rotate(2deg)}
@keyframes markIn{
  0%{opacity:0;transform:scale(.55) rotate(-14deg)}
  60%{opacity:1}
  100%{opacity:1;transform:scale(1) rotate(-3deg)}
}
.mark-img.mark-x{animation-name:markInX}
@keyframes markInX{
  0%{opacity:0;transform:scale(.55) rotate(14deg)}
  60%{opacity:1}
  100%{opacity:1;transform:scale(1) rotate(2deg)}
}

/* 상황 그림 */
.qi-figure{margin:0 0 16px;border-radius:var(--r-md);overflow:hidden;
  border:1px solid var(--line);background:#EEF3FA}
.scene-art{display:block;width:100%;height:auto}
/* 실제 사진이 들어간 문항 — SVG 자리와 동일하게 폭을 꽉 채운다 */
.scene-photo{display:block;width:100%;height:auto;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;pointer-events:none}
.scene-cap{display:flex;align-items:center;gap:10px;padding:10px 12px;
  background:var(--card);border-top:1px solid var(--line)}
.scene-tag{font-size:var(--fs-sub);font-weight:700;color:var(--text-sub);letter-spacing:-.02em}
.scene-play{
  margin-left:auto;display:inline-flex;align-items:center;gap:6px;flex-shrink:0;
  height:34px;padding:0 13px;border-radius:var(--r-pill);
  background:#F1F5FA;border:1px solid #E3EAF4;
  font-size:var(--fs-sub);font-weight:700;color:var(--text-sub);
  transition:background .3s var(--ease), color .3s var(--ease), transform .3s var(--ease);
}
.scene-play svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.scene-play:hover{background:#E7EFFA;color:var(--signal-blue)}
.scene-play:active{transform:scale(.96)}
.scene-defs{position:absolute;width:0;height:0;overflow:hidden}

/* ── 보기 ───────────────────────────────────────── */
.qi-choices{display:grid;gap:9px}

/* 다지선다 */
.choice{
  position:relative;display:flex;align-items:center;gap:11px;width:100%;
  min-height:58px;padding:13px 15px;text-align:left;
  border-radius:var(--r-md);background:#FAFCFF;border:1.5px solid #E7EDF6;
  font-size:var(--fs-choice);font-weight:600;letter-spacing:-.02em;color:var(--text);
  transition:border-color .3s var(--ease), background .3s var(--ease), transform .3s var(--ease);
}
.choice .key{flex-shrink:0;display:grid;place-items:center;width:28px;height:28px;border-radius:9px;
  background:#EAF0F8;color:var(--text-sub);font-size:var(--fs-sub);font-weight:800;
  transition:background .3s var(--ease), color .3s var(--ease)}
.choice .txt{flex:1}
.choice .mark{flex-shrink:0;width:20px;height:20px;opacity:0;transition:opacity .3s var(--ease)}
.choice .mark svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2.8;
  stroke-linecap:round;stroke-linejoin:round}
.choice:hover:not(:disabled){border-color:#BDD0EC;background:#fff;transform:translateY(-2px)}
.choice:active:not(:disabled){transform:scale(.99)}
.choice:disabled{cursor:default}
.choice.is-correct{border-color:#12B886;background:#EEFBF6;color:#046B4E}
.choice.is-correct .key{background:#12B886;color:#fff}
.choice.is-correct .mark{opacity:1;color:#12B886}
.choice.is-wrong{border-color:#FF6B6B;background:#FEF0F0;color:#B02121}
.choice.is-wrong .key{background:#FF6B6B;color:#fff}
.choice.is-dim{opacity:.45}

/* OX — 좌우 2칸, 기호만 */
.qi-choices.ox{grid-template-columns:1fr 1fr;gap:18px;gap:clamp(10px,4vw,28px);
  justify-items:center;padding:6px 0 2px}
.oxbtn{
  position:relative;display:flex;flex-direction:column;align-items:center;gap:12px;
  padding:10px 6px;background:none;border:0;width:100%;
  transition:transform .4s var(--ease), opacity .4s var(--ease);
}
.oxbtn .halo{position:absolute;top:-6px;left:50%;transform:translateX(-50%) scale(.5);
  width:140px;height:140px;
  width:clamp(112px,32vw,168px);height:auto;aspect-ratio:1;
  border-radius:50%;
  background:radial-gradient(circle,var(--ox) 0%,transparent 68%);
  opacity:0;transition:opacity .45s var(--ease), transform .45s var(--ease);pointer-events:none}
.oxbtn .sym{width:112px;width:clamp(92px,26vw,132px);height:auto;overflow:visible}
.oxbtn .sym circle,.oxbtn .sym path{fill:none;stroke:var(--ox);stroke-width:9;stroke-linecap:round}
.oxbtn .cap{font-size:var(--fs-choice);font-weight:700;letter-spacing:-.02em;color:var(--text-sub);
  transition:color .35s var(--ease)}
.oxbtn.o{--ox:#12B886}
.oxbtn.x{--ox:#FF6B6B}
.oxbtn .sym circle{stroke-dasharray:208;stroke-dashoffset:208;animation:drawO .7s var(--ease-out) .05s forwards}
.oxbtn .sym path{stroke-dasharray:60;stroke-dashoffset:60;animation:drawX .38s var(--ease-out) forwards}
.oxbtn .sym path:nth-child(1){animation-delay:.1s}
.oxbtn .sym path:nth-child(2){animation-delay:.26s}
@keyframes drawO{to{stroke-dashoffset:0}}
@keyframes drawX{to{stroke-dashoffset:0}}
.oxbtn:hover:not(:disabled){transform:translateY(-5px) scale(1.04)}
.oxbtn:hover:not(:disabled) .halo{opacity:.16;transform:translateX(-50%) scale(1)}
.oxbtn:hover:not(:disabled) .cap{color:var(--ox)}
.oxbtn:active:not(:disabled){transform:translateY(-2px) scale(.99)}
.oxbtn:disabled{cursor:default}
.oxbtn.is-correct .halo{opacity:.24;transform:translateX(-50%) scale(1.04)}
.oxbtn.is-correct .cap{color:var(--ox);font-weight:800}
.oxbtn.is-correct .sym{animation:pop .5s var(--ease-out)}
.oxbtn.is-wrong .sym{animation:shake .5s var(--ease)}
.oxbtn.is-wrong .cap{color:var(--ox)}
.oxbtn.is-dim{opacity:.18}
@keyframes pop{0%{transform:scale(1)}45%{transform:scale(1.12)}100%{transform:scale(1)}}
@keyframes shake{0%,100%{transform:translateX(0)}22%{transform:translateX(-9px)}
  46%{transform:translateX(8px)}70%{transform:translateX(-5px)}}

/* ── 해설 ───────────────────────────────────────── */
.qi-explain{margin-top:16px;padding:15px 16px;border-radius:var(--r-md);
  background:#F5FBF8;border:1px solid #D8EFE5;
  animation:exIn .45s var(--ease-out) both}
.qi-explain.is-wrong{background:#FFF6F6;border-color:#F8DCDC}
@keyframes exIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

.ex-bar{display:flex;height:26px;border-radius:8px;overflow:hidden;margin-bottom:13px}
/* min-width:0 이 없으면 글자 폭만큼 자리가 남아 반대쪽이 100% 를 채우지 못한다
   (플렉스 항목의 기본값이 min-width:auto 라서 내용보다 작아지지 않는다) */
.ex-bar span{display:grid;place-items:center;min-width:0;overflow:hidden;
  white-space:nowrap;font-size:var(--fs-label);font-weight:800;color:#fff}
.ex-bar .ex-o{flex:1;background:#12B886}
.ex-bar .ex-x{flex:0 0 0;background:#FF6B6B;opacity:0;transition:flex .5s var(--ease)}
.qi-explain.is-wrong .ex-o{flex:0 0 0;opacity:0}
.qi-explain.is-wrong .ex-x{flex:1;opacity:1}

.ex-body{display:grid;grid-template-columns:auto 1fr;gap:7px 12px;align-items:start}
.ex-body dt{font-size:var(--fs-sub);font-weight:800;color:var(--text-dim);white-space:nowrap;
  padding-top:2px}
.ex-body dd{font-size:var(--fs-body);color:var(--text-sub);line-height:1.68;text-align:justify;word-break:normal}
.ex-body .ex-ans{font-weight:800;color:#046B4E}
.qi-explain.is-wrong .ex-ans{color:#B02121}
.ex-body .ex-goal{color:var(--text-dim);font-size:var(--fs-sub)}

/* 해설 아래 조작 줄 — 왼쪽 「해설 듣기」, 오른쪽 끝 「건너뛰기」 */
.ex-foot{display:flex;align-items:center;gap:8px;margin-top:13px}
.ex-skip{
  margin-left:auto;flex-shrink:0;
  display:inline-flex;align-items:center;gap:5px;
  height:38px;padding:0 16px;border-radius:var(--r-pill);
  background:#FEF0F0;border:1.5px solid #F5C4C4;
  font-size:var(--fs-sub);font-weight:800;color:#B02121;
  transition:background .25s var(--ease), border-color .25s var(--ease), transform .25s var(--ease);
}
.ex-skip svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round}
.ex-skip:hover{background:#FDE2E2;border-color:#EDA6A6}
.ex-skip:active{transform:scale(.96)}

.ex-play{display:inline-flex;align-items:center;gap:6px;
  height:34px;padding:0 13px;border-radius:var(--r-pill);
  background:#fff;border:1px solid var(--line);
  font-size:var(--fs-sub);font-weight:700;color:var(--text-sub);
  transition:background .3s var(--ease), color .3s var(--ease)}
.ex-play svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.ex-play:hover{background:#F7FAFF;color:var(--signal-blue)}


/* ── 태블릿 가로 ────────────────────────────────── */
@media (min-width:768px){
  /* 대문·대상선택과 같은 규칙 — 셸 폭을 그대로 쓰고 좌우 40px */
  .sheet{padding:24px 40px 8px;gap:20px}
  .pchip{margin:16px 40px 0}   /* 문항 카드와 좌우를 맞춘다 */
  .qitem{padding:26px 24px}
  /* 폭이 넉넉하므로 지문을 배지와 같은 줄로 올린다.
     flex-basis 를 0 으로 둬야 지문이 길어도 아랫줄로 밀려나지 않고
     남은 폭 안에서 스스로 줄바꿈한다. auto 로 두면 내용 폭이 넘칠 때 줄이 넘어간다. */
  .qi-stem{flex:1 1 0;font-size:calc(1.3rem * var(--fs-k))}
  .dock .dock-row{max-width:860px;margin:0 auto}

  /* 4지선다 — 왼쪽 그림, 오른쪽 지문·보기의 2단 배치.
     보기가 네 개라 한 줄로 쌓으면 카드가 지나치게 길어진다.
     그림은 두 행에 걸쳐 왼쪽 열을 차지한다. */
  .qitem.is-quad{
    display:grid;
    /* 그림 칸을 좁혀 보기 4개의 높이(약 250px)에 가깝게 맞춘다.
       남는 높이는 위 규칙이 그림을 줄여 흡수한다. */
    grid-template-columns:minmax(0,0.72fr) minmax(0,1fr);
    grid-template-areas:
      "head    head"
      "figure  choices"
      "explain explain";
    column-gap:22px;
  }
  .qitem.is-quad .qi-head{grid-area:head}
  /* 그림은 제 비율대로 둔다. 높이를 억지로 맞추면 SVG 가 줄면서
     박스 좌우에 빈 여백이 생긴다. */
  .qitem.is-quad .qi-figure{grid-area:figure;margin-bottom:0;align-self:start}
  /* 대신 보기 쪽을 늘려 높이를 맞춘다.
     grid-auto-rows:1fr 로 보기 네 개가 남는 높이를 고르게 나눠 갖는다. */
  .qitem.is-quad .qi-choices{
    grid-area:choices;
    align-self:stretch;
    grid-auto-rows:1fr;
  }
  .qitem.is-quad .qi-explain{grid-area:explain}
}

/* ── 분할 진단 탭 ──────────────────────────────────
   45문항 이상인 대상만 나온다. 세 분야를 오가며 풀고 결과지도 따로 본다.
   좌우 여백은 .sheet 와 맞춰 문항 카드와 끝선이 일치한다. */
.parts{
  display:flex;gap:6px;
  margin:12px 8px 0;padding:5px;
  border-radius:var(--r-md);
  background:#EEF3FA;border:1px solid #E0E8F3;
}
.part{
  flex:1 1 0;min-width:0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:9px 4px;border-radius:var(--r-sm);
  text-align:center;line-height:1.25;
  transition:background .25s var(--ease), box-shadow .25s var(--ease);
}
.part-n{
  font-size:var(--fs-sub);font-weight:800;letter-spacing:-.03em;
  color:var(--text-sub);white-space:nowrap;
}
.part-s{margin-top:2px;font-size:var(--fs-label);font-weight:600;color:var(--text-dim)}
.part:hover{background:rgba(255,255,255,.7)}
/* 지금 풀고 있는 분야 */
.part.on{background:var(--card);box-shadow:var(--shadow-sm)}
.part.on .part-n{color:var(--signal-blue)}
.part.on .part-s{color:var(--signal-blue)}
/* 이미 마친 분야 — 누르면 결과지로 */
.part.done .part-n{color:#046B4E}
.part.done .part-s{color:#0CA678}

@media (min-width:768px){
  .parts{margin:16px 40px 0}
}
@media print{.parts{display:none}}

/* 마지막 문항이 아래에 떠 있는 독(푼 문항·결과 보기)에 가리지 않게 한다.
   독의 높이(약 110px)에 여유 50px 을 더해 문제지 아래를 비운다.
   폭별 .sheet 규칙(위 @media)보다 뒤에 두어야 이 값이 이긴다(지침 3 — 뒤쪽 우선). */
.sheet{padding-bottom:160px;padding-bottom:calc(160px + var(--safe-bottom))}
