@qaiddev/quests-embed 1.0.0 → 1.1.0

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.
@@ -1,102 +1,96 @@
1
- const k = '*{box-sizing:border-box}button{cursor:pointer;font-family:inherit}.qaid-q-root{font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px);color:light-dark(#1f2937,#f9fafb)}.qaid-q-backdrop{position:fixed;inset:0;z-index:45;background:rgba(0,0,0,var(--qaid-backdrop-opacity, .4));animation:qaid-q-fade .18s ease-out}@keyframes qaid-q-fade{0%{opacity:0}to{opacity:1}}.qaid-q-modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:50;width:var(--qaid-modal-width, 480px);max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);pointer-events:auto;display:flex;flex-direction:column}.qaid-q-card{background:light-dark(#ffffff,#1f2937);color:light-dark(#1f2937,#f9fafb);border-radius:1rem;box-shadow:0 25px 50px -12px light-dark(rgba(0,0,0,.25),rgba(0,0,0,.6));padding:1.5rem;overflow:hidden;display:flex;flex-direction:column;min-height:0}:where(.qaid-q-root.qaid-q-inline) .qaid-q-card{box-shadow:none;border:1px solid light-dark(#e5e7eb,#374151);flex:1;min-height:0}:where(.qaid-q-root.qaid-q-inline){height:100%;display:flex;flex-direction:column;min-height:0}.qaid-q-header{display:flex;align-items:center;justify-content:space-between;gap:.75rem;margin-bottom:1rem}.qaid-q-title{font-size:1.125em;font-weight:700;margin:0;color:light-dark(#1f2937,#f9fafb)}.qaid-q-step-counter{font-size:.875em;color:light-dark(#6b7280,#9ca3af);font-variant-numeric:tabular-nums;white-space:nowrap}.qaid-q-close{width:28px;height:28px;padding:0;border:none;border-radius:50%;background:transparent;color:light-dark(#6b7280,#9ca3af);display:inline-flex;align-items:center;justify-content:center;-webkit-appearance:none;appearance:none}.qaid-q-close:hover{background:light-dark(#f3f4f6,#374151);color:light-dark(#1f2937,#f9fafb)}.qaid-q-close:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker, #6366f1) 30%,transparent)}.qaid-q-progress{position:relative;height:4px;background:light-dark(#e5e7eb,#374151);border-radius:9999px;overflow:hidden;margin-bottom:1.25rem}.qaid-q-progress--inline{flex:1;min-width:60px;margin-bottom:0}.qaid-q-progress-fill{position:absolute;inset:0 auto 0 0;background:var(--qaid-positive, #10b981);border-radius:9999px;transition:width .3s ease;width:0%}.qaid-q-body{flex:1;min-height:0;overflow-y:auto}.qaid-q-step{display:flex;flex-direction:column;gap:.75rem;animation:qaid-q-slide .22s ease-out}@keyframes qaid-q-slide{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.qaid-q-label{font-size:1.125em;font-weight:600;margin:0;color:light-dark(#1f2937,#f9fafb);line-height:1.35}.qaid-q-label .qaid-q-required{color:var(--qaid-negative, #ef4444);margin-left:.25rem}.qaid-q-description{font-size:.875em;color:light-dark(#6b7280,#9ca3af);margin:0;line-height:1.4}.qaid-q-error{font-size:.8125em;color:var(--qaid-negative, #ef4444);margin:0}.qaid-q-error:empty{display:none}.qaid-q-input,.qaid-q-textarea{width:100%;padding:.75rem .875rem;border:1px solid light-dark(#d1d5db,#374151);border-radius:.625rem;font-family:inherit;font-size:1em;background:light-dark(#ffffff,#111827);color:light-dark(#1f2937,#f9fafb);transition:border-color .15s,box-shadow .15s;-webkit-appearance:none;appearance:none}.qaid-q-textarea{min-height:7rem;resize:vertical;font-family:inherit}.qaid-q-input:focus,.qaid-q-textarea:focus{outline:none;border-color:var(--qaid-marker, #6366f1);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker, #6366f1) 20%,transparent)}.qaid-q-input::placeholder,.qaid-q-textarea::placeholder{color:light-dark(#9ca3af,#6b7280)}.qaid-q-currency{position:relative}.qaid-q-currency-prefix{position:absolute;left:.875rem;top:50%;transform:translateY(-50%);color:light-dark(#6b7280,#9ca3af);font-size:1em;font-weight:500;pointer-events:none}.qaid-q-currency .qaid-q-input{padding-left:2.25rem}.qaid-q-range-wrap{display:flex;flex-direction:column;gap:.5rem;padding:.5rem 0}.qaid-q-range-value{font-size:2em;font-weight:700;text-align:center;font-variant-numeric:tabular-nums;color:var(--qaid-positive, #10b981)}.qaid-q-range-value .qaid-q-range-unit{font-size:.5em;font-weight:500;color:light-dark(#6b7280,#9ca3af);margin-left:.25rem}.qaid-q-range{width:100%;-webkit-appearance:none;appearance:none;height:6px;border-radius:9999px;background:light-dark(#e5e7eb,#374151);outline:none}.qaid-q-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:22px;height:22px;border-radius:50%;background:var(--qaid-positive, #10b981);border:3px solid light-dark(#ffffff,#1f2937);box-shadow:0 2px 6px #0003;cursor:pointer;transition:transform .1s}.qaid-q-range::-moz-range-thumb{width:22px;height:22px;border-radius:50%;background:var(--qaid-positive, #10b981);border:3px solid light-dark(#ffffff,#1f2937);box-shadow:0 2px 6px #0003;cursor:pointer}.qaid-q-range:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 6px color-mix(in srgb,var(--qaid-marker, #6366f1) 30%,transparent)}.qaid-q-range:focus-visible::-moz-range-thumb{box-shadow:0 0 0 6px color-mix(in srgb,var(--qaid-marker, #6366f1) 30%,transparent)}.qaid-q-range-bounds{display:flex;justify-content:space-between;font-size:.8125em;color:light-dark(#6b7280,#9ca3af);font-variant-numeric:tabular-nums}.qaid-q-options{display:flex;flex-direction:column;gap:.5rem}.qaid-q-option{display:flex;align-items:flex-start;gap:.625rem;padding:.75rem .875rem;border:1px solid light-dark(#e5e7eb,#374151);border-radius:.625rem;background:light-dark(#ffffff,#111827);text-align:left;font-size:1em;color:light-dark(#1f2937,#f9fafb);cursor:pointer;transition:border-color .12s,background .12s,box-shadow .12s;-webkit-appearance:none;appearance:none;width:100%}.qaid-q-option:hover{border-color:light-dark(#9ca3af,#4b5563);background:light-dark(#f9fafb,#1f2937)}.qaid-q-option:focus-visible{outline:none;border-color:var(--qaid-marker, #6366f1);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker, #6366f1) 25%,transparent)}.qaid-q-option.qaid-q-selected{border-color:var(--qaid-positive, #10b981);background:color-mix(in srgb,var(--qaid-positive, #10b981) 10%,transparent)}.qaid-q-option-marker{flex-shrink:0;width:1.25rem;height:1.25rem;border:2px solid light-dark(#d1d5db,#4b5563);border-radius:50%;display:inline-flex;align-items:center;justify-content:center;margin-top:.125rem;background:light-dark(#ffffff,#111827);transition:border-color .12s,background .12s}.qaid-q-option.qaid-q-multi .qaid-q-option-marker{border-radius:.25rem}.qaid-q-option.qaid-q-selected .qaid-q-option-marker{border-color:var(--qaid-positive, #10b981);background:var(--qaid-positive, #10b981)}.qaid-q-option.qaid-q-selected .qaid-q-option-marker:after{content:"";display:block;width:.5rem;height:.5rem;border-radius:50%;background:light-dark(#ffffff,#1f2937)}.qaid-q-option.qaid-q-multi.qaid-q-selected .qaid-q-option-marker:after{content:"";display:block;width:.625rem;height:.625rem;border-radius:0;background:transparent;border-right:2px solid light-dark(#ffffff,#1f2937);border-bottom:2px solid light-dark(#ffffff,#1f2937);transform:rotate(45deg) translate(-1px,-2px)}.qaid-q-option-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:.125rem}.qaid-q-option-image{display:block;width:48px;height:48px;aspect-ratio:1 / 1;object-fit:cover;border-radius:.375rem;background:light-dark(#f3f4f6,#374151);flex-shrink:0}.qaid-q-options--image-horizontal .qaid-q-option-body{flex-direction:row;align-items:center;gap:.75rem}.qaid-q-options--image-horizontal .qaid-q-option-body>:not(.qaid-q-option-image){flex:1;min-width:0;display:flex;flex-direction:column;gap:.125rem}.qaid-q-options--image-vertical{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:.5rem}.qaid-q-options--image-vertical .qaid-q-option{flex-direction:column;align-items:stretch;text-align:center;padding:.75rem;gap:.5rem}.qaid-q-options--image-vertical .qaid-q-option-body{align-items:center;text-align:center}.qaid-q-options--image-vertical .qaid-q-option-image{width:100%;height:auto;max-width:100%}.qaid-q-options--image-vertical .qaid-q-option-marker{position:absolute;top:.5rem;right:.5rem;margin-top:0}.qaid-q-options--image-vertical .qaid-q-option{position:relative}.qaid-q-options--image-vertical .qaid-q-option-key{position:absolute;top:.5rem;left:.5rem;align-self:auto}.qaid-q-option-label{font-weight:500;line-height:1.3}.qaid-q-option-desc{font-size:.8125em;color:light-dark(#6b7280,#9ca3af);line-height:1.4}.qaid-q-option-key{flex-shrink:0;align-self:center;font-size:.7em;font-weight:600;padding:.125rem .375rem;border-radius:.25rem;background:light-dark(#f3f4f6,#374151);color:light-dark(#6b7280,#9ca3af);font-variant-numeric:tabular-nums}.qaid-q-footer{display:flex;align-items:center;justify-content:space-between;gap:.5rem;margin-top:1.25rem}.qaid-q-footer--inline-progress{justify-content:flex-start;gap:.75rem}.qaid-q-footer-left,.qaid-q-footer-right{display:flex;gap:.5rem}.qaid-q-btn{padding:.625rem 1.125rem;border-radius:.5rem;font-size:.9375em;font-weight:500;border:1px solid transparent;cursor:pointer;transition:filter .15s,background .15s,color .15s;-webkit-appearance:none;appearance:none}.qaid-q-btn:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-marker, #6366f1) 30%,transparent)}.qaid-q-btn-secondary{background:transparent;border-color:light-dark(#d1d5db,#4b5563);color:light-dark(#374151,#d1d5db)}.qaid-q-btn-secondary:hover{background:light-dark(#f3f4f6,#374151)}.qaid-q-btn-primary{background:var(--qaid-positive, #10b981);color:var(--qaid-positive-text, #ffffff);border-color:transparent}.qaid-q-btn-primary:hover{filter:brightness(.9)}.qaid-q-btn-primary:disabled{opacity:.5;cursor:not-allowed;filter:none}.qaid-q-hint{font-size:.75em;color:light-dark(#6b7280,#9ca3af)}.qaid-q-hint kbd{display:inline-block;padding:.05rem .35rem;border-radius:.25rem;background:light-dark(#f3f4f6,#374151);border:1px solid light-dark(#e5e7eb,#4b5563);font-family:inherit;font-size:.7em;font-weight:600;color:light-dark(#374151,#e5e7eb)}.qaid-q-done{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.5rem;padding:1.5rem 0}.qaid-q-done-icon{width:48px;height:48px;border-radius:50%;background:color-mix(in srgb,var(--qaid-positive, #10b981) 18%,transparent);color:var(--qaid-positive, #10b981);display:inline-flex;align-items:center;justify-content:center;margin-bottom:.5rem}.qaid-q-done-title{font-size:1.25em;font-weight:700;margin:0}.qaid-q-done-message{color:light-dark(#6b7280,#9ca3af);margin:0}.qaid-q-saving{display:inline-flex;align-items:center;gap:.375rem;font-size:.75em;color:light-dark(#6b7280,#9ca3af);opacity:0;transition:opacity .2s}.qaid-q-saving.qaid-q-visible{opacity:1}.qaid-q-saving-dot{width:6px;height:6px;border-radius:50%;background:var(--qaid-positive, #10b981);animation:qaid-q-pulse 1.2s ease-in-out infinite}@keyframes qaid-q-pulse{0%,to{opacity:.3}50%{opacity:1}}';
2
- function w(t, e, i) {
3
- const [a, n, s] = [t, e, i].map((r) => (r = r / 255, r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4)));
4
- return 0.2126 * a + 0.7152 * n + 0.0722 * s;
1
+ const C = `*{box-sizing:border-box}button{cursor:pointer;font-family:inherit}:where(.qaid-q-root){--qaid-q-card-bg: light-dark(#ffffff, #1f2937);--qaid-q-card-fg: light-dark(#1f2937, #f9fafb);--qaid-q-card-border: light-dark(#e5e7eb, #374151);--qaid-q-card-radius: 1rem;--qaid-q-card-padding: 1.5rem;--qaid-q-card-shadow: 0 25px 50px -12px light-dark(rgba(0, 0, 0, .25), rgba(0, 0, 0, .6));--qaid-q-muted-fg: light-dark(#6b7280, #9ca3af);--qaid-q-progress-track: light-dark(#e5e7eb, #374151);--qaid-q-btn-radius: .5rem;--qaid-q-btn-padding-y: .625rem;--qaid-q-btn-padding-x: 1.125rem;--qaid-q-btn-font-weight: 500;--qaid-q-btn-primary-bg: var(--qaid-q-accent, #10b981);--qaid-q-btn-primary-fg: var(--qaid-q-accent-text, #ffffff);--qaid-q-btn-primary-border: transparent;--qaid-q-btn-secondary-bg: transparent;--qaid-q-btn-secondary-fg: light-dark(#374151, #d1d5db);--qaid-q-btn-secondary-border: light-dark(#d1d5db, #4b5563);--qaid-q-btn-secondary-hover-bg: light-dark(#f3f4f6, #374151);--qaid-q-option-bg: light-dark(#ffffff, #111827);--qaid-q-option-bg-selected: color-mix(in srgb, var(--qaid-q-accent, #10b981) 10%, transparent);--qaid-q-option-bg-hover: light-dark(#f9fafb, #1f2937);--qaid-q-option-fg: light-dark(#1f2937, #f9fafb);--qaid-q-option-border: light-dark(#e5e7eb, #374151);--qaid-q-option-border-selected: var(--qaid-q-accent, #10b981);--qaid-q-option-border-hover: light-dark(#9ca3af, #4b5563);--qaid-q-option-radius: .625rem;--qaid-q-option-padding: .75rem .875rem;--qaid-q-marker-bg: light-dark(#ffffff, #111827);--qaid-q-marker-bg-selected: var(--qaid-q-accent, #10b981);--qaid-q-marker-border: light-dark(#d1d5db, #4b5563);--qaid-q-marker-icon: light-dark(#ffffff, #1f2937);--qaid-q-marker-radius: 50%;--qaid-q-input-bg: light-dark(#ffffff, #111827);--qaid-q-input-fg: light-dark(#1f2937, #f9fafb);--qaid-q-input-border: light-dark(#d1d5db, #374151);--qaid-q-input-radius: .625rem;--qaid-q-input-padding: .75rem .875rem;--qaid-q-input-placeholder: light-dark(#9ca3af, #6b7280);--qaid-q-gap: .75rem;--qaid-q-section-gap: 1.25rem}:where(.qaid-q-root.qaid-q-theme-light){--qaid-q-card-bg: #ffffff;--qaid-q-card-fg: #1f2937;--qaid-q-card-border: #e5e7eb;--qaid-q-card-shadow: 0 25px 50px -12px rgba(0, 0, 0, .25);--qaid-q-muted-fg: #6b7280;--qaid-q-progress-track: #e5e7eb;--qaid-q-btn-secondary-fg: #374151;--qaid-q-btn-secondary-border: #d1d5db;--qaid-q-btn-secondary-hover-bg: #f3f4f6;--qaid-q-option-bg: #ffffff;--qaid-q-option-bg-hover: #f9fafb;--qaid-q-option-fg: #1f2937;--qaid-q-option-border: #e5e7eb;--qaid-q-option-border-hover: #9ca3af;--qaid-q-marker-bg: #ffffff;--qaid-q-marker-border: #d1d5db;--qaid-q-marker-icon: #ffffff;--qaid-q-input-bg: #ffffff;--qaid-q-input-fg: #1f2937;--qaid-q-input-border: #d1d5db;--qaid-q-input-placeholder: #9ca3af}:where(.qaid-q-root.qaid-q-theme-dark){--qaid-q-card-bg: #1f2937;--qaid-q-card-fg: #f9fafb;--qaid-q-card-border: #374151;--qaid-q-card-shadow: 0 25px 50px -12px rgba(0, 0, 0, .6);--qaid-q-muted-fg: #9ca3af;--qaid-q-progress-track: #374151;--qaid-q-btn-secondary-fg: #d1d5db;--qaid-q-btn-secondary-border: #4b5563;--qaid-q-btn-secondary-hover-bg: #374151;--qaid-q-option-bg: #111827;--qaid-q-option-bg-hover: #1f2937;--qaid-q-option-fg: #f9fafb;--qaid-q-option-border: #374151;--qaid-q-option-border-hover: #4b5563;--qaid-q-marker-bg: #111827;--qaid-q-marker-border: #4b5563;--qaid-q-marker-icon: #1f2937;--qaid-q-input-bg: #111827;--qaid-q-input-fg: #f9fafb;--qaid-q-input-border: #374151;--qaid-q-input-placeholder: #6b7280}.qaid-q-root{color-scheme:light dark;font-family:var(--qaid-font-family, system-ui, -apple-system, sans-serif);font-size:var(--qaid-font-size, 16px);color:var(--qaid-q-card-fg)}.qaid-q-root.qaid-q-theme-light{color-scheme:light}.qaid-q-root.qaid-q-theme-dark{color-scheme:dark}.qaid-q-backdrop{position:fixed;inset:0;z-index:45;background:rgba(0,0,0,var(--qaid-backdrop-opacity, .4));animation:qaid-q-fade .18s ease-out}@keyframes qaid-q-fade{0%{opacity:0}to{opacity:1}}.qaid-q-modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:50;width:var(--qaid-modal-width, 480px);max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);pointer-events:auto;display:flex;flex-direction:column}.qaid-q-card{background:var(--qaid-q-card-bg);color:var(--qaid-q-card-fg);border-radius:var(--qaid-q-card-radius);box-shadow:var(--qaid-q-card-shadow);padding:var(--qaid-q-card-padding);overflow:hidden;display:flex;flex-direction:column;min-height:0}:where(.qaid-q-root.qaid-q-inline) .qaid-q-card{box-shadow:none;border:1px solid var(--qaid-q-card-border);flex:1;min-height:0}:where(.qaid-q-root.qaid-q-inline){height:100%;display:flex;flex-direction:column;min-height:0}.qaid-q-header{display:flex;align-items:center;justify-content:space-between;gap:.75rem;margin-bottom:1rem}.qaid-q-title{font-size:1.125em;font-weight:700;margin:0;color:var(--qaid-q-card-fg)}.qaid-q-step-counter{font-size:.875em;color:var(--qaid-q-muted-fg);font-variant-numeric:tabular-nums;white-space:nowrap}.qaid-q-close{width:28px;height:28px;padding:0;border:none;border-radius:50%;background:transparent;color:var(--qaid-q-muted-fg);display:inline-flex;align-items:center;justify-content:center;-webkit-appearance:none;appearance:none}.qaid-q-close:hover{background:var(--qaid-q-btn-secondary-hover-bg);color:var(--qaid-q-card-fg)}.qaid-q-close:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-q-focus, #6366f1) 30%,transparent)}.qaid-q-progress{position:relative;height:4px;background:var(--qaid-q-progress-track);border-radius:9999px;overflow:hidden;margin-bottom:var(--qaid-q-section-gap)}.qaid-q-progress--inline{flex:1;min-width:60px;margin-bottom:0}.qaid-q-progress-fill{position:absolute;inset:0 auto 0 0;background:var(--qaid-q-accent, #10b981);border-radius:9999px;transition:width .3s ease;width:0%}.qaid-q-body{flex:1;min-height:0;overflow-y:auto}.qaid-q-step{display:flex;flex-direction:column;gap:var(--qaid-q-gap);animation:qaid-q-slide .22s ease-out}@keyframes qaid-q-slide{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.qaid-q-no-motion .qaid-q-step,.qaid-q-no-motion.qaid-q-root{animation:none!important}.qaid-q-label{font-size:1.125em;font-weight:600;margin:0;color:var(--qaid-q-card-fg);line-height:1.35}.qaid-q-label .qaid-q-required{color:var(--qaid-q-error, #ef4444);margin-left:.25rem}.qaid-q-description{font-size:.875em;color:var(--qaid-q-muted-fg);margin:0;line-height:1.4}.qaid-q-error{font-size:.8125em;color:var(--qaid-q-error, #ef4444);margin:0}.qaid-q-error:empty{display:none}.qaid-q-input,.qaid-q-textarea{width:100%;padding:var(--qaid-q-input-padding);border:1px solid var(--qaid-q-input-border);border-radius:var(--qaid-q-input-radius);font-family:inherit;font-size:1em;background:var(--qaid-q-input-bg);color:var(--qaid-q-input-fg);transition:border-color .15s,box-shadow .15s;-webkit-appearance:none;appearance:none}.qaid-q-textarea{min-height:7rem;resize:vertical;font-family:inherit}.qaid-q-input:focus,.qaid-q-textarea:focus{outline:none;border-color:var(--qaid-q-focus, #6366f1);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-q-focus, #6366f1) 20%,transparent)}.qaid-q-input::placeholder,.qaid-q-textarea::placeholder{color:var(--qaid-q-input-placeholder)}.qaid-q-currency{position:relative}.qaid-q-currency-prefix{position:absolute;left:.875rem;top:50%;transform:translateY(-50%);color:var(--qaid-q-muted-fg);font-size:1em;font-weight:500;pointer-events:none}.qaid-q-currency .qaid-q-input{padding-left:2.25rem}.qaid-q-range-wrap{display:flex;flex-direction:column;gap:.5rem;padding:.5rem 0}.qaid-q-range-value{font-size:2em;font-weight:700;text-align:center;font-variant-numeric:tabular-nums;color:var(--qaid-q-accent, #10b981)}.qaid-q-range-value .qaid-q-range-unit{font-size:.5em;font-weight:500;color:var(--qaid-q-muted-fg);margin-left:.25rem}.qaid-q-range{width:100%;-webkit-appearance:none;appearance:none;height:6px;border-radius:9999px;background:var(--qaid-q-progress-track);outline:none}.qaid-q-range::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:22px;height:22px;border-radius:50%;background:var(--qaid-q-accent, #10b981);border:3px solid var(--qaid-q-card-bg);box-shadow:0 2px 6px #0003;cursor:pointer;transition:transform .1s}.qaid-q-range::-moz-range-thumb{width:22px;height:22px;border-radius:50%;background:var(--qaid-q-accent, #10b981);border:3px solid var(--qaid-q-card-bg);box-shadow:0 2px 6px #0003;cursor:pointer}.qaid-q-range:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 6px color-mix(in srgb,var(--qaid-q-focus, #6366f1) 30%,transparent)}.qaid-q-range:focus-visible::-moz-range-thumb{box-shadow:0 0 0 6px color-mix(in srgb,var(--qaid-q-focus, #6366f1) 30%,transparent)}.qaid-q-range-bounds{display:flex;justify-content:space-between;font-size:.8125em;color:var(--qaid-q-muted-fg);font-variant-numeric:tabular-nums}.qaid-q-options{display:flex;flex-direction:column;gap:.5rem}.qaid-q-option{display:flex;align-items:flex-start;gap:.625rem;padding:var(--qaid-q-option-padding);border:1px solid var(--qaid-q-option-border);border-radius:var(--qaid-q-option-radius);background:var(--qaid-q-option-bg);text-align:left;font-size:1em;color:var(--qaid-q-option-fg);cursor:pointer;transition:border-color .12s,background .12s,box-shadow .12s;-webkit-appearance:none;appearance:none;width:100%}.qaid-q-option:hover{border-color:var(--qaid-q-option-border-hover);background:var(--qaid-q-option-bg-hover)}.qaid-q-option:focus-visible{outline:none;border-color:var(--qaid-q-focus, #6366f1);box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-q-focus, #6366f1) 25%,transparent)}.qaid-q-option.qaid-q-selected{border-color:var(--qaid-q-option-border-selected);background:var(--qaid-q-option-bg-selected)}.qaid-q-option-marker{flex-shrink:0;width:1.25rem;height:1.25rem;border:2px solid var(--qaid-q-marker-border);border-radius:var(--qaid-q-marker-radius);display:inline-flex;align-items:center;justify-content:center;margin-top:.125rem;background:var(--qaid-q-marker-bg);transition:border-color .12s,background .12s}.qaid-q-option.qaid-q-multi .qaid-q-option-marker{border-radius:.25rem}.qaid-q-option.qaid-q-selected .qaid-q-option-marker{border-color:var(--qaid-q-marker-bg-selected);background:var(--qaid-q-marker-bg-selected)}.qaid-q-option.qaid-q-selected .qaid-q-option-marker:after{content:"";display:block;width:.5rem;height:.5rem;border-radius:50%;background:var(--qaid-q-marker-icon)}.qaid-q-option.qaid-q-multi.qaid-q-selected .qaid-q-option-marker:after{content:"";display:block;width:70%;height:70%;border-radius:0;background:var(--qaid-q-marker-icon);-webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='none' stroke='black' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round' d='M5 12l4 4L19 7'/></svg>");mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='none' stroke='black' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round' d='M5 12l4 4L19 7'/></svg>");-webkit-mask-size:contain;mask-size:contain;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;transform:none}.qaid-q-option-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:.125rem}.qaid-q-option-image{display:block;width:48px;height:48px;aspect-ratio:1 / 1;object-fit:cover;border-radius:.375rem;background:var(--qaid-q-progress-track);flex-shrink:0}.qaid-q-options--image-horizontal .qaid-q-option-body{flex-direction:row;align-items:center;gap:.75rem}.qaid-q-options--image-horizontal .qaid-q-option-body>:not(.qaid-q-option-image){flex:1;min-width:0;display:flex;flex-direction:column;gap:.125rem}.qaid-q-options--image-vertical{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:.5rem}.qaid-q-options--image-vertical .qaid-q-option{flex-direction:column;align-items:stretch;text-align:center;padding:.75rem;gap:.5rem}.qaid-q-options--image-vertical .qaid-q-option-body{align-items:center;text-align:center}.qaid-q-options--image-vertical .qaid-q-option-image{width:100%;height:auto;max-width:100%}.qaid-q-options--image-vertical .qaid-q-option-marker{position:absolute;top:.5rem;right:.5rem;margin-top:0}.qaid-q-options--image-vertical .qaid-q-option{position:relative}.qaid-q-options--image-vertical .qaid-q-option-key{position:absolute;top:.5rem;left:.5rem;align-self:auto}.qaid-q-option-label{font-weight:500;line-height:1.3}.qaid-q-option-desc{font-size:.8125em;color:var(--qaid-q-muted-fg);line-height:1.4}.qaid-q-option-key{flex-shrink:0;align-self:center;font-size:.7em;font-weight:600;padding:.125rem .375rem;border-radius:.25rem;background:var(--qaid-q-progress-track);color:var(--qaid-q-muted-fg);font-variant-numeric:tabular-nums}.qaid-q-footer{display:flex;align-items:center;justify-content:space-between;gap:.5rem;margin-top:var(--qaid-q-section-gap)}.qaid-q-footer--inline-progress{justify-content:flex-start;gap:.75rem}.qaid-q-footer-left,.qaid-q-footer-right{display:flex;gap:.5rem}.qaid-q-btn{padding:var(--qaid-q-btn-padding-y) var(--qaid-q-btn-padding-x);border-radius:var(--qaid-q-btn-radius);font-size:var(--qaid-q-btn-font-size, .9375em);font-weight:var(--qaid-q-btn-font-weight);border:1px solid transparent;cursor:pointer;transition:filter .15s,background .15s,color .15s;-webkit-appearance:none;appearance:none}.qaid-q-btn:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--qaid-q-focus, #6366f1) 30%,transparent)}.qaid-q-btn-secondary{background:var(--qaid-q-btn-secondary-bg);border-color:var(--qaid-q-btn-secondary-border);color:var(--qaid-q-btn-secondary-fg)}.qaid-q-btn-secondary:hover{background:var(--qaid-q-btn-secondary-hover-bg)}.qaid-q-btn-primary{background:var(--qaid-q-btn-primary-bg);color:var(--qaid-q-btn-primary-fg);border-color:var(--qaid-q-btn-primary-border)}.qaid-q-btn-primary:hover{filter:brightness(.9)}.qaid-q-btn-primary:disabled{opacity:.5;cursor:not-allowed;filter:none}.qaid-q-done{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:.5rem;padding:1.5rem 0;flex:1;min-height:0}.qaid-q-done-icon{width:48px;height:48px;border-radius:50%;background:color-mix(in srgb,var(--qaid-q-accent, #10b981) 18%,transparent);color:var(--qaid-q-accent, #10b981);display:inline-flex;align-items:center;justify-content:center;margin-bottom:.5rem}.qaid-q-done-title{font-size:1.25em;font-weight:700;margin:0}.qaid-q-done-message{color:var(--qaid-q-muted-fg);margin:0}.qaid-q-saving{display:inline-flex;align-items:center;gap:.375rem;font-size:.75em;color:var(--qaid-q-muted-fg);opacity:0;transition:opacity .2s}.qaid-q-saving.qaid-q-visible{opacity:1}.qaid-q-saving-dot{width:6px;height:6px;border-radius:50%;background:var(--qaid-q-accent, #10b981);animation:qaid-q-pulse 1.2s ease-in-out infinite}@keyframes qaid-q-pulse{0%,to{opacity:.3}50%{opacity:1}}:where(.qaid-q-root.qaid-q-unstyled) :where(.qaid-q-card,.qaid-q-header,.qaid-q-title,.qaid-q-description,.qaid-q-step,.qaid-q-label,.qaid-q-options,.qaid-q-option,.qaid-q-option-marker,.qaid-q-option-body,.qaid-q-option-label,.qaid-q-option-desc,.qaid-q-input,.qaid-q-textarea,.qaid-q-currency,.qaid-q-currency-prefix,.qaid-q-range,.qaid-q-range-wrap,.qaid-q-range-value,.qaid-q-btn,.qaid-q-footer,.qaid-q-progress,.qaid-q-progress-fill,.qaid-q-step-counter,.qaid-q-error,.qaid-q-saving,.qaid-q-done,.qaid-q-done-icon,.qaid-q-done-title,.qaid-q-done-message){all:unset;display:revert;box-sizing:border-box}`;
2
+ const S = ":where(.qaid-q-root){--qaid-q-card-radius: 0;--qaid-q-card-shadow: none;--qaid-q-btn-radius: 0;--qaid-q-option-radius: 0;--qaid-q-option-bg-selected: transparent;--qaid-q-input-radius: 0}", A = ":where(.qaid-q-root){--qaid-q-card-radius: 1.5rem;--qaid-q-btn-radius: 9999px;--qaid-q-btn-padding-x: 1.5rem;--qaid-q-option-radius: 9999px;--qaid-q-option-padding: .75rem 1.125rem;--qaid-q-input-radius: 9999px;--qaid-q-input-padding: .75rem 1.125rem}", I = ":where(.qaid-q-root){--qaid-q-card-padding: 1rem;--qaid-q-btn-padding-y: .5rem;--qaid-q-btn-padding-x: .875rem;--qaid-q-option-padding: .5rem .625rem;--qaid-q-input-padding: .5rem .625rem;--qaid-q-gap: .5rem;--qaid-q-section-gap: .875rem}", N = {
3
+ default: "",
4
+ minimal: S,
5
+ pill: A,
6
+ dense: I
7
+ };
8
+ function L(t) {
9
+ return N[t] ?? "";
10
+ }
11
+ function T(t, e, i) {
12
+ const [n, a, o] = [t, e, i].map((r) => (r = r / 255, r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4)));
13
+ return 0.2126 * n + 0.7152 * a + 0.0722 * o;
5
14
  }
6
- function C(t) {
15
+ function z(t) {
7
16
  if (t.startsWith("#")) {
8
- const i = t.slice(1), a = i.length === 3 ? i.split("").map((s) => s + s).join("") : i, n = parseInt(a, 16);
9
- return { r: n >> 16 & 255, g: n >> 8 & 255, b: n & 255 };
17
+ const i = t.slice(1), n = i.length === 3 ? i.split("").map((o) => o + o).join("") : i, a = parseInt(n, 16);
18
+ return { r: a >> 16 & 255, g: a >> 8 & 255, b: a & 255 };
10
19
  }
11
20
  const e = t.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
12
21
  return e ? { r: parseInt(e[1]), g: parseInt(e[2]), b: parseInt(e[3]) } : null;
13
22
  }
14
- function y(t) {
15
- const e = C(t);
16
- return e && w(e.r, e.g, e.b) > 0.4 ? "black" : "white";
23
+ function x(t) {
24
+ const e = z(t);
25
+ return e && T(e.r, e.g, e.b) > 0.4 ? "black" : "white";
17
26
  }
18
- function S(t = {}) {
19
- const {
20
- positiveColor: e = "#10b981",
21
- negativeColor: i = "#ef4444",
22
- markerColor: a = "#6366f1",
23
- modalWidth: n = 480,
24
- backdropOpacity: s = 0.4,
25
- fontFamily: r = "system-ui, -apple-system, sans-serif",
26
- fontSize: p = 16
27
- } = t;
28
- return {
29
- "--qaid-positive": e,
30
- "--qaid-positive-text": y(e),
31
- "--qaid-negative": i,
32
- "--qaid-marker": a,
33
- "--qaid-marker-text": y(a),
34
- "--qaid-modal-width": `${n}px`,
35
- "--qaid-backdrop-opacity": String(s),
36
- "--qaid-font-family": r,
37
- "--qaid-font-size": `${p}px`
38
- };
27
+ function V(t = {}) {
28
+ const e = {};
29
+ return t.accentColor !== void 0 && (e["--qaid-q-accent"] = t.accentColor, e["--qaid-q-accent-text"] = x(t.accentColor)), t.errorColor !== void 0 && (e["--qaid-q-error"] = t.errorColor), t.focusColor !== void 0 && (e["--qaid-q-focus"] = t.focusColor, e["--qaid-q-focus-text"] = x(t.focusColor)), t.modalWidth !== void 0 && (e["--qaid-modal-width"] = `${t.modalWidth}px`), t.backdropOpacity !== void 0 && (e["--qaid-backdrop-opacity"] = String(t.backdropOpacity)), t.fontFamily !== void 0 && (e["--qaid-font-family"] = t.fontFamily), t.fontSize !== void 0 && (e["--qaid-font-size"] = `${t.fontSize}px`), e;
30
+ }
31
+ function P(t, e) {
32
+ for (const [i, n] of Object.entries(e))
33
+ t.style.setProperty(i, n);
39
34
  }
40
- function N(t, e) {
41
- for (const [i, a] of Object.entries(e))
42
- t.style.setProperty(i, a);
35
+ function D() {
36
+ return C;
43
37
  }
44
- function A() {
45
- return k;
38
+ function O(t) {
39
+ return L(t);
46
40
  }
47
- function I(t) {
41
+ function H(t) {
48
42
  switch (t.question.type) {
49
43
  case "text":
50
- return L(t.question, t);
44
+ return j(t.question, t);
51
45
  case "currency":
52
- return V(t.question, t);
46
+ return R(t.question, t);
53
47
  case "range":
54
- return D(t.question, t);
48
+ return Q(t.question, t);
55
49
  case "date":
56
- return H(t.question, t);
50
+ return $(t.question, t);
57
51
  case "multiple-choice":
58
- return O(t.question, t);
52
+ return M(t.question, t);
59
53
  }
60
54
  }
61
- function L(t, e) {
55
+ function j(t, e) {
62
56
  const i = typeof e.initialValue == "string" ? e.initialValue : "";
63
- let a;
57
+ let n;
64
58
  if (t.multiline) {
65
- const n = document.createElement("textarea");
66
- n.className = "qaid-q-textarea", n.value = i, t.placeholder && (n.placeholder = t.placeholder), t.maxLength && (n.maxLength = t.maxLength), a = n;
59
+ const a = document.createElement("textarea");
60
+ a.className = "qaid-q-textarea", a.value = i, t.placeholder && (a.placeholder = t.placeholder), t.maxLength && (a.maxLength = t.maxLength), n = a;
67
61
  } else {
68
- const n = document.createElement("input");
69
- n.className = "qaid-q-input", n.type = t.inputType ?? "text", n.value = i, t.placeholder && (n.placeholder = t.placeholder), t.maxLength && (n.maxLength = t.maxLength), n.setAttribute("autocomplete", z(t.inputType)), a = n;
62
+ const a = document.createElement("input");
63
+ a.className = "qaid-q-input", a.type = t.inputType ?? "text", a.value = i, t.placeholder && (a.placeholder = t.placeholder), t.maxLength && (a.maxLength = t.maxLength), a.setAttribute("autocomplete", U(t.inputType)), n = a;
70
64
  }
71
- return a.setAttribute("aria-label", t.label), a.addEventListener("input", () => {
72
- e.onChange(a.value);
73
- }), a.addEventListener("keydown", ((n) => {
74
- if (n.key === "Enter") {
65
+ return n.setAttribute("aria-label", t.label), n.addEventListener("input", () => {
66
+ e.onChange(n.value);
67
+ }), n.addEventListener("keydown", ((a) => {
68
+ if (a.key === "Enter") {
75
69
  if (t.multiline) {
76
- (n.metaKey || n.ctrlKey) && (n.preventDefault(), e.onSubmit());
70
+ (a.metaKey || a.ctrlKey) && (a.preventDefault(), e.onSubmit());
77
71
  return;
78
72
  }
79
- n.isComposing || (n.preventDefault(), e.onSubmit());
73
+ a.isComposing || (a.preventDefault(), e.onSubmit());
80
74
  }
81
75
  })), {
82
- element: a,
76
+ element: n,
83
77
  focus: () => {
84
- a.focus();
85
- const n = a.value.length;
78
+ n.focus();
79
+ const a = n.value.length;
86
80
  try {
87
- a.setSelectionRange(n, n);
81
+ n.setSelectionRange(a, a);
88
82
  } catch {
89
83
  }
90
84
  },
91
- getValue: () => a.value,
85
+ getValue: () => n.value,
92
86
  isValid: () => {
93
87
  if (!t.required) return !0;
94
- const n = a.value.trim();
95
- return !(n.length === 0 || t.minLength && n.length < t.minLength);
88
+ const a = n.value.trim();
89
+ return !(a.length === 0 || t.minLength && a.length < t.minLength);
96
90
  }
97
91
  };
98
92
  }
99
- function z(t) {
93
+ function U(t) {
100
94
  switch (t) {
101
95
  case "email":
102
96
  return "email";
@@ -108,86 +102,86 @@ function z(t) {
108
102
  return "off";
109
103
  }
110
104
  }
111
- function V(t, e) {
105
+ function R(t, e) {
112
106
  const i = document.createElement("div");
113
107
  i.className = "qaid-q-currency";
114
- const a = document.createElement("span");
115
- a.className = "qaid-q-currency-prefix", a.textContent = T(t.currency ?? "USD", t.locale), i.appendChild(a);
116
- const n = document.createElement("input");
117
- return n.className = "qaid-q-input", n.type = "number", n.inputMode = "decimal", n.step = "0.01", typeof t.min == "number" && (n.min = String(t.min)), typeof t.max == "number" && (n.max = String(t.max)), t.placeholder && (n.placeholder = t.placeholder), typeof e.initialValue == "number" ? n.value = String(e.initialValue) : typeof e.initialValue == "string" && e.initialValue !== "" && (n.value = e.initialValue), n.setAttribute("aria-label", t.label), n.addEventListener("input", () => {
118
- const s = n.value;
119
- if (s === "")
108
+ const n = document.createElement("span");
109
+ n.className = "qaid-q-currency-prefix", n.textContent = F(t.currency ?? "USD", t.locale), i.appendChild(n);
110
+ const a = document.createElement("input");
111
+ return a.className = "qaid-q-input", a.type = "number", a.inputMode = "decimal", a.step = "0.01", typeof t.min == "number" && (a.min = String(t.min)), typeof t.max == "number" && (a.max = String(t.max)), t.placeholder && (a.placeholder = t.placeholder), typeof e.initialValue == "number" ? a.value = String(e.initialValue) : typeof e.initialValue == "string" && e.initialValue !== "" && (a.value = e.initialValue), a.setAttribute("aria-label", t.label), a.addEventListener("input", () => {
112
+ const o = a.value;
113
+ if (o === "")
120
114
  e.onChange(null);
121
115
  else {
122
- const r = Number(s);
116
+ const r = Number(o);
123
117
  e.onChange(Number.isNaN(r) ? null : r);
124
118
  }
125
- }), n.addEventListener("keydown", (s) => {
126
- s.key === "Enter" && !s.isComposing && (s.preventDefault(), e.onSubmit());
127
- }), i.appendChild(n), {
119
+ }), a.addEventListener("keydown", (o) => {
120
+ o.key === "Enter" && !o.isComposing && (o.preventDefault(), e.onSubmit());
121
+ }), i.appendChild(a), {
128
122
  element: i,
129
- focus: () => n.focus(),
123
+ focus: () => a.focus(),
130
124
  getValue: () => {
131
- if (n.value === "") return null;
132
- const s = Number(n.value);
133
- return Number.isNaN(s) ? null : s;
125
+ if (a.value === "") return null;
126
+ const o = Number(a.value);
127
+ return Number.isNaN(o) ? null : o;
134
128
  },
135
129
  isValid: () => {
136
- const s = n.value === "" ? null : Number(n.value);
137
- return !(t.required && (s === null || Number.isNaN(s)) || s !== null && !Number.isNaN(s) && (typeof t.min == "number" && s < t.min || typeof t.max == "number" && s > t.max));
130
+ const o = a.value === "" ? null : Number(a.value);
131
+ return !(t.required && (o === null || Number.isNaN(o)) || o !== null && !Number.isNaN(o) && (typeof t.min == "number" && o < t.min || typeof t.max == "number" && o > t.max));
138
132
  }
139
133
  };
140
134
  }
141
- function T(t, e) {
135
+ function F(t, e) {
142
136
  try {
143
137
  return new Intl.NumberFormat(e, {
144
138
  style: "currency",
145
139
  currency: t,
146
140
  currencyDisplay: "narrowSymbol",
147
141
  maximumFractionDigits: 0
148
- }).formatToParts(0).find((s) => s.type === "currency")?.value ?? t;
142
+ }).formatToParts(0).find((o) => o.type === "currency")?.value ?? t;
149
143
  } catch {
150
144
  return t;
151
145
  }
152
146
  }
153
- function D(t, e) {
147
+ function Q(t, e) {
154
148
  const i = document.createElement("div");
155
149
  i.className = "qaid-q-range-wrap";
156
- const a = document.createElement("div");
157
- a.className = "qaid-q-range-value";
158
- const n = document.createElement("span");
159
- if (a.appendChild(n), t.unit) {
160
- const o = document.createElement("span");
161
- o.className = "qaid-q-range-unit", o.textContent = t.unit, a.appendChild(o);
162
- }
163
- const s = typeof e.initialValue == "number" ? e.initialValue : t.defaultValue ?? t.min, r = document.createElement("input");
164
- r.className = "qaid-q-range", r.type = "range", r.min = String(t.min), r.max = String(t.max), r.step = String(t.step ?? 1), r.value = String(s), r.setAttribute("aria-label", t.label), r.setAttribute("aria-valuemin", String(t.min)), r.setAttribute("aria-valuemax", String(t.max));
165
- const p = () => {
166
- n.textContent = r.value, r.setAttribute("aria-valuenow", r.value);
150
+ const n = document.createElement("div");
151
+ n.className = "qaid-q-range-value";
152
+ const a = document.createElement("span");
153
+ if (n.appendChild(a), t.unit) {
154
+ const s = document.createElement("span");
155
+ s.className = "qaid-q-range-unit", s.textContent = t.unit, n.appendChild(s);
156
+ }
157
+ const o = typeof e.initialValue == "number" ? e.initialValue : t.defaultValue ?? t.min, r = document.createElement("input");
158
+ r.className = "qaid-q-range", r.type = "range", r.min = String(t.min), r.max = String(t.max), r.step = String(t.step ?? 1), r.value = String(o), r.setAttribute("aria-label", t.label), r.setAttribute("aria-valuemin", String(t.min)), r.setAttribute("aria-valuemax", String(t.max));
159
+ const q = () => {
160
+ a.textContent = r.value, r.setAttribute("aria-valuenow", r.value);
167
161
  };
168
- p(), r.addEventListener("input", () => {
169
- p(), e.onChange(Number(r.value));
170
- }), r.addEventListener("keydown", (o) => {
171
- o.key === "Enter" && (o.preventDefault(), e.onSubmit());
162
+ q(), r.addEventListener("input", () => {
163
+ q(), e.onChange(Number(r.value));
164
+ }), r.addEventListener("keydown", (s) => {
165
+ s.key === "Enter" && (s.preventDefault(), e.onSubmit());
172
166
  });
173
167
  const h = document.createElement("div");
174
168
  h.className = "qaid-q-range-bounds";
175
- const f = document.createElement("span");
176
- f.textContent = `${t.min}${t.unit ?? ""}`;
177
169
  const m = document.createElement("span");
178
- return m.textContent = `${t.max}${t.unit ?? ""}`, h.appendChild(f), h.appendChild(m), i.appendChild(a), i.appendChild(r), i.appendChild(h), queueMicrotask(() => e.onChange(Number(r.value))), {
170
+ m.textContent = `${t.min}${t.unit ?? ""}`;
171
+ const f = document.createElement("span");
172
+ return f.textContent = `${t.max}${t.unit ?? ""}`, h.appendChild(m), h.appendChild(f), i.appendChild(n), i.appendChild(r), i.appendChild(h), queueMicrotask(() => e.onChange(Number(r.value))), {
179
173
  element: i,
180
174
  focus: () => r.focus(),
181
175
  getValue: () => Number(r.value),
182
176
  isValid: () => !0
183
177
  };
184
178
  }
185
- function H(t, e) {
179
+ function $(t, e) {
186
180
  const i = document.createElement("input");
187
181
  return i.className = "qaid-q-input", i.type = "date", t.min && (i.min = t.min), t.max && (i.max = t.max), typeof e.initialValue == "string" && (i.value = e.initialValue), i.setAttribute("aria-label", t.label), i.addEventListener("input", () => {
188
182
  e.onChange(i.value || null);
189
- }), i.addEventListener("keydown", (a) => {
190
- a.key === "Enter" && !a.isComposing && (a.preventDefault(), e.onSubmit());
183
+ }), i.addEventListener("keydown", (n) => {
184
+ n.key === "Enter" && !n.isComposing && (n.preventDefault(), e.onSubmit());
191
185
  }), {
192
186
  element: i,
193
187
  focus: () => i.focus(),
@@ -195,108 +189,108 @@ function H(t, e) {
195
189
  isValid: () => t.required ? i.value !== "" : !0
196
190
  };
197
191
  }
198
- function O(t, e) {
199
- const i = document.createElement("div"), a = t.imageAlignment ?? "horizontal", s = t.options.some((o) => !!o.image) ? a === "vertical" ? " qaid-q-options--image-vertical" : " qaid-q-options--image-horizontal" : "";
200
- i.className = `qaid-q-options${s}`, i.setAttribute("role", t.multiple ? "group" : "radiogroup"), i.setAttribute("aria-label", t.label);
192
+ function M(t, e) {
193
+ const i = document.createElement("div"), n = t.imageAlignment ?? "horizontal", o = t.options.some((s) => !!s.image) ? n === "vertical" ? " qaid-q-options--image-vertical" : " qaid-q-options--image-horizontal" : "";
194
+ i.className = `qaid-q-options${o}`, i.setAttribute("role", t.multiple ? "group" : "radiogroup"), i.setAttribute("aria-label", t.label);
201
195
  const r = /* @__PURE__ */ new Set();
202
196
  if (t.multiple && Array.isArray(e.initialValue))
203
- for (const o of e.initialValue) r.add(o);
197
+ for (const s of e.initialValue) r.add(s);
204
198
  else !t.multiple && typeof e.initialValue == "string" && r.add(e.initialValue);
205
- const p = [];
206
- t.options.forEach((o, c) => {
207
- const u = document.createElement("button");
208
- u.type = "button", u.className = `qaid-q-option${t.multiple ? " qaid-q-multi" : ""}`, u.dataset.value = o.value, u.setAttribute("role", t.multiple ? "checkbox" : "radio"), u.setAttribute("aria-checked", r.has(o.value) ? "true" : "false"), r.has(o.value) && u.classList.add("qaid-q-selected");
199
+ const q = [];
200
+ t.options.forEach((s, c) => {
201
+ const d = document.createElement("button");
202
+ d.type = "button", d.className = `qaid-q-option${t.multiple ? " qaid-q-multi" : ""}`, d.dataset.value = s.value, d.setAttribute("role", t.multiple ? "checkbox" : "radio"), d.setAttribute("aria-checked", r.has(s.value) ? "true" : "false"), r.has(s.value) && d.classList.add("qaid-q-selected");
203
+ const p = document.createElement("span");
204
+ p.className = "qaid-q-option-marker", p.setAttribute("aria-hidden", "true");
209
205
  const g = document.createElement("span");
210
- g.className = "qaid-q-option-marker", g.setAttribute("aria-hidden", "true");
211
- const l = document.createElement("span");
212
- if (l.className = "qaid-q-option-body", o.image) {
213
- const d = document.createElement("img");
214
- d.className = "qaid-q-option-image", d.src = o.image, d.alt = "", d.loading = "lazy", d.decoding = "async", l.appendChild(d);
206
+ if (g.className = "qaid-q-option-body", s.image) {
207
+ const l = document.createElement("img");
208
+ l.className = "qaid-q-option-image", l.src = s.image, l.alt = "", l.loading = "lazy", l.decoding = "async", g.appendChild(l);
215
209
  }
216
- const b = document.createElement("span");
217
- if (b.className = "qaid-q-option-label", b.textContent = o.label, l.appendChild(b), o.description) {
218
- const d = document.createElement("span");
219
- d.className = "qaid-q-option-desc", d.textContent = o.description, l.appendChild(d);
210
+ const u = document.createElement("span");
211
+ if (u.className = "qaid-q-option-label", u.textContent = s.label, g.appendChild(u), s.description) {
212
+ const l = document.createElement("span");
213
+ l.className = "qaid-q-option-desc", l.textContent = s.description, g.appendChild(l);
220
214
  }
221
- if (u.appendChild(g), u.appendChild(l), c < 9) {
222
- const d = document.createElement("span");
223
- d.className = "qaid-q-option-key", d.textContent = String(c + 1), d.setAttribute("aria-hidden", "true"), u.appendChild(d);
215
+ if (d.appendChild(p), d.appendChild(g), c < 9) {
216
+ const l = document.createElement("span");
217
+ l.className = "qaid-q-option-key", l.textContent = String(c + 1), l.setAttribute("aria-hidden", "true"), d.appendChild(l);
224
218
  }
225
- u.addEventListener("click", () => f(c)), u.addEventListener("keydown", (d) => {
226
- if (d.key === "ArrowDown" || d.key === "ArrowRight") {
227
- d.preventDefault(), h((c + 1) % p.length);
219
+ d.addEventListener("click", () => m(c)), d.addEventListener("keydown", (l) => {
220
+ if (l.key === "ArrowDown" || l.key === "ArrowRight") {
221
+ l.preventDefault(), h((c + 1) % q.length);
228
222
  return;
229
223
  }
230
- if (d.key === "ArrowUp" || d.key === "ArrowLeft") {
231
- d.preventDefault(), h((c - 1 + p.length) % p.length);
224
+ if (l.key === "ArrowUp" || l.key === "ArrowLeft") {
225
+ l.preventDefault(), h((c - 1 + q.length) % q.length);
232
226
  return;
233
227
  }
234
- !t.multiple && d.key === "Enter" && r.size > 0 && (d.preventDefault(), e.onSubmit());
235
- }), p.push(u), i.appendChild(u);
236
- }), i.addEventListener("keydown", (o) => {
237
- const c = o.key;
228
+ !t.multiple && l.key === "Enter" && r.size > 0 && (l.preventDefault(), e.onSubmit());
229
+ }), q.push(d), i.appendChild(d);
230
+ }), i.addEventListener("keydown", (s) => {
231
+ const c = s.key;
238
232
  if (c.length === 1 && c >= "1" && c <= "9") {
239
- const u = parseInt(c, 10) - 1;
240
- u < p.length && (o.preventDefault(), f(u), h(u));
233
+ const d = parseInt(c, 10) - 1;
234
+ d < q.length && (s.preventDefault(), m(d), h(d));
241
235
  }
242
236
  });
243
- function h(o) {
244
- p[o]?.focus();
237
+ function h(s) {
238
+ q[s]?.focus();
245
239
  }
246
- function f(o) {
247
- const c = t.options[o].value;
248
- t.multiple ? r.has(c) ? r.delete(c) : r.add(c) : (r.clear(), r.add(c)), p.forEach((u) => {
249
- const g = u.dataset.value, l = r.has(g);
250
- u.classList.toggle("qaid-q-selected", l), u.setAttribute("aria-checked", l ? "true" : "false");
251
- }), e.onChange(m()), !t.multiple && e.autoAdvance && setTimeout(() => e.onAutoAdvance(), 180);
240
+ function m(s) {
241
+ const c = t.options[s].value;
242
+ t.multiple ? r.has(c) ? r.delete(c) : r.add(c) : (r.clear(), r.add(c)), q.forEach((d) => {
243
+ const p = d.dataset.value, g = r.has(p);
244
+ d.classList.toggle("qaid-q-selected", g), d.setAttribute("aria-checked", g ? "true" : "false");
245
+ }), e.onChange(f()), !t.multiple && e.autoAdvance && setTimeout(() => e.onAutoAdvance(), 180);
252
246
  }
253
- function m() {
247
+ function f() {
254
248
  if (t.multiple) return Array.from(r);
255
- const o = r.values().next();
256
- return o.done ? null : o.value;
249
+ const s = r.values().next();
250
+ return s.done ? null : s.value;
257
251
  }
258
252
  return {
259
253
  element: i,
260
254
  focus: () => {
261
- (p.find((c) => c.classList.contains("qaid-q-selected")) ?? p[0])?.focus();
255
+ (q.find((c) => c.classList.contains("qaid-q-selected")) ?? q[0])?.focus();
262
256
  },
263
- getValue: () => m(),
257
+ getValue: () => f(),
264
258
  isValid: () => t.required ? r.size > 0 : !0
265
259
  };
266
260
  }
267
- function F(t, e) {
261
+ function K(t, e) {
268
262
  return t.questions.filter(
269
263
  (i) => i.visibleIf ? v(i.visibleIf, e) : !0
270
264
  );
271
265
  }
272
266
  function v(t, e) {
273
267
  if ("allOf" in t) {
274
- for (const n of t.allOf)
275
- if (!v(n, e)) return !1;
268
+ for (const a of t.allOf)
269
+ if (!v(a, e)) return !1;
276
270
  return !0;
277
271
  }
278
272
  if ("anyOf" in t) {
279
- for (const n of t.anyOf)
280
- if (v(n, e)) return !0;
273
+ for (const a of t.anyOf)
274
+ if (v(a, e)) return !0;
281
275
  return !1;
282
276
  }
283
- const i = e[t.questionId], a = i != null && !(typeof i == "string" && i.trim() === "") && !(Array.isArray(i) && i.length === 0);
284
- return "answered" in t ? t.answered ? a : !a : a ? "equals" in t ? q(i, t.equals) : "notEquals" in t ? !q(i, t.notEquals) : "in" in t ? t.in.some((n) => q(i, n)) : !1 : !1;
277
+ const i = e[t.questionId], n = i != null && !(typeof i == "string" && i.trim() === "") && !(Array.isArray(i) && i.length === 0);
278
+ return "answered" in t ? t.answered ? n : !n : n ? "equals" in t ? b(i, t.equals) : "notEquals" in t ? !b(i, t.notEquals) : "in" in t ? t.in.some((a) => b(i, a)) : !1 : !1;
285
279
  }
286
- function q(t, e) {
280
+ function b(t, e) {
287
281
  return Array.isArray(t) ? t.some((i) => i === e) : t === e;
288
282
  }
289
- const x = "qaid_visitor_id";
290
- function P() {
283
+ const E = "qaid_visitor_id";
284
+ function B() {
291
285
  try {
292
- let t = localStorage.getItem(x);
293
- return t || (t = crypto.randomUUID(), localStorage.setItem(x, t)), t;
286
+ let t = localStorage.getItem(E);
287
+ return t || (t = crypto.randomUUID(), localStorage.setItem(E, t)), t;
294
288
  } catch {
295
289
  return crypto.randomUUID();
296
290
  }
297
291
  }
298
- const Q = '<svg width="14" height="14" viewBox="0 0 14 14" aria-hidden="true"><path d="M2 2l10 10M12 2L2 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none"/></svg>', U = '<svg width="24" height="24" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12l4 4L19 7" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg>';
299
- class j {
292
+ const W = '<svg width="14" height="14" viewBox="0 0 14 14" aria-hidden="true"><path d="M2 2l10 10M12 2L2 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none"/></svg>', Y = '<svg width="24" height="24" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12l4 4L19 7" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg>';
293
+ class G {
300
294
  config;
301
295
  questionnaire = null;
302
296
  inlineQuestionnaire;
@@ -342,16 +336,32 @@ class j {
342
336
  currentInput = null;
343
337
  boundKeyDown;
344
338
  cssVars = {};
339
+ // Track which theme-related fields the host explicitly set so the
340
+ // theme document can fill the rest. A `themeUrl` / `themeDocument`
341
+ // theme is layered between the embed's defaults and the host's
342
+ // explicit overrides, so the host always wins.
343
+ hostThemeOverrides;
344
+ // Raw, host-provided values for the tokens we inline as inline-style
345
+ // CSS vars on rootEl. Anything `undefined` here is left out of the
346
+ // inline write so theme tokens (which arrive as `:where(...) { ... }`
347
+ // rules) can win the cascade.
348
+ hostInlineVars;
349
+ themeUrl;
350
+ themeDocument;
351
+ hostCss;
345
352
  constructor(e) {
346
353
  this.config = {
347
354
  endpoint: e.endpoint,
348
355
  apiKey: e.apiKey ?? "",
349
356
  container: e.container ?? "",
350
357
  zIndex: e.zIndex ?? 50,
358
+ // Prefer the new quest-only keys; fall back to the deprecated
359
+ // thumbs-style keys (positive/negative/marker) so existing
360
+ // integrations keep rendering until they migrate.
351
361
  colors: {
352
- positive: e.colors?.positive ?? "#10b981",
353
- negative: e.colors?.negative ?? "#ef4444",
354
- marker: e.colors?.marker ?? "#6366f1"
362
+ accent: e.colors?.accent ?? e.colors?.positive ?? "#10b981",
363
+ error: e.colors?.error ?? e.colors?.negative ?? "#ef4444",
364
+ focus: e.colors?.focus ?? e.colors?.marker ?? "#6366f1"
355
365
  },
356
366
  modalWidth: e.modalWidth ?? 480,
357
367
  backdropOpacity: e.backdropOpacity ?? 0.4,
@@ -361,28 +371,44 @@ class j {
361
371
  autoAdvance: e.autoAdvance ?? !1,
362
372
  saveDebounceMs: e.saveDebounceMs ?? 500,
363
373
  autoFocus: e.autoFocus ?? !0,
364
- progressPosition: e.progressPosition ?? "top"
365
- }, this.inlineQuestionnaire = e.questionnaire, this.configUrl = e.configUrl, this.visitorId = P(), this.boundKeyDown = this.handleKeyDown.bind(this), this.init();
374
+ animate: e.animate ?? !0,
375
+ // Don't default here — we want to fall through to the
376
+ // questionnaire's `progressPosition` when the host didn't
377
+ // explicitly set one. effectiveProgressPosition() handles the
378
+ // final fallback to "top".
379
+ progressPosition: e.progressPosition,
380
+ theme: e.theme ?? "auto",
381
+ unstyled: e.unstyled ?? !1,
382
+ preset: e.preset ?? "default"
383
+ }, this.hostThemeOverrides = {
384
+ preset: e.preset !== void 0,
385
+ mode: e.theme !== void 0,
386
+ unstyled: e.unstyled !== void 0,
387
+ css: e.css !== void 0
388
+ }, this.hostInlineVars = {
389
+ accentColor: e.colors?.accent ?? e.colors?.positive,
390
+ errorColor: e.colors?.error ?? e.colors?.negative,
391
+ focusColor: e.colors?.focus ?? e.colors?.marker,
392
+ modalWidth: e.modalWidth,
393
+ backdropOpacity: e.backdropOpacity,
394
+ fontFamily: e.fontFamily,
395
+ fontSize: e.fontSize
396
+ }, this.themeUrl = e.themeUrl, this.themeDocument = e.themeDocument, this.hostCss = e.css ?? "", this.inlineQuestionnaire = e.questionnaire, this.configUrl = e.configUrl, this.visitorId = B(), this.boundKeyDown = this.handleKeyDown.bind(this), this.init();
366
397
  }
367
398
  async init() {
368
- this.cssVars = S({
369
- positiveColor: this.config.colors.positive,
370
- negativeColor: this.config.colors.negative,
371
- markerColor: this.config.colors.marker,
372
- modalWidth: this.config.modalWidth,
373
- backdropOpacity: this.config.backdropOpacity,
374
- fontFamily: this.config.fontFamily,
375
- fontSize: this.config.fontSize
376
- }), this.mountShell(), this.renderLoading();
399
+ this.cssVars = V(this.hostInlineVars), this.mountShell(), this.renderLoading();
377
400
  try {
378
- const e = await this.loadQuestionnaire();
401
+ const [e, i] = await Promise.all([
402
+ this.loadQuestionnaire(),
403
+ this.loadTheme()
404
+ ]);
379
405
  if (!e || !e.questions || e.questions.length === 0)
380
406
  throw new Error("Questionnaire is empty");
381
- if (this.questionnaire = e, this.recomputeVisible(), this.pendingGoToStep) {
382
- const i = this.visibleQuestions.findIndex(
407
+ if (this.questionnaire = e, this.applyResolvedTheme(i), this.recomputeVisible(), this.pendingGoToStep) {
408
+ const n = this.visibleQuestions.findIndex(
383
409
  (a) => a.id === this.pendingGoToStep
384
410
  );
385
- i !== -1 && (this.stepIndex = i), this.pendingGoToStep = null;
411
+ n !== -1 && (this.stepIndex = n), this.pendingGoToStep = null;
386
412
  }
387
413
  this.createResponse(), this.state = "READY", this.renderHeader(), this.renderStep();
388
414
  } catch (e) {
@@ -390,6 +416,64 @@ class j {
390
416
  }
391
417
  }
392
418
  // ------------------------------------------------------------------
419
+ // Theme document loading + merging
420
+ // ------------------------------------------------------------------
421
+ async loadTheme() {
422
+ if (this.themeDocument) return this.themeDocument;
423
+ if (!this.themeUrl) return null;
424
+ try {
425
+ const e = await fetch(this.themeUrl, {
426
+ headers: { Accept: "application/json" }
427
+ });
428
+ return e.ok ? await e.json() : (console.warn(
429
+ `[quests-embed] theme fetch failed (${e.status}) — rendering with defaults`
430
+ ), null);
431
+ } catch (e) {
432
+ return console.warn("[quests-embed] theme fetch error — rendering with defaults", e), null;
433
+ }
434
+ }
435
+ /**
436
+ * Merge a fetched theme document into the live config, then inject
437
+ * the resulting CSS layers + class toggles into the shadow root.
438
+ *
439
+ * Precedence (highest first):
440
+ * 1. Host's explicit `QuestsConfig` fields (preset/theme/unstyled/css)
441
+ * 2. Theme document fields (preset/mode/unstyled/tokens/css)
442
+ * 3. Embed defaults
443
+ *
444
+ * CSS layer order (later wins for same-specificity rules):
445
+ * base stylesheet → theme.tokens block → preset CSS → theme.css → host css
446
+ */
447
+ applyResolvedTheme(e) {
448
+ if (!this.shadowRoot || !this.rootEl) return;
449
+ const i = this.hostThemeOverrides.preset ? this.config.preset : e?.preset ?? this.config.preset, n = this.hostThemeOverrides.mode ? this.config.theme : e?.mode ?? this.config.theme, a = this.hostThemeOverrides.unstyled ? this.config.unstyled : e?.unstyled ?? this.config.unstyled;
450
+ this.rootEl.classList.toggle(
451
+ "qaid-q-theme-light",
452
+ n === "light"
453
+ ), this.rootEl.classList.toggle(
454
+ "qaid-q-theme-dark",
455
+ n === "dark"
456
+ ), this.rootEl.classList.toggle("qaid-q-unstyled", !!a);
457
+ const o = [];
458
+ if (e?.tokens && Object.keys(e.tokens).length > 0) {
459
+ const r = Object.entries(e.tokens).filter(([, q]) => typeof q == "string" && q.trim() !== "").map(([q, h]) => ` ${q}: ${h};`).join(`
460
+ `);
461
+ r && o.push(`:where(.qaid-q-root) {
462
+ ${r}
463
+ }`);
464
+ }
465
+ if (i && i !== "default") {
466
+ const r = O(i);
467
+ r && o.push(r);
468
+ }
469
+ if (e?.css && e.css.trim() !== "" && o.push(e.css), this.hostCss && this.hostCss.trim() !== "" && o.push(this.hostCss), o.length > 0) {
470
+ const r = document.createElement("style");
471
+ r.setAttribute("data-qaid-q-theme", ""), r.textContent = o.join(`
472
+
473
+ `), this.shadowRoot.appendChild(r);
474
+ }
475
+ }
476
+ // ------------------------------------------------------------------
393
477
  // Loading the questionnaire JSON
394
478
  // ------------------------------------------------------------------
395
479
  async loadQuestionnaire() {
@@ -411,16 +495,16 @@ class j {
411
495
  const e = this.config.container ? document.querySelector(this.config.container) : null;
412
496
  e ? (this.shadowHost.style.display = "block", this.shadowHost.style.height = "100%", this.shadowHost.style.minHeight = "0", e.appendChild(this.shadowHost), this.isUserContainer = !0) : (this.shadowHost.style.position = "fixed", this.shadowHost.style.inset = "0", this.shadowHost.style.zIndex = String(this.config.zIndex), this.shadowHost.style.pointerEvents = "none", document.body.appendChild(this.shadowHost)), this.shadowRoot = this.shadowHost.attachShadow({ mode: "open" });
413
497
  const i = document.createElement("style");
414
- if (i.textContent = A(), this.shadowRoot.appendChild(i), this.config.css) {
415
- const a = document.createElement("style");
416
- a.textContent = this.config.css, this.shadowRoot.appendChild(a);
417
- }
418
- if (this.rootEl = document.createElement("div"), this.rootEl.className = `qaid-q-root${this.isUserContainer ? " qaid-q-inline" : ""}`, N(this.rootEl, this.cssVars), this.isUserContainer)
498
+ if (i.textContent = D(), this.shadowRoot.appendChild(i), this.rootEl = document.createElement("div"), this.rootEl.className = [
499
+ "qaid-q-root",
500
+ this.isUserContainer ? "qaid-q-inline" : "",
501
+ this.config.animate ? "" : "qaid-q-no-motion"
502
+ ].filter(Boolean).join(" "), P(this.rootEl, this.cssVars), this.isUserContainer)
419
503
  this.cardEl = document.createElement("div"), this.cardEl.className = "qaid-q-card", this.rootEl.appendChild(this.cardEl);
420
504
  else {
421
505
  this.backdropEl = document.createElement("div"), this.backdropEl.className = "qaid-q-backdrop", this.backdropEl.addEventListener("click", () => this.close()), this.rootEl.appendChild(this.backdropEl);
422
- const a = document.createElement("div");
423
- a.className = "qaid-q-modal", this.cardEl = document.createElement("div"), this.cardEl.className = "qaid-q-card", a.appendChild(this.cardEl), this.rootEl.appendChild(a);
506
+ const n = document.createElement("div");
507
+ n.className = "qaid-q-modal", this.cardEl = document.createElement("div"), this.cardEl.className = "qaid-q-card", n.appendChild(this.cardEl), this.rootEl.appendChild(n);
424
508
  }
425
509
  this.shadowRoot.appendChild(this.rootEl), !this.isUserContainer && this.shadowHost && (this.shadowHost.style.pointerEvents = "auto"), document.addEventListener("keydown", this.boundKeyDown);
426
510
  }
@@ -435,36 +519,39 @@ class j {
435
519
  this.cardEl.replaceChildren();
436
520
  const i = document.createElement("h3");
437
521
  i.className = "qaid-q-title", i.textContent = "Couldn't load form";
438
- const a = document.createElement("p");
439
- a.className = "qaid-q-description", a.textContent = e instanceof Error ? e.message : String(e), this.cardEl.appendChild(i), this.cardEl.appendChild(a);
522
+ const n = document.createElement("p");
523
+ n.className = "qaid-q-description", n.textContent = e instanceof Error ? e.message : String(e), this.cardEl.appendChild(i), this.cardEl.appendChild(n);
524
+ }
525
+ effectiveProgressPosition() {
526
+ return this.config.progressPosition ?? this.questionnaire?.progressPosition ?? "top";
440
527
  }
441
528
  renderHeader() {
442
529
  if (!this.cardEl || !this.questionnaire) return;
443
530
  this.cardEl.replaceChildren();
444
- const e = this.config.progressPosition === "bottom", i = !!this.questionnaire.title, a = !!this.questionnaire.description, n = !this.isUserContainer;
531
+ const e = !!this.questionnaire.hideProgress || this.questionnaire.questions.length <= 1, i = !e && this.effectiveProgressPosition() === "bottom", n = !!this.questionnaire.hideTitle, a = !!this.questionnaire.title && !n, o = !!this.questionnaire.description && !n, r = !this.isUserContainer, q = r || !i && !e;
445
532
  this.savingEl = document.createElement("div"), this.savingEl.className = "qaid-q-saving";
446
- const s = document.createElement("span");
447
- s.className = "qaid-q-saving-dot";
448
- const r = document.createElement("span");
449
- r.textContent = "Saving…", this.savingEl.appendChild(s), this.savingEl.appendChild(r), this.stepCounterEl = document.createElement("div"), this.stepCounterEl.className = "qaid-q-step-counter", this.progressEl = document.createElement("div"), this.progressEl.className = e ? "qaid-q-progress qaid-q-progress--inline" : "qaid-q-progress", this.progressFillEl = document.createElement("div"), this.progressFillEl.className = "qaid-q-progress-fill", this.progressEl.appendChild(this.progressFillEl);
450
- const p = i || n || !e;
451
- if (p) {
452
- const h = document.createElement("div");
453
- h.className = "qaid-q-header";
454
- const f = document.createElement("div");
455
- i && (this.titleEl = document.createElement("h2"), this.titleEl.className = "qaid-q-title", this.titleEl.textContent = this.questionnaire.title, f.appendChild(this.titleEl));
456
- const m = document.createElement("div");
457
- if (m.style.display = "flex", m.style.alignItems = "center", m.style.gap = "0.5rem", e || (m.appendChild(this.savingEl), m.appendChild(this.stepCounterEl)), n) {
458
- const o = document.createElement("button");
459
- o.type = "button", o.className = "qaid-q-close", o.setAttribute("aria-label", "Close form"), o.innerHTML = Q, o.addEventListener("click", () => this.close()), m.appendChild(o);
533
+ const h = document.createElement("span");
534
+ h.className = "qaid-q-saving-dot";
535
+ const m = document.createElement("span");
536
+ m.textContent = "Saving…", this.savingEl.appendChild(h), this.savingEl.appendChild(m), this.stepCounterEl = document.createElement("div"), this.stepCounterEl.className = "qaid-q-step-counter", this.progressEl = document.createElement("div"), this.progressEl.className = i ? "qaid-q-progress qaid-q-progress--inline" : "qaid-q-progress", this.progressFillEl = document.createElement("div"), this.progressFillEl.className = "qaid-q-progress-fill", this.progressEl.appendChild(this.progressFillEl);
537
+ const f = a || q;
538
+ if (f) {
539
+ const s = document.createElement("div");
540
+ s.className = "qaid-q-header";
541
+ const c = document.createElement("div");
542
+ a && (this.titleEl = document.createElement("h2"), this.titleEl.className = "qaid-q-title", this.titleEl.textContent = this.questionnaire.title, c.appendChild(this.titleEl));
543
+ const d = document.createElement("div");
544
+ if (d.style.display = "flex", d.style.alignItems = "center", d.style.gap = "0.5rem", i || (d.appendChild(this.savingEl), e || d.appendChild(this.stepCounterEl)), r) {
545
+ const p = document.createElement("button");
546
+ p.type = "button", p.className = "qaid-q-close", p.setAttribute("aria-label", "Close form"), p.innerHTML = W, p.addEventListener("click", () => this.close()), d.appendChild(p);
460
547
  }
461
- h.appendChild(f), h.appendChild(m), this.cardEl.appendChild(h);
548
+ s.appendChild(c), s.appendChild(d), this.cardEl.appendChild(s);
462
549
  }
463
- if (a) {
464
- const h = document.createElement("p");
465
- h.className = "qaid-q-description", h.textContent = this.questionnaire.description, h.style.marginTop = p ? "-0.5rem" : "0", h.style.marginBottom = "0.75rem", this.cardEl.appendChild(h);
550
+ if (o) {
551
+ const s = document.createElement("p");
552
+ s.className = "qaid-q-description", s.textContent = this.questionnaire.description, s.style.marginTop = f ? "-0.5rem" : "0", s.style.marginBottom = "0.75rem", this.cardEl.appendChild(s);
466
553
  }
467
- e || this.cardEl.appendChild(this.progressEl), this.bodyEl = document.createElement("div"), this.bodyEl.className = "qaid-q-body", this.cardEl.appendChild(this.bodyEl), this.footerEl = document.createElement("div"), this.footerEl.className = "qaid-q-footer", this.cardEl.appendChild(this.footerEl);
554
+ !i && !e && this.cardEl.appendChild(this.progressEl), this.bodyEl = document.createElement("div"), this.bodyEl.className = "qaid-q-body", this.cardEl.appendChild(this.bodyEl), this.footerEl = document.createElement("div"), this.footerEl.className = "qaid-q-footer", this.cardEl.appendChild(this.footerEl);
468
555
  }
469
556
  // ------------------------------------------------------------------
470
557
  // Step rendering
@@ -477,52 +564,50 @@ class j {
477
564
  return;
478
565
  }
479
566
  this.stepIndex >= e && (this.stepIndex = e - 1);
480
- const i = this.stepIndex, a = this.visibleQuestions[i];
567
+ const i = this.stepIndex, n = this.visibleQuestions[i];
481
568
  if (this.stepCounterEl && (this.stepCounterEl.textContent = `${i + 1} / ${e}`), this.progressFillEl) {
482
- const l = (i + 1) / e * 100;
483
- this.progressFillEl.style.width = `${l}%`;
569
+ const u = (i + 1) / e * 100;
570
+ this.progressFillEl.style.width = `${u}%`;
484
571
  }
485
- const n = document.createElement("div");
486
- n.className = "qaid-q-step", n.setAttribute("role", "group"), n.setAttribute("aria-labelledby", `qaid-q-label-${i}`);
487
- const s = document.createElement("label");
488
- if (s.id = `qaid-q-label-${i}`, s.className = "qaid-q-label", s.textContent = a.label, a.required) {
489
- const l = document.createElement("span");
490
- l.className = "qaid-q-required", l.textContent = "*", l.setAttribute("aria-label", "required"), s.appendChild(l);
572
+ const a = document.createElement("div");
573
+ a.className = "qaid-q-step", a.setAttribute("role", "group"), a.setAttribute("aria-labelledby", `qaid-q-label-${i}`);
574
+ const o = document.createElement("label");
575
+ if (o.id = `qaid-q-label-${i}`, o.className = "qaid-q-label", o.textContent = n.label, n.required) {
576
+ const u = document.createElement("span");
577
+ u.className = "qaid-q-required", u.textContent = "*", u.setAttribute("aria-label", "required"), o.appendChild(u);
491
578
  }
492
- if (n.appendChild(s), a.description) {
493
- const l = document.createElement("p");
494
- l.className = "qaid-q-description", l.textContent = a.description, n.appendChild(l);
579
+ if (a.appendChild(o), n.description) {
580
+ const u = document.createElement("p");
581
+ u.className = "qaid-q-description", u.textContent = n.description, a.appendChild(u);
495
582
  }
496
583
  const r = document.createElement("p");
497
584
  r.className = "qaid-q-error", r.setAttribute("aria-live", "polite");
498
- const p = this.answers[a.id] ?? null, h = i === e - 1, f = I({
499
- question: a,
500
- initialValue: p,
501
- onChange: (l) => {
502
- this.handleAnswerChange(a, l), r.textContent && (r.textContent = "");
585
+ const q = this.answers[n.id] ?? null, h = i === e - 1, m = H({
586
+ question: n,
587
+ initialValue: q,
588
+ onChange: (u) => {
589
+ this.handleAnswerChange(n, u), r.textContent && (r.textContent = "");
503
590
  },
504
- onSubmit: () => this.advance(a, r),
505
- onAutoAdvance: () => this.advance(a, r),
591
+ onSubmit: () => this.advance(n, r),
592
+ onAutoAdvance: () => this.advance(n, r),
506
593
  autoAdvance: this.config.autoAdvance
507
594
  });
508
- this.currentInput = f, n.appendChild(f.element), n.appendChild(r), this.bodyEl.replaceChildren(n), this.footerEl.replaceChildren();
509
- const m = this.config.progressPosition === "bottom", o = i > 0 ? (() => {
510
- const l = document.createElement("button");
511
- return l.type = "button", l.className = "qaid-q-btn qaid-q-btn-secondary", l.textContent = this.questionnaire.backLabel ?? "Back", l.addEventListener("click", () => this.back()), l;
512
- })() : null, c = document.createElement("button");
513
- if (c.type = "button", c.className = "qaid-q-btn qaid-q-btn-primary", c.textContent = h ? this.questionnaire.submitLabel ?? "Submit" : this.questionnaire.nextLabel ?? "Next", c.addEventListener("click", () => this.advance(a, r)), m)
514
- this.footerEl.classList.add("qaid-q-footer--inline-progress"), o && this.footerEl.appendChild(o), this.progressEl && this.footerEl.appendChild(this.progressEl), this.savingEl && this.footerEl.appendChild(this.savingEl), this.stepCounterEl && this.footerEl.appendChild(this.stepCounterEl), this.footerEl.appendChild(c);
595
+ this.currentInput = m, a.appendChild(m.element), a.appendChild(r), this.bodyEl.replaceChildren(a), this.footerEl.replaceChildren();
596
+ const s = !(!!this.questionnaire.hideProgress || this.questionnaire.questions.length <= 1) && this.effectiveProgressPosition() === "bottom", c = i > 0 ? (() => {
597
+ const u = document.createElement("button");
598
+ return u.type = "button", u.className = "qaid-q-btn qaid-q-btn-secondary", u.textContent = this.questionnaire.backLabel ?? "Back", u.addEventListener("click", () => this.back()), u;
599
+ })() : null, d = document.createElement("button");
600
+ if (d.type = "button", d.className = "qaid-q-btn qaid-q-btn-primary", d.textContent = h ? this.questionnaire.submitLabel ?? "Submit" : this.questionnaire.nextLabel ?? "Next", d.addEventListener("click", () => this.advance(n, r)), s)
601
+ this.footerEl.classList.add("qaid-q-footer--inline-progress"), c && this.footerEl.appendChild(c), this.progressEl && this.footerEl.appendChild(this.progressEl), this.savingEl && this.footerEl.appendChild(this.savingEl), this.stepCounterEl && this.footerEl.appendChild(this.stepCounterEl), this.footerEl.appendChild(d);
515
602
  else {
516
603
  this.footerEl.classList.remove("qaid-q-footer--inline-progress");
604
+ const u = document.createElement("div");
605
+ u.className = "qaid-q-footer-left";
517
606
  const l = document.createElement("div");
518
- l.className = "qaid-q-footer-left";
519
- const b = document.createElement("div");
520
- b.className = "qaid-q-footer-right", o && l.appendChild(o);
521
- const d = document.createElement("span");
522
- d.className = "qaid-q-hint", d.innerHTML = h ? "<kbd>Enter</kbd> to submit" : "<kbd>Enter</kbd> to continue", b.appendChild(d), b.appendChild(c), this.footerEl.appendChild(l), this.footerEl.appendChild(b);
607
+ l.className = "qaid-q-footer-right", c && u.appendChild(c), l.appendChild(d), this.footerEl.appendChild(u), this.footerEl.appendChild(l);
523
608
  }
524
- const u = !this.hasRenderedStep;
525
- this.hasRenderedStep = !0, (!u || this.config.autoFocus) && requestAnimationFrame(() => f.focus());
609
+ const p = !this.hasRenderedStep;
610
+ this.hasRenderedStep = !0, (!p || this.config.autoFocus) && requestAnimationFrame(() => m.focus());
526
611
  }
527
612
  renderDone() {
528
613
  if (!this.cardEl || !this.questionnaire) return;
@@ -530,15 +615,15 @@ class j {
530
615
  const e = document.createElement("div");
531
616
  e.className = "qaid-q-done";
532
617
  const i = document.createElement("div");
533
- i.className = "qaid-q-done-icon", i.innerHTML = U, e.appendChild(i);
534
- const a = document.createElement("h3");
535
- if (a.className = "qaid-q-done-title", a.textContent = this.questionnaire.thankYouTitle ?? "Thank you!", e.appendChild(a), this.questionnaire.thankYouMessage) {
536
- const n = document.createElement("p");
537
- n.className = "qaid-q-done-message", n.textContent = this.questionnaire.thankYouMessage, e.appendChild(n);
618
+ i.className = "qaid-q-done-icon", i.innerHTML = Y, e.appendChild(i);
619
+ const n = document.createElement("h3");
620
+ if (n.className = "qaid-q-done-title", n.textContent = this.questionnaire.thankYouTitle ?? "Thank you!", e.appendChild(n), this.questionnaire.thankYouMessage) {
621
+ const a = document.createElement("p");
622
+ a.className = "qaid-q-done-message", a.textContent = this.questionnaire.thankYouMessage, e.appendChild(a);
538
623
  }
539
624
  if (!this.isUserContainer) {
540
- const n = document.createElement("button");
541
- n.type = "button", n.className = "qaid-q-btn qaid-q-btn-primary", n.textContent = "Close", n.style.marginTop = "1rem", n.addEventListener("click", () => this.close()), e.appendChild(n);
625
+ const a = document.createElement("button");
626
+ a.type = "button", a.className = "qaid-q-btn qaid-q-btn-primary", a.textContent = "Close", a.style.marginTop = "1rem", a.addEventListener("click", () => this.close()), e.appendChild(a);
542
627
  }
543
628
  this.cardEl.appendChild(e);
544
629
  }
@@ -548,7 +633,7 @@ class j {
548
633
  advance(e, i) {
549
634
  if (!this.currentInput || !this.questionnaire) return;
550
635
  if (!this.currentInput.isValid()) {
551
- i.textContent = R(e), this.currentInput.focus();
636
+ i.textContent = _(e), this.currentInput.focus();
552
637
  return;
553
638
  }
554
639
  if (this.handleAnswerChange(e, this.currentInput.getValue(), { immediate: !0 }), this.stepIndex === this.visibleQuestions.length - 1) {
@@ -564,12 +649,12 @@ class j {
564
649
  // Answer handling + autosave
565
650
  // ------------------------------------------------------------------
566
651
  recomputeVisible() {
567
- this.questionnaire && (this.visibleQuestions = F(this.questionnaire, this.answers));
652
+ this.questionnaire && (this.visibleQuestions = K(this.questionnaire, this.answers));
568
653
  }
569
- handleAnswerChange(e, i, a = {}) {
654
+ handleAnswerChange(e, i, n = {}) {
570
655
  this.answers[e.id] = i, this.recomputeVisible();
571
- const n = e.type === "text" || e.type === "currency" || e.type === "range";
572
- if (a.immediate || !n) {
656
+ const a = e.type === "text" || e.type === "currency" || e.type === "range";
657
+ if (n.immediate || !a) {
573
658
  this.flushPendingSave(), this.saveAnswer(e.id, i);
574
659
  return;
575
660
  }
@@ -589,9 +674,9 @@ class j {
589
674
  });
590
675
  }
591
676
  async doSave(e, i) {
592
- let a = 0;
593
- for (; this.responseId === null && a < 5e3; )
594
- await new Promise((n) => setTimeout(n, 50)), a += 50;
677
+ let n = 0;
678
+ for (; this.responseId === null && n < 5e3; )
679
+ await new Promise((a) => setTimeout(a, 50)), n += 50;
595
680
  if (this.responseId !== null)
596
681
  try {
597
682
  await fetch(`${this.config.endpoint}/${this.responseId}`, {
@@ -599,8 +684,8 @@ class j {
599
684
  headers: this.jsonHeaders(),
600
685
  body: JSON.stringify({ questionId: e, value: i })
601
686
  });
602
- } catch (n) {
603
- console.error("[quests-embed] failed to save answer:", n);
687
+ } catch (a) {
688
+ console.error("[quests-embed] failed to save answer:", a);
604
689
  }
605
690
  }
606
691
  async createResponse() {
@@ -666,6 +751,17 @@ class j {
666
751
  getAnswers() {
667
752
  return { ...this.answers };
668
753
  }
754
+ /**
755
+ * Id of the question currently rendered, or `null` if the embed
756
+ * isn't on a question (still loading, on the thank-you screen, or
757
+ * unmounted). Useful for editor previews that want to restore the
758
+ * user's place after a forced re-mount.
759
+ */
760
+ getCurrentQuestionId() {
761
+ if (this.state !== "READY") return null;
762
+ const e = this.visibleQuestions[this.stepIndex];
763
+ return e ? e.id : null;
764
+ }
669
765
  /**
670
766
  * Jump to the visible question with the given id. Returns true if
671
767
  * the question is currently visible (and the embed navigated to
@@ -678,11 +774,11 @@ class j {
678
774
  goToStep(e) {
679
775
  if (this.state !== "READY" || !this.questionnaire)
680
776
  return this.pendingGoToStep = e, !1;
681
- const i = this.visibleQuestions.findIndex((a) => a.id === e);
777
+ const i = this.visibleQuestions.findIndex((n) => n.id === e);
682
778
  return i === -1 ? !1 : (i === this.stepIndex || (this.flushPendingSave(), this.stepIndex = i, this.renderStep()), !0);
683
779
  }
684
780
  }
685
- function R(t) {
781
+ function _(t) {
686
782
  switch (t.type) {
687
783
  case "text":
688
784
  return t.minLength ? `Please enter at least ${t.minLength} characters.` : "This field is required.";
@@ -696,10 +792,10 @@ function R(t) {
696
792
  return "Please choose a value.";
697
793
  }
698
794
  }
699
- function E(t) {
795
+ function w(t) {
700
796
  return document.querySelector(t)?.textContent?.trim() ?? "";
701
797
  }
702
- function M() {
798
+ function J() {
703
799
  const t = document.querySelector(
704
800
  'script[type="application/json"][data-quests-config]'
705
801
  );
@@ -708,45 +804,49 @@ function M() {
708
804
  if (!e) return null;
709
805
  try {
710
806
  const i = JSON.parse(e);
711
- return i.cssSelector && !i.css && (i.css = E(i.cssSelector), delete i.cssSelector), i;
807
+ return i.cssSelector && !i.css && (i.css = w(i.cssSelector), delete i.cssSelector), i;
712
808
  } catch {
713
809
  return null;
714
810
  }
715
811
  }
716
- function $(t) {
812
+ function X(t) {
717
813
  const e = t.getAttribute("data-endpoint");
718
814
  if (!e) return null;
719
- const i = t.getAttribute("data-config-url"), a = t.getAttribute("data-api-key"), n = t.getAttribute("data-container"), s = t.getAttribute("data-zindex"), r = t.getAttribute("data-positive-color"), p = t.getAttribute("data-negative-color"), h = t.getAttribute("data-marker-color"), f = t.getAttribute("data-modal-width"), m = t.getAttribute("data-backdrop-opacity"), o = t.getAttribute("data-font-family"), c = t.getAttribute("data-font-size"), u = t.getAttribute("data-css-selector"), g = t.getAttribute("data-auto-advance"), l = t.getAttribute("data-save-debounce-ms");
815
+ const i = t.getAttribute("data-config-url"), n = t.getAttribute("data-api-key"), a = t.getAttribute("data-container"), o = t.getAttribute("data-zindex"), r = t.getAttribute("data-positive-color"), q = t.getAttribute("data-negative-color"), h = t.getAttribute("data-marker-color"), m = t.getAttribute("data-modal-width"), f = t.getAttribute("data-backdrop-opacity"), s = t.getAttribute("data-font-family"), c = t.getAttribute("data-font-size"), d = t.getAttribute("data-css-selector"), p = t.getAttribute("data-auto-advance"), g = t.getAttribute("data-save-debounce-ms"), u = t.getAttribute("data-theme-url"), l = t.getAttribute("data-preset"), y = t.getAttribute("data-theme"), k = t.getAttribute("data-unstyled");
720
816
  return {
721
817
  endpoint: e,
722
818
  configUrl: i ?? void 0,
723
- apiKey: a ?? void 0,
724
- container: n ?? void 0,
725
- zIndex: s ? parseInt(s, 10) : void 0,
819
+ apiKey: n ?? void 0,
820
+ container: a ?? void 0,
821
+ zIndex: o ? parseInt(o, 10) : void 0,
726
822
  colors: {
727
823
  positive: r ?? void 0,
728
- negative: p ?? void 0,
824
+ negative: q ?? void 0,
729
825
  marker: h ?? void 0
730
826
  },
731
- modalWidth: f ? parseInt(f, 10) : void 0,
732
- backdropOpacity: m ? parseFloat(m) : void 0,
733
- fontFamily: o ?? void 0,
827
+ modalWidth: m ? parseInt(m, 10) : void 0,
828
+ backdropOpacity: f ? parseFloat(f) : void 0,
829
+ fontFamily: s ?? void 0,
734
830
  fontSize: c ? parseInt(c, 10) : void 0,
735
- css: u ? E(u) : void 0,
736
- autoAdvance: g === "true" ? !0 : void 0,
737
- saveDebounceMs: l ? parseInt(l, 10) : void 0
831
+ css: d ? w(d) : void 0,
832
+ autoAdvance: p === "true" ? !0 : void 0,
833
+ saveDebounceMs: g ? parseInt(g, 10) : void 0,
834
+ themeUrl: u ?? void 0,
835
+ preset: l || void 0,
836
+ theme: y || void 0,
837
+ unstyled: k === "true" ? !0 : void 0
738
838
  };
739
839
  }
740
840
  if (typeof document < "u") {
741
841
  const t = () => {
742
- const e = document.currentScript, i = M(), a = e ? $(e) : null, n = i ?? a;
743
- n?.endpoint && (n.configUrl || n.questionnaire) && new j(n);
842
+ const e = document.currentScript, i = J(), n = e ? X(e) : null, a = i ?? n;
843
+ a?.endpoint && (a.configUrl || a.questionnaire) && new G(a);
744
844
  };
745
845
  document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", t) : t();
746
846
  }
747
847
  export {
748
- j as QaidQuests,
848
+ G as QaidQuests,
749
849
  v as evaluateRule,
750
- F as getVisibleQuestions
850
+ K as getVisibleQuestions
751
851
  };
752
852
  //# sourceMappingURL=qaid-quests.js.map