/* ============================================================
   gaobeicms 会员商城公共样式
   （头部登录区 / 账号页 / 会员中心 / 购物订单共用）
   ============================================================ */

/* ---------- 头部：购物车与会员入口 ---------- */
/* margin-left:auto：在导航条内把自己（语言/购物车/登录注册）推到最右，栏目菜单留在左边 */
.header-tools { display: flex; align-items: center; gap: 16px; flex: none; margin-left: auto; margin-right: 6px; }

.ht-cart {
    position: relative;
    display: flex; align-items: center; justify-content: center;
    width: 38px; height: 38px;
    border-radius: 50%;
    border: 1px solid #dfe4ec;
    background: #fff;
    color: #3c4456;
    transition: all .2s;
}
.ht-cart:hover { background: var(--primary); border-color: var(--primary); color: #fff; }
.ht-cart-num {
    position: absolute; top: -5px; right: -7px;
    min-width: 17px; height: 17px;
    padding: 0 4px;
    border-radius: 9px;
    background: #e64545;
    color: #fff;
    font-size: 11px;
    line-height: 17px;
    text-align: center;
    display: none;
}
.ht-cart-num:not(:empty) { display: block; }

.ht-user { position: relative; flex: none; }
.ht-user-main { display: flex; align-items: center; gap: 8px; cursor: pointer; padding: 5px 8px; border-radius: 20px; transition: background .2s; }
.ht-user-main:hover { background: #f0f3f8; }
.ht-avatar, .ht-avatar-ph {
    width: 30px; height: 30px;
    border-radius: 50%;
    object-fit: cover;
    flex: none;
}
.ht-avatar-ph {
    display: flex; align-items: center; justify-content: center;
    background: var(--primary); color: #fff;
    font-size: 14px;
}
.ht-name { max-width: 96px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; color: #3c4456; }
.ht-user:hover .ht-drop { display: block; }
.ht-drop {
    display: none;
    position: absolute; right: 0; top: calc(100% + 6px);
    width: 150px;
    background: #fff;
    border: 1px solid #e6e9ef;
    border-radius: 10px;
    box-shadow: 0 14px 34px rgba(16, 24, 40, .14);
    padding: 6px;
    z-index: 60;
}
/* 桥接头像触发区与下拉菜单之间的间隙，避免鼠标下移时菜单意外消失 */
.ht-drop::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: -7px;
    height: 8px;
}
.ht-drop a {
    display: block;
    padding: 8px 12px;
    font-size: 14px;
    color: #3c4456;
    border-radius: 6px;
    transition: all .15s;
}
.ht-drop a:hover { background: #f0f3f8; color: var(--primary-dark); }
/* 下拉菜单栏目标题前的图标：仅移动端显示（移动端规则见 mobile.css），PC 端保持原样 */
.ht-drop .hd-ic { display: none; }

/* 登录/注册在深棕导航条上：默认白字；hover 白字 + 微白底（浅色底配深字的原方案只适合白头部） */
.ht-login { display: flex; align-items: center; gap: 4px; flex: none; font-size: 14px; }
.ht-login a { color: #fff; padding: 4px 8px; border-radius: 6px; }
.ht-login a:hover { color: #fff; background: rgba(255, 255, 255, .14); }
.ht-div { color: rgba(255, 255, 255, .45); font-size: 12px; }

/* ---------- 提示条 ---------- */
.tip-msg {
    padding: 11px 16px;
    border-radius: 8px;
    font-size: 14px;
    margin-bottom: 18px;
}
.tip-msg.err { background: #fdeceb; color: #c0392b; border: 1px solid #f5c2bf; }
.tip-msg.ok  { background: #e9f7ef; color: #1e7d4a; border: 1px solid #bfe6d0; }
/* 中性提示（既不是报错也不是成功）：修改密码页「尚未设置登录密码」用 */
.tip-msg.info { background: #eef4fd; color: #1e5fa8; border: 1px solid #cfe0f8; }

/* ---------- 账号页（登录/注册） ---------- */
.auth-main { display: flex; justify-content: center; padding: 52px 0 80px; }
/* 独立登录页 / 注册页的外框，与下面「登录/注册弹窗」是同一套：720px 直角双栏、
   左 272px 深色品牌栏、右栏 44px 控件、#2b7fe0 主按钮。卡片直接在 HTML 上挂 .gb-dialog 类，
   整组 .gb-dialog 规则原样复用，这一段只补「页面里的一张卡」才需要的三件事：
   宽度、描边、投影（弹窗那圈半透明白衬边是压在深色遮罩上的，站在白底页面上看不见）。
   两边共用同一组数值，改样式时这一段和弹窗段必须一起看 */
.auth-card.gb-dialog {
    width: 720px;
    max-width: 100%;
    border: 1px solid #e9ebf0;
    border-radius: 0;
    box-shadow: 0 10px 34px rgba(23, 30, 43, .10);
    /* 页面自己会滚，卡片不再限高 —— 注册页字段多，被 overflow 截掉就麻烦了 */
    max-height: none;
}
/* 页面标题：弹窗没有（它靠左栏站名顶着），页面需要一个 h1，字号压小免得抢品牌栏的注意力 */
.auth-card .auth-title { font-size: 20px; font-weight: 700; color: #242b3a; margin-bottom: 4px; }
.auth-card .auth-sub { font-size: 13px; color: #98a1b0; margin-bottom: 18px; }
.auth-card .auth-foot { margin-top: 20px; text-align: center; font-size: 14px; color: var(--text-2); }
.auth-card .auth-foot a { color: var(--primary); font-weight: 600; }
/* 注册页的自定义字段里会有 textarea / select，它们不是「图标 + 单行输入框」那一档，
   套 44px 行高与 40px 左内边距会塌（textarea 只剩一行高），这里单独还回通用控件的排法 */
.auth-card .u-form textarea.f-input { height: auto; min-height: 90px; padding: 10px 14px; border-radius: 5px; }
.auth-card .u-form select.f-input { padding: 0 14px; }
/* 注册页站长自定义的字段没有固定语义的图标，用 .f-nico 把「图标位」那 40px 左内边距还回来 */
.auth-card .u-form .f-input.f-nico { padding: 0 14px; }
/* 选项卡、面板、「获取验证码」按钮、第三方登录圆钮 —— 全部沿用弹窗那一份
   （.gb-tabs / .gb-pane / .gb-dialog .btn-sms / .gb-oauth），这里不再各写一套，
   免得两处数值慢慢走偏。开关关掉时模板连那一块都不输出，所以不用考虑"怎么藏" */
/* 登录按钮下那一行：左边「注册即同意《用户协议》《隐私协议》」、右边「忘记密码」。
   独立登录页与页头弹窗用的是同一份（两边结构一致），改这儿两边一起变；
   下面那块第三方登录自带 20px 上间距，所以这里只需要与按钮拉开。
   配色按两个链接的主次分开：协议是要点进去看的重点，用橙 #fd6716 挑出来；
   忘记密码是次要出口，压成深灰 #5a6472，不跟左边抢视线 */ 
.auth-extra {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    margin: 14px 0 0;
    font-size: 13px;
    color: #98a1b0;
}
.auth-extra .ae-agree a { margin-left: 3px; color: #fd6716; }
.auth-extra .ae-agree a:hover { color: #e0550a; }
.auth-extra .ae-forgot { white-space: nowrap; color: #5a6472; }
.auth-extra .ae-forgot:hover { color: #333b45; }
.auth-submit { width: 100%; }

.u-form .f-row { margin-bottom: 18px; }
.u-form .f-label { font-size: 14px; color: #3c4456; margin-bottom: 7px; }
.u-form .f-label .req { color: #e64545; margin-right: 3px; }
.u-form .f-input, .u-form .f-area, .u-form .f-select {
    width: 100%;
    border: 1px solid #dfe4ec;
    border-radius: 8px;
    background: #fff;
    font-size: 14px;
    color: #2b3445;
    padding: 10px 13px;
    outline: none;
    transition: border-color .2s;
}
.u-form .f-input:focus, .u-form .f-area:focus, .u-form .f-select:focus { border-color: var(--primary); }
/* 不可修改的控件（个人资料页的「登录账号」是当前唯一的用例：注册后就不许改）：
   上面那条基础规则把 background/color 写死成 #fff / #2b3445，而作者样式一律压过
   浏览器给 :disabled 的默认灰化，于是禁用框和可编辑框长得一模一样 —— 会员会以为能改。
   这里显式灰到底：浅灰底 + 灰字 + 灰色描边 + 禁止光标。
   color 之外还必须写 -webkit-text-fill-color：Chromium 对禁用控件是用后者刷字色的，
   只改 color 有时不动（同一浏览器不同版本行为还变过，两条都写真了更保险）。
   readonly 一并覆盖：它同样属于「看得见、改不了」，且能聚焦，聚焦时也别再亮主题色描边 */
.u-form .f-input:disabled, .u-form .f-area:disabled, .u-form .f-select:disabled,
.u-form .f-input[readonly], .u-form .f-area[readonly] {
    background: #f5f7fa;
    border-color: #e6e9ef;
    color: #98a1b0;
    -webkit-text-fill-color: #98a1b0;
    cursor: not-allowed;
}
.u-form .f-input:disabled:focus, .u-form .f-area:disabled:focus, .u-form .f-select:disabled:focus,
.u-form .f-input[readonly]:focus, .u-form .f-area[readonly]:focus { border-color: #e6e9ef; }
.u-form .f-area { resize: vertical; min-height: 90px; }
.u-form .f-hint { font-size: 12px; color: #98a1b0; margin-top: 6px; }
/* 性别单选（个人资料页唯一一处 f-radio）：与别的行同一条"标签在上、控件在下"的节奏，
   控件区自己横排。

   圆点是**自绘**的，没用原生控件的 accent-color：accent-color 只让浏览器换个颜色，
   环宽/白环/中心点直径仍由各浏览器自己定（Chrome / Edge / Firefox / Safari 画出来
   的粗细都不一样），而设计稿给了一张选中态的特写，要求"完全按这个效果"。自绘才能把
   三个尺寸钉死，且任何浏览器一致：
     外径 17px / 橙环 1.5px / 白环 2px / 中心橙点 ⌀10px（= 0.59×外径）
   对照设计稿的逐像素径向剖面（中心实心 0.60R、白环到 0.87R、橙环厚约 0.13R）是吻合的。
   中心点用 radial-gradient 画而不是 ::before —— input 是空元素，伪元素在部分浏览器
   不渲染；渐变 + background-size 从 0 播到内径，顺带就是"点从中心长出来"的选中动画 */
.u-form .f-radio { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 26px; min-height: 38px; }
.u-form .f-radio label { display: inline-flex; align-items: center; gap: 7px; font-size: 14px; color: #3c4456; cursor: pointer; }
.u-form .f-radio input[type="radio"] {
    appearance: none;
    -webkit-appearance: none;
    width: 17px; height: 17px;
    margin: 0; padding: 0; flex: none;
    border: 1.5px solid #ccd3dd;
    border-radius: 50%;
    background-color: #fff;
    /* 中心点必须落在圆环正中心。背景定位区域取 border-box（不是默认的 padding-box），
       并让渐变铺满该区域（background-size 用 100% 而不是写死的 14px）：
       写死尺寸时图比内框小，那半个像素的位置差要靠 background-position 算，
       浏览器再把不足 1px 的偏移做整像素吸附 —— 实测点会整体歪向右下 0.3px；
       铺满区域后位置差恒为 0，点必然居中，也不受 border 宽度/设备像素比影响 */
    background-origin: border-box;
    background-image: radial-gradient(circle, #fd6716 0 5px, rgba(253, 103, 22, 0) 5px);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 0 0;
    cursor: pointer;
    transition: border-color .12s ease-out, background-size .12s ease-out;
}
.u-form .f-radio input[type="radio"]:checked {
    border-color: #fd6716;
    background-size: 100% 100%;
}
.u-form .f-radio input[type="radio"]:hover { border-color: #aab3bf; }
.u-form .f-radio input[type="radio"]:checked:hover { border-color: #fd6716; }
.u-form .f-radio input[type="radio"]:disabled { border-color: #dfe3e9; background-color: #f5f7fa; cursor: not-allowed; }
.u-form .f-radio input[type="radio"]:focus-visible { outline: 2px solid rgba(253, 103, 22, .35); outline-offset: 2px; }
.u-form .f-radio label:hover { color: #12161f; }
.u-form .f-captcha { display: flex; gap: 10px; }
.u-form .f-captcha .f-input { flex: 1; }
.u-form .f-captcha img { width: 120px; height: 42px; border-radius: 8px; border: 1px solid #e3e7ee; cursor: pointer; flex: none; }

/* 头像上传：圆形预览 + 按钮 + 说明。上传即生效（不再让会员手填图片地址）——
   预览由后端裁切规则决定最终样子，这里只用 object-fit 把「居中裁 1:1」的效果先给出来 */
.u-form .av-up { display: flex; align-items: center; gap: 16px; }
.av-pic {
    position: relative; flex: none;
    width: 72px; height: 72px; border-radius: 50%;
    overflow: hidden;
    background: var(--primary); color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-size: 28px; line-height: 1;
}
.av-pic img { display: none; width: 100%; height: 100%; object-fit: cover; }
.av-pic.has-img img { display: block; }
.av-pic.has-img span { display: none; }
/* 上传中压一层暗色，免得点了按钮像是没反应 */
.av-pic.is-loading::after { content: ""; position: absolute; inset: 0; background: rgba(0, 0, 0, .35); }
.av-file { display: none; }
.av-side { min-width: 0; }
.av-side .f-hint { margin-top: 8px; }

.btn-ghost {
    display: inline-flex; align-items: center; justify-content: center;
    height: 38px; padding: 0 18px;
    border: 1px solid #dfe4ec; border-radius: 8px;
    background: #fff; color: #3c4456;
    font-size: 14px; cursor: pointer;
    transition: border-color .2s, color .2s, background .2s;
}
.btn-ghost:hover:not(:disabled) { border-color: var(--primary); color: var(--primary); background: #f7f9fc; }
.btn-ghost:disabled { opacity: .6; cursor: not-allowed; }

.btn-main {
    display: inline-flex; align-items: center; justify-content: center;
    border: none;
    background: var(--primary);
    color: #fff;
    font-size: 15px;
    padding: 11px 22px;
    border-radius: 8px;
    cursor: pointer;
    transition: background .2s;
}
.btn-main:hover { background: var(--primary-dark); color: #fff; }
.btn-ghost {
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid #dfe4ec;
    background: #fff;
    color: #3c4456;
    font-size: 14px;
    padding: 9px 18px;
    border-radius: 8px;
    cursor: pointer;
    transition: all .2s;
}
.btn-ghost:hover { border-color: var(--primary); color: var(--primary); }
.btn-accent { background: #df8f36; }
.btn-accent:hover { background: #c57a22; color:#fff; }

/* ---------- 会员中心整体布局 ---------- */
.u-wrap { display: flex; gap: 24px; align-items: flex-start; }
.u-aside { width: 230px; flex: none; }
.u-aside-card { background: #fff; border: 1px solid #e9ebf0; border-radius: 12px; padding: 22px 14px; }
.u-aside-user { text-align: center; padding-bottom: 16px; margin-bottom: 10px; border-bottom: 1px dashed #edf0f5; }
.u-aside-avatar {
    width: 64px; height: 64px; margin: 0 auto 12px;
    border-radius: 50%; object-fit: cover;
    display: flex; align-items: center; justify-content: center;
    background: var(--primary); color: #fff; font-size: 26px;
}
.u-aside-name { font-size: 16px; font-weight: 600; color: #242b3a; }
.u-aside-level {
    display: inline-block; margin-top: 6px;
    font-size: 12px; color: #b06d14;
    background: #fdf3e3; border-radius: 10px; padding: 1px 10px;
}
.u-menu { padding: 0; }
/* 导航项 = 图标 + 文字 + 尾部「›」三件：
   PC 端与手机端都显示图标（2026-10-04 用户要求「文字前面都加上图标，像手机端那样」，
   原先 PC 端是把 .u-mi 藏起来、只用 justify-content:space-between 摆「文字 + ›」两件）。
   三件排法统一成「图标 + 文字」靠左、尾部「›」用 margin-left:auto 顶到右边 ——
   不能再留 space-between，否则中间那件（文字）会被推到正中间。
   图标宽度固定 17px 且 flex:none，所以 10 项的文字左边缘严格对齐；
   颜色一律走 currentColor，悬停与选中态的变色不用为图标另写规则。 */
.u-menu a {
    display: flex; align-items: center; justify-content: flex-start;
    padding: 12px 16px; margin-bottom: 6px;
    font-size: 14px; color: #3c4456;
    border-radius: 8px;
    transition: all .15s;
}
.u-menu a:hover { background: #f0f3f8; color: var(--primary-dark); }
.u-menu a.on { background: var(--primary); color: #fff; font-weight: 600; }
.u-menu a .u-mi { display: block; flex: none; width: 17px; height: 17px; margin-right: 10px; }
.u-menu a .cnt { margin-left: auto; font-size: 12px; color: #98a1b0; }
.u-menu a.on .cnt { color: rgba(255,255,255,.85); }
/* 文字不折行：手机上「退款/售后」这类含斜杠的词一旦被拆成两行，会把两列的高度撑乱 */
.u-menu a .u-tx { white-space: nowrap; }

.u-main { flex: 1; min-width: 0; }
.u-card {
    background: #fff;
    border: 1px solid #e9ebf0;
    border-radius: 12px;
    padding: 24px 26px;
    margin-bottom: 20px;
}
.u-card-title { display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px; }
.u-card-title h3 { font-size: 17px; font-weight: 700; color: #242b3a; }
.u-card-title a { font-size: 13px; color: var(--primary); }
.u-card-title a.btn-main { font-size: 13px; color: #fff; }

/* ---------- 个人资料页：社交帐号绑定 ----------
   一行一个平台：圆底图标 + 名称 | 中间状态（未绑定 / 第三方昵称）| 右侧按钮。
   已绑定那颗是纯展示的灰按钮，不给点（解绑不在本期范围内） */
.soc-tip { font-size: 12px; color: #98a1b0; margin: -8px 0 6px; }
.soc-list { margin-top: 4px; }
.soc-row {
    display: flex; align-items: center; gap: 14px;
    padding: 14px 0;
    border-bottom: 1px dashed #edf0f5;
}
.soc-row:last-child { border-bottom: none; padding-bottom: 0; }
.soc-ico {
    width: 36px; height: 36px; flex: none;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    color: #fff;
}
.soc-ico.qq { background: #12b7f5; }
.soc-ico.wx { background: #07c160; }
.soc-ico svg { width: 22px; height: 22px; }
.soc-name { width: 76px; flex: none; font-size: 14px; color: #3c4456; }
.soc-state { flex: 1; font-size: 14px; color: #98a1b0; }
.soc-row.is-bound .soc-state { color: #3c4456; }
/* 按钮尺寸比通用幽灵按钮小一号，别在细长的一行里显得过重 */
.soc-btn, .soc-off { height: 34px; padding: 0 20px; }
.soc-off { color: #b6bdc9; border-color: #e9ebf0; }

/* 概览数据块 */
.u-dash-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 20px; }
.u-dash-item {
    background: #fff; border: 1px solid #e9ebf0; border-radius: 12px;
    padding: 18px 20px; display: block; transition: all .2s;
}
.u-dash-item:hover { border-color: var(--primary); box-shadow: var(--shadow); transform: translateY(-2px); }
.u-dash-item .num { font-size: 24px; font-weight: 700; color: #242b3a; }
.u-dash-item .lab { font-size: 13px; color: var(--text-2); margin-top: 2px; }
.u-dash-item .act { font-size: 12px; color: var(--primary); }
.u-dash-item .num.tone-red { color: #e2563f; }
.u-dash-item .num.tone-orange { color: #df8f36; }
.u-dash-grid.u-col2 { grid-template-columns: repeat(2, 1fr); }

.u-hello { display: flex; align-items: center; gap: 16px; }
.u-hello .hi { flex: 1; }
.u-hello h2 { font-size: 19px; color: #242b3a; margin-bottom: 4px; }
.u-hello p { font-size: 13px; color: var(--text-2); }
.u-hello .money { display: flex; flex-direction: column; align-items: flex-end; }
.u-hello .money b { font-size: 26px; color: #e2563f; font-weight: 700; line-height: 1.3; }
.u-hello .money span { display: block; font-size: 12px; color: var(--text-2); }
.u-hello .money .btn-main { margin-top: 12px; padding: 8px 20px; font-size: 13px; }

/* 表格与列表 */
.u-table { width: 100%; border-collapse: collapse; }
.u-table th {
    text-align: left; font-size: 13px; font-weight: 600; color: #7a8494;
    padding: 9px 10px; border-bottom: 1px solid #edf0f5;
}
.u-table td { padding: 11px 10px; font-size: 14px; border-bottom: 1px solid #f3f5f8; color: #3c4456; }
.u-table tr:last-child td { border-bottom: none; }
.u-table .money-out { color: #c0392b; }
.u-table .money-in { color: #1e7d4a; }
.u-empty { text-align: center; color: #98a1b0; padding: 40px 0; font-size: 14px; }

/* 收藏卡片 */
.fav-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.fav-card { border: 1px solid #e9ebf0; border-radius: 12px; overflow: hidden; background: #fff; transition: all .2s; }
.fav-card:hover { box-shadow: var(--shadow); transform: translateY(-2px); }
.fav-pic { height: 170px; background: #f0f3f8; overflow: hidden; display: flex; align-items: center; justify-content: center; }
.fav-pic img { width: 100%; height: 100%; object-fit: cover; }
.fav-pic .ph { color: #c2c9d4; font-size: 30px; }
/* 电脑端一行 4 条（981 起，与下面 ≤980 的两列无缝衔接）。媒体查询必须排在
   .fav-grid / .fav-pic 的基础规则「之后」—— 同特异性下后者胜，写在前面等于白写。
   只改列数、不动 170px 高：1440/1920 下列宽 249，正好贴近商品原图 640×420 的
   比例（≈1.5）；原来 3 列的 337×170（≈2.0）反倒把封面上下各裁掉一截。 */
@media (min-width: 981px) {
    .fav-grid { grid-template-columns: repeat(4, 1fr); }
}
/* 981~1279 这一段一列只有 155~219px，170 高的封面会立起来（1024 时 155×170 ≈ 0.91），
   压到 150 让比例回到 1.0~1.4；≥1280 列宽 219 起，170 高才合适，不再压。 */
@media (min-width: 981px) and (max-width: 1279px) {
    .fav-pic { height: 150px; }
}
.fav-info { padding: 12px 14px 14px; }
.fav-title {
    display: block; font-size: 14px; color: #2b3445;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-bottom: 8px;
}
.fav-title:hover { color: var(--primary); }
.fav-bottom { display: flex; align-items: center; justify-content: space-between; }
.fav-price { color: #e2563f; font-weight: 700; font-size: 16px; }
.fav-price small { font-size: 12px; }
.fav-del { font-size: 12px; color: #98a1b0; border: none; background: none; cursor: pointer; }
.fav-del:hover { color: #e64545; }

/* 分页条（前台） */
.u-pager { display: flex; justify-content: center; margin-top: 22px; }
.u-pager a, .u-pager span {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 32px; height: 32px; padding: 0 8px;
    margin: 0 3px;
    border: 1px solid #dfe4ec; border-radius: 6px;
    background: #fff; color: #3c4456; font-size: 13px;
}
.u-pager .current { background: var(--primary); border-color: var(--primary); color: #fff; }

/* 响应式 */
@media (max-width: 980px) {
    .header-tools { gap: 8px; }
    .ht-name { display: none; }
    .u-wrap { flex-direction: column; }
    .u-aside { width: 100%; }
    /* .u-wrap 是 align-items:flex-start，改成 column 后这个 flex-start 就落在横向：
       子项宽度不再 stretch、改由内容撑（fit-content），于是内容一窄卡片就跟着缩
       （实测退款/售后页表格改成卡片后只剩 275px，比可用宽度短 90px）。这里把主区拉满。 */
    .u-main { width: 100%; }
    .u-menu { display: flex; flex-wrap: wrap; gap: 6px; }
    /* 手机端两列排列：尾部「›」隐藏，只留「图标 + 文字」。
       刻意左对齐（不用 justify-content:center）：各项文字有 3~5 字之差，
       一旦居中，同一列里图标就会左右错位（实测「购物车」与「我的评价」的图标能差 20px）；
       左对齐后两列图标各成一条竖线。
       内距与项距写全（9px 16px 9px 14px / 2px）是为了**把 PC 端刚加大的那份还回原值** ——
       上面基础规则已改成 12px / 6px，只覆盖 padding-left 的话手机上会跟着一起变高。 */
    .u-menu a { flex: 1; min-width: 130px; padding: 9px 16px 9px 14px; margin-bottom: 2px; justify-content: flex-start; }
    .u-menu a .u-mi { display: inline-block; }
    .u-menu a .cnt { display: none; }
    /* 「表格 → 卡片」：下面这段骨架被三张流水表共用 —— 余额流水（.u-flow，4 列）、
       退款/售后（.as-flow，7 列）、资金明细（.m-flow，5 列）。
       约定：卡片容器 class 以 `-flow` 结尾（.u-card.u-flow / .as-flow / .m-flow）即自动套用骨架，
       各页再写自己的 grid-template-areas 与逐列样式。
       只重排表格自身（tr 变 grid 容器、td 变块），不额外输出第二份 DOM，PC 端表格原样不动。
       手机上一行里每列只剩三十来像素（实测 390 每列 28~40px、每格 7~25 行、一行高 164~551px；
       360 一行 286px、320 一行 429px），中文被逐字拆行，故改成一行一张卡片。 */
    .u-card[class*="-flow"] .table-scroll { overflow: visible; }
    .u-card[class*="-flow"] .u-table { display: block; }
    /* table 改成 block 后，浏览器自动补的那个 tbody 仍是 table-row-group，宽度会收缩到内容宽，
       于是「行卡片」在宽一点的手机上只有内容那么宽（实测 768 只有 250px，占不到半屏）；
       把 tbody 也放成 block，卡片才真正铺满。 */
    .u-card[class*="-flow"] .u-table tbody { display: block; }
    .u-card[class*="-flow"] .u-table tr:first-child { display: none; }   /* 表头行 */
    .u-card[class*="-flow"] .u-table tr {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: center;
        column-gap: 10px;
        padding: 13px 15px;
        margin-bottom: 10px;
        border: 1px solid #eef1f6;
        border-radius: 10px;
        background: #f8fafd;
    }
    .u-card[class*="-flow"] .u-table tr:last-child { margin-bottom: 0; }
    .u-card[class*="-flow"] .u-table td { display: block; padding: 0; border: none; }

    /* —— 余额流水：4 列 —— */
    .u-flow .u-table tr { grid-template-areas: "type money" "time time" "desc desc"; }
    .u-flow .u-table td:nth-child(1) { grid-area: time; margin-top: 5px; font-size: 12px; color: #98a1b0; white-space: nowrap; }
    .u-flow .u-table td:nth-child(2) { grid-area: type; font-size: 14px; font-weight: 600; color: #242b3a; }
    .u-flow .u-table td:nth-child(3) { grid-area: desc; margin-top: 7px; font-size: 13px; color: #7a8494; }
    .u-flow .u-table td:nth-child(4) { grid-area: money; text-align: right; font-size: 15px; font-weight: 700; white-space: nowrap; }

    /* —— 退款/售后：7 列，按「结论在前、细节在后」排：类型 + 状态 → 申请金额 → 两串编号 → 时间 + 操作 —— */
    .as-flow .u-table tr {
        grid-template-areas:
            "type   status"
            "amount amount"
            "code   code"
            "order  order"
            "time   action";
    }
    .as-flow .u-table td:nth-child(3) { grid-area: type; font-size: 14px; font-weight: 600; color: #242b3a; }
    .as-flow .u-table td:nth-child(5) { grid-area: status; text-align: right; font-size: 13px; font-weight: 600; white-space: nowrap; }
    .as-flow .u-table td:nth-child(4) { grid-area: amount; margin-top: 6px; font-size: 16px; font-weight: 700; }
    .as-flow .u-table td:nth-child(1) { grid-area: code; margin-top: 9px; font-size: 12px; color: #b0b6c2; word-break: break-all; }
    .as-flow .u-table td:nth-child(2) { grid-area: order; margin-top: 3px; font-size: 12px; color: #b0b6c2; word-break: break-all; }
    .as-flow .u-table td:nth-child(6) { grid-area: time; margin-top: 8px; font-size: 12px; color: #98a1b0; white-space: nowrap; }
    .as-flow .u-table td:nth-child(7) { grid-area: action; margin-top: 8px; text-align: right; font-size: 13px; }
    /* 售后编号与订单号都是十几位数字、卡片上没有表头可参照，用 data-lb 补一个行内标签（PC 端只用表头，属性不显示） */
    .as-flow .u-table td[data-lb]::before { content: attr(data-lb) "："; color: #c9cfd9; }

    /* —— 资金明细：5 列，按「结论在前、细节在后」排：类型 + 变动金额 → 说明 → 时间 + 变动后余额 —— */
    .m-flow .u-table tr {
        grid-template-areas:
            "type   change"
            "desc   desc"
            "time   after";
    }
    .m-flow .u-table td:nth-child(2) { grid-area: type; font-size: 14px; font-weight: 600; color: #242b3a; }
    .m-flow .u-table td:nth-child(4) { grid-area: change; text-align: right; font-size: 15px; font-weight: 700; white-space: nowrap; }
    .m-flow .u-table td:nth-child(3) { grid-area: desc; margin-top: 7px; font-size: 13px; color: #7a8494; }
    .m-flow .u-table td:nth-child(1) { grid-area: time; margin-top: 8px; font-size: 12px; color: #98a1b0; white-space: nowrap; }
    .m-flow .u-table td:nth-child(5) { grid-area: after; margin-top: 8px; text-align: right; font-size: 12px; color: #98a1b0; white-space: nowrap; }
    /* 「变动后余额」是个裸数字、卡片上没有表头可参照，用 data-lb 补个行内标签 */
    .m-flow .u-table td[data-lb]::before { content: attr(data-lb) "："; color: #c9cfd9; }
    .u-dash-grid { grid-template-columns: repeat(2, 1fr); }
    .fav-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
    /* 头像上传改纵向：横排时右侧说明只剩 ~148px，会被压成四行，
       头像与按钮还各靠一边、看着不成组；纵向后头像居中、按钮居中、说明整行居中 */
    .u-form .av-up { flex-direction: column; align-items: center; text-align: center; }
    .u-form .av-side { display: flex; flex-direction: column; align-items: center; }
    /* 收藏卡一行两条（不再变单列）：390 视口下每列约 149px
       —— u-card 内宽 314，减 12px 间隙再除以 2。
       图片高度必须跟着从 170 收到 108 才接近 4:3，否则会被裁成竖条；
       标题与价格各降 1px，让「智能家庭网关 Pro」这类长标题尽量不截断。 */
    .fav-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
    .fav-pic { height: 108px; }
    .fav-pic .ph { font-size: 22px; }
    .fav-info { padding: 10px 11px 12px; }
    .fav-title { font-size: 13px; margin-bottom: 6px; }
    .fav-price { font-size: 15px; }
    .fav-price small { font-size: 11px; }
    /* 收藏列表页的卡片底部还并着「取消收藏」按钮：两列后横向放不下
       （实测 360 被压成两行、320 竖成四行并把卡片撑高），改成纵向堆叠，谁也不挤谁 */
    .fav-bottom { flex-direction: column; align-items: flex-start; gap: 2px; }
    .fav-del { white-space: nowrap; }
    .u-dash-grid.u-col2 { grid-template-columns: 1fr; }
}

/* ---------- 订单列表 ---------- */
.ord-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 18px; }
.ord-tabs a {
    padding: 7px 16px;
    font-size: 14px;
    color: #3c4456;
    background: #fff;
    border: 1px solid #e3e7ee;
    border-radius: 20px;
    transition: all .2s;
}
.ord-tabs a.on { background: var(--primary); border-color: var(--primary); color: #fff; }
.ord-item {
    border: 1px solid #e9ebf0;
    border-radius: 12px;
    background: #fff;
    margin-bottom: 16px;
    overflow: hidden;
}
.ord-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 11px 18px;
    background: #f8fafc;
    border-bottom: 1px solid #edf0f5;
    font-size: 13px;
    color: #7a8494;
}
.ord-head .st { color: #df8f36; font-weight: 600; font-size: 14px; }
.ord-body { display: flex; align-items: center; padding: 16px 18px; gap: 14px; }
.ord-goods { flex: 1; min-width: 0; display: flex; align-items: center; gap: 12px; }
.ord-goods img { width: 56px; height: 56px; object-fit: cover; border-radius: 8px; flex: none; }
.ord-goods .t {
    flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-size: 14px; color: #2b3445;
}
.ord-goods .sub { font-size: 12px; color: #98a1b0; margin-top: 4px; }
.ord-price { font-size: 16px; font-weight: 700; color: #e2563f; white-space: nowrap; }
.ord-price small { font-size: 12px; }
.ord-foot {
    display: flex; align-items: center; justify-content: space-between;
    padding: 10px 18px;
    border-top: 1px solid #f3f5f8;
}
.ord-note { font-size: 12px; color: #98a1b0; }
.ord-acts { display: flex; gap: 8px; flex-wrap: wrap; }
.btn-sm {
    display: inline-flex; align-items: center;
    padding: 6px 13px;
    font-size: 13px;
    border-radius: 7px;
    cursor: pointer;
    transition: all .15s;
}
.btn-sm.pay { background: var(--primary); color: #fff; border: none; }
.btn-sm.pay:hover { background: var(--primary-dark); }
.btn-sm.ln { background: #fff; color: #3c4456; border: 1px solid #dfe4ec; }
.btn-sm.ln:hover { border-color: var(--primary); color: var(--primary); }
.btn-sm.danger { background: #fff; color: #e64545; border: 1px solid #f3c4c2; }
.btn-sm.danger:hover { background: #fdeceb; }

/* ---------- 订单详情金额表 ---------- */
.amt-line { display: flex; justify-content: space-between; font-size: 14px; color: #3c4456; padding: 5px 0; }
.amt-total { border-top: 1px dashed #e3e7ee; margin-top: 6px; padding-top: 10px; font-size: 16px; }
.amt-total b { color: #e2563f; font-size: 20px; }

/* ---------- 地址列表 ---------- */
.addr-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
.addr-card {
    border: 1px solid #e9ebf0; border-radius: 12px; background: #fff;
    padding: 18px 20px; position: relative;
}
.addr-card.dft { border-color: var(--primary); }
.addr-name { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.addr-name b { font-size: 16px; color: #242b3a; }
.addr-tag {
    font-size: 12px; color: var(--primary);
    background: #edf3fa; padding: 1px 8px; border-radius: 9px;
}
.addr-line { font-size: 13px; color: #7a8494; line-height: 1.7; }
.addr-acts { margin-top: 12px; display: flex; gap: 14px; }
.addr-acts button, .addr-acts a {
    border: none; background: none; padding: 0;
    font-size: 13px; color: #3c4456; cursor: pointer;
}
.addr-acts a:hover, .addr-acts button:hover { color: var(--primary); }
.addr-acts .del:hover { color: #e64545; }
@media (max-width: 900px) {
    .addr-grid { grid-template-columns: 1fr; }
}

/* ---------- 购物车 ---------- */
.cart-table { width: 100%; border-collapse: collapse; }
.cart-table th {
    text-align: left; padding: 10px; font-size: 13px; color: #7a8494;
    border-bottom: 1px solid #edf0f5; font-weight: 600;
}
.cart-table td { padding: 14px 10px; border-bottom: 1px solid #f3f5f8; font-size: 14px; vertical-align: middle; }
.cart-table .cg { display: flex; align-items: center; gap: 12px; }
.cart-table .cg img { width: 64px; height: 64px; border-radius: 8px; object-fit: cover; flex: none; }
.cart-table .cg .t a { color: #2b3445; }
.cart-table .cg .t a:hover { color: var(--primary); }
.cart-table .cg .tag-off { display: inline-block; margin-top: 5px; font-size: 11px; color: #e64545; }
.num-stepper { display: inline-flex; align-items: center; border: 1px solid #dfe4ec; border-radius: 7px; overflow: hidden; }
.num-stepper button {
    width: 30px; height: 30px; border: none; background: #f6f8fa;
    font-size: 16px; color: #3c4456; cursor: pointer;
}
.num-stepper input {
    width: 46px; height: 30px; border: none; text-align: center;
    font-size: 14px; outline: none; background: #fff;
}
.num-stepper button:hover { background: #e8edf3; }
.cart-del { border: none; background: none; color: #98a1b0; cursor: pointer; font-size: 13px; }
.cart-del:hover { color: #e64545; }
.cart-summary {
    display: flex; justify-content: flex-end; align-items: center; gap: 22px;
    margin-top: 22px; padding-top: 18px; border-top: 1px solid #edf0f5;
}
.cart-total { font-size: 15px; color: #3c4456; }
.cart-total b { color: #e2563f; font-size: 22px; }
.empty-box { text-align: center; padding: 70px 20px; color: #98a1b0; }
.empty-box .eb-ico { font-size: 52px; margin-bottom: 14px; }
.empty-box .eb-text { font-size: 15px; margin-bottom: 22px; }

/* ---------- 结算 ---------- */
.co-block { border: 1px solid #e9ebf0; border-radius: 12px; padding: 20px 22px; margin-bottom: 18px; background: #fff; }
.co-title { font-size: 16px; font-weight: 700; color: #242b3a; margin-bottom: 16px; }
/* 买家留言框 */
.co-block .f-area {
    width: 100%;
    border: 1px solid #dfe4ec;
    border-radius: 8px;
    background: #fafbfd;
    color: #3c4456;
    font-size: 14px;
    line-height: 1.7;
    padding: 11px 14px;
    outline: none;
    resize: vertical;
    min-height: 96px;
    transition: border-color .2s, box-shadow .2s, background .2s;
}
.co-block .f-area:focus {
    border-color: var(--primary);
    background: #fff;
    box-shadow: 0 0 0 3px rgba(37, 99, 235, .12);
}
.co-block .f-area::placeholder { color: #a7b0bf; }
.addr-choice { display: flex; gap: 12px; flex-wrap: wrap; }
.addr-opt {
    flex: 1; min-width: 260px;
    border: 2px solid #e9ebf0; border-radius: 10px; padding: 13px 15px;
    cursor: pointer; transition: all .15s; background: #fff;
}
.addr-opt:hover { border-color: #c9d6e6; }
.addr-opt.sel { border-color: var(--primary); background: #f8fbfe; }
.addr-opt .n { font-weight: 600; color: #242b3a; margin-bottom: 4px; }
.addr-opt .d { font-size: 13px; color: #7a8494; line-height: 1.6; }
.co-pay-row { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }
.co-pay {
    border: 2px solid #e9ebf0; border-radius: 10px; padding: 13px 20px;
    cursor: pointer; min-width: 200px;
}
.co-pay.sel { border-color: var(--primary); background: #f8fbfe; }
.co-pay .pn { font-weight: 600; font-size: 15px; color: #242b3a; }
.co-pay .pd { font-size: 12px; color: #98a1b0; margin-top: 3px; }
.co-aside { width: 340px; flex: none; }
.co-sumline { display: flex; justify-content: space-between; font-size: 14px; padding: 6px 0; color: #3c4456; }
.co-sumline .muted { color: #98a1b0; }
.co-go { width: 100%; margin-top: 16px; font-size: 16px; padding: 13px; }
@media (max-width: 1000px) {
    .co-wrap { flex-direction: column; }
    .co-aside { width: 100%; }
}

/* ---------- 商城流程页扩展（购物车 / 结算 / 订单详情） ---------- */
.crumb-simple { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; font-size: 13px; color: #7a8494; margin: 4px 0 18px; }
.crumb-simple a { color: #7a8494; transition: color .15s; }
.crumb-simple a:hover { color: var(--primary); }
.crumb-simple .sep { color: #c5cbd6; }
.crumb-simple .cur { color: #242b3a; font-weight: 600; }

.f-hint { font-size: 12px; color: #98a1b0; margin-top: 6px; }
.cart-price b { color: #e2563f; font-weight: 700; }
.cart-price .cart-unit, .cart-sub { color: #e2563f; }
.cart-unit { font-size: 12px; color: #98a1b0; margin-left: 3px; }
.cart-sub { font-weight: 700; }

.cart-summary { gap: 18px; }
.cart-summary .cs-count { font-size: 14px; color: #7a8494; }
.cart-summary .cs-count b { color: #e2563f; font-size: 18px; }
.cart-summary .cs-note { display: block; font-size: 12px; color: #98a1b0; font-weight: 400; margin-top: 3px; text-align: right; }
.cart-total { text-align: right; }

.co-wrap { display: flex; gap: 20px; align-items: flex-start; }
.co-main { flex: 1; min-width: 0; }
.co-wrap-inner { display: flex; gap: 18px; }
.co-wrap-inner .co-block { flex: 1; min-width: 0; }
.co-title { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.co-title-link { font-size: 13px; font-weight: 400; color: var(--primary); }
.co-title-link:hover { color: var(--primary-dark); }
.co-radio { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; clip: rect(0 0 0 0); }
.co-radio:focus-visible + .n { outline: 2px solid var(--primary); }
.co-pay .pd .warn { color: #df8f36; }
.co-offline-tip {
    margin-top: 12px; padding: 12px 14px;
    background: #fdf8ef; border: 1px solid #f3e2c0; border-radius: 8px;
    font-size: 13px; line-height: 1.8; color: #8a6420;
}
.co-sumline.amt { border-top: 1px dashed #e3e7ee; margin-top: 8px; padding-top: 12px; font-size: 15px; }
.co-sumline.amt b { color: #e2563f; font-size: 22px; }
.co-agree { font-size: 12px; color: #b0b6c2; text-align: center; margin-top: 12px; }
.co-go:disabled { opacity: .6; cursor: not-allowed; }
.btn-add { padding: 7px 16px; font-size: 14px; }

/* 订单列表：商品行 */
.ord-meta { color: #7a8494; }
.ord-code { color: #3c4456; font-weight: 600; }
.ord-head .dot, .ord-note .dot { color: #cfd5de; margin: 0 8px; }
.ord-head .dot-red { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #e2563f; margin-right: 5px; vertical-align: 1px; }
.ord-glist { padding: 4px 18px; }
.og-row {
    display: flex; align-items: center; gap: 12px;
    padding: 11px 0;
    border-bottom: 1px solid #f5f7fa;
}
.og-row:last-child { border-bottom: none; }
.og-pic { width: 52px; height: 52px; flex: none; border-radius: 8px; overflow: hidden; background: #f0f3f8; display: flex; align-items: center; justify-content: center; }
.og-pic img { width: 100%; height: 100%; object-fit: cover; }
.og-ph { color: #c2c9d4; font-size: 14px; }
.og-info { flex: 1; min-width: 0; }
.og-name {
    display: block; font-size: 14px; color: #2b3445;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.og-name:hover { color: var(--primary); }
.og-sub { font-size: 12px; color: #98a1b0; margin-top: 4px; }
.og-count { flex: none; width: 70px; font-size: 14px; color: #3c4456; }
.og-line { flex: none; width: 120px; text-align: right; font-weight: 700; color: #3c4456; }
.ord-note b.ord-total { color: #e2563f; font-size: 16px; }
.ord-note { max-width: 46%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 订单详情 */
.od-state {
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    background: linear-gradient(135deg, #f8fbfe, #eef4fb);
    border: 1px solid #e2ebf5; border-radius: 10px;
    padding: 16px 18px;
}
.od-state-text { font-size: 20px; color: #242b3a; }
.od-state-sub { display: block; font-size: 13px; color: #7a8494; margin-top: 6px; }
.od-state-money { text-align: right; }
.od-state-money span { display: block; font-size: 12px; color: #98a1b0; }
.od-state-money b { font-size: 24px; color: #e2563f; }
.od-pay-tip {
    margin-top: 14px; padding: 14px 16px;
    background: #fdf8ef; border: 1px solid #f3e2c0; border-radius: 10px;
}
.od-pay-tip h4 { font-size: 14px; color: #8a6420; margin-bottom: 8px; }
.od-pay-tip p { font-size: 13px; color: #8a6420; line-height: 1.9; }
.od-pay-tip p.muted { color: #b3945a; }
.amt-box { max-width: 380px; margin-left: auto; }
.amt-line .muted { color: #98a1b0; }

.dl-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px 22px; }
.dl-i { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.dl-i.full { grid-column: 1 / -1; }
.dl-i span { font-size: 12px; color: #98a1b0; }
.dl-i b { font-size: 14px; color: #3c4456; word-break: break-all; }
.dl-i b.st { color: #df8f36; }

.log-list { list-style: none; padding: 0; margin: 0; }
.log-list li { position: relative; display: flex; gap: 12px; padding: 0 0 18px 0; }
.log-list li::before {
    content: '';
    position: absolute; left: 5px; top: 16px; bottom: 0;
    width: 2px; background: #edf0f5;
}
.log-list li:last-child { padding-bottom: 0; }
.log-list li:last-child::before { display: none; }
.lg-dot { flex: none; width: 12px; height: 12px; border-radius: 50%; background: var(--primary); margin-top: 4px; position: relative; z-index: 1; box-shadow: 0 0 0 3px #f0f6fb; }
.lg-main { flex: 1; min-width: 0; }
.lg-line { display: flex; align-items: baseline; gap: 10px; font-size: 14px; color: #2b3445; }
.lg-line b { color: #242b3a; }
.lg-op { font-size: 12px; color: #98a1b0; }
.lg-remark { font-size: 13px; color: #7a8494; margin-top: 3px; }
.lg-time { flex: none; font-size: 12px; color: #b0b6c2; padding-top: 2px; }

.od-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.od-balance { font-size: 13px; color: #98a1b0; margin-right: auto; }

/* 资金明细 */
.money-head {
    display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap;
    background: linear-gradient(135deg, #fff9f5, #fdf3e9);
    border: 1px solid #f6e5d3; border-radius: 10px;
    padding: 18px 20px; margin-bottom: 18px;
}
.money-bal span { display: block; font-size: 13px; color: #b06d14; }
.money-bal b { font-size: 28px; color: #e2563f; }
.money-help { font-size: 13px; color: #8a6420; text-align: right; line-height: 1.9; }
.money-table .muted-code { color: #b0b6c2; font-size: 12px; }

/* 地址 */
.btn-add { text-decoration: none; }
.addr-card > .addr-tag.dft { position: absolute; top: 14px; right: 16px; }
.addr-name .addr-mobile, .addr-opt .n .addr-mobile { font-size: 13px; color: #98a1b0; font-weight: 400; margin-left: 4px; }
.addr-acts .def { color: var(--primary); }
.f-check { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-size: 14px; color: #3c4456; }
.f-check input { width: 16px; height: 16px; accent-color: var(--primary); }

@media (max-width: 1000px) {
    .co-wrap-inner { flex-direction: column; }
}
@media (max-width: 900px) {
    .od-state { align-items: flex-start; flex-direction: column; }
    .od-state-money { text-align: left; }
    .money-head { align-items: flex-start; }
    .money-help { text-align: left; }
    .dl-grid { grid-template-columns: 1fr; }
}
@media (max-width: 700px) {
    /* 我的订单：手机上整卡改为纵向排布，PC 端的一行式布局一点不动。
       原先「订单号：20 位数字 | 时间」加右侧状态挤在一行：390 视口下 .ord-meta 只剩 244px，
       时间被迫折行、状态被压成「已完/成」两行（360/320 更会把整页撑出横向滚动条）。
       现在 .ord-meta 变纵向两行（订单号 / 时间）、状态 nowrap 贴右；
       flex-basis 200px + wrap 让 320 这类极窄屏改成状态整块掉到下一行，而不是把订单号压断。 */
    .ord-head { align-items: flex-start; flex-wrap: wrap; column-gap: 10px; padding: 12px 14px; }
    .ord-meta { flex: 1 1 200px; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
    .ord-meta .dot { display: none; }
    .ord-meta .om-code { font-size: 13px; }
    .ord-meta .om-time { font-size: 12px; color: #a2a9b6; }
    .ord-code { word-break: break-all; }              /* 订单号再长也只会折行，不会撑破卡片 */
    .ord-head .st { flex: none; margin-left: auto; white-space: nowrap; font-size: 13px; }

    /* 底部：说明占一行、按钮两列铺满。原先是「左说明 + 右按钮」并排，
       手机上按钮被挤成 3~4 行、说明只剩 114px 宽而截断（「实付 ¥9,682.00」看不全）。 */
    .ord-foot { flex-direction: column; align-items: stretch; gap: 10px; padding: 12px 14px; }
    .ord-note { max-width: 100%; white-space: normal; overflow: visible; text-overflow: clip; }
    .ord-acts { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
    .ord-acts .btn-sm { justify-content: center; }

    /* 商品行：小计已在手机上隐藏，把留给它的固定宽度让给商品名 */
    .ord-glist { padding: 2px 14px; }
    .og-row { gap: 10px; }
    .og-count { width: auto; min-width: 34px; text-align: right; }
    .og-line { display: none; }
    .cart-table .num-stepper input { width: 34px; }

    /* 「商品明细」（订单详情）：手机上一行一张卡片。
       原表格在 390 视口下商品列只剩 ~96px：「无线 AP 路由」被逐字拆成 8 行、
       规格标签更是「吸/顶/式/A/X/1/5/0/0」一字一行，一行高 400+px、缩略图还被压成十几像素宽。
       只重排表格自身（thead 藏起、tr 变两列 grid、td 变块），不输出第二份 DOM，PC 端表格一点不动。 */
    .od-goods .table-scroll { overflow: visible; margin: 0; padding: 0; }
    .od-goods .cart-table,
    .od-goods .cart-table tbody { display: block; }
    .od-goods .cart-table thead { display: none; }
    .od-goods .cart-table tr {
        display: grid;
        grid-template-columns: 1fr auto;
        column-gap: 10px;
        row-gap: 6px;
        align-items: center;
        padding: 14px;
        margin-bottom: 12px;
        background: #f8fafd;
        border-radius: 10px;
    }
    .od-goods .cart-table tr:last-child { margin-bottom: 0; }
    .od-goods .cart-table td { display: block; padding: 0; border: none; }
    .od-goods .cart-table td:nth-child(1) { grid-column: 1 / -1; }
    .od-goods .cart-table td:nth-child(2) { grid-column: 1; grid-row: 2; font-size: 13px; color: #7a8494; }
    .od-goods .cart-table td:nth-child(3) { grid-column: 1; grid-row: 3; font-size: 13px; color: #7a8494; }
    .od-goods .cart-table td:nth-child(4) { grid-column: 2; grid-row: 2 / span 2; text-align: right; }
    .od-goods .cart-table td:nth-child(5) { grid-column: 1 / -1; grid-row: 4; text-align: right; padding-top: 2px; }
    /* 卡片上没有表头，数字类单元格用 data-lb 补一个行内标签（PC 端只用表头，属性不显示） */
    .od-goods .cart-table td[data-lb]::before { content: attr(data-lb) " "; color: #b0b6c2; }
    .od-goods .cart-table .cart-sub { font-size: 16px; }
    .od-goods .cart-table .cg { align-items: flex-start; gap: 10px; }
    .od-goods .cart-table .cg img { width: 64px; height: 64px; }
}

/* ---------- 登录/注册弹窗 ---------- */
/* 这一段的数值整套照搬后台登录页（app/admin/view/login/login.html + admin.css 的「登录页」段）：
   720px 直角白卡、左 272px 深色品牌栏、四周 10px 半透明白衬边、右栏 42/48 表单区、≤760 收成上下两段。
   后台那头调样式时这里要跟着调 —— 两边是同一个「登录窗口」的两面 */
.gb-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 16px;
}
.gb-modal.open { display: flex; }
.gb-mask {
    position: absolute;
    inset: 0;
    background: rgba(23, 30, 43, .55);
    backdrop-filter: blur(2px);
}
.gb-dialog {
    position: relative;
    z-index: 1;
    display: flex;
    width: 720px;
    max-width: calc(100vw - 34px);
    max-height: 92vh;
    overflow: hidden;              /* 只有右栏滚，品牌栏固定 */
    background: #fff;
    border-radius: 0;              /* 直角，照后台 .login-card */
    /* 四周 10px 半透明白衬边 —— 就是后台 .login-card 那条 box-shadow: 0 0 0 10px rgba(255,255,255,.2)，
       压在深色遮罩上是一圈淡淡的亮边 */
    box-shadow: 0 0 0 10px rgba(255, 255, 255, .2);
    animation: gbPop .18s ease-out;
}
@keyframes gbPop {
    from { opacity: 0; transform: translateY(16px) scale(.98); }
    to   { opacity: 1; transform: none; }
}
/* 左栏：品牌区（图形标 / 站名 / 虚线分隔 / 站点简介 / 底部版本行） */
.gb-brand {
    flex: none;
    width: 272px;
    padding: 44px 26px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    border-right: 1px solid #eef1f5;
    background: linear-gradient(160deg, #262b33 0%, #14171c 100%);
}
/* 品牌块整体居中（margin-top/bottom 都被下面的 .gb-ver 分走一半，视觉上就是"内容居中、版本行钉底"） */
.gb-brand .brand-main { margin-top: auto; }
/* 品牌标就是站点根目录的 /logo.png（201×45），原尺寸显示不缩放，压到七成不透明度；
   左右 auto 让它在品牌块里居中 —— 块宽由下面那行站名撑到内宽（219），不补 auto 的话图会贴着左边 */
.gb-brand .brand-mark { display: block; width: 201px; height: 45px; margin: 0 auto 16px; opacity: .7; }
.gb-brand .brand-name {
    font-family: "Arial Black", "Microsoft YaHei", Arial, sans-serif;
    font-size: 26px;
    font-weight: 900;
    color: #fff;
    letter-spacing: .5px;
}
.gb-brand .brand-name b { color: #f26a21; }
.gb-brand .brand-tag {
    width: 100%;
    margin-top: 20px;
    padding-top: 16px;
    border-top: 1px dashed rgba(255, 255, 255, .16);
    font-size: 12px;
    color: rgba(255, 255, 255, .52);
    line-height: 1.95;
    /* 站点简介长短不一，固定最多两行，多出来的收省略号，免得把卡片撑高 */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.gb-brand .gb-ver { margin-top: auto; padding-top: 14px; font-size: 12px; color: rgba(255, 255, 255, .38); }
/* 右栏：表单区（内容过长时自己滚，品牌栏不动） */
.gb-body { flex: 1; min-width: 0; padding: 42px 48px 38px; overflow-y: auto; }
.gb-close {
    position: absolute;
    top: 10px;
    right: 14px;
    border: none;
    background: none;
    font-size: 24px;
    line-height: 1;
    color: #98a1b0;
    cursor: pointer;
    padding: 4px;
    transition: color .15s;
}
.gb-close:hover { color: #e64545; }
.gb-tabs {
    display: flex;
    margin-bottom: 20px;
    border-bottom: 2px solid #eef0f5;
}
.gb-tab {
    flex: 1;
    border: none;
    background: none;
    padding: 4px 0 12px;
    font-size: 16px;
    color: #7a8494;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    transition: all .15s;
}
.gb-tab:hover { color: #3c4456; }
/* 选中态跟着下面的按钮一起走后台那支蓝（#2b7fe0）：一个弹窗里两种蓝会显得是两个拼起来的组件。
   站内主色 --primary 是灰蓝，只留给页面主体，这里刻意不跟 —— 这一块是"后台登录页风格" */
.gb-tab.active {
    color: #2b7fe0;
    font-weight: 700;
    border-bottom-color: #2b7fe0;
}
/* 「找回密码」不是常驻选项卡：密码登录 / 短信登录 / 注册这三档时那一枚不出现，
   只有点了「忘记密码」才切过去；切过去后 tabs 栏只留「返回登录 + 找回密码」——
   其余三档这一刻都不可达，摆在那儿只会让人点回去把刚填的账号重填一遍。
   「返回登录」固定回密码登录那一档（不管是从哪一档点的忘记密码），它就是这一档的出口。 */
.gb-tabs .gb-tab-find,
.gb-tabs .gb-tab-back { display: none; }
.gb-tabs.tabs-find .gb-tab { display: none; }
.gb-tabs.tabs-find .gb-tab-find,
.gb-tabs.tabs-find .gb-tab-back { display: block; }
.gb-pane { display: none; }
.gb-pane.active { display: block; }
.gb-dialog .u-form .f-row { margin-bottom: 14px; }

/* 表单控件照着后台登录页做（app/admin/view/login/login.html + admin.css 的 .login-form）：
   图标压在框内左侧、框高 44px、圆角 5px、聚焦时描边 + 淡蓝光圈，主按钮同为 #2b7fe0 实心蓝 + 字距 3px。
   两处同一套数值，从后台走到前门不会换手感。
   这些规则一律收在 .gb-dialog 里 —— .u-form / .f-input 会员中心的表单也在用，不能外溢 */
.gb-dialog .f-ctrl { position: relative; }
.gb-dialog .f-ctrl .f-ico {
    position: absolute; left: 13px; top: 50%; transform: translateY(-50%);
    width: 16px; height: 16px; color: #b3bac5; pointer-events: none;
}
.gb-dialog .f-ctrl .f-ico svg { display: block; width: 16px; height: 16px; }
.gb-dialog .u-form .f-input {
    height: 44px;
    padding: 0 14px 0 40px;
    font-size: 14px;
    color: #1f2d3d;
    border: 1px solid #dcdfe6;
    border-radius: 5px;
    transition: border-color .2s, box-shadow .2s;
}
.gb-dialog .u-form .f-input::placeholder { color: #b3bac5; }
.gb-dialog .u-form .f-input:focus { border-color: #2b7fe0; box-shadow: 0 0 0 3px rgba(43, 127, 224, .12); }
.gb-dialog .f-captcha { gap: 10px; }
.gb-dialog .f-captcha .f-ctrl { flex: 1; min-width: 0; }
/* 验证码图按原比例给高度（后台同样 height:44 + width:auto），不写死宽度免得拉伸变形 */
.gb-dialog .f-captcha img {
    height: 44px;
    width: auto;
    border-radius: 5px;
    border: 1px solid #e6e9ef;
    background: #f5f7fa;
    cursor: pointer;
    flex: none;
}
/* 「获取验证码」：占的是验证码图片那个位置，所以同款高度与圆角。
   倒计时期间是 disabled 态 —— 灰掉比「点了没反应」好懂 */
.gb-dialog .btn-sms {
    height: 44px;
    padding: 0 14px;
    border: 1px solid #d7dce5;
    border-radius: 5px;
    background: #f5f7fa;
    color: var(--primary);
    font-size: 13px;
    white-space: nowrap;
    cursor: pointer;
    flex: none;
}
.gb-dialog .btn-sms:hover { border-color: var(--primary); background: #eef4fd; }
.gb-dialog .btn-sms:disabled { color: #98a1b0; border-color: #e6e9ef; cursor: default; }
.gb-dialog .btn-sms:disabled:hover { background: #f5f7fa; border-color: #e6e9ef; }
/* 提交按钮：与后台 .login-btn 同一套数值（含 hover 抬阴影、提交中浅蓝禁用态） */
.gb-dialog .auth-submit {
    width: 100%;
    height: 44px;
    margin-top: 4px;
    padding: 0 22px;
    border: none;
    border-radius: 5px;
    font-size: 15px;
    letter-spacing: 3px;
    color: #fff;
    background: #2b7fe0;
    box-shadow: none;
}
.gb-dialog .auth-submit:hover { background: #4a94ea; color: #fff; box-shadow: 0 6px 16px rgba(43, 127, 224, .28); }
.gb-dialog .auth-submit:disabled { background: #93b8e6; box-shadow: none; cursor: default; }
/* 第三方账号登录（微信 / QQ 圆钮）
   与会员登录页的 .auth-oauth（带文字的胶囊按钮）是同一件事的两种形态 —— 弹窗右栏窄，
   圆钮居中更省地方，也不跟下面的主按钮抢注意力；两处的跳转地址一致（都进 Oauth.php）。
   开关关着时整块不渲染（见 header.html），所以这里不用考虑"关掉怎么藏"。
   图标是内联 SVG 且 fill:currentColor —— 颜色只由这里的 color 决定，hover 直接换底色 */
.gb-oauth { margin-top: 20px; }
.gb-oauth .go-title { position: relative; text-align: center; margin-bottom: 14px; }
.gb-oauth .go-title::before {
    content: ''; position: absolute; left: 0; right: 0; top: 50%;
    height: 1px; background: #eef1f6;
}
.gb-oauth .go-title span {
    position: relative; z-index: 1; padding: 0 12px;
    font-size: 12px; color: #b0b6c2; background: #fff;
}
.gb-oauth .go-btns { display: flex; justify-content: center; gap: 18px; }
.gb-oauth .go-btn {
    display: flex; align-items: center; justify-content: center;
    width: 42px; height: 42px; border-radius: 50%;
    background: #f5f7fa; border: 1px solid #e6e9ef;
    transition: background .2s, border-color .2s, color .2s;
}
.gb-oauth .go-btn svg { display: block; width: 22px; height: 22px; }
.gb-oauth .go-btn.wx { color: #2dc100; }
.gb-oauth .go-btn.qq { color: #12b7f5; }
.gb-oauth .go-btn:hover { color: #fff; }
.gb-oauth .go-btn.wx:hover { background: #2dc100; border-color: #2dc100; }
.gb-oauth .go-btn.qq:hover { background: #12b7f5; border-color: #12b7f5; }

/* ---------- 第三方登录「演示模式」就地扫码面板 ----------
   后台开了微信 / QQ 登录开关、但还没填 AppID 与密钥时，点那枚圆钮不跳外站，
   而是由 header.html 的脚本把 .go-demo 追加进 .gb-body 并加上 .oauth-demo-on。
   这一段负责：① 把原来的选项卡 / 表单 / 第三方入口整体收起；② 把扫码面板排成与登录表单同宽的一列 */
.gb-body.oauth-demo-on .gb-tabs,
.gb-body.oauth-demo-on .gb-pane,
.gb-body.oauth-demo-on .gb-oauth,
.gb-body.oauth-demo-on .auth-extra,
.gb-body.oauth-demo-on .auth-foot,
.gb-body.oauth-demo-on .gb-foot { display: none; }

.go-demo { display: flex; flex-direction: column; align-items: center; text-align: center; }
/* 只有一个渠道时顶部是这句标题；两个渠道时换成 .gd-tabs，这里不渲染 */
.go-demo .gd-head { margin: 2px 0 18px; font-size: 16px; font-weight: 700; color: #1f2d3d; }
/* 双渠道切换：外观照 .gb-tabs / .gb-tab */
.go-demo .gd-tabs { display: flex; align-self: stretch; margin-bottom: 20px; border-bottom: 2px solid #eef0f5; }
.go-demo .gd-tab {
    flex: 1; border: none; background: none; padding: 4px 0 12px;
    font-size: 15px; color: #7a8494; cursor: pointer;
    border-bottom: 2px solid transparent; margin-bottom: -2px; transition: all .15s;
}
.go-demo .gd-tab:hover { color: #3c4456; }
.go-demo .gd-tab.active { color: #2b7fe0; font-weight: 700; border-bottom-color: #2b7fe0; }
/* 二维码白框 */
.go-demo .gd-qr {
    padding: 10px; background: #fff; border: 1px solid #e6e9ef; border-radius: 10px;
    box-shadow: 0 6px 18px rgba(31, 45, 61, .07);
}
.go-demo .gd-qr img { display: block; width: 188px; height: 188px; }
.go-demo .gd-scan { margin-top: 14px; font-size: 14px; color: #3c4456; }
.go-demo .gd-tip { margin-top: 8px; font-size: 12px; line-height: 1.65; color: #b0b6c2; }
/* 给站长看的配置提醒（偏警示的浅黄底） */
.go-demo .gd-conf {
    align-self: stretch; margin-top: 16px; padding: 10px 12px; box-sizing: border-box;
    font-size: 12px; line-height: 1.65; color: #8a6d3b; text-align: left;
    background: #fff8e6; border: 1px solid #ffe8b3; border-radius: 6px;
}
/* 返回登录：做成与登录表单同宽的次级按钮 */
.go-demo .gd-back {
    align-self: stretch; margin-top: 20px; height: 42px; line-height: 40px; padding: 0;
    border: 1px solid #dcdfe6; border-radius: 5px; background: #fff;
    color: #5a6472; font-size: 14px; cursor: pointer; transition: all .15s;
}
.go-demo .gd-back:hover { border-color: #2b7fe0; color: #2b7fe0; background: #f7f9fc; }

/* 「扫码登录」入口：钉在登录卡右下角的小二维码（弹窗与独立登录页共用同一份）。
   .gb-body 没建定位上下文，所以这里的绝对定位相对的是 .gb-dialog / .auth-card 这张卡，
   天然落在卡片右下角；hover 时从图标左侧浮出一枚「扫码登录」气泡（右缘一个指向图标的三角），
   移开即消失。「找回密码」那档与演示面板展开时都不该出现，见末尾两条 */
.gb-qr-entry {
    position: absolute;
    right: 8px;
    bottom: 6px;
    z-index: 5;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    /* 取品牌栏那句简介（.brand-tag：rgba(255,255,255,.52) 压在深色渐变上）合成后的灰 */
    color: #929497;
    cursor: pointer;
    transition: color .2s;
}
/* 三角底色：卡片右下角斜切出来的一块淡蓝光晕，图标正坐在它上面。
   伪元素挂在图标框上、再往右下各外扩一段，正好铺到卡片角上；用一条 45° 对角
   切一半（50%），只让右下那一半着色，于是自然成一个贴着卡角的直角三角形 */
.gb-qr-entry::before {
    content: '';
    position: absolute;
    right: -8px;
    bottom: -6px;
    width: 88px;
    height: 78px;
    background: linear-gradient(to bottom right, transparent 49.6%, #e9f1fc 50.4%);
    z-index: -1;
    pointer-events: none;
}
.gb-qr-entry svg { display: block; width: 26px; height: 26px; fill: currentColor; }
.gb-qr-entry:hover { color: #2b7fe0; }
.gb-qr-entry:hover::before { background: linear-gradient(to bottom right, transparent 49.6%, #d7e7fb 50.4%); }
.gb-qr-entry .qe-tip {
    position: absolute;
    right: calc(100% + 9px);
    top: 50%;
    transform: translateY(-50%);
    padding: 6px 12px;
    border-radius: 6px;
    background: #2b7fe0;
    color: #fff;
    font-size: 13px;
    line-height: 1;
    white-space: nowrap;
    opacity: 0;
    visibility: hidden;
    transition: opacity .18s, visibility .18s;
    pointer-events: none;
}
/* 三角：贴在气泡右缘、尖端朝右指着图标 */
.gb-qr-entry .qe-tip::after {
    content: '';
    position: absolute;
    left: 100%;
    top: 50%;
    margin-top: -6px;
    border: 6px solid transparent;
    border-left-color: #2b7fe0;
}
.gb-qr-entry:hover .qe-tip { opacity: 1; visibility: visible; }
/* 演示面板展开时收起（面板占了整屏，右下角再挂一枚会打架） */
.gb-body.oauth-demo-on .gb-qr-entry { display: none; }
/* 「找回密码」这档选项卡栏只剩「返回登录 + 找回密码」，主入口三档都不在，这枚也一并收起 */
.gb-body:has(.gb-tabs.tabs-find) .gb-qr-entry { display: none; }

/* 登录/注册提示语：桌面端由左栏 .brand-tag 展示（见 header.html），这里默认收起，
   只在小屏露出来 —— 小屏左栏收成一行、.brand-tag 是 display:none，
   提示语总得有个地方落 */
.gb-foot {
    display: none;
    margin-top: 18px;
    font-size: 12px;
    color: #b0b6c2;
    text-align: center;
    line-height: 1.6;
}
/* 小屏：卡片转上下两段，品牌区缩成一行（与后台登录页的 760 断点同款，只把关闭钮留在右上角） */
@media (max-width: 760px) {
    .gb-modal { padding: 14px; }
    .gb-dialog {
        flex-direction: column;
        width: 100%;
        max-width: 100%;
        max-height: 94vh;
        box-shadow: 0 0 0 6px rgba(255, 255, 255, .2);
    }
    .gb-brand {
        width: 100%;
        padding: 18px 20px;
        border-right: none;
        border-bottom: 1px solid #eef1f5;
        flex-direction: row;
        justify-content: flex-start;
        gap: 14px;
        text-align: left;
    }
    /* 横排时：auto 会把品牌块压到行底要还回去，另外这层包壳也得跟着变成横排（默认是 block，会竖着堆） */
    .gb-brand .brand-main { margin-top: 0; display: flex; align-items: center; gap: 10px; }
    .gb-brand .brand-mark { width: 151px; height: 44px; margin: 0; }
    /* 英文站名比中文宽（26px 下 168px），这一行放不下 logo(151)+间隙，收到 22px 才不挤掉右边距 */
    .gb-brand .brand-name { font-size: 22px; }
    .gb-brand .brand-tag { display: none; }
    .gb-brand .gb-ver { display: none; }
    /* 左栏那块收掉后，登录/注册提示语改由右栏底部这一句接棒（桌面端正好反过来） */
    /* 卡片右下角挂着「扫码登录」的三角图标块，提示语右侧留出空间，免得文字被压住 */
    .gb-dialog .gb-foot { display: block; padding-right: 62px; }
    /* 右下角那块三角与图标在窄屏上按比例收一档，免得占掉半个卡片 */
    .gb-qr-entry { right: 8px; bottom: 6px; width: 32px; height: 32px; }
    .gb-qr-entry svg { width: 24px; height: 24px; }
    .gb-qr-entry::before { right: -8px; bottom: -6px; width: 80px; height: 70px; }
    /* 独立登录页底部那行「还没有账号？立即注册」同样给右下角的三角让位 */
    .auth-card .auth-foot { padding-right: 62px; }
    .gb-body { padding: 20px 22px 20px; }
    /* 手机上寸土寸金，把行距收一点，注册那一屏（6 行）就不会在卡片里滚 */
    .gb-tabs { margin-bottom: 16px; }
    .gb-dialog .u-form .f-row { margin-bottom: 12px; }
    /* 关闭钮压在深色品牌行的右侧，颜色调亮一点才看得清 */
    .gb-close { top: 26px; right: 14px; color: rgba(255, 255, 255, .55); }
    .gb-close:hover { color: #fff; }
}

/* ---------- 会员中心通用小工具类（充值/评价/售后等页共用） ---------- */
.u-more { font-size: 13px; color: var(--primary); }
.u-more:hover { color: var(--primary-dark); }
.u-link { color: var(--primary); }
.u-link:hover { color: var(--primary-dark); }
.muted { color: #98a1b0; }
.muted-code { color: #98a1b0; font-size: 12px; }

.btn-primary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: var(--primary);
    color: #fff;
    font-size: 14px;
    line-height: 1.4;
    padding: 10px 20px;
    border-radius: 8px;
    cursor: pointer;
    text-decoration: none;
    transition: background .2s;
}
.btn-primary:hover { background: var(--primary-dark); color: #fff; }
.btn-primary:disabled { opacity: .6; cursor: not-allowed; }

.gb-input, .gb-textarea {
    border: 1px solid #dfe4ec;
    border-radius: 8px;
    background: #fff;
    color: #2b3445;
    font-size: 14px;
    font-family: inherit;
    padding: 10px 13px;
    outline: none;
    transition: border-color .2s;
}
.gb-input:focus, .gb-textarea:focus { border-color: var(--primary); }
.gb-textarea { resize: vertical; }

/* ============================================================
   窄屏表格：横向滚动容器（避免表格把整页撑破）
   ============================================================ */
.table-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-scroll th,
.table-scroll td { white-space: normal; }
.table-scroll td { word-break: break-word; }
.table-scroll .muted-code { word-break: break-all; }

@media (max-width: 768px) {
    .table-scroll { margin: 0 -2px; padding: 0 2px; }
    .table-scroll th { padding: 8px 8px; font-size: 12px; }
    .table-scroll td { padding: 10px 8px; font-size: 13px; }
    .cart-table .cg { align-items: flex-start; }
    .cart-table .cg img { width: 56px; height: 56px; }
}

/* ============================================================
   手机号 / 邮箱认证（资料页）
   ------------------------------------------------------------
   一行里放的是「输入框 + 认证状态 + 去认证」：输入框吃掉剩余宽度，
   状态与按钮 flex:none，不能被压变形。
   手机端（≤980）输入框独占一行，状态与按钮落到第二行。
   ============================================================ */
.vf-field { display: flex; align-items: center; gap: 8px; }
.vf-field .f-input { flex: 1 1 auto; min-width: 0; }
.vf-tag {
    flex: none;
    height: 24px;
    line-height: 22px;
    padding: 0 10px;
    border: 1px solid #e6e9ef;
    border-radius: 12px;
    background: #f5f7fa;
    color: #98a1b0;
    font-size: 12px;
    white-space: nowrap;
}
.vf-tag.is-on { border-color: #c7ecd9; background: #eafaf3; color: #0d9f6e; }
.vf-go {
    flex: none;
    border: 0;
    background: none;
    padding: 0 2px;
    color: var(--primary);
    font-size: 13px;
    cursor: pointer;
}
.vf-go:hover { text-decoration: underline; }
.vf-panel { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.vf-panel .f-input { flex: 1 1 auto; min-width: 0; }
.vf-btn {
    flex: none;
    height: 40px;
    padding: 0 16px;
    border: 1px solid #e6e9ef;
    border-radius: 5px;
    background: #fff;
    color: #2b3445;
    font-size: 13px;
    cursor: pointer;
    transition: border-color .2s, color .2s;
}
.vf-btn:hover { border-color: var(--primary); color: var(--primary); }
.vf-btn:disabled { cursor: not-allowed; background: #f5f7fa; border-color: #e6e9ef; color: #98a1b0; }
.vf-ok { border-color: var(--primary); background: var(--primary); color: #fff; }
.vf-ok:hover { filter: brightness(.94); color: #fff; }
.vf-hint { margin-top: 6px; font-size: 12px; color: #98a1b0; }
.vf-hint.is-bad { color: #e2544c; }
.vf-hint.is-ok { color: #0d9f6e; }

@media (max-width: 980px) {
    .vf-field { flex-wrap: wrap; }
    .vf-field .f-input { flex: 1 1 100%; }
    .vf-panel { flex-wrap: wrap; }
    .vf-panel .f-input { flex: 1 1 100%; }
    .vf-btn { flex: 1 1 auto; }
}

/* ============================================================
   PC 端：卡片外框一律直角（2026-10-04 用户要求，手机端不变）
   ------------------------------------------------------------
   手机端保持圆角 —— 那边卡片已经是纵向堆叠/卡片流的读法，圆角更能认出边界，
   所以走 min-width 断点覆盖，而不是回头去改上面那几条基础规则。
   这段必须留在文件末尾：同特异性靠后的胜出，写在前面会被
   .ord-item(507) / .co-block(621) 这些后面才定义 border-radius 的规则压回去。
   只动「页面级白卡」这一层；按钮、输入框、头像、状态药丸、图标圆底
   各有自己的形状语义，不是"卡片外框"，一律不碰。
   ============================================================ */
@media (min-width: 981px) {
    .u-aside-card,
    .u-card,
    .u-dash-item,
    .fav-card,
    .ord-item,
    .addr-card,
    .co-block { border-radius: 0; }
}
