Plugin Directory

Changeset 3428373


Ignore:
Timestamp:
12/27/2025 07:58:01 PM (2 months ago)
Author:
zephyrwp
Message:

Style fixes for mobile

Location:
iris-ai
Files:
40 added
3 edited

Legend:

Unmodified
Added
Removed
  • iris-ai/trunk/assets/css/front.css

    r3424224 r3428373  
    11/* === 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
     210input: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  
    44 * Plugin Name: Iris AI – AI Homepage, Chatbot & Site Assistant
    55 * Description: AI assistant for WordPress with BYO-key or Proxy mode, chat UI, and content tools.
    6  * Version: 1.0.4
     6 * Version: 1.0.5
    77 * Author: Irisai
    88 * Author URI: https://irisai.cloud
     
    2323
    2424// Plugin constants.
    25 define('IRISAI_VERSION', '1.0.4');
     25define('IRISAI_VERSION', '1.0.5');
    2626define('IRISAI_PATH', plugin_dir_path(__FILE__));
    2727define('IRISAI_URL', plugin_dir_url(__FILE__));
  • iris-ai/trunk/readme.txt

    r3428364 r3428373  
    55Requires at least: 5.0
    66Tested up to: 6.9
    7 Stable tag: 1.0.4
     7Stable tag: 1.0.5
    88Requires PHP: 7.4
    99License: GPLv2 or later
     
    246246
    247247== Changelog ==
     248= 1.0.5 =
     249* Responsive style fixes
    248250= 1.0.4 =
    249251* 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
     
    272274== Upgrade Notice ==
    273275
     276= 1.0.5 =
     277* Fixed issues in responsive mode
     278
    274279= 1.0.4 =
    275280Improved block theme integration and streamlined the chat interface for better performance and cleaner markup.
Note: See TracChangeset for help on using the changeset viewer.