Skip to content

Redesign UI with onboarding walkthrough and query presets - #22

Merged
Catrya merged 7 commits into
mainfrom
redesign
May 20, 2026
Merged

Redesign UI with onboarding walkthrough and query presets#22
Catrya merged 7 commits into
mainfrom
redesign

Conversation

@Catrya

@Catrya Catrya commented Apr 24, 2026

Copy link
Copy Markdown
Owner
  • Sticky topbar with status pills (relays, streaming, "? How it works")
  • Segmented Mode: Search | Stream and Query by: Kind | NIP controls above the filter grid
  • NIP field replaces Kind inline when Query by: NIP is selected; old "Search by NIP" section removed
  • Empty state with suggested relays and 4 query presets (Notes, Mostro, Zaps, Profiles)
  • 3-step walkthrough modal, dismissal persisted in localStorage
  • Stream-bar with evt/sec counter alongside existing connecting/historical/live phases

Test plan

  • Topbar pills show correct relay count and streaming state
  • Walkthrough opens on first load, dismisses, reopens from "? How it works"
  • Toggling Query by: Kind ↔ NIP swaps the field in-place
  • NIP entry resolves automatically when clicking Search/Stream
  • Empty state presets populate filters correctly
  • Suggested relays add on click
  • Search mode returns historical events as before
  • Stream mode shows evt/sec counter and all three phases

Summary by CodeRabbit

  • New Features

    • Interactive three-step walkthrough guide for onboarding (dismissible)
    • Query presets and relay suggestions for quick setup
    • Real-time event-rate metrics during live streaming
    • NIP-based filtering option alongside direct kind filtering
  • Style

    • Complete theme redesign to a deep-violet palette
    • New UI components: stream activity bar, segmented controls, progress/indicator pills
    • Enhanced empty state with preset and relay quick-start cards

Review Change Stack

@coderabbitai

coderabbitai Bot commented Apr 24, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Introduces a three-step onboarding component, a deep-dark violet theme and utility styles, and a refactor of EventMonitor to support search/stream modes, NIP→kind resolution, streaming telemetry (eventRate), and quick-start presets/suggested relays.

Changes

EventMonitor + Theme + Onboarding

Layer / File(s) Summary
Walkthrough component
src/components/Walkthrough.tsx
New exported Walkthrough component with three internal steps, overlay dialog, keyboard/background close handling, and exported WALK_STORAGE_KEY constant.
CSS: palette, body & topbar
src/index.css
Replace :root tokens with deep-dark violet HSL vars and hex helpers; update body radial-gradient; add topbar, status pill, and LED indicator styles.
CSS: controls, empty-state, walkthrough styles
src/index.css
Segmented controls, pulsing stream bar, empty-state quickstart and presets grid, walkthrough modal styles, JSON viewer/container simplification, and updated utility color classes.
EventMonitor: imports, types, helpers
src/pages/EventMonitor.tsx
Add presets/Walkthrough imports, define QueryType union, and consolidate npub/relay normalization helpers.
EventMonitor: state, refs, walkthrough persistence
src/pages/EventMonitor.tsx
Add mode/queryType state, walkthrough persistence in localStorage, streaming telemetry scaffolding, nip refs, and reset effects.
Query builder and search flow
src/pages/EventMonitor.tsx
Memoized filter builder, non-stream query construction, parallel relay querying, dedupe/sort/limit, and backfill of NIP-discovered kinds.
Streaming orchestration and flush/aggregation
src/pages/EventMonitor.tsx
Streaming init/reset, per-relay lifecycle (connecting/historical/live), throttled flushes, event aggregation with live-phase timestamps, and cleanup handling.
NIP resolution, event rate, and handlers
src/pages/EventMonitor.tsx
Rolling eventRate effect, resolveNipKinds implementation, and updated handleSearch/handleStream to resolve NIP-derived kinds prior to actions.
UI: mode/query controls, presets, and filter helpers
src/pages/EventMonitor.tsx
Clear/Apply preset helpers, suggested-relay insertion, segmented Mode/Query controls, conditional NIP vs kind inputs, and mode-aware action buttons with stream-bar.
Empty-state, event list, and minor UI tweaks
src/pages/EventMonitor.tsx
Distinguish no-relays vs no-events empty states, show quick-start relay suggestions and preset cards, event-card loop and footer/link text adjustments.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant EventMonitor
  participant Walkthrough
  participant Relay
  Client->>EventMonitor: Start Search / Start Stream
  EventMonitor->>Walkthrough: read WALK_STORAGE_KEY (on mount)
  EventMonitor->>Relay: query / subscribe (built filters)
  Relay-->>EventMonitor: events, EOSE, closed signals
  EventMonitor->>Client: render events, update eventRate
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰 I hopped through three slides to show the way,
Quick relays and presets to start the play,
Violet nights light the stream's soft glow,
Kinds resolve, rates tick, events flow—hooray! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the two main changes: UI redesign with the addition of onboarding walkthrough and query presets functionality.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch redesign

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (5)
src/index.css (1)

188-201: Consider honoring prefers-reduced-motion for the new pulse/fade animations.

.led.on, .led.violet, .stream-bar::before, and .walk-overlay all animate continuously. Users with vestibular sensitivity typically expect motion to be reduced or removed when the OS preference is set. A single @media (prefers-reduced-motion: reduce) block that sets animation: none on these selectors (and the fade-in on the walk overlay) is enough.

Also applies to: 288-299, 464-467

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/index.css` around lines 188 - 201, Add a prefers-reduced-motion media
rule to disable continuous animations and fades for users who request reduced
motion: target the animated selectors (.led.on, .led.violet,
.stream-bar::before, .walk-overlay and any other continuous-anim selectors like
the ones around lines 288-299 and 464-467) and set animation: none; and remove
transition/animation-based opacity changes (e.g., fade-in) inside the `@media`
(prefers-reduced-motion: reduce) block so those elements stop pulsing or fading
when the OS preference is set.
src/data/presets.ts (1)

1-21: LGTM — small, well-typed data module.

The QueryPreset shape lines up with how EventMonitor consumes it (id for key, title/desc for the card, kind string assigned straight into filters.kinds), and SUGGESTED_RELAYS holding bare hostnames matches addSuggestedRelay, which prepends wss://. One optional nit: storing relays as bare hosts and kinds as strings is fine, but documenting the convention in a short comment would save the next reader a trip to EventMonitor.tsx.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/data/presets.ts` around lines 1 - 21, Add a short inline comment
documenting the conventions: note that SUGGESTED_RELAYS contains bare hostnames
(no protocol) which are later prefixed with wss:// by addSuggestedRelay, and
that QueryPreset.kind is stored as a string and used directly in filters.kinds
(see PRESETS and EventMonitor consumption). Place the comments near the
SUGGESTED_RELAYS declaration and the QueryPreset interface so future readers
immediately understand the expectations.
src/pages/EventMonitor.tsx (3)

1273-1313: Empty state looks good.

Quick-start layout (suggested relays + preset cards) is a nice UX upgrade over the generic "No events found" card and the presets correctly drop the user into the right filters.kinds via applyPreset.

Coding guidelines mention using RelaySelector as the canonical empty state for missing content, but that component targets a single-relay switch flow; the custom SUGGESTED_RELAYS grid here is a better fit for a multi-relay debugging tool. Worth a brief comment noting the intentional deviation so future reviewers don't try to "fix" it.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/EventMonitor.tsx` around lines 1273 - 1313, Add a brief in-code
comment near the empty-state JSX explaining that this custom quickstart grid
(using SUGGESTED_RELAYS, PRESETS, and applyPreset) intentionally deviates from
the canonical RelaySelector component because RelaySelector is single-relay
focused while this view is a multi-relay debugging tool; mention RelaySelector
by name and note that the SUGGESTED_RELAYS grid/preset cards are deliberate to
avoid future reviewers refactoring it back to RelaySelector.

337-348: Rate-tracking array is unbounded between ticks.

addEvent pushes a timestamp for every event while the phase is live, and the 500 ms interval is the only thing trimming the window. At very high event rates (spiky relays) the array can grow large between ticks and produce a GC spike when .filter runs. A tiny guard — e.g., shift off entries older than 1 s on insert, or cap the array length — would make this robust without changing behavior.

Also applies to: 415-428

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/EventMonitor.tsx` around lines 337 - 348, The rate-tracking array
(rateWindowRef) can grow unbounded between ticks; update the addEvent handler(s)
(e.g., addEvent and the similar handler around lines 415-428) so that when you
push Date.now() you also immediately trim old entries (remove timestamps older
than now - 1000ms) or enforce a hard cap (e.g., max length) to prevent unbounded
growth; keep the existing behavior of only tracking after allEoseReceived but
perform the in-place trim/cap right after pushing to avoid large GC spikes when
the interval filter runs.

430-503: setTimeout(..., 0) after state updates is brittle; consider an effect-driven trigger.

resolveNipKinds calls setNipKinds(...) / setFilters(...) and then handleSearch schedules refetch() via setTimeout(0) so the query closure sees the updated nipKinds. This works today thanks to React 18 batching, but it's easy to regress under concurrent rendering or if someone later moves logic into a transition. A cleaner pattern is to set a "pending request" flag and trigger refetch() / setIsStreaming(true) from a useEffect keyed on the resolved kinds.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/EventMonitor.tsx` around lines 430 - 503, handleSearch relies on
setTimeout(..., 0) to let state updates from resolveNipKinds
(setNipKinds/setFilters) flush before calling refetch, which is brittle; instead
introduce a "pendingRequest" state or ref (e.g., pendingNipRef or pendingRequest
state) that handleSearch sets (when queryType === 'nip' and resolveNipKinds
returns kinds) and remove the setTimeout/refetch call there, then add a
useEffect that watches pendingRequest (or nipKinds plus queryType/validRelays)
and performs refetch(), sets setIsStreaming(true), clears error, and resets
pendingRequest after refetch starts; update resolveNipKinds/handleSearch to set
that flag (and not call refetch or rely on setTimeout) so the effect-driven
refetch sees the latest nipKinds reliably.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/Walkthrough.tsx`:
- Around line 44-87: The Walkthrough component currently sets role="dialog" but
lacks keyboard/focus handling; update Walkthrough to (1) create refs for the
dialog container (e.g., walkCardRef) and the primary action button (Start/Next),
(2) in a useEffect when mounted, save document.activeElement to restore later,
focus the dialog or primary button (use walkCardRef.current?.focus() or
startButtonRef.current?.focus()), and add a keydown listener that calls onClose
when Escape is pressed, and (3) on cleanup remove the keydown listener and
restore focus to the previously focused element; implement these changes around
the existing onClose, setStep, step, and isLast logic so behavior and labels
remain unchanged.

In `@src/index.css`:
- Around line 6-77: The :root color variables were fully updated but the .dark
selector still contains the old palette causing mixed/stale colors when the
.dark class is applied; update the .dark { ... } block to mirror the same
remapped custom properties and raw hex helpers you added under :root (all
variables like --bg-main, --surface-card, --text-hi, --accent-soft, --c-bg,
--c-accent, etc.), or remove any legacy .dark overrides so the new :root values
are consistently used when toggling themes.
- Around line 86-91: The Stylelint report flags two issues in the CSS: inside
the body rule (selector "body") add a blank line before the first background
declaration so the declaration-empty-line-before rule is satisfied, and
normalize any occurrences of the color keyword "currentColor" (found in the
block covering lines ~180-201) to lowercase "currentcolor" to satisfy
value-keyword-case; update the background/background-image declarations in the
body block and replace any "currentColor" tokens with "currentcolor" across the
file.

In `@src/pages/EventMonitor.tsx`:
- Line 94: The mode switch currently doesn't stop active streams; update the
mode change handling so switching away from 'stream' stops streaming by clearing
isStreaming (i.e., when calling setMode(...) ensure isStreaming is set false) or
add a useEffect that watches mode and resets isStreaming when mode !== 'stream'.
Specifically, modify where setMode('search') is invoked (the mode and setMode
state) or add a new useEffect that references mode and sets isStreaming = false
(or calls the existing stopStreaming routine) to ensure the streaming useEffect
(the one depending on isStreaming, validRelays, queryFilters, filters.limit) is
terminated when mode changes away from 'stream'.
- Around line 628-636: The custom pill span (className "status-pill clickable",
role="button", tabIndex={0}) currently activates via onKeyDown but doesn't
prevent the browser's default spacebar scroll; update the onKeyDown handler in
the EventMonitor component to call e.preventDefault() when the pressed key is '
' (space) (and optionally for 'Enter') before calling setWalkOpen(true) so the
space key activates the control without scrolling the page; modify the handler
attached to that span (the onKeyDown arrow function) to perform the
preventDefault and then call setWalkOpen(true).

---

Nitpick comments:
In `@src/data/presets.ts`:
- Around line 1-21: Add a short inline comment documenting the conventions: note
that SUGGESTED_RELAYS contains bare hostnames (no protocol) which are later
prefixed with wss:// by addSuggestedRelay, and that QueryPreset.kind is stored
as a string and used directly in filters.kinds (see PRESETS and EventMonitor
consumption). Place the comments near the SUGGESTED_RELAYS declaration and the
QueryPreset interface so future readers immediately understand the expectations.

In `@src/index.css`:
- Around line 188-201: Add a prefers-reduced-motion media rule to disable
continuous animations and fades for users who request reduced motion: target the
animated selectors (.led.on, .led.violet, .stream-bar::before, .walk-overlay and
any other continuous-anim selectors like the ones around lines 288-299 and
464-467) and set animation: none; and remove transition/animation-based opacity
changes (e.g., fade-in) inside the `@media` (prefers-reduced-motion: reduce) block
so those elements stop pulsing or fading when the OS preference is set.

In `@src/pages/EventMonitor.tsx`:
- Around line 1273-1313: Add a brief in-code comment near the empty-state JSX
explaining that this custom quickstart grid (using SUGGESTED_RELAYS, PRESETS,
and applyPreset) intentionally deviates from the canonical RelaySelector
component because RelaySelector is single-relay focused while this view is a
multi-relay debugging tool; mention RelaySelector by name and note that the
SUGGESTED_RELAYS grid/preset cards are deliberate to avoid future reviewers
refactoring it back to RelaySelector.
- Around line 337-348: The rate-tracking array (rateWindowRef) can grow
unbounded between ticks; update the addEvent handler(s) (e.g., addEvent and the
similar handler around lines 415-428) so that when you push Date.now() you also
immediately trim old entries (remove timestamps older than now - 1000ms) or
enforce a hard cap (e.g., max length) to prevent unbounded growth; keep the
existing behavior of only tracking after allEoseReceived but perform the
in-place trim/cap right after pushing to avoid large GC spikes when the interval
filter runs.
- Around line 430-503: handleSearch relies on setTimeout(..., 0) to let state
updates from resolveNipKinds (setNipKinds/setFilters) flush before calling
refetch, which is brittle; instead introduce a "pendingRequest" state or ref
(e.g., pendingNipRef or pendingRequest state) that handleSearch sets (when
queryType === 'nip' and resolveNipKinds returns kinds) and remove the
setTimeout/refetch call there, then add a useEffect that watches pendingRequest
(or nipKinds plus queryType/validRelays) and performs refetch(), sets
setIsStreaming(true), clears error, and resets pendingRequest after refetch
starts; update resolveNipKinds/handleSearch to set that flag (and not call
refetch or rely on setTimeout) so the effect-driven refetch sees the latest
nipKinds reliably.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6a577869-e855-49f6-ab6b-64236a4c7512

📥 Commits

Reviewing files that changed from the base of the PR and between d41cd0e and 019ac41.

📒 Files selected for processing (4)
  • src/components/Walkthrough.tsx
  • src/data/presets.ts
  • src/index.css
  • src/pages/EventMonitor.tsx

Comment thread src/components/Walkthrough.tsx
Comment thread src/index.css
Comment thread src/index.css
Comment on lines 86 to 91
body {
@apply bg-background text-foreground;
background: #1e1e2e;
background-image: none;
background: radial-gradient(circle at top, var(--c-bg-top), var(--c-bg) 60%, var(--c-bg-bottom));
background-attachment: fixed;
background-image: radial-gradient(circle at top, var(--c-bg-top), var(--c-bg) 60%, var(--c-bg-bottom));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Stylelint flags two small issues.

  • Line 88: missing empty line before the background: declaration inside body (declaration-empty-line-before).
  • Line 185: currentColor should be lowercase currentcolor (value-keyword-case).
♻️ Proposed fix
   body {
     `@apply` bg-background text-foreground;
+
     background: radial-gradient(circle at top, var(--c-bg-top), var(--c-bg) 60%, var(--c-bg-bottom));
@@
-  box-shadow: 0 0 0 0 currentColor;
+  box-shadow: 0 0 0 0 currentcolor;

Also applies to: 180-201

🧰 Tools
🪛 Stylelint (17.9.0)

[error] 88-88: Expected empty line before declaration (declaration-empty-line-before)

(declaration-empty-line-before)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/index.css` around lines 86 - 91, The Stylelint report flags two issues in
the CSS: inside the body rule (selector "body") add a blank line before the
first background declaration so the declaration-empty-line-before rule is
satisfied, and normalize any occurrences of the color keyword "currentColor"
(found in the block covering lines ~180-201) to lowercase "currentcolor" to
satisfy value-keyword-case; update the background/background-image declarations
in the body block and replace any "currentColor" tokens with "currentcolor"
across the file.

Comment thread src/pages/EventMonitor.tsx
Comment thread src/pages/EventMonitor.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (2)
src/index.css (2)

6-77: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Mirror the new palette tokens under .dark (or remove dark overrides entirely).

The color scheme remap is only defined in :root; this violates the repo rule for theme token updates and can produce mixed tokens when .dark is active.

♻️ Proposed fix
 `@layer` base {
   :root {
     ...
   }
+
+  .dark {
+    --bg-main: 240 26% 8%;
+    --bg-soft: 240 16% 15%;
+    --surface-card: 240 16% 15%;
+    --surface-input: 240 15% 20%;
+    --surface-border: 240 14% 25%;
+    --text-hi: 267 32% 96%;
+    --text-lo: 240 16% 76%;
+    --text-mute: 240 10% 55%;
+    --accent-soft: 258 90% 66%;
+    --accent-bright: 258 90% 76%;
+    --accent-glow: 251 96% 85%;
+    --accent-2: 239 84% 67%;
+    /* include matching --c-* helpers if .dark is used as an override layer */
+  }
 }

As per coding guidelines, "When implementing custom color schemes, update CSS custom properties in src/index.css for both :root and .dark selectors".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/index.css` around lines 6 - 77, The palette tokens are only defined in
:root which breaks the repo rule for theme updates; mirror all custom properties
declared in :root (e.g., --bg-main, --bg-soft, --surface-card, --surface-input,
--surface-border, --text-hi, --text-lo, --text-mute, --accent-soft,
--accent-bright, --accent-glow, --accent-2, the shadcn tokens like
--background/--foreground/--card/etc., and the raw hex helpers --c-*) into a
matching .dark selector (or remove the dark-specific overrides entirely) so that
when .dark is active the same set of tokens is explicitly set; ensure the values
in .dark reflect the intended dark-theme remap and include the same token names
as in :root.

86-91: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Stylelint issues from prior review still appear unresolved.

declaration-empty-line-before in body and value-keyword-case for currentColor are still present.

♻️ Proposed fix
   body {
     `@apply` bg-background text-foreground;
+
     background: radial-gradient(circle at top, var(--c-bg-top), var(--c-bg) 60%, var(--c-bg-bottom));
@@
-  box-shadow: 0 0 0 0 currentColor;
+  box-shadow: 0 0 0 0 currentcolor;

Also applies to: 187-187

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/index.css` around lines 86 - 91, The body rule is triggering stylelint
rules: add a blank line after the opening brace in the body selector to satisfy
declaration-empty-line-before, and normalize keyword casing by replacing any
instances of "currentColor" with lowercase "currentcolor" (including other
occurrences mentioned) to satisfy value-keyword-case; update the CSS in the body
block and any other selectors using currentColor accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@src/index.css`:
- Around line 6-77: The palette tokens are only defined in :root which breaks
the repo rule for theme updates; mirror all custom properties declared in :root
(e.g., --bg-main, --bg-soft, --surface-card, --surface-input, --surface-border,
--text-hi, --text-lo, --text-mute, --accent-soft, --accent-bright,
--accent-glow, --accent-2, the shadcn tokens like
--background/--foreground/--card/etc., and the raw hex helpers --c-*) into a
matching .dark selector (or remove the dark-specific overrides entirely) so that
when .dark is active the same set of tokens is explicitly set; ensure the values
in .dark reflect the intended dark-theme remap and include the same token names
as in :root.
- Around line 86-91: The body rule is triggering stylelint rules: add a blank
line after the opening brace in the body selector to satisfy
declaration-empty-line-before, and normalize keyword casing by replacing any
instances of "currentColor" with lowercase "currentcolor" (including other
occurrences mentioned) to satisfy value-keyword-case; update the CSS in the body
block and any other selectors using currentColor accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 31d3aeb0-404f-4573-a2ad-825e951ec25d

📥 Commits

Reviewing files that changed from the base of the PR and between 019ac41 and d33902b.

📒 Files selected for processing (3)
  • src/components/Walkthrough.tsx
  • src/index.css
  • src/pages/EventMonitor.tsx

@Catrya
Catrya merged commit 2563b82 into main May 20, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant