max / alloy
- Co-Authored-By
- Claude Opus 4.7 (1M context) <noreply@anthropic.com>
13 files changed,
+1021 insertions,
-1 deletion
| @@ -18,7 +18,8 @@ | |||
| 18 | 18 | - [ ] Multi-stage cargo-install build for Rust tools without published Fedora packages: `ironbar` (bar), `anyrun` (launcher), `wl-screenrec` (screen recorder), and **Gram** (graphical editor — Zed fork, larger build). New `FROM fedora:42 as rust-build` stage runs `cargo install`, then copies binaries to `/usr/local/bin` in the runtime stage. Gram may deserve its own stage due to build weight. | |
| 19 | 19 | - [ ] Address bootc lint's `/var` warnings — Flatpak install writes to `/var/lib/flatpak` at build time, but bootc prefers `/var` empty at build so systemd-tmpfiles populates at first boot. Options: (a) accept the warnings, (b) move Flatpak installs to a first-boot systemd oneshot instead of build-time, (c) `bootc container lint`'s official escape hatch if there is one. | |
| 20 | 20 | - [ ] Boot the image in a VM (`bootc-image-builder` → qcow2 or ISO) to verify it actually runs as an OS beyond just linting clean. | |
| 21 | - | - [ ] Package Alloy-authored config files that STACK.md references but the Containerfile doesn't yet ship: `niri.kdl` defaults, ironbar theme (blocked on ironbar landing), anyrun plugin config (blocked on anyrun), rio config (color palette + kitty-graphics identification), yazi previewer defaults, mako theme, satty defaults, swaylock config, starship prompt. | |
| 21 | + | - [x] Package Alloy-authored config files that STACK.md references but the Containerfile doesn't yet ship. Shipped 2026-07-05 under `etc/skel/.config/`: `niri/config.kdl`, `ironbar/{config.toml,style.css}`, `anyrun/{config.ron,style.css}`, `rio/config.toml`, `yazi/{yazi.toml,theme.toml}`, `mako/config`, `satty/config.toml`, `swaylock/config`, `starship.toml`. All applied Alloy light-mode palette per docs/TOKENS.md and IosevkaTerm Nerd Font per docs/STACK.md#fonts. Live-system verification pending — see the follow-up item below. | |
| 22 | + | - [ ] Live-system verification of the packaged configs. Test on Framework 13 (or QEMU with hardware passthrough where feasible): rio → yazi kitty-graphics preview, Niri Fn-key binds → swayosd overlays, Print → screenshot to `~/Pictures/Screenshots/`, Mod+Print → satty on latest, Mod+Ctrl+L → swaylock with palette, ironbar workspaces reflecting Niri IPC, anyrun launcher, mako urgency colors, starship prompt on nu login. Any config that breaks on real hardware gets fixed and re-shipped as a follow-up. | |
| 22 | 23 | ||
| 23 | 24 | ## When distribution starts | |
| 24 | 25 |
| @@ -1,0 +1,27 @@ | |||
| 1 | + | // Alloy anyrun configuration | |
| 2 | + | // | |
| 3 | + | // Launcher per docs/STACK.md#launcher. Curated plugin set — no fuzzy | |
| 4 | + | // smorgasbord. Style in style.css. | |
| 5 | + | // | |
| 6 | + | // Plugins are shipped by ublue-os/staging COPR alongside anyrun | |
| 7 | + | // itself; paths follow anyrun's convention of `/usr/lib/anyrun/`. | |
| 8 | + | Config( | |
| 9 | + | x: Fraction(0.5), | |
| 10 | + | y: Fraction(0.3), | |
| 11 | + | width: Absolute(600), | |
| 12 | + | height: Absolute(0), | |
| 13 | + | hide_icons: false, | |
| 14 | + | ignore_exclusive_zones: false, | |
| 15 | + | layer: Overlay, | |
| 16 | + | hide_plugin_info: false, | |
| 17 | + | close_on_click: true, | |
| 18 | + | show_results_immediately: false, | |
| 19 | + | max_entries: Some(6), | |
| 20 | + | ||
| 21 | + | plugins: [ | |
| 22 | + | "libapplications.so", | |
| 23 | + | "libsymbols.so", | |
| 24 | + | "libshell.so", | |
| 25 | + | "libtranslate.so", | |
| 26 | + | ], | |
| 27 | + | ) |
| @@ -1,0 +1,69 @@ | |||
| 1 | + | /* | |
| 2 | + | * Alloy anyrun style | |
| 3 | + | * | |
| 4 | + | * Alloy light-mode palette per docs/TOKENS.md. anyrun renders GTK4; | |
| 5 | + | * selectors follow GTK4 conventions. | |
| 6 | + | */ | |
| 7 | + | ||
| 8 | + | * { | |
| 9 | + | font-family: "IosevkaTerm Nerd Font", monospace; | |
| 10 | + | font-size: 13px; | |
| 11 | + | color: #302c22; /* text-primary */ | |
| 12 | + | } | |
| 13 | + | ||
| 14 | + | #window { | |
| 15 | + | background: transparent; | |
| 16 | + | } | |
| 17 | + | ||
| 18 | + | #main { | |
| 19 | + | background-color: #fefcf7; /* surface-overlay */ | |
| 20 | + | border: 1px solid #c9c3b5; /* border */ | |
| 21 | + | border-radius: 6px; | |
| 22 | + | padding: 8px; | |
| 23 | + | } | |
| 24 | + | ||
| 25 | + | #entry { | |
| 26 | + | background-color: #f5f2ea; /* surface */ | |
| 27 | + | color: #302c22; | |
| 28 | + | border: 1px solid #e0dbcf; /* border-subtle */ | |
| 29 | + | border-radius: 4px; | |
| 30 | + | padding: 6px 10px; | |
| 31 | + | min-height: 24px; | |
| 32 | + | } | |
| 33 | + | ||
| 34 | + | #entry:focus { | |
| 35 | + | border: 2px solid #a09982; /* border-strong */ | |
| 36 | + | padding: 5px 9px; /* compensate for 2px border */ | |
| 37 | + | } | |
| 38 | + | ||
| 39 | + | .plugin { | |
| 40 | + | background-color: transparent; | |
| 41 | + | padding: 4px 6px; | |
| 42 | + | border-radius: 4px; | |
| 43 | + | } | |
| 44 | + | ||
| 45 | + | .match { | |
| 46 | + | background-color: transparent; | |
| 47 | + | padding: 6px 8px; | |
| 48 | + | border-radius: 4px; | |
| 49 | + | } | |
| 50 | + | ||
| 51 | + | .match:selected { | |
| 52 | + | background-color: #e0dbcf; /* border-subtle */ | |
| 53 | + | color: #302c22; | |
| 54 | + | } | |
| 55 | + | ||
| 56 | + | .match-title { | |
| 57 | + | color: #302c22; | |
| 58 | + | font-weight: bold; | |
| 59 | + | } | |
| 60 | + | ||
| 61 | + | .match-desc { | |
| 62 | + | color: #5f5a4e; /* text-secondary */ | |
| 63 | + | font-size: 11px; | |
| 64 | + | } | |
| 65 | + | ||
| 66 | + | .plugin-info { | |
| 67 | + | color: #8b8477; /* text-muted */ | |
| 68 | + | font-size: 11px; | |
| 69 | + | } |
| @@ -1,0 +1,59 @@ | |||
| 1 | + | # Alloy Ironbar configuration | |
| 2 | + | # | |
| 3 | + | # Bar layout for the v0 stack per docs/STACK.md#bar. Ironbar is the | |
| 4 | + | # adopted bar; the eventual bespoke egui bar is a v1+ marquee app. | |
| 5 | + | # Do not let this config grow past what a migration to egui could | |
| 6 | + | # reproduce in a weekend. | |
| 7 | + | # | |
| 8 | + | # Layout: workspaces on the left, clock in the center, tray + status | |
| 9 | + | # indicators on the right. Palette + font in style.css. | |
| 10 | + | ||
| 11 | + | position = "top" | |
| 12 | + | height = 28 | |
| 13 | + | start_hidden = false | |
| 14 | + | name = "alloy-bar" | |
| 15 | + | ||
| 16 | + | # ------------------------------------------------------------------- | |
| 17 | + | # Left: workspaces (via niri IPC) | |
| 18 | + | # ------------------------------------------------------------------- | |
| 19 | + | [[start]] | |
| 20 | + | type = "workspaces" | |
| 21 | + | name = "workspaces" | |
| 22 | + | all_monitors = false | |
| 23 | + | ||
| 24 | + | # ------------------------------------------------------------------- | |
| 25 | + | # Center: clock — Iosevka, 24h, ISO date | |
| 26 | + | # ------------------------------------------------------------------- | |
| 27 | + | [[center]] | |
| 28 | + | type = "clock" | |
| 29 | + | name = "clock" | |
| 30 | + | format = "%a %Y-%m-%d %H:%M" | |
| 31 | + | format_popup = "%A, %B %-d %Y | %H:%M:%S" | |
| 32 | + | ||
| 33 | + | # ------------------------------------------------------------------- | |
| 34 | + | # Right: tray, volume, battery, network | |
| 35 | + | # ------------------------------------------------------------------- | |
| 36 | + | [[end]] | |
| 37 | + | type = "tray" | |
| 38 | + | name = "tray" | |
| 39 | + | direction = "right_to_left" | |
| 40 | + | icon_size = 16 | |
| 41 | + | ||
| 42 | + | [[end]] | |
| 43 | + | type = "volume" | |
| 44 | + | name = "volume" | |
| 45 | + | format = "vol {volume_percent}%" | |
| 46 | + | max_volume = 100 | |
| 47 | + | step = 5 | |
| 48 | + | ||
| 49 | + | [[end]] | |
| 50 | + | type = "upower" | |
| 51 | + | name = "battery" | |
| 52 | + | format = "{percentage}% {state}" | |
| 53 | + | ||
| 54 | + | [[end]] | |
| 55 | + | type = "custom" | |
| 56 | + | name = "net" | |
| 57 | + | bar = [ | |
| 58 | + | { type = "label", name = "net-label", label = "{{30000:nmcli -t -f NAME,TYPE connection show --active | awk -F: '$2==\"wifi\" || $2==\"ethernet\"{print $1; exit}'}}" } | |
| 59 | + | ] |
| @@ -1,0 +1,94 @@ | |||
| 1 | + | /* | |
| 2 | + | * Alloy Ironbar style | |
| 3 | + | * | |
| 4 | + | * Alloy light-mode palette per docs/TOKENS.md. IosevkaTerm Nerd Font | |
| 5 | + | * so glyphs align with the bar's 28px cell height. Ironbar is GTK4 | |
| 6 | + | * under the hood, so CSS selectors follow GTK4 conventions. | |
| 7 | + | */ | |
| 8 | + | ||
| 9 | + | * { | |
| 10 | + | font-family: "IosevkaTerm Nerd Font", monospace; | |
| 11 | + | font-size: 12px; | |
| 12 | + | color: #302c22; /* text-primary */ | |
| 13 | + | } | |
| 14 | + | ||
| 15 | + | .bar { | |
| 16 | + | background-color: #faf7ef; /* surface-raised */ | |
| 17 | + | border-bottom: 1px solid #e0dbcf; /* border-subtle */ | |
| 18 | + | padding: 0 8px; | |
| 19 | + | } | |
| 20 | + | ||
| 21 | + | .container { | |
| 22 | + | padding: 0 4px; | |
| 23 | + | } | |
| 24 | + | ||
| 25 | + | /* ------------------------------------------------------------- | |
| 26 | + | * Workspaces | |
| 27 | + | * ------------------------------------------------------------- */ | |
| 28 | + | .workspaces .item { | |
| 29 | + | padding: 2px 8px; | |
| 30 | + | margin: 4px 2px; | |
| 31 | + | border-radius: 4px; | |
| 32 | + | background-color: transparent; | |
| 33 | + | color: #8b8477; /* text-muted */ | |
| 34 | + | border: 1px solid transparent; | |
| 35 | + | } | |
| 36 | + | ||
| 37 | + | .workspaces .item.focused { | |
| 38 | + | background-color: #f5f2ea; /* surface */ | |
| 39 | + | color: #302c22; /* text-primary */ | |
| 40 | + | border: 1px solid #c9c3b5; /* border */ | |
| 41 | + | } | |
| 42 | + | ||
| 43 | + | .workspaces .item.urgent { | |
| 44 | + | color: #c25d4f; /* accent-error */ | |
| 45 | + | } | |
| 46 | + | ||
| 47 | + | .workspaces .item:hover { | |
| 48 | + | background-color: #fefcf7; /* surface-overlay */ | |
| 49 | + | } | |
| 50 | + | ||
| 51 | + | /* ------------------------------------------------------------- | |
| 52 | + | * Clock | |
| 53 | + | * ------------------------------------------------------------- */ | |
| 54 | + | .clock { | |
| 55 | + | padding: 0 12px; | |
| 56 | + | color: #302c22; | |
| 57 | + | } | |
| 58 | + | ||
| 59 | + | .clock button { | |
| 60 | + | background-color: transparent; | |
| 61 | + | border: none; | |
| 62 | + | color: #302c22; | |
| 63 | + | } | |
| 64 | + | ||
| 65 | + | .clock .popup { | |
| 66 | + | background-color: #fefcf7; /* surface-overlay */ | |
| 67 | + | color: #302c22; | |
| 68 | + | border: 1px solid #c9c3b5; | |
| 69 | + | border-radius: 6px; | |
| 70 | + | padding: 8px 12px; | |
| 71 | + | } | |
| 72 | + | ||
| 73 | + | /* ------------------------------------------------------------- | |
| 74 | + | * Tray | |
| 75 | + | * ------------------------------------------------------------- */ | |
| 76 | + | .tray .item { | |
| 77 | + | padding: 0 4px; | |
| 78 | + | } | |
| 79 | + | ||
| 80 | + | /* ------------------------------------------------------------- | |
| 81 | + | * Volume, battery, custom (net) | |
| 82 | + | * ------------------------------------------------------------- */ | |
| 83 | + | .volume, .upower, .custom { | |
| 84 | + | padding: 0 8px; | |
| 85 | + | color: #5f5a4e; /* text-secondary */ | |
| 86 | + | } | |
| 87 | + | ||
| 88 | + | .upower.low { | |
| 89 | + | color: #d1a234; /* accent-warn */ | |
| 90 | + | } | |
| 91 | + | ||
| 92 | + | .upower.critical { | |
| 93 | + | color: #c25d4f; /* accent-error */ | |
| 94 | + | } |
| @@ -1,0 +1,50 @@ | |||
| 1 | + | # Alloy mako configuration | |
| 2 | + | # | |
| 3 | + | # Notification daemon per docs/STACK.md#notification-daemon. Alloy | |
| 4 | + | # light-mode palette per docs/TOKENS.md; urgency shows as border color | |
| 5 | + | # (low = border-subtle, normal = border, critical = accent-error). | |
| 6 | + | # IosevkaTerm Nerd Font so glyphs align with body text. | |
| 7 | + | # | |
| 8 | + | # The v2 bespoke egui daemon should reproduce these defaults verbatim | |
| 9 | + | # so existing users don't feel the switch. | |
| 10 | + | ||
| 11 | + | font=IosevkaTerm Nerd Font 11 | |
| 12 | + | ||
| 13 | + | background-color=#faf7ef | |
| 14 | + | text-color=#302c22 | |
| 15 | + | border-color=#c9c3b5 | |
| 16 | + | border-size=1 | |
| 17 | + | border-radius=4 | |
| 18 | + | ||
| 19 | + | padding=10,14 | |
| 20 | + | margin=8 | |
| 21 | + | ||
| 22 | + | default-timeout=5000 | |
| 23 | + | ignore-timeout=0 | |
| 24 | + | ||
| 25 | + | max-visible=5 | |
| 26 | + | sort=-time | |
| 27 | + | layer=overlay | |
| 28 | + | anchor=top-right | |
| 29 | + | output= | |
| 30 | + | ||
| 31 | + | icons=1 | |
| 32 | + | icon-path=/usr/share/icons/Adwaita/scalable:/usr/share/icons/hicolor | |
| 33 | + | ||
| 34 | + | format=<b>%s</b>\n%b | |
| 35 | + | markup=1 | |
| 36 | + | actions=1 | |
| 37 | + | ||
| 38 | + | # ------------------------------------------------------------------- | |
| 39 | + | # Per-urgency overrides — border color signals severity | |
| 40 | + | # ------------------------------------------------------------------- | |
| 41 | + | [urgency=low] | |
| 42 | + | border-color=#e0dbcf | |
| 43 | + | default-timeout=3000 | |
| 44 | + | ||
| 45 | + | [urgency=normal] | |
| 46 | + | border-color=#c9c3b5 | |
| 47 | + | ||
| 48 | + | [urgency=critical] | |
| 49 | + | border-color=#c25d4f | |
| 50 | + | default-timeout=0 |
| @@ -1,0 +1,202 @@ | |||
| 1 | + | // Alloy Niri configuration | |
| 2 | + | // | |
| 3 | + | // Compositor + Wayland session. Alloy's opinionated defaults per | |
| 4 | + | // docs/STACK.md#compositor. Palette on chrome per docs/TOKENS.md. | |
| 5 | + | // | |
| 6 | + | // Verify on a real Alloy install: swayosd-client bindings on Fn keys, | |
| 7 | + | // yazi previews rendering via kitty graphics in rio, and the `notes` | |
| 8 | + | // workspace reachable when the FW12 fold sensor fires (see | |
| 9 | + | // docs/HARDWARE-FW12.md; the sensor half ships with alloy-hinged in v1). | |
| 10 | + | ||
| 11 | + | input { | |
| 12 | + | keyboard { | |
| 13 | + | xkb { | |
| 14 | + | layout "us" | |
| 15 | + | } | |
| 16 | + | repeat-delay 400 | |
| 17 | + | repeat-rate 30 | |
| 18 | + | } | |
| 19 | + | ||
| 20 | + | touchpad { | |
| 21 | + | tap | |
| 22 | + | natural-scroll | |
| 23 | + | accel-speed 0.2 | |
| 24 | + | } | |
| 25 | + | ||
| 26 | + | mouse { | |
| 27 | + | accel-profile "flat" | |
| 28 | + | } | |
| 29 | + | ||
| 30 | + | // Warp mouse to focused window on focus change. Reduces the "where | |
| 31 | + | // is my cursor" moment that tiling compositors surface. | |
| 32 | + | warp-mouse-to-focus | |
| 33 | + | } | |
| 34 | + | ||
| 35 | + | // Displays are configured per-machine in a drop-in override; ship a | |
| 36 | + | // placeholder here so `niri validate` passes on a fresh install. | |
| 37 | + | // output "eDP-1" { | |
| 38 | + | // mode "1920x1200@60" | |
| 39 | + | // scale 1.0 | |
| 40 | + | // } | |
| 41 | + | ||
| 42 | + | layout { | |
| 43 | + | gaps 8 | |
| 44 | + | center-focused-column "never" | |
| 45 | + | ||
| 46 | + | preset-column-widths { | |
| 47 | + | proportion 0.333 | |
| 48 | + | proportion 0.5 | |
| 49 | + | proportion 0.667 | |
| 50 | + | } | |
| 51 | + | ||
| 52 | + | default-column-width { proportion 0.5; } | |
| 53 | + | ||
| 54 | + | focus-ring { | |
| 55 | + | width 2 | |
| 56 | + | active-color "#a09982" // border-strong | |
| 57 | + | inactive-color "#e0dbcf" // border-subtle | |
| 58 | + | } | |
| 59 | + | ||
| 60 | + | border { | |
| 61 | + | off | |
| 62 | + | } | |
| 63 | + | ||
| 64 | + | struts { | |
| 65 | + | left 0 | |
| 66 | + | right 0 | |
| 67 | + | top 0 | |
| 68 | + | bottom 0 | |
| 69 | + | } | |
| 70 | + | } | |
| 71 | + | ||
| 72 | + | // Named workspace reserved for the FW12 fold-to-notes flow. See | |
| 73 | + | // docs/HARDWARE-FW12.md — alloy-hinged will `focus-workspace notes` | |
| 74 | + | // on tablet-mode transitions. | |
| 75 | + | workspace "notes" | |
| 76 | + | workspace "main" | |
| 77 | + | workspace "media" | |
| 78 | + | ||
| 79 | + | // GTK/adwaita client-side decorations off. Niri handles chrome; apps | |
| 80 | + | // that respect this render frameless. | |
| 81 | + | prefer-no-csd | |
| 82 | + | ||
| 83 | + | // Screenshots land under ~/Pictures/Screenshots. Niri's built-in | |
| 84 | + | // capture is the primary path (STACK.md#screenshot-stack); satty | |
| 85 | + | // handles annotation for the ones that need it. | |
| 86 | + | screenshot-path "~/Pictures/Screenshots/screenshot-%Y%m%d-%H%M%S.png" | |
| 87 | + | ||
| 88 | + | // ------------------------------------------------------------------- | |
| 89 | + | // Startup — long-running helpers Niri spawns once at session boot | |
| 90 | + | // ------------------------------------------------------------------- | |
| 91 | + | ||
| 92 | + | // Clipboard history: two watchers per STACK.md#clipboard-history. | |
| 93 | + | spawn-sh-at-startup "wl-paste --type text --watch cliphist store" | |
| 94 | + | spawn-sh-at-startup "wl-paste --type image --watch cliphist store" | |
| 95 | + | ||
| 96 | + | // swayosd-server backs the volume/brightness/lock indicator overlays. | |
| 97 | + | // The client (`swayosd-client`) is invoked from Fn-key binds below. | |
| 98 | + | spawn-at-startup "swayosd-server" | |
| 99 | + | ||
| 100 | + | // Bar. Ironbar reads etc/skel/.config/ironbar/config.corn on first | |
| 101 | + | // boot; spawned here so it comes up with the session. | |
| 102 | + | spawn-at-startup "ironbar" | |
| 103 | + | ||
| 104 | + | // Cursor theme + size for XWayland clients that read Xcursor state | |
| 105 | + | // via the root window. Non-XWayland apps read env vars from nushell. | |
| 106 | + | environment { | |
| 107 | + | XCURSOR_THEME "Bibata-Modern-Classic" | |
| 108 | + | XCURSOR_SIZE "24" | |
| 109 | + | // Force GTK apps to prefer wayland backend where available. | |
| 110 | + | GDK_BACKEND "wayland,x11" | |
| 111 | + | QT_QPA_PLATFORM "wayland;xcb" | |
| 112 | + | MOZ_ENABLE_WAYLAND "1" | |
| 113 | + | } | |
| 114 | + | ||
| 115 | + | // ------------------------------------------------------------------- | |
| 116 | + | // Window rules | |
| 117 | + | // ------------------------------------------------------------------- | |
| 118 | + | ||
| 119 | + | // Anyrun and satty float; everything else tiles. | |
| 120 | + | window-rule { | |
| 121 | + | match app-id="anyrun" | |
| 122 | + | open-floating true | |
| 123 | + | } | |
| 124 | + | ||
| 125 | + | window-rule { | |
| 126 | + | match app-id="satty" | |
| 127 | + | open-floating true | |
| 128 | + | } | |
| 129 | + | ||
| 130 | + | // ------------------------------------------------------------------- | |
| 131 | + | // Binds | |
| 132 | + | // ------------------------------------------------------------------- | |
| 133 | + | ||
| 134 | + | binds { | |
| 135 | + | // Session | |
| 136 | + | Mod+Shift+Slash { show-hotkey-overlay; } | |
| 137 | + | Mod+Return { spawn "rio"; } | |
| 138 | + | Mod+D { spawn "anyrun"; } | |
| 139 | + | Mod+Ctrl+L { spawn "swaylock"; } | |
| 140 | + | Mod+Shift+E { quit; } | |
| 141 | + | ||
| 142 | + | // Window ops | |
| 143 | + | Mod+Q { close-window; } | |
| 144 | + | Mod+F { maximize-column; } | |
| 145 | + | Mod+Shift+F { fullscreen-window; } | |
| 146 | + | ||
| 147 | + | // Focus (column-first, then row within column) | |
| 148 | + | Mod+H { focus-column-left; } | |
| 149 | + | Mod+L { focus-column-right; } | |
| 150 | + | Mod+J { focus-window-down; } | |
| 151 | + | Mod+K { focus-window-up; } | |
| 152 | + | ||
| 153 | + | // Move windows | |
| 154 | + | Mod+Shift+H { move-column-left; } | |
| 155 | + | Mod+Shift+L { move-column-right; } | |
| 156 | + | Mod+Shift+J { move-window-down; } | |
| 157 | + | Mod+Shift+K { move-window-up; } | |
| 158 | + | ||
| 159 | + | // Column sizing presets | |
| 160 | + | Mod+R { switch-preset-column-width; } | |
| 161 | + | Mod+Minus { set-column-width "-10%"; } | |
| 162 | + | Mod+Equal { set-column-width "+10%"; } | |
| 163 | + | ||
| 164 | + | // Workspaces | |
| 165 | + | Mod+1 { focus-workspace 1; } | |
| 166 | + | Mod+2 { focus-workspace 2; } | |
| 167 | + | Mod+3 { focus-workspace 3; } | |
| 168 | + | Mod+4 { focus-workspace 4; } | |
| 169 | + | Mod+N { focus-workspace "notes"; } | |
| 170 | + | Mod+M { focus-workspace "main"; } | |
| 171 | + | Mod+Shift+1 { move-column-to-workspace 1; } | |
| 172 | + | Mod+Shift+2 { move-column-to-workspace 2; } | |
| 173 | + | Mod+Shift+3 { move-column-to-workspace 3; } | |
| 174 | + | Mod+Shift+4 { move-column-to-workspace 4; } | |
| 175 | + | ||
| 176 | + | // Screenshot — Niri built-in per STACK.md | |
| 177 | + | Print { screenshot; } | |
| 178 | + | Ctrl+Print { screenshot-window; } | |
| 179 | + | Shift+Print { screenshot-screen; } | |
| 180 | + | // Annotate the last screenshot with satty | |
| 181 | + | Mod+Print { spawn "sh" "-c" "satty --filename \"$(ls -t ~/Pictures/Screenshots/*.png | head -1)\""; } | |
| 182 | + | ||
| 183 | + | // Volume — swayosd routes through pulse/wireplumber | |
| 184 | + | XF86AudioRaiseVolume { spawn "swayosd-client" "--output-volume" "raise"; } | |
| 185 | + | XF86AudioLowerVolume { spawn "swayosd-client" "--output-volume" "lower"; } | |
| 186 | + | XF86AudioMute { spawn "swayosd-client" "--output-volume" "mute-toggle"; } | |
| 187 | + | XF86AudioMicMute { spawn "swayosd-client" "--input-volume" "mute-toggle"; } | |
| 188 | + | ||
| 189 | + | // Brightness | |
| 190 | + | XF86MonBrightnessUp { spawn "swayosd-client" "--brightness" "raise"; } | |
| 191 | + | XF86MonBrightnessDown { spawn "swayosd-client" "--brightness" "lower"; } | |
| 192 | + | ||
| 193 | + | // Media keys — playerctl MPRIS | |
| 194 | + | XF86AudioPlay { spawn "playerctl" "play-pause"; } | |
| 195 | + | XF86AudioPause { spawn "playerctl" "play-pause"; } | |
| 196 | + | XF86AudioNext { spawn "playerctl" "next"; } | |
| 197 | + | XF86AudioPrev { spawn "playerctl" "previous"; } | |
| 198 | + | ||
| 199 | + | // Caps-lock indicator (only fires if swayosd-libinput-backend is | |
| 200 | + | // running; wire that when live-system-verifying) | |
| 201 | + | Caps_Lock { spawn "swayosd-client" "--caps-lock"; } | |
| 202 | + | } |
| @@ -1,0 +1,103 @@ | |||
| 1 | + | # Alloy Rio configuration | |
| 2 | + | # | |
| 3 | + | # Terminal per docs/STACK.md#terminal. Kitty graphics protocol so yazi | |
| 4 | + | # previews render inline (image_filter=triangle in yazi.toml). No | |
| 5 | + | # multiplexing — Niri owns tiling. | |
| 6 | + | # | |
| 7 | + | # Rio sets TERM=xterm-256color and TERM_PROGRAM=rio itself; yazi picks | |
| 8 | + | # kitty graphics from that pair with no explicit backend key needed. | |
| 9 | + | ||
| 10 | + | [navigation] | |
| 11 | + | mode = "Plain" # no tabs/splits — Niri handles it | |
| 12 | + | ||
| 13 | + | [window] | |
| 14 | + | background-opacity = 1.0 | |
| 15 | + | decorations = "Disabled" # niri owns the frame; prefer-no-csd | |
| 16 | + | ||
| 17 | + | [renderer] | |
| 18 | + | performance = "High" | |
| 19 | + | backend = "Automatic" # wgpu picks vulkan/gl/mtl per platform | |
| 20 | + | disable-unfocused-render = false | |
| 21 | + | ||
| 22 | + | # ------------------------------------------------------------------- | |
| 23 | + | # Fonts — IosevkaTerm Nerd Font, no ligatures (STACK.md#fonts). | |
| 24 | + | # Size 12 for 1080p; users bump to 13-14 on HiDPI or bigger panels. | |
| 25 | + | # ------------------------------------------------------------------- | |
| 26 | + | [fonts] | |
| 27 | + | size = 12 | |
| 28 | + | family = "IosevkaTerm Nerd Font" | |
| 29 | + | ||
| 30 | + | [fonts.regular] | |
| 31 | + | family = "IosevkaTerm Nerd Font" | |
| 32 | + | style = "Normal" | |
| 33 | + | weight = 400 | |
| 34 | + | ||
| 35 | + | [fonts.bold] | |
| 36 | + | family = "IosevkaTerm Nerd Font" | |
| 37 | + | style = "Normal" | |
| 38 | + | weight = 600 | |
| 39 | + | ||
| 40 | + | [fonts.italic] | |
| 41 | + | family = "IosevkaTerm Nerd Font" | |
| 42 | + | style = "Italic" | |
| 43 | + | weight = 400 | |
| 44 | + | ||
| 45 | + | [fonts.bold-italic] | |
| 46 | + | family = "IosevkaTerm Nerd Font" | |
| 47 | + | style = "Italic" | |
| 48 | + | weight = 600 | |
| 49 | + | ||
| 50 | + | # ------------------------------------------------------------------- | |
| 51 | + | # Cursor | |
| 52 | + | # ------------------------------------------------------------------- | |
| 53 | + | [cursor] | |
| 54 | + | shape = "block" | |
| 55 | + | blinking = false | |
| 56 | + | ||
| 57 | + | # ------------------------------------------------------------------- | |
| 58 | + | # Colors — Alloy Flatwhite (light-mode, docs/TOKENS.md). | |
| 59 | + | # ANSI slots picked so terminal apps that use ANSI colors for | |
| 60 | + | # information (git, ls --color, less, helix's terminal fallback) land | |
| 61 | + | # on the Alloy accents, not raw ANSI red/green/blue. | |
| 62 | + | # ------------------------------------------------------------------- | |
| 63 | + | [colors] | |
| 64 | + | background = "#f5f2ea" # surface | |
| 65 | + | foreground = "#302c22" # text-primary | |
| 66 | + | cursor = "#302c22" # text-primary | |
| 67 | + | selection-background = "#e0dbcf" # border-subtle | |
| 68 | + | selection-foreground = "#302c22" | |
| 69 | + | ||
| 70 | + | # Normal ANSI (0-7) | |
| 71 | + | black = "#302c22" # text-primary | |
| 72 | + | red = "#c25d4f" # accent-error | |
| 73 | + | green = "#5a8f52" # accent-ok (healthy) | |
| 74 | + | yellow = "#d1a234" # accent-warn | |
| 75 | + | blue = "#4a86c0" # accent-info (approx from oklch(60% 0.16 240)) | |
| 76 | + | magenta = "#9a6bb0" # accent-syntax (approx from oklch(55% 0.18 310)) | |
| 77 | + | cyan = "#5f5a4e" # text-secondary (Alloy has no cyan accent; use secondary text) | |
| 78 | + | white = "#faf7ef" # surface-raised | |
| 79 | + | ||
| 80 | + | # Bright ANSI (8-15) | |
| 81 | + | dim-black = "#5f5a4e" # text-secondary | |
| 82 | + | dim-red = "#c25d4f" | |
| 83 | + | dim-green = "#5a8f52" | |
| 84 | + | dim-yellow = "#d1a234" | |
| 85 | + | dim-blue = "#4a86c0" | |
| 86 | + | dim-magenta = "#9a6bb0" | |
| 87 | + | dim-cyan = "#8b8477" # text-muted | |
| 88 | + | dim-foreground = "#8b8477" | |
| 89 | + | ||
| 90 | + | light-black = "#8b8477" # text-muted | |
| 91 | + | light-red = "#c25d4f" | |
| 92 | + | light-green = "#5a8f52" | |
| 93 | + | light-yellow = "#d1a234" | |
| 94 | + | light-blue = "#4a86c0" | |
| 95 | + | light-magenta = "#9a6bb0" | |
| 96 | + | light-cyan = "#5f5a4e" | |
| 97 | + | light-foreground = "#302c22" | |
| 98 | + | ||
| 99 | + | # ------------------------------------------------------------------- | |
| 100 | + | # Bell + scrollback | |
| 101 | + | # ------------------------------------------------------------------- | |
| 102 | + | [bindings] | |
| 103 | + | keys = [] # inherit defaults; override on demand |
| @@ -1,0 +1,40 @@ | |||
| 1 | + | # Alloy satty configuration | |
| 2 | + | # | |
| 3 | + | # Screenshot annotator per docs/STACK.md#screenshot-stack. Niri's | |
| 4 | + | # built-in captures the frame; satty picks up when the user wants | |
| 5 | + | # to annotate before sharing. | |
| 6 | + | # | |
| 7 | + | # Bound in niri.kdl as Mod+Print — annotates the most recent | |
| 8 | + | # screenshot under ~/Pictures/Screenshots/. | |
| 9 | + | ||
| 10 | + | [general] | |
| 11 | + | # Fullscreen so the tool blocks the whole session; matches the | |
| 12 | + | # screenshot-first-then-annotate flow better than a windowed editor. | |
| 13 | + | fullscreen = true | |
| 14 | + | ||
| 15 | + | # Skip the "save as" dialog on Ctrl+S — dump to the standard path. | |
| 16 | + | early-exit = true | |
| 17 | + | ||
| 18 | + | # Save PNG next to the source under ~/Pictures/Screenshots. | |
| 19 | + | save-after-copy = false | |
| 20 | + | output-filename = "%Y%m%d-%H%M%S.png" | |
| 21 | + | ||
| 22 | + | # Initial pen color = accent-warn (Alloy amber). Matches the OSD | |
| 23 | + | # highlight so the user isn't surprised the pen isn't red. | |
| 24 | + | initial-tool = "pen" | |
| 25 | + | ||
| 26 | + | # ------------------------------------------------------------------- | |
| 27 | + | # Palette exposed in the color picker — Alloy accents + neutrals. | |
| 28 | + | # ------------------------------------------------------------------ | |
| 29 | + | [color-palette] | |
| 30 | + | palette = [ | |
| 31 | + | "#d1a234", # accent-warn | |
| 32 | + | "#c25d4f", # accent-error | |
| 33 | + | "#5a8f52", # accent-ok | |
| 34 | + | "#4a86c0", # accent-info | |
| 35 | + | "#302c22", # text-primary | |
| 36 | + | "#faf7ef", # surface-raised | |
| 37 | + | ] | |
| 38 | + | ||
| 39 | + | [font] | |
| 40 | + | family = "IosevkaTerm Nerd Font" |
| @@ -1,0 +1,128 @@ | |||
| 1 | + | # Alloy starship configuration | |
| 2 | + | # | |
| 3 | + | # Cross-shell prompt per docs/STACK.md#shell. Two-line prompt: line | |
| 4 | + | # one for context (cwd + git + language versions), line two for the | |
| 5 | + | # entry glyph. Color reserved for state (git dirty, non-zero exit, | |
| 6 | + | # insert/normal mode) per DESIGN-LANGUAGE.md. | |
| 7 | + | # | |
| 8 | + | # Palette drawn from docs/TOKENS.md hex values, mapped to starship's | |
| 9 | + | # color slots by function, not by name. | |
| 10 | + | ||
| 11 | + | format = """ | |
| 12 | + | $directory\ | |
| 13 | + | $git_branch\ | |
| 14 | + | $git_status\ | |
| 15 | + | $python\ | |
| 16 | + | $rust\ | |
| 17 | + | $nodejs\ | |
| 18 | + | $cmd_duration\ | |
| 19 | + | $line_break\ | |
| 20 | + | $character""" | |
| 21 | + | ||
| 22 | + | right_format = """$time""" | |
| 23 | + | ||
| 24 | + | add_newline = true | |
| 25 | + | ||
| 26 | + | # ------------------------------------------------------------------- | |
| 27 | + | # Entry glyph — the prompt character itself | |
| 28 | + | # ------------------------------------------------------------------- | |
| 29 | + | [character] | |
| 30 | + | success_symbol = "[▸](#5f5a4e)" # text-secondary | |
| 31 | + | error_symbol = "[▸](#c25d4f)" # accent-error on non-zero exit | |
| 32 | + | vimcmd_symbol = "[◂](#5a8f52)" # accent-ok (normal mode) | |
| 33 | + | ||
| 34 | + | # ------------------------------------------------------------------- | |
| 35 | + | # Directory — truncated, primary text | |
| 36 | + | # ------------------------------------------------------------------- | |
| 37 | + | [directory] | |
| 38 | + | style = "bold #302c22" # text-primary | |
| 39 | + | format = "[$path]($style)[$read_only]($read_only_style) " | |
| 40 | + | truncation_length = 4 | |
| 41 | + | truncation_symbol = "…/" | |
| 42 | + | truncate_to_repo = true | |
| 43 | + | read_only = " " | |
| 44 | + | read_only_style = "#c25d4f" | |
| 45 | + | ||
| 46 | + | # ------------------------------------------------------------------- | |
| 47 | + | # Git — branch (secondary), status (accent-warn if dirty) | |
| 48 | + | # ------------------------------------------------------------------- | |
| 49 | + | [git_branch] | |
| 50 | + | symbol = " " | |
| 51 | + | style = "#5f5a4e" # text-secondary | |
| 52 | + | format = "[$symbol$branch]($style) " | |
| 53 | + | ||
| 54 | + | [git_status] | |
| 55 | + | style = "#d1a234" # accent-warn | |
| 56 | + | format = "[$all_status$ahead_behind]($style) " | |
| 57 | + | conflicted = "=" | |
| 58 | + | ahead = "↑${count}" | |
| 59 | + | behind = "↓${count}" | |
| 60 | + | diverged = "↕${ahead_count}↓${behind_count}" | |
| 61 | + | untracked = "?" | |
| 62 | + | stashed = "$" | |
| 63 | + | modified = "!" | |
| 64 | + | staged = "+" | |
| 65 | + | renamed = "»" | |
| 66 | + | deleted = "✘" | |
| 67 | + | ||
| 68 | + | # ------------------------------------------------------------------- | |
| 69 | + | # Language versions — dim, only shown when relevant to cwd | |
| 70 | + | # ------------------------------------------------------------------- | |
| 71 | + | [python] | |
| 72 | + | symbol = " " | |
| 73 | + | style = "#8b8477" # text-muted | |
| 74 | + | format = "[$symbol$version]($style) " | |
| 75 | + | detect_extensions = ["py"] | |
| 76 | + | detect_files = ["pyproject.toml", "requirements.txt", "setup.py"] | |
| 77 | + | ||
| 78 | + | [rust] | |
| 79 | + | symbol = " " | |
| 80 | + | style = "#8b8477" | |
| 81 | + | format = "[$symbol$version]($style) " | |
| 82 | + | ||
| 83 | + | [nodejs] | |
| 84 | + | symbol = " " | |
| 85 | + | style = "#8b8477" | |
| 86 | + | format = "[$symbol$version]($style) " | |
| 87 | + | ||
| 88 | + | # ------------------------------------------------------------------- | |
| 89 | + | # Command duration — only for commands >2s | |
| 90 | + | # ------------------------------------------------------------------- | |
| 91 | + | [cmd_duration] | |
| 92 | + | min_time = 2000 | |
| 93 | + | style = "#5f5a4e" | |
| 94 | + | format = "[$duration]($style) " | |
| 95 | + | show_milliseconds = false | |
| 96 | + | ||
| 97 | + | # ------------------------------------------------------------------- | |
| 98 | + | # Right-aligned clock — display font role (readout, not chrome). | |
| 99 | + | # Kept in Iosevka since starship can't switch fonts per segment; | |
| 100 | + | # this is a small honest deviation from the "readouts in Departure" | |
| 101 | + | # rule that docs/TOKENS.md sanctions for terminal contexts. | |
| 102 | + | # ------------------------------------------------------------------- | |
| 103 | + | [time] | |
| 104 | + | disabled = false | |
| 105 | + | format = "[$time]($style)" | |
| 106 | + | time_format = "%H:%M" | |
| 107 | + | style = "#8b8477" | |
| 108 | + | ||
| 109 | + | # ------------------------------------------------------------------- | |
| 110 | + | # Disabled modules — noise for Alloy's audience | |
| 111 | + | # ------------------------------------------------------------------- | |
| 112 | + | [package] | |
| 113 | + | disabled = true | |
| 114 | + | ||
| 115 | + | [hostname] | |
| 116 | + | disabled = true | |
| 117 | + | ||
| 118 | + | [username] | |
| 119 | + | disabled = true | |
| 120 | + | ||
| 121 | + | [aws] | |
| 122 | + | disabled = true | |
| 123 | + | ||
| 124 | + | [gcloud] | |
| 125 | + | disabled = true | |
| 126 | + | ||
| 127 | + | [docker_context] | |
| 128 | + | disabled = true |