ui: bolder/colored active annotation, readable clip labels, multi-active

- active annotation is now loud: thick colour spine, a wash of its own colour,
  a hard offset shadow, bold title (was just a faint 2px shadow). Annotation
  colour drives it via a --ann-color custom property; added a colour swatch by
  each title so the commentary reads its colours.
- clip name is a solid bordered label chip pinned top-left instead of black
  text + white halo, which muddied over busy thumbnails.
- highlight ALL annotations whose marks contain the playhead, not just one
  (new ::active-annotations set sub), so overlapping marks light up together.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-06-30 10:45:34 -04:00
parent 7e32dc70dd
commit d877655b7a
3 changed files with 43 additions and 13 deletions

View file

@ -110,13 +110,26 @@ body { overflow: hidden; background: var(--desktop); background-size: 2px 2px;
.ann {
position: relative;
padding: 8px 10px; margin-bottom: 8px; border-radius: 0;
border: 1px solid var(--ink); background: var(--paper);
border: 1px solid var(--ink);
border-left: 6px solid var(--ann-color, var(--ink));
background: var(--paper);
transition: box-shadow .12s ease, border-left-width .12s ease, background .12s ease;
}
.ann.active { box-shadow: 2px 2px 0 var(--ink); }
/* the active annotation (playhead inside it) is loud: thick colour spine, a
wash of its own colour, a hard offset shadow, and a bold title. */
.ann.active {
border-left-width: 14px;
background: color-mix(in srgb, var(--ann-color, var(--ink)) 16%, var(--paper));
box-shadow: 4px 4px 0 var(--ann-color, var(--ink));
}
.ann.active .ann-title { font-weight: bold; }
.ann-head { display: flex; align-items: center; justify-content: space-between;
gap: 8px; margin-bottom: 4px; }
.ann-title { font-family: var(--chicago); font-size: 18px; line-height: 1.15;
.ann-title { display: flex; align-items: center; gap: 6px;
font-family: var(--chicago); font-size: 18px; line-height: 1.15;
color: var(--ink); }
.ann-swatch { flex-shrink: 0; width: 12px; height: 12px; border-radius: 0;
border: 1px solid var(--ink); background: var(--ann-color, var(--ink)); }
.ann-empty { color: var(--mute); font-size: 12px; }
.jump-btn { flex-shrink: 0; padding: 1px 7px; font-size: 10px; white-space: nowrap; }
@ -357,14 +370,16 @@ html.dark .timeline-head {
background-size: cover; background-position: center;
opacity: 1;
}
/* a solid label chip pinned top-left — readable over any thumbnail (the old
black-text-with-white-halo muddied over busy frames), shrinks to its text so
the rest of the thumbnail stays visible. */
.clip-name {
position: relative; z-index: 1; height: 100%; box-sizing: border-box;
padding: 0 4px; overflow: hidden; text-overflow: ellipsis; line-height: 1.8;
color: var(--ink); /* white halo keeps black text
legible without veiling the
full-color thumbnail */
text-shadow: 0 0 2px var(--paper), 0 0 2px var(--paper),
1px 1px 0 var(--paper), -1px -1px 0 var(--paper);
position: absolute; top: 0; left: 0; z-index: 1; max-width: 100%;
box-sizing: border-box; padding: 0 4px; line-height: 1.5;
background: var(--paper); color: var(--ink);
border-right: 1px solid var(--ink); border-bottom: 1px solid var(--ink);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
text-shadow: none;
}
/* one full-height playhead spanning both the pinned lanes and the scrolling

View file

@ -106,3 +106,15 @@
(:id (or (some (fn [a] (when (some (fn [[lo hi]] (<= lo ph hi)) (:bars a)) a)) anns)
(last (filter #(<= (:start %) ph) anns))
(first anns)))))
;; every annotation the playhead is currently inside (overlapping marks ⇒ more
;; than one). Falls back to the single ::active-annotation when between marks so
;; there's always one highlighted.
(rf/reg-sub
::active-annotations
:<- [::annotations] :<- [::playhead] :<- [::active-annotation]
(fn [[anns ph fallback] _]
(let [inside (into #{} (keep (fn [a] (when (some (fn [[lo hi]] (<= lo ph hi)) (:bars a))
(:id a)))
anns))]
(if (seq inside) inside (when fallback #{fallback})))))

View file

@ -686,6 +686,7 @@
(fn []
(let [anns @(rf/subscribe [::subs/annotations])
active @(rf/subscribe [::subs/active-annotation])
active-set @(rf/subscribe [::subs/active-annotations])
authed? @(rf/subscribe [::subs/authed?])
scene @(rf/subscribe [::subs/scene])
ctx @(rf/subscribe [::subs/context])
@ -709,10 +710,12 @@
(for [a anns]
^{:key (:id a)}
[:div.ann {:id (str "ann-" (name (:id a)))
:class (when (= (:id a) active) "active")
:style {:border-left (str "8px solid " (:color a))}}
:class (when (contains? active-set (:id a)) "active")
:style {"--ann-color" (:color a)}}
[:div.ann-head
[:div.ann-title (when (:broken a) [:span {:title (:reason a)} "△ "]) (:name a)
[:div.ann-title
[:span.ann-swatch {:style {:background (:color a)}}]
(when (:broken a) [:span {:title (:reason a)} "△ "]) (:name a)
(when (seq (:script a)) [:span.script-badge {:title "linked to script"} "¶"])]
[:div.ann-actions
[jump-control open a scene segs]