/* ============================================================================
 * JussModal.css — 全局应用 Modal 容器插件样式
 *
 * 独立命名空间 .juss-modal-*，不依赖宿主项目任何全局样式（如 .modal / .btn）。
 * Modal body 内部的子元素 class（如 .form-group / .modal-header）由调用方决定，
 * 本插件不强加 —— 这是"容器 + 内容分离"设计的关键。
 *
 * 主题化：所有可定制项走 CSS 变量（--juss-modal-*）
 * 暗色模式：跟随项目 <html class="dark"> 主动切换（与 _dark_store.html 一致），
 *           不读系统 prefers-color-scheme（项目设计为手动切换）
 * 响应式：< 640px 自动全屏铺满
 *
 * 类结构（必需）：
 *   .juss-modal                — 容器（遮罩 + 居中布局）
 *   .juss-modal-content        — 内容卡片（白底圆角）
 *   .juss-modal-close          — 右上角关闭按钮
 *   .juss-modal-body           — 内容容器（HTMX swap target）
 *
 * 状态类：
 *   .juss-modal-active         — 显示状态（JS 添加/移除）
 *
 * 大小变体（可选）：
 *   .juss-modal-content--wide   — 加宽（适合复杂表单）
 *   .juss-modal-content--narrow — 收窄（适合简短确认 / 信息）
 * ============================================================================ */


/* ============================================
 * §1 主题变量（在 :root 上声明默认值，调用方覆盖即可换肤）
 * ============================================ */
:root {
    --juss-modal-z-index: 1000;
    --juss-modal-overlay-bg: rgba(0, 0, 0, 0.45);
    --juss-modal-overlay-blur: 0;          /* 设 4px 起开启背景模糊，性能要求高的场景设 0 */

    --juss-modal-content-bg: #ffffff;
    --juss-modal-content-color: #262626;
    --juss-modal-content-radius: 12px;
    --juss-modal-content-shadow: 0 20px 48px rgba(0, 0, 0, 0.18),
                                 0 8px 16px rgba(0, 0, 0, 0.06);
    --juss-modal-content-max-width: 820px;
    --juss-modal-content-wide-max-width: 960px;
    --juss-modal-content-narrow-max-width: 440px;     /* confirm/alert 类型用,符合 iOS/Material 心智 */
    --juss-modal-content-max-height: 90vh;

    --juss-modal-padding: 24px;            /* 容器外层 padding（让出 viewport 边缘呼吸感）*/

    --juss-modal-close-size: 36px;
    --juss-modal-close-bg: #ffffff;
    --juss-modal-close-color: #64748b;
    --juss-modal-close-border: 1px solid #e5e7eb;
    --juss-modal-close-radius: 8px;
    --juss-modal-close-hover-bg: #fef2f2;
    --juss-modal-close-hover-color: #dc2626;
    --juss-modal-close-hover-border: #fca5a5;
    --juss-modal-close-shadow: 0 2px 6px rgba(0, 0, 0, 0.08),
                               0 4px 12px rgba(0, 0, 0, 0.04);

    --juss-modal-focus-ring: 0 0 0 2px #3b82f6;

    --juss-modal-transition-duration: 0.2s;
    --juss-modal-transition-easing: ease;
}


/* ============================================
 * §2 容器（遮罩 + 居中）
 * ============================================ */
.juss-modal {
    /* 常驻 DOM，靠 visibility + opacity 控制显隐，入场/出场都有过渡 */
    display: flex;
    position: fixed;
    inset: 0;                              /* 等价 top/left/right/bottom: 0 */
    z-index: var(--juss-modal-z-index);
    align-items: center;
    justify-content: center;
    padding: var(--juss-modal-padding);
    background: rgba(0, 0, 0, 0);          /* 默认透明，active 时变深 */
    visibility: hidden;
    pointer-events: none;
    transition:
        background var(--juss-modal-transition-duration) var(--juss-modal-transition-easing),
        visibility 0s linear var(--juss-modal-transition-duration);
}

.juss-modal-active {
    background: var(--juss-modal-overlay-bg);
    visibility: visible;
    pointer-events: auto;
    transition:
        background var(--juss-modal-transition-duration) var(--juss-modal-transition-easing),
        visibility 0s linear 0s;
}

/* 可选模糊背景（设 --juss-modal-overlay-blur: 4px 启用） */
@supports (backdrop-filter: blur(1px)) {
    .juss-modal-active {
        backdrop-filter: blur(var(--juss-modal-overlay-blur));
    }
}


/* ============================================
 * §3 内容卡片
 * ============================================ */
.juss-modal-content {
    position: relative;                    /* 让 .juss-modal-close 可绝对定位 */
    background: var(--juss-modal-content-bg);
    color: var(--juss-modal-content-color);
    border-radius: var(--juss-modal-content-radius);
    box-shadow: var(--juss-modal-content-shadow);
    width: 100%;
    max-width: var(--juss-modal-content-max-width);
    max-height: var(--juss-modal-content-max-height);
    overflow-y: auto;
    /* ⚠️ 不设 padding：内容由调用方决定，避免双重内边距 */

    /* 默认（出场）：仅缩放 + 渐隐，无位移 → 自然"消失"感
       0.16s ease-in：起始慢、结束快，符合"消失"心理预期 */
    opacity: 0;
    transform: scale(0.94);
    transition:
        opacity 0.16s ease-in,
        transform 0.16s ease-in;
}

.juss-modal-active .juss-modal-content {
    /* 入场状态：放大到 1 + 渐显 → 自然"出现"感
       0.22s cubic-bezier 优雅曲线（Material/Headless UI 业界标准）*/
    opacity: 1;
    transform: scale(1);
    transition:
        opacity 0.22s cubic-bezier(0.16, 1, 0.3, 1),
        transform 0.22s cubic-bezier(0.16, 1, 0.3, 1);
}

/* 大小变体 */
.juss-modal-content--wide {
    max-width: var(--juss-modal-content-wide-max-width);
}
.juss-modal-content--narrow {
    max-width: var(--juss-modal-content-narrow-max-width);
}


/* ============================================
 * §4 关闭按钮
 * ============================================ */
.juss-modal-close {
    position: absolute;
    top: 14px;
    right: 14px;
    z-index: 10;

    width: var(--juss-modal-close-size);
    height: var(--juss-modal-close-size);
    padding: 0;
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    user-select: none;

    background: var(--juss-modal-close-bg);
    color: var(--juss-modal-close-color);
    border: var(--juss-modal-close-border);
    border-radius: var(--juss-modal-close-radius);
    box-shadow: var(--juss-modal-close-shadow);

    display: inline-flex;
    align-items: center;
    justify-content: center;

    transition:
        background 0.18s ease, border-color 0.18s ease,
        color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}

.juss-modal-close:hover {
    background: var(--juss-modal-close-hover-bg);
    border-color: var(--juss-modal-close-hover-border);
    color: var(--juss-modal-close-hover-color);
    transform: scale(1.08);
    box-shadow: 0 4px 10px rgba(220, 38, 38, 0.15),
                0 6px 18px rgba(0, 0, 0, 0.06);
}

.juss-modal-close:active {
    transform: scale(0.96);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.juss-modal-close:focus-visible {
    outline: none;
    box-shadow: var(--juss-modal-focus-ring),
                var(--juss-modal-close-shadow);
}


/* ============================================
 * §5 内容容器
 * ============================================ */
.juss-modal-body {
    /* 调用方完全自由控制：本类不设 padding / margin 也不设 background */
    /* 仅做"加载中"占位防止空时高度塌陷 */
    min-height: 60px;
}

.juss-modal-body:empty::before {
    content: '';
    display: block;
    height: 200px;
}

/* HTMX 加载中半透明遮罩（表单提交时） */
.juss-modal-body.htmx-request {
    position: relative;
}
.juss-modal-body.htmx-request::after {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(255, 255, 255, 0.55);
    pointer-events: none;
    border-radius: inherit;
}


/* ============================================
 * §6 锁滚动（modal 打开时禁止页面背景滚动）
 *  统合工业级最佳实践（v2.0.1 抖动根治）：
 *    - html scrollbar-gutter:stable：永远预留滚动条空间（CSS 现代标准 2022+）
 *      → modal 打开时滚动条消失，预留空间仍在 → 宿主布局零抖动
 *      → 替代旧版 padding-right 补偿（旧版让宿主 max-width 居中容器整体向左挪 8.5px 抖动）
 *    - body position:fixed + width:100%：iOS Safari 友好（overflow:hidden 在 iOS 锁不住）
 *    - body top（由 JS 写 -scrollY）：锁定时不跳到顶部，关闭时还原 scrollY
 *    - body overflow:hidden：保险锁（防部分 iOS 版本 fixed 仍能滑）
 * ============================================ */
html {
    scrollbar-gutter: stable;
}
body.juss-modal-open {
    position: fixed;
    width: 100%;
    overflow: hidden;
}


/* ============================================
 * §7 响应式（移动端）
 * ============================================ */
@media (max-width: 640px) {
    .juss-modal {
        padding: 0;                        /* 全屏铺满 */
    }
    .juss-modal-content,
    .juss-modal-content--wide,
    .juss-modal-content--narrow {
        max-width: 100%;
        /* 100vh 在 iOS Safari 滑动地址栏隐藏时会跳变（vh 是静态视口高度）；
           dvh 是动态视口高度（实时跟随地址栏高度）—— 渐进增强：
           不支持 dvh 的浏览器忽略第二行，仍用第一行的 100vh 兜底。 */
        max-height: 100vh;
        max-height: 100dvh;
        height: 100vh;
        height: 100dvh;
        border-radius: 0;                  /* 移动端去圆角，无缝铺满 */
    }
    .juss-modal-close {
        top: 10px;
        right: 10px;
    }
}


/* ============================================
 * §8 暗色模式（跟随项目 <html class="dark"> 主动切换）
 *  与 _dark_store.html / juss-ui.css 的 .dark 选择器同源,确保 modal 与宿主页面
 *  的浅/深状态始终一致;不再读系统 prefers-color-scheme(项目默认手动切换)。
 * ============================================ */
html.dark {
    --juss-modal-overlay-bg: rgba(0, 0, 0, 0.65);
    --juss-modal-content-bg: #1f2937;
    --juss-modal-content-color: #f3f4f6;
    --juss-modal-content-shadow: 0 20px 48px rgba(0, 0, 0, 0.55),
                                 0 8px 16px rgba(0, 0, 0, 0.3);

    --juss-modal-close-bg: #374151;
    --juss-modal-close-color: #d1d5db;
    --juss-modal-close-border: 1px solid #4b5563;
    --juss-modal-close-hover-bg: #4b1d1d;
    --juss-modal-close-hover-color: #fca5a5;
    --juss-modal-close-hover-border: #b91c1c;
    --juss-modal-close-shadow: 0 2px 6px rgba(0, 0, 0, 0.4),
                               0 4px 12px rgba(0, 0, 0, 0.2);
}
html.dark .juss-modal-body.htmx-request::after {
    background: rgba(0, 0, 0, 0.55);
}


/* ============================================
 * §9 减少动效（无障碍：跟随 prefers-reduced-motion）
 * ============================================ */
@media (prefers-reduced-motion: reduce) {
    .juss-modal,
    .juss-modal-active,
    .juss-modal-content {
        transition: none !important;
    }
    .juss-modal-content {
        transform: none;
    }
    .juss-modal-active .juss-modal-content {
        transform: none;
    }
}


/* ============================================
 * §10 高级 API 预设视觉（v2.0.0 吸收 Jussfirm）
 *  适用于 .confirm() / .alert() / .prompt() 装载到 .juss-modal-body 的预设结构
 *  独立 .juss-modal-preset-* 命名空间，与低级 openHTML 自由内容互不影响
 * ============================================ */

/* preset 自动套 narrow 宽度 —— confirm/alert/prompt 不需要 820px 那么宽,
   :has() 选择器现代浏览器全支持(Chrome 105+/Safari 15.4+/Firefox 121+),
   纯 CSS 联动,零 JS 侵入 */
.juss-modal-content:has(.juss-modal-preset) {
    max-width: var(--juss-modal-content-narrow-max-width);
}

/* partial 主动声明窄宽度:partial 根上加 [data-modal-narrow] → modal-content 自动 narrow(440px)
   适合简单表单(改密 / 单字段编辑),与上方 :has(.juss-modal-preset) 同源
   未声明此属性的 partial 走默认 820px,完全向后兼容 */
.juss-modal-content:has([data-modal-narrow]) {
    max-width: var(--juss-modal-content-narrow-max-width);
}

/* ── 预设主题变量（与 --juss-modal-* 隔离）── */
:root {
    --juss-modal-preset-padding: 28px;
    --juss-modal-preset-text-primary: #0f172a;
    --juss-modal-preset-text-secondary: #64748b;

    --juss-modal-preset-primary: #2563eb;
    --juss-modal-preset-primary-hover: #1d4ed8;
    --juss-modal-preset-primary-shadow: 0 1px 2px rgba(37,99,235,0.16),
                                        0 4px 12px rgba(37,99,235,0.22);
    --juss-modal-preset-primary-shadow-hover: 0 2px 4px rgba(37,99,235,0.24),
                                              0 8px 20px rgba(37,99,235,0.30);

    --juss-modal-preset-danger: #dc2626;
    --juss-modal-preset-danger-hover: #b91c1c;
    --juss-modal-preset-danger-shadow: 0 1px 2px rgba(220,38,38,0.16),
                                       0 4px 12px rgba(220,38,38,0.22);
    --juss-modal-preset-danger-shadow-hover: 0 2px 4px rgba(220,38,38,0.24),
                                             0 8px 20px rgba(220,38,38,0.30);

    --juss-modal-preset-warning: #d97706;
    --juss-modal-preset-warning-bg: #fef3c7;
    --juss-modal-preset-success: #059669;
    --juss-modal-preset-success-bg: #d1fae5;
    --juss-modal-preset-info: #2563eb;
    --juss-modal-preset-info-bg: #dbeafe;
    --juss-modal-preset-question: #6366f1;
    --juss-modal-preset-question-bg: #e0e7ff;
    --juss-modal-preset-danger-bg: #fee2e2;

    --juss-modal-preset-border: #e2e8f0;
    --juss-modal-preset-border-hover: #cbd5e1;
    --juss-modal-preset-cancel-bg: #ffffff;
    --juss-modal-preset-cancel-bg-hover: #f8fafc;
    --juss-modal-preset-cancel-text: #334155;
    --juss-modal-preset-cancel-shadow: 0 1px 2px rgba(15,23,42,0.04);
    --juss-modal-preset-cancel-shadow-hover: 0 2px 6px rgba(15,23,42,0.08);

    --juss-modal-preset-input-bg: #ffffff;
    --juss-modal-preset-input-border: #cbd5e1;
    --juss-modal-preset-input-border-focus: #2563eb;

    --juss-modal-preset-error-color: #b91c1c;
    --juss-modal-preset-error-bg: #fef2f2;
    --juss-modal-preset-error-border: #fecaca;
}

/* ── 预设容器 ── */
.juss-modal-preset {
    padding: var(--juss-modal-preset-padding);
    color: var(--juss-modal-preset-text-primary);
    box-sizing: border-box;
}

/* ── 头部：图标 + 标题 ── */
.juss-modal-preset-header {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    margin-bottom: 14px;
}
.juss-modal-preset-icon {
    flex-shrink: 0;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    margin-top: 1px;
    box-shadow: 0 0 0 1px rgba(15,23,42,0.05) inset,
                0 1px 2px rgba(15,23,42,0.06),
                0 4px 12px -2px rgba(15,23,42,0.05);
}
.juss-modal-preset-icon svg { width: 28px; height: 28px; display: block; }

.juss-modal-preset-icon-warning  { background: var(--juss-modal-preset-warning-bg);  color: var(--juss-modal-preset-warning); }
.juss-modal-preset-icon-danger   { background: var(--juss-modal-preset-danger-bg);   color: var(--juss-modal-preset-danger); }
.juss-modal-preset-icon-info     { background: var(--juss-modal-preset-info-bg);     color: var(--juss-modal-preset-info); }
.juss-modal-preset-icon-success  { background: var(--juss-modal-preset-success-bg);  color: var(--juss-modal-preset-success); }
.juss-modal-preset-icon-question { background: var(--juss-modal-preset-question-bg); color: var(--juss-modal-preset-question); }

.juss-modal-preset-title {
    flex: 1;
    margin: 0;
    padding: 8px 0 0;       /* 视觉对齐到图标中线 */
    font-size: 17px;
    font-weight: 600;
    line-height: 1.45;
    letter-spacing: -0.01em;
    word-break: break-word;
}

/* ── 正文：消息 + 输入框 ── */
.juss-modal-preset-body {
    padding-left: 58px;     /* 缩进对齐到标题（图标 44 + gap 14 = 58） */
    margin-bottom: 22px;
}

.juss-modal-preset-message {
    font-size: 14px;
    color: var(--juss-modal-preset-text-secondary);
    line-height: 1.65;
    word-break: break-word;
    white-space: pre-wrap;
}

.juss-modal-preset-input-wrap { margin-top: 16px; }
.juss-modal-preset-input {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 13px;
    font-size: 14px;
    line-height: 1.5;
    color: var(--juss-modal-preset-text-primary);
    background: var(--juss-modal-preset-input-bg);
    border: 1px solid var(--juss-modal-preset-input-border);
    border-radius: 8px;
    outline: none;
    box-shadow: 0 1px 2px rgba(15,23,42,0.04) inset;
    font-family: inherit;
    transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
textarea.juss-modal-preset-input { min-height: 88px; resize: vertical; }
.juss-modal-preset-input::placeholder { color: #94a3b8; }
.juss-modal-preset-input:hover { border-color: var(--juss-modal-preset-border-hover); }
.juss-modal-preset-input:focus {
    border-color: var(--juss-modal-preset-input-border-focus);
    box-shadow: 0 0 0 3px rgba(37,99,235,0.12),
                0 1px 2px rgba(15,23,42,0.04) inset;
}

.juss-modal-preset-error {
    margin-top: 8px;
    padding: 7px 11px;
    font-size: 13px;
    color: var(--juss-modal-preset-error-color);
    background: var(--juss-modal-preset-error-bg);
    border: 1px solid var(--juss-modal-preset-error-border);
    border-radius: 6px;
    line-height: 1.45;
}

/* ── 底部按钮 ── */
.juss-modal-preset-footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}
.juss-modal-preset-btn {
    min-width: 84px;
    padding: 10px 20px;
    font-size: 14px;
    font-weight: 500;
    line-height: 1.4;
    border-radius: 8px;
    border: 1px solid transparent;
    cursor: pointer;
    user-select: none;
    font-family: inherit;
    -webkit-appearance: none;
    appearance: none;
    outline: none;
    letter-spacing: 0.01em;
    transition: background-color 0.18s ease, border-color 0.18s ease,
                color 0.18s ease, transform 0.12s ease, box-shadow 0.18s ease;
}
.juss-modal-preset-btn:focus-visible { box-shadow: 0 0 0 3px rgba(37,99,235,0.32); }
.juss-modal-preset-btn:active { transform: translateY(0); transition-duration: 0.06s; }

.juss-modal-preset-btn-cancel {
    background: var(--juss-modal-preset-cancel-bg);
    border-color: var(--juss-modal-preset-border);
    color: var(--juss-modal-preset-cancel-text);
    box-shadow: var(--juss-modal-preset-cancel-shadow);
}
.juss-modal-preset-btn-cancel:hover {
    background: var(--juss-modal-preset-cancel-bg-hover);
    border-color: var(--juss-modal-preset-border-hover);
    transform: translateY(-1px);
    box-shadow: var(--juss-modal-preset-cancel-shadow-hover);
}
.juss-modal-preset-btn-cancel:active { background: #f1f5f9; }

.juss-modal-preset-btn-confirm {
    background: var(--juss-modal-preset-primary);
    color: #ffffff;
    border-color: var(--juss-modal-preset-primary);
    box-shadow: var(--juss-modal-preset-primary-shadow);
}
.juss-modal-preset-btn-confirm:hover {
    background: var(--juss-modal-preset-primary-hover);
    border-color: var(--juss-modal-preset-primary-hover);
    transform: translateY(-1px);
    box-shadow: var(--juss-modal-preset-primary-shadow-hover);
}
.juss-modal-preset-btn-confirm:active {
    transform: translateY(0);
    box-shadow: var(--juss-modal-preset-primary-shadow);
}

/* type:'danger' 时确认按钮变红（JS 加 .juss-modal-preset-btn-danger 类）*/
.juss-modal-preset-btn-confirm.juss-modal-preset-btn-danger {
    background: var(--juss-modal-preset-danger);
    border-color: var(--juss-modal-preset-danger);
    box-shadow: var(--juss-modal-preset-danger-shadow);
}
.juss-modal-preset-btn-confirm.juss-modal-preset-btn-danger:hover {
    background: var(--juss-modal-preset-danger-hover);
    border-color: var(--juss-modal-preset-danger-hover);
    box-shadow: var(--juss-modal-preset-danger-shadow-hover);
}
.juss-modal-preset-btn-confirm.juss-modal-preset-btn-danger:focus-visible {
    box-shadow: 0 0 0 3px rgba(220,38,38,0.32);
}

/* ── 校验失败抖动（prompt 模式校验不通过时）── */
@keyframes juss-modal-preset-shake {
    0%,100% { transform: translateX(0); }
    15%     { transform: translateX(-7px); }
    30%     { transform: translateX(7px); }
    45%     { transform: translateX(-5px); }
    60%     { transform: translateX(5px); }
    75%     { transform: translateX(-3px); }
}
.juss-modal-preset-shake { animation: juss-modal-preset-shake 0.42s ease; }

/* ── 移动端：按钮全宽叠垒 ── */
@media (max-width: 480px) {
    .juss-modal-preset { padding: 22px; }
    .juss-modal-preset-body { padding-left: 0; }
    .juss-modal-preset-header { gap: 12px; }
    .juss-modal-preset-footer { flex-direction: column-reverse; gap: 8px; }
    .juss-modal-preset-btn { width: 100%; }
}

/* ── 减少动效（无障碍）── */
@media (prefers-reduced-motion: reduce) {
    .juss-modal-preset-btn { transition: none !important; }
    .juss-modal-preset-shake { animation: none !important; }
}

/* ── 暗色模式（跟随项目 <html class="dark">,与 §8 同源）── */
html.dark {
    --juss-modal-preset-text-primary: #f1f5f9;
    --juss-modal-preset-text-secondary: #94a3b8;
    --juss-modal-preset-border: #334155;
    --juss-modal-preset-border-hover: #475569;
    --juss-modal-preset-cancel-bg: #1e293b;
    --juss-modal-preset-cancel-bg-hover: #334155;
    --juss-modal-preset-cancel-text: #e2e8f0;
    --juss-modal-preset-cancel-shadow: 0 1px 2px rgba(0,0,0,0.2);
    --juss-modal-preset-cancel-shadow-hover: 0 2px 6px rgba(0,0,0,0.3);
    --juss-modal-preset-input-bg: #0f172a;
    --juss-modal-preset-input-border: #334155;
    --juss-modal-preset-error-bg: rgba(220,38,38,0.12);
    --juss-modal-preset-error-border: rgba(220,38,38,0.3);
    --juss-modal-preset-warning-bg:  rgba(217,119,6,0.18);
    --juss-modal-preset-danger-bg:   rgba(220,38,38,0.18);
    --juss-modal-preset-info-bg:     rgba(37,99,235,0.18);
    --juss-modal-preset-success-bg:  rgba(5,150,105,0.18);
    --juss-modal-preset-question-bg: rgba(99,102,241,0.18);
}
/* cancel 按钮按下瞬间的色:深色模式下用更深的 cancel-bg 替代浅色硬编码 #f1f5f9
   ([:active 状态短暂,差值大反而会"闪")*/
html.dark .juss-modal-preset-btn-cancel:active { background: var(--juss-modal-preset-cancel-bg-hover); }
