vue3-step-wizard 0.5.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.
package/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # vue3-step-wizard
2
+
3
+ A Vue 3 + TypeScript wizard component.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install vue3-step-wizard
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```vue
14
+ <script setup lang="ts">
15
+ import { ref } from 'vue';
16
+ import { Wizard, type WizardStep, type WizardExpose } from 'vue3-step-wizard';
17
+ import 'vue3-step-wizard/wizard-style.css';
18
+
19
+ import StepDomain from './steps/StepDomain.vue';
20
+ import StepBusiness from './steps/StepBusiness.vue';
21
+ import StepFinish from './steps/StepFinish.vue';
22
+
23
+ const steps: WizardStep[] = [
24
+ { name: 'domain', title: 'Domain', component: StepDomain },
25
+ { name: 'business', title: 'Business info', component: StepBusiness },
26
+ { name: 'finish', title: 'Finish', component: StepFinish }
27
+ ];
28
+
29
+ const current = ref(0);
30
+
31
+ const handleCustomEvent = (payload?: unknown) => {
32
+ console.log('Custom event payload', payload);
33
+ };
34
+
35
+ const handleStepChanged = (payload: { from: string | null; to: string }) => {
36
+ console.log('Step changed', payload);
37
+ };
38
+
39
+ const wizardRef = ref<WizardExpose | null>(null);
40
+
41
+ const goToFinish = () => {
42
+ wizardRef.value?.moveTo('finish');
43
+ };
44
+
45
+ const hideBusiness = () => {
46
+ wizardRef.value?.hideStep('business');
47
+ };
48
+
49
+ const showBusiness = () => {
50
+ wizardRef.value?.showStep('business');
51
+ };
52
+ </script>
53
+
54
+ <template>
55
+ <Wizard
56
+ ref="wizardRef"
57
+ v-model="current"
58
+ :steps="steps"
59
+ :allow-step-click="true"
60
+ :show-controls="true"
61
+ @custom-event="handleCustomEvent"
62
+ @step-changed="handleStepChanged"
63
+ />
64
+ </template>
65
+ ```
66
+
67
+ Each step component should emit `next` and `back` to move through the wizard.
68
+ If you use `custom-event`, include the step name in the payload so the parent can identify the source.
69
+
70
+ Wizard instance methods (via `ref`) let you move or toggle steps at runtime:
71
+ - `moveTo(stepName)`
72
+ - `hideStep(stepName)`
73
+ - `showStep(stepName)`
74
+
75
+ You can also pass `hidden-steps` to control visibility by step name.
76
+
77
+ Wizard emits:
78
+ - `step-changed` with `{ from, to }` step names.
79
+ - `custom-event` forwarded from the active step component.
80
+
81
+ Example step component:
82
+
83
+ ```vue
84
+ <script setup lang="ts">
85
+ const emit = defineEmits<{
86
+ (event: 'next'): void;
87
+ (event: 'back'): void;
88
+ (event: 'custom-event', payload?: unknown): void;
89
+ }>();
90
+ </script>
91
+
92
+ <template>
93
+ <div>
94
+ <button type="button" @click="emit('back')">Back</button>
95
+ <button type="button" @click="emit('next')">Next</button>
96
+ <button type="button" @click="emit('custom-event', { step: 'domain', source: 'step-domain' })">
97
+ Fire custom event
98
+ </button>
99
+ </div>
100
+ </template>
101
+ ```
102
+
103
+ ## Theming
104
+
105
+ All colors are driven by CSS variables defined in `wizard-style.css`. Override them in your app to theme the wizard.
106
+
107
+ ```css
108
+ :root {
109
+ --accent: #f5b24a;
110
+ --accent-2: #5be4ff;
111
+ --text: #f5f7fb;
112
+ --muted: #9aa3b2;
113
+ --wizard-ink: #13161c;
114
+ --wizard-white: #ffffff;
115
+ --wizard-surface-750: rgba(18, 23, 36, 0.75);
116
+ --wizard-surface-900: rgba(18, 23, 36, 0.9);
117
+ --wizard-border-weak: rgba(255, 255, 255, 0.08);
118
+ --wizard-border: rgba(255, 255, 255, 0.1);
119
+ --wizard-shadow-strong: rgba(0, 0, 0, 0.35);
120
+ }
121
+ ```
122
+
123
+ To override fonts, set them on the relevant classes in your app stylesheet:
124
+
125
+ ```css
126
+ .__wizard-panel h1 {
127
+ font-family: 'Your Display Font', sans-serif;
128
+ }
129
+
130
+ .__wizard-page {
131
+ font-family: 'Your UI Font', sans-serif;
132
+ }
133
+ ```
@@ -0,0 +1,120 @@
1
+ import { defineComponent as D, ref as y, watch as b, computed as w, createElementBlock as i, openBlock as l, createElementVNode as c, createCommentVNode as f, toDisplayString as S, Fragment as F, renderList as I, normalizeClass as L, createBlock as M, resolveDynamicComponent as W, mergeProps as H } from "vue";
2
+ const P = { class: "__wizard-page" }, $ = { class: "__wizard" }, j = {
3
+ key: 0,
4
+ class: "__wizard-sidebar"
5
+ }, q = { class: "__eyebrow" }, A = { class: "__step-list" }, G = ["onClick"], J = { class: "__step-index" }, K = { class: "__step-title" }, O = { class: "__wizard-panel" }, Q = {
6
+ key: 1,
7
+ class: "__wizard-controls"
8
+ }, ee = /* @__PURE__ */ D({
9
+ __name: "Wizard",
10
+ props: {
11
+ steps: {},
12
+ modelValue: { default: 0 },
13
+ sidebarTitle: { default: "Setup steps" },
14
+ allowStepClick: { type: Boolean, default: !0 },
15
+ hiddenSteps: { default: () => [] },
16
+ showControls: { type: Boolean, default: !0 }
17
+ },
18
+ emits: ["update:modelValue", "change", "custom-event", "step-changed"],
19
+ setup(u, { expose: V, emit: z }) {
20
+ const s = u, p = z, k = (e) => s.steps.length ? Math.max(0, Math.min(e, s.steps.length - 1)) : 0, n = y(k(s.modelValue ?? 0));
21
+ b(
22
+ () => s.modelValue,
23
+ (e) => {
24
+ const t = k(e ?? 0);
25
+ t !== n.value && (n.value = t);
26
+ }
27
+ );
28
+ const _ = w(() => s.steps[n.value]), o = y(new Set(s.hiddenSteps));
29
+ b(
30
+ () => s.hiddenSteps,
31
+ (e) => {
32
+ o.value = new Set(e ?? []), x();
33
+ }
34
+ );
35
+ const m = (e) => o.value.has(e), B = w(
36
+ () => s.steps.map((e, t) => ({ step: e, index: t })).filter(({ step: e }) => !m(e.name))
37
+ ), r = (e) => {
38
+ var h, d;
39
+ const t = k(e);
40
+ if (t === n.value)
41
+ return;
42
+ const a = ((h = s.steps[n.value]) == null ? void 0 : h.name) ?? null, v = (d = s.steps[t]) == null ? void 0 : d.name;
43
+ n.value = t, p("update:modelValue", t), p("change", t), v && p("step-changed", { from: a, to: v });
44
+ }, N = w(() => n.value >= s.steps.length - 1), C = () => {
45
+ n.value >= s.steps.length - 1 || r(n.value + 1);
46
+ }, g = () => {
47
+ n.value <= 0 || r(n.value - 1);
48
+ }, E = (e) => {
49
+ p("custom-event", e);
50
+ }, T = (e) => {
51
+ s.allowStepClick && (s.steps[e], r(e));
52
+ }, x = () => {
53
+ const e = s.steps[n.value];
54
+ if (e && !m(e.name))
55
+ return;
56
+ const t = s.steps.findIndex((a) => !m(a.name));
57
+ t >= 0 && r(t);
58
+ };
59
+ return V({
60
+ moveTo: (e) => {
61
+ const t = s.steps.findIndex((a) => a.name === e);
62
+ t !== -1 && (m(e) || r(t));
63
+ },
64
+ hideStep: (e) => {
65
+ o.value = new Set(o.value).add(e), x();
66
+ },
67
+ showStep: (e) => {
68
+ if (!o.value.has(e))
69
+ return;
70
+ const t = new Set(o.value);
71
+ t.delete(e), o.value = t;
72
+ }
73
+ }), (e, t) => (l(), i("main", P, [
74
+ c("section", $, [
75
+ u.steps.length ? (l(), i("aside", j, [
76
+ c("p", q, S(u.sidebarTitle), 1),
77
+ c("div", A, [
78
+ (l(!0), i(F, null, I(B.value, ({ step: a, index: v }, h) => {
79
+ var d;
80
+ return l(), i("div", {
81
+ key: a.name,
82
+ class: L(["__step-item", {
83
+ __active: a.name === ((d = _.value) == null ? void 0 : d.name),
84
+ __clickable: u.allowStepClick
85
+ }]),
86
+ onClick: (Y) => T(v)
87
+ }, [
88
+ c("span", J, S(h + 1), 1),
89
+ c("span", K, S(a.title), 1)
90
+ ], 10, G);
91
+ }), 128))
92
+ ])
93
+ ])) : f("", !0),
94
+ c("div", O, [
95
+ _.value ? (l(), M(W(_.value.component), H({ key: 0 }, _.value.props, {
96
+ onNext: C,
97
+ onBack: g,
98
+ onCustomEvent: E
99
+ }), null, 16)) : f("", !0),
100
+ u.showControls ? (l(), i("div", Q, [
101
+ n.value > 0 ? (l(), i("button", {
102
+ key: 0,
103
+ class: "__cta __ghost",
104
+ type: "button",
105
+ onClick: g
106
+ }, " Back ")) : f("", !0),
107
+ c("button", {
108
+ class: "__cta __primary",
109
+ type: "button",
110
+ onClick: C
111
+ }, S(N.value ? "Finish" : "Next"), 1)
112
+ ])) : f("", !0)
113
+ ])
114
+ ])
115
+ ]));
116
+ }
117
+ });
118
+ export {
119
+ ee as Wizard
120
+ };
@@ -0,0 +1 @@
1
+ (function(l,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(l=typeof globalThis<"u"?globalThis:l||self,e(l.Vue3StepWizard={},l.Vue))})(this,function(l,e){"use strict";const g={class:"__wizard-page"},w={class:"__wizard"},y={key:0,class:"__wizard-sidebar"},C={class:"__eyebrow"},B={class:"__step-list"},E=["onClick"],b={class:"__step-index"},x={class:"__step-title"},N={class:"__wizard-panel"},z={key:1,class:"__wizard-controls"},T=e.defineComponent({__name:"Wizard",props:{steps:{},modelValue:{default:0},sidebarTitle:{default:"Setup steps"},allowStepClick:{type:Boolean,default:!0},hiddenSteps:{default:()=>[]},showControls:{type:Boolean,default:!0}},emits:["update:modelValue","change","custom-event","step-changed"],setup(i,{expose:D,emit:v}){const o=i,p=v,f=t=>o.steps.length?Math.max(0,Math.min(t,o.steps.length-1)):0,s=e.ref(f(o.modelValue??0));e.watch(()=>o.modelValue,t=>{const n=f(t??0);n!==s.value&&(s.value=n)});const m=e.computed(()=>o.steps[s.value]),c=e.ref(new Set(o.hiddenSteps));e.watch(()=>o.hiddenSteps,t=>{c.value=new Set(t??[]),V()});const u=t=>c.value.has(t),M=e.computed(()=>o.steps.map((t,n)=>({step:t,index:n})).filter(({step:t})=>!u(t.name))),r=t=>{var h,d;const n=f(t);if(n===s.value)return;const a=((h=o.steps[s.value])==null?void 0:h.name)??null,_=(d=o.steps[n])==null?void 0:d.name;s.value=n,p("update:modelValue",n),p("change",n),_&&p("step-changed",{from:a,to:_})},W=e.computed(()=>s.value>=o.steps.length-1),S=()=>{s.value>=o.steps.length-1||r(s.value+1)},k=()=>{s.value<=0||r(s.value-1)},j=t=>{p("custom-event",t)},F=t=>{o.allowStepClick&&(o.steps[t],r(t))},V=()=>{const t=o.steps[s.value];if(t&&!u(t.name))return;const n=o.steps.findIndex(a=>!u(a.name));n>=0&&r(n)};return D({moveTo:t=>{const n=o.steps.findIndex(a=>a.name===t);n!==-1&&(u(t)||r(n))},hideStep:t=>{c.value=new Set(c.value).add(t),V()},showStep:t=>{if(!c.value.has(t))return;const n=new Set(c.value);n.delete(t),c.value=n}}),(t,n)=>(e.openBlock(),e.createElementBlock("main",g,[e.createElementVNode("section",w,[i.steps.length?(e.openBlock(),e.createElementBlock("aside",y,[e.createElementVNode("p",C,e.toDisplayString(i.sidebarTitle),1),e.createElementVNode("div",B,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(M.value,({step:a,index:_},h)=>{var d;return e.openBlock(),e.createElementBlock("div",{key:a.name,class:e.normalizeClass(["__step-item",{__active:a.name===((d=m.value)==null?void 0:d.name),__clickable:i.allowStepClick}]),onClick:q=>F(_)},[e.createElementVNode("span",b,e.toDisplayString(h+1),1),e.createElementVNode("span",x,e.toDisplayString(a.title),1)],10,E)}),128))])])):e.createCommentVNode("",!0),e.createElementVNode("div",N,[m.value?(e.openBlock(),e.createBlock(e.resolveDynamicComponent(m.value.component),e.mergeProps({key:0},m.value.props,{onNext:S,onBack:k,onCustomEvent:j}),null,16)):e.createCommentVNode("",!0),i.showControls?(e.openBlock(),e.createElementBlock("div",z,[s.value>0?(e.openBlock(),e.createElementBlock("button",{key:0,class:"__cta __ghost",type:"button",onClick:k}," Back ")):e.createCommentVNode("",!0),e.createElementVNode("button",{class:"__cta __primary",type:"button",onClick:S},e.toDisplayString(W.value?"Finish":"Next"),1)])):e.createCommentVNode("",!0)])])]))}});l.Wizard=T,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
package/index.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ import type { DefineComponent, Component } from 'vue';
2
+
3
+ export type WizardStep = {
4
+ name: string;
5
+ title: string;
6
+ component: Component;
7
+ props?: Record<string, unknown>;
8
+ };
9
+
10
+ export type WizardExpose = {
11
+ moveTo: (stepName: string) => void;
12
+ hideStep: (stepName: string) => void;
13
+ showStep: (stepName: string) => void;
14
+ };
15
+
16
+ export const Wizard: DefineComponent<{
17
+ steps: WizardStep[];
18
+ modelValue?: number;
19
+ sidebarTitle?: string;
20
+ allowStepClick?: boolean;
21
+ hiddenSteps?: string[];
22
+ showControls?: boolean;
23
+ }, {}, any, any, any, any, {
24
+ 'step-changed': (payload: { from: string | null; to: string }) => void;
25
+ 'custom-event': (payload?: unknown) => void;
26
+ }> & {
27
+ new (): WizardExpose;
28
+ };
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "vue3-step-wizard",
3
+ "version": "0.5.0",
4
+ "type": "module",
5
+ "description": "A Vue 3 wizard component library.",
6
+ "main": "./dist/vue3-step-wizard.umd.cjs",
7
+ "module": "./dist/vue3-step-wizard.es.js",
8
+ "types": "./index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./index.d.ts",
12
+ "development": "./src/index.ts",
13
+ "import": "./dist/vue3-step-wizard.es.js",
14
+ "require": "./dist/vue3-step-wizard.umd.cjs"
15
+ },
16
+ "./wizard-style.css": "./wizard-style.css"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "index.d.ts",
21
+ "wizard-style.css"
22
+ ],
23
+ "scripts": {
24
+ "dev": "vite",
25
+ "build": "npm run build:types && vite build",
26
+ "build:types": "vue-tsc -p tsconfig.json --declaration --emitDeclarationOnly --outDir dist",
27
+ "prepare": "npm run build",
28
+ "preview": "vite preview",
29
+ "typecheck": "vue-tsc --noEmit"
30
+ },
31
+ "peerDependencies": {
32
+ "vue": "^3.3.0"
33
+ },
34
+ "devDependencies": {
35
+ "@vitejs/plugin-vue": "^5.0.0",
36
+ "typescript": "^5.5.4",
37
+ "vite": "^5.0.0",
38
+ "vue": "^3.3.0",
39
+ "vue-tsc": "^2.0.26"
40
+ },
41
+ "keywords": [
42
+ "vue",
43
+ "wizard",
44
+ "component",
45
+ "typescript"
46
+ ],
47
+ "license": "MIT",
48
+ "publishConfig": {
49
+ "access": "public"
50
+ },
51
+ "packageManager": "yarn@4.11.0+sha512.4e54aeace9141df2f0177c266b05ec50dc044638157dae128c471ba65994ac802122d7ab35bcd9e81641228b7dcf24867d28e750e0bcae8a05277d600008ad54"
52
+ }
@@ -0,0 +1,470 @@
1
+ :root {
2
+ --wizard-accent: #f5b24a;
3
+ --wizard-accent-2: #5be4ff;
4
+ --wizard-text: #f5f7fb;
5
+ --wizard-muted: #9aa3b2;
6
+ --wizard-ink: #13161c;
7
+ --wizard-shadow-strong: rgba(0, 0, 0, 0.35);
8
+ --wizard-surface-strong: rgba(12, 16, 26, 0.9);
9
+ --wizard-surface-750: rgba(18, 23, 36, 0.75);
10
+ --wizard-surface-900: rgba(18, 23, 36, 0.9);
11
+ --wizard-border-weak: rgba(255, 255, 255, 0.08);
12
+ --wizard-border: rgba(255, 255, 255, 0.1);
13
+ --wizard-border-strong: rgba(255, 255, 255, 0.12);
14
+ --wizard-border-strongest: rgba(255, 255, 255, 0.2);
15
+ --wizard-accent-glow: rgba(245, 178, 74, 0.25);
16
+ --wizard-accent-strong: rgba(245, 178, 74, 0.6);
17
+ --wizard-accent-stronger: rgba(245, 178, 74, 0.9);
18
+ --wizard-accent-2-soft: rgba(91, 228, 255, 0.12);
19
+ --wizard-accent-2-strong: rgba(91, 228, 255, 0.6);
20
+ }
21
+
22
+ .__wizard-page {
23
+ min-height: 0;
24
+ color: var(--wizard-text);
25
+ padding: 15px clamp(1.5rem, 5vw, 5rem) calc(3rem - 10px);
26
+ display: flex;
27
+ flex-direction: column;
28
+ gap: 0.5rem;
29
+ }
30
+
31
+ .__wizard {
32
+ display: grid;
33
+ grid-template-columns: minmax(0, 0.35fr) minmax(0, 0.65fr);
34
+ gap: 2rem;
35
+ }
36
+
37
+ .__wizard-sidebar {
38
+ background: var(--wizard-surface-750);
39
+ padding: 2rem;
40
+ border: 1px solid var(--wizard-border-weak);
41
+ box-shadow: 0 20px 50px var(--wizard-shadow-strong);
42
+ align-self: start;
43
+ }
44
+
45
+ .__wizard-sidebar .__eyebrow {
46
+ text-transform: uppercase;
47
+ letter-spacing: 0.2rem;
48
+ font-size: 0.75rem;
49
+ color: var(--wizard-accent-2);
50
+ margin-bottom: 1.5rem;
51
+ }
52
+
53
+ .__step-list {
54
+ display: grid;
55
+ gap: 1rem;
56
+ }
57
+
58
+ .__step-item {
59
+ background: transparent;
60
+ border: 1px solid var(--wizard-border-weak);
61
+ padding: 0.9rem 1rem;
62
+ color: inherit;
63
+ display: grid;
64
+ gap: 0.4rem;
65
+ text-align: left;
66
+ transition: transform 0.2s ease, border-color 0.2s ease;
67
+ }
68
+
69
+ .__step-item.__active {
70
+ border-color: var(--wizard-accent-strong);
71
+ transform: translateY(-2px);
72
+ }
73
+
74
+ .__step-item.__clickable {
75
+ cursor: pointer;
76
+ }
77
+
78
+
79
+ .__step-index {
80
+ font-size: 0.7rem;
81
+ letter-spacing: 0.2rem;
82
+ text-transform: uppercase;
83
+ color: var(--wizard-muted);
84
+ }
85
+
86
+ .__step-title {
87
+ font-weight: 600;
88
+ letter-spacing: 0.08rem;
89
+ text-transform: uppercase;
90
+ font-size: 0.85rem;
91
+ }
92
+
93
+ .__wizard-panel {
94
+ background: var(--wizard-surface-900);
95
+ padding: 2.5rem;
96
+ border: 1px solid var(--wizard-border);
97
+ box-shadow: 0 30px 60px var(--wizard-shadow-strong);
98
+ overflow: visible;
99
+ display: flex;
100
+ flex-direction: column;
101
+ min-height: 77vh;
102
+ }
103
+
104
+ .__wizard-panel h1 {
105
+ font-family: 'Syne', sans-serif;
106
+ font-size: clamp(2.2rem, 4vw, 3.2rem);
107
+ line-height: 1.1;
108
+ margin: 0 0 2rem;
109
+ padding: 0;
110
+ transform: translateY(-0.5rem);
111
+ }
112
+
113
+ .__wizard-title {
114
+ display: flex;
115
+ align-items: center;
116
+ justify-content: space-between;
117
+ gap: 1rem;
118
+ }
119
+
120
+ .__business-step {
121
+ margin-top: 1.5rem;
122
+ display: grid;
123
+ gap: 1.5rem;
124
+ }
125
+
126
+ .__business-step > p {
127
+ margin-top: -60px;
128
+ }
129
+
130
+ .__business-grid {
131
+ display: grid;
132
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
133
+ gap: 1rem;
134
+ margin-top: -10px;
135
+ }
136
+
137
+ .__business-field {
138
+ display: grid;
139
+ gap: 0.4rem;
140
+ font-size: 0.85rem;
141
+ text-transform: uppercase;
142
+ letter-spacing: 0.08rem;
143
+ color: var(--wizard-muted);
144
+ }
145
+
146
+ .__business-field.__full {
147
+ grid-column: 1 / -1;
148
+ }
149
+
150
+ .__business-field input,
151
+ .__business-field textarea,
152
+ .__business-field select {
153
+ background: var(--wizard-surface-strong);
154
+ border: 1px solid var(--wizard-border-strong);
155
+ padding: 0.75rem 0.9rem;
156
+ color: var(--wizard-text);
157
+ font-size: 0.95rem;
158
+ text-transform: none;
159
+ letter-spacing: normal;
160
+ resize: vertical;
161
+ }
162
+
163
+ .__business-field input.__invalid,
164
+ .__business-field textarea.__invalid,
165
+ .__business-field select.__invalid {
166
+ border-color: var(--wizard-accent-stronger);
167
+ }
168
+
169
+ .__business-field input:focus,
170
+ .__business-field textarea:focus,
171
+ .__business-field select:focus {
172
+ outline: none;
173
+ border-color: var(--wizard-accent-2-strong);
174
+ box-shadow: 0 0 0 3px var(--wizard-accent-2-soft);
175
+ }
176
+
177
+
178
+
179
+ .__wizard-panel p {
180
+ color: var(--wizard-muted);
181
+ line-height: 1.8;
182
+ max-width: 36rem;
183
+ }
184
+
185
+ .__wizard-controls {
186
+ margin-top: auto;
187
+ display: flex;
188
+ justify-content: flex-end;
189
+ gap: 1rem;
190
+ padding-top: 2rem;
191
+ }
192
+
193
+
194
+
195
+
196
+
197
+
198
+
199
+
200
+
201
+
202
+
203
+
204
+
205
+
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+
214
+
215
+
216
+
217
+
218
+
219
+
220
+
221
+
222
+
223
+
224
+
225
+
226
+
227
+
228
+
229
+
230
+
231
+
232
+
233
+
234
+
235
+
236
+
237
+
238
+
239
+
240
+
241
+
242
+
243
+
244
+
245
+
246
+
247
+
248
+
249
+
250
+
251
+
252
+
253
+
254
+
255
+
256
+
257
+
258
+
259
+
260
+
261
+
262
+
263
+
264
+
265
+
266
+
267
+
268
+
269
+
270
+
271
+
272
+
273
+
274
+
275
+
276
+
277
+
278
+
279
+
280
+
281
+
282
+
283
+
284
+
285
+
286
+
287
+
288
+
289
+
290
+
291
+
292
+
293
+
294
+
295
+
296
+
297
+
298
+
299
+
300
+
301
+
302
+
303
+
304
+
305
+
306
+
307
+
308
+
309
+
310
+
311
+
312
+
313
+
314
+
315
+
316
+
317
+
318
+
319
+
320
+
321
+
322
+
323
+
324
+
325
+
326
+
327
+
328
+
329
+
330
+
331
+
332
+
333
+
334
+
335
+
336
+
337
+
338
+ .__cta {
339
+ display: inline-flex;
340
+ align-items: center;
341
+ justify-content: center;
342
+ padding: 0.75rem 1.6rem;
343
+ text-transform: uppercase;
344
+ letter-spacing: 0.1rem;
345
+ font-weight: 600;
346
+ border: 1px solid transparent;
347
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
348
+ background: transparent;
349
+ color: inherit;
350
+ cursor: pointer;
351
+ }
352
+
353
+ .__cta:hover {
354
+ transform: translateY(-2px);
355
+ }
356
+
357
+ .__cta.__primary {
358
+ background: var(--wizard-accent);
359
+ color: var(--wizard-ink);
360
+ box-shadow: 0 12px 30px var(--wizard-accent-glow);
361
+ }
362
+
363
+ .__cta.__ghost {
364
+ border-color: var(--wizard-border-strongest);
365
+ color: var(--wizard-text);
366
+ }
367
+
368
+ .__cta:disabled {
369
+ opacity: 0.5;
370
+ cursor: not-allowed;
371
+ box-shadow: none;
372
+ transform: none;
373
+ }
374
+
375
+ @media (max-width: 720px) {
376
+ .__wizard-page {
377
+ padding-top: 0;
378
+ padding-bottom: 2.5rem;
379
+ gap: 0;
380
+ }
381
+
382
+ .__wizard {
383
+ grid-template-columns: 1fr;
384
+ margin-top: 0;
385
+ }
386
+
387
+ .__wizard-sidebar, .__wizard-panel {
388
+ padding: 2rem;
389
+ }
390
+
391
+ .__wizard-panel {
392
+ margin-top: 10px;
393
+ }
394
+
395
+ .__wizard-panel {
396
+ min-height: 80vh;
397
+ }
398
+
399
+
400
+
401
+ .__step-item {
402
+ padding: 0.8rem 0.9rem;
403
+ }
404
+
405
+
406
+
407
+ .__wizard-sidebar {
408
+ display: none;
409
+ }
410
+
411
+
412
+
413
+
414
+
415
+
416
+
417
+
418
+
419
+
420
+
421
+
422
+
423
+
424
+
425
+
426
+
427
+
428
+
429
+
430
+
431
+
432
+
433
+
434
+
435
+
436
+
437
+
438
+
439
+
440
+
441
+
442
+
443
+
444
+
445
+
446
+
447
+
448
+
449
+
450
+
451
+
452
+
453
+
454
+
455
+
456
+
457
+
458
+ }
459
+
460
+
461
+
462
+ @keyframes spin {
463
+ to {
464
+ transform: rotate(360deg);
465
+ }
466
+ }
467
+
468
+
469
+
470
+