diff --git a/app/static/css/style.css b/app/static/css/style.css index 4a5b2d5..df604a3 100644 --- a/app/static/css/style.css +++ b/app/static/css/style.css @@ -1,10 +1,5 @@ /* mc-webui Custom Styles */ - -:root { - --msg-own-bg: #e7f1ff; - --msg-other-bg: #f8f9fa; - --msg-border: #dee2e6; -} +/* Colors are defined as CSS custom properties in theme.css */ /* Page Layout */ html, body { @@ -17,6 +12,8 @@ html, body { body { display: flex; flex-direction: column; + background-color: var(--bg-body); + color: var(--text-primary); } main { @@ -35,8 +32,8 @@ main { display: none; width: 250px; flex-shrink: 0; - border-right: 1px solid #dee2e6; - background: #f8f9fa; + border-right: 1px solid var(--border-color); + background: var(--bg-surface); flex-direction: column; } @@ -44,9 +41,9 @@ main { padding: 0.6rem 0.75rem; font-weight: 600; font-size: 0.85rem; - border-bottom: 1px solid #dee2e6; - color: #495057; - background: #f0f0f0; + border-bottom: 1px solid var(--border-color); + color: var(--text-secondary); + background: var(--bg-surface-alt); } .channel-sidebar-list { @@ -60,22 +57,22 @@ main { display: flex; align-items: center; gap: 0.5rem; - border-bottom: 1px solid #f0f0f0; + border-bottom: 1px solid var(--border-light); font-size: 0.85rem; transition: background-color 0.15s; - color: #212529; + color: var(--text-primary); } .channel-sidebar-item:hover { - background-color: #e9ecef; + background-color: var(--bg-hover); } .channel-sidebar-item.active { - background-color: #e7f1ff; - border-left: 3px solid #0d6efd; + background-color: var(--bg-active); + border-left: 3px solid var(--sender-color); padding-left: calc(0.75rem - 3px); font-weight: 500; - color: #0d6efd; + color: var(--sender-color); } .channel-sidebar-item.muted { @@ -90,7 +87,7 @@ main { } .channel-sidebar-item .sidebar-unread-badge { - background-color: #0d6efd; + background-color: var(--sender-color); color: white; border-radius: 10px; padding: 1px 6px; @@ -119,15 +116,15 @@ main { display: none; width: 280px; flex-shrink: 0; - border-right: 1px solid #dee2e6; - background: #f8f9fa; + border-right: 1px solid var(--border-color); + background: var(--bg-surface); flex-direction: column; } .dm-sidebar-header { padding: 0.5rem; - border-bottom: 1px solid #dee2e6; - background: #f0f0f0; + border-bottom: 1px solid var(--border-color); + background: var(--bg-surface-alt); } .dm-sidebar-list { @@ -138,8 +135,8 @@ main { .dm-sidebar-separator { padding: 0.25rem 0.75rem; font-size: 0.7rem; - color: #6c757d; - background: #f0f0f0; + color: var(--text-muted); + background: var(--bg-surface-alt); font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; @@ -151,13 +148,13 @@ main { display: flex; align-items: center; gap: 0.5rem; - border-bottom: 1px solid #f0f0f0; + border-bottom: 1px solid var(--border-light); font-size: 0.85rem; transition: background-color 0.15s; } .dm-sidebar-item:hover { - background-color: #e9ecef; + background-color: var(--bg-hover); } .dm-sidebar-item.active { @@ -167,6 +164,11 @@ main { font-weight: 500; } +[data-theme="dark"] .dm-sidebar-item.active { + background-color: rgba(16, 185, 129, 0.15); + border-left-color: #10b981; +} + .dm-sidebar-item .contact-name { flex: 1; overflow: hidden; @@ -177,7 +179,7 @@ main { .dm-sidebar-item .sidebar-unread-dot { width: 8px; height: 8px; - background-color: #0d6efd; + background-color: var(--sender-color); border-radius: 50%; flex-shrink: 0; } @@ -206,7 +208,7 @@ main { /* Messages Container */ .messages-container { - background-color: #ffffff; + background-color: var(--bg-messages); padding-left: 0.25rem !important; padding-right: 0.25rem !important; } @@ -282,12 +284,12 @@ main { .message-sender { font-weight: 600; font-size: 0.875rem; - color: #0d6efd; + color: var(--sender-color); } .message-sender-row .message-time { font-size: 0.7rem; - color: #6c757d; + color: var(--text-muted); } /* Message footer for own messages (name + time above bubble) */ @@ -304,13 +306,13 @@ main { .message-footer .message-time { font-size: 0.7rem; - color: #6c757d; + color: var(--text-muted); } .message-footer .message-sender.own { font-weight: 600; font-size: 0.875rem; - color: #084298; + color: var(--sender-own-color); margin-right: 0.5rem; } @@ -320,7 +322,7 @@ main { gap: 0.25rem; margin-top: 0.5rem; padding-top: 0.5rem; - border-top: 1px solid rgba(0, 0, 0, 0.1); + border-top: 1px solid var(--actions-border); } /* Message Bubbles */ @@ -339,7 +341,7 @@ main { /* Own Messages (right-aligned) */ .message.own { background-color: var(--msg-own-bg); - border-color: #b8daff; + border-color: var(--msg-own-border); } /* Other Messages (left-aligned) */ @@ -349,7 +351,7 @@ main { .message-time { font-size: 0.75rem; - color: #6c757d; + color: var(--text-muted); } /* Message Content */ @@ -362,7 +364,7 @@ main { /* Message Metadata */ .message-meta { font-size: 0.7rem; - color: #adb5bd; + color: var(--text-meta); margin-top: 0.25rem; } @@ -404,16 +406,16 @@ main { } .messages-container::-webkit-scrollbar-track { - background: #f1f1f1; + background: var(--scrollbar-track); } .messages-container::-webkit-scrollbar-thumb { - background: #888; + background: var(--scrollbar-thumb); border-radius: 4px; } .messages-container::-webkit-scrollbar-thumb:hover { - background: #555; + background: var(--scrollbar-thumb-hover); } /* Channel selector and date selector - larger font size */ @@ -447,16 +449,16 @@ main { .offcanvas-body .list-group-item { padding: 1rem 0.75rem; border: none; - border-bottom: 1px solid #dee2e6; + border-bottom: 1px solid var(--offcanvas-item-border); font-size: 1rem; } .offcanvas-body .list-group-item:hover { - background-color: #f8f9fa; + background-color: var(--offcanvas-item-hover); } .offcanvas-body .list-group-item i { - color: #0d6efd; + color: var(--offcanvas-icon-color); min-width: 1.5rem; } @@ -577,7 +579,7 @@ main { .empty-state { text-align: center; padding: 3rem 1rem; - color: #6c757d; + color: var(--text-muted); } .empty-state i { @@ -663,7 +665,7 @@ main { display: flex; flex-direction: column; gap: 0.5rem; - background-color: #fafafa; + background-color: var(--bg-dm-messages); } /* DM Messages List (flex container for message alignment) */ @@ -691,7 +693,7 @@ main { .dm-message.own { align-self: flex-end; background-color: var(--msg-own-bg); - border: 1px solid #b8daff; + border: 1px solid var(--msg-own-border); } .dm-message.other { @@ -703,7 +705,7 @@ main { /* DM Message Metadata */ .dm-meta { font-size: 0.65rem; - color: #adb5bd; + color: var(--text-meta); margin-top: 0.25rem; } @@ -726,7 +728,7 @@ main { } .dm-status.unknown { - color: #adb5bd; + color: var(--text-meta); } .dm-status-unknown { @@ -765,17 +767,17 @@ main { /* DM Conversation List Item */ .dm-conversation-item { padding: 0.75rem; - border-bottom: 1px solid #dee2e6; + border-bottom: 1px solid var(--conversation-border); cursor: pointer; transition: background-color 0.15s ease; } .dm-conversation-item:hover { - background-color: #f8f9fa; + background-color: var(--conversation-hover); } .dm-conversation-item.unread { - background-color: #e7f1ff; + background-color: var(--conversation-unread); } .dm-conversation-item:last-child { @@ -785,7 +787,7 @@ main { /* DM Preview Text */ .dm-preview { font-size: 0.85rem; - color: #6c757d; + color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -798,7 +800,7 @@ main { .dm-empty-state { text-align: center; padding: 2rem 1rem; - color: #6c757d; + color: var(--text-muted); } .dm-empty-state i { @@ -813,16 +815,16 @@ main { } .dm-messages-container::-webkit-scrollbar-track { - background: #f1f1f1; + background: var(--scrollbar-track); } .dm-messages-container::-webkit-scrollbar-thumb { - background: #ccc; + background: var(--scrollbar-thumb-light); border-radius: 3px; } .dm-messages-container::-webkit-scrollbar-thumb:hover { - background: #aaa; + background: var(--scrollbar-thumb-light-hover); } /* ============================================================================= @@ -832,7 +834,7 @@ main { /* Mention Badge (similar to Android Meshcore app) */ .mention-badge { display: inline-block; - background-color: #0d6efd; + background-color: var(--mention-bg); color: white; padding: 0.15rem 0.5rem; border-radius: 0.75rem; @@ -843,13 +845,13 @@ main { } .message.own .mention-badge { - background-color: #084298; + background-color: var(--mention-own-bg); } /* Channel Links (#channelname) */ .channel-link { display: inline-block; - background-color: #198754; + background-color: var(--channel-link-bg); color: white; padding: 0.15rem 0.5rem; border-radius: 0.75rem; @@ -863,17 +865,17 @@ main { } .channel-link:hover { - background-color: #157347; + background-color: var(--channel-link-hover); color: white; text-decoration: none; } .message.own .channel-link { - background-color: #0f5132; + background-color: var(--channel-link-own-bg); } .message.own .channel-link:hover { - background-color: #0d4429; + background-color: var(--channel-link-own-hover); } .channel-link.loading { @@ -885,20 +887,20 @@ main { content: '...'; } -/* Quoted Text (»text«) */ +/* Quoted Text */ .quote-text { font-style: italic; - color: #6c757d; - background-color: rgba(108, 117, 125, 0.1); + color: var(--quote-color); + background-color: var(--quote-bg); padding: 0.1rem 0.3rem; border-radius: 0.25rem; - border-left: 2px solid #6c757d; + border-left: 2px solid var(--quote-border); } .message.own .quote-text { - color: #495057; - background-color: rgba(8, 66, 152, 0.1); - border-left-color: #084298; + color: var(--quote-own-color); + background-color: var(--quote-own-bg); + border-left-color: var(--quote-own-border); } /* Large Emoji for emoji-only messages */ @@ -909,22 +911,22 @@ main { /* Clickable Links in Messages */ .message-link { - color: #0d6efd; + color: var(--link-color); text-decoration: underline; word-break: break-all; } .message-link:hover { - color: #0a58ca; + color: var(--link-hover); text-decoration: underline; } .message.own .message-link { - color: #084298; + color: var(--link-own-color); } .message.own .message-link:hover { - color: #052c65; + color: var(--link-own-hover); } /* Image Thumbnails in Messages */ @@ -941,7 +943,7 @@ main { border-radius: 0.5rem; cursor: pointer; transition: transform 0.2s ease, box-shadow 0.2s ease; - border: 1px solid #dee2e6; + border: 1px solid var(--image-border); } .message-image-thumbnail:hover { @@ -977,7 +979,7 @@ main { } /* ============================================================================= - TEST: Floating Action Buttons (FAB) + Floating Action Buttons (FAB) ============================================================================= */ .fab-container { @@ -1001,13 +1003,13 @@ main { justify-content: center; font-size: 1.5rem; cursor: pointer; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); + box-shadow: var(--fab-shadow); transition: transform 0.2s ease, box-shadow 0.2s ease; } .fab:hover { transform: scale(1.1); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.4); + box-shadow: var(--fab-shadow-hover); } .fab:active { @@ -1045,12 +1047,12 @@ main { /* FAB Badge for Pending Contacts (red for consistency and contrast) */ .fab-badge-pending { - background-color: #dc3545; /* Bootstrap danger red - same as notification bell */ + background-color: #dc3545; } /* FAB Badge for Direct Messages (red for consistency and contrast) */ .fab-badge-dm { - background-color: #dc3545; /* Bootstrap danger red - same as notification bell */ + background-color: #dc3545; } /* Animation on hover */ @@ -1194,7 +1196,7 @@ main { .map-filter-badge[data-type="1"] { color: #2196F3; - background-color: white; + background-color: var(--map-badge-inactive-bg); border: 2px solid #2196F3; } .map-filter-badge[data-type="1"].active { @@ -1204,7 +1206,7 @@ main { .map-filter-badge[data-type="2"] { color: #4CAF50; - background-color: white; + background-color: var(--map-badge-inactive-bg); border: 2px solid #4CAF50; } .map-filter-badge[data-type="2"].active { @@ -1214,7 +1216,7 @@ main { .map-filter-badge[data-type="3"] { color: #9C27B0; - background-color: white; + background-color: var(--map-badge-inactive-bg); border: 2px solid #9C27B0; } .map-filter-badge[data-type="3"].active { @@ -1224,7 +1226,7 @@ main { .map-filter-badge[data-type="4"] { color: #FF9800; - background-color: white; + background-color: var(--map-badge-inactive-bg); border: 2px solid #FF9800; } .map-filter-badge[data-type="4"].active { @@ -1245,10 +1247,10 @@ main { max-height: 200px; width: 280px; overflow-y: auto; - background-color: white; - border: 1px solid #dee2e6; + background-color: var(--popup-bg); + border: 1px solid var(--border-color); border-radius: 0.5rem; - box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + box-shadow: var(--popup-shadow); } .mentions-popup.hidden { @@ -1264,7 +1266,7 @@ main { .mention-item { padding: 0.5rem 0.75rem; cursor: pointer; - border-bottom: 1px solid #f0f0f0; + border-bottom: 1px solid var(--mention-item-border); font-size: 0.9rem; transition: background-color 0.1s ease; } @@ -1275,7 +1277,7 @@ main { .mention-item:hover, .mention-item.highlighted { - background-color: #e7f1ff; + background-color: var(--mention-item-highlight); } .mention-item-name { @@ -1285,7 +1287,7 @@ main { .mentions-empty { padding: 0.75rem; text-align: center; - color: #6c757d; + color: var(--text-muted); font-size: 0.85rem; } @@ -1305,16 +1307,16 @@ main { } .mentions-popup::-webkit-scrollbar-track { - background: #f1f1f1; + background: var(--scrollbar-track); } .mentions-popup::-webkit-scrollbar-thumb { - background: #ccc; + background: var(--scrollbar-thumb-light); border-radius: 3px; } .mentions-popup::-webkit-scrollbar-thumb:hover { - background: #aaa; + background: var(--scrollbar-thumb-light-hover); } /* ============================================================================= @@ -1365,23 +1367,17 @@ main { align-items: center; gap: 0.25rem; font-size: 0.7rem; - color: #198754; + color: var(--echo-color); padding: 0.2rem 0.4rem; margin-right: 0.25rem; border-radius: 0.25rem; - background-color: rgba(25, 135, 84, 0.1); + background-color: var(--echo-bg); } .echo-badge i { font-size: 0.65rem; } -/* Dark mode support */ -[data-bs-theme="dark"] .echo-badge { - color: #75b798; - background-color: rgba(117, 183, 152, 0.15); -} - /* Path info in message meta (incoming messages) */ .path-info { cursor: pointer; @@ -1447,8 +1443,8 @@ main { left: 0; right: 0; z-index: 1002; /* Above mentions popup (1001) */ - background-color: #ffffff; - border-bottom: 1px solid #dee2e6; + background-color: var(--filter-bg); + border-bottom: 1px solid var(--border-color); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); padding: 0.75rem; transform: translateY(-100%); @@ -1469,7 +1465,7 @@ main { } .filter-bar.visible ~ .messages-container { - padding-top: calc(1rem + 52px) !important; /* 52px ≈ filter bar height (0.75rem*2 padding + 36px input + border) */ + padding-top: calc(1rem + 52px) !important; /* 52px ~ filter bar height */ } /* Filter bar inner layout */ @@ -1481,9 +1477,11 @@ main { .filter-bar-input { border-radius: 0.375rem; - border: 1px solid #ced4da; + border: 1px solid var(--filter-input-border); padding: 0.5rem 0.75rem; font-size: 0.9rem; + background-color: var(--bg-body); + color: var(--text-primary); } .filter-bar-input:focus { @@ -1492,6 +1490,11 @@ main { box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25); } +[data-theme="dark"] .filter-bar-input:focus { + border-color: #3b82f6; + box-shadow: 0 0 0 0.2rem rgba(59, 130, 246, 0.25); +} + /* Filter bar buttons */ .filter-bar-btn { width: 36px; @@ -1507,21 +1510,21 @@ main { } .filter-bar-btn-me { - background-color: #e7f1ff; - color: #0d6efd; + background-color: var(--filter-btn-me-bg); + color: var(--filter-btn-me-color); } .filter-bar-btn-me:hover { - background-color: #cfe2ff; + background-color: var(--filter-btn-me-hover); } .filter-bar-btn-clear { - background-color: #f8f9fa; - color: #6c757d; + background-color: var(--filter-btn-clear-bg); + color: var(--filter-btn-clear-color); } .filter-bar-btn-clear:hover { - background-color: #e9ecef; + background-color: var(--filter-btn-clear-hover); } .filter-bar-btn-close { @@ -1536,14 +1539,14 @@ main { /* Filter match count indicator */ .filter-match-count { font-size: 0.75rem; - color: #6c757d; + color: var(--text-muted); white-space: nowrap; padding: 0 0.5rem; } /* Highlighted text in filtered messages */ .filter-highlight { - background-color: #fff3cd; + background-color: var(--filter-highlight); border-radius: 0.2rem; padding: 0 0.1rem; } @@ -1558,7 +1561,7 @@ main { .filter-no-matches { text-align: center; padding: 2rem; - color: #6c757d; + color: var(--text-muted); } .filter-no-matches i { @@ -1621,7 +1624,7 @@ main { } #searchResults mark { - background-color: #fff3cd; + background-color: var(--search-mark-bg); padding: 0 2px; border-radius: 2px; } @@ -1631,3 +1634,416 @@ main { background: transparent; border: none; } + +/* ============================================================================= + Emoji Picker (shared between index.html and dm.html) + ============================================================================= */ + +emoji-picker { + --emoji-size: 1.5rem; + --num-columns: 8; +} + +.emoji-picker-container { + position: relative; +} + +.emoji-picker-popup { + position: absolute; + bottom: 100%; + right: 0; + z-index: 1000; + margin-bottom: 0.5rem; + box-shadow: var(--popup-shadow); + border-radius: 0.5rem; + overflow: hidden; +} + +.emoji-picker-popup.hidden { + display: none; +} + +/* Mobile responsive adjustments */ +@media (max-width: 576px) { + emoji-picker { + --emoji-size: 1.25rem; + --num-columns: 6; + } + .emoji-picker-popup { + right: auto; + left: 0; + width: 100%; + max-width: 100%; + } +} + +/* Modal fullscreen - remove all margins and padding */ +#dmModal .modal-dialog.modal-fullscreen, +#contactsModal .modal-dialog.modal-fullscreen, +#logsModal .modal-dialog.modal-fullscreen, +#consoleModal .modal-dialog.modal-fullscreen { + margin: 0 !important; + width: 100vw !important; + max-width: 100vw !important; + height: 100vh !important; + max-height: 100vh !important; +} + +#dmModal .modal-content, +#contactsModal .modal-content, +#logsModal .modal-content, +#consoleModal .modal-content { + border: none !important; + border-radius: 0 !important; + height: 100vh !important; +} + +#dmModal .modal-body, +#contactsModal .modal-body, +#logsModal .modal-body, +#consoleModal .modal-body { + overflow: hidden !important; +} + +/* ============================================================================= + Contact Management Styles (shared between contacts.html and contacts_base.html) + ============================================================================= */ + +.compact-setting { + display: flex; + align-items: center; + gap: 0.75rem; + padding: 0.75rem; + background-color: var(--bg-surface); + border-radius: 0.5rem; + margin-bottom: 1rem; +} + +.info-icon { + color: var(--text-muted); + cursor: help; + font-size: 1.1rem; +} + +.info-icon:hover { + color: var(--sender-color); +} + +.pending-contact-card { + background-color: var(--card-bg); + border: 1px solid var(--border-color); + border-radius: 0.5rem; + padding: 1rem; + margin-bottom: 0.75rem; + box-shadow: var(--card-shadow); +} + +.contact-name { + font-size: 1.1rem; + font-weight: 600; + color: var(--text-primary); + margin-bottom: 0.1rem; + word-wrap: break-word; +} + +.contact-key { + font-family: 'Courier New', monospace; + font-size: 0.85rem; + color: var(--text-muted); + word-break: break-all; + margin-bottom: 0.15rem; +} + +.contact-key.clickable-key { + cursor: pointer; + transition: color 0.15s, background-color 0.15s; + padding: 0.15rem 0.3rem; + margin-left: -0.3rem; + border-radius: 0.25rem; +} + +.contact-key.clickable-key:hover { + color: var(--key-hover-color); + background-color: var(--key-hover-bg); +} + +.contact-key.clickable-key.copied { + color: var(--key-copied-color); + background-color: var(--key-copied-bg); +} + +.btn-action { + min-height: 44px; /* Touch-friendly size */ + font-size: 1rem; +} + +.info-badge { + display: inline-block; + background-color: var(--info-badge-bg); + color: var(--info-badge-color); + padding: 0.5rem 1rem; + border-radius: 0.375rem; + font-size: 0.9rem; + margin-top: 0.5rem; +} + +/* Existing Contacts Styles */ +.existing-contact-card { + background-color: var(--card-bg); + border: 1px solid var(--border-color); + border-radius: 0.5rem; + padding: 1rem; + margin-bottom: 0.75rem; + box-shadow: var(--card-shadow); + transition: box-shadow 0.2s; +} + +.existing-contact-card:hover { + box-shadow: var(--card-shadow-hover); +} + +.type-badge { + font-size: 0.75rem; + padding: 0.25rem 0.5rem; + font-weight: 600; +} + +/* ============================================================================= + DM Contact Dropdown (dm.html) + ============================================================================= */ + +.dm-contact-dropdown { + position: absolute; + top: 100%; + left: 0; + right: 0; + z-index: 1050; + max-height: 300px; + overflow-y: auto; + background: var(--dropdown-bg); + border: 1px solid var(--border-color); + border-top: none; + border-radius: 0 0 0.375rem 0.375rem; + box-shadow: var(--popup-shadow); +} + +.dm-contact-item { + padding: 0.5rem 0.75rem; + cursor: pointer; + display: flex; + align-items: center; + gap: 0.5rem; + border-bottom: 1px solid var(--border-light); +} + +.dm-contact-item:hover, +.dm-contact-item.active { + background-color: var(--dropdown-item-hover); +} + +.dm-contact-item .contact-name { + flex-grow: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.dm-contact-item .badge { + font-size: 0.7rem; +} + +.dm-dropdown-separator { + padding: 0.25rem 0.75rem; + font-size: 0.75rem; + color: var(--text-muted); + background: var(--dropdown-separator-bg); + font-weight: 600; +} + +/* ============================================================================= + Path Management (dm.html) + ============================================================================= */ + +.path-list-item { + display: flex; + align-items: center; + gap: 0.4rem; + padding: 0.35rem 0.5rem; + border: 1px solid var(--path-item-border); + border-radius: 0.25rem; + margin-bottom: 0.25rem; + font-size: 0.8rem; + background: var(--path-item-bg); +} + +.path-list-item.primary { + border-color: var(--path-item-primary-border); + background: var(--path-item-primary-bg); +} + +.path-list-item .path-hex { + font-family: monospace; + font-size: 0.75rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.path-list-item .path-label { + color: var(--text-muted); + font-size: 0.7rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.path-list-item .path-actions { + margin-left: auto; + display: flex; + gap: 0.15rem; + flex-shrink: 0; +} + +.path-list-item .path-actions .btn { + padding: 0 0.25rem; + font-size: 0.7rem; + line-height: 1.2; +} + +.path-section-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 0.5rem; +} + +.path-section-header h6 { + font-size: 0.85rem; + margin: 0; +} + +.repeater-picker-item { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.4rem 0.5rem; + cursor: pointer; + border-bottom: 1px solid var(--border-light); + font-size: 0.8rem; +} + +.repeater-picker-item:hover { + background-color: var(--bg-hover); +} + +.repeater-picker-item .badge { + font-family: monospace; + font-size: 0.7rem; +} + +.path-uniqueness-warning { + color: #dc3545; + font-size: 0.75rem; +} + +/* Leaflet z-index fix for Bootstrap modal (DM repeater map) */ +#rptLeafletMap { z-index: 1; } +#rptLeafletMap .leaflet-top, +#rptLeafletMap .leaflet-bottom { z-index: 1000; } + +/* ============================================================================= + Contact Management - Page-specific Styles (contacts.html) + ============================================================================= */ + +.contact-info-row { + display: flex; + align-items: center; + gap: 0.5rem; + margin-bottom: 0.5rem; + flex-wrap: wrap; +} + +.counter-badge { + font-size: 1rem; + padding: 0.35rem 0.75rem; +} + +.counter-ok { + background-color: #28a745; +} + +.counter-warning { + background-color: #ffc107; + color: #212529; +} + +.counter-alarm { + background-color: #dc3545; + animation: counterPulse 1.5s infinite; +} + +@keyframes counterPulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.7; } +} + +.search-toolbar { + display: flex; + gap: 0.5rem; + margin-bottom: 1rem; + flex-wrap: wrap; +} + +.search-toolbar input, +.search-toolbar select { + flex: 1; + min-width: 150px; +} + +/* Scrollable contacts lists */ +#pendingList { + max-height: 200px; + overflow-y: auto; + overflow-x: hidden; + -webkit-overflow-scrolling: touch; +} + +#existingList { + overflow-y: auto; + overflow-x: hidden; + -webkit-overflow-scrolling: touch; + max-height: calc(100vh - 400px); + min-height: 300px; +} + +@media (max-width: 768px) { + #existingList { + max-height: calc(100vh - 450px); + } +} + +#existingList::-webkit-scrollbar, +#pendingList::-webkit-scrollbar { + width: 8px; +} + +#existingList::-webkit-scrollbar-track, +#pendingList::-webkit-scrollbar-track { + background: var(--scrollbar-track); + border-radius: 4px; +} + +#existingList::-webkit-scrollbar-thumb, +#pendingList::-webkit-scrollbar-thumb { + background: var(--scrollbar-thumb); + border-radius: 4px; +} + +#existingList::-webkit-scrollbar-thumb:hover, +#pendingList::-webkit-scrollbar-thumb:hover { + background: var(--scrollbar-thumb-hover); +} + +.section-compact { + margin-bottom: 0.75rem; +} diff --git a/app/static/css/theme.css b/app/static/css/theme.css new file mode 100644 index 0000000..3f46624 --- /dev/null +++ b/app/static/css/theme.css @@ -0,0 +1,613 @@ +/* ============================================================================= + mc-webui Theme System + Defines CSS custom properties for light/dark themes. + Bootstrap 5.3 data-bs-theme handles most component styling; + these variables cover custom app-specific elements. + ============================================================================= */ + +/* ============================================================================= + Light Theme (default) + ============================================================================= */ +:root { + /* Backgrounds */ + --bg-body: #ffffff; + --bg-surface: #f8f9fa; + --bg-surface-alt: #f0f0f0; + --bg-hover: #e9ecef; + --bg-active: #e7f1ff; + --bg-messages: #ffffff; + --bg-dm-messages: #fafafa; + + /* Text */ + --text-primary: #212529; + --text-secondary: #495057; + --text-muted: #6c757d; + --text-meta: #adb5bd; + + /* Borders */ + --border-color: #dee2e6; + --border-light: #f0f0f0; + + /* Messages */ + --msg-own-bg: #e7f1ff; + --msg-other-bg: #f8f9fa; + --msg-border: #dee2e6; + --msg-own-border: #b8daff; + + /* Sender */ + --sender-color: #0d6efd; + --sender-own-color: #084298; + + /* Navbar */ + --navbar-bg: #0d6efd; + --navbar-border: transparent; + + /* Scrollbar */ + --scrollbar-track: #f1f1f1; + --scrollbar-thumb: #888; + --scrollbar-thumb-hover: #555; + --scrollbar-thumb-light: #ccc; + --scrollbar-thumb-light-hover: #aaa; + + /* Filter */ + --filter-bg: #ffffff; + --filter-highlight: #fff3cd; + --filter-input-border: #ced4da; + --filter-btn-me-bg: #e7f1ff; + --filter-btn-me-color: #0d6efd; + --filter-btn-me-hover: #cfe2ff; + --filter-btn-clear-bg: #f8f9fa; + --filter-btn-clear-color: #6c757d; + --filter-btn-clear-hover: #e9ecef; + + /* Popup / Dropdown */ + --popup-bg: #ffffff; + --popup-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + + /* Quote */ + --quote-color: #6c757d; + --quote-bg: rgba(108, 117, 125, 0.1); + --quote-border: #6c757d; + --quote-own-color: #495057; + --quote-own-bg: rgba(8, 66, 152, 0.1); + --quote-own-border: #084298; + + /* Mention badge */ + --mention-bg: #0d6efd; + --mention-own-bg: #084298; + + /* Links */ + --link-color: #0d6efd; + --link-hover: #0a58ca; + --link-own-color: #084298; + --link-own-hover: #052c65; + + /* Channel link */ + --channel-link-bg: #198754; + --channel-link-hover: #157347; + --channel-link-own-bg: #0f5132; + --channel-link-own-hover: #0d4429; + + /* Echo badge */ + --echo-color: #198754; + --echo-bg: rgba(25, 135, 84, 0.1); + + /* Search */ + --search-mark-bg: #fff3cd; + + /* Offcanvas menu */ + --offcanvas-item-border: #dee2e6; + --offcanvas-item-hover: #f8f9fa; + --offcanvas-icon-color: #0d6efd; + + /* FAB */ + --fab-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); + --fab-shadow-hover: 0 6px 12px rgba(0, 0, 0, 0.4); + + /* Conversation list */ + --conversation-border: #dee2e6; + --conversation-hover: #f8f9fa; + --conversation-unread: #e7f1ff; + + /* Map filter badges */ + --map-badge-inactive-bg: white; + + /* Mention autocomplete */ + --mention-item-highlight: #e7f1ff; + --mention-item-border: #f0f0f0; + + /* Image border */ + --image-border: #dee2e6; + + /* Actions border */ + --actions-border: rgba(0, 0, 0, 0.1); + + /* Cards */ + --card-bg: #ffffff; + --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + --card-shadow-hover: 0 2px 8px rgba(0, 0, 0, 0.15); + + /* Info badge */ + --info-badge-bg: #e7f3ff; + --info-badge-color: #0c5460; + + /* Contact key clickable */ + --key-hover-color: #0d6efd; + --key-hover-bg: #e7f1ff; + --key-copied-color: #198754; + --key-copied-bg: #d1e7dd; + + /* Path items (DM) */ + --path-item-bg: #ffffff; + --path-item-border: #dee2e6; + --path-item-primary-bg: #f0f7ff; + --path-item-primary-border: #0d6efd; + + /* DM contact dropdown */ + --dropdown-bg: #ffffff; + --dropdown-separator-bg: #f8f9fa; + --dropdown-item-hover: #e9ecef; +} + +/* ============================================================================= + Dark Theme + Inspired by mc-webui demo landing page (https://mc-webui.marwoj.net/) + Color palette: deep navy backgrounds, slate surfaces, soft blue accents + ============================================================================= */ +[data-theme="dark"] { + /* Override Bootstrap 5.3 dark mode variables for our custom palette */ + --bs-body-bg: #0f172a; + --bs-body-color: #f8fafc; + --bs-border-color: #334155; + --bs-tertiary-bg: #1e293b; + --bs-secondary-bg: #162032; + + /* Backgrounds */ + --bg-body: #0f172a; + --bg-surface: #1e293b; + --bg-surface-alt: #162032; + --bg-hover: #2d3a4e; + --bg-active: #1e3a5f; + --bg-messages: #0f172a; + --bg-dm-messages: #131c2e; + + /* Text */ + --text-primary: #f8fafc; + --text-secondary: #94a3b8; + --text-muted: #64748b; + --text-meta: #475569; + + /* Borders */ + --border-color: #334155; + --border-light: #1e293b; + + /* Messages */ + --msg-own-bg: #1e3a5f; + --msg-other-bg: #1e293b; + --msg-border: #334155; + --msg-own-border: #2563eb; + + /* Sender */ + --sender-color: #60a5fa; + --sender-own-color: #93c5fd; + + /* Navbar */ + --navbar-bg: #1e293b; + --navbar-border: #334155; + + /* Scrollbar */ + --scrollbar-track: #1e293b; + --scrollbar-thumb: #475569; + --scrollbar-thumb-hover: #64748b; + --scrollbar-thumb-light: #334155; + --scrollbar-thumb-light-hover: #475569; + + /* Filter */ + --filter-bg: #1e293b; + --filter-highlight: rgba(251, 191, 36, 0.2); + --filter-input-border: #334155; + --filter-btn-me-bg: #1e3a5f; + --filter-btn-me-color: #60a5fa; + --filter-btn-me-hover: #264a6f; + --filter-btn-clear-bg: #1e293b; + --filter-btn-clear-color: #94a3b8; + --filter-btn-clear-hover: #2d3a4e; + + /* Popup / Dropdown */ + --popup-bg: #1e293b; + --popup-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.4); + + /* Quote */ + --quote-color: #94a3b8; + --quote-bg: rgba(148, 163, 184, 0.1); + --quote-border: #64748b; + --quote-own-color: #94a3b8; + --quote-own-bg: rgba(37, 99, 235, 0.15); + --quote-own-border: #2563eb; + + /* Mention badge */ + --mention-bg: #2563eb; + --mention-own-bg: #1d4ed8; + + /* Links */ + --link-color: #60a5fa; + --link-hover: #93c5fd; + --link-own-color: #93c5fd; + --link-own-hover: #bfdbfe; + + /* Channel link */ + --channel-link-bg: #059669; + --channel-link-hover: #10b981; + --channel-link-own-bg: #047857; + --channel-link-own-hover: #059669; + + /* Echo badge */ + --echo-color: #10b981; + --echo-bg: rgba(16, 185, 129, 0.15); + + /* Search */ + --search-mark-bg: rgba(251, 191, 36, 0.3); + + /* Offcanvas menu */ + --offcanvas-item-border: #334155; + --offcanvas-item-hover: #253347; + --offcanvas-icon-color: #60a5fa; + + /* FAB */ + --fab-shadow: 0 4px 8px rgba(0, 0, 0, 0.5); + --fab-shadow-hover: 0 6px 12px rgba(0, 0, 0, 0.6); + + /* Conversation list */ + --conversation-border: #334155; + --conversation-hover: #253347; + --conversation-unread: #1e3a5f; + + /* Map filter badges */ + --map-badge-inactive-bg: #1e293b; + + /* Mention autocomplete */ + --mention-item-highlight: #1e3a5f; + --mention-item-border: #334155; + + /* Image border */ + --image-border: #334155; + + /* Actions border */ + --actions-border: rgba(255, 255, 255, 0.1); + + /* Cards */ + --card-bg: #1e293b; + --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + --card-shadow-hover: 0 2px 8px rgba(0, 0, 0, 0.4); + + /* Info badge */ + --info-badge-bg: rgba(37, 99, 235, 0.15); + --info-badge-color: #60a5fa; + + /* Contact key clickable */ + --key-hover-color: #60a5fa; + --key-hover-bg: #1e3a5f; + --key-copied-color: #10b981; + --key-copied-bg: rgba(16, 185, 129, 0.15); + + /* Path items (DM) */ + --path-item-bg: #1e293b; + --path-item-border: #334155; + --path-item-primary-bg: #1e3a5f; + --path-item-primary-border: #2563eb; + + /* DM contact dropdown */ + --dropdown-bg: #1e293b; + --dropdown-separator-bg: #162032; + --dropdown-item-hover: #2d3a4e; +} + +/* ============================================================================= + Dark Theme - Bootstrap Component Overrides + Bootstrap 5.3 data-bs-theme="dark" handles most defaults; these overrides + customize colors to match our deep navy palette. + ============================================================================= */ + +/* Navbar */ +[data-theme="dark"] .navbar.bg-primary { + background-color: var(--navbar-bg) !important; + border-bottom: 1px solid var(--navbar-border); +} + +[data-theme="dark"] .navbar .btn-outline-light { + border-color: #475569; + color: #94a3b8; +} + +[data-theme="dark"] .navbar .btn-outline-light:hover { + background-color: #334155; + border-color: #64748b; + color: #f8fafc; +} + +/* Form controls */ +[data-theme="dark"] .form-control, +[data-theme="dark"] .form-select { + background-color: var(--bg-body); + color: var(--text-primary); + border-color: var(--border-color); +} + +[data-theme="dark"] .form-control:focus, +[data-theme="dark"] .form-select:focus { + background-color: var(--bg-body); + color: var(--text-primary); + border-color: #3b82f6; + box-shadow: 0 0 0 0.2rem rgba(59, 130, 246, 0.25); +} + +[data-theme="dark"] .form-control::placeholder { + color: var(--text-muted); +} + +/* Modal */ +[data-theme="dark"] .modal-content { + background-color: var(--bg-surface); + color: var(--text-primary); + border-color: var(--border-color); +} + +[data-theme="dark"] .modal-header { + border-bottom-color: var(--border-color); +} + +[data-theme="dark"] .modal-footer { + border-top-color: var(--border-color); +} + +[data-theme="dark"] .btn-close { + filter: invert(1) grayscale(100%) brightness(200%); +} + +/* Offcanvas */ +[data-theme="dark"] .offcanvas { + background-color: var(--bg-surface); + color: var(--text-primary); +} + +[data-theme="dark"] .offcanvas-header { + border-bottom-color: var(--border-color); +} + +/* List group */ +[data-theme="dark"] .list-group-item { + background-color: transparent; + color: var(--text-primary); + border-color: var(--border-color); +} + +[data-theme="dark"] .list-group-item-action:hover { + background-color: var(--bg-hover); + color: var(--text-primary); +} + +/* Nav tabs */ +[data-theme="dark"] .nav-tabs { + border-bottom-color: var(--border-color); +} + +[data-theme="dark"] .nav-tabs .nav-link { + color: var(--text-muted); +} + +[data-theme="dark"] .nav-tabs .nav-link:hover { + border-color: var(--border-color); + color: var(--text-secondary); +} + +[data-theme="dark"] .nav-tabs .nav-link.active { + background-color: var(--bg-surface); + color: var(--text-primary); + border-color: var(--border-color) var(--border-color) var(--bg-surface); +} + +/* Tables */ +[data-theme="dark"] .table { + color: var(--text-primary); + border-color: var(--border-color); +} + +/* Alerts */ +[data-theme="dark"] .alert-info { + background-color: rgba(59, 130, 246, 0.1); + color: #60a5fa; + border-color: rgba(59, 130, 246, 0.2); +} + +[data-theme="dark"] .alert-light { + background-color: var(--bg-surface-alt); + color: var(--text-secondary); + border-color: var(--border-color); +} + +/* Card (Bootstrap) */ +[data-theme="dark"] .card { + background-color: var(--bg-surface); + border-color: var(--border-color); + color: var(--text-primary); +} + +/* Badge overrides for better dark mode contrast */ +[data-theme="dark"] .badge.bg-secondary { + background-color: #475569 !important; +} + +/* Text utilities */ +[data-theme="dark"] .text-muted { + color: var(--text-muted) !important; +} + +[data-theme="dark"] .text-dark { + color: var(--text-primary) !important; +} + +[data-theme="dark"] .border-bottom { + border-bottom-color: var(--border-color) !important; +} + +[data-theme="dark"] .border-top { + border-top-color: var(--border-color) !important; +} + +/* bg-light override */ +[data-theme="dark"] .bg-light { + background-color: var(--bg-surface-alt) !important; +} + +/* Toast */ +[data-theme="dark"] .toast { + background-color: var(--bg-surface); + color: var(--text-primary); + border-color: var(--border-color); +} + +[data-theme="dark"] .toast-header { + background-color: var(--bg-surface-alt); + color: var(--text-primary); + border-bottom-color: var(--border-color); +} + +/* Progress bar */ +[data-theme="dark"] .progress { + background-color: var(--bg-surface-alt); +} + +/* Tooltip-like popups */ +[data-theme="dark"] .dm-delivery-popup, +[data-theme="dark"] .path-popup { + background-color: #475569; + color: #f8fafc; +} + +/* Form check / switch */ +[data-theme="dark"] .form-check-input { + background-color: var(--bg-surface-alt); + border-color: var(--border-color); +} + +[data-theme="dark"] .form-check-input:checked { + background-color: #3b82f6; + border-color: #3b82f6; +} + +/* Input group */ +[data-theme="dark"] .input-group-text { + background-color: var(--bg-surface-alt); + color: var(--text-secondary); + border-color: var(--border-color); +} + +/* Accordion (if used) */ +[data-theme="dark"] .accordion-item { + background-color: var(--bg-surface); + border-color: var(--border-color); +} + +/* Dropdown menu (Bootstrap) */ +[data-theme="dark"] .dropdown-menu { + background-color: var(--bg-surface); + border-color: var(--border-color); +} + +[data-theme="dark"] .dropdown-item { + color: var(--text-primary); +} + +[data-theme="dark"] .dropdown-item:hover { + background-color: var(--bg-hover); + color: var(--text-primary); +} + +/* Spinner */ +[data-theme="dark"] .spinner-border { + color: #3b82f6; +} + +/* Status bar (bottom) */ +[data-theme="dark"] .border-top { + border-color: var(--border-color) !important; +} + +/* QR code container - keep white bg for readability */ +[data-theme="dark"] .qr-code-container, +[data-theme="dark"] #shareChannelQR, +[data-theme="dark"] #deviceShareContent .text-center img, +[data-theme="dark"] #deviceShareContent canvas { + background-color: #ffffff; + padding: 8px; + border-radius: 0.5rem; +} + +/* Emoji picker dark mode */ +[data-theme="dark"] emoji-picker { + --background: #1e293b; + --border-color: #334155; + --indicator-color: #3b82f6; + --input-border-color: #334155; + --input-font-color: #f8fafc; + --input-placeholder-color: #64748b; + --outline-color: #3b82f6; + --category-font-color: #94a3b8; + --button-active-background: #334155; + --button-hover-background: #2d3a4e; +} + +/* ============================================================================= + Theme Switcher UI + ============================================================================= */ + +.theme-option { + display: flex; + align-items: center; + gap: 0.75rem; + padding: 0.75rem 1rem; + border: 2px solid var(--border-color); + border-radius: 0.75rem; + cursor: pointer; + transition: all 0.2s ease; + background-color: var(--card-bg); +} + +.theme-option:hover { + border-color: #3b82f6; +} + +.theme-option.active { + border-color: #3b82f6; + background-color: var(--bg-active); +} + +.theme-option-preview { + width: 40px; + height: 40px; + border-radius: 0.5rem; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.25rem; +} + +.theme-option-preview.light { + background: linear-gradient(135deg, #ffffff 50%, #e9ecef 50%); + border: 1px solid #dee2e6; +} + +.theme-option-preview.dark { + background: linear-gradient(135deg, #1e293b 50%, #0f172a 50%); + border: 1px solid #334155; +} + +.theme-option-label { + font-weight: 500; +} + +.theme-option-desc { + font-size: 0.8rem; + color: var(--text-muted); +} diff --git a/app/templates/base.html b/app/templates/base.html index 6a736e2..be43ff4 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -1,5 +1,5 @@ - + @@ -12,6 +12,15 @@ + + + @@ -24,6 +33,8 @@ + + {% block extra_head %}{% endblock %} @@ -360,6 +371,9 @@ +
@@ -432,6 +446,29 @@
+
+
Theme
+
+
+
+ +
+
+
Light
+
Classic bright interface
+
+
+
+
+ +
+
+
Dark
+
Easy on the eyes, deep navy palette
+
+
+
+
@@ -656,6 +693,27 @@ } + + + {% block extra_scripts %}{% endblock %} diff --git a/app/templates/contacts.html b/app/templates/contacts.html index a90b390..6aa64f0 100644 --- a/app/templates/contacts.html +++ b/app/templates/contacts.html @@ -3,208 +3,6 @@ {% block title %}Contact Management - mc-webui{% endblock %} {% block extra_head %} - {% endblock %} {% block content %} diff --git a/app/templates/contacts_base.html b/app/templates/contacts_base.html index 52c3363..c34a22c 100644 --- a/app/templates/contacts_base.html +++ b/app/templates/contacts_base.html @@ -1,10 +1,19 @@ - + {% block title %}Contact Management - mc-webui{% endblock %} + + + @@ -24,126 +33,11 @@ + + {% block extra_head %}{% endblock %} diff --git a/app/templates/dm.html b/app/templates/dm.html index cfbd69e..6f5c8a6 100644 --- a/app/templates/dm.html +++ b/app/templates/dm.html @@ -1,10 +1,19 @@ - + Direct Messages - mc-webui + + + @@ -24,166 +33,12 @@ + + - + diff --git a/app/templates/index.html b/app/templates/index.html index 0c48912..e50dcab 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -5,70 +5,6 @@ {% block extra_head %} - {% endblock %} {% block content %}