/*
 * 展示頁的樣式。
 *
 * 刻意留在一個檔案、不用任何預處理器或框架——這一頁要示範的是「frond
 * 不需要建置流程」，而一份需要編譯的樣式表會讓那句話變得只有一半是真的。
 */

:root {
  color-scheme: light dark;

  --ink: #1c1e21;
  --ink-soft: #5c6169;
  --paper: #fbfaf8;
  --panel: #ffffff;
  --line: #e2ddd5;
  --accent: #2f6b4f;
  --danger: #a4362c;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #dfe1e4;
    --ink-soft: #9aa1ab;
    --paper: #14161a;
    --panel: #1b1e23;
    --line: #2e333a;
    --accent: #6fbf95;
    --danger: #e0796d;
  }
}

* {
  box-sizing: border-box;
}

/*
 * `hidden` 屬性要真的藏得住。
 *
 * UA 樣式表給 `[hidden]` 的是 `display: none`，但那條規則的優先權極低——這份
 * 檔案裡任何一條 id 或 class 選擇器的 `display` 都蓋得過它。於是
 * `element.hidden = true` 變成什麼都沒發生，而 JavaScript 那一側看起來完全正常。
 *
 * 這正是它在這裡的理由：整頁的顯示切換（開書前後、兩個分頁）都靠 `hidden`。
 */
[hidden] {
  display: none !important;
}

body {
  margin: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  color: var(--ink);
  font-family: system-ui, "Noto Sans CJK TC", "Noto Sans TC", sans-serif;
  line-height: 1.7;
}

a {
  color: var(--accent);
}

code,
pre {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85em;
}

/* --- 頁首 ---------------------------------------------------------------- */

.masthead {
  padding: 2rem 1.5rem 1.25rem;
  border-bottom: 1px solid var(--line);
}

.masthead h1 {
  margin: 0;
  font-size: 1.9rem;
  letter-spacing: 0.02em;
}

.tagline {
  margin: 0.4rem 0 0;
  max-width: 46rem;
  color: var(--ink-soft);
}

.masthead-links {
  margin-top: 0.6rem;
  display: flex;
  gap: 1rem;
  font-size: 0.9rem;
}

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

/* --- 開書之前 ------------------------------------------------------------ */

#intro {
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

.dropzone {
  border: 2px dashed var(--line);
  border-radius: 12px;
  padding: 3rem 1.5rem;
  text-align: center;
  transition: border-color 0.15s, background 0.15s;
}

.dropzone.is-hovered {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

.dropzone-headline {
  margin: 0;
  font-size: 1.3rem;
}

.dropzone-sub {
  margin: 0.5rem 0;
  color: var(--ink-soft);
  font-size: 0.9rem;
}

.file-button {
  display: inline-block;
  padding: 0.5rem 1.1rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel);
  cursor: pointer;
  font-size: 0.95rem;
}

.file-button:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.file-button.small {
  padding: 0.25rem 0.8rem;
  font-size: 0.85rem;
}

.file-button input {
  /* 視覺上藏起來，但保留在無障礙樹裡——鍵盤使用者要 tab 得到它。 */
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.intro-columns {
  display: grid;
  gap: 2rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr));
}

.intro-columns h2 {
  font-size: 1.05rem;
  margin: 0 0 0.6rem;
}

.intro-columns ul {
  margin: 0;
  padding-left: 1.1rem;
}

.intro-columns li + li {
  margin-top: 0.5rem;
}

.note {
  color: var(--ink-soft);
  font-size: 0.88rem;
}

pre {
  overflow-x: auto;
  padding: 1rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  line-height: 1.55;
}

/* --- 開書之後 ------------------------------------------------------------ */

#workspace {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.workspace-bar {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.6rem 1rem;
  border-bottom: 1px solid var(--line);
}

.tabs {
  display: flex;
  gap: 0.25rem;
}

.tab {
  padding: 0.3rem 0.9rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background: none;
  color: var(--ink-soft);
  cursor: pointer;
  font: inherit;
  font-size: 0.9rem;
}

.tab[aria-selected="true"] {
  border-color: var(--line);
  background: var(--panel);
  color: var(--ink);
}

.book-title {
  flex: 1;
  /* 分隔線是必要的，不是裝飾：書名緊接在兩個分頁按鈕後面時，看起來像第三個
     分頁。截圖上一眼就看得出來（`讀 檢查 渡口`）。 */
  margin: 0;
  padding-left: 1rem;
  border-left: 1px solid var(--line);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink-soft);
  font-size: 0.9rem;
}

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

.toolbar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.6rem 1rem;
  border-bottom: 1px solid var(--line);
  font-size: 0.85rem;
}

.toolbar-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
}

.toolbar label {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--ink-soft);
}

.toolbar input[type="range"] {
  width: 6.5rem;
}

.toolbar button,
.toolbar select {
  padding: 0.25rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel);
  color: inherit;
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}

.toolbar button:disabled,
.toolbar select:disabled {
  opacity: 0.4;
  cursor: default;
}

#toc {
  max-width: 16rem;
}

/*
 * 渲染的容器。
 *
 * frond 要的只有一件事：一個有大小的元素。它會把自己的 iframe 絕對定位進來，
 * 所以容器如果是 `position: static`，frond 會暫時改成 `relative` 並在
 * `destroy()` 時還原。高度必須由這一層給——內容在 iframe 裡，撐不起父層。
 *
 * ## 為什麼書框不直接填滿剩下的空間
 *
 * 填滿的版本在寬螢幕上會排出一個 1400×600 的「頁」——那個比例不存在於任何一本
 * 實體書上，而讀者對「這是一本書」的判斷有一半來自比例。所以這裡改成先把空間
 * 量出來，再從裡面切一個書的比例出來，剩下的留白。
 *
 * 兩種比例，對應書的兩種看法：
 *
 *   - **單頁** 0.7（1:1.43）——A5 是 0.707、常見平裝本 6×9in 是 0.667，落在中間。
 *   - **攤開** 1.4——就是兩個單頁並排，實體書打開來的樣子。
 *
 * ## 比例怎麼量
 *
 * `.viewer-frame` 宣告成 size container，`#viewer` 於是能用 `cqw`/`cqh` 讀到它
 * 的內距框，兩個方向各取 min 就得到「塞得進去的最大的那個書的比例」。用容器而
 * 不是 `dvh` 算，是因為上面還有頁首、工作列、工具列，狀態列還會在窄螢幕上折行
 * ——那幾層的高度沒有一個常數答案。
 *
 * 換成 `aspect-ratio` 加 `max-width` 是不行的：其中一邊被 max-* 夾住的時候，
 * 另一邊不會跟著回推，比例就破了。所以這裡兩個方向都自己算。
 */
.viewer-frame {
  flex: 1;
  /* 視窗很矮時仍留一個底線；書框會小到讀不了，但至少還在。 */
  min-height: 18rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(0.5rem, 1.5vw, 1.25rem);
  container-type: size;
}

.viewer {
  --page-ratio: 0.7;
  flex: none;
  width: min(100cqw, calc(100cqh * var(--page-ratio)));
  height: min(100cqh, calc(100cqw / var(--page-ratio)));
  border: 1px solid var(--line);
  border-radius: 6px;
  /* 書還沒排出來的那一瞬間、以及邊界設得很大時，露出來的是這一層。 */
  background: var(--panel);
  box-shadow: 0 2px 14px rgb(0 0 0 / 0.14);
  /* iframe 是絕對定位的方角，圓角要靠這一層裁。 */
  overflow: hidden;
}

/*
 * 攤開。
 *
 * 判準只有一條，而且它同時是「哪一種比較大」的答案：**容器比攤開還寬的時候用
 * 攤開**。
 *
 * 容器寬於 1.4 時，攤開被高度卡住——它填滿高度，寬度是高度 × 1.4。同一塊空間裡
 * 的單頁也是被高度卡住的，寬度只有高度 × 0.7，剛好一半。所以在寬容器裡攤開一定
 * 比單頁大，沒有例外，也就不需要再補一條「太矮就改單頁」的門檻。反過來，容器比
 * 1.4 瘦（豎著拿的平板、手機）時攤開會被寬度卡住，只用掉一半多一點的高度，那時
 * 單頁才是大的那一個。
 *
 * 這條線與欄數是分開的兩件事：`columns: "auto"` 看的是行內軸有沒有 700px
 * （`src/renderer/geometry.ts` 的 `TWO_COLUMN_MIN_INLINE_SIZE`），換算過來是書框
 * 高 500px。矮於這個值的攤開是「攤開的形狀、一欄的內容」——那是行長的判斷，讀者
 * 要雙欄的話工具列上就有。
 */
@container (min-aspect-ratio: 7 / 5) {
  .viewer {
    --page-ratio: 1.4;
  }
}

.statusbar {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  padding: 0.5rem 1rem;
  border-top: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 0.82rem;
}

.statusbar code {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.error {
  margin: 0;
  padding: 0.6rem 1rem;
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  color: var(--danger);
  font-size: 0.88rem;
}

/* --- 檢查 ---------------------------------------------------------------- */

#panel-inspect {
  overflow-y: auto;
  padding: 1.25rem 1.5rem 3rem;
}

.facts {
  display: grid;
  grid-template-columns: minmax(8rem, max-content) 1fr;
  gap: 0.4rem 1.5rem;
  margin: 1rem 0 0;
  font-size: 0.9rem;
}

.facts dt {
  color: var(--ink-soft);
}

.facts dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.cover {
  max-width: 150px;
  max-height: 220px;
  margin-top: 1rem;
  border: 1px solid var(--line);
  border-radius: 4px;
}

/* --- 開書之後，頁面自己讓位 ---------------------------------------------- */

/*
 * 書框的大小由**高度**決定（見 `.viewer-frame`），所以頁首與頁尾每多佔一點
 * 高度，書就整個小一圈——手機上那是「書變窄」而不是「上下多一條白」，因為窄
 * 螢幕上寬度早就用滿了，只剩高度在收。開書之後這些東西就不再是主角了。
 *
 * 用 `:has()` 而不是在 app.js 掛一個 class：這條規則只跟版面有關，讓它整條留在
 * 樣式表裡，app.js 就不必知道它存在。條件寫成「工作區沒被藏起來」，跟
 * `openBook()` 切的是同一個開關。
 */
/*
 * 讀書的時候整個頁面就是一個視窗大小的殼，不捲動。
 *
 * `min-height` 與 `height` 在這裡不是同一件事：`min-height` 之下 body 的高度仍
 * 由內容決定（至少一個視窗高），於是往下每一層 flex 的高度都是「先量內容再拉
 * 開」——而 `.viewer-frame` 有 size containment，內容量出來是 0。結果是 `100cqh`
 * 解析成 0，書框整個塌掉。給一個確定的高度，這條鏈才有定值可分。
 *
 * 開書之前照舊：那一頁是文件，內容比視窗長的時候要捲得動。
 */
body:has(#workspace:not([hidden])) {
  height: 100dvh;
  /* `hidden` 會在視窗矮到書框撞上自己的 min-height 時，把狀態列直接裁掉且捲不
     回來。`auto` 只有在真的塞不下時才長出捲軸，其餘時間看起來一樣。 */
  overflow: auto;
}

body:has(#workspace:not([hidden])) .masthead {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 1rem;
  padding: 0.5rem 1rem;
}

body:has(#workspace:not([hidden])) .masthead h1 {
  font-size: 1.15rem;
}

body:has(#workspace:not([hidden])) .masthead-links {
  margin-top: 0;
  font-size: 0.85rem;
}

/* 標語與頁尾在讀書的時候沒有讀者要的資訊，而它們合起來要走三到四行的高度。 */
body:has(#workspace:not([hidden])) .tagline,
body:has(#workspace:not([hidden])) .colophon {
  display: none;
}

/*
 * 窄螢幕上再收一次。
 *
 * 手機上工具列會折成四五行——量到的是 390×844 上 178px，接近整個視窗的四分之一，
 * 而那些高度全是從書上扣的。這裡只動間距、字級與滑桿寬度，**不藏任何一個控制項**：
 * 這一頁的用途就是把 frond 的旋鈕全攤出來給人轉，橫向捲動或收進選單都會讓其中
 * 幾個變成沒人找得到。收完之後書在 390 寬的螢幕上正好用滿寬度。
 */
@media (max-width: 48rem) {
  body:has(#workspace:not([hidden])) .masthead {
    padding: 0.35rem 0.9rem;
  }

  body:has(#workspace:not([hidden])) .masthead h1 {
    font-size: 1rem;
  }

  .workspace-bar {
    gap: 0.6rem;
    padding: 0.4rem 0.75rem;
  }

  .toolbar {
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    font-size: 0.8rem;
  }

  .toolbar-group {
    gap: 0.5rem;
  }

  .toolbar input[type="range"] {
    width: 5rem;
  }

  .statusbar {
    gap: 0.35rem 0.9rem;
    padding: 0.4rem 0.75rem;
    font-size: 0.78rem;
  }
}

/* --- 頁尾 ---------------------------------------------------------------- */

.colophon {
  padding: 1rem 1.5rem;
  border-top: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 0.82rem;
}

.colophon p {
  margin: 0;
}
