/* ==========================================================================
   松鼠工具箱 · 样式表
   主题：小工具都藏在树洞里。
   移动优先：默认样式面向手机，桌面端在 >= 900px 时叠加侧边栏布局。
   零外部依赖，不加载任何 CDN 字体或框架，不使用任何图片资源。
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

:root {
    /* 松鼠暖色 · 浅色模式。主色 #b35e16 配白字对比度 4.64:1，达 WCAG AA */
    --bg: #f5efe6;
    --bg-blur: rgba(245, 239, 230, .82);
    --surface: #fffdf9;
    --surface-2: #f1e9dc;
    --surface-3: #e7dcc8;
    --border: #e3d7c4;
    --text: #2c2118;
    --text-2: #6b5a47;
    --text-3: #9a8772;
    --accent: #b35e16;
    --accent-ink: #ffffff;
    --accent-soft: #fbe9d6;
    --ok: #4f8a3c;
    --ok-soft: #eaf3e2;
    --warn: #b5761a;
    --warn-soft: #f8ecd6;
    --danger: #c0492f;
    --danger-soft: #fbe6e0;

    /* 树洞：洞壁木质渐变 —— 比页面底色更深，才有"凹进去"的观感 */
    --hole-bg: #dcc4a1;
    --hole-bg-2: #c9a97f;
    --hole-rim: #a8834f;
    --hole-inset: rgba(88, 58, 24, .40);
    --hole-lip: rgba(255, 246, 232, .30);
    /* 文字配色已按最深的渐变端算过对比度：#2a1c10 = 7.30:1，#4a3520 = 5.20:1，均达 AA */
    --hole-text: #2a1c10;
    --hole-text-2: #4a3520;

    --radius: 14px;
    --radius-sm: 10px;
    --shadow-sm: 0 1px 2px rgba(70, 45, 20, .07);
    --shadow: 0 1px 2px rgba(70, 45, 20, .06), 0 8px 20px rgba(70, 45, 20, .08);

    --topbar-h: 56px;
    --bottombar-h: 62px;
    --sidebar-w: 212px;
    /* 侧边栏与正文列之间的间距。桌面端 .shell 用它，圆桌的横向纠偏也用它
       （见文件末尾「圆桌的横向锚点」），两处必须同源。 */
    --shell-gap: 28px;

    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
            "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
    --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #16120d;
        --bg-blur: rgba(22, 18, 13, .82);
        --surface: #1f1812;
        --surface-2: #2a211a;
        --surface-3: #352a21;
        --border: #3a2e23;
        --text: #f1e7d8;
        --text-2: #b9a890;
        --text-3: #8a7862;
        --accent: #e3974c;
        --accent-ink: #2a1a0c;
        --accent-soft: #3a2a18;
        --ok: #7bbf57;
        --ok-soft: #1e2c16;
        --warn: #e0a94e;
        --warn-soft: #312514;
        --danger: #ef7a5e;
        --danger-soft: #331a14;

        /* 深色模式下洞口比页面更暗，靠边缘与内阴影勾出轮廓 */
        --hole-bg: #2b2118;
        --hole-bg-2: #1c150f;
        --hole-rim: #4d3b27;
        --hole-inset: rgba(0, 0, 0, .62);
        --hole-lip: rgba(255, 226, 180, .07);
        --hole-text: #f0e4d2;
        --hole-text-2: #b9a890;

        --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
        --shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 8px 20px rgba(0, 0, 0, .35);
    }
}

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    scroll-behavior: smooth;
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font);
    font-size: 15px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-wrap: break-word;
}

a {
    color: inherit;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
}

svg.ico { display: block; flex: none; }
code {
    font-family: var(--mono);
    font-size: .88em;
    background: var(--surface-2);
    padding: 1px 5px;
    border-radius: 5px;
    color: var(--text-2);
}

/* ---------------------------------------------------------------- 顶栏 */
.topbar {
    position: sticky;
    top: 0;
    z-index: 40;
    display: flex;
    align-items: center;
    gap: 10px;
    height: calc(var(--topbar-h) + env(safe-area-inset-top));
    padding: env(safe-area-inset-top) 16px 0;
    background: var(--bg-blur);
    -webkit-backdrop-filter: saturate(1.8) blur(14px);
    backdrop-filter: saturate(1.8) blur(14px);
    /* 提升为独立合成层：WebKit 历史上有带 backdrop-filter 的吸顶元素
       导致触摸命中测试错乱的问题，这行可规避。无视觉副作用 */
    -webkit-transform: translateZ(0);
    transform: translateZ(0);
    border-bottom: 1px solid var(--border);
}

.brand { display: flex; align-items: center; gap: 9px; min-width: 0; }

.brand-mark {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 8px;
    background: var(--accent);
    color: var(--accent-ink);
    font-size: 15px;
    font-weight: 600;
    flex: none;
}

.brand-name {
    font-size: 15.5px;
    font-weight: 600;
    letter-spacing: .2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ------------------------------------------------------- 布局容器 */
.shell { display: block; }

.main {
    padding: 20px 16px calc(var(--bottombar-h) + env(safe-area-inset-bottom) + 24px);
    max-width: 1080px;
    margin: 0 auto;
}

/* ------------------------------------------------ 侧边栏（仅桌面端） */
.sidebar { display: none; }

/* -------------------------------------------- 底部导航（仅移动端） */
.bottombar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    display: flex;
    background: var(--bg-blur);
    -webkit-backdrop-filter: saturate(1.8) blur(14px);
    backdrop-filter: saturate(1.8) blur(14px);
    /* 同 .topbar：规避 WebKit 对带 backdrop-filter 的固定元素命中测试异常 */
    -webkit-transform: translateZ(0);
    transform: translateZ(0);
    border-top: 1px solid var(--border);
    padding-bottom: env(safe-area-inset-bottom);
}

.bottom-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    height: var(--bottombar-h);
    font-size: 11px;
    color: var(--text-3);
    transition: color .15s ease;
    touch-action: manipulation;
}

.bottom-item .ico { width: 22px; height: 22px; }
.bottom-item.is-active { color: var(--accent); }

/* -------------------------------------------------------- 首页主视觉 */
.hero { padding: 6px 2px 22px; }

.hero-title {
    margin: 0 0 6px;
    font-size: 26px;
    font-weight: 700;
    letter-spacing: -.4px;
}

.hero-sub {
    margin: 0;
    color: var(--text-2);
    font-size: 14.5px;
}

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }

.chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 11px;
    border-radius: 20px;
    background: var(--surface);
    border: 1px solid var(--border);
    font-size: 12.5px;
    color: var(--text-2);
    box-shadow: var(--shadow-sm);
}

.chip b { font-weight: 600; color: var(--text); }
.chip-ok { background: var(--ok-soft); border-color: transparent; color: var(--ok); }
.chip-ok b { color: var(--ok); }

/* ------------------------------------------------------------ 分组 */
.group { margin-bottom: 26px; }

.group-title {
    margin: 0 0 12px 2px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-3);
    letter-spacing: .5px;
}

.grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px;
}

/* ------------------------------------------------------------ 卡片 */
/* ------------------------------------------------------------ 卡片 = 树洞
   观感由四件事合成：
   1) 洞壁木质渐变 —— 上沿深、下沿浅，模拟光线自上而下射入洞口
   2) inset 内阴影 —— 上沿压深、下沿一道微光反弹，做出凹陷纵深（最关键）
   3) 非对称圆角 —— 破掉规整的圆角矩形，像天然挖出来的洞
   4) 树皮色描边 —— 勾出洞口轮廓
   -------------------------------------------------------------------- */
.card {
    position: relative;
    display: flex;
    align-items: center;
    gap: 13px;
    padding: 15px 18px;
    background: linear-gradient(178deg, var(--hole-bg-2) 0%, var(--hole-bg) 94%);
    border: 1.5px solid var(--hole-rim);
    border-radius: 20px 26px 18px 24px / 26px 20px 28px 22px;
    box-shadow:
        inset 0 10px 18px -6px var(--hole-inset),
        inset 0 -6px 11px -8px var(--hole-lip),
        0 1px 3px rgba(70, 45, 20, .10);
    color: var(--hole-text);
    transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
    touch-action: manipulation;
    min-height: 68px;
}

.card:active { transform: scale(.985); }

@media (hover: hover) {
    .card:hover {
        border-color: var(--accent);
        box-shadow:
            inset 0 11px 20px -5px var(--hole-inset),
            inset 0 -6px 11px -8px var(--hole-lip),
            0 2px 10px rgba(70, 45, 20, .14);
    }
}

/* 头像做成洞口深处的小凹坑，比洞壁再深一层 */
.card-avatar {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    border-radius: 34% 38% 32% 36% / 36% 32% 38% 34%;
    background: rgba(60, 40, 18, .16);
    box-shadow: inset 0 2px 5px rgba(60, 40, 18, .26);
    color: var(--hole-text);
    font-size: 16px;
    font-weight: 600;
    flex: none;
}

/* 分类色改用深色天然色系，在木质洞壁上对比充足 */
.card-avatar[data-cat="text"]   { color: #2a3f5f; }
.card-avatar[data-cat="encode"] { color: #2c5418; }
.card-avatar[data-cat="dev"]    { color: #4a2c6b; }
.card-avatar[data-cat="life"]   { color: #7a3f08; }
.card-avatar[data-cat="play"]   { color: #6b2f5a; }
.card-avatar[data-cat="other"]  { color: #3a2a1c; }

@media (prefers-color-scheme: dark) {
    .card-avatar {
        background: rgba(0, 0, 0, .30);
        box-shadow: inset 0 2px 6px rgba(0, 0, 0, .50);
    }
    .card-avatar[data-cat="text"]   { color: #9dc0ea; }
    .card-avatar[data-cat="encode"] { color: #9ed47a; }
    .card-avatar[data-cat="dev"]    { color: #c4a6ee; }
    .card-avatar[data-cat="life"]   { color: #f0b877; }
    .card-avatar[data-cat="play"]   { color: #e6a0cc; }
    .card-avatar[data-cat="other"]  { color: #b9a890; }
}

.card-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }

.card-name {
    font-size: 14.5px;
    font-weight: 600;
    color: var(--hole-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* 三列布局下卡片只有 256px 宽，说明文字用两行截断而非单行省略，
   避免「算基础代谢与每日摄入建议，含千焦大卡换…」这种读不全的情况 */
.card-sum {
    font-size: 12.5px;
    color: var(--hole-text-2);
    line-height: 1.45;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ------------------------------------------------------ 工具页 */
.crumb {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 13px;
    color: var(--text-3);
    margin-bottom: 12px;
}

.crumb a { color: var(--accent); }
.crumb-sep { color: var(--text-3); }

.page-title {
    margin: 0 0 4px;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -.3px;
}

.page-sub {
    margin: 0 0 20px;
    color: var(--text-2);
    font-size: 14px;
}

.tool-form { display: flex; flex-direction: column; gap: 16px; }

/* 分段控件 */
/* ---------------------------------------------------------- 分段控件
   这三点都是为了「点下去立刻有反应」，缺一不可：
   1) 真实的 radio 铺满整个选项（inset:0 + opacity:0）—— 手指点到的就是 input 本身，
      不走 label→input 的关联。某些移动端浏览器对「label 包一个零尺寸隐藏 input」
      会失灵，铺满可以彻底绕开。
   2) 选中态由 input:checked + .seg-face 兄弟选择器驱动，纯 CSS 即时生效，
      不依赖服务端渲染的 .is-active（那个要等页面刷新才变，用户会以为点不动）。
   3) 选项本身不做 overflow 裁切，避免个别浏览器裁掉可点区域。 */
.segmented {
    display: flex;
    gap: 3px;
    padding: 3px;
    background: var(--surface-2);
    border-radius: 11px;
    width: fit-content;
    max-width: 100%;
    flex-wrap: wrap;
}

.seg {
    position: relative;
    display: inline-flex;
    min-width: 76px;
    border-radius: 9px;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

.seg input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    opacity: 0;
    cursor: pointer;
    z-index: 1;
}

.seg-face {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1;
    padding: 9px 18px;
    border-radius: 9px;
    font-size: 14px;
    line-height: 1.3;
    color: var(--text-2);
    transition: background .15s ease, color .15s ease;
}

.seg input:checked + .seg-face,
.seg.is-active .seg-face {
    background: var(--surface);
    color: var(--text);
    font-weight: 600;
    box-shadow: var(--shadow-sm);
}

/* ------------------------------------------------------------ Tab 标签页
   纯 CSS 实现（radio + 兄弟选择器），不依赖 JS。
   两个面板都留在 DOM 里，来回切换不会丢掉已经填好的值。 */
.tab-radio {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.tab-bar {
    display: flex;
    gap: 4px;
    padding: 4px;
    background: var(--surface-2);
    border-radius: 12px;
    margin-bottom: 20px;
}

.tab {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px 8px;
    border-radius: 9px;
    font-size: 14.5px;
    line-height: 1.3;
    color: var(--text-2);
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: background .15s ease, color .15s ease;
}

/* 面板默认隐藏，由对应的 radio 选中时显示 */
.tab-panel { display: none; }

#tab-calc:checked    ~ .panel-calc,
#tab-convert:checked ~ .panel-convert,
#conv-unit:checked   ~ .panel-conv-unit,
#conv-weight:checked ~ .panel-conv-weight { display: block; }

/* 选中的 tab 高亮 —— 纯 CSS，点了立刻变 */
#tab-calc:checked    ~ .tab-bar label[for="tab-calc"],
#tab-convert:checked ~ .tab-bar label[for="tab-convert"],
#conv-unit:checked   ~ .tab-bar label[for="conv-unit"],
#conv-weight:checked ~ .tab-bar label[for="conv-weight"] {
    background: var(--surface);
    color: var(--text);
    font-weight: 600;
    box-shadow: var(--shadow-sm);
}

/* 二级 tab 更紧凑一些 */
.tab-bar-sub { margin-bottom: 18px; }
.tab-bar-sub .tab { font-size: 13.5px; padding: 8px 6px; }

/* 字段 */
.field { display: flex; flex-direction: column; gap: 7px; }
.field-label { font-size: 13px; color: var(--text-2); font-weight: 500; }

/* 年龄 / 身高 / 体重 并排：三个数字输入在手机上也能放下 */
.field-row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
}

.input {
    width: 100%;
    padding: 12px 14px;
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: var(--mono);
    /* 必须 >= 16px，否则 iOS Safari 聚焦时会自动放大页面 */
    font-size: 16px;
    line-height: 1.5;
    resize: vertical;
    transition: border-color .15s ease, box-shadow .15s ease;
    -webkit-appearance: none;
    appearance: none;
}

.input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

/* 原生 select 必须自绘箭头 —— .input 的 appearance:none 会把系统箭头一并去掉，
   所以任何 <select> 都要加 class="input select"。箭头是内联 SVG data-URI，零外部资源 */
.select {
    appearance: none;
    -webkit-appearance: none;
    padding-right: 40px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236b5a47' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    cursor: pointer;
}

@media (prefers-color-scheme: dark) {
    .select {
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23b9a890' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    }
}

.field-result .js-copy { align-self: flex-start; }

/* 开关 */
.switch {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13.5px;
    color: var(--text-2);
    cursor: pointer;
    min-height: 32px;
    touch-action: manipulation;
}

.switch input { position: absolute; opacity: 0; width: 0; height: 0; }

.switch-track {
    position: relative;
    width: 40px;
    height: 24px;
    border-radius: 12px;
    background: var(--surface-3);
    flex: none;
    transition: background .18s ease;
}

.switch-track::after {
    content: "";
    position: absolute;
    top: 3px;
    left: 3px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
    transition: transform .18s ease;
}

.switch input:checked + .switch-track { background: var(--accent); }
.switch input:checked + .switch-track::after { transform: translateX(16px); }

.switch-text { line-height: 1.45; }

/* 按钮 */
.actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* ------------------------------------------------- 单位换算的两个模式 */

/* 一行里混合「输入框 + 单位文字 / 下拉」 */
.inline-group {
    display: flex;
    align-items: center;
    gap: 8px;
}

.inline-group .input { flex: 1; min-width: 0; }

.inline-word {
    flex: none;
    font-size: 14px;
    color: var(--text-2);
}

.inline-group .ig-unit {
    flex: none;
    width: auto;
    min-width: 104px;
}

/* 「交换两个单位」的按钮 */
.swap-wrap {
    display: flex;
    justify-content: center;
    margin: 2px 0;
}

.swap-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    min-height: 44px;
    padding: 0 18px;
    border-radius: 22px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--accent);
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: var(--shadow-sm);
    transition: transform .1s ease, border-color .15s ease;
    touch-action: manipulation;
    -webkit-appearance: none;
    appearance: none;
}

.swap-btn:active { transform: scale(.95); }
.swap-btn .ico { width: 18px; height: 18px; }

@media (hover: hover) {
    .swap-btn:hover { border-color: var(--accent); }
}

/* 只读的结果框：外观与 .input 一致，但底色不同以示「不是输入项」 */
.unit-output {
    display: flex;
    align-items: center;
    min-height: 46px;
    background: var(--surface-2);
    color: var(--accent);
    font-weight: 700;
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 46px;
    padding: 0 22px;
    border-radius: 11px;
    border: 1px solid transparent;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    transition: transform .1s ease, background .15s ease, border-color .15s ease;
    touch-action: manipulation;
    -webkit-appearance: none;
    appearance: none;
}

.btn:active { transform: scale(.97); }

.btn-primary { background: var(--accent); color: var(--accent-ink); }

.btn-ghost {
    background: var(--surface);
    color: var(--text-2);
    border-color: var(--border);
}

@media (hover: hover) {
    .btn-primary:hover { filter: brightness(1.06); }
    .btn-ghost:hover { border-color: var(--accent); color: var(--accent); }
}

.alert-error {
    margin: 16px 0 0;
    padding: 12px 15px;
    border-radius: var(--radius-sm);
    background: var(--danger-soft);
    color: var(--danger);
    font-size: 13.5px;
    border-left: 3px solid var(--danger);
}

.alert-warn {
    margin: 16px 0 0;
    padding: 12px 15px;
    border-radius: var(--radius-sm);
    background: var(--warn-soft);
    color: var(--warn);
    font-size: 13.5px;
    line-height: 1.55;
    border-left: 3px solid var(--warn);
}

.disclaimer {
    margin: 22px 0 0;
    padding-top: 14px;
    border-top: 1px solid var(--border);
    color: var(--text-3);
    font-size: 12px;
    line-height: 1.6;
}

/* ------------------------------------------------------ 面板 / 关于页 */
.panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 18px;
    margin-bottom: 16px;
    box-shadow: var(--shadow-sm);
}

.panel-title {
    margin: 0 0 14px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-2);
}

.kv { margin: 0; display: flex; flex-direction: column; gap: 12px; }

.kv dt {
    font-size: 12.5px;
    color: var(--text-3);
    margin-bottom: 2px;
}

.kv dd {
    margin: 0;
    font-size: 14px;
    line-height: 1.65;
}

.api-list { list-style: none; margin: 0; padding: 0; }

.api-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
    font-size: 13.5px;
    flex-wrap: wrap;
}

.api-list li:last-child { border-bottom: none; }
.api-list code { background: transparent; padding: 0; color: var(--accent); }
.api-list span { color: var(--text-3); font-size: 12.5px; }

.footnote {
    color: var(--text-3);
    font-size: 13.5px;
    text-align: center;
    padding: 20px 0;
}

/* ------------------------------------------------- 热量计算结果展示 */
.field-hint {
    font-size: 12px;
    color: var(--text-3);
    line-height: 1.5;
}

/* 顶部紧凑摘要：提交后整页重载会滚回顶部，这行永远在首屏 ——
   它是「不依赖 JS 也能看到结果」的兜底 */
.result-summary {
    margin: 0 0 18px;
    padding: 11px 14px;
    border-radius: var(--radius-sm);
    background: var(--accent-soft);
    color: var(--text);
    font-size: 14px;
    line-height: 1.55;
    box-shadow: var(--shadow-sm);
}

.result-summary b {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* 结果区同样做成树洞，与首页主题呼应 */
.result-card {
    /* JS 滚动到这里时给吸顶栏留出空间，避免标题被顶栏盖住 */
    scroll-margin-top: calc(var(--topbar-h) + 12px);
    padding: 20px 22px;
    background: linear-gradient(178deg, var(--hole-bg-2) 0%, var(--hole-bg) 94%);
    border: 1.5px solid var(--hole-rim);
    border-radius: 22px 26px 20px 24px / 24px 20px 26px 22px;
    box-shadow:
        inset 0 10px 18px -6px var(--hole-inset),
        inset 0 -5px 10px -8px var(--hole-lip);
    color: var(--hole-text);
}

.result-main {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
    text-align: center;
}

.result-item { min-width: 0; }

.result-label {
    font-size: 11.5px;
    opacity: .78;
    margin-bottom: 4px;
    white-space: nowrap;
}

.result-num {
    font-size: 23px;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -.5px;
    font-variant-numeric: tabular-nums;
}

.result-unit {
    font-size: 11px;
    opacity: .68;
    margin-top: 1px;
}

.result-macros {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
    margin-top: 18px;
    padding-top: 15px;
    border-top: 1px solid rgba(60, 40, 18, .20);
    text-align: center;
}

@media (prefers-color-scheme: dark) {
    .result-macros { border-top-color: rgba(255, 226, 180, .12); }
}

.result-accent { color: #7a3f08; }
@media (prefers-color-scheme: dark) { .result-accent { color: #f0b877; } }

/* 千焦大卡换算结果：一行干净的等式 */
.result-inline {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 7px;
    margin: 16px 0 0;
    font-size: 17px;
    font-variant-numeric: tabular-nums;
}

.result-inline b {
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -.3px;
}

.result-inline span { color: var(--text-2); font-size: 13px; }

/* 换算结果放在树洞卡片里时，文字要改用洞内的配色，否则对比度不够 */
.conv-caption {
    margin: 0 0 10px;
    font-size: 13px;
    line-height: 1.6;
    color: var(--hole-text-2);
}

.conv-caption b {
    color: var(--hole-text);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.result-card .result-inline { margin-top: 0; }
.result-card .result-inline b { color: var(--hole-text); }
.result-card .result-inline span { color: var(--hole-text-2); }
.result-card .result-inline b.result-accent { color: #7a3f08; }

@media (prefers-color-scheme: dark) {
    .result-card .result-inline b.result-accent { color: #f0b877; }
}

/* ============================================================ 电子筹码
   圆桌 + 等距座位 + 头像库 + 日志 + 弹窗 + 房间列表
   前缀统一 chip- / av- ，避免与既有类冲突
   ------------------------------------------------------------ */

/* ---- 1. 筹码数字配色 ----------------------------------------
   刻意不复用 --ok / --danger：那两个是给「提示条」用的，做 15–18px 的
   正文数字时在浅色底上对比度偏紧（--ok #4f8a3c 对 #fffdf9 只有 3.4:1，
   不到 AA 的 4.5:1）。这里另设一组更深的绿和更亮的红，专门给数字用。 */
:root {
    --chip-pos: #256a17;   /* 对 #fffdf9 约 5.9:1 */
    --chip-neg: #a82f1a;   /* 对 #fffdf9 约 6.1:1 */
}

@media (prefers-color-scheme: dark) {
    :root {
        --chip-pos: #8fd06a;   /* 对 #1f1812 约 8.4:1 */
        --chip-neg: #ff9276;   /* 对 #1f1812 约 6.7:1 */
    }
}

.chip-num { font-variant-numeric: tabular-nums; font-weight: 700; }
.chip-num.is-pos { color: var(--chip-pos); }
.chip-num.is-neg { color: var(--chip-neg); }
.chip-num.is-zero { color: var(--text); }

/* ---- 2. 头像库 ---------------------------------------------- */
/* 头像是 <img>，撑满外层那个圆形裁剪盒（.seat-avatar-slot / .avatar-face /
   .member-avatar，它们各自负责 border-radius + overflow:hidden）。
   object-fit:cover 是保险：图片在构建脚本里已经裁成正方形了，万一以后
   换了非正方形的图，这里也不会被拉变形，只会居中裁掉一点。 */
.av {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* 图片解码完成前，先露出外壳的背景色，避免闪一下透明 */
    background: var(--surface-2);
}

/* ---- 3. 圆桌 ------------------------------------------------ */
/* 圆桌本身也是一处「树洞」：木质渐变 + inset 内阴影，与首页卡片同一套语言。
   aspect-ratio + max-width:min(...,60vh) 是为了手机横屏时不溢出视口高度 ——
   横屏时高度才是约束，容器自己会超出去，ResizeObserver 管不了这个。 */
.chip-table {
    position: relative;
    width: 100%;
    max-width: min(440px, 60vh);
    aspect-ratio: 1 / 1;
    /* 上下留得比左右松：座位最外侧的文字允许探出容器一点（见 chip.js 的
       OUTER_SLACK），这点余量就是给它兜底的。实测文字最多探出 16px，
       所以 24/32 之后，与上一个区块留 ~9px、与下一个面板留 ~16px。 */
    margin: 24px auto 32px;
}

.table-top {
    position: absolute;
    inset: 21%;
    border-radius: 50%;
    background: radial-gradient(ellipse at 36% 28%,
                var(--hole-bg) 0%, var(--hole-bg-2) 72%, var(--hole-rim) 100%);
    box-shadow:
        inset 0 12px 26px -8px var(--hole-inset),
        inset 0 -6px 12px -9px var(--hole-lip),
        0 8px 24px rgba(70, 45, 20, .16);
    display: grid;
    place-items: center;
    text-align: center;
    color: var(--hole-text-2);
    font-size: 12px;
    line-height: 1.5;
    padding: 10%;
}

.table-center-num {
    font-size: 26px;
    font-weight: 700;
    color: var(--hole-text);
    letter-spacing: -.5px;
    font-variant-numeric: tabular-nums;
}

.table-center-label { font-size: 11px; opacity: .8; }

.table-seats { position: absolute; inset: 0; }

/* ---- 4. 座位 ------------------------------------------------ */
/* 座位盒**就是头像本身**，锚点即头像中心，靠 transform 推到圆环上。
   名字和筹码用绝对定位挂在头像外侧，完全不参与几何计算。

   这一点是关键。早先盒子里装的是「头像 + 名字 + 筹码」三行，盒子的
   *中心* 被对齐到圆环上，而头像在盒子顶部 —— 于是每个头像都被悄悄
   上移了半行。这个偏移换算成角度后随座位位置变化，头像到桌沿的距离
   就忽远忽近：正下方那个直接压到桌上，正上方那个却能放下一只手。
   改成锚在头像之后，所有头像严格落在同一半径上，与名字长短、是否
   换行、有没有房主徽章都无关。 */
.seat {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 56px;
    height: 56px;
    display: grid;
    place-items: center;
    transition: transform .35s ease;
}

.seat.is-clickable { cursor: pointer; touch-action: manipulation; }

.seat.is-clickable:active .seat-avatar { transform: scale(.93); }

/* 名字 + 筹码。挂在外侧：下半圈吊在头像下方，上半圈翻到头像上方。
   必须分上下两种，否则上半圈那几位的文字会印在桌面上。
   挂外侧还有个附带好处：文字永远在头像之外，不会挤到相邻座位。 */
.seat-label {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    width: max-content;
    max-width: 92px;
    text-align: center;
}

/* 下方多留 9px：房主徽章从头像下沿探出 5px，得让它先过去 */
.seat-label.is-below { top: 100%; margin-top: 9px; }
.seat-label.is-above { bottom: 100%; margin-bottom: 4px; }

/* 渐进增强标记：chip.js 在 <html> 上加 .js 类。
   没有 JS 时圆桌整个不出现，改用服务端渲染的成员列表，
   功能一样完整 —— 只是别人操作时要手动刷新页面。
   用 revert 而不是 block，这样 <span> 保持行内、<div> 保持块级，
   一个开关就能两处都用。 */
.js-only { display: none; }
html.js .js-only { display: revert; }
html.js .no-js-only { display: none; }

.seat-avatar {
    position: relative;
    width: 52px;
    height: 52px;
    margin: 0 auto;
    border-radius: 50%;
    /* 不设 overflow:hidden —— 房主徽章要从下沿探出去一点。
       SVG 自己由 border-radius + 下面的 .seat-avatar-slot 圆角裁切。 */
    background: var(--surface);
    border: 2px solid var(--hole-rim);
    box-shadow: var(--shadow-sm);
    transition: transform .12s ease, border-color .15s ease;
}

/* 头像插槽。它夹在 .seat-avatar 和 <svg class="av"> 之间，必须显式
   撑满父级 —— 因为 .av 用的是 width/height:100%，参照的是这个 span，
   而它默认是**行内元素**，行内元素的高度不参与百分比计算，结果是 0，
   SVG 就完全画不出来。
   表现极具迷惑性：.seat-avatar 自己的 background 还在，于是每个头像
   都变成一个一模一样的灰圆 —— 看起来像「头像数据没传过来」，
   实际数据全对，只是 SVG 被画在了 0×0 的盒子里。
   服务端渲染那条路径（member-row 里的 span th:replace）也踩同一个坑。 */
.seat-avatar-slot,
.member-avatar > span {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    overflow: hidden;
}

/* 离线 = 头像变灰度，但筹码一分不少 —— 断网、锁屏、关页面都只是离线 */
.seat-avatar.is-offline { filter: grayscale(1) opacity(.5); }

/* 自己：一圈主色描边，一眼找到 */
.seat.is-self .seat-avatar {
    border-color: var(--accent);
    border-width: 3px;
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.seat-owner {
    position: absolute;
    bottom: -5px;
    left: 50%;
    transform: translateX(-50%);
    padding: 1px 6px;
    border-radius: 7px;
    background: var(--accent);
    color: var(--accent-ink);
    font-size: 9.5px;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
}

.seat-name {
    font-size: 12px;
    line-height: 1.3;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.seat-chips { font-size: 15px; line-height: 1.3; }

/* 没有 JS 时的成员列表。它不在圆桌里，所以不受 .table-seats 的绝对定位影响，
   也不带 .seat 类 —— 带上会被 chip.js 当成座位去摆。 */
.seat-list {
    flex-direction: column;
    gap: 9px;
    margin-bottom: 16px;
}

html:not(.js) .seat-list { display: flex; }

.member-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.member-avatar {
    position: relative;
    width: 44px;
    height: 44px;
    flex: none;
    border-radius: 50%;
    overflow: hidden;
    background: var(--surface);
    border: 2px solid var(--hole-rim);
}

.member-avatar.is-offline { filter: grayscale(1) opacity(.5); }

.member-row.is-self .member-avatar { border-color: var(--accent); }

.member-name {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    font-size: 14px;
}

.member-tag {
    flex: none;
    padding: 1px 6px;
    border-radius: 7px;
    background: var(--accent);
    color: var(--accent-ink);
    font-size: 10px;
    font-weight: 600;
}

.member-tag.is-dim {
    background: var(--surface-3);
    color: var(--text-3);
}

.member-chips { font-size: 17px; flex: none; }

/* ---- 5. 头像选择器 ------------------------------------------ */
/* 与 .segmented 同一套手法：radio 铺满整个选项 + input:checked 兄弟选择器。
   选中态纯 CSS 即时生效，不依赖服务端重新渲染。 */
.avatar-picker {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 9px;
}

.avatar-opt {
    position: relative;
    aspect-ratio: 1 / 1;
    border-radius: 50%;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

.avatar-opt input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
    opacity: 0;
    cursor: pointer;
    z-index: 1;
}

.avatar-face {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    overflow: hidden;
    border: 2px solid transparent;
    background: var(--surface-2);
    transition: border-color .15s ease, box-shadow .15s ease;
}

.avatar-opt input:checked + .avatar-face {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

/* ---- 6. 房间列表 -------------------------------------------- */
.room-list { display: flex; flex-direction: column; gap: 9px; }

.room-item {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 13px 15px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    color: var(--text);
    transition: transform .12s ease, border-color .15s ease;
    touch-action: manipulation;
}

.room-item:active { transform: scale(.99); }

@media (hover: hover) {
    .room-item:hover { border-color: var(--accent); }
}

.room-no {
    font-family: var(--mono);
    font-size: 17px;
    font-weight: 700;
    color: var(--accent);
    letter-spacing: .5px;
}

.room-meta {
    display: flex;
    flex-direction: column;
    gap: 1px;
    font-size: 12px;
    color: var(--text-2);
    flex: 1;
    min-width: 0;
}

.room-dot { color: var(--text-3); }

.room-owner {
    font-size: 12px;
    color: var(--text-3);
    max-width: 7em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.room-input { max-width: 9.5em; font-family: var(--mono); letter-spacing: 1px; }

/* ---- 7. 房间头 ---------------------------------------------- */
.chip-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 4px;
}

.chip-head .page-sub { margin-bottom: 16px; }

.room-no-lg {
    font-family: var(--mono);
    color: var(--accent);
    letter-spacing: 1px;
}

.chip-head-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.chip-head-actions .btn { min-height: 40px; padding: 0 15px; font-size: 14px; }

.btn-danger { color: var(--danger); }
.btn-danger:hover { border-color: var(--danger) !important; color: var(--danger) !important; }

/* ---- 8. 日志区 ---------------------------------------------- */
/* 「一直显示最新一条」：默认只露一行，鼠标悬停 / 聚焦 / 触屏展开时松开。
   日志按「最新在前」存，所以 DOM 第一条就是最新那条。 */
.chip-log {
    display: flex;
    flex-direction: column;
    max-height: 2.1em;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    transition: max-height .2s ease;
    overscroll-behavior: contain;
}

.chip-log.is-expanded { max-height: 13em; }

.log-line {
    margin: 0;
    padding: 3px 0;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--text-2);
    flex: none;
}

.log-line:first-child { color: var(--text); font-weight: 600; }

.log-empty {
    margin: 0;
    font-size: 13.5px;
    color: var(--text-3);
}

.log-toggle {
    margin-top: 9px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent);
    font-family: inherit;
    font-size: 13px;
    cursor: pointer;
    min-height: 32px;
}

/* ---- 9. 给筹码弹窗 ------------------------------------------ */
.chip-modal {
    position: fixed;
    inset: 0;
    z-index: 70;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(28, 18, 8, .52);
}

.chip-modal.is-open { display: flex; }

.chip-modal-card {
    width: min(330px, 100%);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 19px;
    box-shadow: var(--shadow);
    max-height: 88vh;
    overflow-y: auto;
}

.chip-modal-title {
    margin: 0 0 3px;
    font-size: 16px;
    font-weight: 700;
}

.chip-modal-sub {
    margin: 0 0 15px;
    font-size: 13px;
    color: var(--text-2);
}

.chip-modal-preview {
    margin: 12px 0 0;
    padding: 10px 13px;
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    font-size: 13px;
    line-height: 1.6;
    font-variant-numeric: tabular-nums;
}

.chip-modal-preview b { font-weight: 700; }

.chip-modal-actions {
    display: flex;
    gap: 9px;
    margin-top: 15px;
}

.chip-modal-actions .btn { flex: 1; }

/* 快捷面额 */
.chip-quick {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-top: 9px;
}

.chip-quick button {
    flex: 1 1 0;
    min-width: 52px;
    min-height: 38px;
    padding: 0 10px;
    border-radius: 9px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-2);
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    font-variant-numeric: tabular-nums;
    touch-action: manipulation;
    -webkit-appearance: none;
    appearance: none;
}

.chip-quick button:active { transform: scale(.96); }

/* ------------------------------------------------------------ 桌面端 */
@media (min-width: 900px) {

    .bottombar { display: none; }

    .shell {
        display: grid;
        grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
        gap: var(--shell-gap);
        max-width: 1080px;
        margin: 0 auto;
        padding: 0 24px;
        align-items: start;
    }

    .sidebar {
        display: flex;
        flex-direction: column;
        gap: 3px;
        position: sticky;
        top: calc(var(--topbar-h) + 20px);
        padding-top: 20px;
    }

    .side-item {
        display: flex;
        align-items: center;
        gap: 10px;
        padding: 9px 12px;
        border-radius: var(--radius-sm);
        font-size: 14px;
        color: var(--text-2);
        transition: background .15s ease, color .15s ease;
    }

    .side-item .ico { width: 19px; height: 19px; }
    .side-item:hover { background: var(--surface-2); color: var(--text); }
    .side-item.is-active {
        background: var(--accent-soft);
        color: var(--accent);
        font-weight: 600;
    }

    .main {
        padding: 24px 0 64px;
        max-width: none;
        margin: 0;
    }

    .hero { padding-top: 0; }
    .hero-title { font-size: 30px; }

    .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }

    .input { font-size: 15px; }

    /* 电子筹码：桌面端空间富裕，圆桌与头像都放大一档。
       上限不只是「别超过视口高度」，而是要让圆桌的**圆心落在视口中线**：
       圆桌上方的面包屑 + 房间标题 + 留白一共约 215px，所以高度取
       (100vh - 400px) 时圆心恰好落在视口中间偏下 15px 左右 —— 看起来才是
       居中的。只写 62vh 的话，矮一点的窗口（800px 上下很常见）圆桌会整个
       压到折线以下，在窗口里就成了「右下角的那张桌子」。 */
    .chip-table { max-width: max(360px, min(520px, calc(100vh - 400px))); }

    /* 座位盒跟着头像一起放大 —— 它俩尺寸必须一致，否则锚点就偏了 */
    .seat { width: 64px; height: 64px; }

    .seat-avatar { width: 60px; height: 60px; }

    .seat-name { font-size: 13px; }

    .seat-chips { font-size: 16px; }

    .avatar-picker { grid-template-columns: repeat(10, minmax(0, 1fr)); }

    .room-input { font-size: 15px; }

    /* 日志区在桌面端默认多露几行，鼠标扫一眼就能看完最近几条 */
    .chip-log { max-height: 4.2em; }

    .chip-log.is-expanded { max-height: 15em; }
}

/* ------------------------------------------------------ 圆桌的横向锚点
   桌面端正文列被左侧导航整体推右了 (导航宽 + 列间距) / 2 = 120px —— 因为
   .shell 这两列是居中的，导航占了左边，正文列自然就偏右。

   面包屑、面板这些「占满整列」的块看不出这 120px，圆桌看得出：它是这一页
   唯一一个以自身为居中锚点的窄块。实测 1440 宽的窗口里，圆桌中心在
   840px、窗口中心在 720px，正好差这 120px —— 视觉上就是「桌子跑到右边」。

   这里把偏移补回来，让圆桌落在窗口正中。用 position:relative 的 left 而不是
   改 margin：布局盒还在原处，所以下面的面板一行都不会动，只有圆桌自己平移。
   圆桌比正文列窄得多（400~520 vs 792），平移后最左边仍贴着正文列的左缘，
   不会压到导航上。

   900~1024px 之间不补：那时正文列自己就窄（600px 上下），补满 120px 会把
   圆桌推出列外、挤进导航那条竖向通道里，得不偿失。 */
@media (min-width: 1024px) {
    .chip-table {
        left: calc((var(--sidebar-w) + var(--shell-gap)) / -2);
    }
}

@media (min-width: 1180px) {
    .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* 尊重用户的减少动效偏好 */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        transition-duration: .01ms !important;
        animation-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}
