Commit iniziale di eminuxCRM: CRM Rails con pipeline, campagne email e Docker.
CI / scan_ruby (push) Failing after 11m20s
CI / scan_js (push) Successful in 10m35s
CI / lint (push) Has been cancelled

Include autenticazione, progetti isolati, mail marketing HTML con SMTP, test A/B e editor WYSIWYG.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-17 23:01:48 +02:00
co-authored by Cursor
commit c4e5f289cf
258 changed files with 11293 additions and 0 deletions
View File
View File
+310
View File
@@ -0,0 +1,310 @@
/*
* Application styles. Tailwind utilities live in builds/tailwind.css
*/
.pagy {
display: flex;
gap: 0.25rem;
flex-wrap: wrap;
margin-top: 1rem;
}
.pagy a, .pagy span {
display: inline-block;
padding: 0.35rem 0.65rem;
border-radius: 0.375rem;
border: 1px solid #e2e8f0;
font-size: 0.875rem;
background: #fff;
color: #334155;
}
.pagy a:hover {
background: #f8fafc;
}
.pagy .current {
background: #0f172a;
color: #fff;
border-color: #0f172a;
}
html.dark .pagy a,
html.dark .pagy span {
background: #27272a;
color: #e4e4e7;
border-color: #3f3f46;
}
html.dark .pagy a:hover {
background: #3f3f46;
}
html.dark .pagy .current {
background: #fafafa;
color: #18181b;
border-color: #fafafa;
}
/* Kanban: scrollbar orizzontale sempre visibile e usabile */
.kanban-board {
scrollbar-gutter: stable;
scrollbar-width: thin;
scrollbar-color: #94a3b8 #e2e8f0;
}
.kanban-board::-webkit-scrollbar {
height: 12px;
}
.kanban-board::-webkit-scrollbar-track {
background: #e2e8f0;
border-radius: 999px;
}
.kanban-board::-webkit-scrollbar-thumb {
background: #94a3b8;
border-radius: 999px;
}
.kanban-board::-webkit-scrollbar-thumb:hover {
background: #64748b;
}
html.dark .kanban-board {
scrollbar-color: #52525b #27272a;
}
html.dark .kanban-board::-webkit-scrollbar-track {
background: #27272a;
}
html.dark .kanban-board::-webkit-scrollbar-thumb {
background: #52525b;
}
html.dark .kanban-board::-webkit-scrollbar-thumb:hover {
background: #71717a;
}
html {
color-scheme: light;
}
html.dark {
color-scheme: dark;
}
/* Superfici “slate-50” usate come righe/chip senza dark:bg — in dark non restano bianche. */
html.dark .bg-slate-50 {
background-color: #27272a;
}
html.dark tr.hover\:bg-slate-50:hover,
html.dark .hover\:bg-slate-50:hover {
background-color: #27272a;
}
html.dark input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="reset"]),
html.dark select,
html.dark textarea {
background-color: #09090b;
color: #fafafa;
border-color: #3f3f46;
}
html.dark input::placeholder,
html.dark textarea::placeholder {
color: #a1a1aa;
}
html.dark select option {
background-color: #18181b;
color: #fafafa;
}
/* Pulsanti: appearance none così input[type=submit] non resta grigio nativo con testo bianco. */
.btn-primary,
.btn-secondary,
.btn-danger {
appearance: none;
-webkit-appearance: none;
cursor: pointer;
text-decoration: none;
border-style: solid;
border-width: 1px;
}
.btn-primary {
background-color: #18181b;
border-color: #18181b;
color: #fff;
}
.btn-primary:hover {
background-color: #27272a;
border-color: #27272a;
color: #fff;
}
html.dark .btn-primary {
background-color: #f4f4f5;
border-color: #f4f4f5;
color: #18181b;
}
html.dark .btn-primary:hover {
background-color: #fff;
border-color: #fff;
color: #18181b;
}
.btn-secondary {
background-color: #fff;
border-color: #e4e4e7;
color: #3f3f46;
}
.btn-secondary:hover {
background-color: #fafafa;
color: #18181b;
}
html.dark .btn-secondary {
background-color: #18181b;
border-color: #3f3f46;
color: #e4e4e7;
}
html.dark .btn-secondary:hover {
background-color: #27272a;
color: #fafafa;
}
.btn-danger {
background-color: #fff;
border-color: #fecdd3;
color: #be123c;
}
.btn-danger:hover {
background-color: #fff1f2;
color: #9f1239;
}
html.dark .btn-danger {
background-color: #18181b;
border-color: #881337;
color: #fda4af;
}
html.dark .btn-danger:hover {
background-color: #4c0519;
color: #fecdd3;
}
/* Editor Trix (template e campagne email) */
trix-toolbar {
margin-bottom: 0.5rem;
}
trix-toolbar .trix-button-row {
flex-wrap: wrap;
}
trix-toolbar .trix-button-group {
border-color: #e4e4e7;
margin-bottom: 0.25rem;
}
trix-toolbar .trix-button {
background: #fff;
border-color: #e4e4e7;
color: #18181b;
}
html.dark trix-toolbar .trix-button-group {
border-color: #3f3f46;
}
html.dark trix-toolbar .trix-button {
/* Icone SVG nere: inverti su fondo chiaro così diventano bianche su scuro. */
background-color: #f4f4f5;
border-color: #d4d4d8;
filter: invert(1);
}
html.dark trix-toolbar .trix-button.trix-active {
background-color: #d4d4d8;
}
html.dark trix-toolbar .trix-dialog {
background: #18181b;
border-color: #3f3f46;
color: #fafafa;
filter: none;
}
trix-editor {
min-height: 14rem;
border: 1px solid #e4e4e7;
border-radius: 0.5rem;
padding: 0.75rem 0.9rem;
background: #fff;
color: #18181b;
}
trix-editor:focus,
trix-editor:focus-visible {
outline: none;
border-color: #a1a1aa;
box-shadow: 0 0 0 1px #a1a1aa;
}
trix-editor img {
max-width: 100%;
height: auto;
}
trix-editor figure.attachment {
position: relative;
display: inline-block;
max-width: 100%;
}
trix-editor figure.attachment.is-resizing {
outline: 2px solid #18181b;
outline-offset: 2px;
overflow: visible;
}
html.dark trix-editor figure.attachment.is-resizing {
outline-color: #e4e4e7;
}
.trix-resize-handle {
position: absolute;
z-index: 6;
width: 10px;
height: 10px;
box-sizing: border-box;
background: #18181b;
border: 2px solid #fff;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25);
}
html.dark .trix-resize-handle {
background: #fafafa;
border-color: #18181b;
}
.trix-resize-handle--nw { top: -5px; left: -5px; cursor: nwse-resize; }
.trix-resize-handle--ne { top: -5px; right: -5px; cursor: nesw-resize; }
.trix-resize-handle--sw { bottom: -5px; left: -5px; cursor: nesw-resize; }
.trix-resize-handle--se { bottom: -5px; right: -5px; cursor: nwse-resize; }
html.dark trix-editor {
background: #09090b;
border-color: #3f3f46;
color: #fafafa;
}
+6
View File
@@ -0,0 +1,6 @@
@import "tailwindcss";
/* :is() ha specificità reale: dark:bg-* / dark:text-* vincono sui pari light.
:where() (default v4) ha specificità 0 e, a seconda dellordine nel CSS,
le carte restano bianche mentre il testo diventa chiaro (o il contrario). */
@custom-variant dark (&:is(.dark, .dark *));