Changeset 3428373
- Timestamp:
- 12/27/2025 07:58:01 PM (2 months ago)
- Location:
- iris-ai
- Files:
-
- 40 added
- 3 edited
-
tags/1.0.5 (added)
-
tags/1.0.5/assets (added)
-
tags/1.0.5/assets/css (added)
-
tags/1.0.5/assets/css/admin.css (added)
-
tags/1.0.5/assets/css/front.css (added)
-
tags/1.0.5/assets/css/widget.css (added)
-
tags/1.0.5/assets/js (added)
-
tags/1.0.5/assets/js/admin-chat.js (added)
-
tags/1.0.5/assets/js/admin-provider-toggle.js (added)
-
tags/1.0.5/assets/js/admin-usage-guide.js (added)
-
tags/1.0.5/assets/js/admin-vector-index.js (added)
-
tags/1.0.5/assets/js/chatbox.js (added)
-
tags/1.0.5/assets/js/libs (added)
-
tags/1.0.5/assets/js/libs/sine-waves.min.js (added)
-
tags/1.0.5/assets/js/libs/three.min.js (added)
-
tags/1.0.5/assets/js/widget.js (added)
-
tags/1.0.5/assets/logo-transparent.png (added)
-
tags/1.0.5/includes (added)
-
tags/1.0.5/includes/class-irisai-admin.php (added)
-
tags/1.0.5/includes/class-irisai-context-builder.php (added)
-
tags/1.0.5/includes/class-irisai-post-meta.php (added)
-
tags/1.0.5/includes/class-irisai-rest.php (added)
-
tags/1.0.5/includes/class-irisai-settings.php (added)
-
tags/1.0.5/includes/class-irisai-shortcodes.php (added)
-
tags/1.0.5/includes/class-irisai-vector-db.php (added)
-
tags/1.0.5/includes/class-irisai-vector-integration.php (added)
-
tags/1.0.5/includes/class-irisai-widget.php (added)
-
tags/1.0.5/includes/settings (added)
-
tags/1.0.5/includes/settings/traits (added)
-
tags/1.0.5/includes/settings/traits/trait-settings-advancedfields.php (added)
-
tags/1.0.5/includes/settings/traits/trait-settings-apifields.php (added)
-
tags/1.0.5/includes/settings/traits/trait-settings-chatpagefields.php (added)
-
tags/1.0.5/includes/settings/traits/trait-settings-generalfields.php (added)
-
tags/1.0.5/includes/settings/traits/trait-settings-uifields.php (added)
-
tags/1.0.5/includes/settings/traits/trait-settings-usagefields.php (added)
-
tags/1.0.5/includes/settings/traits/trait-settings-vector-indexing.php (added)
-
tags/1.0.5/includes/settings/traits/trait-settings-widgetfields.php (added)
-
tags/1.0.5/iris-ai.php (added)
-
tags/1.0.5/readme.txt (added)
-
tags/1.0.5/uninstall.php (added)
-
trunk/assets/css/front.css (modified) (1 diff)
-
trunk/iris-ai.php (modified) (2 diffs)
-
trunk/readme.txt (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
iris-ai/trunk/assets/css/front.css
r3424224 r3428373 1 1 /* === Enhanced IrisAI theme variables === */ 2 :root { 3 /* Primary colors */ 4 --irisai-primary: #2563eb; 5 --irisai-primary-hover: #1d4ed8; 6 --irisai-primary-text: #ffffff; 7 8 /* Secondary colors */ 9 --irisai-secondary: #7c3aed; 10 --irisai-secondary-hover: #6d28d9; 11 --irisai-secondary-text: #ffffff; 12 13 /* Accent colors */ 14 --irisai-accent: #10b981; 15 --irisai-accent-hover: #059669; 16 --irisai-accent-text: #ffffff; 17 18 /* Background colors */ 19 --irisai-card-bg: rgba(255, 255, 255, 0.9); 20 --irisai-card-border: rgba(0, 0, 0, 0.1); 21 --irisai-input-bg: rgba(255, 255, 255, 0.9); 22 --irisai-input-border: rgba(0, 0, 0, 0.12); 23 24 /* Text colors */ 25 --irisai-text-primary: inherit; 26 --irisai-text-secondary: inherit; 27 --irisai-text-muted: rgba(0, 0, 0, 0.6); 28 29 /* Interactive elements */ 30 --irisai-chip-bg: rgba(255, 255, 255, 0.9); 31 --irisai-chip-hover-bg: var(--irisai-primary); 32 --irisai-chip-hover-text: var(--irisai-primary-text); 33 34 /* Layout */ 35 --irisai-radius: 14px; 36 --irisai-shadow-color: rgba(0, 0, 0, 0.1); 37 38 /* Animation timings */ 39 --irisai-transition-fast: 0.15s; 40 --irisai-transition-normal: 0.25s; 41 --irisai-transition-slow: 0.35s; 42 43 /* Error and status colors */ 44 --irisai-error-color: #dc2626; 45 --irisai-warning-color: #f59e0b; 46 --irisai-info-color: #3b82f6; 47 } 48 49 /* Performance optimization */ 50 * { 51 -webkit-font-smoothing: antialiased; 52 -moz-osx-font-smoothing: grayscale; 53 } 54 55 /* Container */ 56 .irisai-landing { 57 padding: clamp(24px, 5vw, 48px) 0; 58 color: var(--irisai-text-primary, inherit); 59 font-family: inherit; 60 position: relative; 61 overflow-x: hidden; 62 } 63 64 .irisai-wrap { 65 max-width: 1400px; 66 margin: 0 auto; 67 padding: 0 clamp(16px, 4vw, 32px); 68 } 69 70 /* === Privacy & Security Modal Styles === */ 71 .irisai-modal { 72 position: fixed; 73 top: 0; 74 left: 0; 75 right: 0; 76 bottom: 0; 77 z-index: 999999; 78 display: flex; 79 align-items: center; 80 justify-content: center; 81 padding: 16px; 82 } 83 84 .irisai-modal-backdrop { 85 position: absolute; 86 top: 0; 87 left: 0; 88 right: 0; 89 bottom: 0; 90 background: rgba(0, 0, 0, 0.7); 91 backdrop-filter: blur(8px); 92 animation: fadeIn var(--irisai-transition-normal) ease; 93 } 94 95 .irisai-modal-content { 96 position: relative; 97 background: var(--irisai-card-bg); 98 border-radius: calc(var(--irisai-radius) + 8px); 99 box-shadow: 100 0 20px 40px rgba(0, 0, 0, 0.3), 101 0 8px 16px rgba(0, 0, 0, 0.2); 102 backdrop-filter: blur(16px); 103 border: 1px solid var(--irisai-card-border); 104 max-width: 480px; 105 width: 100%; 106 animation: slideInModal var(--irisai-transition-slow) ease; 107 } 108 109 @keyframes slideInModal { 110 from { 111 opacity: 0; 112 transform: translateY(-30px) scale(0.95); 113 } 114 to { 115 opacity: 1; 116 transform: translateY(0) scale(1); 117 } 118 } 119 120 .irisai-modal-header { 121 padding: 24px 24px 12px; 122 border-bottom: 1px solid var(--irisai-card-border); 123 } 124 125 .irisai-modal-header h3 { 126 margin: 0; 127 font-size: 20px; 128 font-weight: 600; 129 color: var(--irisai-text-primary, inherit); 130 } 131 132 .irisai-modal-body { 133 padding: 20px 24px; 134 } 135 136 .irisai-modal-body p { 137 margin: 0; 138 line-height: 1.6; 139 color: var(--irisai-text-secondary, inherit); 140 } 141 142 .irisai-modal-footer { 143 padding: 16px 24px 24px; 144 display: flex; 145 gap: 12px; 146 justify-content: flex-end; 147 } 148 149 /* === Status Messages === */ 150 .irisai-status { 151 max-width: 720px; 152 margin: 16px auto; 153 text-align: center; 154 } 155 156 .irisai-status-message, 157 .irisai-status-login, 158 .irisai-status-consent { 159 background: var(--irisai-card-bg); 160 border: 1px solid var(--irisai-card-border); 161 border-radius: var(--irisai-radius); 162 padding: 20px; 163 backdrop-filter: blur(12px); 164 box-shadow: 0 4px 16px var(--irisai-shadow-color); 165 } 166 167 .irisai-status-login p, 168 .irisai-status-consent p { 169 margin: 0 0 16px; 170 color: var(--irisai-text-secondary, inherit); 171 } 172 173 /* === Button Variants === */ 174 .irisai-btn-secondary { 175 display: inline-flex; 176 align-items: center; 177 gap: 8px; 178 border-radius: var(--irisai-radius); 179 padding: 12px 16px; 180 cursor: pointer; 181 border: 2px solid var(--irisai-card-border); 182 background: transparent; 183 color: var(--irisai-text-secondary, inherit); 184 font: inherit; 185 font-weight: 500; 186 transition: all var(--irisai-transition-normal) cubic-bezier(0.4, 0, 0.2, 1); 187 position: relative; 188 overflow: hidden; 189 will-change: transform, box-shadow; 190 } 191 192 .irisai-btn-secondary:hover { 193 border-color: var(--irisai-text-muted); 194 transform: translateY(-1px); 195 box-shadow: 0 4px 12px var(--irisai-shadow-color); 196 } 197 198 /* Disabled state for buttons and inputs */ 199 .irisai-btn.disabled, 200 .irisai-btn:disabled, 201 .irisai-chip.disabled, 202 .irisai-chip:disabled { 203 opacity: 0.5; 204 cursor: not-allowed; 205 pointer-events: none; 206 transform: none !important; 207 } 208 209 input:disabled { 210 opacity: 0.6; 211 cursor: not-allowed; 212 } 213 214 /* === Error State Styles === */ 215 .irisai-error { 216 color: var(--irisai-error-color); 217 font-weight: 500; 218 } 219 220 .irisai-rate-limit { 221 color: var(--irisai-warning-color); 222 font-weight: 500; 223 } 224 225 /* Shake animation for validation errors */ 226 @keyframes shake { 227 0%, 100% { transform: translateX(0); } 228 10%, 30%, 50%, 70%, 90% { transform: translateX(-3px); } 229 20%, 40%, 60%, 80% { transform: translateX(3px); } 230 } 231 232 .shake { 233 animation: shake 0.5s ease-in-out; 234 } 235 236 /* Hero section */ 237 .irisai-hero { 238 text-align: center; 239 margin-bottom: 32px; 240 opacity: 0; 241 animation: fadeInUp var(--irisai-transition-slow) ease forwards; 242 } 243 244 @keyframes fadeInUp { 245 from { 246 opacity: 0; 247 transform: translateY(20px); 248 } 249 250 to { 251 opacity: 1; 252 transform: translateY(0); 253 } 254 } 255 256 .irisai-badge { 257 display: inline-flex; 258 align-items: center; 259 gap: 8px; 260 border: 1px solid var(--irisai-card-border); 261 background: var(--irisai-card-bg); 262 padding: 8px 14px; 263 border-radius: 999px; 264 font-size: 14px; 265 font-weight: 500; 266 box-shadow: 0 2px 8px var(--irisai-shadow-color); 267 backdrop-filter: blur(10px); 268 margin-bottom: 20px; 269 color: var(--irisai-text-secondary, inherit); 270 transition: all var(--irisai-transition-normal) ease; 271 will-change: transform; 272 } 273 274 .irisai-badge:hover { 275 transform: translateY(-1px); 276 box-shadow: 0 4px 12px var(--irisai-shadow-color); 277 } 278 279 .irisai-badge-icon { 280 font-size: 16px; 281 transition: transform var(--irisai-transition-fast) ease; 282 } 283 284 .irisai-badge:hover .irisai-badge-icon { 285 transform: rotate(90deg); 286 } 287 288 .irisai-h1 { 289 font-weight: 700; 290 margin: 0 0 16px; 291 line-height: 1.2; 292 font-size: clamp(32px, 5vw, 48px); 293 color: var(--irisai-text-primary, inherit); 294 } 295 296 .irisai-grad { 297 background: linear-gradient(135deg, var(--irisai-primary), var(--irisai-secondary)); 298 -webkit-background-clip: text; 299 background-clip: text; 300 color: transparent; 301 position: relative; 302 } 303 304 .irisai-sub { 305 color: var(--irisai-text-muted); 306 margin: 0 auto; 307 max-width: 600px; 308 font-size: 18px; 309 line-height: 1.6; 310 } 311 312 /* Input bar - improved sticky behavior */ 313 .irisai-bar { 314 display: flex; 315 gap: 12px; 316 align-items: center; 317 margin: 32px auto 24px; 318 max-width: 720px; 319 position: sticky; 320 top: 16px; 321 z-index: 10; 322 opacity: 0; 323 animation: fadeInUp var(--irisai-transition-slow) ease 0.2s forwards; 324 325 /* Enhanced glassy effect */ 326 background: 327 linear-gradient(135deg, 328 rgba(255, 255, 255, 0.8) 0%, 329 rgba(255, 255, 255, 0.6) 50%, 330 rgba(255, 255, 255, 0.4) 100%); 331 backdrop-filter: blur(16px) saturate(180%); 332 border: 1px solid rgba(255, 255, 255, 0.3); 333 border-radius: calc(var(--irisai-radius) + 8px); 334 padding: 12px; 335 336 transition: all var(--irisai-transition-normal) ease; 337 will-change: transform, box-shadow; 338 } 339 340 .irisai-bar:hover { 341 transform: translateY(-1px); 342 } 343 344 .irisai-bar-input { 345 position: relative; 346 flex: 1; 347 } 348 349 .irisai-bar-input>input { 350 width: 100%; 351 padding: 16px 50px 16px 16px; 352 border: 2px solid var(--irisai-input-border); 353 border-radius: calc(var(--irisai-radius) + 2px); 354 background: var(--irisai-input-bg); 355 color: var(--irisai-text-primary, inherit); 356 box-shadow: 0 2px 8px var(--irisai-shadow-color); 357 outline: none; 358 font: inherit; 359 font-size: 16px; 360 transition: all var(--irisai-transition-normal) cubic-bezier(0.4, 0, 0.2, 1); 361 backdrop-filter: blur(10px); 362 will-change: border-color, box-shadow; 363 } 364 365 .irisai-bar-input>input:focus { 366 border-color: var(--irisai-primary); 367 box-shadow: 368 0 0 0 4px color-mix(in srgb, var(--irisai-primary) 15%, transparent), 369 0 4px 16px color-mix(in srgb, var(--irisai-primary) 20%, transparent); 370 transform: none; 371 /* Prevent input jumping */ 372 } 373 374 .irisai-bar-input>input::placeholder { 375 color: var(--irisai-text-muted); 376 transition: opacity var(--irisai-transition-fast) ease; 377 } 378 379 .irisai-bar-input>input:focus::placeholder { 380 opacity: 0.7; 381 } 382 383 .irisai-enter { 384 position: absolute; 385 right: 14px; 386 top: 50%; 387 transform: translateY(-50%); 388 opacity: 0.5; 389 pointer-events: none; 390 width: 20px; 391 color: var(--irisai-text-muted); 392 transition: all var(--irisai-transition-fast) ease; 393 } 394 395 .irisai-bar-input>input:focus+.irisai-enter { 396 opacity: 0.8; 397 transform: translateY(-50%) scale(1.1); 398 } 399 400 /* Primary button - enhanced interactions */ 401 .irisai-btn { 402 display: inline-flex; 403 align-items: center; 404 gap: 8px; 405 border-radius: var(--irisai-radius); 406 padding: 16px 20px; 407 cursor: pointer; 408 border: 2px solid var(--irisai-primary); 409 background: var(--irisai-primary); 410 color: var(--irisai-primary-text); 411 font: inherit; 412 font-weight: 600; 413 transition: all var(--irisai-transition-normal) cubic-bezier(0.4, 0, 0.2, 1); 414 position: relative; 415 overflow: hidden; 416 will-change: transform, box-shadow; 417 text-decoration: none; 418 } 419 420 .irisai-btn::before { 421 content: ''; 422 position: absolute; 423 top: 0; 424 left: -100%; 425 width: 100%; 426 height: 100%; 427 background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); 428 transition: left var(--irisai-transition-slow) ease; 429 } 430 431 .irisai-btn:hover::before { 432 left: 100%; 433 } 434 435 .irisai-btn:hover { 436 background: var(--irisai-primary-hover); 437 border-color: var(--irisai-primary-hover); 438 transform: translateY(-2px); 439 box-shadow: 440 0 8px 20px color-mix(in srgb, var(--irisai-primary) 25%, transparent), 441 0 4px 8px color-mix(in srgb, var(--irisai-primary) 15%, transparent); 442 } 443 444 .irisai-btn:active { 445 transform: translateY(-1px); 446 transition-duration: 0.1s; 447 } 448 449 .irisai-btn-icon { 450 display: inline-block; 451 font-size: 16px; 452 transition: transform var(--irisai-transition-normal) ease; 453 will-change: transform; 454 } 455 456 .irisai-btn:hover .irisai-btn-icon { 457 transform: translateX(3px); 458 } 459 460 /* Loading state for button */ 461 .irisai-btn.loading { 462 position: relative; 463 color: transparent; 464 } 465 466 .irisai-btn.loading::after { 467 content: ''; 468 position: absolute; 469 top: 50%; 470 left: 50%; 471 transform: translate(-50%, -50%); 472 width: 16px; 473 height: 16px; 474 border: 2px solid transparent; 475 border-top: 2px solid currentColor; 476 border-radius: 50%; 477 animation: spin 1s linear infinite; 478 } 479 480 @keyframes spin { 481 to { 482 transform: translate(-50%, -50%) rotate(360deg); 483 } 484 } 485 486 /* Chips - smoother interactions */ 487 .irisai-chips { 488 display: flex; 489 flex-wrap: wrap; 490 gap: 10px; 491 justify-content: center; 492 margin-bottom: 32px; 493 opacity: 0; 494 animation: fadeInUp var(--irisai-transition-slow) ease 0.4s forwards; 495 } 496 497 .irisai-chip { 498 border: 1px solid var(--irisai-card-border); 499 background: var(--irisai-chip-bg); 500 color: var(--irisai-text-primary, inherit); 501 border-radius: 999px; 502 padding: 10px 16px; 503 cursor: pointer; 504 font: inherit; 505 font-size: 14px; 506 font-weight: 500; 507 box-shadow: 0 2px 4px var(--irisai-shadow-color); 508 transition: all var(--irisai-transition-normal) cubic-bezier(0.4, 0, 0.2, 1); 509 backdrop-filter: blur(10px); 510 position: relative; 511 overflow: hidden; 512 will-change: transform, background-color; 513 } 514 515 .irisai-chip::before { 516 content: ''; 517 position: absolute; 518 top: 0; 519 left: 0; 520 right: 0; 521 bottom: 0; 522 background: var(--irisai-primary); 523 opacity: 0; 524 transition: opacity var(--irisai-transition-normal) ease; 525 z-index: -1; 526 } 527 528 .irisai-chip:hover::before { 529 opacity: 1; 530 } 531 532 .irisai-chip:hover { 533 color: var(--irisai-primary-text); 534 border-color: var(--irisai-primary); 535 transform: translateY(-3px); 536 box-shadow: 537 0 8px 16px color-mix(in srgb, var(--irisai-primary) 20%, transparent), 538 0 4px 8px color-mix(in srgb, var(--irisai-primary) 10%, transparent); 539 } 540 541 .irisai-chip:active, 542 .irisai-chip.clicked { 543 transform: translateY(-1px); 544 } 545 546 /* Results area - smooth animations */ 547 .irisai-results { 548 margin-top: 24px; 549 display: flex; 550 flex-direction: column-reverse; 551 gap: 16px; 552 } 553 554 .irisai-card { 555 border: 1px solid color-mix(in srgb, var(--irisai-card-border) 120%, transparent); 556 border-radius: calc(var(--irisai-radius) + 2px); 557 background: 558 linear-gradient(145deg, 559 color-mix(in srgb, var(--irisai-card-bg) 90%, transparent), 560 var(--irisai-card-bg)); 561 box-shadow: 562 0 4px 16px color-mix(in srgb, var(--irisai-shadow-color) 150%, transparent), 563 0 1px 4px color-mix(in srgb, var(--irisai-shadow-color) 100%, transparent); 564 padding: 20px; 565 backdrop-filter: blur(12px); 566 transition: all var(--irisai-transition-normal) cubic-bezier(0.4, 0, 0.2, 1); 567 will-change: transform, box-shadow; 568 opacity: 0; 569 transform: translateY(20px); 570 } 571 572 /* Card entrance animation */ 573 .irisai-card.irisai-show { 574 opacity: 1; 575 transform: translateY(0); 576 } 577 578 .irisai-card:hover { 579 box-shadow: 580 0 8px 24px color-mix(in srgb, var(--irisai-shadow-color) 200%, transparent), 581 0 2px 8px color-mix(in srgb, var(--irisai-shadow-color) 120%, transparent); 582 transform: translateY(-2px); 583 } 584 585 /* Empty state */ 586 .irisai-empty { 587 text-align: center; 588 padding: 32px 24px; 589 } 590 591 .irisai-empty-icon { 592 width: 48px; 593 height: 48px; 594 border-radius: 50%; 595 display: grid; 596 place-items: center; 597 margin: 0 auto 16px; 598 color: var(--irisai-primary-text); 599 font-size: 24px; 600 background: linear-gradient(135deg, var(--irisai-primary), var(--irisai-secondary)); 601 animation: pulse 2s ease-in-out infinite; 602 } 603 604 @keyframes pulse { 605 606 0%, 607 100% { 608 transform: scale(1); 609 } 610 611 50% { 612 transform: scale(1.05); 613 } 614 } 615 616 .irisai-empty-icon svg { 617 color: var(--irisai-primary-text); 618 width: 60%; 619 height: 60%; 620 } 621 622 .irisai-empty h3 { 623 margin: 0 0 8px; 624 font-size: 20px; 625 font-weight: 600; 626 color: var(--irisai-text-primary, inherit); 627 } 628 629 .irisai-empty p { 630 margin: 0; 631 color: var(--irisai-text-muted); 632 line-height: 1.5; 633 } 634 635 /* Messages - optimized animations */ 636 .irisai-msg { 637 display: flex; 638 margin-bottom: 16px; 639 opacity: 0; 640 animation: slideInMessage var(--irisai-transition-normal) ease forwards; 641 } 642 643 @keyframes slideInMessage { 644 from { 645 opacity: 0; 646 transform: translateX(-10px); 647 } 648 649 to { 650 opacity: 1; 651 transform: translateX(0); 652 } 653 } 654 655 .irisai-msg.user { 656 justify-content: flex-end; 657 } 658 659 .irisai-msg.user .irisai-msg { 660 animation: slideInMessage var(--irisai-transition-normal) ease forwards; 661 animation-direction: reverse; 662 } 663 664 .irisai-msg .bubble { 665 max-width: 80%; 666 border-radius: var(--irisai-radius); 667 padding: 14px 18px; 668 transition: all var(--irisai-transition-fast) ease; 669 } 670 671 .irisai-msg.user .bubble { 672 background: var(--irisai-primary); 673 color: var(--irisai-primary-text); 674 border-bottom-right-radius: 4px; 675 box-shadow: 0 2px 8px color-mix(in srgb, var(--irisai-primary) 20%, transparent); 676 } 677 678 .irisai-msg.ai .bubble { 679 background: transparent; 680 padding: 0; 681 } 682 683 .irisai-answer { 684 padding: 0; 685 } 686 687 .irisai-answer .prose p { 688 margin: 0 0 12px; 689 line-height: 1.6; 690 color: var(--irisai-text-primary, inherit); 691 opacity: 0; 692 animation: fadeInText var(--irisai-transition-normal) ease forwards; 693 } 694 695 .irisai-answer .prose p:nth-child(1) { 696 animation-delay: 0.1s; 697 } 698 699 .irisai-answer .prose p:nth-child(2) { 700 animation-delay: 0.2s; 701 } 702 703 .irisai-answer .prose p:nth-child(3) { 704 animation-delay: 0.3s; 705 } 706 707 @keyframes fadeInText { 708 from { 709 opacity: 0; 710 transform: translateY(5px); 711 } 712 713 to { 714 opacity: 1; 715 transform: translateY(0); 716 } 717 } 718 719 .irisai-answer .prose p:last-child { 720 margin-bottom: 0; 721 } 722 723 /* Sources */ 724 .irisai-sources { 725 margin-top: 12px; 726 padding-top: 12px; 727 border-top: 1px solid var(--irisai-card-border); 728 display: flex; 729 flex-wrap: wrap; 730 gap: 8px; 731 opacity: 0; 732 animation: fadeIn var(--irisai-transition-normal) ease 0.6s forwards; 733 } 734 735 @keyframes fadeIn { 736 to { 737 opacity: 1; 738 } 739 } 740 741 .irisai-tag { 742 font-size: 12px; 743 padding: 4px 8px; 744 background: color-mix(in srgb, var(--irisai-card-border) 30%, transparent); 745 border-radius: 6px; 746 text-decoration: none; 747 color: var(--irisai-text-secondary, inherit); 748 transition: all var(--irisai-transition-fast) ease; 749 border: 1px solid transparent; 750 } 751 752 .irisai-tag:hover { 753 background: color-mix(in srgb, var(--irisai-accent) 15%, transparent); 754 color: var(--irisai-accent); 755 border-color: color-mix(in srgb, var(--irisai-accent) 30%, transparent); 756 transform: translateY(-1px); 757 } 758 759 /* Loading animation - enhanced */ 760 .irisai-typing { 761 display: flex; 762 align-items: center; 763 justify-content: center; 764 gap: 6px; 765 padding: 20px; 766 min-height: 60px; 767 } 768 769 .irisai-typing-dot { 770 width: 10px; 771 height: 10px; 772 background: var(--irisai-primary); 773 border-radius: 50%; 774 animation: typingDots 1.5s infinite ease-in-out; 775 } 776 777 .irisai-typing-dot:nth-child(1) { 778 animation-delay: 0s; 779 } 780 781 .irisai-typing-dot:nth-child(2) { 782 animation-delay: 0.2s; 783 } 784 785 .irisai-typing-dot:nth-child(3) { 786 animation-delay: 0.4s; 787 } 788 789 @keyframes typingDots { 790 791 0%, 792 60%, 793 100% { 794 transform: translateY(0) scale(1); 795 opacity: 0.4; 796 } 797 798 30% { 799 transform: translateY(-10px) scale(1.2); 800 opacity: 1; 801 } 802 } 803 804 /* Ripple effect for button clicks */ 805 .irisai-rip { 806 position: absolute; 807 border-radius: 50%; 808 background: rgba(255, 255, 255, 0.3); 809 transform: scale(0); 810 animation: ripple 0.6s linear; 811 pointer-events: none; 812 } 813 814 @keyframes ripple { 815 to { 816 transform: scale(2); 817 opacity: 0; 818 } 819 } 820 821 /* Dark mode optimizations */ 822 @media (prefers-color-scheme: dark) { 823 :root { 824 --irisai-card-bg: rgba(255, 255, 255, 0.05); 825 --irisai-card-border: rgba(255, 255, 255, 0.15); 826 --irisai-input-bg: rgba(255, 255, 255, 0.08); 827 --irisai-input-border: rgba(255, 255, 255, 0.15); 828 --irisai-chip-bg: rgba(255, 255, 255, 0.05); 829 --irisai-text-muted: rgba(255, 255, 255, 0.6); 830 --irisai-shadow-color: rgba(0, 0, 0, 0.4); 831 } 832 833 .irisai-bar { 834 background: 835 linear-gradient(135deg, 836 rgba(0, 0, 0, 0.6) 0%, 837 rgba(0, 0, 0, 0.4) 50%, 838 rgba(0, 0, 0, 0.3) 100%); 839 border-color: rgba(255, 255, 255, 0.1); 840 } 841 842 .irisai-modal-backdrop { 843 background: rgba(0, 0, 0, 0.8); 844 } 845 } 846 847 /* Responsive improvements */ 848 @media (max-width: 768px) { 849 .irisai-bar { 850 flex-direction: column; 851 gap: 12px; 852 position: relative; 853 /* Remove sticky on mobile for better UX */ 854 top: auto; 855 } 856 857 .irisai-btn { 858 width: 100%; 859 justify-content: center; 860 } 861 862 .irisai-chips { 863 gap: 8px; 864 } 865 866 .irisai-chip { 867 flex: 1; 868 min-width: calc(50% - 4px); 869 text-align: center; 870 } 871 872 .irisai-msg .bubble { 873 max-width: 90%; 874 } 875 876 .irisai-modal-content { 877 margin: 16px; 878 max-width: calc(100% - 32px); 879 } 880 881 .irisai-modal-footer { 882 flex-direction: column-reverse; 883 } 884 885 .irisai-modal-footer .irisai-btn, 886 .irisai-modal-footer .irisai-btn-secondary { 887 width: 100%; 888 justify-content: center; 889 } 890 } 891 892 @media (max-width: 480px) { 893 .irisai-wrap { 894 padding: 0 16px; 895 } 896 897 .irisai-chip { 898 flex: none; 899 width: 100%; 900 } 901 902 .irisai-bar-input>input { 903 font-size: 16px; 904 /* Prevent zoom on iOS */ 905 } 906 907 .irisai-bar { 908 padding: 8px; 909 } 910 911 .irisai-hero { 912 margin-bottom: 24px; 913 } 914 915 .irisai-modal-content { 916 margin: 8px; 917 max-width: calc(100% - 16px); 918 } 919 920 .irisai-modal-header, 921 .irisai-modal-body, 922 .irisai-modal-footer { 923 padding-left: 16px; 924 padding-right: 16px; 925 } 926 } 927 928 /* Reduce motion for accessibility */ 929 @media (prefers-reduced-motion: reduce) { 930 931 .irisai-typing-dot { 932 animation: none; 933 opacity: 0.6; 934 } 935 936 .irisai-card, 937 .irisai-btn, 938 .irisai-chip, 939 .irisai-hero { 940 animation: none; 941 opacity: 1; 942 transform: none; 943 } 944 945 .irisai-modal-content { 946 animation: none; 947 } 948 } 949 950 /* Performance optimizations */ 951 .irisai-card, 952 .irisai-btn, 953 .irisai-chip, 954 .irisai-bar { 955 contain: layout style paint; 956 } 957 958 /* Hardware acceleration for smooth animations */ 959 .irisai-btn, 960 .irisai-chip, 961 .irisai-card, 962 .irisai-bar-input>input { 963 transform: translateZ(0); 964 backface-visibility: hidden; 965 perspective: 1000px; 966 } 967 968 /* Wave background styles */ 969 .irisai-waves-container { 970 width: 480px; 971 height: 150px; 972 display: flex; 973 align-items: center; 974 justify-content: center; 975 flex-direction: column; 976 color: #FFF; 977 margin: auto; 978 } 979 980 .irisai-waves-container h1 { 981 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; 982 font-size: 24px; 983 letter-spacing: 1px; 984 font-weight: 200; 985 -webkit-user-select: none; 986 -moz-user-select: none; 987 -ms-user-select: none; 988 user-select: none; 989 } 990 991 .irisai-waves-container canvas { 992 width: 100%; 993 } 2 :root { 3 /* Primary colors */ 4 --irisai-primary: #2563eb; 5 --irisai-primary-hover: #1d4ed8; 6 --irisai-primary-text: #ffffff; 7 8 /* Secondary colors */ 9 --irisai-secondary: #7c3aed; 10 --irisai-secondary-hover: #6d28d9; 11 --irisai-secondary-text: #ffffff; 12 13 /* Accent colors */ 14 --irisai-accent: #10b981; 15 --irisai-accent-hover: #059669; 16 --irisai-accent-text: #ffffff; 17 18 /* Background colors */ 19 --irisai-card-bg: rgba(255, 255, 255, 0.9); 20 --irisai-card-border: rgba(0, 0, 0, 0.1); 21 --irisai-input-bg: rgba(255, 255, 255, 0.9); 22 --irisai-input-border: rgba(0, 0, 0, 0.12); 23 24 /* Text colors */ 25 --irisai-text-primary: inherit; 26 --irisai-text-secondary: inherit; 27 --irisai-text-muted: rgba(0, 0, 0, 0.6); 28 29 /* Interactive elements */ 30 --irisai-chip-bg: rgba(255, 255, 255, 0.9); 31 --irisai-chip-hover-bg: var(--irisai-primary); 32 --irisai-chip-hover-text: var(--irisai-primary-text); 33 34 /* Layout */ 35 --irisai-radius: 14px; 36 --irisai-shadow-color: rgba(0, 0, 0, 0.1); 37 38 /* Animation timings */ 39 --irisai-transition-fast: 0.15s; 40 --irisai-transition-normal: 0.25s; 41 --irisai-transition-slow: 0.35s; 42 43 /* Error and status colors */ 44 --irisai-error-color: #dc2626; 45 --irisai-warning-color: #f59e0b; 46 --irisai-info-color: #3b82f6; 47 } 48 49 /* Performance optimization */ 50 * { 51 -webkit-font-smoothing: antialiased; 52 -moz-osx-font-smoothing: grayscale; 53 } 54 55 /* Container */ 56 .irisai-landing { 57 padding: clamp(24px, 5vw, 48px) 0; 58 color: var(--irisai-text-primary, inherit); 59 font-family: inherit; 60 position: relative; 61 overflow-x: hidden; 62 } 63 64 .irisai-wrap { 65 max-width: 1400px; 66 margin: 0 auto; 67 padding: 0 clamp(16px, 4vw, 32px); 68 } 69 70 /* === Privacy & Security Modal Styles === */ 71 .irisai-modal { 72 position: fixed; 73 top: 0; 74 left: 0; 75 right: 0; 76 bottom: 0; 77 z-index: 999999; 78 display: flex; 79 align-items: center; 80 justify-content: center; 81 padding: 16px; 82 } 83 84 .irisai-modal-backdrop { 85 position: absolute; 86 top: 0; 87 left: 0; 88 right: 0; 89 bottom: 0; 90 background: rgba(0, 0, 0, 0.7); 91 backdrop-filter: blur(8px); 92 animation: fadeIn var(--irisai-transition-normal) ease; 93 } 94 95 .irisai-modal-content { 96 position: relative; 97 background: var(--irisai-card-bg); 98 border-radius: calc(var(--irisai-radius) + 8px); 99 box-shadow: 100 0 20px 40px rgba(0, 0, 0, 0.3), 101 0 8px 16px rgba(0, 0, 0, 0.2); 102 backdrop-filter: blur(16px); 103 border: 1px solid var(--irisai-card-border); 104 max-width: 480px; 105 width: 100%; 106 animation: slideInModal var(--irisai-transition-slow) ease; 107 } 108 109 @keyframes slideInModal { 110 from { 111 opacity: 0; 112 transform: translateY(-30px) scale(0.95); 113 } 114 115 to { 116 opacity: 1; 117 transform: translateY(0) scale(1); 118 } 119 } 120 121 .irisai-modal-header { 122 padding: 24px 24px 12px; 123 border-bottom: 1px solid var(--irisai-card-border); 124 } 125 126 .irisai-modal-header h3 { 127 margin: 0; 128 font-size: 20px; 129 font-weight: 600; 130 color: var(--irisai-text-primary, inherit); 131 } 132 133 .irisai-modal-body { 134 padding: 20px 24px; 135 } 136 137 .irisai-modal-body p { 138 margin: 0; 139 line-height: 1.6; 140 color: var(--irisai-text-secondary, inherit); 141 } 142 143 .irisai-modal-footer { 144 padding: 16px 24px 24px; 145 display: flex; 146 gap: 12px; 147 justify-content: flex-end; 148 } 149 150 /* === Status Messages === */ 151 .irisai-status { 152 max-width: 720px; 153 margin: 16px auto; 154 text-align: center; 155 } 156 157 .irisai-status-message, 158 .irisai-status-login, 159 .irisai-status-consent { 160 background: var(--irisai-card-bg); 161 border: 1px solid var(--irisai-card-border); 162 border-radius: var(--irisai-radius); 163 padding: 20px; 164 backdrop-filter: blur(12px); 165 box-shadow: 0 4px 16px var(--irisai-shadow-color); 166 } 167 168 .irisai-status-login p, 169 .irisai-status-consent p { 170 margin: 0 0 16px; 171 color: var(--irisai-text-secondary, inherit); 172 } 173 174 /* === Button Variants === */ 175 .irisai-btn-secondary { 176 display: inline-flex; 177 align-items: center; 178 gap: 8px; 179 border-radius: var(--irisai-radius); 180 padding: 12px 16px; 181 cursor: pointer; 182 border: 2px solid var(--irisai-card-border); 183 background: transparent; 184 color: var(--irisai-text-secondary, inherit); 185 font: inherit; 186 font-weight: 500; 187 transition: all var(--irisai-transition-normal) cubic-bezier(0.4, 0, 0.2, 1); 188 position: relative; 189 overflow: hidden; 190 will-change: transform, box-shadow; 191 } 192 193 .irisai-btn-secondary:hover { 194 border-color: var(--irisai-text-muted); 195 transform: translateY(-1px); 196 box-shadow: 0 4px 12px var(--irisai-shadow-color); 197 } 198 199 /* Disabled state for buttons and inputs */ 200 .irisai-btn.disabled, 201 .irisai-btn:disabled, 202 .irisai-chip.disabled, 203 .irisai-chip:disabled { 204 opacity: 0.5; 205 cursor: not-allowed; 206 pointer-events: none; 207 transform: none !important; 208 } 209 210 input:disabled { 211 opacity: 0.6; 212 cursor: not-allowed; 213 } 214 215 /* === Error State Styles === */ 216 .irisai-error { 217 color: var(--irisai-error-color); 218 font-weight: 500; 219 } 220 221 .irisai-rate-limit { 222 color: var(--irisai-warning-color); 223 font-weight: 500; 224 } 225 226 /* Shake animation for validation errors */ 227 @keyframes shake { 228 229 0%, 230 100% { 231 transform: translateX(0); 232 } 233 234 10%, 235 30%, 236 50%, 237 70%, 238 90% { 239 transform: translateX(-3px); 240 } 241 242 20%, 243 40%, 244 60%, 245 80% { 246 transform: translateX(3px); 247 } 248 } 249 250 .shake { 251 animation: shake 0.5s ease-in-out; 252 } 253 254 /* Hero section */ 255 .irisai-hero { 256 text-align: center; 257 margin-bottom: 32px; 258 opacity: 0; 259 animation: fadeInUp var(--irisai-transition-slow) ease forwards; 260 } 261 262 @keyframes fadeInUp { 263 from { 264 opacity: 0; 265 transform: translateY(20px); 266 } 267 268 to { 269 opacity: 1; 270 transform: translateY(0); 271 } 272 } 273 274 .irisai-badge { 275 display: inline-flex; 276 align-items: center; 277 gap: 8px; 278 border: 1px solid var(--irisai-card-border); 279 background: var(--irisai-card-bg); 280 padding: 8px 14px; 281 border-radius: 999px; 282 font-size: 14px; 283 font-weight: 500; 284 box-shadow: 0 2px 8px var(--irisai-shadow-color); 285 backdrop-filter: blur(10px); 286 margin-bottom: 20px; 287 color: var(--irisai-text-secondary, inherit); 288 transition: all var(--irisai-transition-normal) ease; 289 will-change: transform; 290 } 291 292 .irisai-badge:hover { 293 transform: translateY(-1px); 294 box-shadow: 0 4px 12px var(--irisai-shadow-color); 295 } 296 297 .irisai-badge-icon { 298 font-size: 16px; 299 transition: transform var(--irisai-transition-fast) ease; 300 } 301 302 .irisai-badge:hover .irisai-badge-icon { 303 transform: rotate(90deg); 304 } 305 306 .irisai-h1 { 307 font-weight: 700; 308 margin: 0 0 16px; 309 line-height: 1.2; 310 font-size: clamp(32px, 5vw, 48px); 311 color: var(--irisai-text-primary, inherit); 312 } 313 314 .irisai-grad { 315 background: linear-gradient(135deg, var(--irisai-primary), var(--irisai-secondary)); 316 -webkit-background-clip: text; 317 background-clip: text; 318 color: transparent; 319 position: relative; 320 } 321 322 .irisai-sub { 323 color: var(--irisai-text-muted); 324 margin: 0 auto; 325 max-width: 600px; 326 font-size: 18px; 327 line-height: 1.6; 328 } 329 330 /* Input bar - improved sticky behavior */ 331 .irisai-bar { 332 display: flex; 333 gap: 12px; 334 align-items: center; 335 margin: 32px auto 24px; 336 max-width: 720px; 337 position: sticky; 338 top: 16px; 339 z-index: 10; 340 opacity: 0; 341 animation: fadeInUp var(--irisai-transition-slow) ease 0.2s forwards; 342 343 /* Enhanced glassy effect */ 344 background: 345 linear-gradient(135deg, 346 rgba(255, 255, 255, 0.8) 0%, 347 rgba(255, 255, 255, 0.6) 50%, 348 rgba(255, 255, 255, 0.4) 100%); 349 backdrop-filter: blur(16px) saturate(180%); 350 border: 1px solid rgba(255, 255, 255, 0.3); 351 border-radius: calc(var(--irisai-radius) + 8px); 352 padding: 12px; 353 354 transition: all var(--irisai-transition-normal) ease; 355 will-change: transform, box-shadow; 356 } 357 358 .irisai-bar:hover { 359 transform: translateY(-1px); 360 } 361 362 .irisai-bar-input { 363 display: flex; 364 position: relative; 365 flex: 1; 366 } 367 368 .irisai-bar-input>input { 369 width: 100%; 370 padding: 16px 50px 16px 16px; 371 border: 2px solid var(--irisai-input-border); 372 border-radius: calc(var(--irisai-radius) + 2px); 373 background: var(--irisai-input-bg); 374 color: var(--irisai-text-primary, inherit); 375 box-shadow: 0 2px 8px var(--irisai-shadow-color); 376 outline: none; 377 font: inherit; 378 font-size: 16px; 379 transition: all var(--irisai-transition-normal) cubic-bezier(0.4, 0, 0.2, 1); 380 backdrop-filter: blur(10px); 381 will-change: border-color, box-shadow; 382 } 383 384 .irisai-bar-input>input:focus { 385 border-color: var(--irisai-primary); 386 box-shadow: 387 0 0 0 4px color-mix(in srgb, var(--irisai-primary) 15%, transparent), 388 0 4px 16px color-mix(in srgb, var(--irisai-primary) 20%, transparent); 389 transform: none; 390 /* Prevent input jumping */ 391 } 392 393 .irisai-bar-input>input::placeholder { 394 color: var(--irisai-text-muted); 395 transition: opacity var(--irisai-transition-fast) ease; 396 } 397 398 .irisai-bar-input>input:focus::placeholder { 399 opacity: 0.7; 400 } 401 402 .irisai-enter { 403 position: absolute; 404 right: 14px; 405 top: 50%; 406 transform: translateY(-50%); 407 opacity: 0.5; 408 pointer-events: none; 409 width: 20px; 410 color: var(--irisai-text-muted); 411 transition: all var(--irisai-transition-fast) ease; 412 } 413 414 .irisai-bar-input>input:focus+.irisai-enter { 415 opacity: 0.8; 416 transform: translateY(-50%) scale(1.1); 417 } 418 419 /* Primary button - enhanced interactions */ 420 .irisai-btn { 421 display: inline-flex; 422 align-items: center; 423 gap: 8px; 424 border-radius: var(--irisai-radius); 425 padding: 16px 20px; 426 cursor: pointer; 427 border: 2px solid var(--irisai-primary); 428 background: var(--irisai-primary); 429 color: var(--irisai-primary-text); 430 font: inherit; 431 font-weight: 600; 432 transition: all var(--irisai-transition-normal) cubic-bezier(0.4, 0, 0.2, 1); 433 position: relative; 434 overflow: hidden; 435 will-change: transform, box-shadow; 436 text-decoration: none; 437 } 438 439 .irisai-btn::before { 440 content: ''; 441 position: absolute; 442 top: 0; 443 left: -100%; 444 width: 100%; 445 height: 100%; 446 background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); 447 transition: left var(--irisai-transition-slow) ease; 448 } 449 450 .irisai-btn:hover::before { 451 left: 100%; 452 } 453 454 .irisai-btn:hover { 455 background: var(--irisai-primary-hover); 456 border-color: var(--irisai-primary-hover); 457 transform: translateY(-2px); 458 box-shadow: 459 0 8px 20px color-mix(in srgb, var(--irisai-primary) 25%, transparent), 460 0 4px 8px color-mix(in srgb, var(--irisai-primary) 15%, transparent); 461 } 462 463 .irisai-btn:active { 464 transform: translateY(-1px); 465 transition-duration: 0.1s; 466 } 467 468 .irisai-btn-icon { 469 display: inline-block; 470 font-size: 16px; 471 transition: transform var(--irisai-transition-normal) ease; 472 will-change: transform; 473 } 474 475 .irisai-btn:hover .irisai-btn-icon { 476 transform: translateX(3px); 477 } 478 479 /* Loading state for button */ 480 .irisai-btn.loading { 481 position: relative; 482 color: transparent; 483 } 484 485 .irisai-btn.loading::after { 486 content: ''; 487 position: absolute; 488 top: 50%; 489 left: 50%; 490 transform: translate(-50%, -50%); 491 width: 16px; 492 height: 16px; 493 border: 2px solid transparent; 494 border-top: 2px solid currentColor; 495 border-radius: 50%; 496 animation: spin 1s linear infinite; 497 } 498 499 @keyframes spin { 500 to { 501 transform: translate(-50%, -50%) rotate(360deg); 502 } 503 } 504 505 /* Chips - smoother interactions */ 506 .irisai-chips { 507 display: flex; 508 flex-wrap: wrap; 509 gap: 10px; 510 justify-content: center; 511 margin-bottom: 32px; 512 opacity: 0; 513 animation: fadeInUp var(--irisai-transition-slow) ease 0.4s forwards; 514 } 515 516 .irisai-chip { 517 border: 1px solid var(--irisai-card-border); 518 background: var(--irisai-chip-bg); 519 color: var(--irisai-text-primary, inherit); 520 border-radius: 999px; 521 padding: 10px 16px; 522 cursor: pointer; 523 font: inherit; 524 font-size: 14px; 525 font-weight: 500; 526 box-shadow: 0 2px 4px var(--irisai-shadow-color); 527 transition: all var(--irisai-transition-normal) cubic-bezier(0.4, 0, 0.2, 1); 528 backdrop-filter: blur(10px); 529 position: relative; 530 overflow: hidden; 531 will-change: transform, background-color; 532 } 533 534 .irisai-chip::before { 535 content: ''; 536 position: absolute; 537 top: 0; 538 left: 0; 539 right: 0; 540 bottom: 0; 541 background: var(--irisai-primary); 542 opacity: 0; 543 transition: opacity var(--irisai-transition-normal) ease; 544 z-index: -1; 545 } 546 547 .irisai-chip:hover::before { 548 opacity: 1; 549 } 550 551 .irisai-chip:hover { 552 color: var(--irisai-primary-text); 553 border-color: var(--irisai-primary); 554 transform: translateY(-3px); 555 box-shadow: 556 0 8px 16px color-mix(in srgb, var(--irisai-primary) 20%, transparent), 557 0 4px 8px color-mix(in srgb, var(--irisai-primary) 10%, transparent); 558 } 559 560 .irisai-chip:active, 561 .irisai-chip.clicked { 562 transform: translateY(-1px); 563 } 564 565 /* Results area - smooth animations */ 566 .irisai-results { 567 margin-top: 24px; 568 display: flex; 569 flex-direction: column-reverse; 570 gap: 16px; 571 } 572 573 .irisai-card { 574 border: 1px solid color-mix(in srgb, var(--irisai-card-border) 120%, transparent); 575 border-radius: calc(var(--irisai-radius) + 2px); 576 background: 577 linear-gradient(145deg, 578 color-mix(in srgb, var(--irisai-card-bg) 90%, transparent), 579 var(--irisai-card-bg)); 580 box-shadow: 581 0 4px 16px color-mix(in srgb, var(--irisai-shadow-color) 150%, transparent), 582 0 1px 4px color-mix(in srgb, var(--irisai-shadow-color) 100%, transparent); 583 padding: 20px; 584 backdrop-filter: blur(12px); 585 transition: all var(--irisai-transition-normal) cubic-bezier(0.4, 0, 0.2, 1); 586 will-change: transform, box-shadow; 587 opacity: 0; 588 transform: translateY(20px); 589 } 590 591 /* Card entrance animation */ 592 .irisai-card.irisai-show { 593 opacity: 1; 594 transform: translateY(0); 595 } 596 597 .irisai-card:hover { 598 box-shadow: 599 0 8px 24px color-mix(in srgb, var(--irisai-shadow-color) 200%, transparent), 600 0 2px 8px color-mix(in srgb, var(--irisai-shadow-color) 120%, transparent); 601 transform: translateY(-2px); 602 } 603 604 /* Empty state */ 605 .irisai-empty { 606 text-align: center; 607 padding: 32px 24px; 608 } 609 610 .irisai-empty-icon { 611 width: 48px; 612 height: 48px; 613 border-radius: 50%; 614 display: grid; 615 place-items: center; 616 margin: 0 auto 16px; 617 color: var(--irisai-primary-text); 618 font-size: 24px; 619 background: linear-gradient(135deg, var(--irisai-primary), var(--irisai-secondary)); 620 animation: pulse 2s ease-in-out infinite; 621 } 622 623 @keyframes pulse { 624 625 0%, 626 100% { 627 transform: scale(1); 628 } 629 630 50% { 631 transform: scale(1.05); 632 } 633 } 634 635 .irisai-empty-icon svg { 636 color: var(--irisai-primary-text); 637 width: 60%; 638 height: 60%; 639 } 640 641 .irisai-empty h3 { 642 margin: 0 0 8px; 643 font-size: 20px; 644 font-weight: 600; 645 color: var(--irisai-text-primary, inherit); 646 } 647 648 .irisai-empty p { 649 margin: 0; 650 color: var(--irisai-text-muted); 651 line-height: 1.5; 652 } 653 654 /* Messages - optimized animations */ 655 .irisai-msg { 656 display: flex; 657 margin-bottom: 16px; 658 opacity: 0; 659 animation: slideInMessage var(--irisai-transition-normal) ease forwards; 660 } 661 662 @keyframes slideInMessage { 663 from { 664 opacity: 0; 665 transform: translateX(-10px); 666 } 667 668 to { 669 opacity: 1; 670 transform: translateX(0); 671 } 672 } 673 674 .irisai-msg.user { 675 justify-content: flex-end; 676 } 677 678 .irisai-msg.user .irisai-msg { 679 animation: slideInMessage var(--irisai-transition-normal) ease forwards; 680 animation-direction: reverse; 681 } 682 683 .irisai-msg .bubble { 684 max-width: 80%; 685 border-radius: var(--irisai-radius); 686 padding: 14px 18px; 687 transition: all var(--irisai-transition-fast) ease; 688 } 689 690 .irisai-msg.user .bubble { 691 background: var(--irisai-primary); 692 color: var(--irisai-primary-text); 693 border-bottom-right-radius: 4px; 694 box-shadow: 0 2px 8px color-mix(in srgb, var(--irisai-primary) 20%, transparent); 695 } 696 697 .irisai-msg.ai .bubble { 698 background: transparent; 699 padding: 0; 700 } 701 702 .irisai-answer { 703 padding: 0; 704 } 705 706 .irisai-answer .prose p { 707 margin: 0 0 12px; 708 line-height: 1.6; 709 color: var(--irisai-text-primary, inherit); 710 opacity: 0; 711 animation: fadeInText var(--irisai-transition-normal) ease forwards; 712 } 713 714 .irisai-answer .prose p:nth-child(1) { 715 animation-delay: 0.1s; 716 } 717 718 .irisai-answer .prose p:nth-child(2) { 719 animation-delay: 0.2s; 720 } 721 722 .irisai-answer .prose p:nth-child(3) { 723 animation-delay: 0.3s; 724 } 725 726 @keyframes fadeInText { 727 from { 728 opacity: 0; 729 transform: translateY(5px); 730 } 731 732 to { 733 opacity: 1; 734 transform: translateY(0); 735 } 736 } 737 738 .irisai-answer .prose p:last-child { 739 margin-bottom: 0; 740 } 741 742 /* Sources */ 743 .irisai-sources { 744 margin-top: 12px; 745 padding-top: 12px; 746 border-top: 1px solid var(--irisai-card-border); 747 display: flex; 748 flex-wrap: wrap; 749 gap: 8px; 750 opacity: 0; 751 animation: fadeIn var(--irisai-transition-normal) ease 0.6s forwards; 752 } 753 754 @keyframes fadeIn { 755 to { 756 opacity: 1; 757 } 758 } 759 760 .irisai-tag { 761 font-size: 12px; 762 padding: 4px 8px; 763 background: color-mix(in srgb, var(--irisai-card-border) 30%, transparent); 764 border-radius: 6px; 765 text-decoration: none; 766 color: var(--irisai-text-secondary, inherit); 767 transition: all var(--irisai-transition-fast) ease; 768 border: 1px solid transparent; 769 } 770 771 .irisai-tag:hover { 772 background: color-mix(in srgb, var(--irisai-accent) 15%, transparent); 773 color: var(--irisai-accent); 774 border-color: color-mix(in srgb, var(--irisai-accent) 30%, transparent); 775 transform: translateY(-1px); 776 } 777 778 /* Loading animation - enhanced */ 779 .irisai-typing { 780 display: flex; 781 align-items: center; 782 justify-content: center; 783 gap: 6px; 784 padding: 20px; 785 min-height: 60px; 786 } 787 788 .irisai-typing-dot { 789 width: 10px; 790 height: 10px; 791 background: var(--irisai-primary); 792 border-radius: 50%; 793 animation: typingDots 1.5s infinite ease-in-out; 794 } 795 796 .irisai-typing-dot:nth-child(1) { 797 animation-delay: 0s; 798 } 799 800 .irisai-typing-dot:nth-child(2) { 801 animation-delay: 0.2s; 802 } 803 804 .irisai-typing-dot:nth-child(3) { 805 animation-delay: 0.4s; 806 } 807 808 @keyframes typingDots { 809 810 0%, 811 60%, 812 100% { 813 transform: translateY(0) scale(1); 814 opacity: 0.4; 815 } 816 817 30% { 818 transform: translateY(-10px) scale(1.2); 819 opacity: 1; 820 } 821 } 822 823 /* Ripple effect for button clicks */ 824 .irisai-rip { 825 position: absolute; 826 border-radius: 50%; 827 background: rgba(255, 255, 255, 0.3); 828 transform: scale(0); 829 animation: ripple 0.6s linear; 830 pointer-events: none; 831 } 832 833 @keyframes ripple { 834 to { 835 transform: scale(2); 836 opacity: 0; 837 } 838 } 839 840 /* Dark mode optimizations */ 841 @media (prefers-color-scheme: dark) { 842 :root { 843 --irisai-card-bg: rgba(255, 255, 255, 0.05); 844 --irisai-card-border: rgba(255, 255, 255, 0.15); 845 --irisai-input-bg: rgba(255, 255, 255, 0.08); 846 --irisai-input-border: rgba(255, 255, 255, 0.15); 847 --irisai-chip-bg: rgba(255, 255, 255, 0.05); 848 --irisai-text-muted: rgba(255, 255, 255, 0.6); 849 --irisai-shadow-color: rgba(0, 0, 0, 0.4); 850 } 851 852 .irisai-bar { 853 background: 854 linear-gradient(135deg, 855 rgba(0, 0, 0, 0.6) 0%, 856 rgba(0, 0, 0, 0.4) 50%, 857 rgba(0, 0, 0, 0.3) 100%); 858 border-color: rgba(255, 255, 255, 0.1); 859 } 860 861 .irisai-modal-backdrop { 862 background: rgba(0, 0, 0, 0.8); 863 } 864 } 865 866 /* Responsive improvements */ 867 @media (max-width: 768px) { 868 .irisai-bar { 869 flex-direction: column; 870 gap: 12px; 871 position: relative; 872 /* Remove sticky on mobile for better UX */ 873 top: auto; 874 } 875 876 .irisai-btn { 877 width: 100%; 878 justify-content: center; 879 } 880 881 .irisai-chips { 882 gap: 8px; 883 } 884 885 .irisai-chip { 886 flex: 1; 887 min-width: calc(50% - 4px); 888 text-align: center; 889 } 890 891 .irisai-msg .bubble { 892 max-width: 90%; 893 } 894 895 .irisai-modal-content { 896 margin: 16px; 897 max-width: calc(100% - 32px); 898 } 899 900 .irisai-modal-footer { 901 flex-direction: column-reverse; 902 } 903 904 .irisai-modal-footer .irisai-btn, 905 .irisai-modal-footer .irisai-btn-secondary { 906 width: 100%; 907 justify-content: center; 908 } 909 } 910 911 @media (max-width: 480px) { 912 .irisai-wrap { 913 padding: 0 16px; 914 } 915 916 .irisai-chip { 917 flex: none; 918 width: 100%; 919 } 920 921 .irisai-bar-input>input { 922 font-size: 16px; 923 /* Prevent zoom on iOS */ 924 } 925 926 .irisai-bar { 927 padding: 8px; 928 } 929 930 .irisai-hero { 931 margin-bottom: 24px; 932 } 933 934 .irisai-modal-content { 935 margin: 8px; 936 max-width: calc(100% - 16px); 937 } 938 939 .irisai-modal-header, 940 .irisai-modal-body, 941 .irisai-modal-footer { 942 padding-left: 16px; 943 padding-right: 16px; 944 } 945 } 946 947 /* Reduce motion for accessibility */ 948 @media (prefers-reduced-motion: reduce) { 949 950 .irisai-typing-dot { 951 animation: none; 952 opacity: 0.6; 953 } 954 955 .irisai-card, 956 .irisai-btn, 957 .irisai-chip, 958 .irisai-hero { 959 animation: none; 960 opacity: 1; 961 transform: none; 962 } 963 964 .irisai-modal-content { 965 animation: none; 966 } 967 } 968 969 /* Performance optimizations */ 970 .irisai-card, 971 .irisai-btn, 972 .irisai-chip, 973 .irisai-bar { 974 contain: layout style paint; 975 } 976 977 /* Hardware acceleration for smooth animations */ 978 .irisai-btn, 979 .irisai-chip, 980 .irisai-card, 981 .irisai-bar-input>input { 982 transform: translateZ(0); 983 backface-visibility: hidden; 984 perspective: 1000px; 985 } 986 987 /* Wave background styles */ 988 .irisai-waves-container { 989 width: 480px; 990 height: 150px; 991 display: flex; 992 align-items: center; 993 justify-content: center; 994 flex-direction: column; 995 color: #FFF; 996 margin: auto; 997 } 998 999 @media (max-width: 480px) { 1000 .irisai-waves-container { 1001 width: 300px; 1002 } 1003 } 1004 1005 .irisai-waves-container h1 { 1006 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; 1007 font-size: 24px; 1008 letter-spacing: 1px; 1009 font-weight: 200; 1010 -webkit-user-select: none; 1011 -moz-user-select: none; 1012 -ms-user-select: none; 1013 user-select: none; 1014 } 1015 1016 .irisai-waves-container canvas { 1017 width: 100%; 1018 } -
iris-ai/trunk/iris-ai.php
r3428364 r3428373 4 4 * Plugin Name: Iris AI – AI Homepage, Chatbot & Site Assistant 5 5 * Description: AI assistant for WordPress with BYO-key or Proxy mode, chat UI, and content tools. 6 * Version: 1.0. 46 * Version: 1.0.5 7 7 * Author: Irisai 8 8 * Author URI: https://irisai.cloud … … 23 23 24 24 // Plugin constants. 25 define('IRISAI_VERSION', '1.0. 4');25 define('IRISAI_VERSION', '1.0.5'); 26 26 define('IRISAI_PATH', plugin_dir_path(__FILE__)); 27 27 define('IRISAI_URL', plugin_dir_url(__FILE__)); -
iris-ai/trunk/readme.txt
r3428364 r3428373 5 5 Requires at least: 5.0 6 6 Tested up to: 6.9 7 Stable tag: 1.0. 47 Stable tag: 1.0.5 8 8 Requires PHP: 7.4 9 9 License: GPLv2 or later … … 246 246 247 247 == Changelog == 248 = 1.0.5 = 249 * Responsive style fixes 248 250 = 1.0.4 = 249 251 * Improved compatibility with block themes by safely replacing the theme hero block with the live chat on the front-end while preserving the editor preview … … 272 274 == Upgrade Notice == 273 275 276 = 1.0.5 = 277 * Fixed issues in responsive mode 278 274 279 = 1.0.4 = 275 280 Improved block theme integration and streamlined the chat interface for better performance and cleaner markup.
Note: See TracChangeset
for help on using the changeset viewer.