# Unraid Glass — visionOS Glassmorphism Theme ## Project Custom CSS + JS theme for Unraid 7.2.3 WebGUI. B&W mountain wallpaper with frosted glass cards, collapsible sidebar, dashboard individual glass cards. **Gitea:** https://git.xtrm-lab.org/jazzymc/unraid-glass **Local:** `~/xtrm/unraid-glass/` ## Files | File | Purpose | Deploy path (persistent) | Deploy path (live) | |------|---------|--------------------------|---------------------| | `style.css` | Main CSS theme | `/boot/config/plugins/custom.css/style.css` | `/usr/local/emhttp/plugins/custom.css/style.css` | | `sidebar.js` | Sidebar toggle + search overlay | `/boot/config/plugins/custom.css/assets/sidebar.js` | `/usr/local/emhttp/plugins/custom.css/assets/sidebar.js` | | `update-icons.sh` | Replace Docker/VM icons with selfh.st CDN icons | `/boot/config/plugins/custom.css/assets/update-icons.sh` | `/usr/local/emhttp/plugins/custom.css/assets/update-icons.sh` | | `vm-icons.conf` | VM name → icon name mapping | `/boot/config/plugins/custom.css/assets/vm-icons.conf` | — | ## Deployment Both files must be deployed to TWO paths — persistent (survives reboot) and live (active now): ```bash scp -i ~/.ssh/id_ed25519_unraid -P 422 style.css root@192.168.10.20:/boot/config/plugins/custom.css/style.css scp -i ~/.ssh/id_ed25519_unraid -P 422 style.css root@192.168.10.20:/usr/local/emhttp/plugins/custom.css/style.css scp -i ~/.ssh/id_ed25519_unraid -P 422 sidebar.js root@192.168.10.20:/boot/config/plugins/custom.css/assets/sidebar.js scp -i ~/.ssh/id_ed25519_unraid -P 422 sidebar.js root@192.168.10.20:/usr/local/emhttp/plugins/custom.css/assets/sidebar.js scp -i ~/.ssh/id_ed25519_unraid -P 422 update-icons.sh root@192.168.10.20:/boot/config/plugins/custom.css/assets/update-icons.sh scp -i ~/.ssh/id_ed25519_unraid -P 422 update-icons.sh root@192.168.10.20:/usr/local/emhttp/plugins/custom.css/assets/update-icons.sh scp -i ~/.ssh/id_ed25519_unraid -P 422 vm-icons.conf root@192.168.10.20:/boot/config/plugins/custom.css/assets/vm-icons.conf ``` JS injection is handled by `CustomJS_Loader.page` on the server (persisted via `/boot/config/go`). ## Unraid Sidebar DOM Structure ``` #menu (position: fixed — Unraid's default, DO NOT override) ├── #sidebar-logo (injected by sidebar.js — absolute positioned) ├── #sidebar-toggle-btn (injected by sidebar.js — absolute positioned) └── #nav-block (position: absolute; top:0; bottom:12px; width:100% — Unraid's default) ├── .nav-tile (main nav items — block flow) │ └── .nav-item > a (display: inline-flex — Unraid's default) │ ├── ::before (icon via font-family: docker-icon, fontawesome, unraid) │ ├── bare text node (page name, not wrapped in span) │ ├── (only on utility items, display: none in our CSS) │ └── (only on utility items, display: none in collapsed) └── .nav-tile.right (utility nav items) └── .nav-item.CLASSNAME.util > a ├── ::before (icon code from page Code= property) ├── (icon from page Icon= property) └── Label ``` ## Critical CSS Lessons ### DO NOT override `position` on `#menu` Unraid sets `position: fixed` on `#menu`. Overriding with `position: relative` causes the sidebar to collapse and disappear. ### DO NOT override `display` on `.nav-item a` Unraid sets `display: inline-flex` on `.Theme--sidebar .nav-item a`. Fighting this with `display: grid` or `display: block` doesn't reliably work. Instead, work WITH `inline-flex`: - Center inline elements via `text-align: center` on parent `.nav-item` - Center icon via `position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%)` on `::before` ### `backdrop-filter` creates a containing block `backdrop-filter` on `#menu` creates a new containing block for `position: fixed` descendants. This means `position: fixed` inside the sidebar is relative to `#menu`, NOT the viewport. The search popup must be moved to `document.body` via JS to escape this. ### Work WITH `#nav-block`, don't replace it Unraid's `#nav-block` has `position: absolute; top: 0; bottom: 12px; width: 100%; overflow-y: scroll`. Only override `top` (to clear logo+toggle space) and `padding-left`. Don't add flex/grid layout. ### Utility items have DOUBLE icons Utility `.nav-item` elements have BOTH a `::before` pseudo-element (from page `Code=` property) AND a `` HTML element (from page `Icon=` property). Hide `` with `.nav-item a > * { display: none }`. ### `font-size: 0` for hiding bare text nodes Main nav items have bare text nodes (not wrapped in ``). CSS `display: none` can't target text nodes. Use `font-size: 0` on the `a` element, then explicit `font-size` on `::before`. ### `gap` affects invisible flex items Even with `font-size: 0`, text nodes are still flex items. With `gap: 25px` (Unraid default), invisible text creates spacing. Override `gap: 0` in collapsed mode. ## Icon Fonts on Unraid | Font | Family name | Used by | |------|-------------|---------| | Unraid icons | `unraid` | `icon-u-*` classes, utility nav `::before` (thicker strokes) | | Font Awesome 4 | `FontAwesome` | `.fa` classes, single weight only | | Docker icons | `docker-icon` | Docker page nav icon | | Combined | `docker-icon, fontawesome, unraid` | Main nav `::before` (set by Unraid CSS) | Utility nav `::before` icons use the `unraid` font which has heavier strokes. We replace them with FontAwesome equivalents for consistent thin appearance. ## Utility Button Pages | Class name | Title | FA4 replacement | |------------|-------|-----------------| | `gui_search` | Search | `\f002` | | `LanguageButton` | Switch Language | `\f0ac` | | `LogoutButton` | Logout | `\f08b` | | `TerminalButton` | Terminal | `\f120` | | `BrowseButton` | File Manager | `\f115` | | `FeedbackButton` | Feedback | `\f075` | | `InfoButton` | Info | `\f05a` | | `LogButton` | Log | `\f0f6` | | `HelpButton` | Help | `\f059` | | `LockButton` | Lock/Unlock | `\f09c` (no page Code=, needs manual ::before) | ## Search Overlay The `dynamix.gui.search` plugin uses hover-trigger in sidebar theme. We replace it with: - Click-trigger on the search nav-item - `gui_search()` creates `#guiSearchBoxSpan` inside the sidebar - JS moves it to `document.body` (escapes backdrop-filter containing block) - Backdrop overlay with blur - Cmd+K / Ctrl+K keyboard shortcut - Escape to close ## Custom Docker/VM Icons Icons are sourced from [selfh.st/icons](https://selfh.st/icons/) via jsDelivr CDN. ### How it works `update-icons.sh` reads a `glass.icon` Docker label from each container, downloads the matching PNG from `https://cdn.jsdelivr.net/gh/selfhst/icons@main/png/{name}.png`, and replaces Unraid's cached icon files. This works on Docker page, VM page, and Dashboard — no client-side JS needed. ### Docker label convention Add label `glass.icon` to containers: - Short name: `glass.icon=plex` → fetches from selfh.st CDN - Full URL: `glass.icon=https://example.com/icon.png` → fetches from URL - No label: auto-detects from container name (lowercase + CDN HEAD check) ### VM icons Edit `vm-icons.conf` with `VM_NAME=icon_name` entries (one per line). ### Running ```bash # Dry run (show what would change) ssh -i ~/.ssh/id_ed25519_unraid root@192.168.10.20 -p 422 'bash /boot/config/plugins/custom.css/assets/update-icons.sh --dry-run' # Real run ssh -i ~/.ssh/id_ed25519_unraid root@192.168.10.20 -p 422 'bash /boot/config/plugins/custom.css/assets/update-icons.sh' # Force re-download all ssh -i ~/.ssh/id_ed25519_unraid root@192.168.10.20 -p 422 'bash /boot/config/plugins/custom.css/assets/update-icons.sh --force' ``` ### Icon paths on Unraid - RAM cache: `/usr/local/emhttp/state/plugins/dynamix.docker.manager/images/{Name}-icon.png` - Persistent: `/var/lib/docker/unraid/images/{Name}-icon.png` - VM templates: `/usr/local/emhttp/plugins/dynamix.vm.manager/templates/images/` ## Wallpaper Place wallpaper at `/boot/config/plugins/custom.css/assets/wallpaper.jpg` — accessible at `/custom/wallpaper.jpg`.