The board's card width changed at every group boundary because `columns:` was being tuned per group under the 2026-08-18 "columns = member count" rule. That rule is retired: it sets `lg:grid-cols-N` for one group, so it fixes that group's CARD WIDTH, not its density. Measured on the live board, Notes rendered a single 1464px card, News and Media 728px, Eval & Retrieval 286px, everything else 360px. All 20 groups are now `columns: 4` and every card renders at 360. `.service-name` reserved a 78px status gutter with `padding-right` and relied on `overflow: hidden` to hold it, but overflow clips at the PADDING box — the gutter was spill room the title printed straight through. Six cards on the AI tab rendered their name underneath their own status pill, measured by testing the title text node's box against the status cluster's. The intended ellipsis never fired either: it is painted by whichever block's own line overflows, and that is the anonymous box around the bare title text node, which does not carry `overflow`. The gutter holds by wrapping now, and the description opts back out of it with a negative margin since the pill only ever covers the first line. Scriberr's `homepage.group=AI Systems` named a group absent from `layout:`, so it had no `tab:` and rendered on all four tabs — the same defect as UltraSeedbox in 2026-08-18, arriving this time from a container label. Relabelled to `AI - Audio Tools`, where the other ASR seats already live. The `homepage.group=AI Systems` sample in the repo-root CLAUDE.md was the source of the name and now carries the constraint, plus the fact that a labelled container is discovered from any of the five configured engines and must not also be listed in services.yaml. Also: descriptions clamped to three lines so a five-line outlier stops dragging its row 50px taller than its neighbours; icon ramp overridden off slate-400 -> slate-700, which was sinking the bottom half of every glyph into the card fill; bookmark groups and Jellyfin's trailing stream rows brought into the card and eyebrow vocabulary; group gap 10px -> 22px now that width no longer separates them. The icon override sits on `html[class]`, not `:root`: Homepage sets the same variables on `.theme-slate`, which is on the <html> element, and a class beats `:root` on the same element. Verified with Playwright against the live board — per-group card width, card height spread, and a geometric title-vs-status collision check, before and after. Before/after captures: http://10.100.10.50:8090/b/homepage-relayout/
225 lines
8.2 KiB
YAML
225 lines
8.2 KiB
YAML
---
|
|
# https://gethomepage.dev/latest/configs/settings
|
|
title: ... all my base ...
|
|
theme: dark
|
|
# `color:` only accepts Homepage's built-in Tailwind ramps, and none of them is
|
|
# the Australis Sea ramp. slate is the nearest cool neutral and acts as the
|
|
# base under conf/custom.css, which is where the real palette lives.
|
|
color: slate
|
|
|
|
# NO `background:` BLOCK — DELIBERATE, DO NOT RE-ADD WITHOUT ASKING.
|
|
#
|
|
# This carried a generated full-bleed aurora image (Arbo job 13f0891f4e42,
|
|
# seed 26, flux2-klein-9b) at opacity 30. It went in on an explicit request
|
|
# for an Arbo-generated background and came out on 2026-08-19 when the
|
|
# operator called the result ugly.
|
|
#
|
|
# The image was also against canon on its own terms: Australis says "solid
|
|
# fills only on chrome — no full-bleed photography, no decorative gradients",
|
|
# and permits the aurora motif "never as a background fill behind text". A
|
|
# whole dashboard is text. The predecessor knew and dialled the opacity down
|
|
# instead of dropping it, which is how you end up with a quiet version of the
|
|
# wrong thing. The asset is still in `images/` if this is ever revisited.
|
|
#
|
|
# The aurora now appears exactly where canon sanctions it: a 1px accent edge
|
|
# under the tab bar, in conf/custom.css.
|
|
headerStyle: boxedWidgets
|
|
|
|
providers:
|
|
openweathermap: openweathermapapikey
|
|
weatherapi: weatherapiapikey
|
|
|
|
quicklaunch:
|
|
searchDescriptions: true
|
|
hideInternetSearch: true
|
|
showSearchSuggestions: true
|
|
hideVisitURL: true
|
|
|
|
showStats: false
|
|
statusStyle: ""
|
|
|
|
# Cards size to their own content. This was `true` to stop widget-bearing
|
|
# cards (Uptime Kuma's stat strip, Paperless's counts) standing taller than
|
|
# plain link cards and leaving the grid ragged — but the cure was worse than
|
|
# the disease: every short card in the row inflated into a hollow box to match
|
|
# the tall one. A ragged bottom edge reads as content; a stretched empty card
|
|
# reads as a rendering fault.
|
|
useEqualHeights: false
|
|
|
|
# Function-first layout, four-tab split:
|
|
# Main - daily-use apps, media, bookmarks, monitoring
|
|
# AI - the inference fleet, grouped by role (see below)
|
|
# Infrastructure - hardware, hypervisors, BMCs (per site)
|
|
# Toolchain - backend services running but rarely clicked
|
|
#
|
|
# The AI tab splits the fleet by function so a 20+ service list reads as
|
|
# sorted groups instead of one endless column. Group membership is set by
|
|
# the homepage.group=AI - <role> label on each service's compose file:
|
|
# AI - Inference LLM seats you call (gen, char-rp, char-rp-reasoning, summarizer)
|
|
# AI - Eval & Retrieval judges, reward, rerank, embed, image-quality
|
|
# AI - Gateways & Chat routing gateway, control plane, chat frontends
|
|
# AI - Speech (TTS) text-to-speech engines
|
|
# AI - Audio Tools speech-to-text + audio dataset tooling
|
|
# AI - Image & Media image/video generation + pipelines
|
|
# AI - Dormant stopped stacks (rollback seats, retired auditions)
|
|
#
|
|
# AI TAB ORDER IS BY CLICKABILITY, NOT BY IMPORTANCE (operator, 2026-08-18).
|
|
# Groups render in the order they appear in this block, so the top of the tab
|
|
# is prime real estate and it should hold the things you actually open in a
|
|
# browser — chat frontends, ComfyUI, the control plane. Most of the model
|
|
# seats below them are vLLM API endpoints whose href is a `/docs` page: they
|
|
# are worth SEEING (status at a glance) but not worth reaching for, so they
|
|
# sink. Order is therefore:
|
|
# interactive UIs -> mixed -> API-only seats -> dormant
|
|
# If you add an AI group, place it by asking "would I click this?", not by
|
|
# how central the service is to the fleet.
|
|
#
|
|
# COLUMNS ARE 4 EVERYWHERE. DO NOT TUNE THEM PER GROUP.
|
|
#
|
|
# `columns: N` is not a density dial — it sets `lg:grid-cols-N` on that one
|
|
# group, so it fixes the CARD WIDTH for that group alone. Varying it per group
|
|
# means the card width changes every time you cross a group boundary, and a
|
|
# page whose grid keeps resizing as you scroll reads as broken layout even when
|
|
# every individual group is fine.
|
|
#
|
|
# The predecessor rule here was "columns = the member count", written to avoid
|
|
# the dead cells a 1-member group leaves in a 4-wide row. It trades one flaw
|
|
# for a worse one: at columns:1 a single service becomes a 1500px-wide bar
|
|
# holding six words, and at columns:2 a three-member group orphans its third
|
|
# card onto a half-empty row. Measured on the live board 2026-08-24 — the
|
|
# Notes, News, Media, AI - Image & Media and AI - Audio Tools groups were all
|
|
# rendering cards two to four times wider than the groups above and below them.
|
|
#
|
|
# A short last row is what a grid looks like. A card that is wider than its
|
|
# neighbours is what a mistake looks like. Uniform wins.
|
|
#
|
|
# Homepage's own responsive ramp (`grid-cols-1 md:grid-cols-2 lg:grid-cols-N`)
|
|
# still collapses this to 2-up and 1-up on narrow viewports, so 4 is a desktop
|
|
# maximum, not a hard floor.
|
|
#
|
|
# EVERY GROUP NEEDS A `tab:` — including bookmark groups, and including groups
|
|
# that arrive from a `homepage.group=` container label rather than from this
|
|
# file. A group with no tab assignment renders on ALL FOUR TABS. That is how
|
|
# UltraSeedbox ended up repeated at the bottom of every tab (fixed 2026-08-18)
|
|
# and how Scriberr's `AI Systems` label did the same from 2026-08-23 (fixed
|
|
# 2026-08-24 by relabelling it into `AI - Audio Tools`). It is Homepage
|
|
# behaviour, not a bug, and it will happen again to the next container labelled
|
|
# with a group name that does not appear below.
|
|
# `GET /api/services` prints the live group list — anything in it that is not a
|
|
# key here is currently leaking onto all four tabs.
|
|
layout:
|
|
Notes:
|
|
icon: mdi-note-text-outline
|
|
tab: Main
|
|
style: row
|
|
columns: 4
|
|
News:
|
|
icon: mdi-rss
|
|
tab: Main
|
|
style: row
|
|
columns: 4
|
|
Monitoring:
|
|
icon: mdi-chart-line
|
|
tab: Main
|
|
style: row
|
|
columns: 4
|
|
Apps:
|
|
icon: mdi-apps
|
|
tab: Main
|
|
style: row
|
|
columns: 4
|
|
Media:
|
|
icon: mdi-play-box-multiple
|
|
tab: Main
|
|
style: row
|
|
columns: 4
|
|
Games:
|
|
icon: mdi-gamepad-square
|
|
tab: Main
|
|
style: row
|
|
columns: 4
|
|
# Bookmarks. Listed here for the tab pin above all else — without it this
|
|
# group appears on every tab. `style: row` also turns the eight entries
|
|
# from full-width stacked bars into a compact grid.
|
|
UltraSeedbox:
|
|
icon: mdi-download-network
|
|
tab: Main
|
|
style: row
|
|
columns: 4
|
|
# --- AI tab: ordered interactive -> API-only -> dormant (see note above) ---
|
|
# Things you open: chat frontends, the control plane, the LiteLLM UI.
|
|
AI - Gateways & Chat:
|
|
icon: mdi-router-network
|
|
tab: AI
|
|
style: row
|
|
columns: 4
|
|
# ComfyUI is a full node editor and Arbo has a real UI — both get clicked.
|
|
AI - Image & Media:
|
|
icon: mdi-image-multiple
|
|
tab: AI
|
|
style: row
|
|
columns: 4
|
|
# Mixed: YT Voice Clipper has an audition console, Parakeet is an API.
|
|
# Scriberr joined here 2026-08-24 (it was the stray `AI Systems` group).
|
|
AI - Audio Tools:
|
|
icon: mdi-waveform
|
|
tab: AI
|
|
style: row
|
|
columns: 4
|
|
# Below here: model seats whose href is a vLLM `/docs` page. Status at a
|
|
# glance is the whole value; you consume these through the gateway, not by
|
|
# clicking them.
|
|
AI - Inference:
|
|
icon: mdi-brain
|
|
tab: AI
|
|
style: row
|
|
columns: 4
|
|
AI - Eval & Retrieval:
|
|
icon: mdi-scale-balance
|
|
tab: AI
|
|
style: row
|
|
columns: 4
|
|
AI - Speech (TTS):
|
|
icon: mdi-account-voice
|
|
tab: AI
|
|
style: row
|
|
columns: 4
|
|
# Stopped stacks kept for rollback / superseded seats / retired auditions.
|
|
# They stay 'created' (not running) via `docker compose up --no-start`, so
|
|
# they show here as offline cards and revive with `docker compose start`.
|
|
AI - Dormant:
|
|
icon: mdi-sleep
|
|
tab: AI
|
|
style: row
|
|
columns: 4
|
|
Infra - ANA:
|
|
icon: si-proxmox
|
|
tab: Infrastructure
|
|
style: row
|
|
columns: 4
|
|
Infra - NH3:
|
|
icon: si-proxmox
|
|
tab: Infrastructure
|
|
style: row
|
|
columns: 4
|
|
Infra - IRV:
|
|
icon: mdi-brain
|
|
tab: Infrastructure
|
|
style: row
|
|
columns: 4
|
|
Infra - ESH:
|
|
icon: si-proxmox
|
|
tab: Infrastructure
|
|
style: row
|
|
columns: 4
|
|
Service Networking:
|
|
icon: mdi-transit-connection-variant
|
|
tab: Toolchain
|
|
style: row
|
|
columns: 4
|
|
Toolchain:
|
|
icon: mdi-toolbox
|
|
tab: Toolchain
|
|
style: row
|
|
columns: 4
|