Skip to content

Commit e49e67a

Browse files
committed
Add guided tours via driver.js with three interactive walkthroughs
1 parent a325cbc commit e49e67a

6 files changed

Lines changed: 1219 additions & 14 deletions

File tree

package-lock.json

Lines changed: 8 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"@codemirror/theme-one-dark": "^6.0.0",
4545
"@xyflow/svelte": "^1.5.0",
4646
"codemirror": "^6.0.0",
47+
"driver.js": "^1.4.0",
4748
"jspdf": "^4.1.0",
4849
"katex": "^0.16.0",
4950
"opentype.js": "^1.3.4",

src/app.css

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,3 +717,233 @@ body.assembly-pending .svelte-flow__edge {
717717
transform: scale(1);
718718
}
719719
}
720+
721+
/* --- Guided tour (driver.js) — pathview theme ------------------------- */
722+
723+
/* Theme-aware overlay: light scrim on dark, dark scrim on light. Driver.js
724+
* sets fill via inline attribute on the inner path, so we override with
725+
* !important. Vars live on :root so toggling theme updates immediately. */
726+
:root[data-theme='dark'],
727+
:root:not([data-theme]) {
728+
--tour-overlay-color: rgba(255, 255, 255, 0.22);
729+
}
730+
731+
:root[data-theme='light'] {
732+
--tour-overlay-color: rgba(0, 0, 0, 0.55);
733+
}
734+
735+
.driver-overlay,
736+
.driver-overlay path {
737+
fill: var(--tour-overlay-color) !important;
738+
}
739+
740+
.driver-popover {
741+
background-color: var(--surface) !important;
742+
color: var(--text) !important;
743+
border: 1px solid var(--border) !important;
744+
border-radius: var(--radius-lg) !important;
745+
box-shadow: var(--shadow-lg) !important;
746+
max-width: 420px !important;
747+
min-width: 320px !important;
748+
padding: 0 !important;
749+
overflow: hidden !important;
750+
}
751+
752+
.driver-popover,
753+
.driver-popover * {
754+
font-family: var(--font-ui) !important;
755+
}
756+
757+
.driver-popover-title {
758+
display: flex !important;
759+
align-items: center !important;
760+
min-height: var(--header-height) !important;
761+
margin: 0 !important;
762+
padding: 0 var(--space-md) !important;
763+
background: var(--surface-raised) !important;
764+
border-bottom: 1px solid var(--border) !important;
765+
border-radius: var(--radius-lg) var(--radius-lg) 0 0 !important;
766+
font-size: var(--font-base) !important;
767+
font-weight: 500 !important;
768+
line-height: 1.3 !important;
769+
color: var(--text-muted) !important;
770+
text-transform: uppercase !important;
771+
letter-spacing: 0.5px !important;
772+
}
773+
774+
.driver-popover-description {
775+
font-size: 12px !important;
776+
color: var(--text-muted) !important;
777+
line-height: 1.55 !important;
778+
margin: 0 !important;
779+
padding: 14px 16px 0 !important;
780+
}
781+
782+
.driver-popover-description p {
783+
margin: 0 0 8px !important;
784+
}
785+
786+
.driver-popover-description p:last-child {
787+
margin-bottom: 0 !important;
788+
}
789+
790+
.driver-popover-description ul {
791+
margin: 6px 0 10px !important;
792+
padding-left: 18px !important;
793+
}
794+
795+
.driver-popover-description li {
796+
margin: 2px 0 !important;
797+
}
798+
799+
.driver-popover-description table {
800+
width: 100% !important;
801+
border-collapse: collapse !important;
802+
margin: 6px 0 !important;
803+
font-size: 11px !important;
804+
}
805+
806+
.driver-popover-description table td {
807+
padding: 4px 6px !important;
808+
border-bottom: 1px solid var(--border) !important;
809+
vertical-align: middle !important;
810+
}
811+
812+
.driver-popover-description table tr:last-child td {
813+
border-bottom: none !important;
814+
}
815+
816+
.driver-popover-description table td:last-child {
817+
text-align: right !important;
818+
white-space: nowrap !important;
819+
}
820+
821+
.driver-popover-description kbd {
822+
display: inline-block;
823+
padding: 2px 5px;
824+
font-family: inherit !important;
825+
font-size: 10px;
826+
background: var(--surface-raised);
827+
border: 1px solid var(--border);
828+
border-radius: 3px;
829+
color: var(--text-muted);
830+
min-width: 16px;
831+
text-align: center;
832+
}
833+
834+
.driver-popover-description code {
835+
font-family: var(--font-mono) !important;
836+
color: var(--accent);
837+
background: transparent;
838+
padding: 0;
839+
}
840+
841+
.driver-popover-progress-text {
842+
font-size: 10px !important;
843+
color: var(--text-disabled) !important;
844+
}
845+
846+
.driver-popover-footer {
847+
margin-top: 0 !important;
848+
padding: 12px 16px 14px !important;
849+
}
850+
851+
/* Footer buttons — match the modal action-button styles (with border). */
852+
.driver-popover-footer button {
853+
display: inline-flex !important;
854+
align-items: center !important;
855+
justify-content: center !important;
856+
gap: var(--space-sm) !important;
857+
cursor: pointer !important;
858+
border: 1px solid var(--border) !important;
859+
background: var(--surface-raised) !important;
860+
color: var(--text) !important;
861+
padding: var(--space-sm) var(--space-md) !important;
862+
border-radius: var(--radius-md) !important;
863+
font-size: 11px !important;
864+
font-weight: 500 !important;
865+
text-shadow: none !important;
866+
transition: all var(--transition-fast) !important;
867+
}
868+
869+
.driver-popover-footer button:hover {
870+
background: var(--surface-hover) !important;
871+
border-color: var(--border-focus) !important;
872+
}
873+
874+
.driver-popover-footer button:active {
875+
transform: scale(0.98) !important;
876+
}
877+
878+
.driver-popover-footer button:focus {
879+
outline: none !important;
880+
}
881+
882+
/* Back button as ghost (secondary action). */
883+
.driver-popover-prev-btn {
884+
background: transparent !important;
885+
color: var(--text-muted) !important;
886+
}
887+
888+
.driver-popover-prev-btn:hover {
889+
background: var(--surface-hover) !important;
890+
color: var(--text) !important;
891+
border-color: var(--border-focus) !important;
892+
}
893+
894+
895+
/* Close button: matches the .icon-btn pattern used in modal headers.
896+
* The default "×" character is hidden and replaced by a Lucide X icon
897+
* via a pseudo-element mask so theme colours apply on hover. */
898+
.driver-popover-close-btn {
899+
position: absolute !important;
900+
top: 6px !important;
901+
right: 6px !important;
902+
width: 28px !important;
903+
height: 28px !important;
904+
border: none !important;
905+
border-radius: var(--radius-md) !important;
906+
background: transparent !important;
907+
color: transparent !important;
908+
font-size: 0 !important;
909+
cursor: pointer !important;
910+
text-shadow: none !important;
911+
transition: background var(--transition-fast) !important;
912+
z-index: 2 !important;
913+
}
914+
915+
.driver-popover-close-btn::before {
916+
content: '' !important;
917+
position: absolute !important;
918+
inset: 0 !important;
919+
background: var(--text-muted) !important;
920+
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'/%3E%3Cline x1='6' y1='6' x2='18' y2='18'/%3E%3C/svg%3E") center / 16px no-repeat;
921+
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'/%3E%3Cline x1='6' y1='6' x2='18' y2='18'/%3E%3C/svg%3E") center / 16px no-repeat;
922+
transition: background var(--transition-fast) !important;
923+
}
924+
925+
.driver-popover-close-btn:hover {
926+
background: var(--surface-hover) !important;
927+
}
928+
929+
.driver-popover-close-btn:hover::before {
930+
background: var(--text) !important;
931+
}
932+
933+
.driver-popover-close-btn:focus {
934+
outline: none !important;
935+
}
936+
937+
/* Arrow tip color matches popover background; only the visible side counts. */
938+
.driver-popover-arrow-side-left {
939+
border-left-color: var(--surface) !important;
940+
}
941+
.driver-popover-arrow-side-right {
942+
border-right-color: var(--surface) !important;
943+
}
944+
.driver-popover-arrow-side-top {
945+
border-top-color: var(--surface) !important;
946+
}
947+
.driver-popover-arrow-side-bottom {
948+
border-bottom-color: var(--surface) !important;
949+
}

src/lib/components/ResizablePanel.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@
179179
<aside
180180
class="resizable-panel glass-panel {position}"
181181
class:resizing={isResizing}
182+
data-panel={title ?? ''}
182183
style="
183184
{position === 'left' || position === 'right' ? `width: ${getWidth()}px;` : ''}
184185
{(position === 'bottom-left' || position === 'bottom-right') && controlledWidth !== undefined ? `width: ${getWidth()}px;` : ''}

0 commit comments

Comments
 (0)