Components

Library components

The recordings library: the shell around it, how recordings are listed, searched and annotated, and the messages it gives back. Everything on this page is rendered in desktop mode unless a state is tagged browser only.

Rendered from the shipped source with synthetic demo data. Not captured from a running app. Native microphone capture has not passed host qualification; this page shows interface states only and does not imply working hardware capture.

Browsing the library

How the list of recordings is presented: the page heading, source tabs, the rows themselves and the loading, empty and footer states around them.

H
Page heading
Names the current view in the serif heading and says how many recordings the whole workspace holds.
apps/desktop/src/App.tsx · Workspace() .page-heading
Library

Library.

5 recordings · local workspace

28px Georgia (fallback serif) with a green period; the first block's 40px is overridden.
Recorded here

Recorded here.

5 recordings · local workspace

Imported files

Imported files.

5 recordings · local workspace

A collection (tag name)

meetings.

5 recordings · local workspace

The tag name is shown as typed, with no capitalisation.
One recording quirk

Library.

1 recordings · local workspace

The line is a fixed plural: it reads 1 recordings. The footer handles the singular correctly; this line does not.
Empty

Library.

0 recordings · local workspace

Reads 0 recordings. The count is the whole workspace, never the filtered or searched count.
▭
Source filter tabs
Lets the user narrow the list to everything, things recorded in the app, or imported files.
apps/desktop/src/App.tsx · Workspace() .filter-tabs
All audio active
Only the first tab carries a count badge.
Recordings active
Imports active
A collection is open: no tab active
Opening a tag leaves all three tabs unhighlighted, so the active state does not show the collection filter.
⇄
Library toolbar
Groups source tabs, search and sort on one line directly above the list.
apps/desktop/src/App.tsx · Workspace() .library-toolbar
Desktop, idle
The sort control is 91px wide and the select inherits a 12px side padding from the form rule label > select, so Newest first is cut to Newest fir. This is how it renders in the shipped CSS.
Desktop, with a search
Best matches is cut to Best matc(h) for the same reason.
Browser preview browser only
Different placeholder, no Best matches option, and the full-text features below are unavailable.
▤
List header
Labels the four columns of the recording list so rows read as a table.
apps/desktop/src/App.tsx · Workspace() .list-header
Header
RECORDINGWAVEFORMDURATIONADDED
Five grid cells (the last is an empty spacer for the open arrow). It stays visible while loading and when the list is empty.
Aligned above a row
RECORDINGWAVEFORMDURATIONADDED
The header grid has five columns and the row six; the percentage columns on the right line up, and RECORDING sits over the icon plus title.
♪
Recording row
One recording in the list: title, where it came from, its tags, a waveform preview, length and date, with a link to edit notes and kind.
apps/desktop/src/App.tsx · Workspace() .library-entry > .asset-row, .library-row-details
Recorded here
The Notes and kind link is a separate button under the row. Row hover (a lighter fill and the open arrow) is not shown; it only exists on pointer hover.
Imported
A folder icon and the word Imported replace the microphone and Recording.
Edited recipe revision above 0
The Edited label appears whenever the recipe revision is greater than 0, so any saved trim counts.
No tags
The meta line then holds only the source label.
Three tags: only two shown
Tags beyond the first two are silently dropped from the row (the third tag, onboarding, never shows); they remain in the sidebar collections.
Long title is cut off
The title truncates with an ellipsis on one line; the full text is not exposed on hover (no title attribute).
Recovered recording
Source recovered is drawn exactly like a normal recording; nothing in the row says it was recovered.
Icon colour cycles by row position
The tile and waveform colour follow the position in the list (index mod 4), so they change when the list is re-sorted or filtered; they are not tied to the recording.
Search hit with matches desktop only
A kind chip and up to two matching snippets are added under the meta line.
∿
Waveform preview
A tiny bar-graph of the recording's loudness shown in each row so recordings can be told apart at a glance.
apps/desktop/src/App.tsx · Wave()
Speech: bursts and pauses
65 bars; each bar is the loudest of its slice of the stored peaks.
Steady ambience, tinted
The tint comes from the row's hue class, not from the Wave itself.
Near silence
Bars never fall below a 4px floor, so a silent file still draws a flat dotted line rather than nothing.
Few stored peaks (10)
When there are fewer peaks than bars, neighbouring bars repeat the same peak, giving a blocky shape.
No stored peaks
An empty peaks array renders the same flat floor as silence; it is not flagged as missing data.
∅
Empty and no-match states
Tells the user why the list is blank and offers the one sensible next step: try sample audio, or clear the filters.
apps/desktop/src/App.tsx · Workspace() .empty-state
No recordings yet

No recordings yet

Record a thought or import an audio file to begin.

A single compact row (112px), not an illustration. The only action is Explore with sample audio; Record and Import live in the top bar.
Sample audio being added

No recordings yet

Record a thought or import an audio file to begin.

While an import or sample is running the link is dimmed and disabled.
No matching recordings

No matching recordings

Try another search or collection.

Show all audio clears the query, source tab, collection and kind, but leaves sort and the two search options as they were.
While a search is still running quirk

No matching recordings

Try another search or collection.

On desktop, between typing and the results arriving (180ms debounce plus the search itself) the visible list is empty, so this same No matching recordings message flashes before results appear.
◌
Loading state
Shown for the moment it takes to open the local library at start-up.
apps/desktop/src/App.tsx · Workspace() .loading
Opening your library
Opening your library…
The spinner rotates continuously; reduced-motion users get a still icon. The column header and footer are still on screen around it.

Searching and filtering

Finding a recording by what it contains. On desktop the search looks through titles, tags, notes, labels and transcripts locally; in a browser preview it is a simple title and tag filter.

⇅
Sort control
Chooses the order of the list: newest, oldest, alphabetical, or most relevant to a search.
apps/desktop/src/App.tsx · Workspace() .sort-control
Closed, default
Truncated to Newest fir in the shipped CSS (91px wide select plus the form-field padding leaking from label > select, styles.css:1329-1341).
Desktop options desktop only
Shown as an open list here. Best matches exists only on desktop.
Browser preview options browser only
Three options only.
Best matches with no search quirk
With nothing typed, the list silently falls back to newest-first; the control still says Best matches.
☑
Library search controls
Narrows a search by recording kind and decides whether small typos and older transcript text may count as matches.
apps/desktop/src/App.tsx · Workspace() .library-search-controls
Desktop, idle
Typo matching starts on; older transcript evidence starts off. No status text until a search is active.
Searching
Searching locally…
Shown while the debounced local search runs.
Results found, filtered to a kind
3 matches
One match quirk
1 matches
The count is always plural.
No matches
0 matches
Typo matching off
2 matches
Browser preview browser only
Every control is disabled; the kind list and options are still visible but cannot be used.
Kind choices
The twelve kinds come from RECORDING_KINDS plus All kinds.
“
Match snippets
Shows the user which part of a recording matched their search, so they can trust a result before opening it.
apps/desktop/src/LibrarySearch.tsx · LibraryMatch()
Title
TitleInterview: onboarding research 03
Tags
Tagsresearch, interviews, onboarding
Notes
NotesCompare against the onboarding flow from round one.
User-assigned label
User-assigned label · Speaker 2Participant 3
Recording kind
Recording kindInterview
Reviewed transcript with speaker
Reviewed transcript · Participant 3…the onboarding checklist felt longer than the product itself, so I skipped most of it…
Older transcript text
Raw transcript · older edit…walk me through the onboarding steps again, slowly…
Appears only when Include older transcript evidence is on.
Typo match
Raw transcript · text typo match…the on-boarding flow had three drop-off points…
Appears only when Small text typos is on.
Older and typo together, with speaker
Raw transcript · Participant 3 · older edit · text typo match…the onbording call ran long…
More than two sources
TitleInterview: onboarding research 03NotesCompare against round one.+3 other matching sources
Only two snippets are drawn; the rest collapse into a count (here 1 snippet not drawn plus 2 reported by the search, so +3).
Hit with no snippets
An empty block is rendered (it still takes a few pixels of margin); the row shows no reason for the match.
!
Search limitations and errors
Warns that some transcripts could not be searched, or that the search itself failed, so missing results are not mistaken for no results.
apps/desktop/src/App.tsx · Workspace() .library-search-message
Disclosure, closed
2 evidence limitations — results may be incomplete
  • rec_0a41c9 / tr_0007: transcript file could not be read; skipped.
The count adds the listed warnings and the unlisted extras (1 listed + 1 more = 2). With a single warning it reads 1 evidence limitations.
Disclosure, open
3 evidence limitations — results may be incomplete
  • rec_0a41c9 / tr_0007: transcript file could not be read; skipped.
  • rec_3f90d2: no transcript for this recording.
Each line is asset id, optional transcript id and the reason, in raw form. The ids are internal identifiers, not titles.
Single warning quirk
1 evidence limitations — results may be incomplete
  • rec_0a41c9 / tr_0007: transcript file could not be read; skipped.
The summary is a fixed plural.
Search failed
The text is whatever the desktop shell returns as the error string; this wording is an example.
⇆
Search pagination
Moves through search results fifty at a time when there are more matches than fit on one page.
apps/desktop/src/App.tsx · Workspace() .library-search-pages
First page of many
1–50 of 124
Previous is disabled on the first page.
Middle page
51–100 of 124
Last page
101–124 of 124
Reads 101–124 of 124 and Next is disabled.
Single page of results
1–3 of 3
No results
0–0 of 0
Reads 0–0 of 0 with both buttons disabled.
While searching
51–100 of 124
Both buttons are disabled during a search. The pager appears only on desktop and only once a search has returned a response.

Notes and kind

Per-recording context that is saved separately from title and tags and feeds search: a kind (meeting, journal, interview...) and free-text notes.

✎
Notes and kind panel
Lets the user label a recording with a kind and add notes that stay on this device; reached from the Notes and kind link on a row, inside the Recording details dialog.
apps/desktop/src/LibraryDetails.tsx · LibraryDetails()
Loading
0 / 16,384 bytes
Everything is disabled while the saved details are fetched. Shown at dialog width (510px) without the dialog chrome.
Loaded, nothing changed
85 / 16,384 bytes
Save is disabled until something differs from the saved copy.
Draft edited
107 / 16,384 bytes
Reload now warns that it will discard the draft.
Saved
85 / 16,384 bytes

Notes and kind saved locally.

Too long
16,520 / 16,384 bytes

Notes exceed 16,384 UTF-8 bytes. Shorten them before saving.

The limit is 16,384 UTF-8 bytes, not characters; the counter and alert show the overrun and Save is disabled.
Save failed
39 / 16,384 bytes

The recording's details changed elsewhere. Reload and try again. Your draft is retained in this panel.

The message comes from the desktop shell; this wording is an example. The draft is kept.
Could not load
0 / 16,384 bytes

The recording's details could not be read.

Fields stay disabled and Reload is the only way forward.
Browser preview browser only
0 / 16,384 bytes

Notes and kind are stored in the desktop library.

Nothing can be edited; the panel says where notes live instead.

Feedback and recovery

Messages the library gives back after things happen: a banner when an interrupted recording is found, and the toast that confirms saves, imports and errors.

↺
Recovery banner
Offers to turn leftover audio from an interrupted recording (a crash or power loss) back into a recording.
apps/desktop/src/App.tsx · Workspace() .recovery-banner
One interrupted recording quirk
1 interrupted recording(s) found.
The text is a literal (s): it reads 1 interrupted recording(s) found.
Several
3 interrupted recording(s) found.
Appears under the search controls and above the list header, and only when the desktop reports a recovery count above zero; it is never shown in a browser preview.
◔
Toast notification
Briefly confirms what just happened (saved, imported, recovered) or says what went wrong, then fades away on its own.
apps/desktop/src/App.tsx · Workspace() .toast
Saved
Saved to C:\Users\Demo\Music\Cassette\Recordings\Weekly planning sync.wav
Position is fixed at the bottom centre of the window in the app; it is made static here. It dismisses itself after 6.5 seconds or on the x.
Imported, several
2 recordings imported. Your source files are preserved.
Imported, one
1 recording imported. Your source files are preserved.
Import handles the singular correctly.
Recovery found nothing
No playable audio was found. Recovery files were preserved.
Recovered
2 recordings recovered.
Error
Import failed: the selected file could not be read as audio.
Errors use the same green toast; there is no separate error style. The wording shown is an example of the raw error text.
Long message wraps
Saved to C:\Users\Demo\Music\Cassette\Recordings\Quarterly planning workshop with the full product and design groups, afternoon session, recorded in the large meeting room.wav
The toast is capped at 680px wide and wraps.