/* Manjaro i3 desktop layer.
 *
 * Everything the window manager draws lives here; site.css keeps the site's
 * appearance and is left alone. All window-manager geometry is scoped under
 * html.wm-active, which is added only after a successful synchronous boot, so
 * "no JavaScript" and "the window manager threw" both collapse into the single
 * fallback selector html:not(.wm-active).
 *
 * No new colours: every value below is a theme token or a legacy alias from
 * site.css's generated :root block; the stacking order lives there too.
 */

:root {
  --wm-tab-height: 23px;
  --wm-stack-row: 23px;
  --wm-grip: 6px;
  /* feh's wallpapers, in theme surfaces: the ember glow is chrome-alt fading
     through chrome, the ridge is the marquee tint ruled over a raised ground. */
  --wallpaper-ember: radial-gradient(130% 95% at 50% 0%, var(--chrome-alt) 0%, var(--chrome) 48%, var(--desktop) 100%);
  --wallpaper-ridge:
    repeating-linear-gradient(180deg, var(--color-interaction-marquee) 0 2px, transparent 2px 88px),
    radial-gradient(120% 100% at 18% 0%, var(--surface-raised) 0%, var(--chrome) 55%, var(--desktop) 100%);
}

/* ---------------------------------------------------------------- wallpaper */

.wallpaper {
  position: fixed;
  z-index: -1;
  inset: 0;
  background: var(--desktop);
  pointer-events: none;
}

html[data-wallpaper="ember"] .wallpaper { background: var(--wallpaper-ember); }
html[data-wallpaper="ridge"] .wallpaper { background: var(--wallpaper-ridge); }

/* The desktop wordmark, set in a 4 KB bold face that holds exactly these six
   characters (see scripts/lib/fonts.mjs). */
.wallpaper::after {
  position: absolute;
  z-index: 0;
  top: 50%;
  left: 50%;
  color: var(--foreground-bright);
  content: "j3w1-i3";
  font-family: var(--font);
  font-size: clamp(34px, 9vmin, 104px);
  font-weight: 700;
  letter-spacing: 0.02em;
  opacity: 0.22;
  transform: translate(-50%, -50%);
  white-space: nowrap;
}

/* A centred wordmark on an otherwise empty desktop competes with nothing, so
   raised contrast should make it clearer rather than erase it. The opacity:0
   here was inherited from a full-bleed background texture that genuinely did
   compete with the text sitting on top of it. */
@media (prefers-contrast: more) {
  .wallpaper::after { opacity: 0.42; }
}

/* Forced colours replace `color` with the system palette, which painted the
   wordmark in the same ink as the canvas behind it — invisible. Ask for the
   system text colour explicitly. */
@media (forced-colors: active) {
  .wallpaper::after {
    color: CanvasText;
    opacity: 0.55;
  }

  .wm-tab.is-active,
  #power-menu-toggle[aria-expanded="true"] {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }

  .wm-confocus {
    border-color: Highlight;
  }
}

/* ------------------------------------------------------------ tiling layout */

.workspace-layer {
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
}

/* The wallpaper sits at z-index -1, which paints above the canvas but *below*
   block backgrounds — so an opaque body would hide it and the wordmark with it.
   html keeps the black; body gets out of the way. */
html.wm-active body,
html.wm-active .desktop-shell,
html.wm-active .workspace {
  background: transparent;
}

html.wm-active .workspace-layer {
  position: relative;
  display: block;
  overflow: hidden;
}

html.wm-active .window {
  position: absolute;
  margin: 0;
  contain: layout paint;
}

/* These used to be grid cells inside a larger application window. As direct
   children of a window's flex column they now have to claim the free space
   themselves. */
html.wm-active .content-index,
html.wm-active .content-reader,
html.wm-active .project-table-pane,
html.wm-active .project-detail-pane {
  min-width: 0;
  min-height: 0;
  flex: 1 1 auto;
}

html.wm-active .project-table-pane { border-bottom: 0; }

/* Both browsers lost their third column when the reader became its own window. */
html.wm-active .photography-body,
html.wm-active .library-body {
  display: grid;
  grid-template-columns: 170px minmax(0, 1fr);
}

html.wm-active .wm-deco {
  position: absolute;
  z-index: var(--wm-z-deco);
  inset: 0;
  pointer-events: none;
}

html.wm-active .wm-tabbar,
html.wm-active .wm-grip,
html.wm-active .wm-drag-ghost {
  pointer-events: auto;
}

/* Title bars, tabs and grips are chrome, not prose. Selection has to be off
   before the pointer goes down: switching it off once a drag commits still lets
   the first few pixels highlight the title, which instantly reads as a web page
   rather than a window manager. */
html.wm-active .window-titlebar,
html.wm-active .wm-tabbar,
html.wm-active .wm-grips,
html.wm-active .window-marks {
  user-select: none;
}

html.wm-dragging,
html.wm-dragging * {
  user-select: none;
}

/* ------------------------------------------------------- tabs and stack rows */

.wm-tabbar {
  position: absolute;
  display: block;
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--chrome);
}

.wm-tab {
  position: absolute;
  display: flex;
  overflow: hidden;
  align-items: center;
  padding: 0 8px;
  border: 0;
  border-right: 1px solid var(--border);
  background: var(--chrome);
  color: var(--muted);
  font: inherit;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wm-tabbar-stacked .wm-tab {
  border-bottom: 1px solid var(--border);
  border-right: 0;
}

.wm-tab:hover { background: var(--chrome-alt); }

.wm-tab.is-active {
  background: var(--selection);
  color: var(--prose);
}

.wm-tab:focus-visible {
  outline: var(--focus-ring);
  outline-offset: -3px;
}

/* ------------------------------------------------- floating grips and ghost */

.wm-grips {
  position: absolute;
  pointer-events: none;
}

.wm-grip {
  position: absolute;
  pointer-events: auto;
}

.wm-grip-n, .wm-grip-s { left: var(--wm-grip); width: calc(100% - var(--wm-grip) * 2); height: var(--wm-grip); cursor: ns-resize; }
.wm-grip-e, .wm-grip-w { top: var(--wm-grip); width: var(--wm-grip); height: calc(100% - var(--wm-grip) * 2); cursor: ew-resize; }
.wm-grip-n { top: calc(var(--wm-grip) * -1); }
.wm-grip-s { bottom: calc(var(--wm-grip) * -1); }
.wm-grip-w { left: calc(var(--wm-grip) * -1); }
.wm-grip-e { right: calc(var(--wm-grip) * -1); }
.wm-grip-ne, .wm-grip-nw, .wm-grip-se, .wm-grip-sw { width: calc(var(--wm-grip) * 2); height: calc(var(--wm-grip) * 2); }
.wm-grip-nw { top: calc(var(--wm-grip) * -1); left: calc(var(--wm-grip) * -1); cursor: nwse-resize; }
.wm-grip-se { right: calc(var(--wm-grip) * -1); bottom: calc(var(--wm-grip) * -1); cursor: nwse-resize; }
.wm-grip-ne { top: calc(var(--wm-grip) * -1); right: calc(var(--wm-grip) * -1); cursor: nesw-resize; }
.wm-grip-sw { bottom: calc(var(--wm-grip) * -1); left: calc(var(--wm-grip) * -1); cursor: nesw-resize; }

.wm-drag-ghost {
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
  border: 1px dashed var(--focus);
  background: var(--color-interaction-marquee);
  pointer-events: none;
}

html.wm-active .window.is-floating {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-floating);
}

/* ----------------------------------------------- real title bar controls */

.window-mark {
  display: inline-flex;
  width: 20px;
  height: 18px;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: var(--quiet);
  font: inherit;
  line-height: 1;
}

.window-mark:hover,
.window-mark:focus-visible {
  background: var(--selection-dark);
  color: var(--prose);
}

.window-mark-close:hover,
.window-mark-close:focus-visible { background: var(--selection); }

.window-marks { display: inline-flex; gap: 1px; letter-spacing: normal; }

/* ------------------------------------------------------------ empty desktop */

/* Sits above centre so it does not land on top of the desktop wordmark. */
.wm-empty {
  position: absolute;
  top: 32%;
  left: 50%;
  width: min(30rem, calc(100% - 2rem));
  padding: 16px;
  border: 1px solid var(--color-border-divider);
  background: var(--surface);
  color: var(--muted);
  text-align: center;
  transform: translate(-50%, -50%);
}

.wm-empty p { margin: 0 0 10px; }
.wm-empty p:last-child { margin-bottom: 0; }
.wm-empty-title { color: var(--foreground-bright); }

.wm-restore {
  min-height: 32px;
  padding: 0 14px;
  border: 1px solid var(--border-strong);
  background: var(--surface-raised);
  color: var(--foreground-bright);
}

.wm-restore:hover,
.wm-restore:focus-visible { background: var(--selection-dark); color: var(--prose); }

/* --------------------------------------------------------------- i3 status */

/* The workspace names are the navigation and must never be clipped, so the
   status blocks are the flex item that gives way when the bar runs out of room. */
.i3status {
  display: flex;
  min-width: 0;
  height: 100%;
  flex: 0 1 auto;
  align-items: center;
  margin-left: auto;
  overflow: hidden;
}

/* The container and its blocks share one background, or the strip reads as two
   mismatched panels. Every block carries its own divider rather than only the
   first: which block is leftmost changes with the viewport as blocks are shed,
   and a divider pinned to the first would end up drawn on a hidden one. */
.i3block {
  display: inline-flex;
  height: 100%;
  align-items: center;
  gap: 5px;
  padding: 0 8px;
  border-left: 1px solid var(--border-strong);
  background: var(--chrome-alt);
  color: var(--color7);
  white-space: nowrap;
}

/* i3status colours from the config: good #FFA2A7 (color7), degraded #C81A1A
   (color1 — 3.4:1, so the degraded glyph is color5 instead), and the glyphs
   themselves sit at the decorative floor in color15. */
.i3block-glyph { color: var(--color15); }
.i3block-label { color: var(--color2); }
.i3block-label:empty { display: none; }
.i3block.is-degraded .i3block-glyph { color: var(--color5); }
.i3block-glyph:empty { display: none; }

/* Below 768px the strip scrolls instead, so the tray stays reachable. */
@media (min-width: 768px) {
  html.wm-active .workspace-strip { flex: 0 0 auto; }
}


/* binding_mode: the config wanted fg on color1, which is 2.5:1 — so color7
   with color0 text, the same shape at a readable contrast. */
.wm-mode {
  display: inline-flex;
  align-items: center;
  padding: 0 9px;
  border-bottom: 2px solid var(--color1);
  background: var(--color7);
  color: var(--color0);
  white-space: nowrap;
}

/* bar mode hide: the bar slides away and the desktop takes the full height.
   It comes back on hover at the top edge, while a binding mode is active, and
   whenever anything inside it has focus — it never leaves the Tab order. */
html[data-bar="hide"] .wm-bar {
  position: fixed;
  z-index: var(--wm-z-dunst);
  top: 0;
  right: 0;
  left: 0;
  transform: translateY(-100%);
  transition: transform 120ms ease-out;
}

html[data-bar="hide"] .wm-bar:hover,
html[data-bar="hide"] .wm-bar:focus-within,
html[data-bar="hide"].wm-mode-active .wm-bar,
html[data-bar="hide"] .wm-bar-reveal:hover + .wm-bar {
  transform: translateY(0);
}

html[data-bar="hide"] .wm-bar-reveal {
  position: fixed;
  z-index: var(--wm-z-dunst);
  top: 0;
  right: 0;
  left: 0;
  height: 6px;
}

html[data-bar="hide"] .desktop-shell {
  height: 100dvh;
}

@media (prefers-reduced-motion: reduce) {
  html[data-bar="hide"] .wm-bar { transition: none; }
}

/* j3w1ctl lives in the file manager's Network section now, so the anchor-shaped
   .place-row has to accept a real <button> too. */
button.place-row {
  width: 100%;
  border: 0;
  background: transparent;
  cursor: pointer;
  font: inherit;
  text-align: left;
}


button.place-row:disabled { color: var(--inactive); cursor: default; }

/* The tray buttons were reading as one control: give each its own breathing
   room, a stronger divider, and space between glyph and label. */
html.wm-active .system-status > *,
html.wm-active .status-control {
  gap: 7px;
  padding-inline: 11px;
  border-left-color: var(--border-strong);
}

html.wm-active #power-menu-toggle[aria-expanded="true"] {
  background: var(--selection);
  color: var(--prose);
}

/* urgent_workspace from the config: border color0, background fg, text color0. */
.workspace-link.is-urgent { background: var(--foreground); color: var(--color0); }
.workspace-link.is-urgent::after { margin-left: 4px; content: "!"; }

/* conky: own_window_transparent in the config, over a wallpaper. Here it can
   float over windows, so it keeps a translucent ground rather than bleeding
   the window beneath through its figures. */
html.wm-active .conky-window { background: var(--color-surface-backdrop); border-color: transparent; }
.conky-window .app-statusline { display: none; }
/* The conkyrc's rules and labels were #AE1914, a heritage-only value; color1
   is the nearest approved role. */
.conky { padding: 14px 16px; color: var(--foreground); font-size: var(--font-size-caption); line-height: 1.5; }
.conky p { margin: 0; }
.conky-date { padding-bottom: 8px; border-bottom: 1px solid var(--color1); margin-bottom: 14px; text-align: right; }
.conky-weekday { color: var(--color1); font-size: var(--font-size-h2); }
.conky-day { font-size: 38px; line-height: 1; }
.conky-month { color: var(--color1); font-size: 18px; }
.conky-year { font-size: var(--font-size-h1); }
.conky-row { display: flex; justify-content: space-between; gap: 12px; padding-left: 24px; }
.conky-label { color: var(--color1); }
.conky-strong { color: var(--foreground); font-weight: 700; }
.conky-value { color: var(--foreground); }
.conky-sections { display: flex; flex-direction: column; gap: 2px; }
.conky-foot { margin-top: 14px; text-align: right; }
.conky-foot .conky-row { justify-content: flex-end; padding-left: 0; }

/* focus parent: client.focused_inactive's color6 around the focused container. */
.wm-confocus {
  position: absolute;
  z-index: var(--wm-z-deco);
  box-sizing: border-box;
  border: 2px solid var(--color6);
  pointer-events: none;
}

/* i3 shows a window's marks in its title bar. */
.window-titlebar > [data-wm-marks]::after {
  margin-left: 6px;
  color: var(--color2);
  content: "[" attr(data-wm-marks) "]";
}

/* ------------------------------------------------------------------- dunst */

/* dunstrc geometry "0x4-25+25": top right, 25px in — but 25px *below the
   title-bar row* of a window touching the top edge, so a toast lands in that
   window's body and never on its minimize / maximize / close buttons (the
   reason toasts once lived bottom right). Frame 1px (the overlay border role
   stands in for the dunstrc's heritage red), separator fg, padding 8/10,
   transparency 15. */
.dunst {
  position: fixed;
  z-index: var(--wm-z-dunst);
  top: calc(var(--bar-height) + var(--gap) + var(--title-height) + 25px);
  right: 25px;
  display: flex;
  max-width: min(360px, 45vw);
  flex-direction: column;
  align-items: flex-end;
  gap: 0;
  pointer-events: none;
}

.dunst-toast {
  display: flex;
  max-width: 100%;
  flex-direction: column;
  padding: 8px 10px;
  border: 1px solid var(--color-border-overlay);
  background: var(--color0);
  color: var(--foreground);
  opacity: 0.85;
  overflow: hidden;
  pointer-events: auto;
  font-size: var(--font-size-ui-md);
  line-height: 1.35;
}

.dunst-toast + .dunst-toast { border-top: 1px solid var(--foreground); }
.dunst-summary { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dunst-body { color: var(--color2); white-space: pre-line; }

/* urgency_low is the neutral status fill (color15 with black text: the
   config's color0 on color15 sits just under the contrast floor);
   urgency_critical is the danger fill, no timeout. */
.dunst-toast.is-low { background: var(--color-status-neutral-fill); color: var(--color-status-neutral-on-fill); opacity: 0.95; }
.dunst-toast.is-low .dunst-body { color: var(--color-status-neutral-on-fill); }
.dunst-toast.is-critical { border-color: var(--color-status-danger-on-fill); background: var(--color-status-danger-fill); color: var(--color-status-danger-on-fill); opacity: 1; }
.dunst-toast.is-critical .dunst-body { color: var(--color-status-danger-on-fill); }

/* ----------------------------------------------------------------- greeter */

.greeter,
.lock {
  position: fixed;
  z-index: var(--wm-z-curtain);
  display: grid;
  align-content: center;
  justify-items: center;
  background: var(--desktop);
  inset: 0;
}

.greeter {
  /* The text face is 29 KB and preloaded, and its local fallbacks are
     metric-matched, so the boot log can use the site's own font without a
     mid-animation reflow when the swap lands. */
  align-content: stretch;
  justify-items: stretch;
  padding: 0;
  font-family: var(--font);
  gap: 0;
}


/* The pre-paint script sets data-boot before greeter.js has loaded, so for a
   few frames the desktop would paint and then be covered. This curtain paints
   black from frame 1 instead — the same black a machine shows before tty1.
   It is not the forbidden "opacity curtain that never clears": data-boot is
   removed on login, when the greeter fails to load, and by the inline boot
   guards, so nothing can leave it up over a working page. */
html[data-boot] body::before {
  content: "";
  position: fixed;
  z-index: calc(var(--wm-z-curtain) - 1);
  background: var(--desktop);
  inset: 0;
}

html[data-boot] .desktop-shell { pointer-events: none; }

.greeter.is-leaving { opacity: 0; transition: opacity 240ms linear; }

.greeter-boot {
  overflow: hidden;
  padding: 18px 20px;
  color: var(--muted);
}


.greeter-banner {
  margin: 0 0 10px;
  color: var(--prose);
}

.greeter-banner span { display: block; }

.greeter-login-screen {
  display: grid;
  height: 100%;
  align-content: center;
  justify-items: center;
  padding: 24px;
}


.greeter-panel {
  width: min(320px, 100%);
  padding: 18px 20px;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  text-align: center;
}

.greeter-panel p { margin: 0 0 8px; }
.greeter-host { color: var(--muted); }
.greeter-desktop { color: var(--quiet); }
.greeter-user { padding-top: 6px; color: var(--prose); font-size: var(--font-size-reading); }

.greeter-pass {
  display: flex;
  min-height: 26px;
  align-items: center;
  justify-content: center;
  padding: 0 8px;
  border: 1px solid var(--border);
  background: var(--terminal);
  color: var(--foreground-bright);
  letter-spacing: 3px;
}

.greeter-caret {
  width: 7px;
  height: 13px;
  background: var(--focus);
}

.greeter-login {
  width: 100%;
  min-height: 30px;
  margin-top: 4px;
  border: 1px solid var(--border-strong);
  background: var(--button);
  color: var(--prose);
}

.greeter-login:hover,
.greeter-login:focus-visible { background: var(--selection); }

.greeter-auth { min-height: 1.2em; color: var(--muted); }

.greeter-log {
  width: 100%;
  padding: 0;
  margin: 0;
  list-style: none;
}

.greeter-log li {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.greeter-line-kernel { color: var(--quiet); }
.greeter-line-plain { color: var(--muted); }
/* systemd pads its status tags; without pre the browser collapses them to
   "[ OK ]" and the log stops looking like a real console. */
.greeter-ok,
.greeter-pending { white-space: pre; }
.greeter-ok { color: var(--color-status-success-text); }
.greeter-pending { color: var(--quiet); }

.greeter-hint {
  position: absolute;
  bottom: 16px;
  left: 0;
  width: 100%;
  margin: 0;
  color: var(--quiet);
  text-align: center;
}


/* The login panel waits for a real click or keypress, so keys must not reach
   the desktop underneath while it is up. */
html.wm-greeting .desktop-shell { pointer-events: none; }

/* The power sequences borrow this screen. `shutdown` is the boot-log look;
   `black`, `sleep` and `off` are a dark screen — above the lock screen too,
   which is what a sleeping machine over a locked session is. */
.greeter[data-phase="black"] .greeter-boot,
.greeter[data-phase="sleep"] .greeter-boot,
.greeter[data-phase="off"] .greeter-boot { visibility: hidden; }

.greeter[data-phase="black"],
.greeter[data-phase="sleep"],
.greeter[data-phase="off"] {
  z-index: calc(var(--wm-z-curtain) + 1);
  background: var(--desktop);
  cursor: default;
}

.greeter-power {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 64px;
  height: 64px;
  border: 1px solid var(--quiet);
  border-radius: 50%;
  background: transparent;
  color: var(--quiet);
  cursor: pointer;
  font: inherit;
  font-size: 26px;
  transform: translate(-50%, -50%);
}

.greeter-power:hover,
.greeter-power:focus-visible { border-color: var(--foreground-bright); color: var(--foreground-bright); outline: var(--focus-ring); outline-offset: 4px; }

/* ---------------------------------------------------------------- i3lock */

/* i3lock paints an opaque screen; the session beneath is hidden, not dimmed. */
.lock { background: var(--desktop); gap: 6px; }

.lock-ring {
  width: 96px;
  height: 96px;
  margin-bottom: 14px;
  border: 3px solid var(--focus);
  border-radius: 50%;
}

.lock-time { margin: 0; color: var(--prose); font-size: 30px; }
.lock-date, .lock-user, .lock-hint { margin: 0; color: var(--muted); }
.lock-hint { margin-top: 12px; color: var(--quiet); }

html.wm-locked .desktop-shell { pointer-events: none; }

/* ------------------------------------------------------------ applications */

.wm-app-body {
  min-width: 0;
  min-height: 0;
  flex: 1 1 auto;
  padding: 10px;
  overflow: auto;
}

.shell-line { display: flex; align-items: baseline; }
.shell-prompt { flex: 0 0 auto; white-space: pre; }

.shell-input {
  min-width: 0;
  flex: 1 1 auto;
  border: 0;
  background: transparent;
  color: var(--prose);
  outline: 0;
}

.neofetch { display: flex; gap: 18px; }
.neofetch-logo { margin: 0; color: var(--focus); font-size: 7px; line-height: 1.05; }
.neofetch-column { min-width: 0; }
.neofetch-info { margin: 0; }
.neofetch-info div { display: flex; gap: 6px; }
.neofetch-info dt { min-width: 84px; color: var(--focus); }
.neofetch-info dd { margin: 0; color: var(--prose); }
.neofetch-swatches { display: flex; margin-top: 10px; }
.neofetch-swatch { width: 22px; height: 12px; }
.neofetch-swatch.s0 { background: var(--color0); }
.neofetch-swatch.s1 { background: var(--inactive); }
.neofetch-swatch.s2 { background: var(--selection-dark); }
.neofetch-swatch.s3 { background: var(--selection); }
.neofetch-swatch.s4 { background: var(--button); }
.neofetch-swatch.s5 { background: var(--focus); }
.neofetch-swatch.s6 { background: var(--foreground); }
.neofetch-swatch.s7 { background: var(--prose); }

.htop-meters { margin: 0 0 10px; color: var(--foreground-bright); }
.htop-table { width: 100%; border-collapse: collapse; }
.htop-table th { padding: 2px 6px; background: var(--selection-dark); color: var(--prose); text-align: left; }
.htop-table td { padding: 2px 6px; color: var(--muted); white-space: nowrap; }
.htop-table tr.is-selected td { background: var(--selection-soft); color: var(--prose); }

.cmatrix-window .wm-app-body { padding: 0; overflow: hidden; }
.cmatrix { display: block; }

.feh-grid { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.feh-thumb { padding: 6px; border: 1px solid var(--border); background: var(--terminal); color: var(--muted); text-align: left; }
.feh-thumb.is-selected { border-color: var(--focus); color: var(--prose); }
.feh-preview { display: block; height: 74px; border: 1px solid var(--border); }
.feh-preview.wallpaper-black { background: var(--desktop); }
.feh-preview.wallpaper-ember { background: var(--wallpaper-ember); }
/* The ridge repeats every 88px; a 74px thumbnail shows it at a tighter pitch. */
.feh-preview.wallpaper-ridge { background: repeating-linear-gradient(180deg, var(--color-interaction-marquee) 0 2px, transparent 2px 14px), var(--chrome); }
.feh-label { display: block; margin-top: 5px; }

/* ---------------------------------------- before boot, and when it never comes */

/* Until the window manager has laid the windows out, the routed workspace's
   windows sit in a static grid with i3's gaps. Document mode (no JavaScript,
   or a boot that failed) is site.css's: it stacks the same windows and needs
   only the padding from here. */
html:not(.wm-active) .workspace-layer {
  padding: max(0px, calc(var(--gaps-inner) + var(--gaps-outer)));
}

html.js:not(.wm-active):not([data-wm="off"]) .workspace-layer {
  display: grid;
  gap: var(--gaps-inner);
}

html:not(.wm-active) .writing-grid,
html:not(.wm-active) .photography-grid {
  grid-template-columns: minmax(260px, 0.38fr) minmax(0, 0.62fr);
}

html:not(.wm-active) .books-grid {
  grid-template-columns: minmax(280px, 0.48fr) minmax(0, 0.52fr);
}

html:not(.wm-active) .projects-grid {
  grid-template-rows: minmax(0, 0.58fr) minmax(0, 0.42fr);
}

html:not(.wm-active) .wm-deco,
html:not(.wm-active) .wm-empty {
  display: none;
}

/* i3-nagbar: the session menu, as i3 answers $mod+Shift+E. */
.nagbar {
  position: fixed;
  z-index: var(--wm-z-dunst);
  top: var(--bar-height);
  right: 0;
  left: 0;
  display: flex;
  align-items: center;
  padding: 7px 10px;
  border-bottom: 1px solid var(--focus);
  background: var(--surface-raised);
  gap: 8px;
}


.nagbar-message {
  min-width: 0;
  flex: 1 1 auto;
  margin: 0;
  overflow: hidden;
  color: var(--prose);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.nagbar-action {
  min-height: 26px;
  flex: 0 0 auto;
  padding: 0 12px;
  border: 1px solid var(--border-strong);
  background: var(--button);
  color: var(--prose);
}

.nagbar-action:hover,
.nagbar-action:focus-visible { background: var(--selection); }
.nagbar-cancel { background: var(--surface); color: var(--foreground); }

@media (max-width: 767px) {
  /* Logging in is a button press now, so it has to be a real touch target. */
  .greeter-login { min-height: 44px; }
  .greeter-panel { width: min(340px, 100%); }

  .nagbar { flex-wrap: wrap; }
  .nagbar-message { flex-basis: 100%; }
  .nagbar-action { min-height: 40px; }
}

/* -------------------------------------------------------------- responsive */

/* The bar clips rather than squeezing the workspace names, so blocks are shed
   in ascending order of usefulness before they ever reach that point. */
/* Shedding order: the labels go first — a glyph and a reading say the same
   thing in a third of the width, and the screen-reader label never moves — then
   the least useful readings. Tuned with headroom rather than to the pixel: text
   measures differently across platforms, and the workspace names must never be
   squeezed on any of them. */
@media (max-width: 1699px) { .i3block-label { display: none; } }
@media (max-width: 2199px) { .i3block-lang { display: none; } }
@media (max-width: 2019px) { .i3block-tz { display: none; } }
@media (max-width: 1839px) { .i3block-heap { display: none; } }
@media (max-width: 1719px) { .i3block-up { display: none; } }
@media (max-width: 1579px) { .i3block-res { display: none; } }
@media (max-width: 1339px) { .i3block-mem { display: none; } }
@media (max-width: 1259px) { .i3block-net { display: none; } }
@media (max-width: 1079px) { .i3block-cpu, .i3block-bat { display: none; } }

@media (max-width: 1199px) {
  html.wm-active .photography-body,
  html.wm-active .library-body { grid-template-columns: 145px minmax(0, 1fr); }
}

@media (max-width: 767px) {
  :root { --wm-tab-height: 44px; --wm-stack-row: 44px; }

  .i3status { display: none; }
  .dunst { top: calc(var(--bar-height) + var(--title-height) + 8px); right: 6px; left: 6px; max-width: none; }
  .wm-tab { min-width: 88px; padding: 0 10px; }
  .window-mark { width: 30px; height: 30px; }

  /* The title bar is the long-press target, so it needs real area — and it is
     not scrollable, which makes touch-action:none safe here. */
  html.wm-active .window-titlebar { touch-action: none; }

  .neofetch { flex-direction: column; }
  .neofetch-logo { font-size: 6px; }
  .greeter-log { min-height: 7em; overflow: hidden; font-size: 11px; }

  #command-launcher { top: var(--vv-offset, 0); }
}

@media (max-width: 420px) {
  .workspace-link { padding-inline: 9px; }
}

/* Landscape phones lose so much height to chrome that the app furniture has to
   go: 44 + 44 + 32 + 27 is 39% of a 375px-tall viewport. */
@media (max-width: 926px) and (orientation: landscape) and (pointer: coarse) {
  :root { --bar-height: 32px; --title-height: 26px; --wm-tab-height: 38px; }

  .app-statusline,
  .terminal-statusline,
  .vim-statusline,
  .app-menu,
  .vim-tabline { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .greeter.is-leaving { transition: none; }
}
