* { margin: 0; padding: 0; box-sizing: border-box; }

/* Leaflet 2D map: hide the 1–2px white hairline seams that subpixel rounding
   leaves between 256px raster tiles by overlapping each tile a touch. */
.leaflet-container .leaflet-tile {
    width: 256.5px !important;
    height: 256.5px !important;
}

/* Old Hangul conjoining jamo (U+1100-11FF + Extended-A/B). The Lang Map
   sentence data carries 30 of them — Middle Korean ko_mid renders "나ᄂᆞᆫ
   새로온 ᄆᆞᄅᆞᆯ …" — and this stylesheet, shared by index.html, tree.html and
   namemap.html, had no @font-face for them at all. Google's Noto Sans/Serif
   KR web subsets omit the whole block, so every jamo fell through to the
   system font: broken composition on PC Chrome, tofu on iPhone. wordmap.html
   and hanmap.html each self-hosted their own subset; this is the same file
   they now share, scoped by unicode-range so it is fetched only when a page
   actually shows Old Hangul. The family name still has to appear in the
   font-family chain of anything that renders it — see body and .segment. */
@font-face {
    font-family: 'Noto Serif KR Old Jamo';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/NotoSerifKR-OldHangul.woff2') format('woff2');
    unicode-range: U+1100-11FF, U+302E-302F, U+3130-318F, U+A960-A97F, U+D7B0-D7FF;
}

/* The SANS cut, for the pages whose own text is sans — the Word Order map,
 * the tree and the name map. Reported 2026-09-15: Middle Korean 나ᄂᆞᆫ was
 * coming out with 나 in the UI sans and ᄂᆞᆫ in the serif face above — one
 * word, two typefaces, directly under a modern Korean row that was uniformly
 * sans.
 *
 * The range is long because it has to be. It carries the conjoining jamo AND
 * every precomposed syllable the data uses, because a font at the front of the
 * chain that lacks the syllable makes HarfBuzz DECOMPOSE it into jamo and then
 * fail to recompose them across a font boundary: 나 renders as ㄴ ㅏ side by
 * side. Claiming a syllable the file does not contain would tofu it, so the
 * range is generated from the file — `node tools/build_korean_hist_font.js`
 * prints both, and they must be pasted together. */
@font-face {
    font-family: 'Noto Sans KR Old Jamo';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('fonts/NotoSansKR-OldHangul.woff2') format('woff2');
    unicode-range: U+1100-11FF, U+302E-302F, U+3130-318F, U+A960-A97F, U+D7B0-D7FF, U+AC00, U+AC01, U+AC04, U+AC10, U+AC11, U+AC12, U+AC13, U+AC14, U+AC15, U+AC1C, U+AC54, U+AC70, U+AC74, U+AC78, U+AC83, U+AC8C, U+ACA0, U+ACA8, U+ACAF, U+ACB0, U+ACBD, U+ACC1, U+ACC4, U+ACE0, U+ACE1, U+ACE7, U+ACF1, U+ACF3, U+ACF5, U+ACFC, U+AD00, U+AD2D, U+AD34, U+AD50, U+AD6C, U+AD6D, U+AD70, U+ADC0, U+ADF8, U+ADFC, U+AE00, U+AE08, U+AE14, U+AE30, U+AE34, U+AE38, U+AE4C, U+AE68, U+AF43, U+AF48, U+AF9C, U+AFB8, U+B057, U+B05D, U+B07C, U+B080, U+B098, U+B09C, U+B0A0, U+B0A8, U+B0AB, U+B0AD, U+B0AE, U+B0B4, U+B108, U+B124, U+B140, U+B141, U+B144, U+B150, U+B178, U+B180, U+B18B, U+B193, U+B1E8, U+B204, U+B208, U+B274, U+B290, U+B294, U+B298, U+B2A5, U+B2A6, U+B2C8, U+B2CC, U+B2D0, U+B2D1, U+B2D8, U+B2D9, U+B2E4, U+B2E8, U+B2EB, U+B2EC, U+B2F4, U+B2F5, U+B2F9, U+B300, U+B354, U+B35C, U+B35F, U+B36E, U+B370, U+B394, U+B3C4, U+B3C8, U+B3CC, U+B3D9, U+B418, U+B41C, U+B420, U+B428, U+B434, U+B450, U+B4A4, U+B4DC, U+B4E0, U+B4E3, U+B4E4, U+B4EC, U+B4ED, U+B4F8, U+B514, U+B54C, U+B611, U+B730, U+B77C, U+B780, U+B78C, U+B78F, U+B790, U+B791, U+B798, U+B7C9, U+B7EC, U+B7F0, U+B808, U+B80C, U+B81B, U+B824, U+B825, U+B82C, U+B837, U+B838, U+B85C, U+B85D, U+B86F, U+B8CC, U+B8E8, U+B958, U+B974, U+B978, U+B97C, U+B984, U+B987, U+B9AC, U+B9B0, U+B9BC, U+B9C8, U+B9C9, U+B9CC, U+B9CE, U+B9D0, U+B9D1, U+B9D9, U+B9DB, U+B9DD, U+B9DE, U+B9E4, U+B9E8, U+BA38, U+BA39, U+BA3C, U+BA4D, U+BA54, U+BA83, U+BA85, U+BA87, U+BAA8, U+BAA9, U+BABB, U+BAFC, U+BB34, U+BB35, U+BB38, U+BB3C, U+BB47, U+BBC0, U+BBC4, U+BBC8, U+BBF8, U+BBFC, U+BBFF, U+BC00, U+BC0B, U+BC0C, U+BC0D, U+BC14, U+BC18, U+BC1C, U+BC1D, U+BC24, U+BC25, U+BC29, U+BC30, U+BC84, U+BC88, U+BC95, U+BC97, U+BC9A, U+BCC0, U+BCD1, U+BCF4, U+BCF5, U+BCF8, U+BD10, U+BD24, U+BD48, U+BD80, U+BD84, U+BD88, U+BD89, U+BE0C, U+BE10, U+BE14, U+BE44, U+BE60, U+BE68, U+BED0, U+BFCC, U+C058, U+C05C, U+C0AC, U+C0B0, U+C0C0, U+C0C1, U+C0C8, U+C0DD, U+C11C, U+C11D, U+C120, U+C124, U+C12F, U+C131, U+C138, U+C14B, U+C154, U+C158, U+C170, U+C18C, U+C18D, U+C190, U+C1E0, U+C1FC, U+C218, U+C220, U+C26C, U+C288, U+C2A4, U+C2AC, U+C2B4, U+C2B5, U+C2B9, U+C2DC, U+C2DD, U+C2E0, U+C2E4, U+C2EC, U+C2ED, U+C2F6, U+C2F8, U+C308, U+C309, U+C37B, U+C37C, U+C4F0, U+C4F4, U+C500, U+C528, U+C544, U+C545, U+C548, U+C549, U+C54C, U+C557, U+C559, U+C560, U+C571, U+C57C, U+C57D, U+C591, U+C598, U+C5B4, U+C5B5, U+C5B8, U+C5BC, U+C5C4, U+C5C5, U+C5C6, U+C5C7, U+C5C8, U+C5D0, U+C5D4, U+C5EC, U+C5ED, U+C5F4, U+C5FC, U+C600, U+C601, U+C606, U+C608, U+C624, U+C628, U+C62C, U+C62E, U+C634, U+C635, U+C637, U+C640, U+C653, U+C654, U+C678, U+C694, U+C6A9, U+C6B0, U+C6B4, U+C6B8, U+C6C0, U+C6CC, U+C6D0, U+C6D4, U+C6DF, U+C6E0, U+C6FB, U+C704, U+C720, U+C721, U+C73C, U+C740, U+C744, U+C74C, U+C751, U+C758, U+C774, U+C778, U+C77C, U+C77D, U+C783, U+C784, U+C785, U+C787, U+C788, U+C78A, U+C790, U+C791, U+C794, U+C798, U+C7A0, U+C7A5, U+C7AC, U+C800, U+C801, U+C804, U+C808, U+C810, U+C815, U+C81C, U+C824, U+C82F, U+C838, U+C83C, U+C870, U+C880, U+C88B, U+C8FC, U+C900, U+C904, U+C90C, U+C90D, U+C90F, U+C911, U+C92C, U+C96C, U+C989, U+C990, U+C9C0, U+C9C1, U+C9C4, U+C9D0, U+C9D1, U+C9D3, U+C9F8, U+CABD, U+CC0D, U+CC28, U+CC38, U+CC3D, U+CC3E, U+CC45, U+CC9C, U+CCA0, U+CCAB, U+CCB4, U+CCD0, U+CD08, U+CD2C, U+CD94, U+CD95, U+CD98, U+CDA9, U+CE58, U+CE5C, U+CE60, U+CE68, U+CE74, U+CEE4, U+CF13, U+CF1C, U+CF54, U+CF58, U+CFC4, U+CFE0, U+D070, U+D0A4, U+D0C8, U+D130, U+D134, U+D14C, U+D154, U+D168, U+D1B5, U+D2B8, U+D310, U+D37C, U+D38C, U+D3B8, U+D3F0, U+D480, U+D488, U+D48D, U+D504, U+D514, U+D53C, U+D558, U+D559, U+D55C, U+D560, U+D568, U+D569, U+D56D, U+D574, U+D578, U+D588, U+D589, U+D5A5, U+D5C8, U+D5D0, U+D5D8, U+D5E4, U+D5EC, U+D5F7, U+D615, U+D61C, U+D638, U+D63C, U+D640, U+D648, U+D649, U+D654, U+D655, U+D658, U+D68C, U+D68D, U+D6C4, U+D754, U+D765, U+D788, U+D798;
}

/* Single accent colour for all interactive UI (links, buttons, focus,
   selected states). Consolidated from several near-duplicate blues so the
   interface reads as deliberately designed rather than assembled. */
:root {
    --accent: #2e6fb8;
    --accent-dark: #245a96;
    --accent-tint: #e9f1fa;
    --accent-rgb: 46, 111, 184;   /* #2e6fb8, for rgba() tints */
}


body {
    /* IMPORTANT: do NOT add Tibetan fonts (Kailasa / Microsoft Himalaya /
       Jomolhari / Tibetan Machine Uni / Noto Serif Tibetan) to the body
       cascade. iOS Safari resolves Kailasa as a system font and uses
       its large vertical metrics to compute the line-box for ALL body
       text — even text rendered in Hiragino. The result was CJK
       glyphs sitting in the upper part of an oversized line-box,
       showing up as "text shifted up" inside flex-centred trivia and
       lang-toggle buttons (root cause traced 2026-05-27 to 8f578fd's
       body font-family extension). Tibetan fallback is now scoped to
       the elements that actually contain Tibetan codepoints
       (.segment, .node.leaf .native) below. */
    font-family: 'Noto Sans KR Old Jamo', 'Segoe UI', 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans SC', 'Noto Sans TC', 'Noto Sans Thai', sans-serif;
    background: #f0f2f5;
    min-height: 100vh;
    padding: 20px;
}

.container {
    max-width: 1400px;
    margin: 0 auto;
}

/* --- Site header bar (shared between index.html and wordmap.html) --- */
.site-header-bar {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 8px 20px;
    margin: -20px -20px 20px;
    background: rgba(255,255,255,0.97);
    /* NOTE: no backdrop-filter here. It would make the header a containing
       block for position:fixed descendants, pinning the desktop
       .ui-lang-footer pill to the header instead of the viewport bottom.
       The 0.97-opaque background makes the blur imperceptible anyway. */
    border-bottom: 1px solid #e0e0e0;
    box-shadow: 0 1px 4px rgba(0,0,0,0.08);
}
.site-header-bar .logo {
    font-size: 20px; font-weight: 800; color: #1a1a2e; text-decoration: none;
    letter-spacing: -0.5px; white-space: nowrap;
}
.site-header-bar .logo:hover { color: #333; }
/* Page-indicator badge sitting just to the right of the LangMap wordmark.
   Tells the user at a glance which sub-section they're in (語順/単語/漢字/
   ツリー) using single-char labels (no i18n needed) and a per-section
   colour. */
.site-header-bar .logo-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-left: 4px;
    width: 15px;
    height: 15px;
    color: #fff;
    border-radius: 4px;
    vertical-align: 5px;
}
.site-header-bar .logo-badge svg {
    width: 10px;
    height: 10px;
    stroke: currentColor;
    fill: none;
    stroke-width: 2.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.site-header-bar .logo-badge-han   { background: #c0392b; }   /* Hanmap     */
.site-header-bar .logo-badge-word  { background: #2e8b57; }   /* Wordmap    */
.site-header-bar .logo-badge-tree  { background: #8b4513; }   /* Tree       */
.site-header-bar .logo-badge-order { background: #2563eb; }   /* Word Order */
.site-header-bar .logo-badge-name  { background: #8e44ad; }   /* NameMap    */
/* 字 character badge for Hanmap: CJK serif glyph instead of the
   previous abstract square-rect SVG. Sized to fit inside the 15×15
   badge with consistent vertical alignment. */
.site-header-bar .logo-badge-han-char {
    font-family: 'Noto Serif JP','Noto Serif SC','Noto Serif TC','Noto Serif KR',serif;
    font-weight: 700;
    font-size: 11px;
    line-height: 1;
    color: #fff;
}
.site-header-bar .subtitle {
    font-size: 12px; font-weight: 400; color: #888; margin-left: 4px;
}
.header-nav {
    display: flex; align-items: center; gap: 4px;
    font-size: 13px;
}
.header-nav-current {
    font-weight: 700; color: #1a1a2e; white-space: nowrap;
}
.header-nav-link {
    color: #666; text-decoration: none; white-space: nowrap;
    transition: color 0.2s ease;
}
.header-nav-link:hover {
    color: var(--accent); text-decoration: underline;
}
.header-nav .nav-sep {
    color: #ccc; margin: 0 2px;
}
.site-header-bar .header-url {
    margin-left: auto;
    font-size: 11px; color: #888; text-decoration: none; white-space: nowrap;
    /* Faint frosted pill so the URL stays legible over light/busy map
       areas (the header floats over the map on wordmap/hanmap). */
    padding: 2px 8px; border-radius: 11px;
    background: rgba(255,255,255,0.62);
    -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
.site-header-bar .header-url:hover { color: var(--accent-dark); text-decoration: underline; background: rgba(255,255,255,0.8); }
/* Header UI-lang select (Pass 34/36: unified position + fixed-width
   right-aligned style across index/wordmap/tree pages).
   max-width caps the select so long native names like "Bahasa Indonesia"
   or "日本語(標準)" don't let it auto-stretch across the leftover flex
   space. Without max-width, native <select> elements size to fit their
   widest option and the right-side dropdown ends up spanning the entire
   header. wordmap.html had a separate `.site-header-bar select` rule
   that capped it; promote the cap to the shared class so index.html /
   tree.html inherit it too. */
.site-header-bar .header-ui-lang {
    padding: 4px 8px; font-size: 12px;
    border: 1px solid #d0d0d0; border-radius: 4px;
    background: #fff; color: #444; cursor: pointer;
    margin-left: auto;
    min-width: 140px;
    max-width: 200px;
}
.site-header-bar .header-ui-lang + .header-url { margin-left: 12px; }

/* Audit Task 231: mobile hamburger menu. On desktop the wrapper is
   `display: contents` so its children participate in the header flex
   layout exactly as before. On mobile (≤640px) the hamburger button
   appears, the wrapper collapses, and a checked checkbox reveals the
   wrapper as an absolute-positioned dropdown. CSS-only — no JS.

   Keyboard a11y note: the toggle checkbox is visually hidden using
   the standard sr-only pattern (clip + 1×1px positioned offscreen),
   not display:none, so it stays in the tab order and Space toggles
   it. We don't set aria-hidden since the checkbox is the actual
   interactive control; the label proxies it visually. */
.hdr-menu-toggle {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; overflow: hidden;
    clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.hamburger-btn { display: none; }
.hdr-menu-toggle:focus-visible + .hamburger-btn {
    outline: 2px solid var(--accent); outline-offset: 2px;
}
.header-collapse { display: contents; }
@media (max-width: 720px) {
    body { padding: 10px; }
    .site-header-bar { margin: -10px -10px 16px; padding: 10px 14px; gap: 8px; }
    .site-header-bar .logo { font-size: 16px; }
    .site-header-bar .subtitle { display: none; }
    .site-header-bar .header-url { font-size: 10px; }
}
/* Backdrop behind the open hamburger drawer. Stays in DOM; opacity
   toggles when the checkbox is checked. Hidden on desktop. */
.header-backdrop { display: none; }
@media (max-width: 640px) {
    .site-header-bar { position: relative; flex-wrap: nowrap; }
    .hamburger-btn {
        display: inline-flex; align-items: center; justify-content: center;
        margin-left: auto;
        width: 40px; height: 40px;
        background: transparent; border: 1px solid #d0d0d0; border-radius: 6px;
        font-size: 20px; line-height: 1; color: #444;
        cursor: pointer; user-select: none;
        transition: background-color 0.15s, color 0.15s;
    }
    .hamburger-btn:hover, .hamburger-btn:focus { background: #f3f4f6; outline: none; }
    .hamburger-btn:active { background: #e5e7eb; }
    /* Active-state visual when checkbox is checked: invert colors so users
       see the menu is open even when the dropdown isn't visually obvious. */
    .hdr-menu-toggle:checked + .hamburger-btn { background: var(--accent); color: #fff; border-color: var(--accent); }
    .header-collapse {
        /* Use opacity + visibility instead of display so we can transition. */
        display: flex;
        opacity: 0; visibility: hidden;
        transform: translateY(-4px);
        transition: opacity 0.15s, visibility 0.15s, transform 0.15s;
        position: absolute; top: 100%; left: 0; right: 0;
        flex-direction: column; align-items: stretch; gap: 14px;
        padding: 18px 18px;
        /* A menu taller than the window used to run off the bottom with no
           way to reach its last items — the UI-language select and the site
           links sit at the end, and on a landscape phone they were simply
           unreachable. Cap the drawer at the space below the header and let
           it scroll. --wm-header-h carries the header bar's real measured
           height (set in wordmap.html); 64px is the usual mobile value and
           the fallback if the script has not run. overscroll-behavior stops
           the scroll chaining into the map behind it. */
        max-height: calc(100dvh - var(--wm-header-h, 64px));
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
        background: #fff;
        border-bottom: 1px solid #e0e0e0;
        box-shadow: 0 4px 12px rgba(0,0,0,0.12);
        z-index: 1100;
        /* Honor notch / safe-area on landscape iPhones. */
        padding-left: max(18px, env(safe-area-inset-left));
        padding-right: max(18px, env(safe-area-inset-right));
    }
    .hdr-menu-toggle:checked ~ .header-collapse {
        opacity: 1; visibility: visible; transform: translateY(0);
    }
    /* Vertical nav stack: each item on its own row, generous tap target.
       Hide the "/" separators since they only make sense inline. */
    .header-collapse .header-nav {
        flex-direction: column;
        align-items: stretch;
        gap: 4px;
        font-size: 16px;
    }
    .header-collapse .header-nav .nav-sep { display: none; }
    .header-collapse .header-nav-link,
    .header-collapse .header-nav-current {
        padding: 10px 4px;
        border-radius: 6px;
    }
    .header-collapse .header-nav-link:hover {
        background: #f3f4f6; text-decoration: none;
    }
    .header-collapse .header-nav-current { background: #f3f4f6; }
    .header-collapse .header-ui-lang { margin-left: 0; width: 100%; max-width: none; }
    /* Mobile language selection: use the NATIVE <select> (the OS picker —
       iOS wheel / Android list), not the custom globe dropdown. The custom
       menu, opened inside the hamburger drawer, either dropped its lower items
       below the viewport (unreachable) or, made inline, stretched the drawer
       into an ugly 19-row list. The native select handles the long list cleanly
       and is the expected mobile control. Hide the custom picker, reveal the
       native select (overrides the global `display:none !important` on it). */
    .header-collapse .lang-picker { display: none !important; }
    .site-header-bar .header-collapse select.header-ui-lang {
        display: block !important;
        width: 100%; max-width: none; margin: 0;
        padding: 10px 12px; font-size: 15px;
        border: 1px solid #e5e7eb; border-radius: 8px;
        background: #f9fafb; color: #374151; cursor: pointer;
    }
    .header-collapse .header-url {
        margin-left: 0;
        padding-top: 6px; border-top: 1px solid #eee;
    }
    /* Semi-transparent black backdrop behind the open drawer. Lives
       OUTSIDE .site-header-bar (the header's backdrop-filter creates a
       containing block that traps fixed-position descendants), so we
       use body:has() to react to the toggle state. Tappable — the
       outside-click JS handler closes the menu when the backdrop is hit.
       Header is raised above the backdrop so the menu chrome stays
       visible against the dimmed page. */
    .site-header-bar { z-index: 1101; }
    .header-backdrop {
        display: block;
        position: fixed; inset: 0;
        background: rgba(0,0,0,0.45);
        opacity: 0; visibility: hidden;
        transition: opacity 0.15s, visibility 0.15s;
        z-index: 1099;
        cursor: pointer;
    }
    body:has(.hdr-menu-toggle:checked) .header-backdrop {
        opacity: 1; visibility: visible;
    }
}

.ui-lang-picker {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    margin-bottom: 8px;
}
.ui-lang-picker label {
    font-size: 12px;
    color: #666;
    white-space: nowrap;
}
.ui-lang-picker select {
    width: auto;
    padding: 4px 8px;
    font-size: 13px;
    border-radius: 6px;
}

.btn-inline {
    margin-left: 6px;
    vertical-align: middle;
    padding: 2px 8px;
    font-size: 11px;
}

/* Controls */
.controls {
    background: #fff;
    border-radius: 12px;
    padding: 14px 16px;
    margin-bottom: 16px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.06);
}

.control-row {
    display: flex;
    gap: 10px;
    align-items: center;
    margin-bottom: 10px;
}
.control-row:last-child { margin-bottom: 0; }

/* Sentence row: label + nav buttons inline with select */
.sentence-label {
    font-weight: 600;
    font-size: 12px;
    color: #888;
    white-space: nowrap;
}
.sentence-nav {
    display: flex;
    gap: 4px;
    align-items: center;
    flex: 1;
}
.sentence-nav select { flex: 1; min-width: 0; font-size: 13px; padding: 6px 8px; }
.nav-icon {
    background: none;
    border: none;
    padding: 4px 6px;
    font-size: 18px;
    cursor: pointer;
    color: #999;
    line-height: 1;
}
.nav-icon:hover { color: #333; }
.nav-random { display: inline-flex; align-items: center; gap: 3px; font-size: 13px; }
.random-icon { font-size: 16px; }
.random-text { font-size: 12px; color: #888; }
@media (max-width: 768px) {
    .random-text { display: none; }
}

/* Language row */
.lang-row-ctrl { flex-wrap: wrap; }
.btn-lang-select {
    padding: 6px 14px;
    border-radius: 6px;
    background: var(--accent);
    border: none;
    font-size: 12px;
    font-weight: 600;
    color: #fff;
    cursor: pointer;
    white-space: nowrap;
}
.btn-lang-select:hover { background: var(--accent-dark); }

.hint {
    font-weight: 400;
    color: #999;
    font-size: 11px;
}

select {
    width: 100%;
    padding: 8px 12px;
    border: 2px solid #e0e0e0;
    border-radius: 6px;
    font-size: 14px;
    background: #fff;
    cursor: pointer;
}
select:focus { border-color: var(--accent); outline: none; }

.btn {
    padding: 8px 16px;
    border: none;
    border-radius: 6px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    background: #e8ecf1;
    color: #333;
    transition: all 0.15s;
    white-space: nowrap;
}
.btn:hover { background: #d0d5dd; }
.btn-accent { background: var(--accent); color: #fff; }
.btn-accent:hover { background: var(--accent-dark); }
.btn-sm { padding: 6px 12px; font-size: 12px; }
.btn-group { display: flex; gap: 6px; }

/* Language summary (inline pills + open modal button) */
.lang-summary {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    align-items: center;
}
.lang-pill {
    display: inline;
    font-size: 12px;
    color: #555;
    white-space: nowrap;
}
.lang-pill.experimental { }
/* Collapsed-group pill — shown when every member of a language group
   is selected. Bold so the user can tell at a glance that one chip
   stands in for the whole group (e.g. "日本語" vs 12 dialect pills). */
.lang-pill.lang-group-pill { font-weight: 700; color: #2a2a2a; }
.lang-pill + .lang-pill::before {
    content: '/ ';
    color: #bbb;
}
.btn-open-modal {
    padding: 3px 10px;
    border-radius: 12px;
    background: #fff;
    border: 1.5px solid #ccc;
    font-size: 11px;
    color: #666;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s;
}
.btn-open-modal:hover { background: #f0f2f5; color: #333; }
.exp-badge {
    font-size: 10px;
    font-weight: 700;
    color: #fff;
    background: #e67e22;
    border-radius: 3px;
    padding: 2px 5px;
    margin-left: 4px;
    vertical-align: middle;
    letter-spacing: 0.5px;
}
.hist-badge {
    font-size: 10px;
    font-weight: 700;
    color: #fff;
    background: #8e44ad;
    border-radius: 3px;
    padding: 2px 5px;
    margin-left: 4px;
    vertical-align: middle;
}
.pending-badge {
    font-size: 10px;
    font-weight: 700;
    color: #fff;
    background: #95a5a6;
    border-radius: 3px;
    padding: 2px 5px;
    margin-left: 4px;
    vertical-align: middle;
}
.lang-toggle.pending {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: auto;
}
.lang-toggle.pending:hover { background: inherit; }
.lang-label .hist-badge,
.lang-label .exp-badge {
    font-size: 9px;
    color: #999;
    background: none;
    border: 1px solid #ccc;
    padding: 1px 3px;
}

/* Language selector modal */
.lang-modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.4);
    z-index: 2000;
    justify-content: center;
    align-items: center;
}
.lang-modal-overlay.open { display: flex; }
.lang-modal {
    background: #fff;
    border-radius: 14px;
    width: 90vw;
    max-width: 600px;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
    box-shadow: 0 8px 32px rgba(0,0,0,0.2);
}
.lang-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px 12px;
    border-bottom: 1px solid #eee;
}
.lang-modal-title {
    font-size: 16px;
    font-weight: 700;
    color: #1a1a2e;
}
.lang-modal-actions-top { display: flex; gap: 6px; }
.lang-modal-body {
    flex: 1;
    overflow-y: auto;
    padding: 12px 20px;
    -webkit-overflow-scrolling: touch;
}
.lang-modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 12px 20px 16px;
    border-top: 1px solid #eee;
}

/* Groups inside modal */
.lang-group {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    width: 100%;
    padding: 6px 0;
    border-bottom: 1px solid #f0f0f0;
}
.lang-group:last-child { border-bottom: none; }
.lang-group-label {
    flex-shrink: 0;
    width: 72px;
    font-size: 0.7rem;
    font-weight: 600;
    color: #888;
    padding-top: 5px;
    line-height: 1.2;
}
.lang-group-toggles {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    flex: 1;
}

/* Toggle pills inside modal */
.lang-toggle {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    border-radius: 20px;
    background: #f0f2f5;
    font-size: 12px;
    cursor: pointer;
    user-select: none;
    transition: all 0.15s;
    border: 2px solid transparent;
}
.lang-toggle.active {
    background: var(--accent-tint);
    border-color: var(--accent);
}
.lang-toggle input { display: none; }
.lang-toggle .dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    background: #ccc;
    transition: background 0.15s;
}
.lang-toggle.active .dot { background: var(--accent); }
.lang-toggle.experimental { }
.lang-toggle.experimental.active { }


/* RTL note */
.rtl-note {
    text-align: center;
    padding: 8px 16px;
    margin-bottom: 10px;
    font-size: 12px;
    color: #888;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    flex-wrap: wrap;
}
.rtl-switch {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    font-size: 12px;
    color: #555;
    font-weight: 600;
    white-space: nowrap;
}
.rtl-switch input { display: none; }
.rtl-switch-slider {
    position: relative;
    width: 34px;
    height: 18px;
    background: #ccc;
    border-radius: 9px;
    transition: background 0.2s;
    flex-shrink: 0;
}
.rtl-switch-slider::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    background: #fff;
    border-radius: 50%;
    transition: transform 0.2s;
}
.rtl-switch input:checked + .rtl-switch-slider {
    background: var(--accent);
}
.rtl-switch input:checked + .rtl-switch-slider::after {
    transform: translateX(16px);
}

/* RTL native direction mode */
.lang-row.rtl-native .lang-text {
    direction: rtl;
}

/* Empty message */
.empty-message {
    text-align: center;
    padding: 40px 20px;
    color: #999;
    font-size: 15px;
}

/* Map container */
.map-container {
    position: relative;
    background: #fff;
    border-radius: 12px;
    padding: 30px 40px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.06);
    overflow: visible;
    display: inline-block;
    min-width: 320px;
}

.map-toolbar {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 8px;
}

/* Wrapper to center the inline-block map container */
.map-wrapper {
    text-align: center;
}

.lines-svg {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    pointer-events: none;
    z-index: 1;
}

#langRows {
    position: relative;
    z-index: 2;
    display: inline-block;
    min-width: 100%;
}

/* Language row */
.lang-row {
    display: flex;
    align-items: baseline;
    margin-bottom: 60px;
    flex-wrap: nowrap;
    white-space: nowrap;
    position: relative;
    cursor: grab;
    transition: opacity 0.15s, background 0.15s;
    border-radius: 6px;
    padding: 4px 8px;
    margin-left: -8px;
    margin-right: -8px;
}
.lang-row:last-child { margin-bottom: 0; }
.lang-row.dragging { opacity: 0.7; z-index: 1000; }

.lang-label {
    font-weight: 700;
    font-size: 16px;
    color: #333;
    min-width: 160px;
    width: 240px;
    margin-right: 20px;
    flex-shrink: 0;
    cursor: grab;
    touch-action: none;
    user-select: none;
    text-align: left;
}

.lang-row.dragging .lang-label {
    cursor: grabbing;
}

.lang-text {
    display: flex;
    align-items: baseline;
    gap: 0;
    flex-wrap: nowrap;
}
/* RTL languages: segments flow left-to-right like all languages (for word-order comparison),
   but text within each segment renders right-to-left */
.lang-row[data-lang="ar"] .segment,
.lang-row[data-lang="ar_eg"] .segment,
.lang-row[data-lang="he"] .segment,
.lang-row[data-lang="ar"] .segment-input,
.lang-row[data-lang="ar_eg"] .segment-input,
.lang-row[data-lang="he"] .segment-input {
    direction: rtl;
    unicode-bidi: isolate;
}

.segment {
    /* Tibetan font fallback scoped here (NOT on body — see body rule
     * for why Kailasa in the global cascade breaks button text
     * centring on iOS Safari). bo / xct / dz / khg / xsr / sik / lbj /
     * bft / xkz / xct_litpr sentence segments need this chain.
     * Inherits everything else from body, then appends Tibetan
     * options for codepoints body's chain doesn't cover. */
    /* System sans (covers Latin / Greek / Cyrillic) MUST precede
       'Noto Serif Tibetan': that webfont is loaded for Tibetan but also
       carries SERIF Latin glyphs, so on iOS — where 'Segoe UI' / 'Noto Sans
       JP'… are absent — Latin was falling through to it and rendering serif,
       while Greek/Cyrillic (not in Noto Serif Tibetan) dropped to the system
       sans. Inserting -apple-system etc. here keeps all alphabetic scripts
       uniformly sans-serif; only Tibetan reaches the serif Tibetan fallback. */
    font-family: 'Noto Sans KR Old Jamo',
        'Segoe UI', 'Noto Sans JP', 'Noto Sans KR', 'Noto Sans SC', 'Noto Sans TC', 'Noto Sans Thai',
        -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Roboto', 'Arial',
        'Noto Serif Tibetan', 'Kailasa', 'Microsoft Himalaya', 'Jomolhari', 'Tibetan Machine Uni',
        sans-serif;
    font-size: 20px;
    font-weight: 600;
    padding: 2px 4px;
    border-radius: 3px;
    position: relative;
    cursor: default;
    transition: all 0.15s;
    white-space: nowrap;
}
.segment:hover {
    transform: scale(1.05);
    z-index: 10;
}
.segment-dual {
    display: inline-flex;
    gap: 6px;
    align-items: flex-end;
}
.hiero-pair {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 0;
}
.segment-hiero {
    font-family: 'Noto Sans Egyptian Hieroglyphs', 'Noto Sans Cuneiform', sans-serif;
    font-size: 24px;
    font-weight: 700;
}
.segment-translit {
    font-size: 14px;
    font-weight: 400;
    opacity: 0.65;
    /* Egyptological alef ꜣ (U+A723) and ayin ꜥ (U+A725) are not in the iOS
       system fonts. Gentium Plus and Charis SIL both carry them. */
    font-family: "Gentium Plus", "Charis SIL", "Noto Serif", Georgia, serif;
}
.segment-space {
    width: 6px;
    display: inline-block;
}
.segment-punct {
    font-size: 20px;
    font-weight: 600;
    color: #888;
    padding: 2px 0 2px 1px;
}
.segment-compound {
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

/* Mobile-only action bar — hidden on desktop. Inside the mobile
   media query below, this gets `display: flex` when the row has
   .show-actions (tap-toggled). Without this default rule, the bar
   would render as a default <div> (block) on PC and show the emoji
   buttons all the time. */
.mobile-action-bar { display: none; }

/* Copy & Edit buttons */
.copy-btn, .edit-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: #fff;
    border: 1px solid #ddd;
    border-radius: 4px;
    width: 28px;
    height: 28px;
    font-size: 14px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.15s;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10;
    color: #666;
}
.edit-btn { right: 4px; }
.copy-btn { right: 36px; }
.lang-row:hover .edit-btn,
.lang-row:hover .copy-btn {
    opacity: 1;
}
.edit-btn:hover, .copy-btn:hover {
    background: var(--accent-tint);
    border-color: var(--accent);
    color: var(--accent-dark);
}

/* Editing overlay — covers entire page */
.edit-overlay {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: linear-gradient(135deg, rgba(30,30,50,0.4) 0%, rgba(60,60,90,0.3) 100%);
    backdrop-filter: blur(2px);
    z-index: 50;
    animation: fadeInOverlay 0.2s ease-out;
}
@keyframes fadeInOverlay {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* Editing mode */
.lang-row.editing {
    position: fixed;
    z-index: 51;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    background: linear-gradient(135deg, #ffffff 0%, #f8faff 100%);
    flex-wrap: wrap;
    white-space: normal;
    cursor: default;
    padding: 24px 32px 16px;
    overflow-x: hidden;
    overflow-y: auto;
    max-height: 80vh;
    border-radius: 14px;
    box-shadow: 0 8px 40px rgba(var(--accent-rgb), 0.22), 0 0 0 1px rgba(var(--accent-rgb), 0.12);
    width: 85vw;
    max-width: 1200px;
    box-sizing: border-box;
    max-height: 85vh;
    overflow-y: auto;
}
.lang-row.editing:active {
    cursor: default;
}
.lang-row.editing .edit-btn,
.lang-row.editing .copy-btn {
    display: none;
}
.lang-row.editing .lang-label {
    width: 100%;
    font-size: 18px;
    margin-bottom: 12px;
    text-align: center;
}
.lang-row.editing .lang-text {
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
    width: 100%;
}

/* Segment wrapper — vertical layout with handle on top, delete on bottom */
.segment-input-wrapper {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    border-radius: 8px;
    padding: 4px 2px;
    transition: background 0.15s;
    background: rgba(0,0,0,0.02);
    border: 1px solid transparent;
}
.segment-input-wrapper:hover {
    background: rgba(var(--accent-rgb), 0.06);
    border-color: rgba(var(--accent-rgb), 0.15);
}
.segment-input-wrapper.dragging { opacity: 0.4; }
.segment-input-wrapper.drag-over-left {
    box-shadow: -3px 0 0 0 var(--accent);
}
.segment-input-wrapper.drag-over-right {
    box-shadow: 3px 0 0 0 var(--accent);
}

/* Segment ID badge */
.seg-id-badge {
    font-size: 10px;
    font-weight: 700;
    color: #fff;
    border-radius: 3px;
    padding: 1px 5px;
    line-height: 1.3;
    user-select: none;
}

/* Drag handle — top of wrapper */
.drag-handle {
    font-size: 16px;
    color: #bbb;
    cursor: grab;
    padding: 2px 4px;
    user-select: none;
    line-height: 1;
    transition: color 0.15s;
}
.segment-input-wrapper:hover .drag-handle {
    color: var(--accent);
}
.drag-handle:active { cursor: grabbing; }

/* Delete button — bottom of wrapper */
.seg-delete-btn {
    font-size: 16px;
    color: #ccc;
    cursor: pointer;
    padding: 2px 4px;
    line-height: 1;
    user-select: none;
    transition: color 0.15s;
}
.seg-delete-btn:hover {
    color: #e74c3c;
}

.add-segment-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border: 2px dashed #ccc;
    border-radius: 8px;
    background: transparent;
    color: #999;
    font-size: 20px;
    cursor: pointer;
    margin-left: 4px;
    transition: all 0.15s;
    flex-shrink: 0;
    align-self: center;
}
.add-segment-btn:hover {
    border-color: var(--accent);
    color: var(--accent);
    background: rgba(var(--accent-rgb), 0.05);
}

.add-segment-menu {
    position: absolute;
    background: #fff;
    border: 1px solid #ddd;
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.12);
    padding: 4px 0;
    z-index: 100;
    max-height: 200px;
    overflow-y: auto;
}
.add-segment-menu-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    font-size: 13px;
    cursor: pointer;
    white-space: nowrap;
}
.add-segment-menu-item:hover {
    background: #f0f2f5;
}
.add-segment-menu-item .seg-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}

.segment-input {
    font-size: 22px;
    font-weight: 600;
    padding: 6px 8px;
    border: 1px dashed;
    border-radius: 6px;
    background: #fff;
    outline: none;
    font-family: inherit;
    min-width: 40px;
    text-align: center;
}
.segment-input:focus {
    box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.25);
    border-style: solid;
}

.save-bar {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 12px;
    width: 100%;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid rgba(var(--accent-rgb), 0.15);
}
.save-bar .btn {
    padding: 10px 24px;
    font-size: 14px;
}

.cancel-btn {
    background: #f0f0f0;
    color: #666;
}

/* Clickable seg-id-badge in edit mode */
.segment-input-wrapper .seg-id-badge {
    cursor: pointer;
    transition: transform 0.1s, box-shadow 0.1s;
}
.segment-input-wrapper .seg-id-badge:hover {
    transform: scale(1.15);
    box-shadow: 0 2px 6px rgba(0,0,0,0.2);
}

/* Active item in segment type menu */
.add-segment-menu-item.active {
    background: var(--accent-tint);
    font-weight: 600;
}

/* Touch dragging */
.touch-dragging {
    opacity: 0.85;
    box-shadow: 0 8px 24px rgba(0,0,0,0.2);
    border-radius: 8px;
    background: #fff;
}
.touch-placeholder {
    border: 2px dashed var(--accent);
    border-radius: 8px;
    background: rgba(var(--accent-rgb), 0.05);
    min-height: 40px;
}

/* Footer */
.footer {
    margin-top: 15px;
    text-align: center;
    display: flex;
    gap: 8px;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
}
.footer-sep {
    width: 1px;
    height: 20px;
    background: #ccc;
    margin: 0 4px;
}
.btn-share { font-weight: 700; }
.btn-x { background: #000; color: #fff; }
.btn-x:hover { background: #333; }
.btn-fb { background: #1877f2; color: #fff; }
.btn-fb:hover { background: #1565c0; }
.btn-line { background: #06c755; color: #fff; }
.btn-line:hover { background: #05a847; }
.site-footer {
    margin-top: 20px;
    padding: 12px 0;
    text-align: center;
    font-size: 0.82rem;
    color: #888;
    border-top: 1px solid #ddd;
}
.site-footer a {
    color: #666;
    text-decoration: none;
}
.site-footer a:hover {
    color: #333;
    text-decoration: underline;
}
.footer-dot {
    margin: 0 6px;
    color: #ccc;
}
.site-footer-links {
    margin-bottom: 8px;
}
.disclaimer {
    font-size: 0.75rem;
    color: #aaa;
    margin: 8px 0 0;
    line-height: 1.6;
}
.disclaimer a {
    color: #999;
}
.disclaimer a:hover {
    color: #333;
}
.copy-toast {
    position: fixed;
    bottom: 30px;
    left: 50%;
    transform: translateX(-50%);
    background: #333;
    color: #fff;
    padding: 8px 20px;
    border-radius: 20px;
    font-size: 13px;
    opacity: 0;
    transition: opacity 0.3s;
    pointer-events: none;
    z-index: 1000;
}
.copy-toast.show { opacity: 1; }

/* UI polish: back-to-top floating button (used by index.html and tree.html). */
.back-to-top {
    position: fixed;
    right: max(16px, calc(env(safe-area-inset-right) + 8px));
    bottom: max(16px, calc(env(safe-area-inset-bottom) + 8px));
    width: 44px; height: 44px; line-height: 1;
    background: rgba(255,255,255,0.97); border: 1px solid #d0d0d0;
    border-radius: 50%; cursor: pointer;
    font-size: 22px; color: #444;
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
    z-index: 100; user-select: none;
    transition: background-color 0.15s, transform 0.1s;
}
.back-to-top:hover { background: #f3f4f6; }
.back-to-top:active { transform: scale(0.94); }
.back-to-top:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.back-to-top[hidden] { display: none; }

/* Responsive */
@media (max-width: 768px) {
    body { padding: 10px; overflow-x: hidden; }
    .container { max-width: 100vw; }
    .control-row { flex-direction: column; align-items: stretch; }
    .map-container { padding: 15px 10px; min-width: 0; }
    /* Audit Task 232: prevent iOS Safari focus auto-zoom (font < 16px). */
    input[type="text"], input[type="search"], input[type="number"],
    input[type="email"], input[type="tel"], input[type="url"],
    select, textarea {
        font-size: 16px !important;
    }
    /* Language name: allow wrapping on mobile */
    .lang-label { min-width: 70px; width: 70px; font-size: 10px; white-space: normal; word-break: break-word; line-height: 1.3; flex-shrink: 0; margin-right: 6px; }
    .segment { font-size: 16px; }
    .lang-row { margin-bottom: 40px; flex-wrap: nowrap; white-space: nowrap; }
    /* Export mode: override mobile constraints for full-width export */
    .export-mode .lang-label { min-width: 160px; width: 240px; font-size: 16px; overflow: visible; text-overflow: unset; margin-right: 20px; }
    .export-mode .segment { font-size: 20px; }
    .export-mode .lang-row { margin-bottom: 60px; }
    .export-mode { padding: 30px 40px; }

    /* Compact language summary pills for mobile */
    .lang-summary { gap: 3px; }
    .lang-pill { font-size: 10px; }
    .btn-open-modal { font-size: 10px; padding: 2px 8px; }

    /* Compact modal for mobile */
    .lang-modal {
        width: 95vw;
        max-height: 85vh;
        border-radius: 10px;
    }
    .lang-modal-header { padding: 12px 14px 10px; }
    .lang-modal-body { padding: 8px 14px; }
    .lang-modal-footer { padding: 10px 14px 14px; }
    .lang-modal-title { font-size: 14px; }
    .lang-toggle {
        font-size: 11px;
        padding: 3px 7px;
        gap: 3px;
        border-width: 1.5px;
    }
    .lang-toggle .dot { width: 6px; height: 6px; }
    .lang-group { gap: 4px; padding: 4px 0; }
    .lang-group-label { width: 52px; font-size: 0.6rem; padding-top: 4px; }
    .lang-group-toggles { gap: 3px; }

    /* Horizontal scroll for long language rows */
    .map-wrapper {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Mobile editing improvements */
    .lang-row.editing {
        width: 95vw;
        padding: 16px 12px 12px;
        max-height: 90vh;
    }
    .lang-row.editing .lang-label {
        font-size: 15px;
        margin-bottom: 8px;
    }
    .lang-row.editing .lang-text {
        gap: 6px;
    }
    .segment-input {
        font-size: 16px;
        padding: 5px 6px;
        min-width: 36px;
    }
    .segment-input-wrapper {
        padding: 3px 1px;
    }
    .drag-handle {
        font-size: 18px;
        padding: 4px 8px;
    }
    .seg-delete-btn {
        font-size: 18px;
        padding: 4px 8px;
    }
    .seg-id-badge {
        font-size: 9px;
        padding: 2px 4px;
    }
    .save-bar {
        margin-top: 12px;
        padding-top: 10px;
    }
    .save-bar .btn {
        padding: 8px 20px;
        font-size: 13px;
    }
    .add-segment-btn {
        width: 32px;
        height: 32px;
        font-size: 18px;
    }
    .add-segment-menu {
        max-height: 50vh;
    }

    /* Mobile: hide copy/edit buttons, show on tap below text */
    .edit-btn, .copy-btn {
        display: none !important;
    }
    .lang-row { position: relative; }
    .lang-row.show-actions .mobile-action-bar {
        display: flex !important;
    }
    .mobile-action-bar {
        display: none;
        position: absolute;
        bottom: -28px;
        left: 50%;
        transform: translateX(-50%);
        z-index: 10;
        gap: 8px;
    }
    .mobile-action-bar button {
        background: rgba(255,255,255,0.97);
        border: 1px solid #ccc;
        border-radius: 6px;
        padding: 6px 16px;
        font-size: 14px;
        cursor: pointer;
        display: flex;
        align-items: center;
        gap: 4px;
        box-shadow: 0 2px 6px rgba(0,0,0,0.12);
        white-space: nowrap;
    }
    .mobile-action-bar button:active { background: #f0f0f0; }

    /* Sentence row compact on mobile */
    .sentence-row { flex-direction: column; align-items: stretch; gap: 4px; }
    .sentence-label { font-size: 11px; }
    .sentence-nav select { font-size: 12px; padding: 5px 6px; }

    /* Lang select button compact */
    .btn-lang-select { font-size: 11px; padding: 5px 10px; }

    /* Editing: horizontal scroll for segments + reorder buttons */
    .lang-row.editing .lang-text {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        flex-wrap: nowrap;
        padding-bottom: 8px;
    }
    .segment-input-wrapper {
        flex-shrink: 0;
    }
    /* Hide drag handle on mobile, show move buttons instead */
    .drag-handle { display: none; }
    .seg-move-btns { display: flex !important; }
}

/* Segment move buttons (for mobile, hidden on desktop) */
.seg-move-btns {
    display: none;
    flex-direction: column;
    gap: 1px;
    margin-right: 2px;
}
.seg-move-btn {
    background: none;
    border: 1px solid #ddd;
    border-radius: 2px;
    padding: 0 3px;
    font-size: 9px;
    line-height: 1.2;
    cursor: pointer;
    color: #999;
}
.seg-move-btn:hover { background: #f0f2f5; color: #333; }

/* ============================================================
   Chrome-toggle button (clean-view mode) — 2026-05-26
   Spec: docs/superpowers/specs/2026-05-26-chrome-toggle-design.md
   ============================================================ */
.chrome-toggle-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px;
    background: transparent; border: 1px solid #d0d0d0; border-radius: 6px;
    color: #444;
    cursor: pointer; user-select: none;
    transition: background-color 0.15s, color 0.15s, border-color 0.15s;
    padding: 0;
    margin-left: 8px;
}
.chrome-toggle-btn:hover { background: #f3f4f6; }
.chrome-toggle-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.chrome-toggle-btn:active { background: #e5e7eb; }
body.chrome-hidden .chrome-toggle-btn {
    background: rgba(0,0,0,0.4);
    color: #fff;
    border-color: rgba(255,255,255,0.45);
}
.chrome-toggle-btn .icon-on,
.chrome-toggle-btn .icon-off { width: 20px; height: 20px; display: block; }
.chrome-toggle-btn .icon-off { display: none; }
body.chrome-hidden .chrome-toggle-btn .icon-on  { display: none; }
body.chrome-hidden .chrome-toggle-btn .icon-off { display: block; }

/* PC: chrome-toggle lives ABOVE the zoom buttons inside .right-controls.
   Match the round shape of the 2D/3D toggle so the right-edge column
   reads as one consistent button stack [chrome-toggle][zoom +/-][2D][gear].
   margin-left:8px (default) doesn't apply inside the right-controls
   flex column — its `align-items: center` handles horizontal placement. */
.right-controls > .chrome-toggle-btn {
    margin-left: 0;
    border-radius: 50%;
}

/* Mobile: chrome-toggle sits BETWEEN trivia and hamburger.
   User-requested visual: [LangMap trivia] _______________ [chrome-toggle hamburger]
   — LangMap and trivia stuck together on the LEFT, chrome-toggle and
   hamburger stuck together on the RIGHT, with the auto-margin gap in
   between. We zero out .site-header-bar's flex gap on mobile so the
   only spacing comes from explicit margins below. */
@media (max-width: 640px) {
    .site-header-bar { gap: 0; }
    .site-header-bar > .trivia-btn { margin-left: 6px; }
    .site-header-bar > .chrome-toggle-btn { margin-left: auto; }
    .site-header-bar > .chrome-toggle-btn + .hamburger-btn { margin-left: 6px; }
}

/* Hide map-chrome components when toggled OFF. !important wins over
   per-component display rules (e.g. .compare-fab.visible { display: inline-flex }). */
body.chrome-hidden #word-select,
body.chrome-hidden #word-definition,
/* The "?" goes with the panel it opens. Hiding the panel but leaving the icon
   left a control that visibly did nothing when clicked — the toggle flipped
   aria-expanded and the definition stayed display:none (owner 2026-08-26). */
body.chrome-hidden #word-def-toggle,
body.chrome-hidden #era-filter-row,
body.chrome-hidden .lang-search-wrap,
body.chrome-hidden #compare-fab,
body.chrome-hidden .url-watermark,
body.chrome-hidden #hm-lang-filter-btn,
body.chrome-hidden #char-random-btn {
    display: none !important;
}

/* Pre-body-class state for FOUC avoidance: same hide rules apply when
   <html data-wm-chrome="hidden"> is set by the head script (Task 2 Step 1).
   Cleared once Task 2 Step 3's body-class transfer runs. */
html[data-wm-chrome="hidden"] body #word-select,
html[data-wm-chrome="hidden"] body #word-definition,
html[data-wm-chrome="hidden"] body #word-def-toggle,
html[data-wm-chrome="hidden"] body #era-filter-row,
html[data-wm-chrome="hidden"] body .lang-search-wrap,
html[data-wm-chrome="hidden"] body #compare-fab,
html[data-wm-chrome="hidden"] body .url-watermark,
html[data-wm-chrome="hidden"] body #hm-lang-filter-btn,
html[data-wm-chrome="hidden"] body #char-random-btn {
    display: none !important;
}

/* Aggressive-hide additions (2026-05-26): when chrome is hidden, also strip
   the header chrome itself — hide nav/trivia/ui-lang/url (everything inside
   .header-collapse), hide the right-side 2D/3D toggle and gear button, and
   make the header bar background fully transparent. Only the LangMap logo,
   the hamburger menu, and the chrome-toggle itself remain visible. */
body.chrome-hidden .trivia-btn,
body.chrome-hidden .toggle-3d-btn,
body.chrome-hidden .settings-toggle,
body.chrome-hidden .settings-fab,
body.chrome-hidden .right-secondary-controls,
html[data-wm-chrome="hidden"] body .trivia-btn,
html[data-wm-chrome="hidden"] body .toggle-3d-btn,
html[data-wm-chrome="hidden"] body .settings-toggle,
html[data-wm-chrome="hidden"] body .settings-fab,
html[data-wm-chrome="hidden"] body .right-secondary-controls {
    display: none !important;
}
/* .header-collapse: on PC (display:contents = always-inline) hide most
   children when chrome is off, BUT keep .header-url (langmaps.com)
   visible — per user 2026-05-26 it anchors the right side of the header
   when chrome-toggle is in the right-controls column, so the header
   doesn't look bare with just LangMap on the left. On mobile, leave
   .header-collapse alone — the existing hamburger checkbox controls
   its open/closed state, so pressing the hamburger reveals the full
   menu even in chrome-hidden mode. */
@media (min-width: 641px) {
    body.chrome-hidden .header-collapse > *:not(.header-url),
    html[data-wm-chrome="hidden"] body .header-collapse > *:not(.header-url) {
        display: none !important;
    }
    /* Restore .header-url's natural auto-margin so it floats to the right
       edge of the header. The existing `.header-ui-lang + .header-url
       { margin-left: 12px }` rule (line 84) still matches even when
       .header-ui-lang is display:none, which pins the URL right next to
       LangMap. Override here when ui-lang and friends are hidden. */
    body.chrome-hidden .site-header-bar .header-url,
    html[data-wm-chrome="hidden"] body .site-header-bar .header-url {
        margin-left: auto !important;
    }
}
body.chrome-hidden .site-header-bar,
html[data-wm-chrome="hidden"] body .site-header-bar {
    background: transparent !important;
    backdrop-filter: none !important;
    border-bottom: none !important;
    box-shadow: none !important;
}

/* LangMap logo color adapts to map background in chrome-hidden mode:
   - 2D mode: black text — visible against light tile maps
   - 3D mode: white text — visible against darker globe textures
   Plain color only; no text-shadow per user direction. */
body.chrome-hidden:not(.is-3d) .site-header-bar .logo {
    color: #000 !important;
}
body.chrome-hidden.is-3d .site-header-bar .logo {
    color: #fff !important;
}

/* Mobile + 3D + chrome-hidden: hamburger's "三" glyph is #444 by default,
   which blends into the dark globe background. Switch it to white. */
@media (max-width: 640px) {
    body.chrome-hidden.is-3d .hamburger-btn {
        color: #fff !important;
        border-color: rgba(255,255,255,0.6) !important;
    }
}

/* Play ▾ menu — consolidates the game launchers (Trivia / Langle / quizzes)
   into one header entry to declutter the bar. The original game buttons stay
   in the DOM (hidden) so their existing wiring/labels are reused. */
.game-btn { display: none !important; }
.play-menu-wrap { position: relative; display: inline-flex; }
/* The Play launcher: gamepad icon + label + caret, all the same height and
   vertically centred (was an emoji + text + glyph of mismatched sizes). */
#play-menu-btn { height: 30px; padding: 0 12px; gap: 6px; line-height: 1; }
#play-menu-btn .play-btn-icon { width: 15px; height: 15px; flex: none; }
#play-menu-btn .trivia-btn-label { line-height: 1; }
.play-menu-wrap .play-caret { display: inline-flex; align-items: center; margin-left: 1px; opacity: .6; }
.play-menu-wrap .play-caret svg { width: 11px; height: 11px; transition: transform .15s ease; }
#play-menu-btn[aria-expanded="true"] .play-caret svg { transform: rotate(180deg); }
#play-menu {
    display: none;
    position: absolute; top: 100%; left: 0; margin-top: 4px;
    background: #fff; border: 1px solid #e0e0e0; border-radius: 10px;
    box-shadow: 0 6px 22px rgba(0,0,0,.15); padding: 5px; min-width: 180px;
    z-index: 100003;
}
#play-menu.open { display: block; }
.play-menu-item {
    display: flex; align-items: center; gap: 9px; width: 100%;
    padding: 9px 11px; border: 0; background: none; border-radius: 7px;
    font-size: 13px; color: #222; cursor: pointer; text-align: left; white-space: nowrap;
    font-family: inherit;
}
.play-menu-item:hover, .play-menu-item:focus-visible { background: #f3f4f6; outline: none; }

/* UI-language selector relocated from the header to a small pill at the bottom
   of the map (header declutter). Floats above the map, below modals. */
.ui-lang-footer {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    bottom: 12px;
    z-index: 1200;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: rgba(255,255,255,0.94);
    border: 1px solid #e0e0e0;
    border-radius: 999px;
    padding: 3px 10px 3px 12px;
    box-shadow: 0 2px 12px rgba(0,0,0,0.14);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    max-width: calc(100vw - 24px);
}
.ui-lang-footer .ui-lang-footer-icon { font-size: 14px; line-height: 1; }
.ui-lang-footer .header-ui-lang {
    margin: 0;
    border: 0;
    background: transparent;
    min-width: 120px;
    max-width: 200px;
    font-size: 12px;
    color: #333;
    cursor: pointer;
}
@media (max-width: 640px) {
    /* In the hamburger drawer the language selector is a normal full-width row,
       not the floating desktop pill. */
    .ui-lang-footer {
        position: static; transform: none; max-width: none;
        display: flex; width: 100%; margin-top: 6px;
        border: 0; border-top: 1px solid #eee; border-radius: 0;
        box-shadow: none; background: none;
        -webkit-backdrop-filter: none; backdrop-filter: none;
        padding: 10px 2px 2px;
    }
    .ui-lang-footer .header-ui-lang {
        flex: 1; min-width: 0; max-width: none; font-size: 14px;
        padding: 8px; border: 1px solid #d0d0d0; border-radius: 6px;
    }
    /* On mobile the games show directly in the drawer, so drop the Play ▾
       wrapper and reveal the individual game launchers. */
    .header-collapse .play-menu-wrap { display: none; }
    .header-collapse .game-btn {
        display: flex !important;
        /* Full-width drawer rows, not gold pills: match the nav items. */
        width: 100%;
        justify-content: flex-start;
        margin-left: 0;
        padding: 10px 12px;
        border-radius: 8px;
        border: 1px solid #e5e7eb;
        background: #f9fafb;
        color: #374151;
        box-shadow: none;
        font-size: 15px;
    }
    .header-collapse .game-btn:hover { background: #f3f4f6; box-shadow: none; }
    /* Owner 2026-07-12: in simple-display (chrome-hidden) mode the game
       launchers (quiz / Langle / which-word / trivia) must STAY in the
       hamburger drawer — only the always-visible top bar should be stripped.
       The generic `body.chrome-hidden .trivia-btn { display:none }` rule
       (specificity 0,2,1) otherwise beats the drawer-reveal (0,2,0) and
       blanks them. These selectors are 0,3,1 so they win, re-revealing the
       game rows inside the open drawer while leaving the top bar clean. */
    body.chrome-hidden .header-collapse .game-btn,
    html[data-wm-chrome="hidden"] body .header-collapse .game-btn {
        display: flex !important;
    }
    /* Language picker as a full-width labelled row in the drawer. */
    .header-collapse .lang-picker { width: 100%; gap: 8px; }
    .header-collapse .lang-picker-label {
        display: inline; font-size: 15px; font-weight: 600; color: #374151;
    }
    .header-collapse .lang-picker-btn { margin-left: auto; }
}

/* ---------------------------------------------------------------------------
 * Unified UI-language picker (lang-picker.js) — a globe + current CODE button
 * to the left of the langmaps.com link, opening a "CODE  NativeName"
 * dropdown. Replaces the old .ui-lang-footer pill and the bare header select.
 * ------------------------------------------------------------------------- */
/* The native <select id="header-ui-lang"> is ONLY a data source for the
   lang-picker, which fronts it on every page — it must never be visible. Hide
   it at ALL times (not just after lang-picker.js adds .lang-picker-native),
   otherwise the empty, not-yet-populated select flashes in the header during
   load before the picker upgrades it. The site is fully JS-driven, so there's
   no no-JS state that needs the bare select as a fallback. (2026-07-05) */
.site-header-bar .header-ui-lang { display: none !important; }
.ui-lang-footer { display: none !important; }   /* superseded by the picker */

.lang-picker { position: relative; display: inline-flex; align-items: center; }
.lang-picker-label { display: none; }   /* shown only in the mobile drawer */

/* Unified Share — an icon only, no button chrome (share-button.js). */
.share-icon-btn {
    display: inline-flex; align-items: center; justify-content: center;
    /* flex-shrink:0 — .site-header-bar is a flex row, and a flex item shrinks
       below its declared width by default. On tablet widths the bar is full
       (nav + game buttons + share + lang picker + URL) and the 30px square was
       being squeezed to a sliver, which is what the reader saw on an iPad
       (owner 2026-09-20). The square is the hit target, so it must not give. */
    flex: 0 0 auto;
    width: 30px; height: 30px; padding: 0;
    background: transparent; border: 1px solid #d0d3dc; border-radius: 6px;
    color: #444; cursor: pointer;
    transition: background-color 0.15s, border-color 0.15s;
}
.share-icon-btn:hover { background: #f3f4f6; border-color: #b8bcc8; }
.share-icon-btn > svg { width: 15px; height: 15px; }
@media (max-width: 640px) {
    /* In the drawer keep it icon-sized (don't stretch to a full-width row). */
    .header-collapse .share-icon-btn { align-self: flex-start; }
}
/* Right-align the Share + language-picker + URL as ONE cluster (2026-07-05).
   Previously only .header-url carried `margin-left: auto`, so it flew to the
   right edge alone while the Share icon and lang-picker stayed pinned to the
   left next to the nav (and the map-page game buttons). Move the auto-margin
   onto the Share icon — the first member of the right cluster — so nav/games
   stay left and [share][lang][url] flush right together. Desktop only; the
   ≤640px hamburger drawer lays these out as full-width column rows itself. */
@media (min-width: 641px) {
    .site-header-bar .share-icon-btn { margin-left: auto; }
    /* Neutralize .header-url's own auto-margin once Share precedes it, else the
       two auto-margins split the free space and re-open a gap before the URL.
       (chrome-hidden mode re-asserts url's auto with !important — unaffected.) */
    .site-header-bar .share-icon-btn ~ .header-url { margin-left: 0; }
}
.lang-picker-btn {
    display: inline-flex; align-items: center; gap: 5px;
    flex: 0 0 auto;                  /* same reason as .share-icon-btn above */
    height: 30px; padding: 0 10px;   /* same height as the Share icon button */
    background: transparent;
    border: 1px solid #d0d3dc; border-radius: 6px;
    font-family: inherit; font-size: 12px; font-weight: 600; line-height: 1;
    color: #444; cursor: pointer;
    transition: background-color 0.15s, border-color 0.15s;
}
.lang-picker-btn:hover { background: #f3f4f6; border-color: #b8bcc8; }
.lang-picker-btn > svg { width: 15px; height: 15px; opacity: 0.75; }
.lang-picker-btn .lang-picker-caret { width: 10px; height: 10px; opacity: 0.55; transition: transform 0.15s ease; }
.lang-picker-btn[aria-expanded="true"] .lang-picker-caret { transform: rotate(180deg); }
.lang-picker-code { letter-spacing: 0.5px; }

.lang-picker-menu {
    position: absolute; top: calc(100% + 5px); left: 0;
    z-index: 1300;
    min-width: 190px; max-height: 340px; overflow-y: auto;
    background: #fff; border: 1px solid #e0e0e0; border-radius: 8px;
    box-shadow: 0 6px 22px rgba(0,0,0,0.16);
    padding: 4px; display: none;
}
.lang-picker-menu.open { display: block; }
.lang-picker-item {
    display: flex; align-items: center; gap: 9px; width: 100%;
    padding: 7px 10px; border: 0; border-radius: 6px;
    background: none; cursor: pointer; text-align: left;
    font-family: inherit; font-size: 13px; color: #333;
}
.lang-picker-item:hover, .lang-picker-item:focus-visible { background: #f3f4f6; outline: none; }
.lang-picker-item[aria-selected="true"] { background: var(--accent-tint, #eef2ff); font-weight: 600; }
.lang-picker-item-code {
    flex: none; min-width: 30px;
    font-size: 10px; font-weight: 700; letter-spacing: 0.5px; color: #8a8f9a;
}
[dir="rtl"] .lang-picker-menu { left: auto; right: 0; }

/* Play ▾ menu item with an optional localized descriptor line (e.g. Langle → a
   short "what is this" so an opaque proper-noun launcher is understandable). */
.play-menu-item-txt { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.25; }
.play-menu-item-sub { font-size: 11px; color: #9aa1ad; font-weight: 400; margin-top: 1px; }

/* Quiz modals: keep scrolling but hide the scrollbar (it showed on mobile where
   the fixed-height box/middle band can overflow). */
#lm-quiz-box, #lm-hquiz-box, #lm-quiz-box *, #lm-hquiz-box * { scrollbar-width: none; -ms-overflow-style: none; }
#lm-quiz-box::-webkit-scrollbar, #lm-hquiz-box::-webkit-scrollbar,
#lm-quiz-box *::-webkit-scrollbar, #lm-hquiz-box *::-webkit-scrollbar { width: 0; height: 0; display: none; }
