0% found this document useful (0 votes)
6 views139 pages

Journal Upgrade

The document is an HTML template for a journal application featuring a sidebar, main content area, and various UI components styled with CSS variables. It includes styles for dark and light themes, navigation items, buttons, form elements, and entry cards. The layout is designed to be responsive and user-friendly, with interactive elements like mood chips and tags.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views139 pages

Journal Upgrade

The document is an HTML template for a journal application featuring a sidebar, main content area, and various UI components styled with CSS variables. It includes styles for dark and light themes, navigation items, buttons, form elements, and entry cards. The layout is designed to be responsive and user-friendly, with interactive elements like mood chips and tags.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

<!

DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Journal</title>
<link href="[Link]
al,wght@0,400;0,700;1,400&family=DM+Sans:wght@300;400;500;600&
family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root {
--bg: #f7f3ee;
--surface: #ffffff;
--surface2: #f0ebe4;
--border: #e0d8ce;
--text: #2c2420;
--text2: #7a6e68;
--accent: #c17f4a;
--accent2: #8b5e3c;
--accent-light: #f5e6d3;
--danger: #c0392b;
--success: #27ae60;
--tag-bg: #e8dfd4;
--shadow: 0 2px 16px rgba(44,36,32,0.08);
--shadow-lg: 0 8px 40px rgba(44,36,32,0.14);
--radius: 14px;
--font-display: 'Playfair Display', Georgia, serif;
--font-body: 'DM Sans', sans-serif;
--font-mono: 'DM Mono', monospace;
--sidebar-w: 240px;
}
.dark {
--bg: #1a1612;
--surface: #241f1b;
--surface2: #2e2822;
--border: #3d342c;
--text: #f0e8df;
--text2: #a89b8f;
--accent: #d4914f;
--accent2: #e8a86b;
--accent-light: #3a2d20;
--tag-bg: #3a2d22;
--shadow: 0 2px 16px rgba(0,0,0,0.3);
--shadow-lg: 0 8px 40px rgba(0,0,0,0.4);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: var(--font-body);
background: var(--bg);
color: var(--text);
min-height: 100vh;
transition: background 0.3s, color 0.3s;
display: flex;
flex-direction: column;
}

/* ---- SIDEBAR ---- */


#sidebar {
position: fixed; top: 0; left: 0; bottom: 0;
width: var(--sidebar-w);
background: var(--surface);
border-right: 1px solid var(--border);
display: flex; flex-direction: column;
z-index: 100;
transition: background 0.3s, border-color 0.3s;
box-shadow: var(--shadow);
}
.sidebar-logo {
padding: 28px 24px 20px;
border-bottom: 1px solid var(--border);
}
.active-filter { background: var(--accent-light) !important; color:
var(--accent) !important; border-color: var(--accent) !important;
font-weight: 700; }
.sidebar-logo h1 {
font-family: var(--font-display);
font-size: 1.5rem;
color: var(--accent);
letter-spacing: 0.01em;
line-height: 1;
}
.sidebar-logo p {
font-size: 0.72rem;
color: var(--text2);
margin-top: 4px;
font-weight: 500;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.sidebar-nav { flex: 1; padding: 12px 10px; overflow-y: auto; }
.nav-item {
display: flex; align-items: center; gap: 10px;
padding: 10px 14px;
border-radius: 10px;
cursor: pointer;
font-size: 0.88rem;
font-weight: 500;
color: var(--text2);
transition: all 0.2s;
margin-bottom: 2px;
border: none; background: none; width: 100%; text-align: left;
}
.nav-item:hover { background: var(--surface2); color: var(--text); }
.[Link] { background: var(--accent-light); color: var(--accent); }
.nav-item .icon { font-size: 1.1rem; width: 22px; text-align: center; }
.sidebar-footer {
padding: 14px 10px;
border-top: 1px solid var(--border);
}
.theme-toggle {
display: flex; align-items: center; justify-content: space-between;
padding: 10px 14px;
border-radius: 10px;
background: var(--surface2);
cursor: pointer;
font-size: 0.82rem;
font-weight: 500;
color: var(--text2);
border: none; width: 100%;
}
.toggle-pill {
width: 36px; height: 20px;
background: var(--border);
border-radius: 20px;
position: relative;
transition: background 0.3s;
}
.[Link] { background: var(--accent); }
.toggle-knob {
position: absolute; top: 2px; left: 2px;
width: 16px; height: 16px;
background: white;
border-radius: 50%;
transition: left 0.3s;
box-shadow: 0 1px 4px rgba(0,0,0,0.2);
}
.[Link] .toggle-knob { left: 18px; }

/* ---- MAIN ---- */


#main {
margin-left: var(--sidebar-w);
flex: 1;
min-height: 100vh;
display: flex;
flex-direction: column;
}
.topbar {
position: sticky; top: 0; z-index: 50;
background: var(--bg);
border-bottom: 1px solid var(--border);
padding: 16px 32px;
display: flex; align-items: center; justify-content: space-between;
transition: background 0.3s;
}
.topbar h2 {
font-family: var(--font-display);
font-size: 1.4rem;
color: var(--text);
}
.topbar-meta {
font-size: 0.8rem;
color: var(--text2);
font-family: var(--font-mono);
}
.page { display: none; padding: 32px; max-width: 900px; margin: 0
auto; width: 100%; }
.[Link] { display: block; }

/* ---- BUTTONS ---- */


.btn {
display: inline-flex; align-items: center; gap: 6px;
padding: 9px 18px;
border-radius: 9px;
font-size: 0.85rem;
font-weight: 600;
font-family: var(--font-body);
cursor: pointer;
border: none;
transition: all 0.18s;
}
.btn-primary { background: var(--accent); color: white; }
.btn-primary:hover { background: var(--accent2); }
.btn-outline {
background: transparent;
color: var(--text2);
border: 1.5px solid var(--border);
}
.btn-outline:hover { border-color: var(--accent); color: var(--accent);
background: var(--accent-light); }
.btn-danger { background: var(--danger); color: white; }
.btn-danger:hover { opacity: 0.85; }
.btn-sm { padding: 6px 12px; font-size: 0.78rem; border-radius: 7px; }
.btn-ghost { background: transparent; color: var(--text2); border: none;
padding: 6px 10px; }
.btn-ghost:hover { color: var(--accent); background: var(--accent-light);
}

/* ---- FORM ELEMENTS ---- */


.form-group { margin-bottom: 18px; }
.form-label {
display: block;
font-size: 0.78rem;
font-weight: 600;
color: var(--text2);
text-transform: uppercase;
letter-spacing: 0.07em;
margin-bottom: 7px;
}
input[type="text"], input[type="date"], textarea, select {
width: 100%;
padding: 10px 14px;
border: 1.5px solid var(--border);
border-radius: 9px;
font-size: 0.9rem;
font-family: var(--font-body);
background: var(--surface);
color: var(--text);
transition: border-color 0.2s, background 0.3s;
outline: none;
}
input:focus, textarea:focus, select:focus { border-color: var(--accent); }
textarea { resize: vertical; min-height: 140px; line-height: 1.7; }
select { cursor: pointer; }

/* ---- NEW ENTRY ---- */


.entry-meta-row {
display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
margin-bottom: 14px;
}
.entry-meta-row-3 {
display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 14px;
margin-bottom: 14px;
}
.datetime-display {
background: var(--surface2);
padding: 10px 14px;
border-radius: 9px;
font-family: var(--font-mono);
font-size: 0.82rem;
color: var(--accent);
border: 1.5px solid var(--border);
display: flex; align-items: center; gap: 8px;
}
.timer-display {
background: var(--accent-light);
border: 1.5px solid var(--accent);
border-radius: 9px;
padding: 10px 14px;
font-family: var(--font-mono);
font-size: 0.82rem;
color: var(--accent);
display: flex; align-items: center; gap: 8px;
}
.mood-grid {
display: flex; flex-wrap: wrap; gap: 8px;
margin-bottom: 4px;
}
.mood-chip {
padding: 7px 13px;
border-radius: 20px;
font-size: 0.82rem;
cursor: pointer;
border: 1.5px solid var(--border);
background: var(--surface);
color: var(--text2);
transition: all 0.18s;
font-weight: 500;
}
.mood-chip:hover { border-color: var(--accent); color: var(--accent); }
.[Link] { background: var(--accent); color: white;
border-color: var(--accent); }
.tags-input-wrap {
display: flex; flex-wrap: wrap; gap: 6px;
padding: 8px 10px;
border: 1.5px solid var(--border);
border-radius: 9px;
background: var(--surface);
cursor: text;
min-height: 44px;
align-items: center;
}
.tags-input-wrap:focus-within { border-color: var(--accent); }
.tag-pill {
display: inline-flex; align-items: center; gap: 4px;
padding: 3px 10px 3px 10px;
background: var(--tag-bg);
color: var(--accent2);
border-radius: 20px;
font-size: 0.78rem;
font-weight: 600;
}
.tag-pill button { background: none; border: none; cursor: pointer; color:
var(--text2); font-size: 0.9rem; padding: 0 0 0 2px; line-height: 1; }
.tag-pill button:hover { color: var(--danger); }
.tags-input {
border: none; outline: none; background: transparent;
font-size: 0.85rem; font-family: var(--font-body);
color: var(--text); min-width: 100px; flex: 1;
padding: 2px 4px;
}
.custom-questions-section {
background: var(--surface2);
border-radius: var(--radius);
padding: 16px 18px;
margin-bottom: 18px;
border: 1px solid var(--border);
}
.custom-questions-section h4 {
font-size: 0.78rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--text2);
margin-bottom: 12px;
}
.cq-item { margin-bottom: 14px; }
.cq-item:last-child { margin-bottom: 0; }
.cq-label { font-size: 0.85rem; font-weight: 600; color: var(--text);
margin-bottom: 6px; }
/* ---- ENTRIES LIST ---- */
.entries-list { display: flex; flex-direction: column; gap: 14px; }
.entry-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 20px 22px;
cursor: pointer;
transition: all 0.2s;
box-shadow: var(--shadow);
}
.entry-card:hover { border-color: var(--accent); box-shadow:
var(--shadow-lg); transform: translateY(-1px); }
.entry-card-header {
display: flex; align-items: flex-start; justify-content: space-between;
margin-bottom: 10px;
}
.entry-card-title {
font-family: var(--font-display);
font-size: 1.08rem;
font-weight: 700;
color: var(--text);
flex: 1;
}
.entry-card-meta {
display: flex; flex-wrap: wrap; gap: 8px;
align-items: center;
margin-top: 4px;
}
.meta-badge {
font-size: 0.73rem;
font-weight: 600;
padding: 2px 9px;
border-radius: 20px;
background: var(--surface2);
color: var(--text2);
font-family: var(--font-mono);
}
.[Link] { background: var(--accent-light); color:
var(--accent); }
.[Link] { background: var(--tag-bg); color: var(--accent2); }
.entry-card-preview {
font-size: 0.85rem;
color: var(--text2);
line-height: 1.6;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.entry-card-actions {
display: flex; gap: 6px;
margin-top: 12px;
padding-top: 12px;
border-top: 1px solid var(--border);
}
.entry-checkbox { margin-right: 6px; accent-color: var(--accent); width:
16px; height: 16px; cursor: pointer; }

/* ---- MODAL ---- */


.modal-overlay {
position: fixed; inset: 0;
background: rgba(0,0,0,0.45);
z-index: 200;
display: none; align-items: center; justify-content: center;
padding: 20px;
backdrop-filter: blur(4px);
}
.[Link] { display: flex; }
.modal {
background: var(--surface);
border-radius: 18px;
padding: 28px;
width: 100%; max-width: 680px;
max-height: 85vh;
overflow-y: auto;
box-shadow: var(--shadow-lg);
position: relative;
}
.modal-title {
font-family: var(--font-display);
font-size: 1.4rem;
margin-bottom: 18px;
color: var(--text);
}
.modal-close {
position: absolute; top: 18px; right: 20px;
background: none; border: none; font-size: 1.4rem;
cursor: pointer; color: var(--text2);
width: 32px; height: 32px;
display: flex; align-items: center; justify-content: center;
border-radius: 50%;
transition: all 0.2s;
}
.modal-close:hover { background: var(--surface2); color: var(--text); }

/* ---- STATS ---- */


.stats-grid {
display: grid; grid-template-columns: repeat(auto-fit, minmax(180px,
1fr));
gap: 14px; margin-bottom: 24px;
}
.stat-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 18px 20px;
text-align: center;
box-shadow: var(--shadow);
}
.stat-value {
font-family: var(--font-display);
font-size: 2rem;
font-weight: 700;
color: var(--accent);
line-height: 1;
margin-bottom: 6px;
}
.stat-label { font-size: 0.78rem; color: var(--text2); font-weight: 600;
text-transform: uppercase; letter-spacing: 0.06em; }
.chart-section {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 20px 22px;
margin-bottom: 16px;
box-shadow: var(--shadow);
}
.chart-section h3 {
font-family: var(--font-display);
font-size: 1rem;
color: var(--text);
margin-bottom: 14px;
}
.bar-chart { display: flex; flex-direction: column; gap: 8px; }
.bar-row { display: flex; align-items: center; gap: 10px; }
.bar-label { width: 90px; font-size: 0.78rem; color: var(--text2);
text-align: right; flex-shrink: 0; }
.bar-track { flex: 1; background: var(--surface2); border-radius: 6px;
height: 22px; overflow: hidden; }
.bar-fill { height: 100%; background: linear-gradient(90deg,
var(--accent), var(--accent2)); border-radius: 6px; transition: width 0.6s
ease; display: flex; align-items: center; padding-left: 8px; }
.bar-val { font-size: 0.72rem; color: white; font-weight: 600; }

/* ---- SEARCH ---- */


.search-bar-wrap { position: relative; margin-bottom: 18px; }
.search-bar-wrap input { padding-left: 38px; }
.search-icon { position: absolute; left: 12px; top: 50%; transform:
translateY(-50%); color: var(--text2); font-size: 1rem; pointer-events:
none; }
.filter-row {
display: flex; flex-wrap: wrap; gap: 10px;
margin-bottom: 18px;
padding: 14px 16px;
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
}
.filter-row select, .filter-row input {
flex: 1; min-width: 130px; max-width: 180px;
font-size: 0.82rem; padding: 7px 10px;
}

/* ---- SETTINGS ---- */


.settings-section {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 22px 24px;
margin-bottom: 18px;
box-shadow: var(--shadow);
}
.settings-section h3 {
font-family: var(--font-display);
font-size: 1rem;
margin-bottom: 16px;
color: var(--text);
padding-bottom: 10px;
border-bottom: 1px solid var(--border);
}
.setting-row {
display: flex; align-items: center; justify-content: space-between;
padding: 10px 0;
border-bottom: 1px solid var(--border);
}
.setting-row:last-child { border-bottom: none; }
.setting-info h4 { font-size: 0.88rem; font-weight: 600; color: var(--text);
}
.setting-info p { font-size: 0.78rem; color: var(--text2); margin-top: 2px; }
.cq-list { display: flex; flex-direction: column; gap: 8px; margin-top:
10px; }
.cq-list-item {
display: flex; align-items: center; justify-content: space-between;
padding: 9px 12px;
background: var(--surface2);
border-radius: 8px;
font-size: 0.85rem;
}
.cat-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.cat-badge {
display: inline-flex; align-items: center; gap: 5px;
padding: 5px 12px;
background: var(--tag-bg);
color: var(--accent2);
border-radius: 20px;
font-size: 0.8rem;
font-weight: 600;
}
.cat-badge button { background: none; border: none; cursor: pointer;
color: var(--text2); font-size: 0.85rem; }
.cat-badge button:hover { color: var(--danger); }

/* ---- BACKUP ---- */


.backup-section {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 22px 24px;
margin-bottom: 18px;
box-shadow: var(--shadow);
}
.backup-section h3 {
font-family: var(--font-display);
font-size: 1rem;
margin-bottom: 14px;
color: var(--text);
padding-bottom: 10px;
border-bottom: 1px solid var(--border);
}
.backup-options { display: flex; flex-wrap: wrap; gap: 10px;
margin-bottom: 14px; }
.bulk-select-bar {
display: flex; align-items: center; gap: 10px;
padding: 10px 14px;
background: var(--accent-light);
border: 1px solid var(--accent);
border-radius: 9px;
margin-bottom: 14px;
font-size: 0.85rem;
color: var(--accent);
font-weight: 600;
}
.empty-state {
text-align: center;
padding: 50px 20px;
color: var(--text2);
}
.empty-state .icon { font-size: 3rem; margin-bottom: 12px; }
.empty-state p { font-size: 0.9rem; }

/* ---- DETAIL VIEW ---- */


.detail-content {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 28px 32px;
box-shadow: var(--shadow);
white-space: pre-wrap;
line-height: 1.8;
font-size: 0.95rem;
}
.detail-meta { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom:
18px; }
.detail-qa {
background: var(--surface2);
border-radius: 10px;
padding: 14px 16px;
margin-bottom: 18px;
}
.detail-qa h4 { font-size: 0.8rem; font-weight: 700; text-transform:
uppercase; letter-spacing: 0.07em; color: var(--text2); margin-bottom:
8px; }
.qa-pair { margin-bottom: 8px; }
.qa-pair .q { font-size: 0.82rem; font-weight: 600; color: var(--text2); }
.qa-pair .a { font-size: 0.88rem; color: var(--text); margin-top: 2px; }
.toast {
position: fixed; bottom: 24px; right: 24px;
background: var(--text);
color: var(--bg);
padding: 12px 20px;
border-radius: 10px;
font-size: 0.85rem;
font-weight: 600;
z-index: 999;
box-shadow: var(--shadow-lg);
transform: translateY(80px);
opacity: 0;
transition: all 0.3s;
}
.[Link] { transform: translateY(0); opacity: 1; }
.divider { height: 1px; background: var(--border); margin: 18px 0; }
.flask-status-badge {
display: inline-block;
font-size: 0.75rem;
font-weight: 600;
padding: 3px 10px;
border-radius: 20px;
background: var(--surface2);
color: var(--text2);
border: 1px solid var(--border);
}
.[Link] { background: rgba(39,174,96,0.1); color:
var(--success); border-color: var(--success); }
.[Link] { background: rgba(192,57,43,0.1); color:
var(--danger); border-color: var(--danger); }
.add-inline-wrap { display: flex; gap: 8px; margin-top: 10px; }
.add-inline-wrap input { flex: 1; }
.section-header {
display: flex; align-items: center; justify-content: space-between;
margin-bottom: 20px;
}
.section-header h2 { font-family: var(--font-display); font-size: 1.5rem;
color: var(--text); }

/* ---- QUESTION SESSION ---- */


.q-session-card {
background: var(--surface);
border: 1.5px solid var(--border);
border-radius: var(--radius);
padding: 20px 22px;
margin-bottom: 16px;
box-shadow: var(--shadow);
transition: border-color 0.2s;
}
.[Link]-q { border-color: var(--accent); box-shadow: 0 0
0 3px var(--accent-light); }
.q-session-header {
display: flex; align-items: center; justify-content: space-between;
margin-bottom: 12px; gap: 10px;
}
.q-number {
width: 28px; height: 28px; border-radius: 50%;
background: var(--accent); color: white;
font-size: 0.78rem; font-weight: 700;
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
}
.q-text { font-size: 0.95rem; font-weight: 600; color: var(--text); flex: 1;
line-height: 1.4; }
.q-timer-badge {
display: flex; align-items: center; gap: 5px;
padding: 4px 10px;
border-radius: 20px;
background: var(--surface2);
border: 1.5px solid var(--border);
font-family: var(--font-mono);
font-size: 0.78rem;
color: var(--text2);
flex-shrink: 0;
transition: all 0.3s;
}
.[Link] { background: var(--accent-light); border-color:
var(--accent); color: var(--accent); }
.[Link] { background: #e8f5e9; border-color:
var(--success); color: var(--success); }
.dark .[Link] { background: #1a3a1f; }
.q-timer-dot { width: 7px; height: 7px; border-radius: 50%; background:
var(--text2); }
.[Link] .q-timer-dot { background: var(--accent);
animation: pulse-dot 1s infinite; }
.[Link] .q-timer-dot { background: var(--success); }
@keyframes pulse-dot { 0%,100%{opacity:1;} 50%{opacity:0.3;} }
.q-controls { display: flex; gap: 8px; margin-top: 10px; align-items:
center; flex-wrap: wrap; }
.q-status-line {
font-size: 0.75rem; color: var(--text2);
margin-top: 6px;
font-style: italic;
}
.session-summary {
background: var(--accent-light);
border: 1.5px solid var(--accent);
border-radius: var(--radius);
padding: 18px 20px;
margin-bottom: 20px;
display: none;
}
.session-summary h3 { font-family: var(--font-display); font-size: 1rem;
color: var(--accent); margin-bottom: 12px; }
.summary-row { display: flex; justify-content: space-between; font-size:
0.85rem; padding: 4px 0; border-bottom: 1px solid var(--border); }
.summary-row:last-child { border-bottom: none; font-weight: 700; }
.no-questions-msg {
text-align: center; padding: 50px 20px; color: var(--text2);
}
.no-questions-msg .icon { font-size: 2.5rem; margin-bottom: 10px; }

/* ---- STAR / FAVOURITE ---- */


.star-btn {
background: none; border: none; cursor: pointer;
font-size: 1.2rem; padding: 2px 6px;
color: var(--border);
transition: color 0.2s, transform 0.2s;
line-height: 1;
}
.[Link] { color: #f5c518; }
.star-btn:hover { transform: scale(1.2); }

/* ---- ERA SYSTEM ---- */


.era-timeline { position: relative; padding-left: 24px; }
.era-timeline::before { content: ''; position: absolute; left: 8px; top: 0;
bottom: 0; width: 2px; background: var(--border); }
.era-month-group { margin-bottom: 32px; }
.era-month-label { font-family: var(--font-display); font-size: 1.05rem;
font-weight: 700; color: var(--text); margin-bottom: 12px; padding-left:
8px; }
.era-day-row { display: flex; align-items: stretch; margin-bottom: 6px;
position: relative; }
.era-day-dot { position: absolute; left: -20px; top: 50%; transform:
translateY(-50%); width: 10px; height: 10px; border-radius: 50%;
background: var(--border); border: 2px solid var(--bg); flex-shrink: 0;
z-index: 1; }
.[Link]-entry { background: var(--accent); }
.era-day-card { flex: 1; background: var(--surface); border: 1px solid
var(--border); border-radius: 10px; padding: 10px 14px; display: flex;
align-items: center; gap: 10px; min-height: 46px; transition: border-color
0.2s; }
.era-day-card:hover { border-color: var(--accent); }
.era-day-date { font-family: var(--font-mono); font-size: 0.75rem; color:
var(--text2); flex-shrink: 0; width: 36px; text-align: center; }
.era-day-era-band { width: 6px; border-radius: 4px; align-self: stretch;
flex-shrink: 0; min-height: 20px; }
.era-day-entries { flex: 1; display: flex; flex-direction: column; gap: 3px;
}
.era-day-entry-title { font-size: 0.82rem; font-weight: 600; color:
var(--text); cursor: pointer; white-space: nowrap; overflow: hidden;
text-overflow: ellipsis; }
.era-day-entry-title:hover { color: var(--accent); }
.era-day-entry-title .star-inline { color: #f5c518; font-size: 0.75rem;
margin-right: 3px; }
.era-day-empty { font-size: 0.78rem; color: var(--text2); font-style: italic;
}
.era-label-badge { font-size: 0.7rem; font-weight: 700; padding: 2px
8px; border-radius: 10px; white-space: nowrap; flex-shrink: 0; }
.era-list { display: flex; flex-direction: column; gap: 10px;
margin-bottom: 16px; }
.era-item { display: flex; align-items: center; gap: 10px; background:
var(--surface); border: 1px solid var(--border); border-radius: 10px;
padding: 12px 14px; }
.era-color-dot { width: 14px; height: 14px; border-radius: 50%;
flex-shrink: 0; }
.era-item-info { flex: 1; }
.era-item-name { font-weight: 700; font-size: 0.9rem; color: var(--text); }
.era-item-dates { font-size: 0.75rem; color: var(--text2); font-family:
var(--font-mono); margin-top: 2px; }
.era-add-form { background: var(--surface2); border: 1px solid
var(--border); border-radius: 10px; padding: 14px 16px; display: flex;
flex-direction: column; gap: 10px; }
.era-add-form-row { display: flex; gap: 8px; flex-wrap: wrap;
align-items: center; }
.era-add-form input[type="text"] { flex: 1; min-width: 140px; }
.era-add-form input[type="date"] { flex: 1; min-width: 130px; }
.era-color-picker { display: flex; gap: 6px; flex-wrap: wrap; margin-top:
2px; }
.era-color-opt { width: 22px; height: 22px; border-radius: 50%; border:
2px solid transparent; cursor: pointer; transition: border-color 0.15s,
transform 0.15s; }
.[Link] { border-color: var(--text); transform: scale(1.2);
}
.era-nav-legend { display: flex; flex-wrap: wrap; gap: 6px;
margin-bottom: 16px; }
.era-legend-chip { display: flex; align-items: center; gap: 5px; padding:
4px 10px; border-radius: 20px; font-size: 0.75rem; font-weight: 600;
border: 1.5px solid transparent; cursor: pointer; transition: all 0.18s; }
.[Link] { border-color: var(--text); }
.era-nav-controls { display: flex; align-items: center; gap: 10px;
margin-bottom: 18px; }
.era-nav-controls button { padding: 6px 14px; }
.era-nav-month-label { font-family: var(--font-display); font-size: 1rem;
font-weight: 700; color: var(--text); flex: 1; text-align: center; }
.era-star-filter { display: flex; gap: 6px; margin-bottom: 16px; }
.era-star-filter button { padding: 5px 12px; border-radius: 20px;
font-size: 0.78rem; font-weight: 600; border: 1.5px solid var(--border);
background: none; color: var(--text2); cursor: pointer; transition: all
0.18s; }
.era-star-filter [Link] { background: var(--accent-light); color:
var(--accent); border-color: var(--accent); }
.active-view-btn { background: var(--accent-light) !important; color:
var(--accent) !important; border-color: var(--accent) !important; }
/* ---- ERA GRID ---- */
.era-grid-wrap { display: grid; grid-template-columns: repeat(7, 1fr);
gap: 3px; }
.era-grid-header { display: grid; grid-template-columns: repeat(7, 1fr);
gap: 3px; margin-bottom: 4px; }
.era-grid-dow { text-align: center; font-size: 0.68rem; font-weight: 700;
color: var(--text2); padding: 4px 0; text-transform: uppercase;
letter-spacing: 0.05em; }
.era-grid-cell {
aspect-ratio: 1;
border-radius: 8px;
display: flex; flex-direction: column;
align-items: center; justify-content: center;
font-size: 0.78rem; font-weight: 600;
cursor: pointer;
position: relative;
border: 1.5px solid transparent;
transition: all 0.15s;
overflow: hidden;
min-height: 38px;
}
.era-grid-cell:hover { border-color: var(--accent); z-index: 1; transform:
scale(1.08); }
.[Link] { border-color: var(--accent) !important;
box-shadow: 0 0 0 2px var(--accent-light); }
.[Link] { cursor: default; background: transparent
!important; }
.[Link]:hover { transform: none; border-color: transparent;
}
.era-grid-day-num { font-size: 0.82rem; font-weight: 700; line-height: 1;
z-index: 1; }
.era-grid-dot { width: 5px; height: 5px; border-radius: 50%; background:
white; margin-top: 3px; z-index: 1; opacity: 0.9; }
.era-grid-era-bar { position: absolute; bottom: 0; left: 0; right: 0; height:
4px; }
.era-grid-month-title { font-family: var(--font-display); font-size: 1rem;
font-weight: 700; color: var(--text); margin-bottom: 8px; margin-top: 4px;
}
/* ---- BACKUP ---- */
/* ---- BOTTOM NAV (mobile only) ---- */
#bottom-nav {
display: none;
position: fixed; bottom: 0; left: 0; right: 0;
height: 64px;
background: var(--surface);
border-top: 1px solid var(--border);
z-index: 200;
flex-direction: row;
align-items: stretch;
box-shadow: 0 -2px 16px rgba(44,36,32,0.10);
}
.bnav-item {
flex: 1;
display: flex; flex-direction: column; align-items: center;
justify-content: center;
gap: 3px;
font-size: 0.62rem;
font-weight: 600;
color: var(--text2);
background: none; border: none;
cursor: pointer;
transition: color 0.18s;
padding: 6px 2px 2px;
letter-spacing: 0.03em;
}
.bnav-item .bicon { font-size: 1.3rem; line-height: 1; }
.[Link] { color: var(--accent); }
.[Link] .bicon { transform: scale(1.15); }

/* ---- ERA TIMELINE MOBILE FIX ---- */


.era-day-card { overflow: hidden; }
.era-day-entries { min-width: 0; overflow: hidden; }
.era-day-entry-title { max-width: 100%; }
.era-label-badge { max-width: 80px; overflow: hidden; text-overflow:
ellipsis; }

@media (max-width: 700px) {


:root { --sidebar-w: 0px; }
#sidebar { display: none !important; }
#bottom-nav { display: flex; }
#main {
margin-left: 0 !important;
padding-bottom: 64px;
}
.topbar {
padding: 12px 16px;
}
.topbar h2 { font-size: 1.1rem; }
.topbar-meta { font-size: 0.68rem; max-width: 150px; overflow:
hidden; text-overflow: ellipsis; white-space: nowrap; }
.page { padding: 14px 14px 10px; max-width: 100%; }
.entry-meta-row { grid-template-columns: 1fr 1fr; gap: 10px; }
.entry-meta-row-3 { grid-template-columns: 1fr; gap: 10px; }
.datetime-display, .timer-display { font-size: 0.72rem; padding: 8px
10px; }
.stats-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
.stat-card { padding: 12px 10px; }
.stat-value { font-size: 1.5rem; }
.modal { padding: 20px 16px; border-radius: 14px; }
.modal-overlay { padding: 12px; }
.filter-row { flex-direction: column; gap: 8px; }
.filter-row select, .filter-row input { max-width: 100%; }
.entry-card { padding: 14px 14px; }
.entry-card-actions { flex-wrap: wrap; gap: 6px; }
.btn { padding: 8px 14px; font-size: 0.82rem; }
.btn-sm { padding: 6px 10px; font-size: 0.75rem; }
.backup-options { flex-direction: column; }
.backup-options .btn { width: 100%; justify-content: center; }
.settings-section { padding: 16px 14px; }
.add-inline-wrap { flex-direction: column; }
.add-inline-wrap .btn { width: 100%; justify-content: center; }
.section-header { flex-direction: column; align-items: flex-start; gap:
10px; }
.bar-label { width: 70px; font-size: 0.72rem; }
.cq-list-item { flex-direction: column; align-items: flex-start; gap: 6px; }
.detail-content { padding: 16px; font-size: 0.88rem; }
/* ERA TIMELINE MOBILE */
.era-timeline { padding-left: 18px; }
.era-day-card { padding: 8px 8px; gap: 6px; }
.era-day-date { width: 28px; font-size: 0.68rem; }
.era-label-badge { display: none; }
.era-day-era-band { width: 4px; }
.era-day-entry-title { font-size: 0.78rem; }
.era-nav-controls { gap: 6px; }
.era-legend-chip { font-size: 0.7rem; padding: 3px 7px; }
}
@media (max-width: 380px) {
.entry-meta-row { grid-template-columns: 1fr; }
.topbar-meta { display: none; }
}
</style>
</head>
<body>

<!-- SIDEBAR -->


<nav id="sidebar">
<div class="sidebar-logo">
<h1>Journal</h1>
<p>Personal Diary</p>
</div>
<div class="sidebar-nav">
<button class="nav-item active" onclick="showPage('new-entry')">
<span class="icon">'þ</span><span>New Entry</span>
</button>
<button class="nav-item" onclick="showPage('entries')">
<span class="icon">Ø=ÜÖ</span><span>All Entries</span>
</button>
<button class="nav-item" onclick="showPage('favourites')">
<span class="icon">+P</span><span>Favourites</span>
</button>
<button class="nav-item" onclick="showPage('eras')">
<span class="icon">Ø=ÝÓþ</span><span>Eras</span>
</button>

<button class="nav-item" onclick="showPage('search')">


<span class="icon">Ø=Ý</span><span>Search</span>
</button>
<button class="nav-item" onclick="showPage('stats')">
<span class="icon">Ø=ÜÊ</span><span>Statistics</span>
</button>
<button class="nav-item" onclick="showPage('braindump')">
<span class="icon">Ø>Ýà</span> Thought Capture
</button>
<button class="nav-item" onclick="showPage('other')">
<span class="icon">Ø=ÝÂþ</span><span>Other</span>
</button>
<button class="nav-item" onclick="showPage('backup')">
<span class="icon">Ø=ܾ</span><span>Backup</span>
</button>
<button class="nav-item" onclick="showPage('settings')">
<span class="icon">&™þ</span><span>Settings</span>
</button>

</div>
<div class="sidebar-footer">
<button class="theme-toggle" onclick="toggleTheme()">
<span>Ø<ß Dark Mode</span>
<div class="toggle-pill" id="dark-toggle"><div
class="toggle-knob"></div></div>
</button>
</div>
</nav>

<!-- BOTTOM NAV (mobile) -->


<nav id="bottom-nav">
<button class="bnav-item active" onclick="showPage('new-entry')"
id="bnav-new-entry"><span
class="bicon">'þ</span><span>Write</span></button>
<button class="bnav-item" onclick="showPage('entries')"
id="bnav-entries"><span
class="bicon">Ø=ÜÖ</span><span>Entries</span></button>
<button class="bnav-item" onclick="showPage('favourites')"
id="bnav-favourites"><span
class="bicon">+P</span><span>Stars</span></button>
<button class="bnav-item" onclick="showPage('eras')"
id="bnav-eras"><span
class="bicon">Ø=ÝÓþ</span><span>Eras</span></button>
<button class="bnav-item" onclick="showPage('search')"
id="bnav-search"><span
class="bicon">Ø=Ý</span><span>Search</span></button>
<button class="bnav-item" onclick="showPage('stats')"
id="bnav-stats"><span
class="bicon">Ø=ÜÊ</span><span>Stats</span></button>
<button class="bnav-item" onclick="showPage('braindump')"
id="bnav-braindump"><span
class="bicon">Ø>Ýà</span><span>Capture</span></button>
<button class="bnav-item" onclick="showPage('other')"
id="bnav-other"><span
class="bicon">Ø=ÝÂþ</span><span>Other</span></button>
<button class="bnav-item" onclick="showPage('backup')"
id="bnav-backup"><span
class="bicon">Ø=ܾ</span><span>Backup</span></button>
<button class="bnav-item" onclick="showPage('settings')"
id="bnav-settings"><span
class="bicon">&™þ</span><span>Settings</span></button>

</nav>

<!-- MAIN -->


<div id="main">
<div class="topbar">
<h2 id="page-title">New Entry</h2>
<span class="topbar-meta" id="live-clock"></span>
</div>

<!-- ======= NEW ENTRY PAGE ======= -->


<div class="page active" id="page-new-entry">
<!-- Date/Time & Total Timer row -->
<div class="entry-meta-row" style="margin-bottom:18px;">
<div>
<label class="form-label">Ø=ÜÅ Date & Time</label>
<div class="datetime-display" id="entry-datetime">—</div>
</div>
<div>
<label class="form-label">#ñ Total Time (all questions)</label>
<div class="timer-display" id="writing-timer">#ñ 00:00</div>
</div>
</div>

<!-- Meta: mood, category, tags -->


<div class="entry-meta-row-3">
<div>
<label class="form-label">Ø=Þ Mood</label>
<div class="mood-grid" id="mood-grid"></div>
</div>
<div>
<label class="form-label">Ø=ÝÂ Category</label>
<select id="entry-category"
onchange="renderCustomQuestionsForm()">
<option value="">Select category…</option>
</select>
<button class="btn btn-ghost btn-sm" style="margin-top:6px;"
onclick="promptAddCategory()">+ Add new</button>
</div>
<div>
<label class="form-label">Ø<ß÷ Tags <span
style="font-weight:400;text-transform:none;letter-spacing:0">(press
Enter)</span></label>
<div class="tags-input-wrap" id="tags-wrap">
<input class="tags-input" id="tag-input" placeholder="Add tag…"
onkeydown="handleTagInput(event)">
</div>
</div>
</div>

<!-- Custom Questions with per-question timer -->


<div id="cq-section">
<div id="cq-answers"></div>
</div>

<!-- No questions fallback -->


<div id="cq-empty" style="display:none;text-align:center;padding:32px
16px;background:var(--surface);border:1px solid
var(--border);border-radius:var(--radius);margin-bottom:18px;">
<div style="font-size:2rem;margin-bottom:8px;">Ø=ܬ</div>
<p style="font-size:0.88rem;color:var(--text2);">Koi custom question
set nahi hai.</p>
<button class="btn btn-outline btn-sm" style="margin-top:12px;"
onclick="showPage('settings')">&™ Settings mein add karein</button>
</div>

<!-- Title -->


<div class="form-group">
<label class="form-label">Ø=ÜÌ Title <span
style="color:var(--danger);font-size:0.85em;">*</span></label>
<input type="text" id="entry-title" placeholder="Is entry ka title likhein
(zaruri hai)…" required>
</div>

<!-- hidden textarea kept for save logic compatibility -->


<textarea id="entry-text" style="display:none;"></textarea>

<div style="display:flex;align-items:center;gap:10px;flex-wrap:wrap;">
<button class="btn btn-primary" onclick="saveEntry()">Ø=ܾ Save
Entry</button>
<button class="btn btn-outline" onclick="clearEntry()">'
Clear</button>
<span id="draft-status"
style="font-size:0.75rem;color:var(--text2);font-style:italic;"></span>
</div>
</div>

<!-- ======= ALL ENTRIES PAGE ======= -->


<div class="page" id="page-entries">
<div class="section-header">
<h2>All Entries</h2>
<button class="btn btn-outline" onclick="showPage('new-entry')">+
New Entry</button>
</div>
<div id="entries-list-container"></div>
</div>

<!-- ======= QUESTIONS PAGE ======= -->

<!-- ======= FAVOURITES PAGE ======= -->


<div class="page" id="page-favourites">
<div class="section-header"><h2>+P Favourites</h2></div>
<div id="favourites-list" class="entries-list"></div>
</div>

<!-- ======= ERAS PAGE ======= -->


<div class="page" id="page-eras">
<!-- Header row -->
<div style="display:flex;align-items:center;justify-content:space-betwe
en;margin-bottom:16px;flex-wrap:wrap;gap:10px;">
<h2 style="font-family:var(--font-display);font-size:1.5rem;">Ø=ÝÓþ
Eras</h2>
<div style="display:flex;gap:8px;flex-wrap:wrap;">
<button class="btn btn-outline btn-sm" onclick="exportEras()"
title="Eras export karein">+ Export</button>
<label class="btn btn-outline btn-sm" style="cursor:pointer;"
title="Eras import karein">+ Import<input type="file" accept=".json"
style="display:none;" onchange="importEras(event)"></label>
<button class="btn btn-primary btn-sm"
onclick="toggleEraForm()">+ New Era</button>
</div>
</div>

<!-- Era Add Form -->


<div class="era-add-form" id="era-add-form"
style="display:none;margin-bottom:20px;">
<div style="font-weight:700;font-size:0.9rem;color:var(--text);margin-
bottom:4px;">New Era</div>
<div class="era-add-form-row">
<input type="text" id="era-name-input" placeholder="Era name
(e.g. Termux Era)">
</div>
<div class="era-add-form-row">
<input type="date" id="era-start-input">
<span
style="color:var(--text2);font-size:0.82rem;align-self:center;">to</span>
<input type="date" id="era-end-input" placeholder="End
(optional)">
</div>
<div>
<div style="font-size:0.75rem;color:var(--text2);margin-bottom:6px;f
ont-weight:600;text-transform:uppercase;letter-spacing:0.06em;">Color<
/div>
<div class="era-color-picker" id="era-color-picker"></div>
<div
style="display:flex;align-items:center;gap:8px;margin-top:8px;">
<label style="font-size:0.75rem;color:var(--text2);font-weight:600;"
>Custom:</label>
<input type="color" id="era-custom-color" value="#c17f4a"
style="width:36px;height:28px;padding:0 2px;border:1.5px solid var(--bo
rder);border-radius:6px;cursor:pointer;background:var(--surface);"
oninput="setEraCustomColor([Link])">
<button class="btn btn-outline btn-sm"
onclick="addEraCustomColor()" style="font-size:0.75rem;">+ Add to
palette</button>
</div>
</div>
<div style="display:flex;gap:8px;">
<button class="btn btn-primary btn-sm" onclick="saveEra()">Save
Era</button>
<button class="btn btn-outline btn-sm"
onclick="toggleEraForm()">Cancel</button>
</div>
</div>

<!-- Era Legend -->


<div class="era-nav-legend" id="era-legend"></div>

<!-- View toggle + Star filter -->


<div style="display:flex;align-items:center;justify-content:space-betwe
en;flex-wrap:wrap;gap:8px;margin-bottom:14px;">
<div class="era-star-filter" style="margin-bottom:0;">
<button id="era-filter-all" class="active"
onclick="setEraStarFilter('all')">All entries</button>
<button id="era-filter-starred" onclick="setEraStarFilter('starred')">+P
Starred only</button>
</div>
<div style="display:flex;gap:6px;">
<button id="era-view-timeline-btn" class="btn btn-outline btn-sm
active-view-btn" onclick="setEraView('timeline')">&0 Timeline</button>
<button id="era-view-grid-btn" class="btn btn-outline btn-sm"
onclick="setEraView('grid')">"ž Grid</button>
</div>
</div>

<!-- Month nav -->


<div class="era-nav-controls">
<button class="btn btn-outline btn-sm"
onclick="eraMonthNav(-1)">%À</button>
<div class="era-nav-month-label" id="era-month-label">—</div>
<button class="btn btn-outline btn-sm"
onclick="eraMonthNav(1)">%¶</button>
<button class="btn btn-ghost btn-sm"
onclick="eraGoToday()">Today</button>
</div>

<!-- Timeline view -->


<div class="era-timeline" id="era-timeline-container"></div>

<!-- Grid view -->


<div id="era-grid-container" style="display:none;"></div>
</div>

<!-- ======= SEARCH PAGE ======= -->


<div class="page" id="page-search">
<div class="section-header"><h2>Search Entries</h2></div>
<div class="search-bar-wrap">
<span class="search-icon">Ø=Ý</span>
<input type="text" id="search-q" placeholder="Search by keyword,
title, tag…" oninput="doSearch()">
</div>
<div class="filter-row">
<select id="filter-mood" onchange="doSearch()"><option
value="">All Moods</option></select>
<select id="filter-cat" onchange="doSearch()"><option value="">All
Categories</option></select>
<input type="date" id="filter-date-from" onchange="doSearch()"
title="From date">
<input type="date" id="filter-date-to" onchange="doSearch()"
title="To date">
<button class="btn btn-outline btn-sm"
onclick="clearSearch()">Clear Filters</button>
</div>
<div id="search-results"></div>
</div>

<!-- ======= STATS PAGE ======= -->


<div class="page" id="page-stats">
<div class="section-header"><h2>Statistics</h2></div>
<div class="stats-grid" id="stats-grid"></div>
<div class="chart-section">
<h3>Mood Distribution</h3>
<div class="bar-chart" id="mood-chart"></div>
</div>
<div class="chart-section">
<h3>Top Categories</h3>
<div class="bar-chart" id="cat-chart"></div>
</div>
<div class="chart-section">
<h3>Writing Activity (Last 7 days)</h3>
<div class="bar-chart" id="activity-chart"></div>
</div>

<!-- Thought Capture Stats -->


<div class="chart-section" style="border:1.5px solid
var(--accent);background:var(--accent-light);">
<h3 style="color:var(--accent2);">Ø>Ýà Thought Capture
Overview</h3>
<div class="stats-grid" id="bd-stats-grid"
style="margin-bottom:16px;"></div>
<div class="bar-chart" id="bd-cat-chart"></div>
</div>
</div>

<!-- ======= BACKUP PAGE ======= -->


<div class="page" id="page-braindump">
<div class="section-header">
<h2>Ø>Ýà Thought Capture</h2>
<p
style="font-size:0.85rem;color:var(--text2);margin-top:4px;">Capture any
idea or task that crosses your mind — log it here and revisit it later. Stay
focused, stay productive.</p>
</div>

<!-- Add Item -->


<div style="background:var(--surface);border-radius:var(--radius);pad
ding:20px;margin-bottom:16px;box-shadow:var(--shadow);">
<div
style="display:flex;gap:10px;align-items:flex-start;flex-wrap:wrap;">
<div style="flex:1;min-width:200px;">
<textarea id="bd-input" placeholder="What's on your mind? Jot
down any idea, task, or thought — you can write multiple lines here."
style="margin-bottom:8px;min-height:80px;resize:vertical;"></textarea>
<div style="display:flex;gap:8px;flex-wrap:wrap;">
<select id="bd-category" style="width:auto;flex:1;"></select>
<select id="bd-priority" style="width:auto;">
<option value="low">Ø=ßâ Low</option>
<option value="medium">Ø=ßá Medium</option>
<option value="high">Ø=Ý4 High</option>
</select>
</div>
</div>
<button class="btn btn-primary" onclick="addBrainDump()"
style="align-self:flex-start;">+ Add</button>
</div>
</div>

<!-- Custom Categories Manager -->


<details style="background:var(--surface);border-radius:var(--radius);
padding:14px 18px;margin-bottom:16px;box-shadow:var(--shadow);">
<summary style="cursor:pointer;font-weight:600;font-size:0.88rem;c
olor:var(--text2);user-select:none;">Ø=ÝÂ Manage Categories (Add /
Delete)</summary>
<div style="margin-top:14px;">
<div id="bd-cat-list"
style="display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px;"></div>
<div style="display:flex;gap:8px;">
<input type="text" id="bd-new-cat-input" placeholder="Emoji +
name, e.g. Ø<ß® Gaming" style="flex:1;">
<button class="btn btn-primary btn-sm"
onclick="addBDCategory()">+ Add</button>
</div>
<p style="font-size:0.75rem;color:var(--text2);margin-top:8px;">Ø=Ü¡
Start with an emoji followed by the category name — e.g. "Ø<߬ Movies" or
"Ø=ܪ Fitness"</p>
</div>
</details>

<!-- Filter Tabs -->


<div
style="display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px;">
<button class="btn btn-outline btn-sm bd-filter-btn active-filter"
onclick="filterBD('all')" id="bdf-all">All</button>
<button class="btn btn-outline btn-sm bd-filter-btn"
onclick="filterBD('pending')" id="bdf-pending">#ó Pending</button>
<button class="btn btn-outline btn-sm bd-filter-btn"
onclick="filterBD('done')" id="bdf-done">' Done</button>
</div>

<!-- Stats bar -->


<div id="bd-stats" style="font-size:0.8rem;color:var(--text2);margin-bot
tom:14px;font-family:var(--font-mono);"></div>

<!-- List -->


<div id="bd-list"></div>

<!-- Completed Analysis -->


<div id="bd-analysis" style="display:none;margin-top:24px;">
<div class="chart-section" style="border:1.5px solid
var(--success);background:rgba(39,174,96,0.06);">
<h3 style="color:var(--success);">' Completed Tasks —
Breakdown</h3>
<div id="bd-analysis-content"></div>
</div>
</div>
</div>

<div class="page" id="page-backup">


<div class="section-header"><h2>Backup & Restore</h2></div>

<!-- Last Backup Info -->


<div id="last-backup-bar"
style="background:var(--surface2);border:1px solid
var(--border);border-radius:10px;padding:10px 16px;margin-bottom:16p
x;display:flex;flex-wrap:wrap;gap:10px;align-items:center;font-size:0.82r
em;color:var(--text2);">
<span>Ø=ÜÅ <b>Last Journal Backup:</b> <span
id="last-backup-journal">Never</span></span>
<span style="color:var(--border);">|</span>
<span>Ø=ÝÓþ <b>Last Eras Backup:</b> <span
id="last-backup-eras">Never</span></span>
<span style="color:var(--border);">|</span>
<span>&™þ <b>Last Settings Backup:</b> <span
id="last-backup-settings">Never</span></span>
<span style="color:var(--border);">|</span>
<span>Ø>Ýà <b>Last Capture Backup:</b> <span
id="last-backup-capture">Never</span></span>
</div>

<!-- Google Drive Upload Section -->


<div class="backup-section" style="border:2px solid
var(--accent);background:var(--accent-light);">
<h3 style="color:var(--accent2);">&þ Google Drive Upload</h3>
<p
style="font-size:0.82rem;color:var(--text2);margin-bottom:14px;">Flask
server + rclone se seedha Google Drive par upload karo</p>
<div
style="margin-bottom:12px;display:flex;flex-wrap:wrap;gap:6px;">
<span id="flask-status" class="flask-status-badge">#ó
Checking...</span>
<span id="rclone-status" class="flask-status-badge"
style="margin-left:0px;"></span>
</div>
<div class="backup-options" style="margin-bottom:14px;">
<button class="btn btn-primary" onclick="uploadAllToDrive()">&þ
Sab Upload Karo</button>
<button class="btn btn-outline"
onclick="uploadSelectedToDrive()">&þ Selected Upload Karo</button>
<button class="btn btn-outline" onclick="refreshDriveStatus()">Ø=Ý
Drive Status Check</button>
<button class="btn btn-outline" onclick="updateFlaskStatus()">Ø=Ý
Server Check</button>
</div>
<div id="upload-progress-wrap"
style="display:none;margin-bottom:14px;">
<div style="display:flex;justify-content:space-between;align-items:c
enter;margin-bottom:6px;">
<span
style="font-size:0.82rem;font-weight:600;color:var(--accent);"
id="upload-progress-label">Uploading...</span>
<span
style="font-size:0.78rem;color:var(--text2);font-family:var(--font-mono);"
id="upload-progress-count">0 / 0</span>
</div>
<div style="background:var(--border);border-radius:20px;height:12p
x;overflow:hidden;">
<div id="upload-progress-bar" style="height:100%;background:lin
ear-gradient(90deg,var(--accent),var(--accent2));border-radius:20px;widt
h:0%;transition:width 0.3s;"></div>
</div>
<div id="upload-current-entry" style="font-size:0.75rem;color:var(--t
ext2);margin-top:6px;font-style:italic;"></div>
</div>
<div id="upload-result-summary" style="display:none;padding:10px
14px;border-radius:10px;background:var(--surface);border:1px solid
var(--border);margin-bottom:12px;font-size:0.82rem;"></div>
<p style="font-size:0.75rem;color:var(--text2);">Ø=Ü¡ Har nai entry
automatically local save + Drive sync hoti hai</p>
</div>

<!-- Drive Status List -->


<div class="backup-section" id="drive-status-section"
style="display:none;">
<h3>Ø=ÜÊ Drive Upload Status</h3>
<p
style="font-size:0.82rem;color:var(--text2);margin-bottom:12px;">Kaunsi
entries Google Drive pe hain</p>
<div
style="display:flex;gap:8px;margin-bottom:12px;flex-wrap:wrap;">
<span id="drive-stat-uploaded"
style="font-size:0.82rem;padding:4px 12px;background:#e8f5e9;color:#
2e7d32;border-radius:20px;font-weight:600;">' 0 Uploaded</span>
<span id="drive-stat-pending" style="font-size:0.82rem;padding:4px
12px;background:#fff3e0;color:#e65100;border-radius:20px;font-weight:
600;">#ó 0 Pending</span>
</div>
<div id="drive-entries-list"
style="display:flex;flex-direction:column;gap:8px;"></div>
</div>

<!-- Export Journal Entries -->


<div class="backup-section">
<h3>Ø=ÜÔ Journal Entries Backup</h3>
<p style="font-size:0.85rem;color:var(--text2);margin-bottom:14px;">
Download journal entries by date range</p>
<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:center;m
argin-bottom:14px;padding:12px;background:var(--surface2);border-radi
us:10px;border:1px solid var(--border);">
<div style="display:flex;flex-direction:column;gap:4px;flex:1;min-wid
th:120px;">
<label style="font-size:0.72rem;font-weight:600;color:var(--text2);t
ext-transform:uppercase;letter-spacing:0.06em;">From</label>
<input type="date" id="backup-date-from"
style="font-size:0.82rem;padding:7px 10px;">
</div>
<div style="display:flex;flex-direction:column;gap:4px;flex:1;min-wid
th:120px;">
<label style="font-size:0.72rem;font-weight:600;color:var(--text2);t
ext-transform:uppercase;letter-spacing:0.06em;">To</label>
<input type="date" id="backup-date-to"
style="font-size:0.82rem;padding:7px 10px;">
</div>
<div style="display:flex;flex-direction:column;gap:4px;">
<label style="font-size:0.72rem;font-weight:600;color:var(--text2);t
ext-transform:uppercase;letter-spacing:0.06em;">Quick</label>
<select id="backup-quick-range"
onchange="applyBackupQuickRange()"
style="font-size:0.82rem;padding:7px 10px;">
<option value="">Custom</option>
<option value="7">Last 7 days</option>
<option value="30">Last 30 days</option>
<option value="90">Last 3 months</option>
<option value="180">Last 6 months</option>
<option value="365">Last 1 year</option>
<option value="all">All time</option>
</select>
</div>
<button class="btn btn-outline btn-sm"
onclick="applyBackupDateFilter()" style="align-self:flex-end;">Ø=Ý
Filter</button>
<button class="btn btn-ghost btn-sm" onclick="clearBackupFilter()"
style="align-self:flex-end;">' Clear</button>
</div>
<div id="backup-filter-info" style="font-size:0.8rem;color:var(--text2);
margin-bottom:10px;font-family:var(--font-mono);"></div>
<div class="backup-options">
<button class="btn btn-primary" onclick="exportAll('json')">+ Export
All (JSON)</button>
<button class="btn btn-outline" onclick="exportFiltered('json')">+
Export Filtered</button>
<button class="btn btn-outline"
onclick="exportSelected('json')">Export Selected (JSON)</button>
<button class="btn btn-outline" onclick="exportZip()">Ø=ÝÜ Export
ZIP</button>
</div>
</div>

<!-- Eras Backup -->


<div class="backup-section">
<h3>Ø=ÝÓþ Eras Backup</h3>
<p
style="font-size:0.85rem;color:var(--text2);margin-bottom:14px;">Export
or import your Era definitions</p>
<div class="backup-options">
<button class="btn btn-primary" onclick="exportErasBackup()">+
Export Eras (JSON)</button>
<label class="btn btn-outline" style="cursor:pointer;">+ Import Eras
<input type="file" accept=".json" style="display:none"
onchange="importErasBackup(event)"></label>
</div>
</div>
<!-- Settings Backup -->
<div class="backup-section">
<h3>&™þ Settings Backup</h3>
<p
style="font-size:0.85rem;color:var(--text2);margin-bottom:14px;">Backup
all settings — moods, categories, custom questions, appearance</p>
<div class="backup-options">
<button class="btn btn-primary"
onclick="exportSettingsBackup()">+ Export Settings (JSON)</button>
<label class="btn btn-outline" style="cursor:pointer;">+ Import
Settings <input type="file" accept=".json" style="display:none"
onchange="importSettingsBackup(event)"></label>
</div>
</div>

<!-- Thought Capture Backup -->


<div class="backup-section">
<h3>Ø>Ýà Thought Capture Backup</h3>
<p
style="font-size:0.85rem;color:var(--text2);margin-bottom:14px;">Backup
all captured thoughts and custom categories</p>
<div class="backup-options">
<button class="btn btn-primary"
onclick="exportCaptureBackup()">+ Export Capture (JSON)</button>
<label class="btn btn-outline" style="cursor:pointer;">+ Import
Capture <input type="file" accept=".json" style="display:none"
onchange="importCaptureBackup(event)"></label>
</div>
</div>

<!-- Import -->


<div class="backup-section">
<h3>Ø=Üå Import Journal Entries</h3>
<div class="backup-options">
<label class="btn btn-outline" style="cursor:pointer;">Ø=ÜÂ Import
JSON (Multiple) <input type="file" accept=".json" style="display:none"
multiple onchange="importFile(event,'json')"></label>
</div>
<p style="font-size:0.78rem;color:var(--text2);margin-top:8px;">Ø=Ü¡
Ctrl+Click or Shift+Click to select multiple files at once!</p>
</div>

<!-- Select Entries -->


<div class="backup-section">
<h3>Ø=ÜË Select Entries</h3>
<div
style="display:flex;gap:8px;margin-bottom:12px;flex-wrap:wrap;">
<button class="btn btn-outline btn-sm"
onclick="selectAllBackup()">Select All</button>
<button class="btn btn-outline btn-sm"
onclick="deselectAllBackup()">Deselect All</button>
<span id="backup-selected-count"
style="font-size:0.82rem;color:var(--text2);align-self:center;"></span>
</div>
<div id="backup-entries-list"></div>
</div>
</div>

<!-- ======= SETTINGS PAGE ======= -->


<div class="page" id="page-settings">
<div class="section-header"><h2>Settings</h2></div>

<div class="settings-section">
<h3>Ø<ߨ Appearance</h3>
<div class="setting-row">
<div class="setting-info"><h4>Dark Theme</h4><p>Save your
theme preference</p></div>
<button class="btn btn-outline btn-sm"
onclick="toggleTheme()">Toggle</button>
</div>
<div class="setting-row">
<div class="setting-info"><h4>Font Size</h4><p>Entry text
size</p></div>
<select id="font-size-sel" onchange="changeFontSize()"
style="width:130px">
<option value="0.9rem">Normal</option>
<option value="1.05rem">Large</option>
<option value="1.18rem">X-Large</option>
</select>
</div>
</div>

<div class="settings-section">
<h3>Ø=ܬ Custom Questions</h3>
<p
style="font-size:0.82rem;color:var(--text2);margin-bottom:12px;">These
questions appear in each new entry</p>
<div class="cq-list" id="settings-cq-list"></div>
<div class="add-inline-wrap" style="margin-top:12px;">
<input type="text" id="new-cq-input" placeholder="Type a
question…">
<button class="btn btn-primary btn-sm"
onclick="addCustomQuestion()">+ Add</button>
</div>
</div>

<div class="settings-section" id="settings-catq-section">


<h3>Ø=ÜÂ Category-wise Questions</h3>
<p
style="font-size:0.82rem;color:var(--text2);margin-bottom:12px;">Kisi
specific category ke liye extra questions add karo — sirf woh category
select karne par dikhenge</p>
<div style="display:flex;gap:8px;align-items:center;margin-bottom:14
px;flex-wrap:wrap;">
<select id="catq-category-sel" onchange="renderCategoryQList()"
style="flex:1;min-width:140px;">
<option value="">-- Category chunein --</option>
</select>
<span id="catq-count-badge" style="font-size:0.75rem;color:var(--a
ccent);font-weight:600;white-space:nowrap;"></span>
</div>
<div id="catq-list" style="margin-bottom:10px;"></div>
<div class="add-inline-wrap" id="catq-add-wrap"
style="margin-top:8px;display:none;">
<input type="text" id="new-catq-input" placeholder="Category ke
liye question likhein…">
<button class="btn btn-primary btn-sm"
onclick="addCategoryQuestion()">+ Add</button>
</div>
</div>

<div class="settings-section">
<h3>Ø=ÝÂ Custom Categories</h3>
<div class="cat-list" id="settings-cat-list"></div>
<div class="add-inline-wrap" style="margin-top:12px;">
<input type="text" id="new-cat-input" placeholder="New
category…">
<button class="btn btn-primary btn-sm" onclick="addCategory()">+
Add</button>
</div>
</div>

<div class="settings-section">
<h3>Ø=Þ Mood Options</h3>
<div class="mood-grid" id="settings-mood-preview"></div>
<div class="add-inline-wrap" style="margin-top:12px;">
<input type="text" id="new-mood-input" placeholder="New mood
emoji + label e.g. Ø>Ý) Amazing">
<button class="btn btn-primary btn-sm" onclick="addMood()">+
Add</button>
</div>
</div>

<div class="settings-section">
<h3>Ø=ÜÁ Local Save + rclone Config</h3>
<p
style="font-size:0.82rem;color:var(--text2);margin-bottom:14px;">Har nai
entry automatically local save hogi aur rclone se Google Drive par sync
hogi</p>
<div style="margin-bottom:12px;">
<span id="flask-status" class="flask-status-badge">#ó Server check
ho raha hai...</span>
<span id="rclone-status" class="flask-status-badge"
style="margin-left:8px;"></span>
</div>
<div class="form-group">
<label class="form-label">Ø=ÜÂ Save Path (Local)</label>
<input type="text" id="flask-journal-dir"
placeholder="/storage/emulated/0/Journal">
<p
style="font-size:0.73rem;color:var(--text2);margin-top:4px;">Entries
yahan save hongi</p>
</div>
<div class="form-group">
<label class="form-label">&þ rclone Remote Path</label>
<input type="text" id="flask-rclone-remote"
placeholder="gdrive:Journal">
<p
style="font-size:0.73rem;color:var(--text2);margin-top:4px;">Format:
remote_name:folder (e.g. gdrive:MyJournal)</p>
</div>
<div class="setting-row" style="margin-bottom:12px;">
<div class="setting-info"><h4>Auto rclone Sync</h4><p>Har entry
save pe Drive par sync</p></div>
<label
style="display:flex;align-items:center;gap:8px;cursor:pointer;">
<input type="checkbox" id="flask-rclone-toggle"
style="width:auto;" checked>
<span
style="font-size:0.82rem;color:var(--text2);">Enable</span>
</label>
</div>
<div style="display:flex;gap:8px;flex-wrap:wrap;">
<button class="btn btn-primary btn-sm"
onclick="saveFlaskConfig()">Ø=ܾ Config Save Karo</button>
<button class="btn btn-outline btn-sm"
onclick="manualRcloneSync()">&þ Abhi Sync Karo</button>
<button class="btn btn-outline btn-sm"
onclick="updateFlaskStatus()">Ø=Ý Status Check</button>
</div>
<div style="margin-top:12px;background:var(--surface2);border-radiu
s:10px;padding:12px
14px;font-size:0.78rem;color:var(--text2);line-height:1.8;">
<b style="color:var(--accent);">rclone setup (ek baar):</b><br>
1. Termux: <code>pkg install rclone</code><br>
2. <code>rclone config</code> !’ n !’ name: gdrive !’ type: drive !’
follow steps<br>
3. Upar remote name daalo (e.g. gdrive:Journal) '
</div>
</div>

<div class="settings-section">
<h3>Ø=ÝÑ Data Management</h3>
<div class="setting-row">
<div class="setting-info"><h4>Clear All
Entries</h4><p>Permanently delete all journal entries</p></div>
<button class="btn btn-danger btn-sm"
onclick="clearAllData()">Clear All</button>
</div>
</div>
</div>

<!-- ======= OTHER PAGE ======= -->


<div class="page" id="page-other">
<div class="section-header">
<h2>Ø=ÝÂþ Other Apps</h2>
<p
style="font-size:0.85rem;color:var(--text2);margin-top:4px;">Custom
HTML tools — app icons ki tarah save karo aur ek tap mein kholo.</p>
</div>

<!-- Upload new HTML file -->


<div style="background:var(--surface);border-radius:var(--radius);pad
ding:20px;margin-bottom:18px;box-shadow:var(--shadow);border:1px
solid var(--border);">
<h3 style="font-family:var(--font-display);font-size:1rem;color:var(--te
xt);margin-bottom:14px;padding-bottom:10px;border-bottom:1px solid
var(--border);">'• Naya App Add Karo</h3>
<div style="display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap
;margin-bottom:10px;">
<div style="flex:1;min-width:140px;">
<label class="form-label">App ka naam</label>
<input type="text" id="other-fname" placeholder="e.g. Budget,
Habit Tracker">
</div>
<div style="min-width:100px;">
<label class="form-label">Icon</label>
<div style="display:flex;gap:6px;align-items:center;">
<span id="other-icon-preview"
style="font-size:1.6rem;cursor:pointer;padding:4px
8px;background:var(--surface2);border-radius:8px;border:1.5px solid
var(--border);" onclick="toggleIconPicker()">Ø>Ýé</span>
<span style="font-size:0.75rem;color:var(--text2);">tap to
change</span>
</div>
</div>
<label class="btn btn-outline"
style="cursor:pointer;margin-bottom:0;white-space:nowrap;">
Ø=ÜÂ File Choose Karo
<input type="file" accept=".html,.htm" id="other-file-input"
style="display:none;" onchange="otherFileChosen(event)">
</label>
<button class="btn btn-primary" onclick="uploadOtherFile()"
style="white-space:nowrap;">Ø=ܾ Save Karo</button>
</div>
<!-- Icon picker -->
<div id="other-icon-picker" style="display:none;margin:10px 0;paddi
ng:12px;background:var(--surface2);border-radius:10px;border:1px solid
var(--border);">
<div style="font-size:0.75rem;font-weight:600;color:var(--text2);text
-transform:uppercase;letter-spacing:0.07em;margin-bottom:8px;">Icon
choose karo</div>
<div id="other-icon-grid"
style="display:flex;flex-wrap:wrap;gap:6px;"></div>
</div>
<div id="other-file-info"
style="font-size:0.78rem;color:var(--text2);min-height:18px;"></div>
</div>

<!-- App Grid -->


<div style="background:var(--surface);border-radius:var(--radius);pad
ding:20px;box-shadow:var(--shadow);border:1px solid var(--border);">
<div style="display:flex;align-items:center;justify-content:space-betw
een;margin-bottom:16px;padding-bottom:10px;border-bottom:1px solid
var(--border);">
<h3
style="font-family:var(--font-display);font-size:1rem;color:var(--text);">Ø=Üñ
My Apps</h3>
<button class="btn btn-outline btn-sm" onclick="loadOtherList()">Ø=Ý
Refresh</button>
</div>
<div id="other-files-list">
<div style="text-align:center;padding:30px;color:var(--text2);">
<div style="font-size:2rem;margin-bottom:8px;">Ø=Üí</div>
<div style="font-size:0.85rem;">Koi app nahi. Upar se add
karo!</div>
</div>
</div>
</div>

</div>

</div>

<!-- ======= MODAL: Entry Detail ======= -->


<div class="modal-overlay" id="detail-modal">
<div class="modal">
<button class="modal-close"
onclick="closeModal('detail-modal')">'</button>
<div id="detail-modal-content"></div>
<div style="display:flex;gap:8px;flex-wrap:wrap;margin-top:18px;paddi
ng-top:14px;border-top:1px solid var(--border);">
<button class="btn btn-primary" onclick="editCurrentEntry()">'
Edit</button>
<button class="btn btn-outline" id="detail-star-btn"
onclick="toggleStarCurrent()">& Favourite</button>
<button class="btn btn-outline" onclick="exportEntry('json')">+
JSON</button>
<button class="btn btn-danger" onclick="deleteCurrentEntry()">Ø=ÝÑ
Delete</button>
</div>
</div>
</div>

<!-- ======= MODAL: Edit Entry ======= -->


<div class="modal-overlay" id="edit-modal">
<div class="modal">
<button class="modal-close"
onclick="closeModal('edit-modal')">'</button>
<h2 class="modal-title">Edit Entry</h2>
<div class="form-group">
<label class="form-label">Title</label>
<input type="text" id="edit-title">
</div>
<div class="form-group">
<label class="form-label">Entry</label>
<textarea id="edit-text" style="min-height:200px;"></textarea>
</div>
<div class="form-group">
<label class="form-label">Mood</label>
<div class="mood-grid" id="edit-mood-grid"></div>
</div>
<div class="form-group">
<label class="form-label">Category</label>
<select id="edit-category"></select>
</div>
<div class="form-group">
<label class="form-label">Tags</label>
<div class="tags-input-wrap" id="edit-tags-wrap">
<input class="tags-input" id="edit-tag-input" placeholder="Add
tag…" onkeydown="handleEditTagInput(event)">
</div>
</div>
<button class="btn btn-primary" onclick="saveEdit()">Ø=ܾ Save
Changes</button>
</div>
</div>

<!-- ======= SAVE LOCALLY MODAL ======= -->


<div class="modal-overlay" id="save-local-modal">
<div class="modal" style="max-width:440px;">
<button class="modal-close"
onclick="closeModal('save-local-modal')">'</button>
<h2 class="modal-title">Ø=ܾ Save to Device</h2>
<p
style="font-size:0.85rem;color:var(--text2);margin-bottom:18px;">Entry
browser mein save ho gayi '<br>Ab device storage mein bhi save
karein?</p>
<div class="form-group">
<label class="form-label">Format</label>
<div style="display:flex;gap:10px;">
<label id="fmt-json" style="cursor:pointer;padding:12px
14px;border:2px solid var(--accent);border-radius:10px;text-align:center;
background:var(--accent-light);flex:1;">
<div style="font-size:1.4rem;">Ø=ÝÂ</div>
<div style="font-size:0.82rem;font-weight:700;color:var(--accent);
margin-top:4px;">JSON</div>
<div style="font-size:0.72rem;color:var(--text2);">.json</div>
</label>
</div>
<input type="hidden" id="local-save-format" value="json">
</div>

<div
style="background:var(--surface2);border-radius:10px;padding:12px 14p
x;margin-bottom:14px;font-size:0.82rem;color:var(--text2);line-height:1.6
;">
<b style="color:var(--accent);">!9þ Kaise kaam karta hai:</b><br>
"Save Karein" dabate hi aapka browser <b>Save As dialog</b>
kholega — aap khud koi bhi folder choose kar sakte ho (Downloads,
Documents, ya koi bhi jagah). Folder lock nahi hoga! '
</div>

<div style="display:flex;gap:10px;margin-top:4px;">
<button class="btn btn-primary" style="flex:1;"
onclick="confirmLocalSave()">Ø=ܾ Save Karein</button>
<button class="btn btn-outline" onclick="rcloneSyncEntry()"
title="rclone se Drive par sync karo">&þ Drive Sync</button>
<button class="btn btn-outline"
onclick="closeModal('save-local-modal')">Skip</button>
</div>
</div>
</div>

<div class="toast" id="toast"></div>

<script src="[Link]
s"></script>
<script>
// =====================================
// STATE & STORAGE
// =====================================
let state = {
entries: [],
settings: {
dark: false,
customQuestions: [],
categoryQuestions: {}, // {categoryName: [q1, q2, ...]}
categories:
['Personal','Work','Travel','Health','Goals','Gratitude','Dreams','Ideas'],
moods: ['Ø=Þ Happy','Ø=Þ Calm','Ø=Þ Sad','Ø=Þ$ Angry','Ø=Þ0 Anxious','Ø>
Tired','Ø=Þ Excited','Ø>Ý Thoughtful','Ø=Þ6 Neutral','Ø>Ýp Grateful'],
fontSize: '0.9rem',
eras: []
}
};

let currentPage = 'new-entry';


let currentDetailId = null;
let editTags = [];
let newEntryTags = [];
let timerInterval = null;
let timerSeconds = 0;
let timerStarted = false;
let pendingSaveEntry = null;

// =====================================
// FLASK API CONFIG
// =====================================
const FLASK_API = '[Link]
let flaskConfig = { journal_dir: '/storage/emulated/0/Journal',
rclone_remote: 'gdrive:Journal', rclone_enabled: true };

async function loadFlaskConfig() {


try {
const r = await fetch(`${FLASK_API}/config`);
if ([Link]) flaskConfig = await [Link]();
renderFlaskConfigUI();
} catch {}
}

function renderFlaskConfigUI() {
const dirEl = [Link]('flask-journal-dir');
const remoteEl = [Link]('flask-rclone-remote');
const toggleEl = [Link]('flask-rclone-toggle');
if (dirEl) [Link] = flaskConfig.journal_dir || '';
if (remoteEl) [Link] = flaskConfig.rclone_remote || '';
if (toggleEl) [Link] = flaskConfig.rclone_enabled;
// Status update
updateFlaskStatus();
}

async function updateFlaskStatus() {


const statusEl = [Link]('flask-status');
const rcloneStatusEl = [Link]('rclone-status');
if (!statusEl) return;
try {
const r = await fetch(`${FLASK_API}/check_rclone`);
const d = await [Link]();
if (rcloneStatusEl) {
if ([Link]) {
[Link] = `' rclone available · Remotes:
${[Link](', ') || 'none'}`;
[Link] = 'flask-status-badge ok';
} else {
[Link] = ''L rclone nahi mila — pkg install
rclone';
[Link] = 'flask-status-badge err';
}
}
[Link] = '' Server connected';
[Link] = 'flask-status-badge ok';
} catch {
if (statusEl) { [Link] = ''L Server nahi mila — python
journal_server.py chalao'; [Link] = 'flask-status-badge err';
}
}
}
async function saveFlaskConfig() {
const dir = [Link]('flask-journal-dir')?.[Link]();
const remote =
[Link]('flask-rclone-remote')?.[Link]();
const enabled =
[Link]('flask-rclone-toggle')?.checked;
try {
const r = await fetch(`${FLASK_API}/config`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ journal_dir: dir, rclone_remote: remote,
rclone_enabled: enabled })
});
const d = await [Link]();
flaskConfig = { journal_dir: d.journal_dir, rclone_remote:
d.rclone_remote, rclone_enabled: enabled };
showToast('' Config save ho gaya!');
} catch {
showToast(''L Server se connect nahi hua!');
}
}

async function saveEntryToFlask(entry, fmt = 'txt', autoSync = true) {


try {
const r = await fetch(`${FLASK_API}/save`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ entry, fmt, auto_sync: autoSync })
});
const d = await [Link]();
if ([Link] === 'ok') {
let msg = `' Local save: ${[Link]}`;
if ([Link]?.status === 'success') msg += ' · &þ Drive sync!';
else if ([Link]?.status === 'error') msg += ` · & þ rclone:
${[Link]}`;
showToast(msg);
return d;
} else {
showToast('& þ Save error: ' + ([Link] || 'unknown'));
}
} catch {
showToast('& þ Flask server nahi mila — sirf LocalStorage mein save
hua');
}
return null;
}

async function manualRcloneSync(filename) {


showToast('#ó rclone sync ho raha hai...');
try {
const body = filename ? { filename } : {};
const r = await fetch(`${FLASK_API}/sync`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link](body)
});
const d = await [Link]();
if ([Link] === 'success') showToast('&þ ' + [Link]);
else showToast(''L ' + [Link]);
} catch {
showToast(''L Server se connect nahi hua!');
}
}

async function flaskSaveAll() {


if (![Link]) { showToast('& þ Koi entry nahi!'); return; }
showToast('#ó Sari entries save ho rahi hain...');
try {
const r = await fetch(`${FLASK_API}/save_all`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ entries: [Link] })
});
const d = await [Link]();
if ([Link] === 'ok') {
let msg = `' ${[Link]} entries saved: ${[Link]}`;
if ([Link]?.status === 'success') msg += ' · &þ Drive!';
showToast(msg);
}
} catch {
showToast(''L Server se connect nahi hua!');
}
}

// =====================================
// DRIVE UPLOAD WITH PROGRESS
// =====================================
let driveUploadedFiles = []; // Drive pe existing files ki list

async function refreshDriveStatus() {


showToast('#ó Drive status check ho raha hai...');
try {
const r = await fetch(`${FLASK_API}/drive_status`);
const d = await [Link]();
if ([Link] === 'ok') {
driveUploadedFiles = [Link] || [];
renderDriveStatusList();
showToast(`' Drive check ho gaya — ${[Link]}
files mili`);
} else if ([Link] === 'disabled') {
showToast('& þ rclone disabled hai — Settings mein enable karo');
} else {
showToast(''L Drive check fail: ' + ([Link] || 'unknown error'));
}
} catch {
showToast(''L Server se connect nahi hua!');
}
}

function entryFilename(entry) {
const slug = ([Link] || 'entry').replace(/[^a-zA-Z0-9]/g,
'_').toLowerCase().slice(0, 40);
const dateStr = ([Link] || new Date().toISOString()).slice(0, 10);
const entryId = ([Link] || 'unknown').slice(0, 8);
return `${dateStr}_${slug}_${entryId}.json`;
}

function isEntryOnDrive(entry) {
const entryId = ([Link] || '').slice(0, 8);
const dateStr = ([Link] || '').slice(0, 10);
const exactName = entryFilename(entry);

return [Link](f => {


const fname = [Link]().toLowerCase();
// 1. Exact match
if (fname === [Link]()) return true;
// 2. Entry ID se match (sabse reliable)
if (entryId && [Link]([Link]())) return true;
// 3. Date + title ke pehle 10 chars se match
if (dateStr && [Link](dateStr)) {
const titleSlug = ([Link] || '').replace(/[^a-zA-Z0-9]/g,
'_').toLowerCase().slice(0, 10);
if (titleSlug && [Link](titleSlug)) return true;
}
return false;
});
}

function renderDriveStatusList() {
const section = [Link]('drive-status-section');
const listEl = [Link]('drive-entries-list');
if (!section || !listEl) return;
[Link] = '';

const uploaded = [Link](e => isEntryOnDrive(e));


const pending = [Link](e => !isEntryOnDrive(e));

[Link]('drive-stat-uploaded').textContent = `'
${[Link]} Uploaded`;
[Link]('drive-stat-pending').textContent = `#ó
${[Link]} Pending`;

[Link] = '';

// Drive pe total files info


if ([Link] > 0) {
const infoDiv = [Link]('div');
[Link] =
'font-size:0.72rem;color:var(--text2);margin-bottom:8px;padding:8px
12px;background:var(--surface2);border-radius:8px;';
[Link] = `<b>Drive pe mili files
(${[Link]}):</b>
${[Link](0,3).join(', ')}${[Link] > 3
? ` ...+${[Link]-3} aur` : ''}`;
[Link](infoDiv);
}

// Pending entries pehle


[...pending, ...uploaded].forEach(entry => {
const onDrive = isEntryOnDrive(entry);
const card = [Link]('div');
[Link] =
`display:flex;align-items:center;gap:10px;padding:10px
14px;border-radius:10px;border:1px solid ${onDrive ? '#a5d6a7' :
'var(--border)'};background:${onDrive ?
([Link]('dark') ? '#1a3a1f' : '#f1f8f1') :
'var(--surface)'};margin-bottom:2px;`;

const statusDot = [Link]('div');


[Link] = `width:10px;height:10px;border-radius:50%;
flex-shrink:0;background:${onDrive ? '#4caf50' : 'var(--border)'};`;

const info = [Link]('div');


[Link] = 'flex:1;min-width:0;';
[Link] = `<div style="font-size:0.85rem;font-weight:600;color
:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">$
{[Link] || 'Untitled'}</div>
<div style="font-size:0.72rem;color:var(--text2);font-family:var(--font-
mono);">${([Link]||'').slice(0,10)} · ${onDrive ? '&þ Drive pe hai' : '#ó
Upload nahi hua'}</div>`;

[Link](statusDot);
[Link](info);

if (!onDrive) {
const btn = [Link]('button');
[Link] = 'btn btn-outline btn-sm';
[Link] = '&þ Upload';
[Link] = `drive-upload-btn-${[Link]}`;
[Link] = () => uploadSingleEntryToDrive(entry);
[Link](btn);
} else {
const badge = [Link]('span');
[Link] =
'font-size:0.72rem;color:#4caf50;font-weight:700;white-space:nowrap;';
[Link] = '' Done';
[Link](badge);
}

[Link](card);
});
}

async function uploadSingleEntryToDrive(entry) {


const btn = [Link](`drive-upload-btn-${[Link]}`);
if (btn) { [Link] = true; [Link] = '#ó...'; }
try {
const r = await fetch(`${FLASK_API}/upload_entry`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ entry })
});
const d = await [Link]();
if ([Link] === 'success') {
[Link]([Link]);
showToast(`' "${[Link]}" Drive pe upload ho gaya!`);
renderDriveStatusList();
} else {
showToast(''L Upload fail: ' + ([Link] || 'error'));
if (btn) { [Link] = false; [Link] = '&þ Upload'; }
}
} catch {
showToast(''L Server se connect nahi hua!');
if (btn) { [Link] = false; [Link] = '&þ Upload'; }
}
}

async function uploadAllToDrive() {


if (![Link]) { showToast('& þ Koi entry nahi!'); return; }
const entriesToUpload = [Link]; // sab upload karo
await runDriveUpload(entriesToUpload);
}

async function uploadSelectedToDrive() {


const ids = getSelectedIds();
if (![Link]) { showToast('& þ Pehle entries select karo niche se!');
return; }
const selected = [Link](e => [Link]([Link]));
await runDriveUpload(selected);
}

async function runDriveUpload(entries) {


if (![Link]) return;

const wrap = [Link]('upload-progress-wrap');


const bar = [Link]('upload-progress-bar');
const label = [Link]('upload-progress-label');
const countEl = [Link]('upload-progress-count');
const currentEl = [Link]('upload-current-entry');
const summaryEl =
[Link]('upload-result-summary');

[Link] = '';
[Link] = 'none';
[Link] = '0%';
[Link] = 'Uploading...';

let success = 0, failed = 0;


const failedEntries = [];

for (let i = 0; i < [Link]; i++) {


const entry = entries[i];
const pct = [Link](((i) / [Link]) * 100);
[Link] = pct + '%';
[Link] = `${i} / ${[Link]}`;
[Link] = `Ø=ÜÝ "${[Link] || 'Untitled'}" upload ho raha
hai...`;

try {
const r = await fetch(`${FLASK_API}/upload_entry`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ entry })
});
const d = await [Link]();
if ([Link] === 'success') {
success++;
if (![Link]([Link]))
[Link]([Link]);
} else {
failed++;
[Link]([Link] || 'Untitled');
}
} catch {
failed++;
[Link]([Link] || 'Untitled');
}
}

// 100% complete
[Link] = '100%';
[Link] = `${[Link]} / ${[Link]}`;
[Link] = '';
[Link] = failed === 0 ? '' Upload complete!' : `& þ ${failed}
fail hua`;

// Summary
[Link] = '';
if (failed === 0) {
[Link] = 'display:block;padding:10px
14px;border-radius:10px;background:#e8f5e9;border:1px solid
#a5d6a7;font-size:0.82rem;color:#2e7d32;';
[Link] = `' <b>${success} entries</b> successfully
Google Drive pe upload ho gayi!`;
} else {
[Link] = 'display:block;padding:10px
14px;border-radius:10px;background:#fff3e0;border:1px solid
#ffcc80;font-size:0.82rem;color:#e65100;';
[Link] = `& þ <b>${success} success</b>,
<b>${failed} fail</b><br><span style="font-size:0.75rem;">Failed:
${[Link](0,3).join(', ')}${[Link]>3?'
...':''}</span>`;
}

// Drive status list refresh


renderDriveStatusList();
setTimeout(() => { [Link] = 'none'; }, 3000);
}

function saveState() {
[Link]('journal_data', [Link](state));
// Category questions ko bhi Flask par save karo (async, silent)
if ([Link]) {
fetch(FLASK_API + '/category_questions', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: [Link]({categoryQuestions:
[Link]})
}).catch(function(){});
}
// Flask server pe bhi save karo (device storage)
flaskSaveState();
}

async function flaskSaveState() {


try {
// Entries save karo
await fetch(`${FLASK_API}/entries`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ entries: [Link] })
});
// Settings (categories, moods, questions, eras, theme etc.) save karo
await fetch(`${FLASK_API}/settings`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ settings: [Link] })
});
} catch(e) {
// Server nahi mila — sirf localStorage pe hai, koi baat nahi
}
}

async function loadStateFromFlask() {


try {
const [eRes, sRes, erasRes, cqRes] = await [Link]([
fetch(`${FLASK_API}/entries`),
fetch(`${FLASK_API}/settings`),
fetch(`${FLASK_API}/eras`),
fetch(`${FLASK_API}/category_questions`)
]);
if ([Link]) {
const ed = await [Link]();
if ([Link] && [Link] > 0) {
[Link] = [Link];
}
}
if ([Link]) {
const sd = await [Link]();
if ([Link]) {
[Link] = { ...[Link], ...[Link] };
}
}
// Eras alag file se load karo (agar settings mein nahi hain)
if ([Link]) {
const ed = await [Link]();
if ([Link] && [Link] > 0) {
[Link] = [Link];
}
}
// Category Questions alag file se load karo
if (cqRes && [Link]) {
try {
const cqd = await [Link]();
if ([Link] &&
[Link]([Link]).length > 0) {
[Link] = [Link];
}
} catch(e) {}
}
// LocalStorage bhi update karo
[Link]('journal_data', [Link](state));
} catch(e) {
// Flask nahi mila — localStorage se hi chalega
}
}

function loadState() {
try {
const raw = [Link]('journal_data');
if (raw) {
const saved = [Link](raw);
[Link] = [Link] || [];
if ([Link]) {
[Link] = { ...[Link], ...[Link] };
}
}
} catch(e) {}
}
function genId() { return [Link]().toString(36) +
[Link]().toString(36).substr(2,5); }

// =====================================
// DRAFT AUTOSAVE
// =====================================
const DRAFT_KEY = 'journal_draft';
let draftTimer = null;

function saveDraft() {
const draft = {
title: [Link]('entry-title')?.value || '',
mood: selectedMood,
category: [Link]('entry-category')?.value || '',
tags: [...newEntryTags],
cqAnswers: {},
cqSeconds: {},
savedAt: [Link]()
};
const _draftCat = ([Link]('entry-category') ?
[Link]('entry-category').value : '').trim();
const _draftGlobal = [Link] || [];
const _draftCatQs = ([Link] && _draftCat
&& [Link][_draftCat]) || [];
const _draftAllQs = [..._draftGlobal];
_draftCatQs.forEach(function(q){ if (!_draftAllQs.includes(q))
_draftAllQs.push(q); });
_draftAllQs.forEach(function(q, i) {
const el = [Link]('cq-ans-' + i);
[Link][i] = el ? [Link] : '';
[Link][i] = cqTimers[i] ? cqTimers[i].seconds : 0;
});
[Link](DRAFT_KEY, [Link](draft));
// Flask pe bhi save karo
fetch(`${FLASK_API}/draft`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ draft })
}).catch(() => {});
const ds = [Link]('draft-status');
if (ds) {
const t = new Date().toLocaleTimeString('en-US', {hour:'2-digit',
minute:'2-digit'});
[Link] = '' Draft saved ' + t;
}
}

function clearDraft() {
[Link](DRAFT_KEY);
// Flask se bhi delete karo
fetch(`${FLASK_API}/draft`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ draft: null })
}).catch(() => {});
const ds = [Link]('draft-status');
if (ds) [Link] = '';
}

async function loadDraftFromFlask() {


try {
const r = await fetch(`${FLASK_API}/draft`);
if ([Link]) {
const d = await [Link]();
if ([Link]) {
[Link](DRAFT_KEY, [Link]([Link]));
return true;
}
}
} catch(e) {}
return false;
}

function loadDraft() {
try {
const raw = [Link](DRAFT_KEY);
if (!raw) return false;
const draft = [Link](raw);
// Check if draft is less than 7 days old
if ([Link]() - [Link] > 7 * 24 * 3600 * 1000) { clearDraft();
return false; }

// Restore title
const titleEl = [Link]('entry-title');
if (titleEl && [Link]) [Link] = [Link];

// Restore mood
if ([Link]) { selectedMood = [Link];
renderMoodGrid('mood-grid'); }

// Restore category
const catEl = [Link]('entry-category');
if (catEl && [Link]) [Link] = [Link];

// Restore tags
if ([Link] && [Link]) {
newEntryTags = [Link];
renderTagsInWrap('tags-wrap', newEntryTags, 'removeNewTag');
}
// Restore CQ answers + timer seconds (after questions rendered)
setTimeout(() => {
const _rCat = ([Link]('entry-category') ?
[Link]('entry-category').value : '').trim();
const _rGlobal = [Link] || [];
const _rCatQs = ([Link] && _rCat &&
[Link][_rCat]) || [];
const _rAllQs = [..._rGlobal];
_rCatQs.forEach(function(q){ if (!_rAllQs.includes(q))
_rAllQs.push(q); });
_rAllQs.forEach(function(q, i) {
const el = [Link]('cq-ans-' + i);
if (el && [Link] && [Link][i] !== undefined) {
[Link] = [Link][i];
}
if (cqTimers[i] && [Link] && [Link][i]) {
cqTimers[i].seconds = [Link][i];
const m = String([Link](cqTimers[i].seconds / 60)).padStart(2,
'0');
const s = String(cqTimers[i].seconds % 60).padStart(2, '0');
const el2 = [Link]('cq-time-' + i);
if (el2) [Link] = m + ':' + s;
const badge = [Link]('cq-badge-' + i);
if (badge) [Link]('done');
}
});
// Update total timer display
const total = [Link](cqTimers).reduce((s, t) => s + [Link],
0);
if (total > 0) {
const tm = String([Link](total / 60)).padStart(2, '0');
const ts = String(total % 60).padStart(2, '0');
const wt = [Link]('writing-timer');
if (wt) [Link] = '#ñ ' + tm + ':' + ts;
}
// Show draft restored notice
const ds = [Link]('draft-status');
const ago = [Link](([Link]() - [Link]) / 60000);
const agoStr = ago < 1 ? 'abhi abhi' : ago + ' min pehle';
if (ds) [Link] = 'Ø=ÜÝ Draft restore hua (' + agoStr + ')';
}, 100);
return true;
} catch(e) { return false; }
}

function startDraftAutosave() {
// Save draft every 3 seconds when something changes
['entry-title', 'entry-category'].forEach(id => {
const el = [Link](id);
if (el) [Link]('input', scheduleDraftSave);
});
// For textareas inside cq-answers, use event delegation
[Link]('cq-answers')?.addEventListener('input',
scheduleDraftSave);
[Link]('tags-wrap')?.addEventListener('input',
scheduleDraftSave);
}

function scheduleDraftSave() {
clearTimeout(draftTimer);
draftTimer = setTimeout(saveDraft, 1500);
}

// =====================================
// INIT
// =====================================
function init() {
loadState(); // pehle localStorage se fast load
applyTheme();
applyFontSize();
renderMoodGrid('mood-grid');
renderMoodGrid('edit-mood-grid');
renderMoodPreview();
renderCategories();
populateCategorySelect('entry-category');
populateCategorySelect('edit-category');
renderCustomQuestionsForm();
renderSettingsCQ(); populateCatQSelector();
renderSettingsCats();
startClock();
startWritingTimer();
startDraftAutosave();
refreshPage();
// Flask config + data load (async)
loadFlaskConfig();
loadFlaskDataOnStartup();
loadBDFromFlask();
loadBDCategoriesFromFlask();
}

async function loadFlaskDataOnStartup() {


// Pehle flask se latest data load karo
await loadStateFromFlask();
// Draft bhi flask se load karo agar localStorage mein nahi
const localDraft = [Link](DRAFT_KEY);
if (!localDraft) {
await loadDraftFromFlask();
}
// Ab UI refresh karo fresh data ke saath
applyTheme();
applyFontSize();
renderMoodGrid('mood-grid');
renderMoodGrid('edit-mood-grid');
renderMoodPreview();
renderCategories();
populateCategorySelect('entry-category');
populateCategorySelect('edit-category');
renderCustomQuestionsForm();
renderSettingsCQ(); populateCatQSelector();
renderSettingsCats();
loadDraft();
refreshPage();
}

function showPage(name) {
[Link]('.page').forEach(p =>
[Link]('active'));
[Link]('.nav-item').forEach(n =>
[Link]('active'));
const page = [Link]('page-' + name);
if (page) [Link]('active');
const navIdx = ['new-entry','entries','favourites','eras','search','stats','bra
indump','other','backup','settings'];
const navItems = [Link]('.nav-item');
const idx = [Link](name);
if (idx >= 0 && navItems[idx]) navItems[idx].[Link]('active');
const titles = {'new-entry':'New Entry','entries':'All Entries','favourites':'+P
Favourites','eras':'Ø=ÝÓþ Era
Timeline','search':'Search','stats':'Statistics','braindump':'Ø>Ýà Thought
Capture','other':'Ø=ÝÂþ Other','backup':'Backup &
Restore','settings':'Settings'};
[Link]('page-title').textContent = titles[name] ||
name;
currentPage = name;
// sync bottom nav
[Link](".bnav-item").forEach(b =>
[Link]("active"));
const bnavEl = [Link]("bnav-" + name);
if (bnavEl) [Link]("active");
refreshPage();
}

function refreshPage() {
if (currentPage === 'entries') renderEntriesList();
if (currentPage === 'favourites') renderFavouritesList();
if (currentPage === 'eras') renderEraTimeline();
if (currentPage === 'stats') renderStats();
if (currentPage === 'braindump') renderBDList();
if (currentPage === 'backup') { renderBackupList();
renderLastBackupTimes(); if ([Link] > 0)
renderDriveStatusList(); }
if (currentPage === 'other') loadOtherList();
if (currentPage === 'search') doSearch();
if (currentPage === 'settings') { renderSettingsCQ();
populateCatQSelector(); renderSettingsCats(); renderMoodPreview(); }
}

// =====================================
// CLOCK
// =====================================
function startClock() {
function tick() {
const now = new Date();
const isMobile = [Link] <= 700;
[Link]('live-clock').textContent = isMobile
? [Link]('en-US', { hour:'2-digit', minute:'2-digit' })
: [Link]('en-US', { weekday:'short', month:'short',
day:'numeric', hour:'2-digit', minute:'2-digit', second:'2-digit' });
[Link]('entry-datetime').textContent = 'Ø=ÜÅ ' +
[Link]('en-US', { dateStyle:'medium', timeStyle:'short' });
}
tick(); setInterval(tick, 1000);
}

// =====================================
// WRITING TIMER
// =====================================
function startWritingTimer() {
// Writing timer is now driven by per-question CQ timers
(startCQTimer/pauseCQTimer)
// This function kept for compatibility
}

function onTextInput() {
if (!timerStarted) { timerStarted = true; }
}

// =====================================
// MOOD
// =====================================
let selectedMood = '';
let editSelectedMood = '';

function renderMoodGrid(containerId) {
const wrap = [Link](containerId);
if (!wrap) return;
[Link] = '';
[Link](mood => {
const el = [Link]('button');
[Link] = 'mood-chip';
[Link] = mood;
const isCurrent = containerId === 'mood-grid' ? selectedMood ===
mood : editSelectedMood === mood;
if (isCurrent) [Link]('selected');
[Link] = () => {
if (containerId === 'mood-grid') {
selectedMood = mood;
} else {
editSelectedMood = mood;
}
renderMoodGrid(containerId);
};
[Link](el);
});
}

function renderMoodPreview() {
const wrap = [Link]('settings-mood-preview');
if (!wrap) return;
[Link] = '';
[Link]((mood, i) => {
const el = [Link]('span');
[Link] = 'mood-chip';
[Link] = mood + ' <button onclick="removeMood(' + i + ')" styl
e="background:none;border:none;cursor:pointer;color:var(--text2);margi
n-left:4px;font-size:0.8rem;">'</button>';
[Link](el);
});
}

function addMood() {
const val = [Link]('new-mood-input').[Link]();
if (!val) return;
[Link](val);
[Link]('new-mood-input').value = '';
saveState(); renderMoodPreview(); renderMoodGrid('mood-grid');
renderMoodGrid('edit-mood-grid');
showToast('Mood added!');
}
function removeMood(i) {
[Link](i, 1);
saveState(); renderMoodPreview(); renderMoodGrid('mood-grid');
renderMoodGrid('edit-mood-grid');
}

// =====================================
// CATEGORIES
// =====================================
function renderCategories() {
populateCategorySelect('entry-category');
populateCategorySelect('edit-category');
populateCategorySelect('filter-cat');
renderSettingsCats();
}

function populateCategorySelect(id) {
const sel = [Link](id);
if (!sel) return;
const val = [Link];
[Link] = '<option value="">Select category…</option>';
[Link](c => {
const opt = [Link]('option');
[Link] = c; [Link] = c;
[Link](opt);
});
[Link] = val;
}

function renderSettingsCats() {
const wrap = [Link]('settings-cat-list');
if (!wrap) return;
[Link] = '';
[Link]((c, i) => {
const el = [Link]('span');
[Link] = 'cat-badge';
[Link] = c + ' <button onclick="removeCategory(' + i +
')">'</button>';
[Link](el);
});
}
function addCategory() {
const val = [Link]('new-cat-input').[Link]();
if (!val || [Link](val)) return;
[Link](val);
[Link]('new-cat-input').value = '';
saveState(); renderCategories(); showToast('Category added!');
}

function promptAddCategory() {
const val = prompt('Enter new category name:');
if (val && [Link]() && ![Link]([Link]())) {
[Link]([Link]());
saveState(); renderCategories(); showToast('Category "' + [Link]() +
'" added!');
[Link]('entry-category').value = [Link]();
}
}

function removeCategory(i) {
[Link](i, 1);
saveState(); renderCategories();
}

// =====================================
// CUSTOM QUESTIONS
// =====================================
// per-question entry timers (separate from qTimers used in questions
page)
let cqTimers = {};

function renderCustomQuestionsForm() {
const answersDiv = [Link]('cq-answers');
const emptyMsg = [Link]('cq-empty');
if (!answersDiv) return;

// Global questions
const globalQs = [Link] || [];
// Category-specific questions
const selectedCat = ([Link]('entry-category') ?
[Link]('entry-category').value : '').trim();
const catQs = ([Link] && selectedCat &&
[Link][selectedCat]) || [];

// Merge: global first, then category-specific (deduplicated)


const allQs = [...globalQs];
[Link](function(q){ if (![Link](q)) [Link](q); });

if ([Link] === 0) {
[Link] = '';
if (emptyMsg) [Link] = 'block';
return;
}
if (emptyMsg) [Link] = 'none';

// Stop any old timers


[Link](cqTimers).forEach(function(t){ if ([Link])
clearInterval([Link]); });
cqTimers = {};
[Link] = '';

// Show category banner if cat-specific questions exist


if ([Link] > 0 && selectedCat) {
const catBanner = [Link]('div');
[Link] = 'font-size:0.78rem;font-weight:600;color:var
(--accent);text-transform:uppercase;letter-spacing:0.07em;margin-botto
m:8px;padding:6px 10px;background:var(--accent-light);border-radius:8
px;display:inline-block;';
[Link] = '\uD83D\uDCC2 ' + selectedCat + ' ke
questions bhi include hain';
[Link](catBanner);
}

[Link](function(q, i) {
const isCatQ = [Link](q) && ![Link](q);
cqTimers[i] = { seconds: 0, interval: null };

const div = [Link]('div');


[Link] = 'q-session-card';
[Link] = 'cq-card-' + i;
if (isCatQ) [Link] = '3px solid var(--accent)';
[Link] =
'<div class="q-session-header">' +
'<div class="q-number">' + (i + 1) + '</div>' +
'<div class="q-text">' + q + (isCatQ ? ' <span style="font-size:0.7re
m;color:var(--accent);font-weight:600;margin-left:6px;">Ø=ÜÂ ' +
selectedCat + '</span>' : '') + '</div>' +
'<div class="q-timer-badge" id="cq-badge-' + i + '">' +
'<div class="q-timer-dot"></div>' +
'<span id="cq-time-' + i + '">00:00</span>' +
'</div>' +
'</div>' +
'<textarea id="cq-ans-' + i + '" placeholder="Yahan apna jawab
likhein\u2026" style="min-height:90px;width:100%;"
onfocus="startCQTimer(' + i + ')" onblur="pauseCQTimer(' + i + ')"
oninput="scheduleDraftSave()"></textarea>';
[Link](div);
});
}

function startCQTimer(i) {
const t = cqTimers[i];
if (!t || [Link]) return;
[Link] = setInterval(() => {
[Link]++;
// update this question's badge
const el = [Link]('cq-time-' + i);
if (el) {
const m = String([Link]([Link] / 60)).padStart(2, '0');
const s = String([Link] % 60).padStart(2, '0');
[Link] = m + ':' + s;
}
const badge = [Link]('cq-badge-' + i);
if (badge) [Link]('running');
[Link]('cq-card-' + i)?.[Link]('active-q');

// also update total writing-timer


const total = [Link](cqTimers).reduce((s, t) => s + [Link],
0);
const tm = String([Link](total / 60)).padStart(2, '0');
const ts = String(total % 60).padStart(2, '0');
const wt = [Link]('writing-timer');
if (wt) [Link] = '#ñ ' + tm + ':' + ts;
}, 1000);
}

function pauseCQTimer(i) {
const t = cqTimers[i];
if (!t || ![Link]) return;
clearInterval([Link]);
[Link] = null;
const badge = [Link]('cq-badge-' + i);
if (badge) { [Link]('running');
[Link]('done'); }
[Link]('cq-card-' + i)?.[Link]('active-q');
}

function renderSettingsCQ() {
const list = [Link]('settings-cq-list');
if (!list) return;
[Link] = '';
const qs = [Link];
if ([Link] === 0) {
[Link] = '<p style="font-size:0.82rem;color:var(--text2);">No
global questions yet.</p>';
return;
}
[Link](function(q, i) {
const div = [Link]('div');
[Link] = 'cq-list-item';
[Link] =
'display:flex;align-items:center;gap:6px;padding:8px 10px;background:v
ar(--surface2);border-radius:8px;margin-bottom:6px;border:1px solid
var(--border);';
[Link] =
'<div
style="display:flex;flex-direction:column;gap:2px;margin-right:2px;">' +
'<button class="btn btn-ghost btn-sm" style="padding:1px
5px;font-size:0.7rem;" onclick="moveCQ('+i+',-1)"
title="Upar">%²</button>' +
'<button class="btn btn-ghost btn-sm" style="padding:1px
5px;font-size:0.7rem;" onclick="moveCQ('+i+',1)"
title="Neeche">%¼</button>' +
'</div>' +
'<span style="flex:1;font-size:0.85rem;">'+q+'</span>' +
'<button class="btn btn-ghost btn-sm" onclick="removeCQ('+i+')"
style="color:var(--danger);">'</button>';
[Link](div);
});
}

function moveCQ(i, dir) {


const qs = [Link];
const j = i + dir;
if (j < 0 || j >= [Link]) return;
[qs[i], qs[j]] = [qs[j], qs[i]];
saveState(); renderSettingsCQ(); renderCustomQuestionsForm();
}

function addCustomQuestion() {
const val = [Link]('new-cq-input').[Link]();
if (!val) return;
[Link](val);
[Link]('new-cq-input').value = '';
saveState(); renderSettingsCQ(); renderCustomQuestionsForm();
showToast('Question added!');
}

function removeCQ(i) {
[Link](i, 1);
saveState(); renderSettingsCQ(); renderCustomQuestionsForm();
}

// =====================================
// CATEGORY-WISE QUESTIONS
// =====================================
function populateCatQSelector() {
const sel = [Link]('catq-category-sel');
if (!sel) return;
const current = [Link];
[Link] = '<option value="">-- Category chunein --</option>';
([Link] || []).forEach(function(c) {
const opt = [Link]('option');
[Link] = c;
const cnt = ([Link] &&
[Link][c] &&
[Link][c].length) || 0;
[Link] = c + (cnt > 0 ? ' (' + cnt + ')' : '');
if (c === current) [Link] = true;
[Link](opt);
});
renderCategoryQList();
}

function renderCategoryQList() {
const sel = [Link]('catq-category-sel');
const list = [Link]('catq-list');
const addWrap = [Link]('catq-add-wrap');
const badge = [Link]('catq-count-badge');
if (!sel || !list) return;
const cat = [Link];
if (!cat) {
[Link] = '<p
style="font-size:0.82rem;color:var(--text2);">Pehle category select
karein.</p>';
if (addWrap) [Link] = 'none';
if (badge) [Link] = '';
return;
}
if (![Link]) [Link]
= {};
const qs = [Link][cat] || [];
if (badge) [Link] = [Link] ? [Link] + ' question(s)' : '';
[Link] = '';
if ([Link] === 0) {
[Link] = '<p style="font-size:0.82rem;color:var(--text2);">"' +
cat + '" ke liye koi question nahi abhi.</p>';
} else {
[Link](function(q, i) {
const div = [Link]('div');
[Link] =
'display:flex;align-items:center;gap:6px;padding:8px 10px;background:v
ar(--accent-light);border-radius:8px;margin-bottom:6px;border:1px solid
var(--border);';
[Link] =
'<div
style="display:flex;flex-direction:column;gap:2px;margin-right:2px;">' +
'<button class="btn btn-ghost btn-sm" style="padding:1px
5px;font-size:0.7rem;"
onclick="moveCatQ(\''+cat+'\','+i+',-1)">%²</button>' +
'<button class="btn btn-ghost btn-sm" style="padding:1px
5px;font-size:0.7rem;" onclick="moveCatQ(\''+cat+'\','+i+',1)">%¼</button>'
+
'</div>' +
'<span style="flex:1;font-size:0.85rem;">'+q+'</span>' +
'<span style="font-size:0.7rem;color:var(--accent);font-weight:600;
margin-right:4px;">Ø=ÜÂ '+cat+'</span>' +
'<button class="btn btn-ghost btn-sm"
onclick="removeCatQ(\''+cat+'\','+i+')"
style="color:var(--danger);">'</button>';
[Link](div);
});
}
if (addWrap) [Link] = 'flex';
}

function addCategoryQuestion() {
const sel = [Link]('catq-category-sel');
const inp = [Link]('new-catq-input');
if (!sel || !inp) return;
const cat = [Link]();
const val = [Link]();
if (!cat) { showToast('& þ Pehle category select karein!'); return; }
if (!val) { showToast('& þ Question likhein!'); return; }
if (![Link]) [Link]
= {};
if (![Link][cat])
[Link][cat] = [];
[Link][cat].push(val);
[Link] = '';
saveState(); renderCategoryQList(); populateCatQSelector();
renderCustomQuestionsForm();
showToast('' "' + cat + '" mein question add hua!');
}

function removeCatQ(cat, i) {
if (![Link] ||
![Link][cat]) return;
[Link][cat].splice(i, 1);
if ([Link][cat].length === 0) delete
[Link][cat];
saveState(); renderCategoryQList(); populateCatQSelector();
renderCustomQuestionsForm();
}

function moveCatQ(cat, i, dir) {


const qs = [Link] &&
[Link][cat];
if (!qs) return;
const j = i + dir;
if (j < 0 || j >= [Link]) return;
const tmp = qs[i]; qs[i] = qs[j]; qs[j] = tmp;
saveState(); renderCategoryQList(); renderCustomQuestionsForm();
}

// =====================================
// TAGS
// =====================================
function renderTagsInWrap(wrapId, tags, removeFn) {
const wrap = [Link](wrapId);
const input = [Link]('.tags-input');
// remove old pills
[Link]('.tag-pill').forEach(p => [Link]());
[Link]((t, i) => {
const pill = [Link]('span');
[Link] = 'tag-pill';
[Link] = '#' + t + `<button
onclick="${removeFn}(${i})">'</button>`;
[Link](pill, input);
});
}

function handleTagInput(e) {
if ([Link] === 'Enter' || [Link] === ',') {
[Link]();
const val = [Link]().replace(/,/g,'');
if (val && ![Link](val)) {
[Link](val);
renderTagsInWrap('tags-wrap', newEntryTags, 'removeNewTag');
}
[Link] = '';
}
}

function removeNewTag(i) {
[Link](i, 1);
renderTagsInWrap('tags-wrap', newEntryTags, 'removeNewTag');
}

function handleEditTagInput(e) {
if ([Link] === 'Enter' || [Link] === ',') {
[Link]();
const val = [Link]().replace(/,/g,'');
if (val && ![Link](val)) {
[Link](val);
renderTagsInWrap('edit-tags-wrap', editTags, 'removeEditTag');
}
[Link] = '';
}
}

function removeEditTag(i) {
[Link](i, 1);
renderTagsInWrap('edit-tags-wrap', editTags, 'removeEditTag');
}

// =====================================
// SAVE ENTRY
// =====================================
function saveEntry() {
const title = [Link]('entry-title').[Link]();
if (!title) {
[Link]('entry-title').focus();
[Link]('entry-title').[Link] =
'var(--danger)';
showToast('& þ Pehle title likhein!');
setTimeout(() => {
[Link]('entry-title').[Link] = ''; }, 2000);
return;
}
const category = [Link]('entry-category').value;
const now = new Date();

// Collect CQ answers — global + category-specific merged


const globalQsSave = [Link] || [];
const catQsSave = ([Link] && category &&
[Link][category]) || [];
const allQsSave = [...globalQsSave];
[Link](function(q){ if (![Link](q))
[Link](q); });

const cqAnswers = {};


const cqTimes = {};
[Link](function(q, i) {
const el = [Link]('cq-ans-' + i);
cqAnswers[q] = el ? [Link]() : '';
cqTimes[q] = cqTimers[i] ? cqTimers[i].seconds : 0;
});

// Main text from the text area (not from Q&A - those are stored
separately in cqAnswers)
const text = ([Link]('entry-text')?.value || '').trim();

const totalTime = [Link](cqTimers).reduce((s, t) => s +


[Link], 0);
const allText = text + ' ' + [Link](cqAnswers).join(' ');
const wordCount = [Link]().split(/ /).filter(Boolean).length;

const entry = {
id: genId(),
title,
text,
mood: selectedMood,
category,
tags: [...newEntryTags],
cqAnswers,
cqTimes,
wordCount,
writingTime: totalTime,
date: [Link](),
created: [Link]()
};

[Link](entry);
saveState();

// Flask se local + rclone save (background mein)


saveEntryToFlask(entry, 'json', true);

pendingSaveEntry = entry;
selectedSaveFmt = 'json';
selectFmt('json');
showModal('save-local-modal');
showToast('' Entry saved!');
clearEntry();
}

function clearEntry() {
[Link]('entry-title').value = '';
[Link]('entry-text').value = '';
const cat = [Link]('entry-category');
if (cat) [Link] = '';
selectedMood = '';
newEntryTags = [];
renderMoodGrid('mood-grid');
renderTagsInWrap('tags-wrap', newEntryTags, 'removeNewTag');
// reset total timer display
timerSeconds = 0; timerStarted = false;
const wt = [Link]('writing-timer');
if (wt) [Link] = '#ñ 00:00';
// Stop and clear all CQ timers + re-render fresh
[Link](cqTimers).forEach(t => { if ([Link])
clearInterval([Link]); });
cqTimers = {};
renderCustomQuestionsForm();
clearDraft();
}

// =====================================
// LOCAL SAVE (Save As dialog)
// =====================================
let selectedSaveFmt = 'json';

function selectFmt(fmt) {
selectedSaveFmt = 'json';
[Link]('local-save-format').value = 'json';
}

async function saveWithDialog(entry, fmt) {


const slug = ([Link] ||
'entry').replace(/[^a-z0-9]/gi,'_').toLowerCase().slice(0,40);
const filename = slug + '_' + new
Date([Link]).toISOString().slice(0,10) + '.json';
const fileContent = [Link](entry, null, 2);

if ([Link]) {
try {
const fh = await [Link]({
suggestedName: filename,
types: [{ description: 'JSON File', accept: { 'application/json': ['.json']
} }]
});
const writable = await [Link]();
await [Link](fileContent);
await [Link]();
showToast('' File save ho gayi!');
return;
} catch(e) {
if ([Link] === 'AbortError') return;
}
}

downloadFile(fileContent, filename, 'application/json');


showToast('' File download ho rahi hai!');
}

async function confirmLocalSave() {


const fmt = 'json';
if (pendingSaveEntry) await saveWithDialog(pendingSaveEntry, fmt);
pendingSaveEntry = null;
closeModal('save-local-modal');
}

// =====================================
// ENTRIES LIST
// =====================================
function renderEntriesList() {
const container = [Link]('entries-list-container');
if (!container) return;
if ([Link] === 0) {
[Link] = `<div class="empty-state"><div
class="icon">Ø=ÜÖ</div><p>No entries yet. Start writing!</p></div>`;
return;
}
[Link] = '';
[Link](entry => {
[Link](makeEntryCard(entry, false));
});
}

function makeEntryCard(entry, forBackup=false) {


const card = [Link]('div');
[Link] = 'entry-card';
const date = new Date([Link]).toLocaleString('en-US', {
dateStyle:'medium', timeStyle:'short' });
const tagsHtml = ([Link]||[]).map(t => `<span
class="meta-badge">#${t}</span>`).join('');
const wt = [Link] ? formatTime([Link]) : '—';
[Link] = `
<div class="entry-card-header">
${forBackup ? `<input type="checkbox" class="entry-checkbox
backup-checkbox" data-id="${[Link]}">` : ''}
<div style="flex:1">
<div class="entry-card-title">${[Link] ? '+P ' : ''}${[Link] ||
'Untitled'}</div>
<div class="entry-card-meta">
<span class="meta-badge">Ø=ÜÅ ${date}</span>
${[Link] ? `<span class="meta-badge
mood">${[Link]}</span>` : ''}
${[Link] ? `<span class="meta-badge cat">Ø=ÝÂ
${[Link]}</span>` : ''}
<span class="meta-badge">Ø=ÜÝ ${[Link]||0}
words</span>
<span class="meta-badge">#ñ ${wt}</span>
${tagsHtml}
</div>
</div>
${!forBackup ? `<button class="star-btn ${[Link]?'starred':''}"
onclick="[Link]();toggleStar('${[Link]}')"
title="Favourite">&</button>` : ''}
</div>
<div class="entry-card-preview">${[Link] || ([Link] ?
[Link]([Link]).find(a=>a) || '' : '')}</div>
${!forBackup ? `<div class="entry-card-actions">
<button class="btn btn-outline btn-sm"
onclick="openDetail('${[Link]}')">Ø=ÜA View</button>
<button class="btn btn-outline btn-sm"
onclick="openEdit('${[Link]}')">' Edit</button>
<button class="btn btn-outline btn-sm"
onclick="downloadEntry(getEntry('${[Link]}'),'json')">+ JSON</button>
<button class="btn btn-danger btn-sm"
onclick="deleteEntry('${[Link]}')">Ø=ÝÑ</button>
</div>` : ''}
`;
if (!forBackup) [Link]('dblclick', () =>
openDetail([Link]));
return card;
}

function formatTime(secs) {
if (!secs) return '0s';
if (secs < 60) return secs + 's';
const m = [Link](secs/60); const s = secs%60;
return m + 'm ' + (s>0?s+'s':'');
}

function getEntry(id) { return [Link](e => [Link] === id); }

// =====================================
// DETAIL VIEW
// =====================================
function openDetail(id) {
currentDetailId = id;
const entry = getEntry(id);
if (!entry) return;
const date = new Date([Link]).toLocaleString('en-US', {
dateStyle:'full', timeStyle:'medium' });
const tagsHtml = ([Link]||[]).map(t => `<span
class="meta-badge">#${t}</span>`).join('');
const wt = [Link] ? formatTime([Link]) : '—';

let cqHtml = '';


if ([Link] && [Link]([Link]).length > 0) {
cqHtml = `<div class="detail-qa"><h4>Custom Questions</h4>`;
for (const [q, a] of [Link]([Link])) {
if (a) cqHtml += `<div class="qa-pair"><div class="q">Q:
${q}</div><div class="a">${a}</div></div>`;
}
cqHtml += '</div>';
}

[Link]('detail-modal-content').innerHTML = `
<h2 class="modal-title" style="padding-right:32px">${[Link] ||
'Untitled'}</h2>
<div class="detail-meta">
<span class="meta-badge">Ø=ÜÅ ${date}</span>
${[Link] ? `<span class="meta-badge
mood">${[Link]}</span>` : ''}
${[Link] ? `<span class="meta-badge cat">Ø=ÝÂ
${[Link]}</span>` : ''}
<span class="meta-badge">Ø=ÜÝ ${[Link]||0} words</span>
<span class="meta-badge">#ñ ${wt}</span>
${tagsHtml}
</div>
${cqHtml}
${[Link] ? `<div class="detail-content">${[Link]}</div>` : ''}
`;
showModal('detail-modal');
const starBtn = [Link]('detail-star-btn');
if (starBtn) {
[Link] = [Link] ? '& Starred' : '& Favourite';
[Link] = [Link] ? '#f5c518' : '';
[Link] = [Link] ? '#f5c518' : '';
}
}

function editCurrentEntry() { if (currentDetailId) {


closeModal('detail-modal'); openEdit(currentDetailId); } }

function deleteCurrentEntry() {
if (currentDetailId && confirm('Delete this entry?')) {
deleteEntry(currentDetailId);
closeModal('detail-modal');
}
}

function exportEntry(fmt) {
if (currentDetailId) downloadEntry(getEntry(currentDetailId), fmt);
}

// =====================================
// EDIT ENTRY
// =====================================
function openEdit(id) {
const entry = getEntry(id);
if (!entry) return;
currentDetailId = id;
[Link]('edit-title').value = [Link] || '';
[Link]('edit-text').value = [Link] || '';
editSelectedMood = [Link] || '';
editTags = [...([Link]||[])];
renderMoodGrid('edit-mood-grid');
renderTagsInWrap('edit-tags-wrap', editTags, 'removeEditTag');
populateCategorySelect('edit-category');
[Link]('edit-category').value = [Link] || '';
showModal('edit-modal');
}

function saveEdit() {
const entry = getEntry(currentDetailId);
if (!entry) return;
[Link] = [Link]('edit-title').[Link]();
[Link] = [Link]('edit-text').[Link]();
[Link] = editSelectedMood;
[Link] = [Link]('edit-category').value;
[Link] = [...editTags];
[Link] = [Link] ?
[Link]().split(/ /).filter(Boolean).length : 0;
saveState();
closeModal('edit-modal');
showToast('' Entry updated!');
refreshPage();
}

// =====================================
// DELETE
// =====================================
function deleteEntry(id) {
if (!confirm('Delete this entry? This cannot be undone.')) return;
[Link] = [Link](e => [Link] !== id);
saveState(); refreshPage(); showToast('Entry deleted.');
}

// =====================================
// SEARCH
// =====================================
function doSearch() {
const q = ([Link]('search-q')?.value ||
'').toLowerCase();
const mood = [Link]('filter-mood')?.value || '';
const cat = [Link]('filter-cat')?.value || '';
const from = [Link]('filter-date-from')?.value;
const to = [Link]('filter-date-to')?.value;

// Populate filter dropdowns — always refresh moods from settings


const moodSel = [Link]('filter-mood');
if (moodSel) {
const curMood = [Link];
[Link] = '<option value="">All Moods</option>';
[Link](m => { const o =
[Link]('option'); [Link]=m; [Link]=m;
[Link](o); });
[Link] = curMood;
}
const catSel = [Link]('filter-cat');
if (catSel && [Link] <= 1) {
[Link](c => { const o =
[Link]('option'); [Link]=c; [Link]=c;
[Link](o); });
}

let results = [Link];


if (q) results = [Link](e =>
([Link]||'').toLowerCase().includes(q) ||
([Link]||'').toLowerCase().includes(q) ||
([Link]||[]).some(t => [Link]().includes(q)) ||
([Link]||'').toLowerCase().includes(q)
);
if (mood) results = [Link](e => [Link] === mood);
if (cat) results = [Link](e => [Link] === cat);
if (from) results = [Link](e => new Date([Link]) >= new
Date(from));
if (to) results = [Link](e => new Date([Link]) <= new Date(to +
'T23:59:59'));

const container = [Link]('search-results');


if (!container) return;
if ([Link] === 0) {
[Link] = `<div class="empty-state"><div
class="icon">Ø=Ý</div><p>No entries found matching your
filters.</p></div>`;
return;
}
[Link] = `<p style="font-size:0.82rem;color:var(--text2);
margin-bottom:12px;">${[Link]} result${[Link]!==1?'s':''}
found</p>`;
[Link](e => [Link](makeEntryCard(e, false)));
}

function clearSearch() {
[Link]('search-q').value = '';
[Link]('filter-mood').value = '';
[Link]('filter-cat').value = '';
[Link]('filter-date-from').value = '';
[Link]('filter-date-to').value = '';
doSearch();
}

// =====================================
// STATISTICS
// =====================================
function renderStats() {
const entries = [Link];
const total = [Link];
const totalWords = [Link]((s, e) => s + ([Link]||0), 0);
const avgWords = total ? [Link](totalWords / total) : 0;
const totalTime = [Link]((s, e) => s + ([Link]||0), 0);
const avgTime = total ? [Link](totalTime / total) : 0;

[Link]('stats-grid').innerHTML = `
<div class="stat-card"><div class="stat-value">${total}</div><div
class="stat-label">Total Entries</div></div>
<div class="stat-card"><div
class="stat-value">${[Link]()}</div><div
class="stat-label">Total Words</div></div>
<div class="stat-card"><div
class="stat-value">${avgWords}</div><div class="stat-label">Avg
Words/Entry</div></div>
<div class="stat-card"><div
class="stat-value">${formatTime(avgTime)}</div><div
class="stat-label">Avg Writing Time</div></div>
<div class="stat-card"><div
class="stat-value">${formatTime(totalTime)}</div><div
class="stat-label">Total Writing Time</div></div>
<div class="stat-card"><div
class="stat-value">${getStreak()}</div><div class="stat-label">Day
Streak Ø=Ý%</div></div>
`;

// Mood chart
const moodCounts = {};
[Link](e => { if ([Link]) moodCounts[[Link]] =
(moodCounts[[Link]]||0)+1; });
renderBarChart('mood-chart', moodCounts, total);

// Category chart
const catCounts = {};
[Link](e => { if ([Link]) catCounts[[Link]] =
(catCounts[[Link]]||0)+1; });
renderBarChart('cat-chart', catCounts, total);

// Activity last 7 days


const actMap = {};
for (let i=6; i>=0; i--) {
const d = new Date(); [Link]([Link]()-i);
const key = [Link]('en-US', {month:'short',
day:'numeric'});
actMap[key] = 0;
}
[Link](e => {
const d = new Date([Link]);
const key = [Link]('en-US', {month:'short',
day:'numeric'});
if ([Link](key)) actMap[key]++;
});
const maxAct = [Link](...[Link](actMap), 1);
renderBarChart('activity-chart', actMap, maxAct, true);

// ---- Thought Capture Stats ----


const bdItems = getBDItems();
const bdTotal = [Link];
const bdDone = [Link](i => [Link]).length;
const bdPending = bdTotal - bdDone;
const bdHigh = [Link](i => [Link] === 'high').length;
const bdGrid = [Link]('bd-stats-grid');
if (bdGrid) {
[Link] = `
<div class="stat-card"><div class="stat-value">${bdTotal}</div><div
class="stat-label">Total Captured</div></div>
<div class="stat-card"><div class="stat-value"
style="color:var(--success)">${bdDone}</div><div
class="stat-label">Completed</div></div>
<div class="stat-card"><div class="stat-value"
style="color:#f39c12">${bdPending}</div><div
class="stat-label">Pending</div></div>
<div class="stat-card"><div class="stat-value"
style="color:#e74c3c">${bdHigh}</div><div class="stat-label">High
Priority</div></div>
`;
}
// BD category breakdown
const bdCatCounts = {};
[Link](i => { const lbl = [Link] || [Link] ||
'Other'; bdCatCounts[lbl] = (bdCatCounts[lbl]||0)+1; });
renderBarChart('bd-cat-chart', bdCatCounts, bdTotal);
}

function renderBarChart(id, data, total, absolute=false) {


const wrap = [Link](id);
if (!wrap) return;
const sorted = [Link](data).sort((a,b) => b[1]-a[1]).slice(0,8);
if ([Link] === 0) { [Link] = '<p
style="font-size:0.82rem;color:var(--text2);">No data yet.</p>'; return; }
const max = absolute ? total : [Link](...[Link](e=>e[1]));
[Link] = [Link](([label, val]) => {
const pct = max ? [Link]((val/max)*100) : 0;
const disp = absolute ? val : [Link]((val/total)*100) + '%';
return `<div class="bar-row">
<div class="bar-label">${label}</div>
<div class="bar-track"><div class="bar-fill"
style="width:${pct}%"><span
class="bar-val">${disp}</span></div></div>
</div>`;
}).join('');
}

function getStreak() {
if (![Link]) return 0;
const days = [...new Set([Link](e => new
Date([Link]).toDateString()))];
[Link]((a,b) => new Date(b)-new Date(a));
let streak = 0;
let check = new Date();
for (const d of days) {
const dd = new Date(d);
const diff = [Link]((check - dd) / 86400000);
if (diff <= 1) { streak++; check = dd; }
else break;
}
return streak;
}

// =====================================
// BACKUP & RESTORE
// =====================================
function renderBackupList() {
const container = [Link]('backup-entries-list');
if (!container) return;
let entries = [Link];
// Apply active date filter if set
const from = [Link]('backup-date-from')?.value;
const to = [Link]('backup-date-to')?.value;
if (from) entries = [Link](e => [Link] && [Link] >= from);
if (to) entries = [Link](e => [Link] && [Link] <= to + 'T23:59:59');
if ([Link] === 0) { [Link] = `<div
class="empty-state"><div class="icon">Ø=ܾ</div><p>No entries found for
selected range.</p></div>`; return; }
[Link] = '';
[Link](e => [Link](makeEntryCard(e, true)));
updateBackupCount();
const info = [Link]('backup-filter-info');
if (info) [Link] = (from || to) ? `Showing ${[Link]} of
${[Link]} entries` : `${[Link]} entries total`;
}

// ---- Last backup times ----


function renderLastBackupTimes() {
const fmt = key => {
const t = [Link](key);
if (!t) return 'Never';
return new Date(t).toLocaleString('en-IN',
{day:'numeric',month:'short',year:'numeric',hour:'2-digit',minute:'2-digit'});
};
const el = id => [Link](id);
if (el('last-backup-journal')) el('last-backup-journal').textContent =
fmt('last_backup_journal');
if (el('last-backup-eras')) el('last-backup-eras').textContent =
fmt('last_backup_eras');
if (el('last-backup-settings')) el('last-backup-settings').textContent =
fmt('last_backup_settings');
if (el('last-backup-capture')) el('last-backup-capture').textContent =
fmt('last_backup_capture');
}

// ---- Date filter for backup entries ----


function applyBackupQuickRange() {
const val = [Link]('backup-quick-range')?.value;
if (!val || val === 'all') {
if (val === 'all') {
[Link]('backup-date-from').value = '';
[Link]('backup-date-to').value = '';
}
if (!val) return;
} else {
const days = parseInt(val);
const to = new Date();
const from = new Date(); [Link]([Link]() - days);
[Link]('backup-date-from').value =
[Link]().slice(0,10);
[Link]('backup-date-to').value =
[Link]().slice(0,10);
}
renderBackupList();
}

function applyBackupDateFilter() { renderBackupList(); }

function clearBackupFilter() {
[Link]('backup-date-from').value = '';
[Link]('backup-date-to').value = '';
[Link]('backup-quick-range').value = '';
renderBackupList();
}

// ---- Export filtered entries ----


function exportFiltered() {
const from = [Link]('backup-date-from')?.value;
const to = [Link]('backup-date-to')?.value;
let entries = [Link];
if (from) entries = [Link](e => [Link] && [Link] >= from);
if (to) entries = [Link](e => [Link] && [Link] <= to + 'T23:59:59');
if (![Link]) { showToast('& þ No entries in selected range!');
return; }
const slug = 'journal_filtered_' + new Date().toISOString().slice(0,10);
downloadFile([Link](entries, null, 2), slug + '.json',
'application/json');
[Link]('last_backup_journal', new Date().toISOString());
renderLastBackupTimes();
showToast('' Exported ' + [Link] + ' entries!');
}

// ---- Eras backup ----


function exportErasBackup() {
const eras = [Link] || [];
downloadFile([Link]({ eras, exportedAt: new
Date().toISOString() }, null, 2), 'eras_backup_' + new
Date().toISOString().slice(0,10) + '.json', 'application/json');
[Link]('last_backup_eras', new Date().toISOString());
renderLastBackupTimes();
showToast('' Eras exported!');
}
function importErasBackup(event) {
const file = [Link][0]; if (!file) return;
const reader = new FileReader();
[Link] = e => {
try {
const data = [Link]([Link]);
const eras = [Link] || data;
if (![Link](eras)) { showToast(''L Invalid eras file!'); return; }
if (!confirm(`Import ${[Link]} eras? This will replace existing
eras.`)) return;
[Link] = eras; saveState();
renderEraTimeline();
showToast('' Eras imported!');
} catch { showToast(''L Could not read file!'); }
};
[Link](file);
[Link] = '';
}

// ---- Settings backup ----


function exportSettingsBackup() {
const data = { settings: [Link], exportedAt: new
Date().toISOString() };
downloadFile([Link](data, null, 2), 'settings_backup_' + new
Date().toISOString().slice(0,10) + '.json', 'application/json');
[Link]('last_backup_settings', new Date().toISOString());
renderLastBackupTimes();
showToast('' Settings exported!');
}
function importSettingsBackup(event) {
const file = [Link][0]; if (!file) return;
const reader = new FileReader();
[Link] = e => {
try {
const data = [Link]([Link]);
const settings = [Link] || data;
if (!settings || typeof settings !== 'object') { showToast(''L Invalid
settings file!'); return; }
if (!confirm('Import settings? Current settings will be overwritten.'))
return;
[Link] = { ...[Link], ...settings };
saveState(); refreshPage();
showToast('' Settings imported!');
} catch { showToast(''L Could not read file!'); }
};
[Link](file);
[Link] = '';
}

// ---- Capture backup ----


function exportCaptureBackup() {
const items = getBDItems();
const cats = getBDCategories();
const data = { items, categories: cats, exportedAt: new
Date().toISOString() };
downloadFile([Link](data, null, 2), 'capture_backup_' + new
Date().toISOString().slice(0,10) + '.json', 'application/json');
[Link]('last_backup_capture', new Date().toISOString());
renderLastBackupTimes();
showToast('' Capture backup exported!');
}
function importCaptureBackup(event) {
const file = [Link][0]; if (!file) return;
const reader = new FileReader();
[Link] = e => {
try {
const data = [Link]([Link]);
const items = [Link] || data;
const cats = [Link];
if (![Link](items)) { showToast(''L Invalid capture file!'); return; }
if (!confirm(`Import ${[Link]} capture items? This will replace
existing items.`)) return;
saveBDItems(items);
if (cats && [Link](cats)) saveBDCategoriesLocal(cats);
renderBDList();
showToast('' Capture data imported!');
} catch { showToast(''L Could not read file!'); }
};
[Link](file);
[Link] = '';
}

function updateBackupCount() {
const checked =
[Link]('.backup-checkbox:checked').length;
[Link]('backup-selected-count').textContent =
checked ? checked + ' selected' : '';
}

[Link]('change', e => { if
([Link]('backup-checkbox')) updateBackupCount();
});

function selectAllBackup() {
[Link]('.backup-checkbox').forEach(c =>
[Link]=true); updateBackupCount(); }
function deselectAllBackup() {
[Link]('.backup-checkbox').forEach(c =>
[Link]=false); updateBackupCount(); }

function getSelectedIds() {
return
[...[Link]('.backup-checkbox:checked')].map(c =>
[Link]);
}

// =====================================
// EXPORT / IMPORT
// =====================================
function entryToTxt(entry) {
const date = new Date([Link]).toLocaleString('en-US', {
dateStyle:'full', timeStyle:'medium' });
let out = `TITLE: ${[Link] || 'Untitled'}\n`;
out += `DATE: ${date}\n`;
out += `DATE_ISO: ${[Link] || new Date().toISOString()}\n`;
out += `MOOD: ${[Link] || 'Not set'}\n`;
out += `CATEGORY: ${[Link] || 'None'}\n`;
out += `TAGS: ${([Link]||[]).map(t=>'#'+t).join(' ') || 'None'}\n`;
out += `WORDS: ${[Link] || 0}\n`;
out += `WRITING TIME: ${formatTime([Link]||0)}\n`;
if ([Link] && [Link]([Link]).length > 0) {
out += '\n--- CUSTOM QUESTIONS ---\n';
for (const [q, a] of [Link]([Link])) {
if (a) out += `Q: ${q}\nA: ${a}\n`;
}
}
out += '\n--- ENTRY ---\n';
out += ([Link] || '') + '\n';
out += '\n' + '='.repeat(60) + '\n';
return out;
}

function downloadFile(content, filename, type) {


const blob = new Blob([content], { type });
const a = [Link]('a');
[Link] = [Link](blob);
[Link] = filename;
[Link]();
[Link]([Link]);
}

function downloadEntry(entry, fmt) {


if (!entry) return;
const slug = ([Link] ||
'entry').replace(/[^a-z0-9]/gi,'_').toLowerCase().slice(0,40);
downloadFile([Link](entry, null, 2), slug+'.json',
'application/json');
}

function exportAll(fmt) {
const slug = 'journal_all_' + new Date().toISOString().slice(0,10);
downloadFile([Link]([Link], null, 2), slug+'.json',
'application/json');
[Link]('last_backup_journal', new Date().toISOString());
renderLastBackupTimes();
showToast('' Exported ' + [Link] + ' entries!');
}
function exportSelected(fmt) {
const ids = getSelectedIds();
if (![Link]) { showToast('& þ No entries selected!'); return; }
const sel = [Link](e => [Link]([Link]));
const slug = 'journal_selected_' + new Date().toISOString().slice(0,10);
downloadFile([Link](sel, null, 2), slug+'.json',
'application/json');
[Link]('last_backup_journal', new Date().toISOString());
renderLastBackupTimes();
showToast('' Exported ' + [Link] + ' entries!');
}

async function exportZip() {


if (typeof JSZip === 'undefined') { showToast('& þ JSZip not loaded');
return; }
const ids = getSelectedIds();
const entries = [Link] ? [Link](e => [Link]([Link])) :
[Link];
const zip = new JSZip();
[Link](entry => {
const slug = ([Link] ||
'entry').replace(/[^a-z0-9]/gi,'_').toLowerCase().slice(0,40);
[Link](slug + '_' + [Link] + '.json', [Link](entry, null, 2));
});
const blob = await [Link]({ type: 'blob' });
const a = [Link]('a');
[Link] = [Link](blob);
[Link] = 'journal_backup_' + new Date().toISOString().slice(0,10)
+ '.zip';
[Link]();
showToast('' ZIP created with ' + [Link] + ' entries!');
}

function importFile(event, fmt) {


const files = [Link]([Link]);
if (![Link]) return;

let totalImported = 0;
let filesProcessed = 0;
const allNew = [];
[Link](file => {
const reader = new FileReader();
[Link] = e => {
try {
let imported = [];
if (fmt === 'json') {
const data = [Link]([Link]);
imported = [Link](data) ? data : [data];
} else {
const text = [Link];
// Split multiple entries by separator
const parts = [Link](/={60,}/);
[Link](part => {
if (![Link]()) return;

// Helper to extract field value


const get = (key) => {
const m = [Link](new RegExp(key + ': (.+)'));
return m ? m[1].trim() : '';
};

// Parse writing time — handles "5m 30s", "45s", "2m", "05:30"


formats
const parseTime = (str) => {
if (!str || str === '—') return 0;
// "MM:SS" format
const colonFmt = [Link](/^(\d+):(\d+)$/);
if (colonFmt) return parseInt(colonFmt[1]) * 60 +
parseInt(colonFmt[2]);
// "5m 30s" or "5m" or "30s" format
const mins = [Link](/(\d+)m/);
const secs = [Link](/(\d+)s/);
return (mins ? parseInt(mins[1]) * 60 : 0) + (secs ?
parseInt(secs[1]) : 0);
};

// Parse tags "#tag1 #tag2" !’ ['tag1', 'tag2']


const parseTags = (str) => {
if (!str || str === 'None') return [];
return [Link](/#(\w+)/g)?.map(t => [Link](1)) || [];
};

// Parse date string back to ISO


const parseDate = (str) => {
if (!str) return new Date().toISOString();
try {
const d = new Date(str);
// Agar valid date hai toh use karo
if (!isNaN([Link]())) return [Link]();
} catch {}
return new Date().toISOString();
};

// Parse custom questions section


const cqAnswers = {};
const cqSection = [Link]('--- CUSTOM QUESTIONS
---')[1]?.split('--- ENTRY ---')[0] || '';
const cqLines = [Link]('\n');
let currentQ = '';
[Link](line => {
const qm = [Link](/^Q: (.+)/);
const am = [Link](/^A: (.+)/);
if (qm) currentQ = qm[1].trim();
else if (am && currentQ) { cqAnswers[currentQ] = am[1].trim();
currentQ = ''; }
});

const rawText = ([Link]('--- ENTRY ---')[1] || '').trim();


const mood = get('MOOD');
const category = get('CATEGORY');
const writingTimeStr = get('WRITING TIME');
const wordsStr = get('WORDS');
const dateStr = get('DATE_ISO') || get('DATE');

const entry = {
id: genId(),
title: get('TITLE') || 'Imported Entry',
date: parseDate(dateStr),
text: rawText,
mood: mood === 'Not set' ? '' : mood,
category: category === 'None' ? '' : category,
tags: parseTags(get('TAGS')),
wordCount: parseInt(wordsStr) ||
[Link]().split(/ /).filter(Boolean).length,
writingTime: parseTime(writingTimeStr),
cqAnswers
};
[Link](entry);
});
}
[Link](...imported);
} catch(err) {
showToast(''L ' + [Link] + ' read nahi hua!');
}
filesProcessed++;
if (filesProcessed === [Link]) {
// Avoid duplicates by id
const existingIds = new Set([Link](e => [Link]));
const newOnes = [Link](e => ![Link]([Link]));
[Link] = [...newOnes, ...[Link]];
saveState(); refreshPage();
showToast('' ' + [Link] + ' entr' +
([Link]!==1?'ies':'y') + ' import hui (' + [Link] + ' file' +
([Link]>1?'s':'') + ')!');
}
};
[Link](file);
});
[Link] = '';
}

// =====================================
// THEME
// =====================================
function applyTheme() {
const isDark = [Link];
[Link]('dark', isDark);
const pill = [Link]('dark-toggle');
if (pill) [Link]('on', isDark);
}

function toggleTheme() {
[Link] = ![Link];
applyTheme();
saveState();
}

function applyFontSize() {
[Link]('textarea').forEach(t => [Link] =
[Link]);
const sel = [Link]('font-size-sel');
if (sel) [Link] = [Link];
}

function changeFontSize() {
[Link] =
[Link]('font-size-sel').value;
applyFontSize();
saveState();
}

// =====================================
// DATA MANAGEMENT
// =====================================
function clearAllData() {
if (!confirm('& þ This will permanently delete ALL entries. Are you
sure?')) return;
if (!confirm('Last chance! Really delete everything?')) return;
[Link] = [];
saveState(); refreshPage(); showToast('All entries deleted.');
}

// =====================================
// MODAL HELPERS
// =====================================
function showModal(id) {
[Link](id).[Link]('open'); }
function closeModal(id) {
[Link](id).[Link]('open'); }
[Link]('.modal-overlay').forEach(o => {
[Link]('click', e => { if ([Link] === o) closeModal([Link]);
});
});

// =====================================
// TOAST
// =====================================
function showToast(msg) {
const t = [Link]('toast');
[Link] = msg; [Link]('show');
setTimeout(() => [Link]('show'), 2800);
}

// =====================================
// KEYBOARD SHORTCUTS
// =====================================
[Link]('keydown', e => {
if ([Link] === 'Escape') {
[Link]('.[Link]').forEach(m =>
[Link]('open'));
}
});

// =====================================
// QUESTIONS SESSION
// =====================================
let qTimers = {}; // { index: { seconds, interval, started, done } }
let qSessionActive = false;

function initQuestionsPage() {
const qs = [Link];
const noQ = [Link]('q-no-questions');
const container = [Link]('q-cards-container');
const saveRow = [Link]('q-save-row');
const summary = [Link]('q-session-summary');
if (!container) return;

if (!qs || [Link] === 0) {


if (noQ) [Link] = 'block';
[Link] = '';
if (saveRow) [Link] = 'none';
return;
}
if (noQ) [Link] = 'none';

// If session already rendered, don't re-render


if (qSessionActive) return;

// Reset
qTimers = {};
if (summary) { [Link] = 'none'; [Link] =
''; }
[Link] = '';
if (saveRow) [Link] = 'none';

[Link]((q, i) => {
qTimers[i] = { seconds: 0, interval: null, started: false, done: false };
const card = [Link]('div');
[Link] = 'q-session-card';
[Link] = 'q-card-' + i;
[Link] = `
<div class="q-session-header">
<div class="q-number">${i+1}</div>
<div class="q-text">${q}</div>
<div class="q-timer-badge" id="q-badge-${i}">
<div class="q-timer-dot"></div>
<span id="q-time-${i}">00:00</span>
</div>
</div>
<textarea
id="q-ans-${i}"
placeholder="Yahan apna jawab likhein…"
style="min-height:90px;width:100%;"
onfocus="startQTimer(${i})"
onblur="pauseQTimer(${i})"
oninput="onQInput(${i})"
></textarea>
<div class="q-controls">
<button class="btn btn-outline btn-sm" onclick="toggleQTimer(${i})"
id="q-btn-${i}">%¶ Start Timer</button>
<button class="btn btn-ghost btn-sm" onclick="resetQTimer(${i})">!º
Reset</button>
<span class="q-status-line" id="q-status-${i}">Timer shuru nahi
hua</span>
</div>
`;
[Link](card);
});

if (saveRow) [Link] = 'flex';


qSessionActive = true;
}

function startNewSession() {
qSessionActive = false;
// Stop all running timers
[Link](qTimers).forEach(t => { if ([Link])
clearInterval([Link]); });
qTimers = {};
initQuestionsPage();
}

function resetSession() {
if (!confirm('Saari answers aur timers reset ho jaayenge?')) return;
qSessionActive = false;
[Link](qTimers).forEach(t => { if ([Link])
clearInterval([Link]); });
qTimers = {};
initQuestionsPage();
}

function startQTimer(i) {
const t = qTimers[i];
if (!t || [Link]) return;
if ([Link]) return; // already running
[Link] = true;
[Link] = setInterval(() => {
[Link]++;
updateQTimerDisplay(i);
}, 1000);
updateQBadge(i, 'running');
[Link]('q-card-' + i)?.[Link]('active-q');
const btn = [Link]('q-btn-' + i);
if (btn) [Link] = '#ø Pause';
const status = [Link]('q-status-' + i);
if (status) [Link] = 'Likh rahe ho… timer chal raha hai #ñ';
}

function pauseQTimer(i) {
const t = qTimers[i];
if (!t || ![Link]) return;
clearInterval([Link]);
[Link] = null;
updateQBadge(i, [Link] ? 'done' : 'paused');
[Link]('q-card-' + i)?.[Link]('active-q');
const btn = [Link]('q-btn-' + i);
if (btn) [Link] = '%¶ Resume';
const status = [Link]('q-status-' + i);
if (status) [Link] = 'Paused — ' + formatTime([Link]) + '
likha';
}

function toggleQTimer(i) {
const t = qTimers[i];
if (!t) return;
if ([Link]) {
pauseQTimer(i);
} else {
startQTimer(i);
// also focus the textarea
[Link]('q-ans-' + i)?.focus();
}
}

function resetQTimer(i) {
const t = qTimers[i];
if (!t) return;
if ([Link]) clearInterval([Link]);
[Link] = 0; [Link] = null; [Link] = false; [Link] = false;
updateQTimerDisplay(i);
updateQBadge(i, 'idle');
[Link]('q-card-' + i)?.[Link]('active-q');
const btn = [Link]('q-btn-' + i);
if (btn) [Link] = '%¶ Start Timer';
const status = [Link]('q-status-' + i);
if (status) [Link] = 'Timer shuru nahi hua';
}

function onQInput(i) {
const t = qTimers[i];
if (!t) return;
if (![Link] && ![Link]) {
startQTimer(i);
}
}

function updateQTimerDisplay(i) {
const t = qTimers[i];
const el = [Link]('q-time-' + i);
if (el) {
const m = String([Link]([Link] / 60)).padStart(2, '0');
const s = String([Link] % 60).padStart(2, '0');
[Link] = m + ':' + s;
}
}

function updateQBadge(i, state_str) {


const badge = [Link]('q-badge-' + i);
if (!badge) return;
[Link]('running', 'done');
if (state_str === 'running') [Link]('running');
else if (state_str === 'done') [Link]('done');
}

function saveQuestionSession() {
const qs = [Link];
if (!qs || [Link] === 0) return;

// Stop all timers


[Link](qTimers).forEach(i => {
const t = qTimers[i];
if ([Link]) { clearInterval([Link]); [Link] = null; }
[Link] = true;
updateQBadge(i, 'done');
[Link]('q-card-' + i)?.[Link]('active-q');
const btn = [Link]('q-btn-' + i);
if (btn) [Link] = '' Done';
const status = [Link]('q-status-' + i);
if (status) [Link] = '' Saved — Total time: ' +
formatTime([Link]);
});

const cqAnswers = {};


const cqTimes = {};
let totalSecs = 0;
[Link]((q, i) => {
const ans = [Link]('q-ans-' + i)?.[Link]() || '';
const secs = qTimers[i]?.seconds || 0;
cqAnswers[q] = ans;
cqTimes[q] = secs;
totalSecs += secs;
});

const wordCount = [Link](cqAnswers).join('


').trim().split(/ /).filter(Boolean).length;

const entry = {
id: genId(),
title: 'Q&A Session — ' + new Date().toLocaleDateString('en-US', {
month: 'short', day: 'numeric', year: 'numeric' }),
text: [Link](cqAnswers).map(([q,a]) => 'Q: ' + q + '\nA: ' + (a ||
'(no answer)')).join('\n\n'),
mood: '',
category: 'Q&A Session',
tags: ['questions', 'reflection'],
cqAnswers,
cqTimes,
wordCount,
writingTime: totalSecs,
date: new Date().toISOString(),
created: [Link](),
isQSession: true
};

[Link](entry);
saveState();

// Flask se local + rclone save


saveEntryToFlask(entry, 'json', true);

// Show summary
const summary = [Link]('q-session-summary');
if (summary) {
let rows = [Link]((q, i) => {
const secs = qTimers[i]?.seconds || 0;
const ans = cqAnswers[q];
return `<div class="summary-row"><span>${[Link] > 40 ?
[Link](0,40)+'…' : q}</span><span><b>${formatTime(secs)}</b>${ans
? '' : ' <span style="color:var(--text2);font-size:0.72rem;">(skipped)</spa
n>'}</span></div>`;
}).join('');
rows += `<div class="summary-row"><span>Total
Time</span><span>${formatTime(totalSecs)}</span></div>`;
[Link] = `<h3>' Session Saved!</h3>${rows}`;
[Link] = 'block';
[Link]({ behavior: 'smooth' });
}

pendingSaveEntry = entry;
selectedSaveFmt = 'json';
selectFmt('json');
showModal('save-local-modal');
showToast('' Q&A Session save ho gayi!');
}

// =====================================
// STAR / FAVOURITE
// =====================================
function toggleStar(id) {
const entry = getEntry(id);
if (!entry) return;
[Link] = ![Link];
saveState();
refreshPage();
showToast([Link] ? '+P Starred!' : 'Star removed');
}

function toggleStarCurrent() {
if (!currentDetailId) return;
toggleStar(currentDetailId);
const entry = getEntry(currentDetailId);
const starBtn = [Link]('detail-star-btn');
if (starBtn && entry) {
[Link] = [Link] ? '& Starred' : '& Favourite';
[Link] = [Link] ? '#f5c518' : '';
[Link] = [Link] ? '#f5c518' : '';
}
}

function renderFavouritesList() {
const container = [Link]('favourites-list');
if (!container) return;
const favs = [Link](e => [Link]);
if ([Link] === 0) {
[Link] = `<div class="empty-state"><div
class="icon">+P</div><p>Koi favourite entry nahi hai abhi.<br>Entry par
& click karo favourite karne ke liye.</p></div>`;
return;
}
[Link] = '';
[Link](entry => [Link](makeEntryCard(entry,
false)));
}

// =====================================
// ERA SYSTEM
// =====================================
const ERA_COLORS_DEFAULT = ['#e74c3c','#e67e22','#f1c40f','#2ecc
71','#1abc9c','#3498db','#9b59b6','#e91e63','#00bcd4','#ff5722','#8bc34
a','#607d8b'];
function getEraColors() {
try { return [Link]([Link]('era_colors') || 'null') ||
[...ERA_COLORS_DEFAULT]; } catch { return
[...ERA_COLORS_DEFAULT]; }
}
function saveEraColors(colors) { [Link]('era_colors',
[Link](colors)); }
let eraViewYear = new Date().getFullYear();
let eraViewMonth = new Date().getMonth(); // 0-based
let eraStarFilter = 'all';
let newEraColor = getEraColors()[0];

function setEraCustomColor(val) { newEraColor = val; }

function addEraCustomColor() {
const val = [Link]('era-custom-color')?.value;
if (!val) return;
const colors = getEraColors();
if (![Link](val)) { [Link](val); saveEraColors(colors); }
newEraColor = val;
renderEraColorPicker();
showToast('' Color added to palette!');
}

function deleteEraColor(color) {
const colors = getEraColors().filter(c => c !== color);
if ([Link] === 0) { showToast('& þ At least one color required!');
return; }
saveEraColors(colors);
if (newEraColor === color) newEraColor = colors[0];
renderEraColorPicker();
showToast('Ø=ÝÑ Color removed!');
}

function toggleEraForm() {
const f = [Link]('era-add-form');
if (!f) return;
const visible = [Link] !== 'none';
[Link] = visible ? 'none' : 'block';
if (!visible) renderEraColorPicker();
}

function renderEraColorPicker() {
const wrap = [Link]('era-color-picker');
if (!wrap) return;
const colors = getEraColors();
[Link] = '';
[Link](c => {
const container = [Link]('div');
[Link] = 'position:relative;display:inline-block;';
const el = [Link]('div');
[Link] = 'era-color-opt' + (c === newEraColor ? ' selected' : '');
[Link] = c;
[Link] = () => { newEraColor = c;
[Link]('era-custom-color').value = c;
renderEraColorPicker(); };
[Link] = c;
// Delete button (small x on hover)
const del = [Link]('button');
[Link] = '×';
[Link] = 'position:absolute;top:-5px;right:-5px;width:14px;he
ight:14px;border-radius:50%;background:#e74c3c;color:white;border:no
ne;cursor:pointer;font-size:9px;line-height:1;padding:0;display:flex;align-i
tems:center;justify-content:center;opacity:0;transition:opacity 0.15s;';
[Link] = (e) => { [Link](); deleteEraColor(c); };
[Link]('mouseenter', () => [Link] = '1');
[Link]('mouseleave', () => [Link] =
'0');
[Link](el);
[Link](del);
[Link](container);
});
}

function flaskSaveEras() {
fetch(`${FLASK_API}/eras`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ eras: [Link] || [] })
}).catch(() => {});
}

function saveEra() {
const name =
[Link]('era-name-input')?.[Link]();
const start = [Link]('era-start-input')?.value;
const end = [Link]('era-end-input')?.value;
if (!name || !start) { showToast('& þ Name aur start date zaroori hai!');
return; }
if (![Link]) [Link] = [];
[Link]({ id: genId(), name, start, end: end || null,
color: newEraColor });
saveState();
flaskSaveEras();
[Link]('era-name-input').value = '';
[Link]('era-start-input').value = '';
[Link]('era-end-input').value = '';
toggleEraForm();
renderEraTimeline();
showToast('' Era save ho gaya!');
}

function deleteEra(id) {
if (!confirm('Yeh era delete kar dein?')) return;
[Link] = ([Link] || []).filter(e => [Link] !== id);
saveState();
flaskSaveEras();
renderEraTimeline();
}

function getEraForDate(dateStr) {
const eras = [Link] || [];
const d = new Date(dateStr);
for (const era of eras) {
const s = new Date([Link]);
const e = [Link] ? new Date([Link]) : new Date('9999-12-31');
if (d >= s && d <= e) return era;
}
return null;
}

function eraMonthNav(dir) {
eraViewMonth += dir;
if (eraViewMonth > 11) { eraViewMonth = 0; eraViewYear++; }
if (eraViewMonth < 0) { eraViewMonth = 11; eraViewYear--; }
if (eraCurrentView === 'grid') { updateEraMonthLabel();
renderEraGrid(); }
else renderEraTimeline();
}

function eraGoToday() {
eraViewYear = new Date().getFullYear();
eraViewMonth = new Date().getMonth();
if (eraCurrentView === 'grid') { updateEraMonthLabel();
renderEraGrid(); }
else renderEraTimeline();
}

function updateEraMonthLabel() {
const monthLabel = [Link]('era-month-label');
if (monthLabel) [Link] = new Date(eraViewYear,
eraViewMonth, 1).toLocaleDateString('en-US', { month: 'long', year:
'numeric' });
}

function setEraStarFilter(f) {
eraStarFilter = f;
[Link]('era-filter-all').[Link]('active', f ===
'all');
[Link]('era-filter-starred').[Link]('active', f
=== 'starred');
if (eraCurrentView === 'grid') renderEraGrid();
else renderEraTimeline();
}

function renderEraTimeline() {
const eras = [Link] || [];

// Month label
updateEraMonthLabel();

// Legend
const legend = [Link]('era-legend');
if (legend) {
if ([Link] === 0) {
[Link] = '<span
style="font-size:0.8rem;color:var(--text2);">Koi era nahi hai abhi. "+ New
Era" se banao.</span>';
} else {
[Link] = [Link](era => `
<div class="era-legend-chip" style="background:${[Link]}22;colo
r:${[Link]};border-color:${[Link]}44;">
<div style="width:8px;height:8px;border-radius:50%;background:$
{[Link]};flex-shrink:0;"></div>
${[Link]}
<button onclick="deleteEra('${[Link]}')" style="background:none;b
order:none;cursor:pointer;color:${[Link]};font-size:0.75rem;padding:0
0 0 4px;line-height:1;">'</button>
</div>
`).join('');
}
}

// Build days of month


const container = [Link]('era-timeline-container');
if (!container) return;
[Link] = '';

const daysInMonth = new Date(eraViewYear, eraViewMonth + 1,


0).getDate();
const today = new Date();
const todayStr = [Link]().slice(0, 10);

// Build entry map by date


const entryMap = {};
[Link](entry => {
const d = [Link] ? [Link](0, 10) : null;
if (!d) return;
if (eraStarFilter === 'starred' && ![Link]) return;
if (!entryMap[d]) entryMap[d] = [];
entryMap[d].push(entry);
});

for (let day = 1; day <= daysInMonth; day++) {


const dateStr = `${eraViewYear}-${String(eraViewMonth +
1).padStart(2,'0')}-${String(day).padStart(2,'0')}`;
const era = getEraForDate(dateStr);
const entries = entryMap[dateStr] || [];
const isToday = dateStr === todayStr;
const dayName = new Date(dateStr).toLocaleDateString('en-US', {
weekday: 'short' });

const row = [Link]('div');


[Link] = 'era-day-row';

const dot = [Link]('div');


[Link] = 'era-day-dot' + ([Link] > 0 ? ' has-entry' : '');
[Link](dot);

const card = [Link]('div');


[Link] = 'era-day-card';
if (isToday) [Link] = 'var(--accent)';
if (isToday) [Link] = '0 0 0 2px var(--accent-light)';

// Date
const dateDiv = [Link]('div');
[Link] = 'era-day-date';
[Link] = `<div style="font-weight:${isToday?'800':'400'};c
olor:${isToday?'var(--accent)':'var(--text2)'};">${day}</div><div
style="font-size:0.68rem;">${dayName}</div>`;
[Link](dateDiv);

// Era band
const band = [Link]('div');
[Link] = 'era-day-era-band';
[Link] = era ? [Link] : 'var(--border)';
[Link] = era ? '1' : '0.3';
[Link] = era ? [Link] : '';
[Link](band);
// Entries
const entriesDiv = [Link]('div');
[Link] = 'era-day-entries';
if ([Link] === 0) {
const empty = [Link]('div');
[Link] = 'era-day-empty';
[Link] = era ? [Link] : '—';
[Link](empty);
} else {
[Link](e => {
const t = [Link]('div');
[Link] = 'era-day-entry-title';
[Link] = ([Link] ? '<span class="star-inline">&</span>' : '')
+ ([Link] || 'Untitled');
[Link] = () => openDetail([Link]);
[Link](t);
});
}
[Link](entriesDiv);

// Era badge
if (era) {
const badge = [Link]('div');
[Link] = 'era-label-badge';
[Link] = [Link] + '22';
[Link] = [Link];
[Link] = [Link];
[Link](badge);
}

[Link](card);
[Link](row);
}
}

// =====================================
// ERA VIEW TOGGLE
// =====================================
let eraCurrentView = 'timeline'; // 'timeline' or 'grid'
function setEraView(view) {
eraCurrentView = view;
[Link]('era-timeline-container').[Link] = view
=== 'timeline' ? '' : 'none';
[Link]('era-grid-container').[Link] = view
=== 'grid' ? '' : 'none';
[Link]('era-view-timeline-btn').[Link]('acti
ve-view-btn', view === 'timeline');
[Link]('era-view-grid-btn').[Link]('active-v
iew-btn', view === 'grid');
if (view === 'timeline') renderEraTimeline();
else renderEraGrid();
}

// =====================================
// ERA GRID VIEW
// =====================================
function renderEraGrid() {
const container = [Link]('era-grid-container');
if (!container) return;
[Link] = '';

const daysInMonth = new Date(eraViewYear, eraViewMonth + 1,


0).getDate();
const firstDow = new Date(eraViewYear, eraViewMonth, 1).getDay(); //
0=Sun
const todayStr = new Date().toISOString().slice(0, 10);

// Build entry map


const entryMap = {};
[Link](e => {
const d = [Link] ? [Link](0, 10) : null;
if (!d) return;
if (eraStarFilter === 'starred' && ![Link]) return;
if (!entryMap[d]) entryMap[d] = [];
entryMap[d].push(e);
});

// Day-of-week headers
const headerDiv = [Link]('div');
[Link] = 'era-grid-header';
['Sun','Mon','Tue','Wed','Thu','Fri','Sat'].forEach(d => {
const h = [Link]('div');
[Link] = 'era-grid-dow';
[Link] = d;
[Link](h);
});
[Link](headerDiv);

const gridDiv = [Link]('div');


[Link] = 'era-grid-wrap';

// Empty cells before first day


for (let i = 0; i < firstDow; i++) {
const empty = [Link]('div');
[Link] = 'era-grid-cell empty';
[Link](empty);
}

for (let day = 1; day <= daysInMonth; day++) {


const dateStr = `${eraViewYear}-${String(eraViewMonth+1).padStart(
2,'0')}-${String(day).padStart(2,'0')}`;
const era = getEraForDate(dateStr);
const entries = entryMap[dateStr] || [];
const isToday = dateStr === todayStr;

const cell = [Link]('div');


[Link] = 'era-grid-cell' + (isToday ? ' today' : '');

// Era background color


if (era) {
[Link] = [Link] + '33';
[Link] = [Link] + '66';
} else {
[Link] = 'var(--surface)';
[Link] = 'var(--border)';
}

// Day number
const num = [Link]('div');
[Link] = 'era-grid-day-num';
[Link] = day;
[Link] = isToday ? 'var(--accent)' : (era ? [Link] :
'var(--text)');
[Link](num);

// Entry dot
if ([Link] > 0) {
const dot = [Link]('div');
[Link] = 'era-grid-dot';
[Link] = era ? [Link] : 'var(--accent)';
[Link](dot);
}

// Era bar at bottom


if (era) {
const bar = [Link]('div');
[Link] = 'era-grid-era-bar';
[Link] = [Link];
[Link] = [Link];
[Link](bar);
}

// Click: if entries exist open first, else show date toast


if ([Link] === 1) {
[Link] = () => openDetail(entries[0].id);
} else if ([Link] > 1) {
[Link] = () => {
// show mini picker — open first entry for now, toast tells count
showToast(`${[Link]} entries on this day`);
openDetail(entries[0].id);
};
// badge
const badge = [Link]('div');
[Link] = 'position:absolute;top:2px;right:3px;font-size:0
.6rem;font-weight:800;color:white;background:var(--accent);border-radiu
s:8px;padding:0 4px;line-height:1.4;z-index:2;';
[Link] = [Link];
[Link](badge);
} else {
[Link] = era ? [Link] : '';
}

[Link](cell);
}

[Link](gridDiv);

// Era legend below grid


const eras = [Link] || [];
if ([Link] > 0) {
const leg = [Link]('div');
[Link] =
'display:flex;flex-wrap:wrap;gap:6px;margin-top:14px;';
[Link](era => {
const chip = [Link]('div');
[Link] =
`display:flex;align-items:center;gap:5px;padding:3px 10px;border-radius:
12px;font-size:0.72rem;font-weight:700;background:${[Link]}22;color:
${[Link]};`;
[Link] = `<div style="width:8px;height:8px;border-radius:50
%;background:${[Link]};"></div>${[Link]}`;
[Link](chip);
});
[Link](leg);
}
}

// =====================================
// ERA EXPORT / IMPORT
// =====================================
function exportEras() {
const eras = [Link] || [];
if ([Link] === 0) { showToast('& þ Koi era nahi hai export karne ke
liye!'); return; }
const data = [Link]({ eras, exportedAt: new
Date().toISOString() }, null, 2);
const blob = new Blob([data], { type: 'application/json' });
const a = [Link]('a');
[Link] = [Link](blob);
[Link] = 'my_eras_' + new Date().toISOString().slice(0,10) +
'.json';
[Link]();
[Link]([Link]);
showToast('' Eras export ho gaye!');
}

function importEras(event) {
const file = [Link][0];
if (!file) return;
const reader = new FileReader();
[Link] = function(e) {
try {
const data = [Link]([Link]);
const incoming = [Link] || data; // support both formats
if (![Link](incoming)) { showToast(''L Invalid file format!');
return; }
// Merge: skip duplicates by id
if (![Link]) [Link] = [];
let added = 0;
[Link](era => {
if (![Link](e => [Link] === [Link])) {
[Link](era);
added++;
}
});
saveState();
renderEraTimeline();
if (eraCurrentView === 'grid') renderEraGrid();
showToast(`' ${added} era(s) import ho gaye!`);
} catch(err) {
showToast(''L File read nahi ho saki!');
}
};
[Link](file);
[Link] = ''; // reset input
}

// =====================================
// RCLONE ENTRY SYNC
// =====================================
async function rcloneSyncEntry() {
if (!pendingSaveEntry) return;
showToast('#ó Syncing to Drive via rclone...');
const result = await saveEntryToFlask(pendingSaveEntry,
selectedSaveFmt || 'json', true);
if (result) {
closeModal('save-local-modal');
pendingSaveEntry = null;
}
}

// =====================================
// BRAIN DUMP
// =====================================

const BD_DEFAULT_CATS = [
{id:'video', label:'Ø=Üù Watch Later'},
{id:'idea', label:'Ø=Ü¡ Idea'},
{id:'kaam', label:'' Task'},
{id:'padhai', label:'Ø=ÜÚ Study'},
{id:'baad', label:'#ó Post-Exam'},
{id:'other', label:'Ø=ÝÂ Other'}
];

function getBDCategories() {
try { return [Link]([Link]('bd_categories') || 'null') ||
BD_DEFAULT_CATS; } catch { return BD_DEFAULT_CATS; }
}
function saveBDCategoriesLocal(cats) {
[Link]('bd_categories', [Link](cats));
}

function getBDItems() {
try { return [Link]([Link]('braindump_items') || '[]');
} catch { return []; }
}
function saveBDItems(items) {
[Link]('braindump_items', [Link](items));
// Flask se bhi save karo agar available hai
saveBDToFlask(items);
}

async function saveBDToFlask(items) {


try {
await fetch('[Link] {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: [Link]({items})
});
} catch(e) { /* Flask nahi mila toh ignore */ }
}

async function loadBDFromFlask() {


try {
const res = await fetch('[Link]
if (![Link]) return;
const data = await [Link]();
if ([Link] && [Link] > 0) {
saveBDItems([Link]);
renderBDList();
}
} catch(e) { /* offline mode */ }
}

async function saveBDCategoriesToFlask(cats) {


try {
await fetch('[Link] {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: [Link]({categories: cats})
});
} catch(e) {}
}

async function loadBDCategoriesFromFlask() {


try {
const res = await fetch('[Link]
if (![Link]) return;
const data = await [Link]();
if ([Link] && [Link] > 0) {
saveBDCategoriesLocal([Link]);
renderBDCategorySelect();
renderBDCategoryManager();
}
} catch(e) {}
}

function renderBDCategorySelect() {
const sel = [Link]('bd-category');
if (!sel) return;
const cats = getBDCategories();
[Link] = [Link](c => `<option
value="${[Link]}">${[Link]}</option>`).join('');
}

function renderBDCategoryManager() {
const container = [Link]('bd-cat-list');
if (!container) return;
const cats = getBDCategories();
[Link] = [Link](c => `
<div style="display:flex;align-items:center;gap:6px;background:var(--s
urface2);
padding:5px 10px;border-radius:20px;font-size:0.82rem;">
<span>${[Link]}</span>
<button onclick="deleteBDCategory('${[Link]}')"

style="background:none;border:none;cursor:pointer;color:var(--text2);
font-size:1rem;line-height:1;padding:0 2px;"
title="Delete">×</button>
</div>
`).join('');
}

function addBDCategory() {
const input = [Link]('bd-new-cat-input');
const val = [Link]();
if (!val) { showToast('& þ Please enter something!'); return; }
const cats = getBDCategories();
const newId = 'cat_' + [Link]();
[Link]({id: newId, label: val});
saveBDCategoriesLocal(cats);
saveBDCategoriesToFlask(cats);
[Link] = '';
renderBDCategorySelect();
renderBDCategoryManager();
showToast('' Category added successfully!');
}

function deleteBDCategory(id) {
const defaults = ['video','idea','kaam','padhai','baad','other'];
if ([Link](id)) { showToast('& þ Default categories cannot be
deleted!'); return; }
const cats = getBDCategories().filter(c => [Link] !== id);
saveBDCategoriesLocal(cats);
saveBDCategoriesToFlask(cats);
renderBDCategorySelect();
renderBDCategoryManager();
showToast('Ø=ÝÑ Category removed!');
}

function addBrainDump() {
const text = [Link]('bd-input').[Link]();
if (!text) { showToast('& þ Please enter something!'); return; }
const catId = [Link]('bd-category').value;
const cats = getBDCategories();
const cat = [Link](c => [Link] === catId) || {id: catId, label: catId};
const priority = [Link]('bd-priority').value;
const items = getBDItems();
[Link]({
id: [Link](),
text,
categoryId: [Link],
categoryLabel: [Link],
priority,
done: false,
createdAt: new Date().toISOString()
});
saveBDItems(items);
[Link]('bd-input').value = '';
renderBDList();
showToast('' Logged! Now get back to what matters Ø=Ý%');
}

let bdCurrentFilter = 'all';


function filterBD(filter) {
bdCurrentFilter = filter;
[Link]('.bd-filter-btn').forEach(b =>
[Link]('active-filter'));
const btn = [Link]('bdf-' + filter);
if (btn) [Link]('active-filter');
renderBDList();
}

const priorityColors = { low:'#27ae60', medium:'#f39c12', high:'#e74c3c'


};
const priorityLabels = { low:'Ø=ßâ Low', medium:'Ø=ßá Medium', high:'Ø=Ý4 Hig
};

function renderBDList() {
renderBDCategorySelect();
renderBDCategoryManager();
const items = getBDItems();
const list = [Link]('bd-list');
const stats = [Link]('bd-stats');
if (!list) return;

const pending = [Link](i => ![Link]).length;


const done = [Link](i => [Link]).length;
if (stats) [Link] = `Total: ${[Link]} · Pending:
${pending} · Done: ${done}`;

let filtered = items;


if (bdCurrentFilter === 'pending') filtered = [Link](i => ![Link]);
else if (bdCurrentFilter === 'done') filtered = [Link](i => [Link]);
else if (bdCurrentFilter === 'exam-baad') filtered = [Link](i =>
[Link] === 'baad');

if ([Link] === 0) {
[Link] = `<div
style="text-align:center;padding:40px;color:var(--text2);">
<div style="font-size:2rem;margin-bottom:10px;">Ø>Ýà</div>
<div>${bdCurrentFilter === 'done' ? 'Nothing completed yet!' : 'All
clear! Time to focus. Ø=Ý%'}</div>
</div>`;
return;
}

[Link] = [Link](item => `


<div
style="background:var(--surface);border-radius:12px;padding:14px
16px;margin-bottom:10px;
box-shadow:var(--shadow);border-left:4px solid
${priorityColors[[Link]] || '#ccc'};
opacity:${[Link] ? '0.6' : '1'};transition:opacity 0.2s;">
<div style="display:flex;align-items:flex-start;gap:12px;">
<input type="checkbox" ${[Link] ? 'checked' : ''}
onchange="toggleBDItem(${[Link]})"
style="margin-top:3px;width:18px;height:18px;accent-color:var(--a
ccent);cursor:pointer;flex-shrink:0;">
<div style="flex:1;">
<div style="font-size:0.95rem;font-weight:500;${[Link] ?
'text-decoration:line-through;color:var(--text2);' : ''}">${[Link]}</div>
<div style="display:flex;gap:8px;margin-top:6px;flex-wrap:wrap;">
<span
style="font-size:0.72rem;background:var(--surface2);padding:2px
8px;border-radius:10px;color:var(--text2);">${[Link] ||
[Link] || ''}</span>
<span style="font-size:0.72rem;color:${priorityColors[[Link]
y]};font-weight:600;">${priorityLabels[[Link]]}</span>
<span style="font-size:0.7rem;color:var(--text2);font-family:var(--f
ont-mono);">${new Date([Link]).toLocaleDateString('en-IN',{da
y:'numeric',month:'short',hour:'2-digit',minute:'2-digit'})}</span>
</div>
</div>
<button onclick="deleteBDItem(${[Link]})" class="btn btn-ghost
btn-sm"
style="flex-shrink:0;padding:4px 8px;font-size:1rem;"
title="Delete">Ø=ÝÑ</button>
</div>
</div>
`).join('');

renderBDAnalysis(items);
}

function toggleBDItem(id) {
const items = getBDItems();
const item = [Link](i => [Link] === id);
if (item) {
[Link] = ![Link];
saveBDItems(items);
renderBDList();
if ([Link]) showToast('' Marked complete! Review the rest later
Ø=Þ');
}
}

function deleteBDItem(id) {
const items = getBDItems().filter(i => [Link] !== id);
saveBDItems(items);
renderBDList();
showToast('Ø=ÝÑ Item removed!');
}

function renderBDAnalysis(items) {
const analysisBox = [Link]('bd-analysis');
const analysisContent =
[Link]('bd-analysis-content');
if (!analysisBox || !analysisContent) return;

const doneItems = [Link](i => [Link]);


if ([Link] === 0) { [Link] = 'none'; return;
}
[Link] = 'block';

// Category breakdown of completed


const catMap = {};
[Link](i => { const l = [Link] || [Link] ||
'Other'; catMap[l] = (catMap[l]||0)+1; });
const catRows =
[Link](catMap).sort((a,b)=>b[1]-a[1]).map(([label, val]) => {
const pct = [Link]((val / [Link]) * 100);
return `<div class="bar-row">
<div class="bar-label">${label}</div>
<div class="bar-track"><div class="bar-fill" style="width:${pct}%;bac
kground:linear-gradient(90deg,var(--success),#52c48a);">
<span class="bar-val">${val}</span></div></div>
</div>`;
}).join('');

// Priority breakdown of completed


const priMap = { high: 0, medium: 0, low: 0 };
[Link](i => { if (priMap[[Link]] !== undefined)
priMap[[Link]]++; });

const completionRate = [Link] ? [Link](([Link] /


[Link]) * 100) : 0;

[Link] = `
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax
(140px,1fr));gap:10px;margin-bottom:16px;">
<div class="stat-card" style="padding:12px 14px;">
<div class="stat-value"
style="font-size:1.5rem;color:var(--success)">${[Link]}</div>
<div class="stat-label">Tasks Done</div>
</div>
<div class="stat-card" style="padding:12px 14px;">
<div class="stat-value"
style="font-size:1.5rem;color:var(--accent)">${completionRate}%</div>
<div class="stat-label">Completion Rate</div>
</div>
<div class="stat-card" style="padding:12px 14px;">
<div class="stat-value"
style="font-size:1.5rem;color:#e74c3c">${[Link]}</div>
<div class="stat-label">High Priority Done</div>
</div>
</div>
<p style="font-size:0.78rem;font-weight:700;text-transform:uppercase;
letter-spacing:0.07em;color:var(--text2);margin-bottom:10px;">Complete
d by Category</p>
<div class="bar-chart">${catRows}</div>
<div style="margin-top:14px;display:flex;gap:10px;flex-wrap:wrap;">
<span style="font-size:0.8rem;background:rgba(231,76,60,0.1);color
:#e74c3c;padding:4px 12px;border-radius:20px;font-weight:600;">Ø=Ý4
High: ${[Link]}</span>
<span style="font-size:0.8rem;background:rgba(243,156,18,0.1);col
or:#f39c12;padding:4px 12px;border-radius:20px;font-weight:600;">Ø=ßá
Medium: ${[Link]}</span>
<span style="font-size:0.8rem;background:rgba(39,174,96,0.1);color
:var(--success);padding:4px
12px;border-radius:20px;font-weight:600;">Ø=ßâ Low:
${[Link]}</span>
</div>
`;
}

// =====================================
// OTHER MODULES
// =====================================
let otherFileContent = '';
let otherFileOriginalName = '';
let otherSelectedIcon = 'Ø>Ýé';

const OTHER_ICONS = [
'Ø>Ýé','Ø=ÜÊ','Ø=ܰ','Ø=ÜÅ',''','Ø<ßËþ','Ø=ÜÚ','Ø<߯','Ø=Ü¡','Ø=ÝÒþ',
'Ø=Ý'','Ø<ß®','Ø<ß','Ø=ÜÈ','Ø>Ýî','Ø<ߨ','Ø=Ý','Ø=Üæ','Ø<ß1','#ñþ',
'Ø<ßµ','Ø<ßN','Ø=ÜŠ','Ø=Þ—',''þ','Ø<ßà','Ø=Üd','Ø=Ü÷','Ø>Ýà','&¡'
];

function initIconPicker() {
const grid = [Link]('other-icon-grid');
if (!grid || [Link] > 0) return;
[Link] = OTHER_ICONS.map(ic => `
<span onclick="selectOtherIcon('${ic}')"
style="font-size:1.5rem;padding:6px
8px;border-radius:8px;cursor:pointer;
background:var(--surface);border:1.5px solid var(--border);
transition:transform 0.15s,border-color 0.15s;"
onmouseenter="[Link]='scale(1.2)';[Link]
or='var(--accent)'"
onmouseleave="[Link]='scale(1)';[Link]
='var(--border)'"
title="${ic}">${ic}</span>
`).join('');
}

function toggleIconPicker() {
initIconPicker();
const p = [Link]('other-icon-picker');
[Link] = [Link] === 'none' ? 'block' : 'none';
}

function selectOtherIcon(ic) {
otherSelectedIcon = ic;
[Link]('other-icon-preview').textContent = ic;
[Link]('other-icon-picker').[Link] = 'none';
}

function otherFileChosen(event) {
const file = [Link][0];
if (!file) return;
otherFileOriginalName = [Link](/\.html?$/i, '');
const fnInput = [Link]('other-fname');
if (![Link]()) [Link] = otherFileOriginalName;
const reader = new FileReader();
[Link] = function(e) {
otherFileContent = [Link];
[Link]('other-file-info').textContent = `' File
loaded: ${[Link]} (${([Link]/1024).toFixed(1)} KB)`;
};
[Link](file);
}

async function uploadOtherFile() {


const name = [Link]('other-fname').[Link]();
if (!name) { showToast('& þ Pehle app ka naam daalo!'); return; }
if (!otherFileContent) { showToast('& þ Pehle HTML file choose karo!');
return; }
try {
const r = await fetch(`${FLASK_API}/modules/save`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ filename: name, content: otherFileContent })
});
const d = await [Link]();
if ([Link] === 'ok') {
// Save icon meta
const key = [Link](/\.html$/i, '');
await fetch(`${FLASK_API}/modules/meta`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ key, icon: otherSelectedIcon })
});
showToast(`' ${name} save ho gaya!`);
[Link]('other-fname').value = '';
[Link]('other-file-info').textContent = '';
[Link]('other-file-input').value = '';
[Link]('other-icon-preview').textContent = 'Ø>Ýé';
otherFileContent = '';
otherFileOriginalName = '';
otherSelectedIcon = 'Ø>Ýé';
loadOtherList();
} else {
showToast(''L Error: ' + ([Link] || 'unknown'));
}
} catch {
showToast(''L Flask server se connect nahi hua!');
}
}

async function loadOtherList() {


const listDiv = [Link]('other-files-list');
if (!listDiv) return;
try {
const [listRes, metaRes] = await [Link]([
fetch(`${FLASK_API}/modules/list`),
fetch(`${FLASK_API}/modules/meta`)
]);
const listData = await [Link]();
const metaData = await [Link]();
const meta = [Link] || {};

if (![Link] || [Link] === 0) {


[Link] = `<div
style="text-align:center;padding:30px;color:var(--text2);">
<div style="font-size:2rem;margin-bottom:8px;">Ø=Üí</div>
<div style="font-size:0.85rem;">Koi app nahi. Upar se add
karo!</div>
</div>`;
return;
}

// App icon grid


[Link] = `<div style="display:grid;grid-template-columns:re
peat(auto-fill,minmax(110px,1fr));gap:14px;padding:4px;">
${[Link](f => {
const key = [Link](/\.html$/i, '');
const m = meta[key] || {};
const icon = [Link] || 'Ø>Ýé';
const lastOpened = m.last_opened
? new Date(m.last_opened).toLocaleDateString('en-IN',{day:'num
eric',month:'short',hour:'2-digit',minute:'2-digit'})
: null;
return `<div
style="display:flex;flex-direction:column;align-items:center;gap:6px;
background:var(--surface2);border-radius:14px;padding:16px
8px 12px;
border:1.5px solid var(--border);cursor:pointer;
transition:transform 0.18s,border-color 0.18s,box-shadow 0.18s;
position:relative;"
onclick="openOtherFile('${[Link]}','${[Link]}')"
onmouseenter="[Link]='translateY(-3px)';[Link].b
orderColor='var(--accent)';[Link]='var(--shadow-lg)'"
onmouseleave="[Link]='translateY(0)';[Link]
erColor='var(--border)';[Link]='none'">

<!-- options button -->


<div style="position:absolute;top:6px;right:6px;"
onclick="[Link]()">
<button class="btn btn-ghost" style="padding:2px
6px;font-size:0.85rem;border-radius:6px;"
onclick="toggleAppMenu('${key}')" title="Options">"î</button>
<div id="appmenu-${key}"
style="display:none;position:absolute;right:0;top:24px;
background:var(--surface);border:1px solid
var(--border);border-radius:10px;
box-shadow:var(--shadow-lg);z-index:200;min-width:120px;ove
rflow:hidden;">
<button class="btn btn-ghost"
style="width:100%;text-align:left;padding:8px
14px;font-size:0.82rem;border-radius:0;"
onclick="startRenameApp('${key}','${[Link]}')">'þ
Rename</button>
<button class="btn btn-ghost"
style="width:100%;text-align:left;padding:8px
14px;font-size:0.82rem;border-radius:0;"
onclick="changeAppIcon('${key}')">Ø<ߨ Icon Badlo</button>
<button class="btn btn-ghost"
style="width:100%;text-align:left;padding:8px
14px;font-size:0.82rem;color:var(--danger);border-radius:0;"
onclick="deleteOtherFile('${[Link]}')">Ø=ÝÑ Delete</button>
</div>
</div>

<div
style="font-size:2.4rem;line-height:1;margin-bottom:2px;">${icon}</div>
<div
style="font-size:0.8rem;font-weight:600;color:var(--text);text-align:center;
word-break:break-word;line-height:1.3;max-width:90px;">${[Link]
me}</div>
${lastOpened ? `<div style="font-size:0.65rem;color:var(--text2);te
xt-align:center;line-height:1.2;">${lastOpened}</div>` : ''}
<div
style="font-size:0.65rem;color:var(--text2);">${([Link]/1024).toFixed(1)}
KB</div>
</div>`;
}).join('')}
</div>`;
// Close menus on outside click
[Link]('click', closeAllAppMenus, { once: true });
} catch {
[Link] = `<div style="text-align:center;padding:20px;color:
var(--text2);font-size:0.85rem;">& þ Flask server se list nahi mili</div>`;
}
}

function toggleAppMenu(key) {
const menu = [Link](`appmenu-${key}`);
if (!menu) return;
const wasHidden = [Link] === 'none';
closeAllAppMenus();
if (wasHidden) {
[Link] = 'block';
setTimeout(() => [Link]('click',
closeAllAppMenus, { once: true }), 10);
}
}

function closeAllAppMenus() {
[Link]('[id^="appmenu-"]').forEach(m =>
[Link] = 'none');
}

function openOtherFile(filename, name) {


const url =
`${FLASK_API}/modules/file/${encodeURIComponent(filename)}`;
[Link](url, '_blank');
showToast(`%¶ ${name} khul raha hai...`);
// Refresh list after open (to update last_opened)
setTimeout(loadOtherList, 1200);
}

function startRenameApp(key, currentName) {


closeAllAppMenus();
const newName = prompt(`"${currentName}" ka naya naam:`,
currentName);
if (!newName || [Link]() === currentName) return;
renameOtherFile(key, [Link]());
}

async function renameOtherFile(oldKey, newName) {


try {
const r = await fetch(`${FLASK_API}/modules/rename`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ old: oldKey, new: newName })
});
const d = await [Link]();
if ([Link] === 'ok') {
showToast(`' Rename ho gaya !’ ${newName}`);
loadOtherList();
} else {
showToast(''L ' + ([Link] || 'Rename fail'));
}
} catch {
showToast(''L Server se connect nahi hua!');
}
}

function changeAppIcon(key) {
closeAllAppMenus();
// Show a small inline icon picker in a toast-style prompt
const chosen = prompt(`Naya icon paste karo (koi bhi emoji):\nJaise:
Ø=ܰ Ø=ÜÊ ' Ø<߯ Ø<ßËþ Ø=ÜÚ`, 'Ø>Ýé');
if (!chosen) return;
const icon = [Link]().slice(0, 4); // emoji max
fetch(`${FLASK_API}/modules/meta`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ key, icon })
}).then(() => {
showToast(`Ø<ߨ Icon update ho gaya!`);
loadOtherList();
}).catch(() => showToast(''L Server error'));
}

function reloadOtherViewer() {}
function closeOtherViewer() {}

async function deleteOtherFile(filename) {


closeAllAppMenus();
if (!confirm(`"${filename}" delete karna chahte ho?`)) return;
try {
const r = await fetch(`${FLASK_API}/modules/delete`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: [Link]({ filename })
});
const d = await [Link]();
if ([Link] === 'ok') {
showToast(`Ø=ÝÑ ${filename} delete ho gaya!`);
loadOtherList();
} else {
showToast(''L ' + ([Link] || 'Delete fail'));
}
} catch {
showToast(''L Server se connect nahi hua!');
}
}

// =====================================
// RUN
// =====================================
init();
[Link]('load', () => {
updateFlaskStatus();
});
</script>
</body>
</html>

You might also like