|
40 | 40 | flex: 1; |
41 | 41 | min-height: 0; |
42 | 42 | overflow: hidden; |
| 43 | + // Positioning context for the onboarding prompt overlay, which is |
| 44 | + // detached from its template position and re-parented here so it |
| 45 | + // covers the Files/AI tab strip as well as the panel body. |
| 46 | + position: relative; |
43 | 47 | } |
44 | 48 |
|
45 | 49 | .ai-chat-panel { |
|
145 | 149 | .ai-chat-panel.ai-history-open { |
146 | 150 | > .ai-chat-messages, |
147 | 151 | > .ai-chat-status, |
148 | | - > .ai-chat-input-area { |
| 152 | + > .ai-chat-input-area, |
| 153 | + > .ai-onboarding-wrap { |
149 | 154 | display: none !important; |
150 | 155 | } |
151 | 156 | } |
|
265 | 270 | } |
266 | 271 | } |
267 | 272 |
|
| 273 | +/* ── Onboarding iframe (guided AI starter) ──────────────────────────── */ |
| 274 | +/* The wrap sits where .ai-chat-messages would. When visible it claims |
| 275 | + the same flex slot — when hidden the chat takes that slot back. */ |
| 276 | +.ai-onboarding-wrap { |
| 277 | + flex: 1; |
| 278 | + min-height: 0; |
| 279 | + min-width: 0; |
| 280 | + position: relative; |
| 281 | + background-color: @bc-ai-sidebar-bg; |
| 282 | + |
| 283 | + .ai-onboarding-frame { |
| 284 | + width: 100%; |
| 285 | + height: 100%; |
| 286 | + border: 0; |
| 287 | + display: block; |
| 288 | + } |
| 289 | +} |
| 290 | + |
| 291 | +/* Prompt confirm overlay — top-level rule (NOT nested under |
| 292 | + .ai-onboarding-wrap) because at runtime _initOnboarding detaches |
| 293 | + the overlay element and re-parents it to .ai-tab-container so it |
| 294 | + covers the Files/AI tab strip in addition to the panel body. |
| 295 | + Neutral dark-panel chrome — no blue accent. Title strip + full- |
| 296 | + bleed textarea + bottom action row with Cancel and an icon-only |
| 297 | + send button that mirrors .ai-send-btn's transparent quiet style. */ |
| 298 | +.ai-onboarding-prompt-overlay { |
| 299 | + position: absolute; |
| 300 | + inset: 0; |
| 301 | + z-index: 10; |
| 302 | + background: rgba(0, 0, 0, 0.45); |
| 303 | + display: flex; |
| 304 | + align-items: center; |
| 305 | + justify-content: center; |
| 306 | + padding: 16px; |
| 307 | + animation: ai-onboarding-overlay-fade 0.15s ease-out; |
| 308 | + |
| 309 | + .ai-onboarding-prompt-card { |
| 310 | + width: 100%; |
| 311 | + max-width: 440px; |
| 312 | + border: 1px solid @bc-ai-input-border; |
| 313 | + border-radius: 8px; |
| 314 | + background: @bc-ai-sidebar-bg; |
| 315 | + overflow: hidden; |
| 316 | + display: flex; |
| 317 | + flex-direction: column; |
| 318 | + box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45); |
| 319 | + animation: ai-onboarding-card-pop 0.18s ease-out; |
| 320 | + } |
| 321 | + |
| 322 | + .ai-onboarding-prompt-header { |
| 323 | + display: flex; |
| 324 | + align-items: center; |
| 325 | + gap: 8px; |
| 326 | + padding: 8px 8px 8px 14px; |
| 327 | + border-bottom: 1px solid rgba(255, 255, 255, 0.06); |
| 328 | + } |
| 329 | + |
| 330 | + .ai-onboarding-prompt-title { |
| 331 | + flex: 1; |
| 332 | + min-width: 0; |
| 333 | + font-size: @ai-text-body; |
| 334 | + font-weight: 600; |
| 335 | + color: @project-panel-text-1; |
| 336 | + line-height: 1.3; |
| 337 | + } |
| 338 | + |
| 339 | + .ai-onboarding-prompt-close { |
| 340 | + background: none; |
| 341 | + border: 0; |
| 342 | + color: @project-panel-text-2; |
| 343 | + width: 26px; |
| 344 | + height: 26px; |
| 345 | + border-radius: 4px; |
| 346 | + cursor: pointer; |
| 347 | + display: flex; |
| 348 | + align-items: center; |
| 349 | + justify-content: center; |
| 350 | + opacity: 0.55; |
| 351 | + flex-shrink: 0; |
| 352 | + transition: opacity 0.15s ease, color 0.15s ease, background-color 0.15s ease; |
| 353 | + |
| 354 | + i { font-size: 0.95em; } |
| 355 | + |
| 356 | + &:hover { |
| 357 | + opacity: 1; |
| 358 | + color: @project-panel-text-1; |
| 359 | + background: rgba(255, 255, 255, 0.05); |
| 360 | + } |
| 361 | + } |
| 362 | + |
| 363 | + .ai-onboarding-prompt-text { |
| 364 | + // display: block + width: 100% + box-sizing makes the textarea |
| 365 | + // span the card's full inner width regardless of the rows attr |
| 366 | + // or the browser's textarea default width. |
| 367 | + display: block; |
| 368 | + width: 100%; |
| 369 | + box-sizing: border-box; |
| 370 | + background: @bc-ai-input-bg; |
| 371 | + border: 0; |
| 372 | + border-radius: 0; |
| 373 | + color: @project-panel-text-1; |
| 374 | + font-size: @ai-text-body; |
| 375 | + line-height: @ai-line-prose; |
| 376 | + padding: 12px 14px; |
| 377 | + resize: vertical; |
| 378 | + min-height: 110px; |
| 379 | + max-height: 260px; |
| 380 | + outline: none; |
| 381 | + box-shadow: none; |
| 382 | + |
| 383 | + // Phoenix's global textarea focus rule paints a border + shadow |
| 384 | + // that shifts the dialog by ~2px and reads as a flicker. Force |
| 385 | + // the no-chrome focus state so only the bg darkening signals |
| 386 | + // focus. |
| 387 | + &:focus, |
| 388 | + &:focus-visible { |
| 389 | + background: @bc-ai-input-bg-focused; |
| 390 | + border: 0; |
| 391 | + outline: none; |
| 392 | + box-shadow: none; |
| 393 | + } |
| 394 | + } |
| 395 | + |
| 396 | + .ai-onboarding-prompt-actions { |
| 397 | + display: flex; |
| 398 | + justify-content: flex-end; |
| 399 | + align-items: center; |
| 400 | + gap: 4px; |
| 401 | + padding: 6px 8px 6px 12px; |
| 402 | + border-top: 1px solid rgba(255, 255, 255, 0.06); |
| 403 | + } |
| 404 | + |
| 405 | + .ai-onboarding-prompt-cancel { |
| 406 | + background: transparent; |
| 407 | + border: 0; |
| 408 | + color: @project-panel-text-2; |
| 409 | + font-size: @ai-text-secondary; |
| 410 | + line-height: @ai-line-compact; |
| 411 | + padding: 6px 10px; |
| 412 | + border-radius: 4px; |
| 413 | + cursor: pointer; |
| 414 | + transition: background-color 0.15s ease, color 0.15s ease; |
| 415 | + |
| 416 | + &:hover { |
| 417 | + background: rgba(255, 255, 255, 0.05); |
| 418 | + color: @project-panel-text-1; |
| 419 | + } |
| 420 | + } |
| 421 | + |
| 422 | + .ai-onboarding-prompt-send { |
| 423 | + background: none; |
| 424 | + border: 0; |
| 425 | + color: @project-panel-text-2; |
| 426 | + width: 32px; |
| 427 | + height: 28px; |
| 428 | + border-radius: 4px; |
| 429 | + cursor: pointer; |
| 430 | + display: flex; |
| 431 | + align-items: center; |
| 432 | + justify-content: center; |
| 433 | + opacity: 0.6; |
| 434 | + transition: opacity 0.15s ease, color 0.15s ease, background-color 0.15s ease; |
| 435 | + |
| 436 | + i { font-size: 0.95em; } |
| 437 | + |
| 438 | + &:hover { |
| 439 | + opacity: 1; |
| 440 | + color: @project-panel-text-1; |
| 441 | + background: rgba(255, 255, 255, 0.05); |
| 442 | + } |
| 443 | + } |
| 444 | +} |
| 445 | + |
268 | 446 | /* ── Message list ───────────────────────────────────────────────────── */ |
269 | 447 | .ai-chat-messages { |
270 | 448 | flex: 1; |
|
2892 | 3070 | } |
2893 | 3071 | } |
2894 | 3072 |
|
| 3073 | +/* Onboarding prompt overlay entrance animations. Kept at file scope so |
| 3074 | + the keyframes resolve regardless of nesting context. */ |
| 3075 | +@keyframes ai-onboarding-overlay-fade { |
| 3076 | + from { opacity: 0; } |
| 3077 | + to { opacity: 1; } |
| 3078 | +} |
| 3079 | + |
| 3080 | +@keyframes ai-onboarding-card-pop { |
| 3081 | + from { |
| 3082 | + opacity: 0; |
| 3083 | + transform: scale(0.96) translateY(6px); |
| 3084 | + } |
| 3085 | + to { |
| 3086 | + opacity: 1; |
| 3087 | + transform: scale(1) translateY(0); |
| 3088 | + } |
| 3089 | +} |
| 3090 | + |
0 commit comments