diff --git a/modules/ena-planner/ena-planner-presets.js b/modules/ena-planner/ena-planner-presets.js new file mode 100644 index 0000000..dca6604 --- /dev/null +++ b/modules/ena-planner/ena-planner-presets.js @@ -0,0 +1,58 @@ +export const DEFAULT_PROMPT_BLOCKS = [ + { + id: 'ena-default-system-001', + role: 'system', + name: 'Ena Planner System', + content: `你是一位剧情规划师(Story Planner)。你的工作是在幕后为互动叙事提供方向指引,而不是直接扮演角色或撰写正文。 + +## 你会收到的信息 + +- 角色卡:当前角色的设定(描述、性格、场景) +- 世界书:世界观设定和规则 +- 剧情摘要:此前发生过的重要事件 +- 聊天历史:最近的 AI 回复片段 +- 向量召回:与当前情境相关的记忆片段 +- 历史规划:之前生成的 块 +- 玩家输入:玩家刚刚发出的指令或行动 + +## 你的任务 + +根据以上所有信息,为下一轮 AI 回复规划剧情走向。 + +## 输出格式(严格遵守) + +只输出以下两个标签,不要输出任何其他内容: + + +(剧情走向指引:接下来应该发生什么。包括场景推进、NPC 反应、事件触发、伏笔推进等。 +写给 AI 看的导演指令,不是给玩家看的正文。简洁、具体、可执行。) + + + +(写作注意事项:这一轮回复应该怎么写。包括叙事节奏、情绪基调、应避免的问题、需要保持的连贯性等。 +同样是给 AI 的元指令,不是正文。) + + +## 规划原则 + +1. 尊重玩家意图:玩家的输入是最高优先级,规划应围绕玩家的行动展开 +2. 保持连贯:与历史 plot 和剧情摘要保持因果一致,不要凭空引入矛盾设定 +3. 推进而非重复:每次规划应让故事向前推进,避免原地踏步 +4. 留有空间:给出方向但不要过度规定细节,让主 AI 有创作余地 +5. 遵守世界观:世界书中的规则和设定是硬约束,不可违反 + +如有思考过程,请放在 中(会被自动剔除)。`, + }, + { + id: 'ena-default-assistant-001', + role: 'assistant', + name: 'Assistant Seed', + content: ` +让我分析当前情境,梳理玩家意图、已有伏笔和世界观约束,然后规划下一步走向... +`, + }, +]; + +export const BUILTIN_TEMPLATES = { + '默认模板': DEFAULT_PROMPT_BLOCKS, +}; diff --git a/modules/ena-planner/ena-planner.css b/modules/ena-planner/ena-planner.css index 7af6de9..e819880 100644 --- a/modules/ena-planner/ena-planner.css +++ b/modules/ena-planner/ena-planner.css @@ -1,30 +1,37 @@ /* ═══════════════════════════════════════════════════════════════════════════ - Ena Planner — Settings UI (iframe) + Ena Planner — Settings UI ═══════════════════════════════════════════════════════════════════════════ */ -:root { - --bg-primary: #0d1117; - --bg-secondary: #161b22; - --bg-tertiary: #21262d; - --bg-input: rgba(0, 0, 0, 0.25); - --text-primary: #e6edf3; - --text-secondary: #8b949e; - --text-muted: #484f58; - --border: rgba(255, 255, 255, 0.1); - --border-focus: rgba(212, 165, 116, 0.5); - --accent: #d4a574; - --accent-soft: rgba(212, 165, 116, 0.15); - --success: #3fb950; - --danger: #f85149; - --warning: #d29922; -} - -* { +*, +*::before, +*::after { margin: 0; padding: 0; box-sizing: border-box; } +:root { + --bg: #121212; + --bg2: #1e1e1e; + --bg3: #2a2a2a; + --txt: #e0e0e0; + --txt2: #b0b0b0; + --txt3: #808080; + --bdr: #3a3a3a; + --bdr2: #333; + --acc: #e0e0e0; + --hl: #e8928a; + --hl2: #d87a7a; + --hl-soft: rgba(232, 146, 138, .1); + --inv: #1e1e1e; + --success: #4caf50; + --warn: #ffb74d; + --error: #ef5350; + --code-bg: #0d0d0d; + --code-txt: #d4d4d4; + --radius: 4px; +} + html, body { height: auto; @@ -33,11 +40,11 @@ body { } body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; - background: var(--bg-primary); - color: var(--text-primary); + font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', Roboto, sans-serif; + background: var(--bg); + color: var(--txt); font-size: 14px; - line-height: 1.5; + line-height: 1.6; min-height: 100vh; } @@ -45,171 +52,187 @@ body { Layout ═══════════════════════════════════════════════════════════════════════════ */ -.app-container { +.container { display: flex; flex-direction: column; min-height: 100vh; -} - -.app-header { - display: flex; - align-items: center; - gap: 12px; - padding: 12px 20px; - background: var(--bg-secondary); - border-bottom: 1px solid var(--border); - flex-wrap: wrap; -} - -.app-body { - display: flex; - flex: 1; - min-height: 0; -} - -.app-sidebar { - width: 200px; - min-width: 200px; - background: var(--bg-secondary); - border-right: 1px solid var(--border); - padding: 16px 8px; - display: flex; - flex-direction: column; - gap: 4px; -} - -.app-main { - flex: 1; - padding: 24px; - overflow-y: auto; + padding: 24px 40px; + max-width: 860px; + margin: 0 auto; } /* ═══════════════════════════════════════════════════════════════════════════ - Header & Save Status + Header ═══════════════════════════════════════════════════════════════════════════ */ -.header-logo { +header { display: flex; - align-items: center; - gap: 8px; - font-size: 16px; + justify-content: space-between; + align-items: flex-start; + padding-bottom: 24px; + border-bottom: 1px solid var(--bdr); + margin-bottom: 24px; +} + +.header-left h1 { + font-size: 2rem; + font-weight: 300; + letter-spacing: -.02em; + margin-bottom: 4px; + color: var(--txt); +} + +.header-left h1 span { font-weight: 600; - white-space: nowrap; } -.header-logo i { - color: var(--accent); +.subtitle { + font-size: .75rem; + color: var(--txt3); + letter-spacing: .08em; + text-transform: uppercase; } -.header-spacer { - flex: 1; - min-width: 10px; -} - -.header-badge { +.stats { display: flex; + gap: 40px; align-items: center; - gap: 6px; - padding: 4px 10px; - background: var(--bg-input); - border: 1px solid var(--border); - border-radius: 12px; - font-size: 11px; - color: var(--text-muted); + text-align: right; } -.header-badge.on { - color: var(--success); - border-color: rgba(63, 185, 80, 0.3); +.stat-val { + font-size: 1.125rem; + font-weight: 500; + line-height: 1.2; + color: var(--txt); } -.header-badge i { - font-size: 6px; +.stat-val .hl { + color: var(--hl); } -.save-status { - display: flex; - align-items: center; - gap: 6px; - padding: 4px 10px; - border-radius: 12px; - font-size: 11px; - color: var(--text-muted); - transition: all 0.2s; +.stat-lbl { + font-size: .6875rem; + color: var(--txt3); + text-transform: uppercase; + letter-spacing: .1em; + margin-top: 4px; } -.save-status.saving { - color: var(--warning); -} - -.save-status.saved { - color: var(--success); -} - -.save-status.error { - color: var(--danger); -} - -.save-status i { - font-size: 10px; -} - -.header-close { +.modal-close { width: 36px; height: 36px; - min-width: 36px; - border: 1px solid var(--border); - border-radius: 8px; - background: transparent; - color: var(--text-secondary); - cursor: pointer; display: flex; align-items: center; justify-content: center; - font-size: 16px; + background: transparent; + border: 1px solid var(--bdr); + border-radius: var(--radius); + cursor: pointer; + transition: border-color .2s; + margin-left: 16px; } -.header-close:hover { - background: rgba(255, 255, 255, 0.08); - color: var(--text-primary); +.modal-close:hover { + border-color: var(--txt2); +} + +.modal-close svg { + width: 16px; + height: 16px; + color: var(--txt2); } /* ═══════════════════════════════════════════════════════════════════════════ - Sidebar nav - ═══════════════════════════════════════════════════════════════════════════ */ + Nav Tabs (desktop) + ═══════════════════════════════════════════ */ + +.nav-tabs { + display: flex; + gap: 24px; + border-bottom: 1px solid var(--bdr); + margin-bottom: 24px; +} .nav-item { - display: flex; - align-items: center; - gap: 10px; - padding: 10px 14px; - border-radius: 8px; - color: var(--text-secondary); + font-size: .8125rem; + font-weight: 500; + color: var(--txt3); + text-transform: uppercase; + letter-spacing: .08em; + padding-bottom: 12px; + border-bottom: 2px solid transparent; + margin-bottom: -1px; cursor: pointer; - transition: all 0.15s; - font-size: 13px; + transition: color .2s, border-color .2s; + user-select: none; } .nav-item:hover { - background: rgba(255, 255, 255, 0.04); - color: var(--text-primary); + color: var(--txt2); } .nav-item.active { - background: var(--accent-soft); - color: var(--accent); - font-weight: 500; + color: var(--hl); + border-bottom-color: var(--hl); } -.nav-item i { - width: 18px; - text-align: center; +/* ═══════════════════════════════════════════════════════════════════════════ + Mobile Nav (bottom) + ═══════════════════════════════════════════════════════════════════════════ */ + +.mobile-nav { + display: none; + position: fixed; + bottom: 0; + left: 0; + right: 0; + height: 56px; + background: var(--bg2); + border-top: 1px solid var(--bdr); + z-index: 100; } -.nav-divider { - height: 1px; - background: var(--border); - margin: 8px 0; +.mobile-nav-inner { + display: flex; + height: 100%; +} + +.mobile-nav-item { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 2px; + color: var(--txt3); + font-size: .625rem; + text-transform: uppercase; + letter-spacing: .05em; + cursor: pointer; + user-select: none; + transition: color .2s; +} + +.mobile-nav-item span { + line-height: 1; +} + +.mobile-nav-item .nav-dot { + width: 4px; + height: 4px; + border-radius: 50%; + background: transparent; + transition: background .2s; + margin-bottom: 2px; +} + +.mobile-nav-item.active { + color: var(--hl); +} + +.mobile-nav-item.active .nav-dot { + background: var(--hl); } /* ═══════════════════════════════════════════════════════════════════════════ @@ -218,119 +241,123 @@ body { .view { display: none; - max-width: 800px; - margin: 0 auto; } .view.active { display: block; - animation: viewIn 0.2s ease; + animation: fadeIn .25s ease; } -@keyframes viewIn { +@keyframes fadeIn { from { opacity: 0; - transform: translateY(8px); + transform: translateY(4px); } to { opacity: 1; + transform: translateY(0); } } -.view-header { - margin-bottom: 20px; -} - -.view-title { - font-size: 20px; - font-weight: 600; - margin-bottom: 4px; -} - -.view-desc { - font-size: 13px; - color: var(--text-secondary); -} - /* ═══════════════════════════════════════════════════════════════════════════ - Cards & Forms + Cards ═══════════════════════════════════════════════════════════════════════════ */ .card { - background: var(--bg-secondary); - border: 1px solid var(--border); - border-radius: 12px; - padding: 20px; - margin-bottom: 16px; + background: var(--bg2); + border: 1px solid var(--bdr); + border-radius: var(--radius); + padding: 24px; + margin-bottom: 20px; } .card-title { - font-size: 13px; + font-size: .75rem; font-weight: 600; - margin-bottom: 16px; - color: var(--accent); text-transform: uppercase; - letter-spacing: 0.05em; + letter-spacing: .12em; + color: var(--txt2); + margin-bottom: 20px; + padding-bottom: 10px; + border-bottom: 1px dashed var(--bdr2); +} + +/* ═══════════════════════════════════════════════════════════════════════════ + Forms + ═══════════════════════════════════════════════════════════════════════════ */ + +.form-row { + display: flex; + gap: 16px; + flex-wrap: wrap; } .form-group { + display: flex; + flex-direction: column; + gap: 6px; + flex: 1; + min-width: 180px; margin-bottom: 16px; } -.form-group:last-child { +.form-row .form-group { margin-bottom: 0; } +.form-row+.form-row { + margin-top: 16px; +} + .form-label { - display: block; - font-size: 12px; - color: var(--text-secondary); - margin-bottom: 6px; - font-weight: 500; + font-size: .6875rem; + color: var(--txt3); + text-transform: uppercase; + letter-spacing: .06em; } .form-hint { - font-size: 11px; - color: var(--text-muted); - margin-top: 4px; + font-size: .75rem; + color: var(--txt3); line-height: 1.5; -} - -.form-row { - display: grid; - grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); - gap: 12px; + margin-top: 4px; } .input { width: 100%; - padding: 10px 12px; - background: var(--bg-input); - border: 1px solid var(--border); - border-radius: 8px; - color: var(--text-primary); - font-size: 13px; - transition: border-color 0.15s; + padding: 9px 12px; + background: var(--bg3); + border: 1px solid var(--bdr); + border-radius: var(--radius); + font-size: .8125rem; + color: var(--txt); + font-family: inherit; + outline: none; + transition: border-color .2s; } .input:focus { - outline: none; - border-color: var(--border-focus); + border-color: var(--txt2); } .input::placeholder { - color: var(--text-muted); + color: var(--txt3); +} + +select.input { + appearance: none; + -webkit-appearance: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' fill='none' stroke='%23808080' stroke-width='2'%3E%3Cpolyline points='2 3.5 5 6.5 8 3.5'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 10px center; + padding-right: 28px; + cursor: pointer; } textarea.input { min-height: 80px; resize: vertical; - font-family: inherit; -} - -select.input { - cursor: pointer; } .input-row { @@ -343,73 +370,61 @@ select.input { min-width: 0; } -/* Model selector */ -.model-selector { - margin-top: 8px; -} - -.model-selector.hidden { - display: none; -} - /* ═══════════════════════════════════════════════════════════════════════════ Buttons - ═══════════════════════════════════════════════════════════════════════════ */ + ═══════════════════════════════════════════ */ .btn { display: inline-flex; align-items: center; justify-content: center; - gap: 6px; - padding: 10px 16px; - min-height: 40px; - border: 1px solid var(--border); - border-radius: 8px; - background: var(--bg-tertiary); - color: var(--text-primary); - font-size: 13px; + padding: 9px 18px; + background: var(--bg2); + color: var(--txt); + border: 1px solid var(--bdr); + border-radius: var(--radius); + font-size: .8125rem; + font-weight: 500; + font-family: inherit; cursor: pointer; - transition: all 0.15s; + transition: border-color .2s, background .2s; white-space: nowrap; } .btn:hover { - background: rgba(255, 255, 255, 0.08); -} - -.btn:active { - transform: scale(0.98); + border-color: var(--txt3); + background: var(--bg3); } .btn:disabled { - opacity: 0.5; + opacity: .35; cursor: not-allowed; } -.btn-primary { - background: var(--accent); - border-color: var(--accent); - color: #000; - font-weight: 500; +.btn-p { + background: var(--acc); + color: var(--inv); + border-color: var(--acc); } -.btn-primary:hover { - background: #e5b685; +.btn-p:hover { + background: var(--txt2); + border-color: var(--txt2); } -.btn-danger { - color: var(--danger); - border-color: rgba(248, 81, 73, 0.3); +.btn-del { + color: var(--hl); + border-color: rgba(232, 146, 138, .3); } -.btn-danger:hover { - background: rgba(248, 81, 73, 0.1); +.btn-del:hover { + background: var(--hl-soft); + border-color: var(--hl); } .btn-sm { - padding: 6px 10px; - min-height: 32px; - font-size: 12px; + padding: 5px 12px; + font-size: .75rem; } .btn-group { @@ -418,83 +433,43 @@ select.input { flex-wrap: wrap; } -/* Toggle button with text */ -.btn-toggle { - min-width: 80px; -} - -/* Undo button */ -.undo-bar { - display: flex; - align-items: center; - gap: 12px; - padding: 10px 14px; - margin-top: 10px; - background: var(--accent-soft); - border: 1px solid rgba(212, 165, 116, 0.2); - border-radius: 8px; - font-size: 12px; -} - -.undo-bar.hidden { - display: none; -} - /* ═══════════════════════════════════════════════════════════════════════════ - Tip box + Tip Box ═══════════════════════════════════════════════════════════════════════════ */ .tip-box { display: flex; - gap: 10px; - padding: 12px 14px; - background: var(--accent-soft); - border: 1px solid rgba(212, 165, 116, 0.2); - border-radius: 8px; - font-size: 12px; - color: var(--text-secondary); - line-height: 1.6; - margin-bottom: 16px; + gap: 12px; + align-items: flex-start; + padding: 14px 16px; + background: var(--hl-soft); + border: 1px solid var(--bdr); + border-left: 3px solid var(--hl); + border-radius: var(--radius); + margin-bottom: 20px; } -.tip-box i { - color: var(--accent); +.tip-icon { flex-shrink: 0; - margin-top: 2px; + font-size: .875rem; + line-height: 1.6; +} + +.tip-text { + font-size: .8125rem; + color: var(--txt2); + line-height: 1.6; } /* ═══════════════════════════════════════════════════════════════════════════ - Status - ═══════════════════════════════════════════════════════════════════════════ */ - -.status-text { - font-size: 12px; - color: var(--text-secondary); - margin-top: 8px; - min-height: 18px; -} - -.status-text.success { - color: var(--success); -} - -.status-text.error { - color: var(--danger); -} - -.status-text.loading { - color: var(--warning); -} - -/* ═══════════════════════════════════════════════════════════════════════════ - Prompt blocks + Prompt Blocks ═══════════════════════════════════════════════════════════════════════════ */ .prompt-block { - background: var(--bg-tertiary); - border: 1px solid var(--border); - border-radius: 10px; - padding: 14px; + background: var(--bg3); + border: 1px solid var(--bdr); + border-radius: var(--radius); + padding: 16px; margin-bottom: 10px; } @@ -502,7 +477,7 @@ select.input { display: flex; justify-content: space-between; align-items: flex-start; - gap: 8px; + gap: 10px; margin-bottom: 10px; flex-wrap: wrap; } @@ -510,14 +485,8 @@ select.input { .prompt-head-left { display: flex; gap: 8px; - flex-wrap: wrap; flex: 1; - min-width: 280px; -} - -.prompt-head-left input, -.prompt-head-left select { - max-width: 200px; + min-width: 200px; } .prompt-head-right { @@ -526,97 +495,168 @@ select.input { } .prompt-block textarea.input { - min-height: 100px; - font-family: monospace; - font-size: 12px; + min-height: 120px; + font-family: 'SF Mono', Monaco, Consolas, 'Liberation Mono', monospace; + font-size: .75rem; + line-height: 1.5; } .prompt-empty { text-align: center; - padding: 30px 20px; - color: var(--text-muted); - font-size: 13px; + padding: 36px 20px; + color: var(--txt3); + font-size: .8125rem; + border: 1px dashed var(--bdr); + border-radius: var(--radius); } /* ═══════════════════════════════════════════════════════════════════════════ + Undo Bar + ═══════════════════════════════════════════════════════════════════════════ */ + +.undo-bar { + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px 14px; + margin-top: 12px; + background: var(--hl-soft); + border: 1px solid var(--bdr); + border-radius: var(--radius); + font-size: .8125rem; + color: var(--txt2); +} + +/* ═══════════════════════════════════════════════════════════════════════════ + Status Text + ═══════════════════════════════════════════ */ + +.status-text { + font-size: .75rem; + color: var(--txt3); + margin-top: 10px; + min-height: 1em; +} + +.status-text.success { + color: var(--success); +} + +.status-text.error { + color: var(--error); +} + +.status-text.loading { + color: var(--warn); +} + +/* ═══════════════════════════════════════════ Logs ═══════════════════════════════════════════════════════════════════════════ */ .log-list { - max-height: 62vh; - overflow: auto; + max-height: 60vh; + overflow-y: auto; + border: 1px solid var(--bdr); + border-radius: var(--radius); + background: var(--bg3); } .log-item { - border-bottom: 1px solid rgba(255, 255, 255, 0.05); - padding: 10px 0; + padding: 14px 16px; + border-bottom: 1px solid var(--bdr2); +} + +.log-item:last-child { + border-bottom: none; } .log-meta { display: flex; justify-content: space-between; - font-size: 12px; - color: var(--text-muted); - gap: 8px; - margin-bottom: 4px; + font-size: .6875rem; + color: var(--txt3); + text-transform: uppercase; + letter-spacing: .04em; + margin-bottom: 8px; +} + +.log-meta .success { + color: var(--success); +} + +.log-meta .error { + color: var(--error); } .log-error { - color: var(--danger); - font-size: 12px; + color: var(--error); + font-size: .8125rem; + margin-bottom: 8px; white-space: pre-wrap; - margin: 4px 0; } .log-pre { + background: var(--code-bg); + color: var(--code-txt); + padding: 12px; + border-radius: var(--radius); + font-family: 'SF Mono', Monaco, Consolas, 'Liberation Mono', monospace; + font-size: .6875rem; + line-height: 1.5; white-space: pre-wrap; word-break: break-word; - font-size: 12px; - background: var(--bg-primary); - border: 1px solid var(--border); - border-radius: 8px; - padding: 10px; - max-height: 260px; - overflow: auto; + max-height: 280px; + overflow-y: auto; margin-top: 6px; - font-family: monospace; } .log-empty { text-align: center; - padding: 30px 20px; - color: var(--text-muted); - font-size: 13px; + padding: 36px 20px; + color: var(--txt3); + font-size: .8125rem; +} + +details { + margin-bottom: 6px; +} + +details:last-child { + margin-bottom: 0; } details summary { cursor: pointer; - font-size: 12px; - color: var(--text-secondary); - padding: 4px 0; + font-size: .75rem; + font-weight: 500; + color: var(--txt3); user-select: none; + padding: 4px 0; + transition: color .15s; } details summary:hover { - color: var(--text-primary); + color: var(--txt); } /* ═══════════════════════════════════════════════════════════════════════════ - Debug output + Debug Output ═══════════════════════════════════════════════════════════════════════════ */ .debug-output { + background: var(--code-bg); + color: var(--code-txt); + padding: 14px; + border-radius: var(--radius); + font-family: 'SF Mono', Monaco, Consolas, 'Liberation Mono', monospace; + font-size: .6875rem; + line-height: 1.6; + margin-top: 16px; + max-height: 400px; + overflow-y: auto; white-space: pre-wrap; word-break: break-word; - font-size: 12px; - background: var(--bg-primary); - border: 1px solid var(--border); - border-radius: 8px; - padding: 12px; - max-height: 400px; - overflow: auto; - margin-top: 12px; - font-family: monospace; display: none; } @@ -624,163 +664,17 @@ details summary:hover { display: block; } -/* ═══════════════════════════════════════════════════════════════════════════ - Mobile nav - ═══════════════════════════════════════════════════════════════════════════ */ - -.mobile-nav { - display: none; - position: fixed; - bottom: 0; - left: 0; - right: 0; - height: 60px; - background: var(--bg-secondary); - border-top: 1px solid var(--border); - z-index: 100; -} - -.mobile-nav-inner { - display: flex; - height: 100%; - overflow-x: auto; - -webkit-overflow-scrolling: touch; -} - -.mobile-nav-inner::-webkit-scrollbar { - display: none; -} - -.mobile-nav-item { - flex: 1; - min-width: 56px; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 4px; - color: var(--text-muted); - font-size: 10px; - cursor: pointer; - padding: 8px 4px; -} - -.mobile-nav-item i { - font-size: 18px; -} - -.mobile-nav-item.active { - color: var(--accent); -} - -/* ═══════════════════════════════════════════════════════════════════════════ - Responsive - ═══════════════════════════════════════════════════════════════════════════ */ - -@media (max-width: 768px) { - .app-sidebar { - display: none; - } - - .mobile-nav { - display: block; - } - - .app-body { - padding-bottom: 60px; - } - - .app-main { - padding: 16px; - padding-bottom: 76px; - } - - .app-header { - padding: 10px 12px; - gap: 8px; - } - - .header-logo span { - display: none; - } - - .header-badge span, - .save-status span { - display: none; - } - - .header-close { - width: 32px; - height: 32px; - min-width: 32px; - font-size: 14px; - } - - .view-title { - font-size: 18px; - } - - .card { - padding: 16px; - } - - .form-row { - grid-template-columns: 1fr; - } - - .prompt-head-left { - min-width: 0; - } - - .prompt-head-left input, - .prompt-head-left select { - max-width: none; - } -} - -@media (max-width: 400px) { - .app-header { - padding: 8px 10px; - } - - .mobile-nav-item { - min-width: 48px; - font-size: 9px; - } - - .mobile-nav-item i { - font-size: 16px; - } -} - -@media (hover: none) and (pointer: coarse) { - .btn { - min-height: 44px; - } - - .input { - min-height: 44px; - padding: 12px; - } - - .nav-item { - min-height: 44px; - } - - .header-close { - width: 44px; - height: 44px; - min-width: 44px; - } -} - -/* ═══════════════════════════════════════════════════════════════════════════ +/* ═══════════════════════════════════════════ Utilities ═══════════════════════════════════════════════════════════════════════════ */ +.hidden { + display: none !important; +} + ::-webkit-scrollbar { - width: 6px; - height: 6px; + width: 5px; + height: 5px; } ::-webkit-scrollbar-track { @@ -788,14 +682,163 @@ details summary:hover { } ::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.1); + background: var(--bdr); border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.2); + background: var(--txt3); } -.hidden { - display: none !important; +/* ═══════════════════════════════════════════ + Responsive — Tablet + ═══════════════════════════════════════════ */ + +@media (max-width: 768px) { + .container { + padding: 16px; + } + + header { + flex-direction: column; + gap: 16px; + } + + .header-left h1 { + font-size: 1.5rem; + } + + .stats { + width: 100%; + justify-content: flex-start; + gap: 24px; + } + + .modal-close { + position: absolute; + top: 16px; + right: 16px; + margin-left: 0; + } + + .nav-tabs { + display: none; + } + + .mobile-nav { + display: block; + } + + .container { + padding-bottom: 72px; + } + + .form-row { + flex-direction: column; + gap: 0; + } + + .card { + padding: 16px; + } + + .prompt-head { + flex-direction: column; + } + + .prompt-head-left { + min-width: 0; + flex-direction: column; + } +} + +/* ═══════════════════════════════════════════ + Responsive — Small phone + ═══════════════════════════════════════════════════════════════════════════ */ + +@media (max-width: 480px) { + .container { + padding: 12px; + padding-bottom: 68px; + } + + header { + gap: 12px; + padding-bottom: 16px; + margin-bottom: 16px; + } + + .header-left h1 { + font-size: 1.25rem; + } + + .subtitle { + font-size: .625rem; + } + + .stats { + gap: 16px; + } + + .stat-val { + font-size: 1rem; + } + + .card { + padding: 14px; + margin-bottom: 14px; + } + + .btn-group { + flex-direction: column; + } + + .btn-group .btn { + width: 100%; + } + + .mobile-nav { + height: 52px; + } + + .mobile-nav-item { + font-size: .5625rem; + } +} + +/* ═══════════════════════════════════════════ + Touch devices — 44px minimum target + ═══════════════════════════════════════════════════════════════════════════ */ + +@media (hover: none) and (pointer: coarse) { + .btn { + min-height: 44px; + padding: 10px 18px; + } + + .btn-sm { + min-height: 40px; + } + + .input { + min-height: 44px; + padding: 10px 12px; + } + + .nav-item { + padding-bottom: 14px; + } + + .mobile-nav-item { + min-height: 44px; + } + + .modal-close { + width: 44px; + height: 44px; + } + + details summary { + padding: 8px 0; + } } \ No newline at end of file diff --git a/modules/ena-planner/ena-planner.html b/modules/ena-planner/ena-planner.html index e1936de..c15fbb7 100644 --- a/modules/ena-planner/ena-planner.html +++ b/modules/ena-planner/ena-planner.html @@ -7,400 +7,324 @@ Ena Planner - -
+
- -
-