﻿  :root {
    color-scheme: light dark;
    --bg-grouped: #f2f2f7;
    --bg-cell: #ffffff;
    /* Alternate fill used by nested grouping boxes so depth alternation
       is actually visible (not just transparent vs bg-cell â€” that all
       resolves to the same visible color). */
    --bg-cell-alt: #e7e7ed;
    --bg-header: rgba(248, 248, 250, 0.82);
    --border: rgba(60, 60, 67, 0.18);
    --text: #000;
    --text-secondary: rgba(60, 60, 67, 0.78);
    --text-tertiary: rgba(60, 60, 67, 0.48);
    --tint: #34a853;
    --tint-press: #2a8844;
    --badge-bg: rgba(118, 118, 128, 0.16);
    --search-bg: rgba(118, 118, 128, 0.12);
    --show-all-species-bg: #e8f0ff;
    --browse-group-bg: #ffffff;
    --control-bg: #ffffff;
    --control-bg-active: #34a853;
    --book-section-bg: #e7e7ed;
    --radius: 12px;
    --header-h: 52px;
    --row-h: 58px;
    --color-kingdom: #ffffff;
    --color-phylum:  #f2f2f7;
    --color-subphylum: #ececf1;
    --color-class:   #ffffff;
    --color-subclass: #ececf1;
    --color-order:   #f2f2f7;
    --color-suborder: #ececf1;
    --color-superfamily: #e4e4ea;
    --color-family:  #ffffff;
    --color-subfamily: #ececf1;
    --color-tribe:   #e4e4ea;
    --color-subtribe: #dcdce2;
    --color-genus:   #f2f2f7;
    --color-subgenus: #ececf1;
    --color-other:   #ffffff;
        font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI",
                 Roboto, "Helvetica Neue", Arial, sans-serif;
  }
  /* Auto: system preference picks dark when no user override is set. */
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
      --bg-grouped: #000000;
      --bg-cell: #1c1c1e;
      --bg-cell-alt: #2c2c2e;
      --bg-header: rgba(28, 28, 30, 0.82);
      --border: rgba(84, 84, 88, 0.65);
      --text: #ffffff;
      --text-secondary: rgba(235, 235, 245, 0.78);
      --text-tertiary: rgba(235, 235, 245, 0.48);
      --badge-bg: rgba(120, 120, 128, 0.36);
      --search-bg: rgba(118, 118, 128, 0.24);
      --show-all-species-bg: #2c3a52;
      --browse-group-bg: #1c1c1e;
      --control-bg: #2c2c2e;
      --control-bg-active: #30d158;
      --book-section-bg: #2c2c2e;
      --tint: #30d158;
      --tint-press: #26a647;
      /* Per-rank fill (DARK theme defaults) â€” tweak any of these. */
      --color-kingdom: #1c1c1e;
      --color-phylum:  #232325;
      --color-subphylum: #262628;
      --color-class:   #2a2a2c;
      --color-subclass: #2d2d2f;
      --color-order:   #313133;
      --color-suborder: #343436;
      --color-superfamily: #373739;
      --color-family:  #38383a;
      --color-subfamily: #3a3a3c;
      --color-tribe:   #3d3d3f;
      --color-subtribe: #404042;
      --color-genus:   #3f3f41;
      --color-subgenus: #424244;
      --color-other:   #2c2c2e;
    }
  }
  /* Explicit user override (Settings â†’ Theme). Wins over the system
     media-query above because rules with the same specificity that
     come later in the source cascade win. */
  :root[data-theme="dark"] {
    color-scheme: dark;
    --bg-grouped: #000000;
    --bg-cell: #1c1c1e;
    --bg-cell-alt: #2c2c2e;
    --bg-header: rgba(28, 28, 30, 0.82);
    --border: rgba(84, 84, 88, 0.65);
    --text: #ffffff;
    --text-secondary: rgba(235, 235, 245, 0.78);
    --text-tertiary: rgba(235, 235, 245, 0.48);
    --badge-bg: rgba(120, 120, 128, 0.36);
    --search-bg: rgba(118, 118, 128, 0.24);
    --show-all-species-bg: #2c3a52;
    --browse-group-bg: #1c1c1e;
    --control-bg: #2c2c2e;
    --control-bg-active: #30d158;
    --book-section-bg: #2c2c2e;
    --tint: #30d158;
    --tint-press: #26a647;
    /* Per-rank fill (DARK theme â€” same defaults as the auto block). */
    --color-kingdom: #1c1c1e;
    --color-phylum:  #232325;
    --color-subphylum: #262628;
    --color-class:   #2a2a2c;
    --color-subclass: #2d2d2f;
    --color-order:   #313133;
    --color-suborder: #343436;
    --color-superfamily: #373739;
    --color-family:  #38383a;
    --color-subfamily: #3a3a3c;
    --color-tribe:   #3d3d3f;
    --color-subtribe: #404042;
    --color-genus:   #3f3f41;
    --color-subgenus: #424244;
    --color-other:   #2c2c2e;
  }
  :root[data-theme="light"] {
    color-scheme: light;
    /* Light now uses the old colorful palette as the standard default. */
    --bg-grouped: #f8fafc;
    --bg-cell: #ffffff;
    --bg-cell-alt: #eef2ff;
    --bg-header: rgba(255, 255, 255, 0.92);
    --border: rgba(15, 23, 42, 0.14);
    --text: #0f172a;
    --text-secondary: rgba(15, 23, 42, 0.75);
    --text-tertiary: rgba(15, 23, 42, 0.52);
    --badge-bg: rgba(15, 23, 42, 0.08);
    --search-bg: rgba(15, 23, 42, 0.06);
    --show-all-species-bg: #eef4ff;
    --browse-group-bg: #ffffff;
    --control-bg: #ffffff;
    --control-bg-active: #2563eb;
    --book-section-bg: #eef2ff;
    --tint: #2563eb;
    --tint-press: #1d4ed8;
    --color-kingdom: #ff4d4d;
    --color-phylum:  #ff9f1a;
    --color-subphylum: #ffbf69;
    --color-class:   #ffe066;
    --color-subclass: #fff0a6;
    --color-order:   #34d399;
    --color-suborder: #86efac;
    --color-superfamily: #22d3ee;
    --color-family:  #38bdf8;
    --color-subfamily: #93c5fd;
    --color-tribe:   #818cf8;
    --color-subtribe: #a5b4fc;
    --color-genus:   #c084fc;
    --color-subgenus: #d8b4fe;
    --color-other:   #e2e8f0;
  }
  /* === Forest Fairy theme ===
     Twilight forest meets pixie magic. Deep mossy base climbs into
     dusky lavender and bright orchid; the tint is cotton-candy pink.
     Rank palette starts at the moonshadow forest floor (kingdom) and
     blooms up to fairy violet (genus). */
  :root[data-theme="fairy"] {
    color-scheme: dark;
    --bg-grouped: #1a132a;
    --bg-cell: #271d3e;
    --bg-cell-alt: #322550;
    --bg-header: rgba(26, 19, 42, 0.92);
    --border: rgba(247, 230, 243, 0.22);
    --text: #f7e6f3;
    --text-secondary: rgba(247, 230, 243, 0.82);
    --text-tertiary: rgba(247, 230, 243, 0.52);
    --badge-bg: rgba(255, 179, 217, 0.20);
    --search-bg: rgba(255, 179, 217, 0.12);
    --show-all-species-bg: #4a3a64;
    --browse-group-bg: #271d3e;
    --control-bg: #322550;
    --control-bg-active: #ffb3d9;
    --book-section-bg: #322550;
    --tint: #ffb3d9;
    --tint-press: #e58fbb;
    /* Rank palette â€” moonshadow â†’ orchid â†’ fairy violet. Greens at
       the base anchor it as a forest before the lavenders take over. */
    --color-kingdom: #1f1934;     /* moonshadow forest floor */
    --color-phylum:  #2a2440;     /* mossy twilight */
    --color-subphylum: #322a4b;   /* moonlit fern */
    --color-class:   #382f4f;     /* gloaming sage */
    --color-subclass: #42365a;    /* dusk lilac */
    --color-order:   #4a3a64;     /* deep lavender mist */
    --color-suborder: #564171;    /* twilight orchid */
    --color-superfamily: #63497d; /* enchanted heather */
    --color-family:  #6a4880;     /* rich orchid bloom */
    --color-subfamily: #75558d;   /* fairy thistle */
    --color-tribe:   #80609a;     /* spellbound violet */
    --color-subtribe: #8a6aa7;    /* violet haze */
    --color-genus:   #8a5da0;     /* fairy violet glow */
    --color-subgenus: #9a72b0;    /* orchid shimmer */
    --color-other:   #3b3050;     /* default twilight mid-tone */
  }
  /* Theme refresh overrides: softer fairy. These
     appear later so they win over the earlier draft palette above. */
  :root[data-theme="fairy"] {
    color-scheme: light;
    --bg-grouped: #f8f4fb;
    --bg-cell: #fffdfd;
    --bg-cell-alt: #f1f7ff;
    --bg-header: rgba(248, 244, 251, 0.92);
    --border: rgba(120, 92, 150, 0.18);
    --text: #3f3a4f;
    --text-secondary: rgba(63, 58, 79, 0.78);
    --text-tertiary: rgba(63, 58, 79, 0.50);
    --badge-bg: rgba(177, 214, 255, 0.20);
    --search-bg: rgba(255, 202, 223, 0.16);
    --show-all-species-bg: #f6e7f3;
    --browse-group-bg: #fffdfd;
    --control-bg: #fffdfd;
    --control-bg-active: #d97aa8;
    --book-section-bg: #f1f7ff;
    --tint: #d97aa8;
    --tint-press: #be648f;
    --color-kingdom: #d7eef8;
    --color-phylum:  #f7d7e7;
    --color-subphylum: #fbe7ef;
    --color-class:   #d9ecff;
    --color-subclass: #edf6ff;
    --color-order:   #efe0fb;
    --color-suborder: #f7ecff;
    --color-superfamily: #dff3ef;
    --color-family:  #fbe3dc;
    --color-subfamily: #eef5ff;
    --color-tribe:   #f4dbe8;
    --color-subtribe: #e4efff;
    --color-genus:   #f2dff7;
    --color-subgenus: #f7eefb;
    --color-other:   #edeaf6;
  }
  * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
  html, body { margin: 0; padding: 0; background: var(--bg-grouped); color: var(--text); height: 100%; min-height: 100%; }
  html { font-size: 17px; line-height: 1.3; -webkit-text-size-adjust: 100%; }
  body {
    padding-top: 0;
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
    height: 100%;
    min-height: 100vh;
    min-height: 100svh;
    min-height: 100dvh;
  }
  .app {
    max-width: 560px; margin: 0 auto; min-height: 100%;
    min-height: 100vh;
    min-height: 100svh;
    min-height: 100dvh;
    display: flex; flex-direction: column; background: var(--bg-grouped);
  }
  #account-gate {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: var(--bg-grouped);
  }
  #account-gate[hidden] { display: none !important; }
  .account-gate-card {
    width: min(100%, 420px);
    background: var(--bg-cell);
    border: 1px solid var(--border);
    border-radius: 28px;
    box-shadow: 0 24px 60px rgba(15, 23, 42, 0.12);
    padding: 28px 24px 24px;
  }
  .account-gate-kicker {
    font-size: 0.88rem;
    letter-spacing: 0.08em;
    color: var(--text-tertiary);
    margin-bottom: 8px;
  }
  .account-gate-title {
    margin: 0 0 10px;
    font-size: 1.9rem;
    line-height: 1.05;
    color: var(--text);
  }
  .account-gate-text {
    margin: 0 0 18px;
    color: var(--text-secondary);
    font-size: 1rem;
    line-height: 1.45;
  }
  .account-gate-label {
    display: block;
    margin-bottom: 8px;
    color: var(--text);
    font-weight: 600;
  }
  #account-gate-input {
    width: 100%;
    border: 1px solid var(--border);
    background: var(--control-bg);
    color: var(--text);
    border-radius: 16px;
    padding: 14px 16px;
    font: inherit;
    margin-bottom: 12px;
  }
  #account-gate-input:focus {
    outline: none;
    border-color: var(--tint);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--tint) 18%, transparent);
  }
  #account-gate-error {
    color: #c62828;
    font-size: 0.95rem;
    margin-bottom: 12px;
  }
  #account-gate-submit {
    width: 100%;
    border: none;
    border-radius: 16px;
    background: var(--tint);
    color: #fff;
    padding: 14px 16px;
    font: inherit;
    font-weight: 700;
  }
  #account-gate-submit:active {
    background: var(--tint-press);
  }
  header#app-bar {
    position: sticky; top: 0; z-index: 20;
    display: flex; align-items: center; gap: 4px;
    padding: calc(env(safe-area-inset-top) - 16px) 6px 0 6px;
    height: calc(var(--header-h) + env(safe-area-inset-top) - 12px);
    background: var(--bg-header);
    backdrop-filter: saturate(180%) blur(18px);
    -webkit-backdrop-filter: saturate(180%) blur(18px);
    border-bottom: 0.5px solid var(--border);
  }
  header button {
    background: transparent; border: 0; color: var(--tint);
    font: inherit; font-size: 17px; padding: 0 10px;
    min-width: 44px; height: 44px; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 8px;
  }
  header button:active { background: var(--badge-bg); color: var(--tint-press); }
  header button[hidden] { display: none; }
  #back { gap: 2px; font-size: 17px; padding-right: 12px; }
  #back::before { content: "\2039"; font-size: 28px; font-weight: 400; margin-right: 1px; }
  .titles { flex: 1; min-width: 0; text-align: center; padding: 0 4px; }
  #title {
    font-weight: 600; font-size: var(--font-app-title); line-height: 1.15;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    color: var(--text);
  }
  #subtitle {
    font-size: var(--font-app-subtitle); line-height: 1.2;
    color: var(--text-tertiary);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .page-header-hidden #filter-btn,
  .page-header-hidden #back {
    visibility: hidden;
    pointer-events: none;
  }
  #search-btn::before { content: ""; display: block; width: 18px; height: 18px;
    background: currentColor;
    mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M10.5 7a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0zm-.72 4.3a5.5 5.5 0 1 1 1.42-1.42l3.58 3.58a1 1 0 1 1-1.42 1.42l-3.58-3.58z'/></svg>") center / contain no-repeat;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M10.5 7a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0zm-.72 4.3a5.5 5.5 0 1 1 1.42-1.42l3.58 3.58a1 1 0 1 1-1.42 1.42l-3.58-3.58z'/></svg>") center / contain no-repeat;
  }
  #notification-btn { position: relative; }
  #notification-btn::before { content: ""; display: block; width: 18px; height: 18px;
    background: currentColor;
    mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M12 22a2.5 2.5 0 0 0 2.45-2h-4.9A2.5 2.5 0 0 0 12 22zm7-6V11a7 7 0 1 0-14 0v5l-2 2v1h18v-1l-2-2z'/></svg>") center / contain no-repeat;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M12 22a2.5 2.5 0 0 0 2.45-2h-4.9A2.5 2.5 0 0 0 12 22zm7-6V11a7 7 0 1 0-14 0v5l-2 2v1h18v-1l-2-2z'/></svg>") center / contain no-repeat;
  }
  #notification-btn.has-unread::after {
    content: attr(data-badge);
    position: absolute;
    top: 6px;
    right: 5px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 999px;
    background: #d93636;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
    box-sizing: border-box;
  }
  /* Settings (gear) button in the header â€” same shape and size as
     the search button, just a different masked SVG. */
  #filter-btn::before { content: ""; display: block; width: 18px; height: 18px;
    background: currentColor;
    mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M3 5h18l-7 8v5l-4 2v-7L3 5z'/></svg>") center / contain no-repeat;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M3 5h18l-7 8v5l-4 2v-7L3 5z'/></svg>") center / contain no-repeat;
  }
  #filter-btn.is-active { background: var(--badge-bg); }
  #settings-btn::before { content: ""; display: block; width: 19px; height: 19px;
    background: currentColor;
    mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M19.14 12.94c.04-.31.06-.62.06-.94s-.02-.63-.06-.94l2.03-1.58a.5.5 0 0 0 .12-.64l-1.92-3.32a.5.5 0 0 0-.6-.22l-2.39.96a7.07 7.07 0 0 0-1.62-.94l-.36-2.54A.5.5 0 0 0 14 2h-3.84a.5.5 0 0 0-.5.42l-.36 2.54c-.59.24-1.13.55-1.62.94l-2.39-.96a.5.5 0 0 0-.6.22L2.77 8.48a.5.5 0 0 0 .12.64l2.03 1.58c-.04.31-.06.62-.06.94s.02.63.06.94l-2.03 1.58a.5.5 0 0 0-.12.64l1.92 3.32a.5.5 0 0 0 .6.22l2.39-.96c.49.39 1.03.7 1.62.94l.36 2.54c.04.24.25.42.5.42h3.84a.5.5 0 0 0 .5-.42l.36-2.54c.59-.24 1.13-.55 1.62-.94l2.39.96a.5.5 0 0 0 .6-.22l1.92-3.32a.5.5 0 0 0-.12-.64l-2.03-1.58zM12 15.5A3.5 3.5 0 1 1 12 8.5a3.5 3.5 0 0 1 0 7z'/></svg>") center / contain no-repeat;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M19.14 12.94c.04-.31.06-.62.06-.94s-.02-.63-.06-.94l2.03-1.58a.5.5 0 0 0 .12-.64l-1.92-3.32a.5.5 0 0 0-.6-.22l-2.39.96a7.07 7.07 0 0 0-1.62-.94l-.36-2.54A.5.5 0 0 0 14 2h-3.84a.5.5 0 0 0-.5.42l-.36 2.54c-.59.24-1.13.55-1.62.94l-2.39-.96a.5.5 0 0 0-.6.22L2.77 8.48a.5.5 0 0 0 .12.64l2.03 1.58c-.04.31-.06.62-.06.94s.02.63.06.94l-2.03 1.58a.5.5 0 0 0-.12.64l1.92 3.32a.5.5 0 0 0 .6.22l2.39-.96c.49.39 1.03.7 1.62.94l.36 2.54c.04.24.25.42.5.42h3.84a.5.5 0 0 0 .5-.42l.36-2.54c.59-.24 1.13-.55 1.62-.94l2.39.96a.5.5 0 0 0 .6-.22l1.92-3.32a.5.5 0 0 0-.12-.64l-2.03-1.58zM12 15.5A3.5 3.5 0 1 1 12 8.5a3.5 3.5 0 0 1 0 7z'/></svg>") center / contain no-repeat;
  }
  #taxa-btn::before { content: ""; display: block; width: 19px; height: 19px;
    background: currentColor;
    mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M10 4H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-8l-2-2z'/></svg>") center / contain no-repeat;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M10 4H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-8l-2-2z'/></svg>") center / contain no-repeat;
  }
  #map-btn::before { content: ""; display: block; width: 19px; height: 19px;
    background: currentColor;
    mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 1 1 0-5 2.5 2.5 0 0 1 0 5z'/></svg>") center / contain no-repeat;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 1 1 0-5 2.5 2.5 0 0 1 0 5z'/></svg>") center / contain no-repeat;
  }
  /* Theme picker â€” segmented control inside the settings popup. */
  .settings-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 0;
  }
  .settings-row-stack {
    display: flex;
    flex-direction: column;
    align-items: stretch;
  }
  .settings-row-actions {
    justify-content: flex-end;
  }
  .settings-row-label { font-size: 14px; font-weight: 500; color: var(--text); }
  .download-size {
    font-size: 13px;
    color: var(--text-secondary);
    text-align: right;
    min-width: 100px;
  }
  .settings-section {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 8px 0 2px;
  }
  .filter-section-card {
    background: var(--bg-cell);
    border: 1px solid var(--border);
    border-radius: 18px;
    padding: 12px 12px 10px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
    gap: 6px;
    margin-bottom: 12px;
  }
  .filter-section-card .settings-section-title {
    font-size: 15px;
    font-weight: 700;
  }
  .filter-section-card .settings-section-subtitle {
    line-height: 1.35;
    margin-bottom: 2px;
  }
  .filter-section-card .settings-row {
    padding: 6px 0;
  }
  .filter-section-card .settings-toggle {
    padding: 7px 0;
  }
  .filter-section-card .settings-toggle.settings-toggle--nested {
    padding-left: 26px;
  }
  .filter-section-card .settings-row:last-child,
  .filter-section-card .settings-toggle:last-child {
    padding-bottom: 0;
  }
  .settings-action-row {
    padding: 4px 0;
  }
  .filter-reset-card {
    padding: 0;
    background: transparent;
    border: 0;
    box-shadow: none;
    margin-bottom: 12px;
    margin-left: -8px;
    margin-right: -8px;
  }
  .filter-reset-btn {
    width: 100%;
    border: 0;
    border-radius: 18px;
    padding: 14px 16px;
    background: var(--tint);
    color: #fff;
    font: inherit;
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0,0,0,0.12);
  }
  .filter-reset-btn:active { opacity: 0.82; }
  .settings-date-field {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    flex: 1 1 0;
    min-width: 0;
  }
  .settings-date-field input[type="date"] {
    width: 100%;
    max-width: 100%;
  }
  .settings-section-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
  }
  .settings-section-subtitle {
    font-size: 12px;
    color: var(--text-tertiary);
  }
  .settings-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 6px 0;
    font-size: 13px;
    color: var(--text);
  }
  .settings-toggle.settings-toggle--nested {
    padding-left: 28px;
  }
  .settings-toggle span {
    min-width: 0;
    flex: 1;
  }
  .settings-toggle input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
    border-radius: 5px;
    border: 1.5px solid var(--border);
    background: var(--control-bg);
    position: relative;
    cursor: pointer;
  }
  .settings-toggle input[type="checkbox"]:checked {
    background: var(--control-bg-active);
    border-color: var(--control-bg-active);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='white' d='M6.4 11.6 3.2 8.4l-1.1 1.1 4.3 4.3 7.5-7.5-1.1-1.1z'/></svg>");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 12px 12px;
  }
  .settings-radio {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 0;
    color: var(--text);
  }
  .settings-radio-copy {
    min-width: 0;
    flex: 1;
  }
  .settings-radio-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
  }
  .settings-radio-subtitle {
    font-size: 12px;
    line-height: 1.35;
    color: var(--text-tertiary);
    margin-top: 2px;
  }
  .settings-radio input[type="radio"] {
    appearance: none;
    -webkit-appearance: none;
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
    border-radius: 50%;
    border: 1.5px solid var(--border);
    background: var(--control-bg);
    cursor: pointer;
  }
  .settings-radio input[type="radio"]:checked {
    background: var(--control-bg-active);
    border-color: var(--control-bg-active);
    box-shadow: inset 0 0 0 4px #fff;
  }
  .ndbg-embedded .ndbg-actions {
    margin: 10px 0 8px;
  }
  .ndbg-embedded,
  .ndbg-embedded * {
    pointer-events: auto !important;
    touch-action: manipulation;
  }
  .ndbg-embedded .ndbg-log {
    max-height: none;
    overflow: visible;
  }
  .settings-btn-danger {
    color: #c62828;
  }
  .theme-picker {
    display: flex;
    align-items: center;
    flex: 1 1 220px;
    min-width: 0;
  }
  .theme-picker-select {
    width: 100%;
    min-width: 0;
    background: var(--bg-cell);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 8px 10px;
    font: inherit;
    font-size: 13px;
    appearance: none;
    -webkit-appearance: none;
  }
  /* Secondary settings button (used for "Customizeâ€¦" and "Reset all"). */
  .settings-btn-secondary {
    background: var(--badge-bg);
    color: var(--text);
    border: 0;
    border-radius: 8px;
    padding: 6px 14px;
    font: inherit;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
  }
  .settings-btn-block {
    display: block;
    width: 100%;
    text-align: left;
    padding: 12px 14px;
    border-radius: 14px;
    font-size: 15px;
    font-weight: 600;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  }
  .settings-btn-secondary:active { opacity: 0.7; }
  /* Toggle variant — stays highlighted when "on" */
  .settings-btn-toggle--on {
    background: var(--tint);
    color: #fff;
  }
  /* Pulsing ring while actively downloading */
  .settings-btn-toggle--active {
    outline: 2px solid var(--tint);
    outline-offset: 2px;
  }
  /* Side-by-side sync buttons */
  .sync-btn-pair {
    display: flex;
    gap: 8px;
    padding: 4px 0;
  }
  .sync-btn-pair .settings-btn-block {
    flex: 0 0 auto;
    width: auto;
    padding: 8px 18px;
    font-size: 14px;
    font-weight: 500;
    text-align: center;
    border-radius: 10px;
  }
  /* Offline toggle row: [button] [size] */
  .offline-toggle-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 0;
  }
  .offline-toggle-row .settings-btn-block {
    flex: 0 0 auto;
    width: auto;
    padding: 8px 18px;
    font-size: 14px;
    font-weight: 500;
    border-radius: 10px;
    touch-action: manipulation;
  }
  .offline-size-label {
    font-size: 12px;
    color: var(--text-secondary);
    white-space: nowrap;
    flex-shrink: 0;
  }
  .theme-name-input,
  .theme-copy-select {
    background: var(--bg-cell);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 8px 10px;
    font: inherit;
    font-size: 13px;
  }
  .theme-name-input {
    min-width: 160px;
    flex: 0 0 180px;
  }
  .settings-text-input {
    width: 100%;
    min-width: 0;
    flex: 1 1 auto;
  }
  .theme-copy-controls {
    display: flex;
    align-items: center;
    gap: 8px;
  }
  /* Custom theme editor uses a wider popup so swatches + labels fit
     comfortably side-by-side. */
  .popup-card.popup-card-wide { max-width: 480px; }
  .popup-body.color-editor {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 8px;
  }
  .color-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 4px;
    border-bottom: 0.5px solid var(--border);
    cursor: pointer;
  }
  .color-row:last-child { border-bottom: 0; }
  .color-row-label {
    font-size: 14px;
    color: var(--text);
    flex: 1;
    min-width: 0;
  }
  .color-row-right {
    display: inline-flex;
    align-items: center;
    gap: 10px;
  }
  .color-row-hex {
    font: 12px/1 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
    color: var(--text-tertiary);
    text-transform: uppercase;
  }
  .color-row-picker {
    width: 36px; height: 28px;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0;
    background: transparent;
    cursor: pointer;
  }
  .color-row-picker::-webkit-color-swatch { border: 0; border-radius: 4px; }
  .color-row-picker::-moz-color-swatch    { border: 0; border-radius: 4px; }
  .popup-footer {
    margin-top: 10px;
    display: flex;
    justify-content: flex-end;
    gap: 8px;
  }

  #search-container {
    position: sticky;
    top: calc(var(--header-h) + env(safe-area-inset-top) - 12px);
    z-index: 15;
    padding: 0 14px 4px;
    background: var(--bg-grouped);
    border-bottom: 0.5px solid var(--border);
  }
  #search-container[hidden] { display: none; }
  #search-input {
    width: 100%; height: 40px; padding: 0 12px;
    border: 0; border-radius: 10px;
    background: var(--search-bg); color: var(--text);
    font-size: 17px; outline: none;
    -webkit-appearance: none; appearance: none;
  }
  #search-input::placeholder { color: var(--text-tertiary); }
  #search-mode-toggle {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    margin-top: 6px;
  }
  #search-mode-toggle button {
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-cell);
    color: var(--text-secondary);
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    padding: 8px 12px;
  }
  #search-mode-toggle button.is-active {
    background: color-mix(in srgb, var(--tint) 12%, var(--bg-cell));
    border-color: color-mix(in srgb, var(--tint) 38%, var(--border));
    color: var(--tint);
  }
  #search-mode-toggle button:active {
    opacity: 0.8;
  }
  #search-literature-filters {
    margin-top: 8px;
    display: grid;
    gap: 10px;
    padding-bottom: 2px;
  }
  .search-literature-filter-group {
    background: var(--bg-cell);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 10px 12px 12px;
  }
  .search-literature-filter-global-actions {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    margin: 0 0 12px;
  }
  .search-literature-filter-header {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
  }
  .search-literature-filter-header-main {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
  }
  .search-literature-filter-title {
    font-size: 14px;
    font-weight: 700;
    color: var(--text);
  }
  .search-literature-filter-meta {
    font-size: 12px;
    color: var(--text-tertiary);
  }
  .search-literature-filter-actions {
    display: flex;
    gap: 10px;
    align-items: baseline;
  }
  .search-literature-filter-link {
    border: 0;
    background: transparent;
    color: var(--tint);
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    padding: 0;
  }
  .search-literature-filter-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 8px;
  }
  .search-literature-filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-grouped);
    color: var(--text-secondary);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    padding: 7px 10px;
  }
  .search-literature-filter-chip.is-active {
    background: color-mix(in srgb, var(--tint) 12%, var(--bg-cell));
    border-color: color-mix(in srgb, var(--tint) 38%, var(--border));
    color: var(--tint);
  }
  .search-literature-filter-chip-icon {
    width: 16px;
    height: 16px;
    flex: 0 0 auto;
  }
  .search-result-book-icons {
    display: flex;
    gap: 6px;
    align-items: center;
    flex: 0 0 auto;
  }
  .search-result-book-icon {
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
  }
  .search-result-primary-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
  }
  .search-result-primary-row > .primary {
    min-width: 0;
    flex: 1 1 auto;
  }

  main#list {
    /* Horizontal padding matches --marg-allGroup-h0 (page edge to
       outermost group). Top padding matches --marg-path-v2 so the
       gap below the breadcrumb (or app bar, on root) is tunable. */
    flex: 1;
    padding-bottom: calc(76px + env(safe-area-inset-bottom));
    padding: var(--marg-path-v2) var(--marg-allGroup-h0)
             calc(28px + env(safe-area-inset-bottom));
  }
  body.search-page-open main#list {
    padding-top: 0;
  }
  body.map-page-open main#list {
    padding-top: 0;
  }
  /* Strip the first child's leading margin so it doesn't double up
     against the padding-top above. */
  main#list > .minor-group:first-child,
  main#list > .group:first-child { margin-top: 0; }

  /* Breadcrumb trail. Each crumb is a 3-row column:
       common name (top, link color)
       scientific name (middle, italic, fainter)
       rank label   (bottom, smallest, uppercase, centered) */
  nav.breadcrumb {
    display: flex; align-items: stretch; gap: 2px;
    /* Top: gap from app bar (--marg-path-v1).
       Bottom: nav-internal gap before crumb labels (kept fixed). */
    padding: var(--marg-path-v1) 4px 8px;
    overflow-x: auto; overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    white-space: nowrap;
  }
  nav.breadcrumb::-webkit-scrollbar { display: none; }
  .crumb {
    background: transparent; border: 0; padding: 3px 6px;
    font: inherit; cursor: pointer;
    border-radius: 6px; white-space: nowrap;
    max-width: 180px;
    display: inline-flex; flex-direction: column; align-items: center;
    line-height: 1.15; text-align: center;
  }
  .crumb .crumb-common {
    font-size: var(--font-bc-common); color: var(--tint);
    overflow: hidden; text-overflow: ellipsis; max-width: 100%;
    font-weight: 500;
  }
  .crumb .crumb-name {
    font-size: var(--font-bc-name); color: var(--text-secondary);
    overflow: hidden; text-overflow: ellipsis; max-width: 100%;
    font-style: italic;
  }
  .crumb .crumb-rank {
    font-size: var(--font-bc-rank); color: var(--text-tertiary);
    margin-top: 1px; letter-spacing: 0.06em;
    text-transform: uppercase; font-weight: 500;
  }
  .crumb:active { background: var(--badge-bg); }
  .crumb.current { cursor: default; }
  .crumb.current .crumb-common {
    color: var(--text-secondary);
  }
  .crumb.current:active { background: transparent; }
  .crumb.home {
    padding: 3px 6px;
    display: inline-flex; flex-direction: row; align-items: center;
    color: var(--tint);
  }
  .crumb.home::before {
    content: ""; width: 14px; height: 14px; display: inline-block;
    background: currentColor;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M2 7.25 8 2l6 5.25v6.5a1 1 0 0 1-1 1h-3.5V10.5h-3v4.25H3a1 1 0 0 1-1-1v-6.5Zm6-3.85-4.9 4.28V13h2.4V9.75h5V13h2.4V7.68L8 3.4Z'/></svg>") center/contain no-repeat;
    mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='black' d='M2 7.25 8 2l6 5.25v6.5a1 1 0 0 1-1 1h-3.5V10.5h-3v4.25H3a1 1 0 0 1-1-1v-6.5Zm6-3.85-4.9 4.28V13h2.4V9.75h5V13h2.4V7.68L8 3.4Z'/></svg>") center/contain no-repeat;
  }
  .crumb-sep {
    color: var(--text-tertiary); font-size: 13px; padding: 0 1px;
    user-select: none;
    display: inline-flex; align-items: center;
  }

  /* Description: no card. Sits directly on the page background.
     First 4 lines visible; tap anywhere in the block to expand. */
  .description {
    padding: 4px 4px 14px;
    margin: 4px 0 10px;
    font-size: 14px;
    line-height: 1.45;
    color: var(--text);
    cursor: default;
    position: relative;
  }
  .desc-text {
    /* Each paragraph is its own block; the description is clamped via
       max-height in the collapsed state so multi-paragraph + section-
       heading content all collapse together. */
    overflow: hidden;
    max-height: calc(1.45em * 4 + 2px);
    position: relative;
  }
  .description[data-expanded="true"] .desc-text {
    max-height: none;
    overflow: visible;
  }
  .desc-para {
    white-space: pre-wrap;
    margin: 0 0 0.85em;
    text-indent: 2em;
  }
  .desc-para:last-child { margin-bottom: 0; }
  .desc-loading {
    color: var(--text-tertiary);
    font-style: italic;
  }
  .desc-wiki-preview {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 6;
    overflow: hidden;
  }
  .desc-heading {
    font-size: 15px;
    font-weight: 600;
    color: var(--text);
    margin: 1.1em 0 0.45em;
    line-height: 1.3;
  }
  .desc-heading:first-child { margin-top: 0; }
  /* Subtle "more" affordance under the clamped text */
  .desc-more {
    display: inline-block;
    margin-top: 6px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--tint);
    font-weight: 500;
    font: inherit;
    font-size: 12px;
    user-select: none;
    cursor: pointer;
  }
  .desc-wiki-link {
    display: inline-block;
    margin-top: 8px;
    margin-left: 12px;
    color: var(--tint);
    text-decoration: none;
    font-size: 13px;
    font-weight: 500;
  }
  .desc-wiki-link:active { opacity: 0.6; }
  .description[data-source="synth"] {
    color: var(--text-secondary);
    font-style: italic;
  }

  /* "Show all species" button: surfaces every species card under the
     current taxon's subtree on a tap. Lives between the description and
     the children list. Styled like a simple text action row. */
  .show-all-species-btn {
    display: flex;
    width: 100%;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 14px 16px;
    margin: 8px 0 14px;
    border: 1px solid color-mix(in srgb, var(--tint) 22%, var(--border));
    border-radius: 18px;
    background: var(--show-all-species-bg);
    color: var(--tint);
    font: inherit;
    font-size: 16px;
    font-weight: 700;
    cursor: pointer;
    text-align: left;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
  }
  .show-all-species-btn:active {
    opacity: 1;
    transform: translateY(1px);
    background: var(--show-all-species-bg);
  }
  .show-all-species-label::after {
    content: " \203A";
    font-weight: 700;
  }
  .show-all-species-meta {
    color: var(--text-secondary);
    font-weight: 600;
    font-size: 13px;
  }

  /* Minor-rank grouping. The wrapper is a flex column holding two
     children: a tab (legend) and the body (.group). */

  /* === EDIT HERE: spacing + font-size + color knobs ============
     Variable names match the labels in the annotated screenshot
     (`marg_<area><axis><n>`). After editing any value, re-run
     `python build_taxonomy_viewer.py` to regenerate the HTML. */
  :root {
    --marg-title-v1: 0px;          /* vertical inset ABOVE the app-bar text */
    --marg-title-v2: 0px;          /* vertical inset BELOW the app-bar text (gap before content) */
    --marg-path-v1: 6px;          /* vertical gap between app bar and the breadcrumb */
    --marg-path-v2: 6px;           /* vertical gap below the breadcrumb (to first card) */

    --marg-allGroup-v0: 10px;      /* gap between SIBLING top-level groups */
    --marg-allGroup-v1: 4px;       /* gap above each nested ring (margin-top of every group) */
    --marg-allGroup-v2: 6px;       /* body padding-top â€” visible "lip" below each pill */
    --marg-allGroup-v3: 6px;       /* vertical gap between species cards in a row */
    --marg-allGroup-v4: 8px;       /* body padding-bottom â€” lip above each box's bottom edge */
    --marg-allGroup-v5: 0px;       /* extra padding-bottom on the outermost group only */

    --marg-allGroup-h0: 4px;      /* page-edge to outermost group (left + right) */
    --marg-allGroup-h1: 2px;       /* horizontal indent each nested ring takes from its parent */
    --marg-allGroup-h2: 4px;       /* body padding-left/right â€” gap inside each ring */
    --marg-allGroup-h3: 6px;       /* horizontal gap between species cards in a row */

    --marg-popup-book-h: 8px;      /* horizontal gap from popup card edge to content (book tab) */
    --marg-popup-book-text-h: 6px; /* horizontal gap from blue book-section bubble edge to its inner text (book tab) */
    --marg-popup-wiki-h: 8px;     /* horizontal gap from popup card edge to content (wiki tab) */
    --marg-popup-obs-h: 8px;      /* horizontal gap from popup card edge to content (observations tab) */

    --font-app-title: 17px;        /* the page title text in the app bar (e.g. "All species") */
    --font-app-subtitle: 11px;     /* app-bar subtitle line ("Under Plants Â· 224 species ...") */
    --font-bc-common: 13px;        /* breadcrumb common-name text (top of crumb) */
    --font-bc-name: 12px;          /* breadcrumb scientific-name text (italic, middle) */
    --font-bc-rank: 9px;           /* breadcrumb RANK label (small caps, bottom) */
    --font-rank-label: 9px;        /* "PHYLUM"/"CLASS"/etc. RANK label on every pill */
    --font-sci-name: 12px;         /* italic scientific name shown on each pill */
    --font-common-name: 13px;      /* tinted/clickable common name shown on each pill */
    --font-row-primary: 16px;      /* primary text in a taxon-page table row */
    --font-row-secondary: 13px;    /* secondary text below the primary in each row */
    --font-card-common: 13px;      /* common-name overlay at TOP of each species card */
    --font-card-sci: 13px;         /* sci-name overlay at BOTTOM of each species card */
    --font-section-header: 13px;   /* uppercase section header (e.g. "NEEDS ID") */

    --color-kingdom: #ffffff;      /* fill for the kingdom-rank ring (light-theme default) */
    --color-phylum:  #f2f2f7;      /* fill for the phylum-rank ring */
    --color-subphylum: #ececf1;     /* fill for the subphylum-rank ring */
    --color-class:   #ffffff;      /* fill for the class-rank ring */
    --color-subclass: #ececf1;     /* fill for the subclass-rank ring */
    --color-order:   #f2f2f7;      /* fill for the order-rank ring */
    --color-suborder: #ececf1;     /* fill for the suborder-rank ring */
    --color-superfamily: #e4e4ea;  /* fill for the superfamily-rank ring */
    --color-family:  #ffffff;      /* fill for the family-rank ring */
    --color-subfamily: #ececf1;    /* fill for the subfamily-rank ring */
    --color-tribe:   #e4e4ea;      /* fill for the tribe-rank ring */
    --color-subtribe: #dcdce2;     /* fill for the subtribe-rank ring */
    --color-genus:   #f2f2f7;      /* fill for the genus-rank ring */
    --color-subgenus: #ececf1;     /* fill for the subgenus-rank ring */
    --color-other:   #ffffff;      /* fill for minor ranks (tribe/subphylum/etc.) */

    /* Backwards-compat aliases â€” older CSS rules still use the short names. */
    --v0-margin: var(--marg-allGroup-v0);
    --v1-margin: var(--marg-allGroup-v1);
    --v2-margin: var(--marg-allGroup-v2);
    --h1-margin: var(--marg-allGroup-h1);
    --h2-margin: var(--marg-allGroup-h2);
  }
  .minor-group {
    /* No top/bottom margin by default â€” the spacing variables below
       (V0/V1/V2) each target ONE specific dimension via more specific
       selectors so changing one doesn't leak into the others. */
    margin: 0 var(--marg-allGroup-h1) 0 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;        /* tab shrink-wraps; body stretches */
    min-width: 0;
  }
  /* V0: gap between SIBLING groups at the same nesting level. */
  .minor-group + .minor-group { margin-top: var(--marg-allGroup-v0); }
  /* V1: gap between a parent pill and its FIRST nested-rank child pill. */
  .minor-group > .group > .minor-group { margin-top: var(--marg-allGroup-v1); }
  /* V0 again, but more specific so it overrides V1 for nested SIBLINGS
     (the rule above matches subsequent siblings too via the .minor-group
     selector â€” without this override, V1 wins by specificity and V0
     does nothing). */
  .minor-group > .group > .minor-group + .minor-group {
    margin-top: var(--marg-allGroup-v0);
  }
  /* V2: gap between the DEEPEST pill and the species cards inside it. */
  .minor-group > .group > .species-grid { margin-top: var(--marg-allGroup-v2); }
  .minor-group-legend {
    /* Default to the same fill as a standalone card-list .group, so a
       minor-rank subgroup (tribe, subphylum, etc.) blends in seamlessly
       with the surrounding cards. Per-rank rules below override this
       only for the recognized major ranks. */
    background: var(--bg-cell);
    border-top-left-radius: 999px;
    border-top-right-radius: 999px;
    padding: 3px 12px 4px;
    margin-left: 0;
    margin-bottom: 0;
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    gap: 4px;
    line-height: 1.1;
    text-align: left;
    white-space: nowrap;
    color: var(--text-tertiary);
    overflow: hidden;
    max-width: calc(100% - 28px);
    border-bottom-left-radius: 0;
  }
  .minor-group-collapse {
    position: absolute;
    inset: 0;
    background: transparent;
    border: 0;
    padding: 0;
    margin: 0;
    opacity: 0;
    cursor: pointer;
    z-index: 1;
  }
  .minor-group > .group {
    align-self: stretch;             /* body fills full wrapper width */
    border-radius: var(--radius);
    border-top-left-radius: 0;
    background: var(--bg-cell);     /* matches standalone .group */
    /* Top padding is 0 â€” the V1/V2 lip below each pill comes from the
       FIRST child's margin-top, so V1 and V2 each control exactly
       one place. V4 sets the bottom lip on non-deepest bodies only. */
    padding: 0 var(--marg-allGroup-h2) var(--marg-allGroup-v4);
    margin: 0;
  }
  /* V3: padding-bottom of the DEEPEST body (gap between the species
     cards and the deepest body's bottom edge â€” what's labeled V3 in
     the annotated screenshot). This overrides V4 for the deepest
     body so V4 is non-deepest only â€” they never bleed into each
     other. (Row-gap of the species grid uses V3 too, since it's the
     same conceptual "gap below cards" knob.) */
  .minor-group > .group:has(> .species-grid) {
    padding-bottom: var(--marg-allGroup-v3);
  }
  /* Outermost group's body gets the extra V5 padding-bottom on top of
     V4 â€” its colored strip extends a bit further at the page bottom. */
  main#list > .minor-group > .group {
    padding-bottom: calc(var(--marg-allGroup-v4) + var(--marg-allGroup-v5));
  }
  /* Outermost group's body that's also the deepest (single-level
     all_species view): V3 + V5 (deepest gets V3, plus extra V5 for
     outermost). V4 is suppressed since it's a deepest body. */
  main#list > .minor-group > .group:has(> .species-grid) {
    padding-bottom: calc(var(--marg-allGroup-v3) + var(--marg-allGroup-v5));
  }
  /* Per-rank fill â€” both tab and body draw from the rank stamped on
     the wrapper via data-rank. The minor-group wrapper's data-rank is
     set by the JS to whichever rank the legend's tab is showing. */
  .minor-group[data-rank="kingdom"] > .group,
  .minor-group[data-rank="kingdom"] > .minor-group-legend { background: var(--color-kingdom); }
  .minor-group[data-rank="phylum"] > .group,
  .minor-group[data-rank="phylum"] > .minor-group-legend { background: var(--color-phylum); }
  .minor-group[data-rank="subphylum"] > .group,
  .minor-group[data-rank="subphylum"] > .minor-group-legend { background: var(--color-subphylum); }
  .minor-group[data-rank="class"] > .group,
  .minor-group[data-rank="class"] > .minor-group-legend { background: var(--color-class); }
  .minor-group[data-rank="subclass"] > .group,
  .minor-group[data-rank="subclass"] > .minor-group-legend { background: var(--color-subclass); }
  .minor-group[data-rank="order"] > .group,
  .minor-group[data-rank="order"] > .minor-group-legend { background: var(--color-order); }
  .minor-group[data-rank="suborder"] > .group,
  .minor-group[data-rank="suborder"] > .minor-group-legend { background: var(--color-suborder); }
  .minor-group[data-rank="superfamily"] > .group,
  .minor-group[data-rank="superfamily"] > .minor-group-legend { background: var(--color-superfamily); }
  .minor-group[data-rank="family"] > .group,
  .minor-group[data-rank="family"] > .minor-group-legend { background: var(--color-family); }
  .minor-group[data-rank="subfamily"] > .group,
  .minor-group[data-rank="subfamily"] > .minor-group-legend { background: var(--color-subfamily); }
  .minor-group[data-rank="tribe"] > .group,
  .minor-group[data-rank="tribe"] > .minor-group-legend { background: var(--color-tribe); }
  .minor-group[data-rank="subtribe"] > .group,
  .minor-group[data-rank="subtribe"] > .minor-group-legend { background: var(--color-subtribe); }
  .minor-group[data-rank="genus"] > .group,
  .minor-group[data-rank="genus"] > .minor-group-legend { background: var(--color-genus); }
  .minor-group[data-rank="subgenus"] > .group,
  .minor-group[data-rank="subgenus"] > .minor-group-legend { background: var(--color-subgenus); }

  /* Regular browsing pages use a calmer, more generic grouped-card look.
     The colorful per-rank ring fills are reserved for the dedicated
     "All species" view. */
  main#list.browse-view .minor-group > .group,
  main#list.browse-view .minor-group > .minor-group-legend {
    background: var(--browse-group-bg);
  }
  main#list.browse-view .minor-group > .group {
    border: 1px solid var(--border);
    box-shadow: 0 6px 14px rgba(0, 0, 0, 0.04);
  }
  main#list.browse-view .minor-group > .minor-group-legend {
    color: var(--text-secondary);
    border: 1px solid var(--border);
    border-bottom: 0;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.03);
  }
  /* RANK label â€” same style as .crumb-rank in the breadcrumb. */
  .minor-group-rank {
    font-size: var(--font-rank-label);
    color: var(--text-tertiary);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    font-weight: 500;
  }
  /* Scientific name â€” italic muted, like .crumb-name. */
  .minor-group-sci {
    font-size: var(--font-sci-name);
    font-style: italic;
    color: var(--text-secondary);
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
  }
  /* Clickable common name â€” tinted/medium, like .crumb-common. */
  .minor-group-name {
    font: inherit;
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
    color: var(--tint);
    font-size: var(--font-common-name);
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    position: relative;
    z-index: 2;
  }
  .minor-group-name:active { opacity: 0.6; }
  /* Invisible hit area for collapsing a subgroup without showing a chevron. */
  /* Collapse/expand chevron â€” only major-rank groups (all_species view)
     get one. The chevron rotates 90Â° when its group is collapsed. */
  .minor-group.collapsed > .group { display: none; }
  /* When collapsed, the tab is a standalone pill â€” round its bottom
     corners too so it reads as a full oval, not a tab with a flat base. */
  .minor-group.collapsed > .minor-group-legend {
    border-bottom-left-radius: 999px;
    border-bottom-right-radius: 999px;
  }

  /* === Sticky breadcrumb overlay (all-species view) ===
     The original pills stay as plain natural-flow tabs on their boxes.
     A SEPARATE overlay sits fixed below the app header and gets
     populated by JS as the user scrolls. It clones the legend of
     whichever major-rank group is currently behind the viewport top
     for each rank â€” kingdom, phylum, class, order, family, genus â€”
     stacked vertically. This decouples the visual layout from the
     scroll feedback, so the original layout matches screenshot 2 and
     the overlay reads cleanly on top. */
  #sticky-overlay {
    position: fixed;
    top: calc(var(--header-h) + env(safe-area-inset-top, 0px) - 12px + var(--search-bar-h, 0px));
    left: 0;
    right: 0;
    width: min(560px, 100%);
    margin: 0 auto;
    z-index: 60;
    pointer-events: none;
    /* Page bg fills the overlay area so cards never bleed through the
       gap above/around the rank boxes. Since this is the same color
       the natural-flow page paints around its boxes, the overlay is
       visually indistinguishable from the page bg outside the boxes â€”
       the user perceives ONLY the rank-colored boxes as the overlay. */
    background: var(--bg-grouped);
    /* Match main#list's horizontal padding so the outermost overlay
       box lines up with the outermost in-page box below. */
    padding: 0 var(--marg-allGroup-h0);
  }
  #sticky-overlay[hidden] { display: none; }
  /* The overlay reuses the natural .minor-group / .group structure so
     it renders as a stack of nested boxes with pill tabs on top â€”
     identical to the in-page layout, just floating below the app
     header. JS clones each active major-group's pill into a fresh
     wrapper and nests subsequent ranks inside its empty body, so the
     boxes step down and to the right just like the page below. */
  .overlay-level {
    pointer-events: auto;
    transition: transform 150ms ease-out, opacity 150ms ease-out;
    will-change: transform, opacity;
  }
  /* No extra tail on intermediate overlay levels. */
  .overlay-body {
    padding-bottom: 0 !important;
  }
  /* Square the bottom corners on every overlay box so the colored
     strips below the pills end in clean vertical edges, not rounded
     curves that show the parent rank's color at the corners. The
     natural padding-top on each body still produces the bottom strip
     itself; only the corner shape changes. */
  .overlay-level > .group {
    border-bottom-left-radius: 0 !important;
    border-bottom-right-radius: 0 !important;
  }
  /* Chevron in the cloned legend stays visible â€” clicking it toggles
     the collapsed state of the SOURCE group (and the clone reflects
     the same .collapsed class for consistent rotation). */
  /* Major-rank nested groups (used by the all_species view) share the
     minor-group layout exactly â€” the only override below is the margin
     override is dropped because the new flex-based layout already has
     consistent spacing. */

  /* Popup modal for minor-rank Wikipedia descriptions. */
  .popup-backdrop {
    --popup-pad: 12px;
    --popup-card-radius: 30px;
    --popup-card-pad-x: 18px;
    --popup-card-pad-top: 18px;
    --popup-card-pad-bottom: 14px;
    --popup-scroll-margin-top: 4px;
    --popup-scroll-margin-bottom: 4px;
    --popup-scroll-pad-right: 8px;
    --popup-header-gap: 12px;
    --popup-header-margin-bottom: 8px;
    --popup-body-margin-top: 8px;
    --popup-link-margin-top: 6px;
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 100;
    display: flex; align-items: flex-start; justify-content: center;
    padding-left: var(--popup-pad);
    padding-right: var(--popup-pad);
    padding-top: calc(var(--header-h) + env(safe-area-inset-top) - 2px);
    padding-bottom: env(safe-area-inset-bottom);
  }
  #bottom-nav {
    position: sticky;
    bottom: 0;
    z-index: 24;
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 6px;
    padding: 8px 10px calc(8px + env(safe-area-inset-bottom));
    margin-bottom: calc(-1 * env(safe-area-inset-bottom));
    background: var(--bg-header);
    backdrop-filter: saturate(180%) blur(18px);
    -webkit-backdrop-filter: saturate(180%) blur(18px);
    border-top: 0.5px solid var(--border);
  }
  #bottom-nav button {
    position: relative;
    background: transparent;
    border: 0;
    color: var(--text-tertiary);
    min-height: 44px;
    border-radius: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font: inherit;
  }
  #bottom-nav button::before {
    content: "";
    display: block;
    width: 22px;
    height: 22px;
    background: currentColor;
  }
  #bottom-nav button.is-active {
    color: var(--tint);
    background: color-mix(in srgb, var(--tint) 10%, transparent);
  }
  #bottom-nav button:active {
    opacity: 0.8;
  }
  #bottom-nav #notification-btn.has-unread::after {
    top: 7px;
    right: calc(50% - 18px);
  }
  body.popup-open {
    overflow: hidden;
    overscroll-behavior: none;
    touch-action: none;
  }
  .popup-card {
    background: var(--bg-cell);
    color: var(--text);
    border-radius: var(--popup-card-radius);
    max-width: 620px;
    width: 100%;
    max-height: calc(100dvh - (var(--header-h) + env(safe-area-inset-top) + env(safe-area-inset-bottom)));
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: var(--popup-card-pad-top) var(--popup-card-pad-x) var(--popup-card-pad-bottom);
    box-shadow: 0 10px 40px rgba(0,0,0,0.5);
  }
  .popup-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-y;
  }
  .popup-scroll button, .popup-scroll input, .popup-scroll label {
    touch-action: manipulation;
  }
  .popup-scroll {
    margin-top: var(--popup-scroll-margin-top);
    margin-bottom: var(--popup-scroll-margin-bottom);
    margin-left: calc(-1 * var(--popup-card-pad-x));
    margin-right: calc(-1 * var(--popup-card-pad-x));
    padding-left: var(--popup-card-pad-x);
    padding-right: calc(var(--popup-card-pad-x) + var(--popup-scroll-pad-right));
    scrollbar-gutter: stable;
  }
  .popup-scroll {
    scrollbar-width: none;
    padding-right: var(--popup-card-pad-x);
  }
  .popup-scroll::-webkit-scrollbar {
    display: none;
  }
  .popup-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    padding: 0;
    margin-bottom: 10px;
  }
  /* Top row (Observations / Map / Wiki) always fits on one line */
  .popup-tabs-top {
    flex-wrap: nowrap;
  }
  .popup-tabs-top .popup-tab {
    flex: 1 1 0;
    min-width: 0;
    padding: 9px 6px;
    font-size: 12px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .popup-tab {
    flex: 1 1 120px;
    min-width: 120px;
    border: 1px solid rgba(127, 127, 127, 0.14);
    border-radius: 999px;
    padding: 9px 12px;
    background: linear-gradient(180deg, rgba(255,255,255,0.92), rgba(241,241,245,0.84));
    color: var(--text-secondary);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    letter-spacing: 0.01em;
    transition: background-color 140ms ease, color 140ms ease, box-shadow 140ms ease, transform 140ms ease, border-color 140ms ease;
  }
  .popup-tab[aria-pressed="true"] {
    background: linear-gradient(180deg, rgba(98, 98, 106, 0.86), rgba(71, 71, 77, 0.94));
    color: #fff;
    border-color: rgba(255,255,255,0.12);
    box-shadow: 0 4px 12px rgba(0,0,0,0.14), inset 0 1px 0 rgba(255,255,255,0.10);
    transform: translateY(-1px);
  }
  .popup-tab:not([aria-pressed="true"]):hover {
    background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(245,245,248,0.92));
    border-color: rgba(127, 127, 127, 0.20);
    color: var(--text);
  }
  .popup-tab:active { transform: translateY(0); }
  .popup-panel[hidden] { display: none; }
  .popup-panel {
    padding-top: 0;
  }
.popup-book {
    font-size: 14px;
    line-height: 1.5;
    color: var(--text);
    display: flex;
    flex-direction: column;
    gap: 12px;
    /* Break out of the popup-scroll's left/right padding (which mirrors
       --popup-card-pad-x) so the book-section bubble can extend all the
       way to the popup card edge, then re-pad by --marg-popup-book-h.
       That variable is the sole knob for the book tab's side gap. */
    margin-left: calc(-1 * var(--popup-card-pad-x));
    margin-right: calc(-1 * var(--popup-card-pad-x));
    padding-left: var(--marg-popup-book-h);
    padding-right: var(--marg-popup-book-h);
  }
  .popup-book-section {
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
  .popup-book-section {
    /* Horizontal padding is driven solely by --marg-popup-book-text-h
       so the gap between the blue bubble edge and the inner text is a
       single knob. Vertical padding is kept fixed. */
    padding: 10px var(--marg-popup-book-text-h) 12px;
    border: 1px solid var(--border);
    border-radius: 18px;
    background: var(--book-section-bg);
  }
  .popup-book-section-head {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 0 10px;
  }
  .popup-book-section-title {
    color: var(--text);
    font-size: 15px;
    font-weight: 800;
    line-height: 1.15;
    margin: 0;
  }
  .popup-book-section-body[hidden] { display: none; }
  /* Non-collapsible inline subheading used by short-entry books like
     Trees & Shrubs of PNW to break up a single body paragraph into
     LEAVES / FLOWERS / FRUIT / CONES / ECOLOGY visual blocks. Line height
     and bottom margin are pulled tight so the body paragraph following
     the heading sits directly under it (single-spaced). */
  .popup-book-inline-heading {
    color: var(--text);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
    line-height: 1.2;
    margin: 10px 0 0;
  }
  .popup-book-inline-heading:first-child { margin-top: 0; }
  /* When a paragraph immediately follows the inline heading, drop its
     top margin so the gap matches a normal line break. */
  .popup-book-inline-heading + .desc-para { margin-top: 0; }
  .popup-wiki {
    font-size: 14px;
    line-height: 1.55;
    color: var(--text);
    display: flex;
    flex-direction: column;
    gap: 14px;
    /* Break out of the popup-scroll's left/right padding (which mirrors
       --popup-card-pad-x) so the wiki content can extend to the popup
       card edge, then re-pad by --marg-popup-wiki-h. That variable is
       the sole knob for the wiki tab's side gap. */
    margin-left: calc(-1 * var(--popup-card-pad-x));
    margin-right: calc(-1 * var(--popup-card-pad-x));
    padding-left: var(--marg-popup-wiki-h);
    padding-right: var(--marg-popup-wiki-h);
    overflow-x: hidden;
  }
  .popup-wiki .wiki-shell {
    overflow: hidden;
    width: 100%;
    min-width: 0;
    align-self: stretch;
  }
  .popup-wiki .wiki-article {
    /* Vertical padding only â€” horizontal spacing is owned entirely by
       --marg-popup-wiki-h on .popup-wiki. Both regular and iPhone
       preview modes use the same rule so the variable controls them
       both. */
    padding: 18px 0;
    width: 100%;
    min-width: 0;
    align-self: stretch;
  }
  .popup-wiki .wiki-article-title {
    font-size: 34px;
    line-height: 1.08;
    font-weight: 850;
    margin: 0;
  }
  .popup-wiki .wiki-article-common {
    font-size: 18px;
    line-height: 1.3;
    color: var(--text-secondary);
    font-style: italic;
    margin: 6px 0 0;
  }
  .popup-wiki .wiki-link {
    display: inline-block;
    margin-top: 12px;
    color: var(--tint);
    text-decoration: none;
    font-size: 17px;
    font-weight: 700;
  }
  .popup-wiki .wiki-article-body {
    margin-top: 12px;
    line-height: 1.65;
    font-size: 15px;
    width: 100%;
    min-width: 0;
    align-self: stretch;
    overflow-x: hidden;
  }
  .popup-wiki .wiki-article-body::after {
    content: "";
    display: block;
    clear: both;
  }
  .popup-wiki .wiki-article-body > :first-child {
    margin-top: 0;
  }
  .popup-wiki .wiki-article-body p {
    margin: 0 0 0.72em;
  }
  .popup-wiki .wiki-article-body ul,
  .popup-wiki .wiki-article-body ol {
    margin: 0 0 0.9em 1.4em;
    padding: 0;
  }
  .popup-wiki .wiki-article-body li {
    margin: 0.2em 0;
  }
  .popup-wiki .wiki-article-body h2,
  .popup-wiki .wiki-article-body h3,
  .popup-wiki .wiki-article-body h4 {
    line-height: 1.2;
    margin: 1em 0 0.45em;
  }
  .popup-wiki .wiki-article-body h2 {
    font-size: 24px;
    font-weight: 850;
  }
  .popup-wiki .wiki-article-body h3 {
    font-size: 18px;
    font-weight: 800;
  }
  .popup-wiki .wiki-article-body h4 {
    font-size: 16px;
    font-weight: 750;
  }
  .popup-wiki .wiki-article-body table {
    border-collapse: collapse;
  }
  .popup-wiki .wiki-article-body table.infobox,
  .popup-wiki .wiki-article-body table.sidebar,
  .popup-wiki .wiki-article-body table.taxobox,
  .popup-wiki .wiki-article-body table.biota {
    /* Fill the available wiki content width so the infobox and the
       collapsible sections below it line up with the popup's right edge. */
    display: table;
    float: none;
    clear: both;
    width: 100% !important;
    max-width: none;
    table-layout: fixed;
    margin: 0 0 18px;
    border: 1px solid var(--border);
    border-radius: 16px;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.82);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
    font-size: 13px;
    box-sizing: border-box;
  }
  .popup-wiki .wiki-article-body table.infobox th,
  .popup-wiki .wiki-article-body table.infobox td,
  .popup-wiki .wiki-article-body table.sidebar th,
  .popup-wiki .wiki-article-body table.sidebar td,
  .popup-wiki .wiki-article-body table.taxobox th,
  .popup-wiki .wiki-article-body table.taxobox td,
  .popup-wiki .wiki-article-body table.biota th,
  .popup-wiki .wiki-article-body table.biota td {
    padding: 6px 10px;
    border-top: 1px solid rgba(60, 60, 67, 0.10);
    vertical-align: top;
    box-sizing: border-box;
    overflow-wrap: anywhere;
    word-break: break-word;
  }
  .popup-wiki .wiki-article-body table.infobox td[colspan="2"] > span:only-child,
  .popup-wiki .wiki-article-body table.infobox td[colspan="2"] > div:only-child,
  .popup-wiki .wiki-article-body table.infobox td[colspan="2"] > figure:only-child {
    display: block;
    text-align: center;
  }
  .popup-wiki .wiki-article-body table.infobox td[colspan="2"] > span:only-child img,
  .popup-wiki .wiki-article-body table.infobox td[colspan="2"] > div:only-child img,
  .popup-wiki .wiki-article-body table.infobox td[colspan="2"] > figure:only-child img {
    margin-left: auto;
    margin-right: auto;
  }
  .popup-wiki .wiki-article-body table.infobox th,
  .popup-wiki .wiki-article-body table.sidebar th,
  .popup-wiki .wiki-article-body table.taxobox th,
  .popup-wiki .wiki-article-body table.biota th {
    font-weight: 700;
    text-align: left;
    background: rgba(216, 214, 178, 0.40);
  }
  .popup-wiki .wiki-collapse-group {
    width: 100%;
    max-width: none;
    margin: 0.8em 0 0;
    border-top: 1px solid rgba(60, 60, 67, 0.12);
    padding-top: 0.6em;
  }
  .popup-wiki .wiki-collapse-head {
    width: 100%;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 0.75em;
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    position: relative;
  }
  .popup-wiki .wiki-collapse-caret {
    flex: 0 0 auto;
    width: 0;
    height: 0;
    margin-top: 0.55em;
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
    border-top: 8px solid var(--text-secondary);
    transition: transform 0.15s ease;
  }
  .popup-wiki .wiki-collapse-title {
    flex: 1 1 auto;
    font-size: 24px;
    font-weight: 900;
    line-height: 1.02;
    color: var(--text);
    min-width: 0;
  }
  .popup-wiki .wiki-collapse-level-3 .wiki-collapse-title {
    font-size: 18px;
    font-weight: 800;
    line-height: 1.06;
  }
  .popup-wiki .wiki-collapse-level-4 .wiki-collapse-title {
    font-size: 16px;
    font-weight: 750;
    line-height: 1.06;
  }
  .popup-wiki .wiki-collapse-level-3 > .wiki-collapse-head {
    padding-left: 18px;
  }
  .popup-wiki .wiki-collapse-level-4 > .wiki-collapse-head {
    padding-left: 30px;
  }
  .popup-wiki .wiki-collapse-group .wiki-collapse-head[aria-expanded="false"] .wiki-collapse-caret {
    transform: rotate(-90deg);
  }
  .popup-wiki .wiki-collapse-group .wiki-collapse-body[hidden] {
    display: none;
  }
  .popup-wiki .wiki-article-body table.infobox.biota .wiki-taxobox-toggle {
    cursor: pointer;
  }
  .popup-wiki .wiki-article-body table.infobox.biota .wiki-taxobox-section-row-hidden {
    display: none !important;
  }
  .popup-wiki .wiki-article-body table.infobox.biota .wiki-taxobox-section-collapsed > th,
  .popup-wiki .wiki-article-body table.infobox.biota .wiki-taxobox-section-collapsed > td {
    background: rgba(188, 246, 187, 0.75);
  }
  .popup-wiki .wiki-collapse-group:hover .wiki-collapse-caret {
    border-top-color: var(--text);
  }
  .popup-wiki .wiki-article-body .mw-editsection,
  .popup-wiki .wiki-article-body .reference,
  .popup-wiki .wiki-article-body sup.reference,
  .popup-wiki .wiki-article-body .noprint,
  .popup-wiki .wiki-article-body .metadata,
  .popup-wiki .wiki-article-body .shortdescription,
  .popup-wiki .wiki-article-body .hatnote,
  .popup-wiki .wiki-article-body .navbox,
  .popup-wiki .wiki-article-body .navbox-styles,
  .popup-wiki .wiki-article-body .mw-references-wrap,
  .popup-wiki .wiki-article-body .reflist,
  .popup-wiki .wiki-article-body .references {
    display: none !important;
  }
  .popup-wiki .wiki-article-body figure,
  .popup-wiki .wiki-article-body .thumb,
  .popup-wiki .wiki-article-body .thumbinner,
  .popup-wiki .wiki-article-body .thumbcaption {
    box-sizing: border-box;
  }
  .popup-wiki .wiki-article-body figure,
  .popup-wiki .wiki-article-body table.thumb {
    max-width: 100%;
    margin: 0.35em auto 0.8em;
    display: block;
    text-align: center;
  }
  .popup-wiki .wiki-article-body table.thumb.tright,
  .popup-wiki .wiki-article-body figure.tright,
  .popup-wiki .wiki-article-body .mw-halign-right,
  .popup-wiki .wiki-article-body .mw-float-right,
  .popup-wiki .wiki-article-body table.thumb.tleft,
  .popup-wiki .wiki-article-body figure.tleft,
  .popup-wiki .wiki-article-body .mw-halign-left,
  .popup-wiki .wiki-article-body .mw-float-left {
    float: none;
    clear: none;
    margin: 0.35em auto 0.8em;
  }
  .popup-wiki .wiki-article-body .thumbinner {
    display: inline-block;
    padding: 4px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: rgba(255, 255, 255, 0.82);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.10);
    max-width: 100%;
  }
  .popup-wiki .wiki-article-body .thumbinner img,
  .popup-wiki .wiki-article-body figure img,
  .popup-wiki .wiki-article-body img.mw-file-element {
    display: block;
    max-width: 100%;
    height: auto;
    margin: 0 auto;
  }
  .popup-wiki .wiki-article-body .thumbcaption,
  .popup-wiki .wiki-article-body figcaption {
    padding: 6px 8px 2px;
    font-size: 12px;
    line-height: 1.35;
    color: var(--text-secondary);
  }
  .popup-wiki .wiki-article-body .gallery {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin: 0.8em 0;
    align-items: start;
    justify-content: flex-start;
    padding-left: 0;
    list-style: none;
  }
  .popup-wiki .wiki-article-body .gallerybox {
    margin: 0;
    flex: 0 1 200px;
    min-width: 160px;
    max-width: 220px;
    border-radius: 14px;
    overflow: hidden;
    background: var(--bg-panel);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.10);
  }
  .popup-wiki .wiki-article-body .gallerybox .thumb {
    width: auto !important;
    max-width: 100% !important;
    box-sizing: border-box;
  }
  .popup-wiki .wiki-article-body .gallerybox .thumb img {
    width: auto !important;
    max-width: 100% !important;
    margin: 0 auto;
  }
  .popup-wiki .wiki-article-body .gallerytext {
    padding: 6px 8px 8px;
    font-size: 12px;
    line-height: 1.35;
    color: var(--text-secondary);
  }
  .popup-wiki .wiki-article-body .gallery img {
    display: block;
    width: auto;
    max-width: 100%;
    height: auto;
  }
  .popup-wiki .wiki-article-body .mw-empty-elt {
    display: none;
  }
  .popup-wiki .wiki-section-overlay {
    position: sticky;
    top: 0;
    z-index: 60;
    pointer-events: none;
    background: rgba(255, 255, 255, 0.56);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid rgba(60, 60, 67, 0.32);
    margin: 0 0 12px;
  }
  .popup-wiki .wiki-section-overlay-stack {
    display: flex;
    flex-direction: column;
    pointer-events: auto;
  }
  .popup-wiki .wiki-section-overlay[hidden] {
    display: none !important;
  }
  .popup-wiki .wiki-section-overlay .wiki-collapse-group {
    margin: 0;
    padding-top: 0;
    border-top: none;
    background: rgba(255, 255, 255, 0.56);
    border-radius: 0;
    box-shadow: none;
  }
  .popup-wiki .wiki-section-overlay .wiki-collapse-head {
    margin-bottom: 0;
    padding: 0 calc(28px + var(--wiki-overlay-depth, 0) * 22px) 0.32em;
    align-items: center;
  }
  .popup-wiki .wiki-section-overlay .wiki-collapse-title {
    padding-left: 0;
  }
  .popup-wiki .wiki-section-overlay .wiki-collapse-caret {
    margin-top: 0;
  }
  .popup-wiki .wiki-note {
    color: var(--text-tertiary);
    font-size: 14px;
    margin-top: 4px;
  }
  .popup-wiki .wiki-lightbox {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: grid;
    place-items: center;
    background: rgba(14, 16, 18, 0.88);
    padding: 24px;
  }
  .popup-wiki .wiki-lightbox[hidden] {
    display: none !important;
  }
  .popup-wiki .wiki-lightbox-panel {
    position: relative;
    max-width: min(96vw, 1400px);
    max-height: 92vh;
    display: grid;
    place-items: center;
  }
  .popup-wiki .wiki-lightbox-image {
    display: block;
    max-width: 96vw;
    max-height: 92vh;
    width: auto;
    height: auto;
    object-fit: contain;
    box-shadow: 0 18px 60px rgba(0, 0, 0, 0.45);
    border-radius: 12px;
  }
  .popup-wiki .wiki-lightbox-close {
    position: absolute;
    top: -14px;
    right: -14px;
    width: 40px;
    height: 40px;
    border: 0;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.95);
    color: #1f2328;
    font-size: 24px;
    line-height: 40px;
    font-weight: 700;
    cursor: pointer;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.25);
  }
  .popup-observations {
    font-size: 14px;
    line-height: 1.55;
    color: var(--text);
    display: flex;
    flex-direction: column;
    gap: 14px;
    /* Same trick as .popup-book / .popup-wiki: break out of the
       popup-scroll's side padding and re-pad by --marg-popup-obs-h so
       that variable is the sole knob for the observations tab's side
       gap. */
    margin-left: calc(-1 * var(--popup-card-pad-x));
    margin-right: calc(-1 * var(--popup-card-pad-x));
    padding-left: var(--marg-popup-obs-h);
    padding-right: var(--marg-popup-obs-h);
  }
  .popup-map {
    font-size: 14px;
    line-height: 1.55;
    color: var(--text);
    display: flex;
    flex-direction: column;
    gap: 12px;
  }
  body.map-page-open .popup-map-frame {
    border-radius: 0;
    box-shadow: none;
  }
  .popup-map-frame {
    position: relative;
    border-radius: 20px;
    overflow: hidden;
    background: var(--bg-panel);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.10);
  }
  .popup-map-tiles {
    position: absolute;
    inset: 0;
    z-index: 0;
    background: #dde6ee;
    overflow: hidden;
  }
  .popup-map-tile {
    position: absolute;
    display: block;
    user-select: none;
    pointer-events: none;
  }
  .popup-map-svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    z-index: 1;
    background: transparent;
  }
  .popup-map-note {
    color: var(--text-secondary);
    font-size: 13px;
    text-align: center;
  }
  .wiki-article-title {
    font-size: 28px;
    font-weight: 800;
    line-height: 1.12;
    margin: 0;
  }
  .wiki-article-common {
    font-size: 18px;
    line-height: 1.3;
    color: var(--text-secondary);
    font-style: italic;
    margin: -6px 0 0;
  }
  .wiki-infobox {
    border: 1px solid var(--border);
    border-radius: 18px;
    overflow: hidden;
    background: rgba(255, 255, 255, 0.72);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
    width: calc(100% + var(--popup-card-pad-x) + var(--popup-scroll-pad-right));
    max-width: none;
    min-width: 0;
    box-sizing: border-box;
    align-self: stretch;
    margin-right: calc(-1 * (var(--popup-card-pad-x) + var(--popup-scroll-pad-right)));
  }
  .wiki-infobox-head {
    padding: 10px 14px;
    background: rgba(216, 214, 178, 0.88);
    color: var(--tint);
    font-size: 16px;
    font-weight: 800;
    text-align: center;
  }
  .wiki-infobox-row {
    display: grid;
    grid-template-columns: 1.15fr 1.85fr;
    gap: 12px;
    padding: 8px 14px;
    border-top: 1px solid rgba(60, 60, 67, 0.12);
  }
  .wiki-infobox-label {
    font-weight: 700;
    color: var(--text-secondary);
  }
  .wiki-infobox-value {
    color: var(--text);
  }
  .wiki-section {
    display: flex;
    flex-direction: column;
    gap: 6px;
  }
  .wiki-hero {
    margin: 2px 0 8px;
    border-radius: 20px;
    overflow: hidden;
    background: var(--bg-panel);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.10);
  }
  .wiki-gallery {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 2px 0 8px;
  }
  .wiki-gallery-item {
    margin: 0;
    border-radius: 16px;
    overflow: hidden;
    background: var(--bg-panel);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.10);
  }
  .wiki-hero img {
    display: block;
    width: 100%;
    height: auto;
  }
  .wiki-gallery-item img {
    display: block;
    width: 100%;
    height: auto;
  }
  .wiki-hero-caption {
    padding: 8px 12px 10px;
    font-size: 12px;
    line-height: 1.35;
    color: var(--text-secondary);
  }
  .wiki-section-title {
    font-size: 20px;
    font-weight: 800;
    margin: 0;
    color: var(--tint);
  }
  .wiki-section-head {
    display: flex;
    align-items: center;
    gap: 10px;
  }
  .wiki-section-toggle {
    border: 0;
    border-radius: 999px;
    padding: 6px 12px;
    background: rgba(60, 60, 67, 0.12);
    color: var(--text);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
    flex: 0 0 auto;
  }
  .wiki-section-toggle:active { opacity: 0.8; }
  .wiki-section-title-text {
    font-size: 24px;
    font-weight: 800;
    line-height: 1.15;
    color: var(--text);
  }
  .wiki-section-body .desc-para {
    text-indent: 2em;
    margin: 0 0 0.7em;
  }
  .wiki-section-body[hidden] { display: none; }
  .popup-book-intro {
    display: block;
  }
  .popup-book-intro-title {
    display: block;
    font-size: 22px;
    font-weight: 700;
    line-height: 1.25;
    margin: 0 0 3px;
  }
  .popup-book-intro-titleitalic {
    display: block;
    font-size: 22px;
    font-weight: 700;
    font-style: italic;
    line-height: 1.25;
    margin: 0 0 3px;
  }
  .popup-book-intro-subtitle {
    display: block;
    font-size: 15px;
    margin: 0 0 3px;
  }
  .popup-book-intro-subtitleitalic {
    display: block;
    font-size: 15px;
    font-style: italic;
    margin: 0 0 3px;
  }
  .popup-book-names-section {
    margin-bottom: 10px;
    border-bottom: 1.5px solid rgba(48, 58, 78, 0.28);
    padding-bottom: 10px;
  }
  .popup-book-names-section-head {
    display: flex;
    align-items: center;
    cursor: pointer;
    user-select: none;
    gap: 6px;
  }
  .popup-book-names-section-title {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-secondary);
  }
  .popup-book-names-section-head::after {
    content: "▸";
    font-size: 10px;
    color: var(--text-secondary);
    transition: transform 0.15s;
  }
  .popup-book-names-section-head[aria-expanded="true"]::after {
    transform: rotate(90deg);
  }
  .popup-book-names-block {
    display: block;
    padding-top: 8px;
  }
  .popup-book-names-block[hidden] { display: none; }
  .popup-book-name-gap {
    height: 0.5em;
  }
  .popup-book-name-label {
    display: inline-block;
    font-weight: 400;
    text-transform: uppercase;
    text-decoration: underline;
    text-underline-offset: 0.12em;
  }
  .popup-book-name-line {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    column-gap: 6px;
    align-items: start;
  }
  .popup-book-name-values {
    display: block;
    text-transform: none;
    letter-spacing: normal;
    min-width: 0;
  }
  .popup-book-intro-summary {
    display: block;
    font-style: italic;
    margin: 0 0 6px;
  }
  .popup-book-intro-caption {
    display: block;
    text-align: center;
    margin: 0 0 6px;
  }
  .popup-book-intro-body {
    display: block;
    margin: 0 0 6px;
  }
  .popup-book-media {
    display: grid;
    gap: 12px;
  }
  .popup-book-figure {
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  .popup-book-figure img {
    display: block;
    max-width: 100%;
    width: auto;
    height: auto;
    border-radius: 10px;
  }
  .popup-book-caption {
    padding: 6px 4px 4px;
    font-size: 12px;
    line-height: 1.4;
    color: var(--text-secondary);
    text-align: center;
  }
  .popup-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--popup-header-gap);
    margin-bottom: var(--popup-header-margin-bottom);
  }
  .popup-meta-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: -2px 0 8px;
    min-width: 0;
  }
  .popup-location-text {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--text-secondary);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .popup-title { font-size: 18px; font-weight: 700; line-height: 1.2; }
  .popup-rank { font-size: 12px; color: var(--text-tertiary);
                text-transform: uppercase; letter-spacing: 0.04em;
                margin-top: 2px; }
  .popup-sci { font-size: 13px; color: var(--text-secondary);
               font-style: italic; margin-top: 2px; }
  .popup-native-badge {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .popup-native-badge .badge-img {
    width: 22px;
    height: 22px;
    display: block;
    object-fit: contain;
  }
  .popup-header-btns {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
  }
  .popup-share {
    background: var(--badge-bg); border: none; color: var(--text-secondary);
    width: 28px; height: 28px; border-radius: 14px; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
  }
  .popup-share:active { opacity: 0.7; }
  .popup-share:disabled { opacity: 0.4; cursor: default; }
  .popup-close {
    background: var(--badge-bg); border: none; color: transparent;
    width: 28px; height: 28px; border-radius: 14px; cursor: pointer;
    font-size: 0; line-height: 1; font-weight: 700; flex-shrink: 0;
    position: relative;
  }
  .popup-close::before {
    content: "X";
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-size: 18px;
    line-height: 1;
    color: #d63c3c;
  }
  .popup-body {
    font-size: 14px; line-height: 1.5;
    margin-top: var(--popup-body-margin-top);
  }
  .popup-body .desc-para { text-indent: 2em; margin: 0 0 0.7em; }
  .popup-body .desc-heading { font-weight: 600; margin: 0.8em 0 0.3em; }
  .popup-body .empty { color: var(--text-tertiary); font-style: italic; }
  .popup-link {
    display: inline-block; margin-top: var(--popup-link-margin-top); color: var(--tint);
    text-decoration: none; font-size: 13px; font-weight: 500;
  }

  /* Fairy confirmation modal */
  .fairy-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999;
    padding: 12px;
  }
  .fairy-modal-card {
    background: var(--bg-cell);
    color: var(--text);
    border-radius: 30px;
    padding: 28px 24px;
    max-width: 300px;
    width: 100%;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
    display: flex;
    flex-direction: column;
    gap: 20px;
    align-items: center;
  }
  .fairy-modal-message {
    text-align: center;
    font-size: 16px;
    font-weight: 500;
    line-height: 1.6;
  }
  .fairy-name {
    display: block;
    font-size: 14px;
    color: var(--text-secondary);
    font-style: italic;
    margin-top: 8px;
  }
  .fairy-modal-buttons {
    display: flex;
    gap: 12px;
    width: 100%;
  }
  .fairy-modal-btn {
    flex: 1;
    padding: 10px 16px;
    border: none;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s;
    text-align: center;
  }
  .fairy-modal-yes {
    background: var(--tint);
    color: white;
  }
  .fairy-modal-yes:active {
    background: var(--tint-press);
    transform: scale(0.95);
  }
  /* Remove variant — both buttons grey so the action feels neutral/reversible */
  .fairy-modal-yes--remove {
    background: var(--badge-bg);
    color: var(--text);
  }
  .fairy-modal-yes--remove:active {
    background: var(--border);
  }
  .fairy-modal-no {
    background: var(--badge-bg);
    color: var(--text);
  }
  .fairy-modal-no:active {
    background: var(--border);
    transform: scale(0.95);
  }

  .section-header {
    font-size: var(--font-section-header); font-weight: 400;
    color: var(--text-tertiary);
    padding: 14px 4px 6px; letter-spacing: 0.02em;
    text-transform: uppercase;
  }
  body.search-page-open main#list > .section-header:first-child {
    padding-top: 4px;
  }
  .group {
    background: var(--bg-cell);
    border-radius: var(--radius);
    overflow: hidden;
    margin-bottom: 14px;
  }
  .row {
    display: flex; align-items: center; gap: 10px;
    width: 100%; min-height: var(--row-h);
    padding: 8px 14px;
    background: transparent; border: 0;
    color: inherit; font: inherit; text-align: left;
    cursor: pointer; position: relative;
  }
  .row:not(:last-child)::after {
    content: ""; position: absolute; left: 14px; right: 0; bottom: 0;
    height: 0.5px; background: var(--border);
  }
  .row:active { background: var(--badge-bg); }
  .row .main { flex: 1; min-width: 0; }
  .row .primary {
    font-size: var(--font-row-primary); font-weight: 500; color: var(--text);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .row .secondary {
    font-size: var(--font-row-secondary); color: var(--text-tertiary);
    margin-top: 1px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .row .row-native-badge {
    display: inline-flex;
    align-items: center;
    margin-top: 4px;
    pointer-events: none;
    filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.22));
  }
  .row .row-native-badge svg {
    width: 18px;
    height: 18px;
    display: block;
    overflow: visible;
    aspect-ratio: 1 / 1;
  }
  .row .row-native-badge .badge-img {
    width: 18px;
    height: 18px;
    display: block;
    object-fit: contain;
  }
  .row .row-native-badge--native svg .badge-circle,
  .row .row-native-badge--non-native svg .badge-circle,
  .row .row-native-badge--endemic svg .badge-circle,
  .row .row-native-badge--unknown svg .badge-circle {
    stroke: #000;
    stroke-width: 1.2;
  }
  .row .row-native-badge--native svg .badge-circle { fill: #30c66e; }
  .row .row-native-badge--non-native svg .badge-circle { fill: #e24d4d; }
  .row .row-native-badge--endemic svg .badge-circle { fill: #2dbb47; }
  .row .row-native-badge--unknown svg .badge-circle { fill: #9a9a9a; }
  .row .row-native-badge svg .badge-ink {
    fill: #fff;
    stroke: #000;
    stroke-width: 1.15;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  .sci { font-style: italic; }
  .rank-kingdom .primary, .rank-phylum .primary, .rank-class .primary,
  .rank-order   .primary, .rank-family .primary {
    font-weight: 600;
  }
  .row .trailing {
    display: flex; align-items: center; gap: 6px; flex-shrink: 0;
    color: var(--text-tertiary);
  }
  .badge {
    font-size: 13px; color: var(--text-secondary);
    background: var(--badge-bg);
    padding: 2px 9px; border-radius: 999px; min-width: 26px; text-align: center;
  }
  .chevron { font-size: 20px; line-height: 1; color: var(--text-tertiary); }

  .photo-grid {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px;
    background: var(--bg-cell); border-radius: var(--radius); overflow: hidden;
  }
  .photo-tile {
    aspect-ratio: 1; position: relative; overflow: hidden;
    display: block; text-decoration: none; color: inherit;
    background: var(--search-bg);
    /* button reset (we render this as a <button> so taps stay in-app) */
    border: 0; padding: 0; margin: 0; font: inherit; text-align: left;
    cursor: pointer; width: 100%;
  }
  .photo-tile img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .photo-tile.no-photo {
    display: flex; align-items: center; justify-content: center;
    padding: 6px; font-size: 11px; color: var(--text-tertiary); text-align: center;
  }
  .photo-tile .photo-caption {
    position: absolute; left: 0; right: 0; bottom: 0;
    padding: 4px 6px; font-size: 10px; color: #fff;
    background: linear-gradient(transparent, rgba(0,0,0,0.6));
    text-shadow: 0 1px 2px rgba(0,0,0,0.6);
  }
  .photo-tile:active { opacity: 0.7; }

  /* Species-grouped cards (shown at any node with direct observations).
     Two-column grid of larger cards. Photo fills the card; text overlays
     bottom-left with a soft gradient for legibility. */
  .species-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    /* Vertical gap between card rows + horizontal gap between cards. */
    row-gap: var(--marg-allGroup-v3);
    column-gap: var(--marg-allGroup-h3);
    margin-top: 4px;
  }
  .species-card {
    position: relative; aspect-ratio: 1;
    background: transparent; color: inherit;
    border: 0; padding: 0;
    border-radius: var(--radius); overflow: hidden;
    cursor: pointer; text-align: left; font: inherit;
    display: block;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
  }
  .species-card,
  .species-card *,
  .species-card img {
    -webkit-touch-callout: none !important;
    -webkit-user-select: none !important;
  }
  .species-card img {
    width: 100%; height: 100%; object-fit: cover; display: block;
    user-select: none;
    -webkit-user-drag: none;
  }
  /* No-photo cards used to render as a gray placeholder square; we now
     leave the background transparent so empty cells (and cards without a
     photo) blend into the page rather than reading as a "real" tile. */
  .species-card.no-photo {
    display: flex; align-items: center; justify-content: center;
    background: transparent;
  }
  .species-card.no-photo .no-photo-mark {
    font-size: 28px; color: var(--text-tertiary);
  }
  /* Top overlay: common name, anchored at the top with a downward
     gradient so text stays legible on any photo. */
  .species-card .species-overlay-top-name {
    position: absolute; left: 0; right: 0; top: 0;
    padding: 12px 14px 18px;
    background: linear-gradient(rgba(0,0,0,0.72) 0%,
                                rgba(0,0,0,0.42) 60%,
                                transparent 100%);
    color: #fff;
    text-shadow: 0 1px 3px rgba(0,0,0,0.65);
    text-align: left;
    font-size: var(--font-card-common); font-weight: 700; line-height: 1.2;
    overflow: hidden; text-overflow: ellipsis;
    display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
    pointer-events: auto;
    cursor: pointer;
  }
  .species-card .species-native-badge {
    position: absolute;
    left: 10px;
    top: var(--species-badge-top, 56px);
    display: inline-flex;
    align-items: center;
    z-index: 2;
    pointer-events: none;
    filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.26));
  }
  .species-card .species-location-line {
    position: absolute;
    left: 14px;
    right: 14px;
    bottom: 28px;
    z-index: 2;
    color: #fff;
    text-shadow: 0 1px 3px rgba(0,0,0,0.75);
    font-size: 11px;
    font-weight: 600;
    line-height: 1.15;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
  }
  .species-card .species-native-badge svg {
    width: 22px;
    height: 22px;
    display: block;
    aspect-ratio: 1 / 1;
  }
  .species-card .species-native-badge .badge-img {
    width: 22px;
    height: 22px;
    display: block;
    object-fit: contain;
  }
  .species-card .species-native-badge--native svg,
  .species-card .species-native-badge--non-native svg,
  .species-card .species-native-badge--endemic svg {
    overflow: visible;
  }
  .species-card .species-native-badge--native svg .badge-circle {
    fill: #30c66e;
    stroke: #000;
    stroke-width: 1.2;
  }
  .species-card .species-native-badge--non-native svg .badge-circle {
    fill: #e24d4d;
    stroke: #000;
    stroke-width: 1.2;
  }
  .species-card .species-native-badge--endemic svg .badge-circle {
    fill: #2dbb47;
    stroke: #000;
    stroke-width: 1.2;
  }
  .species-card .species-native-badge--unknown svg .badge-circle {
    fill: #9a9a9a;
    stroke: #000;
    stroke-width: 1.2;
  }
  .species-card .species-native-badge svg .badge-ink {
    fill: #fff;
    stroke: #000;
    stroke-width: 1.15;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  /* Bottom overlay: scientific name (italic). */
  .species-card .species-overlay-bottom-sci {
    position: absolute; left: 0; right: 0; bottom: 0;
    padding: 18px 14px 10px;
    background: linear-gradient(transparent 0%,
                                rgba(0,0,0,0.42) 60%,
                                rgba(0,0,0,0.78) 100%);
    color: #fff;
    text-shadow: 0 1px 3px rgba(0,0,0,0.6);
    text-align: left;
    font-size: var(--font-card-sci); font-style: italic; line-height: 1.2;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    pointer-events: none;
  }
  .species-card.book-match .species-book-icons {
    position: absolute;
    top: 7px;
    right: 7px;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    z-index: 2;
    pointer-events: none;
  }
  .species-card.book-match .species-book-icon {
    width: 22px;
    height: 22px;
    flex: 0 0 auto;
    filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.28));
  }
  /* Fairy mark (sam_m_ only). Sits on the lower-left of the card,
     just above the location text and italic scientific-name overlay. Same size as book icons. */
  .species-card .species-fairy-icon {
    position: absolute;
    left: 10px;
    bottom: 50px;
    width: 22px;
    height: 22px;
    z-index: 3;
    pointer-events: none;
    filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.28));
  }
  .species-card:active { opacity: 0.85; }

  /* Observation detail view: full-width photo gallery + metadata block.
     Reached by tapping a photo tile (or in some cases a species card). */
  .obs-photos {
    display: flex; flex-direction: column; gap: 6px;
    margin: 4px 0 12px;
  }
  .obs-photo {
    width: 100%;
    background: var(--search-bg);
    border-radius: var(--radius);
    overflow: hidden;
    aspect-ratio: 1;
  }
  .obs-photo img {
    width: 100%; height: 100%; object-fit: cover; display: block;
  }
  .obs-photo.no-photo {
    display: flex; align-items: center; justify-content: center;
    color: var(--text-tertiary); font-size: 14px;
  }
  .obs-meta {
    background: var(--bg-cell);
    border-radius: var(--radius);
    overflow: hidden;
    margin-bottom: 14px;
  }
  .obs-meta-row {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 14px;
    font-size: 15px;
    color: var(--text);
    position: relative;
  }
  .obs-meta-row:not(:last-child)::after {
    content: ""; position: absolute; left: 14px; right: 0; bottom: 0;
    height: 0.5px; background: var(--border);
  }
  .obs-meta-label {
    color: var(--text-tertiary);
    font-size: 13px;
    min-width: 72px;
    flex-shrink: 0;
  }
  .obs-meta-value {
    flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis;
  }
  .obs-meta-row.link-row .obs-meta-value {
    color: var(--tint);
  }
  .obs-meta-row.link-row a {
    color: inherit; text-decoration: none;
    display: inline-flex; align-items: center; gap: 4px;
  }
  .obs-meta-row.link-row a:active { opacity: 0.6; }

  /* ---- Species feed (vertical scroll of observation cards) ---- */
  .obs-feed {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin: 4px 0 16px;
  }
  .obs-card {
    background: var(--bg-cell);
    border-radius: var(--radius);
    overflow: hidden;
    border: 1px solid var(--border);
  }
  .obs-card-head {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
  }
  .obs-card-head-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px 12px;
  }
  .obs-card-date {
    font-size: 15px; font-weight: 600; color: var(--text);
  }
  .obs-card-place {
    font-size: 13px; color: var(--text-secondary);
    display: flex;
    align-items: center;
    gap: 6px;
    text-shadow:
      -0.35px 0 rgba(0,0,0,0.7),
      0 0.35px rgba(0,0,0,0.7),
      0.35px 0 rgba(0,0,0,0.7),
      0 -0.35px rgba(0,0,0,0.7);
    min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .obs-card-place-icon {
    width: 16px;
    height: 16px;
    flex: 0 0 auto;
    filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.3));
  }
  .obs-card-badge-icon {
    width: 16px;
    height: 16px;
    flex: 0 0 auto;
  }
  .obs-photo-stack {
    display: flex; flex-direction: column; gap: 4px;
  }
  .obs-photo-tile {
    position: relative;
    width: 100%;
    background: var(--search-bg);
    cursor: zoom-in;
    user-select: none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;          /* suppress native long-press menu on iOS */
  }
  .obs-photo-tile img {
    width: 100%; max-height: 80vh; object-fit: contain;
    display: block;
    background: var(--bg-grouped);
  }
  .obs-photo-cover-badge {
    position: absolute; top: 10px; left: 10px;
    padding: 3px 8px;
    background: var(--tint); color: #fff;
    border-radius: 999px;
    font-size: 11px; font-weight: 700;
    letter-spacing: 0.04em; text-transform: uppercase;
    box-shadow: 0 1px 2px rgba(0,0,0,0.4);
  }
  .obs-card-foot {
    padding: 10px 14px;
    border-top: 1px solid var(--border);
    text-align: right;
  }
  .obs-card-foot a {
    color: var(--tint); text-decoration: none;
    font-size: 13px; font-weight: 500;
  }
  .obs-card-foot a:active { opacity: 0.6; }

  /* ---- Embedded OSM map ---- */
  .obs-map {
    position: relative;
    width: 100%; height: 240px;
    background: var(--search-bg);
  }
  .obs-map iframe {
    width: 100%; height: 100%;
    border: 0; display: block;
  }
  .obs-map-note {
    position: absolute; right: 8px; bottom: 8px;
    background: rgba(0, 0, 0, 0.6); color: #fff;
    font-size: 11px; padding: 3px 8px; border-radius: 4px;
    pointer-events: none;
  }
  /* Transparent overlay that blocks iframe touch capture while locked.
     Sits above the iframe; double-tap removes it so the map becomes
     fully interactive. Touch events on the overlay bubble normally so
     the popup's scroll container handles single-finger drags. */
  .obs-map-overlay {
    position: absolute; inset: 0; z-index: 2;
    cursor: pointer;
    -webkit-user-select: none; user-select: none;
    /* Visually invisible except for the hint badge */
  }
  .obs-map-hint {
    position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%);
    background: rgba(0, 0, 0, 0.55); color: #fff;
    font-size: 12px; font-weight: 500; white-space: nowrap;
    padding: 5px 12px; border-radius: 20px;
    pointer-events: none;
    backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  }

  /* ---- Fullscreen photo lightbox ---- */
  .lightbox-backdrop {
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.92);
    z-index: 200;
    display: flex; align-items: center; justify-content: center;
    overflow: auto;
    touch-action: none; /* prevent the rest of the app from zooming */
  }
  .lightbox-img {
    max-width: 96vw; max-height: 96vh;
    object-fit: contain; display: block;
    touch-action: none;
    -webkit-user-select: none; user-select: none;
    will-change: transform;
  }
  .lightbox-close {
    position: fixed; top: calc(16px + env(safe-area-inset-top)); right: calc(16px + env(safe-area-inset-right));
    width: 44px; height: 44px;
    background: #e24d4d; color: #fff;
    border: 0; border-radius: 22px;
    font-size: 28px; line-height: 1; cursor: pointer;
    font-weight: bold;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
  }
  .lightbox-close:active { opacity: 0.8; }

  .empty {
    text-align: center; color: var(--text-tertiary);
    padding: 40px 20px; font-size: 15px;
  }

  /* Simple slide-in when drilling deeper */
  @media (prefers-reduced-motion: no-preference) {
    main#list { animation: slide-in 0.22s ease-out; }
    main#list.reverse { animation: slide-in-reverse 0.22s ease-out; }
    @keyframes slide-in {
      from { opacity: 0; transform: translateX(14px); }
      to   { opacity: 1; transform: translateX(0); }
    }
    @keyframes slide-in-reverse {
      from { opacity: 0; transform: translateX(-14px); }
      to   { opacity: 1; transform: translateX(0); }
    }
  }
  .notification-section-label {
    padding: 14px 16px 4px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-tertiary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }
  .notification-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding-top: 6px;
    padding-left: 6px;
  }
  .notification-item-wrap {
    position: relative;
  }
  .notification-item-wrap.notification-item--new::before {
    content: "";
    position: absolute;
    left: -3px;
    top: -3px;
    width: 18px;
    height: 18px;
    border-radius: 999px;
    background: #ff2d2d;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.22);
    pointer-events: none;
    z-index: 1;
  }
  .notification-item {
    background: var(--bg-cell);
    border: 1px solid var(--border);
    border-radius: 18px;
    padding: 12px 14px;
    position: relative;
    overflow: hidden;
  }
  .notification-item.has-thumb {
    padding-right: calc(14px + 72px + 8px);
  }
  .notification-item-thumb-wrap {
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    aspect-ratio: 1 / 1;
    overflow: hidden;
  }
  .notification-item-thumb {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
  .notification-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 6px;
  }
  .notification-name-container {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
  }
  .notification-name {
    font-size: 15px;
    font-weight: 700;
    color: var(--text);
  }
  .notification-badge-icon {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
  }
  .notification-date {
    font-size: 12px;
    color: var(--text-tertiary);
    white-space: nowrap;
  }
  .notification-sci {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    color: var(--text-secondary);
    margin-bottom: 8px;
  }
  .notification-sci-name {
    font-style: italic;
  }
  .notification-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }
  .notification-pill {
    display: inline-flex;
    align-items: center;
    border-radius: 999px;
    padding: 4px 10px;
    font-size: 12px;
    font-weight: 600;
    background: var(--bg-cell-alt);
    color: var(--text-secondary);
  }
  .notification-pill.new-species {
    background: rgba(74, 163, 80, 0.16);
    color: #2e7d32;
  }

  #startup-loading[hidden] {
    display: none !important;
  }
  #startup-loading {
    position: fixed;
    inset: 0;
    z-index: 20000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: var(--bg, #f2f2f7);
  }
  .startup-loading-card {
    width: min(420px, 100%);
    background: var(--bg-cell, #fff);
    border: 1px solid var(--border, #d7d7dc);
    border-radius: 22px;
    padding: 20px 18px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
  }
  #startup-loading-text {
    font-size: 16px;
    font-weight: 700;
    color: var(--text, #1d1d1f);
    margin-bottom: 12px;
  }
  .startup-loading-bar {
    width: 100%;
    height: 10px;
    border-radius: 999px;
    background: var(--bg-cell-alt, #e8e8ee);
    overflow: hidden;
  }
  #startup-loading-fill {
    width: 0%;
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, #4b67ff 0%, #6f87ff 100%);
    transition: width 180ms ease;
  }
  #startup-loading-percent {
    margin-top: 10px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-secondary, #555);
    text-align: right;
  }

