buds rename + applet-list shell — Buddies → Buds everywhere (model field, slug, URL, view, DOM, CSS); my_buds.html + my_posts.html share new _applet-list-shell.html partial — vertical-title applet-scroll card; my_posts hosts two side-by-side in landscape, stacked in portrait — TDD

- lyric/0005 RemoveField+AddField (RenameField doesn't rename the implicit M2M through table; field was new in 0004 so no data loss). Lyric.User.buddies → User.buds; related_name added_as_buddy → added_as_bud.
  - applets/0007 renames Applet slug my-buddies → my-buds + name 'My Buddies' → 'My Buds'. UI rationale: BILLBUDDIES overflowed the page-header band; in-game term collapses to BILLBUDS.
  - billboard/0006 alter Line.Meta.ordering = ('created_at', 'id') — was already in models.py, just generates the corresponding migration (formalizing the ordering decision from the May-8b refactor).
  - global rename via sed: buddies → buds, buddy → bud across 16 files (templates, SCSS, JS, ITs, FTs, page object, view code). 4 file renames via git mv: my_buddies.html → my_buds.html, _applet-my-buddies.html → _applet-my-buds.html, _buddy_panel.html → _bud_panel.html, _buddy_add_panel.html → _bud_add_panel.html, _buddy.scss → _bud.scss. Test files renamed too: test_buddies.py → test_buds.py, test_my_buddies.py → test_my_buds.py, test_buddy_btn.py → test_bud_btn.py. core.scss @import 'buddy' → 'bud'.
  - new shared partial templates/apps/applets/_partials/_applet-list-shell.html — vertical-rotated <h2> + scrollable <ul> aperture, parameterised via {% include %} so a single page can invoke it more than once. Params: shell_title, shell_items, shell_item_template, shell_list_id, shell_empty.
  - my_buds.html: single shell invocation w. add-bud panel below (page_class page-billbuds).
  - my_posts.html: two shell invocations (own posts + posts shared with me) inside .applet-list-page--two-up — portrait stacks them; landscape lays side-by-side via @media (orientation: landscape) flex-direction: row (page_class page-billposts).
  - SCSS: drop the bottom-anchored .buds-page block; new shared .applet-list-page (extends %billboard-page-base, flex-column + padding) w. .applet-scroll inside (extends %applet-box) and .applet-list inside that (flex: 1, overflow-y: auto). .applet-list-page--two-up flips to row layout in landscape. Body class trio gains page-billposts.
  - 841 ITs + 5 my_buds/my_posts FTs green.

Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Disco DeDisco
2026-05-08 23:08:33 -04:00
parent 5f6002aa70
commit 246e45e55d
29 changed files with 552 additions and 443 deletions

View File

@@ -36,14 +36,16 @@
html:has(body.page-billboard),
html:has(body.page-billscroll),
html:has(body.page-billpost),
html:has(body.page-billbuddies) {
html:has(body.page-billbuds),
html:has(body.page-billposts) {
overflow: hidden;
}
body.page-billboard,
body.page-billscroll,
body.page-billpost,
body.page-billbuddies {
body.page-billbuds,
body.page-billposts {
overflow: hidden;
.container {
@@ -217,54 +219,62 @@ body.page-billbuddies {
}
}
// ── My Buddies page (aperture list + add-buddy panel) ────────────────────
// Mirrors .post-page's flex-column / overflow / bottom-anchor pattern;
// the add-buddy panel is included from the same _buddy*.scss styling.
// ── Applet-list page (Billbuds, Billposts) ───────────────────────────────
// Shared shell for pages built around _applet-list-shell.html — vertical
// title rotated on the left of an .applet-scroll card + scrollable <ul>
// aperture. `--single` hosts one section (My Buds); `--two-up` stacks
// two sections in portrait, places them side-by-side in landscape (My
// Posts: own + shared).
.buddies-page {
.applet-list-page {
@extend %billboard-page-base;
display: flex;
flex-direction: column;
padding: 0.75rem;
gap: 0.5rem;
gap: 0.75rem;
.buddies-header {
flex-shrink: 0;
.applet-scroll {
@extend %applet-box;
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
.buddies-title {
margin: 0 0 0.25rem;
font-weight: bold;
.applet-list {
list-style: none;
margin: 0;
padding: 0 0.75rem 0 0;
flex: 1;
min-height: 0;
overflow-y: auto;
}
.applet-list-entry {
padding: 0.4rem 0;
.bud-name { font-weight: bold; opacity: 0.85; }
&--empty { opacity: 0.6; font-style: italic; }
a {
color: inherit;
text-decoration: none;
font-weight: bold;
&:hover { opacity: 0.85; }
}
}
.applet-list-buffer {
flex-shrink: 0;
height: 0.5rem;
}
}
#id_buddies_list {
list-style: none;
margin: 0;
padding: 0 0.75rem 0 0;
flex: 1;
min-height: 0;
overflow-y: auto;
display: flex;
flex-direction: column;
justify-content: flex-end;
.buddy-entry {
padding: 0.4rem 0;
.buddy-name {
font-weight: bold;
opacity: 0.85;
}
&--empty {
opacity: 0.6;
font-style: italic;
}
}
.buddy-entry-buffer {
flex-shrink: 0;
height: 0.25rem;
// Side-by-side in landscape; stacked in portrait (default).
&--two-up {
@media (orientation: landscape) {
flex-direction: row;
.applet-scroll { flex: 1; }
}
}
}
@@ -276,13 +286,13 @@ body.page-billbuddies {
#id_billboard_applets_container {
#id_applet_my_scrolls { grid-column: 1 / span 4; grid-row: 1 / span 3; }
#id_applet_my_buddies { grid-column: 1 / span 4; grid-row: 4 / span 3; }
#id_applet_my_buds { grid-column: 1 / span 4; grid-row: 4 / span 3; }
#id_applet_notes { grid-column: 1 / span 4; grid-row: 7 / span 4; }
#id_applet_most_recent_scroll { grid-column: 5 / span 8; grid-row: 1 / span 10; }
@container (max-width: 550px) {
#id_applet_my_scrolls,
#id_applet_my_buddies,
#id_applet_my_buds,
#id_applet_notes,
#id_applet_most_recent_scroll {
grid-column: 1 / span 12;

View File

@@ -1,13 +1,13 @@
// Buddy btn (bottom-left mirror of #id_kit_btn)
// Bud btn (bottom-left mirror of #id_kit_btn)
//
// Lives on post.html only slide-out recipient field for the share-post
// async flow. Mutually exclusive w. #id_kit_btn (bottom-right): when one is
// active (.active class on btn + html.{kit|buddy}-open class on root), the
// active (.active class on btn + html.{kit|bud}-open class on root), the
// other quickly fades to opacity 0.
//
// Spec: functional_tests/test_buddy_btn.py.
// Spec: functional_tests/test_bud_btn.py.
#id_buddy_btn {
#id_bud_btn {
position: fixed;
bottom: 0.5rem;
left: 0.5rem;
@@ -43,12 +43,12 @@
}
// Slide-out panel: collapsed by default; opens to span ~viewport - 3rem.
#id_buddy_panel {
#id_bud_panel {
position: fixed;
bottom: 0.5rem; // align bottom edge w. buddy btn
bottom: 0.5rem; // align bottom edge w. bud btn
left: 1.5rem;
right: 1.5rem;
height: 3rem; // match buddy btn height for vertical-centre alignment
height: 3rem; // match bud btn height for vertical-centre alignment
z-index: 317;
display: flex;
align-items: center;
@@ -56,7 +56,7 @@
pointer-events: none;
overflow: hidden;
// Closed state collapse leftward into the buddy btn
// Closed state collapse leftward into the bud btn
transform-origin: left center;
transform: scaleX(0);
transition: transform 0.2s ease-out, opacity 0.15s ease;
@@ -76,7 +76,7 @@
flex: 1;
min-width: 0;
height: 100%;
// Generous left padding so the buddy btn glyph (3rem circle pinned
// Generous left padding so the bud btn glyph (3rem circle pinned
// at left:1.5rem) doesn't visually overlap the placeholder/typed text.
padding: 0 1rem 0 3.5rem;
background-color: rgba(var(--priUser), 1);
@@ -97,9 +97,9 @@
}
}
// html.buddy-open: slide the panel out, fade the kit btn away.
html.buddy-open {
#id_buddy_panel {
// html.bud-open: slide the panel out, fade the kit btn away.
html.bud-open {
#id_bud_panel {
transform: scaleX(1);
opacity: 1;
pointer-events: auto;
@@ -111,10 +111,10 @@ html.buddy-open {
}
}
// Kit dialog open: hide the buddy btn. We don't add an `html.kit-open`
// Kit dialog open: hide the bud btn. We don't add an `html.kit-open`
// class (game-kit.js uses [open] on the dialog + .active on the btn), so
// the mutual-exclusion is driven by `:has()` against the open dialog.
html:has(#id_kit_bag_dialog[open]) #id_buddy_btn {
html:has(#id_kit_bag_dialog[open]) #id_bud_btn {
opacity: 0;
pointer-events: none;
}

View File

@@ -13,7 +13,7 @@
@import 'note';
@import 'tooltips';
@import 'game-kit';
@import 'buddy';
@import 'bud';
@import 'wallet-tokens';