sms-verification-api 0.9.1

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.
Files changed (50) hide show
  1. package/.env.example +20 -0
  2. package/DEPLOYMENT.md +151 -0
  3. package/README.md +475 -0
  4. package/docs/app/(home)/layout.tsx +7 -0
  5. package/docs/app/(home)/page.tsx +38 -0
  6. package/docs/app/docs/[[...slug]]/page.tsx +59 -0
  7. package/docs/app/docs/layout.tsx +12 -0
  8. package/docs/app/docs-og/[...slug]/route.ts +24 -0
  9. package/docs/app/globals.css +587 -0
  10. package/docs/app/layout.config.tsx +13 -0
  11. package/docs/app/layout.tsx +27 -0
  12. package/docs/app/logo.tsx +35 -0
  13. package/docs/content/docs/API_AUTHENTICATION.md +91 -0
  14. package/docs/content/docs/DEPLOYMENT.md +181 -0
  15. package/docs/content/docs/api/post.mdx +35 -0
  16. package/docs/content/docs/api/verify.mdx +34 -0
  17. package/docs/content/docs/meta.json +8 -0
  18. package/docs/content/docs/verify-legal-name.md +339 -0
  19. package/docs/lib/source.ts +14 -0
  20. package/docs/mdx-components.tsx +12 -0
  21. package/docs/next.config.mjs +51 -0
  22. package/docs/openapi.json +329 -0
  23. package/docs/package.json +37 -0
  24. package/docs/postcss.config.mjs +5 -0
  25. package/docs/scripts/generate-docs.mjs +23 -0
  26. package/docs/source.config.ts +5 -0
  27. package/docs/tsconfig.json +29 -0
  28. package/docs/worker.js +35 -0
  29. package/docs/wrangler.toml +26 -0
  30. package/examples/client.js +119 -0
  31. package/examples/demo.html +325 -0
  32. package/examples/libphonenumber-example.js +120 -0
  33. package/openapi.json +329 -0
  34. package/package.json +71 -0
  35. package/scripts/deploy.sh +63 -0
  36. package/src/identity-verification-server.ts +553 -0
  37. package/src/index.js +8 -0
  38. package/src/sns.js +236 -0
  39. package/src/verify-phone-server.js +448 -0
  40. package/src/verify-phone.ts +551 -0
  41. package/test/api.test.js +201 -0
  42. package/test/integration.test.js +152 -0
  43. package/test/metadata-test.js +73 -0
  44. package/test/server.test.js +143 -0
  45. package/test/setup.js +32 -0
  46. package/test/utils.test.js +186 -0
  47. package/test/verify.test.js +23 -0
  48. package/test/voip.test.js +112 -0
  49. package/vitest.config.js +10 -0
  50. package/wrangler.toml +27 -0
@@ -0,0 +1,59 @@
1
+ import { source } from '@/lib/source';
2
+ import {
3
+ DocsBody,
4
+ DocsDescription,
5
+ DocsPage,
6
+ DocsTitle,
7
+ } from 'fumadocs-ui/page';
8
+ import { notFound } from 'next/navigation';
9
+ import { getMDXComponents } from '@/mdx-components';
10
+ import type { Metadata } from 'next';
11
+ import React from 'react';
12
+
13
+ export default async function Page(props: {
14
+ params: Promise<{ slug?: string[] }>;
15
+ }) {
16
+ const params = await props.params;
17
+ const page = source.getPage(params.slug);
18
+
19
+ if (!page) {
20
+ notFound();
21
+ }
22
+
23
+ const MDX = page.data.body;
24
+
25
+ return (
26
+ <DocsPage toc={page.data.toc} full={page.data.full}>
27
+ <DocsTitle>{page.data.title}</DocsTitle>
28
+ <DocsDescription>{page.data.description}</DocsDescription>
29
+ <DocsBody>
30
+ {MDX && React.createElement(MDX, { components: getMDXComponents() })}
31
+ </DocsBody>
32
+ </DocsPage>
33
+ );
34
+ }
35
+
36
+ export async function generateStaticParams() {
37
+ return source.generateParams();
38
+ }
39
+
40
+ export async function generateMetadata(props: {
41
+ params: Promise<{ slug?: string[] }>;
42
+ }) {
43
+ const params = await props.params;
44
+ const page = source.getPage(params.slug);
45
+ if (!page) notFound();
46
+ const image = ['/docs-og', ...(params.slug ?? []), 'image.png'].join('/');
47
+
48
+ return {
49
+ title: page.data.title,
50
+ description: page.data.description,
51
+ openGraph: {
52
+ images: image,
53
+ },
54
+ twitter: {
55
+ card: 'summary_large_image',
56
+ images: image,
57
+ },
58
+ } satisfies Metadata;
59
+ }
@@ -0,0 +1,12 @@
1
+ import { source } from '@/lib/source';
2
+ import { DocsLayout } from 'fumadocs-ui/layouts/notebook';
3
+ import type { ReactNode } from 'react';
4
+ import { baseOptions } from '@/app/layout.config';
5
+
6
+ export default function RootDocsLayout({ children }: { children: ReactNode }) {
7
+ return (
8
+ <DocsLayout tree={source.pageTree} {...baseOptions}>
9
+ {children}
10
+ </DocsLayout>
11
+ );
12
+ }
@@ -0,0 +1,24 @@
1
+ import { generateOGImage } from 'fumadocs-ui/og';
2
+ import { source } from '@/lib/source';
3
+ import { notFound } from 'next/navigation';
4
+
5
+ export async function GET(
6
+ _req: Request,
7
+ { params }: { params: Promise<{ slug: string[] }> },
8
+ ) {
9
+ const { slug } = await params;
10
+ const page = source.getPage(slug.slice(0, -1));
11
+ if (!page) notFound();
12
+
13
+ return generateOGImage({
14
+ title: page.data.title,
15
+ description: page.data.description,
16
+ });
17
+ }
18
+
19
+ export function generateStaticParams() {
20
+ return source.generateParams().map((page) => ({
21
+ ...page,
22
+ slug: [...page.slug, 'image.png'],
23
+ }));
24
+ }
@@ -0,0 +1,587 @@
1
+ @import "tailwindcss";
2
+ @import 'fumadocs-ui/css/shadcn.css';
3
+ @import "fumadocs-ui/css/preset.css";
4
+ @import 'fumadocs-openapi/css/preset.css';
5
+
6
+ /* Custom Refined Beige & Sand Desert Paper Theme Variables */
7
+ :root {
8
+ --color-fd-background: hsl(42, 35%, 97%);
9
+ --color-fd-primary: hsl(38, 45%, 52%);
10
+ --color-fd-accent: hsl(32, 55%, 62%);
11
+ --color-fd-muted: hsl(42, 25%, 92%);
12
+ --color-fd-border: hsl(38, 30%, 82%);
13
+ --color-fd-text: hsl(28, 30%, 22%);
14
+ --color-fd-text-muted: hsl(28, 25%, 42%);
15
+
16
+ /* Layout customization */
17
+ --fd-layout-width: 1400px;
18
+ }
19
+
20
+ .dark {
21
+ --color-fd-background: hsl(28, 20%, 14%);
22
+ --color-fd-primary: hsl(38, 45%, 65%);
23
+ --color-fd-accent: hsl(32, 55%, 75%);
24
+ --color-fd-muted: hsl(28, 25%, 20%);
25
+ --color-fd-border: hsl(28, 30%, 28%);
26
+ --color-fd-text: hsl(42, 25%, 88%);
27
+ --color-fd-text-muted: hsl(42, 20%, 72%);
28
+ }
29
+
30
+ /* Sidebar Glass Effect Override - Comprehensive */
31
+ .bg-sidebar,
32
+ [data-sidebar="sidebar"],
33
+ [data-slot="sidebar"],
34
+ [data-slot="sidebar-inner"],
35
+ div[class*="bg-sidebar"],
36
+ div[class*="sidebar"],
37
+ [data-collapsible="offcanvas"],
38
+ [data-state="collapsed"],
39
+ [data-slot="sidebar-container"],
40
+ [data-slot="sidebar-gap"] {
41
+ background-color: rgba(255, 255, 255, 0.25) !important;
42
+ backdrop-filter: blur(20px) !important;
43
+ -webkit-backdrop-filter: blur(20px) !important;
44
+ border: 1px solid rgba(255, 255, 255, 0.3) !important;
45
+ box-shadow:
46
+ 0 8px 32px rgba(0, 0, 0, 0.15),
47
+ inset 0 1px 0 rgba(255, 255, 255, 0.3) !important;
48
+ }
49
+
50
+ .dark .bg-sidebar,
51
+ .dark [data-sidebar="sidebar"],
52
+ .dark [data-slot="sidebar"],
53
+ .dark [data-slot="sidebar-inner"],
54
+ .dark div[class*="bg-sidebar"],
55
+ .dark div[class*="sidebar"],
56
+ .dark [data-collapsible="offcanvas"],
57
+ .dark [data-state="collapsed"],
58
+ .dark [data-slot="sidebar-container"],
59
+ .dark [data-slot="sidebar-gap"] {
60
+ background-color: rgba(30, 41, 59, 0.35) !important;
61
+ backdrop-filter: blur(24px) !important;
62
+ -webkit-backdrop-filter: blur(24px) !important;
63
+ border: 1px solid rgba(148, 163, 184, 0.2) !important;
64
+ box-shadow:
65
+ 0 8px 32px rgba(0, 0, 0, 0.4),
66
+ inset 0 1px 0 rgba(255, 255, 255, 0.15) !important;
67
+ }
68
+
69
+ /* Enhanced Sidebar Container Glass Effect */
70
+ [data-slot="sidebar-inner"],
71
+ [data-sidebar="sidebar"],
72
+ [data-collapsible="offcanvas"] [data-slot="sidebar-inner"],
73
+ [data-state="collapsed"] [data-slot="sidebar-inner"] {
74
+ background-color: rgba(255, 255, 255, 0.2) !important;
75
+ backdrop-filter: blur(16px) !important;
76
+ -webkit-backdrop-filter: blur(16px) !important;
77
+ border: 1px solid rgba(255, 255, 255, 0.25) !important;
78
+ box-shadow:
79
+ 0 4px 16px rgba(0, 0, 0, 0.1),
80
+ inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
81
+ }
82
+
83
+ .dark [data-slot="sidebar-inner"],
84
+ .dark [data-sidebar="sidebar"],
85
+ .dark [data-collapsible="offcanvas"] [data-slot="sidebar-inner"],
86
+ .dark [data-state="collapsed"] [data-slot="sidebar-inner"] {
87
+ background-color: rgba(30, 41, 59, 0.25) !important;
88
+ backdrop-filter: blur(20px) !important;
89
+ -webkit-backdrop-filter: blur(20px) !important;
90
+ border: 1px solid rgba(148, 163, 184, 0.15) !important;
91
+ box-shadow:
92
+ 0 4px 16px rgba(0, 0, 0, 0.25),
93
+ inset 0 1px 0 rgba(255, 255, 255, 0.1) !important;
94
+ }
95
+
96
+ /* Mobile Sidebar Glass Effect */
97
+ [data-mobile="true"],
98
+ [data-mobile="true"] [data-sidebar="sidebar"],
99
+ [data-mobile="true"] [data-slot="sidebar"],
100
+ [data-collapsible="offcanvas"][data-mobile="true"],
101
+ [data-state="collapsed"][data-mobile="true"] {
102
+ background-color: rgba(255, 255, 255, 0.3) !important;
103
+ backdrop-filter: blur(24px) !important;
104
+ -webkit-backdrop-filter: blur(24px) !important;
105
+ border: 1px solid rgba(255, 255, 255, 0.35) !important;
106
+ box-shadow:
107
+ 0 12px 40px rgba(0, 0, 0, 0.2),
108
+ inset 0 1px 0 rgba(255, 255, 255, 0.4) !important;
109
+ }
110
+
111
+ .dark [data-mobile="true"],
112
+ .dark [data-mobile="true"] [data-sidebar="sidebar"],
113
+ .dark [data-mobile="true"] [data-slot="sidebar"],
114
+ .dark [data-collapsible="offcanvas"][data-mobile="true"],
115
+ .dark [data-state="collapsed"][data-mobile="true"] {
116
+ background-color: rgba(30, 41, 59, 0.4) !important;
117
+ backdrop-filter: blur(28px) !important;
118
+ -webkit-backdrop-filter: blur(28px) !important;
119
+ border: 1px solid rgba(148, 163, 184, 0.25) !important;
120
+ box-shadow:
121
+ 0 12px 40px rgba(0, 0, 0, 0.5),
122
+ inset 0 1px 0 rgba(255, 255, 255, 0.15) !important;
123
+ }
124
+
125
+ /* Force override for any sidebar-related elements */
126
+ *[class*="sidebar"],
127
+ *[data-sidebar],
128
+ *[data-slot*="sidebar"] {
129
+ background-color: rgba(255, 255, 255, 0.2) !important;
130
+ backdrop-filter: blur(18px) !important;
131
+ -webkit-backdrop-filter: blur(18px) !important;
132
+ }
133
+
134
+ .dark *[class*="sidebar"],
135
+ .dark *[data-sidebar],
136
+ .dark *[data-slot*="sidebar"] {
137
+ background-color: rgba(30, 41, 59, 0.3) !important;
138
+ backdrop-filter: blur(22px) !important;
139
+ -webkit-backdrop-filter: blur(22px) !important;
140
+ }
141
+
142
+ /* 3D Glassmorphism Effects */
143
+ .glass-3d {
144
+ background-color: rgba(255, 255, 255, 0.2);
145
+ backdrop-filter: blur(24px);
146
+ border: 1px solid rgba(255, 255, 255, 0.4);
147
+ border-radius: 1rem;
148
+ transform-style: preserve-3d;
149
+ perspective: 1000px;
150
+ box-shadow:
151
+ 0 8px 32px rgba(0, 0, 0, 0.1),
152
+ inset 0 1px 0 rgba(255, 255, 255, 0.2);
153
+ }
154
+
155
+ .glass-3d-hover {
156
+ background-color: rgba(255, 255, 255, 0.2);
157
+ backdrop-filter: blur(24px);
158
+ border: 1px solid rgba(255, 255, 255, 0.4);
159
+ border-radius: 1rem;
160
+ transform-style: preserve-3d;
161
+ perspective: 1000px;
162
+ box-shadow:
163
+ 0 8px 32px rgba(0, 0, 0, 0.1),
164
+ inset 0 1px 0 rgba(255, 255, 255, 0.2);
165
+ transition: all 0.5s ease-out;
166
+ transform: translateZ(0);
167
+ }
168
+
169
+ .glass-3d-hover:hover {
170
+ background-color: rgba(255, 255, 255, 0.3);
171
+ box-shadow:
172
+ 0 20px 40px rgba(0, 0, 0, 0.15),
173
+ 0 0 0 1px rgba(255, 255, 255, 0.3),
174
+ inset 0 1px 0 rgba(255, 255, 255, 0.3);
175
+ transform: translateZ(20px) rotateX(5deg) rotateY(5deg);
176
+ }
177
+
178
+ /* Advanced Hover Animations */
179
+ .hover-lift {
180
+ transition: all 0.3s ease-out;
181
+ transform: translateY(0) scale(1);
182
+ }
183
+
184
+ .hover-lift:hover {
185
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
186
+ transform: translateY(-8px) scale(1.02);
187
+ }
188
+
189
+ .hover-glow {
190
+ transition: all 0.3s ease-out;
191
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
192
+ }
193
+
194
+ .hover-glow:hover {
195
+ box-shadow:
196
+ 0 10px 25px rgba(0, 0, 0, 0.15),
197
+ 0 0 0 1px rgba(255, 255, 255, 0.1),
198
+ 0 0 20px rgba(255, 255, 255, 0.1);
199
+ }
200
+
201
+ .hover-rotate {
202
+ transition: all 0.5s ease-out;
203
+ transform: rotate(0deg) scale(1);
204
+ }
205
+
206
+ .hover-rotate:hover {
207
+ transform: rotate(2deg) scale(1.05);
208
+ }
209
+
210
+ .hover-bounce {
211
+ transition: all 0.3s ease-out;
212
+ animation: none;
213
+ }
214
+
215
+ .hover-bounce:hover {
216
+ animation: bounce 0.6s ease-in-out;
217
+ }
218
+
219
+ .hover-pulse {
220
+ transition: all 0.3s ease-out;
221
+ }
222
+
223
+ .hover-pulse:hover {
224
+ animation: pulse 1s ease-in-out infinite;
225
+ }
226
+
227
+ .hover-shake {
228
+ transition: all 0.3s ease-out;
229
+ }
230
+
231
+ .hover-shake:hover {
232
+ animation: shake 0.5s ease-in-out;
233
+ }
234
+
235
+ /* 3D Card Effects */
236
+ .card-3d {
237
+ transition: all 0.5s ease-out;
238
+ transform-style: preserve-3d;
239
+ perspective: 1000px;
240
+ }
241
+
242
+ .card-3d:hover {
243
+ transform: rotateX(10deg) rotateY(10deg) translateZ(20px);
244
+ }
245
+
246
+ /* NEW: Gradient Animations */
247
+ .gradient-animate {
248
+ background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
249
+ background-size: 400% 400%;
250
+ animation: gradientShift 3s ease infinite;
251
+ }
252
+
253
+ .gradient-animate-hover {
254
+ background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
255
+ background-size: 400% 400%;
256
+ transition: all 0.3s ease;
257
+ }
258
+
259
+ .gradient-animate-hover:hover {
260
+ animation: gradientShift 2s ease infinite;
261
+ transform: scale(1.05);
262
+ }
263
+
264
+ /* NEW: Morphing Effects */
265
+ .morph {
266
+ transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
267
+ border-radius: 1rem;
268
+ }
269
+
270
+ .morph:hover {
271
+ border-radius: 2rem;
272
+ transform: scale(1.1) rotate(5deg);
273
+ }
274
+
275
+ /* NEW: Particle Effect */
276
+ .particle-effect {
277
+ position: relative;
278
+ overflow: hidden;
279
+ }
280
+
281
+ .particle-effect::before {
282
+ content: '';
283
+ position: absolute;
284
+ top: 0;
285
+ left: -100%;
286
+ width: 100%;
287
+ height: 100%;
288
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
289
+ transition: left 0.5s;
290
+ }
291
+
292
+ .particle-effect:hover::before {
293
+ left: 100%;
294
+ }
295
+
296
+ /* NEW: Neon Glow Effect */
297
+ .neon-glow {
298
+ transition: all 0.3s ease;
299
+ box-shadow: 0 0 5px rgba(255, 255, 255, 0.5);
300
+ }
301
+
302
+ .neon-glow:hover {
303
+ box-shadow:
304
+ 0 0 20px rgba(255, 255, 255, 0.8),
305
+ 0 0 40px rgba(255, 255, 255, 0.6),
306
+ 0 0 60px rgba(255, 255, 255, 0.4);
307
+ transform: scale(1.05);
308
+ }
309
+
310
+ /* NEW: Magnetic Effect */
311
+ .magnetic {
312
+ transition: all 0.3s ease;
313
+ transform: translate(0, 0);
314
+ }
315
+
316
+ .magnetic:hover {
317
+ transform: translate(5px, -5px);
318
+ box-shadow: -5px 5px 15px rgba(0, 0, 0, 0.2);
319
+ }
320
+
321
+ /* NEW: Elastic Bounce */
322
+ .elastic-bounce {
323
+ transition: all 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55);
324
+ }
325
+
326
+ .elastic-bounce:hover {
327
+ transform: scale(1.2) rotate(10deg);
328
+ }
329
+
330
+ /* NEW: Slide In Effect */
331
+ .slide-in {
332
+ transition: all 0.4s ease;
333
+ transform: translateX(-100%);
334
+ }
335
+
336
+ .slide-in:hover {
337
+ transform: translateX(0);
338
+ opacity: 1;
339
+ }
340
+
341
+ /* NEW: Flip Card Effect */
342
+ .flip-card {
343
+ perspective: 1000px;
344
+ transform-style: preserve-3d;
345
+ }
346
+
347
+ .flip-card-inner {
348
+ transition: transform 0.6s;
349
+ transform-style: preserve-3d;
350
+ }
351
+
352
+ .flip-card:hover .flip-card-inner {
353
+ transform: rotateY(180deg);
354
+ }
355
+
356
+ .flip-card-front, .flip-card-back {
357
+ backface-visibility: hidden;
358
+ position: absolute;
359
+ top: 0;
360
+ left: 0;
361
+ width: 100%;
362
+ height: 100%;
363
+ }
364
+
365
+ .flip-card-back {
366
+ transform: rotateY(180deg);
367
+ }
368
+
369
+ /* NEW: Typewriter Effect */
370
+ .typewriter {
371
+ overflow: hidden;
372
+ border-right: 2px solid;
373
+ white-space: nowrap;
374
+ animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite;
375
+ }
376
+
377
+ /* NEW: Breathing Effect */
378
+ .breathing {
379
+ animation: breathing 4s ease-in-out infinite;
380
+ }
381
+
382
+ /* NEW: Ripple Effect */
383
+ .ripple {
384
+ position: relative;
385
+ overflow: hidden;
386
+ }
387
+
388
+ .ripple::after {
389
+ content: '';
390
+ position: absolute;
391
+ top: 50%;
392
+ left: 50%;
393
+ width: 0;
394
+ height: 0;
395
+ border-radius: 50%;
396
+ background: rgba(255, 255, 255, 0.3);
397
+ transform: translate(-50%, -50%);
398
+ transition: width 0.6s, height 0.6s;
399
+ }
400
+
401
+ .ripple:hover::after {
402
+ width: 300px;
403
+ height: 300px;
404
+ }
405
+
406
+ /* NEW: Glitch Effect */
407
+ .glitch {
408
+ position: relative;
409
+ }
410
+
411
+ .glitch::before,
412
+ .glitch::after {
413
+ content: attr(data-text);
414
+ position: absolute;
415
+ top: 0;
416
+ left: 0;
417
+ width: 100%;
418
+ height: 100%;
419
+ }
420
+
421
+ .glitch::before {
422
+ animation: glitch-1 0.5s infinite;
423
+ color: #ff0000;
424
+ z-index: -1;
425
+ }
426
+
427
+ .glitch::after {
428
+ animation: glitch-2 0.5s infinite;
429
+ color: #00ff00;
430
+ z-index: -2;
431
+ }
432
+
433
+ /* Floating Animation */
434
+ @keyframes float {
435
+ 0%, 100% { transform: translateY(0px); }
436
+ 50% { transform: translateY(-10px); }
437
+ }
438
+
439
+ .hover-float {
440
+ transition: all 0.3s ease-out;
441
+ }
442
+
443
+ .hover-float:hover {
444
+ animation: float 2s ease-in-out infinite;
445
+ }
446
+
447
+ /* Shake Animation */
448
+ @keyframes shake {
449
+ 0%, 100% { transform: translateX(0); }
450
+ 10%, 30%, 50%, 70%, 90% { transform: translateX(-2px); }
451
+ 20%, 40%, 60%, 80% { transform: translateX(2px); }
452
+ }
453
+
454
+ /* Bounce Animation */
455
+ @keyframes bounce {
456
+ 0%, 20%, 53%, 80%, 100% { transform: translate3d(0,0,0); }
457
+ 40%, 43% { transform: translate3d(0,-8px,0); }
458
+ 70% { transform: translate3d(0,-4px,0); }
459
+ 90% { transform: translate3d(0,-2px,0); }
460
+ }
461
+
462
+ /* Pulse Animation */
463
+ @keyframes pulse {
464
+ 0%, 100% { opacity: 1; }
465
+ 50% { opacity: 0.8; }
466
+ }
467
+
468
+ /* NEW: Gradient Shift Animation */
469
+ @keyframes gradientShift {
470
+ 0% { background-position: 0% 50%; }
471
+ 50% { background-position: 100% 50%; }
472
+ 100% { background-position: 0% 50%; }
473
+ }
474
+
475
+ /* NEW: Typewriter Animation */
476
+ @keyframes typing {
477
+ from { width: 0; }
478
+ to { width: 100%; }
479
+ }
480
+
481
+ @keyframes blink-caret {
482
+ from, to { border-color: transparent; }
483
+ 50% { border-color: currentColor; }
484
+ }
485
+
486
+ /* NEW: Breathing Animation */
487
+ @keyframes breathing {
488
+ 0%, 100% { transform: scale(1); }
489
+ 50% { transform: scale(1.05); }
490
+ }
491
+
492
+ /* NEW: Glitch Animations */
493
+ @keyframes glitch-1 {
494
+ 0%, 100% { transform: translate(0); }
495
+ 20% { transform: translate(-2px, 2px); }
496
+ 40% { transform: translate(-2px, -2px); }
497
+ 60% { transform: translate(2px, 2px); }
498
+ 80% { transform: translate(2px, -2px); }
499
+ }
500
+
501
+ @keyframes glitch-2 {
502
+ 0%, 100% { transform: translate(0); }
503
+ 20% { transform: translate(2px, -2px); }
504
+ 40% { transform: translate(2px, 2px); }
505
+ 60% { transform: translate(-2px, -2px); }
506
+ 80% { transform: translate(-2px, 2px); }
507
+ }
508
+
509
+ /* Hover Animation Utility */
510
+ .hover-animate {
511
+ transition: all 0.3s ease-in-out;
512
+ }
513
+
514
+ .hover-animate:hover {
515
+ transform: scale(1.05);
516
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
517
+ transform: translateY(-4px);
518
+ }
519
+
520
+ /* Enhanced typography for MDX content */
521
+ .prose {
522
+ color: var(--color-fd-text);
523
+ }
524
+
525
+ .prose h1, .prose h2, .prose h3, .prose h4, .prose h5, .prose h6 {
526
+ color: var(--color-fd-text);
527
+ }
528
+
529
+ .prose a {
530
+ color: var(--color-fd-primary);
531
+ }
532
+
533
+ .prose a:hover {
534
+ color: var(--color-fd-accent);
535
+ }
536
+
537
+ /* Custom refined beige accent for code blocks */
538
+ .prose pre {
539
+ background-color: var(--color-fd-muted);
540
+ border: 1px solid var(--color-fd-border);
541
+ }
542
+
543
+ .prose code {
544
+ color: var(--color-fd-primary);
545
+ background-color: var(--color-fd-muted);
546
+ }
547
+
548
+ /* --- FORCE GLASS EFFECT FOR FLYOUT/POPOUT SIDEBAR --- */
549
+ .fixed[data-slot="sidebar-container"],
550
+ .absolute[data-slot="sidebar-container"],
551
+ .fixed.bg-sidebar,
552
+ .absolute.bg-sidebar,
553
+ .fixed[data-sidebar="sidebar"],
554
+ .absolute[data-sidebar="sidebar"],
555
+ .fixed[data-slot*="sidebar"],
556
+ .absolute[data-slot*="sidebar"],
557
+ .fixed.inset-y-0.left-0,
558
+ .absolute.inset-y-0.left-0,
559
+ .md\:flex[data-slot="sidebar-container"],
560
+ .md\:flex.bg-sidebar {
561
+ background-color: rgba(255, 255, 255, 0.28) !important;
562
+ backdrop-filter: blur(22px) !important;
563
+ -webkit-backdrop-filter: blur(22px) !important;
564
+ border: 1px solid rgba(255, 255, 255, 0.32) !important;
565
+ box-shadow: 0 8px 32px rgba(0,0,0,0.18), inset 0 1px 0 rgba(255,255,255,0.22) !important;
566
+ z-index: 1000 !important;
567
+ }
568
+
569
+ .dark .fixed[data-slot="sidebar-container"],
570
+ .dark .absolute[data-slot="sidebar-container"],
571
+ .dark .fixed.bg-sidebar,
572
+ .dark .absolute.bg-sidebar,
573
+ .dark .fixed[data-sidebar="sidebar"],
574
+ .dark .absolute[data-sidebar="sidebar"],
575
+ .dark .fixed[data-slot*="sidebar"],
576
+ .dark .absolute[data-slot*="sidebar"],
577
+ .dark .fixed.inset-y-0.left-0,
578
+ .dark .absolute.inset-y-0.left-0,
579
+ .dark .md\:flex[data-slot="sidebar-container"],
580
+ .dark .md\:flex.bg-sidebar {
581
+ background-color: rgba(30, 41, 59, 0.42) !important;
582
+ backdrop-filter: blur(28px) !important;
583
+ -webkit-backdrop-filter: blur(28px) !important;
584
+ border: 1px solid rgba(148, 163, 184, 0.22) !important;
585
+ box-shadow: 0 8px 32px rgba(0,0,0,0.32), inset 0 1px 0 rgba(255,255,255,0.12) !important;
586
+ z-index: 1000 !important;
587
+ }
@@ -0,0 +1,13 @@
1
+ import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
2
+ import { Phone } from 'lucide-react';
3
+
4
+ export const baseOptions: BaseLayoutProps = {
5
+ nav: {
6
+ title: (
7
+ <span className="inline-flex items-center gap-2">
8
+ <Phone />
9
+ Verify Phone
10
+ </span>
11
+ ),
12
+ },
13
+ };