/* ===========================================================================
 * 组件层 — 按钮 / 表单 / 卡片 / 模态 / Toast / 骨架 / 上传 / 日期时间
 * 依赖 tokens.css，不得出现硬编码色值。
 * =========================================================================== */

/* ===========================================================================
 * 按钮
 * =========================================================================== */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--kk-space-2);
    padding: var(--kk-space-3) var(--kk-space-5);
    border: 1px solid transparent;
    border-radius: var(--kk-radius-md);
    font-size: var(--kk-text-base);
    font-weight: 650;
    line-height: 1.2;
    /* 触摸目标下限 44×44 */
    min-height: 48px;
    box-shadow: var(--kk-control-shadow);
    user-select: none;
    transition: background-color var(--kk-dur-fast) var(--kk-ease),
        border-color var(--kk-dur-fast) var(--kk-ease),
        box-shadow var(--kk-dur-fast) var(--kk-ease),
        opacity var(--kk-dur-fast) var(--kk-ease),
        transform var(--kk-dur-fast) var(--kk-ease);
}

/* 按下用轻微缩放而非位移：位移会推动周围元素，造成视觉抖动 */
.btn:active:not(:disabled) {
    transform: scale(0.985);
    box-shadow: none;
}

.btn:disabled {
    opacity: 0.46;
    box-shadow: none;
}

.btn:focus-visible,
.preset-btn:focus-visible,
.panel-btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--kk-focus-ring);
}

.btn-primary:focus-visible,
.btn-save:focus-visible {
    box-shadow: 0 0 0 3px var(--kk-focus-ring), var(--kk-button-shadow);
}

.btn-danger:focus-visible {
    box-shadow: 0 0 0 3px var(--kk-focus-ring), var(--kk-danger-shadow);
}

.btn-primary {
    background-color: var(--kk-primary);
    color: var(--kk-on-primary);
    box-shadow: var(--kk-button-shadow);
}

.btn-secondary,
.btn-cancel {
    background-color: var(--kk-surface);
    color: var(--kk-text);
    border-color: var(--kk-control-border);
}

.btn-save {
    background-color: var(--kk-primary);
    color: var(--kk-on-primary);
    box-shadow: var(--kk-button-shadow);
}

.btn-danger {
    background-color: var(--kk-danger);
    color: var(--kk-on-danger);
    box-shadow: var(--kk-danger-shadow);
}

/* 轮廓型：用于「现在」这类辅助操作，弱于 secondary */
.btn-outline-secondary {
    background-color: var(--kk-primary-soft);
    color: var(--kk-primary);
    border-color: transparent;
    box-shadow: none;
}

.btn-sm {
    padding: var(--kk-space-2) var(--kk-space-3);
    font-size: var(--kk-text-sm);
    min-height: var(--kk-touch-target);
    border-radius: var(--kk-radius-sm);
}

/* 悬停效果只给真正有指针的设备，避免触摸后「粘住」高亮 */
@media (hover: hover) and (pointer: fine) {
    .btn-primary:hover:not(:disabled),
    .btn-save:hover:not(:disabled) {
        transform: translateY(-1px);
        box-shadow: var(--kk-button-shadow);
    }

    .btn-secondary:hover:not(:disabled),
    .btn-cancel:hover:not(:disabled),
    .btn-outline-secondary:hover:not(:disabled) {
        border-color: var(--kk-primary);
        background-color: var(--kk-control-hover);
        transform: translateY(-1px);
    }

    .btn-danger:hover:not(:disabled) {
        transform: translateY(-1px);
        box-shadow: var(--kk-danger-shadow);
    }
}

/* 加载态：前置转圈，宽度不变以免布局跳动 */
.btn.is-loading {
    opacity: 0.75;
    cursor: progress;
}

.btn.is-loading::before {
    content: '';
    width: 14px;
    height: 14px;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: kk-spin 0.7s linear infinite;
    flex-shrink: 0;
}

/* ===========================================================================
 * 表单
 * =========================================================================== */
.form-group {
    margin-bottom: var(--kk-space-5);
}

.form-group > label,
.user-id-label {
    display: block;
    margin-bottom: var(--kk-space-2);
    font-size: var(--kk-text-sm);
    font-weight: 650;
    color: var(--kk-text);
}

.form-control {
    display: block;
    width: 100%;
    padding: var(--kk-space-3) var(--kk-space-4);
    background-color: var(--kk-control-bg);
    color: var(--kk-text);
    border: 1px solid var(--kk-control-border);
    border-radius: var(--kk-radius-md);
    /* 必须 ≥16px：更小的字号会让 iOS Safari 在聚焦时自动放大整个页面 */
    font-size: var(--kk-text-base);
    font-family: inherit;
    font-weight: 500;
    line-height: 1.4;
    min-height: var(--kk-control-height);
    caret-color: var(--kk-primary);
    box-shadow: var(--kk-control-shadow);
    appearance: none;
    -webkit-appearance: none;
    transition: background-color var(--kk-dur-fast) var(--kk-ease),
        border-color var(--kk-dur-fast) var(--kk-ease),
        box-shadow var(--kk-dur-fast) var(--kk-ease);
}

.form-control::placeholder {
    color: var(--kk-text-subtle);
}

.form-control:focus {
    outline: none;
    border-color: var(--kk-primary);
    background-color: var(--kk-surface);
    box-shadow: 0 0 0 3px var(--kk-focus-ring), var(--kk-control-shadow);
}

@media (hover: hover) and (pointer: fine) {
    .form-control:hover:not(:focus):not(:disabled) {
        border-color: var(--kk-border-strong);
        background-color: var(--kk-control-hover);
    }
}

.form-control:disabled {
    opacity: 0.55;
    cursor: not-allowed;
    box-shadow: none;
}

/* 下拉箭头：默认样式在暗色下是亮色三角，用内联 SVG 换成 currentColor */
select.form-control {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--kk-space-3) center;
    background-size: 18px 18px;
    padding-right: var(--kk-space-8);
}

/* 原生弹层在 Telegram Desktop / WebView 中可能脱离 select 自身的深色表面。
 * 显式给 option 提供语义色，避免浅色弹层上出现浅色文字；选中项仍保留主色层级。 */
select option {
    color: var(--kk-text);
    background-color: var(--kk-surface);
}

select option:checked {
    color: var(--kk-on-primary);
    background-color: var(--kk-primary);
}

input[type='number'].form-control {
    appearance: textfield;
    -moz-appearance: textfield;
}

input[type='number'].form-control::-webkit-inner-spin-button,
input[type='number'].form-control::-webkit-outer-spin-button {
    margin: 0;
    appearance: none;
    -webkit-appearance: none;
}

input[type='date'].form-control,
input[type='time'].form-control {
    color: var(--kk-text);
    /* 部分 Telegram Android WebView 的暗色原生面板会画成黑底黑字。
     * 强制原生选择面板使用浅色方案；输入框本身仍由语义色保持暗色外观。 */
    color-scheme: light;
    color-scheme: only light;
    -webkit-text-fill-color: var(--kk-text);
    font-variant-numeric: tabular-nums;
}

input[type='date'].form-control::-webkit-datetime-edit,
input[type='time'].form-control::-webkit-datetime-edit,
input[type='date'].form-control::-webkit-datetime-edit-fields-wrapper,
input[type='time'].form-control::-webkit-datetime-edit-fields-wrapper,
input[type='date'].form-control::-webkit-datetime-edit-year-field,
input[type='date'].form-control::-webkit-datetime-edit-month-field,
input[type='date'].form-control::-webkit-datetime-edit-day-field,
input[type='time'].form-control::-webkit-datetime-edit-hour-field,
input[type='time'].form-control::-webkit-datetime-edit-minute-field {
    color: var(--kk-text);
    -webkit-text-fill-color: var(--kk-text);
    opacity: 1;
}

input[type='date'].form-control::-webkit-datetime-edit-text,
input[type='time'].form-control::-webkit-datetime-edit-text {
    color: var(--kk-text-muted);
    -webkit-text-fill-color: var(--kk-text-muted);
}

input[type='date'].form-control::-webkit-date-and-time-value,
input[type='time'].form-control::-webkit-date-and-time-value {
    min-height: 1.4em;
    color: var(--kk-text);
    -webkit-text-fill-color: var(--kk-text);
    text-align: left;
}

input[type='date'].form-control::-webkit-calendar-picker-indicator,
input[type='time'].form-control::-webkit-calendar-picker-indicator {
    margin: 0;
    padding: var(--kk-space-2);
    border-radius: var(--kk-radius-sm);
    cursor: pointer;
    filter: var(--kk-picker-indicator-filter);
    opacity: 0.82;
}

input[type='date'].form-control::-webkit-calendar-picker-indicator:hover,
input[type='time'].form-control::-webkit-calendar-picker-indicator:hover {
    background-color: var(--kk-control-hover);
    opacity: 1;
}

.form-hint {
    display: block;
    margin-top: var(--kk-space-2);
    font-size: var(--kk-text-sm);
    color: var(--kk-text-muted);
    line-height: 1.45;
}

/* 警示态提示，如「该用户已是管理员」 */
.form-hint-warn {
    color: var(--kk-warning-fg);
    font-weight: 600;
}

.form-row {
    display: flex;
    gap: var(--kk-space-3);
    flex-wrap: wrap;
}

.form-row > * {
    flex: 1;
    min-width: 160px;
}

.form-section {
    margin-bottom: var(--kk-space-6);
}

/* 表单容器：改造前 .config-form / .add-group-form 完全没有样式定义 */
.config-form,
.add-group-form,
.export-section,
.restore-section,
.upload-section {
    display: block;
}

.form-actions {
    display: flex;
    align-items: center;
    gap: var(--kk-space-2);
    flex-wrap: wrap;
}

.option-panel {
    margin: var(--kk-space-5) 0;
    padding: var(--kk-space-4);
    border: 1px solid var(--kk-border);
    border-radius: var(--kk-radius-lg);
    background: var(--kk-surface-2);
    box-shadow: none;
}

.option-panel-heading {
    display: flex;
    align-items: flex-start;
    gap: var(--kk-space-3);
    margin-bottom: var(--kk-space-4);
}

.option-panel-heading > [data-icon] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    flex: 0 0 36px;
    border-radius: var(--kk-radius-sm);
    color: var(--kk-primary);
    background: var(--kk-primary-soft);
}

.option-panel-heading h4 {
    margin: 0;
    color: var(--kk-text);
    font-size: var(--kk-text-md);
    font-weight: 700;
}

.option-panel-heading p {
    margin-top: var(--kk-space-1);
    color: var(--kk-text-muted);
    font-size: var(--kk-text-sm);
}

.option-panel > .form-group:last-child,
.option-panel > .date-inputs:last-child,
.option-panel > .preset-group:last-child {
    margin-bottom: 0;
}

.progressive-options {
    margin-top: var(--kk-space-5);
    padding: var(--kk-space-4);
    border: 1px solid var(--kk-border);
    border-radius: var(--kk-radius-lg);
    background: var(--kk-surface-2);
    box-shadow: none;
}

.compact-help,
.filter-summary {
    color: var(--kk-text-muted);
    font-size: var(--kk-text-sm);
}

.filter-summary {
    padding: var(--kk-space-3);
    margin: var(--kk-space-4) 0 var(--kk-space-2);
    border: 1px solid var(--kk-border);
    border-radius: var(--kk-radius-md);
    background: var(--kk-primary-soft);
    color: var(--kk-text);
    font-weight: 600;
}

.sticky-primary-action {
    margin-top: var(--kk-space-4);
}

.sticky-primary-action .btn {
    width: 100%;
}

/* ===========================================================================
 * 开关
 * 视觉主体是 .switch 上的 ::before 滑块。改造前 HTML 里还留着一个
 * <span class="slider">（早期实现的残留，且只出现在三个开关中的一个），
 * 既无样式也无作用，已在 index.html 中移除。
 * =========================================================================== */
.switch-label {
    display: flex !important;
    align-items: center;
    gap: var(--kk-space-3);
    cursor: pointer;
    font-weight: 400 !important;
    margin-bottom: 0 !important;
    min-height: 44px;
}

.switch {
    position: relative;
    width: 50px;
    height: 30px;
    flex-shrink: 0;
    appearance: none;
    -webkit-appearance: none;
    background-color: var(--kk-surface-3);
    border: 1px solid var(--kk-control-border);
    border-radius: var(--kk-radius-full);
    cursor: pointer;
    box-shadow: inset 0 1px 2px var(--kk-border);
    transition: background-color var(--kk-dur-base) var(--kk-ease),
        border-color var(--kk-dur-base) var(--kk-ease),
        box-shadow var(--kk-dur-base) var(--kk-ease);
}

.switch:checked {
    background-color: var(--kk-primary);
    border-color: var(--kk-primary);
    box-shadow: inset 0 1px 2px var(--kk-overlay);
}

.switch::before {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 24px;
    height: 24px;
    background-color: var(--kk-control-thumb);
    border-radius: 50%;
    box-shadow: var(--kk-shadow-sm);
    transition: transform var(--kk-dur-base) var(--kk-ease);
}

.switch:checked::before {
    transform: translateX(20px);
}

.switch:active::before {
    transform: scale(0.92);
}

.switch:checked:active::before {
    transform: translateX(20px) scale(0.92);
}

.switch:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--kk-focus-ring);
}

input[type='checkbox']:not(.switch),
input[type='radio'] {
    display: inline-grid;
    place-content: center;
    width: 22px;
    height: 22px;
    flex: 0 0 22px;
    margin: 0;
    appearance: none;
    -webkit-appearance: none;
    background-color: var(--kk-control-bg);
    border: 2px solid var(--kk-control-border);
    box-shadow: var(--kk-control-shadow);
    cursor: pointer;
    transition: background-color var(--kk-dur-fast) var(--kk-ease),
        border-color var(--kk-dur-fast) var(--kk-ease),
        box-shadow var(--kk-dur-fast) var(--kk-ease),
        transform var(--kk-dur-fast) var(--kk-ease);
}

input[type='checkbox']:not(.switch) {
    border-radius: 7px;
}

input[type='checkbox']:not(.switch)::before {
    content: '';
    width: 10px;
    height: 6px;
    border-left: 2px solid var(--kk-control-thumb);
    border-bottom: 2px solid var(--kk-control-thumb);
    opacity: 0;
    transform: translateY(-1px) rotate(-45deg) scale(0.7);
    transition: opacity var(--kk-dur-fast) var(--kk-ease),
        transform var(--kk-dur-fast) var(--kk-ease);
}

input[type='checkbox']:not(.switch):checked {
    background-color: var(--kk-primary);
    border-color: var(--kk-primary);
}

input[type='checkbox']:not(.switch):checked::before {
    opacity: 1;
    transform: translateY(-1px) rotate(-45deg) scale(1);
}

input[type='radio'] {
    border-radius: var(--kk-radius-full);
}

input[type='radio']::before {
    content: '';
    width: 10px;
    height: 10px;
    border-radius: var(--kk-radius-full);
    background: var(--kk-primary);
    transform: scale(0);
    transition: transform var(--kk-dur-fast) var(--kk-ease);
}

input[type='radio']:checked {
    border-color: var(--kk-primary);
    background-color: var(--kk-surface);
}

input[type='radio']:checked::before {
    transform: scale(1);
}

input[type='checkbox']:not(.switch):focus-visible,
input[type='radio']:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--kk-focus-ring);
}

/* ===========================================================================
 * 卡片与区块内的信息行
 * =========================================================================== */
.detail-row {
    display: grid;
    grid-template-columns: minmax(88px, auto) minmax(0, 1fr);
    align-items: baseline;
    gap: var(--kk-space-3);
    padding: var(--kk-space-2) 0;
    border-bottom: 1px solid var(--kk-border);
    font-size: var(--kk-text-sm);
}

.detail-row:last-child {
    border-bottom: none;
}

.detail-label {
    color: var(--kk-text-muted);
    flex-shrink: 0;
}

.detail-value {
    color: var(--kk-text);
    font-weight: 500;
    text-align: right;
    overflow-wrap: anywhere;
    word-break: normal;
}

/* ===========================================================================
 * 徽标
 * =========================================================================== */
.status-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--kk-space-1);
    padding: 2px var(--kk-space-2);
    border-radius: var(--kk-radius-full);
    font-size: var(--kk-text-xs);
    font-weight: 600;
    line-height: 1.6;
}

.status-badge.enabled,
.status-badge.active,
.status-badge.running {
    background-color: var(--kk-success-bg);
    color: var(--kk-success-fg);
}

.status-badge.disabled,
.status-badge.stopped {
    background-color: var(--kk-surface-2);
    color: var(--kk-text-muted);
}

.status-badge.error {
    background-color: var(--kk-danger-bg);
    color: var(--kk-danger-fg);
}

/* ===========================================================================
 * 提示块（alert / info-card / warning）
 * =========================================================================== */
.alert,
.info-card,
.cleanup-warning,
.restore-warning,
.import-warning,
.confirm-warning,
.cleanup-example,
.export-default-hint,
.dashboard-permission-note {
    display: flex;
    align-items: flex-start;
    gap: var(--kk-space-3);
    padding: var(--kk-space-4);
    border: 1px solid var(--kk-border);
    border-radius: var(--kk-radius-lg);
    background-color: var(--kk-surface);
    box-shadow: var(--kk-control-shadow);
    font-size: var(--kk-text-sm);
    line-height: 1.55;
    margin-bottom: var(--kk-space-4);
}

/* 单栏排布的提示块（内部没有图标列） */
.cleanup-example,
.export-default-hint,
.dashboard-permission-note,
.info-card {
    flex-direction: column;
    gap: var(--kk-space-2);
}

.alert-info,
.info-card,
.restore-warning,
.dashboard-permission-note {
    border-color: var(--kk-border);
    background: linear-gradient(135deg, var(--kk-info-bg), var(--kk-surface) 72%);
    box-shadow: inset 3px 0 0 var(--kk-info), var(--kk-control-shadow);
}

.cleanup-warning,
.confirm-warning,
.import-warning {
    border-color: var(--kk-border);
    background: linear-gradient(135deg, var(--kk-danger-bg), var(--kk-surface) 72%);
    box-shadow: inset 3px 0 0 var(--kk-danger), var(--kk-control-shadow);
}

.cleanup-example,
.export-default-hint {
    border-color: var(--kk-border);
    background: linear-gradient(135deg, var(--kk-warning-bg), var(--kk-surface) 72%);
    box-shadow: inset 3px 0 0 var(--kk-warning), var(--kk-control-shadow);
}

.alert.success {
    border-color: var(--kk-border);
    background: linear-gradient(135deg, var(--kk-success-bg), var(--kk-surface) 72%);
    box-shadow: inset 3px 0 0 var(--kk-success), var(--kk-control-shadow);
}

.cleanup-warning > .warning-icon,
.restore-warning > .info-icon,
.import-warning > .warning-icon,
.alert > .info-icon,
.alert > .warning-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex: 0 0 40px;
    border-radius: var(--kk-radius-md);
    background: var(--kk-surface);
    box-shadow: var(--kk-control-shadow);
}

.cleanup-warning > .warning-icon,
.import-warning > .warning-icon {
    color: var(--kk-danger-fg);
}

.restore-warning > .info-icon,
.alert > .info-icon {
    color: var(--kk-info-fg);
}

.alert h4,
.info-card h4,
.cleanup-warning h4,
.restore-warning h4,
.warning-content h4 {
    margin-bottom: var(--kk-space-1);
    font-size: var(--kk-text-sm);
    font-weight: 700;
}

.alert p,
.info-card p,
.warning-content p,
.success-content p,
.info-content p,
.permission-note-text {
    color: var(--kk-text-muted);
    font-size: var(--kk-text-sm);
}

.info-card ul,
.cleanup-example ul {
    font-size: var(--kk-text-sm);
    color: var(--kk-text-muted);
}

.permission-note-header {
    display: flex;
    align-items: center;
    gap: var(--kk-space-2);
}

.permission-note-title {
    font-size: var(--kk-text-sm);
    font-weight: 700;
}

/* 操作成功后的短暂高亮，引导视线到结果区 */
.result-highlight {
    animation: kk-highlight 2.4s var(--kk-ease);
}

@keyframes kk-highlight {
    0% {
        box-shadow: 0 0 0 0 var(--kk-primary-soft);
    }
    30% {
        box-shadow: 0 0 0 4px var(--kk-primary-soft);
    }
    100% {
        box-shadow: 0 0 0 0 transparent;
    }
}

/* ===========================================================================
 * Toast 轻提示
 * 取代原先「保存成功也弹全屏模态框停 3 秒」的打断式反馈。
 * =========================================================================== */
.kk-toast-container {
    position: fixed;
    /* 放底部而非顶部：顶部挤着头部、群组切换器和 7 个 tab 的导航，
     * 提示浮在上面会盖住用户正要点的控件；底部只有页面内容，
     * 而且更靠近拇指，错误提示的关闭按钮更好按。
     * bottom 计入安全区，避开 iPhone 手势条。 */
    bottom: calc(var(--kk-safe-bottom) + var(--kk-space-4));
    left: 50%;
    transform: translateX(-50%);
    z-index: var(--kk-z-toast);
    display: flex;
    /* 容器贴底、向上生长，默认 column 即可让后追加的一条落在最下方——
     * 也就是最靠近底边、最先被看到的位置。用 column-reverse 反而会把
     * 最新一条顶到上面去。 */
    flex-direction: column;
    gap: var(--kk-space-2);
    width: min(560px, calc(100vw - var(--kk-space-8)));
    /* 容器不吃点击，只有 toast 本体可交互 */
    pointer-events: none;
}

.kk-toast {
    display: flex;
    align-items: flex-start;
    gap: var(--kk-space-3);
    padding: var(--kk-space-3) var(--kk-space-4);
    background-color: var(--kk-surface);
    color: var(--kk-text);
    border: 1px solid var(--kk-border);
    border-radius: var(--kk-radius-lg);
    box-shadow: var(--kk-shadow-lg);
    font-size: var(--kk-text-sm);
    line-height: 1.5;
    pointer-events: auto;

    opacity: 0;
    /* 从下方滑入，与容器停靠在底部的方向一致 */
    transform: translateY(10px);
    transition: opacity var(--kk-dur-base) var(--kk-ease),
        transform var(--kk-dur-base) var(--kk-ease);
}

.kk-toast.show {
    opacity: 1;
    transform: translateY(0);
}

.kk-toast-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    border-radius: var(--kk-radius-sm);
    background: var(--kk-surface-2);
}

.kk-toast-text {
    flex: 1;
    min-width: 0;
    /* 后端错误可能是长句，允许换行而非截断 */
    word-break: break-word;
}

.kk-toast-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 44px;
    height: 44px;
    margin: calc(-1 * var(--kk-space-2)) calc(-1 * var(--kk-space-3))
        calc(-1 * var(--kk-space-2)) 0;
    border-radius: var(--kk-radius-sm);
    color: var(--kk-text-subtle);
    transition: background-color var(--kk-dur-fast) var(--kk-ease),
        color var(--kk-dur-fast) var(--kk-ease),
        transform var(--kk-dur-fast) var(--kk-ease);
}

.kk-toast-close:active {
    background-color: var(--kk-overlay);
    color: var(--kk-text);
    transform: scale(0.96);
}

.kk-toast-success {
    box-shadow: inset 3px 0 0 var(--kk-success), var(--kk-shadow-lg);
}

.kk-toast-success .kk-toast-icon {
    color: var(--kk-success);
}

.kk-toast-error {
    box-shadow: inset 3px 0 0 var(--kk-danger), var(--kk-shadow-lg);
}

.kk-toast-error .kk-toast-icon {
    color: var(--kk-danger);
}

.kk-toast-warning {
    box-shadow: inset 3px 0 0 var(--kk-warning), var(--kk-shadow-lg);
}

.kk-toast-warning .kk-toast-icon {
    color: var(--kk-warning);
}

.kk-toast-info {
    box-shadow: inset 3px 0 0 var(--kk-info), var(--kk-shadow-lg);
}

.kk-toast-info .kk-toast-icon {
    color: var(--kk-info);
}

/* ===========================================================================
 * 骨架屏
 * =========================================================================== */
.kk-skeleton-group {
    display: flex;
    flex-direction: column;
    gap: var(--kk-space-3);
}

.kk-skeleton-group-card {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}

.kk-skeleton-group-chip {
    flex-direction: row;
    flex-wrap: wrap;
}

.kk-skeleton,
.kk-loading-value {
    /* 两段式渐变横扫，比纯闪烁更能表达「正在来数据」 */
    background-image: linear-gradient(
        90deg,
        var(--kk-skeleton) 25%,
        var(--kk-skeleton-shine) 37%,
        var(--kk-skeleton) 63%
    );
    background-size: 400% 100%;
    animation: kk-shimmer 1.4s ease-in-out infinite;
    border-radius: var(--kk-radius-sm);
}

@keyframes kk-shimmer {
    0% {
        background-position: 100% 50%;
    }
    100% {
        background-position: 0 50%;
    }
}

/* 降低动效偏好下换成静态灰块，仍能表达占位 */
@media (prefers-reduced-motion: reduce) {
    .kk-skeleton,
    .kk-loading-value {
        animation: none;
        background-image: none;
        background-color: var(--kk-skeleton);
    }
}

.kk-skeleton-row {
    height: 64px;
    border-radius: var(--kk-radius-md);
}

.kk-skeleton-card {
    height: 104px;
    border-radius: var(--kk-radius-lg);
}

.kk-skeleton-line {
    height: 14px;
}

.kk-skeleton-chip {
    width: 56px;
    height: 28px;
    border-radius: var(--kk-radius-full);
}

/* 原地把已有数字变成灰块：不动 textContent，尺寸不变，数据到达时无跳动 */
.kk-loading-value {
    color: transparent !important;
    min-width: 3ch;
    user-select: none;
}

/* ===========================================================================
 * 空态与错误态
 * =========================================================================== */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 260px;
    padding: var(--kk-space-10) var(--kk-space-5);
    text-align: center;
    gap: var(--kk-space-2);
    border: 1px solid var(--kk-border);
    border-radius: var(--kk-radius-lg);
    background: linear-gradient(145deg, var(--kk-surface), var(--kk-surface-2));
}

.empty-state-icon,
.empty-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    color: var(--kk-primary);
    background: var(--kk-primary-soft);
    border-radius: var(--kk-radius-full);
    margin-bottom: var(--kk-space-2);
}

.empty-state h2 {
    font-size: var(--kk-text-lg);
    margin-bottom: var(--kk-space-1);
}

.empty-state p,
.empty-message p {
    color: var(--kk-text-muted);
    font-size: var(--kk-text-sm);
}

.empty-state .btn {
    margin-top: var(--kk-space-5);
}

/* 列表内联空态 */
.empty-message,
.admin-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--kk-space-1);
    padding: var(--kk-space-8) var(--kk-space-4);
    text-align: center;
    color: var(--kk-text-muted);
    font-size: var(--kk-text-sm);
    border: 1px solid var(--kk-border);
    border-radius: var(--kk-radius-lg);
    background: linear-gradient(145deg, var(--kk-surface), var(--kk-surface-2));
    box-shadow: var(--kk-control-shadow);
}

.error-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--kk-space-2);
    padding: var(--kk-space-8) var(--kk-space-4);
    text-align: center;
}

.error-title {
    font-weight: 600;
    color: var(--kk-danger-fg);
}

.error-state .btn {
    margin-top: var(--kk-space-3);
}

/* ===========================================================================
 * 进度条
 * =========================================================================== */
.progress-section {
    margin: var(--kk-space-5) 0;
}

.progress-section h4 {
    margin-bottom: var(--kk-space-3);
}

.progress-bar {
    width: 100%;
    height: 8px;
    background-color: var(--kk-surface-2);
    border-radius: var(--kk-radius-full);
    overflow: hidden;
}

.progress-fill {
    height: 100%;
    width: 0;
    background-color: var(--kk-primary);
    border-radius: var(--kk-radius-full);
    transition: width var(--kk-dur-slow) var(--kk-ease);
}

.progress-info {
    margin-top: var(--kk-space-2);
    font-size: var(--kk-text-sm);
    color: var(--kk-text-muted);
    text-align: center;
}

/* ===========================================================================
 * 文件上传区
 * =========================================================================== */
.upload-area {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--kk-space-2);
    padding: var(--kk-space-8) var(--kk-space-5);
    background: linear-gradient(135deg, var(--kk-primary-soft), var(--kk-surface-2));
    border: 1px dashed var(--kk-border-strong);
    border-radius: var(--kk-radius-xl);
    box-shadow: var(--kk-control-shadow);
    text-align: center;
    cursor: pointer;
    transition: border-color var(--kk-dur-fast) var(--kk-ease),
        background-color var(--kk-dur-fast) var(--kk-ease),
        box-shadow var(--kk-dur-fast) var(--kk-ease),
        transform var(--kk-dur-fast) var(--kk-ease);
}

.upload-area:active {
    transform: scale(0.995);
}

/* 拖拽悬停高亮 */
.upload-area.dragover {
    border-color: var(--kk-primary);
    border-style: solid;
    background-color: var(--kk-primary-soft);
}

.upload-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 68px;
    height: 68px;
    color: var(--kk-primary);
    background: var(--kk-surface);
    border: 1px solid var(--kk-border);
    border-radius: var(--kk-radius-full);
    box-shadow: var(--kk-shadow-sm);
}

.upload-area p {
    font-size: var(--kk-text-base);
    font-weight: 650;
    color: var(--kk-text);
    margin: 0;
}

.upload-hint {
    color: var(--kk-text-muted) !important;
    font-size: var(--kk-text-sm) !important;
    font-weight: 400 !important;
}

.excel-options,
.txt-options,
.restore-options {
    margin-top: var(--kk-space-4);
}

/* ===========================================================================
 * 模态框
 * =========================================================================== */
.modal,
.admin-edit-modal {
    position: fixed;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    padding: var(--kk-space-5);
    padding-top: calc(var(--kk-safe-top) + var(--kk-space-5));
    padding-bottom: calc(var(--kk-safe-bottom) + var(--kk-space-5));
    background-color: var(--kk-scrim);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    z-index: var(--kk-z-modal);
}

/* .modal 由 JS 写 style.display=flex 控制；.admin-edit-modal 用 .active 类 */
.admin-edit-modal.active {
    display: flex;
}

.modal-content,
.admin-edit-modal-content {
    width: 100%;
    max-width: 440px;
    max-height: 100%;
    overflow-y: auto;
    padding: var(--kk-space-6);
    background-color: var(--kk-surface);
    color: var(--kk-text);
    border: 1px solid var(--kk-border);
    border-radius: var(--kk-radius-xl);
    box-shadow: var(--kk-shadow-lg);
    animation: kk-modal-in var(--kk-dur-base) var(--kk-ease);
}

@keyframes kk-modal-in {
    from {
        opacity: 0;
        transform: translateY(8px) scale(0.985);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.large-modal .modal-content,
.large-modal.admin-edit-modal-content {
    max-width: 680px;
}

.modal-content h3,
.modal-content h4,
.admin-edit-modal-content h3 {
    margin-bottom: var(--kk-space-4);
}

.modal-content p {
    color: var(--kk-text-muted);
    font-size: var(--kk-text-sm);
    margin-bottom: var(--kk-space-5);
    word-break: break-word;
}

.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--kk-space-3);
    margin-bottom: var(--kk-space-4);
    padding-bottom: var(--kk-space-3);
    border-bottom: 1px solid var(--kk-border);
}

.modal-body {
    margin-bottom: var(--kk-space-5);
}

.modal-footer,
.modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--kk-space-3);
    margin-top: var(--kk-space-5);
}

.modal-actions .btn,
.modal-footer .btn {
    min-width: 88px;
}

.modal-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: var(--kk-radius-sm);
    color: var(--kk-text-subtle);
    transition: background-color var(--kk-dur-fast) var(--kk-ease),
        color var(--kk-dur-fast) var(--kk-ease),
        transform var(--kk-dur-fast) var(--kk-ease);
}

.modal-close:active {
    background-color: var(--kk-overlay);
    color: var(--kk-text);
    transform: scale(0.96);
}

/* ===========================================================================
 * 群组多选列表（添加管理员 / 分配管辖群组）
 * =========================================================================== */
.chat-checkbox-list {
    display: flex;
    flex-direction: column;
    gap: var(--kk-space-2);
    max-height: 260px;
    overflow-y: auto;
    padding: var(--kk-space-2);
    border: 1px solid var(--kk-border);
    border-radius: var(--kk-radius-lg);
    background: var(--kk-control-bg);
    box-shadow: var(--kk-control-shadow);
}

.chat-checkbox {
    display: flex;
    align-items: center;
    gap: var(--kk-space-3);
    padding: var(--kk-space-2) var(--kk-space-3);
    border: 1px solid transparent;
    border-radius: var(--kk-radius-md);
    cursor: pointer;
    min-height: 44px;
    transition: background-color var(--kk-dur-fast) var(--kk-ease),
        border-color var(--kk-dur-fast) var(--kk-ease),
        transform var(--kk-dur-fast) var(--kk-ease);
}

.chat-checkbox:active {
    background-color: var(--kk-control-hover);
    transform: scale(0.99);
}

@media (hover: hover) and (pointer: fine) {
    .kk-toast-close:hover,
    .modal-close:hover {
        background-color: var(--kk-overlay);
        color: var(--kk-text);
    }

    .upload-area:hover {
        border-color: var(--kk-primary);
        box-shadow: var(--kk-shadow-md);
    }

    .chat-checkbox:hover {
        border-color: var(--kk-control-border);
        background-color: var(--kk-control-hover);
    }
}

.chat-checkbox input[type='checkbox'] {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
}

.chat-checkbox-title {
    font-size: var(--kk-text-sm);
    color: var(--kk-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.chat-checkbox-id {
    font-size: var(--kk-text-xs);
    color: var(--kk-text-subtle);
    margin-left: auto;
    flex-shrink: 0;
}

/* ===========================================================================
 * 预设按钮组（导出日期预设 / 清理方案预设）
 * =========================================================================== */
.preset-group {
    margin-bottom: var(--kk-space-4);
}

.preset-group-title {
    display: block;
    margin-bottom: var(--kk-space-2);
    font-size: var(--kk-text-sm);
    font-weight: 650;
    color: var(--kk-text-muted);
}

.preset-buttons,
.date-presets {
    display: flex;
    flex-wrap: wrap;
    gap: var(--kk-space-2);
}

.preset-btn {
    padding: var(--kk-space-2) var(--kk-space-4);
    background-color: var(--kk-surface);
    color: var(--kk-text);
    border: 1px solid var(--kk-control-border);
    border-radius: var(--kk-radius-md);
    font-size: var(--kk-text-sm);
    font-weight: 650;
    min-height: 46px;
    box-shadow: var(--kk-control-shadow);
    transition: background-color var(--kk-dur-fast) var(--kk-ease),
        border-color var(--kk-dur-fast) var(--kk-ease),
        box-shadow var(--kk-dur-fast) var(--kk-ease),
        transform var(--kk-dur-fast) var(--kk-ease);
}

.preset-btn:active {
    transform: scale(0.985);
}

@media (hover: hover) and (pointer: fine) {
    .preset-btn:hover:not(.active):not(.selected) {
        background-color: var(--kk-control-hover);
        border-color: var(--kk-primary);
        box-shadow: var(--kk-shadow-sm);
        transform: translateY(-1px);
    }
}

.preset-btn.active,
.preset-btn.selected {
    background-color: var(--kk-primary-soft);
    border-color: var(--kk-primary);
    color: var(--kk-primary);
    box-shadow: 0 0 0 1px var(--kk-primary), var(--kk-control-shadow);
}

.preset-btn.preset-primary {
    background-color: var(--kk-primary);
    border-color: var(--kk-primary);
    color: var(--kk-on-primary);
    box-shadow: var(--kk-button-shadow);
}

/* 保守方案：保留最近 N 天 */
.preset-btn.safe {
    background: linear-gradient(135deg, var(--kk-success-bg), var(--kk-surface));
    border-color: var(--kk-border);
    color: var(--kk-success-fg);
    box-shadow: var(--kk-control-shadow);
}

/* 精确删除指定时段，误操作代价更高 */
.preset-btn.warning {
    background: linear-gradient(135deg, var(--kk-warning-bg), var(--kk-surface));
    border-color: var(--kk-border);
    color: var(--kk-warning-fg);
    box-shadow: var(--kk-control-shadow);
}

.preset-btn.preset-clear {
    background: var(--kk-surface-2);
    color: var(--kk-text-muted);
    border-color: transparent;
    box-shadow: none;
}

.preset-btn.safe.active,
.preset-btn.safe.selected {
    background-color: var(--kk-success-bg);
    border-color: var(--kk-success);
    color: var(--kk-success-fg);
    box-shadow: 0 0 0 1px var(--kk-success), var(--kk-control-shadow);
}

.preset-btn.warning.active,
.preset-btn.warning.selected {
    background-color: var(--kk-warning-bg);
    border-color: var(--kk-warning);
    color: var(--kk-warning-fg);
    box-shadow: 0 0 0 1px var(--kk-warning), var(--kk-control-shadow);
}

/* ===========================================================================
 * 日期时间选择组件（导出 / 清理 / 统计共用）
 * =========================================================================== */
.date-range-controls {
    display: flex;
    flex-direction: column;
    gap: var(--kk-space-4);
}

.date-inputs,
.date-time-inputs {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--kk-space-4);
}

.date-input-group,
.datetime-group {
    display: flex;
    flex-direction: column;
    gap: var(--kk-space-2);
}

.date-input-group > label,
.datetime-group > label {
    font-size: var(--kk-text-sm);
    font-weight: 650;
    color: var(--kk-text);
}

.datetime-input-wrapper,
.datetime-inputs {
    display: flex;
    align-items: center;
    min-width: 0;
    gap: var(--kk-space-1);
    padding: var(--kk-space-1);
    background: var(--kk-control-bg);
    border: 1px solid var(--kk-control-border);
    border-radius: var(--kk-radius-md);
    box-shadow: var(--kk-control-shadow);
    transition: border-color var(--kk-dur-fast) var(--kk-ease),
        box-shadow var(--kk-dur-fast) var(--kk-ease),
        background-color var(--kk-dur-fast) var(--kk-ease);
}

.datetime-input-wrapper:focus-within,
.datetime-inputs:focus-within {
    border-color: var(--kk-primary);
    background-color: var(--kk-surface);
    box-shadow: 0 0 0 3px var(--kk-focus-ring);
}

.datetime-input-wrapper .form-control,
.datetime-inputs .form-control {
    min-height: 44px;
    padding: var(--kk-space-2) var(--kk-space-3);
    background: transparent;
    border-color: transparent;
    border-radius: var(--kk-radius-sm);
    box-shadow: none;
}

.datetime-input-wrapper .form-control:focus,
.datetime-inputs .form-control:focus {
    background: var(--kk-control-hover);
    border-color: transparent;
    box-shadow: none;
}

@media (hover: hover) and (pointer: fine) {
    .datetime-input-wrapper .form-control:hover:not(:focus):not(:disabled),
    .datetime-inputs .form-control:hover:not(:focus):not(:disabled) {
        background: var(--kk-control-hover);
        border-color: transparent;
    }
}

/* 时间输入比日期窄，不让它平分宽度 */
.datetime-input-wrapper input[type='time'],
.datetime-inputs input[type='time'] {
    flex: 0 0 110px;
    min-width: 100px;
}

.datetime-input-wrapper input[type='date'],
.datetime-inputs input[type='date'] {
    flex: 1;
    min-width: 130px;
}

.now-btn {
    flex-shrink: 0;
    white-space: nowrap;
    background: var(--kk-primary-soft);
    color: var(--kk-primary);
    border-color: transparent;
    box-shadow: none;
}

/* 输入值刚被预设按钮改写时的短暂高亮 */
.form-control.input-changed {
    border-color: var(--kk-primary);
    box-shadow: 0 0 0 3px var(--kk-focus-ring);
}

/* 提示「可以点应用了」的脉冲 */
.pulse-hint {
    animation: kk-pulse-hint 1s var(--kk-ease) 2;
}

@keyframes kk-pulse-hint {
    0%,
    100% {
        box-shadow: 0 0 0 0 transparent;
    }
    50% {
        box-shadow: 0 0 0 4px var(--kk-primary-soft);
    }
}

/* 手机竖屏与横屏统一使用紧凑日期组合；横屏仍可让开始/结束两组并排。 */
@media (max-width: 767px) {
    .datetime-input-wrapper,
    .datetime-inputs {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 84px auto;
    }

    .datetime-input-wrapper .now-btn {
        grid-column: auto;
        min-width: 48px;
        width: auto;
        padding-inline: var(--kk-space-2);
    }

    .datetime-input-wrapper .form-control,
    .datetime-inputs .form-control {
        padding-inline: var(--kk-space-2);
    }

    .datetime-input-wrapper input[type='date']::-webkit-calendar-picker-indicator,
    .datetime-input-wrapper input[type='time']::-webkit-calendar-picker-indicator,
    .datetime-inputs input[type='date']::-webkit-calendar-picker-indicator,
    .datetime-inputs input[type='time']::-webkit-calendar-picker-indicator {
        width: 18px;
        height: 18px;
        padding: 0;
    }

    .datetime-input-wrapper input[type='date'],
    .datetime-input-wrapper input[type='time'],
    .datetime-inputs input[type='date'],
    .datetime-inputs input[type='time'] {
        width: 100%;
        min-width: 0;
    }
}

@media (max-width: 560px) {
    .form-group {
        margin-bottom: var(--kk-space-4);
    }

    .form-row {
        flex-direction: column;
    }

    .form-row > * {
        width: 100%;
        min-width: 0;
    }

    .option-panel,
    .progressive-options {
        margin-top: var(--kk-space-4);
        margin-bottom: var(--kk-space-4);
        padding: var(--kk-space-3);
    }

    .detail-row {
        grid-template-columns: 76px minmax(0, 1fr);
        align-items: start;
        gap: var(--kk-space-2);
    }

    .detail-value {
        text-align: left;
    }

    .date-inputs,
    .date-time-inputs {
        grid-template-columns: 1fr;
    }

    .modal-actions,
    .modal-footer {
        flex-direction: column-reverse;
    }

    .modal-actions .btn,
    .modal-footer .btn {
        width: 100%;
    }

    .modal,
    .admin-edit-modal {
        align-items: flex-end;
        padding: 0;
        padding-top: calc(var(--kk-safe-top) + var(--kk-space-8));
    }

    .modal-content,
    .admin-edit-modal-content {
        max-width: none;
        max-height: min(88dvh, 760px);
        padding: var(--kk-space-5) var(--kk-space-4);
        padding-bottom: calc(var(--kk-safe-bottom) + var(--kk-space-5));
        border-right: none;
        border-bottom: none;
        border-left: none;
        border-radius: var(--kk-radius-xl) var(--kk-radius-xl) 0 0;
        animation-name: kk-sheet-in;
    }
}

/* 320/360px 级别窄屏容不下日期、时间和“现在”三列，只有这里退回两行；
 * 仍然不隐藏任何功能。 */
@media (max-width: 374px) {
    .datetime-input-wrapper {
        grid-template-columns: minmax(0, 1fr) minmax(78px, 88px);
    }

    .datetime-input-wrapper .now-btn {
        grid-column: 1 / -1;
        width: 100%;
    }

    .datetime-inputs {
        grid-template-columns: minmax(0, 1fr) minmax(78px, 88px);
    }
}

@keyframes kk-sheet-in {
    from {
        opacity: 0;
        transform: translateY(24px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}
