@brett_lamy/docstream 1.6.0 → 1.7.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.
Files changed (43) hide show
  1. package/README.md +34 -7
  2. package/dist/index.d.ts +2 -2
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/replay/ReplayPlayer.d.ts +64 -0
  7. package/dist/replay/ReplayPlayer.d.ts.map +1 -0
  8. package/dist/replay/ReplayPlayer.js +211 -0
  9. package/dist/replay/ReplayPlayer.js.map +1 -0
  10. package/dist/replay/ReplayPreview.d.ts +24 -12
  11. package/dist/replay/ReplayPreview.d.ts.map +1 -1
  12. package/dist/replay/ReplayPreview.js +37 -32
  13. package/dist/replay/ReplayPreview.js.map +1 -1
  14. package/dist/replay/ReplayStage.d.ts +1 -1
  15. package/dist/replay/ReplayStage.js +1 -1
  16. package/dist/replay/ReplayStageImpl.js +1 -1
  17. package/dist/replay/ReplayStageImpl.js.map +1 -1
  18. package/dist/replay/demo/index.d.ts +3 -0
  19. package/dist/replay/demo/index.d.ts.map +1 -0
  20. package/dist/replay/demo/index.js +66 -0
  21. package/dist/replay/demo/index.js.map +1 -0
  22. package/dist/replay/index.d.ts +2 -2
  23. package/dist/replay/index.d.ts.map +1 -1
  24. package/dist/replay/index.js +1 -1
  25. package/dist/replay/index.js.map +1 -1
  26. package/dist/replay/types.js +3 -3
  27. package/dist/replay/types.js.map +1 -1
  28. package/dist/styles.css +565 -75
  29. package/package.json +8 -6
  30. package/src/index.ts +2 -1
  31. package/src/replay/ReplayPlayer.tsx +430 -0
  32. package/src/replay/ReplayPreview.tsx +111 -85
  33. package/src/replay/ReplayStage.tsx +1 -1
  34. package/src/replay/ReplayStageImpl.tsx +1 -1
  35. package/src/replay/demo/index.ts +67 -0
  36. package/src/replay/index.ts +6 -1
  37. package/src/replay/types.ts +3 -3
  38. package/src/styles.css +565 -75
  39. package/dist/replay/NativeReplay.d.ts +0 -9
  40. package/dist/replay/NativeReplay.d.ts.map +0 -1
  41. package/dist/replay/NativeReplay.js +0 -175
  42. package/dist/replay/NativeReplay.js.map +0 -1
  43. package/src/replay/NativeReplay.tsx +0 -240
package/src/styles.css CHANGED
@@ -2343,95 +2343,585 @@
2343
2343
  }
2344
2344
  }
2345
2345
 
2346
- /* Replay embeds (ReplayPreview / ReplayEmbed). Part of the one package stylesheet so no
2347
- module imports CSS on the eager path: the root entry stays importable from Node
2348
- (SSR, vitest) without a CSS loader. */
2349
- .replay-preview {
2350
- width: 100%;
2351
- min-width: 0;
2352
- color: var(--replay-preview-fg, #e5e7eb);
2353
- background: var(--replay-preview-bg, #0f172a);
2354
- border: 1px solid var(--replay-preview-border, rgba(148, 163, 184, 0.28));
2355
- border-radius: 12px;
2356
- overflow: hidden;
2357
- }
2346
+ /* ReplayPreview / ReplayEmbed: the session-replay player and its iframe embed. Part of the one package
2347
+ stylesheet so no module imports CSS on the eager path: the root entry stays importable from Node
2348
+ (SSR, vitest) without a CSS loader.
2349
+
2350
+ Everything sits in the `docstream.replay` cascade layer and under `:where()`, so a host's own rules win:
2351
+ unlayered CSS always does, and Tailwind-style utilities (`w-full`, `pointer-events-none`, `h-full`) do as
2352
+ long as their layer is declared after this one. If your utilities layer comes earlier in the layer order,
2353
+ put `@layer docstream.replay;` before it. Colors read the shadcn-style tokens below and fall back to
2354
+ neutral values: --card --background --foreground --muted --muted-foreground --border --primary --ring
2355
+ --destructive --success --warning --tertiary-foreground. The root sets `--replay-ar` (recorded aspect
2356
+ ratio) on the stage; the page and overlay run in recorded-viewport pixels with `--replay-scale` set. */
2357
+ @layer docstream.replay {
2358
+ :where([data-slot="replay-preview"]) {
2359
+ position: relative;
2360
+ isolation: isolate;
2361
+ display: flex;
2362
+ flex-direction: column;
2363
+ box-sizing: border-box;
2364
+ min-width: 0;
2365
+ overflow: hidden;
2366
+ outline: none;
2367
+ color: var(--foreground, #18181b);
2368
+ background: var(--card, #ffffff);
2369
+ font-size: 13px;
2370
+ line-height: 1.4;
2371
+ }
2358
2372
 
2359
- .replay-preview__frame {
2360
- display: block;
2361
- width: 100%;
2362
- aspect-ratio: 16 / 9;
2363
- border: 0;
2364
- background: #0f172a;
2365
- }
2373
+ :where([data-slot="replay-preview"] *, [data-slot="replay-preview"] *::before, [data-slot="replay-preview"] *::after) {
2374
+ box-sizing: border-box;
2375
+ }
2366
2376
 
2367
- .replay-preview__invalid,
2368
- .replay-preview__empty,
2369
- .replay-preview__error {
2370
- display: flex;
2371
- align-items: center;
2372
- justify-content: center;
2373
- min-height: 140px;
2374
- padding: 20px;
2375
- color: var(--replay-preview-muted, #94a3b8);
2376
- font: 13px/1.5 ui-sans-serif, system-ui, sans-serif;
2377
- text-align: center;
2378
- }
2377
+ :where([data-slot="replay-preview"][data-chrome="browser"]) {
2378
+ border: 1px solid var(--border, #e4e4e7);
2379
+ border-radius: 14px;
2380
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06), 0 18px 40px -18px rgba(0, 0, 0, 0.28);
2381
+ }
2379
2382
 
2380
- .replay-preview__invalid {
2381
- color: var(--replay-preview-link, #7dd3fc);
2382
- }
2383
+ :where([data-slot="replay-preview"][data-chrome="minimal"]) {
2384
+ border: 1px solid var(--border, #e4e4e7);
2385
+ border-radius: 12px;
2386
+ }
2383
2387
 
2384
- .replay-preview__error {
2385
- color: #fda4af;
2386
- }
2388
+ :where([data-slot="replay-preview"][data-fit="contain"]) {
2389
+ height: 100%;
2390
+ }
2387
2391
 
2388
- .replay-preview__native {
2389
- width: 100%;
2390
- background: #0f172a;
2391
- }
2392
+ :where([data-slot="replay-preview"][data-fullscreen]) {
2393
+ border: 0;
2394
+ border-radius: 0;
2395
+ }
2392
2396
 
2393
- .replay-preview__stage {
2394
- position: relative;
2395
- width: 100%;
2396
- min-height: 160px;
2397
- overflow: hidden;
2398
- background: #020617;
2399
- }
2397
+ /* ── browser bar ─────────────────────────────────────────────── */
2398
+ :where([data-slot="replay-preview-bar"]) {
2399
+ display: flex;
2400
+ flex-shrink: 0;
2401
+ align-items: center;
2402
+ gap: 12px;
2403
+ height: 40px;
2404
+ padding: 0 14px;
2405
+ border-bottom: 1px solid var(--border, #e4e4e7);
2406
+ background: color-mix(in srgb, var(--muted, #f4f4f5) 60%, transparent);
2407
+ }
2400
2408
 
2401
- .replay-preview__scaler {
2402
- position: absolute;
2403
- inset: 0 auto auto 0;
2404
- }
2409
+ :where([data-slot="replay-preview-lights"]) {
2410
+ display: flex;
2411
+ flex-shrink: 0;
2412
+ gap: 7px;
2413
+ }
2405
2414
 
2406
- .replay-preview__player {
2407
- position: relative;
2408
- overflow: hidden;
2415
+ :where([data-slot="replay-preview-lights"] > span) {
2416
+ width: 11px;
2417
+ height: 11px;
2418
+ border-radius: 50%;
2419
+ background: var(--light);
2420
+ box-shadow: inset 0 0 0 0.5px rgba(0, 0, 0, 0.12);
2421
+ }
2422
+
2423
+ :where([data-slot="replay-preview-lights-spacer"]) {
2424
+ flex-shrink: 0;
2425
+ width: 47px;
2426
+ }
2427
+
2428
+ :where([data-slot="replay-preview-address"]) {
2429
+ display: flex;
2430
+ align-items: center;
2431
+ justify-content: center;
2432
+ gap: 6px;
2433
+ width: 100%;
2434
+ max-width: 460px;
2435
+ min-width: 0;
2436
+ height: 26px;
2437
+ margin-inline: auto;
2438
+ padding: 0 10px;
2439
+ border-radius: 7px;
2440
+ background: var(--background, #ffffff);
2441
+ box-shadow: inset 0 0 0 1px var(--border, #e4e4e7);
2442
+ font-size: 12px;
2443
+ }
2444
+
2445
+ :where([data-slot="replay-preview-lock"]) {
2446
+ display: grid;
2447
+ flex-shrink: 0;
2448
+ place-items: center;
2449
+ width: 12px;
2450
+ height: 12px;
2451
+ color: var(--tertiary-foreground, #a1a1aa);
2452
+ }
2453
+
2454
+ :where([data-slot="replay-preview-url"]) {
2455
+ min-width: 0;
2456
+ overflow: hidden;
2457
+ text-overflow: ellipsis;
2458
+ white-space: nowrap;
2459
+ }
2460
+
2461
+ :where([data-slot="replay-preview-url"] > :first-child) {
2462
+ color: var(--foreground, #18181b);
2463
+ }
2464
+
2465
+ :where([data-slot="replay-preview-url"] > :last-child) {
2466
+ color: var(--muted-foreground, #71717a);
2467
+ }
2468
+
2469
+ :where([data-slot="replay-preview-spinner"]) {
2470
+ width: 11px;
2471
+ height: 11px;
2472
+ border: 1.5px solid currentColor;
2473
+ border-right-color: transparent;
2474
+ border-radius: 50%;
2475
+ animation: docstream-replay-spin 0.7s linear infinite;
2476
+ }
2477
+
2478
+ /* ── stage: the page, its poster, the pointer overlay ────────── */
2479
+ :where([data-slot="replay-preview-stage"]) {
2480
+ position: relative;
2481
+ min-height: 0;
2482
+ overflow: hidden;
2483
+ aspect-ratio: var(--replay-ar, 16 / 9);
2484
+ background: var(--muted, #f4f4f5);
2485
+ }
2486
+
2487
+ :where([data-slot="replay-preview"][data-fit="contain"] > [data-slot="replay-preview-stage"]) {
2488
+ flex: 1 1 0%;
2489
+ aspect-ratio: auto;
2490
+ }
2491
+
2492
+ /* ReplayStage sets its own inline size and position; the stage box overrides them to fill the frame. */
2493
+ [data-slot="replay-preview-stage"] > .replay-preview__page {
2494
+ position: absolute !important;
2495
+ inset: 0 !important;
2496
+ }
2497
+
2498
+ :where([data-slot="replay-preview-pointer"]) {
2499
+ position: absolute;
2500
+ inset: 0;
2501
+ overflow: hidden;
2502
+ }
2503
+
2504
+ :where([data-slot="replay-preview-ripple"]) {
2505
+ position: absolute;
2506
+ width: 44px;
2507
+ height: 44px;
2508
+ transform-origin: center;
2509
+ border: 2px solid var(--primary, #4f46e5);
2510
+ border-radius: 50%;
2511
+ background: color-mix(in srgb, var(--primary, #4f46e5) 20%, transparent);
2512
+ }
2513
+
2514
+ :where([data-slot="replay-preview-cursor"]) {
2515
+ position: absolute;
2516
+ transform-origin: top left;
2517
+ filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, 0.35));
2518
+ }
2519
+
2520
+ :where([data-slot="replay-preview-poster"]) {
2521
+ position: absolute;
2522
+ inset: 0;
2523
+ z-index: 10;
2524
+ transition: opacity 0.22s ease-out;
2525
+ }
2526
+
2527
+ :where([data-slot="replay-preview-poster"][data-leaving]) {
2528
+ opacity: 0;
2529
+ pointer-events: none;
2530
+ }
2531
+
2532
+ :where([data-slot="replay-preview-skeleton"]) {
2533
+ position: relative;
2534
+ display: flex;
2535
+ flex-direction: column;
2536
+ gap: 6%;
2537
+ width: 100%;
2538
+ height: 100%;
2539
+ padding: 4%;
2540
+ background: var(--background, #ffffff);
2541
+ }
2542
+
2543
+ :where([data-slot="replay-preview-skeleton"] i) {
2544
+ display: block;
2545
+ height: 5%;
2546
+ min-height: 8px;
2547
+ border-radius: 4px;
2548
+ background: color-mix(in srgb, var(--muted-foreground, #71717a) 16%, transparent);
2549
+ animation: docstream-replay-pulse 1.6s ease-in-out infinite;
2550
+ }
2551
+
2552
+ :where([data-slot="replay-preview-skeleton"] i[data-tone="block"]) {
2553
+ border-radius: 8px;
2554
+ min-height: 12px;
2555
+ }
2556
+
2557
+ :where([data-slot="replay-preview-skeleton"] [data-part="header"]) {
2558
+ display: flex;
2559
+ align-items: center;
2560
+ gap: 3%;
2561
+ }
2562
+
2563
+ :where([data-slot="replay-preview-skeleton"] [data-part="header"] > span) {
2564
+ flex: 1;
2565
+ }
2566
+
2567
+ :where([data-slot="replay-preview-skeleton"] [data-part="hero"]) {
2568
+ display: flex;
2569
+ flex-direction: column;
2570
+ gap: 8px;
2571
+ }
2572
+
2573
+ :where([data-slot="replay-preview-skeleton"] [data-part="hero"] i) {
2574
+ min-height: 0;
2575
+ }
2576
+
2577
+ :where([data-slot="replay-preview-skeleton"] [data-part="grid"]) {
2578
+ display: grid;
2579
+ flex: 1;
2580
+ grid-template-columns: repeat(4, 1fr);
2581
+ gap: 2.5%;
2582
+ }
2583
+
2584
+ :where([data-slot="replay-preview-skeleton"] [data-part="grid"] i) {
2585
+ height: 70%;
2586
+ }
2587
+
2588
+ :where([data-slot="replay-preview-skeleton"] [data-part="empty"]) {
2589
+ position: absolute;
2590
+ inset: 0;
2591
+ display: grid;
2592
+ place-items: center;
2593
+ }
2594
+
2595
+ :where([data-slot="replay-preview-skeleton"] [data-part="empty"] > span) {
2596
+ padding: 6px 12px;
2597
+ border-radius: 999px;
2598
+ color: var(--muted-foreground, #71717a);
2599
+ background: var(--card, #ffffff);
2600
+ box-shadow: 0 0 0 1px var(--border, #e4e4e7), 0 4px 16px rgba(0, 0, 0, 0.08);
2601
+ font-size: 12.5px;
2602
+ font-weight: 500;
2603
+ }
2604
+
2605
+ /* ── the big play button ─────────────────────────────────────── */
2606
+ :where([data-slot="replay-preview-center"]) {
2607
+ position: absolute;
2608
+ inset: 0;
2609
+ z-index: 10;
2610
+ display: grid;
2611
+ place-items: center;
2612
+ pointer-events: none;
2613
+ visibility: hidden;
2614
+ opacity: 0;
2615
+ scale: 1.15;
2616
+ transition: opacity 0.16s ease-out, scale 0.2s ease-out, visibility 0s linear 0.2s;
2617
+ }
2618
+
2619
+ :where([data-slot="replay-preview-center"][data-show]) {
2620
+ visibility: visible;
2621
+ opacity: 1;
2622
+ scale: 1;
2623
+ transition: opacity 0.2s ease-out, scale 0.32s cubic-bezier(0.34, 1.56, 0.64, 1), visibility 0s;
2624
+ }
2625
+
2626
+ :where([data-slot="replay-preview-center"] > button) {
2627
+ display: grid;
2628
+ place-items: center;
2629
+ width: 56px;
2630
+ height: 56px;
2631
+ margin: 0;
2632
+ padding: 0;
2633
+ border: 0;
2634
+ border-radius: 50%;
2635
+ outline: none;
2636
+ cursor: pointer;
2637
+ pointer-events: auto;
2638
+ appearance: none;
2639
+ color: var(--background, #ffffff);
2640
+ background: color-mix(in srgb, var(--foreground, #18181b) 72%, transparent);
2641
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
2642
+ -webkit-backdrop-filter: blur(12px);
2643
+ backdrop-filter: blur(12px);
2644
+ transition: scale 0.16s ease-out;
2645
+ }
2646
+
2647
+ :where([data-slot="replay-preview-center"] > button:hover) {
2648
+ scale: 1.05;
2649
+ }
2650
+
2651
+ :where([data-slot="replay-preview-center"] > button:active) {
2652
+ scale: 0.95;
2653
+ }
2654
+
2655
+ :where([data-slot="replay-preview-center"] > button > svg) {
2656
+ translate: 1px 0;
2657
+ }
2658
+
2659
+ /* ── controls ────────────────────────────────────────────────── */
2660
+ :where([data-slot="replay-preview-controls"]) {
2661
+ display: flex;
2662
+ flex-shrink: 0;
2663
+ align-items: center;
2664
+ gap: 4px;
2665
+ height: 44px;
2666
+ padding: 0 6px;
2667
+ border-top: 1px solid var(--border, #e4e4e7);
2668
+ background: var(--card, #ffffff);
2669
+ }
2670
+
2671
+ :where([data-slot="replay-preview-controls"] button) {
2672
+ display: inline-grid;
2673
+ flex-shrink: 0;
2674
+ place-items: center;
2675
+ height: 32px;
2676
+ min-width: 32px;
2677
+ margin: 0;
2678
+ padding: 0;
2679
+ border: 0;
2680
+ border-radius: 8px;
2681
+ outline: none;
2682
+ cursor: pointer;
2683
+ appearance: none;
2684
+ color: var(--foreground, #18181b);
2685
+ background: transparent;
2686
+ font: inherit;
2687
+ transition: background-color 0.12s ease-out;
2688
+ }
2689
+
2690
+ :where([data-slot="replay-preview-controls"] button:hover:not(:disabled)) {
2691
+ background: color-mix(in srgb, var(--foreground, #18181b) 8%, transparent);
2692
+ }
2693
+
2694
+ :where([data-slot="replay-preview-controls"] button:disabled) {
2695
+ cursor: default;
2696
+ opacity: 0.5;
2697
+ }
2698
+
2699
+ :where([data-slot="replay-preview-controls"] button:focus-visible) {
2700
+ box-shadow: 0 0 0 2px var(--ring, #6366f1);
2701
+ }
2702
+
2703
+ :where([data-slot="replay-preview-speed"]) {
2704
+ height: 28px;
2705
+ min-width: 42px;
2706
+ padding: 0 6px;
2707
+ border-radius: 6px;
2708
+ font-size: 12px;
2709
+ font-variant-numeric: tabular-nums;
2710
+ }
2711
+
2712
+ :where([data-slot="replay-preview-time"]) {
2713
+ flex-shrink: 0;
2714
+ width: 74px;
2715
+ color: var(--muted-foreground, #71717a);
2716
+ font-size: 11.5px;
2717
+ font-weight: 500;
2718
+ font-variant-numeric: tabular-nums;
2719
+ }
2720
+
2721
+ :where([data-slot="replay-preview-time"] > span) {
2722
+ color: var(--foreground, #18181b);
2723
+ }
2724
+
2725
+ /* ── scrubber: a native range, with the markers' rail above it ─
2726
+ (the thumb and track pseudo-elements can't sit inside :where(); the layer still lets hosts win) */
2727
+ :where([data-slot="replay-preview-scrubber"]) {
2728
+ position: relative;
2729
+ display: flex;
2730
+ flex: 1 1 0%;
2731
+ flex-direction: column;
2732
+ justify-content: center;
2733
+ align-self: stretch;
2734
+ min-width: 0;
2735
+ padding-inline: 4px;
2736
+ }
2737
+
2738
+ :where([data-slot="replay-preview-markers"]) {
2739
+ position: absolute;
2740
+ inset-inline: 4px;
2741
+ top: 13px;
2742
+ height: 10px;
2743
+ margin-inline: 6px;
2744
+ }
2745
+
2746
+ :where([data-slot="replay-preview-scrubber"][data-markers] > input) {
2747
+ transform: translateY(5px);
2748
+ }
2749
+
2750
+ :where([data-slot="replay-preview-markers"] > button) {
2751
+ position: absolute;
2752
+ top: 50%;
2753
+ box-sizing: border-box;
2754
+ width: 8px;
2755
+ height: 8px;
2756
+ min-width: 0;
2757
+ margin: 0;
2758
+ padding: 0;
2759
+ border: 0;
2760
+ border-radius: 50%;
2761
+ outline: none;
2762
+ cursor: pointer;
2763
+ appearance: none;
2764
+ background: var(--success, #22c55e);
2765
+ box-shadow: 0 0 0 2px var(--card, #ffffff);
2766
+ translate: -50% -50%;
2767
+ transition: scale 0.16s ease-out;
2768
+ }
2769
+
2770
+ :where([data-slot="replay-preview-markers"] > button:hover:not(:disabled)) {
2771
+ scale: 1.5;
2772
+ }
2773
+
2774
+ :where([data-slot="replay-preview-markers"] > button[data-kind="click"]) {
2775
+ width: 3px;
2776
+ height: 8px;
2777
+ border-radius: 1.5px;
2778
+ background: var(--tertiary-foreground, #a1a1aa);
2779
+ box-shadow: none;
2780
+ }
2781
+
2782
+ :where([data-slot="replay-preview-markers"] > button[data-kind="error"]) {
2783
+ background: var(--destructive, #ef4444);
2784
+ }
2785
+
2786
+ :where([data-slot="replay-preview-markers"] > button[data-kind="network"]) {
2787
+ background: var(--warning, #f59e0b);
2788
+ }
2789
+
2790
+ :where([data-slot="replay-preview-markers"] > button[data-kind="navigation"]) {
2791
+ background: var(--primary, #4f46e5);
2792
+ }
2793
+
2794
+ :where([data-slot="replay-preview-markers"] > button:focus-visible) {
2795
+ box-shadow: 0 0 0 2px var(--card, #ffffff), 0 0 0 4px var(--ring, #6366f1);
2796
+ }
2797
+
2798
+ :where([data-slot="replay-preview-scrubber"] > input[type="range"]) {
2799
+ --replay-track: 4px;
2800
+ --replay-thumb: 12px;
2801
+ appearance: none;
2802
+ -webkit-appearance: none;
2803
+ display: block;
2804
+ width: 100%;
2805
+ height: 20px;
2806
+ margin: 0;
2807
+ padding: 0;
2808
+ outline: none;
2809
+ cursor: pointer;
2810
+ background: transparent;
2811
+ }
2812
+
2813
+ :where([data-slot="replay-preview-scrubber"] > input[type="range"]:disabled) {
2814
+ cursor: default;
2815
+ opacity: 0.5;
2816
+ }
2817
+
2818
+ [data-slot="replay-preview-scrubber"] > input[type="range"]::-webkit-slider-runnable-track {
2819
+ height: var(--replay-track);
2820
+ border-radius: 999px;
2821
+ background: linear-gradient(
2822
+ to right,
2823
+ var(--primary, #4f46e5) var(--replay-progress, 0%),
2824
+ color-mix(in srgb, var(--muted-foreground, #71717a) 26%, transparent) var(--replay-progress, 0%)
2825
+ );
2826
+ }
2827
+
2828
+ [data-slot="replay-preview-scrubber"] > input[type="range"]::-moz-range-track {
2829
+ height: var(--replay-track);
2830
+ border-radius: 999px;
2831
+ background: color-mix(in srgb, var(--muted-foreground, #71717a) 26%, transparent);
2832
+ }
2833
+
2834
+ [data-slot="replay-preview-scrubber"] > input[type="range"]::-moz-range-progress {
2835
+ height: var(--replay-track);
2836
+ border-radius: 999px;
2837
+ background: var(--primary, #4f46e5);
2838
+ }
2839
+
2840
+ [data-slot="replay-preview-scrubber"] > input[type="range"]::-webkit-slider-thumb {
2841
+ -webkit-appearance: none;
2842
+ width: var(--replay-thumb);
2843
+ height: var(--replay-thumb);
2844
+ margin-top: calc((var(--replay-track) - var(--replay-thumb)) / 2);
2845
+ border: 0;
2846
+ border-radius: 50%;
2847
+ background: var(--primary, #4f46e5);
2848
+ box-shadow: 0 0 0 2px var(--card, #ffffff), 0 1px 3px rgba(0, 0, 0, 0.3);
2849
+ }
2850
+
2851
+ [data-slot="replay-preview-scrubber"] > input[type="range"]::-moz-range-thumb {
2852
+ width: var(--replay-thumb);
2853
+ height: var(--replay-thumb);
2854
+ border: 0;
2855
+ border-radius: 50%;
2856
+ background: var(--primary, #4f46e5);
2857
+ box-shadow: 0 0 0 2px var(--card, #ffffff), 0 1px 3px rgba(0, 0, 0, 0.3);
2858
+ }
2859
+
2860
+ [data-slot="replay-preview-scrubber"] > input[type="range"]:focus-visible::-webkit-slider-thumb {
2861
+ box-shadow: 0 0 0 2px var(--card, #ffffff), 0 0 0 4px var(--ring, #6366f1);
2862
+ }
2863
+
2864
+ [data-slot="replay-preview-scrubber"] > input[type="range"]:focus-visible::-moz-range-thumb {
2865
+ box-shadow: 0 0 0 2px var(--card, #ffffff), 0 0 0 4px var(--ring, #6366f1);
2866
+ }
2867
+
2868
+ /* ── iframe embeds (a public Loop QA page) and their notes ───── */
2869
+ :where(.replay-preview__frame) {
2870
+ position: absolute;
2871
+ inset: 0;
2872
+ display: block;
2873
+ width: 100%;
2874
+ height: 100%;
2875
+ border: 0;
2876
+ background: var(--background, #ffffff);
2877
+ }
2878
+
2879
+ :where(.replay-preview__invalid, .replay-preview__empty, .replay-preview__error) {
2880
+ position: absolute;
2881
+ inset: 0;
2882
+ display: flex;
2883
+ align-items: center;
2884
+ justify-content: center;
2885
+ padding: 20px;
2886
+ color: var(--muted-foreground, #71717a);
2887
+ font-size: 13px;
2888
+ line-height: 1.5;
2889
+ text-align: center;
2890
+ }
2891
+
2892
+ :where(.replay-preview__invalid) {
2893
+ color: var(--primary, #4f46e5);
2894
+ }
2895
+
2896
+ :where(.replay-preview__error) {
2897
+ color: var(--destructive, #ef4444);
2898
+ }
2409
2899
  }
2410
2900
 
2411
- .replay-preview__controls {
2412
- display: flex;
2413
- align-items: center;
2414
- gap: 8px;
2415
- padding: 8px 10px;
2416
- border-top: 1px solid rgba(148, 163, 184, 0.2);
2417
- background: #111827;
2418
- font: 12px/1.2 ui-sans-serif, system-ui, sans-serif;
2901
+ @keyframes docstream-replay-spin {
2902
+ to {
2903
+ transform: rotate(360deg);
2904
+ }
2419
2905
  }
2420
2906
 
2421
- .replay-preview__controls button,
2422
- .replay-preview__controls select {
2423
- border: 1px solid rgba(148, 163, 184, 0.3);
2424
- border-radius: 6px;
2425
- padding: 5px 8px;
2426
- color: inherit;
2427
- background: #1e293b;
2428
- cursor: pointer;
2907
+ @keyframes docstream-replay-pulse {
2908
+ 50% {
2909
+ opacity: 0.55;
2910
+ }
2429
2911
  }
2430
2912
 
2431
- .replay-preview__controls input[type='range'] {
2432
- min-width: 60px;
2433
- flex: 1;
2434
- accent-color: #38bdf8;
2913
+ @media (prefers-reduced-motion: reduce) {
2914
+ @layer docstream.replay {
2915
+ :where([data-slot="replay-preview"] *) {
2916
+ animation: none !important;
2917
+ transition-duration: 0.01ms !important;
2918
+ transition-delay: 0s !important;
2919
+ }
2920
+
2921
+ :where([data-slot="replay-preview-center"]) {
2922
+ scale: 1;
2923
+ }
2924
+ }
2435
2925
  }
2436
2926
 
2437
2927
  /* Keep every rendered table variant flush, after the shared block spacing rules. */
@@ -1,9 +0,0 @@
1
- import type { ReplayEvent } from './types.js';
2
-
3
- export default function NativeReplay({ events, autoplay, loop, speeds, }: {
4
- events: ReplayEvent[];
5
- autoplay?: boolean;
6
- loop?: boolean;
7
- speeds?: number[];
8
- }): import("react").JSX.Element;
9
- //# sourceMappingURL=NativeReplay.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"NativeReplay.d.ts","sourceRoot":"","sources":["../../src/replay/NativeReplay.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,sBAAsB,CAAC;AAK9B,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACnC,MAAM,EACN,QAAgB,EAChB,IAAY,EACZ,MAAuB,GACxB,EAAE;IACD,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,+BAwNA"}