@papermap/papermap 1.0.3 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@papermap/papermap",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "Embeddable AI chat bar and UI components from the Papermap data analytics platform",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -22,8 +22,10 @@
22
22
  "styles.css"
23
23
  ],
24
24
  "scripts": {
25
+ "sync:sdk-version": "node scripts/sync-sdk-version.mjs",
26
+ "prebuild": "npm run sync:sdk-version",
25
27
  "build": "tsup && npm run build:styles",
26
- "build:styles": "cp src/styles.css styles.css",
28
+ "build:styles": "cat node_modules/driver.js/dist/driver.css src/tour-overrides.css src/styles.css > styles.css",
27
29
  "dev": "tsup --watch",
28
30
  "storybook": "storybook dev -p 3001",
29
31
  "build-storybook": "storybook build",
@@ -31,7 +33,9 @@
31
33
  "ts-check": "tsc --noEmit",
32
34
  "format": "prettier --write \"src/**/*.{ts,tsx}\"",
33
35
  "format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
34
- "validate": "npm run lint && npm run ts-check",
36
+ "test": "vitest run",
37
+ "test:watch": "vitest",
38
+ "validate": "npm run lint && npm run ts-check && npm run test",
35
39
  "validate:watch": "npm run validate -- --watch",
36
40
  "clean": "rm -rf dist styles.css",
37
41
  "prepare": "husky || true",
@@ -64,9 +68,10 @@
64
68
  "@radix-ui/react-tooltip": "^1.2.8",
65
69
  "@tanstack/react-query": "^5.22.2",
66
70
  "@tanstack/react-table": "^8.21.3",
67
- "axios": "1.7.9",
71
+ "axios": "1.8.2",
68
72
  "class-variance-authority": "^0.7.1",
69
73
  "clsx": "^2.1.1",
74
+ "driver.js": "^1.4.0",
70
75
  "framer-motion": "^11.17.0",
71
76
  "html2canvas": "^1.4.1",
72
77
  "lottie-react": "^2.4.1",
@@ -87,6 +92,9 @@
87
92
  "@storybook/blocks": "^8.6.14",
88
93
  "@storybook/react": "^8.6.18",
89
94
  "@storybook/react-vite": "^8.6.18",
95
+ "@testing-library/jest-dom": "^6.9.1",
96
+ "@testing-library/react": "^16.3.2",
97
+ "@testing-library/user-event": "^14.6.1",
90
98
  "@types/react": "^18.3.18",
91
99
  "@types/react-dom": "^18.3.5",
92
100
  "@types/react-syntax-highlighter": "^15.5.13",
@@ -100,6 +108,7 @@
100
108
  "eslint-plugin-react": "^7.37.4",
101
109
  "eslint-plugin-react-hooks": "^5.1.0",
102
110
  "husky": "^9.1.7",
111
+ "jsdom": "^29.0.2",
103
112
  "lint-staged": "^15.3.0",
104
113
  "playwright": "^1.58.2",
105
114
  "postcss": "^8.5.8",
@@ -111,7 +120,8 @@
111
120
  "tailwindcss-animate": "^1.0.7",
112
121
  "tsup": "^8.4.0",
113
122
  "typescript": "^5.7.3",
114
- "vite": "^6.4.1"
123
+ "vite": "^6.4.1",
124
+ "vitest": "^4.1.3"
115
125
  },
116
126
  "engines": {
117
127
  "node": ">=18"
package/readme.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  Embeddable AI-powered components from the [Papermap](https://www.papermap.ai) data analytics platform. This is a standalone package — **independent** from the main Papermap app. Services, SSE streaming, and UI are self-contained; the repos do not depend on each other.
4
4
 
5
+ ## Backend setup
6
+
7
+ For **server-side setup** (HMAC auth, dashboards per tenant, embed tokens, API endpoints), see the [Backend implementation guide](https://docs.papermap.ai/documentation/multi-tenancy/backend) in the Papermap docs.
8
+
5
9
  ## Main components
6
10
 
7
11
  - **`PaperChat`** — Full AI chat assistant with streaming, conversation history, and chart generation.
@@ -73,11 +77,7 @@ import '@papermap/papermap/styles.css'
73
77
  `PapermapConfigProvider` is an alias for `PapermapProvider` — same component, useful for naming consistency in app code.
74
78
 
75
79
  ```tsx
76
- import {
77
- PapermapConfigProvider,
78
- PaperChat,
79
- PaperCard,
80
- } from '@papermap/papermap'
80
+ import { PapermapConfigProvider, PaperChat, PaperCard } from '@papermap/papermap'
81
81
 
82
82
  function App() {
83
83
  return (
@@ -125,40 +125,40 @@ function App() {
125
125
 
126
126
  #### `PaperChat` props
127
127
 
128
- | Prop | Type | Required | Default | Description |
129
- | ------------- | ---------------------- | -------- | --------------------------------- | ------------------------------------ |
130
- | `token` | `string` | Yes\* | -- | Base64-encoded API key token |
131
- | `workspaceId` | `string` | Yes\* | -- | Workspace ID |
132
- | `dashboardId` | `string` | Yes\* | -- | Dashboard ID |
133
- | `apiUrl` | `string` | No | `https://dataapi.papermap.ai` | API base URL |
134
- | `theme` | `'light' \| 'dark'` | No | -- | Force light or dark theme |
135
- | `placeholder` | `string` | No | `"Ask anything..."` | Input placeholder text |
136
- | `shortcutKey` | `string` | No | `"k"` | Keyboard shortcut (Cmd/Ctrl + key) |
137
- | `autoFade` | `boolean` | No | `false` | Fade toolbar after inactivity |
138
- | `fadeDelay` | `number` | No | `5000` | Milliseconds before auto-fade |
139
- | `className` | `string` | No | -- | Extra CSS class on toolbar container |
128
+ | Prop | Type | Required | Default | Description |
129
+ | ------------- | ------------------- | -------- | ----------------------------- | ------------------------------------ |
130
+ | `token` | `string` | Yes\* | -- | Base64-encoded API key token |
131
+ | `workspaceId` | `string` | Yes\* | -- | Workspace ID |
132
+ | `dashboardId` | `string` | Yes\* | -- | Dashboard ID |
133
+ | `apiUrl` | `string` | No | `https://dataapi.papermap.ai` | API base URL |
134
+ | `theme` | `'light' \| 'dark'` | No | -- | Force light or dark theme |
135
+ | `placeholder` | `string` | No | `"Ask anything..."` | Input placeholder text |
136
+ | `shortcutKey` | `string` | No | `"k"` | Keyboard shortcut (Cmd/Ctrl + key) |
137
+ | `autoFade` | `boolean` | No | `false` | Fade toolbar after inactivity |
138
+ | `fadeDelay` | `number` | No | `5000` | Milliseconds before auto-fade |
139
+ | `className` | `string` | No | -- | Extra CSS class on toolbar container |
140
140
 
141
141
  \*Omit on the component when values come from `PapermapConfigProvider` / `PapermapProvider`.
142
142
 
143
143
  #### `PaperCard` props
144
144
 
145
- | Prop | Type | Required | Default | Description |
146
- | -------------- | ---------------------------------------- | -------- | --------------------------------- | --------------------------------------------------------------------- |
147
- | `token` | `string` | Yes\* | -- | Base64-encoded API key token |
148
- | `workspaceId` | `string` | Yes\* | -- | Workspace ID |
149
- | `dashboardId` | `string` | Yes\* | -- | Dashboard ID |
150
- | `apiUrl` | `string` | No | `https://dataapi.papermap.ai` | API base URL |
151
- | `chartId` | `string` | No | -- | Backend chat id to load the latest chart for |
152
- | `chart` | `TChartResponse` | No | -- | Pre-loaded chart data (skips API fetch) |
153
- | `theme` | `'light' \| 'dark'` | No | -- | Force light or dark theme |
154
- | `onEditClick` | `(chartId: string) => void` | No | -- | Called when the edit button is clicked |
155
- | `onDelete` | `(chartId: string) => void` | No | -- | Called when chart deletion is confirmed |
156
- | `onPinChange` | `(chartId: string, pinned: boolean) => void` | No | -- | Called when pin state changes |
157
- | `wide` | `boolean` | No | `false` | Wide mode for table charts |
158
- | `hideVariants` | `boolean` | No | `true` | Hide the chart variation selector |
159
- | `showToolbar` | `boolean` | No | `true` | Show toolbar with maximize/edit/delete buttons |
160
- | `className` | `string` | No | -- | Extra CSS class on the card container |
161
- | `variant` | `'default' \| 'streaming'` | No | `'default'` | `'streaming'`: edit opens embedded dialog + chat |
145
+ | Prop | Type | Required | Default | Description |
146
+ | -------------- | -------------------------------------------- | -------- | ----------------------------- | ------------------------------------------------ |
147
+ | `token` | `string` | Yes\* | -- | Base64-encoded API key token |
148
+ | `workspaceId` | `string` | Yes\* | -- | Workspace ID |
149
+ | `dashboardId` | `string` | Yes\* | -- | Dashboard ID |
150
+ | `apiUrl` | `string` | No | `https://dataapi.papermap.ai` | API base URL |
151
+ | `chartId` | `string` | No | -- | Backend chat id to load the latest chart for |
152
+ | `chart` | `TChartResponse` | No | -- | Pre-loaded chart data (skips API fetch) |
153
+ | `theme` | `'light' \| 'dark'` | No | -- | Force light or dark theme |
154
+ | `onEditClick` | `(chartId: string) => void` | No | -- | Called when the edit button is clicked |
155
+ | `onDelete` | `(chartId: string) => void` | No | -- | Called when chart deletion is confirmed |
156
+ | `onPinChange` | `(chartId: string, pinned: boolean) => void` | No | -- | Called when pin state changes |
157
+ | `wide` | `boolean` | No | `false` | Wide mode for table charts |
158
+ | `hideVariants` | `boolean` | No | `true` | Hide the chart variation selector |
159
+ | `showToolbar` | `boolean` | No | `true` | Show toolbar with maximize/edit/delete buttons |
160
+ | `className` | `string` | No | -- | Extra CSS class on the card container |
161
+ | `variant` | `'default' \| 'streaming'` | No | `'default'` | `'streaming'`: edit opens embedded dialog + chat |
162
162
 
163
163
  **Pre-loaded chart:**
164
164
 
@@ -195,16 +195,16 @@ const chart: TChartResponse = {
195
195
 
196
196
  #### `PaperBoard` props (high level)
197
197
 
198
- | Prop | Notes |
199
- | ---- | ----- |
200
- | `token`, `workspaceId`, `dashboardId`, `apiUrl` | Same as other components; can come from provider. |
201
- | `charts` | Optional pre-loaded charts; otherwise fetched when `enableFetch` is true (default). |
202
- | `layouts` / `onLayoutsChange` | Controlled grid layouts per breakpoint. |
203
- | `isEditMode`, `editLayout`, `isViewer` | Edit vs view behavior. |
204
- | `showToolbar`, `showScreenshot`, `showGenerateDashboard`, `showHeader`, `showChatAssistant` | Feature toggles. |
205
- | `variant` | `'default' \| 'streaming'` for embedded chart cards (matches `PaperCard`). |
206
- | `dashboardTheme`, `onDashboardThemeChange`, `persistWorkspaceTheme`, `renderThemeModal` | Theming; built-in modal uses `ThemeCustomizationSettings`. |
207
- | Callbacks | `onEditChart`, `onDeleteChart`, `onPinChange`, `onGenerateDashboard`, `onTakeScreenshot`, `onThemeModalOpen`, etc. |
198
+ | Prop | Notes |
199
+ | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
200
+ | `token`, `workspaceId`, `dashboardId`, `apiUrl` | Same as other components; can come from provider. |
201
+ | `charts` | Optional pre-loaded charts; otherwise fetched when `enableFetch` is true (default). |
202
+ | `layouts` / `onLayoutsChange` | Controlled grid layouts per breakpoint. |
203
+ | `isEditMode`, `editLayout`, `isViewer` | Edit vs view behavior. |
204
+ | `showToolbar`, `showScreenshot`, `showGenerateDashboard`, `showHeader`, `showChatAssistant` | Feature toggles. |
205
+ | `variant` | `'default' \| 'streaming'` for embedded chart cards (matches `PaperCard`). |
206
+ | `dashboardTheme`, `onDashboardThemeChange`, `persistWorkspaceTheme`, `renderThemeModal` | Theming; built-in modal uses `ThemeCustomizationSettings`. |
207
+ | Callbacks | `onEditChart`, `onDeleteChart`, `onPinChange`, `onGenerateDashboard`, `onTakeScreenshot`, `onThemeModalOpen`, etc. |
208
208
 
209
209
  See TypeScript types `PaperBoardProps` and Storybook stories for full detail.
210
210
 
package/styles.css CHANGED
@@ -1,4 +1,362 @@
1
- @tailwind base;
1
+ .driver-active .driver-overlay,.driver-active *{pointer-events:none}.driver-active .driver-active-element,.driver-active .driver-active-element *,.driver-popover,.driver-popover *{pointer-events:auto}@keyframes animate-fade-in{0%{opacity:0}to{opacity:1}}.driver-fade .driver-overlay{animation:animate-fade-in .2s ease-in-out}.driver-fade .driver-popover{animation:animate-fade-in .2s}.driver-popover{all:unset;box-sizing:border-box;color:#2d2d2d;margin:0;padding:15px;border-radius:5px;min-width:250px;max-width:300px;box-shadow:0 1px 10px #0006;z-index:1000000000;position:fixed;top:0;right:0;background-color:#fff}.driver-popover *{font-family:Helvetica Neue,Inter,ui-sans-serif,"Apple Color Emoji",Helvetica,Arial,sans-serif}.driver-popover-title{font:19px/normal sans-serif;font-weight:700;display:block;position:relative;line-height:1.5;zoom:1;margin:0}.driver-popover-close-btn{all:unset;position:absolute;top:0;right:0;width:32px;height:28px;cursor:pointer;font-size:18px;font-weight:500;color:#d2d2d2;z-index:1;text-align:center;transition:color;transition-duration:.2s}.driver-popover-close-btn:hover,.driver-popover-close-btn:focus{color:#2d2d2d}.driver-popover-title[style*=block]+.driver-popover-description{margin-top:5px}.driver-popover-description{margin-bottom:0;font:14px/normal sans-serif;line-height:1.5;font-weight:400;zoom:1}.driver-popover-footer{margin-top:15px;text-align:right;zoom:1;display:flex;align-items:center;justify-content:space-between}.driver-popover-progress-text{font-size:13px;font-weight:400;color:#727272;zoom:1}.driver-popover-footer button{all:unset;display:inline-block;box-sizing:border-box;padding:3px 7px;text-decoration:none;text-shadow:1px 1px 0 #fff;background-color:#fff;color:#2d2d2d;font:12px/normal sans-serif;cursor:pointer;outline:0;zoom:1;line-height:1.3;border:1px solid #ccc;border-radius:3px}.driver-popover-footer .driver-popover-btn-disabled{opacity:.5;pointer-events:none}:not(body):has(>.driver-active-element){overflow:hidden!important}.driver-no-interaction,.driver-no-interaction *{pointer-events:none!important}.driver-popover-footer button:hover,.driver-popover-footer button:focus{background-color:#f7f7f7}.driver-popover-navigation-btns{display:flex;flex-grow:1;justify-content:flex-end}.driver-popover-navigation-btns button+button{margin-left:4px}.driver-popover-arrow{content:"";position:absolute;border:5px solid #fff}.driver-popover-arrow-side-over{display:none}.driver-popover-arrow-side-left{left:100%;border-right-color:transparent;border-bottom-color:transparent;border-top-color:transparent}.driver-popover-arrow-side-right{right:100%;border-left-color:transparent;border-bottom-color:transparent;border-top-color:transparent}.driver-popover-arrow-side-top{top:100%;border-right-color:transparent;border-bottom-color:transparent;border-left-color:transparent}.driver-popover-arrow-side-bottom{bottom:100%;border-left-color:transparent;border-top-color:transparent;border-right-color:transparent}.driver-popover-arrow-side-center{display:none}.driver-popover-arrow-side-left.driver-popover-arrow-align-start,.driver-popover-arrow-side-right.driver-popover-arrow-align-start{top:15px}.driver-popover-arrow-side-top.driver-popover-arrow-align-start,.driver-popover-arrow-side-bottom.driver-popover-arrow-align-start{left:15px}.driver-popover-arrow-align-end.driver-popover-arrow-side-left,.driver-popover-arrow-align-end.driver-popover-arrow-side-right{bottom:15px}.driver-popover-arrow-side-top.driver-popover-arrow-align-end,.driver-popover-arrow-side-bottom.driver-popover-arrow-align-end{right:15px}.driver-popover-arrow-side-left.driver-popover-arrow-align-center,.driver-popover-arrow-side-right.driver-popover-arrow-align-center{top:50%;margin-top:-5px}.driver-popover-arrow-side-top.driver-popover-arrow-align-center,.driver-popover-arrow-side-bottom.driver-popover-arrow-align-center{left:50%;margin-left:-5px}.driver-popover-arrow-none{display:none}
2
+ /* Custom Driver.js Tour Styles for Papermap - Premium Redesign */
3
+
4
+ /* Overlay - above app UI (e.g. workspace selector z-[10001]) */
5
+ .driver-overlay {
6
+ z-index: 99998 !important;
7
+ background-color: rgba(0, 0, 0, 0.4) !important;
8
+ backdrop-filter: none !important;
9
+ -webkit-backdrop-filter: none !important;
10
+ transition: all 0.4s ease-in-out !important;
11
+ }
12
+
13
+ .dark .driver-overlay {
14
+ background-color: rgba(0, 0, 0, 0.3) !important;
15
+ }
16
+
17
+ /* Popover container - above overlay, glassmorphism */
18
+ .driver-popover.papermap-tour-popover {
19
+ z-index: 99999 !important;
20
+ background: rgba(255, 255, 255, 0.9) !important;
21
+ border-radius: 24px !important;
22
+ /* smooth rounded corners */
23
+ border: 1px solid rgba(0, 0, 0, 0.05) !important;
24
+ box-shadow:
25
+ 0 24px 48px -12px rgba(0, 0, 0, 0.15),
26
+ 0 0 0 1px rgba(0, 0, 0, 0.05),
27
+ inset 0 1px 0 0 rgba(255, 255, 255, 0.1) !important;
28
+ max-width: 420px !important;
29
+ padding: 0 !important;
30
+ color: #000 !important;
31
+ overflow: hidden !important;
32
+ }
33
+
34
+ /* Expand: modal-like size (create dashboard modal is sm:max-w-[500px]; we go larger for media) */
35
+ .driver-popover.papermap-tour-popover.papermap-tour-popover--expand {
36
+ max-width: 640px !important;
37
+ min-width: 520px !important;
38
+ }
39
+
40
+ .driver-popover.papermap-tour-popover.papermap-tour-popover--expand .driver-popover-description img,
41
+ .driver-popover.papermap-tour-popover.papermap-tour-popover--expand .driver-popover-description video {
42
+ max-width: 560px !important;
43
+ width: 100% !important;
44
+ }
45
+
46
+ /* Dark mode popover */
47
+ .dark .driver-popover.papermap-tour-popover {
48
+ background: hsl(var(--card)) !important;
49
+ border: 1px solid hsl(var(--border)) !important;
50
+ box-shadow:
51
+ 0 24px 48px -12px rgba(0, 0, 0, 0.8),
52
+ 0 0 0 1px hsl(var(--border)),
53
+ inset 0 1px 0 0 rgba(255, 255, 255, 0.05) !important;
54
+ color: hsl(var(--foreground)) !important;
55
+ }
56
+
57
+ /* Arrow - adjust to be subtle or transparent */
58
+ .driver-popover-arrow {
59
+ border-width: 8px !important;
60
+ }
61
+
62
+ .driver-popover-arrow-side-left.driver-popover-arrow {
63
+ border-left-color: rgba(255, 255, 255, 0.9) !important;
64
+ }
65
+
66
+ .driver-popover-arrow-side-right.driver-popover-arrow {
67
+ border-right-color: rgba(255, 255, 255, 0.9) !important;
68
+ }
69
+
70
+ .driver-popover-arrow-side-top.driver-popover-arrow {
71
+ border-top-color: rgba(255, 255, 255, 0.9) !important;
72
+ }
73
+
74
+ .driver-popover-arrow-side-bottom.driver-popover-arrow {
75
+ border-bottom-color: rgba(255, 255, 255, 0.9) !important;
76
+ }
77
+
78
+ /* Dark mode arrows */
79
+ .dark .driver-popover-arrow-side-left.driver-popover-arrow {
80
+ border-left-color: hsl(var(--card)) !important;
81
+ }
82
+
83
+ .dark .driver-popover-arrow-side-right.driver-popover-arrow {
84
+ border-right-color: hsl(var(--card)) !important;
85
+ }
86
+
87
+ .dark .driver-popover-arrow-side-top.driver-popover-arrow {
88
+ border-top-color: hsl(var(--card)) !important;
89
+ }
90
+
91
+ .dark .driver-popover-arrow-side-bottom.driver-popover-arrow {
92
+ border-bottom-color: hsl(var(--card)) !important;
93
+ }
94
+
95
+ /* Title styling - Minimalist */
96
+ .driver-popover-title {
97
+ font-family: 'Manrope', 'Inter', sans-serif !important;
98
+ font-size: 22px !important;
99
+ font-weight: 700 !important;
100
+ color: #000 !important;
101
+ margin: 0 !important;
102
+ padding: 32px 32px 12px 32px !important;
103
+ line-height: 1.2 !important;
104
+ letter-spacing: -0.02em !important;
105
+ }
106
+
107
+ .dark .driver-popover-title {
108
+ color: hsl(var(--foreground)) !important;
109
+ }
110
+
111
+ /* Description styling */
112
+ .driver-popover-description {
113
+ font-family: 'Manrope', 'Inter', sans-serif !important;
114
+ font-size: 15px !important;
115
+ line-height: 1.6 !important;
116
+ color: rgba(0, 0, 0, 0.6) !important;
117
+ /* More subtle text */
118
+ margin: 0 !important;
119
+ padding: 0 32px 32px 32px !important;
120
+ font-weight: 400 !important;
121
+ }
122
+
123
+ .dark .driver-popover-description {
124
+ color: hsl(var(--muted-foreground)) !important;
125
+ }
126
+
127
+ /* Footer styling */
128
+ .driver-popover-footer {
129
+ display: flex !important;
130
+ align-items: center !important;
131
+ justify-content: space-between !important;
132
+ padding: 24px 32px !important;
133
+ background: rgba(0, 0, 0, 0.03) !important;
134
+ border-top: 1px solid rgba(0, 0, 0, 0.05) !important;
135
+ }
136
+
137
+ .dark .driver-popover-footer {
138
+ background: rgba(0, 0, 0, 0.2) !important;
139
+ border-top: 1px solid hsl(var(--border)) !important;
140
+ }
141
+
142
+ .driver-popover-footer button {
143
+ text-shadow: none !important;
144
+ }
145
+
146
+ /* Progress text */
147
+ .driver-popover-progress-text {
148
+ font-family: 'Manrope', 'Inter', sans-serif !important;
149
+ font-size: 13px !important;
150
+ font-weight: 700 !important;
151
+ color: rgba(0, 0, 0, 0.6) !important;
152
+ letter-spacing: 0.5px !important;
153
+ }
154
+
155
+ .dark .driver-popover-progress-text {
156
+ color: hsl(var(--muted-foreground)) !important;
157
+ }
158
+
159
+ /* Navigation buttons container */
160
+ .driver-popover-navigation-btns {
161
+ display: flex !important;
162
+ align-items: center !important;
163
+ gap: 16px !important;
164
+ }
165
+
166
+ /* Button base styles */
167
+ .driver-popover-btn {
168
+ padding: 0 20px !important;
169
+ font-family: 'TWK Lausanne', 'Manrope', 'Inter', sans-serif !important;
170
+ font-size: 14px !important;
171
+ font-weight: 500 !important;
172
+ border-radius: 8px !important;
173
+ transition: all 0.2s ease !important;
174
+ cursor: pointer !important;
175
+ display: inline-flex !important;
176
+ align-items: center !important;
177
+ justify-content: center !important;
178
+ gap: 12px !important;
179
+ outline: none !important;
180
+ height: 48px !important;
181
+ }
182
+
183
+ /* Next/Done button */
184
+ .driver-popover-next-btn,
185
+ .driver-popover-btn-group .driver-popover-btn:last-child {
186
+ background-color: #000000 !important;
187
+ color: #FFFFFF !important;
188
+ border: 1px solid rgba(0, 0, 0, 0.1) !important;
189
+ box-shadow: none !important;
190
+ font-weight: 500 !important;
191
+ }
192
+
193
+ .driver-popover-next-btn:hover,
194
+ .driver-popover-btn-group .driver-popover-btn:last-child:hover {
195
+ background-color: rgba(0, 0, 0, 0.9) !important;
196
+ border-color: rgba(0, 0, 0, 0.2) !important;
197
+ transform: none !important;
198
+ box-shadow: none !important;
199
+ }
200
+
201
+ .driver-popover-next-btn:active {
202
+ background-color: #000000 !important;
203
+ transform: none !important;
204
+ opacity: 0.9 !important;
205
+ }
206
+
207
+ .dark .driver-popover-next-btn,
208
+ .dark .driver-popover-btn-group .driver-popover-btn:last-child {
209
+ background-color: hsl(var(--primary)) !important;
210
+ color: hsl(var(--primary-foreground)) !important;
211
+ border: 1px solid hsl(var(--border)) !important;
212
+ }
213
+
214
+ .dark .driver-popover-next-btn:hover,
215
+ .dark .driver-popover-btn-group .driver-popover-btn:last-child:hover {
216
+ background-color: hsl(var(--primary)) !important;
217
+ opacity: 0.9 !important;
218
+ border-color: hsl(var(--border)) !important;
219
+ }
220
+
221
+ .dark .driver-popover-next-btn:active {
222
+ background-color: hsl(var(--primary)) !important;
223
+ opacity: 0.8 !important;
224
+ }
225
+
226
+ /* Previous button */
227
+ .driver-popover-prev-btn {
228
+ background: rgba(0, 0, 0, 0.05) !important;
229
+ color: rgba(0, 0, 0, 0.6) !important;
230
+ padding: 0 16px !important;
231
+ font-size: 13px !important;
232
+ border: 1px solid rgba(0, 0, 0, 0.1) !important;
233
+ font-weight: 600 !important;
234
+ }
235
+
236
+ .driver-popover-prev-btn:hover {
237
+ color: #000 !important;
238
+ background: rgba(0, 0, 0, 0.08) !important;
239
+ border-color: rgba(0, 0, 0, 0.15) !important;
240
+ }
241
+
242
+ .dark .driver-popover-prev-btn {
243
+ background: hsl(var(--secondary)) !important;
244
+ color: hsl(var(--secondary-foreground)) !important;
245
+ border: 1px solid hsl(var(--border)) !important;
246
+ }
247
+
248
+ .dark .driver-popover-prev-btn:hover {
249
+ background: hsl(var(--muted)) !important;
250
+ color: hsl(var(--foreground)) !important;
251
+ border-color: hsl(var(--border)) !important;
252
+ }
253
+
254
+ /* Expand toggle button (when step has expand: true) */
255
+ .papermap-tour-expand-btn {
256
+ position: absolute !important;
257
+ top: 24px !important;
258
+ right: 52px !important;
259
+ width: 32px !important;
260
+ height: 32px !important;
261
+ z-index: 2 !important;
262
+ display: flex !important;
263
+ align-items: center !important;
264
+ justify-content: center !important;
265
+ background: transparent !important;
266
+ color: rgba(0, 0, 0, 0.6) !important;
267
+ border-radius: 6px !important;
268
+ padding: 0 !important;
269
+ transition: all 0.2s ease !important;
270
+ border: none !important;
271
+ cursor: pointer !important;
272
+ }
273
+
274
+ .papermap-tour-expand-btn:hover {
275
+ background: rgba(0, 0, 0, 0.08) !important;
276
+ color: #000 !important;
277
+ }
278
+
279
+ .papermap-tour-expand-btn svg {
280
+ flex-shrink: 0 !important;
281
+ }
282
+
283
+ .dark .papermap-tour-expand-btn {
284
+ color: hsl(var(--muted-foreground)) !important;
285
+ }
286
+
287
+ .dark .papermap-tour-expand-btn:hover {
288
+ background: hsl(var(--muted)) !important;
289
+ color: hsl(var(--foreground)) !important;
290
+ }
291
+
292
+ /* Close button */
293
+ .driver-popover-close-btn {
294
+ position: absolute !important;
295
+ top: 24px !important;
296
+ right: 24px !important;
297
+ width: 24px !important;
298
+ height: 24px !important;
299
+ display: flex !important;
300
+ align-items: center !important;
301
+ justify-content: center !important;
302
+ background: transparent !important;
303
+ color: rgba(0, 0, 0, 0.6) !important;
304
+ border-radius: 4px !important;
305
+ font-size: 20px !important;
306
+ padding: 0 !important;
307
+ transition: all 0.2s ease !important;
308
+ border: none !important;
309
+ }
310
+
311
+ .driver-popover-close-btn:hover {
312
+ background: rgba(0, 0, 0, 0.1) !important;
313
+ color: #000 !important;
314
+ }
315
+
316
+ .dark .driver-popover-close-btn {
317
+ color: hsl(var(--muted-foreground)) !important;
318
+ }
319
+
320
+ .dark .driver-popover-close-btn:hover {
321
+ background: hsl(var(--muted)) !important;
322
+ color: hsl(var(--foreground)) !important;
323
+ }
324
+
325
+ /* Highlighted element */
326
+ .driver-highlighted-element {
327
+ border-radius: 6px !important;
328
+ box-shadow:
329
+ 0 0 0 4px rgba(0, 0, 0, 0.2),
330
+ 0 0 0 5px rgba(255, 255, 255, 0.5) !important;
331
+ transition: all 0.4s cubic-bezier(0.2, 0.8, 0.2, 1) !important;
332
+ }
333
+
334
+ .dark .driver-highlighted-element {
335
+ box-shadow:
336
+ 0 0 0 4px rgba(255, 255, 255, 0.1),
337
+ 0 0 0 5px hsl(var(--border)) !important;
338
+ }
339
+
340
+ /* Animation */
341
+ .driver-popover {
342
+ animation: driverPopoverSlide 0.4s cubic-bezier(0.16, 1, 0.3, 1) !important;
343
+ }
344
+
345
+ @keyframes driverPopoverSlide {
346
+ 0% {
347
+ opacity: 0;
348
+ transform: scale(0.96) translateY(8px);
349
+ }
350
+
351
+ 100% {
352
+ opacity: 1;
353
+ transform: scale(1) translateY(0);
354
+ }
355
+ }
356
+
357
+ .driver-popover-skip-btn {
358
+ display: none !important;
359
+ }@tailwind base;
2
360
  @tailwind components;
3
361
  @tailwind utilities;
4
362