Commit Graph

67 Commits

Author SHA1 Message Date
Anton Volnuhin
bda882d89a Fix eye button tap on touch devices in details panel
On touch devices, tapping an eye button in the details panel would
trigger chart mouseout → showDefaultView() which rebuilt the DOM
before the click event fired. Added pointerdown/pointerup guards
on the details box to prevent the race condition.

Also added @media (pointer: coarse) to always show eye buttons
on touch devices regardless of viewport width.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 01:01:00 +03:00
Anton Volnuhin
7e87a03b90 Fix home icon centering, eye icons on touch, tune landscape layout
- Center donut at 50% for compact landscape phones (was ~47%, misaligned
  with CSS center-label)
- Show eye buttons on touch devices via @media (pointer: coarse)
- Reduce right padding to 34px, narrow chart-wrapper to 49%

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 00:48:50 +03:00
Anton Volnuhin
3d7dc24a2d Landscape phone polish: fixed padding, compact header, cache-busting
- Replace safe-area-inset padding with fixed 42px right / 24px left
  (safe-area was 59px on both sides of iPhone Pro Max, too aggressive)
- Move center-label/eye-button hiding to height-based media query
  covering all landscape phones, not just >851px
- Add compact h1 (24px), smaller month-preview donuts (28px) for
  larger landscape phones
- Server: add Cache-Control: no-cache, strip query strings from URLs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 00:44:21 +03:00
Anton Volnuhin
2da9e3e3e7 Use pure safe-area-inset for landscape side padding
Just env(safe-area-inset-*) with 8px fallback — no extra base padding
on top. The inset values already provide sufficient clearance.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 23:44:10 +03:00
Anton Volnuhin
51a5d39c45 Reduce landscape side padding: 8px base (safe-area-inset handles the rest)
20px + safe-area was too much — the inset alone provides Dynamic Island
clearance, only need minimal base padding.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 23:43:12 +03:00
Anton Volnuhin
2d8cf00c3b Narrower donut container and safe-area side padding for landscape phones
- Chart wrapper 52% (was 58%) for visual separation from details box
- Container padding 20px + safe-area-inset on both sides to clear
  Dynamic Island in landscape
- Details box right offset includes safe-area-inset-right

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 23:42:07 +03:00
Anton Volnuhin
4508a0f143 Compact donut layout for larger landscape phones (iPhone Pro Max)
For viewports >850px wide but <=500px tall (landscape):
- Hide center label text (month/amount), keep home icon on drill-down
- Wider details panel (40vw), smaller fonts (12-13px)
- Tighter spacing to fit all content without clipping

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 23:38:12 +03:00
Anton Volnuhin
3a34d11548 Hide level 3 outside labels in compact donut mode
iPhone 17 Pro Max landscape is 956px wide, above the previous 950px
label threshold. Use isCompact flag instead of isMobile for hiding
level 3 outside labels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 23:33:24 +03:00
Anton Volnuhin
4a604d6d54 Fix compact donut detection: use height threshold for landscape phones
iPhone 17 Pro Max landscape viewport is ~956px wide, above the 850px
threshold. Use height <= 500px instead to detect all landscape phones
regardless of width.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 23:29:27 +03:00
Anton Volnuhin
029e428bb4 Landscape phone layout: compact donut, PWA support, safe-area insets
- Add compact donut mode for landscape phones (<=850px, landscape):
  wider radii (56%/93%/100%), no outside labels, bolder fonts
- Refine landscape CSS: smaller header (h1:20px), 55/45 chart/details
  split, compact month previews (22px), tighter spacing
- Add PWA standalone support: manifest.json, apple-mobile-web-app
  meta tags, viewport-fit=cover
- Add safe-area-inset padding for Dynamic Island and home indicator

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 23:25:35 +03:00
Anton Volnuhin
cc8b10dadb mid update 2026-02-07 22:54:12 +03:00
Anton Volnuhin
f99bb963e4 Responsive timeline layout: mobile legend below chart, orientation-aware breakpoints
- Move timeline legend from vertical top-right to horizontal bottom on portrait phones (<=850px + portrait)
- Landscape phones and tablets use desktop layout (vertical legend on right)
- CSS: cap chart-wrapper height with min(Xvw, calc(100dvh - 130px)) to prevent landscape overflow
- CSS: timeline-mode fills viewport height in portrait for better space utilization
- Rotate x-axis month labels to -90° on mobile for cleaner vertical display
- Add debounced resize handler to re-render on orientation/breakpoint changes
- Guard zrender click handler with y-bounds to prevent legend-zone false positives

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 19:53:30 +03:00
Anton Volnuhin
646c5959d1 Add Escape key to reset timeline legend filter
Extract resetLegendSelection into a reusable function exposed via
window._timelineResetLegend, allowing both the reset button click
and the Escape key handler to clear legend filtering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 18:15:54 +03:00
Anton Volnuhin
7e477269c0 Add Docker support for home server deployment
Support DATA_DIR env var for configurable CSV directory,
add docker-compose.yml and .dockerignore for containerized hosting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 18:15:32 +03:00
Anton Volnuhin
400c0ac765 Fix timeline reset label alignment and hover state 2026-02-06 20:07:48 +03:00
Anton Volnuhin
06fb6bf768 feat: add multi-level drill-down, browser history, and legend filtering to timeline
- Support 3-level drill: category → subcategory → microcategory
- Integrate browser back/forward with drill path and legend selection state
- Cmd-click isolates single series, Opt-click toggles series off
- Dynamic total labels update to reflect only visible series
- Add "Очистить" reset button when series are filtered
- Click month labels to switch to that month's donut view
- Persist timeline drill path in localStorage across reloads

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 19:17:05 +03:00
Anton Volnuhin
9b848610ae feat: move legend to top-right box with hover highlighting
- Move legend from bottom to vertical top-right box with background
- Highlight hovered category in legend (bold text, others dimmed)
- Dim legend color swatches to 0.15 opacity for non-hovered items
- Make drill-down title larger (22px bold centered)
- Reserve right margin (180px) for legend, free up bottom space

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 18:11:51 +03:00
Anton Volnuhin
b91aa65f61 feat: enhance timeline view with drill-down, category highlighting, and native labels
- Add drill-down into subcategories when clicking a category bar
- Use native ECharts emphasis/blur for category highlighting (focus: series)
- Show per-category labels on all bars via dispatchAction highlight
- Display total sum labels (к) above bars, ₽ on y-axis only
- Add color legend at bottom of chart
- Increase font sizes and angle x-axis labels for readability
- Remove details panel from timeline mode
- Clean up label management: no manual setOption race conditions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 17:58:08 +03:00
Anton Volnuhin
33a245728d Add timeline view with stacked bar chart and view switcher
Adds a second visualization mode showing spending across all months
as a stacked bar chart, with a месяц/таймлайн switcher in the header.
Includes side panel with category breakdowns, bar click-to-drill,
and localStorage persistence of the selected view.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 16:05:48 +03:00
Anton Volnuhin
e8c47a0773 fix: allow month switching while drilled down 2026-02-06 12:27:48 +03:00
Anton Volnuhin
44a97c2ca8 fix: preserve month and drill-down state across reload 2026-02-06 12:24:50 +03:00
Anton Volnuhin
95fea028d8 Remove primary indicator dot from multi-month selection
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 15:43:52 +03:00
Anton Volnuhin
3553ff6258 Rename page heading to Семейные траты
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 15:41:44 +03:00
Anton Volnuhin
c2166be06e Change multi-select to Cmd+click, Shift+click for interval
- Cmd/Ctrl+click: toggle individual months in/out of selection
- Shift+click: select contiguous interval from current to clicked month

This matches standard selection behavior in file managers and lists.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 15:40:54 +03:00
Anton Volnuhin
423844af3e Add multi-month selection with Shift+click
Hold Shift and click months to select multiple, showing aggregated
spending data. Normal click resets to single month selection.
Cannot deselect the last remaining month.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 15:36:16 +03:00
Anton Volnuhin
c192ac394d Make home icon bigger and remove shadow
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 18:38:40 +03:00
Anton Volnuhin
abc6ef2a9d Show home icon only on mobile with white background
- Home icon only appears on narrow screens (≤850px), not desktop
- Added white circular background with subtle shadow for readability
- Icon is larger (28px + padding) for easier touch targeting

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 18:36:50 +03:00
Anton Volnuhin
e29ff21747 Add home icon in donut center when drilled down
- Home icon appears in center only when at least one level deep
- Clicking the icon navigates back to root view
- On narrow screens (≤850px), shows only the home icon (label hidden)
- Black/white styling with hover effect
- Works on both desktop and mobile/touch devices

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 18:34:17 +03:00
Anton Volnuhin
0821d8f6f0 Hide donut eye icon and always show details eyes on narrow layouts
- Use !important to ensure chart eye btn is hidden on narrow (≤850px)
- Always show eye buttons in details panel on narrow layouts (opacity 0.5)
- Touch devices don't have hover, so eyes need to be visible by default
- Desktop (>850px) retains hover behavior for eye icons

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 18:29:46 +03:00
Anton Volnuhin
f6ae4aa3de Add mobile optimizations: smaller/bolder fonts, hide eye icon, center chart
- Smaller font sizes on mobile (10px/9px vs 13px/11px on desktop)
- Bolder font weight on mobile (600) for better readability
- Hide chart eye icon on narrow/stacked layouts (≤850px)
- Center chart at 50% when layout is stacked (≤850px)
- Dynamic font size/weight updates on resize

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 16:12:20 +03:00
Anton Volnuhin
d76e80dc02 Improve responsive chart scaling and hide center label earlier
- Scale chart layers on mobile (≤500px) to fill container while
  keeping same hole size as desktop (20%)
- Add resize handler to dynamically update proportions when crossing
  500px threshold
- Hide center label at 850px (stacked layout) instead of 500px to
  prevent overlap with chart
- Center chart at 50% on mobile since details box is below

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 15:57:16 +03:00
Anton Volnuhin
2b45a42b49 Hide center label on mobile and enlarge chart
- Hide center label on screens ≤500px (redundant with details box)
- Increase chart height to 95vw (500px) and 98vw (400px)
- Reduce container padding to minimize white space
- Adjust details box margin and max-height calculation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 15:30:40 +03:00
Anton Volnuhin
f01d7f791f Add mobile-optimized styles for iPhone 13 and 16 Pro Max
- Add 500px breakpoint: smaller fonts, tighter spacing, smaller
  month buttons and previews, center label adjustments
- Add 400px breakpoint for iPhone 13 (390px): even smaller fonts,
  reduced padding, compact details box styling
- Title now fits on one line at all mobile sizes
- Month navigator buttons all visible without cutoff
- Center label scales appropriately for small screens

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 15:27:09 +03:00
Anton Volnuhin
8fa8b32ad2 Fix scroll jumping in narrow layout when hovering subcategories
Use calc() to set details box max-height based on remaining viewport
space after chart (90lvw) and header (~140px). This prevents page
scrolling when hovering items with many subcategories - the details
box scrolls internally instead.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 15:21:10 +03:00
Anton Volnuhin
805d70cdf7 Remove max-height limit on details box in narrow layout
Allow details box to show all categories instead of being cut off
at 300px height on mobile/narrow screens.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 15:15:54 +03:00
Anton Volnuhin
a680943417 Improve responsive layout at medium screen widths
At 1200px and below, reduce chart width to 60% and increase details
box width to 38% (min 340px) to prevent amounts from being truncated.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 15:14:31 +03:00
Anton Volnuhin
aaa05bf2c9 Fix center label positioning in responsive layout
Added chart-wrapper div to contain both chart-container and center-label,
allowing the center-label to be positioned relative to the chart area
regardless of the overall layout (side-by-side or stacked).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 15:11:08 +03:00
Anton Volnuhin
c441d5979f Improve center label and details box styling
- Move center label from ECharts canvas to HTML overlay for better font rendering
- Style ₽ symbol separately with lighter color (#888) and slightly smaller size (20px)
- Use tighter line height (1.0) for center label
- Remove "Детали" heading from details box, use total as header
- Remove top border from details header
- Increase header font sizes to 20px
- Add more whitespace above "Top Items:"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 15:02:31 +03:00
Anton Volnuhin
fbbf94c3c4 Use consistent RUB formatting: integers with narrow no-break space
Add formatRUB() helper that formats amounts without decimals and uses
U+202F (narrow no-break space) as thousands separator and before ₽ symbol.
This prevents unwanted line breaks within currency amounts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 14:32:55 +03:00
Anton Volnuhin
3e0726d34f Add click-on-same-month to exit drill-down
Clicking on the already-selected month button now returns to root
view when drilled down, providing a quick way to reset the chart
without using browser back or center click.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 18:52:30 +03:00
Anton Volnuhin
d93c7c6051 Fix drill-down navigation and unknown subcategory colors
Bug A: Center click to go back now works after switching months while
drilled down. Fixed by saving root state BEFORE drilled state in
selectMonth, so historyIndex=0 always points to root.

Bug B: Unknown subcategories (not in December data) now get distinct
colors. Fixed by tracking unknownCount separately and using
(predefinedCount + unknownIndex) % 10 to assign colors starting after
the predefined palette positions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 18:47:45 +03:00
Anton Volnuhin
d934b5465b Add fixed subcategory order based on December 2025 data
- Add subcategoryOrder derived from subcategoryColors
- Add sortBySubcategoryOrder helper function
- Update click handler, transformDrillDownData, and mini-chart gradient
  to use fixed order instead of value-based sorting
- Update details box to preserve fixed order for drilled-down views
  while keeping value-based sorting for root level categories

This ensures subcategories maintain consistent positions when switching
months, even when their values differ (e.g., "Хобби Залины" always comes
before "Подписки" regardless of which has higher spending that month).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 18:36:59 +03:00
Anton Volnuhin
e8318166dd Fix consistent subcategory colors and mini-chart sync
- Add fixed subcategory color mapping based on December 2025 data
- Update click handler and transformDrillDownData to use getSubcategoryColor
- Rotate mini-charts 90° clockwise to match main chart orientation
- Change month selector active state from blue to neutral gray (#4a4a4a)
- Ensure colors stay consistent when switching months while drilled down

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 18:26:18 +03:00
Anton Volnuhin
b0983a751e feat: sync drill-down state across mini-charts and months
- Add currentDrillPath to track category hierarchy during drill-down
- Mini-charts now update to show the same category breakdown when
  drilling into a category on the main chart
- Switching months while drilled down preserves the category path,
  navigating to the same category in the new month
- Empty state shown for months that don't have the drilled category
- Browser back/forward navigation syncs mini-charts correctly

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 17:50:48 +03:00
Anton Volnuhin
0bc2725d4d Use system font with proper ₽ symbol and fix modal close behavior
- Switch to SF Pro / system font stack for consistent ₽ rendering
- Apply font to both HTML and ECharts center text
- Reset chart highlight and details panel when closing modal

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:29:27 +03:00
Anton Volnuhin
23b32fab31 Fix eye button hover and modal back button behavior
- Keep details panel showing sector info when hovering eye button
- Don't reset details when mouse moves from chart to eye button
- Close modals first when pressing browser back button

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:35:48 +03:00
Anton Volnuhin
58082e02f4 Add browser history integration for drill-down navigation
- Push drill-down states to browser history via history.pushState()
- Listen for popstate event to handle browser back/forward
- Mouse back/forward buttons and browser buttons now navigate drill-down
- Click center still works (calls history.back())
- Reset details panel when mouse leaves chart sector

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 19:48:58 +03:00
Anton Volnuhin
08db280f84 Add sortable transaction table with row detail modal
- Add custom column sorting (click headers to sort, click again to reverse)
- Add row click to open detail modal showing all transaction fields
- Row detail modal uses table layout with labels and values side by side
- Always show scrollbars, reset scroll position when modal opens
- Global escape key handler closes detail modal first, then main modal

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 19:31:18 +03:00
Anton Volnuhin
bd6b73b389 Fix header blinking on hover by tracking section state
- Set isInsideSection=true for all depth levels (1, 2, and others)
- Only reset to default view if not inside a section
- Prevents mouseout from resetting header when moving between sectors

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 19:04:15 +03:00
Anton Volnuhin
12b8b74f38 Show drilled-down sector name in details header
When clicking into a sector to drill down, the details header now shows
the sector name instead of the month name. The contextName parameter is
passed from the click handler to setupHoverEvents.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 19:01:43 +03:00