@product7/feedback-sdk 1.1.4 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -80,7 +80,7 @@
80
80
  }
81
81
 
82
82
  const MOCK_CONFIG = {
83
- primaryColor: '#155EEF',
83
+ primaryColor: '#21244A',
84
84
  backgroundColor: '#ffffff',
85
85
  textColor: '#1F2937',
86
86
  boardId: 'feature-requests',
@@ -88,7 +88,6 @@
88
88
  displayMode: 'modal',
89
89
  };
90
90
 
91
- // Environment URLs
92
91
  const ENV_URLS = {
93
92
  production: {
94
93
  base: 'https://api.product7.io/api/v1',
@@ -96,7 +95,8 @@
96
95
  },
97
96
  staging: {
98
97
  base: 'https://staging.api.product7.io/api/v1',
99
- withWorkspace: (workspace) => `https://${workspace}.staging.api.product7.io/api/v1`,
98
+ withWorkspace: (workspace) =>
99
+ `https://${workspace}.staging.api.product7.io/api/v1`,
100
100
  },
101
101
  };
102
102
 
@@ -107,13 +107,11 @@
107
107
  this.sessionExpiry = null;
108
108
  this.userContext = config.userContext || null;
109
109
  this.mock = config.mock || false;
110
- this.env = config.env || 'production'; // 'production' or 'staging'
110
+ this.env = config.env || 'production';
111
111
 
112
112
  if (config.apiUrl) {
113
- // Custom API URL takes precedence
114
113
  this.baseURL = config.apiUrl;
115
114
  } else {
116
- // Use environment-based URL
117
115
  const envConfig = ENV_URLS[this.env] || ENV_URLS.production;
118
116
  this.baseURL = this.workspace
119
117
  ? envConfig.withWorkspace(this.workspace)
@@ -192,7 +190,7 @@
192
190
 
193
191
  // Mock mode - simulate success
194
192
  if (this.mock) {
195
- await new Promise(resolve => setTimeout(resolve, 500));
193
+ await new Promise((resolve) => setTimeout(resolve, 500));
196
194
  return {
197
195
  success: true,
198
196
  data: {
@@ -205,7 +203,8 @@
205
203
  }
206
204
 
207
205
  const payload = {
208
- board: feedbackData.board_id || feedbackData.board || feedbackData.boardId,
206
+ board:
207
+ feedbackData.board_id || feedbackData.board || feedbackData.boardId,
209
208
  title: feedbackData.title,
210
209
  content: feedbackData.content,
211
210
  attachments: feedbackData.attachments || [],
@@ -247,7 +246,10 @@
247
246
  setUserContext(userContext) {
248
247
  this.userContext = userContext;
249
248
  if (typeof localStorage !== 'undefined') {
250
- localStorage.setItem('feedbackSDK_userContext', JSON.stringify(userContext));
249
+ localStorage.setItem(
250
+ 'feedbackSDK_userContext',
251
+ JSON.stringify(userContext)
252
+ );
251
253
  }
252
254
  }
253
255
 
@@ -308,7 +310,8 @@
308
310
 
309
311
  try {
310
312
  responseData = await response.json();
311
- errorMessage = responseData.message || responseData.error || errorMessage;
313
+ errorMessage =
314
+ responseData.message || responseData.error || errorMessage;
312
315
  } catch (e) {
313
316
  errorMessage = (await response.text()) || errorMessage;
314
317
  }
@@ -641,9 +644,9 @@
641
644
  container: null,
642
645
  position: this.sdk.config.position,
643
646
  boardId: this.sdk.config.boardId,
644
- displayMode: options.displayMode || 'panel', // 'panel' or 'modal'
645
- size: options.size || 'medium', // 'small', 'medium', 'large'
646
- primaryColor: options.primaryColor || '#155EEF',
647
+ displayMode: options.displayMode || 'panel',
648
+ size: options.size || 'medium',
649
+ primaryColor: options.primaryColor || '#21244A',
647
650
  backgroundColor: options.backgroundColor || '#ffffff',
648
651
  textColor: options.textColor || '#1F2937',
649
652
  autoShow: false,
@@ -886,12 +889,21 @@
886
889
  this.backdropElement.addEventListener('click', this.closePanel);
887
890
  }
888
891
 
889
- const modeClass = this.options.displayMode === 'modal' ? 'feedback-modal' : 'feedback-panel';
892
+ const modeClass =
893
+ this.options.displayMode === 'modal'
894
+ ? 'feedback-modal'
895
+ : 'feedback-panel';
890
896
  const sizeClass = `size-${this.options.size}`;
891
897
  this.panelElement = document.createElement('div');
892
898
  this.panelElement.className = `${modeClass} ${sizeClass}`;
893
- this.panelElement.style.setProperty('--primary-color', this.options.primaryColor);
894
- this.panelElement.style.setProperty('--bg-color', this.options.backgroundColor);
899
+ this.panelElement.style.setProperty(
900
+ '--primary-color',
901
+ this.options.primaryColor
902
+ );
903
+ this.panelElement.style.setProperty(
904
+ '--bg-color',
905
+ this.options.backgroundColor
906
+ );
895
907
  this.panelElement.style.setProperty('--text-color', this.options.textColor);
896
908
  this.panelElement.innerHTML = this._getPanelHTML();
897
909
 
@@ -906,44 +918,41 @@
906
918
 
907
919
  _getPanelHTML() {
908
920
  return `
909
- <div class="feedback-panel-content">
910
- <div class="feedback-panel-header">
911
- <h3>Send Feedback</h3>
912
- <button class="feedback-panel-close" type="button" aria-label="Close">&times;</button>
913
- </div>
914
- <div class="feedback-panel-body">
915
- <form class="feedback-form">
916
- <div class="feedback-form-group">
917
- <label for="feedback-title-${this.id}">Title (optional)</label>
921
+ <div class="feedback-panel-content">
922
+ <div class="feedback-panel-header">
923
+ <h3>Share Your Thoughts</h3>
924
+ <button class="feedback-panel-close" type="button" aria-label="Close">&times;</button>
925
+ </div>
926
+ <div class="feedback-panel-body">
927
+ <form class="feedback-form">
928
+ <div class="feedback-form-group">
929
+ <div class="feedback-input-container">
918
930
  <input
919
931
  type="text"
920
932
  id="feedback-title-${this.id}"
921
933
  name="title"
922
- placeholder="Brief description of your feedback"
934
+ placeholder="Title"
923
935
  value="${this.state.title}"
924
936
  />
925
- </div>
926
- <div class="feedback-form-group">
927
- <label for="feedback-content-${this.id}">Message *</label>
928
937
  <textarea
929
938
  id="feedback-content-${this.id}"
930
939
  name="content"
931
- placeholder="Tell us what you think..."
940
+ placeholder="Tell us what's on your mind..."
932
941
  required
933
942
  >${this.state.content}</textarea>
934
943
  </div>
935
- <div class="feedback-error" role="alert"></div>
936
- <div class="feedback-form-actions">
937
- <button type="submit" class="feedback-btn feedback-btn-submit">
938
- ${this.state.isSubmitting ? 'Sending...' : 'Send Feedback'}
939
- </button>
940
- </div>
941
- </form>
942
- </div>
944
+ </div>
945
+ <div class="feedback-error" role="alert"></div>
946
+ <div class="feedback-form-group">
947
+ <button type="submit" class="feedback-btn feedback-btn-submit">
948
+ ${this.state.isSubmitting ? 'Sending...' : 'Submit Feedback'}
949
+ </button>
950
+ </div>
951
+ </form>
943
952
  </div>
944
- `;
953
+ </div>
954
+ `;
945
955
  }
946
-
947
956
  _attachPanelEvents() {
948
957
  const panel = this.panelElement;
949
958
 
@@ -1079,12 +1088,15 @@
1079
1088
  const button = document.createElement('div');
1080
1089
  button.className = `feedback-widget feedback-widget-button theme-${this.options.theme} position-${this.options.position}`;
1081
1090
  button.innerHTML = `
1082
- <button class="feedback-trigger-btn" type="button" aria-label="Send feedback">
1083
- <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1084
- <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
1085
- </svg>
1086
- </button>
1087
- `;
1091
+ <button class="feedback-trigger-btn" type="button" aria-label="Send feedback">
1092
+ <svg width="28" height="32" viewBox="0 0 28 32" fill="none" xmlns="http://www.w3.org/2000/svg">
1093
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M15.0615 5.28044C8.5161 4.42949 3.30825 11.1456 5.89967 17.6588C6.9321 20.2538 9.06268 22.2644 11.8777 23.1968C16.2682 24.6507 18.4038 22.3222 19.0483 23.9691C19.4055 24.8894 18.7282 25.3209 17.988 25.4938C10.9146 27.15 5.15304 22.7566 3.5869 17.5531C1.52205 10.6941 5.98684 4.6667 11.3483 3.41065C17.8801 1.88094 24.0325 6.19355 24.3926 12.7175C24.7448 19.0921 18.6217 24.5978 11.927 22.2036C10.8789 21.8285 8.8419 20.6682 8.46823 19.858C8.06026 18.9727 8.80261 18.1725 9.68285 18.3576C10.2223 18.4726 10.3116 18.8706 11.3161 19.5372C14.4549 21.6213 19.1276 20.6132 21.2046 17.0972C23.991 12.3817 21.0481 6.05351 15.06 5.27758L15.0615 5.28044Z" fill="#21244A"/>
1094
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M15.2492 2.19833C11.944 1.71463 8.88819 3.07214 6.91479 4.49682C2.27067 7.85488 0.76169 14.5038 3.49672 19.8731C4.08535 21.0096 4.84379 22.0497 5.7459 22.9576L7.16343 24.2515C7.67214 24.9131 7.27203 25.7176 6.64115 25.9269C5.13502 26.4271 2.0499 21.8172 1.42044 20.5383C0.0872204 17.8297 -0.312889 14.9047 0.242977 11.503C1.66908 2.77063 11.221 -2.51652 19.7197 1.21021C27.7548 4.73331 30.2733 15.4555 23.9351 22.0773C23.3107 22.7296 21.6352 24.4823 20.6278 23.8907C20.0076 23.5263 19.8933 22.6446 20.5192 22.1238C21.0301 21.6986 21.4759 21.435 21.9896 20.9734C23.6665 19.4688 25.2562 16.8752 25.3477 13.5636C25.4427 10.2055 24.1266 7.5848 22.3904 5.74859C20.6392 3.89665 18.6751 2.69919 15.2456 2.19691L15.2492 2.19833Z" fill="#F69F06"/>
1095
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M8.48332 27.2217C7.93817 26.265 8.89987 25.3776 10.1352 25.8641C15.5653 27.9926 18.3081 25.5269 19.0255 27.0823C19.2655 27.6039 19.0448 28.1619 18.7354 28.3863C17.9895 28.9257 14.82 28.9343 13.9262 28.8714C12.9071 28.8053 11.897 28.6377 10.9111 28.3713C10.0888 28.1348 8.88057 27.9247 8.48189 27.2281L8.48332 27.2217Z" fill="#21244A"/>
1096
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M15.8722 31.0607C15.7765 32.1381 14.579 32.0331 13.5766 31.9545C12.5742 31.8759 11.5203 31.8502 11.601 30.7013C11.6789 29.5882 12.8035 29.7532 13.8274 29.8332C14.4425 29.8811 15.9951 29.681 15.8722 31.0607Z" fill="#21244A"/>
1097
+ </svg>
1098
+ </button>
1099
+ `;
1088
1100
 
1089
1101
  if (this.options.customStyles) {
1090
1102
  Object.assign(button.style, this.options.customStyles);
@@ -1092,7 +1104,6 @@
1092
1104
 
1093
1105
  return button;
1094
1106
  }
1095
-
1096
1107
  _attachEvents() {
1097
1108
  const button = this.element.querySelector('.feedback-trigger-btn');
1098
1109
  button.addEventListener('click', this.openPanel);
@@ -1307,7 +1318,10 @@
1307
1318
  show() {
1308
1319
  this._renderSurvey();
1309
1320
  this.surveyState.isVisible = true;
1310
- this.sdk.eventBus.emit('survey:shown', { widget: this, type: this.surveyOptions.surveyType });
1321
+ this.sdk.eventBus.emit('survey:shown', {
1322
+ widget: this,
1323
+ type: this.surveyOptions.surveyType,
1324
+ });
1311
1325
  return this;
1312
1326
  }
1313
1327
 
@@ -1322,16 +1336,19 @@
1322
1336
 
1323
1337
  const config = this._getSurveyConfig();
1324
1338
  const positionStyles = this._getPositionStyles();
1325
- const themeStyles = this.surveyOptions.theme === 'dark'
1326
- ? 'background: #1a1a1a; color: #fff;'
1327
- : 'background: #fff; color: #1d1d1f;';
1339
+ const themeStyles =
1340
+ this.surveyOptions.theme === 'dark'
1341
+ ? 'background: #1a1a1a; color: #fff;'
1342
+ : 'background: #fff; color: #1d1d1f;';
1328
1343
 
1329
1344
  // Create backdrop for center position
1330
1345
  if (this.surveyOptions.position === 'center') {
1331
1346
  this.backdropElement = document.createElement('div');
1332
1347
  this.backdropElement.className = 'feedback-survey-backdrop';
1333
1348
  document.body.appendChild(this.backdropElement);
1334
- this.backdropElement.addEventListener('click', () => this._handleDismiss());
1349
+ this.backdropElement.addEventListener('click', () =>
1350
+ this._handleDismiss()
1351
+ );
1335
1352
  }
1336
1353
 
1337
1354
  this.surveyElement = document.createElement('div');
@@ -1355,67 +1372,92 @@
1355
1372
  // Animate in
1356
1373
  requestAnimationFrame(() => {
1357
1374
  this.surveyElement.style.opacity = '1';
1358
- this.surveyElement.style.transform = this.surveyOptions.position === 'center'
1359
- ? 'translate(-50%, -50%) scale(1)'
1360
- : 'translateY(0)';
1375
+ this.surveyElement.style.transform =
1376
+ this.surveyOptions.position === 'center'
1377
+ ? 'translate(-50%, -50%) scale(1)'
1378
+ : 'translateY(0)';
1361
1379
  });
1362
1380
  }
1363
1381
 
1364
1382
  _getSurveyConfig() {
1365
1383
  const configs = {
1366
1384
  nps: {
1367
- title: this.surveyOptions.title || 'How likely are you to recommend us?',
1368
- description: this.surveyOptions.description || 'On a scale of 0-10, how likely are you to recommend our product to a friend or colleague?',
1385
+ title:
1386
+ this.surveyOptions.title || 'How likely are you to recommend us?',
1387
+ description:
1388
+ this.surveyOptions.description ||
1389
+ 'On a scale of 0-10, how likely are you to recommend our product to a friend or colleague?',
1369
1390
  html: `
1370
1391
  <div class="feedback-survey-nps" style="display: flex; justify-content: space-between; gap: 4px;">
1371
- ${[...Array(11).keys()].map(n => `
1392
+ ${[...Array(11).keys()]
1393
+ .map(
1394
+ (n) => `
1372
1395
  <button class="feedback-survey-nps-btn" data-score="${n}" style="width: 28px; height: 36px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 6px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 12px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;">${n}</button>
1373
- `).join('')}
1396
+ `
1397
+ )
1398
+ .join('')}
1374
1399
  </div>
1375
1400
  <div style="display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#888' : '#86868b'};">
1376
1401
  <span>${this.surveyOptions.lowLabel || 'Not likely'}</span>
1377
1402
  <span>${this.surveyOptions.highLabel || 'Very likely'}</span>
1378
1403
  </div>
1379
- `
1404
+ `,
1380
1405
  },
1381
1406
  csat: {
1382
1407
  title: this.surveyOptions.title || 'How satisfied are you?',
1383
- description: this.surveyOptions.description || 'How would you rate your overall satisfaction with our product?',
1408
+ description:
1409
+ this.surveyOptions.description ||
1410
+ 'How would you rate your overall satisfaction with our product?',
1384
1411
  html: `
1385
1412
  <div class="feedback-survey-csat" style="display: flex; justify-content: center; gap: 16px;">
1386
- ${['😞', '😕', '😐', '🙂', '😄'].map((emoji, i) => `
1413
+ ${['😞', '😕', '😐', '🙂', '😄']
1414
+ .map(
1415
+ (emoji, i) => `
1387
1416
  <button class="feedback-survey-csat-btn" data-score="${i + 1}" style="background: none; border: none; cursor: pointer; font-size: 36px; transition: transform 0.15s; padding: 8px;">${emoji}</button>
1388
- `).join('')}
1417
+ `
1418
+ )
1419
+ .join('')}
1389
1420
  </div>
1390
1421
  <div style="display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#888' : '#86868b'};">
1391
1422
  <span>${this.surveyOptions.lowLabel || 'Very dissatisfied'}</span>
1392
1423
  <span>${this.surveyOptions.highLabel || 'Very satisfied'}</span>
1393
1424
  </div>
1394
- `
1425
+ `,
1395
1426
  },
1396
1427
  ces: {
1397
1428
  title: this.surveyOptions.title || 'How easy was it?',
1398
- description: this.surveyOptions.description || 'How easy was it to accomplish your task today?',
1429
+ description:
1430
+ this.surveyOptions.description ||
1431
+ 'How easy was it to accomplish your task today?',
1399
1432
  html: `
1400
1433
  <div class="feedback-survey-ces" style="display: flex; justify-content: space-between; gap: 8px;">
1401
- ${['Very Difficult', 'Difficult', 'Neutral', 'Easy', 'Very Easy'].map((label, i) => `
1434
+ ${['Very Difficult', 'Difficult', 'Neutral', 'Easy', 'Very Easy']
1435
+ .map(
1436
+ (label, i) => `
1402
1437
  <button class="feedback-survey-ces-btn" data-score="${i + 1}" style="flex: 1; padding: 12px 8px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;">${label}</button>
1403
- `).join('')}
1438
+ `
1439
+ )
1440
+ .join('')}
1404
1441
  </div>
1405
- `
1442
+ `,
1406
1443
  },
1407
1444
  custom: {
1408
1445
  title: this.surveyOptions.title || 'Quick Feedback',
1409
- description: this.surveyOptions.description || 'Help us improve by answering a few questions.',
1410
- html: this._renderCustomQuestions()
1411
- }
1446
+ description:
1447
+ this.surveyOptions.description ||
1448
+ 'Help us improve by answering a few questions.',
1449
+ html: this._renderCustomQuestions(),
1450
+ },
1412
1451
  };
1413
1452
 
1414
1453
  return configs[this.surveyOptions.surveyType] || configs.nps;
1415
1454
  }
1416
1455
 
1417
1456
  _renderCustomQuestions() {
1418
- if (!this.surveyOptions.customQuestions || this.surveyOptions.customQuestions.length === 0) {
1457
+ if (
1458
+ !this.surveyOptions.customQuestions ||
1459
+ this.surveyOptions.customQuestions.length === 0
1460
+ ) {
1419
1461
  // Default custom questions
1420
1462
  return `
1421
1463
  <div style="margin-bottom: 16px;">
@@ -1431,20 +1473,28 @@
1431
1473
  <div>
1432
1474
  <label style="display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500;">How often do you use it?</label>
1433
1475
  <div class="feedback-survey-frequency" style="display: flex; gap: 8px;">
1434
- ${['Daily', 'Weekly', 'Monthly', 'Rarely'].map(freq => `
1476
+ ${['Daily', 'Weekly', 'Monthly', 'Rarely']
1477
+ .map(
1478
+ (freq) => `
1435
1479
  <button class="feedback-survey-freq-btn" data-freq="${freq}" style="flex: 1; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 12px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;">${freq}</button>
1436
- `).join('')}
1480
+ `
1481
+ )
1482
+ .join('')}
1437
1483
  </div>
1438
1484
  </div>
1439
1485
  `;
1440
1486
  }
1441
1487
 
1442
- return this.surveyOptions.customQuestions.map((q, index) => `
1488
+ return this.surveyOptions.customQuestions
1489
+ .map(
1490
+ (q, index) => `
1443
1491
  <div style="margin-bottom: 16px;">
1444
1492
  <label style="display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500;">${q.label}</label>
1445
1493
  ${this._renderQuestionInput(q, index)}
1446
1494
  </div>
1447
- `).join('');
1495
+ `
1496
+ )
1497
+ .join('');
1448
1498
  }
1449
1499
 
1450
1500
  _renderQuestionInput(question, index) {
@@ -1453,7 +1503,7 @@
1453
1503
  return `
1454
1504
  <select class="feedback-survey-select" data-question="${question.id || index}" style="width: 100%; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'};">
1455
1505
  <option value="">${question.placeholder || 'Select an option'}</option>
1456
- ${question.options.map(opt => `<option value="${opt.value}">${opt.label}</option>`).join('')}
1506
+ ${question.options.map((opt) => `<option value="${opt.value}">${opt.label}</option>`).join('')}
1457
1507
  </select>
1458
1508
  `;
1459
1509
  case 'text':
@@ -1467,10 +1517,14 @@
1467
1517
 
1468
1518
  _getPositionStyles() {
1469
1519
  const positions = {
1470
- 'bottom-right': 'bottom: 24px; right: 24px; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',
1471
- 'bottom-left': 'bottom: 24px; left: 24px; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',
1472
- 'center': 'top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.95); opacity: 0; transition: all 0.3s ease;',
1473
- 'bottom': 'bottom: 0; left: 0; right: 0; border-radius: 16px 16px 0 0; max-width: none; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;'
1520
+ 'bottom-right':
1521
+ 'bottom: 24px; right: 24px; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',
1522
+ 'bottom-left':
1523
+ 'bottom: 24px; left: 24px; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',
1524
+ center:
1525
+ 'top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.95); opacity: 0; transition: all 0.3s ease;',
1526
+ bottom:
1527
+ 'bottom: 0; left: 0; right: 0; border-radius: 16px 16px 0 0; max-width: none; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',
1474
1528
  };
1475
1529
  return positions[this.surveyOptions.position] || positions['bottom-right'];
1476
1530
  }
@@ -1483,11 +1537,15 @@
1483
1537
  closeBtn.addEventListener('click', () => this._handleDismiss());
1484
1538
 
1485
1539
  // Submit button
1486
- const submitBtn = this.surveyElement.querySelector('.feedback-survey-submit');
1540
+ const submitBtn = this.surveyElement.querySelector(
1541
+ '.feedback-survey-submit'
1542
+ );
1487
1543
  submitBtn.addEventListener('click', () => this._handleSubmit());
1488
1544
 
1489
1545
  // Feedback textarea
1490
- const textarea = this.surveyElement.querySelector('.feedback-survey-textarea');
1546
+ const textarea = this.surveyElement.querySelector(
1547
+ '.feedback-survey-textarea'
1548
+ );
1491
1549
  textarea.addEventListener('input', (e) => {
1492
1550
  this.surveyState.feedback = e.target.value;
1493
1551
  });
@@ -1508,133 +1566,177 @@
1508
1566
  const type = this.surveyOptions.surveyType;
1509
1567
 
1510
1568
  if (type === 'nps') {
1511
- this.surveyElement.querySelectorAll('.feedback-survey-nps-btn').forEach(btn => {
1512
- btn.addEventListener('click', () => this._selectNPS(parseInt(btn.dataset.score)));
1513
- btn.addEventListener('mouseenter', () => {
1514
- if (this.surveyState.score !== parseInt(btn.dataset.score)) {
1515
- btn.style.borderColor = '#007aff';
1516
- }
1517
- });
1518
- btn.addEventListener('mouseleave', () => {
1519
- if (this.surveyState.score !== parseInt(btn.dataset.score)) {
1520
- btn.style.borderColor = this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';
1521
- }
1569
+ this.surveyElement
1570
+ .querySelectorAll('.feedback-survey-nps-btn')
1571
+ .forEach((btn) => {
1572
+ btn.addEventListener('click', () =>
1573
+ this._selectNPS(parseInt(btn.dataset.score))
1574
+ );
1575
+ btn.addEventListener('mouseenter', () => {
1576
+ if (this.surveyState.score !== parseInt(btn.dataset.score)) {
1577
+ btn.style.borderColor = '#007aff';
1578
+ }
1579
+ });
1580
+ btn.addEventListener('mouseleave', () => {
1581
+ if (this.surveyState.score !== parseInt(btn.dataset.score)) {
1582
+ btn.style.borderColor =
1583
+ this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';
1584
+ }
1585
+ });
1522
1586
  });
1523
- });
1524
1587
  }
1525
1588
 
1526
1589
  if (type === 'csat') {
1527
- this.surveyElement.querySelectorAll('.feedback-survey-csat-btn').forEach(btn => {
1528
- btn.addEventListener('click', () => this._selectCSAT(parseInt(btn.dataset.score)));
1529
- btn.addEventListener('mouseenter', () => {
1530
- btn.style.transform = 'scale(1.1)';
1531
- });
1532
- btn.addEventListener('mouseleave', () => {
1533
- if (this.surveyState.score !== parseInt(btn.dataset.score)) {
1534
- btn.style.transform = 'scale(1)';
1535
- }
1590
+ this.surveyElement
1591
+ .querySelectorAll('.feedback-survey-csat-btn')
1592
+ .forEach((btn) => {
1593
+ btn.addEventListener('click', () =>
1594
+ this._selectCSAT(parseInt(btn.dataset.score))
1595
+ );
1596
+ btn.addEventListener('mouseenter', () => {
1597
+ btn.style.transform = 'scale(1.1)';
1598
+ });
1599
+ btn.addEventListener('mouseleave', () => {
1600
+ if (this.surveyState.score !== parseInt(btn.dataset.score)) {
1601
+ btn.style.transform = 'scale(1)';
1602
+ }
1603
+ });
1536
1604
  });
1537
- });
1538
1605
  }
1539
1606
 
1540
1607
  if (type === 'ces') {
1541
- this.surveyElement.querySelectorAll('.feedback-survey-ces-btn').forEach(btn => {
1542
- btn.addEventListener('click', () => this._selectCES(parseInt(btn.dataset.score)));
1543
- btn.addEventListener('mouseenter', () => {
1544
- if (this.surveyState.score !== parseInt(btn.dataset.score)) {
1545
- btn.style.borderColor = '#007aff';
1546
- }
1547
- });
1548
- btn.addEventListener('mouseleave', () => {
1549
- if (this.surveyState.score !== parseInt(btn.dataset.score)) {
1550
- btn.style.borderColor = this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';
1551
- }
1608
+ this.surveyElement
1609
+ .querySelectorAll('.feedback-survey-ces-btn')
1610
+ .forEach((btn) => {
1611
+ btn.addEventListener('click', () =>
1612
+ this._selectCES(parseInt(btn.dataset.score))
1613
+ );
1614
+ btn.addEventListener('mouseenter', () => {
1615
+ if (this.surveyState.score !== parseInt(btn.dataset.score)) {
1616
+ btn.style.borderColor = '#007aff';
1617
+ }
1618
+ });
1619
+ btn.addEventListener('mouseleave', () => {
1620
+ if (this.surveyState.score !== parseInt(btn.dataset.score)) {
1621
+ btn.style.borderColor =
1622
+ this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';
1623
+ }
1624
+ });
1552
1625
  });
1553
- });
1554
1626
  }
1555
1627
 
1556
1628
  if (type === 'custom') {
1557
1629
  // Frequency buttons
1558
- this.surveyElement.querySelectorAll('.feedback-survey-freq-btn').forEach(btn => {
1559
- btn.addEventListener('click', () => this._selectFrequency(btn.dataset.freq));
1560
- });
1630
+ this.surveyElement
1631
+ .querySelectorAll('.feedback-survey-freq-btn')
1632
+ .forEach((btn) => {
1633
+ btn.addEventListener('click', () =>
1634
+ this._selectFrequency(btn.dataset.freq)
1635
+ );
1636
+ });
1561
1637
 
1562
1638
  // Select inputs
1563
- this.surveyElement.querySelectorAll('.feedback-survey-select').forEach(select => {
1564
- select.addEventListener('change', (e) => {
1565
- this.surveyState.customAnswers[select.dataset.question] = e.target.value;
1639
+ this.surveyElement
1640
+ .querySelectorAll('.feedback-survey-select')
1641
+ .forEach((select) => {
1642
+ select.addEventListener('change', (e) => {
1643
+ this.surveyState.customAnswers[select.dataset.question] =
1644
+ e.target.value;
1645
+ });
1566
1646
  });
1567
- });
1568
1647
 
1569
1648
  // Text inputs
1570
- this.surveyElement.querySelectorAll('.feedback-survey-input').forEach(input => {
1571
- input.addEventListener('input', (e) => {
1572
- this.surveyState.customAnswers[input.dataset.question] = e.target.value;
1649
+ this.surveyElement
1650
+ .querySelectorAll('.feedback-survey-input')
1651
+ .forEach((input) => {
1652
+ input.addEventListener('input', (e) => {
1653
+ this.surveyState.customAnswers[input.dataset.question] =
1654
+ e.target.value;
1655
+ });
1573
1656
  });
1574
- });
1575
1657
  }
1576
1658
  }
1577
1659
 
1578
1660
  _selectNPS(score) {
1579
1661
  this.surveyState.score = score;
1580
- this.surveyElement.querySelectorAll('.feedback-survey-nps-btn').forEach(btn => {
1581
- const btnScore = parseInt(btn.dataset.score);
1582
- if (btnScore === score) {
1583
- btn.style.background = '#007aff';
1584
- btn.style.borderColor = '#007aff';
1585
- btn.style.color = '#fff';
1586
- } else {
1587
- btn.style.background = this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';
1588
- btn.style.borderColor = this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';
1589
- btn.style.color = this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';
1590
- }
1591
- });
1662
+ this.surveyElement
1663
+ .querySelectorAll('.feedback-survey-nps-btn')
1664
+ .forEach((btn) => {
1665
+ const btnScore = parseInt(btn.dataset.score);
1666
+ if (btnScore === score) {
1667
+ btn.style.background = '#007aff';
1668
+ btn.style.borderColor = '#007aff';
1669
+ btn.style.color = '#fff';
1670
+ } else {
1671
+ btn.style.background =
1672
+ this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';
1673
+ btn.style.borderColor =
1674
+ this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';
1675
+ btn.style.color =
1676
+ this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';
1677
+ }
1678
+ });
1592
1679
  }
1593
1680
 
1594
1681
  _selectCSAT(score) {
1595
1682
  this.surveyState.score = score;
1596
- this.surveyElement.querySelectorAll('.feedback-survey-csat-btn').forEach(btn => {
1597
- const btnScore = parseInt(btn.dataset.score);
1598
- btn.style.transform = btnScore === score ? 'scale(1.2)' : 'scale(1)';
1599
- });
1683
+ this.surveyElement
1684
+ .querySelectorAll('.feedback-survey-csat-btn')
1685
+ .forEach((btn) => {
1686
+ const btnScore = parseInt(btn.dataset.score);
1687
+ btn.style.transform = btnScore === score ? 'scale(1.2)' : 'scale(1)';
1688
+ });
1600
1689
  }
1601
1690
 
1602
1691
  _selectCES(score) {
1603
1692
  this.surveyState.score = score;
1604
- this.surveyElement.querySelectorAll('.feedback-survey-ces-btn').forEach(btn => {
1605
- const btnScore = parseInt(btn.dataset.score);
1606
- if (btnScore === score) {
1607
- btn.style.background = '#007aff';
1608
- btn.style.borderColor = '#007aff';
1609
- btn.style.color = '#fff';
1610
- } else {
1611
- btn.style.background = this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';
1612
- btn.style.borderColor = this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';
1613
- btn.style.color = this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';
1614
- }
1615
- });
1693
+ this.surveyElement
1694
+ .querySelectorAll('.feedback-survey-ces-btn')
1695
+ .forEach((btn) => {
1696
+ const btnScore = parseInt(btn.dataset.score);
1697
+ if (btnScore === score) {
1698
+ btn.style.background = '#007aff';
1699
+ btn.style.borderColor = '#007aff';
1700
+ btn.style.color = '#fff';
1701
+ } else {
1702
+ btn.style.background =
1703
+ this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';
1704
+ btn.style.borderColor =
1705
+ this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';
1706
+ btn.style.color =
1707
+ this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';
1708
+ }
1709
+ });
1616
1710
  }
1617
1711
 
1618
1712
  _selectFrequency(freq) {
1619
1713
  this.surveyState.customAnswers.frequency = freq;
1620
- this.surveyElement.querySelectorAll('.feedback-survey-freq-btn').forEach(btn => {
1621
- if (btn.dataset.freq === freq) {
1622
- btn.style.background = '#007aff';
1623
- btn.style.borderColor = '#007aff';
1624
- btn.style.color = '#fff';
1625
- } else {
1626
- btn.style.background = this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';
1627
- btn.style.borderColor = this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';
1628
- btn.style.color = this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';
1629
- }
1630
- });
1714
+ this.surveyElement
1715
+ .querySelectorAll('.feedback-survey-freq-btn')
1716
+ .forEach((btn) => {
1717
+ if (btn.dataset.freq === freq) {
1718
+ btn.style.background = '#007aff';
1719
+ btn.style.borderColor = '#007aff';
1720
+ btn.style.color = '#fff';
1721
+ } else {
1722
+ btn.style.background =
1723
+ this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';
1724
+ btn.style.borderColor =
1725
+ this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';
1726
+ btn.style.color =
1727
+ this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';
1728
+ }
1729
+ });
1631
1730
  }
1632
1731
 
1633
1732
  async _handleSubmit() {
1634
1733
  const type = this.surveyOptions.surveyType;
1635
1734
 
1636
1735
  // Validate
1637
- if ((type === 'nps' || type === 'csat' || type === 'ces') && this.surveyState.score === null) {
1736
+ if (
1737
+ (type === 'nps' || type === 'csat' || type === 'ces') &&
1738
+ this.surveyState.score === null
1739
+ ) {
1638
1740
  this._showError('Please select a rating');
1639
1741
  return;
1640
1742
  }
@@ -1682,10 +1784,13 @@
1682
1784
 
1683
1785
  const error = document.createElement('div');
1684
1786
  error.className = 'feedback-survey-error';
1685
- error.style.cssText = 'color: #ef4444; font-size: 13px; margin-top: 8px; text-align: center;';
1787
+ error.style.cssText =
1788
+ 'color: #ef4444; font-size: 13px; margin-top: 8px; text-align: center;';
1686
1789
  error.textContent = message;
1687
1790
 
1688
- const submitBtn = this.surveyElement.querySelector('.feedback-survey-submit');
1791
+ const submitBtn = this.surveyElement.querySelector(
1792
+ '.feedback-survey-submit'
1793
+ );
1689
1794
  submitBtn.parentNode.insertBefore(error, submitBtn);
1690
1795
 
1691
1796
  setTimeout(() => error.remove(), 3000);
@@ -1735,9 +1840,10 @@
1735
1840
 
1736
1841
  if (surveyEl) {
1737
1842
  surveyEl.style.opacity = '0';
1738
- surveyEl.style.transform = this.surveyOptions.position === 'center'
1739
- ? 'translate(-50%, -50%) scale(0.95)'
1740
- : 'translateY(20px)';
1843
+ surveyEl.style.transform =
1844
+ this.surveyOptions.position === 'center'
1845
+ ? 'translate(-50%, -50%) scale(0.95)'
1846
+ : 'translateY(20px)';
1741
1847
  setTimeout(() => {
1742
1848
  if (surveyEl && surveyEl.parentNode) {
1743
1849
  surveyEl.parentNode.removeChild(surveyEl);
@@ -1946,7 +2052,9 @@
1946
2052
 
1947
2053
  createWidget(type = 'button', options = {}) {
1948
2054
  if (!this.initialized) {
1949
- throw new SDKError('SDK must be initialized before creating widgets. Call init() first.');
2055
+ throw new SDKError(
2056
+ 'SDK must be initialized before creating widgets. Call init() first.'
2057
+ );
1950
2058
  }
1951
2059
 
1952
2060
  const widgetId = generateId('widget');
@@ -1988,7 +2096,9 @@
1988
2096
  */
1989
2097
  showSurvey(options = {}) {
1990
2098
  if (!this.initialized) {
1991
- throw new SDKError('SDK must be initialized before showing surveys. Call init() first.');
2099
+ throw new SDKError(
2100
+ 'SDK must be initialized before showing surveys. Call init() first.'
2101
+ );
1992
2102
  }
1993
2103
 
1994
2104
  const surveyWidget = this.createWidget('survey', {
@@ -2056,7 +2166,10 @@
2056
2166
  }
2057
2167
 
2058
2168
  getUserContext() {
2059
- return this.config.userContext || (this.apiService ? this.apiService.getUserContext() : null);
2169
+ return (
2170
+ this.config.userContext ||
2171
+ (this.apiService ? this.apiService.getUserContext() : null)
2172
+ );
2060
2173
  }
2061
2174
 
2062
2175
  async reinitialize(newUserContext = null) {
@@ -2112,7 +2225,10 @@
2112
2225
  env: 'production', // 'production' or 'staging'
2113
2226
  };
2114
2227
 
2115
- const mergedConfig = deepMerge(deepMerge(defaultConfig, existingConfig), newConfig);
2228
+ const mergedConfig = deepMerge(
2229
+ deepMerge(defaultConfig, existingConfig),
2230
+ newConfig
2231
+ );
2116
2232
 
2117
2233
  if (!mergedConfig.workspace) {
2118
2234
  throw new ConfigError('Missing required configuration: workspace');
@@ -2127,7 +2243,9 @@
2127
2243
 
2128
2244
  _validateUserContext(userContext) {
2129
2245
  if (!userContext.user_id && !userContext.email) {
2130
- throw new ConfigError('User context must include at least user_id or email');
2246
+ throw new ConfigError(
2247
+ 'User context must include at least user_id or email'
2248
+ );
2131
2249
  }
2132
2250
 
2133
2251
  const validStructure = {
@@ -2140,7 +2258,9 @@
2140
2258
 
2141
2259
  for (const [key, expectedType] of Object.entries(validStructure)) {
2142
2260
  if (userContext[key] && typeof userContext[key] !== expectedType) {
2143
- throw new ConfigError(`User context field '${key}' must be of type '${expectedType}'`);
2261
+ throw new ConfigError(
2262
+ `User context field '${key}' must be of type '${expectedType}'`
2263
+ );
2144
2264
  }
2145
2265
  }
2146
2266
  }
@@ -2173,18 +2293,21 @@
2173
2293
  plan: authData.plan || authData.subscription?.plan,
2174
2294
  ...(authData.custom_fields || {}),
2175
2295
  },
2176
- company: authData.company || authData.organization ? {
2177
- id: authData.company?.id || authData.organization?.id,
2178
- name: authData.company?.name || authData.organization?.name,
2179
- monthly_spend: authData.company?.monthly_spend,
2180
- } : undefined,
2296
+ company:
2297
+ authData.company || authData.organization
2298
+ ? {
2299
+ id: authData.company?.id || authData.organization?.id,
2300
+ name: authData.company?.name || authData.organization?.name,
2301
+ monthly_spend: authData.company?.monthly_spend,
2302
+ }
2303
+ : undefined,
2181
2304
  };
2182
2305
  }
2183
2306
  }
2184
2307
 
2185
2308
  const CSS_STYLES = `
2186
2309
  .feedback-widget {
2187
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', Oxygen, Ubuntu, Cantarell, sans-serif;
2310
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
2188
2311
  font-size: 14px;
2189
2312
  line-height: 1.4;
2190
2313
  z-index: 999999;
@@ -2240,47 +2363,45 @@
2240
2363
  transform: translate(-50%, -50%);
2241
2364
  }
2242
2365
 
2243
- /* Circular button design with white bg and blue border */
2366
+ /* New button design - white with elevation */
2244
2367
  .feedback-trigger-btn {
2245
- width: 56px;
2246
- height: 56px;
2368
+ width: 52px;
2369
+ height: 52px;
2247
2370
  border-radius: 50%;
2248
- border: 2px solid #155eff;
2249
- background-color: #ffffff;
2371
+ border: none;
2372
+ background: #ffffff;
2250
2373
  cursor: pointer;
2251
2374
  display: flex;
2252
2375
  align-items: center;
2253
2376
  justify-content: center;
2254
- box-shadow: 0 4px 12px rgba(21, 94, 255, 0.15);
2255
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
2377
+ box-shadow:
2378
+ 0 2px 8px rgba(0, 0, 0, 0.08),
2379
+ 0 4px 16px rgba(0, 0, 0, 0.06);
2380
+ transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
2256
2381
  padding: 0;
2257
- color: #155eff; /* Icon color matches border */
2258
2382
  }
2259
2383
 
2260
2384
  .feedback-trigger-btn:hover {
2261
- background-color: #155eff;
2262
- color: #ffffff;
2263
- box-shadow: 0 6px 20px rgba(21, 94, 255, 0.3);
2385
+ box-shadow:
2386
+ 0 4px 12px rgba(0, 0, 0, 0.1),
2387
+ 0 8px 24px rgba(0, 0, 0, 0.08);
2388
+ transform: translateY(-2px);
2264
2389
  }
2265
2390
 
2266
2391
  .feedback-trigger-btn:active {
2267
- transform: scale(0.95);
2392
+ transform: translateY(0px);
2393
+ box-shadow:
2394
+ 0 2px 6px rgba(0, 0, 0, 0.08),
2395
+ 0 1px 4px rgba(0, 0, 0, 0.06);
2268
2396
  }
2269
-
2270
2397
  .feedback-trigger-btn svg {
2271
2398
  flex-shrink: 0;
2399
+ width: 22px;
2400
+ height: 25px;
2272
2401
  }
2273
2402
 
2274
- /* Dark theme support */
2275
- .theme-dark .feedback-trigger-btn {
2276
- background-color: #1a1a1a;
2277
- border-color: #155eff;
2278
- color: #155eff;
2279
- }
2280
-
2281
- .theme-dark .feedback-trigger-btn:hover {
2282
- background-color: #155eff;
2283
- color: #ffffff;
2403
+ .feedback-trigger-btn svg path {
2404
+ fill: #21244A;
2284
2405
  }
2285
2406
 
2286
2407
  /* Loading Modal */
@@ -2302,17 +2423,12 @@
2302
2423
  .feedback-loading-spinner {
2303
2424
  width: 48px;
2304
2425
  height: 48px;
2305
- border: 4px solid rgba(255, 255, 255, 0.3);
2306
- border-top-color: #155EEF;
2426
+ border: 4px solid rgba(0, 0, 0, 0.1);
2427
+ border-top-color: #21244A;
2307
2428
  border-radius: 50%;
2308
2429
  animation: spin 0.8s linear infinite;
2309
2430
  }
2310
2431
 
2311
- .theme-dark .feedback-loading-spinner {
2312
- border-color: rgba(255, 255, 255, 0.2);
2313
- border-top-color: #155EEF;
2314
- }
2315
-
2316
2432
  @keyframes spin {
2317
2433
  to { transform: rotate(360deg); }
2318
2434
  }
@@ -2367,15 +2483,6 @@
2367
2483
  width: 520px;
2368
2484
  }
2369
2485
 
2370
- /* Adjust textarea height for sizes */
2371
- .size-small .feedback-form-group textarea {
2372
- min-height: 120px;
2373
- }
2374
-
2375
- .size-large .feedback-form-group textarea {
2376
- min-height: 280px;
2377
- }
2378
-
2379
2486
  /* Side Panel Styles */
2380
2487
  .feedback-panel {
2381
2488
  position: fixed;
@@ -2399,7 +2506,8 @@
2399
2506
  left: 0;
2400
2507
  right: 0;
2401
2508
  bottom: 0;
2402
- background: rgba(0, 0, 0, 0.5);
2509
+ background: rgba(0, 0, 0, 0.4);
2510
+ backdrop-filter: blur(4px);
2403
2511
  opacity: 0;
2404
2512
  transition: opacity 0.3s ease;
2405
2513
  pointer-events: none;
@@ -2413,22 +2521,19 @@
2413
2521
 
2414
2522
  .feedback-panel-content {
2415
2523
  background: var(--bg-color, #ffffff);
2416
- color: var(--text-color, #1F2937);
2524
+ color: var(--text-color, #171717);
2417
2525
  height: 100%;
2418
2526
  display: flex;
2419
2527
  flex-direction: column;
2420
- border-radius: 16px;
2421
- box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1),
2422
- 0 10px 10px -5px rgba(0, 0, 0, 0.04),
2423
- 0 0 0 1px rgba(0, 0, 0, 0.05);
2528
+ border-radius: 12px;
2529
+ border: 1px solid #e5e5e5;
2424
2530
  }
2425
2531
 
2426
2532
  .feedback-panel-header {
2427
2533
  display: flex;
2428
2534
  align-items: center;
2429
2535
  justify-content: space-between;
2430
- padding: 16px 20px;
2431
- border-bottom: 1px solid rgba(128, 128, 128, 0.2);
2536
+ padding: 24px 24px 20px 24px;
2432
2537
  flex-shrink: 0;
2433
2538
  }
2434
2539
 
@@ -2436,40 +2541,39 @@
2436
2541
  margin: 0;
2437
2542
  font-size: 18px;
2438
2543
  font-weight: 600;
2439
- color: var(--text-color, #111827);
2544
+ color: var(--text-color, #171717);
2440
2545
  }
2441
2546
 
2442
2547
  .feedback-panel-close {
2443
2548
  background: none;
2444
2549
  border: none;
2445
- font-size: 24px;
2550
+ font-size: 20px;
2446
2551
  cursor: pointer;
2447
- color: var(--text-color, #6B7280);
2448
- opacity: 0.6;
2449
- padding: 4px;
2552
+ color: #737373;
2553
+ padding: 0;
2450
2554
  width: 32px;
2451
2555
  height: 32px;
2452
2556
  display: flex;
2453
2557
  align-items: center;
2454
2558
  justify-content: center;
2455
- border-radius: 6px;
2456
- transition: all 0.2s ease;
2559
+ border-radius: 8px;
2560
+ transition: all 0.15s ease;
2457
2561
  }
2458
2562
 
2459
2563
  .feedback-panel-close:hover {
2460
- opacity: 1;
2461
- background: rgba(128, 128, 128, 0.1);
2564
+ background: #f5f5f5;
2565
+ color: #171717;
2462
2566
  }
2463
2567
 
2464
2568
  .feedback-panel-close:focus-visible {
2465
- outline: 2px solid var(--primary-color, #155EEF);
2569
+ outline: 2px solid var(--primary-color, #21244A);
2466
2570
  outline-offset: 2px;
2467
2571
  }
2468
2572
 
2469
2573
  .feedback-panel-body {
2470
2574
  flex: 1;
2471
2575
  overflow-y: auto;
2472
- padding: 16px 20px;
2576
+ padding: 0 24px 24px 24px;
2473
2577
  }
2474
2578
 
2475
2579
  .feedback-form {
@@ -2479,85 +2583,59 @@
2479
2583
  }
2480
2584
 
2481
2585
  .feedback-form-group {
2482
- display: flex;
2483
- flex-direction: column;
2484
- gap: 8px;
2485
- margin-bottom: 20px;
2586
+ margin-bottom: 16px;
2486
2587
  }
2487
2588
 
2488
2589
  .feedback-form-group:last-child {
2489
2590
  margin-bottom: 0;
2490
2591
  }
2491
2592
 
2492
- .feedback-form-group label {
2493
- font-size: 14px;
2494
- font-weight: 500;
2495
- line-height: 1.25;
2496
- color: var(--text-color, #374151);
2497
- opacity: 0.8;
2593
+ /* Unified input container */
2594
+ .feedback-input-container {
2595
+ border: 1px solid #e5e5e5;
2596
+ border-radius: 8px;
2597
+ padding: 16px;
2598
+ background: #ffffff;
2599
+ transition: all 0.15s ease;
2498
2600
  }
2499
2601
 
2500
- .feedback-form-group input {
2501
- height: 44px;
2602
+ .feedback-input-container:focus-within {
2603
+ border-color: var(--primary-color, #21244A);
2604
+ box-shadow: 0 0 0 3px rgba(33, 36, 74, 0.08);
2605
+ }
2606
+
2607
+ .feedback-form-group input,
2608
+ .feedback-form-group textarea {
2502
2609
  width: 100%;
2503
- border-radius: 8px;
2504
- border: 1px solid rgba(128, 128, 128, 0.3);
2505
- background: rgba(128, 128, 128, 0.05);
2506
- padding: 10px 14px;
2507
- font-size: 15px;
2508
- font-weight: 400;
2509
- line-height: 1.5;
2510
- color: var(--text-color, #1F2937);
2610
+ border: none;
2611
+ padding: 0;
2612
+ font-size: 14px;
2511
2613
  font-family: inherit;
2614
+ color: var(--text-color, #171717);
2615
+ background: transparent;
2512
2616
  outline: none;
2513
- transition: all 0.2s ease;
2617
+ resize: none;
2514
2618
  }
2515
2619
 
2516
- .feedback-form-group input::placeholder {
2620
+ .feedback-form-group input {
2621
+ font-weight: 600;
2517
2622
  font-size: 15px;
2518
- color: var(--text-color, #9CA3AF);
2519
- opacity: 0.5;
2623
+ margin-bottom: 12px;
2520
2624
  }
2521
2625
 
2522
- .feedback-form-group input:focus {
2523
- border-color: var(--primary-color, #155EEF);
2524
- box-shadow: 0 0 0 3px rgba(21, 94, 239, 0.1);
2525
- }
2526
-
2527
- .feedback-form-group input:focus-visible {
2528
- outline: none;
2626
+ .feedback-form-group input::placeholder {
2627
+ color: #737373;
2628
+ font-weight: 600;
2529
2629
  }
2530
2630
 
2531
2631
  .feedback-form-group textarea {
2532
- min-height: 200px;
2533
- width: 100%;
2534
- resize: vertical;
2535
- border-radius: 8px;
2536
- border: 1px solid rgba(128, 128, 128, 0.3);
2537
- background: rgba(128, 128, 128, 0.05);
2538
- padding: 10px 14px;
2539
- font-size: 15px;
2632
+ min-height: 120px;
2540
2633
  font-weight: 400;
2541
- line-height: 1.5;
2542
- color: var(--text-color, #1F2937);
2543
- font-family: inherit;
2544
- outline: none;
2545
- transition: all 0.2s ease;
2546
2634
  }
2547
2635
 
2548
2636
  .feedback-form-group textarea::placeholder {
2549
- font-size: 15px;
2550
- color: var(--text-color, #9CA3AF);
2551
- opacity: 0.5;
2552
- }
2553
-
2554
- .feedback-form-group textarea:focus {
2555
- border-color: var(--primary-color, #155EEF);
2556
- box-shadow: 0 0 0 3px rgba(21, 94, 239, 0.1);
2557
- }
2558
-
2559
- .feedback-form-group textarea:focus-visible {
2560
- outline: none;
2637
+ color: #a3a3a3;
2638
+ font-weight: 400;
2561
2639
  }
2562
2640
 
2563
2641
  .feedback-btn {
@@ -2574,7 +2652,7 @@
2574
2652
  font-weight: 500;
2575
2653
  font-family: inherit;
2576
2654
  cursor: pointer;
2577
- transition: all 0.2s ease;
2655
+ transition: all 0.15s ease;
2578
2656
  }
2579
2657
 
2580
2658
  .feedback-btn:disabled {
@@ -2583,53 +2661,32 @@
2583
2661
  }
2584
2662
 
2585
2663
  .feedback-btn:focus-visible {
2586
- outline: 2px solid #155EEF;
2664
+ outline: 2px solid #21244A;
2587
2665
  outline-offset: 2px;
2588
2666
  }
2589
2667
 
2590
2668
  .feedback-btn-submit {
2591
- background: var(--primary-color, #155EEF);
2669
+ background: var(--primary-color, #21244A);
2592
2670
  color: white;
2593
2671
  width: 100%;
2594
2672
  }
2595
2673
 
2596
2674
  .feedback-btn-submit:hover:not(:disabled) {
2597
- background: var(--primary-color, #155EEF);
2598
- filter: brightness(0.9);
2675
+ background: #2d3159;
2599
2676
  }
2600
2677
 
2601
2678
  .feedback-btn-submit:active:not(:disabled) {
2602
- background: var(--primary-color, #155EEF);
2603
- filter: brightness(0.8);
2604
- }
2605
-
2606
- .feedback-btn-cancel {
2607
- background: transparent;
2608
- color: var(--text-color, #6B7280);
2609
- border: 1px solid rgba(128, 128, 128, 0.3);
2610
- }
2611
-
2612
- .feedback-btn-cancel:hover:not(:disabled) {
2613
- background: rgba(128, 128, 128, 0.1);
2614
- }
2615
-
2616
- .feedback-form-actions {
2617
- display: flex;
2618
- flex-direction: column;
2619
- gap: 12px;
2620
- margin-top: auto;
2621
- padding-top: 24px;
2679
+ transform: scale(0.98);
2622
2680
  }
2623
2681
 
2624
2682
  .feedback-error {
2683
+ background: #FEF2F2;
2684
+ border: 1px solid #FEE2E2;
2625
2685
  color: #DC2626;
2626
- font-size: 14px;
2627
- font-weight: 400;
2628
- margin-top: 8px;
2629
- padding: 12px;
2630
- background: #FEE2E2;
2631
- border: 1px solid #FECACA;
2686
+ padding: 12px 14px;
2632
2687
  border-radius: 8px;
2688
+ font-size: 13px;
2689
+ margin-top: 12px;
2633
2690
  display: none;
2634
2691
  }
2635
2692
 
@@ -2637,12 +2694,6 @@
2637
2694
  display: block;
2638
2695
  }
2639
2696
 
2640
- .feedback-panel.theme-dark .feedback-error {
2641
- background: #7F1D1D;
2642
- border-color: #991B1B;
2643
- color: #FCA5A5;
2644
- }
2645
-
2646
2697
  .feedback-success-notification {
2647
2698
  position: fixed;
2648
2699
  top: 24px;
@@ -2707,7 +2758,7 @@
2707
2758
  }
2708
2759
 
2709
2760
  .feedback-success-close:focus-visible {
2710
- outline: 2px solid #155EEF;
2761
+ outline: 2px solid #21244A;
2711
2762
  outline-offset: 2px;
2712
2763
  }
2713
2764
 
@@ -2769,18 +2820,10 @@
2769
2820
  border-radius: 2px;
2770
2821
  }
2771
2822
 
2772
- .feedback-panel.theme-dark .feedback-panel-header::before {
2773
- background: #4B5563;
2774
- }
2775
-
2776
2823
  .feedback-panel-body {
2777
2824
  padding: 20px;
2778
2825
  }
2779
2826
 
2780
- .feedback-form-group textarea {
2781
- min-height: 150px;
2782
- }
2783
-
2784
2827
  .feedback-widget-button {
2785
2828
  bottom: 16px;
2786
2829
  right: 16px;
@@ -2817,74 +2860,13 @@
2817
2860
  display: none !important;
2818
2861
  }
2819
2862
  }
2820
-
2821
- /* Survey Widget Styles */
2822
- .feedback-survey-backdrop {
2823
- position: fixed;
2824
- top: 0;
2825
- left: 0;
2826
- right: 0;
2827
- bottom: 0;
2828
- background: rgba(0, 0, 0, 0.5);
2829
- z-index: 9999;
2830
- opacity: 0;
2831
- transition: opacity 0.3s ease;
2832
- }
2833
-
2834
- .feedback-survey-backdrop.show {
2835
- opacity: 1;
2836
- }
2837
-
2838
- .feedback-survey {
2839
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
2840
- }
2841
-
2842
- .feedback-survey-csat-btn:hover {
2843
- transform: scale(1.1) !important;
2844
- }
2845
-
2846
- .feedback-survey-nps-btn:hover,
2847
- .feedback-survey-ces-btn:hover,
2848
- .feedback-survey-freq-btn:hover {
2849
- border-color: #007aff !important;
2850
- }
2851
-
2852
- @media (max-width: 768px) {
2853
- .feedback-survey {
2854
- left: 16px !important;
2855
- right: 16px !important;
2856
- max-width: none !important;
2857
- min-width: auto !important;
2858
- }
2859
-
2860
- .feedback-survey.feedback-survey-center {
2861
- width: calc(100% - 32px) !important;
2862
- }
2863
-
2864
- .feedback-survey-nps {
2865
- flex-wrap: wrap;
2866
- justify-content: center !important;
2867
- }
2868
-
2869
- .feedback-survey-nps-btn {
2870
- width: 32px !important;
2871
- height: 32px !important;
2872
- font-size: 11px !important;
2873
- }
2874
-
2875
- .feedback-survey-ces {
2876
- flex-direction: column !important;
2877
- }
2878
-
2879
- .feedback-survey-ces-btn {
2880
- flex: none !important;
2881
- width: 100% !important;
2882
- }
2883
- }
2884
2863
  `;
2885
2864
 
2886
2865
  function injectStyles() {
2887
- if (typeof document !== 'undefined' && !document.querySelector('#feedback-sdk-styles')) {
2866
+ if (
2867
+ typeof document !== 'undefined' &&
2868
+ !document.querySelector('#feedback-sdk-styles')
2869
+ ) {
2888
2870
  const style = document.createElement('style');
2889
2871
  style.id = 'feedback-sdk-styles';
2890
2872
  style.textContent = CSS_STYLES;