/* RBQ 绘图 v2 — one responsive page. Layout A (工作台) >= 1024px, Layout B (创作流) below.
   Theme: <html data-theme="light|dark">, all colours are CSS variables (shared scheme with admin/dashboard). */

/* ============================== theme tokens ============================== */
:root, [data-theme="dark"] {
    --bg: #0d0f14;
    --surface: #151922;
    --surface-2: #1c2130;
    --text: #e8eaf0;
    --text-dim: #9aa3b6;
    --border: #272d3b;
    --accent: #8592ff;
    --danger: #f87171;
    --success: #34d399;
    --warning: #fbbf24;
    --on-accent: #0b0e1c;
    --shadow: 0 18px 44px rgba(0, 0, 0, .55);
    /* page-local helpers (derived) */
    --surface-3: #242a3b;
    --border-strong: #3a4258;
    --accent-2: #b39cff;
    --accent-soft: rgba(133, 146, 255, .16);
    --accent-text: #a9b2ff;
    --overlay: rgba(4, 6, 12, .62);
    --canvas: #0a0c11;
    --checker-a: #11141b;
    --checker-b: #161a23;
    --scrim: rgba(12, 14, 20, .72);
    --scrim-text: #f1f3f8;
    --scrim-border: rgba(255, 255, 255, .10);
    --warning-soft: rgba(251, 191, 36, .12);
    --danger-soft: rgba(248, 113, 113, .12);
    --success-soft: rgba(52, 211, 153, .12);
    --focus: 0 0 0 3px rgba(133, 146, 255, .35);
    --input-bg: #11151e;
    color-scheme: dark;
}
[data-theme="light"] {
    --bg: #f4f5f9;
    --surface: #ffffff;
    --surface-2: #eef0f6;
    --text: #171b26;
    --text-dim: #586174;
    --border: #dde1ea;
    --accent: #4f5fe0;
    --danger: #d12f2f;
    --success: #077a50;
    --warning: #9a5b00;
    --on-accent: #ffffff;
    --shadow: 0 14px 36px rgba(23, 30, 60, .14);
    --surface-3: #e4e7f0;
    --border-strong: #c3c9d8;
    --accent-2: #7c5ce6;
    --accent-soft: rgba(79, 95, 224, .10);
    --accent-text: #3f4fd0;
    --overlay: rgba(20, 24, 40, .38);
    --canvas: #e6e8ef;
    --checker-a: #e9ebf1;
    --checker-b: #f2f3f7;
    --scrim: rgba(255, 255, 255, .86);
    --scrim-text: #171b26;
    --scrim-border: rgba(20, 24, 40, .10);
    --warning-soft: rgba(196, 120, 0, .10);
    --danger-soft: rgba(209, 47, 47, .08);
    --success-soft: rgba(11, 138, 92, .10);
    --focus: 0 0 0 3px rgba(79, 95, 224, .28);
    --input-bg: #ffffff;
    color-scheme: light;
}

/* ============================== base ============================== */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
    font-family: "Noto Sans CJK SC", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", system-ui, -apple-system, "Segoe UI", sans-serif;
    font-size: 13px; line-height: 1.5; color: var(--text); background: var(--bg);
    -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent;
    overflow: hidden;
}
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
button:disabled { cursor: not-allowed; }
a { color: var(--accent-text); }
img { display: block; max-width: 100%; }
:focus-visible { outline: none; box-shadow: var(--focus); }
[hidden] { display: none !important; }
.mono { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-variant-numeric: tabular-nums; }
.dim { color: var(--text-dim); }
.spacer { flex: 1; }
kbd { display: inline-block; min-width: 18px; padding: 0 5px; border: 1px solid var(--border-strong); border-bottom-width: 2px; border-radius: 5px; font: 11px/16px ui-monospace, Menlo, monospace; color: var(--text-dim); background: var(--surface-2); text-align: center; }
code { font: 12px ui-monospace, Menlo, monospace; background: var(--surface-2); padding: 1px 5px; border-radius: 5px; }
.ic { flex: none; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--surface-3); border-radius: 10px; border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background-color: var(--border-strong); }
::-webkit-scrollbar-track { background: transparent; }

.checker { background-color: var(--checker-a); background-image: linear-gradient(45deg, var(--checker-b) 25%, transparent 25%, transparent 75%, var(--checker-b) 75%), linear-gradient(45deg, var(--checker-b) 25%, transparent 25%, transparent 75%, var(--checker-b) 75%); background-size: 16px 16px; background-position: 0 0, 8px 8px; }
.checker-soft { background-color: var(--canvas); }

/* ============================== splash ============================== */
.splash { position: fixed; inset: 0; z-index: 100; display: grid; place-items: center; background: var(--bg); transition: opacity .25s; padding: 24px; }
.splash.hide { opacity: 0; pointer-events: none; }
.splash-card { text-align: center; max-width: 440px; display: flex; flex-direction: column; align-items: center; gap: 10px; color: var(--text); }
.splash-card h2 { margin: 4px 0 0; font-size: 20px; }
.splash-card p { margin: 0; color: var(--text-dim); }
.splash-icon { width: 60px; height: 60px; border-radius: 18px; display: grid; place-items: center; background: var(--accent-soft); color: var(--accent-text); }
.splash-card.danger .splash-icon { background: var(--danger-soft); color: var(--danger); }
.splash-detail { max-width: 100%; white-space: pre-wrap; word-break: break-word; font-size: 12px; color: var(--text-dim); background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; text-align: left; margin: 4px 0 0; }
.splash-actions { display: flex; gap: 10px; margin-top: 10px; flex-wrap: wrap; justify-content: center; }
.noscript { padding: 40px; text-align: center; }

/* ============================== buttons & inputs ============================== */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 36px; padding: 0 14px; border-radius: 10px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); font-weight: 600; font-size: 13px; text-decoration: none; white-space: nowrap; transition: background .15s, border-color .15s, transform .05s; }
.btn:hover:not(:disabled) { border-color: var(--border-strong); background: var(--surface-3); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: .5; }
.btn.primary { background: var(--accent); border-color: transparent; color: var(--on-accent); }
.btn.primary:hover:not(:disabled) { background: var(--accent); filter: brightness(1.08); }
.btn.danger { background: var(--danger); border-color: transparent; color: #fff; }
.btn.ghost { background: transparent; }
.btn.danger-ghost { background: transparent; color: var(--danger); border-color: var(--danger-soft); }
.btn.dashed { background: transparent; border-style: dashed; color: var(--text-dim); font-weight: 500; }
.btn.dashed:hover:not(:disabled) { color: var(--text); border-color: var(--accent); background: var(--accent-soft); }
.btn.block { width: 100%; }
.btn.sm { height: 30px; padding: 0 10px; font-size: 12px; border-radius: 8px; }
.icon-btn { display: inline-grid; place-items: center; width: 34px; height: 34px; border-radius: 9px; border: 1px solid transparent; background: transparent; color: var(--text-dim); transition: background .15s, color .15s; flex: none; padding: 0; }
.icon-btn:hover:not(:disabled) { background: var(--surface-2); color: var(--text); }
.icon-btn.on { color: var(--accent-text); background: var(--accent-soft); border-color: transparent; }
.icon-btn:disabled { opacity: .35; }
.icon-btn.sm { width: 28px; height: 28px; border-radius: 7px; }
.link-btn { background: none; border: 0; padding: 0; color: var(--accent-text); font-size: 12px; cursor: pointer; }
.link-btn:hover { text-decoration: underline; }
.mini-btn { display: inline-flex; align-items: center; gap: 4px; height: 26px; padding: 0 9px; border-radius: 7px; border: 1px solid var(--border); background: var(--surface); color: var(--text-dim); font-size: 12px; white-space: nowrap; }
.mini-btn:hover:not(:disabled) { color: var(--text); border-color: var(--border-strong); }
.mini-btn.danger:hover:not(:disabled) { color: var(--danger); border-color: var(--danger); }
.mini-btn:disabled { opacity: .45; }

.input { width: 100%; background: var(--input-bg); border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px; color: var(--text); outline: none; transition: border-color .15s, box-shadow .15s; }
.input:focus { border-color: var(--accent); box-shadow: var(--focus); }
.input::placeholder { color: var(--text-dim); opacity: .75; }
.input:disabled { opacity: .55; }
select.input { appearance: none; padding-right: 30px; background-image: linear-gradient(45deg, transparent 50%, var(--text-dim) 50%), linear-gradient(135deg, var(--text-dim) 50%, transparent 50%); background-position: calc(100% - 15px) 52%, calc(100% - 10px) 52%; background-size: 5px 5px; background-repeat: no-repeat; }
textarea.input { resize: none; line-height: 1.6; }
.input.num { width: 80px; text-align: right; font-variant-numeric: tabular-nums; padding: 6px 8px; }
.input.num::-webkit-inner-spin-button { opacity: .4; }
.input.sm { font-size: 12px; padding: 6px 9px; }

/* range */
input[type="range"] { -webkit-appearance: none; appearance: none; width: 100%; height: 22px; background: transparent; margin: 0; --p: 50%; }
input[type="range"]::-webkit-slider-runnable-track { height: 4px; border-radius: 4px; background: linear-gradient(90deg, var(--accent) var(--p), var(--surface-3) var(--p)); }
input[type="range"]::-moz-range-track { height: 4px; border-radius: 4px; background: var(--surface-3); }
input[type="range"]::-moz-range-progress { height: 4px; border-radius: 4px; background: var(--accent); }
input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 16px; height: 16px; border-radius: 50%; background: var(--surface); border: 2px solid var(--accent); margin-top: -6px; box-shadow: 0 1px 4px rgba(0,0,0,.3); }
input[type="range"]::-moz-range-thumb { width: 14px; height: 14px; border-radius: 50%; background: var(--surface); border: 2px solid var(--accent); }
input[type="range"]:disabled { opacity: .45; }
input[type="range"]:focus-visible { box-shadow: none; }
input[type="range"]:focus-visible::-webkit-slider-thumb { box-shadow: var(--focus); }

/* switch */
.switch-input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.switch { position: relative; width: 36px; height: 20px; border-radius: 20px; background: var(--surface-3); border: 1px solid var(--border-strong); flex: none; transition: background .15s, border-color .15s; }
.switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--text-dim); transition: transform .15s, background .15s; }
.switch-input:checked + .switch { background: var(--accent); border-color: var(--accent); }
.switch-input:checked + .switch::after { transform: translateX(16px); background: var(--on-accent); }
.switch-input:focus-visible + .switch { box-shadow: var(--focus); }
.switch-input:disabled + .switch { opacity: .45; }
.switch.sm { width: 30px; height: 18px; }
.switch.sm::after { width: 12px; height: 12px; }
.switch-input:checked + .switch.sm::after { transform: translateX(12px); }

/* segmented */
.seg { display: flex; background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px; padding: 3px; gap: 3px; }
.seg-btn { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 5px; min-height: 30px; padding: 4px 6px; border: 0; border-radius: 7px; background: transparent; color: var(--text-dim); font-size: 12.5px; font-weight: 500; white-space: nowrap; transition: background .15s, color .15s; }
.seg-btn:hover:not(:disabled) { color: var(--text); }
.seg-btn.on { background: var(--surface); color: var(--text); font-weight: 650; box-shadow: 0 1px 3px rgba(0,0,0,.18), inset 0 0 0 1px var(--border-strong); }
[data-theme="dark"] .seg-btn.on { background: var(--surface-3); }
.seg.sm .seg-btn { min-height: 26px; font-size: 12px; }

/* chips */
.chip { display: inline-flex; align-items: center; gap: 5px; height: 28px; padding: 0 10px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border); color: var(--text-dim); font-size: 12px; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.chip:hover:not(:disabled) { color: var(--text); border-color: var(--border-strong); }
.chip.on { border-color: var(--accent); color: var(--accent-text); background: var(--accent-soft); }
.chip.sm { height: 26px; padding: 0 9px; }
.chip:disabled { opacity: .75; cursor: default; }
.count-badge { display: inline-flex; align-items: center; min-width: 18px; height: 18px; padding: 0 6px; border-radius: 999px; background: var(--accent-soft); color: var(--accent-text); font-size: 11px; font-weight: 600; }
.mini-badge { margin-left: 6px; font-size: 10px; padding: 0 5px; border-radius: 5px; background: var(--accent-soft); color: var(--accent-text); font-weight: 600; vertical-align: 1px; }
.pill { display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 12px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border); color: var(--text-dim); font-size: 12px; white-space: nowrap; }
.pill b { color: var(--text); font-weight: 650; }
.pill.bal b { color: var(--success); font-variant-numeric: tabular-nums; }
.pill.bal.low b { color: var(--danger); }
button.pill:hover { border-color: var(--border-strong); }

.note { display: flex; gap: 8px; align-items: flex-start; padding: 9px 11px; border-radius: 10px; background: var(--surface-2); border: 1px solid var(--border); color: var(--text-dim); font-size: 12px; line-height: 1.55; }
.note .ic { margin-top: 2px; }
.note.info { background: var(--accent-soft); border-color: transparent; color: var(--text); }
.note.info .ic { color: var(--accent-text); }
.note.warn { background: var(--warning-soft); border-color: transparent; color: var(--text); }
.note.warn .ic { color: var(--warning); }
.note b { color: var(--text); }

/* fields */
.field { display: flex; flex-direction: column; gap: 6px; }
.field + .field { margin-top: 12px; }
.field-head { display: flex; align-items: center; gap: 8px; color: var(--text-dim); font-size: 12px; }
.field-head label { flex: 1; }
.sl-val { margin-left: auto; color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; font-size: 12.5px; }
.field-hint { color: var(--text-dim); font-size: 11.5px; line-height: 1.5; }
.field-hint.warn { color: var(--warning); }
.field-hint.err { color: var(--danger); }
.field-hint[hidden] { display: none; }
.lock-note { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; color: var(--warning); background: var(--warning-soft); padding: 1px 7px; border-radius: 999px; white-space: nowrap; }
.slider-field.locked .sl-val { color: var(--text-dim); }
.locked-row { flex-direction: row; justify-content: space-between; align-items: center; color: var(--text-dim); font-size: 12px; padding: 4px 0; }
.toggle-field { flex-direction: row; align-items: center; justify-content: space-between; gap: 12px; cursor: pointer; position: relative; padding: 2px 0; }
.toggle-field.disabled { cursor: not-allowed; opacity: .6; }
.tg-text { display: flex; flex-direction: column; gap: 1px; }
.tg-label { font-size: 13px; color: var(--text); }

.sec { margin-bottom: 16px; }
.sec-label { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; color: var(--text); font-weight: 650; font-size: 13px; }
.sec-meta { color: var(--text-dim); font-weight: 400; font-size: 12px; display: inline-flex; align-items: center; gap: 3px; }
.sec-meta.warn { color: var(--warning); }
.kbd-hint kbd { font-size: 10px; line-height: 15px; min-width: 16px; }

/* ============================== prompt editor ============================== */
.prompt-wrap { position: relative; }
.prompt-ta { min-height: 64px; font-size: 13.5px; background: var(--input-bg); }
.prompt-ta.sm { min-height: 44px; font-size: 12.5px; }
.prompt-wrap.dimmed .prompt-ta, .prompt-wrap .prompt-ta.dimmed { opacity: .55; }
.prompt-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 7px; }
.prompt-foot .count { color: var(--text-dim); font-size: 11.5px; white-space: nowrap; }
.ac-list { position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 40; background: var(--surface); border: 1px solid var(--border-strong); border-radius: 12px; box-shadow: var(--shadow); overflow: hidden auto; max-height: 300px; }
.ac-list.up { top: auto; bottom: calc(100% + 6px); }
.ac-head { display: flex; justify-content: space-between; gap: 10px; padding: 6px 12px; color: var(--text-dim); font-size: 11px; border-bottom: 1px solid var(--border); position: sticky; top: 0; background: var(--surface); }
.ac-row { display: flex; align-items: center; gap: 9px; padding: 7px 12px; cursor: pointer; white-space: nowrap; min-height: 34px; }
.ac-row.sel, .ac-row:hover { background: var(--accent-soft); }
.ac-en { font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; }
.ac-zh { color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; }
.ac-cat { margin-left: auto; color: var(--text-dim); font-size: 11px; opacity: .8; }
.ac-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: #94a3b8; }
.cat-p { background: #f472b6; } .cat-h { background: #f59e0b; } .cat-e { background: #60a5fa; } .cat-c { background: #a78bfa; }
.cat-a { background: #34d399; } .cat-v { background: #22d3ee; } .cat-s { background: #84cc16; } .cat-l { background: #facc15; }
.cat-st { background: #fb7185; } .cat-q { background: #818cf8; } .cat-o { background: #2dd4bf; } .cat-b { background: #fda4af; }

/* ============================== model ============================== */
.model-card, .model-opt { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; background: var(--surface-2); border: 1px solid var(--border); border-radius: 12px; padding: 9px 12px; color: var(--text); transition: border-color .15s, background .15s; }
.model-card:hover, .model-opt:hover { border-color: var(--border-strong); }
.model-opt.on { border-color: var(--accent); background: var(--accent-soft); }
.model-list { display: flex; flex-direction: column; gap: 8px; }
.model-badge { width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center; font-weight: 750; font-size: 11px; color: #fff; flex: none; letter-spacing: -.02em; }
.tone-v45 { background: linear-gradient(135deg, #6366f1, #8b5cf6); }
.tone-v45c { background: linear-gradient(135deg, #0ea5e9, #6366f1); }
.tone-v5 { background: linear-gradient(135deg, #f59e0b, #ef4444); }
.tone-v5m { background: linear-gradient(135deg, #f97316, #ec4899); }
.tone-v5c { background: linear-gradient(135deg, #10b981, #0ea5e9); }
.mo-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.mo-text b { font-size: 13px; font-weight: 650; }
.mo-text span { color: var(--text-dim); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mo-price { color: var(--warning); font-size: 12px; white-space: nowrap; font-weight: 600; }
.mo-check { color: var(--accent-text); }
.model-menu { padding: 6px; display: flex; flex-direction: column; gap: 6px; }
#app .sec > div > .toggle-field, #app .sec > div > .note { margin-top: 10px; }
.sheet-content .toggle-field, .sheet-content .model-list + .note { margin-top: 12px; }

/* ============================== size ============================== */
.ratios { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.ratio { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px; min-height: 52px; padding: 7px 2px 6px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px; color: var(--text-dim); font-size: 11.5px; white-space: nowrap; overflow: hidden; }
.ratio:hover { color: var(--text); border-color: var(--border-strong); }
.ratio.on { border-color: var(--accent); color: var(--text); background: var(--accent-soft); }
.ratio-glyph { display: block; border: 1.6px solid currentColor; border-radius: 3px; }
.ratio-glyph.dashed { border-style: dashed; }
.dims-row { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
.dims-row .dim { flex: 1; display: flex; align-items: center; gap: 6px; background: var(--input-bg); border: 1px solid var(--border); border-radius: 10px; padding: 0 0 0 10px; color: var(--text-dim); font-size: 12px; min-width: 0; }
.dims-row .dim .input.num { border: 0; background: transparent; box-shadow: none; width: 100%; min-width: 0; }
.dims-row .dim:focus-within { border-color: var(--accent); box-shadow: var(--focus); }
.seed-row { display: flex; gap: 6px; align-items: center; }
.seed-row .input { flex: 1; min-width: 0; }

/* ============================== folds ============================== */
.fold { border: 1px solid var(--border); border-radius: 12px; background: var(--surface); margin-bottom: 8px; }
[data-theme="dark"] .fold { background: #121620; }
.fold-head { display: flex; align-items: center; gap: 8px; width: 100%; padding: 11px 12px; background: none; border: 0; text-align: left; color: var(--text); font-weight: 650; font-size: 13px; border-radius: 12px; }
.fold-head:hover { background: var(--surface-2); }
.fold-head.static { cursor: default; }
.fold-head.static:hover { background: none; }
.fold-head > .ic:first-child { color: var(--text-dim); }
.fold-title { white-space: nowrap; }
.fold-hint { margin-left: auto; color: var(--text-dim); font-weight: 400; font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fold-arrow { color: var(--text-dim); transition: transform .2s; margin-left: 4px; }
.fold-hint + .fold-arrow { margin-left: 6px; }
.count-badge + .fold-arrow { margin-left: auto; }
.fold-title + .fold-arrow { margin-left: auto; }
.fold.open .fold-arrow { transform: rotate(180deg); }
.fold-body { display: none; padding: 2px 12px 12px; }
.fold.open .fold-body { display: block; }
.disabled-fold { opacity: .6; }

/* references, characters */
.ref-card { position: relative; display: flex; gap: 10px; padding: 10px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface-2); margin-bottom: 8px; }
.ref-thumb { width: 64px; height: 64px; object-fit: cover; border-radius: 8px; flex: none; background: var(--surface-3); }
.ref-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; padding-right: 22px; }
.ref-body .field + .field { margin-top: 4px; }
.ref-x { position: absolute; top: 6px; right: 6px; }
.ref-status { font-size: 11.5px; display: flex; gap: 8px; flex-wrap: wrap; align-items: center; color: var(--text-dim); }
.ref-status.ok { color: var(--success); }
.ref-status.busy { color: var(--accent-text); }
.char-head { display: flex; align-items: center; gap: 6px; }
.char-dot { width: 22px; height: 22px; border-radius: 7px; display: grid; place-items: center; font-weight: 700; font-size: 11.5px; color: #fff; background: var(--char); flex: none; }
.char-title { font-weight: 600; font-size: 12.5px; margin-right: auto; white-space: nowrap; }
.char-enable { position: relative; display: inline-flex; align-items: center; cursor: pointer; }

.drop-zone { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; min-height: 112px; margin-top: 10px; border: 1.5px dashed var(--border-strong); border-radius: 12px; color: var(--text-dim); cursor: pointer; text-align: center; padding: 12px; overflow: hidden; background: var(--surface-2); }
.drop-zone:hover { border-color: var(--accent); color: var(--text); }
.drop-zone b { color: var(--text); font-size: 13px; }
.drop-zone span { font-size: 11.5px; }
.drop-zone.has { padding: 0; min-height: 0; border-style: solid; cursor: default; }
.drop-zone.has img { width: 100%; max-height: 220px; object-fit: contain; background: var(--canvas); }
.dz-bar { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; gap: 4px; padding: 5px 6px 5px 10px; background: var(--scrim); color: var(--scrim-text); font-size: 11.5px; backdrop-filter: blur(8px); }
.dz-bar span { margin-right: auto; }
.dz-bar .icon-btn { color: var(--scrim-text); }

/* ============================== popover menu ============================== */
.popmenu { position: fixed; z-index: 70; min-width: 180px; max-width: min(380px, calc(100vw - 16px)); max-height: min(70vh, 520px); overflow: auto; background: var(--surface); border: 1px solid var(--border-strong); border-radius: 12px; box-shadow: var(--shadow); padding: 5px; animation: pop .12s ease-out; }
@keyframes pop { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.pm-item { display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px 10px; min-height: 34px; border: 0; background: none; border-radius: 8px; color: var(--text); text-align: left; font-size: 13px; }
.pm-item:hover:not(:disabled) { background: var(--surface-2); }
.pm-item:disabled { color: var(--text-dim); cursor: default; }
.pm-item.danger { color: var(--danger); }
.pm-item.active { color: var(--accent-text); }
.pm-item .ic { color: var(--text-dim); }
.pm-item.danger .ic { color: var(--danger); }
.pm-label { flex: 1; white-space: nowrap; }
.pm-hint { color: var(--text-dim); font-size: 11.5px; white-space: nowrap; }
.pm-check { color: var(--accent-text) !important; }
.pm-sep { height: 1px; background: var(--border); margin: 4px 2px; }
.pm-title { padding: 6px 10px 4px; color: var(--text-dim); font-size: 11.5px; }
.preset-menu { width: 340px; }
.preset-opt { display: block; width: 100%; text-align: left; padding: 9px 10px; border: 0; background: none; border-radius: 9px; color: var(--text); }
.preset-opt:hover { background: var(--surface-2); }
.preset-opt.active { background: var(--accent-soft); }
.po-head { display: flex; align-items: center; gap: 8px; }
.po-head span { color: var(--text-dim); font-size: 12px; flex: 1; }
.po-head .ic { color: var(--accent-text); }
.po-tags { margin-top: 3px; font-size: 11.5px; line-height: 1.5; color: var(--text-dim); font-family: ui-monospace, Menlo, monospace; word-break: break-word; }

/* ============================== layers: dialog / sheet ============================== */
.layer { position: fixed; inset: 0; z-index: 60; background: var(--overlay); display: flex; opacity: 0; transition: opacity .18s; }
.layer.open { opacity: 1; }
.layer.is-dialog { align-items: center; justify-content: center; padding: 24px; }
.layer.is-sheet { align-items: flex-end; }
.layer-panel { background: var(--surface); color: var(--text); border: 1px solid var(--border); box-shadow: var(--shadow); display: flex; flex-direction: column; max-height: 100%; }
.layer-panel.dialog { width: min(480px, 100%); border-radius: 16px; transform: translateY(8px) scale(.98); transition: transform .18s; max-height: calc(100vh - 48px); }
.layer-panel.dialog.wide { width: min(820px, 100%); }
.layer.open .layer-panel.dialog { transform: none; }
.layer-panel.sheet { width: 100%; border-radius: 18px 18px 0 0; border-bottom: 0; max-height: 86vh; transform: translateY(100%); transition: transform .22s cubic-bezier(.2, .8, .2, 1); padding-bottom: env(safe-area-inset-bottom); }
.layer.open .layer-panel.sheet { transform: none; }
.sheet-grip { width: 40px; height: 4px; border-radius: 4px; background: var(--border-strong); margin: 8px auto 0; flex: none; }
.layer-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 12px 8px 18px; flex: none; }
.layer-title { font-weight: 700; font-size: 15px; }
.layer-body { overflow: auto; padding: 4px 18px 16px; flex: 1; min-height: 0; overscroll-behavior: contain; }
.layer-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 18px; border-top: 1px solid var(--border); flex: none; flex-wrap: wrap; }
.confirm-msg { margin: 4px 0 6px; line-height: 1.7; }
.kv { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; margin: 0; font-size: 12.5px; }
.kv dt { color: var(--text-dim); white-space: nowrap; }
.kv dd { margin: 0; color: var(--text); word-break: break-word; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.info-grid, .imp-grid, .tool-grid { display: grid; grid-template-columns: 260px 1fr; gap: 18px; }
.info-img, .imp-img, .tool-img { position: relative; border-radius: 12px; overflow: hidden; align-self: start; border: 1px solid var(--border); }
.info-img img, .imp-img img, .tool-img img { width: 100%; max-height: 420px; object-fit: contain; }
.info-main, .imp-side, .tool-side { min-width: 0; display: flex; flex-direction: column; gap: 12px; }
.info-block { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
.ib-head { display: flex; justify-content: space-between; align-items: center; padding: 6px 10px; background: var(--surface-2); color: var(--text-dim); font-size: 12px; }
.ib-text { margin: 0; padding: 9px 10px; white-space: pre-wrap; word-break: break-word; font: 12px/1.6 ui-monospace, Menlo, monospace; max-height: 180px; overflow: auto; color: var(--text); }
.ib-char { display: flex; gap: 8px; align-items: baseline; padding: 6px 10px; font-size: 12px; border-top: 1px solid var(--border); }
.ib-char b { color: var(--accent-text); }
.ib-char span { flex: 1; word-break: break-word; }
.ib-char small { color: var(--text-dim); white-space: nowrap; }
.imp-dims { position: absolute; right: 8px; bottom: 8px; font-size: 11px; padding: 2px 8px; border-radius: 999px; background: var(--scrim); color: var(--scrim-text); }
.imp-ok, .imp-none { display: flex; align-items: center; gap: 6px; font-weight: 650; }
.imp-ok { color: var(--success); }
.imp-none { color: var(--text-dim); }
.imp-meta { display: flex; flex-direction: column; gap: 8px; }
.imp-prompt { font-size: 12px; color: var(--text-dim); background: var(--surface-2); border-radius: 9px; padding: 8px 10px; max-height: 96px; overflow: auto; word-break: break-word; font-family: ui-monospace, Menlo, monospace; }
.imp-choices { display: flex; flex-direction: column; gap: 8px; }
.imp-choice { display: flex; align-items: center; gap: 12px; padding: 11px 13px; min-height: 52px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface-2); color: var(--text); text-align: left; }
.imp-choice:hover:not(:disabled) { border-color: var(--accent); }
.imp-choice.primary { border-color: var(--accent); background: var(--accent-soft); }
.imp-choice .ic { color: var(--accent-text); }
.imp-choice:disabled { opacity: .55; }
.imp-choice:disabled .ic { color: var(--text-dim); }
.ic-text { display: flex; flex-direction: column; }
.ic-text b { font-size: 13.5px; }
.ic-text span { font-size: 12px; color: var(--text-dim); }
.tool-desc { margin: 0; color: var(--text-dim); line-height: 1.6; }
.tool-form { display: flex; flex-direction: column; gap: 10px; }
.tool-form .field + .field { margin-top: 0; }
.price-line { display: flex; justify-content: space-between; align-items: center; padding: 10px 12px; border-radius: 10px; background: var(--surface-2); border: 1px solid var(--border); }
.price-line span { color: var(--text-dim); }
.price-val { color: var(--warning); font-size: 15px; }
.price-val.tbd { color: var(--text-dim); }
.emo-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; }
.emo { display: flex; flex-direction: column; align-items: center; padding: 6px 2px; min-height: 44px; border: 1px solid var(--border); border-radius: 9px; background: var(--surface-2); color: var(--text); }
.emo small { color: var(--text-dim); font-size: 10px; }
.emo.on { border-color: var(--accent); background: var(--accent-soft); }
.stepper { flex-direction: row !important; align-items: center; gap: 10px !important; }
.stepper > span:first-child { color: var(--text-dim); font-size: 12px; margin-right: auto; }

/* toast */
.toast { position: fixed; left: 50%; bottom: 28px; z-index: 90; transform: translate(-50%, 20px); opacity: 0; pointer-events: none; max-width: min(560px, calc(100vw - 32px)); padding: 10px 16px; border-radius: 12px; background: var(--text); color: var(--bg); font-size: 13px; box-shadow: var(--shadow); transition: opacity .2s, transform .2s; white-space: pre-line; text-align: center; }
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast.error { background: var(--danger); color: #fff; }
.toast.warn { background: var(--warning); color: var(--bg); }
body.is-mobile .toast { top: auto; bottom: calc(var(--composer-h, 150px) + 16px + env(safe-area-inset-bottom)); transform: translate(-50%, 12px); }
body.is-mobile .toast.show { transform: translate(-50%, 0); }

/* drop overlay */
.drop-overlay { position: fixed; inset: 0; z-index: 80; background: var(--overlay); display: grid; place-items: center; padding: 24px; backdrop-filter: blur(3px); }
.drop-card { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 34px 44px; border-radius: 20px; border: 2px dashed var(--accent); background: var(--surface); color: var(--text); box-shadow: var(--shadow); text-align: center; }
.drop-card .ic { color: var(--accent-text); }
.drop-card span { color: var(--text-dim); }

/* spinner / progress */
.spinner { display: inline-block; width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--surface-3); border-top-color: var(--accent); animation: spin .8s linear infinite; flex: none; }
.spinner.xs { width: 12px; height: 12px; border-width: 2px; }
.spinner.sm { width: 16px; height: 16px; }
.spinner.lg { width: 40px; height: 40px; border-width: 3px; }
.spinner.idle { animation-duration: 2.4s; border-top-color: var(--text-dim); }
@keyframes spin { to { transform: rotate(360deg); } }
.progress { position: relative; height: 4px; border-radius: 4px; background: var(--surface-3); overflow: hidden; }
.progress.indeterminate i { position: absolute; top: 0; bottom: 0; width: 40%; border-radius: 4px; background: linear-gradient(90deg, var(--accent), var(--accent-2)); animation: indet 1.4s ease-in-out infinite; }
@keyframes indet { 0% { left: -40%; } 100% { left: 100%; } }
@media (prefers-reduced-motion: reduce) { .spinner, .progress.indeterminate i { animation-duration: 3s; } }

/* ============================== generate button ============================== */
.gen-btn { position: relative; display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; height: 48px; border: 0; border-radius: 13px; color: var(--on-accent); font-weight: 700; font-size: 15px; background: linear-gradient(135deg, var(--accent), var(--accent-2)); box-shadow: 0 8px 24px var(--accent-soft); transition: filter .15s, transform .05s; }
.gen-btn:disabled, .gen-btn.blocked { opacity: .55; cursor: not-allowed; filter: grayscale(.4); }
.gen-btn:hover { filter: brightness(1.07); }
.gen-btn:active { transform: translateY(1px); }
.gen-cost { font-weight: 600; font-size: 12.5px; padding: 2px 9px; border-radius: 999px; background: rgba(0, 0, 0, .14); white-space: nowrap; font-variant-numeric: tabular-nums; }
[data-theme="light"] .gen-cost { background: rgba(255, 255, 255, .22); }
.gen-queue { position: absolute; top: -8px; right: -4px; font-size: 11px; font-weight: 700; padding: 1px 8px; border-radius: 999px; background: var(--warning); color: #1a1300; box-shadow: 0 2px 6px rgba(0,0,0,.25); }
.gen-sub { margin-top: 8px; }
.gs-row { display: flex; justify-content: space-between; gap: 10px; color: var(--text-dim); font-size: 11.5px; }
.gs-left { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gs-right { white-space: nowrap; font-variant-numeric: tabular-nums; }
.cost-warn { display: flex; gap: 6px; align-items: flex-start; margin-top: 6px; font-size: 12px; color: var(--warning); line-height: 1.5; white-space: pre-wrap; word-break: break-word; }

/* ============================== LAYOUT A: desktop ============================== */
.app { height: 100%; }
.app.desktop { display: flex; flex-direction: column; }
.topbar { height: 54px; flex: none; display: flex; align-items: center; gap: 10px; padding: 0 14px 0 18px; border-bottom: 1px solid var(--border); background: var(--surface); }
.logo { display: flex; align-items: center; gap: 9px; font-weight: 750; font-size: 15px; white-space: nowrap; margin-right: 6px; }
.logo small { font-weight: 500; color: var(--text-dim); font-size: 12px; padding-left: 9px; border-left: 1px solid var(--border); }
.logo-mark { width: 24px; height: 24px; border-radius: 8px; background: linear-gradient(135deg, var(--accent), var(--accent-2)); display: inline-block; box-shadow: 0 4px 12px var(--accent-soft); }
.queue-pill b { color: var(--accent-text); }
.theme-switch { display: inline-flex; padding: 3px; gap: 2px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface-2); }
.ts-btn { display: inline-flex; align-items: center; justify-content: center; gap: 5px; height: 26px; min-width: 30px; padding: 0 8px; border-radius: 999px; border: 0; background: transparent; color: var(--text-dim); font-size: 12.5px; }
.ts-btn:hover { color: var(--text); }
.ts-btn.on { background: var(--surface); color: var(--text); box-shadow: 0 1px 3px rgba(0,0,0,.2), inset 0 0 0 1px var(--border-strong); }
[data-theme="dark"] .ts-btn.on { background: var(--surface-3); }
.theme-switch:not(.compact) { width: 100%; border-radius: 12px; }
.theme-switch:not(.compact) .ts-btn { flex: 1; height: 40px; border-radius: 9px; font-size: 13px; }
.avatar-btn { border-radius: 50%; background: var(--surface-2); border: 1px solid var(--border); }

.main { flex: 1; min-height: 0; display: flex; }
.side { position: relative; width: 360px; flex: none; display: flex; flex-direction: column; background: var(--surface); border-right: 1px solid var(--border); transition: width .2s; }
.side-scroll { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 16px 16px 8px; }
.side-foot { flex: none; padding: 12px 16px 14px; border-top: 1px solid var(--border); background: var(--surface); }
.collapse-btn { position: absolute; right: -13px; top: 16px; z-index: 5; width: 26px; height: 26px; border-radius: 50%; border: 1px solid var(--border-strong); background: var(--surface); color: var(--text-dim); display: grid; place-items: center; padding: 0; box-shadow: 0 2px 6px rgba(0,0,0,.2); }
.collapse-btn:hover { color: var(--text); }
.rail { display: none; flex-direction: column; align-items: center; gap: 8px; padding: 14px 0; }
.side.collapsed { width: 60px; }
.side.collapsed .side-scroll, .side.collapsed .side-foot { display: none; }
.side.collapsed .rail { display: flex; }
.rail-gen { color: var(--on-accent) !important; background: linear-gradient(135deg, var(--accent), var(--accent-2)) !important; width: 40px; height: 40px; border-radius: 12px; }
.sec-group { margin-top: 4px; }

.work { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.stage { position: relative; flex: 1; min-height: 0; overflow: hidden; }
.viewer { position: absolute; inset: 0; overflow: hidden; cursor: default; touch-action: none; }
.viewer.zoomed { cursor: grab; }
.viewer.panning { cursor: grabbing; }
.vw-img { position: absolute; left: 0; top: 0; transform-origin: 0 0; max-width: none; user-select: none; -webkit-user-drag: none; border-radius: 4px; box-shadow: 0 20px 60px rgba(0, 0, 0, .35); background-color: var(--checker-a); background-image: linear-gradient(45deg, var(--checker-b) 25%, transparent 25%, transparent 75%, var(--checker-b) 75%), linear-gradient(45deg, var(--checker-b) 25%, transparent 25%, transparent 75%, var(--checker-b) 75%); background-size: 16px 16px; background-position: 0 0, 8px 8px; image-rendering: auto; }
[data-theme="light"] .vw-img { box-shadow: 0 16px 44px rgba(23, 30, 60, .18); }
.batch-grid { position: absolute; inset: 56px 24px 84px; display: grid; gap: 12px; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: minmax(0, 1fr); }
.batch-grid[data-n="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: 1fr; }
.batch-grid[data-n="2"] { grid-template-rows: 1fr; }
.bg-cell { position: relative; border: 2px solid transparent; border-radius: 12px; overflow: hidden; padding: 0; background: var(--surface); display: grid; place-items: center; min-height: 0; }
.bg-cell img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.bg-cell:hover { border-color: var(--border-strong); }
.bg-cell.on { border-color: var(--accent); }
.bg-idx { position: absolute; left: 8px; top: 8px; width: 22px; height: 22px; border-radius: 7px; display: grid; place-items: center; font-size: 12px; font-weight: 700; background: var(--scrim); color: var(--scrim-text); }
.stage-empty { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; text-align: center; padding: 24px; color: var(--text-dim); }
.stage-empty h2, .feed-empty h2 { margin: 6px 0 2px; color: var(--text); font-size: 18px; }
.stage-empty p, .feed-empty p { margin: 0; max-width: 420px; line-height: 1.7; }
.se-mark { width: 64px; height: 64px; border-radius: 20px; display: grid; place-items: center; color: var(--accent-text); background: var(--accent-soft); }
.stage-badge, .stage-tools, .action-bar, .batch-pager { position: absolute; z-index: 3; background: var(--scrim); color: var(--scrim-text); border: 1px solid var(--scrim-border); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); box-shadow: 0 6px 20px rgba(0, 0, 0, .25); }
.stage-badge { left: 14px; top: 14px; display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 11px; border-radius: 999px; font-size: 12px; }
.stage-badge span + span::before { content: "·"; margin-right: 8px; opacity: .5; }
.stage-badge .cost { color: var(--warning); }
.stage-tools { right: 14px; top: 14px; display: flex; align-items: center; gap: 2px; padding: 3px; border-radius: 12px; }
.stage-tools:empty { display: none; }
.tool-btn { display: inline-flex; align-items: center; gap: 5px; height: 28px; padding: 0 9px; border-radius: 8px; border: 0; background: transparent; color: var(--scrim-text); font-size: 12px; white-space: nowrap; }
.tool-btn:hover, .tool-btn.on { background: rgba(127, 127, 127, .2); }
.tool-btn.icon-only { padding: 0 6px; }
.zoom-label { min-width: 44px; text-align: center; font-size: 11.5px; font-variant-numeric: tabular-nums; opacity: .8; }
.batch-pager { left: 50%; top: 14px; transform: translateX(-50%); display: flex; align-items: center; gap: 4px; padding: 4px; border-radius: 12px; }
.batch-pager .icon-btn { color: var(--scrim-text); }
.pg-thumb { width: 30px; height: 30px; padding: 0; border-radius: 7px; overflow: hidden; border: 2px solid transparent; background: none; opacity: .7; }
.pg-thumb img { width: 100%; height: 100%; object-fit: cover; }
.pg-thumb.on { border-color: var(--accent); opacity: 1; }
.action-bar { left: 50%; bottom: 18px; transform: translateX(-50%); display: flex; align-items: center; gap: 2px; padding: 5px; border-radius: 14px; max-width: calc(100% - 28px); overflow-x: auto; }
.act-btn { display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 11px; border-radius: 9px; border: 0; background: transparent; color: var(--scrim-text); font-size: 12.5px; font-weight: 550; white-space: nowrap; }
.act-btn:hover:not(:disabled) { background: rgba(127, 127, 127, .2); }
.act-btn:first-child { background: var(--accent); color: var(--on-accent); }
.act-btn:first-child:hover:not(:disabled) { background: var(--accent); filter: brightness(1.08); }
.act-btn:disabled { opacity: .45; }
.act-btn.icon-only { padding: 0 9px; }
.act-btn.danger:hover:not(:disabled) { color: var(--danger); }
.act-cost { font-size: 11px; opacity: .75; font-weight: 500; }
.ab-sep { width: 1px; height: 20px; background: var(--scrim-border); margin: 0 3px; flex: none; }

.jobs-box { position: absolute; right: 14px; bottom: 18px; z-index: 4; display: flex; flex-direction: column; gap: 8px; width: 300px; max-height: calc(100% - 80px); overflow: auto; }
.job-card { background: var(--surface); border: 1px solid var(--border); border-radius: 14px; padding: 11px 12px; box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 7px; }
.jc-head { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.jc-head b { white-space: nowrap; }
.jc-sum { color: var(--text-dim); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jc-time { margin-left: auto; color: var(--text-dim); font-size: 12px; font-variant-numeric: tabular-nums; }
.jc-stage { color: var(--text-dim); font-size: 12px; }
.jc-cost { color: var(--warning); font-size: 11.5px; }
.job-card.error { border-color: var(--danger); background: var(--surface); }
.job-card.error .jc-head .ic { color: var(--danger); }
.jc-err, .job-err pre { margin: 0; white-space: pre-wrap; word-break: break-word; font-size: 12px; line-height: 1.55; color: var(--text); background: var(--danger-soft); border-radius: 8px; padding: 8px 10px; max-height: 160px; overflow: auto; font-family: inherit; }
.jc-acts { display: flex; gap: 6px; justify-content: flex-end; }

.strip { flex: none; height: 132px; display: flex; flex-direction: column; border-top: 1px solid var(--border); background: var(--surface); }
.strip-head { display: flex; align-items: center; gap: 6px; padding: 8px 14px 6px; flex: none; }
.strip-title { font-weight: 650; margin-right: auto; white-space: nowrap; }
.strip-title small { color: var(--text-dim); font-weight: 400; }
.strip-sel { color: var(--accent-text); font-size: 12px; margin-right: 6px; }
.strip-list { flex: 1; min-height: 0; display: flex; align-items: center; gap: 8px; padding: 0 14px 10px; overflow-x: auto; overflow-y: hidden; }
.daysep { flex: none; writing-mode: vertical-rl; color: var(--text-dim); font-size: 11px; padding: 0 2px; letter-spacing: 2px; }
.th { position: relative; flex: none; width: 64px; height: 80px; padding: 0; border-radius: 10px; overflow: hidden; border: 2px solid transparent; background: var(--surface-2); transition: border-color .15s, transform .15s; }
.th img { width: 100%; height: 100%; object-fit: cover; }
.th:hover { border-color: var(--border-strong); }
.th.on { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.th.sel { border-color: var(--accent); }
.th-ph { position: absolute; inset: 0; background: var(--surface-3); }
.th-badge { position: absolute; right: 4px; bottom: 4px; font-size: 10px; font-weight: 700; padding: 0 5px; border-radius: 5px; background: var(--scrim); color: var(--scrim-text); }
.th-badge.up { left: 4px; right: auto; }
.th-check { position: absolute; left: 4px; top: 4px; width: 18px; height: 18px; border-radius: 6px; border: 1.5px solid #fff; background: rgba(0,0,0,.35); display: none; place-items: center; color: transparent; }
.strip-list.selecting .th-check { display: grid; }
.th.sel .th-check { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.th.pending { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; border: 1.5px dashed var(--border-strong); background: transparent; color: var(--text-dim); font-size: 11px; }
.strip-empty { color: var(--text-dim); font-size: 12px; padding: 0 6px; }

/* ============================== LAYOUT B: mobile ============================== */
.app.mobile { display: flex; flex-direction: column; height: 100%; height: 100dvh; }
.m-top { flex: none; display: flex; align-items: center; gap: 8px; height: 54px; padding: 0 10px 0 6px; padding-top: env(safe-area-inset-top); border-bottom: 1px solid var(--border); background: var(--surface); }
.m-top .icon-btn { width: 44px; height: 44px; }
.m-top .logo { font-size: 16px; }
.m-top .pill { height: 34px; }
.feed { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; padding: 12px 12px 16px; display: flex; flex-direction: column; gap: 14px; overscroll-behavior: contain; }
.feed > :first-child { margin-top: auto; }
.feed-day { align-self: center; font-size: 11.5px; color: var(--text-dim); background: var(--surface-2); padding: 2px 12px; border-radius: 999px; }
.feed-empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 6px; padding: 30px 12px; color: var(--text-dim); }
.load-more { min-height: 44px; }
.card { background: var(--surface); border: 1px solid var(--border); border-radius: 18px; padding: 12px; display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.card-prompt { margin: 0; font-size: 14px; line-height: 1.55; color: var(--text); word-break: break-word; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; cursor: pointer; }
.card-prompt.open { -webkit-line-clamp: unset; display: block; }
.card-meta { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.card-meta .tag { height: 24px; display: inline-flex; align-items: center; padding: 0 9px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border); color: var(--text-dim); font-size: 11.5px; white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.card-meta .tag.cost { color: var(--warning); border-color: var(--warning-soft); background: var(--warning-soft); }
.card-time { margin-left: auto; color: var(--text-dim); font-size: 11.5px; }
.card-imgs { display: grid; gap: 6px; }
.card-imgs.n1 { grid-template-columns: 1fr; }
.card-imgs.n2, .card-imgs.n4 { grid-template-columns: 1fr 1fr; }
.card-imgs.n3 { grid-template-columns: 1fr 1fr 1fr; }
.tile { display: block; width: 100%; padding: 0; border: 0; border-radius: 12px; overflow: hidden; max-height: 70vh; }
.tile img { width: 100%; height: 100%; object-fit: cover; }
.card-imgs.n1 .tile img { object-fit: contain; }
.card-acts { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin: 0 -4px -4px; }
.c-act { display: inline-flex; align-items: center; gap: 5px; min-height: 44px; padding: 0 10px; border-radius: 10px; border: 0; background: transparent; color: var(--text-dim); font-size: 13px; white-space: nowrap; }
.c-act:hover, .c-act:active { background: var(--surface-2); color: var(--text); }
.c-act.icon-only { width: 44px; justify-content: center; padding: 0; }
.c-act.primary { color: var(--accent-text); background: var(--accent-soft); }
.card.job .job-body { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; border-radius: 12px; background: var(--surface-2); padding: 18px; text-align: center; max-height: 46vh; min-height: 180px; }
.jb-stage { font-size: 14px; }
.jb-time { color: var(--text-dim); font-size: 12px; }
.job-body .progress { width: 66%; }
.card.job.error { border-color: var(--danger); }
.job-err { display: flex; flex-direction: column; gap: 6px; }
.je-head { display: flex; align-items: center; gap: 6px; color: var(--danger); }
.je-head span { margin-left: auto; color: var(--text-dim); font-size: 12px; }

.composer { flex: none; margin: 0 8px 8px; margin-bottom: calc(8px + env(safe-area-inset-bottom)); background: var(--surface); border: 1px solid var(--border-strong); border-radius: 20px; box-shadow: var(--shadow); padding: 8px 8px 10px; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.cmp-box .prompt-ta { border: 0; background: transparent; box-shadow: none; font-size: 15px; min-height: 44px; padding: 10px 8px; }
.cmp-box .prompt-ta:focus { box-shadow: none; }
.cmp-chips { display: flex; gap: 6px; overflow-x: auto; overflow-y: hidden; padding: 2px 2px 4px; scrollbar-width: none; -webkit-overflow-scrolling: touch; min-width: 0; }
.cmp-chips::-webkit-scrollbar { display: none; }
.m-chip { flex: none; display: inline-flex; align-items: center; gap: 5px; height: 44px; padding: 0 13px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); font-size: 13px; white-space: nowrap; }
.m-chip .ic { color: var(--text-dim); }
.m-chip.on { border-color: var(--accent); background: var(--accent-soft); }
.m-chip.on .ic { color: var(--accent-text); }
.m-chip.warn { border-color: var(--warning); color: var(--warning); }
/* model chip (prototype B): accent outline, readable in both themes (the old white-on-tone text lost its
   gradient to .m-chip's background and was nearly invisible in the light theme) */
.m-chip.model { font-weight: 650; color: var(--accent-text); border: 1.5px solid var(--accent); background: var(--accent-soft); }
.m-chip.model .ic { color: var(--accent-text); }
.mc-badge { font-size: 11px; padding: 0 6px; border-radius: 999px; background: var(--accent); color: var(--on-accent); }
.cmp-foot { display: flex; align-items: center; gap: 10px; padding: 0 2px; }
.cmp-bal { flex: 1; min-width: 0; display: flex; flex-direction: column; font-size: 12px; color: var(--text-dim); line-height: 1.35; }
.cmp-bal b { color: var(--success); }
.cmp-bal small { font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmp-bal small.warn { color: var(--warning); white-space: normal; }
.gen-btn.mobile { width: auto; min-width: 150px; height: 48px; padding: 0 18px; flex: none; border-radius: 14px; font-size: 16px; }
.sheet-content .sec:last-child { margin-bottom: 4px; }
.sheet-content .ratio { min-height: 56px; }
.sheet-content .seg-btn { min-height: 40px; font-size: 14px; }
.sheet-content .icon-btn { width: 44px; height: 44px; }
.sheet-content .icon-btn.sm { width: 40px; height: 40px; }
.sheet-content .input { font-size: 16px; min-height: 44px; }
.sheet-content textarea.input { min-height: 64px; }
.sheet-content input[type="range"] { height: 32px; }
.sheet-content input[type="range"]::-webkit-slider-thumb { width: 22px; height: 22px; margin-top: -9px; }
.sheet-content .model-opt { min-height: 56px; }
.sheet-content .btn { min-height: 44px; }
.sheet-content .toggle-field { min-height: 44px; }
.sheet-content .char-head .icon-btn.sm { width: 36px; height: 36px; }
.settings .btn-col { display: flex; flex-direction: column; gap: 8px; }

.m-viewer { position: fixed; inset: 0; z-index: 59; display: flex; flex-direction: column; background: var(--bg); }
.mv-top { display: flex; align-items: center; justify-content: space-between; height: 54px; padding: 0 6px; padding-top: env(safe-area-inset-top); flex: none; }
.mv-top .icon-btn { width: 44px; height: 44px; color: var(--text); }
.mv-count { font-size: 13px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.mv-stage { position: relative; flex: 1; min-height: 0; }
.mv-nav { position: absolute; top: 50%; transform: translateY(-50%); z-index: 3; width: 44px !important; height: 44px !important; border-radius: 50% !important; background: var(--scrim) !important; color: var(--scrim-text) !important; }
.mv-nav.left { left: 8px; } .mv-nav.right { right: 8px; }
.mv-actions { flex: none; display: flex; gap: 2px; overflow-x: auto; padding: 8px 8px calc(10px + env(safe-area-inset-bottom)); border-top: 1px solid var(--border); background: var(--surface); scrollbar-width: none; }
.mv-actions::-webkit-scrollbar { display: none; }
.mv-act { flex: 1 0 auto; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; min-width: 52px; min-height: 56px; padding: 4px 8px; border: 0; border-radius: 12px; background: transparent; color: var(--text); font-size: 11.5px; }
.mv-act:active, .mv-act:hover { background: var(--surface-2); }
.mv-act:disabled { opacity: .4; }
.mv-act.danger { color: var(--danger); }
.mv-act .act-cost { font-size: 10px; color: var(--text-dim); }
.mv-act .ic.dim { display: none; }

body.is-mobile .layer.is-dialog { padding: 12px; }
body.is-mobile .popmenu .pm-item { min-height: 44px; }
body.is-mobile .ac-row { min-height: 44px; }

@media (max-width: 720px) {
    .info-grid, .imp-grid, .tool-grid { grid-template-columns: 1fr; }
    .info-img img, .imp-img img, .tool-img img { max-height: 240px; }
    .emo-grid { grid-template-columns: repeat(4, 1fr); }
    .gen-btn.mobile { min-width: 0; }
}
@media (max-width: 380px) {
    .gen-btn.mobile { padding: 0 12px; font-size: 15px; }
    .gen-btn.mobile > .ic { display: none; }
    .m-top .pill span { display: none; }
}
@media (min-width: 1024px) and (max-width: 1240px) {
    .side { width: 320px; }
    .act-btn { padding: 0 9px; }
    .logo small { display: none; }
}

/* ============================== round 16: settings drawer, job cards ============================== */
.set-group { margin-bottom: 18px; }
.set-title { font-size: 12px; font-weight: 650; color: var(--text-dim); letter-spacing: .02em; margin: 0 0 8px; }
.set-row { display: flex; align-items: center; gap: 10px; min-height: 44px; }
.set-k { color: var(--text-dim); font-size: 13px; flex: none; min-width: 44px; }
.set-v { flex: 1; min-width: 0; text-align: left; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.set-btn { width: 100%; padding: 0 12px; border-radius: 12px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); margin-bottom: 12px; }
.set-btn .ic { color: var(--text-dim); }
.num-stepper { margin-left: auto; display: inline-flex; align-items: center; gap: 4px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface-2); padding: 3px; }
.num-stepper .icon-btn { width: 40px; height: 38px; }
.ns-val { min-width: 54px; text-align: center; font-size: 14px; }
.m-chip.settings-chip { font-weight: 650; }
.jc-cost .no-charge { color: var(--text-dim); }
/* desktop A: compact collapsible groups so 角色 / 参考 stay above the fold at 1440x900 */
.side .folds .fold { margin-bottom: 6px; }
.side .folds .fold-head { padding: 9px 12px; }
.side-scroll > .sec { margin-bottom: 14px; }
.side .folds { margin-top: 0; }
.side .folds .fold-head { padding: 8px 12px; }
/* mobile B: the 设置 chip stays outside the scrolling chip row, so it is reachable even when the chips scroll */
.cmp-chips-wrap { display: flex; align-items: flex-start; gap: 6px; min-width: 0; }
.cmp-chips-wrap > .cmp-chips { flex: 1; min-width: 0; -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 18px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 18px), transparent); }
.cmp-settings { flex: none; padding: 2px 2px 4px 0; }
.cmp-chips-wrap .m-chip { padding: 0 11px; }
.progress.determinate i { position: absolute; left: 0; top: 0; bottom: 0; width: 0; border-radius: 4px; background: linear-gradient(90deg, var(--accent), var(--accent-2)); transition: width 1.6s linear; }

/* ============================== round 18: characters (official per-model positioning) ============================== */
.char-head { gap: 8px; min-width: 0; }
.char-dot { color: #fff; background: var(--char, var(--accent)); text-shadow: 0 1px 1px rgba(0,0,0,.35); }
.char-title { margin-right: 0; flex: none; }
.pos-chip { display: inline-flex; align-items: center; gap: 4px; min-width: 0; max-width: 100%; height: 28px; padding: 0 9px; margin-right: auto; border-radius: 999px;
    border: 1px solid var(--border); background: var(--surface); color: var(--text-dim); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 0 1 auto; }
.pos-chip > span { overflow: hidden; text-overflow: ellipsis; }
.pos-chip.on { border-color: var(--char, var(--accent)); color: var(--text); }
.pos-chip .ic { flex: none; color: var(--char, var(--accent)); }
.char-head .char-enable { flex: none; }
.char-head .icon-btn.sm { flex: none; }
.pos-guides { position: absolute; inset: 0; pointer-events: none;
    background-image: linear-gradient(to right, transparent calc(33.333% - .5px), var(--border) calc(33.333% - .5px), var(--border) calc(33.333% + .5px), transparent calc(33.333% + .5px), transparent calc(66.666% - .5px), var(--border) calc(66.666% - .5px), var(--border) calc(66.666% + .5px), transparent calc(66.666% + .5px)),
                      linear-gradient(to bottom, transparent calc(33.333% - .5px), var(--border) calc(33.333% - .5px), var(--border) calc(33.333% + .5px), transparent calc(33.333% + .5px), transparent calc(66.666% - .5px), var(--border) calc(66.666% - .5px), var(--border) calc(66.666% + .5px), transparent calc(66.666% + .5px)); }
body.is-mobile .pos-board { max-height: 300px; }
body.is-mobile .pos-board.free .pos-dot { width: 34px; height: 34px; font-size: 13px; }
body.is-mobile .pos-chip { height: 32px; }
.char-head-fill { flex: 1; min-width: 0; }   /* V4.5 with one character: no position chip (official canPositionOneCharacter) */

/* ============================== round 18: prompt text / tag-block mode ============================== */
.prompt-wrap.has-mode .prompt-ta { padding-bottom: 28px; }
.pm-toggle-mode { position: absolute; right: 6px; bottom: 6px; z-index: 2; display: inline-flex; padding: 2px; gap: 2px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border); }
.pmt-btn { height: 20px; padding: 0 8px; border: 0; border-radius: 999px; background: transparent; color: var(--text-dim); font-size: 11px; line-height: 20px; }
.pmt-btn.on { background: var(--accent); color: var(--on-accent, #fff); font-weight: 600; }
.tag-ed-wrap { position: relative; }
.tag-ed { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; min-height: 64px; padding: 7px 8px 30px; border: 1px solid var(--border); border-radius: 10px; background: var(--input-bg, var(--surface)); cursor: text; }
.prompt-ta.sm ~ .tag-ed-wrap .tag-ed, .prompt-wrap:has(.prompt-ta.sm) .tag-ed { min-height: 44px; }
.tag-ed:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.tb { position: relative; display: inline-flex; align-items: center; gap: 4px; max-width: 100%; min-height: 28px; padding: 2px 4px 2px 8px; border-radius: 8px; border: 1px solid var(--border);
    background: var(--surface-2); color: var(--text); font-size: 12.5px; line-height: 1.25; cursor: grab; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; touch-action: pan-y; }
.tb:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.tb-main { display: inline-flex; flex-direction: column; min-width: 0; padding: 1px 0; cursor: text; }
.tb-en { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 22ch; }
.tb-zh { font-size: 10.5px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 22ch; }
.tb-w { flex: none; min-width: 26px; padding: 0 5px; height: 18px; line-height: 18px; border-radius: 999px; text-align: center; font-size: 10.5px; font-weight: 700; font-variant-numeric: tabular-nums;
    background: var(--accent-soft); color: var(--accent-text); }
.tb.down .tb-w { background: var(--surface-3); color: var(--text-dim); }
.tb.neg { border-style: dashed; }
.tb.neg .tb-w { background: var(--warning-soft); color: var(--warning); }
.tb.up { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.tb-ctrl { display: inline-flex; gap: 1px; flex: none; }
.tb-btn { display: inline-grid; place-items: center; width: 20px; height: 20px; padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--text-dim); }
.tb-btn:hover { background: var(--surface-3); color: var(--text); }
.tb-btn.x:hover { color: var(--danger, #e5484d); }
/* desktop: −/+ float just above the block's right end on hover/focus, so showing them never reflows the row (no hover flicker)
   and never covers the tag text; they touch the block so the hover is kept while moving onto them */
body.is-desktop .tb .tb-ctrl .tb-btn:not(.x) { display: none; position: absolute; bottom: calc(100% - 3px); z-index: 3; width: 22px; height: 20px; background: var(--surface); box-shadow: 0 0 0 1px var(--border-strong), 0 2px 6px rgba(0,0,0,.18); color: var(--text); }
body.is-desktop .tb .tb-ctrl .tb-btn:nth-child(1) { right: 26px; border-radius: 6px 0 0 6px; }
body.is-desktop .tb .tb-ctrl .tb-btn:nth-child(2) { right: 3px; border-radius: 0 6px 6px 0; }
body.is-desktop .tb:hover .tb-ctrl .tb-btn, body.is-desktop .tb:focus-within .tb-ctrl .tb-btn { display: inline-grid; }
body.is-mobile .tb .tb-ctrl .tb-btn { display: none; }   /* mobile: −/+/× only on the selected block (a stray tap near a short tag must never delete it) */
body.is-mobile .tb.sel .tb-ctrl .tb-btn { display: inline-grid; width: 28px; height: 28px; }
body.is-mobile .tb { min-height: 34px; font-size: 13px; }
.tb.text { background: var(--surface); border-style: dotted; }
.tb.text .tb-en { max-width: 30ch; font-style: italic; }
.tb.editing { padding: 2px; cursor: auto; }
.tb-edit { border: 0; outline: 0; background: transparent; color: var(--text); font: inherit; font-size: 13px; min-width: 6ch; padding: 3px 4px; }
.tb.dragging { opacity: .55; cursor: grabbing; box-shadow: var(--shadow); }
.tb.drop-before { box-shadow: -3px 0 0 0 var(--accent); }
.tb.drop-after { box-shadow: 3px 0 0 0 var(--accent); }
.tb-sep.pipe { color: var(--text-dim); font-weight: 700; padding: 0 2px; }
.tb-br { flex-basis: 100%; height: 0; }
.tb-input { flex: 1 1 90px; min-width: 90px; height: 28px; border: 0; outline: 0; background: transparent; color: var(--text); font: inherit; font-size: 13px; padding: 0 4px; }
.tb-undo { display: inline-flex; align-items: center; gap: 3px; height: 22px; padding: 0 7px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface); color: var(--text-dim); font-size: 11px; }
.cmp-box .tag-ed { border: 0; background: transparent; box-shadow: none; min-height: 44px; padding: 6px 4px 28px; max-height: 132px; overflow-y: auto; }
.cmp-box .tag-ed:focus-within { box-shadow: none; }
.cmp-box .prompt-wrap.has-mode .prompt-ta { padding-bottom: 10px; padding-right: 92px; }
.cmp-box .pm-toggle-mode { top: 6px; bottom: auto; right: 4px; }
.cmp-box .tag-ed { padding: 32px 4px 6px; }
/* mobile: the text/tag toggle keeps its small pill look but gets a 44px touch target (padding outside the painted pill,
   negative margins keep the layout) */
body.is-mobile .pmt-btn { height: 44px; min-width: 44px; margin: -12px 0; padding: 12px 8px; line-height: 20px; background-clip: content-box; border-radius: 20px; }
body.is-mobile .pmt-btn.on { border-radius: 20px; }
body.is-mobile .pm-toggle-mode { overflow: visible; }

/* ==== tagdb ==== tag autocomplete category colours (Danbooru convention: general blue, artist red, copyright purple,
   character green, meta orange; NAI quality words = accent). Used by .ac-dot (both editors) and available as .tc-* elsewhere. */
.ac-dot.tc-0 { background: #4ba3f0; } .ac-dot.tc-1 { background: #f06262; } .ac-dot.tc-3 { background: #c77df0; }
.ac-dot.tc-4 { background: #36c26a; } .ac-dot.tc-5 { background: #f5a524; } .ac-dot.tc-9 { background: var(--accent); }
[data-theme="light"] .ac-dot.tc-0 { background: #0b84d8; } [data-theme="light"] .ac-dot.tc-1 { background: #d42828; }
[data-theme="light"] .ac-dot.tc-3 { background: #9b30c8; } [data-theme="light"] .ac-dot.tc-4 { background: #12963f; }
[data-theme="light"] .ac-dot.tc-5 { background: #d98200; }
.ac-row .ac-zh { min-width: 0; }
.ac-row .ac-cat { white-space: nowrap; font-variant-numeric: tabular-nums; }
/* ==== neg always visible ==== */
/* desktop / drawer: plain always-open field under the prompt, same look as the prompt box */
.neg-sec { padding-top: 2px; }
.neg-field .sec-label .neg-label-r { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.neg-meta { color: var(--text-dim); font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* mobile composer: one compact line under the prompt input; grows (auto-size) while focused */
.cmp-neg { border-top: 1px dashed var(--border); margin: -2px 2px 0; padding-top: 4px; min-width: 0; }
.cmp-neg .neg-row { display: flex; align-items: center; gap: 6px; min-width: 0; padding: 0 4px; }
.cmp-neg .neg-k { display: inline-flex; align-items: center; gap: 3px; flex: none; color: var(--text-dim); font-size: 12px; font-weight: 600; }
.cmp-neg .neg-meta { flex: 1 1 auto; text-align: right; }
.cmp-neg .chip.sm { height: 44px; margin: -10px 0; padding: 0 10px; border: 12px solid transparent; border-left-width: 0; border-right-width: 0; background-clip: padding-box; border-radius: 22px; flex: none; font-size: 12px; }
.cmp-neg .prompt-ta { border: 0; background: transparent; box-shadow: none; font-size: 14px; min-height: 36px; padding: 8px 8px; }
.cmp-neg .prompt-ta:focus { box-shadow: none; }
.cmp-neg .prompt-wrap.has-mode .prompt-ta { padding-bottom: 8px; padding-right: 92px; }
.cmp-neg .pm-toggle-mode { top: 5px; bottom: auto; right: 4px; }
.cmp-neg .tag-ed { border: 0; background: transparent; box-shadow: none; min-height: 36px; padding: 30px 4px 4px; max-height: 110px; overflow-y: auto; }
.cmp-neg .tag-ed:focus-within { box-shadow: none; }
.cmp-neg:not(:focus-within) .prompt-ta { max-height: 36px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.cmp-neg:not(:focus-within) .tag-ed { max-height: 72px; }
.neg-sec .prompt-ta { min-height: 44px; }
.neg-sec .tag-ed { min-height: 44px; }

/* ==== posedit ==== character position editor layer over the preview (ui/charpos.js) */
.pe-layer { position: absolute; inset: 0; z-index: 8; display: flex; flex-direction: column; gap: 10px; padding: 14px 18px; background: var(--bg); }
.pe-layer.mobile { position: fixed; z-index: 66; padding: calc(10px + env(safe-area-inset-top)) 12px calc(10px + env(safe-area-inset-bottom)); }
.pe-top { flex: none; display: flex; justify-content: center; }
.pe-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; max-height: 76px; overflow-y: auto; }
.pe-chip { display: inline-flex; align-items: center; gap: 5px; height: 32px; padding: 0 10px 0 4px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface); color: var(--text-dim); font-size: 12px; max-width: 200px; }
.pe-chip.on { color: var(--text); border-color: var(--char); box-shadow: 0 0 0 1px var(--char) inset; }
.pe-chip.dim { opacity: .5; }
.pe-chip.warn .pe-num { box-shadow: 0 0 0 2px var(--warning); }
.pe-num { display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 999px; background: var(--char); color: #fff; font-weight: 700; font-size: 12px; text-shadow: 0 1px 1px rgba(0,0,0,.35); flex: none; }
.pe-g { font-size: 13px; line-height: 1; }
.pe-g.female { color: #ec4899; } .pe-g.male { color: #3b82f6; }
.pe-lbl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pe-stage { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; }
.pe-frame { position: relative; border-radius: 10px; overflow: hidden; box-shadow: 0 0 0 1px var(--border-strong), 0 10px 30px rgba(0,0,0,.25); background: var(--surface-2); touch-action: none; user-select: none; -webkit-user-select: none; }
.pe-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: fill; pointer-events: none; }
.pe-frame.has-bg .pe-bg { filter: saturate(.85); }
.pe-empty { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; padding-bottom: 12px; gap: 2px; color: var(--text-dim); font-size: 13px;
    background-image: linear-gradient(45deg, var(--surface) 25%, transparent 25%, transparent 75%, var(--surface) 75%), linear-gradient(45deg, var(--surface) 25%, transparent 25%, transparent 75%, var(--surface) 75%);
    background-size: 24px 24px; background-position: 0 0, 12px 12px; }
.pe-empty small { font-size: 11px; opacity: .8; }
.pe-guides { position: absolute; inset: 0; pointer-events: none; }
.pe-guides i { position: absolute; background: rgba(255,255,255,.75); box-shadow: 0 0 0 .5px rgba(0,0,0,.35); }
.pe-guides i.v { top: 0; bottom: 0; width: 1px; } .pe-guides i.hz { left: 0; right: 0; height: 1px; }
.pe-free { position: absolute; inset: 0; cursor: crosshair; }
.pe-dot { display: inline-grid; place-items: center; width: 28px; height: 28px; border-radius: 999px; background: var(--char); color: #fff; font-size: 12px; font-weight: 700; padding: 0;
    border: 2px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,.45); text-shadow: 0 1px 1px rgba(0,0,0,.35); }
.pe-free .pe-dot { position: absolute; transform: translate(-50%, -50%); width: 32px; height: 32px; font-size: 13px; cursor: grab; }
.pe-free .pe-dot:active { cursor: grabbing; }
.pe-layer.mobile .pe-free .pe-dot { width: 38px; height: 38px; font-size: 14px; }
.pe-dot.sel { outline: 3px solid var(--char); outline-offset: 2px; }
.pe-dot.warn { box-shadow: 0 0 0 3px var(--warning); }
.pe-dot.dim { opacity: .55; }
.pe-grid { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(5, 1fr); grid-template-rows: repeat(5, 1fr); }
.pe-cell { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 3px; padding: 0; border: 0; border-right: 1px dashed rgba(255,255,255,.55); border-bottom: 1px dashed rgba(255,255,255,.55);
    background: rgba(0,0,0,.08); min-width: 0; min-height: 0; }
.pe-cell:nth-child(5n) { border-right: 0; } .pe-cell:nth-child(n+21) { border-bottom: 0; }
.pe-cell:hover { background: rgba(124,108,255,.18); }
.pe-cell.on { background: rgba(124,108,255,.28); box-shadow: inset 0 0 0 2px var(--accent); }
.pe-cell.warn { box-shadow: inset 0 0 0 2px var(--warning); }
.pe-frame.empty .pe-cell { border-color: var(--border-strong); }
.pe-bottom { flex: none; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pe-guide { display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 8px; border-radius: 10px; border: 1px solid var(--border); background: var(--surface); color: var(--text-dim); }
.pe-guide-sel { border: 0; background: transparent; color: var(--text); font-size: 12px; outline: none; }
.pe-info { flex: 1; min-width: 0; font-size: 12px; color: var(--text-dim); display: flex; align-items: center; gap: 4px; }
.pe-info b { color: var(--text); }
.pe-info.warn { color: var(--warning); }
.pe-done { height: 40px; padding: 0 18px; font-size: 14px; gap: 6px; }
.pe-layer.mobile .pe-bottom { gap: 8px; }
.pe-layer.mobile .pe-info { order: -1; flex-basis: 100%; justify-content: center; }
.pe-layer.mobile .pe-tip { display: none; }
.pe-layer.mobile .pe-done { flex: 1; height: 44px; }

/* ==== canvas v1 ==== free result canvas (desktop stage + mobile canvas view) */
.cv-stage { background: var(--canvas, var(--bg)); }
.cv { position: absolute; inset: 0; overflow: hidden; touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; cursor: default; outline: none; contain: strict;
    background-image: radial-gradient(circle at 1px 1px, rgba(127, 127, 127, .16) 1px, transparent 0); background-size: 24px 24px; }
.cv.panning, .cv.space-pan { cursor: grabbing; }
.cv.space-pan .cv-item { cursor: grabbing; }
.cv.cv-drop { box-shadow: inset 0 0 0 3px var(--accent); }
.cv-world { position: absolute; left: 0; top: 0; width: 0; height: 0; transform-origin: 0 0; }
.cv-item { position: absolute; cursor: pointer; }
.cv-frame { position: absolute; inset: 0; border-radius: calc(6px * var(--cv-ui, 1)); overflow: hidden; background-color: var(--checker-a);
    background-image: linear-gradient(45deg, var(--checker-b) 25%, transparent 25%, transparent 75%, var(--checker-b) 75%), linear-gradient(45deg, var(--checker-b) 25%, transparent 25%, transparent 75%, var(--checker-b) 75%);
    background-size: 32px 32px; background-position: 0 0, 16px 16px; box-shadow: 0 calc(10px * var(--cv-ui, 1)) calc(36px * var(--cv-ui, 1)) rgba(0, 0, 0, .35); }
[data-theme="light"] .cv-frame { box-shadow: 0 calc(8px * var(--cv-ui, 1)) calc(28px * var(--cv-ui, 1)) rgba(23, 30, 60, .16); }
.cv.far .cv-frame { box-shadow: none; }
.cv-img { display: block; width: 100%; height: 100%; object-fit: fill; pointer-events: none; -webkit-user-drag: none; }
.cv-item:hover .cv-frame { outline: calc(2px * var(--cv-ui, 1)) solid var(--border-strong); }
.cv-item.on .cv-frame { outline: var(--cv-ring, 3px) solid var(--accent); outline-offset: 0; }
.cv-item.dragging { cursor: grabbing; }
.cv-item.dragging .cv-frame { box-shadow: 0 calc(24px * var(--cv-ui, 1)) calc(60px * var(--cv-ui, 1)) rgba(0, 0, 0, .45); outline: var(--cv-ring, 3px) solid var(--accent); }
.cv.dragging-item { cursor: grabbing; }
.cv-badge { position: absolute; left: 0; top: 0; transform: scale(var(--cv-ui, 1)); transform-origin: 0 0; margin: 0; padding: 2px 7px; border-radius: 0 0 8px 0; font-size: 11px; font-weight: 700; background: var(--scrim); color: var(--scrim-text); pointer-events: none; }
/* small per-image bar under the selected image: constant screen size whatever the zoom */
.cv-mini { position: absolute; left: 50%; top: 100%; transform: translateX(-50%) scale(var(--cv-ui, 1)); transform-origin: 50% 0; margin-top: 0; padding-top: 8px; display: flex; gap: 2px; z-index: 2; cursor: default; }
.cv-mini::before { content: ""; position: absolute; inset: 8px 0 0; border-radius: 10px; background: var(--scrim); border: 1px solid var(--scrim-border); box-shadow: 0 6px 18px rgba(0, 0, 0, .25); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); z-index: -1; }
.cv-mb { display: inline-grid; place-items: center; width: 30px; height: 30px; margin: 2px 0; border: 0; border-radius: 8px; background: transparent; color: var(--scrim-text); padding: 0; }
.cv-mb:first-child { margin-left: 3px; } .cv-mb:last-child { margin-right: 3px; }
.cv-mb:hover { background: rgba(127, 127, 127, .22); }
.cv-mb.danger:hover { color: var(--danger); }
.cv-item.cv-locked { cursor: default; }
.cv-ovl { position: absolute; inset: 0; z-index: 3; }
.cv-ph .cv-frame { background: var(--surface-2); background-image: none; outline: calc(2px * var(--cv-ui, 1)) dashed var(--border-strong); }
/* ghosts: where queued / running results will land */
.cv-ghost { position: absolute; pointer-events: none; }
.cv-ghost-cell { position: absolute; border-radius: calc(6px * var(--cv-ui, 1)); border: calc(2px * var(--cv-ui, 1)) dashed var(--border-strong); background: rgba(127, 127, 127, .07); animation: cvPulse 1.6s ease-in-out infinite; }
.cv-ghost.queued .cv-ghost-cell { animation: none; opacity: .6; }
.cv-ghost-label { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(var(--cv-ui, 1)); display: flex; align-items: center; gap: 8px; padding: 6px 12px; border-radius: 999px; background: var(--scrim); color: var(--scrim-text); font-size: 12.5px; white-space: nowrap; }
@keyframes cvPulse { 50% { background: rgba(127, 127, 127, .16); } }
@media (prefers-reduced-motion: reduce) { .cv-ghost-cell { animation: none; } }
.cv-stage .stage-empty { pointer-events: none; z-index: 1; }
.tool-sep { width: 1px; height: 18px; background: var(--scrim-border); margin: 0 3px; }
.tool-btn.help { cursor: help; opacity: .75; }
.strip .th.off-canvas img { opacity: .45; }
.strip .th.off-canvas::after { content: "未在画布"; position: absolute; left: 3px; right: 3px; top: 50%; transform: translateY(-50%); text-align: center; font-size: 10px; font-weight: 600; color: #fff; background: rgba(0, 0, 0, .5); border-radius: 5px; padding: 1px 0; pointer-events: none; }
/* mobile canvas view */
.m-canvas { position: fixed; inset: 0; z-index: 58; display: flex; flex-direction: column; background: var(--bg); }
.mc-top { flex: none; display: flex; align-items: center; gap: 4px; height: 54px; padding: 0 6px; padding-top: env(safe-area-inset-top); border-bottom: 1px solid var(--border); background: var(--surface); }
.mc-top .icon-btn { width: 44px; height: 44px; }
.mc-title { font-weight: 650; margin-right: auto; padding-left: 2px; }
.mc-stage { position: relative; flex: 1; min-height: 0; background: var(--canvas, var(--bg)); }
.mc-hint { position: absolute; left: 50%; top: 10px; transform: translateX(-50%); z-index: 3; padding: 5px 12px; border-radius: 999px; font-size: 12px; white-space: nowrap; background: var(--scrim); color: var(--scrim-text); border: 1px solid var(--scrim-border); pointer-events: none; transition: opacity .4s; }
.mc-hint.hide { opacity: 0; }
.mc-meta { position: absolute; left: 10px; bottom: 10px; z-index: 3; padding: 4px 10px; border-radius: 999px; font-size: 12px; background: var(--scrim); color: var(--scrim-text); border: 1px solid var(--scrim-border); }
.mc-meta:empty { display: none; }
.mc-bar { flex: none; display: flex; gap: 2px; overflow-x: auto; padding: 6px 8px; padding-bottom: calc(6px + env(safe-area-inset-bottom)); border-top: 1px solid var(--border); background: var(--surface); scrollbar-width: none; }
.mc-bar::-webkit-scrollbar { display: none; }
.mc-bar:empty::before { content: "点一下图片选中，长按图片可拖动摆放"; color: var(--text-dim); font-size: 12.5px; padding: 12px 6px; }
.mc-bar .mv-act { color: var(--text); }
.cv.touch .cv-mb { width: 38px; height: 38px; }
.m-top .canvas-btn { gap: 4px; }
/* ==== mobile v2 ==== (approved mock v2: collapsed bar + prompt sheet + 生成设置 sheet) */
.composer.m2 { position: relative; gap: 10px; padding: 16px 10px 10px; }
.m-handle { position: absolute; top: -14px; left: 50%; transform: translateX(-50%); width: 120px; height: 44px; padding: 0; border: 0; background: transparent; cursor: grab; }
.m-handle i { position: absolute; left: 50%; top: 20px; width: 38px; height: 4px; margin-left: -19px; border-radius: 4px; background: var(--border-strong); }
.m-prompt { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 50px; padding: 0 12px; border-radius: 14px; border: 1px solid var(--border); background: var(--input-bg); color: var(--text); font: inherit; font-size: 15px; text-align: left; }
.m-prompt > svg { color: var(--text-dim); flex: none; }
.mp-txt { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.m-prompt.empty .mp-txt { color: var(--text-dim); }
.mp-cnt { flex: none; font-size: 11.5px; color: var(--text-dim); background: var(--surface-2); border: 1px solid var(--border); border-radius: 999px; padding: 2px 8px; white-space: nowrap; }
.m-bottom { display: flex; flex-direction: column; gap: 6px; min-width: 0; width: 100%; }
.m-warn { font-size: 12px; color: var(--warning); padding: 0 2px; }
.m-warn[hidden] { display: none; }
.m-row2 { display: flex; align-items: stretch; gap: 10px; min-width: 0; }
.m-sum { flex: 1; min-width: 0; min-height: 60px; display: flex; align-items: center; gap: 8px; padding: 0 10px 0 12px; border-radius: 14px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); font: inherit; text-align: left; }
.m-sum.warn { border-color: var(--warning); }
.ms-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
.ms-l1 { font-weight: 700; font-size: 14.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ms-l2 { font-size: 12px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ms-cv { flex: none; width: 28px; height: 28px; border-radius: 8px; display: grid; place-items: center; color: var(--text-dim); background: var(--surface); border: 1px solid var(--border); }
.gen-btn.mobile.big { flex: 0 1 auto; max-width: 40%; min-width: 118px; height: auto; min-height: 60px; padding: 6px 12px; border-radius: 16px; flex-wrap: wrap; align-content: center; justify-content: center; row-gap: 1px; column-gap: 6px; }
.gen-btn.mobile.big .gen-label { font-size: 17px; }
.gen-btn.mobile.big .gen-cost { font-size: 12px; padding: 1px 7px; }
.gen-bal { flex-basis: 100%; text-align: center; font-size: 11.5px; font-weight: 500; opacity: .88; }
@media (max-width: 380px) { .gen-btn.mobile.big { min-width: 112px; padding: 6px 8px; } .gen-btn.mobile.big > svg { display: none; } }
/* pinned bottom inside sheets (prompt sheet + 生成设置): same summary + generate */
.layer-panel.sheet.m-pinned .layer-foot, .layer-panel.sheet.m-psheet-panel .layer-foot { display: block; padding: 10px 12px; border-top: 1px solid var(--border); background: var(--surface); }
/* prompt sheet ~75% of the visible viewport; fullscreen = whole viewport, no pinned bottom */
.layer-panel.sheet.m-psheet-panel { height: calc(var(--vvh, 100dvh) * .75); max-height: calc(var(--vvh, 100dvh) - 24px); transition: transform .22s cubic-bezier(.2,.8,.2,1), height .22s cubic-bezier(.2,.8,.2,1); }
.layer-panel.sheet.m-psheet-panel .layer-body { display: flex; flex-direction: column; padding: 4px 12px 10px; }
.layer.kb-open .layer-panel.sheet.m-psheet-panel { height: calc(var(--vvh, 100dvh) - 12px); }
.layer-panel.sheet.m-psheet-panel.full { height: var(--vvh, 100dvh); max-height: none; border-radius: 0; }
.layer-panel.sheet.m-psheet-panel.full .layer-foot, .layer-panel.sheet.m-psheet-panel.full .sheet-grip { display: none; }
.m-psheet { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 8px; }
.mp-head { display: flex; align-items: center; gap: 6px; flex: none; padding-top: 4px; touch-action: pan-x; }
.mp-head .spacer { flex: 1; }
.mt-tabs { display: inline-flex; padding: 3px; gap: 2px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border); max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.mt-tab { flex: none; height: 44px; min-width: 76px; padding: 0 14px; border: 0; border-radius: 999px; background: transparent; color: var(--text-dim); font: inherit; font-size: 14px; font-weight: 600; display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.mt-tab.on { background: var(--surface); color: var(--text); box-shadow: 0 1px 4px rgba(0,0,0,.16); }
.mt-tab[hidden] { display: none; }
.mt-badge { min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px; background: var(--surface-3); color: var(--text-dim); font-size: 11px; line-height: 20px; text-align: center; }
.mt-tab.on .mt-badge { background: var(--accent); color: var(--on-accent, #fff); }
[data-theme="light"] .mt-tab.on .mt-badge { color: #fff; }
.mt-badge[hidden] { display: none; }
.mp-full, .mp-close { width: 44px; height: 44px; }
.mp-done { min-height: 44px; padding: 0 16px; }
.mp-done[hidden], .mp-full[hidden], .mp-close[hidden] { display: none; }
.mp-panes { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.mp-pane { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.mp-pane[hidden] { display: none; }
.mp-pane > .prompt-wrap, .mp-pane > .mp-neg { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.mp-pane > .mp-neg > .prompt-wrap { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.mp-neg { padding: 0; margin: 0; }
.mp-neg .sec-label { margin-bottom: 6px; }
.mp-pane .prompt-ta { flex: 1; min-height: 120px; height: auto !important; max-height: none !important; font-size: 15.5px; line-height: 1.55; resize: none; }
.mp-pane .tag-ed-wrap { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.mp-pane .tag-ed { flex: 1; min-height: 120px; max-height: none; overflow-y: auto; align-content: flex-start; }
.mp-pane .prompt-wrap[hidden], .mp-pane .prompt-ta[hidden] { display: none; }
.mp-hint { display: none; text-align: center; font-size: 12.5px; color: var(--text-dim); padding: 2px 0 calc(4px + env(safe-area-inset-bottom)); }
.m-psheet-panel.full .mp-hint { display: block; }
@media (prefers-reduced-motion: reduce) { .layer-panel.sheet.m-psheet-panel { transition: none; } }
.mp-pane > .mp-pos { flex: 1; min-height: 0; display: flex; flex-direction: column; padding: 0; margin: 0; }
.mp-pane > .mp-pos > .prompt-wrap { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.mp-pos .sec-label, .mp-neg .sec-label { margin-bottom: 6px; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.mp-pos .chip.sm, .mp-neg .chip.sm { min-height: 36px; }
/* ---- mobile v3: character tabs in the prompt sheet; pinned bar flush with the screen bottom ---- */
.layer-panel.sheet.m-pinned .layer-foot, .layer-panel.sheet.m-psheet-panel .layer-foot { padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px)); }
.layer.kb-open .layer-panel.sheet.m-psheet-panel .layer-foot { padding-bottom: 8px; }
.layer-panel.sheet.m-psheet-panel .layer-body { flex: 1 1 auto; min-height: 0; }
.m-psheet { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.mp-panes { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.mp-pane:not([hidden]) { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: auto; }
.mt-scroll { flex: 1 1 auto; min-width: 0; display: flex; }
.mt-scroll .mt-tabs { display: flex; flex: 0 1 auto; min-width: 0; overflow-x: auto; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; }
.mt-scroll .mt-tabs::-webkit-scrollbar { display: none; }
.mt-tab { scroll-snap-align: start; }
.mt-tab.char { min-width: 0; padding: 0 12px 0 8px; }
.mt-tab.char.off { opacity: .55; }
.mt-num { display: inline-grid; place-items: center; min-width: 22px; height: 22px; padding: 0 5px; border-radius: 999px; color: #fff; font-size: 12px; font-weight: 700; line-height: 1; }
.mt-add { flex: none; width: 44px; height: 44px; border: 0; border-radius: 999px; background: transparent; color: var(--text-dim); display: inline-grid; place-items: center; }
.mt-add[hidden] { display: none; }
.mt-add:active { background: var(--surface); }
.mp-full, .mp-close { flex: none; }
.mp-char { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 8px; padding: 0; margin: 0; }
.mp-char > .prompt-wrap:not([hidden]) { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.mp-char > .prompt-wrap[hidden] { display: none; }
.mp-char .prompt-ta { height: auto !important; flex: 1; min-height: 120px; }
.mc-head { display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 6px 0 0; flex-wrap: nowrap; min-width: 0; }
.mc-head .char-dot { flex: none; width: 24px; height: 24px; border-radius: 999px; background: var(--char); color: #fff; display: inline-grid; place-items: center; font-size: 12px; font-weight: 700; }
.mc-head .char-title { flex: none; font-weight: 700; font-size: 14px; white-space: nowrap; }
.mc-head .char-enable { flex: none; display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; cursor: pointer; }
.mc-head .mc-side { flex: none; }
.mc-head .mc-side .seg-btn { min-height: 36px; padding: 0 10px; }
.mc-head .char-head-fill { flex: 1 1 0; min-width: 0; }
.mc-head .pos-chip { flex: 0 1 auto; min-width: 0; max-width: 112px; min-height: 36px; overflow: hidden; }
.mc-head .pos-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mc-head .mc-more { flex: none; width: 44px; height: 44px; margin-right: 0; }
.mp-char.off .prompt-wrap { opacity: .6; }
.mc-note:empty { display: none; }
.m-sum .ms-chars { text-decoration: underline dotted; text-underline-offset: 3px; }
.mt-scroll { align-items: center; gap: 2px; }
.mc-head { gap: 6px; }
.mc-head .char-title { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; font-size: 13px; }
.mc-head .mc-side .seg-btn { padding: 0 9px; font-size: 13px; }
.mc-head .pos-chip { flex: none; max-width: 120px; }
/* autocomplete in the prompt sheet: overlay the lower part of the editor, so it always sits above the pinned bar / keyboard */
.mp-pane .prompt-wrap { position: relative; }
.mp-pane .prompt-wrap > .ac-list, .mp-pane .prompt-wrap .ac-list { top: auto; bottom: 52px; left: 6px; right: 6px; max-height: min(260px, 55%); }
/* ---- fix1: prompt sheet top row = [tab pill incl. '+'] + fullscreen only; tabs fit uncut at 360 / 390 with 2 characters ---- */
.mp-head { gap: 4px; margin: 0 -4px; }
.mt-scroll .mt-tabs { padding: 2px; gap: 0; }
.mt-tab { min-width: 44px; padding: 0 7px; gap: 3px; font-size: 13px; }
.mt-tab .mt-badge { min-width: 16px; height: 18px; padding: 0 4px; font-size: 11px; line-height: 18px; border-radius: 9px; }
.mt-tab.char { padding: 0 7px 0 5px; }
.mt-num { min-width: 18px; height: 18px; padding: 0 4px; font-size: 11px; }
.mt-tabs .mt-add { width: 44px; margin-left: -2px; }
.mp-full { width: 44px; }
.mp-head { margin: 0 -6px; }
.mt-tab { padding: 0 6px; gap: 2px; }
.mt-tab.char { padding: 0 6px 0 4px; gap: 3px; }
.mt-tabs .mt-add { margin-left: -4px; }
/* ==== tagac fix ==== desktop tag autocomplete: no inner focus ring, bottom tool strip, two-line rows, solid whole-row dropdown */
/* (1) the tag input has no ring of its own: the rounded editor already shows focus (.tag-ed:focus-within) */
.tb-input:focus, .tb-input:focus-visible { box-shadow: none; outline: 0; }
/* (2) bottom tool strip inside the editor: 撤销 left, 文本/标签 right, one line under the last tag row */
.tag-ed { padding-bottom: 36px; }
.tb-undo { position: absolute; left: 8px; bottom: 7px; z-index: 2; height: 24px; }
.tb-undo[hidden] { display: none; }
.prompt-wrap.has-mode.tagmode .pm-toggle-mode { bottom: 6px; }
/* (3) rows: line 1 = dot · full English (wraps, never cut) · count; line 2 = Chinese · category */
.ac-row { display: grid; grid-template-columns: 8px minmax(0, 1fr) auto; grid-template-areas: "dot en cnt" ". zh cat"; column-gap: 9px; row-gap: 1px; align-items: baseline; white-space: normal; padding: 7px 12px; min-height: 44px; }
.ac-dot { grid-area: dot; align-self: center; }
.ac-en { grid-area: en; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; line-height: 1.3; }
.ac-row .ac-zh { grid-area: zh; font-size: 12px; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; line-height: 1.3; }
.ac-cnt { grid-area: cnt; font-size: 11.5px; color: var(--text-dim); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ac-row .ac-cat { grid-area: cat; margin: 0; font-size: 10.5px; justify-self: end; opacity: .75; }
.ac-cnt:empty, .ac-row .ac-cat:empty { display: none; }
/* (4) dropdown: solid, above everything in the side panel; JS (fitWholeRows) trims max-height to whole rows */
.ac-list { z-index: 60; background: var(--surface); border-color: var(--border-strong); box-shadow: 0 18px 44px rgba(0,0,0,.45), 0 0 0 1px var(--border); }
[data-theme="light"] .ac-list { box-shadow: 0 18px 44px rgba(20,24,40,.18), 0 0 0 1px var(--border); }
body.is-desktop .ac-list { left: -6px; right: -6px; max-height: min(330px, 52vh); }
.ac-list { scroll-padding-top: 30px; }   /* the sticky header never covers the row scrolled to with ↑ */
/* ==== msettings ==== mobile 生成设置 sheet: header 「✎ 提示词」, compact size (inputs inside 更多), one row per group (accordion) */
.m-to-prompt { height: 44px; margin: -6px -6px -6px 0; padding: 0 12px; border: 6px solid transparent; background-clip: padding-box; box-shadow: inset 0 0 0 1px var(--border); color: var(--text); font-size: 13px; font-weight: 600; gap: 5px; }
.m-to-prompt .ic { color: var(--text-dim); }
.m-gsheet .ratio.open { border-color: var(--border-strong); color: var(--text); }
.m-gsheet .size-more { margin-top: 8px; display: flex; flex-direction: column; gap: 8px; }
.m-gsheet .size-more .dims-row { margin-top: 0; }
.m-gsheet .size-list-btn { display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 12px; justify-content: flex-start; }
.m-gsheet .size-list-btn .sl-cur { margin-left: auto; color: var(--text-dim); font-weight: 400; }
.m-gsheet .size-more .dims-row .dim { min-height: 44px; }
.m-gsheet .size-more .dims-row .icon-btn.sm { width: 44px; height: 44px; }
.m-rows { margin-top: 4px; }
.m-gsheet .m-row-fold { background: var(--surface-2); border-radius: 14px; margin-bottom: 10px; }
.m-gsheet .m-row-fold > .fold-head { min-height: 56px; padding: 0 14px; gap: 10px; font-size: 14.5px; border-radius: 14px; }
.m-gsheet .m-row-fold > .fold-head:hover { background: transparent; }
.m-gsheet .m-row-fold > .fold-head:active { background: var(--surface-3); }
.m-gsheet .m-row-fold .fold-hint { font-size: 12.5px; min-width: 0; }
.m-gsheet .m-row-fold .fold-title { flex: none; }
.m-gsheet .m-row-fold.open > .fold-head { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.m-gsheet .m-row-fold > .fold-body { padding: 4px 14px 14px; }
.m-gsheet .m-row-fold > .fold-body > .sec + .sec { margin-top: 12px; }
/* ==== iOS keyboard ==== sheets pinned to the visual viewport (ui/mobile.js pinToViewport) */
html.m-lock, html.m-lock body { overflow: hidden; overscroll-behavior: none; }
html.m-lock body { position: fixed; inset: 0; width: 100%; }
.layer.kb-open { will-change: transform; }
.layer.kb-open .layer-panel.sheet { padding-bottom: 0; }                       /* keyboard covers the home indicator */
.layer.kb-open .layer-panel.sheet.m-psheet-panel:not(.full) { height: calc(var(--vvh) - 12px); max-height: none; }
.layer.kb-open .layer-panel.sheet.m-psheet-panel .layer-foot { padding-bottom: 8px; }
.layer-panel.sheet.m-psheet-panel { overflow: visible; }
.layer.kb-open .layer-panel.sheet.m-psheet-panel::after { content: ''; position: absolute; left: -1px; right: -1px; top: 100%; height: var(--skirt, 60vh); background: var(--surface); pointer-events: none; }
.layer-panel.sheet.m-psheet-panel.full { padding-top: env(safe-area-inset-top, 0px); }
.layer.kb-open .layer-panel.sheet.m-psheet-panel.full { height: var(--vvh); padding-top: 0; }
.layer.kb-open .layer-panel.sheet.m-psheet-panel.full .mp-panes { min-height: 0; }
/* 生成设置 with the keyboard up (宽 / 高 / 种子): at most the visual viewport, bar on the keyboard top, same skirt */
.layer.kb-open .layer-panel.sheet.m-pinned { position: relative; max-height: calc(var(--vvh) - 12px); overflow: visible; }
.layer.kb-open .layer-panel.sheet.m-pinned .layer-foot { padding-bottom: 8px; }
.layer.kb-open .layer-panel.sheet.m-pinned::after { content: ''; position: absolute; left: -1px; right: -1px; top: 100%; height: var(--skirt, 60vh); background: var(--surface); pointer-events: none; }

/* ===== Liquid Glass layer (v5, 2.4.4). Static material works without js/liquid.js; liquid.js adds refraction (Chromium) + spring motion. ===== */
/* ===== premium Glass v3 "Liquid Glass" — appended after draw2.css (v2 material + v3 lens / motion layer) ===== */
/* ===== premium layer: shared component hooks (all values come from the --p-* / --r-* tokens set per direction) ===== */
body { font-family: var(--font-ui); letter-spacing: var(--ls-ui, 0); font-feature-settings: "kern"; }
.sl-val, .gs-right, .jc-time, .ns-val, .zoom-label, .mv-count, .count-badge, .mp-cnt, .gen-cost, .act-cost, .pill.bal b, .cmp-bal b, .ac-cnt, .input.num { font-variant-numeric: tabular-nums; }
/* radii */
.btn, .input, .seg, .ratio, .note, .tag-ed, .dims-row .dim, .price-line, .imp-choice, .info-block, .num-stepper, .set-btn, .th, .tile, .pe-guide { border-radius: var(--r-md); }
.btn.sm, .icon-btn, .seg-btn, .mini-btn, .tb, .pm-item, .preset-opt, .tool-btn, .act-btn, .cv-mb, .c-act, .mv-act, .ref-thumb { border-radius: var(--r-sm); }
.fold, .fold-head, .model-card, .model-opt, .ref-card, .popmenu, .gen-btn, .stage-tools, .action-bar, .job-card, .ac-list, .drop-zone, .m-prompt, .m-sum, .bg-cell { border-radius: var(--r-lg); }
.card, .composer, .layer-panel.dialog, .drop-card { border-radius: var(--r-xl); }
.layer-panel.sheet { border-radius: var(--r-xl) var(--r-xl) 0 0; }
.layer-panel.sheet.m-psheet-panel.full { border-radius: 0; }
.gen-btn.mobile.big { border-radius: var(--r-lg); }
.pill, .chip, .theme-switch.compact, .ts-btn, .mt-tabs, .mt-tab, .card-meta .tag, .pm-toggle-mode, .pmt-btn, .feed-day, .stage-badge, .pos-chip, .pe-chip, .lock-note, .count-badge, .mp-cnt, .gen-cost, .tb-undo { border-radius: var(--r-pill); }
/* hairlines + elevation */
.topbar, .m-top, .mc-top { border-bottom: 1px solid var(--hair); }
.side { border-right: 1px solid var(--hair); }
.strip, .side-foot, .mv-actions, .mc-bar, .layer-foot { border-top: 1px solid var(--hair); }
.composer { box-shadow: var(--elev-3); }
.popmenu, .ac-list, .job-card, .layer-panel { box-shadow: var(--elev-3); }
.model-card, .model-opt, .fold, .ref-card, .card { box-shadow: var(--elev-1); }
/* focus */
:focus-visible { box-shadow: var(--focus); }
.input:focus, .tag-ed:focus-within, .dims-row .dim:focus-within { border-color: var(--focus-border); box-shadow: var(--focus); }
/* motion: one easing everywhere, short + calm */
.btn, .icon-btn, .chip, .pill, .seg-btn, .ratio, .model-card, .model-opt, .fold-head, .th, .m-chip, .m-sum, .m-prompt, .act-btn, .tool-btn, .gen-btn { transition-timing-function: cubic-bezier(.2, .7, .2, 1); transition-duration: .18s; }
@media (prefers-reduced-motion: reduce) { * { transition-duration: 0s !important; } }
/* section labels: calmer hierarchy */
.sec-label { font-weight: var(--w-label, 650); letter-spacing: var(--ls-label, 0); }
.set-title { letter-spacing: var(--ls-label, .02em); }
.layer-title { font-weight: 650; letter-spacing: .01em; }
/* ---- brand: wordmark ---- */
.logo { gap: 10px; }
.logo > span { font-family: var(--font-brand); font-weight: var(--w-brand, 600); letter-spacing: var(--ls-brand, .02em); font-size: var(--fs-brand, 16px); font-feature-settings: "kern", "liga"; }
.logo small { font-family: var(--font-ui); letter-spacing: .14em; font-size: 11.5px; font-weight: 500; border-left-color: var(--hair); }
.logo-mark { width: 26px; height: 26px; border-radius: 0; background: var(--logo-svg) center / contain no-repeat; box-shadow: var(--logo-glow, none); }
/* ---- header pills ---- */
.topbar .pill, .m-top .pill { background: var(--pill-bg); border-color: var(--pill-border); color: var(--text-dim); font-size: 11.5px; letter-spacing: .06em; gap: 7px; box-shadow: var(--pill-shadow, none); }
.topbar .pill b, .m-top .pill b { font-family: var(--font-display); font-weight: var(--w-pill, 600); color: var(--text); letter-spacing: var(--ls-pill, .01em); font-size: 12.5px; }
.topbar button.pill:hover { border-color: var(--pill-border-hover); }
.pill.bal b { color: var(--bal); }
/* ---- model card ---- */
.mo-text b { font-family: var(--font-display); font-weight: var(--w-model, 600); letter-spacing: var(--ls-model, .01em); font-size: var(--fs-model, 13.5px); }
.mo-text span { letter-spacing: .02em; }
.mo-price { font-family: var(--font-num); font-variant-numeric: tabular-nums lining-nums; color: var(--price); font-weight: 600; letter-spacing: .02em; padding: 2px 9px; border-radius: var(--r-pill); border: 1px solid var(--price-border); background: var(--price-bg); }
.model-opt.on { border-color: var(--sel-border); background: var(--sel-bg); }
.model-badge { --tier: var(--tier-v45); width: 34px; height: 34px; font-family: var(--font-badge); font-weight: var(--w-badge, 700); font-size: var(--fs-badge, 12px); letter-spacing: var(--ls-badge, 0); text-shadow: none; }
.tone-v5, .tone-v5c { --tier: var(--tier-v5); --tier-2: var(--tier-v5-2); }
.tone-v5m { --tier: var(--tier-v5m); --tier-2: var(--tier-v5m-2); }
.tone-v45, .tone-v45c { --tier: var(--tier-v45); --tier-2: var(--tier-v45-2); }
/* ---- primary actions ---- */
.gen-btn { background: var(--gen-bg); color: var(--gen-fg); box-shadow: var(--gen-shadow); letter-spacing: var(--ls-gen, .04em); font-weight: 650; }
.gen-btn .gen-cost { background: var(--gen-cost-bg); color: inherit; font-family: var(--font-num); }
[data-theme="light"] .gen-btn .gen-cost { background: var(--gen-cost-bg); }
.rail-gen { background: var(--gen-bg) !important; color: var(--gen-fg) !important; box-shadow: var(--gen-shadow); }
.btn.primary, .act-btn:first-child { background: var(--gen-bg); color: var(--gen-fg); }
.act-btn:first-child:hover:not(:disabled) { background: var(--gen-bg); }
/* selection */
.seg-btn.on, [data-theme="dark"] .seg-btn.on, .ts-btn.on, [data-theme="dark"] .ts-btn.on, .mt-tab.on { background: var(--seg-on-bg); color: var(--text); box-shadow: var(--seg-on-shadow); }
.chip.on, .ratio.on, .m-chip.on, .emo.on, .imp-choice.primary { border-color: var(--sel-border); background: var(--sel-bg); color: var(--text); }
.th.on { border-color: var(--sel-border); box-shadow: 0 0 0 3px var(--sel-ring); }
.cv-item.on .cv-frame { outline-color: var(--sel-border); }
.fold, [data-theme="dark"] .fold { background: var(--fold-bg); border-color: var(--hair); }
.switch-input:checked + .switch { background: var(--switch-on); border-color: var(--switch-on); }
.switch-input:checked + .switch::after { background: var(--switch-knob); }
input[type="range"]::-webkit-slider-runnable-track { background: linear-gradient(90deg, var(--range) var(--p), var(--surface-3) var(--p)); height: 3px; }
input[type="range"]::-webkit-slider-thumb { border-color: var(--range); margin-top: -6.5px; }
.cv { background-image: radial-gradient(circle at 1px 1px, var(--dot) 1px, transparent 0); }
.m-sum .ms-l1 { font-family: var(--font-display); font-weight: var(--w-model, 600); letter-spacing: var(--ls-model, .01em); }

.tone-v45, .tone-v45c { font-size: calc(var(--fs-badge, 12px) - 1.5px); letter-spacing: -.01em; }

/* ---- Glass v2 ---- */

@font-face { font-family: "RBQ Display G"; src: url("fonts/inter-tight-latin.woff2") format("woff2"); font-weight: 400 700; font-display: swap; unicode-range: U+0020-007E, U+00B7, U+00D7, U+2013-2014; }
:root, [data-theme="dark"] {
  --font-ui: -apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang SC", "Noto Sans SC", "Noto Sans CJK SC", "Microsoft YaHei", system-ui, sans-serif; --font-display: "RBQ Display G", "SF Pro Display", -apple-system, BlinkMacSystemFont, "PingFang SC", "Noto Sans SC", "Noto Sans CJK SC", "Microsoft YaHei", system-ui, sans-serif; --font-brand: "RBQ Display G", "SF Pro Display", -apple-system, BlinkMacSystemFont, "PingFang SC", "Noto Sans SC", "Noto Sans CJK SC", "Microsoft YaHei", system-ui, sans-serif; --font-badge: "RBQ Display G", "SF Pro Display", -apple-system, BlinkMacSystemFont, "PingFang SC", "Noto Sans SC", "Noto Sans CJK SC", "Microsoft YaHei", system-ui, sans-serif; --font-num: "RBQ Display G", "SF Pro Display", -apple-system, BlinkMacSystemFont, "PingFang SC", "Noto Sans SC", "Noto Sans CJK SC", "Microsoft YaHei", system-ui, sans-serif;
  --w-brand: 600; --ls-brand: -.015em; --fs-brand: 16.5px; --w-model: 600; --ls-model: -.012em; --fs-model: 14px; --w-pill: 550; --ls-pill: -.005em;
  --w-label: 600; --ls-label: -.005em; --ls-gen: .01em; --fs-badge: 12.5px; --w-badge: 600; --ls-badge: -.02em;
  --r-sm: 9px; --r-md: 11px; --r-lg: 15px; --r-xl: 22px; --r-pill: 999px;
  --bg: #07090d; --canvas: transparent; --input-bg: rgba(255, 255, 255, .028);
  --surface: rgba(20, 24, 32, .62); --surface-2: rgba(255, 255, 255, .045); --surface-3: rgba(255, 255, 255, .085);
  --text: #eef1f7; --text-dim: #9aa3b5; --border: rgba(255, 255, 255, .075); --border-strong: rgba(255, 255, 255, .14); --hair: rgba(255, 255, 255, .065);
  --accent: #aab8ff; --accent-2: #c9d4ff; --accent-text: #b9c5ff; --accent-soft: rgba(170, 184, 255, .12); --on-accent: #0a0d18;
  --success: #8fe0bf; --warning: #f0cf86; --danger: #ff9c94; --checker-a: rgba(255,255,255,.025); --checker-b: rgba(255,255,255,.05);
  --scrim: rgba(16, 19, 26, .58); --scrim-text: #eef1f7; --scrim-border: rgba(255, 255, 255, .09); --overlay: rgba(3, 4, 7, .55);
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5  0 0 0 0 .5  0 0 0 0 .5  0 0 0 .07 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url%28%23n%29'/%3E%3C/svg%3E");
  /* material levels: L1 = docked panels, L2 = controls on glass, L3 = floating */
  --l1: rgba(17, 20, 27, .58); --l1-solid: #11141b; --l3: rgba(19, 23, 31, .86); --l3-solid: #161a23;
  --blur1: blur(28px) saturate(1.7); --blur3: blur(40px) saturate(1.8);
  --rim-top: rgba(255, 255, 255, .085); --rim-bot: rgba(0, 0, 0, .35);
  --edge: linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,.035) 38%, rgba(255,255,255,.02) 70%, rgba(255,255,255,.07));
  --edge-strong: linear-gradient(170deg, rgba(255,255,255,.34), rgba(255,255,255,.06) 40%, rgba(255,255,255,.03) 70%, rgba(200,215,255,.16));
  --l2-fill: linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.025));
  --l2-fill-hover: linear-gradient(180deg, rgba(255,255,255,.08), rgba(255,255,255,.04));
  --shadow: 0 30px 80px -20px rgba(0, 0, 0, .7), 0 0 0 1px rgba(255,255,255,.06), inset 0 1px 0 var(--rim-top);
  --elev-1: inset 0 1px 0 rgba(255,255,255,.05), inset 0 -1px 0 rgba(0,0,0,.25);
  --elev-3: 0 28px 70px -18px rgba(0, 0, 0, .75), 0 2px 8px rgba(0,0,0,.25), inset 0 1px 0 var(--rim-top), inset 0 -1px 0 var(--rim-bot);
  --focus: 0 0 0 1px rgba(7,9,13,.9), 0 0 0 3px rgba(170, 184, 255, .45); --focus-border: rgba(185, 197, 255, .6);
  --logo-svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cdefs%3E%3ClinearGradient id='r' x1='.1' y1='0' x2='.9' y2='1'%3E%3Cstop offset='0' stop-color='%23ffffff'/%3E%3Cstop offset='.55' stop-color='%23ffffff' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='%23a9bbff' stop-opacity='.95'/%3E%3C/linearGradient%3E%3ClinearGradient id='f' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%233a4663'/%3E%3Cstop offset='1' stop-color='%23121726'/%3E%3C/linearGradient%3E%3CradialGradient id='c' cx='.55' cy='.86' r='.42'%3E%3Cstop offset='0' stop-color='%23d6e0ff' stop-opacity='.95'/%3E%3Cstop offset='1' stop-color='%23d6e0ff' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='k' x1='0' y1='0' x2='1' y2='0'%3E%3Cstop offset='0' stop-color='%239ff3ff' stop-opacity='0'/%3E%3Cstop offset='.5' stop-color='%239ff3ff'/%3E%3Cstop offset='1' stop-color='%23c9b8ff'/%3E%3C/linearGradient%3E%3ClinearGradient id='s' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%23ffffff'/%3E%3Cstop offset='1' stop-color='%23ffffff' stop-opacity='0'/%3E%3C/linearGradient%3E%3CclipPath id='d'%3E%3Cpath d='M12 2.2C12 2.2 18.6 9.3 18.6 14.1A6.6 6.6 0 0 1 5.4 14.1C5.4 9.3 12 2.2 12 2.2Z'/%3E%3C/clipPath%3E%3C/defs%3E%3Cg transform='rotate%2832 12 13%29'%3E%3Cpath d='M12 2.2C12 2.2 18.6 9.3 18.6 14.1A6.6 6.6 0 0 1 5.4 14.1C5.4 9.3 12 2.2 12 2.2Z' fill='url%28%23f%29'/%3E%3Cg clip-path='url%28%23d%29'%3E%3Cellipse cx='12.6' cy='17.4' rx='5.4' ry='3.6' fill='url%28%23c%29'/%3E%3Cpath d='M14.6 20.2A6.6 6.6 0 0 0 18.4 15.4' fill='none' stroke='url%28%23k%29' stroke-width='1.1' stroke-linecap='round' opacity='.9'/%3E%3C/g%3E%3Cpath d='M8.3 14.4C8.1 12 9.6 9.5 11 7.6' fill='none' stroke='url%28%23s%29' stroke-width='1.1' stroke-linecap='round' opacity='.8'/%3E%3Cpath d='M12 2.2C12 2.2 18.6 9.3 18.6 14.1A6.6 6.6 0 0 1 5.4 14.1C5.4 9.3 12 2.2 12 2.2Z' fill='none' stroke='url%28%23r%29' stroke-width='.95'/%3E%3C/g%3E%3C/svg%3E");
  --pill-bg: rgba(255,255,255,.035); --pill-border: rgba(255,255,255,.08); --pill-border-hover: rgba(185,197,255,.35); --pill-shadow: inset 0 1px 0 rgba(255,255,255,.06); --bal: #a6ead0;
  --price: #e4e9ff; --price-border: rgba(255,255,255,.09); --price-bg: linear-gradient(180deg, rgba(255,255,255,.07), rgba(255,255,255,.025));
  --tier-v5: #e9eeff; --tier-v5-2: #a9b9ff; --tier-v5m: #8ff0e6; --tier-v5m-2: #55b8c9; --tier-v45: #c3c9d4; --tier-v45-2: #7d8696;
  --gen-bg: radial-gradient(70% 100% at 50% -10%, rgba(255,255,255,.6), transparent 70%), radial-gradient(80% 120% at 50% 135%, rgba(160, 236, 255, .55), transparent 62%), linear-gradient(180deg, rgba(212, 221, 255, .94), rgba(162, 178, 252, .90)); --gen-ts: 0 1px 0 rgba(255,255,255,.35);
  --gen-fg: #0b1024; --gen-cost-bg: rgba(11, 16, 36, .09);
  --gen-shadow: inset 0 1px 0 #fff, inset 0 -1px 0 rgba(70, 90, 190, .35), inset 0 0 18px rgba(255,255,255,.35), 0 0 0 1px rgba(0,0,0,.45), 0 12px 36px -12px rgba(150, 172, 255, .65), 0 0 46px -18px rgba(170, 200, 255, .8);
  --seg-on-bg: linear-gradient(180deg, rgba(255,255,255,.13), rgba(255,255,255,.07)); --seg-on-shadow: inset 0 1px 0 rgba(255,255,255,.16), 0 1px 3px rgba(0,0,0,.35), 0 0 0 .5px rgba(255,255,255,.08);
  --sel-border: rgba(185, 197, 255, .55); --sel-bg: rgba(170, 184, 255, .08); --sel-ring: rgba(170, 184, 255, .2);
  --fold-bg: transparent; --switch-on: rgba(170, 184, 255, .85); --switch-knob: #ffffff; --range: #aab8ff; --dot: rgba(255, 255, 255, .045);
  /* ambient light: neutral ink + two very soft, low-saturation pools; --amb-img = colour picked from the latest image (static mock: muted rose from the sample set) */
  --amb-cool: rgba(122, 142, 190, .20); --amb-img-rgb: 176, 124, 152; --amb-img: rgba(var(--amb-img-rgb), .12);
  --ambient: radial-gradient(1200px 820px at 12% -18%, var(--amb-cool), transparent 70%), radial-gradient(1100px 900px at 96% 112%, var(--amb-img), transparent 70%), radial-gradient(900px 600px at 55% 45%, rgba(90, 100, 130, .06), transparent 70%), #07090d;
}
[data-theme="light"] {
  --bg: #e8ebf1; --input-bg: rgba(255, 255, 255, .55);
  --surface: rgba(250, 251, 253, .66); --surface-2: rgba(255, 255, 255, .5); --surface-3: rgba(20, 30, 60, .07);
  --text: #11151f; --text-dim: #545d70; --border: rgba(20, 30, 60, .09); --border-strong: rgba(20, 30, 60, .16); --hair: rgba(20, 30, 60, .075);
  --accent: #3b52d4; --accent-2: #5a6fe0; --accent-text: #3346c4; --accent-soft: rgba(59, 82, 212, .09); --on-accent: #ffffff;
  --success: #0b6e4a; --warning: #8a5600; --danger: #bf2e2e; --checker-a: rgba(20,30,60,.03); --checker-b: rgba(20,30,60,.055);
  --scrim: rgba(255, 255, 255, .62); --scrim-text: #11151f; --scrim-border: rgba(255, 255, 255, .85); --overlay: rgba(30, 38, 60, .2);
  --l1: rgba(246, 248, 251, .6); --l1-solid: #f3f5f8; --l3: rgba(250, 251, 253, .84); --l3-solid: #f8f9fb;
  --rim-top: rgba(255, 255, 255, .95); --rim-bot: rgba(20, 30, 60, .06);
  --edge: linear-gradient(180deg, rgba(255,255,255,1), rgba(255,255,255,.55) 40%, rgba(20,30,60,.06) 75%, rgba(20,30,60,.12));
  --edge-strong: linear-gradient(170deg, #ffffff, rgba(255,255,255,.6) 40%, rgba(20,30,60,.08) 75%, rgba(20,30,60,.16));
  --l2-fill: linear-gradient(180deg, rgba(255,255,255,.72), rgba(255,255,255,.48));
  --l2-fill-hover: linear-gradient(180deg, rgba(255,255,255,.9), rgba(255,255,255,.62));
  --shadow: 0 26px 60px -18px rgba(30, 40, 80, .28), 0 0 0 1px rgba(20,30,60,.05), inset 0 1px 0 #fff;
  --elev-1: 0 1px 2px rgba(30,40,80,.06), inset 0 1px 0 rgba(255,255,255,.9);
  --elev-3: 0 26px 60px -18px rgba(30, 40, 80, .3), 0 2px 6px rgba(30,40,80,.06), inset 0 1px 0 #fff, inset 0 -1px 0 var(--rim-bot);
  --focus: 0 0 0 1px rgba(255,255,255,.9), 0 0 0 3px rgba(59, 82, 212, .35); --focus-border: rgba(59, 82, 212, .55);
  --logo-svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cdefs%3E%3ClinearGradient id='r' x1='.1' y1='0' x2='.9' y2='1'%3E%3Cstop offset='0' stop-color='%23ffffff'/%3E%3Cstop offset='.55' stop-color='%23ffffff' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='%233b52d4' stop-opacity='.95'/%3E%3C/linearGradient%3E%3ClinearGradient id='f' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%2356658c'/%3E%3Cstop offset='1' stop-color='%23151b2c'/%3E%3C/linearGradient%3E%3CradialGradient id='c' cx='.55' cy='.86' r='.42'%3E%3Cstop offset='0' stop-color='%23dbe3ff' stop-opacity='.95'/%3E%3Cstop offset='1' stop-color='%23dbe3ff' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='k' x1='0' y1='0' x2='1' y2='0'%3E%3Cstop offset='0' stop-color='%237fe6f5' stop-opacity='0'/%3E%3Cstop offset='.5' stop-color='%237fe6f5'/%3E%3Cstop offset='1' stop-color='%23a99bff'/%3E%3C/linearGradient%3E%3ClinearGradient id='s' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%23ffffff'/%3E%3Cstop offset='1' stop-color='%23ffffff' stop-opacity='0'/%3E%3C/linearGradient%3E%3CclipPath id='d'%3E%3Cpath d='M12 2.2C12 2.2 18.6 9.3 18.6 14.1A6.6 6.6 0 0 1 5.4 14.1C5.4 9.3 12 2.2 12 2.2Z'/%3E%3C/clipPath%3E%3C/defs%3E%3Cg transform='rotate%2832 12 13%29'%3E%3Cpath d='M12 2.2C12 2.2 18.6 9.3 18.6 14.1A6.6 6.6 0 0 1 5.4 14.1C5.4 9.3 12 2.2 12 2.2Z' fill='url%28%23f%29'/%3E%3Cg clip-path='url%28%23d%29'%3E%3Cellipse cx='12.6' cy='17.4' rx='5.4' ry='3.6' fill='url%28%23c%29'/%3E%3Cpath d='M14.6 20.2A6.6 6.6 0 0 0 18.4 15.4' fill='none' stroke='url%28%23k%29' stroke-width='1.1' stroke-linecap='round' opacity='.9'/%3E%3C/g%3E%3Cpath d='M8.3 14.4C8.1 12 9.6 9.5 11 7.6' fill='none' stroke='url%28%23s%29' stroke-width='1.1' stroke-linecap='round' opacity='.8'/%3E%3Cpath d='M12 2.2C12 2.2 18.6 9.3 18.6 14.1A6.6 6.6 0 0 1 5.4 14.1C5.4 9.3 12 2.2 12 2.2Z' fill='none' stroke='url%28%23r%29' stroke-width='.95'/%3E%3C/g%3E%3C/svg%3E");
  --pill-bg: rgba(255,255,255,.5); --pill-border: rgba(255,255,255,.9); --pill-border-hover: rgba(59,82,212,.3); --pill-shadow: 0 1px 2px rgba(30,40,80,.08), inset 0 1px 0 #fff; --bal: #0b6e4a;
  --price: #2b3a9e; --price-border: rgba(255,255,255,.95); --price-bg: linear-gradient(180deg, rgba(255,255,255,.95), rgba(255,255,255,.6));
  --tier-v5: #4258d6; --tier-v5-2: #1b2670; --tier-v5m: #0e8f95; --tier-v5m-2: #0a5a66; --tier-v45: #6a7384; --tier-v45-2: #353c4a;
  --gen-bg: linear-gradient(180deg, rgba(78, 104, 236, .92), rgba(52, 76, 210, .9));
  --gen-fg: #ffffff; --gen-cost-bg: rgba(255, 255, 255, .18); --gen-ts: 0 1px 1px rgba(10, 14, 60, .35);
  --gen-shadow: inset 0 1px 0 rgba(255,255,255,.6), inset 0 -10px 18px -10px rgba(190,205,255,.7), inset 0 0 0 1px rgba(255,255,255,.18), 0 12px 26px -12px rgba(52,76,210,.6), 0 1px 2px rgba(20,30,80,.25);
  --seg-on-bg: linear-gradient(180deg, #ffffff, rgba(255,255,255,.82)); --seg-on-shadow: 0 1px 3px rgba(30,40,80,.12), 0 0 0 .5px rgba(20,30,60,.08), inset 0 1px 0 #fff;
  --sel-border: rgba(59, 82, 212, .5); --sel-bg: rgba(59, 82, 212, .06); --sel-ring: rgba(59, 82, 212, .16);
  --switch-on: #3b52d4; --range: #3b52d4; --dot: rgba(20, 30, 60, .06);
  --amb-cool: rgba(255, 255, 255, .9); --amb-img: rgba(var(--amb-img-rgb), .26);
  --ambient: radial-gradient(1200px 820px at 10% -18%, var(--amb-cool), transparent 70%), radial-gradient(1100px 900px at 96% 112%, var(--amb-img), transparent 70%), radial-gradient(900px 700px at 60% 40%, rgba(170, 185, 215, .25), transparent 70%), #e8ebf1;
}
body { background: var(--ambient); background-attachment: fixed; }
/* ---- L1 docked panels (the ONLY elements with backdrop-filter besides sheets / menus) ---- */
.topbar, .side, .strip, .m-top, .mc-top, .mv-actions, .mc-bar { background: var(--grain), var(--l1); background-size: 160px 160px, auto; -webkit-backdrop-filter: var(--blur1); backdrop-filter: var(--blur1); }
.side-foot { background: transparent; }
.topbar { box-shadow: inset 0 -1px 0 var(--hair), 0 1px 0 rgba(0,0,0,.25); border-bottom-color: transparent; position: relative; z-index: 6; }
.side { box-shadow: inset -1px 0 0 var(--hair); border-right-color: transparent; }
.strip { box-shadow: inset 0 1px 0 var(--hair); border-top-color: transparent; }
/* ---- L3 floating (sheets, menus, mobile bottom bar) ---- */
.composer, .layer-panel, .popmenu, .ac-list { background: var(--grain), var(--l3); background-size: 160px 160px, auto; -webkit-backdrop-filter: var(--blur3); backdrop-filter: var(--blur3); border-color: transparent; box-shadow: var(--elev-3); }
.ac-head { background: transparent; }
.stage-tools, .action-bar, .stage-badge { background: var(--grain), var(--scrim); background-size: 160px 160px, auto; border-color: transparent; box-shadow: 0 12px 30px -10px rgba(0,0,0,.5), inset 0 1px 0 var(--rim-top), inset 0 0 0 1px var(--scrim-border); }
.job-card { background: var(--l3-solid); border-color: transparent; box-shadow: var(--elev-3); }
/* gradient edge light (1px, brighter on top) via mask: no extra DOM */
.composer, .layer-panel, .popmenu, .model-card, .model-opt, .m-sum, .m-prompt, .card, .gen-btn, .action-bar, .stage-tools { position: relative; isolation: isolate; }
.popmenu { position: fixed; } .action-bar, .stage-tools { position: absolute; }
.composer::before, .layer-panel::before, .popmenu::before, .model-card::before, .model-opt::before, .m-sum::before, .m-prompt::before, .card::before, .gen-btn::before, .action-bar::before, .stage-tools::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px; background: var(--edge); pointer-events: none; z-index: 2;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); }
.composer::before, .layer-panel::before, .popmenu::before, .gen-btn::before { background: var(--edge-strong); }
.layer-panel.sheet::before { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
/* ---- L2 controls on glass ---- */
.model-card, .model-opt, .m-sum, .m-prompt, .card { background: var(--l2-fill); border-color: transparent; box-shadow: var(--elev-1); }
.model-card:hover, .model-opt:hover, .m-sum:hover { background: var(--l2-fill-hover); border-color: transparent; }
.card { background: var(--grain), var(--l2-fill); background-size: 160px 160px, auto; }
.input, .tag-ed, .dims-row .dim { background: var(--input-bg); border-color: var(--border); box-shadow: inset 0 1px 2px rgba(0,0,0,.18), inset 0 -1px 0 rgba(255,255,255,.03); }
[data-theme="light"] .input, [data-theme="light"] .tag-ed, [data-theme="light"] .dims-row .dim { box-shadow: inset 0 1px 2px rgba(30,40,80,.06), 0 1px 0 rgba(255,255,255,.8); }
.btn, .chip, .ratio, .seg, .mini-btn, .num-stepper, .theme-switch, .mt-tabs, .fold { border-color: var(--border); }
.btn, .ratio, .chip, .mini-btn { background: var(--l2-fill); box-shadow: inset 0 1px 0 rgba(255,255,255,.05); }
[data-theme="light"] .btn, [data-theme="light"] .ratio, [data-theme="light"] .chip, [data-theme="light"] .mini-btn { box-shadow: 0 1px 2px rgba(30,40,80,.05), inset 0 1px 0 #fff; }
.seg, .theme-switch, .mt-tabs, .pm-toggle-mode { background: rgba(0,0,0,.18); box-shadow: inset 0 1px 2px rgba(0,0,0,.25); }
[data-theme="light"] .seg, [data-theme="light"] .theme-switch, [data-theme="light"] .mt-tabs, [data-theme="light"] .pm-toggle-mode { background: rgba(20,30,60,.055); box-shadow: inset 0 1px 2px rgba(20,30,60,.08); }
.pmt-btn.on { background: var(--seg-on-bg); color: var(--text); box-shadow: var(--seg-on-shadow); }
.fold-head:hover { background: rgba(255,255,255,.03); }
.chip.on, .ratio.on { box-shadow: inset 0 0 0 .5px var(--sel-border), 0 0 18px -6px var(--sel-ring), inset 0 1px 0 rgba(255,255,255,.08); }
/* specular sheen on hover (one gradient sweep, L2 only) */
.model-card::after, .m-sum::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 1; opacity: 0; transition: opacity .35s cubic-bezier(.2,.7,.2,1);
  background: radial-gradient(120% 140% at 20% -30%, rgba(255,255,255,.10), transparent 55%); }
.model-card:hover::after, .m-sum:hover::after { opacity: 1; }
.model-card > *, .model-opt > * { position: relative; z-index: 3; }
/* ---- generate: liquid glass pill ---- */
.gen-btn { border-radius: 999px; -webkit-backdrop-filter: none; text-shadow: var(--gen-ts); font-weight: 650; }
.gen-btn.mobile.big { border-radius: 22px; }
.gen-btn::after { content: ""; position: absolute; left: 18%; right: 18%; top: 1px; height: 30%; border-radius: 999px 999px 60% 60% / 999px 999px 100% 100%; pointer-events: none; z-index: 1;
  background: radial-gradient(50% 100% at 50% 0%, rgba(255,255,255,.55), transparent 70%); opacity: .55; transition: opacity .3s; }
.gen-btn > * { position: relative; z-index: 3; }
.gen-btn:hover:not(:disabled) { filter: brightness(1.08) saturate(1.05); }
.gen-btn:active:not(:disabled) { transform: scale(.985); }
.gen-btn .gen-cost { background: var(--gen-cost-bg); box-shadow: inset 0 1px 0 rgba(255,255,255,.25), inset 0 0 0 .5px rgba(255,255,255,.2); font-weight: 600; }
.gen-queue { z-index: 4; }
/* 2.4.10: '.gen-btn > *' (position: relative) above overrode the badge's absolute position -> it fell into the wrapping
   flex row of the big mobile button and covered '生成'. Pin it to the corner again. */
.gen-btn > .gen-queue { position: absolute; top: -8px; right: -4px; }
.gen-btn.mobile.big > .gen-queue { top: -9px; right: 10px; }
.rail-gen { border-radius: 999px !important; }
.act-btn:first-child { box-shadow: inset 0 1px 0 rgba(255,255,255,.45), inset 0 -6px 12px -6px rgba(210,224,255,.5); text-shadow: var(--gen-ts); }
/* ---- brand ---- */
.logo-mark { width: 26px; height: 26px; filter: drop-shadow(0 2px 6px rgba(120, 145, 255, .22)); box-shadow: none; }
.logo > span { background: linear-gradient(180deg, var(--text) 35%, color-mix(in srgb, var(--text) 62%, var(--accent)) 110%) text; -webkit-background-clip: text; color: transparent; }
.logo small { letter-spacing: .08em; color: var(--text-dim); border-left-color: var(--hair); }
.topbar .pill b, .m-top .pill b { font-variant-numeric: tabular-nums; }
.topbar .pill, .m-top .pill { -webkit-backdrop-filter: none; backdrop-filter: none; }
/* ---- model chip: frosted numeral, thin luminous tier ring ---- */
.model-badge { border-radius: 11px; color: transparent;
  background: linear-gradient(180deg, #ffffff 0%, var(--tier) 55%, var(--tier-2) 120%) text, radial-gradient(120% 90% at 50% 0%, rgba(255,255,255,.16), rgba(255,255,255,.03) 60%) padding-box, color-mix(in srgb, var(--tier) 10%, rgba(10,12,18,.6)) padding-box;
  -webkit-background-clip: text, padding-box, padding-box; background-clip: text, padding-box, padding-box;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tier) 50%, transparent), inset 0 1px 0 rgba(255,255,255,.28), inset 0 -6px 10px -6px color-mix(in srgb, var(--tier) 45%, transparent), 0 0 14px -4px color-mix(in srgb, var(--tier) 45%, transparent); }
[data-theme="light"] .model-badge {
  background: linear-gradient(180deg, var(--tier) 0%, var(--tier-2) 100%) text, radial-gradient(120% 90% at 50% 0%, #ffffff, rgba(255,255,255,.55) 70%) padding-box, color-mix(in srgb, var(--tier) 8%, #f4f6fa) padding-box;
  -webkit-background-clip: text, padding-box, padding-box; background-clip: text, padding-box, padding-box;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tier) 40%, transparent), inset 0 1px 0 #fff, 0 2px 6px -2px color-mix(in srgb, var(--tier) 35%, transparent); }
.mo-price { box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 1px 2px rgba(0,0,0,.2); font-weight: 600; letter-spacing: -.005em; }
[data-theme="light"] .mo-price { box-shadow: 0 1px 2px rgba(30,40,80,.08), inset 0 1px 0 #fff; }
.sec-label { font-family: var(--font-display); }
.mt-tab.on .mt-badge { background: var(--accent); color: var(--on-accent); }
.th { box-shadow: 0 4px 12px -4px rgba(0,0,0,.4); }
.th.on { box-shadow: 0 0 0 2px var(--sel-border), 0 0 18px -2px var(--sel-ring); border-color: transparent; }
.cv-item.on .cv-frame { outline: 2px solid rgba(200,210,255,.7); box-shadow: 0 0 0 6px rgba(170,184,255,.10), 0 18px 50px rgba(0,0,0,.5); }
/* ---- fallbacks + accessibility ---- */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .topbar, .side, .strip, .m-top, .mc-top, .mv-actions, .mc-bar { background: var(--l1-solid); }
  .composer, .layer-panel, .popmenu, .ac-list { background: var(--l3-solid); }
}
@media (prefers-reduced-transparency: reduce) {
  .topbar, .side, .strip, .m-top, .mc-top, .mv-actions, .mc-bar { background: var(--l1-solid); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .composer, .layer-panel, .popmenu, .ac-list { background: var(--l3-solid); -webkit-backdrop-filter: none; backdrop-filter: none; }
  body { background: var(--bg); }
}
@media (prefers-reduced-motion: reduce) { .model-card::after, .m-sum::after, .gen-btn::after { transition: none; } }

/* ================= v3: liquid lens material + spring motion ================= */
:root { --spring: linear(0.0000, 0.0253, 0.0923, 0.1880, 0.3014, 0.4229, 0.5447, 0.6608, 0.7670, 0.8602, 0.9390, 1.0027, 1.0518, 1.0872, 1.1102, 1.1227, 1.1263, 1.1230, 1.1145, 1.1023, 1.0879, 1.0726, 1.0572, 1.0426, 1.0292, 1.0174, 1.0075, 0.9995, 0.9933, 0.9889, 0.9860, 0.9845, 0.9840, 0.9845, 0.9856, 0.9871, 0.9889, 0.9909, 0.9928, 0.9947, 0.9963, 0.9978, 0.9991, 1.0001, 1.0009, 1.0014, 1.0018, 1.0020, 1.0020); --spring-d: 0.61s; --spring-sheet: linear(0.0000, 0.0148, 0.0542, 0.1116, 0.1810, 0.2579, 0.3384, 0.4192, 0.4982, 0.5733, 0.6435, 0.7078, 0.7657, 0.8171, 0.8619, 0.9004, 0.9330, 0.9601, 0.9821, 0.9996, 1.0131, 1.0231, 1.0303, 1.0349, 1.0375, 1.0384, 1.0380, 1.0366, 1.0346, 1.0319, 1.0290, 1.0260, 1.0228, 1.0198, 1.0169, 1.0141, 1.0116, 1.0094, 1.0074, 1.0056, 1.0041, 1.0028, 1.0017, 1.0008, 1.0001, 0.9996, 0.9992, 0.9989, 0.9987); --spring-sheet-d: 0.72s; }
:root, [data-theme="dark"] {
  /* lens rim: brightest at the top-left with a faint chromatic fringe either side, a secondary glint bottom-right */
  --rim-lens: conic-gradient(from -58deg, rgba(255,255,255,.78) 0deg, rgba(160,230,255,.42) 14deg, rgba(255,255,255,.14) 40deg, rgba(255,255,255,.05) 110deg, rgba(255,255,255,.26) 175deg, rgba(255,255,255,.05) 230deg, rgba(255,190,225,.30) 336deg, rgba(255,255,255,.78) 360deg);
  --lg-inner: inset 0 1px 0 rgba(255,255,255,.20), inset 0 10px 14px -12px rgba(255,255,255,.30), inset 0 -10px 16px -12px rgba(150,190,255,.26), inset 0 0 22px rgba(0,0,0,.20);
  --lg-ind: linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,.05));
  --lg-ind-shadow: inset 0 1px 0 rgba(255,255,255,.42), inset 0 -1px 0 rgba(0,0,0,.25), inset 0 0 10px rgba(255,255,255,.06), 0 3px 10px -2px rgba(0,0,0,.45), 0 0 0 .5px rgba(255,255,255,.16);
  --composer-glass: rgba(16, 19, 27, .56); --bar-glass: rgba(16, 19, 26, .50);
}
[data-theme="light"] {
  --rim-lens: conic-gradient(from -58deg, #ffffff 0deg, rgba(150,225,255,.7) 14deg, rgba(255,255,255,.7) 40deg, rgba(20,30,60,.06) 110deg, rgba(20,30,60,.14) 175deg, rgba(20,30,60,.06) 230deg, rgba(255,180,220,.6) 336deg, #ffffff 360deg);
  --lg-inner: inset 0 1px 0 #fff, inset 0 10px 14px -12px rgba(255,255,255,.9), inset 0 -10px 16px -12px rgba(120,150,230,.22), inset 0 0 20px rgba(255,255,255,.35);
  --lg-ind: linear-gradient(180deg, rgba(255,255,255,.62), rgba(255,255,255,.28));
  --lg-ind-shadow: inset 0 1px 0 #fff, inset 0 -1px 0 rgba(20,30,60,.08), 0 3px 10px -3px rgba(30,40,90,.28), 0 0 0 .5px rgba(20,30,60,.10);
  --composer-glass: rgba(250, 251, 253, .58); --bar-glass: rgba(255, 255, 255, .5);
}
/* lens rim on the floating glass (replaces the v2 linear edge) */
.composer::before, .layer-panel::before, .popmenu::before, .gen-btn::before, .action-bar::before, .stage-tools::before { background: var(--rim-lens); }
.composer, .layer-panel, .popmenu, .action-bar, .stage-tools { box-shadow: var(--elev-3), var(--lg-inner); }
.model-card, .model-opt, .m-sum, .m-prompt { box-shadow: var(--elev-1), inset 0 8px 12px -12px rgba(255,255,255,.22); }
/* thinner, clearer floating bars so the content behind can bend through them */
.action-bar, .stage-tools { background: var(--grain), var(--bar-glass); background-size: 160px 160px, auto; -webkit-backdrop-filter: blur(14px) saturate(1.8); backdrop-filter: blur(14px) saturate(1.8); }
.app.mobile > .composer { background: var(--grain), var(--composer-glass); background-size: 160px 160px, auto; }
/* labels on clear glass keep a soft shadow so they stay legible over bright content */
.action-bar .act-btn:not(:first-child), .stage-tools .tool-btn, .stage-tools .zoom-label { text-shadow: 0 1px 2px rgba(0,0,0,.55); }
[data-theme="light"] .action-bar .act-btn:not(:first-child), [data-theme="light"] .stage-tools .tool-btn { text-shadow: 0 0 6px rgba(255,255,255,.9); }
/* Chromium: per-element lens map (liquid.js) -> real refraction at the rim; everyone else keeps the blur above */
.lg-refract-ok .lg-lens { -webkit-backdrop-filter: var(--lg-bf); backdrop-filter: var(--lg-bf); }
/* mobile: let the feed run under the bottom bar (positions at rest are unchanged: the feed gets the same space back as padding) */
.app.mobile > .feed { margin-bottom: calc(-1 * (var(--composer-h, 150px) + 8px + env(safe-area-inset-bottom))); padding-bottom: calc(var(--composer-h, 150px) + 24px + env(safe-area-inset-bottom)); }
.app.mobile > .composer { z-index: 5; }
/* ---- liquid indicator (tabs, segmented controls, theme switch) ---- */
:where(.lg-has-ind) { position: relative; }   /* zero specificity: never overrides an absolutely positioned group (e.g. 文本/标签) */
.lg-ind { position: absolute; left: 0; top: 0; z-index: 2; pointer-events: none; transform-origin: 0 50%; border-radius: var(--r-pill); background: var(--lg-ind); box-shadow: var(--lg-ind-shadow); will-change: transform; opacity: 0; transition: opacity .2s; }
.seg > .lg-ind { border-radius: var(--r-sm); }
[data-theme="light"] .lg-ind { z-index: 0; }   /* light: the white lens sits under the label so text keeps full contrast */
.lg-has-ind > .on, [data-theme="dark"] .lg-has-ind > .on, .mt-tabs.lg-has-ind .mt-tab.on { background: transparent !important; box-shadow: none !important; }
.lg-has-ind > button { position: relative; z-index: 1; }
.mt-tabs.lg-has-ind { overflow-y: hidden; }
/* ---- spring easing everywhere a control reacts ---- */
.chip, .mini-btn, .icon-btn, .tool-btn, .act-btn, button.pill, .ratio, .m-chip, .mt-tab, .seg-btn, .ts-btn, .tb-btn, .pmt-btn, .c-act, .mv-act, .cv-mb {
  transition: transform var(--spring-d) var(--spring), background-color .2s, color .2s, border-color .2s, box-shadow .2s, opacity .2s; }
@media (hover: hover) {
  .chip:hover:not(:disabled), .mini-btn:hover:not(:disabled), .icon-btn:hover:not(:disabled), .tool-btn:hover, .act-btn:hover:not(:disabled), button.pill:hover, .ratio:hover, .m-chip:hover, .mt-tab:hover, .ts-btn:hover, .cv-mb:hover { transform: scale(1.045); }
  .seg-btn:hover:not(:disabled) { transform: scale(1.03); }
}
.chip:active:not(:disabled), .mini-btn:active:not(:disabled), .icon-btn:active:not(:disabled), .tool-btn:active, .act-btn:active:not(:disabled), button.pill:active, .ratio:active, .m-chip:active, .mt-tab:active, .seg-btn:active, .ts-btn:active, .c-act:active, .mv-act:active, .cv-mb:active { transform: scale(.94); transition-duration: .12s; }
.model-card, .m-sum, .m-prompt { transition: transform var(--spring-d) var(--spring), background .25s; }
.model-card:active, .m-sum:active, .m-prompt:active { transform: scale(.985); }
/* ---- generate: CSS-only press spring (no JS); with liquid.js the JS spring owns transform ---- */
.gen-btn { transition: transform var(--spring-d) var(--spring), filter .2s; }
.gen-btn:active:not(:disabled) { transform: scale(1.03, .93); transition-duration: .1s; }
.lg-js .gen-btn { transition: filter .2s; }
.lg-js .gen-btn:active:not(:disabled) { transform: none; }
.lg-clip { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; pointer-events: none; z-index: 2; }
.lg-spec { position: absolute; left: 0; top: 0; width: 160px; height: 160px; margin: -80px 0 0 -80px; border-radius: 50%; background: radial-gradient(closest-side, rgba(255,255,255,.75), rgba(255,255,255,.18) 45%, transparent 75%); opacity: 0; transition: opacity .35s; mix-blend-mode: soft-light; will-change: transform; }
[data-theme="light"] .lg-spec { mix-blend-mode: overlay; }
.gen-btn.lg-lit .lg-spec { opacity: 1; }
.lg-clip::after { content: ""; position: absolute; inset: 0; background: linear-gradient(105deg, transparent 28%, rgba(255,255,255,.55) 46%, rgba(190,235,255,.35) 52%, transparent 70%); transform: translate3d(-110%, 0, 0); opacity: 0; }
.gen-btn.lg-busy .lg-clip::after, .gen-btn:has(.gen-queue:not([hidden])) .lg-clip::after { opacity: 1; animation: lg-flow 1.9s cubic-bezier(.45,.05,.35,1) infinite; }
@keyframes lg-flow { from { transform: translate3d(-110%, 0, 0); } to { transform: translate3d(110%, 0, 0); } }
/* ---- sheets: fluid expand with overshoot + highlight sweep ---- */
.layer-panel.sheet { transform: translate3d(0, 100%, 0) scale(.94, 1); transition: transform .26s cubic-bezier(.4, 0, 1, 1); transform-origin: 50% 100%; }
.layer.open .layer-panel.sheet { transform: none; transition: transform var(--spring-sheet-d) var(--spring-sheet); }
.layer.open .layer-panel.sheet.m-psheet-panel { transition: transform var(--spring-sheet-d) var(--spring-sheet), height .22s cubic-bezier(.2,.8,.2,1); }
.layer-panel.sheet { box-shadow: var(--elev-3), var(--lg-inner), 0 56px 0 0 var(--l3-solid); }
.layer-panel.dialog { transition: transform var(--spring-d) var(--spring); }
.popmenu { animation: lg-pop var(--spring-d) var(--spring) both; transform-origin: 50% 0; }
@keyframes lg-pop { from { opacity: 0; transform: translate3d(0, -6px, 0) scale(.94); } 30% { opacity: 1; } to { opacity: 1; transform: none; } }
.lg-sweep { position: absolute; inset: 0; border-radius: inherit; overflow: hidden; pointer-events: none; z-index: 6; }
.lg-sweep::before { content: ""; position: absolute; left: -10%; right: -10%; top: 0; height: 46%; background: linear-gradient(180deg, transparent, rgba(255,255,255,.10) 45%, rgba(200,230,255,.14) 52%, transparent); transform: translate3d(0, -100%, 0); animation: lg-sweep .9s .12s cubic-bezier(.3,.6,.2,1) both; }
[data-theme="light"] .lg-sweep::before { background: linear-gradient(180deg, transparent, rgba(255,255,255,.55) 48%, transparent); }
@keyframes lg-sweep { from { transform: translate3d(0, -100%, 0); opacity: 1; } to { transform: translate3d(0, 240%, 0); opacity: 0; } }
/* ---- ambient light drifts (desktop stage only, so the docked panels never re-blur) ---- */
.stage::before { content: ""; position: absolute; inset: -25%; pointer-events: none; z-index: 0;
  background: radial-gradient(40% 35% at 30% 30%, rgba(122, 142, 190, .10), transparent 70%), radial-gradient(35% 40% at 72% 70%, rgba(var(--amb-img-rgb), .10), transparent 70%);
  animation: lg-drift 36s ease-in-out infinite alternate; will-change: transform; }
[data-theme="light"] .stage::before { background: radial-gradient(40% 35% at 30% 30%, rgba(255,255,255,.7), transparent 70%), radial-gradient(35% 40% at 72% 70%, rgba(var(--amb-img-rgb), .22), transparent 70%); }
@keyframes lg-drift { 0% { transform: translate3d(-3%, -2%, 0) scale(1); } 50% { transform: translate3d(3%, 2%, 0) scale(1.06); } 100% { transform: translate3d(-1%, 3%, 0) scale(1.02); } }
/* ---- logo: liquid highlight runs through the droplet on hover ---- */
.logo-mark { position: relative; overflow: hidden; filter: none; -webkit-mask: var(--logo-svg) center / contain no-repeat; mask: var(--logo-svg) center / contain no-repeat; }
.logo-mark::after { content: ""; position: absolute; inset: -30%; background: linear-gradient(125deg, transparent 38%, rgba(255,255,255,.85) 48%, rgba(170,230,255,.55) 53%, transparent 62%); transform: translate3d(-90%, -60%, 0); }
.logo:hover .logo-mark::after, .logo-mark.lg-demo::after { animation: lg-logo 1.1s cubic-bezier(.3,.7,.2,1) both; }
@keyframes lg-logo { from { transform: translate3d(-90%, -60%, 0); } to { transform: translate3d(90%, 60%, 0); } }
/* ---- accessibility / fallbacks ---- */
@media (prefers-reduced-motion: reduce) {
  .stage::before, .gen-btn .lg-clip::after, .lg-sweep::before, .logo-mark::after, .popmenu { animation: none !important; }
  .layer-panel.sheet, .layer.open .layer-panel.sheet { transition: opacity .15s !important; transform: none; }
  .chip, .mini-btn, .icon-btn, .tool-btn, .act-btn, button.pill, .ratio, .m-chip, .mt-tab, .seg-btn, .ts-btn, .gen-btn, .model-card, .m-sum { transform: none !important; }
}
@media (prefers-reduced-transparency: reduce) {
  .action-bar, .stage-tools, .app.mobile > .composer { background: var(--l3-solid); -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
  .stage::before { display: none; }
}
@media (pointer: coarse) { .stage::before { animation: none; } }

/* ===== v3.1: desktop gets the same liquid language ===== */
/* indicator flavours: accent pill for 文本/标签, tinted lens-ring for the size cards */
.pm-toggle-mode.lg-has-ind > .lg-ind { background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 88%, #fff), var(--accent)); box-shadow: inset 0 1px 0 rgba(255,255,255,.45), 0 2px 8px -2px color-mix(in srgb, var(--accent) 70%, transparent); z-index: 0; }
.pm-toggle-mode.lg-has-ind > .pmt-btn { z-index: 1; }
body.is-mobile .pm-toggle-mode > .lg-ind { top: 2px !important; height: 20px !important; }   /* mobile buttons are 44px hit targets with a clipped 20px pill */
.pm-toggle-mode.lg-has-ind > .pmt-btn.on { color: var(--on-accent, #fff); }
.ratios.lg-has-ind > .lg-ind { border-radius: 10px; background: color-mix(in srgb, var(--accent) 12%, transparent); box-shadow: inset 0 0 0 1px var(--accent), inset 0 1px 0 rgba(255,255,255,.22), 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent), 0 6px 16px -6px color-mix(in srgb, var(--accent) 55%, transparent); }
.ratios.lg-has-ind > .ratio.on { border-color: transparent; background: var(--l2-fill) !important; }
/* collapsibles: body flows in with the spring, chevron springs round */
.fold-arrow { transition: transform var(--spring-d) var(--spring); }
.fold.open > .fold-body { position: relative; animation: lg-unfold var(--spring-d) var(--spring) both; transform-origin: 50% 0; }
@keyframes lg-unfold { from { opacity: 0; transform: translate3d(0, -10px, 0) scale(.97, .9); } 35% { opacity: 1; } to { opacity: 1; transform: none; } }
.fold-head { transition: transform var(--spring-d) var(--spring), background-color .2s; }
.fold-head:active { transform: scale(.985); }
/* dropdown / popover close: a ghost copy drains away (the real menu is already gone) */
.popmenu.lg-ghost { pointer-events: none; animation: lg-pop-out .2s cubic-bezier(.4,0,.8,.4) both !important; }
@keyframes lg-pop-out { to { opacity: 0; transform: translate3d(0, -4px, 0) scale(.95, .9); } }
.model-opt { transition: transform var(--spring-d) var(--spring), background-color .15s; }
@media (hover: hover) { .model-opt:hover { transform: translate3d(2px,0,0); } }
/* primary buttons share the generate press */
:where(.btn.primary) { position: relative; }
.btn.primary.lg-lit .lg-spec { opacity: .8; }
/* canvas: one liquid selection ring that morphs between images */
.lg-ring { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 99990; border-radius: calc(6px * var(--cv-ui, 1)); opacity: 0; transition: opacity .18s;
  box-shadow: 0 0 0 var(--cv-ring, 3px) var(--accent), 0 0 0 calc(var(--cv-ring, 3px) + 5px * var(--cv-ui, 1)) color-mix(in srgb, var(--accent) 20%, transparent), inset 0 0 calc(18px * var(--cv-ui, 1)) rgba(255,255,255,.18); will-change: transform; }
.lg-ring::after { content: ""; position: absolute; inset: calc(-1 * var(--cv-ring, 3px)); border-radius: inherit; padding: var(--cv-ring, 3px); background: var(--rim-lens); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); opacity: .8; }
.lg-ring.on { opacity: 1; }
.cv-world.lg-ring-on .cv-item.on:not(.dragging) .cv-frame { outline-color: transparent; }
@media (prefers-reduced-motion: reduce) {
  .fold.open > .fold-body, .popmenu.lg-ghost { animation: none !important; }
  .popmenu.lg-ghost { display: none; }
  .fold-arrow, .fold-head, .model-opt { transition: none !important; }
}

/* ================= v4: Apple-grade liquid glass material (stills pass) ================= */
:root, [data-theme="dark"] {
  /* rim: light pools in the top-left and bottom-right corners, sides stay a hairline (works for any aspect ratio) */
  --rim4: radial-gradient(90px 46px at 0 0, rgba(255,255,255,.95), rgba(255,255,255,0) 70%),
          radial-gradient(80px 40px at 100% 100%, rgba(255,255,255,.55), rgba(255,255,255,0) 70%),
          radial-gradient(60px 30px at 100% 0, rgba(170,225,255,.30), rgba(255,255,255,0) 70%),
          linear-gradient(rgba(255,255,255,.16), rgba(255,255,255,.10));
  /* body: thick glass = bright inner bevel top-left, softer bevel bottom-right, faint inner caustic, no muddy inner shadow */
  --bevel4: inset 1.5px 1.5px 1px -1px rgba(255,255,255,.55), inset -1.5px -1.5px 1px -1px rgba(255,255,255,.28),
            inset 0 0 0 .5px rgba(255,255,255,.08), inset 0 14px 22px -18px rgba(255,255,255,.35), inset 0 -16px 24px -20px rgba(160,200,255,.30);
  --float4: 0 1px 1px rgba(0,0,0,.25), 0 10px 30px -8px rgba(0,0,0,.55), 0 24px 60px -24px rgba(0,0,0,.45);
  --clear4: rgba(30, 34, 46, .30);        /* floating bars: clear glass, lighter than the stage */
  --clear4-mob: rgba(30, 34, 46, .30);
  --ind4: linear-gradient(180deg, rgba(255,255,255,.22), rgba(255,255,255,.08));
  --ind4-shadow: inset 1.5px 1.5px 1px -1px rgba(255,255,255,.75), inset -1px -1px 1px -.5px rgba(255,255,255,.35), inset 0 0 0 .5px rgba(255,255,255,.14), inset 0 0 12px rgba(255,255,255,.06), 0 4px 12px -4px rgba(0,0,0,.55);
}
[data-theme="light"] {
  --rim4: radial-gradient(90px 46px at 0 0, #fff, rgba(255,255,255,0) 70%), radial-gradient(80px 40px at 100% 100%, rgba(255,255,255,.95), rgba(255,255,255,0) 70%),
          linear-gradient(rgba(20,30,60,.10), rgba(20,30,60,.14));
  --bevel4: inset 1.5px 1.5px 1px -1px #fff, inset -1.5px -1.5px 1px -1px rgba(255,255,255,.9), inset 0 14px 22px -18px rgba(255,255,255,.95), inset 0 -16px 24px -20px rgba(120,150,230,.18);
  --float4: 0 1px 1px rgba(20,30,60,.08), 0 10px 30px -10px rgba(30,40,90,.25), 0 24px 60px -28px rgba(30,40,90,.25);
  --clear4: rgba(255, 255, 255, .42); --clear4-mob: rgba(250, 251, 253, .50);
  --ind4: linear-gradient(180deg, rgba(255,255,255,.9), rgba(255,255,255,.55));
  --ind4-shadow: inset 1.5px 1.5px 1px -1px #fff, 0 0 0 .5px rgba(20,30,60,.10), 0 4px 12px -5px rgba(30,40,90,.35);
}
.composer::before, .layer-panel::before, .popmenu::before, .action-bar::before, .stage-tools::before { background: var(--rim4); }
.composer, .popmenu, .action-bar, .stage-tools { box-shadow: var(--float4), var(--bevel4); }
.action-bar::before, .stage-tools::before, .composer::before, .popmenu::before { padding: 1.5px; }
/* top specular strip: the 'wet' highlight that sells thickness */
.action-bar::after, .stage-tools::after { content: ""; position: absolute; left: 10px; right: 10px; top: 1.5px; height: 42%; border-radius: inherit; pointer-events: none; z-index: 1; background: linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,0)); -webkit-mask: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent); mask: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent); }
[data-theme="light"] .action-bar::after, [data-theme="light"] .stage-tools::after { background: linear-gradient(180deg, rgba(255,255,255,.7), rgba(255,255,255,0)); }
.layer-panel { box-shadow: 0 -10px 40px -10px rgba(0,0,0,.5), var(--bevel4); }
.action-bar, .stage-tools { background: var(--clear4); -webkit-backdrop-filter: blur(9px) saturate(1.9) brightness(1.12); backdrop-filter: blur(9px) saturate(1.9) brightness(1.12); }
[data-theme="light"] .action-bar, [data-theme="light"] .stage-tools { -webkit-backdrop-filter: blur(9px) saturate(1.8) brightness(1.04); backdrop-filter: blur(9px) saturate(1.8) brightness(1.04); }
.app.mobile > .composer { background: var(--clear4-mob); }
.lg-refract-ok .lg-lens { -webkit-backdrop-filter: var(--lg-bf); backdrop-filter: var(--lg-bf); }
/* labels on clear glass: soft vibrancy halo instead of a hard drop shadow */
.action-bar .act-btn:not(:first-child), .stage-tools .tool-btn, .stage-tools .zoom-label { text-shadow: 0 0 1px rgba(0,0,0,.55), 0 0 8px rgba(0,0,0,.55); }
/* indicator: a real little lens */
.lg-ind { background: var(--ind4); box-shadow: var(--ind4-shadow); }
/* generate: tinted liquid glass (icy body you can sense depth in), crisp rim, inner caustic */
[data-theme="dark"] .gen-btn, :root:not([data-theme="light"]) .gen-btn {
  background: radial-gradient(120% 140% at 30% -20%, rgba(255,255,255,.95), rgba(255,255,255,0) 55%),
              radial-gradient(90% 120% at 85% 130%, rgba(150,225,255,.55), rgba(150,225,255,0) 60%),
              linear-gradient(180deg, #e9f1ff, #b9c9f3);
  box-shadow: 0 10px 30px -10px rgba(150,190,255,.55), 0 2px 6px -2px rgba(0,0,0,.5), inset 1.5px 1.5px 1px -1px #fff, inset -1.5px -2px 2px -1px rgba(90,120,200,.45), inset 0 -10px 18px -10px rgba(110,150,240,.45);
}
.gen-btn::before { background: radial-gradient(90px 40px at 0 0, #fff, rgba(255,255,255,0) 70%), radial-gradient(80px 40px at 100% 100%, rgba(255,255,255,.9), rgba(255,255,255,0) 70%), linear-gradient(rgba(255,255,255,.45), rgba(120,150,230,.35)); }
[data-theme="light"] .gen-btn {
  background: radial-gradient(120% 140% at 30% -20%, rgba(255,255,255,.55), rgba(255,255,255,0) 50%), radial-gradient(90% 120% at 85% 130%, rgba(120,200,255,.55), rgba(120,200,255,0) 60%), linear-gradient(180deg, #4f6ff0, #3550d8);
  box-shadow: 0 10px 26px -10px rgba(53,80,216,.6), inset 1.5px 1.5px 1px -1px rgba(255,255,255,.85), inset 0 -10px 18px -10px rgba(20,30,120,.45);
}
/* generating: the flow must read on an icy pill -> a cool caustic band, not white-on-white */
.gen-btn .lg-clip::after { background: linear-gradient(105deg, transparent 30%, rgba(120,170,255,.0) 36%, rgba(110,165,255,.55) 45%, rgba(255,255,255,.95) 50%, rgba(170,140,255,.45) 56%, transparent 66%); mix-blend-mode: normal; }
[data-theme="light"] .gen-btn .lg-clip::after { background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,.0) 36%, rgba(255,255,255,.45) 47%, rgba(190,230,255,.7) 50%, rgba(255,255,255,.35) 55%, transparent 66%); }
/* mobile bar: inner controls become lighter glass chips, not dark wells */
.app.mobile > .composer .m-prompt, .app.mobile > .composer .m-sum { background: rgba(255,255,255,.07); box-shadow: inset 1px 1px 1px -.5px rgba(255,255,255,.35), inset 0 0 0 .5px rgba(255,255,255,.08), 0 2px 8px -3px rgba(0,0,0,.4); -webkit-backdrop-filter: none; backdrop-filter: none; }
[data-theme="light"] .app.mobile > .composer .m-prompt, [data-theme="light"] .app.mobile > .composer .m-sum { background: rgba(255,255,255,.55); box-shadow: inset 1px 1px 1px -.5px #fff, 0 0 0 .5px rgba(20,30,60,.08); }
/* canvas ring: thinner, glassier */
.lg-ring { box-shadow: 0 0 0 calc(var(--cv-ring, 3px) * .75) rgba(235,242,255,.92), 0 0 0 calc(var(--cv-ring, 3px) + 6px * var(--cv-ui, 1)) rgba(150,190,255,.16), 0 calc(14px * var(--cv-ui,1)) calc(40px * var(--cv-ui,1)) rgba(0,0,0,.4); }
[data-theme="light"] .lg-ring { box-shadow: 0 0 0 calc(var(--cv-ring, 3px) * .75) var(--accent), 0 0 0 calc(var(--cv-ring, 3px) + 6px * var(--cv-ui, 1)) color-mix(in srgb, var(--accent) 16%, transparent); }

/* ================= v5: glass on the floating control layer only ================= */
:root, [data-theme="dark"] {
  --g5-fill: linear-gradient(180deg, rgba(255,255,255,.13), rgba(255,255,255,.045));
  --g5-fill-hi: linear-gradient(180deg, rgba(255,255,255,.20), rgba(255,255,255,.07));
  --g5-edge: inset 1px 1px 0 -.5px rgba(255,255,255,.50), inset -1px -1px 0 -.5px rgba(255,255,255,.20), inset 0 0 0 .5px rgba(255,255,255,.09), 0 2px 8px -3px rgba(0,0,0,.55);
  --g5-rim: radial-gradient(40px 22px at 0 0, rgba(255,255,255,.85), rgba(255,255,255,0) 70%), radial-gradient(36px 20px at 100% 100%, rgba(255,255,255,.45), rgba(255,255,255,0) 70%), linear-gradient(rgba(255,255,255,.10), rgba(255,255,255,.06));
  --g5-sheen: rgba(255,255,255,.22);
  --g5-trough: inset 0 1px 2px rgba(0,0,0,.38), inset 0 -.5px 0 rgba(255,255,255,.12), inset 0 0 0 .5px rgba(255,255,255,.05);
  --g5-pop: rgba(22, 26, 36, .70);
  --drop: radial-gradient(circle at 50% 118%, rgba(160,205,255,.55), rgba(160,205,255,0) 58%), radial-gradient(circle at 34% 26%, #fff 0 16%, rgba(255,255,255,0) 52%), rgba(232,240,255,.80);
  --drop-shadow: inset 0 0 0 .5px rgba(255,255,255,.9), inset 0 -1.5px 2px rgba(70,100,190,.35), 0 1px 3px rgba(0,0,0,.45), 0 3px 8px -2px rgba(0,0,0,.35);
}
[data-theme="light"] {
  --g5-fill: linear-gradient(180deg, rgba(255,255,255,.85), rgba(255,255,255,.55));
  --g5-fill-hi: linear-gradient(180deg, #fff, rgba(255,255,255,.75));
  --g5-edge: inset 1px 1px 0 -.5px #fff, inset 0 0 0 .5px rgba(20,30,60,.10), 0 2px 8px -4px rgba(30,40,90,.30);
  --g5-rim: radial-gradient(40px 22px at 0 0, #fff, rgba(255,255,255,0) 70%), linear-gradient(rgba(20,30,60,.08), rgba(20,30,60,.12));
  --g5-sheen: rgba(255,255,255,.85);
  --g5-trough: inset 0 1px 2px rgba(20,30,60,.14), inset 0 -.5px 0 rgba(255,255,255,.9);
  --g5-pop: rgba(255, 255, 255, .74);
  --drop: radial-gradient(circle at 50% 118%, rgba(120,170,255,.45), rgba(120,170,255,0) 58%), radial-gradient(circle at 34% 26%, #fff 0 18%, rgba(255,255,255,0) 52%), rgba(255,255,255,.88);
  --drop-shadow: inset 0 0 0 .5px rgba(20,30,60,.18), inset 0 -1.5px 2px rgba(60,90,180,.25), 0 1px 3px rgba(20,30,60,.30), 0 3px 8px -2px rgba(20,30,60,.22);
}
/* --- floating glass buttons: shared mechanics (rim mask in ::before, pointer sheen in background) --- */
.topbar .pill, .topbar .avatar-btn, .m-top .pill, .m-top > .icon-btn, .stage-tools .tool-btn:not(.help), .action-bar .act-btn:not(:first-child), .cv-mb, .mt-add, .mp-full, .m-to-prompt { position: relative; isolation: isolate; }
.topbar .pill::before, .topbar .avatar-btn::before, .m-top .pill::before, .m-top > .icon-btn::before, .stage-tools .tool-btn:not(.help)::before, .action-bar .act-btn:not(:first-child)::before, .cv-mb::before, .mt-add::before, .mp-full::before, .m-to-prompt::before { content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px; background: var(--g5-rim); pointer-events: none; z-index: -1;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); transition: opacity .25s; }
.topbar .pill, .topbar .avatar-btn, .m-top .pill, .m-top > .icon-btn, .m-to-prompt { background: radial-gradient(70px 44px at var(--mx, 30%) var(--my, -40%), var(--g5-sheen), transparent 70%) no-repeat, var(--g5-fill); background-size: 100% 100%; border-color: transparent; box-shadow: var(--g5-edge); }
.m-top > .icon-btn { background: transparent; box-shadow: none; }
.m-top > .icon-btn::before { opacity: 0; }
.stage-tools .tool-btn:not(.help), .action-bar .act-btn:not(:first-child), .cv-mb, .mt-add, .mp-full { background: transparent; box-shadow: none; }
.stage-tools .tool-btn:not(.help)::before, .action-bar .act-btn:not(:first-child)::before, .cv-mb::before, .mt-add::before, .mp-full::before { opacity: 0; }
@media (hover: hover) {
  .stage-tools .tool-btn:not(.help):hover, .action-bar .act-btn:not(:first-child):hover, .cv-mb:hover, .mt-add:hover, .mp-full:hover, .m-top > .icon-btn:hover { background: radial-gradient(60px 40px at var(--mx, 50%) var(--my, 0%), var(--g5-sheen), transparent 70%) no-repeat, var(--g5-fill); box-shadow: var(--g5-edge); }
  .stage-tools .tool-btn:not(.help):hover::before, .action-bar .act-btn:not(:first-child):hover::before, .cv-mb:hover::before, .mt-add:hover::before, .mp-full:hover::before, .m-top > .icon-btn:hover::before { opacity: 1; }
  .topbar .pill:hover, .topbar .avatar-btn:hover, .m-top .pill:hover, .m-top > .icon-btn:hover, .m-to-prompt:hover { background: radial-gradient(70px 44px at var(--mx, 30%) var(--my, -40%), var(--g5-sheen), transparent 70%) no-repeat, var(--g5-fill-hi); }
}
.stage-tools .tool-btn:not(.help).lg-down, .action-bar .act-btn:not(:first-child).lg-down, .cv-mb.lg-down, .mt-add.lg-down, .mp-full.lg-down, .m-top > .icon-btn.lg-down, .topbar .pill.lg-down, .topbar .avatar-btn.lg-down, .m-top .pill.lg-down, .m-top > .icon-btn.lg-down, .m-to-prompt.lg-down { background: radial-gradient(60px 40px at var(--mx, 50%) var(--my, 0%), var(--g5-sheen), transparent 75%) no-repeat, var(--g5-fill-hi); box-shadow: var(--g5-edge), 0 6px 16px -6px rgba(0,0,0,.5); }
.stage-tools .tool-btn:not(.help).lg-down::before, .action-bar .act-btn:not(:first-child).lg-down::before, .cv-mb.lg-down::before, .mt-add.lg-down::before, .mp-full.lg-down::before, .m-top > .icon-btn.lg-down::before { opacity: 1; }
.action-bar .act-btn.on, .action-bar .act-btn[aria-pressed="true"] { background: var(--g5-fill-hi); box-shadow: var(--g5-edge); }
/* CSS-only press = a bulge, not a dent (with liquid.js a spring owns transform) */
.topbar .pill:active, .topbar .avatar-btn:active, .m-top .pill:active, .m-top > .icon-btn:active, .stage-tools .tool-btn:not(.help):active, .action-bar .act-btn:not(:first-child):active, .cv-mb:active, .mt-add:active, .mp-full:active, .m-to-prompt:active { transform: scale(1.06); }
.cv-mb { z-index: 1; }
.pill.bal { cursor: default; }
/* --- troughs under liquid indicators: a slight inner depth, no extra blur --- */
.theme-switch, .mt-tabs { box-shadow: var(--g5-trough); }
/* --- canvas minibar: a clear refractive capsule (glass lives in .lg-mbg when liquid.js runs) --- */
.cv-mini.lg-mb::before { display: none; }
.cv-mini.lg-mb > .lg-mbg + .cv-mb { margin-left: 3px; }
.lg-mbg { position: absolute; inset: 8px 0 0; border-radius: 12px; z-index: 0; pointer-events: none; background: var(--clear4); box-shadow: var(--float4), var(--bevel4);
  -webkit-backdrop-filter: blur(8px) saturate(1.9) brightness(1.12); backdrop-filter: blur(8px) saturate(1.9) brightness(1.12); }
.lg-mbg::before { content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1.5px; background: var(--rim4); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); }
.lg-mbg::after { content: ""; position: absolute; left: 8px; right: 8px; top: 1.5px; height: 45%; border-radius: inherit; background: linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,0)); }
[data-theme="light"] .lg-mbg::after { background: linear-gradient(180deg, rgba(255,255,255,.7), rgba(255,255,255,0)); }
.lg-refract-ok .lg-mbg.lg-lens { -webkit-backdrop-filter: var(--lg-bf); backdrop-filter: var(--lg-bf); }
.cv-mb { text-shadow: 0 0 6px rgba(0,0,0,.5); }
.stage-badge::after { content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px; background: var(--g5-rim); pointer-events: none; -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); }
/* --- popovers (model dropdown, ⋯ menus, account menu): clear glass with a refractive rim; tint kept dense enough for AA on bright art --- */
.popmenu { background: var(--g5-pop); -webkit-backdrop-filter: blur(18px) saturate(1.9) brightness(.96); backdrop-filter: blur(18px) saturate(1.9) brightness(.96); box-shadow: var(--float4), var(--bevel4); }
.lg-refract-ok .popmenu.lg-lens { -webkit-backdrop-filter: var(--lg-bf); backdrop-filter: var(--lg-bf); }
.pm-item, .model-opt { transition: background .2s, box-shadow .2s, transform var(--spring-d) var(--spring); }
.pm-item:hover:not(:disabled), .model-opt:hover { background: var(--g5-fill); box-shadow: var(--g5-edge); }
.pm-item:active:not(:disabled), .model-opt:active { transform: scale(.98); }
/* --- sheets: wet top highlight on the glass edge --- */
.layer-panel.sheet > .lg-sweep + *, .layer-panel.sheet { }
.layer-panel.sheet { box-shadow: 0 -10px 40px -10px rgba(0,0,0,.5), var(--bevel4), inset 0 1px 0 rgba(255,255,255,.14); }
/* --- mobile sheet handle: a little glass capsule that stretches when grabbed --- */
.m-handle i { background: linear-gradient(180deg, rgba(255,255,255,.55), rgba(255,255,255,.22)); box-shadow: inset 0 .5px 0 rgba(255,255,255,.8), 0 1px 3px rgba(0,0,0,.35); transition: transform var(--spring-d) var(--spring), background .2s; }
[data-theme="light"] .m-handle i { background: linear-gradient(180deg, rgba(20,30,60,.30), rgba(20,30,60,.20)); }
.m-handle:active i, .m-handle.lg-down i { transform: scaleX(1.4) scaleY(1.25); background: linear-gradient(180deg, rgba(255,255,255,.8), rgba(255,255,255,.4)); }
/* --- switch knob = glass droplet (stretches into a lens while held) --- */
.switch { --kx: 0px; }
.switch-input:checked + .switch { --kx: 16px; }
.switch-input:checked + .switch.sm { --kx: 12px; }
.switch::after, .lg-knob { background: var(--drop); box-shadow: var(--drop-shadow); }
.switch-input:checked + .switch::after { background: var(--drop); }
.switch.lg-k::after { opacity: 0; }
.lg-knob { position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; pointer-events: none; transform: translateX(var(--kx)) scale(var(--ks, 1), var(--ksy, 1));
  transition: transform .5s var(--spring), background .25s, box-shadow .25s; z-index: 1; }
.switch.sm .lg-knob { width: 12px; height: 12px; }
.switch.lg-press .lg-knob { --ks: 1.7; --ksy: 1.45; background: radial-gradient(circle at 50% 120%, rgba(160,205,255,.45), rgba(160,205,255,0) 60%), radial-gradient(circle at 34% 24%, rgba(255,255,255,.9) 0 10%, rgba(255,255,255,0) 40%), rgba(255,255,255,.16);
  box-shadow: inset 0 0 0 .6px rgba(255,255,255,.95), inset 1px 1px 1px -.5px #fff, inset 0 -1px 2px rgba(120,160,255,.5), 0 2px 8px -2px rgba(0,0,0,.5); transition-duration: .32s; }
.lg-refract-ok .switch .lg-knob.lg-lens { -webkit-backdrop-filter: none; backdrop-filter: none; }
.lg-refract-ok .switch.lg-press .lg-knob.lg-lens { -webkit-backdrop-filter: var(--lg-bf); backdrop-filter: var(--lg-bf); }
.switch { transition: background .3s, border-color .3s, box-shadow .3s; }
.switch-input:checked + .switch { box-shadow: inset 0 1px 2px rgba(0,0,0,.25), 0 0 10px -2px color-mix(in srgb, var(--switch-on) 60%, transparent); }
/* --- slider thumb = glass droplet; while dragging a magnifying drop (liquid.js) takes its place --- */
input[type="range"]::-webkit-slider-thumb { background: var(--drop); border-color: rgba(255,255,255,.55); box-shadow: inset 0 -2px 3px -1px color-mix(in srgb, var(--range) 70%, transparent), 0 1px 4px rgba(0,0,0,.45); transition: opacity .12s, transform .3s var(--spring); }
[data-theme="light"] input[type="range"]::-webkit-slider-thumb { border-color: rgba(255,255,255,.95); box-shadow: inset 0 -2px 3px -1px color-mix(in srgb, var(--range) 55%, transparent), 0 0 0 .5px rgba(20,30,60,.2), 0 1px 4px rgba(20,30,60,.3); }
input[type="range"]:active::-webkit-slider-thumb { transform: scale(1.25); }
input[type="range"].lg-sliding::-webkit-slider-thumb { opacity: 0; }
.lg-drop { position: fixed; left: 0; top: 0; width: 40px; height: 40px; margin: -20px 0 0 -20px; border-radius: 50%; pointer-events: none; z-index: 9000; will-change: transform;
  background: radial-gradient(circle at 50% 115%, rgba(160,205,255,.30), rgba(160,205,255,0) 55%), radial-gradient(circle at 32% 22%, rgba(255,255,255,.85) 0 7%, rgba(255,255,255,0) 30%), rgba(255,255,255,.05);
  box-shadow: inset 0 0 0 .6px rgba(255,255,255,.9), inset 1.5px 1.5px 1px -1px #fff, inset -1px -1.5px 2px -1px rgba(140,180,255,.7), inset 0 -6px 10px -6px rgba(140,180,255,.5), 0 4px 14px -4px rgba(0,0,0,.55);
  -webkit-backdrop-filter: blur(.4px) saturate(1.5) brightness(1.1); backdrop-filter: blur(.4px) saturate(1.5) brightness(1.1); }
.app.mobile ~ .lg-drop, body.is-mobile .lg-drop { width: 48px; height: 48px; margin: -24px 0 0 -24px; }
.lg-refract-ok .lg-drop.lg-lens { -webkit-backdrop-filter: var(--lg-bf); backdrop-filter: var(--lg-bf); }
/* --- user feedback on v4 mobile bar: keep the clarity + rim, stop over-saturating the art behind text --- */
html:not(.lg-refract-ok) .action-bar, html:not(.lg-refract-ok) .stage-tools, html:not(.lg-refract-ok) .app.mobile > .composer { -webkit-backdrop-filter: blur(9px) saturate(1.3) brightness(1.06); backdrop-filter: blur(9px) saturate(1.3) brightness(1.06); }
.app.mobile > .composer { background: linear-gradient(180deg, rgba(12,14,20,.06), rgba(12,14,20,.16)), var(--clear4-mob); }
[data-theme="dark"] .app.mobile > .composer .m-prompt, [data-theme="dark"] .app.mobile > .composer .m-sum, :root:not([data-theme="light"]) .app.mobile > .composer .m-prompt, :root:not([data-theme="light"]) .app.mobile > .composer .m-sum {
  background: radial-gradient(90px 50px at var(--mx, 20%) var(--my, -30%), rgba(255,255,255,.10), transparent 70%) no-repeat, linear-gradient(180deg, rgba(255,255,255,.08), rgba(255,255,255,.025)), rgba(8, 10, 16, .26); }
.app.mobile > .composer .m-prompt.lg-down, .app.mobile > .composer .m-sum.lg-down { background: radial-gradient(90px 50px at var(--mx, 20%) var(--my, -30%), rgba(255,255,255,.22), transparent 70%) no-repeat, linear-gradient(180deg, rgba(255,255,255,.12), rgba(255,255,255,.04)), rgba(8, 10, 16, .22); }
.app.mobile > .composer .m-prompt, .app.mobile > .composer .m-sum { text-shadow: 0 0 1px rgba(0,0,0,.45), 0 0 6px rgba(0,0,0,.35); }
/* --- content stays clean: only a subtle press response --- */
.tb, .th, .tile, .set-row, .fold-head, .pos-chip, .btn, .tb-undo, .collapse-btn, .num-stepper .icon-btn, .seed-row .icon-btn, .dims-row .icon-btn, .char-head .icon-btn, .mc-more { transition: transform var(--spring-d) var(--spring), background-color .2s, border-color .2s, color .2s, box-shadow .2s; }
.tb:active, .th:active, .tile:active, .set-row:active, .pos-chip:active, .btn:active:not(:disabled), .tb-undo:active, .collapse-btn:active { transform: scale(.97); }
.fold-head:active { transform: scale(.99); }
.tb.lg-new { animation: lg-tb-in .5s var(--spring) both; }
@keyframes lg-tb-in { from { opacity: 0; transform: scale(.6); } 40% { opacity: 1; } to { opacity: 1; transform: none; } }
.tb.lg-out { animation: lg-tb-out .22s cubic-bezier(.4,0,.8,.4) both; pointer-events: none; }
@keyframes lg-tb-out { to { opacity: 0; transform: scale(.6); } }
@media (prefers-reduced-motion: reduce) {
  .topbar .pill:active, .topbar .avatar-btn:active, .m-top .pill:active, .m-top > .icon-btn:active, .stage-tools .tool-btn:not(.help):active, .action-bar .act-btn:not(:first-child):active, .cv-mb:active, .mt-add:active, .mp-full:active, .m-to-prompt:active, .lg-knob, .tb, .th, .tile, .set-row, .pos-chip, .btn, .m-handle i { transform: none !important; animation: none !important; }
  .lg-knob { transform: translateX(var(--kx)) !important; }
  .lg-drop { display: none; } input[type="range"].lg-sliding::-webkit-slider-thumb { opacity: 1; }
}

/* ================= v5b: count/size droplet indicators + iOS 26 style knobs (solid at rest, clear glass while held) ================= */
.seg.lg-has-ind { box-shadow: var(--g5-trough); }
.ratios.lg-has-ind > .lg-ind { border-radius: 10px; background: var(--ind4); box-shadow: var(--ind4-shadow), inset 0 0 0 1px color-mix(in srgb, var(--accent) 85%, transparent), 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent), 0 6px 16px -8px color-mix(in srgb, var(--accent) 60%, transparent); }
.lg-refract-ok .seg > .lg-ind.lg-lens:not(.lg-live), .lg-refract-ok .ratios > .lg-ind.lg-lens:not(.lg-live) { -webkit-backdrop-filter: none; backdrop-filter: none; }
.lg-refract-ok .seg > .lg-ind.lg-lens.lg-live, .lg-refract-ok .ratios > .lg-ind.lg-lens.lg-live { -webkit-backdrop-filter: var(--lg-bf); backdrop-filter: var(--lg-bf); }
:root { --kn-rest: 0 0 0 .5px rgba(0,0,0,.10), 0 1px 1.5px rgba(0,0,0,.20), 0 2px 7px -1px rgba(0,0,0,.30);
  --kn-glass: inset 0 0 0 .6px rgba(255,255,255,.95), inset 1.5px 1.5px 1px -1px #fff, inset -1px -1.5px 1.5px -1px rgba(255,255,255,.75), 0 0 0 .5px rgba(0,0,0,.14), 0 3px 10px -3px rgba(0,0,0,.35); }
[data-theme="light"] { --kn-rest: 0 0 0 .5px rgba(20,30,60,.14), 0 1px 1.5px rgba(20,30,60,.16), 0 2px 7px -1px rgba(20,30,60,.22);
  --kn-glass: inset 0 0 0 .6px rgba(255,255,255,1), inset 1.5px 1.5px 1px -1px #fff, inset -1px -1.5px 1.5px -1px rgba(255,255,255,.8), inset 0 -3px 5px -3px rgba(40,60,140,.28), 0 0 0 .75px rgba(20,30,60,.30), 0 4px 12px -3px rgba(20,30,60,.34); }
.switch.lg-k .lg-knob, .switch.lg-k.lg-press .lg-knob, .lg-thumb { --ks: 1; --ksy: 1; background: transparent; box-shadow: var(--kn-rest); transition: box-shadow .18s, opacity .2s; will-change: transform; transform-origin: 50% 50%; }
.lg-knob::before, .lg-thumb::before { content: ""; position: absolute; inset: 0; border-radius: inherit; background: #fff; transition: opacity .16s ease-out; }
.lg-knob::after, .lg-thumb::after { content: ""; position: absolute; inset: 0; border-radius: inherit; opacity: 0; transition: opacity .16s;
  background: radial-gradient(circle at 32% 24%, rgba(255,255,255,.95) 0 9%, rgba(255,255,255,0) 30%), radial-gradient(circle at 50% 115%, rgba(255,255,255,.35), rgba(255,255,255,0) 55%); }
.switch.lg-k .lg-knob.lg-glass, .lg-thumb.lg-glass { box-shadow: var(--kn-glass); }
.lg-knob.lg-glass::before, .lg-thumb.lg-glass::before { opacity: 0; }
.lg-knob.lg-glass::after, .lg-thumb.lg-glass::after { opacity: 1; }
html:not(.lg-refract-ok) .lg-knob.lg-glass, html:not(.lg-refract-ok) .lg-thumb.lg-glass { -webkit-backdrop-filter: saturate(1.6) brightness(1.08); backdrop-filter: saturate(1.6) brightness(1.08); }
.lg-refract-ok .switch .lg-knob.lg-lens, .lg-refract-ok .switch.lg-press .lg-knob.lg-lens, .lg-refract-ok .lg-thumb.lg-lens { -webkit-backdrop-filter: none; backdrop-filter: none; }
.lg-refract-ok .switch .lg-knob.lg-lens.lg-glass, .lg-refract-ok .lg-thumb.lg-lens.lg-glass { -webkit-backdrop-filter: var(--lg-bf); backdrop-filter: var(--lg-bf); }
.switch-input:disabled + .switch .lg-knob { box-shadow: none; }
.lg-sl-host { position: relative; }
.toggle-field { touch-action: pan-y; }   /* sideways drag on the row drives the droplet; vertical still scrolls the sheet */
input[type="range"].lg-sl::-webkit-slider-thumb { opacity: 0 !important; transform: none !important; }
.lg-thumb { position: absolute; left: 0; top: 0; width: 20px; height: 20px; border-radius: 50%; pointer-events: none; z-index: 1; }
.lg-thumb.lg-big { width: 26px; height: 26px; }
.lg-thumb.lg-dis { opacity: .45; }
input[type="range"].lg-sl:focus-visible + .lg-thumb { outline: 2px solid var(--accent); outline-offset: 2px; }
.lg-drop { display: none !important; }
@media (prefers-reduced-motion: reduce) { .lg-thumb { transition: none; } }
/* 2.4.4 merge: keyboard up -> the sheet and its skirt are one solid colour (translucent --surface would let the page show under the iOS bars again) */
.layer.kb-open .layer-panel.sheet { background: var(--l3-solid); -webkit-backdrop-filter: none; backdrop-filter: none; }
.layer.kb-open .layer-panel.sheet.m-psheet-panel::after, .layer.kb-open .layer-panel.sheet.m-pinned::after { background: var(--l3-solid); }
/* perf (2.4.4 merge): desktop chrome panels only ever sit on the static ambient background, where a 28px blur is a visual no-op
   (<0.1% pixels differ, max 19/255) but forced Chromium to re-blur three large panels on every canvas pan frame (37 -> 17 ms) */
.app.desktop .topbar, .app.desktop .side, .app.desktop .strip { -webkit-backdrop-filter: none; backdrop-filter: none; }
/* tag autocomplete sits on top of the text being edited: keep it solid for legibility (no glass) */
.ac-list { background: var(--l3-solid); -webkit-backdrop-filter: none; backdrop-filter: none; }
@media (prefers-reduced-transparency: reduce) { .lg-knob.lg-glass::before, .lg-thumb.lg-glass::before { opacity: 1; } .lg-knob.lg-glass::after, .lg-thumb.lg-glass::after { opacity: 0; } .lg-knob.lg-glass, .lg-thumb.lg-glass, .seg > .lg-ind, .ratios > .lg-ind { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; } }

/* ===== 2.4.6 glass: v4 material (vivid, sat ~1.8) on the v5 coverage, unified motion tokens, no ancestor press,
   static ambient (no infinite animation under backdrop-filters), richer WebKit/Gecko fallback ===== */
:root { --m-press: 140ms; --m-release: 340ms; --m-slide: 420ms; --m-sheet: 480ms; --m-pop: 240ms; --m-exit: 220ms;
  --spring-d: var(--m-release); --spring-sheet-d: var(--m-sheet); }
/* motion: press-in is short and critically damped, release / popovers / sheets use the tokens above */
:is(button, .ratio, .seg-btn, .mt-tab, .chip, .m-chip, .pill, .tb, .th, .pos-chip, .model-card, .m-sum, .m-prompt, .fold-head):active { transition-duration: var(--m-press) !important; }
.popmenu { animation-duration: var(--m-pop); }
.popmenu.lg-ghost { animation-duration: var(--m-exit) !important; }
.tb.lg-new { animation-duration: 360ms; }
.tb.lg-out { animation-duration: var(--m-exit); }
.lg-sweep::before { animation-duration: .7s; }
.layer-panel.sheet { transition-duration: var(--m-exit); }
/* tapping a button inside a card / row must not shrink the whole card (mobile :active applies to every ancestor) */
.tile:active, .set-row:active:has(:is(button, a, input, select, label):active), .fold-head:active:has(:is(button, a, input):active) { transform: none !important; }
/* perf: the ambient drift behind every backdrop-filter forced a re-blur each frame -> static ambient */
.stage::before { animation: none !important; will-change: auto; }
/* material: v4 (clear bars, corner-pool rim, soft bevel) everywhere, incl. the v5 pills/buttons (their hard 1px insets go) */
:root, [data-theme="dark"] {
  --g5-edge: inset 0 1px 0 rgba(255,255,255,.16), inset 0 -1px 0 rgba(0,0,0,.22), inset 0 10px 16px -14px rgba(255,255,255,.22), 0 2px 8px -3px rgba(0,0,0,.45);
  --g5-rim: var(--rim4);
  --ind4-shadow: inset 0 1px 0 rgba(255,255,255,.34), inset 0 -1px 0 rgba(0,0,0,.22), inset 0 0 12px rgba(255,255,255,.06), 0 4px 12px -4px rgba(0,0,0,.5);
}
[data-theme="light"] {
  --g5-edge: inset 0 1px 0 #fff, inset 0 -1px 0 rgba(20,30,60,.06), inset 0 0 0 .5px rgba(20,30,60,.08), 0 2px 8px -4px rgba(30,40,90,.25);
  --ind4-shadow: inset 0 1px 0 #fff, inset 0 0 0 .5px rgba(20,30,60,.08), 0 3px 10px -4px rgba(30,40,90,.30);
}
.action-bar, .stage-tools { -webkit-backdrop-filter: blur(9px) saturate(1.8) brightness(1.12); backdrop-filter: blur(9px) saturate(1.8) brightness(1.12); }
[data-theme="light"] .action-bar, [data-theme="light"] .stage-tools { -webkit-backdrop-filter: blur(9px) saturate(1.8) brightness(1.03); backdrop-filter: blur(9px) saturate(1.8) brightness(1.03); }
.popmenu { -webkit-backdrop-filter: blur(18px) saturate(1.7) brightness(.98); backdrop-filter: blur(18px) saturate(1.7) brightness(.98); }
/* bottom bar back to the v4 material (2.4.4's v5 darkening gradient + heavy text halo made it grey and muted) */
.app.mobile > .composer { background: var(--clear4-mob); }
.app.mobile > .composer .m-prompt, .app.mobile > .composer .m-sum { text-shadow: 0 0 1px rgba(0,0,0,.35), 0 0 4px rgba(0,0,0,.18); }
[data-theme="light"] .app.mobile > .composer .m-prompt, [data-theme="light"] .app.mobile > .composer .m-sum { text-shadow: none; }
/* very light text scrim on clear glass: labels keep AA over bright art without a dark slab */
.action-bar .act-btn:not(:first-child), .stage-tools .tool-btn, .cv-mb { background-image: radial-gradient(closest-side, rgba(8,10,16,.14), rgba(8,10,16,0)); }
[data-theme="light"] .action-bar .act-btn:not(:first-child), [data-theme="light"] .stage-tools .tool-btn { background-image: radial-gradient(closest-side, rgba(255,255,255,.25), rgba(255,255,255,0)); }
/* every indicator refracts only while pressed / moving (idle backdrop-filter count stays at the bars) */
.lg-refract-ok .lg-ind.lg-lens:not(.lg-live) { -webkit-backdrop-filter: none; backdrop-filter: none; }
.lg-refract-ok .lg-ind.lg-lens.lg-live { -webkit-backdrop-filter: var(--lg-bf); backdrop-filter: var(--lg-bf); }
/* WebKit / Gecko (feature-detected by liquid.js, no SVG refraction there): approximate the lens with layered edge light -
   light gathered along the rim, a bright top band, a darker inner bottom edge (= thickness) and a soft blur + saturate */
html.lg-fallback.lg-js .app.mobile > .composer, html.lg-fallback.lg-js .action-bar, html.lg-fallback.lg-js .stage-tools, html.lg-fallback.lg-js .popmenu, html.lg-fallback .cv-mini .lg-mbg {
  -webkit-backdrop-filter: blur(12px) saturate(1.8) brightness(1.12); backdrop-filter: blur(12px) saturate(1.8) brightness(1.12);
  box-shadow: var(--float4), var(--bevel4), inset 0 0 0 .5px rgba(255,255,255,.12),
    inset 0 12px 14px -12px rgba(255,255,255,.30), inset 0 -12px 16px -12px rgba(0,0,0,.28),
    inset 14px 0 16px -15px rgba(255,255,255,.16), inset -14px 0 16px -15px rgba(255,255,255,.16); }
[data-theme="light"].lg-fallback.lg-js .app.mobile > .composer, [data-theme="light"].lg-fallback.lg-js .action-bar, [data-theme="light"].lg-fallback.lg-js .stage-tools, [data-theme="light"].lg-fallback.lg-js .popmenu {
  -webkit-backdrop-filter: blur(12px) saturate(1.8) brightness(1.03); backdrop-filter: blur(12px) saturate(1.8) brightness(1.03);
  box-shadow: var(--float4), var(--bevel4), inset 0 0 0 .5px rgba(20,30,60,.08), inset 0 12px 14px -12px #fff, inset 0 -12px 16px -12px rgba(20,30,60,.10); }
html.lg-fallback .lg-ind { box-shadow: var(--ind4-shadow), inset 0 6px 8px -6px rgba(255,255,255,.35), inset 0 -6px 8px -6px rgba(0,0,0,.18); }
html.lg-fallback .lg-knob.lg-glass, html.lg-fallback .lg-thumb.lg-glass { -webkit-backdrop-filter: blur(.6px) saturate(1.5) brightness(1.1); backdrop-filter: blur(.6px) saturate(1.5) brightness(1.1);
  box-shadow: var(--kn-glass), inset 0 3px 4px -3px rgba(255,255,255,.9), inset 0 -3px 5px -3px rgba(40,60,140,.35); }
@media (prefers-reduced-transparency: reduce) { html.lg-fallback.lg-js .app.mobile > .composer, html.lg-fallback.lg-js .action-bar, html.lg-fallback.lg-js .stage-tools, html.lg-fallback.lg-js .popmenu { background: var(--l3-solid); -webkit-backdrop-filter: none; backdrop-filter: none; } }

/* ===== 2.4.5 hotfix (iOS keyboard + glass): while a mobile sheet is open the feed's bottom bar is hidden outright
   (no ghost copy under / through the sheet), and a sheet being typed in is opaque edge to edge - the glass sheet let the
   bar and the page show through on iPhone (WebKit) ===== */
html.m-lock .app.mobile > .composer { visibility: hidden; transition: none; }
.app.mobile ~ .layer .layer-panel.sheet:focus-within, .layer:has(.m-psheet-panel) .layer-panel.sheet:focus-within { background: var(--l3-solid); -webkit-backdrop-filter: none; backdrop-filter: none; }
.layer.kb-open, .layer:has(.layer-panel.sheet :is(textarea, input):focus) { background: var(--bg); }
.layer.kb-open .layer-panel.sheet::after, .layer:has(.layer-panel.sheet :is(textarea, input):focus) .layer-panel.sheet::after { background: var(--l3-solid); }

/* ===== 2.4.6 edges (iOS 26 folder rim): no border, no grey outline. The rim is a ~1px luminous edge lit from the top-left:
   bright at the top-left and bottom-right corners, fading to almost nothing at the side midpoints (masked gradient ring on
   ::before, plus-lighter), a very faint inner glow and practically no outer shadow. Same on every floating glass surface. ===== */
:root, [data-theme="dark"] {
  --ios-rim: linear-gradient(135deg, rgba(255,255,255,.55) 0%, rgba(255,255,255,.12) 16%, rgba(255,255,255,0) 32%, rgba(255,255,255,0) 68%, rgba(255,255,255,.10) 84%, rgba(255,255,255,.42) 100%);
  --ios-glow: inset 0 0 14px rgba(255,255,255,.035);
  --ios-out: 0 10px 30px -22px rgba(0,0,0,.45);
}
[data-theme="light"] {
  --ios-rim: linear-gradient(135deg, rgba(255,255,255,.95) 0%, rgba(255,255,255,.35) 16%, rgba(255,255,255,0) 32%, rgba(255,255,255,0) 68%, rgba(255,255,255,.30) 84%, rgba(255,255,255,.85) 100%);
  --ios-glow: inset 0 0 16px rgba(255,255,255,.22);
  --ios-out: 0 10px 28px -22px rgba(30,40,90,.16);
}
.app.mobile > .composer, .action-bar, .stage-tools, .cv-mini .lg-mbg, .popmenu, .layer-panel.sheet,
.composer .m-prompt, .composer .m-sum, .m-top .pill, .m-top > .icon-btn, .m-to-prompt, .topbar .pill, .topbar .avatar-btn,
.action-bar .act-btn.on, .action-bar .act-btn[aria-pressed="true"] { border-color: transparent !important; box-shadow: var(--ios-glow), var(--ios-out) !important; }
.app.mobile > .composer::before, .action-bar::before, .stage-tools::before, .cv-mini .lg-mbg::before, .popmenu::before, .layer-panel.sheet::before,
.composer .m-prompt::before, .composer .m-sum::before, .m-top .pill::before, .m-top > .icon-btn::before, .m-to-prompt::before, .topbar .pill::before, .topbar .avatar-btn::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px; pointer-events: none; z-index: 2;
  background: var(--ios-rim) !important; mix-blend-mode: plus-lighter; opacity: 1;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0); }
[data-theme="light"] :is(.app.mobile > .composer, .action-bar, .stage-tools, .popmenu, .layer-panel.sheet, .composer .m-prompt, .composer .m-sum, .m-top .pill, .topbar .pill)::before { mix-blend-mode: normal; }
.layer-panel.sheet::before { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
@media (prefers-contrast: more) { .app.mobile > .composer, .composer .m-prompt, .composer .m-sum, .m-top .pill, .topbar .pill { box-shadow: inset 0 0 0 1px var(--border-strong) !important; } }
/* small chips inside the bar (正面/负面 count, settings chevron): fill only, no grey outline */
.composer .mp-cnt, .composer .ms-cv { border-color: transparent; box-shadow: var(--ios-glow); }

/* ===== 2.4.7 no sibling flash on press (desktop): the glass buttons keep their own compositing layer at rest. 2.4.6 created the
   layer only while the press spring ran (inline transform) and dropped it after, and each layer change re-rendered the parent
   bar's refracting backdrop (.action-bar / .stage-tools lens), so the bar rim and its other buttons flickered on every click.
   (The other flash, every selected pill of the side panel blinking, was fixed in liquid.js: re-created droplets no longer fade in.) */
.topbar .pill, .topbar .avatar-btn, .m-top .pill, .m-top > .icon-btn, .stage-tools .tool-btn:not(.help), .action-bar .act-btn:not(:first-child), .cv-mb, .mt-add, .mp-full, .m-to-prompt, .m-prompt, .m-sum { will-change: transform; }

/* ===== 2.4.8 desktop character column (js/ui/charcol.js): the sidebar keeps its layout, 角色 opens a column next to it
   that pushes the canvas; one active character editor behind a chip strip ===== */
.sec-label .chars-toggle { order: 3; margin-left: 8px; }
.sec-label:has(.chars-toggle) > span:first-child { margin-right: auto; }
.sec-label:has(.chars-toggle) .kbd-hint { order: 2; }
.chars-toggle { display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 8px; border-radius: var(--r-pill); border: 1px solid var(--border); background: var(--surface-2); color: var(--text-dim); font: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer; white-space: nowrap; flex: none; }
.chars-toggle:hover, .chars-toggle[aria-expanded="true"] { color: var(--text); border-color: var(--accent); }
.chars-row { width: 100%; display: flex; align-items: center; gap: 8px; padding: 8px 12px; min-height: 40px; border: 1px solid var(--border); background: var(--surface-2); color: var(--text); font: inherit; font-size: 13px; cursor: pointer; text-align: left; }
.chars-row .fold-title { font-weight: 600; }
.chars-row .fold-hint { margin-left: auto; color: var(--text-dim); font-size: 12px; }
.chars-row .fold-arrow { color: var(--text-dim); flex: none; }
.chars-row:hover .fold-hint { color: var(--text); }
.chars-row.on { border-color: var(--accent); }
.chars-row.on .fold-hint { color: var(--accent-text); }

.char-col { position: relative; flex: none; width: var(--cc-w, 380px); min-height: 0; overflow: hidden; z-index: 4;
  background: var(--grain), var(--l1); background-size: 160px 160px, auto; box-shadow: inset -1px 0 0 var(--hair);
  /* motion tokens shared with the sheets (.layer-panel.sheet): open = --spring-sheet-d (--m-sheet) on --spring-sheet, close = --m-exit on the sheet exit curve */
  transition: width var(--spring-sheet-d, .48s) var(--spring-sheet); }
.char-col[hidden] { display: none; }
.char-col.entering, .char-col.leaving { width: 0; }
.char-col.leaving { transition: width var(--m-exit, .22s) cubic-bezier(.4, 0, 1, 1); }
.char-col.dragging { transition: none; }
.char-col.cc-anim { will-change: width; }
.char-col.cc-anim .cc-inner { will-change: opacity, transform; }
/* contents: popover / sheet language (lg-pop: fade in over --m-pop, slide + slight scale on the spring), anchored to the sidebar edge */
.cc-inner { width: var(--cc-w, 380px); height: 100%; display: flex; flex-direction: column; gap: 10px; padding: 14px 14px 0 22px; min-height: 0;
  transform-origin: 0 50%; transition: opacity var(--m-pop, .24s) ease, transform var(--spring-sheet-d, .48s) var(--spring-sheet); }
.char-col.entering .cc-inner { opacity: 0; transform: translate3d(-18px, 0, 0) scale(.98); }
.char-col.leaving .cc-inner { opacity: 0; transform: translate3d(-12px, 0, 0) scale(.98); transition: opacity var(--m-exit, .22s) ease, transform var(--m-exit, .22s) cubic-bezier(.4, 0, 1, 1); }
.cc-grip { position: absolute; top: 0; right: 0; bottom: 0; width: 8px; cursor: col-resize; z-index: 3; touch-action: none; }
.cc-grip::after { content: ""; position: absolute; top: 50%; right: 2px; width: 4px; height: 40px; margin-top: -20px; border-radius: 4px; background: var(--border-strong); opacity: 0; transition: opacity .2s; }
.char-col:hover .cc-grip::after, .char-col.dragging .cc-grip::after, .cc-grip:focus-visible::after { opacity: 1; }
.cc-grip:focus-visible { outline: none; }
/* 2.4.9: column contents = official Character Prompts (header + 「+」 女/男/其他, 位置 [AI 决定 | 自定义 ▦], stacked cards) */
.cc-top { display: flex; align-items: flex-start; gap: 6px; }
.cc-titles { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; padding-top: 2px; }
.cc-h { font-size: 14px; font-weight: 700; color: var(--text); }
.cc-sub { font-size: 12px; color: var(--text-dim); line-height: 1.35; }
.cc-add { flex: none; width: 38px; height: 38px; border-radius: var(--r-md, 10px); border: 1px solid var(--border); background: var(--surface-2); color: var(--text); }
.cc-add:hover:not(:disabled) { border-color: var(--accent); background: var(--accent-soft); }
.cc-close { flex: none; margin-top: 4px; }
.cc-posrow { display: flex; align-items: center; gap: 10px; }
.cc-posrow[hidden] { display: none; }
.cc-pos-k { flex: none; font-size: 12.5px; font-weight: 600; color: var(--text-dim); }
.cc-posseg { flex: 1; min-width: 0; }
.cc-posseg .seg-btn { flex: 1; }
.cc-grid { flex: none; width: 34px; height: 34px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface-2); color: var(--text-dim); }
.cc-grid:hover, .cc-grid.on { color: var(--text); border-color: var(--accent); }
.cc-body { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 10px; overflow-y: auto; padding: 2px 2px 120px; margin: 0 -2px; scrollbar-width: thin; }
.cc-body > .note { margin: 0; }
.cc-empty { padding: 26px 12px; text-align: center; color: var(--text-dim); font-size: 12.5px; border: 1px dashed var(--border); border-radius: var(--r-lg); }
.cc-card { flex: none; border: 1px solid var(--border); border-radius: var(--r-lg); background: var(--surface-2); }
/* 停用 dimming on the editor parts, NOT on .cc-cbody: opacity < 1 there made a stacking context that trapped the tag
   autocomplete list (z-index 60) under the next card (and at 50 % opacity) -> no visible autocomplete for disabled characters */
.cc-card.off .char-title, .cc-card.off .cc-gender, .cc-card.off .cc-tabs, .cc-card.off .prompt-ta, .cc-card.off .tag-ed, .cc-card.off .pm-toggle-mode, .cc-card.off .tb-undo { opacity: .5; }
/* the card being edited stacks above the cards after it, so its autocomplete list always paints on top */
.cc-card:focus-within { position: relative; z-index: 2; }
.cc-head { display: flex; align-items: center; gap: 2px; min-height: 34px; padding: 2px 4px 2px 10px; border-bottom: 1px solid var(--hair); }
.cc-card.folded .cc-head { border-bottom: 0; }
.cc-head .char-title { font-weight: 650; font-size: 13px; margin-left: 6px; color: var(--text-dim); }
.cc-head .icon-btn { width: 28px; height: 28px; color: var(--text-dim); }
.cc-head .icon-btn:hover:not(:disabled) { color: var(--text); }
.cc-head .icon-btn:disabled { opacity: .35; }
.cc-head .cc-en.on { color: var(--text); }
.cc-head .cc-del:hover { color: var(--danger, #e5484d); }
.cc-gender { display: inline-grid; place-items: center; width: 18px; height: 18px; color: var(--text-dim); }
.cc-gender.female { color: #f06aa4; }
.cc-gender.male { color: #5aa7ff; }
.cc-cbody { padding: 8px 10px 10px; display: flex; flex-direction: column; gap: 6px; }
.cc-cbody[hidden] { display: none; }
.cc-tabs { display: flex; gap: 4px; }
.cc-tab { height: 26px; padding: 0 10px; border: 0; border-radius: 7px; background: transparent; color: var(--text-dim); font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.cc-tab:hover { color: var(--text); }
.cc-tab.on { background: var(--surface-3); color: var(--text); }
.cc-cbody .prompt-wrap[hidden] { display: none; }
.cc-cbody .prompt-ta { min-height: 72px; }
/* narrow canvas: action bar / view tools become icon-only (tooltips stay), the size · seed badge drops its extra parts */
.action-bar.compact .act-btn > .ic ~ span, .action-bar.compact .act-btn > .ic ~ small, .action-bar.compact .act-btn > .ic.dim { display: none; }
.action-bar.compact .act-btn { padding: 0 9px; }
.stage-tools.compact .tool-btn > .ic ~ span { display: none; }
.stage-tools.compact .tool-btn { padding: 0 6px; }
.stage-badge.compact span:nth-child(n+3) { display: none; }
@media (prefers-reduced-motion: reduce) { .char-col, .char-col.leaving { transition: none !important; } .cc-inner, .char-col .cc-inner { transform: none !important; transition: opacity var(--m-pop, .24s) ease !important; } }

/* ---- mobile fixes (r26) ------------------------------------------------------------------------------------- */
/* character pane: 正面 / 负面 on its own row right above the editor (V5 Medium: a muted note instead) */
.mc-siderow { flex: none; display: flex; min-width: 0; }
.mc-siderow .mc-side { flex: 1; min-width: 0; }
.mc-siderow .mc-side .seg-btn { min-height: 36px; font-size: 13px; }
.mc-uc-off { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-dim); padding: 2px 2px 0; }
.mc-uc-off .ic, .mc-uc-off svg { flex: none; opacity: .8; }
/* app shell: the page never scrolls, rubber-bands or zooms; only the feed / sheets scroll inside */
html.m-app, html.m-app body { position: fixed; inset: 0; width: 100%; height: 100%; overflow: hidden; overscroll-behavior: none; touch-action: pan-x pan-y; }
html.m-app body { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
html.m-app .app.mobile { overflow: hidden; }
/* iOS zooms into any focused field under 16px and stays zoomed: every mobile field is >= 16px */
body.is-mobile :is(input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=file]):not([type=color]), textarea, select, [contenteditable]:not([contenteditable=false])) { font-size: 16px !important; }
/* prompt sheet: the editors fill the pane and scroll inside (autosize's overflow:hidden hid the caret -> iOS panned the page) */
.mp-pane .prompt-ta { overflow-y: auto !important; overscroll-behavior: contain; }
/* keyboard moving: the sheet follows the visual viewport in the same frame, no transitions in between */
.layer.kb-moving, .layer.kb-moving .layer-panel.sheet, .layer.kb-moving .layer-panel.sheet .layer-foot { transition: none !important; }
.layer.kb-open .layer-panel.sheet.m-psheet-panel { max-height: none; }

/* feed option B (r26, approved): image column left (40%), prompt / tags / icon actions right; every image at its
   true aspect (never cropped), ~2 cards per iPhone screen. Error cards keep the single column (message needs width). */
.app.mobile .feed { gap: 10px; padding-top: 10px; padding-left: 10px; padding-right: 10px; }   /* padding-bottom = composer height (glass rule above) */
.app.mobile .feed .card:not(.error) { display: grid; grid-template-columns: 40% minmax(0, 1fr); grid-template-rows: auto auto 1fr auto;
    grid-template-areas: "img prompt" "img meta" "img fill" "img acts"; column-gap: 10px; row-gap: 6px; padding: 8px; border-radius: 16px; }
.app.mobile .feed .card.wide:not(.error) { grid-template-columns: 48% minmax(0, 1fr); }
.app.mobile .feed .card.error { padding: 10px; gap: 8px; border-radius: 16px; }
.app.mobile .feed .card-prompt { grid-area: prompt; -webkit-line-clamp: 3; font-size: 13px; line-height: 1.45; }
.app.mobile .feed .card-prompt.open { -webkit-line-clamp: unset; }
.app.mobile .feed .card-meta { grid-area: meta; gap: 4px; }
.app.mobile .feed .card-meta .tag { height: 21px; font-size: 10.5px; padding: 0 6px; }
.app.mobile .feed .card:not(.error) .card-time { width: 100%; margin-left: 0; font-size: 11px; }
.app.mobile .feed .card-imgs { grid-area: img; align-self: start; --h: 210px; gap: 4px; justify-items: center; }
.app.mobile .feed .card-imgs.n2, .app.mobile .feed .card-imgs.n3, .app.mobile .feed .card-imgs.n4 { grid-template-columns: 1fr 1fr; --h: 104px; }
.app.mobile .feed .tile { width: min(100%, calc(var(--h) * var(--r, .68))); height: auto; max-height: none; margin-inline: auto; border-radius: 10px; background: var(--surface-2); }
.app.mobile .feed .card-imgs:not(.n1) .tile { min-height: 44px; }   /* tap target; a mixed-size batch letterboxes inside it (contain) */
.app.mobile .feed .tile img { display: block; width: 100%; height: 100%; object-fit: contain; }
.app.mobile .feed .card-acts { grid-area: acts; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)) 44px; gap: 2px; margin: 0; }
.app.mobile .feed .card-acts .spacer { display: none; }
.app.mobile .feed .card:not(.error) .c-act { flex-direction: column; justify-content: center; gap: 2px; min-height: 48px; min-width: 0; padding: 0 2px; font-size: 11px; }
.app.mobile .feed .card:not(.error) .c-act.icon-only { min-width: 44px; }
.app.mobile .feed .card-acts > .c-act.icon-only { grid-column: 4; }   /* ··· always last (upscale / director results: 查看 + ···) */
/* running / queued job: the placeholder sits in the image column at the expected aspect */
.app.mobile .feed .card.job:not(.error) .job-body { grid-area: img; align-self: start; width: min(100%, calc(210px * var(--r, .68))); margin-inline: auto; min-height: 0; max-height: none; padding: 10px 6px; gap: 6px; border-radius: 10px; }
.app.mobile .feed .card.job:not(.error) .jb-stage { font-size: 12.5px; }
.app.mobile .feed .card.job:not(.error) .jb-time { font-size: 11px; }
.app.mobile .feed .card.job:not(.error) .job-body .progress { width: 80%; }
.app.mobile .feed .card.job:not(.error) .job-body .btn { min-height: 40px; }
/* 2.4.9 mobile character tabs: the gender icon sits on the number badge's corner (no extra width: the 390px tab row
   still fits 正面 | 负面 | 角色1 | 角色2 | +); no icon when the first tag is not girl / boy */
.mt-tab.char { position: relative; }
.mt-tab.char > .cc-gender { position: absolute; left: 22px; top: 5px; width: 14px; height: 14px; border-radius: 99px; background: var(--surface); box-shadow: 0 0 0 1px var(--hair); pointer-events: none; }
.mt-tab.char > .cc-gender svg { width: 10px; height: 10px; }
.mt-tab.char > .cc-gender.none { display: none; }
.mc-head .cc-gender { flex: none; margin-left: -2px; }

/* ============ 2.4.10 mobile 创作流 (approved mock A): two-column masonry gallery + compressed dock + 44px top bar ============
   Everything below is scoped to .app.mobile, the desktop layout (A) is untouched. */
.app.mobile > .m-top { height: calc(44px + env(safe-area-inset-top)); gap: 6px; padding: env(safe-area-inset-top) 8px 0 2px; }
.app.mobile > .m-top .logo-mark { display: none; }
.app.mobile > .m-top .logo { font-size: 16px; }
.app.mobile > .m-top .pill { height: 30px; padding: 0 11px; gap: 5px; }
/* feed: full-width rows (day / load more / errors) between two-column segments */
.app.mobile .feed { gap: 8px; padding-top: 8px; padding-left: 8px; padding-right: 8px; }
.m-mas { display: flex; gap: 6px; align-items: flex-end; min-width: 0; flex: none; }
.m-col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.app.mobile .feed .card.m-tile { display: block; padding: 0; margin: 0; border: 0; border-radius: 0; background: none; box-shadow: none; isolation: auto; min-width: 0; }
.app.mobile .feed .card.m-tile::before, .app.mobile .feed .card.m-tile::after { display: none; }
.app.mobile .feed .m-tile .mt-img { position: relative; width: 100%; border-radius: 12px; overflow: hidden; background: var(--surface-2); }
.app.mobile .feed .m-tile .mt-img > .tile { position: absolute; inset: 0; width: 100%; height: 100%; max-height: none; min-height: 0; margin: 0; border-radius: 0; background: transparent; }
.app.mobile .feed .m-tile .tile img { width: 100%; height: 100%; object-fit: contain; }
.app.mobile .feed .m-tile .tile:active { transform: none; filter: brightness(.92); }
.mt-n { position: absolute; left: 5px; top: 5px; z-index: 2; height: 18px; padding: 0 6px; border-radius: 6px; display: inline-flex; align-items: center; font-size: 10.5px; font-weight: 600;
    color: #fff; background: rgba(10, 12, 18, .55); pointer-events: none; font-variant-numeric: tabular-nums; }
.mt-more { position: absolute; right: 0; top: 0; z-index: 2; width: 44px; height: 44px; padding: 0; border: 0; background: transparent; display: grid; place-items: center; color: #fff; cursor: pointer; }
.mt-more .mt-dot { width: 28px; height: 28px; border-radius: 14px; display: grid; place-items: center; background: rgba(10, 12, 18, .45); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); box-shadow: inset 0 0 0 .5px rgba(255,255,255,.18); }
.mt-more:active .mt-dot { background: rgba(10, 12, 18, .7); }
.app.mobile .feed .m-tile .mt-cap { display: flex; flex-direction: column; gap: 1px; padding: 4px 3px 0; min-width: 0; }
.app.mobile .feed .m-tile .card-prompt { display: block; font-size: 12px; line-height: 1.4; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; -webkit-line-clamp: unset; }
.app.mobile .feed .m-tile .card-prompt.open { white-space: normal; word-break: break-word; }
.app.mobile .feed .m-tile .mt-meta { display: block; font-size: 10.5px; line-height: 1.35; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* pending batch: placeholder tiles at the expected aspect */
.app.mobile .feed .card.m-tile.job .job-body { position: relative; width: 100%; margin: 0; min-height: 0; max-height: none; padding: 8px 6px; gap: 5px; border-radius: 12px; text-align: center;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    background: linear-gradient(110deg, var(--surface-2) 30%, var(--surface-3) 50%, var(--surface-2) 70%); box-shadow: inset 0 0 0 1px var(--accent-soft); }
.app.mobile .feed .card.m-tile.job .jb-stage { font-size: 11.5px; font-weight: 600; line-height: 1.35; color: var(--text); }
.app.mobile .feed .card.m-tile.job .jb-stage.sub { font-weight: 500; color: var(--text-dim); }
.app.mobile .feed .card.m-tile.job .jb-time { font-size: 10.5px; color: var(--text-dim); }
.app.mobile .feed .card.m-tile.job .jb-time:empty { display: none; }
.app.mobile .feed .card.m-tile.job .job-body .progress { width: 70%; }
.app.mobile .feed .card.m-tile.job .spinner.lg { width: 26px; height: 26px; }
.mt-cancel { position: absolute; right: 0; top: 0; width: 56px; height: 44px; padding: 0; border: 0; background: transparent; display: grid; place-items: center; cursor: pointer; }
.mt-cancel span { height: 24px; padding: 0 9px; border-radius: 8px; display: inline-flex; align-items: center; font-size: 11px; color: var(--text-dim); background: var(--surface); box-shadow: inset 0 0 0 .5px var(--border-strong); }
@media (prefers-reduced-motion: no-preference) {
    .app.mobile .feed .card.m-tile.job.running .job-body { background-size: 300% 100%; animation: mt-shimmer 1.6s linear infinite; }
}
@keyframes mt-shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }
/* compressed dock: row 1 summary + 角色 + 参数 (34px visuals in 44px tap boxes), row 2 prompt + generate */
.app.mobile > .composer.m3 { padding: 2px 7px 7px; gap: 1px; }
.composer.m3 .m-row1 { display: flex; align-items: stretch; gap: 1px; min-width: 0; margin: 0 -5px; }
.composer.m3 .m-row1 .m-sum, .composer.m3 .m-quick { border: 5px solid transparent; background-clip: padding-box; }
.composer.m3 .m-row1 .m-sum { flex: 1; min-height: 44px; height: 44px; padding: 0 6px 0 9px; gap: 6px; border-radius: 17px; }
.composer.m3 .m-row1 .m-sum.warn { border-color: transparent; box-shadow: inset 0 0 0 1px var(--warning); }
.composer.m3 .m-row1 .ms-tx { flex-direction: row; align-items: baseline; gap: 5px; line-height: 1.2; }
.composer.m3 .m-row1 .ms-l1 { flex: none; font-size: 13px; }
.composer.m3 .m-row1 .ms-l2 { flex: 0 1 auto; min-width: 0; font-size: 12px; }
.composer.m3 .m-row1 .ms-l2::before { content: "· "; }
.composer.m3 .m-row1 .ms-cv { width: 22px; height: 22px; border: 0; background: transparent; box-shadow: none; margin-left: auto; }
.composer.m3 .m-quick { flex: none; width: 44px; height: 44px; padding: 0; border-radius: 17px; display: grid; place-items: center; color: var(--text-dim); cursor: pointer; font: inherit;
    background-color: rgba(255,255,255,.07); box-shadow: inset 1px 1px 1px -.5px rgba(255,255,255,.3), inset 0 0 0 .5px rgba(255,255,255,.1); }
[data-theme="light"] .composer.m3 .m-quick { background-color: rgba(255,255,255,.55); box-shadow: inset 1px 1px 1px -.5px #fff, inset 0 0 0 .5px rgba(20,30,60,.1); }
.composer.m3 .m-quick:active { color: var(--text); background-color: rgba(255,255,255,.14); }
.composer.m3 .m-quick .mq-in { display: grid; place-items: center; }
.composer.m3 .m-row2 { display: flex; align-items: stretch; gap: 6px; min-width: 0; }
.composer.m3 .m-row2 .m-prompt { flex: 1; min-width: 0; width: auto; min-height: 44px; height: 44px; padding: 0 6px 0 11px; gap: 7px; border-radius: 13px; font-size: 16px; }
.composer.m3 .m-row2 .mp-cnt { font-size: 11px; padding: 2px 7px; }
.composer.m3 .m-row2 .gen-btn.mobile.big { flex: none; max-width: none; min-width: 0; height: 44px; min-height: 44px; padding: 0 12px; flex-wrap: nowrap; gap: 6px; border-radius: 13px; }
.composer.m3 .m-row2 .gen-btn.mobile.big .gen-label { font-size: 15.5px; }
.composer.m3 .m-row2 .gen-btn.mobile.big .gen-cost { font-size: 11.5px; padding: 1px 7px; }
.composer.m3 .m-row2 .gen-btn.mobile.big > .gen-queue { top: -7px; right: -4px; }
@media (max-width: 380px) { .composer.m3 .m-row2 .gen-btn.mobile.big { padding: 0 9px; } .composer.m3 .m-row2 .gen-btn.mobile.big > svg { display: none; } }
.composer.m3 .m-row2 .mp-cnt { font-size: 0; min-width: 22px; text-align: center; }
.composer.m3 .m-row2 .mp-cnt::after { content: attr(data-short); font-size: 11.5px; }

/* ============ 2.4.15 mobile: the sheets' bottom row = the collapsed dock's row 2 ============
   生成设置 and the prompt sheet get the dock's 44px 生成 button (same size / label / 点 pill / radius) and a 44px one-line card,
   at the dock's position (16px side inset, 16px + safe area from the bottom; the sheet's own padding already holds the safe area,
   so the foot no longer adds it twice). Scoped to .m-bottom.m3 and mobile sheets: the dock and desktop are untouched. */
.m-bottom.m3 .m-row2 { display: flex; align-items: stretch; gap: 6px; min-width: 0; }
.m-bottom.m3 .m-row2 .gen-btn.mobile.big { flex: none; max-width: none; min-width: 0; height: 44px; min-height: 44px; padding: 0 12px; flex-wrap: nowrap; gap: 6px; border-radius: 13px; }
.m-bottom.m3 .m-row2 .gen-btn.mobile.big .gen-label { font-size: 15.5px; }
.m-bottom.m3 .m-row2 .gen-btn.mobile.big .gen-cost { font-size: 11.5px; padding: 1px 7px; }
.m-bottom.m3 .m-row2 .gen-btn.mobile.big > .gen-queue { top: -7px; right: -4px; }
@media (max-width: 380px) { .m-bottom.m3 .m-row2 .gen-btn.mobile.big { padding: 0 9px; } .m-bottom.m3 .m-row2 .gen-btn.mobile.big > svg { display: none; } }
.m-bottom.m3 .m-row2 .m-sum { flex: 1; min-width: 0; min-height: 44px; height: 44px; padding: 0 6px 0 11px; gap: 7px; border-radius: 13px; }
.m-bottom.m3 .m-row2 .m-sum.warn { box-shadow: inset 0 0 0 1px var(--warning); }
.m-bottom.m3 .m-row2 .ms-tx { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: row; align-items: baseline; gap: 5px; line-height: 1.2; overflow: hidden; }
.m-bottom.m3 .m-row2 .ms-l1 { flex: none; font-size: 13px; }
.m-bottom.m3 .m-row2 .ms-l2 { flex: 0 1 auto; min-width: 0; font-size: 12px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.m-bottom.m3 .m-row2 .ms-l2::before { content: "· "; }
.m-bottom.m3 .m-row2 .ms-cv { flex: none; width: 22px; height: 22px; border: 0; background: transparent; box-shadow: none; margin-left: auto; display: grid; place-items: center; color: var(--text-dim); }
.m-bottom.m3 .m-row2 .m-sum.as-prompt .ms-ic { flex: none; display: grid; place-items: center; color: var(--text-dim); margin-right: -1px; }
.layer .layer-panel.sheet:is(.m-pinned, .m-psheet-panel) .layer-foot { padding-left: 15px; padding-right: 15px; padding-bottom: 16px; }

/* ============ 2.4.15-beta2 mobile: iOS keyboard without the sheet jumping ============
   With the keyboard up the sheet keeps its top edge where it is on screen; JS writes --kbsheet = visual height - that top
   (pinToViewport), only the bottom edge follows the keyboard. The editors give up their 120px floor so they shrink inside
   (the caret is revealed by scrolling the editor). Mobile sheets only: desktop untouched. */
.layer.kb-open .layer-panel.sheet.m-psheet-panel:not(.full) { height: var(--kbsheet, calc(var(--vvh) - 12px)); max-height: none; }
.layer.kb-open .layer-panel.sheet.m-pinned { height: var(--kbsheet, auto); }
.layer.kb-open .layer-panel.sheet.m-psheet-panel .mp-pane :is(.prompt-ta, .tag-ed) { min-height: 72px; }
/* ============ 2.4.15-beta3 mobile: tag autocomplete in the prompt sheet (fix 2) ============
   JS (dom.js placeSheetList) floats the list next to the caret, above the keyboard / bottom bar, outside the editor scrollers
   that clipped it to 0-2 rows; it sets top / left / width / --acmax inline. Desktop lists are untouched. */
.mp-pane .prompt-wrap .ac-list.m-float { position: fixed; right: auto; bottom: auto; max-height: var(--acmax, 300px); }
