From 6175826c1993dc89984d074c2273c84c3904e62e Mon Sep 17 00:00:00 2001 From: GREENRAT-K405 Date: Tue, 20 Jan 2026 02:34:42 +0530 Subject: [PATCH 1/5] add darkmode to concore editor --- src/App.css | 141 ++++-- src/App.jsx | 10 + src/GraphArea.jsx | 17 +- src/GraphWorkspace.jsx | 2 +- src/component/Header.jsx | 21 + src/component/HeaderComps.jsx | 5 +- src/component/fileBrowser.css | 588 +++++++++++++++++-------- src/component/header.css | 47 ++ src/component/tabBar.css | 54 ++- src/component/zoomSetter.css | 52 ++- src/config/cytoscape-options.js | 10 +- src/config/cytoscape-style.js | 395 +++++++++-------- src/graph-builder/graph-core/1-core.js | 45 +- src/graphWorkspace.css | 20 +- src/reducer/actionType.js | 1 + src/reducer/initialState.js | 3 +- src/reducer/reducer.js | 4 + 17 files changed, 991 insertions(+), 424 deletions(-) diff --git a/src/App.css b/src/App.css index 445c6b7..a1723cf 100644 --- a/src/App.css +++ b/src/App.css @@ -1,87 +1,136 @@ +/* CSS Variables for Light Mode (Default) */ +:root { + /* Background colors */ + --bg-primary: rgb(240, 242, 245); + --bg-secondary: #fff; + + /* Text colors */ + --text-primary: #212529; + --text-secondary: #fff; + + /* Border colors */ + --border-primary: #999; + --border-transparent: transparent; + + /* Button colors */ + --btn-primary-bg: #007bff; + --btn-primary-border: #007bff; + --btn-secondary-bg: #6c757d; + --btn-secondary-border: #6c757d; +} + +/* Dark Mode Variables - Productivity Tool Theme */ +[data-theme='dark'] { + /* Background colors - Neutral dark grays (not pure black) */ + --bg-primary: #1E1E1E; + /* Main background - matches VS Code */ + --bg-secondary: #2D2D2D; + /* Cards, panels, elevated surfaces */ + + /* Text colors - Clear hierarchy, not harsh white */ + --text-primary: #E4E4E4; + /* Primary text - softer than pure white */ + --text-secondary: #E4E4E4; + /* Secondary text on buttons */ + + /* Border colors - Subtle separation */ + --border-primary: #3E3E3E; + /* Borders - subtle but visible */ + --border-transparent: transparent; + + /* Button colors - Subtle blue accent matching brand */ + --btn-primary-bg: #2B8CF7; + /* Accent blue - matching titlebar */ + --btn-primary-border: #2B8CF7; + --btn-secondary-bg: #3E3E3E; + /* Neutral secondary actions */ + --btn-secondary-border: #3E3E3E; +} + * { - font-family: 'Helvetica', 'Arial', sans-serif; + font-family: 'Helvetica', 'Arial', sans-serif; } input { - border: 1px solid #999; + border: 1px solid var(--border-primary); } .container { - height: 100vh; - display: flex; - width: 100vw; - flex-direction: column; + height: 100vh; + display: flex; + width: 100vw; + flex-direction: column; } .body { - background-color: rgb(240, 242, 245); - height: -webkit-fill-available; - flex: 1; + background-color: var(--bg-primary); + height: -webkit-fill-available; + flex: 1; } .graph { - padding: 50px; - background-color: rgb(240, 242, 245); - height: -webkit-fill-available; - flex: 80; + padding: 50px; + background-color: var(--bg-primary); + height: -webkit-fill-available; + flex: 80; } .graph-container { - background-color: #fff; + background-color: var(--bg-secondary); } .middle { - display: flex; - justify-content: center; - align-items: center; + display: flex; + justify-content: center; + align-items: center; } .btn { - display: inline-block; - font-weight: 400; - color: #212529; - text-align: center; - vertical-align: middle; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; - background-color: transparent; - border: 1px solid transparent; - padding: .375rem .75rem; - line-height: 1.5; - border-radius: .25rem; + display: inline-block; + font-weight: 400; + color: var(--text-primary); + text-align: center; + vertical-align: middle; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + background-color: transparent; + border: 1px solid var(--border-transparent); + padding: .375rem .75rem; + line-height: 1.5; + border-radius: .25rem; } .btn-primary { - color: #fff; - background-color: #007bff; - border-color: #007bff; + color: var(--text-secondary); + background-color: var(--btn-primary-bg); + border-color: var(--btn-primary-border); } .btn-secondary { - color: #fff; - background-color: #6c757d; - border-color: #6c757d; + color: var(--text-secondary); + background-color: var(--btn-secondary-bg); + border-color: var(--btn-secondary-border); } .btn:not(:disabled):not(.disabled) { - cursor: pointer; + cursor: pointer; } @media screen and (max-width: 1000px) { - .graph { - padding: 40px; - } + .graph { + padding: 40px; + } } @media screen and (max-width: 650px) { - .graph { - padding: 35px; - } + .graph { + padding: 35px; + } } @media screen and (max-width: 500px) { - .graph { - padding: 20px; - } + .graph { + padding: 20px; + } } \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index d702cc0..8af2ccd 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -31,6 +31,16 @@ const app = () => { window.onbeforeunload = null; }; }, []); + + // Update document theme attribute when darkMode changes + useEffect(() => { + if (superState.darkMode) { + document.documentElement.setAttribute('data-theme', 'dark'); + } else { + document.documentElement.removeAttribute('data-theme'); + } + }, [superState.darkMode]); + return (
diff --git a/src/GraphArea.jsx b/src/GraphArea.jsx index 373eb82..2396e84 100644 --- a/src/GraphArea.jsx +++ b/src/GraphArea.jsx @@ -18,7 +18,15 @@ function Graph({ const initialiseNewGraph = () => { const myGraph = new MyGraph( - graphID, ref.current, dispatcher, superState, projectName, nodeValidator, edgeValidator, authorName, + graphID, + ref.current, + dispatcher, + superState, + projectName, + nodeValidator, + edgeValidator, + authorName, + superState.darkMode, ); if (graphID) myGraph.loadGraphFromLocalStorage(); if (serverID) { @@ -55,6 +63,13 @@ function Graph({ } }, [ref]); + // Update theme when darkMode changes + useEffect(() => { + if (instance && instance.updateTheme) { + instance.updateTheme(superState.darkMode); + } + }, [superState.darkMode, instance]); + const { id } = el; return ( diff --git a/src/GraphWorkspace.jsx b/src/GraphWorkspace.jsx index b092393..3b5a98e 100644 --- a/src/GraphWorkspace.jsx +++ b/src/GraphWorkspace.jsx @@ -59,7 +59,7 @@ const GraphComp = (props) => { }} > -
+
{superState.graphs.map((el, i) => ( { } - concore Editor` : 'untitled' } +
dispatcher({ type: T.TOGGLE_DARK_MODE })} + style={{ + cursor: 'pointer', + padding: '0 15px', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + transition: 'opacity 0.2s', + }} + onMouseEnter={(e) => { e.currentTarget.style.opacity = '0.7'; }} + onMouseLeave={(e) => { e.currentTarget.style.opacity = '1'; }} + role="button" + tabIndex={0} + onKeyDown={(e) => e.key === 'Enter' && dispatcher({ type: T.TOGGLE_DARK_MODE })} + aria-label="Toggle dark mode" + > + {superState.darkMode ? : } +
diff --git a/src/component/HeaderComps.jsx b/src/component/HeaderComps.jsx index ed2c3ac..3062785 100644 --- a/src/component/HeaderComps.jsx +++ b/src/component/HeaderComps.jsx @@ -30,7 +30,7 @@ const FileUploader = ({ ); const Switcher = ({ - text, action, active, tabIndex, + text, action, active, tabIndex, Icon, }) => (
ev.key === ' ' && action()} > + {Icon &&
} -
+
{text}
diff --git a/src/component/fileBrowser.css b/src/component/fileBrowser.css index fb56556..acf67ae 100644 --- a/src/component/fileBrowser.css +++ b/src/component/fileBrowser.css @@ -1,201 +1,445 @@ /* Same file as react-file-browser.css in node modules but with few modifications */ -.inputButton{ - font-size: large; - text-align: center; - color: #fff; - padding-top: 10px; - padding-bottom: 10px; - width: 100%; - border: 2px solid white; - background-color: #1e88e5; - font-weight: bold; - display: block; +.inputButton { + font-size: large; + text-align: center; + color: #fff; + padding-top: 10px; + padding-bottom: 10px; + width: 100%; + border: 2px solid white; + background-color: #1e88e5; + font-weight: bold; + display: block; } div.rendered-react-keyed-file-browser div.action-bar { - margin-bottom: 0.5rem; - flex-wrap: wrap; - display: flex; - align-items: flex-start; } - div.rendered-react-keyed-file-browser div.action-bar input[type="search"] { + margin-bottom: 0.5rem; + flex-wrap: wrap; + display: flex; + align-items: flex-start; +} + +div.rendered-react-keyed-file-browser div.action-bar input[type="search"] { display: block; flex-grow: 2; min-width: 300px; padding: 0.25rem 0.5rem; line-height: 1em; margin-bottom: 0.5rem; - border: 0.1rem solid #ddd; } - div.rendered-react-keyed-file-browser div.action-bar .item-actions { + border: 0.1rem solid #ddd; +} + +div.rendered-react-keyed-file-browser div.action-bar .item-actions { text-align: right; margin: 0; - padding: 0; } - div.rendered-react-keyed-file-browser div.action-bar ul.item-actions { + padding: 0; +} + +div.rendered-react-keyed-file-browser div.action-bar ul.item-actions { display: block; flex-grow: 1; min-width: 300px; margin-left: 10px; - white-space: nowrap; } - div.rendered-react-keyed-file-browser div.action-bar ul.item-actions li { - display: inline-block; - margin: 0; } - div.rendered-react-keyed-file-browser div.action-bar ul.item-actions li:not(:last-child) { - margin-right: 0.5rem; } + white-space: nowrap; +} + +div.rendered-react-keyed-file-browser div.action-bar ul.item-actions li { + display: inline-block; + margin: 0; +} + +div.rendered-react-keyed-file-browser div.action-bar ul.item-actions li:not(:last-child) { + margin-right: 0.5rem; +} div.rendered-react-keyed-file-browser div.files { - /* overflow: auto; */ - width: 30vw; + /* overflow: auto; */ + width: 30vw; } div.rendered-react-keyed-file-browser div.files table { - width: 100%; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; } - div.rendered-react-keyed-file-browser div.files table th, div.rendered-react-keyed-file-browser div.files table td { + width: 100%; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +div.rendered-react-keyed-file-browser div.files table th, +div.rendered-react-keyed-file-browser div.files table td { font-weight: normal; text-align: left; margin: 0; - padding: 0.25rem; } - div.rendered-react-keyed-file-browser div.files table th { + padding: 0.25rem; +} + +div.rendered-react-keyed-file-browser div.files table th { font-weight: bold; - width:1px; - white-space:nowrap; } - div.rendered-react-keyed-file-browser div.files table td { - width:1px; - white-space:nowrap; } - div.rendered-react-keyed-file-browser div.files table th.size, div.rendered-react-keyed-file-browser div.files table th.modified, div.rendered-react-keyed-file-browser div.files table td.size, div.rendered-react-keyed-file-browser div.files table td.modified { - text-align: right; } - div.rendered-react-keyed-file-browser div.files table th.name i, div.rendered-react-keyed-file-browser div.files table td.name i { - padding-right: 0.5rem; } - div.rendered-react-keyed-file-browser div.files table thead th { - border-bottom: 0.1rem solid #ddd; } - div.rendered-react-keyed-file-browser div.files table tr:not(:last-child) td { - border-bottom: 0.1rem solid #eee; } - div.rendered-react-keyed-file-browser div.files table td.name { - padding-left: 0.8rem; } - div.rendered-react-keyed-file-browser div.files table td.name form.renaming { - display: flex; - align-items: center; } - div.rendered-react-keyed-file-browser div.files table td.name form.renaming i { - flex-grow: 0; - flex-shrink: 0; } - div.rendered-react-keyed-file-browser div.files table td.name form.renaming input[type="text"] { - flex: 1; } - div.rendered-react-keyed-file-browser div.files table tr td { - cursor: pointer; } - div.rendered-react-keyed-file-browser div.files table tr.selected td { - font-weight: bold; } - div.rendered-react-keyed-file-browser div.files table tr.selected td input, div.rendered-react-keyed-file-browser div.files table tr.selected td button { - font-weight: normal; } - div.rendered-react-keyed-file-browser div.files table tr.selected td.name { - position: relative; } - div.rendered-react-keyed-file-browser div.files table tr.selected td.name:after { - content: ' '; - position: absolute; - left: 0; - top: 0; - width: 0.3rem; - height: 100%; - background: #1d4567; } - div.rendered-react-keyed-file-browser div.files table tr.dragover td, div.rendered-react-keyed-file-browser div.files table tr.dragover th { - background: #eee; } - -div.rendered-file-browser div.files li.file.pending, div.rendered-file-browser div.files li.file.dragging, div.rendered-file-browser div.files li.folder.pending, div.rendered-file-browser div.files li.folder.dragging { - opacity: 0.4; } - -div.rendered-file-browser div.files li.file.dragover, div.rendered-file-browser div.files li.folder.dragover { - background: #eee; } - -div.rendered-file-browser div.files li.file.selected > div.item, div.rendered-file-browser div.files li.folder.selected > div.item { - color: #fff; - background: #ccc; } - div.rendered-file-browser div.files li.file.selected > div.item .text-muted, div.rendered-file-browser div.files li.folder.selected > div.item .text-muted { - color: #e6e6e6; } - div.rendered-file-browser div.files li.file.selected > div.item a:not(.btn), div.rendered-file-browser div.files li.file.selected > div.item.folder a:not(.btn), div.rendered-file-browser div.files li.file.selected > div.item i, div.rendered-file-browser div.files li.folder.selected > div.item a:not(.btn), div.rendered-file-browser div.files li.folder.selected > div.item.folder a:not(.btn), div.rendered-file-browser div.files li.folder.selected > div.item i { - color: #fff; } + width: 1px; + white-space: nowrap; +} + +div.rendered-react-keyed-file-browser div.files table td { + width: 1px; + white-space: nowrap; +} + +div.rendered-react-keyed-file-browser div.files table th.size, +div.rendered-react-keyed-file-browser div.files table th.modified, +div.rendered-react-keyed-file-browser div.files table td.size, +div.rendered-react-keyed-file-browser div.files table td.modified { + text-align: right; +} + +div.rendered-react-keyed-file-browser div.files table th.name i, +div.rendered-react-keyed-file-browser div.files table td.name i { + padding-right: 0.5rem; +} + +div.rendered-react-keyed-file-browser div.files table thead th { + border-bottom: 0.1rem solid #ddd; +} + +div.rendered-react-keyed-file-browser div.files table tr:not(:last-child) td { + border-bottom: 0.1rem solid #eee; +} + +div.rendered-react-keyed-file-browser div.files table td.name { + padding-left: 0.8rem; +} + +div.rendered-react-keyed-file-browser div.files table td.name form.renaming { + display: flex; + align-items: center; +} + +div.rendered-react-keyed-file-browser div.files table td.name form.renaming i { + flex-grow: 0; + flex-shrink: 0; +} + +div.rendered-react-keyed-file-browser div.files table td.name form.renaming input[type="text"] { + flex: 1; +} + +div.rendered-react-keyed-file-browser div.files table tr td { + cursor: pointer; +} + +div.rendered-react-keyed-file-browser div.files table tr.selected td { + font-weight: bold; +} + +div.rendered-react-keyed-file-browser div.files table tr.selected td input, +div.rendered-react-keyed-file-browser div.files table tr.selected td button { + font-weight: normal; +} + +div.rendered-react-keyed-file-browser div.files table tr.selected td.name { + position: relative; +} + +div.rendered-react-keyed-file-browser div.files table tr.selected td.name:after { + content: ' '; + position: absolute; + left: 0; + top: 0; + width: 0.3rem; + height: 100%; + background: #1d4567; +} + +div.rendered-react-keyed-file-browser div.files table tr.dragover td, +div.rendered-react-keyed-file-browser div.files table tr.dragover th { + background: #eee; +} + +div.rendered-file-browser div.files li.file.pending, +div.rendered-file-browser div.files li.file.dragging, +div.rendered-file-browser div.files li.folder.pending, +div.rendered-file-browser div.files li.folder.dragging { + opacity: 0.4; +} + +div.rendered-file-browser div.files li.file.dragover, +div.rendered-file-browser div.files li.folder.dragover { + background: #eee; +} + +div.rendered-file-browser div.files li.file.selected>div.item, +div.rendered-file-browser div.files li.folder.selected>div.item { + color: #fff; + background: #ccc; +} + +div.rendered-file-browser div.files li.file.selected>div.item .text-muted, +div.rendered-file-browser div.files li.folder.selected>div.item .text-muted { + color: #e6e6e6; +} + +div.rendered-file-browser div.files li.file.selected>div.item a:not(.btn), +div.rendered-file-browser div.files li.file.selected>div.item.folder a:not(.btn), +div.rendered-file-browser div.files li.file.selected>div.item i, +div.rendered-file-browser div.files li.folder.selected>div.item a:not(.btn), +div.rendered-file-browser div.files li.folder.selected>div.item.folder a:not(.btn), +div.rendered-file-browser div.files li.folder.selected>div.item i { + color: #fff; +} div.rendered-file-browser div.files ul { - list-style: none; - padding: 0; - display: grid; - gap: 4px; - grid-template-columns: repeat(3, 1fr); } - div.rendered-file-browser div.files ul li.folder { - grid-column: 1/4; } - div.rendered-file-browser div.files ul li.folder > div.item { - display: flex; - flex-direction: row; - align-items: center; - padding-left: 4px; - border: 1px solid #eee; } - div.rendered-file-browser div.files ul li.folder > div.item span.name { - flex: 1; - line-height: folder-size; } - div.rendered-file-browser div.files ul li.folder > div.item span.thumb { - flex-basis: 45px; - border: none; - text-align: center; } - div.rendered-file-browser div.files ul li.folder > div.item span.thumb > i { - line-height: 45px; - font-size: 18px; } - div.rendered-file-browser div.files ul li.folder > div.item form.renaming { - margin-top: 8px; - margin-right: 8px; } - div.rendered-file-browser div.files ul li.folder > p { - margin: 8px; - margin-bottom: 0; - padding: 0; } - div.rendered-file-browser div.files ul li.folder.expanded { - padding-bottom: 8px; - border-bottom: 1px solid #eee; - border-left: 4px solid #eee; - border-right: 1px solid #eee; } - div.rendered-file-browser div.files ul li.folder.expanded > div.item { - padding-left: 0px; - margin-right: -1px; - margin-left: -1px; } - div.rendered-file-browser div.files ul li.folder.expanded.selected { - border-bottom: 1px solid #ccc; - border-left: 4px solid #ccc; - border-right: 1px solid #ccc; } - div.rendered-file-browser div.files ul li.selected.folder > div.item { - border: 1px solid #bfbfbf; } - div.rendered-file-browser div.files ul li.selected.folder > div.item span.thumb { - border: none; } - div.rendered-file-browser div.files ul li.file { + list-style: none; + padding: 0; + display: grid; + gap: 4px; + grid-template-columns: repeat(3, 1fr); +} + +div.rendered-file-browser div.files ul li.folder { + grid-column: 1/4; +} + +div.rendered-file-browser div.files ul li.folder>div.item { + display: flex; + flex-direction: row; + align-items: center; + padding-left: 4px; + border: 1px solid #eee; +} + +div.rendered-file-browser div.files ul li.folder>div.item span.name { + flex: 1; + line-height: folder-size; +} + +div.rendered-file-browser div.files ul li.folder>div.item span.thumb { + flex-basis: 45px; + border: none; + text-align: center; +} + +div.rendered-file-browser div.files ul li.folder>div.item span.thumb>i { + line-height: 45px; + font-size: 18px; +} + +div.rendered-file-browser div.files ul li.folder>div.item form.renaming { + margin-top: 8px; + margin-right: 8px; +} + +div.rendered-file-browser div.files ul li.folder>p { + margin: 8px; + margin-bottom: 0; + padding: 0; +} + +div.rendered-file-browser div.files ul li.folder.expanded { + padding-bottom: 8px; + border-bottom: 1px solid #eee; + border-left: 4px solid #eee; + border-right: 1px solid #eee; +} + +div.rendered-file-browser div.files ul li.folder.expanded>div.item { + padding-left: 0px; + margin-right: -1px; + margin-left: -1px; +} + +div.rendered-file-browser div.files ul li.folder.expanded.selected { + border-bottom: 1px solid #ccc; + border-left: 4px solid #ccc; + border-right: 1px solid #ccc; +} + +div.rendered-file-browser div.files ul li.selected.folder>div.item { + border: 1px solid #bfbfbf; +} + +div.rendered-file-browser div.files ul li.selected.folder>div.item span.thumb { + border: none; +} + +div.rendered-file-browser div.files ul li.file { margin: 4px; - padding: 0; } - div.rendered-file-browser div.files ul li.file > div.item { - display: flex; - flex-direction: column; - padding: 4px; - margin: 0; } - div.rendered-file-browser div.files ul li.file > div.item span.thumb { - flex-basis: 120px; - text-align: center; - position: relative; - border: 1px solid #eee; - margin-bottom: 10px; } - div.rendered-file-browser div.files ul li.file > div.item span.thumb > i { - font-size: 40px; - line-height: 120px; } - div.rendered-file-browser div.files ul li.file > div.item span.thumb div.image { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-size: cover; - background-position: 50% 50%; - background-repeat: no-repeat; } - div.rendered-file-browser div.files ul li.selected.file > div.item span.thumb { - border: 1px solid #bfbfbf; } - div.rendered-file-browser div.files ul li.selected.file > div.item span.thumb div.image { - opacity: 0.8; } - -div.rendered-file-browser p.loading, div.rendered-file-browser p.empty { - margin: 16px 0; } \ No newline at end of file + padding: 0; +} + +div.rendered-file-browser div.files ul li.file>div.item { + display: flex; + flex-direction: column; + padding: 4px; + margin: 0; +} + +div.rendered-file-browser div.files ul li.file>div.item span.thumb { + flex-basis: 120px; + text-align: center; + position: relative; + border: 1px solid #eee; + margin-bottom: 10px; +} + +div.rendered-file-browser div.files ul li.file>div.item span.thumb>i { + font-size: 40px; + line-height: 120px; +} + +div.rendered-file-browser div.files ul li.file>div.item span.thumb div.image { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-size: cover; + background-position: 50% 50%; + background-repeat: no-repeat; +} + +div.rendered-file-browser div.files ul li.selected.file>div.item span.thumb { + border: 1px solid #bfbfbf; +} + +div.rendered-file-browser div.files ul li.selected.file>div.item span.thumb div.image { + opacity: 0.8; +} + +div.rendered-file-browser p.loading, +div.rendered-file-browser p.empty { + margin: 16px 0; +} + +/* ============================================ + DARK MODE - LEFT SIDEBAR / FILE BROWSER + ============================================ */ + +[data-theme='dark'] { + /* Main sidebar background */ + background: #181818; +} + +/* Upload Directory Button */ +[data-theme='dark'] .inputButton { + background-color: #2B8CF7; + /* Accent Blue */ + color: #FFFFFF; + border: 1px solid #2B8CF7; +} + +[data-theme='dark'] .inputButton:hover { + background-color: #1e88e5; + /* Slightly darker/different blue on hover */ +} + +/* Section Header (h4 - Folder Name) */ +[data-theme='dark'] h4 { + background-color: #202020; + color: #EAEAEA; + padding: 10px; + margin: 0; + border-bottom: 1px solid #2C2C2C; +} + +/* Filter Input Field */ +[data-theme='dark'] div.rendered-react-keyed-file-browser div.action-bar input[type="search"] { + background: #242424; + border: 1px solid #333333; + color: #FFFFFF; +} + +[data-theme='dark'] div.rendered-react-keyed-file-browser div.action-bar input[type="search"]::placeholder { + color: #888888; +} + +/* File Browser Container */ +[data-theme='dark'] div.rendered-react-keyed-file-browser div.files { + background: #181818; + color: #EAEAEA; +} + +/* Table Column Headers */ +[data-theme='dark'] div.rendered-react-keyed-file-browser div.files table thead th { + color: #9AA0A6; + border-bottom: 1px solid #2C2C2C; + background: #181818; +} + +/* Table Rows */ +[data-theme='dark'] div.rendered-react-keyed-file-browser div.files table tr td { + color: #EAEAEA; + border-bottom: 1px solid #202020; +} + +/* Table Row Hover */ +[data-theme='dark'] div.rendered-react-keyed-file-browser div.files table tr:hover td { + background: #252525; +} + +/* Selected Row */ +[data-theme='dark'] div.rendered-react-keyed-file-browser div.files table tr.selected td { + background: #2A2A2A; + color: #FFFFFF; +} + +[data-theme='dark'] div.rendered-react-keyed-file-browser div.files table tr.selected td.name:after { + background: #2B8CF7; + /* Accent blue for selection indicator */ +} + +/* Dragover State */ +[data-theme='dark'] div.rendered-react-keyed-file-browser div.files table tr.dragover td, +[data-theme='dark'] div.rendered-react-keyed-file-browser div.files table tr.dragover th { + background: #2A2A2A; +} + +/* Empty State ("No files.") */ +[data-theme='dark'] div.rendered-file-browser p.empty { + color: #6F6F6F; +} + +[data-theme='dark'] div.rendered-file-browser p.loading { + color: #9AA0A6; +} + +/* Folder/File Items in List View */ +[data-theme='dark'] div.rendered-file-browser div.files ul li.folder>div.item { + border: 1px solid #2C2C2C; + background: #181818; +} + +[data-theme='dark'] div.rendered-file-browser div.files ul li.folder>div.item:hover { + background: #252525; +} + +[data-theme='dark'] div.rendered-file-browser div.files li.file.selected>div.item, +[data-theme='dark'] div.rendered-file-browser div.files li.folder.selected>div.item { + background: #2A2A2A; + color: #FFFFFF; + border: 1px solid #2B8CF7; +} + +[data-theme='dark'] div.rendered-file-browser div.files ul li.file>div.item span.thumb { + border: 1px solid #2C2C2C; + background: #202020; +} + +[data-theme='dark'] div.rendered-file-browser div.files li.file.dragover, +[data-theme='dark'] div.rendered-file-browser div.files li.folder.dragover { + background: #2A2A2A; +} + +/* Expanded Folder Borders */ +[data-theme='dark'] div.rendered-file-browser div.files ul li.folder.expanded { + border-bottom: 1px solid #2C2C2C; + border-left: 4px solid #2C2C2C; + border-right: 1px solid #2C2C2C; +} + +[data-theme='dark'] div.rendered-file-browser div.files ul li.folder.expanded.selected { + border-bottom: 1px solid #2B8CF7; + border-left: 4px solid #2B8CF7; + border-right: 1px solid #2B8CF7; +} \ No newline at end of file diff --git a/src/component/header.css b/src/component/header.css index feea4ad..065ef24 100644 --- a/src/component/header.css +++ b/src/component/header.css @@ -97,4 +97,51 @@ background: transparent; margin: 0; padding: 0; +} + +/* ============================================ + DARK MODE STYLES + ============================================ */ + +[data-theme='dark'] .header { + background: #262626; +} + +[data-theme='dark'] .toolbar { + background: #262626; +} + +[data-theme='dark'] .toolbar .tool { + color: #6A6A6A; + /* Disabled/inactive icon color */ +} + +[data-theme='dark'] .toolbar .tool.active { + color: #E6E6E6; + /* Primary icons/text */ +} + +[data-theme='dark'] .toolbar .tool-text-only { + color: #B0B0B0; + /* Secondary text */ +} + +[data-theme='dark'] .toolbar .tool.active:hover { + background: #2A2A2A; + /* Hover effect */ +} + +[data-theme='dark'] .titlebar { + background-color: #2B8CF7; + /* Accent Blue for app title */ + color: #fff; +} + +[data-theme='dark'] .sep { + background: rgba(255, 255, 255, 0.1); +} + +[data-theme='dark'] .rc-switch-checked { + border: 1px solid #2B8CF7; + background-color: #2B8CF7; } \ No newline at end of file diff --git a/src/component/tabBar.css b/src/component/tabBar.css index 921c805..4090751 100644 --- a/src/component/tabBar.css +++ b/src/component/tabBar.css @@ -2,7 +2,8 @@ display: flex; overflow: auto; margin-bottom: -1px; - width: 100%;; + width: 100%; + ; } .tab { @@ -57,4 +58,55 @@ .tab-act:hover { text-shadow: 0px 0px 10px #000; +} + +/* ============================================ + DARK MODE - NODE / FLOW TAB BAR + ============================================ */ + +/* Tab Bar Container */ +[data-theme='dark'] .tab-par { + background: #1B1B1B; + border-bottom: 1px solid #2A2A2A; +} + +/* Inactive Tabs */ +[data-theme='dark'] .tab { + background-color: #1B1B1B; + border: 1px solid #2A2A2A; + border-bottom: 1px solid #2A2A2A; + color: #A0A0A0; + /* Inactive tab text */ +} + +[data-theme='dark'] .tab:hover { + background-color: #202020; +} + +/* Active/Selected Tab */ +[data-theme='dark'] .tab.selected { + background-color: #232323; + color: #FFFFFF; + /* Active tab text */ + border: 1px solid #2A2A2A; + border-bottom: 0; +} + +/* Tab Action Icons (➕ ✏ ❌) */ +[data-theme='dark'] .tab-act { + color: #B5B5B5; + /* Default icon color */ +} + +[data-theme='dark'] .tab-act:hover { + color: #FFFFFF; + /* Hover icon color */ + text-shadow: 0px 0px 5px rgba(255, 255, 255, 0.3); +} + +/* Delete Icon Hover (specific red color) */ +[data-theme='dark'] .tab-act.delete-icon:hover { + color: #E5533D; + /* Delete hover - red */ + text-shadow: 0px 0px 5px rgba(229, 83, 61, 0.5); } \ No newline at end of file diff --git a/src/component/zoomSetter.css b/src/component/zoomSetter.css index e1b8a45..62a2dbc 100644 --- a/src/component/zoomSetter.css +++ b/src/component/zoomSetter.css @@ -12,7 +12,8 @@ border-bottom: none; border-top-left-radius: 3px; } -.zoom-comp > *{ + +.zoom-comp>* { padding: 2px 5px; } @@ -31,13 +32,58 @@ user-select: none; } -.zoom-comp .zoom-btn{ +.zoom-comp .zoom-btn { cursor: pointer; } -.zoom-comp .zoom-btn:hover{ + +.zoom-comp .zoom-btn:hover { background: #eee; } .zoom-comp .zoom-value { width: 40px; +} + +/* ============================================ + DARK MODE - ZOOM CONTROLS + ============================================ */ + +/* Container */ +[data-theme='dark'] .zoom-comp { + background: #1E1E1E; + border: 1px solid #2A2A2A; + border-right: none; + border-bottom: none; +} + +/* Text & Icons */ +[data-theme='dark'] .zoom-comp .zoom-box { + color: #E0E0E0; + /* Text (100%) */ + border-right: 1px solid #2A2A2A; +} + +/* Button Hover State */ +[data-theme='dark'] .zoom-comp .zoom-btn:hover { + background: #2A2A2A; +} + +/* Slider Track (Rail) */ +[data-theme='dark'] .zoom-comp .rc-slider-rail { + background-color: #2A2A2A; +} + +/* Slider Thumb (Handle) */ +[data-theme='dark'] .zoom-comp .rc-slider-handle { + border-color: #2B8CF7; + background-color: #2B8CF7; + box-shadow: none; + /* Clean look */ +} + +/* Handle active/focus state for slider */ +[data-theme='dark'] .zoom-comp .rc-slider-handle:active, +[data-theme='dark'] .zoom-comp .rc-slider-handle:focus, +[data-theme='dark'] .zoom-comp .rc-slider-handle-click-focused { + box-shadow: 0 0 0 5px rgba(43, 140, 247, 0.2); } \ No newline at end of file diff --git a/src/config/cytoscape-options.js b/src/config/cytoscape-options.js index d0c7b60..870f68d 100644 --- a/src/config/cytoscape-options.js +++ b/src/config/cytoscape-options.js @@ -1,11 +1,11 @@ -import style from './cytoscape-style'; +import getCytoscapeStyle from './cytoscape-style'; -const options = { - style: [...style], +const getCytoscapeOptions = (darkMode = false) => ({ + style: [...getCytoscapeStyle(darkMode)], zoomingEnabled: true, userZoomingEnabled: true, minZoom: 0.25, maxZoom: 5, -}; +}); -export default options; +export default getCytoscapeOptions; diff --git a/src/config/cytoscape-style.js b/src/config/cytoscape-style.js index 4bbba03..6e05ca2 100644 --- a/src/config/cytoscape-style.js +++ b/src/config/cytoscape-style.js @@ -1,206 +1,225 @@ -const style = [ - { - selector: '*', - style: { - overlayOpacity: '0', - }, - }, - { - selector: 'node[type = "ordin"]', - style: { - content: 'data(label)', - zIndex: 100, - width: 'data(style.width)', - height: 'data(style.height)', - shape: 'data(style.shape)', - opacity: 'data(style.opacity)', - backgroundColor: 'data(style.backgroundColor)', - borderColor: 'data(style.borderColor)', - borderWidth: 'data(style.borderWidth)', - textValign: 'center', - textHalign: 'center', - fontSize: (ele) => { - const w = ele.data('style').width; - const h = ele.data('style').height; - const val = Math.min(w, h); - if (val < 20) return 5; - if (val > 500) return 60; - return 10 + ((val - 20) * 50) / 480; +const getCytoscapeStyle = (darkMode = false) => { + // Theme-aware colors + const edgeLabelTextColor = darkMode ? '#ffffff' : '#333'; + const edgeLabelBgColor = darkMode ? '#2d2d2d' : '#fff'; + const bendNodeColor = darkMode ? '#7e57c2' : '#9575cd'; + const handleColor = darkMode ? '#ff1744' : '#f50057'; + const overlayColor = darkMode ? '#fff' : '#000'; + const nodeTextColor = darkMode ? '#FFFFFF' : '#000'; // Text color for nodes + + return [ + { + selector: '*', + style: { + overlayOpacity: '0', }, - textWrap: 'wrap', - textMaxWidth: 'data(style.width)', }, - }, - { - selector: 'node[type="special"]', - style: { - width: 8, - height: 8, - backgroundColor: 'data(style.backgroundColor)', - zIndex: 1000, + { + selector: 'node[type = "ordin"]', + style: { + content: 'data(label)', + zIndex: 100, + width: 'data(style.width)', + height: 'data(style.height)', + shape: 'data(style.shape)', + opacity: 'data(style.opacity)', + backgroundColor: 'data(style.backgroundColor)', + borderColor: 'data(style.borderColor)', + borderWidth: 'data(style.borderWidth)', + color: nodeTextColor, // Theme-aware text color + textValign: 'center', + textHalign: 'center', + fontSize: (ele) => { + const w = ele.data('style').width; + const h = ele.data('style').height; + const val = Math.min(w, h); + if (val < 20) return 5; + if (val > 500) return 60; + return 10 + ((val - 20) * 50) / 480; + }, + textWrap: 'wrap', + textMaxWidth: 'data(style.width)', + }, }, - }, - - { - selector: 'edge', - style: { - curveStyle: 'bezier', - targetArrowShape: 'triangle', - arrowScale: 1.2, + { + selector: 'node[type="special"]', + style: { + width: 8, + height: 8, + backgroundColor: 'data(style.backgroundColor)', + zIndex: 1000, + }, }, - }, - { - selector: 'edge[type = "ordin"]', - style: { - width: 'data(style.thickness)', - lineColor: 'data(style.backgroundColor)', - targetArrowColor: 'data(style.backgroundColor)', - curveStyle: (ele) => { - const source = ele.source(); - const target = ele.target(); - - // Check if there are parallel edges - const parallelEdges = source.edgesWith(target); - const hasParallelEdges = parallelEdges.length > 1; - - // Get positions - const p1 = source.position(); - const p2 = target.position(); - - // Calculate distance between nodes - const distance = Math.sqrt( - (p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2, - ); - - // Calculate difference - const dx = Math.abs(p1.x - p2.x); - const dy = Math.abs(p1.y - p2.y); - - // Define a threshold for what counts as "aligned" - const threshold = 10; - - // Check if edge has custom bend data - const bendDistance = ele.data('bendData')?.bendDistance || 0; - const hasBend = Math.abs(bendDistance) > 0; - - // When nodes are very close, always use straight style to prevent edge disappearance - if (distance < 50) { - return 'straight'; - } - - // For parallel edges or edges with bend, use bezier curves - if (hasParallelEdges || hasBend) { - return 'unbundled-bezier'; - } - // If aligned horizontally OR vertically, be straight - if (dx < threshold || dy < threshold) { - return 'straight'; - } - - // use unbundled-bezier to respect bend points - return 'unbundled-bezier'; - }, - segmentDistances: (ele) => { - // When nodes are very close, don't apply bend to prevent edge disappearance - const source = ele.source(); - const target = ele.target(); - const p1 = source.position(); - const p2 = target.position(); - const distance = Math.sqrt( - (p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2, - ); - - if (distance < 50) { - return 0; - } - - return ele.data('bendData.bendDistance'); + { + selector: 'edge', + style: { + curveStyle: 'bezier', + targetArrowShape: 'triangle', + arrowScale: 1.2, }, - segmentWeights: 'data(bendData.bendWeight)', - edgeDistances: 'node-position', - lineStyle: 'data(style.shape)', - controlPointDistances: (ele) => { - // For parallel edges, ensure adequate control point spacing - const bendDistance = ele.data('bendData')?.bendDistance || 0; - return Math.abs(bendDistance) > 0 ? bendDistance : undefined; + }, + { + selector: 'edge[type = "ordin"]', + style: { + width: 'data(style.thickness)', + lineColor: darkMode ? '#E0E0E0' : 'data(style.backgroundColor)', + targetArrowColor: darkMode ? '#E0E0E0' : 'data(style.backgroundColor)', + curveStyle: (ele) => { + const source = ele.source(); + const target = ele.target(); + + // Check if there are parallel edges + const parallelEdges = source.edgesWith(target); + const hasParallelEdges = parallelEdges.length > 1; + + // Get positions + const p1 = source.position(); + const p2 = target.position(); + + // Calculate distance between nodes + const distance = Math.sqrt( + (p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2, + ); + + // Calculate difference + const dx = Math.abs(p1.x - p2.x); + const dy = Math.abs(p1.y - p2.y); + + // Define a threshold for what counts as "aligned" + const threshold = 10; + + // Check if edge has custom bend data + const bendDistance = ele.data('bendData')?.bendDistance || 0; + const hasBend = Math.abs(bendDistance) > 0; + + // When nodes are very close, always use straight style to prevent edge disappearance + if (distance < 50) { + return 'straight'; + } + + // For parallel edges or edges with bend, use bezier curves + if (hasParallelEdges || hasBend) { + return 'unbundled-bezier'; + } + + // If aligned horizontally OR vertically, be straight + if (dx < threshold || dy < threshold) { + return 'straight'; + } + + // use unbundled-bezier to respect bend points + return 'unbundled-bezier'; + }, + segmentDistances: (ele) => { + // When nodes are very close, don't apply bend to prevent edge disappearance + const source = ele.source(); + const target = ele.target(); + const p1 = source.position(); + const p2 = target.position(); + const distance = Math.sqrt( + (p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2, + ); + + if (distance < 50) { + return 0; + } + + return ele.data('bendData.bendDistance'); + }, + segmentWeights: 'data(bendData.bendWeight)', + edgeDistances: 'node-position', + lineStyle: 'data(style.shape)', + controlPointDistances: (ele) => { + // For parallel edges, ensure adequate control point spacing + const bendDistance = ele.data('bendData')?.bendDistance || 0; + return Math.abs(bendDistance) > 0 ? bendDistance : undefined; + }, + controlPointWeights: (ele) => { + const bendWeight = ele.data('bendData')?.bendWeight; + return bendWeight !== undefined ? bendWeight : 0.5; + }, }, - controlPointWeights: (ele) => { - const bendWeight = ele.data('bendData')?.bendWeight; - return bendWeight !== undefined ? bendWeight : 0.5; + }, + { + selector: 'edge[label]', + style: { + label: (ele) => { + // Get source and target nodes + const source = ele.source(); + const target = ele.target(); + + // Calculate distance between nodes + const p1 = source.position(); + const p2 = target.position(); + const distance = Math.sqrt( + (p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2, + ); + + // Define minimum distance threshold (in pixels) + // Below this distance, hide the label to prevent visual clutter + const minDistanceForLabel = 80; + + // Return label only if nodes are far enough apart + return distance >= minDistanceForLabel ? ele.data('label') : ''; + }, + edgeTextRotation: 'autorotate', + zIndex: 999, + fontSize: 12, + textBackgroundOpacity: 1, + textBackgroundPadding: '3px', + textBorderWidth: 0, + color: edgeLabelTextColor, + textBackgroundColor: edgeLabelBgColor, + textBackgroundShape: 'roundrectangle', }, }, - }, - { - selector: 'edge[label]', - style: { - label: (ele) => { - // Get source and target nodes - const source = ele.source(); - const target = ele.target(); - - // Calculate distance between nodes - const p1 = source.position(); - const p2 = target.position(); - const distance = Math.sqrt( - (p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2, - ); - - // Define minimum distance threshold (in pixels) - // Below this distance, hide the label to prevent visual clutter - const minDistanceForLabel = 80; - - // Return label only if nodes are far enough apart - return distance >= minDistanceForLabel ? ele.data('label') : ''; + { + selector: '.hidden', + style: { + display: 'none', }, - edgeTextRotation: 'autorotate', - zIndex: 999, - fontSize: 12, - textBackgroundOpacity: 1, - textBackgroundPadding: '3px', - textBorderWidth: 0, - color: '#333', - textBackgroundColor: '#fff', - textBackgroundShape: 'roundrectangle', }, - }, - { - selector: '.hidden', - style: { - display: 'none', + { + selector: '.eh-handle,node[type="bend"]', + style: { + height: 25, + width: 25, + opacity: 0.4, + borderWidth: 5, + borderOpacity: 0.1, + }, }, - }, - { - selector: '.eh-handle,node[type="bend"]', - style: { - height: 25, - width: 25, - opacity: 0.4, - borderWidth: 5, - borderOpacity: 0.1, + { + selector: 'node[type="bend"]', + style: { + backgroundColor: bendNodeColor, + }, }, - }, - { - selector: 'node[type="bend"]', - style: { - backgroundColor: '#9575cd', + { + selector: '.eh-handle', + style: { + backgroundColor: handleColor, + }, }, - }, - { - selector: '.eh-handle', - style: { - backgroundColor: '#f50057', + { + selector: ':selected', + style: { + overlayColor: darkMode ? '#2B8CF7' : overlayColor, // Accent blue for selected in dark mode + overlayOpacity: darkMode ? 0.3 : 0.1, + overlayPadding: darkMode ? 3 : 5, + }, }, - }, - { - selector: ':selected', - style: { - overlayColor: '#000', - overlayOpacity: 0.1, - overlayPadding: 5, + // Selected nodes - enhanced border + { + selector: 'node:selected', + style: { + 'border-color': darkMode ? '#2B8CF7' : 'data(style.borderColor)', + 'border-width': darkMode ? 3 : 'data(style.borderWidth)', + }, }, - }, -]; + ]; +}; -export default style; +export default getCytoscapeStyle; diff --git a/src/graph-builder/graph-core/1-core.js b/src/graph-builder/graph-core/1-core.js index 6d2602e..2acf1d8 100644 --- a/src/graph-builder/graph-core/1-core.js +++ b/src/graph-builder/graph-core/1-core.js @@ -5,6 +5,7 @@ import Konva from 'konva'; import nodeEditing from 'cytoscape-node-editing'; import $ from 'jquery'; import cyOptions from '../../config/cytoscape-options'; +import getCytoscapeStyle from '../../config/cytoscape-style'; import BendingDistanceWeight from '../calculations/bending-dist-weight'; import { actionType as T } from '../../reducer'; @@ -23,11 +24,17 @@ class CoreGraph { bendNode; + darkMode = false; // Current theme state + gridSize = 20; // Configurable grid size in pixels - constructor(id, element, dispatcher, superState, projectName, nodeValidator, edgeValidator, authorName) { + constructor( + id, element, dispatcher, superState, projectName, + nodeValidator, edgeValidator, authorName, darkMode = false, + ) { if (dispatcher) this.dispatcher = dispatcher; if (superState) this.superState = superState; + this.darkMode = darkMode; // Store dark mode state if (typeof cytoscape('core', 'edgehandles') !== 'function') { cytoscape.use(edgehandles); } @@ -38,7 +45,7 @@ class CoreGraph { gridGuide(cytoscape); } // if (cy) this.cy = cy; - this.cy = cytoscape({ ...cyOptions, container: element }); + this.cy = cytoscape({ ...cyOptions(darkMode), container: element }); this.cy.on('position', 'node', () => { this.cy.edges().updateStyle(); }); @@ -131,6 +138,15 @@ class CoreGraph { isNoControlsMode(node) { return node.data('type') !== 'ordin'; }, }); + // Grid colors based on dark mode + const gridColors = this.darkMode ? { + gridColor: '#606060', // Major grid lines - Light Grey + lineColor: 'rgba(96, 96, 96, 0.4)', // Minor grid lines - Light Grey (transparent) + } : { + gridColor: 'rgba(0, 0, 0, 0.2)', // Light mode major grid + lineColor: 'rgba(0, 0, 0, 0.1)', // Light mode minor grid + }; + this.cy.gridGuide({ snapToGridOnRelease: true, snapToGridDuringDrag: false, @@ -138,6 +154,8 @@ class CoreGraph { panGrid: true, gridSpacing: this.gridSize, snapToAlignmentLocationOnRelease: true, + gridColor: gridColors.gridColor, + lineColor: gridColors.lineColor, }); this.cy.edgehandles({ preview: false, @@ -332,6 +350,29 @@ class CoreGraph { this.selectDeselectEventHandler(); } + updateTheme(darkMode) { + this.darkMode = darkMode; // Update stored dark mode state + const newStyle = getCytoscapeStyle(darkMode); + this.cy.style(newStyle); + + // Update grid colors for dark mode + const gridColors = darkMode ? { + gridColor: '#606060', // Major grid lines - Light Grey + lineColor: 'rgba(96, 96, 96, 0.4)', // Minor grid lines - Light Grey (transparent) + } : { + gridColor: 'rgba(0, 0, 0, 0.2)', // Light mode major grid + lineColor: 'rgba(0, 0, 0, 0.1)', // Light mode minor grid + }; + + // Update grid guide with new colors + if (this.cy.gridGuide) { + this.cy.gridGuide({ + gridColor: gridColors.gridColor, + lineColor: gridColors.lineColor, + }); + } + } + reset() { this.resetAllComp(); this.resetAllAction(); diff --git a/src/graphWorkspace.css b/src/graphWorkspace.css index 9287120..60efe95 100644 --- a/src/graphWorkspace.css +++ b/src/graphWorkspace.css @@ -1,4 +1,20 @@ .graph-container { - flex: 1; - border: 1px solid #888; + flex: 1; + border: 1px solid #888; +} + +/* ============================================ + DARK MODE - CANVAS / EDITOR AREA + ============================================ */ + +[data-theme='dark'] .graph-container { + background-color: #262626; + /* Slightly Darker Grey */ + border: 1px solid #2C2C2C; + /* Subtle border */ +} + +/* Cytoscape canvas background */ +[data-theme='dark'] .graph-element { + background-color: #262626 !important; } \ No newline at end of file diff --git a/src/reducer/actionType.js b/src/reducer/actionType.js index 09f7981..ea540e1 100644 --- a/src/reducer/actionType.js +++ b/src/reducer/actionType.js @@ -45,6 +45,7 @@ const actionType = { SET_LOGS: 'SET_LOGS', SET_LOGS_MESSAGE: 'SET_LOGS_MESSAGE', SET_GRAPH_INSTANCE: 'SET_GRAPH_INSTANCE', + TOGGLE_DARK_MODE: 'TOGGLE_DARK_MODE', }; export default zealit(actionType); diff --git a/src/reducer/initialState.js b/src/reducer/initialState.js index b1432b5..f607e2a 100644 --- a/src/reducer/initialState.js +++ b/src/reducer/initialState.js @@ -1,7 +1,7 @@ const initialState = { ModelOpen: false, modalPayload: { - cb: () => {}, + cb: () => { }, title: '', submitText: '', Children: '', @@ -38,6 +38,7 @@ const initialState = { octave: false, logs: false, logsmessage: '', + darkMode: false, }; const initialGraphState = { diff --git a/src/reducer/reducer.js b/src/reducer/reducer.js index dd3139f..948d347 100644 --- a/src/reducer/reducer.js +++ b/src/reducer/reducer.js @@ -251,6 +251,10 @@ const reducer = (state, action) => { return { ...newState }; } + case T.TOGGLE_DARK_MODE: { + return { ...state, darkMode: !state.darkMode }; + } + default: return state; } From a43387d4726f0d6d92928d231e58214696c47dba Mon Sep 17 00:00:00 2001 From: GREENRAT-K405 Date: Wed, 21 Jan 2026 02:27:56 +0530 Subject: [PATCH 2/5] complete DARK MODE --- src/component/Header.jsx | 7 +++-- src/component/header.css | 5 +++ src/component/modals/FileEdit.jsx | 2 +- src/component/modals/contributeDetails.css | 35 +++++++++++++++------ src/component/modals/graph-comp-details.css | 4 +++ src/component/modals/nodeDetails.css | 17 ++++++++++ src/component/modals/optionsModal.css | 19 +++++++++++ src/component/modals/parent-modal.css | 29 ++++++++++++++--- 8 files changed, 101 insertions(+), 17 deletions(-) diff --git a/src/component/Header.jsx b/src/component/Header.jsx index 5b51e9e..65648be 100644 --- a/src/component/Header.jsx +++ b/src/component/Header.jsx @@ -52,7 +52,8 @@ const Header = ({ superState, dispatcher }) => { onClick={() => dispatcher({ type: T.TOGGLE_DARK_MODE })} style={{ cursor: 'pointer', - padding: '0 15px', + border: '1px solid #ccc', + padding: '0 8px', display: 'flex', alignItems: 'center', justifyContent: 'center', @@ -65,7 +66,9 @@ const Header = ({ superState, dispatcher }) => { onKeyDown={(e) => e.key === 'Enter' && dispatcher({ type: T.TOGGLE_DARK_MODE })} aria-label="Toggle dark mode" > - {superState.darkMode ? : } + {superState.darkMode + ? + : }
diff --git a/src/component/header.css b/src/component/header.css index 065ef24..947c48e 100644 --- a/src/component/header.css +++ b/src/component/header.css @@ -144,4 +144,9 @@ [data-theme='dark'] .rc-switch-checked { border: 1px solid #2B8CF7; background-color: #2B8CF7; +} + +/* Theme Icon Color */ +.theme-icon { + color: black; } \ No newline at end of file diff --git a/src/component/modals/FileEdit.jsx b/src/component/modals/FileEdit.jsx index c93859f..4789297 100644 --- a/src/component/modals/FileEdit.jsx +++ b/src/component/modals/FileEdit.jsx @@ -116,7 +116,7 @@ const FileEditModal = ({ superState, dispatcher }) => { setCodeStuff(value)} options={{ diff --git a/src/component/modals/contributeDetails.css b/src/component/modals/contributeDetails.css index 42b627a..ddb98ec 100644 --- a/src/component/modals/contributeDetails.css +++ b/src/component/modals/contributeDetails.css @@ -1,43 +1,58 @@ -.contribute-details{ +.contribute-details { padding: 20px; display: grid; grid-template-columns: auto auto; gap: 20px; } -.contribute-details *{ +.contribute-details * { padding: 10px 5px; text-align: center; } -.contribute-details .expand{ +.contribute-details .expand { grid-column: 1 / span 2; padding: 0; } -.contribute-details .btn{ +.contribute-details .btn { width: 100%; } -.contribute-details .btn-secondary{ + +.contribute-details .btn-secondary { align-self: flex-end; } -.contribute-details textarea{ + +.contribute-details textarea { resize: vertical; max-height: 200px; max-width: 300px; text-align: left; max-lines: 10; } + .Toastify__toast-container { /* width: 350px; */ /* height: 80px; */ padding: 3px 15px; display: inline-block; - } - - .Toastify__toast { +} + +.Toastify__toast { /* width: 350px; */ /* height: 80px; */ width: fit-content; font-size: 16px; - } \ No newline at end of file +} + +/* DARK MODE STYLES */ +[data-theme='dark'] .contribute-details input, +[data-theme='dark'] .contribute-details textarea { + background-color: #1a1a1a; + border: 1px solid #444; + color: #e5e7eb; +} + +[data-theme='dark'] .contribute-details span { + color: #e5e7eb; +} \ No newline at end of file diff --git a/src/component/modals/graph-comp-details.css b/src/component/modals/graph-comp-details.css index 240fdc7..4d37983 100644 --- a/src/component/modals/graph-comp-details.css +++ b/src/component/modals/graph-comp-details.css @@ -18,4 +18,8 @@ color: #f00; font-family: monospaceoo; padding-bottom: 20px; +} + +[data-theme='dark'] .ReactModalPortal .modal-footer { + border-top: 1px solid #333; } \ No newline at end of file diff --git a/src/component/modals/nodeDetails.css b/src/component/modals/nodeDetails.css index e61517f..f6a5a83 100644 --- a/src/component/modals/nodeDetails.css +++ b/src/component/modals/nodeDetails.css @@ -106,10 +106,27 @@ grid-template-columns: auto auto; width: auto } + .nodeform .nodeLabel { grid-column: 2 / span 1; } + .nodeform .nodeLabelFile { grid-column: 2 / span 1; } +} + +/* DARK MODE STYLES */ +[data-theme='dark'] .parent-div { + background: #1a1a1a; +} + +[data-theme='dark'] .nodeform input { + background-color: #1a1a1a; + border: 1px solid #444; + color: #e5e7eb; +} + +[data-theme='dark'] .nodeform div { + color: #e5e7eb; } \ No newline at end of file diff --git a/src/component/modals/optionsModal.css b/src/component/modals/optionsModal.css index 9f1d56b..4c8a892 100644 --- a/src/component/modals/optionsModal.css +++ b/src/component/modals/optionsModal.css @@ -1,6 +1,25 @@ .main-div { padding: 30px; } + .main-div-comp { margin: 20px; +} + +/* DARK MODE STYLES */ +[data-theme='dark'] .main-div input[type="text"], +[data-theme='dark'] .main-div textarea { + background-color: #1a1a1a; + border: 1px solid #444; + color: #e5e7eb; + padding: 5px; +} + +[data-theme='dark'] .main-div input[type="checkbox"] { + accent-color: #3b82f6; +} + +[data-theme='dark'] .main-div label, +[data-theme='dark'] .main-div span { + color: #e5e7eb; } \ No newline at end of file diff --git a/src/component/modals/parent-modal.css b/src/component/modals/parent-modal.css index 39d876f..c19bf8f 100644 --- a/src/component/modals/parent-modal.css +++ b/src/component/modals/parent-modal.css @@ -2,7 +2,8 @@ transition: all 200ms ease-out; } -.ReactModalPortal, .ReactModal__Overlay { +.ReactModalPortal, +.ReactModal__Overlay { z-index: 3 } @@ -43,8 +44,8 @@ line-height: 1.5; } -.modal-body{ - max-height: calc( 80vh - 70px); +.modal-body { + max-height: calc(80vh - 70px); overflow: auto; } @@ -114,7 +115,8 @@ .ReactModalPortal .Overlay.closing { opacity: 0; } -.ReactModal__Overlay.ReactModal__Overlay--after-open.Overlay{ + +.ReactModal__Overlay.ReactModal__Overlay--after-open.Overlay { overflow: auto; } @@ -128,4 +130,23 @@ .ReactModalPortal .Modal { min-width: 90%; } +} + +/* DARK MODE STYLES */ +[data-theme='dark'] .ReactModalPortal .modal-content { + background-color: #262626; + border: 1px solid #444; + color: #e5e7eb; +} + +[data-theme='dark'] .ReactModalPortal .modal-header { + border-bottom: 1px solid #333; +} + +[data-theme='dark'] .ReactModalPortal .modal-header .close { + color: #e5e7eb; +} + +[data-theme='dark'] .ReactModalPortal .modal-title { + color: #e5e7eb; } \ No newline at end of file From 0eb0bf961267ac16d7604999cebd2153439fe392 Mon Sep 17 00:00:00 2001 From: GREENRAT-K405 Date: Wed, 21 Jan 2026 13:10:24 +0530 Subject: [PATCH 3/5] update edges dark mode --- src/component/fileBrowser.css | 563 +++++++++++---------------- src/component/modals/edgeDetails.css | 87 ++++- src/component/modals/file-edit.css | 28 +- 3 files changed, 324 insertions(+), 354 deletions(-) diff --git a/src/component/fileBrowser.css b/src/component/fileBrowser.css index acf67ae..5cf30c1 100644 --- a/src/component/fileBrowser.css +++ b/src/component/fileBrowser.css @@ -1,445 +1,328 @@ /* Same file as react-file-browser.css in node modules but with few modifications */ -.inputButton { - font-size: large; - text-align: center; - color: #fff; - padding-top: 10px; - padding-bottom: 10px; - width: 100%; - border: 2px solid white; - background-color: #1e88e5; - font-weight: bold; - display: block; +.inputButton{ + font-size: large; + text-align: center; + color: #fff; + padding-top: 10px; + padding-bottom: 10px; + width: 100%; + border: 2px solid white; + background-color: #1e88e5; + font-weight: bold; + display: block; } div.rendered-react-keyed-file-browser div.action-bar { - margin-bottom: 0.5rem; - flex-wrap: wrap; - display: flex; - align-items: flex-start; -} - -div.rendered-react-keyed-file-browser div.action-bar input[type="search"] { + margin-bottom: 0.5rem; + flex-wrap: wrap; + display: flex; + align-items: flex-start; } + div.rendered-react-keyed-file-browser div.action-bar input[type="search"] { display: block; flex-grow: 2; min-width: 300px; padding: 0.25rem 0.5rem; line-height: 1em; margin-bottom: 0.5rem; - border: 0.1rem solid #ddd; -} - -div.rendered-react-keyed-file-browser div.action-bar .item-actions { + border: 0.1rem solid #ddd; } + div.rendered-react-keyed-file-browser div.action-bar .item-actions { text-align: right; margin: 0; - padding: 0; -} - -div.rendered-react-keyed-file-browser div.action-bar ul.item-actions { + padding: 0; } + div.rendered-react-keyed-file-browser div.action-bar ul.item-actions { display: block; flex-grow: 1; min-width: 300px; margin-left: 10px; - white-space: nowrap; -} - -div.rendered-react-keyed-file-browser div.action-bar ul.item-actions li { - display: inline-block; - margin: 0; -} - -div.rendered-react-keyed-file-browser div.action-bar ul.item-actions li:not(:last-child) { - margin-right: 0.5rem; -} + white-space: nowrap; } + div.rendered-react-keyed-file-browser div.action-bar ul.item-actions li { + display: inline-block; + margin: 0; } + div.rendered-react-keyed-file-browser div.action-bar ul.item-actions li:not(:last-child) { + margin-right: 0.5rem; } div.rendered-react-keyed-file-browser div.files { - /* overflow: auto; */ - width: 30vw; + /* overflow: auto; */ + width: 30vw; } div.rendered-react-keyed-file-browser div.files table { - width: 100%; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -div.rendered-react-keyed-file-browser div.files table th, -div.rendered-react-keyed-file-browser div.files table td { + width: 100%; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + div.rendered-react-keyed-file-browser div.files table th, div.rendered-react-keyed-file-browser div.files table td { font-weight: normal; text-align: left; margin: 0; - padding: 0.25rem; -} - -div.rendered-react-keyed-file-browser div.files table th { - font-weight: bold; - width: 1px; - white-space: nowrap; -} - -div.rendered-react-keyed-file-browser div.files table td { - width: 1px; - white-space: nowrap; -} - -div.rendered-react-keyed-file-browser div.files table th.size, -div.rendered-react-keyed-file-browser div.files table th.modified, -div.rendered-react-keyed-file-browser div.files table td.size, -div.rendered-react-keyed-file-browser div.files table td.modified { - text-align: right; -} - -div.rendered-react-keyed-file-browser div.files table th.name i, -div.rendered-react-keyed-file-browser div.files table td.name i { - padding-right: 0.5rem; -} - -div.rendered-react-keyed-file-browser div.files table thead th { - border-bottom: 0.1rem solid #ddd; -} - -div.rendered-react-keyed-file-browser div.files table tr:not(:last-child) td { - border-bottom: 0.1rem solid #eee; -} - -div.rendered-react-keyed-file-browser div.files table td.name { - padding-left: 0.8rem; -} - -div.rendered-react-keyed-file-browser div.files table td.name form.renaming { - display: flex; - align-items: center; -} - -div.rendered-react-keyed-file-browser div.files table td.name form.renaming i { - flex-grow: 0; - flex-shrink: 0; -} - -div.rendered-react-keyed-file-browser div.files table td.name form.renaming input[type="text"] { - flex: 1; -} - -div.rendered-react-keyed-file-browser div.files table tr td { - cursor: pointer; -} - -div.rendered-react-keyed-file-browser div.files table tr.selected td { + padding: 0.25rem; } + div.rendered-react-keyed-file-browser div.files table th { font-weight: bold; -} - -div.rendered-react-keyed-file-browser div.files table tr.selected td input, -div.rendered-react-keyed-file-browser div.files table tr.selected td button { - font-weight: normal; -} - -div.rendered-react-keyed-file-browser div.files table tr.selected td.name { - position: relative; -} - -div.rendered-react-keyed-file-browser div.files table tr.selected td.name:after { - content: ' '; - position: absolute; - left: 0; - top: 0; - width: 0.3rem; - height: 100%; - background: #1d4567; -} - -div.rendered-react-keyed-file-browser div.files table tr.dragover td, -div.rendered-react-keyed-file-browser div.files table tr.dragover th { - background: #eee; -} - -div.rendered-file-browser div.files li.file.pending, -div.rendered-file-browser div.files li.file.dragging, -div.rendered-file-browser div.files li.folder.pending, -div.rendered-file-browser div.files li.folder.dragging { - opacity: 0.4; -} - -div.rendered-file-browser div.files li.file.dragover, -div.rendered-file-browser div.files li.folder.dragover { - background: #eee; -} - -div.rendered-file-browser div.files li.file.selected>div.item, -div.rendered-file-browser div.files li.folder.selected>div.item { - color: #fff; - background: #ccc; -} - -div.rendered-file-browser div.files li.file.selected>div.item .text-muted, -div.rendered-file-browser div.files li.folder.selected>div.item .text-muted { - color: #e6e6e6; -} - -div.rendered-file-browser div.files li.file.selected>div.item a:not(.btn), -div.rendered-file-browser div.files li.file.selected>div.item.folder a:not(.btn), -div.rendered-file-browser div.files li.file.selected>div.item i, -div.rendered-file-browser div.files li.folder.selected>div.item a:not(.btn), -div.rendered-file-browser div.files li.folder.selected>div.item.folder a:not(.btn), -div.rendered-file-browser div.files li.folder.selected>div.item i { - color: #fff; -} + width:1px; + white-space:nowrap; } + div.rendered-react-keyed-file-browser div.files table td { + width:1px; + white-space:nowrap; } + div.rendered-react-keyed-file-browser div.files table th.size, div.rendered-react-keyed-file-browser div.files table th.modified, div.rendered-react-keyed-file-browser div.files table td.size, div.rendered-react-keyed-file-browser div.files table td.modified { + text-align: right; } + div.rendered-react-keyed-file-browser div.files table th.name i, div.rendered-react-keyed-file-browser div.files table td.name i { + padding-right: 0.5rem; } + div.rendered-react-keyed-file-browser div.files table thead th { + border-bottom: 0.1rem solid #ddd; } + div.rendered-react-keyed-file-browser div.files table tr:not(:last-child) td { + border-bottom: 0.1rem solid #eee; } + div.rendered-react-keyed-file-browser div.files table td.name { + padding-left: 0.8rem; } + div.rendered-react-keyed-file-browser div.files table td.name form.renaming { + display: flex; + align-items: center; } + div.rendered-react-keyed-file-browser div.files table td.name form.renaming i { + flex-grow: 0; + flex-shrink: 0; } + div.rendered-react-keyed-file-browser div.files table td.name form.renaming input[type="text"] { + flex: 1; } + div.rendered-react-keyed-file-browser div.files table tr td { + cursor: pointer; } + div.rendered-react-keyed-file-browser div.files table tr.selected td { + font-weight: bold; } + div.rendered-react-keyed-file-browser div.files table tr.selected td input, div.rendered-react-keyed-file-browser div.files table tr.selected td button { + font-weight: normal; } + div.rendered-react-keyed-file-browser div.files table tr.selected td.name { + position: relative; } + div.rendered-react-keyed-file-browser div.files table tr.selected td.name:after { + content: ' '; + position: absolute; + left: 0; + top: 0; + width: 0.3rem; + height: 100%; + background: #1d4567; } + div.rendered-react-keyed-file-browser div.files table tr.dragover td, div.rendered-react-keyed-file-browser div.files table tr.dragover th { + background: #eee; } + +div.rendered-file-browser div.files li.file.pending, div.rendered-file-browser div.files li.file.dragging, div.rendered-file-browser div.files li.folder.pending, div.rendered-file-browser div.files li.folder.dragging { + opacity: 0.4; } + +div.rendered-file-browser div.files li.file.dragover, div.rendered-file-browser div.files li.folder.dragover { + background: #eee; } + +div.rendered-file-browser div.files li.file.selected > div.item, div.rendered-file-browser div.files li.folder.selected > div.item { + color: #fff; + background: #ccc; } + div.rendered-file-browser div.files li.file.selected > div.item .text-muted, div.rendered-file-browser div.files li.folder.selected > div.item .text-muted { + color: #e6e6e6; } + div.rendered-file-browser div.files li.file.selected > div.item a:not(.btn), div.rendered-file-browser div.files li.file.selected > div.item.folder a:not(.btn), div.rendered-file-browser div.files li.file.selected > div.item i, div.rendered-file-browser div.files li.folder.selected > div.item a:not(.btn), div.rendered-file-browser div.files li.folder.selected > div.item.folder a:not(.btn), div.rendered-file-browser div.files li.folder.selected > div.item i { + color: #fff; } div.rendered-file-browser div.files ul { - list-style: none; - padding: 0; - display: grid; - gap: 4px; - grid-template-columns: repeat(3, 1fr); -} - -div.rendered-file-browser div.files ul li.folder { - grid-column: 1/4; -} - -div.rendered-file-browser div.files ul li.folder>div.item { - display: flex; - flex-direction: row; - align-items: center; - padding-left: 4px; - border: 1px solid #eee; -} - -div.rendered-file-browser div.files ul li.folder>div.item span.name { - flex: 1; - line-height: folder-size; -} - -div.rendered-file-browser div.files ul li.folder>div.item span.thumb { - flex-basis: 45px; - border: none; - text-align: center; -} - -div.rendered-file-browser div.files ul li.folder>div.item span.thumb>i { - line-height: 45px; - font-size: 18px; -} - -div.rendered-file-browser div.files ul li.folder>div.item form.renaming { - margin-top: 8px; - margin-right: 8px; -} - -div.rendered-file-browser div.files ul li.folder>p { - margin: 8px; - margin-bottom: 0; - padding: 0; -} - -div.rendered-file-browser div.files ul li.folder.expanded { - padding-bottom: 8px; - border-bottom: 1px solid #eee; - border-left: 4px solid #eee; - border-right: 1px solid #eee; -} - -div.rendered-file-browser div.files ul li.folder.expanded>div.item { - padding-left: 0px; - margin-right: -1px; - margin-left: -1px; -} - -div.rendered-file-browser div.files ul li.folder.expanded.selected { - border-bottom: 1px solid #ccc; - border-left: 4px solid #ccc; - border-right: 1px solid #ccc; -} - -div.rendered-file-browser div.files ul li.selected.folder>div.item { - border: 1px solid #bfbfbf; -} - -div.rendered-file-browser div.files ul li.selected.folder>div.item span.thumb { - border: none; -} - -div.rendered-file-browser div.files ul li.file { + list-style: none; + padding: 0; + display: grid; + gap: 4px; + grid-template-columns: repeat(3, 1fr); } + div.rendered-file-browser div.files ul li.folder { + grid-column: 1/4; } + div.rendered-file-browser div.files ul li.folder > div.item { + display: flex; + flex-direction: row; + align-items: center; + padding-left: 4px; + border: 1px solid #eee; } + div.rendered-file-browser div.files ul li.folder > div.item span.name { + flex: 1; + line-height: folder-size; } + div.rendered-file-browser div.files ul li.folder > div.item span.thumb { + flex-basis: 45px; + border: none; + text-align: center; } + div.rendered-file-browser div.files ul li.folder > div.item span.thumb > i { + line-height: 45px; + font-size: 18px; } + div.rendered-file-browser div.files ul li.folder > div.item form.renaming { + margin-top: 8px; + margin-right: 8px; } + div.rendered-file-browser div.files ul li.folder > p { + margin: 8px; + margin-bottom: 0; + padding: 0; } + div.rendered-file-browser div.files ul li.folder.expanded { + padding-bottom: 8px; + border-bottom: 1px solid #eee; + border-left: 4px solid #eee; + border-right: 1px solid #eee; } + div.rendered-file-browser div.files ul li.folder.expanded > div.item { + padding-left: 0px; + margin-right: -1px; + margin-left: -1px; } + div.rendered-file-browser div.files ul li.folder.expanded.selected { + border-bottom: 1px solid #ccc; + border-left: 4px solid #ccc; + border-right: 1px solid #ccc; } + div.rendered-file-browser div.files ul li.selected.folder > div.item { + border: 1px solid #bfbfbf; } + div.rendered-file-browser div.files ul li.selected.folder > div.item span.thumb { + border: none; } + div.rendered-file-browser div.files ul li.file { margin: 4px; - padding: 0; -} - -div.rendered-file-browser div.files ul li.file>div.item { - display: flex; - flex-direction: column; - padding: 4px; - margin: 0; -} - -div.rendered-file-browser div.files ul li.file>div.item span.thumb { - flex-basis: 120px; - text-align: center; - position: relative; - border: 1px solid #eee; - margin-bottom: 10px; -} - -div.rendered-file-browser div.files ul li.file>div.item span.thumb>i { - font-size: 40px; - line-height: 120px; -} - -div.rendered-file-browser div.files ul li.file>div.item span.thumb div.image { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-size: cover; - background-position: 50% 50%; - background-repeat: no-repeat; -} - -div.rendered-file-browser div.files ul li.selected.file>div.item span.thumb { - border: 1px solid #bfbfbf; -} - -div.rendered-file-browser div.files ul li.selected.file>div.item span.thumb div.image { - opacity: 0.8; -} - -div.rendered-file-browser p.loading, -div.rendered-file-browser p.empty { - margin: 16px 0; -} - -/* ============================================ - DARK MODE - LEFT SIDEBAR / FILE BROWSER - ============================================ */ + padding: 0; } + div.rendered-file-browser div.files ul li.file > div.item { + display: flex; + flex-direction: column; + padding: 4px; + margin: 0; } + div.rendered-file-browser div.files ul li.file > div.item span.thumb { + flex-basis: 120px; + text-align: center; + position: relative; + border: 1px solid #eee; + margin-bottom: 10px; } + div.rendered-file-browser div.files ul li.file > div.item span.thumb > i { + font-size: 40px; + line-height: 120px; } + div.rendered-file-browser div.files ul li.file > div.item span.thumb div.image { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-size: cover; + background-position: 50% 50%; + background-repeat: no-repeat; } + div.rendered-file-browser div.files ul li.selected.file > div.item span.thumb { + border: 1px solid #bfbfbf; } + div.rendered-file-browser div.files ul li.selected.file > div.item span.thumb div.image { + opacity: 0.8; } + +div.rendered-file-browser p.loading, div.rendered-file-browser p.empty { + margin: 16px 0; } + +/* DARK MODE - LEFT SIDEBAR / FILE BROWSER*/ [data-theme='dark'] { - /* Main sidebar background */ - background: #181818; + /* Main sidebar background */ + background: #181818; } /* Upload Directory Button */ [data-theme='dark'] .inputButton { - background-color: #2B8CF7; - /* Accent Blue */ - color: #FFFFFF; - border: 1px solid #2B8CF7; + background-color: #2B8CF7; /* Accent Blue */ + color: #FFFFFF; + border: 1px solid #2B8CF7; } [data-theme='dark'] .inputButton:hover { - background-color: #1e88e5; - /* Slightly darker/different blue on hover */ + background-color: #1e88e5; } /* Section Header (h4 - Folder Name) */ [data-theme='dark'] h4 { - background-color: #202020; - color: #EAEAEA; - padding: 10px; - margin: 0; - border-bottom: 1px solid #2C2C2C; + background-color: #202020; + color: #EAEAEA; + padding: 10px; + margin: 0; + border-bottom: 1px solid #2C2C2C; } /* Filter Input Field */ [data-theme='dark'] div.rendered-react-keyed-file-browser div.action-bar input[type="search"] { - background: #242424; - border: 1px solid #333333; - color: #FFFFFF; + background: #242424; + border: 1px solid #333333; + color: #FFFFFF; } [data-theme='dark'] div.rendered-react-keyed-file-browser div.action-bar input[type="search"]::placeholder { - color: #888888; + color: #888888; } /* File Browser Container */ [data-theme='dark'] div.rendered-react-keyed-file-browser div.files { - background: #181818; - color: #EAEAEA; + background: #181818; + color: #EAEAEA; } /* Table Column Headers */ [data-theme='dark'] div.rendered-react-keyed-file-browser div.files table thead th { - color: #9AA0A6; - border-bottom: 1px solid #2C2C2C; - background: #181818; + color: #9AA0A6; + border-bottom: 1px solid #2C2C2C; + background: #181818; } /* Table Rows */ [data-theme='dark'] div.rendered-react-keyed-file-browser div.files table tr td { - color: #EAEAEA; - border-bottom: 1px solid #202020; + color: #EAEAEA; + border-bottom: 1px solid #202020; } /* Table Row Hover */ [data-theme='dark'] div.rendered-react-keyed-file-browser div.files table tr:hover td { - background: #252525; + background: #252525; } /* Selected Row */ [data-theme='dark'] div.rendered-react-keyed-file-browser div.files table tr.selected td { - background: #2A2A2A; - color: #FFFFFF; + background: #2A2A2A; + color: #FFFFFF; } [data-theme='dark'] div.rendered-react-keyed-file-browser div.files table tr.selected td.name:after { - background: #2B8CF7; - /* Accent blue for selection indicator */ + background: #2B8CF7; /* Accent blue for selection indicator */ } /* Dragover State */ [data-theme='dark'] div.rendered-react-keyed-file-browser div.files table tr.dragover td, [data-theme='dark'] div.rendered-react-keyed-file-browser div.files table tr.dragover th { - background: #2A2A2A; + background: #2A2A2A; } /* Empty State ("No files.") */ [data-theme='dark'] div.rendered-file-browser p.empty { - color: #6F6F6F; + color: #6F6F6F; } [data-theme='dark'] div.rendered-file-browser p.loading { - color: #9AA0A6; + color: #9AA0A6; } /* Folder/File Items in List View */ -[data-theme='dark'] div.rendered-file-browser div.files ul li.folder>div.item { - border: 1px solid #2C2C2C; - background: #181818; +[data-theme='dark'] div.rendered-file-browser div.files ul li.folder > div.item { + border: 1px solid #2C2C2C; + background: #181818; } -[data-theme='dark'] div.rendered-file-browser div.files ul li.folder>div.item:hover { - background: #252525; +[data-theme='dark'] div.rendered-file-browser div.files ul li.folder > div.item:hover { + background: #252525; } -[data-theme='dark'] div.rendered-file-browser div.files li.file.selected>div.item, -[data-theme='dark'] div.rendered-file-browser div.files li.folder.selected>div.item { - background: #2A2A2A; - color: #FFFFFF; - border: 1px solid #2B8CF7; +[data-theme='dark'] div.rendered-file-browser div.files li.file.selected > div.item, +[data-theme='dark'] div.rendered-file-browser div.files li.folder.selected > div.item { + background: #2A2A2A; + color: #FFFFFF; + border: 1px solid #2B8CF7; } -[data-theme='dark'] div.rendered-file-browser div.files ul li.file>div.item span.thumb { - border: 1px solid #2C2C2C; - background: #202020; +[data-theme='dark'] div.rendered-file-browser div.files ul li.file > div.item span.thumb { + border: 1px solid #2C2C2C; + background: #202020; } [data-theme='dark'] div.rendered-file-browser div.files li.file.dragover, [data-theme='dark'] div.rendered-file-browser div.files li.folder.dragover { - background: #2A2A2A; + background: #2A2A2A; } /* Expanded Folder Borders */ [data-theme='dark'] div.rendered-file-browser div.files ul li.folder.expanded { - border-bottom: 1px solid #2C2C2C; - border-left: 4px solid #2C2C2C; - border-right: 1px solid #2C2C2C; + border-bottom: 1px solid #2C2C2C; + border-left: 4px solid #2C2C2C; + border-right: 1px solid #2C2C2C; } [data-theme='dark'] div.rendered-file-browser div.files ul li.folder.expanded.selected { - border-bottom: 1px solid #2B8CF7; - border-left: 4px solid #2B8CF7; - border-right: 1px solid #2B8CF7; + border-bottom: 1px solid #2B8CF7; + border-left: 4px solid #2B8CF7; + border-right: 1px solid #2B8CF7; } \ No newline at end of file diff --git a/src/component/modals/edgeDetails.css b/src/component/modals/edgeDetails.css index b46b7b3..61f0e97 100644 --- a/src/component/modals/edgeDetails.css +++ b/src/component/modals/edgeDetails.css @@ -2,7 +2,7 @@ text-align: center; } -.par-div{ +.par-div { height: 1px; min-height: 100px; width: auto; @@ -13,7 +13,7 @@ padding: 20px; } -.edge-div{ +.edge-div { border: none; width: 240px; height: 0; @@ -41,12 +41,12 @@ padding: 20px; } -.span-rest{ +.span-rest { grid-column: 2 / span 3; } -.edgeform .color-box{ +.edgeform .color-box { width: 36px; height: 14px; border-radius: 2px; @@ -54,7 +54,7 @@ border: 1px solid gray } -.color-box-par{ +.color-box-par { padding: 5px; background: rgba(0, 0, 0, 0.384); border-radius: 1px; @@ -64,13 +64,15 @@ width: fit-content; border: 1px solid gray } -.color-picker{ + +.color-picker { display: inline-block; margin: 13px 0px; position: absolute; background: transparent; } -.color-picker .overlay{ + +.color-picker .overlay { top: 0; bottom: 0; left: 0; @@ -82,22 +84,85 @@ } -.edgeform .label{ +.edgeform .label { position: absolute; margin-top: 30px; } -.hascheckbox{ +.hascheckbox { display: flex; -justify-content: space-between; + justify-content: space-between; } @media screen and (max-width: 650px) { - .edgeform .form { + .edgeform .form { grid-template-columns: auto auto; width: auto } + .edgeform .span-rest { grid-column: 2; } +} + +/* DARK MODE - EDGE DETAILS MODAL */ + +[data-theme='dark'] .edgeform { + color: #EAEAEA; +} + +/* Edge preview container */ +[data-theme='dark'] .par-div { + background: #202020; + border: 1px solid #2C2C2C; +} + +/* Edge label text */ +[data-theme='dark'] .edgeform .label { + color: #FFFFFF; +} + +/* Input field */ +[data-theme='dark'] .edgeform input[type="text"] { + background: #242424; + border: 1px solid #333333; + color: #FFFFFF; +} + +[data-theme='dark'] .edgeform input[type="text"]::placeholder { + color: #888888; +} + +[data-theme='dark'] .edgeform input[type="text"]:focus { + border-color: #2B8CF7; + outline: none; +} + +/* Number inputs */ +[data-theme='dark'] .edgeform input[type="number"] { + background: #242424; + border: 1px solid #333333; + color: #FFFFFF; +} + +[data-theme='dark'] .edgeform input[type="number"]:focus { + border-color: #2B8CF7; + outline: none; +} + +/* Form container */ +[data-theme='dark'] .edgeform .form { + background: transparent; + color: #EAEAEA; +} + +/* Color box container */ +[data-theme='dark'] .color-box-par { + background: #2A2A2A; + border: 1px solid #333333; + box-shadow: rgb(255 255 255 / 5%) 0px 0px 0px 1px; +} + +[data-theme='dark'] .edgeform .color-box { + border: 1px solid #333333; } \ No newline at end of file diff --git a/src/component/modals/file-edit.css b/src/component/modals/file-edit.css index 0a79641..cde2f53 100644 --- a/src/component/modals/file-edit.css +++ b/src/component/modals/file-edit.css @@ -1,4 +1,4 @@ -.setting-container{ +.setting-container { display: grid; grid-template-columns: auto auto; grid-gap: 0px; @@ -7,7 +7,7 @@ min-height: '400px', } -.save-bar{ +.save-bar { display: flex; flex-wrap: wrap; justify-content: flex-end; @@ -20,7 +20,29 @@ } @media screen and (max-width: 890px) { - .setting-container{ + .setting-container { grid-template-columns: auto; } } + +/* DARK MODE - FILE EDIT MODAL */ + +[data-theme='dark'] .save-bar .btn { + background: #2A2A2A; + border: 1px solid #333333; + color: #FFFFFF; +} + +[data-theme='dark'] .save-bar .btn:hover { + background: #333333; + border-color: #2B8CF7; +} + +[data-theme='dark'] .save-bar .btn-primary { + background: #2B8CF7; + border-color: #2B8CF7; +} + +[data-theme='dark'] .save-bar .btn-primary:hover { + background: #1e88e5; +} \ No newline at end of file From 7a87a02ebd2cb0ea0fc46f065c3c6efcaac6bd46 Mon Sep 17 00:00:00 2001 From: GREENRAT-K405 Date: Wed, 21 Jan 2026 21:05:46 +0530 Subject: [PATCH 4/5] update darkmode: removed unnecessary comments --- src/App.css | 76 +++++++++++----------- src/component/modals/contributeDetails.css | 14 ++-- src/component/modals/edgeDetails.css | 21 +++--- src/component/modals/file-edit.css | 6 +- src/component/modals/nodeDetails.css | 2 - src/component/modals/optionsModal.css | 1 - src/component/modals/parent-modal.css | 8 +-- src/component/tabBar.css | 7 +- src/component/zoomSetter.css | 12 ++-- src/graph-builder/graph-core/1-core.js | 15 ++--- src/graphWorkspace.css | 7 +- src/reducer/initialState.js | 2 +- 12 files changed, 75 insertions(+), 96 deletions(-) diff --git a/src/App.css b/src/App.css index a1723cf..2917c18 100644 --- a/src/App.css +++ b/src/App.css @@ -48,7 +48,7 @@ } * { - font-family: 'Helvetica', 'Arial', sans-serif; + font-family: 'Helvetica', 'Arial', sans-serif } input { @@ -56,23 +56,23 @@ input { } .container { - height: 100vh; - display: flex; - width: 100vw; - flex-direction: column; + height: 100vh; + display: flex; + width: 100vw; + flex-direction: column; } .body { - background-color: var(--bg-primary); - height: -webkit-fill-available; - flex: 1; + background-color: var(--bg-primary); + height: -webkit-fill-available; + flex: 1; } .graph { - padding: 50px; - background-color: var(--bg-primary); - height: -webkit-fill-available; - flex: 80; + padding: 50px; + background-color: var(--bg-primary); + height: -webkit-fill-available; + flex: 80; } .graph-container { @@ -80,25 +80,25 @@ input { } .middle { - display: flex; - justify-content: center; - align-items: center; + display: flex; + justify-content: center; + align-items: center; } .btn { - display: inline-block; - font-weight: 400; - color: var(--text-primary); - text-align: center; - vertical-align: middle; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; - background-color: transparent; - border: 1px solid var(--border-transparent); - padding: .375rem .75rem; - line-height: 1.5; - border-radius: .25rem; + display: inline-block; + font-weight: 400; + color: var(--text-primary); + text-align: center; + vertical-align: middle; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + background-color: transparent; + border: 1px solid var(--border-transparent); + padding: .375rem .75rem; + line-height: 1.5; + border-radius: .25rem; } .btn-primary { @@ -114,23 +114,23 @@ input { } .btn:not(:disabled):not(.disabled) { - cursor: pointer; + cursor: pointer; } @media screen and (max-width: 1000px) { - .graph { - padding: 40px; - } + .graph { + padding: 40px; + } } @media screen and (max-width: 650px) { - .graph { - padding: 35px; - } + .graph { + padding: 35px; + } } @media screen and (max-width: 500px) { - .graph { - padding: 20px; - } + .graph { + padding: 20px; + } } \ No newline at end of file diff --git a/src/component/modals/contributeDetails.css b/src/component/modals/contributeDetails.css index ddb98ec..ddca03a 100644 --- a/src/component/modals/contributeDetails.css +++ b/src/component/modals/contributeDetails.css @@ -1,36 +1,34 @@ -.contribute-details { +.contribute-details{ padding: 20px; display: grid; grid-template-columns: auto auto; gap: 20px; } -.contribute-details * { +.contribute-details *{ padding: 10px 5px; text-align: center; } -.contribute-details .expand { +.contribute-details .expand{ grid-column: 1 / span 2; padding: 0; } -.contribute-details .btn { +.contribute-details .btn{ width: 100%; } -.contribute-details .btn-secondary { +.contribute-details .btn-secondary{ align-self: flex-end; } - -.contribute-details textarea { +.contribute-details textarea{ resize: vertical; max-height: 200px; max-width: 300px; text-align: left; max-lines: 10; } - .Toastify__toast-container { /* width: 350px; */ /* height: 80px; */ diff --git a/src/component/modals/edgeDetails.css b/src/component/modals/edgeDetails.css index 61f0e97..6728f57 100644 --- a/src/component/modals/edgeDetails.css +++ b/src/component/modals/edgeDetails.css @@ -2,7 +2,7 @@ text-align: center; } -.par-div { +.par-div{ height: 1px; min-height: 100px; width: auto; @@ -13,7 +13,7 @@ padding: 20px; } -.edge-div { +.edge-div{ border: none; width: 240px; height: 0; @@ -41,12 +41,12 @@ padding: 20px; } -.span-rest { +.span-rest{ grid-column: 2 / span 3; } -.edgeform .color-box { +.edgeform .color-box{ width: 36px; height: 14px; border-radius: 2px; @@ -54,7 +54,7 @@ border: 1px solid gray } -.color-box-par { +.color-box-par{ padding: 5px; background: rgba(0, 0, 0, 0.384); border-radius: 1px; @@ -65,7 +65,7 @@ border: 1px solid gray } -.color-picker { +.color-picker{ display: inline-block; margin: 13px 0px; position: absolute; @@ -84,22 +84,21 @@ } -.edgeform .label { +.edgeform .label{ position: absolute; margin-top: 30px; } -.hascheckbox { +.hascheckbox{ display: flex; - justify-content: space-between; +justify-content: space-between; } @media screen and (max-width: 650px) { - .edgeform .form { + .edgeform .form { grid-template-columns: auto auto; width: auto } - .edgeform .span-rest { grid-column: 2; } diff --git a/src/component/modals/file-edit.css b/src/component/modals/file-edit.css index cde2f53..08b3ca3 100644 --- a/src/component/modals/file-edit.css +++ b/src/component/modals/file-edit.css @@ -1,4 +1,4 @@ -.setting-container { +.setting-container{ display: grid; grid-template-columns: auto auto; grid-gap: 0px; @@ -7,7 +7,7 @@ min-height: '400px', } -.save-bar { +.save-bar{ display: flex; flex-wrap: wrap; justify-content: flex-end; @@ -20,7 +20,7 @@ } @media screen and (max-width: 890px) { - .setting-container { + .setting-container{ grid-template-columns: auto; } } diff --git a/src/component/modals/nodeDetails.css b/src/component/modals/nodeDetails.css index f6a5a83..1377bf5 100644 --- a/src/component/modals/nodeDetails.css +++ b/src/component/modals/nodeDetails.css @@ -106,11 +106,9 @@ grid-template-columns: auto auto; width: auto } - .nodeform .nodeLabel { grid-column: 2 / span 1; } - .nodeform .nodeLabelFile { grid-column: 2 / span 1; } diff --git a/src/component/modals/optionsModal.css b/src/component/modals/optionsModal.css index 4c8a892..5747e09 100644 --- a/src/component/modals/optionsModal.css +++ b/src/component/modals/optionsModal.css @@ -1,7 +1,6 @@ .main-div { padding: 30px; } - .main-div-comp { margin: 20px; } diff --git a/src/component/modals/parent-modal.css b/src/component/modals/parent-modal.css index c19bf8f..220f3ae 100644 --- a/src/component/modals/parent-modal.css +++ b/src/component/modals/parent-modal.css @@ -2,8 +2,7 @@ transition: all 200ms ease-out; } -.ReactModalPortal, -.ReactModal__Overlay { +.ReactModalPortal, .ReactModal__Overlay { z-index: 3 } @@ -44,7 +43,7 @@ line-height: 1.5; } -.modal-body { +.modal-body{ max-height: calc(80vh - 70px); overflow: auto; } @@ -115,8 +114,7 @@ .ReactModalPortal .Overlay.closing { opacity: 0; } - -.ReactModal__Overlay.ReactModal__Overlay--after-open.Overlay { +.ReactModal__Overlay.ReactModal__Overlay--after-open.Overlay{ overflow: auto; } diff --git a/src/component/tabBar.css b/src/component/tabBar.css index 4090751..33e1187 100644 --- a/src/component/tabBar.css +++ b/src/component/tabBar.css @@ -2,8 +2,7 @@ display: flex; overflow: auto; margin-bottom: -1px; - width: 100%; - ; + width: 100%;; } .tab { @@ -60,9 +59,7 @@ text-shadow: 0px 0px 10px #000; } -/* ============================================ - DARK MODE - NODE / FLOW TAB BAR - ============================================ */ +/* DARK MODE - NODE / FLOW TAB BAR */ /* Tab Bar Container */ [data-theme='dark'] .tab-par { diff --git a/src/component/zoomSetter.css b/src/component/zoomSetter.css index 62a2dbc..ace4adb 100644 --- a/src/component/zoomSetter.css +++ b/src/component/zoomSetter.css @@ -12,8 +12,7 @@ border-bottom: none; border-top-left-radius: 3px; } - -.zoom-comp>* { +.zoom-comp > *{ padding: 2px 5px; } @@ -32,11 +31,10 @@ user-select: none; } -.zoom-comp .zoom-btn { +.zoom-comp .zoom-btn{ cursor: pointer; } - -.zoom-comp .zoom-btn:hover { +.zoom-comp .zoom-btn:hover{ background: #eee; } @@ -44,9 +42,7 @@ width: 40px; } -/* ============================================ - DARK MODE - ZOOM CONTROLS - ============================================ */ +/* DARK MODE - ZOOM CONTROLS*/ /* Container */ [data-theme='dark'] .zoom-comp { diff --git a/src/graph-builder/graph-core/1-core.js b/src/graph-builder/graph-core/1-core.js index 2acf1d8..1ec5f94 100644 --- a/src/graph-builder/graph-core/1-core.js +++ b/src/graph-builder/graph-core/1-core.js @@ -24,7 +24,7 @@ class CoreGraph { bendNode; - darkMode = false; // Current theme state + darkMode = false; gridSize = 20; // Configurable grid size in pixels @@ -34,7 +34,7 @@ class CoreGraph { ) { if (dispatcher) this.dispatcher = dispatcher; if (superState) this.superState = superState; - this.darkMode = darkMode; // Store dark mode state + this.darkMode = darkMode; if (typeof cytoscape('core', 'edgehandles') !== 'function') { cytoscape.use(edgehandles); } @@ -351,20 +351,19 @@ class CoreGraph { } updateTheme(darkMode) { - this.darkMode = darkMode; // Update stored dark mode state + this.darkMode = darkMode; const newStyle = getCytoscapeStyle(darkMode); this.cy.style(newStyle); // Update grid colors for dark mode const gridColors = darkMode ? { - gridColor: '#606060', // Major grid lines - Light Grey - lineColor: 'rgba(96, 96, 96, 0.4)', // Minor grid lines - Light Grey (transparent) + gridColor: '#606060', + lineColor: 'rgba(96, 96, 96, 0.4)', } : { - gridColor: 'rgba(0, 0, 0, 0.2)', // Light mode major grid - lineColor: 'rgba(0, 0, 0, 0.1)', // Light mode minor grid + gridColor: 'rgba(0, 0, 0, 0.2)', + lineColor: 'rgba(0, 0, 0, 0.1)', }; - // Update grid guide with new colors if (this.cy.gridGuide) { this.cy.gridGuide({ gridColor: gridColors.gridColor, diff --git a/src/graphWorkspace.css b/src/graphWorkspace.css index 60efe95..addfc8d 100644 --- a/src/graphWorkspace.css +++ b/src/graphWorkspace.css @@ -3,18 +3,13 @@ border: 1px solid #888; } -/* ============================================ - DARK MODE - CANVAS / EDITOR AREA - ============================================ */ +/* DARK MODE - CANVAS / EDITOR AREA */ [data-theme='dark'] .graph-container { background-color: #262626; - /* Slightly Darker Grey */ border: 1px solid #2C2C2C; - /* Subtle border */ } -/* Cytoscape canvas background */ [data-theme='dark'] .graph-element { background-color: #262626 !important; } \ No newline at end of file diff --git a/src/reducer/initialState.js b/src/reducer/initialState.js index f607e2a..4fb1993 100644 --- a/src/reducer/initialState.js +++ b/src/reducer/initialState.js @@ -1,7 +1,7 @@ const initialState = { ModelOpen: false, modalPayload: { - cb: () => { }, + cb: () => {}, title: '', submitText: '', Children: '', From b215d7cb1a4e3b93c21646bd07f649cb8d7aca5a Mon Sep 17 00:00:00 2001 From: GREENRAT-K405 Date: Wed, 21 Jan 2026 22:46:14 +0530 Subject: [PATCH 5/5] complete dark mode UI --- src/component/Header.jsx | 7 ++- src/component/modals/project-details.css | 54 ++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/component/Header.jsx b/src/component/Header.jsx index 65648be..971e874 100644 --- a/src/component/Header.jsx +++ b/src/component/Header.jsx @@ -1,7 +1,7 @@ /* eslint-disable react/jsx-props-no-spreading */ import React from 'react'; import hotkeys from 'hotkeys-js'; -import { FaMoon, FaSun } from 'react-icons/fa'; +import { FaMoon } from 'react-icons/fa'; import toolbarList from '../toolbarActions/toolbarList'; import { actionType as T } from '../reducer'; import '@szhsin/react-menu/dist/index.css'; @@ -58,6 +58,7 @@ const Header = ({ superState, dispatcher }) => { alignItems: 'center', justifyContent: 'center', transition: 'opacity 0.2s', + backgroundColor: '#eee', }} onMouseEnter={(e) => { e.currentTarget.style.opacity = '0.7'; }} onMouseLeave={(e) => { e.currentTarget.style.opacity = '1'; }} @@ -66,9 +67,7 @@ const Header = ({ superState, dispatcher }) => { onKeyDown={(e) => e.key === 'Enter' && dispatcher({ type: T.TOGGLE_DARK_MODE })} aria-label="Toggle dark mode" > - {superState.darkMode - ? - : } +
diff --git a/src/component/modals/project-details.css b/src/component/modals/project-details.css index 6c2996c..c201e8f 100644 --- a/src/component/modals/project-details.css +++ b/src/component/modals/project-details.css @@ -28,4 +28,58 @@ .proj-details .serverIDText{ width: calc( 100% - 20px); margin-bottom: 20px; +} + +/* DARK MODE */ + +[data-theme='dark'] .proj-details { + color: #EAEAEA; +} + +[data-theme='dark'] .proj-details input { + background: #242424; + border: 1px solid #333333; + color: #FFFFFF; +} + +[data-theme='dark'] .proj-details input::placeholder { + color: #888888; +} + +[data-theme='dark'] .proj-details input:focus { + border-color: #FFFFFF; + outline: none; +} + +[data-theme='dark'] .proj-details .btn { + background: #2A2A2A; + border: 1px solid #333333; + color: #FFFFFF; +} + +[data-theme='dark'] .proj-details .btn:hover { + background: #333333; + border-color: #2B8CF7; +} + +[data-theme='dark'] .proj-details .btn-primary { + background: #2B8CF7; + border-color: #2B8CF7; +} + +[data-theme='dark'] .proj-details .btn-primary:hover { + background: #1e88e5; +} + +[data-theme='dark'] .proj-details .btn-secondary { + background: #2A2A2A; + border: 1px solid #333333; +} + +[data-theme='dark'] .proj-details .btn-secondary:hover { + background: #333333; +} + +[data-theme='dark'] .proj-details .divider { + border-bottom: 1px solid #333333; } \ No newline at end of file