onboarding-kit 0.1.0 → 0.2.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.
@@ -8,6 +8,11 @@ exports.CSS = `
8
8
  :root{--bg:#faf9f6;--surface:#fff;--surface-2:#f3f1ec;--text:#1b1a18;--muted:#68645c;--border:#e6e3dc;--track:#e8e5de;--shadow:0 1px 2px rgb(30 25 15/.04),0 10px 30px rgb(30 25 15/.07);--al:47%;--as:72%;--on-accent:#fff;--code-bg:#f1efe9;--term-bg:#161514;--term-text:#efece5;color-scheme:light}
9
9
  @media (prefers-color-scheme:dark){:root:not([data-theme="light"]){${DARK}}}
10
10
  :root[data-theme="dark"]{${DARK}}
11
+ /* marcas sem cor (preto/cinza): destaque escuro no claro e claro no escuro */
12
+ :root[data-mono]{--al:26%;--wl:16%}
13
+ @media (prefers-color-scheme:dark){:root[data-mono]:not([data-theme="light"]){--al:84%;--wl:24%}}
14
+ :root[data-mono][data-theme="dark"]{--al:84%;--wl:24%}
15
+ @property --bh{syntax:"<number>";inherits:true;initial-value:255}
11
16
  *{box-sizing:border-box}
12
17
  html,body{height:100%;margin:0}
13
18
  body{background:var(--bg);color:var(--text);font:16px/1.6 "Plus Jakarta Sans",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;-webkit-font-smoothing:antialiased;overflow:hidden}
@@ -17,28 +22,29 @@ code,pre{font-family:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospac
17
22
  code{font-size:.85em;background:var(--code-bg);padding:.12em .42em;border-radius:6px}
18
23
  pre{margin:12px 0 0;background:var(--code-bg);border-radius:12px;padding:14px 16px;overflow-x:auto;font-size:.82rem;line-height:1.6}
19
24
  pre code{background:none;padding:0;font-size:inherit}
20
- :focus-visible{outline:2px solid hsl(var(--h,255) var(--as) var(--al));outline-offset:2px}
25
+ :focus-visible{outline:2px solid hsl(var(--h,255) calc(var(--as) * var(--k,1)) var(--al));outline-offset:2px}
21
26
 
22
27
  /* ── estrutura ── */
23
- .deck{position:fixed;inset:0;display:grid;grid-template-rows:auto minmax(0,1fr) auto}
28
+ .deck{position:fixed;inset:0;z-index:1;display:grid;grid-template-rows:auto minmax(0,1fr) auto}
24
29
  .topbar{display:flex;align-items:center;gap:18px;padding:16px 24px;z-index:3}
25
- .brand{font-weight:800;letter-spacing:-.01em;white-space:nowrap;max-width:20ch;overflow:hidden;text-overflow:ellipsis}
30
+ .brand{display:flex;align-items:center;gap:10px;font-weight:800;letter-spacing:-.01em;white-space:nowrap;min-width:0}
31
+ .brand-name{max-width:20ch;overflow:hidden;text-overflow:ellipsis}
32
+ .brand-mark,.brand-logo,.solo-logo{display:inline-grid;place-items:center;flex:none;background:#fff;border-radius:12px;box-shadow:0 1px 2px rgb(0 0 0/.08),0 0 0 1px rgb(0 0 0/.05)}
33
+ .brand-mark{height:34px;padding:5px 8px;border-radius:10px}
34
+ .brand-mark img{height:100%;width:auto;max-width:90px;object-fit:contain}
26
35
  .segments{flex:1;display:flex;gap:5px;align-items:center;min-width:0;height:20px}
27
36
  .seg{flex:var(--w) 1 0;min-width:6px;height:6px;border:0;padding:0;border-radius:99px;background:var(--track);cursor:pointer;overflow:hidden;position:relative;transition:height .2s}
28
37
  .seg:hover,.seg.is-current{height:9px}
29
- .seg>span{position:absolute;inset:0 auto 0 0;width:0;border-radius:inherit;background:hsl(var(--h) var(--as) var(--al));transition:width .5s cubic-bezier(.2,.7,.2,1)}
38
+ .seg>span{position:absolute;inset:0 auto 0 0;width:0;border-radius:inherit;background:hsl(var(--h) calc(var(--as) * var(--k,1)) var(--al));transition:width .5s cubic-bezier(.2,.7,.2,1)}
30
39
  .icon-btn{flex:none;width:40px;height:40px;display:grid;place-items:center;border-radius:12px;border:1px solid var(--border);background:var(--surface);cursor:pointer;color:var(--muted);transition:color .2s,transform .2s}
31
40
  .icon-btn:hover{color:var(--text);transform:translateY(-1px)}
32
41
  .icon-btn svg{width:18px;height:18px}
33
42
  .stage{position:relative;overflow:hidden}
34
43
 
35
44
  /* ── slides ── */
36
- .slide{--accent:hsl(var(--h) var(--as) var(--al));--accent-soft:hsl(var(--h) 85% 55% / .13);position:absolute;inset:0;display:flex;opacity:0;visibility:hidden;transform:translateX(56px);transition:opacity .45s ease,transform .6s cubic-bezier(.2,.7,.2,1),visibility .45s}
37
- .slide.is-before{transform:translateX(-56px)}
38
- .slide.is-active{opacity:1;visibility:visible;transform:none}
39
- .slide::before,.slide::after{content:"";position:absolute;border-radius:50%;pointer-events:none}
40
- .slide::before{width:72vmax;height:72vmax;right:-30vmax;top:-38vmax;background:radial-gradient(circle,hsl(var(--h) 90% 62% / .17),transparent 62%)}
41
- .slide::after{width:50vmax;height:50vmax;left:-24vmax;bottom:-30vmax;background:radial-gradient(circle,hsl(calc(var(--h) + 50) 90% 62% / .10),transparent 62%)}
45
+ .slide{--accent:hsl(var(--h) calc(var(--as) * var(--k,1)) var(--al));--accent-soft:hsl(var(--h) calc(85% * var(--k,1)) 55% / .13);position:absolute;inset:0;display:flex;opacity:0;visibility:hidden;transform:translateX(72px) scale(.97);filter:blur(6px);transition:opacity .5s ease,transform .75s cubic-bezier(.16,1,.3,1),filter .5s ease,visibility .5s}
46
+ .slide.is-before{transform:translateX(-72px) scale(.97)}
47
+ .slide.is-active{opacity:1;visibility:visible;transform:none;filter:none}
42
48
  .slide-inner{position:relative;z-index:1;margin:auto;width:100%;max-width:1080px;max-height:100%;overflow-y:auto;padding:24px 40px 32px;scrollbar-width:thin;scrollbar-color:transparent transparent}
43
49
  .slide-inner:hover{scrollbar-color:var(--border) transparent}
44
50
  .slide-inner::-webkit-scrollbar{width:8px}.slide-inner::-webkit-scrollbar-thumb{background:transparent;border-radius:8px}.slide-inner:hover::-webkit-scrollbar-thumb{background:var(--border)}.slide-inner::-webkit-scrollbar-track{background:transparent}
@@ -51,16 +57,48 @@ pre code{background:none;padding:0;font-size:inherit}
51
57
  .statement.small{font-size:clamp(1.15rem,.95rem + .9vw,1.6rem);max-width:40ch;margin:22px 0 0}
52
58
  .mini-label,.label{display:block;font-size:.72rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);margin:0 0 10px}
53
59
 
54
- /* entrada dos elementos */
55
- .slide.is-active .reveal>*{animation:rise .6s cubic-bezier(.2,.7,.2,1) both}
56
- .reveal>*:nth-child(2){animation-delay:.06s!important}.reveal>*:nth-child(3){animation-delay:.12s!important}.reveal>*:nth-child(4){animation-delay:.18s!important}.reveal>*:nth-child(5){animation-delay:.24s!important}.reveal>*:nth-child(6){animation-delay:.3s!important}.reveal>*:nth-child(7){animation-delay:.36s!important}.reveal>*:nth-child(8){animation-delay:.42s!important}
57
- @keyframes rise{from{opacity:0;transform:translateY(16px)}}
60
+ /* entrada dos elementos: cabeçalho primeiro, depois os blocos em cascata (--i vem do JS) */
61
+ .slide.is-active .slide-inner>.kicker{animation:kick-in .6s cubic-bezier(.16,1,.3,1) .08s both}
62
+ .slide.is-active .slide-inner>.title,.slide.is-active .welcome>.title,.slide.is-active .finale>.title{animation:title-in .9s cubic-bezier(.16,1,.3,1) .12s both}
63
+ .slide.is-active .slide-inner>.lede,.slide.is-active .slide-inner>.statement,.slide.is-active .slide-inner>.mini-label{animation:rise .7s cubic-bezier(.16,1,.3,1) .22s both}
64
+ .slide.is-active .reveal>*{animation:rise .75s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(.28s + var(--i,0) * 70ms)}
65
+ .slide.is-active .welcome>*:not(.title):not(.brand-logo),.slide.is-active .finale>*:not(.title):not(.party){animation:rise .8s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(.1s + var(--i,0) * 80ms)}
66
+ .slide.is-active .tour-step>*{animation:rise .75s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(.15s + var(--i,0) * 120ms)}
67
+ .slide.is-active .bignum{animation:num-in 1.1s cubic-bezier(.16,1,.3,1) .1s both}
68
+ @keyframes rise{from{opacity:0;translate:0 22px;scale:.97}}
69
+ @keyframes kick-in{from{opacity:0;translate:-22px 0}}
70
+ @keyframes title-in{from{opacity:0;translate:0 28px;filter:blur(12px);letter-spacing:-.01em}}
71
+ @keyframes num-in{from{opacity:0;scale:1.6;filter:blur(10px)}}
72
+
73
+ /* fundo vivo: manchas de cor que derivam devagar e mudam de tom junto com o capítulo */
74
+ .backdrop{position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none;transition:--bh 1.2s ease}
75
+ .backdrop i{position:absolute;border-radius:50%;width:74vmax;height:74vmax;right:-30vmax;top:-38vmax;background:radial-gradient(circle,hsl(var(--bh) calc(90% * var(--k,1)) 62% / .2),transparent 62%);animation:drift 24s ease-in-out infinite alternate}
76
+ .backdrop i:nth-child(2){right:auto;top:auto;left:-26vmax;bottom:-34vmax;width:56vmax;height:56vmax;background:radial-gradient(circle,hsl(var(--h2,calc(var(--bh) + 50)) calc(90% * var(--k,1)) 62% / .13),transparent 62%);animation-duration:30s;animation-direction:alternate-reverse}
77
+ .backdrop i:nth-child(3){right:auto;top:38%;left:34%;width:40vmax;height:40vmax;background:radial-gradient(circle,hsl(calc(var(--bh) - 40) calc(90% * var(--k,1)) 64% / .08),transparent 62%);animation-duration:36s}
78
+ @keyframes drift{0%{transform:translate(0,0) scale(1)}50%{transform:translate(-7vmax,5vmax) scale(1.1)}100%{transform:translate(5vmax,-4vmax) scale(.94)}}
79
+
80
+ /* cortina entre capítulos */
81
+ .wipe{position:absolute;inset:0;z-index:6;display:grid;place-content:center;justify-items:center;gap:4px;padding:24px;text-align:center;color:#fff;pointer-events:none;visibility:hidden;clip-path:inset(0 100% 0 0);background:linear-gradient(125deg,hsl(var(--h,255) calc(78% * var(--k,1)) var(--wl,46%)),hsl(calc(var(--h,255) + 24) calc(82% * var(--k,1)) calc(var(--wl,46%) - 10%)))}
82
+ .wipe span{font-size:clamp(4.5rem,3rem + 8vw,10rem);font-weight:800;line-height:.9;letter-spacing:-.06em;opacity:.35}
83
+ .wipe strong{font-size:clamp(1.6rem,1.2rem + 2vw,3rem);font-weight:800;letter-spacing:-.03em}
84
+ .wipe.run{visibility:visible;animation:wipe 1s cubic-bezier(.77,0,.18,1) both}
85
+ .wipe.run.back{animation-name:wipe-back}
86
+ .wipe.run>*{animation:wipe-text 1s cubic-bezier(.16,1,.3,1) both}
87
+ .wipe.run>strong{animation-delay:.04s}
88
+ @keyframes wipe{0%{clip-path:inset(0 100% 0 0)}40%,58%{clip-path:inset(0 0 0 0)}100%{clip-path:inset(0 0 0 100%)}}
89
+ @keyframes wipe-back{0%{clip-path:inset(0 0 0 100%)}40%,58%{clip-path:inset(0 0 0 0)}100%{clip-path:inset(0 100% 0 0)}}
90
+ @keyframes wipe-text{0%,22%{opacity:0;translate:0 18px;scale:.94}42%,60%{opacity:1;translate:0 0;scale:1}88%,100%{opacity:0;translate:0 -14px}}
58
91
 
59
92
  /* ── blocos ── */
60
93
  .grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(min(100%,280px),1fr))}
61
94
  .grid-2{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(min(100%,360px),1fr))}
62
95
  .stack-list,.rules,.tasks,.modules,.quiz{display:grid;gap:14px}
63
96
  .card{position:relative;background:var(--surface);border:1px solid var(--border);border-radius:20px;padding:22px;box-shadow:var(--shadow)}
97
+ /* cartões inclinam na direção do mouse e ganham um brilho que segue o cursor */
98
+ .card,.module,.task{transform:perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));transition:transform .35s cubic-bezier(.16,1,.3,1),box-shadow .3s,border-color .25s,opacity .25s}
99
+ .card:hover,.module:hover,.task:hover{box-shadow:0 2px 4px rgb(0 0 0/.05),0 18px 40px hsl(var(--h,255) calc(60% * var(--k,1)) 30% / .16)}
100
+ .card::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;opacity:0;transition:opacity .3s;background:radial-gradient(420px circle at var(--mx,50%) var(--my,50%),hsl(var(--h,255) calc(90% * var(--k,1)) 60% / .12),transparent 45%)}
101
+ .card:hover::after{opacity:1}
64
102
  .card h3{margin:0 0 6px;font-size:1.12rem;letter-spacing:-.015em;line-height:1.3}
65
103
  .card p{margin:0;color:var(--muted)}
66
104
  .card p.strong{color:var(--text);font-size:1.08rem;font-weight:600}
@@ -141,7 +179,7 @@ a.ev:hover{color:var(--accent);border-color:var(--accent)}
141
179
  .term-bar i{width:11px;height:11px;border-radius:50%;background:#ff5f57}.term-bar i:nth-child(2){background:#febc2e}.term-bar i:nth-child(3){background:#28c840}
142
180
  .cmd{display:grid;grid-template-columns:1fr auto;gap:14px;align-items:center;padding:12px 16px;border-top:1px solid rgb(255 255 255/.07)}
143
181
  .cmd code{background:none;color:inherit;font-size:.92rem;padding:0;word-break:break-all}
144
- .cmd code::before{content:"$ ";color:hsl(var(--h) 75% 66%)}
182
+ .cmd code::before{content:"$ ";color:hsl(var(--h) calc(75% * var(--k,1)) 66%)}
145
183
  .cmd p{margin:4px 0 0;color:rgb(255 255 255/.55);font-size:.86rem}
146
184
  .cmd p code{background:rgb(255 255 255/.08);padding:.1em .4em}.cmd p code::before{content:none}
147
185
  .copy{border:1px solid rgb(255 255 255/.16);background:transparent;color:inherit;border-radius:9px;padding:6px 12px;font-size:.78rem;font-weight:600;cursor:pointer}
@@ -164,10 +202,11 @@ a.ev:hover{color:var(--accent);border-color:var(--accent)}
164
202
  .gotcha .emoji{margin:0}
165
203
  .split{display:grid;gap:18px;grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr));margin-top:14px}
166
204
  .split p{color:var(--text)}
167
- .task{display:flex;gap:16px;align-items:flex-start;padding:18px 20px;border-radius:18px;background:var(--surface);border:1px solid var(--border);cursor:pointer;box-shadow:var(--shadow);transition:opacity .25s,border-color .25s}
205
+ .task{display:flex;gap:16px;align-items:flex-start;padding:18px 20px;border-radius:18px;background:var(--surface);border:1px solid var(--border);cursor:pointer;box-shadow:var(--shadow)}
168
206
  .task:hover{border-color:var(--accent)}
169
207
  .task input{appearance:none;-webkit-appearance:none;flex:none;width:26px;height:26px;margin:1px 0 0;border-radius:9px;border:2px solid var(--border);display:grid;place-items:center;cursor:pointer;transition:background .2s,border-color .2s}
170
- .task input:checked{background:var(--accent);border-color:var(--accent)}
208
+ .task input:checked{background:var(--accent);border-color:var(--accent);animation:check .45s cubic-bezier(.2,1.6,.4,1)}
209
+ @keyframes check{50%{scale:1.25}}
171
210
  .task input:checked::after{content:"✓";color:var(--on-accent);font-weight:800;font-size:.9rem}
172
211
  .task strong{display:block;font-size:1.05rem}
173
212
  .task-desc{display:block;color:var(--muted);margin-top:2px}
@@ -181,15 +220,21 @@ a.ev:hover{color:var(--accent);border-color:var(--accent)}
181
220
  @keyframes wave{0%,60%,100%{transform:rotate(0)}10%,30%{transform:rotate(14deg)}20%,40%{transform:rotate(-8deg)}50%{transform:rotate(10deg)}}
182
221
  .welcome .title{font-size:clamp(2.4rem,min(1.4rem + 4.6vw,9vh),5.2rem);max-width:16ch}
183
222
  .welcome .lede{margin-bottom:24px}
184
- .grad{background:linear-gradient(110deg,hsl(var(--h) 85% var(--al)),hsl(calc(var(--h) + 70) 85% var(--al)));-webkit-background-clip:text;background-clip:text;color:transparent}
223
+ .grad{background:linear-gradient(110deg,hsl(var(--h) calc(85% * var(--k,1)) var(--al)),hsl(var(--h2,calc(var(--h) + 70)) calc(85% * var(--k,1)) var(--al)),hsl(var(--h) calc(85% * var(--k,1)) var(--al)));background-size:200% auto;-webkit-background-clip:text;background-clip:text;color:transparent;animation:shimmer 7s linear infinite}
224
+ @keyframes shimmer{to{background-position:-200% center}}
225
+ .brand-logo{height:clamp(56px,10vh,84px);padding:10px 14px;border-radius:18px;margin-bottom:22px}
226
+ .brand-logo img{height:100%;width:auto;max-width:260px;object-fit:contain}
227
+ .slide.is-active .brand-logo{animation:logo-in .9s cubic-bezier(.2,1.5,.4,1) both,float 6s ease-in-out 1s infinite}
228
+ @keyframes logo-in{from{opacity:0;scale:.6;rotate:-8deg}}
229
+ @keyframes float{50%{translate:0 -6px}}
185
230
  .tagline{font-size:clamp(1.15rem,1rem + .7vw,1.5rem);font-weight:600;margin:0 0 14px;max-width:44ch;text-wrap:balance}
186
- .cta{display:inline-flex;align-items:center;gap:10px;padding:15px 24px;border-radius:16px;border:0;background:var(--accent);color:var(--on-accent);font-weight:800;font-size:1.02rem;cursor:pointer;box-shadow:0 10px 28px hsl(var(--h) 80% 50% / .35);transition:transform .2s,box-shadow .2s}
187
- .cta:hover{transform:translateY(-2px);box-shadow:0 14px 34px hsl(var(--h) 80% 50% / .42)}
231
+ .cta{display:inline-flex;align-items:center;gap:10px;padding:15px 24px;border-radius:16px;border:0;background:var(--accent);color:var(--on-accent);font-weight:800;font-size:1.02rem;cursor:pointer;box-shadow:0 10px 28px hsl(var(--h) calc(80% * var(--k,1)) 50% / .35);transition:transform .2s,box-shadow .2s}
232
+ .cta:hover{transform:translateY(-2px);box-shadow:0 14px 34px hsl(var(--h) calc(80% * var(--k,1)) 50% / .42)}
188
233
  .cta .arrow{transition:transform .2s}.cta:hover .arrow{transform:translateX(3px)}
189
234
  .journey{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:8px}
190
235
  .journey button{display:inline-flex;align-items:center;gap:8px;padding:6px 14px 6px 6px;border-radius:99px;background:var(--surface);border:1px solid var(--border);cursor:pointer;font-size:.86rem;font-weight:600;transition:border-color .2s,transform .2s}
191
- .journey button:hover{border-color:hsl(var(--ch) var(--as) var(--al));transform:translateY(-1px)}
192
- .journey .n{display:grid;place-items:center;width:24px;height:24px;border-radius:50%;font-size:.72rem;font-weight:800;background:hsl(var(--ch) 85% 55% / .15);color:hsl(var(--ch) var(--as) var(--al))}
236
+ .journey button:hover{border-color:hsl(var(--ch) calc(var(--as) * var(--k,1)) var(--al));transform:translateY(-1px)}
237
+ .journey .n{display:grid;place-items:center;width:24px;height:24px;border-radius:50%;font-size:.72rem;font-weight:800;background:hsl(var(--ch) calc(85% * var(--k,1)) 55% / .15);color:hsl(var(--ch) calc(var(--as) * var(--k,1)) var(--al))}
193
238
  .journey-wrap{margin-top:clamp(20px,4vh,44px)}
194
239
  .meta{margin-top:20px}
195
240
  .meta{display:flex;flex-wrap:wrap;gap:8px 16px;align-items:center;margin-top:26px;color:var(--muted);font-size:.84rem}
@@ -201,7 +246,7 @@ a.ev:hover{color:var(--accent);border-color:var(--accent)}
201
246
  @keyframes pop{from{transform:scale(.3) rotate(-20deg);opacity:0}}
202
247
  .recap{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;list-style:none;padding:0;margin:0 auto 22px;max-width:760px}
203
248
  .recap li{padding:6px 14px;border-radius:99px;background:var(--surface);border:1px solid var(--border);font-size:.86rem;font-weight:600}
204
- .recap li::before{content:"✓ ";color:hsl(var(--ch) var(--as) var(--al));font-weight:800}
249
+ .recap li::before{content:"✓ ";color:hsl(var(--ch) calc(var(--as) * var(--k,1)) var(--al));font-weight:800}
205
250
  .task-count{color:var(--muted);font-weight:600;margin:0 0 26px}
206
251
  .actions{display:flex;gap:10px;flex-wrap:wrap;justify-content:center}
207
252
  .ghost{padding:15px 22px;border-radius:16px;border:1px solid var(--border);background:var(--surface);font-weight:700;cursor:pointer}
@@ -213,7 +258,7 @@ a.ev:hover{color:var(--accent);border-color:var(--accent)}
213
258
  .controls [data-next]{justify-self:end}
214
259
  .nav-btn{display:inline-flex;align-items:center;gap:8px;padding:12px 20px;border-radius:14px;border:1px solid var(--border);background:var(--surface);font-weight:700;cursor:pointer;box-shadow:var(--shadow);transition:transform .2s,opacity .2s}
215
260
  .nav-btn:hover:not(:disabled){transform:translateY(-1px)}
216
- .nav-btn.primary{background:var(--text);color:var(--bg);border-color:var(--text)}
261
+ .nav-btn.primary{background:var(--brand-c,var(--text));color:var(--brand-on,var(--bg));border-color:var(--brand-c,var(--text))}
217
262
  .nav-btn:disabled{opacity:0;visibility:hidden}
218
263
  .where{display:flex;flex-direction:column;align-items:center;text-align:center;font-size:.8rem;color:var(--muted);line-height:1.4}
219
264
  .where strong{color:var(--text);font-size:.9rem}
@@ -228,7 +273,7 @@ a.ev:hover{color:var(--accent);border-color:var(--accent)}
228
273
  .ov-grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(min(100%,290px),1fr))}
229
274
  .ov-chapter{background:var(--surface);border:1px solid var(--border);border-radius:18px;padding:16px;box-shadow:var(--shadow)}
230
275
  .ov-chapter h3{display:flex;gap:10px;align-items:center;margin:0 0 8px;font-size:1rem}
231
- .ov-chapter h3 .n{display:grid;place-items:center;width:26px;height:26px;border-radius:9px;font-size:.78rem;background:hsl(var(--ch) 85% 55% / .15);color:hsl(var(--ch) var(--as) var(--al))}
276
+ .ov-chapter h3 .n{display:grid;place-items:center;width:26px;height:26px;border-radius:9px;font-size:.78rem;background:hsl(var(--ch) calc(85% * var(--k,1)) 55% / .15);color:hsl(var(--ch) calc(var(--as) * var(--k,1)) var(--al))}
232
277
  .ov-chapter button{display:block;width:100%;text-align:left;padding:7px 10px;border-radius:10px;border:0;background:none;cursor:pointer;color:var(--muted);font-size:.9rem;line-height:1.35}
233
278
  .ov-chapter button:hover,.ov-chapter button.is-current{background:var(--surface-2);color:var(--text)}
234
279
  .ov-chapter button.is-current{font-weight:700}
@@ -245,8 +290,32 @@ a.ev:hover{color:var(--accent);border-color:var(--accent)}
245
290
  @keyframes fall{to{transform:translate3d(var(--dx),110vh,0) rotate(var(--r))}}
246
291
 
247
292
  /* páginas de aviso */
248
- .solo-wrap{min-height:100%;display:grid;place-items:center;padding:32px 16px;--h:255;--accent:hsl(var(--h) var(--as) var(--al));--accent-soft:hsl(var(--h) 85% 55% / .13)}
249
- .solo-card{max-width:640px;width:100%;background:var(--surface);border:1px solid var(--border);border-radius:24px;padding:36px;box-shadow:var(--shadow)}
293
+ .solo-wrap{position:relative;z-index:1;min-height:100%;display:grid;place-items:center;padding:32px 16px;--accent:hsl(var(--h) calc(var(--as) * var(--k,1)) var(--al));--accent-soft:hsl(var(--h) calc(85% * var(--k,1)) 55% / .13)}
294
+ .solo-card{max-width:680px;width:100%;background:color-mix(in srgb,var(--surface) 88%,transparent);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid var(--border);border-radius:28px;padding:36px;box-shadow:var(--shadow)}
295
+ .solo-card>*{animation:rise .8s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--i,0) * 80ms)}
296
+ .solo-logo{display:grid;width:fit-content;height:56px;padding:8px 12px;border-radius:16px;margin-bottom:18px}
297
+ .solo-logo img{height:100%;width:auto;max-width:200px;object-fit:contain}
298
+ .solo-steps{list-style:none;padding:0;margin:0 0 18px;display:grid;gap:10px}
299
+ .solo-steps li{display:flex;gap:12px;align-items:center;font-weight:600}
300
+ .solo-steps b{display:grid;place-items:center;flex:none;width:28px;height:28px;border-radius:9px;background:var(--accent-soft);color:var(--accent);font-size:.82rem}
301
+ .prompt-box{position:relative;border-radius:18px;padding:3px;background:linear-gradient(120deg,var(--accent),hsl(var(--h2,calc(var(--h) + 60)) calc(85% * var(--k,1)) 60%),var(--accent));background-size:200% auto;animation:shimmer 6s linear infinite}
302
+ .prompt-text{margin:0;border-radius:15px;background:var(--surface);padding:18px 18px 70px;white-space:pre-wrap;font-size:.86rem;line-height:1.65;user-select:all;-webkit-user-select:all;cursor:text}
303
+ .copy-cta{position:absolute;right:14px;bottom:14px;padding:11px 18px;font-size:.92rem;border-radius:12px}
304
+ .solo-card .waiting{display:flex;align-items:center;gap:10px;margin:20px 0 0;font-weight:600;color:var(--muted)}
305
+ .pulse{position:relative;width:10px;height:10px;border-radius:50%;background:var(--accent)}
306
+ .pulse::after{content:"";position:absolute;inset:0;border-radius:50%;background:var(--accent);animation:ping 1.6s cubic-bezier(0,0,.2,1) infinite}
307
+ @keyframes ping{75%,100%{transform:scale(2.6);opacity:0}}
308
+ .solo-card .progress .mini-label{margin-bottom:10px}
309
+ .progress{margin-top:22px;padding-top:20px;border-top:1px solid var(--border)}
310
+ .progress-bar{height:6px;border-radius:99px;background:var(--track);overflow:hidden;margin-bottom:14px}
311
+ .progress-bar span{display:block;height:100%;border-radius:inherit;background:var(--accent);transition:width .8s cubic-bezier(.16,1,.3,1)}
312
+ .progress-list{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:6px}
313
+ .progress-list li{padding:5px 12px;border-radius:99px;border:1px solid var(--border);font-size:.8rem;font-weight:600;color:var(--muted);transition:background .4s,color .4s,border-color .4s}
314
+ .progress-list li.is-done{background:var(--accent-soft);border-color:transparent;color:var(--accent)}
315
+ .progress-list li.is-done::before{content:"✓ "}
316
+ .progress-list li.pop{animation:check .5s cubic-bezier(.2,1.6,.4,1)}
317
+ .manual{margin:18px 0 0!important;font-size:.88rem}
318
+ .error-text{white-space:pre-wrap}
250
319
  .solo-card h1{font-size:clamp(1.6rem,1.2rem + 1.4vw,2.2rem);letter-spacing:-.03em;line-height:1.15;margin:0 0 12px}
251
320
  .solo-card p{color:var(--muted);margin:0 0 20px}
252
321
  .prompt{display:flex;gap:10px;align-items:flex-start}
@@ -256,7 +325,7 @@ a.ev:hover{color:var(--accent);border-color:var(--accent)}
256
325
  /* ── telas pequenas ── */
257
326
  @media (max-width:760px){
258
327
  .topbar{padding:12px 16px;gap:10px}
259
- .brand{display:none}
328
+ .brand-name{display:none}
260
329
  .slide-inner{padding:12px 16px 28px}
261
330
  .controls{padding:10px 16px 14px;gap:8px}
262
331
  .nav-btn{padding:11px 14px}
@@ -266,6 +335,7 @@ a.ev:hover{color:var(--accent);border-color:var(--accent)}
266
335
  .bignum{font-size:4rem}
267
336
  .journey-wrap{margin-top:32px}
268
337
  .solo-card{padding:24px}
338
+ .prompt-text{padding-bottom:64px}
269
339
  }
270
340
  @media (prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}}
271
341
  `;
@@ -285,14 +355,38 @@ exports.JS = `
285
355
  var segs=[].slice.call(document.querySelectorAll('.seg'));
286
356
  var $=function(id){return document.getElementById(id)};
287
357
  var prevBtn=document.querySelector('[data-prev]'),nextBtn=document.querySelector('[data-next]');
288
- var overview=$('ok-overview'),toast=$('ok-toast'),hint=$('ok-hint');
358
+ var overview=$('ok-overview'),toast=$('ok-toast'),hint=$('ok-hint'),wipe=$('ok-wipe'),backdrop=$('ok-backdrop'),timer=0;
359
+ function reduced(){return matchMedia('(prefers-reduced-motion: reduce)').matches}
360
+
361
+ // índice de cada filho, para a entrada em cascata
362
+ [].forEach.call(document.querySelectorAll('.reveal,.welcome,.finale,.tour-step,.solo-card'),function(box){[].forEach.call(box.children,function(c,j){c.style.setProperty('--i',j)})});
363
+
364
+ function show(i){
365
+ slides.forEach(function(s,j){var on=j===i;s.classList.toggle('is-active',on);s.classList.toggle('is-before',j<i);s.setAttribute('aria-hidden',on?'false':'true');if('inert' in s)s.inert=!on});
366
+ var s=slides[i],inner=s.querySelector('.slide-inner'); if(inner) inner.scrollTop=0;
367
+ if(backdrop) backdrop.style.setProperty('--bh',s.style.getPropertyValue('--h'));
368
+ if(s.dataset.kind==='finale'&&!celebrated){celebrated=true;confetti()}
369
+ }
370
+ // cortina com o número e o nome do capítulo; o slide troca por baixo quando ela cobre a tela
371
+ function runWipe(s,back){
372
+ wipe.style.setProperty('--h',s.style.getPropertyValue('--h'));
373
+ wipe.firstElementChild.textContent=s.dataset.chapterNum||'';
374
+ wipe.lastElementChild.textContent=s.dataset.chapterName||'';
375
+ wipe.classList.remove('run','back'); void wipe.offsetWidth;
376
+ wipe.classList.add('run'); if(back) wipe.classList.add('back');
377
+ }
378
+ if(wipe) wipe.addEventListener('animationend',function(e){if(e.target===wipe)wipe.classList.remove('run','back')});
289
379
 
290
380
  function go(i){
291
381
  if(!n) return;
292
382
  i=Math.max(0,Math.min(n-1,i|0)); if(i===cur) return;
293
- slides.forEach(function(s,j){var on=j===i;s.classList.toggle('is-active',on);s.classList.toggle('is-before',j<i);s.setAttribute('aria-hidden',on?'false':'true');if('inert' in s)s.inert=!on});
383
+ var prev=cur,s=slides[i];
384
+ if(timer){clearTimeout(timer);timer=0}
294
385
  cur=i;
295
- var s=slides[i],inner=s.querySelector('.slide-inner'); if(inner) inner.scrollTop=0;
386
+ if(prev>=0&&wipe&&!reduced()&&slides[prev].dataset.chapter!==s.dataset.chapter){
387
+ runWipe(s,i<prev);
388
+ timer=setTimeout(function(){timer=0;show(i)},400);
389
+ }else show(i);
296
390
  segs.forEach(function(g){var st=+g.dataset.start,c=+g.dataset.count,p=i<st?0:i>=st+c?1:(i-st+1)/c;g.firstElementChild.style.width=(p*100)+'%';g.classList.toggle('is-current',i>=st&&i<st+c)});
297
391
  $('ok-chapter').textContent=s.dataset.chapterName;
298
392
  $('ok-count').textContent=(i+1)+' / '+n;
@@ -300,7 +394,6 @@ exports.JS = `
300
394
  [].forEach.call(document.querySelectorAll('.ov-chapter [data-go]'),function(b){b.classList.toggle('is-current',+b.dataset.go===i)});
301
395
  try{history.replaceState(null,'','#/'+(i+1))}catch(e){}
302
396
  sset('slide',String(i));
303
- if(s.dataset.kind==='finale'&&!celebrated){celebrated=true;confetti()}
304
397
  }
305
398
  function step(d){go(cur+d);if(hint)hint.classList.add('is-hidden');closeToast()}
306
399
  function openOverview(open){if(!overview)return;overview.classList.toggle('is-open',open);overview.setAttribute('aria-hidden',open?'false':'true');if(open){var c=overview.querySelector('.is-current')||overview.querySelector('button');c&&c.focus()}}
@@ -318,7 +411,10 @@ exports.JS = `
318
411
  if(el.hasAttribute('data-dismiss')) return closeToast();
319
412
  if(el.hasAttribute('data-copy')){
320
413
  var txt=el.dataset.copy,orig=el.textContent;
321
- if(navigator.clipboard) navigator.clipboard.writeText(txt).then(function(){el.textContent=el.dataset.done||'✓';setTimeout(function(){el.textContent=orig},1600)});
414
+ var done=function(){el.textContent=el.dataset.done||'✓';el.classList.add('is-copied');setTimeout(function(){el.textContent=orig;el.classList.remove('is-copied')},1800)};
415
+ // fora de HTTPS/localhost não há navigator.clipboard: cai no execCommand
416
+ var fallback=function(){var ta=document.createElement('textarea');ta.value=txt;ta.style.position='fixed';ta.style.opacity='0';document.body.appendChild(ta);ta.select();try{document.execCommand('copy');done()}catch(e){}ta.remove()};
417
+ if(navigator.clipboard&&window.isSecureContext) navigator.clipboard.writeText(txt).then(done,fallback); else fallback();
322
418
  return;
323
419
  }
324
420
  if(el.classList.contains('flip')){var f=el.classList.toggle('is-flipped');el.setAttribute('aria-pressed',f?'true':'false');return}
@@ -359,10 +455,41 @@ exports.JS = `
359
455
  boxes.forEach(function(b){b.checked=!!tasks[b.dataset.task];b.addEventListener('change',function(){tasks[b.dataset.task]=b.checked;sset('tasks',JSON.stringify(tasks));countTasks()})});
360
456
  countTasks();
361
457
 
458
+ // cartões inclinam na direção do mouse
459
+ var tilted=null;
460
+ document.addEventListener('pointermove',function(e){
461
+ if(e.pointerType!=='mouse'||reduced()) return;
462
+ var el=e.target.closest&&e.target.closest('.slide .card,.slide .module,.slide .task');
463
+ if(tilted&&tilted!==el){tilted.style.removeProperty('--rx');tilted.style.removeProperty('--ry')}
464
+ tilted=el; if(!el) return;
465
+ var r=el.getBoundingClientRect(),x=(e.clientX-r.left)/r.width,y=(e.clientY-r.top)/r.height;
466
+ el.style.setProperty('--rx',((.5-y)*5).toFixed(2)+'deg');el.style.setProperty('--ry',((x-.5)*6).toFixed(2)+'deg');
467
+ el.style.setProperty('--mx',(x*100).toFixed(1)+'%');el.style.setProperty('--my',(y*100).toFixed(1)+'%');
468
+ },{passive:true});
469
+
470
+ // páginas de espera: consultam a rota e recarregam quando o onboarding muda de estado
471
+ var state=document.body.dataset.okState;
472
+ if(state){
473
+ var poll=function(){
474
+ fetch(location.href,{cache:'no-store'}).then(function(r){return r.text()}).then(function(html){
475
+ var m=/data-ok-state="(\w+)"/.exec(html);
476
+ if(!m||m[1]!==state) return location.reload();
477
+ var box=$('ok-progress'); if(!box) return;
478
+ var next=new DOMParser().parseFromString(html,'text/html').getElementById('ok-progress');
479
+ if(!next||next.innerHTML===box.innerHTML) return;
480
+ var before={};[].forEach.call(box.querySelectorAll('.is-done'),function(li){before[li.dataset.key]=1});
481
+ box.innerHTML=next.innerHTML;
482
+ [].forEach.call(box.querySelectorAll('.is-done'),function(li){if(!before[li.dataset.key])li.classList.add('pop')});
483
+ }).catch(function(){}).then(function(){setTimeout(poll,2500)});
484
+ };
485
+ setTimeout(poll,2500);
486
+ }
487
+
362
488
  function confetti(){
363
- if(matchMedia('(prefers-reduced-motion: reduce)').matches) return;
489
+ if(reduced()) return;
490
+ var pal=(root.dataset.palette||'').split(' ').filter(Boolean);
364
491
  var box=document.createElement('div');box.className='confetti';box.setAttribute('aria-hidden','true');
365
- for(var i=0;i<120;i++){var p=document.createElement('i');p.style.left=(Math.random()*100)+'%';p.style.background='hsl('+Math.floor(Math.random()*360)+' 85% 60%)';p.style.setProperty('--dx',(Math.random()*240-120)+'px');p.style.setProperty('--r',(Math.random()*900-450)+'deg');p.style.animationDuration=(2.4+Math.random()*2.2)+'s';p.style.animationDelay=(Math.random()*.7)+'s';box.appendChild(p)}
492
+ for(var i=0;i<140;i++){var p=document.createElement('i');p.style.left=(Math.random()*100)+'%';p.style.background=pal.length&&Math.random()<.75?pal[i%pal.length]:'hsl('+Math.floor(Math.random()*360)+' 85% 60%)';p.style.setProperty('--dx',(Math.random()*240-120)+'px');p.style.setProperty('--r',(Math.random()*900-450)+'deg');p.style.animationDuration=(2.4+Math.random()*2.2)+'s';p.style.animationDelay=(Math.random()*.7)+'s';box.appendChild(p)}
366
493
  document.body.appendChild(box);setTimeout(function(){box.remove()},6000);
367
494
  }
368
495
 
@@ -374,7 +501,11 @@ exports.JS = `
374
501
 
375
502
  window.__okMermaid=function(){
376
503
  if(!window.mermaid) return;
377
- mermaid.initialize({startOnLoad:false,theme:isDark()?'dark':'neutral',securityLevel:'strict',fontFamily:'Plus Jakarta Sans, system-ui, sans-serif'});
504
+ var brand=(root.dataset.palette||'').split(' ')[0],dark=isDark();
505
+ // mistura a cor da marca com o fundo para pintar os nós sem perder a leitura do texto
506
+ function mix(hex,base,a){var c=function(h,i){return parseInt(h.substr(1+i*2,2),16)};var o='#';for(var i=0;i<3;i++)o+=('0'+Math.round(c(hex,i)*a+c(base,i)*(1-a)).toString(16)).slice(-2);return o}
507
+ var vars=brand?{primaryColor:mix(brand,dark?'#1a1918':'#ffffff',.16),primaryBorderColor:brand,lineColor:brand,primaryTextColor:dark?'#f2f0eb':'#1b1a18',secondaryColor:mix(brand,dark?'#1a1918':'#ffffff',.08),tertiaryColor:dark?'#232220':'#f3f1ec',darkMode:dark,fontFamily:'Plus Jakarta Sans, system-ui, sans-serif'}:undefined;
508
+ mermaid.initialize({startOnLoad:false,theme:brand?'base':dark?'dark':'neutral',themeVariables:vars,securityLevel:'strict',fontFamily:'Plus Jakarta Sans, system-ui, sans-serif'});
378
509
  mermaid.run({querySelector:'pre.mermaid'});
379
510
  };
380
511
  })();
@@ -118,13 +118,21 @@ declare const pt: {
118
118
  pending: {
119
119
  title: string;
120
120
  body: string;
121
+ steps: string[];
122
+ copy: string;
123
+ copied: string;
124
+ waiting: string;
125
+ progress: string;
126
+ sections: Record<string, string>;
121
127
  };
122
128
  missing: {
123
129
  title: string;
124
130
  body: string;
131
+ manual: string;
125
132
  };
126
133
  invalid: {
127
134
  title: string;
135
+ body: string;
128
136
  };
129
137
  };
130
138
  export type Copy = typeof pt;
@@ -152,13 +152,38 @@ const pt = {
152
152
  },
153
153
  pending: {
154
154
  title: "O onboarding ainda não foi gerado",
155
- body: "O arquivo existe, mas a IA ainda não o preencheu. Abra a IA que você usa neste projeto (Claude Code, Cursor, Copilot…) e envie:",
155
+ body: "O onboarding.json já existe, mas a IA ainda não o preencheu. Leva só um minuto:",
156
+ steps: [
157
+ "Copie o prompt abaixo",
158
+ "Cole na IA que você usa neste projeto (Claude Code, Cursor, Copilot…)",
159
+ "Deixe esta página aberta: ela se atualiza sozinha quando o onboarding ficar pronto",
160
+ ],
161
+ copy: "Copiar prompt",
162
+ copied: "Copiado!",
163
+ waiting: "Aguardando a IA…",
164
+ progress: "{done} de {total} seções preenchidas",
165
+ sections: {
166
+ project: "Visão geral",
167
+ business: "Negócio",
168
+ features: "Produto",
169
+ domain: "Vocabulário e regras",
170
+ stack: "Stack",
171
+ architecture: "Arquitetura",
172
+ gettingStarted: "Como rodar",
173
+ conventions: "Convenções",
174
+ tours: "Tour pelo código",
175
+ gotchas: "Cuidados",
176
+ decisions: "Decisões",
177
+ firstTasks: "Primeira missão",
178
+ brand: "Cores e logo",
179
+ },
156
180
  },
157
181
  missing: {
158
- title: "Arquivo de onboarding não encontrado",
159
- body: "Rode o comando abaixo na raiz do projeto para criar o arquivo:",
182
+ title: "Vamos criar o onboarding deste projeto",
183
+ body: "Ainda não existe um onboarding.json aqui. A sua IA cria e preenche o arquivo:",
184
+ manual: "Prefere começar à mão? Rode na raiz do projeto:",
160
185
  },
161
- invalid: { title: "O arquivo de onboarding tem um erro" },
186
+ invalid: { title: "O arquivo de onboarding tem um erro", body: "Se a IA ainda está escrevendo o arquivo, espere: esta página se atualiza sozinha." },
162
187
  };
163
188
  const en = {
164
189
  chapters: {
@@ -280,10 +305,38 @@ const en = {
280
305
  },
281
306
  pending: {
282
307
  title: "Onboarding has not been generated yet",
283
- body: "The file exists but your AI has not filled it in yet. Open the AI you use in this project (Claude Code, Cursor, Copilot…) and send:",
308
+ body: "onboarding.json exists, but your AI has not filled it in yet. It only takes a minute:",
309
+ steps: [
310
+ "Copy the prompt below",
311
+ "Paste it into the AI you use in this project (Claude Code, Cursor, Copilot…)",
312
+ "Keep this page open: it refreshes by itself when the onboarding is ready",
313
+ ],
314
+ copy: "Copy prompt",
315
+ copied: "Copied!",
316
+ waiting: "Waiting for the AI…",
317
+ progress: "{done} of {total} sections filled",
318
+ sections: {
319
+ project: "Overview",
320
+ business: "Business",
321
+ features: "Product",
322
+ domain: "Vocabulary and rules",
323
+ stack: "Stack",
324
+ architecture: "Architecture",
325
+ gettingStarted: "Running it",
326
+ conventions: "Conventions",
327
+ tours: "Code tour",
328
+ gotchas: "Watch out",
329
+ decisions: "Decisions",
330
+ firstTasks: "First mission",
331
+ brand: "Colors and logo",
332
+ },
333
+ },
334
+ missing: {
335
+ title: "Let's create this project's onboarding",
336
+ body: "There is no onboarding.json here yet. Your AI creates and fills it in:",
337
+ manual: "Prefer to start by hand? Run at the project root:",
284
338
  },
285
- missing: { title: "Onboarding file not found", body: "Run this command at the project root to create it:" },
286
- invalid: { title: "The onboarding file has an error" },
339
+ invalid: { title: "The onboarding file has an error", body: "If the AI is still writing the file, hang on: this page refreshes by itself." },
287
340
  };
288
341
  function copyFor(language) {
289
342
  return language && !language.toLowerCase().startsWith("pt") ? en : pt;
@@ -1,5 +1,9 @@
1
1
  import type { OnboardingData } from "../types";
2
2
  export { escapeHtml } from "./html";
3
- export declare function renderMissingPage(): string;
4
- export declare function renderErrorPage(message: string): string;
5
- export declare function renderOnboarding(data: OnboardingData): string;
3
+ export interface RenderOptions {
4
+ /** Raiz do projeto: usada para detectar cores e logo quando o JSON não traz `brand`. */
5
+ root?: string;
6
+ }
7
+ export declare function renderMissingPage(root?: string): string;
8
+ export declare function renderErrorPage(message: string, root?: string): string;
9
+ export declare function renderOnboarding(data: OnboardingData, options?: RenderOptions): string;