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