* fix(charts): restyle hover tooltips with soft shadow + larger radius
Match the elevation pattern of DS::Select dropdown
(shadow-lg + shadow-border-xs) and increase radius (rounded-lg →
rounded-xl) + padding (p-2 → p-3) for better breathing. Drops the
hard border in favour of the soft drop shadow.
time_series_chart_controller:
- p-2 → p-3, rounded-lg → rounded-xl
- remove border border-secondary
- add shadow-lg shadow-border-xs (theme-aware drop + border-edge)
- add explicit text-primary (was missing per #2011's drift note)
- add z-50 (matches goal_projection + sankey controllers)
sankey_chart_controller:
- bg-gray-700 text-white → bg-container text-primary (theme-aware;
was broken in light mode after dark-bg flip)
- p-2 rounded → p-3 rounded-xl
- add shadow-lg shadow-border-xs
- add font-sans for consistency with the other chart tooltips
- add privacy-sensitive class (was missing — sankey money values
were rendered in the clear with privacy mode on)
DS::Tooltip (icon-trigger help, bg-inverse) is intentionally a
different primitive and is not touched.
Refs #2011 — className consolidation into a shared module is tracked
separately and intentionally not closed by this PR; the new string
applies to two of the three call sites today (time_series, sankey).
The third (goal_projection_chart_controller) lives on the
feat/goals-v2-architecture branch and will adopt the same string when
goals v2 merges.
* fix(charts): align every chart tooltip on the borderless soft-shadow card
One visual contract for all three D3 tooltip surfaces, matching the
design reference: p-4, rounded-2xl, shadow-xl, no edge ring in light
mode. Dark mode keeps a 1px alpha-white ring since a shadow alone
disappears against dark surfaces.
- goal_projection_chart_controller drops its hand-copied class string
(it still carried the old bordered recipe — the drift this util
exists to prevent) and builds its two lines through the shared
factory: secondary date line, tabular value line.
- New content conventions exported alongside the container contract:
context line = text-xs text-secondary, values = font-medium
tabular-nums. Time-series and sankey adopt them.
- Sankey node titles now escape before .html(); user-named categories
were previously interpolated raw into the tooltip markup.
* fix(charts): match the tooltip surface to the design reference exactly
The previous pass approximated the reference with utility guesses
(rounded-2xl, p-4, shadow-xl, dark ring). The actual spec is a hairline
border ring composed with a soft 0 8px 24px drop shadow, 10px radius,
12x14 padding, and an 80ms left/top glide. Tailwind shadow utilities
can't compose a ring with a custom drop shadow, so the surface moves
into the design system as .chart-tooltip (theme-aware: dark swaps the
ring to alpha-white and lets it carry the edge).
Money/numeric figures also pick up the reference's mono treatment:
font-mono + tabular-nums on every value across time-series, sankey,
and goal-projection, so digits don't jitter while the scrubber moves.
* fix(charts): tighten tooltip padding to 10x12
* feat(charts): give sankey and goal tooltips their missing context rows
Chart tooltips answer three stacked questions: context (what am I
looking at), value (how much), relation (vs what). Time-series already
had all three; the other two were missing rows.
- Sankey links showed a bare "$X (Y%)" with no indication of which
flow was hovered. Links now lead with a swatch-dotted
"Source → Target" context line; nodes get the same dot + name
treatment, tying the card to the ribbon color. The context builder
escapes node names centrally (they're user-named categories).
- Goal projection adds a tertiary relation line — "52% of $20K
target" — computed from the payload the chart already carries, for
both the saved and projected segments. Hidden when the goal has no
positive target. Template is i18n-wired like the existing tooltip
strings (goals.show.projection.tooltip_target_relation).
Verified with Playwright against the running app: all three surfaces
pass computed-style and content assertions.
* fix(charts): drop the color dot from sankey tooltip context
The hover highlight on the diagram already identifies the ribbon; the
swatch repeated it inside the card. Names alone keep the context line
quieter.
* fix(charts): use the app's sans money treatment in tooltips, not mono
font-mono in this codebase marks code, keys, and admin surfaces; money
is sans + tabular-nums everywhere else (cards, KPIs, tables). Keep the
tabular figures for scrub stability, drop the mono.
* fix(charts): address review — glide opt-in, no shadowed var, truncate cap
- The 80ms left/top transition moved out of .chart-tooltip: it eased the
snap-positioned goal tooltip but made cursor-following tooltips
(sankey, time-series) trail the pointer by a frame. Goal projection
opts back in via inline style; the component comment documents the
split.
- setRelation reuses _draw()'s targetAmount const instead of declaring
a local 'target' that shadowed the target-date const.
- Sankey context line gets max-w-64 so truncate has a constraint to
fire against on deep flows.
- Component comment now says 10x12 padding, matching the declaration.
* Revert `schema.rb` changes
---------
Co-authored-by: Juan José Mata <jjmata@jjmata.com>
Closes#2011.
time-series and sankey each created their cursor-following tooltip with a
duplicated className literal that had already drifted apart: time-series was
missing `text-primary` and `z-50`. Move the visual contract into
app/javascript/utils/chart_tooltip.js as CHART_TOOLTIP_CLASSES and have both
controllers reference it. Each keeps its own behavioural classes (time-series
its initial `opacity-0`; both `top-0`; sankey toggles opacity via inline
style). `privacy-sensitive` stays bundled so future copies can't drop it.
Also exports a createChartTooltip factory for the raw-DOM idiom.
goal_projection_chart_controller is not in main yet (it lands with the goals
work in #1798); it migrates to the same symbol there.