{% extends "base.twig" %}
{% block title %}{{ t('ui.netmail.title', {}, locale, ['common']) }} - {{ parent() }}{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h2>
<i class="fas fa-envelope"></i>
{{ t('ui.netmail.title', {}, locale, ['common']) }}
</h2>
<div class="d-flex gap-2">
<button class="btn btn-fidonet" onclick="composeMessage('netmail')">
<i class="fas fa-plus"></i>
{{ t('ui.netmail.compose', {}, locale, ['common']) }}
</button>
{% if ai_assistant_enabled %}
{# <button class="btn btn-outline-secondary" onclick="openAiAssistant(typeof currentMessageId !== 'undefined' ? currentMessageId : null, 'netmail')">
<i class="fas fa-robot me-1"></i>{{ t('ui.ai_assistant.button', {}, locale, ['common']) }}
</button> #}
{% endif %}
</div>
</div>
<div class="row">
<div class="col-lg-9">
<div class="card">
<div class="card-header">
<div class="d-flex flex-column flex-sm-row justify-content-between align-items-start align-items-sm-center gap-2">
<h6 class="mb-0 d-none d-sm-block">{{ t('ui.netmail.messages', {}, locale, ['common']) }}</h6>
<div class="d-flex align-items-center gap-2">
<div id="bulkActions" class="d-none">
<button type="button" class="btn btn-outline-danger btn-sm" onclick="deleteSelectedMessages()" disabled>
<i class="fas fa-trash"></i>
{{ t('ui.netmail.delete_selected', {}, locale, ['common']) }} (<span id="selectedCount">0</span>)
</button>
</div>
<div class="d-flex gap-2 filter-controls">
<div class="btn-group btn-group-sm flex-nowrap" role="group">
<input type="radio" class="btn-check" name="filter" id="all" value="all" checked>
<label class="btn btn-outline-secondary" for="all">{{ t('ui.common.all', {}, locale, ['common']) }}</label>
<input type="radio" class="btn-check" name="filter" id="unread" value="unread">
<label class="btn btn-outline-secondary" for="unread">{{ t('ui.common.unread', {}, locale, ['common']) }}</label>
<input type="radio" class="btn-check" name="filter" id="sent" value="sent">
<label class="btn btn-outline-secondary" for="sent">{{ t('ui.common.sent', {}, locale, ['common']) }}</label>
<input type="radio" class="btn-check" name="filter" id="saved" value="saved">
<label class="btn btn-outline-secondary" for="saved">{{ t('ui.netmail.saved_items', {}, locale, ['common']) }} <span class="badge bg-secondary ms-1" id="savedFilterBadge" style="display:none;"></span></label>
<input type="radio" class="btn-check" name="filter" id="drafts" value="drafts">
<label class="btn btn-outline-secondary" for="drafts">{{ t('ui.common.drafts', {}, locale, ['common']) }}</label>
</div>
<div class="dropdown">
<button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-bs-toggle="dropdown">
<i class="fas fa-sort"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item sort-option" data-sort="date_desc" href="#" onclick="sortMessages('date_desc')">{{ t('ui.common.sort.newest_first', {}, locale, ['common']) }}</a></li>
<li><a class="dropdown-item sort-option" data-sort="date_asc" href="#" onclick="sortMessages('date_asc')">{{ t('ui.common.sort.oldest_first', {}, locale, ['common']) }}</a></li>
<li><a class="dropdown-item sort-option" data-sort="subject" href="#" onclick="sortMessages('subject')">{{ t('ui.common.sort.by_subject', {}, locale, ['common']) }}</a></li>
<li><a class="dropdown-item sort-option" data-sort="author" href="#" onclick="sortMessages('author')">{{ t('ui.common.sort.by_author', {}, locale, ['common']) }}</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#" onclick="toggleThreading()">
<i class="fas fa-project-diagram"></i>
<span id="threadingToggleText">{{ t('ui.common.threading.show_threaded', {}, locale, ['common']) }}</span>
</a></li>
</ul>
</div>
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="toggleSelectMode()" id="selectModeBtn">
<i class="fas fa-check-square"></i>
{{ t('ui.common.select', {}, locale, ['common']) }}
</button>
</div>
</div>
</div>
</div>
<div class="card-body p-0">
<div id="messagesContainer">
<div class="loading-spinner">
<i class="fas fa-spinner fa-spin me-2"></i>
{{ t('ui.common.loading_messages', {}, locale, ['common']) }}
</div>
</div>
</div>
<div class="card-footer">
<nav id="pagination">
<!-- Pagination will be inserted here -->
</nav>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="card">
<div class="card-header">
<h6 class="mb-0">{{ t('ui.common.search', {}, locale, ['common']) }}</h6>
</div>
<div class="card-body">
<div class="mb-3">
<input type="text" class="form-control" id="searchInput" placeholder="{{ t('ui.common.search_messages_placeholder', {}, locale, ['common']) }}">
</div>
<div class="d-flex gap-2">
<button class="btn btn-outline-primary btn-sm flex-fill" onclick="searchMessages()">
<i class="fas fa-search"></i>
{{ t('ui.common.search', {}, locale, ['common']) }}
</button>
<button class="btn btn-outline-secondary btn-sm" onclick="openAdvancedSearch()" title="{{ t('ui.common.advanced_search', {}, locale, ['common']) }}">
<i class="fas fa-sliders-h"></i>
</button>
</div>
</div>
</div>
<div class="card mt-3">
<div class="card-header">
<div class="d-flex justify-content-between align-items-center">
<h6 class="mb-0">{{ t('ui.address_book.title', {}, locale, ['common']) }}</h6>
<button class="btn btn-sm btn-outline-primary" onclick="showAddAddressModal()">
<i class="fas fa-plus"></i>
</button>
</div>
</div>
<div class="card-body">
<div class="mb-2">
<input type="text" class="form-control form-control-sm" id="addressBookSearch" placeholder="{{ t('ui.address_book.search_placeholder', {}, locale, ['common']) }}">
</div>
<div id="addressBookList" style="max-height: 200px; overflow-y: auto;">
<div class="text-center text-muted py-2">
<i class="fas fa-spinner fa-spin"></i> {{ t('ui.common.loading', {}, locale, ['common']) }}
</div>
</div>
<div class="mt-2">
<small class="text-muted" id="addressBookStats">0 {{ t('ui.address_book.entries', {}, locale, ['common']) }}</small>
</div>
</div>
</div>
<div class="card mt-3">
<div class="card-header">
<h6 class="mb-0">{{ t('ui.netmail.quick_stats', {}, locale, ['common']) }}</h6>
</div>
<div class="card-body">
<dl class="row mb-0">
<dt class="col-6">{{ t('ui.common.total', {}, locale, ['common']) }}:</dt>
<dd class="col-6" id="totalCount">-</dd>
<dt class="col-6">{{ t('ui.common.unread', {}, locale, ['common']) }}:</dt>
<dd class="col-6" id="unreadCount">-</dd>
<dt class="col-6">{{ t('ui.common.sent', {}, locale, ['common']) }}:</dt>
<dd class="col-6" id="sentCount">-</dd>
<dt class="col-6">{{ t('ui.netmail.saved_items', {}, locale, ['common']) }}:</dt>
<dd class="col-6" id="savedCount">-</dd>
</dl>
</div>
</div>
</div>
</div>
<div id="messageContextMenu" class="dropdown-menu" style="display:none; position:absolute; z-index:1080;">
<button type="button" class="dropdown-item" onclick="replyFromContextMenu()">
<i class="fas fa-reply me-2"></i>{{ t('ui.common.reply', {}, 'common') }}
</button>
<button type="button" class="dropdown-item" onclick="repostFromContextMenu()">
<i class="fas fa-share me-2"></i>{{ t('ui.common.repost', {}, 'common') }}
</button>
<button type="button" class="dropdown-item" onclick="viewConversationFromContextMenu()">
<i class="fas fa-comments me-2"></i>{{ t('ui.common.view_conversation', {}, locale, ['common']) }}
</button>
<button type="button" class="dropdown-item" id="messageContextMenuSave" onclick="saveFromContextMenu()">
<i class="fas fa-bookmark me-2"></i><span id="messageContextMenuSaveLabel">{{ t('ui.common.save_for_later', {}, locale, ['common']) }}</span>
</button>
<button type="button" class="dropdown-item" onclick="downloadMessageFromContextMenu()">
<i class="fas fa-download me-2"></i>{{ t('ui.common.download_message', {}, locale, ['common']) }}
</button>
{% if current_user.email %}
<button type="button" class="dropdown-item" onclick="forwardMessageToEmailFromContextMenu()">
<i class="fas fa-envelope me-2"></i>{{ t('ui.common.forward_to_me_by_email', {}, locale, ['common']) }}
</button>
{% endif %}
</div>
<!-- Message View Modal -->
<div class="modal fade" id="messageModal" tabindex="-1">
<div class="modal-dialog modal-lg modal-message-reader{% if appearance.message_reader.scrollable_body %} modal-dialog-scrollable message-reader-scrollable{% endif %}">
<div class="modal-content">
<div class="modal-header">
<div class="d-flex align-items-center gap-2">
<button type="button" class="btn btn-outline-secondary btn-sm" id="prevMessageBtn" onclick="navigateMessage(-1)" title="{{ t('ui.common.previous_message', {}, locale, ['common']) }}">
<i class="fas fa-chevron-left"></i>
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" id="nextMessageBtn" onclick="navigateMessage(1)" title="{{ t('ui.common.next_message', {}, locale, ['common']) }}">
<i class="fas fa-chevron-right"></i>
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" id="editMessageButton" onclick="openEditMessage()" title="{{ t('ui.common.edit', {}, locale, ['common']) }}">
<i class="fas fa-pencil-alt"></i>
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" id="toggleHeaders" onclick="toggleKludgeLines()" title="{{ t('ui.common.show_kludge_lines', {}, locale, ['common']) }}">
<i class="fas fa-code" id="toggleIcon"></i>
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="printMessage()" title="{{ t('ui.common.print', {}, locale, ['common']) }}">
<i class="fas fa-print"></i>
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="toggleKeyboardHelp()" title="{{ t('ui.echomail.shortcuts.title', {}, locale, ['common']) }}">
<i class="fas fa-keyboard"></i>
</button>
</div>
<h5 class="modal-title" id="messageSubject">{{ t('ui.common.message', {}, locale, ['common']) }}</h5>
<button type="button" class="btn btn-outline-secondary btn-sm me-2" id="fullscreenToggle" onclick="toggleModalFullscreen()" title="{{ t('ui.common.toggle_fullscreen', {}, locale, ['common']) }}">
<i class="fas fa-expand"></i>
</button>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div id="messageContent">
<div class="loading-spinner">
<i class="fas fa-spinner fa-spin me-2"></i>
{{ t('ui.common.loading_message', {}, locale, ['common']) }}
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger btn-compact-label" id="deleteButton">
<i class="fas fa-trash"></i>
<span class="btn-text">{{ t('ui.common.delete', {}, locale, ['common']) }}</span>
</button>
<button type="button" class="btn btn-secondary btn-compact-label" data-bs-dismiss="modal">
<i class="fas fa-times"></i>
<span class="btn-text">{{ t('ui.common.close', {}, locale, ['common']) }}</span>
</button>
<button type="button" class="btn btn-outline-warning btn-compact-label" id="modalSaveButton">
<i class="fas fa-bookmark"></i>
<span class="btn-text" id="modalSaveText">{{ t('ui.common.save', {}, locale, ['common']) }}</span>
</button>
<button type="button" class="btn btn-fidonet btn-compact-label" id="replyButton">
<i class="fas fa-reply"></i>
<span class="btn-text">{{ t('ui.common.reply', {}, locale, ['common']) }}</span>
</button>
<button type="button" class="btn btn-outline-primary btn-compact-label" id="repostButton">
<i class="fas fa-share"></i>
<span class="btn-text">{{ t('ui.common.repost', {}, locale, ['common']) }}</span>
</button>
</div>
{# Keyboard shortcuts help overlay #}
<div id="keyboardHelpOverlay" style="display:none; position:absolute; inset:0; z-index:20; background:rgba(0,0,0,0.82); padding:2rem; overflow-y:auto;">
<div class="mx-auto" style="max-width:480px;">
<h5 class="text-white mb-3"><i class="fas fa-keyboard me-2"></i>{{ t('ui.echomail.shortcuts.title', {}, locale, ['common']) }}</h5>
<table class="table table-sm table-dark table-borderless mb-3">
<tbody>
<tr>
<td class="text-center" style="width:120px;">
<kbd>←</kbd> <kbd>→</kbd>
</td>
<td>{{ t('ui.echomail.shortcuts.prev_next', {}, locale, ['common']) }}</td>
</tr>
<tr>
<td class="text-center"><kbd>A</kbd></td>
<td>{{ t('ui.echomail.shortcuts.cycle_viewer_mode', {}, locale, ['common']) }}</td>
</tr>
<tr>
<td class="text-center"><kbd>D</kbd></td>
<td>{{ t('ui.echomail.shortcuts.download', {}, locale, ['common']) }}</td>
</tr>
<tr>
<td class="text-center"><kbd>F</kbd></td>
<td>{{ t('ui.echomail.shortcuts.fullscreen', {}, locale, ['common']) }}</td>
</tr>
<tr>
<td class="text-center"><kbd>?</kbd> <kbd>H</kbd></td>
<td>{{ t('ui.echomail.shortcuts.help', {}, locale, ['common']) }}</td>
</tr>
<tr>
<td class="text-center"><kbd>Esc</kbd></td>
<td>{{ t('ui.echomail.shortcuts.close', {}, locale, ['common']) }}</td>
</tr>
</tbody>
</table>
<p class="text-muted small mb-0">{{ t('ui.echomail.shortcuts.dismiss', {}, locale, ['common']) }}</p>
</div>
</div>
</div>
</div>
</div>
<!-- Advanced Search Modal -->
<div class="modal fade" id="advancedSearchModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="fas fa-sliders-h me-2"></i>{{ t('ui.common.advanced_search.title', {}, locale, ['common']) }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p class="text-muted small mb-3">{{ t('ui.common.advanced_search.help', {}, locale, ['common']) }}</p>
<div class="mb-3">
<label for="advSearchFromName" class="form-label">{{ t('ui.common.advanced_search.from_name', {}, locale, ['common']) }}</label>
<input type="text" class="form-control" id="advSearchFromName" placeholder="{{ t('ui.common.advanced_search.from_name_placeholder', {}, locale, ['common']) }}">
</div>
<div class="mb-3">
<label for="advSearchSubject" class="form-label">{{ t('ui.common.advanced_search.subject', {}, locale, ['common']) }}</label>
<input type="text" class="form-control" id="advSearchSubject" placeholder="{{ t('ui.common.advanced_search.subject_placeholder', {}, locale, ['common']) }}">
</div>
<div class="mb-3">
<label for="advSearchBody" class="form-label">{{ t('ui.common.advanced_search.body', {}, locale, ['common']) }}</label>
<input type="text" class="form-control" id="advSearchBody" placeholder="{{ t('ui.common.advanced_search.body_placeholder', {}, locale, ['common']) }}">
</div>
<div class="mb-3">
<label class="form-label">{{ t('ui.common.advanced_search.date_range', {}, locale, ['common']) }}</label>
<div class="d-flex gap-2 align-items-center">
<input type="date" class="form-control" id="advSearchDateFrom">
<span class="text-muted flex-shrink-0">?</span>
<input type="date" class="form-control" id="advSearchDateTo">
</div>
</div>
<div id="advSearchError" class="alert alert-danger d-none"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ t('ui.common.cancel', {}, locale, ['common']) }}</button>
<button type="button" class="btn btn-primary" onclick="runAdvancedSearch()">
<i class="fas fa-search me-1"></i>{{ t('ui.common.search', {}, locale, ['common']) }}
</button>
</div>
</div>
</div>
</div>
<!-- Address Book Entry Modal -->
<div class="modal fade" id="addressBookModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addressBookModalTitle">{{ t('ui.address_book.add_entry', {}, locale, ['common']) }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div id="addressBookModalError" class="alert alert-danger d-none" role="alert"></div>
<form id="addressBookForm">
<input type="hidden" id="addressBookEntryId">
<div class="mb-3">
<label for="addressBookName" class="form-label">{{ t('ui.common.name', {}, locale, ['common']) }}</label>
<input type="text" class="form-control" id="addressBookName" required
placeholder="{{ t('ui.address_book.name_placeholder', {}, locale, ['common']) }}">
<div class="form-text">{{ t('ui.address_book.name_help', {}, locale, ['common']) }}</div>
</div>
<div class="mb-3">
<label for="addressBookUserId" class="form-label">{{ t('ui.address_book.user_id', {}, locale, ['common']) }}</label>
<input type="text" class="form-control" id="addressBookUserId" required
placeholder="{{ t('ui.address_book.user_id_placeholder', {}, locale, ['common']) }}">
<div class="form-text">{{ t('ui.address_book.user_id_help', {}, locale, ['common']) }}</div>
</div>
<div class="mb-3">
<label for="addressBookNodeAddress" class="form-label">{{ t('ui.address_book.node_address', {}, locale, ['common']) }}</label>
<input type="text" class="form-control" id="addressBookNodeAddress" required
placeholder="{{ t('ui.address_book.node_address_placeholder', {}, locale, ['common']) }}" pattern="^\d+:\d+\/\d+(\.\d+)?$"
title="{{ t('ui.address_book.node_address_title', {}, locale, ['common']) }}">
<div class="form-text">{{ t('ui.address_book.node_address_help', {}, locale, ['common']) }}</div>
</div>
<div class="mb-3">
<label for="addressBookEmail" class="form-label">{{ t('ui.address_book.email_address', {}, locale, ['common']) }} <small class="text-muted">({{ t('ui.common.optional', {}, locale, ['common']) }})</small></label>
<input type="email" class="form-control" id="addressBookEmail"
placeholder="email@example.com">
<div class="form-text">{{ t('ui.address_book.email_help', {}, locale, ['common']) }}</div>
</div>
<div class="mb-3">
<label for="addressBookDescription" class="form-label">{{ t('ui.common.description', {}, locale, ['common']) }} <small class="text-muted">({{ t('ui.common.optional', {}, locale, ['common']) }})</small></label>
<textarea class="form-control" id="addressBookDescription" rows="3"
placeholder="{{ t('ui.address_book.description_placeholder', {}, locale, ['common']) }}"></textarea>
</div>
{% if crashmail_enabled %}
<div class="mb-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" id="addressBookAlwaysCrashmail" name="always_crashmail">
<label class="form-check-label" for="addressBookAlwaysCrashmail">
<i class="fas fa-bolt text-warning me-1"></i>{{ t('ui.address_book.always_crashmail', {}, locale, ['common']) }}
</label>
<div class="form-text">{{ t('ui.address_book.always_crashmail_help', {}, locale, ['common']) }}</div>
</div>
</div>
{% endif %}
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ t('ui.common.cancel', {}, locale, ['common']) }}</button>
<button type="button" class="btn btn-primary" onclick="saveAddressBookEntry()">
<i class="fas fa-save"></i> {{ t('ui.common.save', {}, locale, ['common']) }}
</button>
</div>
</div>
</div>
</div>
<!-- Edit Message Modal -->
<div class="modal fade" id="editMessageModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editMessageModalTitle"><i class="fas fa-pencil-alt me-2"></i>{{ t('ui.echomail.edit_message', {}, locale, ['common']) }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<table class="table table-sm table-borderless mb-3">
<tbody>
<tr>
<th class="text-muted small fw-normal ps-0" style="width:30%">{{ t('ui.common.db_id', {}, locale, ['common']) }}</th>
<td class="small font-monospace" id="editMsgDbId"></td>
</tr>
<tr>
<th class="text-muted small fw-normal ps-0">{{ t('ui.common.message_id', {}, locale, ['common']) }}</th>
<td class="small font-monospace" id="editMsgId"></td>
</tr>
<tr>
<th class="text-muted small fw-normal ps-0">{{ t('ui.common.date_label', {}, locale, ['common']) }}</th>
<td class="small" id="editMsgDate"></td>
</tr>
<tr>
<th class="text-muted small fw-normal ps-0">{{ t('ui.common.from_label', {}, locale, ['common']) }}</th>
<td class="small" id="editMsgFrom"></td>
</tr>
<tr>
<th class="text-muted small fw-normal ps-0">{{ t('ui.common.subject_label', {}, locale, ['common']) }}</th>
<td class="small" id="editMsgSubject"></td>
</tr>
</tbody>
</table>
<hr>
<div class="mb-3">
<label for="editArtFormat" class="form-label">{{ t('ui.echomail.art_format', {}, locale, ['common']) }}</label>
<select class="form-select" id="editArtFormat">
<option value="">{{ t('ui.echomail.art_format_auto', {}, locale, ['common']) }}</option>
<option value="plain">{{ t('ui.echomail.art_format_plain', {}, locale, ['common']) }}</option>
<option value="ansi">{{ t('ui.echomail.art_format_ansi', {}, locale, ['common']) }}</option>
<option value="amiga_ansi">{{ t('ui.echomail.art_format_amiga_ansi', {}, locale, ['common']) }}</option>
</select>
</div>
<div class="mb-3">
<label for="editCharset" class="form-label">{{ t('ui.echomail.message_charset', {}, locale, ['common']) }}</label>
<select class="form-select" id="editCharset">
{% for cs in supported_charsets %}
<option value="{{ cs.value }}">{{ cs.label }}</option>
{% endfor %}
</select>
</div>
<div id="editMessageError" class="alert alert-danger d-none"></div>
<div id="editMessageSuccess" class="alert alert-success d-none">
<i class="fas fa-check-circle me-2"></i>{{ t('ui.echomail.edit_message_saved', {}, locale, ['common']) }}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ t('ui.common.close', {}, locale, ['common']) }}</button>
<button type="button" class="btn btn-primary" id="saveEditMessageBtn" onclick="saveEditMessage()">
<i class="fas fa-save me-1"></i>{{ t('ui.common.save', {}, locale, ['common']) }}
</button>
</div>
</div>
</div>
</div>
{% if ai_assistant_enabled %}
{% include 'partials/ai_assistant_modal.twig' %}
{% endif %}
{% endblock %}
{% block scripts %}
<script>
window.systemAddress = '{{ system_address }}';
window.currentUser = {{ current_user|json_encode(15)|raw }};
</script>
<script src="/js/ansisys.js"></script>
<script src="/js/sixel.js"></script>
<script src="/js/pcboard.js"></script>
<script src="/js/message-list-context-menu.js"></script>
<script src="/js/netmail.js"></script>
<script src="/vendor/marked.min.js"></script>
<script src="/js/ai-assistant.js?v=1"></script>
<style>
/* Read/Unread message styling - colors handled by theme stylesheets */
.message-row.table-light strong {
font-weight: 600;
}
/* Threading styles */
.thread-root {
border-left: 3px solid #0d6efd;
background-color: rgba(13, 110, 253, 0.05);
}
.thread-level-1 {
border-left: 2px solid #6c757d;
background-color: rgba(108, 117, 125, 0.05);
}
.thread-level-2 {
border-left: 2px solid #28a745;
background-color: rgba(40, 167, 69, 0.05);
}
.thread-level-3 {
border-left: 2px solid #ffc107;
background-color: rgba(255, 193, 7, 0.05);
}
.thread-level-4, .thread-level-5, .thread-level-6, .thread-level-7, .thread-level-8, .thread-level-9 {
border-left: 2px solid #dc3545;
background-color: rgba(220, 53, 69, 0.05);
}
/* Thread root styling enhancement */
.thread-root .message-subject {
font-weight: 500;
}
/* Reply badge styling */
.thread-root .badge.bg-secondary {
background-color: #0d6efd !important;
font-size: 0.7em;
}
/* Hover effects for threads */
.thread-root:hover {
background-color: rgba(13, 110, 253, 0.1) !important;
}
.thread-reply:hover {
background-color: rgba(108, 117, 125, 0.1) !important;
}
/* Threading icons */
.thread-reply .fa-reply {
color: #6c757d;
font-size: 0.8em;
}
/* Address Book Styling */
.address-book-entry {
transition: all 0.2s ease;
}
.address-book-entry:hover {
background-color: #f8f9fa;
border-color: #0d6efd !important;
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.address-book-entry .dropdown-toggle {
opacity: 0.6;
transition: opacity 0.2s ease;
}
.address-book-entry:hover .dropdown-toggle {
opacity: 1;
}
.smaller {
font-size: 0.75em;
}
/* Ensure proper spacing in threaded view */
.thread-reply td {
vertical-align: middle;
}
/* Mobile threading adjustments */
@media (max-width: 991.98px) {
.thread-level-1, .thread-level-2, .thread-level-3,
.thread-level-4, .thread-level-5, .thread-level-6,
.thread-level-7, .thread-level-8, .thread-level-9 {
border-left-width: 1px;
}
.thread-root {
border-left-width: 2px;
}
}
/* Mobile filter controls */
@media (max-width: 575.98px) {
/* Reduce thread indentation on very small screens */
td[style*="padding-left"] {
padding-left: 5px !important;
}
/* Make filter controls full width and scrollable on mobile */
.filter-controls {
width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
padding-bottom: 2px;
}
.filter-controls .btn-group {
flex-shrink: 0;
}
.filter-controls .btn {
padding: 0.25rem 0.5rem;
font-size: 0.75rem;
}
}
/* Search term highlighting */
.search-highlight {
background-color: #ffff00 !important;
color: #000000 !important;
font-weight: 600;
padding: 0.1em 0.2em;
border-radius: 0.2em;
box-shadow: 0 0 0 1px #cccc00;
}
/* Ensure highlighting works in different contexts */
.message-formatted .search-highlight,
.message-preformatted .search-highlight,
.quote-line .search-highlight,
.message-line .search-highlight,
.message-signature .search-highlight {
background-color: #ffff00 !important;
color: #000000 !important;
font-weight: 600;
padding: 0.1em 0.2em;
border-radius: 0.2em;
box-shadow: 0 0 0 1px #cccc00;
}
/* Dark mode support for search highlighting */
@media (prefers-color-scheme: dark) {
.search-highlight,
.message-formatted .search-highlight,
.message-preformatted .search-highlight,
.quote-line .search-highlight,
.message-line .search-highlight,
.message-signature .search-highlight {
background-color: #ffff66 !important;
color: #000000 !important;
box-shadow: 0 0 0 1px #cccc00;
}
}
/* Modal header layout improvements */
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-title {
flex: 1;
text-align: center;
margin: 0 1rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Message modal navigation buttons */
.modal-header .btn-sm {
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
min-width: 32px;
}
.modal-header .btn-sm:disabled {
opacity: 0.3;
cursor: not-allowed;
}
.modal-header .btn-sm i {
font-size: 0.75rem;
}
.modal-header .d-flex {
flex-shrink: 0;
}
/* Mobile modal navigation adjustments */
@media (max-width: 576px) {
.modal-header .btn-sm {
padding: 0.2rem 0.4rem;
font-size: 0.8rem;
min-width: 28px;
}
.modal-header .btn-sm i {
font-size: 0.7rem;
}
.modal-title {
font-size: 1rem;
margin: 0 0.5rem;
}
}
</style>
{% endblock %}
|