@speechos/client 0.2.9 → 0.2.11

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.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { state, events, getConfig, getFetchHandler, getSettingsToken, clearSettingsToken, getBackend, setConfig, updateUserId } from '@speechos/core';
1
+ import { state, events, getConfig, getSettingsToken, clearSettingsToken, getBackend, setConfig, updateUserId } from '@speechos/core';
2
2
  export { DEFAULT_HOST, events, getConfig, livekit, resetConfig, setConfig, state } from '@speechos/core';
3
3
 
4
4
  /**
@@ -12,6 +12,7 @@ const defaultClientConfig = {
12
12
  commands: [],
13
13
  zIndex: 999999,
14
14
  alwaysVisible: false,
15
+ useExternalSettings: false,
15
16
  };
16
17
  /**
17
18
  * Current client configuration singleton
@@ -27,6 +28,7 @@ function validateClientConfig(config) {
27
28
  commands: config.commands ?? defaultClientConfig.commands,
28
29
  zIndex: config.zIndex ?? defaultClientConfig.zIndex,
29
30
  alwaysVisible: config.alwaysVisible ?? defaultClientConfig.alwaysVisible,
31
+ useExternalSettings: config.useExternalSettings ?? defaultClientConfig.useExternalSettings,
30
32
  };
31
33
  // Validate zIndex
32
34
  if (typeof resolved.zIndex !== "number" || resolved.zIndex < 0) {
@@ -78,6 +80,12 @@ function getZIndex() {
78
80
  function isAlwaysVisible() {
79
81
  return currentClientConfig.alwaysVisible;
80
82
  }
83
+ /**
84
+ * Check if external settings page should be used
85
+ */
86
+ function useExternalSettings() {
87
+ return currentClientConfig.useExternalSettings;
88
+ }
81
89
 
82
90
  /**
83
91
  * Form field focus detection for SpeechOS Client SDK
@@ -248,6 +256,17 @@ class FormDetector {
248
256
  document.addEventListener("touchstart", this.touchHandler, true);
249
257
  document.addEventListener("mousedown", this.mouseDownHandler, true);
250
258
  this.isActive = true;
259
+ // Check for already-focused form field (e.g., page loaded with autofocus)
260
+ const activeElement = document.activeElement;
261
+ if (isFormField(activeElement)) {
262
+ console.log("[SpeechOS] FormDetector: found initially focused form field", {
263
+ element: activeElement,
264
+ tagName: activeElement?.tagName,
265
+ });
266
+ state.setFocusedElement(activeElement);
267
+ state.show();
268
+ events.emit("form:focus", { element: activeElement });
269
+ }
251
270
  }
252
271
  /**
253
272
  * Stop detecting form field focus events
@@ -492,9 +511,12 @@ let memoryCache$3 = null;
492
511
  * Sorted alphabetically by name for dropdown display
493
512
  */
494
513
  const SUPPORTED_LANGUAGES = [
514
+ { name: "Belarusian", code: "be", variants: ["be"] },
515
+ { name: "Bengali", code: "bn", variants: ["bn"] },
516
+ { name: "Bosnian", code: "bs", variants: ["bs"] },
495
517
  { name: "Bulgarian", code: "bg", variants: ["bg"] },
496
518
  { name: "Catalan", code: "ca", variants: ["ca"] },
497
- { name: "Chinese", code: "zh", variants: ["zh"] },
519
+ { name: "Croatian", code: "hr", variants: ["hr"] },
498
520
  { name: "Czech", code: "cs", variants: ["cs"] },
499
521
  { name: "Danish", code: "da", variants: ["da", "da-DK"] },
500
522
  { name: "Dutch", code: "nl", variants: ["nl"] },
@@ -515,18 +537,26 @@ const SUPPORTED_LANGUAGES = [
515
537
  { name: "Indonesian", code: "id", variants: ["id"] },
516
538
  { name: "Italian", code: "it", variants: ["it"] },
517
539
  { name: "Japanese", code: "ja", variants: ["ja"] },
540
+ { name: "Kannada", code: "kn", variants: ["kn"] },
518
541
  { name: "Korean", code: "ko", variants: ["ko", "ko-KR"] },
519
542
  { name: "Latvian", code: "lv", variants: ["lv"] },
520
543
  { name: "Lithuanian", code: "lt", variants: ["lt"] },
544
+ { name: "Macedonian", code: "mk", variants: ["mk"] },
521
545
  { name: "Malay", code: "ms", variants: ["ms"] },
546
+ { name: "Marathi", code: "mr", variants: ["mr"] },
522
547
  { name: "Norwegian", code: "no", variants: ["no"] },
523
548
  { name: "Polish", code: "pl", variants: ["pl"] },
524
549
  { name: "Portuguese", code: "pt", variants: ["pt", "pt-BR", "pt-PT"] },
525
550
  { name: "Romanian", code: "ro", variants: ["ro"] },
526
551
  { name: "Russian", code: "ru", variants: ["ru"] },
552
+ { name: "Serbian", code: "sr", variants: ["sr"] },
527
553
  { name: "Slovak", code: "sk", variants: ["sk"] },
554
+ { name: "Slovenian", code: "sl", variants: ["sl"] },
528
555
  { name: "Spanish", code: "es", variants: ["es", "es-419"] },
529
556
  { name: "Swedish", code: "sv", variants: ["sv", "sv-SE"] },
557
+ { name: "Tagalog", code: "tl", variants: ["tl"] },
558
+ { name: "Tamil", code: "ta", variants: ["ta"] },
559
+ { name: "Telugu", code: "te", variants: ["te"] },
530
560
  { name: "Turkish", code: "tr", variants: ["tr"] },
531
561
  { name: "Ukrainian", code: "uk", variants: ["uk"] },
532
562
  { name: "Vietnamese", code: "vi", variants: ["vi"] },
@@ -1319,25 +1349,14 @@ class SettingsSync {
1319
1349
  this.syncDisabled = false;
1320
1350
  }
1321
1351
  /**
1322
- * Make a fetch request using custom fetchHandler if configured, otherwise native fetch.
1323
- * This allows the Chrome extension to route fetch traffic through the service worker
1324
- * to bypass page CSP restrictions.
1352
+ * Make a fetch request using native fetch.
1325
1353
  */
1326
1354
  async doFetch(url, options) {
1327
1355
  const config = getConfig();
1328
- const customHandler = getFetchHandler();
1329
- if (customHandler) {
1330
- if (config.debug) {
1331
- console.log("[SpeechOS] Using custom fetch handler (extension proxy)", options.method, url);
1332
- }
1333
- return customHandler(url, options);
1334
- }
1335
1356
  if (config.debug) {
1336
1357
  console.log("[SpeechOS] Using native fetch", options.method, url);
1337
1358
  }
1338
- // Use native fetch and wrap response to match FetchResponse interface
1339
- const response = await fetch(url, options);
1340
- return response;
1359
+ return fetch(url, options);
1341
1360
  }
1342
1361
  /**
1343
1362
  * Initialize the settings sync manager
@@ -1717,9 +1736,9 @@ const themeStyles = i$4 `
1717
1736
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
1718
1737
 
1719
1738
  /* Color tokens */
1720
- --speechos-primary: #10B981;
1721
- --speechos-primary-hover: #059669;
1722
- --speechos-primary-active: #047857;
1739
+ --speechos-primary: #0d9488;
1740
+ --speechos-primary-hover: #0f766e;
1741
+ --speechos-primary-active: #115e59;
1723
1742
 
1724
1743
  --speechos-bg: #ffffff;
1725
1744
  --speechos-bg-hover: #f9fafb;
@@ -2284,45 +2303,51 @@ let SpeechOSMicButton = class SpeechOSMicButton extends i$1 {
2284
2303
  width: 56px;
2285
2304
  height: 56px;
2286
2305
  border-radius: var(--speechos-radius-full);
2287
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
2306
+ background: #10b981;
2288
2307
  border: none;
2289
2308
  cursor: pointer;
2290
2309
  display: flex;
2291
2310
  align-items: center;
2292
2311
  justify-content: center;
2293
2312
  color: white;
2294
- box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);
2295
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
2313
+ box-shadow: 0 4px 16px rgba(16, 185, 129, 0.35);
2314
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
2296
2315
  position: relative;
2297
2316
  overflow: hidden;
2298
2317
  }
2299
2318
 
2300
2319
  .mic-button:hover {
2320
+ background: #059669;
2301
2321
  transform: scale(1.05);
2302
- box-shadow: 0 6px 20px rgba(16, 185, 129, 0.5);
2322
+ box-shadow: 0 6px 24px rgba(16, 185, 129, 0.45);
2303
2323
  }
2304
2324
 
2305
2325
  .mic-button:active {
2306
2326
  transform: scale(0.98);
2307
2327
  }
2308
2328
 
2329
+ .mic-button:focus {
2330
+ outline: none;
2331
+ box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.4), 0 4px 16px rgba(16, 185, 129, 0.35);
2332
+ }
2333
+
2309
2334
  /* Expanded state - bubbles visible */
2310
2335
  .mic-button.expanded {
2311
- background: linear-gradient(135deg, #059669 0%, #047857 100%);
2336
+ background: #059669;
2312
2337
  }
2313
2338
 
2314
2339
  /* Connecting state - Siri-style metallic spinner */
2315
2340
  .mic-button.connecting {
2316
2341
  background: radial-gradient(
2317
2342
  circle at 30% 30%,
2318
- #34d399 0%,
2319
- #10b981 40%,
2320
- #059669 70%,
2321
- #047857 100%
2343
+ #2dd4bf 0%,
2344
+ #14b8a6 40%,
2345
+ #0d9488 70%,
2346
+ #0f766e 100%
2322
2347
  );
2323
2348
  cursor: wait;
2324
- box-shadow: 0 0 20px rgba(16, 185, 129, 0.4),
2325
- 0 0 40px rgba(16, 185, 129, 0.2),
2349
+ box-shadow: 0 0 20px rgba(13, 148, 136, 0.4),
2350
+ 0 0 40px rgba(13, 148, 136, 0.2),
2326
2351
  inset 0 0 20px rgba(255, 255, 255, 0.1);
2327
2352
  }
2328
2353
 
@@ -2365,15 +2390,15 @@ let SpeechOSMicButton = class SpeechOSMicButton extends i$1 {
2365
2390
  background: conic-gradient(
2366
2391
  from 0deg,
2367
2392
  transparent 0deg,
2368
- rgba(52, 211, 153, 0.1) 30deg,
2369
- rgba(16, 185, 129, 0.8) 90deg,
2393
+ rgba(45, 212, 191, 0.1) 30deg,
2394
+ rgba(13, 148, 136, 0.8) 90deg,
2370
2395
  rgba(255, 255, 255, 0.95) 120deg,
2371
- rgba(52, 211, 153, 0.9) 150deg,
2372
- rgba(16, 185, 129, 0.6) 180deg,
2373
- rgba(5, 150, 105, 0.3) 210deg,
2396
+ rgba(45, 212, 191, 0.9) 150deg,
2397
+ rgba(13, 148, 136, 0.6) 180deg,
2398
+ rgba(15, 118, 110, 0.3) 210deg,
2374
2399
  transparent 270deg,
2375
- rgba(110, 231, 183, 0.2) 300deg,
2376
- rgba(16, 185, 129, 0.5) 330deg,
2400
+ rgba(94, 234, 212, 0.2) 300deg,
2401
+ rgba(13, 148, 136, 0.5) 330deg,
2377
2402
  transparent 360deg
2378
2403
  );
2379
2404
  -webkit-mask: linear-gradient(#fff 0 0) content-box,
@@ -2394,13 +2419,13 @@ let SpeechOSMicButton = class SpeechOSMicButton extends i$1 {
2394
2419
  background: conic-gradient(
2395
2420
  from 180deg,
2396
2421
  transparent 0deg,
2397
- rgba(167, 243, 208, 0.3) 60deg,
2422
+ rgba(153, 246, 228, 0.3) 60deg,
2398
2423
  rgba(255, 255, 255, 0.7) 90deg,
2399
- rgba(110, 231, 183, 0.5) 120deg,
2424
+ rgba(94, 234, 212, 0.5) 120deg,
2400
2425
  transparent 180deg,
2401
- rgba(52, 211, 153, 0.2) 240deg,
2426
+ rgba(45, 212, 191, 0.2) 240deg,
2402
2427
  rgba(255, 255, 255, 0.5) 270deg,
2403
- rgba(16, 185, 129, 0.4) 300deg,
2428
+ rgba(13, 148, 136, 0.4) 300deg,
2404
2429
  transparent 360deg
2405
2430
  );
2406
2431
  -webkit-mask: linear-gradient(#fff 0 0) content-box,
@@ -2441,8 +2466,8 @@ let SpeechOSMicButton = class SpeechOSMicButton extends i$1 {
2441
2466
  border-radius: 50%;
2442
2467
  background: radial-gradient(
2443
2468
  circle,
2444
- rgba(16, 185, 129, 0.4) 0%,
2445
- rgba(16, 185, 129, 0.15) 40%,
2469
+ rgba(13, 148, 136, 0.4) 0%,
2470
+ rgba(13, 148, 136, 0.15) 40%,
2446
2471
  transparent 70%
2447
2472
  );
2448
2473
  animation: siri-glow-pulse 2s ease-in-out infinite;
@@ -3862,15 +3887,15 @@ const modalLayoutStyles = i$4 `
3862
3887
  }
3863
3888
 
3864
3889
  .modal {
3865
- background: #1a1d24;
3890
+ background: #f5f5f4;
3866
3891
  border-radius: 16px;
3867
3892
  width: 90%;
3868
3893
  max-width: 580px;
3869
3894
  height: min(560px, 85vh);
3870
3895
  display: flex;
3871
3896
  flex-direction: column;
3872
- box-shadow: 0 24px 48px rgba(0, 0, 0, 0.4),
3873
- 0 0 0 1px rgba(255, 255, 255, 0.05);
3897
+ box-shadow: 0 24px 48px rgba(0, 0, 0, 0.15),
3898
+ 0 0 0 1px rgba(0, 0, 0, 0.05);
3874
3899
  transform: scale(0.95) translateY(10px);
3875
3900
  transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
3876
3901
  pointer-events: auto;
@@ -3895,16 +3920,16 @@ const modalLayoutStyles = i$4 `
3895
3920
  align-items: center;
3896
3921
  justify-content: space-between;
3897
3922
  padding: 16px 20px;
3898
- border-bottom: 1px solid rgba(255, 255, 255, 0.06);
3899
- background: rgba(0, 0, 0, 0.2);
3923
+ border-bottom: 1px solid #e5e5e5;
3924
+ background: #ffffff;
3900
3925
  }
3901
3926
 
3902
3927
  .modal-title {
3903
3928
  font-size: 17px;
3904
3929
  font-weight: 600;
3905
- color: white;
3930
+ color: #171717;
3906
3931
  margin: 0;
3907
- letter-spacing: -0.01em;
3932
+ letter-spacing: -0.02em;
3908
3933
  }
3909
3934
 
3910
3935
  .modal-logo {
@@ -3917,7 +3942,7 @@ const modalLayoutStyles = i$4 `
3917
3942
  width: 28px;
3918
3943
  height: 28px;
3919
3944
  border-radius: 8px;
3920
- background: linear-gradient(135deg, #10b981 0%, #8b5cf6 100%);
3945
+ background: linear-gradient(135deg, #14b8a6 0%, #2563eb 100%);
3921
3946
  display: flex;
3922
3947
  align-items: center;
3923
3948
  justify-content: center;
@@ -3932,13 +3957,13 @@ const modalLayoutStyles = i$4 `
3932
3957
  .logo-text {
3933
3958
  font-size: 17px;
3934
3959
  font-weight: 500;
3935
- color: white;
3960
+ color: #171717;
3936
3961
  letter-spacing: -0.02em;
3937
3962
  }
3938
3963
 
3939
3964
  .logo-os {
3940
3965
  font-weight: 700;
3941
- background: linear-gradient(135deg, #34d399 0%, #a78bfa 100%);
3966
+ background: linear-gradient(135deg, #14b8a6 0%, #2563eb 100%);
3942
3967
  -webkit-background-clip: text;
3943
3968
  -webkit-text-fill-color: transparent;
3944
3969
  background-clip: text;
@@ -3954,13 +3979,22 @@ const modalLayoutStyles = i$4 `
3954
3979
  display: flex;
3955
3980
  align-items: center;
3956
3981
  justify-content: center;
3957
- color: rgba(255, 255, 255, 0.5);
3982
+ color: #737373;
3958
3983
  transition: all 0.15s ease;
3959
3984
  }
3960
3985
 
3961
3986
  .close-button:hover {
3962
- background: rgba(255, 255, 255, 0.08);
3963
- color: white;
3987
+ background: #f5f5f4;
3988
+ color: #171717;
3989
+ }
3990
+
3991
+ .close-button:focus {
3992
+ outline: none;
3993
+ box-shadow: 0 0 0 2px #0d9488, 0 0 0 4px rgba(13, 148, 136, 0.2);
3994
+ }
3995
+
3996
+ .close-button:active {
3997
+ transform: scale(0.95);
3964
3998
  }
3965
3999
 
3966
4000
  .modal-body {
@@ -3972,8 +4006,8 @@ const modalLayoutStyles = i$4 `
3972
4006
  .sidebar {
3973
4007
  width: 110px;
3974
4008
  flex-shrink: 0;
3975
- background: rgba(0, 0, 0, 0.25);
3976
- border-right: 1px solid rgba(255, 255, 255, 0.06);
4009
+ background: #fafaf9;
4010
+ border-right: 1px solid #e5e5e5;
3977
4011
  padding: 12px 8px;
3978
4012
  display: flex;
3979
4013
  flex-direction: column;
@@ -4002,19 +4036,25 @@ const modalLayoutStyles = i$4 `
4002
4036
  border-radius: 10px;
4003
4037
  background: transparent;
4004
4038
  cursor: pointer;
4005
- color: rgba(255, 255, 255, 0.5);
4039
+ color: #525252;
4006
4040
  transition: all 0.15s ease;
4007
4041
  position: relative;
4008
4042
  }
4009
4043
 
4010
4044
  .sidebar-item:hover {
4011
- background: rgba(255, 255, 255, 0.05);
4012
- color: rgba(255, 255, 255, 0.8);
4045
+ background: #ffffff;
4046
+ color: #171717;
4047
+ }
4048
+
4049
+ .sidebar-item:focus {
4050
+ outline: none;
4051
+ box-shadow: inset 0 0 0 2px rgba(13, 148, 136, 0.4);
4013
4052
  }
4014
4053
 
4015
4054
  .sidebar-item.active {
4016
- background: rgba(16, 185, 129, 0.12);
4017
- color: #34d399;
4055
+ background: rgba(15, 118, 110, 0.12);
4056
+ color: #0f766e;
4057
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
4018
4058
  }
4019
4059
 
4020
4060
  .sidebar-item.active::before {
@@ -4025,7 +4065,7 @@ const modalLayoutStyles = i$4 `
4025
4065
  transform: translateY(-50%);
4026
4066
  width: 3px;
4027
4067
  height: 24px;
4028
- background: #34d399;
4068
+ background: #0f766e;
4029
4069
  border-radius: 0 3px 3px 0;
4030
4070
  }
4031
4071
 
@@ -4068,14 +4108,14 @@ const tabContentStyles = i$4 `
4068
4108
  .section-title {
4069
4109
  font-size: 15px;
4070
4110
  font-weight: 600;
4071
- color: white;
4111
+ color: #171717;
4072
4112
  margin: 0 0 6px 0;
4073
- letter-spacing: -0.01em;
4113
+ letter-spacing: -0.02em;
4074
4114
  }
4075
4115
 
4076
4116
  .section-description {
4077
4117
  font-size: 13px;
4078
- color: rgba(255, 255, 255, 0.5);
4118
+ color: #525252;
4079
4119
  line-height: 1.5;
4080
4120
  margin: 0;
4081
4121
  }
@@ -4083,7 +4123,7 @@ const tabContentStyles = i$4 `
4083
4123
  .empty-state {
4084
4124
  text-align: center;
4085
4125
  padding: 40px 20px;
4086
- color: rgba(255, 255, 255, 0.5);
4126
+ color: #737373;
4087
4127
  }
4088
4128
 
4089
4129
  .empty-state-icon {
@@ -4095,7 +4135,7 @@ const tabContentStyles = i$4 `
4095
4135
  font-size: 15px;
4096
4136
  font-weight: 500;
4097
4137
  margin-bottom: 8px;
4098
- color: rgba(255, 255, 255, 0.7);
4138
+ color: #525252;
4099
4139
  }
4100
4140
 
4101
4141
  .empty-state-text {
@@ -4113,7 +4153,7 @@ const tabContentStyles = i$4 `
4113
4153
  display: flex;
4114
4154
  align-items: center;
4115
4155
  justify-content: center;
4116
- color: rgba(255, 255, 255, 0.35);
4156
+ color: #737373;
4117
4157
  transition: all 0.15s ease;
4118
4158
  }
4119
4159
 
@@ -4151,20 +4191,30 @@ const formStyles = i$4 `
4151
4191
  align-items: center;
4152
4192
  gap: 6px;
4153
4193
  padding: 10px 16px;
4154
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
4194
+ background: #0d9488;
4155
4195
  border: none;
4156
4196
  border-radius: 8px;
4157
4197
  color: white;
4158
4198
  font-size: 13px;
4159
4199
  font-weight: 600;
4200
+ letter-spacing: 0.01em;
4160
4201
  cursor: pointer;
4161
- transition: all 0.2s ease;
4162
- box-shadow: 0 2px 8px rgba(16, 185, 129, 0.2);
4202
+ transition: all 0.15s ease;
4203
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
4163
4204
  }
4164
4205
 
4165
4206
  .add-button:hover:not(:disabled) {
4166
- transform: translateY(-1px);
4167
- box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
4207
+ background: #0f766e;
4208
+ box-shadow: 0 4px 12px rgba(13, 148, 136, 0.25);
4209
+ }
4210
+
4211
+ .add-button:focus:not(:disabled) {
4212
+ outline: none;
4213
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #0d9488;
4214
+ }
4215
+
4216
+ .add-button:active:not(:disabled) {
4217
+ transform: scale(0.98);
4168
4218
  }
4169
4219
 
4170
4220
  .add-button:disabled {
@@ -4175,7 +4225,7 @@ const formStyles = i$4 `
4175
4225
 
4176
4226
  .count-badge {
4177
4227
  font-size: 12px;
4178
- color: rgba(255, 255, 255, 0.45);
4228
+ color: #737373;
4179
4229
  font-weight: 500;
4180
4230
  }
4181
4231
 
@@ -4187,11 +4237,12 @@ const formStyles = i$4 `
4187
4237
  }
4188
4238
 
4189
4239
  .add-form {
4190
- background: rgba(255, 255, 255, 0.04);
4191
- border: 1px solid rgba(255, 255, 255, 0.08);
4240
+ background: #ffffff;
4241
+ border: 1px solid #e5e5e5;
4192
4242
  border-radius: 12px;
4193
4243
  padding: 16px;
4194
4244
  margin-bottom: 16px;
4245
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
4195
4246
  }
4196
4247
 
4197
4248
  .form-group {
@@ -4206,7 +4257,7 @@ const formStyles = i$4 `
4206
4257
  display: block;
4207
4258
  font-size: 12px;
4208
4259
  font-weight: 600;
4209
- color: rgba(255, 255, 255, 0.7);
4260
+ color: #525252;
4210
4261
  margin-bottom: 8px;
4211
4262
  text-transform: uppercase;
4212
4263
  letter-spacing: 0.04em;
@@ -4215,10 +4266,10 @@ const formStyles = i$4 `
4215
4266
  .form-input {
4216
4267
  width: 100%;
4217
4268
  padding: 12px 14px;
4218
- background: rgba(0, 0, 0, 0.3);
4219
- border: 1px solid rgba(255, 255, 255, 0.08);
4269
+ background: #ffffff;
4270
+ border: 1px solid #d4d4d4;
4220
4271
  border-radius: 8px;
4221
- color: white;
4272
+ color: #171717;
4222
4273
  font-size: 14px;
4223
4274
  font-family: inherit;
4224
4275
  transition: all 0.15s ease;
@@ -4227,12 +4278,12 @@ const formStyles = i$4 `
4227
4278
 
4228
4279
  .form-input:focus {
4229
4280
  outline: none;
4230
- border-color: #34d399;
4231
- box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.15);
4281
+ border-color: #0d9488;
4282
+ box-shadow: 0 0 0 3px rgba(13, 148, 136, 0.15);
4232
4283
  }
4233
4284
 
4234
4285
  .form-input::placeholder {
4235
- color: rgba(255, 255, 255, 0.3);
4286
+ color: #a3a3a3;
4236
4287
  }
4237
4288
 
4238
4289
  .form-input.error {
@@ -4256,7 +4307,7 @@ const formStyles = i$4 `
4256
4307
 
4257
4308
  .char-count {
4258
4309
  font-size: 11px;
4259
- color: rgba(255, 255, 255, 0.4);
4310
+ color: #737373;
4260
4311
  font-variant-numeric: tabular-nums;
4261
4312
  }
4262
4313
 
@@ -4290,26 +4341,35 @@ const formStyles = i$4 `
4290
4341
  }
4291
4342
 
4292
4343
  .form-btn.cancel {
4293
- background: transparent;
4294
- border: 1px solid rgba(255, 255, 255, 0.15);
4295
- color: rgba(255, 255, 255, 0.7);
4344
+ background: #ffffff;
4345
+ border: 1px solid #d4d4d4;
4346
+ color: #525252;
4296
4347
  }
4297
4348
 
4298
4349
  .form-btn.cancel:hover {
4299
- background: rgba(255, 255, 255, 0.05);
4300
- border-color: rgba(255, 255, 255, 0.25);
4350
+ background: #fafaf9;
4351
+ border-color: #a3a3a3;
4301
4352
  }
4302
4353
 
4303
4354
  .form-btn.save {
4304
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
4355
+ background: #0d9488;
4305
4356
  border: none;
4306
4357
  color: white;
4307
- box-shadow: 0 2px 8px rgba(16, 185, 129, 0.2);
4358
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
4308
4359
  }
4309
4360
 
4310
4361
  .form-btn.save:hover:not(:disabled) {
4311
- transform: translateY(-1px);
4312
- box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
4362
+ background: #0f766e;
4363
+ box-shadow: 0 4px 12px rgba(13, 148, 136, 0.25);
4364
+ }
4365
+
4366
+ .form-btn.save:focus:not(:disabled) {
4367
+ outline: none;
4368
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #0d9488;
4369
+ }
4370
+
4371
+ .form-btn.save:active:not(:disabled) {
4372
+ transform: scale(0.98);
4313
4373
  }
4314
4374
 
4315
4375
  .form-btn.save:disabled {
@@ -4343,16 +4403,17 @@ let SpeechOSHistoryTab = class SpeechOSHistoryTab extends i$1 {
4343
4403
  }
4344
4404
 
4345
4405
  .transcript-item {
4346
- background: rgba(255, 255, 255, 0.04);
4347
- border: 1px solid rgba(255, 255, 255, 0.06);
4406
+ background: #ffffff;
4407
+ border: 1px solid #e5e5e5;
4348
4408
  border-radius: 10px;
4349
4409
  padding: 12px 14px;
4350
4410
  transition: all 0.15s ease;
4411
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
4351
4412
  }
4352
4413
 
4353
4414
  .transcript-item:hover {
4354
- background: rgba(255, 255, 255, 0.06);
4355
- border-color: rgba(255, 255, 255, 0.1);
4415
+ border-color: #d4d4d4;
4416
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
4356
4417
  }
4357
4418
 
4358
4419
  .transcript-header {
@@ -4375,28 +4436,28 @@ let SpeechOSHistoryTab = class SpeechOSHistoryTab extends i$1 {
4375
4436
  }
4376
4437
 
4377
4438
  .transcript-badge.dictate {
4378
- background: rgba(16, 185, 129, 0.15);
4379
- color: #34d399;
4439
+ background: rgba(13, 148, 136, 0.18);
4440
+ color: #0f766e;
4380
4441
  }
4381
4442
 
4382
4443
  .transcript-badge.edit {
4383
- background: rgba(139, 92, 246, 0.15);
4384
- color: #a78bfa;
4444
+ background: rgba(139, 92, 246, 0.18);
4445
+ color: #7c3aed;
4385
4446
  }
4386
4447
 
4387
4448
  .transcript-badge.command {
4388
- background: rgba(245, 158, 11, 0.15);
4389
- color: #fbbf24;
4449
+ background: rgba(245, 158, 11, 0.18);
4450
+ color: #b45309;
4390
4451
  }
4391
4452
 
4392
4453
  .transcript-time {
4393
4454
  font-size: 12px;
4394
- color: rgba(255, 255, 255, 0.35);
4455
+ color: #737373;
4395
4456
  }
4396
4457
 
4397
4458
  .transcript-text {
4398
4459
  font-size: 14px;
4399
- color: rgba(255, 255, 255, 0.85);
4460
+ color: #171717;
4400
4461
  line-height: 1.5;
4401
4462
  word-break: break-word;
4402
4463
  display: -webkit-box;
@@ -4411,7 +4472,7 @@ let SpeechOSHistoryTab = class SpeechOSHistoryTab extends i$1 {
4411
4472
  gap: 8px;
4412
4473
  margin-top: 10px;
4413
4474
  padding-top: 10px;
4414
- border-top: 1px solid rgba(255, 255, 255, 0.06);
4475
+ border-top: 1px solid #e5e5e5;
4415
4476
  }
4416
4477
 
4417
4478
  .transcript-action-btn {
@@ -4420,23 +4481,23 @@ let SpeechOSHistoryTab = class SpeechOSHistoryTab extends i$1 {
4420
4481
  gap: 6px;
4421
4482
  padding: 6px 10px;
4422
4483
  border-radius: 6px;
4423
- background: rgba(255, 255, 255, 0.06);
4484
+ background: rgba(0, 0, 0, 0.08);
4424
4485
  border: none;
4425
4486
  cursor: pointer;
4426
4487
  font-size: 12px;
4427
4488
  font-weight: 500;
4428
- color: rgba(255, 255, 255, 0.6);
4489
+ color: #404040;
4429
4490
  transition: all 0.15s ease;
4430
4491
  }
4431
4492
 
4432
4493
  .transcript-action-btn:hover {
4433
- background: rgba(255, 255, 255, 0.1);
4434
- color: rgba(255, 255, 255, 0.9);
4494
+ background: rgba(0, 0, 0, 0.12);
4495
+ color: #171717;
4435
4496
  }
4436
4497
 
4437
4498
  .transcript-action-btn.copied {
4438
- background: rgba(16, 185, 129, 0.2);
4439
- color: #34d399;
4499
+ background: rgba(13, 148, 136, 0.2);
4500
+ color: #0d9488;
4440
4501
  }
4441
4502
 
4442
4503
  .transcript-action-btn.delete:hover {
@@ -4450,9 +4511,9 @@ let SpeechOSHistoryTab = class SpeechOSHistoryTab extends i$1 {
4450
4511
  margin-top: 16px;
4451
4512
  padding: 10px;
4452
4513
  background: rgba(239, 68, 68, 0.1);
4453
- border: 1px solid rgba(239, 68, 68, 0.15);
4514
+ border: 1px solid rgba(239, 68, 68, 0.2);
4454
4515
  border-radius: 8px;
4455
- color: #f87171;
4516
+ color: #dc2626;
4456
4517
  font-size: 13px;
4457
4518
  font-weight: 500;
4458
4519
  cursor: pointer;
@@ -4461,18 +4522,18 @@ let SpeechOSHistoryTab = class SpeechOSHistoryTab extends i$1 {
4461
4522
 
4462
4523
  .clear-all-button:hover {
4463
4524
  background: rgba(239, 68, 68, 0.18);
4464
- border-color: rgba(239, 68, 68, 0.25);
4525
+ border-color: rgba(239, 68, 68, 0.3);
4465
4526
  }
4466
4527
 
4467
4528
  .command-matched {
4468
4529
  font-size: 12px;
4469
- color: rgba(255, 255, 255, 0.5);
4530
+ color: #525252;
4470
4531
  margin-top: 6px;
4471
4532
  }
4472
4533
 
4473
4534
  .command-matched code {
4474
4535
  background: rgba(245, 158, 11, 0.15);
4475
- color: #fbbf24;
4536
+ color: #d97706;
4476
4537
  padding: 2px 6px;
4477
4538
  border-radius: 4px;
4478
4539
  font-family: monospace;
@@ -4660,21 +4721,21 @@ let SpeechOSHelpTab = class SpeechOSHelpTab extends i$1 {
4660
4721
  gap: 8px;
4661
4722
  font-size: 15px;
4662
4723
  font-weight: 600;
4663
- color: white;
4724
+ color: #171717;
4664
4725
  margin-bottom: 10px;
4665
4726
  }
4666
4727
 
4667
4728
  .help-title.dictate {
4668
- color: #34d399;
4729
+ color: #0f766e;
4669
4730
  }
4670
4731
 
4671
4732
  .help-title.edit {
4672
- color: #a78bfa;
4733
+ color: #7c3aed;
4673
4734
  }
4674
4735
 
4675
4736
  .help-text {
4676
4737
  font-size: 13px;
4677
- color: rgba(255, 255, 255, 0.6);
4738
+ color: #525252;
4678
4739
  line-height: 1.6;
4679
4740
  margin-bottom: 10px;
4680
4741
  }
@@ -4691,17 +4752,17 @@ let SpeechOSHelpTab = class SpeechOSHelpTab extends i$1 {
4691
4752
  }
4692
4753
 
4693
4754
  .help-example {
4694
- background: rgba(255, 255, 255, 0.04);
4695
- border: 1px solid rgba(255, 255, 255, 0.06);
4755
+ background: #ffffff;
4756
+ border: 1px solid #e5e5e5;
4696
4757
  border-radius: 6px;
4697
4758
  padding: 8px 12px;
4698
4759
  font-size: 12px;
4699
- color: rgba(255, 255, 255, 0.5);
4760
+ color: #525252;
4700
4761
  font-style: italic;
4701
4762
  }
4702
4763
 
4703
4764
  .help-title.languages {
4704
- background: linear-gradient(135deg, #34d399 0%, #a78bfa 100%);
4765
+ background: linear-gradient(135deg, #0f766e 0%, #1d4ed8 100%);
4705
4766
  -webkit-background-clip: text;
4706
4767
  -webkit-text-fill-color: transparent;
4707
4768
  background-clip: text;
@@ -4779,7 +4840,7 @@ let SpeechOSAboutTab = class SpeechOSAboutTab extends i$1 {
4779
4840
  width: 36px;
4780
4841
  height: 36px;
4781
4842
  border-radius: 10px;
4782
- background: linear-gradient(135deg, #10b981 0%, #8b5cf6 100%);
4843
+ background: linear-gradient(135deg, #14b8a6 0%, #2563eb 100%);
4783
4844
  display: flex;
4784
4845
  align-items: center;
4785
4846
  justify-content: center;
@@ -4794,13 +4855,13 @@ let SpeechOSAboutTab = class SpeechOSAboutTab extends i$1 {
4794
4855
  .about-logo-text {
4795
4856
  font-size: 22px;
4796
4857
  font-weight: 500;
4797
- color: white;
4858
+ color: #171717;
4798
4859
  letter-spacing: -0.02em;
4799
4860
  }
4800
4861
 
4801
4862
  .logo-os {
4802
4863
  font-weight: 700;
4803
- background: linear-gradient(135deg, #34d399 0%, #a78bfa 100%);
4864
+ background: linear-gradient(135deg, #14b8a6 0%, #2563eb 100%);
4804
4865
  -webkit-background-clip: text;
4805
4866
  -webkit-text-fill-color: transparent;
4806
4867
  background-clip: text;
@@ -4808,7 +4869,7 @@ let SpeechOSAboutTab = class SpeechOSAboutTab extends i$1 {
4808
4869
 
4809
4870
  .about-description {
4810
4871
  font-size: 14px;
4811
- color: rgba(255, 255, 255, 0.65);
4872
+ color: #525252;
4812
4873
  line-height: 1.7;
4813
4874
  margin-bottom: 24px;
4814
4875
  }
@@ -4826,19 +4887,29 @@ let SpeechOSAboutTab = class SpeechOSAboutTab extends i$1 {
4826
4887
  align-items: center;
4827
4888
  gap: 8px;
4828
4889
  padding: 12px 18px;
4829
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
4890
+ background: #0d9488;
4830
4891
  border-radius: 10px;
4831
4892
  color: white;
4832
4893
  font-size: 14px;
4833
4894
  font-weight: 600;
4895
+ letter-spacing: 0.01em;
4834
4896
  text-decoration: none;
4835
- transition: all 0.2s ease;
4836
- box-shadow: 0 4px 12px rgba(16, 185, 129, 0.25);
4897
+ transition: all 0.15s ease;
4898
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
4837
4899
  }
4838
4900
 
4839
4901
  .about-link:hover {
4840
- transform: translateY(-1px);
4841
- box-shadow: 0 6px 16px rgba(16, 185, 129, 0.35);
4902
+ background: #0f766e;
4903
+ box-shadow: 0 4px 12px rgba(13, 148, 136, 0.25);
4904
+ }
4905
+
4906
+ .about-link:focus {
4907
+ outline: none;
4908
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #0d9488;
4909
+ }
4910
+
4911
+ .about-link:active {
4912
+ transform: scale(0.98);
4842
4913
  }
4843
4914
  `,
4844
4915
  ]; }
@@ -4918,20 +4989,21 @@ let SpeechOSAudioLevelMeter = class SpeechOSAudioLevelMeter extends i$1 {
4918
4989
  gap: 3px;
4919
4990
  height: 32px;
4920
4991
  padding: 8px 12px;
4921
- background: rgba(0, 0, 0, 0.2);
4992
+ background: #ffffff;
4993
+ border: 2px solid #e5e5e5;
4922
4994
  border-radius: 8px;
4923
4995
  }
4924
4996
 
4925
4997
  .meter-bar {
4926
4998
  width: 6px;
4927
4999
  min-height: 4px;
4928
- background: rgba(255, 255, 255, 0.2);
5000
+ background: #d4d4d4;
4929
5001
  border-radius: 2px;
4930
5002
  transition: height 50ms ease-out, background 100ms ease;
4931
5003
  }
4932
5004
 
4933
5005
  .meter-bar.active {
4934
- background: var(--speechos-primary);
5006
+ background: #10b981;
4935
5007
  }
4936
5008
 
4937
5009
  .meter-inactive {
@@ -4940,14 +5012,15 @@ let SpeechOSAudioLevelMeter = class SpeechOSAudioLevelMeter extends i$1 {
4940
5012
  justify-content: center;
4941
5013
  height: 32px;
4942
5014
  padding: 8px 12px;
4943
- background: rgba(0, 0, 0, 0.2);
5015
+ background: #ffffff;
5016
+ border: 2px solid #e5e5e5;
4944
5017
  border-radius: 8px;
4945
- color: rgba(255, 255, 255, 0.4);
5018
+ color: #737373;
4946
5019
  font-size: 13px;
4947
5020
  }
4948
5021
 
4949
5022
  .meter-error {
4950
- color: #f87171;
5023
+ color: #dc2626;
4951
5024
  }
4952
5025
  `,
4953
5026
  ]; }
@@ -5144,18 +5217,18 @@ let SpeechOSSettingsTab = class SpeechOSSettingsTab extends i$1 {
5144
5217
  }
5145
5218
 
5146
5219
  .settings-section-icon {
5147
- color: #34d399;
5220
+ color: #0d9488;
5148
5221
  }
5149
5222
 
5150
5223
  .settings-section-title {
5151
5224
  font-size: 14px;
5152
5225
  font-weight: 600;
5153
- color: white;
5226
+ color: #171717;
5154
5227
  }
5155
5228
 
5156
5229
  .settings-section-description {
5157
5230
  font-size: 13px;
5158
- color: rgba(255, 255, 255, 0.45);
5231
+ color: #525252;
5159
5232
  line-height: 1.5;
5160
5233
  margin-bottom: 14px;
5161
5234
  }
@@ -5184,10 +5257,10 @@ let SpeechOSSettingsTab = class SpeechOSSettingsTab extends i$1 {
5184
5257
  .settings-select {
5185
5258
  width: 100%;
5186
5259
  padding: 12px 40px 12px 14px;
5187
- background: rgba(0, 0, 0, 0.3);
5188
- border: 1px solid rgba(255, 255, 255, 0.08);
5260
+ background: #ffffff;
5261
+ border: 1px solid #d4d4d4;
5189
5262
  border-radius: 10px;
5190
- color: white;
5263
+ color: #171717;
5191
5264
  font-size: 14px;
5192
5265
  font-family: inherit;
5193
5266
  cursor: pointer;
@@ -5197,34 +5270,44 @@ let SpeechOSSettingsTab = class SpeechOSSettingsTab extends i$1 {
5197
5270
  }
5198
5271
 
5199
5272
  .settings-select:hover {
5200
- border-color: rgba(255, 255, 255, 0.15);
5201
- background: rgba(0, 0, 0, 0.4);
5273
+ border-color: #a3a3a3;
5274
+ background: #ffffff;
5202
5275
  }
5203
5276
 
5204
5277
  .settings-select:focus {
5205
5278
  outline: none;
5206
- border-color: #34d399;
5207
- box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.15);
5279
+ border-color: #0d9488;
5280
+ box-shadow: 0 0 0 3px rgba(13, 148, 136, 0.15);
5208
5281
  }
5209
5282
 
5210
5283
  .settings-select option {
5211
- background: #1a1d24;
5212
- color: white;
5284
+ background: #ffffff;
5285
+ color: #171717;
5213
5286
  padding: 8px;
5214
5287
  }
5215
5288
 
5289
+ .settings-select:disabled {
5290
+ opacity: 0.4;
5291
+ cursor: not-allowed;
5292
+ }
5293
+
5294
+ .settings-select:disabled:hover {
5295
+ border-color: #d4d4d4;
5296
+ background: #ffffff;
5297
+ }
5298
+
5216
5299
  .settings-select-arrow {
5217
5300
  position: absolute;
5218
5301
  right: 14px;
5219
5302
  top: 50%;
5220
5303
  transform: translateY(-50%);
5221
5304
  pointer-events: none;
5222
- color: rgba(255, 255, 255, 0.4);
5305
+ color: #737373;
5223
5306
  }
5224
5307
 
5225
5308
  .settings-permission-note {
5226
5309
  font-size: 12px;
5227
- color: rgba(255, 255, 255, 0.4);
5310
+ color: #737373;
5228
5311
  margin-top: 10px;
5229
5312
  font-style: italic;
5230
5313
  }
@@ -5234,7 +5317,7 @@ let SpeechOSSettingsTab = class SpeechOSSettingsTab extends i$1 {
5234
5317
  align-items: center;
5235
5318
  gap: 4px;
5236
5319
  font-size: 11px;
5237
- color: #34d399;
5320
+ color: #059669;
5238
5321
  font-weight: 500;
5239
5322
  opacity: 0;
5240
5323
  transition: opacity 0.2s ease;
@@ -5250,28 +5333,34 @@ let SpeechOSSettingsTab = class SpeechOSSettingsTab extends i$1 {
5250
5333
  align-items: center;
5251
5334
  justify-content: space-between;
5252
5335
  padding: 12px 14px;
5253
- background: rgba(0, 0, 0, 0.3);
5254
- border: 1px solid rgba(255, 255, 255, 0.08);
5336
+ background: #ffffff;
5337
+ border: 1px solid #e5e5e5;
5255
5338
  border-radius: 10px;
5339
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
5256
5340
  }
5257
5341
 
5258
5342
  .settings-toggle-label {
5259
5343
  font-size: 14px;
5260
- color: white;
5344
+ color: #171717;
5261
5345
  }
5262
5346
 
5263
5347
  .settings-toggle {
5264
5348
  position: relative;
5265
5349
  width: 44px;
5266
5350
  height: 24px;
5267
- background: rgba(255, 255, 255, 0.1);
5351
+ background: #d4d4d4;
5268
5352
  border-radius: 12px;
5269
5353
  cursor: pointer;
5270
5354
  transition: background 0.2s ease;
5271
5355
  }
5272
5356
 
5273
5357
  .settings-toggle.active {
5274
- background: #34d399;
5358
+ background: #0d9488;
5359
+ }
5360
+
5361
+ .settings-toggle:focus {
5362
+ outline: none;
5363
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #0d9488;
5275
5364
  }
5276
5365
 
5277
5366
  .settings-toggle-knob {
@@ -5394,13 +5483,14 @@ let SpeechOSSettingsTab = class SpeechOSSettingsTab extends i$1 {
5394
5483
  setSmartFormatEnabled(this.smartFormatEnabled);
5395
5484
  this.showSaved();
5396
5485
  }
5397
- renderLanguageSelector(selectedCode, onChange) {
5486
+ renderLanguageSelector(selectedCode, onChange, disabled = false) {
5398
5487
  return b `
5399
5488
  <div class="settings-select-wrapper">
5400
5489
  <select
5401
5490
  class="settings-select"
5402
5491
  .value="${selectedCode}"
5403
5492
  @change="${onChange}"
5493
+ ?disabled="${disabled}"
5404
5494
  >
5405
5495
  ${SUPPORTED_LANGUAGES.map((lang) => b `
5406
5496
  <option
@@ -5518,7 +5608,7 @@ let SpeechOSSettingsTab = class SpeechOSSettingsTab extends i$1 {
5518
5608
  <div class="settings-section-description">
5519
5609
  AI automatically removes filler words, adds punctuation, and polishes
5520
5610
  your text. Disable for raw transcription output. Note: disabling also
5521
- turns off text snippets.
5611
+ turns off text snippets and output language translation.
5522
5612
  </div>
5523
5613
  <div class="settings-toggle-row">
5524
5614
  <span class="settings-toggle-label">Enable AI formatting</span>
@@ -5559,9 +5649,13 @@ let SpeechOSSettingsTab = class SpeechOSSettingsTab extends i$1 {
5559
5649
  </div>
5560
5650
  <div class="settings-section-description">
5561
5651
  The language for your transcribed text. Usually the same as input, but
5562
- can differ for translation.
5652
+ can differ for translation.${!this.smartFormatEnabled
5653
+ ? " Requires Smart Format to be enabled."
5654
+ : ""}
5563
5655
  </div>
5564
- ${this.renderLanguageSelector(this.selectedOutputLanguageCode, this.handleOutputLanguageChange.bind(this))}
5656
+ ${this.renderLanguageSelector(this.smartFormatEnabled
5657
+ ? this.selectedOutputLanguageCode
5658
+ : this.selectedInputLanguageCode, this.handleOutputLanguageChange.bind(this), !this.smartFormatEnabled)}
5565
5659
  </div>
5566
5660
  `;
5567
5661
  }
@@ -5624,17 +5718,18 @@ let SpeechOSSnippetsTab = class SpeechOSSnippetsTab extends i$1 {
5624
5718
  }
5625
5719
 
5626
5720
  .snippet-item {
5627
- background: rgba(255, 255, 255, 0.04);
5628
- border: 1px solid rgba(255, 255, 255, 0.06);
5721
+ background: #ffffff;
5722
+ border: 1px solid #e5e5e5;
5629
5723
  border-radius: 10px;
5630
5724
  padding: 14px;
5631
5725
  transition: all 0.15s ease;
5632
5726
  position: relative;
5727
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
5633
5728
  }
5634
5729
 
5635
5730
  .snippet-item:hover {
5636
- background: rgba(255, 255, 255, 0.06);
5637
- border-color: rgba(255, 255, 255, 0.1);
5731
+ border-color: #d4d4d4;
5732
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
5638
5733
  }
5639
5734
 
5640
5735
  .snippet-trigger {
@@ -5647,7 +5742,7 @@ let SpeechOSSnippetsTab = class SpeechOSSnippetsTab extends i$1 {
5647
5742
  .snippet-trigger-text {
5648
5743
  font-size: 14px;
5649
5744
  font-weight: 600;
5650
- color: #34d399;
5745
+ color: #0d9488;
5651
5746
  }
5652
5747
 
5653
5748
  .snippet-trigger-text::before {
@@ -5665,12 +5760,12 @@ let SpeechOSSnippetsTab = class SpeechOSSnippetsTab extends i$1 {
5665
5760
  align-items: flex-start;
5666
5761
  gap: 8px;
5667
5762
  font-size: 13px;
5668
- color: rgba(255, 255, 255, 0.65);
5763
+ color: #525252;
5669
5764
  line-height: 1.5;
5670
5765
  }
5671
5766
 
5672
5767
  .snippet-expansion-arrow {
5673
- color: rgba(255, 255, 255, 0.3);
5768
+ color: #a3a3a3;
5674
5769
  flex-shrink: 0;
5675
5770
  margin-top: 2px;
5676
5771
  }
@@ -5699,13 +5794,13 @@ let SpeechOSSnippetsTab = class SpeechOSSnippetsTab extends i$1 {
5699
5794
  display: flex;
5700
5795
  align-items: center;
5701
5796
  justify-content: center;
5702
- color: rgba(255, 255, 255, 0.4);
5797
+ color: #737373;
5703
5798
  transition: all 0.15s ease;
5704
5799
  }
5705
5800
 
5706
5801
  .edit-btn:hover {
5707
- background: rgba(52, 211, 153, 0.15);
5708
- color: #34d399;
5802
+ background: rgba(13, 148, 136, 0.1);
5803
+ color: #0d9488;
5709
5804
  }
5710
5805
  `,
5711
5806
  ]; }
@@ -5988,30 +6083,32 @@ let SpeechOSVocabularyTab = class SpeechOSVocabularyTab extends i$1 {
5988
6083
  gap: 8px;
5989
6084
  padding: 8px 12px;
5990
6085
  background: rgba(139, 92, 246, 0.1);
5991
- border: 1px solid rgba(139, 92, 246, 0.2);
6086
+ border: 1px solid rgba(139, 92, 246, 0.25);
5992
6087
  border-radius: 8px;
5993
6088
  transition: all 0.15s ease;
5994
6089
  }
5995
6090
 
5996
6091
  .vocabulary-chip:hover {
5997
6092
  background: rgba(139, 92, 246, 0.15);
5998
- border-color: rgba(139, 92, 246, 0.3);
6093
+ border-color: rgba(139, 92, 246, 0.35);
5999
6094
  }
6000
6095
 
6001
6096
  .vocabulary-chip-text {
6002
6097
  font-size: 13px;
6003
6098
  font-weight: 500;
6004
- color: #c4b5fd;
6099
+ color: #7c3aed;
6005
6100
  }
6006
6101
 
6007
6102
  .vocabulary-chip .delete-btn {
6008
6103
  width: 20px;
6009
6104
  height: 20px;
6010
6105
  margin: -4px -4px -4px 0;
6106
+ color: #737373;
6011
6107
  }
6012
6108
 
6013
6109
  .vocabulary-chip .delete-btn:hover {
6014
6110
  background: rgba(239, 68, 68, 0.2);
6111
+ color: #f87171;
6015
6112
  }
6016
6113
  `,
6017
6114
  ]; }
@@ -6412,14 +6509,14 @@ const popupModalStyles = i$4 `
6412
6509
  }
6413
6510
 
6414
6511
  .modal-card {
6415
- background: #1a1d24;
6512
+ background: #f5f5f4;
6416
6513
  border-radius: 16px;
6417
6514
  width: 90%;
6418
6515
  max-width: 400px;
6419
6516
  display: flex;
6420
6517
  flex-direction: column;
6421
- box-shadow: 0 24px 48px rgba(0, 0, 0, 0.4),
6422
- 0 0 0 1px rgba(255, 255, 255, 0.05);
6518
+ box-shadow: 0 24px 48px rgba(0, 0, 0, 0.15),
6519
+ 0 0 0 1px rgba(0, 0, 0, 0.05);
6423
6520
  transform: scale(0.95) translateY(10px);
6424
6521
  transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
6425
6522
  pointer-events: auto;
@@ -6435,14 +6532,14 @@ const popupModalStyles = i$4 `
6435
6532
  align-items: center;
6436
6533
  justify-content: space-between;
6437
6534
  padding: 16px 20px;
6438
- border-bottom: 1px solid rgba(255, 255, 255, 0.06);
6439
- background: rgba(0, 0, 0, 0.2);
6535
+ border-bottom: 1px solid #e5e5e5;
6536
+ background: #ffffff;
6440
6537
  }
6441
6538
 
6442
6539
  .modal-title {
6443
6540
  font-size: 16px;
6444
6541
  font-weight: 600;
6445
- color: white;
6542
+ color: #171717;
6446
6543
  margin: 0;
6447
6544
  letter-spacing: -0.01em;
6448
6545
  }
@@ -6457,13 +6554,22 @@ const popupModalStyles = i$4 `
6457
6554
  display: flex;
6458
6555
  align-items: center;
6459
6556
  justify-content: center;
6460
- color: rgba(255, 255, 255, 0.5);
6557
+ color: #737373;
6461
6558
  transition: all 0.15s ease;
6462
6559
  }
6463
6560
 
6464
6561
  .close-button:hover {
6465
- background: rgba(255, 255, 255, 0.08);
6466
- color: white;
6562
+ background: #f5f5f4;
6563
+ color: #171717;
6564
+ }
6565
+
6566
+ .close-button:focus {
6567
+ outline: none;
6568
+ box-shadow: 0 0 0 2px #0d9488, 0 0 0 4px rgba(13, 148, 136, 0.2);
6569
+ }
6570
+
6571
+ .close-button:active {
6572
+ transform: scale(0.95);
6467
6573
  }
6468
6574
 
6469
6575
  .modal-body {
@@ -6475,8 +6581,8 @@ const popupModalStyles = i$4 `
6475
6581
  justify-content: flex-end;
6476
6582
  gap: 10px;
6477
6583
  padding: 16px 20px;
6478
- border-top: 1px solid rgba(255, 255, 255, 0.06);
6479
- background: rgba(0, 0, 0, 0.1);
6584
+ border-top: 1px solid #e5e5e5;
6585
+ background: #ffffff;
6480
6586
  }
6481
6587
 
6482
6588
  .btn {
@@ -6493,42 +6599,47 @@ const popupModalStyles = i$4 `
6493
6599
  }
6494
6600
 
6495
6601
  .btn-secondary {
6496
- background: rgba(255, 255, 255, 0.08);
6497
- color: rgba(255, 255, 255, 0.8);
6602
+ background: rgba(0, 0, 0, 0.08);
6603
+ color: #525252;
6498
6604
  }
6499
6605
 
6500
6606
  .btn-secondary:hover {
6501
- background: rgba(255, 255, 255, 0.12);
6502
- color: white;
6607
+ background: rgba(0, 0, 0, 0.12);
6608
+ color: #171717;
6503
6609
  }
6504
6610
 
6505
6611
  .btn-primary {
6506
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
6612
+ background: #0d9488;
6507
6613
  color: white;
6508
- box-shadow: 0 2px 8px rgba(16, 185, 129, 0.2);
6614
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
6509
6615
  }
6510
6616
 
6511
6617
  .btn-primary:hover {
6512
- transform: translateY(-1px);
6513
- box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
6618
+ background: #0f766e;
6619
+ box-shadow: 0 4px 12px rgba(13, 148, 136, 0.25);
6620
+ }
6621
+
6622
+ .btn-primary:focus {
6623
+ outline: none;
6624
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #0d9488;
6514
6625
  }
6515
6626
 
6516
6627
  .btn-primary:active {
6517
- transform: translateY(0);
6628
+ transform: scale(0.98);
6518
6629
  }
6519
6630
 
6520
6631
  /* Success state for copy button */
6521
6632
  .btn-success {
6522
- background: linear-gradient(135deg, #34d399 0%, #10b981 100%);
6633
+ background: #059669;
6523
6634
  }
6524
6635
 
6525
6636
  /* Text display area */
6526
6637
  .text-display {
6527
- background: rgba(0, 0, 0, 0.3);
6528
- border: 1px solid rgba(255, 255, 255, 0.08);
6638
+ background: #ffffff;
6639
+ border: 1px solid #e5e5e5;
6529
6640
  border-radius: 10px;
6530
6641
  padding: 14px 16px;
6531
- color: white;
6642
+ color: #171717;
6532
6643
  font-size: 14px;
6533
6644
  line-height: 1.5;
6534
6645
  max-height: 200px;
@@ -6547,12 +6658,12 @@ const popupModalStyles = i$4 `
6547
6658
  }
6548
6659
 
6549
6660
  .text-display::-webkit-scrollbar-thumb {
6550
- background: rgba(255, 255, 255, 0.15);
6661
+ background: rgba(0, 0, 0, 0.15);
6551
6662
  border-radius: 3px;
6552
6663
  }
6553
6664
 
6554
6665
  .text-display::-webkit-scrollbar-thumb:hover {
6555
- background: rgba(255, 255, 255, 0.25);
6666
+ background: rgba(0, 0, 0, 0.25);
6556
6667
  }
6557
6668
 
6558
6669
  /* Instruction list styling */
@@ -6567,7 +6678,7 @@ const popupModalStyles = i$4 `
6567
6678
  align-items: flex-start;
6568
6679
  gap: 12px;
6569
6680
  padding: 12px 0;
6570
- border-bottom: 1px solid rgba(255, 255, 255, 0.06);
6681
+ border-bottom: 1px solid #e5e5e5;
6571
6682
  }
6572
6683
 
6573
6684
  .instruction-item:last-child {
@@ -6578,7 +6689,7 @@ const popupModalStyles = i$4 `
6578
6689
  width: 24px;
6579
6690
  height: 24px;
6580
6691
  border-radius: 50%;
6581
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
6692
+ background: #0d9488;
6582
6693
  color: white;
6583
6694
  font-size: 12px;
6584
6695
  font-weight: 700;
@@ -6590,7 +6701,7 @@ const popupModalStyles = i$4 `
6590
6701
 
6591
6702
  .instruction-text {
6592
6703
  font-size: 14px;
6593
- color: rgba(255, 255, 255, 0.85);
6704
+ color: #171717;
6594
6705
  line-height: 1.5;
6595
6706
  padding-top: 2px;
6596
6707
  }
@@ -6648,7 +6759,7 @@ let SpeechOSDictationOutputModal = class SpeechOSDictationOutputModal extends i$
6648
6759
  width: 32px;
6649
6760
  height: 32px;
6650
6761
  border-radius: 8px;
6651
- background: linear-gradient(135deg, #10b981 0%, #8b5cf6 100%);
6762
+ background: linear-gradient(135deg, #14b8a6 0%, #2563eb 100%);
6652
6763
  display: flex;
6653
6764
  align-items: center;
6654
6765
  justify-content: center;
@@ -6662,31 +6773,35 @@ let SpeechOSDictationOutputModal = class SpeechOSDictationOutputModal extends i$
6662
6773
  }
6663
6774
 
6664
6775
  .modal-title {
6665
- background: linear-gradient(135deg, #34d399 0%, #a78bfa 100%);
6776
+ background: linear-gradient(135deg, #14b8a6 0%, #2563eb 100%);
6666
6777
  -webkit-background-clip: text;
6667
6778
  -webkit-text-fill-color: transparent;
6668
6779
  background-clip: text;
6669
6780
  }
6670
6781
 
6671
6782
  .btn-primary {
6672
- background: linear-gradient(135deg, #10b981 0%, #059669 100%);
6673
- box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
6783
+ background: #0d9488;
6784
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
6674
6785
  border-radius: 999px;
6675
6786
  }
6676
6787
 
6677
6788
  .btn-primary:hover {
6678
- background: linear-gradient(135deg, #34d399 0%, #10b981 100%);
6679
- transform: translateY(-2px);
6680
- box-shadow: 0 6px 16px rgba(16, 185, 129, 0.4);
6789
+ background: #0f766e;
6790
+ box-shadow: 0 4px 12px rgba(13, 148, 136, 0.25);
6791
+ }
6792
+
6793
+ .btn-primary:focus {
6794
+ outline: none;
6795
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #0d9488;
6681
6796
  }
6682
6797
 
6683
6798
  .btn-primary:active {
6684
- transform: translateY(0);
6799
+ transform: scale(0.98);
6685
6800
  }
6686
6801
 
6687
6802
  .btn-success {
6688
- background: linear-gradient(135deg, #34d399 0%, #10b981 100%);
6689
- box-shadow: 0 4px 12px rgba(52, 211, 153, 0.3);
6803
+ background: #059669;
6804
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
6690
6805
  border-radius: 999px;
6691
6806
  }
6692
6807
 
@@ -6700,14 +6815,15 @@ let SpeechOSDictationOutputModal = class SpeechOSDictationOutputModal extends i$
6700
6815
  gap: 6px;
6701
6816
  margin-top: 12px;
6702
6817
  padding: 8px 12px;
6703
- background: rgba(16, 185, 129, 0.08);
6818
+ background: #ffffff;
6819
+ border: 1px solid #e5e5e5;
6704
6820
  border-radius: 8px;
6705
6821
  font-size: 12px;
6706
- color: rgba(255, 255, 255, 0.6);
6822
+ color: #525252;
6707
6823
  }
6708
6824
 
6709
6825
  .hint-icon {
6710
- color: #10b981;
6826
+ color: #0d9488;
6711
6827
  flex-shrink: 0;
6712
6828
  }
6713
6829
 
@@ -7553,7 +7669,14 @@ let SpeechOSWidget = class SpeechOSWidget extends i$1 {
7553
7669
  state.hide();
7554
7670
  }
7555
7671
  handleSettingsClick() {
7556
- this.settingsOpen = true;
7672
+ if (useExternalSettings()) {
7673
+ const host = getConfig().host;
7674
+ const fullUrl = `${host}/a/extension-settings`;
7675
+ window.open(fullUrl, '_blank', 'noopener,noreferrer');
7676
+ }
7677
+ else {
7678
+ this.settingsOpen = true;
7679
+ }
7557
7680
  }
7558
7681
  handleDragStart(e) {
7559
7682
  if (e.button !== 0)
@@ -8094,10 +8217,17 @@ let SpeechOSWidget = class SpeechOSWidget extends i$1 {
8094
8217
  this.editSelectionStart = null;
8095
8218
  this.editSelectionEnd = null;
8096
8219
  this.editSelectedText = "";
8097
- // Open settings modal
8098
- this.settingsOpen = true;
8220
+ // Open settings - either external URL or modal
8221
+ if (useExternalSettings()) {
8222
+ const host = getConfig().host;
8223
+ const fullUrl = `${host}/a/extension-settings`;
8224
+ window.open(fullUrl, '_blank', 'noopener,noreferrer');
8225
+ }
8226
+ else {
8227
+ this.settingsOpen = true;
8228
+ }
8099
8229
  if (getConfig().debug) {
8100
- console.log("[SpeechOS] Settings modal opened from no-audio warning");
8230
+ console.log("[SpeechOS] Settings opened from no-audio warning", { useExternalSettings: useExternalSettings() });
8101
8231
  }
8102
8232
  await disconnectPromise;
8103
8233
  }
@@ -8611,5 +8741,5 @@ class SpeechOS {
8611
8741
  // Version
8612
8742
  const VERSION = "0.1.0";
8613
8743
 
8614
- export { DefaultTextInputHandler, FormDetector, SUPPORTED_LANGUAGES, SpeechOS, VERSION, addSnippet, addTerm, audioSettings, clearSnippets, clearTranscripts, clearVocabulary, SpeechOS as default, defaultTextInputHandler, deleteSnippet, deleteTerm, deleteTranscript, formDetector, getAudioDeviceId, getAudioInputDevices, getAudioSettings, getClientConfig, getCommands, getInputLanguageCode, getInputLanguageName, getLanguageByCode, getLanguageCode, getLanguageName, getLanguageSettings, getOutputLanguageCode, getOutputLanguageName, getSessionSettings, getSmartFormatEnabled, getSnippetCount, getSnippets, getTextInputHandler, getTranscripts, getVocabulary, getVocabularyCount, getZIndex, hasCommands, isAtSnippetLimit, isAtVocabularyLimit, isSelectedDeviceAvailable, languageSettings, resetAudioSettings, resetClientConfig, resetLanguageSettings, resetTextInputHandler, saveTranscript, setAudioDeviceId, setClientConfig, setInputLanguageCode, setLanguageCode, setOutputLanguageCode, setSmartFormatEnabled, setTextInputHandler, settingsSync, snippetsStore, transcriptStore, updateSnippet, vocabularyStore };
8744
+ export { DefaultTextInputHandler, FormDetector, SUPPORTED_LANGUAGES, SpeechOS, VERSION, addSnippet, addTerm, audioSettings, clearSnippets, clearTranscripts, clearVocabulary, SpeechOS as default, defaultTextInputHandler, deleteSnippet, deleteTerm, deleteTranscript, formDetector, getAudioDeviceId, getAudioInputDevices, getAudioSettings, getClientConfig, getCommands, getInputLanguageCode, getInputLanguageName, getLanguageByCode, getLanguageCode, getLanguageName, getLanguageSettings, getOutputLanguageCode, getOutputLanguageName, getSessionSettings, getSmartFormatEnabled, getSnippetCount, getSnippets, getTextInputHandler, getTranscripts, getVocabulary, getVocabularyCount, getZIndex, hasCommands, isAtSnippetLimit, isAtVocabularyLimit, isSelectedDeviceAvailable, languageSettings, resetAudioSettings, resetClientConfig, resetLanguageSettings, resetTextInputHandler, saveTranscript, setAudioDeviceId, setClientConfig, setInputLanguageCode, setLanguageCode, setOutputLanguageCode, setSmartFormatEnabled, setTextInputHandler, settingsSync, snippetsStore, transcriptStore, updateSnippet, useExternalSettings, vocabularyStore };
8615
8745
  //# sourceMappingURL=index.js.map