/* ==========================================================================
   EIP Study — 암기 카드 (cards.html) 전용 스타일

   🔒 style.css 에 넣지 않고 따로 둔다. 약어 사전(glossary.css)과 같은 이유다 —
      이 화면에서만 쓰는 규칙이라 다른 화면으로 샐 이유가 없고,
      style.css 는 여러 작업이 동시에 건드리는 파일이라 충돌이 잦다.
      색은 전부 style.css 의 디자인 토큰을 쓰므로 다크 모드가 그대로 따라온다.
   ========================================================================== */

/* ---------- 기기별 안내 ----------
   쓰지 않는 조작을 읽게 하지 않는다. 두 벌을 다 그려 두고 여기서 하나만 보여 준다.
   🔒 JS 로 판별하지 않는다 — 노트북에 마우스를 꽂았다 뺐다 하면 화면이 안 따라온다.
      (hover: hover) and (pointer: fine) 이 "정밀 포인터가 있다" = PC 라는 뜻이다.
      터치스크린 노트북은 둘 다라 PC 쪽이 뜨는데, 그래도 밀기는 그대로 된다. */
.only-pc { display: none; }
.only-touch { display: inline; }
@media (hover: hover) and (pointer: fine) {
  .only-pc { display: inline; }
  .only-touch { display: none; }
}

/* ---------- 단계 탭 ---------- */
.ctabs {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 0 0 10px;
}
.ctab {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 15px;
  background: var(--bg-elev); color: var(--fg-muted);
  border: 1px solid var(--border); border-radius: 999px;
  font-size: 13px;
  transition: border-color .15s, color .15s;
}
.ctab:hover { border-color: var(--accent); color: var(--fg); }
.ctab[aria-pressed="true"] {
  border-color: var(--accent); color: var(--accent); font-weight: 700;
}
.ctab__n {
  min-width: 18px; padding: 0 5px;
  background: var(--bg-sunken); border-radius: 999px;
  font-size: 11.5px; text-align: center; color: var(--fg-faint);
}
.ctab[aria-pressed="true"] .ctab__n { color: var(--accent); }

/* ---------- 조작 줄 ---------- */
.cctl {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin: 0 0 20px;
}
.cctl__sel, .cctl__btn {
  padding: 6px 10px;
  background: var(--bg-elev); color: var(--fg-muted);
  border: 1px solid var(--border); border-radius: var(--radius-s);
  font-size: 12.5px; font-family: inherit;
}
.cctl__sel:hover, .cctl__btn:hover:not(:disabled) {
  border-color: var(--accent); color: var(--fg);
}
.cctl__btn[aria-pressed="true"] {
  background: var(--accent-weak); border-color: var(--accent); color: var(--accent);
}
.cctl__btn:disabled { opacity: .4; cursor: default; }

/* ---------- 카드 블록 ----------
   🔒 밀기를 받는 범위는 카드 요소가 아니라 이 블록 전체다
   (위치 표시 · 좌우 힌트 · 카드 · 조작 안내).

   카드 요소만 잡았더니 카드 둘레 여백을 짚었을 때 밀기가 안 먹었다.
   눈에는 다 "카드 있는 자리"인데 손끝 몇 px 차이로 갈리면 고장으로 읽힌다.

   📌 축을 좌우로 되돌린 뒤에도 이 범위는 그대로다 — 밀기를 놓치는 문제는 축과 무관하다.
   📌 touch-action 은 선언일 뿐이고 실제로 끊는 것은 cards.js 의 preventDefault 다. */
.cdeck { touch-action: none; }

/* ---------- 카드 위 정보 ---------- */
.cmeta {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 8px;
  margin: 0 0 8px;
  font-size: 12px; color: var(--fg-faint);
}
/* 챕터 · 섹션까지 담아 길어졌다. 잘라 내지 말고 줄바꿈시킨다 —
   어느 섹션에서 온 카드인지가 잘리면 적어 둔 뜻이 없다. */
.cmeta__where { flex: 1 1 auto; min-width: 0; word-break: keep-all; }
a.cmeta__where { color: inherit; text-decoration: none; }
a.cmeta__where:hover { color: var(--accent); text-decoration: underline; }
/* 챕터는 맥락, **섹션이 목적지**다 — 누르면 그 개념을 가르치는 섹션으로 간다 (T34).
   🚨 챕터를 흐리게 두어 눈이 섹션 이름에 먼저 가게 한다. 예전에는 챕터만 있었다. */
.cmeta__ch  { color: var(--fg-faint); }
.cmeta__sec { color: var(--fg-muted); }
.cmeta__ch + .cmeta__sec::before { content: ' · '; color: var(--fg-faint); }
a.cmeta__where:hover .cmeta__ch,
a.cmeta__where:hover .cmeta__sec { color: var(--accent); }
.cmeta__saved { flex: none; color: var(--star, var(--warn)); font-weight: 700; }
.cmeta__pos { flex: none; font-variant-numeric: tabular-nums; }

/* 좌·우가 무슨 뜻인지 늘 보이게 둔다.
   구역을 눈에 보이지 않게 나눠 두면 "왜 어떤 때는 뒤집히고 어떤 때는 넘어가지" 가 된다. */
.chint {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin: 0 0 8px;
  font-size: 12px; color: var(--fg-faint);
}
.chint__side { font-weight: 700; color: var(--fg-muted); }

/* ---------- 카드 ---------- */
.ccard {
  position: relative;
  width: 100%; min-height: 260px;
  perspective: 1200px;
  cursor: pointer; user-select: none; -webkit-user-select: none;
  touch-action: none;   /* .cdeck 과 한 벌 — 설명은 .cdeck 쪽에 */
  -webkit-tap-highlight-color: transparent;
  transition: transform .19s ease, opacity .19s ease;
}
.ccard:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: var(--radius); }

/* 미는 동안에는 손가락을 그대로 따라와야 하므로 전환을 끈다 */
.ccard.is-dragging { transition: none; }

/* 민 방향으로 날아간다 */
.ccard.is-out-left  { transform: translateX(-120%) rotate(-12deg); opacity: 0; }
.ccard.is-out-right { transform: translateX(120%) rotate(12deg); opacity: 0; }

.ccard__inner {
  position: relative;
  width: 100%; min-height: 260px;
  transform-style: preserve-3d;
  transition: transform .42s cubic-bezier(.4,0,.2,1);
}
.ccard.is-flipped .ccard__inner { transform: rotateY(180deg); }

.ccard__face {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 28px 26px;
  background: var(--bg-elev);
  border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow);
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  text-align: center; line-height: 1.7;
  /* 글이 카드보다 길어지는 드문 경우의 안전판.
     스크롤 컨테이너가 되므로 여기서 스크롤이 바깥으로 번지지 않게 막아 둔다 —
     실제로 끊는 것은 cards.js 의 preventDefault 지만 그것이 안 먹는 경우의 보험이다. */
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* 글은 면의 자식 하나에 담는다 — cards.js 주석 참고.
   ⚠️ word-break: keep-all 이 없으면 한글이 낱말 한가운데서 끊긴다 ("언 / 어)").
      body 의 overflow-wrap: break-word 를 여기서 되돌리는 것이다.
      대신 overflow-wrap: anywhere 를 남겨 아주 긴 덩어리는 마지막 수단으로 끊는다. */
/* 🔒 길이에 따라 정렬이나 글자 크기를 바꾸지 말 것.
      길이 기준으로 왼쪽 정렬 + 축소를 넣었더니 카드마다 생김새가 달라져
      넘길 때마다 눈이 새로 적응해야 했다. 모든 카드가 같은 모양이어야 한다. */
.ccard__text {
  width: 100%;
  word-break: keep-all;
  overflow-wrap: anywhere;
}

.ccard__face--front { font-size: 20px; font-weight: 700; letter-spacing: -.01em; }
.ccard__face--back {
  transform: rotateY(180deg);
  font-size: 16px; color: var(--fg-muted);
}
.ccard__face--back b { color: var(--fg); font-weight: 800; }
.ccard__face code {
  padding: 1px 5px;
  background: var(--bg-sunken); border-radius: 5px;
  font-family: var(--font-mono); font-size: .92em;
}

/* 좌·우 끝이 넘김 구역이라는 것을 은근히 보여 준다 */
.ccard::before, .ccard::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: 34%;
  border-radius: var(--radius);
  opacity: 0; transition: opacity .15s;
  pointer-events: none; z-index: 2;
}
.ccard::before { left: 0; background: linear-gradient(90deg, var(--accent-weak), transparent); }
.ccard::after  { right: 0; background: linear-gradient(270deg, var(--warn-weak), transparent); }
/* 좌·우 구역은 PC 전용이다. 모바일은 축이 세로라 좌우에 색이 뜨면 거짓말이 된다
   (터치 뒤 :hover 가 남아 있는 브라우저가 있다). */
@media (hover: hover) and (pointer: fine) {
  .ccard:hover::before, .ccard:hover::after { opacity: .55; }
}

.ckeys {
  margin: 12px 0 0; text-align: center;
  font-size: 11.5px; color: var(--fg-faint);
}

/* ---------- 다 넘긴 뒤 ---------- */
.cdone {
  padding: 44px 24px; text-align: center;
  background: var(--bg-elev);
  border: 1px solid var(--border); border-radius: var(--radius);
}
.cdone__msg { margin: 0 0 6px; font-size: 17px; font-weight: 700; }
.cdone__sub { margin: 0 0 18px; font-size: 13.5px; color: var(--fg-muted); }
.cdone__btn {
  margin: 0 4px;
  padding: 9px 18px;
  background: var(--bg); color: var(--fg-muted);
  border: 1px solid var(--border); border-radius: var(--radius-s);
  font-size: 13.5px; font-family: inherit;
}
.cdone__btn:hover { border-color: var(--accent); color: var(--accent); }

.cempty {
  margin: 40px 0; text-align: center;
  color: var(--fg-faint); font-size: 14px;
}

/* ---------- 넓은 화면 ---------- */
@media (min-width: 700px) {
  .ccard, .ccard__inner { min-height: 320px; }
  .ccard__face--front { font-size: 24px; }
  .ccard__face--back { font-size: 17px; }
}

@media print {
  .ctabs, .cctl, .chint, .ckeys { display: none !important; }
}

/* ==========================================================================
   화면에 고정한다 — 페이지가 아예 스크롤되지 않는다 (2026-08-10, T26)

   🚨 증상이 아니라 원인을 끊는다.
      카드가 화면보다 짧은데 페이지는 스크롤됐다. 밀려고 잡으면 페이지가 따라 움직여
      당시의 「위아래로 밀기」 제스처와 싸웠다. 이 자리를 이미 두 번 손봤는데
      (바깥 스크롤 따라오던 것 · 미는 범위를 블록으로) 둘 다 증상 쪽이었다.
      **페이지가 스크롤될 수 있다는 것 자체가 원인**이다.

   📌 이걸 막고 나니 축을 세로로 옮겼던 이유도 사라져 **좌우로 되돌렸다** (cards.js ②).

   🔒 `.page-cards`(html 요소)로 범위를 묶는다. 다른 화면은 스크롤이 맞다 —
      본문·퀴즈·오답노트는 목록이 원래 길다. 전역으로 새면 그쪽이 망가진다.

   📌 100vh 가 아니라 100dvh 다. 모바일 주소창이 접혔다 펴질 때 vh 는 튄다.
      dvh 를 모르는 브라우저를 위해 height: 100% 를 먼저 둔다.
   ========================================================================== */
.page-cards, .page-cards body {
  height: 100%;
  height: 100dvh;
  overflow: hidden;
  overscroll-behavior: none;   /* 당겨서 새로고침도 막는다 */
}

.page-cards .layout {
  height: 100%;
  box-sizing: border-box;
}
.page-cards .main {
  height: 100%;
  min-height: 0;
  box-sizing: border-box;
  padding: 14px 16px 12px;     /* 원래 bottom 96px 은 스크롤 버튼 자리였다 — 안 뜨므로 뺀다 */
  display: flex;
  overflow: hidden;
}
.page-cards .wrap {
  display: flex; flex-direction: column;
  width: 100%; height: 100%; min-height: 0;
}

/* hero 는 자리를 많이 먹는다. 이 화면에서는 줄인다 */
.page-cards .hero { margin: 0 0 12px; }
.page-cards .hero h1 { font-size: 20px; }
.page-cards .hero p { margin-top: 4px; font-size: 12.5px; }

/* 카드가 남는 높이를 다 쓴다 */
.page-cards #cards {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
}
.page-cards .cdeck {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
}
.page-cards .ccard {
  flex: 1 1 auto;
  min-height: 0;              /* 260px 하한을 푼다 — 짧은 화면에서 넘치면 안 된다 */
}
.page-cards .ccard__inner { height: 100%; min-height: 0; }

.page-cards .ckeys { flex: none; margin-bottom: 0; }
.page-cards .cdone { flex: none; }
.page-cards .footer { flex: none; margin-top: 10px; padding-top: 10px; }

/* 화면이 낮으면 설명부터 접는다. 같은 안내가 카드 위 좌우 힌트에 또 있다.
   🚨 푸터를 통째로 숨기면 바로가기까지 사라진다 — 설명 줄만 접고 바로가기는 남긴다. */
@media (max-height: 700px) {
  .page-cards .hero p { display: none; }
  .page-cards .footer p { display: none; }
  .page-cards .footer { margin-top: 6px; padding-top: 6px; }
}
@media (max-height: 560px) {
  .page-cards .hero { display: none; }
}

/* 위에서 min-height 하한을 풀었으므로 넓은 화면 규칙도 함께 푼다 */
@media (min-width: 720px) {
  .page-cards .ccard, .page-cards .ccard__inner { min-height: 0; }
}

/* 인쇄에서는 고정을 푼다 — 안 그러면 첫 화면 한 장만 찍힌다 */
@media print {
  .page-cards, .page-cards body,
  .page-cards .layout, .page-cards .main, .page-cards .wrap {
    height: auto; min-height: 0; overflow: visible; display: block;
  }
  .page-cards .hero, .page-cards .hero p, .page-cards .footer { display: block; }
  .page-cards .ccard, .page-cards .ccard__inner { min-height: 260px; }
}


/* 🚨 `hidden` 속성은 UA 기본값(display:none)이라 **display 를 지정한 규칙에 진다.**
   위에서 .cdeck 에 display:flex 를 준 탓에 「다 넘긴 뒤」 화면과 카드가 겹쳐 보였다.
   T26 에서 만든 버그다. hidden 이 이기도록 명시한다. */
.page-cards .cdeck[hidden], .page-cards .cdone[hidden] { display: none; }

/* ---------- 카드 자리를 넓힌다 (2026-08-10) ----------
   모바일에서 위쪽이 낭비되고, 챕터 선택창이 길어 「섞기」 다음이 줄바꿈됐다.
   조작 줄이 두 줄이 되면 그만큼 카드가 줄어든다. */
.page-cards .ctabs { margin-bottom: 7px; }
.page-cards .cctl { margin-bottom: 12px; gap: 6px; }
.page-cards .ctab { padding: 5px 12px; font-size: 12.5px; }
.page-cards .cctl__sel, .page-cards .cctl__btn { padding: 5px 8px; font-size: 12px; }

/* 선택창 너비는 가장 긴 항목이 정한다. 잘라서 한 줄에 들어가게 한다 —
   고른 챕터는 어차피 카드 위 「어디서 온 카드인가」 줄에 다시 나온다. */
.page-cards .cctl__sel {
  max-width: 8.5em;
  text-overflow: ellipsis;
}
@media (min-width: 520px) { .page-cards .cctl__sel { max-width: 14em; } }

.page-cards .cmeta { margin-bottom: 6px; }
.page-cards .chint { margin-bottom: 6px; }
.page-cards .ckeys { margin-top: 8px; }
