v3: the invite tree spaces every row the same — a child sat 0.2rem under its parent but siblings 0.4rem apart, since each row's spacing was split into top and bottom padding and a last child dropped its bottom half. Every row now has one gap above it (--invite-tree-gap), the connectors run through it from the same variable, and the user link is a block, so a theme's line height can't push the avatar off the connector's center.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
khannurien
2026-09-29 21:28:43 +00:00
parent 07ac4bc629
commit 2af64721c7

View File

@@ -5729,7 +5729,13 @@ body.has-player .chat-fab {
}
/* ── Invite tree ── */
/* Every row but the very first has the same gap above it, a child's as a
sibling's: the gap is the node's top padding, so the connectors can run
through it. --invite-tree-avatar-center is where a row's avatar is centered,
from the top of its node. */
.invite-tree {
--invite-tree-gap: 0.5rem;
--invite-tree-avatar-center: calc(var(--invite-tree-gap) + 12px);
list-style: none;
padding: 0;
margin: 0;
@@ -5737,60 +5743,54 @@ body.has-player .chat-fab {
.invite-tree-node {
position: relative;
padding: 0.2rem 0;
padding-top: var(--invite-tree-gap);
}
.invite-tree-node:last-child {
padding-bottom: 0;
.invite-tree-node:first-child:not(.invite-tree-node .invite-tree-node) {
padding-top: 0;
}
/* Child list: indented so connector lines have room on the left.
The vertical line sits at the list's left:0, centered under the parent
avatar (avatar center 12px - 1px half-line = 11px). */
/* A child list is indented so that the vertical connector, at its left edge,
is centered under the parent's 24px avatar (12px center - 1px half-line). */
.invite-tree-node > .invite-tree {
margin-left: 11px;
padding-left: calc(12px + 0.5rem);
}
/* Connectors are owned per child node (not by the list) so they always anchor
to that child's own avatar center, regardless of how deep its subtree is.
--avatar-center = node top padding (0.2rem) + half the 24px avatar (12px). */
.invite-tree-node > .invite-tree > .invite-tree-node {
--avatar-center: calc(0.2rem + 12px);
}
/* Vertical segment: drops from the top of the child node to its avatar center,
joining the line coming down from the parent / previous sibling. */
.invite-tree-node > .invite-tree > .invite-tree-node::before {
/* Each child draws its own connectors, so they anchor to its avatar however
deep its subtree is. The vertical one drops from the row above to its
avatar center, and on through its subtree when a sibling follows. */
.invite-tree-node .invite-tree-node::before {
content: "";
position: absolute;
left: calc(-12px - 0.5rem);
top: 0;
height: var(--avatar-center);
height: var(--invite-tree-avatar-center);
width: 2px;
background: var(--color-border-subtle);
}
/* Non-last children extend the vertical segment through their full height
(including any subtree) so it reaches the next sibling. */
.invite-tree-node > .invite-tree > .invite-tree-node:not(:last-child)::before {
.invite-tree-node .invite-tree-node:not(:last-child)::before {
height: auto;
bottom: 0;
}
/* Horizontal connector: from the vertical line to the child's avatar. */
.invite-tree-node > .invite-tree > .invite-tree-node::after {
/* The horizontal one runs from the vertical line to the avatar. */
.invite-tree-node .invite-tree-node::after {
content: "";
position: absolute;
left: calc(-12px - 0.5rem);
top: calc(var(--avatar-center) - 1px); /* straddle center with the 2px bar */
top: calc(var(--invite-tree-avatar-center) - 1px);
width: calc(12px + 0.5rem);
height: 2px;
background: var(--color-border-subtle);
}
/* A block, not inline: in a line box, the theme's line height would add space
under the avatar and move it off --invite-tree-avatar-center. */
.invite-tree-user {
display: inline-flex;
display: flex;
width: fit-content;
align-items: center;
gap: 0.5rem;
color: var(--color-text);