diff --git a/.cursor/rules/ui-ux-design-guidelines.mdc b/.cursor/rules/ui-ux-design-guidelines.mdc new file mode 100644 index 00000000..a6ad9158 --- /dev/null +++ b/.cursor/rules/ui-ux-design-guidelines.mdc @@ -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`. \ No newline at end of file diff --git a/app/assets/fonts/geist/Geist-Black.woff2 b/app/assets/fonts/geist/Geist-Black.woff2 new file mode 100644 index 00000000..32ccbc99 Binary files /dev/null and b/app/assets/fonts/geist/Geist-Black.woff2 differ diff --git a/app/assets/fonts/geist/Geist-Bold.woff2 b/app/assets/fonts/geist/Geist-Bold.woff2 new file mode 100644 index 00000000..cb112fb5 Binary files /dev/null and b/app/assets/fonts/geist/Geist-Bold.woff2 differ diff --git a/app/assets/fonts/geist/Geist-ExtraBold.woff2 b/app/assets/fonts/geist/Geist-ExtraBold.woff2 new file mode 100644 index 00000000..0c8065c8 Binary files /dev/null and b/app/assets/fonts/geist/Geist-ExtraBold.woff2 differ diff --git a/app/assets/fonts/geist/Geist-ExtraLight.woff2 b/app/assets/fonts/geist/Geist-ExtraLight.woff2 new file mode 100644 index 00000000..d42a9be0 Binary files /dev/null and b/app/assets/fonts/geist/Geist-ExtraLight.woff2 differ diff --git a/app/assets/fonts/geist/Geist-Light.woff2 b/app/assets/fonts/geist/Geist-Light.woff2 new file mode 100644 index 00000000..f67fafee Binary files /dev/null and b/app/assets/fonts/geist/Geist-Light.woff2 differ diff --git a/app/assets/fonts/geist/Geist-Medium.woff2 b/app/assets/fonts/geist/Geist-Medium.woff2 new file mode 100644 index 00000000..9f5717da Binary files /dev/null and b/app/assets/fonts/geist/Geist-Medium.woff2 differ diff --git a/app/assets/fonts/geist/Geist-Regular.woff2 b/app/assets/fonts/geist/Geist-Regular.woff2 new file mode 100644 index 00000000..a7b2ff8c Binary files /dev/null and b/app/assets/fonts/geist/Geist-Regular.woff2 differ diff --git a/app/assets/fonts/geist/Geist-SemiBold.woff2 b/app/assets/fonts/geist/Geist-SemiBold.woff2 new file mode 100644 index 00000000..91d63ebb Binary files /dev/null and b/app/assets/fonts/geist/Geist-SemiBold.woff2 differ diff --git a/app/assets/fonts/geist/Geist-Thin.woff2 b/app/assets/fonts/geist/Geist-Thin.woff2 new file mode 100644 index 00000000..d4dbf549 Binary files /dev/null and b/app/assets/fonts/geist/Geist-Thin.woff2 differ diff --git a/app/assets/fonts/geist/Geist[wght].woff2 b/app/assets/fonts/geist/Geist[wght].woff2 new file mode 100644 index 00000000..6fd61c44 Binary files /dev/null and b/app/assets/fonts/geist/Geist[wght].woff2 differ diff --git a/app/assets/fonts/geist_mono/GeistMono-Black.woff2 b/app/assets/fonts/geist_mono/GeistMono-Black.woff2 new file mode 100644 index 00000000..5609afd3 Binary files /dev/null and b/app/assets/fonts/geist_mono/GeistMono-Black.woff2 differ diff --git a/app/assets/fonts/geist_mono/GeistMono-Bold.woff2 b/app/assets/fonts/geist_mono/GeistMono-Bold.woff2 new file mode 100644 index 00000000..3bb7b951 Binary files /dev/null and b/app/assets/fonts/geist_mono/GeistMono-Bold.woff2 differ diff --git a/app/assets/fonts/geist_mono/GeistMono-Light.woff2 b/app/assets/fonts/geist_mono/GeistMono-Light.woff2 new file mode 100644 index 00000000..c43c125c Binary files /dev/null and b/app/assets/fonts/geist_mono/GeistMono-Light.woff2 differ diff --git a/app/assets/fonts/geist_mono/GeistMono-Medium.woff2 b/app/assets/fonts/geist_mono/GeistMono-Medium.woff2 new file mode 100644 index 00000000..67495e48 Binary files /dev/null and b/app/assets/fonts/geist_mono/GeistMono-Medium.woff2 differ diff --git a/app/assets/fonts/geist_mono/GeistMono-Regular.woff2 b/app/assets/fonts/geist_mono/GeistMono-Regular.woff2 new file mode 100644 index 00000000..d6d865af Binary files /dev/null and b/app/assets/fonts/geist_mono/GeistMono-Regular.woff2 differ diff --git a/app/assets/fonts/geist_mono/GeistMono-SemiBold.woff2 b/app/assets/fonts/geist_mono/GeistMono-SemiBold.woff2 new file mode 100644 index 00000000..bf25a1da Binary files /dev/null and b/app/assets/fonts/geist_mono/GeistMono-SemiBold.woff2 differ diff --git a/app/assets/fonts/geist_mono/GeistMono-Thin.woff2 b/app/assets/fonts/geist_mono/GeistMono-Thin.woff2 new file mode 100644 index 00000000..76b4619d Binary files /dev/null and b/app/assets/fonts/geist_mono/GeistMono-Thin.woff2 differ diff --git a/app/assets/fonts/geist_mono/GeistMono-UltraBlack.woff2 b/app/assets/fonts/geist_mono/GeistMono-UltraBlack.woff2 new file mode 100644 index 00000000..ffb26733 Binary files /dev/null and b/app/assets/fonts/geist_mono/GeistMono-UltraBlack.woff2 differ diff --git a/app/assets/fonts/geist_mono/GeistMono-UltraLight.woff2 b/app/assets/fonts/geist_mono/GeistMono-UltraLight.woff2 new file mode 100644 index 00000000..9c6469bf Binary files /dev/null and b/app/assets/fonts/geist_mono/GeistMono-UltraLight.woff2 differ diff --git a/app/assets/fonts/geist_mono/GeistMono[wght].woff2 b/app/assets/fonts/geist_mono/GeistMono[wght].woff2 new file mode 100644 index 00000000..dae00379 Binary files /dev/null and b/app/assets/fonts/geist_mono/GeistMono[wght].woff2 differ diff --git a/app/assets/tailwind/application.css b/app/assets/tailwind/application.css index 668e3a13..9153362f 100644 --- a/app/assets/tailwind/application.css +++ b/app/assets/tailwind/application.css @@ -1,389 +1,13 @@ @import 'tailwindcss'; +@import "./maybe-design-system.css"; + +@import "./geist-font.css"; +@import "./geist-mono-font.css"; + @plugin "@tailwindcss/typography"; @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 { .hw-combobox__main__wrapper, .hw-combobox__input { @@ -398,6 +22,10 @@ @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 { @apply h-px; @@ -412,6 +40,20 @@ --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 */ .windows { ::-webkit-scrollbar { @@ -426,4 +68,19 @@ ::-webkit-scrollbar-thumb:hover { background: #a6a6a6; } +} + +.scrollbar { + &::-webkit-scrollbar { + width: 4px; + } + + &::-webkit-scrollbar-thumb { + background: #d6d6d6; + border-radius: 10px; + } + + &::-webkit-scrollbar-thumb:hover { + background: #a6a6a6; + } } \ No newline at end of file diff --git a/app/assets/tailwind/geist-font.css b/app/assets/tailwind/geist-font.css new file mode 100644 index 00000000..7c2f048a --- /dev/null +++ b/app/assets/tailwind/geist-font.css @@ -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; + } +} diff --git a/app/assets/tailwind/geist-mono-font.css b/app/assets/tailwind/geist-mono-font.css new file mode 100644 index 00000000..207351c7 --- /dev/null +++ b/app/assets/tailwind/geist-mono-font.css @@ -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; + } +} diff --git a/app/assets/tailwind/maybe-design-system.css b/app/assets/tailwind/maybe-design-system.css new file mode 100644 index 00000000..eaaa1cb2 --- /dev/null +++ b/app/assets/tailwind/maybe-design-system.css @@ -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; + } +} \ No newline at end of file diff --git a/app/helpers/accounts_helper.rb b/app/helpers/accounts_helper.rb index 04be4b52..356798e5 100644 --- a/app/helpers/accounts_helper.rb +++ b/app/helpers/accounts_helper.rb @@ -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" }, "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" }, "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" }, "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" } - }.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 diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 033014e9..7549b6b5 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -76,8 +76,8 @@ module ApplicationHelper is_current = current_page?(path) || (request.path.start_with?(path) && path != "/") classes = [ - "flex items-center gap-2 px-3 py-2 rounded-xl border text-sm font-medium text-gray-500", - (is_current ? "bg-white text-gray-900 shadow-xs border-alpha-black-50" : "hover:bg-gray-100 border-transparent") + "flex items-center gap-2 px-3 py-2 rounded-xl border text-sm font-medium text-secondary", + (is_current ? "bg-white text-primary shadow-xs border-alpha-black-50" : "hover:bg-gray-100 border-transparent") ].compact.join(" ") link_to path, **options.merge(class: classes), aria: { current: ("page" if current_page?(path)) } do @@ -106,7 +106,7 @@ module ApplicationHelper end 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? bg_class, text_class, symbol, icon = case trend.direction @@ -115,7 +115,7 @@ module ApplicationHelper when "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" - [ "bg-gray-500/5", "text-gray-500", "", "minus" ] + [ "bg-gray-500/5", "text-secondary", "", "minus" ] else raise ArgumentError, "Invalid trend direction: #{trend.direction}" end diff --git a/app/helpers/forms_helper.rb b/app/helpers/forms_helper.rb index a66c740e..39fa0740 100644 --- a/app/helpers/forms_helper.rb +++ b/app/helpers/forms_helper.rb @@ -17,7 +17,7 @@ module FormsHelper 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 = [ %w[CWD current_week], # Current Week to Date %w[7D last_7_days], @@ -39,7 +39,7 @@ end private 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 tag.span(label, class: "group-has-checked:font-semibold") end diff --git a/app/helpers/imports_helper.rb b/app/helpers/imports_helper.rb index a202a697..b7718ecf 100644 --- a/app/helpers/imports_helper.rb +++ b/app/helpers/imports_helper.rb @@ -45,7 +45,7 @@ module ImportsHelper end 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 diff --git a/app/helpers/menus_helper.rb b/app/helpers/menus_helper.rb index 74ec8752..55ad55a3 100644 --- a/app/helpers/menus_helper.rb +++ b/app/helpers/menus_helper.rb @@ -7,8 +7,8 @@ module MenusHelper end 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 - concat(lucide_icon(icon, class: "shrink-0 w-5 h-5 text-gray-500")) + 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-secondary")) concat(tag.span(label, class: "text-sm")) end end @@ -26,7 +26,7 @@ module MenusHelper private def contextual_menu_icon 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 diff --git a/app/javascript/controllers/time_series_chart_controller.js b/app/javascript/controllers/time_series_chart_controller.js index 0f687e0d..4ae37bfa 100644 --- a/app/javascript/controllers/time_series_chart_controller.js +++ b/app/javascript/controllers/time_series_chart_controller.js @@ -401,11 +401,11 @@ export default class extends Controller { up: datum.trend.favorable_direction === "up" ? "var(--color-success)" - : "var(--color-error)", + : "var(--color-destructive)", down: datum.trend.favorable_direction === "down" ? "var(--color-success)" - : "var(--color-error)", + : "var(--color-destructive)", flat: "var(--color-gray-500)", }[datum.trend.direction]; } @@ -509,7 +509,7 @@ export default class extends Controller { if (this._trendDirection === this._favorableDirection) { return "var(--color-green-500)"; } - return "var(--color-error)"; + return "var(--color-destructive)"; } get _trendDirection() { diff --git a/app/views/account/entries/_empty.html.erb b/app/views/account/entries/_empty.html.erb index 9cb5e3fa..60c296e9 100644 --- a/app/views/account/entries/_empty.html.erb +++ b/app/views/account/entries/_empty.html.erb @@ -1,4 +1,4 @@
-

<%= t(".title") %>

-

<%= t(".description") %>

+

<%= t(".title") %>

+

<%= t(".description") %>

diff --git a/app/views/account/entries/_entry_group.html.erb b/app/views/account/entries/_entry_group.html.erb index a58d0f15..4006b070 100644 --- a/app/views/account/entries/_entry_group.html.erb +++ b/app/views/account/entries/_entry_group.html.erb @@ -1,10 +1,10 @@ <%# locals: (date:, entries:, content:, selectable:, totals: false) %>
-
+
<% if selectable %> <%= 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}", data: { action: "bulk-select#toggleGroupSelection" } %> <% end %> diff --git a/app/views/account/entries/_loading.html.erb b/app/views/account/entries/_loading.html.erb index 4f49ca61..7436f568 100644 --- a/app/views/account/entries/_loading.html.erb +++ b/app/views/account/entries/_loading.html.erb @@ -1,5 +1,5 @@
- <%= tag.p t(".loading"), class: "text-gray-500 animate-pulse text-sm" %> + <%= tag.p t(".loading"), class: "text-secondary animate-pulse text-sm" %>
diff --git a/app/views/account/entries/_selection_bar.html.erb b/app/views/account/entries/_selection_bar.html.erb index 3bbf39d1..78d69c45 100644 --- a/app/views/account/entries/_selection_bar.html.erb +++ b/app/views/account/entries/_selection_bar.html.erb @@ -1,11 +1,11 @@
- <%= 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" } %>

-
+
<%= form_with url: bulk_delete_account_transactions_path, data: { turbo_confirm: true, turbo_frame: "_top" } do %> @@ -23,7 +23,7 @@ <% if eu_link_token %> diff --git a/app/views/accounts/show/_activity.html.erb b/app/views/accounts/show/_activity.html.erb index e47e84fc..eb593e74 100644 --- a/app/views/accounts/show/_activity.html.erb +++ b/app/views/accounts/show/_activity.html.erb @@ -12,13 +12,13 @@ -
+
<%= check_box_tag "selection_entry", - class: "maybe-checkbox maybe-checkbox--light", + class: "checkbox checkbox--light", data: { action: "bulk-select#togglePageSelection" } %>

<%= t(".date") %>

diff --git a/app/views/accounts/show/_chart.html.erb b/app/views/accounts/show/_chart.html.erb index 168182fd..c1f06dd6 100644 --- a/app/views/accounts/show/_chart.html.erb +++ b/app/views/accounts/show/_chart.html.erb @@ -7,11 +7,11 @@
- <%= 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 %>
- <%= 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" %>
<%= form_with url: request.path, method: :get, data: { controller: "auto-submit-form" } do |form| %> diff --git a/app/views/accounts/show/_header.html.erb b/app/views/accounts/show/_header.html.erb index a6e925e9..8dbaf273 100644 --- a/app/views/accounts/show/_header.html.erb +++ b/app/views/accounts/show/_header.html.erb @@ -13,7 +13,7 @@

<%= title || account.name %>

<% if subtitle.present? %> -

<%= subtitle %>

+

<%= subtitle %>

<% end %>
@@ -23,12 +23,12 @@ <% if account.plaid_account_id.present? %> <% 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 %> - <%= 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 %> <% else %> <%= 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 %> diff --git a/app/views/accounts/show/_loading.html.erb b/app/views/accounts/show/_loading.html.erb index a4254988..26167412 100644 --- a/app/views/accounts/show/_loading.html.erb +++ b/app/views/accounts/show/_loading.html.erb @@ -1,3 +1,3 @@
-

Loading account...

+

Loading account...

diff --git a/app/views/accounts/show/_menu.html.erb b/app/views/accounts/show/_menu.html.erb index 5d9efa44..f41723a6 100644 --- a/app/views/accounts/show/_menu.html.erb +++ b/app/views/accounts/show/_menu.html.erb @@ -1,20 +1,20 @@ <%# locals: (account:) %> <%= contextual_menu do %> -
+
<% if account.plaid_account_id.present? %> <%= link_to accounts_path, 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 %> - <%= lucide_icon "pencil-line", class: "w-5 h-5 text-gray-500" %> + 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-secondary" %> <%= t(".manage") %> <% end %> <% else %> <%= link_to edit_account_path(account), 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 %> - <%= lucide_icon "pencil-line", class: "w-5 h-5 text-gray-500" %> + 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-secondary" %> <%= t(".edit") %> <% end %> @@ -22,8 +22,8 @@ <% unless account.crypto? %> <%= link_to new_import_path, 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 %> - <%= lucide_icon "download", class: "w-5 h-5 text-gray-500" %> + 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-secondary" %> <%= t(".import") %> <% end %> diff --git a/app/views/accounts/show/_tabs.html.erb b/app/views/accounts/show/_tabs.html.erb index 6c69d803..2a0e2b2f 100644 --- a/app/views/accounts/show/_tabs.html.erb +++ b/app/views/accounts/show/_tabs.html.erb @@ -2,7 +2,7 @@ <% selected_tab = tabs.find { |tab| tab[:key] == params[:tab] } || tabs.first %> -
+
<% tabs.each do |tab| %> <%= render "accounts/show/tab", account: account, key: tab[:key], is_selected: selected_tab[:key] == tab[:key] %> <% end %> diff --git a/app/views/accounts/summary.html.erb b/app/views/accounts/summary.html.erb index 0894ee34..098b67c6 100644 --- a/app/views/accounts/summary.html.erb +++ b/app/views/accounts/summary.html.erb @@ -4,7 +4,7 @@ <%= render "accounts/summary/header" %> -
+
<%= render partial: "shared/value_heading", locals: { @@ -41,10 +41,10 @@
-

Assets

+

Assets

<%= 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") %>

<%= t(".new") %>

<% end %> <%= 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 } %> <% else %>
- <%= lucide_icon "blocks", class: "w-6 h-6 shrink-0 text-gray-500" %> -

<%= t(".no_assets") %>

-

<%= t(".no_assets_description") %>

+ <%= lucide_icon "blocks", class: "w-6 h-6 shrink-0 text-secondary" %> +

<%= t(".no_assets") %>

+

<%= t(".no_assets_description") %>

<% end %>
-

Liabilities

+

Liabilities

<%= 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") %>

<%= t(".new") %>

<% end %> <%= 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 } %> <% else %>
- <%= lucide_icon "scale", class: "w-6 h-6 shrink-0 text-gray-500" %> -

<%= t(".no_liabilities") %>

-

<%= t(".no_liabilities_description") %>

+ <%= lucide_icon "scale", class: "w-6 h-6 shrink-0 text-secondary" %> +

<%= t(".no_liabilities") %>

+

<%= t(".no_liabilities_description") %>

<% end %>
diff --git a/app/views/accounts/summary/_header.html.erb b/app/views/accounts/summary/_header.html.erb index f8c8eb3e..1cf47f07 100644 --- a/app/views/accounts/summary/_header.html.erb +++ b/app/views/accounts/summary/_header.html.erb @@ -1,12 +1,12 @@ -
+

<%= t(".accounts") %>

<%= contextual_menu do %> -
+
<%= 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 %> - <%= lucide_icon "settings", class: "w-5 h-5 text-gray-500" %> + 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-secondary" %> <%= t(".manage") %> <% end %>
diff --git a/app/views/application/_pagination.html.erb b/app/views/application/_pagination.html.erb index 10b27327..04685600 100644 --- a/app/views/application/_pagination.html.erb +++ b/app/views/application/_pagination.html.erb @@ -6,8 +6,8 @@ <% if pagy.prev %> <%= link_to pagy_url_for(pagy, pagy.prev), 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 %> - <%= lucide_icon("chevron-left", class: "w-5 h-5 text-gray-500") %> + 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-secondary") %> <% end %> <% else %>
@@ -20,17 +20,17 @@ <% if series_item.is_a?(Integer) %> <%= link_to pagy_url_for(pagy, series_item), 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 %> <% end %> <% elsif series_item.is_a?(String) %> <%= link_to pagy_url_for(pagy, series_item), 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 %> <% end %> <% elsif series_item == :gap %> - ... + ... <% end %> <% end %>
@@ -38,8 +38,8 @@ <% if pagy.next %> <%= link_to pagy_url_for(pagy, pagy.next), 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 %> - <%= lucide_icon("chevron-right", class: "w-5 h-5 text-gray-500") %> + 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-secondary") %> <% end %> <% else %>
@@ -52,6 +52,6 @@ <%= select_tag :per_page, options_for_select(["10", "20", "30", "50"], pagy.limit), 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" %>
diff --git a/app/views/budget_categories/_allocation_progress.erb b/app/views/budget_categories/_allocation_progress.erb index 8355a978..8302a57d 100644 --- a/app/views/budget_categories/_allocation_progress.erb +++ b/app/views/budget_categories/_allocation_progress.erb @@ -9,17 +9,17 @@ <% end %> <% if budget.available_to_allocate.negative? %> -

> 100% set

+

> 100% set

<% else %> -

+

<%= number_to_percentage(budget.allocated_percent, precision: 0) %> set

<% end %>

- "><%= format_money(budget.allocated_spending_money) %> - / - <%= format_money(budget.budgeted_spending_money) %> + "><%= format_money(budget.allocated_spending_money) %> + / + <%= format_money(budget.budgeted_spending_money) %>

@@ -33,12 +33,12 @@
<% if budget.available_to_allocate.negative? %> -

+

Budget exceeded by <%= format_money(budget.available_to_allocate_money.abs) %>

<% else %> - <%= format_money(budget.available_to_allocate_money) %> - left to allocate + <%= format_money(budget.available_to_allocate_money) %> + left to allocate <% end %>
diff --git a/app/views/budget_categories/_budget_category.html.erb b/app/views/budget_categories/_budget_category.html.erb index 27dc80d1..888d6daf 100644 --- a/app/views/budget_categories/_budget_category.html.erb +++ b/app/views/budget_categories/_budget_category.html.erb @@ -18,30 +18,30 @@ <% end %>
-

<%= budget_category.category.name %>

+

<%= budget_category.category.name %>

<% if budget_category.initialized? %> <% if budget_category.available_to_spend.negative? %>

<%= format_money(budget_category.available_to_spend_money.abs) %> over

<% elsif budget_category.available_to_spend.zero? %> -

"> +

"> <%= format_money(budget_category.available_to_spend_money) %> left

<% else %> -

<%= format_money(budget_category.available_to_spend_money) %> left

+

<%= format_money(budget_category.available_to_spend_money) %> left

<% end %> <% else %> -

+

<%= format_money(budget_category.category.avg_monthly_total_money, precision: 0) %> avg

<% end %>
-

<%= format_money(budget_category.actual_spending_money) %>

+

<%= format_money(budget_category.actual_spending_money) %>

<% if budget_category.initialized? %> -

from <%= format_money(budget_category.budgeted_spending_money) %>

+

from <%= format_money(budget_category.budgeted_spending_money) %>

<% end %>
<% end %> diff --git a/app/views/budget_categories/_budget_category_form.html.erb b/app/views/budget_categories/_budget_category_form.html.erb index 08fd70e0..ee67345d 100644 --- a/app/views/budget_categories/_budget_category_form.html.erb +++ b/app/views/budget_categories/_budget_category_form.html.erb @@ -6,16 +6,16 @@
-

<%= budget_category.category.name %>

+

<%= budget_category.category.name %>

-

<%= format_money(budget_category.category.avg_monthly_total_money, precision: 0) %>/m average

+

<%= format_money(budget_category.category.avg_monthly_total_money, precision: 0) %>/m average

<%= form_with model: [budget_category.budget, budget_category], data: { controller: "auto-submit-form preserve-focus" } do |f| %>
- <%= currency.symbol %> + <%= currency.symbol %> <%= 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", placeholder: "0", diff --git a/app/views/budget_categories/_confirm_button.html.erb b/app/views/budget_categories/_confirm_button.html.erb index 53c52533..6b473633 100644 --- a/app/views/budget_categories/_confirm_button.html.erb +++ b/app/views/budget_categories/_confirm_button.html.erb @@ -4,7 +4,7 @@ budget_path(budget), class: "block btn btn--primary w-full text-center" %> <% else %> - + Confirm <% end %> diff --git a/app/views/budget_categories/_no_categories.html.erb b/app/views/budget_categories/_no_categories.html.erb index aaa0a865..8755d0b8 100644 --- a/app/views/budget_categories/_no_categories.html.erb +++ b/app/views/budget_categories/_no_categories.html.erb @@ -1,7 +1,7 @@
-

Oops!

-

+

Oops!

+

You have not created or assigned any expense categories to your transactions yet.

diff --git a/app/views/budget_categories/_uncategorized_budget_category_form.html.erb b/app/views/budget_categories/_uncategorized_budget_category_form.html.erb index f26a9f80..70c887e3 100644 --- a/app/views/budget_categories/_uncategorized_budget_category_form.html.erb +++ b/app/views/budget_categories/_uncategorized_budget_category_form.html.erb @@ -6,14 +6,14 @@
-

<%= budget_category.category.name %>

-

<%= format_money(Money.new(budget_category.category.avg_monthly_total, budget_category.category.family.currency), precision: 0) %>/m average

+

<%= budget_category.category.name %>

+

<%= format_money(Money.new(budget_category.category.avg_monthly_total, budget_category.category.family.currency), precision: 0) %>/m average

- $ + $ <%= 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 %>
diff --git a/app/views/budget_categories/index.html.erb b/app/views/budget_categories/index.html.erb index 1ae9ea97..db03a5a5 100644 --- a/app/views/budget_categories/index.html.erb +++ b/app/views/budget_categories/index.html.erb @@ -8,8 +8,8 @@
-

Edit your category budgets

-

+

Edit your category budgets

+

Adjust category budgets to set spending limits. Unallocated funds will be automatically assigned as uncategorized.

@@ -31,7 +31,7 @@
<% group.budget_subcategories.each do |budget_subcategory| %>
-
+
<%= lucide_icon "corner-down-right", class: "w-5 h-5 shrink-0" %>
@@ -45,7 +45,7 @@ <%= render "budget_categories/uncategorized_budget_category_form", budget: @budget %>
- <%= render "budget_categories/confirm_button", budget: @budget %> + <%= render "budget_categories/confirm_button", budget: @budget %>
<% end %>
diff --git a/app/views/budget_categories/show.html.erb b/app/views/budget_categories/show.html.erb index e7abe251..b7f891f8 100644 --- a/app/views/budget_categories/show.html.erb +++ b/app/views/budget_categories/show.html.erb @@ -2,14 +2,14 @@
-

Category

-

+

Category

+

<%= @budget_category.category.name %>

<% if @budget_category.budget.initialized? %> -

- +

+ <%= format_money(@budget_category.actual_spending_money) %> / @@ -28,26 +28,26 @@

+ text-xs font-medium uppercase text-secondary bg-gray-25 focus-visible:outline-hidden">

Overview

<%= 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" %>
-
+
<%= @budget_category.budget.start_date.strftime("%b %Y") %> spending
-
+
<%= format_money @budget_category.actual_spending_money %>
<% if @budget_category.budget.initialized? %>
-
Status
+
Status
<% if @budget_category.available_to_spend.negative? %>
<%= lucide_icon "alert-circle", class: "shrink-0 w-4 h-4 text-red-500" %> @@ -61,7 +61,7 @@ left
<% else %> -
+
<%= lucide_icon "check-circle-2", class: "shrink-0 w-4 h-4 text-green-500" %> <%= format_money @budget_category.available_to_spend_money %> left @@ -70,23 +70,23 @@
-
Budgeted
-
+
Budgeted
+
<%= format_money @budget_category.budgeted_spending_money %>
<% end %>
-
Monthly average spending
-
+
Monthly average spending
+
<%= format_money @budget_category.category.avg_monthly_total_money, precision: 0 %>
-
Monthly median spending
-
+
Monthly median spending
+
<%= format_money @budget_category.category.median_monthly_total_money, precision: 0 %>
@@ -96,10 +96,10 @@
+ text-xs font-medium uppercase text-secondary bg-gray-25 focus-visible:outline-hidden">

Recent Transactions

<%= 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" %>
@@ -117,12 +117,12 @@
-

+

<%= entry.date.strftime("%b %d") %>

-

<%= entry.name %>

+

<%= entry.name %>

-

+

<%= format_money entry.amount_money %>

@@ -139,7 +139,7 @@ data: { turbo_frame: :_top }, class: "block text-center btn btn--outline w-full" %> <% else %> -

+

No transactions found for this budget period.

<% end %> diff --git a/app/views/budgets/_actuals_summary.html.erb b/app/views/budgets/_actuals_summary.html.erb index 1ecebbae..67cac86b 100644 --- a/app/views/budgets/_actuals_summary.html.erb +++ b/app/views/budgets/_actuals_summary.html.erb @@ -2,11 +2,11 @@
-

Income

+

Income

<% 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 %> - + <%= format_money(income_totals.total_money) %> @@ -22,8 +22,8 @@ <% income_categories.each do |item| %>
- <%= item.category.name %> - <%= number_to_percentage(item.percentage, precision: 0) %> + <%= item.category.name %> + <%= number_to_percentage(item.percentage, precision: 0) %>
<% end %>
@@ -32,12 +32,12 @@
-

Expenses

+

Expenses

<% 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 %> - <%= format_money(expense_totals.total_money) %> + <%= format_money(expense_totals.total_money) %> <% if expense_categories.any? %>
@@ -51,8 +51,8 @@ <% expense_categories.each do |item| %>
- <%= item.category.name %> - <%= number_to_percentage(item.percentage, precision: 0) %> + <%= item.category.name %> + <%= number_to_percentage(item.percentage, precision: 0) %>
<% end %>
diff --git a/app/views/budgets/_budget_categories.html.erb b/app/views/budgets/_budget_categories.html.erb index 86cc3012..122c8348 100644 --- a/app/views/budgets/_budget_categories.html.erb +++ b/app/views/budgets/_budget_categories.html.erb @@ -1,9 +1,9 @@ <%# locals: (budget:) %>
-
+

Categories

- · + ·

<%= budget.budget_categories.count %>

Amount

@@ -24,7 +24,7 @@
<% group.budget_subcategories.each do |budget_subcategory| %>
-
+
<%= lucide_icon "corner-down-right", class: "w-5 h-5 shrink-0" %>
diff --git a/app/views/budgets/_budget_donut.html.erb b/app/views/budgets/_budget_donut.html.erb index 035389f7..8ec57be3 100644 --- a/app/views/budgets/_budget_donut.html.erb +++ b/app/views/budgets/_budget_donut.html.erb @@ -8,18 +8,18 @@ Spent
-
"> +
"> <%= format_money(budget.actual_spending_money) %>
<%= link_to edit_budget_path(budget), class: "btn btn--secondary flex items-center gap-1 mt-2" do %> - + of <%= format_money(budget.budgeted_spending_money) %> - <%= 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 %> <% else %> -
+
<%= format_money Money.new(0, budget.currency || budget.family.currency) %>
<%= link_to edit_budget_path(budget), class: "flex items-center gap-2 btn btn--primary" do %> @@ -34,26 +34,26 @@
-

<%= bc.category.name %>

+

<%= bc.category.name %>

-

"> +

"> <%= format_money(bc.actual_spending_money) %>

<%= link_to budget_budget_categories_path(budget), class: "btn btn--secondary flex items-center gap-1" do %> of <%= format_money(bc.budgeted_spending_money, precision: 0) %> - <%= 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 %> diff --git a/app/views/budgets/_budget_header.html.erb b/app/views/budgets/_budget_header.html.erb index 5dd041dc..333c59b4 100644 --- a/app/views/budgets/_budget_header.html.erb +++ b/app/views/budgets/_budget_header.html.erb @@ -7,7 +7,7 @@ <%= lucide_icon "chevron-left" %> <% end %> <% else %> - <%= lucide_icon "chevron-left", class: "text-gray-400" %> + <%= lucide_icon "chevron-left", class: "text-subdued" %> <% end %> <% if @next_budget %> @@ -15,14 +15,14 @@ <%= lucide_icon "chevron-right" %> <% end %> <% else %> - <%= lucide_icon "chevron-right", class: "text-gray-400" %> + <%= lucide_icon "chevron-right", class: "text-subdued" %> <% end %>
<%= tag.button data: { menu_target: "button" }, class: "flex items-center gap-1 hover:bg-gray-50 rounded-md p-2" do %> - <%= @budget.name %> - <%= lucide_icon "chevron-down", class: "w-5 h-5 shrink-0 text-gray-500" %> + <%= @budget.name %> + <%= lucide_icon "chevron-down", class: "w-5 h-5 shrink-0 text-secondary" %> <% end %>