diff --git a/src/components/ai-edition/NewEditorShell.module.css b/src/components/ai-edition/NewEditorShell.module.css index bb96cc6c..19928dbe 100644 --- a/src/components/ai-edition/NewEditorShell.module.css +++ b/src/components/ai-edition/NewEditorShell.module.css @@ -1,2212 +1,2280 @@ -/* Editor shell — 4-row grid: titlebar · workbench · handle · bottombar. - * Mirrors design/openscreen-editor.html. Tokens come from - * src/styles/design-tokens.css (light + dark via :root[data-theme="dark"]). */ - -.app { - display: grid; - grid-template-rows: var(--titlebar-h) 1fr var(--handle-h) var(--bottom-h); - height: 100vh; - min-width: 1024px; - background: var(--bg); - color: var(--fg); - font-family: var(--font-body); - font-size: var(--fs-app); - line-height: 1.5; - overflow: hidden; - user-select: none; -} - -.app[data-collapse~="left"] { - --panel-w-left: 0px; -} -.app[data-collapse~="left"] .leftRail, -.app[data-collapse~="left"] .leftPanel, -.app[data-collapse~="left"] .handleLeft { - display: none; -} - -.app[data-collapse~="right"] { - --panel-w-right: 0px; -} -.app[data-collapse~="right"] .rightStack, -.app[data-collapse~="right"] .rightRail, -.app[data-collapse~="right"] .handleRight { - display: none; -} - -.app[data-collapse~="bottom"] { - --bottom-h: 0px; -} -.app[data-collapse~="bottom"] .bottombar { - display: none; -} -.app[data-collapse~="bottom"] .handleBottom { - display: none; -} - -/* ─── titlebar ──────────────────────────────────────────────────── */ -.titlebar { - display: flex; - align-items: center; - gap: var(--sp-3); - padding-inline: var(--sp-4); - background: var(--bg); - border-bottom: 1px solid var(--border-soft); - min-width: 0; - /* ponytail: make the titlebar the drag region in Electron. The buttons - * opt out via inline -webkit-app-region: no-drag (see Titlebar.tsx). */ - -webkit-app-region: drag; - app-region: drag; -} -.titlebar button, -.titlebar input, -.titlebar select, -.titlebar textarea, -.titlebar .langSel, -.titlebar .recorderBtn { - -webkit-app-region: no-drag; - app-region: no-drag; -} -.titlebar .lights { - display: inline-flex; - gap: 6px; - margin-right: var(--sp-3); -} -.titlebar .lights span { - width: 11px; - height: 11px; - border-radius: 50%; - border: 1px solid var(--overlay-border); -} -.titlebar .lights .r { background: var(--light-red); } -.titlebar .lights .y { background: var(--light-yellow); } -.titlebar .lights .g { background: var(--light-green); } - -.titlebar .brand { - display: inline-flex; - align-items: center; - gap: 8px; - font-family: var(--font-display); - font-size: var(--fs-title); - font-weight: 500; - letter-spacing: -0.005em; - color: var(--fg); -} -.titlebar .brandMark { - width: 18px; - height: 18px; - border-radius: 5px; - background: var(--accent); - display: grid; - place-items: center; - color: var(--accent-on); - font: 600 11px/1 var(--font-display); -} -.titlebar .sep { - width: 1px; - height: 16px; - background: var(--border); -} -.titlebar .project { - display: inline-flex; - align-items: center; - gap: var(--sp-2); - font-size: var(--fs-app); - color: var(--muted); - min-width: 0; -} -.titlebar .projectName { - color: var(--fg-2); - font-weight: 500; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-width: 280px; - background: transparent; - border: 0; - padding: 2px 6px; - border-radius: var(--r-sm); - cursor: text; - font: inherit; - -webkit-app-region: no-drag; - app-region: no-drag; -} -.titlebar .projectName:hover:not(:disabled) { - background: var(--surface-3); -} -.titlebar .projectInput { - background: var(--surface); - color: var(--fg); - border: 1px solid var(--accent); - border-radius: var(--r-sm); - padding: 2px 6px; - font: 500 13px var(--font-body); - outline: none; - min-width: 200px; - max-width: 360px; - -webkit-app-region: no-drag; - app-region: no-drag; -} -.titlebar .saved { - display: inline-flex; - align-items: center; - gap: 6px; - font-family: var(--font-mono); - font-size: var(--fs-app-sm); - color: var(--muted); -} -.titlebar .saved .dot { - width: 6px; - height: 6px; - border-radius: 50%; - background: var(--success); -} -.titlebar .projActions { - display: inline-flex; - align-items: center; - gap: var(--sp-1); - margin-right: var(--sp-1); -} -.titlebar .right { - margin-left: auto; - display: inline-flex; - align-items: center; - gap: var(--sp-1); -} -.titlebar .iconBtn { - width: 28px; - height: 28px; - display: grid; - place-items: center; - border-radius: var(--r-sm); - color: var(--muted); - background: transparent; - border: 0; - cursor: pointer; - transition: background var(--motion-fast) var(--ease), color var(--motion-fast) var(--ease); -} -.titlebar .iconBtn:hover { - background: var(--surface-3); - color: var(--fg); -} -.titlebar .iconBtn[aria-pressed="true"] { - background: var(--accent-soft); - color: var(--accent); -} -.titlebar .langSel { - display: inline-flex; - align-items: center; - gap: 6px; - height: 26px; - padding: 0 6px; - background: transparent; - border: 1px solid var(--border-soft); - border-radius: var(--r-md); - color: var(--fg-2); - font: 500 var(--fs-app)/1 var(--font-display); - cursor: pointer; - transition: background var(--motion-fast) var(--ease), border-color var(--motion-fast) var(--ease), color var(--motion-fast) var(--ease); -} -.titlebar .langSel:hover { - background: var(--surface-3); - border-color: var(--border); - color: var(--fg); -} -.titlebar .recorderBtn { - display: inline-flex; - align-items: center; - gap: 6px; - height: 26px; - padding: 0 10px 0 8px; - border-radius: var(--r-md); - background: var(--accent-soft); - color: var(--accent); - border: 1px solid color-mix(in oklch, var(--accent) 22%, transparent); - transition: background var(--motion-fast) var(--ease), color var(--motion-fast) var(--ease); - font: 500 var(--fs-app-sm)/1 var(--font-display); - letter-spacing: 0.01em; - cursor: pointer; -} -.titlebar .recorderBtn:hover { - background: color-mix(in oklch, var(--accent) 18%, var(--surface-3)); -} - -/* ─── workbench — 7 columns: rail · panel · handle · preview · handle · stack · rail */ -.workbench { - display: grid; - grid-template-columns: - var(--rail-w) - var(--panel-w-left) - var(--handle-w) - 1fr - var(--handle-w) - var(--panel-w-right) - var(--rail-w); - min-height: 0; - background: var(--bg); - overflow: hidden; -} -.workbench > * { - min-height: 0; -} -.workbench > * + * { - border-left: 1px solid var(--border-soft); -} - -.leftPanel { - display: flex; - flex-direction: column; - overflow: hidden; - min-height: 0; -} - -/* ─── rails — vertical icon strips ─────────────────────────────── */ -.rail { - display: flex; - flex-direction: column; - align-items: center; - gap: var(--sp-1); - padding: var(--sp-2) 0; - background: var(--bg); - min-width: 0; -} -.rail button { - width: 36px; - height: 36px; - display: grid; - place-items: center; - border-radius: var(--r-md); - color: var(--muted); - background: transparent; - border: 0; - cursor: pointer; - transition: background var(--motion-fast) var(--ease), color var(--motion-fast) var(--ease); - position: relative; -} -.rail button:hover { - background: var(--surface-3); - color: var(--fg); -} -.rail button[aria-pressed="true"] { - color: var(--accent); - background: var(--accent-soft); -} -.rail button[aria-pressed="true"]::before { - content: ""; - position: absolute; - left: -8px; - top: 8px; - bottom: 8px; - width: 3px; - border-radius: 2px; - background: var(--accent); -} -.rail .sepH { - width: 24px; - height: 1px; - background: var(--border); - margin: var(--sp-1) 0; -} - -/* ─── panels (chat, transcript, etc.) ──────────────────────────── */ -.panel { - display: flex; - flex-direction: column; - flex: 1 1 0; - min-width: 0; - min-height: 0; - background: var(--bg); - overflow: hidden; -} - -/* Direct children of .panel: panelHeader (auto), panelBody (1fr), chatInput (auto). */ -.panel > .panelHeader, -.panel > .chatInput { - flex: 0 0 auto; -} -.panel > .panelBody { - flex: 1 1 0; -} -.panelHead { - display: flex; - align-items: center; - gap: var(--sp-2); - padding: var(--sp-3) var(--sp-4); - border-bottom: 1px solid var(--border-soft); - min-height: 44px; -} -.panelHead h2 { - margin: 0; - font-family: var(--font-display); - font-size: 14px; - font-weight: 500; - letter-spacing: -0.005em; - color: var(--fg); -} -.panelHead .right { - margin-left: auto; - display: inline-flex; - gap: var(--sp-1); -} -.panelHead .iconBtn { - width: 24px; - height: 24px; - display: grid; - place-items: center; - border-radius: var(--r-sm); - color: var(--meta); - background: transparent; - border: 0; - cursor: pointer; - transition: background var(--motion-fast) var(--ease), color var(--motion-fast) var(--ease); -} -.panelHead .iconBtn:hover { - background: var(--surface-3); - color: var(--fg-2); -} -.panelBody { - overflow-y: auto; - padding: var(--sp-3) var(--sp-4); - scrollbar-width: thin; - scrollbar-color: var(--border) transparent; - min-height: 0; -} -.panelBody::-webkit-scrollbar { - width: 8px; - height: 8px; -} -.panelBody::-webkit-scrollbar-thumb { - background: var(--border); - border-radius: 4px; -} -.panelBody::-webkit-scrollbar-thumb:hover { - background: var(--border-hi); -} - -/* ─── resize handles ───────────────────────────────────────────── */ -.handle { - background: transparent; - position: relative; - z-index: 2; - transition: background var(--motion-fast) var(--ease); - cursor: col-resize; -} -.handleRow { - cursor: row-resize; - grid-column: 1 / -1; - border-bottom: 1px solid var(--border); -} -.handle:hover, -.handle.isDragging { - background: var(--surface-2); -} -.handle::before, -.handle::after { - content: ""; - position: absolute; - background: var(--dim); - border-radius: 1px; - opacity: 0.45; - transition: opacity var(--motion-fast) var(--ease); - pointer-events: none; -} -.handleCol::before, -.handleCol::after { - left: 50%; - width: 1px; - height: 14px; - transform: translateX(-50%); -} -.handleCol::before { top: calc(50% - 16px); } -.handleCol::after { top: calc(50% + 2px); } -.handleRow::before, -.handleRow::after { - top: 50%; - height: 1px; - width: 14px; - transform: translateY(-50%); -} -.handleRow::before { left: calc(50% - 16px); } -.handleRow::after { left: calc(50% + 2px); } -.handle:hover::before, -.handle:hover::after, -.handle.isDragging::before, -.handle.isDragging::after { - opacity: 1; -} -.handle.isDragging { - background: var(--accent-soft); -} - -/* ─── preview area ─────────────────────────────────────────────── */ -/* ponytail: the stage wrapper (in NewEditorShell.tsx) already provides the - padding that reserves room for the floating inspector, and .stage paints the - scene gradient. previewWrap is a single transparent, zero-padding centering - layer so the wallpaper card floats on that gradient — matching the design's - stage-wrap (one framed card, no surface slab, no double padding). It is also - the positioned ancestor for the timecode/badge overlays and the box the - frame measures for its contain-fit. */ -.previewWrap { - position: relative; - display: grid; - place-items: center; - width: 100%; - height: 100%; - min-width: 0; - min-height: 0; -} -.previewFrame { - position: relative; - aspect-ratio: 16 / 9; - max-width: 100%; - max-height: 100%; - width: 100%; - min-width: 0; - min-height: 0; - background: - radial-gradient(ellipse at 50% 35%, - var(--scene-sky-hi) 0%, - var(--scene-sky-mid) 35%, - var(--scene-foliage) 70%, - var(--scene-foliage-d) 100%); - /* ponytail: the wallpaper card is a floating, rounded surface (per the v4 - design's preview frame) — rounded corners + a layered drop shadow lift it - off the scene gradient. The custom background (buildFrameStyle) fills this - card; the video sits on top with its own padding so the wallpaper shows - around it. */ - border-radius: 16px; - box-shadow: - 0 40px 90px -30px rgba(0, 0, 0, 0.75), - 0 12px 28px -12px rgba(0, 0, 0, 0.5), - inset 0 0 0 1px rgba(255, 255, 255, 0.09); - overflow: hidden; - display: grid; - place-items: center; -} -.videoStage { - position: relative; - display: grid; - place-items: center; - min-width: 0; - min-height: 0; - overflow: visible; - z-index: 1; -} -.screenStage { - position: absolute; - overflow: hidden; - z-index: 1; - display: flex; -} -.screenStage > .container, -.screenStage > div > .container { - width: 100%; - height: 100%; -} -.previewEmpty { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: 8px; - color: var(--muted); - font-size: var(--fs-app); -} -.previewEmpty strong { color: var(--fg-2); } - -/* ─── preview empty state (no project / no asset) ───────────────── */ -.previewEmptyDrop { - position: relative; - width: 100%; - height: 100%; - display: flex; - align-items: center; - justify-content: center; -} -.previewEmptyDropOverlay { - position: absolute; - inset: 0; - z-index: 10; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - gap: var(--sp-2); - border: 2px dashed var(--primary, #34B27B); - background: color-mix(in srgb, var(--primary, #34B27B) 10%, transparent); - border-radius: var(--r-sm); - pointer-events: none; -} -.previewEmptyDropIcon { - width: 40px; - height: 40px; - color: var(--primary, #34B27B); -} -.previewEmptyDropLabel { - font-size: var(--fs-app); - font-weight: 600; - color: var(--primary, #34B27B); -} -.previewEmptyInner { - display: flex; - flex-direction: column; - align-items: center; - gap: var(--sp-4); - padding: var(--sp-5); - text-align: center; - max-width: 28rem; -} -.previewEmptyLogo { - width: 64px; - height: 64px; - border-radius: var(--r-md); - opacity: 0.9; -} -.previewEmptyHeading { - display: flex; - flex-direction: column; - gap: var(--sp-1); -} -.previewEmptyTitle { - margin: 0; - font-size: 1.25rem; - font-weight: 600; - color: var(--fg-2); -} -.previewEmptyDescription { - margin: 0; - font-size: 0.875rem; - color: var(--muted); - line-height: 1.5; -} -.previewEmptyActions { - display: flex; - flex-direction: column; - gap: var(--sp-2); - width: 100%; - max-width: 18rem; -} -.previewEmptyPrimaryButton { - display: flex; - align-items: center; - justify-content: center; - gap: var(--sp-2); - padding: var(--sp-3) var(--sp-4); - border-radius: var(--r-sm); - background: var(--primary, #34B27B); - color: #fff; - border: none; - font-weight: 500; - font-size: 0.875rem; - cursor: pointer; - transition: background-color 120ms ease; -} -.previewEmptyPrimaryButton:hover { - filter: brightness(0.95); -} -.previewEmptySecondaryButton { - display: flex; - align-items: center; - justify-content: center; - gap: var(--sp-2); - padding: var(--sp-3) var(--sp-4); - border-radius: var(--r-sm); - background: var(--card); - color: var(--fg-2); - border: 1px solid var(--border); - font-weight: 500; - font-size: 0.875rem; - cursor: pointer; - transition: background-color 120ms ease; -} -.previewEmptySecondaryButton:hover { - background: var(--accent, rgba(255, 255, 255, 0.06)); -} -.previewEmptyButtonIcon { - width: 16px; - height: 16px; -} -.previewEmptyHint { - margin: 0; - font-size: 0.75rem; - color: var(--muted-foreground, rgba(255, 255, 255, 0.5)); -} -.previewEmptyDragHint { - display: flex; - align-items: center; - gap: var(--sp-1); - margin: 0; - font-size: 0.75rem; - color: var(--muted-foreground, rgba(255, 255, 255, 0.4)); -} -.previewEmptyDragHintIcon { - width: 12px; - height: 12px; -} -.previewEmptyDialog { - max-width: 24rem; - padding: var(--sp-5); - background: var(--bg); - border: 1px solid var(--border); -} -.previewEmptyDialogHeader { - margin-bottom: var(--sp-3); -} -.previewEmptyDialogHeaderInner { - display: flex; - align-items: center; - gap: var(--sp-2); -} -.previewEmptyDialogLogo { - width: 36px; - height: 36px; - border-radius: var(--r-sm); - flex-shrink: 0; -} -.previewEmptyDialogTitle { - font-size: 1rem; - font-weight: 600; - color: var(--fg-2); - line-height: 1.2; -} -.previewEmptyDialogBody { - display: flex; - flex-direction: column; - align-items: center; - gap: var(--sp-2); - margin-bottom: var(--sp-4); - text-align: center; -} -.previewEmptyDialogIcon { - display: flex; - align-items: center; - justify-content: center; - width: 40px; - height: 40px; - border-radius: 9999px; - background: var(--card); - border: 1px solid var(--border); -} -.previewEmptyDialogAlertIcon { - width: 20px; - height: 20px; - color: var(--muted); -} -.previewEmptyDialogMessage { - margin: 0; - font-size: 0.875rem; - color: var(--muted); - line-height: 1.5; -} -.previewEmptyDialogClose { - display: flex; - align-items: center; - justify-content: center; - gap: var(--sp-1); - width: 100%; - padding: var(--sp-2) var(--sp-3); - border-radius: var(--r-sm); - background: var(--card); - color: var(--fg-2); - border: 1px solid var(--border); - font-size: 0.875rem; - font-weight: 500; - cursor: pointer; -} -.previewEmptyDialogCloseIcon { - width: 14px; - height: 14px; -} -.previewPip { - position: absolute; - right: var(--sp-3); - bottom: var(--sp-3); - width: 120px; - aspect-ratio: 16 / 9; - border-radius: var(--r-sm); - background: linear-gradient(135deg, var(--pip-bg-1) 0%, var(--pip-bg-2) 50%, var(--pip-bg-3) 100%); - border: 2px solid var(--bg); - box-shadow: var(--elev-card); - overflow: hidden; - display: grid; - place-items: center; - color: var(--overlay-text); - font-family: var(--font-mono); - font-size: 9px; - letter-spacing: 0.06em; - text-transform: uppercase; -} -.previewFrame > .screenStage video { - position: relative; - z-index: 1; - /* Pixels come from the native canvas now; this