/* motimoti — 박스 없는 편집 레이아웃.
   구조는 왼쪽 정렬축과 테라코타 룰이 만든다. 카드도 테두리도 쓰지 않는다.

   색 규칙
   - 순백(#fff)과 순흑(#000)은 쓰지 않는다. 눈부심과 과대비를 피하기 위해서다.
   - 본문·저자 등 글자는 배경 대비 4.5:1(WCAG AA) 이상을 지킨다.
     --accent 는 3.97:1 이라 글자에 쓰면 미달이므로, 글자와 테두리에는
     한 단계 진한 --accent-text(5.3:1)를 쓴다. --accent 는 룰과 하트 같은
     그래픽 전용이다(그래픽 기준 3:1, 통과).
   - 포인트 컬러는 하나뿐이고 작은 요소에만 쓴다. */

/* 토큰은 tokens.css 에 있다 (수집기와 공유). index.html 에서 먼저 불러온다. */


/* 베트남어는 라틴 문자라 영어와 같은 크기·자간을 쓴다. 성조 부호가 위아래로
   쌓여도 줄 간격 1.85 안에 들어간다(시험에서 잰다). */
html[lang="en"],
html[lang="vi"] {
  --tracking-btn: 0.1em;
  --tracking-meta: 0.05em;
  --quote-size: 22px;
}

* {
  box-sizing: border-box;
}

html, body {
  height: 100%;
  margin: 0;
}

/* 가로 스크롤은 어떤 경우에도 없다. html 에 걸면 화면(뷰포트)으로 올라가므로
   body 가 따로 스크롤 상자가 되지 않는다. .app 의 overflow-x: clip 이 1차로
   막고, 이것이 2차다 — iPhone 에서 1차가 새어 화면이 옆으로 밀린 채 남았다. */
html {
  overflow-x: hidden;
}

body {
  font-family: var(--font-kr);
  background: var(--bg);
  color: var(--ink);
  min-height: 100vh;
  min-height: 100dvh;
  -webkit-font-smoothing: antialiased;
}

.app {
  max-width: 480px;
  margin: 0 auto;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  padding: env(safe-area-inset-top) var(--pad) env(safe-area-inset-bottom);
  /* 책장 넘김의 낱장·그림자가 움직이며 화면 밖으로 잠깐 나간다. 그대로 두면
     휴대폰에서 가로 스크롤이 생겨 화면이 출렁인다. clip 은 스크롤 상자를
     만들지 않아서 세로 흐름에는 영향이 없다. */
  overflow-x: clip;
}

.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 28px 0 8px;
  margin-right: -10px;
}

/* 언어 전환 — 국기나 지구본 아이콘을 쓰지 않는다. 국기는 언어가 아니라
   국가를 뜻하고(영어는 어느 나라인가), 이 디자인은 자간 넓힌 타이포로
   구조를 만들기 때문에 그림이 하나 늘면 목소리가 깨진다.
   현재 언어만 --ink 로 올리고 나머지는 --ink-soft 로 둔다. */

.header-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.lang-toggle {
  display: flex;
  align-items: center;
  gap: 2px;
}

.lang-btn {
  border: none;
  background: none;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--ink-soft);
  cursor: pointer;
  padding: 15px 5px;   /* 글자는 작아도 터치 영역은 44px 를 넘긴다 */
  transition: color 0.15s ease;
}

.lang-btn.active {
  color: var(--ink);
}

/* 베타 표시 — 버튼 글자 옆에 작게. 자간을 물려받지 않게 0 으로 둔다. */
.beta-mark {
  font-size: 8px;
  letter-spacing: 0;
  margin-left: 1px;
  vertical-align: 5px;
  line-height: 0;
}

.lang-btn[hidden],
.lang-sep[hidden] {
  display: none;
}

.lang-sep {
  font-size: 12px;
  color: var(--ink-soft);
  opacity: 0.6;
}

.logo {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  margin: 0;
}

/* 스테이징 표시 — …/staging/ 에서만 로고 옆에 작게. 본 앱에는 보이지 않는다. */
.staging .logo::after {
  content: "STG";
  margin-left: 8px;
  padding: 1px 5px;
  border: 1px solid var(--accent-text);
  border-radius: var(--radius);
  font-size: 9px;
  letter-spacing: 0.12em;
  color: var(--accent-text);
  vertical-align: 2px;
}

.view {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* 룰 — 카드를 대신해 "여기서 시작"을 표시하는 유일한 앵커. */
.rule {
  width: 36px;
  height: 2px;
  background: var(--accent);
  flex: none;
}

/* ── 메인 ─────────────────────────────────────────────── */

#main-view {
  justify-content: flex-end;
}

.quote-block {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: 36px;
  /* 아래를 더 비워 명언을 중앙보다 위로 올린다.
     상하 대칭이면 정적이 되고, 비대칭이라야 긴장이 생긴다. */
  padding-bottom: 96px;
  transition: opacity 0.25s ease, transform 0.25s ease;
  /* 책장 넘김의 낱장(.sheet)이 이 안에 겹쳐 깔린다. */
  position: relative;
  isolation: isolate;
  touch-action: pan-y;   /* 세로 스크롤은 브라우저에, 가로 밀기는 넘김에 */
}

.quote-block.fade {
  opacity: 0;
  transform: translateY(8px);
}

/* ── 책장 넘김 (숨은 장치) ─────────────────────────────
   「다음」을 짧게 누르면 위의 페이드로 바뀐다. 길게 누르거나 명언을 왼쪽으로
   밀면 4~7장이 주르륵 넘어가다 멈춘다. 필수 기능이 아니라 즐거움이라서
   화면에 표시하지 않는다.

   3D 로 돌리지 않는다. 정면에서 본 책장처럼 책등(왼쪽) 쪽으로 좁아지며
   접힌다. 원근 왜곡이 있으면 이 박스 없는 평면 디자인에서 「3D 과제」처럼
   보인다(실제로 시험판에서 그랬다). 종이는 바탕과 같은 색이고, 경계는
   테두리 대신 책등의 접힘 그늘과 아래 쪽에 드리우는 그림자가 만든다. */
.sheet {
  position: absolute;
  top: 0;
  bottom: 0;
  /* 화면 가장자리까지 — 종이니까. .app 의 좌우 여백만큼 밖으로 낸다. */
  left: calc(var(--pad) * -1);
  right: calc(var(--pad) * -1);
  padding: 0 var(--pad) 96px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: 36px;
  background: var(--bg);
  transform-origin: left center;
  will-change: transform;
  /* 낱장이 탭을 받는다. 그대로 통과시키면 「멈추려고」 누른 탭이 아래에 깔린
     새 명언의 즐겨찾기·공유 버튼을 눌러 버린다. */
  pointer-events: auto;
}

.sheet .crease {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 28%;
  background: linear-gradient(90deg, var(--fold), transparent);
  opacity: 0.72;   /* 폭이 넓은 만큼 연하게 — 시험판에서 고른 28% 의 짝 */
}

.sheet .shade {
  position: absolute;
  inset: 0;
  background: var(--fold);
  opacity: 0;
}

.cast {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--pad) * -1);
  width: 44px;
  background: linear-gradient(90deg, var(--cast), transparent);
  opacity: 0;
  pointer-events: none;
  will-change: transform, opacity;
}

/* 반동: 쪽이 오른쪽으로 들릴 때 책등 쪽 틈에 생기는 그림자. 낱장의 왼쪽
   가장자리에 붙어 같이 움직이고, 틈(왼쪽)으로 갈수록 옅어진다. */
.cast.cast-lift {
  left: calc(var(--pad) * -1 - 22px);
  width: 22px;
  background: linear-gradient(270deg, var(--cast), transparent);
}

.quote-body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 26px;
}

.quote-text {
  /* --quote-fit 은 app.js 가 긴 명언일 때만 심는다. 없으면 CSS 가 정한
     기본 크기를 쓴다 — 대부분의 명언은 이 경로로 간다. */
  font-size: var(--quote-fit, var(--quote-size));
  font-weight: 400;
  line-height: 1.85;
  margin: 0;
  text-align: left;
  word-break: keep-all; /* 없으면 한글이 단어 중간에서 끊긴다. */
  text-wrap: pretty;
}

.quote-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
}

/* 작가 이름은 출처 쪽지를 여는 버튼이지만 겉으로는 글자 그대로다(숨은 장치).
   밑줄도 화살표도 없다. 누르는 자리만 위아래로 넓혀 둔다. */
.quote-author {
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  letter-spacing: var(--tracking-meta);
  text-align: left;
  border: none;
  background: none;
  padding: 12px 0;
  margin: -12px 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.quote-author:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 3px;
}

.quote-actions {
  display: flex;
  gap: 6px;
  margin-left: -10px;
}

/* ── 버튼 ─────────────────────────────────────────────── */

.icon-btn {
  width: 44px;
  height: 44px;
  border: none;
  background: none;
  padding: 0;
  color: var(--ink-soft);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.1s ease;
  /* 수집기 링크가 a 라서 필요하다. 버튼에는 영향이 없다. */
  text-decoration: none;
}

.icon-btn svg {
  width: 20px;
  height: 20px;
}

.app-header .icon-btn svg {
  width: 21px;
  height: 21px;
}

.icon-btn:active {
  transform: scale(0.92);
}

.heart-icon {
  fill: none;
}

.icon-btn.active {
  color: var(--accent);
}

.icon-btn.active .heart-icon {
  fill: var(--accent);
}

.primary-btn {
  width: 100%;
  height: 56px;
  border: 1.5px solid var(--accent-text);
  border-radius: var(--radius);
  background: none;
  color: var(--accent-text);
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: var(--tracking-btn);
  text-indent: var(--tracking-btn); /* 자간이 만든 오른쪽 여백만큼 되민다. */
  cursor: pointer;
  margin-bottom: 40px;
  transition: transform 0.1s ease, opacity 0.15s ease;
  /* 길게 누르기가 책장 넘김이다. 휴대폰의 글자 선택·확대·메뉴를 막는다. */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  touch-action: manipulation;
}

.primary-btn:active {
  transform: scale(0.98);
  opacity: 0.75;
}

/* ── 즐겨찾기 ─────────────────────────────────────────── */

#favorites-view {
  padding-bottom: 32px;
}

.favorites-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 28px 0 4px;
}

.favorites-header-left {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: -10px;
}

.favorites-header h2 {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  margin: 0;
}

.favorites-count-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-top: 18px;
}

.favorites-count {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  letter-spacing: 0.14em;
  margin: 0;
}

/* 켬/끔을 스위치 모양 대신 글자 색과 점 하나로 보인다. 꺼지면 점이 빈 원이 된다. */
.weight-btn {
  margin-left: auto;
  border: none;
  background: none;
  font-family: inherit;
  font-size: 12px;
  letter-spacing: 0.12em;
  color: var(--ink-soft);
  cursor: pointer;
  padding: 12px 0 12px 10px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: color 0.15s ease;
}

.weight-btn::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  border: 1px solid currentColor;
  box-sizing: border-box;
}

.weight-btn.active {
  color: var(--ink);
}

.weight-btn.active::before {
  background: currentColor;
}

/* 박스 대신 얇은 선과 여백으로 항목을 나눈다. 인쇄물 색인의 방식이다. */
.favorites-list {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}

.favorite-item {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 26px 0 10px;
}

.favorite-item + .favorite-item {
  border-top: 1px solid var(--hairline);
}

.favorite-item-text {
  font-size: 16px;
  line-height: 1.75;
  margin: 0;
  word-break: keep-all;
  text-wrap: pretty;
}

.favorite-item-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: -10px -10px -10px 0;
}

.favorite-item-author {
  font-family: inherit;
  text-align: left;
  border: none;
  background: none;
  -webkit-tap-highlight-color: transparent;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  letter-spacing: var(--tracking-meta);
  margin: 0;
  padding: 10px 0;
}

button.favorite-item-author {
  cursor: pointer;
}

button.favorite-item-author:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 3px;
}

.remove-btn {
  border: none;
  background: none;
  font-family: inherit;
  font-size: 12px;
  color: var(--ink-soft);
  letter-spacing: 0.12em;
  cursor: pointer;
  padding: 12px 10px;
}

.favorites-empty {
  font-size: 14px;
  color: var(--ink-soft);
  letter-spacing: 0.02em;
  margin-top: 48px;
}

/* ── 토스트 ───────────────────────────────────────────── */

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(32px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  background: var(--toast-bg);
  color: var(--toast-ink);
  padding: 12px 20px;
  border-radius: var(--radius);
  font-family: var(--font-kr);
  font-size: 13px;
  letter-spacing: 0.06em;
  /* 베타 안내처럼 긴 문구는 줄을 바꾼다. 좁은 화면에서도 양옆 16px 을 남긴다. */
  width: max-content;
  max-width: calc(100vw - 32px);
  text-align: center;
  word-break: keep-all;   /* 한글이 낱자로 끊기지 않게 */
  text-wrap: balance;     /* 두 줄이면 길이를 고르게 */
  transition: opacity 0.2s ease;
  z-index: 10;
}

.toast.hidden {
  display: block; /* .hidden 의 display:none 을 되돌리고 페이드로 숨긴다. */
  opacity: 0;
  pointer-events: none;
}

/* ── 출처 쪽지 ────────────────────────────────────────
   작가 이름을 누르면 아래에서 올라온다. 명언이 나온 책·편지·연설을 적은
   쪽지다 — 종류와 연도, 출처, 원문, 그리고 원전으로 가는 링크. */
.note-veil {
  position: fixed;
  inset: 0;
  background: var(--veil);
  opacity: 0;
  transition: opacity 0.25s ease;
  z-index: 20;
}

.note-veil.on {
  opacity: 1;
}

.source-note {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 21;
  max-width: 480px;
  margin: 0 auto;
  max-height: 78vh;
  max-height: 78dvh;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--paper);
  border-radius: 10px 10px 0 0;
  box-shadow: 0 -8px 30px var(--note-shadow);
  padding: 10px var(--pad) calc(32px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  transform: translateY(105%);
  transition: transform 0.32s cubic-bezier(0.2, 0.8, 0.2, 1);
  outline: none;
}

.source-note.on {
  transform: none;
}

/* 닫힘 — 열림의 거울상이 아니라 무게를 받아 빨라지며 떨어진다(0.24초).
   손가락으로 끌어내렸다 놓으면 app.js 가 그 속도에 맞춰 시간을 다시 정한다. */
.source-note:not(.on) {
  transition: transform 0.24s cubic-bezier(0.4, 0, 1, 1);
}

.note-veil:not(.on) {
  transition: opacity 0.24s linear;
}

.note-veil[hidden],
.source-note[hidden],
.source-note [hidden] {
  display: none;
}

.note-grip {
  align-self: center;
  width: 36px;
  height: 4px;
  border-radius: 2px;
  background: var(--hairline);
  margin-bottom: 6px;
}

.note-kind {
  margin: 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.16em;
  /* 대문자로 바꾸지 않는다 — 「c. 450 BC」 의 c. 가 「C.」 가 된다. */
  color: var(--accent-text);
}

.note-title {
  margin: 0;
  font-size: 17px;
  line-height: 1.6;
  word-break: keep-all;
  text-wrap: pretty;
}

/* 이 문장이 나온 자리 — 쪽지에서 가장 긴 글이라 본문 크기로, 줄 간격을 넉넉히. */
.note-context p {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.85;
  word-break: keep-all;
  text-wrap: pretty;
}

.note-orig {
  margin: 0;
  padding-left: 14px;
  border-left: 2px solid var(--hairline);
  font-size: 15px;
  line-height: 1.8;
  word-break: keep-all;
}

.note-orig-label {
  display: block;
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--ink-soft);
  margin-bottom: 2px;
}

.note-line {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--ink-soft);
  word-break: keep-all;
}

.note-link {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  padding-block: 6px;
  color: var(--accent-text);
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.04em;
}

.note-link:hover .note-link-label {
  text-decoration: underline;
  text-underline-offset: 4px;
}

.note-link:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 3px;
}

.note-host {
  font-size: 11.5px;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}

/* ── 판권면 ───────────────────────────────────────────
   즐겨찾기 화면 맨 아래 「이 책에 대하여」. 책의 맨 뒤 한 쪽처럼 모토와
   이 책에 실린 것, 고른 기준, 번역, 엮은이, 펴낸 날을 적는다. 숫자는
   앱이 데이터에서 센다. 종이는 출처 쪽지(.source-note)와 같다. */
.about-btn {
  flex: none;
  width: 100%;
  text-align: left;
  border: none;
  border-top: 1px solid var(--hairline);
  background: none;
  font-family: inherit;
  font-size: 12px;
  letter-spacing: 0.12em;
  color: var(--ink-soft);
  cursor: pointer;
  padding: 18px 0 12px;
  /* 목록이 짧거나 비어도 화면 맨 아래 — 책의 맨 뒤 자리다. */
  margin-top: auto;
}

.about-btn:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 3px;
}

.source-note.colophon {
  max-height: 88vh;
  max-height: 88dvh;
  gap: 28px;
  align-items: stretch;
}

.colophon .note-grip {
  margin-bottom: 0;
}

.colophon-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 18px;
}

.colophon-title {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  margin: 0;
}

.colophon-motto {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.colophon-motto p {
  margin: 0;
}

.colophon-motto-orig {
  font-size: 22px;
  letter-spacing: 0.12em;
}

.colophon-motto-tr {
  font-size: 15px;
  line-height: 1.7;
  word-break: keep-all;
}

.colophon-motto-src {
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}

.colophon-text {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.colophon-text p {
  margin: 0;
  font-size: 14px;
  line-height: 1.85;
  word-break: keep-all;
  text-wrap: pretty;
}

/* 이름과 값이 맞선 두 줄 표 — 인쇄된 판권면의 방식이다. */
.colophon-table {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 10px 18px;
  margin: 0;
  padding-top: 22px;
  border-top: 1px solid var(--hairline);
  font-size: 12.5px;
  line-height: 1.7;
}

.colophon-table dt {
  color: var(--ink-soft);
  letter-spacing: 0.08em;
  white-space: nowrap;
}

.colophon-table dd {
  margin: 0;
  min-width: 0;
  word-break: keep-all;
  font-variant-numeric: tabular-nums;
}

.colophon-sub {
  display: block;
  font-size: 11.5px;
  color: var(--ink-soft);
}

/* ── 좁은 화면 ────────────────────────────────────────── */

@media (max-width: 359px) {
  :root {
    --pad: 22px;
    --quote-size: 20px;
  }

  /* 언어 버튼이 셋이라 로고와 붙는다. 버튼 사이만 좁힌다 — 터치 높이는 그대로. */
  .lang-btn {
    padding-left: 3px;
    padding-right: 3px;
  }

  .lang-toggle {
    gap: 0;
  }

  /* html[lang="en"] 이 :root 보다 특정도가 높으므로 여기서도 따로 덮는다. */
  html[lang="en"],
  html[lang="vi"] {
    --quote-size: 21px;
  }
}

@media (min-width: 600px) {
  :root {
    --quote-size: 23px;
  }

  html[lang="en"],
  html[lang="vi"] {
    --quote-size: 24px;
  }

  .app-header {
    padding-top: 40px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .quote-block,
  .icon-btn,
  .primary-btn,
  .toast,
  .note-veil,
  .note-veil:not(.on),
  .source-note,
  .source-note:not(.on) {
    transition: none;
  }
}

/* ── 유틸리티 ─────────────────────────────────────────────
   .hidden 은 반드시 파일 맨 끝에 둔다. 특정도가 같은 컴포넌트 규칙
   (.favorites-count-row 의 display:flex 등)을 소스 순서로 이겨야 하기 때문이다.
   .toast.hidden 은 특정도가 더 높아 순서와 무관하게 이 규칙을 덮는다. */

.hidden {
  display: none;
}
