1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-22 06:39:39 +02:00

Maybe Design System Updates (#1856)

* Add geist font

* Design system css file

* Add cursor ui/ux rules

* Add shadows and shadow borders

* Replace primitives with tokens for common text and backgrounds

* Organize css

* Update switch and checkbox class names

* Add back global color variables
This commit is contained in:
Zach Gollwitzer 2025-02-13 11:31:07 -05:00 committed by GitHub
parent c0e290a07e
commit 849c58dd3e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
193 changed files with 1356 additions and 1073 deletions

View file

@ -0,0 +1,13 @@
---
description: This file describes Maybe's design system and how views should be styled
globs: app/views/**,app/helpers/**,app/javascript/controllers/**
---
Use this rule whenever you are writing html, css, or even styles in Stimulus controllers that use D3.js.
The codebase uses TailwindCSS v4.x (the newest version) with a custom design system defined in [maybe-design-system.css](mdc:app/assets/tailwind/maybe-design-system.css)
- Always start by referencing [maybe-design-system.css](mdc:app/assets/tailwind/maybe-design-system.css) to see the base primitives and tokens we use in the codebase
- Always generate semantic HTML
- Never create new styles in [maybe-design-system.css](mdc:app/assets/tailwind/maybe-design-system.css) or [application.css](mdc:app/assets/tailwind/application.css) without explicitly receiving permission to do so
- Always favor the "utility first" Tailwind approach. Reusable style classes should not be created often. Code should be reused primarily through ERB partials.
- Always prefer using the utility "tokens" defined in [maybe-design-system.css](mdc:app/assets/tailwind/maybe-design-system.css) when possible. For example, use `text-primary` rather than `text-gray-900`.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,389 +1,13 @@
@import 'tailwindcss'; @import 'tailwindcss';
@import "./maybe-design-system.css";
@import "./geist-font.css";
@import "./geist-mono-font.css";
@plugin "@tailwindcss/typography"; @plugin "@tailwindcss/typography";
@plugin "@tailwindcss/forms"; @plugin "@tailwindcss/forms";
@theme {
/* Base colors */
--color-white: #ffffff;
--color-black: #0B0B0B;
--color-success: #10A861;
--color-warning: #F79009;
--color-error: #F13636;
/* Gray scale */
--color-gray-25: #FAFAFA;
--color-gray-50: #F5F5F5;
--color-gray-100: #F0F0F0;
--color-gray-200: #E5E5E5;
--color-gray-300: #D6D6D6;
--color-gray-400: #A3A3A3;
--color-gray-500: #737373;
--color-gray-600: #525252;
--color-gray-700: #3D3D3D;
--color-gray-800: #212121;
--color-gray-900: #141414;
/* Alpha colors */
--color-alpha-white-25: rgba(255, 255, 255, 0.03);
--color-alpha-white-50: rgba(255, 255, 255, 0.05);
--color-alpha-white-100: rgba(255, 255, 255, 0.08);
--color-alpha-white-200: rgba(255, 255, 255, 0.1);
--color-alpha-white-300: rgba(255, 255, 255, 0.15);
--color-alpha-white-400: rgba(255, 255, 255, 0.2);
--color-alpha-white-500: rgba(255, 255, 255, 0.3);
--color-alpha-white-600: rgba(255, 255, 255, 0.4);
--color-alpha-white-700: rgba(255, 255, 255, 0.5);
--color-alpha-white-800: rgba(255, 255, 255, 0.6);
--color-alpha-white-900: rgba(255, 255, 255, 0.7);
--color-alpha-black-25: rgba(11, 11, 11, 0.03);
--color-alpha-black-50: rgba(11, 11, 11, 0.05);
--color-alpha-black-100: rgba(11, 11, 11, 0.08);
--color-alpha-black-200: rgba(11, 11, 11, 0.1);
--color-alpha-black-300: rgba(11, 11, 11, 0.15);
--color-alpha-black-400: rgba(11, 11, 11, 0.2);
--color-alpha-black-500: rgba(11, 11, 11, 0.3);
--color-alpha-black-600: rgba(11, 11, 11, 0.4);
--color-alpha-black-700: rgba(11, 11, 11, 0.5);
--color-alpha-black-800: rgba(11, 11, 11, 0.6);
--color-alpha-black-900: rgba(11, 11, 11, 0.7);
/* Red scale */
--color-red-25: #FFFBFB;
--color-red-50: #FFF1F0;
--color-red-100: #FFDEDB;
--color-red-200: #FEB9B3;
--color-red-300: #F88C86;
--color-red-400: #ED4E4E;
--color-red-500: #F13636;
--color-red-600: #EC2222;
--color-red-700: #C91313;
--color-red-800: #A40E0E;
--color-red-900: #7E0707;
/* Green scale */
--color-green-25: #F6FEF9;
--color-green-50: #ECFDF3;
--color-green-100: #D1FADF;
--color-green-200: #A6F4C5;
--color-green-300: #6CE9A6;
--color-green-400: #32D583;
--color-green-500: #12B76A;
--color-green-600: #10A861;
--color-green-700: #078C52;
--color-green-800: #05603A;
--color-green-900: #054F31;
/* Yellow scale */
--color-yellow-25: #FFFCF5;
--color-yellow-50: #FFFAEB;
--color-yellow-100: #FEF0C7;
--color-yellow-200: #FEDF89;
--color-yellow-300: #FEC84B;
--color-yellow-400: #FDB022;
--color-yellow-500: #F79009;
--color-yellow-600: #DC6803;
--color-yellow-700: #B54708;
--color-yellow-800: #93370D;
--color-yellow-900: #7A2E0E;
/* Cyan scale */
--color-cyan-25: #F5FEFF;
--color-cyan-50: #ECFDFF;
--color-cyan-100: #CFF9FE;
--color-cyan-200: #A5F0FC;
--color-cyan-300: #67E3F9;
--color-cyan-400: #22CCEE;
--color-cyan-500: #06AED4;
--color-cyan-600: #088AB2;
--color-cyan-700: #0E7090;
--color-cyan-800: #155B75;
--color-cyan-900: #155B75;
/* Blue scale */
--color-blue-25: #F5FAFF;
--color-blue-50: #EFF8FF;
--color-blue-100: #D1E9FF;
--color-blue-200: #B2DDFF;
--color-blue-300: #84CAFF;
--color-blue-400: #53B1FD;
--color-blue-500: #2E90FA;
--color-blue-600: #1570EF;
--color-blue-700: #175CD3;
--color-blue-800: #1849A9;
--color-blue-900: #194185;
/* Indigo scale */
--color-indigo-25: #F5F8FF;
--color-indigo-50: #EFF4FF;
--color-indigo-100: #E0EAFF;
--color-indigo-200: #C7D7FE;
--color-indigo-300: #A4BCFD;
--color-indigo-400: #8098F9;
--color-indigo-500: #6172F3;
--color-indigo-600: #444CE7;
--color-indigo-700: #3538CD;
--color-indigo-800: #2D31A6;
--color-indigo-900: #2D3282;
/* Violet scale */
--color-violet-25: #FBFAFF;
--color-violet-50: #F5F3FF;
--color-violet-100: #ECE9FE;
--color-violet-200: #DDD6FE;
--color-violet-300: #C3B5FD;
--color-violet-400: #A48AFB;
--color-violet-500: #875BF7;
--color-violet-600: #7839EE;
--color-violet-700: #6927DA;
/* Fuchsia scale */
--color-fuchsia-25: #FEFAFF;
--color-fuchsia-50: #FDF4FF;
--color-fuchsia-100: #FBE8FF;
--color-fuchsia-200: #F6D0FE;
--color-fuchsia-300: #EEAAFD;
--color-fuchsia-400: #E478FA;
--color-fuchsia-500: #D444F1;
--color-fuchsia-600: #BA24D5;
--color-fuchsia-700: #9F1AB1;
--color-fuchsia-800: #821890;
--color-fuchsia-900: #6F1877;
/* Pink scale */
--color-pink-25: #FFFAFC;
--color-pink-50: #FEF0F7;
--color-pink-100: #FFD1E2;
--color-pink-200: #FFB1CE;
--color-pink-300: #FD8FBA;
--color-pink-400: #F86BA7;
--color-pink-500: #F23E94;
--color-pink-600: #D5327F;
--color-pink-700: #BA256B;
--color-pink-800: #9E1958;
--color-pink-900: #840B45;
/* Orange scale */
--color-orange-25: #FFF9F5;
--color-orange-50: #FFF4ED;
--color-orange-100: #FFE6D5;
--color-orange-200: #FFD6AE;
--color-orange-300: #FF9C66;
--color-orange-400: #FF692E;
--color-orange-500: #FF4405;
--color-orange-600: #E62E05;
--color-orange-700: #BC1B06;
--color-orange-800: #97180C;
--color-orange-900: #771A0D;
/* Shadows */
--shadow-none: 0 0 #0000;
--shadow-xs: 0px 1px 2px 0px rgba(11, 11, 11, 0.05);
--shadow-sm: 0px 1px 2px 0px rgba(11, 11, 11, 0.06), 0px 1px 3px 0px rgba(11, 11, 11, 0.10);
--shadow-md: 0px 2px 4px -2px rgba(11, 11, 11, 0.06), 0px 4px 8px -2px rgba(11, 11, 11, 0.10);
--shadow-lg: 0px 4px 6px -2px rgba(11, 11, 11, 0.03), 0px 12px 16px -4px rgba(11, 11, 11, 0.08);
--shadow-xl: 0px 8px 8px -4px rgba(11, 11, 11, 0.03), 0px 20px 24px -4px rgba(11, 11, 11, 0.08);
--shadow-2xl: 0px 24px 48px -12px rgba(11, 11, 11, 0.12);
--shadow-3xl: 0px 32px 64px -12px rgba(11, 11, 11, 0.14);
/* Border radius */
--border-radius-none: 0;
--border-radius-full: 9999px;
--border-radius-xs: 2px;
--border-radius-sm: 4px;
--border-radius-md: 8px;
--border-radius-lg: 10px;
--border-radius-xl: 12px;
--border-radius-2xl: 16px;
--border-radius-3xl: 24px;
}
.form-field {
@apply flex flex-col gap-1 relative px-3 py-2 rounded-md border bg-white border-alpha-black-100 shadow-xs w-full;
@apply focus-within:border-gray-900 focus-within:shadow-none focus-within:ring-4 focus-within:ring-gray-100;
}
.form-field__label {
@apply block text-xs text-gray-500 peer-disabled:text-gray-400;
}
.hw-combobox__label {
@apply block text-xs text-gray-500 peer-disabled:text-gray-400;
}
.form-field__input {
@apply border-none bg-transparent text-sm opacity-100 w-full p-0;
@apply focus:opacity-100 focus:outline-hidden focus:ring-0;
@apply placeholder-shown:opacity-50;
@apply disabled:text-gray-400;
@apply text-ellipsis overflow-hidden whitespace-nowrap;
&select {
@apply pr-8;
}
}
.form-field__radio {
@apply text-gray-900;
}
.form-field__submit {
@apply cursor-pointer rounded-lg bg-black p-3 text-center text-white hover:bg-gray-700;
}
.toggle-switch-dot {
input:checked + label + & {
transform: translateX(100%);
}
}
.maybe-checkbox {
&[type='checkbox'] {
@apply rounded-sm;
}
}
.maybe-checkbox--light {
&[type='checkbox'] {
@apply border-alpha-black-200 checked:bg-gray-900 checked:ring-gray-900 focus:ring-gray-900 focus-visible:ring-gray-900 checked:hover:bg-gray-500;
}
&[type='checkbox']:disabled {
@apply cursor-not-allowed opacity-80 bg-gray-50 border-gray-200 checked:bg-gray-400 checked:ring-gray-400;
}
}
.maybe-checkbox--dark {
&[type='checkbox'] {
@apply ring-gray-900 checked:text-white;
}
&[type='checkbox']:disabled {
@apply cursor-not-allowed opacity-80 ring-gray-600;
}
&[type='checkbox']:checked {
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='111827' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
}
}
.maybe-switch {
@apply block bg-gray-100 w-9 h-5 rounded-full cursor-pointer;
@apply after:content-[''] after:block after:absolute after:top-0.5 after:left-0.5 after:bg-white after:w-4 after:h-4 after:rounded-full after:transition-transform after:duration-300 after:ease-in-out;
@apply peer-checked:bg-green-600 peer-checked:after:translate-x-4;
}
.prose {
@apply max-w-none;
h2 {
@apply text-xl font-medium;
}
h3 {
@apply text-lg font-medium;
}
li {
@apply m-0;
}
details {
@apply mb-4 rounded-xl mt-3.5;
}
summary {
@apply flex items-center gap-1;
}
video {
@apply m-0 rounded-b-xl;
}
}
.prose--github-release-notes {
.octicon {
@apply inline-block overflow-visible align-text-bottom fill-current;
}
.dropdown-caret {
@apply content-none border-4 border-b-0 border-transparent border-t-gray-500 size-0 inline-block;
}
.user-mention {
@apply font-bold;
}
}
.tooltip {
@apply hidden absolute;
}
.btn {
@apply px-3 py-2 rounded-lg text-sm font-medium cursor-pointer disabled:cursor-not-allowed focus:outline-gray-500;
}
.btn--primary {
@apply bg-gray-900 text-white hover:bg-gray-700 disabled:bg-gray-50 disabled:hover:bg-gray-50 disabled:text-gray-400;
}
.btn--secondary {
@apply bg-gray-50 hover:bg-gray-100 text-gray-900;
}
.btn--outline {
@apply border border-alpha-black-200 text-gray-900 hover:bg-gray-50 disabled:bg-gray-50 disabled:hover:bg-gray-50 disabled:text-gray-400;
}
.btn--ghost {
@apply border border-transparent text-gray-900 hover:bg-gray-50;
}
.scrollbar {
&::-webkit-scrollbar {
width: 4px;
}
&::-webkit-scrollbar-thumb {
background: #d6d6d6;
border-radius: 10px;
}
&::-webkit-scrollbar-thumb:hover {
background: #a6a6a6;
}
}
/* Reset rules, default styles applied to plain HTML */
@layer base {
details>summary::-webkit-details-marker {
@apply hidden;
}
details>summary {
@apply list-none;
}
}
@layer components {
select[multiple="multiple"] {
@apply py-2 pr-2 space-y-0.5 overflow-y-auto;
}
select[multiple="multiple"] option {
@apply py-2 rounded-md;
}
select[multiple="multiple"] option:checked {
@apply after:content-['\2713'] bg-white after:text-gray-500 after:ml-2;
}
select[multiple="multiple"] option:active,
select[multiple="multiple"] option:focus {
@apply bg-white;
}
}
@utility combobox { @utility combobox {
.hw-combobox__main__wrapper, .hw-combobox__main__wrapper,
.hw-combobox__input { .hw-combobox__input {
@ -398,6 +22,10 @@
@apply absolute top-[160%] right-0 w-full bg-transparent rounded z-30; @apply absolute top-[160%] right-0 w-full bg-transparent rounded z-30;
} }
.hw-combobox__label {
@apply block text-xs text-gray-500 peer-disabled:text-gray-400;
}
.hw_combobox__pagination__wrapper { .hw_combobox__pagination__wrapper {
@apply h-px; @apply h-px;
@ -412,6 +40,20 @@
--hw-handle-offset-right: 0px; --hw-handle-offset-right: 0px;
} }
.prose--github-release-notes {
.octicon {
@apply inline-block overflow-visible align-text-bottom fill-current;
}
.dropdown-caret {
@apply content-none border-4 border-b-0 border-transparent border-t-gray-500 size-0 inline-block;
}
.user-mention {
@apply font-bold;
}
}
/* Custom scrollbar implementation for Windows browsers */ /* Custom scrollbar implementation for Windows browsers */
.windows { .windows {
::-webkit-scrollbar { ::-webkit-scrollbar {
@ -427,3 +69,18 @@
background: #a6a6a6; background: #a6a6a6;
} }
} }
.scrollbar {
&::-webkit-scrollbar {
width: 4px;
}
&::-webkit-scrollbar-thumb {
background: #d6d6d6;
border-radius: 10px;
}
&::-webkit-scrollbar-thumb:hover {
background: #a6a6a6;
}
}

View file

@ -0,0 +1,83 @@
/* Variable font */
@font-face {
font-family: 'Geist';
src: url('../fonts/geist/Geist[wght].woff2') format('woff2-variations');
font-weight: 100 900;
font-style: normal;
font-display: swap;
}
/* Static fonts (fallback) */
@supports not (font-variation-settings: normal) {
@font-face {
font-family: 'Geist';
src: url('../fonts/geist/Geist-Thin.woff2') format('woff2');
font-weight: 100;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist';
src: url('../fonts/geist/Geist-ExtraLight.woff2') format('woff2');
font-weight: 200;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist';
src: url('../fonts/geist/Geist-Light.woff2') format('woff2');
font-weight: 300;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist';
src: url('../fonts/geist/Geist-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist';
src: url('../fonts/geist/Geist-Medium.woff2') format('woff2');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist';
src: url('../fonts/geist/Geist-SemiBold.woff2') format('woff2');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist';
src: url('../fonts/geist/Geist-Bold.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist';
src: url('../fonts/geist/Geist-ExtraBold.woff2') format('woff2');
font-weight: 800;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist';
src: url('../fonts/geist/Geist-Black.woff2') format('woff2');
font-weight: 900;
font-style: normal;
font-display: swap;
}
}

View file

@ -0,0 +1,83 @@
/* Variable font */
@font-face {
font-family: 'Geist Mono';
src: url('../fonts/geist_mono/GeistMono[wght].woff2') format('woff2-variations');
font-weight: 100 950;
font-style: normal;
font-display: swap;
}
/* Static fonts (fallback) */
@supports not (font-variation-settings: normal) {
@font-face {
font-family: 'Geist Mono';
src: url('../fonts/geist_mono/GeistMono-Thin.woff2') format('woff2');
font-weight: 100;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist Mono';
src: url('../fonts/geist_mono/GeistMono-UltraLight.woff2') format('woff2');
font-weight: 200;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist Mono';
src: url('../fonts/geist_mono/GeistMono-Light.woff2') format('woff2');
font-weight: 300;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist Mono';
src: url('../fonts/geist_mono/GeistMono-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist Mono';
src: url('../fonts/geist_mono/GeistMono-Medium.woff2') format('woff2');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist Mono';
src: url('../fonts/geist_mono/GeistMono-SemiBold.woff2') format('woff2');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist Mono';
src: url('../fonts/geist_mono/GeistMono-Bold.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist Mono';
src: url('../fonts/geist_mono/GeistMono-Black.woff2') format('woff2');
font-weight: 900;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Geist Mono';
src: url('../fonts/geist_mono/GeistMono-UltraBlack.woff2') format('woff2');
font-weight: 950;
font-style: normal;
font-display: swap;
}
}

View file

@ -0,0 +1,448 @@
/*
This file contains all of the Figma design tokens, components, etc. that
are used globally across the app.
One-off styling (3rd party overrides, etc.) should be done in the application.css file.
*/
@theme {
/* Font families */
--font-sans: 'Geist', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
--font-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
/* Base colors */
--color-white: #ffffff;
--color-black: #0B0B0B;
--color-success: var(--color-green-600);
--color-warning: var(--color-yellow-600);
--color-destructive: var(--color-red-600);
/* Gray scale */
--color-gray-25: #FAFAFA;
--color-gray-50: #F7F7F7;
--color-gray-100: #F0F0F0;
--color-gray-200: #E7E7E7;
--color-gray-300: #CFCFCF;
--color-gray-400: #9E9E9E;
--color-gray-500: #737373;
--color-gray-600: #5C5C5C;
--color-gray-700: #363636;
--color-gray-800: #242424;
--color-gray-900: #171717;
--color-gray: var(--color-gray-500);
--color-gray-tint-5: --alpha(var(--color-gray-500) / 5%);
--color-gray-tint-10: --alpha(var(--color-gray-500) / 10%);
/* Alpha colors */
--color-alpha-white-25: --alpha(var(--color-white) / 3%);
--color-alpha-white-50: --alpha(var(--color-white) / 5%);
--color-alpha-white-100: --alpha(var(--color-white) / 8%);
--color-alpha-white-200: --alpha(var(--color-white) / 10%);
--color-alpha-white-300: --alpha(var(--color-white) / 15%);
--color-alpha-white-400: --alpha(var(--color-white) / 20%);
--color-alpha-white-500: --alpha(var(--color-white) / 30%);
--color-alpha-white-600: --alpha(var(--color-white) / 40%);
--color-alpha-white-700: --alpha(var(--color-white) / 50%);
--color-alpha-white-800: --alpha(var(--color-white) / 70%);
--color-alpha-white-900: --alpha(var(--color-white) / 85%);
--color-alpha-black-25: --alpha(var(--color-black) / 3%);
--color-alpha-black-50: --alpha(var(--color-black) / 5%);
--color-alpha-black-100: --alpha(var(--color-black) / 8%);
--color-alpha-black-200: --alpha(var(--color-black) / 10%);
--color-alpha-black-300: --alpha(var(--color-black) / 15%);
--color-alpha-black-400: --alpha(var(--color-black) / 20%);
--color-alpha-black-500: --alpha(var(--color-black) / 30%);
--color-alpha-black-600: --alpha(var(--color-black) / 40%);
--color-alpha-black-700: --alpha(var(--color-black) / 50%);
--color-alpha-black-800: --alpha(var(--color-black) / 70%);
--color-alpha-black-900: --alpha(var(--color-black) / 85%);
/* Red scale */
--color-red-25: #FFFBFB;
--color-red-50: #FFF1F0;
--color-red-100: #FFDEDB;
--color-red-200: #FEB9B3;
--color-red-300: #F88C86;
--color-red-400: #ED4E4E;
--color-red-500: #F13636;
--color-red-600: #EC2222;
--color-red-700: #C91313;
--color-red-800: #A40E0E;
--color-red-900: #7E0707;
--color-red-tint-5: --alpha(var(--color-red-500) / 5%);
--color-red-tint-10: --alpha(var(--color-red-500) / 10%);
/* Green scale */
--color-green-25: #F6FEF9;
--color-green-50: #ECFDF3;
--color-green-100: #D1FADF;
--color-green-200: #A6F4C5;
--color-green-300: #6CE9A6;
--color-green-400: #32D583;
--color-green-500: #12B76A;
--color-green-600: #10A861;
--color-green-700: #078C52;
--color-green-800: #05603A;
--color-green-900: #054F31;
--color-green-tint-5: --alpha(var(--color-green-500) / 5%);
--color-green-tint-10: --alpha(var(--color-green-500) / 10%);
/* Yellow scale */
--color-yellow-25: #FFFCF5;
--color-yellow-50: #FFFAEB;
--color-yellow-100: #FEF0C7;
--color-yellow-200: #FEDF89;
--color-yellow-300: #FEC84B;
--color-yellow-400: #FDB022;
--color-yellow-500: #F79009;
--color-yellow-600: #DC6803;
--color-yellow-700: #B54708;
--color-yellow-800: #93370D;
--color-yellow-900: #7A2E0E;
--color-yellow-tint-5: --alpha(var(--color-yellow-500) / 5%);
--color-yellow-tint-10: --alpha(var(--color-yellow-500) / 10%);
/* Cyan scale */
--color-cyan-25: #F5FEFF;
--color-cyan-50: #ECFDFF;
--color-cyan-100: #CFF9FE;
--color-cyan-200: #A5F0FC;
--color-cyan-300: #67E3F9;
--color-cyan-400: #22CCEE;
--color-cyan-500: #06AED4;
--color-cyan-600: #088AB2;
--color-cyan-700: #0E7090;
--color-cyan-800: #155B75;
--color-cyan-900: #155B75;
--color-cyan-tint-5: --alpha(var(--color-cyan-500) / 5%);
--color-cyan-tint-10: --alpha(var(--color-cyan-500) / 10%);
/* Blue scale */
--color-blue-25: #F5FAFF;
--color-blue-50: #EFF8FF;
--color-blue-100: #D1E9FF;
--color-blue-200: #B2DDFF;
--color-blue-300: #84CAFF;
--color-blue-400: #53B1FD;
--color-blue-500: #2E90FA;
--color-blue-600: #1570EF;
--color-blue-700: #175CD3;
--color-blue-800: #1849A9;
--color-blue-900: #194185;
--color-blue-tint-5: --alpha(var(--color-blue-500) / 5%);
--color-blue-tint-10: --alpha(var(--color-blue-500) / 10%);
/* Indigo scale */
--color-indigo-25: #F5F8FF;
--color-indigo-50: #EFF4FF;
--color-indigo-100: #E0EAFF;
--color-indigo-200: #C7D7FE;
--color-indigo-300: #A4BCFD;
--color-indigo-400: #8098F9;
--color-indigo-500: #6172F3;
--color-indigo-600: #444CE7;
--color-indigo-700: #3538CD;
--color-indigo-800: #2D31A6;
--color-indigo-900: #2D3282;
--color-indigo-tint-5: --alpha(var(--color-indigo-500) / 5%);
--color-indigo-tint-10: --alpha(var(--color-indigo-500) / 10%);
/* Violet scale */
--color-violet-25: #FBFAFF;
--color-violet-50: #F5F3FF;
--color-violet-100: #ECE9FE;
--color-violet-200: #DDD6FE;
--color-violet-300: #C3B5FD;
--color-violet-400: #A48AFB;
--color-violet-500: #875BF7;
--color-violet-600: #7839EE;
--color-violet-700: #6927DA;
--color-violet-tint-5: --alpha(var(--color-violet-500) / 5%);
--color-violet-tint-10: --alpha(var(--color-violet-500) / 10%);
/* Fuchsia scale */
--color-fuchsia-25: #FEFAFF;
--color-fuchsia-50: #FDF4FF;
--color-fuchsia-100: #FBE8FF;
--color-fuchsia-200: #F6D0FE;
--color-fuchsia-300: #EEAAFD;
--color-fuchsia-400: #E478FA;
--color-fuchsia-500: #D444F1;
--color-fuchsia-600: #BA24D5;
--color-fuchsia-700: #9F1AB1;
--color-fuchsia-800: #821890;
--color-fuchsia-900: #6F1877;
--color-fuchsia-tint-5: --alpha(var(--color-fuchsia-500) / 5%);
--color-fuchsia-tint-10: --alpha(var(--color-fuchsia-500) / 10%);
/* Pink scale */
--color-pink-25: #FFFAFC;
--color-pink-50: #FEF0F7;
--color-pink-100: #FFD1E2;
--color-pink-200: #FFB1CE;
--color-pink-300: #FD8FBA;
--color-pink-400: #F86BA7;
--color-pink-500: #F23E94;
--color-pink-600: #D5327F;
--color-pink-700: #BA256B;
--color-pink-800: #9E1958;
--color-pink-900: #840B45;
--color-pink-tint-5: --alpha(var(--color-pink-500) / 5%);
--color-pink-tint-10: --alpha(var(--color-pink-500) / 10%);
/* Orange scale */
--color-orange-25: #FFF9F5;
--color-orange-50: #FFF4ED;
--color-orange-100: #FFE6D5;
--color-orange-200: #FFD6AE;
--color-orange-300: #FF9C66;
--color-orange-400: #FF692E;
--color-orange-500: #FF4405;
--color-orange-600: #E62E05;
--color-orange-700: #BC1B06;
--color-orange-800: #97180C;
--color-orange-900: #771A0D;
--color-orange-tint-5: --alpha(var(--color-orange-500) / 5%);
--color-orange-tint-10: --alpha(var(--color-orange-500) / 10%);
/* Border radius overrides */
--border-radius-md: 8px;
--border-radius-lg: 10px;
--shadow-xs: 0px 1px 2px 0px --alpha(var(--color-black) / 6%);
--shadow-sm: 0px 1px 6px 0px --alpha(var(--color-black) / 6%);
--shadow-md: 0px 4px 8px -2px --alpha(var(--color-black) / 6%);
--shadow-lg: 0px 12px 16px -4px --alpha(var(--color-black) / 6%);
--shadow-xl: 0px 20px 24px -4px --alpha(var(--color-black) / 6%);
}
/* Custom shadow borders used for surfaces / containers */
@utility shadow-border-xs {
box-shadow: var(--shadow-xs), 0px 0px 0px 1px var(--color-alpha-black-50);
}
@utility shadow-border-sm {
box-shadow: var(--shadow-sm), 0px 0px 0px 1px var(--color-alpha-black-50);
}
@utility shadow-border-md {
box-shadow: var(--shadow-md), 0px 0px 0px 1px var(--color-alpha-black-50);
}
@utility shadow-border-lg {
box-shadow: var(--shadow-lg), 0px 0px 0px 1px var(--color-alpha-black-50);
}
@utility shadow-border-xl {
box-shadow: var(--shadow-xl), 0px 0px 0px 1px var(--color-alpha-black-50);
}
/* Design system color utilities */
@utility text-primary {
@apply text-gray-900;
}
@utility text-secondary {
@apply text-gray-500;
}
@utility text-subdued {
@apply text-gray-400;
}
@utility text-link {
@apply text-blue-600;
}
@utility bg-surface {
@apply bg-gray-50 hover:bg-gray-100;
}
@utility bg-surface-inset {
@apply bg-gray-100 hover:bg-gray-200;
}
@utility bg-container {
@apply bg-white hover:bg-gray-50;
}
@utility bg-container-inset {
@apply bg-gray-50 hover:bg-gray-100;
}
@utility bg-inverse {
@apply bg-gray-800 hover:bg-gray-700;
}
@utility bg-overlay {
@apply bg-alpha-black-200;
}
@utility border-primary {
@apply border-alpha-black-300;
}
@utility border-secondary {
@apply border-alpha-black-200;
}
@utility border-tertiary {
@apply border-alpha-black-100;
}
@layer base {
details>summary::-webkit-details-marker {
@apply hidden;
}
details>summary {
@apply list-none;
}
select[multiple="multiple"] {
@apply py-2 pr-2 space-y-0.5 overflow-y-auto;
}
select[multiple="multiple"] option {
@apply py-2 rounded-md;
}
select[multiple="multiple"] option:checked {
@apply after:content-['\2713'] bg-white after:text-gray-500 after:ml-2;
}
select[multiple="multiple"] option:active,
select[multiple="multiple"] option:focus {
@apply bg-white;
}
}
@layer components {
/* Buttons */
.btn {
@apply px-3 py-2 rounded-lg text-sm font-medium cursor-pointer disabled:cursor-not-allowed focus:outline-gray-500;
}
.btn--primary {
@apply bg-gray-900 text-white hover:bg-gray-700 disabled:bg-gray-50 disabled:hover:bg-gray-50 disabled:text-gray-400;
}
.btn--secondary {
@apply bg-gray-50 hover:bg-gray-100 text-gray-900;
}
.btn--outline {
@apply border border-alpha-black-200 text-gray-900 hover:bg-gray-50 disabled:bg-gray-50 disabled:hover:bg-gray-50 disabled:text-gray-400;
}
.btn--ghost {
@apply border border-transparent text-gray-900 hover:bg-gray-50;
}
.btn--destructive {
@apply bg-red-500 text-white hover:bg-red-600 disabled:bg-red-50 disabled:hover:bg-red-50 disabled:text-red-400;
}
/* Forms */
.form-field {
@apply flex flex-col gap-1 relative px-3 py-2 rounded-md border bg-white border-alpha-black-100 shadow-xs w-full;
@apply focus-within:border-gray-900 focus-within:shadow-none focus-within:ring-4 focus-within:ring-gray-100;
}
.form-field__label {
@apply block text-xs text-gray-500 peer-disabled:text-gray-400;
}
.form-field__input {
@apply border-none bg-transparent text-sm opacity-100 w-full p-0;
@apply focus:opacity-100 focus:outline-hidden focus:ring-0;
@apply placeholder-shown:opacity-50;
@apply disabled:text-gray-400;
@apply text-ellipsis overflow-hidden whitespace-nowrap;
&select {
@apply pr-8;
}
}
.form-field__radio {
@apply text-gray-900;
}
.form-field__submit {
@apply cursor-pointer rounded-lg bg-black p-3 text-center text-white hover:bg-gray-700;
}
/* Checkboxes */
.checkbox {
&[type='checkbox'] {
@apply rounded-sm;
}
}
.checkbox--light {
&[type='checkbox'] {
@apply border-alpha-black-200 checked:bg-gray-900 checked:ring-gray-900 focus:ring-gray-900 focus-visible:ring-gray-900 checked:hover:bg-gray-500;
}
&[type='checkbox']:disabled {
@apply cursor-not-allowed opacity-80 bg-gray-50 border-gray-200 checked:bg-gray-400 checked:ring-gray-400;
}
}
.checkbox--dark {
&[type='checkbox'] {
@apply ring-gray-900 checked:text-white;
}
&[type='checkbox']:disabled {
@apply cursor-not-allowed opacity-80 ring-gray-600;
}
&[type='checkbox']:checked {
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='111827' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
}
}
/* Switches */
.switch {
@apply block bg-gray-100 w-9 h-5 rounded-full cursor-pointer;
@apply after:content-[''] after:block after:absolute after:top-0.5 after:left-0.5 after:bg-white after:w-4 after:h-4 after:rounded-full after:transition-transform after:duration-300 after:ease-in-out;
@apply peer-checked:bg-green-600 peer-checked:after:translate-x-4;
}
/* Typography */
.prose {
@apply max-w-none;
h2 {
@apply text-xl font-medium;
}
h3 {
@apply text-lg font-medium;
}
li {
@apply m-0;
}
details {
@apply mb-4 rounded-xl mt-3.5;
}
summary {
@apply flex items-center gap-1;
}
video {
@apply m-0 rounded-b-xl;
}
}
/* Tooltips */
.tooltip {
@apply hidden absolute;
}
}

View file

@ -76,12 +76,12 @@ module AccountsHelper
{ {
"CreditCard" => { text: "text-red-500", bg: "bg-red-500", bg_transparent: "bg-red-500/10", fill: "fill-red-500", hex: "#F13636" }, "CreditCard" => { text: "text-red-500", bg: "bg-red-500", bg_transparent: "bg-red-500/10", fill: "fill-red-500", hex: "#F13636" },
"Loan" => { text: "text-fuchsia-500", bg: "bg-fuchsia-500", bg_transparent: "bg-fuchsia-500/10", fill: "fill-fuchsia-500", hex: "#D444F1" }, "Loan" => { text: "text-fuchsia-500", bg: "bg-fuchsia-500", bg_transparent: "bg-fuchsia-500/10", fill: "fill-fuchsia-500", hex: "#D444F1" },
"OtherLiability" => { text: "text-gray-500", bg: "bg-gray-500", bg_transparent: "bg-gray-500/10", fill: "fill-gray-500", hex: "#737373" }, "OtherLiability" => { text: "text-secondary", bg: "bg-gray-500", bg_transparent: "bg-gray-500/10", fill: "fill-gray-500", hex: "#737373" },
"Depository" => { text: "text-violet-500", bg: "bg-violet-500", bg_transparent: "bg-violet-500/10", fill: "fill-violet-500", hex: "#875BF7" }, "Depository" => { text: "text-violet-500", bg: "bg-violet-500", bg_transparent: "bg-violet-500/10", fill: "fill-violet-500", hex: "#875BF7" },
"Investment" => { text: "text-blue-600", bg: "bg-blue-600", bg_transparent: "bg-blue-600/10", fill: "fill-blue-600", hex: "#1570EF" }, "Investment" => { text: "text-blue-600", bg: "bg-blue-600", bg_transparent: "bg-blue-600/10", fill: "fill-blue-600", hex: "#1570EF" },
"OtherAsset" => { text: "text-green-500", bg: "bg-green-500", bg_transparent: "bg-green-500/10", fill: "fill-green-500", hex: "#12B76A" }, "OtherAsset" => { text: "text-green-500", bg: "bg-green-500", bg_transparent: "bg-green-500/10", fill: "fill-green-500", hex: "#12B76A" },
"Property" => { text: "text-cyan-500", bg: "bg-cyan-500", bg_transparent: "bg-cyan-500/10", fill: "fill-cyan-500", hex: "#06AED4" }, "Property" => { text: "text-cyan-500", bg: "bg-cyan-500", bg_transparent: "bg-cyan-500/10", fill: "fill-cyan-500", hex: "#06AED4" },
"Vehicle" => { text: "text-pink-500", bg: "bg-pink-500", bg_transparent: "bg-pink-500/10", fill: "fill-pink-500", hex: "#F23E94" } "Vehicle" => { text: "text-pink-500", bg: "bg-pink-500", bg_transparent: "bg-pink-500/10", fill: "fill-pink-500", hex: "#F23E94" }
}.fetch(accountable_type, { text: "text-gray-500", bg: "bg-gray-500", bg_transparent: "bg-gray-500/10", fill: "fill-gray-500", hex: "#737373" }) }.fetch(accountable_type, { text: "text-secondary", bg: "bg-gray-500", bg_transparent: "bg-gray-500/10", fill: "fill-gray-500", hex: "#737373" })
end end
end end

View file

@ -76,8 +76,8 @@ module ApplicationHelper
is_current = current_page?(path) || (request.path.start_with?(path) && path != "/") is_current = current_page?(path) || (request.path.start_with?(path) && path != "/")
classes = [ classes = [
"flex items-center gap-2 px-3 py-2 rounded-xl border text-sm font-medium text-gray-500", "flex items-center gap-2 px-3 py-2 rounded-xl border text-sm font-medium text-secondary",
(is_current ? "bg-white text-gray-900 shadow-xs border-alpha-black-50" : "hover:bg-gray-100 border-transparent") (is_current ? "bg-white text-primary shadow-xs border-alpha-black-50" : "hover:bg-gray-100 border-transparent")
].compact.join(" ") ].compact.join(" ")
link_to path, **options.merge(class: classes), aria: { current: ("page" if current_page?(path)) } do link_to path, **options.merge(class: classes), aria: { current: ("page" if current_page?(path)) } do
@ -106,7 +106,7 @@ module ApplicationHelper
end end
def trend_styles(trend) def trend_styles(trend)
fallback = { bg_class: "bg-gray-500/5", text_class: "text-gray-500", symbol: "", icon: "minus" } fallback = { bg_class: "bg-gray-500/5", text_class: "text-secondary", symbol: "", icon: "minus" }
return fallback if trend.nil? || trend.direction.flat? return fallback if trend.nil? || trend.direction.flat?
bg_class, text_class, symbol, icon = case trend.direction bg_class, text_class, symbol, icon = case trend.direction
@ -115,7 +115,7 @@ module ApplicationHelper
when "down" when "down"
trend.favorable_direction.down? ? [ "bg-green-500/5", "text-green-500", "-", "arrow-down" ] : [ "bg-red-500/5", "text-red-500", "-", "arrow-down" ] trend.favorable_direction.down? ? [ "bg-green-500/5", "text-green-500", "-", "arrow-down" ] : [ "bg-red-500/5", "text-red-500", "-", "arrow-down" ]
when "flat" when "flat"
[ "bg-gray-500/5", "text-gray-500", "", "minus" ] [ "bg-gray-500/5", "text-secondary", "", "minus" ]
else else
raise ArgumentError, "Invalid trend direction: #{trend.direction}" raise ArgumentError, "Invalid trend direction: #{trend.direction}"
end end

View file

@ -17,7 +17,7 @@ module FormsHelper
end end
end end
def period_select(form:, selected:, classes: "border border-alpha-black-100 shadow-xs rounded-lg text-sm pr-7 cursor-pointer text-gray-900 focus:outline-hidden focus:ring-0") def period_select(form:, selected:, classes: "border border-tertiary shadow-xs rounded-lg text-sm pr-7 cursor-pointer text-primary focus:outline-hidden focus:ring-0")
periods_for_select = [ periods_for_select = [
%w[CWD current_week], # Current Week to Date %w[CWD current_week], # Current Week to Date
%w[7D last_7_days], %w[7D last_7_days],
@ -39,7 +39,7 @@ end
private private
def radio_tab_contents(label:, icon:) def radio_tab_contents(label:, icon:)
tag.div(class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-gray-400 group-has-checked:bg-white group-has-checked:text-gray-800 group-has-checked:shadow-sm") do tag.div(class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-subdued group-has-checked:bg-white group-has-checked:text-gray-800 group-has-checked:shadow-sm") do
concat lucide_icon(icon, class: "w-5 h-5") concat lucide_icon(icon, class: "w-5 h-5")
concat tag.span(label, class: "group-has-checked:font-semibold") concat tag.span(label, class: "group-has-checked:font-semibold")
end end

View file

@ -45,7 +45,7 @@ module ImportsHelper
end end
def cell_class(row, field) def cell_class(row, field)
base = "text-sm focus:ring-gray-900 focus:border-gray-900 w-full max-w-full disabled:text-gray-400" base = "text-sm focus:ring-gray-900 focus:border-gray-900 w-full max-w-full disabled:text-subdued"
row.valid? # populate errors row.valid? # populate errors

View file

@ -7,8 +7,8 @@ module MenusHelper
end end
def contextual_menu_modal_action_item(label, url, icon: "pencil-line", turbo_frame: :modal) def contextual_menu_modal_action_item(label, url, icon: "pencil-line", turbo_frame: :modal)
link_to url, class: "flex items-center rounded-lg text-gray-900 hover:bg-gray-50 py-2 px-3 gap-2", data: { turbo_frame: } do link_to url, class: "flex items-center rounded-lg text-primary hover:bg-gray-50 py-2 px-3 gap-2", data: { turbo_frame: } do
concat(lucide_icon(icon, class: "shrink-0 w-5 h-5 text-gray-500")) concat(lucide_icon(icon, class: "shrink-0 w-5 h-5 text-secondary"))
concat(tag.span(label, class: "text-sm")) concat(tag.span(label, class: "text-sm"))
end end
end end
@ -26,7 +26,7 @@ module MenusHelper
private private
def contextual_menu_icon def contextual_menu_icon
tag.button class: "flex hover:bg-gray-100 p-2 rounded cursor-pointer", data: { menu_target: "button" } do tag.button class: "flex hover:bg-gray-100 p-2 rounded cursor-pointer", data: { menu_target: "button" } do
lucide_icon "more-horizontal", class: "w-5 h-5 text-gray-500" lucide_icon "more-horizontal", class: "w-5 h-5 text-secondary"
end end
end end

View file

@ -401,11 +401,11 @@ export default class extends Controller {
up: up:
datum.trend.favorable_direction === "up" datum.trend.favorable_direction === "up"
? "var(--color-success)" ? "var(--color-success)"
: "var(--color-error)", : "var(--color-destructive)",
down: down:
datum.trend.favorable_direction === "down" datum.trend.favorable_direction === "down"
? "var(--color-success)" ? "var(--color-success)"
: "var(--color-error)", : "var(--color-destructive)",
flat: "var(--color-gray-500)", flat: "var(--color-gray-500)",
}[datum.trend.direction]; }[datum.trend.direction];
} }
@ -509,7 +509,7 @@ export default class extends Controller {
if (this._trendDirection === this._favorableDirection) { if (this._trendDirection === this._favorableDirection) {
return "var(--color-green-500)"; return "var(--color-green-500)";
} }
return "var(--color-error)"; return "var(--color-destructive)";
} }
get _trendDirection() { get _trendDirection() {

View file

@ -1,4 +1,4 @@
<div class="flex flex-col items-center justify-center py-40"> <div class="flex flex-col items-center justify-center py-40">
<p class="text-gray-500 mb-2"><%= t(".title") %></p> <p class="text-secondary mb-2"><%= t(".title") %></p>
<p class="text-gray-400 max-w-xs text-center"><%= t(".description") %></p> <p class="text-subdued max-w-xs text-center"><%= t(".description") %></p>
</div> </div>

View file

@ -1,10 +1,10 @@
<%# locals: (date:, entries:, content:, selectable:, totals: false) %> <%# locals: (date:, entries:, content:, selectable:, totals: false) %>
<div id="entry-group-<%= date %>" class="bg-gray-25 rounded-xl p-1 w-full" data-bulk-select-target="group"> <div id="entry-group-<%= date %>" class="bg-gray-25 rounded-xl p-1 w-full" data-bulk-select-target="group">
<div class="py-2 px-4 flex items-center justify-between font-medium text-xs text-gray-500"> <div class="py-2 px-4 flex items-center justify-between font-medium text-xs text-secondary">
<div class="flex pl-0.5 items-center gap-4"> <div class="flex pl-0.5 items-center gap-4">
<% if selectable %> <% if selectable %>
<%= check_box_tag "#{date}_entries_selection", <%= check_box_tag "#{date}_entries_selection",
class: ["maybe-checkbox maybe-checkbox--light", "hidden": entries.size == 0], class: ["checkbox checkbox--light", "hidden": entries.size == 0],
id: "selection_entry_#{date}", id: "selection_entry_#{date}",
data: { action: "bulk-select#toggleGroupSelection" } %> data: { action: "bulk-select#toggleGroupSelection" } %>
<% end %> <% end %>

View file

@ -1,5 +1,5 @@
<div class="bg-white space-y-4 p-5 border border-alpha-black-25 rounded-xl shadow-xs"> <div class="bg-white space-y-4 p-5 border border-alpha-black-25 rounded-xl shadow-xs">
<div class="p-5 flex justify-center items-center"> <div class="p-5 flex justify-center items-center">
<%= tag.p t(".loading"), class: "text-gray-500 animate-pulse text-sm" %> <%= tag.p t(".loading"), class: "text-secondary animate-pulse text-sm" %>
</div> </div>
</div> </div>

View file

@ -1,11 +1,11 @@
<div class="fixed bottom-6 z-10 flex items-center justify-between rounded-xl bg-gray-900 px-4 text-sm text-white w-[420px] py-1.5"> <div class="fixed bottom-6 z-10 flex items-center justify-between rounded-xl bg-gray-900 px-4 text-sm text-white w-[420px] py-1.5">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<%= check_box_tag "entry_selection", 1, true, class: "maybe-checkbox maybe-checkbox--dark", data: { action: "bulk-select#deselectAll" } %> <%= check_box_tag "entry_selection", 1, true, class: "checkbox checkbox--dark", data: { action: "bulk-select#deselectAll" } %>
<p data-bulk-select-target="selectionBarText"></p> <p data-bulk-select-target="selectionBarText"></p>
</div> </div>
<div class="flex items-center gap-1 text-gray-500"> <div class="flex items-center gap-1 text-secondary">
<%= form_with url: bulk_delete_account_transactions_path, data: { turbo_confirm: true, turbo_frame: "_top" } do %> <%= form_with url: bulk_delete_account_transactions_path, data: { turbo_confirm: true, turbo_frame: "_top" } do %>
<button type="button" data-bulk-select-scope-param="bulk_delete" data-action="bulk-select#submitBulkRequest" class="p-1.5 group hover:bg-gray-700 flex items-center justify-center rounded-md" title="Delete"> <button type="button" data-bulk-select-scope-param="bulk_delete" data-action="bulk-select#submitBulkRequest" class="p-1.5 group hover:bg-gray-700 flex items-center justify-center rounded-md" title="Delete">
<%= lucide_icon "trash-2", class: "w-5 group-hover:text-white" %> <%= lucide_icon "trash-2", class: "w-5 group-hover:text-white" %>

View file

@ -2,13 +2,13 @@
<% currency = Money::Currency.new(account.currency) %> <% currency = Money::Currency.new(account.currency) %>
<div class="grid grid-cols-12 items-center text-gray-900 text-sm font-medium p-4"> <div class="grid grid-cols-12 items-center text-primary text-sm font-medium p-4">
<div class="col-span-4 flex items-center gap-4"> <div class="col-span-4 flex items-center gap-4">
<%= render "shared/circle_logo", name: currency.iso_code %> <%= render "shared/circle_logo", name: currency.iso_code %>
<div class="space-y-0.5"> <div class="space-y-0.5">
<%= tag.p t(".brokerage_cash"), class: "text-gray-900" %> <%= tag.p t(".brokerage_cash"), class: "text-primary" %>
<%= tag.p account.currency, class: "text-gray-500 text-xs uppercase" %> <%= tag.p account.currency, class: "text-secondary text-xs uppercase" %>
</div> </div>
</div> </div>
@ -19,7 +19,7 @@
</div> </div>
<div class="col-span-2 text-right"> <div class="col-span-2 text-right">
<%= tag.p "--", class: "text-gray-500" %> <%= tag.p "--", class: "text-secondary" %>
</div> </div>
<div class="col-span-2 text-right"> <div class="col-span-2 text-right">
@ -27,6 +27,6 @@
</div> </div>
<div class="col-span-2 text-right"> <div class="col-span-2 text-right">
<%= tag.p "--", class: "text-gray-500" %> <%= tag.p "--", class: "text-secondary" %>
</div> </div>
</div> </div>

View file

@ -1,7 +1,7 @@
<%# locals: (holding:) %> <%# locals: (holding:) %>
<%= turbo_frame_tag dom_id(holding) do %> <%= turbo_frame_tag dom_id(holding) do %>
<div class="grid grid-cols-12 items-center text-gray-900 text-sm font-medium p-4"> <div class="grid grid-cols-12 items-center text-primary text-sm font-medium p-4">
<div class="col-span-4 flex items-center gap-4"> <div class="col-span-4 flex items-center gap-4">
<%= image_tag "https://logo.synthfinance.com/ticker/#{holding.ticker}", class: "w-9 h-9 rounded-full", loading: "lazy" %> <%= image_tag "https://logo.synthfinance.com/ticker/#{holding.ticker}", class: "w-9 h-9 rounded-full", loading: "lazy" %>
@ -9,7 +9,7 @@
<%= link_to holding.name, account_holding_path(holding), data: { turbo_frame: :drawer }, class: "hover:underline" %> <%= link_to holding.name, account_holding_path(holding), data: { turbo_frame: :drawer }, class: "hover:underline" %>
<% if holding.amount %> <% if holding.amount %>
<%= tag.p holding.ticker, class: "text-gray-500 text-xs uppercase" %> <%= tag.p holding.ticker, class: "text-secondary text-xs uppercase" %>
<% else %> <% else %>
<%= render "missing_price_tooltip" %> <%= render "missing_price_tooltip" %>
<% end %> <% end %>
@ -21,22 +21,22 @@
<%= render "shared/progress_circle", progress: holding.weight, text_class: "text-blue-500" %> <%= render "shared/progress_circle", progress: holding.weight, text_class: "text-blue-500" %>
<%= tag.p number_to_percentage(holding.weight, precision: 1) %> <%= tag.p number_to_percentage(holding.weight, precision: 1) %>
<% else %> <% else %>
<%= tag.p "--", class: "text-gray-500 mb-5" %> <%= tag.p "--", class: "text-secondary mb-5" %>
<% end %> <% end %>
</div> </div>
<div class="col-span-2 text-right"> <div class="col-span-2 text-right">
<%= tag.p format_money holding.avg_cost %> <%= tag.p format_money holding.avg_cost %>
<%= tag.p t(".per_share"), class: "font-normal text-gray-500" %> <%= tag.p t(".per_share"), class: "font-normal text-secondary" %>
</div> </div>
<div class="col-span-2 text-right"> <div class="col-span-2 text-right">
<% if holding.amount_money %> <% if holding.amount_money %>
<%= tag.p format_money holding.amount_money %> <%= tag.p format_money holding.amount_money %>
<% else %> <% else %>
<%= tag.p "--", class: "text-gray-500" %> <%= tag.p "--", class: "text-secondary" %>
<% end %> <% end %>
<%= tag.p t(".shares", qty: number_with_precision(holding.qty, precision: 1)), class: "font-normal text-gray-500" %> <%= tag.p t(".shares", qty: number_with_precision(holding.qty, precision: 1)), class: "font-normal text-secondary" %>
</div> </div>
<div class="col-span-2 text-right"> <div class="col-span-2 text-right">
@ -44,7 +44,7 @@
<%= tag.p format_money(holding.trend.value), style: "color: #{holding.trend.color};" %> <%= tag.p format_money(holding.trend.value), style: "color: #{holding.trend.color};" %>
<%= tag.p "(#{number_to_percentage(holding.trend.percent, precision: 1)})", style: "color: #{holding.trend.color};" %> <%= tag.p "(#{number_to_percentage(holding.trend.percent, precision: 1)})", style: "color: #{holding.trend.color};" %>
<% else %> <% else %>
<%= tag.p "--", class: "text-gray-500 mb-4" %> <%= tag.p "--", class: "text-secondary mb-4" %>
<% end %> <% end %>
</div> </div>
</div> </div>

View file

@ -5,14 +5,14 @@
<%= link_to new_account_trade_path(account_id: @account.id), <%= link_to new_account_trade_path(account_id: @account.id),
id: dom_id(@account, "new_trade"), id: dom_id(@account, "new_trade"),
data: { turbo_frame: :modal }, data: { turbo_frame: :modal },
class: "flex gap-1 font-medium items-center bg-gray-50 text-gray-900 p-2 rounded-lg" do %> class: "flex gap-1 font-medium items-center bg-gray-50 text-primary p-2 rounded-lg" do %>
<%= lucide_icon("plus", class: "w-5 h-5 text-gray-900") %> <%= lucide_icon("plus", class: "w-5 h-5 text-primary") %>
<%= tag.span t(".new_holding"), class: "text-sm" %> <%= tag.span t(".new_holding"), class: "text-sm" %>
<% end %> <% end %>
</div> </div>
<div class="rounded-xl bg-gray-25 p-1"> <div class="rounded-xl bg-gray-25 p-1">
<div class="grid grid-cols-12 items-center uppercase text-xs font-medium text-gray-500 px-4 py-2"> <div class="grid grid-cols-12 items-center uppercase text-xs font-medium text-secondary px-4 py-2">
<%= tag.p t(".name"), class: "col-span-4" %> <%= tag.p t(".name"), class: "col-span-4" %>
<%= tag.p t(".weight"), class: "col-span-2 justify-self-end" %> <%= tag.p t(".weight"), class: "col-span-2 justify-self-end" %>
<%= tag.p t(".cost"), class: "col-span-2 justify-self-end" %> <%= tag.p t(".cost"), class: "col-span-2 justify-self-end" %>
@ -26,7 +26,7 @@
<%= render "account/holdings/ruler" %> <%= render "account/holdings/ruler" %>
<%= render partial: "account/holdings/holding", collection: @account.current_holdings, spacer_template: "ruler" %> <%= render partial: "account/holdings/holding", collection: @account.current_holdings, spacer_template: "ruler" %>
<% else %> <% else %>
<p class="text-gray-500 text-sm p-4"><%= t(".no_holdings") %></p> <p class="text-secondary text-sm p-4"><%= t(".no_holdings") %></p>
<% end %> <% end %>
</div> </div>
</div> </div>

View file

@ -2,43 +2,43 @@
<div class="space-y-4"> <div class="space-y-4">
<header class="flex justify-between"> <header class="flex justify-between">
<div> <div>
<%= tag.h3 @holding.name, class: "text-2xl font-medium text-gray-900" %> <%= tag.h3 @holding.name, class: "text-2xl font-medium text-primary" %>
<%= tag.p @holding.ticker, class: "text-sm text-gray-500" %> <%= tag.p @holding.ticker, class: "text-sm text-secondary" %>
</div> </div>
<%= image_tag "https://logo.synthfinance.com/ticker/#{@holding.ticker}", loading: "lazy", class: "w-9 h-9 rounded-full" %> <%= image_tag "https://logo.synthfinance.com/ticker/#{@holding.ticker}", loading: "lazy", class: "w-9 h-9 rounded-full" %>
</header> </header>
<details class="group space-y-2" open> <details class="group space-y-2" open>
<summary class="flex list-none items-center justify-between rounded-xl px-3 py-2 text-xs font-medium uppercase text-gray-500 bg-gray-25 focus-visible:outline-hidden"> <summary class="flex list-none items-center justify-between rounded-xl px-3 py-2 text-xs font-medium uppercase text-secondary bg-gray-25 focus-visible:outline-hidden">
<h4><%= t(".overview") %></h4> <h4><%= t(".overview") %></h4>
<%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-gray-500 w-5" %> <%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-secondary w-5" %>
</summary> </summary>
<div class="pb-4"> <div class="pb-4">
<dl class="space-y-3 px-3 py-2"> <dl class="space-y-3 px-3 py-2">
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500"><%= t(".ticker_label") %></dt> <dt class="text-secondary"><%= t(".ticker_label") %></dt>
<dd class="text-gray-900"><%= @holding.ticker %></dd> <dd class="text-primary"><%= @holding.ticker %></dd>
</div> </div>
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500"><%= t(".current_market_price_label") %></dt> <dt class="text-secondary"><%= t(".current_market_price_label") %></dt>
<dd class="text-gray-900"><%= @holding.security.current_price ? format_money(@holding.security.current_price) : t(".unknown") %></dd> <dd class="text-primary"><%= @holding.security.current_price ? format_money(@holding.security.current_price) : t(".unknown") %></dd>
</div> </div>
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500"><%= t(".portfolio_weight_label") %></dt> <dt class="text-secondary"><%= t(".portfolio_weight_label") %></dt>
<dd class="text-gray-900"><%= @holding.weight ? number_to_percentage(@holding.weight, precision: 2) : t(".unknown") %></dd> <dd class="text-primary"><%= @holding.weight ? number_to_percentage(@holding.weight, precision: 2) : t(".unknown") %></dd>
</div> </div>
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500"><%= t(".avg_cost_label") %></dt> <dt class="text-secondary"><%= t(".avg_cost_label") %></dt>
<dd class="text-gray-900"><%= @holding.avg_cost ? format_money(@holding.avg_cost) : t(".unknown") %></dd> <dd class="text-primary"><%= @holding.avg_cost ? format_money(@holding.avg_cost) : t(".unknown") %></dd>
</div> </div>
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500"><%= t(".trend_label") %></dt> <dt class="text-secondary"><%= t(".trend_label") %></dt>
<dd style="color: <%= @holding.trend&.color %>;"> <dd style="color: <%= @holding.trend&.color %>;">
<%= @holding.trend ? render("shared/trend_change", trend: @holding.trend) : t(".unknown") %> <%= @holding.trend ? render("shared/trend_change", trend: @holding.trend) : t(".unknown") %>
</dd> </dd>
@ -48,9 +48,9 @@
</details> </details>
<details class="group space-y-2" open> <details class="group space-y-2" open>
<summary class="flex list-none items-center justify-between rounded-xl px-3 py-2 text-xs font-medium uppercase text-gray-500 bg-gray-25 focus-visible:outline-hidden"> <summary class="flex list-none items-center justify-between rounded-xl px-3 py-2 text-xs font-medium uppercase text-secondary bg-gray-25 focus-visible:outline-hidden">
<h4><%= t(".history") %></h4> <h4><%= t(".history") %></h4>
<%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-gray-500 w-5" %> <%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-secondary w-5" %>
</summary> </summary>
<div class="space-y-2"> <div class="space-y-2">
@ -67,7 +67,7 @@
</div> </div>
<div> <div>
<p class="text-gray-500 text-xs uppercase"><%= l(trade_entry.date, format: :long) %></p> <p class="text-secondary text-xs uppercase"><%= l(trade_entry.date, format: :long) %></p>
<p><%= t( <p><%= t(
".trade_history_entry", ".trade_history_entry",
@ -81,29 +81,29 @@
</ul> </ul>
<% else %> <% else %>
<p class="text-gray-500">No trade history available for this holding.</p> <p class="text-secondary">No trade history available for this holding.</p>
<% end %> <% end %>
</div> </div>
</div> </div>
</details> </details>
<details class="group space-y-2" open> <details class="group space-y-2" open>
<summary class="flex list-none items-center justify-between rounded-xl px-3 py-2 text-xs font-medium uppercase text-gray-500 bg-gray-25 focus-visible:outline-hidden"> <summary class="flex list-none items-center justify-between rounded-xl px-3 py-2 text-xs font-medium uppercase text-secondary bg-gray-25 focus-visible:outline-hidden">
<h4><%= t(".settings") %></h4> <h4><%= t(".settings") %></h4>
<%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-gray-500 w-5" %> <%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-secondary w-5" %>
</summary> </summary>
<div class="pb-4"> <div class="pb-4">
<div class="flex items-center justify-between gap-2 p-3"> <div class="flex items-center justify-between gap-2 p-3">
<div class="text-sm space-y-1"> <div class="text-sm space-y-1">
<h4 class="text-gray-900"><%= t(".delete_title") %></h4> <h4 class="text-primary"><%= t(".delete_title") %></h4>
<p class="text-gray-500"><%= t(".delete_subtitle") %></p> <p class="text-secondary"><%= t(".delete_subtitle") %></p>
</div> </div>
<%= button_to t(".delete"), <%= button_to t(".delete"),
account_holding_path(@holding), account_holding_path(@holding),
method: :delete, method: :delete,
class: "rounded-lg px-3 py-2 text-red-500 text-sm font-medium border border-alpha-black-200", class: "rounded-lg px-3 py-2 text-red-500 text-sm font-medium border border-secondary",
data: { turbo_confirm: true } %> data: { turbo_confirm: true } %>
</div> </div>
</div> </div>

View file

@ -2,7 +2,7 @@
<div id="<%= dom_id(entry, :header) %>"> <div id="<%= dom_id(entry, :header) %>">
<%= tag.header class: "mb-4 space-y-1" do %> <%= tag.header class: "mb-4 space-y-1" do %>
<span class="text-gray-500 text-sm"> <span class="text-secondary text-sm">
<%= entry.amount.negative? ? t(".sell") : t(".buy") %> <%= entry.amount.negative? ? t(".sell") : t(".buy") %>
</span> </span>
@ -12,13 +12,13 @@
<%= format_money entry.amount_money %> <%= format_money entry.amount_money %>
</span> </span>
<span class="text-lg text-gray-500"> <span class="text-lg text-secondary">
<%= entry.currency %> <%= entry.currency %>
</span> </span>
</h3> </h3>
</div> </div>
<span class="text-sm text-gray-500"> <span class="text-sm text-secondary">
<%= I18n.l(entry.date, format: :long) %> <%= I18n.l(entry.date, format: :long) %>
</span> </span>
<% end %> <% end %>
@ -30,32 +30,32 @@
<div class="pb-4"> <div class="pb-4">
<dl class="space-y-3 px-3 py-2"> <dl class="space-y-3 px-3 py-2">
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500"><%= t(".symbol_label") %></dt> <dt class="text-secondary"><%= t(".symbol_label") %></dt>
<dd class="text-gray-900"><%= trade.security.ticker %></dd> <dd class="text-primary"><%= trade.security.ticker %></dd>
</div> </div>
<% if trade.qty.positive? %> <% if trade.qty.positive? %>
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500"><%= t(".purchase_qty_label") %></dt> <dt class="text-secondary"><%= t(".purchase_qty_label") %></dt>
<dd class="text-gray-900"><%= trade.qty.abs %></dd> <dd class="text-primary"><%= trade.qty.abs %></dd>
</div> </div>
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500"><%= t(".purchase_price_label") %></dt> <dt class="text-secondary"><%= t(".purchase_price_label") %></dt>
<dd class="text-gray-900"><%= format_money trade.price_money %></dd> <dd class="text-primary"><%= format_money trade.price_money %></dd>
</div> </div>
<% end %> <% end %>
<% if trade.security.current_price.present? %> <% if trade.security.current_price.present? %>
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500"><%= t(".current_market_price_label") %></dt> <dt class="text-secondary"><%= t(".current_market_price_label") %></dt>
<dd class="text-gray-900"><%= format_money trade.security.current_price %></dd> <dd class="text-primary"><%= format_money trade.security.current_price %></dd>
</div> </div>
<% end %> <% end %>
<% if trade.qty.positive? && trade.unrealized_gain_loss.present? %> <% if trade.qty.positive? && trade.unrealized_gain_loss.present? %>
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500"><%= t(".total_return_label") %></dt> <dt class="text-secondary"><%= t(".total_return_label") %></dt>
<dd style="color: <%= trade.unrealized_gain_loss.color %>;"> <dd style="color: <%= trade.unrealized_gain_loss.color %>;">
<%= render "shared/trend_change", trend: trade.unrealized_gain_loss %> <%= render "shared/trend_change", trend: trade.unrealized_gain_loss %>
</dd> </dd>

View file

@ -1,11 +1,11 @@
<div class="fixed bottom-6 z-10 flex items-center justify-between rounded-xl bg-gray-900 px-4 text-sm text-white w-[420px] py-1.5"> <div class="fixed bottom-6 z-10 flex items-center justify-between rounded-xl bg-gray-900 px-4 text-sm text-white w-[420px] py-1.5">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<%= check_box_tag "entry_selection", 1, true, class: "maybe-checkbox maybe-checkbox--dark", data: { action: "bulk-select#deselectAll" } %> <%= check_box_tag "entry_selection", 1, true, class: "checkbox checkbox--dark", data: { action: "bulk-select#deselectAll" } %>
<p data-bulk-select-target="selectionBarText"></p> <p data-bulk-select-target="selectionBarText"></p>
</div> </div>
<div class="flex items-center gap-1 text-gray-500"> <div class="flex items-center gap-1 text-secondary">
<%= form_with url: bulk_delete_account_transactions_path, data: { turbo_confirm: true, turbo_frame: "_top" } do %> <%= form_with url: bulk_delete_account_transactions_path, data: { turbo_confirm: true, turbo_frame: "_top" } do %>
<button type="button" data-bulk-select-scope-param="bulk_delete" data-action="bulk-select#submitBulkRequest" class="p-1.5 group hover:bg-gray-700 flex items-center justify-center rounded-md" title="Delete"> <button type="button" data-bulk-select-scope-param="bulk_delete" data-action="bulk-select#submitBulkRequest" class="p-1.5 group hover:bg-gray-700 flex items-center justify-center rounded-md" title="Delete">
<%= lucide_icon "trash-2", class: "w-5 group-hover:text-white" %> <%= lucide_icon "trash-2", class: "w-5 group-hover:text-white" %>

View file

@ -2,11 +2,11 @@
<% trade, account = entry.account_trade, entry.account %> <% trade, account = entry.account_trade, entry.account %>
<div class="grid grid-cols-12 items-center <%= entry.excluded ? "text-gray-400 bg-gray-25" : "text-gray-900" %> text-sm font-medium p-4"> <div class="grid grid-cols-12 items-center <%= entry.excluded ? "text-subdued bg-gray-25" : "text-primary" %> text-sm font-medium p-4">
<div class="col-span-6 flex items-center gap-4"> <div class="col-span-6 flex items-center gap-4">
<% if selectable %> <% if selectable %>
<%= check_box_tag dom_id(entry, "selection"), <%= check_box_tag dom_id(entry, "selection"),
class: "maybe-checkbox maybe-checkbox--light", class: "checkbox checkbox--light",
data: { id: entry.id, "bulk-select-target": "row", action: "bulk-select#toggleRowSelection" } %> data: { id: entry.id, "bulk-select-target": "row", action: "bulk-select#toggleRowSelection" } %>
<% end %> <% end %>
@ -43,10 +43,10 @@
<div class="col-span-2 justify-self-end"> <div class="col-span-2 justify-self-end">
<% if balance_trend&.trend %> <% if balance_trend&.trend %>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<%= tag.p format_money(balance_trend.trend.current), class: "font-medium text-sm text-gray-900" %> <%= tag.p format_money(balance_trend.trend.current), class: "font-medium text-sm text-primary" %>
</div> </div>
<% else %> <% else %>
<%= tag.p "--", class: "font-medium text-sm text-gray-400" %> <%= tag.p "--", class: "font-medium text-sm text-subdued" %>
<% end %> <% end %>
</div> </div>
</div> </div>

View file

@ -4,17 +4,17 @@
<h3 class="font-medium text-lg"><%= t(".trades") %></h3> <h3 class="font-medium text-lg"><%= t(".trades") %></h3>
<%= link_to new_account_trade_path(@account), <%= link_to new_account_trade_path(@account),
id: dom_id(@account, "new_trade"), id: dom_id(@account, "new_trade"),
class: "flex gap-1 font-medium items-center bg-gray-50 text-gray-900 p-2 rounded-lg", class: "flex gap-1 font-medium items-center bg-gray-50 text-primary p-2 rounded-lg",
data: { turbo_frame: :modal } do %> data: { turbo_frame: :modal } do %>
<%= lucide_icon("plus", class: "w-5 h-5 text-gray-900") %> <%= lucide_icon("plus", class: "w-5 h-5 text-primary") %>
<span class="text-sm"><%= t(".new") %></span> <span class="text-sm"><%= t(".new") %></span>
<% end %> <% end %>
</div> </div>
<div class="bg-gray-25 rounded-xl grid grid-cols-12 items-center uppercase text-xs font-medium text-gray-500 px-5 py-3"> <div class="bg-gray-25 rounded-xl grid grid-cols-12 items-center uppercase text-xs font-medium text-secondary px-5 py-3">
<div class="pl-0.5 col-span-6 flex items-center gap-4"> <div class="pl-0.5 col-span-6 flex items-center gap-4">
<%= check_box_tag "selection_entry", <%= check_box_tag "selection_entry",
class: "maybe-checkbox maybe-checkbox--light", class: "checkbox checkbox--light",
data: { action: "bulk-select#togglePageSelection" } %> data: { action: "bulk-select#togglePageSelection" } %>
<%= tag.p t(".trade") %> <%= tag.p t(".trade") %>
</div> </div>
@ -29,7 +29,7 @@
</div> </div>
<% if @entries.empty? %> <% if @entries.empty? %>
<p class="text-gray-500 py-4"><%= t(".no_trades") %></p> <p class="text-secondary py-4"><%= t(".no_trades") %></p>
<% else %> <% else %>
<div class="space-y-6"> <div class="space-y-6">
<%= entries_by_date(@entries) do |entries, _transfers| %> <%= entries_by_date(@entries) do |entries, _transfers| %>

View file

@ -68,8 +68,8 @@
data: { controller: "auto-submit-form" } do |f| %> data: { controller: "auto-submit-form" } do |f| %>
<div class="flex cursor-pointer items-center gap-2 justify-between"> <div class="flex cursor-pointer items-center gap-2 justify-between">
<div class="text-sm space-y-1"> <div class="text-sm space-y-1">
<h4 class="text-gray-900"><%= t(".exclude_title") %></h4> <h4 class="text-primary"><%= t(".exclude_title") %></h4>
<p class="text-gray-500"><%= t(".exclude_subtitle") %></p> <p class="text-secondary"><%= t(".exclude_subtitle") %></p>
</div> </div>
<div class="relative inline-block select-none"> <div class="relative inline-block select-none">
@ -77,7 +77,7 @@
class: "sr-only peer", class: "sr-only peer",
"data-auto-submit-form-target": "auto" %> "data-auto-submit-form-target": "auto" %>
<label for="account_entry_excluded" <label for="account_entry_excluded"
class="maybe-switch"></label> class="switch"></label>
</div> </div>
</div> </div>
<% end %> <% end %>
@ -85,15 +85,15 @@
<!-- Delete Trade Form --> <!-- Delete Trade Form -->
<div class="flex items-center justify-between gap-2 p-3"> <div class="flex items-center justify-between gap-2 p-3">
<div class="text-sm space-y-1"> <div class="text-sm space-y-1">
<h4 class="text-gray-900"><%= t(".delete_title") %></h4> <h4 class="text-primary"><%= t(".delete_title") %></h4>
<p class="text-gray-500"><%= t(".delete_subtitle") %></p> <p class="text-secondary"><%= t(".delete_subtitle") %></p>
</div> </div>
<%= button_to t(".delete"), <%= button_to t(".delete"),
account_entry_path(@entry), account_entry_path(@entry),
method: :delete, method: :delete,
class: "rounded-lg px-3 py-2 text-red-500 text-sm class: "rounded-lg px-3 py-2 text-red-500 text-sm
font-medium border border-alpha-black-200", font-medium border border-secondary",
data: { turbo_confirm: true } %> data: { turbo_confirm: true } %>
</div> </div>
</div> </div>

View file

@ -8,7 +8,7 @@
<fieldset class="bg-gray-50 rounded-lg p-1 grid grid-flow-col justify-stretch gap-x-2"> <fieldset class="bg-gray-50 rounded-lg p-1 grid grid-flow-col justify-stretch gap-x-2">
<%= radio_tab_tag form: f, name: :nature, value: :outflow, label: t(".expense"), icon: "minus-circle", checked: params[:nature] == "outflow" || params[:nature].nil? %> <%= radio_tab_tag form: f, name: :nature, value: :outflow, label: t(".expense"), icon: "minus-circle", checked: params[:nature] == "outflow" || params[:nature].nil? %>
<%= radio_tab_tag form: f, name: :nature, value: :inflow, label: t(".income"), icon: "plus-circle", checked: params[:nature] == "inflow" %> <%= radio_tab_tag form: f, name: :nature, value: :inflow, label: t(".income"), icon: "plus-circle", checked: params[:nature] == "inflow" %>
<%= link_to new_transfer_path, data: { turbo_frame: :modal }, class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-gray-400 group-has-checked:bg-white group-has-checked:text-gray-800 group-has-checked:shadow-sm" do %> <%= link_to new_transfer_path, data: { turbo_frame: :modal }, class: "flex px-4 py-1 rounded-lg items-center space-x-2 justify-center text-subdued group-has-checked:bg-white group-has-checked:text-gray-800 group-has-checked:shadow-sm" do %>
<%= lucide_icon "arrow-right-left", class: "w-5 h-5" %> <%= lucide_icon "arrow-right-left", class: "w-5 h-5" %>
<%= tag.span t(".transfer") %> <%= tag.span t(".transfer") %>
<% end %> <% end %>

View file

@ -7,17 +7,17 @@
<%= format_money -entry.amount_money %> <%= format_money -entry.amount_money %>
</span> </span>
<span class="text-lg text-gray-500"> <span class="text-lg text-secondary">
<%= entry.currency %> <%= entry.currency %>
</span> </span>
</h3> </h3>
<% if entry.account_transaction.transfer? %> <% if entry.account_transaction.transfer? %>
<%= lucide_icon "arrow-left-right", class: "text-gray-500 mt-1 w-5 h-5" %> <%= lucide_icon "arrow-left-right", class: "text-secondary mt-1 w-5 h-5" %>
<% end %> <% end %>
</div> </div>
<span class="text-sm text-gray-500"> <span class="text-sm text-secondary">
<%= I18n.l(entry.date, format: :long) %> <%= I18n.l(entry.date, format: :long) %>
</span> </span>
<% end %> <% end %>

View file

@ -1,11 +1,11 @@
<div class="fixed bottom-6 z-10 flex items-center justify-between rounded-xl bg-gray-900 px-4 text-sm text-white w-[420px] py-1.5"> <div class="fixed bottom-6 z-10 flex items-center justify-between rounded-xl bg-gray-900 px-4 text-sm text-white w-[420px] py-1.5">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<%= check_box_tag "entry_selection", 1, true, class: "maybe-checkbox maybe-checkbox--dark", data: { action: "bulk-select#deselectAll" } %> <%= check_box_tag "entry_selection", 1, true, class: "checkbox checkbox--dark", data: { action: "bulk-select#deselectAll" } %>
<p data-bulk-select-target="selectionBarText"></p> <p data-bulk-select-target="selectionBarText"></p>
</div> </div>
<div class="flex items-center gap-1 text-gray-500"> <div class="flex items-center gap-1 text-secondary">
<%= turbo_frame_tag "bulk_transaction_edit_drawer" %> <%= turbo_frame_tag "bulk_transaction_edit_drawer" %>
<%= link_to bulk_edit_account_transactions_path, <%= link_to bulk_edit_account_transactions_path,

View file

@ -1,11 +1,11 @@
<%# locals: (entry:, selectable: true, balance_trend: nil) %> <%# locals: (entry:, selectable: true, balance_trend: nil) %>
<div class="grid grid-cols-12 items-center text-gray-900 text-sm font-medium p-4 <%= @focused_record == entry ? "border border-gray-900 rounded-lg" : "" %>"> <div class="grid grid-cols-12 items-center text-primary text-sm font-medium p-4 <%= @focused_record == entry ? "border border-gray-900 rounded-lg" : "" %>">
<div class="pr-10 flex items-center gap-4 <%= balance_trend ? "col-span-6" : "col-span-8" %>"> <div class="pr-10 flex items-center gap-4 <%= balance_trend ? "col-span-6" : "col-span-8" %>">
<% if selectable %> <% if selectable %>
<%= check_box_tag dom_id(entry, "selection"), <%= check_box_tag dom_id(entry, "selection"),
disabled: entry.entryable.transfer?, disabled: entry.entryable.transfer?,
class: "maybe-checkbox maybe-checkbox--light", class: "checkbox checkbox--light",
data: { id: entry.id, "bulk-select-target": "row", action: "bulk-select#toggleRowSelection" } %> data: { id: entry.id, "bulk-select-target": "row", action: "bulk-select#toggleRowSelection" } %>
<% end %> <% end %>
@ -40,7 +40,7 @@
<% end %> <% end %>
</div> </div>
<div class="text-gray-500 text-xs font-normal"> <div class="text-secondary text-xs font-normal">
<% if entry.entryable.transfer? %> <% if entry.entryable.transfer? %>
<%= render "transfers/account_links", transfer: entry.entryable.transfer, is_inflow: entry.entryable.transfer_as_inflow.present? %> <%= render "transfers/account_links", transfer: entry.entryable.transfer, is_inflow: entry.entryable.transfer_as_inflow.present? %>
<% else %> <% else %>
@ -66,9 +66,9 @@
<% if balance_trend %> <% if balance_trend %>
<div class="col-span-2 justify-self-end"> <div class="col-span-2 justify-self-end">
<% if balance_trend.trend %> <% if balance_trend.trend %>
<%= tag.p format_money(balance_trend.trend.current), class: "font-medium text-sm text-gray-900" %> <%= tag.p format_money(balance_trend.trend.current), class: "font-medium text-sm text-primary" %>
<% else %> <% else %>
<%= tag.p "--", class: "font-medium text-sm text-gray-400" %> <%= tag.p "--", class: "font-medium text-sm text-subdued" %>
<% end %> <% end %>
</div> </div>
<% end %> <% end %>

View file

@ -12,7 +12,7 @@
<%= button_to transfer_path(entry.account_transaction.transfer, transfer: { status: "confirmed" }), <%= button_to transfer_path(entry.account_transaction.transfer, transfer: { status: "confirmed" }),
method: :patch, method: :patch,
class: "text-gray-500 hover:text-gray-800 flex items-center justify-center", class: "text-secondary hover:text-gray-800 flex items-center justify-center",
title: "Confirm match" do %> title: "Confirm match" do %>
<%= lucide_icon "check", class: "w-4 h-4 text-indigo-400 hover:text-indigo-600" %> <%= lucide_icon "check", class: "w-4 h-4 text-indigo-400 hover:text-indigo-600" %>
<% end %> <% end %>
@ -20,9 +20,9 @@
<%= button_to transfer_path(entry.account_transaction.transfer, transfer: { status: "rejected" }), <%= button_to transfer_path(entry.account_transaction.transfer, transfer: { status: "rejected" }),
method: :patch, method: :patch,
data: { turbo: false }, data: { turbo: false },
class: "text-gray-500 hover:text-gray-800 flex items-center justify-center", class: "text-secondary hover:text-gray-800 flex items-center justify-center",
title: "Reject match" do %> title: "Reject match" do %>
<%= lucide_icon "x", class: "w-4 h-4 text-gray-400 hover:text-gray-600" %> <%= lucide_icon "x", class: "w-4 h-4 text-subdued hover:text-gray-600" %>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>

View file

@ -21,9 +21,9 @@
<div class="space-y-2"> <div class="space-y-2">
<details class="group space-y-2" open> <details class="group space-y-2" open>
<summary class="flex list-none items-center justify-between rounded-xl px-3 py-2 text-xs font-medium uppercase text-gray-500 bg-gray-25 focus-visible:outline-hidden"> <summary class="flex list-none items-center justify-between rounded-xl px-3 py-2 text-xs font-medium uppercase text-secondary bg-gray-25 focus-visible:outline-hidden">
<h4><%= t(".overview") %></h4> <h4><%= t(".overview") %></h4>
<%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-gray-500 w-5" %> <%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-secondary w-5" %>
</summary> </summary>
<div class="pb-6 space-y-2"> <div class="pb-6 space-y-2">
@ -32,14 +32,14 @@
</details> </details>
<details class="group space-y-2" open> <details class="group space-y-2" open>
<summary class="flex list-none items-center justify-between rounded-xl px-3 py-2 text-xs font-medium uppercase text-gray-500 bg-gray-25 focus-visible:outline-hidden"> <summary class="flex list-none items-center justify-between rounded-xl px-3 py-2 text-xs font-medium uppercase text-secondary bg-gray-25 focus-visible:outline-hidden">
<h4><%= t(".details") %></h4> <h4><%= t(".details") %></h4>
<%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-gray-500 w-5" %> <%= lucide_icon "chevron-down", class: "group-open:transform group-open:rotate-180 text-secondary w-5" %>
</summary> </summary>
<div class="space-y-2"> <div class="space-y-2">
<%= form.collection_select :category_id, Current.family.categories.alphabetically, :id, :name, { prompt: t(".category_placeholder"), label: t(".category_label"), class: "text-gray-400" } %> <%= form.collection_select :category_id, Current.family.categories.alphabetically, :id, :name, { prompt: t(".category_placeholder"), label: t(".category_label"), class: "text-subdued" } %>
<%= form.collection_select :merchant_id, Current.family.merchants.alphabetically, :id, :name, { prompt: t(".merchant_placeholder"), label: t(".merchant_label"), class: "text-gray-400" } %> <%= form.collection_select :merchant_id, Current.family.merchants.alphabetically, :id, :name, { prompt: t(".merchant_placeholder"), label: t(".merchant_label"), class: "text-subdued" } %>
<%= form.text_area :notes, label: t(".note_label"), placeholder: t(".note_placeholder"), rows: 5 %> <%= form.text_area :notes, label: t(".note_label"), placeholder: t(".note_placeholder"), rows: 5 %>
</div> </div>
</details> </details>
@ -49,7 +49,7 @@
</div> </div>
<div class="flex justify-end items-center gap-2"> <div class="flex justify-end items-center gap-2">
<%= link_to t(".cancel"), transactions_path, class: "text-sm font-medium text-gray-900 px-3 py-2" %> <%= link_to t(".cancel"), transactions_path, class: "text-sm font-medium text-primary px-3 py-2" %>
<%= tag.button t(".save"), <%= tag.button t(".save"),
type: "button", type: "button",

View file

@ -3,9 +3,9 @@
<div class="flex justify-between items-center"> <div class="flex justify-between items-center">
<h3 class="font-medium text-lg"><%= t(".transactions") %></h3> <h3 class="font-medium text-lg"><%= t(".transactions") %></h3>
<%= link_to new_account_transaction_path(account_id: @account), <%= link_to new_account_transaction_path(account_id: @account),
class: "flex gap-1 font-medium items-center bg-gray-50 text-gray-900 p-2 rounded-lg", class: "flex gap-1 font-medium items-center bg-gray-50 text-primary p-2 rounded-lg",
data: { turbo_frame: :modal } do %> data: { turbo_frame: :modal } do %>
<%= lucide_icon("plus", class: "w-5 h-5 text-gray-900") %> <%= lucide_icon("plus", class: "w-5 h-5 text-primary") %>
<span class="text-sm"><%= t(".new") %></span> <span class="text-sm"><%= t(".new") %></span>
<% end %> <% end %>
</div> </div>
@ -16,7 +16,7 @@
</div> </div>
<% if @entries.empty? %> <% if @entries.empty? %>
<p class="text-gray-500 py-4"><%= t(".no_transactions") %></p> <p class="text-secondary py-4"><%= t(".no_transactions") %></p>
<% else %> <% else %>
<div class="space-y-6"> <div class="space-y-6">
<%= entries_by_date(@entries) do |entries, _transfers| %> <%= entries_by_date(@entries) do |entries, _transfers| %>

View file

@ -38,7 +38,7 @@
Current.family.categories.alphabetically, Current.family.categories.alphabetically,
:id, :name, :id, :name,
{ label: t(".category_label"), { label: t(".category_label"),
class: "text-gray-400", include_blank: t(".uncategorized") }, class: "text-subdued", include_blank: t(".uncategorized") },
"data-auto-submit-form-target": "auto" %> "data-auto-submit-form-target": "auto" %>
<% end %> <% end %>
<% end %> <% end %>
@ -70,7 +70,7 @@
:id, :name, :id, :name,
{ include_blank: t(".none"), { include_blank: t(".none"),
label: t(".merchant_label"), label: t(".merchant_label"),
class: "text-gray-400" }, class: "text-subdued" },
"data-auto-submit-form-target": "auto" %> "data-auto-submit-form-target": "auto" %>
<%= ef.select :tag_ids, <%= ef.select :tag_ids,
@ -105,8 +105,8 @@
data: { controller: "auto-submit-form" } do |f| %> data: { controller: "auto-submit-form" } do |f| %>
<div class="flex cursor-pointer items-center gap-4 justify-between"> <div class="flex cursor-pointer items-center gap-4 justify-between">
<div class="text-sm space-y-1"> <div class="text-sm space-y-1">
<h4 class="text-gray-900">One-time <%= @entry.amount.negative? ? "Income" : "Expense" %></h4> <h4 class="text-primary">One-time <%= @entry.amount.negative? ? "Income" : "Expense" %></h4>
<p class="text-gray-500">One-time transactions will be excluded from certain budgeting calculations and reports to help you see what's really important.</p> <p class="text-secondary">One-time transactions will be excluded from certain budgeting calculations and reports to help you see what's really important.</p>
</div> </div>
<div class="relative inline-block select-none"> <div class="relative inline-block select-none">
@ -114,15 +114,15 @@
class: "sr-only peer", class: "sr-only peer",
"data-auto-submit-form-target": "auto" %> "data-auto-submit-form-target": "auto" %>
<label for="account_entry_excluded" <label for="account_entry_excluded"
class="maybe-switch"></label> class="switch"></label>
</div> </div>
</div> </div>
<% end %> <% end %>
<div class="flex items-center justify-between gap-4 p-3"> <div class="flex items-center justify-between gap-4 p-3">
<div class="text-sm space-y-1"> <div class="text-sm space-y-1">
<h4 class="text-gray-900">Transfer or Debt Payment?</h4> <h4 class="text-primary">Transfer or Debt Payment?</h4>
<p class="text-gray-500">Transfers and payments are special types of transactions that indicate money movement between 2 accounts.</p> <p class="text-secondary">Transfers and payments are special types of transactions that indicate money movement between 2 accounts.</p>
</div> </div>
<%= link_to new_account_transaction_transfer_match_path(@entry), class: "btn btn--outline flex items-center gap-2", data: { turbo_frame: :modal } do %> <%= link_to new_account_transaction_transfer_match_path(@entry), class: "btn btn--outline flex items-center gap-2", data: { turbo_frame: :modal } do %>
@ -134,15 +134,15 @@
<!-- Delete Transaction Form --> <!-- Delete Transaction Form -->
<div class="flex items-center justify-between gap-2 p-3"> <div class="flex items-center justify-between gap-2 p-3">
<div class="text-sm space-y-1"> <div class="text-sm space-y-1">
<h4 class="text-gray-900"><%= t(".delete_title") %></h4> <h4 class="text-primary"><%= t(".delete_title") %></h4>
<p class="text-gray-500"><%= t(".delete_subtitle") %></p> <p class="text-secondary"><%= t(".delete_subtitle") %></p>
</div> </div>
<%= button_to t(".delete"), <%= button_to t(".delete"),
account_entry_path(@entry), account_entry_path(@entry),
method: :delete, method: :delete,
class: "rounded-lg px-3 py-2 text-red-500 text-sm class: "rounded-lg px-3 py-2 text-red-500 text-sm
font-medium border border-alpha-black-200", font-medium border border-secondary",
data: { turbo_confirm: true, turbo_frame: "_top" } %> data: { turbo_confirm: true, turbo_frame: "_top" } %>
</div> </div>
</div> </div>

View file

@ -2,7 +2,7 @@
<% if candidates.any? %> <% if candidates.any? %>
<div data-controller="transfer-match" class="space-y-2"> <div data-controller="transfer-match" class="space-y-2">
<p class="text-sm text-gray-500"> <p class="text-sm text-secondary">
Select a method for matching your transactions. Select a method for matching your transactions.
</p> </p>
@ -29,7 +29,7 @@
</div> </div>
</div> </div>
<% else %> <% else %>
<p class="text-sm text-gray-500"> <p class="text-sm text-secondary">
We couldn't find any transactions to match from your other accounts. We couldn't find any transactions to match from your other accounts.
Please select an account and we will create a new inflow transaction for you. Please select an account and we will create a new inflow transaction for you.
</p> </p>

View file

@ -1,7 +1,7 @@
<%# locals: (entry:) %> <%# locals: (entry:) %>
<%= tag.header class: "mb-4 space-y-1", id: dom_id(entry, :header) do %> <%= tag.header class: "mb-4 space-y-1", id: dom_id(entry, :header) do %>
<span class="text-gray-500 text-sm"> <span class="text-secondary text-sm">
<%= t(".balance") %> <%= t(".balance") %>
</span> </span>
@ -13,7 +13,7 @@
</h3> </h3>
</div> </div>
<span class="text-sm text-gray-500"> <span class="text-sm text-secondary">
<%= I18n.l(entry.date, format: :long) %> <%= I18n.l(entry.date, format: :long) %>
</span> </span>
<% end %> <% end %>

View file

@ -3,11 +3,11 @@
<% color = balance_trend&.trend&.color || "#D444F1" %> <% color = balance_trend&.trend&.color || "#D444F1" %>
<% icon = balance_trend&.trend&.icon || "plus" %> <% icon = balance_trend&.trend&.icon || "plus" %>
<div class="p-4 grid grid-cols-12 items-center text-gray-900 text-sm font-medium"> <div class="p-4 grid grid-cols-12 items-center text-primary text-sm font-medium">
<div class="col-span-8 flex items-center gap-4"> <div class="col-span-8 flex items-center gap-4">
<% if selectable %> <% if selectable %>
<%= check_box_tag dom_id(entry, "selection"), <%= check_box_tag dom_id(entry, "selection"),
class: "maybe-checkbox maybe-checkbox--light", class: "checkbox checkbox--light",
data: { id: entry.id, "bulk-select-target": "row", action: "bulk-select#toggleRowSelection" } %> data: { id: entry.id, "bulk-select-target": "row", action: "bulk-select#toggleRowSelection" } %>
<% end %> <% end %>
@ -16,7 +16,7 @@
<%= lucide_icon icon, class: "w-4 h-4 shrink-0" %> <%= lucide_icon icon, class: "w-4 h-4 shrink-0" %>
<% end %> <% end %>
<div class="truncate text-gray-900"> <div class="truncate text-primary">
<% if entry.new_record? %> <% if entry.new_record? %>
<%= content_tag :p, entry.display_name %> <%= content_tag :p, entry.display_name %>
<% else %> <% else %>
@ -33,11 +33,11 @@
<% if balance_trend&.trend %> <% if balance_trend&.trend %>
<%= tag.span format_money(balance_trend.trend.value), style: "color: #{balance_trend.trend.color}" %> <%= tag.span format_money(balance_trend.trend.value), style: "color: #{balance_trend.trend.color}" %>
<% else %> <% else %>
<%= tag.span "--", class: "text-gray-400" %> <%= tag.span "--", class: "text-subdued" %>
<% end %> <% end %>
</div> </div>
<div class="col-span-2 justify-self-end"> <div class="col-span-2 justify-self-end">
<%= tag.p format_money(entry.amount_money), class: "font-medium text-sm text-gray-900" %> <%= tag.p format_money(entry.amount_money), class: "font-medium text-sm text-primary" %>
</div> </div>
</div> </div>

View file

@ -4,14 +4,14 @@
<%= tag.h2 t(".valuations"), class: "font-medium text-lg" %> <%= tag.h2 t(".valuations"), class: "font-medium text-lg" %>
<%= link_to new_account_valuation_path(@account), <%= link_to new_account_valuation_path(@account),
data: { turbo_frame: dom_id(@account.entries.account_valuations.new) }, data: { turbo_frame: dom_id(@account.entries.account_valuations.new) },
class: "flex gap-1 font-medium items-center bg-gray-50 text-gray-900 p-2 rounded-lg" do %> class: "flex gap-1 font-medium items-center bg-gray-50 text-primary p-2 rounded-lg" do %>
<%= lucide_icon("plus", class: "w-5 h-5 text-gray-900") %> <%= lucide_icon("plus", class: "w-5 h-5 text-primary") %>
<%= tag.span t(".new_entry"), class: "text-sm" %> <%= tag.span t(".new_entry"), class: "text-sm" %>
<% end %> <% end %>
</div> </div>
<div class="rounded-xl bg-gray-25 p-1"> <div class="rounded-xl bg-gray-25 p-1">
<div class="grid grid-cols-10 items-center uppercase text-xs font-medium text-gray-500 px-4 py-2"> <div class="grid grid-cols-10 items-center uppercase text-xs font-medium text-secondary px-4 py-2">
<%= tag.p t(".date"), class: "col-span-5" %> <%= tag.p t(".date"), class: "col-span-5" %>
<%= tag.p t(".value"), class: "col-span-2 justify-self-end" %> <%= tag.p t(".value"), class: "col-span-2 justify-self-end" %>
<%= tag.p t(".change"), class: "col-span-2 justify-self-end" %> <%= tag.p t(".change"), class: "col-span-2 justify-self-end" %>
@ -27,7 +27,7 @@
as: :entry, as: :entry,
spacer_template: "account/entries/ruler" %> spacer_template: "account/entries/ruler" %>
<% else %> <% else %>
<p class="text-gray-500 text-sm p-4"><%= t(".no_valuations") %></p> <p class="text-secondary text-sm p-4"><%= t(".no_valuations") %></p>
<% end %> <% end %>
</div> </div>
</div> </div>

View file

@ -51,14 +51,14 @@
<!-- Delete Valuation Form --> <!-- Delete Valuation Form -->
<div class="flex items-center justify-between gap-2 p-3"> <div class="flex items-center justify-between gap-2 p-3">
<div class="text-sm space-y-1"> <div class="text-sm space-y-1">
<h4 class="text-gray-900"><%= t(".delete_title") %></h4> <h4 class="text-primary"><%= t(".delete_title") %></h4>
<p class="text-gray-500"><%= t(".delete_subtitle") %></p> <p class="text-secondary"><%= t(".delete_subtitle") %></p>
</div> </div>
<%= button_to t(".delete"), <%= button_to t(".delete"),
account_entry_path(entry), account_entry_path(entry),
method: :delete, method: :delete,
class: "rounded-lg px-3 py-2 text-red-500 text-sm font-medium border border-alpha-black-200", class: "rounded-lg px-3 py-2 text-red-500 text-sm font-medium border border-secondary",
data: { turbo_confirm: true, turbo_frame: "_top" } %> data: { turbo_confirm: true, turbo_frame: "_top" } %>
</div> </div>
</div> </div>

View file

@ -7,7 +7,7 @@
<div> <div>
<% if account.scheduled_for_deletion? %> <% if account.scheduled_for_deletion? %>
<p class="text-sm font-medium text-gray-900"> <p class="text-sm font-medium text-primary">
<span> <span>
<%= account.name %> <%= account.name %>
</span> </span>
@ -16,7 +16,7 @@
</span> </span>
</p> </p>
<% else %> <% else %>
<%= link_to account.name, account, class: [(account.is_active ? "text-gray-900" : "text-gray-400"), "text-sm font-medium hover:underline"], data: { turbo_frame: "_top" } %> <%= link_to account.name, account, class: [(account.is_active ? "text-primary" : "text-subdued"), "text-sm font-medium hover:underline"], data: { turbo_frame: "_top" } %>
<% if account.has_issues? %> <% if account.has_issues? %>
<div class="text-sm flex items-center gap-1 text-error"> <div class="text-sm flex items-center gap-1 text-error">
<%= lucide_icon "alert-octagon", class: "shrink-0 w-4 h-4" %> <%= lucide_icon "alert-octagon", class: "shrink-0 w-4 h-4" %>
@ -29,12 +29,12 @@
<% unless account.scheduled_for_deletion? %> <% unless account.scheduled_for_deletion? %>
<%= link_to edit_account_path(account, return_to: return_to), data: { turbo_frame: :modal }, class: "group-hover/account:flex hidden hover:opacity-80 items-center justify-center" do %> <%= link_to edit_account_path(account, return_to: return_to), data: { turbo_frame: :modal }, class: "group-hover/account:flex hidden hover:opacity-80 items-center justify-center" do %>
<%= lucide_icon "pencil-line", class: "w-4 h-4 text-gray-500" %> <%= lucide_icon "pencil-line", class: "w-4 h-4 text-secondary" %>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>
<div class="flex items-center gap-8"> <div class="flex items-center gap-8">
<p class="text-sm font-medium <%= account.is_active ? "text-gray-900" : "text-gray-400" %>"> <p class="text-sm font-medium <%= account.is_active ? "text-primary" : "text-subdued" %>">
<%= format_money account.balance_money %> <%= format_money account.balance_money %>
</p> </p>
@ -44,7 +44,7 @@
data: { controller: "auto-submit-form", turbo_frame: "_top" } do |form| %> data: { controller: "auto-submit-form", turbo_frame: "_top" } do |form| %>
<div class="relative inline-block select-none"> <div class="relative inline-block select-none">
<%= form.check_box :is_active, { class: "sr-only peer", data: { "auto-submit-form-target": "auto" } } %> <%= form.check_box :is_active, { class: "sr-only peer", data: { "auto-submit-form-target": "auto" } } %>
<%= form.label :is_active, "&nbsp;".html_safe, class: "maybe-switch" %> <%= form.label :is_active, "&nbsp;".html_safe, class: "switch" %>
</div> </div>
<% end %> <% end %>
<% end %> <% end %>

View file

@ -10,9 +10,9 @@
<summary class="flex gap-4 px-3 py-2 items-center w-full rounded-[10px] font-medium <summary class="flex gap-4 px-3 py-2 items-center w-full rounded-[10px] font-medium
hover:bg-gray-100 cursor-pointer"> hover:bg-gray-100 cursor-pointer">
<%= lucide_icon("chevron-down", <%= lucide_icon("chevron-down",
class: "hidden group-open:block text-gray-500 w-5 h-5") %> class: "hidden group-open:block text-secondary w-5 h-5") %>
<%= lucide_icon("chevron-right", <%= lucide_icon("chevron-right",
class: "group-open:hidden text-gray-500 w-5 h-5") %> class: "group-open:hidden text-secondary w-5 h-5") %>
<div class="text-left"><%= type.model_name.human %></div> <div class="text-left"><%= type.model_name.human %></div>
@ -36,7 +36,7 @@
<div class="overflow-hidden"> <div class="overflow-hidden">
<p class="font-medium truncate"><%= account_value_node.name %></p> <p class="font-medium truncate"><%= account_value_node.name %></p>
<% if account.subtype %> <% if account.subtype %>
<p class="text-xs text-gray-500"><%= account.subtype&.humanize %></p> <p class="text-xs text-secondary"><%= account.subtype&.humanize %></p>
<% end %> <% end %>
</div> </div>
<div class="flex flex-col items-end font-medium text-right ml-auto"> <div class="flex flex-col items-end font-medium text-right ml-auto">
@ -53,7 +53,7 @@
</div> </div>
<% end %> <% end %>
<% end %> <% end %>
<%= link_to new_polymorphic_path(type, step: "method_select"), class: "flex items-center min-h-10 gap-4 px-3 py-2 mb-1 text-gray-500 text-sm font-medium rounded-[10px] hover:bg-gray-100", data: { turbo_frame: "modal" } do %> <%= link_to new_polymorphic_path(type, step: "method_select"), class: "flex items-center min-h-10 gap-4 px-3 py-2 mb-1 text-secondary text-sm font-medium rounded-[10px] hover:bg-gray-100", data: { turbo_frame: "modal" } do %>
<%= lucide_icon("plus", class: "w-5 h-5") %> <%= lucide_icon("plus", class: "w-5 h-5") %>
<%= t(".new_account", type: type.model_name.human.downcase) %> <%= t(".new_account", type: type.model_name.human.downcase) %>
<% end %> <% end %>

View file

@ -1,5 +1,5 @@
<div class="h-10"> <div class="h-10">
</div> </div>
<div class="h-64 flex items-center justify-center"> <div class="h-64 flex items-center justify-center">
<p class="text-gray-500 animate-pulse text-sm">Loading...</p> <p class="text-secondary animate-pulse text-sm">Loading...</p>
</div> </div>

View file

@ -1,7 +1,7 @@
<div class="flex justify-center items-center h-[800px] text-sm"> <div class="flex justify-center items-center h-[800px] text-sm">
<div class="text-center flex flex-col items-center max-w-[300px]"> <div class="text-center flex flex-col items-center max-w-[300px]">
<%= tag.p t(".no_accounts"), class: "text-gray-900 mb-1 font-medium" %> <%= tag.p t(".no_accounts"), class: "text-primary mb-1 font-medium" %>
<%= tag.p t(".empty_message"), class: "text-gray-500 mb-4" %> <%= tag.p t(".empty_message"), class: "text-secondary mb-4" %>
<%= link_to new_account_path, class: "w-fit flex text-white text-sm font-medium items-center gap-1 bg-gray-900 rounded-lg p-2 pr-3", data: { turbo_frame: "modal" } do %> <%= link_to new_account_path, class: "w-fit flex text-white text-sm font-medium items-center gap-1 bg-gray-900 rounded-lg p-2 pr-3", data: { turbo_frame: "modal" } do %>
<%= lucide_icon("plus", class: "w-5 h-5") %> <%= lucide_icon("plus", class: "w-5 h-5") %>

View file

@ -1,8 +1,8 @@
<%# locals: (title:, content:) %> <%# locals: (title:, content:) %>
<div class="rounded-xl bg-white shadow-xs border border-alpha-black-25 p-4"> <div class="rounded-xl bg-white shadow-xs border border-alpha-black-25 p-4">
<h4 class="text-gray-500 text-sm"><%= title %></h4> <h4 class="text-secondary text-sm"><%= title %></h4>
<p class="text-xl font-medium text-gray-900"> <p class="text-xl font-medium text-primary">
<%= content %> <%= content %>
</p> </p>
</div> </div>

View file

@ -5,7 +5,7 @@
<%= turbo_frame_tag dom_id(@account, :chart_details) do %> <%= turbo_frame_tag dom_id(@account, :chart_details) do %>
<div class="px-4"> <div class="px-4">
<% if trend.direction.flat? %> <% if trend.direction.flat? %>
<%= tag.span t(".no_change"), class: "text-gray-500" %> <%= tag.span t(".no_change"), class: "text-secondary" %>
<% else %> <% else %>
<%= tag.span "#{trend.value.positive? ? "+" : ""}#{format_money(trend.value)}", style: "color: #{trend.color}" %> <%= tag.span "#{trend.value.positive? ? "+" : ""}#{format_money(trend.value)}", style: "color: #{trend.color}" %>
<% unless trend.percent.infinite? %> <% unless trend.percent.infinite? %>
@ -13,7 +13,7 @@
<% end %> <% end %>
<% end %> <% end %>
<%= tag.span period_label(period), class: "text-gray-500" %> <%= tag.span period_label(period), class: "text-secondary" %>
</div> </div>
<div class="h-64"> <div class="h-64">
@ -25,11 +25,11 @@
data-time-series-chart-data-value="<%= series.to_json %>"></div> data-time-series-chart-data-value="<%= series.to_json %>"></div>
<% elsif series.empty? %> <% elsif series.empty? %>
<div class="w-full h-full flex items-center justify-center"> <div class="w-full h-full flex items-center justify-center">
<p class="text-gray-500 text-sm">No data available for the selected period.</p> <p class="text-secondary text-sm">No data available for the selected period.</p>
</div> </div>
<% else %> <% else %>
<div class="w-full h-full flex items-center justify-center"> <div class="w-full h-full flex items-center justify-center">
<p class="text-gray-500 text-sm animate-pulse">Calculating latest balance data...</p> <p class="text-secondary text-sm animate-pulse">Calculating latest balance data...</p>
</div> </div>
<% end %> <% end %>
</div> </div>

View file

@ -3,7 +3,7 @@
<% end %> <% end %>
<div class="space-y-4"> <div class="space-y-4">
<header class="flex justify-between items-center text-gray-900 font-medium"> <header class="flex justify-between items-center text-primary font-medium">
<h1 class="text-xl"><%= t(".accounts") %></h1> <h1 class="text-xl"><%= t(".accounts") %></h1>
<div class="flex items-center gap-5"> <div class="flex items-center gap-5">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">

View file

@ -2,9 +2,9 @@
<% accounts.group_by(&:accountable_type).sort_by { |group, _| group }.each do |group, accounts| %> <% accounts.group_by(&:accountable_type).sort_by { |group, _| group }.each do |group, accounts| %>
<div class="bg-gray-25 p-1 rounded-xl"> <div class="bg-gray-25 p-1 rounded-xl">
<div class="flex items-center px-4 py-2 text-xs font-medium text-gray-500"> <div class="flex items-center px-4 py-2 text-xs font-medium text-secondary">
<p><%= to_accountable_title(Accountable.from_type(group)) %></p> <p><%= to_accountable_title(Accountable.from_type(group)) %></p>
<span class="text-gray-400 mx-2">&middot;</span> <span class="text-subdued mx-2">&middot;</span>
<p><%= accounts.count %></p> <p><%= accounts.count %></p>
<p class="ml-auto"><%= totals_by_currency(collection: accounts, money_method: :balance_money) %></p> <p class="ml-auto"><%= totals_by_currency(collection: accounts, money_method: :balance_money) %></p>
</div> </div>

View file

@ -2,13 +2,13 @@
<details open class="group bg-white p-4 border border-alpha-black-25 shadow-xs rounded-xl"> <details open class="group bg-white p-4 border border-alpha-black-25 shadow-xs rounded-xl">
<summary class="flex items-center gap-2 focus-visible:outline-hidden"> <summary class="flex items-center gap-2 focus-visible:outline-hidden">
<%= lucide_icon "chevron-right", class: "group-open:transform group-open:rotate-90 text-gray-500 w-5" %> <%= lucide_icon "chevron-right", class: "group-open:transform group-open:rotate-90 text-secondary w-5" %>
<div class="flex items-center justify-center h-8 w-8 rounded-full bg-black/5"> <div class="flex items-center justify-center h-8 w-8 rounded-full bg-black/5">
<%= lucide_icon("folder-pen", class: "w-5 h-5 text-gray-500") %> <%= lucide_icon("folder-pen", class: "w-5 h-5 text-secondary") %>
</div> </div>
<span class="mr-auto text-sm font-medium text-gray-900"><%= t(".other_accounts") %></span> <span class="mr-auto text-sm font-medium text-primary"><%= t(".other_accounts") %></span>
</summary> </summary>
<div class="space-y-4 mt-4"> <div class="space-y-4 mt-4">

View file

@ -5,11 +5,11 @@
<div class="border-b border-alpha-black-25 p-4 text-gray-800 flex items-center space-x-3"> <div class="border-b border-alpha-black-25 p-4 text-gray-800 flex items-center space-x-3">
<% if back_path %> <% if back_path %>
<%= link_to back_path, class: "flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 focus:outline-gray-300 focus:outline" do %> <%= link_to back_path, class: "flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 focus:outline-gray-300 focus:outline" do %>
<%= lucide_icon("arrow-left", class: "text-gray-500 w-5 h-5") %> <%= lucide_icon("arrow-left", class: "text-secondary w-5 h-5") %>
<% end %> <% end %>
<% end %> <% end %>
<span class="text-gray-400"><%= title %></span> <span class="text-subdued"><%= title %></span>
</div> </div>
<div class="p-2"> <div class="p-2">
@ -19,7 +19,7 @@
<%= yield %> <%= yield %>
</div> </div>
<div class="border-t border-alpha-black-25 p-4 text-gray-500 text-sm flex justify-between"> <div class="border-t border-alpha-black-25 p-4 text-secondary text-sm flex justify-between">
<div class="flex space-x-5"> <div class="flex space-x-5">
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<span>Select</span> <span>Select</span>

View file

@ -4,7 +4,7 @@
<div class="text-sm"> <div class="text-sm">
<%= link_to path, class: "flex items-center gap-4 w-full text-center focus:outline-hidden focus:bg-gray-50 border border-transparent focus:border focus:border-gray-200 px-2 hover:bg-gray-50 rounded-lg p-2" do %> <%= link_to path, class: "flex items-center gap-4 w-full text-center focus:outline-hidden focus:bg-gray-50 border border-transparent focus:border focus:border-gray-200 px-2 hover:bg-gray-50 rounded-lg p-2" do %>
<span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 shadow-[inset_0_0_0_1px_rgba(0,0,0,0.02)]"> <span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 shadow-[inset_0_0_0_1px_rgba(0,0,0,0.02)]">
<%= lucide_icon("keyboard", class: "text-gray-500 w-5 h-5") %> <%= lucide_icon("keyboard", class: "text-secondary w-5 h-5") %>
</span> </span>
<%= t("accounts.new.method_selector.manual_entry") %> <%= t("accounts.new.method_selector.manual_entry") %>
<% end %> <% end %>
@ -13,7 +13,7 @@
<%# Default US-only Link %> <%# Default US-only Link %>
<button data-controller="plaid" data-action="plaid#open modal#close" data-plaid-region-value="us" data-plaid-link-token-value="<%= us_link_token %>" class="flex items-center gap-4 w-full text-center focus:outline-hidden focus:bg-gray-50 border border-transparent focus:border focus:border-gray-200 px-2 hover:bg-gray-50 rounded-lg p-2"> <button data-controller="plaid" data-action="plaid#open modal#close" data-plaid-region-value="us" data-plaid-link-token-value="<%= us_link_token %>" class="flex items-center gap-4 w-full text-center focus:outline-hidden focus:bg-gray-50 border border-transparent focus:border focus:border-gray-200 px-2 hover:bg-gray-50 rounded-lg p-2">
<span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 shadow-[inset_0_0_0_1px_rgba(0,0,0,0.02)]"> <span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 shadow-[inset_0_0_0_1px_rgba(0,0,0,0.02)]">
<%= lucide_icon("link-2", class: "text-gray-500 w-5 h-5") %> <%= lucide_icon("link-2", class: "text-secondary w-5 h-5") %>
</span> </span>
<%= t("accounts.new.method_selector.connected_entry") %> <%= t("accounts.new.method_selector.connected_entry") %>
</button> </button>
@ -23,7 +23,7 @@
<% if eu_link_token %> <% if eu_link_token %>
<button data-controller="plaid" data-action="plaid#open modal#close" data-plaid-region-value="eu" data-plaid-link-token-value="<%= eu_link_token %>" class="flex items-center gap-4 w-full text-center focus:outline-hidden focus:bg-gray-50 border border-transparent focus:border focus:border-gray-200 px-2 hover:bg-gray-50 rounded-lg p-2"> <button data-controller="plaid" data-action="plaid#open modal#close" data-plaid-region-value="eu" data-plaid-link-token-value="<%= eu_link_token %>" class="flex items-center gap-4 w-full text-center focus:outline-hidden focus:bg-gray-50 border border-transparent focus:border focus:border-gray-200 px-2 hover:bg-gray-50 rounded-lg p-2">
<span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 shadow-[inset_0_0_0_1px_rgba(0,0,0,0.02)]"> <span class="flex w-8 h-8 shrink-0 grow-0 items-center justify-center rounded-lg bg-alpha-black-50 shadow-[inset_0_0_0_1px_rgba(0,0,0,0.02)]">
<%= lucide_icon("link-2", class: "text-gray-500 w-5 h-5") %> <%= lucide_icon("link-2", class: "text-secondary w-5 h-5") %>
</span> </span>
<%= t("accounts.new.method_selector.connected_entry_eu") %> <%= t("accounts.new.method_selector.connected_entry_eu") %>
</button> </button>

View file

@ -12,13 +12,13 @@
</button> </button>
<div data-menu-target="content" class="z-10 hidden bg-white rounded-lg border border-alpha-black-25 shadow-xs p-1"> <div data-menu-target="content" class="z-10 hidden bg-white rounded-lg border border-alpha-black-25 shadow-xs p-1">
<%= link_to new_account_valuation_path(account_id: @account.id), data: { turbo_frame: :modal }, class: "block p-2 rounded-lg hover:bg-gray-50 flex items-center gap-2" do %> <%= link_to new_account_valuation_path(account_id: @account.id), data: { turbo_frame: :modal }, class: "block p-2 rounded-lg hover:bg-gray-50 flex items-center gap-2" do %>
<%= lucide_icon("circle-dollar-sign", class: "text-gray-500 w-5 h-5") %> <%= lucide_icon("circle-dollar-sign", class: "text-secondary w-5 h-5") %>
<%= tag.span t(".new_balance"), class: "text-sm" %> <%= tag.span t(".new_balance"), class: "text-sm" %>
<% end %> <% end %>
<% unless @account.crypto? %> <% unless @account.crypto? %>
<%= link_to @account.investment? ? new_account_trade_path(account_id: @account.id) : new_account_transaction_path(account_id: @account.id), data: { turbo_frame: :modal }, class: "block p-2 rounded-lg hover:bg-gray-50 flex items-center gap-2" do %> <%= link_to @account.investment? ? new_account_trade_path(account_id: @account.id) : new_account_transaction_path(account_id: @account.id), data: { turbo_frame: :modal }, class: "block p-2 rounded-lg hover:bg-gray-50 flex items-center gap-2" do %>
<%= lucide_icon("credit-card", class: "text-gray-500 w-5 h-5") %> <%= lucide_icon("credit-card", class: "text-secondary w-5 h-5") %>
<%= tag.span t(".new_transaction"), class: "text-sm" %> <%= tag.span t(".new_transaction"), class: "text-sm" %>
<% end %> <% end %>
<% end %> <% end %>
@ -36,12 +36,12 @@
<div class="flex gap-2 mb-4"> <div class="flex gap-2 mb-4">
<div class="grow"> <div class="grow">
<div class="flex items-center px-3 py-2 gap-2 border border-gray-200 rounded-lg focus-within:ring-gray-100 focus-within:border-gray-900"> <div class="flex items-center px-3 py-2 gap-2 border border-gray-200 rounded-lg focus-within:ring-gray-100 focus-within:border-gray-900">
<%= lucide_icon("search", class: "w-5 h-5 text-gray-500") %> <%= lucide_icon("search", class: "w-5 h-5 text-secondary") %>
<%= hidden_field_tag :account_id, @account.id %> <%= hidden_field_tag :account_id, @account.id %>
<%= form.search_field :search, <%= form.search_field :search,
placeholder: "Search entries by name", placeholder: "Search entries by name",
value: @q[:search], value: @q[:search],
class: "form-field__input placeholder:text-sm placeholder:text-gray-500", class: "form-field__input placeholder:text-sm placeholder:text-secondary",
"data-auto-submit-form-target": "auto" %> "data-auto-submit-form-target": "auto" %>
</div> </div>
</div> </div>
@ -50,7 +50,7 @@
</div> </div>
<% if @entries.empty? %> <% if @entries.empty? %>
<p class="text-gray-500 text-sm p-4"><%= t(".no_entries") %></p> <p class="text-secondary text-sm p-4"><%= t(".no_entries") %></p>
<% else %> <% else %>
<%= tag.div id: dom_id(@account, "entries_bulk_select"), <%= tag.div id: dom_id(@account, "entries_bulk_select"),
data: { data: {
@ -62,10 +62,10 @@
<%= render "account/entries/selection_bar" %> <%= render "account/entries/selection_bar" %>
</div> </div>
<div class="grid bg-gray-25 rounded-xl grid-cols-12 items-center uppercase text-xs font-medium text-gray-500 px-5 py-3 mb-4"> <div class="grid bg-gray-25 rounded-xl grid-cols-12 items-center uppercase text-xs font-medium text-secondary px-5 py-3 mb-4">
<div class="pl-0.5 col-span-8 flex items-center gap-4"> <div class="pl-0.5 col-span-8 flex items-center gap-4">
<%= check_box_tag "selection_entry", <%= check_box_tag "selection_entry",
class: "maybe-checkbox maybe-checkbox--light", class: "checkbox checkbox--light",
data: { action: "bulk-select#togglePageSelection" } %> data: { action: "bulk-select#togglePageSelection" } %>
<p><%= t(".date") %></p> <p><%= t(".date") %></p>
</div> </div>

View file

@ -7,11 +7,11 @@
<div class="flex justify-between px-4 pt-4 mb-2"> <div class="flex justify-between px-4 pt-4 mb-2">
<div class="space-y-2"> <div class="space-y-2">
<div class="flex items-center gap-1"> <div class="flex items-center gap-1">
<%= tag.p title || default_value_title, class: "text-sm font-medium text-gray-500" %> <%= tag.p title || default_value_title, class: "text-sm font-medium text-secondary" %>
<%= tooltip %> <%= tooltip %>
</div> </div>
<%= tag.p format_money(account.balance_money), class: "text-gray-900 text-3xl font-medium" %> <%= tag.p format_money(account.balance_money), class: "text-primary text-3xl font-medium" %>
</div> </div>
<%= form_with url: request.path, method: :get, data: { controller: "auto-submit-form" } do |form| %> <%= form_with url: request.path, method: :get, data: { controller: "auto-submit-form" } do |form| %>

View file

@ -13,7 +13,7 @@
<div class="truncate"> <div class="truncate">
<h2 class="font-medium text-xl truncate"><%= title || account.name %></h2> <h2 class="font-medium text-xl truncate"><%= title || account.name %></h2>
<% if subtitle.present? %> <% if subtitle.present? %>
<p class="text-sm text-gray-500"><%= subtitle %></p> <p class="text-sm text-secondary"><%= subtitle %></p>
<% end %> <% end %>
</div> </div>
</div> </div>
@ -23,12 +23,12 @@
<% if account.plaid_account_id.present? %> <% if account.plaid_account_id.present? %>
<% if Rails.env.development? %> <% if Rails.env.development? %>
<%= button_to sync_plaid_item_path(account.plaid_account.plaid_item), disabled: account.syncing?, data: { turbo: false }, class: "flex items-center gap-2", title: "Sync Account" do %> <%= button_to sync_plaid_item_path(account.plaid_account.plaid_item), disabled: account.syncing?, data: { turbo: false }, class: "flex items-center gap-2", title: "Sync Account" do %>
<%= lucide_icon "refresh-cw", class: "w-4 h-4 text-gray-500 hover:text-gray-400" %> <%= lucide_icon "refresh-cw", class: "w-4 h-4 text-secondary hover:text-subdued" %>
<% end %> <% end %>
<% end %> <% end %>
<% else %> <% else %>
<%= button_to sync_account_path(account), disabled: account.syncing?, data: { turbo: false }, class: "flex items-center gap-2", title: "Sync Account" do %> <%= button_to sync_account_path(account), disabled: account.syncing?, data: { turbo: false }, class: "flex items-center gap-2", title: "Sync Account" do %>
<%= lucide_icon "refresh-cw", class: "w-4 h-4 text-gray-500 hover:text-gray-400" %> <%= lucide_icon "refresh-cw", class: "w-4 h-4 text-secondary hover:text-subdued" %>
<% end %> <% end %>
<% end %> <% end %>

View file

@ -1,3 +1,3 @@
<div class="p-5"> <div class="p-5">
<p class="text-gray-500 animate-pulse">Loading account...</p> <p class="text-secondary animate-pulse">Loading account...</p>
</div> </div>

View file

@ -1,20 +1,20 @@
<%# locals: (account:) %> <%# locals: (account:) %>
<%= contextual_menu do %> <%= contextual_menu do %>
<div class="w-48 p-1 text-sm leading-6 text-gray-900 bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5"> <div class="w-48 p-1 text-sm leading-6 text-primary bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5">
<% if account.plaid_account_id.present? %> <% if account.plaid_account_id.present? %>
<%= link_to accounts_path, <%= link_to accounts_path,
data: { turbo_frame: :_top }, data: { turbo_frame: :_top },
class: "block w-full py-2 px-3 space-x-2 text-gray-900 hover:bg-gray-50 flex items-center rounded-lg" do %> class: "block w-full py-2 px-3 space-x-2 text-primary hover:bg-gray-50 flex items-center rounded-lg" do %>
<%= lucide_icon "pencil-line", class: "w-5 h-5 text-gray-500" %> <%= lucide_icon "pencil-line", class: "w-5 h-5 text-secondary" %>
<span><%= t(".manage") %></span> <span><%= t(".manage") %></span>
<% end %> <% end %>
<% else %> <% else %>
<%= link_to edit_account_path(account), <%= link_to edit_account_path(account),
data: { turbo_frame: :modal }, data: { turbo_frame: :modal },
class: "block w-full py-2 px-3 space-x-2 text-gray-900 hover:bg-gray-50 flex items-center rounded-lg" do %> class: "block w-full py-2 px-3 space-x-2 text-primary hover:bg-gray-50 flex items-center rounded-lg" do %>
<%= lucide_icon "pencil-line", class: "w-5 h-5 text-gray-500" %> <%= lucide_icon "pencil-line", class: "w-5 h-5 text-secondary" %>
<span><%= t(".edit") %></span> <span><%= t(".edit") %></span>
<% end %> <% end %>
@ -22,8 +22,8 @@
<% unless account.crypto? %> <% unless account.crypto? %>
<%= link_to new_import_path, <%= link_to new_import_path,
data: { turbo_frame: :modal }, data: { turbo_frame: :modal },
class: "block w-full py-2 px-3 space-x-2 text-gray-900 hover:bg-gray-50 flex items-center rounded-lg" do %> class: "block w-full py-2 px-3 space-x-2 text-primary hover:bg-gray-50 flex items-center rounded-lg" do %>
<%= lucide_icon "download", class: "w-5 h-5 text-gray-500" %> <%= lucide_icon "download", class: "w-5 h-5 text-secondary" %>
<span><%= t(".import") %></span> <span><%= t(".import") %></span>
<% end %> <% end %>

View file

@ -2,7 +2,7 @@
<% selected_tab = tabs.find { |tab| tab[:key] == params[:tab] } || tabs.first %> <% selected_tab = tabs.find { |tab| tab[:key] == params[:tab] } || tabs.first %>
<div class="flex gap-2 text-sm text-gray-900 font-medium mb-4"> <div class="flex gap-2 text-sm text-primary font-medium mb-4">
<% tabs.each do |tab| %> <% tabs.each do |tab| %>
<%= render "accounts/show/tab", account: account, key: tab[:key], is_selected: selected_tab[:key] == tab[:key] %> <%= render "accounts/show/tab", account: account, key: tab[:key], is_selected: selected_tab[:key] == tab[:key] %>
<% end %> <% end %>

View file

@ -4,7 +4,7 @@
<%= render "accounts/summary/header" %> <%= render "accounts/summary/header" %>
<div class="bg-white rounded-xl shadow-xs border border-alpha-black-100 flex divide-x divide-gray-200"> <div class="bg-white rounded-xl shadow-xs border border-tertiary flex divide-x divide-gray-200">
<div class="w-1/2 p-4 flex items-stretch justify-between"> <div class="w-1/2 p-4 flex items-stretch justify-between">
<div class="space-y-2 grow"> <div class="space-y-2 grow">
<%= render partial: "shared/value_heading", locals: { <%= render partial: "shared/value_heading", locals: {
@ -41,10 +41,10 @@
</div> </div>
<div class="p-4 bg-white rounded-xl shadow-xs border border-alpha-black-25 space-y-4"> <div class="p-4 bg-white rounded-xl shadow-xs border border-alpha-black-25 space-y-4">
<div class="flex justify-between items-center mb-5"> <div class="flex justify-between items-center mb-5">
<h2 class="text-lg font-medium text-gray-900">Assets</h2> <h2 class="text-lg font-medium text-primary">Assets</h2>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<%= link_to new_account_path, class: "btn btn--secondary flex items-center gap-1", data: { turbo_frame: "modal" } do %> <%= link_to new_account_path, class: "btn btn--secondary flex items-center gap-1", data: { turbo_frame: "modal" } do %>
<%= lucide_icon("plus", class: "w-5 h-5 text-gray-500") %> <%= lucide_icon("plus", class: "w-5 h-5 text-secondary") %>
<p><%= t(".new") %></p> <p><%= t(".new") %></p>
<% end %> <% end %>
<%= form_with url: summary_accounts_path, method: :get, data: { controller: "auto-submit-form" } do |form| %> <%= form_with url: summary_accounts_path, method: :get, data: { controller: "auto-submit-form" } do |form| %>
@ -58,18 +58,18 @@
<%= render partial: "pages/account_percentages_table", locals: { account_groups: @account_groups[:assets].children } %> <%= render partial: "pages/account_percentages_table", locals: { account_groups: @account_groups[:assets].children } %>
<% else %> <% else %>
<div class="py-20 flex flex-col items-center"> <div class="py-20 flex flex-col items-center">
<%= lucide_icon "blocks", class: "w-6 h-6 shrink-0 text-gray-500" %> <%= lucide_icon "blocks", class: "w-6 h-6 shrink-0 text-secondary" %>
<p class="text-gray-900 text-sm font-medium mb-1 mt-4"><%= t(".no_assets") %></p> <p class="text-primary text-sm font-medium mb-1 mt-4"><%= t(".no_assets") %></p>
<p class="text-gray-500 text-sm max-w-xs text-center"><%= t(".no_assets_description") %></p> <p class="text-secondary text-sm max-w-xs text-center"><%= t(".no_assets_description") %></p>
</div> </div>
<% end %> <% end %>
</div> </div>
<div class="p-4 bg-white rounded-xl shadow-xs border border-alpha-black-25 space-y-4"> <div class="p-4 bg-white rounded-xl shadow-xs border border-alpha-black-25 space-y-4">
<div class="flex justify-between items-center mb-5"> <div class="flex justify-between items-center mb-5">
<h2 class="text-lg font-medium text-gray-900">Liabilities</h2> <h2 class="text-lg font-medium text-primary">Liabilities</h2>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<%= link_to new_account_path, class: "btn btn--secondary flex items-center gap-1", data: { turbo_frame: "modal" } do %> <%= link_to new_account_path, class: "btn btn--secondary flex items-center gap-1", data: { turbo_frame: "modal" } do %>
<%= lucide_icon("plus", class: "w-5 h-5 text-gray-500") %> <%= lucide_icon("plus", class: "w-5 h-5 text-secondary") %>
<p><%= t(".new") %></p> <p><%= t(".new") %></p>
<% end %> <% end %>
<%= form_with url: summary_accounts_path, method: :get, data: { controller: "auto-submit-form" } do |form| %> <%= form_with url: summary_accounts_path, method: :get, data: { controller: "auto-submit-form" } do |form| %>
@ -83,9 +83,9 @@
<%= render partial: "pages/account_percentages_table", locals: { account_groups: @account_groups[:liabilities].children } %> <%= render partial: "pages/account_percentages_table", locals: { account_groups: @account_groups[:liabilities].children } %>
<% else %> <% else %>
<div class="py-20 flex flex-col items-center"> <div class="py-20 flex flex-col items-center">
<%= lucide_icon "scale", class: "w-6 h-6 shrink-0 text-gray-500" %> <%= lucide_icon "scale", class: "w-6 h-6 shrink-0 text-secondary" %>
<p class="text-gray-900 text-sm font-medium mb-1 mt-4"><%= t(".no_liabilities") %></p> <p class="text-primary text-sm font-medium mb-1 mt-4"><%= t(".no_liabilities") %></p>
<p class="text-gray-500 text-sm max-w-xs text-center"><%= t(".no_liabilities_description") %></p> <p class="text-secondary text-sm max-w-xs text-center"><%= t(".no_liabilities_description") %></p>
</div> </div>
<% end %> <% end %>
</div> </div>

View file

@ -1,12 +1,12 @@
<header class="flex justify-between items-center text-gray-900 font-medium"> <header class="flex justify-between items-center text-primary font-medium">
<h1 class="text-xl"><%= t(".accounts") %></h1> <h1 class="text-xl"><%= t(".accounts") %></h1>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<%= contextual_menu do %> <%= contextual_menu do %>
<div class="w-48 p-1 text-sm leading-6 text-gray-900 bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5"> <div class="w-48 p-1 text-sm leading-6 text-primary bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5">
<%= link_to accounts_path(return_to: summary_accounts_path), <%= link_to accounts_path(return_to: summary_accounts_path),
class: "block w-full py-2 px-3 space-x-2 text-gray-900 hover:bg-gray-50 flex items-center rounded-lg font-normal" do %> class: "block w-full py-2 px-3 space-x-2 text-primary hover:bg-gray-50 flex items-center rounded-lg font-normal" do %>
<%= lucide_icon "settings", class: "w-5 h-5 text-gray-500" %> <%= lucide_icon "settings", class: "w-5 h-5 text-secondary" %>
<span class="text-black"><%= t(".manage") %></span> <span class="text-black"><%= t(".manage") %></span>
<% end %> <% end %>
</div> </div>

View file

@ -6,8 +6,8 @@
<% if pagy.prev %> <% if pagy.prev %>
<%= link_to pagy_url_for(pagy, pagy.prev), <%= link_to pagy_url_for(pagy, pagy.prev),
data: { turbo_frame: :_top }, data: { turbo_frame: :_top },
class: "inline-flex items-center p-2 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700" do %> class: "inline-flex items-center p-2 text-sm font-medium text-secondary hover:border-gray-300 hover:text-gray-700" do %>
<%= lucide_icon("chevron-left", class: "w-5 h-5 text-gray-500") %> <%= lucide_icon("chevron-left", class: "w-5 h-5 text-secondary") %>
<% end %> <% end %>
<% else %> <% else %>
<div class="inline-flex items-center p-2 text-sm font-medium hover:border-gray-300"> <div class="inline-flex items-center p-2 text-sm font-medium hover:border-gray-300">
@ -20,17 +20,17 @@
<% if series_item.is_a?(Integer) %> <% if series_item.is_a?(Integer) %>
<%= link_to pagy_url_for(pagy, series_item), <%= link_to pagy_url_for(pagy, series_item),
data: { turbo_frame: :_top }, data: { turbo_frame: :_top },
class: "rounded-md px-2 py-1 inline-flex items-center text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700" do %> class: "rounded-md px-2 py-1 inline-flex items-center text-sm font-medium text-secondary hover:border-gray-300 hover:text-gray-700" do %>
<%= series_item %> <%= series_item %>
<% end %> <% end %>
<% elsif series_item.is_a?(String) %> <% elsif series_item.is_a?(String) %>
<%= link_to pagy_url_for(pagy, series_item), <%= link_to pagy_url_for(pagy, series_item),
data: { turbo_frame: :_top }, data: { turbo_frame: :_top },
class: "rounded-md px-2 py-1 bg-white border border-alpha-black-25 shadow-xs inline-flex items-center text-sm font-medium text-gray-900" do %> class: "rounded-md px-2 py-1 bg-white border border-alpha-black-25 shadow-xs inline-flex items-center text-sm font-medium text-primary" do %>
<%= series_item %> <%= series_item %>
<% end %> <% end %>
<% elsif series_item == :gap %> <% elsif series_item == :gap %>
<span class="inline-flex items-center px-2 py-1 text-sm font-medium text-gray-500">...</span> <span class="inline-flex items-center px-2 py-1 text-sm font-medium text-secondary">...</span>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>
@ -38,8 +38,8 @@
<% if pagy.next %> <% if pagy.next %>
<%= link_to pagy_url_for(pagy, pagy.next), <%= link_to pagy_url_for(pagy, pagy.next),
data: { turbo_frame: :_top }, data: { turbo_frame: :_top },
class: "inline-flex items-center p-2 text-sm font-medium text-gray-500 hover:border-gray-300 hover:text-gray-700" do %> class: "inline-flex items-center p-2 text-sm font-medium text-secondary hover:border-gray-300 hover:text-gray-700" do %>
<%= lucide_icon("chevron-right", class: "w-5 h-5 text-gray-500") %> <%= lucide_icon("chevron-right", class: "w-5 h-5 text-secondary") %>
<% end %> <% end %>
<% else %> <% else %>
<div class="inline-flex items-center p-2 text-sm font-medium hover:border-gray-300"> <div class="inline-flex items-center p-2 text-sm font-medium hover:border-gray-300">
@ -52,6 +52,6 @@
<%= select_tag :per_page, <%= select_tag :per_page,
options_for_select(["10", "20", "30", "50"], pagy.limit), options_for_select(["10", "20", "30", "50"], pagy.limit),
data: { controller: "selectable-link" }, data: { controller: "selectable-link" },
class: "py-1.5 pr-8 text-sm text-gray-900 font-medium border border-gray-200 rounded-lg focus:border-gray-900 focus:ring-gray-900 focus-visible:ring-gray-900" %> class: "py-1.5 pr-8 text-sm text-primary font-medium border border-gray-200 rounded-lg focus:border-gray-900 focus:ring-gray-900 focus-visible:ring-gray-900" %>
</div> </div>
</nav> </nav>

View file

@ -9,17 +9,17 @@
<% end %> <% end %>
<% if budget.available_to_allocate.negative? %> <% if budget.available_to_allocate.negative? %>
<p class="text-gray-900 text-sm">&gt; 100% set</p> <p class="text-primary text-sm">&gt; 100% set</p>
<% else %> <% else %>
<p class="text-gray-500 text-sm"> <p class="text-secondary text-sm">
<%= number_to_percentage(budget.allocated_percent, precision: 0) %> set <%= number_to_percentage(budget.allocated_percent, precision: 0) %> set
</p> </p>
<% end %> <% end %>
<p class="ml-auto text-sm space-x-1"> <p class="ml-auto text-sm space-x-1">
<span class="<%= budget.available_to_allocate.negative? ? "text-red-500" : "text-gray-900" %>"><%= format_money(budget.allocated_spending_money) %></span> <span class="<%= budget.available_to_allocate.negative? ? "text-red-500" : "text-primary" %>"><%= format_money(budget.allocated_spending_money) %></span>
<span class="text-gray-500"> / </span> <span class="text-secondary"> / </span>
<span class="text-gray-500"><%= format_money(budget.budgeted_spending_money) %></span> <span class="text-secondary"><%= format_money(budget.budgeted_spending_money) %></span>
</p> </p>
</div> </div>
@ -33,12 +33,12 @@
<div class="text-sm"> <div class="text-sm">
<% if budget.available_to_allocate.negative? %> <% if budget.available_to_allocate.negative? %>
<p class="text-gray-500"> <p class="text-secondary">
Budget exceeded by <span class="text-red-500"><%= format_money(budget.available_to_allocate_money.abs) %></span> Budget exceeded by <span class="text-red-500"><%= format_money(budget.available_to_allocate_money.abs) %></span>
</p> </p>
<% else %> <% else %>
<span class="text-gray-900"><%= format_money(budget.available_to_allocate_money) %></span> <span class="text-primary"><%= format_money(budget.available_to_allocate_money) %></span>
<span class="text-gray-500">left to allocate</span> <span class="text-secondary">left to allocate</span>
<% end %> <% end %>
</div> </div>
</div> </div>

View file

@ -18,30 +18,30 @@
<% end %> <% end %>
<div> <div>
<p class="text-sm font-medium text-gray-900"><%= budget_category.category.name %></p> <p class="text-sm font-medium text-primary"><%= budget_category.category.name %></p>
<% if budget_category.initialized? %> <% if budget_category.initialized? %>
<% if budget_category.available_to_spend.negative? %> <% if budget_category.available_to_spend.negative? %>
<p class="text-sm font-medium text-red-500"><%= format_money(budget_category.available_to_spend_money.abs) %> over</p> <p class="text-sm font-medium text-red-500"><%= format_money(budget_category.available_to_spend_money.abs) %> over</p>
<% elsif budget_category.available_to_spend.zero? %> <% elsif budget_category.available_to_spend.zero? %>
<p class="text-sm font-medium <%= budget_category.budgeted_spending.positive? ? "text-orange-500" : "text-gray-500" %>"> <p class="text-sm font-medium <%= budget_category.budgeted_spending.positive? ? "text-orange-500" : "text-secondary" %>">
<%= format_money(budget_category.available_to_spend_money) %> left <%= format_money(budget_category.available_to_spend_money) %> left
</p> </p>
<% else %> <% else %>
<p class="text-sm text-gray-500 font-medium"><%= format_money(budget_category.available_to_spend_money) %> left</p> <p class="text-sm text-secondary font-medium"><%= format_money(budget_category.available_to_spend_money) %> left</p>
<% end %> <% end %>
<% else %> <% else %>
<p class="text-sm text-gray-500 font-medium"> <p class="text-sm text-secondary font-medium">
<%= format_money(budget_category.category.avg_monthly_total_money, precision: 0) %> avg <%= format_money(budget_category.category.avg_monthly_total_money, precision: 0) %> avg
</p> </p>
<% end %> <% end %>
</div> </div>
<div class="ml-auto text-right"> <div class="ml-auto text-right">
<p class="text-sm font-medium text-gray-900"><%= format_money(budget_category.actual_spending_money) %></p> <p class="text-sm font-medium text-primary"><%= format_money(budget_category.actual_spending_money) %></p>
<% if budget_category.initialized? %> <% if budget_category.initialized? %>
<p class="text-sm text-gray-500">from <%= format_money(budget_category.budgeted_spending_money) %></p> <p class="text-sm text-secondary">from <%= format_money(budget_category.budgeted_spending_money) %></p>
<% end %> <% end %>
</div> </div>
<% end %> <% end %>

View file

@ -6,16 +6,16 @@
<div class="w-1 h-3 rounded-xl mt-1" style="background-color: <%= budget_category.category.color %>"></div> <div class="w-1 h-3 rounded-xl mt-1" style="background-color: <%= budget_category.category.color %>"></div>
<div class="text-sm mr-3"> <div class="text-sm mr-3">
<p class="text-gray-900 font-medium mb-0.5"><%= budget_category.category.name %></p> <p class="text-primary font-medium mb-0.5"><%= budget_category.category.name %></p>
<p class="text-gray-500"><%= format_money(budget_category.category.avg_monthly_total_money, precision: 0) %>/m average</p> <p class="text-secondary"><%= format_money(budget_category.category.avg_monthly_total_money, precision: 0) %>/m average</p>
</div> </div>
<div class="ml-auto"> <div class="ml-auto">
<%= form_with model: [budget_category.budget, budget_category], data: { controller: "auto-submit-form preserve-focus" } do |f| %> <%= form_with model: [budget_category.budget, budget_category], data: { controller: "auto-submit-form preserve-focus" } do |f| %>
<div class="form-field w-[120px]"> <div class="form-field w-[120px]">
<div class="flex items-center"> <div class="flex items-center">
<span class="text-gray-500 text-sm mr-2"><%= currency.symbol %></span> <span class="text-secondary text-sm mr-2"><%= currency.symbol %></span>
<%= f.number_field :budgeted_spending, <%= f.number_field :budgeted_spending,
class: "form-field__input text-right [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none", class: "form-field__input text-right [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
placeholder: "0", placeholder: "0",

View file

@ -4,7 +4,7 @@
budget_path(budget), budget_path(budget),
class: "block btn btn--primary w-full text-center" %> class: "block btn btn--primary w-full text-center" %>
<% else %> <% else %>
<span class="block btn btn--secondary w-full text-center text-gray-400 cursor-not-allowed"> <span class="block btn btn--secondary w-full text-center text-subdued cursor-not-allowed">
Confirm Confirm
</span> </span>
<% end %> <% end %>

View file

@ -1,7 +1,7 @@
<div class="flex justify-center items-center"> <div class="flex justify-center items-center">
<div class="text-center flex flex-col items-center max-w-[500px]"> <div class="text-center flex flex-col items-center max-w-[500px]">
<h2 class="text-lg text-gray-900 font-medium">Oops!</h2> <h2 class="text-lg text-primary font-medium">Oops!</h2>
<p class="text-gray-500 text-sm max-w-sm mx-auto mb-4"> <p class="text-secondary text-sm max-w-sm mx-auto mb-4">
You have not created or assigned any expense categories to your transactions yet. You have not created or assigned any expense categories to your transactions yet.
</p> </p>

View file

@ -6,14 +6,14 @@
<div class="w-1 h-3 rounded-xl mt-1" style="background-color: <%= budget_category.category.color %>"></div> <div class="w-1 h-3 rounded-xl mt-1" style="background-color: <%= budget_category.category.color %>"></div>
<div class="text-sm mr-3"> <div class="text-sm mr-3">
<p class="text-gray-900 font-medium mb-0.5"><%= budget_category.category.name %></p> <p class="text-primary font-medium mb-0.5"><%= budget_category.category.name %></p>
<p class="text-gray-500"><%= format_money(Money.new(budget_category.category.avg_monthly_total, budget_category.category.family.currency), precision: 0) %>/m average</p> <p class="text-secondary"><%= format_money(Money.new(budget_category.category.avg_monthly_total, budget_category.category.family.currency), precision: 0) %>/m average</p>
</div> </div>
<div class="ml-auto"> <div class="ml-auto">
<div class="form-field w-[120px]"> <div class="form-field w-[120px]">
<div class="flex items-center"> <div class="flex items-center">
<span class="text-gray-400 text-sm mr-2">$</span> <span class="text-subdued text-sm mr-2">$</span>
<%= text_field_tag :uncategorized, budget_category.budgeted_spending_money, autocomplete: "off", class: "form-field__input text-right [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none", disabled: true %> <%= text_field_tag :uncategorized, budget_category.budgeted_spending_money, autocomplete: "off", class: "form-field__input text-right [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none", disabled: true %>
</div> </div>
</div> </div>

View file

@ -8,8 +8,8 @@
<div> <div>
<div class="space-y-6"> <div class="space-y-6">
<div class="text-center space-y-2"> <div class="text-center space-y-2">
<h1 class="text-3xl text-gray-900 font-medium">Edit your category budgets</h1> <h1 class="text-3xl text-primary font-medium">Edit your category budgets</h1>
<p class="text-gray-500 text-sm max-w-md mx-auto"> <p class="text-secondary text-sm max-w-md mx-auto">
Adjust category budgets to set spending limits. Unallocated funds will be automatically assigned as uncategorized. Adjust category budgets to set spending limits. Unallocated funds will be automatically assigned as uncategorized.
</p> </p>
</div> </div>
@ -31,7 +31,7 @@
<div class="space-y-4"> <div class="space-y-4">
<% group.budget_subcategories.each do |budget_subcategory| %> <% group.budget_subcategories.each do |budget_subcategory| %>
<div class="w-full flex items-center gap-4"> <div class="w-full flex items-center gap-4">
<div class="ml-4 flex items-center justify-center text-gray-400"> <div class="ml-4 flex items-center justify-center text-subdued">
<%= lucide_icon "corner-down-right", class: "w-5 h-5 shrink-0" %> <%= lucide_icon "corner-down-right", class: "w-5 h-5 shrink-0" %>
</div> </div>

View file

@ -2,14 +2,14 @@
<div class="space-y-4"> <div class="space-y-4">
<header class="flex justify-between"> <header class="flex justify-between">
<div> <div>
<p class="text-sm text-gray-500">Category</p> <p class="text-sm text-secondary">Category</p>
<h3 class="text-2xl font-medium text-gray-900"> <h3 class="text-2xl font-medium text-primary">
<%= @budget_category.category.name %> <%= @budget_category.category.name %>
</h3> </h3>
<% if @budget_category.budget.initialized? %> <% if @budget_category.budget.initialized? %>
<p class="text-sm text-gray-500"> <p class="text-sm text-secondary">
<span class="text-gray-900"> <span class="text-primary">
<%= format_money(@budget_category.actual_spending_money) %> <%= format_money(@budget_category.actual_spending_money) %>
</span> </span>
<span>/</span> <span>/</span>
@ -28,26 +28,26 @@
<details class="group space-y-2" open> <details class="group space-y-2" open>
<summary class="flex list-none items-center justify-between rounded-xl px-3 py-2 <summary class="flex list-none items-center justify-between rounded-xl px-3 py-2
text-xs font-medium uppercase text-gray-500 bg-gray-25 focus-visible:outline-hidden"> text-xs font-medium uppercase text-secondary bg-gray-25 focus-visible:outline-hidden">
<h4>Overview</h4> <h4>Overview</h4>
<%= lucide_icon "chevron-down", <%= lucide_icon "chevron-down",
class: "group-open:transform group-open:rotate-180 text-gray-500 w-5" %> class: "group-open:transform group-open:rotate-180 text-secondary w-5" %>
</summary> </summary>
<div class="pb-4"> <div class="pb-4">
<dl class="space-y-3 px-3 py-2"> <dl class="space-y-3 px-3 py-2">
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500"> <dt class="text-secondary">
<%= @budget_category.budget.start_date.strftime("%b %Y") %> spending <%= @budget_category.budget.start_date.strftime("%b %Y") %> spending
</dt> </dt>
<dd class="text-gray-900 font-medium"> <dd class="text-primary font-medium">
<%= format_money @budget_category.actual_spending_money %> <%= format_money @budget_category.actual_spending_money %>
</dd> </dd>
</div> </div>
<% if @budget_category.budget.initialized? %> <% if @budget_category.budget.initialized? %>
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500">Status</dt> <dt class="text-secondary">Status</dt>
<% if @budget_category.available_to_spend.negative? %> <% if @budget_category.available_to_spend.negative? %>
<dd class="text-red-500 flex items-center gap-1 text-red-500 font-medium"> <dd class="text-red-500 flex items-center gap-1 text-red-500 font-medium">
<%= lucide_icon "alert-circle", class: "shrink-0 w-4 h-4 text-red-500" %> <%= lucide_icon "alert-circle", class: "shrink-0 w-4 h-4 text-red-500" %>
@ -61,7 +61,7 @@
<span>left</span> <span>left</span>
</dd> </dd>
<% else %> <% else %>
<dd class="text-gray-900 flex items-center gap-1 text-green-500 font-medium"> <dd class="text-primary flex items-center gap-1 text-green-500 font-medium">
<%= lucide_icon "check-circle-2", class: "shrink-0 w-4 h-4 text-green-500" %> <%= lucide_icon "check-circle-2", class: "shrink-0 w-4 h-4 text-green-500" %>
<%= format_money @budget_category.available_to_spend_money %> <%= format_money @budget_category.available_to_spend_money %>
<span>left</span> <span>left</span>
@ -70,23 +70,23 @@
</div> </div>
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500">Budgeted</dt> <dt class="text-secondary">Budgeted</dt>
<dd class="text-gray-900 font-medium"> <dd class="text-primary font-medium">
<%= format_money @budget_category.budgeted_spending_money %> <%= format_money @budget_category.budgeted_spending_money %>
</dd> </dd>
</div> </div>
<% end %> <% end %>
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500">Monthly average spending</dt> <dt class="text-secondary">Monthly average spending</dt>
<dd class="text-gray-900 font-medium"> <dd class="text-primary font-medium">
<%= format_money @budget_category.category.avg_monthly_total_money, precision: 0 %> <%= format_money @budget_category.category.avg_monthly_total_money, precision: 0 %>
</dd> </dd>
</div> </div>
<div class="flex items-center justify-between text-sm"> <div class="flex items-center justify-between text-sm">
<dt class="text-gray-500">Monthly median spending</dt> <dt class="text-secondary">Monthly median spending</dt>
<dd class="text-gray-900 font-medium"> <dd class="text-primary font-medium">
<%= format_money @budget_category.category.median_monthly_total_money, precision: 0 %> <%= format_money @budget_category.category.median_monthly_total_money, precision: 0 %>
</dd> </dd>
</div> </div>
@ -96,10 +96,10 @@
<details class="group space-y-2" open> <details class="group space-y-2" open>
<summary class="flex list-none items-center justify-between rounded-xl px-3 py-2 <summary class="flex list-none items-center justify-between rounded-xl px-3 py-2
text-xs font-medium uppercase text-gray-500 bg-gray-25 focus-visible:outline-hidden"> text-xs font-medium uppercase text-secondary bg-gray-25 focus-visible:outline-hidden">
<h4>Recent Transactions</h4> <h4>Recent Transactions</h4>
<%= lucide_icon "chevron-down", <%= lucide_icon "chevron-down",
class: "group-open:transform group-open:rotate-180 text-gray-500 w-5" %> class: "group-open:transform group-open:rotate-180 text-secondary w-5" %>
</summary> </summary>
<div class="space-y-2"> <div class="space-y-2">
@ -117,12 +117,12 @@
<div class="flex justify-between w-full"> <div class="flex justify-between w-full">
<div> <div>
<p class="text-gray-500 text-xs uppercase"> <p class="text-secondary text-xs uppercase">
<%= entry.date.strftime("%b %d") %> <%= entry.date.strftime("%b %d") %>
</p> </p>
<p class="text-gray-900"><%= entry.name %></p> <p class="text-primary"><%= entry.name %></p>
</div> </div>
<p class="text-gray-900 font-medium"> <p class="text-primary font-medium">
<%= format_money entry.amount_money %> <%= format_money entry.amount_money %>
</p> </p>
</div> </div>
@ -139,7 +139,7 @@
data: { turbo_frame: :_top }, data: { turbo_frame: :_top },
class: "block text-center btn btn--outline w-full" %> class: "block text-center btn btn--outline w-full" %>
<% else %> <% else %>
<p class="text-gray-500 text-sm mb-4"> <p class="text-secondary text-sm mb-4">
No transactions found for this budget period. No transactions found for this budget period.
</p> </p>
<% end %> <% end %>

View file

@ -2,11 +2,11 @@
<div> <div>
<div class="p-4 border-b border-gray-100"> <div class="p-4 border-b border-gray-100">
<h3 class="text-sm text-gray-500 mb-2">Income</h3> <h3 class="text-sm text-secondary mb-2">Income</h3>
<% income_totals = budget.income_categories_with_totals %> <% income_totals = budget.income_categories_with_totals %>
<% income_categories = income_totals.category_totals.reject { |ct| ct.amount_money.zero? }.sort_by { |ct| ct.percentage }.reverse %> <% income_categories = income_totals.category_totals.reject { |ct| ct.amount_money.zero? }.sort_by { |ct| ct.percentage }.reverse %>
<span class="inline-block mb-2 text-xl font-medium text-gray-900"> <span class="inline-block mb-2 text-xl font-medium text-primary">
<%= format_money(income_totals.total_money) %> <%= format_money(income_totals.total_money) %>
</span> </span>
@ -22,8 +22,8 @@
<% income_categories.each do |item| %> <% income_categories.each do |item| %>
<div class="flex items-center gap-1.5"> <div class="flex items-center gap-1.5">
<div class="w-2.5 h-2.5 rounded-full shrink-0" style="background-color: <%= item.category.color %>"></div> <div class="w-2.5 h-2.5 rounded-full shrink-0" style="background-color: <%= item.category.color %>"></div>
<span class="text-gray-500"><%= item.category.name %></span> <span class="text-secondary"><%= item.category.name %></span>
<span class="text-gray-900"><%= number_to_percentage(item.percentage, precision: 0) %></span> <span class="text-primary"><%= number_to_percentage(item.percentage, precision: 0) %></span>
</div> </div>
<% end %> <% end %>
</div> </div>
@ -32,12 +32,12 @@
</div> </div>
<div class="p-4"> <div class="p-4">
<h3 class="text-sm text-gray-500 mb-2">Expenses</h3> <h3 class="text-sm text-secondary mb-2">Expenses</h3>
<% expense_totals = budget.expense_categories_with_totals %> <% expense_totals = budget.expense_categories_with_totals %>
<% expense_categories = expense_totals.category_totals.reject { |ct| ct.amount_money.zero? || ct.category.subcategory? }.sort_by { |ct| ct.percentage }.reverse %> <% expense_categories = expense_totals.category_totals.reject { |ct| ct.amount_money.zero? || ct.category.subcategory? }.sort_by { |ct| ct.percentage }.reverse %>
<span class="inline-block mb-2 text-xl font-medium text-gray-900"><%= format_money(expense_totals.total_money) %></span> <span class="inline-block mb-2 text-xl font-medium text-primary"><%= format_money(expense_totals.total_money) %></span>
<% if expense_categories.any? %> <% if expense_categories.any? %>
<div> <div>
@ -51,8 +51,8 @@
<% expense_categories.each do |item| %> <% expense_categories.each do |item| %>
<div class="flex items-center gap-1.5"> <div class="flex items-center gap-1.5">
<div class="w-2.5 h-2.5 rounded-full shrink-0" style="background-color: <%= item.category.color %>"></div> <div class="w-2.5 h-2.5 rounded-full shrink-0" style="background-color: <%= item.category.color %>"></div>
<span class="text-gray-500"><%= item.category.name %></span> <span class="text-secondary"><%= item.category.name %></span>
<span class="text-gray-900"><%= number_to_percentage(item.percentage, precision: 0) %></span> <span class="text-primary"><%= number_to_percentage(item.percentage, precision: 0) %></span>
</div> </div>
<% end %> <% end %>
</div> </div>

View file

@ -1,9 +1,9 @@
<%# locals: (budget:) %> <%# locals: (budget:) %>
<div> <div>
<div class="flex items-center gap-1.5 px-4 py-2 text-xs font-medium text-gray-500 uppercase"> <div class="flex items-center gap-1.5 px-4 py-2 text-xs font-medium text-secondary uppercase">
<p>Categories</p> <p>Categories</p>
<span class="text-gray-400">&middot;</span> <span class="text-subdued">&middot;</span>
<p><%= budget.budget_categories.count %></p> <p><%= budget.budget_categories.count %></p>
<p class="ml-auto">Amount</p> <p class="ml-auto">Amount</p>
@ -24,7 +24,7 @@
<div> <div>
<% group.budget_subcategories.each do |budget_subcategory| %> <% group.budget_subcategories.each do |budget_subcategory| %>
<div class="w-full flex items-center -mt-4"> <div class="w-full flex items-center -mt-4">
<div class="ml-8 flex items-center justify-center text-gray-400"> <div class="ml-8 flex items-center justify-center text-subdued">
<%= lucide_icon "corner-down-right", class: "w-5 h-5 shrink-0" %> <%= lucide_icon "corner-down-right", class: "w-5 h-5 shrink-0" %>
</div> </div>

View file

@ -8,18 +8,18 @@
<span>Spent</span> <span>Spent</span>
</div> </div>
<div class="text-3xl font-medium <%= budget.available_to_spend.negative? ? "text-red-500" : "text-gray-900" %>"> <div class="text-3xl font-medium <%= budget.available_to_spend.negative? ? "text-red-500" : "text-primary" %>">
<%= format_money(budget.actual_spending_money) %> <%= format_money(budget.actual_spending_money) %>
</div> </div>
<%= link_to edit_budget_path(budget), class: "btn btn--secondary flex items-center gap-1 mt-2" do %> <%= link_to edit_budget_path(budget), class: "btn btn--secondary flex items-center gap-1 mt-2" do %>
<span class="text-gray-900 font-medium"> <span class="text-primary font-medium">
of <%= format_money(budget.budgeted_spending_money) %> of <%= format_money(budget.budgeted_spending_money) %>
</span> </span>
<%= lucide_icon "pencil", class: "w-4 h-4 text-gray-500 hover:text-gray-600" %> <%= lucide_icon "pencil", class: "w-4 h-4 text-secondary hover:text-gray-600" %>
<% end %> <% end %>
<% else %> <% else %>
<div class="text-gray-400 text-3xl mb-2"> <div class="text-subdued text-3xl mb-2">
<span><%= format_money Money.new(0, budget.currency || budget.family.currency) %></span> <span><%= format_money Money.new(0, budget.currency || budget.family.currency) %></span>
</div> </div>
<%= link_to edit_budget_path(budget), class: "flex items-center gap-2 btn btn--primary" do %> <%= link_to edit_budget_path(budget), class: "flex items-center gap-2 btn btn--primary" do %>
@ -34,26 +34,26 @@
<div class="flex flex-col gap-2 items-center"> <div class="flex flex-col gap-2 items-center">
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<div class="w-1 h-3 rounded-xl" style="background-color: <%= bc.category.color %>"></div> <div class="w-1 h-3 rounded-xl" style="background-color: <%= bc.category.color %>"></div>
<p class="text-sm text-gray-500"><%= bc.category.name %></p> <p class="text-sm text-secondary"><%= bc.category.name %></p>
</div> </div>
<p class="text-3xl font-medium <%= bc.available_to_spend.negative? ? "text-red-500" : "text-gray-900" %>"> <p class="text-3xl font-medium <%= bc.available_to_spend.negative? ? "text-red-500" : "text-primary" %>">
<%= format_money(bc.actual_spending_money) %> <%= format_money(bc.actual_spending_money) %>
</p> </p>
<%= link_to budget_budget_categories_path(budget), class: "btn btn--secondary flex items-center gap-1" do %> <%= link_to budget_budget_categories_path(budget), class: "btn btn--secondary flex items-center gap-1" do %>
<span>of <%= format_money(bc.budgeted_spending_money, precision: 0) %></span> <span>of <%= format_money(bc.budgeted_spending_money, precision: 0) %></span>
<%= lucide_icon "pencil", class: "w-4 h-4 text-gray-500 shrink-0" %> <%= lucide_icon "pencil", class: "w-4 h-4 text-secondary shrink-0" %>
<% end %> <% end %>
</div> </div>
</div> </div>
<% end %> <% end %>
<div id="segment_unused" class="hidden"> <div id="segment_unused" class="hidden">
<p class="text-sm text-gray-500 text-center mb-2">Unused</p> <p class="text-sm text-secondary text-center mb-2">Unused</p>
<p class="text-3xl font-medium text-gray-900"> <p class="text-3xl font-medium text-primary">
<%= format_money(budget.available_to_spend_money) %> <%= format_money(budget.available_to_spend_money) %>
</p> </p>
</div> </div>

View file

@ -7,7 +7,7 @@
<%= lucide_icon "chevron-left" %> <%= lucide_icon "chevron-left" %>
<% end %> <% end %>
<% else %> <% else %>
<%= lucide_icon "chevron-left", class: "text-gray-400" %> <%= lucide_icon "chevron-left", class: "text-subdued" %>
<% end %> <% end %>
<% if @next_budget %> <% if @next_budget %>
@ -15,14 +15,14 @@
<%= lucide_icon "chevron-right" %> <%= lucide_icon "chevron-right" %>
<% end %> <% end %>
<% else %> <% else %>
<%= lucide_icon "chevron-right", class: "text-gray-400" %> <%= lucide_icon "chevron-right", class: "text-subdued" %>
<% end %> <% end %>
</div> </div>
<div data-controller="menu" data-menu-placement-value="bottom-start"> <div data-controller="menu" data-menu-placement-value="bottom-start">
<%= tag.button data: { menu_target: "button" }, class: "flex items-center gap-1 hover:bg-gray-50 rounded-md p-2" do %> <%= tag.button data: { menu_target: "button" }, class: "flex items-center gap-1 hover:bg-gray-50 rounded-md p-2" do %>
<span class="text-gray-900 font-medium"><%= @budget.name %></span> <span class="text-primary font-medium"><%= @budget.name %></span>
<%= lucide_icon "chevron-down", class: "w-5 h-5 shrink-0 text-gray-500" %> <%= lucide_icon "chevron-down", class: "w-5 h-5 shrink-0 text-secondary" %>
<% end %> <% end %>
<div data-menu-target="content" class="hidden z-10"> <div data-menu-target="content" class="hidden z-10">
@ -32,7 +32,7 @@
<div class="ml-auto"> <div class="ml-auto">
<% if @budget.current? %> <% if @budget.current? %>
<span class="border border-alpha-black-200 text-gray-900 text-sm font-medium px-3 py-2 rounded-lg">Today</span> <span class="border border-secondary text-primary text-sm font-medium px-3 py-2 rounded-lg">Today</span>
<% else %> <% else %>
<%= link_to "Today", budget_path(@latest_budget), class: "btn btn--outline" %> <%= link_to "Today", budget_path(@latest_budget), class: "btn btn--outline" %>
<% end %> <% end %>

View file

@ -11,9 +11,9 @@
<% is_current = request.path == step[:path] %> <% is_current = request.path == step[:path] %>
<% text_class = if is_current <% text_class = if is_current
"text-gray-900" "text-primary"
else else
step[:is_complete] ? "text-green-600" : "text-gray-500" step[:is_complete] ? "text-green-600" : "text-secondary"
end %> end %>
<% step_class = if is_current <% step_class = if is_current
"bg-gray-900 text-white" "bg-gray-900 text-white"

View file

@ -2,9 +2,9 @@
<div> <div>
<div class="p-4 border-b border-gray-100"> <div class="p-4 border-b border-gray-100">
<h3 class="text-sm text-gray-500 mb-2">Expected income</h3> <h3 class="text-sm text-secondary mb-2">Expected income</h3>
<span class="inline-block mb-2 text-xl font-medium text-gray-900"> <span class="inline-block mb-2 text-xl font-medium text-primary">
<%= format_money(budget.expected_income_money) %> <%= format_money(budget.expected_income_money) %>
</span> </span>
@ -19,12 +19,12 @@
<% end %> <% end %>
</div> </div>
<div class="flex justify-between text-sm"> <div class="flex justify-between text-sm">
<p class="text-gray-500"><%= format_money(budget.actual_income_money) %> earned</p> <p class="text-secondary"><%= format_money(budget.actual_income_money) %> earned</p>
<p class="font-medium"> <p class="font-medium">
<% if budget.remaining_expected_income.negative? %> <% if budget.remaining_expected_income.negative? %>
<span class="text-green-500"><%= format_money(budget.remaining_expected_income_money.abs) %> over</span> <span class="text-green-500"><%= format_money(budget.remaining_expected_income_money.abs) %> over</span>
<% else %> <% else %>
<span class="text-gray-900"><%= format_money(budget.remaining_expected_income_money) %> left</span> <span class="text-primary"><%= format_money(budget.remaining_expected_income_money) %> left</span>
<% end %> <% end %>
</p> </p>
</div> </div>
@ -32,9 +32,9 @@
</div> </div>
<div class="p-4"> <div class="p-4">
<h3 class="text-sm text-gray-500 mb-2">Budgeted</h3> <h3 class="text-sm text-secondary mb-2">Budgeted</h3>
<span class="inline-block mb-2 text-xl font-medium text-gray-900"> <span class="inline-block mb-2 text-xl font-medium text-primary">
<%= format_money(budget.budgeted_spending_money) %> <%= format_money(budget.budgeted_spending_money) %>
</span> </span>
@ -49,12 +49,12 @@
<% end %> <% end %>
</div> </div>
<div class="flex justify-between text-sm"> <div class="flex justify-between text-sm">
<p class="text-gray-500"><%= format_money(budget.actual_spending_money) %> spent</p> <p class="text-secondary"><%= format_money(budget.actual_spending_money) %> spent</p>
<p class="font-medium"> <p class="font-medium">
<% if budget.available_to_spend.negative? %> <% if budget.available_to_spend.negative? %>
<span class="text-red-500"><%= format_money(budget.available_to_spend_money.abs) %> over</span> <span class="text-red-500"><%= format_money(budget.available_to_spend_money.abs) %> over</span>
<% else %> <% else %>
<span class="text-gray-900"><%= format_money(budget.available_to_spend_money) %> left</span> <span class="text-primary"><%= format_money(budget.available_to_spend_money) %> left</span>
<% end %> <% end %>
</p> </p>
</div> </div>

View file

@ -2,12 +2,12 @@
<div class="flex flex-col gap-4 items-center justify-center h-full"> <div class="flex flex-col gap-4 items-center justify-center h-full">
<%= lucide_icon "alert-triangle", class: "w-6 h-6 text-red-500" %> <%= lucide_icon "alert-triangle", class: "w-6 h-6 text-red-500" %>
<p class="text-gray-500 text-sm text-center">You have over-allocated your budget. Please fix your allocations.</p> <p class="text-secondary text-sm text-center">You have over-allocated your budget. Please fix your allocations.</p>
<%= link_to budget_budget_categories_path(budget), class: "btn btn--secondary flex items-center gap-1" do %> <%= link_to budget_budget_categories_path(budget), class: "btn btn--secondary flex items-center gap-1" do %>
<span class="text-gray-900 font-medium"> <span class="text-primary font-medium">
Fix allocations Fix allocations
</span> </span>
<%= lucide_icon "pencil", class: "w-4 h-4 text-gray-500 hover:text-gray-600" %> <%= lucide_icon "pencil", class: "w-4 h-4 text-secondary hover:text-gray-600" %>
<% end %> <% end %>
</div> </div>

View file

@ -5,25 +5,25 @@
<div class="flex items-center gap-2 justify-between"> <div class="flex items-center gap-2 justify-between">
<% if year > family.oldest_entry_date.year %> <% if year > family.oldest_entry_date.year %>
<%= link_to picker_budgets_path(year: year - 1), data: { turbo_frame: "budget_picker" }, class: "p-2 flex items-center justify-center hover:bg-alpha-black-25 rounded-md" do %> <%= link_to picker_budgets_path(year: year - 1), data: { turbo_frame: "budget_picker" }, class: "p-2 flex items-center justify-center hover:bg-alpha-black-25 rounded-md" do %>
<%= lucide_icon "chevron-left", class: "w-5 h-5 shrink-0 text-gray-500" %> <%= lucide_icon "chevron-left", class: "w-5 h-5 shrink-0 text-secondary" %>
<% end %> <% end %>
<% else %> <% else %>
<span class="p-2 flex items-center justify-center text-gray-300 rounded-md"> <span class="p-2 flex items-center justify-center text-gray-300 rounded-md">
<%= lucide_icon "chevron-left", class: "w-5 h-5 shrink-0 text-gray-400" %> <%= lucide_icon "chevron-left", class: "w-5 h-5 shrink-0 text-subdued" %>
</span> </span>
<% end %> <% end %>
<span class="w-40 text-center px-3 py-2 border border-alpha-black-100 rounded-md" data-budget-picker-target="year"> <span class="w-40 text-center px-3 py-2 border border-tertiary rounded-md" data-budget-picker-target="year">
<%= year %> <%= year %>
</span> </span>
<% if year < Date.current.year %> <% if year < Date.current.year %>
<%= link_to picker_budgets_path(year: year + 1), data: { turbo_frame: "budget_picker" }, class: "p-2 flex items-center justify-center hover:bg-alpha-black-25 rounded-md" do %> <%= link_to picker_budgets_path(year: year + 1), data: { turbo_frame: "budget_picker" }, class: "p-2 flex items-center justify-center hover:bg-alpha-black-25 rounded-md" do %>
<%= lucide_icon "chevron-right", class: "w-5 h-5 shrink-0 text-gray-500" %> <%= lucide_icon "chevron-right", class: "w-5 h-5 shrink-0 text-secondary" %>
<% end %> <% end %>
<% else %> <% else %>
<span class="p-2 flex items-center justify-center text-gray-300 rounded-md"> <span class="p-2 flex items-center justify-center text-gray-300 rounded-md">
<%= lucide_icon "chevron-right", class: "w-5 h-5 shrink-0 text-gray-400" %> <%= lucide_icon "chevron-right", class: "w-5 h-5 shrink-0 text-subdued" %>
</span> </span>
<% end %> <% end %>
</div> </div>
@ -35,13 +35,13 @@
<% budget = family.budgets.for_date(start_date) %> <% budget = family.budgets.for_date(start_date) %>
<% if budget %> <% if budget %>
<%= link_to month_name, budget_path(budget), data: { turbo_frame: "_top" }, class: "block px-3 py-2 text-sm text-gray-900 hover:bg-gray-100 rounded-md" %> <%= link_to month_name, budget_path(budget), data: { turbo_frame: "_top" }, class: "block px-3 py-2 text-sm text-primary hover:bg-gray-100 rounded-md" %>
<% elsif start_date >= family.oldest_entry_date.beginning_of_month && start_date <= Date.current %> <% elsif start_date >= family.oldest_entry_date.beginning_of_month && start_date <= Date.current %>
<%= button_to budgets_path(budget: { start_date: start_date }), data: { turbo_frame: "_top" }, class: "block w-full px-3 py-2 text-gray-900 hover:bg-gray-100 rounded-md" do %> <%= button_to budgets_path(budget: { start_date: start_date }), data: { turbo_frame: "_top" }, class: "block w-full px-3 py-2 text-primary hover:bg-gray-100 rounded-md" do %>
<%= month_name %> <%= month_name %>
<% end %> <% end %>
<% else %> <% else %>
<span class="px-3 py-2 text-gray-400 rounded-md"><%= month_name %></span> <span class="px-3 py-2 text-subdued rounded-md"><%= month_name %></span>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>

View file

@ -8,8 +8,8 @@
<div> <div>
<div class="space-y-4"> <div class="space-y-4">
<div class="text-center space-y-2"> <div class="text-center space-y-2">
<h1 class="text-3xl text-gray-900 font-medium">Setup your budget</h1> <h1 class="text-3xl text-primary font-medium">Setup your budget</h1>
<p class="text-gray-500 text-sm max-w-sm mx-auto"> <p class="text-secondary text-sm max-w-sm mx-auto">
Enter your monthly earnings and planned spending below to setup your budget. Enter your monthly earnings and planned spending below to setup your budget.
</p> </p>
</div> </div>
@ -20,11 +20,11 @@
<%= f.money_field :expected_income, label: "Expected income", required: true, disable_currency: true %> <%= f.money_field :expected_income, label: "Expected income", required: true, disable_currency: true %>
<% if @budget.estimated_income && @budget.estimated_spending %> <% if @budget.estimated_income && @budget.estimated_spending %>
<div class="border border-alpha-black-100 rounded-lg p-3 flex"> <div class="border border-tertiary rounded-lg p-3 flex">
<%= lucide_icon "sparkles", class: "w-5 h-5 text-gray-500 shrink-0" %> <%= lucide_icon "sparkles", class: "w-5 h-5 text-secondary shrink-0" %>
<div class="ml-2 space-y-1 text-sm"> <div class="ml-2 space-y-1 text-sm">
<h4 class="text-gray-900">Autosuggest income & spending budget</h4> <h4 class="text-primary">Autosuggest income & spending budget</h4>
<p class="text-gray-500"> <p class="text-secondary">
This will be based on transaction history. AI can make mistakes, verify before continuing. This will be based on transaction history. AI can make mistakes, verify before continuing.
</p> </p>
</div> </div>
@ -35,7 +35,7 @@
budget_form_income_param: { key: "budget_expected_income", value: sprintf("%.2f", @budget.estimated_income) }, budget_form_income_param: { key: "budget_expected_income", value: sprintf("%.2f", @budget.estimated_income) },
budget_form_spending_param: { key: "budget_budgeted_spending", value: sprintf("%.2f", @budget.estimated_spending) } budget_form_spending_param: { key: "budget_budgeted_spending", value: sprintf("%.2f", @budget.estimated_spending) }
} %> } %>
<label for="auto_fill" class="maybe-switch"></label> <label for="auto_fill" class="switch"></label>
</div> </div>
</div> </div>
<% end %> <% end %>

View file

@ -25,16 +25,16 @@
budget_path(@budget, tab: "budgeted"), budget_path(@budget, tab: "budgeted"),
class: class_names( class: class_names(
base_classes, base_classes,
"bg-white shadow-xs text-gray-900": selected_tab == "budgeted", "bg-white shadow-xs text-primary": selected_tab == "budgeted",
"text-gray-500": selected_tab != "budgeted" "text-secondary": selected_tab != "budgeted"
) %> ) %>
<%= link_to "Actual", <%= link_to "Actual",
budget_path(@budget, tab: "actuals"), budget_path(@budget, tab: "actuals"),
class: class_names( class: class_names(
base_classes, base_classes,
"bg-white shadow-xs text-gray-900": selected_tab == "actuals", "bg-white shadow-xs text-primary": selected_tab == "actuals",
"text-gray-500": selected_tab != "actuals" "text-secondary": selected_tab != "actuals"
) %> ) %>
</div> </div>

View file

@ -3,14 +3,14 @@
<div id="<%= dom_id(category) %>" class="flex justify-between items-center px-4 pb-4 <%= "pt-4" unless category.subcategory? %> <%= "pb-4" unless category.subcategories.any? %> bg-white"> <div id="<%= dom_id(category) %>" class="flex justify-between items-center px-4 pb-4 <%= "pt-4" unless category.subcategory? %> <%= "pb-4" unless category.subcategories.any? %> bg-white">
<div class="flex w-full items-center gap-2.5"> <div class="flex w-full items-center gap-2.5">
<% if category.subcategory? %> <% if category.subcategory? %>
<%= lucide_icon "corner-down-right", class: "shrink-0 w-5 h-5 text-gray-400 ml-2" %> <%= lucide_icon "corner-down-right", class: "shrink-0 w-5 h-5 text-subdued ml-2" %>
<% end %> <% end %>
<%= render partial: "categories/badge", locals: { category: category } %> <%= render partial: "categories/badge", locals: { category: category } %>
</div> </div>
<div class="justify-self-end"> <div class="justify-self-end">
<%= contextual_menu do %> <%= contextual_menu do %>
<div class="w-48 p-1 text-sm leading-6 text-gray-900 bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5"> <div class="w-48 p-1 text-sm leading-6 text-primary bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5">
<%= contextual_menu_modal_action_item t(".edit"), edit_category_path(category) %> <%= contextual_menu_modal_action_item t(".edit"), edit_category_path(category) %>
<% if category.transactions.any? %> <% if category.transactions.any? %>

View file

@ -1,9 +1,9 @@
<%# locals: (title:, categories:) %> <%# locals: (title:, categories:) %>
<div class="rounded-xl bg-gray-25 space-y-1 p-1"> <div class="rounded-xl bg-gray-25 space-y-1 p-1">
<div class="flex items-center gap-1.5 px-4 py-2 text-xs font-medium text-gray-500 uppercase"> <div class="flex items-center gap-1.5 px-4 py-2 text-xs font-medium text-secondary uppercase">
<p><%= title %></p> <p><%= title %></p>
<span class="text-gray-400">&middot;</span> <span class="text-subdued">&middot;</span>
<p><%= categories.count %></p> <p><%= categories.count %></p>
</div> </div>

View file

@ -5,10 +5,10 @@
<%= render partial: "categories/badge", locals: { category: transaction.category } %> <%= render partial: "categories/badge", locals: { category: transaction.category } %>
</button> </button>
<div data-menu-target="content" class="absolute z-10 hidden w-screen mt-2 max-w-min cursor-default"> <div data-menu-target="content" class="absolute z-10 hidden w-screen mt-2 max-w-min cursor-default">
<div class="w-80 text-sm font-semibold leading-6 text-gray-900 bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5"> <div class="w-80 text-sm font-semibold leading-6 text-primary bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5">
<%= turbo_frame_tag "category_dropdown", src: category_dropdown_path(category_id: transaction.category_id, transaction_id: transaction.id), loading: :lazy do %> <%= turbo_frame_tag "category_dropdown", src: category_dropdown_path(category_id: transaction.category_id, transaction_id: transaction.id), loading: :lazy do %>
<div class="p-6 flex items-center justify-center"> <div class="p-6 flex items-center justify-center">
<p class="text-sm text-gray-500 animate-pulse"><%= t(".loading") %></p> <p class="text-sm text-secondary animate-pulse"><%= t(".loading") %></p>
</div> </div>
<% end %> <% end %>
</div> </div>

View file

@ -4,7 +4,7 @@
<section class="space-y-4"> <section class="space-y-4">
<header class="flex items-center justify-between"> <header class="flex items-center justify-between">
<h1 class="text-gray-900 text-xl font-medium"><%= t(".categories") %></h1> <h1 class="text-primary text-xl font-medium"><%= t(".categories") %></h1>
<%= link_to new_category_path, class: "btn btn--primary flex items-center gap-1 justify-center", data: { turbo_frame: :modal } do %> <%= link_to new_category_path, class: "btn btn--primary flex items-center gap-1 justify-center", data: { turbo_frame: :modal } do %>
<%= lucide_icon "plus", class: "w-5 h-5" %> <%= lucide_icon "plus", class: "w-5 h-5" %>
@ -26,7 +26,7 @@
<% else %> <% else %>
<div class="flex justify-center items-center py-20"> <div class="flex justify-center items-center py-20">
<div class="text-center flex flex-col items-center max-w-[500px]"> <div class="text-center flex flex-col items-center max-w-[500px]">
<p class="text-sm text-gray-500 mb-4"><%= t(".empty") %></p> <p class="text-sm text-secondary mb-4"><%= t(".empty") %></p>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<%= button_to t(".bootstrap"), bootstrap_categories_path, class: "btn btn--primary" %> <%= button_to t(".bootstrap"), bootstrap_categories_path, class: "btn btn--primary" %>

View file

@ -13,20 +13,20 @@
class: "flex w-full items-center gap-1.5 cursor-pointer" do %> class: "flex w-full items-center gap-1.5 cursor-pointer" do %>
<span class="w-5 h-5"> <span class="w-5 h-5">
<%= lucide_icon("check", class: "w-5 h-5 text-gray-500") if is_selected %> <%= lucide_icon("check", class: "w-5 h-5 text-secondary") if is_selected %>
</span> </span>
<% if category.subcategory? %> <% if category.subcategory? %>
<%= lucide_icon "corner-down-right", class: "shrink-0 w-5 h-5 text-gray-400" %> <%= lucide_icon "corner-down-right", class: "shrink-0 w-5 h-5 text-subdued" %>
<% end %> <% end %>
<%= render partial: "categories/badge", locals: { category: category } %> <%= render partial: "categories/badge", locals: { category: category } %>
<% end %> <% end %>
<%= contextual_menu do %> <%= contextual_menu do %>
<div class="w-48 p-1 text-sm leading-6 text-gray-900 bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5"> <div class="w-48 p-1 text-sm leading-6 text-primary bg-white shadow-lg shrink rounded-xl ring-1 ring-gray-900/5">
<%= link_to edit_category_path(category), <%= link_to edit_category_path(category),
class: "block w-full py-2 px-3 space-x-2 text-gray-900 hover:bg-gray-50 flex items-center rounded-lg", class: "block w-full py-2 px-3 space-x-2 text-primary hover:bg-gray-50 flex items-center rounded-lg",
data: { turbo_frame: :modal } do %> data: { turbo_frame: :modal } do %>
<%= lucide_icon "pencil-line", class: "w-5 h-5 text-gray-500" %> <%= lucide_icon "pencil-line", class: "w-5 h-5 text-secondary" %>
<span><%= t(".edit") %></span> <span><%= t(".edit") %></span>
<% end %> <% end %>

Some files were not shown because too many files have changed in this diff Show more