From 26424469db9c675c202e6d557001fbde177ac5d7 Mon Sep 17 00:00:00 2001 From: dtoro Date: Wed, 8 Apr 2026 21:34:18 +0200 Subject: [PATCH] feat: center hints over the timeline + add hubris footer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - KeyboardHints: switch from fixed positioning to absolute, mounted inside the main content column. The column is now relative-positioned so the hints overlay centers against the timeline area instead of the raw viewport (which was off-center because of the sidebars). - AppFooter: tiny "Built with hubris • " pinned to the bottom-right corner of the main column. Year is computed at render time and converted via a small toRoman helper. Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/src/App.tsx | 15 ++++---- frontend/src/components/AppFooter.tsx | 43 +++++++++++++++++++++++ frontend/src/components/KeyboardHints.tsx | 6 +++- 3 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 frontend/src/components/AppFooter.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 29900fb..1f0dffd 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -6,6 +6,7 @@ import { TopBar } from './components/layout/TopBar' import { ScanProgress } from './components/ScanProgress' import { ToastContainer } from './components/ToastContainer' import { KeyboardHints } from './components/KeyboardHints' +import { AppFooter } from './components/AppFooter' import { PreviewView } from './components/preview/PreviewView' import { FilterBar } from './components/filter/FilterBar' import { DiscardActionBar } from './components/discard/DiscardActionBar' @@ -66,13 +67,19 @@ function App() { {/* Main column — filter bar, discard bar, timeline. Lives to the * right of the left sidebar so the filter row doesn't bleed - * across the sidebar. */} -
+ * across the sidebar. relative so the KeyboardHints overlay + * centers against this column, not the viewport. */} +
+ {/* Floating keyboard hints — bottom-center of the main column, + * glassy. Mounted here so it's centered against the timeline, + * not the viewport (which would be offset by the sidebars). */} + +
{/* Right Sidebar */} @@ -85,10 +92,6 @@ function App() {
- {/* Floating keyboard hints — pinned bottom-center, glassy. Sits - * above the timeline and below the toast layer. */} - - {/* Scan Progress Indicator */} diff --git a/frontend/src/components/AppFooter.tsx b/frontend/src/components/AppFooter.tsx new file mode 100644 index 0000000..a13204a --- /dev/null +++ b/frontend/src/components/AppFooter.tsx @@ -0,0 +1,43 @@ +/** + * Tiny corner footer pinned to the bottom-right of the main column. + * Renders "Built with hubris • ", refreshed + * once per page load. + */ + +const ROMAN_PAIRS: [number, string][] = [ + [1000, 'M'], + [900, 'CM'], + [500, 'D'], + [400, 'CD'], + [100, 'C'], + [90, 'XC'], + [50, 'L'], + [40, 'XL'], + [10, 'X'], + [9, 'IX'], + [5, 'V'], + [4, 'IV'], + [1, 'I'], +] + +function toRoman(n: number): string { + let result = '' + for (const [value, symbol] of ROMAN_PAIRS) { + while (n >= value) { + result += symbol + n -= value + } + } + return result +} + +export function AppFooter() { + const year = new Date().getFullYear() + return ( +
+ + Built with hubris • {toRoman(year)} + +
+ ) +} diff --git a/frontend/src/components/KeyboardHints.tsx b/frontend/src/components/KeyboardHints.tsx index e011ca0..084b72c 100644 --- a/frontend/src/components/KeyboardHints.tsx +++ b/frontend/src/components/KeyboardHints.tsx @@ -25,7 +25,11 @@ export function KeyboardHints() { ] return ( -
+ // Absolute (not fixed) so the parent's flex/position context can + // center it relative to the timeline area, not the viewport. Mount + // inside the main column in App.tsx so it isn't offset by the + // sidebar widths. +
{hints.map((hint, i) => (