/* ==========================================================================
   绩效管理系统 · 后台 UI 设计系统 v2.0
   ThinkPHP 8 + Layui 2.9.20
   说明：本文件只做「主题皮肤 + 组件增强」，不改动任何业务类名，
        所有 perf-* 类名保持向后兼容。
   ========================================================================== */

/* ---------- 1. 设计令牌 ---------- */
:root {
    /* 品牌主色：靛蓝 */
    --perf-primary:        #4f46e5;
    --perf-primary-hover:  #4338ca;
    --perf-primary-active: #3730a3;
    --perf-primary-soft:   #eef2ff;
    --perf-primary-rgb:    79, 70, 229;

    /* 语义色 */
    --perf-success: #10b981;
    --perf-warning: #f59e0b;
    --perf-danger:  #ef4444;
    --perf-info:    #2f6fed;

    /* 中性色 */
    --perf-bg:          #f4f6fa;
    --perf-surface:     #ffffff;
    --perf-border:      #e7e9f2;
    --perf-border-soft: #f0f1f7;

    --perf-text:   #1b2130;
    --perf-text-2: #5c6579;
    --perf-text-3: #949cb0;

    /* 侧栏 */
    --perf-side-w:        236px;
    --perf-side-bg:       #191e33;
    --perf-side-bg-2:     #12162a;
    --perf-side-text:     #a6aec5;
    --perf-side-text-hi:  #ffffff;

    /* 形状、阴影、动效 */
    --perf-radius:    14px;
    --perf-radius-sm: 9px;
    --perf-radius-xs: 7px;

    --perf-shadow-xs: 0 1px 2px rgba(20, 26, 48, .05);
    --perf-shadow-sm: 0 1px 3px rgba(20, 26, 48, .07), 0 1px 2px rgba(20, 26, 48, .04);
    --perf-shadow:    0 4px 16px rgba(20, 26, 48, .07), 0 1px 3px rgba(20, 26, 48, .04);
    --perf-shadow-lg: 0 20px 50px rgba(20, 26, 48, .15), 0 4px 12px rgba(20, 26, 48, .08);

    --perf-ease: cubic-bezier(.4, 0, .2, 1);
    --perf-header-h: 64px;
}

/* ---------- 2. 基础重置 ---------- */
* { box-sizing: border-box; }

html, body {
    height: 100%;
    margin: 0;
    padding: 0;
}

body {
    background: var(--perf-bg);
    color: var(--perf-text);
    font-family: "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei", "Helvetica Neue",
                 Helvetica, Arial, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    font-size: 14px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

a { color: var(--perf-primary); text-decoration: none; transition: color .18s var(--perf-ease); }
a:hover { color: var(--perf-primary-hover); }

/* 自定义滚动条 */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(120, 130, 155, .28); border-radius: 8px; }
::-webkit-scrollbar-thumb:hover { background: rgba(120, 130, 155, .45); }

/* ---------- 3. 应用骨架 ---------- */
.perf-app { display: flex; min-height: 100vh; }

.perf-main {
    flex: 1;
    min-width: 0;
    margin-left: var(--perf-side-w);
    display: flex;
    flex-direction: column;
}

.perf-content {
    flex: 1;
    padding: 22px 26px 8px;
    min-width: 0;
}

/* ---------- 4. 侧边栏 ---------- */
.perf-sidebar {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: var(--perf-side-w);
    display: flex;
    flex-direction: column;
    background: linear-gradient(180deg, var(--perf-side-bg) 0%, var(--perf-side-bg-2) 100%);
    color: var(--perf-side-text);
    z-index: 200;
    overflow-y: auto;
    overflow-x: hidden;
}

.perf-brand {
    display: flex;
    align-items: center;
    gap: 11px;
    height: var(--perf-header-h);
    padding: 0 20px;
    flex-shrink: 0;
    border-bottom: 1px solid rgba(255, 255, 255, .06);
}

.perf-brand-mark {
    width: 34px; height: 34px;
    flex-shrink: 0;
    border-radius: 10px;
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, #6366f1 0%, #4f46e5 55%, #7c3aed 100%);
    box-shadow: 0 4px 12px rgba(var(--perf-primary-rgb), .45);
    color: #fff;
    font-size: 17px;
    font-weight: 700;
    letter-spacing: -.5px;
}

.perf-brand-text { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.perf-brand-text b { color: #fff; font-size: 14.5px; font-weight: 600; letter-spacing: .3px; }
.perf-brand-text small { color: rgba(255, 255, 255, .35); font-size: 10.5px; letter-spacing: 1.2px; text-transform: uppercase; }

.perf-nav { flex: 1; padding: 14px 12px 8px; }

.perf-nav-group {
    padding: 14px 12px 8px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 1.4px;
    color: rgba(255, 255, 255, .28);
    text-transform: uppercase;
}
.perf-nav-group:first-child { padding-top: 4px; }

.perf-nav-item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 11px;
    height: 42px;
    margin-bottom: 3px;
    padding: 0 12px;
    border-radius: 10px;
    color: var(--perf-side-text);
    font-size: 13.8px;
    cursor: pointer;
    transition: background .18s var(--perf-ease), color .18s var(--perf-ease);
    user-select: none;
}
.perf-nav-item:hover { background: rgba(255, 255, 255, .06); color: #e7e9f5; }

.perf-nav-item > .layui-icon { font-size: 16px; width: 18px; text-align: center; flex-shrink: 0; }
.perf-nav-item > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 选中态：左侧竖向指示条 + 半透明主色底 */
.perf-nav-item.is-active {
    background: linear-gradient(90deg, rgba(var(--perf-primary-rgb), .28) 0%, rgba(var(--perf-primary-rgb), .10) 100%);
    color: #fff;
    font-weight: 600;
}
.perf-nav-item.is-active::before {
    content: '';
    position: absolute;
    left: 0; top: 50%;
    transform: translateY(-50%);
    width: 3px; height: 20px;
    border-radius: 0 3px 3px 0;
    background: #818cf8;
    box-shadow: 0 0 10px rgba(129, 140, 248, .8);
}
.perf-nav-item.is-active > .layui-icon { color: #a5b4fc; }

.perf-nav-arrow {
    font-size: 11px !important;
    width: auto !important;
    opacity: .55;
    transition: transform .22s var(--perf-ease);
}
.perf-nav-item.is-open .perf-nav-arrow { transform: rotate(180deg); }

/* 二级菜单：展开与否只由 .is-open 类决定（单一数据源）。
   这里用 max-height 过渡做动画，不要再让 JS 的 slideToggle 去管 display，
   否则 CSS 的 display 与 jQuery 的内联 display 会各自维护一套状态而错位 */
.perf-nav-sub {
    max-height: 0;
    padding: 0;
    overflow: hidden;
    transition: max-height .26s var(--perf-ease), padding .26s var(--perf-ease);
}
.perf-nav-item.is-open + .perf-nav-sub {
    max-height: 260px;
    padding: 2px 0 6px;
}

.perf-nav-subitem {
    position: relative;
    display: block;
    height: 36px;
    line-height: 36px;
    margin: 1px 0;
    padding: 0 12px 0 41px;
    border-radius: 9px;
    color: rgba(255, 255, 255, .55);
    font-size: 13px;
    transition: all .18s var(--perf-ease);
}
.perf-nav-subitem:hover { background: rgba(255, 255, 255, .05); color: #dfe3f3; }
.perf-nav-subitem.is-active {
    background: rgba(var(--perf-primary-rgb), .18);
    color: #fff;
    font-weight: 600;
}
.perf-nav-subitem.is-active::before {
    content: '';
    position: absolute;
    left: 28px; top: 50%;
    transform: translateY(-50%);
    width: 5px; height: 5px;
    border-radius: 50%;
    background: #818cf8;
}

.perf-side-foot {
    padding: 14px 20px 18px;
    border-top: 1px solid rgba(255, 255, 255, .06);
    color: rgba(255, 255, 255, .26);
    font-size: 11.5px;
    letter-spacing: .4px;
}

/* ---------- 5. 顶部栏 ---------- */
.perf-topbar {
    position: sticky;
    top: 0;
    z-index: 150;
    height: var(--perf-header-h);
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 0 26px;
    background: rgba(255, 255, 255, .88);
    backdrop-filter: saturate(180%) blur(12px);
    -webkit-backdrop-filter: saturate(180%) blur(12px);
    border-bottom: 1px solid var(--perf-border);
}

/* 必须是 flex：汉堡按钮与标题块要并排。
   原来这里是 block（桌面端标题在上、面包屑在下正好竖排），
   手机端加了汉堡按钮后就变成上下堆叠、互相重叠 */
.perf-topbar-left {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}
.perf-page-title {
    font-size: 17px;
    font-weight: 600;
    color: var(--perf-text);
    letter-spacing: .2px;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.perf-crumb { font-size: 12px; color: var(--perf-text-3); line-height: 1.4; }

.perf-topbar-right { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }

/* 汉堡按钮与抽屉遮罩：桌面端不存在，手机端由 20 节显示出来 */
.perf-nav-toggle {
    display: none;
    position: relative;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 11px;
    /* 必须重置：<button> 自带浏览器默认边框和灰底，不重置就是一个灰框 */
    background: transparent;
    border: 0;
    padding: 0;
    color: var(--perf-text);
    cursor: pointer;
    flex-shrink: 0;
    transition: background .18s var(--perf-ease), color .18s var(--perf-ease);
}
.perf-nav-toggle:hover { background: #f2f3f9; color: var(--perf-text); }
.perf-nav-toggle:active { background: #e9ebf4; }

/* 三条横线：用一条 + 两道 box-shadow 画出来，比图标字体更清晰，
   也不受图标库缺字形影响（layui 并没有 menu 这类图标） */
.perf-nav-toggle::before {
    content: '';
    display: block;
    width: 19px;
    height: 2px;
    border-radius: 2px;
    background: currentColor;
    box-shadow: 0 -6px 0 currentColor, 0 6px 0 currentColor;
    transition: transform .22s var(--perf-ease);
}
.perf-nav-toggle:hover::before { width: 21px; }

.perf-nav-mask { display: none; }
.perf-nav-close { display: none; }

/* ---------- 顶栏待办通知（铃铛） ---------- */
.perf-todo { position: relative; }
.perf-todo-btn {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 10px;
    color: var(--perf-text-2);
    font-size: 18px;
    transition: background .18s var(--perf-ease), color .18s var(--perf-ease);
}
.perf-todo-btn:hover { background: #f2f3f9; }
.perf-todo-btn.has-dot { color: var(--perf-primary); }
/* 有待办时在铃铛右上角点一个红点（不用数字角标：太抢眼，数量在条目文案里已经写了） */
.perf-todo-btn.has-dot::after {
    content: '';
    position: absolute;
    top: 7px;
    right: 7px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #ef4444;
    border: 2px solid #fff;
}
.perf-todo-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    width: 296px;
    background: #fff;
    border: 1px solid var(--perf-border);
    border-radius: 12px;
    box-shadow: var(--perf-shadow-lg);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
    transition: all .18s var(--perf-ease);
}
.perf-todo-menu.is-open { opacity: 1; visibility: visible; transform: translateY(0); }
.perf-todo-list { max-height: 320px; overflow-y: auto; padding: 6px; }
.perf-todo-item {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 10px;
    border-radius: 8px;
    color: var(--perf-text-2);
    font-size: 13.2px;
    transition: background .16s var(--perf-ease);
}
.perf-todo-item:hover { background: #f6f7fb; }
.perf-todo-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--perf-text-3); flex-shrink: 0; }
.perf-todo-item.is-warm   .perf-todo-dot { background: #f59e0b; }
.perf-todo-item.is-danger .perf-todo-dot { background: #ef4444; }
.perf-todo-item.is-normal .perf-todo-dot { background: var(--perf-primary); }
.perf-todo-text { flex: 1; min-width: 0; }
.perf-todo-arrow { font-size: 13px; color: var(--perf-text-3); }
.perf-todo-item:hover .perf-todo-arrow { color: var(--perf-primary); }
.perf-todo-empty { padding: 26px 10px; text-align: center; color: var(--perf-text-3); font-size: 13px; }

/* 用户胶囊 + 悬浮菜单 */
.perf-user {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    height: 44px;
    padding: 0 12px 0 6px;
    border-radius: 12px;
    cursor: pointer;
    transition: background .18s var(--perf-ease);
}
.perf-user:hover { background: #f2f3f9; }

.perf-avatar {
    width: 34px; height: 34px;
    flex-shrink: 0;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, #6366f1 0%, #4f46e5 60%, #7c3aed 100%);
    color: #fff;
    font-size: 14px;
    font-weight: 600;
    box-shadow: 0 2px 8px rgba(var(--perf-primary-rgb), .3);
}

.perf-user-meta { display: flex; flex-direction: column; line-height: 1.25; }
.perf-user-meta b { font-size: 13.5px; font-weight: 600; color: var(--perf-text); }
.perf-user-meta small { font-size: 11.5px; color: var(--perf-text-3); }
.perf-user-meta .perf-role-tag {
    display: inline-block;
    margin-top: 1px;
    padding: 0 6px;
    border-radius: 5px;
    background: var(--perf-primary-soft);
    color: var(--perf-primary);
    font-size: 10.5px;
    font-weight: 600;
    line-height: 16px;
    align-self: flex-start;
}

.perf-user-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 148px;
    padding: 6px;
    background: #fff;
    border: 1px solid var(--perf-border);
    border-radius: 12px;
    box-shadow: var(--perf-shadow-lg);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-6px);
    transition: all .18s var(--perf-ease);
}
.perf-user:hover .perf-user-menu { opacity: 1; visibility: visible; transform: translateY(0); }

.perf-user-menu a {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 11px;
    border-radius: 8px;
    color: var(--perf-text-2);
    font-size: 13.2px;
    transition: all .16s var(--perf-ease);
}
.perf-user-menu a i { font-size: 15px; color: var(--perf-text-3); }
.perf-user-menu a:hover { background: var(--perf-primary-soft); color: var(--perf-primary); }
.perf-user-menu a:hover i { color: var(--perf-primary); }
.perf-user-menu .perf-menu-sep { height: 1px; margin: 5px 4px; background: var(--perf-border-soft); }
.perf-user-menu a.is-danger:hover { background: #fef2f2; color: var(--perf-danger); }
.perf-user-menu a.is-danger:hover i { color: var(--perf-danger); }

/* ---------- 6. 卡片 ---------- */
.perf-card {
    background: var(--perf-surface);
    border: 1px solid var(--perf-border);
    border-radius: var(--perf-radius);
    box-shadow: var(--perf-shadow-sm);
    padding: 20px 22px;
    margin-bottom: 18px;
    transition: box-shadow .22s var(--perf-ease), border-color .22s var(--perf-ease);
}
.perf-card:hover { box-shadow: var(--perf-shadow); border-color: #dfe2ee; }

.perf-card-title {
    position: relative;
    display: flex;
    align-items: center;
    font-size: 15px;
    font-weight: 600;
    color: var(--perf-text);
    letter-spacing: .2px;
    padding: 0 0 0 12px;
    margin-bottom: 18px;
}
.perf-card-title::before {
    content: '';
    position: absolute;
    left: 0; top: 50%;
    transform: translateY(-50%);
    width: 3px; height: 15px;
    border-radius: 3px;
    background: linear-gradient(180deg, #818cf8 0%, var(--perf-primary) 100%);
}

/* 卡片标题右侧可放按钮 */
.perf-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 18px;
}
.perf-card-head .perf-card-title { margin-bottom: 0; }

/* ---------- 7. 数据卡片 ---------- */
.perf-stat-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 16px;
    margin-bottom: 18px;
}

.perf-stat {
    position: relative;
    overflow: hidden;
    background: var(--perf-surface);
    border: 1px solid var(--perf-border);
    border-radius: var(--perf-radius);
    box-shadow: var(--perf-shadow-sm);
    padding: 20px 22px;
    transition: transform .22s var(--perf-ease), box-shadow .22s var(--perf-ease);
}
.perf-stat:hover { transform: translateY(-3px); box-shadow: var(--perf-shadow); }
.perf-stat::after {
    content: '';
    position: absolute;
    right: -28px; top: -28px;
    width: 96px; height: 96px;
    border-radius: 50%;
    background: linear-gradient(135deg, rgba(var(--perf-primary-rgb), .10) 0%, rgba(var(--perf-primary-rgb), .02) 100%);
}

.perf-stat .num {
    font-size: 30px;
    font-weight: 700;
    color: var(--perf-primary);
    line-height: 1.35;
    letter-spacing: -.5px;
}
.perf-stat .label { font-size: 12.5px; color: var(--perf-text-3); }

/* 数字卡图标 */
.perf-stat-icon {
    width: 40px; height: 40px;
    margin-bottom: 14px;
    border-radius: 11px;
    display: flex; align-items: center; justify-content: center;
    background: var(--perf-primary-soft);
    color: var(--perf-primary);
    font-size: 20px;
}
.perf-stat-icon.is-blue   { background: #eaf1ff; color: var(--perf-info); }
.perf-stat-icon.is-orange { background: #fff4e5; color: #d97706; }
.perf-stat-icon.is-green  { background: #e7f8f2; color: #059669; }
.perf-stat-icon.is-purple { background: #f3edff; color: #7c3aed; }

.perf-stat .num .grade-badge { font-size: 17px; padding: 3px 14px; border-radius: 8px; }

/* ---------- 8. 工具栏 ---------- */
.perf-toolbar {
    display: flex;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: 16px;
}
.perf-toolbar .layui-inline { margin-right: 0; }
.perf-toolbar .layui-input { height: 34px; }

/* ---------- 9. 等级徽标 ---------- */
.grade-badge {
    display: inline-block;
    min-width: 26px;
    text-align: center;
    border-radius: var(--perf-radius-xs);
    padding: 2px 9px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .5px;
    line-height: 18px;
}
.grade-S { background: #fef2f2; color: #dc2626; }
.grade-A { background: #fff7ed; color: #ea580c; }
.grade-B { background: #eff6ff; color: #2563eb; }
.grade-C { background: #ecfdf5; color: #059669; }
.grade-D { background: #f4f5f9; color: #64748b; }

/* 文字色工具类 */
.perf-text-danger { color: var(--perf-danger) !important; }
.perf-text-muted  { color: var(--perf-text-3) !important; }
.perf-text-primary { color: var(--perf-primary) !important; }

/* ---------- 10. 提示与空态 ---------- */
.perf-empty {
    padding: 64px 0;
    text-align: center;
    color: var(--perf-text-3);
    font-size: 13.5px;
}
.perf-empty .layui-icon { display: block; font-size: 42px; margin-bottom: 10px; opacity: .35; color: var(--perf-text-3); }

/* 页内提示条（原模板里用的 .layui-alert 全项目并无定义，是裸文本，这里给正式样式） */
.perf-notice {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 11px 14px;
    border-radius: var(--perf-radius-xs);
    background: rgba(var(--perf-primary-rgb), .07);
    border: 1px solid rgba(var(--perf-primary-rgb), .20);
    color: var(--perf-text-2);
    font-size: 13px;
    line-height: 1.75;
}
.perf-notice > .layui-icon { color: var(--perf-primary); font-size: 15px; line-height: 1.75; flex-shrink: 0; }
.perf-notice b { color: var(--perf-text); font-weight: 600; }
/* 需要注意（如任务未启动导致无法自评） */
.perf-notice.is-warn {
    background: rgba(245, 158, 11, .09);
    border-color: rgba(245, 158, 11, .30);
}
.perf-notice.is-warn > .layui-icon { color: #d97706; }

/* 左右分栏（评分页等） */
.perf-split { display: flex; gap: 16px; align-items: flex-start; }
.perf-split-aside { width: 300px; flex-shrink: 0; }
.perf-split-main { flex: 1; min-width: 0; }

/* 行内小表单组合 */
.perf-inline-form { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.perf-inline-form .layui-input { display: inline-block; height: 32px; }

/* 评分录入：上级评分与评语上下分行并铺满。
   原来并排时评语框只有 170px，"评语（选填）"会被截掉一半 */
.perf-score-inputs { display: flex; flex-direction: column; gap: 6px; }
.perf-score-inputs .layui-input { width: 100% !important; }

/* 表格下方的工具栏 */
.perf-toolbar.is-bottom { margin-top: 16px; margin-bottom: 0; }

/* ---------- 11. Layui 按钮重写 ---------- */
.layui-btn {
    height: 36px;
    line-height: 36px;
    padding: 0 17px;
    border: none;
    border-radius: var(--perf-radius-sm);
    font-size: 13.5px;
    font-weight: 500;
    background: var(--perf-primary);
    box-shadow: 0 2px 6px rgba(var(--perf-primary-rgb), .22);
    transition: all .18s var(--perf-ease);
}
.layui-btn:hover {
    background: var(--perf-primary-hover);
    box-shadow: 0 4px 12px rgba(var(--perf-primary-rgb), .3);
    opacity: 1;
}
.layui-btn:active { background: var(--perf-primary-active); }
.layui-btn .layui-icon { font-size: 15px; margin-right: 2px; }

.layui-btn-sm { height: 34px; line-height: 34px; padding: 0 15px; font-size: 13px; }
.layui-btn-lg { height: 44px; line-height: 44px; padding: 0 26px; font-size: 15px; border-radius: 11px; }
.layui-btn-fluid { width: 100%; }

.layui-btn-primary {
    background: #fff;
    border: 1px solid #e0e3ee;
    color: var(--perf-text-2);
    box-shadow: none;
}
.layui-btn-primary:hover {
    background: #f7f8ff;
    border-color: var(--perf-primary);
    color: var(--perf-primary);
    box-shadow: none;
}

.layui-btn-normal { background: var(--perf-info);    box-shadow: 0 2px 6px rgba(47, 111, 237, .22); }
.layui-btn-normal:hover { background: #2560d8; opacity: 1; }
.layui-btn-warm    { background: var(--perf-warning); box-shadow: 0 2px 6px rgba(245, 158, 11, .24); }
.layui-btn-warm:hover { background: #d97706; opacity: 1; }
.layui-btn-danger  { background: var(--perf-danger);  box-shadow: 0 2px 6px rgba(239, 68, 68, .22); }
.layui-btn-danger:hover { background: #dc2626; opacity: 1; }
/* 按钮禁用态。本项目重写过 .layui-btn 的配色，layui 自带的 .layui-btn-disabled
   会被盖掉，导致置灰按钮在页面上看起来仍可点，这里显式补一个明确的禁用外观 */
.layui-btn-disabled,
.layui-btn.layui-btn-disabled {
    opacity: .5 !important;
    cursor: not-allowed !important;
    box-shadow: none !important;
    pointer-events: none;
}

/* 表格行内按钮：改为轻量标签式，去掉厚重实心块 */
.layui-btn-xs {
    height: 26px;
    line-height: 26px;
    padding: 0 10px;
    border: none;
    border-radius: 6px;
    font-size: 12px;
    box-shadow: none;
    background: rgba(var(--perf-primary-rgb), .1);
    color: var(--perf-primary);
}
.layui-btn-xs:hover { background: rgba(var(--perf-primary-rgb), .18); color: var(--perf-primary-hover); opacity: 1; }
.layui-btn-xs.layui-btn-normal { background: rgba(47, 111, 237, .1);  color: var(--perf-info); }
.layui-btn-xs.layui-btn-normal:hover { background: rgba(47, 111, 237, .18); }
.layui-btn-xs.layui-btn-warm    { background: rgba(245, 158, 11, .14); color: #d97706; }
.layui-btn-xs.layui-btn-warm:hover { background: rgba(245, 158, 11, .24); }
.layui-btn-xs.layui-btn-danger  { background: rgba(239, 68, 68, .1);  color: #dc2626; }
.layui-btn-xs.layui-btn-danger:hover { background: rgba(239, 68, 68, .18); }
.layui-btn-xs.layui-btn-primary { background: #fff; border: 1px solid #e0e3ee; color: var(--perf-text-2); }
.layui-btn-xs.layui-btn-primary:hover { background: #f7f8ff; border-color: var(--perf-primary); color: var(--perf-primary); }
.layui-btn-xs .layui-icon { font-size: 13px; margin: 0; }

/* ---------- 12. Layui 表单重写 ---------- */
.layui-input,
.layui-select,
.layui-textarea {
    height: 38px;
    border-radius: var(--perf-radius-sm);
    border: 1px solid #e0e3ee;
    font-size: 13.5px;
    color: var(--perf-text);
    transition: border-color .18s var(--perf-ease), box-shadow .18s var(--perf-ease);
}
.layui-textarea { height: auto; min-height: 76px; line-height: 1.7; padding: 8px 12px; }
.layui-input:hover,
.layui-select:hover,
.layui-textarea:hover { border-color: #c8cdec; }

.layui-input:focus,
.layui-textarea:focus {
    border-color: var(--perf-primary) !important;
    box-shadow: 0 0 0 3px rgba(var(--perf-primary-rgb), .13) !important;
}

.layui-form-label {
    color: var(--perf-text-2);
    font-size: 13.5px;
    padding: 9px 12px 9px 0;
}
.layui-form-item { margin-bottom: 16px; }
.layui-form-item .layui-input-inline { margin-right: 0; }

/* ---------- 12.1 下拉选择框（Layui 渲染后的自定义外观） ---------- */
/* Layui 渲染时不会删掉原生 select，而是在它后面插入 .layui-form-select，
   必须把原生 select 藏起来，否则同一位置会出现两个控件 */
select:has(+ .layui-form-select) { display: none; }

.layui-form-select { width: 100%; }
.layui-form-select .layui-input {
    height: 38px;
    line-height: 36px;
    padding: 0 30px 0 12px;
    border: 1px solid #e0e3ee;
    border-radius: var(--perf-radius-sm);
    font-size: 13.5px;
    color: var(--perf-text);
    background: #fff;
    transition: border-color .18s var(--perf-ease), box-shadow .18s var(--perf-ease);
}
.layui-form-select:hover .layui-input { border-color: #c8cdec; }
.layui-form-select .layui-edge {
    right: 12px;
    margin-top: -3px;
    border-top-color: #9aa1b5;
    transition: transform .22s var(--perf-ease);
}

/* 展开态：输入框高亮 + 箭头翻转 */
.layui-form-selected .layui-input {
    border-color: var(--perf-primary) !important;
    box-shadow: 0 0 0 3px rgba(var(--perf-primary-rgb), .13) !important;
}
.layui-form-selected .layui-edge {
    border-top-color: var(--perf-primary);
    transform: rotate(180deg);
}

/* 下拉面板 */
.layui-form-select dl {
    top: 42px;
    padding: 6px;
    border: 1px solid var(--perf-border);
    border-radius: var(--perf-radius-sm);
    box-shadow: var(--perf-shadow-lg);
    overflow-x: hidden;
    animation: perf-dropdown-in .16s var(--perf-ease);
}
.layui-form-select dl dd {
    margin: 1px 0;
    padding: 0 10px;
    line-height: 34px;
    border-radius: var(--perf-radius-xs);
    font-size: 13.5px;
    color: var(--perf-text-2);
    transition: background .15s var(--perf-ease), color .15s var(--perf-ease);
}
.layui-form-select dl dd:hover { background: var(--perf-primary-soft); color: var(--perf-primary); }
.layui-form-select dl dd.layui-this {
    background: var(--perf-primary-soft) !important;
    color: var(--perf-primary) !important;
    font-weight: 600;
}
.layui-form-select dl dd.layui-select-tips { color: var(--perf-text-3); }
@keyframes perf-dropdown-in {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* 兜底：极少数没被 Layui 渲染到的原生 select，至少和输入框保持同一观感 */
select.layui-select,
.layui-form-item select:not([multiple]) {
    -webkit-appearance: none;
    appearance: none;
    height: 38px;
    padding: 0 30px 0 12px;
    border: 1px solid #e0e3ee;
    border-radius: var(--perf-radius-sm);
    background-color: #fff;
    background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2 4l4 4 4-4' stroke='%239aa1b5' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 11px center;
    background-size: 12px;
    font-size: 13.5px;
    color: var(--perf-text);
    transition: border-color .18s var(--perf-ease), box-shadow .18s var(--perf-ease);
}
select.layui-select:hover,
.layui-form-item select:not([multiple]):hover { border-color: #c8cdec; }
select.layui-select:focus,
.layui-form-item select:not([multiple]):focus {
    border-color: var(--perf-primary);
    box-shadow: 0 0 0 3px rgba(var(--perf-primary-rgb), .13);
    outline: none;
}

/* 复选框 / 单选 / 开关 */
.layui-form-checkbox { border-radius: 6px; padding-right: 10px; }
.layui-form-checkbox:hover i { border-color: var(--perf-primary); }
.layui-form-checked[lay-skin="primary"] i { border-color: var(--perf-primary) !important; background-color: var(--perf-primary) !important; }
.layui-form-checkbox[lay-skin="primary"]:hover i { border-color: var(--perf-primary) !important; }
.layui-form-radio > i:hover, .layui-form-radioed > i { color: var(--perf-primary) !important; }
.layui-form-onswitch { border-color: var(--perf-primary) !important; background-color: var(--perf-primary) !important; }
.layui-form-switch { border-radius: 20px; }

/* 必填星号 */
.layui-form-item .layui-form-label .perf-req { color: var(--perf-danger); margin-right: 2px; }

/* ---------- 13. Layui 表格重写 ---------- */
.layui-table-view {
    margin: 0 !important;
    border: 1px solid var(--perf-border) !important;
    border-radius: var(--perf-radius);
    box-shadow: var(--perf-shadow-xs);
    overflow: hidden;
}
.layui-table-view .layui-table { margin: 0; }
.layui-table-header { background: #fafbfd; border-bottom: 1px solid var(--perf-border) !important; }

.layui-table th {
    background: transparent !important;
    color: var(--perf-text-2);
    font-weight: 600;
    font-size: 13px;
    padding: 11px 12px;
}
.layui-table td {
    color: var(--perf-text);
    font-size: 13.2px;
    padding: 11px 12px;
    border-color: var(--perf-border-soft) !important;
}

/* ---------- 13.1 操作列按钮：绝不允许被省略号吞掉 ----------
   text-overflow: ellipsis 只是绘制层面的效果：放不下的按钮会从画面上消失、
   被画成"…"，但它的布局盒子仍留在原位，于是在"…"附近出现一块
   看不见却能点中的热区（用户会"莫明其妙触发按钮"）。
   因此凡含行内按钮的单元格，一律改为可换行的 flex 布局，按钮永远完整可见。 */
.layui-table-view .layui-table td .layui-table-cell:has(a[lay-event]) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 6px;
    height: auto;
    min-height: 40px;
    padding: 8px 12px;
    line-height: 1.4;
    white-space: normal;
    text-overflow: clip;
}

/* ---------- 13.2 单元格内含输入控件（如「我的自评」的评分框、说明框、保存按钮） ----------
   layui 把 .layui-table-cell 固定成 38px 高（box-sizing:border-box）并 overflow:hidden，
   上下各 6px 内边距后可用高度只剩 26px；而本项目 .layui-input 本身就是 38px 高，
   于是输入框底部被裁掉一截（实测下溢出 6px），保存按钮也被压扁——即"表单被遮住"。
   这里改为高度自适应并解除裁剪。注意保持 display:block 不改成 flex：
   模板里已有一层负责横向排布的 flex div，block 才能让它继续撑满单元格宽度。 */
.layui-table-view .layui-table td .layui-table-cell:has(input),
.layui-table-view .layui-table td .layui-table-cell:has(select),
.layui-table-view .layui-table td .layui-table-cell:has(textarea),
.layui-table-view .layui-table td .layui-table-cell:has(button.layui-btn) {
    height: auto;
    min-height: 40px;
    padding: 8px 12px;
    line-height: normal;
    white-space: normal;
    text-overflow: clip;
    /* visible 而非 hidden：否则输入框聚焦时的 3px 高亮环也会被切掉 */
    overflow: visible;
}
/* 含输入框的行整体变高，同排其他单元格随之垂直居中，避免文字贴着行顶 */
.layui-table-view .layui-table tbody tr:has(.layui-table-cell input) td,
.layui-table-view .layui-table tbody tr:has(.layui-table-cell button.layui-btn) td {
    vertical-align: middle;
}
.layui-table tbody tr:hover,
.layui-table-hover { background: #f7f8ff !important; }
.layui-table-click { background: var(--perf-primary-soft) !important; }

.layui-table-tool { background: #fff; border-bottom: 1px solid var(--perf-border-soft); padding: 8px 12px; }
.layui-table-page { border-top: 1px solid var(--perf-border-soft); padding: 10px 12px; }
.layui-table-page > div { float: right; }
.layui-laypage a,
.layui-laypage span {
    border-radius: 7px;
    border: 1px solid var(--perf-border);
    margin: 0 3px;
    height: 30px;
    line-height: 30px;
    padding: 0 11px;
    color: var(--perf-text-2);
    background: #fff;
}
.layui-laypage a:hover { color: var(--perf-primary); border-color: var(--perf-primary); }
.layui-laypage .layui-laypage-curr .layui-laypage-em { background: var(--perf-primary) !important; border-radius: 7px; }
.layui-laypage .layui-laypage-curr em { color: #fff !important; }
.layui-laypage select, .layui-laypage input { border-radius: 7px; border-color: var(--perf-border); }

/* 无边框表格（弹层内使用） */
.layui-table:not(.layui-table-view .layui-table) { border-radius: var(--perf-radius-xs); overflow: hidden; }
.layui-table:not(.layui-table-view .layui-table) thead tr { background: #fafbfd; }
.layui-table:not(.layui-table-view .layui-table) th { border-bottom: 1px solid var(--perf-border); }

/* ---------- 14. 徽标 / 标签 ---------- */
.layui-badge {
    height: auto;
    line-height: 1.6;
    padding: 2px 9px;
    border-radius: 6px;
    font-size: 12px;
    font-weight: 500;
    background: #f1f3f9;
    color: var(--perf-text-2);
}
.layui-badge.layui-bg-green  { background: rgba(16, 185, 129, .13); color: #059669; }
.layui-badge.layui-bg-blue   { background: rgba(47, 111, 237, .12); color: var(--perf-info); }
.layui-badge.layui-bg-orange { background: rgba(245, 158, 11, .15); color: #d97706; }
.layui-badge.layui-bg-red    { background: rgba(239, 68, 68, .12);  color: #dc2626; }
.layui-badge.layui-bg-gray   { background: #f1f3f9; color: var(--perf-text-2); }

/* ---------- 15. 进度条 ---------- */
.layui-progress { height: 8px; border-radius: 8px; background: #eef0f7; overflow: hidden; }
.layui-progress-bar {
    background: linear-gradient(90deg, #818cf8 0%, var(--perf-primary) 100%);
    border-radius: 8px;
}

/* ---------- 16. 弹层 / 消息 ---------- */
/* 注意：圆角/大阴影只能作用于真正的弹窗层，不能加在 .layui-layer 基类上。
   loading 层与 msg 层同样带 .layui-layer 基类，会被波及
   （加载圈本该 box-shadow:none，却会套上巨型阴影）。这里按类型限定 */
.layui-layer-dialog,
.layui-layer-page,
.layui-layer-iframe {
    border-radius: var(--perf-radius) !important;
    overflow: hidden;
    box-shadow: var(--perf-shadow-lg) !important;
}
.layui-layer-title {
    height: 54px !important;
    line-height: 54px !important;
    padding: 0 20px !important;
    background: #fff !important;
    border-bottom: 1px solid var(--perf-border) !important;
    color: var(--perf-text) !important;
    font-size: 15px !important;
    font-weight: 600;
}
.layui-layer-setwin { top: 17px !important; right: 14px !important; }
.layui-layer-setwin a { color: var(--perf-text-3) !important; }
.layui-layer-setwin a:hover { color: var(--perf-danger) !important; }
.layui-layer-content { font-size: 13.5px; }
.layui-layer-btn { padding: 0 14px 14px !important; }
.layui-layer-btn a {
    height: 34px !important;
    line-height: 34px !important;
    border-radius: var(--perf-radius-sm) !important;
    border: none !important;
    font-size: 13.5px !important;
    background: var(--perf-primary);
}
.layui-layer-btn .layui-layer-btn1 { background: #fff; border: 1px solid #e0e3ee !important; color: var(--perf-text-2); }
.layui-layer-btn .layui-layer-btn1:hover { color: var(--perf-primary); border-color: var(--perf-primary) !important; }
/* 轻提示 toast：layer.msg 带 icon 时是 .layui-layer-msg（白底浅灰边），
   不带 icon 时会额外套 .layui-layer-hui（黑底半透明）。
   这里统一成一套白底风格，并去掉 layui 默认的灰色描边 */
.layui-layer-msg,
.layui-layer-hui {
    border: none !important;
    border-radius: 12px !important;
    background: #fff !important;
    background-color: #fff !important;
    color: var(--perf-text) !important;
    box-shadow: 0 10px 34px rgba(20, 26, 48, .16), 0 2px 8px rgba(20, 26, 48, .08) !important;
}
.layui-layer-msg .layui-layer-content { font-size: 14px; }
/* layer.msg 图标类名对照（layui 内置数组）：
   0 tips / 1 success / 2 error / 3 question / 4 lock / 5 face-cry / 6 face-smile */
.layui-layer-msg .layui-icon-success    { color: #10b981 !important; }
.layui-layer-msg .layui-icon-face-smile { color: #10b981 !important; }
.layui-layer-msg .layui-icon-error      { color: #ef4444 !important; }
.layui-layer-msg .layui-icon-face-cry   { color: #ef4444 !important; }
.layui-layer-msg .layui-icon-tips,
.layui-layer-msg .layui-icon-lock       { color: #f59e0b !important; }
.layui-layer-msg .layui-icon-question   { color: #2f6fed !important; }
/* 图标为绝对定位，垂直居中更精致 */
.layui-layer-msg .layui-layer-content .layui-layer-face {
    top: 50% !important;
    left: 18px;
    transform: translateY(-50%);
}
/* 不带图标的 msg（.layui-layer-hui，黑底已改白底）内容间距 */
.layui-layer-hui .layui-layer-content { padding: 14px 24px !important; }

/* 加载层：还原为透明无阴影，仅把转圈图标换成主色 */
.layui-layer-loading {
    background: none !important;
    box-shadow: none !important;
    border: none !important;
}
.layui-layer-loading-icon { color: var(--perf-primary) !important; }

/* 注意：layer.msg 本身也是 .layui-layer-dialog 类型（type 0），
   带 icon 时其内容区还带 .layui-layer-padding（为绝对定位图标预留 padding-left:58px）。
   若在这里无差别重置 padding，会把左侧预留空间清掉，导致图标与文字重叠。
   所以必须排除 .layui-layer-padding */
.layui-layer-dialog .layui-layer-content:not(.layui-layer-padding) {
    padding: 26px 26px 20px;
    font-size: 14px;
}

/* 弹层内表单的提交按钮居中 */
.layui-layer-content .layui-form-item[style*="center"] { margin-top: 22px; }

/* ---------- 17. 页脚 ---------- */
.perf-footer {
    padding: 16px 26px 22px;
    text-align: center;
    color: var(--perf-text-3);
    font-size: 12px;
}

/* ---------- 18. 登录页 ---------- */
.perf-login {
    display: flex;
    min-height: 100vh;
    background: var(--perf-bg);
}

.perf-login-hero {
    position: relative;
    flex: 1.15;
    overflow: hidden;
    display: flex;
    align-items: center;
    padding: 60px 66px;
    background: linear-gradient(150deg, #1b1f38 0%, #232a52 45%, #3730a3 100%);
    color: #fff;
}
.perf-login-hero::before {
    content: '';
    position: absolute;
    width: 460px; height: 460px;
    right: -140px; top: -160px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(129, 140, 248, .38) 0%, rgba(129, 140, 248, 0) 70%);
}
.perf-login-hero::after {
    content: '';
    position: absolute;
    width: 380px; height: 380px;
    left: -120px; bottom: -150px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(124, 58, 237, .32) 0%, rgba(124, 58, 237, 0) 70%);
}

.perf-hero-inner { position: relative; z-index: 1; max-width: 480px; }

.perf-hero-brand { display: flex; align-items: center; gap: 12px; margin-bottom: 46px; }
.perf-hero-brand .perf-brand-mark { width: 42px; height: 42px; border-radius: 12px; font-size: 20px; background: linear-gradient(135deg, #818cf8 0%, #4f46e5 100%); }
.perf-hero-brand b { font-size: 19px; font-weight: 600; letter-spacing: .5px; }
.perf-hero-brand small { display: block; font-size: 11px; letter-spacing: 1.6px; color: rgba(255, 255, 255, .45); text-transform: uppercase; }

.perf-hero-inner h2 {
    font-size: 38px;
    line-height: 1.4;
    font-weight: 700;
    letter-spacing: 1px;
    margin: 0 0 18px;
    background: linear-gradient(92deg, #ffffff 0%, #c7d2fe 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}
.perf-hero-inner .hero-desc {
    font-size: 15px;
    line-height: 1.9;
    color: rgba(255, 255, 255, .68);
    margin-bottom: 38px;
}

.perf-hero-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 14px 18px; }
.perf-hero-list li {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 13.5px;
    color: rgba(255, 255, 255, .82);
}
.perf-hero-list li i {
    width: 26px; height: 26px;
    flex-shrink: 0;
    border-radius: 8px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255, 255, 255, .12);
    font-size: 14px;
}

.perf-login-panel {
    flex: .85;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 60px 40px;
    background: var(--perf-surface);
}

.perf-login-box { width: 100%; max-width: 352px; }
.perf-login-box h1 {
    font-size: 25px;
    font-weight: 700;
    color: var(--perf-text);
    margin: 0 0 8px;
    letter-spacing: .3px;
}
.perf-login-box .sub { color: var(--perf-text-3); font-size: 13.5px; margin-bottom: 30px; }

.perf-login-box .layui-form-item { margin-bottom: 18px; position: relative; }
.perf-login-box .layui-input {
    height: 46px;
    padding-left: 42px;
    border-radius: 11px;
    border-color: #e5e7f2;
    background: #fafbfd;
    font-size: 14px;
}
.perf-login-box .layui-input:focus { background: #fff; }
.perf-login-box .perf-field-icon {
    position: absolute;
    left: 15px; top: 50%;
    transform: translateY(-50%);
    color: var(--perf-text-3);
    font-size: 17px;
    pointer-events: none;
    z-index: 2;
}
.perf-login-box .layui-btn {
    height: 46px;
    line-height: 46px;
    border-radius: 11px;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: 2px;
    background: linear-gradient(135deg, #5b54ea 0%, var(--perf-primary) 55%, #4338ca 100%);
    box-shadow: 0 6px 18px rgba(var(--perf-primary-rgb), .32);
}
.perf-login-box .layui-btn:hover { box-shadow: 0 8px 24px rgba(var(--perf-primary-rgb), .42); }

.perf-login-tip {
    margin-top: 26px;
    padding-top: 20px;
    border-top: 1px solid var(--perf-border-soft);
    text-align: center;
    color: var(--perf-text-3);
    font-size: 12px;
    line-height: 1.8;
}

/* ---------- 19. 无权限页 ---------- */
.perf-denied {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    background: var(--perf-bg);
    text-align: center;
    padding: 40px;
}
.perf-denied .perf-denied-icon {
    width: 76px; height: 76px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: #fef2f2;
    color: var(--perf-danger);
    font-size: 38px;
    margin-bottom: 6px;
}
.perf-denied h3 { margin: 0; font-size: 20px; font-weight: 600; color: var(--perf-text); }
.perf-denied p { margin: 0; color: var(--perf-text-3); font-size: 13.5px; }
.perf-denied .layui-btn { margin-top: 14px; }

/* ---------- 20. 响应式 ---------- */

/* 桌面/平板大屏 */
@media (max-width: 1200px) {
    .perf-content { padding: 18px 18px 6px; }
    .perf-topbar { padding: 0 18px; }
}

/* 平板：侧栏收成图标栏 */
@media (max-width: 992px) {
    :root { --perf-side-w: 68px; }
    .perf-brand-text,
    .perf-nav-item > span,
    .perf-nav-arrow,
    .perf-nav-group,
    .perf-side-foot { display: none; }
    .perf-brand, .perf-nav-item { justify-content: center; padding: 0; }
    .perf-nav-subitem { padding-left: 0; text-align: center; font-size: 0; height: 32px; line-height: 32px; }
    .perf-nav-subitem::after { content: '·'; font-size: 18px; }
    .perf-nav-subitem.is-active::before { display: none; }
    .perf-login-hero { display: none; }
    /* hero 隐藏后只剩 panel 一个 flex 子项，而它仍带着 flex:.85 ——
       单个子项时空闲空间全按 0.85 分配，于是右侧空出 15%。必须让它独占整行 */
    .perf-login-panel { flex: 1 1 auto; }
}

/* ============ 手机端（≤768px）============
   做三件事：
   1) 侧栏由 68px 图标栏改为抽屉。图标栏在手机上既表达不了含义，
      又白占掉 13% 的屏幕宽度。
   2) 表格转卡片列表。这是手机端最要紧的一件事：本项目表格的列宽合计
      普遍在 900~1300px，而 layui 会把超宽表格塞进它自带的横向滚动容器，
      结果手机上只看得见 fixed 固定在右侧的「操作」列，任务名、状态、
      月份这些数据全在屏幕外（实测任务页表格宽 1052px / 视口 375px）。
      卡片模式下 tr 变成一张卡、表头隐藏、每格用 data-label 显示
      "字段名：值"，一条记录一屏就能看完。
   3) 弹层、工具栏、表单一律改窄屏形态。layui 大量使用内联宽度，
      所以覆盖时必须带 !important。
   ---------------------------------------- */
@media (max-width: 768px) {
    /* ---- 1. 抽屉导航 ---- */
    :root { --perf-side-w: 0px; --perf-header-h: 56px; }

    .perf-sidebar {
        width: 248px;
        transform: translateX(-100%);
        transition: transform .26s var(--perf-ease);
        z-index: 300;
    }
    .perf-sidebar.is-open { transform: translateX(0); box-shadow: 0 12px 40px rgba(20, 26, 48, .28); }

    /* 图标栏那套隐藏规则在抽屉里要全部恢复，否则菜单只剩一列小图标 */
    .perf-brand-text,
    .perf-nav-item > span { display: inline; }
    .perf-nav-arrow { display: inline-block; }
    .perf-nav-group,
    .perf-side-foot { display: block; }
    .perf-brand, .perf-nav-item { justify-content: flex-start; padding: 0 18px; }
    .perf-nav-subitem { padding: 0 18px 0 32px; text-align: left; font-size: 13px; height: auto; line-height: 32px; }
    .perf-nav-subitem::after { content: ''; }
    .perf-nav-subitem.is-active::before { display: block; }

    /* 显隐用 pointer-events 而不是 visibility：visibility 是离散过渡，
       在部分环境下带 is-open 也可能停在 hidden 上（遮罩点不到、抽屉关不掉） */
    .perf-nav-mask {
        display: block;
        position: fixed;
        top: 0; right: 0; bottom: 0; left: 0;
        background: rgba(20, 26, 48, .42);
        opacity: 0;
        pointer-events: none;
        transition: opacity .26s var(--perf-ease);
        z-index: 290;
    }
    .perf-nav-mask.is-open { opacity: 1; pointer-events: auto; }

    /* 抽屉里的关闭按钮：不能只靠"点遮罩"来收起，手机上没有 ESC 可按 */
    .perf-nav-close {
        display: flex;
        position: absolute;
        top: 0; right: 0;
        width: var(--perf-header-h);
        height: var(--perf-header-h);
        align-items: center;
        justify-content: center;
        /* 必须重置：<button> 自带浏览器默认背景（灰白方块），会盖在深色抽屉上 */
        background: transparent;
        border: 0;
        padding: 0;
        color: rgba(255, 255, 255, .7);
        font-size: 17px;
        cursor: pointer;
        z-index: 1;
    }
    .perf-nav-close:hover { color: #fff; }

    .perf-nav-toggle { display: flex; }
    .perf-crumb { display: none; }
    /* 手机端也要显示当前登录账号。之前这里直接 display:none，顶栏只剩一个头像，
       多人共用一台设备时根本看不出自己是以哪个账号登录的。
       限宽 + 省略号兜底：顶栏宽度紧张，页面标题要优先保住完整显示 */
    .perf-user-meta {
        display: flex;
        flex-direction: column;
        line-height: 1.25;
        max-width: 92px;
    }
    .perf-user-meta b,
    .perf-user-meta .perf-role-tag {
        max-width: 92px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .perf-user { padding: 0 4px; }
    /* 手机端顶栏瘦身：页面标题与头像都去掉。
       标题在左侧抽屉里已经能看到（品牌名 + 当前分组），头像又紧挨着姓名，
       两者都是重复信息；让出来之后顶栏不再拥挤，通知面板也有地方摆 */
    .perf-page-title { display: none; }
    .perf-avatar { display: none; }
    /* 手机端通知面板改为相对视口定位。
       原来挂在铃铛按钮上（right:0），而铃铛右边还并排放着姓名块，
       铃铛被推到 x≈173；面板固定 296px 宽，于是向左溢出屏幕约 61px，
       每条待办的圆点和开头文字都被截掉，elementFromPoint 打在上面也只会
       命中面板后面的卡片标题。改用视口定位后右边与顶栏内边距对齐，
       不再受铃铛在顶栏里的位置影响 */
    .perf-todo-menu {
        position: fixed;
        top: calc(var(--perf-header-h) + 4px);
        right: 12px;
        left: auto;
        max-width: calc(100vw - 24px);
    }
    .perf-topbar { padding: 0 12px; gap: 8px; }
    .perf-content { padding: 14px 12px 8px; }

    /* ---- 2. 表格转卡片 ----
       选择器要同时覆盖 .layui-table-view（table.render 渲染的）和 .layui-table
       （页面里手写的，如考核评分录入表、我的绩效明细表）。两者 DOM 结构还不同：
       前者的表头与表体是两个独立的 <table>，所以表头要单独藏。 */
    .layui-table-view { border: 0; background: transparent; }
    /* 表头在卡片模式下多余（每格自带字段名）；
       .layui-table-fixed 是 fixed 列的副本，留着会和卡片重叠 */
    .layui-table-header,
    .layui-table-tool,
    .layui-table-fixed { display: none !important; }
    .layui-table-box,
    .layui-table-body,
    .layui-table-main { border: 0; overflow: visible !important; height: auto !important; }

    .layui-table-view table,
    .layui-table-view colgroup,
    .layui-table-view col,
    .layui-table,
    .layui-table colgroup,
    .layui-table col {
        display: block;
        width: 100% !important;
        min-width: 0 !important;
        table-layout: auto !important;
        border: 0;
    }
    .layui-table-view thead,
    .layui-table thead { display: none !important; }
    .layui-table-view tbody,
    .layui-table tbody { display: block; }

    /* tr 变成一张卡片，同时作为 flex 容器：
       用 order 把「标题 + 徽标」提到最前一行，明细各占一行，按钮条落到最后。
       如果所有列都一视同仁地排成"字段名：值"，卡片会长得跟调试输出一样、没有层次。 */
    .layui-table-view tbody tr,
    .layui-table tbody tr {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        background: var(--perf-surface);
        border: 1px solid var(--perf-border);
        border-radius: 12px;
        box-shadow: var(--perf-shadow-sm);
        margin-bottom: 12px;
        padding: 2px 0;
    }

    /* 明细行：字段名固定宽度，左边成一列，值从同一处起排。
       注意 flex-wrap 是必须的：本页「评分录入」格里两个输入框是 <td> 的直接子元素，
       td 本身是 flex 容器，不允许换行的话两个框会被 flex-shrink 挤在同一行（各剩 ~99px） */
    .layui-table-view tbody td,
    .layui-table tbody td {
        order: 1;
        flex: 1 1 100%;
        display: flex;
        flex-wrap: wrap;
        align-items: flex-start;
        gap: 10px;
        width: auto !important;
        min-width: 0 !important;
        margin: 0;
        padding: 7px 15px !important;
        border: 0 !important;
        text-align: left !important;
        line-height: 1.55;
        background: transparent !important;
        color: var(--perf-text);
    }
    .layui-table-view tbody td::before,
    .layui-table tbody td::before {
        content: attr(data-label);
        flex: 0 0 72px;
        color: var(--perf-text-3);
        font-size: 12.5px;
        font-weight: 400;
        line-height: 1.55;
    }
    /* 解除裁剪与省略号：窄屏下把"销售员工1"截成"销售…"没有意义 */
    .layui-table-cell {
        height: auto !important;
        min-height: 0 !important;
        padding: 0 !important;
        line-height: 1.55;
        white-space: normal !important;
        text-overflow: clip !important;
        overflow: visible !important;
    }

    /* 卡片标题：不带字段名前缀，字号更大更醒目 */
    .layui-table-view tbody td.perf-col-title,
    .layui-table tbody td.perf-col-title {
        order: -2;
        flex: 1 1 auto;
        align-items: center;
        padding: 13px 15px 4px !important;
        font-size: 15.5px;
        font-weight: 600;
        color: var(--perf-text);
        overflow-wrap: anywhere;
    }
    .layui-table-view tbody td.perf-col-title::before,
    .layui-table tbody td.perf-col-title::before { display: none; }

    /* 状态 / 等级徽标：贴到标题右侧同一行 */
    .layui-table-view tbody td.perf-col-badge,
    .layui-table tbody td.perf-col-badge {
        order: -1;
        flex: 0 0 auto;
        align-items: center;
        margin-left: auto;
        padding: 13px 15px 4px 0 !important;
    }
    .layui-table-view tbody td.perf-col-badge::before,
    .layui-table tbody td.perf-col-badge::before { display: none; }

    /* 主键在手机上没有参考价值，去掉更干净 */
    .layui-table-view tbody td.perf-col-id,
    .layui-table tbody td.perf-col-id { display: none !important; }

    /* 值为空或 "-" 的行在卡片里是纯噪音，直接不显示 */
    .layui-table-view tbody td.perf-col-empty,
    .layui-table tbody td.perf-col-empty { display: none !important; }

    /* 按钮条：独立成一块，按钮加高到手指好按的尺寸 */
    .layui-table-view tbody td.perf-col-ops,
    .layui-table tbody td.perf-col-ops {
        order: 2;
        flex: 1 1 100%;
        display: block;
        margin-top: 4px;
        padding: 11px 15px 13px !important;
        border-top: 1px solid var(--perf-border-soft) !important;
        border-radius: 0 0 11px 11px;
        background: rgba(var(--perf-primary-rgb), .025);
    }
    .layui-table-view tbody td.perf-col-ops::before,
    .layui-table tbody td.perf-col-ops::before { display: none; }
    .layui-table-view tbody td.perf-col-ops .layui-btn,
    .layui-table tbody td.perf-col-ops .layui-btn {
        height: 36px;
        line-height: 36px;
        margin: 0 8px 0 0;
        padding: 0 16px;
        border-radius: 8px;
    }

    /* 自评/评分录入：卡片里横向空间不够，让输入框换行铺满，
       否则会被挤成半个（桌面端保持一行排开） */
    .layui-table-view tbody td .layui-table-cell > div,
    .layui-table tbody td .layui-table-cell > div { flex-wrap: wrap !important; }
    /* 评分录入那组输入框外面包了一层 .perf-score-inputs，
       卡片模式下要让它独占一整行，否则会挤在字段名旁边 */
    .layui-table-view tbody td .perf-score-inputs,
    .layui-table tbody td .perf-score-inputs { flex: 1 1 100%; min-width: 0; }
    /* 自评/评分录入的输入框现在都由外层 .perf-score-inputs（纵向 flex）负责分行，
       这里只需把高度锁死。绝对不要再给这些输入框加 flex:1 1 100% ——
       纵向容器里 flex-basis 会作用到高度，两个框会被压扁成 20px 高。 */
    .layui-table-view tbody td .perf-score-inputs .layui-input,
    .layui-table tbody td .perf-score-inputs .layui-input {
        flex: 0 0 auto !important;
        height: 38px;
    }

    /* 分页不能隐藏，否则数据多的表在手机上翻不了页 */
    .layui-table-page { border: 0; padding: 6px 0 0; text-align: center; }
    .layui-table-page .layui-laypage { display: flex; flex-wrap: wrap; gap: 4px; justify-content: center; width: 100%; }
    .layui-table-page .layui-laypage a,
    .layui-table-page .layui-laypage span,
    .layui-table-page .layui-laypage input,
    .layui-table-page .layui-laypage button { height: 30px; line-height: 30px; padding: 0 10px; margin: 0; }

    /* ---- 3. 弹层 / 工具栏 / 表单 ---- */
    /* layui 的 area 写成内联 px 宽度，只能靠 max-width 收住 */
    .layui-layer { max-width: 94vw !important; }
    .layui-layer-page { width: 94vw !important; top: 5vh !important; }
    .layui-layer-content { max-height: 88vh; overflow-y: auto; }
    .layui-layer-title { padding: 12px 16px; }

    .perf-toolbar { flex-direction: column; align-items: stretch; gap: 8px; }
    /* 工具栏里的说明文字：压缩成一条紧凑提示。不这么处理的话，
       任务页那段流程说明会占掉三四行灰字，把首屏都吃掉 */
    .perf-toolbar > span {
        width: 100%;
        padding: 8px 11px;
        border-radius: 8px;
        background: rgba(var(--perf-primary-rgb), .045);
        font-size: 12px;
        line-height: 1.6;
        color: var(--perf-text-3);
    }
    .perf-toolbar .layui-inline,
    .perf-toolbar .layui-input,
    .perf-toolbar .layui-btn,
    .perf-toolbar .layui-form-select { width: 100% !important; margin-right: 0 !important; }

    /* 考核评分页的保存条：手机端吸底悬浮，滚动时始终可见。
       是否可点由 updateTip() 控制——没填完时按钮置灰并提示还剩几项，
       省得点下去才被拦。上面竖排工具栏的那套规则这里要逐条覆盖回去。 */
    .perf-toolbar.is-bottom {
        position: fixed;
        left: 0; right: 0; bottom: 0;
        z-index: 200;
        margin: 0;
        /* iPhone 底部安全区，避免被 Home Indicator 压住 */
        padding: 10px 14px calc(10px + env(safe-area-inset-bottom, 0px));
        background: rgba(255, 255, 255, .96);
        backdrop-filter: saturate(180%) blur(10px);
        -webkit-backdrop-filter: saturate(180%) blur(10px);
        border-top: 1px solid var(--perf-border);
        box-shadow: 0 -4px 18px rgba(20, 26, 48, .10);
        flex-direction: row !important;
        align-items: center !important;
        gap: 12px;
    }
    .perf-toolbar.is-bottom > span {
        width: auto !important;
        flex: 1;
        min-width: 0;
        padding: 0;
        background: none !important;
    }
    .perf-toolbar.is-bottom .layui-btn { width: auto !important; flex-shrink: 0; margin-right: 0 !important; }
    /* 给吸底条留出空间，别遮住最后一张卡片 */
    .perf-split-main { padding-bottom: 84px; }
    .perf-card.has-sticky-bar { padding-bottom: 100px; }

    /* 表单：label 由左侧移到上方，输入框占满宽度 */
    .layui-form-item { margin-bottom: 14px; }
    .layui-form-label {
        float: none !important;
        display: block;
        width: auto !important;
        text-align: left;
        padding: 0 0 5px;
        line-height: 1.6;
    }
    .layui-input-block,
    .layui-inline { margin-left: 0 !important; width: 100% !important; margin-right: 0 !important; }

    /* ---- 4. 其它 ---- */
    .perf-stat-row { grid-template-columns: 1fr 1fr; gap: 10px; }
    .perf-card { padding: 16px 14px; border-radius: var(--perf-radius-sm); }
    .perf-split { flex-direction: column; }
    /* 选人区限高，否则评分区会被顶到很下面 */
    .perf-split-aside { width: 100%; max-height: 42vh; overflow-y: auto; }
    .perf-split-main { width: 100%; }
    .perf-login-panel { padding: 32px 20px; }
    .perf-footer { text-align: center; }
}

/* 超窄屏（375px 及以下）：统计卡改单列，否则两列会把数字挤到换行 */
@media (max-width: 420px) {
    .perf-stat-row { grid-template-columns: 1fr; }
}
