/* Visual language shared with taigikeyboard.tw/taigi-converter: #f5f5f7 page, white 18px
   cards, Iansui by default (jf-openhuninn selectable), hairline rows with grey labels, #0071e3 focus ring. */
@font-face {
  font-family: "jf-openhuninn";
  /* local(): a reader who installed the font skips the download (full name, then PostScript name) */
  src: local("jf-openhuninn-2.1"), url("fonts/jf-openhuninn-2.1.ttf") format("truetype");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
  /* CJK, bopomofo and fullwidth punctuation only: the font's combining tone marks
     misplace (tsi̍t renders as tsit), so romanization falls through to the system font */
  unicode-range: U+3000-303F, U+3100-312F, U+31A0-31BF, U+3400-4DBF, U+4E00-9FFF,
    U+F900-FAFF, U+FF00-FFEF, U+20000-2FFFF;
}
/* settings-panel typefaces (taigikeyboard's roster), same CJK-only range: an installed copy
   (local()) is the full font, so the range is what keeps romanization in the system font;
   scripts/subset-fonts.sh cuts the web files to it. A browser fetches one only once it is in use (Iansui is the default). */
@font-face {
  font-family: "Iansui";
  src: local("Iansui Regular"), local("Iansui-Regular"), url("fonts/iansui_regular.woff2") format("woff2");
  font-display: swap;
  unicode-range: U+3000-303F, U+3100-312F, U+31A0-31BF, U+3400-4DBF, U+4E00-9FFF,
    U+F900-FAFF, U+FF00-FFEF, U+20000-2FFFF;
}
@font-face {
  font-family: "GenYoMin2 TW";
  src: local("GenYoMin2 TW R"), local("GenYoMin2TW-R"), url("fonts/genyomin2tw_r.woff2") format("woff2");
  font-display: swap;
  unicode-range: U+3000-303F, U+3100-312F, U+31A0-31BF, U+3400-4DBF, U+4E00-9FFF,
    U+F900-FAFF, U+FF00-FFEF, U+20000-2FFFF;
}
@font-face {
  font-family: "GenYoGothic2 TW";
  src: local("GenYoGothic2 TW R"), local("GenYoGothic2TW-R"), url("fonts/genyogothic2tw_r.woff2") format("woff2");
  font-display: swap;
  unicode-range: U+3000-303F, U+3100-312F, U+31A0-31BF, U+3400-4DBF, U+4E00-9FFF,
    U+F900-FAFF, U+FF00-FFEF, U+20000-2FFFF;
}

/* Follows the system theme unless the sidebar's 外觀 pins one via <html data-theme> ("auto" pins none). */
:root { color-scheme: light dark; }
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

:root {
  --bg: light-dark(#f5f5f7, #000000);
  --card: light-dark(#ffffff, #1c1c1e);
  --text: light-dark(#1d1d1f, #f5f5f7);
  /* light grey is apple.com's #6e6e73: 5.1:1 on white, 4.7:1 on #f5f5f7 (WCAG AA for small text) */
  --secondary: light-dark(#6e6e73, #98989d);
  --border: light-dark(#d2d2d7, #3a3a3c);
  --field: light-dark(#fafafa, #2c2c2e);
  --hairline: light-dark(#e8e8ed, #38383a);
  --hover: light-dark(#f5f5f7, #2c2c2e);
  --accent: light-dark(#0071e3, #2997ff);
  --ring: light-dark(rgba(0, 113, 227, 0.15), rgba(41, 151, 255, 0.25));
  --card-shadow: 0 1px 3px light-dark(rgba(0, 0, 0, 0.04), transparent),
    0 4px 12px light-dark(rgba(0, 0, 0, 0.03), transparent);
  --menu-shadow: 0 4px 24px light-dark(rgba(0, 0, 0, 0.08), rgba(0, 0, 0, 0.5));

  --system-font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
    "Helvetica Neue", Helvetica, "PingFang TC", "Noto Sans TC", Arial, sans-serif;
  --font: "Iansui", var(--system-font);
  --measure: 760px;
  /* Starlight's sidebar width */
  --sidebar-width: 18.75rem;
}

/* --- display settings (src/settings.js sets these <html> attributes) --- */
:root[data-font="system"] { --font: var(--system-font); }
:root[data-font="openhuninn"] { --font: "jf-openhuninn", var(--system-font); }
:root[data-font="genyomin"] { --font: "GenYoMin2 TW", var(--system-font); }
:root[data-font="genyogothic"] { --font: "GenYoGothic2 TW", var(--system-font); }
:root[data-poj="off"] .poj, :root[data-tps="off"] .tps { display: none; }
/* 選單顯示: dropdown-only display switches (src/index.html); 語音差異 / 詞彙比較 / 異用字 hints
   have none: a row opens a headword that differs from the typed form, so its hint always shows */
:root[data-suggest-gloss="off"] .suggest .row-gloss,
:root[data-suggest-reading="off"] .suggest .row-via.reading { display: none; }

* { box-sizing: border-box; }

/* reserve the scrollbar so long pages don't shift the centered layout sideways */
html { -webkit-text-size-adjust: 100%; scrollbar-gutter: stable; }

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 4rem 1.5rem 2rem;
  background: var(--bg);
  color: var(--text);
  /* 17px at the browser default; text sizes are rem, so the browser's own font-size
     setting scales the page */
  font: 1.0625rem/1.65 var(--font);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* --- round 36px icon buttons: corner + sidebar buttons, word-audio play, entry actions, retry --- */
.corner-button, .play, .entry-action, .retry {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  transition: color 0.2s, background 0.2s;
}
.corner-button:hover, .play:hover, .entry-action:hover, .retry:hover { background: var(--hover); }
.corner-button:focus-visible, .play:focus-visible, .entry-action:focus-visible, .retry:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--ring); }

.corner-button { color: var(--secondary); }
.corner-button:hover { color: var(--text); }
.corner-button svg { width: 18px; height: 18px; }

/* --- sidebar toggle (top left) --- */
.sidebar-toggle { position: fixed; top: 0.75rem; left: 0.75rem; z-index: 20; }

/* --- left sidebar: page-coloured with a hairline edge, holding an inset grouped card like macOS
   System Settings. Wide screens dock it beside the page and the corner button slides it away;
   narrow ones open it as a popover sliding over a dimmed page. --- */
.sidebar {
  inset: 0 auto 0 0;
  width: min(var(--sidebar-width), 85vw);
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 1rem 1.5rem 1.5rem;
  overflow-y: auto;
  border: 0;
  border-right: 1px solid var(--hairline);
  background: var(--bg);
  color: var(--text);
  box-shadow: var(--menu-shadow);
  transform: translateX(-100%);
  transition: transform 0.25s ease, overlay 0.25s allow-discrete, display 0.25s allow-discrete;
}
.sidebar:popover-open { transform: none; }
@starting-style { .sidebar:popover-open { transform: translateX(-100%); } }
.sidebar::backdrop { background: rgba(0, 0, 0, 0.3); }
.sidebar-close { display: flex; justify-content: flex-end; margin: -0.25rem -0.5rem 0 0; }
@media (min-width: 50rem) {
  /* docked, collapsed by default: slid out left and hidden (its controls leave the tab order);
     display: block overrides the UA's display: none for a closed popover so it can slide;
     top padding clears the toggle */
  .sidebar {
    position: fixed;
    display: block;
    padding-top: 3.5rem;
    box-shadow: none;
    visibility: hidden;
    transition: transform 0.25s ease, visibility 0.25s;
  }
  .sidebar-close { display: none; }
  body { transition: padding-left 0.25s ease; }
  /* opened with the toggle: slides in and the page makes room */
  :root[data-sidebar="open"] .sidebar { transform: none; visibility: visible; }
  :root[data-sidebar="open"] body { padding-left: calc(var(--sidebar-width) + 1.5rem); }
}


/* 收藏 rows: hanzi + grey reading, one line each; hover and the open entry get a soft highlight */
.bookmarks { margin: 1.5rem -0.5rem 0; }
.bookmark {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.375rem 0.5rem;
  border-radius: 8px;
  color: var(--text);
  font-size: 0.9375rem;
}
.bookmark:hover { background: var(--hairline); text-decoration: none; }
.bookmark[aria-current="page"] { background: var(--hairline); }
.bookmark-hanzi { flex: none; max-width: 60%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.bookmark-tl {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--secondary);
  font-size: 0.875rem;
}

/* settings rows sit straight on the sidebar: label left, control right, hairlines between */
.setting {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 2.75rem;
  font-size: 0.9375rem;
}
.setting + .setting { border-top: 1px solid var(--hairline); }
.settings-heading { margin-top: 1.25rem; padding-bottom: 0.25rem; color: var(--secondary); font-size: 0.8125rem; }
/* borderless pop-up value with a small chevron, like a macOS settings row */
.setting select {
  padding: 0.25rem 1.125rem 0.25rem 0.25rem;
  border: 0;
  border-radius: 6px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Cpath d='M2.5 4l2.5 2.5L7.5 4' fill='none' stroke='%236e6e73' stroke-width='1.3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") right center / 10px no-repeat;
  color: var(--secondary);
  font: inherit;
  text-align: right;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.setting select:hover { color: var(--text); }
.setting select:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--ring); }
/* iOS-style switch */
.setting input[type="checkbox"] {
  position: relative;
  flex: none;
  width: 44px;
  height: 26px;
  margin: 0;
  border-radius: 13px;
  background: var(--border);
  cursor: pointer;
  transition: background 0.2s;
  -webkit-appearance: none;
  appearance: none;
}
.setting input[type="checkbox"]::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--card);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
  transition: transform 0.2s;
}
/* monochrome when on: the page keeps blue for links */
.setting input[type="checkbox"]:checked { background: var(--text); }
.setting input[type="checkbox"]:checked::before { transform: translateX(18px); }
.setting input[type="checkbox"]:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--ring); }

/* --- title + search --- */
.masthead {
  width: 100%;
  max-width: var(--measure);
  display: flex;
  flex-direction: column;
  align-items: center;
}

h1 {
  margin: 0;
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.2;
}
.wordmark { color: var(--text); }
.wordmark:hover { text-decoration: none; }

.search {
  position: relative;
  width: 100%;
  margin-top: 1.75rem;
}
.search-icon {
  position: absolute;
  left: 1rem;
  top: 50%;
  width: 15px;
  height: 15px;
  transform: translateY(-50%);
  color: var(--secondary);
  pointer-events: none;
}
.search input {
  width: 100%;
  height: 44px;
  padding: 0 1rem 0 2.6rem;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--field);
  color: var(--text);
  font: inherit;
  outline: none;
  transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;
  -webkit-appearance: none;
  appearance: none;
}
.search input:focus {
  border-color: var(--accent);
  background: var(--card);
  box-shadow: 0 0 0 3px var(--ring);
}
.search input::-webkit-search-cancel-button { display: none; }
/* overlay hint for the "/" shortcut (main.js); a placeholder can't draw the <kbd> box, so #q keeps a blank
   placeholder only to drive :placeholder-shown. Touch devices have no key to press. */
.search-hint {
  position: absolute;
  left: 2.6rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--secondary);
  pointer-events: none;
}
.search-hint kbd {
  display: inline-block;
  min-width: 1.25rem;
  padding: 0 0.3rem;
  border: 1px solid var(--border);
  border-radius: 5px;
  font: 0.8125rem/1.4 var(--system-font);
  text-align: center;
}
.search input:not(:placeholder-shown) ~ .search-hint { display: none; }
@media not ((hover: hover) and (pointer: fine)) {
  .search-hint { display: none; }
}

/* --- suggestion dropdown --- */
.suggest {
  position: absolute;
  z-index: 10;
  left: 0;
  right: 0;
  top: calc(100% + 8px);
  max-height: 420px; /* suggest.js narrows it to the viewport space below */
  overflow-y: auto;
  padding: 0.375rem;
  border: 1px solid var(--hairline);
  border-radius: 12px;
  background: var(--card);
  box-shadow: var(--menu-shadow);
}

/* shared row layout: dropdown options + full result list */
.row {
  display: flex;
  flex-wrap: wrap; /* long readings + 方音符號 move to a second line on phones */
  align-items: baseline;
  gap: 0.25rem 1rem;
  padding: 0.5rem 0.75rem;
  border-radius: 8px;
  color: var(--text);
  transition: background 0.15s;
}
.row:hover { text-decoration: none; }
.row.active, .results .row:hover { background: var(--hover); }
.row-hanzi { overflow-wrap: anywhere; }
.row-roman { color: var(--secondary); font-size: 0.9375rem; overflow-wrap: anywhere; }
/* match hint (bôr): why a row turned up for the typed form */
.row-via { flex: 0 1 auto; min-width: 0; overflow: hidden; color: var(--secondary); font-size: 0.8125rem; white-space: nowrap; text-overflow: ellipsis; }
.row-via .poj, .row-via .tps { margin-left: 0.375em; }
/* one line, cut with …; wraps to its own line when under 8em is left */
.row-gloss {
  flex: 1 1 8em;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--secondary);
  font-size: 0.875rem;
}
/* sets the 華語釋義 apart from a 詞彙比較 hint's hanzi right before it (尪仔冊 ang-á-tsheh | 漫畫書) */
.row-gloss::before { content: "| "; }

/* --- content card --- */
.card {
  width: 100%;
  max-width: var(--measure);
  margin-top: 1.5rem;
  padding: 1.75rem;
  border-radius: 18px;
  background: var(--card);
  box-shadow: var(--card-shadow);
}
.card:empty { display: none; }

.status { display: flex; align-items: center; justify-content: center; gap: 0.25rem; margin: 0; color: var(--secondary); }
.retry { color: var(--accent); }
.retry svg { width: 20px; height: 20px; }

.loading {
  width: 28px;
  height: 28px;
  margin: 0 auto;
  border: 3px solid var(--hairline);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
/* hidden for the first 200ms: a fast load never flashes the spinner card */
.card:has(> .loading) { animation: appear 0s 200ms backwards; }
@keyframes appear { from { opacity: 0; } }

.results { list-style: none; margin: -0.5rem -0.75rem; padding: 0; }
.results li + li { border-top: 1px solid var(--hairline); }
.results .row { padding: 0.875rem 0.75rem; }
/* 例句 hits under the headword results: sentence, romanization, 華語 stacked */
.results-heading { margin: 1.75rem 0 1rem; color: var(--secondary); font-size: 0.9375rem; font-weight: normal; }
.results-heading:first-child { margin-top: 0; }
.example-row { flex-direction: column; gap: 0.125rem; }
/* dropdown 例句: one line, cut with … */
.example-row.compact { flex-direction: row; flex-wrap: nowrap; }
.example-row.compact .ex-hanzi { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.suggest-heading { padding: 0.625rem 0.75rem 0.25rem; color: var(--secondary); font-size: 0.875rem; }
.suggest-heading:not(:first-child) { margin-top: 0.25rem; border-top: 1px solid var(--hairline); }

/* --- entry --- */
.entry-head { position: relative; }
/* copy / share / word card, top right of the card; the headword keeps clear of them */
.entry-actions { position: absolute; top: -0.5rem; right: -0.5rem; display: flex; gap: 0.125rem; }
.entry-action { color: var(--secondary); }
.entry-action:hover { color: var(--text); }
.entry-action svg { width: 18px; height: 18px; }
.entry-hanzi {
  /* clears the four 36px entry actions */
  padding-right: 9.5rem;
  margin: 0;
  font-size: 2.25rem;
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.25;
  overflow-wrap: anywhere;
}
.readings { margin: 0.375rem 0 0; display: flex; flex-wrap: wrap; gap: 0.25rem 1.25rem; font-size: 1.25rem; }
.reading-alt { color: var(--secondary); }
.reading-label { margin-right: 0.375rem; font-size: 0.65em; letter-spacing: 0.02em; }
.mark { color: var(--secondary); font-weight: 400; font-size: 0.6em; letter-spacing: 0; }
.reading-tl .mark { font-size: 0.8em; }
/* inline in the reading line; negative margin keeps the line height */
.play {
  display: inline-grid;
  margin: -6px 0 -6px 0.25rem;
  color: var(--accent);
  vertical-align: middle;
}
.play svg { width: 20px; height: 20px; }
.play.is-error { color: var(--secondary); }
.entry-meta { margin: 0.5rem 0 0; color: var(--secondary); font-size: 0.8125rem; }

/* label/value rows, like the converter's result rows */
.facts, .relations { margin: 1.25rem 0 0; display: grid; grid-template-columns: 6rem 1fr; }
.facts dt, .facts dd, .relations dt, .relations dd {
  margin: 0;
  padding: 0.875rem 0;
  border-top: 1px solid var(--hairline);
}
.facts dt, .relations dt { color: var(--secondary); font-size: 0.9375rem; }
.facts dd { overflow-wrap: anywhere; }
.facts dd:has(a) { display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; }
.dialects, .comparison { border-collapse: collapse; }
.dialects th, .comparison th { padding: 0 1.5rem 0.25rem 0; color: var(--secondary); font-size: 0.9375rem; font-weight: 400; text-align: left; vertical-align: top; }
.dialects td { padding: 0 0 0.25rem; }
/* 語音差異 / 詞彙比較 reading: 台羅, then grey POJ / 方音符號, wrapping like the entry's reading line */
.reading-set { display: flex; flex-wrap: wrap; gap: 0 0.75rem; }
.comparison td { padding: 0 1.5rem 0.25rem 0; }
.comparison td:last-child { padding-right: 0; }
.comparison caption { padding-bottom: 0.5rem; text-align: left; }
.comparison + .comparison { margin-top: 1.25rem; }
.relations dd { display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; }
.relations span { color: var(--secondary); }

.senses { margin: 1.25rem 0 0; padding: 0; list-style: none; }
.sense { padding: 1.25rem 0; border-top: 1px solid var(--hairline); }
.sense:last-child { padding-bottom: 0; }
.sense-head { display: flex; flex-direction: column; }
.pos { color: var(--secondary); font-size: 0.9375rem; white-space: pre; }
.def { margin: 0; }
.examples { margin: 0.75rem 0 0; padding: 0 0 0 1rem; list-style: none; border-left: 2px solid var(--hairline); }
.example + .example { margin-top: 0.75rem; }
.ex-roman, .ex-zh { color: var(--secondary); font-size: 0.9375rem; }
.sense .relations { margin-top: 0.75rem; }


/* --- footer --- */
.footer {
  margin-top: auto;
  padding-top: 2.5rem;
  color: var(--secondary);
  font-size: 0.8125rem;
  letter-spacing: -0.01em;
  text-align: center;
}
.footer p { margin: 0.25rem 0; }
.footer a { color: var(--secondary); transition: color 0.2s; }
.footer a:hover { color: var(--text); text-decoration: none; }

/* touch screens: icon buttons grow to the 44pt minimum touch target (Apple HIG) */
@media (pointer: coarse) {
  .corner-button, .play, .entry-action, .retry { width: 44px; height: 44px; }
  .entry-hanzi { padding-right: 11.25rem; }
  .play { margin: -10px 0 -10px 0.125rem; }
}

@media (max-width: 560px) {
  body { padding: 2.5rem 1rem 1.5rem; }
  .card { padding: 1.25rem; }
  h1 { font-size: 1.375rem; }
  .entry-hanzi { font-size: 2rem; }
  .facts, .relations { grid-template-columns: 4.5rem 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .loading { animation-duration: 2.4s; }
}
