Repository navigation
How Rounded Panels Work
This chapter explains how the Rounded panels setting turns the workspace into separate rounded panels, in any color theme. The user side is in Rounded Panels.
With rounded panels, tool windows and the editor float as rounded "islets" on the window color. Users asked for this look. We first tied it to our Islet Light and Islet Dark themes, then made it a setting of its own, because the shape is a layout choice and people want it with their favorite colors too.
The whole feature is one boolean attribute on <html> and CSS rules that only match while it is there. No component renders anything different, so turning it on or off never remounts an editor or a terminal.
flowchart LR
S["settings.roundedPanels"] --> A["applyAppearance()"]
A --> H["html data-rounded-panels"]
H --> W["AppShell and SplitGrid look rounded: gaps, frame, rounded panels and groups"]
H --> R["ResizeHandle.svelte: handle fills the gap"]
H --> F["Header, StatusBar, activity bars: frame color"]
H --> T["TabStrip look rounded: pill tabs"]
H --> P["AppShell: the rounded bottom panel"]
roundedPanels is a boolean preference in settingsData.ts (default true, parsed with pickBoolean). Settings > Appearance has a switch for it. applyAppearance() in settings.svelte.ts runs on every preference change and calls root.toggleAttribute("data-rounded-panels", this.roundedPanels), next to data-ligatures.
Two size tokens set the look: appShell.panelGap (6px) and appShell.panelRadius (10px) in ui/design-tokens. Workspace.svelte passes look="rounded" to the library's AppShell and SplitGrid: the body, main column and editor area get gap: var(--panel-gap), the body gets side and bottom padding on the frame color, and the panels and editor groups get border-radius without divider borders. Editor groups and the terminal panel also get overflow: hidden so their contents are clipped to the corners.
The activity bars get a negative margin equal to the gap, so they stay flush with the window edge while the panels keep their gap.
A ResizeHandle is normally 5px wide with margin: 0 -2px, so it takes 1px of layout. With rounded panels it becomes exactly as wide as the gap and has a negative margin of one gap on each side. Together with the two flex gaps around it, the handle adds one gap of space and covers that gap exactly, so the space between panels is the drag area. Horizontal handles (the terminal panel) do the same with height.
flowchart LR
L["Sidebar"] --- G1["flex gap 6px"] --- H["handle 6px, margins -6px"] --- G2["flex gap 6px"] --- M["Editor"]
The window behind the panels uses the color token --frame. Every theme must set it, and it must stand apart from both --panel and --editor-bg, or the gaps would be invisible. The editor is a panel too: in rounded mode its tab strip takes the editor color.
- The built-in themes set it in
colors.json(colors.css):#ebecf0for Nibtree Light,#131416for Nibtree Dark. - Catalog themes get it from
frameColor()in the UI library'sthemes/derive.ts: the theme's--bgwhen its CIELAB distance from both the panel and the editor color is at least 5 (FRAME_DISTANCE), else the darker of the two darkened (dark themes) or the panel greyed toward the text (light themes), and as a last resort moved further toward the text. High contrast dark themes with a black panel and GitHub Dark, whose editor is almost black, end up there. -
legible()inderiveColorsnow also checks the frame, so dim text and status colors stay readable on the header and status bar.
With rounded panels on, EditorTabs.svelte gives the library's TabStrip the rounded look, which draws pill tabs: the strip takes the editor background, each tab is 26px tall with a 6px radius, and the separators and the accent line on top are gone. The active tab uses --selected with an outline mixed from --accent. In an unfocused split group it uses --selected-inactive and --border-strong.
| File | What |
|---|---|
src/lib/stores/settingsData.ts |
roundedPanels type, default and parsing |
src/lib/stores/settings.svelte.ts |
the store field and data-rounded-panels in applyAppearance()
|
src/lib/views/settings/AppearanceSettings.svelte |
the Appearance switch |
ui/design-tokens/components.json, colors.json
|
appShell.panelGap, appShell.panelRadius and the built-in --frame
|
ui/web/src/lib/themes/colorTokens.ts, derive.ts
|
--frame as a color token, frameColor()
|
src/lib/views/Workspace.svelte, AppShell and SplitGrid (UI library) |
gaps, padding, frame, rounded panels |
src/lib/ui/ResizeHandle.svelte |
handles that fill the gaps |
src/lib/views/Header.svelte, StatusBar.svelte, ActivityBar.svelte, RightActivityBar.svelte
|
frame color, no dividers (the library's AppHeader and StatusBar take look="rounded") |
ui/web/src/lib/components/EditorTab.svelte |
pill tabs (look rounded) |
AppShell (UI library) |
the rounded bottom panel |
SplitGrid (UI library) |
editor groups clip to the panel's corners |
An attribute, not a component prop. CSS on one root attribute keeps every component unaware of the setting and avoids remounting editors and terminals. It is the same pattern as data-ligatures and data-contrast.
Separate from the color theme. Shape and color are independent choices. The Islet themes only bring colors; the setting brings the shape for every theme.
A derived frame instead of --bg. Many themes paint --bg and --panel the same, which would hide the gaps. A tested token keeps the look working in all 41 themes.
The file toolbar is square at the top. With the File toolbar at the Bottom, the editor group's clipping rounds the bar's bottom corners. At the Top the bar sits right under the tabs, inside the panel, so it stays a square band joined to the tab strip. Rounding its top corners there was tried and made the bar look like a separate box.
On by default. New installs start with the rounded look, the one the app is designed around. Existing users keep their choice: settings.json saves every preference, so anyone who already has one keeps "roundedPanels": false and the classic look until they change it.
See Rounded Panels Bugs We Fixed.
-
settingsData.test.ts: the default,true, and a non-boolean value falling back to off. -
catalog.test.ts: for every theme,--frameis at least 5 CIELAB units from--paneland--editor-bg, and--textkeeps its contrast minimum on it;--frameis in all threecolors.cssblocks. - The look itself needs a visual check:
rounded-panelsandrounded-panels-islet-lightinscripts/screenshots.ts.
- A new top-level panel in the workspace needs its own rounded rule under
html[data-rounded-panels]and must sit in a flex container with the panel gap. - A new resize handle works as is if it is a
ResizeHandlebetween two flex children of such a container. Inside one panel, passinPanel. - New UI on the frame (header, status bar, activity bars) should use
--framein rounded mode, not--bg.
These pages are generated from docs/wiki. To correct something, open a pull request against the source file; edits made here are overwritten.
Using Nibtree
- Getting Started
- Welcome Screen
- Workspaces
- Files Panel
- File Operations
- File Icons
- Rounded Panels
- Editor and Tabs
- Pin Reorder and Wrap Tabs
- Single Tab Title
- Split Editor
- New File and Unsaved Changes
- Unload Hidden Tabs
- Editing Code
- Code Appearance
- Markdown Editor
- Image and PDF Preview
- Search Everywhere
- Recent Files
- Navigation Bar
- Find and Replace
- Changes and Commits
- Sign In Prompts
- Commit Box Layout
- Repository Actions
- Commit Options
- Ignoring Files
- Diffs
- Inline Diffs
- Staging View
- Revert a Change
- Resolving Conflicts
- Merge Tool
- Blame
- History and Log
- Merge Commits
- Branches and Tags
- Branches Popup
- Remotes
- Stashes
- Shelf
- Git Menu
- Git Dialogs
- Interactive Rebase
- Worktrees
- AI Agents
- AI Tasks
- AI Usage
- Keep Computer Awake
- Submodules
- Git LFS
- GitHub
- Git Console
- Terminal
- Terminal Features
- Scripts
- Navigation
- Menus
- Settings
- Settings Search
- Color Themes
- Settings Terminal and Automation
- Settings Files
- Updates
- Status Bar and Help
- Notifications
- Memory Use
- Clear Cache
- MCP and CLI
- Git Mergetool
- Keyboard Shortcuts
- Keyboard Shortcuts Editor
- Troubleshooting
- Troubleshooting Git
Developers
- Developer Guide
- Architecture
- Project Layout
- Backend
- How Folder Watching Works
- Folder Watching Bugs We Fixed
- How Workspace Files Work
- How the Preview Scheme Works
- Backend Services
- How Terminal Features Work
- Terminal Bugs We Fixed
- Frontend
- How the Rich Markdown Editor Works
- Rich Markdown Bugs We Fixed
- Git Menu Links
- Menu Keys and Routing
- Frontend Modules
- Blame Bugs We Fixed
- Project Color And Title Bar
- One Diff View
- Diff Bugs We Fixed
- Merge Tool Layouts
- Merge Tool Bugs We Fixed
- Color Theme Bugs We Fixed
- How the Connected Diff Works
- Rounded Panels Bugs We Fixed
- Update Bugs We Fixed
- Status Bar Bugs We Fixed
- MCP and CLI Bugs We Fixed
- Repository Actions Bugs We Fixed
- How the Changes Tab Works
- CodeMirror Patterns
- How the Cursor Works
- How Editor Features Work
- How the Path Bar Works
- Commands and Events
- Settings Reference
- Commands Workspace and Changes
- Commands Branches and Remotes
- Commands History and Extras
- Commands App and Tools
- Testing
- Test Suites
- Debugging
- Debugging with MCP
- Measuring Setting Memory
- How Terminal Memory Is Measured
- How Markdown Diagrams Work
- Releases and CI
- Publishing the Wiki
- Versioning and Changelog
- Browser Version Packages
- Browser Release Checks
- Docker Image
- Platforms and Signing
- Windows Support
- Windows Bugs We Fixed
- Windows MCP and CLI
- Docs and Screenshots
- UI Library
- UI Library MCP
- UI Library Bugs
- UI Library Migration
- Contributing
How features work
- Welcome screen
- Workspaces and folders
- Files panel
- File operations
- File icons
- Editor and tabs
- Pin, reorder and wrap tabs
- Single tab title
- Split editor
- New File and unsaved changes
- Unload hidden tabs
- Editing code
- Code appearance
- Markdown editor
- Image and PDF preview
- Search Everywhere
- Recent Files
- Navigation Bar
- Find and replace
- Changes and commits
- Sign-in prompts
- Commit box layout
- Repository actions
- Commit options
- Ignoring files
- Diffs
- Inline diffs
- Staging view
- Revert a change
- Resolving conflicts
- Merge tool
- Blame
- History and log
- Merge commits
- Commit tabs
- Branches and tags
- Branches popup
- Remotes
- Stashes
- Shelf
- Git menu
- Git dialogs
- Interactive rebase
- Worktrees
- AI agents
- AI usage
- Keep computer awake
- AI tasks
- Submodules
- Git LFS
- GitHub account
- Git Console
- Back and Forward
- Integrated terminal
- Scripts tool window
- Menu bar
- Settings
- Search in Settings
- Color themes
- Rounded panels
- Updates and release channels
- Status bar and help links
- Notifications
- Memory readout and memory log
- Clear Cache
- MCP server and command line tool
- git mergetool mode