eleven / ocho Public

web: staged attachment chips float over the feed (#52)

The staged-attachment previews sat in their own in-flow band above the
composer (an opaque strip that pushed the feed up). Anchor them to a
zero-height wrapper at the top of the composer stack instead, painting
upward — so they float over the messages, rise with any reply/edit
banners, and wrapped rows grow upward. Chips get panel bg + border +
shadow so they read as floating cards over whatever's underneath;
pointer-events pass through the empty row so the feed stays scrollable.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell 533c7c803a31ae8b00a43d4cc6d3e825769575cc parent b778aac
2 files changed, +28 −4
  • web/pages/index.html +6 −1
  • web/static/style.css +22 −3
diff --git a/web/pages/index.html b/web/pages/index.html
index a73e8ed..6b7fe4f 100644
--- a/web/pages/index.html
+++ b/web/pages/index.html
@@ -108,11 +108,16 @@
</header>
<div class="feed" id="feed"></div>
<div class="drop-overlay hidden" id="drop-overlay">Drop a photo or file to send</div>
+ <!-- Zero-height anchor at the top of the composer stack: the staged-
+ attachment chips paint upward from here, floating over the feed
+ instead of occupying their own band (see .composer-float). -->
+ <div class="composer-float">
+ <div class="composer-preview hidden" id="composer-preview"></div>
+ </div>
<div class="typing hidden" id="typing" aria-live="polite"></div>
<div class="typeahead hidden" id="typeahead" role="listbox"></div>
<div class="composer-reply hidden" id="composer-reply"></div>
<div class="composer-edit hidden" id="composer-edit"></div>
- <div class="composer-preview hidden" id="composer-preview"></div>
<form class="composer" id="composer" autocomplete="off">
<button type="button" class="attach-btn" id="attach-btn" aria-label="Add a photo or file">+</button>
<input type="file" id="file-input" multiple
diff --git a/web/static/style.css b/web/static/style.css
index b1e6ed9..037ddfd 100644
--- a/web/static/style.css
+++ b/web/static/style.css
@@ -582,8 +582,23 @@ input:focus, textarea:focus { outline: 2px solid var(--accent); border-color: tr
}
.lp-host { font-size: 11px; color: var(--muted); margin-top: 5px; }
-/* composer attachment preview */
-.composer-preview { padding: 10px 16px 0; display: flex; flex-wrap: wrap; gap: 8px; }
+/* composer attachment preview — floats over the feed instead of taking its own
+ band. .composer-float is a zero-height in-flow anchor at the top of the
+ composer stack; the chip row is absolutely anchored to its bottom, so it
+ paints upward over the messages and rises with any banners (reply/edit)
+ that grow the stack. Wrapped rows grow upward too (bottom-anchored). */
+.composer-float { position: relative; height: 0; z-index: 5; }
+.composer-preview {
+ position: absolute;
+ bottom: 8px;
+ left: 16px;
+ right: 16px;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ pointer-events: none; /* the empty row lets feed clicks/scroll through */
+}
+.composer-preview > * { pointer-events: auto; }
.composer-preview.hidden { display: none; }
.preview-spinner {
width: 16px; height: 16px; border-radius: 50%;
@@ -595,7 +610,11 @@ input:focus, textarea:focus { outline: 2px solid var(--accent); border-color: tr
display: inline-flex;
align-items: center;
gap: 8px;
- background: var(--bubble-them);
+ /* Panel bg + border + shadow so the chip reads as a floating card over
+ whatever messages happen to be underneath it. */
+ background: var(--panel);
+ border: 1px solid var(--border);
+ box-shadow: 0 6px 20px var(--shadow);
border-radius: 12px;
padding: 6px 34px 6px 8px;
max-width: 100%;