theme: YoRHa dark — NieR:Automata interface on the space-1 wallpaper
Replaces the Persona x Mocha rice. NieR's menu language is kept whole — plain rectangles, hairline rules, letter-spaced upright capitals, a square marker on the current row, corner ticks round panels, and selection shown by inverting the row — but the colours come from ~/.wallpapers/space-1.jpg rather than from the game's beige: the grey-green void as the ground, the suit's sage grey as text, the planet's white as the one accent, and the hull's red indicator lights as the alarm. The Persona geometry is switched off rather than ripped out: Theme.skew and Theme.cut are 0, so P5Panel, Skew and Geom collapse to rectangles. Overshoot easing, italics and black weights are gone shell-wide. New, borrowed from caelestia's screen border: bar/Frame.qml draws the bar, the rail and a thin left/bottom band as one hull on the bottom layer, with the desktop as a rounded opening cut out of it. Frame also owns all four exclusive zones, so the bar and rail are placed from the screen edge. Hyprland moves to 1px borders lit from the planet white into grey, a soft wide shadow and gaps measured from the opening. Alacritty, fish and dunst get matching YoRHa palettes. Neovim, GTK/Qt and btop are still Mocha. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5be22d86a9
commit
18091a7109
56 files changed
+796
-605
No files matched your search
+101
-92
@@ -1,10 +1,12 @@
|
||||
# Takemi — Persona × Mocha
|
||||
# Takemi — YoRHa dark
|
||||
|
||||
A Persona 5 flavoured Quickshell desktop for Hyprland, painted in Catppuccin
|
||||
Mocha. Blue for anything live, mauve for anything wrong, the Mocha greys for
|
||||
everything else, and no gradients anywhere. Everything leans by the same 14°,
|
||||
corners are chopped rather than rounded, and every surface is one continuous
|
||||
slab divided by hairlines rather than a cluster of floating cards.
|
||||
A NieR:Automata flavoured Quickshell desktop for Hyprland, kept dark and lit
|
||||
like its wallpaper: a lone figure at a porthole, the void outside, one planet's
|
||||
light. The planet white for anything live, the hull red for anything wrong,
|
||||
grey-green for everything else. Hairlines, square markers, corner ticks,
|
||||
letter-spaced capitals, and selection shown by inverting the row. The bar, the
|
||||
rail and a thin border are one hull around the desktop, and the desktop is the
|
||||
porthole cut out of it.
|
||||
|
||||
Replaces Waybar, dunst and hyprlock.
|
||||
|
||||
@@ -25,29 +27,30 @@ costs 2.5% of the width, where another 48px strip along the bottom would have
|
||||
cost 4.4% of the height on top of what the bar already takes.
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────┐
|
||||
│ ◆ │ 1 2 3 │ window title ♪ TRACK │ 42% │ 00:09 │ bar — 48px exclusive
|
||||
├────────────────────────────────────────────┤
|
||||
│ ▐█▌│ rail — 48px exclusive
|
||||
│ windows ▐ ▌│
|
||||
│ ▐ ▌│
|
||||
│ ▐ ▌│
|
||||
└────────────────────────────────────────────┘
|
||||
████████████████████████████████████████████████
|
||||
█ ◉ │ 1 2 3 │ window title ♪ TRACK │ CPU │ 20:04 █ bar — 40px, part of the hull
|
||||
█╭──────────────────────────────────────────╮ ▐▌█
|
||||
█│ │ ▐▌█ rail — 48px, part of the hull
|
||||
█│ windows │ ▐▌█
|
||||
█│ │ ▐▌█
|
||||
█╰──────────────────────────────────────────╯ █ frame — 8px left and bottom
|
||||
████████████████████████████████████████████████
|
||||
```
|
||||
|
||||
- **bar** — one slab: identity and workspaces on the left; the focused window,
|
||||
the player, the CPU/MEM/GPU readout and the clock on the right.
|
||||
- **rail** — one slab: network, bluetooth, audio, mic, backlight, battery, tray,
|
||||
- **hull** — `bar/Frame.qml`: one surface round the whole screen, with the
|
||||
desktop as a rounded opening. The bar and the rail sit on it.
|
||||
- **bar** — identity and workspaces on the left; the focused window, the
|
||||
player, the CPU/MEM/GPU readout and the clock on the right.
|
||||
- **rail** — network, bluetooth, audio, mic, backlight, battery, tray,
|
||||
notifications, power. Popouts open leftward, into the screen.
|
||||
|
||||
Each permanent surface is a single continuous `ChromeSurface` with modules
|
||||
divided by sheared hairlines. `BarPill` is chromeless by default — a module is
|
||||
*content inside* a surface, not a surface of its own — and marks hover with an
|
||||
accent underline. Pass `standalone: true` for the rare thing that really is its
|
||||
own panel.
|
||||
Modules are divided by hairlines. `BarPill` is chromeless by default — a module
|
||||
is *content inside* the hull, not a surface of its own — and marks hover with
|
||||
an accent underline. Pass `standalone: true` for the rare thing that really is
|
||||
its own panel.
|
||||
|
||||
The shell uses three deliberate surface tiers. **Chrome** (`ChromeSurface`) is
|
||||
the calm, texture-free bar, rail, and tooltip layer. **Transient**
|
||||
The shell uses three deliberate surface tiers. **Chrome** (the hull and
|
||||
`ChromeSurface`) is the calm, texture-free bar, rail, and tooltip layer. **Transient**
|
||||
(`PopoutSurface`) is reserved for expressive menus and detail panels, with one
|
||||
clear composition and stronger separation from the desktop. **Cinematic**
|
||||
(`P5Backdrop`) belongs only to scene-scale experiences such as power and lock;
|
||||
@@ -56,7 +59,7 @@ it is never used as decoration inside ordinary chrome or popouts.
|
||||
```
|
||||
shell.qml entrypoint — bar, rail, power menu, toasts, OSD per screen
|
||||
config/ palette, type scale, geometry, motion curves
|
||||
components/ the P5 primitives: panels, sliders, list rows, print-shadowed text
|
||||
components/ the primitives: panels, sliders, list rows, display text
|
||||
services/ data sources, all singletons
|
||||
bar/ the two surfaces and their modules
|
||||
popouts/ hover panels hanging off rail and bar modules
|
||||
@@ -204,39 +207,45 @@ means restarting Hyprland from a TTY.
|
||||
`power-profiles-daemon` is not installed (TLP is), so the power-profile
|
||||
switching in `services/Battery.qml` stays dormant. Nothing else depends on it.
|
||||
|
||||
The display face is Archivo Black, set italic almost everywhere. Change
|
||||
`Theme.fontDisplay` and everything follows.
|
||||
The display face is Noto Sans, upright and widely tracked — the nearest free
|
||||
face to NieR's FOT-Rodin that is already installed. Change `Theme.fontDisplay`
|
||||
and everything follows.
|
||||
|
||||
## Palette discipline
|
||||
|
||||
Catppuccin Mocha, spent on two hues. **Hue is meaning**; nothing gets a colour
|
||||
for decoration.
|
||||
YoRHa dark: NieR:Automata's interface language, painted from the wallpaper
|
||||
(`~/.wallpapers/space-1.jpg`) rather than from the game's beige. Two hues, and
|
||||
**hue is meaning**; nothing gets a colour for decoration.
|
||||
|
||||
- **Blue (`accent`, Mocha blue)** means live: the focused workspace, the
|
||||
selected row, the hovered control, a channel that is on, an unread badge.
|
||||
- **Mauve (`alarm`, Mocha mauve)** means wrong or destructive: critical battery,
|
||||
an urgent workspace, a critical notification, reboot and shut down.
|
||||
- **Grey** is everything else, and that includes *off*. A muted speaker, a
|
||||
muted mic and Do Not Disturb drop to `muted` grey with their off glyph. They
|
||||
used to be painted in the accent, which made a silenced channel look the most
|
||||
alive thing on the rail.
|
||||
- **Crust (`ink`)** is structure: the hard keyline, the offset under display
|
||||
type and panels, the text on an accent slab.
|
||||
- **Light (`accent`, `#eef1ea`)** means live: the focused workspace, the
|
||||
selected row, the hovered control, a channel that is on, an unread badge. It
|
||||
is the planet's white, barely a colour at all — NieR marks attention with
|
||||
brightness and inversion, not with hue.
|
||||
- **Red (`alarm`, `#c8684f`)** means wrong or destructive: critical battery, an
|
||||
urgent workspace, a critical notification, reboot and shut down. It is the
|
||||
hull's indicator lights, the only warm thing in the wallpaper.
|
||||
- **Grey-green** is everything else, and that includes *off*. A muted speaker,
|
||||
a muted mic and Do Not Disturb drop to `muted` grey with their off glyph.
|
||||
- **Ink** is the text on an inverted slab and the faint drop under display
|
||||
type.
|
||||
|
||||
**Selection is an inverted slab.** Focus and selection fill with the accent and
|
||||
print their text in crust (about 9:1). Hover stays on the surface tone with an
|
||||
accent mark. Destructive-active is the same slab in mauve. The `treatment*`
|
||||
tokens in `Theme.qml` encode all of this; use them rather than picking colours
|
||||
per widget.
|
||||
**Selection is the NieR cursor.** Focus and selection invert the row: a slab of
|
||||
the light with ink punched out of it. Hover lifts the surface one step and
|
||||
brings the marker up to full light, but never inverts. Destructive-active is
|
||||
the same slab in red. The `treatment*` tokens in `Theme.qml` encode all of
|
||||
this; use them rather than picking colours per widget.
|
||||
|
||||
**Print, not blur.** Display text (`SplitText`) carries one hard crust offset.
|
||||
The blue and mauve ghosts appear only while `glitch()` runs. Drawn permanently
|
||||
1.6px off the body, they read as a focus problem on Mocha's pastels rather than
|
||||
as misregistered print. The lock screen and the power menu are the exceptions;
|
||||
they are the cinematic surfaces and keep their split.
|
||||
**Markers, not slashes.** The current row, a button under the pointer and the
|
||||
end of a header rule carry a small square (`Theme.marker`). Popouts are framed
|
||||
by corner ticks (`Theme.tick`) in their tone colour; the border itself is
|
||||
structure and stays neutral.
|
||||
|
||||
**Flicker, not print.** Display text (`SplitText`) is upright, tracked by
|
||||
`Theme.tracking`, on a one-pixel soft drop. The two ghosts either side of it
|
||||
appear only while `glitch()` runs — NieR's brief data-corruption flicker.
|
||||
|
||||
**Texture is tiered.** Chrome (bar, rail, tooltips) and transient panels
|
||||
(popouts, OSD, toasts) are flat. Stripes and halftone live only in
|
||||
(popouts, OSD, toasts) are flat. The hairline grid and the dot wash live only in
|
||||
`P5Backdrop`, behind the lock screen and the power menu.
|
||||
|
||||
**Type has a floor.** Nothing renders below `Theme.fsMicro` (10px).
|
||||
@@ -245,60 +254,60 @@ they are the cinematic surfaces and keep their split.
|
||||
|
||||
| File | Covers |
|
||||
|---|---|
|
||||
| `quickshell/config/Theme.qml` | the shell: `accent`, `alarm` and the neutral ramp |
|
||||
| `hypr/lua/palette.lua` | window borders, groups, shadows |
|
||||
| `alacritty/catppuccin-mocha.toml` | the terminal (stock Mocha, cursor in the accent) |
|
||||
| `quickshell/config/Theme.qml` | the shell: `accent`, `alarm`, the neutral ramp, the hull |
|
||||
| `hypr/lua/palette.lua` | window borders, groups |
|
||||
| `alacritty/yorha.toml` | the terminal |
|
||||
| `fish/conf.d/yorha_theme.fish` | the prompt and pager |
|
||||
|
||||
Everything else derives. `accentDim` and `accentSoft` come off `accent`, `glow`
|
||||
*is* `accent`, and `primary` is plain `text`. `Theme.heat()` is a continuous
|
||||
text → blue → mauve ramp, so a CPU figure that has gone mauve means the same
|
||||
thing as a battery that has gone mauve. Tray icons are flattened to one colour
|
||||
(subtext, the accent on hover) for the same reason: app brand colours wreck the
|
||||
palette faster than anything else in the shell. nm-applet and blueman are
|
||||
hidden from the tray, since the rail already shows network and bluetooth, but
|
||||
keep running as the secret and pairing agents.
|
||||
Everything else derives. `glow` *is* `accent`, and `primary` is plain `text`.
|
||||
`Theme.heat()` is a continuous text → light → red ramp, so a CPU figure that
|
||||
has gone red means the same thing as a battery that has gone red. Tray icons
|
||||
are flattened to one colour (subtext, the accent on hover) for the same reason:
|
||||
app brand colours wreck the palette faster than anything else in the shell.
|
||||
nm-applet and blueman are hidden from the tray, since the rail already shows
|
||||
network and bluetooth, but keep running as the secret and pairing agents.
|
||||
|
||||
## The rest of the desktop
|
||||
|
||||
- **Hyprland** — `hypr/lua/look.lua`. No rounding, no blur, both opacities at
|
||||
`1.0`. The active border runs blue into lavender and the inactive border is
|
||||
`surfaceAlt`. The window shadow is a sharp 4px crust offset, the same printed
|
||||
drop the shell's panels carry, not a soft glow.
|
||||
- **Alacritty** — `alacritty/catppuccin-mocha.toml`, selected by the `import`
|
||||
in `alacritty.toml`. Stock Mocha except for the cursor, which is the accent.
|
||||
`takemi.toml` is left in place, unreferenced.
|
||||
- **Neovim** — the `catppuccin` plugin, flavour mocha, configured in
|
||||
`nvim/lua/plugins/ui.lua`. Blue is the accent there too. `colors/takemi.lua`
|
||||
is left in place, unused.
|
||||
- **Fish** — `fish/conf.d/takemi_theme.fish` is Catppuccin Mocha's fish theme
|
||||
with the Takemi selection rows: a solid accent block with crust punched out.
|
||||
`1.0`, 1px borders. The active border runs from the light into the suit's
|
||||
grey; the inactive border is `overlay`. The shadow is soft and wide, so
|
||||
windows float in the opening rather than being printed onto it. `gaps_out`
|
||||
is measured from the hull's opening, since the hull reserves its own zones.
|
||||
- **Alacritty** — `alacritty/yorha.toml`, selected by the `import` in
|
||||
`alacritty.toml`. Muted earth hues on the void; selection inverts.
|
||||
The Catppuccin and `takemi.toml` files are left in place, unreferenced.
|
||||
- **Neovim** — still the `catppuccin` plugin, flavour mocha, configured in
|
||||
`nvim/lua/plugins/ui.lua`. Not yet moved to the YoRHa palette.
|
||||
- **GTK and Qt** — still `catppuccin-mocha-blue`. Not yet moved either.
|
||||
- **Fish** — `fish/conf.d/yorha_theme.fish`.
|
||||
- **The launcher** — no external theming to keep in step, because it is part of
|
||||
this shell (`launcher/`). Fuzzel is gone; `takemi-dmenu` stands in for
|
||||
`fuzzel --dmenu` where a script needs a picker.
|
||||
- **No glass anywhere.** Alacritty is `opacity = 1.0, blur = false`, and
|
||||
Hyprland's `decoration:blur` is disabled. Blur is the signature of the
|
||||
frosted-glass look, which is the opposite of flat ink on flat ground — and
|
||||
with nothing translucent left it was costing three render passes for no
|
||||
visible result.
|
||||
Hyprland's `decoration:blur` is disabled.
|
||||
|
||||
There are **no gradients in this shell**; every fill is flat. `Theme.sheen`
|
||||
still exists as a no-op property because a teal-to-transparent wash on every
|
||||
panel was once the biggest source of murk in the design.
|
||||
There are **no gradients in the chrome**; every fill is flat. `Theme.sheen`
|
||||
still exists as a no-op property so old call sites need not be chased down.
|
||||
|
||||
## Geometry discipline
|
||||
|
||||
**One angle, one chamfer, everywhere.** `Theme.skew` is `tan(14°)` and every
|
||||
edge in the shell leans by exactly that, in the same direction; every corner is
|
||||
chopped by exactly `Theme.cut`. A vertical panel (the rail) leans its horizontal
|
||||
edges by a fraction of its *width*, which works out to the same 14°.
|
||||
**The hull.** Borrowed from caelestia's screen border: the bar, the rail and a
|
||||
thin band down the left and along the bottom (`Theme.frame`) are one surface,
|
||||
drawn by `bar/Frame.qml` on the bottom layer, and the desktop is a rounded
|
||||
opening cut out of it (`Theme.frameRadius`). Read against the wallpaper, you are
|
||||
inside the ship and the windows sit in the porthole. The bar and the rail draw
|
||||
no surface of their own and ignore exclusive zones; Frame reserves all four
|
||||
zones itself, so every piece is placed from the screen edge.
|
||||
|
||||
This is deliberate and was learned the hard way. An earlier pass gave every
|
||||
module a different lean, chamfer and height from per-index variance tables, on
|
||||
the theory that Persona geometry is "chaotic". It isn't — Persona UI is
|
||||
meticulously clean, and the chaos lives in composition and motion, not in each
|
||||
element being a different shape. Randomised geometry just reads as noise. If you
|
||||
find yourself adding a variance table, don't.
|
||||
**Rectangles, everywhere else.** NieR panels are plain boxes. `Theme.skew` and
|
||||
`Theme.cut` are both `0`, so `P5Panel`, `Skew` and `Geom` all collapse to
|
||||
rectangles; the knobs are kept so a shape can be brought back on purpose. The
|
||||
porthole's curve is the only one on screen, which is what lets it read.
|
||||
|
||||
Each surface is **one continuous slab**, with modules divided by sheared
|
||||
hairline rules rather than by gaps. A row of separate floating cards reads as
|
||||
clutter; that is what the dividers exist to avoid.
|
||||
**Motion glides.** No overshoot anywhere: things ease in on `OutCubic` or
|
||||
`OutExpo` and settle. NieR's interface is calm and mechanical.
|
||||
|
||||
Each surface is **one continuous slab**, with modules divided by hairline rules
|
||||
rather than by gaps. A row of separate floating cards reads as clutter; that is
|
||||
what the dividers exist to avoid.
|
||||
@@ -394,7 +394,7 @@ PanelWindow {
|
||||
NumberAnimation {
|
||||
target: drop; property: "y"
|
||||
from: -shell.height; to: 0
|
||||
duration: Theme.durSlow; easing.type: Easing.OutBack
|
||||
duration: Theme.durSlow; easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 304 B |
Binary file not shown.
|
After Width: | Height: | Size: 337 B |
@@ -51,13 +51,12 @@ Item {
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: Theme.fsSmall
|
||||
font.family: Theme.fontDisplay
|
||||
font.italic: true
|
||||
font.weight: Font.DemiBold
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
// Accent duplicate: visible only during the landing transition. The
|
||||
// small opposing offset gives the title Persona's rough print snap
|
||||
// small opposing offset gives the title NieR's brief corruption flicker
|
||||
// without leaving permanent motion in the bar.
|
||||
Text {
|
||||
id: ghost
|
||||
@@ -144,7 +143,7 @@ Item {
|
||||
NumberAnimation {
|
||||
target: label; property: "x"
|
||||
from: -10; to: 0
|
||||
duration: Theme.durBase; easing.type: Easing.OutBack
|
||||
duration: Theme.durBase; easing.type: Easing.OutCubic
|
||||
}
|
||||
NumberAnimation {
|
||||
target: label; property: "opacity"
|
||||
|
||||
+13
-33
@@ -27,29 +27,16 @@ PanelWindow {
|
||||
right: true
|
||||
}
|
||||
|
||||
margins {
|
||||
top: Theme.barMargin
|
||||
left: Theme.barMargin
|
||||
right: Theme.barMargin
|
||||
}
|
||||
|
||||
// Flush with the screen edge and drawn on nothing: the hull behind it is
|
||||
// painted by Frame, which is what joins the bar, the rail and the border
|
||||
// into one surface. Exclusive zones are Frame's job too, so every piece
|
||||
// of the hull is placed from the screen edge rather than from whichever
|
||||
// piece the compositor happened to arrange first.
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
implicitHeight: Theme.barHeight
|
||||
exclusiveZone: Theme.barHeight + Theme.barMargin
|
||||
color: "transparent"
|
||||
|
||||
// Calm permanent chrome: one opaque slab with no texture or offset copy.
|
||||
ChromeSurface {
|
||||
id: slab
|
||||
anchors.fill: parent
|
||||
lean: Theme.skew
|
||||
chop: Theme.cut
|
||||
chopCorners: [1, 3]
|
||||
padding: 0
|
||||
active: true
|
||||
slashWidth: 5
|
||||
}
|
||||
|
||||
readonly property real edgeInset: Theme.barHeight * Theme.skew + Theme.padM
|
||||
readonly property real edgeInset: Theme.padM
|
||||
|
||||
// ------------------------------------------------------------------ left
|
||||
Row {
|
||||
@@ -108,25 +95,18 @@ PanelWindow {
|
||||
}
|
||||
}
|
||||
|
||||
// A hairline rule between modules, sheared to the house angle. This is what
|
||||
// divides the bar now — gaps between cards are what made it look scattered.
|
||||
// A hairline rule between modules. This is what divides the bar — gaps
|
||||
// between cards are what made it look scattered.
|
||||
component Divider: Item {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
implicitWidth: Theme.padM * 2
|
||||
implicitHeight: Theme.barHeight
|
||||
|
||||
// A leaning hairline needs a box wide enough to hold the lean: at 20px
|
||||
// tall the top edge sits 20 * skew ≈ 5px right of the bottom one, so a
|
||||
// 1px-wide Skew folded into a bowtie instead. Width is the lean plus the
|
||||
// stroke the rule should actually read as.
|
||||
readonly property real ruleWeight: 1.5
|
||||
readonly property real ruleHeight: 20
|
||||
|
||||
Skew {
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: parent.ruleHeight * Theme.skew + parent.ruleWeight
|
||||
height: parent.ruleHeight
|
||||
color: Theme.alpha(Theme.outline, 0.5)
|
||||
width: 1
|
||||
height: 16
|
||||
color: Theme.alpha(Theme.outline, 0.6)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,6 @@ BarPill {
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsTitle
|
||||
font.weight: Theme.weightDisplay
|
||||
font.italic: true
|
||||
font.letterSpacing: 0.5
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
import QtQuick
|
||||
import QtQuick.Shapes
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import "root:/config"
|
||||
|
||||
// The hull: one surface for the bar, the rail and the thin band down the left
|
||||
// and along the bottom, with the desktop as a rounded opening cut out of it.
|
||||
// The idea is caelestia's screen border; the reading is the wallpaper's — you
|
||||
// are inside the ship, and the windows sit in the porthole.
|
||||
//
|
||||
// The hull lives on the bottom layer, under every window. Hyprland's gaps keep
|
||||
// tiled windows inside the opening, so nothing ever has to be drawn over a
|
||||
// window; a floating window dragged onto the frame simply covers it, and a
|
||||
// fullscreen one hides it, which is what should happen in both cases.
|
||||
//
|
||||
// The bar and the rail draw no surface of their own and ignore exclusive
|
||||
// zones, so every piece is placed from the screen edge. The four zones are
|
||||
// reserved here instead, by windows that draw nothing — that way the usable
|
||||
// area is exactly the opening, whichever surface the compositor arranges
|
||||
// first.
|
||||
Scope {
|
||||
id: root
|
||||
|
||||
required property var modelData
|
||||
|
||||
PanelWindow {
|
||||
id: hull
|
||||
|
||||
screen: root.modelData
|
||||
|
||||
WlrLayershell.layer: WlrLayer.Bottom
|
||||
WlrLayershell.namespace: "takemi-frame"
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
bottom: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
|
||||
color: "transparent"
|
||||
mask: Region {}
|
||||
|
||||
// The opening, in window coordinates.
|
||||
readonly property real x0: Theme.frame
|
||||
readonly property real y0: Theme.barHeight
|
||||
readonly property real x1: width - Theme.railWidth
|
||||
readonly property real y1: height - Theme.frame
|
||||
readonly property real r: Theme.frameRadius
|
||||
|
||||
readonly property string opening: {
|
||||
const x0 = hull.x0, y0 = hull.y0, x1 = hull.x1, y1 = hull.y1, r = hull.r;
|
||||
return `M ${x0 + r} ${y0} H ${x1 - r} A ${r} ${r} 0 0 1 ${x1} ${y0 + r}`
|
||||
+ ` V ${y1 - r} A ${r} ${r} 0 0 1 ${x1 - r} ${y1}`
|
||||
+ ` H ${x0 + r} A ${r} ${r} 0 0 1 ${x0} ${y1 - r}`
|
||||
+ ` V ${y0 + r} A ${r} ${r} 0 0 1 ${x0 + r} ${y0} Z`;
|
||||
}
|
||||
|
||||
Shape {
|
||||
anchors.fill: parent
|
||||
preferredRendererType: Shape.CurveRenderer
|
||||
|
||||
// The hull itself: the whole screen, minus the opening.
|
||||
ShapePath {
|
||||
fillColor: Theme.hull
|
||||
fillRule: ShapePath.OddEvenFill
|
||||
strokeColor: "transparent"
|
||||
|
||||
PathSvg {
|
||||
path: `M 0 0 H ${hull.width} V ${hull.height} H 0 Z ` + hull.opening
|
||||
}
|
||||
}
|
||||
|
||||
// The rim — a hairline round the opening, the lit edge of the
|
||||
// porthole in the wallpaper.
|
||||
ShapePath {
|
||||
fillColor: "transparent"
|
||||
strokeColor: Theme.rim
|
||||
strokeWidth: 1
|
||||
|
||||
PathSvg {
|
||||
path: hull.opening
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExclusionZone {
|
||||
anchors.top: true
|
||||
exclusiveZone: Theme.barHeight
|
||||
}
|
||||
|
||||
ExclusionZone {
|
||||
anchors.right: true
|
||||
exclusiveZone: Theme.railWidth
|
||||
}
|
||||
|
||||
ExclusionZone {
|
||||
anchors.bottom: true
|
||||
exclusiveZone: Theme.frame
|
||||
}
|
||||
|
||||
ExclusionZone {
|
||||
anchors.left: true
|
||||
exclusiveZone: Theme.frame
|
||||
}
|
||||
|
||||
component ExclusionZone: PanelWindow {
|
||||
screen: root.modelData
|
||||
WlrLayershell.layer: WlrLayer.Bottom
|
||||
WlrLayershell.namespace: "takemi-frame-zone"
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
color: "transparent"
|
||||
mask: Region {}
|
||||
implicitWidth: 1
|
||||
implicitHeight: 1
|
||||
}
|
||||
}
|
||||
@@ -109,7 +109,6 @@ BarPill {
|
||||
font.pixelSize: Theme.fsSmall
|
||||
font.family: Theme.fontDisplay
|
||||
font.weight: Font.DemiBold
|
||||
font.italic: true
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
@@ -217,7 +216,7 @@ BarPill {
|
||||
id: titleGlitch
|
||||
NumberAnimation {
|
||||
target: artFrame; property: "rotation"
|
||||
from: -8; to: 0; duration: Theme.durSlow; easing.type: Easing.OutBack
|
||||
from: -8; to: 0; duration: Theme.durSlow; easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-35
@@ -30,30 +30,14 @@ PanelWindow {
|
||||
right: true
|
||||
}
|
||||
|
||||
margins {
|
||||
top: Theme.barHeight + Theme.barMargin * 2
|
||||
bottom: Theme.barMargin
|
||||
right: Theme.barMargin
|
||||
}
|
||||
|
||||
// Hangs from the underside of the bar, flush with the screen edge. Like
|
||||
// the bar it draws no surface of its own; see Frame.
|
||||
margins.top: Theme.barHeight
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
implicitWidth: Theme.railWidth
|
||||
exclusiveZone: Theme.railWidth + Theme.barMargin
|
||||
color: "transparent"
|
||||
|
||||
// The same calm permanent-chrome preset used by the top bar.
|
||||
ChromeSurface {
|
||||
id: slab
|
||||
anchors.fill: parent
|
||||
vertical: true
|
||||
lean: Theme.skew
|
||||
chop: Theme.cut
|
||||
chopCorners: [1, 3]
|
||||
padding: 0
|
||||
active: true
|
||||
slashWidth: 5
|
||||
}
|
||||
|
||||
readonly property real edgeInset: Theme.railWidth * Theme.skew + Theme.padM
|
||||
readonly property real edgeInset: Theme.padM
|
||||
|
||||
// ------------------------------------------------------------------- top
|
||||
Column {
|
||||
@@ -183,25 +167,16 @@ PanelWindow {
|
||||
}
|
||||
}
|
||||
|
||||
// The rail's counterpart to the bar's divider: a horizontal hairline,
|
||||
// sheared to the same angle the rail's own edges lean at.
|
||||
// The rail's counterpart to the bar's divider: a horizontal hairline.
|
||||
component Divider: Item {
|
||||
implicitWidth: Theme.railWidth
|
||||
implicitHeight: Theme.padM + 4
|
||||
|
||||
// Same correction as the bar's divider, on the other axis: a 22px rule
|
||||
// rises 22 * skew ≈ 5px across its run, so the box has to be that tall
|
||||
// plus the weight of the stroke. At height 1 the polygon inverted and
|
||||
// the rule rendered as a stubby wedge sitting left of centre.
|
||||
readonly property real ruleWeight: 1.5
|
||||
readonly property real ruleWidth: 22
|
||||
|
||||
Skew {
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: parent.ruleWidth
|
||||
height: parent.ruleWidth * Theme.skew + parent.ruleWeight
|
||||
vertical: true
|
||||
color: Theme.alpha(Theme.outline, 0.5)
|
||||
width: 16
|
||||
height: 1
|
||||
color: Theme.alpha(Theme.outline, 0.6)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ Item {
|
||||
|
||||
scale: root.hovered ? 1.08 : 1.0
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: Theme.durBase; easing.type: Easing.OutBack }
|
||||
NumberAnimation { duration: Theme.durBase; easing.type: Easing.OutCubic }
|
||||
}
|
||||
|
||||
onAlarmChanged: if (alarm) glyph.bump()
|
||||
|
||||
@@ -121,7 +121,6 @@ BarPill {
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsBody
|
||||
font.weight: Theme.weightDisplay
|
||||
font.italic: true
|
||||
font.letterSpacing: 0.5
|
||||
renderType: Text.NativeRendering
|
||||
|
||||
|
||||
@@ -12,33 +12,15 @@ BarPill {
|
||||
required property var screenRef
|
||||
|
||||
accent: Theme.accent
|
||||
slash: true
|
||||
padding: Theme.padS
|
||||
lean: Theme.skew
|
||||
implicitWidth: Theme.barHeight + contentPad
|
||||
|
||||
onClicked: Actions.toggleLauncher()
|
||||
onRightClicked: Actions.reloadShell()
|
||||
|
||||
// The wordmark. Was the Death arcana skull (nf-md-skull, U+F068C) — a
|
||||
// pictogram in a shell that otherwise says everything in heavy italic
|
||||
// type. SplitText puts it in the display face with the ink print
|
||||
// offset every other heading carries, so the house mark is built out of
|
||||
// the same parts as the rest of the bar.
|
||||
SplitText {
|
||||
id: mark
|
||||
Porthole {
|
||||
anchors.centerIn: parent
|
||||
text: "P5"
|
||||
pixelSize: Theme.fsLarge
|
||||
letterSpacing: 0
|
||||
color: root.hovered ? Theme.accent : Theme.primary
|
||||
}
|
||||
|
||||
// Kick the ghosts out and let them snap back. The skull could spin a full
|
||||
// turn and still read as a skull; a wordmark upside down just reads as
|
||||
// broken, so the click gets the glitch instead.
|
||||
Connections {
|
||||
target: root
|
||||
function onClicked() { mark.glitch(); }
|
||||
size: 18
|
||||
lit: root.hovered
|
||||
}
|
||||
}
|
||||
@@ -79,7 +79,7 @@ Column {
|
||||
|
||||
scale: itemHover.hovered ? 1.18 : 1.0
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: Theme.durBase; easing.type: Easing.OutBack }
|
||||
NumberAnimation { duration: Theme.durBase; easing.type: Easing.OutCubic }
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
|
||||
@@ -75,7 +75,7 @@ Item {
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: Theme.durSlow
|
||||
easing.type: Easing.OutBack
|
||||
easing.type: Easing.OutCubic
|
||||
easing.overshoot: 1.6
|
||||
}
|
||||
}
|
||||
@@ -122,7 +122,6 @@ Item {
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsSmall
|
||||
font.weight: Theme.weightDisplay
|
||||
font.italic: true
|
||||
renderType: Text.NativeRendering
|
||||
|
||||
Behavior on opacity {
|
||||
|
||||
@@ -3,7 +3,7 @@ import "root:/config"
|
||||
import "root:/components"
|
||||
|
||||
// Calm, permanent-chrome preset. It is deliberately flat and opaque: one
|
||||
// neutral keyline, no texture, no offset copy, and no accent unless active.
|
||||
// neutral hairline, no texture, no ticks, and no accent unless active.
|
||||
P5Panel {
|
||||
property bool active: false
|
||||
property color tone: Theme.treatmentActiveMark
|
||||
@@ -12,16 +12,10 @@ P5Panel {
|
||||
fillOpacity: 1.0
|
||||
border: Theme.treatmentRestMark
|
||||
borderWidth: 1
|
||||
// Keep the hard ink contour. Removing both texture and keyline made the
|
||||
// permanent slabs read as generic broadcast HUD chrome.
|
||||
keyline: true
|
||||
drop: false
|
||||
halftone: false
|
||||
sheen: false
|
||||
slash: active
|
||||
slashColor: tone
|
||||
slashWidth: 4
|
||||
lean: 0.06
|
||||
chop: Theme.cut
|
||||
slashWidth: 2
|
||||
padding: Theme.padS
|
||||
}
|
||||
@@ -3,7 +3,10 @@ pragma Singleton
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
// Polygon maths for the Persona 5 panel language: everything leans, and corners
|
||||
// Polygon maths for panel shapes. Under the YoRHa theme nothing leans and
|
||||
// nothing is chopped (Theme.skew and Theme.cut are 0), so these collapse to
|
||||
// plain rectangles; they are kept so a shape can be brought back on purpose.
|
||||
// Originally the Persona 5 panel language: everything leans, and corners
|
||||
// get chopped rather than rounded.
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
@@ -39,7 +39,7 @@ Text {
|
||||
}
|
||||
NumberAnimation {
|
||||
target: root; property: "scale"
|
||||
to: 1.0; duration: Theme.durSlow; easing.type: Easing.OutBack
|
||||
to: 1.0; duration: Theme.durSlow; easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,8 @@ import "root:/config"
|
||||
// came out as a faint milky film. This is the one row they share now.
|
||||
//
|
||||
// Rest is bare. Hover lifts the row onto the surface tone. The current item —
|
||||
// connected, in use — carries an accent tick down its leading edge and an
|
||||
// accent glyph, and its label goes to full weight.
|
||||
// connected, in use — carries the NieR square marker at its leading edge and
|
||||
// an accent glyph, and its label goes to full weight.
|
||||
Item {
|
||||
id: root
|
||||
|
||||
@@ -40,12 +40,13 @@ Item {
|
||||
Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 3
|
||||
height: root.current ? root.height - 10 : 0
|
||||
anchors.leftMargin: 2
|
||||
width: root.current ? Theme.marker : 0
|
||||
height: width
|
||||
color: Theme.accent
|
||||
|
||||
Behavior on height {
|
||||
NumberAnimation { duration: Theme.durBase; easing.type: Easing.OutBack }
|
||||
Behavior on width {
|
||||
NumberAnimation { duration: Theme.durBase; easing.type: Easing.OutCubic }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,8 +77,7 @@ Item {
|
||||
color: root.current || root.hovered ? Theme.text : Theme.subtext
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsSmall
|
||||
font.italic: true
|
||||
font.weight: root.current ? Font.Black : Font.Medium
|
||||
font.weight: root.current ? Font.DemiBold : Font.Medium
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import QtQuick
|
||||
import "root:/config"
|
||||
import "root:/components"
|
||||
|
||||
// A segmented load meter — slanted ticks that light up left to right. Reads as
|
||||
// A segmented load meter — upright ticks that light up left to right. Reads as
|
||||
// a gauge at a glance and keeps the panel language consistent.
|
||||
Item {
|
||||
id: root
|
||||
|
||||
@@ -21,8 +21,8 @@ Item {
|
||||
// The card's own geometry, published so anything drawn along its edges —
|
||||
// the toast countdown rule — can stay inside the chopped corners instead of
|
||||
// running out past them.
|
||||
readonly property real lean: 0.05
|
||||
readonly property real chop: 12
|
||||
readonly property real lean: Theme.skew
|
||||
readonly property real chop: Theme.cut
|
||||
|
||||
implicitHeight: panel.height
|
||||
|
||||
@@ -84,8 +84,7 @@ Item {
|
||||
wrapMode: Text.WordWrap
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsBody
|
||||
font.weight: Font.Black
|
||||
font.italic: true
|
||||
font.weight: Font.DemiBold
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
@@ -141,7 +140,6 @@ Item {
|
||||
color: actionHover.hovered ? Theme.ink : Theme.text
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsMicro
|
||||
font.italic: true
|
||||
font.weight: Font.DemiBold
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
@@ -1,54 +1,46 @@
|
||||
import QtQuick
|
||||
import QtQuick.Shapes
|
||||
import "root:/config"
|
||||
import "root:/components"
|
||||
|
||||
// The shared ground for the two full-screen surfaces: an accent wedge leaning
|
||||
// at the house angle, a tiled stripe field that sweeps in from the left, and a
|
||||
// halftone dot wash over the top.
|
||||
// The shared ground for the two full-screen surfaces, in the NieR menu
|
||||
// pattern: a hairline grid that sweeps in from the left, a darker column down
|
||||
// the left-hand side for the menu or the clock to stand in, and a dot wash
|
||||
// over the top.
|
||||
//
|
||||
// The lock screen and the power menu each used to draw their own version of
|
||||
// this. They disagreed — the power menu had a wedge and a full stripe field,
|
||||
// the lock had a 42px stripe band and no wedge, and the wedge leaned at 0.32
|
||||
// where every panel in the shell leans at Theme.skew. Building both on one
|
||||
// component is what makes them read as the same object seen twice rather than
|
||||
// as two guesses at the same brief.
|
||||
// The lock screen and the power menu both stand on this one component, which
|
||||
// is what makes them read as the same object seen twice rather than as two
|
||||
// guesses at the same brief.
|
||||
Item {
|
||||
id: root
|
||||
|
||||
// 0 = withdrawn, 1 = fully present. Drives the stripe slide, the stripe
|
||||
// opacity and the wedge together, so a caller animates one number instead
|
||||
// 0 = withdrawn, 1 = fully present. Drives the grid slide, the grid
|
||||
// opacity and the column together, so a caller animates one number instead
|
||||
// of keeping three in sync. The power menu runs it both ways on open and
|
||||
// close; the lock runs it once on entry.
|
||||
property real reveal: 1
|
||||
|
||||
property color tone: Theme.accent
|
||||
|
||||
// The column: a band of the void, edged by a hairline of the light.
|
||||
// `wedge*` names are kept from the Persona layout so callers did not have
|
||||
// to move; there is nothing wedge-shaped left.
|
||||
property bool wedge: true
|
||||
property real wedgeOpacity: 0.35
|
||||
// Bottom-left corner of the wedge and its span, as fractions of width. The
|
||||
// wedge leans right going up, like every other edge in the shell, so its
|
||||
// top edge sits `leanOffset` further right than its bottom.
|
||||
property real wedgeLeft: 0
|
||||
property real wedgeSpan: 0.34
|
||||
|
||||
property bool stripes: true
|
||||
// Tuned down from 0.10 for Mocha. Crust stripes on the blue-grey base read
|
||||
// far heavier than they did on black, and buzzed against the text.
|
||||
property real stripeOpacity: 0.07
|
||||
property real stripeOpacity: 0.05
|
||||
|
||||
property bool halftone: true
|
||||
property real halftoneOpacity: 0.05
|
||||
property color halftoneColor: Theme.primary
|
||||
|
||||
// ONE angle, everywhere — the same rule the panels follow.
|
||||
readonly property real leanOffset: root.height * Theme.skew
|
||||
|
||||
// Diagonal stripe field, sliding in from off-screen left.
|
||||
// Hairline grid, sliding in from off-screen left.
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
visible: root.stripes && root.reveal > 0
|
||||
source: Theme.texStripes
|
||||
source: Theme.texGrid
|
||||
fillMode: Image.Tile
|
||||
opacity: root.stripeOpacity * root.reveal
|
||||
smooth: false
|
||||
@@ -63,39 +55,33 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
// The wedge. Drawn after the stripes so it reads as a slab laid over them.
|
||||
Shape {
|
||||
anchors.fill: parent
|
||||
// The column. Drawn after the grid so it reads as a panel laid over it.
|
||||
Item {
|
||||
x: root.wedgeLeft * root.width
|
||||
width: root.wedgeSpan * root.width
|
||||
height: root.height
|
||||
visible: root.wedge && root.reveal > 0
|
||||
opacity: root.reveal
|
||||
preferredRendererType: Shape.CurveRenderer
|
||||
|
||||
ShapePath {
|
||||
fillColor: Theme.alpha(Theme.accentDim, root.wedgeOpacity)
|
||||
strokeColor: "transparent"
|
||||
joinStyle: ShapePath.MiterJoin
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Theme.alpha(Theme.ink, root.wedgeOpacity)
|
||||
}
|
||||
|
||||
PathPolyline {
|
||||
path: {
|
||||
const x = root.wedgeLeft * root.width;
|
||||
const span = root.wedgeSpan * root.width;
|
||||
const off = root.leanOffset;
|
||||
return Geom.closed([
|
||||
Qt.point(x + off, 0),
|
||||
Qt.point(x + off + span, 0),
|
||||
Qt.point(x + span, root.height),
|
||||
Qt.point(x, root.height)
|
||||
]);
|
||||
}
|
||||
}
|
||||
// Its edge, drawn top-down as the column arrives.
|
||||
Rectangle {
|
||||
anchors.right: parent.right
|
||||
width: 1
|
||||
height: parent.height * root.reveal
|
||||
color: Theme.alpha(root.tone, 0.35)
|
||||
}
|
||||
}
|
||||
|
||||
// Screen-printed dot wash over the whole thing.
|
||||
// Dot wash over the whole thing.
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
visible: root.halftone
|
||||
source: Theme.texHalftone
|
||||
source: Theme.texDots
|
||||
fillMode: Image.Tile
|
||||
opacity: root.halftoneOpacity
|
||||
smooth: false
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import QtQuick
|
||||
import "root:/config"
|
||||
|
||||
// Chopped, leaning button with one activation path for pointer and keyboard.
|
||||
// NieR menu button: a hairline box with a square marker that lights when the
|
||||
// button is pointed at or chosen. One activation path for pointer and keyboard.
|
||||
FocusScope {
|
||||
id: root
|
||||
|
||||
@@ -11,7 +12,7 @@ FocusScope {
|
||||
property bool destructive: false
|
||||
property bool selected: false
|
||||
property real lean: Theme.skew
|
||||
property real lunge: 6
|
||||
property real lunge: 4
|
||||
property bool wide: false
|
||||
|
||||
signal clicked()
|
||||
@@ -24,7 +25,7 @@ FocusScope {
|
||||
// Keyboard focus and roving selection invert the slab to solid accent.
|
||||
// Pointer hover stays a keyline change, so the two never look alike and a
|
||||
// mouse user never sees the "selected" treatment by accident. Destructive
|
||||
// buttons keep their own mauve inversion for both.
|
||||
// buttons keep their own red inversion for both.
|
||||
readonly property bool inverted: root.enabled && !root.destructive && root.focusedOrSelected
|
||||
|
||||
// Pointer activation must not turn a transient action into the black/white
|
||||
@@ -70,8 +71,6 @@ FocusScope {
|
||||
return Theme.alpha(root.accent, 0.55);
|
||||
}
|
||||
borderWidth: Theme.stroke
|
||||
slash: !root.highlighted
|
||||
slashColor: root.destructive ? Theme.alarm : root.accent
|
||||
|
||||
Behavior on fillOpacity {
|
||||
NumberAnimation { duration: Theme.durFast }
|
||||
@@ -83,6 +82,20 @@ FocusScope {
|
||||
anchors.left: parent.left
|
||||
spacing: Theme.padM
|
||||
|
||||
// The marker. Dim at rest, full strength under the pointer or the
|
||||
// cursor, in whatever colour the label is wearing.
|
||||
Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: Theme.marker
|
||||
height: Theme.marker
|
||||
color: label.color
|
||||
opacity: root.highlighted ? 1.0 : 0.35
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation { duration: Theme.durFast }
|
||||
}
|
||||
}
|
||||
|
||||
Icon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: root.icon !== ""
|
||||
@@ -100,6 +113,7 @@ FocusScope {
|
||||
}
|
||||
|
||||
Text {
|
||||
id: label
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: root.text
|
||||
color: {
|
||||
@@ -114,8 +128,7 @@ FocusScope {
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsBody
|
||||
font.weight: Theme.weightDisplay
|
||||
font.italic: true
|
||||
font.letterSpacing: 1.5
|
||||
font.letterSpacing: Theme.tracking
|
||||
font.capitalization: Font.AllUppercase
|
||||
renderType: Text.NativeRendering
|
||||
|
||||
@@ -132,7 +145,7 @@ FocusScope {
|
||||
Behavior on x {
|
||||
NumberAnimation {
|
||||
duration: Theme.durBase
|
||||
easing.type: Easing.OutBack
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,13 @@ import QtQuick.Effects
|
||||
import "root:/config"
|
||||
import "root:/components"
|
||||
|
||||
// The base surface for everything in this shell: a leaning, corner-chopped slab
|
||||
// with an optional halftone wash and a accent slash along its leading edge.
|
||||
// The base surface for everything in this shell. Under the YoRHa theme it is a
|
||||
// plain rectangle with a hairline border, an optional dot wash, an optional
|
||||
// accent bar down its leading edge, and optional corner ticks — the brackets
|
||||
// NieR frames its panels with.
|
||||
//
|
||||
// The lean and chop knobs still exist and still work, so a caller can bring a
|
||||
// shape back on purpose, but Theme.skew and Theme.cut are both zero.
|
||||
Item {
|
||||
id: root
|
||||
|
||||
@@ -29,12 +34,12 @@ Item {
|
||||
property real chop: Theme.cut
|
||||
property var chopCorners: [1, 3]
|
||||
|
||||
// Tone slash down the leading edge — the Persona 5 tell.
|
||||
// Accent bar down the leading edge.
|
||||
property bool slash: false
|
||||
property color slashColor: Theme.accent
|
||||
property real slashWidth: 4
|
||||
|
||||
// Screen-printed dot wash.
|
||||
// Dot-grid wash.
|
||||
property bool halftone: false
|
||||
property color halftoneColor: Theme.primary
|
||||
property real halftoneOpacity: 0.07
|
||||
@@ -45,16 +50,20 @@ Item {
|
||||
// call sites that still set it don't have to be chased down.
|
||||
property bool sheen: false
|
||||
|
||||
// The screen-print stack. A pure-black copy of the silhouette sits behind
|
||||
// the fill, offset down-and-right, and the fill carries a black keyline
|
||||
// outside its coloured border. Together these are what stop the panel from
|
||||
// reading as a flat clip-path.
|
||||
property bool drop: true
|
||||
// Optional print stack: an ink copy of the silhouette offset behind the
|
||||
// fill, and an ink keyline outside the border. Both off by default — on a
|
||||
// dark ground they only thicken the edge.
|
||||
property bool drop: false
|
||||
property real dropOffset: Theme.dropOffset
|
||||
property color dropColor: Theme.ink
|
||||
property bool keyline: true
|
||||
property bool keyline: false
|
||||
property real keylineWidth: Theme.keylineWidth
|
||||
|
||||
// Corner ticks: a short L at each corner, just outside the border.
|
||||
property bool ticks: false
|
||||
property color tickColor: Theme.outline
|
||||
property real tickLength: Theme.tick
|
||||
|
||||
readonly property real leanInset:
|
||||
(vertical ? width : height) * Math.abs(lean)
|
||||
|
||||
@@ -165,7 +174,7 @@ Item {
|
||||
asynchronous: true
|
||||
sourceComponent: Image {
|
||||
anchors.fill: parent
|
||||
source: Theme.texHalftone
|
||||
source: Theme.texDots
|
||||
fillMode: Image.Tile
|
||||
opacity: root.halftoneOpacity
|
||||
smooth: false
|
||||
@@ -237,6 +246,44 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
// Corner ticks. Two hairlines per corner, sitting 3px outside the panel so
|
||||
// they read as a frame around it rather than as part of its border.
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
anchors.margins: -3
|
||||
active: root.ticks
|
||||
sourceComponent: Item {
|
||||
Repeater {
|
||||
model: 4
|
||||
|
||||
Item {
|
||||
required property int index
|
||||
readonly property bool atRight: index === 1 || index === 2
|
||||
readonly property bool atBottom: index >= 2
|
||||
|
||||
x: atRight ? parent.width - width : 0
|
||||
y: atBottom ? parent.height - height : 0
|
||||
width: root.tickLength
|
||||
height: root.tickLength
|
||||
|
||||
Rectangle {
|
||||
y: parent.atBottom ? parent.height - 1 : 0
|
||||
width: parent.width
|
||||
height: 1
|
||||
color: root.tickColor
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
x: parent.atRight ? parent.width - 1 : 0
|
||||
width: 1
|
||||
height: parent.height
|
||||
color: root.tickColor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentHolder
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -2,7 +2,8 @@ import QtQuick
|
||||
import "root:/config"
|
||||
import "root:/components"
|
||||
|
||||
// Leaning slider with a chopped handle. Drag or click anywhere on the rail.
|
||||
// Hairline slider with a square handle, the NieR settings-menu slider. Drag or
|
||||
// click anywhere on the rail.
|
||||
Item {
|
||||
id: root
|
||||
|
||||
@@ -30,7 +31,7 @@ Item {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: root.activeFocus ? 10 : 6
|
||||
height: root.activeFocus ? 4 : 2
|
||||
// Focus widens the rail and rings it in the accent rather than filling
|
||||
// it: the level fill is often the accent itself, and a solid accent
|
||||
// rail swallowed it.
|
||||
@@ -50,7 +51,7 @@ Item {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
width: Math.max(0, Math.min(1, root.value)) * root.width
|
||||
height: 6
|
||||
height: root.activeFocus ? 4 : 2
|
||||
color: root.enabled ? root.accent : Theme.treatmentDisabledText
|
||||
|
||||
Behavior on width {
|
||||
@@ -66,14 +67,14 @@ Item {
|
||||
// Handle
|
||||
Skew {
|
||||
id: handle
|
||||
width: 6
|
||||
height: root.activeFocus || hover.hovered || drag.active ? 18 : 14
|
||||
width: height
|
||||
height: root.activeFocus || hover.hovered || drag.active ? 12 : 10
|
||||
color: root.enabled ? Theme.text : Theme.treatmentDisabledText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
x: Math.max(0, Math.min(1, root.value)) * root.width - width / 2
|
||||
|
||||
Behavior on height {
|
||||
NumberAnimation { duration: Theme.durFast; easing.type: Easing.OutBack }
|
||||
NumberAnimation { duration: Theme.durFast; easing.type: Easing.OutCubic }
|
||||
}
|
||||
Behavior on x {
|
||||
enabled: !drag.active
|
||||
|
||||
@@ -69,7 +69,6 @@ PopupWindow {
|
||||
ChromeSurface {
|
||||
anchors.fill: parent
|
||||
padding: root.pad
|
||||
lean: 0.06
|
||||
|
||||
Column {
|
||||
id: textColumn
|
||||
@@ -84,7 +83,6 @@ PopupWindow {
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsSmall
|
||||
font.weight: Theme.weightDisplay
|
||||
font.italic: true
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
|
||||
@@ -226,12 +226,12 @@ PopupWindow {
|
||||
}
|
||||
NumberAnimation {
|
||||
target: contentHolder; property: "scale"
|
||||
to: 1.0; duration: Theme.durSlow; easing.type: Easing.OutBack
|
||||
to: 1.0; duration: Theme.durSlow; easing.type: Easing.OutCubic
|
||||
}
|
||||
NumberAnimation {
|
||||
target: contentHolder; property: root.slideProperty
|
||||
from: root.slideOrigin; to: root.bleed
|
||||
duration: Theme.durSlow; easing.type: Easing.OutBack
|
||||
duration: Theme.durSlow; easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import QtQuick
|
||||
import "root:/config"
|
||||
|
||||
// The house mark: a porthole with a planet low in it — the wallpaper's one
|
||||
// composition, drawn in a hairline ring and a disc. The bar's sigil and the
|
||||
// lock screen both draw it, so the two are the same mark at two sizes.
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property real size: 18
|
||||
property bool lit: false
|
||||
|
||||
implicitWidth: root.size
|
||||
implicitHeight: root.size
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: width / 2
|
||||
color: "transparent"
|
||||
border.width: Math.max(1, Math.round(root.size / 18))
|
||||
border.color: root.lit ? Theme.accent : Theme.primaryDim
|
||||
|
||||
Behavior on border.color {
|
||||
ColorAnimation { duration: Theme.durFast }
|
||||
}
|
||||
}
|
||||
|
||||
// The planet's limb, sitting on the ring's lower edge. Always the planet
|
||||
// white; `lit` only lets it rise a little.
|
||||
Rectangle {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: root.size / 6
|
||||
width: root.size * (root.lit ? 0.44 : 0.34)
|
||||
height: width
|
||||
radius: width / 2
|
||||
color: Theme.accent
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation { duration: Theme.durBase; easing.type: Easing.OutCubic }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
import QtQuick
|
||||
import "root:/config"
|
||||
|
||||
// Display text, screen-printed: the body sits on a hard crust copy knocked a
|
||||
// pixel and a half down-right — the same offset `P5Panel` puts behind every
|
||||
// slab. Drives most headings in the shell.
|
||||
// Display text: upright, widely tracked, sitting on a soft ink copy a pixel
|
||||
// down-right — the faint drop NieR puts under every line of its interface.
|
||||
// Drives most headings in the shell.
|
||||
//
|
||||
// This used to carry a permanent RGB split, a blue and a mauve ghost either
|
||||
// side of the body. On crimson-and-black that read as misregistered print; on
|
||||
// Mocha's pastels it read as blur, and it turned every heading in the shell
|
||||
// soft. The two ghosts still exist, but only for the moment `glitch()` runs.
|
||||
// The two ghosts either side of the body are the data-corruption flicker NieR
|
||||
// uses when something changes under you. They are invisible at rest and only
|
||||
// appear for the moment `glitch()` runs.
|
||||
Item {
|
||||
id: root
|
||||
|
||||
@@ -16,16 +15,16 @@ Item {
|
||||
property int pixelSize: Theme.fsLarge
|
||||
property int weight: Theme.weightDisplay
|
||||
property string family: Theme.fontDisplay
|
||||
property bool italic: true
|
||||
property bool italic: false
|
||||
property color color: Theme.text
|
||||
property int elide: Text.ElideNone
|
||||
property int horizontalAlignment: Text.AlignLeft
|
||||
property real letterSpacing: 0.5
|
||||
property real letterSpacing: Theme.tracking
|
||||
|
||||
// Print shadow. Scales gently with size so a 34px heading does not sit on
|
||||
// Drop shadow. Scales gently with size so a 34px heading does not sit on
|
||||
// the same hairline offset as an 11px label.
|
||||
property real shadowOffset: Math.max(1, Math.round(root.pixelSize / 10))
|
||||
property color shadowColor: Theme.ink
|
||||
property real shadowOffset: Math.max(1, Math.round(root.pixelSize / 16))
|
||||
property color shadowColor: Theme.alpha(Theme.ink, 0.85)
|
||||
|
||||
// Ghost offset and resting strength. Resting strength is zero, so the
|
||||
// ghosts are invisible until `glitch()` kicks them out. A caller that sets
|
||||
|
||||
+113
-95
@@ -3,85 +3,93 @@ pragma Singleton
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
// Mocha palette: Catppuccin Mocha ground, blue as the accent, mauve as the
|
||||
// alarm. Persona geometry, softer colour.
|
||||
// YoRHa dark: the NieR:Automata interface language, lit the way
|
||||
// ~/.wallpapers/space-1.jpg is lit.
|
||||
//
|
||||
// The Takemi branch ran monochrome-plus-crimson, where one hue carried both
|
||||
// "active" and "wrong". Mocha has room for two: blue is every resting accent —
|
||||
// focus, selection, the thing you are pointing at — and mauve is reserved for
|
||||
// the things that bite, so destructive and error still read at a glance
|
||||
// without a third colour entering the shell.
|
||||
// NieR's menus are sand paper and graphite — monochrome, hairline rules,
|
||||
// letter-spaced capitals, a small square marking where you are, and selection
|
||||
// shown by inverting the row rather than by colouring it. That language is
|
||||
// kept whole. The colours are not NieR's: the game's beige is a lit room, and
|
||||
// this rice is the dark outside the porthole. The ground is the wallpaper's
|
||||
// grey-green void, the text is the same sage grey the suit catches, and the
|
||||
// one bright thing on screen is the planet's white — so focus and selection
|
||||
// are a slab of that light with the void punched out of it.
|
||||
//
|
||||
// Mauve rather than Mocha's pink: pink is a pastel, and a slab of it over this
|
||||
// ground goes chalky. Mauve is saturated enough to hold an edge against the
|
||||
// near-black surfaces the Persona layout is built from.
|
||||
//
|
||||
// Everything else is Mocha's own neutral ramp. Fills stay flat and keylines
|
||||
// stay hard; only the hues moved.
|
||||
// There is still no third colour. The only warm thing in the wallpaper is the
|
||||
// tiny red of the hull's indicator lights, and that is what `alarm` is.
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
// ---------------------------------------------------------------- colors
|
||||
// Crust, not pure black: it is the darkest thing in Mocha, so it keeps its
|
||||
// job as the hard keyline and as text punched out of an accent fill.
|
||||
readonly property color ink: "#11111b"
|
||||
// Darker than the ground: text punched out of a light fill, and the
|
||||
// shadow under display text.
|
||||
readonly property color ink: "#090a08"
|
||||
|
||||
readonly property color base: "#1e1e2e"
|
||||
readonly property color mantle: "#181825"
|
||||
readonly property color surface: "#313244"
|
||||
readonly property color surfaceAlt: "#45475a"
|
||||
readonly property color overlay: "#585b70"
|
||||
readonly property color outline: "#6c7086"
|
||||
// The void. Green-black rather than neutral so the shell and the
|
||||
// wallpaper read as one dark, not two.
|
||||
readonly property color base: "#0f110e"
|
||||
readonly property color mantle: "#0c0d0b"
|
||||
readonly property color surface: "#161915"
|
||||
readonly property color surfaceAlt: "#20241f"
|
||||
readonly property color overlay: "#383e35"
|
||||
|
||||
readonly property color text: "#cdd6f4"
|
||||
readonly property color subtext: "#a6adc8"
|
||||
readonly property color muted: "#7f849c"
|
||||
// The hull the desktop is framed by. Darker than anything inside the
|
||||
// opening, so the frame reads as the inside of the ship and the windows as
|
||||
// what you are looking out at.
|
||||
readonly property color hull: root.mantle
|
||||
readonly property color rim: "#2a2f28"
|
||||
readonly property color outline: "#545c52"
|
||||
|
||||
readonly property color text: "#ccd2cb"
|
||||
readonly property color subtext: "#9fa7a2"
|
||||
readonly property color muted: "#79847a"
|
||||
|
||||
// ------------------------------------------------------------ THE KNOBS
|
||||
// Two colours, two meanings, and nothing else in the shell carries hue.
|
||||
//
|
||||
// `accent` is blue: anything live, focused or selected. `alarm` is mauve:
|
||||
// `accent` is the planet light: anything live, focused or selected. It is
|
||||
// barely a colour at all, which is the point — NieR marks attention with
|
||||
// brightness and inversion, not with hue. `alarm` is the hull's red:
|
||||
// anything destructive, failed or critical. Things that are merely off —
|
||||
// muted, disabled, do-not-disturb — carry no hue at all; see the `Off`
|
||||
// treatment below. Swap either line and everything derived
|
||||
// from it recolours.
|
||||
// muted, disabled, do-not-disturb — stay in the grey ramp; see the `Off`
|
||||
// treatment below.
|
||||
//
|
||||
// Keep them in step with `c.accent` / `c.alarm` in
|
||||
// ~/.config/hypr/lua/palette.lua, which is what colours the Hyprland
|
||||
// window borders. Those are the only places the colours are written.
|
||||
readonly property color accent: "#89b4fa"
|
||||
readonly property color alarm: "#cba6f7"
|
||||
readonly property color accent: "#eef1ea"
|
||||
readonly property color alarm: "#c8684f"
|
||||
|
||||
readonly property color accentDim: "#5a7dc0"
|
||||
readonly property color accentSoft: "#b4befe"
|
||||
readonly property color accentDim: "#8e978d"
|
||||
readonly property color accentSoft: "#bcc1bf"
|
||||
|
||||
// `primary` is the resting voice of the UI, which is now simply white.
|
||||
// Kept under the old name so the existing call sites don't all have to move.
|
||||
// `primary` is the resting voice of the UI — the sage text grey. Kept under
|
||||
// the old name so the existing call sites don't all have to move.
|
||||
readonly property color primary: root.text
|
||||
readonly property color primaryDim: "#9399b2"
|
||||
readonly property color primaryDim: "#8e978d"
|
||||
readonly property color deep: root.surfaceAlt
|
||||
|
||||
// `glow` is the hover highlight. Pointing at a thing lights it up blue —
|
||||
// the same signal as focus, because it is the same statement about where
|
||||
// your attention is.
|
||||
// `glow` is the hover highlight: pointing at a thing brightens it toward
|
||||
// the planet light, the same signal as focus at a lower volume.
|
||||
readonly property color glow: root.accent
|
||||
|
||||
// ------------------------------------------------ semantic treatments
|
||||
// These tokens describe interaction meaning, not new palette entries. Each
|
||||
// state is composed only from crust, the neutral ramp, blue and mauve, so
|
||||
// state is composed only from ink, the grey ramp, the light and the red, so
|
||||
// callers do not invent one-off state colours.
|
||||
readonly property color treatmentRestFill: root.surface
|
||||
readonly property color treatmentRestMark: root.outline
|
||||
readonly property color treatmentRestMark: root.overlay
|
||||
readonly property color treatmentRestText: root.text
|
||||
|
||||
readonly property color treatmentHoverFill: root.surface
|
||||
// Hover lifts the surface a step and brings the marker up to full light.
|
||||
// It never inverts: inversion is the cursor, and the pointer resting on
|
||||
// something is not the same statement as the keyboard choosing it.
|
||||
readonly property color treatmentHoverFill: root.surfaceAlt
|
||||
readonly property color treatmentHoverMark: root.accent
|
||||
readonly property color treatmentHoverText: root.text
|
||||
readonly property color treatmentHoverText: root.accent
|
||||
|
||||
// Focus and selection are an inverted slab: solid blue with crust punched
|
||||
// out of it (9:1). This used to be a white fill, which was right against
|
||||
// Takemi's black but glares as a lavender-white block on Mocha — and it
|
||||
// made "selected" a third look that was neither hover nor accent.
|
||||
// Focus and selection are the NieR cursor: the row inverted, a slab of the
|
||||
// planet light with ink punched out of it.
|
||||
readonly property color treatmentFocusFill: root.accent
|
||||
readonly property color treatmentFocusMark: root.ink
|
||||
readonly property color treatmentFocusText: root.ink
|
||||
@@ -89,16 +97,16 @@ Singleton {
|
||||
readonly property color treatmentSelectedMark: root.treatmentFocusMark
|
||||
readonly property color treatmentSelectedText: root.treatmentFocusText
|
||||
|
||||
readonly property color treatmentActiveFill: root.surface
|
||||
readonly property color treatmentActiveFill: root.surfaceAlt
|
||||
readonly property color treatmentActiveMark: root.accent
|
||||
readonly property color treatmentActiveText: root.text
|
||||
readonly property color treatmentActiveText: root.accent
|
||||
|
||||
// Mauve carries destructive/error meaning — never blue, so a dangerous
|
||||
// Red carries destructive/error meaning — never the light, so a dangerous
|
||||
// button can never be mistaken for a merely focused one.
|
||||
//
|
||||
// At rest it is a keyline and a label, not a fill. The solid mauve is held
|
||||
// At rest it is a hairline and a label, not a fill. The solid red is held
|
||||
// back for the moment the pointer or the selection is actually on the
|
||||
// thing — then it lands hard, with crust punched out of it at 9.1:1.
|
||||
// thing, with ink punched out of it.
|
||||
readonly property color treatmentDestructiveFill: root.surface
|
||||
readonly property color treatmentDestructiveMark: root.alarm
|
||||
readonly property color treatmentDestructiveText: root.alarm
|
||||
@@ -115,12 +123,11 @@ Singleton {
|
||||
readonly property color treatmentUrgentText: root.text
|
||||
|
||||
readonly property color treatmentDisabledFill: root.surface
|
||||
readonly property color treatmentDisabledMark: root.outline
|
||||
readonly property color treatmentDisabledMark: root.overlay
|
||||
readonly property color treatmentDisabledText: root.muted
|
||||
|
||||
// Off is a state the user chose — muted, do-not-disturb, radio switched
|
||||
// off. It is neither live nor wrong, so it gets no hue: painting a muted
|
||||
// speaker blue said "active", and painting it mauve would say "broken".
|
||||
// off. It is neither live nor wrong, so it sinks into the grey ramp.
|
||||
readonly property color treatmentOffFill: root.surface
|
||||
readonly property color treatmentOffMark: root.overlay
|
||||
readonly property color treatmentOffText: root.muted
|
||||
@@ -138,27 +145,30 @@ Singleton {
|
||||
a.a + (b.a - a.a) * k);
|
||||
}
|
||||
|
||||
// Load readouts sit at text until the number actually matters, then climb
|
||||
// through the accent before they reach the alarm. Going straight from text
|
||||
// to mauve passes through a washed-out mid-tone that reads as a faded red
|
||||
// rather than as a rising number; routing through blue keeps every step of
|
||||
// the ramp a colour the shell already uses.
|
||||
// Load readouts sit at text until the number actually matters, brighten
|
||||
// toward the light, and only then warm into the red. Every step of the ramp
|
||||
// is a colour the shell already uses.
|
||||
function heat(pct: real): color {
|
||||
if (pct <= 45) return root.text;
|
||||
if (pct <= 75) return root.mix(root.text, root.accent, (pct - 45) / 30);
|
||||
return root.mix(root.accent, root.alarm, (pct - 75) / 25);
|
||||
if (pct <= 55) return root.text;
|
||||
if (pct <= 80) return root.mix(root.text, root.accent, (pct - 55) / 25);
|
||||
return root.mix(root.accent, root.alarm, (pct - 80) / 20);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------- fonts
|
||||
readonly property string fontDisplay: "Archivo Black"
|
||||
// NieR sets its UI in FOT-Rodin, a plain Japanese gothic, upright and
|
||||
// widely tracked. Noto Sans is the closest free face that is already on
|
||||
// the machine. Display text is never italic and never heavy; the wide
|
||||
// tracking is what makes it read as a heading.
|
||||
readonly property string fontDisplay: "Noto Sans"
|
||||
readonly property string fontMono: "JetBrainsMono Nerd Font"
|
||||
readonly property string fontIcon: "JetBrainsMono Nerd Font"
|
||||
|
||||
readonly property int weightDisplay: Font.Black
|
||||
readonly property int weightBody: Font.Medium
|
||||
readonly property int weightDisplay: Font.Medium
|
||||
readonly property int weightBody: Font.Normal
|
||||
|
||||
// Letter-spacing for uppercase labels and headings.
|
||||
readonly property real tracking: 2.5
|
||||
|
||||
// Nothing in the shell renders below this. 9px mono was legible on
|
||||
// crimson-on-black; on Mocha's lower-contrast ramp it was not.
|
||||
readonly property int fsMicro: 10
|
||||
readonly property int fsSmall: 11
|
||||
readonly property int fsBody: 12
|
||||
@@ -170,27 +180,32 @@ Singleton {
|
||||
readonly property int fsRailIcon: 17
|
||||
|
||||
// -------------------------------------------------------------- geometry
|
||||
// The hull. The bar along the top, the rail down the right and a thin band
|
||||
// down the left and along the bottom are one continuous surface, and the
|
||||
// desktop is the rounded opening cut out of it — the porthole the
|
||||
// wallpaper is looking through. `frame` is the band's thickness where
|
||||
// there is no bar or rail, `frameRadius` the opening's corner.
|
||||
readonly property int barHeight: 40
|
||||
readonly property int barMargin: 8
|
||||
readonly property int barGap: 8
|
||||
|
||||
// The right-hand rail uses the same lean and chamfer as the bar — a
|
||||
// vertical panel leans its horizontal edges by a fraction of its width,
|
||||
// which works out to the same 14 degrees.
|
||||
readonly property int railWidth: 48
|
||||
readonly property int frame: 8
|
||||
readonly property int frameRadius: 18
|
||||
|
||||
// ONE angle, everywhere. tan(14deg). Persona geometry is disciplined, not
|
||||
// random: every edge in the shell leans by exactly this much in exactly the
|
||||
// same direction, and every corner is chopped by exactly `cut`. Varying
|
||||
// these per module reads as noise, not as style.
|
||||
readonly property real skew: 0.249
|
||||
readonly property int cut: 10
|
||||
readonly property int stroke: 2
|
||||
// Nothing leans and nothing is chopped. NieR panels are plain rectangles;
|
||||
// their character comes from hairlines, square markers and corner ticks.
|
||||
// Both knobs are kept so the shape code still has one place to ask.
|
||||
readonly property real skew: 0
|
||||
readonly property int cut: 0
|
||||
readonly property int stroke: 1
|
||||
|
||||
// Crust keyline and offset copy behind panels. This is the one piece of
|
||||
// layering the style needs; it is not a soft shadow and never blurs.
|
||||
readonly property real dropOffset: 3
|
||||
readonly property real keylineWidth: 2
|
||||
// No printed drop and no ink contour: on a dark ground they only thicken
|
||||
// the edge. The shadow under display text is the one offset left.
|
||||
readonly property real dropOffset: 0
|
||||
readonly property real keylineWidth: 0
|
||||
|
||||
// The square bullet that marks the current row, and the length of the
|
||||
// corner ticks that frame a panel.
|
||||
readonly property int marker: 6
|
||||
readonly property int tick: 8
|
||||
|
||||
readonly property int padS: 6
|
||||
readonly property int padM: 12
|
||||
@@ -201,24 +216,27 @@ Singleton {
|
||||
readonly property int popoutGap: 10
|
||||
|
||||
// ------------------------------------------------------------ animation
|
||||
// P5 motion is snappy and slightly overshooting — never soft.
|
||||
readonly property int durFast: 110
|
||||
readonly property int durBase: 190
|
||||
readonly property int durSlow: 340
|
||||
readonly property int durLazy: 620
|
||||
// NieR motion is calm and mechanical: things glide in and settle, they
|
||||
// never bounce.
|
||||
readonly property int durFast: 120
|
||||
readonly property int durBase: 220
|
||||
readonly property int durSlow: 380
|
||||
readonly property int durLazy: 700
|
||||
|
||||
readonly property var easeSnap: [0.16, 1.0, 0.3, 1.0, 1, 1] // outExpo-ish
|
||||
readonly property var easeBack: [0.34, 1.56, 0.64, 1.0, 1, 1] // overshoot
|
||||
readonly property var easeSnap: [0.22, 1.0, 0.36, 1.0, 1, 1] // outQuint
|
||||
readonly property var easeGlide: [0.4, 0.0, 0.2, 1.0, 1, 1] // standard
|
||||
readonly property var easeIn: [0.55, 0.0, 0.9, 0.35, 1, 1]
|
||||
|
||||
// -------------------------------------------------------------- textures
|
||||
readonly property url texHalftone: "root:/assets/halftone.png"
|
||||
readonly property url texStripes: "root:/assets/stripes.png"
|
||||
// A 1px dot every 8px, and a 32px hairline grid — the two backgrounds the
|
||||
// NieR menus are printed on.
|
||||
readonly property url texDots: "root:/assets/dots.png"
|
||||
readonly property url texGrid: "root:/assets/grid.png"
|
||||
readonly property url texScanline: "root:/assets/scanline.png"
|
||||
|
||||
// Last resort only. The live wallpaper comes from the Wallpaper singleton,
|
||||
// which asks hyprpaper what is actually on screen — a path written down
|
||||
// here goes stale the moment the wallpaper is switched, which is exactly
|
||||
// what happened to the lock screen.
|
||||
readonly property url fallbackWallpaper: "file:///home/narl/.wallpapers/arch.png"
|
||||
readonly property url fallbackWallpaper: "file:///home/narl/.wallpapers/space-1.jpg"
|
||||
}
|
||||
@@ -527,7 +527,7 @@ PanelWindow {
|
||||
}
|
||||
NumberAnimation {
|
||||
target: rise; property: "y"
|
||||
from: 24; to: 0; duration: Theme.durSlow; easing.type: Easing.OutBack
|
||||
from: 24; to: 0; duration: Theme.durSlow; easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ Item {
|
||||
color: Theme.accent
|
||||
|
||||
Behavior on height {
|
||||
NumberAnimation { duration: Theme.durFast; easing.type: Easing.OutBack }
|
||||
NumberAnimation { duration: Theme.durFast; easing.type: Easing.OutCubic }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ Item {
|
||||
reveal: 0
|
||||
wedgeSpan: 0.30
|
||||
wedgeOpacity: 0.30
|
||||
stripeOpacity: 0.07
|
||||
stripeOpacity: 0.04
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------ clock
|
||||
@@ -84,17 +84,14 @@ Item {
|
||||
precision: SystemClock.Minutes
|
||||
}
|
||||
|
||||
// The house mark, same wordmark the bar carries far left. Small, above the
|
||||
// clock — the lock's hero is the time, not the branding.
|
||||
SplitText {
|
||||
// The house mark, the same porthole the bar carries far left. Small, above
|
||||
// the clock — the lock's hero is the time, not the branding.
|
||||
Porthole {
|
||||
id: mark
|
||||
anchors.left: timeBlock.left
|
||||
anchors.bottom: timeBlock.top
|
||||
anchors.bottomMargin: 6
|
||||
text: "P5"
|
||||
pixelSize: Theme.fsTitle
|
||||
split: 2
|
||||
letterSpacing: 0
|
||||
anchors.bottomMargin: 10
|
||||
size: 28
|
||||
opacity: timeBlock.opacity
|
||||
}
|
||||
|
||||
@@ -110,7 +107,6 @@ Item {
|
||||
text: Qt.formatDateTime(clock.date, "HH")
|
||||
pixelSize: Theme.fsMega * 1.7
|
||||
split: 5
|
||||
splitOpacity: 0.85
|
||||
}
|
||||
|
||||
SplitText {
|
||||
@@ -118,7 +114,6 @@ Item {
|
||||
pixelSize: Theme.fsMega * 1.7
|
||||
color: Theme.primary
|
||||
split: 5
|
||||
splitOpacity: 0.6
|
||||
}
|
||||
|
||||
Text {
|
||||
@@ -214,8 +209,6 @@ Item {
|
||||
anchors.topMargin: Theme.padL
|
||||
width: Math.min(380, authBlock.width - Theme.padL * 2)
|
||||
height: 56
|
||||
lean: 0.12
|
||||
chop: 16
|
||||
fill: Theme.mantle
|
||||
fillOpacity: 0.94
|
||||
border: surface.failed
|
||||
@@ -251,7 +244,7 @@ Item {
|
||||
property: "scale"
|
||||
from: 0.2; to: 1
|
||||
duration: Theme.durBase
|
||||
easing.type: Easing.OutBack
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -399,7 +392,7 @@ Item {
|
||||
}
|
||||
NumberAnimation {
|
||||
target: shakeShift; property: "x"
|
||||
to: 0; duration: 90; easing.type: Easing.OutBack
|
||||
to: 0; duration: 90; easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
@@ -424,7 +417,7 @@ Item {
|
||||
}
|
||||
NumberAnimation {
|
||||
target: shakeShift; property: "y"
|
||||
from: 40; to: 0; duration: Theme.durLazy; easing.type: Easing.OutBack
|
||||
from: 40; to: 0; duration: Theme.durLazy; easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,6 @@ Item {
|
||||
elide: Text.ElideRight
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsSmall
|
||||
font.italic: true
|
||||
font.weight: Font.DemiBold
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
@@ -111,8 +111,6 @@ PanelWindow {
|
||||
slash: true
|
||||
slashColor: root.tone
|
||||
slashWidth: 5
|
||||
lean: 0.09
|
||||
chop: 14
|
||||
padding: Theme.padM
|
||||
|
||||
opacity: root.shown ? 1 : 0
|
||||
@@ -122,7 +120,7 @@ PanelWindow {
|
||||
NumberAnimation { id: fade; duration: Theme.durBase }
|
||||
}
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: Theme.durSlow; easing.type: Easing.OutBack }
|
||||
NumberAnimation { duration: Theme.durSlow; easing.type: Easing.OutCubic }
|
||||
}
|
||||
|
||||
Icon {
|
||||
|
||||
@@ -75,14 +75,12 @@ PanelWindow {
|
||||
}
|
||||
}
|
||||
|
||||
// Stripes and wedge, shared with the lock screen. The wedge used to lean at
|
||||
// 0.32 here, which was its own angle and nothing else's; P5Backdrop leans
|
||||
// it at Theme.skew like every other edge in the shell.
|
||||
// Grid and column, shared with the lock screen.
|
||||
P5Backdrop {
|
||||
id: ground
|
||||
anchors.fill: parent
|
||||
reveal: 0
|
||||
stripeOpacity: 0.10
|
||||
stripeOpacity: 0.05
|
||||
wedgeOpacity: 0.35
|
||||
wedgeSpan: 0.34
|
||||
// The live desktop is still visible behind this, so a dot wash would be
|
||||
@@ -102,29 +100,26 @@ PanelWindow {
|
||||
opacity: 0
|
||||
|
||||
SplitText {
|
||||
text: "TAKE"
|
||||
text: "GLORY"
|
||||
pixelSize: Theme.fsMega
|
||||
split: 4
|
||||
splitOpacity: 0.9
|
||||
}
|
||||
|
||||
SplitText {
|
||||
text: "YOUR"
|
||||
text: "TO"
|
||||
pixelSize: Theme.fsMega
|
||||
color: Theme.accent
|
||||
split: 4
|
||||
splitOpacity: 0.5
|
||||
}
|
||||
|
||||
SplitText {
|
||||
text: "TIME."
|
||||
text: "MANKIND."
|
||||
pixelSize: Theme.fsMega
|
||||
split: 4
|
||||
splitOpacity: 0.9
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "— TAE TAKEMI"
|
||||
text: "— YORHA"
|
||||
color: Theme.primary
|
||||
font.family: Theme.fontMono
|
||||
font.pixelSize: Theme.fsSmall
|
||||
@@ -212,7 +207,7 @@ PanelWindow {
|
||||
target: slide; property: "x"
|
||||
from: 90; to: 0
|
||||
duration: Theme.durSlow
|
||||
easing.type: Easing.OutBack
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
// Slabs land out of true and snap square. Sliding alone
|
||||
// reads like a slide deck; the tilt is what makes it
|
||||
@@ -223,7 +218,7 @@ PanelWindow {
|
||||
target: tilt; property: "angle"
|
||||
from: -3; to: 0
|
||||
duration: Theme.durSlow
|
||||
easing.type: Easing.OutBack
|
||||
easing.type: Easing.OutCubic
|
||||
easing.overshoot: 2.2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ PanelWindow {
|
||||
|
||||
anchors { top: true; right: true }
|
||||
margins {
|
||||
top: Theme.barHeight + Theme.barMargin * 2
|
||||
right: Theme.barMargin
|
||||
top: Theme.barHeight + Theme.frame
|
||||
right: Theme.railWidth + Theme.frame
|
||||
}
|
||||
|
||||
implicitWidth: 400
|
||||
@@ -115,7 +115,7 @@ PanelWindow {
|
||||
onFinished: root.retire(toast.modelData)
|
||||
}
|
||||
|
||||
// Slide in from the right, Persona-style.
|
||||
// Slide in from the right.
|
||||
opacity: 0
|
||||
transform: Translate { id: shove; x: 60 }
|
||||
|
||||
@@ -135,7 +135,7 @@ PanelWindow {
|
||||
target: shove; property: "x"
|
||||
from: 60; to: 0
|
||||
duration: Theme.durSlow
|
||||
easing.type: Easing.OutBack
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ Item {
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsSmall
|
||||
font.weight: Font.DemiBold
|
||||
font.italic: true
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ Item {
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsHuge
|
||||
font.weight: Theme.weightDisplay
|
||||
font.italic: true
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
@@ -45,7 +44,6 @@ Item {
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsSmall
|
||||
font.weight: Font.DemiBold
|
||||
font.italic: true
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
|
||||
@@ -163,7 +163,6 @@ Popout {
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsSmall
|
||||
font.weight: Font.DemiBold
|
||||
font.italic: true
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
|
||||
@@ -145,8 +145,7 @@ Popout {
|
||||
}
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsSmall
|
||||
font.italic: true
|
||||
font.weight: cell.modelData.today ? Font.Black : Font.Medium
|
||||
font.weight: cell.modelData.today ? Font.DemiBold : Font.Medium
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,8 +123,7 @@ Popout {
|
||||
color: Theme.text
|
||||
pixelSize: Theme.fsLarge
|
||||
family: Theme.fontDisplay
|
||||
weight: Font.Black
|
||||
italic: true
|
||||
weight: Font.DemiBold
|
||||
}
|
||||
|
||||
Marquee {
|
||||
@@ -134,7 +133,6 @@ Popout {
|
||||
color: Theme.primary
|
||||
pixelSize: Theme.fsSmall
|
||||
family: Theme.fontDisplay
|
||||
italic: true
|
||||
weight: Font.DemiBold
|
||||
}
|
||||
|
||||
@@ -359,7 +357,7 @@ Popout {
|
||||
color: {
|
||||
if (!tb.enabled) return Theme.alpha(Theme.muted, 0.5);
|
||||
if (tb.activeFocus) return Theme.treatmentFocusText;
|
||||
// Ink on the accent slab. White on light blue was barely 2:1.
|
||||
// Ink on the accent slab, for contrast.
|
||||
if (tbHover.hovered && tb.primary) return Theme.ink;
|
||||
return Theme.text;
|
||||
}
|
||||
@@ -367,7 +365,7 @@ Popout {
|
||||
|
||||
scale: tbHover.hovered && tb.enabled ? 1.12 : 1.0
|
||||
Behavior on scale {
|
||||
NumberAnimation { duration: Theme.durBase; easing.type: Easing.OutBack }
|
||||
NumberAnimation { duration: Theme.durBase; easing.type: Easing.OutCubic }
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
|
||||
@@ -56,8 +56,7 @@ Popout {
|
||||
color: Theme.muted
|
||||
font.family: Theme.fontDisplay
|
||||
font.pixelSize: Theme.fsBody
|
||||
font.italic: true
|
||||
font.weight: Font.Black
|
||||
font.weight: Font.DemiBold
|
||||
font.letterSpacing: 3
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
@@ -84,7 +83,7 @@ Popout {
|
||||
properties: "x"
|
||||
from: 40
|
||||
duration: Theme.durSlow
|
||||
easing.type: Easing.OutBack
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
|
||||
@@ -2,8 +2,8 @@ import QtQuick
|
||||
import "root:/config"
|
||||
import "root:/components"
|
||||
|
||||
// Title bar for a popout: glyph, print-shadowed heading, right-aligned status
|
||||
// text, and a rule with a chopped accent tail.
|
||||
// Title bar for a popout, in the NieR header pattern: glyph, tracked heading,
|
||||
// right-aligned status text, and a hairline rule that ends in a square.
|
||||
Item {
|
||||
id: root
|
||||
|
||||
@@ -31,7 +31,6 @@ Item {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: root.title.toUpperCase()
|
||||
pixelSize: Theme.fsLarge
|
||||
letterSpacing: 1.5
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,19 +49,19 @@ Item {
|
||||
|
||||
Rectangle {
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: (Theme.marker - 1) / 2
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 22
|
||||
height: 2
|
||||
color: Theme.alpha(root.accent, 0.8)
|
||||
anchors.right: endMark.left
|
||||
height: 1
|
||||
color: Theme.alpha(root.accent, 0.6)
|
||||
}
|
||||
|
||||
Skew {
|
||||
Rectangle {
|
||||
id: endMark
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
width: 16
|
||||
height: 2
|
||||
width: Theme.marker
|
||||
height: Theme.marker
|
||||
color: Theme.accent
|
||||
lean: 1.4
|
||||
}
|
||||
}
|
||||
@@ -10,20 +10,14 @@ P5Panel {
|
||||
|
||||
fill: Theme.mantle
|
||||
fillOpacity: 0.97
|
||||
// A neutral keyline. `tone` used to colour the whole border at 75%, and
|
||||
// since most panels pass the resting text colour that put a pale 2px frame
|
||||
// around every popout — the loudest thing on screen for no reason. The
|
||||
// tone lives in the slash now; the frame is structure.
|
||||
// The frame is structure: a neutral hairline. The tone goes into the
|
||||
// corner ticks, which is where NieR puts the one bright mark on a panel.
|
||||
border: Theme.surfaceAlt
|
||||
borderWidth: Theme.stroke
|
||||
halftone: textured
|
||||
halftoneColor: tone
|
||||
halftoneOpacity: 0.06
|
||||
sheen: true
|
||||
slash: true
|
||||
slashColor: tone
|
||||
slashWidth: 5
|
||||
lean: 0.06
|
||||
chop: 16
|
||||
ticks: true
|
||||
tickColor: tone
|
||||
padding: Theme.padM
|
||||
}
|
||||
@@ -29,7 +29,7 @@ PopupWindow {
|
||||
// The slab's own lean and padding, which the entries sit inside. Sizing the
|
||||
// window to the entry widths alone left every label short by that inset and
|
||||
// elided perfectly ordinary items.
|
||||
readonly property real slabLean: 0.06
|
||||
readonly property real slabLean: Theme.skew
|
||||
readonly property real slabPad: Theme.padS
|
||||
|
||||
readonly property real contentHeight: list.implicitHeight + slabPad * 2
|
||||
@@ -114,7 +114,6 @@ PopupWindow {
|
||||
anchors.fill: parent
|
||||
tone: Theme.accent
|
||||
padding: root.slabPad
|
||||
chop: 12
|
||||
lean: root.slabLean
|
||||
|
||||
TrayMenuList {
|
||||
@@ -139,12 +138,12 @@ PopupWindow {
|
||||
}
|
||||
NumberAnimation {
|
||||
target: holder; property: "scale"
|
||||
to: 1.0; duration: Theme.durSlow; easing.type: Easing.OutBack
|
||||
to: 1.0; duration: Theme.durSlow; easing.type: Easing.OutCubic
|
||||
}
|
||||
NumberAnimation {
|
||||
target: holder; property: "x"
|
||||
from: root.bleed + 14; to: root.bleed
|
||||
duration: Theme.durSlow; easing.type: Easing.OutBack
|
||||
duration: Theme.durSlow; easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,19 +84,12 @@ Column {
|
||||
width: root.width
|
||||
|
||||
// ------------------------------------------------------ separator
|
||||
//
|
||||
// A horizontal rule slants by a fraction of its own width, so at
|
||||
// menu width the house lean turns a hairline into a 30px diagonal
|
||||
// gash straight across the entries above and below it. The rise is
|
||||
// pinned in pixels instead, matching the rail's dividers.
|
||||
Skew {
|
||||
Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: row.entry.isSeparator
|
||||
width: parent.width - Theme.padM * 2
|
||||
x: Theme.padM
|
||||
height: 1
|
||||
vertical: true
|
||||
lean: width > 0 ? 5 / width : 0
|
||||
color: Theme.alpha(Theme.outline, 0.9)
|
||||
}
|
||||
|
||||
@@ -226,20 +219,12 @@ Column {
|
||||
NumberAnimation { duration: Theme.durFast; easing.type: Easing.OutExpo }
|
||||
}
|
||||
|
||||
// The guide rule down the side of an expanded submenu.
|
||||
//
|
||||
// Same trap the separators hit, from the other direction: the
|
||||
// house lean is a fraction of *height*, and this rule is as tall
|
||||
// as the submenu. A Wi-Fi list of thirty networks made it 600px
|
||||
// tall, which sheared a 1px hairline into a 150px crimson wedge
|
||||
// lying across every entry in the list. The rise is pinned in
|
||||
// pixels, and it is declared before the entries so it can never
|
||||
// paint over them again.
|
||||
Skew {
|
||||
// The guide rule down the side of an expanded submenu,
|
||||
// declared before the entries so it can never paint over them.
|
||||
Rectangle {
|
||||
x: Theme.padS
|
||||
width: 1
|
||||
height: parent.height
|
||||
lean: height > 0 ? 5 / height : 0
|
||||
visible: row.expanded
|
||||
color: Theme.alpha(Theme.accent, 0.8)
|
||||
}
|
||||
|
||||
@@ -8,9 +8,10 @@ import "root:/ask"
|
||||
import "root:/overlays"
|
||||
import "root:/lock"
|
||||
|
||||
// Takemi — a Persona 5 flavoured Quickshell desktop.
|
||||
// Takemi — a YoRHa-dark Quickshell desktop: NieR:Automata's interface
|
||||
// language, lit like the wallpaper.
|
||||
//
|
||||
// bar/ the top bar and its modules
|
||||
// bar/ the hull, the top bar, the rail and their modules
|
||||
// popouts/ hover panels hanging off bar modules
|
||||
// launcher/ the application launcher
|
||||
// ask/ the question panel, dropped from the top edge
|
||||
@@ -35,6 +36,12 @@ ShellRoot {
|
||||
void Apps.index;
|
||||
}
|
||||
|
||||
Variants {
|
||||
model: Quickshell.screens
|
||||
|
||||
Frame {}
|
||||
}
|
||||
|
||||
Variants {
|
||||
model: Quickshell.screens
|
||||
|
||||
|
||||
Reference in new issue
Block a user