/* Sidora shared base layer (Sidora-mobile-web-addendum.md Tier 1).
 *
 * Linked on every page BEFORE its own inline <style> block. Two invariants
 * here use !important on purpose — they are accessibility/mobile correctness
 * rules that must never be overridden by a page's own copy-pasted styles, and
 * centralizing them here avoids editing the same declaration in all nine
 * pages' inline CSS:
 *   1. form controls at 16px — below 16px, iOS Safari auto-zooms the whole
 *      page on focus, which reads as distinctly "not an app."
 *   2. a CJK-capable font fallback stack — without it, some systems render
 *      Chinese (zh-Hans/zh-Hant) as invisible "tofu" boxes. The stack also
 *      covers Swedish å/ä/ö (every Latin font has them, but confirmed).
 * Everything else here is a plain rule pages may still override intentionally.
 */

/* Site-wide type decision (owner, 2026-07-27):
 *   - English + Swedish (Latin): Marcellus, ligatures on. For titles/subtitles
 *     where all-caps reads well, the small-caps cut Marcellus SC (.sidora-display).
 *   - zh-Hans: Noto Serif SC.   zh-Hant: Noto Serif HK.
 * All four are hosted on Google Fonts and pulled in below. The CSS2 endpoint
 * splits the CJK families into unicode-range subsets, so an en/sv page never
 * downloads the (multi-MB) Chinese glyph files — only the subsets it renders.
 * The active family is chosen by locale via :root[lang=…]; i18n.js stamps
 * <html lang> once the dictionary loads, so a pre-JS paint (or a stray CJK
 * glyph in a Latin locale) falls through the CJK stack rather than showing
 * tofu. Palette is still TBD — this decision is fonts only. */
@import url("https://fonts.googleapis.com/css2?family=Marcellus&family=Marcellus+SC&family=Noto+Serif+HK:wght@200..900&family=Noto+Serif+SC:wght@200..900&display=swap");

:root {
  /* CJK fallbacks kept in every stack for tofu-safety (see header note). */
  --sidora-cjk-fallback: "PingFang SC", "PingFang TC", "Hiragino Sans GB",
    "Microsoft YaHei", "Noto Sans CJK SC", "Noto Sans CJK TC",
    "Source Han Sans SC", "Source Han Sans TC";

  /* Latin default (en/sv) — also the pre-JS / undetected-locale baseline. */
  --sidora-font: "Marcellus", Georgia, "Times New Roman",
    var(--sidora-cjk-fallback), serif;
  --sidora-font-display: "Marcellus SC", "Marcellus", Georgia,
    var(--sidora-cjk-fallback), serif;

  /* Brand palette (owner, 2026-07-27). Semantic names so pages reference a
   * role (--sidora-accent) not a value (#4B5D3A) — the dark theme below then
   * remaps the same roles. All page/component CSS should use these, never a
   * raw hex, so light/dark stays consistent everywhere.
   *   ink            text / primary foreground
   *   bg             page background (cream)
   *   surface        cards / raised panels (slightly lighter than bg)
   *   accent         links, CTAs, active state
   *   on-accent      text/icon sitting on an accent fill
   *   muted          secondary body copy
   *   muted-label    captions / labels (quieter still)
   *   border         hairline dividers and control borders
   *   dark-surface   footers / intentionally-dark panels (same in both themes)
   * danger/notice are not in the brand spec — warm-toned so they sit on cream
   * rather than the old Material red/amber. */
  --sidora-ink: #2C3527;
  --sidora-bg: #F1EEE3;
  --sidora-surface: #F9F8F0;
  --sidora-accent: #4B5D3A;
  --sidora-accent-hover: #374528;
  --sidora-on-accent: #F9F8F0;
  --sidora-muted: #6B7161;
  --sidora-muted-label: #7D8770;
  --sidora-border: #DBE0CE;
  --sidora-dark-surface: #1D2318;

  --sidora-danger: #A8362B;
  --sidora-danger-hover: #8A2A21;
  --sidora-on-danger: #F9F8F0;
  --sidora-notice-bg: #F5EFD9;
  --sidora-notice-border: #E4D9A8;
  --sidora-notice-ink: #6B5A1E;

  /* Native form controls / scrollbars follow the theme. Flipped in dark. */
  color-scheme: light;
}

/* Dark theme — activated by data-theme="dark" on <html>, stamped pre-paint by
 * the inline no-flash snippet in each page head (source of truth: localStorage
 * 'sidora_theme'; unset follows the OS). Only the palette roles change; every
 * consumer inherits automatically. Accent is brightened for AA contrast on the
 * dark ground and on-accent flips to dark ink (per owner values). */
:root[data-theme="dark"] {
  --sidora-ink: #F1EEE3;
  --sidora-bg: #1D2318;
  --sidora-surface: #242B1E;
  --sidora-accent: #7A9163;
  --sidora-accent-hover: #94AC7D;
  --sidora-on-accent: #1D2318;
  --sidora-muted: #A9B39C;
  --sidora-muted-label: #8B9682;
  --sidora-border: #333D2A;
  --sidora-dark-surface: #1D2318;

  --sidora-danger: #E0836F;
  --sidora-danger-hover: #ECA08F;
  --sidora-on-danger: #1D2318;
  --sidora-notice-bg: #2A3120;
  --sidora-notice-border: #3D3A24;
  --sidora-notice-ink: #D8CE9E;

  color-scheme: dark;
}

/* zh-Hans / zh-Hant have no Latin small-caps notion, so display == body.
 * Marcellus leads the stack so Latin runs (the "Sidora" wordmark, digits,
 * any Latin book titles) render in Marcellus via per-glyph fallback, while
 * Chinese characters — which Marcellus lacks — fall through to Noto Serif
 * SC/HK. Without this, the CJK face's own Latin cut renders "Sidora" and it
 * reads as a plain serif rather than the wordmark (owner, 2026-07-27). */
:root[lang="zh-Hans"] {
  --sidora-font: "Marcellus", "Noto Serif SC", var(--sidora-cjk-fallback), serif;
  --sidora-font-display: var(--sidora-font);
}
:root[lang="zh-Hant"] {
  --sidora-font: "Marcellus", "Noto Serif HK", var(--sidora-cjk-fallback), serif;
  --sidora-font-display: var(--sidora-font);
}

body {
  font-family: var(--sidora-font) !important;
  /* Ligatures on, per the type decision. Harmless no-op for the CJK faces. */
  font-variant-ligatures: common-ligatures contextual;
  /* Brand palette baseline. Pages may still set their own bg on inner panels,
   * but the page ground + default text color come from here so every page —
   * and both themes — start consistent. The transition makes the toggle a
   * soft cross-fade rather than a hard flip; it's only on color properties so
   * it never animates layout. */
  background: var(--sidora-bg);
  color: var(--sidora-ink);
  transition: background-color 0.2s ease, color 0.2s ease;
}

/* Opt-in display face for UI titles/subtitles where all-caps reads well
 * (Marcellus SC in Latin locales; the body serif in CJK). Applied to static
 * page-chrome titles, not to dynamic content like book titles or author names. */
.sidora-display {
  font-family: var(--sidora-font-display);
  font-variant-ligatures: common-ligatures contextual;
}

/* Prevent iOS focus-zoom. Scoped to text-entry controls (buttons don't
 * trigger the zoom and keep their smaller uppercase label size). */
input,
select,
textarea {
  font-size: 16px !important;
}

/* Form controls don't inherit font-family by default — the UA stylesheet
 * gives buttons/inputs/selects/textareas their own system font, so they
 * render in Helvetica/Arial instead of the site serif while everything
 * around them is Marcellus. Force inheritance here, once, so every control
 * matches: the "Borrowing"/"Lending" tabs, the SAVE / "Add contact method"
 * buttons, contact-method selects, the postcode/handle inputs, the file
 * input's "Choose file" text, "Remove photo", and the book-description box. */
button,
input,
select,
textarea {
  font-family: inherit;
}
/* The file input's picker button is a separate shadow control that ignores
 * the inherited family unless targeted directly. */
input[type="file"]::file-selector-button {
  font-family: inherit;
}

/* Touch ergonomics: comfortable hit targets and no 300ms double-tap delay /
 * accidental double-tap-to-zoom on interactive elements. Not !important —
 * a page may deliberately style a smaller inline control. */
button,
a,
input,
select,
textarea,
label {
  touch-action: manipulation;
}

button {
  min-height: 44px;
}

/* Opt-in 44x44 hit area for non-button tap targets (icons, map circles, etc.)
 * without forcing it on every link. */
.tap-target {
  min-width: 44px;
  min-height: 44px;
}

/* Shared language switcher (SidoraI18n.createLanguageSelect) — compact,
 * fits the top bar and the sign-in card. font-size stays 16px via the rule
 * above (iOS-zoom safe); the tight padding keeps it small regardless. */
.sidora-lang-select {
  padding: 4px 6px;
  border: 1px solid var(--sidora-border);
  border-radius: 4px;
  background: var(--sidora-surface);
  color: var(--sidora-ink);
  font-family: inherit;
  cursor: pointer;
}

/* Shared theme toggle (SidoraTheme.createThemeToggle) — a compact icon button
 * that sits beside the language switcher in the top bar, sign-in bar, and map
 * bar. Sun/moon glyph is swapped in JS; the button chrome matches the lang
 * select so the two read as a pair. */
.sidora-theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  min-height: 0;
  border: 1px solid var(--sidora-border);
  border-radius: 4px;
  background: var(--sidora-surface);
  color: var(--sidora-ink);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
.sidora-theme-toggle:hover {
  border-color: var(--sidora-accent);
  color: var(--sidora-accent);
}

/* Minimalist theme switch (SidoraTheme.createThemeSwitch) — replaces the
 * single-glyph toggle where both modes should be visible at once: a pill
 * with a fixed sun (left) and moon (right) and a knob that slides between
 * them. aria-checked="true" == dark, which slides the knob right onto the
 * moon. Both glyphs stay visible so it reads as a light/dark selector, not
 * a mystery button.
 *
 * The selector is deliberately doubled (.sidora-theme-switch.sidora-theme-switch)
 * to raise its specificity to (0,2,0). The switch is a <button>, and pages
 * like sign-in style their own action buttons with a single-class rule such
 * as `.card button { width:100%; background:accent; padding:12px; ... }`
 * (specificity 0,1,1) that would otherwise stretch this control to full width
 * and repaint it green. Two classes outrank one-class-one-element regardless
 * of source order, so the shared control always wins — same intent as the
 * !important form-control invariants above, without leaking !important. */
.sidora-theme-switch.sidora-theme-switch {
  position: relative;
  box-sizing: border-box;
  width: 52px;
  height: 26px;
  padding: 0 6px;
  min-height: 0;
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  border: 1px solid var(--sidora-border);
  border-radius: 13px;
  background: var(--sidora-bg);
  color: var(--sidora-ink);
  text-transform: none;
  cursor: pointer;
  flex: 0 0 auto;
}
.sidora-theme-switch .switch-ico {
  font-size: 11px;
  line-height: 1;
  position: relative;
  z-index: 1;
  opacity: 0.5;
  transition: opacity 0.2s ease;
}
/* Brighten the glyph for the active side. */
.sidora-theme-switch[aria-checked="false"] .switch-ico.sun,
.sidora-theme-switch[aria-checked="true"] .switch-ico.moon {
  opacity: 1;
}
.sidora-theme-switch .switch-knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--sidora-accent);
  transition: transform 0.2s ease;
}
.sidora-theme-switch[aria-checked="true"] .switch-knob {
  transform: translateX(26px);
}
.sidora-theme-switch.sidora-theme-switch:hover {
  border-color: var(--sidora-accent);
  background: var(--sidora-bg);
  color: var(--sidora-ink);
}

/* Minimalist flag dropdown language switcher (SidoraI18n.createLanguageFlags).
 * The trigger shows only the current locale's flag + a caret, so it stays
 * compact (letting the sidebar hug its content); the four flags are revealed
 * in a small popover on click. The popover opens upward so it isn't clipped
 * when the control sits at the bottom of the sidebar. */
.sidora-lang-dd {
  position: relative;
  display: inline-flex;
}
.sidora-lang-dd .lang-current {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  min-height: 0;
  padding: 3px 6px;
  border: 1px solid var(--sidora-border);
  background: var(--sidora-surface);
  border-radius: 6px;
  line-height: 1;
  cursor: pointer;
}
.sidora-lang-dd .lang-current:hover {
  border-color: var(--sidora-accent);
}
.sidora-lang-dd .lang-current .flag {
  font-size: 18px;
  line-height: 1;
}
.sidora-lang-dd .lang-current .caret {
  font-size: 10px;
  color: var(--sidora-muted);
}
.sidora-lang-dd .lang-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  display: none;
  flex-direction: column;
  gap: 2px;
  padding: 4px;
  background: var(--sidora-surface);
  border: 1px solid var(--sidora-border);
  border-radius: 8px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
  z-index: 10;
}
.sidora-lang-dd.open .lang-menu {
  display: flex;
}
/* Opt-in: open upward. Used in the sidebar, where the control sits near the
 * bottom of the drawer; the default (downward) is right everywhere the
 * control sits at the top of its container (sign-in, landing, about). */
.sidora-lang-dd.up .lang-menu {
  top: auto;
  bottom: calc(100% + 6px);
}
.sidora-lang-dd .lang-menu button {
  min-height: 0;
  padding: 5px 8px;
  border: none;
  background: none;
  border-radius: 5px;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  opacity: 0.55;
  filter: grayscale(0.4);
  transition: opacity 0.12s ease, filter 0.12s ease, background 0.12s ease;
}
.sidora-lang-dd .lang-menu button:hover {
  opacity: 1;
  filter: none;
  background: var(--sidora-bg);
}
.sidora-lang-dd .lang-menu button.active {
  opacity: 1;
  filter: none;
  background: var(--sidora-bg);
}

/* Deliberate pull-to-refresh stance: don't let a stray over-scroll at the top
 * of a page trigger the browser's native reload (it fights modal/list scroll
 * and reads as janky). Horizontal chaining is left alone. */
html {
  overscroll-behavior-y: contain;
}
