/**
 * 全站统一公共样式（原生 CSS 部分）
 * 所有页面通过 <link rel="stylesheet" href="/css/shared.css"> 引入
 *
 * Tailwind 组件/工具类（.btn-*、.glass、.icon-*、.scrollbar-thin、.tab-btn 等）
 * 通过 Standalone CLI 从 frontend/css/tailwind.input.css 预编译到 frontend/css/tailwind.min.css。
 * 原 <style type="text/tailwindcss"> 运行时注入方式已废弃（见 tailwind.config.js）。
 */

/* ==========================================
   Animations
   ========================================== */
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes toastSlideIn { from { opacity: 0; transform: translateX(100%) scale(0.95); } to { opacity: 1; transform: translateX(0) scale(1); } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes modalIn { from { opacity: 0; transform: scale(0.95) translateY(8px); } to { opacity: 1; transform: scale(1) translateY(0); } }
@keyframes pulse-ring { 0% { box-shadow: 0 0 0 0 rgba(16,185,129,0.3); } 70% { box-shadow: 0 0 0 8px rgba(16,185,129,0); } 100% { box-shadow: 0 0 0 0 rgba(16,185,129,0); } }
@keyframes progress-stripe { 0% { background-position: 1rem 0; } 100% { background-position: 0 0; } }
@keyframes brandPulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(16,185,129,0.3); } 50% { box-shadow: 0 0 16px 4px rgba(16,185,129,0.15); } }

/* ==========================================
   Loading Spinner
   ========================================== */
.loading-spinner {
    width: 36px; height: 36px;
    border: 3px solid rgba(255,255,255,0.1); border-top-color: #10b981;
    border-radius: 50%; animation: spin 0.8s linear infinite;
}

/* ==========================================
   Toast Notifications
   ========================================== */
.toast {
    display: flex; align-items: center; gap: 10px;
    padding: 12px 16px; border-radius: 10px;
    font-size: 13px; font-weight: 500;
    box-shadow: 0 8px 24px rgba(0,0,0,0.12);
    animation: toastSlideIn 0.3s cubic-bezier(0.21,1.02,0.73,1);
    max-width: 340px; transition: all 0.3s ease;
    border: 1px solid transparent;
}
.toast.success, .toast-success { background: rgba(16,185,129,0.15); color: #6ee7b7; border-color: rgba(16,185,129,0.25); backdrop-filter: blur(12px); }
.toast.error, .toast-error { background: rgba(239,68,68,0.15); color: #fca5a5; border-color: rgba(239,68,68,0.25); backdrop-filter: blur(12px); }
.toast.warning, .toast-warning { background: rgba(245,158,11,0.15); color: #fcd34d; border-color: rgba(245,158,11,0.25); backdrop-filter: blur(12px); }
.toast.info, .toast-info { background: rgba(59,130,246,0.15); color: #93c5fd; border-color: rgba(59,130,246,0.25); backdrop-filter: blur(12px); }
.toast.fade-out { opacity: 0; transform: translateX(40px); }
.toast-close { cursor: pointer; opacity: 0.5; transition: opacity 0.2s; margin-left: auto; padding: 2px; }
.toast-close:hover { opacity: 1; }
.toast-action-btn {
    flex-shrink: 0; padding: 4px 10px;
    border-radius: 6px; font-size: 12px; font-weight: 600;
    border: 1px solid currentColor;
    background: transparent; color: inherit; cursor: pointer;
    transition: background 0.15s;
}
.toast-action-btn:hover { background: rgba(255,255,255,0.1); }

/* ==========================================
   Modal Animation
   ========================================== */
.modal-backdrop { animation: fadeIn 0.2s ease; }
.modal-content { animation: modalIn 0.3s cubic-bezier(0.21,1.02,0.73,1); }

/* ==========================================
   Switch / Toggle
   ========================================== */
.switch { position: relative; display: inline-block; width: 44px; height: 24px; }
.switch input { opacity: 0; width: 0; height: 0; }
.slider { position: absolute; cursor: pointer; inset: 0; background-color: rgba(255,255,255,0.15); transition: .3s; border-radius: 24px; }
.slider:before { position: absolute; content: ""; height: 18px; width: 18px; left: 3px; bottom: 3px; background-color: white; transition: .3s; border-radius: 50%; }
input:checked + .slider { background-color: #10b981; }
input:checked + .slider:before { transform: translateX(20px); }

/* ==========================================
   Progress Bar
   ========================================== */
.bar-fill {
    height: 100%;
    background: linear-gradient(90deg, #10b981, #34d399);
    border-radius: 999px; transition: width 0.5s ease;
    background-size: 1rem 1rem;
    background-image: linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);
    animation: progress-stripe 0.5s linear infinite;
}

/* ==========================================
   Global Focus Ring + Contrast Enhancements
   ========================================== */
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):focus-visible,
textarea:focus-visible,
select:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px rgba(16,185,129,0.25);
    border-color: rgba(16,185,129,0.4);
}

/* Placeholder 对比度增强 */
::placeholder { color: #6b7280 !important; opacity: 1 !important; }

/* Disabled 态统一处理 */
input:disabled, textarea:disabled, select:disabled, button:disabled {
    cursor: not-allowed;
}

/* Scrollbar (non-Tailwind fallback) */
.scrollbar-thin-css { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,0.08) transparent; }
.scrollbar-thin-css::-webkit-scrollbar { width: 6px; height: 6px; }
.scrollbar-thin-css::-webkit-scrollbar-track { background: transparent; margin: 4px 0; }
.scrollbar-thin-css::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 9999px; border: 1px solid transparent; background-clip: content-box; }
.scrollbar-thin-css::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.18); border-radius: 9999px; border: 1px solid transparent; background-clip: content-box; }
.scrollbar-thin-css:hover::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 9999px; border: 1px solid transparent; background-clip: content-box; }
.scrollbar-thin-css::-webkit-scrollbar-corner { background: transparent; }

/* ==========================================
   Native Select Fallback (hidden by custom-select.js)
   ========================================== */
select {
    background-color: rgba(255,255,255,0.06) !important;
    color: #d1d5db !important;
    border-color: rgba(255,255,255,0.1) !important;
}
select option { background: #1e293b; color: #d1d5db; }

/* ==========================================
   Custom Select Component (.cs-*)
   ========================================== */
.cs-wrap { position: relative; display: inline-block; }
.cs-trigger {
    display: flex; align-items: center; gap: 6px;
    padding: 6px 10px;
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 0.5rem;
    background: rgba(255,255,255,0.05);
    color: #d1d5db; font-size: 0.75rem;
    cursor: pointer; outline: none;
    transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
    white-space: nowrap;
    user-select: none;
}
.cs-wrap.cs-lg .cs-trigger { padding: 10px 12px; font-size: 0.875rem; }
.cs-trigger:hover { border-color: rgba(255,255,255,0.18); background: rgba(255,255,255,0.08); }
.cs-wrap.cs-open .cs-trigger,
.cs-trigger:focus-visible {
    border-color: rgba(16,185,129,0.5);
    box-shadow: 0 0 0 2px rgba(16,185,129,0.15);
}
.cs-arrow { flex-shrink: 0; opacity: 0.45; transition: transform 0.2s; }
.cs-wrap.cs-open .cs-arrow { transform: rotate(180deg); }
.cs-dropdown {
    position: absolute; left: 0; top: 0;
    min-width: 100%; width: max-content;
    background: rgba(30,41,59,0.98);
    backdrop-filter: blur(16px);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 0.75rem;
    padding: 4px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.5);
    z-index: 9999;
    display: none;
    animation: csDropIn 0.15s ease-out;
}
.cs-dropdown.cs-visible { display: block; }
.cs-option {
    padding: 6px 10px;
    border-radius: 0.5rem;
    font-size: 0.75rem;
    color: #d1d5db;
    cursor: pointer;
    transition: background 0.1s, color 0.1s;
    white-space: nowrap;
}
.cs-wrap.cs-lg .cs-option { padding: 8px 12px; font-size: 0.875rem; }
.cs-option:hover { background: rgba(255,255,255,0.08); }
.cs-option.cs-active { color: #10b981; background: rgba(16,185,129,0.1); }

/* 表单行：标题左 30% / 下拉右 70%，副标题与主标题上下排列 */
.select-row { display: flex; align-items: center; gap: 0.75rem; }
.select-row > .label-col { width: 30%; flex-shrink: 0; display: flex; flex-direction: column; gap: 2px; }
.select-row > .field-col { width: 70%; min-width: 0; }
.select-row > .field-col .cs-wrap { display: block; width: 100%; }
.select-row > .field-col .cs-trigger { width: 100%; justify-content: space-between; }

/* 通用工具类：任意容器加 .cs-full 即可让 custom-select 擑满宽度 + label 左 / 箭头右两端对齐 */
.cs-full > .cs-wrap { display: block; width: 100%; }
.cs-full .cs-trigger { width: 100%; justify-content: space-between; }
@keyframes csDropIn {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ==========================================
   Date Input Dark Style (fallback for non-enhanced)
   ========================================== */
input[type="date"],
input[type="datetime-local"] {
    color-scheme: dark;
    background-color: rgba(255,255,255,0.06) !important;
    color: #d1d5db !important;
    border-color: rgba(255,255,255,0.1) !important;
}
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator {
    filter: invert(0.7);
    cursor: pointer;
    opacity: 0.6;
    transition: opacity 0.2s;
}
input[type="date"]::-webkit-calendar-picker-indicator:hover,
input[type="datetime-local"]::-webkit-calendar-picker-indicator:hover {
    opacity: 1;
}

/* ==========================================
   Custom Date Picker Component (.cdp-*)
   ========================================== */
.cdp-wrap { position: relative; display: inline-block; }
.cdp-trigger {
    display: flex; align-items: center; gap: 6px;
    padding: 6px 10px;
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 0.5rem;
    background: rgba(255,255,255,0.05);
    color: #d1d5db; font-size: 0.75rem;
    cursor: pointer; outline: none;
    transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
    white-space: nowrap; user-select: none;
    min-width: 110px;
}
.cdp-trigger:hover { border-color: rgba(255,255,255,0.18); background: rgba(255,255,255,0.08); }
.cdp-wrap.cdp-open .cdp-trigger {
    border-color: rgba(16,185,129,0.5);
    box-shadow: 0 0 0 2px rgba(16,185,129,0.15);
}
.cdp-trigger .cdp-icon { flex-shrink: 0; opacity: 0.45; }
.cdp-trigger .cdp-text { flex: 1; }
.cdp-trigger .cdp-clear {
    flex-shrink: 0; opacity: 0; width: 14px; height: 14px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%; transition: opacity 0.15s, background 0.15s;
}
.cdp-trigger:hover .cdp-clear.cdp-has-val { opacity: 0.5; }
.cdp-trigger .cdp-clear.cdp-has-val:hover { opacity: 1; background: rgba(255,255,255,0.1); }

/* Calendar popup (portal to body) */
.cdp-popup {
    position: absolute;
    background: rgba(30,41,59,0.98);
    backdrop-filter: blur(16px);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 0.75rem;
    padding: 12px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.5);
    z-index: 9999;
    display: none;
    animation: csDropIn 0.15s ease-out;
    width: 260px;
}
.cdp-popup.cdp-visible { display: block; }

/* Header: prev / title / next */
.cdp-header {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 8px;
}
.cdp-header button {
    width: 28px; height: 28px;
    display: flex; align-items: center; justify-content: center;
    border-radius: 0.375rem; border: none; background: none;
    color: #9ca3af; cursor: pointer; transition: background 0.1s, color 0.1s;
}
.cdp-header button:hover { background: rgba(255,255,255,0.08); color: #e5e7eb; }
.cdp-title { font-size: 0.8rem; font-weight: 600; color: #e5e7eb; }

/* Weekday labels */
.cdp-weekdays {
    display: grid; grid-template-columns: repeat(7, 1fr);
    margin-bottom: 4px;
}
.cdp-weekdays span {
    text-align: center; font-size: 0.65rem; font-weight: 500;
    color: #6b7280; padding: 2px 0;
}

/* Day grid */
.cdp-days { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.cdp-day {
    text-align: center; font-size: 0.75rem; padding: 5px 0;
    border-radius: 0.375rem; cursor: pointer;
    color: #d1d5db; transition: background 0.1s, color 0.1s;
    line-height: 1.3;
}
.cdp-day:hover { background: rgba(255,255,255,0.08); }
.cdp-day.cdp-other { color: #4b5563; }
.cdp-day.cdp-today { color: #10b981; font-weight: 600; }
.cdp-day.cdp-selected { background: rgba(16,185,129,0.2); color: #10b981; font-weight: 600; }

/* Footer: today shortcut */
.cdp-footer {
    margin-top: 8px; padding-top: 8px;
    border-top: 1px solid rgba(255,255,255,0.06);
    display: flex; justify-content: center;
}
.cdp-footer button {
    font-size: 0.7rem; color: #10b981; background: none; border: none;
    cursor: pointer; padding: 3px 10px; border-radius: 0.375rem;
    transition: background 0.1s;
}
.cdp-footer button:hover { background: rgba(16,185,129,0.1); }

/* ==========================================
   JSON View (executions page)
   ========================================== */
pre.json-view { white-space: pre-wrap; word-break: break-all; max-height: 400px; overflow-y: auto; }
pre.json-view::-webkit-scrollbar { width: 6px; height: 6px; }
pre.json-view::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 9999px; }
pre.json-view::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.18); }
pre.json-view::-webkit-scrollbar-track { background: transparent; }

/* ==========================================
   Fade In (login etc.)
   ========================================== */
.fade-in { animation: fadeIn 0.4s ease; }

/* ==========================================
   Batch Image Upload (BUG-005)
   ========================================== */
.batch-img-upload { margin: 8px 0; padding: 8px; border: 1px dashed #d1d5db; border-radius: 6px; }
.batch-img-label { cursor: pointer; font-size: 0.85rem; color: #6b7280; display: inline-flex; align-items: center; gap: 4px; }
.batch-img-input { display: none; }
.batch-img-preview { display: flex; gap: 8px; margin-top: 6px; }
.batch-img-preview img { width: 60px; height: 60px; object-fit: cover; border-radius: 4px; }

/* ==========================================
   Config Select (从 index.html 内联 迁入，Task 2 B3)
   用于所有需要自定义下拉箭头的 <select> 或 .config-select 元素
   ========================================== */
.config-select {
    appearance: none; -webkit-appearance: none;
    background-color: rgba(255,255,255,0.04);
    color: #d1d5db;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%236b7280' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 32px;
}

/* ==========================================
 * W022 Workspace 两态切换
 * 配置态 / 运行态两态切换，不删 DOM 只隐藏。
 * 用 !important 压制外部 inline display 冲突（内联 style="display:none" 不会被覆盖 data-stage 切换）。
 * [Bug #2 Fix 2026-05-12] data-stage 从 main 上提到 body：.mode-pill 被 layout.js 搬到 header（<main> 外），必须用 body 选择器才能穿透整页命中。
 * 后人维护请勿当作 hack 删掉——这是态切换的唯一段落执行点。
 * ========================================== */
body[data-stage="config"] [data-stage-running] { display: none !important; }
body[data-stage="running"] [data-stage-config] { display: none !important; }

/* 运行态下 mode-pill disable（Q5）：不隐藏以保留语义结构 + 键盘焦点映射 */
body[data-stage="running"] .mode-pill { pointer-events: none; opacity: 0.5; }

/* 配置态多列布局（2026-05-12 改版：原 2 列网格 → 4 列 flex；模板/模块单独成列）
 * 设计约束：
 *   - 空间占满（去掉 max-width 1000px 死限）
 *   - 每列独立滚（flex 列 min-height:0 + 内部 overflow-y:auto），避免"列表撑高 → 整页滚"的老路
 *   - 4 列：素材 / 风格 / 模板 / 模块；tab=custom 时 .config-col-templates 整列 display:none，flex 自动均分剩余 3 列
 *   - 响应式：≥1280 四列；960-1279 两行两列；<960 一列纵向堆叠（整页滚回来）
 */
.config-grid {
    display: flex;
    flex-wrap: nowrap;
    gap: 1rem;
    padding: 1rem 1.25rem;
    width: 100%;
    min-width: 0;
    overflow: hidden; /* 每列内部自滚，外层不滚 */
}
.config-col {
    flex: 1 1 0;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    background: rgba(255,255,255,0.04);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid rgba(255,255,255,0.06);
    border-radius: 12px;
    overflow-y: auto; /* 每列独立滚动 */
    overflow-x: hidden;
    scrollbar-gutter: stable;
}
/* 中屏两行两列 */
@media (max-width: 1279px) {
    .config-grid { flex-wrap: wrap; }
    .config-col { flex: 1 1 calc(50% - 0.5rem); min-height: 300px; }
}
/* 小屏一列纵向（回到整页滚） */
@media (max-width: 767px) {
    .config-grid { flex-direction: column; overflow: auto; }
    .config-col { flex: 1 1 auto; overflow: visible; min-height: 0; }
}
/* 旧类保留以防遗留引用（两列时代兼容） */
.config-col-left,
.config-col-right {
    display: flex;
    flex-direction: column;
    min-width: 0;
    background: rgba(255,255,255,0.04);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid rgba(255,255,255,0.06);
    border-radius: 12px;
    overflow: hidden;
}

/* 常驻底栏视觉分隔（CD #4） */
.app-bottombar {
    position: sticky;
    bottom: 0;
    z-index: 50;
    border-top: 1px solid rgba(255,255,255,0.06);
    background: rgba(17,24,39,0.80);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}
