@cccarv82/freya 3.4.1 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli/web-ui.js CHANGED
@@ -28,6 +28,18 @@
28
28
  document.documentElement.setAttribute('data-theme', 'dark');
29
29
  }
30
30
 
31
+ function toggleTheme() {
32
+ var isDark = document.documentElement.getAttribute('data-theme') === 'dark';
33
+ if (isDark) {
34
+ document.documentElement.removeAttribute('data-theme');
35
+ try { localStorage.setItem('freya-theme', 'light'); } catch(_) {}
36
+ } else {
37
+ document.documentElement.setAttribute('data-theme', 'dark');
38
+ try { localStorage.setItem('freya-theme', 'dark'); } catch(_) {}
39
+ }
40
+ }
41
+ window.toggleTheme = toggleTheme;
42
+
31
43
  function setPill(kind, text) {
32
44
  const dot = $('dot');
33
45
  const rail = $('railStatus');
@@ -1407,6 +1419,16 @@
1407
1419
  }
1408
1420
  }
1409
1421
 
1422
+ /* ── Smooth Page Navigation with Transition ── */
1423
+ function navigateTo(url) {
1424
+ document.body.classList.add('navigating');
1425
+ // Close mobile menu if open
1426
+ closeMobileNav();
1427
+ setTimeout(function() {
1428
+ window.location.href = url;
1429
+ }, 180);
1430
+ }
1431
+
1410
1432
  function wireRailNav() {
1411
1433
  const dash = $('railDashboard');
1412
1434
  const rep = $('railReports');
@@ -1423,7 +1445,7 @@
1423
1445
  if (dash) {
1424
1446
  dash.onclick = () => {
1425
1447
  if (!isDashboard) {
1426
- window.location.href = '/';
1448
+ navigateTo('/');
1427
1449
  } else {
1428
1450
  const c = document.querySelector('.centerBody');
1429
1451
  if (c) c.scrollTo({ top: 0, behavior: 'smooth' });
@@ -1432,37 +1454,37 @@
1432
1454
  }
1433
1455
  if (rep) {
1434
1456
  rep.onclick = () => {
1435
- if (curPage !== 'reports') window.location.href = '/reports';
1457
+ if (curPage !== 'reports') navigateTo('/reports');
1436
1458
  };
1437
1459
  }
1438
1460
  if (proj) {
1439
1461
  proj.onclick = () => {
1440
- if (curPage !== 'projects') window.location.href = '/projects';
1462
+ if (curPage !== 'projects') navigateTo('/projects');
1441
1463
  };
1442
1464
  }
1443
1465
  if (health) {
1444
1466
  health.onclick = () => {
1445
- if (curPage !== 'companion') window.location.href = '/companion';
1467
+ if (curPage !== 'companion') navigateTo('/companion');
1446
1468
  };
1447
1469
  }
1448
1470
  if (kanban) {
1449
1471
  kanban.onclick = () => {
1450
- if (curPage !== 'kanban') window.location.href = '/kanban';
1472
+ if (curPage !== 'kanban') navigateTo('/kanban');
1451
1473
  };
1452
1474
  }
1453
1475
  if (tl) {
1454
1476
  tl.onclick = () => {
1455
- if (curPage !== 'timeline') window.location.href = '/timeline';
1477
+ if (curPage !== 'timeline') navigateTo('/timeline');
1456
1478
  };
1457
1479
  }
1458
1480
  if (graph) {
1459
1481
  graph.onclick = () => {
1460
- if (curPage !== 'graph') window.location.href = '/graph';
1482
+ if (curPage !== 'graph') navigateTo('/graph');
1461
1483
  };
1462
1484
  }
1463
1485
  if (docs) {
1464
1486
  docs.onclick = () => {
1465
- if (curPage !== 'docs') window.location.href = '/docs';
1487
+ if (curPage !== 'docs') navigateTo('/docs');
1466
1488
  };
1467
1489
  }
1468
1490
  }
@@ -2613,8 +2635,16 @@
2613
2635
  }
2614
2636
  }
2615
2637
 
2616
- // init
2617
- applyDarkTheme();
2638
+ // init — apply saved theme preference (default: light)
2639
+ (function initTheme() {
2640
+ var saved = null;
2641
+ try { saved = localStorage.getItem('freya-theme'); } catch(_) {}
2642
+ if (saved === 'dark') {
2643
+ document.documentElement.setAttribute('data-theme', 'dark');
2644
+ } else {
2645
+ document.documentElement.removeAttribute('data-theme');
2646
+ }
2647
+ })();
2618
2648
  const chipPort = $('chipPort');
2619
2649
  if (chipPort) chipPort.textContent = location.host;
2620
2650
  loadLocal();
@@ -3533,4 +3563,109 @@
3533
3563
  window.openBlockerEdit = openBlockerEdit;
3534
3564
  window.closeBlockerEdit = closeBlockerEdit;
3535
3565
  window.submitBlockerEdit = submitBlockerEdit;
3566
+
3567
+ /* ── Mobile Navigation Menu ── */
3568
+ var _mobileNavOpen = false;
3569
+
3570
+ function buildMobileNav() {
3571
+ // Only build on small screens and if not already built
3572
+ if (document.querySelector('.mobileMenuBtn')) return;
3573
+
3574
+ var curPage = (document.body && document.body.dataset) ? document.body.dataset.page : null;
3575
+ var isDashboard = !curPage || curPage === 'dashboard';
3576
+
3577
+ // Hamburger button
3578
+ var btn = document.createElement('button');
3579
+ btn.className = 'mobileMenuBtn';
3580
+ btn.setAttribute('aria-label', 'Menu de navegação');
3581
+ btn.innerHTML = '<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg>';
3582
+ btn.onclick = toggleMobileNav;
3583
+ document.body.appendChild(btn);
3584
+
3585
+ // Navigation overlay
3586
+ var nav = document.createElement('div');
3587
+ nav.className = 'mobileNav';
3588
+ nav.id = 'mobileNav';
3589
+ nav.onclick = function(e) {
3590
+ if (e.target === nav) closeMobileNav();
3591
+ };
3592
+
3593
+ var items = [
3594
+ { label: 'Dashboard', page: null, url: '/', icon: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="9"></rect><rect x="14" y="3" width="7" height="5"></rect><rect x="14" y="12" width="7" height="9"></rect><rect x="3" y="16" width="7" height="5"></rect></svg>' },
3595
+ { label: 'Relatórios', page: 'reports', url: '/reports', icon: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline></svg>' },
3596
+ { label: 'Companion', page: 'companion', url: '/companion', icon: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"></polygon></svg>' },
3597
+ { label: 'Kanban', page: 'kanban', url: '/kanban', icon: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="5" height="18" rx="1"></rect><rect x="10" y="3" width="5" height="12" rx="1"></rect><rect x="17" y="3" width="5" height="15" rx="1"></rect></svg>' },
3598
+ { label: 'Projetos', page: 'projects', url: '/projects', icon: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path></svg>' },
3599
+ { label: 'Timeline', page: 'timeline', url: '/timeline', icon: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>' },
3600
+ { label: 'Grafo', page: 'graph', url: '/graph', icon: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line></svg>' },
3601
+ { label: 'Configurações', page: 'settings', url: '/settings', icon: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09"></path></svg>' }
3602
+ ];
3603
+
3604
+ var panel = document.createElement('div');
3605
+ panel.className = 'mobileNav-panel';
3606
+
3607
+ for (var i = 0; i < items.length; i++) {
3608
+ var item = items[i];
3609
+ var isActive = item.page === curPage || (item.page === null && isDashboard);
3610
+ var el = document.createElement('button');
3611
+ el.className = 'mobileNav-item' + (isActive ? ' active' : '');
3612
+ el.innerHTML = item.icon + '<span>' + item.label + '</span>';
3613
+ el.setAttribute('data-url', item.url);
3614
+ el.onclick = function() {
3615
+ var url = this.getAttribute('data-url');
3616
+ navigateTo(url);
3617
+ };
3618
+ panel.appendChild(el);
3619
+ }
3620
+
3621
+ nav.appendChild(panel);
3622
+ document.body.appendChild(nav);
3623
+ }
3624
+
3625
+ function toggleMobileNav() {
3626
+ _mobileNavOpen ? closeMobileNav() : openMobileNav();
3627
+ }
3628
+
3629
+ function openMobileNav() {
3630
+ var nav = document.getElementById('mobileNav');
3631
+ var btn = document.querySelector('.mobileMenuBtn');
3632
+ if (!nav) return;
3633
+ nav.style.display = 'block';
3634
+ _mobileNavOpen = true;
3635
+ if (btn) btn.classList.add('open');
3636
+ // Trigger reflow for transition
3637
+ nav.offsetHeight;
3638
+ nav.classList.add('visible');
3639
+ }
3640
+
3641
+ function closeMobileNav() {
3642
+ var nav = document.getElementById('mobileNav');
3643
+ var btn = document.querySelector('.mobileMenuBtn');
3644
+ if (!nav) return;
3645
+ nav.classList.remove('visible');
3646
+ _mobileNavOpen = false;
3647
+ if (btn) btn.classList.remove('open');
3648
+ setTimeout(function() {
3649
+ nav.style.display = 'none';
3650
+ }, 250);
3651
+ }
3652
+
3653
+ // Build mobile nav on load
3654
+ buildMobileNav();
3655
+ window.closeMobileNav = closeMobileNav;
3656
+
3657
+ // Also intercept chip.clickable clicks for smooth transition
3658
+ document.querySelectorAll('.chip.clickable').forEach(function(el) {
3659
+ var href = el.getAttribute('onclick');
3660
+ if (href && href.indexOf('location.href') !== -1) {
3661
+ var match = href.match(/['"]([^'"]+)['"]/);
3662
+ if (match) {
3663
+ el.removeAttribute('onclick');
3664
+ el.onclick = function(e) {
3665
+ e.preventDefault();
3666
+ navigateTo(match[1]);
3667
+ };
3668
+ }
3669
+ }
3670
+ });
3536
3671
  })();
package/cli/web.js CHANGED
@@ -1572,7 +1572,7 @@ function buildReportsHtml(safeDefault, appVersion) {
1572
1572
  </button>
1573
1573
 
1574
1574
  </div>
1575
- <div class="railBottom">\n <button id="railSettings" class="railBtn" title="Configurações">\n <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>\n </button>
1575
+ <div class="railBottom">\n <button id="railSettings" class="railBtn" title="Configurações" onclick="if (document.body.dataset.page !== 'settings') window.location.href='/settings';">\n <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>\n </button>
1576
1576
 
1577
1577
  </div>
1578
1578
  </aside>
@@ -1931,7 +1931,9 @@ function buildTimelineHtml(safeDefault, appVersion) {
1931
1931
 
1932
1932
  </div>
1933
1933
  <div class=\"railBottom\">
1934
- <div class=\"railStatus\" id=\"railStatus\" title=\"status\"></div>
1934
+ <button id=\"railSettings\" class=\"railBtn\" title=\"Configurações\" onclick=\"if (document.body.dataset.page !== 'settings') window.location.href='/settings';\">
1935
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
1936
+ </button>
1935
1937
  </div>
1936
1938
  </aside>
1937
1939
 
@@ -3061,7 +3063,7 @@ async function cmdWeb({ port, dir, open, dev }) {
3061
3063
  if (t.project_slug && nodeIds.has(t.project_slug)) {
3062
3064
  edges.push({ from: tid, to: t.project_slug });
3063
3065
  } else {
3064
- addNode('unassigned', 'Sin Asignar', 'unassigned');
3066
+ addNode('unassigned', 'Sem Atribuir', 'unassigned');
3065
3067
  edges.push({ from: tid, to: 'unassigned' });
3066
3068
  }
3067
3069
  }
@@ -5040,7 +5042,7 @@ function buildSettingsHtml(safeDefault, appVersion) {
5040
5042
  <span class="chip" style="font-weight:normal; font-size:11px;">Rules</span>
5041
5043
  </div>
5042
5044
  <div class="panelBody">
5043
- <p style="margin-top: 0; color: #666; font-size: 13px;">
5045
+ <p style="margin-top: 0; color: var(--muted); font-size: 13px;">
5044
5046
  A FREYA tenta adivinhar automaticamente a qual projeto uma tarefa pertence com base no LLM.
5045
5047
  Se você quiser <b>garantir</b> que uma palavra sempre caia em um projeto específico, adicione uma regra abaixo.
5046
5048
  </p>
@@ -5176,7 +5178,7 @@ function buildKanbanHtml(safeDefault, appVersion) {
5176
5178
  <button class="railBtn" id="railDashboard" type="button" title="Dashboard">
5177
5179
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="9"></rect><rect x="14" y="3" width="7" height="5"></rect><rect x="14" y="12" width="7" height="9"></rect><rect x="3" y="16" width="7" height="5"></rect></svg>
5178
5180
  </button>
5179
- <button class="railBtn" id="railReports" type="button" title="Relat\\u00f3rios">
5181
+ <button class="railBtn" id="railReports" type="button" title="Relatórios">
5180
5182
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
5181
5183
  </button>
5182
5184
  <button class="railBtn" id="railCompanion" type="button" title="Companion">
@@ -5196,7 +5198,7 @@ function buildKanbanHtml(safeDefault, appVersion) {
5196
5198
  </button>
5197
5199
  </div>
5198
5200
  <div class="railBottom">
5199
- <button id="railSettings" class="railBtn" title="Configura\\u00e7\\u00f5es" onclick="if (document.body.dataset.page !== 'settings') window.location.href='/settings';">
5201
+ <button id="railSettings" class="railBtn" title="Configurações" onclick="if (document.body.dataset.page !== 'settings') window.location.href='/settings';">
5200
5202
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
5201
5203
  </button>
5202
5204
  </div>
@@ -5208,7 +5210,7 @@ function buildKanbanHtml(safeDefault, appVersion) {
5208
5210
  <span class="spark"></span>
5209
5211
  <div class="brandStack">
5210
5212
  <div class="brand">FREYA</div>
5211
- <div class="brandSub">Kanban Board &mdash; Vis\\u00e3o SM</div>
5213
+ <div class="brandSub">Kanban Board &mdash; Visão SM</div>
5212
5214
  </div>
5213
5215
  </div>
5214
5216
  <div class="topActions">
@@ -5310,7 +5312,7 @@ function buildKanbanHtml(safeDefault, appVersion) {
5310
5312
  <span style="font-weight:700; font-size:14px;">Nova Task</span>
5311
5313
  <button class="btn small" type="button" onclick="window.closeQuickAdd()" style="padding:2px 8px;">&times;</button>
5312
5314
  </div>
5313
- <textarea id="qaDesc" class="qa-input" placeholder="Descri\\u00e7\\u00e3o da task..." rows="3"></textarea>
5315
+ <textarea id="qaDesc" class="qa-input" placeholder="Descrição da task..." rows="3"></textarea>
5314
5316
  <div class="qa-row">
5315
5317
  <select id="qaCat" class="qa-select">
5316
5318
  <option value="DO_NOW">DO_NOW</option>
@@ -5319,9 +5321,9 @@ function buildKanbanHtml(safeDefault, appVersion) {
5319
5321
  </select>
5320
5322
  <select id="qaPriority" class="qa-select">
5321
5323
  <option value="">Prioridade</option>
5322
- <option value="critical">Cr\\u00edtica</option>
5324
+ <option value="critical">Crítica</option>
5323
5325
  <option value="high">Alta</option>
5324
- <option value="medium">M\\u00e9dia</option>
5326
+ <option value="medium">Média</option>
5325
5327
  <option value="low">Baixa</option>
5326
5328
  </select>
5327
5329
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cccarv82/freya",
3
- "version": "3.4.1",
3
+ "version": "3.5.0",
4
4
  "description": "Personal AI Assistant with local-first persistence",
5
5
  "scripts": {
6
6
  "health": "node scripts/validate-data.js && node scripts/validate-structure.js",