@nightkatana/kronosys-app 1.0.0-beta.48 → 1.0.0-beta.49
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/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/action/route.js +2 -2
- package/.next/standalone/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/guide/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/implementation/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/licenses/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/page.js +2 -2
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/reporting/page.js +1 -1
- package/.next/standalone/.next/server/app/reporting/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page.js +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/277.js +1 -1
- package/.next/standalone/.next/server/chunks/752.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/static/chunks/400-cac6dc0640f386c4.js +1 -0
- package/.next/standalone/.next/static/chunks/840-28f9828e00e2f8c3.js +1 -0
- package/.next/standalone/.next/static/chunks/app/{page-c5be0f23f5bc42fd.js → page-1766656a21070335.js} +2 -2
- package/.next/standalone/.next/static/chunks/app/reporting/page-0615e693da39c7c7.js +1 -0
- package/.next/standalone/.next/static/chunks/app/settings/page-4c3075515a042cab.js +1 -0
- package/.next/standalone/.next/static/css/4405bf3014ccb6d4.css +1 -0
- package/.next/standalone/kronosys-package-meta.json +1 -1
- package/.next/standalone/package.json +1 -1
- package/package.json +1 -1
- package/.next/standalone/.next/static/chunks/400-2e05c0740eee8135.js +0 -1
- package/.next/standalone/.next/static/chunks/840-83aa65cc3eee5ac5.js +0 -1
- package/.next/standalone/.next/static/chunks/app/reporting/page-e5506b66f4ed8196.js +0 -1
- package/.next/standalone/.next/static/chunks/app/settings/page-6bc04b3bf71dae02.js +0 -1
- package/.next/standalone/.next/static/css/ac2f8ba1e863e1ef.css +0 -1
- /package/.next/standalone/.next/static/{UFeDt42q5AGTIPvMliAsx → 3fUAt3ojvE1CqWQDFTi7g}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{UFeDt42q5AGTIPvMliAsx → 3fUAt3ojvE1CqWQDFTi7g}/_ssgManifest.js +0 -0
|
@@ -87,4 +87,4 @@ Les p\xe9riodes rapides fixent la plage ; \xab Semaine \xbb = lundi–dimanche (
|
|
|
87
87
|
|
|
88
88
|
\xc9tiquettes : d\xe8s qu’au moins une \xe9tiquette est choisie, toute session sans aucune t\xe2che correspondante est enti\xe8rement exclue.
|
|
89
89
|
|
|
90
|
-
Sessions archiv\xe9es : pour les m\xe9triques bas\xe9es sur les t\xe2ches, seules les t\xe2ches enti\xe8rement boucl\xe9es (sous-t\xe2ches comprises) sont prises en compte — voir aussi l’aide des indicateurs de synth\xe8se.`,reportingNonFinalLegend:"Travail ouvert —",reportingNonFinalSessionsBadge:"Sessions",reportingNonFinalProjectsBadge:"Projets",reportingNonFinalTagsBadge:"\xc9tiquettes",sectionFilteredBadge:"Filtr\xe9",sectionFilteredBadgeTitle:"Ces chiffres tiennent compte de la plage de dates et des \xe9tiquettes choisies en haut de page.",summarySessionsInRange:"Sessions (plage)",summaryTaskEvents:"Lignes de t\xe2ches (plage)",summaryKronoFocusCompleted:"Sessions KronoFocus termin\xe9es (total par session)",summaryKronoFocusTasksUsed:"T\xe2ches avec KronoFocus utilis\xe9",summaryKronoFocusCycles:"Cycles KronoFocus (t\xe2ches)",summaryTaskTimeRecorded:"Temps enregistr\xe9 sur les t\xe2ches",summarySessionCoding:"Temps de codage (sessions)",summarySessionActive:"Temps actif (sessions)",summarySessionWallClock:"Dur\xe9e murale des sessions",summaryAssiduityWithReference:"Sessions (d\xe9but pr\xe9vu enregistr\xe9)",summaryAssiduityLateSessions:"D\xe9parts en retard (apr\xe8s l’heure pr\xe9vue)",summaryAssiduityLateTotal:"Retard cumul\xe9",summaryAssiduityAvgLateWhenLate:"Retard moyen (si en retard)",chartSessionsPerDay:"Sessions par jour",chartTasksByStatusPerDay:"T\xe2ches par jour et par statut",chartTaskTimePerDay:"Temps enregistr\xe9 sur les t\xe2ches par jour",chartSessionWallPerDay:"Dur\xe9e murale des sessions par jour",sessionDayTaskBreakdownTitle:"Sessions par jour — temps des t\xe2ches",sessionDayTaskBreakdownIntro:"Chaque jour affich\xe9 est le jour de session (enregistrement ou fin). Sous chaque session : temps enregistr\xe9 sur les t\xe2ches qui tombe dans la plage de dates (m\xeames r\xe8gles que le graphique \xab temps t\xe2che \xbb ; archives : seules les t\xe2ches enti\xe8rement boucl\xe9es). Les t\xe2ches planifi\xe9es (cr\xe9neau futur) affichent une fen\xeatre planifi\xe9e distincte, pas la dur\xe9e enregistr\xe9e. La colonne murale indique la fraction de dur\xe9e murale attribu\xe9e \xe0 ce jour lorsque la session traverse minuit. Chaque # sous une t\xe2che affiche la dur\xe9e compl\xe8te de la ligne (m\xeame r\xe8gle que les grilles d’allocation # plus haut). Basculez l’ordre des lignes pour additionner le temps par # dans la session, et voyez un total journalier par # lorsque vous mettez les # en t\xeate.",sessionDayTaskBreakdownColWall:"Murale (ce jour)",sessionDayTaskBreakdownColTask:"T\xe2che",sessionDayTaskBreakdownColTags:"Par #",sessionDayTaskBreakdownColTime:"Enregistr\xe9",sessionDayTaskBreakdownTotalPlanned:"Planifi\xe9",sessionDayBreakdownPlannedPrefix:"planifi\xe9",sessionDayTaskBreakdownTotalTasks:"Somme t\xe2ches",sessionDayTaskBreakdownEmptyDay:"Aucune session ce jour-l\xe0 avec les filtres actuels.",sessionDayTaskBreakdownAddPastSession:"Ajouter une session pass\xe9e pour ce jour…",sessionDayTaskBreakdownNoTasksInRange:"Aucun temps de t\xe2che dans la plage pour cette session (ou t\xe2ches exclues par les r\xe8gles d’archives).",sessionDayTaskBreakdownHelpAria:"Aide : sessions par jour avec ventilation des t\xe2ches",sessionDayTaskBreakdownHelpBody:"Les sessions sont regroup\xe9es par jour de session (m\xeame regroupement que le graphique \xab sessions par jour \xbb). Les minutes de t\xe2che sont les portions de la dur\xe9e enregistr\xe9e dont les jours calendaires tombent dans la plage choisie. Les t\xe2ches planifi\xe9es (cr\xe9neau futur) n’entrent pas dans les totaux enregistr\xe9s : leur fen\xeatre horaire planifi\xe9e s’affiche \xe0 part en ambre. Le filtre d’\xe9tiquettes s’applique : seules les t\xe2ches correspondantes sont list\xe9es ; une session sans aucune t\xe2che correspondante dispara\xeet enti\xe8rement. Sous chaque t\xe2che, chaque ligne # distincte affiche la dur\xe9e compl\xe8te de la ligne (m\xeame r\xe8gle que les grilles d’allocation #). Le bascule permet la lecture t\xe2che → # (tableau par d\xe9faut) ou # → t\xe2che (regroupement par # avec sous-totaux par session ; en mode # d’abord, un encart r\xe9sume les m\xeames tranches sur toutes les sessions du jour). Le choix est m\xe9moris\xe9 dans ce navigateur.",tocSessionDayTaskBreakdown:"Sessions par jour (t\xe2ches)",sessionDayBreakdownOrderLegend:"Ordre des lignes",sessionDayBreakdownOrderGroupAria:"Ordre des lignes pour le d\xe9tail sessions par jour",sessionDayBreakdownOrderTasksFirst:"T\xe2che → #",sessionDayBreakdownOrderTagsFirst:"# → t\xe2che",sessionDayBreakdownDayTagRollupTitle:"Totaux du jour par #",sessionDayBreakdownRollupColTag:"\xc9tiquette",sessionDayBreakdownRenameSessionHint:"Cliquer pour renommer cette session",sessionDayBreakdownRenameSessionAria:"Nom de la session",sessionDayBreakdownRenameTaskHint:"Cliquer pour renommer cette t\xe2che",sessionDayBreakdownRenameTaskAria:"Nom de la t\xe2che",dayMarkerLabel:"Type de jour",dayMarkerNone:"Jour travaill\xe9",dayMarkerBusy:"Enregistrement…",legendSessions:"Sessions",legendDone:"Termin\xe9es",legendActive:"En cours",tableDay:"Jour",tableSessions:"Sessions",tableDone:"Termin\xe9es",tableActive:"En cours",tableTaskTime:"Temps (t\xe2ches)",tableTaskTimeNonConcurrent:"Temps (t\xe2ches, non concurrent)",tableSessionCoding:"Codage (sessions)",tableSessionWall:"Dur\xe9e session",undatedLabel:"Sans date",loading:"Chargement…",noRowsInRange:"Aucune donn\xe9e dans cette plage pour les filtres actuels.",projectSectionTitle:"Temps enregistr\xe9 par projet",projectWeeklyCalendarTitle:"Calendrier hebdomadaire",projectColProject:"Projet",projectColTasks:"T\xe2ches",projectColTime:"Temps enregistr\xe9",projectUnassigned:"(sans projet)",projectTableHint:"Une ligne par semaine calendaire, puis un tableau : chaque projet sur sa propre ligne, sept colonnes jour et le total de la semaine — m\xeame navigation par semaine et m\xeame premier jour de semaine que le calendrier par \xe9tiquette ci-dessus. Utilisez le contr\xf4le Travail (@) / Personnel (!) sous le titre pour changer de registre : Travail (d\xe9faut) exclut le registre personnel ; Personnel n’affiche que celui-ci (t\xe2ches marqu\xe9es personnelles, ou titre avec jeton ! reconnu si le drapeau n’a pas \xe9t\xe9 enregistr\xe9), avec le pr\xe9fixe \xab ! \xbb.",projectScopeLegend:"Registre projet",projectScopeGroupAria:"Temps par projet : registre travail ou personnel",projectScopeWork:"Travail (@)",projectScopePersonal:"Personnel (!)",tagTimeSectionTitle:"Temps enregistr\xe9 par \xe9tiquette",tagTimeSectionHint:"Chaque #tag peut correspondre \xe0 une cl\xe9 externe (ex. poste WBS ou NWA dans SAP). La dur\xe9e enregistr\xe9e compl\xe8te d’une t\xe2che est compt\xe9e pour chaque \xe9tiquette associ\xe9e (additionner les lignes peut d\xe9passer le temps r\xe9el). Le pied du calendrier hebdo affiche le temps enregistr\xe9 une fois par t\xe2che et par jour — pas la somme des lignes #. Plusieurs \xe9tiquettes `projet#code` pour un m\xeame projet sont regroup\xe9es sous une ligne @projet : d\xe9veloppez-la pour voir chaque ligne d’\xe9tiquette.",tagTimeByDayTitle:"Par jour calendaire",tagTimeByWeekTitle:"Calendrier hebdomadaire",tagWeekStartsOnLegend:"La semaine commence",weekStartsMonday:"Lundi",weekStartsSunday:"Dimanche",weekStartsSaturday:"Samedi",tagWeekSumColumn:"Σ semaine",weekCalendarDayTotalsRow:"Total jour",tagWeekDistinctDayTotalsRow:"Temps enregistr\xe9 (par t\xe2che)",tagTimeColTag:"\xc9tiquette",tagTimeColDay:"Jour (t\xe2che)",tagTimeColMinutes:"Temps enregistr\xe9",tagTimeUntagged:"d\xe9faut",tagWeekScopedRollupToggleAria:"Afficher ou masquer le d\xe9tail des \xe9tiquettes pour ce projet",summaryLinesWrittenTotal:"Lignes \xe9crites (sessions dans la plage)",summaryLinesWrittenHuman:"Lignes — humain (estim., somme)",summaryLinesWrittenAi:"Lignes — IA (estim., somme)",locByLanguageSectionTitle:"Lignes par langage (agr\xe9g\xe9)",locByLanguageColLang:"Langage",locByLanguageColLines:"Lignes",codingSignalsSectionTitle:"Signaux de codage par langage (agr\xe9g\xe9)",codingSignalsColLang:"Langage",codingSignalsColCount:"Signaux",locMetricsHint:"Les totaux additionnent les compteurs enregistr\xe9s par session pour les sessions dans la plage (m\xeame r\xe8gle que le temps de codage des sessions). Le filtre d’\xe9tiquettes exclut encore toute la session si aucune t\xe2che ne correspond.",workspaceSnapshotTitle:"Dossier ouvert — lignes par langage (instantan\xe9)",workspaceSnapshotIntro:"Ind\xe9pendant des sessions et des t\xe2ches : estimation du nombre de lignes dans le premier dossier du workspace (fichiers suivis par Git si possible, sinon parcours avec extensions courantes). Mise en cache ~5 minutes.",workspaceSnapshotRefresh:"Rafra\xeechir l’instantan\xe9",workspaceSnapshotRefreshing:"Actualisation…",workspaceSnapshotSourceGit:"Source : fichiers suivis par Git",workspaceSnapshotSourceWalk:"Source : parcours du dossier (sans Git ou liste Git vide)",workspaceSnapshotTotalLines:"Total de lignes (approx.)",workspaceSnapshotFileCount:"Fichiers parcourus",workspaceSnapshotColLang:"Langage",workspaceSnapshotColLines:"Lignes",workspaceSnapshotColPercent:"Part",workspaceSnapshotNoWorkspace:"Aucune racine de workspace configur\xe9e pour l’instantan\xe9.",workspaceSnapshotEmpty:"Aucun fichier source correspondant trouv\xe9.",workspaceSnapshotError:"Impossible de construire l’instantan\xe9.",workspaceSnapshotRefreshHint:"Utilisez \xab Rafra\xeechir l’instantan\xe9 \xbb apr\xe8s un changement de chemins ou d’exclusions du workspace dans les param\xe8tres.",tocTitle:"Sur cette page",tocNavAria:"Rapports — sections de la page",tocSummaryKpis:"Indicateurs de synth\xe8se",tocClosureBreakdown:"Sessions par type de cl\xf4ture",closureBreakdownTitle:"Sessions par type de cl\xf4ture",closureBreakdownUnspecified:"Sans cat\xe9gorie (ouverte ou non enregistr\xe9e)",tocDailyTable:"Tableau par jour",tocTagTimeSection:"Temps par \xe9tiquette",weekNavPrev:"Semaine pr\xe9c\xe9dente",weekNavNext:"Semaine suivante",weekNavAriaLabel:"Navigation par semaine pour les graphiques et tableaux",tocWeekNav:"Navigation par semaine",weekNavHelpHint:"Affich\xe9 lorsque plusieurs semaines dans la plage ont des donn\xe9es de session (dur\xe9e murale ou nombre de sessions), sinon des semaines issues du temps enregistr\xe9 par \xe9tiquette ou par projet. Les graphiques, le tableau par jour et les calendriers hebdomadaires suivent la semaine s\xe9lectionn\xe9e.",weekNavNoTagDataThisWeek:"Aucun temps de t\xe2che enregistr\xe9 pour cette semaine.",weekNavNoProjectDataThisWeek:"Aucun temps de t\xe2che par projet pour cette semaine.",tocLocSection:"Lignes et signaux de codage",tocViewTabs:"Vues (onglets)",reportingViewTabBilling:"Allocation facturation",reportingViewTabRhythm:"Rythme",reportingViewTabAdvanced:"Avanc\xe9",reportingViewTabGroupAria:"Vues des rapports",reportingViewBillingIntro:"Associez le temps enregistr\xe9 aux #\xe9tiquettes et aux @projets pour vos codes de facturation. Les totaux suivent les m\xeames filtres qu’en haut ; le travail encore ouvert est rappel\xe9 dans Filtres le cas \xe9ch\xe9ant.",reportingViewTabBillingDesc:"R\xe9partissez le temps enregistr\xe9 par #\xe9tiquette et @projet sur des grilles hebdomadaires pour codifier des lignes de facturation client, des postes WBS SAP ou des cl\xe9s de refacturation interne.",reportingViewTabRhythmDesc:"Consultez les graphiques d’activit\xe9 par jour et la liste sessions-par-jour : dur\xe9e murale, temps de t\xe2che enregistr\xe9 et fen\xeatres planifi\xe9es sur la semaine affich\xe9e.",reportingViewTabAdvancedDesc:"Indicateurs de synth\xe8se sur toute la plage filtr\xe9e, tableau jour par jour, lignes et signaux de codage, instantan\xe9 du workspace et r\xe9partition des sessions par type de cl\xf4ture.",billingTaskTimeWeekScope:"Total pour la semaine {weekRange}",scrollToTopAria:"Retour en haut de la page",...{metricHelpSessionsAria:"Aide : sessions dans la plage",metricHelpSessionsBody:"Nombre de sessions dont le jour calendaire (savedAt, ou endAt, ou startAt) tombe dans la plage choisie. Avec un filtre d’\xe9tiquettes, une session n’est compt\xe9e que si au moins une de ses t\xe2ches correspond.",metricHelpTaskRowsAria:"Aide : lignes de t\xe2ches dans la plage",metricHelpTaskRowsBody:"Nombre d’enregistrements de t\xe2ches pris en compte : le jour de la t\xe2che (fin ou d\xe9but) doit \xeatre dans la plage et la t\xe2che doit passer le filtre d’\xe9tiquettes. Les r\xe8gles des sessions archiv\xe9es s’appliquent (t\xe2ches non termin\xe9es parfois exclues).",metricHelpKronoFocusCompletedAria:"Aide : sessions KronoFocus termin\xe9es",metricHelpKronoFocusCompletedBody:"Somme du compteur \xab sessions termin\xe9es \xbb au niveau session enregistr\xe9 sur chaque instantan\xe9, pour les sessions dont le jour est dans la plage. Ce n’est pas par t\xe2che ; c’est l’\xe9tat KronoFocus sauvegard\xe9 avec la session.",metricHelpKronoFocusTasksUsedAria:"Aide : t\xe2ches avec KronoFocus utilis\xe9",metricHelpKronoFocusTasksUsedBody:"Nombre de t\xe2ches dans la plage avec usedKronoFocus, apr\xe8s filtres d’\xe9tiquettes et r\xe8gles d’archivage.",metricHelpKronoFocusCyclesAria:"Aide : cycles KronoFocus (t\xe2ches)",metricHelpKronoFocusCyclesBody:"Somme des kronoFocusCycles sur les t\xe2ches incluses dans la plage (m\xeames filtres que les autres m\xe9triques t\xe2che).",metricHelpTaskTimeAria:"Aide : temps enregistr\xe9 sur les t\xe2ches",metricHelpTaskTimeBody:"Dur\xe9e totale enregistr\xe9e (durationMs) des t\xe2ches incluses, affich\xe9e en heures/minutes. Filtres de jour et d’\xe9tiquettes appliqu\xe9s.",metricHelpSessionCodingAria:"Aide : temps de codage (sessions)",metricHelpSessionCodingBody:"Somme des minutes de codage sauvegard\xe9es par session (codingMinutesSession) pour les sessions dont le jour est dans la plage. Ind\xe9pendant des minuteurs de t\xe2che.",metricHelpSessionActiveAria:"Aide : temps actif (sessions)",metricHelpSessionActiveBody:"Somme des minutes actives sauvegard\xe9es par session (activeMinutes) pour les sessions dans la plage. Bas\xe9 sur les signaux d’activit\xe9 de l’IDE, pas sur le temps t\xe2che.",metricHelpLinesTotalAria:"Aide : lignes \xe9crites (sessions dans la plage)",metricHelpLinesTotalBody:"Somme des linesWrittenTotal de chaque session incluse dans la plage (lignes nettes des modifications suivies, m\xeame d\xe9finition que le tableau de bord).",metricHelpLinesHumanAria:"Aide : lignes — humain (estim.)",metricHelpLinesHumanBody:"Somme des lignes estim\xe9es \xab humain \xbb (linesWrittenHuman) par session dans la plage. La r\xe9partition repose sur une heuristique par modification, pas sur une attribution exacte.",metricHelpLinesAiAria:"Aide : lignes — IA (estim.)",metricHelpLinesAiBody:"Somme des lignes estim\xe9es \xab IA \xbb (linesWrittenAi) par session dans la plage. Les gros blocs ou les modifications multi-plages sont plus souvent class\xe9s c\xf4t\xe9 IA.",metricHelpLocByLangTitleAria:"Aide : lignes par langage (agr\xe9g\xe9)",metricHelpLocByLangTitleBody:"Fusion des couples locByLanguage de chaque session dans la plage : total de lignes nettes par identifiant de langage.",metricHelpCodingSignalsTitleAria:"Aide : signaux de codage par langage (agr\xe9g\xe9)",metricHelpCodingSignalsTitleBody:"Fusion des codingSignalsByLanguage des sessions incluses : nombre d’\xe9v\xe9nements de contexte de codage (ouverture, enregistrement, \xe9dition, \xe9diteur actif, etc.) par langage.",metricHelpChartSessionsAria:"Aide : sessions par jour",metricHelpChartSessionsBody:"Pour chaque jour du graphique, combien de sessions ont leur jour de session dans ce compartiment. M\xeames r\xe8gles de plage et d’\xe9tiquettes que les cartes r\xe9capitulatives.",metricHelpChartTasksAria:"Aide : t\xe2ches par jour et par statut",metricHelpChartTasksBody:"Par jour : vert = t\xe2ches termin\xe9es dans la plage ; ambre = t\xe2ches encore en cours. Filtres de jour et d’\xe9tiquettes ; les sessions archiv\xe9es ont des r\xe8gles de compl\xe9tion plus strictes.",metricHelpChartTaskTimeAria:"Aide : temps enregistr\xe9 sur les t\xe2ches par jour",metricHelpChartTaskTimeBody:"Pour chaque jour, somme des dur\xe9es enregistr\xe9es sur les t\xe2ches (durationMs → minutes) dont le jour de t\xe2che tombe dans ce compartiment. M\xeames r\xe8gles d’\xe9tiquettes et d’archivage que les d\xe9comptes de t\xe2ches. La hauteur des barres est proportionnelle au jour le plus charg\xe9 dans la vue.",metricHelpChartSessionWallAria:"Aide : dur\xe9e murale des sessions par jour",metricHelpChartSessionWallBody:"Par jour calendaire, somme des minutes \xab murales \xbb de session : sessionDurationMinutes enregistr\xe9 si pr\xe9sent, sinon \xe9cart entre startAt et endAt. Rattachement au jour de session (comme le d\xe9compte des sessions). Diff\xe8re du temps de codage (les pauses inactivit\xe9 ne comptent pas comme codage).",metricHelpTblDayAria:"Aide : colonne jour",metricHelpTblDayBody:"Cl\xe9 de jour calendaire (date locale) ou \xab sans date \xbb si aucune date n’a pu \xeatre d\xe9riv\xe9e.",metricHelpTblSessionsAria:"Aide : colonne sessions",metricHelpTblSessionsBody:"Nombre de sessions rattach\xe9es \xe0 ce jour (m\xeames r\xe8gles que le graphique des sessions).",metricHelpTblDoneAria:"Aide : colonne termin\xe9es",metricHelpTblDoneBody:"Nombre de t\xe2ches termin\xe9es rattach\xe9es \xe0 ce jour.",metricHelpTblActiveAria:"Aide : colonne en cours",metricHelpTblActiveBody:"Nombre de t\xe2ches encore en cours rattach\xe9es \xe0 ce jour.",metricHelpTblTaskTimeAria:"Aide : colonne — temps enregistr\xe9 (t\xe2ches)",metricHelpTblTaskTimeBody:"Somme des durationMs (en minutes) pour les t\xe2ches rattach\xe9es \xe0 ce jour calendaire — m\xeame base que \xab Temps enregistr\xe9 sur les t\xe2ches \xbb dans la synth\xe8se et qu’un total type feuille de temps / Jira par jour.",metricHelpTblSessionCodingAria:"Aide : colonne — temps de codage (sessions)",metricHelpTblSessionCodingBody:"Somme des codingMinutesSession pour les sessions dont le jour de session correspond \xe0 cette ligne. Repose sur le jour de session (pas le jour de t\xe2che), comme la colonne \xab Sessions \xbb.",metricHelpTblSessionWallAria:"Aide : colonne — dur\xe9e murale (sessions)",metricHelpTblSessionWallBody:"Total des minutes \xab murales \xbb pour les sessions de ce jour de session : dur\xe9e persist\xe9e ou startAt→endAt. \xc0 comparer au \xab Codage (sessions) \xbb (temps de frappe actif seulement).",metricHelpSessionWallSummaryAria:"Aide : dur\xe9e murale des sessions (synth\xe8se)",metricHelpSessionWallSummaryBody:"Somme des minutes murales pour chaque session incluse dans la plage (r\xe8gles de jour de session et d’\xe9tiquettes). Ind\xe9pendant des minuteurs de t\xe2che ; compl\xe8te les temps de codage et d’activit\xe9.",metricHelpTagTimeSectionAria:"Aide : temps par \xe9tiquette (type WBS / SAP)",metricHelpTagTimeSectionBody:"Temps enregistr\xe9 sur les t\xe2ches (durationMs) rattach\xe9 \xe0 chaque #tag. La dur\xe9e compl\xe8te est compt\xe9e pour chaque \xe9tiquette de la t\xe2che (en additionnant les lignes par \xe9tiquette, le total peut d\xe9passer celui des indicateurs lorsque des t\xe2ches portent plusieurs \xe9tiquettes). Les t\xe2ches sans \xe9tiquette explicite sont regroup\xe9es dans le compartiment par d\xe9faut (affich\xe9 \xab d\xe9faut \xbb en fran\xe7ais). M\xeames filtres de dates, d’\xe9tiquettes et r\xe8gles d’archivage que les autres m\xe9triques t\xe2che.",metricHelpTagTimeDayTableAria:"Aide : tableau temps par \xe9tiquette et par jour",metricHelpTagTimeDayTableBody:"Une ligne par \xe9tiquette et par jour de t\xe2che, avec la somme des minutes pour ce couple. Les lignes sont regroup\xe9es par jour calendaire ; plusieurs \xe9tiquettes `projet#code` pour un m\xeame projet le m\xeame jour sont sous une ligne de synth\xe8se @projet — d\xe9veloppez pour voir chaque \xe9tiquette.",metricHelpTagTimeWeekTableAria:"Aide : calendrier hebdomadaire par \xe9tiquette",metricHelpTagTimeWeekTableBody:"Sept cases pour les jours de la semaine plus une colonne total : minutes enregistr\xe9es sur les t\xe2ches pour chaque date, dans l’ordre impos\xe9 par le premier jour de semaine choisi (lundi, dimanche ou samedi). La p\xe9riode rapide \xab Semaine \xbb des filtres reste lundi–dimanche ; seule cette grille suit votre r\xe9glage.",metricHelpTagWeekCalendarAria:"Aide : colonnes du calendrier hebdomadaire",metricHelpTagWeekCalendarBody:"Pour chaque semaine calendaire, la p\xe9riode s’affiche une seule fois au-dessus d’un tableau unique : une ligne par \xe9tiquette, les colonnes sont les sept jours locaux (selon le premier jour de semaine) plus le total de la semaine. Chaque en-t\xeate de colonne indique le jour de la semaine et la date calendaire r\xe9elle ; survolez un en-t\xeate ou une case jour pour la date exacte (AAAA-MM-JJ). Lorsque plusieurs \xe9tiquettes suivent le motif `projet#code` pour un m\xeame projet, elles sont regroup\xe9es sous une ligne de synth\xe8se @projet ; le chevron permet de d\xe9velopper le d\xe9tail par \xe9tiquette et par minutes.",metricHelpTagWeekDistinctTotalsAria:"Aide : ligne de pied du calendrier par #",metricHelpTagWeekDistinctTotalsBody:"Par jour calendaire et pour la colonne semaine : temps enregistr\xe9 sur les t\xe2ches, compt\xe9 une fois par t\xe2che (m\xeame base que l’indicateur de synth\xe8se et les graphiques Rythme). Ce n’est pas la somme des lignes # ci-dessus — une t\xe2che multi-\xe9tiquettes affiche toujours sa dur\xe9e compl\xe8te sur chaque ligne # pour le rattachement WBS.",metricHelpTagWeekStartsOnAria:"Aide : premier jour de la semaine",metricHelpTagWeekStartsOnBody:"D\xe9termine quel jour commence la bande des 7 jours : lundi (habitude ISO), dimanche (habitude nord-am\xe9ricaine) ou samedi. M\xe9moris\xe9 uniquement dans ce navigateur (localStorage).",metricHelpWeekNavAria:"Aide : navigation par semaine",metricHelpWeekNavBody:"Pr\xe9c\xe9dente / suivante fait d\xe9filer une semaine \xe0 la fois parmi les semaines qui ont une dur\xe9e murale de session ou au moins une session dans la plage filtr\xe9e. Sinon, les semaines proviennent du temps enregistr\xe9 par \xe9tiquette ou par @projet. Les graphiques en barres, le tableau par jour et les deux calendriers hebdomadaires (\xe9tiquettes et projets) ne montrent que la semaine s\xe9lectionn\xe9e (sept jours locaux selon le premier jour de semaine).",metricHelpTagTimeColTagAria:"Aide : colonne \xe9tiquette",metricHelpTagTimeColTagBody:"\xc9tiquette Kronosys (#tag) ; peut servir de libell\xe9 pour la cl\xe9 saisie \xe0 l’ext\xe9rieur (ex. \xe9l\xe9ment WBS).",metricHelpTagTimeColDayAria:"Aide : colonne jour",metricHelpTagTimeColDayBody:"Jour de la t\xe2che (horodatage de fin ou de d\xe9but), AAAA-MM-JJ.",metricHelpTagTimeColWeekAria:"Aide : ligne de p\xe9riode",metricHelpTagTimeColWeekBody:"Cette ligne nomme la semaine calendaire une seule fois pour le tableau ci-dessous (dates locales). La fronti\xe8re de semaine suit le r\xe9glage \xab La semaine commence \xbb.",metricHelpTagTimeColMinutesAria:"Aide : colonne minutes",metricHelpTagTimeColMinutesBody:"Somme des minutes de t\xe2che attribu\xe9es \xe0 cette \xe9tiquette sur la p\xe9riode de la ligne. Les minutes ne sont pas r\xe9parties entre les \xe9tiquettes : une t\xe2che multi-\xe9tiquettes compte sa dur\xe9e enti\xe8re sur chaque ligne d’\xe9tiquette.",metricHelpProjectTitleAria:"Aide : temps enregistr\xe9 par projet",metricHelpProjectTitleBody:"Dur\xe9e enregistr\xe9e sur les t\xe2ches (durationMs) ventil\xe9e par le champ projet de chaque t\xe2che, sous forme de calendrier hebdomadaire : une ligne de p\xe9riode par semaine, puis un tableau avec une ligne par projet et sept colonnes jour plus le total de la semaine. Utilisez le s\xe9lecteur Travail (@) / Personnel (!) pour choisir le registre : Travail (d\xe9faut) ne compte que les t\xe2ches non personnelles ; Personnel compte les t\xe2ches marqu\xe9es personnelles (`personalProject`) et celles dont le titre contient un jeton `!` reconnu (repli si le drapeau n’a pas \xe9t\xe9 enregistr\xe9), avec libell\xe9s \xab ! \xbb. M\xeames plage de dates, filtre d’\xe9tiquettes, r\xe8gles d’archivage et navigation par semaine que le calendrier par \xe9tiquette.",metricHelpProjectCalendarAria:"Aide : calendrier hebdomadaire par projet",metricHelpProjectCalendarBody:"M\xeame pr\xe9sentation que le calendrier par \xe9tiquette : pour chaque semaine, la plage de dates s’affiche une fois ; chaque ligne correspond \xe0 un projet pour le registre choisi (Travail ou Personnel). Les en-t\xeates de colonnes indiquent le jour de la semaine et la date calendaire ; les cases jour utilisent le jour de la t\xe2che (fin ou d\xe9but) ; survol d’un en-t\xeate ou d’une case pour AAAA-MM-JJ.",metricHelpProjectColProjAria:"Aide : colonne projet",metricHelpProjectColProjBody:"Nom du projet sur la t\xe2che (avec @ ou ! selon le registre), ou \xab sans projet \xbb si absent.",metricHelpProjectColTasksAria:"Aide : colonne t\xe2ches",metricHelpProjectColTasksBody:"Nombre de lignes de t\xe2ches agr\xe9g\xe9es pour ce projet.",metricHelpProjectColTimeAria:"Aide : colonne temps enregistr\xe9",metricHelpProjectColTimeBody:"Total des minutes enregistr\xe9es sur les t\xe2ches pour ce projet sur les sept jours de la ligne (durationMs), pour le registre Travail ou Personnel s\xe9lectionn\xe9.",metricHelpWorkspaceTitleAria:"Aide : instantan\xe9 du dossier ouvert",metricHelpWorkspaceTitleBody:"Instantan\xe9 du premier dossier du workspace : lignes par langage \xe0 partir des fichiers suivis par Git ou d’un parcours du dossier. Ind\xe9pendant des sessions Kronosys ; mis en cache ~5 minutes. Voir le paragraphe descriptif sous le titre.",metricHelpWsTotalLinesAria:"Aide : total de lignes (approx.)",metricHelpWsTotalLinesBody:"Total approximatif de lignes lues dans les fichiers source (extensions reconnues), pour cet instantan\xe9.",metricHelpWsFileCountAria:"Aide : fichiers parcourus",metricHelpWsFileCountBody:"Nombre de fichiers ayant contribu\xe9 \xe0 l’instantan\xe9 (apr\xe8s filtres de taille et de type).",metricHelpWsColLangAria:"Aide : colonne langage",metricHelpWsColLangBody:"Identifiant de langage (style TextMate) d\xe9duit de l’extension du fichier.",metricHelpWsColLinesAria:"Aide : colonne lignes",metricHelpWsColLinesBody:"Nombre de lignes pour ce langage dans les fichiers parcourus.",metricHelpWsColPercentAria:"Aide : colonne part",metricHelpWsColPercentBody:"Pourcentage du total de lignes de l’instantan\xe9 pour ce langage (la somme des arrondis peut diff\xe9rer l\xe9g\xe8rement de 100 %).",metricHelpAggLocColLangAria:"Aide : langage (lignes agr\xe9g\xe9es)",metricHelpAggLocColLangBody:"Identifiant de langage (style TextMate) ; les valeurs sont additionn\xe9es sur les sessions dans la plage.",metricHelpAggLocColLinesAria:"Aide : lignes (agr\xe9g\xe9)",metricHelpAggLocColLinesBody:"Total des lignes nettes \xe9crites dans ce langage pour les sessions incluses.",metricHelpAggSigColLangAria:"Aide : langage (signaux)",metricHelpAggSigColLangBody:"Identifiant de langage pour les comptes de signaux agr\xe9g\xe9s.",metricHelpAggSigColCountAria:"Aide : nombre de signaux",metricHelpAggSigColCountBody:"Total de signaux de contexte de codage pour ce langage sur les sessions incluses.",metricHelpLegendDoneAria:"Aide : l\xe9gende — t\xe2ches termin\xe9es",metricHelpLegendDoneBody:"Segment vert : t\xe2ches marqu\xe9es termin\xe9es pour ce jour (m\xeames filtres que le graphique).",metricHelpLegendActiveAria:"Aide : l\xe9gende — en cours",metricHelpLegendActiveBody:"Segment ambre : t\xe2ches non termin\xe9es pour ce jour.",metricHelpLegendSessionsAria:"Aide : l\xe9gende — sessions",metricHelpLegendSessionsBody:"Hauteur de chaque barre : nombre de sessions dont le jour de session correspond \xe0 cette colonne (m\xeames r\xe8gles de plage et d’\xe9tiquettes).",metricHelpAssiduityRefAria:"Aide : sessions avec heure de d\xe9but de r\xe9f\xe9rence",metricHelpAssiduityRefBody:"Sessions de la plage pour lesquelles l’h\xf4te a enregistr\xe9 un instant de d\xe9but pr\xe9vu \xe0 l’ouverture (`scheduledStartAt` sur l’action `newSession`). Seul l’encha\xeenement qui lance la session (p. ex. moteur d’horaire) fournit en g\xe9n\xe9ral ce champ : une nouvelle session lanc\xe9e depuis le seul tableau de bord n’y a pas, sauf int\xe9gration. M\xeames r\xe8gles de jour de session et d’\xe9tiquettes que le comptage des sessions.",metricHelpAssiduityLateCountAria:"Aide : sessions en retard (assiduit\xe9)",metricHelpAssiduityLateCountBody:"Parmi les sessions r\xe9f\xe9renc\xe9es, combien ont d\xe9marr\xe9 apr\xe8s l’instant pr\xe9vu (\xe9cart strictement positif en minutes). Un d\xe9marrage \xe0 l’heure ou en avance n’augmente pas ce compteur.",metricHelpAssiduityLateTotalAria:"Aide : retard cumul\xe9",metricHelpAssiduityLateTotalBody:"Somme des retards (minutes) session par session dans la plage, en ne comptant que la partie tardive (les d\xe9marrages \xe0 l’heure ou avant comptent 0).",metricHelpAssiduityAvgLateAria:"Aide : retard moyen (lorsqu’en retard)",metricHelpAssiduityAvgLateBody:"Retard cumul\xe9 divis\xe9 par le nombre de sessions en retard ; indiqu\xe9 en \xab — \xbb s’il n’y en a pas. Pertinent lorsqu’une heure de d\xe9but a \xe9t\xe9 enregistr\xe9e c\xf4t\xe9 h\xf4te.",metricHelpClosureBreakdownAria:"Aide : sessions par type de cl\xf4ture",metricHelpClosureBreakdownBody:"Nombre de sessions incluses par cat\xe9gorie enregistr\xe9e \xe0 la fin de session (conforme au pr\xe9vu, anticip\xe9e, prolongation, autre). \xab Sans cat\xe9gorie \xbb regroupe les sessions encore ouvertes et celles termin\xe9es sans choix enregistr\xe9. M\xeames r\xe8gles de jour de session et d’\xe9tiquettes que \xab Sessions (plage) \xbb ; la somme des cinq lignes \xe9gale ce total.",metricHelpSummaryKpisSectionAria:"Aide : indicateurs de synth\xe8se",metricHelpSummaryKpisSectionBody:"Les cartes agr\xe8gent sessions et t\xe2ches sur toute la plage de dates et d’\xe9tiquettes — pas la semaine choisie dans Allocation facturation et Rythme. Les m\xe9triques session utilisent le jour de session ; le temps de t\xe2che, le jour de t\xe2che. Sessions archiv\xe9es : les totaux bas\xe9s sur les t\xe2ches n’incluent que les t\xe2ches enti\xe8rement termin\xe9es (sous-t\xe2ches incluses). KronoFocus suit la m\xeame r\xe9partition session/t\xe2che qu’ailleurs sur cette page.",metricHelpLocMetricsSectionAria:"Aide : lignes et signaux de codage",metricHelpLocMetricsSectionBody:"Les totaux additionnent les compteurs enregistr\xe9s par session pour les sessions dont le jour est dans la plage. Le filtre d’\xe9tiquettes exclut toute la session si aucune t\xe2che ne correspond. Les tableaux \xab Lignes par langage \xbb et \xab Signaux de codage \xbb agr\xe8gent le m\xeame ensemble de sessions.",metricHelpDailyTableSectionAria:"Aide : tableau par jour",metricHelpDailyTableSectionBody:"Une ligne par jour calendaire dans la plage filtr\xe9e. Les colonnes session utilisent le jour de session ; le temps de t\xe2che, le jour de t\xe2che. \xab Temps t\xe2che (non concurrent) \xbb retire le chevauchement entre intervalles horodat\xe9s ce jour-l\xe0. Le filtre d’\xe9tiquettes s’applique aux colonnes t\xe2che ; les sessions sans t\xe2che correspondante sont omises des comptages session."}};function g(a){return"fr"===a?f:e}function h(a){let b=g(a),c=(0,d.z)(a);return{dashboard:b.dashboard,reporting:b.reporting,settings:b.settings,logs:b.logs,guide:b.guide,implementation:b.implementation,changelog:b.changelog,dashboardAttentionHint:c.navDashboardPlannedConflictPulseHint,navGanttDashboardOnlyTooltip:b.navGanttDashboardOnlyTooltip,navGlobalPauseDashboardOnlyTooltip:b.navGlobalPauseDashboardOnlyTooltip,navGlobalPauseNoSessionContextTooltip:b.navGlobalPauseNoSessionContextTooltip,navChangelogUnavailableTooltip:b.navChangelogUnavailableTooltip,navGanttButtonLabel:b.navGanttButtonLabel,navGlobalPauseButtonLabel:b.navGlobalPauseButtonLabel,navGroupAppAria:c.appShellRouteNavGroupAppAria,navGroupDocsAria:c.appShellRouteNavGroupDocsAria,navGroupToolsAria:c.appShellRouteNavGroupToolsAria}}},55435:(a,b,c)=>{"use strict";c.d(b,{DataEnvironmentChrome:()=>d});let d=(0,c(77943).registerClientReference)(function(){throw Error("Attempted to call DataEnvironmentChrome() from the server but DataEnvironmentChrome is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/dashboard/DataEnvironmentChrome.tsx","DataEnvironmentChrome")},58032:(a,b,c)=>{"use strict";c.d(b,{Z:()=>g});var d=c(73024),e=c(76760);function f(a){try{let b=d.readFileSync(a,"utf8"),c=JSON.parse(b).version;if("string"==typeof c&&c.trim().length>0)return c.trim()}catch{}return null}function g(){let a=process.env.KRONOSYS_APP_VERSION?.trim();if(a)return a;let b=process.cwd(),c=f(e.join(b,"kronosys-package-meta.json"));return c||(f(e.join(b,"package.json"))??"0.0.0")}},58857:(a,b,c)=>{Promise.resolve().then(c.bind(c,48528)),Promise.resolve().then(c.bind(c,31066)),Promise.resolve().then(c.bind(c,55435)),Promise.resolve().then(c.bind(c,49194)),Promise.resolve().then(c.bind(c,77071)),Promise.resolve().then(c.bind(c,67227)),Promise.resolve().then(c.bind(c,90665)),Promise.resolve().then(c.bind(c,84490)),Promise.resolve().then(c.bind(c,93356)),Promise.resolve().then(c.bind(c,9576)),Promise.resolve().then(c.bind(c,25876)),Promise.resolve().then(c.bind(c,11081)),Promise.resolve().then(c.bind(c,90595)),Promise.resolve().then(c.bind(c,17843)),Promise.resolve().then(c.t.bind(c,23318,23))},59899:(a,b,c)=>{"use strict";c.d(b,{r:()=>g,z:()=>f});let d={kronoFocusTitle:"KronoFocus",workMode:"KronoFocus",breakMode:"Short break",longBreakMode:"Long break",kronoFocusStart:"Start",kronoFocusPause:"Pause",kronoFocusReset:"Reset",kronoFocusControlsReadOnlyTooltip:"Read-only while you inspect an archive — these controls target the live session.",kronoFocusLinkedTaskIntro:"Started from:",kronoFocusEditDurationTitle:"Configure KronoFocus rhythm (timer not started)",kronoFocusDurationPickerLabel:"Duration (hours : minutes : seconds)",kronoFocusApplyDuration:"Apply",kronoFocusCancelDurationEdit:"Cancel",kronoFocusDurationHelpAriaLabel:"Duration help",kronoFocusDurationHelpBody:"Enter the work segment length as hours, minutes, and seconds (elapsed time, e.g. 00:25:00 or 01:30:00 — not a time of day). You may omit seconds (e.g. 0:25). Range: 1 minute to 8 hours. Short and long breaks are set in whole minutes in the same dialog. Set everything before starting KronoFocus.",kronoFocusDurationInputPlaceholder:"00:25:00",kronoFocusDefaultWorkDuration:"Default — 00:25:00",kronoFocusDurationHistoryLabel:"Recent custom durations",kronoFocusDurationHistoryPickAria:"Select duration {time}",kronoFocusDurationHistoryClear:"Clear",kronoFocusDurationHistoryClearTitle:"Clear all saved custom durations",kronoFocusRhythmPresetsHeading:"Quick presets (work / short / long break)",kronoFocusRhythmPresetLabels:["25 / 5","50 / 10","45 / 15","52 / 17"],kronoFocusRhythmPresetTitles:["25 min work, 5 min short break, 15 min long break after every 4 work segments","50 min work, 10 min short break, 20 min long break after every 4 work segments","45 min work, 15 min short break, 15 min long break after every 4 work segments","52 min work, 17 min short break, 30 min long break after every 4 work segments"],kronoFocusShortBreakMinutesLabel:"Short break (minutes)",kronoFocusLongBreakMinutesLabel:"Long break (minutes)",kronoFocusRhythmBreaksMinutesHint:"Whole minutes, 1–480 each. Long break runs after every 4 completed work segments.",startTaskWithKronoFocus:"Also start the KronoFocus timer",startTaskWithKronoFocusToggleAriaOff:"Also start KronoFocus when tracking begins — off. Press to turn on.",startTaskWithKronoFocusToggleAriaOn:"Also start KronoFocus when tracking begins — on. Press to turn off.",startKronoFocusFromActiveTask:"Start KronoFocus",startKronoFocusFromTaskConfirm:"KronoFocus is already running or paused. Reset the timer and start a new work segment?",launcherTitle:"Tasks",taskPlaceholder:"What are you working on?",taskNoteLabel:"Task note",taskNoteAddBtn:"Add a note",taskNotePlaceholder:"Add a free-form note for this task…",taskNoteEditHint:"Click to edit note (Markdown supported)",taskMarkdownHelpAriaLabel:"Markdown help for task notes",taskMarkdownHelpIntro:"Use **Add a note** on the task card or launcher to open the field. Saved notes render as Markdown (GFM subset, GitLab/GitHub compatible). Task titles support inline Markdown in read-only mode.",taskMarkdownHelpNoteHeading:"Note (block)",taskMarkdownHelpTitleHeading:"Title (inline when reading)",taskMarkdownHelpSecurity:"Raw HTML is not allowed; external links open in a new tab.",taskMarkdownHelpGfmLimits:"Supported: bold, italic, strikethrough, lists, task checkboxes, tables, autolinks, images (http/https). Not supported: Mermaid, math, GitLab @mentions/#issues, alert blocks, emoji shortcuts.",taskPlaceholderPast:"What did you work on?",archiveAddTaskIntro:"Past entry: open the time-range modal to set start and end (end is prefilled from start plus the minimum duration in Settings). Adjust timer duration (h/m/s) if needed. Tags and @project work as usual; live timers and detail items do not apply — live or archived session.",archiveAddTaskIntroHelpAria:"Help: past entry",taskEntryModeRealtime:"Real-time",taskEntryModePast:"Past/planned",taskEntryModeGroupAria:"Entry mode",archiveTaskStartLabel:"Start",archiveTaskEndLabel:"End",taskTimingDurationLabel:"Duration",taskTimingAdjustModalTitle:"Adjust duration?",taskTimingAdjustModalMessage:"You changed task timing. Choose how duration should be recalculated.",taskTimingAdjustKeepDuration:"Keep the recorded timer duration",taskTimingAdjustManualDuration:"Set duration manually (h/m/s)",taskTimingAdjustFromBounds:"Set duration from start/end timestamps",taskTimingAdjustHours:"Hours",taskTimingAdjustMinutes:"Minutes",taskTimingAdjustSeconds:"Seconds",taskTimingAdjustLapSectionTitle:"Running timer lap (lap #{n})",taskTimingAdjustLapKeep:"Keep this lap as-is (lap timestamps unchanged)",taskTimingAdjustLapFlush:"Close this lap now (save it as a completed lap)",taskTimingAdjustLapAlignStart:"Realign this lap to the new task start",taskTimingAdjustModalMessageRunning:"You changed the task start while a timer lap is running. Choose what to do with that lap and how total duration should be recalculated.",taskTimerLapsHeading:"Tracking laps",taskTimerLapDeleteBtn:"Delete lap",taskTimerLapDeleteConfirmTitle:"Delete this lap?",taskTimerLapDeleteConfirmMessage:"This removes the lap from the list and subtracts its duration from the task timer total.",taskTimerLapRunningLabel:"running…",taskStartTimeSaveAria:"Save corrected task start time",sessionStartTimeSaveAria:"Save corrected session start time",taskEndTimeSaveAria:"Save corrected task end time",sessionEndTimeSaveAria:"Save corrected session end time",sessionEndTimeEditSectionTitle:"Session end",sessionStartTimeEditSectionTitle:"Session start",taskPastDatetimePlaceholder:"yy-mm-dd --:--:--",taskPastDatetimeTimeLabel:"Time",taskPastDatetimeHourAria:"Hour (24-hour clock)",taskPastDatetimeMinuteAria:"Minutes",taskPastDatetimeTodayBtn:"Today",taskPastDatetimeNowBtn:"Now",archiveAddTaskBtn:"Add to session",archiveTaskDatetimeRangeInvalid:"Enter a valid start and end; the end must be after the start (local date and time).",archiveTaskTimerDurationLabel:"Timer duration",pastTaskTimingModalTitle:"Past entry — time range",pastTaskTimingEditBtn:"Set start, end & timer duration…",pastTaskTimingSummaryAria:"Edit start, end, and timer duration for past entry",pastTaskTimingModalConfirm:"OK",pastTaskTimingModalCancel:"Cancel",pastTaskTimingEndOptional:"optional",archiveTaskManualDurationInvalid:"Enter a timer duration greater than zero and no longer than the gap between start and end.",activeTaskTitleEditHint:"Click to edit title; type #tags in the field or use the row below",activeTaskTitleInputAria:"Edit title; optional #tags or @project in the field, pills below for existing tags",taskStartBlockedByPlannedBoundaryConflict:"Close the planned-task timer dialog first, then start another task.",plannedTaskScheduleActivatedToast:"Scheduled task is now tracking time: \xab {name} \xbb",plannedTaskScheduleActivatedToastUnnamed:"Untitled task",plannedSessionScheduleActivatedToast:"Scheduled session has started: \xab {name} \xbb",plannedSessionScheduleActivatedToastUnnamed:"Untitled session",startTaskBtn:"Start tracking",taskSaveTemplateBtn:"Save as template",taskAlreadyTemplateBtn:"Already saved as template",taskTemplateSavedToast:"Task template saved.",finishTaskBtn:"Finish",finishTaskOpenSubtasksWarnTitle:"Finish task?",finishTaskOpenSubtasksWarnBody:"This task still has open detail items. They will all be marked done when you finish the task.",reopenTaskBtn:"Reopen",reopenTaskModalTitle:"Reopen this task?",reopenTaskModalMessage:"The task will be active again. Choose how to handle the recorded timer duration.",reopenTaskTimerResume:"Resume timer (keep recorded duration)",reopenTaskTimerPaused:"Reopen paused (keep recorded duration)",reopenTaskTimerManual:"Set duration manually (h/m/s)",reopenTaskTimerReset:"Reset timer to zero",reopenTaskSubtasksNote:"Detail items will be reopened as well.",reopenTaskEndedSessionHint:"This session is closed — the timer cannot run live; duration choices still apply to the snapshot.",taskDeleteBtn:"Delete",taskDuplicateBtn:"Copy task to input",taskDuplicateTooltip:"Copy title, tags, and project to the input field.",taskDeleteConfirm:"Delete this entry? Recorded time will be lost. This cannot be undone.",taskConcurrentTrackingConflictTitle:"Tracking already active",taskConcurrentTrackingConflictMessage:"One or more tasks already have a running timer. Choose what to do with them before starting this task: finish them (moved to completed), pause them (resume later from the paused list), or keep them running and start this task in parallel.",taskConcurrentTrackingConflictPauseBtn:"Pause active tasks",taskConcurrentTrackingConflictFinishBtn:"Finish active tasks",taskConcurrentTrackingConflictParallelBtn:"Start in parallel (keep timers running)",taskConcurrentTrackingDontShowAgain:"Remember this choice and don’t show this dialog again (the same action will run automatically next time).",taskPlannedBoundaryConflictTitle:"Planned task is now live",taskPlannedBoundaryConflictMessage:"A task that was shown under Planned has reached its start time and now counts as running while another timer was already running. Choose what to do with the tasks that were already running: pause them (they move to the paused list), finish them (they move to completed), or keep them running alongside the new one.",taskPlannedBoundaryConflictResolveError:"Could not apply your choice for the running timers. Check the server and try again.",navDashboardPlannedConflictPulseHint:"Dashboard: review the timer conflict dialog",tasksPausedHeading:"Paused",tasksCompletedHeading:"Completed",tasksArchiveOpenHeading:"Unfinished (snapshot)",tasksRunningHeading:"Running now",tasksPlannedHeading:"Planned",tasksTimelineEmpty:"No timed task intervals in this session view.",tasksTimelineGanttOpenBtn:"Gantt",tasksTimelineGanttOpenBtnAria:"Open task timeline as a Gantt-style chart",tasksTimelineGanttTitle:"Task timeline (Gantt)",tasksTimelineGanttDescription:"Timeline aligned on the session start: one row per task; coloured bars are tracked timer intervals. Scroll horizontally when the session spans a long wall-clock range.",tasksTimelineGanttTodayTitle:"Today timeline (Gantt)",tasksTimelineGanttTodayDescription:"Global timeline for the current day: all task intervals across sessions are grouped in one view.",tasksTimelineGanttWindowStartLabel:"Timeline start",tasksTimelineGanttWindowEndLabel:"Timeline end",tasksTimelineGanttLegendWork:"Tracked time",tasksTimelineGanttLegendGap:"Outside this task’s interval",tasksTimelineGanttLegendProductive:"Productive (@ projects)",tasksTimelineGanttLegendPersonal:"Personal (! projects)",tasksTimelineGanttSummaryProductive:"Productive total: {duration}",tasksTimelineGanttSummaryPersonal:"Personal total: {duration}",tasksTimelineGanttCloseBtn:"Close",tasksTimelineGanttTooltipStart:"Start",tasksTimelineGanttTooltipEnd:"End",tasksTimelineGanttTooltipTimer:"Timer duration",tasksTimelineGanttTooltipWall:"Wall-clock span",tasksTimelineGanttTooltipTimerUnknown:"—",tasksTimelineGanttLapsPopoverAria:"Tracking laps for this task segment",ganttColorPickerAria:"Gantt bar color",ganttColorPickerAuto:"Automatic color",ganttColorPickerSwatch:"Color {color}",taskGanttColorLabel:"Gantt bar color",hideTaskList:"Hide list",showAllTasks:"Show full list",pauseTaskBtn:"Pause — moves to the paused list",resumeTaskBtn:"Resume tracking",taskTimerPausedManual:"Timer paused (manual).",pausedNote:"Session is paused because you are inspecting history.",viewingHistoryBannerTitle:"You are viewing a past session.",resumeBtn:"Resume active session",inspectingLabel:"Viewing session:",historyInspectBannerAria:"Past session view",liveSessionWallPausedBannerAria:"Live session paused",liveSessionWallPausedTitle:"Session tracking is paused",liveSessionWallPausedDetail:"Wall-clock time is frozen. Use Resume below or press play on a task — both restart session tracking.",liveSessionResumeWallBtn:"Resume session",autoTagsDetected:"Tags detected",autoProjectDetected:"Project",tagsHelpAriaLabel:"Tag help",tagSyntaxHelp:"#tag after a space or at the start, or glued (word#tag). @project uses the same placement; if you type several @projects, the last one wins (one project per task). Tokens: letters, numbers, -, _ (no spaces).",tagSuggestionsHelp:"Next to this (?), the small field applies a line like #tag, @project, or a plain tag name when you press Enter. Typing #tag in the title is separate.",tagsHelpWorkflowSummary:"Read-only labels above list every tag on the task; the project line shows its project. Edit the title or use the quick field (Enter). @Project#code is optional.",taskAppliedTagsHelpHeading:"Tags on this task",taskAppliedTagsHelpHint:"Everything merged from the title, the new-task field, and the quick line under each task. Type #tag, @project, or a tag name and press Enter; @ alone clears the project.",taskTagsExtraHelpAria:"Help: tags and project applied to this task",taskTagsOrphanProjectHelpBody:"From the title, not in your saved list. Pin under Tags & projects or change the title.",taskTagProjectQuickAddPlaceholder:"#tag, @project or label… Enter (@ alone clears project)",taskTagProjectQuickAddAria:"Quick add: type #tag, @project, or a tag name, then Enter",taskTagProjectMultiGroupTags:"Saved tags",taskTagProjectMultiGroupProjects:"Saved projects",taskTagProjectMultiOptionClearProject:"Clear project (same as @ alone)",taskTagProjectMultiSelectAria:"Multi-select saved tags and projects, then use Add selection",taskTagDefaultBucket:"default",taskTagProjectMultiHint:"Ctrl or ⌘-click to select several rows, then add.",taskTagProjectApplySelectionBtn:"Add selection",tagsUserGuideIntro:"This guide explains how task titles, saved shortcuts, and optional @project#code labels work together. You can ignore advanced features and keep only #tags plus one @project if you prefer.",tagsUserGuideBasicsTitle:"Basics: title tokens",tagsUserGuideBasicsBody:"In the task title you can mix plain text with:\n• #name — a global tag (letters, numbers, hyphen, underscore).\n• @Project — assigns the task to a project (if several @ appear, the last one wins — one project per task).\nTokens can appear after a space or glued to a word (word#tag). The dashboard shows merged tags under the task.",tagsUserGuideShortcutsTitle:"Quick field on each task",tagsUserGuideShortcutsBody:"In Settings → Tags & saved projects (or the Tags column on the right), you pin tags and projects you reuse. On a task, the narrow field next to the tag help (?) suggests those values; press Enter to apply a line (#tag, @project, plain name, or @ alone to clear the project). This does not rewrite the title unless you edit it yourself.",tagsUserGuideScopedTitle:"Optional: @project#code (project-scoped labels)",tagsUserGuideScopedBody:"Syntax @Client#invoice in the title stores a label tied to that project (shown as Client#invoice). Useful when the same local label means different things per client, or for stricter reporting. If you never need that, use #tag + @project only — the product supports both styles.",tagsUserGuideUseCasesTitle:"Use cases",tagsUserGuideUseCasesBody:"• Solo dev, one project: type My feature @acme and #frontend — no saved list required.\n• Many tickets: pin #triage, #bugfix, @sprint-42 in Tags & projects; use the quick field per task instead of retyping.\n• Client work: use @ClientA#retainer vs @ClientB#retainer in titles to keep namespaces separate; filter by project in reporting.\n• Retro entry: same # and @ rules in the past-task form; the quick field still accepts the same syntax.",tagsUserGuideFooterNote:"Descriptions on tags/projects (hover for a few seconds on a chip that has one) are optional notes for your team — they do not change how Kronosys filters data.",subtasksHeading:"Detail items",addSubtaskLinkBtn:"Add a detail item",addSubtaskPlaceholder:"New item…",addSubtaskBtn:"Add",subtaskMarkDone:"Mark this item done",subtaskMarkUndone:"Mark this item not done",subtaskDelete:"Remove this item",subtaskDragReorderHandle:"Drag to reorder",subtaskMoveUp:"Move this item up",subtaskMoveDown:"Move this item down",subtaskTimerStart:"Track time on this item",subtaskTimerStop:"Stop tracking time on this item",subtaskDurationNotMeasured:"Not measured",subtaskDurationNotRecorded:"Not recorded",subtaskDurationNotShown:"Not shown",subtaskDurationTooltipNotMeasured:"No time has been accumulated on this item yet. Use the play control to start tracking.",subtaskDurationTooltipNotRecorded:"This snapshot does not include a duration for this item (not tracked here or missing from the saved snapshot).",subtaskDurationTooltipNotShown:"No duration is shown for completed items without recorded time in this archived view.",noData:"No data yet.",sessionsColumnTitle:"Sessions",sessionsColumnHelpAria:"Help: Sessions column",sessionsColumnHelpBody:"Your saved sessions and the live session appear here while tracking is on.\n\nOpen the active session to edit tracking in real time.",dashboardColSessionTeaser:"Pick the session you’re in (or start one). The rest of the dashboard follows that choice.",dashboardColSessionFlowHint:"Next → Tasks in the middle",dashboardColTasksTeaser:"Log tasks, timers, and KronoFocus — all tied to the session on the left.",dashboardColTasksFlowHint:"Then → Tags & projects on the right",dashboardColTagsTeaser:"Add #tags, @projects, and shortcuts so history and reports stay clear.",dashboardColTagsFlowHint:"Optional, but your future self will notice.",dashboardColumnHintsPanelTitle:"How the three columns work",dashboardColumnHintsExpandAria:"Show how the three dashboard columns work",dashboardColumnHintsCollapseAria:"Hide the column guide",dashboardColumnHintsDismissTitle:"Hide this guide permanently",sessionsListAriaLabel:"Sessions",sessionLiveBadge:"Live",sessionListWallDurationTitle:"Wall-clock session duration: saved minutes when available, otherwise the span from session start to end.",sessionListWallDurationAlertTooltip:"At or past the alert threshold ({hours} h) — adjust under Settings → Web dashboard.",sessionListStartedPrefix:"Start:",sessionListEndedPrefix:"End:",sessionListOpenGanttAria:"Open Gantt timeline for this session",selectedSessionSidebarTimelineIconTooltip:"Gantt",selectedSessionSidebarTimelineIconAria:"Open the horizontal task timeline for this session",sessionEndLiveTitle:"End session — save to history without starting a new one (tracking can stay on)",sessionEndLiveAria:"End current session",sessionEndLiveConfirmTitle:"End this session?",sessionEndLiveConfirmIntro:"There is still open work in this session. Ending saves a snapshot to history: timers and item tracking will no longer run for this session, but you can still edit names, tags, and projects when you open the archived session.",sessionEndLiveConfirmIntroCalm:"Ending saves a snapshot to history with the current end time. Timers and item tracking will no longer run for this session, but you can still edit names, tags, and projects when you open the archived session.",sessionEndLiveWarnActiveTask:"Something is currently being tracked (in progress).",sessionEndLiveWarnPausedTasks:"One or more entries are paused or not finished.",sessionEndLiveWarnIncompleteSubtasks:"One or more items are not marked done.",sessionEndLiveTasksHandlingLegend:"When ending, what should happen to open tasks?",sessionEndLiveTasksHandlingKeep:"Leave tasks unfinished in this session’s snapshot — timers stop (recorded time is kept)",sessionEndLiveTasksHandlingFinish:"Finish open tasks with this session",sessionEndLiveTasksHandlingMoveToPaused:"Move open tasks to a new paused session",sessionEndLiveConfirmBtn:"End session",sessionEndLiveSidebarBtn:"End this session",sessionEndReasonModalHint:"Optional: record why you are closing the session (reports, timesheets, retrospectives).",sessionEndReasonFieldsetLegend:"Closure reason",sessionEndReasonSkip:"Do not save a category",sessionEndReasonPlanned:"Ended as planned (time or scope)",sessionEndReasonEarly:"Ended early (before planned time or deadline)",sessionEndReasonOverrun:"Overrun relative to plan",sessionEndReasonOther:"Other",sessionEndReasonNotePlaceholder:"Optional detail…",sessionEndReasonNoteAria:"Optional free-text detail for how this session ended",selectedSessionEndReasonTitle:"Closure",sessionEndReasonEditHint:"Update the saved closure category or detail for this session.",sessionEndReasonSaveBtn:"Save closure",sessionEndReasonSaveAria:"Save closure reason",sessionEndReasonSaving:"Saving…",beforeUnloadLiveSessionMessage:"A Kronosys session is open in this dashboard. Closing this tab does not end the session. Use “End this session” in the left column to close it here, or leave this tab — the session keeps running in the background.",openSessionInNewTab:"Open this session in a new tab",detachedSessionUrlHint:"This tab is driven by the URL. Inspecting an archive here only updates this tab — it does not change your live session or which session is selected in other open tabs.",detachedSessionUrlHintDismiss:"Hide this note",detachedSessionInvalidUrl:"No session matches this URL parameter.",tasksInSessionSingular:"item",tasksInSessionPlural:"items",rightColumnTitle:"Tasks",tagsProjectsColumnTitle:"Tags, projects & templates",tagsProjectsColumnIntro:"Pin shortcuts, descriptions, and hide chips — same as in Settings, here while you work. Use the two tabs to switch between global tags and projects.",tagsProjectsColumnHelpAria:"Help: tags & projects column",tagsProjectsColumnHelpBody:"Global tags apply to any task. Project-linked tags use Project#code and only appear when that task’s @project matches.\n\nIn this column, the Global tags tab lists shortcuts, hidden tags, and descriptions; the Projects & linked tags tab lists saved projects and per-project codes.\n\nThis column mirrors the Tags & saved projects section in Settings; changes sync immediately.\n\nUse the (?) next to task tags on a card for the full help and use cases.",tasksColumnSubtitle:"Running, planned (future start or end), paused, and completed for the selected session.",tasksColumnSubtitleHelpAria:"Help: what this column shows",taskFocusNoSessionTitle:"No active session",taskFocusNoSessionBody:"Start a session from the Sessions column on the left to track tasks here.",taskStartAutoSessionToast:"No active session — starting one now so your task can be tracked in this session.",selectedSessionSidebarTitle:"Selected session",selectedSessionSidebarTitleLive:"Active session",selectedSessionSidebarTitleIdle:"No active session",selectedSessionSidebarPausedBadgeGlobal:"Global pause",selectedSessionSidebarPausedBadgeSession:"Paused",dashboardPauseBackdropTitleGlobal:"Global pause is on",dashboardPauseBackdropDetailGlobal:"Tracking is frozen for this session, tasks, and subtasks. Resume from the global pause control in the top bar.",dashboardPauseBackdropAriaGlobal:"Dashboard: global pause is active",dashboardPauseBackdropTitleSession:"Session tracking is paused",dashboardPauseBackdropDetailSession:"Wall-clock time and affected timers are frozen. Resume from the banner above Tasks or the usual resume control.",dashboardPauseBackdropAriaSession:"Dashboard: session wall-clock pause is active",sessionNoteLabel:"Session note",sessionNotePlaceholder:"Add a free-form note for this session…",selectedSessionIdleHint:"Start a session from the Sessions column to record time, tracking, and metrics.",sessionDetailsModalTitle:"Session summary",sessionDetailsModalCloseAria:"Close session summary",sessionDetailsModalReopenBtn:"Session summary",statsMetricSessionDurationHelpAria:"Help: session duration",statsMetricSessionDurationHelpBody:"Wall-clock time from the first activity event recorded in this session until now (live session) or until the snapshot was saved (archived). Separate from active time, coding time, and tracking or item timers.",sessionRemainingDurationLabel:"Remaining duration",sessionRemainingDurationUndetermined:"Undetermined",sessionPlannedTotalDurationLabel:"Total planned duration",sessionPlannedTasksTotalLabel:"Planned total (tasks)",sessionListPlannedTotalPrefix:"planned",statsMetricCodingTimeHelpAria:"Help: coding time",statsMetricCodingTimeHelpBody:"Time accumulated while a productive (non-excluded) file is in the coding context: opened, saved, active editor change, or edits. Stops growing after about one minute without such signals. Independent of the tracking timer.",statsMetricActiveTimeHelpAria:"Help: active time",statsMetricActiveTimeHelpBody:"Time accumulated from workstation activity: edits, file open, selection changes, active editor changes, and window focus. Gaps longer than about three minutes are not counted. Often between coding time and session wall-clock.",statsMetricTasksHelpAria:"Help: task counts by status",statsMetricTasksHelpBody:"For the selected session: tasks with the tracking timer running (“Running now”), tasks whose start or end is still in the future (“Planned”), other tasks not marked done (“Paused”), and completed tasks whose end is not in the future. Matches the sections in the Tasks column.",statsTasksRowRunning:"Running (timer)",statsTasksRowPausedList:"Not done (list)",statsTasksRowCompleted:"Completed",statsTasksRowPlanned:"Planned (future)",gitRepoCardTitle:"Workspace Git repository",gitRepoNotARepo:"The first workspace folder is not a Git checkout (or Git is unavailable).",gitRepoCardHelpAria:"Help: workspace Git overview",gitRepoCardHelpBody:"Summary of the Git repository at the first workspace root: branch counts, commit counts, a short `git log --graph --all` view, and a sorted sample of tracked paths from `git ls-files`. Updated when the dashboard refreshes from the server.",gitRepoCurrentBranchLabel:"Current branch",gitRepoBranchesLocalLabel:"Local branches",gitRepoBranchesLocalHelpAria:"Help: local branches",gitRepoBranchesLocalHelpBody:"Number of local branch refs (`git branch --list`).",gitRepoBranchesRemoteLabel:"Remote branches",gitRepoBranchesRemoteHelpAria:"Help: remote branches",gitRepoBranchesRemoteHelpBody:"Number of remote-tracking branches (`git branch -r`), excluding the symbolic `*/HEAD` alias.",gitRepoCommitsHeadLabel:"Commits (HEAD)",gitRepoCommitsHeadHelpAria:"Help: commits on current branch",gitRepoCommitsHeadHelpBody:"Count of commits reachable from HEAD (`git rev-list --count HEAD`), i.e. the current branch history.",gitRepoCommitsAllLabel:"Commits (all refs)",gitRepoCommitsAllHelpAria:"Help: commits all refs",gitRepoCommitsAllHelpBody:"Count across all refs (`git rev-list --all --count`). Can be slower on huge repositories; shown as — if the command fails.",gitRepoStashesLabel:"Stashes",gitRepoStashesHelpAria:"Help: stash list",gitRepoStashesHelpBody:"Number of entries in `git stash list`.",gitRepoGraphTitle:"Recent graph",gitRepoGraphHelpAria:"Help: commit graph",gitRepoGraphHelpBody:"ASCII graph from `git log --graph --decorate --all` (last 40 commits). Useful to see how branches relate.",gitRepoGraphEmpty:"No graph lines returned.",gitRepoGraphPreviewNote:"Partial preview — last 40 commits only in this box.",gitRepoGraphOpenFullAria:"Open full commit graph in a new tab",gitRepoGraphOpenFullTitle:"Open full commit graph in a new browser tab",gitRepoGraphDetailDocTitle:"Git commit graph — Kronosys",gitRepoTreeTitle:"Tracked files (sample)",gitRepoTreeHelpAria:"Help: tracked paths sample",gitRepoTreeHelpBody:"Alphabetically sorted sample of paths from `git ls-files` (up to 300). Not the full tree; large repos may omit paths beyond the buffer limit.",gitRepoTreeEmpty:"No tracked paths in the sample.",gitRepoTreePreviewNote:"Partial preview — sample of up to 300 tracked paths.",gitRepoTreeOpenFullAria:"Open full tracked paths list in a new tab",gitRepoTreeOpenFullTitle:"Open full tracked paths list in a new browser tab",gitRepoTreeDetailDocTitle:"Tracked files — Kronosys",statsLocSectionTitle:"Lines & languages",statsLinesWrittenTotal:"Lines written",statsLinesWrittenHuman:"Human (est.)",statsLinesWrittenAi:"AI (est.)",statsLocByLanguageHeading:"Lines by language",statsCodingSignalsHeading:"Coding signals by language",statsMetricLinesWrittenHelpAria:"Help: lines written",statsMetricLinesWrittenHelpBody:"Net lines added from tracked edits (estimated from newlines in diffs). Single large inserts are partially capped. “Human” vs “AI” is a heuristic per edit: multi-range changes, more than ~6 net lines, or a single chunk with many characters and a newline often count as AI-style (agent or paste)—not exact attribution.",statsMetricLocByLanguageHelpAria:"Help: lines by language",statsMetricLocByLanguageHelpBody:"How many net lines were attributed to each language id in this session (same basis as “Lines written”).",statsMetricCodingSignalsHelpAria:"Help: coding signals",statsMetricCodingSignalsHelpBody:"Count of coding-context signals per language (file open, save, edit, active editor change, and heartbeats while recently editing).",sessionNameReadOnly:"Session name (read-only for this archive)",sessionArchiveBtn:"Archive",sessionArchiveTitle:"Hide this session from the list (restorable from Archives)",sessionRestoreBtn:"Restore",sessionDeleteBtn:"Delete",sessionDeleteTitle:"Delete session",sessionDeleteIntro:"This removes the session from your history. Choose what to do with its items.",sessionDeleteDiscardTasks:"Delete items with the session (discard them)",sessionDeleteMoveTasks:"Move items to another session first",sessionDeleteTargetLabel:"Target session",sessionDeleteTargetPlaceholder:"Select a session…",sessionDeleteConfirmBtn:"Delete session",sessionDeleteCancelBtn:"Cancel",archivesModalTitle:"Archived sessions",archivesEmpty:"No archived sessions.",archivesCloseBtn:"Close",archivedBadge:"Archived",sessionArchiveConfirm:"Archive this session?\n\n• Hidden from the list until you restore it from Archives.\n• Reporting omits unfinished entries and any entry with an unchecked item (totals, charts, time by project, linked KronoFocus).",sessionArchiveDontShowAgain:"Don’t show this warning again",storageBadgeLabelSqlite:"SQLite",storageBadgeTooltipSqlite:"Session history is stored in SQLite in your Kronosys data directory (local persistence driver in Settings).",storageBadgeLabelJson:"JSON",storageBadgeTooltipJson:"Session history uses JSON partition files (legacy local driver). You can switch to SQLite in Kronosys settings.",storageBadgeLabelMongo:"MongoDB",storageBadgeTooltipMongo:"MongoDB mirror is enabled and connected. You can push sessions from the list; local sessions still follow your persistence driver.",workspaceFoldersLabel:"Workspace roots",workspaceFoldersEmpty:"No workspace root is configured for this dashboard.",headerDisplayRegionTitle:"Display time zone {timeZone}; clock {clock}.",headerClockFormat24Short:"24 h",headerClockFormat12Short:"12 h (AM/PM)",headerWallClockAriaLabel:"Wall clock in display time zone {timeZone}: {datetime}.",gitIdentityBannerAria:"Git author not configured",gitIdentityBannerBody:"Set the Git author (name, email, optional forge username) for the line under the dashboard title. Use Set up here to enter them in a quick dialog — values stay local; you can change them anytime under Settings → Git identity.",gitIdentityBannerConfigure:"Set up here",gitIdentityBannerDismiss:"Hide this reminder",gitIdentityModalTitle:"Git author (quick setup)",gitIdentityModalIntro:"Enter at least one of the fields below. Nothing is sent to the cloud from this dialog — data stays in your local Kronosys store, like in Settings.\n\nYou can change or complete these values anytime under Settings → Git identity.",gitIdentityModalNeedOneField:"Fill at least one field (name, email, or forge username) before saving.",gitIdentityModalSaveError:"Could not save. Check the connection and try again.",gitIdentityModalFooter:"GitLab tokens, auto sync, and other advanced options remain under Settings in the Git identity section when you need them.",mongoSyncLocalLabel:"Local JSON",mongoSyncMongoLabel:"MongoDB",mongoSyncStatusAligned:"In sync",mongoSyncStatusUnknown:"Mongo count unavailable",mongoSyncStatusLocalAhead:"Drift — fewer documents in Mongo",mongoSyncStatusMongoAhead:"Drift — more documents in Mongo",mongoSyncHelpAriaLabel:"Help: MongoDB mirror vs local sessions",mongoSyncHelpBody:"Local JSON is the source of truth. Counts are unique sessions in your history files (including archived). MongoDB is updated only when you push a session or use Resync in settings — not on every save. Count mismatches usually mean some sessions were never pushed or extra documents exist in Mongo. The live session is counted locally after it is written to disk.",sessionMongoPushAriaLabel:"Push this session to MongoDB",sessionMongoPushSyncedTitle:"Up to date on MongoDB for this snapshot",sessionMongoPushDirtyTitle:"Session changed since last Mongo push — click to update",sessionMongoPushNeverTitle:"Not yet pushed to MongoDB — click to send",sessionMongoPushBusy:"Pushing…",sessionMongoPushFailedDisabled:"MongoDB is not enabled in settings.",sessionMongoPushFailedNotFound:"Session not found.",sessionMongoPushFailedMongo:"MongoDB rejected the write. Check the connection and logs.",sessionMongoPushFailedUri:"MongoDB connection is incomplete (URI or password).",dashboardLoadingAriaLabel:"Loading dashboard, please wait",dashboardLoadingMessage:"Fetching session data from the Kronosys server…",dashboardConnectionErrorAriaLabel:"Cannot reach the Kronosys server",dashboardConnectionErrorTitle:"Server not reachable",dashboardConnectionErrorBody:"Start the Kronosys app (for example `kronosys start` or `npm run dev`) and check that this browser tab can reach it. If you use a custom data folder, verify SQLite file permissions.",dashboardConnectionRetryLabel:"Try again",dashboardConnectionTechnicalDetailsLabel:"Technical details",dashboardSyncErrorBanner:"Could not refresh data from the server. Showing the last loaded state.",dataSearchTrigger:"Spotlight…",dataSearchPlaceholder:"Filter sessions, tasks, templates, projects, tags, dates, or duration (e.g. 12:55 <, 0:10 >)…",dataSearchPaletteAriaLabel:"Spotlight search",dataSearchTypePrompt:"Type to filter sessions, tasks, saved task templates, projects, and tags in this workspace. You can also use a calendar day or a full timestamp (e.g. 2026-01-15 14:30:00) or a recorded duration condition: minutes:seconds (or h:m:s) with < or >, e.g. 45:00 > or 1:0:0 <. Choosing a template fills the task draft.",dataSearchEmpty:"No matching sessions, tasks, or templates.",dataSearchFooter:"↑↓ to move \xb7 Enter to open \xb7 Esc to close",dataSearchKindSession:"Session",dataSearchKindTask:"Task",dataSearchKindTaskTemplate:"Task template",taskTemplateDatalistPrefix:"Template:",taskTitleTemplateSuggestAria:"Task templates and recurring titles",taskTokenSuggestTagsAria:"Suggested tags",taskTokenSuggestWorkProjectsAria:"Suggested work projects",taskTokenSuggestPersonalProjectsAria:"Suggested personal projects",dataSearchTaskDistinguishId:"ID: {id}",dataSearchTaskStopwatchLabel:"Timer",dataSearchTaskRecordedTimeLabel:"Logged",dataSearchSessionWallLabel:"Wall time",commandNewSession:"New session",commandRefresh:"Refresh dashboard",commandOpenReporting:"Open reporting",commandOpenSettings:"Open settings",commandOpenUserGuide:"Open user guide",commandFocusSessions:"Focus sessions column",commandFocusTasks:"Focus tasks column",commandFocusTags:"Focus tags & projects column",commandToggleTheme:"Toggle light / dark theme",commandToggleLang:"Switch interface language (EN / FR)",commandEndLiveSession:"End live session",commandToggleFocusMode:"Toggle dashboard focus mode (columns only)",dashboardFocusModeEnterTitle:"Focus mode — sessions, tasks and tags only",dashboardFocusModeEnterAria:"Enter dashboard focus mode",dashboardFocusModeExitTitle:"Exit focus mode",dashboardFocusModeExitAria:"Exit dashboard focus mode",dashboardFocusModeExitHint:"Esc",shortcutsModalTitle:"Keyboard shortcuts",shortcutsModalCloseAriaLabel:"Close keyboard shortcuts",shortcutsModalIntro:"Click \xab Change \xbb, then press the new shortcut (must include Ctrl, Alt, Shift, or Meta). Escape cancels recording. Ctrl+K / ⌘K is reserved for quick data search (not editable here).",shortcutsTableAction:"Action",shortcutsTableShortcut:"Shortcut",shortcutsTableAssign:"Assign",shortcutsChangeBtn:"Change…",shortcutsRecordPrompt:"Press keys…",shortcutsResetAll:"Reset all to defaults",shortcutsPaletteRow:"Spotlight search — Ctrl+K or ⌘K (fixed)",tourProgressLabel:"Step {n} of {total}",tourStep1Title:"Welcome to the Kronosys dashboard",tourStep1Body:"This dashboard loads live session data from this web app (Next.js API routes and local SQLite) — not a static snapshot.",tourStep2Title:"Three-column guide (above the board)",tourStep2Body:"This strip sits just under the header and explains how **Sessions**, **Tasks**, and **Tags & projects** fit together — left to right on a wide screen, stacked on a narrow one, with arrows between the ideas.\n\nOpen or fold it with the chevron; each cell is a short teaser before you dive into the real columns below. **Use the X** to dismiss the whole strip for this browser; turn it back on under **Settings → Dashboard & API → Three-column guide**. Folded and dismissed states are remembered separately.",tourStep3Title:"Sessions (left column)",tourStep3Body:"Browse your session history, start a new session, and inspect the selected session’s duration, coding time, and stats.\n\nWhen a live session is open, you can end it from here; archived sessions open in read-only mode.\n\nFor advanced timing, open Settings (gear): under Dashboard & API, set the **session duration alert** (when a long wall-clock session is highlighted in this column). The **Work schedule** section starts and stops tracking on your weekday hours, and **Specific planned sessions** define recurring blocks that override the general schedule during their time window.",tourStep4Title:"Tasks & focus (center)",tourStep4Body:"Track what you are working on, finish tasks, and use subtasks or Git-linked options when you need them.\n\nThis column follows the session you select in the Sessions column — the rest of the header aligns with that choice.\n\nYou only track one work stream at a time on other parents: starting subtask time on a task also runs that parent’s main stopwatch, and it stops time on other tasks (their segments are saved). If you pause the main stopwatch, any subtask segment in progress on the same task stops and records time. Resuming a parent’s main stopwatch anywhere ends subtask timers on the other tasks and pauses their main stopwatches.\n\nDetail items are optional. The task’s total time is always at least the sum of time on those items; the rest is work recorded on the task without a per-item breakdown.\n\nOn a running, paused, or completed task, **Save as template** stores its title, #tags, and @project so you can reuse them later — the new-task field suggests them with a **Template:** prefix and the Ctrl+K / ⌘K palette lists them too. You can also **adjust task time bounds** by keeping the recorded duration, entering a manual h/m/s value, or recalculating from start and end.",tourStep5Title:"Tags & projects (right)",tourStep5Body:"Pin tags, manage saved projects, and add descriptions — the same controls as in Settings, available while you work. Two tabs separate global tags from projects and project-linked tags.\n\nIn task titles you can use @project and #tags (including @project#code) to organise work across projects.\n\nReporting (charts) depends heavily on these objects: consistent tags and projects make breakdowns, filters, and trends in Reporting far more meaningful.",tourStep6Title:"Top toolbar: every icon",tourStep6Body:"From left to right in this cluster: quick data search / command palette (same as Ctrl+K or ⌘K — sessions, tasks, **task templates**, projects, and tags), the keyboard icon for shortcut help and custom bindings, route icons for Dashboard, Reporting (charts), Settings (gear), User Guide (book), and **Implementation** (code file — exhaustive ✓ / ✗ list of user stories), the **Today Gantt** button (task intervals across all sessions of the current day), the **global pause** toggle, the light/dark theme toggle, refresh data from the API without reloading the whole browser tab, and the language menu (FR / EN).\n\nThe global pause stays inactive when nothing is running. Otherwise it opens a confirmation modal with a summary (start, end or *ongoing*, wall duration, coding/active session times when the host records them, task and subtask counts, total recorded task-timer time, plus the split between main task time and subtask timers) before pausing the session, its tasks, and any active subtasks; the next click resumes only that paused set.\n\nEach control has a tooltip on hover; route icons keep you in the same Kronosys shell.",tourStep7Title:"Your Git identity & storage badge",tourStep7Body:"This area shows your Git author line and forge account when they are configured in Settings → Git identity, the workspace roots detected for metrics, and a small badge for how session data is stored here: SQLite (default), JSON driver, or MongoDB mirror when enabled.\n\nSQLite keeps the dashboard payload on this machine under your Kronosys data directory; this page reads and writes it through the local API.",tourStep8Title:"What is KronoFocus?",tourStep8Body:"**KronoFocus** paces your session with a configurable work segment, short breaks, then a long break after several cycles. It is built into Kronosys (counts, phases, how it ties to the session) and is not limited to a fixed Pomodoro-style recipe.\n\nThe header toolbar always includes KronoFocus so navigation stays aligned on every page. Whether you also show it next to task actions is configured under Settings → Dashboard & API (KronoFocus).",tourStep8LearnMoreUrl:"https://en.wikipedia.org/wiki/Time_management",tourStep8LearnMoreLabel:"Further reading — time management (new tab)",tourStep8LearnMoreAriaLabel:"Opens the English Wikipedia article on time management in a new tab",tourStep9Title:"Git identity: your first follow-up after the tour",tourStep9Body:"This panel appears when your Git name, email, or forge account is still empty. Use Set up here to fill a short form without leaving the dashboard — that is the recommended first action once you finish the tour. You can use Hide this reminder if you prefer to postpone.",tourSkipBtn:"Skip tour",tourBackBtn:"Back",tourNextBtn:"Next",tourDoneBtn:"Done",settingsTourProgressLabel:"Step {n} of {total}",settingsTourStep1Title:"Settings & Options",settingsTourStep1Body:"Some advanced options are only available here in the settings, not on the dashboard. This tour highlights key configurations for your workspace.",settingsTourStep2Title:"Usage Profile",settingsTourStep2Body:"Switch between 'Manager' and 'Developer' modes to adjust the level of detail in the dashboard and the frequency of notifications.",settingsTourStep3Title:"Persistence & Drivers",settingsTourStep3Body:"Choose between SQLite (recommended) and legacy JSON for your local history storage. You can also configure a MongoDB mirror for cloud backup.",settingsTourStep4Title:"Git & GitLab Integration",settingsTourStep4Body:"Configure your Git identity and GitLab API token to enable issue importing and commit message generation.",settingsTourStep5Title:"Reporting & Exclusions",settingsTourStep5Body:"Define which directories and file patterns should be excluded from line counting and time tracking to keep your reports clean.",settingsTourStep6Title:"Schedules & Automation",settingsTourStep6Body:"Set up recurring work hours and planned sessions to automatically start tracking or transfer tasks at specific times.",settingsTourSkipBtn:"Skip tour",settingsTourBackBtn:"Back",settingsTourNextBtn:"Next",settingsTourDoneBtn:"Done",tourUndismissBtn:"Relaunch tour",reportingTourProgressLabel:"Reporting tour — step {n} of {total}",reportingTourStep1Title:"Welcome to Kronosys Reporting",reportingTourStep1Body:"This page aggregates your Kronosys history from the local API. Use it to review sessions, recorded task time, KronoFocus usage, and — when filters allow — per-tag and per-project splits.",reportingTourStep2Title:"Filters",reportingTourStep2Body:"Pick a date range (or use Day / Week / Month / Year presets), optionally narrow by #tags, then reset when you want the full picture again. Green badges warn when live data or unfinished tasks still affect the totals.",reportingTourStep3Title:"Summary KPIs",reportingTourStep3Body:"These cards condense the same window as the charts: session counts, task rows, KronoFocus stats, and recorded minutes. The (?) icons open short metric definitions without cluttering the layout.",reportingTourStep4Title:"Daily charts",reportingTourStep4Body:"Bar views show sessions, tasks by status, recorded task time, and session wall-clock by calendar day. When several weeks exist, use the week strip to align charts and tag calendars.",reportingTourStep5aTitle:"Time by tag",reportingTourStep5aBody:"Review recorded task minutes grouped by #tags (including the untagged bucket when it applies), with weekly grids when data spans multiple days.",reportingTourStep5bTitle:"Time by project (Work vs Personal)",reportingTourStep5bBody:"The weekly-by-project grid has a Work (@) / Personal (!) toggle under the section title: Work (default) excludes personal-ledger minutes; Personal shows only that ledger (including tasks inferred from a ! token in the title when the saved flag is missing). Tag totals above still mix both ledgers unless you filter by tags.",reportingTourStep6Title:"Outline and two-column layout",reportingTourStep6Body:"This block is the main Reporting layout: your content on the left and, on wide screens, a sticky jump list on the right. On phones, the same anchors appear as chips above the filters.",newSessionModalTitle:"New session — scope",newSessionModalHelpAria:"Help: session start and scope (duration, dates, weekdays)",newSessionModalHelpBody:"Choose whether the session starts now or with a backdated start. Enter **both start and end** (local browser time) for a **past** start. For **Now**, you can optionally set a **scheduled end** — the session closes automatically at that time (same as setting an end on a live session later). If the end is still **ahead** on a backdated start, Kronosys opens a **live** session from that start and **closes it automatically** at the scheduled end; if the end is **already past**, the closed interval is stored as a history row. Starting now while a session is already live opens the end-session dialog first; a **fully past** backdated row leaves the current session running and adds a history row you can switch to. Then these scope options set expectations for this session only. They do not stop Kronosys automatically: you get reminders from the collector (heartbeat) and a banner here when you are close to or outside the limits.\n\n• Maximum wall-clock duration — counted from the first tracked event in the session.\n\n• Calendar period — local dates inclusive (start and/or end).\n\n• Weekdays — restrict to selected days; you can add a daily time window (local 24 h). Overnight windows are supported (e.g. 22:00–06:00).",newSessionTimingSectionTitle:"Session start",newSessionTimingImmediate:"Now (start immediately)",newSessionTimingPast:"In the past (backdated start)",newSessionPastStartLabel:"Session started at (local)",newSessionPastStartHint:"Uses your browser’s local timezone. The session wall clock starts from this instant; you can still add tasks and adjust times afterward.",newSessionPastEndLabel:"Session ends at (local)",newSessionPastEndHint:"Must be after the start. If the end is still ahead, this opens a live session and closes it automatically at that time; if the end is already past, the closed interval is stored in history.",newSessionImmediateEndLabel:"Scheduled end (optional, local)",newSessionImmediateEndHint:"Leave empty for no automatic end. If set, the session must end in the future — it closes automatically at that time.",newSessionScopeFieldsetLegend:"Scope (reminders)",newSessionModeNone:"No limit",newSessionModeMax:"Maximum wall-clock duration",newSessionModeCalendar:"Calendar period (dates)",newSessionModeWeekly:"Weekdays (optional daily hours)",newSessionMaxHoursLabel:"Max duration (hours)",newSessionDateFromLabel:"From (date)",newSessionDateToLabel:"To (date)",newSessionTodayBtn:"Today",newSessionWeekdaysLegend:"Active weekdays",newSessionQuickWeekdays:"Weekdays",newSessionQuickWeekends:"Weekends",newSessionQuickAll:"All days",newSessionTimeFromLabel:"Daily from",newSessionTimeToLabel:"Daily to",newSessionNowBtn:"Now",newSessionUseTimeWindow:"Restrict to a daily time window on those days",newSessionUseTimeWindowHelpAria:"Help: daily time window",newSessionUseTimeWindowHelpBody:"When enabled, the session only tracks time within the specified daily window on the selected weekdays. Outside this window, the session is considered paused. Supports overnight windows (e.g. 22:00–06:00).",newSessionErrorMax:"Enter a maximum duration between 0.1 and 8760 hours.",newSessionErrorCalendar:"Choose at least one date (from and/or to).",newSessionErrorWeekly:"Select at least one weekday.",newSessionErrorPastMissing:"Enter the start date and time for a backdated session.",newSessionErrorPastEndMissing:"Enter the end date and time for a backdated session.",newSessionErrorPastEndBeforeStart:"The end must be strictly after the start.",newSessionErrorPastFuture:"Pick a date and time in the past or now (not in the future).",newSessionErrorPastInvalid:"Unrecognized date or time.",newSessionErrorImmediateEndNotFuture:"The scheduled end must be in the future (at least about one minute ahead).",newSessionStartBtn:"Start session",newSessionCancelBtn:"Cancel",sessionScopeNoticeAria:"Session scope reminder",appShellRouteNavAria:"Main sections",appShellRouteNavTodayGantt:"Open today timeline (Gantt)",appShellRouteNavGlobalPause:"Pause session, tasks, and subtasks in this context",appShellRouteNavGlobalResume:"Resume everything paused by global pause in this context",appShellRouteNavGlobalPauseDisabledTooltip:"Nothing is active to pause: the session wall clock is already paused and no task or subtask timer is running.",appShellRouteNavGanttDashboardOnlyTooltip:"Today’s Gantt is available from the dashboard only.",appShellRouteNavGlobalPauseDashboardOnlyTooltip:"Global pause is available from the dashboard when a live session is loaded.",appShellRouteNavGlobalPauseNoSessionContextTooltip:"Global pause is not available while you inspect an archived session or before the live session is loaded.",appShellRouteNavChangelogUnavailableTooltip:"Changelog shortcut is hidden on this screen (no label).",appShellRouteNavImplementationUnavailableTooltip:"Implementation shortcut is hidden on this screen (no label).",appShellHeaderKronoFocusLoadingAria:"KronoFocus — waiting for session data",appShellRouteNavGroupAppAria:"Main app areas",appShellRouteNavGroupDocsAria:"Help and reference",appShellRouteNavGroupToolsAria:"In-session tools",appShellRouteNavGroupLegalAria:"Legal information",appShellRouteNavDataEnvironmentGroupAria:"Production or QA data store",dataEnvironmentNavGroupHint:"Switch between production data and an isolated QA sandbox",dataEnvironmentNavActiveLabel:"Active",dataEnvironmentNavActiveProd:"Production",dataEnvironmentNavActiveQa:"QA",dataEnvironmentNavPendingRestart:"After restart: {env}",dataEnvironmentNavEnableQaShort:"QA",dataEnvironmentNavEnableQaTitle:"Enable a separate QA data store (v4-qa) alongside production",dataEnvironmentNavSettingsLink:"Settings",dataEnvironmentDualEnabledHint:"QA store enabled. Use Prod / QA to switch, then restart the Kronosys server.",dataEnvironmentNavTraceOverrideShort:"Custom path",dataEnvironmentNavTraceOverrideAria:"TRACE_DATA_DIR is set; production and QA vault switching is disabled",dataEnvironmentNavProdShort:"Prod",dataEnvironmentNavQaShort:"QA",dataEnvironmentNavProdTitle:"Production data (your real sessions and tasks)",dataEnvironmentNavQaTitle:"QA data (isolated copy for tests and reproducing issues)",dataEnvironmentQaBanner:"QA environment — data here is separate from production. Do not use this screen for real work.",dataEnvironmentSwitchRestartHint:"Data store preference saved. Restart the Kronosys server (stop and start `kronosys` or your dev server) to open the selected environment.",dataEnvironmentSwitchSuccessHint:"Switched to the {env} data store.",dataEnvironmentSwitchError:"Could not switch the data environment.",dataEnvironmentSwitchDisabled:"Enable dual environments in Settings → General first.",dataEnvironmentSwitchConfirmTitle:"Switch data store",dataEnvironmentSwitchConfirmMessage:"You are about to switch to the {env} data store.\n\nAfter you confirm, Kronosys will reopen the selected SQLite file immediately.",dataEnvironmentSwitchConfirmBtn:"Switch",dataEnvironmentSwitchLockBackdropTitleSwitching:"Switching data store…",dataEnvironmentSwitchLockBackdropDetailSwitching:"Please wait while the preference is saved.",dataEnvironmentSwitchLockBackdropAriaSwitching:"Application locked: data store switch in progress",dataEnvironmentSwitchLockBackdropTitleLocked:"Restart required",dataEnvironmentSwitchLockBackdropDetailLocked:"The data store preference was saved. Restart the Kronosys server to continue. The interface stays locked until then.",dataEnvironmentSwitchLockBackdropAriaLocked:"Application locked: restart the Kronosys server to apply the data store",dataEnvironmentQaSeedTitle:"Set up the QA data store",dataEnvironmentQaSeedMessage:"This is your first switch to the QA store. Choose how to initialize it:\n\n• Copy production — duplicate your current sessions and tasks into QA (production data is not modified).\n• Start empty — an isolated empty store for tests and experiments.",dataEnvironmentQaSeedCopyBtn:"Copy production data",dataEnvironmentQaSeedEmptyBtn:"Start empty",dataEnvironmentQaSeedRequiredError:"Choose whether to copy production data or start with an empty QA store.",dataEnvironmentQaSeedProductionMissingError:"Production has no data file yet; choose “Start empty” or add data in production first.",appShellUtilityToolbarGroupAria:"Display and language",globalPauseConfirmTitle:"Global pause",globalPauseConfirmIntro:"Global pause freezes the session wall clock when it is running, pauses each task timer that is not already paused, and stops any active subtask timer (recording elapsed time). The next click on this control resumes only what was paused in this operation.\n\nReview what will be affected:",globalPauseConfirmSessionHeading:"Session",globalPauseConfirmSummaryHeading:"Summary",globalPauseConfirmSummaryStart:"Start",globalPauseConfirmSummaryEnd:"End",globalPauseConfirmSummaryEndOngoing:"Ongoing (no end yet)",globalPauseConfirmSummaryWallDuration:"Wall duration",globalPauseConfirmSummaryTasks:"Tasks",globalPauseConfirmSummarySubtasks:"Subtasks",globalPauseConfirmSummaryMainTimer:"Task timers (excl. subtasks)",globalPauseConfirmSummarySubtaskTimers:"Subtask timers",globalPauseConfirmSummaryCodingSession:"Session coding time",globalPauseConfirmSummaryActiveSession:"Session active time",globalPauseConfirmSummaryTaskTimersTotal:"Total recorded (task timers)",globalPauseConfirmSummaryUnknownInstant:"—",globalPauseConfirmSessionWallWillPause:"Wall-clock time for this session will pause.",globalPauseConfirmSessionWallAlreadyPaused:"The session wall clock is already paused; it stays frozen.",globalPauseConfirmTasksHeading:"Tasks and subtasks",globalPauseConfirmNoTaskEffects:"No task or subtask timers need freezing in the current state.",globalPauseConfirmEffectMainTimer:"Main task timer will pause.",globalPauseConfirmEffectSubtaskStop:"Subtask timer stops — \xab {title} \xbb.",globalPauseConfirmConfirmBtn:"Pause now",appShellLiveDrawerAria:"Live session activity",appShellLiveDrawerTitle:"In progress",appShellLiveDrawerOpenDashboard:"Open dashboard",appShellLiveDrawerSessionPaused:"Session paused",appShellLiveDrawerWallClock:"Wall time",appShellLiveDrawerTasksHeading:"Timers",appShellLiveDrawerKronoFocusRunning:"Running",appShellLiveDrawerKronoFocusPaused:"Paused",appShellLiveDrawerKronoFocusPhaseWork:"Work",appShellLiveDrawerSubtaskTracking:"Subtask",appShellLiveDrawerExpand:"Expand panel",appShellLiveDrawerCollapse:"Collapse panel",appShellLiveDrawerNoRunningTasks:"No task timers running.",dashboardSideDrawerSessionsAria:"Sessions panel",dashboardSideDrawerTagsAria:"Tags and projects panel",dashboardTaskLauncherDrawerAria:"Task entry launcher",dashboardTaskLauncherDrawerExpand:"Expand task launcher",dashboardTaskLauncherDrawerCollapse:"Collapse task launcher",brandTagline:"The relativity of productive time",appVersionAriaLabel:"Kronosys dashboard package version {version}.",dialogOkBtn:"OK",dialogCancelBtn:"Cancel",dialogConfirmBtn:"Confirm",pageRefreshTitle:"Refresh data",pageRefreshAriaLabel:"Reload data for this page without a full browser refresh",pageRefreshProgressLabel:"Syncing with the Kronosys server…",pageRefreshDoneToast:"Data reloaded from the Kronosys server.",pageRefreshFailedToast:"Could not reload data. Check that the Kronosys server is running and try again."},e={kronoFocusTitle:"KronoFocus",workMode:"KronoFocus",breakMode:"Pause courte",longBreakMode:"Pause longue",kronoFocusStart:"D\xe9marrer",kronoFocusPause:"Pause",kronoFocusReset:"R\xe9initialiser",kronoFocusControlsReadOnlyTooltip:"Lecture seule pendant l’inspection d’une archive — ces commandes s’appliquent \xe0 la session en cours.",kronoFocusLinkedTaskIntro:"Lanc\xe9 depuis :",kronoFocusEditDurationTitle:"Configurer le rythme KronoFocus (minuteur non d\xe9marr\xe9)",kronoFocusDurationPickerLabel:"Dur\xe9e (heures : minutes : secondes)",kronoFocusApplyDuration:"Appliquer",kronoFocusCancelDurationEdit:"Annuler",kronoFocusDurationHelpAriaLabel:"Aide sur la dur\xe9e",kronoFocusDurationHelpBody:"Indiquez la dur\xe9e du segment de travail en heures, minutes et secondes (temps \xe9coul\xe9, ex. 00:25:00 ou 01:30:00 — pas une heure du jour). Vous pouvez omettre les secondes (ex. 0:25). Plage : 1 min \xe0 8 h. Les pauses courte et longue se r\xe8glent en minutes enti\xe8res dans la m\xeame bo\xeete. R\xe9glez tout avant de d\xe9marrer KronoFocus.",kronoFocusDurationInputPlaceholder:"00:25:00",kronoFocusDefaultWorkDuration:"D\xe9faut — 00:25:00",kronoFocusDurationHistoryLabel:"Dur\xe9es r\xe9centes",kronoFocusDurationHistoryPickAria:"Choisir la dur\xe9e {time}",kronoFocusDurationHistoryClear:"Effacer",kronoFocusDurationHistoryClearTitle:"Effacer toutes les dur\xe9es personnalis\xe9es enregistr\xe9es",kronoFocusRhythmPresetsHeading:"Pr\xe9r\xe9glages (travail / pause courte / pause longue)",kronoFocusRhythmPresetLabels:["25 / 5","50 / 10","45 / 15","52 / 17"],kronoFocusRhythmPresetTitles:["25 min de travail, 5 min de pause courte, 15 min de pause longue apr\xe8s chaque 4e segment de travail","50 min de travail, 10 min de pause courte, 20 min de pause longue apr\xe8s chaque 4e segment de travail","45 min de travail, 15 min de pause courte, 15 min de pause longue apr\xe8s chaque 4e segment de travail","52 min de travail, 17 min de pause courte, 30 min de pause longue apr\xe8s chaque 4e segment de travail"],kronoFocusShortBreakMinutesLabel:"Pause courte (minutes)",kronoFocusLongBreakMinutesLabel:"Pause longue (minutes)",kronoFocusRhythmBreaksMinutesHint:"Minutes enti\xe8res, 1 \xe0 480 chacune. La pause longue suit chaque 4e segment de travail termin\xe9.",startTaskWithKronoFocus:"Lancer aussi KronoFocus",startTaskWithKronoFocusToggleAriaOff:"Lancer aussi KronoFocus au d\xe9marrage — d\xe9sactiv\xe9. Appuyer pour activer.",startTaskWithKronoFocusToggleAriaOn:"Lancer aussi KronoFocus au d\xe9marrage — activ\xe9. Appuyer pour d\xe9sactiver.",startKronoFocusFromActiveTask:"D\xe9marrer KronoFocus",startKronoFocusFromTaskConfirm:"KronoFocus est d\xe9j\xe0 en cours ou en pause. R\xe9initialiser le minuteur et d\xe9marrer un nouveau segment de travail ?",launcherTitle:"T\xe2ches",taskPlaceholder:"Sur quoi travaillez-vous ?",taskNoteLabel:"Note de t\xe2che",taskNoteAddBtn:"Ajouter une note",taskNotePlaceholder:"Ajouter une note libre pour cette t\xe2che…",taskNoteEditHint:"Cliquer pour modifier la note (Markdown accept\xe9)",taskMarkdownHelpAriaLabel:"Aide Markdown pour les notes de t\xe2che",taskMarkdownHelpIntro:"Sur la carte ou au lanceur, **Ajouter une note** ouvre le champ ; une fois enregistr\xe9e, la note est interpr\xe9t\xe9e en Markdown (sous-ensemble GFM, compatible GitLab/GitHub). Le titre accepte du Markdown inline en lecture seule.",taskMarkdownHelpNoteHeading:"Note (bloc)",taskMarkdownHelpTitleHeading:"Titre (inline en lecture)",taskMarkdownHelpSecurity:"Pas de HTML brut ; les liens externes s’ouvrent dans un nouvel onglet.",taskMarkdownHelpGfmLimits:"Pris en charge : gras, italique, barr\xe9, listes, cases \xe0 cocher, tableaux, autolinks, images (http/https). Hors scope : Mermaid, formules, @mentions/#issues GitLab, blocs d’alerte, raccourcis emoji.",taskPlaceholderPast:"Sur quoi avez-vous travaill\xe9 ?",archiveAddTaskIntro:"Entr\xe9e pass\xe9e : ouvrez la modale de plage horaire pour le d\xe9but et la fin (la fin est pr\xe9remplie au d\xe9but plus la dur\xe9e minimale des param\xe8tres). Ajustez la dur\xe9e du minuteur (h/m/s) si besoin. \xc9tiquettes et @projet comme d’habitude ; pas de minuteur live ni de points de d\xe9tail — session en cours ou archiv\xe9e.",archiveAddTaskIntroHelpAria:"Aide : saisie d’une entr\xe9e pass\xe9e",taskEntryModeRealtime:"Temps r\xe9el",taskEntryModePast:"Pass\xe9/planifi\xe9",taskEntryModeGroupAria:"Mode de saisie",archiveTaskStartLabel:"D\xe9but",archiveTaskEndLabel:"Fin",taskTimingDurationLabel:"Dur\xe9e",taskTimingAdjustModalTitle:"Ajuster la dur\xe9e ?",taskTimingAdjustModalMessage:"Vous avez modifi\xe9 l’horaire de la t\xe2che. Choisissez comment recalculer la dur\xe9e.",taskTimingAdjustKeepDuration:"Conserver la dur\xe9e du minuteur enregistr\xe9e",taskTimingAdjustManualDuration:"D\xe9finir la dur\xe9e manuellement (h/m/s)",taskTimingAdjustFromBounds:"D\xe9finir la dur\xe9e selon d\xe9but/fin",taskTimingAdjustHours:"Heures",taskTimingAdjustMinutes:"Minutes",taskTimingAdjustSeconds:"Secondes",taskTimingAdjustLapSectionTitle:"Tour de minuteur en cours (lap n\xb0{n})",taskTimingAdjustLapKeep:"Conserver ce tour tel quel (horodatage du lap inchang\xe9)",taskTimingAdjustLapFlush:"Cl\xf4turer ce tour maintenant (l’enregistrer comme lap termin\xe9)",taskTimingAdjustLapAlignStart:"R\xe9aligner ce tour sur le nouveau d\xe9but de t\xe2che",taskTimingAdjustModalMessageRunning:"Vous avez modifi\xe9 le d\xe9but alors qu’un tour de minuteur est en cours. Indiquez quoi faire de ce tour et comment recalculer la dur\xe9e totale.",taskTimerLapsHeading:"Laps de suivi",taskTimerLapDeleteBtn:"Supprimer le lap",taskTimerLapDeleteConfirmTitle:"Supprimer ce lap ?",taskTimerLapDeleteConfirmMessage:"Le lap est retir\xe9 de la liste et sa dur\xe9e est soustraite du total du minuteur de la t\xe2che.",taskTimerLapRunningLabel:"en cours…",taskStartTimeSaveAria:"Enregistrer l'heure de d\xe9but corrig\xe9e de la t\xe2che",sessionStartTimeSaveAria:"Enregistrer l'heure de d\xe9but corrig\xe9e de la session",taskEndTimeSaveAria:"Enregistrer l'heure de fin corrig\xe9e de la t\xe2che",sessionEndTimeSaveAria:"Enregistrer l'heure de fin corrig\xe9e de la session",sessionEndTimeEditSectionTitle:"Fin de session",sessionStartTimeEditSectionTitle:"D\xe9but de session",taskPastDatetimePlaceholder:"yy-mm-dd --:--:--",taskPastDatetimeTimeLabel:"Heure",taskPastDatetimeHourAria:"Heure (format 24 h)",taskPastDatetimeMinuteAria:"Minutes",taskPastDatetimeTodayBtn:"Aujourd’hui",taskPastDatetimeNowBtn:"Maintenant",archiveAddTaskBtn:"Ajouter \xe0 la session",archiveTaskDatetimeRangeInvalid:"Indiquez un d\xe9but et une fin valides ; la fin doit \xeatre post\xe9rieure au d\xe9but (date et heure locales).",archiveTaskTimerDurationLabel:"Dur\xe9e du minuteur",pastTaskTimingModalTitle:"Entr\xe9e pass\xe9e — plage horaire",pastTaskTimingEditBtn:"R\xe9gler d\xe9but, fin et dur\xe9e…",pastTaskTimingSummaryAria:"Modifier le d\xe9but, la fin et la dur\xe9e du minuteur pour l’entr\xe9e pass\xe9e",pastTaskTimingModalConfirm:"OK",pastTaskTimingModalCancel:"Annuler",pastTaskTimingEndOptional:"facultatif",archiveTaskManualDurationInvalid:"Indiquez une dur\xe9e de minuteur sup\xe9rieure \xe0 z\xe9ro et au plus \xe9gale \xe0 l’intervalle entre le d\xe9but et la fin.",activeTaskTitleEditHint:"Cliquer pour modifier le titre ; saisir #\xe9tiquettes dans le champ ou utiliser la ligne du bas",activeTaskTitleInputAria:"Modifier le titre ; #\xe9tiquettes ou @projet optionnels dans le champ, pastilles en dessous pour l’existant",taskStartBlockedByPlannedBoundaryConflict:"Fermez d’abord la bo\xeete de conflit de minuteurs (t\xe2che planifi\xe9e), puis lancez une autre t\xe2che.",plannedTaskScheduleActivatedToast:"La t\xe2che planifi\xe9e \xab {name} \xbb est maintenant au minuteur.",plannedTaskScheduleActivatedToastUnnamed:"T\xe2che sans titre",plannedSessionScheduleActivatedToast:"La session planifi\xe9e \xab {name} \xbb a atteint son heure de d\xe9but.",plannedSessionScheduleActivatedToastUnnamed:"Session sans titre",startTaskBtn:"D\xe9marrer le suivi",taskSaveTemplateBtn:"Sauvegarder comme template",taskAlreadyTemplateBtn:"D\xe9j\xe0 enregistr\xe9 comme template",taskTemplateSavedToast:"Template de t\xe2che sauvegard\xe9.",finishTaskBtn:"Terminer",finishTaskOpenSubtasksWarnTitle:"Terminer la t\xe2che ?",finishTaskOpenSubtasksWarnBody:"Il reste des points de d\xe9tail non coch\xe9s. Ils seront tous marqu\xe9s comme termin\xe9s lorsque vous terminez la t\xe2che.",reopenTaskBtn:"Rouvrir",reopenTaskModalTitle:"Rouvrir cette t\xe2che ?",reopenTaskModalMessage:"La t\xe2che redevient active. Choisissez comment g\xe9rer la dur\xe9e enregistr\xe9e du minuteur.",reopenTaskTimerResume:"Reprendre le minuteur (conserver la dur\xe9e)",reopenTaskTimerPaused:"Rouvrir en pause (conserver la dur\xe9e)",reopenTaskTimerManual:"D\xe9finir la dur\xe9e manuellement (h/m/s)",reopenTaskTimerReset:"Remettre le minuteur \xe0 z\xe9ro",reopenTaskSubtasksNote:"Les points de d\xe9tail seront aussi rouverts.",reopenTaskEndedSessionHint:"Session cl\xf4tur\xe9e — le minuteur ne peut pas repartir en direct ; les choix de dur\xe9e s’appliquent \xe0 l’instantan\xe9.",taskDeleteBtn:"Supprimer",taskDuplicateBtn:"Copier la t\xe2che dans le champ",taskDuplicateTooltip:"Copier le titre, les \xe9tiquettes et le projet dans le champ.",taskDeleteConfirm:"Supprimer cette entr\xe9e ? Le temps enregistr\xe9 sera perdu. Cette action est irr\xe9versible.",taskConcurrentTrackingConflictTitle:"Suivi d\xe9j\xe0 actif",taskConcurrentTrackingConflictMessage:"Au moins une t\xe2che a d\xe9j\xe0 un minuteur actif. Indiquez ce que vous en faites avant de lancer celle-ci : les terminer (elles passent dans \xab termin\xe9es \xbb), les mettre en pause (reprise plus tard dans \xab en pause \xbb), ou les laisser tourner et d\xe9marrer la nouvelle t\xe2che en parall\xe8le.",taskConcurrentTrackingConflictPauseBtn:"Mettre les t\xe2ches actives en pause",taskConcurrentTrackingConflictFinishBtn:"Terminer les t\xe2ches actives",taskConcurrentTrackingConflictParallelBtn:"D\xe9marrer en parall\xe8le (garder les minuteurs)",taskConcurrentTrackingDontShowAgain:"M\xe9moriser ce choix et ne plus afficher cette bo\xeete (la m\xeame action sera appliqu\xe9e automatiquement la prochaine fois).",taskPlannedBoundaryConflictTitle:"Une t\xe2che planifi\xe9e entre en cours",taskPlannedBoundaryConflictMessage:"Une t\xe2che qui \xe9tait sous Planifi\xe9es a atteint son heure de d\xe9but et compte d\xe9sormais comme en cours alors qu’un autre minuteur tournait d\xe9j\xe0. Indiquez ce que vous faites des t\xe2ches d\xe9j\xe0 au minuteur : les mettre en pause (elles passent dans la liste des pauses), les terminer (elles passent dans les termin\xe9es), ou les laisser tourner en parall\xe8le avec la nouvelle.",taskPlannedBoundaryConflictResolveError:"Impossible d’appliquer votre choix sur les minuteurs. V\xe9rifiez le serveur et r\xe9essayez.",navDashboardPlannedConflictPulseHint:"Tableau de bord : modale de conflit de minuteurs \xe0 traiter",tasksPausedHeading:"En pause",tasksCompletedHeading:"Termin\xe9es",tasksArchiveOpenHeading:"Non termin\xe9es (instantan\xe9)",tasksRunningHeading:"En cours (minuteur)",tasksPlannedHeading:"Planifi\xe9es",tasksTimelineEmpty:"Aucun cr\xe9neau horaire de t\xe2che dans cette vue de session.",tasksTimelineGanttOpenBtn:"Gantt",tasksTimelineGanttOpenBtnAria:"Ouvrir le fil chronologique en vue Gantt",tasksTimelineGanttTitle:"Fil chronologique (vue Gantt)",tasksTimelineGanttDescription:"Frise align\xe9e sur le d\xe9but de la session : une ligne par t\xe2che ; les barres color\xe9es suivent les intervalles du minuteur. Faire d\xe9filer horizontalement si la session s’\xe9tire sur une longue plage.",tasksTimelineGanttTodayTitle:"Fil de la journ\xe9e (vue Gantt)",tasksTimelineGanttTodayDescription:"Frise globale de la journ\xe9e en cours : tous les intervalles de t\xe2ches de toutes les sessions sont regroup\xe9s dans une seule vue.",tasksTimelineGanttWindowStartLabel:"D\xe9but de la frise",tasksTimelineGanttWindowEndLabel:"Fin de la frise",tasksTimelineGanttLegendWork:"Temps suivi",tasksTimelineGanttLegendGap:"Hors intervalle (sur cette ligne)",tasksTimelineGanttLegendProductive:"Productif (projets @)",tasksTimelineGanttLegendPersonal:"Personnel (projets !)",tasksTimelineGanttSummaryProductive:"Total productif : {duration}",tasksTimelineGanttSummaryPersonal:"Total personnel : {duration}",tasksTimelineGanttCloseBtn:"Fermer",tasksTimelineGanttTooltipStart:"D\xe9but",tasksTimelineGanttTooltipEnd:"Fin",tasksTimelineGanttTooltipTimer:"Dur\xe9e minuteur",tasksTimelineGanttTooltipWall:"Dur\xe9e murale",tasksTimelineGanttTooltipTimerUnknown:"—",tasksTimelineGanttLapsPopoverAria:"Laps de suivi pour ce segment de t\xe2che",ganttColorPickerAria:"Couleur des barres Gantt",ganttColorPickerAuto:"Couleur automatique",ganttColorPickerSwatch:"Couleur {color}",taskGanttColorLabel:"Couleur Gantt",hideTaskList:"Masquer la liste",showAllTasks:"Afficher toute la liste",pauseTaskBtn:"Pause — affichage dans la liste des pauses",resumeTaskBtn:"Reprendre le suivi",taskTimerPausedManual:"Minuteur en pause (manuel).",pausedNote:"La session est en pause pendant la consultation de l’historique.",viewingHistoryBannerTitle:"Vous consultez une session pass\xe9e.",resumeBtn:"Reprendre la session active",inspectingLabel:"Consultation :",historyInspectBannerAria:"Consultation d’une session pass\xe9e",liveSessionWallPausedBannerAria:"Session en pause (collecte)",liveSessionWallPausedTitle:"La session est en pause",liveSessionWallPausedDetail:"L’horloge murale est fig\xe9e. Utilisez \xab Reprendre \xbb ci-dessous ou le bouton lecture sur une t\xe2che — les deux relancent le suivi de session.",liveSessionResumeWallBtn:"Reprendre la session",autoTagsDetected:"\xc9tiquettes d\xe9tect\xe9es",autoProjectDetected:"Projet",tagsHelpAriaLabel:"Aide sur les \xe9tiquettes",tagSyntaxHelp:"#mot apr\xe8s un espace ou en d\xe9but, ou coll\xe9 (mot#nom). @projet : m\xeames r\xe8gles ; plusieurs @ → le dernier l’emporte (un seul projet par t\xe2che). Jetons : lettres, chiffres, tiret, soulign\xe9 (sans espaces).",tagSuggestionsHelp:"\xc0 c\xf4t\xe9 du (?), le petit champ applique une ligne du type #mot, @projet ou un nom d’\xe9tiquette lorsque vous appuyez sur Entr\xe9e. Taper #mot dans le titre est \xe0 part.",tagsHelpWorkflowSummary:"Au-dessus, les \xe9tiquettes en lecture seule listent tout ce qui est sur la t\xe2che ; la ligne projet affiche son projet. Modifiez le titre ou utilisez le champ rapide (Entr\xe9e). @Projet#code reste optionnel.",taskAppliedTagsHelpHeading:"\xc9tiquettes sur cette t\xe2che",taskAppliedTagsHelpHint:"Tout est fusionn\xe9 : titre, champ de nouvelle t\xe2che et ligne rapide sous chaque t\xe2che. Saisissez #\xe9tiquette, @projet ou un nom puis Entr\xe9e ; @ seul retire le projet.",taskTagsExtraHelpAria:"Aide : \xe9tiquettes et projet appliqu\xe9s \xe0 cette t\xe2che",taskTagsOrphanProjectHelpBody:"Issu du titre, absent de la liste enregistr\xe9e. \xc9pinglez sous \xc9tiquettes et projets ou modifiez le titre.",taskTagProjectQuickAddPlaceholder:"#\xe9tiquette, @projet ou nom… Entr\xe9e (@ seul retire le projet)",taskTagProjectQuickAddAria:"Ajout rapide : saisir #\xe9tiquette, @projet ou un nom d’\xe9tiquette, puis Entr\xe9e",taskTagProjectMultiGroupTags:"\xc9tiquettes enregistr\xe9es",taskTagProjectMultiGroupProjects:"Projets enregistr\xe9s",taskTagProjectMultiOptionClearProject:"Retirer le projet (\xe9quivaut \xe0 @ seul)",taskTagProjectMultiSelectAria:"S\xe9lection multiple d’\xe9tiquettes et de projets enregistr\xe9s, puis bouton Ajouter la s\xe9lection",taskTagDefaultBucket:"d\xe9faut",taskTagProjectMultiHint:"Ctrl ou ⌘ + clic pour s\xe9lectionner plusieurs lignes, puis ajoutez.",taskTagProjectApplySelectionBtn:"Ajouter la s\xe9lection",tagsUserGuideIntro:"Ce guide explique comment le titre de t\xe2che, les raccourcis enregistr\xe9s et l’option @projet#code s’articulent. Vous pouvez ignorer les fonctions avanc\xe9es et n’utiliser que des #\xe9tiquettes et un seul @projet.",tagsUserGuideBasicsTitle:"Bases : jetons dans le titre",tagsUserGuideBasicsBody:"Dans le titre d’une t\xe2che, vous pouvez m\xealer du texte libre \xe0 :\n• #nom — \xe9tiquette globale (lettres, chiffres, tiret, soulign\xe9).\n• @Projet — affecte la t\xe2che \xe0 un projet (plusieurs @ : le dernier l’emporte — un seul projet par t\xe2che).\nLes jetons peuvent suivre un espace ou \xeatre coll\xe9s au mot pr\xe9c\xe9dent (mot#tag). Le tableau de bord fusionne tout sous la t\xe2che.",tagsUserGuideShortcutsTitle:"Champ rapide sur chaque t\xe2che",tagsUserGuideShortcutsBody:"Dans Param\xe8tres → \xc9tiquettes et projets enregistr\xe9s (ou la colonne \xc9tiquettes \xe0 droite), vous \xe9pinglez \xe9tiquettes et projets que vous r\xe9utilisez. Sur une t\xe2che, l’\xe9troit champ \xe0 c\xf4t\xe9 de l’aide (?) propose ces valeurs ; appuyez sur Entr\xe9e pour appliquer une ligne (#\xe9tiquette, @projet, nom seul, ou @ seul pour retirer le projet). Cela ne r\xe9\xe9crit pas le titre tant que vous ne le modifiez pas vous-m\xeame.",tagsUserGuideScopedTitle:"Optionnel : @projet#code (\xe9tiquettes li\xe9es au projet)",tagsUserGuideScopedBody:"La syntaxe @Client#facture dans le titre enregistre une \xe9tiquette rattach\xe9e \xe0 ce projet (affich\xe9e Client#facture). Utile quand le m\xeame libell\xe9 local change selon le client, ou pour un filtrage plus strict. Si vous n’en avez pas besoin, restez sur #\xe9tiquette + @projet — les deux styles coexistent.",tagsUserGuideUseCasesTitle:"Cas d’usage",tagsUserGuideUseCasesBody:"• D\xe9veloppeur solo, un projet : tapez Ma fonctionnalit\xe9 @acme #frontend — sans liste enregistr\xe9e.\n• Beaucoup de tickets : \xe9pinglez #triage, #bugfix, @sprint-42 ; utilisez le champ rapide par t\xe2che au lieu de retaper.\n• Travail client : @ClientA#abonnement vs @ClientB#abonnement dans les titres pour s\xe9parer les espaces de noms ; filtrez par projet dans les rapports.\n• Saisie r\xe9troactive : m\xeames r\xe8gles # et @ dans le formulaire pass\xe9 ; le champ rapide accepte la m\xeame syntaxe.",tagsUserGuideFooterNote:"Les descriptions sur les \xe9tiquettes ou projets (survol long sur une pastille qui en a une) sont des notes pour l’\xe9quipe — elles ne changent pas le filtrage des donn\xe9es dans Kronosys.",subtasksHeading:"Points de d\xe9tail",addSubtaskLinkBtn:"Ajouter un point de d\xe9tail",addSubtaskPlaceholder:"Nouveau point…",addSubtaskBtn:"Ajouter",subtaskMarkDone:"Marquer ce point comme fait",subtaskMarkUndone:"Marquer ce point comme non fait",subtaskDelete:"Supprimer ce point",subtaskDragReorderHandle:"Glisser pour r\xe9ordonner",subtaskMoveUp:"Monter ce point dans la liste",subtaskMoveDown:"Descendre ce point dans la liste",subtaskTimerStart:"Suivre le temps sur ce point",subtaskTimerStop:"Arr\xeater le suivi sur ce point",subtaskDurationNotMeasured:"Pas mesur\xe9e",subtaskDurationNotRecorded:"Pas enregistr\xe9e",subtaskDurationNotShown:"Pas affich\xe9e",subtaskDurationTooltipNotMeasured:"Aucune dur\xe9e accumul\xe9e sur ce point pour l’instant. Utilisez la lecture pour d\xe9marrer le suivi.",subtaskDurationTooltipNotRecorded:"Cet instantan\xe9 ne contient pas de dur\xe9e pour ce point (non suivie ici ou absente de l’instantan\xe9 enregistr\xe9).",subtaskDurationTooltipNotShown:"Aucune dur\xe9e n’est affich\xe9e pour ce point termin\xe9 sans temps enregistr\xe9 dans cette vue archiv\xe9e.",noData:"Pas encore de donn\xe9es.",sessionsColumnTitle:"Sessions",sessionsColumnHelpAria:"Aide : colonne Sessions",sessionsColumnHelpBody:"Vos sessions enregistr\xe9es et la session en cours s’affichent ici lorsque le suivi est actif.\n\nOuvrez la session active pour modifier le suivi en direct.",dashboardColSessionTeaser:"Choisis la session en cours (ou d\xe9marre-en une). Tout le tableau de bord s’aligne sur ce choix.",dashboardColSessionFlowHint:"Ensuite → T\xe2ches au centre",dashboardColTasksTeaser:"Inscris le travail r\xe9el : t\xe2ches, minuteurs, KronoFocus — li\xe9 \xe0 la session \xe0 gauche.",dashboardColTasksFlowHint:"Puis → \xc9tiquettes & projets \xe0 droite",dashboardColTagsTeaser:"Ajoute #\xe9tiquettes, @projets et raccourcis pour garder l’historique et les rapports lisibles.",dashboardColTagsFlowHint:"Facultatif, mais le futur-toi remercie.",dashboardColumnHintsPanelTitle:"Comment lire les trois colonnes",dashboardColumnHintsExpandAria:"Afficher l’aide sur les trois colonnes du tableau de bord",dashboardColumnHintsCollapseAria:"Masquer l’aide sur les colonnes",dashboardColumnHintsDismissTitle:"Masquer d\xe9finitivement ce rappel",sessionsListAriaLabel:"Sessions",sessionLiveBadge:"En cours",sessionListWallDurationTitle:"Dur\xe9e murale de la session : minutes enregistr\xe9es si disponibles, sinon \xe9cart entre le d\xe9but et la fin.",sessionListWallDurationAlertTooltip:"Au seuil d’alerte ou au-del\xe0 ({hours} h) — modifiable dans Param\xe8tres → Tableau de bord web.",sessionListStartedPrefix:"D\xe9but :",sessionListEndedPrefix:"Fin :",sessionListOpenGanttAria:"Ouvrir la vue Gantt pour cette session",selectedSessionSidebarTimelineIconTooltip:"Gantt",selectedSessionSidebarTimelineIconAria:"Ouvrir la frise horizontale des t\xe2ches pour cette session",sessionEndLiveTitle:"Terminer la session — enregistrer dans l’historique sans en d\xe9marrer une nouvelle (le suivi peut rester actif)",sessionEndLiveAria:"Terminer la session en cours",sessionEndLiveConfirmTitle:"Terminer cette session ?",sessionEndLiveConfirmIntro:"Il reste du travail ouvert dans cette session. En la terminant, un instantan\xe9 est enregistr\xe9 dans l’historique : les minuteurs et le suivi par points ne s’appliquent plus \xe0 cette session, mais vous pourrez encore modifier les noms, les \xe9tiquettes et les projets en ouvrant la session archiv\xe9e.",sessionEndLiveConfirmIntroCalm:"En terminant la session, un instantan\xe9 est enregistr\xe9 dans l’historique avec l’heure de fin actuelle. Les minuteurs et le suivi par points ne s’appliquent plus \xe0 cette session, mais vous pourrez encore modifier les noms, les \xe9tiquettes et les projets en ouvrant la session archiv\xe9e.",sessionEndLiveWarnActiveTask:"Un suivi est actuellement actif (en cours).",sessionEndLiveWarnPausedTasks:"Au moins une entr\xe9e est en pause ou non termin\xe9e.",sessionEndLiveWarnIncompleteSubtasks:"Au moins un point n’est pas marqu\xe9 comme termin\xe9.",sessionEndLiveTasksHandlingLegend:"\xc0 la fermeture, que faire des t\xe2ches encore ouvertes ?",sessionEndLiveTasksHandlingKeep:"Laisser les t\xe2ches non termin\xe9es dans l’instantan\xe9 — les minuteurs s’arr\xeatent (le temps d\xe9j\xe0 cumul\xe9 est conserv\xe9)",sessionEndLiveTasksHandlingFinish:"Terminer les t\xe2ches ouvertes avec cette session",sessionEndLiveTasksHandlingMoveToPaused:"Transposer les t\xe2ches ouvertes vers une nouvelle session en pause",sessionEndLiveConfirmBtn:"Terminer la session",sessionEndLiveSidebarBtn:"Terminer cette session",sessionEndReasonModalHint:"Facultatif : indiquez pourquoi vous cl\xf4turez la session (bilans, feuilles de temps, r\xe9trospectives).",sessionEndReasonFieldsetLegend:"Raison de cl\xf4ture",sessionEndReasonSkip:"Ne pas enregistrer de cat\xe9gorie",sessionEndReasonPlanned:"Fin conforme au temps ou au p\xe9rim\xe8tre pr\xe9vu",sessionEndReasonEarly:"Fin anticip\xe9e (avant le temps ou l’\xe9ch\xe9ance pr\xe9vus)",sessionEndReasonOverrun:"Prolongation ou d\xe9passement par rapport au pr\xe9vu",sessionEndReasonOther:"Autre",sessionEndReasonNotePlaceholder:"Pr\xe9cision (facultatif)…",sessionEndReasonNoteAria:"Pr\xe9cision libre sur la fa\xe7on dont cette session se termine",selectedSessionEndReasonTitle:"Cl\xf4ture",sessionEndReasonEditHint:"Modifiez la cat\xe9gorie ou la pr\xe9cision enregistr\xe9e pour la cl\xf4ture de cette session.",sessionEndReasonSaveBtn:"Enregistrer la cl\xf4ture",sessionEndReasonSaveAria:"Enregistrer la raison de cl\xf4ture",sessionEndReasonSaving:"Enregistrement…",beforeUnloadLiveSessionMessage:"Une session Kronosys est ouverte dans ce tableau de bord. Fermer cet onglet ne met pas fin \xe0 la session. Utilisez \xab Terminer cette session \xbb dans la colonne de gauche pour la cl\xf4turer ici, ou quittez cet onglet — la session reste active en arri\xe8re-plan.",openSessionInNewTab:"Ouvrir cette session dans un nouvel onglet",detachedSessionUrlHint:"Cet onglet suit l’URL. Consulter une archive ici ne modifie que cet onglet — pas la session en cours ni la session s\xe9lectionn\xe9e dans les autres onglets ouverts.",detachedSessionUrlHintDismiss:"Masquer ce message",detachedSessionInvalidUrl:"Aucune session ne correspond \xe0 ce param\xe8tre d’URL.",tasksInSessionSingular:"\xe9l\xe9ment",tasksInSessionPlural:"\xe9l\xe9ments",rightColumnTitle:"T\xe2ches",tagsProjectsColumnTitle:"\xc9tiquettes, projets et mod\xe8les",tagsProjectsColumnIntro:"\xc9pinglage, descriptions et masquage des pastilles — comme dans les param\xe8tres, ici \xe0 c\xf4t\xe9 du flux de travail. Deux onglets permettent de basculer entre les \xe9tiquettes globales et les projets.",tagsProjectsColumnHelpAria:"Aide : colonne \xe9tiquettes et projets",tagsProjectsColumnHelpBody:"Les \xe9tiquettes globales s’appliquent \xe0 toute t\xe2che. Les \xe9tiquettes li\xe9es utilisent Projet#code et ne s’affichent en suggestion que si le @projet de la t\xe2che correspond.\n\nDans cette colonne, l’onglet \xc9tiquettes globales regroupe raccourcis, masqu\xe9es et descriptions ; l’onglet Projets et \xe9tiquettes li\xe9es regroupe les projets enregistr\xe9s et les codes par projet.\n\nCette colonne reprend la section \xab \xc9tiquettes et projets enregistr\xe9s \xbb des param\xe8tres ; les changements sont imm\xe9diats.\n\nL’aide compl\xe8te et les cas d’usage sont dans le \xab ? \xbb \xe0 c\xf4t\xe9 des \xe9tiquettes sur une carte t\xe2che.",tasksColumnSubtitle:"En cours au minuteur, planifi\xe9es (d\xe9but ou fin futur), en pause et termin\xe9es pour la session s\xe9lectionn\xe9e.",tasksColumnSubtitleHelpAria:"Aide : contenu de cette colonne",taskFocusNoSessionTitle:"Aucune session active",taskFocusNoSessionBody:"D\xe9marrez une session depuis la colonne Sessions \xe0 gauche pour enregistrer des t\xe2ches ici.",taskStartAutoSessionToast:"Aucune session en cours — d\xe9marrage d’une session pour y rattacher cette t\xe2che.",selectedSessionSidebarTitle:"Session s\xe9lectionn\xe9e",selectedSessionSidebarTitleLive:"Session en cours",selectedSessionSidebarTitleIdle:"Aucune session active",selectedSessionSidebarPausedBadgeGlobal:"Pause globale",selectedSessionSidebarPausedBadgeSession:"En pause",dashboardPauseBackdropTitleGlobal:"Pause globale active",dashboardPauseBackdropDetailGlobal:"Le suivi est fig\xe9 pour cette session, les t\xe2ches et les sous-t\xe2ches concern\xe9es. Reprenez via la commande de pause globale dans la barre du haut.",dashboardPauseBackdropAriaGlobal:"Tableau de bord : pause globale active",dashboardPauseBackdropTitleSession:"Suivi de session en pause",dashboardPauseBackdropDetailSession:"La dur\xe9e murale et les minuteurs concern\xe9s sont fig\xe9s. Reprenez depuis le bandeau au-dessus de la colonne T\xe2ches.",dashboardPauseBackdropAriaSession:"Tableau de bord : pause de session (murale) active",sessionNoteLabel:"Note de session",sessionNotePlaceholder:"Ajouter une note libre pour cette session…",selectedSessionIdleHint:"D\xe9marrez une session depuis la colonne Sessions pour enregistrer le temps, le suivi et les m\xe9triques.",sessionDetailsModalTitle:"R\xe9sum\xe9 de la session",sessionDetailsModalCloseAria:"Fermer le r\xe9sum\xe9 de session",sessionDetailsModalReopenBtn:"R\xe9sum\xe9 session",statsMetricSessionDurationHelpAria:"Aide : dur\xe9e de session",statsMetricSessionDurationHelpBody:"Temps \xe9coul\xe9 (horloge murale) depuis le premier \xe9v\xe9nement d’activit\xe9 enregistr\xe9 dans cette session jusqu’\xe0 maintenant (session en cours) ou jusqu’\xe0 l’enregistrement de l’instantan\xe9 (archive). Distinct du temps actif, du temps de codage et des minuteurs de suivi ou de point.",sessionRemainingDurationLabel:"Dur\xe9e restante",sessionRemainingDurationUndetermined:"Ind\xe9termin\xe9e",sessionPlannedTotalDurationLabel:"Dur\xe9e totale planifi\xe9e",sessionPlannedTasksTotalLabel:"Total planifi\xe9 (t\xe2ches)",sessionListPlannedTotalPrefix:"planifi\xe9",statsMetricCodingTimeHelpAria:"Aide : temps de codage",statsMetricCodingTimeHelpBody:"Temps cumul\xe9 lorsqu’un fichier productif (hors langages exclus) est au centre du contexte de codage : ouverture, enregistrement, changement d’\xe9diteur actif ou modifications. Cesse d’augmenter apr\xe8s environ une minute sans signal de ce type. Ind\xe9pendant du minuteur de suivi.",statsMetricActiveTimeHelpAria:"Aide : temps actif",statsMetricActiveTimeHelpBody:"Temps cumul\xe9 \xe0 partir de signaux d’activit\xe9 sur le poste : modifications, ouverture de fichier, changements de s\xe9lection, \xe9diteur actif et focus de fen\xeatre. Les intervalles de plus d’environ trois minutes ne comptent pas. Souvent entre le temps de codage et la dur\xe9e de session.",statsMetricTasksHelpAria:"Aide : t\xe2ches par statut",statsMetricTasksHelpBody:"Pour la session affich\xe9e : t\xe2ches avec le minuteur de suivi actif (\xab En cours (minuteur) \xbb), t\xe2ches dont le d\xe9but ou la fin est encore dans le futur (\xab Planifi\xe9es \xbb), autres t\xe2ches non termin\xe9es (section \xab En pause \xbb), et t\xe2ches termin\xe9es dont la fin n’est pas dans le futur. Reprend les blocs de la colonne T\xe2ches.",statsTasksRowRunning:"En cours (minuteur)",statsTasksRowPausedList:"En liste (non termin\xe9es)",statsTasksRowCompleted:"Termin\xe9es",statsTasksRowPlanned:"Planifi\xe9es (futur)",gitRepoCardTitle:"D\xe9p\xf4t Git du workspace",gitRepoNotARepo:"Le premier dossier du workspace n’est pas un d\xe9p\xf4t Git (ou Git n’est pas disponible).",gitRepoCardHelpAria:"Aide : aper\xe7u Git du workspace",gitRepoCardHelpBody:"R\xe9sum\xe9 du d\xe9p\xf4t Git \xe0 la racine du premier dossier du workspace : nombre de branches, de commits, extrait de `git log --graph --all`, et \xe9chantillon tri\xe9 des chemins suivis via `git ls-files`. Mis \xe0 jour lors du rafra\xeechissement du tableau de bord depuis le serveur.",gitRepoCurrentBranchLabel:"Branche courante",gitRepoBranchesLocalLabel:"Branches locales",gitRepoBranchesLocalHelpAria:"Aide : branches locales",gitRepoBranchesLocalHelpBody:"Nombre de branches locales (`git branch --list`).",gitRepoBranchesRemoteLabel:"Branches distantes",gitRepoBranchesRemoteHelpAria:"Aide : branches distantes",gitRepoBranchesRemoteHelpBody:"Nombre de branches de suivi distant (`git branch -r`), hors l’alias symbolique `*/HEAD`.",gitRepoCommitsHeadLabel:"Commits (HEAD)",gitRepoCommitsHeadHelpAria:"Aide : commits sur la branche courante",gitRepoCommitsHeadHelpBody:"Nombre de commits atteignables depuis HEAD (`git rev-list --count HEAD`), soit l’historique de la branche actuelle.",gitRepoCommitsAllLabel:"Commits (toutes refs)",gitRepoCommitsAllHelpAria:"Aide : commits toutes r\xe9f\xe9rences",gitRepoCommitsAllHelpBody:"Nombre sur toutes les r\xe9f\xe9rences (`git rev-list --all --count`). Peut \xeatre co\xfbteux sur les tr\xe8s gros d\xe9p\xf4ts ; affich\xe9 en — si la commande \xe9choue.",gitRepoStashesLabel:"Stashes",gitRepoStashesHelpAria:"Aide : liste des stashes",gitRepoStashesHelpBody:"Nombre d’entr\xe9es dans `git stash list`.",gitRepoGraphTitle:"Graphe r\xe9cent",gitRepoGraphHelpAria:"Aide : graphe de commits",gitRepoGraphHelpBody:"Graphe ASCII produit par `git log --graph --decorate --all` (40 derniers commits). Utile pour voir la relation entre branches.",gitRepoGraphEmpty:"Aucune ligne de graphe.",gitRepoGraphPreviewNote:"Aper\xe7u partiel — seulement les 40 derniers commits dans cette zone.",gitRepoGraphOpenFullAria:"Ouvrir le graphe de commits complet dans un nouvel onglet",gitRepoGraphOpenFullTitle:"Ouvrir le graphe de commits complet dans un nouvel onglet du navigateur",gitRepoGraphDetailDocTitle:"Graphe Git — Kronosys",gitRepoTreeTitle:"Fichiers suivis (extrait)",gitRepoTreeHelpAria:"Aide : extrait des chemins suivis",gitRepoTreeHelpBody:"\xc9chantillon tri\xe9 alphab\xe9tiquement des chemins de `git ls-files` (jusqu’\xe0 300). Ce n’est pas l’arborescence compl\xe8te ; sur les gros d\xe9p\xf4ts, des chemins peuvent manquer selon les limites de m\xe9moire.",gitRepoTreeEmpty:"Aucun chemin dans l’extrait.",gitRepoTreePreviewNote:"Aper\xe7u partiel — \xe9chantillon d’au plus 300 chemins suivis.",gitRepoTreeOpenFullAria:"Ouvrir la liste compl\xe8te des chemins suivis dans un nouvel onglet",gitRepoTreeOpenFullTitle:"Ouvrir la liste compl\xe8te des chemins suivis dans un nouvel onglet du navigateur",gitRepoTreeDetailDocTitle:"Fichiers suivis — Kronosys",statsLocSectionTitle:"Lignes et langages",statsLinesWrittenTotal:"Lignes \xe9crites",statsLinesWrittenHuman:"Humain (estim.)",statsLinesWrittenAi:"IA (estim.)",statsLocByLanguageHeading:"Lignes par langage",statsCodingSignalsHeading:"Signaux de codage par langage",statsMetricLinesWrittenHelpAria:"Aide : lignes \xe9crites",statsMetricLinesWrittenHelpBody:"Lignes nettes ajout\xe9es \xe0 partir des modifications suivies (estimation via les retours \xe0 la ligne dans les diffs). Les insertions tr\xe8s massives sont partiellement plafonn\xe9es. \xab Humain \xbb / \xab IA \xbb est une heuristique par transaction : plusieurs plages de modification, plus d’environ 6 lignes nettes, ou un bloc unique long avec saut de ligne ressemblent souvent \xe0 une insertion agent ou collage — ce n’est pas une attribution exacte.",statsMetricLocByLanguageHelpAria:"Aide : lignes par langage",statsMetricLocByLanguageHelpBody:"R\xe9partition des lignes nettes par identifiant de langage pour cette session (m\xeame base que \xab Lignes \xe9crites \xbb).",statsMetricCodingSignalsHelpAria:"Aide : signaux de codage",statsMetricCodingSignalsHelpBody:"Nombre de signaux de contexte de codage par langage (ouverture, enregistrement, \xe9dition, changement d’\xe9diteur actif, et signaux p\xe9riodiques lorsqu’une \xe9dition r\xe9cente a eu lieu).",sessionNameReadOnly:"Nom de la session (lecture seule pour cette archive)",sessionArchiveBtn:"Archiver",sessionArchiveTitle:"Masquer cette session de la liste (r\xe9cup\xe9rable dans Archives)",sessionRestoreBtn:"Restaurer",sessionDeleteBtn:"Supprimer",sessionDeleteTitle:"Supprimer la session",sessionDeleteIntro:"La session sera retir\xe9e de votre historique. Choisissez le sort des \xe9l\xe9ments associ\xe9s.",sessionDeleteDiscardTasks:"Supprimer les \xe9l\xe9ments avec la session (les abandonner)",sessionDeleteMoveTasks:"D\xe9placer les \xe9l\xe9ments vers une autre session",sessionDeleteTargetLabel:"Session cible",sessionDeleteTargetPlaceholder:"Choisir une session…",sessionDeleteConfirmBtn:"Supprimer la session",sessionDeleteCancelBtn:"Annuler",archivesModalTitle:"Sessions archiv\xe9es",archivesEmpty:"Aucune session archiv\xe9e.",archivesCloseBtn:"Fermer",archivedBadge:"Archiv\xe9e",sessionArchiveConfirm:"Archiver cette session ?\n\n• Masqu\xe9e de la liste jusqu’\xe0 restauration (Archives).\n• Rapports : exclues les entr\xe9es non termin\xe9es et celles dont un point reste ouvert (totaux, graphiques, temps par projet, KronoFocus li\xe9).",sessionArchiveDontShowAgain:"Ne plus afficher cet avertissement",storageBadgeLabelSqlite:"SQLite",storageBadgeTooltipSqlite:"L’historique des sessions est stock\xe9 en SQLite dans le r\xe9pertoire de donn\xe9es Kronosys (pilote de persistance locale dans les param\xe8tres).",storageBadgeLabelJson:"JSON",storageBadgeTooltipJson:"L’historique des sessions utilise des fichiers JSON partitionn\xe9s (pilote local h\xe9rit\xe9). Vous pouvez passer \xe0 SQLite dans les param\xe8tres Kronosys",storageBadgeLabelMongo:"MongoDB",storageBadgeTooltipMongo:"Le miroir MongoDB est activ\xe9 et connect\xe9. Vous pouvez envoyer les sessions depuis la liste ; les sessions locales suivent toujours votre pilote de persistance.",workspaceFoldersLabel:"Racines du workspace",workspaceFoldersEmpty:"Aucune racine de workspace n’est configur\xe9e pour ce tableau de bord.",headerDisplayRegionTitle:"Fuseau d’affichage {timeZone} ; format d’horloge {clock}.",headerClockFormat24Short:"24 h",headerClockFormat12Short:"12 h (AM/PM)",headerWallClockAriaLabel:"Horloge murale, fuseau d’affichage {timeZone} : {datetime}.",gitIdentityBannerAria:"Auteur Git non configur\xe9",gitIdentityBannerBody:"Indiquez l’auteur Git (nom, courriel, identifiant de forge optionnel) pour la ligne sous le titre du tableau de bord. Utilisez Configurer ici pour un formulaire rapide — tout reste local et modifiable plus tard dans Param\xe8tres → Identit\xe9 Git.",gitIdentityBannerConfigure:"Configurer ici",gitIdentityBannerDismiss:"Masquer ce rappel",gitIdentityModalTitle:"Auteur Git (saisie rapide)",gitIdentityModalIntro:"Renseignez au moins un des champs ci-dessous. Les valeurs sont enregistr\xe9es localement avec vos donn\xe9es Kronosys — rien n’est envoy\xe9 au nuage depuis cette bo\xeete de dialogue.\n\nVous pourrez les modifier ou les compl\xe9ter \xe0 tout moment dans Param\xe8tres → Identit\xe9 Git.",gitIdentityModalNeedOneField:"Renseignez au moins un champ (nom, courriel ou identifiant sur la forge) avant d’enregistrer.",gitIdentityModalSaveError:"Enregistrement impossible. V\xe9rifiez la connexion et r\xe9essayez.",gitIdentityModalFooter:"Jeton GitLab, synchronisation Git automatique et autres options avanc\xe9es restent accessibles dans Param\xe8tres, section Identit\xe9 Git, lorsque vous en avez besoin.",mongoSyncLocalLabel:"JSON local",mongoSyncMongoLabel:"MongoDB",mongoSyncStatusAligned:"Align\xe9",mongoSyncStatusUnknown:"Nombre Mongo indisponible",mongoSyncStatusLocalAhead:"D\xe9calage — moins de documents dans Mongo",mongoSyncStatusMongoAhead:"D\xe9calage — plus de documents dans Mongo",mongoSyncHelpAriaLabel:"Aide : miroir MongoDB et sessions locales",mongoSyncHelpBody:"Les fichiers JSON locaux font foi. Les totaux comptent les sessions uniques dans l’historique (y compris archiv\xe9es). MongoDB n’est mis \xe0 jour que lorsque vous envoyez une session ou via Resynchroniser dans les param\xe8tres — pas \xe0 chaque sauvegarde locale. Un \xe9cart de totaux indique souvent des sessions jamais envoy\xe9es ou des documents suppl\xe9mentaires dans Mongo. La session en cours n’appara\xeet dans le d\xe9compte local qu’apr\xe8s \xe9criture sur disque.",sessionMongoPushAriaLabel:"Envoyer cette session vers MongoDB",sessionMongoPushSyncedTitle:"\xc0 jour sur MongoDB pour cet instantan\xe9",sessionMongoPushDirtyTitle:"Session modifi\xe9e depuis le dernier envoi — cliquer pour mettre \xe0 jour",sessionMongoPushNeverTitle:"Pas encore envoy\xe9e vers MongoDB — cliquer pour envoyer",sessionMongoPushBusy:"Envoi…",sessionMongoPushFailedDisabled:"MongoDB n’est pas activ\xe9 dans les param\xe8tres.",sessionMongoPushFailedNotFound:"Session introuvable.",sessionMongoPushFailedMongo:"MongoDB a refus\xe9 l’\xe9criture. V\xe9rifiez la connexion et les journaux.",sessionMongoPushFailedUri:"Connexion MongoDB incompl\xe8te (URI ou mot de passe).",dashboardLoadingAriaLabel:"Chargement du tableau de bord, veuillez patienter",dashboardLoadingMessage:"R\xe9cup\xe9ration des donn\xe9es de session depuis le serveur Kronosys…",dashboardConnectionErrorAriaLabel:"Serveur Kronosys injoignable",dashboardConnectionErrorTitle:"Connexion au serveur impossible",dashboardConnectionErrorBody:"D\xe9marrez l’application Kronosys (par ex. `kronosys start` ou `npm run dev`) et v\xe9rifiez que cet onglet peut la joindre. Si vous utilisez un dossier de donn\xe9es personnalis\xe9, contr\xf4lez les permissions du fichier SQLite.",dashboardConnectionRetryLabel:"R\xe9essayer",dashboardConnectionTechnicalDetailsLabel:"D\xe9tails techniques",dashboardSyncErrorBanner:"Impossible de resynchroniser avec le serveur. Affichage du dernier \xe9tat charg\xe9.",dataSearchTrigger:"Spotlight…",dataSearchPlaceholder:"Filtrer sessions, t\xe2ches, mod\xe8les, projets, \xe9tiquettes, dates, ou dur\xe9e (ex. 12:55 <, 0:10 >)…",dataSearchPaletteAriaLabel:"Recherche Spotlight",dataSearchTypePrompt:"Saisissez du texte pour filtrer les sessions, les t\xe2ches, les mod\xe8les de t\xe2che enregistr\xe9s, les projets et les \xe9tiquettes. Vous pouvez aussi saisir une date, une heure, ou une condition sur la dur\xe9e enregistr\xe9e : m:s (ou h:m:s) suivi (ou pr\xe9c\xe9d\xe9) de < ou >, p. ex. 45:00 > ou 1:0:0 <. Choisir un mod\xe8le remplit le brouillon de t\xe2che.",dataSearchEmpty:"Aucune session, t\xe2che ou mod\xe8le ne correspond.",dataSearchFooter:"↑↓ pour se d\xe9placer \xb7 Entr\xe9e pour ouvrir \xb7 \xc9chap pour fermer",dataSearchKindSession:"Session",dataSearchKindTask:"T\xe2che",dataSearchKindTaskTemplate:"Mod\xe8le de t\xe2che",taskTemplateDatalistPrefix:"Mod\xe8le :",taskTitleTemplateSuggestAria:"Mod\xe8les et titres r\xe9currents",taskTokenSuggestTagsAria:"\xc9tiquettes sugg\xe9r\xe9es",taskTokenSuggestWorkProjectsAria:"Projets sugg\xe9r\xe9s",taskTokenSuggestPersonalProjectsAria:"Projets personnels sugg\xe9r\xe9s",dataSearchTaskDistinguishId:"ID : {id}",dataSearchTaskStopwatchLabel:"Minuterie",dataSearchTaskRecordedTimeLabel:"Temps enregistr\xe9",dataSearchSessionWallLabel:"Dur\xe9e (session)",commandNewSession:"Nouvelle session",commandRefresh:"Actualiser le tableau de bord",commandOpenReporting:"Ouvrir les rapports",commandOpenSettings:"Ouvrir les param\xe8tres",commandOpenUserGuide:"Ouvrir le guide d’utilisation",commandFocusSessions:"Aller \xe0 la colonne Sessions",commandFocusTasks:"Aller \xe0 la colonne T\xe2ches",commandFocusTags:"Aller \xe0 la colonne \xc9tiquettes et projets",commandToggleTheme:"Basculer th\xe8me clair / sombre",commandToggleLang:"Changer la langue de l’interface (FR / EN)",commandEndLiveSession:"Terminer la session en cours",commandToggleFocusMode:"Basculer le mode focus (colonnes seules)",dashboardFocusModeEnterTitle:"Mode focus — sessions, t\xe2ches et \xe9tiquettes seulement",dashboardFocusModeEnterAria:"Activer le mode focus du tableau de bord",dashboardFocusModeExitTitle:"Quitter le mode focus",dashboardFocusModeExitAria:"Quitter le mode focus du tableau de bord",dashboardFocusModeExitHint:"\xc9chap",shortcutsModalTitle:"Raccourcis clavier",shortcutsModalCloseAriaLabel:"Fermer la fen\xeatre des raccourcis clavier",shortcutsModalIntro:"Cliquez sur \xab Modifier \xbb, puis enregistrez la nouvelle combinaison (au moins une touche Ctrl, Alt, Maj ou Meta). \xc9chap annule l’enregistrement. Ctrl+K / ⌘K est r\xe9serv\xe9 \xe0 la recherche rapide dans les donn\xe9es (non modifiable ici).",shortcutsTableAction:"Action",shortcutsTableShortcut:"Raccourci",shortcutsTableAssign:"Personnaliser",shortcutsChangeBtn:"Modifier…",shortcutsRecordPrompt:"Enregistrement…",shortcutsResetAll:"Tout r\xe9tablir aux valeurs par d\xe9faut",shortcutsPaletteRow:"Recherche Spotlight — Ctrl+K ou ⌘K (fixe)",tourProgressLabel:"\xc9tape {n} sur {total}",tourStep1Title:"Bienvenue dans le tableau de bord Kronosys",tourStep1Body:"Ce tableau de bord charge les donn\xe9es de session en direct depuis cette application web (routes API Next.js et SQLite local) — ce n’est pas un instantan\xe9 fig\xe9.",tourStep2Title:"Guide des trois colonnes (au-dessus du tableau)",tourStep2Body:"Cette bande se place juste sous l’en-t\xeate et r\xe9sume comment s’articulent **Sessions**, **T\xe2ches** et **\xc9tiquettes et projets** — de gauche \xe0 droite sur grand \xe9cran, empil\xe9es sur petit \xe9cran, avec des fl\xe8ches entre les blocs.\n\nD\xe9ployez-la ou repliez-la avec le chevron ; chaque encadr\xe9 est un court rappel avant les vraies colonnes plus bas. **Le bouton X** \xe0 droite masque tout le bandeau pour ce navigateur ; r\xe9activez-le sous **Param\xe8tres → Tableau de bord et API → Aide trois colonnes**. Le repli au chevron et le masquage complet sont m\xe9moris\xe9s s\xe9par\xe9ment.",tourStep3Title:"Sessions (colonne de gauche)",tourStep3Body:"Parcourez l’historique des sessions, d\xe9marrez une nouvelle session et consultez la dur\xe9e, le temps de codage et les statistiques de la session s\xe9lectionn\xe9e.\n\nLorsqu’une session en cours est ouverte, vous pouvez la terminer d’ici ; les sessions archiv\xe9es s’affichent en lecture seule.\n\nPour des options d’horaire plus pouss\xe9es, ouvrez Param\xe8tres (engrenage) : sous **Tableau de bord et API**, l’**alerte de dur\xe9e de session** met en \xe9vidence une session trop longue dans cette colonne ; les sections **Horaire de travail** et **Sessions sp\xe9cifiques planifi\xe9es** r\xe8glent le suivi automatique sur la semaine et des cr\xe9neaux r\xe9currents pr\xe9cis qui priment sur l’horaire g\xe9n\xe9ral pendant leur plage horaire.",tourStep4Title:"T\xe2ches et suivi (centre)",tourStep4Body:"Suivez ce sur quoi vous travaillez, terminez des t\xe2ches et utilisez les sous-t\xe2ches ou les options li\xe9es \xe0 Git au besoin.\n\nCette colonne suit la session choisie dans la colonne Sessions — le reste de l’en-t\xeate s’aligne sur ce choix.\n\nSur les autres t\xe2ches parentes, un seul flux de suivi : lancer le suivi d’une sous-t\xe2che lance aussi le minuteur de la t\xe2che parente et interrompt le suivi sur les autres t\xe2ches (le segment est enregistr\xe9). Mettre la t\xe2che parente en pause met en pause le suivi d’une sous-t\xe2che active sur la m\xeame t\xe2che. Reprendre le minuteur d’une t\xe2che ailleurs met fin aux suivi de sous-t\xe2ches sur les autres t\xe2ches et met en pause leur minuteur principal.\n\nLes points de d\xe9tail sont facultatifs. Le total sur la t\xe2che est toujours au moins la somme du temps enregistr\xe9 sur ces points ; l’\xe9cart correspond au suivi sur la t\xe2che sans d\xe9tail par point.\n\nSur une t\xe2che en cours, en pause ou termin\xe9e, **Sauvegarder comme template** enregistre son titre, ses #\xe9tiquettes et son @projet pour les r\xe9utiliser plus tard — le champ nouvelle t\xe2che les propose avec le pr\xe9fixe **Mod\xe8le :** et la palette Ctrl+K / ⌘K les liste \xe9galement. Vous pouvez aussi **corriger les bornes temporelles** d’une t\xe2che en conservant la dur\xe9e enregistr\xe9e, en saisissant une dur\xe9e manuelle (h/m/s) ou en recalculant depuis le d\xe9but et la fin.",tourStep5Title:"\xc9tiquettes et projets (droite)",tourStep5Body:"\xc9pinglez des \xe9tiquettes, g\xe9rez les projets enregistr\xe9s et r\xe9digez des descriptions — les m\xeames r\xe9glages que dans les param\xe8tres, accessibles pendant le travail. Deux onglets s\xe9parent les \xe9tiquettes globales des projets et des \xe9tiquettes li\xe9es.\n\nDans les titres de t\xe2ches, utilisez @projet et #\xe9tiquettes (y compris @projet#code) pour structurer le travail par projet.\n\nLes rapports (graphiques) s’appuient fortement sur ces objets : des \xe9tiquettes et des projets coh\xe9rents rendent les ventilations, filtres et tendances dans Rapports beaucoup plus utiles.",tourStep6Title:"Barre du haut : toutes les ic\xf4nes",tourStep6Body:"Dans ce groupe, de gauche \xe0 droite : la recherche rapide / palette de commandes (\xe9quivalent \xe0 Ctrl+K ou ⌘K — sessions, t\xe2ches, **mod\xe8les de t\xe2che**, projets et \xe9tiquettes), l’ic\xf4ne clavier pour l’aide aux raccourcis et leur personnalisation, les ic\xf4nes de navigation vers Tableau de bord, Rapports (graphiques), Param\xe8tres (engrenage), Guide d’utilisation (livre) et **Impl\xe9mentation** (fichier code — inventaire exhaustif ✓ / ✗ des user stories), le bouton **Gantt du jour** (intervalles des t\xe2ches de toutes les sessions du jour courant), la bascule de **pause globale**, le basculement th\xe8me clair / sombre, le bouton qui actualise les donn\xe9es sans recharger tout l’onglet du navigateur, et le menu de langue (FR / EN).\n\nLa pause globale reste inactive lorsque rien ne tourne. Sinon, elle ouvre une **modale de confirmation** avec un r\xe9sum\xe9 (d\xe9but, fin ou *en cours*, dur\xe9e murale, temps de codage et temps actif de session lorsque l’h\xf4te les fournit, d\xe9compte t\xe2ches / sous-t\xe2ches, total enregistr\xe9 sur les minuteurs de t\xe2ches puis r\xe9partition principal vs sous-t\xe2ches) avant de mettre en pause la session, ses t\xe2ches et les sous-t\xe2ches actives ; le clic suivant reprend uniquement ce lot.\n\nChaque contr\xf4le a une infobulle au survol ; les ic\xf4nes de navigation conservent le m\xeame habillage Kronosys.",tourStep7Title:"Identit\xe9 Git et pastille de stockage",tourStep7Body:"Ici s’affichent la ligne d’auteur Git et le compte forge lorsqu’ils sont renseign\xe9s dans Param\xe8tres → Identit\xe9 Git, les racines de workspace d\xe9tect\xe9es pour les m\xe9triques, et une pastille indiquant comment les sessions sont enregistr\xe9es ici : SQLite (par d\xe9faut), pilote JSON ou miroir MongoDB si activ\xe9.\n\nSQLite conserve la charge utile du tableau de bord sur cette machine dans le r\xe9pertoire de donn\xe9es Kronosys ; cette page lit et \xe9crit via l’API locale.",tourStep8Title:"Qu’est-ce que KronoFocus ?",tourStep8Body:"**KronoFocus** cadence votre session : un segment de travail dont vous choisissez la dur\xe9e, des pauses courtes, puis une pause longue apr\xe8s plusieurs cycles. Ce dispositif est int\xe9gr\xe9 \xe0 Kronosys (compteurs, phases, lien \xe0 la session) ; il ne se r\xe9sume pas \xe0 une m\xe9thode Pomodoro fig\xe9e.\n\nLa barre d’outils affiche toujours KronoFocus pour garder la navigation align\xe9e sur toutes les pages. L’affichage \xe0 c\xf4t\xe9 des actions de t\xe2che se r\xe8gle toujours dans Param\xe8tres → Tableau de bord et API (section KronoFocus).",tourStep8LearnMoreUrl:"https://fr.wikipedia.org/wiki/Gestion_du_temps",tourStep8LearnMoreLabel:"Pour aller plus loin — gestion du temps (nouvel onglet)",tourStep8LearnMoreAriaLabel:"Ouvre l’article Wikip\xe9dia sur la gestion du temps dans un nouvel onglet",tourStep9Title:"Identit\xe9 Git : la premi\xe8re chose apr\xe8s la visite",tourStep9Body:"Ce panneau s’affiche tant que le nom, le courriel ou le compte forge ne sont pas renseign\xe9s. Utilisez Configurer ici pour remplir un court formulaire sans quitter le tableau de bord — c’est l’action recommand\xe9e juste apr\xe8s la visite. Vous pouvez choisir Masquer ce rappel si vous pr\xe9f\xe9rez le faire plus tard.",tourSkipBtn:"Passer la visite",tourBackBtn:"Pr\xe9c\xe9dent",tourNextBtn:"Suivant",tourDoneBtn:"Terminer",settingsTourProgressLabel:"\xc9tape {n} sur {total}",settingsTourStep1Title:"Param\xe8tres et options",settingsTourStep1Body:"Certaines options avanc\xe9es ne sont pr\xe9sentes que dans les param\xe8tres et non sur le tableau de bord. Cette visite souligne les configurations cl\xe9s de votre espace de travail.",settingsTourStep2Title:"Profil d’usage",settingsTourStep2Body:"Basculez entre les modes 'Manager' et 'D\xe9veloppeur' pour ajuster le niveau de d\xe9tail du tableau de bord et la fr\xe9quence des rappels.",settingsTourStep3Title:"Persistance et pilotes",settingsTourStep3Body:"Choisissez entre SQLite (recommand\xe9) et l’ancien format JSON pour votre historique local. Vous pouvez aussi configurer un miroir MongoDB.",settingsTourStep4Title:"Int\xe9gration Git et GitLab",settingsTourStep4Body:"Configurez votre identit\xe9 Git et votre jeton d’API GitLab pour activer l’import d’issues et la g\xe9n\xe9ration de messages de commit.",settingsTourStep5Title:"Rapports et exclusions",settingsTourStep5Body:"D\xe9finissez les r\xe9pertoires et motifs de fichiers \xe0 exclure du d\xe9compte de lignes et du suivi de temps pour garder vos rapports propres.",settingsTourStep6Title:"Horaires et automatisation",settingsTourStep6Body:"Configurez vos heures de travail r\xe9currentes et vos sessions planifi\xe9es pour automatiser le d\xe9marrage du suivi ou le transfert de t\xe2ches.",settingsTourSkipBtn:"Passer la visite",settingsTourBackBtn:"Pr\xe9c\xe9dent",settingsTourNextBtn:"Suivant",settingsTourDoneBtn:"Terminer",tourUndismissBtn:"Relancer la visite",reportingTourProgressLabel:"Visite Rapports — \xe9tape {n} sur {total}",reportingTourStep1Title:"Bienvenue dans Rapports Kronosys",reportingTourStep1Body:"Cette page agr\xe8ge l’historique Kronosys via l’API locale. Elle sert \xe0 revoir les sessions, le temps enregistr\xe9 sur les t\xe2ches, l’usage KronoFocus et, selon les filtres, les r\xe9partitions par #\xe9tiquette et par @projet.",reportingTourStep2Title:"Filtres",reportingTourStep2Body:"Choisissez une plage de dates (ou les raccourcis Jour / Semaine / Mois / Ann\xe9e), affinez \xe9ventuellement par #\xe9tiquettes, puis r\xe9initialisez pour tout r\xe9afficher. Les pastilles vertes signalent des donn\xe9es encore mouvantes (session ou t\xe2ches non termin\xe9es).",reportingTourStep3Title:"Indicateurs r\xe9capitulatifs",reportingTourStep3Body:"Ces cartes condensent la m\xeame fen\xeatre que les graphiques : sessions, lignes de t\xe2ches, KronoFocus et minutes enregistr\xe9es. Les ic\xf4nes (?) ouvrent une courte d\xe9finition sans encombrer la page.",reportingTourStep4Title:"Graphiques par jour",reportingTourStep4Body:"Les barres montrent les sessions, les t\xe2ches par \xe9tat, le temps enregistr\xe9 sur les t\xe2ches et la dur\xe9e murale des sessions par jour calendaire. Quand plusieurs semaines existent, la bande de navigation aligne graphiques et calendriers par \xe9tiquette.",reportingTourStep5aTitle:"Temps par \xe9tiquette",reportingTourStep5aBody:"Consultez les minutes enregistr\xe9es sur les t\xe2ches regroup\xe9es par #\xe9tiquettes (y compris le compartiment sans \xe9tiquette explicite le cas \xe9ch\xe9ant), avec des grilles hebdomadaires lorsque les donn\xe9es couvrent plusieurs jours.",reportingTourStep5bTitle:"Temps par projet (Travail vs Personnel)",reportingTourStep5bBody:"La grille hebdomadaire par projet propose un s\xe9lecteur Travail (@) / Personnel (!) sous le titre de la section : Travail (d\xe9faut) exclut le registre personnel ; Personnel n’affiche que celui-ci (y compris les t\xe2ches d\xe9duites d’un jeton \xab ! \xbb dans le titre si le drapeau enregistr\xe9 manque). Les totaux par \xe9tiquette au-dessus combinent toujours les deux registres, sauf filtre par \xe9tiquettes.",reportingTourStep6Title:"Sommaire et mise en page \xe0 deux colonnes",reportingTourStep6Body:"Ce bloc correspond \xe0 la disposition principale de Rapports : le contenu \xe0 gauche et, sur grand \xe9cran, le sommaire fixe \xe0 droite. Sur t\xe9l\xe9phone, les m\xeames ancres sont propos\xe9es en pastilles au-dessus des filtres.",newSessionModalTitle:"Nouvelle session — port\xe9e",newSessionModalHelpAria:"Aide : d\xe9but de session et port\xe9e (dur\xe9e, dates, jours)",newSessionModalHelpBody:"Choisissez si la session d\xe9marre **maintenant** ou avec un **d\xe9but r\xe9troactif**. Saisissez **le d\xe9but et la fin** (heure locale du navigateur) pour un d\xe9but **pass\xe9**. En mode **Maintenant**, vous pouvez optionnellement indiquer une **fin planifi\xe9e** — la session se cl\xf4ture automatiquement \xe0 cette heure (comme si vous la posiez ensuite sur une session live). Si la fin est encore **\xe0 venir** sur un d\xe9but r\xe9troactif, Kronosys ouvre une session **live** \xe0 partir de ce d\xe9but et la **cl\xf4ture automatiquement** \xe0 l’heure pr\xe9vue ; si la fin est **d\xe9j\xe0 pass\xe9e**, la plage close est consign\xe9e dans l’historique. Un lancement **imm\xe9diat** alors qu’une session est d\xe9j\xe0 active ouvre d’abord la fin de session ; une session **enti\xe8rement pass\xe9e** n’interrompt pas la session active : la ligne va dans l’historique et l’\xe9cran bascule dessus. Ensuite, ces options de port\xe9e fixent le cadre attendu pour cette session seulement. Elles n’arr\xeatent pas Kronosys automatiquement : des rappels viennent de la collecte (battement de cœur) et une banni\xe8re ici lorsque vous approchez ou sortez des limites.\n\n• Dur\xe9e murale maximale — compt\xe9e depuis le premier \xe9v\xe9nement trac\xe9 dans la session.\n\n• P\xe9riode calendaire — dates locales inclusives (d\xe9but et/ou fin).\n\n• Jours de la semaine — limite aux jours choisis ; vous pouvez ajouter une plage horaire quotidienne (24 h locale). Les plages qui passent minuit sont prises en charge (ex. 22:00–06:00).",newSessionTimingSectionTitle:"D\xe9but de la session",newSessionTimingImmediate:"Maintenant (lancement imm\xe9diat)",newSessionTimingPast:"Dans le pass\xe9 (d\xe9but r\xe9troactif)",newSessionPastStartLabel:"La session a commenc\xe9 \xe0 (local)",newSessionPastStartHint:"Interpr\xe9t\xe9 dans le fuseau local du navigateur. L’horloge murale de session part de cet instant ; vous pourrez ensuite ajouter des t\xe2ches et ajuster les heures.",newSessionPastEndLabel:"La session se termine \xe0 (local)",newSessionPastEndHint:"Doit \xeatre apr\xe8s le d\xe9but. Si la fin est encore \xe0 venir, une session live s’ouvre et se cl\xf4ture automatiquement \xe0 cette heure ; si la fin est d\xe9j\xe0 pass\xe9e, la plage close est consign\xe9e dans l’historique.",newSessionImmediateEndLabel:"Fin planifi\xe9e (optionnelle, local)",newSessionImmediateEndHint:"Laissez vide pour aucune fin automatique. Si renseign\xe9e, la fin doit \xeatre dans le futur — la session se cl\xf4ture automatiquement \xe0 cet instant.",newSessionScopeFieldsetLegend:"Port\xe9e (rappels)",newSessionModeNone:"Aucune limite",newSessionModeMax:"Dur\xe9e murale maximale",newSessionModeCalendar:"P\xe9riode calendaire (dates)",newSessionModeWeekly:"Jours de la semaine (horaire optionnel)",newSessionMaxHoursLabel:"Dur\xe9e max (heures)",newSessionDateFromLabel:"Du (date)",newSessionDateToLabel:"Au (date)",newSessionTodayBtn:"Aujourd’hui",newSessionWeekdaysLegend:"Jours actifs",newSessionQuickWeekdays:"Jours de semaine",newSessionQuickWeekends:"Week-ends",newSessionQuickAll:"Tous les jours",newSessionTimeFromLabel:"Quotidiennement de",newSessionTimeToLabel:"\xe0",newSessionNowBtn:"Maintenant",newSessionUseTimeWindow:"Limiter \xe0 une plage horaire chaque jour s\xe9lectionn\xe9",newSessionUseTimeWindowHelpAria:"Aide : plage horaire quotidienne",newSessionUseTimeWindowHelpBody:"Quand activ\xe9e, la session ne suit le temps que dans la plage horaire sp\xe9cifi\xe9e pour les jours s\xe9lectionn\xe9s. En dehors de cette plage, la session est consid\xe9r\xe9e comme en pause. Prend en charge les plages chevauchant minuit (ex. 22:00–06:00).",newSessionErrorMax:"Indiquez une dur\xe9e maximale entre 0,1 et 8760 heures.",newSessionErrorCalendar:"Choisissez au moins une date (du et/ou au).",newSessionErrorWeekly:"S\xe9lectionnez au moins un jour de la semaine.",newSessionErrorPastMissing:"Indiquez la date et l’heure de d\xe9but pour une session pass\xe9e.",newSessionErrorPastEndMissing:"Indiquez la date et l’heure de fin pour une session pass\xe9e.",newSessionErrorPastEndBeforeStart:"La fin doit \xeatre strictement apr\xe8s le d\xe9but.",newSessionErrorPastFuture:"Choisissez une date et une heure dans le pass\xe9 ou au pr\xe9sent (pas dans le futur).",newSessionErrorPastInvalid:"Date ou heure non reconnues.",newSessionErrorImmediateEndNotFuture:"La fin planifi\xe9e doit \xeatre dans le futur (au moins environ une minute).",newSessionStartBtn:"D\xe9marrer la session",newSessionCancelBtn:"Annuler",sessionScopeNoticeAria:"Rappel de port\xe9e de session",appShellRouteNavAria:"Sections principales",appShellRouteNavTodayGantt:"Ouvrir le fil de la journ\xe9e (vue Gantt)",appShellRouteNavGlobalPause:"Mettre en pause la session, les t\xe2ches et les sous-t\xe2ches dans ce contexte",appShellRouteNavGlobalResume:"Reprendre uniquement ce qui a \xe9t\xe9 mis en pause globalement dans ce contexte",appShellRouteNavGlobalPauseDisabledTooltip:"Rien n’est actif \xe0 mettre en pause : l’horloge murale est d\xe9j\xe0 fig\xe9e et aucun minuteur de t\xe2che ou de sous-t\xe2che ne tourne.",appShellRouteNavGanttDashboardOnlyTooltip:"Le Gantt du jour n’est disponible que depuis le tableau de bord.",appShellRouteNavGlobalPauseDashboardOnlyTooltip:"La pause globale n’est disponible que depuis le tableau de bord lorsqu’une session live est charg\xe9e.",appShellRouteNavGlobalPauseNoSessionContextTooltip:"La pause globale n’est pas disponible pendant la consultation d’une archive ou avant le chargement de la session live.",appShellRouteNavChangelogUnavailableTooltip:"Raccourci changelog masqu\xe9 sur cet \xe9cran (libell\xe9 vide).",appShellRouteNavImplementationUnavailableTooltip:"Raccourci impl\xe9mentation masqu\xe9 sur cet \xe9cran (libell\xe9 vide).",appShellHeaderKronoFocusLoadingAria:"KronoFocus — attente des donn\xe9es de session",appShellRouteNavGroupAppAria:"Zones principales de l’application",appShellRouteNavGroupDocsAria:"Aide et documentation",appShellRouteNavGroupToolsAria:"Outils de session",appShellRouteNavGroupLegalAria:"Informations l\xe9gales",appShellRouteNavDataEnvironmentGroupAria:"Coffre production ou QA",dataEnvironmentNavGroupHint:"Basculer entre les donn\xe9es de production et un bac \xe0 sable QA isol\xe9",dataEnvironmentNavActiveLabel:"Actif",dataEnvironmentNavActiveProd:"Production",dataEnvironmentNavActiveQa:"QA",dataEnvironmentNavPendingRestart:"Au red\xe9marrage : {env}",dataEnvironmentNavEnableQaShort:"QA",dataEnvironmentNavEnableQaTitle:"Activer un coffre QA distinct (v4-qa) en plus de la production",dataEnvironmentNavSettingsLink:"Param\xe8tres",dataEnvironmentDualEnabledHint:"Coffre QA activ\xe9. Utilisez Prod / QA pour basculer, puis red\xe9marrez le serveur Kronosys.",dataEnvironmentNavTraceOverrideShort:"Chemin perso.",dataEnvironmentNavTraceOverrideAria:"TRACE_DATA_DIR est d\xe9fini ; le basculement production / QA est d\xe9sactiv\xe9",dataEnvironmentNavProdShort:"Prod",dataEnvironmentNavQaShort:"QA",dataEnvironmentNavProdTitle:"Donn\xe9es de production (vos vraies sessions et t\xe2ches)",dataEnvironmentNavQaTitle:"Donn\xe9es QA (copie isol\xe9e pour tests et reproduction de probl\xe8mes)",dataEnvironmentQaBanner:"Environnement QA — les donn\xe9es ici sont distinctes de la production. N’utilisez pas cet \xe9cran pour du travail r\xe9el.",dataEnvironmentSwitchRestartHint:"Pr\xe9f\xe9rence de coffre enregistr\xe9e. Red\xe9marrez le serveur Kronosys (arr\xeat puis `kronosys start` ou votre serveur de dev) pour ouvrir l’environnement choisi.",dataEnvironmentSwitchSuccessHint:"Bascule vers le coffre {env} effectu\xe9e.",dataEnvironmentSwitchError:"Impossible de changer d’environnement de donn\xe9es.",dataEnvironmentSwitchDisabled:"Activez d’abord les deux environnements dans Param\xe8tres → G\xe9n\xe9ral.",dataEnvironmentSwitchConfirmTitle:"Changer de coffre de donn\xe9es",dataEnvironmentSwitchConfirmMessage:"Vous allez basculer vers le coffre {env}.\n\nApr\xe8s confirmation, Kronosys rouvrira imm\xe9diatement le fichier SQLite correspondant.",dataEnvironmentSwitchConfirmBtn:"Basculer",dataEnvironmentSwitchLockBackdropTitleSwitching:"Bascule en cours…",dataEnvironmentSwitchLockBackdropDetailSwitching:"Veuillez patienter pendant l’enregistrement de la pr\xe9f\xe9rence.",dataEnvironmentSwitchLockBackdropAriaSwitching:"Application verrouill\xe9e : bascule de coffre en cours",dataEnvironmentSwitchLockBackdropTitleLocked:"Red\xe9marrage requis",dataEnvironmentSwitchLockBackdropDetailLocked:"La pr\xe9f\xe9rence de coffre a \xe9t\xe9 enregistr\xe9e. Red\xe9marrez le serveur Kronosys pour continuer. L’interface reste verrouill\xe9e jusqu’alors.",dataEnvironmentSwitchLockBackdropAriaLocked:"Application verrouill\xe9e : red\xe9marrez le serveur Kronosys pour appliquer le coffre",dataEnvironmentQaSeedTitle:"Configurer le coffre QA",dataEnvironmentQaSeedMessage:"C’est votre premi\xe8re bascule vers le coffre QA. Choisissez comment l’initialiser :\n\n• Copier la production — duplique vos sessions et t\xe2ches actuelles dans QA (la production n’est pas modifi\xe9e).\n• Partir \xe0 z\xe9ro — coffre vide isol\xe9 pour tests et essais.",dataEnvironmentQaSeedCopyBtn:"Copier les donn\xe9es de production",dataEnvironmentQaSeedEmptyBtn:"Partir \xe0 z\xe9ro",dataEnvironmentQaSeedRequiredError:"Indiquez si vous copiez la production ou si vous partez d’un coffre QA vide.",dataEnvironmentQaSeedProductionMissingError:"Aucun fichier de donn\xe9es en production ; choisissez \xab Partir \xe0 z\xe9ro \xbb ou ajoutez d’abord des donn\xe9es en production.",appShellUtilityToolbarGroupAria:"Affichage et langue",globalPauseConfirmTitle:"Pause globale",globalPauseConfirmIntro:"La pause globale fige l’horloge murale de la session si elle tourne encore, met en pause chaque minuteur de t\xe2che qui ne l’est pas d\xe9j\xe0 et arr\xeate tout minuteur de sous-t\xe2che actif (en consolidant le temps \xe9coul\xe9). Le prochain clic sur ce contr\xf4le ne reprend que ce qui a \xe9t\xe9 fig\xe9 dans cette op\xe9ration.\n\nVoici ce qui sera concern\xe9 :",globalPauseConfirmSessionHeading:"Session",globalPauseConfirmSummaryHeading:"R\xe9sum\xe9",globalPauseConfirmSummaryStart:"D\xe9but",globalPauseConfirmSummaryEnd:"Fin",globalPauseConfirmSummaryEndOngoing:"En cours (pas encore de fin)",globalPauseConfirmSummaryWallDuration:"Dur\xe9e murale",globalPauseConfirmSummaryTasks:"T\xe2ches",globalPauseConfirmSummarySubtasks:"Sous-t\xe2ches",globalPauseConfirmSummaryMainTimer:"Minuteurs des t\xe2ches (hors sous-t\xe2ches)",globalPauseConfirmSummarySubtaskTimers:"Minuteurs des sous-t\xe2ches",globalPauseConfirmSummaryCodingSession:"Temps de codage (session)",globalPauseConfirmSummaryActiveSession:"Temps actif (session)",globalPauseConfirmSummaryTaskTimersTotal:"Total enregistr\xe9 (minuteurs t\xe2ches)",globalPauseConfirmSummaryUnknownInstant:"—",globalPauseConfirmSessionWallWillPause:"L’horloge murale de cette session sera mise en pause.",globalPauseConfirmSessionWallAlreadyPaused:"L’horloge murale est d\xe9j\xe0 en pause ; elle demeure fig\xe9e.",globalPauseConfirmTasksHeading:"T\xe2ches et sous-t\xe2ches",globalPauseConfirmNoTaskEffects:"Aucun minuteur de t\xe2che ou de sous-t\xe2che \xe0 figer dans l’\xe9tat actuel.",globalPauseConfirmEffectMainTimer:"Le minuteur principal de la t\xe2che sera mis en pause.",globalPauseConfirmEffectSubtaskStop:"Arr\xeat du minuteur de sous-t\xe2che \xab {title} \xbb (temps enregistr\xe9).",globalPauseConfirmConfirmBtn:"Mettre en pause",appShellLiveDrawerAria:"Activit\xe9 de la session en cours",appShellLiveDrawerTitle:"En cours",appShellLiveDrawerOpenDashboard:"Ouvrir le tableau de bord",appShellLiveDrawerSessionPaused:"Session en pause",appShellLiveDrawerWallClock:"Temps mural",appShellLiveDrawerTasksHeading:"Minuteurs",appShellLiveDrawerKronoFocusRunning:"En marche",appShellLiveDrawerKronoFocusPaused:"En pause",appShellLiveDrawerKronoFocusPhaseWork:"Travail",appShellLiveDrawerSubtaskTracking:"Sous-t\xe2che",appShellLiveDrawerExpand:"D\xe9ployer le panneau",appShellLiveDrawerCollapse:"Replier le panneau",appShellLiveDrawerNoRunningTasks:"Aucune t\xe2che au minuteur.",dashboardSideDrawerSessionsAria:"Panneau Sessions",dashboardSideDrawerTagsAria:"Panneau \xc9tiquettes et projets",dashboardTaskLauncherDrawerAria:"Lanceur de saisie de t\xe2che",dashboardTaskLauncherDrawerExpand:"D\xe9ployer le lanceur",dashboardTaskLauncherDrawerCollapse:"Replier le lanceur",brandTagline:"La relativit\xe9 du temps productif",appVersionAriaLabel:"Version du paquet du tableau de bord Kronosys : {version}.",dialogOkBtn:"OK",dialogCancelBtn:"Annuler",dialogConfirmBtn:"Confirmer",pageRefreshTitle:"Rafra\xeechir les donn\xe9es",pageRefreshAriaLabel:"Actualiser les donn\xe9es de cette page sans recharger tout le navigateur",pageRefreshProgressLabel:"Synchronisation avec le serveur Kronosys…",pageRefreshDoneToast:"Donn\xe9es recharg\xe9es depuis le serveur Kronosys",pageRefreshFailedToast:"Impossible de recharger les donn\xe9es. V\xe9rifiez que le serveur Kronosys tourne et r\xe9essayez."};function f(a){return"fr"===a?e:d}function g(a,b,c){return"fr"===c?a>1?b.tasksInSessionPlural:b.tasksInSessionSingular:1===a?b.tasksInSessionSingular:b.tasksInSessionPlural}},62576:(a,b,c)=>{"use strict";c.d(b,{KronosysPackageVersionProvider:()=>g,a:()=>h});var d=c(48249),e=c(67484);let f=(0,e.createContext)("0.0.0");function g({version:a,children:b}){return(0,d.jsx)(f.Provider,{value:a,children:b})}function h(){return(0,e.useContext)(f)}},65126:(a,b,c)=>{Promise.resolve().then(c.t.bind(c,81921,23))},65529:(a,b,c)=>{"use strict";c.d(b,{M:()=>f});let d={pageTitle:"User stories — \xe9tat d’impl\xe9mentation",pageSubtitle:"Liste exhaustive des intentions utilisateur\xb7rice\xb7s : chaque ligne indique si la capacit\xe9 est livr\xe9e (✓) ou absente / hors p\xe9rim\xe8tre (✗). Les cases \xe0 droite servent \xe0 cocher une ligne \xab revue \xbb sur cet appareil — le d\xe9tail technique long reste dans le d\xe9p\xf4t.",statusKeyLine:"✓ vert = impl\xe9ment\xe9 dans le produit \xb7 ✗ rouge = non livr\xe9 ou volontairement exclu.",lastUpdated:"Derni\xe8re mise \xe0 jour : 2026-05-19 (v1.0.0-beta.27)",repositoryDocLabel:"Documents d\xe9p\xf4t : docs/README.md (index), docs/IMPLEMENTATION_DETAILS.md",storyGroupsHeading:"Inventaire des user stories",implementationColumnLabel:"Impl\xe9mentation",storyColumnLabel:"User story",integrationColumnLabel:"Int\xe9gration",e2eColumnLabel:"E2E",openChangelogAria:"Ouvrir le changelog usager",openChangelogTooltip:"Ouvrir le changelog",storyDetailsToggleExpand:"Afficher pr\xe9cisions et exemple",storyDetailsToggleCollapse:"Masquer pr\xe9cisions et exemple",storyDetailExampleLabel:"Exemple :",storyExpandHintLine:"Certaines lignes ont un chevron : ouvrez-les pour une pr\xe9cision et un exemple en police r\xe9duite.",storyDiscardedBadge:"\xc9cart\xe9",storyDiscardedLegendLine:"Les lignes marqu\xe9es \xab \xc9cart\xe9 \xbb documentent une intention volontairement abandonn\xe9e ; elles restent dans la liste pour \xe9viter qu’on rouvre le m\xeame d\xe9bat par inadvertance.",storyGroups:[{id:"us-shell",title:"Coque, navigation, confort",lead:"Barre d’outils commune, pages principales, th\xe8me et langue.",stories:[{implemented:!0,text:"Naviguer entre tableau de bord, guide, rapports, param\xe8tres et cette page depuis les ic\xf4nes du haut.",detail:"Les destinations couvrent le tableau de bord, les rapports (graphiques), les param\xe8tres, le guide in-app, cette page d’impl\xe9mentation, les journaux d’actions, les licences et le changelog usager ; les ic\xf4nes sont regroup\xe9es dans la barre d’outils.",example:"Sur le tableau de bord, cliquer l’ic\xf4ne livre ouvre /guide tout en conservant le param\xe8tre de session (?session=) lorsqu’il est pr\xe9sent."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Consulter le journal des actions enregistr\xe9es c\xf4t\xe9 serveur (type, succ\xe8s, date, session).",detail:"**1.0.0-beta.26** — `server/userActionLog.ts` ; journalisation depuis `app/api/action/route.ts` ; `GET /api/action-logs` ; page `/logs` ; purge `clearUserActionLogs`."},{implemented:!0,text:"Voir une horloge murale continue dans la barre d’outils (fuseau et format 12/24 h des param\xe8tres tableau de bord web)."},{implemented:!0,text:"Pour une livraison donn\xe9e (p. ex. 1.0.0-beta.27), valider le comportement en croisant la section correspondante du **CHANGELOG**, les r\xe9cits marqu\xe9s livr\xe9s sur cette page et `docs/IMPLEMENTATION_DETAILS.md`, puis cocher au besoin **int\xe9gration** / **E2E**.",detail:"**1.0.0-beta.27** — index `docs/README.md` ; API et cartographie dans `docs/IMPLEMENTATION_DETAILS.md` ; JSDoc sur le noyau serveur et les routes `app/api/*`."},{implemented:!0,text:"Ouvrir la page Licences depuis l’ic\xf4ne document lorsque je suis d\xe9j\xe0 sur Licences."},{implemented:!0,text:"Basculer entre th\xe8me clair et sombre pour le confort visuel."},{implemented:!0,text:"Actualiser l’\xe9tat serveur sans recharger toute l’application."},{implemented:!0,text:"Choisir la langue d’interface (FR / EN) avec pr\xe9f\xe9rence pouvant \xeatre m\xe9moris\xe9e."},{implemented:!0,text:"Conserver le param\xe8tre de session du tableau de bord (?session=) quand je passe d’une route \xe0 l’autre."}]},{id:"us-sessions",title:"Sessions — cadre, horloge murale, pause, fin",stories:[{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Cr\xe9er une nouvelle session maintenant (lancement imm\xe9diat) et la voir appara\xeetre dans la liste des sessions.",detail:"La modale \xab Nouvelle session \xbb propose le timing \xab Maintenant \xbb ; apr\xe8s confirmation, la ligne appara\xeet dans la colonne Sessions avec l’\xe9tat live.",example:"Nouvelle session → \xab D\xe9marrer la session \xbb : une ligne \xab Live \xbb remonte en t\xeate de liste avec l’heure de d\xe9but."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Cr\xe9er une session pass\xe9e en saisissant le d\xe9but et la fin (heure locale), puis la voir appara\xeetre dans la liste des sessions.",detail:"Le mode \xab Dans le pass\xe9 \xbb impose d\xe9but et fin en heure locale ; l’intervalle ferm\xe9 est historis\xe9 sans n\xe9cessairement arr\xeater une session d\xe9j\xe0 ouverte.",example:"Hier 14:00–16:00 : une ligne termin\xe9e s’affiche avec ces bornes pendant qu’une autre session peut rester active."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Cr\xe9er une session sans limite optionnelle (ni dur\xe9e max, ni fen\xeatre calendrier, ni jours/plage horaire).",detail:"La port\xe9e \xab Aucune limite \xbb \xe9vite tout plafond mural, toute fen\xeatre calendaire et tout gabarit hebdomadaire pour cette session.",example:"Laisser \xab Aucune limite \xbb puis d\xe9marrer : seuls des rappels ult\xe9rieurs (collecteur / banni\xe8res) peuvent signaler un d\xe9rapage."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Encadrer une session par une dur\xe9e maximale d’horloge murale (rappel de cadre).",detail:"La dur\xe9e maximale s’exprime en heures de mur accumul\xe9 ; l’interface peut signaler le d\xe9passement ou le voisinage du seuil selon les param\xe8tres.",example:"4 h max : au-del\xe0, la dur\xe9e affich\xe9e peut passer en alerte visuelle (couleur ou clignotement lent)."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"D\xe9finir une fen\xeatre calendrier (dates de d\xe9but et de fin) pour une session.",detail:"Les dates \xab Du \xbb et \xab Au \xbb sont inclusives dans le fuseau / affichage local du tableau de bord ; elles encadrent la session pour les rappels.",example:"Du 3 au 10 du mois pour une s\xe9rie de s\xe9ances dans une m\xeame fen\xeatre contractuelle."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"D\xe9finir une semaine avec jours choisis et plage horaire.",detail:"On coche les jours actifs et, au besoin, une fen\xeatre horaire quotidienne ; les fen\xeatres overnight (ex. 22:00–06:00) sont prises en charge.",example:"Mar/Jeu + 18:30–21:00 pour des cr\xe9neaux fixes apr\xe8s la journ\xe9e bureau."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Utiliser les raccourcis \xab Aujourd’hui \xbb / \xab Maintenant \xbb dans les s\xe9lecteurs de dates et heures.",detail:"Les boutons posent la date du jour ou l’instant courant dans les champs de la modale sans saisie compl\xe8te.",example:"\xab Aujourd’hui \xbb sur une date \xab Du \xbb ; \xab Maintenant \xbb comme fin d’une session pass\xe9e qui vient de se terminer."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Voir la dur\xe9e de session suivre une horloge murale (temps r\xe9el) tant que la session est vivante et non en pause session.",detail:"La carte session affiche une dur\xe9e murale qui avance tant que la session n’est ni termin\xe9e ni en pause session (pause murale).",example:"Sans pause session, la ligne \xab Dur\xe9e \xbb suit la seconde ; \xab Pause session \xbb fige l’affichage jusqu’\xe0 reprise."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Mettre la session en pause : le mur cesse de s’accumuler sans confondre avec la pause d’une t\xe2che.",detail:"La pause session agit sur le mur collecteur ; le serveur peut aussi figer les minuteurs de t\xe2ches et sous-t\xe2ches actifs via un instantan\xe9 `sessionPauseContext` (reprise cibl\xe9e). La pause d’une t\xe2che seule reste sur la carte et n’est pas synonyme de pause globale.",example:"Pause session → bandeau \xab Session en pause \xbb ; une t\xe2che peut encore avoir \xe9t\xe9 laiss\xe9e en pause manuelle avant la pause session."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"D\xe9clencher une pause globale avec une modale de confirmation qui r\xe9sume effets, dur\xe9es et p\xe9rim\xe8tre.",detail:"La pause globale aligne la session live, les minuteurs de t\xe2ches et les sous-t\xe2ches concern\xe9es ; la modale affiche un r\xe9sum\xe9 (mur, temps enregistr\xe9s, volumes) avant d’appliquer ou d’annuler.",example:"Barre d’outils → contr\xf4le \xab Pause session, t\xe2ches et sous-t\xe2ches dans ce contexte \xbb → lecture du r\xe9sum\xe9 → \xab Pause maintenant \xbb ou retour en arri\xe8re."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Quand la session live est en pause (murale ou pause globale), reconna\xeetre l’\xe9tat sur la carte Session en cours (pastille), voir un rappel central sur fond voil\xe9 tout en gardant la barre du haut utilisable, et rep\xe9rer le bouton de reprise de pause globale mis en \xe9vidence lorsque la pause globale est active.",detail:"Serveur : `setPaused` enregistre `sessionPauseContext` pour les minuteurs actifs et ne restaure \xe0 la reprise que ce gel ; une entr\xe9e en pause globale efface tout `sessionPauseContext` r\xe9siduel. UI : pastilles \xab En pause \xbb / \xab Pause globale \xbb (`SelectedSessionSidebarBlock.tsx`), overlay plein \xe9cran `DashboardPauseBackdrop` sous l’en-t\xeate (`z-40` vs `z-50`), anneau ambre sur le contr\xf4le pause globale lorsqu’il affiche lecture (`AppShellRouteNav.tsx`).",example:"Apr\xe8s pause globale : pastille \xab Pause globale \xbb, voile \xab Pause globale active \xbb, bouton lecture cercl\xe9 dans la barre d’outils."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Terminer une session avec une raison de cl\xf4ture facultative (dans les temps, avance, d\xe9passement, autre + note).",detail:"La modale de fin propose cat\xe9gories facultatives et une note libre ; elles sont attach\xe9es \xe0 l’instantan\xe9 d’historique avec l’heure de fin courante.",example:"\xab Fin anticip\xe9e \xbb + \xab livraison report\xe9e \xbb puis \xab Terminer la session \xbb depuis la barre lat\xe9rale ou la liste."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Ajouter une note libre \xe0 une session et la revoir dans la barre lat\xe9rale de session.",detail:"Le champ \xab Note de session \xbb se trouve dans la carte session (colonne Sessions). La valeur est envoy\xe9e au serveur lorsque le champ perd le focus et reste visible apr\xe8s rechargement.",example:"Saisir \xab Point revue client — pr\xe9parer d\xe9mo \xbb avant une r\xe9union pour retrouver le contexte dans la m\xeame carte."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Voir un aper\xe7u de note de session (ic\xf4ne + extrait) dans la liste des sessions et dans la liste des archives.",detail:"Quand une note existe, la liste affiche une ic\xf4ne et un extrait tronqu\xe9 \xe0 c\xf4t\xe9 du titre de session ; m\xeame logique pour les entr\xe9es archiv\xe9es pertinentes.",example:"Une ligne montre \xab …compte-rendu… \xbb sous le nom lorsque la note contient ce texte."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Voir la session live mise en \xe9vidence lorsque l’heure de d\xe9but officielle est encore dans le futur (cercle d’\xe9tat et fond distincts dans la liste).",detail:"Tant que l’horloge r\xe9elle n’a pas atteint le d\xe9but officiel enregistr\xe9, la ligne live garde un style \xab pas encore d\xe9marr\xe9e \xbb (point et fond diff\xe9rents).",example:"Session \xe9tiquet\xe9e pour 18:00 alors qu’il est 14:00 : la ligne reste visuellement distincte jusqu’\xe0 18:00."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Programmer une heure de fin sur une session live : la session se termine automatiquement \xe0 l’\xe9ch\xe9ance (instantan\xe9 en historique).",detail:"Une \xe9ch\xe9ance de fin session peut \xeatre d\xe9finie ; au passage de l’instant programm\xe9, la session est cl\xf4tur\xe9e : le mur est consolid\xe9 jusqu’\xe0 cette heure, les t\xe2ches ouvertes sont fig\xe9es comme apr\xe8s une fin de session en mode conserver, sans modale de cl\xf4ture.",example:"Fin \xe0 17:00 : sans clic suppl\xe9mentaire, la session live devient une ligne d’historique \xe0 17:00 si elle est encore ouverte."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"\xc0 la fermeture d’une session avec t\xe2ches encore ouvertes, choisir de les terminer ou de les transposer vers une nouvelle session en pause.",detail:"La modale de fin liste les t\xe2ches non termin\xe9es et propose de les laisser dans l’instantan\xe9 (choix par d\xe9faut, \xe9quivalent \xab conserver \xbb), de les marquer termin\xe9es ou de les d\xe9placer vers une nouvelle session cr\xe9\xe9e en pause. \xc0 distinguer : une fin automatique \xe0 l’heure planifi\xe9e (`scheduledEndAt`) ne passe pas par cette modale ; c\xf4t\xe9 donn\xe9es, le comportement correspond \xe0 conserver les t\xe2ches ouvertes dans l’instantan\xe9 (minuteurs fig\xe9s), comme le premier choix de la modale. Un r\xe9glage produit pour imposer un autre mode par d\xe9faut \xe0 l’\xe9ch\xe9ance n’est pas livr\xe9 dans cette version.",example:"\xab Transposer vers une nouvelle session en pause \xbb pour reporter un lot de correctifs sans tout fermer au m\xeame titre."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Reprendre une session en pause depuis le bandeau ; reprendre une t\xe2che relance aussi l’accumulation du mur.",detail:"Le bandeau \xab Session en pause \xbb offre la reprise ; lorsqu’une t\xe2che repasse en suivi actif selon les r\xe8gles du dashboard, le mur peut \xe0 nouveau s’accumuler.",example:"Reprendre depuis le bandeau puis lancer une t\xe2che : la dur\xe9e murale augmente \xe0 nouveau."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Configurer un gabarit de nom de session initial (codes date/heure, %UUID, fuseau align\xe9 sur le tableau de bord).",detail:"Sous Param\xe8tres → tableau de bord, un mod\xe8le de nom peut r\xe9f\xe9rencer la date, l’heure, un UUID court ou le fuseau utilis\xe9 pour l’affichage.",example:"\xab Session %Y-%m-%d \xbb produit \xab Session 2026-05-08 \xbb \xe0 chaque cr\xe9ation."},{discarded:!0,implemented:!1,text:"Disposer d’une seule action \xab pause \xbb identique qui applique le m\xeame effet au mur de session et \xe0 tous les minuteurs comme une primitive unique.",detail:"D\xe9cision : \xe9cart\xe9e. La pause globale couvre d\xe9j\xe0 le gel coordonn\xe9 du mur et des minuteurs du contexte affich\xe9 ; la pause minuteur par t\xe2che reste un r\xe9glage fin volontairement s\xe9par\xe9.",example:"Ne pas fusionner en un seul bouton universel : conserver la pause globale (barre d’outils) et les pauses cibl\xe9es selon l’intention."},{discarded:!0,implemented:!1,text:"Obtenir la dur\xe9e murale de session comme somme automatique des dur\xe9es enregistr\xe9es des t\xe2ches.",detail:"D\xe9cision : \xe9cart\xe9e. Le mur suit des segments collecteur ; les totaux t\xe2che sont agr\xe9g\xe9s \xe0 part dans les m\xe9triques et rapports.",example:"Comparer carte session et colonne T\xe2ches : les deux lectures peuvent diverger — c’est attendu."}]},{id:"us-tasks",title:"T\xe2ches, \xe9tiquettes, projets, minuteurs",stories:[{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Cr\xe9er une t\xe2che avec titre et utiliser # pour \xe9tiquettes, @ pour projets productifs et ! pour projets personnels, avec aide \xe0 la saisie.",detail:"Le champ \xab sur quoi travaillez-vous \xbb accepte dans le libell\xe9 des jetons #\xe9tiquette, @projet (travail) et !projet (personnel) ; ils sont interpr\xe9t\xe9s au lancement (`startTask`), alimentent les listes d’\xe9tiquettes, `knownProjects` / `knownPersonalProjects`, et s’affichent sur la carte t\xe2che. Depuis **1.0.0-beta.21**, le **`!`** peut \xeatre **coll\xe9** au mot pr\xe9c\xe9dent (sans espace), comme certaines formes de **`#`** — ex. `Courrier!perso#dentiste` ; le **`@`** reste en g\xe9n\xe9ral apr\xe8s **espace** ou en **d\xe9but** de segment pour limiter les faux positifs sur les courriels. Depuis **1.0.0-beta.26**, une **liste d\xe9roulante** (`lib/taskEntryTokenSuggest.ts`, `TaskEntryInputWithTokenSuggest`) propose les jetons **les plus utilis\xe9s** puis **les plus r\xe9cents** d\xe8s que `#`, `@` ou `!` est actif (y compris en \xe9dition de titre) ; les **mod\xe8les** (\xab Mod\xe8le : \xbb, `datalist`) restent en parall\xe8le.",example:"Taper \xab #bu \xbb : la liste propose `bugfix` si c’est l’\xe9tiquette la plus fr\xe9quente ; choisir puis `@mo` pour le projet `mobile` ; lancer le suivi — pastilles et listes connues se mettent \xe0 jour."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"D\xe9clarer un projet personnel avec le jeton `!` (temps de suivi distinct des projets `@`), y compris en t\xe2che pass\xe9e, au renommage c\xf4t\xe9 serveur et dans les mod\xe8les de t\xe2che.",detail:"`lib/taskParsing.ts` (`parseTaskWithAutoTags`, `buildStartTaskFromDraft`, `formatProjectDisplay`, jetons `!p#t`) ; persistance `personalProject` sur les t\xe2ches et `knownPersonalProjects` sur le payload ; `server/actionDispatch.ts` et `server/actionTaskSession.ts` (`startTask`, `addHistoricalTask`, `updateTask`, `saveTaskTemplate`, `renameProjectMetadata` avec `personalOnly` c\xf4t\xe9 API) ; UI : `TaskFocusPanel`, `TaskSessionLiveCard`, `SavedProjectPicker`, `taskFieldStyles` (pastilles rose). Tests unitaires : `lib/taskTemplateDraft.test.ts` (mod\xe8les `!`).",example:"\xab Lecture !perso \xbb en session live : la carte affiche le projet en rose ; enregistrer comme mod\xe8le conserve `!perso` dans Param\xe8tres → Mod\xe8les de t\xe2che."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Utiliser des \xe9tiquettes sous port\xe9e projet personnel au format `!projet#sous-\xe9tiquette` (\xe9quivalent de `@projet#code` pour le travail).",detail:"`TagPills`, `formatTagDisplayForTask` et le parsing scoped dans `lib/taskParsing.ts` propagent le contexte `personalProject` pour l’affichage. Le jeton **`!`** de port\xe9e peut \xeatre **coll\xe9** au mot pr\xe9c\xe9dent (**1.0.0-beta.21**, `findProjectTokens`).",example:"\xab Suivi !dentiste#urgent \xbb : l’\xe9tiquette scoped s’affiche avec le pr\xe9fixe `!`."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Sur la modale Gantt d’une t\xe2che, distinguer le temps productif (`@`) et le temps personnel (`!`) : barres de couleurs diff\xe9rentes et totaux s\xe9par\xe9s.",detail:"`lib/taskTimelineGantt.ts`, `components/dashboard/TaskTimelineGanttModal.tsx`, cha\xeenes `lib/dashboardCopy.ts` (l\xe9gende et r\xe9sum\xe9s productif / personnel)."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"D\xe9marrer, mettre en pause et terminer le minuteur d’une t\xe2che ind\xe9pendamment du mur de session.",detail:"Le cycle du minuteur sur une t\xe2che (d\xe9marrage, pause volontaire sur la ligne, fin) est distinct du temps mural : la pause ou la reprise du mur de session (`setPaused`) ne se confond pas avec la pause du minuteur d’une t\xe2che (`setTaskTimerPaused` / reprise) ; les segments et contextes c\xf4t\xe9 serveur gardent cette s\xe9paration. Un sc\xe9nario Playwright clique sur la pause depuis la carte et v\xe9rifie le passage en \xab Reprendre \xbb (`e2e/task-lifecycle.spec.ts`).",example:"Mettre une t\xe2che en pause depuis sa carte puis reprendre uniquement la session : le minuteur de cette t\xe2che reste en pause jusqu’\xe0 une reprise explicite sur la ligne. \xab Terminer \xbb depuis la carte enregistre la fin du suivi pour cette t\xe2che."},{implemented:!0,text:"Lorsqu’un autre minuteur tourne, choisir pause, fin ou parall\xe9lisme et m\xe9moriser le choix pour les prochains lancements."},{implemented:!0,text:"Ajouter des sous-t\xe2ches, les cocher et les r\xe9ordonner par glisser-d\xe9poser."},{implemented:!0,text:"Enregistrer un mod\xe8le de t\xe2che depuis une t\xe2che en cours, en pause ou termin\xe9e, le g\xe9rer dans Param\xe8tres, et le retrouver (saisie avec debounce, suggestions \xab Mod\xe8le : \xbb, palette Ctrl+K), y compris avec projet personnel `!`.",detail:"`saveTaskTemplate` enregistre `personalProject` ; `lib/taskTemplateDraft.ts` (`formatTaskTemplateDraftLine`, `parseTaskTemplatesFromPayload`, `buildTaskTemplateSignature` avec segment travail/personnel) ; `SettingsTaskTemplatesSection.tsx`."},{implemented:!0,text:"Saisir une t\xe2che en direct ou la reporter dans le pass\xe9 avec d\xe9but et fin explicites."},{implemented:!0,text:"Ajouter une note libre sur une t\xe2che (directe ou pass\xe9e) pour documenter le contexte de l’activit\xe9."},{implemented:!0,text:"Afficher la note de t\xe2che avant la liste des sous-t\xe2ches pour garder le contexte visible pendant le d\xe9coupage."},{implemented:!0,text:"Corriger les bornes temporelles d’une t\xe2che en choisissant de conserver la dur\xe9e syst\xe8me, une dur\xe9e manuelle ou un recalcul depuis d\xe9but/fin."},{implemented:!0,text:"Voir les t\xe2ches dont le d\xe9but (non termin\xe9e) est encore dans le futur regroup\xe9es sous \xab Planifi\xe9es \xbb avec un style distinct, sans minuteur \xab en direct \xbb ni apparence \xab termin\xe9e barr\xe9e \xbb pr\xe9matur\xe9e ; pour une t\xe2che termin\xe9e, le m\xeame affichage \xab planifi\xe9 \xbb seulement si d\xe9but et fin sont encore tous deux dans le futur."},{implemented:!0,text:"\xc0 l’heure de d\xe9but planifi\xe9e (`startTime`), voir le minuteur s’activer automatiquement (sans temps compt\xe9 avant cet instant) ; \xe0 l’heure de fin planifi\xe9e (`scheduledEndAt`), la t\xe2che se termine automatiquement.",detail:"`deferFutureStartMainTimersInSession`, `activateDuePlannedTaskTimersInSession` (`server/actionTaskSession.ts`) ; `materializeRunningMainTimersInPayload` (`server/mainTimerHydrate.ts`). Tests : `server/mainTimerHydrate.test.ts`."},{implemented:!0,text:"Recevoir un toast global (toute route) lorsqu’une t\xe2che planifi\xe9e ou une session live atteint son heure de d\xe9but officielle — titre ou nom rappel\xe9 dans le message.",detail:"`PlannedScheduleActivationWatcher` (`components/dashboard/PlannedScheduleActivationWatcher.tsx`), `lib/plannedScheduleActivation.ts` ; cha\xeenes `plannedTaskScheduleActivatedToast` / `plannedSessionScheduleActivatedToast` (`lib/dashboardCopy.ts`). Tests : `lib/plannedScheduleActivation.test.ts`."},{implemented:!0,text:"Lorsqu’une t\xe2che sort de \xab Planifi\xe9es \xbb et devient en cours alors qu’un autre minuteur tournait d\xe9j\xe0, r\xe9soudre pause / terminer / parall\xe8le sur les t\xe2ches d\xe9j\xe0 au minuteur (m\xeame pr\xe9f\xe9rence m\xe9moris\xe9e que pour un lancement manuel) et faire pulser l’ic\xf4ne Tableau de bord hors route pour signaler l’attention."},{implemented:!0,text:"Programmer une heure de fin sur une t\xe2che en cours : la t\xe2che se termine automatiquement \xe0 l’\xe9ch\xe9ance (carte pass\xe9e en termin\xe9e \xe0 cet instant)."},{implemented:!0,text:"Lancer KronoFocus depuis une t\xe2che pour alterner travail et pauses sans perdre le lien avec la t\xe2che."},{discarded:!0,implemented:!1,text:"Traiter en rapport le temps mur de session et le temps t\xe2che comme une seule mesure interchangeable sans les distinguer.",detail:"D\xe9cision : \xe9cart\xe9e. Les rapports et agr\xe9gats distinguent volontairement le temps mur (segments collecteur) du temps t\xe2che ; les deux lectures compl\xe8tent une analyse honn\xeate.",example:"Comparer les totaux \xab mur \xbb et \xab t\xe2che \xbb dans les vues reporting — les \xe9carts sont informatifs, pas des erreurs \xe0 effacer."}]},{id:"us-kronofocus",title:"KronoFocus",stories:[{implemented:!0,text:"Activer l’affichage du minuteur KronoFocus dans l’en-t\xeate et/ou pr\xe8s des actions de t\xe2che selon les r\xe9glages."},{implemented:!0,text:"Encha\xeener phases de travail, pause et longue pause avec dur\xe9e au format HH:MM:SS."},{implemented:!0,text:"R\xe9utiliser une dur\xe9e depuis l’historique des dur\xe9es r\xe9centes."},{implemented:!0,text:"Attacher le focus \xe0 la t\xe2che active pour retrouver le lien dans l’historique."}]},{id:"us-search-shortcuts",title:"Recherche dans les donn\xe9es et raccourcis",stories:[{implemented:!0,text:"Ouvrir la palette de recherche Spotlight (Ctrl+K / ⌘K) et filtrer sessions, t\xe2ches, mod\xe8les de t\xe2che, \xe9tiquettes et projets ; choisir un mod\xe8le remplit le brouillon nouvelle t\xe2che."},{implemented:!0,text:"Filtrer les rubriques du guide utilisateur sur /guide avec le champ en t\xeate de page."},{implemented:!0,text:"Consulter et personnaliser les raccourcis clavier du tableau de bord depuis la modale d\xe9di\xe9e."}]},{id:"us-reporting",title:"Rapports et agr\xe9gats",stories:[{implemented:!0,text:"Choisir une plage de dates avec pr\xe9r\xe9glages jour / semaine / mois / ann\xe9e selon ce que l’interface expose."},{implemented:!0,text:"Restreindre les vues par une ou plusieurs \xe9tiquettes lorsque les donn\xe9es sont bas\xe9es sur les t\xe2ches."},{implemented:!0,text:"Lire r\xe9sum\xe9s, tableaux par jour, r\xe9partition par projet et par \xe9tiquette."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Sur la page Rapports, basculer la grille hebdomadaire par projet entre le registre travail (@) et le registre personnel (!) avec les m\xeames filtres de plage et d’\xe9tiquettes.",detail:"**1.0.0-beta.26** — `app/reporting/page.tsx` appelle `aggregateProjectTaskMinutesByDay` avec le scope `work` ou `personal` selon le s\xe9lecteur (`lib/reportingAggregate.ts`, `taskMatchesReportingProjectScope`, `taskIsReportingPersonalLedger`). La vue **Travail** (d\xe9faut) exclut le registre personnel ; la vue **Personnel** ne l’inclut qu’elles, avec libell\xe9s `!` via `formatProjectDisplay`. Une t\xe2che est **personnelle** pour l’agr\xe9gat si `personalProject` est vrai **ou** si le **titre** contient un jeton `!` reconnu (repli lorsque le drapeau manque sur d’anciennes donn\xe9es)."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Consulter par d\xe9faut les grilles par projet en temps productif (@) sans y m\xe9langer le temps des projets personnels (!).",detail:"Au chargement, le s\xe9lecteur est sur **Travail (@)** : m\xeame comportement qu’auparavant (scope `work` seul)."},{implemented:!0,text:"Voir un total de temps t\xe2che non concurrent (fusion des chevauchements) par jour pour comparaison."},{implemented:!0,text:"Configurer le jour de d\xe9but de semaine pour les vues calendaires coh\xe9rentes avec mon organisation."},{implemented:!0,text:"Relancer la visite guid\xe9e des rapports depuis les param\xe8tres."},{implemented:!0,text:"Lorsque l’environnement fournit une heure de d\xe9but pr\xe9vue, voir des indicateurs d’assiduit\xe9 / d’\xe9cart sur les sessions."},{implemented:!0,text:"Voir des signaux honn\xeates sur le travail encore non finalis\xe9 dans la plage s\xe9lectionn\xe9e."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Dans la liste sessions par jour (Rythme), chaque # sous une t\xe2che affiche la dur\xe9e enregistr\xe9e compl\xe8te de la t\xe2che (m\xeame r\xe8gle que les grilles d’allocation #), sans r\xe9partition \xe0 parts \xe9gales entre plusieurs \xe9tiquettes.",detail:"`buildTaskTagSlicesFullDuration` dans `lib/reportingAggregate.ts` ; affichage `app/reporting/page.tsx` (ventilation par #). Tests : `lib/reportingAggregate.test.ts`."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Les totaux et graphiques des rapports n’incluent que le temps r\xe9ellement enregistr\xe9 ; le cr\xe9neau planifi\xe9 (t\xe2che encore dans le futur) s’affiche \xe0 part sans alimenter les agr\xe9gats enregistr\xe9s.",detail:"`isTaskDisplayPlanned` (`lib/temporalDisplayPlanned.ts`) exclu de `aggregateReporting` ; `plannedMinutes` / libell\xe9 ambre dans la liste sessions/jour (`app/reporting/page.tsx`, `lib/reportingStrings.ts`). Tests : `lib/reportingAggregate.test.ts`."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Sur les calendriers hebdomadaires # et @, lire une ligne Total jour en bas de chaque semaine (somme par jour et total de semaine).",detail:"`sumWeekCalendarSlots` (`lib/reportingWeekLayout.ts`) ; pied de tableau `WeekCalendarDayTotalsFoot` dans `app/reporting/page.tsx`. Tests : `lib/reportingWeekLayout.test.ts`."}]},{id:"us-settings-data",title:"Param\xe8tres, export, int\xe9grations, danger",stories:[{implemented:!0,text:"Adapter le profil d’usage pour masquer des blocs peu pertinents (ex. lignes de code pour un profil non d\xe9veloppeur)."},{implemented:!0,text:"Configurer horaire de travail, sessions planifi\xe9es, collecte et tampons."},{implemented:!0,text:"G\xe9rer \xe9tiquettes avanc\xe9es et migration d’\xe9tiquettes entre port\xe9e globale et port\xe9e projet."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Renommer une \xe9tiquette ou un projet en inline (crayon, saisie directe, Entr\xe9e/\xc9chap), avec avertissement d’impact reporting et option \xab ne plus afficher \xbb.",detail:"Propagation serveur : `renameTagEverywhere` / `renameProjectEverywhere` — tests `server/actionTaskSession.test.ts` ; pas de parcours E2E Param\xe8tres d\xe9di\xe9."},{implemented:!1,text:"G\xe9rer et renommer depuis Param\xe8tres la liste des projets personnels connus (`knownPersonalProjects`, jetons `!`) de la m\xeame fa\xe7on que les projets `@`.",detail:"Le payload et les actions serveur maintiennent `knownPersonalProjects` et `renameProjectMetadata` avec `personalOnly` ; la section Projets / \xe9tiquettes avanc\xe9es n’expose pas encore d’inline d\xe9di\xe9 aux `!` au 2026-05-12."},{implemented:!0,text:"Activer des commutateurs de correction d’horodatage pour les bornes de t\xe2ches et de sessions."},{implemented:!0,text:"Brancher Git et MongoDB de fa\xe7on opt-in."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Obtenir une sauvegarde via l’API d’export et les options pr\xe9vues dans l’interface.",detail:"Tests : `test/integration/apiBackup.test.ts` (export sqlite + aller-retour restore)."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Effacer l’historique dans une zone dangereuse prot\xe9g\xe9e par confirmation explicite.",detail:"Tests : `server/actionDispatch.test.ts` (`clearHistory`) ; `test/integration/apiActionLogs.test.ts`."},{implemented:!0,text:"En d\xe9veloppement local (next dev), utiliser un coffre de donn\xe9es distinct et optionnellement partag\xe9 avec la prod."},{implemented:!0,text:"Activer deux coffres SQLite (production `v4` et QA `v4-qa`), basculer depuis la navigation (Prod / QA) et afficher un rep\xe8re visuel fort en mode QA.",detail:"**1.0.0-beta.26** — `lib/dataEnvironmentPreferenceFile.ts`, `lib/dataDir.ts`, `switchDataEnvironment` avec `qaSeed` (`copy_production` | `empty` si `v4-qa` absent), `dataEnvironmentRuntime` sur `/api/state`, `DataEnvironmentSwitchProvider`, `AppShellHeaderDataEnvironmentChip`, `DataEnvironmentChrome` ; red\xe9marrage serveur requis. D\xe9sactiv\xe9 si `TRACE_DATA_DIR` est d\xe9fini."},{implemented:!0,text:"Configurer le Web, l’API et la relance de visites guid\xe9es depuis les param\xe8tres."}]},{id:"us-architecture-quality",title:"Architecture, qualit\xe9, documentation",stories:[{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"B\xe9n\xe9ficier de mutations qui passent par un point d’entr\xe9e serveur unique pour les invariants.",detail:"Couverture indirecte : `server/actionDispatch.test.ts`, `test/integration/apiAction*.test.ts`."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Recharger la page et retrouver l’\xe9tat depuis le payload JSON persist\xe9.",detail:"Tests : `server/payloadStore.test.ts` (read/write SQLite)."},{implemented:!0,text:"Disposer de cha\xeenes d’interface en fran\xe7ais et en anglais pour les surfaces visibles."},{implemented:!0,text:"S’appuyer sur une suite de tests de bout en bout Playwright pour les parcours critiques."},{implemented:!0,text:"Consulter cette liste de user stories sur /implementation pour suivre le p\xe9rim\xe8tre livr\xe9."},{implemented:!0,text:"Retrouver l’index de la documentation d\xe9p\xf4t et les contrats API document\xe9s pour les int\xe9grateurs.",detail:"**1.0.0-beta.27** — `docs/README.md` ; README racine (API HTTP) ; JSDoc `server/*` et `app/api/*`."},{implemented:!1,text:"Remplacer le guide utilisateur (/guide) par cette page pour apprendre le produit."}]}]},e={pageTitle:"User stories — implementation status",pageSubtitle:"An exhaustive list of user intentions: each row shows whether the capability is shipped (✓) or missing / out of scope (✗). Checkboxes on the right mark a row as reviewed on this device — long technical detail stays in the repo doc.",statusKeyLine:"Green ✓ = implemented in the product \xb7 Red ✗ = not shipped or intentionally excluded.",lastUpdated:"Last updated: 2026-05-19 (v1.0.0-beta.27)",repositoryDocLabel:"Repository docs: docs/README.md (index), docs/IMPLEMENTATION_DETAILS.md",storyGroupsHeading:"User story inventory",implementationColumnLabel:"Implementation",storyColumnLabel:"User story",integrationColumnLabel:"Integration",e2eColumnLabel:"E2E",openChangelogAria:"Open user changelog",openChangelogTooltip:"Open changelog",storyDetailsToggleExpand:"Show details and example",storyDetailsToggleCollapse:"Hide details and example",storyDetailExampleLabel:"Example:",storyExpandHintLine:"Some rows include a chevron — expand for extra detail and a smaller-type example.",storyDiscardedBadge:"Discarded",storyDiscardedLegendLine:"Rows tagged “Discarded” record intents we deliberately closed; they stay listed so the same debate does not reopen by mistake.",storyGroups:[{id:"us-shell",title:"Chrome, navigation, comfort",lead:"Shared toolbar, main routes, theme and language.",stories:[{implemented:!0,text:"Move between dashboard, guide, reporting, settings, and this page from the top icons.",detail:"Targets include the dashboard, reporting charts, settings, the in-app guide, this implementation page, action logs, licenses, and the user changelog; icons sit in the shared header toolbar.",example:"From the dashboard, clicking the book icon opens /guide while keeping the session query (?session=) when it is set."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Review server-recorded action history (type, success, timestamp, session).",detail:"**1.0.0-beta.26** — `server/userActionLog.ts`; logging from `app/api/action/route.ts`; `GET /api/action-logs`; `/logs` page; `clearUserActionLogs` purge."},{implemented:!0,text:"See a live-updating wall clock in the header toolbar (time zone and 12/24 h from web dashboard settings)."},{implemented:!0,text:"For a given release (e.g. 1.0.0-beta.27), cross-check the matching **CHANGELOG** section, the shipped stories on this page and `docs/IMPLEMENTATION_DETAILS.md`, then tick **Integration** / **E2E** as appropriate.",detail:"**1.0.0-beta.27** — `docs/README.md` index; API and repo map in `docs/IMPLEMENTATION_DETAILS.md`; JSDoc on server core and `app/api/*` routes."},{implemented:!0,text:"Open the Licenses page from the document icon when I am already on Licenses."},{implemented:!0,text:"Switch between light and dark theme for visual comfort."},{implemented:!0,text:"Refresh server state without reloading the whole app."},{implemented:!0,text:"Pick UI language (FR / EN) with an optional persisted preference."},{implemented:!0,text:"Keep the dashboard session query (?session=) when navigating between routes."}]},{id:"us-sessions",title:"Sessions — scope, wall clock, pause, end",stories:[{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Create a new session now (immediate start) and see it in the session list.",detail:"The New session modal offers Start now; after confirm, the row appears in the Sessions column as live.",example:"New session → Start session: a Live row appears at the top with your start time."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Create a past session by entering start and end (local time), then see it in the session list.",detail:"In the past mode requires both bounds in browser-local time; the closed interval is saved to history without necessarily stopping an already running session.",example:"Yesterday 2:00–4:00 pm — a completed row shows those bounds while another session can stay active."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Create a session with no optional limits (no max duration, no calendar window, no weekdays/time window).",detail:"No limit skips max wall duration, calendar bounds, and weekday/time-window scope for that session.",example:"Leave No limit checked and start — only later heartbeats/banners may warn if work runs long."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Cap a session with a maximum wall-clock duration (nudge to reframe).",detail:"Max duration is expressed in hours of accumulated wall time; the UI can warn when you approach or exceed the cap depending on settings.",example:"4 h max — beyond that, duration styling may turn alert (color or slow blink)."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Set a calendar window (start and end dates) for a session.",detail:"From / To dates are inclusive in your dashboard display timezone; they frame expectations for reminders.",example:"March 3–10 for a fixed delivery sprint window."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Define a week pattern with selected weekdays and a time window.",detail:"Pick active weekdays and optionally a daily time slot; overnight windows (e.g. 10:00 pm–6:00 am) are supported.",example:"Tue/Thu + 6:30–9:00 pm for after-hours sessions."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Use “Today” / “Now” shortcuts in date and time pickers.",detail:"Buttons stamp today’s date or the current instant into modal fields without full typing.",example:"Today on a From date; Now as the end of a past session that just finished."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"See session duration follow wall-clock time while the session is live and not session-paused.",detail:"The session card shows wall duration advancing while the session is neither ended nor session-paused.",example:"Without session pause, Duration ticks each second; session pause freezes display until resume."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Pause the session so wall time stops accruing, distinct from pausing a task timer.",detail:"Session pause targets the collector wall; the server may also freeze active task and subtask timers using a `sessionPauseContext` snapshot (selective restore). Task-only pause stays on the card and is not the same as global pause.",example:"Session pause → Live session paused banner; a task you left manually paused before session pause stays consistent with the snapshot rules."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Start a global pause with a confirmation modal summarizing effects, durations, and scope.",detail:"Global pause aligns the live session with affected task and subtask timers; the modal summarizes wall time, recorded times, and counts before you confirm or cancel.",example:"Toolbar → “Pause session, tasks, and subtasks in this context” → read the summary → “Pause now” or dismiss."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"When the live session is paused (wall-clock or global pause), recognize it on the Active session card (chip), see a centered reminder on a dimmed overlay while the top bar stays usable, and spot the global resume control highlighted when global pause is active.",detail:"Server: `setPaused` stores `sessionPauseContext` for active timers and restores only that snapshot on resume; starting global pause clears any leftover `sessionPauseContext`. UI: “Paused” / “Global pause” chips (`SelectedSessionSidebarBlock.tsx`), full-screen `DashboardPauseBackdrop` under the header (`z-40` vs `z-50`), amber ring on the global pause control when it shows play (`AppShellRouteNav.tsx`).",example:"After global pause: “Global pause” chip, “Global pause is on” overlay, circled play button in the toolbar."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"End a session with an optional closure reason (on time, early, overrun, other + note).",detail:"The end-session modal offers optional categories and a free-text note; both are stored on the history snapshot with the current end time.",example:"Ended early + “release slipped” then End session from the sidebar or row controls."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Add a free-text note to a session and review it in the session sidebar.",detail:"The “Session note” field lives in the session card (Sessions column). It is saved on blur and survives a full page reload.",example:"Type “Client review checkpoint — prep demo” before a meeting to keep context in the same card."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"See a session-note preview (icon + excerpt) in the sessions list and in archived sessions.",detail:"When a note exists, the list shows an icon and truncated excerpt next to the session title; archived rows follow the same pattern where applicable.",example:"A row shows “…stand-up notes…” under the title when that text is in the note."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"See the live session row highlighted when the official start time is still in the future (status dot and distinct row styling in the list).",detail:"Until real time reaches the recorded official start, the live row keeps a “not yet started” look (dot + background).",example:"Official start at 6:00 pm while it is 2:00 pm — styling stays distinct until 6:00 pm."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Schedule an end time on a live session so it automatically ends when the deadline is reached (snapshot moves to history).",detail:"You can set a scheduled session end time; when real time reaches it, the session closes: wall time is finalized up to that instant, open tasks are frozen like ending with keep (no closure modal).",example:"End at 5:00 pm — without extra clicks, the live session becomes a history row at 5:00 pm if it was still open."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"When closing a session with open tasks, finish them or move them to a new paused session.",detail:"The end-session modal lists unfinished work and lets you keep it in the snapshot (default, same semantics as leaving tasks open), finish it with this session, or move it into a newly created paused session. Contrast: a scheduled automatic end (`scheduledEndAt`) does not show this modal; server-side it matches keep (open tasks stay in the snapshot with timers stopped). A user preference to pick a different default at scheduled end is not shipped in this version.",example:"Move open tasks to a new paused session to carry a bugfix batch without closing every card."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Resume a paused session from the banner; resuming a task also resumes wall accumulation.",detail:"The Live session paused banner offers resume; when a task returns to active tracking under dashboard rules, wall time can accrue again.",example:"Resume from the banner then start a task — wall duration increases again."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Configure an initial session name template (date/time codes, %UUID, timezone aligned with the dashboard).",detail:"Under Settings → web dashboard, a name pattern can include date, time, short UUID, or the display timezone token.",example:"“Session %Y-%m-%d” becomes “Session 2026-05-08” on each create."},{discarded:!0,implemented:!1,text:"Have a single “pause” action that applies the same effect to wall time and all task timers as one primitive.",detail:"Decision: discarded. Global pause already freezes the wall and timers for the displayed context together; per-task pause stays a separate fine control on purpose.",example:"We keep global pause (toolbar) and targeted pauses instead of one universal button."},{discarded:!0,implemented:!1,text:"Get wall session duration as the automatic sum of recorded task durations.",detail:"Decision: discarded. Wall time follows collector segments; task totals are aggregated separately in metrics and reporting.",example:"Compare the session card with tasks — both views may differ; that is expected."}]},{id:"us-tasks",title:"Tasks, tags, projects, timers",stories:[{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Create a task with a title and use # for tags, @ for work projects, and ! for personal projects with typing assistance.",detail:"The “what are you working on” field accepts #tag, @project (work), and !project (personal) tokens in the title; they are parsed on start (`startTask`), feed known tag lists plus `knownProjects` / `knownPersonalProjects`, and render on the task card. Since **1.0.0-beta.21**, **`!`** may be **glued** to the previous word (no space), like some **`#`** forms — e.g. `Errands!me#dentist`; **`@`** still expects **leading whitespace** or **string start** so mid-token emails are not parsed as projects. Since **1.0.0-beta.26**, a **dropdown** (`lib/taskEntryTokenSuggest.ts`, `TaskEntryInputWithTokenSuggest`) ranks **most-used** then **recent** `#` / `@` / `!` choices while the token is active (including title edit); **templates** (“Template:”, `datalist`) remain alongside.",example:"Enter “Auth fixes #bugfix @mobile” or “Rest #rest !me”, start tracking: the project chip is sky or rose depending on the token; known lists update for the next picks."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Declare a personal project with the `!` token (tracking separate from `@` work projects), including past tasks, server rename paths, and task templates.",detail:"`lib/taskParsing.ts` (`parseTaskWithAutoTags`, `buildStartTaskFromDraft`, `formatProjectDisplay`, `!p#t` tokens) ; `personalProject` on tasks and `knownPersonalProjects` on the payload ; `server/actionDispatch.ts` and `server/actionTaskSession.ts` (`startTask`, `addHistoricalTask`, `updateTask`, `saveTaskTemplate`, `renameProjectMetadata` with `personalOnly` on the API) ; UI: `TaskFocusPanel`, `TaskSessionLiveCard`, `SavedProjectPicker`, `taskFieldStyles` (rose chips). Unit tests: `lib/taskTemplateDraft.test.ts` (`!` templates).",example:"“Reading !me” while live: the card shows the rose project chip; saving as a template keeps `!me` under Settings → Task templates."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Use per-personal-project scoped tags in the `!project#subtag` form (same idea as `@project#code` for work).",detail:"`TagPills`, `formatTagDisplayForTask`, and scoped parsing in `lib/taskParsing.ts` carry `personalProject` for display. The scoped **`!`** token may be **glued** to the previous word (**1.0.0-beta.21**, `findProjectTokens`).",example:"“Follow-up !dentist#urgent”: scoped tag renders with the `!` prefix."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"On a task’s Gantt modal, separate productive (`@`) vs personal (`!`) time with distinct bar colors and split totals.",detail:"`lib/taskTimelineGantt.ts`, `components/dashboard/TaskTimelineGanttModal.tsx`, `lib/dashboardCopy.ts` strings (legend and summaries)."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Start, pause, and finish a task timer independently of session wall time.",detail:"Each task timer cycle (start, manual pause on the row, finish) is separate from wall time: pausing or resuming the session wall (`setPaused`) is not the same as pausing that task’s timer (`setTaskTimerPaused` / resume); server-side segments and pause contexts preserve the distinction. A Playwright scenario clicks pause on the card and checks the resume control (`e2e/task-lifecycle.spec.ts`).",example:"Pause a task from its card, then resume only the session: that task’s timer stays paused until you explicitly resume the row. “Finish” on the card ends tracking for that task."},{implemented:!0,text:"When another timer is running, choose pause, finish, or parallel run and save the default for next time."},{implemented:!0,text:"Add subtasks, check them off, and reorder by drag and drop."},{implemented:!0,text:"Save a task template from a running, paused, or completed task, manage it in Settings, and find it again (debounced input, “Template:” hints, Ctrl+K palette), including personal `!` projects.",detail:"`saveTaskTemplate` stores `personalProject` ; `lib/taskTemplateDraft.ts` (`formatTaskTemplateDraftLine`, `parseTaskTemplatesFromPayload`, `buildTaskTemplateSignature` with work/personal segment) ; `SettingsTaskTemplatesSection.tsx`."},{implemented:!0,text:"Log a task live or backfill it with explicit start and end times."},{implemented:!0,text:"Add a free-text note on a task (live or past entry) to keep activity context."},{implemented:!0,text:"Render task notes before the subtasks block so context stays visible while breaking down work."},{implemented:!0,text:"Edit task time bounds by keeping system duration, entering manual duration, or recalculating from bounds."},{implemented:!0,text:"See not-done tasks whose start is still in the future grouped under Planned with distinct styling, no live-running timer, and no crossed-out completed look too early; for completed tasks, the same Planned styling only when both start and end are still strictly in the future."},{implemented:!0,text:"At the scheduled start (`startTime`), see the timer turn on automatically (no time counted before that instant); at the scheduled end (`scheduledEndAt`), the task finishes automatically.",detail:"`deferFutureStartMainTimersInSession`, `activateDuePlannedTaskTimersInSession` (`server/actionTaskSession.ts`); `materializeRunningMainTimersInPayload` (`server/mainTimerHydrate.ts`). Tests: `server/mainTimerHydrate.test.ts`."},{implemented:!0,text:"Get a global toast (any route) when a planned task or live session reaches its official start time — task title or session name in the message.",detail:"`PlannedScheduleActivationWatcher` (`components/dashboard/PlannedScheduleActivationWatcher.tsx`), `lib/plannedScheduleActivation.ts`; copy `plannedTaskScheduleActivatedToast` / `plannedSessionScheduleActivatedToast` (`lib/dashboardCopy.ts`). Tests: `lib/plannedScheduleActivation.test.ts`."},{implemented:!0,text:"When a planned task becomes live tracking while another timer was already running, resolve pause/finish/parallel for the previously running tasks (same remembered preference as manual starts) and pulse the dashboard nav icon when attention is needed off-route."},{implemented:!0,text:"Schedule an end time on a running task so it automatically completes when the deadline is reached."},{implemented:!0,text:"Launch KronoFocus from a task to alternate work and breaks without losing task context."},{discarded:!0,implemented:!1,text:"Treat wall session time and task time as one interchangeable reporting measure without separating them.",detail:"Decision: discarded. Reporting and aggregates intentionally keep wall time (collector segments) separate from task time; both views support an honest read.",example:"Compare wall vs task totals in reporting — gaps are informative, not mistakes to merge away."}]},{id:"us-kronofocus",title:"KronoFocus",stories:[{implemented:!0,text:"Show the KronoFocus timer in the header and/or near task actions per settings."},{implemented:!0,text:"Run work, break, and long-break phases with duration in HH:MM:SS."},{implemented:!0,text:"Reuse a duration from recent duration history."},{implemented:!0,text:"Attach focus to the active task so history stays linked."}]},{id:"us-search-shortcuts",title:"Data search and shortcuts",stories:[{implemented:!0,text:"Open the Spotlight data-search palette (Ctrl+K / ⌘K) and filter sessions, tasks, task templates, tags, and projects; choosing a template fills the new-task draft."},{implemented:!0,text:"Filter user guide sections on /guide with the field at the top of the page."},{implemented:!0,text:"View and customize dashboard keyboard shortcuts in the dedicated modal."}]},{id:"us-reporting",title:"Reporting and aggregates",stories:[{implemented:!0,text:"Pick a date range with day / week / month / year presets as exposed by the UI."},{implemented:!0,text:"Restrict views by one or more tags when data is task-based."},{implemented:!0,text:"Read summaries, per-day tables, and breakdowns by project and tag."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"On the Reporting page, switch the weekly-by-project grid between the work (@) ledger and the personal (!) ledger with the same date-range and tag filters.",detail:"**1.0.0-beta.26** — `app/reporting/page.tsx` calls `aggregateProjectTaskMinutesByDay` with scope `work` or `personal` from the toggle (`lib/reportingAggregate.ts`, `taskMatchesReportingProjectScope`, `taskIsReportingPersonalLedger`). **Work** (default) excludes the personal ledger; **Personal** includes only it, with `!` labels via `formatProjectDisplay`. A task is **personal** for aggregates when `personalProject` is true **or** when the **title** contains a recognized `!` token (fallback when the flag is missing on older rows)."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"By default, per-project grids show productive (@) time without mixing in personal (!) minutes.",detail:"On first load the toggle is **Work (@)** — same behaviour as before (work scope only)."},{implemented:!0,text:"See non-overlapping task minutes per day for comparison with raw totals."},{implemented:!0,text:"Set the week start day for calendar views to match how I work."},{implemented:!0,text:"Relaunch the reporting tour from settings."},{implemented:!0,text:"When the host supplies a planned start time, see punctuality / variance indicators on sessions."},{implemented:!0,text:"See honest signals about work not yet finalized in the selected range."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"In the session-by-day list (Rhythm), each # under a task shows the task’s full recorded duration (same rule as tag allocation grids), not an even split across multiple tags.",detail:"`buildTaskTagSlicesFullDuration` in `lib/reportingAggregate.ts` ; UI in `app/reporting/page.tsx`. Tests: `lib/reportingAggregate.test.ts`."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Reporting totals and charts count only recorded time; a planned window for future tasks is shown separately and does not feed recorded aggregates.",detail:"`isTaskDisplayPlanned` (`lib/temporalDisplayPlanned.ts`) skipped in `aggregateReporting` ; `plannedMinutes` / amber copy in session-by-day (`app/reporting/page.tsx`, `lib/reportingStrings.ts`). Tests: `lib/reportingAggregate.test.ts`."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"On weekly # and @ calendars, read a Daily total footer row per week (per-day column sums and week total).",detail:"`sumWeekCalendarSlots` (`lib/reportingWeekLayout.ts`) ; `WeekCalendarDayTotalsFoot` in `app/reporting/page.tsx`. Tests: `lib/reportingWeekLayout.test.ts`."}]},{id:"us-settings-data",title:"Settings, export, integrations, danger zone",stories:[{implemented:!0,text:"Tune usage profile to hide blocks that are not relevant (e.g. lines of code for a non-dev profile)."},{implemented:!0,text:"Configure work schedule, planned sessions, collection, and buffers."},{implemented:!0,text:"Manage advanced tags and migrate tags between global and per-project scope."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Rename a tag or project inline (pencil, direct edit, Enter/Escape), with a reporting-impact warning and a “don’t show again” option.",detail:"Server propagation: `renameTagEverywhere` / `renameProjectEverywhere` — `server/actionTaskSession.test.ts`; no dedicated Settings E2E."},{implemented:!1,text:"Manage and rename known personal projects (`knownPersonalProjects`, `!` tokens) from Settings the same way as `@` projects.",detail:"Payload + server actions maintain `knownPersonalProjects` and `renameProjectMetadata` with `personalOnly`; the Settings projects/tags area does not yet expose dedicated `!` inline management as of 2026-05-12."},{implemented:!0,text:"Toggle correction switches for task and session time bounds."},{implemented:!0,text:"Opt in to Git and MongoDB integrations."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Download backups via the export API and UI options.",detail:"Tests: `test/integration/apiBackup.test.ts` (sqlite export + restore round-trip)."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Erase history in a danger zone gated by explicit confirmation.",detail:"Tests: `server/actionDispatch.test.ts` (`clearHistory`); `test/integration/apiActionLogs.test.ts`."},{implemented:!0,text:"In local dev (next dev), use a separate dataset vault and optionally share with prod."},{implemented:!0,text:"Enable two SQLite vaults (production `v4` and QA `v4-qa`), switch from the navigation bar (Prod / QA), and show a strong visual cue in QA mode.",detail:"**1.0.0-beta.26** — `lib/dataEnvironmentPreferenceFile.ts`, `lib/dataDir.ts`, `switchDataEnvironment` with `qaSeed` (`copy_production` | `empty` when `v4-qa` is missing), `dataEnvironmentRuntime` on `/api/state`, `DataEnvironmentSwitchProvider`, `AppShellHeaderDataEnvironmentChip`, `DataEnvironmentChrome`; server restart required. Disabled when `TRACE_DATA_DIR` is set."},{implemented:!0,text:"Configure web, API, and guided-tour relaunches from settings."}]},{id:"us-architecture-quality",title:"Architecture, quality, documentation",stories:[{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Rely on mutations going through a single server entry point for invariants.",detail:"Indirect coverage: `server/actionDispatch.test.ts`, `test/integration/apiAction*.test.ts`."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Reload the page and restore state from persisted JSON payload.",detail:"Tests: `server/payloadStore.test.ts` (SQLite read/write)."},{implemented:!0,text:"Use French and English UI strings on visible surfaces."},{implemented:!0,text:"Benefit from Playwright end-to-end tests on critical flows."},{implemented:!0,text:"Open this user-story list on /implementation to track shipped scope."},{implemented:!0,text:"Find the repository documentation index and documented API contracts for integrators.",detail:"**1.0.0-beta.27** — `docs/README.md`; root README (HTTP API); JSDoc on `server/*` and `app/api/*`."},{implemented:!1,text:"Replace the user guide (/guide) with this page for learning the product."}]}]};function f(a){return"fr"===a?d:e}},66430:(a,b,c)=>{"use strict";function d(a){return a.replace(/\[([^\]]+)\]\(\/[^)]+\)/g,"$1").replaceAll("**","")}function e(a){return"fr"===a?{pageTitle:"Guide d’utilisation",pageSubtitle:"Chaque rubrique m\xe9lange **l’intention** (\xe0 quoi \xe7a sert *pour vous*), des **\xe9tapes** quand c’est enchain\xe9 \xe0 l’\xe9cran, et des **options** concr\xe8tes — le tout dans le **m\xeame th\xe8me** clair ou sombre que l’appli.",defaultStepBlockTitle:"Proc\xe9dure (pas \xe0 pas dans l’interface)",defaultOptionsBlockTitle:"Options, modes et rappels",searchPlaceholder:"Filtrer les rubriques (sens, \xe9tapes, options, KronoFocus…)",searchAriaLabel:"Recherche dans le guide",searchNoResults:"Aucune rubrique ne correspond \xe0 votre recherche. Essayez un autre mot-cl\xe9 ou effacez le filtre.",tocHeading:"Sur cette page",tocNavAria:"Sommaire du guide d’utilisation",lastUpdated:"Derni\xe8re mise \xe0 jour : 3 juin 2026 (v1.0.0-beta.36)",helpLinksHeading:"Pages compl\xe9mentaires",helpLinksAria:"Liens vers l’impl\xe9mentation et les licences",helpImplementationLink:"User stories — impl\xe9mentation",helpLicensesLink:"Licences et logiciels tiers",sections:[{id:"ug-essence",title:"C’est quoi Kronosys — le sens, pas l’onglet",searchIndex:"but intention pourquoi aide b\xe9n\xe9fice productivit\xe9 focus temps m\xe9moire concentration \xe9quipe client reconstituer oubli rythme travail vie attention local donn\xe9es chez soi",paragraphs:["Kronosys, c’est un **compagnon** pour *temps* et *travail* : poser **ce** que vous faites, **combien** de temps, dans quel **sujet**, sans th\xe9\xe2tre administratif. **\xc0 quoi \xe7a sert ?** Moins d’amn\xe9sie sur *\xab j’y ai vraiment mis quoi, cette semaine ? \xbb*, plus de **cl\xf4ture** propre \xe0 la fin d’un bloc, un **r\xe9cit** (pour vous, une \xe9quipe, un client) quand il le faut.","**Pour qui** est-ce pens\xe9 ? Les journ\xe9es en **morceaux** (code, contenu, op\xe9rations, recherche…), les **contextes** qui s’entassent, ou le besoin d’**expliquer** sans tout refaire sur Excel. Kronosys reste *chez vous* c\xf4t\xe9 donn\xe9es; Git, miroir, grosse sauvegarde, ce sont des **c\xe2bles** que l’on ajoute *quand vous voulez*."],optionsTitle:"Trois \xab pi\xe8ces \xbb pour trois gestes",options:["**Tableau de bord** — l’*atelier* (sessions, t\xe2ches, minuteur, raccourcis **#\xe9tiquettes** / **@projets** travail / **!projets** personnels).","**Rapports** — la p\xe9riode en **trois vues** (allocation facturation, rythme, avanc\xe9) \xe0 partir de l’historique d\xe9j\xe0 enregistr\xe9.","**Param\xe8tres** — l’*arri\xe8re-boutique* (habitudes, raccordements, zone o\xf9 l’on *efface* l’histoire *avec prudence*). [Ouvrir Param\xe8tres](/settings#settings-usage-profile)."],stepsTitle:"Premier contact en cinq pas (sans tout ma\xeetriser le jour 1)",steps:["Ouvrez l’**accueil** (tableau de bord) : c’est ici que d\xe9marre l’**atelier**.","D\xe9clenchez **Nouvelle session** (ou laissez l’app en cr\xe9er une *la premi\xe8re fois* qu’une t\xe2che part).","D\xe9crivez un **coup de t\xe2che** (titre) ; un **#mot** = \xe9tiquette ; **@nom** = *projet* de travail ; **!nom** = *projet personnel* (le formulaire *devine* souvent l’un et l’autre). Ajoutez au besoin une **note libre** sur la t\xe2che et, c\xf4t\xe9 session, une **note de session**.","Appuyez sur **D\xe9marrer** (ou lancez le **KronoFocus** *\xe0 c\xf4t\xe9*) pour **tenir** un *cr\xe9neau*.","Quand la journ\xe9e le demande, ouvrez **Rapports** pour *voir* ce qui c’est *pass\xe9* dans la p\xe9riode — *sans* y passer la soir\xe9e en tableurs."]},{id:"ug-nav-theme",title:"Barre d’outils, th\xe8me et langue",searchIndex:"th\xe8me clair sombre mode violet zinc langue fr en ruban groupe navigation repli plusieurs rang\xe9es",paragraphs:["La **barre du haut** est *toujours* la m\xeame famille : m\xeames outils, m\xeame **ton** (zinc, accents **violet**), pour ne pas recharger le cerveau *\xe0 chaque page*. Les **raccourcis** de pages sont **regroup\xe9s** en **petits blocs** par **contexte** (zones principales, aide et documentation, outils de session), sur le mod\xe8le d’un **ruban** l\xe9ger. L’ic\xf4ne **roue** m\xe8ne \xe0 [Param\xe8tres](/settings#settings-usage-profile) (raccourci **Alt+Shift+S** depuis le tableau de bord).","Sur **\xe9cran \xe9troit** (petit portable, fen\xeatre r\xe9duite, **PWA** c\xf4t\xe9 tablette), la rang\xe9e se **replie** en **plusieurs lignes centr\xe9es** au lieu d’afficher une **barre de d\xe9filement horizontale** — les **blocs** (horloge, KronoFocus, navigation, utilitaires) restent **group\xe9s** et accessibles **sans glisser** lat\xe9ralement."],steps:["En **tableau de bord** : l’ic\xf4ne **Livre** m\xe8ne ici, puis **Rapports** (graphe) et **Param\xe8tres** (roue).","Sur **les autres pages** : revenez \xe0 l’**accueil** (ic\xf4ne **grille** du tableau de bord), puis m\xeames **Livre**, **Rapports**, **Param\xe8tres** ; l’ic\xf4ne **changelog** ouvre `/changelog` depuis la barre.","Depuis ce **guide**, les boutons **Impl\xe9mentation** et **Licences** (sous le titre) m\xe8nent \xe0 l’inventaire des user stories et aux mentions l\xe9gales — elles ne sont plus dans la barre d’ic\xf4nes.","Sur **Impl\xe9mentation**, les lignes pourvues d’un **chevron** d\xe9ploient une **pr\xe9cision** et un **exemple** (texte plus petit) sans allonger la liste principale.","Toujours en tableau de bord, un bouton **Gantt du jour** (grille) ouvre une frise globale avec les t\xe2ches de **toutes** les sessions pour la journ\xe9e en cours.","Le **bouton th\xe8me** bascule **clair / sombre** (le soir ou salle trop lumineuse).","Le bouton **actualiser** redemande l’**\xe9tat** au serveur (utile si quelqu’un/quelque chose a chang\xe9 dehors *sans* recharger toute l’**app**).","Ouvrez le **menu de langue** (FR / EN) ; la **pr\xe9f\xe9rence** peut se **m\xe9moriser** c\xf4t\xe9 moteur si c’est la configuration chez vous."],options:["**Livre** = ce **guide** ; **graphe** = **Rapports** ; **roue** = **Param\xe8tres** ; **grille** = **Gantt du jour** (tableau de bord) ; **changelog** = journal utilisateur. **Impl\xe9mentation** et **Licences** : boutons en haut de ce guide.","Changer de **th\xe8me** ne modifie **pas** le **fond** de vos enregistrements — seulement le **confort** visuel (m\xeame **d\xe9cor** d’\xe9cran d’une page \xe0 l’autre, pour ne pas se **perdre** entre les onglets)."]},{id:"ug-layout",title:"O\xf9 travailler, o\xf9 regarder, o\xf9 r\xe9gler — + juridique",searchIndex:"navigation tableaux bord rapports param\xe8tres licences horloge fuseau tiroir drawer focus colonnes xl",paragraphs:["Trois gestes, trois endroits : l’**atelier** (maintenant), les **Rapports** (retour sur une p\xe9riode), les **Param\xe8tres** (coulisses, effacements sensibles, branchements). Puis **Licences**, la page d’honn\xeatet\xe9 sur le code **open source** et les polices."],options:["**Tableau de bord** — \xe0 gauche la **file des sessions** ; au centre les **t\xe2ches** (minuteurs, d\xe9tail) ; \xe0 droite les raccourcis d’**\xe9tiquettes** et de **projets** (**@** travail, **!** personnel). Sur **grand \xe9cran** (xl+), les panneaux lat\xe9raux deviennent des **tiroirs repliables** **coll\xe9s au bord gauche ou droit de l’\xe9cran** (languette vers les t\xe2ches, bande repli\xe9e avec **ic\xf4ne** et titre vertical) ; le **lanceur de t\xe2che** est aussi un **tiroir repliable** (sans languette) ; la colonne **T\xe2ches** reste **centr\xe9e** (base **42 rem**, **+20 %** de largeur max par tiroir lat\xe9ral repli\xe9) ; l’\xe9tat ouvert / ferm\xe9 est **m\xe9moris\xe9** dans le navigateur ; la **liste des sessions** d\xe9file **dans le tiroir** (carte session s\xe9lectionn\xe9e fixe au-dessus quand elle s’y affiche). **Une seule ligne** d’en-t\xeate **T\xe2ches** regroupe le **total**, le **d\xe9compte** par statut (En cours, Planifi\xe9es, En pause, Compl\xe9t\xe9es, Non termin\xe9es en archive), l’indicateur **SUIVI**, l’aide **(?)** et le **chevron** d\xe9plier / replier (xl+) ; repli\xe9 : m\xeame ligne, formulaire masqu\xe9. **Mode focus** : bouton **agrandir** (ruban utilitaire), commande palette **Ctrl+K** / **⌘K**, raccourci **Alt+Shift+F** — masque l’en-t\xeate et les bandeaux pour ne garder que les **trois colonnes** ; quitter avec **\xc9chap** ou le bouton **r\xe9duire** en haut \xe0 droite.","**Rapports** — choisir une **plage de dates** et, si besoin, des **#\xe9tiquettes** ; puis les **onglets** (allocation facturation, rythme, avanc\xe9). Une **visite guid\xe9e** est propos\xe9e la premi\xe8re fois sur l’\xe9cran.","**Param\xe8tres** — profil, collecte, planification, \xe9tiquettes avanc\xe9es, **Git** ou miroir en **option** ; la **zone dangereuse** supprime l’historique (avec saisie de confirmation). [Sommaire des param\xe8tres](/settings#settings-usage-profile) \xb7 [zone de danger](/settings#settings-danger-zone). N’y entrez **que** quand vous le **d\xe9cidez**.","**Journaux d’actions** (`/logs`) — historique des **mutations** enregistr\xe9es c\xf4t\xe9 serveur (type, succ\xe8s, date, session) ; ic\xf4ne **liste** dans le bloc navigation principal.","**Licences** — textes MIT, logiciels tiers, polices ; accessible via le bouton **Licences** en haut de ce guide.","Une **horloge murale** (fuseau et format 12/24 h des param\xe8tres **Tableau de bord web**) tourne en permanence dans la **barre d’outils** de l’en-t\xeate ; le **KronoFocus** se place **juste \xe0 c\xf4t\xe9**, avant les ic\xf4nes de navigation — il reste **toujours** visible pour garder la barre stable. Si les **coffres production et QA** sont activ\xe9s, un commutateur **Prod / QA** pr\xe9c\xe8de ces ic\xf4nes : la bascule **rouvre imm\xe9diatement** le bon fichier SQLite (sans red\xe9marrer le serveur). En consultation d’**archive**, ses **boutons** restent **visibles** mais **d\xe9sactiv\xe9s** : ils refl\xe8tent toujours la **session live**. La **palette donn\xe9es** (Ctrl+K / ⌘K), le **Gantt du jour** et la **pause globale** sont **les m\xeames** sur **toutes** les pages (tableau de bord, rapports, param\xe8tres, journaux, guide, impl\xe9mentation, changelog, licences) ; hors tableau de bord, certaines actions **vous y ram\xe8nent** pour terminer (ex. ouvrir un r\xe9sultat de recherche)."]},{id:"ug-convention-end-vs-pause",title:"Convention : heure de fin et pause",searchIndex:"convention pause fin programm\xe9e \xe9ch\xe9ance terminaison cl\xf4ture minuteur pause globale diff\xe9r\xe9e mise en veille",paragraphs:["Dans Kronosys, une **heure de fin** que vous **programmez** sur une **t\xe2che** ou une **session** en cours d\xe9finit une **terminaison** \xe0 cet instant — ce n’est **pas** une pause **report\xe9e**, ni une mise en veille diff\xe9r\xe9e.","Pour **mettre en pause** le suivi (minuteur, murale, session), utilisez les **actions de pause** pr\xe9vues \xe0 cet effet ; elles sont **distinctes** de la notion d’**\xe9ch\xe9ance** ou de **fin programm\xe9e**."],bullets:["**Fin programm\xe9e** → la t\xe2che est **termin\xe9e** ou la session **cl\xf4tur\xe9e** \xe0 l’instant choisi.","**Pause** → action **explicite** (minuteur, session live en pause, pause globale, etc.)."]},{id:"ug-sessions-tasks",title:"Sessions, t\xe2ches, \xe9tiquettes et projets",searchIndex:"session live archiver terminer t\xe2che minuteur pause sous-t\xe2che historique liste r\xe9sum\xe9 planifi\xe9e pastille badge conflit navigation projet personnel !perso jeton coll\xe9 courriel rouvrir reopen dur\xe9e minimale minimum half-hour demi-heure fin future session pass\xe9e",paragraphs:["La **session** est le **sac** o\xf9 vient s’additionner le travail sur une p\xe9riode ; la **t\xe2che** est le fil conducteur du moment. **#mot** = th\xe8me ; **@nom** = projet **productif** ; **!nom** = projet **personnel** (suivi hors travail facturable, pastille souvent **rose**) — c’est de la **classification**, pas un examen d’orthographe. Le **`!`** (y compris **`!projet#sous-\xe9tiquette`**) peut \xeatre **coll\xe9** au mot pr\xe9c\xe9dent **sans espace** — ex. `Courrier!perso#dentiste` ; le **`@`** reste en principe **apr\xe8s un espace** ou en **d\xe9but** de segment pour limiter les faux positifs sur les courriels."],optionsTitle:"Nouvelle session — le cadre, au choix",options:["**D\xe9but** : **maintenant** (lancement imm\xe9diat) avec **fin planifi\xe9e optionnelle** d\xe8s la modale, ou **dans le pass\xe9** — saisie du **d\xe9but et de la fin** en heure locale du navigateur. Si la fin est encore **\xe0 venir**, une session **live** s’ouvre \xe0 partir de ce d\xe9but et se **cl\xf4ture automatiquement** \xe0 l’heure pr\xe9vue ; si la fin est **d\xe9j\xe0 pass\xe9e**, la plage close va dans l’**historique** (sans interrompre une session active) et l’\xe9cran bascule dessus pour **saisir des t\xe2ches**. Un lancement **imm\xe9diat** alors qu’une session est **d\xe9j\xe0 active** ouvre d’abord la **fin de session**.","**Port\xe9e minimale** : pas de bordage particulier — vous lancez et c’est le flux qui m\xe8ne.","**Dur\xe9e max (horloge murale)** : l’onglet s’y pr\xeate (rappel, pas alarme) quand on veut cadrer un gros **morceau** de journ\xe9e.","**Fen\xeatre calendrier** : dates de **d\xe9but** et de **fin** (engagement aupr\xe8s de vous-m\xeame ou d’un tiers).","**Semaine** : jours de la semaine + **plage horaire** (utile en rythme **fixe** — pas pour tout le monde, et c’est normal).","Dans les s\xe9lecteurs de dates/heures, les actions rapides **Aujourd’hui** et/ou **Maintenant** sont disponibles pour \xe9viter la saisie manuelle.","Les **t\xe2ches** se suivent en **direct** (minuteur) ou s’inscrivent **dans le pass\xe9** (d\xe9but, fin et **dur\xe9e du minuteur** en h/m/s — comme lors d’un ajustement) : honn\xeate quand on remplit **apr\xe8s coup** le soir, sans th\xe9\xe2tre."],stepsTitle:"D\xe8s que vous avez cliqu\xe9 \xab D\xe9marrer \xbb sur une t\xe2che (ordre usuel)",steps:["Taper un **titre** (champ pleine largeur sous la barre d’actions) ; saupoudrer d’un **#** (\xe9tiquette), d’un **@** (projet travail) et/ou d’un **!** (projet personnel) : une **liste d\xe9roulante** propose alors les choix **les plus utilis\xe9s** puis **les plus r\xe9cents** (filtrage au fil de la frappe, **↑** / **↓**, **Entr\xe9e** ou clic), y compris en **\xe9dition du titre** sur une carte.","Cliquer **D\xe9marrer** sur la t\xe2che — ou, si l’heure s’y pr\xeate, lancer d’**abord** le **KronoFocus** depuis cette t\xe2che (m\xeame bateau, rythme diff\xe9rent).","Si le minuteur d’**une** autre t\xe2che tourne d\xe9j\xe0 : l’appli offre **pause** sur l’ancienne, **terminer** l’ancienne, ou **tout** tenir en parall\xe8le (vous **pouvez** m\xe9moriser l’**option** pour les prochains lancements).","En **cours** : lister des **sous-t\xe2ches** ; les cocher, les reclasser au **glisser-d\xe9poser** ; **pause** / reprise en douceur.","**Terminer la session** quand le bloc a une fin (bouton d’en-t\xeate ou banni\xe8re) ; une **raison** de cl\xf4ture **facultative** (dans les temps, en avance, d\xe9passement, autre + note) : pour poser mots sur la **fin** du cycle — d’**abord** pour vous, pas pour un **audit** froid."],bullets:["Chaque **t\xe2che** peut porter une **note libre** : lien **Ajouter une note** sur la carte ou au lanceur (champ masqu\xe9 tant qu’elle est vide) ; une note **enregistr\xe9e** s’affiche en Markdown avant les **sous-t\xe2ches** (clic pour modifier). Le **titre** accepte du Markdown **inline** en lecture. Ic\xf4ne **(?)** : aide Markdown (exemples et aper\xe7u).","**Lanceur de t\xe2che** : comme les cartes — mode maintenant/pass\xe9, KronoFocus, aide et **pastilles** projet / `#\xe9tiquettes` **en haut \xe0 droite** ; en **mode pass\xe9**, un bouton ouvre une **modale** pour **d\xe9but**, **fin** et **dur\xe9e du minuteur** (r\xe9sum\xe9 visible dans le lanceur) ; **titre** avec bouton **D\xe9marrer / Ajouter** **en fin de ligne**, puis **note** en dessous ; suggestions **Mod\xe8le :** sur **toute la largeur** de la ligne titre. Sur **xl+**, tiroir repliable (encadr\xe9 comme les tiroirs lat\xe9raux) : **m\xeame ligne** que le titre colonne **T\xe2ches** (d\xe9compte, **SUIVI**, aide **(?)**, **chevron**) ; repli\xe9 : bandeau compact, formulaire masqu\xe9 ; sous xl, toujours d\xe9ploy\xe9.","Chaque **session** peut porter une **note de session** ; un aper\xe7u (ic\xf4ne + extrait) appara\xeet dans la liste des sessions et dans les archives.","Le bouton de **pause globale** est **inactif** (avec une infobulle) lorsque **rien ne tourne** : murale d\xe9j\xe0 fig\xe9e et aucun minuteur ; sinon il ouvre une **confirmation** avec un **r\xe9sum\xe9** : **d\xe9but** et **fin** (ou mention *en cours*), **dur\xe9e murale**, **temps de codage** et **temps actif** de session lorsque l’h\xf4te les fournit, d\xe9compte **t\xe2ches** / **sous-t\xe2ches**, **total enregistr\xe9** sur les minuteurs de t\xe2ches puis **r\xe9partition** minuteur principal vs sous-t\xe2ches, puis la liste des effets sur les minuteurs ; une fois valid\xe9e, il met en pause la session, les t\xe2ches et les sous-t\xe2ches en cours du contexte affich\xe9 ; le clic suivant **reprend uniquement** ce lot.","La **pause session** (contr\xf4le d’**en-t\xeate** lorsque la session est **live**) **fige aussi** les minuteurs **actifs** des **t\xe2ches** et **sous-t\xe2ches** ; **reprendre la session** ne rallume que ce qui avait \xe9t\xe9 gel\xe9 **par cette pause** — pas une t\xe2che d\xe9j\xe0 laiss\xe9e en pause **manuelle** avant. Reprendre une **t\xe2che** avant le bandeau retire cette entr\xe9e du **lot** concern\xe9 par une reprise session ult\xe9rieure.","Sans **`#` explicite**, une t\xe2che re\xe7oit l’\xe9tiquette r\xe9serv\xe9e **\xab d\xe9faut \xbb** ; d\xe8s qu’un **`#tag`** est ajout\xe9 (cr\xe9ation, \xe9dition du titre, mise \xe0 jour), **\xab d\xe9faut \xbb est retir\xe9e** automatiquement — option dans [T\xe2ches et \xe9tiquettes](/settings#settings-task-tags).","Sur les **pastilles** (carte t\xe2che, rapports, listes), seul le **nom** s’affiche — **sans** `#`, `@` ni `!` — la **couleur** distingue \xe9tiquette (**vert**), projet travail (**bleu ciel**) et projet personnel (**rose**) ; les **jetons** restent visibles \xe0 la **saisie**, dans les **suggestions** et le **marquage** rapide. Option [Param\xe8tres → Tableau de bord web](/settings#settings-web) **\xab Ne pas distinguer par la couleur seule \xbb** : pr\xe9fixes `#` / `@` / `!` et bordures distinctes en compl\xe9ment des couleurs.","\xc0 la **fermeture** d’une session avec des t\xe2ches ouvertes, vous pouvez les **terminer**, les **transposer** vers une **nouvelle session en pause**, ou les **laisser ouvertes** dans l’instantan\xe9 archiv\xe9 ; dans tous les cas, les **minuteurs** de cette session **cessent**.","Dans une **session live** ainsi en pause, un **bandeau** propose de **reprendre la session** ; le **lecture** sur une t\xe2che **reprend aussi** l’horloge murale (collecte).","Lorsque la session live est en **pause** (murale et minuteurs concern\xe9s, ou **pause globale**), le bloc **Session en cours** affiche une pastille **En pause** ou **Pause globale** ; un **voile** \xe0 l’\xe9cran centre un rappel, la **barre du haut** restant utilisable pour **reprendre**.","Dans le bloc timing **Session en cours**, une **barre de progression** sous **Fin** avance de l’heure de **d\xe9but** vers la **fin planifi\xe9e** lorsqu’elle est renseign\xe9e (alerte visuelle en fin de cr\xe9neau, comme sur les cartes t\xe2che). **Dur\xe9e totale planifi\xe9e** (cr\xe9neau d\xe9but → fin planifi\xe9e) et **Total planifi\xe9 (t\xe2ches)** n’apparaissent **que** lorsque la donn\xe9e existe ; sinon la ligne est **masqu\xe9e**. Sous **Dur\xe9e**, **Dur\xe9e restante** affiche le temps restant ; sinon **Ind\xe9termin\xe9e**. La liste Sessions reprend `planifi\xe9 X` sur la ligne live lorsqu’une fin planifi\xe9e est d\xe9finie.","M\xeame une **session pass\xe9e termin\xe9e** accepte encore une **entr\xe9e dans le pass\xe9** : s\xe9lectionnez-la ; le **d\xe9but** est arrondi \xe0 la demi-heure pr\xe9c\xe9dente, la **fin** est pr\xe9remplie (d\xe9but + **dur\xe9e minimale** dans [T\xe2ches et \xe9tiquettes](/settings#settings-task-tags)), ajustez la dur\xe9e du minuteur si besoin.","Dans [Param\xe8tres → Tableau de bord web](/settings#settings-default-session-name), un **gabarit** optionnel d\xe9finit le **nom initial** des **nouvelles** sessions (`%UUID`, codes date/heure fa\xe7on POSIX `strftime` — r\xe9f\xe9rence indiqu\xe9e sur l’\xe9cran) avec le m\xeame **fuseau d’affichage** que le tableau de bord et les rapports.","Sur une t\xe2che **en cours**, **en pause** ou **termin\xe9e**, un bouton **Sauvegarder comme template** (ic\xf4ne) enregistre son titre, **#\xe9tiquettes** et projet **@** ou **!** ; la saisie \xab sur quoi travaillez-vous \xbb propose ces mod\xe8les (**Mod\xe8le :**, liste **pleine largeur** de la ligne titre) avec recherche **debounce** — la s\xe9lection **reprend les derni\xe8res heures de d\xe9but/fin** sur la **journ\xe9e courante** (mode pass\xe9) ; la **palette Ctrl+K** les inclut, et [Param\xe8tres → Mod\xe8les de t\xe2che](/settings#settings-task-templates) permet aussi de les **g\xe9rer**.","Lorsqu'un mod\xe8le fournit \xe0 la fois la **derni\xe8re heure de d\xe9but** et la **derni\xe8re heure de fin**, la modale horaire est **contourn\xe9e** : les cr\xe9neaux (recal\xe9s sur la journ\xe9e courante) et la dur\xe9e du minuteur sont pr\xe9remplis **directement** dans le lanceur — validez par **Entr\xe9e** sans \xe9tape suppl\xe9mentaire.","Sur chaque carte, un bouton r\xe9sum\xe9 **d\xe9but → fin** (comme en **mode pass\xe9** du lanceur) ouvre une **seule modale** (deux calendriers c\xf4te \xe0 c\xf4te, **fin facultative**, dur\xe9e du minuteur si la fin est renseign\xe9e) ; la validation applique les corrections en une fois. Si un **lap** est en cours (minuteur actif ou **en pause**), un nouveau **d\xe9but** **r\xe9aligne** le lap ; si une **fin** est d\xe9j\xe0 renseign\xe9e, la dur\xe9e totale peut \xeatre **recalcul\xe9e** depuis les bornes. Sur une t\xe2che **termin\xe9e** \xe0 **un seul** lap enregistr\xe9, corriger d\xe9but ou fin **met \xe0 jour** ce lap en cons\xe9quence. La section **Laps de suivi** reprend le **m\xeame bouton r\xe9sum\xe9** et la **m\xeame modale** par lap (num\xe9ro **#** et **dur\xe9e** du lap restent visibles sur la ligne) ; vous pouvez **supprimer** un lap enregistr\xe9 — sous r\xe9serve du param\xe8tre **Autoriser la correction de l’heure de d\xe9but** pour les t\xe2ches en cours. Pour une t\xe2che en cours, une **heure de fin** (pass\xe9e ou future) **termine la t\xe2che** \xe0 cet instant — ce n’est pas une simple pause du minuteur.","Sur une t\xe2che **termin\xe9e**, le bouton **Rouvrir** (ic\xf4ne ↺) la remet **en cours** : une modale propose de **reprendre le minuteur**, de **rouvrir en pause**, d’**ajuster la dur\xe9e** manuellement ou de **remettre le minuteur \xe0 z\xe9ro** ; les **sous-t\xe2ches** sont rouvertes aussi. En **session live**, si un autre minuteur tourne d\xe9j\xe0 lors d’une **reprise**, les m\xeames options **pause / terminer / parall\xe8le** s’appliquent (m\xe9morisation possible). Dans un **instantan\xe9 cl\xf4tur\xe9**, le minuteur ne repart pas en direct — seuls statut et dur\xe9e changent ; la t\xe2che appara\xeet sous **Non termin\xe9es (instantan\xe9)**.","Lorsque le **d\xe9but** d’une t\xe2che **non termin\xe9e** est encore **dans le futur** (horloge), l’entr\xe9e est sous **Planifi\xe9es** avec un style **bleu ciel** : pas de **minuteur** \xab en direct \xbb et **aucun temps compt\xe9** avant l’heure officielle. En r\xe9glant le **d\xe9but** sur la carte, la **fin** suit avec l’\xe9cart **dur\xe9e minimale** ([T\xe2ches et \xe9tiquettes](/settings#settings-task-tags)) ; sans fin d\xe9j\xe0 enregistr\xe9e, la validation du d\xe9but **programme** cette fin. \xc0 l’**heure de d\xe9but** (`startTime`), le **serveur** active le suivi (synchronisation d’\xe9tat, environ **toutes les 2 s**) : la carte quitte **Planifi\xe9es** et le minuteur d\xe9marre **\xe0 partir de ce d\xe9but**. Une **heure de fin** sur une t\xe2che **en cours** programme `scheduledEndAt` : la t\xe2che se **termine** automatiquement \xe0 cet instant. Pour une t\xe2che **termin\xe9e**, le bloc \xab planifi\xe9 \xbb ne s’applique que si **d\xe9but et fin** sont encore **tous deux** dans le futur ; si le d\xe9but est d\xe9j\xe0 pass\xe9 et seule la fin est future, l’entr\xe9e reste avec les **termin\xe9es** (\xe9vite d’y rester coinc\xe9e jusqu’\xe0 l’heure de fin). M\xeame logique visuelle pour une **session live** dont l’**heure de d\xe9but officielle** est encore dans le futur (ligne distincte dans la liste). Il n’y a **pas de pastille texte** \xab planifi\xe9 \xbb : la distinction repose sur la section, le style et le point d’\xe9tat.","\xc0 l’activation d’un cr\xe9neau planifi\xe9 (t\xe2che ou session live), un **toast** en bas \xe0 droite confirme le d\xe9marrage **sur n’importe quelle page** de l’app (param\xe8tres, rapports, guide, etc.) — le titre de la t\xe2che ou le nom de la session est rappel\xe9.","Lorsqu’une t\xe2che **sort de Planifi\xe9es** et devient **en cours** alors qu’**au moins un** autre minuteur \xe9tait d\xe9j\xe0 affich\xe9 comme **en cours**, une modale propose les m\xeames options **pause / terminer / parall\xe8le** (avec la m\xeame m\xe9morisation que pour le d\xe9marrage manuel) pour les **t\xe2ches d\xe9j\xe0 au minuteur** ; hors route du tableau de bord, l’ic\xf4ne **Tableau de bord** peut **pulser** bri\xe8vement pour signaler qu’une action est attendue.","Pour une **session** de l’**historique** (pas la session **live**), le **r\xe9sum\xe9** (nom, dur\xe9e, m\xe9triques) s’affiche **sous la ligne** correspondante dans la **liste** des sessions, pour garder le d\xe9tail au m\xeame endroit pendant la navigation."]},{id:"ug-kronofocus",title:"KronoFocus — retenir le rythme, pas un bulletin",searchIndex:"pomodoro focus minuteur travail pause dur\xe9e hh:mm",paragraphs:["**Travail**, **pause**, **reprise**, **longue pause** : l’id\xe9e est l’**alternance** saine, pas une **note** sur le nombre de minutes. Proche d’un **pomodoro**, sans s’y figer si votre rythme diff\xe8re."],optionsTitle:"O\xf9 c’est propos\xe9, quoi cliquer",options:["Section [KronoFocus (tableau de bord)](/settings#settings-kronoFocus) dans **Param\xe8tres** : le minuteur reste **dans la barre d’outils** ; vous choisissez encore s’il appara\xeet **pr\xe8s des actions de t\xe2che** (le **profil** d’usage peut **masquer** d’autres blocs ailleurs).","Sur le **panneau** : **D\xe9marrer**, **Pause**, reprise ; **dur\xe9e** en `HH:MM:SS` ; **dur\xe9e par d\xe9faut** (p. ex. 25 min) d’un clic ; **historique** des dur\xe9es pour **r\xe9appliquer** la m\xeame mesure **sans** la retaper.","Lier le KronoFocus **\xe0** la t\xe2che **active** : utile pour **retrouver** dans l’historique **quelle** t\xe2che portait ce **bloc** de focus."],steps:["Ouvrez le KronoFocus (en-t\xeate ou pr\xe8s d’une t\xe2che) ; basculez **travail** / **pause** / **longue pause** selon l’**\xe9tat** affich\xe9.","Ajustez la **dur\xe9e** (saisie ou raccourci) ; enregistrez souvent la **m\xeame** dur\xe9e **dans l’historique** pour un **r\xe9emploi** en un clic.","Lancez le **d\xe9compte** ; en fin de phase, l’**\xe9cran** propose la **suite** (reprise, autre mode) selon le **flux** en cours."]},{id:"ug-search-palette",title:"Recherche Spotlight : donn\xe9es (tableau de bord) & rubriques (ce guide)",searchIndex:"palette recherche donn\xe9es sessions t\xe2ches mod\xe8les ctrl k",paragraphs:["M\xeame **allure** de champ (bordure zinc, focus **violet**) : **deux cibles** — d’**abord** l’**atelier** (sessions, t\xe2ches, **mod\xe8les de t\xe2che**, \xe9tiquettes, mots du workspace) ; **ensuite** le **fil** en t\xeate de **cette** page, qui ne filtre **que** les **rubriques** du **guide**."],stepsTitle:"Donn\xe9es — la palette (tableau de bord)",steps:["Cliquer sur **Rechercher dans les donn\xe9es** ou presser **Ctrl+K** (Windows / Linux) / **⌘K** (macOS) : la **palette** s’ouvre (raccourci **r\xe9serv\xe9** : on ne le **red\xe9finit** **pas** dans la modale raccourcis).","Saisir **deux** ou **trois** **lettres** d’**une** **session**, d’**une** **t\xe2che**, d’**un** **mod\xe8le**, d’**un** **#**, d’**un** **@** ou d’**un** **!** : la **liste** se **restreint** en **direct**.","Choisir **une** **ligne** (**Entr\xe9e** ou **clic**) : l’**\xe9cran** **saute** **vers** l’**objet** ; pour **un mod\xe8le**, le **champ** nouvelle **t\xe2che** est **rempli** ; **\xc9chap** **ferme** la **bo\xeete** **sans** **toucher** le **fond**."],optionsTitle:"Ce guide — le champ coll\xe9 en haut de page",options:["Il ne **lit** **pas** la **base** Kronosys : **seules** les **sections** de **ce** texte d’aide (titres + corps) **subissent** le **filtre**.","Le **compteur** `n / total` (\xe0 **droite** du **champ**) rappelle **combien** de **rubriques** **restent** **visibles** **apr\xe8s** la **saisie**."]},{id:"ug-shortcuts",title:"Raccourcis clavier (tableau de bord)",searchIndex:"raccourcis clavier alt shift ctrl",paragraphs:["Ouvrez la **modale des raccourcis** depuis le petit clavier pr\xe8s de la palette pour voir, **modifier** ou **r\xe9initialiser** les combinaisons (les touches **Ctrl+K** / **⌘K** restent r\xe9serv\xe9es \xe0 la palette **Spotlight**). La relance de **certaines** visites guid\xe9es et des options d’**API** se g\xe8rent aussi dans [Param\xe8tres — Web & API](/settings#settings-web)."],bullets:["Nouvelle session : Alt+Shift+N (par d\xe9faut).","Rapports : Alt+Shift+G \xb7 Param\xe8tres : Alt+Shift+S \xb7 **Guide (cette app)** : Alt+Shift+U.","Colonnes : Ctrl+Alt+H (sessions) \xb7 J (t\xe2ches) \xb7 Y (\xe9tiquettes).","Th\xe8me : Alt+Shift+T \xb7 Langue : Alt+Shift+L \xb7 Terminer session live : Alt+Shift+E.","Mode focus (colonnes seules) : Alt+Shift+F \xb7 palette Ctrl+K (\xab Basculer le mode focus \xbb) \xb7 quitter avec \xc9chap ou le bouton en haut \xe0 droite."]},{id:"ug-reporting",title:"Rapports : la m\xe9moire qui tient, quand on doit la raconter",searchIndex:"agregats kpi plage date \xe9tiquette semaine assiduit\xe9 retard heure planifi\xe9e onglets allocation facturation rythme avanc\xe9",paragraphs:["Les **rapports** ne jaugent pas votre humanit\xe9 : ils aident \xe0 **r\xe9pondre** \xe0 *est-ce qu’on peut, ensemble, s’y retrouver sur une p\xe9riode ?* Ce qui n’est **pas** **encore** fini reste **indiqu\xe9** (brouillon **honn\xeate**, pas punition).","Sous les filtres, **trois cartes** (Allocation facturation, Rythme, Avanc\xe9) d\xe9crivent chaque vue : **Allocation facturation** (#\xe9tiquettes, @projets, calendriers hebdo avec **Total jour** en bas) — le KPI **Temps de t\xe2che enregistr\xe9** est le **total de la semaine affich\xe9e** ; **Rythme** (graphiques par jour et **liste sessions / jour**) ; **Avanc\xe9** (synth\xe8se sur toute la plage, tableau journalier, lignes / signaux, instantan\xe9 workspace). **Un seul (?)** par section regroupe l’aide d\xe9taill\xe9e. L’appli **agr\xe8ge** ce que vous avez **d\xe9j\xe0** enregistr\xe9 ; une **visite** adoucit le **premier** tour.","Lorsque l’**h\xf4te** d’enregistrement a **fourni** l’heure de **d\xe9but pr\xe9vue** \xe0 l’ouverture d’une session (p. ex. moteur li\xe9 \xe0 l’[horaire](/settings#settings-schedule) ou aux [sessions planifi\xe9es](/settings#settings-planned-sessions)), l’**\xe9cart** (retard ou avance) est **sauvegard\xe9** sur la session et des **indicateurs d’assiduit\xe9** apparaissent dans le **r\xe9sum\xe9** (vue **Avanc\xe9**) : ce n’est en g\xe9n\xe9ral **pas** rempli par le seul bouton *Nouvelle session* du navigateur, sauf int\xe9gration explicite."],stepsTitle:"Parcours type sur l’\xe9cran Rapports",steps:["Ouvrir **Rapports** (ic\xf4ne **graphe** ou raccourci **Alt+Shift+G** sur le tableau de bord).","Choisir une **plage** : champs **Du** / **Au**, bouton **Aujourd’hui**, ou pr\xe9r\xe9glages **jour** / **semaine** / **mois** / **ann\xe9e** (selon ce que l’UI expose).","Optionnel : **s\xe9lectionner** une ou plusieurs **#\xe9tiquettes** pour **restreindre** les t\xe2ches (les **sessions** **sans** t\xe2che **correspondante** **disparaissent** des **vues** **bas\xe9es** **t\xe2ches**).","Choisir une **carte** sous les filtres : **Allocation facturation** pour le temps par #\xe9tiquette et @projet (grilles hebdo, navigation de semaine, d\xe9but de semaine) ; **Rythme** pour les graphiques par jour et la **liste sessions / jour** ; **Avanc\xe9** pour les indicateurs de synth\xe8se, le tableau journalier, les lignes de code (si activ\xe9es) et l’instantan\xe9 workspace.","**Lancer** la **visite** **guid\xe9e** **si** la **pancarte** **le** **propose**."],options:["**Indicateurs non finaux** (pastilles) : rappellent le **travail encore ouvert** dans la plage — lire prudemment, pas de chiffrage *fig\xe9* tant que des t\xe2ches *bougent* encore.","Sous le **r\xe9sum\xe9** (vue **Avanc\xe9**), une **ventilation** peut compter les **sessions** par **type de cl\xf4ture** enregistr\xe9 \xe0 la fin de session (lorsque l’h\xf4te en a choisi un) ; les sessions **sans** cat\xe9gorie y figurent \xe0 part.","Le **tableau par jour** (vue **Avanc\xe9**) inclut aussi un total de temps t\xe2che **non concurrent** (sans chevauchement des intervalles horodat\xe9s) pour comparer avec le temps enregistr\xe9 brut.","**D\xe9but de semaine** (dimanche, lundi ou samedi) : **Param\xe8tres → Tableau de bord et API** (d\xe9faut **dimanche**) ; s’applique aux calendriers des s\xe9lecteurs de date et aux grilles hebdo des rapports (raccourci aussi pr\xe8s des calendriers rapports).","Le calendrier hebdo **@projet** affiche une ligne **Total jour** (somme des lignes projet). Le calendrier **#** affiche en pied **Temps enregistr\xe9 (par t\xe2che)** — une fois par t\xe2che, pas la somme des lignes # (la dur\xe9e compl\xe8te reste sur chaque ligne # pour le WBS).","Les valeurs entre parenth\xe8ses (0,25 h) sont arrondies au quart d'heure (15 min) pour la saisie en feuille de temps. Ex. 1 h 11 min → 1,25 h car 71 min arrondi \xe0 75 min = 1,25 h.","Relancer la visite **Rapports** (aide **premier pas** sur l’\xe9cran) : [Param\xe8tres — visite Rapports](/settings#settings-reporting-tour).","Sous le **calendrier hebdomadaire par projet (@)**, le s\xe9lecteur **Travail (@)** / **Personnel (!)** change de registre : **Travail** (d\xe9faut) exclut le temps personnel ; **Personnel** n’affiche que celui-ci (t\xe2ches `personalProject` ou titre avec jeton `!` reconnu)."]},{id:"ug-settings-integrations",title:"Param\xe8tres, sauvegardes et bouts d’usine (quand vous \xeates pr\xeat\xb7e)",searchIndex:"export backup restore restauration sqlite json csv gitlab mongo v4 v4-qa v4-dev qa production environnement coffre donn\xe9es next dev d\xe9veloppement local",paragraphs:["Ici, vous **r\xe9glez** l’**appareil** (KronoFocus, **\xe9tiquettes** / **@** avanc\xe9s, planification) et, **seulement si** vous voulez, le **c\xe2ble** (Git, GitLab, miroir). La **zone dangereuse** : **lisez** le texte \xe0 l’**\xe9cran** et la **phrase** de confirmation avant de **valider** un **effacement**. L’[index de la page Param\xe8tres](/settings#settings-usage-profile) liste toutes les sections (sommaire \xe0 gauche en grand \xe9cran)."],optionsTitle:"Principaux blocs (noms fr\xe9quents, selon votre version)",options:["**Profil d’usage** ([ancre Profil d’utilisation](/settings#settings-usage-profile)) : ex. *gestion* masque des blocs (p. ex. Lignes de code) qu’un **d\xe9v** n’aurait pas cach\xe9.","[KronoFocus](/settings#settings-kronoFocus), [Collecte et tampons](/settings#settings-collection), [Horaire de travail](/settings#settings-schedule) ou [sessions planifi\xe9es](/settings#settings-planned-sessions), [T\xe2ches et \xe9tiquettes](/settings#settings-task-tags) ; [Git](/settings#settings-git) / [MongoDB](/settings#settings-mongo) en branchement **opt-in** (rien n’impose d’ouvrir tout le premier soir).","**Migration d’\xe9tiquettes** : dans [T\xe2ches et \xe9tiquettes](/settings#settings-task-tags), l’outil de port\xe9e permet de **copier** ou **d\xe9placer** une \xe9tiquette globale vers une port\xe9e projet (`Projet#tag`) et l’inverse.","**\xc9tiquettes sans #** : \xe9tiquette seau \xab d\xe9faut \xbb activable ; option pour **retirer \xab d\xe9faut \xbb** d\xe8s qu’une autre \xe9tiquette explicite est ajout\xe9e ([T\xe2ches et \xe9tiquettes](/settings#settings-task-tags)).","Sans `#` explicite, une nouvelle t\xe2che re\xe7oit l’\xe9tiquette r\xe9serv\xe9e **\xab d\xe9faut \xbb** (reporting) ; d\xe8s que vous ajoutez un **`#tag`** (cr\xe9ation, \xe9dition du titre ou mise \xe0 jour), **\xab d\xe9faut \xbb dispara\xeet** — sauf si vous d\xe9sactivez le retrait automatique dans [T\xe2ches et \xe9tiquettes](/settings#settings-task-tags).","**Renommage des \xe9tiquettes/projets (inline)** : dans la colonne droite **Tags / Projects / Templates**, cliquez sur le crayon, modifiez le nom directement dans la ligne puis validez par **Entr\xe9e** (ou **\xc9chap** pour annuler). Un avertissement pr\xe9cise l’impact sur les **rapports** ; vous pouvez cocher \xab ne plus afficher \xbb pour les prochains renommages. (Les listes **`knownPersonalProjects`** pour les jetons **`!`** ne disposent pas encore du m\xeame \xe9cran d’inline que les projets **`@`**.)","**Corrections d’horaire** : commutateurs **on/off** dans [T\xe2ches et \xe9tiquettes](/settings#settings-task-tags) pour le **d\xe9but** et la **fin** d’une **t\xe2che**, et le **d\xe9but** et la **fin** d’une **session**. **Dur\xe9e minimale d’une t\xe2che** (minutes, d\xe9faut 30) : pr\xe9remplit la **fin** lors d’une entr\xe9e **pass\xe9e** ou **planifi\xe9e** (d\xe9but arrondi \xe0 la demi-heure pr\xe9c\xe9dente). Sur une **t\xe2che** en cours, une heure de fin **termine la t\xe2che** \xe0 l’instant pr\xe9vu. Sur une **session** live, une heure de fin **cl\xf4t la session** \xe0 l’instant pr\xe9vu (instantan\xe9 en historique, \xe9quivalent d’une fin de session en mode conserver les t\xe2ches ouvertes).","**G\xe9n\xe9ral — coffres production et QA** ([Param\xe8tres → G\xe9n\xe9ral](/settings#settings-data-environment)) : activez **deux coffres** (`v4` production + `v4-qa` tests) ; basculez avec **Prod / QA** dans la barre de navigation (effet **imm\xe9diat**) ou le s\xe9lecteur sur cet \xe9cran (**Enregistrer**). Au **premier** passage en QA sans coffre existant, une modale propose de **copier la production** ou de **d\xe9marrer vide**. En mode QA, un **bandeau violet** et un **liser\xe9** rappellent que les donn\xe9es ne sont pas celles de la production.","**G\xe9n\xe9ral — mode d\xe9veloppement (coffre local)** ([Param\xe8tres → G\xe9n\xe9ral](/settings#settings-dev-data), seulement en `next dev`) : **Enregistrer** avec le bouton principal ; par d\xe9faut, **jeu de donn\xe9es** s\xe9par\xe9 de la **production** (`v4-dev`) ; on peut partager le coffre `v4` (puis **red\xe9marrer** le serveur de dev). Distinct des coffres **Prod / QA** ci-dessus (usage quotidien packag\xe9 ou `next start`).","**Sauvegarde / restauration compl\xe8te** : c\xf4t\xe9 technique, `GET /api/backup` exporte (format), et `POST /api/restore` restaure un fichier JSON ou SQLite ; c\xf4t\xe9 appli, la **Zone de danger** fournit les actions de sauvegarde + restauration guid\xe9e."],stepsTitle:"Avant d’effacer l’historique (check-list courte)",steps:["Pr\xe9f\xe9rer un **export** (souvent propos\xe9 dans l’**\xe9cran** d’avertissement) : JSON, CSV, copie **SQLite** selon ce qu’ouvre la **brique** d’h\xe9bergement **chez** vous, ou l’[export par d\xe9faut](/settings#settings-export) dans l’**UI** quand c’est propos\xe9.","Relire [la zone dangereuse](/settings#settings-danger-zone) (liste de ce **qui** **dispara\xeet** *vraiment*).","Saisir le **mot** de confirmation *exact* demand\xe9 ; annuler s’il reste le **doute**."]}]}:{pageTitle:"User guide",pageSubtitle:"Each section blends *why* it matters **to you**, **step-by-step** moves in the UI when order matters, and **options** you can actually pick — same **light or dark** look as the app.",defaultStepBlockTitle:"Step by step in the app",defaultOptionsBlockTitle:"Options, modes, and quick facts",searchPlaceholder:"Filter topics (purpose, steps, options, KronoFocus…)",searchAriaLabel:"Search the user guide",searchNoResults:"No section matches. Try another keyword or clear the filter.",tocHeading:"On this page",tocNavAria:"User guide table of contents",lastUpdated:"Last updated: 3 June 2026 (v1.0.0-beta.36)",helpLinksHeading:"More pages",helpLinksAria:"Links to implementation status and licenses",helpImplementationLink:"User stories — implementation",helpLicensesLink:"Licenses and third-party notices",sections:[{id:"ug-essence",title:"What Kronosys is for — the heart, not the tab",searchIndex:"purpose why meaning help people benefit productivity time memory focus calm team client explain remember rhythm work life attention local your data",paragraphs:["Kronosys is a **companion** for time and work: record **what** you are doing, **for how long**, in which **thread** — not to fill a paperwork show. **What is it for?** A little **less** amnesia about *“how much of my week was that, really?”*, a **clean** way to **end** a work block, and a **story** (for you, a team, a client) when the moment needs it.","Built for people who work in **chunks** (code, copy, operations, research…), **juggle** contexts, or have to **explain** without rebuilding Excel at midnight. Data stays **on your** machine; Git, mirrors, and large backups are **cables** you add when **you** choose."],optionsTitle:"Three “rooms” for three moves",options:["**Dashboard** — the workbench (sessions, tasks, focus timer, **#** tags, **@** work projects, and **!** personal projects).","**Reports** — the span in **three tabs** (billing allocation, rhythm, advanced) from what you **already** logged.","**Settings** — the back room (habits, connections, the **danger** zone where you wipe history **carefully**). [Open Settings](/settings#settings-usage-profile)."],stepsTitle:"A calm first run (day one need not be perfect)",steps:["Open the **home** (dashboard) — the workbench starts there.","Start a **new session** (or let the app start one the first time a task needs it).","Name a **task**; **#** = tag; **@** = work project; **!** = personal project (the form often **suggests** tags and projects from what you type).","Press **Start** on the task, or add **KronoFocus** on the **side** if a ritual helps more than a bare timer in the list.","When you need the bigger picture, open **Reports** for a **date range** — you should not have to re-run the week in spreadsheets to see it."]},{id:"ug-nav-theme",title:"Toolbar, theme, and language",searchIndex:"theme light dark language fr en ribbon group navigation wrap multiple rows narrow screen",paragraphs:["The top bar reuses the **same** **family** of controls (zinc, **violet** accents) on every page so **navigation** stays **light** on the brain. **Page shortcuts** sit in **small grouped blocks** by **context** (main areas, help and docs, in-session tools), like a **lightweight ribbon**. The **cog** icon opens [Settings](/settings#settings-usage-profile) (shortcut **Alt+Shift+S** from the dashboard).","On a **narrow screen** (small laptop, shrunk window, tablet **PWA**), the row **wraps** into **multiple centered lines** instead of showing a **horizontal scrollbar** — the **blocks** (clock, KronoFocus, navigation, utilities) stay **grouped** and reachable **without side-scrolling**."],steps:["On the **dashboard**: **Book** → this guide; **chart** → **Reports**; **cog** → **Settings**.","On **other** pages: **grid** (dashboard icon) back to **home**; same book / chart / cog; the **changelog** icon opens `/changelog` from the bar.","From this **guide**, the **Implementation** and **Licenses** buttons (below the title) open the user-story inventory and legal notices — they are no longer in the icon bar.","On **Implementation**, rows with a **chevron** expand for extra **detail** and an **example** (smaller type) under the short wording.","Still on the dashboard, a **Today Gantt** button (grid) opens one global timeline for tasks from **all** sessions in the current day.","**Theme** toggle: **light** or **dark** (evening work or a bright room).","**Refresh** fetches state again from the **server** (e.g. after a change you know happened elsewhere).","**Language** menu: **EN** / **FR**; if the server is configured, the choice can **stick** between visits."],options:["**Book** = this guide; **Chart** = **Reports**; **Cog** = **Settings**; **Grid** = **Today Gantt** (dashboard); **Changelog** = user update log. **Implementation** and **Licenses**: buttons at the top of this guide.","The **theme** only changes how the **UI** looks — it does **not** alter your stored work."]},{id:"ug-layout",title:"Where to work, where to look back, where to tune",searchIndex:"workspace dashboard reports settings license legal clock timezone drawer focus columns xl",paragraphs:["Three main moves: the workbench (now), **Reports** (then), **Settings** (how the app runs + serious cleanup). **Licenses** is the honest credit page for the open building blocks we use."],options:["**Dashboard** — **sessions** on the left, **tasks** (timers, detail) in the **centre**, **tag** and **project** shortcuts (**@** work, **!** personal) on the right. On **wide screens** (xl+), side panels become **retractable drawers** **flush to the left or right screen edge** (pull tab toward tasks, collapsed strip with **icon** and vertical title); the **task launcher** is also a **collapsible drawer** (no pull tab); the **Tasks** column stays **centered** (**42 rem** base, **+20 %** max width per collapsed **side** drawer); open/closed state is **remembered** in the browser; the **session list** scrolls **inside** the drawer (selected session card stays pinned above when shown). A **single Tasks header row** combines the **total**, **counts** per status (Running, Planned, Paused, Completed, Unfinished in archive), **TRACKING**, **(?)** help, and **chevron** expand/collapse (xl+); collapsed: same row, form hidden. **Focus mode**: **expand** button (utility ribbon), **Ctrl+K** / **⌘K** palette command, **Alt+Shift+F** shortcut — hides header and banners to show the **three columns** only; exit with **Esc** or the **minimize** button at the top right.","**Reports** — pick a **date range** and, if needed, **#** tags; then use the **tabs** (billing allocation, rhythm, advanced); the **tour** may offer itself the first time you land there.","**Settings** — profile, collection, scheduling, **advanced** tags, optional **Git** or **remote**; the **danger zone** can **delete** all **history** (type-to-confirm). [Settings overview](/settings#settings-usage-profile) \xb7 [danger zone](/settings#settings-danger-zone).","**Action logs** (`/logs`) — server-side **mutation** history (type, success, timestamp, session); **list** icon in the main navigation block.","**Licenses** — MIT, third parties, **fonts**; open it from the **Licenses** button at the top of this guide.","A **wall clock** (time zone and 12/24 h from **Web dashboard** settings) stays visible in the header **toolbar**; **KronoFocus** sits **right beside it**, before the navigation icons — it is **always** shown so the bar stays stable. When **production and QA vaults** are enabled, a **Prod / QA** switch appears before those icons and **reopens the correct SQLite file immediately** (no server restart). While you **inspect an archive**, its **buttons** stay **visible but disabled** — they still reflect the **live session**. The **data palette** (Ctrl+K / ⌘K), **Today Gantt**, and **global pause** are the **same** on **every** main page (dashboard, reporting, settings, logs, guide, implementation, changelog, licenses); off the **dashboard**, some actions **return** there to **finish** (e.g. open a search hit)."]},{id:"ug-convention-end-vs-pause",title:"Convention: scheduled end time vs pause",searchIndex:"convention pause scheduled end completion closure timer wall clock deferred break",paragraphs:["In Kronosys, a **scheduled end time** on a **running task** or **session** means **completion** at that instant — it is **not** a **deferred pause** or “pause later at this clock time”.","To **pause** tracking (timer, wall clock, session), use the **pause actions** built for that purpose; they are **separate** from **deadlines** and **scheduled ends**."],bullets:["**Scheduled end** → the **task finishes** or the **session closes** at the chosen instant.","**Pause** → an **explicit action** (task timer, paused live session, global pause, etc.)."]},{id:"ug-sessions-tasks",title:"Sessions, tasks, tags, and projects",searchIndex:"session archive end task timer pause subtask history list summary planned badge chip conflict navigation personal project glued bang email reopen minimum duration half-hour future end backdated live",paragraphs:["A **session** is the **bag** work piles into; a **task** is the **thread** of a moment. **#** tags themes; **@** marks a **work** project; **!** marks a **personal** project (often a **rose** chip) — naming helpers, not a grammar test. **`!`** (including **`!project#subtag`**) may be **glued** to the previous word with **no space** — e.g. `Errands!personal#dentist`; **`@`** still expects **whitespace before** or **start of field** so emails like `user@host` are not parsed as projects."],optionsTitle:"New session — the frame, your choice",options:["**Start** **now** (immediate) with an optional **scheduled end** in the modal, or **in the past** — enter **both start and end** in your browser’s local date and time. If the end is still **ahead**, Kronosys opens a **live** session from that start and **closes it automatically** at the scheduled time; if the end is **already past**, the closed interval goes to **history** (without interrupting an active session) and the UI focuses it for **task entry**. **Starting now** while a session is **already live** runs the usual **end session** flow first.","**No** extra frame in particular: start, and the flow **carries** you.","**Max wall** clock: a **nudge** to reframe a **very** long stint.","**Calendar** window: from / to **dates** (a commitment to your later self or someone else).","**Week** + time window on selected **weekdays** (handy in a **fixed** rhythm; skip it if you hate that).","Tasks in **real time** or back-filled with start, end, and **timer duration** (h/m/s — same idea as duration adjustments): honest to log the evening for **yesterday**’s work."],stepsTitle:"After you press “Start” on a task (usual order)",steps:["Type a **title** (full-width field below the action bar); add **#**, **@**, and/or **!** — a **dropdown** then lists **most-used** then **recent** choices (filters as you type; **↑** / **↓**, **Enter**, or click), including when **editing a task title** on the card. Add an optional **free-text task note**, and a **session note** when useful.","Click **Start** on the task — or, if it fits, launch **KronoFocus** from that **task** first (same work, different rhythm).","If another **timer** is on: **pause** it, **finish** it, or allow both in **parallel** (you can **save** the choice for the next time).","While in progress: add **subtasks**; check them; **reorder** by **drag and drop**; use **pause** and **resume** kindly.","**End session** from the header or banner: optional end reason (on time, early, overrun, other + note) — a word for **how** the block **ended**, not a cold verdict."],bullets:["Each **task** supports a **free-text note**: **Add a note** on the card or launcher (field hidden while empty); a **saved** note renders as Markdown before **subtasks** (click to edit). The **title** supports **inline** Markdown when read-only. **(?)** icon opens Markdown help with examples and preview.","**Task launcher**: like task cards — now/past mode, KronoFocus, help and **project** / `#tag` **chips top right**; in **past mode**, a button opens a **modal** for **start**, **end**, and **timer duration** (summary shown in the launcher); **title** with **Start / Add** **at end of row**, then **note** below; **Template:** suggestions span the **full title row** width. On **xl+**, **collapsible drawer** (same chrome as side drawers): **same row** as the **Tasks** column title (counts, **TRACKING**, **(?)** help, **chevron**); collapsed: compact strip, form hidden; below xl, always expanded.","Each **session** supports a **session note**; a preview (icon + excerpt) appears in the session list and in archived sessions.","The **global pause** control is **inactive** (with a tooltip) when **nothing is running** — wall clock already frozen and no timers — otherwise it opens a **confirmation** with a **summary**: **start** and **end** (*ongoing* when there is no end yet), **wall duration**, **session coding** and **active** times when the host records them, **task** / **subtask** counts, **total recorded** task-timer time, then the **split** between **main task** time (excluding subtasks) and **subtask** timers, followed by the list of timer effects; once confirmed, it pauses the current session context (session, task timers, and subtask timers); the next click resumes **only that paused set**.","**Session pause** (header control while the session is **live**) also **freezes** **active** **task** and **subtask** timers; **resume session** only restarts what was frozen **by that pause** — not a task you had already paused **manually** beforehand. Resuming a **single task** removes it from the batch that a later **resume session** would restart.","With no **explicit `#`**, a task gets the reserved **“default”** tag; when you add a **`#tag`** (create, title edit, or update), **“default” is dropped** automatically — toggle under [Tasks & tags](/settings#settings-task-tags).","On **chips** (task card, reporting, lists), only the **name** shows — **no** `#`, `@`, or `!` — **color** distinguishes tags (**green**), work projects (**sky blue**), and personal projects (**rose**); **tokens** still appear while **typing**, in **suggestions**, and **quick marking**. [Settings → Web dashboard](/settings#settings-web) option **“Do not rely on color alone”** adds `#` / `@` / `!` prefixes and distinct border styles alongside the colors.","When ending a session that still has open tasks, you can **finish** them, **move** them to a **new paused session**, or **leave** them **open** in the archived snapshot — **task timers for that session always stop**.","In that **live paused** session, a **banner** lets you **resume session**; **play** on a task also **resumes** wall-clock tracking.","When the live session is **paused** (wall clock and affected timers, or **global pause**), the **Active session** card shows a **Paused** or **Global pause** chip; a **dimmed overlay** centers a reminder while the **top bar** stays usable to **resume**.","In the **Active session** timing block, a **progress bar** below **End** advances from **start** toward the **scheduled end** when one is set (visual alert near the deadline, same as on task cards). **Total planned duration** (start → scheduled end) and **Planned total (tasks)** appear **only** when the data exists; otherwise the row is **hidden**. Below **Duration**, **Remaining duration** shows the time left; otherwise **Undetermined**. The Sessions list shows `planned X` on the live row when a scheduled end is set.","Even a **completed past session** still accepts a **past entry**: select it, set start (defaults to the previous half-hour), end is prefilled from start plus the **minimum task duration** in [Tasks & tags](/settings#settings-task-tags), then adjust duration if needed.","Under [Settings → Web dashboard](/settings#settings-default-session-name), an optional **template** sets the **default name** for each **new** session (`%UUID`, POSIX-style `strftime` fields — authoritative link on that screen). Expansion uses your **display** **time zone** (same buckets as Reporting).","On a **running**, **paused**, or **completed** task, **Save as template** (icon) saves its title, **#tags**, and either an **@** or **!** project. The “what are you working on” input suggests them (**Template:**, **full-width** title row list) with **debounced** filtering — picking one **reapplies the last start/end times on today’s date** (past mode); **Ctrl+K / ⌘K** search lists them; [Settings → Task templates](/settings#settings-task-templates) also lets you **manage** them.","When a template provides both a **last start time** and a **last end time**, the time modal is **skipped**: the slots (shifted to today’s date) and timer duration are prefilled **directly** in the launcher — press **Enter** to submit without extra steps.","On each card, a **start → end** summary button (same as the launcher’s **past** mode) opens a **single modal** (two inline calendars side by side, **optional end**, timer duration when end is set); confirming applies your changes in one step. If a **lap** is active (running timer or **paused**), a new **start** **realigns** that lap; when an **end** is already set, total duration may be **recalculated** from the bounds. On a **completed** task with a **single** saved lap, correcting start or end **updates** that lap accordingly. The **Tracking laps** block uses the **same summary button** and **same modal** per lap (**#** and lap **duration** stay visible on the row); you can **delete** a saved lap — subject to **Allow task start-time correction** for running tasks. On a **running** task, an **end time** **completes the task** at that instant — it is not a soft pause.","On a **completed** task, **Reopen** (↺ icon) makes it **active** again: a modal offers **resume timer**, **reopen paused**, **manual duration**, or **reset timer to zero**; **subtasks** are reopened too. On a **live** session, if another timer is already running when you **resume**, the same **pause / finish / parallel** choices apply (optional remember). On a **closed snapshot**, the timer cannot run live — only status and duration change; the row appears under **Unfinished (snapshot)**.","When a **not-done** task’s **start** is still **in the future**, it is grouped under **Planned** with **sky** styling (no live timer, and **no recorded time** before the official start). When you adjust **start** on the card, **end** follows with the **minimum duration** gap ([Tasks & tags](/settings#settings-task-tags)); if no end was stored yet, confirming start **schedules** that end. At the scheduled **start** (`startTime`), the **server** turns tracking on (state sync, about **every 2 s**): the card leaves **Planned** and the timer runs **from that start**. A scheduled **end** on a **running** task sets `scheduledEndAt` and the task **finishes** automatically at that instant. For a **completed** task, that **Planned** styling applies only when **both start and end** are still **strictly in the future**; if the start has passed but the end is still ahead (e.g. a scheduled end), the row stays under **Completed** instead of being stuck under **Planned** until the end time. The same idea applies to a **live** session whose official **start time** is still in the future (**distinct** row in the list). There is **no “planned” text badge** — section, styling, and the status dot carry the meaning.","When a **planned** slot **activates** (task or live session), a **toast** at the bottom-right confirms it on **any app route** (settings, reporting, guide, etc.) — the task title or session name is shown in the message.","When a **planned** task **becomes live tracking** while **another** timer was already shown as **running**, a modal offers **pause**, **finish**, and **parallel** (with the same optional **remember** setting as when you start a task manually), applying only to the **tasks that were already running** before the clock crossed; away from the dashboard route, the **Dashboard** icon may **pulse briefly** as a hint.","For a **session** in **history** (not the **live** one), the **summary** (name, duration, metrics) appears **under that row** in the sessions **list**, so details stay anchored to the same entry while you browse."]},{id:"ug-kronofocus",title:"KronoFocus — the rhythm, not a report card",searchIndex:"pomodoro timer focus work break duration",paragraphs:["**Work**, **pause**, **resume**, long **pause**: the idea is **healthy** alternation at the **bench**, not a score in minutes. Close to a **Pomodoro** — without locking in if your day does not match."],optionsTitle:"Where to find it, what the controls do",options:["In **Settings**: the [KronoFocus (dashboard)](/settings#settings-kronoFocus) section — the timer **stays in the header**; you can still choose whether it also appears **on** **task** actions (your **usage** profile can hide other panels elsewhere in the app).","On the **card**: **Start**, **Pause**, resume; **duration** as `HH:MM:SS`; a **one-tap** default (e.g. 25 min); **history** of durations to **reapply** without retyping.","Link the timer to the **active** **task** so you can later see **which** **task** carried that focus block in the **archive**."],steps:["Open **KronoFocus** (header or on a **task**); pick **work** / **pause** / **long** **pause** from the state the bar shows.","Adjust the **duration**; add a favourite to **history** to reuse the same **measure** in one click.","Start the **count**down; when a phase ends, the **UI** suggests the **next** **step** in the current flow."]},{id:"ug-search-palette",title:"Spotlight search: data (dashboard) and topics (this guide)",searchIndex:"palette data search templates ctrl k",paragraphs:["Same field **look** (zinc **border**, **violet** ring on **focus**): first the **workshop** (sessions, tasks, **task templates**, **#** / **@** / **!**); on **this** page, the line at the top only **filters** this help text."],stepsTitle:"Data — the search palette (dashboard)",steps:["Click **search data** or press **Ctrl+K** (win/linux) / **⌘K** (mac) — the palette is **reserved**; you do **not** rebind that chord in the **shortcuts** **modal**.","Type a few **letters** of a **session**, **task**, **template**, **#**, **@**, or **!**; the list **tightens** as you type.","**Enter** a row to **jump**; for a **template**, the **new task** field is **filled**; **Esc** closes the box without a full **page** **reload**."],optionsTitle:"This guide — filter at the top of the page",options:["It does **not** read your Kronosys database; it only **filters** the **sections** of this **guide** (titles and body) for **reading** here.","The **n / total** to the right of the field: how many **headings** stay **visible** after you type."]},{id:"ug-shortcuts",title:"Keyboard shortcuts (dashboard)",searchIndex:"keyboard hotkey alt shift",paragraphs:["Open the **shortcuts** modal (small keyboard by the **search** **trigger**) to view, rebind, or **reset** combinations. **Ctrl+K** / **⌘K** stay reserved for the **data** **palette**. Re-running some **tours** and the **API** options live under [Settings — dashboard & API](/settings#settings-web)."],bullets:["New session: Alt+Shift+N (default).","Reporting: Alt+Shift+G \xb7 Settings: Alt+Shift+S \xb7 **This guide**: Alt+Shift+U.","Columns: Ctrl+Alt+H (sessions) \xb7 J (tasks) \xb7 Y (tags & projects).","Theme: Alt+Shift+T \xb7 Language: Alt+Shift+L \xb7 End live session: Alt+Shift+E.","Focus mode (columns only): Alt+Shift+F \xb7 Ctrl+K palette (“Toggle dashboard focus mode”) \xb7 exit with Esc or the top-right button."]},{id:"ug-reporting",title:"Reports: memory you can read back, not a verdict on you",searchIndex:"filter date tag week kpi punctuality late schedule planned tabs billing rhythm advanced",paragraphs:["Reports are for a **calm** read of a time span, not a moral tally. They help answer: can we, together, make sense of this **period**? Unfinished work stays **indicated** where the UI does — honest draft, not **punishment**.","Under the filters, **three centered cards** (Billing allocation, Rhythm, Advanced) describe each view: **Billing allocation** (#tags, @projects, weekly grids with a **Daily total** footer) — the **Recorded task time** KPI is the **selected week’s total**; **Rhythm** (per-day charts and **session-by-day list**); **Advanced** (summary KPIs for the full filter range, day table, code lines / signals, workspace snapshot). **One (?)** per section holds the detailed help. The app **aggregates** what you **already** logged; a **guided** **tour** may soften the **first** visit.","If the **recording** **host** **passed** a **planned** start instant when a session was opened (for example a worker tied to your [work schedule](/settings#settings-schedule) or [planned sessions](/settings#settings-planned-sessions)), the app stores the **offset** in minutes and shows **punctuality** **summary** KPIs under **Advanced** — a browser-only **New session** usually does **not** set this by itself, unless a connector does."],stepsTitle:"A typical run on the Reports page",steps:["Open **Reports** (chart icon, or **Alt+Shift+G** from the dashboard).","Set **from** and **to** (or a day / week / month / year **preset**, depending on what the UI offers).","Use **Today** / **Now** quick actions in date/time pickers whenever available to jump to the current value.","Optionally pick one or more **#** **tags** (sessions with **no** **matching** task may **disappear** from some **task**-based **views**).","Pick a **card** under the filters: **Billing allocation** for time by #tag and @project (weekly grids, week nudger, week start); **Rhythm** for per-day charts and the **session-by-day list**; **Advanced** for summary KPIs, the day table, lines-of-code (when on), and the workspace snapshot.","Start the **guided** **tour** if a prompt appears the **first** time."],options:["**Non-final** chips mark work that is not **closed** in the **range** you are looking at: read them gently; the **draft** is not a **failure**.","Under **Advanced**, below the **summary** KPIs, a **breakdown** may count **sessions** by **closure type** saved when a session ended (when the host picked one); sessions **without** a stored category are grouped separately.","The **day table** (under **Advanced**) includes a **non-concurrent** task-time total (timestamped overlap removed) so you can compare it against raw recorded task time.","**Week starts on** (Sunday, Monday, or Saturday): **Settings → Dashboard & API** (default **Sunday**); applies to date-picker calendars and weekly report grids (shortcut also near report calendars).","The weekly **@project** calendar shows a **Daily total** row (sum of project rows). The **#tag** calendar footer is **Recorded time (per task)** — once per task, not the sum of # rows (each # row still shows full duration for WBS mapping).","Values in parentheses (0.25 h) are rounded to the nearest quarter hour (15 min) for timesheet entry. E.g., 1 h 11 min → 1.25 h because 71 min rounds to 75 min = 1.25 h.","Re-launch the **Reports** first-time **tour** from [Settings — Reporting tour](/settings#settings-reporting-tour).","Under the weekly **@ project** calendar, the **Work (@)** / **Personal (!)** switch changes ledger: **Work** (default) excludes personal time; **Personal** shows only personal entries (`personalProject` or a recognized `!` token in the title)."]},{id:"ug-settings-integrations",title:"Settings, safety copies, and extra wiring (when you are ready)",searchIndex:"export backup restore sqlite json gitlab mongo v4 v4-qa v4-dev qa production environment data store next dev local development",paragraphs:["Here you tune how the app **presents** itself (KronoFocus, tags and **@** **advanced** paths, **schedule**) and, only if you want, the **cable** to **Git**, GitLab, a **mirror**… The **danger** **zone** — read the on-screen text and the **type**-**to**-**confirm** line before a full **wipe**. The [Settings page index](/settings#settings-usage-profile) links every section (left-hand **TOC** on a wide window)."],optionsTitle:"What you are likely to find (names can vary with version)",options:["**Usage** profile ([Usage profile section](/settings#settings-usage-profile)): e.g. *manager* hides some developer-heavy **panels** you might still want in *dev* mode.","[KronoFocus](/settings#settings-kronoFocus), [Collection & buffers](/settings#settings-collection), [work schedule](/settings#settings-schedule) or [planned sessions](/settings#settings-planned-sessions), [Tasks & tags](/settings#settings-task-tags) ; [Git](/settings#settings-git) / [MongoDB mirror](/settings#settings-mongo) as **opt-in** (nothing forces you to turn everything on day one).","In [Tasks & tags](/settings#settings-task-tags), the scope migration tool lets you **copy** or **move** a global tag into a project scope (`Project#tag`) and back to global.","**Tasks without #tags**: optional reserved **default** bucket; optional **drop default** when another explicit `#tag` is added ([Tasks & tags](/settings#settings-task-tags)).","With no explicit `#`, a new task gets the reserved **“default”** bucket (reporting); as soon as you add a **`#tag`** (create, title edit, or update), **“default” is removed** — unless you turn off automatic removal under [Tasks & tags](/settings#settings-task-tags).","**Inline tag/project rename**: in the right **Tags / Projects / Templates** column, click the pencil, edit the name in-place, then confirm with **Enter** (**Escape** cancels). A warning explains the reporting impact; you can tick “don’t show again” for future renames. (**`knownPersonalProjects`** for **`!`** tokens does not yet get the same dedicated inline screen as **`@`** projects.)","**Time correction**: **on/off** toggles in [Tasks & tags](/settings#settings-task-tags) for **task** and **session** **start** and **end** times. **Minimum task duration** (minutes, default 30) prefills **end** for **past** or **planned** entry (start rounded to the previous half-hour). On a **running task**, an end time **completes the task** at that instant. On a **live session**, an end time **closes the session** at that instant (history snapshot), like ending with **keep** for open tasks.","**General — production and QA data stores** ([Settings → General](/settings#settings-data-environment)): enable **two vaults** (`v4` production + `v4-qa` for tests); switch with **Prod / QA** in the navigation bar (**immediate**) or the selector on this screen (**Save**). On the **first** switch to QA when no vault exists yet, a modal offers **copy production** or **start empty**. In QA mode, a **purple banner** and **tinted chrome** remind you that data is not production.","**General — local development (data store)** ([Settings → General](/settings#settings-dev-data), only under `next dev`): use the main **Save** button; by default, **dev** uses a **separate** folder (`v4-dev`) from **production**; you can opt into the same `v4` path, then **restart** the dev server. This is separate from **Prod / QA** above (day-to-day packaged or `next start` runs).","**Backup / full restore**: technically `GET /api/backup` exports by **format**, and `POST /api/restore` restores a JSON or SQLite backup file; in the app, use the **Danger zone** controls for guided backup and restore."],stepsTitle:"Before clearing all history (short list)",steps:["Prefer an **export** when the UI or hosting layer offers it (JSON, CSV, or **SQLite** copy, depending on what your stack exposes), or [Export defaults](/settings#settings-export) when the UI offers it.","Re-read the [danger zone](/settings#settings-danger-zone): what **actually** **goes** **away**.","Type the **confirmation** word **exact**ly; use **Cancel** if doubt remains."]}]}}function f(a){let b=a.paragraphs.map(d).join(" "),c=(a.bullets??[]).map(d).join(" "),e=(a.steps??[]).map(d).join(" "),f=(a.options??[]).map(d).join(" ");return`${a.title} ${b} ${c} ${e} ${f} ${a.searchIndex}`.toLowerCase()}c.d(b,{Y:()=>e,a:()=>f})},67227:(a,b,c)=>{"use strict";c.d(b,{PlannedTaskBoundaryConflictWatcher:()=>d});let d=(0,c(77943).registerClientReference)(function(){throw Error("Attempted to call PlannedTaskBoundaryConflictWatcher() from the server but PlannedTaskBoundaryConflictWatcher is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/dashboard/PlannedTaskBoundaryConflictWatcher.tsx","PlannedTaskBoundaryConflictWatcher")},74464:(a,b,c)=>{"use strict";c.d(b,{DashboardToastProvider:()=>g,f:()=>h});var d=c(48249),e=c(67484);let f=(0,e.createContext)(null);function g({children:a}){let[b,c]=(0,e.useState)([]),h=(0,e.useRef)(0),i=(0,e.useCallback)(a=>{let b=a.trim();if(!b)return;let d=++h.current;c(a=>[...a,{id:d,message:b}]),window.setTimeout(()=>{c(a=>a.filter(a=>a.id!==d))},5500)},[]),j=(0,e.useMemo)(()=>({pushToast:i}),[i]);return(0,d.jsxs)(f.Provider,{value:j,children:[a,(0,d.jsx)("div",{className:"pointer-events-none fixed bottom-4 right-4 z-[100] flex w-[min(calc(100vw-2rem),22rem)] flex-col gap-2","aria-live":"polite",children:b.map(a=>(0,d.jsx)("div",{className:"pointer-events-auto rounded-lg border border-zinc-200 bg-white/95 px-4 py-3 text-sm leading-snug text-zinc-800 shadow-lg dark:border-zinc-600 dark:bg-zinc-900/95 dark:text-zinc-100",children:a.message},a.id))})]})}function h(){let a=(0,e.useContext)(f);return a||{pushToast:()=>{}}}},75761:(a,b,c)=>{"use strict";c.d(b,{c:()=>e});var d=c(67484);function e(a,b,c){let[e,f]=(0,d.useState)(null);return"running"===b&&"number"==typeof c&&Number.isFinite(c)?e??Math.max(0,Math.floor(a)):Math.max(0,Math.floor(a))}},76346:(a,b,c)=>{"use strict";c.d(b,{n:()=>f});var d=c(31417),e=c(300);let f=(0,d.v)()((0,e.Zr)(a=>({kronoFocusDurationHistory:[],pushKronoFocusDuration:(b,c)=>a(a=>{var d;let e;return{kronoFocusDurationHistory:(d=a.kronoFocusDurationHistory,(e=Math.max(60,Math.min(28800,Math.floor(b))))===c?d:[e,...d.filter(a=>a!==e)].slice(0,12))}}),clearKronoFocusDurationHistory:()=>a({kronoFocusDurationHistory:[]}),concurrentTaskStartPreference:null,setConcurrentTaskStartPreference:b=>a({concurrentTaskStartPreference:b}),keybindingOverrides:{},setKeybindingOverrides:b=>a({keybindingOverrides:b}),resetKeybindingOverrides:()=>a({keybindingOverrides:{}})}),{name:"kronosys.dashboard.prefs.v2",partialize:a=>({kronoFocusDurationHistory:a.kronoFocusDurationHistory,concurrentTaskStartPreference:a.concurrentTaskStartPreference,keybindingOverrides:a.keybindingOverrides})}))},77071:(a,b,c)=>{"use strict";c.d(b,{PlannedScheduleActivationWatcher:()=>d});let d=(0,c(77943).registerClientReference)(function(){throw Error("Attempted to call PlannedScheduleActivationWatcher() from the server but PlannedScheduleActivationWatcher is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/dashboard/PlannedScheduleActivationWatcher.tsx","PlannedScheduleActivationWatcher")},78335:()=>{},79159:(a,b,c)=>{"use strict";c.d(b,{At:()=>e,Dv:()=>d,_u:()=>f});let d="kronosys-dashboard-semantic-chip-accessible";function e(a){var b;return((b=a.cfg)&&"dashboardSemanticChipAccessibleMode"in b?!0===b.dashboardSemanticChipAccessibleMode:null)??a.stored??!1}function f(a){if("u"<typeof document)return;let b=document.documentElement;a?b.setAttribute("data-kronosys-semantic-chips","accessible"):b.removeAttribute("data-kronosys-semantic-chips")}},79436:(a,b,c)=>{Promise.resolve().then(c.t.bind(c,95547,23)),Promise.resolve().then(c.t.bind(c,15098,23)),Promise.resolve().then(c.t.bind(c,47644,23)),Promise.resolve().then(c.t.bind(c,33859,23)),Promise.resolve().then(c.t.bind(c,98099,23)),Promise.resolve().then(c.t.bind(c,16237,23)),Promise.resolve().then(c.t.bind(c,98562,23)),Promise.resolve().then(c.t.bind(c,36675,23))},82704:()=>{},84490:(a,b,c)=>{"use strict";c.d(b,{KronosysPackageVersionProvider:()=>e});var d=c(77943);let e=(0,d.registerClientReference)(function(){throw Error("Attempted to call KronosysPackageVersionProvider() from the server but KronosysPackageVersionProvider is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/KronosysPackageVersionProvider.tsx","KronosysPackageVersionProvider");(0,d.registerClientReference)(function(){throw Error("Attempted to call useKronosysPackageVersion() from the server but useKronosysPackageVersion is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/KronosysPackageVersionProvider.tsx","useKronosysPackageVersion")},84735:(a,b,c)=>{"use strict";c.d(b,{PlannedScheduleActivationWatcher:()=>i});var d=c(67484),e=c(24682),f=c(74464),g=c(59899),h=c(55017);function i(){let{payload:a}=(0,e.y)(),{pushToast:b}=(0,f.f)(),[c,i]=(0,d.useState)(()=>Date.now());(0,d.useRef)(null),(0,d.useRef)(null);let j=a?.current,k=h.h.getState().lang,l=j?.language==="fr"?"fr":"en";return(0,g.z)(k??l),null}c(43894)},85242:(a,b,c)=>{"use strict";c.d(b,{LightThemeVariantSync:()=>e}),c(67484);var d=c(24682);function e(){let{payload:a}=(0,d.y)();return null}c(48516),c(31162)},85516:(a,b,c)=>{Promise.resolve().then(c.t.bind(c,81921,23)),Promise.resolve().then(c.t.bind(c,60440,23)),Promise.resolve().then(c.t.bind(c,84342,23)),Promise.resolve().then(c.t.bind(c,82265,23)),Promise.resolve().then(c.t.bind(c,35421,23)),Promise.resolve().then(c.t.bind(c,61335,23)),Promise.resolve().then(c.t.bind(c,70664,23)),Promise.resolve().then(c.bind(c,74661))},88987:(a,b,c)=>{"use strict";c.d(b,{NH:()=>m,qR:()=>l,qS:()=>k});var d=c(48249),e=c(67484),f=c(74429),g=c(11001);let h="z-[250]";function i({children:a}){return"u"<typeof document?null:(0,f.createPortal)(a,document.body)}function j(a){let[b,c]=(0,e.useState)(a),[d,f]=(0,e.useState)(a);return{shouldRender:b,visible:d}}function k({open:a,title:b,message:c,okLabel:f,onClose:l}){let m=(0,e.useId)(),n=(0,e.useId)(),{shouldRender:o,visible:p}=j(a);return o?(0,d.jsx)(i,{children:(0,d.jsx)("div",{className:`fixed inset-0 ${h} flex items-center justify-center bg-black/60 p-4 transition-opacity duration-150 ease-out motion-reduce:transition-none ${p?"opacity-100":"opacity-0"}`,role:"alertdialog","aria-modal":"true","aria-labelledby":b?m:n,"aria-describedby":b?n:void 0,children:(0,d.jsxs)("div",{className:`max-h-[90vh] w-full max-w-md overflow-y-auto rounded-xl border border-zinc-200 bg-white p-5 shadow-xl transition-all duration-150 ease-out motion-reduce:transition-none dark:border-zinc-700 dark:bg-zinc-900 ${p?"translate-y-0 scale-100 opacity-100":"translate-y-1 scale-[0.985] opacity-0"}`,children:[b?(0,d.jsx)("h2",{id:m,className:"text-lg font-semibold text-zinc-900 dark:text-zinc-100",children:b}):null,(0,d.jsx)("p",{id:n,className:`whitespace-pre-wrap text-sm leading-relaxed text-zinc-600 dark:text-zinc-300 ${b?"mt-3":""}`,children:c}),(0,d.jsx)("div",{className:"mt-6 flex justify-end",children:(0,d.jsx)("button",{type:"button",className:g.Sx,onClick:l,children:f})})]})})}):null}function l({open:a,title:b,message:c,cancelLabel:f,confirmLabel:k,confirmVariant:m="neutral",dismissCheckbox:n,typeToConfirm:o,extra:p,pending:q=!1,onCancel:r,onConfirm:s}){let t=(0,e.useId)(),u=(0,e.useId)(),v=(0,e.useId)(),[w,x]=(0,e.useState)(""),{shouldRender:y,visible:z}=j(a);if(!y)return null;let A=!o||w===o.expected,B="danger"===m?g.fO:g.Sx;return(0,d.jsx)(i,{children:(0,d.jsx)("div",{className:`fixed inset-0 ${h} flex items-center justify-center bg-black/60 p-4 transition-opacity duration-150 ease-out motion-reduce:transition-none ${z?"opacity-100":"opacity-0"}`,role:"dialog","aria-modal":"true","aria-labelledby":b?t:u,"aria-describedby":b?u:void 0,children:(0,d.jsxs)("div",{className:`max-h-[90vh] w-full max-w-md overflow-y-auto rounded-xl border border-zinc-200 bg-white p-5 shadow-xl transition-all duration-150 ease-out motion-reduce:transition-none dark:border-zinc-700 dark:bg-zinc-900 ${z?"translate-y-0 scale-100 opacity-100":"translate-y-1 scale-[0.985] opacity-0"}`,children:[b?(0,d.jsx)("h2",{id:t,className:"text-lg font-semibold text-zinc-900 dark:text-zinc-100",children:b}):null,(0,d.jsx)("p",{id:u,className:`whitespace-pre-wrap text-sm leading-relaxed text-zinc-600 dark:text-zinc-300 ${b?"mt-3":""}`,children:c}),n?(0,d.jsxs)("label",{className:"mt-4 flex cursor-pointer items-start gap-2.5 text-sm text-zinc-600 dark:text-zinc-400",children:[(0,d.jsx)("input",{type:"checkbox",className:"mt-0.5 size-4 shrink-0 rounded border-zinc-300 bg-white text-violet-600 focus:ring-2 focus:ring-violet-500/50 dark:border-zinc-600 dark:bg-zinc-950",checked:n.checked,disabled:q,onChange:a=>n.onChange(a.target.checked)}),(0,d.jsx)("span",{className:"leading-snug",children:n.label})]}):null,p?(0,d.jsx)("div",{className:"mt-4",children:p}):null,o?(0,d.jsxs)("div",{className:"mt-4 space-y-2",children:[(0,d.jsx)("p",{className:"text-sm leading-relaxed text-zinc-600 dark:text-zinc-400",children:o.instruction}),(0,d.jsx)("label",{htmlFor:v,className:"block text-xs font-semibold uppercase tracking-wide text-zinc-500",children:o.label}),(0,d.jsx)("input",{id:v,type:"text",value:w,onChange:a=>x(a.target.value),placeholder:o.expected,disabled:q,className:"w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 font-mono text-sm text-zinc-900 outline-none ring-violet-500/30 focus:ring-2 disabled:opacity-50 dark:border-zinc-600 dark:bg-zinc-950 dark:text-zinc-100",autoComplete:"off",spellCheck:!1,"aria-label":o.inputAriaLabel})]}):null,(0,d.jsxs)("div",{className:"mt-6 flex flex-wrap justify-end gap-2",children:[(0,d.jsx)("button",{type:"button",className:"rounded-lg border border-zinc-300 px-4 py-2 text-sm text-zinc-700 hover:bg-zinc-100 disabled:opacity-50 dark:border-zinc-600 dark:text-zinc-300 dark:hover:bg-zinc-800",disabled:q,onClick:r,children:f}),(0,d.jsx)("button",{type:"button",className:`${B} disabled:cursor-not-allowed disabled:opacity-40`,disabled:!A||q,onClick:()=>{A&&!q&&s()},children:k})]})]})})})}function m({open:a,title:b,message:c,dismissLabel:f,tertiaryLabel:k,secondaryLabel:l,primaryLabel:n,primaryVariant:o="danger",dismissCheckbox:p,onDismiss:q,onTertiary:r,onSecondary:s,onPrimary:t}){let u=(0,e.useId)(),v=(0,e.useId)(),{shouldRender:w,visible:x}=j(a);if(!w)return null;let y="danger"===o?g.fO:g.Sx;return(0,d.jsx)(i,{children:(0,d.jsx)("div",{className:`fixed inset-0 ${h} flex items-center justify-center bg-black/60 p-4 transition-opacity duration-150 ease-out motion-reduce:transition-none ${x?"opacity-100":"opacity-0"}`,role:"dialog","aria-modal":"true","aria-labelledby":b?u:v,"aria-describedby":b?v:void 0,children:(0,d.jsxs)("div",{className:`max-h-[90vh] w-full max-w-md overflow-y-auto rounded-xl border border-zinc-200 bg-white p-5 shadow-xl transition-all duration-150 ease-out motion-reduce:transition-none dark:border-zinc-700 dark:bg-zinc-900 ${x?"translate-y-0 scale-100 opacity-100":"translate-y-1 scale-[0.985] opacity-0"}`,children:[b?(0,d.jsx)("h2",{id:u,className:"text-lg font-semibold text-zinc-900 dark:text-zinc-100",children:b}):null,(0,d.jsx)("p",{id:v,className:`whitespace-pre-wrap text-sm leading-relaxed text-zinc-600 dark:text-zinc-300 ${b?"mt-3":""}`,children:c}),p?(0,d.jsxs)("label",{className:"mt-4 flex cursor-pointer items-start gap-2.5 text-sm text-zinc-600 dark:text-zinc-400",children:[(0,d.jsx)("input",{type:"checkbox",className:"mt-0.5 size-4 shrink-0 rounded border-zinc-300 bg-white text-violet-600 focus:ring-2 focus:ring-violet-500/50 dark:border-zinc-600 dark:bg-zinc-950",checked:p.checked,onChange:a=>p.onChange(a.target.checked)}),(0,d.jsx)("span",{className:"leading-snug",children:p.label})]}):null,(0,d.jsxs)("div",{className:"mt-6 flex flex-wrap justify-end gap-2",children:[(0,d.jsx)("button",{type:"button",className:"rounded-lg border border-zinc-300 px-4 py-2 text-sm text-zinc-700 hover:bg-zinc-100 dark:border-zinc-600 dark:text-zinc-300 dark:hover:bg-zinc-800",onClick:q,children:f}),k&&r?(0,d.jsx)("button",{type:"button",className:"rounded-lg border border-violet-400/60 bg-violet-500/10 px-4 py-2 text-sm font-medium text-violet-900 hover:bg-violet-500/16 dark:border-violet-400/45 dark:bg-violet-950/45 dark:text-violet-100 dark:hover:bg-violet-950/70",onClick:()=>void r(),children:k}):null,(0,d.jsx)("button",{type:"button",className:g.Sx,onClick:()=>void s(),children:l}),(0,d.jsx)("button",{type:"button",className:y,onClick:()=>void t(),children:n})]})]})})})}},89806:(a,b,c)=>{"use strict";function d(){return null}c.d(b,{PwaRegister:()=>d}),c(67484)},90595:(a,b,c)=>{"use strict";c.d(b,{SemanticChipAccessibleModeSync:()=>d});let d=(0,c(77943).registerClientReference)(function(){throw Error("Attempted to call SemanticChipAccessibleModeSync() from the server but SemanticChipAccessibleModeSync is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/SemanticChipAccessibleModeSync.tsx","SemanticChipAccessibleModeSync")},90665:(a,b,c)=>{"use strict";c.d(b,{DocumentTitleSync:()=>d});let d=(0,c(77943).registerClientReference)(function(){throw Error("Attempted to call DocumentTitleSync() from the server but DocumentTitleSync is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/DocumentTitleSync.tsx","DocumentTitleSync")},91355:(a,b,c)=>{"use strict";function d(a,b){let c="string"==typeof b?b.trim():"";if(!c)return a;let d=a.indexOf("#"),e=d>=0?a.slice(0,d):a,f=d>=0?a.slice(d):"",g=e.includes("?")?"&":"?";return`${e}${g}session=${encodeURIComponent(c)}${f}`}function e(a,b,c){let d=new URLSearchParams(b);null===c||""===c?d.delete("session"):d.set("session",c);let e=d.toString();return e?`${a}?${e}`:a}c.d(b,{c:()=>d,q:()=>e})},91592:(a,b,c)=>{"use strict";c.d(b,{x:()=>g});let d=[{version:"1.0.0-beta.48",items:["**T\xe2ches planifi\xe9es exclues** : les t\xe2ches planifi\xe9es (d\xe9but dans le futur) ne sont plus compt\xe9es dans les totaux de temps enregistr\xe9 (grilles par \xe9tiquette, par projet, et breakdown par session).","**Scope projet sur le breakdown session** : le breakdown par session respecte maintenant le filtre work/personal/all, alignant ses totaux avec les grilles par \xe9tiquette et par projet.","**D\xe9tails de t\xe2che — session unique** : la modale de d\xe9tails d'une t\xe2che n'affiche plus qu'une seule session (celle avec la dur\xe9e la plus \xe9lev\xe9e) au lieu de lister toutes les sessions contenant un snapshot de la t\xe2che.","**Tableau d'anomalies** : nouvelle section dans l'onglet Avanc\xe9 d\xe9tectant 7 types d'anomalies (sessions sans t\xe2ches, t\xe2ches sans dur\xe9e, dur\xe9es > 24 h, chevauchements, t\xe2ches dupliqu\xe9es entre sessions, \xe9carts dur\xe9e session vs somme t\xe2ches).","**Totaux align\xe9s** : le footer du Gantt somme maintenant par t\xe2che unique (pas par lap), ce qui correspond au total affich\xe9 dans le panneau lat\xe9ral de session. Le nombre de t\xe2ches est affich\xe9.","**Alignement horizontal** : les lignes de noms et de barres utilisent une hauteur fixe identique (`h-11`) — plus de d\xe9calage vertical entre les deux colonnes.","**Popover d\xe9tails** : au survol du nom d'une t\xe2che, un popover affiche le nom complet, le projet, les heures d\xe9but/fin et la dur\xe9e track\xe9e.","**Prolongation de t\xe2che termin\xe9e** : lorsqu'une t\xe2che termin\xe9e est rouverte (heure de fin repouss\xe9e), les ancres de minuteur (`MAIN_TIMER_SEGMENT_STARTED_AT`, `TASK_CURRENT_LAP_STARTED_AT`) sont positionn\xe9es \xe0 `nowMs` au lieu de rester vides. Cela emp\xeache la cr\xe9ation d'un nouveau lap qui chevaucherait l'ancien.","**Affichage \xe9tiquettes scop\xe9es** : `formatTagDisplay` n'ajoute plus le pr\xe9fixe `@` pour les \xe9tiquettes `projet#code` (ex. `acme#dev` reste `acme#dev`, pas `@acme#dev`).","**Activation minuteur planifi\xe9** : `activateDuePlannedTaskTimersInSession` ancre le minuteur au `startTime` de la t\xe2che (pas `nowMs`) pour que la dur\xe9e s'accumule correctement depuis le d\xe9but planifi\xe9.","next 16.2.3 → 16.2.9, react 19.2.4 → 19.2.7, react-dom 19.2.4 → 19.2.7, eslint-config-next 16.2.3 → 16.2.9, plus mises \xe0 jour semver-range (playwright, tailwindcss, date-fns, lucide-react, vitest, etc.)."]},{version:"1.0.0-beta.47",items:["**Correction d\xe9but/fin** : lorsqu’une session **cl\xf4tur\xe9e** a ses bornes modifi\xe9es, `sessionDurationMinutes` est recalcul\xe9e \xe0 partir de la **nouvelle plage** en conservant l’\xe9cart de pause implicite (plus seulement un delta qui laissait une dur\xe9e obsol\xe8te, p. ex. 24 h pour une fen\xeatre de 8 h 30). \xc0 la **cl\xf4ture live** avec une fin pass\xe9e, la dur\xe9e est **plafonn\xe9e** au span mural `d\xe9but → fin`."]},{version:"1.0.0-beta.46",items:["**Tri chronologique** : les t\xe2ches planifi\xe9es sont maintenant affich\xe9es de la plus proche (en haut) \xe0 la plus \xe9loign\xe9e (en bas), tri\xe9es par `startTime` ascendant.","**Compteur \xe0 z\xe9ro** : les t\xe2ches planifi\xe9es affichent `0:00` au lieu de leur dur\xe9e planifi\xe9e, puisqu'elles n'ont pas encore d\xe9marr\xe9."]},{version:"1.0.0-beta.45",items:["**Bouton +N min** : dans la carte lat\xe9rale et la liste des sessions, un bouton ambre prolonge la session de N minutes (configurable via `dashboardSessionExtendMinutes`, d\xe9faut 30).",'**Fin auto planifi\xe9e** : le mode "Planifi\xe9" de la nouvelle session calcule automatiquement la fin \xe0 `d\xe9but + heures de base` (configurable via `dashboardBaseDailyHours`).',"**Nouveau param\xe8tre** : `dashboardSessionExtendMinutes` (30 par d\xe9faut) dans les param\xe8tres serveur.","**Minuteur t\xe2che temps r\xe9el** : correction du red\xe9marrage toutes les 2 secondes — `derivedLiveBaseMs` utilise d\xe9sormais `task.durationMs` quand il n'y a pas de laps, au lieu de repartir de z\xe9ro.","**Heure de fin sur t\xe2che temps r\xe9el** : le champ `taskEndDraft` n'est plus auto-rempli avec `startTime + dur\xe9e mini` pour les t\xe2ches sans heure de fin explicite.","**Suggestions de mod\xe8les invisibles** : la liste `<ul>` \xe9tait rendue dans un anc\xeatre avec `backdrop-filter`, ce qui brisait le positionnement `fixed`. Passage par `createPortal` → `document.body`.","**Format `@projet#tag` dans les mod\xe8les** : les tags scop\xe9s sont maintenant format\xe9s correctement (`@acme#dev` au lieu de `#acme#dev`) et le projet implicite n'est plus dupliqu\xe9.",'**Autocomplete navigateur d\xe9sactiv\xe9** : `autoComplete="off"` sur le champ titre de t\xe2che pour ne plus m\xe9langer suggestions navigateur et mod\xe8les Kronosys.',"**D\xe9filement panneaux lat\xe9raux** : \xe9couteur `scroll` ajout\xe9 dans `DashboardSideDrawerTopSync` + `overflow-y-auto` sur le `<nav>` de la liste des sessions.",'**Titre panneau droit** : mis \xe0 jour en "\xc9tiquettes, projets et mod\xe8les" (FR) / "Tags, projects & templates" (EN).']},{version:"1.0.0-beta.44",items:["**Before/After payload** : chaque action enregistre maintenant un snapshot JSON de la session live avant et apr\xe8s l'ex\xe9cution. Dans `/logs`, cliquez sur une ligne pour voir le d\xe9tail (requ\xeate, \xe9tat avant, \xe9tat apr\xe8s)."]},{version:"1.0.0-beta.43",items:['**T\xe2ches planifi\xe9es** : les t\xe2ches dont le d\xe9but est dans le futur s\'affichent avec un style distinct (fond sky, bordure pointill\xe9e, pastille "Planifi\xe9" dans la colonne des noms). L\xe9gende mise \xe0 jour.',"**Correction d\xe9rive affichage minuteur** : si `mainTimerSegmentStartedAt` est ant\xe9rieur \xe0 `startTime`, le calcul utilise `startTime` comme borne minimale → plus de dur\xe9es gonfl\xe9es."]},{version:"1.0.0-beta.42",items:["**Ajout de laps manuel** : nouvelle action serveur `addTaskTimerLap` pour ins\xe9rer un laps dans une t\xe2che existante, avec recalcule de `durationMs`. Permet de combler les trous dans la frise sans recr\xe9er une t\xe2che.","**Clic sur les trous** : cliquez sur une zone vide du Gantt pour ajouter une t\xe2che \xe0 cet instant pr\xe9cis.","**Suppression de t\xe2che** : le bouton Corbeille est r\xe9activ\xe9 dans la modale d'inspection des t\xe2ches (Rapports), avec confirmation de suppression."]},{version:"1.0.0-beta.41",items:["**Timeline dans Rapports** : s\xe9lectionnez une journ\xe9e dans le tableau \xab Recorded time by project \xbb pour afficher le Gantt (t\xe2ches, laps, barres). Bouton \xab + Ajouter une t\xe2che \xbb pour ajouter une t\xe2che oubli\xe9e \xe0 une session de la journ\xe9e. Navigation par semaine int\xe9gr\xe9e.","**Gantt — colonne sticky** : les noms de t\xe2ches restent fixes au scroll horizontal (tableau → `position: sticky`).","**Gantt — barres cliquables** : cliquez sur une barre pour ouvrir la modale de modification de la t\xe2che.","**Gantt — fen\xeatre temporelle** : d\xe9but 30 min avant la session, fin 30 min apr\xe8s (ou fin de journ\xe9e si session live). Scroll automatique \xe0 la premi\xe8re t\xe2che.","**Boutons Today/Now** : \xab Today \xbb conserve l'heure s\xe9lectionn\xe9e (ne change que la date) ; \xab Now \xbb met date et heure \xe0 l'instant courant.","**Scroll restoration** : la sauvegarde/restauration de position dans Rapports ne s'ex\xe9cute qu'au premier chargement, plus de fighting avec le scroll.",'**Variance nette** : la colonne totale de la ligne "\xc9cart" affiche maintenant la diff\xe9rence nette entre le temps enregistr\xe9 et les heures de base (ex. `+2 h 30 min`) au lieu des heures de base seules, avec la m\xeame colorim\xe9trie que les cellules individuelles.']},{version:"1.0.0-beta.39",items:["**Gantt \xab Aujourd'hui \xbb** : les laps des t\xe2ches \xe9taient perdus dans la vue \xab Today timeline \xbb — une seule barre apparaissait par t\xe2che au lieu d'une barre par lap. Corrig\xe9 en copiant `taskTimerLaps` et `taskCurrentLapStartedAt` dans les t\xe2ches merg\xe9es."]},{version:"1.0.0-beta.38",items:["**@default** : les t\xe2ches sans projet explicite re\xe7oivent automatiquement le projet `@default` pour un suivi \xe9quilibr\xe9 dans les rapports.","**Avertissement** : un bandeau appara\xeet dans *Billing allocation* quand du temps est allou\xe9 \xe0 `@default`.","**Heures de base** : nouveau champ configurable dans *Settings* (d\xe9faut 7,5 h/jour) avec tol\xe9rance (d\xe9faut \xb110 min).",'**Ligne d\'\xe9cart** : dans *Recorded time by project*, une ligne "\xc9cart" compare le total journalier aux heures de base. Color\xe9e en \uD83D\uDD34\uD83D\uDFE2\uD83D\uDFE0 selon le seuil de tol\xe9rance.',"**Arrondi quart d'heure** : chaque cellule dur\xe9e affiche l'arrondi au 15 min entre parenth\xe8ses (ex. `31 min 55 s (0,50 h)`).","**Chevron align\xe9** : le bouton collapse/expand est maintenant \xe0 droite du nom du projet dans le tableau, pour un alignement vertical parfait.","**Abr\xe9viation** : toutes les dates (sessions, t\xe2ches, Gantt) incluent le jour de la semaine (ex. `lun. 2026-06-03`).","**Inspecteur persistant** : le panneau de d\xe9tail des t\xe2ches (clic sur une cellule dur\xe9e) ne se ferme plus au clic \xe0 l'ext\xe9rieur — permet des modifications multiples sans rouvrir.","**R\xe9sum\xe9 session** : l'en-t\xeate du panneau affiche maintenant les bornes d\xe9but/fin de la session concern\xe9e, pour \xe9viter de corriger des entr\xe9es hors p\xe9riode.","**Timer t\xe2che planifi\xe9e** : le minuteur n'affiche plus la dur\xe9e totale depuis le d\xe9but pr\xe9vu au moment de l'activation (ex. 30 min pour une t\xe2che 9h30 activ\xe9e \xe0 10h). Il d\xe9marre maintenant pr\xe8s de z\xe9ro et s'accumule progressivement.","**Conflit concurrent** : la modale de conflit ne s'affiche plus quand on ajoute une t\xe2che pass\xe9e (mode *past*) alors qu'une t\xe2che est active dans la session live.","**S\xe9lecteur de mode t\xe2che** : les ic\xf4nes Temps r\xe9el (⚡) et Pass\xe9 (\uD83D\uDD50) ont maintenant un anneau violet (`ring-2`) quand elles sont s\xe9lectionn\xe9es, pour un rep\xe8re visuel clair sur les deux th\xe8mes.","**Ic\xf4nes plus nettes** : dimensions des boutons ic\xf4nes pass\xe9es de `rem` \xe0 `px` (`30px`), `strokeWidth` uniformis\xe9 \xe0 `2`, et `box-sizing: border-box` ajout\xe9 — \xe9limine le flou d\xfb aux dimensions fractionnaires.","**Format chronom\xe8tre** : le temps est toujours affich\xe9 `HH:MM:SS.cc` (ex. `00:02:00.00` au lieu de `2:00.00`) pour \xe9viter la confusion entre minutes et heures."]},{version:"1.0.0-beta.37",items:["**Migration compl\xe8te** : toutes les pr\xe9f\xe9rences locales (`localStorage`) sont d\xe9sormais g\xe9r\xe9es par **Zustand** avec middleware `persist`, rempla\xe7ant le pattern manuel `useState` + `useEffect` + `read/write`. 8 stores, ~200 lignes de code en moins.","**Vue active** (Allocation / Rythme / Avanc\xe9) : conserv\xe9e entre les visites.","**Scope Travail/Personnel** : m\xe9moris\xe9.","**Filtres p\xe9riode et tags** : persist\xe9s.","**D\xe9tail des sections** (d\xe9pli\xe9/repli\xe9) : conserv\xe9.","**Position de d\xe9filement** : restaur\xe9e en revenant sur la page (sauvegard\xe9e par onglet).","**194 issues utilisateur** cr\xe9\xe9es sur GitLab \xe0 partir des *user stories* de la page `/implementation`.","**Labels** : `group::*` (8 groupes), `implemented`, `integration-checked`, `e2e-checked`, `discarded`.","**Synchro au build** : `npm run build` met \xe0 jour `implementationNotes.ts` depuis GitLab (si token configur\xe9), les flags `implemented`/`integrationChecked`/`e2eChecked` sont align\xe9s sur les labels GitLab.","**D\xe9pendance** : `zustand` (state management).","**Refactor** : 6 anciens fichiers de stockage localStorage supprim\xe9s, ~150 lignes de hooks et `useEffect` retir\xe9es.","**Pipeline** : la commande `build` inclut d\xe9sormais `node scripts/sync-implementation.mjs` avant Next build."]},{version:"1.0.0-beta.36",items:["**D\xe9filement (xl+)** : la liste des sessions d\xe9file **dans le tiroir** (une seule zone scroll) ; la carte session s\xe9lectionn\xe9e reste fixe au-dessus de la liste quand elle y est affich\xe9e. Corrige le double scroll ou le d\xe9filement bloqu\xe9 avec les tiroirs lat\xe9raux.","**Dur\xe9e session** (correction d\xe9but/fin) : l'ajustement du d\xe9but ou de la fin d'une session modifie `sessionDurationMinutes` par **\xe9cart** (delta) au lieu de recalculer toute la plage `d\xe9but → fin` — le temps de pause reste donc d\xe9duit quand on recale les bornes.","**Finalisation intempestive** : le s\xe9lecteur date/heure ne conserve plus des `hour`/`minute` obsol\xe8tes du montage initial — un `useEffect` rafra\xeechit les parties \xab maintenant \xbb \xe0 chaque ouverture, ce qui \xe9vite la soumission involontaire d'un horaire pass\xe9 et la finalisation de session au moment de choisir une fin future.","**Affichage dur\xe9e** : le panneau session pr\xe9f\xe8re la valeur serveur `sessionDurationMinutes` (qui d\xe9duit les pauses) \xe0 la d\xe9rivation `endAt − startAt` c\xf4t\xe9 client.","**Saisie automatique des horaires** : lorsqu'un mod\xe8le fournit `lastUsedStartTime` et `lastUsedEndTime`, la modale horaire est **contourn\xe9e** ; les cr\xe9neaux (d\xe9cal\xe9s sur la journ\xe9e courante) et la dur\xe9e du minuteur sont pr\xe9remplis directement dans le lanceur — l'utilisateur peut valider imm\xe9diatement par **Entr\xe9e**, sans confirmation interm\xe9diaire.","**Point vert dans la barre d'outils** : un **point vert puls\xe9** appara\xeet dans la barre de navigation (\xe0 c\xf4t\xe9 des ic\xf4nes de route) lorsqu'une **version plus r\xe9cente** est disponible sur le registre npm. Au survol, un tooltip affiche le num\xe9ro de version (`vX.Y.Z`) ; un clic m\xe8ne au **changelog** (`/changelog`). La v\xe9rification est mise en cache **1 heure** c\xf4t\xe9 serveur (`GET /api/version-check`) et rafra\xeechie toutes les heures c\xf4t\xe9 client.","**Dur\xe9e session delta** : trois tests unitaires (`server/actionDispatch.test.ts`) v\xe9rifient que `setSessionStartTime` et `setSessionEndTime` ajustent `sessionDurationMinutes` par \xe9cart (delta) plut\xf4t que par recalcul int\xe9gral — y compris pour une session live avec pause.","**Comparaison semver** : `lib/semverCompare.test.ts` — `isNewerVersion` couvre majeurs, mineurs, correctifs, pr\xe9release (beta.N) et formats invalides (8 cas).","**Guide utilisateur** : mod\xe8les de t\xe2che — contournement de la modale quand les horaires sont fournis par le mod\xe8le (`lib/userGuideCopy.ts`, `docs/USER_GUIDE.md`).","**Impl\xe9mentation** : `lib/implementationNotes.ts`, `docs/IMPLEMENTATION_DETAILS.md` — p\xe9rim\xe8tre **1.0.0-beta.36** (nouvelle story **indicateur version**, flags `integrationChecked` sur correction horodatage)."]},{version:"1.0.0-beta.35",items:["**Dur\xe9e totale planifi\xe9e** : affich\xe9e seulement lorsqu’une session live a une **fin planifi\xe9e** (`scheduledEndAt`) ; ligne masqu\xe9e sinon. **Total planifi\xe9 (t\xe2ches)** : idem — uniquement s’il existe des t\xe2ches encore planifi\xe9es.","**D\xe9but / fin** sur les cartes (planifi\xe9es, en cours, termin\xe9es) : **m\xeame interaction** que le lanceur en mode pass\xe9 — bouton r\xe9sum\xe9 **d\xe9but → fin** ouvrant une **seule modale** avec les deux calendriers **inline** (plus de popover/modale empil\xe9e) ; **fin facultative** ; dur\xe9e du minuteur affich\xe9e seulement si une fin est renseign\xe9e. **Laps de suivi** : m\xeame bouton et modale, avec le **#** et la **dur\xe9e** du lap sur la ligne. **Nouvelle session** : calendriers pass\xe9 / imm\xe9diat \xe9galement inline dans la modale.","**Allocation facturation** : le KPI **Temps de t\xe2che enregistr\xe9** refl\xe8te le **total de la semaine affich\xe9e** (navigation de semaine), pas toute la plage filtr\xe9e.","**Vues** : trois **cartes centr\xe9es** (Allocation facturation, Rythme, Avanc\xe9) avec une courte description de l’objectif de chaque vue.","**Aide (?)** : **un seul** bouton d’aide par section (grilles #/@, graphiques, synth\xe8se, tableau journalier, etc.) ; sous-titres \xab Calendrier hebdomadaire \xbb redondants retir\xe9s.","**Mise en page** : sections **Temps par \xe9tiquette** et **Temps par projet** align\xe9es (m\xeame encadr\xe9, m\xeame indentation des colonnes).","**Guide utilisateur** : modale horaire unique (calendriers inline, fin facultative), laps de suivi, rapports et totaux planifi\xe9s session (`lib/userGuideCopy.ts`, `docs/USER_GUIDE.md`).","**Impl\xe9mentation** : `lib/implementationNotes.ts`, `docs/IMPLEMENTATION_DETAILS.md` — p\xe9rim\xe8tre **1.0.0-beta.35**.","Release **1.0.0-beta.35** : `npm test`, `npm run changelog:build`, `npm run pack:release`, `npm run release:verify` (voir `.cursor/rules/release-workflow.mdc`)."]},{version:"1.0.0-beta.34",items:["**Correctif tarball** : le paquet npm embarque un **changelog in-app** et un **`kronosys-package-meta.json`** align\xe9s sur la version semver du paquet (corrige **1.0.0-beta.33**, publi\xe9e avec un build stale affichant encore **beta.32** dans le changelog et la version standalone).","**Garde-fous release** (obligatoires avant publish) :","`scripts/lib/releaseVersionAlignment.mjs` — logique partag\xe9e + tests ;","`verify-standalone-pack-alignment.mjs` — pr\xe9-pack : semver, lockfile, m\xe9ta standalone, changelog embarqu\xe9 ;","`verify-packed-tarball.mjs` — post-pack : contenu r\xe9el du `.tgz` ;","`pack-with-zip.sh` — build explicite → v\xe9rif pr\xe9-pack → `npm pack --ignore-scripts` → v\xe9rif tarball ;","`prepublishOnly` — rebuild + v\xe9rif standalone si publish sans tarball pr\xe9-construit ;","`sync-standalone-assets.mjs` — auto-v\xe9rif apr\xe8s \xe9criture du m\xe9ta-fichier."]},{version:"1.0.0-beta.33",items:["**Sessions** (gauche) et **\xc9tiquettes / projets** (droite) : tiroirs **coll\xe9s au bord du viewport** (`left` / `right` : 0 + encoche safe-area) au lieu d’\xeatre d\xe9cal\xe9s vers le centre du conteneur max 1920px ; largeur ouverte toujours proportionnelle (**1fr** de l’ancienne grille `1fr / 2,25fr / 1fr`, calcul\xe9e sur **100vw**). La colonne **T\xe2ches** reste centr\xe9e dans le flux ; repli\xe9 : bande **2,75 rem** au bord d’\xe9cran. Mode focus inchang\xe9 (alignement bord + repli haut).","**Mode pass\xe9 / archive** : bouton **R\xe9gler d\xe9but, fin et dur\xe9e…** ouvrant une **modale** (d\xe9but, fin, dur\xe9e du minuteur) — plus de bloc horaire inline dans le lanceur ; les calendriers internes s’ouvrent en popover ancr\xe9 dans cette modale.","**Mod\xe8les et titres r\xe9currents** : liste d\xe9roulante **pleine largeur** de la ligne titre (remplace le `datalist` natif \xe9troit) ; filtrage diff\xe9r\xe9 inchang\xe9 ; m\xe9morisation des **derni\xe8res heures de d\xe9but/fin** utilis\xe9es (r\xe9appliqu\xe9es sur la **journ\xe9e courante** \xe0 la s\xe9lection, mode pass\xe9).","**Carte t\xe2che — horaires** : calendriers **d\xe9but** / **fin** (et laps) en **modale centr\xe9e** plein \xe9cran (portail `document.body`, plus de popover rogn\xe9 dans la carte) ; question d’**ajustement de dur\xe9e** uniquement \xe0 la modification de la **fin** ; le **d\xe9but** s’applique directement et **r\xe9aligne** le lap en cours (minuteur actif ou en pause) sur le nouveau d\xe9but ; t\xe2che **termin\xe9e** \xe0 un seul lap : le lap suit les bornes corrig\xe9es. **Correctif** : \xe0 la terminaison, `durationMs` est **r\xe9concili\xe9** sur la somme des laps (\xe9vite l’affichage 1 h pour un cr\xe9neau 10:30→11:00 avec lap 30 min).","**Points de d\xe9tail** : lien **Ajouter un point de d\xe9tail** (comme **Ajouter une note**) tant qu’il n’y en a aucun ; le champ d’ajout n’appara\xeet qu’apr\xe8s clic ou lorsqu’au moins un point est d\xe9j\xe0 list\xe9.","**Correctif terminer une t\xe2che** : une t\xe2che **termin\xe9e** (bouton Terminer) n’appara\xeet plus \xe0 tort dans **En pause** lorsque la pile active contenait des copies dupliqu\xe9es du m\xeame identifiant.","**Correctif lanceur pass\xe9** : le bascule **Temps r\xe9el / Pass\xe9** et les champs d\xe9but/fin/dur\xe9e restent accessibles **sans session live** (ex. apr\xe8s cl\xf4ture) ; l’ajout d’une t\xe2che pass\xe9e **cr\xe9e la session** automatiquement si besoin.","**Correctif minuteur t\xe2che planifi\xe9e** : apr\xe8s correction du **d\xe9but** (alignement au cr\xe9neau), le gros compteur vert ne **double** plus le temps (ex. ~58 min affich\xe9es pour ~28 min r\xe9elles) ; une **fin planifi\xe9e future** ne gonfle plus `durationMs` sur toute la plage lors du recalcul des bornes.","**Guide utilisateur** : modale **entr\xe9e pass\xe9e** (lanceur), calendriers modale sur cartes t\xe2che, tiroirs bord viewport, correctifs minuteur / terminaison (`lib/userGuideCopy.ts`, `docs/USER_GUIDE.md`)."]},{version:"1.0.0-beta.32",items:["**Fin planifi\xe9e / fin renseign\xe9e** : la **barre de progression** est sur la **m\xeame ligne** que **D\xe9but** et **Fin** (\xe0 droite), au lieu d’une ligne pleine largeur en dessous.","**Note libre** : lien **Ajouter une note** / **Add a note** pour afficher le champ ; si la note est **vide**, le bloc est masqu\xe9 (carte et lanceur). Au **lanceur**, le champ source n’appara\xeet qu’apr\xe8s ouverture explicite du lien (brouillon non vide sans \xe9diteur ouvert reste masqu\xe9). Une note **enregistr\xe9e** sur une carte reste affich\xe9e en lecture (clic pour modifier) ; aide Markdown **(?)** \xe0 c\xf4t\xe9 du lien ou du champ.","**Correctif note au lanceur** : suppression de l’aper\xe7u Markdown sous le champ pendant la saisie — le texte n’appara\xeet plus en double (source + rendu).","**Espacement** : r\xe9duction de l’\xe9cart entre la note et le bloc **sous-t\xe2ches**.","**Disposition align\xe9e sur les cartes** : mode maintenant/pass\xe9, KronoFocus, aide et pastilles projet / `#\xe9tiquettes` **en haut \xe0 droite** ; **titre** avec bouton **D\xe9marrer / Ajouter** **en fin de ligne** (comme avant pour ce seul contr\xf4le), puis **note** en dessous (`TaskFocusPanel.tsx`).","**Tiroir repliable (xl+)** : le lanceur est encadr\xe9 comme les tiroirs lat\xe9raux (bordure, flou, coins arrondis) ; **une seule ligne d’en-t\xeate** fusionne le titre **T\xe2ches** / **Tasks**, le **d\xe9compte par statut**, l’indicateur **SUIVI**, les **dates pass\xe9es** (mode pass\xe9) et le **chevron** d\xe9plier / replier (pas de languette) ; repli\xe9 : bandeau compact (m\xeame ligne, formulaire masqu\xe9) ; \xe9tat m\xe9moris\xe9 (`kronosys.dashboard.taskLauncherDrawer.open.v1`, `DashboardTaskLauncherDrawer.tsx`). Sous xl : toujours d\xe9ploy\xe9.","**Libell\xe9 du lanceur** : l’en-t\xeate du formulaire d’entr\xe9e et l’en-t\xeate repli\xe9 affichent **T\xe2ches** / **Tasks** (align\xe9 sur la colonne) au lieu de **En cours** / **In focus** ; **En cours (minuteur)** reste r\xe9serv\xe9 \xe0 la liste des t\xe2ches au minuteur actif.","**Guide utilisateur** : note repliable, position de la barre de progression sur les cartes, disposition du **lanceur de t\xe2che** (libell\xe9 **T\xe2ches** / **Tasks**, **expand/collapse** par chevron), **tiroir repliable** du lanceur (`lib/userGuideCopy.ts`, `docs/USER_GUIDE.md`).","**Aide (?)** : texte d’intro Markdown align\xe9 sur le flux **Ajouter une note** (`lib/dashboardCopy.ts`).","Release **1.0.0-beta.32** : bump semver, `npm run build`, `npm run pack:release`, `npm run changelog:build`, `npm run release:verify`. Publication npm au commit `chore(release): 1.0.0-beta.32` (voir `.cursor/rules/release-workflow.mdc`)."]},{version:"1.0.0-beta.31",items:["**Changelog in-app** : r\xe9g\xe9n\xe9ration `lib/generatedUserChangelog.ts` (`npm run changelog:build`) align\xe9e sur **1.0.0-beta.31**.","**Guide utilisateur** : en-t\xeate `docs/USER_GUIDE.md` et r\xe9f\xe9rences semver **`1.0.0-beta.31`** (2026-05-29).","**Impl\xe9mentation** : `lib/implementationNotes.ts`, `docs/IMPLEMENTATION_DETAILS.md`, `docs/README.md`, `README.md` — r\xe9f\xe9rences semver synchronis\xe9es.","**Workflow release** : script `scripts/verify-release-alignment.mjs` et r\xe8gle `.cursor/rules/release-workflow.mdc` — v\xe9rification locale avant tag et publish.","**Build standalone** : `npm run build` obligatoire avant `npm run pack:release` pour garantir un tarball npm avec l’UI \xe0 jour.","Release **1.0.0-beta.31** : bump semver, `npm run build`, `npm run pack:release`, `npm run changelog:build`, `npm run release:verify`. Publication npm au commit `chore(release): 1.0.0-beta.31` (voir `.cursor/rules/release-workflow.mdc`)."]},{version:"1.0.0-beta.30",items:["**Mode focus** : masque l’en-t\xeate, les bandeaux et le pied de page pour n’afficher que les **trois colonnes** (sessions, t\xe2ches, \xe9tiquettes / projets). Bouton **agrandir** dans la barre d’outils (\xe0 c\xf4t\xe9 du th\xe8me) ; **\xc9chap** ou bouton **r\xe9duire** en haut \xe0 droite pour quitter. Raccourci par d\xe9faut : **Alt+Shift+F** (modifiable dans la modale raccourcis). Pr\xe9f\xe9rence m\xe9moris\xe9e dans le navigateur.","**Palette donn\xe9es** (Ctrl+K / ⌘K) : commande **Basculer le mode focus** (`toggle-focus-mode`, `DashboardCommandCenter`) — en compl\xe9ment du bouton **agrandir**, du raccourci **Alt+Shift+F** et de la sortie **\xc9chap** / bouton **r\xe9duire**.","**Sessions** (gauche) et **\xc9tiquettes et projets** (droite) : panneaux repliables en tiroirs (`DashboardSideDrawer`, xl+) ; \xe0 l’ouverture, largeur lat\xe9rale identique \xe0 l’ancienne colonne **1fr** (grille `1fr / 2.25fr / 1fr`, conteneur max 1920px) ; repli\xe9 : languette **2,75 rem** avec libell\xe9 vertical (titre de colonne). La colonne **T\xe2ches** reste centr\xe9e sans d\xe9calage ; sa largeur max augmente de **20 % par tiroir repli\xe9** (base **42 rem**). \xc9tat m\xe9moris\xe9 dans le navigateur (`lib/dashboardSideDrawerStorage.ts`). Sous xl : disposition empil\xe9e inchang\xe9e.","**Bande repli\xe9e** : ic\xf4ne de colonne (`DashboardColumnTitleIcon`) au-dessus du **libell\xe9 vertical** ; languette vers la colonne T\xe2ches ; **Alignement sous l’en-t\xeate** via `DashboardSideDrawerTopSync` (`--kronosys-dash-drawer-top`) ; en mode focus, tiroirs cal\xe9s en haut de page.","**Ligne de titre** : \xe0 c\xf4t\xe9 du **total**, d\xe9compte par bloc (**En cours**, **Planifi\xe9es**, **En pause**, **Compl\xe9t\xe9es**, **Non termin\xe9es (instantan\xe9)**) — segments non nuls align\xe9s sur les en-t\xeates de `TaskFocusPanel` (`lib/taskColumnStatusSummary.ts`).","**KronoFocus** reste **toujours visible** dans la barre d’outils (\xe0 c\xf4t\xe9 de l’horloge), sur toutes les pages principales.","**Carte t\xe2che** : **minuteur live** \xe0 droite sur la **ligne du titre** ; boutons d’action ic\xf4ne compacts sur une ligne sous le titre.","**Dur\xe9e restante** sous **Dur\xe9e** lorsque `scheduledEndAt` est renseign\xe9 ; barre de progression sous **Fin** ; **Nouvelle session** avec fin planifi\xe9e optionnelle → cl\xf4ture automatique.","**Markdown** titre (inline) et note (block) ; aide **(?)** ; GFM ; popover **laps de suivi** au survol Gantt.","**Note** : champ source auto-ajust\xe9 en hauteur (`TaskNoteTextarea`, `ResizeObserver`).","**D\xe9but avec minuteur actif** : modale **Tour de minuteur en cours** (`lapAdjustMode`).","**Laps enregistr\xe9s** : \xe9dition d\xe9but/fin et suppression sur la carte.","**Rouvrir** (↺) une t\xe2che termin\xe9e ; **dur\xe9e minimale** et pr\xe9remplissage fin ; **\xe9tiquette \xab d\xe9faut \xbb** et retrait automatique avec `#tag` explicite.","**Nouvelle session** d\xe9but r\xe9troactif + fin future → session live planifi\xe9e.","Bascule **Prod** / **QA** imm\xe9diate (`resetSqliteConnection`) — sans red\xe9marrage requis.","**Param\xe8tres → Tableau de bord web** : **\xab Ne pas distinguer par la couleur seule \xbb** — pr\xe9fixes `#` / `@` / `!` et bordures distinctes sur les pastilles (`lib/semanticChipAccessibleMode.ts`).","**Guide utilisateur** : `lib/userGuideCopy.ts`, `docs/USER_GUIDE.md` — en-t\xeate **`1.0.0-beta.30`** (2026-05-28).","**Impl\xe9mentation** : `lib/implementationNotes.ts`, `docs/IMPLEMENTATION_DETAILS.md`, `docs/README.md`.","**Tests** : suite Vitest compl\xe8te (543 tests) ; couverture tiroirs, focus mode, r\xe9sum\xe9 statuts, pastilles accessibles, Markdown, laps, QA switch, etc.","**Correctifs build** : `lib/taskMarkdownComponents.tsx`, `lib/taskTimelineGantt.ts`, `formatProjectDisplay` (libell\xe9s `!` en rapports).","Release **1.0.0-beta.30** : bump semver, `npm run build`, `npm run pack:release`, `npm run changelog:build`, `npm run release:verify`. Publication npm au commit `chore(release): 1.0.0-beta.30` (voir `.cursor/rules/release-workflow.mdc`)."]},{version:"1.0.0-beta.29",items:["**Mode focus** : masque l’en-t\xeate, les bandeaux et le pied de page pour n’afficher que les **trois colonnes** (sessions, t\xe2ches, \xe9tiquettes / projets). Bouton **agrandir** dans la barre d’outils (\xe0 c\xf4t\xe9 du th\xe8me) ; **\xc9chap** ou bouton **r\xe9duire** en haut \xe0 droite pour quitter. Raccourci par d\xe9faut : **Alt+Shift+F** (modifiable dans la modale raccourcis). Pr\xe9f\xe9rence m\xe9moris\xe9e dans le navigateur.","**Palette donn\xe9es** (Ctrl+K / ⌘K) : commande **Basculer le mode focus** (`toggle-focus-mode`, `DashboardCommandCenter`) — en compl\xe9ment du bouton **agrandir**, du raccourci **Alt+Shift+F** et de la sortie **\xc9chap** / bouton **r\xe9duire**.","**Sessions** (gauche) et **\xc9tiquettes et projets** (droite) : panneaux repliables en tiroirs (`DashboardSideDrawer`, xl+) ; \xe0 l’ouverture, largeur lat\xe9rale identique \xe0 l’ancienne colonne **1fr** (grille `1fr / 2.25fr / 1fr`, conteneur max 1920px) ; repli\xe9 : languette **2,75 rem** avec libell\xe9 vertical (titre de colonne). La colonne **T\xe2ches** reste centr\xe9e sans d\xe9calage \xe0 l’ouverture ou la fermeture ; sa largeur max augmente de **20 % par tiroir repli\xe9** (base **42 rem**). \xc9tat m\xe9moris\xe9 dans le navigateur (`lib/dashboardSideDrawerStorage.ts`). Sous xl : disposition empil\xe9e inchang\xe9e.","**Bande repli\xe9e** : ic\xf4ne de colonne (`DashboardColumnTitleIcon` — Historique / \xc9tiquettes) au-dessus du **libell\xe9 vertical** du titre ; m\xeame pictogramme que la rang\xe9e titre ouverte.","**Languette** : centr\xe9e verticalement sur le **bord int\xe9rieur** (vers la colonne T\xe2ches) ; en repli, positionn\xe9e vers le bas pour \xe9viter le chevauchement du libell\xe9 vertical.","**Alignement sous l’en-t\xeate** : `DashboardSideDrawerTopSync` mesure la bande des colonnes et pose `--kronosys-dash-drawer-top` pour que les tiroirs restent visibles sous la barre d’outils ; en **mode focus**, les tiroirs se calent en haut de page (`app/globals.css`).","**Ligne de titre** : \xe0 c\xf4t\xe9 du **total**, d\xe9compte par bloc (**En cours**, **Planifi\xe9es**, **En pause**, **Compl\xe9t\xe9es**, **Non termin\xe9es (instantan\xe9)**) — segments non nuls align\xe9s sur les en-t\xeates de `TaskFocusPanel` (`lib/taskColumnStatusSummary.ts`, `buildTaskColumnStatusSegments`).","**Panneau timing** : sous **Dur\xe9e**, **Dur\xe9e restante** affiche le temps jusqu’\xe0 la fin planifi\xe9e (`scheduledEndAt`) lorsqu’une heure de fin est renseign\xe9e ; sinon **Ind\xe9termin\xe9e** — bloc **Session en cours** (`SelectedSessionSidebarBlock.tsx`).","**Fin planifi\xe9e** : barre de progression sous la ligne **Fin** (m\xeame logique que les cartes t\xe2che : avancement de `startAt` vers `scheduledEndAt`, alerte visuelle < 15 / 5 min).","**Actions session** : boutons Gantt / terminer la session, **Nouvelle session** (+), **Archives**, crayon nom, et ic\xf4nes de ligne de liste — gabarit compact des cartes t\xe2che (`TASK_CARD_ICON_BTN_*`, 30\xd730 px, ic\xf4nes 14 px).","**Nouvelle session (Maintenant)** : fin planifi\xe9e optionnelle d\xe8s la modale **Nouvelle session** → cl\xf4ture automatique \xe0 l’\xe9ch\xe9ance (`scheduledEndAt` sur `newSession`).","**Actions** : boutons ic\xf4ne compacts (m\xeame \xe9chelle que les pastilles `#` / `@`) sur une **ligne sous le titre** ; le titre occupe toute la largeur (minuteur live \xe0 droite sur la ligne du titre).","**Fin planifi\xe9e** : barre de progression sous **D\xe9but** / **Fin** lorsque `scheduledEndAt` est d\xe9fini (avancement de `startTime` vers l’\xe9ch\xe9ance).","**Modale enrichie** : lorsqu’une t\xe2che **au minuteur** (lap en cours) voit son **d\xe9but** modifi\xe9, une section **Tour de minuteur en cours** propose de **conserver** le lap, le **cl\xf4turer** (enregistr\xe9 dans `taskTimerLaps`) ou le **r\xe9aligner** sur le nouveau d\xe9but — en plus du recalcul de la **dur\xe9e totale** d\xe9j\xe0 existant.","**Serveur** : `setTaskStartTime` accepte `lapAdjustMode` (`keep` | `flush` | `align_start`) ; impl\xe9ment\xe9 dans `updateTaskStartTimeInSession`.","**Titre** : en lecture sur la carte, Markdown **inline** rendu (`TaskMarkdownContent`, variante `inline`) — gras, italique, lien, code ; les listes et aper\xe7us compacts retirent la syntaxe (`stripTaskMarkdownPlainText`).","**Note libre** : Markdown **block** rendu sur la carte (`TaskNoteField`) ; clic pour \xe9diter la source ; aper\xe7u live sous le champ au **lanceur** de t\xe2che ; ic\xf4ne **(?)** (`TaskMarkdownHelpTrigger`) avec exemples source + rendu.","**Saisie note** : le champ source (`TaskNoteTextarea`) s’**ajuste en hauteur** automatiquement \xe0 la saisie (`ResizeObserver`) — meilleure lisibilit\xe9 lors de l’\xe9dition Markdown.","**S\xe9curit\xe9** : pas de HTML brut (`react-markdown` sans `rehype-raw`) ; liens externes `noopener`.","**GFM** : plugin `remark-gfm` — tableaux, `~~barr\xe9~~`, listes `- [ ]` / `- [x]`, autolinks ; hors scope GitLab : Mermaid, @mentions, alertes `> [!note]`, HTML.","**Gantt** : survol d’un segment de t\xe2che — popover listant tous les **laps de suivi** (`TaskTimelineGanttModal`).","**Carte t\xe2che** : section **Laps de suivi** — correction **d\xe9but/fin** par lap (popover date-heure) et **suppression** avec confirmation ; le lap **en cours** reste en lecture seule jusqu’\xe0 cl\xf4ture.","**Serveur** : actions `setTaskTimerLap` et `deleteTaskTimerLap` (`updateTaskTimerLapInSession`, `deleteTaskTimerLapInSession`) — ajustement de `durationMs` par delta, ordre chronologique entre laps contigus.","**Correctif** : la bascule **Prod** / **QA** rouvre imm\xe9diatement le bon fichier SQLite (`resetSqliteConnection` avant toute \xe9criture payload) — y compris lorsque le coffre QA existe d\xe9j\xe0 (sans modale d’amor\xe7age) ou via **Param\xe8tres → G\xe9n\xe9ral**.","**Documentation** : guide in-app (`lib/userGuideCopy.ts`) et `docs/USER_GUIDE.md` (FR/EN) — bascule **imm\xe9diate** (plus de red\xe9marrage requis) ; `lib/settingsCopy.ts` (libell\xe9s coffres) ; `lib/implementationNotes.ts` et `docs/IMPLEMENTATION_DETAILS.md`.","**Param\xe8tre** `taskMinimumDurationMinutes` (d\xe9faut **30 min**, plage **15–480**) dans **Param\xe8tres → T\xe2ches et \xe9tiquettes** (`/settings#settings-task-tags`).","**Entr\xe9e pass\xe9e** (mode \xab Pass\xe9 \xbb ou session archiv\xe9e) : le **d\xe9but** est arrondi \xe0 la **demi-heure pr\xe9c\xe9dente** ; la **fin** est pr\xe9remplie \xe0 **d\xe9but + dur\xe9e minimale** (recalcul\xe9e quand le d\xe9but change) ; la **dur\xe9e du minuteur** suit la plage d\xe9but/fin.","**T\xe2che planifi\xe9e** : sur la carte t\xe2che, la **fin** (brouillon) suit le **d\xe9but** avec le m\xeame \xe9cart ; si aucune fin n’\xe9tait encore enregistr\xe9e, une **fin planifi\xe9e** est pos\xe9e automatiquement \xe0 la validation du d\xe9but (`scheduledEndAt` via `setTaskEndTime`).","**Correctif** : une t\xe2che **termin\xe9e** dont le cr\xe9neau planifi\xe9 (d\xe9but + fin futurs) atteint son **d\xe9but** se **rouvre** et **active** le minuteur automatiquement au lieu de rester dans **Compl\xe9t\xe9es** ; un d\xe9but futur sur une t\xe2che ouverte **l\xe8ve** la pause manuelle pour permettre l’activation \xe0 l’\xe9ch\xe9ance.","**Seau par d\xe9faut** (`taskDefaultTagBucketEnabled`, inchang\xe9) : une t\xe2che **sans** `#` explicite re\xe7oit l’\xe9tiquette r\xe9serv\xe9e `default` (affich\xe9e \xab d\xe9faut \xbb en fran\xe7ais).","**Retrait automatique** (`taskStripDefaultTagWhenExplicitTags`, **activ\xe9** par d\xe9faut) : d\xe8s qu’**au moins une autre** \xe9tiquette explicite est pr\xe9sente (saisie `#…`, tableau `tags`, \xe9dition du titre), l’\xe9tiquette `default` est **retir\xe9e** — y compris lors d’une **cr\xe9ation** avec `#tag` dans le titre ou d’une **mise \xe0 jour** (`updateTask`).","**Persistance serveur** : fusion titre + `tags` \xe0 la cr\xe9ation (`startTask`, `addHistoricalTask`) via `resolveStoredTaskTagsFromTaskLine` ; normalisation centralis\xe9e dans `normalizeTaskTagsForStorage` (`lib/taskParsing.ts`).","**Param\xe8tres** : second commutateur dans **T\xe2ches et \xe9tiquettes** (`#settings-task-tags`) pour conserver volontairement `default` \xe0 c\xf4t\xe9 d’autres \xe9tiquettes.","**Fin future autoris\xe9e** : en mode \xab Dans le pass\xe9 \xbb, une **fin encore \xe0 venir** ouvre une **session live** avec `startAt` r\xe9troactif et **`scheduledEndAt`** ; l’horloge murale part du d\xe9but saisi (dur\xe9e initiale = maintenant − d\xe9but) et la session se **cl\xf4ture automatiquement** \xe0 l’\xe9ch\xe9ance — m\xeame m\xe9canisme que `setSessionEndTime` sur une session live. Si la fin est **d\xe9j\xe0 pass\xe9e**, la plage **close** reste **historis\xe9e** comme avant.","**Session live d\xe9j\xe0 ouverte** : un d\xe9but r\xe9troactif avec **fin future** d\xe9clenche d’abord le flux **fin de session** (comme \xab Maintenant \xbb), en conservant les bornes saisies ; une session **enti\xe8rement pass\xe9e** n’interrompt toujours **pas** la session active.","**Bouton Rouvrir** (↺) sur chaque carte **termin\xe9e** (session live ou archive).","**Modale** : reprendre le **minuteur** (dur\xe9e conserv\xe9e), rouvrir en **pause**, **dur\xe9e manuelle** (h/m/s) ou **remise \xe0 z\xe9ro** ; les **sous-t\xe2ches** sont rouvertes.","**Session live** : si un autre minuteur tourne d\xe9j\xe0 lors d’une **reprise**, modale **pause / terminer / parall\xe8le** (m\xeame m\xe9morisation que pour un d\xe9marrage).","**Instantan\xe9 cl\xf4tur\xe9** : pas de minuteur live — correction de **statut** et de **dur\xe9e** ; regroupement **Non termin\xe9es (instantan\xe9)** dans la colonne t\xe2ches.","**Param\xe8tres → Tableau de bord web** : option **\xab Ne pas distinguer par la couleur seule \xbb** (`dashboardSemanticChipAccessibleMode`) — pr\xe9fixes `#` / `@` / `!` et bordures distinctes (pleine, double, pointill\xe9e) sur les pastilles \xe9tiquette / projet travail / projet personnel, en compl\xe9ment des teintes vert / bleu ciel / rose (`lib/semanticChipAccessibleMode.ts`, `globals.css`, `taskFieldStyles.ts`).","**Guide utilisateur** : `lib/userGuideCopy.ts`, `docs/USER_GUIDE.md` — lot **beta.28–beta.29** (mode focus et palette, tiroirs lat\xe9raux xl+, r\xe9sum\xe9 statuts colonne T\xe2ches, note auto-ajust\xe9e, Markdown t\xe2che, laps, rouvrir t\xe2che, dur\xe9e minimale, \xe9tiquette d\xe9faut, nouvelle session fin future, pastilles accessibles, coffres Prod/QA imm\xe9diats) ; en-t\xeate **`1.0.0-beta.29`**.","**Impl\xe9mentation** : `lib/implementationNotes.ts`, `docs/IMPLEMENTATION_DETAILS.md`, `docs/README.md` — cartographie compl\xe8te du cycle ; user stories **beta.28** et **beta.29**.","**Tests** : `server/actionDispatch.test.ts`, `server/actionTaskSession.test.ts`, `test/integration/apiActionNewSessionScope.test.ts`, `test/integration/apiActionDataEnvironmentQaSeed.test.ts` ; `lib/taskMinimumDuration.test.ts`, `lib/taskParsing.test.ts`, `lib/taskColumnStatusSummary.test.ts` ; `lib/dashboardSideDrawerStorage.test.ts`, `lib/dashboardFocusMode.test.ts`, `lib/dashboardSideDrawerLayout.test.ts`, `lib/semanticChipAccessibleMode.test.ts` ; `server/mainTimerHydrate.test.ts` ; composants Markdown (`TaskMarkdownContent.test.tsx`, `TaskMarkdownHelpTrigger.test.tsx`, `TaskNotesDisplay.test.tsx`).","Release **1.0.0-beta.29** sur npm (dist-tag `beta`) : lot **beta.28** non publi\xe9 s\xe9par\xe9ment — contenu usager consolid\xe9 sous cette section ; bump `package.json` / `package-lock.json`, r\xe9g\xe9n\xe9ration `lib/generatedUserChangelog.ts` (`npm run changelog:build`), v\xe9rification `npm run release:verify` (voir `.cursor/rules/release-workflow.mdc`)."]},{version:"1.0.0-beta.28",items:["**Version non publi\xe9e sur npm** : le d\xe9veloppement \xe9tiquet\xe9 beta.28 a \xe9t\xe9 livr\xe9 dans le paquet **1.0.0-beta.29** ; l’historique d\xe9taill\xe9 des changements usagers figure dans la section **1.0.0-beta.29** ci-dessus."]},{version:"1.0.0-beta.27",items:["**Toast global** : lorsqu’une **t\xe2che planifi\xe9e** atteint son heure de d\xe9but (`startTime`) ou qu’une **session live** atteint son **`startAt` officiel**, un message temporaire s’affiche en bas \xe0 droite **sur toute route** de l’app (tableau de bord, param\xe8tres, rapports, guide, etc.) — le titre de la t\xe2che ou le nom de la session est rappel\xe9 dans le libell\xe9.","La **modale de conflit** (pause / terminer / parall\xe8le) reste affich\xe9e lorsque le passage planifi\xe9 → en cours co\xefncide avec un autre minuteur d\xe9j\xe0 actif ; le toast d’activation s’ajoute en compl\xe9ment, pas en remplacement.","**Alignement livraison** : `lib/userGuideCopy.ts`, `docs/USER_GUIDE.md`, `lib/implementationNotes.ts` et `docs/IMPLEMENTATION_DETAILS.md` — p\xe9rim\xe8tre **beta.26** document\xe9 de fa\xe7on homog\xe8ne (coffres Prod/QA et amor\xe7age QA, journal `/logs`, cr\xe9neaux planifi\xe9s, suggestions `#` / `@` / `!`, rapports avec **Travail / Personnel** et **Total jour**) ; **beta.27** : toast global \xe0 l’activation d’un cr\xe9neau planifi\xe9 ; en-t\xeates et r\xe9f\xe9rences de version **`1.0.0-beta.27`**.","**Index d\xe9p\xf4t** : `docs/README.md` (r\xf4les des fichiers, cartographie, r\xe8gles de maintenance) ; `README.md` racine — section **API HTTP** compl\xe8te (six routes, plus de mention \xab stub \xbb pour `/api/state`).","**Conception** : `docs/IMPLEMENTATION_DETAILS.md` — cartographie du code, contrats API ; **documentation in-code** sur le noyau (`server/payloadStore`, `actionDispatch`, `db`, `userActionLog`, `app/api/*`, `lib/kronosysApi.ts`).","**CHANGELOG usager** : r\xe9g\xe9n\xe9ration via `npm run changelog:build` (`lib/generatedUserChangelog.ts`).","**Tests** : `lib/plannedScheduleActivation.test.ts` — d\xe9tection planifi\xe9 → minuteur et session ; composant global `PlannedScheduleActivationWatcher` (layout racine).","Les versions **pr\xe9release** (`1.0.0-beta.*`) doivent \xeatre publi\xe9es avec un dist-tag explicite, par ex. `npm publish … --access public --tag beta` (sinon npm refuse la publication).","Bump applicatif : **`1.0.0-beta.27`** (`package.json`, `package-lock.json`)."]},{version:"1.0.0-beta.26",items:["**Deux coffres SQLite** : lorsque l’option est activ\xe9e dans **Param\xe8tres → G\xe9n\xe9ral** (*Coffres production et QA*), les donn\xe9es de production restent dans `…/v4` et un coffre **QA** isol\xe9 vit dans `…/v4-qa` (pr\xe9f\xe9rence sur disque : `data-environment-preference.json`, hors des deux dossiers).","**Bascule** : boutons **Prod** / **QA** dans la barre de navigation (visible seulement si les deux coffres sont activ\xe9s) ; action `switchDataEnvironment` ; **red\xe9marrage du serveur** requis pour ouvrir le bon fichier SQLite (comme tout changement de r\xe9pertoire de donn\xe9es).",'**Rep\xe8re visuel QA** : bandeau violet persistant, liser\xe9 et fond l\xe9g\xe8rement teint\xe9s (`data-kronosys-env="qa"` sur `<html>`) lorsque le processus sert effectivement le coffre QA.',"**Priorit\xe9** : si `TRACE_DATA_DIR` est d\xe9fini, les options prod/QA sont d\xe9sactiv\xe9es ; en `next dev`, lorsque les deux coffres sont activ\xe9s, ils priment sur le segment `v4-dev` (coffres `v4` ou `v4-qa`).","**Premier passage en QA** : si le coffre `v4-qa` n’existe pas encore, une modale propose de **copier la production** ou de **d\xe9marrer vide** avant d’enregistrer la bascule (`switchDataEnvironment` avec `qaSeed`).","**Page** `/logs` (ic\xf4ne **liste** dans le bloc navigation principal) : historique des **mutations** pass\xe9es par `POST /api/action` (type d’action, succ\xe8s/\xe9chec, horodatage, session li\xe9e, IP source).","**Persistance** : table SQLite `user_action_log` (`server/userActionLog.ts`) ; champs sensibles du corps (`token`, `password`, `uri`) **masqu\xe9s** dans le JSON archiv\xe9.","**Lecture** : `GET /api/action-logs?limit=…` ; action `clearUserActionLogs` pour vider le journal depuis l’UI.","**D\xe9but planifi\xe9** : tant que le **d\xe9but officiel** (`startTime`) d’une t\xe2che **non termin\xe9e** est encore **futur**, le **serveur** n’accumule **pas** de dur\xe9e et ne laisse **pas** tourner un segment de minuteur en arri\xe8re-plan ; \xe0 l’**heure de d\xe9but**, la t\xe2che **rejoint le suivi actif** (pile `activeTasks` si besoin) et le minuteur s’**ancre** \xe0 ce `startTime` (synchronisation d’\xe9tat, typiquement toutes les **~2 s** via `/api/state`).","**Fin planifi\xe9e** : une **heure de fin** sur une t\xe2che **en cours** pose toujours `scheduledEndAt` ; \xe0 l’\xe9ch\xe9ance, la t\xe2che se **termine** automatiquement (comportement existant, coh\xe9rent avec le d\xe9but planifi\xe9).","**`setTaskStartTime`** : un d\xe9but **futur** ne pose plus de segment de minuteur **imm\xe9diat**.","**Conflit planifi\xe9 → en cours** : si plusieurs cr\xe9neaux deviennent actifs en m\xeame temps qu’un autre minuteur tournait d\xe9j\xe0, la **modale** pause / terminer / parall\xe8le (m\xe9morisation possible) s’applique comme avant.","**Liste d\xe9roulante** : lorsque le jeton **`#`** (\xe9tiquette), **`@`** (projet travail) ou **`!`** (projet personnel) est actif dans le champ \xab sur quoi travaillez-vous \xbb ou en **\xe9dition du titre** d’une t\xe2che, une liste propose les choix **les plus utilis\xe9s** puis **les plus r\xe9cents** (fr\xe9quence dans l’historique des t\xe2ches, puis listes `knownTags` / `knownProjects` / `knownPersonalProjects`).","**Interaction** : filtrage au fil de la frappe ; navigation clavier (**↑** / **↓**, **Entr\xe9e**, **Tab**, **\xc9chap**) et s\xe9lection \xe0 la souris.","**Port\xe9e projet** : apr\xe8s `@projet#` ou `!projet#`, les suggestions **`#`** ciblent les **\xe9tiquettes li\xe9es** \xe0 ce projet.","Les **mod\xe8les de t\xe2che** (pr\xe9fixe **Mod\xe8le :**) restent propos\xe9s via le m\xe9canisme existant (`datalist`), en parall\xe8le de cette liste.","**Sessions par jour — temps des t\xe2ches** : sous chaque t\xe2che, chaque **#** affiche la **dur\xe9e compl\xe8te** enregistr\xe9e (m\xeame r\xe8gle que les grilles d’allocation #) — **plus** de r\xe9partition \xe0 parts \xe9gales lorsque plusieurs \xe9tiquettes portent sur la m\xeame ligne.","**Temps enregistr\xe9 vs planifi\xe9** : les **totaux**, graphiques et grilles # / @ ne comptent que le **temps r\xe9ellement pass\xe9** (`durationMs`, r\xe8gles d’archives inchang\xe9es). Les t\xe2ches dont le cr\xe9neau est encore **dans le futur** (m\xeame crit\xe8re d’affichage \xab planifi\xe9 \xbb que le tableau de bord) montrent une **fen\xeatre planifi\xe9e** \xe0 part (libell\xe9 ambre), sans l’ajouter aux totaux enregistr\xe9s.","**Calendriers hebdomadaires** (# et @) : ligne **Total jour** en bas de chaque tableau de semaine — **somme par colonne** (chaque jour) et **total de semaine** dans la derni\xe8re colonne.","**Grille par projet (@)** : s\xe9lecteur **Travail (@)** / **Personnel (!)** sous le calendrier hebdomadaire par projet — **Travail** (d\xe9faut) exclut le registre personnel ; **Personnel** n’affiche que le temps `!` (`personalProject` ou jeton `!` reconnu dans le titre si le drapeau manque sur d’anciennes donn\xe9es).","**Tests** : `lib/dataDir.test.ts`, `lib/dataEnvironmentPreferenceFile.test.ts` — r\xe9solution `v4` / `v4-qa`, priorit\xe9 du double coffre en dev ; `server/mainTimerHydrate.test.ts`, `server/actionTaskSession.test.ts` — d\xe9but planifi\xe9 (pas d’accumulation avant l’heure, activation et fin \xe0 l’\xe9ch\xe9ance) ; `setTaskStartTime` avec d\xe9but futur sans segment imm\xe9diat.","**Tests** : `lib/taskEntryTokenSuggest.test.ts` — d\xe9tection des jetons actifs, classement et insertion d’une suggestion.","**Tests** : `lib/reportingAggregate.test.ts` — temps planifi\xe9 exclu des agr\xe9gats enregistr\xe9s ; `lib/reportingWeekLayout.test.ts` — `sumWeekCalendarSlots`.","**Tests** : `test/integration/apiActionLogs.test.ts`, `test/integration/apiActionDataEnvironmentQaSeed.test.ts`.","**Guide utilisateur** : `lib/userGuideCopy.ts` et `docs/USER_GUIDE.md` (FR/EN) — **coffres production / QA** (activation, bascule Prod/QA, amor\xe7age QA, red\xe9marrage, rep\xe8re visuel) ; **journal des actions** (`/logs`) ; **cr\xe9neau planifi\xe9** (activation au d\xe9but, fin automatique) ; liste d\xe9roulante `#` / `@` / `!` ; **Rapports** (dur\xe9e compl\xe8te par # en sessions/jour, temps planifi\xe9 \xe0 part, **Total jour** sur calendriers hebdo, s\xe9lecteur **Travail / Personnel** sur la grille @) ; en-t\xeate **`1.0.0-beta.26`**.","**Impl\xe9mentation** : `lib/implementationNotes.ts` (FR + EN, `lastUpdated`) ; `docs/IMPLEMENTATION_DETAILS.md` — `lib/dataDir.ts` / `lib/dataEnvironmentPreferenceFile.ts`, `switchDataEnvironment`, `server/userActionLog.ts`, `activateDuePlannedTaskTimersInSession` / `deferFutureStartMainTimersInSession`, `lib/taskEntryTokenSuggest.ts`, agr\xe9gats reporting (scopes `work` / `personal`).","**D\xe9p\xf4t** : `README.md` (r\xe9f\xe9rence de version npm).","**Aide Rapports** : `lib/reportingStrings.ts` (textes **Rythme**, calendriers, totaux journaliers).","Bump applicatif : **`1.0.0-beta.26`** (`package.json`, `package-lock.json`) ; **CHANGELOG** usager r\xe9g\xe9n\xe9r\xe9 (`npm run changelog:build`)."]},{version:"1.0.0-beta.25",items:["**Cause** : en production, **`node server.js`** s’ex\xe9cute avec **`cwd` = `.next/standalone`** ; le tarball npm ne publie pas le **`package.json`** racine de l’app, et le **`package.json`** minimal g\xe9n\xe9r\xe9 par Next dans le standalone ne porte pas la version **`@nightkatana/kronosys-app`** — l’UI et **`/api/health`** pouvaient donc afficher une version **d\xe9cal\xe9e** (ex. livraison **beta.24** lue comme **beta.23**).","**Correctif** : apr\xe8s **`next build`**, **`scripts/sync-standalone-assets.mjs`** \xe9crit **`kronosys-package-meta.json`** dans le standalone avec la **`version`** du **`package.json`** source ; **`readKronosysPackageVersion()`** lit ce fichier (ou **`KRONOSYS_APP_VERSION`**, pos\xe9e par **`bin/kronosys.mjs`** au lancement du serveur standalone).","**`app/layout.tsx`** : le layout reste **`force-dynamic`** pour \xe9viter une version RSC fig\xe9e au build lorsque la lecture fichier est pertinente.","Bump applicatif : **`1.0.0-beta.25`** (`package.json`, `package-lock.json`) ; **CHANGELOG** usager r\xe9g\xe9n\xe9r\xe9 (`npm run changelog:build`)."]},{version:"1.0.0-beta.24",items:['**`output: "standalone"`** (`next.config.ts`) + **`scripts/sync-standalone-assets.mjs`** apr\xe8s **`npm run build`** : **`kronosys start`** et **`npm run start`** ex\xe9cutent **`node server.js`** dans **`.next/standalone`** (plus **`next start`** sur ce livrable).','**`package.json` → `"files"`** : le tarball publi\xe9 se limite \xe0 **`bin/`**, **`.next/BUILD_ID`** et **`.next/standalone`** (sans sources `app/` / `server/`), pour une archive nettement plus l\xe9g\xe8re qu’un paquet monolithique.',"**Portabilit\xe9** : exclusion du tra\xe7age **`sharp` / `@img/sharp*`** (**`outputFileTracingExcludes`**) + **`images.unoptimized`**, afin d’\xe9viter des binaires **Linux-only** dans un paquet vis\xe9 **Windows / macOS**.","**Docker** : image d’ex\xe9cution all\xe9g\xe9e (**`node server.js`** depuis le standalone copi\xe9).","**`kronosys dev`** : refus explicite depuis un install tarball slim sans dossier **`app/`** (flux dev = checkout source).","Bump applicatif : **`1.0.0-beta.24`** (`package.json`, `package-lock.json`) ; **CHANGELOG** usager r\xe9g\xe9n\xe9r\xe9 (`npm run changelog:build`)."]},{version:"1.0.0-beta.23",items:["**SQLite** : **`better-sqlite3` retir\xe9** au profit de **`node:sqlite`** (`DatabaseSync`) ; **`engines.node`** **≥ 22.13.0** ; r\xe8gle **`.cursor/rules/platform-native-deps.mdc`**.","**Publication / CLI** : cadre **Linux, Windows, macOS** et strat\xe9gie **`kronosys`** — r\xe8gle **`.cursor/rules/kronosys-npm-packaging.mdc`** (it\xe9rations ult\xe9rieures du contenu du tarball : voir **1.0.0-beta.25**).","Bump applicatif : **`1.0.0-beta.23`** (`package.json`, `package-lock.json`) ; **CHANGELOG** usager r\xe9g\xe9n\xe9r\xe9 (`npm run changelog:build`)."]},{version:"1.0.0-beta.22",items:["**Plus de barre de d\xe9filement horizontale** sur la barre d’outils d’en-t\xeate (`lib/appShellHeaderClasses.ts`) : les segments **horloge / KronoFocus / palette de commandes / navigation de routes / utilitaires (th\xe8me, actualiser, langue)** passent d\xe9sormais **\xe0 la ligne** (`flex-wrap`) lorsqu’ils ne tiennent plus, en gardant chaque rang\xe9e **centr\xe9e**, au lieu de produire un ascenseur horizontal sur le conteneur. Le comportement est identique sur **toutes** les routes principales (tableau de bord, rapports, param\xe8tres, journaux, guide, impl\xe9mentation, changelog, licences).","**Bandeau \xab Donn\xe9es actualis\xe9es \xbb du bouton actualiser** (`components/dashboard/PageRefreshButton.tsx`) : rendu via **portail** vers `document.body` avec **`position: fixed`** au lieu d’un positionnement absolu sous le bouton. Corrige l’apparition intermittente d’une **barre de d\xe9filement verticale** sur la page \xe0 chaque clic — l’\xe9l\xe9ment absolu participait au d\xe9bordement du `<body>` et faisait osciller le `scrollHeight` pendant les ~2,8 s d’affichage du libell\xe9.",'**Popover d’\xe9dition de dur\xe9e KronoFocus** (`components/dashboard/KronoFocusPanel.tsx`) : ouvrir le temps depuis l’en-t\xeate (`variant="headerBar"`) ne d\xe9clenche plus l’apparition de **scrollbars sur les deux axes** dans l’alv\xe9ole du ruban. La cause \xe9tait la combinaison `overflow-x-auto` sur l’alv\xe9ole + popover en `position: absolute` : selon la spec CSS, d\xe8s qu’un axe d’overflow n’est pas `visible`, l’autre est promu en `auto`, donc deux ascenseurs apparaissaient sit\xf4t que le panneau d\xe9passait. Le popover est d\xe9sormais rendu en **portail** avec `position: fixed` centr\xe9 sous le bouton du temps. D\xe9tection click-outside r\xe9vis\xe9e pour v\xe9rifier le **d\xe9clencheur** et le **panneau** par leurs `ref` distinctes (ils ne partagent plus de sous-arbre DOM).',"**Surcouche carte \xab compl\xe8te \xbb** (variante `default` de `KronoFocusPanel`) align\xe9e sur le m\xeame pattern portail pour rester coh\xe9rente.",'**`useAnchoredFloatingPortalStyle`** (`components/dashboard/useAnchoredFloatingPortalStyle.ts`) gagne l’alignement **`"center"`** en plus de `start` / `end` : le panneau portail peut maintenant \xeatre centr\xe9 horizontalement sous son d\xe9clencheur. Les autres consommateurs (`PageRefreshButton`, `PlainHelpPopover`, `TagsHelpTrigger`, `InlineMetricHelpTrigger`) conservent leurs alignements existants ; le hook continue de g\xe9rer la contrainte au viewport (marge 10 px) et le **basculement au-dessus** du d\xe9clencheur s’il manque de place en bas.',"**Guide utilisateur** : `lib/userGuideCopy.ts` et `docs/USER_GUIDE.md` (FR/EN) — note explicite sur le repli en plusieurs rang\xe9es de la barre d’outils sur \xe9cran \xe9troit ; en-t\xeate de version pointe **`1.0.0-beta.22`**.","**Impl\xe9mentation** : `lib/implementationNotes.ts` (FR + EN, `lastUpdated`) ; `docs/IMPLEMENTATION_DETAILS.md` — date d’en-t\xeate et note sur le pattern \xab portail + `position: fixed` \xbb pour les surcouches ancr\xe9es \xe0 des \xe9l\xe9ments d’en-t\xeate (\xe9vite la propagation au `scrollableOverflow` du `<body>`).","**D\xe9p\xf4t** : `README.md` (r\xe9f\xe9rence de version npm).","Bump applicatif : **`1.0.0-beta.22`** (`package.json`, `package-lock.json`) ; **CHANGELOG** usager r\xe9g\xe9n\xe9r\xe9 (`npm run changelog:build`)."]},{version:"1.0.0-beta.21",items:["**Parsing** : `findProjectTokens` (`lib/taskParsing.ts`) reconna\xeet d\xe9sormais **`!projet`** et **`!projet#sous-\xe9tiquette`** lorsque le **`!`** suit **directement** un caract\xe8re autoris\xe9 (sans espace avant le sigil), sur le m\xeame principe que les **`#\xe9tiquettes`** \xab coll\xe9es \xbb au mot pr\xe9c\xe9dent. Les jetons **`@`** restent limit\xe9s \xe0 une **fronti\xe8re d\xe9but de cha\xeene ou espace** afin d’\xe9viter les faux positifs (ex. adresses courriel du type `contact@domaine`).","**Effet** : la modification d’un libell\xe9 du type `Courrier!perso#dentiste` met correctement \xe0 jour **`project`**, **`personalProject`** et les **\xe9tiquettes** persist\xe9es (y compris via **`updateTask`**), ce qui aligne le **reporting** (\xe9tiquettes, ventilation par projet selon le scope) sur l’intention utilisateur.","**Guide utilisateur** : `lib/userGuideCopy.ts` et `docs/USER_GUIDE.md` (FR/EN) — pr\xe9cision sur l’espace optionnel avant **`!`** ; en-t\xeate et exemples de livraison pointent **`1.0.0-beta.21`**.","**Impl\xe9mentation** : `docs/IMPLEMENTATION_DETAILS.md` (r\xe8gle de fronti\xe8re `!` / `@`) ; `lib/implementationNotes.ts` (version affich\xe9e et d\xe9tail parsing scoped `!`).","**D\xe9p\xf4t** : `README.md` (r\xe9f\xe9rence de version npm).","**Tests** : `lib/taskParsing.test.ts` — cas `Courrier!perso#dentiste` ; attentes **`personalProject`** pour `parseQuickAddTagOrProjectLine` / `buildStartTaskFromInput` lorsqu’un projet est pr\xe9sent.","Bump applicatif : **`1.0.0-beta.21`** (`package.json`, `package-lock.json`) ; **CHANGELOG** usager r\xe9g\xe9n\xe9r\xe9 (`npm run changelog:build`)."]},{version:"1.0.0-beta.20",items:["**D\xe9pendances runtime** : `@types/node`, `@types/react` et `@types/react-dom` pass\xe9es en **`dependencies`** avec `typescript` — Next.js 16 exige ces paquets pour la phase \xab Running TypeScript \xbb du `next build` ; une installation **`npm install --omit=dev`** ne les omet plus (\xe9vite le message *It looks like you're trying to use TypeScript…* hors environnement de d\xe9veloppement complet).","**Contenu du tarball publi\xe9** : suppression du champ **`files`** dans `package.json` (il neutralisait **`.npmignore`**, comportement **npm-packlist**) ; filtrage du paquet via **`.npmignore`** (fichiers `*.test.*` / `*.spec.*`, dossiers `e2e/`, `test/`, `docs/`, outils CI, etc.) en conservant les sources n\xe9cessaires au build.","Bump applicatif : **`1.0.0-beta.20`** (`package.json`, `package-lock.json`) ; **CHANGELOG** usager r\xe9g\xe9n\xe9r\xe9 (`npm run changelog:build`)."]},{version:"1.0.0-beta.19",items:["**Affichage planifi\xe9** : regroupement sous **Planifi\xe9es**, styles distincts (section, fond, point d’\xe9tat) ; **suppression des pastilles texte** \xab planifi\xe9 \xbb sur les cartes t\xe2che et les lignes de session. T\xe2che **non termin\xe9e** dont le **d\xe9but** (`startTime`) est encore **futur** : pas de minuteur \xab en direct \xbb. T\xe2che **termin\xe9e** : regroupement planifi\xe9 seulement si **d\xe9but et fin** parseables sont **tous deux** strictement futurs — une **fin** future seule ne retient plus la carte sous Planifi\xe9es lorsque le d\xe9but est d\xe9j\xe0 pass\xe9 (`isTaskDisplayPlanned`). Session live \xe0 **startAt** futur : ligne distincte dans la liste ; d\xe9compte planifi\xe9es sur la carte session ; tiroir AppShell sans ces entr\xe9es comme suivi actif.","**Fronti\xe8re planifi\xe9 → en cours** : lorsqu’une t\xe2che rejoint les minuteurs **en cours** alors qu’**au moins un** autre minuteur \xe9tait d\xe9j\xe0 visible comme en cours, une **modale** (pause / terminer / parall\xe8le, m\xeame m\xe9morisation que le d\xe9marrage manuel) s’applique aux t\xe2ches d\xe9j\xe0 au minuteur ; hors route `/`, l’ic\xf4ne **Tableau de bord** peut **pulser**.","**Modales globales** : correction d’un d\xe9calage de positionnement lors des transitions de route ; l’animation de conteneur ne transporte plus de `transform`, ce qui r\xe9tablit l’ancrage viewport des modales en `position: fixed`.","**Horloge murale** permanente dans la barre d’outils : fuseau IANA et format 12/24 h des param\xe8tres **Tableau de bord web**, tick chaque seconde ; correctif d’**hydratation** SSR/CSR sur les secondes au premier rendu.","**S\xe9lecteurs date/heure** : bouton **crochet** pour valider et fermer le calendrier ; pr\xe9remplissage **d\xe9but** avec minutes `:00` (bouton **Today** idem) ; **Now** \xe0 l’instant exact ; champs de **fin** arrondis \xe0 la **demi-heure** suivante (**Today** inclus).","**Heure de fin planifi\xe9e** (t\xe2che ou session) : clignotement doux entre 15 et 5 minutes restantes, puis plus rapide jusqu’\xe0 0.","**Colonne t\xe2ches** : suppression d’une troncature visuelle pendant l’animation d’ouverture ; d\xe9filement correct sur les listes longues.","**Installation desktop / PWA** : priorit\xe9 **512x512** + r\xf4le `maskable` pour l’ic\xf4ne install\xe9e.","**Jeton `!`** : en parall\xe8le de `@projet`, le libell\xe9 de t\xe2che accepte **`!projet`** et les \xe9tiquettes sous port\xe9e **`!projet#sous-\xe9tiquette`** ; le moteur distingue **`personalProject`** sur les t\xe2ches et maintient **`knownPersonalProjects`** sur le payload (liste distincte de `knownProjects`).","**Actions** : `startTask`, `addHistoricalTask`, `updateTask`, `saveTaskTemplate` ; renommage serveur avec **`renameProjectMetadata`** et **`personalOnly`** (pas encore d’inline Param\xe8tres d\xe9di\xe9 aux listes `!`).","**UI** : pastilles et suggestions **rose** pour le personnel (`taskFieldStyles`, `TaskFocusPanel`, `TaskSessionLiveCard`, `SavedProjectPicker`, `TagPills`) ; **Gantt** d’une t\xe2che : barres et **totaux s\xe9par\xe9s** temps productif (`@`) vs personnel (`!`).","**Rapports** : les grilles \xab par projet \xbb utilisent par d\xe9faut le scope **`work`** (`aggregateProjectTaskMinutesByDay`) — le temps `!` n’y est pas m\xe9lang\xe9 ; les scopes **`personal`** / **`all`** existent dans `lib/reportingAggregate.ts` pour une future vue UI d\xe9di\xe9e.","**Qualit\xe9** : tests unitaires sur les mod\xe8les avec projet personnel (`lib/taskTemplateDraft.test.ts`) ; pas de parcours E2E Playwright d\xe9di\xe9 aux jetons `!` dans cette version.","**Guide utilisateur** : `lib/userGuideCopy.ts` et `docs/USER_GUIDE.md` (FR/EN) — convention **`#` / `@` / `!`**, rapports (grilles projet `@` sans m\xe9langer `!`), limite actuelle c\xf4t\xe9 Param\xe8tres pour les projets personnels.","**Impl\xe9mentation** : `lib/implementationNotes.ts` (user stories et coches int\xe9gration/E2E) ; **`docs/IMPLEMENTATION_DETAILS.md`** — section projets personnels et scopes reporting.","**Changelog usager** : r\xe9g\xe9n\xe9ration via `npm run changelog:build` (`lib/generatedUserChangelog.ts`).","**Paquet npm** : version **`1.0.0-beta.19`** ; script **`prepublishOnly`** = `npm run build` avant `npm publish` sur `@nightkatana/kronosys-app`."]},{version:"1.0.0-beta.18",items:["Nouveaut\xe9s — Sauvegarde/restauration: ajout de l’API `POST /api/restore` (import `json` ou `sqlite`) avec couverture d’int\xe9gration d\xe9di\xe9e.","Nouveaut\xe9s — User stories in-app: ajout de la page **Impl\xe9mentation** (`/implementation`) avec inventaire exhaustif ✓/✗, checklist locale \xab revue \xbb et acc\xe8s direct au changelog usager.","Nouveaut\xe9s — Mod\xe8les de t\xe2che: section d\xe9di\xe9e dans Param\xe8tres, cr\xe9ation depuis une t\xe2che, suggestions \xab Mod\xe8le : \xbb dans la saisie, disponibilit\xe9 dans la palette **Spotlight**.","Nouveaut\xe9s — Vue **Gantt du jour**: modal timeline globale des intervalles de t\xe2ches sur les sessions de la journ\xe9e.","Nouveaut\xe9s — Pause globale contextuelle: modal de confirmation enrichie avec r\xe9sum\xe9 d\xe9taill\xe9 (murale, temps actifs/codage, compteurs t\xe2ches/sous-t\xe2ches, ventilation minuteurs).","Nouveaut\xe9s — Nom de session par d\xe9faut: gabarit configurable (`%UUID` + tokens `strftime`) appliqu\xe9 \xe0 la cr\xe9ation de session.","Am\xe9liorations — Tableau de bord: en-t\xeate AppShell consolid\xe9 (m\xe9tadonn\xe9es de session, placeholder commande, navigation), transitions de route et coh\xe9rence inter-pages accrues.","Am\xe9liorations — Reporting: ajout du temps non concurrent par jour, ventilation des sessions par type de cl\xf4ture, aides m\xe9triques et pr\xe9cision accrue des agr\xe9gats.","Am\xe9liorations — Sessions/t\xe2ches: consolidation des statistiques lat\xe9rales, gestion des notes et meilleure continuit\xe9 live/historique.","Am\xe9liorations — Param\xe8tres: \xe9volution des sections \xc9tiquettes/Projets/Mod\xe8les et meilleure ergonomie des flux de configuration.","Qualit\xe9 — Tests: renforcement substantiel de la couverture (unitaires + int\xe9gration + E2E) sur restore API, templates, Gantt, pause globale, agr\xe9gats reporting et flux session/t\xe2che.","Documentation — Guide utilisateur synchronis\xe9 pour `beta.18` sur les deux surfaces (`/guide` et `docs/USER_GUIDE.md`), Spotlight harmonis\xe9, page `/implementation` et `docs/IMPLEMENTATION_DETAILS.md` align\xe9s.","Maintenance — Bump applicatif vers `1.0.0-beta.18` (`package.json`, `package-lock.json`) et r\xe9g\xe9n\xe9ration du changelog usager (`lib/generatedUserChangelog.ts`)."]},{version:"1.0.0-beta.17",items:["Nouveaut\xe9s — Notes libres: ajout d’une **note de t\xe2che** et d’une **note de session** (texte libre) pour documenter le contexte de travail directement sur l’activit\xe9 concern\xe9e.","Am\xe9liorations — Tableau de bord: la note de t\xe2che est affich\xe9e **avant** la liste des sous-t\xe2ches pour garder le contexte visible pendant la d\xe9composition.","Am\xe9liorations — Sessions et archives: aper\xe7u de note de session (ic\xf4ne + extrait) dans la liste des sessions et dans la liste des sessions archiv\xe9es.","Qualit\xe9 — Tests: ajout de tests unitaires UI pour l’ordre d’affichage note/sous-t\xe2ches et la pr\xe9sence de l’aper\xe7u de note en liste de sessions, en plus des tests serveur sur la persistance des notes.","Documentation — Mise \xe0 jour du guide utilisateur (in-app + d\xe9p\xf4t) et des d\xe9tails d’impl\xe9mentation pour les notes de t\xe2ches/sessions.","Nouveaut\xe9s — Planification d’heure de fin sur les **t\xe2ches en cours** : d\xe9finir une heure de fin programme l’\xe9ch\xe9ance et met automatiquement le minuteur en pause lorsqu’elle est atteinte.","Nouveaut\xe9s — Planification d’heure de fin sur la **session live** : d\xe9finir une heure de fin agit comme \xe9ch\xe9ance de session et met automatiquement en pause la dur\xe9e murale \xe0 l’instant pr\xe9vu.","Am\xe9liorations — Tableau de bord : le s\xe9lecteur **Fin** est disponible aussi sur t\xe2ches/sessions en cours (plus seulement sur les \xe9l\xe9ments d\xe9j\xe0 termin\xe9s), avec affichage de l’\xe9ch\xe9ance planifi\xe9e.","Qualit\xe9 — Tests : renforcement de la couverture (dispatch + hydratation minuteurs/session) pour les sc\xe9narios planifi\xe9s et les cas d’\xe9ch\xe9ance d\xe9pass\xe9e.","Documentation — Guide utilisateur et d\xe9tails d’impl\xe9mentation mis \xe0 jour pour expliciter la diff\xe9rence \xab fin r\xe9elle \xbb vs \xab fin planifi\xe9e (auto-pause) \xbb.","Nouveaut\xe9s — \xc9tiquettes et projets : renommage **inline** dans la colonne droite du tableau de bord (\xe9dition en place, validation **Entr\xe9e**, annulation **\xc9chap**).","Am\xe9liorations — Confirmation de renommage : avertissement explicite sur l’impact reporting + option \xab ne plus afficher \xbb m\xe9moris\xe9e localement.","Qualit\xe9 — UX : suppression des ambigu\xeft\xe9s d’actions (pas de bouton de sauvegarde en double pendant le renommage inline)."]},{version:"1.0.0-beta.16",items:["Nouveaut\xe9s — Page Impl\xe9mentation (`/implementation`) avec inventaire exhaustif des user stories (✓ livr\xe9 \xb7 ✗ absent/hors p\xe9rim\xe8tre), checklist locale \xab revue \xbb et acc\xe8s direct au changelog usager.","Nouveaut\xe9s — Documentation technique d’impl\xe9mentation ajout\xe9e dans `docs/IMPLEMENTATION_DETAILS.md` (mod\xe8le temps session murale vs minuteurs de t\xe2ches, pauses, reporting, architecture et maintenance).","Nouveaut\xe9s — Mod\xe8les de t\xe2che: sauvegarde depuis une t\xe2che, suggestions \xab Mod\xe8le: \xbb dans la saisie, pr\xe9sence dans la palette `Ctrl+K`, gestion d\xe9di\xe9e dans Param\xe8tres.","Nouveaut\xe9s — Pause globale contextuelle avec modale de confirmation et aper\xe7u d\xe9taill\xe9 (murale, temps actif/codage, compteurs t\xe2ches/sous-t\xe2ches, ventilation des minuteurs).","Nouveaut\xe9s — Vue Gantt du jour: frise des intervalles de t\xe2ches sur l’ensemble des sessions de la journ\xe9e.","Nouveaut\xe9s — Nom de session par d\xe9faut avec gabarit configurable (`%UUID` + tokens `strftime`) dans les param\xe8tres.","Nouveaut\xe9s — Restauration locale via `POST /api/restore` (`json` ou `sqlite`) en compl\xe9ment de `GET /api/backup`.","Am\xe9liorations — Reporting: ajout du temps non concurrent par jour, ventilation des sessions par type de cl\xf4ture, m\xe9triques d’assiduit\xe9 quand une heure pr\xe9vue est fournie.","Am\xe9liorations — Spotlight: la palette de recherche rapide est d\xe9sormais explicitement nomm\xe9e \xab Spotlight \xbb dans l’interface.","Qualit\xe9 — Tests: ajout/renforcement des parcours E2E et tests unitaires (impl\xe9mentation, templates, pause globale, restauration API, agr\xe9gats).","Documentation — Guide utilisateur: mise \xe0 jour compl\xe8te in-app + d\xe9p\xf4t, et alignement des cha\xeenes FR/EN (dashboard, reporting, param\xe8tres, licences, impl\xe9mentation)."]},{version:"1.0.0-beta.15",items:["Ajout de la commande de version CLI: `kronosys --version` affiche d\xe9sormais la version install\xe9e.","Ajout des alias `kronosys -v` et `kronosys version` pour afficher la version install\xe9e."]},{version:"1.0.0-beta.14",items:["Ajout de la page **Impl\xe9mentation** (`/implementation`) avec inventaire exhaustif des user stories livr\xe9es ou hors p\xe9rim\xe8tre.","Ajout des **mod\xe8les de t\xe2che** (cr\xe9ation depuis une t\xe2che, gestion dans Param\xe8tres, recherche rapide Ctrl+K).","Ajout d’une **pause globale contextuelle** avec modale de confirmation et aper\xe7u des dur\xe9es associ\xe9es.","Ajout de la vue **Gantt du jour** pour visualiser les intervalles de t\xe2ches de la session affich\xe9e."]},{version:"1.0.0-beta.13",items:["Version interm\xe9diaire de stabilisation (pas de nouveaut\xe9 utilisateur majeure document\xe9e)."]},{version:"1.0.0-beta.12",items:["Correctif du runtime CLI: installation des d\xe9pendances avec `--ignore-scripts` pour \xe9viter les erreurs Husky hors d\xe9p\xf4t."]},{version:"1.0.0-beta.11",items:["Correctif Windows du lanceur CLI (PowerShell + installation runtime locale).","Rebuild explicite de `better-sqlite3` dans le runtime local."]},{version:"1.0.0-beta.10",items:["Correctif de dispatch des commandes Windows pour le runtime CLI."]},{version:"1.0.0-beta.9",items:["Correctif de quoting des commandes Windows dans le lanceur CLI."]},{version:"1.0.0-beta.8",items:["Correctif initial Windows du launcher (`npm.cmd`/`npx.cmd`)."]},{version:"1.0.0-beta.7",items:["Stabilisation du packaging b\xeata et g\xe9n\xe9ration des archives de distribution."]},{version:"1.0.0-beta.6",items:["Correctif de r\xe9solution d’alias d’import (`@/...`) pour le build de production."]},{version:"1.0.0-beta.5",items:["Retour temporaire au mode build \xe0 la premi\xe8re ex\xe9cution pour am\xe9liorer la compatibilit\xe9 multiplateforme."]},{version:"1.0.0-beta.4",items:["Ajustements de packaging et de lancement CLI pour la s\xe9rie b\xeata."]},{version:"1.0.0-beta.2",items:["Correctif des d\xe9pendances de build n\xe9cessaires au runtime CLI."]},{version:"1.0.0-beta.1",items:["`kronosys` lance maintenant le build de production automatiquement si `.next` est absent."]},{version:"1.0.0-beta.0",items:["Premi\xe8re version b\xeata publi\xe9e."]},{version:"0.1.1",items:["Added an in-app user CHANGELOG page (`/changelog`).","Added an update modal on Dashboard startup that opens the CHANGELOG after a version change.","Added browser-local tracking of the last seen app version to show update notes once per version."]}],e={title:"User CHANGELOG",subtitle:"This page lists user-visible changes after each software update.",empty:"No changelog entry is available yet.",entries:d},f={title:"CHANGELOG usager",subtitle:"Cette page liste les changements visibles c\xf4t\xe9 utilisateur apr\xe8s chaque mise \xe0 jour du logiciel.",empty:"Aucune entr\xe9e de changelog n’est encore disponible.",entries:d};function g(a){return"fr"===a?f:e}},92776:(a,b,c)=>{"use strict";c.d(b,{J:()=>f});let d={title:"Settings",subtitle:"Kronosys options stored locally on this machine.",loading:"Loading settings…",reload:"Reload from server",save:"Save",saving:"Saving…",savedOk:"Settings saved.",settingsUnsavedStickyHint:"You have unsaved changes.",resetToDefaults:"Reset to defaults",resetToDefaultsConfirm:"Restore every Kronosys option to its factory default? Stored GitLab tokens and MongoDB connection flags are not removed from secure storage; only the settings shown on this page are reset.",resettingDefaults:"Resetting…",resetDefaultsDone:"Defaults applied.",openIdeSettings:"These fields map to persisted configuration keys in the local store.",tocHeading:"On this page",tocNavAriaLabel:"Jump to a settings section",tocSearchPlaceholder:"Filter table of contents…",tocSearchAriaLabel:"Filter settings sections in the table of contents",tocSearchNoResults:"No section title matches.",sectionUsageProfile:"Usage profile",usageProfile:"Profile",usageProfileDesc:"Developer: lines written, per-language stats, coding-signal counts, workspace LOC snapshot, and Git repo card. Manager: tasks, sessions, KronoFocus, and time only — no code-linked metrics or UI.",profileDeveloper:"Developer",profileManager:"Manager",workspaceLocSectionHiddenManager:"These options apply only in Developer profile (workspace code snapshot on Reporting).",sectionGeneral:"General",sectionPrivacy:"Privacy",sectionKronoFocus:"KronoFocus (dashboard)",kronoFocusHeaderPinnedNote:"The KronoFocus timer and controls always stay in the app header toolbar (next to the clock and command palette) so the navigation bar keeps the same width on every page. While you inspect an archive, the controls stay visible but target the live session.",kronoFocusShowInTaskOps:"Show in task action buttons",kronoFocusShowInTaskOpsDesc:"KronoFocus start on active tasks and the optional “start KronoFocus with new task” toggle in the task launcher.",sectionTaskTags:"Tasks & tags",taskDefaultTagBucketEnabled:"Implicit default tag for tasks without #tags",taskDefaultTagBucketEnabledDesc:"When enabled, any task with no hashtag labels after cleanup is stored with the reserved default bucket (shown as “default” in English or “d\xe9faut” in French). When disabled, such tasks keep an empty label list until you add one.",taskStripDefaultTagWhenExplicitTags:"Drop default tag when another #tag is added",taskStripDefaultTagWhenExplicitTagsDesc:"When enabled, as soon as a task carries at least one explicit hashtag label other than the reserved default bucket, the default label is removed automatically. When disabled, default can stay alongside other labels.",taskMinimumDurationMinutes:"Minimum task duration (minutes)",taskMinimumDurationMinutesDesc:"Default span for past or planned task entry: the end time is prefilled as start plus this many minutes (e.g. 30 or 60). Range: 15–480.",dashboardAllowTaskStartTimeEdit:"Allow task start-time correction in the dashboard",dashboardAllowTaskStartTimeEditDesc:"Shows controls to edit a task start time from the Tasks column while it is running or after it is completed.",dashboardAllowSessionStartTimeEdit:"Allow session start-time correction in the dashboard",dashboardAllowSessionStartTimeEditDesc:"Shows controls to edit a session start time from the Sessions column for the live session or a historical session.",dashboardAllowTaskEndTimeEdit:"Allow task end-time correction in the dashboard",dashboardAllowTaskEndTimeEditDesc:"Shows controls to set or edit task end time in the Tasks column, including while a task is running (the task completes automatically when that planned end is reached).",dashboardAllowSessionEndTimeEdit:"Allow session end-time correction in the dashboard",dashboardAllowSessionEndTimeEditDesc:"Shows controls to set or edit a session end time in the Sessions column, including while a live session is open (the session closes automatically when that planned end is reached).",sectionCollection:"Collection & buffers",sectionHistory:"Session history",sectionDangerZone:"Danger zone",dangerClearHistoryTitle:"Clear all local dashboard data",dangerClearHistoryBodyIntro:"Permanently removes, in this dashboard’s local store:",dangerClearHistoryBodyBullets:["Every session (live view, history list, and archived list) and the session you were inspecting","All tag & project shortcuts: pinned tags, tags hidden from chips, tag/project descriptions, known tag & project suggestion lists","Git identity saved here (display name, email, forge login) and the Git statistics card data","The cached workspace lines-of-code snapshot used on Reporting (Developer profile)","The “skip archive confirm” preference for this dashboard","The browser’s saved dashboard language and explicit language choice (you will pick English or Fran\xe7ais again before the guided tour)"],dangerClearHistoryBodyAfterList1:"Afterwards, the welcome guided tour will be offered again on the dashboard, and the “show welcome on startup” option is turned back on in settings.",dangerClearHistoryBodyAfterList2:"This cannot be undone.",dangerClearHistoryButton:"Clear all local data…",dangerClearHistoryConfirm:"You are about to erase everything listed in the danger-zone description above (sessions, tags/projects metadata, Git identity in this store, etc.). Continue?",dangerClearHistoryVaultTargetTitle:"Vault targeted by this erase",dangerClearHistoryVaultTargetTrace:"Erase applies to the directory forced by TRACE_DATA_DIR: {path}. No other Kronosys vault is involved.",dangerClearHistoryVaultTargetDual:"Erase applies only to the {env} vault currently loaded by this server ({path}). The {otherEnv} vault ({otherPath}) is not modified.",dangerClearHistoryVaultTargetSingle:"Erase applies to the data directory currently loaded by this server ({path}).",dangerClearHistoryVaultTargetDev:"Erase applies to the development data directory currently loaded by this server ({path}), not the packaged production vault unless you explicitly share it.",dangerClearHistoryVaultMismatch:"Note: your saved preference points to {preferredEnv} ({preferredPath}) after restart, but this process is still using {activePath}. The erase will affect the directory in use now.",dangerClearHistoryConfirmPhrase:"DELETE",dangerClearHistoryTypeInstruction:"To enable “Confirm”, type {phrase} exactly below (all capitals, no spaces).",dangerClearHistoryTypeFieldLabel:"Confirmation word",dangerClearHistoryTypeInputAria:"Type the confirmation word to allow the full erase described above (sessions, metadata, Git identity, etc.)",dangerClearHistoryBackupIntro:"Before you confirm, you can download a local backup (same data the dashboard uses on this machine):",dangerClearHistoryBackupJson:"JSON — full state snapshot",dangerClearHistoryBackupJsonHint:"Entire persisted Kronosys payload in one file (sessions including live `current`, tasks, tag/project metadata, Git identity, `cfg`, Git stats snapshot, workspace LOC snapshot, etc.).",dangerClearHistoryBackupCsvBlockTitle:"CSV — multiple tables (one download per link)",dangerClearHistoryBackupCsvBlockHint:"Together these tables mirror what the danger-zone erase removes: sessions (with a full JSON column per row), every task and subtask, tag/project lists and descriptions, Git identity, plus configuration and JSON blobs (`cfg`, Git stats, workspace code snapshot, inspecting session id, etc.).",dangerClearHistoryBackupCsvZip:"CSV — all tables (ZIP)",dangerClearHistoryBackupCsvZipHint:"One download containing the eight UTF-8 CSV files.",dangerClearHistoryBackupCsvSeparateTitle:"Individual files (optional)",dangerClearHistoryBackupCsvSessions:"Sessions — extended metrics + full session JSON",dangerClearHistoryBackupCsvTasks:"Tasks — one row per task + full task JSON",dangerClearHistoryBackupCsvSubtasks:"Subtasks — one row per checklist item + JSON",dangerClearHistoryBackupCsvRegistry:"Tag & project registry — known / pinned / hidden lists",dangerClearHistoryBackupCsvTagDesc:"Tag descriptions",dangerClearHistoryBackupCsvProjectDesc:"Project descriptions",dangerClearHistoryBackupCsvGitId:"Git identity (saved in this store)",dangerClearHistoryBackupCsvStoreBlobs:"Config & snapshots — `cfg`, Git stats, workspace LOC, UI prefs",dangerClearHistoryBackupSqlite:"SQLite — database file",dangerClearHistoryBackupSqliteHint:"Raw kronosys.sqlite after a WAL checkpoint (restore by replacing the file when the app is stopped).",dangerBackupRestoreTitle:"Backups and full restore",dangerBackupRestoreIntro:"Download a full backup first, then restore from a previous backup file when needed (JSON snapshot or SQLite file).",dangerRestorePickFile:"Restore file (`.json` or `.sqlite`)",dangerRestoreHint:"Restoring replaces the current local store on this machine. Create a backup right before restoring if you are unsure.",dangerRestoreButton:"Restore from backup…",dangerRestoreBusy:"Restoring…",dangerRestoreConfirm:"Restore this backup file now? The current local data store will be replaced for this environment.",dangerRestoreNoFile:"Choose a backup file before starting restore.",dangerRestoreDoneJson:"Restore completed from JSON snapshot. The dashboard data has been reloaded.",dangerRestoreDoneSqlite:"Restore completed from SQLite file. The dashboard data has been reloaded.",dangerRestoreFailed:"Restore failed: {detail}",sectionArchivedSessions:"Archived sessions",archivedSessionsIntro:"Sessions hidden from the main dashboard list, newest first. Restore adds them back to the Sessions column.",archivesPaginationPrev:"Previous page",archivesPaginationNext:"Next page",archivesPaginationNavAria:"Archived sessions pagination",archivesPaginationRange:"{from}–{to} of {total}",sectionExport:"Export defaults",sectionGit:"Git sync",sectionMongo:"MongoDB mirror",sectionWeb:"Dashboard & API",devDataBlockTitle:"Development mode (local data store)",devDataIntro:"While you run the Next.js dev server (`next dev`), SQLite and local state use a separate folder (`…/v4-dev` by default) from the production build (`next start`, `…/v4`) so you do not overwrite your real data. Save with the main **Save** button at the bottom of this page, like any other setting.",devDataUseProdLabel:"Use the same data directory as production (v4)",devDataUseProdDesc:"When off (default), dev uses an isolated `v4-dev` directory. When on, dev reads and writes the same `v4` path as a packaged or `next start` run. After changing this, restart the dev server so it opens the right database file.",devDataActivePath:"Data directory in use (this process)",devDataPreferredPath:"Would apply after restart",devDataProdPath:"Default production directory (v4)",devDataPrefsFile:"Preference file on disk",devDataTraceOverride:"The server was started with TRACE_DATA_DIR; that path is used and this toggle is disabled.",devDataEnvOverride:"The environment variable KRONOSYS_DEV_USE_PROD_DATA is set; the dev server uses the production v4 path and this toggle is disabled.",devDataRestartHint:"Your saved preference no longer matches the open database. Restart the Next.js dev server to apply it.",devDataHiddenNotDev:"This block is only shown when the dashboard is served in development mode (`next dev`).",dataEnvBlockTitle:"Production and QA data stores",dataEnvIntro:"Keep your real sessions in the production folder (`…/v4`) and use a separate QA folder (`…/v4-qa`) to try features or reproduce issues without touching production data. Enable both stores below, then switch with **Prod / QA** in the navigation bar (immediate) or change the active environment here and **Save**.",dataEnvDualLabel:"Enable separate production and QA data stores",dataEnvDualDesc:"When on, SQLite and local state use either `v4` (production) or `v4-qa` (QA) depending on the active environment. When off, only the production store is used.",dataEnvActiveLabel:"Active environment",dataEnvActiveDesc:"Folder opened by this server process. You can also switch from the navigation bar without opening Settings.",dataEnvActiveProduction:"Production (v4)",dataEnvActiveQa:"QA (v4-qa)",dataEnvActivePath:"Data directory in use (this process)",dataEnvPreferredPath:"Saved preference (should match when in sync)",dataEnvProdPath:"Production directory (v4)",dataEnvQaPath:"QA directory (v4-qa)",dataEnvPrefsFile:"Preference file on disk",dataEnvTraceOverride:"The server was started with TRACE_DATA_DIR; that path is used and these options are disabled.",dataEnvRestartHint:"Your saved environment no longer matches the open database. Restart the Kronosys server to apply it.",sectionWorkspaceLoc:"Reporting — workspace code snapshot",sectionTagsProjects:"Tags & saved projects",sectionTaskTemplates:"Task templates",taskTemplatesIntro:"Saved lines for the “what are you working on” field (title, optional #tags and @project). You can still save a template from an active or completed task on the dashboard.",taskTemplatesHelpAria:"Help: task templates",taskTemplatesHelpBody:"Templates only prefill the task draft — they do not start a timer or change recorded tasks.\n\nUse the same syntax as on the dashboard: a title, optional #tags, optional @project. Editing or deleting a template does not modify existing sessions or tasks.",taskTemplatesEmpty:"No task templates yet. Add one above or save one from the dashboard.",taskTemplatesDraftPlaceholder:"e.g. Deep work #focus @acme",taskTemplatesAddBtn:"Add template",taskTemplatesSavedToast:"Task template saved.",taskTemplatesRemovedToast:"Task template removed.",taskTemplatesUpdatedToast:"Task template updated.",taskTemplatesColDraft:"Template",taskTemplatesColUpdated:"Updated",taskTemplatesColActions:"Actions",taskTemplatesEditBtn:"Edit template",taskTemplatesSaveBtn:"Save changes",taskTemplatesCancelBtn:"Cancel",taskTemplatesDeleteBtn:"Delete template",taskTemplatesDeleteConfirm:"Remove this task template from the saved list?",tagsProjectsIntro:"Manage global tags, saved projects, and project-linked tags separately. The same controls appear in the right column on the main dashboard. Actions here do not bulk-edit tasks or session files.",tagsProjectsHelpAria:"Help: impact of tag and project changes",tagsProjectsHelpBody:"This page is split into three areas: global tags (no project), saved projects, then project-linked tags grouped under each project.\n\nHide (eye-off icon): the tag no longer appears in suggestion chips. Tasks are unchanged.\n\nDelete permanently (trash icon): removes the tag from pinned and hidden lists and clears its description. Tasks are unchanged.\n\nPin icons: manage your pinned shortcut list.\n\nProject-scoped tags: use @Project#code in a task title (stored as Project#code). Suggestion chips only show that code when the task’s project matches Project.\n\nDescriptions: optional local notes; tooltips on dashboard chips.\n\nDelete project (trash): removes the project from the saved list, clears its description, and purges metadata for tags stored as Project#… under that project. Tasks are unchanged.",tagsGlobalHeading:"Global tags (no project)",tagsGlobalIntro:"Shortcuts for tags that are not tied to a specific project. They are suggested on every task, regardless of @project.",tagsByProjectHeading:"Project-linked tags",tagsByProjectIntro:"Each block is a project key; tags stored as Project#code appear under that project. Pin, hide, and descriptions are still per tag.",tagsByProjectOrphanIntro:"Project#code scopes that do not match any saved project above. Pin or edit them here, or add the project to the list first.",tagsByProjectOrphanHelpAria:"Help: project-linked tags without a matching saved project",tocSubTagsGlobal:"Global tags",tocSubTagsProjects:"Projects",tocSubTagsByProject:"Tags by project",tagsHiddenHeading:"Hidden from shortcuts",tagsPinFieldLabel:"Pin a global tag",tagsPinPlaceholder:"e.g. bugfix or deep-work",tagsPinScopedFieldLabel:"Pin a project-linked tag",tagsPinScopedPlaceholder:"e.g. 204822-1530 or ClientABC#204822-1530",tagsPinAddBtn:"Pin",tagsTableTagCol:"Tag",tagsTableActionsCol:"Actions",tagBadgePinned:"Pinned",tagPinBtn:"Add tag to pinned shortcuts",tagUnpinBtn:"Remove tag from pinned shortcuts",tagExcludeBtn:"Hide tag from suggestion shortcuts",tagRestoreBtn:"Show tag in shortcuts again",tagPurgeAriaLabel:"Delete tag metadata permanently",tagPurgeConfirm:"Permanently delete this tag’s metadata? Its description will be cleared, it will be unpinned, and it will be hidden from dashboard tag lists (it appears under “Hidden from shortcuts” if tasks still reference it). Tasks are not modified.",tagPurgeHiddenConfirm:"Remove this tag from the hidden list and clear its description? If tasks still use it, it can show again in shortcuts. Tasks are not modified.",tagPurgeHiddenAriaLabel:"Permanently delete this hidden tag’s metadata",tagRenameBtn:"Rename tag",tagRenamePrompt:"New tag name",tagRenameImpactConfirm:"Rename this tag everywhere? Reporting and historical task breakdowns will now use the new name. Existing sessions and task entries will be updated.",renameImpactDontShowAgain:"Remember this choice and don’t show again",tagUnpinConfirm:"Remove this tag from your pinned list? It may still appear if used on tasks.",tagExcludeConfirm:"Hide this tag from dashboard shortcuts? Task and session data are not changed; existing tasks keep the tag and reporting can still count it.",projectsHeading:"Saved projects",projectsIntro:"Projects you added via @project or the dashboard.",projectsHelpAria:"Help: saved projects",projectsHelpBody:"Deleting a project (trash icon) removes it from the saved list, clears its description, and purges metadata for tags stored as Project#… for that project. Tasks are not modified; any task that still references @project keeps it.",projectsAddFieldLabel:"Add a project",projectsAddPlaceholder:"e.g. ClientABC",projectsAddBtn:"Add project",projectsTableProjectCol:"Project",projectsRenameBtn:"Rename project",projectsRenamePrompt:"New project name",projectRenameImpactConfirm:"Rename this project everywhere? Reporting by project and historical task breakdowns will now use the new name. Existing sessions and task entries will be updated.",projectsRemoveBtn:"Delete project and related tag metadata",projectRemoveConfirm:"Permanently delete this project’s metadata? It will be removed from the saved list, its description cleared, and pinned/hidden/description data for tags in the form Project#… under this project will be removed. Tasks are not modified.",tagDescriptionLabel:"Description (tooltip in dashboard)",projectDescriptionLabel:"Description (tooltip in dashboard)",descriptionSaveBtn:"Save description",tagStartTrackedTaskBtn:"Start tracking a task with this tag (and project if linked)",tagStartTrackedTaskFromProjectBtn:"Start tracking a task with this project",tagStartTaskAutoSessionToast:"No active session — starting one now so your task can be tracked in this session.",tagStartTaskConflictTitle:"Tracking already active",tagStartTaskConflictMessage:"One or more tasks already have a running timer. Choose what to do with them before starting this task: finish them (moved to completed), pause them (resume later from the paused list), or keep them running and start this task in parallel.",tagStartTaskConflictPauseBtn:"Pause active tasks",tagStartTaskConflictFinishBtn:"Finish active tasks",tagStartTaskConflictParallelBtn:"Start in parallel (keep timers running)",tagStartTaskConflictDontShowAgain:"Remember this choice and don’t show this dialog again (the same action will run automatically next time).",tagsScopeToolHeading:"Tag scope migration",tagsScopeToolSourceLabel:"Source tag",tagsScopeToolTargetProjectLabel:"Target project scope",tagsScopeToolTargetGlobalOption:"Global (no project)",tagsScopeToolCopyBtn:"Copy to target scope",tagsScopeToolMoveBtn:"Move to target scope",tagsScopeToolNoTags:"No known tag available to migrate yet.",tagsEmptyGlobal:"No global tags in shortcuts yet. Pin one above or add #tags on tasks.",tagsByProjectSectionEmpty:"No project-linked tags in shortcuts yet. Use @Project#code on a task or pin one below.",tagsByProjectSubEmpty:"No linked tag for this project in shortcuts yet.",projectsEmpty:"No saved projects yet. Use @project on a task or pick a project on the dashboard.",hiddenTagsEmpty:"No tags hidden.",workspaceLocExcludedDirs:"Excluded directory name segments",workspaceLocExcludedDirsDesc:"One name per line (a single path segment, not a full path). If any segment of a file path equals a listed name, that file is skipped — for both Git-tracked lists and folder walks. Examples: node_modules, .git, .husky, .venv, dist.",workspaceLocExcludedPatterns:"Excluded path patterns",workspaceLocExcludedPatternsDesc:"One pattern per line (minimatch syntax: *, ?, **), relative to the workspace root. Examples: **/*.min.js, generated/**, **/*.gen.ts. After saving, refresh the snapshot from the Reporting page.",pickStorageFolder:"Choose folder…",hintPortRestart:"After changing the port, restart the Kronosys server process so the API listens on the new port.",hintDashboardUrl:"Display-only reference URL; does not start the Next.js server.",tocSubDashboardTour:"Guided tour",tocSubReportingTour:"Reporting tour",tocSubDashboardColumnHints:"Three-column guide",dashboardColumnHintsBlockTitle:"Three-column guide on the dashboard",dashboardColumnHintsBlockIntro:"If you removed the strip under the dashboard header (X button), restore it here. This preference is stored in the browser for this site.",dashboardColumnHintsRestoreBtn:"Show three-column guide again",dashboardColumnHintsRestoreDone:"Preference reset. Open the dashboard to see the strip.",tagsProjectsTabsAriaLabel:"Tags column sections",tagsProjectsTabGlobal:"Global tags",tagsProjectsTabProjects:"Projects & linked tags",tagsProjectsTabTemplates:"Task templates",tocSubSessionDurationAlert:"Session duration alert",tocSubDefaultSessionNameTemplate:"Default session name",dashboardSessionDurationAlertHours:"Session duration alert (hours)",dashboardSessionDurationAlertHoursDesc:"Wall-clock session duration in the dashboard sidebar: when it reaches this many hours or more, the value is shown in red with a slow blink. Default: 24. Range: 1–8760.",dashboardTourBlockTitle:"Dashboard guided tour",dashboardTourBlockIntro:"Five short steps explain sessions, tasks, tags, and shortcuts. You can reopen the tour anytime from here.",dashboardTourReplayLinkLabel:"Open dashboard and start tour",reportingTourBlockTitle:"Reporting guided tour",reportingTourBlockIntro:"Filters, KPIs, charts, and tag/project splits on the Reporting page. You can reopen this walkthrough anytime.",reportingTourReplayLinkLabel:"Open Reporting and start tour",enabled:"Enable activity collection",enabledDesc:"Global switch for activity collection.",autoStart:"Auto-start",autoStartDesc:"Start collection when the Kronosys process starts.",sectionSchedule:"Work Schedule",scheduleEnabled:"Enable automatic schedule",scheduleEnabledDesc:"Automatically start and stop tracking sessions based on your working hours.",scheduleDays:"Active days",scheduleDaysDesc:"Days of the week when auto-tracking is active.",scheduleStartTime:"Start time",scheduleEndTime:"End time",timePickerPopoverTimeLabel:"Time (24 h)",timePickerPopoverHourAria:"Hour (24 h)",timePickerPopoverMinuteAria:"Minutes",scheduleCreateDailySession:"Create daily session",scheduleCreateDailySessionDesc:"Automatically create a new session at the schedule start time for each active day.",scheduleTransferTasks:"Transfer active tasks",scheduleTransferTasksDesc:"Automatically transfer active tasks from the previous session into the new session.",schedulePauseTasks:"Pause tasks on stop",schedulePauseTasksDesc:"Automatically pause active tasks when the work schedule ends.",sectionPlannedSessions:"Specific Planned Sessions",plannedSessionsIntro:"Add specific recurring sessions. These take precedence over the general work schedule during their time block.",plannedSessionAdd:"Add planned session",plannedSessionName:"Session name",plannedSessionTags:"Tags (comma-separated)",plannedSessionProject:"Project",plannedSessionRemove:"Remove this session",showWelcome:"Welcome screen",showWelcomeDesc:"Show welcome until dismissed.",anonymizePaths:"Anonymize paths",anonymizePathsDesc:"Hash file paths before writing events.",flushInterval:"Flush interval (seconds)",flushIntervalDesc:"How often buffered events are written to storage (5–3600).",heartbeatInterval:"Heartbeat interval (seconds)",heartbeatIntervalDesc:"Minimum time between heartbeat events (30–86400).",maxBuffered:"Max buffered events",maxBufferedDesc:"Events kept in memory before trimming (100–100000).",historyPath:"History storage path",historyPathDesc:"Leave empty for the default application data directory. ~ is your home directory.",historyPartition:"History file partition",historyPartitionDesc:"How session files are split on disk.",localPersistenceDriver:"Local session storage",localPersistenceDriverDesc:"JSON keeps the legacy partitioned files. SQLite stores sessions in a single database file in the same folder; existing JSON is imported once. MongoDB mirror (if enabled) is unchanged. Restart the process after changing this.",persistenceDriverJson:"JSON files",persistenceDriverSqlite:"SQLite",localPersistenceReloadHint:"After changing the driver, restart the Kronosys process so the new setting is applied.",partitionDaily:"Daily",partitionWeekly:"Weekly",partitionMonthly:"Monthly",sessionStartMode:"When tracking starts",sessionStartModeDesc:"Continue previous session or always start fresh.",modeContinue:"Continue previous session",modeNew:"Always new session",exportFormat:"Default export format",exportFormatDesc:"Used for session history exports.",fmtJson:"JSON",fmtCsv:"CSV",fmtJira:"Jira table",fmtSap:"SAP",csvDelimiter:"CSV delimiter",csvDelimiterDesc:"Single character, e.g. , or ;",autoGitSync:"Auto Git sync",autoGitSyncDesc:"Optional: after each local save, commit and push the history folder to your remote. Session list still loads from local JSON only.",gitRemoteUrl:"Git remote URL",gitRemoteUrlDesc:"Required if auto sync is enabled.",tocSubGitIdentity:"Git author (dashboard)",gitIdentitySubheading:"Git author shown in the dashboard",gitIdentityIntro:"Stored locally with your Kronosys data (SQLite). Shown in the dashboard header next to workspace paths — this does not run git config on your machine.",gitIdentityNameLabel:"Display name",gitIdentityNameDesc:"Like git config user.name (how you want to be credited).",gitIdentityEmailLabel:"Email",gitIdentityEmailDesc:"Like git config user.email (for display only here).",gitIdentityLoginLabel:"Forge username",gitIdentityLoginDesc:"Optional: GitHub, GitLab, or other host login (not the same as the display name).",gitIdentitySave:"Save Git author",gitIdentitySaving:"Saving…",gitIdentitySavedFlash:"Git author saved.",glabRemoteSuggest:"GitLab CLI (glab) is available and a token is configured: you can create a private remote named kronosys-sessions and enable auto sync in one step.",glabRemoteCreate:"Create GitLab repo with glab",glabRemoteCreating:"Creating repository…",gitlabToken:"GitLab token",gitlabTokenDesc:"Optional personal access token for glab (private repo creation, issue list). In this dashboard, saving stores the token in local SQLite (not in the JSON state) so issue import can call GitLab; it overrides GITLAB_TOKEN from the server environment when saved. Use Test connection to enable “Import issue from Git”.",gitlabTokenSave:"Save token",gitlabTokenClear:"Clear stored token",gitlabTokenSaveNeedValue:"Paste your token in the field first — saving with an empty field does not keep a secret on this server.",gitlabTokenStoredYes:"A token is stored in the local secret store; it takes precedence over GITLAB_TOKEN when calling glab.",gitlabTokenFromEnvYes:"No stored token; glab uses GITLAB_TOKEN from the server environment.",gitlabTokenNone:"No token yet — save one below or set GITLAB_TOKEN for the dashboard server process.",gitlabInstanceUrl:"GitLab instance URL",gitlabInstanceUrlDesc:"Origin only (no /api/v4 path). Leave empty for GitLab.com. For self-managed GitLab, set your instance (e.g. https://gitlab.example.org). You can also set GITLAB_INSTANCE_URL on the server process.",gitlabTest401Help:"401 usually means the token does not match this host (wrong instance URL), or the token is expired, revoked, or missing the api scope.",gitlabTestConnection:"Test GitLab connection",gitlabTestConnectionAria:"Test GitLab API token",gitlabTestRunning:"Testing GitLab…",gitlabTestOk:"GitLab API responded successfully. Issue import is enabled in the task column.",gitlabTestFail:"GitLab API test failed. Check the token, the instance URL field above, and your network.",gitlabTestNoToken:"No token to test: paste a token in the field, save it, or ensure GITLAB_TOKEN is available to this dashboard process when using the environment token.",gitlabTestErrorGeneric:"Could not run the GitLab connection test.",gitlabApiVerifiedYes:"GitLab API: verified — task issue import is available.",gitlabApiVerifiedNo:"GitLab API: not verified — run Test connection to enable task issue import.",gitlabTestPasteStoredHint:"To test a token already saved locally, paste it temporarily in the field above (this dashboard cannot read the secret back from storage).",historyLocalFirstHint:"Session history is read from local JSON files or SQLite (see Local session storage). Git auto-sync pushes the folder after saves when enabled. MongoDB is updated only when you push sessions from the dashboard or use Resync in settings.",mongoEnabled:"MongoDB integration",mongoEnabledDesc:"When enabled, you can push individual sessions to MongoDB from the dashboard (and bulk-resync in settings). Nothing is sent automatically on each save. The dashboard still reads local storage only (JSON or SQLite).",mongoDatabase:"MongoDB database",mongoDatabaseDesc:"Database name (letters, digits, underscore, hyphen).",mongoCollection:"MongoDB collection",mongoCollectionDesc:"Collection name (one document per session).",sectionMongoConnection:"MongoDB connection",mongoConnectionIntro:"Build mongodb://user:pass@host:port/?authSource=… from the fields below, or set a full URI in Advanced. A stored full URI takes precedence. Main Save also applies host/port/user/auth and stores password or manual URI when those fields are not empty.",mongoHost:"Host",mongoHostDesc:"Hostname or IP (e.g. 127.0.0.1).",mongoPort:"Port",mongoPortDesc:"TCP port (default 27017).",mongoUser:"Username",mongoUserDesc:"Leave empty for no authentication. If set, a password is required (stored in the secret store).",mongoPassword:"Password",mongoPasswordDesc:"Stored in the local secret store only. Use Save password or the main Save button when the field is not empty.",mongoPasswordSave:"Save password",mongoPasswordClear:"Clear stored password",mongoPasswordConfiguredYes:"A password is stored.",mongoPasswordConfiguredNo:"No password stored.",mongoAuthSource:"authSource",mongoAuthSourceDesc:"Database for authentication (often admin).",mongoManualUri:"Full URI (advanced)",mongoManualUriDesc:"If set, this URI is used instead of host/user/password. Stored in the secret store. Clear to use the built connection again.",mongoUri:"Connection URI",mongoUriDesc:"mongodb:// or mongodb+srv:// — main Save stores this when not empty.",mongoUriSave:"Save URI",mongoUriClear:"Clear stored URI",mongoUriConfiguredYes:"A full connection URI is stored (advanced).",mongoUriConfiguredNo:"No full URI stored; built connection is used when possible.",mongoRemoteStatus:"MongoDB status",mongoStatusConnected:"Connected",mongoStatusFailed:"Failed or misconfigured",mongoStatusPending:"Checking…",mongoConnectionResolvableYes:"Connection parameters are sufficient.",mongoConnectionResolvableNo:"Incomplete (e.g. set password if username is filled).",mongoTestConnection:"Test connection",mongoTestConnectionAria:"Test MongoDB connection",mongoTestRunning:"Testing connection…",mongoTestOk:"Connection test succeeded (ping on the configured database).",mongoTestFail:"Connection test failed. Check host, port, credentials, URI, and network.",mongoTestDisabled:"Enable the MongoDB mirror above to run a connection test.",mongoTestErrorGeneric:"Could not run the connection test via the local API.",mongoTestUsesSavedConfigHint:"Host, port, database, collection, and user below are used for the test even if you have not clicked Save. A stored full URI or password (via the dedicated buttons) always comes from the local secret store.",mongoSyncSectionTitle:"Local vs MongoDB",mongoResyncButton:"Resync all sessions to MongoDB",mongoResyncAriaLabel:"Resync all local sessions to the MongoDB mirror",mongoResyncConfirm:"Upsert every local session snapshot into MongoDB? This can take a moment if you have many sessions.",mongoResyncRunning:"Resyncing…",mongoResyncDone:"Resync finished: {upserted} sessions written, {failed} failed.",mongoResyncHint:"Upserts every local session into MongoDB and updates push metadata in JSON. Extra documents already in MongoDB are not deleted.",mongoResyncDisabled:"Enable the MongoDB mirror in settings before resyncing.",mongoResyncUnsupported:"This storage backend does not support Mongo resync.",mongoResyncErrorGeneric:"Could not run the resync action.",mongoResyncErrorDetail:"Resync failed: {detail}",workspaceFoldersLabel:"Workspace roots",workspaceFoldersEmpty:"No workspace root is configured for this dashboard.",localApiPort:"Local API port",localApiPortDesc:"Loopback HTTP API for this dashboard (127.0.0.1 only).",dashboardWebUrl:"Dashboard URL (display)",dashboardWebUrlDesc:"Suggested URL for opening the dashboard in a browser (e.g. bookmarks). Use a loopback URL (localhost, 127.0.0.1, [::1]) or a hostname in /etc/hosts that resolves to loopback (e.g. kronosys).",dashboardDisplayTimeZone:"Display time zone",dashboardDisplayTimeZoneDesc:"Used for session dates on the dashboard, task timestamps, and reporting day buckets. Pick a suggestion or type any IANA time zone (e.g. Europe/Brussels). Default is Eastern Time (America/Toronto).",dashboardClockFormat:"Clock format",dashboardClockFormatDesc:"How times are shown on the dashboard (task start/end, past-task date preview) and in schedule time previews. Dates are unchanged.",dashboardClock24hOption:"24-hour",dashboardClock12hOption:"12-hour (AM/PM)",dashboardCalendarWeekStartsOn:"Week starts on",dashboardCalendarWeekStartsOnDesc:"First column in date-picker calendars (dashboard task times, past sessions) and weekly grids in Reports. The date filter preset “Week” still uses Monday–Sunday.",calendarWeekStartsSunday:"Sunday",calendarWeekStartsMonday:"Monday",calendarWeekStartsSaturday:"Saturday",dashboardLightThemeVariant:"Light theme tint",dashboardLightThemeVariantDesc:"Applies when the dashboard is in light mode (moon icon in the toolbar). Dark mode is unchanged. Your choice is saved in this browser and in local settings.",dashboardLightThemeWarm:"Warm",dashboardLightThemeSoft:"Soft",dashboardLightThemeContrast:"High contrast",dashboardSemanticChipAccessibleMode:"Do not rely on color alone",dashboardSemanticChipAccessibleModeDesc:"When enabled, tag, work project, and personal project chips show #, @, and ! prefixes plus distinct border styles (solid, double, dashed) in addition to their colors — on the dashboard, reporting filters, and anywhere those chips appear. Saved in this browser and in local settings.",dashboardBaseDailyHours:"Base daily hours",dashboardBaseDailyHoursDesc:"Reference hours per day for variance tracking in Billing allocation reports.",dashboardBaseDailyToleranceMinutes:"Tolerance (minutes)",dashboardBaseDailyToleranceMinutesDesc:"Allowed deviation from base hours before highlighting (default: 10 min).",dashboardDefaultSessionNameTemplate:"Default new session name template",dashboardDefaultSessionNameTemplateDesc:"Applied when a brand-new live session is created (dashboard “New session”, or the implicit session when the first task starts with no session yet). Leave empty to leave the name blank. Tokens: `%%` for a literal percent; `%UUID` for the full session id; `%Y` `%y` `%m` `%d` `%H` `%M` `%S` plus `%F` (same as `%Y-%m-%d`) follow POSIX strftime semantics (IEEE / Open Group reference: https://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html). Note: `%m` is the month; `%M` is minutes. Expansion uses the Display time zone chosen above (consistent with dashboard reporting day buckets).",invalidDashboardTimeZone:"Unrecognized time zone. Enter a valid IANA name (e.g. America/Toronto).",dialogOkBtn:"OK",dialogCancelBtn:"Cancel",dialogConfirmBtn:"Confirm",scrollToTopAria:"Back to top",licensesPageLink:"Licenses & third-party notices"},e={title:"Param\xe8tres",subtitle:"Options Kronosys enregistr\xe9es localement sur cette machine.",loading:"Chargement des param\xe8tres…",reload:"Recharger depuis le serveur",save:"Enregistrer",saving:"Enregistrement…",savedOk:"Param\xe8tres enregistr\xe9s.",settingsUnsavedStickyHint:"Modifications non enregistr\xe9es.",resetToDefaults:"R\xe9initialiser aux valeurs par d\xe9faut",resetToDefaultsConfirm:"R\xe9tablir toutes les options Kronosys \xe0 leurs valeurs d’usine ? Les jetons GitLab et les indicateurs de connexion MongoDB d\xe9j\xe0 enregistr\xe9s dans le stockage s\xe9curis\xe9 ne sont pas supprim\xe9s ; seuls les champs de configuration affich\xe9s sur cette page sont remis \xe0 z\xe9ro.",resettingDefaults:"R\xe9initialisation…",resetDefaultsDone:"Valeurs par d\xe9faut appliqu\xe9es.",openIdeSettings:"Ces champs correspondent aux cl\xe9s de configuration persist\xe9es dans le stockage local.",tocHeading:"Sur cette page",tocNavAriaLabel:"Aller \xe0 une section des param\xe8tres",tocSearchPlaceholder:"Filtrer le sommaire…",tocSearchAriaLabel:"Filtrer les sections affich\xe9es dans le sommaire",tocSearchNoResults:"Aucun titre de section ne correspond.",sectionUsageProfile:"Profil d’utilisation",usageProfile:"Profil",usageProfileDesc:"D\xe9veloppeur : lignes \xe9crites, stats par langage, signaux de codage, instantan\xe9 LOC et carte Git du d\xe9p\xf4t. Gestionnaire : t\xe2ches, sessions, KronoFocus et temps seulement — pas de m\xe9triques ni d’affichages li\xe9s au code source.",profileDeveloper:"D\xe9veloppeur",profileManager:"Gestionnaire",workspaceLocSectionHiddenManager:"Ces options ne s’appliquent qu’au profil D\xe9veloppeur (instantan\xe9 lignes de code dans Rapports).",sectionGeneral:"G\xe9n\xe9ral",sectionPrivacy:"Confidentialit\xe9",sectionKronoFocus:"KronoFocus (tableau de bord)",kronoFocusHeaderPinnedNote:"Le minuteur KronoFocus et ses contr\xf4les restent toujours dans la barre d’outils de l’application (\xe0 c\xf4t\xe9 de l’horloge et de la palette de commandes), afin que la barre de navigation garde la m\xeame largeur sur toutes les pages. En consultation d’archive, les contr\xf4les restent visibles mais ciblent la session live.",kronoFocusShowInTaskOps:"Afficher dans les boutons op\xe9rationnels des t\xe2ches",kronoFocusShowInTaskOpsDesc:"Bouton pour lancer le KronoFocus depuis une t\xe2che suivie et option \xab lancer aussi le KronoFocus \xbb lors de la cr\xe9ation d’une t\xe2che.",sectionTaskTags:"T\xe2ches et \xe9tiquettes",taskDefaultTagBucketEnabled:"\xc9tiquette \xab d\xe9faut \xbb pour les t\xe2ches sans #",taskDefaultTagBucketEnabledDesc:"Activ\xe9 : une t\xe2che sans aucune \xe9tiquette explicite re\xe7oit l’\xe9tiquette r\xe9serv\xe9e (affich\xe9e \xab d\xe9faut \xbb). D\xe9sactiv\xe9 : la liste d’\xe9tiquettes reste vide jusqu’\xe0 ce que vous en ajoutiez une.",taskStripDefaultTagWhenExplicitTags:"Retirer \xab d\xe9faut \xbb lorsqu’une autre \xe9tiquette est ajout\xe9e",taskStripDefaultTagWhenExplicitTagsDesc:"Activ\xe9 : d\xe8s qu’une t\xe2che re\xe7oit au moins une \xe9tiquette explicite (#autre que \xab d\xe9faut \xbb), l’\xe9tiquette r\xe9serv\xe9e \xab d\xe9faut \xbb est retir\xe9e automatiquement. D\xe9sactiv\xe9 : \xab d\xe9faut \xbb peut coexister avec d’autres \xe9tiquettes.",taskMinimumDurationMinutes:"Dur\xe9e minimale d’une t\xe2che (minutes)",taskMinimumDurationMinutesDesc:"\xc9cart par d\xe9faut pour la saisie pass\xe9e ou planifi\xe9e : la fin est pr\xe9remplie au d\xe9but plus cette dur\xe9e (ex. 30 ou 60). Plage : 15–480.",dashboardAllowTaskStartTimeEdit:"Autoriser la correction de l’heure de d\xe9but des t\xe2ches dans le tableau de bord",dashboardAllowTaskStartTimeEditDesc:"Affiche des contr\xf4les pour modifier l’heure de d\xe9but d’une t\xe2che dans la colonne T\xe2ches, pendant son ex\xe9cution ou apr\xe8s sa fin.",dashboardAllowSessionStartTimeEdit:"Autoriser la correction de l’heure de d\xe9but des sessions dans le tableau de bord",dashboardAllowSessionStartTimeEditDesc:"Affiche des contr\xf4les pour modifier l’heure de d\xe9but d’une session dans la colonne Sessions, en cours ou dans l’historique.",dashboardAllowTaskEndTimeEdit:"Autoriser la correction de l’heure de fin des t\xe2ches dans le tableau de bord",dashboardAllowTaskEndTimeEditDesc:"Affiche des contr\xf4les pour d\xe9finir ou modifier l’heure de fin d’une t\xe2che dans la colonne T\xe2ches, y compris pendant son ex\xe9cution (la t\xe2che se termine automatiquement \xe0 l’heure planifi\xe9e).",dashboardAllowSessionEndTimeEdit:"Autoriser la correction de l’heure de fin des sessions dans le tableau de bord",dashboardAllowSessionEndTimeEditDesc:"Affiche des contr\xf4les pour d\xe9finir ou modifier l’heure de fin d’une session dans la colonne Sessions, y compris sur une session live (la session se cl\xf4t automatiquement \xe0 l’heure planifi\xe9e).",sectionCollection:"Collecte et tampons",sectionHistory:"Historique des sessions",sectionDangerZone:"Zone de danger",dangerClearHistoryTitle:"Effacer toutes les donn\xe9es locales du tableau de bord",dangerClearHistoryBodyIntro:"Supprime d\xe9finitivement, dans le stockage local de ce tableau de bord :",dangerClearHistoryBodyBullets:["Toutes les sessions (vue en cours, liste principale et archives) ainsi que la session consult\xe9e","Toute la m\xe9tadonn\xe9e \xe9tiquettes / projets : raccourcis \xe9pingl\xe9s, \xe9tiquettes masqu\xe9es des pastilles, descriptions, listes de suggestions connues","L’identit\xe9 Git enregistr\xe9e ici (nom affich\xe9, courriel, identifiant forge) et les donn\xe9es de la carte statistiques Git","L’instantan\xe9 lignes de code du workspace mis en cache pour Rapports (profil D\xe9veloppeur)","La pr\xe9f\xe9rence locale \xab ne plus demander confirmation d’archivage \xbb","La langue du tableau de bord m\xe9moris\xe9e dans le navigateur et le marqueur de choix explicite (vous choisirez \xe0 nouveau anglais ou fran\xe7ais avant la visite guid\xe9e)"],dangerClearHistoryBodyAfterList1:"Ensuite, la visite guid\xe9e d’accueil sera repropos\xe9e sur le tableau de bord et l’option \xab \xe9cran d’accueil au d\xe9marrage \xbb est r\xe9activ\xe9e dans les param\xe8tres.",dangerClearHistoryBodyAfterList2:"Action irr\xe9versible.",dangerClearHistoryButton:"Tout effacer…",dangerClearHistoryConfirm:"Vous effacez tout ce qui est d\xe9crit ci-dessus dans la zone de danger (sessions, m\xe9tadonn\xe9es \xe9tiquettes/projets, identit\xe9 Git dans ce stockage, etc.). Poursuivre ?",dangerClearHistoryVaultTargetTitle:"Coffre cibl\xe9 par cet effacement",dangerClearHistoryVaultTargetTrace:"L’effacement porte sur le r\xe9pertoire impos\xe9 par TRACE_DATA_DIR : {path}. Aucun autre coffre Kronosys n’est concern\xe9.",dangerClearHistoryVaultTargetDual:"L’effacement ne concerne que le coffre {env} actuellement charg\xe9 par ce serveur ({path}). Le coffre {otherEnv} ({otherPath}) n’est pas modifi\xe9.",dangerClearHistoryVaultTargetSingle:"L’effacement porte sur le r\xe9pertoire de donn\xe9es actuellement charg\xe9 par ce serveur ({path}).",dangerClearHistoryVaultTargetDev:"L’effacement porte sur le r\xe9pertoire de d\xe9veloppement actuellement charg\xe9 par ce serveur ({path}), pas sur le coffre production packag\xe9 sauf si vous le partagez explicitement.",dangerClearHistoryVaultMismatch:"Attention : la pr\xe9f\xe9rence enregistr\xe9e vise {preferredEnv} ({preferredPath}) au prochain red\xe9marrage, mais ce processus utilise encore {activePath}. L’effacement portera sur le r\xe9pertoire en cours d’utilisation.",dangerClearHistoryConfirmPhrase:"EFFACER",dangerClearHistoryTypeInstruction:"Pour activer \xab Confirmer \xbb, saisissez exactement {phrase} ci-dessous (toutes majuscules, sans espaces).",dangerClearHistoryTypeFieldLabel:"Mot de confirmation",dangerClearHistoryTypeInputAria:"Saisir le mot de confirmation pour autoriser l’effacement complet d\xe9crit ci-dessus (sessions, m\xe9tadonn\xe9es, identit\xe9 Git, etc.)",dangerClearHistoryBackupIntro:"Avant de confirmer, vous pouvez t\xe9l\xe9charger une copie locale (les m\xeames donn\xe9es que le tableau de bord sur cette machine) :",dangerClearHistoryBackupJson:"JSON — instantan\xe9 complet d’\xe9tat",dangerClearHistoryBackupJsonHint:"Charge utile Kronosys enti\xe8re dans un seul fichier (sessions y compris la session active `current`, t\xe2ches, m\xe9tadonn\xe9es \xe9tiquettes/projets, identit\xe9 Git, `cfg`, instantan\xe9 statistiques Git, instantan\xe9 lignes de code du workspace, etc.).",dangerClearHistoryBackupCsvBlockTitle:"CSV — plusieurs tableaux (un t\xe9l\xe9chargement par lien)",dangerClearHistoryBackupCsvBlockHint:"R\xe9unis, ces fichiers refl\xe8tent ce que l’effacement de la zone de danger supprime : sessions (avec une colonne JSON compl\xe8te par ligne), chaque t\xe2che et sous-t\xe2che, listes et descriptions d’\xe9tiquettes/projets, identit\xe9 Git, ainsi que la configuration et les blocs JSON (`cfg`, stats Git, instantan\xe9 lignes de code, session inspect\xe9e, etc.).",dangerClearHistoryBackupCsvZip:"CSV — tous les tableaux (ZIP)",dangerClearHistoryBackupCsvZipHint:"Un seul t\xe9l\xe9chargement contenant les huit fichiers CSV en UTF-8.",dangerClearHistoryBackupCsvSeparateTitle:"Fichiers s\xe9par\xe9s (optionnel)",dangerClearHistoryBackupCsvSessions:"Sessions — indicateurs \xe9tendus + JSON de session complet",dangerClearHistoryBackupCsvTasks:"T\xe2ches — une ligne par t\xe2che + JSON de t\xe2che complet",dangerClearHistoryBackupCsvSubtasks:"Sous-t\xe2ches — une ligne par \xe9l\xe9ment de liste + JSON",dangerClearHistoryBackupCsvRegistry:"Registre \xe9tiquettes / projets — listes connues, \xe9pingl\xe9es, masqu\xe9es",dangerClearHistoryBackupCsvTagDesc:"Descriptions d’\xe9tiquettes",dangerClearHistoryBackupCsvProjectDesc:"Descriptions de projets",dangerClearHistoryBackupCsvGitId:"Identit\xe9 Git (enregistr\xe9e dans ce stockage)",dangerClearHistoryBackupCsvStoreBlobs:"Configuration et instantan\xe9s — `cfg`, stats Git, LOC workspace, pr\xe9f\xe9rences d’affichage",dangerClearHistoryBackupSqlite:"SQLite — fichier de base de donn\xe9es",dangerClearHistoryBackupSqliteHint:"Fichier kronosys.sqlite apr\xe8s pointage WAL (restauration en rempla\xe7ant le fichier \xe0 l’arr\xeat de l’application).",dangerBackupRestoreTitle:"Sauvegardes et restauration compl\xe8te",dangerBackupRestoreIntro:"T\xe9l\xe9chargez d’abord une sauvegarde compl\xe8te, puis restaurez un fichier de sauvegarde ant\xe9rieur au besoin (instantan\xe9 JSON ou fichier SQLite).",dangerRestorePickFile:"Fichier de restauration (`.json` ou `.sqlite`)",dangerRestoreHint:"La restauration remplace le stockage local courant sur cette machine. Faites une sauvegarde juste avant si vous avez un doute.",dangerRestoreButton:"Restaurer depuis une sauvegarde…",dangerRestoreBusy:"Restauration…",dangerRestoreConfirm:"Restaurer ce fichier de sauvegarde maintenant ? Le stockage local courant sera remplac\xe9 pour cet environnement.",dangerRestoreNoFile:"Choisissez un fichier de sauvegarde avant de lancer la restauration.",dangerRestoreDoneJson:"Restauration termin\xe9e depuis l’instantan\xe9 JSON. Les donn\xe9es du tableau de bord ont \xe9t\xe9 recharg\xe9es.",dangerRestoreDoneSqlite:"Restauration termin\xe9e depuis le fichier SQLite. Les donn\xe9es du tableau de bord ont \xe9t\xe9 recharg\xe9es.",dangerRestoreFailed:"\xc9chec de la restauration : {detail}",sectionArchivedSessions:"Sessions archiv\xe9es",archivedSessionsIntro:"Sessions retir\xe9es de la liste principale du tableau de bord, tri\xe9es par enregistrement le plus r\xe9cent. Restaurer les r\xe9int\xe8gre dans la colonne Sessions.",archivesPaginationPrev:"Page pr\xe9c\xe9dente",archivesPaginationNext:"Page suivante",archivesPaginationNavAria:"Pagination des sessions archiv\xe9es",archivesPaginationRange:"{from}–{to} sur {total}",sectionExport:"Export par d\xe9faut",sectionGit:"Synchronisation Git",sectionMongo:"Miroir MongoDB",sectionWeb:"Tableau de bord et API",devDataBlockTitle:"Mode d\xe9veloppement (coffre local)",devDataIntro:"Lorsque le serveur de d\xe9veloppement Next.js est utilis\xe9 (`next dev`), SQLite et l’\xe9tat local vont par d\xe9faut dans un dossier distinct (`…/v4-dev`) de l’instance de production (`next start`, `…/v4`) afin d’\xe9viter d’\xe9craser vos vraies donn\xe9es. Enregistrez avec le bouton **Enregistrer** en bas de page, comme les autres param\xe8tres.",devDataUseProdLabel:"Utiliser le m\xeame r\xe9pertoire de donn\xe9es qu’en production (v4)",devDataUseProdDesc:"D\xe9sactiv\xe9 (d\xe9faut) : le mode dev utilise un r\xe9pertoire isol\xe9 `v4-dev`. Activ\xe9 : le mode dev lit et \xe9crit le chemin `v4` comme une ex\xe9cution packag\xe9e ou `next start`. Apr\xe8s modification, red\xe9marrez le serveur de dev pour ouvrir le bon fichier SQLite.",devDataActivePath:"R\xe9pertoire de donn\xe9es utilis\xe9 (ce processus)",devDataPreferredPath:"S’appliquerait au prochain red\xe9marrage",devDataProdPath:"R\xe9pertoire production par d\xe9faut (v4)",devDataPrefsFile:"Fichier de pr\xe9f\xe9rence sur le disque",devDataTraceOverride:"Le serveur a \xe9t\xe9 lanc\xe9 avec TRACE_DATA_DIR ; ce chemin est utilis\xe9 et ce commutateur est d\xe9sactiv\xe9.",devDataEnvOverride:"La variable d’environnement KRONOSYS_DEV_USE_PROD_DATA est d\xe9finie ; le mode dev utilise le chemin v4 de production et ce commutateur est d\xe9sactiv\xe9.",devDataRestartHint:"La pr\xe9f\xe9rence enregistr\xe9e ne correspond plus \xe0 la base ouverte. Red\xe9marrez le serveur `next dev` pour l’appliquer.",devDataHiddenNotDev:"Ce bloc s’affiche seulement lorsque le tableau de bord est servi en mode d\xe9veloppement (`next dev`).",dataEnvBlockTitle:"Coffres production et QA",dataEnvIntro:"Conservez vos vraies sessions dans le dossier de production (`…/v4`) et utilisez un dossier QA distinct (`…/v4-qa`) pour essayer des fonctions ou reproduire un probl\xe8me sans toucher \xe0 la production. Activez les deux coffres ci-dessous, puis basculez avec **Prod / QA** dans la barre de navigation (effet imm\xe9diat) ou changez l’environnement actif ici et **Enregistrez**.",dataEnvDualLabel:"Activer deux coffres de donn\xe9es (production et QA)",dataEnvDualDesc:"Activ\xe9 : SQLite et l’\xe9tat local utilisent `v4` (production) ou `v4-qa` (QA) selon l’environnement actif. D\xe9sactiv\xe9 : seul le coffre de production est utilis\xe9.",dataEnvActiveLabel:"Environnement actif",dataEnvActiveDesc:"Dossier ouvert par ce processus serveur. Vous pouvez aussi basculer depuis la barre de navigation sans ouvrir les param\xe8tres.",dataEnvActiveProduction:"Production (v4)",dataEnvActiveQa:"QA (v4-qa)",dataEnvActivePath:"R\xe9pertoire de donn\xe9es utilis\xe9 (ce processus)",dataEnvPreferredPath:"Pr\xe9f\xe9rence enregistr\xe9e (doit correspondre si synchronis\xe9)",dataEnvProdPath:"R\xe9pertoire production (v4)",dataEnvQaPath:"R\xe9pertoire QA (v4-qa)",dataEnvPrefsFile:"Fichier de pr\xe9f\xe9rence sur le disque",dataEnvTraceOverride:"Le serveur a \xe9t\xe9 d\xe9marr\xe9 avec TRACE_DATA_DIR ; ce chemin est utilis\xe9 et ces options sont d\xe9sactiv\xe9es.",dataEnvRestartHint:"L’environnement enregistr\xe9 ne correspond plus \xe0 la base ouverte. Red\xe9marrez le serveur Kronosys pour l’appliquer.",sectionWorkspaceLoc:"Rapports — instantan\xe9 lignes de code",sectionTagsProjects:"\xc9tiquettes et projets enregistr\xe9s",sectionTaskTemplates:"Mod\xe8les de t\xe2che",taskTemplatesIntro:"Lignes enregistr\xe9es pour le champ \xab sur quoi travaillez-vous \xbb (titre, #\xe9tiquettes et @projet facultatifs). Vous pouvez aussi enregistrer un mod\xe8le depuis une t\xe2che en cours ou termin\xe9e sur le tableau de bord.",taskTemplatesHelpAria:"Aide : mod\xe8les de t\xe2che",taskTemplatesHelpBody:"Les mod\xe8les ne font que pr\xe9remplir le brouillon de t\xe2che — ils ne d\xe9marrent pas le minuteur ni ne modifient les enregistrements existants.\n\nM\xeame syntaxe que sur le tableau de bord : un titre, des #\xe9tiquettes facultatives, un @projet facultatif. Modifier ou supprimer un mod\xe8le ne change pas les sessions ou t\xe2ches d\xe9j\xe0 saisies.",taskTemplatesEmpty:"Aucun mod\xe8le de t\xe2che. Ajoutez-en un ci-dessus ou enregistrez-en un depuis le tableau de bord.",taskTemplatesDraftPlaceholder:"ex. Travail profond #focus @acme",taskTemplatesAddBtn:"Ajouter le mod\xe8le",taskTemplatesSavedToast:"Mod\xe8le de t\xe2che enregistr\xe9.",taskTemplatesRemovedToast:"Mod\xe8le de t\xe2che supprim\xe9.",taskTemplatesUpdatedToast:"Mod\xe8le de t\xe2che mis \xe0 jour.",taskTemplatesColDraft:"Mod\xe8le",taskTemplatesColUpdated:"Mis \xe0 jour",taskTemplatesColActions:"Actions",taskTemplatesEditBtn:"Modifier le mod\xe8le",taskTemplatesSaveBtn:"Enregistrer",taskTemplatesCancelBtn:"Annuler",taskTemplatesDeleteBtn:"Supprimer le mod\xe8le",taskTemplatesDeleteConfirm:"Retirer ce mod\xe8le de la liste enregistr\xe9e ?",tagsProjectsIntro:"G\xe9rez \xe0 part les \xe9tiquettes globales, les projets enregistr\xe9s et les \xe9tiquettes li\xe9es regroup\xe9es par projet. Les m\xeames contr\xf4les sont disponibles dans la colonne de droite du tableau de bord. Ces actions ne r\xe9\xe9crivent pas en masse les t\xe2ches ni les fichiers de session.",tagsProjectsHelpAria:"Aide : impact des changements d’\xe9tiquettes et de projets",tagsProjectsHelpBody:"Cette page comporte trois zones : \xe9tiquettes globales (sans projet), projets enregistr\xe9s, puis \xe9tiquettes li\xe9es regroup\xe9es par projet.\n\nMasquer (ic\xf4ne œil barr\xe9) : l’\xe9tiquette dispara\xeet des pastilles de suggestion ; les t\xe2ches ne sont pas modifi\xe9es.\n\nSupprimer d\xe9finitivement (ic\xf4ne corbeille) : retire l’\xe9tiquette des listes \xe9pingl\xe9es et masqu\xe9es et efface sa description ; les t\xe2ches ne sont pas modifi\xe9es.\n\nIc\xf4nes d’\xe9pingle : g\xe8rent la liste de raccourcis \xe9pingl\xe9s.\n\n\xc9tiquettes li\xe9es : dans une t\xe2che, @Projet#code (stock\xe9 Projet#code) ; les suggestions ne montrent le code que si le projet de la t\xe2che correspond.\n\nDescriptions : notes locales ; infobulles sur le tableau de bord.\n\nSupprimer un projet (corbeille) : retire le projet enregistr\xe9, efface sa description et purge les m\xe9tadonn\xe9es des \xe9tiquettes Projet#… associ\xe9es ; les t\xe2ches ne sont pas modifi\xe9es.",tagsGlobalHeading:"\xc9tiquettes globales (sans projet)",tagsGlobalIntro:"Raccourcis pour des \xe9tiquettes qui ne sont pas li\xe9es \xe0 un projet pr\xe9cis : elles sont propos\xe9es sur toute t\xe2che, avec ou sans @projet.",tagsByProjectHeading:"\xc9tiquettes li\xe9es \xe0 un projet",tagsByProjectIntro:"Chaque bloc correspond \xe0 une cl\xe9 de projet ; les \xe9tiquettes enregistr\xe9es sous la forme Projet#code y sont regroup\xe9es. \xc9pinglage, masquage et descriptions restent propres \xe0 chaque \xe9tiquette.",tagsByProjectOrphanIntro:"Port\xe9es Projet#code sans projet correspondant dans la liste enregistr\xe9e ci-dessus. \xc9pinglez ou modifiez-les ici, ou ajoutez d’abord le projet \xe0 la liste.",tagsByProjectOrphanHelpAria:"Aide : \xe9tiquettes li\xe9es sans projet enregistr\xe9 correspondant",tocSubTagsGlobal:"\xc9tiquettes globales",tocSubTagsProjects:"Projets",tocSubTagsByProject:"\xc9tiquettes par projet",tagsHiddenHeading:"Masqu\xe9es des raccourcis",tagsPinFieldLabel:"\xc9pingler une \xe9tiquette globale",tagsPinPlaceholder:"ex. bugfix ou deep-work",tagsPinScopedFieldLabel:"\xc9pingler une \xe9tiquette li\xe9e \xe0 un projet",tagsPinScopedPlaceholder:"ex. 204822-1530 ou ClientABC#204822-1530",tagsPinAddBtn:"\xc9pingler",tagsTableTagCol:"\xc9tiquette",tagsTableActionsCol:"Actions",tagBadgePinned:"\xc9pingl\xe9e",tagPinBtn:"Ajouter l’\xe9tiquette aux raccourcis \xe9pingl\xe9s",tagUnpinBtn:"Retirer l’\xe9tiquette des raccourcis \xe9pingl\xe9s",tagExcludeBtn:"Masquer l’\xe9tiquette des raccourcis de suggestion",tagRestoreBtn:"R\xe9afficher l’\xe9tiquette dans les raccourcis",tagPurgeAriaLabel:"Supprimer d\xe9finitivement les m\xe9tadonn\xe9es de l’\xe9tiquette",tagPurgeConfirm:"Supprimer d\xe9finitivement les m\xe9tadonn\xe9es de cette \xe9tiquette ? Sa description sera effac\xe9e, elle sera d\xe9s\xe9pingl\xe9e et masqu\xe9e des listes du tableau de bord (elle appara\xeet sous \xab Masqu\xe9es des raccourcis \xbb si des t\xe2ches y font encore r\xe9f\xe9rence). Les t\xe2ches ne sont pas modifi\xe9es.",tagPurgeHiddenConfirm:"Retirer cette \xe9tiquette de la liste masqu\xe9e et effacer sa description ? Si des t\xe2ches l’utilisent encore, elle peut r\xe9appara\xeetre dans les raccourcis. Les t\xe2ches ne sont pas modifi\xe9es.",tagPurgeHiddenAriaLabel:"Supprimer d\xe9finitivement les m\xe9tadonn\xe9es de cette \xe9tiquette masqu\xe9e",tagRenameBtn:"Renommer l’\xe9tiquette",tagRenamePrompt:"Nouveau nom de l’\xe9tiquette",tagRenameImpactConfirm:"Renommer cette \xe9tiquette partout ? Les rapports et les ventilations historiques des t\xe2ches utiliseront d\xe9sormais le nouveau nom. Les sessions et entr\xe9es de t\xe2ches existantes seront mises \xe0 jour.",renameImpactDontShowAgain:"M\xe9moriser ce choix et ne plus afficher",tagUnpinConfirm:"Retirer cette \xe9tiquette de la liste \xe9pingl\xe9e ? Elle peut r\xe9appara\xeetre si des t\xe2ches l’utilisent encore.",tagExcludeConfirm:"Masquer cette \xe9tiquette des raccourcis du tableau de bord ? Les donn\xe9es des t\xe2ches et sessions ne sont pas modifi\xe9es ; les t\xe2ches existantes gardent l’\xe9tiquette et les bilans peuvent encore la compter.",projectsHeading:"Projets enregistr\xe9s",projectsIntro:"Projets ajout\xe9s via @projet ou le tableau de bord.",projectsHelpAria:"Aide : projets enregistr\xe9s",projectsHelpBody:"La suppression (ic\xf4ne corbeille) retire le projet de la liste enregistr\xe9e, efface sa description et purge les m\xe9tadonn\xe9es des \xe9tiquettes enregistr\xe9es sous la forme Projet#… pour ce projet. Les t\xe2ches ne sont pas modifi\xe9es.",projectsAddFieldLabel:"Ajouter un projet",projectsAddPlaceholder:"ex. ClientABC",projectsAddBtn:"Ajouter le projet",projectsTableProjectCol:"Projet",projectsRenameBtn:"Renommer le projet",projectsRenamePrompt:"Nouveau nom du projet",projectRenameImpactConfirm:"Renommer ce projet partout ? Les rapports par projet et les ventilations historiques des t\xe2ches utiliseront d\xe9sormais le nouveau nom. Les sessions et entr\xe9es de t\xe2ches existantes seront mises \xe0 jour.",projectsRemoveBtn:"Supprimer le projet et les m\xe9tadonn\xe9es d’\xe9tiquettes li\xe9es",projectRemoveConfirm:"Supprimer d\xe9finitivement les m\xe9tadonn\xe9es de ce projet ? Il sera retir\xe9 de la liste enregistr\xe9e, sa description effac\xe9e, et les donn\xe9es \xe9pingl\xe9es / masqu\xe9es / descriptions des \xe9tiquettes Projet#… sous ce projet seront supprim\xe9es. Les t\xe2ches ne sont pas modifi\xe9es.",tagDescriptionLabel:"Description (infobulle dans le tableau de bord)",projectDescriptionLabel:"Description (infobulle dans le tableau de bord)",descriptionSaveBtn:"Enregistrer la description",tagStartTrackedTaskBtn:"D\xe9marrer le suivi d’une t\xe2che avec cette \xe9tiquette (et ce projet si li\xe9)",tagStartTrackedTaskFromProjectBtn:"D\xe9marrer le suivi d’une t\xe2che avec ce projet",tagStartTaskAutoSessionToast:"Aucune session en cours — d\xe9marrage d’une session pour y rattacher cette t\xe2che.",tagStartTaskConflictTitle:"Suivi d\xe9j\xe0 actif",tagStartTaskConflictMessage:"Au moins une t\xe2che a d\xe9j\xe0 un minuteur actif. Indiquez ce que vous en faites avant de lancer celle-ci : les terminer (elles passent dans \xab termin\xe9es \xbb), les mettre en pause (reprise plus tard dans \xab en pause \xbb), ou les laisser tourner et d\xe9marrer la nouvelle t\xe2che en parall\xe8le.",tagStartTaskConflictPauseBtn:"Mettre les t\xe2ches actives en pause",tagStartTaskConflictFinishBtn:"Terminer les t\xe2ches actives",tagStartTaskConflictParallelBtn:"D\xe9marrer en parall\xe8le (garder les minuteurs)",tagStartTaskConflictDontShowAgain:"M\xe9moriser ce choix et ne plus afficher cette bo\xeete (la m\xeame action sera appliqu\xe9e automatiquement la prochaine fois).",tagsScopeToolHeading:"Migration de port\xe9e des \xe9tiquettes",tagsScopeToolSourceLabel:"\xc9tiquette source",tagsScopeToolTargetProjectLabel:"Port\xe9e projet cible",tagsScopeToolTargetGlobalOption:"Globale (sans projet)",tagsScopeToolCopyBtn:"Copier vers la port\xe9e cible",tagsScopeToolMoveBtn:"D\xe9placer vers la port\xe9e cible",tagsScopeToolNoTags:"Aucune \xe9tiquette connue \xe0 migrer pour le moment.",tagsEmptyGlobal:"Aucune \xe9tiquette globale dans les raccourcis pour l’instant. \xc9pinglez-en une ci-dessus ou utilisez des #tags sur les t\xe2ches.",tagsByProjectSectionEmpty:"Aucune \xe9tiquette li\xe9e \xe0 un projet dans les raccourcis pour l’instant. Utilisez @Projet#code sur une t\xe2che ou \xe9pinglez un code ci-dessous.",tagsByProjectSubEmpty:"Aucune \xe9tiquette li\xe9e \xe0 ce projet dans les raccourcis pour l’instant.",projectsEmpty:"Aucun projet enregistr\xe9 pour l’instant. Utilisez @projet sur une t\xe2che ou choisissez un projet sur le tableau de bord.",hiddenTagsEmpty:"Aucune \xe9tiquette masqu\xe9e.",workspaceLocExcludedDirs:"Segments de dossiers exclus",workspaceLocExcludedDirsDesc:"Un nom par ligne (un seul segment de chemin, pas un chemin complet). Si un segment du chemin d’un fichier correspond \xe0 une entr\xe9e, le fichier est ignor\xe9 — pour la liste Git et le parcours disque. Ex. : node_modules, .git, .husky, .venv, dist.",workspaceLocExcludedPatterns:"Motifs de chemins exclus",workspaceLocExcludedPatternsDesc:"Un motif par ligne (syntaxe minimatch : *, ?, **), relatif \xe0 la racine du workspace. Ex. : **/*.min.js, generated/**, **/*.gen.ts. Apr\xe8s enregistrement, actualisez l’instantan\xe9 depuis la page Rapports.",pickStorageFolder:"Choisir un dossier…",hintPortRestart:"Apr\xe8s un changement de port, red\xe9marrez le processus Kronosys pour que l’API \xe9coute sur le nouveau port.",hintDashboardUrl:"URL de r\xe9f\xe9rence affich\xe9e seulement ; ne d\xe9marre pas le serveur Next.js.",tocSubDashboardTour:"Visite guid\xe9e",tocSubReportingTour:"Visite Rapports",tocSubDashboardColumnHints:"Aide trois colonnes",dashboardColumnHintsBlockTitle:"Aide \xab trois colonnes \xbb sur le tableau de bord",dashboardColumnHintsBlockIntro:"Si vous avez masqu\xe9 le bandeau sous l’en-t\xeate du tableau de bord (bouton X), vous pouvez le r\xe9afficher ici. Cette pr\xe9f\xe9rence est stock\xe9e dans le navigateur pour ce site.",dashboardColumnHintsRestoreBtn:"R\xe9afficher l’aide des trois colonnes",dashboardColumnHintsRestoreDone:"Pr\xe9f\xe9rence r\xe9initialis\xe9e. Ouvrez le tableau de bord pour voir le bandeau.",tagsProjectsTabsAriaLabel:"Sections de la colonne \xe9tiquettes",tagsProjectsTabGlobal:"\xc9tiquettes globales",tagsProjectsTabProjects:"Projets et \xe9tiquettes li\xe9es",tagsProjectsTabTemplates:"Mod\xe8les de t\xe2che",tocSubSessionDurationAlert:"Alerte dur\xe9e de session",tocSubDefaultSessionNameTemplate:"Nom de session par d\xe9faut",dashboardSessionDurationAlertHours:"Seuil d’alerte dur\xe9e de session (heures)",dashboardSessionDurationAlertHoursDesc:"Dur\xe9e murale de session (panneau lat\xe9ral du tableau de bord) : d\xe8s qu’elle atteint ce nombre d’heures (ou plus), la valeur s’affiche en rouge avec un clignotement lent. D\xe9faut : 24. Plage : 1–8760.",dashboardTourBlockTitle:"Visite guid\xe9e du tableau de bord",dashboardTourBlockIntro:"Cinq courtes \xe9tapes pr\xe9sentent les sessions, les t\xe2ches, les \xe9tiquettes et les raccourcis. Vous pouvez relancer la visite \xe0 tout moment depuis ici.",dashboardTourReplayLinkLabel:"Ouvrir le tableau de bord et lancer la visite",reportingTourBlockTitle:"Visite guid\xe9e Rapports",reportingTourBlockIntro:"Filtres, indicateurs, graphiques et ventilation par \xe9tiquette ou par projet sur la page Rapports. Vous pouvez relancer cette visite \xe0 tout moment.",reportingTourReplayLinkLabel:"Ouvrir Rapports et lancer la visite",enabled:"Activer la collecte d’activit\xe9",enabledDesc:"Interrupteur global de la collecte d’activit\xe9.",autoStart:"D\xe9marrage automatique",autoStartDesc:"Lancer la collecte au d\xe9marrage du processus Kronosys.",sectionSchedule:"Horaire de travail",scheduleEnabled:"Activer l’horaire automatique",scheduleEnabledDesc:"D\xe9marrer et arr\xeater automatiquement les sessions selon vos heures de travail.",scheduleDays:"Jours actifs",scheduleDaysDesc:"Jours de la semaine o\xf9 le suivi est actif.",scheduleStartTime:"Heure de d\xe9but",scheduleEndTime:"Heure de fin",timePickerPopoverTimeLabel:"Heure (24 h)",timePickerPopoverHourAria:"Heure (24 h)",timePickerPopoverMinuteAria:"Minutes",scheduleCreateDailySession:"Cr\xe9er une session par jour",scheduleCreateDailySessionDesc:"Cr\xe9er automatiquement une nouvelle session au d\xe9marrage de l'horaire pour chaque jour actif.",scheduleTransferTasks:"Transposer les t\xe2ches",scheduleTransferTasksDesc:"Transf\xe9rer automatiquement les t\xe2ches actives de la session pr\xe9c\xe9dente vers la nouvelle session.",schedulePauseTasks:"Mettre les t\xe2ches en pause \xe0 l'arr\xeat",schedulePauseTasksDesc:"Mettre automatiquement en pause les t\xe2ches actives lorsque l'horaire de travail se termine.",sectionPlannedSessions:"Sessions Sp\xe9cifiques Planifi\xe9es",plannedSessionsIntro:"Ajoutez des sessions r\xe9currentes sp\xe9cifiques. Celles-ci ont priorit\xe9 sur l'horaire de travail g\xe9n\xe9ral pendant leur plage horaire.",plannedSessionAdd:"Ajouter une session planifi\xe9e",plannedSessionName:"Nom de la session",plannedSessionTags:"\xc9tiquettes (s\xe9par\xe9es par des virgules)",plannedSessionProject:"Projet",plannedSessionRemove:"Supprimer cette session",showWelcome:"\xc9cran d’accueil",showWelcomeDesc:"Afficher l’accueil tant qu’il n’est pas ferm\xe9.",anonymizePaths:"Anonymiser les chemins",anonymizePathsDesc:"Hacher les chemins de fichiers avant d’\xe9crire les \xe9v\xe9nements.",flushInterval:"Intervalle de vidage (secondes)",flushIntervalDesc:"Fr\xe9quence d’\xe9criture du tampon vers le stockage (5–3600).",heartbeatInterval:"Intervalle des battements (secondes)",heartbeatIntervalDesc:"Temps minimal entre deux \xe9v\xe9nements \xab heartbeat \xbb (30–86400).",maxBuffered:"\xc9v\xe9nements tampon max",maxBufferedDesc:"\xc9v\xe9nements en m\xe9moire avant r\xe9duction (100–100000).",historyPath:"Chemin du stockage d’historique",historyPathDesc:"Vide = r\xe9pertoire de donn\xe9es applicatif par d\xe9faut. ~ d\xe9signe le dossier personnel.",historyPartition:"Partition des fichiers d’historique",historyPartitionDesc:"D\xe9coupage des fichiers de sessions sur le disque.",localPersistenceDriver:"Stockage local des sessions",localPersistenceDriverDesc:"JSON conserve l’historique en fichiers partitionn\xe9s. SQLite enregistre les sessions dans un fichier unique dans le m\xeame dossier ; les JSON existants sont import\xe9s une fois. Le miroir MongoDB (s’il est activ\xe9) reste inchang\xe9. Red\xe9marrez le processus apr\xe8s modification.",persistenceDriverJson:"Fichiers JSON",persistenceDriverSqlite:"SQLite",localPersistenceReloadHint:"Apr\xe8s un changement de moteur, red\xe9marrez le processus Kronosys pour appliquer le r\xe9glage.",partitionDaily:"Quotidien",partitionWeekly:"Hebdomadaire",partitionMonthly:"Mensuel",sessionStartMode:"Au d\xe9marrage du suivi",sessionStartModeDesc:"Reprendre la session pr\xe9c\xe9dente ou toujours repartir \xe0 neuf.",modeContinue:"Poursuivre la session pr\xe9c\xe9dente",modeNew:"Toujours une nouvelle session",exportFormat:"Format d’export par d\xe9faut",exportFormatDesc:"Utilis\xe9 pour les exports d’historique de sessions.",fmtJson:"JSON",fmtCsv:"CSV",fmtJira:"Table Jira",fmtSap:"SAP",csvDelimiter:"S\xe9parateur CSV",csvDelimiterDesc:"Un seul caract\xe8re, ex. , ou ;",autoGitSync:"Sync Git automatique",autoGitSyncDesc:"Optionnel : apr\xe8s chaque sauvegarde locale, valider et pousser le dossier d’historique vers le d\xe9p\xf4t distant. La liste des sessions reste lue depuis les fichiers JSON locaux.",gitRemoteUrl:"URL du d\xe9p\xf4t Git distant",gitRemoteUrlDesc:"Requis si la sync automatique est activ\xe9e.",tocSubGitIdentity:"Auteur Git (tableau de bord)",gitIdentitySubheading:"Auteur Git affich\xe9 dans le tableau de bord",gitIdentityIntro:"Enregistr\xe9 localement avec vos donn\xe9es Kronosys (SQLite). Affich\xe9 sous le titre du tableau de bord \xe0 c\xf4t\xe9 des chemins du workspace — cela n’ex\xe9cute pas git config sur votre machine.",gitIdentityNameLabel:"Nom affich\xe9",gitIdentityNameDesc:"\xc9quivalent \xe0 git config user.name (cr\xe9dit souhait\xe9).",gitIdentityEmailLabel:"Courriel",gitIdentityEmailDesc:"\xc9quivalent \xe0 git config user.email (affichage seulement ici).",gitIdentityLoginLabel:"Identifiant sur la forge",gitIdentityLoginDesc:"Optionnel : compte GitHub, GitLab ou autre h\xe9bergeur (distinct du nom affich\xe9).",gitIdentitySave:"Enregistrer l’auteur Git",gitIdentitySaving:"Enregistrement…",gitIdentitySavedFlash:"Auteur Git enregistr\xe9.",glabRemoteSuggest:"L’outil glab est disponible et un jeton est configur\xe9 : vous pouvez cr\xe9er un d\xe9p\xf4t priv\xe9 nomm\xe9 kronosys-sessions et activer la sync automatique en une \xe9tape.",glabRemoteCreate:"Cr\xe9er le d\xe9p\xf4t GitLab avec glab",glabRemoteCreating:"Cr\xe9ation du d\xe9p\xf4t…",gitlabToken:"Jeton GitLab",gitlabTokenDesc:"Jeton d’acc\xe8s personnel facultatif pour glab (cr\xe9ation de d\xe9p\xf4t priv\xe9, liste des issues). Dans ce tableau de bord, l’enregistrement conserve le jeton dans SQLite local (hors JSON d’\xe9tat) pour que l’import d’issues appelle GitLab ; il remplace GITLAB_TOKEN de l’environnement du serveur une fois enregistr\xe9. Utilisez \xab Tester la connexion \xbb pour activer \xab Importer une issue Git \xbb.",gitlabTokenSave:"Enregistrer le jeton",gitlabTokenClear:"Effacer le jeton stock\xe9",gitlabTokenSaveNeedValue:"Collez d’abord votre jeton dans le champ — enregistrer avec un champ vide ne conserve pas de secret sur ce serveur.",gitlabTokenStoredYes:"Un jeton est enregistr\xe9 dans le coffre de secrets local ; il est prioritaire sur GITLAB_TOKEN pour les appels \xe0 glab.",gitlabTokenFromEnvYes:"Aucun jeton enregistr\xe9 ; glab utilise GITLAB_TOKEN de l’environnement du serveur.",gitlabTokenNone:"Aucun jeton pour l’instant — enregistrez-en un ci-dessous ou d\xe9finissez GITLAB_TOKEN pour le processus du tableau de bord.",gitlabInstanceUrl:"URL de l’instance GitLab",gitlabInstanceUrlDesc:"Origine seulement (sans chemin /api/v4). Laissez vide pour GitLab.com. Pour une instance auto-h\xe9berg\xe9e, indiquez son URL (p. ex. https://gitlab.entreprise.com). Vous pouvez aussi d\xe9finir GITLAB_INSTANCE_URL sur le processus serveur.",gitlabTest401Help:"401 : souvent le jeton ne correspond pas \xe0 cet h\xf4te (mauvaise URL d’instance), ou le jeton est expir\xe9/r\xe9voqu\xe9 ou sans port\xe9e api.",gitlabTestConnection:"Tester la connexion GitLab",gitlabTestConnectionAria:"Tester le jeton d’API GitLab",gitlabTestRunning:"Test GitLab en cours…",gitlabTestOk:"L’API GitLab a r\xe9pondu correctement. L’import d’issues est activ\xe9 dans la colonne des t\xe2ches.",gitlabTestFail:"\xc9chec du test GitLab. V\xe9rifiez le jeton, l’URL d’instance ci-dessus et le r\xe9seau.",gitlabTestNoToken:"Aucun jeton \xe0 tester : collez un jeton dans le champ, enregistrez-le, ou assurez-vous que GITLAB_TOKEN est disponible pour ce processus lorsque vous utilisez le jeton d’environnement.",gitlabTestErrorGeneric:"Impossible d’ex\xe9cuter le test de connexion GitLab.",gitlabApiVerifiedYes:"API GitLab : v\xe9rifi\xe9e — l’import d’issues dans les t\xe2ches est disponible.",gitlabApiVerifiedNo:"API GitLab : non v\xe9rifi\xe9e — lancez \xab Tester la connexion \xbb pour activer l’import d’issues dans les t\xe2ches.",gitlabTestPasteStoredHint:"Pour tester un jeton d\xe9j\xe0 enregistr\xe9 localement, collez-le temporairement dans le champ ci-dessus (ce tableau de bord ne peut pas relire le secret depuis le stockage).",historyLocalFirstHint:"L’historique des sessions est lu depuis les fichiers JSON locaux ou SQLite (voir Stockage local des sessions). La sync Git automatique pousse le dossier apr\xe8s les sauvegardes si elle est activ\xe9e. MongoDB n’est mis \xe0 jour que lorsque l’envoi est d\xe9clench\xe9 depuis le tableau de bord ou via Resynchroniser dans les param\xe8tres.",mongoEnabled:"Int\xe9gration MongoDB",mongoEnabledDesc:"Si activ\xe9, vous pouvez envoyer chaque session vers MongoDB depuis le tableau de bord (et tout resynchroniser dans les param\xe8tres). Rien n’est envoy\xe9 automatiquement \xe0 chaque sauvegarde locale. Le tableau de bord lit toujours le stockage local (JSON ou SQLite).",mongoDatabase:"Base MongoDB",mongoDatabaseDesc:"Nom de la base (lettres, chiffres, tiret, soulign\xe9).",mongoCollection:"Collection MongoDB",mongoCollectionDesc:"Nom de la collection (un document par session).",sectionMongoConnection:"Connexion MongoDB",mongoConnectionIntro:"Construire mongodb://utilisateur:motdepasse@h\xf4te:port/?authSource=… avec les champs ci-dessous, ou d\xe9finir une URI compl\xe8te en mode avanc\xe9. Une URI compl\xe8te enregistr\xe9e est prioritaire. Le bouton Enregistrer en haut applique aussi h\xf4te/port/utilisateur/authSource et enregistre le mot de passe ou l’URI manuelle si les champs sont remplis.",mongoHost:"H\xf4te",mongoHostDesc:"Nom d’h\xf4te ou adresse IP (ex. 127.0.0.1).",mongoPort:"Port",mongoPortDesc:"Port TCP (d\xe9faut 27017).",mongoUser:"Utilisateur",mongoUserDesc:"Vide = sans authentification. Si renseign\xe9, un mot de passe est requis (stock\xe9 dans le coffre de secrets).",mongoPassword:"Mot de passe",mongoPasswordDesc:"Stock\xe9 uniquement dans le coffre de secrets local. Utilisez Enregistrer le mot de passe ou le bouton Enregistrer en haut si le champ n’est pas vide.",mongoPasswordSave:"Enregistrer le mot de passe",mongoPasswordClear:"Effacer le mot de passe stock\xe9",mongoPasswordConfiguredYes:"Un mot de passe est enregistr\xe9.",mongoPasswordConfiguredNo:"Aucun mot de passe enregistr\xe9.",mongoAuthSource:"authSource",mongoAuthSourceDesc:"Base d’authentification (souvent admin).",mongoManualUri:"URI compl\xe8te (avanc\xe9)",mongoManualUriDesc:"Si d\xe9finie, cette URI remplace h\xf4te / utilisateur / mot de passe. Stock\xe9e dans le coffre de secrets. Effacer pour revenir \xe0 la connexion construite.",mongoUri:"URI de connexion",mongoUriDesc:"mongodb:// ou mongodb+srv:// — le bouton Enregistrer en haut enregistre aussi cette URI si le champ n’est pas vide.",mongoUriSave:"Enregistrer l’URI",mongoUriClear:"Effacer l’URI stock\xe9e",mongoUriConfiguredYes:"Une URI compl\xe8te est enregistr\xe9e (mode avanc\xe9).",mongoUriConfiguredNo:"Aucune URI compl\xe8te ; la connexion construite est utilis\xe9e si possible.",mongoRemoteStatus:"\xc9tat MongoDB",mongoStatusConnected:"Connect\xe9",mongoStatusFailed:"\xc9chec ou configuration incompl\xe8te",mongoStatusPending:"V\xe9rification…",mongoConnectionResolvableYes:"Param\xe8tres de connexion suffisants.",mongoConnectionResolvableNo:"Incomplet (ex. mot de passe si l’utilisateur est renseign\xe9).",mongoTestConnection:"Tester la connexion",mongoTestConnectionAria:"Tester la connexion MongoDB",mongoTestRunning:"Test de connexion en cours…",mongoTestOk:"Test de connexion r\xe9ussi (ping sur la base configur\xe9e).",mongoTestFail:"\xc9chec du test de connexion. V\xe9rifiez l’h\xf4te, le port, les identifiants, l’URI et le r\xe9seau.",mongoTestDisabled:"Activez le miroir MongoDB ci-dessus pour lancer un test de connexion.",mongoTestErrorGeneric:"Impossible d’ex\xe9cuter le test de connexion via l’API locale.",mongoTestUsesSavedConfigHint:"L’h\xf4te, le port, la base, la collection et l’utilisateur ci-dessous sont pris en compte pour le test m\xeame sans cliquer sur Enregistrer. Une URI compl\xe8te ou un mot de passe enregistr\xe9 (boutons d\xe9di\xe9s) provient toujours du coffre de secrets local.",mongoSyncSectionTitle:"Fichiers locaux et MongoDB",mongoResyncButton:"Resynchroniser toutes les sessions vers MongoDB",mongoResyncAriaLabel:"Resynchroniser toutes les sessions locales vers le miroir MongoDB",mongoResyncConfirm:"Enregistrer chaque session locale dans MongoDB (upsert) ? Cela peut prendre du temps s’il y a beaucoup de sessions.",mongoResyncRunning:"Resynchronisation…",mongoResyncDone:"Resynchronisation termin\xe9e : {upserted} sessions \xe9crites, {failed} \xe9checs.",mongoResyncHint:"\xc9crit toutes les sessions locales dans MongoDB et met \xe0 jour les m\xe9tadonn\xe9es d’envoi dans les JSON. Les documents suppl\xe9mentaires d\xe9j\xe0 pr\xe9sents dans MongoDB ne sont pas supprim\xe9s.",mongoResyncDisabled:"Activez le miroir MongoDB dans les param\xe8tres avant de resynchroniser.",mongoResyncUnsupported:"Ce stockage ne prend pas en charge la resynchronisation MongoDB.",mongoResyncErrorGeneric:"Impossible d’ex\xe9cuter la resynchronisation.",mongoResyncErrorDetail:"\xc9chec de la resynchronisation : {detail}",workspaceFoldersLabel:"Racines du workspace",workspaceFoldersEmpty:"Aucune racine de workspace n’est configur\xe9e pour ce tableau de bord.",localApiPort:"Port de l’API locale",localApiPortDesc:"API HTTP loopback pour ce tableau de bord (127.0.0.1 uniquement).",dashboardWebUrl:"URL du tableau de bord (affichage)",dashboardWebUrlDesc:"URL sugg\xe9r\xe9e pour ouvrir le tableau de bord dans un navigateur (signets, etc.). Utilisez une URL loopback (localhost, 127.0.0.1, [::1]) ou un nom d’h\xf4te dans /etc/hosts r\xe9solu vers loopback (ex. kronosys).",dashboardDisplayTimeZone:"Fuseau horaire d’affichage",dashboardDisplayTimeZoneDesc:"Sert aux dates des sessions sur le tableau de bord, aux horodatages des t\xe2ches et au regroupement par jour dans les rapports. Choisissez une suggestion ou saisissez un fuseau IANA (ex. Europe/Brussels). Par d\xe9faut : heure de l’Est (America/Toronto).",dashboardClockFormat:"Format de l’horloge",dashboardClockFormatDesc:"Affichage des heures sur le tableau de bord (d\xe9but et fin des t\xe2ches, aper\xe7u des dates de t\xe2ches pass\xe9es) et dans les aper\xe7us des s\xe9lecteurs d’heure du calendrier. Les dates ne changent pas.",dashboardClock24hOption:"24 heures",dashboardClock12hOption:"12 heures (AM/PM)",dashboardCalendarWeekStartsOn:"La semaine commence",dashboardCalendarWeekStartsOnDesc:"Premi\xe8re colonne des calendriers (s\xe9lecteurs de date du tableau de bord, sessions pass\xe9es) et grilles hebdomadaires des rapports. Le pr\xe9r\xe9glage de plage \xab Semaine \xbb reste lundi–dimanche.",calendarWeekStartsSunday:"Dimanche",calendarWeekStartsMonday:"Lundi",calendarWeekStartsSaturday:"Samedi",dashboardLightThemeVariant:"Teinte du th\xe8me clair",dashboardLightThemeVariantDesc:"S’applique lorsque le tableau de bord est en mode clair (ic\xf4ne lune dans la barre d’outils). Le mode sombre n’est pas modifi\xe9. Le choix est enregistr\xe9 dans ce navigateur et dans les param\xe8tres locaux.",dashboardLightThemeWarm:"Chaud",dashboardLightThemeSoft:"Doux",dashboardLightThemeContrast:"Contraste",dashboardSemanticChipAccessibleMode:"Ne pas distinguer par la couleur seule",dashboardSemanticChipAccessibleModeDesc:"Si activ\xe9, les pastilles d'\xe9tiquette, de projet travail et de projet personnel affichent les pr\xe9fixes #, @ et ! ainsi que des bordures distinctes (pleine, double, pointill\xe9e) en compl\xe9ment de leurs couleurs — tableau de bord, filtres des rapports et partout o\xf9 ces pastilles apparaissent. Enregistr\xe9 dans ce navigateur et dans les param\xe8tres locaux.",dashboardBaseDailyHours:"Heures de base par jour",dashboardBaseDailyHoursDesc:"Heures de r\xe9f\xe9rence par jour pour le suivi d'\xe9cart dans les rapports d'allocation.",dashboardBaseDailyToleranceMinutes:"Tol\xe9rance (minutes)",dashboardBaseDailyToleranceMinutesDesc:"\xc9cart autoris\xe9 par rapport aux heures de base avant surbrillance (d\xe9faut : 10 min).",dashboardDefaultSessionNameTemplate:"Gabarit du nom des nouvelles sessions",dashboardDefaultSessionNameTemplateDesc:"Renseign\xe9 lors du d\xe9marrage d’une nouvelle session active (commande \xab Nouvelle session \xbb ou session implicite cr\xe9\xe9e par la premi\xe8re t\xe2che). Laissez vide pour garder le champ vide. S\xe9quences : `%%` pour un pourcentage litt\xe9ral ; `%UUID` pour l’identifiant complet de session ; `%Y` `%y` `%m` `%d` `%H` `%M` `%S` ainsi que `%F` (\xe9quivalent `%Y-%m-%d`) suivent la s\xe9mantique de `strftime()` POSIX (r\xe9f\xe9rence IEEE / Open Group : https://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html). Attention : `%m` est le mois ; `%M` repr\xe9sente les minutes. Les valeurs utilisent le fuseau d’affichage choisi ci-dessus (coh\xe9rent avec les regroupements quotidiens des rapports).",invalidDashboardTimeZone:"Fuseau horaire non reconnu. Saisissez un nom IANA valide (ex. America/Toronto).",dialogOkBtn:"OK",dialogCancelBtn:"Annuler",dialogConfirmBtn:"Confirmer",scrollToTopAria:"Retour en haut de la page",licensesPageLink:"Licences et logiciels tiers"};function f(a){return"fr"===a?e:d}},93356:(a,b,c)=>{"use strict";c.d(b,{KronosysPayloadProvider:()=>e});var d=c(77943);let e=(0,d.registerClientReference)(function(){throw Error("Attempted to call KronosysPayloadProvider() from the server but KronosysPayloadProvider is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/KronosysPayloadProvider.tsx","KronosysPayloadProvider");(0,d.registerClientReference)(function(){throw Error("Attempted to call useKronosysPayload() from the server but useKronosysPayload is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/KronosysPayloadProvider.tsx","useKronosysPayload")},96487:()=>{},98257:(a,b,c)=>{"use strict";c.d(b,{DataEnvironmentSwitchProvider:()=>r,l:()=>q});var d=c(48249),e=c(67484),f=c(24682),g=c(11001);function h({open:a,dt:b,pending:c,onCancel:f,onChoose:i}){let j=(0,e.useId)(),k=(0,e.useId)(),{shouldRender:l,visible:m}=function(a){let[b,c]=(0,e.useState)(a),[d,f]=(0,e.useState)(a);return{shouldRender:b,visible:d}}(a);if(!l)return null;let n="w-full rounded-lg px-4 py-2.5 text-sm font-medium transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 disabled:opacity-40";return(0,d.jsx)("div",{className:`fixed inset-0 z-[100] flex items-center justify-center bg-black/60 p-4 transition-opacity duration-150 ease-out motion-reduce:transition-none ${m?"opacity-100":"opacity-0"}`,role:"dialog","aria-modal":"true","aria-labelledby":j,"aria-describedby":k,children:(0,d.jsxs)("div",{className:`max-h-[90vh] w-full max-w-md overflow-y-auto rounded-xl border border-zinc-200 bg-white p-5 shadow-xl transition-all duration-150 ease-out motion-reduce:transition-none dark:border-zinc-700 dark:bg-zinc-900 ${m?"translate-y-0 scale-100 opacity-100":"translate-y-1 scale-[0.985] opacity-0"}`,children:[(0,d.jsx)("h2",{id:j,className:"text-lg font-semibold text-zinc-900 dark:text-zinc-100",children:b.dataEnvironmentQaSeedTitle}),(0,d.jsx)("p",{id:k,className:"mt-3 whitespace-pre-wrap text-sm leading-relaxed text-zinc-600 dark:text-zinc-300",children:b.dataEnvironmentQaSeedMessage}),(0,d.jsxs)("div",{className:"mt-5 flex flex-col gap-2",children:[(0,d.jsx)("button",{type:"button",className:`${n} ${g.Sx}`,disabled:c,onClick:()=>void i("copy_production"),children:b.dataEnvironmentQaSeedCopyBtn}),(0,d.jsx)("button",{type:"button",className:`${n} border border-zinc-300 bg-zinc-100 text-zinc-900 hover:bg-zinc-200 dark:border-zinc-600 dark:bg-zinc-800 dark:text-zinc-100 dark:hover:bg-zinc-700`,disabled:c,onClick:()=>void i("empty"),children:b.dataEnvironmentQaSeedEmptyBtn}),(0,d.jsx)("button",{type:"button",className:`${n} text-zinc-600 hover:bg-zinc-100 dark:text-zinc-400 dark:hover:bg-zinc-800`,disabled:c,onClick:f,children:b.dialogCancelBtn})]})]})})}var i=c(88987);function j({open:a,target:b,dt:c,pending:e,onCancel:f,onConfirm:g}){if(!b)return null;let h="qa"===b?c.dataEnvironmentNavActiveQa:c.dataEnvironmentNavActiveProd,k=c.dataEnvironmentSwitchConfirmMessage.replace("{env}",h);return(0,d.jsx)(i.qR,{open:a,title:c.dataEnvironmentSwitchConfirmTitle,message:k,cancelLabel:c.dialogCancelBtn,confirmLabel:c.dataEnvironmentSwitchConfirmBtn,confirmVariant:"neutral",pending:e,onCancel:f,onConfirm:g})}function k({variant:a,dt:b}){let c="switching"===a?b.dataEnvironmentSwitchLockBackdropTitleSwitching:b.dataEnvironmentSwitchLockBackdropTitleLocked,e="switching"===a?b.dataEnvironmentSwitchLockBackdropDetailSwitching:b.dataEnvironmentSwitchLockBackdropDetailLocked,f="switching"===a?b.dataEnvironmentSwitchLockBackdropAriaSwitching:b.dataEnvironmentSwitchLockBackdropAriaLocked;return(0,d.jsxs)("div",{className:"fixed inset-0 z-[60] flex items-center justify-center p-5 sm:p-8",role:"alertdialog","aria-modal":"true","aria-live":"assertive","aria-label":f,children:[(0,d.jsx)("div",{className:"absolute inset-0 bg-zinc-950/55 dark:bg-black/65","aria-hidden":!0}),(0,d.jsxs)("div",{className:"relative z-10 max-w-md rounded-2xl border border-violet-500/45 bg-[#0f0a14]/95 px-5 py-5 text-center shadow-2xl backdrop-blur-[2px] dark:border-violet-600/40 sm:px-7 sm:py-6",children:[(0,d.jsx)("p",{className:"text-xs font-semibold uppercase tracking-wide text-violet-200/95",children:c}),(0,d.jsx)("p",{className:"mt-2.5 text-sm leading-snug text-violet-100/92",children:e})]})]})}var l=c(74464),m=c(59899),n=c(55017),o=c(23912);let p=(0,e.createContext)(null);function q(){let a=(0,e.useContext)(p);if(!a)throw Error("useDataEnvironmentSwitch must be used within DataEnvironmentSwitchProvider");return a}function r({children:a}){let b,{payload:c,refresh:g}=(0,f.y)(),{pushToast:i}=(0,l.f)(),q="fr"===(b=c?.current?.language)||"en"===b?b:"en"===n.h.getState().lang?"en":"fr",s=(0,m.z)(q),t=c?.dataEnvironmentRuntime,[u,v]=(0,e.useState)(null),[w,x]=(0,e.useState)(null),[y,z]=(0,e.useState)(null),[A,B]=(0,e.useState)(!1),C=t?.dualDataEnvironmentEnabled===!0,D=t?.traceDataDirOverride===!0,E=C&&!D&&t?.dataDirectoryResolutionMismatch===!0,F=A||E,G=(0,e.useCallback)(()=>{A||(v(null),x(null),z(null))},[A]),H=(0,e.useCallback)(a=>{if(A||E||!C||D)return;let b=t?.effectiveActiveDataEnvironment??"production",c=t?.dataDirectoryResolutionMismatch===!0;(a!==b||c)&&(v(a),z(null),x("qa"===a&&t?.qaVaultUninitialized===!0?"qaSeed":"confirm"))},[C,E,A,t,D]),I=(0,e.useCallback)(a=>{z(a),x("confirm")},[]),J=(0,e.useCallback)(async()=>{if(u&&!A&&!E){if("qa"===u&&t?.qaVaultUninitialized===!0&&!y){i(s.dataEnvironmentQaSeedRequiredError),x("qaSeed");return}B(!0);try{let b={type:"switchDataEnvironment",target:u};"qa"===u&&y&&(b.qaSeed=y);let c=await (0,o.$)(b);if(!c.ok||c.result?.dataEnvironmentError){var a;i((a=c.result?.dataEnvironmentError,"qa_seed_required"===a?s.dataEnvironmentQaSeedRequiredError:"production_missing"===a?s.dataEnvironmentQaSeedProductionMissingError:s.dataEnvironmentSwitchError)),c.result?.dataEnvironmentError==="qa_seed_required"&&x("qaSeed");return}if(v(null),x(null),z(null),await g({routerInvalidate:!0}),c.result?.dataEnvironmentReloaded===!0){let a="qa"===u?s.dataEnvironmentNavQaShort:s.dataEnvironmentNavProdShort;i(s.dataEnvironmentSwitchSuccessHint.replace("{env}",a))}else i(s.dataEnvironmentSwitchRestartHint)}catch{i(s.dataEnvironmentSwitchError)}finally{B(!1)}}},[s,E,A,y,u,i,g,t?.qaVaultUninitialized]),K=(0,e.useMemo)(()=>({requestSwitch:H,isSwitching:A,isLockedUntilRestart:E,isInteractionBlocked:F}),[F,E,A,H]),L=A&&null===w,M=E&&!A;return(0,d.jsxs)(p.Provider,{value:K,children:[a,(0,d.jsx)(h,{open:"qaSeed"===w&&"qa"===u,dt:s,pending:A,onCancel:G,onChoose:I}),(0,d.jsx)(j,{open:"confirm"===w&&null!==u,target:u,dt:s,pending:A,onCancel:G,onConfirm:()=>void J()}),L?(0,d.jsx)(k,{variant:"switching",dt:s}):null,M?(0,d.jsx)(k,{variant:"restartRequired",dt:s}):null]})}},98782:(a,b,c)=>{Promise.resolve().then(c.t.bind(c,95547,23))}};
|
|
90
|
+
Sessions archiv\xe9es : pour les m\xe9triques bas\xe9es sur les t\xe2ches, seules les t\xe2ches enti\xe8rement boucl\xe9es (sous-t\xe2ches comprises) sont prises en compte — voir aussi l’aide des indicateurs de synth\xe8se.`,reportingNonFinalLegend:"Travail ouvert —",reportingNonFinalSessionsBadge:"Sessions",reportingNonFinalProjectsBadge:"Projets",reportingNonFinalTagsBadge:"\xc9tiquettes",sectionFilteredBadge:"Filtr\xe9",sectionFilteredBadgeTitle:"Ces chiffres tiennent compte de la plage de dates et des \xe9tiquettes choisies en haut de page.",summarySessionsInRange:"Sessions (plage)",summaryTaskEvents:"Lignes de t\xe2ches (plage)",summaryKronoFocusCompleted:"Sessions KronoFocus termin\xe9es (total par session)",summaryKronoFocusTasksUsed:"T\xe2ches avec KronoFocus utilis\xe9",summaryKronoFocusCycles:"Cycles KronoFocus (t\xe2ches)",summaryTaskTimeRecorded:"Temps enregistr\xe9 sur les t\xe2ches",summarySessionCoding:"Temps de codage (sessions)",summarySessionActive:"Temps actif (sessions)",summarySessionWallClock:"Dur\xe9e murale des sessions",summaryAssiduityWithReference:"Sessions (d\xe9but pr\xe9vu enregistr\xe9)",summaryAssiduityLateSessions:"D\xe9parts en retard (apr\xe8s l’heure pr\xe9vue)",summaryAssiduityLateTotal:"Retard cumul\xe9",summaryAssiduityAvgLateWhenLate:"Retard moyen (si en retard)",chartSessionsPerDay:"Sessions par jour",chartTasksByStatusPerDay:"T\xe2ches par jour et par statut",chartTaskTimePerDay:"Temps enregistr\xe9 sur les t\xe2ches par jour",chartSessionWallPerDay:"Dur\xe9e murale des sessions par jour",sessionDayTaskBreakdownTitle:"Sessions par jour — temps des t\xe2ches",sessionDayTaskBreakdownIntro:"Chaque jour affich\xe9 est le jour de session (enregistrement ou fin). Sous chaque session : temps enregistr\xe9 sur les t\xe2ches qui tombe dans la plage de dates (m\xeames r\xe8gles que le graphique \xab temps t\xe2che \xbb ; archives : seules les t\xe2ches enti\xe8rement boucl\xe9es). Les t\xe2ches planifi\xe9es (cr\xe9neau futur) affichent une fen\xeatre planifi\xe9e distincte, pas la dur\xe9e enregistr\xe9e. La colonne murale indique la fraction de dur\xe9e murale attribu\xe9e \xe0 ce jour lorsque la session traverse minuit. Chaque # sous une t\xe2che affiche la dur\xe9e compl\xe8te de la ligne (m\xeame r\xe8gle que les grilles d’allocation # plus haut). Basculez l’ordre des lignes pour additionner le temps par # dans la session, et voyez un total journalier par # lorsque vous mettez les # en t\xeate.",sessionDayTaskBreakdownColWall:"Murale (ce jour)",sessionDayTaskBreakdownColTask:"T\xe2che",sessionDayTaskBreakdownColTags:"Par #",sessionDayTaskBreakdownColTime:"Enregistr\xe9",sessionDayTaskBreakdownTotalPlanned:"Planifi\xe9",sessionDayBreakdownPlannedPrefix:"planifi\xe9",sessionDayTaskBreakdownTotalTasks:"Somme t\xe2ches",sessionDayTaskBreakdownEmptyDay:"Aucune session ce jour-l\xe0 avec les filtres actuels.",sessionDayTaskBreakdownAddPastSession:"Ajouter une session pass\xe9e pour ce jour…",sessionDayTaskBreakdownNoTasksInRange:"Aucun temps de t\xe2che dans la plage pour cette session (ou t\xe2ches exclues par les r\xe8gles d’archives).",sessionDayTaskBreakdownHelpAria:"Aide : sessions par jour avec ventilation des t\xe2ches",sessionDayTaskBreakdownHelpBody:"Les sessions sont regroup\xe9es par jour de session (m\xeame regroupement que le graphique \xab sessions par jour \xbb). Les minutes de t\xe2che sont les portions de la dur\xe9e enregistr\xe9e dont les jours calendaires tombent dans la plage choisie. Les t\xe2ches planifi\xe9es (cr\xe9neau futur) n’entrent pas dans les totaux enregistr\xe9s : leur fen\xeatre horaire planifi\xe9e s’affiche \xe0 part en ambre. Le filtre d’\xe9tiquettes s’applique : seules les t\xe2ches correspondantes sont list\xe9es ; une session sans aucune t\xe2che correspondante dispara\xeet enti\xe8rement. Sous chaque t\xe2che, chaque ligne # distincte affiche la dur\xe9e compl\xe8te de la ligne (m\xeame r\xe8gle que les grilles d’allocation #). Le bascule permet la lecture t\xe2che → # (tableau par d\xe9faut) ou # → t\xe2che (regroupement par # avec sous-totaux par session ; en mode # d’abord, un encart r\xe9sume les m\xeames tranches sur toutes les sessions du jour). Le choix est m\xe9moris\xe9 dans ce navigateur.",tocSessionDayTaskBreakdown:"Sessions par jour (t\xe2ches)",sessionDayBreakdownOrderLegend:"Ordre des lignes",sessionDayBreakdownOrderGroupAria:"Ordre des lignes pour le d\xe9tail sessions par jour",sessionDayBreakdownOrderTasksFirst:"T\xe2che → #",sessionDayBreakdownOrderTagsFirst:"# → t\xe2che",sessionDayBreakdownDayTagRollupTitle:"Totaux du jour par #",sessionDayBreakdownRollupColTag:"\xc9tiquette",sessionDayBreakdownRenameSessionHint:"Cliquer pour renommer cette session",sessionDayBreakdownRenameSessionAria:"Nom de la session",sessionDayBreakdownRenameTaskHint:"Cliquer pour renommer cette t\xe2che",sessionDayBreakdownRenameTaskAria:"Nom de la t\xe2che",dayMarkerLabel:"Type de jour",dayMarkerNone:"Jour travaill\xe9",dayMarkerBusy:"Enregistrement…",legendSessions:"Sessions",legendDone:"Termin\xe9es",legendActive:"En cours",tableDay:"Jour",tableSessions:"Sessions",tableDone:"Termin\xe9es",tableActive:"En cours",tableTaskTime:"Temps (t\xe2ches)",tableTaskTimeNonConcurrent:"Temps (t\xe2ches, non concurrent)",tableSessionCoding:"Codage (sessions)",tableSessionWall:"Dur\xe9e session",undatedLabel:"Sans date",loading:"Chargement…",noRowsInRange:"Aucune donn\xe9e dans cette plage pour les filtres actuels.",projectSectionTitle:"Temps enregistr\xe9 par projet",projectWeeklyCalendarTitle:"Calendrier hebdomadaire",projectColProject:"Projet",projectColTasks:"T\xe2ches",projectColTime:"Temps enregistr\xe9",projectUnassigned:"(sans projet)",projectTableHint:"Une ligne par semaine calendaire, puis un tableau : chaque projet sur sa propre ligne, sept colonnes jour et le total de la semaine — m\xeame navigation par semaine et m\xeame premier jour de semaine que le calendrier par \xe9tiquette ci-dessus. Utilisez le contr\xf4le Travail (@) / Personnel (!) sous le titre pour changer de registre : Travail (d\xe9faut) exclut le registre personnel ; Personnel n’affiche que celui-ci (t\xe2ches marqu\xe9es personnelles, ou titre avec jeton ! reconnu si le drapeau n’a pas \xe9t\xe9 enregistr\xe9), avec le pr\xe9fixe \xab ! \xbb.",projectScopeLegend:"Registre projet",projectScopeGroupAria:"Temps par projet : registre travail ou personnel",projectScopeWork:"Travail (@)",projectScopePersonal:"Personnel (!)",tagTimeSectionTitle:"Temps enregistr\xe9 par \xe9tiquette",tagTimeSectionHint:"Chaque #tag peut correspondre \xe0 une cl\xe9 externe (ex. poste WBS ou NWA dans SAP). La dur\xe9e enregistr\xe9e compl\xe8te d’une t\xe2che est compt\xe9e pour chaque \xe9tiquette associ\xe9e (additionner les lignes peut d\xe9passer le temps r\xe9el). Le pied du calendrier hebdo affiche le temps enregistr\xe9 une fois par t\xe2che et par jour — pas la somme des lignes #. Plusieurs \xe9tiquettes `projet#code` pour un m\xeame projet sont regroup\xe9es sous une ligne @projet : d\xe9veloppez-la pour voir chaque ligne d’\xe9tiquette.",tagTimeByDayTitle:"Par jour calendaire",tagTimeByWeekTitle:"Calendrier hebdomadaire",tagWeekStartsOnLegend:"La semaine commence",weekStartsMonday:"Lundi",weekStartsSunday:"Dimanche",weekStartsSaturday:"Samedi",tagWeekSumColumn:"Σ semaine",weekCalendarDayTotalsRow:"Total jour",tagWeekDistinctDayTotalsRow:"Temps enregistr\xe9 (par t\xe2che)",tagTimeColTag:"\xc9tiquette",tagTimeColDay:"Jour (t\xe2che)",tagTimeColMinutes:"Temps enregistr\xe9",tagTimeUntagged:"d\xe9faut",tagWeekScopedRollupToggleAria:"Afficher ou masquer le d\xe9tail des \xe9tiquettes pour ce projet",summaryLinesWrittenTotal:"Lignes \xe9crites (sessions dans la plage)",summaryLinesWrittenHuman:"Lignes — humain (estim., somme)",summaryLinesWrittenAi:"Lignes — IA (estim., somme)",locByLanguageSectionTitle:"Lignes par langage (agr\xe9g\xe9)",locByLanguageColLang:"Langage",locByLanguageColLines:"Lignes",codingSignalsSectionTitle:"Signaux de codage par langage (agr\xe9g\xe9)",codingSignalsColLang:"Langage",codingSignalsColCount:"Signaux",locMetricsHint:"Les totaux additionnent les compteurs enregistr\xe9s par session pour les sessions dans la plage (m\xeame r\xe8gle que le temps de codage des sessions). Le filtre d’\xe9tiquettes exclut encore toute la session si aucune t\xe2che ne correspond.",workspaceSnapshotTitle:"Dossier ouvert — lignes par langage (instantan\xe9)",workspaceSnapshotIntro:"Ind\xe9pendant des sessions et des t\xe2ches : estimation du nombre de lignes dans le premier dossier du workspace (fichiers suivis par Git si possible, sinon parcours avec extensions courantes). Mise en cache ~5 minutes.",workspaceSnapshotRefresh:"Rafra\xeechir l’instantan\xe9",workspaceSnapshotRefreshing:"Actualisation…",workspaceSnapshotSourceGit:"Source : fichiers suivis par Git",workspaceSnapshotSourceWalk:"Source : parcours du dossier (sans Git ou liste Git vide)",workspaceSnapshotTotalLines:"Total de lignes (approx.)",workspaceSnapshotFileCount:"Fichiers parcourus",workspaceSnapshotColLang:"Langage",workspaceSnapshotColLines:"Lignes",workspaceSnapshotColPercent:"Part",workspaceSnapshotNoWorkspace:"Aucune racine de workspace configur\xe9e pour l’instantan\xe9.",workspaceSnapshotEmpty:"Aucun fichier source correspondant trouv\xe9.",workspaceSnapshotError:"Impossible de construire l’instantan\xe9.",workspaceSnapshotRefreshHint:"Utilisez \xab Rafra\xeechir l’instantan\xe9 \xbb apr\xe8s un changement de chemins ou d’exclusions du workspace dans les param\xe8tres.",tocTitle:"Sur cette page",tocNavAria:"Rapports — sections de la page",tocSummaryKpis:"Indicateurs de synth\xe8se",tocClosureBreakdown:"Sessions par type de cl\xf4ture",closureBreakdownTitle:"Sessions par type de cl\xf4ture",closureBreakdownUnspecified:"Sans cat\xe9gorie (ouverte ou non enregistr\xe9e)",tocDailyTable:"Tableau par jour",tocTagTimeSection:"Temps par \xe9tiquette",weekNavPrev:"Semaine pr\xe9c\xe9dente",weekNavNext:"Semaine suivante",weekNavAriaLabel:"Navigation par semaine pour les graphiques et tableaux",tocWeekNav:"Navigation par semaine",weekNavHelpHint:"Affich\xe9 lorsque plusieurs semaines dans la plage ont des donn\xe9es de session (dur\xe9e murale ou nombre de sessions), sinon des semaines issues du temps enregistr\xe9 par \xe9tiquette ou par projet. Les graphiques, le tableau par jour et les calendriers hebdomadaires suivent la semaine s\xe9lectionn\xe9e.",weekNavNoTagDataThisWeek:"Aucun temps de t\xe2che enregistr\xe9 pour cette semaine.",weekNavNoProjectDataThisWeek:"Aucun temps de t\xe2che par projet pour cette semaine.",tocLocSection:"Lignes et signaux de codage",tocViewTabs:"Vues (onglets)",reportingViewTabBilling:"Allocation facturation",reportingViewTabRhythm:"Rythme",reportingViewTabAdvanced:"Avanc\xe9",reportingViewTabGroupAria:"Vues des rapports",reportingViewBillingIntro:"Associez le temps enregistr\xe9 aux #\xe9tiquettes et aux @projets pour vos codes de facturation. Les totaux suivent les m\xeames filtres qu’en haut ; le travail encore ouvert est rappel\xe9 dans Filtres le cas \xe9ch\xe9ant.",reportingViewTabBillingDesc:"R\xe9partissez le temps enregistr\xe9 par #\xe9tiquette et @projet sur des grilles hebdomadaires pour codifier des lignes de facturation client, des postes WBS SAP ou des cl\xe9s de refacturation interne.",reportingViewTabRhythmDesc:"Consultez les graphiques d’activit\xe9 par jour et la liste sessions-par-jour : dur\xe9e murale, temps de t\xe2che enregistr\xe9 et fen\xeatres planifi\xe9es sur la semaine affich\xe9e.",reportingViewTabAdvancedDesc:"Indicateurs de synth\xe8se sur toute la plage filtr\xe9e, tableau jour par jour, lignes et signaux de codage, instantan\xe9 du workspace et r\xe9partition des sessions par type de cl\xf4ture.",billingTaskTimeWeekScope:"Total pour la semaine {weekRange}",scrollToTopAria:"Retour en haut de la page",...{metricHelpSessionsAria:"Aide : sessions dans la plage",metricHelpSessionsBody:"Nombre de sessions dont le jour calendaire (savedAt, ou endAt, ou startAt) tombe dans la plage choisie. Avec un filtre d’\xe9tiquettes, une session n’est compt\xe9e que si au moins une de ses t\xe2ches correspond.",metricHelpTaskRowsAria:"Aide : lignes de t\xe2ches dans la plage",metricHelpTaskRowsBody:"Nombre d’enregistrements de t\xe2ches pris en compte : le jour de la t\xe2che (fin ou d\xe9but) doit \xeatre dans la plage et la t\xe2che doit passer le filtre d’\xe9tiquettes. Les r\xe8gles des sessions archiv\xe9es s’appliquent (t\xe2ches non termin\xe9es parfois exclues).",metricHelpKronoFocusCompletedAria:"Aide : sessions KronoFocus termin\xe9es",metricHelpKronoFocusCompletedBody:"Somme du compteur \xab sessions termin\xe9es \xbb au niveau session enregistr\xe9 sur chaque instantan\xe9, pour les sessions dont le jour est dans la plage. Ce n’est pas par t\xe2che ; c’est l’\xe9tat KronoFocus sauvegard\xe9 avec la session.",metricHelpKronoFocusTasksUsedAria:"Aide : t\xe2ches avec KronoFocus utilis\xe9",metricHelpKronoFocusTasksUsedBody:"Nombre de t\xe2ches dans la plage avec usedKronoFocus, apr\xe8s filtres d’\xe9tiquettes et r\xe8gles d’archivage.",metricHelpKronoFocusCyclesAria:"Aide : cycles KronoFocus (t\xe2ches)",metricHelpKronoFocusCyclesBody:"Somme des kronoFocusCycles sur les t\xe2ches incluses dans la plage (m\xeames filtres que les autres m\xe9triques t\xe2che).",metricHelpTaskTimeAria:"Aide : temps enregistr\xe9 sur les t\xe2ches",metricHelpTaskTimeBody:"Dur\xe9e totale enregistr\xe9e (durationMs) des t\xe2ches incluses, affich\xe9e en heures/minutes. Filtres de jour et d’\xe9tiquettes appliqu\xe9s.",metricHelpSessionCodingAria:"Aide : temps de codage (sessions)",metricHelpSessionCodingBody:"Somme des minutes de codage sauvegard\xe9es par session (codingMinutesSession) pour les sessions dont le jour est dans la plage. Ind\xe9pendant des minuteurs de t\xe2che.",metricHelpSessionActiveAria:"Aide : temps actif (sessions)",metricHelpSessionActiveBody:"Somme des minutes actives sauvegard\xe9es par session (activeMinutes) pour les sessions dans la plage. Bas\xe9 sur les signaux d’activit\xe9 de l’IDE, pas sur le temps t\xe2che.",metricHelpLinesTotalAria:"Aide : lignes \xe9crites (sessions dans la plage)",metricHelpLinesTotalBody:"Somme des linesWrittenTotal de chaque session incluse dans la plage (lignes nettes des modifications suivies, m\xeame d\xe9finition que le tableau de bord).",metricHelpLinesHumanAria:"Aide : lignes — humain (estim.)",metricHelpLinesHumanBody:"Somme des lignes estim\xe9es \xab humain \xbb (linesWrittenHuman) par session dans la plage. La r\xe9partition repose sur une heuristique par modification, pas sur une attribution exacte.",metricHelpLinesAiAria:"Aide : lignes — IA (estim.)",metricHelpLinesAiBody:"Somme des lignes estim\xe9es \xab IA \xbb (linesWrittenAi) par session dans la plage. Les gros blocs ou les modifications multi-plages sont plus souvent class\xe9s c\xf4t\xe9 IA.",metricHelpLocByLangTitleAria:"Aide : lignes par langage (agr\xe9g\xe9)",metricHelpLocByLangTitleBody:"Fusion des couples locByLanguage de chaque session dans la plage : total de lignes nettes par identifiant de langage.",metricHelpCodingSignalsTitleAria:"Aide : signaux de codage par langage (agr\xe9g\xe9)",metricHelpCodingSignalsTitleBody:"Fusion des codingSignalsByLanguage des sessions incluses : nombre d’\xe9v\xe9nements de contexte de codage (ouverture, enregistrement, \xe9dition, \xe9diteur actif, etc.) par langage.",metricHelpChartSessionsAria:"Aide : sessions par jour",metricHelpChartSessionsBody:"Pour chaque jour du graphique, combien de sessions ont leur jour de session dans ce compartiment. M\xeames r\xe8gles de plage et d’\xe9tiquettes que les cartes r\xe9capitulatives.",metricHelpChartTasksAria:"Aide : t\xe2ches par jour et par statut",metricHelpChartTasksBody:"Par jour : vert = t\xe2ches termin\xe9es dans la plage ; ambre = t\xe2ches encore en cours. Filtres de jour et d’\xe9tiquettes ; les sessions archiv\xe9es ont des r\xe8gles de compl\xe9tion plus strictes.",metricHelpChartTaskTimeAria:"Aide : temps enregistr\xe9 sur les t\xe2ches par jour",metricHelpChartTaskTimeBody:"Pour chaque jour, somme des dur\xe9es enregistr\xe9es sur les t\xe2ches (durationMs → minutes) dont le jour de t\xe2che tombe dans ce compartiment. M\xeames r\xe8gles d’\xe9tiquettes et d’archivage que les d\xe9comptes de t\xe2ches. La hauteur des barres est proportionnelle au jour le plus charg\xe9 dans la vue.",metricHelpChartSessionWallAria:"Aide : dur\xe9e murale des sessions par jour",metricHelpChartSessionWallBody:"Par jour calendaire, somme des minutes \xab murales \xbb de session : sessionDurationMinutes enregistr\xe9 si pr\xe9sent, sinon \xe9cart entre startAt et endAt. Rattachement au jour de session (comme le d\xe9compte des sessions). Diff\xe8re du temps de codage (les pauses inactivit\xe9 ne comptent pas comme codage).",metricHelpTblDayAria:"Aide : colonne jour",metricHelpTblDayBody:"Cl\xe9 de jour calendaire (date locale) ou \xab sans date \xbb si aucune date n’a pu \xeatre d\xe9riv\xe9e.",metricHelpTblSessionsAria:"Aide : colonne sessions",metricHelpTblSessionsBody:"Nombre de sessions rattach\xe9es \xe0 ce jour (m\xeames r\xe8gles que le graphique des sessions).",metricHelpTblDoneAria:"Aide : colonne termin\xe9es",metricHelpTblDoneBody:"Nombre de t\xe2ches termin\xe9es rattach\xe9es \xe0 ce jour.",metricHelpTblActiveAria:"Aide : colonne en cours",metricHelpTblActiveBody:"Nombre de t\xe2ches encore en cours rattach\xe9es \xe0 ce jour.",metricHelpTblTaskTimeAria:"Aide : colonne — temps enregistr\xe9 (t\xe2ches)",metricHelpTblTaskTimeBody:"Somme des durationMs (en minutes) pour les t\xe2ches rattach\xe9es \xe0 ce jour calendaire — m\xeame base que \xab Temps enregistr\xe9 sur les t\xe2ches \xbb dans la synth\xe8se et qu’un total type feuille de temps / Jira par jour.",metricHelpTblSessionCodingAria:"Aide : colonne — temps de codage (sessions)",metricHelpTblSessionCodingBody:"Somme des codingMinutesSession pour les sessions dont le jour de session correspond \xe0 cette ligne. Repose sur le jour de session (pas le jour de t\xe2che), comme la colonne \xab Sessions \xbb.",metricHelpTblSessionWallAria:"Aide : colonne — dur\xe9e murale (sessions)",metricHelpTblSessionWallBody:"Total des minutes \xab murales \xbb pour les sessions de ce jour de session : dur\xe9e persist\xe9e ou startAt→endAt. \xc0 comparer au \xab Codage (sessions) \xbb (temps de frappe actif seulement).",metricHelpSessionWallSummaryAria:"Aide : dur\xe9e murale des sessions (synth\xe8se)",metricHelpSessionWallSummaryBody:"Somme des minutes murales pour chaque session incluse dans la plage (r\xe8gles de jour de session et d’\xe9tiquettes). Ind\xe9pendant des minuteurs de t\xe2che ; compl\xe8te les temps de codage et d’activit\xe9.",metricHelpTagTimeSectionAria:"Aide : temps par \xe9tiquette (type WBS / SAP)",metricHelpTagTimeSectionBody:"Temps enregistr\xe9 sur les t\xe2ches (durationMs) rattach\xe9 \xe0 chaque #tag. La dur\xe9e compl\xe8te est compt\xe9e pour chaque \xe9tiquette de la t\xe2che (en additionnant les lignes par \xe9tiquette, le total peut d\xe9passer celui des indicateurs lorsque des t\xe2ches portent plusieurs \xe9tiquettes). Les t\xe2ches sans \xe9tiquette explicite sont regroup\xe9es dans le compartiment par d\xe9faut (affich\xe9 \xab d\xe9faut \xbb en fran\xe7ais). M\xeames filtres de dates, d’\xe9tiquettes et r\xe8gles d’archivage que les autres m\xe9triques t\xe2che.",metricHelpTagTimeDayTableAria:"Aide : tableau temps par \xe9tiquette et par jour",metricHelpTagTimeDayTableBody:"Une ligne par \xe9tiquette et par jour de t\xe2che, avec la somme des minutes pour ce couple. Les lignes sont regroup\xe9es par jour calendaire ; plusieurs \xe9tiquettes `projet#code` pour un m\xeame projet le m\xeame jour sont sous une ligne de synth\xe8se @projet — d\xe9veloppez pour voir chaque \xe9tiquette.",metricHelpTagTimeWeekTableAria:"Aide : calendrier hebdomadaire par \xe9tiquette",metricHelpTagTimeWeekTableBody:"Sept cases pour les jours de la semaine plus une colonne total : minutes enregistr\xe9es sur les t\xe2ches pour chaque date, dans l’ordre impos\xe9 par le premier jour de semaine choisi (lundi, dimanche ou samedi). La p\xe9riode rapide \xab Semaine \xbb des filtres reste lundi–dimanche ; seule cette grille suit votre r\xe9glage.",metricHelpTagWeekCalendarAria:"Aide : colonnes du calendrier hebdomadaire",metricHelpTagWeekCalendarBody:"Pour chaque semaine calendaire, la p\xe9riode s’affiche une seule fois au-dessus d’un tableau unique : une ligne par \xe9tiquette, les colonnes sont les sept jours locaux (selon le premier jour de semaine) plus le total de la semaine. Chaque en-t\xeate de colonne indique le jour de la semaine et la date calendaire r\xe9elle ; survolez un en-t\xeate ou une case jour pour la date exacte (AAAA-MM-JJ). Lorsque plusieurs \xe9tiquettes suivent le motif `projet#code` pour un m\xeame projet, elles sont regroup\xe9es sous une ligne de synth\xe8se @projet ; le chevron permet de d\xe9velopper le d\xe9tail par \xe9tiquette et par minutes.",metricHelpTagWeekDistinctTotalsAria:"Aide : ligne de pied du calendrier par #",metricHelpTagWeekDistinctTotalsBody:"Par jour calendaire et pour la colonne semaine : temps enregistr\xe9 sur les t\xe2ches, compt\xe9 une fois par t\xe2che (m\xeame base que l’indicateur de synth\xe8se et les graphiques Rythme). Ce n’est pas la somme des lignes # ci-dessus — une t\xe2che multi-\xe9tiquettes affiche toujours sa dur\xe9e compl\xe8te sur chaque ligne # pour le rattachement WBS.",metricHelpTagWeekStartsOnAria:"Aide : premier jour de la semaine",metricHelpTagWeekStartsOnBody:"D\xe9termine quel jour commence la bande des 7 jours : lundi (habitude ISO), dimanche (habitude nord-am\xe9ricaine) ou samedi. M\xe9moris\xe9 uniquement dans ce navigateur (localStorage).",metricHelpWeekNavAria:"Aide : navigation par semaine",metricHelpWeekNavBody:"Pr\xe9c\xe9dente / suivante fait d\xe9filer une semaine \xe0 la fois parmi les semaines qui ont une dur\xe9e murale de session ou au moins une session dans la plage filtr\xe9e. Sinon, les semaines proviennent du temps enregistr\xe9 par \xe9tiquette ou par @projet. Les graphiques en barres, le tableau par jour et les deux calendriers hebdomadaires (\xe9tiquettes et projets) ne montrent que la semaine s\xe9lectionn\xe9e (sept jours locaux selon le premier jour de semaine).",metricHelpTagTimeColTagAria:"Aide : colonne \xe9tiquette",metricHelpTagTimeColTagBody:"\xc9tiquette Kronosys (#tag) ; peut servir de libell\xe9 pour la cl\xe9 saisie \xe0 l’ext\xe9rieur (ex. \xe9l\xe9ment WBS).",metricHelpTagTimeColDayAria:"Aide : colonne jour",metricHelpTagTimeColDayBody:"Jour de la t\xe2che (horodatage de fin ou de d\xe9but), AAAA-MM-JJ.",metricHelpTagTimeColWeekAria:"Aide : ligne de p\xe9riode",metricHelpTagTimeColWeekBody:"Cette ligne nomme la semaine calendaire une seule fois pour le tableau ci-dessous (dates locales). La fronti\xe8re de semaine suit le r\xe9glage \xab La semaine commence \xbb.",metricHelpTagTimeColMinutesAria:"Aide : colonne minutes",metricHelpTagTimeColMinutesBody:"Somme des minutes de t\xe2che attribu\xe9es \xe0 cette \xe9tiquette sur la p\xe9riode de la ligne. Les minutes ne sont pas r\xe9parties entre les \xe9tiquettes : une t\xe2che multi-\xe9tiquettes compte sa dur\xe9e enti\xe8re sur chaque ligne d’\xe9tiquette.",metricHelpProjectTitleAria:"Aide : temps enregistr\xe9 par projet",metricHelpProjectTitleBody:"Dur\xe9e enregistr\xe9e sur les t\xe2ches (durationMs) ventil\xe9e par le champ projet de chaque t\xe2che, sous forme de calendrier hebdomadaire : une ligne de p\xe9riode par semaine, puis un tableau avec une ligne par projet et sept colonnes jour plus le total de la semaine. Utilisez le s\xe9lecteur Travail (@) / Personnel (!) pour choisir le registre : Travail (d\xe9faut) ne compte que les t\xe2ches non personnelles ; Personnel compte les t\xe2ches marqu\xe9es personnelles (`personalProject`) et celles dont le titre contient un jeton `!` reconnu (repli si le drapeau n’a pas \xe9t\xe9 enregistr\xe9), avec libell\xe9s \xab ! \xbb. M\xeames plage de dates, filtre d’\xe9tiquettes, r\xe8gles d’archivage et navigation par semaine que le calendrier par \xe9tiquette.",metricHelpProjectCalendarAria:"Aide : calendrier hebdomadaire par projet",metricHelpProjectCalendarBody:"M\xeame pr\xe9sentation que le calendrier par \xe9tiquette : pour chaque semaine, la plage de dates s’affiche une fois ; chaque ligne correspond \xe0 un projet pour le registre choisi (Travail ou Personnel). Les en-t\xeates de colonnes indiquent le jour de la semaine et la date calendaire ; les cases jour utilisent le jour de la t\xe2che (fin ou d\xe9but) ; survol d’un en-t\xeate ou d’une case pour AAAA-MM-JJ.",metricHelpProjectColProjAria:"Aide : colonne projet",metricHelpProjectColProjBody:"Nom du projet sur la t\xe2che (avec @ ou ! selon le registre), ou \xab sans projet \xbb si absent.",metricHelpProjectColTasksAria:"Aide : colonne t\xe2ches",metricHelpProjectColTasksBody:"Nombre de lignes de t\xe2ches agr\xe9g\xe9es pour ce projet.",metricHelpProjectColTimeAria:"Aide : colonne temps enregistr\xe9",metricHelpProjectColTimeBody:"Total des minutes enregistr\xe9es sur les t\xe2ches pour ce projet sur les sept jours de la ligne (durationMs), pour le registre Travail ou Personnel s\xe9lectionn\xe9.",metricHelpWorkspaceTitleAria:"Aide : instantan\xe9 du dossier ouvert",metricHelpWorkspaceTitleBody:"Instantan\xe9 du premier dossier du workspace : lignes par langage \xe0 partir des fichiers suivis par Git ou d’un parcours du dossier. Ind\xe9pendant des sessions Kronosys ; mis en cache ~5 minutes. Voir le paragraphe descriptif sous le titre.",metricHelpWsTotalLinesAria:"Aide : total de lignes (approx.)",metricHelpWsTotalLinesBody:"Total approximatif de lignes lues dans les fichiers source (extensions reconnues), pour cet instantan\xe9.",metricHelpWsFileCountAria:"Aide : fichiers parcourus",metricHelpWsFileCountBody:"Nombre de fichiers ayant contribu\xe9 \xe0 l’instantan\xe9 (apr\xe8s filtres de taille et de type).",metricHelpWsColLangAria:"Aide : colonne langage",metricHelpWsColLangBody:"Identifiant de langage (style TextMate) d\xe9duit de l’extension du fichier.",metricHelpWsColLinesAria:"Aide : colonne lignes",metricHelpWsColLinesBody:"Nombre de lignes pour ce langage dans les fichiers parcourus.",metricHelpWsColPercentAria:"Aide : colonne part",metricHelpWsColPercentBody:"Pourcentage du total de lignes de l’instantan\xe9 pour ce langage (la somme des arrondis peut diff\xe9rer l\xe9g\xe8rement de 100 %).",metricHelpAggLocColLangAria:"Aide : langage (lignes agr\xe9g\xe9es)",metricHelpAggLocColLangBody:"Identifiant de langage (style TextMate) ; les valeurs sont additionn\xe9es sur les sessions dans la plage.",metricHelpAggLocColLinesAria:"Aide : lignes (agr\xe9g\xe9)",metricHelpAggLocColLinesBody:"Total des lignes nettes \xe9crites dans ce langage pour les sessions incluses.",metricHelpAggSigColLangAria:"Aide : langage (signaux)",metricHelpAggSigColLangBody:"Identifiant de langage pour les comptes de signaux agr\xe9g\xe9s.",metricHelpAggSigColCountAria:"Aide : nombre de signaux",metricHelpAggSigColCountBody:"Total de signaux de contexte de codage pour ce langage sur les sessions incluses.",metricHelpLegendDoneAria:"Aide : l\xe9gende — t\xe2ches termin\xe9es",metricHelpLegendDoneBody:"Segment vert : t\xe2ches marqu\xe9es termin\xe9es pour ce jour (m\xeames filtres que le graphique).",metricHelpLegendActiveAria:"Aide : l\xe9gende — en cours",metricHelpLegendActiveBody:"Segment ambre : t\xe2ches non termin\xe9es pour ce jour.",metricHelpLegendSessionsAria:"Aide : l\xe9gende — sessions",metricHelpLegendSessionsBody:"Hauteur de chaque barre : nombre de sessions dont le jour de session correspond \xe0 cette colonne (m\xeames r\xe8gles de plage et d’\xe9tiquettes).",metricHelpAssiduityRefAria:"Aide : sessions avec heure de d\xe9but de r\xe9f\xe9rence",metricHelpAssiduityRefBody:"Sessions de la plage pour lesquelles l’h\xf4te a enregistr\xe9 un instant de d\xe9but pr\xe9vu \xe0 l’ouverture (`scheduledStartAt` sur l’action `newSession`). Seul l’encha\xeenement qui lance la session (p. ex. moteur d’horaire) fournit en g\xe9n\xe9ral ce champ : une nouvelle session lanc\xe9e depuis le seul tableau de bord n’y a pas, sauf int\xe9gration. M\xeames r\xe8gles de jour de session et d’\xe9tiquettes que le comptage des sessions.",metricHelpAssiduityLateCountAria:"Aide : sessions en retard (assiduit\xe9)",metricHelpAssiduityLateCountBody:"Parmi les sessions r\xe9f\xe9renc\xe9es, combien ont d\xe9marr\xe9 apr\xe8s l’instant pr\xe9vu (\xe9cart strictement positif en minutes). Un d\xe9marrage \xe0 l’heure ou en avance n’augmente pas ce compteur.",metricHelpAssiduityLateTotalAria:"Aide : retard cumul\xe9",metricHelpAssiduityLateTotalBody:"Somme des retards (minutes) session par session dans la plage, en ne comptant que la partie tardive (les d\xe9marrages \xe0 l’heure ou avant comptent 0).",metricHelpAssiduityAvgLateAria:"Aide : retard moyen (lorsqu’en retard)",metricHelpAssiduityAvgLateBody:"Retard cumul\xe9 divis\xe9 par le nombre de sessions en retard ; indiqu\xe9 en \xab — \xbb s’il n’y en a pas. Pertinent lorsqu’une heure de d\xe9but a \xe9t\xe9 enregistr\xe9e c\xf4t\xe9 h\xf4te.",metricHelpClosureBreakdownAria:"Aide : sessions par type de cl\xf4ture",metricHelpClosureBreakdownBody:"Nombre de sessions incluses par cat\xe9gorie enregistr\xe9e \xe0 la fin de session (conforme au pr\xe9vu, anticip\xe9e, prolongation, autre). \xab Sans cat\xe9gorie \xbb regroupe les sessions encore ouvertes et celles termin\xe9es sans choix enregistr\xe9. M\xeames r\xe8gles de jour de session et d’\xe9tiquettes que \xab Sessions (plage) \xbb ; la somme des cinq lignes \xe9gale ce total.",metricHelpSummaryKpisSectionAria:"Aide : indicateurs de synth\xe8se",metricHelpSummaryKpisSectionBody:"Les cartes agr\xe8gent sessions et t\xe2ches sur toute la plage de dates et d’\xe9tiquettes — pas la semaine choisie dans Allocation facturation et Rythme. Les m\xe9triques session utilisent le jour de session ; le temps de t\xe2che, le jour de t\xe2che. Sessions archiv\xe9es : les totaux bas\xe9s sur les t\xe2ches n’incluent que les t\xe2ches enti\xe8rement termin\xe9es (sous-t\xe2ches incluses). KronoFocus suit la m\xeame r\xe9partition session/t\xe2che qu’ailleurs sur cette page.",metricHelpLocMetricsSectionAria:"Aide : lignes et signaux de codage",metricHelpLocMetricsSectionBody:"Les totaux additionnent les compteurs enregistr\xe9s par session pour les sessions dont le jour est dans la plage. Le filtre d’\xe9tiquettes exclut toute la session si aucune t\xe2che ne correspond. Les tableaux \xab Lignes par langage \xbb et \xab Signaux de codage \xbb agr\xe8gent le m\xeame ensemble de sessions.",metricHelpDailyTableSectionAria:"Aide : tableau par jour",metricHelpDailyTableSectionBody:"Une ligne par jour calendaire dans la plage filtr\xe9e. Les colonnes session utilisent le jour de session ; le temps de t\xe2che, le jour de t\xe2che. \xab Temps t\xe2che (non concurrent) \xbb retire le chevauchement entre intervalles horodat\xe9s ce jour-l\xe0. Le filtre d’\xe9tiquettes s’applique aux colonnes t\xe2che ; les sessions sans t\xe2che correspondante sont omises des comptages session."}};function g(a){return"fr"===a?f:e}function h(a){let b=g(a),c=(0,d.z)(a);return{dashboard:b.dashboard,reporting:b.reporting,settings:b.settings,logs:b.logs,guide:b.guide,implementation:b.implementation,changelog:b.changelog,dashboardAttentionHint:c.navDashboardPlannedConflictPulseHint,navGanttDashboardOnlyTooltip:b.navGanttDashboardOnlyTooltip,navGlobalPauseDashboardOnlyTooltip:b.navGlobalPauseDashboardOnlyTooltip,navGlobalPauseNoSessionContextTooltip:b.navGlobalPauseNoSessionContextTooltip,navChangelogUnavailableTooltip:b.navChangelogUnavailableTooltip,navGanttButtonLabel:b.navGanttButtonLabel,navGlobalPauseButtonLabel:b.navGlobalPauseButtonLabel,navGroupAppAria:c.appShellRouteNavGroupAppAria,navGroupDocsAria:c.appShellRouteNavGroupDocsAria,navGroupToolsAria:c.appShellRouteNavGroupToolsAria}}},55435:(a,b,c)=>{"use strict";c.d(b,{DataEnvironmentChrome:()=>d});let d=(0,c(77943).registerClientReference)(function(){throw Error("Attempted to call DataEnvironmentChrome() from the server but DataEnvironmentChrome is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/dashboard/DataEnvironmentChrome.tsx","DataEnvironmentChrome")},58032:(a,b,c)=>{"use strict";c.d(b,{Z:()=>g});var d=c(73024),e=c(76760);function f(a){try{let b=d.readFileSync(a,"utf8"),c=JSON.parse(b).version;if("string"==typeof c&&c.trim().length>0)return c.trim()}catch{}return null}function g(){let a=process.env.KRONOSYS_APP_VERSION?.trim();if(a)return a;let b=process.cwd(),c=f(e.join(b,"kronosys-package-meta.json"));return c||(f(e.join(b,"package.json"))??"0.0.0")}},58857:(a,b,c)=>{Promise.resolve().then(c.bind(c,48528)),Promise.resolve().then(c.bind(c,31066)),Promise.resolve().then(c.bind(c,55435)),Promise.resolve().then(c.bind(c,49194)),Promise.resolve().then(c.bind(c,77071)),Promise.resolve().then(c.bind(c,67227)),Promise.resolve().then(c.bind(c,90665)),Promise.resolve().then(c.bind(c,84490)),Promise.resolve().then(c.bind(c,93356)),Promise.resolve().then(c.bind(c,9576)),Promise.resolve().then(c.bind(c,25876)),Promise.resolve().then(c.bind(c,11081)),Promise.resolve().then(c.bind(c,90595)),Promise.resolve().then(c.bind(c,17843)),Promise.resolve().then(c.t.bind(c,23318,23))},59899:(a,b,c)=>{"use strict";c.d(b,{r:()=>g,z:()=>f});let d={kronoFocusTitle:"KronoFocus",workMode:"KronoFocus",breakMode:"Short break",longBreakMode:"Long break",kronoFocusStart:"Start",kronoFocusPause:"Pause",kronoFocusReset:"Reset",kronoFocusControlsReadOnlyTooltip:"Read-only while you inspect an archive — these controls target the live session.",kronoFocusLinkedTaskIntro:"Started from:",kronoFocusEditDurationTitle:"Configure KronoFocus rhythm (timer not started)",kronoFocusDurationPickerLabel:"Duration (hours : minutes : seconds)",kronoFocusApplyDuration:"Apply",kronoFocusCancelDurationEdit:"Cancel",kronoFocusDurationHelpAriaLabel:"Duration help",kronoFocusDurationHelpBody:"Enter the work segment length as hours, minutes, and seconds (elapsed time, e.g. 00:25:00 or 01:30:00 — not a time of day). You may omit seconds (e.g. 0:25). Range: 1 minute to 8 hours. Short and long breaks are set in whole minutes in the same dialog. Set everything before starting KronoFocus.",kronoFocusDurationInputPlaceholder:"00:25:00",kronoFocusDefaultWorkDuration:"Default — 00:25:00",kronoFocusDurationHistoryLabel:"Recent custom durations",kronoFocusDurationHistoryPickAria:"Select duration {time}",kronoFocusDurationHistoryClear:"Clear",kronoFocusDurationHistoryClearTitle:"Clear all saved custom durations",kronoFocusRhythmPresetsHeading:"Quick presets (work / short / long break)",kronoFocusRhythmPresetLabels:["25 / 5","50 / 10","45 / 15","52 / 17"],kronoFocusRhythmPresetTitles:["25 min work, 5 min short break, 15 min long break after every 4 work segments","50 min work, 10 min short break, 20 min long break after every 4 work segments","45 min work, 15 min short break, 15 min long break after every 4 work segments","52 min work, 17 min short break, 30 min long break after every 4 work segments"],kronoFocusShortBreakMinutesLabel:"Short break (minutes)",kronoFocusLongBreakMinutesLabel:"Long break (minutes)",kronoFocusRhythmBreaksMinutesHint:"Whole minutes, 1–480 each. Long break runs after every 4 completed work segments.",startTaskWithKronoFocus:"Also start the KronoFocus timer",startTaskWithKronoFocusToggleAriaOff:"Also start KronoFocus when tracking begins — off. Press to turn on.",startTaskWithKronoFocusToggleAriaOn:"Also start KronoFocus when tracking begins — on. Press to turn off.",startKronoFocusFromActiveTask:"Start KronoFocus",startKronoFocusFromTaskConfirm:"KronoFocus is already running or paused. Reset the timer and start a new work segment?",launcherTitle:"Tasks",taskPlaceholder:"What are you working on?",taskNoteLabel:"Task note",taskNoteAddBtn:"Add a note",taskNotePlaceholder:"Add a free-form note for this task…",taskNoteEditHint:"Click to edit note (Markdown supported)",taskMarkdownHelpAriaLabel:"Markdown help for task notes",taskMarkdownHelpIntro:"Use **Add a note** on the task card or launcher to open the field. Saved notes render as Markdown (GFM subset, GitLab/GitHub compatible). Task titles support inline Markdown in read-only mode.",taskMarkdownHelpNoteHeading:"Note (block)",taskMarkdownHelpTitleHeading:"Title (inline when reading)",taskMarkdownHelpSecurity:"Raw HTML is not allowed; external links open in a new tab.",taskMarkdownHelpGfmLimits:"Supported: bold, italic, strikethrough, lists, task checkboxes, tables, autolinks, images (http/https). Not supported: Mermaid, math, GitLab @mentions/#issues, alert blocks, emoji shortcuts.",taskPlaceholderPast:"What did you work on?",archiveAddTaskIntro:"Past entry: open the time-range modal to set start and end (end is prefilled from start plus the minimum duration in Settings). Adjust timer duration (h/m/s) if needed. Tags and @project work as usual; live timers and detail items do not apply — live or archived session.",archiveAddTaskIntroHelpAria:"Help: past entry",taskEntryModeRealtime:"Real-time",taskEntryModePast:"Past/planned",taskEntryModeGroupAria:"Entry mode",archiveTaskStartLabel:"Start",archiveTaskEndLabel:"End",taskTimingDurationLabel:"Duration",taskTimingAdjustModalTitle:"Adjust duration?",taskTimingAdjustModalMessage:"You changed task timing. Choose how duration should be recalculated.",taskTimingAdjustKeepDuration:"Keep the recorded timer duration",taskTimingAdjustManualDuration:"Set duration manually (h/m/s)",taskTimingAdjustFromBounds:"Set duration from start/end timestamps",taskTimingAdjustHours:"Hours",taskTimingAdjustMinutes:"Minutes",taskTimingAdjustSeconds:"Seconds",taskTimingAdjustLapSectionTitle:"Running timer lap (lap #{n})",taskTimingAdjustLapKeep:"Keep this lap as-is (lap timestamps unchanged)",taskTimingAdjustLapFlush:"Close this lap now (save it as a completed lap)",taskTimingAdjustLapAlignStart:"Realign this lap to the new task start",taskTimingAdjustModalMessageRunning:"You changed the task start while a timer lap is running. Choose what to do with that lap and how total duration should be recalculated.",taskTimerLapsHeading:"Tracking laps",taskTimerLapDeleteBtn:"Delete lap",taskTimerLapDeleteConfirmTitle:"Delete this lap?",taskTimerLapDeleteConfirmMessage:"This removes the lap from the list and subtracts its duration from the task timer total.",taskTimerLapRunningLabel:"running…",taskStartTimeSaveAria:"Save corrected task start time",sessionStartTimeSaveAria:"Save corrected session start time",taskEndTimeSaveAria:"Save corrected task end time",sessionEndTimeSaveAria:"Save corrected session end time",sessionEndTimeEditSectionTitle:"Session end",sessionStartTimeEditSectionTitle:"Session start",taskPastDatetimePlaceholder:"yy-mm-dd --:--:--",taskPastDatetimeTimeLabel:"Time",taskPastDatetimeHourAria:"Hour (24-hour clock)",taskPastDatetimeMinuteAria:"Minutes",taskPastDatetimeTodayBtn:"Today",taskPastDatetimeNowBtn:"Now",archiveAddTaskBtn:"Add to session",archiveTaskDatetimeRangeInvalid:"Enter a valid start and end; the end must be after the start (local date and time).",archiveTaskTimerDurationLabel:"Timer duration",pastTaskTimingModalTitle:"Past entry — time range",pastTaskTimingEditBtn:"Set start, end & timer duration…",pastTaskTimingSummaryAria:"Edit start, end, and timer duration for past entry",pastTaskTimingModalConfirm:"OK",pastTaskTimingModalCancel:"Cancel",pastTaskTimingEndOptional:"optional",archiveTaskManualDurationInvalid:"Enter a timer duration greater than zero and no longer than the gap between start and end.",activeTaskTitleEditHint:"Click to edit title; type #tags in the field or use the row below",activeTaskTitleInputAria:"Edit title; optional #tags or @project in the field, pills below for existing tags",taskStartBlockedByPlannedBoundaryConflict:"Close the planned-task timer dialog first, then start another task.",plannedTaskScheduleActivatedToast:"Scheduled task is now tracking time: \xab {name} \xbb",plannedTaskScheduleActivatedToastUnnamed:"Untitled task",plannedSessionScheduleActivatedToast:"Scheduled session has started: \xab {name} \xbb",plannedSessionScheduleActivatedToastUnnamed:"Untitled session",startTaskBtn:"Start tracking",taskSaveTemplateBtn:"Save as template",taskAlreadyTemplateBtn:"Already saved as template",taskTemplateSavedToast:"Task template saved.",finishTaskBtn:"Finish",finishTaskOpenSubtasksWarnTitle:"Finish task?",finishTaskOpenSubtasksWarnBody:"This task still has open detail items. They will all be marked done when you finish the task.",reopenTaskBtn:"Reopen",reopenTaskModalTitle:"Reopen this task?",reopenTaskModalMessage:"The task will be active again. Choose how to handle the recorded timer duration.",reopenTaskTimerResume:"Resume timer (keep recorded duration)",reopenTaskTimerPaused:"Reopen paused (keep recorded duration)",reopenTaskTimerManual:"Set duration manually (h/m/s)",reopenTaskTimerReset:"Reset timer to zero",reopenTaskSubtasksNote:"Detail items will be reopened as well.",reopenTaskEndedSessionHint:"This session is closed — the timer cannot run live; duration choices still apply to the snapshot.",taskDeleteBtn:"Delete",taskDuplicateBtn:"Copy task to input",taskDuplicateTooltip:"Copy title, tags, and project to the input field.",taskDeleteConfirm:"Delete this entry? Recorded time will be lost. This cannot be undone.",taskConcurrentTrackingConflictTitle:"Tracking already active",taskConcurrentTrackingConflictMessage:"One or more tasks already have a running timer. Choose what to do with them before starting this task: finish them (moved to completed), pause them (resume later from the paused list), or keep them running and start this task in parallel.",taskConcurrentTrackingConflictPauseBtn:"Pause active tasks",taskConcurrentTrackingConflictFinishBtn:"Finish active tasks",taskConcurrentTrackingConflictParallelBtn:"Start in parallel (keep timers running)",taskConcurrentTrackingDontShowAgain:"Remember this choice and don’t show this dialog again (the same action will run automatically next time).",taskPlannedBoundaryConflictTitle:"Planned task is now live",taskPlannedBoundaryConflictMessage:"A task that was shown under Planned has reached its start time and now counts as running while another timer was already running. Choose what to do with the tasks that were already running: pause them (they move to the paused list), finish them (they move to completed), or keep them running alongside the new one.",taskPlannedBoundaryConflictResolveError:"Could not apply your choice for the running timers. Check the server and try again.",navDashboardPlannedConflictPulseHint:"Dashboard: review the timer conflict dialog",tasksPausedHeading:"Paused",tasksCompletedHeading:"Completed",tasksArchiveOpenHeading:"Unfinished (snapshot)",tasksRunningHeading:"Running now",tasksPlannedHeading:"Planned",tasksTimelineEmpty:"No timed task intervals in this session view.",tasksTimelineGanttOpenBtn:"Gantt",tasksTimelineGanttOpenBtnAria:"Open task timeline as a Gantt-style chart",tasksTimelineGanttTitle:"Task timeline (Gantt)",tasksTimelineGanttDescription:"Timeline aligned on the session start: one row per task; coloured bars are tracked timer intervals. Scroll horizontally when the session spans a long wall-clock range.",tasksTimelineGanttTodayTitle:"Today timeline (Gantt)",tasksTimelineGanttTodayDescription:"Global timeline for the current day: all task intervals across sessions are grouped in one view.",tasksTimelineGanttWindowStartLabel:"Timeline start",tasksTimelineGanttWindowEndLabel:"Timeline end",tasksTimelineGanttLegendWork:"Tracked time",tasksTimelineGanttLegendGap:"Outside this task’s interval",tasksTimelineGanttLegendProductive:"Productive (@ projects)",tasksTimelineGanttLegendPersonal:"Personal (! projects)",tasksTimelineGanttSummaryProductive:"Productive total: {duration}",tasksTimelineGanttSummaryPersonal:"Personal total: {duration}",tasksTimelineGanttCloseBtn:"Close",tasksTimelineGanttTooltipStart:"Start",tasksTimelineGanttTooltipEnd:"End",tasksTimelineGanttTooltipTimer:"Timer duration",tasksTimelineGanttTooltipWall:"Wall-clock span",tasksTimelineGanttTooltipTimerUnknown:"—",tasksTimelineGanttLapsPopoverAria:"Tracking laps for this task segment",ganttColorPickerAria:"Gantt bar color",ganttColorPickerAuto:"Automatic color",ganttColorPickerSwatch:"Color {color}",taskGanttColorLabel:"Gantt bar color",hideTaskList:"Hide list",showAllTasks:"Show full list",pauseTaskBtn:"Pause — moves to the paused list",resumeTaskBtn:"Resume tracking",taskTimerPausedManual:"Timer paused (manual).",pausedNote:"Session is paused because you are inspecting history.",viewingHistoryBannerTitle:"You are viewing a past session.",resumeBtn:"Resume active session",inspectingLabel:"Viewing session:",historyInspectBannerAria:"Past session view",liveSessionWallPausedBannerAria:"Live session paused",liveSessionWallPausedTitle:"Session tracking is paused",liveSessionWallPausedDetail:"Wall-clock time is frozen. Use Resume below or press play on a task — both restart session tracking.",liveSessionResumeWallBtn:"Resume session",autoTagsDetected:"Tags detected",autoProjectDetected:"Project",tagsHelpAriaLabel:"Tag help",tagSyntaxHelp:"#tag after a space or at the start, or glued (word#tag). @project uses the same placement; if you type several @projects, the last one wins (one project per task). Tokens: letters, numbers, -, _ (no spaces).",tagSuggestionsHelp:"Next to this (?), the small field applies a line like #tag, @project, or a plain tag name when you press Enter. Typing #tag in the title is separate.",tagsHelpWorkflowSummary:"Read-only labels above list every tag on the task; the project line shows its project. Edit the title or use the quick field (Enter). @Project#code is optional.",taskAppliedTagsHelpHeading:"Tags on this task",taskAppliedTagsHelpHint:"Everything merged from the title, the new-task field, and the quick line under each task. Type #tag, @project, or a tag name and press Enter; @ alone clears the project.",taskTagsExtraHelpAria:"Help: tags and project applied to this task",taskTagsOrphanProjectHelpBody:"From the title, not in your saved list. Pin under Tags & projects or change the title.",taskTagProjectQuickAddPlaceholder:"#tag, @project or label… Enter (@ alone clears project)",taskTagProjectQuickAddAria:"Quick add: type #tag, @project, or a tag name, then Enter",taskTagProjectMultiGroupTags:"Saved tags",taskTagProjectMultiGroupProjects:"Saved projects",taskTagProjectMultiOptionClearProject:"Clear project (same as @ alone)",taskTagProjectMultiSelectAria:"Multi-select saved tags and projects, then use Add selection",taskTagDefaultBucket:"default",taskTagProjectMultiHint:"Ctrl or ⌘-click to select several rows, then add.",taskTagProjectApplySelectionBtn:"Add selection",tagsUserGuideIntro:"This guide explains how task titles, saved shortcuts, and optional @project#code labels work together. You can ignore advanced features and keep only #tags plus one @project if you prefer.",tagsUserGuideBasicsTitle:"Basics: title tokens",tagsUserGuideBasicsBody:"In the task title you can mix plain text with:\n• #name — a global tag (letters, numbers, hyphen, underscore).\n• @Project — assigns the task to a project (if several @ appear, the last one wins — one project per task).\nTokens can appear after a space or glued to a word (word#tag). The dashboard shows merged tags under the task.",tagsUserGuideShortcutsTitle:"Quick field on each task",tagsUserGuideShortcutsBody:"In Settings → Tags & saved projects (or the Tags column on the right), you pin tags and projects you reuse. On a task, the narrow field next to the tag help (?) suggests those values; press Enter to apply a line (#tag, @project, plain name, or @ alone to clear the project). This does not rewrite the title unless you edit it yourself.",tagsUserGuideScopedTitle:"Optional: @project#code (project-scoped labels)",tagsUserGuideScopedBody:"Syntax @Client#invoice in the title stores a label tied to that project (shown as Client#invoice). Useful when the same local label means different things per client, or for stricter reporting. If you never need that, use #tag + @project only — the product supports both styles.",tagsUserGuideUseCasesTitle:"Use cases",tagsUserGuideUseCasesBody:"• Solo dev, one project: type My feature @acme and #frontend — no saved list required.\n• Many tickets: pin #triage, #bugfix, @sprint-42 in Tags & projects; use the quick field per task instead of retyping.\n• Client work: use @ClientA#retainer vs @ClientB#retainer in titles to keep namespaces separate; filter by project in reporting.\n• Retro entry: same # and @ rules in the past-task form; the quick field still accepts the same syntax.",tagsUserGuideFooterNote:"Descriptions on tags/projects (hover for a few seconds on a chip that has one) are optional notes for your team — they do not change how Kronosys filters data.",subtasksHeading:"Detail items",addSubtaskLinkBtn:"Add a detail item",addSubtaskPlaceholder:"New item…",addSubtaskBtn:"Add",subtaskMarkDone:"Mark this item done",subtaskMarkUndone:"Mark this item not done",subtaskDelete:"Remove this item",subtaskDragReorderHandle:"Drag to reorder",subtaskMoveUp:"Move this item up",subtaskMoveDown:"Move this item down",subtaskTimerStart:"Track time on this item",subtaskTimerStop:"Stop tracking time on this item",subtaskDurationNotMeasured:"Not measured",subtaskDurationNotRecorded:"Not recorded",subtaskDurationNotShown:"Not shown",subtaskDurationTooltipNotMeasured:"No time has been accumulated on this item yet. Use the play control to start tracking.",subtaskDurationTooltipNotRecorded:"This snapshot does not include a duration for this item (not tracked here or missing from the saved snapshot).",subtaskDurationTooltipNotShown:"No duration is shown for completed items without recorded time in this archived view.",noData:"No data yet.",sessionsColumnTitle:"Sessions",sessionsColumnHelpAria:"Help: Sessions column",sessionsColumnHelpBody:"Your saved sessions and the live session appear here while tracking is on.\n\nOpen the active session to edit tracking in real time.",dashboardColSessionTeaser:"Pick the session you’re in (or start one). The rest of the dashboard follows that choice.",dashboardColSessionFlowHint:"Next → Tasks in the middle",dashboardColTasksTeaser:"Log tasks, timers, and KronoFocus — all tied to the session on the left.",dashboardColTasksFlowHint:"Then → Tags & projects on the right",dashboardColTagsTeaser:"Add #tags, @projects, and shortcuts so history and reports stay clear.",dashboardColTagsFlowHint:"Optional, but your future self will notice.",dashboardColumnHintsPanelTitle:"How the three columns work",dashboardColumnHintsExpandAria:"Show how the three dashboard columns work",dashboardColumnHintsCollapseAria:"Hide the column guide",dashboardColumnHintsDismissTitle:"Hide this guide permanently",sessionsListAriaLabel:"Sessions",sessionLiveBadge:"Live",sessionListWallDurationTitle:"Wall-clock session duration: saved minutes when available, otherwise the span from session start to end.",sessionListWallDurationAlertTooltip:"At or past the alert threshold ({hours} h) — adjust under Settings → Web dashboard.",sessionListStartedPrefix:"Start:",sessionListEndedPrefix:"End:",sessionListOpenGanttAria:"Open Gantt timeline for this session",selectedSessionSidebarTimelineIconTooltip:"Gantt",selectedSessionSidebarTimelineIconAria:"Open the horizontal task timeline for this session",sessionEndLiveTitle:"End session — save to history without starting a new one (tracking can stay on)",sessionEndLiveAria:"End current session",sessionEndLiveConfirmTitle:"End this session?",sessionEndLiveConfirmIntro:"There is still open work in this session. Ending saves a snapshot to history: timers and item tracking will no longer run for this session, but you can still edit names, tags, and projects when you open the archived session.",sessionEndLiveConfirmIntroCalm:"Ending saves a snapshot to history with the current end time. Timers and item tracking will no longer run for this session, but you can still edit names, tags, and projects when you open the archived session.",sessionEndLiveWarnActiveTask:"Something is currently being tracked (in progress).",sessionEndLiveWarnPausedTasks:"One or more entries are paused or not finished.",sessionEndLiveWarnIncompleteSubtasks:"One or more items are not marked done.",sessionEndLiveTasksHandlingLegend:"When ending, what should happen to open tasks?",sessionEndLiveTasksHandlingKeep:"Leave tasks unfinished in this session’s snapshot — timers stop (recorded time is kept)",sessionEndLiveTasksHandlingFinish:"Finish open tasks with this session",sessionEndLiveTasksHandlingMoveToPaused:"Move open tasks to a new paused session",sessionEndLiveConfirmBtn:"End session",sessionEndLiveSidebarBtn:"End this session",sessionEndReasonModalHint:"Optional: record why you are closing the session (reports, timesheets, retrospectives).",sessionEndReasonFieldsetLegend:"Closure reason",sessionEndReasonSkip:"Do not save a category",sessionEndReasonPlanned:"Ended as planned (time or scope)",sessionEndReasonEarly:"Ended early (before planned time or deadline)",sessionEndReasonOverrun:"Overrun relative to plan",sessionEndReasonOther:"Other",sessionEndReasonNotePlaceholder:"Optional detail…",sessionEndReasonNoteAria:"Optional free-text detail for how this session ended",selectedSessionEndReasonTitle:"Closure",sessionEndReasonEditHint:"Update the saved closure category or detail for this session.",sessionEndReasonSaveBtn:"Save closure",sessionEndReasonSaveAria:"Save closure reason",sessionEndReasonSaving:"Saving…",beforeUnloadLiveSessionMessage:"A Kronosys session is open in this dashboard. Closing this tab does not end the session. Use “End this session” in the left column to close it here, or leave this tab — the session keeps running in the background.",openSessionInNewTab:"Open this session in a new tab",detachedSessionUrlHint:"This tab is driven by the URL. Inspecting an archive here only updates this tab — it does not change your live session or which session is selected in other open tabs.",detachedSessionUrlHintDismiss:"Hide this note",detachedSessionInvalidUrl:"No session matches this URL parameter.",tasksInSessionSingular:"item",tasksInSessionPlural:"items",rightColumnTitle:"Tasks",tagsProjectsColumnTitle:"Tags, projects & templates",tagsProjectsColumnIntro:"Pin shortcuts, descriptions, and hide chips — same as in Settings, here while you work. Use the two tabs to switch between global tags and projects.",tagsProjectsColumnHelpAria:"Help: tags & projects column",tagsProjectsColumnHelpBody:"Global tags apply to any task. Project-linked tags use Project#code and only appear when that task’s @project matches.\n\nIn this column, the Global tags tab lists shortcuts, hidden tags, and descriptions; the Projects & linked tags tab lists saved projects and per-project codes.\n\nThis column mirrors the Tags & saved projects section in Settings; changes sync immediately.\n\nUse the (?) next to task tags on a card for the full help and use cases.",tasksColumnSubtitle:"Running, planned (future start or end), paused, and completed for the selected session.",tasksColumnSubtitleHelpAria:"Help: what this column shows",taskFocusNoSessionTitle:"No active session",taskFocusNoSessionBody:"Start a session from the Sessions column on the left to track tasks here.",taskStartAutoSessionToast:"No active session — starting one now so your task can be tracked in this session.",selectedSessionSidebarTitle:"Selected session",selectedSessionSidebarTitleLive:"Active session",selectedSessionSidebarTitleIdle:"No active session",selectedSessionSidebarPausedBadgeGlobal:"Global pause",selectedSessionSidebarPausedBadgeSession:"Paused",dashboardPauseBackdropTitleGlobal:"Global pause is on",dashboardPauseBackdropDetailGlobal:"Tracking is frozen for this session, tasks, and subtasks. Resume from the global pause control in the top bar.",dashboardPauseBackdropAriaGlobal:"Dashboard: global pause is active",dashboardPauseBackdropTitleSession:"Session tracking is paused",dashboardPauseBackdropDetailSession:"Wall-clock time and affected timers are frozen. Resume from the banner above Tasks or the usual resume control.",dashboardPauseBackdropAriaSession:"Dashboard: session wall-clock pause is active",sessionNoteLabel:"Session note",sessionNotePlaceholder:"Add a free-form note for this session…",selectedSessionIdleHint:"Start a session from the Sessions column to record time, tracking, and metrics.",sessionDetailsModalTitle:"Session summary",sessionDetailsModalCloseAria:"Close session summary",sessionDetailsModalReopenBtn:"Session summary",statsMetricSessionDurationHelpAria:"Help: session duration",statsMetricSessionDurationHelpBody:"Wall-clock time from the first activity event recorded in this session until now (live session) or until the snapshot was saved (archived). Separate from active time, coding time, and tracking or item timers.",sessionRemainingDurationLabel:"Remaining duration",sessionRemainingDurationUndetermined:"Undetermined",sessionPlannedTotalDurationLabel:"Total planned duration",sessionPlannedTasksTotalLabel:"Planned total (tasks)",sessionListPlannedTotalPrefix:"planned",statsMetricCodingTimeHelpAria:"Help: coding time",statsMetricCodingTimeHelpBody:"Time accumulated while a productive (non-excluded) file is in the coding context: opened, saved, active editor change, or edits. Stops growing after about one minute without such signals. Independent of the tracking timer.",statsMetricActiveTimeHelpAria:"Help: active time",statsMetricActiveTimeHelpBody:"Time accumulated from workstation activity: edits, file open, selection changes, active editor changes, and window focus. Gaps longer than about three minutes are not counted. Often between coding time and session wall-clock.",statsMetricTasksHelpAria:"Help: task counts by status",statsMetricTasksHelpBody:"For the selected session: tasks with the tracking timer running (“Running now”), tasks whose start or end is still in the future (“Planned”), other tasks not marked done (“Paused”), and completed tasks whose end is not in the future. Matches the sections in the Tasks column.",statsTasksRowRunning:"Running (timer)",statsTasksRowPausedList:"Not done (list)",statsTasksRowCompleted:"Completed",statsTasksRowPlanned:"Planned (future)",gitRepoCardTitle:"Workspace Git repository",gitRepoNotARepo:"The first workspace folder is not a Git checkout (or Git is unavailable).",gitRepoCardHelpAria:"Help: workspace Git overview",gitRepoCardHelpBody:"Summary of the Git repository at the first workspace root: branch counts, commit counts, a short `git log --graph --all` view, and a sorted sample of tracked paths from `git ls-files`. Updated when the dashboard refreshes from the server.",gitRepoCurrentBranchLabel:"Current branch",gitRepoBranchesLocalLabel:"Local branches",gitRepoBranchesLocalHelpAria:"Help: local branches",gitRepoBranchesLocalHelpBody:"Number of local branch refs (`git branch --list`).",gitRepoBranchesRemoteLabel:"Remote branches",gitRepoBranchesRemoteHelpAria:"Help: remote branches",gitRepoBranchesRemoteHelpBody:"Number of remote-tracking branches (`git branch -r`), excluding the symbolic `*/HEAD` alias.",gitRepoCommitsHeadLabel:"Commits (HEAD)",gitRepoCommitsHeadHelpAria:"Help: commits on current branch",gitRepoCommitsHeadHelpBody:"Count of commits reachable from HEAD (`git rev-list --count HEAD`), i.e. the current branch history.",gitRepoCommitsAllLabel:"Commits (all refs)",gitRepoCommitsAllHelpAria:"Help: commits all refs",gitRepoCommitsAllHelpBody:"Count across all refs (`git rev-list --all --count`). Can be slower on huge repositories; shown as — if the command fails.",gitRepoStashesLabel:"Stashes",gitRepoStashesHelpAria:"Help: stash list",gitRepoStashesHelpBody:"Number of entries in `git stash list`.",gitRepoGraphTitle:"Recent graph",gitRepoGraphHelpAria:"Help: commit graph",gitRepoGraphHelpBody:"ASCII graph from `git log --graph --decorate --all` (last 40 commits). Useful to see how branches relate.",gitRepoGraphEmpty:"No graph lines returned.",gitRepoGraphPreviewNote:"Partial preview — last 40 commits only in this box.",gitRepoGraphOpenFullAria:"Open full commit graph in a new tab",gitRepoGraphOpenFullTitle:"Open full commit graph in a new browser tab",gitRepoGraphDetailDocTitle:"Git commit graph — Kronosys",gitRepoTreeTitle:"Tracked files (sample)",gitRepoTreeHelpAria:"Help: tracked paths sample",gitRepoTreeHelpBody:"Alphabetically sorted sample of paths from `git ls-files` (up to 300). Not the full tree; large repos may omit paths beyond the buffer limit.",gitRepoTreeEmpty:"No tracked paths in the sample.",gitRepoTreePreviewNote:"Partial preview — sample of up to 300 tracked paths.",gitRepoTreeOpenFullAria:"Open full tracked paths list in a new tab",gitRepoTreeOpenFullTitle:"Open full tracked paths list in a new browser tab",gitRepoTreeDetailDocTitle:"Tracked files — Kronosys",statsLocSectionTitle:"Lines & languages",statsLinesWrittenTotal:"Lines written",statsLinesWrittenHuman:"Human (est.)",statsLinesWrittenAi:"AI (est.)",statsLocByLanguageHeading:"Lines by language",statsCodingSignalsHeading:"Coding signals by language",statsMetricLinesWrittenHelpAria:"Help: lines written",statsMetricLinesWrittenHelpBody:"Net lines added from tracked edits (estimated from newlines in diffs). Single large inserts are partially capped. “Human” vs “AI” is a heuristic per edit: multi-range changes, more than ~6 net lines, or a single chunk with many characters and a newline often count as AI-style (agent or paste)—not exact attribution.",statsMetricLocByLanguageHelpAria:"Help: lines by language",statsMetricLocByLanguageHelpBody:"How many net lines were attributed to each language id in this session (same basis as “Lines written”).",statsMetricCodingSignalsHelpAria:"Help: coding signals",statsMetricCodingSignalsHelpBody:"Count of coding-context signals per language (file open, save, edit, active editor change, and heartbeats while recently editing).",sessionNameReadOnly:"Session name (read-only for this archive)",sessionArchiveBtn:"Archive",sessionArchiveTitle:"Hide this session from the list (restorable from Archives)",sessionRestoreBtn:"Restore",sessionDeleteBtn:"Delete",sessionDeleteTitle:"Delete session",sessionDeleteIntro:"This removes the session from your history. Choose what to do with its items.",sessionDeleteDiscardTasks:"Delete items with the session (discard them)",sessionDeleteMoveTasks:"Move items to another session first",sessionDeleteTargetLabel:"Target session",sessionDeleteTargetPlaceholder:"Select a session…",sessionDeleteConfirmBtn:"Delete session",sessionDeleteCancelBtn:"Cancel",archivesModalTitle:"Archived sessions",archivesEmpty:"No archived sessions.",archivesCloseBtn:"Close",archivedBadge:"Archived",sessionArchiveConfirm:"Archive this session?\n\n• Hidden from the list until you restore it from Archives.\n• Reporting omits unfinished entries and any entry with an unchecked item (totals, charts, time by project, linked KronoFocus).",sessionArchiveDontShowAgain:"Don’t show this warning again",storageBadgeLabelSqlite:"SQLite",storageBadgeTooltipSqlite:"Session history is stored in SQLite in your Kronosys data directory (local persistence driver in Settings).",storageBadgeLabelJson:"JSON",storageBadgeTooltipJson:"Session history uses JSON partition files (legacy local driver). You can switch to SQLite in Kronosys settings.",storageBadgeLabelMongo:"MongoDB",storageBadgeTooltipMongo:"MongoDB mirror is enabled and connected. You can push sessions from the list; local sessions still follow your persistence driver.",workspaceFoldersLabel:"Workspace roots",workspaceFoldersEmpty:"No workspace root is configured for this dashboard.",headerDisplayRegionTitle:"Display time zone {timeZone}; clock {clock}.",headerClockFormat24Short:"24 h",headerClockFormat12Short:"12 h (AM/PM)",headerWallClockAriaLabel:"Wall clock in display time zone {timeZone}: {datetime}.",gitIdentityBannerAria:"Git author not configured",gitIdentityBannerBody:"Set the Git author (name, email, optional forge username) for the line under the dashboard title. Use Set up here to enter them in a quick dialog — values stay local; you can change them anytime under Settings → Git identity.",gitIdentityBannerConfigure:"Set up here",gitIdentityBannerDismiss:"Hide this reminder",gitIdentityModalTitle:"Git author (quick setup)",gitIdentityModalIntro:"Enter at least one of the fields below. Nothing is sent to the cloud from this dialog — data stays in your local Kronosys store, like in Settings.\n\nYou can change or complete these values anytime under Settings → Git identity.",gitIdentityModalNeedOneField:"Fill at least one field (name, email, or forge username) before saving.",gitIdentityModalSaveError:"Could not save. Check the connection and try again.",gitIdentityModalFooter:"GitLab tokens, auto sync, and other advanced options remain under Settings in the Git identity section when you need them.",mongoSyncLocalLabel:"Local JSON",mongoSyncMongoLabel:"MongoDB",mongoSyncStatusAligned:"In sync",mongoSyncStatusUnknown:"Mongo count unavailable",mongoSyncStatusLocalAhead:"Drift — fewer documents in Mongo",mongoSyncStatusMongoAhead:"Drift — more documents in Mongo",mongoSyncHelpAriaLabel:"Help: MongoDB mirror vs local sessions",mongoSyncHelpBody:"Local JSON is the source of truth. Counts are unique sessions in your history files (including archived). MongoDB is updated only when you push a session or use Resync in settings — not on every save. Count mismatches usually mean some sessions were never pushed or extra documents exist in Mongo. The live session is counted locally after it is written to disk.",sessionMongoPushAriaLabel:"Push this session to MongoDB",sessionMongoPushSyncedTitle:"Up to date on MongoDB for this snapshot",sessionMongoPushDirtyTitle:"Session changed since last Mongo push — click to update",sessionMongoPushNeverTitle:"Not yet pushed to MongoDB — click to send",sessionMongoPushBusy:"Pushing…",sessionMongoPushFailedDisabled:"MongoDB is not enabled in settings.",sessionMongoPushFailedNotFound:"Session not found.",sessionMongoPushFailedMongo:"MongoDB rejected the write. Check the connection and logs.",sessionMongoPushFailedUri:"MongoDB connection is incomplete (URI or password).",dashboardLoadingAriaLabel:"Loading dashboard, please wait",dashboardLoadingMessage:"Fetching session data from the Kronosys server…",dashboardConnectionErrorAriaLabel:"Cannot reach the Kronosys server",dashboardConnectionErrorTitle:"Server not reachable",dashboardConnectionErrorBody:"Start the Kronosys app (for example `kronosys start` or `npm run dev`) and check that this browser tab can reach it. If you use a custom data folder, verify SQLite file permissions.",dashboardConnectionRetryLabel:"Try again",dashboardConnectionTechnicalDetailsLabel:"Technical details",dashboardSyncErrorBanner:"Could not refresh data from the server. Showing the last loaded state.",dataSearchTrigger:"Spotlight…",dataSearchPlaceholder:"Filter sessions, tasks, templates, projects, tags, dates, or duration (e.g. 12:55 <, 0:10 >)…",dataSearchPaletteAriaLabel:"Spotlight search",dataSearchTypePrompt:"Type to filter sessions, tasks, saved task templates, projects, and tags in this workspace. You can also use a calendar day or a full timestamp (e.g. 2026-01-15 14:30:00) or a recorded duration condition: minutes:seconds (or h:m:s) with < or >, e.g. 45:00 > or 1:0:0 <. Choosing a template fills the task draft.",dataSearchEmpty:"No matching sessions, tasks, or templates.",dataSearchFooter:"↑↓ to move \xb7 Enter to open \xb7 Esc to close",dataSearchKindSession:"Session",dataSearchKindTask:"Task",dataSearchKindTaskTemplate:"Task template",taskTemplateDatalistPrefix:"Template:",taskTitleTemplateSuggestAria:"Task templates and recurring titles",taskTokenSuggestTagsAria:"Suggested tags",taskTokenSuggestWorkProjectsAria:"Suggested work projects",taskTokenSuggestPersonalProjectsAria:"Suggested personal projects",dataSearchTaskDistinguishId:"ID: {id}",dataSearchTaskStopwatchLabel:"Timer",dataSearchTaskRecordedTimeLabel:"Logged",dataSearchSessionWallLabel:"Wall time",commandNewSession:"New session",commandRefresh:"Refresh dashboard",commandOpenReporting:"Open reporting",commandOpenSettings:"Open settings",commandOpenUserGuide:"Open user guide",commandFocusSessions:"Focus sessions column",commandFocusTasks:"Focus tasks column",commandFocusTags:"Focus tags & projects column",commandToggleTheme:"Toggle light / dark theme",commandToggleLang:"Switch interface language (EN / FR)",commandEndLiveSession:"End live session",commandToggleFocusMode:"Toggle dashboard focus mode (columns only)",dashboardFocusModeEnterTitle:"Focus mode — sessions, tasks and tags only",dashboardFocusModeEnterAria:"Enter dashboard focus mode",dashboardFocusModeExitTitle:"Exit focus mode",dashboardFocusModeExitAria:"Exit dashboard focus mode",dashboardFocusModeExitHint:"Esc",shortcutsModalTitle:"Keyboard shortcuts",shortcutsModalCloseAriaLabel:"Close keyboard shortcuts",shortcutsModalIntro:"Click \xab Change \xbb, then press the new shortcut (must include Ctrl, Alt, Shift, or Meta). Escape cancels recording. Ctrl+K / ⌘K is reserved for quick data search (not editable here).",shortcutsTableAction:"Action",shortcutsTableShortcut:"Shortcut",shortcutsTableAssign:"Assign",shortcutsChangeBtn:"Change…",shortcutsRecordPrompt:"Press keys…",shortcutsResetAll:"Reset all to defaults",shortcutsPaletteRow:"Spotlight search — Ctrl+K or ⌘K (fixed)",tourProgressLabel:"Step {n} of {total}",tourStep1Title:"Welcome to the Kronosys dashboard",tourStep1Body:"This dashboard loads live session data from this web app (Next.js API routes and local SQLite) — not a static snapshot.",tourStep2Title:"Three-column guide (above the board)",tourStep2Body:"This strip sits just under the header and explains how **Sessions**, **Tasks**, and **Tags & projects** fit together — left to right on a wide screen, stacked on a narrow one, with arrows between the ideas.\n\nOpen or fold it with the chevron; each cell is a short teaser before you dive into the real columns below. **Use the X** to dismiss the whole strip for this browser; turn it back on under **Settings → Dashboard & API → Three-column guide**. Folded and dismissed states are remembered separately.",tourStep3Title:"Sessions (left column)",tourStep3Body:"Browse your session history, start a new session, and inspect the selected session’s duration, coding time, and stats.\n\nWhen a live session is open, you can end it from here; archived sessions open in read-only mode.\n\nFor advanced timing, open Settings (gear): under Dashboard & API, set the **session duration alert** (when a long wall-clock session is highlighted in this column). The **Work schedule** section starts and stops tracking on your weekday hours, and **Specific planned sessions** define recurring blocks that override the general schedule during their time window.",tourStep4Title:"Tasks & focus (center)",tourStep4Body:"Track what you are working on, finish tasks, and use subtasks or Git-linked options when you need them.\n\nThis column follows the session you select in the Sessions column — the rest of the header aligns with that choice.\n\nYou only track one work stream at a time on other parents: starting subtask time on a task also runs that parent’s main stopwatch, and it stops time on other tasks (their segments are saved). If you pause the main stopwatch, any subtask segment in progress on the same task stops and records time. Resuming a parent’s main stopwatch anywhere ends subtask timers on the other tasks and pauses their main stopwatches.\n\nDetail items are optional. The task’s total time is always at least the sum of time on those items; the rest is work recorded on the task without a per-item breakdown.\n\nOn a running, paused, or completed task, **Save as template** stores its title, #tags, and @project so you can reuse them later — the new-task field suggests them with a **Template:** prefix and the Ctrl+K / ⌘K palette lists them too. You can also **adjust task time bounds** by keeping the recorded duration, entering a manual h/m/s value, or recalculating from start and end.",tourStep5Title:"Tags & projects (right)",tourStep5Body:"Pin tags, manage saved projects, and add descriptions — the same controls as in Settings, available while you work. Two tabs separate global tags from projects and project-linked tags.\n\nIn task titles you can use @project and #tags (including @project#code) to organise work across projects.\n\nReporting (charts) depends heavily on these objects: consistent tags and projects make breakdowns, filters, and trends in Reporting far more meaningful.",tourStep6Title:"Top toolbar: every icon",tourStep6Body:"From left to right in this cluster: quick data search / command palette (same as Ctrl+K or ⌘K — sessions, tasks, **task templates**, projects, and tags), the keyboard icon for shortcut help and custom bindings, route icons for Dashboard, Reporting (charts), Settings (gear), User Guide (book), and **Implementation** (code file — exhaustive ✓ / ✗ list of user stories), the **Today Gantt** button (task intervals across all sessions of the current day), the **global pause** toggle, the light/dark theme toggle, refresh data from the API without reloading the whole browser tab, and the language menu (FR / EN).\n\nThe global pause stays inactive when nothing is running. Otherwise it opens a confirmation modal with a summary (start, end or *ongoing*, wall duration, coding/active session times when the host records them, task and subtask counts, total recorded task-timer time, plus the split between main task time and subtask timers) before pausing the session, its tasks, and any active subtasks; the next click resumes only that paused set.\n\nEach control has a tooltip on hover; route icons keep you in the same Kronosys shell.",tourStep7Title:"Your Git identity & storage badge",tourStep7Body:"This area shows your Git author line and forge account when they are configured in Settings → Git identity, the workspace roots detected for metrics, and a small badge for how session data is stored here: SQLite (default), JSON driver, or MongoDB mirror when enabled.\n\nSQLite keeps the dashboard payload on this machine under your Kronosys data directory; this page reads and writes it through the local API.",tourStep8Title:"What is KronoFocus?",tourStep8Body:"**KronoFocus** paces your session with a configurable work segment, short breaks, then a long break after several cycles. It is built into Kronosys (counts, phases, how it ties to the session) and is not limited to a fixed Pomodoro-style recipe.\n\nThe header toolbar always includes KronoFocus so navigation stays aligned on every page. Whether you also show it next to task actions is configured under Settings → Dashboard & API (KronoFocus).",tourStep8LearnMoreUrl:"https://en.wikipedia.org/wiki/Time_management",tourStep8LearnMoreLabel:"Further reading — time management (new tab)",tourStep8LearnMoreAriaLabel:"Opens the English Wikipedia article on time management in a new tab",tourStep9Title:"Git identity: your first follow-up after the tour",tourStep9Body:"This panel appears when your Git name, email, or forge account is still empty. Use Set up here to fill a short form without leaving the dashboard — that is the recommended first action once you finish the tour. You can use Hide this reminder if you prefer to postpone.",tourSkipBtn:"Skip tour",tourBackBtn:"Back",tourNextBtn:"Next",tourDoneBtn:"Done",settingsTourProgressLabel:"Step {n} of {total}",settingsTourStep1Title:"Settings & Options",settingsTourStep1Body:"Some advanced options are only available here in the settings, not on the dashboard. This tour highlights key configurations for your workspace.",settingsTourStep2Title:"Usage Profile",settingsTourStep2Body:"Switch between 'Manager' and 'Developer' modes to adjust the level of detail in the dashboard and the frequency of notifications.",settingsTourStep3Title:"Persistence & Drivers",settingsTourStep3Body:"Choose between SQLite (recommended) and legacy JSON for your local history storage. You can also configure a MongoDB mirror for cloud backup.",settingsTourStep4Title:"Git & GitLab Integration",settingsTourStep4Body:"Configure your Git identity and GitLab API token to enable issue importing and commit message generation.",settingsTourStep5Title:"Reporting & Exclusions",settingsTourStep5Body:"Define which directories and file patterns should be excluded from line counting and time tracking to keep your reports clean.",settingsTourStep6Title:"Schedules & Automation",settingsTourStep6Body:"Set up recurring work hours and planned sessions to automatically start tracking or transfer tasks at specific times.",settingsTourSkipBtn:"Skip tour",settingsTourBackBtn:"Back",settingsTourNextBtn:"Next",settingsTourDoneBtn:"Done",tourUndismissBtn:"Relaunch tour",reportingTourProgressLabel:"Reporting tour — step {n} of {total}",reportingTourStep1Title:"Welcome to Kronosys Reporting",reportingTourStep1Body:"This page aggregates your Kronosys history from the local API. Use it to review sessions, recorded task time, KronoFocus usage, and — when filters allow — per-tag and per-project splits.",reportingTourStep2Title:"Filters",reportingTourStep2Body:"Pick a date range (or use Day / Week / Month / Year presets), optionally narrow by #tags, then reset when you want the full picture again. Green badges warn when live data or unfinished tasks still affect the totals.",reportingTourStep3Title:"Summary KPIs",reportingTourStep3Body:"These cards condense the same window as the charts: session counts, task rows, KronoFocus stats, and recorded minutes. The (?) icons open short metric definitions without cluttering the layout.",reportingTourStep4Title:"Daily charts",reportingTourStep4Body:"Bar views show sessions, tasks by status, recorded task time, and session wall-clock by calendar day. When several weeks exist, use the week strip to align charts and tag calendars.",reportingTourStep5aTitle:"Time by tag",reportingTourStep5aBody:"Review recorded task minutes grouped by #tags (including the untagged bucket when it applies), with weekly grids when data spans multiple days.",reportingTourStep5bTitle:"Time by project (Work vs Personal)",reportingTourStep5bBody:"The weekly-by-project grid has a Work (@) / Personal (!) toggle under the section title: Work (default) excludes personal-ledger minutes; Personal shows only that ledger (including tasks inferred from a ! token in the title when the saved flag is missing). Tag totals above still mix both ledgers unless you filter by tags.",reportingTourStep6Title:"Outline and two-column layout",reportingTourStep6Body:"This block is the main Reporting layout: your content on the left and, on wide screens, a sticky jump list on the right. On phones, the same anchors appear as chips above the filters.",newSessionModalTitle:"New session — scope",newSessionModalHelpAria:"Help: session start and scope (duration, dates, weekdays)",newSessionModalHelpBody:"Choose whether the session starts now or with a backdated start. Enter **both start and end** (local browser time) for a **past** start. For **Now**, you can optionally set a **scheduled end** — the session closes automatically at that time (same as setting an end on a live session later). If the end is still **ahead** on a backdated start, Kronosys opens a **live** session from that start and **closes it automatically** at the scheduled end; if the end is **already past**, the closed interval is stored as a history row. Starting now while a session is already live opens the end-session dialog first; a **fully past** backdated row leaves the current session running and adds a history row you can switch to. Then these scope options set expectations for this session only. They do not stop Kronosys automatically: you get reminders from the collector (heartbeat) and a banner here when you are close to or outside the limits.\n\n• Maximum wall-clock duration — counted from the first tracked event in the session.\n\n• Calendar period — local dates inclusive (start and/or end).\n\n• Weekdays — restrict to selected days; you can add a daily time window (local 24 h). Overnight windows are supported (e.g. 22:00–06:00).",newSessionTimingSectionTitle:"Session start",newSessionTimingImmediate:"Now (start immediately)",newSessionTimingPast:"In the past (backdated start)",newSessionPastStartLabel:"Session started at (local)",newSessionPastStartHint:"Uses your browser’s local timezone. The session wall clock starts from this instant; you can still add tasks and adjust times afterward.",newSessionPastEndLabel:"Session ends at (local)",newSessionPastEndHint:"Must be after the start. If the end is still ahead, this opens a live session and closes it automatically at that time; if the end is already past, the closed interval is stored in history.",newSessionImmediateEndLabel:"Scheduled end (optional, local)",newSessionImmediateEndHint:"Leave empty for no automatic end. If set, the session must end in the future — it closes automatically at that time.",newSessionScopeFieldsetLegend:"Scope (reminders)",newSessionModeNone:"No limit",newSessionModeMax:"Maximum wall-clock duration",newSessionModeCalendar:"Calendar period (dates)",newSessionModeWeekly:"Weekdays (optional daily hours)",newSessionMaxHoursLabel:"Max duration (hours)",newSessionDateFromLabel:"From (date)",newSessionDateToLabel:"To (date)",newSessionTodayBtn:"Today",newSessionWeekdaysLegend:"Active weekdays",newSessionQuickWeekdays:"Weekdays",newSessionQuickWeekends:"Weekends",newSessionQuickAll:"All days",newSessionTimeFromLabel:"Daily from",newSessionTimeToLabel:"Daily to",newSessionNowBtn:"Now",newSessionUseTimeWindow:"Restrict to a daily time window on those days",newSessionUseTimeWindowHelpAria:"Help: daily time window",newSessionUseTimeWindowHelpBody:"When enabled, the session only tracks time within the specified daily window on the selected weekdays. Outside this window, the session is considered paused. Supports overnight windows (e.g. 22:00–06:00).",newSessionErrorMax:"Enter a maximum duration between 0.1 and 8760 hours.",newSessionErrorCalendar:"Choose at least one date (from and/or to).",newSessionErrorWeekly:"Select at least one weekday.",newSessionErrorPastMissing:"Enter the start date and time for a backdated session.",newSessionErrorPastEndMissing:"Enter the end date and time for a backdated session.",newSessionErrorPastEndBeforeStart:"The end must be strictly after the start.",newSessionErrorPastFuture:"Pick a date and time in the past or now (not in the future).",newSessionErrorPastInvalid:"Unrecognized date or time.",newSessionErrorImmediateEndNotFuture:"The scheduled end must be in the future (at least about one minute ahead).",newSessionStartBtn:"Start session",newSessionCancelBtn:"Cancel",sessionScopeNoticeAria:"Session scope reminder",appShellRouteNavAria:"Main sections",appShellRouteNavTodayGantt:"Open today timeline (Gantt)",appShellRouteNavGlobalPause:"Pause session, tasks, and subtasks in this context",appShellRouteNavGlobalResume:"Resume everything paused by global pause in this context",appShellRouteNavGlobalPauseDisabledTooltip:"Nothing is active to pause: the session wall clock is already paused and no task or subtask timer is running.",appShellRouteNavGanttDashboardOnlyTooltip:"Today’s Gantt is available from the dashboard only.",appShellRouteNavGlobalPauseDashboardOnlyTooltip:"Global pause is available from the dashboard when a live session is loaded.",appShellRouteNavGlobalPauseNoSessionContextTooltip:"Global pause is not available while you inspect an archived session or before the live session is loaded.",appShellRouteNavChangelogUnavailableTooltip:"Changelog shortcut is hidden on this screen (no label).",appShellRouteNavImplementationUnavailableTooltip:"Implementation shortcut is hidden on this screen (no label).",appShellHeaderKronoFocusLoadingAria:"KronoFocus — waiting for session data",appShellRouteNavGroupAppAria:"Main app areas",appShellRouteNavGroupDocsAria:"Help and reference",appShellRouteNavGroupToolsAria:"In-session tools",appShellRouteNavGroupLegalAria:"Legal information",appShellRouteNavDataEnvironmentGroupAria:"Production or QA data store",dataEnvironmentNavGroupHint:"Switch between production data and an isolated QA sandbox",dataEnvironmentNavActiveLabel:"Active",dataEnvironmentNavActiveProd:"Production",dataEnvironmentNavActiveQa:"QA",dataEnvironmentNavPendingRestart:"After restart: {env}",dataEnvironmentNavEnableQaShort:"QA",dataEnvironmentNavEnableQaTitle:"Enable a separate QA data store (v4-qa) alongside production",dataEnvironmentNavSettingsLink:"Settings",dataEnvironmentDualEnabledHint:"QA store enabled. Use Prod / QA to switch, then restart the Kronosys server.",dataEnvironmentNavTraceOverrideShort:"Custom path",dataEnvironmentNavTraceOverrideAria:"TRACE_DATA_DIR is set; production and QA vault switching is disabled",dataEnvironmentNavProdShort:"Prod",dataEnvironmentNavQaShort:"QA",dataEnvironmentNavProdTitle:"Production data (your real sessions and tasks)",dataEnvironmentNavQaTitle:"QA data (isolated copy for tests and reproducing issues)",dataEnvironmentQaBanner:"QA environment — data here is separate from production. Do not use this screen for real work.",dataEnvironmentSwitchRestartHint:"Data store preference saved. Restart the Kronosys server (stop and start `kronosys` or your dev server) to open the selected environment.",dataEnvironmentSwitchSuccessHint:"Switched to the {env} data store.",dataEnvironmentSwitchError:"Could not switch the data environment.",dataEnvironmentSwitchDisabled:"Enable dual environments in Settings → General first.",dataEnvironmentSwitchConfirmTitle:"Switch data store",dataEnvironmentSwitchConfirmMessage:"You are about to switch to the {env} data store.\n\nAfter you confirm, Kronosys will reopen the selected SQLite file immediately.",dataEnvironmentSwitchConfirmBtn:"Switch",dataEnvironmentSwitchLockBackdropTitleSwitching:"Switching data store…",dataEnvironmentSwitchLockBackdropDetailSwitching:"Please wait while the preference is saved.",dataEnvironmentSwitchLockBackdropAriaSwitching:"Application locked: data store switch in progress",dataEnvironmentSwitchLockBackdropTitleLocked:"Restart required",dataEnvironmentSwitchLockBackdropDetailLocked:"The data store preference was saved. Restart the Kronosys server to continue. The interface stays locked until then.",dataEnvironmentSwitchLockBackdropAriaLocked:"Application locked: restart the Kronosys server to apply the data store",dataEnvironmentQaSeedTitle:"Set up the QA data store",dataEnvironmentQaSeedMessage:"This is your first switch to the QA store. Choose how to initialize it:\n\n• Copy production — duplicate your current sessions and tasks into QA (production data is not modified).\n• Start empty — an isolated empty store for tests and experiments.",dataEnvironmentQaSeedCopyBtn:"Copy production data",dataEnvironmentQaSeedEmptyBtn:"Start empty",dataEnvironmentQaSeedRequiredError:"Choose whether to copy production data or start with an empty QA store.",dataEnvironmentQaSeedProductionMissingError:"Production has no data file yet; choose “Start empty” or add data in production first.",appShellUtilityToolbarGroupAria:"Display and language",globalPauseConfirmTitle:"Global pause",globalPauseConfirmIntro:"Global pause freezes the session wall clock when it is running, pauses each task timer that is not already paused, and stops any active subtask timer (recording elapsed time). The next click on this control resumes only what was paused in this operation.\n\nReview what will be affected:",globalPauseConfirmSessionHeading:"Session",globalPauseConfirmSummaryHeading:"Summary",globalPauseConfirmSummaryStart:"Start",globalPauseConfirmSummaryEnd:"End",globalPauseConfirmSummaryEndOngoing:"Ongoing (no end yet)",globalPauseConfirmSummaryWallDuration:"Wall duration",globalPauseConfirmSummaryTasks:"Tasks",globalPauseConfirmSummarySubtasks:"Subtasks",globalPauseConfirmSummaryMainTimer:"Task timers (excl. subtasks)",globalPauseConfirmSummarySubtaskTimers:"Subtask timers",globalPauseConfirmSummaryCodingSession:"Session coding time",globalPauseConfirmSummaryActiveSession:"Session active time",globalPauseConfirmSummaryTaskTimersTotal:"Total recorded (task timers)",globalPauseConfirmSummaryUnknownInstant:"—",globalPauseConfirmSessionWallWillPause:"Wall-clock time for this session will pause.",globalPauseConfirmSessionWallAlreadyPaused:"The session wall clock is already paused; it stays frozen.",globalPauseConfirmTasksHeading:"Tasks and subtasks",globalPauseConfirmNoTaskEffects:"No task or subtask timers need freezing in the current state.",globalPauseConfirmEffectMainTimer:"Main task timer will pause.",globalPauseConfirmEffectSubtaskStop:"Subtask timer stops — \xab {title} \xbb.",globalPauseConfirmConfirmBtn:"Pause now",appShellLiveDrawerAria:"Live session activity",appShellLiveDrawerTitle:"In progress",appShellLiveDrawerOpenDashboard:"Open dashboard",appShellLiveDrawerSessionPaused:"Session paused",appShellLiveDrawerWallClock:"Wall time",appShellLiveDrawerTasksHeading:"Timers",appShellLiveDrawerKronoFocusRunning:"Running",appShellLiveDrawerKronoFocusPaused:"Paused",appShellLiveDrawerKronoFocusPhaseWork:"Work",appShellLiveDrawerSubtaskTracking:"Subtask",appShellLiveDrawerExpand:"Expand panel",appShellLiveDrawerCollapse:"Collapse panel",appShellLiveDrawerNoRunningTasks:"No task timers running.",dashboardSideDrawerSessionsAria:"Sessions panel",dashboardSideDrawerTagsAria:"Tags and projects panel",dashboardTaskLauncherDrawerAria:"Task entry launcher",dashboardTaskLauncherDrawerExpand:"Expand task launcher",dashboardTaskLauncherDrawerCollapse:"Collapse task launcher",brandTagline:"The relativity of productive time",appVersionAriaLabel:"Kronosys dashboard package version {version}.",dialogOkBtn:"OK",dialogCancelBtn:"Cancel",dialogConfirmBtn:"Confirm",pageRefreshTitle:"Refresh data",pageRefreshAriaLabel:"Reload data for this page without a full browser refresh",pageRefreshProgressLabel:"Syncing with the Kronosys server…",pageRefreshDoneToast:"Data reloaded from the Kronosys server.",pageRefreshFailedToast:"Could not reload data. Check that the Kronosys server is running and try again."},e={kronoFocusTitle:"KronoFocus",workMode:"KronoFocus",breakMode:"Pause courte",longBreakMode:"Pause longue",kronoFocusStart:"D\xe9marrer",kronoFocusPause:"Pause",kronoFocusReset:"R\xe9initialiser",kronoFocusControlsReadOnlyTooltip:"Lecture seule pendant l’inspection d’une archive — ces commandes s’appliquent \xe0 la session en cours.",kronoFocusLinkedTaskIntro:"Lanc\xe9 depuis :",kronoFocusEditDurationTitle:"Configurer le rythme KronoFocus (minuteur non d\xe9marr\xe9)",kronoFocusDurationPickerLabel:"Dur\xe9e (heures : minutes : secondes)",kronoFocusApplyDuration:"Appliquer",kronoFocusCancelDurationEdit:"Annuler",kronoFocusDurationHelpAriaLabel:"Aide sur la dur\xe9e",kronoFocusDurationHelpBody:"Indiquez la dur\xe9e du segment de travail en heures, minutes et secondes (temps \xe9coul\xe9, ex. 00:25:00 ou 01:30:00 — pas une heure du jour). Vous pouvez omettre les secondes (ex. 0:25). Plage : 1 min \xe0 8 h. Les pauses courte et longue se r\xe8glent en minutes enti\xe8res dans la m\xeame bo\xeete. R\xe9glez tout avant de d\xe9marrer KronoFocus.",kronoFocusDurationInputPlaceholder:"00:25:00",kronoFocusDefaultWorkDuration:"D\xe9faut — 00:25:00",kronoFocusDurationHistoryLabel:"Dur\xe9es r\xe9centes",kronoFocusDurationHistoryPickAria:"Choisir la dur\xe9e {time}",kronoFocusDurationHistoryClear:"Effacer",kronoFocusDurationHistoryClearTitle:"Effacer toutes les dur\xe9es personnalis\xe9es enregistr\xe9es",kronoFocusRhythmPresetsHeading:"Pr\xe9r\xe9glages (travail / pause courte / pause longue)",kronoFocusRhythmPresetLabels:["25 / 5","50 / 10","45 / 15","52 / 17"],kronoFocusRhythmPresetTitles:["25 min de travail, 5 min de pause courte, 15 min de pause longue apr\xe8s chaque 4e segment de travail","50 min de travail, 10 min de pause courte, 20 min de pause longue apr\xe8s chaque 4e segment de travail","45 min de travail, 15 min de pause courte, 15 min de pause longue apr\xe8s chaque 4e segment de travail","52 min de travail, 17 min de pause courte, 30 min de pause longue apr\xe8s chaque 4e segment de travail"],kronoFocusShortBreakMinutesLabel:"Pause courte (minutes)",kronoFocusLongBreakMinutesLabel:"Pause longue (minutes)",kronoFocusRhythmBreaksMinutesHint:"Minutes enti\xe8res, 1 \xe0 480 chacune. La pause longue suit chaque 4e segment de travail termin\xe9.",startTaskWithKronoFocus:"Lancer aussi KronoFocus",startTaskWithKronoFocusToggleAriaOff:"Lancer aussi KronoFocus au d\xe9marrage — d\xe9sactiv\xe9. Appuyer pour activer.",startTaskWithKronoFocusToggleAriaOn:"Lancer aussi KronoFocus au d\xe9marrage — activ\xe9. Appuyer pour d\xe9sactiver.",startKronoFocusFromActiveTask:"D\xe9marrer KronoFocus",startKronoFocusFromTaskConfirm:"KronoFocus est d\xe9j\xe0 en cours ou en pause. R\xe9initialiser le minuteur et d\xe9marrer un nouveau segment de travail ?",launcherTitle:"T\xe2ches",taskPlaceholder:"Sur quoi travaillez-vous ?",taskNoteLabel:"Note de t\xe2che",taskNoteAddBtn:"Ajouter une note",taskNotePlaceholder:"Ajouter une note libre pour cette t\xe2che…",taskNoteEditHint:"Cliquer pour modifier la note (Markdown accept\xe9)",taskMarkdownHelpAriaLabel:"Aide Markdown pour les notes de t\xe2che",taskMarkdownHelpIntro:"Sur la carte ou au lanceur, **Ajouter une note** ouvre le champ ; une fois enregistr\xe9e, la note est interpr\xe9t\xe9e en Markdown (sous-ensemble GFM, compatible GitLab/GitHub). Le titre accepte du Markdown inline en lecture seule.",taskMarkdownHelpNoteHeading:"Note (bloc)",taskMarkdownHelpTitleHeading:"Titre (inline en lecture)",taskMarkdownHelpSecurity:"Pas de HTML brut ; les liens externes s’ouvrent dans un nouvel onglet.",taskMarkdownHelpGfmLimits:"Pris en charge : gras, italique, barr\xe9, listes, cases \xe0 cocher, tableaux, autolinks, images (http/https). Hors scope : Mermaid, formules, @mentions/#issues GitLab, blocs d’alerte, raccourcis emoji.",taskPlaceholderPast:"Sur quoi avez-vous travaill\xe9 ?",archiveAddTaskIntro:"Entr\xe9e pass\xe9e : ouvrez la modale de plage horaire pour le d\xe9but et la fin (la fin est pr\xe9remplie au d\xe9but plus la dur\xe9e minimale des param\xe8tres). Ajustez la dur\xe9e du minuteur (h/m/s) si besoin. \xc9tiquettes et @projet comme d’habitude ; pas de minuteur live ni de points de d\xe9tail — session en cours ou archiv\xe9e.",archiveAddTaskIntroHelpAria:"Aide : saisie d’une entr\xe9e pass\xe9e",taskEntryModeRealtime:"Temps r\xe9el",taskEntryModePast:"Pass\xe9/planifi\xe9",taskEntryModeGroupAria:"Mode de saisie",archiveTaskStartLabel:"D\xe9but",archiveTaskEndLabel:"Fin",taskTimingDurationLabel:"Dur\xe9e",taskTimingAdjustModalTitle:"Ajuster la dur\xe9e ?",taskTimingAdjustModalMessage:"Vous avez modifi\xe9 l’horaire de la t\xe2che. Choisissez comment recalculer la dur\xe9e.",taskTimingAdjustKeepDuration:"Conserver la dur\xe9e du minuteur enregistr\xe9e",taskTimingAdjustManualDuration:"D\xe9finir la dur\xe9e manuellement (h/m/s)",taskTimingAdjustFromBounds:"D\xe9finir la dur\xe9e selon d\xe9but/fin",taskTimingAdjustHours:"Heures",taskTimingAdjustMinutes:"Minutes",taskTimingAdjustSeconds:"Secondes",taskTimingAdjustLapSectionTitle:"Tour de minuteur en cours (lap n\xb0{n})",taskTimingAdjustLapKeep:"Conserver ce tour tel quel (horodatage du lap inchang\xe9)",taskTimingAdjustLapFlush:"Cl\xf4turer ce tour maintenant (l’enregistrer comme lap termin\xe9)",taskTimingAdjustLapAlignStart:"R\xe9aligner ce tour sur le nouveau d\xe9but de t\xe2che",taskTimingAdjustModalMessageRunning:"Vous avez modifi\xe9 le d\xe9but alors qu’un tour de minuteur est en cours. Indiquez quoi faire de ce tour et comment recalculer la dur\xe9e totale.",taskTimerLapsHeading:"Laps de suivi",taskTimerLapDeleteBtn:"Supprimer le lap",taskTimerLapDeleteConfirmTitle:"Supprimer ce lap ?",taskTimerLapDeleteConfirmMessage:"Le lap est retir\xe9 de la liste et sa dur\xe9e est soustraite du total du minuteur de la t\xe2che.",taskTimerLapRunningLabel:"en cours…",taskStartTimeSaveAria:"Enregistrer l'heure de d\xe9but corrig\xe9e de la t\xe2che",sessionStartTimeSaveAria:"Enregistrer l'heure de d\xe9but corrig\xe9e de la session",taskEndTimeSaveAria:"Enregistrer l'heure de fin corrig\xe9e de la t\xe2che",sessionEndTimeSaveAria:"Enregistrer l'heure de fin corrig\xe9e de la session",sessionEndTimeEditSectionTitle:"Fin de session",sessionStartTimeEditSectionTitle:"D\xe9but de session",taskPastDatetimePlaceholder:"yy-mm-dd --:--:--",taskPastDatetimeTimeLabel:"Heure",taskPastDatetimeHourAria:"Heure (format 24 h)",taskPastDatetimeMinuteAria:"Minutes",taskPastDatetimeTodayBtn:"Aujourd’hui",taskPastDatetimeNowBtn:"Maintenant",archiveAddTaskBtn:"Ajouter \xe0 la session",archiveTaskDatetimeRangeInvalid:"Indiquez un d\xe9but et une fin valides ; la fin doit \xeatre post\xe9rieure au d\xe9but (date et heure locales).",archiveTaskTimerDurationLabel:"Dur\xe9e du minuteur",pastTaskTimingModalTitle:"Entr\xe9e pass\xe9e — plage horaire",pastTaskTimingEditBtn:"R\xe9gler d\xe9but, fin et dur\xe9e…",pastTaskTimingSummaryAria:"Modifier le d\xe9but, la fin et la dur\xe9e du minuteur pour l’entr\xe9e pass\xe9e",pastTaskTimingModalConfirm:"OK",pastTaskTimingModalCancel:"Annuler",pastTaskTimingEndOptional:"facultatif",archiveTaskManualDurationInvalid:"Indiquez une dur\xe9e de minuteur sup\xe9rieure \xe0 z\xe9ro et au plus \xe9gale \xe0 l’intervalle entre le d\xe9but et la fin.",activeTaskTitleEditHint:"Cliquer pour modifier le titre ; saisir #\xe9tiquettes dans le champ ou utiliser la ligne du bas",activeTaskTitleInputAria:"Modifier le titre ; #\xe9tiquettes ou @projet optionnels dans le champ, pastilles en dessous pour l’existant",taskStartBlockedByPlannedBoundaryConflict:"Fermez d’abord la bo\xeete de conflit de minuteurs (t\xe2che planifi\xe9e), puis lancez une autre t\xe2che.",plannedTaskScheduleActivatedToast:"La t\xe2che planifi\xe9e \xab {name} \xbb est maintenant au minuteur.",plannedTaskScheduleActivatedToastUnnamed:"T\xe2che sans titre",plannedSessionScheduleActivatedToast:"La session planifi\xe9e \xab {name} \xbb a atteint son heure de d\xe9but.",plannedSessionScheduleActivatedToastUnnamed:"Session sans titre",startTaskBtn:"D\xe9marrer le suivi",taskSaveTemplateBtn:"Sauvegarder comme template",taskAlreadyTemplateBtn:"D\xe9j\xe0 enregistr\xe9 comme template",taskTemplateSavedToast:"Template de t\xe2che sauvegard\xe9.",finishTaskBtn:"Terminer",finishTaskOpenSubtasksWarnTitle:"Terminer la t\xe2che ?",finishTaskOpenSubtasksWarnBody:"Il reste des points de d\xe9tail non coch\xe9s. Ils seront tous marqu\xe9s comme termin\xe9s lorsque vous terminez la t\xe2che.",reopenTaskBtn:"Rouvrir",reopenTaskModalTitle:"Rouvrir cette t\xe2che ?",reopenTaskModalMessage:"La t\xe2che redevient active. Choisissez comment g\xe9rer la dur\xe9e enregistr\xe9e du minuteur.",reopenTaskTimerResume:"Reprendre le minuteur (conserver la dur\xe9e)",reopenTaskTimerPaused:"Rouvrir en pause (conserver la dur\xe9e)",reopenTaskTimerManual:"D\xe9finir la dur\xe9e manuellement (h/m/s)",reopenTaskTimerReset:"Remettre le minuteur \xe0 z\xe9ro",reopenTaskSubtasksNote:"Les points de d\xe9tail seront aussi rouverts.",reopenTaskEndedSessionHint:"Session cl\xf4tur\xe9e — le minuteur ne peut pas repartir en direct ; les choix de dur\xe9e s’appliquent \xe0 l’instantan\xe9.",taskDeleteBtn:"Supprimer",taskDuplicateBtn:"Copier la t\xe2che dans le champ",taskDuplicateTooltip:"Copier le titre, les \xe9tiquettes et le projet dans le champ.",taskDeleteConfirm:"Supprimer cette entr\xe9e ? Le temps enregistr\xe9 sera perdu. Cette action est irr\xe9versible.",taskConcurrentTrackingConflictTitle:"Suivi d\xe9j\xe0 actif",taskConcurrentTrackingConflictMessage:"Au moins une t\xe2che a d\xe9j\xe0 un minuteur actif. Indiquez ce que vous en faites avant de lancer celle-ci : les terminer (elles passent dans \xab termin\xe9es \xbb), les mettre en pause (reprise plus tard dans \xab en pause \xbb), ou les laisser tourner et d\xe9marrer la nouvelle t\xe2che en parall\xe8le.",taskConcurrentTrackingConflictPauseBtn:"Mettre les t\xe2ches actives en pause",taskConcurrentTrackingConflictFinishBtn:"Terminer les t\xe2ches actives",taskConcurrentTrackingConflictParallelBtn:"D\xe9marrer en parall\xe8le (garder les minuteurs)",taskConcurrentTrackingDontShowAgain:"M\xe9moriser ce choix et ne plus afficher cette bo\xeete (la m\xeame action sera appliqu\xe9e automatiquement la prochaine fois).",taskPlannedBoundaryConflictTitle:"Une t\xe2che planifi\xe9e entre en cours",taskPlannedBoundaryConflictMessage:"Une t\xe2che qui \xe9tait sous Planifi\xe9es a atteint son heure de d\xe9but et compte d\xe9sormais comme en cours alors qu’un autre minuteur tournait d\xe9j\xe0. Indiquez ce que vous faites des t\xe2ches d\xe9j\xe0 au minuteur : les mettre en pause (elles passent dans la liste des pauses), les terminer (elles passent dans les termin\xe9es), ou les laisser tourner en parall\xe8le avec la nouvelle.",taskPlannedBoundaryConflictResolveError:"Impossible d’appliquer votre choix sur les minuteurs. V\xe9rifiez le serveur et r\xe9essayez.",navDashboardPlannedConflictPulseHint:"Tableau de bord : modale de conflit de minuteurs \xe0 traiter",tasksPausedHeading:"En pause",tasksCompletedHeading:"Termin\xe9es",tasksArchiveOpenHeading:"Non termin\xe9es (instantan\xe9)",tasksRunningHeading:"En cours (minuteur)",tasksPlannedHeading:"Planifi\xe9es",tasksTimelineEmpty:"Aucun cr\xe9neau horaire de t\xe2che dans cette vue de session.",tasksTimelineGanttOpenBtn:"Gantt",tasksTimelineGanttOpenBtnAria:"Ouvrir le fil chronologique en vue Gantt",tasksTimelineGanttTitle:"Fil chronologique (vue Gantt)",tasksTimelineGanttDescription:"Frise align\xe9e sur le d\xe9but de la session : une ligne par t\xe2che ; les barres color\xe9es suivent les intervalles du minuteur. Faire d\xe9filer horizontalement si la session s’\xe9tire sur une longue plage.",tasksTimelineGanttTodayTitle:"Fil de la journ\xe9e (vue Gantt)",tasksTimelineGanttTodayDescription:"Frise globale de la journ\xe9e en cours : tous les intervalles de t\xe2ches de toutes les sessions sont regroup\xe9s dans une seule vue.",tasksTimelineGanttWindowStartLabel:"D\xe9but de la frise",tasksTimelineGanttWindowEndLabel:"Fin de la frise",tasksTimelineGanttLegendWork:"Temps suivi",tasksTimelineGanttLegendGap:"Hors intervalle (sur cette ligne)",tasksTimelineGanttLegendProductive:"Productif (projets @)",tasksTimelineGanttLegendPersonal:"Personnel (projets !)",tasksTimelineGanttSummaryProductive:"Total productif : {duration}",tasksTimelineGanttSummaryPersonal:"Total personnel : {duration}",tasksTimelineGanttCloseBtn:"Fermer",tasksTimelineGanttTooltipStart:"D\xe9but",tasksTimelineGanttTooltipEnd:"Fin",tasksTimelineGanttTooltipTimer:"Dur\xe9e minuteur",tasksTimelineGanttTooltipWall:"Dur\xe9e murale",tasksTimelineGanttTooltipTimerUnknown:"—",tasksTimelineGanttLapsPopoverAria:"Laps de suivi pour ce segment de t\xe2che",ganttColorPickerAria:"Couleur des barres Gantt",ganttColorPickerAuto:"Couleur automatique",ganttColorPickerSwatch:"Couleur {color}",taskGanttColorLabel:"Couleur Gantt",hideTaskList:"Masquer la liste",showAllTasks:"Afficher toute la liste",pauseTaskBtn:"Pause — affichage dans la liste des pauses",resumeTaskBtn:"Reprendre le suivi",taskTimerPausedManual:"Minuteur en pause (manuel).",pausedNote:"La session est en pause pendant la consultation de l’historique.",viewingHistoryBannerTitle:"Vous consultez une session pass\xe9e.",resumeBtn:"Reprendre la session active",inspectingLabel:"Consultation :",historyInspectBannerAria:"Consultation d’une session pass\xe9e",liveSessionWallPausedBannerAria:"Session en pause (collecte)",liveSessionWallPausedTitle:"La session est en pause",liveSessionWallPausedDetail:"L’horloge murale est fig\xe9e. Utilisez \xab Reprendre \xbb ci-dessous ou le bouton lecture sur une t\xe2che — les deux relancent le suivi de session.",liveSessionResumeWallBtn:"Reprendre la session",autoTagsDetected:"\xc9tiquettes d\xe9tect\xe9es",autoProjectDetected:"Projet",tagsHelpAriaLabel:"Aide sur les \xe9tiquettes",tagSyntaxHelp:"#mot apr\xe8s un espace ou en d\xe9but, ou coll\xe9 (mot#nom). @projet : m\xeames r\xe8gles ; plusieurs @ → le dernier l’emporte (un seul projet par t\xe2che). Jetons : lettres, chiffres, tiret, soulign\xe9 (sans espaces).",tagSuggestionsHelp:"\xc0 c\xf4t\xe9 du (?), le petit champ applique une ligne du type #mot, @projet ou un nom d’\xe9tiquette lorsque vous appuyez sur Entr\xe9e. Taper #mot dans le titre est \xe0 part.",tagsHelpWorkflowSummary:"Au-dessus, les \xe9tiquettes en lecture seule listent tout ce qui est sur la t\xe2che ; la ligne projet affiche son projet. Modifiez le titre ou utilisez le champ rapide (Entr\xe9e). @Projet#code reste optionnel.",taskAppliedTagsHelpHeading:"\xc9tiquettes sur cette t\xe2che",taskAppliedTagsHelpHint:"Tout est fusionn\xe9 : titre, champ de nouvelle t\xe2che et ligne rapide sous chaque t\xe2che. Saisissez #\xe9tiquette, @projet ou un nom puis Entr\xe9e ; @ seul retire le projet.",taskTagsExtraHelpAria:"Aide : \xe9tiquettes et projet appliqu\xe9s \xe0 cette t\xe2che",taskTagsOrphanProjectHelpBody:"Issu du titre, absent de la liste enregistr\xe9e. \xc9pinglez sous \xc9tiquettes et projets ou modifiez le titre.",taskTagProjectQuickAddPlaceholder:"#\xe9tiquette, @projet ou nom… Entr\xe9e (@ seul retire le projet)",taskTagProjectQuickAddAria:"Ajout rapide : saisir #\xe9tiquette, @projet ou un nom d’\xe9tiquette, puis Entr\xe9e",taskTagProjectMultiGroupTags:"\xc9tiquettes enregistr\xe9es",taskTagProjectMultiGroupProjects:"Projets enregistr\xe9s",taskTagProjectMultiOptionClearProject:"Retirer le projet (\xe9quivaut \xe0 @ seul)",taskTagProjectMultiSelectAria:"S\xe9lection multiple d’\xe9tiquettes et de projets enregistr\xe9s, puis bouton Ajouter la s\xe9lection",taskTagDefaultBucket:"d\xe9faut",taskTagProjectMultiHint:"Ctrl ou ⌘ + clic pour s\xe9lectionner plusieurs lignes, puis ajoutez.",taskTagProjectApplySelectionBtn:"Ajouter la s\xe9lection",tagsUserGuideIntro:"Ce guide explique comment le titre de t\xe2che, les raccourcis enregistr\xe9s et l’option @projet#code s’articulent. Vous pouvez ignorer les fonctions avanc\xe9es et n’utiliser que des #\xe9tiquettes et un seul @projet.",tagsUserGuideBasicsTitle:"Bases : jetons dans le titre",tagsUserGuideBasicsBody:"Dans le titre d’une t\xe2che, vous pouvez m\xealer du texte libre \xe0 :\n• #nom — \xe9tiquette globale (lettres, chiffres, tiret, soulign\xe9).\n• @Projet — affecte la t\xe2che \xe0 un projet (plusieurs @ : le dernier l’emporte — un seul projet par t\xe2che).\nLes jetons peuvent suivre un espace ou \xeatre coll\xe9s au mot pr\xe9c\xe9dent (mot#tag). Le tableau de bord fusionne tout sous la t\xe2che.",tagsUserGuideShortcutsTitle:"Champ rapide sur chaque t\xe2che",tagsUserGuideShortcutsBody:"Dans Param\xe8tres → \xc9tiquettes et projets enregistr\xe9s (ou la colonne \xc9tiquettes \xe0 droite), vous \xe9pinglez \xe9tiquettes et projets que vous r\xe9utilisez. Sur une t\xe2che, l’\xe9troit champ \xe0 c\xf4t\xe9 de l’aide (?) propose ces valeurs ; appuyez sur Entr\xe9e pour appliquer une ligne (#\xe9tiquette, @projet, nom seul, ou @ seul pour retirer le projet). Cela ne r\xe9\xe9crit pas le titre tant que vous ne le modifiez pas vous-m\xeame.",tagsUserGuideScopedTitle:"Optionnel : @projet#code (\xe9tiquettes li\xe9es au projet)",tagsUserGuideScopedBody:"La syntaxe @Client#facture dans le titre enregistre une \xe9tiquette rattach\xe9e \xe0 ce projet (affich\xe9e Client#facture). Utile quand le m\xeame libell\xe9 local change selon le client, ou pour un filtrage plus strict. Si vous n’en avez pas besoin, restez sur #\xe9tiquette + @projet — les deux styles coexistent.",tagsUserGuideUseCasesTitle:"Cas d’usage",tagsUserGuideUseCasesBody:"• D\xe9veloppeur solo, un projet : tapez Ma fonctionnalit\xe9 @acme #frontend — sans liste enregistr\xe9e.\n• Beaucoup de tickets : \xe9pinglez #triage, #bugfix, @sprint-42 ; utilisez le champ rapide par t\xe2che au lieu de retaper.\n• Travail client : @ClientA#abonnement vs @ClientB#abonnement dans les titres pour s\xe9parer les espaces de noms ; filtrez par projet dans les rapports.\n• Saisie r\xe9troactive : m\xeames r\xe8gles # et @ dans le formulaire pass\xe9 ; le champ rapide accepte la m\xeame syntaxe.",tagsUserGuideFooterNote:"Les descriptions sur les \xe9tiquettes ou projets (survol long sur une pastille qui en a une) sont des notes pour l’\xe9quipe — elles ne changent pas le filtrage des donn\xe9es dans Kronosys.",subtasksHeading:"Points de d\xe9tail",addSubtaskLinkBtn:"Ajouter un point de d\xe9tail",addSubtaskPlaceholder:"Nouveau point…",addSubtaskBtn:"Ajouter",subtaskMarkDone:"Marquer ce point comme fait",subtaskMarkUndone:"Marquer ce point comme non fait",subtaskDelete:"Supprimer ce point",subtaskDragReorderHandle:"Glisser pour r\xe9ordonner",subtaskMoveUp:"Monter ce point dans la liste",subtaskMoveDown:"Descendre ce point dans la liste",subtaskTimerStart:"Suivre le temps sur ce point",subtaskTimerStop:"Arr\xeater le suivi sur ce point",subtaskDurationNotMeasured:"Pas mesur\xe9e",subtaskDurationNotRecorded:"Pas enregistr\xe9e",subtaskDurationNotShown:"Pas affich\xe9e",subtaskDurationTooltipNotMeasured:"Aucune dur\xe9e accumul\xe9e sur ce point pour l’instant. Utilisez la lecture pour d\xe9marrer le suivi.",subtaskDurationTooltipNotRecorded:"Cet instantan\xe9 ne contient pas de dur\xe9e pour ce point (non suivie ici ou absente de l’instantan\xe9 enregistr\xe9).",subtaskDurationTooltipNotShown:"Aucune dur\xe9e n’est affich\xe9e pour ce point termin\xe9 sans temps enregistr\xe9 dans cette vue archiv\xe9e.",noData:"Pas encore de donn\xe9es.",sessionsColumnTitle:"Sessions",sessionsColumnHelpAria:"Aide : colonne Sessions",sessionsColumnHelpBody:"Vos sessions enregistr\xe9es et la session en cours s’affichent ici lorsque le suivi est actif.\n\nOuvrez la session active pour modifier le suivi en direct.",dashboardColSessionTeaser:"Choisis la session en cours (ou d\xe9marre-en une). Tout le tableau de bord s’aligne sur ce choix.",dashboardColSessionFlowHint:"Ensuite → T\xe2ches au centre",dashboardColTasksTeaser:"Inscris le travail r\xe9el : t\xe2ches, minuteurs, KronoFocus — li\xe9 \xe0 la session \xe0 gauche.",dashboardColTasksFlowHint:"Puis → \xc9tiquettes & projets \xe0 droite",dashboardColTagsTeaser:"Ajoute #\xe9tiquettes, @projets et raccourcis pour garder l’historique et les rapports lisibles.",dashboardColTagsFlowHint:"Facultatif, mais le futur-toi remercie.",dashboardColumnHintsPanelTitle:"Comment lire les trois colonnes",dashboardColumnHintsExpandAria:"Afficher l’aide sur les trois colonnes du tableau de bord",dashboardColumnHintsCollapseAria:"Masquer l’aide sur les colonnes",dashboardColumnHintsDismissTitle:"Masquer d\xe9finitivement ce rappel",sessionsListAriaLabel:"Sessions",sessionLiveBadge:"En cours",sessionListWallDurationTitle:"Dur\xe9e murale de la session : minutes enregistr\xe9es si disponibles, sinon \xe9cart entre le d\xe9but et la fin.",sessionListWallDurationAlertTooltip:"Au seuil d’alerte ou au-del\xe0 ({hours} h) — modifiable dans Param\xe8tres → Tableau de bord web.",sessionListStartedPrefix:"D\xe9but :",sessionListEndedPrefix:"Fin :",sessionListOpenGanttAria:"Ouvrir la vue Gantt pour cette session",selectedSessionSidebarTimelineIconTooltip:"Gantt",selectedSessionSidebarTimelineIconAria:"Ouvrir la frise horizontale des t\xe2ches pour cette session",sessionEndLiveTitle:"Terminer la session — enregistrer dans l’historique sans en d\xe9marrer une nouvelle (le suivi peut rester actif)",sessionEndLiveAria:"Terminer la session en cours",sessionEndLiveConfirmTitle:"Terminer cette session ?",sessionEndLiveConfirmIntro:"Il reste du travail ouvert dans cette session. En la terminant, un instantan\xe9 est enregistr\xe9 dans l’historique : les minuteurs et le suivi par points ne s’appliquent plus \xe0 cette session, mais vous pourrez encore modifier les noms, les \xe9tiquettes et les projets en ouvrant la session archiv\xe9e.",sessionEndLiveConfirmIntroCalm:"En terminant la session, un instantan\xe9 est enregistr\xe9 dans l’historique avec l’heure de fin actuelle. Les minuteurs et le suivi par points ne s’appliquent plus \xe0 cette session, mais vous pourrez encore modifier les noms, les \xe9tiquettes et les projets en ouvrant la session archiv\xe9e.",sessionEndLiveWarnActiveTask:"Un suivi est actuellement actif (en cours).",sessionEndLiveWarnPausedTasks:"Au moins une entr\xe9e est en pause ou non termin\xe9e.",sessionEndLiveWarnIncompleteSubtasks:"Au moins un point n’est pas marqu\xe9 comme termin\xe9.",sessionEndLiveTasksHandlingLegend:"\xc0 la fermeture, que faire des t\xe2ches encore ouvertes ?",sessionEndLiveTasksHandlingKeep:"Laisser les t\xe2ches non termin\xe9es dans l’instantan\xe9 — les minuteurs s’arr\xeatent (le temps d\xe9j\xe0 cumul\xe9 est conserv\xe9)",sessionEndLiveTasksHandlingFinish:"Terminer les t\xe2ches ouvertes avec cette session",sessionEndLiveTasksHandlingMoveToPaused:"Transposer les t\xe2ches ouvertes vers une nouvelle session en pause",sessionEndLiveConfirmBtn:"Terminer la session",sessionEndLiveSidebarBtn:"Terminer cette session",sessionEndReasonModalHint:"Facultatif : indiquez pourquoi vous cl\xf4turez la session (bilans, feuilles de temps, r\xe9trospectives).",sessionEndReasonFieldsetLegend:"Raison de cl\xf4ture",sessionEndReasonSkip:"Ne pas enregistrer de cat\xe9gorie",sessionEndReasonPlanned:"Fin conforme au temps ou au p\xe9rim\xe8tre pr\xe9vu",sessionEndReasonEarly:"Fin anticip\xe9e (avant le temps ou l’\xe9ch\xe9ance pr\xe9vus)",sessionEndReasonOverrun:"Prolongation ou d\xe9passement par rapport au pr\xe9vu",sessionEndReasonOther:"Autre",sessionEndReasonNotePlaceholder:"Pr\xe9cision (facultatif)…",sessionEndReasonNoteAria:"Pr\xe9cision libre sur la fa\xe7on dont cette session se termine",selectedSessionEndReasonTitle:"Cl\xf4ture",sessionEndReasonEditHint:"Modifiez la cat\xe9gorie ou la pr\xe9cision enregistr\xe9e pour la cl\xf4ture de cette session.",sessionEndReasonSaveBtn:"Enregistrer la cl\xf4ture",sessionEndReasonSaveAria:"Enregistrer la raison de cl\xf4ture",sessionEndReasonSaving:"Enregistrement…",beforeUnloadLiveSessionMessage:"Une session Kronosys est ouverte dans ce tableau de bord. Fermer cet onglet ne met pas fin \xe0 la session. Utilisez \xab Terminer cette session \xbb dans la colonne de gauche pour la cl\xf4turer ici, ou quittez cet onglet — la session reste active en arri\xe8re-plan.",openSessionInNewTab:"Ouvrir cette session dans un nouvel onglet",detachedSessionUrlHint:"Cet onglet suit l’URL. Consulter une archive ici ne modifie que cet onglet — pas la session en cours ni la session s\xe9lectionn\xe9e dans les autres onglets ouverts.",detachedSessionUrlHintDismiss:"Masquer ce message",detachedSessionInvalidUrl:"Aucune session ne correspond \xe0 ce param\xe8tre d’URL.",tasksInSessionSingular:"\xe9l\xe9ment",tasksInSessionPlural:"\xe9l\xe9ments",rightColumnTitle:"T\xe2ches",tagsProjectsColumnTitle:"\xc9tiquettes, projets et mod\xe8les",tagsProjectsColumnIntro:"\xc9pinglage, descriptions et masquage des pastilles — comme dans les param\xe8tres, ici \xe0 c\xf4t\xe9 du flux de travail. Deux onglets permettent de basculer entre les \xe9tiquettes globales et les projets.",tagsProjectsColumnHelpAria:"Aide : colonne \xe9tiquettes et projets",tagsProjectsColumnHelpBody:"Les \xe9tiquettes globales s’appliquent \xe0 toute t\xe2che. Les \xe9tiquettes li\xe9es utilisent Projet#code et ne s’affichent en suggestion que si le @projet de la t\xe2che correspond.\n\nDans cette colonne, l’onglet \xc9tiquettes globales regroupe raccourcis, masqu\xe9es et descriptions ; l’onglet Projets et \xe9tiquettes li\xe9es regroupe les projets enregistr\xe9s et les codes par projet.\n\nCette colonne reprend la section \xab \xc9tiquettes et projets enregistr\xe9s \xbb des param\xe8tres ; les changements sont imm\xe9diats.\n\nL’aide compl\xe8te et les cas d’usage sont dans le \xab ? \xbb \xe0 c\xf4t\xe9 des \xe9tiquettes sur une carte t\xe2che.",tasksColumnSubtitle:"En cours au minuteur, planifi\xe9es (d\xe9but ou fin futur), en pause et termin\xe9es pour la session s\xe9lectionn\xe9e.",tasksColumnSubtitleHelpAria:"Aide : contenu de cette colonne",taskFocusNoSessionTitle:"Aucune session active",taskFocusNoSessionBody:"D\xe9marrez une session depuis la colonne Sessions \xe0 gauche pour enregistrer des t\xe2ches ici.",taskStartAutoSessionToast:"Aucune session en cours — d\xe9marrage d’une session pour y rattacher cette t\xe2che.",selectedSessionSidebarTitle:"Session s\xe9lectionn\xe9e",selectedSessionSidebarTitleLive:"Session en cours",selectedSessionSidebarTitleIdle:"Aucune session active",selectedSessionSidebarPausedBadgeGlobal:"Pause globale",selectedSessionSidebarPausedBadgeSession:"En pause",dashboardPauseBackdropTitleGlobal:"Pause globale active",dashboardPauseBackdropDetailGlobal:"Le suivi est fig\xe9 pour cette session, les t\xe2ches et les sous-t\xe2ches concern\xe9es. Reprenez via la commande de pause globale dans la barre du haut.",dashboardPauseBackdropAriaGlobal:"Tableau de bord : pause globale active",dashboardPauseBackdropTitleSession:"Suivi de session en pause",dashboardPauseBackdropDetailSession:"La dur\xe9e murale et les minuteurs concern\xe9s sont fig\xe9s. Reprenez depuis le bandeau au-dessus de la colonne T\xe2ches.",dashboardPauseBackdropAriaSession:"Tableau de bord : pause de session (murale) active",sessionNoteLabel:"Note de session",sessionNotePlaceholder:"Ajouter une note libre pour cette session…",selectedSessionIdleHint:"D\xe9marrez une session depuis la colonne Sessions pour enregistrer le temps, le suivi et les m\xe9triques.",sessionDetailsModalTitle:"R\xe9sum\xe9 de la session",sessionDetailsModalCloseAria:"Fermer le r\xe9sum\xe9 de session",sessionDetailsModalReopenBtn:"R\xe9sum\xe9 session",statsMetricSessionDurationHelpAria:"Aide : dur\xe9e de session",statsMetricSessionDurationHelpBody:"Temps \xe9coul\xe9 (horloge murale) depuis le premier \xe9v\xe9nement d’activit\xe9 enregistr\xe9 dans cette session jusqu’\xe0 maintenant (session en cours) ou jusqu’\xe0 l’enregistrement de l’instantan\xe9 (archive). Distinct du temps actif, du temps de codage et des minuteurs de suivi ou de point.",sessionRemainingDurationLabel:"Dur\xe9e restante",sessionRemainingDurationUndetermined:"Ind\xe9termin\xe9e",sessionPlannedTotalDurationLabel:"Dur\xe9e totale planifi\xe9e",sessionPlannedTasksTotalLabel:"Total planifi\xe9 (t\xe2ches)",sessionListPlannedTotalPrefix:"planifi\xe9",statsMetricCodingTimeHelpAria:"Aide : temps de codage",statsMetricCodingTimeHelpBody:"Temps cumul\xe9 lorsqu’un fichier productif (hors langages exclus) est au centre du contexte de codage : ouverture, enregistrement, changement d’\xe9diteur actif ou modifications. Cesse d’augmenter apr\xe8s environ une minute sans signal de ce type. Ind\xe9pendant du minuteur de suivi.",statsMetricActiveTimeHelpAria:"Aide : temps actif",statsMetricActiveTimeHelpBody:"Temps cumul\xe9 \xe0 partir de signaux d’activit\xe9 sur le poste : modifications, ouverture de fichier, changements de s\xe9lection, \xe9diteur actif et focus de fen\xeatre. Les intervalles de plus d’environ trois minutes ne comptent pas. Souvent entre le temps de codage et la dur\xe9e de session.",statsMetricTasksHelpAria:"Aide : t\xe2ches par statut",statsMetricTasksHelpBody:"Pour la session affich\xe9e : t\xe2ches avec le minuteur de suivi actif (\xab En cours (minuteur) \xbb), t\xe2ches dont le d\xe9but ou la fin est encore dans le futur (\xab Planifi\xe9es \xbb), autres t\xe2ches non termin\xe9es (section \xab En pause \xbb), et t\xe2ches termin\xe9es dont la fin n’est pas dans le futur. Reprend les blocs de la colonne T\xe2ches.",statsTasksRowRunning:"En cours (minuteur)",statsTasksRowPausedList:"En liste (non termin\xe9es)",statsTasksRowCompleted:"Termin\xe9es",statsTasksRowPlanned:"Planifi\xe9es (futur)",gitRepoCardTitle:"D\xe9p\xf4t Git du workspace",gitRepoNotARepo:"Le premier dossier du workspace n’est pas un d\xe9p\xf4t Git (ou Git n’est pas disponible).",gitRepoCardHelpAria:"Aide : aper\xe7u Git du workspace",gitRepoCardHelpBody:"R\xe9sum\xe9 du d\xe9p\xf4t Git \xe0 la racine du premier dossier du workspace : nombre de branches, de commits, extrait de `git log --graph --all`, et \xe9chantillon tri\xe9 des chemins suivis via `git ls-files`. Mis \xe0 jour lors du rafra\xeechissement du tableau de bord depuis le serveur.",gitRepoCurrentBranchLabel:"Branche courante",gitRepoBranchesLocalLabel:"Branches locales",gitRepoBranchesLocalHelpAria:"Aide : branches locales",gitRepoBranchesLocalHelpBody:"Nombre de branches locales (`git branch --list`).",gitRepoBranchesRemoteLabel:"Branches distantes",gitRepoBranchesRemoteHelpAria:"Aide : branches distantes",gitRepoBranchesRemoteHelpBody:"Nombre de branches de suivi distant (`git branch -r`), hors l’alias symbolique `*/HEAD`.",gitRepoCommitsHeadLabel:"Commits (HEAD)",gitRepoCommitsHeadHelpAria:"Aide : commits sur la branche courante",gitRepoCommitsHeadHelpBody:"Nombre de commits atteignables depuis HEAD (`git rev-list --count HEAD`), soit l’historique de la branche actuelle.",gitRepoCommitsAllLabel:"Commits (toutes refs)",gitRepoCommitsAllHelpAria:"Aide : commits toutes r\xe9f\xe9rences",gitRepoCommitsAllHelpBody:"Nombre sur toutes les r\xe9f\xe9rences (`git rev-list --all --count`). Peut \xeatre co\xfbteux sur les tr\xe8s gros d\xe9p\xf4ts ; affich\xe9 en — si la commande \xe9choue.",gitRepoStashesLabel:"Stashes",gitRepoStashesHelpAria:"Aide : liste des stashes",gitRepoStashesHelpBody:"Nombre d’entr\xe9es dans `git stash list`.",gitRepoGraphTitle:"Graphe r\xe9cent",gitRepoGraphHelpAria:"Aide : graphe de commits",gitRepoGraphHelpBody:"Graphe ASCII produit par `git log --graph --decorate --all` (40 derniers commits). Utile pour voir la relation entre branches.",gitRepoGraphEmpty:"Aucune ligne de graphe.",gitRepoGraphPreviewNote:"Aper\xe7u partiel — seulement les 40 derniers commits dans cette zone.",gitRepoGraphOpenFullAria:"Ouvrir le graphe de commits complet dans un nouvel onglet",gitRepoGraphOpenFullTitle:"Ouvrir le graphe de commits complet dans un nouvel onglet du navigateur",gitRepoGraphDetailDocTitle:"Graphe Git — Kronosys",gitRepoTreeTitle:"Fichiers suivis (extrait)",gitRepoTreeHelpAria:"Aide : extrait des chemins suivis",gitRepoTreeHelpBody:"\xc9chantillon tri\xe9 alphab\xe9tiquement des chemins de `git ls-files` (jusqu’\xe0 300). Ce n’est pas l’arborescence compl\xe8te ; sur les gros d\xe9p\xf4ts, des chemins peuvent manquer selon les limites de m\xe9moire.",gitRepoTreeEmpty:"Aucun chemin dans l’extrait.",gitRepoTreePreviewNote:"Aper\xe7u partiel — \xe9chantillon d’au plus 300 chemins suivis.",gitRepoTreeOpenFullAria:"Ouvrir la liste compl\xe8te des chemins suivis dans un nouvel onglet",gitRepoTreeOpenFullTitle:"Ouvrir la liste compl\xe8te des chemins suivis dans un nouvel onglet du navigateur",gitRepoTreeDetailDocTitle:"Fichiers suivis — Kronosys",statsLocSectionTitle:"Lignes et langages",statsLinesWrittenTotal:"Lignes \xe9crites",statsLinesWrittenHuman:"Humain (estim.)",statsLinesWrittenAi:"IA (estim.)",statsLocByLanguageHeading:"Lignes par langage",statsCodingSignalsHeading:"Signaux de codage par langage",statsMetricLinesWrittenHelpAria:"Aide : lignes \xe9crites",statsMetricLinesWrittenHelpBody:"Lignes nettes ajout\xe9es \xe0 partir des modifications suivies (estimation via les retours \xe0 la ligne dans les diffs). Les insertions tr\xe8s massives sont partiellement plafonn\xe9es. \xab Humain \xbb / \xab IA \xbb est une heuristique par transaction : plusieurs plages de modification, plus d’environ 6 lignes nettes, ou un bloc unique long avec saut de ligne ressemblent souvent \xe0 une insertion agent ou collage — ce n’est pas une attribution exacte.",statsMetricLocByLanguageHelpAria:"Aide : lignes par langage",statsMetricLocByLanguageHelpBody:"R\xe9partition des lignes nettes par identifiant de langage pour cette session (m\xeame base que \xab Lignes \xe9crites \xbb).",statsMetricCodingSignalsHelpAria:"Aide : signaux de codage",statsMetricCodingSignalsHelpBody:"Nombre de signaux de contexte de codage par langage (ouverture, enregistrement, \xe9dition, changement d’\xe9diteur actif, et signaux p\xe9riodiques lorsqu’une \xe9dition r\xe9cente a eu lieu).",sessionNameReadOnly:"Nom de la session (lecture seule pour cette archive)",sessionArchiveBtn:"Archiver",sessionArchiveTitle:"Masquer cette session de la liste (r\xe9cup\xe9rable dans Archives)",sessionRestoreBtn:"Restaurer",sessionDeleteBtn:"Supprimer",sessionDeleteTitle:"Supprimer la session",sessionDeleteIntro:"La session sera retir\xe9e de votre historique. Choisissez le sort des \xe9l\xe9ments associ\xe9s.",sessionDeleteDiscardTasks:"Supprimer les \xe9l\xe9ments avec la session (les abandonner)",sessionDeleteMoveTasks:"D\xe9placer les \xe9l\xe9ments vers une autre session",sessionDeleteTargetLabel:"Session cible",sessionDeleteTargetPlaceholder:"Choisir une session…",sessionDeleteConfirmBtn:"Supprimer la session",sessionDeleteCancelBtn:"Annuler",archivesModalTitle:"Sessions archiv\xe9es",archivesEmpty:"Aucune session archiv\xe9e.",archivesCloseBtn:"Fermer",archivedBadge:"Archiv\xe9e",sessionArchiveConfirm:"Archiver cette session ?\n\n• Masqu\xe9e de la liste jusqu’\xe0 restauration (Archives).\n• Rapports : exclues les entr\xe9es non termin\xe9es et celles dont un point reste ouvert (totaux, graphiques, temps par projet, KronoFocus li\xe9).",sessionArchiveDontShowAgain:"Ne plus afficher cet avertissement",storageBadgeLabelSqlite:"SQLite",storageBadgeTooltipSqlite:"L’historique des sessions est stock\xe9 en SQLite dans le r\xe9pertoire de donn\xe9es Kronosys (pilote de persistance locale dans les param\xe8tres).",storageBadgeLabelJson:"JSON",storageBadgeTooltipJson:"L’historique des sessions utilise des fichiers JSON partitionn\xe9s (pilote local h\xe9rit\xe9). Vous pouvez passer \xe0 SQLite dans les param\xe8tres Kronosys",storageBadgeLabelMongo:"MongoDB",storageBadgeTooltipMongo:"Le miroir MongoDB est activ\xe9 et connect\xe9. Vous pouvez envoyer les sessions depuis la liste ; les sessions locales suivent toujours votre pilote de persistance.",workspaceFoldersLabel:"Racines du workspace",workspaceFoldersEmpty:"Aucune racine de workspace n’est configur\xe9e pour ce tableau de bord.",headerDisplayRegionTitle:"Fuseau d’affichage {timeZone} ; format d’horloge {clock}.",headerClockFormat24Short:"24 h",headerClockFormat12Short:"12 h (AM/PM)",headerWallClockAriaLabel:"Horloge murale, fuseau d’affichage {timeZone} : {datetime}.",gitIdentityBannerAria:"Auteur Git non configur\xe9",gitIdentityBannerBody:"Indiquez l’auteur Git (nom, courriel, identifiant de forge optionnel) pour la ligne sous le titre du tableau de bord. Utilisez Configurer ici pour un formulaire rapide — tout reste local et modifiable plus tard dans Param\xe8tres → Identit\xe9 Git.",gitIdentityBannerConfigure:"Configurer ici",gitIdentityBannerDismiss:"Masquer ce rappel",gitIdentityModalTitle:"Auteur Git (saisie rapide)",gitIdentityModalIntro:"Renseignez au moins un des champs ci-dessous. Les valeurs sont enregistr\xe9es localement avec vos donn\xe9es Kronosys — rien n’est envoy\xe9 au nuage depuis cette bo\xeete de dialogue.\n\nVous pourrez les modifier ou les compl\xe9ter \xe0 tout moment dans Param\xe8tres → Identit\xe9 Git.",gitIdentityModalNeedOneField:"Renseignez au moins un champ (nom, courriel ou identifiant sur la forge) avant d’enregistrer.",gitIdentityModalSaveError:"Enregistrement impossible. V\xe9rifiez la connexion et r\xe9essayez.",gitIdentityModalFooter:"Jeton GitLab, synchronisation Git automatique et autres options avanc\xe9es restent accessibles dans Param\xe8tres, section Identit\xe9 Git, lorsque vous en avez besoin.",mongoSyncLocalLabel:"JSON local",mongoSyncMongoLabel:"MongoDB",mongoSyncStatusAligned:"Align\xe9",mongoSyncStatusUnknown:"Nombre Mongo indisponible",mongoSyncStatusLocalAhead:"D\xe9calage — moins de documents dans Mongo",mongoSyncStatusMongoAhead:"D\xe9calage — plus de documents dans Mongo",mongoSyncHelpAriaLabel:"Aide : miroir MongoDB et sessions locales",mongoSyncHelpBody:"Les fichiers JSON locaux font foi. Les totaux comptent les sessions uniques dans l’historique (y compris archiv\xe9es). MongoDB n’est mis \xe0 jour que lorsque vous envoyez une session ou via Resynchroniser dans les param\xe8tres — pas \xe0 chaque sauvegarde locale. Un \xe9cart de totaux indique souvent des sessions jamais envoy\xe9es ou des documents suppl\xe9mentaires dans Mongo. La session en cours n’appara\xeet dans le d\xe9compte local qu’apr\xe8s \xe9criture sur disque.",sessionMongoPushAriaLabel:"Envoyer cette session vers MongoDB",sessionMongoPushSyncedTitle:"\xc0 jour sur MongoDB pour cet instantan\xe9",sessionMongoPushDirtyTitle:"Session modifi\xe9e depuis le dernier envoi — cliquer pour mettre \xe0 jour",sessionMongoPushNeverTitle:"Pas encore envoy\xe9e vers MongoDB — cliquer pour envoyer",sessionMongoPushBusy:"Envoi…",sessionMongoPushFailedDisabled:"MongoDB n’est pas activ\xe9 dans les param\xe8tres.",sessionMongoPushFailedNotFound:"Session introuvable.",sessionMongoPushFailedMongo:"MongoDB a refus\xe9 l’\xe9criture. V\xe9rifiez la connexion et les journaux.",sessionMongoPushFailedUri:"Connexion MongoDB incompl\xe8te (URI ou mot de passe).",dashboardLoadingAriaLabel:"Chargement du tableau de bord, veuillez patienter",dashboardLoadingMessage:"R\xe9cup\xe9ration des donn\xe9es de session depuis le serveur Kronosys…",dashboardConnectionErrorAriaLabel:"Serveur Kronosys injoignable",dashboardConnectionErrorTitle:"Connexion au serveur impossible",dashboardConnectionErrorBody:"D\xe9marrez l’application Kronosys (par ex. `kronosys start` ou `npm run dev`) et v\xe9rifiez que cet onglet peut la joindre. Si vous utilisez un dossier de donn\xe9es personnalis\xe9, contr\xf4lez les permissions du fichier SQLite.",dashboardConnectionRetryLabel:"R\xe9essayer",dashboardConnectionTechnicalDetailsLabel:"D\xe9tails techniques",dashboardSyncErrorBanner:"Impossible de resynchroniser avec le serveur. Affichage du dernier \xe9tat charg\xe9.",dataSearchTrigger:"Spotlight…",dataSearchPlaceholder:"Filtrer sessions, t\xe2ches, mod\xe8les, projets, \xe9tiquettes, dates, ou dur\xe9e (ex. 12:55 <, 0:10 >)…",dataSearchPaletteAriaLabel:"Recherche Spotlight",dataSearchTypePrompt:"Saisissez du texte pour filtrer les sessions, les t\xe2ches, les mod\xe8les de t\xe2che enregistr\xe9s, les projets et les \xe9tiquettes. Vous pouvez aussi saisir une date, une heure, ou une condition sur la dur\xe9e enregistr\xe9e : m:s (ou h:m:s) suivi (ou pr\xe9c\xe9d\xe9) de < ou >, p. ex. 45:00 > ou 1:0:0 <. Choisir un mod\xe8le remplit le brouillon de t\xe2che.",dataSearchEmpty:"Aucune session, t\xe2che ou mod\xe8le ne correspond.",dataSearchFooter:"↑↓ pour se d\xe9placer \xb7 Entr\xe9e pour ouvrir \xb7 \xc9chap pour fermer",dataSearchKindSession:"Session",dataSearchKindTask:"T\xe2che",dataSearchKindTaskTemplate:"Mod\xe8le de t\xe2che",taskTemplateDatalistPrefix:"Mod\xe8le :",taskTitleTemplateSuggestAria:"Mod\xe8les et titres r\xe9currents",taskTokenSuggestTagsAria:"\xc9tiquettes sugg\xe9r\xe9es",taskTokenSuggestWorkProjectsAria:"Projets sugg\xe9r\xe9s",taskTokenSuggestPersonalProjectsAria:"Projets personnels sugg\xe9r\xe9s",dataSearchTaskDistinguishId:"ID : {id}",dataSearchTaskStopwatchLabel:"Minuterie",dataSearchTaskRecordedTimeLabel:"Temps enregistr\xe9",dataSearchSessionWallLabel:"Dur\xe9e (session)",commandNewSession:"Nouvelle session",commandRefresh:"Actualiser le tableau de bord",commandOpenReporting:"Ouvrir les rapports",commandOpenSettings:"Ouvrir les param\xe8tres",commandOpenUserGuide:"Ouvrir le guide d’utilisation",commandFocusSessions:"Aller \xe0 la colonne Sessions",commandFocusTasks:"Aller \xe0 la colonne T\xe2ches",commandFocusTags:"Aller \xe0 la colonne \xc9tiquettes et projets",commandToggleTheme:"Basculer th\xe8me clair / sombre",commandToggleLang:"Changer la langue de l’interface (FR / EN)",commandEndLiveSession:"Terminer la session en cours",commandToggleFocusMode:"Basculer le mode focus (colonnes seules)",dashboardFocusModeEnterTitle:"Mode focus — sessions, t\xe2ches et \xe9tiquettes seulement",dashboardFocusModeEnterAria:"Activer le mode focus du tableau de bord",dashboardFocusModeExitTitle:"Quitter le mode focus",dashboardFocusModeExitAria:"Quitter le mode focus du tableau de bord",dashboardFocusModeExitHint:"\xc9chap",shortcutsModalTitle:"Raccourcis clavier",shortcutsModalCloseAriaLabel:"Fermer la fen\xeatre des raccourcis clavier",shortcutsModalIntro:"Cliquez sur \xab Modifier \xbb, puis enregistrez la nouvelle combinaison (au moins une touche Ctrl, Alt, Maj ou Meta). \xc9chap annule l’enregistrement. Ctrl+K / ⌘K est r\xe9serv\xe9 \xe0 la recherche rapide dans les donn\xe9es (non modifiable ici).",shortcutsTableAction:"Action",shortcutsTableShortcut:"Raccourci",shortcutsTableAssign:"Personnaliser",shortcutsChangeBtn:"Modifier…",shortcutsRecordPrompt:"Enregistrement…",shortcutsResetAll:"Tout r\xe9tablir aux valeurs par d\xe9faut",shortcutsPaletteRow:"Recherche Spotlight — Ctrl+K ou ⌘K (fixe)",tourProgressLabel:"\xc9tape {n} sur {total}",tourStep1Title:"Bienvenue dans le tableau de bord Kronosys",tourStep1Body:"Ce tableau de bord charge les donn\xe9es de session en direct depuis cette application web (routes API Next.js et SQLite local) — ce n’est pas un instantan\xe9 fig\xe9.",tourStep2Title:"Guide des trois colonnes (au-dessus du tableau)",tourStep2Body:"Cette bande se place juste sous l’en-t\xeate et r\xe9sume comment s’articulent **Sessions**, **T\xe2ches** et **\xc9tiquettes et projets** — de gauche \xe0 droite sur grand \xe9cran, empil\xe9es sur petit \xe9cran, avec des fl\xe8ches entre les blocs.\n\nD\xe9ployez-la ou repliez-la avec le chevron ; chaque encadr\xe9 est un court rappel avant les vraies colonnes plus bas. **Le bouton X** \xe0 droite masque tout le bandeau pour ce navigateur ; r\xe9activez-le sous **Param\xe8tres → Tableau de bord et API → Aide trois colonnes**. Le repli au chevron et le masquage complet sont m\xe9moris\xe9s s\xe9par\xe9ment.",tourStep3Title:"Sessions (colonne de gauche)",tourStep3Body:"Parcourez l’historique des sessions, d\xe9marrez une nouvelle session et consultez la dur\xe9e, le temps de codage et les statistiques de la session s\xe9lectionn\xe9e.\n\nLorsqu’une session en cours est ouverte, vous pouvez la terminer d’ici ; les sessions archiv\xe9es s’affichent en lecture seule.\n\nPour des options d’horaire plus pouss\xe9es, ouvrez Param\xe8tres (engrenage) : sous **Tableau de bord et API**, l’**alerte de dur\xe9e de session** met en \xe9vidence une session trop longue dans cette colonne ; les sections **Horaire de travail** et **Sessions sp\xe9cifiques planifi\xe9es** r\xe8glent le suivi automatique sur la semaine et des cr\xe9neaux r\xe9currents pr\xe9cis qui priment sur l’horaire g\xe9n\xe9ral pendant leur plage horaire.",tourStep4Title:"T\xe2ches et suivi (centre)",tourStep4Body:"Suivez ce sur quoi vous travaillez, terminez des t\xe2ches et utilisez les sous-t\xe2ches ou les options li\xe9es \xe0 Git au besoin.\n\nCette colonne suit la session choisie dans la colonne Sessions — le reste de l’en-t\xeate s’aligne sur ce choix.\n\nSur les autres t\xe2ches parentes, un seul flux de suivi : lancer le suivi d’une sous-t\xe2che lance aussi le minuteur de la t\xe2che parente et interrompt le suivi sur les autres t\xe2ches (le segment est enregistr\xe9). Mettre la t\xe2che parente en pause met en pause le suivi d’une sous-t\xe2che active sur la m\xeame t\xe2che. Reprendre le minuteur d’une t\xe2che ailleurs met fin aux suivi de sous-t\xe2ches sur les autres t\xe2ches et met en pause leur minuteur principal.\n\nLes points de d\xe9tail sont facultatifs. Le total sur la t\xe2che est toujours au moins la somme du temps enregistr\xe9 sur ces points ; l’\xe9cart correspond au suivi sur la t\xe2che sans d\xe9tail par point.\n\nSur une t\xe2che en cours, en pause ou termin\xe9e, **Sauvegarder comme template** enregistre son titre, ses #\xe9tiquettes et son @projet pour les r\xe9utiliser plus tard — le champ nouvelle t\xe2che les propose avec le pr\xe9fixe **Mod\xe8le :** et la palette Ctrl+K / ⌘K les liste \xe9galement. Vous pouvez aussi **corriger les bornes temporelles** d’une t\xe2che en conservant la dur\xe9e enregistr\xe9e, en saisissant une dur\xe9e manuelle (h/m/s) ou en recalculant depuis le d\xe9but et la fin.",tourStep5Title:"\xc9tiquettes et projets (droite)",tourStep5Body:"\xc9pinglez des \xe9tiquettes, g\xe9rez les projets enregistr\xe9s et r\xe9digez des descriptions — les m\xeames r\xe9glages que dans les param\xe8tres, accessibles pendant le travail. Deux onglets s\xe9parent les \xe9tiquettes globales des projets et des \xe9tiquettes li\xe9es.\n\nDans les titres de t\xe2ches, utilisez @projet et #\xe9tiquettes (y compris @projet#code) pour structurer le travail par projet.\n\nLes rapports (graphiques) s’appuient fortement sur ces objets : des \xe9tiquettes et des projets coh\xe9rents rendent les ventilations, filtres et tendances dans Rapports beaucoup plus utiles.",tourStep6Title:"Barre du haut : toutes les ic\xf4nes",tourStep6Body:"Dans ce groupe, de gauche \xe0 droite : la recherche rapide / palette de commandes (\xe9quivalent \xe0 Ctrl+K ou ⌘K — sessions, t\xe2ches, **mod\xe8les de t\xe2che**, projets et \xe9tiquettes), l’ic\xf4ne clavier pour l’aide aux raccourcis et leur personnalisation, les ic\xf4nes de navigation vers Tableau de bord, Rapports (graphiques), Param\xe8tres (engrenage), Guide d’utilisation (livre) et **Impl\xe9mentation** (fichier code — inventaire exhaustif ✓ / ✗ des user stories), le bouton **Gantt du jour** (intervalles des t\xe2ches de toutes les sessions du jour courant), la bascule de **pause globale**, le basculement th\xe8me clair / sombre, le bouton qui actualise les donn\xe9es sans recharger tout l’onglet du navigateur, et le menu de langue (FR / EN).\n\nLa pause globale reste inactive lorsque rien ne tourne. Sinon, elle ouvre une **modale de confirmation** avec un r\xe9sum\xe9 (d\xe9but, fin ou *en cours*, dur\xe9e murale, temps de codage et temps actif de session lorsque l’h\xf4te les fournit, d\xe9compte t\xe2ches / sous-t\xe2ches, total enregistr\xe9 sur les minuteurs de t\xe2ches puis r\xe9partition principal vs sous-t\xe2ches) avant de mettre en pause la session, ses t\xe2ches et les sous-t\xe2ches actives ; le clic suivant reprend uniquement ce lot.\n\nChaque contr\xf4le a une infobulle au survol ; les ic\xf4nes de navigation conservent le m\xeame habillage Kronosys.",tourStep7Title:"Identit\xe9 Git et pastille de stockage",tourStep7Body:"Ici s’affichent la ligne d’auteur Git et le compte forge lorsqu’ils sont renseign\xe9s dans Param\xe8tres → Identit\xe9 Git, les racines de workspace d\xe9tect\xe9es pour les m\xe9triques, et une pastille indiquant comment les sessions sont enregistr\xe9es ici : SQLite (par d\xe9faut), pilote JSON ou miroir MongoDB si activ\xe9.\n\nSQLite conserve la charge utile du tableau de bord sur cette machine dans le r\xe9pertoire de donn\xe9es Kronosys ; cette page lit et \xe9crit via l’API locale.",tourStep8Title:"Qu’est-ce que KronoFocus ?",tourStep8Body:"**KronoFocus** cadence votre session : un segment de travail dont vous choisissez la dur\xe9e, des pauses courtes, puis une pause longue apr\xe8s plusieurs cycles. Ce dispositif est int\xe9gr\xe9 \xe0 Kronosys (compteurs, phases, lien \xe0 la session) ; il ne se r\xe9sume pas \xe0 une m\xe9thode Pomodoro fig\xe9e.\n\nLa barre d’outils affiche toujours KronoFocus pour garder la navigation align\xe9e sur toutes les pages. L’affichage \xe0 c\xf4t\xe9 des actions de t\xe2che se r\xe8gle toujours dans Param\xe8tres → Tableau de bord et API (section KronoFocus).",tourStep8LearnMoreUrl:"https://fr.wikipedia.org/wiki/Gestion_du_temps",tourStep8LearnMoreLabel:"Pour aller plus loin — gestion du temps (nouvel onglet)",tourStep8LearnMoreAriaLabel:"Ouvre l’article Wikip\xe9dia sur la gestion du temps dans un nouvel onglet",tourStep9Title:"Identit\xe9 Git : la premi\xe8re chose apr\xe8s la visite",tourStep9Body:"Ce panneau s’affiche tant que le nom, le courriel ou le compte forge ne sont pas renseign\xe9s. Utilisez Configurer ici pour remplir un court formulaire sans quitter le tableau de bord — c’est l’action recommand\xe9e juste apr\xe8s la visite. Vous pouvez choisir Masquer ce rappel si vous pr\xe9f\xe9rez le faire plus tard.",tourSkipBtn:"Passer la visite",tourBackBtn:"Pr\xe9c\xe9dent",tourNextBtn:"Suivant",tourDoneBtn:"Terminer",settingsTourProgressLabel:"\xc9tape {n} sur {total}",settingsTourStep1Title:"Param\xe8tres et options",settingsTourStep1Body:"Certaines options avanc\xe9es ne sont pr\xe9sentes que dans les param\xe8tres et non sur le tableau de bord. Cette visite souligne les configurations cl\xe9s de votre espace de travail.",settingsTourStep2Title:"Profil d’usage",settingsTourStep2Body:"Basculez entre les modes 'Manager' et 'D\xe9veloppeur' pour ajuster le niveau de d\xe9tail du tableau de bord et la fr\xe9quence des rappels.",settingsTourStep3Title:"Persistance et pilotes",settingsTourStep3Body:"Choisissez entre SQLite (recommand\xe9) et l’ancien format JSON pour votre historique local. Vous pouvez aussi configurer un miroir MongoDB.",settingsTourStep4Title:"Int\xe9gration Git et GitLab",settingsTourStep4Body:"Configurez votre identit\xe9 Git et votre jeton d’API GitLab pour activer l’import d’issues et la g\xe9n\xe9ration de messages de commit.",settingsTourStep5Title:"Rapports et exclusions",settingsTourStep5Body:"D\xe9finissez les r\xe9pertoires et motifs de fichiers \xe0 exclure du d\xe9compte de lignes et du suivi de temps pour garder vos rapports propres.",settingsTourStep6Title:"Horaires et automatisation",settingsTourStep6Body:"Configurez vos heures de travail r\xe9currentes et vos sessions planifi\xe9es pour automatiser le d\xe9marrage du suivi ou le transfert de t\xe2ches.",settingsTourSkipBtn:"Passer la visite",settingsTourBackBtn:"Pr\xe9c\xe9dent",settingsTourNextBtn:"Suivant",settingsTourDoneBtn:"Terminer",tourUndismissBtn:"Relancer la visite",reportingTourProgressLabel:"Visite Rapports — \xe9tape {n} sur {total}",reportingTourStep1Title:"Bienvenue dans Rapports Kronosys",reportingTourStep1Body:"Cette page agr\xe8ge l’historique Kronosys via l’API locale. Elle sert \xe0 revoir les sessions, le temps enregistr\xe9 sur les t\xe2ches, l’usage KronoFocus et, selon les filtres, les r\xe9partitions par #\xe9tiquette et par @projet.",reportingTourStep2Title:"Filtres",reportingTourStep2Body:"Choisissez une plage de dates (ou les raccourcis Jour / Semaine / Mois / Ann\xe9e), affinez \xe9ventuellement par #\xe9tiquettes, puis r\xe9initialisez pour tout r\xe9afficher. Les pastilles vertes signalent des donn\xe9es encore mouvantes (session ou t\xe2ches non termin\xe9es).",reportingTourStep3Title:"Indicateurs r\xe9capitulatifs",reportingTourStep3Body:"Ces cartes condensent la m\xeame fen\xeatre que les graphiques : sessions, lignes de t\xe2ches, KronoFocus et minutes enregistr\xe9es. Les ic\xf4nes (?) ouvrent une courte d\xe9finition sans encombrer la page.",reportingTourStep4Title:"Graphiques par jour",reportingTourStep4Body:"Les barres montrent les sessions, les t\xe2ches par \xe9tat, le temps enregistr\xe9 sur les t\xe2ches et la dur\xe9e murale des sessions par jour calendaire. Quand plusieurs semaines existent, la bande de navigation aligne graphiques et calendriers par \xe9tiquette.",reportingTourStep5aTitle:"Temps par \xe9tiquette",reportingTourStep5aBody:"Consultez les minutes enregistr\xe9es sur les t\xe2ches regroup\xe9es par #\xe9tiquettes (y compris le compartiment sans \xe9tiquette explicite le cas \xe9ch\xe9ant), avec des grilles hebdomadaires lorsque les donn\xe9es couvrent plusieurs jours.",reportingTourStep5bTitle:"Temps par projet (Travail vs Personnel)",reportingTourStep5bBody:"La grille hebdomadaire par projet propose un s\xe9lecteur Travail (@) / Personnel (!) sous le titre de la section : Travail (d\xe9faut) exclut le registre personnel ; Personnel n’affiche que celui-ci (y compris les t\xe2ches d\xe9duites d’un jeton \xab ! \xbb dans le titre si le drapeau enregistr\xe9 manque). Les totaux par \xe9tiquette au-dessus combinent toujours les deux registres, sauf filtre par \xe9tiquettes.",reportingTourStep6Title:"Sommaire et mise en page \xe0 deux colonnes",reportingTourStep6Body:"Ce bloc correspond \xe0 la disposition principale de Rapports : le contenu \xe0 gauche et, sur grand \xe9cran, le sommaire fixe \xe0 droite. Sur t\xe9l\xe9phone, les m\xeames ancres sont propos\xe9es en pastilles au-dessus des filtres.",newSessionModalTitle:"Nouvelle session — port\xe9e",newSessionModalHelpAria:"Aide : d\xe9but de session et port\xe9e (dur\xe9e, dates, jours)",newSessionModalHelpBody:"Choisissez si la session d\xe9marre **maintenant** ou avec un **d\xe9but r\xe9troactif**. Saisissez **le d\xe9but et la fin** (heure locale du navigateur) pour un d\xe9but **pass\xe9**. En mode **Maintenant**, vous pouvez optionnellement indiquer une **fin planifi\xe9e** — la session se cl\xf4ture automatiquement \xe0 cette heure (comme si vous la posiez ensuite sur une session live). Si la fin est encore **\xe0 venir** sur un d\xe9but r\xe9troactif, Kronosys ouvre une session **live** \xe0 partir de ce d\xe9but et la **cl\xf4ture automatiquement** \xe0 l’heure pr\xe9vue ; si la fin est **d\xe9j\xe0 pass\xe9e**, la plage close est consign\xe9e dans l’historique. Un lancement **imm\xe9diat** alors qu’une session est d\xe9j\xe0 active ouvre d’abord la fin de session ; une session **enti\xe8rement pass\xe9e** n’interrompt pas la session active : la ligne va dans l’historique et l’\xe9cran bascule dessus. Ensuite, ces options de port\xe9e fixent le cadre attendu pour cette session seulement. Elles n’arr\xeatent pas Kronosys automatiquement : des rappels viennent de la collecte (battement de cœur) et une banni\xe8re ici lorsque vous approchez ou sortez des limites.\n\n• Dur\xe9e murale maximale — compt\xe9e depuis le premier \xe9v\xe9nement trac\xe9 dans la session.\n\n• P\xe9riode calendaire — dates locales inclusives (d\xe9but et/ou fin).\n\n• Jours de la semaine — limite aux jours choisis ; vous pouvez ajouter une plage horaire quotidienne (24 h locale). Les plages qui passent minuit sont prises en charge (ex. 22:00–06:00).",newSessionTimingSectionTitle:"D\xe9but de la session",newSessionTimingImmediate:"Maintenant (lancement imm\xe9diat)",newSessionTimingPast:"Dans le pass\xe9 (d\xe9but r\xe9troactif)",newSessionPastStartLabel:"La session a commenc\xe9 \xe0 (local)",newSessionPastStartHint:"Interpr\xe9t\xe9 dans le fuseau local du navigateur. L’horloge murale de session part de cet instant ; vous pourrez ensuite ajouter des t\xe2ches et ajuster les heures.",newSessionPastEndLabel:"La session se termine \xe0 (local)",newSessionPastEndHint:"Doit \xeatre apr\xe8s le d\xe9but. Si la fin est encore \xe0 venir, une session live s’ouvre et se cl\xf4ture automatiquement \xe0 cette heure ; si la fin est d\xe9j\xe0 pass\xe9e, la plage close est consign\xe9e dans l’historique.",newSessionImmediateEndLabel:"Fin planifi\xe9e (optionnelle, local)",newSessionImmediateEndHint:"Laissez vide pour aucune fin automatique. Si renseign\xe9e, la fin doit \xeatre dans le futur — la session se cl\xf4ture automatiquement \xe0 cet instant.",newSessionScopeFieldsetLegend:"Port\xe9e (rappels)",newSessionModeNone:"Aucune limite",newSessionModeMax:"Dur\xe9e murale maximale",newSessionModeCalendar:"P\xe9riode calendaire (dates)",newSessionModeWeekly:"Jours de la semaine (horaire optionnel)",newSessionMaxHoursLabel:"Dur\xe9e max (heures)",newSessionDateFromLabel:"Du (date)",newSessionDateToLabel:"Au (date)",newSessionTodayBtn:"Aujourd’hui",newSessionWeekdaysLegend:"Jours actifs",newSessionQuickWeekdays:"Jours de semaine",newSessionQuickWeekends:"Week-ends",newSessionQuickAll:"Tous les jours",newSessionTimeFromLabel:"Quotidiennement de",newSessionTimeToLabel:"\xe0",newSessionNowBtn:"Maintenant",newSessionUseTimeWindow:"Limiter \xe0 une plage horaire chaque jour s\xe9lectionn\xe9",newSessionUseTimeWindowHelpAria:"Aide : plage horaire quotidienne",newSessionUseTimeWindowHelpBody:"Quand activ\xe9e, la session ne suit le temps que dans la plage horaire sp\xe9cifi\xe9e pour les jours s\xe9lectionn\xe9s. En dehors de cette plage, la session est consid\xe9r\xe9e comme en pause. Prend en charge les plages chevauchant minuit (ex. 22:00–06:00).",newSessionErrorMax:"Indiquez une dur\xe9e maximale entre 0,1 et 8760 heures.",newSessionErrorCalendar:"Choisissez au moins une date (du et/ou au).",newSessionErrorWeekly:"S\xe9lectionnez au moins un jour de la semaine.",newSessionErrorPastMissing:"Indiquez la date et l’heure de d\xe9but pour une session pass\xe9e.",newSessionErrorPastEndMissing:"Indiquez la date et l’heure de fin pour une session pass\xe9e.",newSessionErrorPastEndBeforeStart:"La fin doit \xeatre strictement apr\xe8s le d\xe9but.",newSessionErrorPastFuture:"Choisissez une date et une heure dans le pass\xe9 ou au pr\xe9sent (pas dans le futur).",newSessionErrorPastInvalid:"Date ou heure non reconnues.",newSessionErrorImmediateEndNotFuture:"La fin planifi\xe9e doit \xeatre dans le futur (au moins environ une minute).",newSessionStartBtn:"D\xe9marrer la session",newSessionCancelBtn:"Annuler",sessionScopeNoticeAria:"Rappel de port\xe9e de session",appShellRouteNavAria:"Sections principales",appShellRouteNavTodayGantt:"Ouvrir le fil de la journ\xe9e (vue Gantt)",appShellRouteNavGlobalPause:"Mettre en pause la session, les t\xe2ches et les sous-t\xe2ches dans ce contexte",appShellRouteNavGlobalResume:"Reprendre uniquement ce qui a \xe9t\xe9 mis en pause globalement dans ce contexte",appShellRouteNavGlobalPauseDisabledTooltip:"Rien n’est actif \xe0 mettre en pause : l’horloge murale est d\xe9j\xe0 fig\xe9e et aucun minuteur de t\xe2che ou de sous-t\xe2che ne tourne.",appShellRouteNavGanttDashboardOnlyTooltip:"Le Gantt du jour n’est disponible que depuis le tableau de bord.",appShellRouteNavGlobalPauseDashboardOnlyTooltip:"La pause globale n’est disponible que depuis le tableau de bord lorsqu’une session live est charg\xe9e.",appShellRouteNavGlobalPauseNoSessionContextTooltip:"La pause globale n’est pas disponible pendant la consultation d’une archive ou avant le chargement de la session live.",appShellRouteNavChangelogUnavailableTooltip:"Raccourci changelog masqu\xe9 sur cet \xe9cran (libell\xe9 vide).",appShellRouteNavImplementationUnavailableTooltip:"Raccourci impl\xe9mentation masqu\xe9 sur cet \xe9cran (libell\xe9 vide).",appShellHeaderKronoFocusLoadingAria:"KronoFocus — attente des donn\xe9es de session",appShellRouteNavGroupAppAria:"Zones principales de l’application",appShellRouteNavGroupDocsAria:"Aide et documentation",appShellRouteNavGroupToolsAria:"Outils de session",appShellRouteNavGroupLegalAria:"Informations l\xe9gales",appShellRouteNavDataEnvironmentGroupAria:"Coffre production ou QA",dataEnvironmentNavGroupHint:"Basculer entre les donn\xe9es de production et un bac \xe0 sable QA isol\xe9",dataEnvironmentNavActiveLabel:"Actif",dataEnvironmentNavActiveProd:"Production",dataEnvironmentNavActiveQa:"QA",dataEnvironmentNavPendingRestart:"Au red\xe9marrage : {env}",dataEnvironmentNavEnableQaShort:"QA",dataEnvironmentNavEnableQaTitle:"Activer un coffre QA distinct (v4-qa) en plus de la production",dataEnvironmentNavSettingsLink:"Param\xe8tres",dataEnvironmentDualEnabledHint:"Coffre QA activ\xe9. Utilisez Prod / QA pour basculer, puis red\xe9marrez le serveur Kronosys.",dataEnvironmentNavTraceOverrideShort:"Chemin perso.",dataEnvironmentNavTraceOverrideAria:"TRACE_DATA_DIR est d\xe9fini ; le basculement production / QA est d\xe9sactiv\xe9",dataEnvironmentNavProdShort:"Prod",dataEnvironmentNavQaShort:"QA",dataEnvironmentNavProdTitle:"Donn\xe9es de production (vos vraies sessions et t\xe2ches)",dataEnvironmentNavQaTitle:"Donn\xe9es QA (copie isol\xe9e pour tests et reproduction de probl\xe8mes)",dataEnvironmentQaBanner:"Environnement QA — les donn\xe9es ici sont distinctes de la production. N’utilisez pas cet \xe9cran pour du travail r\xe9el.",dataEnvironmentSwitchRestartHint:"Pr\xe9f\xe9rence de coffre enregistr\xe9e. Red\xe9marrez le serveur Kronosys (arr\xeat puis `kronosys start` ou votre serveur de dev) pour ouvrir l’environnement choisi.",dataEnvironmentSwitchSuccessHint:"Bascule vers le coffre {env} effectu\xe9e.",dataEnvironmentSwitchError:"Impossible de changer d’environnement de donn\xe9es.",dataEnvironmentSwitchDisabled:"Activez d’abord les deux environnements dans Param\xe8tres → G\xe9n\xe9ral.",dataEnvironmentSwitchConfirmTitle:"Changer de coffre de donn\xe9es",dataEnvironmentSwitchConfirmMessage:"Vous allez basculer vers le coffre {env}.\n\nApr\xe8s confirmation, Kronosys rouvrira imm\xe9diatement le fichier SQLite correspondant.",dataEnvironmentSwitchConfirmBtn:"Basculer",dataEnvironmentSwitchLockBackdropTitleSwitching:"Bascule en cours…",dataEnvironmentSwitchLockBackdropDetailSwitching:"Veuillez patienter pendant l’enregistrement de la pr\xe9f\xe9rence.",dataEnvironmentSwitchLockBackdropAriaSwitching:"Application verrouill\xe9e : bascule de coffre en cours",dataEnvironmentSwitchLockBackdropTitleLocked:"Red\xe9marrage requis",dataEnvironmentSwitchLockBackdropDetailLocked:"La pr\xe9f\xe9rence de coffre a \xe9t\xe9 enregistr\xe9e. Red\xe9marrez le serveur Kronosys pour continuer. L’interface reste verrouill\xe9e jusqu’alors.",dataEnvironmentSwitchLockBackdropAriaLocked:"Application verrouill\xe9e : red\xe9marrez le serveur Kronosys pour appliquer le coffre",dataEnvironmentQaSeedTitle:"Configurer le coffre QA",dataEnvironmentQaSeedMessage:"C’est votre premi\xe8re bascule vers le coffre QA. Choisissez comment l’initialiser :\n\n• Copier la production — duplique vos sessions et t\xe2ches actuelles dans QA (la production n’est pas modifi\xe9e).\n• Partir \xe0 z\xe9ro — coffre vide isol\xe9 pour tests et essais.",dataEnvironmentQaSeedCopyBtn:"Copier les donn\xe9es de production",dataEnvironmentQaSeedEmptyBtn:"Partir \xe0 z\xe9ro",dataEnvironmentQaSeedRequiredError:"Indiquez si vous copiez la production ou si vous partez d’un coffre QA vide.",dataEnvironmentQaSeedProductionMissingError:"Aucun fichier de donn\xe9es en production ; choisissez \xab Partir \xe0 z\xe9ro \xbb ou ajoutez d’abord des donn\xe9es en production.",appShellUtilityToolbarGroupAria:"Affichage et langue",globalPauseConfirmTitle:"Pause globale",globalPauseConfirmIntro:"La pause globale fige l’horloge murale de la session si elle tourne encore, met en pause chaque minuteur de t\xe2che qui ne l’est pas d\xe9j\xe0 et arr\xeate tout minuteur de sous-t\xe2che actif (en consolidant le temps \xe9coul\xe9). Le prochain clic sur ce contr\xf4le ne reprend que ce qui a \xe9t\xe9 fig\xe9 dans cette op\xe9ration.\n\nVoici ce qui sera concern\xe9 :",globalPauseConfirmSessionHeading:"Session",globalPauseConfirmSummaryHeading:"R\xe9sum\xe9",globalPauseConfirmSummaryStart:"D\xe9but",globalPauseConfirmSummaryEnd:"Fin",globalPauseConfirmSummaryEndOngoing:"En cours (pas encore de fin)",globalPauseConfirmSummaryWallDuration:"Dur\xe9e murale",globalPauseConfirmSummaryTasks:"T\xe2ches",globalPauseConfirmSummarySubtasks:"Sous-t\xe2ches",globalPauseConfirmSummaryMainTimer:"Minuteurs des t\xe2ches (hors sous-t\xe2ches)",globalPauseConfirmSummarySubtaskTimers:"Minuteurs des sous-t\xe2ches",globalPauseConfirmSummaryCodingSession:"Temps de codage (session)",globalPauseConfirmSummaryActiveSession:"Temps actif (session)",globalPauseConfirmSummaryTaskTimersTotal:"Total enregistr\xe9 (minuteurs t\xe2ches)",globalPauseConfirmSummaryUnknownInstant:"—",globalPauseConfirmSessionWallWillPause:"L’horloge murale de cette session sera mise en pause.",globalPauseConfirmSessionWallAlreadyPaused:"L’horloge murale est d\xe9j\xe0 en pause ; elle demeure fig\xe9e.",globalPauseConfirmTasksHeading:"T\xe2ches et sous-t\xe2ches",globalPauseConfirmNoTaskEffects:"Aucun minuteur de t\xe2che ou de sous-t\xe2che \xe0 figer dans l’\xe9tat actuel.",globalPauseConfirmEffectMainTimer:"Le minuteur principal de la t\xe2che sera mis en pause.",globalPauseConfirmEffectSubtaskStop:"Arr\xeat du minuteur de sous-t\xe2che \xab {title} \xbb (temps enregistr\xe9).",globalPauseConfirmConfirmBtn:"Mettre en pause",appShellLiveDrawerAria:"Activit\xe9 de la session en cours",appShellLiveDrawerTitle:"En cours",appShellLiveDrawerOpenDashboard:"Ouvrir le tableau de bord",appShellLiveDrawerSessionPaused:"Session en pause",appShellLiveDrawerWallClock:"Temps mural",appShellLiveDrawerTasksHeading:"Minuteurs",appShellLiveDrawerKronoFocusRunning:"En marche",appShellLiveDrawerKronoFocusPaused:"En pause",appShellLiveDrawerKronoFocusPhaseWork:"Travail",appShellLiveDrawerSubtaskTracking:"Sous-t\xe2che",appShellLiveDrawerExpand:"D\xe9ployer le panneau",appShellLiveDrawerCollapse:"Replier le panneau",appShellLiveDrawerNoRunningTasks:"Aucune t\xe2che au minuteur.",dashboardSideDrawerSessionsAria:"Panneau Sessions",dashboardSideDrawerTagsAria:"Panneau \xc9tiquettes et projets",dashboardTaskLauncherDrawerAria:"Lanceur de saisie de t\xe2che",dashboardTaskLauncherDrawerExpand:"D\xe9ployer le lanceur",dashboardTaskLauncherDrawerCollapse:"Replier le lanceur",brandTagline:"La relativit\xe9 du temps productif",appVersionAriaLabel:"Version du paquet du tableau de bord Kronosys : {version}.",dialogOkBtn:"OK",dialogCancelBtn:"Annuler",dialogConfirmBtn:"Confirmer",pageRefreshTitle:"Rafra\xeechir les donn\xe9es",pageRefreshAriaLabel:"Actualiser les donn\xe9es de cette page sans recharger tout le navigateur",pageRefreshProgressLabel:"Synchronisation avec le serveur Kronosys…",pageRefreshDoneToast:"Donn\xe9es recharg\xe9es depuis le serveur Kronosys",pageRefreshFailedToast:"Impossible de recharger les donn\xe9es. V\xe9rifiez que le serveur Kronosys tourne et r\xe9essayez."};function f(a){return"fr"===a?e:d}function g(a,b,c){return"fr"===c?a>1?b.tasksInSessionPlural:b.tasksInSessionSingular:1===a?b.tasksInSessionSingular:b.tasksInSessionPlural}},62576:(a,b,c)=>{"use strict";c.d(b,{KronosysPackageVersionProvider:()=>g,a:()=>h});var d=c(48249),e=c(67484);let f=(0,e.createContext)("0.0.0");function g({version:a,children:b}){return(0,d.jsx)(f.Provider,{value:a,children:b})}function h(){return(0,e.useContext)(f)}},65126:(a,b,c)=>{Promise.resolve().then(c.t.bind(c,81921,23))},65529:(a,b,c)=>{"use strict";c.d(b,{M:()=>f});let d={pageTitle:"User stories — \xe9tat d’impl\xe9mentation",pageSubtitle:"Liste exhaustive des intentions utilisateur\xb7rice\xb7s : chaque ligne indique si la capacit\xe9 est livr\xe9e (✓) ou absente / hors p\xe9rim\xe8tre (✗). Les cases \xe0 droite servent \xe0 cocher une ligne \xab revue \xbb sur cet appareil — le d\xe9tail technique long reste dans le d\xe9p\xf4t.",statusKeyLine:"✓ vert = impl\xe9ment\xe9 dans le produit \xb7 ✗ rouge = non livr\xe9 ou volontairement exclu.",lastUpdated:"Derni\xe8re mise \xe0 jour : 2026-05-19 (v1.0.0-beta.27)",repositoryDocLabel:"Documents d\xe9p\xf4t : docs/README.md (index), docs/IMPLEMENTATION_DETAILS.md",storyGroupsHeading:"Inventaire des user stories",implementationColumnLabel:"Impl\xe9mentation",storyColumnLabel:"User story",integrationColumnLabel:"Int\xe9gration",e2eColumnLabel:"E2E",openChangelogAria:"Ouvrir le changelog usager",openChangelogTooltip:"Ouvrir le changelog",storyDetailsToggleExpand:"Afficher pr\xe9cisions et exemple",storyDetailsToggleCollapse:"Masquer pr\xe9cisions et exemple",storyDetailExampleLabel:"Exemple :",storyExpandHintLine:"Certaines lignes ont un chevron : ouvrez-les pour une pr\xe9cision et un exemple en police r\xe9duite.",storyDiscardedBadge:"\xc9cart\xe9",storyDiscardedLegendLine:"Les lignes marqu\xe9es \xab \xc9cart\xe9 \xbb documentent une intention volontairement abandonn\xe9e ; elles restent dans la liste pour \xe9viter qu’on rouvre le m\xeame d\xe9bat par inadvertance.",storyGroups:[{id:"us-shell",title:"Coque, navigation, confort",lead:"Barre d’outils commune, pages principales, th\xe8me et langue.",stories:[{implemented:!0,text:"Naviguer entre tableau de bord, guide, rapports, param\xe8tres et cette page depuis les ic\xf4nes du haut.",detail:"Les destinations couvrent le tableau de bord, les rapports (graphiques), les param\xe8tres, le guide in-app, cette page d’impl\xe9mentation, les journaux d’actions, les licences et le changelog usager ; les ic\xf4nes sont regroup\xe9es dans la barre d’outils.",example:"Sur le tableau de bord, cliquer l’ic\xf4ne livre ouvre /guide tout en conservant le param\xe8tre de session (?session=) lorsqu’il est pr\xe9sent."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Consulter le journal des actions enregistr\xe9es c\xf4t\xe9 serveur (type, succ\xe8s, date, session).",detail:"**1.0.0-beta.26** — `server/userActionLog.ts` ; journalisation depuis `app/api/action/route.ts` ; `GET /api/action-logs` ; page `/logs` ; purge `clearUserActionLogs`."},{implemented:!0,text:"Voir une horloge murale continue dans la barre d’outils (fuseau et format 12/24 h des param\xe8tres tableau de bord web)."},{implemented:!0,text:"Pour une livraison donn\xe9e (p. ex. 1.0.0-beta.27), valider le comportement en croisant la section correspondante du **CHANGELOG**, les r\xe9cits marqu\xe9s livr\xe9s sur cette page et `docs/IMPLEMENTATION_DETAILS.md`, puis cocher au besoin **int\xe9gration** / **E2E**.",detail:"**1.0.0-beta.27** — index `docs/README.md` ; API et cartographie dans `docs/IMPLEMENTATION_DETAILS.md` ; JSDoc sur le noyau serveur et les routes `app/api/*`."},{implemented:!0,text:"Ouvrir la page Licences depuis l’ic\xf4ne document lorsque je suis d\xe9j\xe0 sur Licences."},{implemented:!0,text:"Basculer entre th\xe8me clair et sombre pour le confort visuel."},{implemented:!0,text:"Actualiser l’\xe9tat serveur sans recharger toute l’application."},{implemented:!0,text:"Choisir la langue d’interface (FR / EN) avec pr\xe9f\xe9rence pouvant \xeatre m\xe9moris\xe9e."},{implemented:!0,text:"Conserver le param\xe8tre de session du tableau de bord (?session=) quand je passe d’une route \xe0 l’autre."}]},{id:"us-sessions",title:"Sessions — cadre, horloge murale, pause, fin",stories:[{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Cr\xe9er une nouvelle session maintenant (lancement imm\xe9diat) et la voir appara\xeetre dans la liste des sessions.",detail:"La modale \xab Nouvelle session \xbb propose le timing \xab Maintenant \xbb ; apr\xe8s confirmation, la ligne appara\xeet dans la colonne Sessions avec l’\xe9tat live.",example:"Nouvelle session → \xab D\xe9marrer la session \xbb : une ligne \xab Live \xbb remonte en t\xeate de liste avec l’heure de d\xe9but."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Cr\xe9er une session pass\xe9e en saisissant le d\xe9but et la fin (heure locale), puis la voir appara\xeetre dans la liste des sessions.",detail:"Le mode \xab Dans le pass\xe9 \xbb impose d\xe9but et fin en heure locale ; l’intervalle ferm\xe9 est historis\xe9 sans n\xe9cessairement arr\xeater une session d\xe9j\xe0 ouverte.",example:"Hier 14:00–16:00 : une ligne termin\xe9e s’affiche avec ces bornes pendant qu’une autre session peut rester active."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Cr\xe9er une session sans limite optionnelle (ni dur\xe9e max, ni fen\xeatre calendrier, ni jours/plage horaire).",detail:"La port\xe9e \xab Aucune limite \xbb \xe9vite tout plafond mural, toute fen\xeatre calendaire et tout gabarit hebdomadaire pour cette session.",example:"Laisser \xab Aucune limite \xbb puis d\xe9marrer : seuls des rappels ult\xe9rieurs (collecteur / banni\xe8res) peuvent signaler un d\xe9rapage."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Encadrer une session par une dur\xe9e maximale d’horloge murale (rappel de cadre).",detail:"La dur\xe9e maximale s’exprime en heures de mur accumul\xe9 ; l’interface peut signaler le d\xe9passement ou le voisinage du seuil selon les param\xe8tres.",example:"4 h max : au-del\xe0, la dur\xe9e affich\xe9e peut passer en alerte visuelle (couleur ou clignotement lent)."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"D\xe9finir une fen\xeatre calendrier (dates de d\xe9but et de fin) pour une session.",detail:"Les dates \xab Du \xbb et \xab Au \xbb sont inclusives dans le fuseau / affichage local du tableau de bord ; elles encadrent la session pour les rappels.",example:"Du 3 au 10 du mois pour une s\xe9rie de s\xe9ances dans une m\xeame fen\xeatre contractuelle."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"D\xe9finir une semaine avec jours choisis et plage horaire.",detail:"On coche les jours actifs et, au besoin, une fen\xeatre horaire quotidienne ; les fen\xeatres overnight (ex. 22:00–06:00) sont prises en charge.",example:"Mar/Jeu + 18:30–21:00 pour des cr\xe9neaux fixes apr\xe8s la journ\xe9e bureau."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Utiliser les raccourcis \xab Aujourd’hui \xbb / \xab Maintenant \xbb dans les s\xe9lecteurs de dates et heures.",detail:"Les boutons posent la date du jour ou l’instant courant dans les champs de la modale sans saisie compl\xe8te.",example:"\xab Aujourd’hui \xbb sur une date \xab Du \xbb ; \xab Maintenant \xbb comme fin d’une session pass\xe9e qui vient de se terminer."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Voir la dur\xe9e de session suivre une horloge murale (temps r\xe9el) tant que la session est vivante et non en pause session.",detail:"La carte session affiche une dur\xe9e murale qui avance tant que la session n’est ni termin\xe9e ni en pause session (pause murale).",example:"Sans pause session, la ligne \xab Dur\xe9e \xbb suit la seconde ; \xab Pause session \xbb fige l’affichage jusqu’\xe0 reprise."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Mettre la session en pause : le mur cesse de s’accumuler sans confondre avec la pause d’une t\xe2che.",detail:"La pause session agit sur le mur collecteur ; le serveur peut aussi figer les minuteurs de t\xe2ches et sous-t\xe2ches actifs via un instantan\xe9 `sessionPauseContext` (reprise cibl\xe9e). La pause d’une t\xe2che seule reste sur la carte et n’est pas synonyme de pause globale.",example:"Pause session → bandeau \xab Session en pause \xbb ; une t\xe2che peut encore avoir \xe9t\xe9 laiss\xe9e en pause manuelle avant la pause session."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"D\xe9clencher une pause globale avec une modale de confirmation qui r\xe9sume effets, dur\xe9es et p\xe9rim\xe8tre.",detail:"La pause globale aligne la session live, les minuteurs de t\xe2ches et les sous-t\xe2ches concern\xe9es ; la modale affiche un r\xe9sum\xe9 (mur, temps enregistr\xe9s, volumes) avant d’appliquer ou d’annuler.",example:"Barre d’outils → contr\xf4le \xab Pause session, t\xe2ches et sous-t\xe2ches dans ce contexte \xbb → lecture du r\xe9sum\xe9 → \xab Pause maintenant \xbb ou retour en arri\xe8re."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Quand la session live est en pause (murale ou pause globale), reconna\xeetre l’\xe9tat sur la carte Session en cours (pastille), voir un rappel central sur fond voil\xe9 tout en gardant la barre du haut utilisable, et rep\xe9rer le bouton de reprise de pause globale mis en \xe9vidence lorsque la pause globale est active.",detail:"Serveur : `setPaused` enregistre `sessionPauseContext` pour les minuteurs actifs et ne restaure \xe0 la reprise que ce gel ; une entr\xe9e en pause globale efface tout `sessionPauseContext` r\xe9siduel. UI : pastilles \xab En pause \xbb / \xab Pause globale \xbb (`SelectedSessionSidebarBlock.tsx`), overlay plein \xe9cran `DashboardPauseBackdrop` sous l’en-t\xeate (`z-40` vs `z-50`), anneau ambre sur le contr\xf4le pause globale lorsqu’il affiche lecture (`AppShellRouteNav.tsx`).",example:"Apr\xe8s pause globale : pastille \xab Pause globale \xbb, voile \xab Pause globale active \xbb, bouton lecture cercl\xe9 dans la barre d’outils."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Terminer une session avec une raison de cl\xf4ture facultative (dans les temps, avance, d\xe9passement, autre + note).",detail:"La modale de fin propose cat\xe9gories facultatives et une note libre ; elles sont attach\xe9es \xe0 l’instantan\xe9 d’historique avec l’heure de fin courante.",example:"\xab Fin anticip\xe9e \xbb + \xab livraison report\xe9e \xbb puis \xab Terminer la session \xbb depuis la barre lat\xe9rale ou la liste."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Ajouter une note libre \xe0 une session et la revoir dans la barre lat\xe9rale de session.",detail:"Le champ \xab Note de session \xbb se trouve dans la carte session (colonne Sessions). La valeur est envoy\xe9e au serveur lorsque le champ perd le focus et reste visible apr\xe8s rechargement.",example:"Saisir \xab Point revue client — pr\xe9parer d\xe9mo \xbb avant une r\xe9union pour retrouver le contexte dans la m\xeame carte."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Voir un aper\xe7u de note de session (ic\xf4ne + extrait) dans la liste des sessions et dans la liste des archives.",detail:"Quand une note existe, la liste affiche une ic\xf4ne et un extrait tronqu\xe9 \xe0 c\xf4t\xe9 du titre de session ; m\xeame logique pour les entr\xe9es archiv\xe9es pertinentes.",example:"Une ligne montre \xab …compte-rendu… \xbb sous le nom lorsque la note contient ce texte."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Voir la session live mise en \xe9vidence lorsque l’heure de d\xe9but officielle est encore dans le futur (cercle d’\xe9tat et fond distincts dans la liste).",detail:"Tant que l’horloge r\xe9elle n’a pas atteint le d\xe9but officiel enregistr\xe9, la ligne live garde un style \xab pas encore d\xe9marr\xe9e \xbb (point et fond diff\xe9rents).",example:"Session \xe9tiquet\xe9e pour 18:00 alors qu’il est 14:00 : la ligne reste visuellement distincte jusqu’\xe0 18:00."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Programmer une heure de fin sur une session live : la session se termine automatiquement \xe0 l’\xe9ch\xe9ance (instantan\xe9 en historique).",detail:"Une \xe9ch\xe9ance de fin session peut \xeatre d\xe9finie ; au passage de l’instant programm\xe9, la session est cl\xf4tur\xe9e : le mur est consolid\xe9 jusqu’\xe0 cette heure, les t\xe2ches ouvertes sont fig\xe9es comme apr\xe8s une fin de session en mode conserver, sans modale de cl\xf4ture.",example:"Fin \xe0 17:00 : sans clic suppl\xe9mentaire, la session live devient une ligne d’historique \xe0 17:00 si elle est encore ouverte."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"\xc0 la fermeture d’une session avec t\xe2ches encore ouvertes, choisir de les terminer ou de les transposer vers une nouvelle session en pause.",detail:"La modale de fin liste les t\xe2ches non termin\xe9es et propose de les laisser dans l’instantan\xe9 (choix par d\xe9faut, \xe9quivalent \xab conserver \xbb), de les marquer termin\xe9es ou de les d\xe9placer vers une nouvelle session cr\xe9\xe9e en pause. \xc0 distinguer : une fin automatique \xe0 l’heure planifi\xe9e (`scheduledEndAt`) ne passe pas par cette modale ; c\xf4t\xe9 donn\xe9es, le comportement correspond \xe0 conserver les t\xe2ches ouvertes dans l’instantan\xe9 (minuteurs fig\xe9s), comme le premier choix de la modale. Un r\xe9glage produit pour imposer un autre mode par d\xe9faut \xe0 l’\xe9ch\xe9ance n’est pas livr\xe9 dans cette version.",example:"\xab Transposer vers une nouvelle session en pause \xbb pour reporter un lot de correctifs sans tout fermer au m\xeame titre."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Reprendre une session en pause depuis le bandeau ; reprendre une t\xe2che relance aussi l’accumulation du mur.",detail:"Le bandeau \xab Session en pause \xbb offre la reprise ; lorsqu’une t\xe2che repasse en suivi actif selon les r\xe8gles du dashboard, le mur peut \xe0 nouveau s’accumuler.",example:"Reprendre depuis le bandeau puis lancer une t\xe2che : la dur\xe9e murale augmente \xe0 nouveau."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Configurer un gabarit de nom de session initial (codes date/heure, %UUID, fuseau align\xe9 sur le tableau de bord).",detail:"Sous Param\xe8tres → tableau de bord, un mod\xe8le de nom peut r\xe9f\xe9rencer la date, l’heure, un UUID court ou le fuseau utilis\xe9 pour l’affichage.",example:"\xab Session %Y-%m-%d \xbb produit \xab Session 2026-05-08 \xbb \xe0 chaque cr\xe9ation."},{discarded:!0,implemented:!1,text:"Disposer d’une seule action \xab pause \xbb identique qui applique le m\xeame effet au mur de session et \xe0 tous les minuteurs comme une primitive unique.",detail:"D\xe9cision : \xe9cart\xe9e. La pause globale couvre d\xe9j\xe0 le gel coordonn\xe9 du mur et des minuteurs du contexte affich\xe9 ; la pause minuteur par t\xe2che reste un r\xe9glage fin volontairement s\xe9par\xe9.",example:"Ne pas fusionner en un seul bouton universel : conserver la pause globale (barre d’outils) et les pauses cibl\xe9es selon l’intention."},{discarded:!0,implemented:!1,text:"Obtenir la dur\xe9e murale de session comme somme automatique des dur\xe9es enregistr\xe9es des t\xe2ches.",detail:"D\xe9cision : \xe9cart\xe9e. Le mur suit des segments collecteur ; les totaux t\xe2che sont agr\xe9g\xe9s \xe0 part dans les m\xe9triques et rapports.",example:"Comparer carte session et colonne T\xe2ches : les deux lectures peuvent diverger — c’est attendu."}]},{id:"us-tasks",title:"T\xe2ches, \xe9tiquettes, projets, minuteurs",stories:[{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Cr\xe9er une t\xe2che avec titre et utiliser # pour \xe9tiquettes, @ pour projets productifs et ! pour projets personnels, avec aide \xe0 la saisie.",detail:"Le champ \xab sur quoi travaillez-vous \xbb accepte dans le libell\xe9 des jetons #\xe9tiquette, @projet (travail) et !projet (personnel) ; ils sont interpr\xe9t\xe9s au lancement (`startTask`), alimentent les listes d’\xe9tiquettes, `knownProjects` / `knownPersonalProjects`, et s’affichent sur la carte t\xe2che. Depuis **1.0.0-beta.21**, le **`!`** peut \xeatre **coll\xe9** au mot pr\xe9c\xe9dent (sans espace), comme certaines formes de **`#`** — ex. `Courrier!perso#dentiste` ; le **`@`** reste en g\xe9n\xe9ral apr\xe8s **espace** ou en **d\xe9but** de segment pour limiter les faux positifs sur les courriels. Depuis **1.0.0-beta.26**, une **liste d\xe9roulante** (`lib/taskEntryTokenSuggest.ts`, `TaskEntryInputWithTokenSuggest`) propose les jetons **les plus utilis\xe9s** puis **les plus r\xe9cents** d\xe8s que `#`, `@` ou `!` est actif (y compris en \xe9dition de titre) ; les **mod\xe8les** (\xab Mod\xe8le : \xbb, `datalist`) restent en parall\xe8le.",example:"Taper \xab #bu \xbb : la liste propose `bugfix` si c’est l’\xe9tiquette la plus fr\xe9quente ; choisir puis `@mo` pour le projet `mobile` ; lancer le suivi — pastilles et listes connues se mettent \xe0 jour."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"D\xe9clarer un projet personnel avec le jeton `!` (temps de suivi distinct des projets `@`), y compris en t\xe2che pass\xe9e, au renommage c\xf4t\xe9 serveur et dans les mod\xe8les de t\xe2che.",detail:"`lib/taskParsing.ts` (`parseTaskWithAutoTags`, `buildStartTaskFromDraft`, `formatProjectDisplay`, jetons `!p#t`) ; persistance `personalProject` sur les t\xe2ches et `knownPersonalProjects` sur le payload ; `server/actionDispatch.ts` et `server/actionTaskSession.ts` (`startTask`, `addHistoricalTask`, `updateTask`, `saveTaskTemplate`, `renameProjectMetadata` avec `personalOnly` c\xf4t\xe9 API) ; UI : `TaskFocusPanel`, `TaskSessionLiveCard`, `SavedProjectPicker`, `taskFieldStyles` (pastilles rose). Tests unitaires : `lib/taskTemplateDraft.test.ts` (mod\xe8les `!`).",example:"\xab Lecture !perso \xbb en session live : la carte affiche le projet en rose ; enregistrer comme mod\xe8le conserve `!perso` dans Param\xe8tres → Mod\xe8les de t\xe2che."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Utiliser des \xe9tiquettes sous port\xe9e projet personnel au format `!projet#sous-\xe9tiquette` (\xe9quivalent de `@projet#code` pour le travail).",detail:"`TagPills`, `formatTagDisplayForTask` et le parsing scoped dans `lib/taskParsing.ts` propagent le contexte `personalProject` pour l’affichage. Le jeton **`!`** de port\xe9e peut \xeatre **coll\xe9** au mot pr\xe9c\xe9dent (**1.0.0-beta.21**, `findProjectTokens`).",example:"\xab Suivi !dentiste#urgent \xbb : l’\xe9tiquette scoped s’affiche avec le pr\xe9fixe `!`."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Sur la modale Gantt d’une t\xe2che, distinguer le temps productif (`@`) et le temps personnel (`!`) : barres de couleurs diff\xe9rentes et totaux s\xe9par\xe9s.",detail:"`lib/taskTimelineGantt.ts`, `components/dashboard/TaskTimelineGanttModal.tsx`, cha\xeenes `lib/dashboardCopy.ts` (l\xe9gende et r\xe9sum\xe9s productif / personnel)."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"D\xe9marrer, mettre en pause et terminer le minuteur d’une t\xe2che ind\xe9pendamment du mur de session.",detail:"Le cycle du minuteur sur une t\xe2che (d\xe9marrage, pause volontaire sur la ligne, fin) est distinct du temps mural : la pause ou la reprise du mur de session (`setPaused`) ne se confond pas avec la pause du minuteur d’une t\xe2che (`setTaskTimerPaused` / reprise) ; les segments et contextes c\xf4t\xe9 serveur gardent cette s\xe9paration. Un sc\xe9nario Playwright clique sur la pause depuis la carte et v\xe9rifie le passage en \xab Reprendre \xbb (`e2e/task-lifecycle.spec.ts`).",example:"Mettre une t\xe2che en pause depuis sa carte puis reprendre uniquement la session : le minuteur de cette t\xe2che reste en pause jusqu’\xe0 une reprise explicite sur la ligne. \xab Terminer \xbb depuis la carte enregistre la fin du suivi pour cette t\xe2che."},{implemented:!0,text:"Lorsqu’un autre minuteur tourne, choisir pause, fin ou parall\xe9lisme et m\xe9moriser le choix pour les prochains lancements."},{implemented:!0,text:"Ajouter des sous-t\xe2ches, les cocher et les r\xe9ordonner par glisser-d\xe9poser."},{implemented:!0,text:"Enregistrer un mod\xe8le de t\xe2che depuis une t\xe2che en cours, en pause ou termin\xe9e, le g\xe9rer dans Param\xe8tres, et le retrouver (saisie avec debounce, suggestions \xab Mod\xe8le : \xbb, palette Ctrl+K), y compris avec projet personnel `!`.",detail:"`saveTaskTemplate` enregistre `personalProject` ; `lib/taskTemplateDraft.ts` (`formatTaskTemplateDraftLine`, `parseTaskTemplatesFromPayload`, `buildTaskTemplateSignature` avec segment travail/personnel) ; `SettingsTaskTemplatesSection.tsx`."},{implemented:!0,text:"Saisir une t\xe2che en direct ou la reporter dans le pass\xe9 avec d\xe9but et fin explicites."},{implemented:!0,text:"Ajouter une note libre sur une t\xe2che (directe ou pass\xe9e) pour documenter le contexte de l’activit\xe9."},{implemented:!0,text:"Afficher la note de t\xe2che avant la liste des sous-t\xe2ches pour garder le contexte visible pendant le d\xe9coupage."},{implemented:!0,text:"Corriger les bornes temporelles d’une t\xe2che en choisissant de conserver la dur\xe9e syst\xe8me, une dur\xe9e manuelle ou un recalcul depuis d\xe9but/fin."},{implemented:!0,text:"Voir les t\xe2ches dont le d\xe9but (non termin\xe9e) est encore dans le futur regroup\xe9es sous \xab Planifi\xe9es \xbb avec un style distinct, sans minuteur \xab en direct \xbb ni apparence \xab termin\xe9e barr\xe9e \xbb pr\xe9matur\xe9e ; pour une t\xe2che termin\xe9e, le m\xeame affichage \xab planifi\xe9 \xbb seulement si d\xe9but et fin sont encore tous deux dans le futur."},{implemented:!0,text:"\xc0 l’heure de d\xe9but planifi\xe9e (`startTime`), voir le minuteur s’activer automatiquement (sans temps compt\xe9 avant cet instant) ; \xe0 l’heure de fin planifi\xe9e (`scheduledEndAt`), la t\xe2che se termine automatiquement.",detail:"`deferFutureStartMainTimersInSession`, `activateDuePlannedTaskTimersInSession` (`server/actionTaskSession.ts`) ; `materializeRunningMainTimersInPayload` (`server/mainTimerHydrate.ts`). Tests : `server/mainTimerHydrate.test.ts`."},{implemented:!0,text:"Recevoir un toast global (toute route) lorsqu’une t\xe2che planifi\xe9e ou une session live atteint son heure de d\xe9but officielle — titre ou nom rappel\xe9 dans le message.",detail:"`PlannedScheduleActivationWatcher` (`components/dashboard/PlannedScheduleActivationWatcher.tsx`), `lib/plannedScheduleActivation.ts` ; cha\xeenes `plannedTaskScheduleActivatedToast` / `plannedSessionScheduleActivatedToast` (`lib/dashboardCopy.ts`). Tests : `lib/plannedScheduleActivation.test.ts`."},{implemented:!0,text:"Lorsqu’une t\xe2che sort de \xab Planifi\xe9es \xbb et devient en cours alors qu’un autre minuteur tournait d\xe9j\xe0, r\xe9soudre pause / terminer / parall\xe8le sur les t\xe2ches d\xe9j\xe0 au minuteur (m\xeame pr\xe9f\xe9rence m\xe9moris\xe9e que pour un lancement manuel) et faire pulser l’ic\xf4ne Tableau de bord hors route pour signaler l’attention."},{implemented:!0,text:"Programmer une heure de fin sur une t\xe2che en cours : la t\xe2che se termine automatiquement \xe0 l’\xe9ch\xe9ance (carte pass\xe9e en termin\xe9e \xe0 cet instant)."},{implemented:!0,text:"Lancer KronoFocus depuis une t\xe2che pour alterner travail et pauses sans perdre le lien avec la t\xe2che."},{discarded:!0,implemented:!1,text:"Traiter en rapport le temps mur de session et le temps t\xe2che comme une seule mesure interchangeable sans les distinguer.",detail:"D\xe9cision : \xe9cart\xe9e. Les rapports et agr\xe9gats distinguent volontairement le temps mur (segments collecteur) du temps t\xe2che ; les deux lectures compl\xe8tent une analyse honn\xeate.",example:"Comparer les totaux \xab mur \xbb et \xab t\xe2che \xbb dans les vues reporting — les \xe9carts sont informatifs, pas des erreurs \xe0 effacer."}]},{id:"us-kronofocus",title:"KronoFocus",stories:[{implemented:!0,text:"Activer l’affichage du minuteur KronoFocus dans l’en-t\xeate et/ou pr\xe8s des actions de t\xe2che selon les r\xe9glages."},{implemented:!0,text:"Encha\xeener phases de travail, pause et longue pause avec dur\xe9e au format HH:MM:SS."},{implemented:!0,text:"R\xe9utiliser une dur\xe9e depuis l’historique des dur\xe9es r\xe9centes."},{implemented:!0,text:"Attacher le focus \xe0 la t\xe2che active pour retrouver le lien dans l’historique."}]},{id:"us-search-shortcuts",title:"Recherche dans les donn\xe9es et raccourcis",stories:[{implemented:!0,text:"Ouvrir la palette de recherche Spotlight (Ctrl+K / ⌘K) et filtrer sessions, t\xe2ches, mod\xe8les de t\xe2che, \xe9tiquettes et projets ; choisir un mod\xe8le remplit le brouillon nouvelle t\xe2che."},{implemented:!0,text:"Filtrer les rubriques du guide utilisateur sur /guide avec le champ en t\xeate de page."},{implemented:!0,text:"Consulter et personnaliser les raccourcis clavier du tableau de bord depuis la modale d\xe9di\xe9e."}]},{id:"us-reporting",title:"Rapports et agr\xe9gats",stories:[{implemented:!0,text:"Choisir une plage de dates avec pr\xe9r\xe9glages jour / semaine / mois / ann\xe9e selon ce que l’interface expose."},{implemented:!0,text:"Restreindre les vues par une ou plusieurs \xe9tiquettes lorsque les donn\xe9es sont bas\xe9es sur les t\xe2ches."},{implemented:!0,text:"Lire r\xe9sum\xe9s, tableaux par jour, r\xe9partition par projet et par \xe9tiquette."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Sur la page Rapports, basculer la grille hebdomadaire par projet entre le registre travail (@) et le registre personnel (!) avec les m\xeames filtres de plage et d’\xe9tiquettes.",detail:"**1.0.0-beta.26** — `app/reporting/page.tsx` appelle `aggregateProjectTaskMinutesByDay` avec le scope `work` ou `personal` selon le s\xe9lecteur (`lib/reportingAggregate.ts`, `taskMatchesReportingProjectScope`, `taskIsReportingPersonalLedger`). La vue **Travail** (d\xe9faut) exclut le registre personnel ; la vue **Personnel** ne l’inclut qu’elles, avec libell\xe9s `!` via `formatProjectDisplay`. Une t\xe2che est **personnelle** pour l’agr\xe9gat si `personalProject` est vrai **ou** si le **titre** contient un jeton `!` reconnu (repli lorsque le drapeau manque sur d’anciennes donn\xe9es)."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Consulter par d\xe9faut les grilles par projet en temps productif (@) sans y m\xe9langer le temps des projets personnels (!).",detail:"Au chargement, le s\xe9lecteur est sur **Travail (@)** : m\xeame comportement qu’auparavant (scope `work` seul)."},{implemented:!0,text:"Voir un total de temps t\xe2che non concurrent (fusion des chevauchements) par jour pour comparaison."},{implemented:!0,text:"Configurer le jour de d\xe9but de semaine pour les vues calendaires coh\xe9rentes avec mon organisation."},{implemented:!0,text:"Relancer la visite guid\xe9e des rapports depuis les param\xe8tres."},{implemented:!0,text:"Lorsque l’environnement fournit une heure de d\xe9but pr\xe9vue, voir des indicateurs d’assiduit\xe9 / d’\xe9cart sur les sessions."},{implemented:!0,text:"Voir des signaux honn\xeates sur le travail encore non finalis\xe9 dans la plage s\xe9lectionn\xe9e."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Dans la liste sessions par jour (Rythme), chaque # sous une t\xe2che affiche la dur\xe9e enregistr\xe9e compl\xe8te de la t\xe2che (m\xeame r\xe8gle que les grilles d’allocation #), sans r\xe9partition \xe0 parts \xe9gales entre plusieurs \xe9tiquettes.",detail:"`buildTaskTagSlicesFullDuration` dans `lib/reportingAggregate.ts` ; affichage `app/reporting/page.tsx` (ventilation par #). Tests : `lib/reportingAggregate.test.ts`."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Les totaux et graphiques des rapports n’incluent que le temps r\xe9ellement enregistr\xe9 ; le cr\xe9neau planifi\xe9 (t\xe2che encore dans le futur) s’affiche \xe0 part sans alimenter les agr\xe9gats enregistr\xe9s.",detail:"`isTaskDisplayPlanned` (`lib/temporalDisplayPlanned.ts`) exclu de `aggregateReporting` ; `plannedMinutes` / libell\xe9 ambre dans la liste sessions/jour (`app/reporting/page.tsx`, `lib/reportingStrings.ts`). Tests : `lib/reportingAggregate.test.ts`."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Sur les calendriers hebdomadaires # et @, lire une ligne Total jour en bas de chaque semaine (somme par jour et total de semaine).",detail:"`sumWeekCalendarSlots` (`lib/reportingWeekLayout.ts`) ; pied de tableau `WeekCalendarDayTotalsFoot` dans `app/reporting/page.tsx`. Tests : `lib/reportingWeekLayout.test.ts`."}]},{id:"us-settings-data",title:"Param\xe8tres, export, int\xe9grations, danger",stories:[{implemented:!0,text:"Adapter le profil d’usage pour masquer des blocs peu pertinents (ex. lignes de code pour un profil non d\xe9veloppeur)."},{implemented:!0,text:"Configurer horaire de travail, sessions planifi\xe9es, collecte et tampons."},{implemented:!0,text:"G\xe9rer \xe9tiquettes avanc\xe9es et migration d’\xe9tiquettes entre port\xe9e globale et port\xe9e projet."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Renommer une \xe9tiquette ou un projet en inline (crayon, saisie directe, Entr\xe9e/\xc9chap), avec avertissement d’impact reporting et option \xab ne plus afficher \xbb.",detail:"Propagation serveur : `renameTagEverywhere` / `renameProjectEverywhere` — tests `server/actionTaskSession.test.ts` ; pas de parcours E2E Param\xe8tres d\xe9di\xe9."},{implemented:!1,text:"G\xe9rer et renommer depuis Param\xe8tres la liste des projets personnels connus (`knownPersonalProjects`, jetons `!`) de la m\xeame fa\xe7on que les projets `@`.",detail:"Le payload et les actions serveur maintiennent `knownPersonalProjects` et `renameProjectMetadata` avec `personalOnly` ; la section Projets / \xe9tiquettes avanc\xe9es n’expose pas encore d’inline d\xe9di\xe9 aux `!` au 2026-05-12."},{implemented:!0,text:"Activer des commutateurs de correction d’horodatage pour les bornes de t\xe2ches et de sessions."},{implemented:!0,text:"Brancher Git et MongoDB de fa\xe7on opt-in."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Obtenir une sauvegarde via l’API d’export et les options pr\xe9vues dans l’interface.",detail:"Tests : `test/integration/apiBackup.test.ts` (export sqlite + aller-retour restore)."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Effacer l’historique dans une zone dangereuse prot\xe9g\xe9e par confirmation explicite.",detail:"Tests : `server/actionDispatch.test.ts` (`clearHistory`) ; `test/integration/apiActionLogs.test.ts`."},{implemented:!0,text:"En d\xe9veloppement local (next dev), utiliser un coffre de donn\xe9es distinct et optionnellement partag\xe9 avec la prod."},{implemented:!0,text:"Activer deux coffres SQLite (production `v4` et QA `v4-qa`), basculer depuis la navigation (Prod / QA) et afficher un rep\xe8re visuel fort en mode QA.",detail:"**1.0.0-beta.26** — `lib/dataEnvironmentPreferenceFile.ts`, `lib/dataDir.ts`, `switchDataEnvironment` avec `qaSeed` (`copy_production` | `empty` si `v4-qa` absent), `dataEnvironmentRuntime` sur `/api/state`, `DataEnvironmentSwitchProvider`, `AppShellHeaderDataEnvironmentChip`, `DataEnvironmentChrome` ; red\xe9marrage serveur requis. D\xe9sactiv\xe9 si `TRACE_DATA_DIR` est d\xe9fini."},{implemented:!0,text:"Configurer le Web, l’API et la relance de visites guid\xe9es depuis les param\xe8tres."}]},{id:"us-architecture-quality",title:"Architecture, qualit\xe9, documentation",stories:[{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"B\xe9n\xe9ficier de mutations qui passent par un point d’entr\xe9e serveur unique pour les invariants.",detail:"Couverture indirecte : `server/actionDispatch.test.ts`, `test/integration/apiAction*.test.ts`."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Recharger la page et retrouver l’\xe9tat depuis le payload JSON persist\xe9.",detail:"Tests : `server/payloadStore.test.ts` (read/write SQLite)."},{implemented:!0,text:"Disposer de cha\xeenes d’interface en fran\xe7ais et en anglais pour les surfaces visibles."},{implemented:!0,text:"S’appuyer sur une suite de tests de bout en bout Playwright pour les parcours critiques."},{implemented:!0,text:"Consulter cette liste de user stories sur /implementation pour suivre le p\xe9rim\xe8tre livr\xe9."},{implemented:!0,text:"Retrouver l’index de la documentation d\xe9p\xf4t et les contrats API document\xe9s pour les int\xe9grateurs.",detail:"**1.0.0-beta.27** — `docs/README.md` ; README racine (API HTTP) ; JSDoc `server/*` et `app/api/*`."},{implemented:!1,text:"Remplacer le guide utilisateur (/guide) par cette page pour apprendre le produit."}]}]},e={pageTitle:"User stories — implementation status",pageSubtitle:"An exhaustive list of user intentions: each row shows whether the capability is shipped (✓) or missing / out of scope (✗). Checkboxes on the right mark a row as reviewed on this device — long technical detail stays in the repo doc.",statusKeyLine:"Green ✓ = implemented in the product \xb7 Red ✗ = not shipped or intentionally excluded.",lastUpdated:"Last updated: 2026-05-19 (v1.0.0-beta.27)",repositoryDocLabel:"Repository docs: docs/README.md (index), docs/IMPLEMENTATION_DETAILS.md",storyGroupsHeading:"User story inventory",implementationColumnLabel:"Implementation",storyColumnLabel:"User story",integrationColumnLabel:"Integration",e2eColumnLabel:"E2E",openChangelogAria:"Open user changelog",openChangelogTooltip:"Open changelog",storyDetailsToggleExpand:"Show details and example",storyDetailsToggleCollapse:"Hide details and example",storyDetailExampleLabel:"Example:",storyExpandHintLine:"Some rows include a chevron — expand for extra detail and a smaller-type example.",storyDiscardedBadge:"Discarded",storyDiscardedLegendLine:"Rows tagged “Discarded” record intents we deliberately closed; they stay listed so the same debate does not reopen by mistake.",storyGroups:[{id:"us-shell",title:"Chrome, navigation, comfort",lead:"Shared toolbar, main routes, theme and language.",stories:[{implemented:!0,text:"Move between dashboard, guide, reporting, settings, and this page from the top icons.",detail:"Targets include the dashboard, reporting charts, settings, the in-app guide, this implementation page, action logs, licenses, and the user changelog; icons sit in the shared header toolbar.",example:"From the dashboard, clicking the book icon opens /guide while keeping the session query (?session=) when it is set."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Review server-recorded action history (type, success, timestamp, session).",detail:"**1.0.0-beta.26** — `server/userActionLog.ts`; logging from `app/api/action/route.ts`; `GET /api/action-logs`; `/logs` page; `clearUserActionLogs` purge."},{implemented:!0,text:"See a live-updating wall clock in the header toolbar (time zone and 12/24 h from web dashboard settings)."},{implemented:!0,text:"For a given release (e.g. 1.0.0-beta.27), cross-check the matching **CHANGELOG** section, the shipped stories on this page and `docs/IMPLEMENTATION_DETAILS.md`, then tick **Integration** / **E2E** as appropriate.",detail:"**1.0.0-beta.27** — `docs/README.md` index; API and repo map in `docs/IMPLEMENTATION_DETAILS.md`; JSDoc on server core and `app/api/*` routes."},{implemented:!0,text:"Open the Licenses page from the document icon when I am already on Licenses."},{implemented:!0,text:"Switch between light and dark theme for visual comfort."},{implemented:!0,text:"Refresh server state without reloading the whole app."},{implemented:!0,text:"Pick UI language (FR / EN) with an optional persisted preference."},{implemented:!0,text:"Keep the dashboard session query (?session=) when navigating between routes."}]},{id:"us-sessions",title:"Sessions — scope, wall clock, pause, end",stories:[{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Create a new session now (immediate start) and see it in the session list.",detail:"The New session modal offers Start now; after confirm, the row appears in the Sessions column as live.",example:"New session → Start session: a Live row appears at the top with your start time."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Create a past session by entering start and end (local time), then see it in the session list.",detail:"In the past mode requires both bounds in browser-local time; the closed interval is saved to history without necessarily stopping an already running session.",example:"Yesterday 2:00–4:00 pm — a completed row shows those bounds while another session can stay active."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Create a session with no optional limits (no max duration, no calendar window, no weekdays/time window).",detail:"No limit skips max wall duration, calendar bounds, and weekday/time-window scope for that session.",example:"Leave No limit checked and start — only later heartbeats/banners may warn if work runs long."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Cap a session with a maximum wall-clock duration (nudge to reframe).",detail:"Max duration is expressed in hours of accumulated wall time; the UI can warn when you approach or exceed the cap depending on settings.",example:"4 h max — beyond that, duration styling may turn alert (color or slow blink)."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Set a calendar window (start and end dates) for a session.",detail:"From / To dates are inclusive in your dashboard display timezone; they frame expectations for reminders.",example:"March 3–10 for a fixed delivery sprint window."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Define a week pattern with selected weekdays and a time window.",detail:"Pick active weekdays and optionally a daily time slot; overnight windows (e.g. 10:00 pm–6:00 am) are supported.",example:"Tue/Thu + 6:30–9:00 pm for after-hours sessions."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Use “Today” / “Now” shortcuts in date and time pickers.",detail:"Buttons stamp today’s date or the current instant into modal fields without full typing.",example:"Today on a From date; Now as the end of a past session that just finished."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"See session duration follow wall-clock time while the session is live and not session-paused.",detail:"The session card shows wall duration advancing while the session is neither ended nor session-paused.",example:"Without session pause, Duration ticks each second; session pause freezes display until resume."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Pause the session so wall time stops accruing, distinct from pausing a task timer.",detail:"Session pause targets the collector wall; the server may also freeze active task and subtask timers using a `sessionPauseContext` snapshot (selective restore). Task-only pause stays on the card and is not the same as global pause.",example:"Session pause → Live session paused banner; a task you left manually paused before session pause stays consistent with the snapshot rules."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Start a global pause with a confirmation modal summarizing effects, durations, and scope.",detail:"Global pause aligns the live session with affected task and subtask timers; the modal summarizes wall time, recorded times, and counts before you confirm or cancel.",example:"Toolbar → “Pause session, tasks, and subtasks in this context” → read the summary → “Pause now” or dismiss."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"When the live session is paused (wall-clock or global pause), recognize it on the Active session card (chip), see a centered reminder on a dimmed overlay while the top bar stays usable, and spot the global resume control highlighted when global pause is active.",detail:"Server: `setPaused` stores `sessionPauseContext` for active timers and restores only that snapshot on resume; starting global pause clears any leftover `sessionPauseContext`. UI: “Paused” / “Global pause” chips (`SelectedSessionSidebarBlock.tsx`), full-screen `DashboardPauseBackdrop` under the header (`z-40` vs `z-50`), amber ring on the global pause control when it shows play (`AppShellRouteNav.tsx`).",example:"After global pause: “Global pause” chip, “Global pause is on” overlay, circled play button in the toolbar."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"End a session with an optional closure reason (on time, early, overrun, other + note).",detail:"The end-session modal offers optional categories and a free-text note; both are stored on the history snapshot with the current end time.",example:"Ended early + “release slipped” then End session from the sidebar or row controls."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Add a free-text note to a session and review it in the session sidebar.",detail:"The “Session note” field lives in the session card (Sessions column). It is saved on blur and survives a full page reload.",example:"Type “Client review checkpoint — prep demo” before a meeting to keep context in the same card."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"See a session-note preview (icon + excerpt) in the sessions list and in archived sessions.",detail:"When a note exists, the list shows an icon and truncated excerpt next to the session title; archived rows follow the same pattern where applicable.",example:"A row shows “…stand-up notes…” under the title when that text is in the note."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"See the live session row highlighted when the official start time is still in the future (status dot and distinct row styling in the list).",detail:"Until real time reaches the recorded official start, the live row keeps a “not yet started” look (dot + background).",example:"Official start at 6:00 pm while it is 2:00 pm — styling stays distinct until 6:00 pm."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Schedule an end time on a live session so it automatically ends when the deadline is reached (snapshot moves to history).",detail:"You can set a scheduled session end time; when real time reaches it, the session closes: wall time is finalized up to that instant, open tasks are frozen like ending with keep (no closure modal).",example:"End at 5:00 pm — without extra clicks, the live session becomes a history row at 5:00 pm if it was still open."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"When closing a session with open tasks, finish them or move them to a new paused session.",detail:"The end-session modal lists unfinished work and lets you keep it in the snapshot (default, same semantics as leaving tasks open), finish it with this session, or move it into a newly created paused session. Contrast: a scheduled automatic end (`scheduledEndAt`) does not show this modal; server-side it matches keep (open tasks stay in the snapshot with timers stopped). A user preference to pick a different default at scheduled end is not shipped in this version.",example:"Move open tasks to a new paused session to carry a bugfix batch without closing every card."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Resume a paused session from the banner; resuming a task also resumes wall accumulation.",detail:"The Live session paused banner offers resume; when a task returns to active tracking under dashboard rules, wall time can accrue again.",example:"Resume from the banner then start a task — wall duration increases again."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Configure an initial session name template (date/time codes, %UUID, timezone aligned with the dashboard).",detail:"Under Settings → web dashboard, a name pattern can include date, time, short UUID, or the display timezone token.",example:"“Session %Y-%m-%d” becomes “Session 2026-05-08” on each create."},{discarded:!0,implemented:!1,text:"Have a single “pause” action that applies the same effect to wall time and all task timers as one primitive.",detail:"Decision: discarded. Global pause already freezes the wall and timers for the displayed context together; per-task pause stays a separate fine control on purpose.",example:"We keep global pause (toolbar) and targeted pauses instead of one universal button."},{discarded:!0,implemented:!1,text:"Get wall session duration as the automatic sum of recorded task durations.",detail:"Decision: discarded. Wall time follows collector segments; task totals are aggregated separately in metrics and reporting.",example:"Compare the session card with tasks — both views may differ; that is expected."}]},{id:"us-tasks",title:"Tasks, tags, projects, timers",stories:[{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Create a task with a title and use # for tags, @ for work projects, and ! for personal projects with typing assistance.",detail:"The “what are you working on” field accepts #tag, @project (work), and !project (personal) tokens in the title; they are parsed on start (`startTask`), feed known tag lists plus `knownProjects` / `knownPersonalProjects`, and render on the task card. Since **1.0.0-beta.21**, **`!`** may be **glued** to the previous word (no space), like some **`#`** forms — e.g. `Errands!me#dentist`; **`@`** still expects **leading whitespace** or **string start** so mid-token emails are not parsed as projects. Since **1.0.0-beta.26**, a **dropdown** (`lib/taskEntryTokenSuggest.ts`, `TaskEntryInputWithTokenSuggest`) ranks **most-used** then **recent** `#` / `@` / `!` choices while the token is active (including title edit); **templates** (“Template:”, `datalist`) remain alongside.",example:"Enter “Auth fixes #bugfix @mobile” or “Rest #rest !me”, start tracking: the project chip is sky or rose depending on the token; known lists update for the next picks."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Declare a personal project with the `!` token (tracking separate from `@` work projects), including past tasks, server rename paths, and task templates.",detail:"`lib/taskParsing.ts` (`parseTaskWithAutoTags`, `buildStartTaskFromDraft`, `formatProjectDisplay`, `!p#t` tokens) ; `personalProject` on tasks and `knownPersonalProjects` on the payload ; `server/actionDispatch.ts` and `server/actionTaskSession.ts` (`startTask`, `addHistoricalTask`, `updateTask`, `saveTaskTemplate`, `renameProjectMetadata` with `personalOnly` on the API) ; UI: `TaskFocusPanel`, `TaskSessionLiveCard`, `SavedProjectPicker`, `taskFieldStyles` (rose chips). Unit tests: `lib/taskTemplateDraft.test.ts` (`!` templates).",example:"“Reading !me” while live: the card shows the rose project chip; saving as a template keeps `!me` under Settings → Task templates."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Use per-personal-project scoped tags in the `!project#subtag` form (same idea as `@project#code` for work).",detail:"`TagPills`, `formatTagDisplayForTask`, and scoped parsing in `lib/taskParsing.ts` carry `personalProject` for display. The scoped **`!`** token may be **glued** to the previous word (**1.0.0-beta.21**, `findProjectTokens`).",example:"“Follow-up !dentist#urgent”: scoped tag renders with the `!` prefix."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"On a task’s Gantt modal, separate productive (`@`) vs personal (`!`) time with distinct bar colors and split totals.",detail:"`lib/taskTimelineGantt.ts`, `components/dashboard/TaskTimelineGanttModal.tsx`, `lib/dashboardCopy.ts` strings (legend and summaries)."},{implemented:!0,integrationChecked:!0,e2eChecked:!0,text:"Start, pause, and finish a task timer independently of session wall time.",detail:"Each task timer cycle (start, manual pause on the row, finish) is separate from wall time: pausing or resuming the session wall (`setPaused`) is not the same as pausing that task’s timer (`setTaskTimerPaused` / resume); server-side segments and pause contexts preserve the distinction. A Playwright scenario clicks pause on the card and checks the resume control (`e2e/task-lifecycle.spec.ts`).",example:"Pause a task from its card, then resume only the session: that task’s timer stays paused until you explicitly resume the row. “Finish” on the card ends tracking for that task."},{implemented:!0,text:"When another timer is running, choose pause, finish, or parallel run and save the default for next time."},{implemented:!0,text:"Add subtasks, check them off, and reorder by drag and drop."},{implemented:!0,text:"Save a task template from a running, paused, or completed task, manage it in Settings, and find it again (debounced input, “Template:” hints, Ctrl+K palette), including personal `!` projects.",detail:"`saveTaskTemplate` stores `personalProject` ; `lib/taskTemplateDraft.ts` (`formatTaskTemplateDraftLine`, `parseTaskTemplatesFromPayload`, `buildTaskTemplateSignature` with work/personal segment) ; `SettingsTaskTemplatesSection.tsx`."},{implemented:!0,text:"Log a task live or backfill it with explicit start and end times."},{implemented:!0,text:"Add a free-text note on a task (live or past entry) to keep activity context."},{implemented:!0,text:"Render task notes before the subtasks block so context stays visible while breaking down work."},{implemented:!0,text:"Edit task time bounds by keeping system duration, entering manual duration, or recalculating from bounds."},{implemented:!0,text:"See not-done tasks whose start is still in the future grouped under Planned with distinct styling, no live-running timer, and no crossed-out completed look too early; for completed tasks, the same Planned styling only when both start and end are still strictly in the future."},{implemented:!0,text:"At the scheduled start (`startTime`), see the timer turn on automatically (no time counted before that instant); at the scheduled end (`scheduledEndAt`), the task finishes automatically.",detail:"`deferFutureStartMainTimersInSession`, `activateDuePlannedTaskTimersInSession` (`server/actionTaskSession.ts`); `materializeRunningMainTimersInPayload` (`server/mainTimerHydrate.ts`). Tests: `server/mainTimerHydrate.test.ts`."},{implemented:!0,text:"Get a global toast (any route) when a planned task or live session reaches its official start time — task title or session name in the message.",detail:"`PlannedScheduleActivationWatcher` (`components/dashboard/PlannedScheduleActivationWatcher.tsx`), `lib/plannedScheduleActivation.ts`; copy `plannedTaskScheduleActivatedToast` / `plannedSessionScheduleActivatedToast` (`lib/dashboardCopy.ts`). Tests: `lib/plannedScheduleActivation.test.ts`."},{implemented:!0,text:"When a planned task becomes live tracking while another timer was already running, resolve pause/finish/parallel for the previously running tasks (same remembered preference as manual starts) and pulse the dashboard nav icon when attention is needed off-route."},{implemented:!0,text:"Schedule an end time on a running task so it automatically completes when the deadline is reached."},{implemented:!0,text:"Launch KronoFocus from a task to alternate work and breaks without losing task context."},{discarded:!0,implemented:!1,text:"Treat wall session time and task time as one interchangeable reporting measure without separating them.",detail:"Decision: discarded. Reporting and aggregates intentionally keep wall time (collector segments) separate from task time; both views support an honest read.",example:"Compare wall vs task totals in reporting — gaps are informative, not mistakes to merge away."}]},{id:"us-kronofocus",title:"KronoFocus",stories:[{implemented:!0,text:"Show the KronoFocus timer in the header and/or near task actions per settings."},{implemented:!0,text:"Run work, break, and long-break phases with duration in HH:MM:SS."},{implemented:!0,text:"Reuse a duration from recent duration history."},{implemented:!0,text:"Attach focus to the active task so history stays linked."}]},{id:"us-search-shortcuts",title:"Data search and shortcuts",stories:[{implemented:!0,text:"Open the Spotlight data-search palette (Ctrl+K / ⌘K) and filter sessions, tasks, task templates, tags, and projects; choosing a template fills the new-task draft."},{implemented:!0,text:"Filter user guide sections on /guide with the field at the top of the page."},{implemented:!0,text:"View and customize dashboard keyboard shortcuts in the dedicated modal."}]},{id:"us-reporting",title:"Reporting and aggregates",stories:[{implemented:!0,text:"Pick a date range with day / week / month / year presets as exposed by the UI."},{implemented:!0,text:"Restrict views by one or more tags when data is task-based."},{implemented:!0,text:"Read summaries, per-day tables, and breakdowns by project and tag."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"On the Reporting page, switch the weekly-by-project grid between the work (@) ledger and the personal (!) ledger with the same date-range and tag filters.",detail:"**1.0.0-beta.26** — `app/reporting/page.tsx` calls `aggregateProjectTaskMinutesByDay` with scope `work` or `personal` from the toggle (`lib/reportingAggregate.ts`, `taskMatchesReportingProjectScope`, `taskIsReportingPersonalLedger`). **Work** (default) excludes the personal ledger; **Personal** includes only it, with `!` labels via `formatProjectDisplay`. A task is **personal** for aggregates when `personalProject` is true **or** when the **title** contains a recognized `!` token (fallback when the flag is missing on older rows)."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"By default, per-project grids show productive (@) time without mixing in personal (!) minutes.",detail:"On first load the toggle is **Work (@)** — same behaviour as before (work scope only)."},{implemented:!0,text:"See non-overlapping task minutes per day for comparison with raw totals."},{implemented:!0,text:"Set the week start day for calendar views to match how I work."},{implemented:!0,text:"Relaunch the reporting tour from settings."},{implemented:!0,text:"When the host supplies a planned start time, see punctuality / variance indicators on sessions."},{implemented:!0,text:"See honest signals about work not yet finalized in the selected range."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"In the session-by-day list (Rhythm), each # under a task shows the task’s full recorded duration (same rule as tag allocation grids), not an even split across multiple tags.",detail:"`buildTaskTagSlicesFullDuration` in `lib/reportingAggregate.ts` ; UI in `app/reporting/page.tsx`. Tests: `lib/reportingAggregate.test.ts`."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Reporting totals and charts count only recorded time; a planned window for future tasks is shown separately and does not feed recorded aggregates.",detail:"`isTaskDisplayPlanned` (`lib/temporalDisplayPlanned.ts`) skipped in `aggregateReporting` ; `plannedMinutes` / amber copy in session-by-day (`app/reporting/page.tsx`, `lib/reportingStrings.ts`). Tests: `lib/reportingAggregate.test.ts`."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"On weekly # and @ calendars, read a Daily total footer row per week (per-day column sums and week total).",detail:"`sumWeekCalendarSlots` (`lib/reportingWeekLayout.ts`) ; `WeekCalendarDayTotalsFoot` in `app/reporting/page.tsx`. Tests: `lib/reportingWeekLayout.test.ts`."}]},{id:"us-settings-data",title:"Settings, export, integrations, danger zone",stories:[{implemented:!0,text:"Tune usage profile to hide blocks that are not relevant (e.g. lines of code for a non-dev profile)."},{implemented:!0,text:"Configure work schedule, planned sessions, collection, and buffers."},{implemented:!0,text:"Manage advanced tags and migrate tags between global and per-project scope."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Rename a tag or project inline (pencil, direct edit, Enter/Escape), with a reporting-impact warning and a “don’t show again” option.",detail:"Server propagation: `renameTagEverywhere` / `renameProjectEverywhere` — `server/actionTaskSession.test.ts`; no dedicated Settings E2E."},{implemented:!1,text:"Manage and rename known personal projects (`knownPersonalProjects`, `!` tokens) from Settings the same way as `@` projects.",detail:"Payload + server actions maintain `knownPersonalProjects` and `renameProjectMetadata` with `personalOnly`; the Settings projects/tags area does not yet expose dedicated `!` inline management as of 2026-05-12."},{implemented:!0,text:"Toggle correction switches for task and session time bounds."},{implemented:!0,text:"Opt in to Git and MongoDB integrations."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Download backups via the export API and UI options.",detail:"Tests: `test/integration/apiBackup.test.ts` (sqlite export + restore round-trip)."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Erase history in a danger zone gated by explicit confirmation.",detail:"Tests: `server/actionDispatch.test.ts` (`clearHistory`); `test/integration/apiActionLogs.test.ts`."},{implemented:!0,text:"In local dev (next dev), use a separate dataset vault and optionally share with prod."},{implemented:!0,text:"Enable two SQLite vaults (production `v4` and QA `v4-qa`), switch from the navigation bar (Prod / QA), and show a strong visual cue in QA mode.",detail:"**1.0.0-beta.26** — `lib/dataEnvironmentPreferenceFile.ts`, `lib/dataDir.ts`, `switchDataEnvironment` with `qaSeed` (`copy_production` | `empty` when `v4-qa` is missing), `dataEnvironmentRuntime` on `/api/state`, `DataEnvironmentSwitchProvider`, `AppShellHeaderDataEnvironmentChip`, `DataEnvironmentChrome`; server restart required. Disabled when `TRACE_DATA_DIR` is set."},{implemented:!0,text:"Configure web, API, and guided-tour relaunches from settings."}]},{id:"us-architecture-quality",title:"Architecture, quality, documentation",stories:[{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Rely on mutations going through a single server entry point for invariants.",detail:"Indirect coverage: `server/actionDispatch.test.ts`, `test/integration/apiAction*.test.ts`."},{implemented:!0,integrationChecked:!0,e2eChecked:!1,text:"Reload the page and restore state from persisted JSON payload.",detail:"Tests: `server/payloadStore.test.ts` (SQLite read/write)."},{implemented:!0,text:"Use French and English UI strings on visible surfaces."},{implemented:!0,text:"Benefit from Playwright end-to-end tests on critical flows."},{implemented:!0,text:"Open this user-story list on /implementation to track shipped scope."},{implemented:!0,text:"Find the repository documentation index and documented API contracts for integrators.",detail:"**1.0.0-beta.27** — `docs/README.md`; root README (HTTP API); JSDoc on `server/*` and `app/api/*`."},{implemented:!1,text:"Replace the user guide (/guide) with this page for learning the product."}]}]};function f(a){return"fr"===a?d:e}},66430:(a,b,c)=>{"use strict";function d(a){return a.replace(/\[([^\]]+)\]\(\/[^)]+\)/g,"$1").replaceAll("**","")}function e(a){return"fr"===a?{pageTitle:"Guide d’utilisation",pageSubtitle:"Chaque rubrique m\xe9lange **l’intention** (\xe0 quoi \xe7a sert *pour vous*), des **\xe9tapes** quand c’est enchain\xe9 \xe0 l’\xe9cran, et des **options** concr\xe8tes — le tout dans le **m\xeame th\xe8me** clair ou sombre que l’appli.",defaultStepBlockTitle:"Proc\xe9dure (pas \xe0 pas dans l’interface)",defaultOptionsBlockTitle:"Options, modes et rappels",searchPlaceholder:"Filtrer les rubriques (sens, \xe9tapes, options, KronoFocus…)",searchAriaLabel:"Recherche dans le guide",searchNoResults:"Aucune rubrique ne correspond \xe0 votre recherche. Essayez un autre mot-cl\xe9 ou effacez le filtre.",tocHeading:"Sur cette page",tocNavAria:"Sommaire du guide d’utilisation",lastUpdated:"Derni\xe8re mise \xe0 jour : 3 juin 2026 (v1.0.0-beta.36)",helpLinksHeading:"Pages compl\xe9mentaires",helpLinksAria:"Liens vers l’impl\xe9mentation et les licences",helpImplementationLink:"User stories — impl\xe9mentation",helpLicensesLink:"Licences et logiciels tiers",sections:[{id:"ug-essence",title:"C’est quoi Kronosys — le sens, pas l’onglet",searchIndex:"but intention pourquoi aide b\xe9n\xe9fice productivit\xe9 focus temps m\xe9moire concentration \xe9quipe client reconstituer oubli rythme travail vie attention local donn\xe9es chez soi",paragraphs:["Kronosys, c’est un **compagnon** pour *temps* et *travail* : poser **ce** que vous faites, **combien** de temps, dans quel **sujet**, sans th\xe9\xe2tre administratif. **\xc0 quoi \xe7a sert ?** Moins d’amn\xe9sie sur *\xab j’y ai vraiment mis quoi, cette semaine ? \xbb*, plus de **cl\xf4ture** propre \xe0 la fin d’un bloc, un **r\xe9cit** (pour vous, une \xe9quipe, un client) quand il le faut.","**Pour qui** est-ce pens\xe9 ? Les journ\xe9es en **morceaux** (code, contenu, op\xe9rations, recherche…), les **contextes** qui s’entassent, ou le besoin d’**expliquer** sans tout refaire sur Excel. Kronosys reste *chez vous* c\xf4t\xe9 donn\xe9es; Git, miroir, grosse sauvegarde, ce sont des **c\xe2bles** que l’on ajoute *quand vous voulez*."],optionsTitle:"Trois \xab pi\xe8ces \xbb pour trois gestes",options:["**Tableau de bord** — l’*atelier* (sessions, t\xe2ches, minuteur, raccourcis **#\xe9tiquettes** / **@projets** travail / **!projets** personnels).","**Rapports** — la p\xe9riode en **trois vues** (allocation facturation, rythme, avanc\xe9) \xe0 partir de l’historique d\xe9j\xe0 enregistr\xe9.","**Param\xe8tres** — l’*arri\xe8re-boutique* (habitudes, raccordements, zone o\xf9 l’on *efface* l’histoire *avec prudence*). [Ouvrir Param\xe8tres](/settings#settings-usage-profile)."],stepsTitle:"Premier contact en cinq pas (sans tout ma\xeetriser le jour 1)",steps:["Ouvrez l’**accueil** (tableau de bord) : c’est ici que d\xe9marre l’**atelier**.","D\xe9clenchez **Nouvelle session** (ou laissez l’app en cr\xe9er une *la premi\xe8re fois* qu’une t\xe2che part).","D\xe9crivez un **coup de t\xe2che** (titre) ; un **#mot** = \xe9tiquette ; **@nom** = *projet* de travail ; **!nom** = *projet personnel* (le formulaire *devine* souvent l’un et l’autre). Ajoutez au besoin une **note libre** sur la t\xe2che et, c\xf4t\xe9 session, une **note de session**.","Appuyez sur **D\xe9marrer** (ou lancez le **KronoFocus** *\xe0 c\xf4t\xe9*) pour **tenir** un *cr\xe9neau*.","Quand la journ\xe9e le demande, ouvrez **Rapports** pour *voir* ce qui c’est *pass\xe9* dans la p\xe9riode — *sans* y passer la soir\xe9e en tableurs."]},{id:"ug-nav-theme",title:"Barre d’outils, th\xe8me et langue",searchIndex:"th\xe8me clair sombre mode violet zinc langue fr en ruban groupe navigation repli plusieurs rang\xe9es",paragraphs:["La **barre du haut** est *toujours* la m\xeame famille : m\xeames outils, m\xeame **ton** (zinc, accents **violet**), pour ne pas recharger le cerveau *\xe0 chaque page*. Les **raccourcis** de pages sont **regroup\xe9s** en **petits blocs** par **contexte** (zones principales, aide et documentation, outils de session), sur le mod\xe8le d’un **ruban** l\xe9ger. L’ic\xf4ne **roue** m\xe8ne \xe0 [Param\xe8tres](/settings#settings-usage-profile) (raccourci **Alt+Shift+S** depuis le tableau de bord).","Sur **\xe9cran \xe9troit** (petit portable, fen\xeatre r\xe9duite, **PWA** c\xf4t\xe9 tablette), la rang\xe9e se **replie** en **plusieurs lignes centr\xe9es** au lieu d’afficher une **barre de d\xe9filement horizontale** — les **blocs** (horloge, KronoFocus, navigation, utilitaires) restent **group\xe9s** et accessibles **sans glisser** lat\xe9ralement."],steps:["En **tableau de bord** : l’ic\xf4ne **Livre** m\xe8ne ici, puis **Rapports** (graphe) et **Param\xe8tres** (roue).","Sur **les autres pages** : revenez \xe0 l’**accueil** (ic\xf4ne **grille** du tableau de bord), puis m\xeames **Livre**, **Rapports**, **Param\xe8tres** ; l’ic\xf4ne **changelog** ouvre `/changelog` depuis la barre.","Depuis ce **guide**, les boutons **Impl\xe9mentation** et **Licences** (sous le titre) m\xe8nent \xe0 l’inventaire des user stories et aux mentions l\xe9gales — elles ne sont plus dans la barre d’ic\xf4nes.","Sur **Impl\xe9mentation**, les lignes pourvues d’un **chevron** d\xe9ploient une **pr\xe9cision** et un **exemple** (texte plus petit) sans allonger la liste principale.","Toujours en tableau de bord, un bouton **Gantt du jour** (grille) ouvre une frise globale avec les t\xe2ches de **toutes** les sessions pour la journ\xe9e en cours.","Le **bouton th\xe8me** bascule **clair / sombre** (le soir ou salle trop lumineuse).","Le bouton **actualiser** redemande l’**\xe9tat** au serveur (utile si quelqu’un/quelque chose a chang\xe9 dehors *sans* recharger toute l’**app**).","Ouvrez le **menu de langue** (FR / EN) ; la **pr\xe9f\xe9rence** peut se **m\xe9moriser** c\xf4t\xe9 moteur si c’est la configuration chez vous."],options:["**Livre** = ce **guide** ; **graphe** = **Rapports** ; **roue** = **Param\xe8tres** ; **grille** = **Gantt du jour** (tableau de bord) ; **changelog** = journal utilisateur. **Impl\xe9mentation** et **Licences** : boutons en haut de ce guide.","Changer de **th\xe8me** ne modifie **pas** le **fond** de vos enregistrements — seulement le **confort** visuel (m\xeame **d\xe9cor** d’\xe9cran d’une page \xe0 l’autre, pour ne pas se **perdre** entre les onglets)."]},{id:"ug-layout",title:"O\xf9 travailler, o\xf9 regarder, o\xf9 r\xe9gler — + juridique",searchIndex:"navigation tableaux bord rapports param\xe8tres licences horloge fuseau tiroir drawer focus colonnes xl",paragraphs:["Trois gestes, trois endroits : l’**atelier** (maintenant), les **Rapports** (retour sur une p\xe9riode), les **Param\xe8tres** (coulisses, effacements sensibles, branchements). Puis **Licences**, la page d’honn\xeatet\xe9 sur le code **open source** et les polices."],options:["**Tableau de bord** — \xe0 gauche la **file des sessions** ; au centre les **t\xe2ches** (minuteurs, d\xe9tail) ; \xe0 droite les raccourcis d’**\xe9tiquettes** et de **projets** (**@** travail, **!** personnel). Sur **grand \xe9cran** (xl+), les panneaux lat\xe9raux deviennent des **tiroirs repliables** **coll\xe9s au bord gauche ou droit de l’\xe9cran** (languette vers les t\xe2ches, bande repli\xe9e avec **ic\xf4ne** et titre vertical) ; le **lanceur de t\xe2che** est aussi un **tiroir repliable** (sans languette) ; la colonne **T\xe2ches** reste **centr\xe9e** (base **42 rem**, **+20 %** de largeur max par tiroir lat\xe9ral repli\xe9) ; l’\xe9tat ouvert / ferm\xe9 est **m\xe9moris\xe9** dans le navigateur ; la **liste des sessions** d\xe9file **dans le tiroir** (carte session s\xe9lectionn\xe9e fixe au-dessus quand elle s’y affiche). **Une seule ligne** d’en-t\xeate **T\xe2ches** regroupe le **total**, le **d\xe9compte** par statut (En cours, Planifi\xe9es, En pause, Compl\xe9t\xe9es, Non termin\xe9es en archive), l’indicateur **SUIVI**, l’aide **(?)** et le **chevron** d\xe9plier / replier (xl+) ; repli\xe9 : m\xeame ligne, formulaire masqu\xe9. **Mode focus** : bouton **agrandir** (ruban utilitaire), commande palette **Ctrl+K** / **⌘K**, raccourci **Alt+Shift+F** — masque l’en-t\xeate et les bandeaux pour ne garder que les **trois colonnes** ; quitter avec **\xc9chap** ou le bouton **r\xe9duire** en haut \xe0 droite.","**Rapports** — choisir une **plage de dates** et, si besoin, des **#\xe9tiquettes** ; puis les **onglets** (allocation facturation, rythme, avanc\xe9). Une **visite guid\xe9e** est propos\xe9e la premi\xe8re fois sur l’\xe9cran.","**Param\xe8tres** — profil, collecte, planification, \xe9tiquettes avanc\xe9es, **Git** ou miroir en **option** ; la **zone dangereuse** supprime l’historique (avec saisie de confirmation). [Sommaire des param\xe8tres](/settings#settings-usage-profile) \xb7 [zone de danger](/settings#settings-danger-zone). N’y entrez **que** quand vous le **d\xe9cidez**.","**Journaux d’actions** (`/logs`) — historique des **mutations** enregistr\xe9es c\xf4t\xe9 serveur (type, succ\xe8s, date, session) ; ic\xf4ne **liste** dans le bloc navigation principal.","**Licences** — textes MIT, logiciels tiers, polices ; accessible via le bouton **Licences** en haut de ce guide.","Une **horloge murale** (fuseau et format 12/24 h des param\xe8tres **Tableau de bord web**) tourne en permanence dans la **barre d’outils** de l’en-t\xeate ; le **KronoFocus** se place **juste \xe0 c\xf4t\xe9**, avant les ic\xf4nes de navigation — il reste **toujours** visible pour garder la barre stable. Si les **coffres production et QA** sont activ\xe9s, un commutateur **Prod / QA** pr\xe9c\xe8de ces ic\xf4nes : la bascule **rouvre imm\xe9diatement** le bon fichier SQLite (sans red\xe9marrer le serveur). En consultation d’**archive**, ses **boutons** restent **visibles** mais **d\xe9sactiv\xe9s** : ils refl\xe8tent toujours la **session live**. La **palette donn\xe9es** (Ctrl+K / ⌘K), le **Gantt du jour** et la **pause globale** sont **les m\xeames** sur **toutes** les pages (tableau de bord, rapports, param\xe8tres, journaux, guide, impl\xe9mentation, changelog, licences) ; hors tableau de bord, certaines actions **vous y ram\xe8nent** pour terminer (ex. ouvrir un r\xe9sultat de recherche)."]},{id:"ug-convention-end-vs-pause",title:"Convention : heure de fin et pause",searchIndex:"convention pause fin programm\xe9e \xe9ch\xe9ance terminaison cl\xf4ture minuteur pause globale diff\xe9r\xe9e mise en veille",paragraphs:["Dans Kronosys, une **heure de fin** que vous **programmez** sur une **t\xe2che** ou une **session** en cours d\xe9finit une **terminaison** \xe0 cet instant — ce n’est **pas** une pause **report\xe9e**, ni une mise en veille diff\xe9r\xe9e.","Pour **mettre en pause** le suivi (minuteur, murale, session), utilisez les **actions de pause** pr\xe9vues \xe0 cet effet ; elles sont **distinctes** de la notion d’**\xe9ch\xe9ance** ou de **fin programm\xe9e**."],bullets:["**Fin programm\xe9e** → la t\xe2che est **termin\xe9e** ou la session **cl\xf4tur\xe9e** \xe0 l’instant choisi.","**Pause** → action **explicite** (minuteur, session live en pause, pause globale, etc.)."]},{id:"ug-sessions-tasks",title:"Sessions, t\xe2ches, \xe9tiquettes et projets",searchIndex:"session live archiver terminer t\xe2che minuteur pause sous-t\xe2che historique liste r\xe9sum\xe9 planifi\xe9e pastille badge conflit navigation projet personnel !perso jeton coll\xe9 courriel rouvrir reopen dur\xe9e minimale minimum half-hour demi-heure fin future session pass\xe9e",paragraphs:["La **session** est le **sac** o\xf9 vient s’additionner le travail sur une p\xe9riode ; la **t\xe2che** est le fil conducteur du moment. **#mot** = th\xe8me ; **@nom** = projet **productif** ; **!nom** = projet **personnel** (suivi hors travail facturable, pastille souvent **rose**) — c’est de la **classification**, pas un examen d’orthographe. Le **`!`** (y compris **`!projet#sous-\xe9tiquette`**) peut \xeatre **coll\xe9** au mot pr\xe9c\xe9dent **sans espace** — ex. `Courrier!perso#dentiste` ; le **`@`** reste en principe **apr\xe8s un espace** ou en **d\xe9but** de segment pour limiter les faux positifs sur les courriels."],optionsTitle:"Nouvelle session — le cadre, au choix",options:["**D\xe9but** : **maintenant** (lancement imm\xe9diat) avec **fin planifi\xe9e optionnelle** d\xe8s la modale, ou **dans le pass\xe9** — saisie du **d\xe9but et de la fin** en heure locale du navigateur. Si la fin est encore **\xe0 venir**, une session **live** s’ouvre \xe0 partir de ce d\xe9but et se **cl\xf4ture automatiquement** \xe0 l’heure pr\xe9vue ; si la fin est **d\xe9j\xe0 pass\xe9e**, la plage close va dans l’**historique** (sans interrompre une session active) et l’\xe9cran bascule dessus pour **saisir des t\xe2ches**. Un lancement **imm\xe9diat** alors qu’une session est **d\xe9j\xe0 active** ouvre d’abord la **fin de session**.","**Port\xe9e minimale** : pas de bordage particulier — vous lancez et c’est le flux qui m\xe8ne.","**Dur\xe9e max (horloge murale)** : l’onglet s’y pr\xeate (rappel, pas alarme) quand on veut cadrer un gros **morceau** de journ\xe9e.","**Fen\xeatre calendrier** : dates de **d\xe9but** et de **fin** (engagement aupr\xe8s de vous-m\xeame ou d’un tiers).","**Semaine** : jours de la semaine + **plage horaire** (utile en rythme **fixe** — pas pour tout le monde, et c’est normal).","Dans les s\xe9lecteurs de dates/heures, les actions rapides **Aujourd’hui** et/ou **Maintenant** sont disponibles pour \xe9viter la saisie manuelle.","Les **t\xe2ches** se suivent en **direct** (minuteur) ou s’inscrivent **dans le pass\xe9** (d\xe9but, fin et **dur\xe9e du minuteur** en h/m/s — comme lors d’un ajustement) : honn\xeate quand on remplit **apr\xe8s coup** le soir, sans th\xe9\xe2tre."],stepsTitle:"D\xe8s que vous avez cliqu\xe9 \xab D\xe9marrer \xbb sur une t\xe2che (ordre usuel)",steps:["Taper un **titre** (champ pleine largeur sous la barre d’actions) ; saupoudrer d’un **#** (\xe9tiquette), d’un **@** (projet travail) et/ou d’un **!** (projet personnel) : une **liste d\xe9roulante** propose alors les choix **les plus utilis\xe9s** puis **les plus r\xe9cents** (filtrage au fil de la frappe, **↑** / **↓**, **Entr\xe9e** ou clic), y compris en **\xe9dition du titre** sur une carte.","Cliquer **D\xe9marrer** sur la t\xe2che — ou, si l’heure s’y pr\xeate, lancer d’**abord** le **KronoFocus** depuis cette t\xe2che (m\xeame bateau, rythme diff\xe9rent).","Si le minuteur d’**une** autre t\xe2che tourne d\xe9j\xe0 : l’appli offre **pause** sur l’ancienne, **terminer** l’ancienne, ou **tout** tenir en parall\xe8le (vous **pouvez** m\xe9moriser l’**option** pour les prochains lancements).","En **cours** : lister des **sous-t\xe2ches** ; les cocher, les reclasser au **glisser-d\xe9poser** ; **pause** / reprise en douceur.","**Terminer la session** quand le bloc a une fin (bouton d’en-t\xeate ou banni\xe8re) ; une **raison** de cl\xf4ture **facultative** (dans les temps, en avance, d\xe9passement, autre + note) : pour poser mots sur la **fin** du cycle — d’**abord** pour vous, pas pour un **audit** froid."],bullets:["Chaque **t\xe2che** peut porter une **note libre** : lien **Ajouter une note** sur la carte ou au lanceur (champ masqu\xe9 tant qu’elle est vide) ; une note **enregistr\xe9e** s’affiche en Markdown avant les **sous-t\xe2ches** (clic pour modifier). Le **titre** accepte du Markdown **inline** en lecture. Ic\xf4ne **(?)** : aide Markdown (exemples et aper\xe7u).","**Lanceur de t\xe2che** : comme les cartes — mode maintenant/pass\xe9, KronoFocus, aide et **pastilles** projet / `#\xe9tiquettes` **en haut \xe0 droite** ; en **mode pass\xe9**, un bouton ouvre une **modale** pour **d\xe9but**, **fin** et **dur\xe9e du minuteur** (r\xe9sum\xe9 visible dans le lanceur) ; **titre** avec bouton **D\xe9marrer / Ajouter** **en fin de ligne**, puis **note** en dessous ; suggestions **Mod\xe8le :** sur **toute la largeur** de la ligne titre. Sur **xl+**, tiroir repliable (encadr\xe9 comme les tiroirs lat\xe9raux) : **m\xeame ligne** que le titre colonne **T\xe2ches** (d\xe9compte, **SUIVI**, aide **(?)**, **chevron**) ; repli\xe9 : bandeau compact, formulaire masqu\xe9 ; sous xl, toujours d\xe9ploy\xe9.","Chaque **session** peut porter une **note de session** ; un aper\xe7u (ic\xf4ne + extrait) appara\xeet dans la liste des sessions et dans les archives.","Le bouton de **pause globale** est **inactif** (avec une infobulle) lorsque **rien ne tourne** : murale d\xe9j\xe0 fig\xe9e et aucun minuteur ; sinon il ouvre une **confirmation** avec un **r\xe9sum\xe9** : **d\xe9but** et **fin** (ou mention *en cours*), **dur\xe9e murale**, **temps de codage** et **temps actif** de session lorsque l’h\xf4te les fournit, d\xe9compte **t\xe2ches** / **sous-t\xe2ches**, **total enregistr\xe9** sur les minuteurs de t\xe2ches puis **r\xe9partition** minuteur principal vs sous-t\xe2ches, puis la liste des effets sur les minuteurs ; une fois valid\xe9e, il met en pause la session, les t\xe2ches et les sous-t\xe2ches en cours du contexte affich\xe9 ; le clic suivant **reprend uniquement** ce lot.","La **pause session** (contr\xf4le d’**en-t\xeate** lorsque la session est **live**) **fige aussi** les minuteurs **actifs** des **t\xe2ches** et **sous-t\xe2ches** ; **reprendre la session** ne rallume que ce qui avait \xe9t\xe9 gel\xe9 **par cette pause** — pas une t\xe2che d\xe9j\xe0 laiss\xe9e en pause **manuelle** avant. Reprendre une **t\xe2che** avant le bandeau retire cette entr\xe9e du **lot** concern\xe9 par une reprise session ult\xe9rieure.","Sans **`#` explicite**, une t\xe2che re\xe7oit l’\xe9tiquette r\xe9serv\xe9e **\xab d\xe9faut \xbb** ; d\xe8s qu’un **`#tag`** est ajout\xe9 (cr\xe9ation, \xe9dition du titre, mise \xe0 jour), **\xab d\xe9faut \xbb est retir\xe9e** automatiquement — option dans [T\xe2ches et \xe9tiquettes](/settings#settings-task-tags).","Sur les **pastilles** (carte t\xe2che, rapports, listes), seul le **nom** s’affiche — **sans** `#`, `@` ni `!` — la **couleur** distingue \xe9tiquette (**vert**), projet travail (**bleu ciel**) et projet personnel (**rose**) ; les **jetons** restent visibles \xe0 la **saisie**, dans les **suggestions** et le **marquage** rapide. Option [Param\xe8tres → Tableau de bord web](/settings#settings-web) **\xab Ne pas distinguer par la couleur seule \xbb** : pr\xe9fixes `#` / `@` / `!` et bordures distinctes en compl\xe9ment des couleurs.","\xc0 la **fermeture** d’une session avec des t\xe2ches ouvertes, vous pouvez les **terminer**, les **transposer** vers une **nouvelle session en pause**, ou les **laisser ouvertes** dans l’instantan\xe9 archiv\xe9 ; dans tous les cas, les **minuteurs** de cette session **cessent**.","Dans une **session live** ainsi en pause, un **bandeau** propose de **reprendre la session** ; le **lecture** sur une t\xe2che **reprend aussi** l’horloge murale (collecte).","Lorsque la session live est en **pause** (murale et minuteurs concern\xe9s, ou **pause globale**), le bloc **Session en cours** affiche une pastille **En pause** ou **Pause globale** ; un **voile** \xe0 l’\xe9cran centre un rappel, la **barre du haut** restant utilisable pour **reprendre**.","Dans le bloc timing **Session en cours**, une **barre de progression** sous **Fin** avance de l’heure de **d\xe9but** vers la **fin planifi\xe9e** lorsqu’elle est renseign\xe9e (alerte visuelle en fin de cr\xe9neau, comme sur les cartes t\xe2che). **Dur\xe9e totale planifi\xe9e** (cr\xe9neau d\xe9but → fin planifi\xe9e) et **Total planifi\xe9 (t\xe2ches)** n’apparaissent **que** lorsque la donn\xe9e existe ; sinon la ligne est **masqu\xe9e**. Sous **Dur\xe9e**, **Dur\xe9e restante** affiche le temps restant ; sinon **Ind\xe9termin\xe9e**. La liste Sessions reprend `planifi\xe9 X` sur la ligne live lorsqu’une fin planifi\xe9e est d\xe9finie.","M\xeame une **session pass\xe9e termin\xe9e** accepte encore une **entr\xe9e dans le pass\xe9** : s\xe9lectionnez-la ; le **d\xe9but** est arrondi \xe0 la demi-heure pr\xe9c\xe9dente, la **fin** est pr\xe9remplie (d\xe9but + **dur\xe9e minimale** dans [T\xe2ches et \xe9tiquettes](/settings#settings-task-tags)), ajustez la dur\xe9e du minuteur si besoin.","Dans [Param\xe8tres → Tableau de bord web](/settings#settings-default-session-name), un **gabarit** optionnel d\xe9finit le **nom initial** des **nouvelles** sessions (`%UUID`, codes date/heure fa\xe7on POSIX `strftime` — r\xe9f\xe9rence indiqu\xe9e sur l’\xe9cran) avec le m\xeame **fuseau d’affichage** que le tableau de bord et les rapports.","Sur une t\xe2che **en cours**, **en pause** ou **termin\xe9e**, un bouton **Sauvegarder comme template** (ic\xf4ne) enregistre son titre, **#\xe9tiquettes** et projet **@** ou **!** ; la saisie \xab sur quoi travaillez-vous \xbb propose ces mod\xe8les (**Mod\xe8le :**, liste **pleine largeur** de la ligne titre) avec recherche **debounce** — la s\xe9lection **reprend les derni\xe8res heures de d\xe9but/fin** sur la **journ\xe9e courante** (mode pass\xe9) ; la **palette Ctrl+K** les inclut, et [Param\xe8tres → Mod\xe8les de t\xe2che](/settings#settings-task-templates) permet aussi de les **g\xe9rer**.","Lorsqu'un mod\xe8le fournit \xe0 la fois la **derni\xe8re heure de d\xe9but** et la **derni\xe8re heure de fin**, la modale horaire est **contourn\xe9e** : les cr\xe9neaux (recal\xe9s sur la journ\xe9e courante) et la dur\xe9e du minuteur sont pr\xe9remplis **directement** dans le lanceur — validez par **Entr\xe9e** sans \xe9tape suppl\xe9mentaire.","Sur chaque carte, un bouton r\xe9sum\xe9 **d\xe9but → fin** (comme en **mode pass\xe9** du lanceur) ouvre une **seule modale** (deux calendriers c\xf4te \xe0 c\xf4te, **fin facultative**, dur\xe9e du minuteur si la fin est renseign\xe9e) ; la validation applique les corrections en une fois. Si un **lap** est en cours (minuteur actif ou **en pause**), un nouveau **d\xe9but** **r\xe9aligne** le lap ; si une **fin** est d\xe9j\xe0 renseign\xe9e, la dur\xe9e totale peut \xeatre **recalcul\xe9e** depuis les bornes. Sur une t\xe2che **termin\xe9e** \xe0 **un seul** lap enregistr\xe9, corriger d\xe9but ou fin **met \xe0 jour** ce lap en cons\xe9quence. La section **Laps de suivi** reprend le **m\xeame bouton r\xe9sum\xe9** et la **m\xeame modale** par lap (num\xe9ro **#** et **dur\xe9e** du lap restent visibles sur la ligne) ; vous pouvez **supprimer** un lap enregistr\xe9 — sous r\xe9serve du param\xe8tre **Autoriser la correction de l’heure de d\xe9but** pour les t\xe2ches en cours. Pour une t\xe2che en cours, une **heure de fin** (pass\xe9e ou future) **termine la t\xe2che** \xe0 cet instant — ce n’est pas une simple pause du minuteur.","Sur une t\xe2che **termin\xe9e**, le bouton **Rouvrir** (ic\xf4ne ↺) la remet **en cours** : une modale propose de **reprendre le minuteur**, de **rouvrir en pause**, d’**ajuster la dur\xe9e** manuellement ou de **remettre le minuteur \xe0 z\xe9ro** ; les **sous-t\xe2ches** sont rouvertes aussi. En **session live**, si un autre minuteur tourne d\xe9j\xe0 lors d’une **reprise**, les m\xeames options **pause / terminer / parall\xe8le** s’appliquent (m\xe9morisation possible). Dans un **instantan\xe9 cl\xf4tur\xe9**, le minuteur ne repart pas en direct — seuls statut et dur\xe9e changent ; la t\xe2che appara\xeet sous **Non termin\xe9es (instantan\xe9)**.","Lorsque le **d\xe9but** d’une t\xe2che **non termin\xe9e** est encore **dans le futur** (horloge), l’entr\xe9e est sous **Planifi\xe9es** avec un style **bleu ciel** : pas de **minuteur** \xab en direct \xbb et **aucun temps compt\xe9** avant l’heure officielle. En r\xe9glant le **d\xe9but** sur la carte, la **fin** suit avec l’\xe9cart **dur\xe9e minimale** ([T\xe2ches et \xe9tiquettes](/settings#settings-task-tags)) ; sans fin d\xe9j\xe0 enregistr\xe9e, la validation du d\xe9but **programme** cette fin. \xc0 l’**heure de d\xe9but** (`startTime`), le **serveur** active le suivi (synchronisation d’\xe9tat, environ **toutes les 2 s**) : la carte quitte **Planifi\xe9es** et le minuteur d\xe9marre **\xe0 partir de ce d\xe9but**. Une **heure de fin** sur une t\xe2che **en cours** programme `scheduledEndAt` : la t\xe2che se **termine** automatiquement \xe0 cet instant. Pour une t\xe2che **termin\xe9e**, le bloc \xab planifi\xe9 \xbb ne s’applique que si **d\xe9but et fin** sont encore **tous deux** dans le futur ; si le d\xe9but est d\xe9j\xe0 pass\xe9 et seule la fin est future, l’entr\xe9e reste avec les **termin\xe9es** (\xe9vite d’y rester coinc\xe9e jusqu’\xe0 l’heure de fin). M\xeame logique visuelle pour une **session live** dont l’**heure de d\xe9but officielle** est encore dans le futur (ligne distincte dans la liste). Il n’y a **pas de pastille texte** \xab planifi\xe9 \xbb : la distinction repose sur la section, le style et le point d’\xe9tat.","\xc0 l’activation d’un cr\xe9neau planifi\xe9 (t\xe2che ou session live), un **toast** en bas \xe0 droite confirme le d\xe9marrage **sur n’importe quelle page** de l’app (param\xe8tres, rapports, guide, etc.) — le titre de la t\xe2che ou le nom de la session est rappel\xe9.","Lorsqu’une t\xe2che **sort de Planifi\xe9es** et devient **en cours** alors qu’**au moins un** autre minuteur \xe9tait d\xe9j\xe0 affich\xe9 comme **en cours**, une modale propose les m\xeames options **pause / terminer / parall\xe8le** (avec la m\xeame m\xe9morisation que pour le d\xe9marrage manuel) pour les **t\xe2ches d\xe9j\xe0 au minuteur** ; hors route du tableau de bord, l’ic\xf4ne **Tableau de bord** peut **pulser** bri\xe8vement pour signaler qu’une action est attendue.","Pour une **session** de l’**historique** (pas la session **live**), le **r\xe9sum\xe9** (nom, dur\xe9e, m\xe9triques) s’affiche **sous la ligne** correspondante dans la **liste** des sessions, pour garder le d\xe9tail au m\xeame endroit pendant la navigation."]},{id:"ug-kronofocus",title:"KronoFocus — retenir le rythme, pas un bulletin",searchIndex:"pomodoro focus minuteur travail pause dur\xe9e hh:mm",paragraphs:["**Travail**, **pause**, **reprise**, **longue pause** : l’id\xe9e est l’**alternance** saine, pas une **note** sur le nombre de minutes. Proche d’un **pomodoro**, sans s’y figer si votre rythme diff\xe8re."],optionsTitle:"O\xf9 c’est propos\xe9, quoi cliquer",options:["Section [KronoFocus (tableau de bord)](/settings#settings-kronoFocus) dans **Param\xe8tres** : le minuteur reste **dans la barre d’outils** ; vous choisissez encore s’il appara\xeet **pr\xe8s des actions de t\xe2che** (le **profil** d’usage peut **masquer** d’autres blocs ailleurs).","Sur le **panneau** : **D\xe9marrer**, **Pause**, reprise ; **dur\xe9e** en `HH:MM:SS` ; **dur\xe9e par d\xe9faut** (p. ex. 25 min) d’un clic ; **historique** des dur\xe9es pour **r\xe9appliquer** la m\xeame mesure **sans** la retaper.","Lier le KronoFocus **\xe0** la t\xe2che **active** : utile pour **retrouver** dans l’historique **quelle** t\xe2che portait ce **bloc** de focus."],steps:["Ouvrez le KronoFocus (en-t\xeate ou pr\xe8s d’une t\xe2che) ; basculez **travail** / **pause** / **longue pause** selon l’**\xe9tat** affich\xe9.","Ajustez la **dur\xe9e** (saisie ou raccourci) ; enregistrez souvent la **m\xeame** dur\xe9e **dans l’historique** pour un **r\xe9emploi** en un clic.","Lancez le **d\xe9compte** ; en fin de phase, l’**\xe9cran** propose la **suite** (reprise, autre mode) selon le **flux** en cours."]},{id:"ug-search-palette",title:"Recherche Spotlight : donn\xe9es (tableau de bord) & rubriques (ce guide)",searchIndex:"palette recherche donn\xe9es sessions t\xe2ches mod\xe8les ctrl k",paragraphs:["M\xeame **allure** de champ (bordure zinc, focus **violet**) : **deux cibles** — d’**abord** l’**atelier** (sessions, t\xe2ches, **mod\xe8les de t\xe2che**, \xe9tiquettes, mots du workspace) ; **ensuite** le **fil** en t\xeate de **cette** page, qui ne filtre **que** les **rubriques** du **guide**."],stepsTitle:"Donn\xe9es — la palette (tableau de bord)",steps:["Cliquer sur **Rechercher dans les donn\xe9es** ou presser **Ctrl+K** (Windows / Linux) / **⌘K** (macOS) : la **palette** s’ouvre (raccourci **r\xe9serv\xe9** : on ne le **red\xe9finit** **pas** dans la modale raccourcis).","Saisir **deux** ou **trois** **lettres** d’**une** **session**, d’**une** **t\xe2che**, d’**un** **mod\xe8le**, d’**un** **#**, d’**un** **@** ou d’**un** **!** : la **liste** se **restreint** en **direct**.","Choisir **une** **ligne** (**Entr\xe9e** ou **clic**) : l’**\xe9cran** **saute** **vers** l’**objet** ; pour **un mod\xe8le**, le **champ** nouvelle **t\xe2che** est **rempli** ; **\xc9chap** **ferme** la **bo\xeete** **sans** **toucher** le **fond**."],optionsTitle:"Ce guide — le champ coll\xe9 en haut de page",options:["Il ne **lit** **pas** la **base** Kronosys : **seules** les **sections** de **ce** texte d’aide (titres + corps) **subissent** le **filtre**.","Le **compteur** `n / total` (\xe0 **droite** du **champ**) rappelle **combien** de **rubriques** **restent** **visibles** **apr\xe8s** la **saisie**."]},{id:"ug-shortcuts",title:"Raccourcis clavier (tableau de bord)",searchIndex:"raccourcis clavier alt shift ctrl",paragraphs:["Ouvrez la **modale des raccourcis** depuis le petit clavier pr\xe8s de la palette pour voir, **modifier** ou **r\xe9initialiser** les combinaisons (les touches **Ctrl+K** / **⌘K** restent r\xe9serv\xe9es \xe0 la palette **Spotlight**). La relance de **certaines** visites guid\xe9es et des options d’**API** se g\xe8rent aussi dans [Param\xe8tres — Web & API](/settings#settings-web)."],bullets:["Nouvelle session : Alt+Shift+N (par d\xe9faut).","Rapports : Alt+Shift+G \xb7 Param\xe8tres : Alt+Shift+S \xb7 **Guide (cette app)** : Alt+Shift+U.","Colonnes : Ctrl+Alt+H (sessions) \xb7 J (t\xe2ches) \xb7 Y (\xe9tiquettes).","Th\xe8me : Alt+Shift+T \xb7 Langue : Alt+Shift+L \xb7 Terminer session live : Alt+Shift+E.","Mode focus (colonnes seules) : Alt+Shift+F \xb7 palette Ctrl+K (\xab Basculer le mode focus \xbb) \xb7 quitter avec \xc9chap ou le bouton en haut \xe0 droite."]},{id:"ug-reporting",title:"Rapports : la m\xe9moire qui tient, quand on doit la raconter",searchIndex:"agregats kpi plage date \xe9tiquette semaine assiduit\xe9 retard heure planifi\xe9e onglets allocation facturation rythme avanc\xe9",paragraphs:["Les **rapports** ne jaugent pas votre humanit\xe9 : ils aident \xe0 **r\xe9pondre** \xe0 *est-ce qu’on peut, ensemble, s’y retrouver sur une p\xe9riode ?* Ce qui n’est **pas** **encore** fini reste **indiqu\xe9** (brouillon **honn\xeate**, pas punition).","Sous les filtres, **trois cartes** (Allocation facturation, Rythme, Avanc\xe9) d\xe9crivent chaque vue : **Allocation facturation** (#\xe9tiquettes, @projets, calendriers hebdo avec **Total jour** en bas) — le KPI **Temps de t\xe2che enregistr\xe9** est le **total de la semaine affich\xe9e** ; **Rythme** (graphiques par jour et **liste sessions / jour**) ; **Avanc\xe9** (synth\xe8se sur toute la plage, tableau journalier, lignes / signaux, instantan\xe9 workspace). **Un seul (?)** par section regroupe l’aide d\xe9taill\xe9e. L’appli **agr\xe8ge** ce que vous avez **d\xe9j\xe0** enregistr\xe9 ; une **visite** adoucit le **premier** tour.","Lorsque l’**h\xf4te** d’enregistrement a **fourni** l’heure de **d\xe9but pr\xe9vue** \xe0 l’ouverture d’une session (p. ex. moteur li\xe9 \xe0 l’[horaire](/settings#settings-schedule) ou aux [sessions planifi\xe9es](/settings#settings-planned-sessions)), l’**\xe9cart** (retard ou avance) est **sauvegard\xe9** sur la session et des **indicateurs d’assiduit\xe9** apparaissent dans le **r\xe9sum\xe9** (vue **Avanc\xe9**) : ce n’est en g\xe9n\xe9ral **pas** rempli par le seul bouton *Nouvelle session* du navigateur, sauf int\xe9gration explicite."],stepsTitle:"Parcours type sur l’\xe9cran Rapports",steps:["Ouvrir **Rapports** (ic\xf4ne **graphe** ou raccourci **Alt+Shift+G** sur le tableau de bord).","Choisir une **plage** : champs **Du** / **Au**, bouton **Aujourd’hui**, ou pr\xe9r\xe9glages **jour** / **semaine** / **mois** / **ann\xe9e** (selon ce que l’UI expose).","Optionnel : **s\xe9lectionner** une ou plusieurs **#\xe9tiquettes** pour **restreindre** les t\xe2ches (les **sessions** **sans** t\xe2che **correspondante** **disparaissent** des **vues** **bas\xe9es** **t\xe2ches**).","Choisir une **carte** sous les filtres : **Allocation facturation** pour le temps par #\xe9tiquette et @projet (grilles hebdo, navigation de semaine, d\xe9but de semaine) ; **Rythme** pour les graphiques par jour et la **liste sessions / jour** ; **Avanc\xe9** pour les indicateurs de synth\xe8se, le tableau journalier, les lignes de code (si activ\xe9es) et l’instantan\xe9 workspace.","**Lancer** la **visite** **guid\xe9e** **si** la **pancarte** **le** **propose**."],options:["**Indicateurs non finaux** (pastilles) : rappellent le **travail encore ouvert** dans la plage — lire prudemment, pas de chiffrage *fig\xe9* tant que des t\xe2ches *bougent* encore.","Sous le **r\xe9sum\xe9** (vue **Avanc\xe9**), une **ventilation** peut compter les **sessions** par **type de cl\xf4ture** enregistr\xe9 \xe0 la fin de session (lorsque l’h\xf4te en a choisi un) ; les sessions **sans** cat\xe9gorie y figurent \xe0 part.","Le **tableau par jour** (vue **Avanc\xe9**) inclut aussi un total de temps t\xe2che **non concurrent** (sans chevauchement des intervalles horodat\xe9s) pour comparer avec le temps enregistr\xe9 brut.","**D\xe9but de semaine** (dimanche, lundi ou samedi) : **Param\xe8tres → Tableau de bord et API** (d\xe9faut **dimanche**) ; s’applique aux calendriers des s\xe9lecteurs de date et aux grilles hebdo des rapports (raccourci aussi pr\xe8s des calendriers rapports).","Le calendrier hebdo **@projet** affiche une ligne **Total jour** (somme des lignes projet). Le calendrier **#** affiche en pied **Temps enregistr\xe9 (par t\xe2che)** — une fois par t\xe2che, pas la somme des lignes # (la dur\xe9e compl\xe8te reste sur chaque ligne # pour le WBS).","Les valeurs entre parenth\xe8ses (0,25 h) sont arrondies au quart d'heure (15 min) pour la saisie en feuille de temps. Ex. 1 h 11 min → 1,25 h car 71 min arrondi \xe0 75 min = 1,25 h.","Relancer la visite **Rapports** (aide **premier pas** sur l’\xe9cran) : [Param\xe8tres — visite Rapports](/settings#settings-reporting-tour).","Sous le **calendrier hebdomadaire par projet (@)**, le s\xe9lecteur **Travail (@)** / **Personnel (!)** change de registre : **Travail** (d\xe9faut) exclut le temps personnel ; **Personnel** n’affiche que celui-ci (t\xe2ches `personalProject` ou titre avec jeton `!` reconnu)."]},{id:"ug-settings-integrations",title:"Param\xe8tres, sauvegardes et bouts d’usine (quand vous \xeates pr\xeat\xb7e)",searchIndex:"export backup restore restauration sqlite json csv gitlab mongo v4 v4-qa v4-dev qa production environnement coffre donn\xe9es next dev d\xe9veloppement local",paragraphs:["Ici, vous **r\xe9glez** l’**appareil** (KronoFocus, **\xe9tiquettes** / **@** avanc\xe9s, planification) et, **seulement si** vous voulez, le **c\xe2ble** (Git, GitLab, miroir). La **zone dangereuse** : **lisez** le texte \xe0 l’**\xe9cran** et la **phrase** de confirmation avant de **valider** un **effacement**. L’[index de la page Param\xe8tres](/settings#settings-usage-profile) liste toutes les sections (sommaire \xe0 gauche en grand \xe9cran)."],optionsTitle:"Principaux blocs (noms fr\xe9quents, selon votre version)",options:["**Profil d’usage** ([ancre Profil d’utilisation](/settings#settings-usage-profile)) : ex. *gestion* masque des blocs (p. ex. Lignes de code) qu’un **d\xe9v** n’aurait pas cach\xe9.","[KronoFocus](/settings#settings-kronoFocus), [Collecte et tampons](/settings#settings-collection), [Horaire de travail](/settings#settings-schedule) ou [sessions planifi\xe9es](/settings#settings-planned-sessions), [T\xe2ches et \xe9tiquettes](/settings#settings-task-tags) ; [Git](/settings#settings-git) / [MongoDB](/settings#settings-mongo) en branchement **opt-in** (rien n’impose d’ouvrir tout le premier soir).","**Migration d’\xe9tiquettes** : dans [T\xe2ches et \xe9tiquettes](/settings#settings-task-tags), l’outil de port\xe9e permet de **copier** ou **d\xe9placer** une \xe9tiquette globale vers une port\xe9e projet (`Projet#tag`) et l’inverse.","**\xc9tiquettes sans #** : \xe9tiquette seau \xab d\xe9faut \xbb activable ; option pour **retirer \xab d\xe9faut \xbb** d\xe8s qu’une autre \xe9tiquette explicite est ajout\xe9e ([T\xe2ches et \xe9tiquettes](/settings#settings-task-tags)).","Sans `#` explicite, une nouvelle t\xe2che re\xe7oit l’\xe9tiquette r\xe9serv\xe9e **\xab d\xe9faut \xbb** (reporting) ; d\xe8s que vous ajoutez un **`#tag`** (cr\xe9ation, \xe9dition du titre ou mise \xe0 jour), **\xab d\xe9faut \xbb dispara\xeet** — sauf si vous d\xe9sactivez le retrait automatique dans [T\xe2ches et \xe9tiquettes](/settings#settings-task-tags).","**Renommage des \xe9tiquettes/projets (inline)** : dans la colonne droite **Tags / Projects / Templates**, cliquez sur le crayon, modifiez le nom directement dans la ligne puis validez par **Entr\xe9e** (ou **\xc9chap** pour annuler). Un avertissement pr\xe9cise l’impact sur les **rapports** ; vous pouvez cocher \xab ne plus afficher \xbb pour les prochains renommages. (Les listes **`knownPersonalProjects`** pour les jetons **`!`** ne disposent pas encore du m\xeame \xe9cran d’inline que les projets **`@`**.)","**Corrections d’horaire** : commutateurs **on/off** dans [T\xe2ches et \xe9tiquettes](/settings#settings-task-tags) pour le **d\xe9but** et la **fin** d’une **t\xe2che**, et le **d\xe9but** et la **fin** d’une **session**. **Dur\xe9e minimale d’une t\xe2che** (minutes, d\xe9faut 30) : pr\xe9remplit la **fin** lors d’une entr\xe9e **pass\xe9e** ou **planifi\xe9e** (d\xe9but arrondi \xe0 la demi-heure pr\xe9c\xe9dente). Sur une **t\xe2che** en cours, une heure de fin **termine la t\xe2che** \xe0 l’instant pr\xe9vu. Sur une **session** live, une heure de fin **cl\xf4t la session** \xe0 l’instant pr\xe9vu (instantan\xe9 en historique, \xe9quivalent d’une fin de session en mode conserver les t\xe2ches ouvertes).","**G\xe9n\xe9ral — coffres production et QA** ([Param\xe8tres → G\xe9n\xe9ral](/settings#settings-data-environment)) : activez **deux coffres** (`v4` production + `v4-qa` tests) ; basculez avec **Prod / QA** dans la barre de navigation (effet **imm\xe9diat**) ou le s\xe9lecteur sur cet \xe9cran (**Enregistrer**). Au **premier** passage en QA sans coffre existant, une modale propose de **copier la production** ou de **d\xe9marrer vide**. En mode QA, un **bandeau violet** et un **liser\xe9** rappellent que les donn\xe9es ne sont pas celles de la production.","**G\xe9n\xe9ral — mode d\xe9veloppement (coffre local)** ([Param\xe8tres → G\xe9n\xe9ral](/settings#settings-dev-data), seulement en `next dev`) : **Enregistrer** avec le bouton principal ; par d\xe9faut, **jeu de donn\xe9es** s\xe9par\xe9 de la **production** (`v4-dev`) ; on peut partager le coffre `v4` (puis **red\xe9marrer** le serveur de dev). Distinct des coffres **Prod / QA** ci-dessus (usage quotidien packag\xe9 ou `next start`).","**Sauvegarde / restauration compl\xe8te** : c\xf4t\xe9 technique, `GET /api/backup` exporte (format), et `POST /api/restore` restaure un fichier JSON ou SQLite ; c\xf4t\xe9 appli, la **Zone de danger** fournit les actions de sauvegarde + restauration guid\xe9e."],stepsTitle:"Avant d’effacer l’historique (check-list courte)",steps:["Pr\xe9f\xe9rer un **export** (souvent propos\xe9 dans l’**\xe9cran** d’avertissement) : JSON, CSV, copie **SQLite** selon ce qu’ouvre la **brique** d’h\xe9bergement **chez** vous, ou l’[export par d\xe9faut](/settings#settings-export) dans l’**UI** quand c’est propos\xe9.","Relire [la zone dangereuse](/settings#settings-danger-zone) (liste de ce **qui** **dispara\xeet** *vraiment*).","Saisir le **mot** de confirmation *exact* demand\xe9 ; annuler s’il reste le **doute**."]}]}:{pageTitle:"User guide",pageSubtitle:"Each section blends *why* it matters **to you**, **step-by-step** moves in the UI when order matters, and **options** you can actually pick — same **light or dark** look as the app.",defaultStepBlockTitle:"Step by step in the app",defaultOptionsBlockTitle:"Options, modes, and quick facts",searchPlaceholder:"Filter topics (purpose, steps, options, KronoFocus…)",searchAriaLabel:"Search the user guide",searchNoResults:"No section matches. Try another keyword or clear the filter.",tocHeading:"On this page",tocNavAria:"User guide table of contents",lastUpdated:"Last updated: 3 June 2026 (v1.0.0-beta.36)",helpLinksHeading:"More pages",helpLinksAria:"Links to implementation status and licenses",helpImplementationLink:"User stories — implementation",helpLicensesLink:"Licenses and third-party notices",sections:[{id:"ug-essence",title:"What Kronosys is for — the heart, not the tab",searchIndex:"purpose why meaning help people benefit productivity time memory focus calm team client explain remember rhythm work life attention local your data",paragraphs:["Kronosys is a **companion** for time and work: record **what** you are doing, **for how long**, in which **thread** — not to fill a paperwork show. **What is it for?** A little **less** amnesia about *“how much of my week was that, really?”*, a **clean** way to **end** a work block, and a **story** (for you, a team, a client) when the moment needs it.","Built for people who work in **chunks** (code, copy, operations, research…), **juggle** contexts, or have to **explain** without rebuilding Excel at midnight. Data stays **on your** machine; Git, mirrors, and large backups are **cables** you add when **you** choose."],optionsTitle:"Three “rooms” for three moves",options:["**Dashboard** — the workbench (sessions, tasks, focus timer, **#** tags, **@** work projects, and **!** personal projects).","**Reports** — the span in **three tabs** (billing allocation, rhythm, advanced) from what you **already** logged.","**Settings** — the back room (habits, connections, the **danger** zone where you wipe history **carefully**). [Open Settings](/settings#settings-usage-profile)."],stepsTitle:"A calm first run (day one need not be perfect)",steps:["Open the **home** (dashboard) — the workbench starts there.","Start a **new session** (or let the app start one the first time a task needs it).","Name a **task**; **#** = tag; **@** = work project; **!** = personal project (the form often **suggests** tags and projects from what you type).","Press **Start** on the task, or add **KronoFocus** on the **side** if a ritual helps more than a bare timer in the list.","When you need the bigger picture, open **Reports** for a **date range** — you should not have to re-run the week in spreadsheets to see it."]},{id:"ug-nav-theme",title:"Toolbar, theme, and language",searchIndex:"theme light dark language fr en ribbon group navigation wrap multiple rows narrow screen",paragraphs:["The top bar reuses the **same** **family** of controls (zinc, **violet** accents) on every page so **navigation** stays **light** on the brain. **Page shortcuts** sit in **small grouped blocks** by **context** (main areas, help and docs, in-session tools), like a **lightweight ribbon**. The **cog** icon opens [Settings](/settings#settings-usage-profile) (shortcut **Alt+Shift+S** from the dashboard).","On a **narrow screen** (small laptop, shrunk window, tablet **PWA**), the row **wraps** into **multiple centered lines** instead of showing a **horizontal scrollbar** — the **blocks** (clock, KronoFocus, navigation, utilities) stay **grouped** and reachable **without side-scrolling**."],steps:["On the **dashboard**: **Book** → this guide; **chart** → **Reports**; **cog** → **Settings**.","On **other** pages: **grid** (dashboard icon) back to **home**; same book / chart / cog; the **changelog** icon opens `/changelog` from the bar.","From this **guide**, the **Implementation** and **Licenses** buttons (below the title) open the user-story inventory and legal notices — they are no longer in the icon bar.","On **Implementation**, rows with a **chevron** expand for extra **detail** and an **example** (smaller type) under the short wording.","Still on the dashboard, a **Today Gantt** button (grid) opens one global timeline for tasks from **all** sessions in the current day.","**Theme** toggle: **light** or **dark** (evening work or a bright room).","**Refresh** fetches state again from the **server** (e.g. after a change you know happened elsewhere).","**Language** menu: **EN** / **FR**; if the server is configured, the choice can **stick** between visits."],options:["**Book** = this guide; **Chart** = **Reports**; **Cog** = **Settings**; **Grid** = **Today Gantt** (dashboard); **Changelog** = user update log. **Implementation** and **Licenses**: buttons at the top of this guide.","The **theme** only changes how the **UI** looks — it does **not** alter your stored work."]},{id:"ug-layout",title:"Where to work, where to look back, where to tune",searchIndex:"workspace dashboard reports settings license legal clock timezone drawer focus columns xl",paragraphs:["Three main moves: the workbench (now), **Reports** (then), **Settings** (how the app runs + serious cleanup). **Licenses** is the honest credit page for the open building blocks we use."],options:["**Dashboard** — **sessions** on the left, **tasks** (timers, detail) in the **centre**, **tag** and **project** shortcuts (**@** work, **!** personal) on the right. On **wide screens** (xl+), side panels become **retractable drawers** **flush to the left or right screen edge** (pull tab toward tasks, collapsed strip with **icon** and vertical title); the **task launcher** is also a **collapsible drawer** (no pull tab); the **Tasks** column stays **centered** (**42 rem** base, **+20 %** max width per collapsed **side** drawer); open/closed state is **remembered** in the browser; the **session list** scrolls **inside** the drawer (selected session card stays pinned above when shown). A **single Tasks header row** combines the **total**, **counts** per status (Running, Planned, Paused, Completed, Unfinished in archive), **TRACKING**, **(?)** help, and **chevron** expand/collapse (xl+); collapsed: same row, form hidden. **Focus mode**: **expand** button (utility ribbon), **Ctrl+K** / **⌘K** palette command, **Alt+Shift+F** shortcut — hides header and banners to show the **three columns** only; exit with **Esc** or the **minimize** button at the top right.","**Reports** — pick a **date range** and, if needed, **#** tags; then use the **tabs** (billing allocation, rhythm, advanced); the **tour** may offer itself the first time you land there.","**Settings** — profile, collection, scheduling, **advanced** tags, optional **Git** or **remote**; the **danger zone** can **delete** all **history** (type-to-confirm). [Settings overview](/settings#settings-usage-profile) \xb7 [danger zone](/settings#settings-danger-zone).","**Action logs** (`/logs`) — server-side **mutation** history (type, success, timestamp, session); **list** icon in the main navigation block.","**Licenses** — MIT, third parties, **fonts**; open it from the **Licenses** button at the top of this guide.","A **wall clock** (time zone and 12/24 h from **Web dashboard** settings) stays visible in the header **toolbar**; **KronoFocus** sits **right beside it**, before the navigation icons — it is **always** shown so the bar stays stable. When **production and QA vaults** are enabled, a **Prod / QA** switch appears before those icons and **reopens the correct SQLite file immediately** (no server restart). While you **inspect an archive**, its **buttons** stay **visible but disabled** — they still reflect the **live session**. The **data palette** (Ctrl+K / ⌘K), **Today Gantt**, and **global pause** are the **same** on **every** main page (dashboard, reporting, settings, logs, guide, implementation, changelog, licenses); off the **dashboard**, some actions **return** there to **finish** (e.g. open a search hit)."]},{id:"ug-convention-end-vs-pause",title:"Convention: scheduled end time vs pause",searchIndex:"convention pause scheduled end completion closure timer wall clock deferred break",paragraphs:["In Kronosys, a **scheduled end time** on a **running task** or **session** means **completion** at that instant — it is **not** a **deferred pause** or “pause later at this clock time”.","To **pause** tracking (timer, wall clock, session), use the **pause actions** built for that purpose; they are **separate** from **deadlines** and **scheduled ends**."],bullets:["**Scheduled end** → the **task finishes** or the **session closes** at the chosen instant.","**Pause** → an **explicit action** (task timer, paused live session, global pause, etc.)."]},{id:"ug-sessions-tasks",title:"Sessions, tasks, tags, and projects",searchIndex:"session archive end task timer pause subtask history list summary planned badge chip conflict navigation personal project glued bang email reopen minimum duration half-hour future end backdated live",paragraphs:["A **session** is the **bag** work piles into; a **task** is the **thread** of a moment. **#** tags themes; **@** marks a **work** project; **!** marks a **personal** project (often a **rose** chip) — naming helpers, not a grammar test. **`!`** (including **`!project#subtag`**) may be **glued** to the previous word with **no space** — e.g. `Errands!personal#dentist`; **`@`** still expects **whitespace before** or **start of field** so emails like `user@host` are not parsed as projects."],optionsTitle:"New session — the frame, your choice",options:["**Start** **now** (immediate) with an optional **scheduled end** in the modal, or **in the past** — enter **both start and end** in your browser’s local date and time. If the end is still **ahead**, Kronosys opens a **live** session from that start and **closes it automatically** at the scheduled time; if the end is **already past**, the closed interval goes to **history** (without interrupting an active session) and the UI focuses it for **task entry**. **Starting now** while a session is **already live** runs the usual **end session** flow first.","**No** extra frame in particular: start, and the flow **carries** you.","**Max wall** clock: a **nudge** to reframe a **very** long stint.","**Calendar** window: from / to **dates** (a commitment to your later self or someone else).","**Week** + time window on selected **weekdays** (handy in a **fixed** rhythm; skip it if you hate that).","Tasks in **real time** or back-filled with start, end, and **timer duration** (h/m/s — same idea as duration adjustments): honest to log the evening for **yesterday**’s work."],stepsTitle:"After you press “Start” on a task (usual order)",steps:["Type a **title** (full-width field below the action bar); add **#**, **@**, and/or **!** — a **dropdown** then lists **most-used** then **recent** choices (filters as you type; **↑** / **↓**, **Enter**, or click), including when **editing a task title** on the card. Add an optional **free-text task note**, and a **session note** when useful.","Click **Start** on the task — or, if it fits, launch **KronoFocus** from that **task** first (same work, different rhythm).","If another **timer** is on: **pause** it, **finish** it, or allow both in **parallel** (you can **save** the choice for the next time).","While in progress: add **subtasks**; check them; **reorder** by **drag and drop**; use **pause** and **resume** kindly.","**End session** from the header or banner: optional end reason (on time, early, overrun, other + note) — a word for **how** the block **ended**, not a cold verdict."],bullets:["Each **task** supports a **free-text note**: **Add a note** on the card or launcher (field hidden while empty); a **saved** note renders as Markdown before **subtasks** (click to edit). The **title** supports **inline** Markdown when read-only. **(?)** icon opens Markdown help with examples and preview.","**Task launcher**: like task cards — now/past mode, KronoFocus, help and **project** / `#tag` **chips top right**; in **past mode**, a button opens a **modal** for **start**, **end**, and **timer duration** (summary shown in the launcher); **title** with **Start / Add** **at end of row**, then **note** below; **Template:** suggestions span the **full title row** width. On **xl+**, **collapsible drawer** (same chrome as side drawers): **same row** as the **Tasks** column title (counts, **TRACKING**, **(?)** help, **chevron**); collapsed: compact strip, form hidden; below xl, always expanded.","Each **session** supports a **session note**; a preview (icon + excerpt) appears in the session list and in archived sessions.","The **global pause** control is **inactive** (with a tooltip) when **nothing is running** — wall clock already frozen and no timers — otherwise it opens a **confirmation** with a **summary**: **start** and **end** (*ongoing* when there is no end yet), **wall duration**, **session coding** and **active** times when the host records them, **task** / **subtask** counts, **total recorded** task-timer time, then the **split** between **main task** time (excluding subtasks) and **subtask** timers, followed by the list of timer effects; once confirmed, it pauses the current session context (session, task timers, and subtask timers); the next click resumes **only that paused set**.","**Session pause** (header control while the session is **live**) also **freezes** **active** **task** and **subtask** timers; **resume session** only restarts what was frozen **by that pause** — not a task you had already paused **manually** beforehand. Resuming a **single task** removes it from the batch that a later **resume session** would restart.","With no **explicit `#`**, a task gets the reserved **“default”** tag; when you add a **`#tag`** (create, title edit, or update), **“default” is dropped** automatically — toggle under [Tasks & tags](/settings#settings-task-tags).","On **chips** (task card, reporting, lists), only the **name** shows — **no** `#`, `@`, or `!` — **color** distinguishes tags (**green**), work projects (**sky blue**), and personal projects (**rose**); **tokens** still appear while **typing**, in **suggestions**, and **quick marking**. [Settings → Web dashboard](/settings#settings-web) option **“Do not rely on color alone”** adds `#` / `@` / `!` prefixes and distinct border styles alongside the colors.","When ending a session that still has open tasks, you can **finish** them, **move** them to a **new paused session**, or **leave** them **open** in the archived snapshot — **task timers for that session always stop**.","In that **live paused** session, a **banner** lets you **resume session**; **play** on a task also **resumes** wall-clock tracking.","When the live session is **paused** (wall clock and affected timers, or **global pause**), the **Active session** card shows a **Paused** or **Global pause** chip; a **dimmed overlay** centers a reminder while the **top bar** stays usable to **resume**.","In the **Active session** timing block, a **progress bar** below **End** advances from **start** toward the **scheduled end** when one is set (visual alert near the deadline, same as on task cards). **Total planned duration** (start → scheduled end) and **Planned total (tasks)** appear **only** when the data exists; otherwise the row is **hidden**. Below **Duration**, **Remaining duration** shows the time left; otherwise **Undetermined**. The Sessions list shows `planned X` on the live row when a scheduled end is set.","Even a **completed past session** still accepts a **past entry**: select it, set start (defaults to the previous half-hour), end is prefilled from start plus the **minimum task duration** in [Tasks & tags](/settings#settings-task-tags), then adjust duration if needed.","Under [Settings → Web dashboard](/settings#settings-default-session-name), an optional **template** sets the **default name** for each **new** session (`%UUID`, POSIX-style `strftime` fields — authoritative link on that screen). Expansion uses your **display** **time zone** (same buckets as Reporting).","On a **running**, **paused**, or **completed** task, **Save as template** (icon) saves its title, **#tags**, and either an **@** or **!** project. The “what are you working on” input suggests them (**Template:**, **full-width** title row list) with **debounced** filtering — picking one **reapplies the last start/end times on today’s date** (past mode); **Ctrl+K / ⌘K** search lists them; [Settings → Task templates](/settings#settings-task-templates) also lets you **manage** them.","When a template provides both a **last start time** and a **last end time**, the time modal is **skipped**: the slots (shifted to today’s date) and timer duration are prefilled **directly** in the launcher — press **Enter** to submit without extra steps.","On each card, a **start → end** summary button (same as the launcher’s **past** mode) opens a **single modal** (two inline calendars side by side, **optional end**, timer duration when end is set); confirming applies your changes in one step. If a **lap** is active (running timer or **paused**), a new **start** **realigns** that lap; when an **end** is already set, total duration may be **recalculated** from the bounds. On a **completed** task with a **single** saved lap, correcting start or end **updates** that lap accordingly. The **Tracking laps** block uses the **same summary button** and **same modal** per lap (**#** and lap **duration** stay visible on the row); you can **delete** a saved lap — subject to **Allow task start-time correction** for running tasks. On a **running** task, an **end time** **completes the task** at that instant — it is not a soft pause.","On a **completed** task, **Reopen** (↺ icon) makes it **active** again: a modal offers **resume timer**, **reopen paused**, **manual duration**, or **reset timer to zero**; **subtasks** are reopened too. On a **live** session, if another timer is already running when you **resume**, the same **pause / finish / parallel** choices apply (optional remember). On a **closed snapshot**, the timer cannot run live — only status and duration change; the row appears under **Unfinished (snapshot)**.","When a **not-done** task’s **start** is still **in the future**, it is grouped under **Planned** with **sky** styling (no live timer, and **no recorded time** before the official start). When you adjust **start** on the card, **end** follows with the **minimum duration** gap ([Tasks & tags](/settings#settings-task-tags)); if no end was stored yet, confirming start **schedules** that end. At the scheduled **start** (`startTime`), the **server** turns tracking on (state sync, about **every 2 s**): the card leaves **Planned** and the timer runs **from that start**. A scheduled **end** on a **running** task sets `scheduledEndAt` and the task **finishes** automatically at that instant. For a **completed** task, that **Planned** styling applies only when **both start and end** are still **strictly in the future**; if the start has passed but the end is still ahead (e.g. a scheduled end), the row stays under **Completed** instead of being stuck under **Planned** until the end time. The same idea applies to a **live** session whose official **start time** is still in the future (**distinct** row in the list). There is **no “planned” text badge** — section, styling, and the status dot carry the meaning.","When a **planned** slot **activates** (task or live session), a **toast** at the bottom-right confirms it on **any app route** (settings, reporting, guide, etc.) — the task title or session name is shown in the message.","When a **planned** task **becomes live tracking** while **another** timer was already shown as **running**, a modal offers **pause**, **finish**, and **parallel** (with the same optional **remember** setting as when you start a task manually), applying only to the **tasks that were already running** before the clock crossed; away from the dashboard route, the **Dashboard** icon may **pulse briefly** as a hint.","For a **session** in **history** (not the **live** one), the **summary** (name, duration, metrics) appears **under that row** in the sessions **list**, so details stay anchored to the same entry while you browse."]},{id:"ug-kronofocus",title:"KronoFocus — the rhythm, not a report card",searchIndex:"pomodoro timer focus work break duration",paragraphs:["**Work**, **pause**, **resume**, long **pause**: the idea is **healthy** alternation at the **bench**, not a score in minutes. Close to a **Pomodoro** — without locking in if your day does not match."],optionsTitle:"Where to find it, what the controls do",options:["In **Settings**: the [KronoFocus (dashboard)](/settings#settings-kronoFocus) section — the timer **stays in the header**; you can still choose whether it also appears **on** **task** actions (your **usage** profile can hide other panels elsewhere in the app).","On the **card**: **Start**, **Pause**, resume; **duration** as `HH:MM:SS`; a **one-tap** default (e.g. 25 min); **history** of durations to **reapply** without retyping.","Link the timer to the **active** **task** so you can later see **which** **task** carried that focus block in the **archive**."],steps:["Open **KronoFocus** (header or on a **task**); pick **work** / **pause** / **long** **pause** from the state the bar shows.","Adjust the **duration**; add a favourite to **history** to reuse the same **measure** in one click.","Start the **count**down; when a phase ends, the **UI** suggests the **next** **step** in the current flow."]},{id:"ug-search-palette",title:"Spotlight search: data (dashboard) and topics (this guide)",searchIndex:"palette data search templates ctrl k",paragraphs:["Same field **look** (zinc **border**, **violet** ring on **focus**): first the **workshop** (sessions, tasks, **task templates**, **#** / **@** / **!**); on **this** page, the line at the top only **filters** this help text."],stepsTitle:"Data — the search palette (dashboard)",steps:["Click **search data** or press **Ctrl+K** (win/linux) / **⌘K** (mac) — the palette is **reserved**; you do **not** rebind that chord in the **shortcuts** **modal**.","Type a few **letters** of a **session**, **task**, **template**, **#**, **@**, or **!**; the list **tightens** as you type.","**Enter** a row to **jump**; for a **template**, the **new task** field is **filled**; **Esc** closes the box without a full **page** **reload**."],optionsTitle:"This guide — filter at the top of the page",options:["It does **not** read your Kronosys database; it only **filters** the **sections** of this **guide** (titles and body) for **reading** here.","The **n / total** to the right of the field: how many **headings** stay **visible** after you type."]},{id:"ug-shortcuts",title:"Keyboard shortcuts (dashboard)",searchIndex:"keyboard hotkey alt shift",paragraphs:["Open the **shortcuts** modal (small keyboard by the **search** **trigger**) to view, rebind, or **reset** combinations. **Ctrl+K** / **⌘K** stay reserved for the **data** **palette**. Re-running some **tours** and the **API** options live under [Settings — dashboard & API](/settings#settings-web)."],bullets:["New session: Alt+Shift+N (default).","Reporting: Alt+Shift+G \xb7 Settings: Alt+Shift+S \xb7 **This guide**: Alt+Shift+U.","Columns: Ctrl+Alt+H (sessions) \xb7 J (tasks) \xb7 Y (tags & projects).","Theme: Alt+Shift+T \xb7 Language: Alt+Shift+L \xb7 End live session: Alt+Shift+E.","Focus mode (columns only): Alt+Shift+F \xb7 Ctrl+K palette (“Toggle dashboard focus mode”) \xb7 exit with Esc or the top-right button."]},{id:"ug-reporting",title:"Reports: memory you can read back, not a verdict on you",searchIndex:"filter date tag week kpi punctuality late schedule planned tabs billing rhythm advanced",paragraphs:["Reports are for a **calm** read of a time span, not a moral tally. They help answer: can we, together, make sense of this **period**? Unfinished work stays **indicated** where the UI does — honest draft, not **punishment**.","Under the filters, **three centered cards** (Billing allocation, Rhythm, Advanced) describe each view: **Billing allocation** (#tags, @projects, weekly grids with a **Daily total** footer) — the **Recorded task time** KPI is the **selected week’s total**; **Rhythm** (per-day charts and **session-by-day list**); **Advanced** (summary KPIs for the full filter range, day table, code lines / signals, workspace snapshot). **One (?)** per section holds the detailed help. The app **aggregates** what you **already** logged; a **guided** **tour** may soften the **first** visit.","If the **recording** **host** **passed** a **planned** start instant when a session was opened (for example a worker tied to your [work schedule](/settings#settings-schedule) or [planned sessions](/settings#settings-planned-sessions)), the app stores the **offset** in minutes and shows **punctuality** **summary** KPIs under **Advanced** — a browser-only **New session** usually does **not** set this by itself, unless a connector does."],stepsTitle:"A typical run on the Reports page",steps:["Open **Reports** (chart icon, or **Alt+Shift+G** from the dashboard).","Set **from** and **to** (or a day / week / month / year **preset**, depending on what the UI offers).","Use **Today** / **Now** quick actions in date/time pickers whenever available to jump to the current value.","Optionally pick one or more **#** **tags** (sessions with **no** **matching** task may **disappear** from some **task**-based **views**).","Pick a **card** under the filters: **Billing allocation** for time by #tag and @project (weekly grids, week nudger, week start); **Rhythm** for per-day charts and the **session-by-day list**; **Advanced** for summary KPIs, the day table, lines-of-code (when on), and the workspace snapshot.","Start the **guided** **tour** if a prompt appears the **first** time."],options:["**Non-final** chips mark work that is not **closed** in the **range** you are looking at: read them gently; the **draft** is not a **failure**.","Under **Advanced**, below the **summary** KPIs, a **breakdown** may count **sessions** by **closure type** saved when a session ended (when the host picked one); sessions **without** a stored category are grouped separately.","The **day table** (under **Advanced**) includes a **non-concurrent** task-time total (timestamped overlap removed) so you can compare it against raw recorded task time.","**Week starts on** (Sunday, Monday, or Saturday): **Settings → Dashboard & API** (default **Sunday**); applies to date-picker calendars and weekly report grids (shortcut also near report calendars).","The weekly **@project** calendar shows a **Daily total** row (sum of project rows). The **#tag** calendar footer is **Recorded time (per task)** — once per task, not the sum of # rows (each # row still shows full duration for WBS mapping).","Values in parentheses (0.25 h) are rounded to the nearest quarter hour (15 min) for timesheet entry. E.g., 1 h 11 min → 1.25 h because 71 min rounds to 75 min = 1.25 h.","Re-launch the **Reports** first-time **tour** from [Settings — Reporting tour](/settings#settings-reporting-tour).","Under the weekly **@ project** calendar, the **Work (@)** / **Personal (!)** switch changes ledger: **Work** (default) excludes personal time; **Personal** shows only personal entries (`personalProject` or a recognized `!` token in the title)."]},{id:"ug-settings-integrations",title:"Settings, safety copies, and extra wiring (when you are ready)",searchIndex:"export backup restore sqlite json gitlab mongo v4 v4-qa v4-dev qa production environment data store next dev local development",paragraphs:["Here you tune how the app **presents** itself (KronoFocus, tags and **@** **advanced** paths, **schedule**) and, only if you want, the **cable** to **Git**, GitLab, a **mirror**… The **danger** **zone** — read the on-screen text and the **type**-**to**-**confirm** line before a full **wipe**. The [Settings page index](/settings#settings-usage-profile) links every section (left-hand **TOC** on a wide window)."],optionsTitle:"What you are likely to find (names can vary with version)",options:["**Usage** profile ([Usage profile section](/settings#settings-usage-profile)): e.g. *manager* hides some developer-heavy **panels** you might still want in *dev* mode.","[KronoFocus](/settings#settings-kronoFocus), [Collection & buffers](/settings#settings-collection), [work schedule](/settings#settings-schedule) or [planned sessions](/settings#settings-planned-sessions), [Tasks & tags](/settings#settings-task-tags) ; [Git](/settings#settings-git) / [MongoDB mirror](/settings#settings-mongo) as **opt-in** (nothing forces you to turn everything on day one).","In [Tasks & tags](/settings#settings-task-tags), the scope migration tool lets you **copy** or **move** a global tag into a project scope (`Project#tag`) and back to global.","**Tasks without #tags**: optional reserved **default** bucket; optional **drop default** when another explicit `#tag` is added ([Tasks & tags](/settings#settings-task-tags)).","With no explicit `#`, a new task gets the reserved **“default”** bucket (reporting); as soon as you add a **`#tag`** (create, title edit, or update), **“default” is removed** — unless you turn off automatic removal under [Tasks & tags](/settings#settings-task-tags).","**Inline tag/project rename**: in the right **Tags / Projects / Templates** column, click the pencil, edit the name in-place, then confirm with **Enter** (**Escape** cancels). A warning explains the reporting impact; you can tick “don’t show again” for future renames. (**`knownPersonalProjects`** for **`!`** tokens does not yet get the same dedicated inline screen as **`@`** projects.)","**Time correction**: **on/off** toggles in [Tasks & tags](/settings#settings-task-tags) for **task** and **session** **start** and **end** times. **Minimum task duration** (minutes, default 30) prefills **end** for **past** or **planned** entry (start rounded to the previous half-hour). On a **running task**, an end time **completes the task** at that instant. On a **live session**, an end time **closes the session** at that instant (history snapshot), like ending with **keep** for open tasks.","**General — production and QA data stores** ([Settings → General](/settings#settings-data-environment)): enable **two vaults** (`v4` production + `v4-qa` for tests); switch with **Prod / QA** in the navigation bar (**immediate**) or the selector on this screen (**Save**). On the **first** switch to QA when no vault exists yet, a modal offers **copy production** or **start empty**. In QA mode, a **purple banner** and **tinted chrome** remind you that data is not production.","**General — local development (data store)** ([Settings → General](/settings#settings-dev-data), only under `next dev`): use the main **Save** button; by default, **dev** uses a **separate** folder (`v4-dev`) from **production**; you can opt into the same `v4` path, then **restart** the dev server. This is separate from **Prod / QA** above (day-to-day packaged or `next start` runs).","**Backup / full restore**: technically `GET /api/backup` exports by **format**, and `POST /api/restore` restores a JSON or SQLite backup file; in the app, use the **Danger zone** controls for guided backup and restore."],stepsTitle:"Before clearing all history (short list)",steps:["Prefer an **export** when the UI or hosting layer offers it (JSON, CSV, or **SQLite** copy, depending on what your stack exposes), or [Export defaults](/settings#settings-export) when the UI offers it.","Re-read the [danger zone](/settings#settings-danger-zone): what **actually** **goes** **away**.","Type the **confirmation** word **exact**ly; use **Cancel** if doubt remains."]}]}}function f(a){let b=a.paragraphs.map(d).join(" "),c=(a.bullets??[]).map(d).join(" "),e=(a.steps??[]).map(d).join(" "),f=(a.options??[]).map(d).join(" ");return`${a.title} ${b} ${c} ${e} ${f} ${a.searchIndex}`.toLowerCase()}c.d(b,{Y:()=>e,a:()=>f})},67227:(a,b,c)=>{"use strict";c.d(b,{PlannedTaskBoundaryConflictWatcher:()=>d});let d=(0,c(77943).registerClientReference)(function(){throw Error("Attempted to call PlannedTaskBoundaryConflictWatcher() from the server but PlannedTaskBoundaryConflictWatcher is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/dashboard/PlannedTaskBoundaryConflictWatcher.tsx","PlannedTaskBoundaryConflictWatcher")},74464:(a,b,c)=>{"use strict";c.d(b,{DashboardToastProvider:()=>g,f:()=>h});var d=c(48249),e=c(67484);let f=(0,e.createContext)(null);function g({children:a}){let[b,c]=(0,e.useState)([]),h=(0,e.useRef)(0),i=(0,e.useCallback)(a=>{let b=a.trim();if(!b)return;let d=++h.current;c(a=>[...a,{id:d,message:b}]),window.setTimeout(()=>{c(a=>a.filter(a=>a.id!==d))},5500)},[]),j=(0,e.useMemo)(()=>({pushToast:i}),[i]);return(0,d.jsxs)(f.Provider,{value:j,children:[a,(0,d.jsx)("div",{className:"pointer-events-none fixed bottom-4 right-4 z-[100] flex w-[min(calc(100vw-2rem),22rem)] flex-col gap-2","aria-live":"polite",children:b.map(a=>(0,d.jsx)("div",{className:"pointer-events-auto rounded-lg border border-zinc-200 bg-white/95 px-4 py-3 text-sm leading-snug text-zinc-800 shadow-lg dark:border-zinc-600 dark:bg-zinc-900/95 dark:text-zinc-100",children:a.message},a.id))})]})}function h(){let a=(0,e.useContext)(f);return a||{pushToast:()=>{}}}},75761:(a,b,c)=>{"use strict";c.d(b,{c:()=>e});var d=c(67484);function e(a,b,c){let[e,f]=(0,d.useState)(null);return"running"===b&&"number"==typeof c&&Number.isFinite(c)?e??Math.max(0,Math.floor(a)):Math.max(0,Math.floor(a))}},76346:(a,b,c)=>{"use strict";c.d(b,{n:()=>f});var d=c(31417),e=c(300);let f=(0,d.v)()((0,e.Zr)(a=>({kronoFocusDurationHistory:[],pushKronoFocusDuration:(b,c)=>a(a=>{var d;let e;return{kronoFocusDurationHistory:(d=a.kronoFocusDurationHistory,(e=Math.max(60,Math.min(28800,Math.floor(b))))===c?d:[e,...d.filter(a=>a!==e)].slice(0,12))}}),clearKronoFocusDurationHistory:()=>a({kronoFocusDurationHistory:[]}),concurrentTaskStartPreference:null,setConcurrentTaskStartPreference:b=>a({concurrentTaskStartPreference:b}),keybindingOverrides:{},setKeybindingOverrides:b=>a({keybindingOverrides:b}),resetKeybindingOverrides:()=>a({keybindingOverrides:{}})}),{name:"kronosys.dashboard.prefs.v2",partialize:a=>({kronoFocusDurationHistory:a.kronoFocusDurationHistory,concurrentTaskStartPreference:a.concurrentTaskStartPreference,keybindingOverrides:a.keybindingOverrides})}))},77071:(a,b,c)=>{"use strict";c.d(b,{PlannedScheduleActivationWatcher:()=>d});let d=(0,c(77943).registerClientReference)(function(){throw Error("Attempted to call PlannedScheduleActivationWatcher() from the server but PlannedScheduleActivationWatcher is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/dashboard/PlannedScheduleActivationWatcher.tsx","PlannedScheduleActivationWatcher")},78335:()=>{},79159:(a,b,c)=>{"use strict";c.d(b,{At:()=>e,Dv:()=>d,_u:()=>f});let d="kronosys-dashboard-semantic-chip-accessible";function e(a){var b;return((b=a.cfg)&&"dashboardSemanticChipAccessibleMode"in b?!0===b.dashboardSemanticChipAccessibleMode:null)??a.stored??!1}function f(a){if("u"<typeof document)return;let b=document.documentElement;a?b.setAttribute("data-kronosys-semantic-chips","accessible"):b.removeAttribute("data-kronosys-semantic-chips")}},79436:(a,b,c)=>{Promise.resolve().then(c.t.bind(c,95547,23)),Promise.resolve().then(c.t.bind(c,15098,23)),Promise.resolve().then(c.t.bind(c,47644,23)),Promise.resolve().then(c.t.bind(c,33859,23)),Promise.resolve().then(c.t.bind(c,98099,23)),Promise.resolve().then(c.t.bind(c,16237,23)),Promise.resolve().then(c.t.bind(c,98562,23)),Promise.resolve().then(c.t.bind(c,36675,23))},82704:()=>{},84490:(a,b,c)=>{"use strict";c.d(b,{KronosysPackageVersionProvider:()=>e});var d=c(77943);let e=(0,d.registerClientReference)(function(){throw Error("Attempted to call KronosysPackageVersionProvider() from the server but KronosysPackageVersionProvider is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/KronosysPackageVersionProvider.tsx","KronosysPackageVersionProvider");(0,d.registerClientReference)(function(){throw Error("Attempted to call useKronosysPackageVersion() from the server but useKronosysPackageVersion is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/KronosysPackageVersionProvider.tsx","useKronosysPackageVersion")},84735:(a,b,c)=>{"use strict";c.d(b,{PlannedScheduleActivationWatcher:()=>i});var d=c(67484),e=c(24682),f=c(74464),g=c(59899),h=c(55017);function i(){let{payload:a}=(0,e.y)(),{pushToast:b}=(0,f.f)(),[c,i]=(0,d.useState)(()=>Date.now());(0,d.useRef)(null),(0,d.useRef)(null);let j=a?.current,k=h.h.getState().lang,l=j?.language==="fr"?"fr":"en";return(0,g.z)(k??l),null}c(43894)},85242:(a,b,c)=>{"use strict";c.d(b,{LightThemeVariantSync:()=>e}),c(67484);var d=c(24682);function e(){let{payload:a}=(0,d.y)();return null}c(48516),c(31162)},85516:(a,b,c)=>{Promise.resolve().then(c.t.bind(c,81921,23)),Promise.resolve().then(c.t.bind(c,60440,23)),Promise.resolve().then(c.t.bind(c,84342,23)),Promise.resolve().then(c.t.bind(c,82265,23)),Promise.resolve().then(c.t.bind(c,35421,23)),Promise.resolve().then(c.t.bind(c,61335,23)),Promise.resolve().then(c.t.bind(c,70664,23)),Promise.resolve().then(c.bind(c,74661))},88987:(a,b,c)=>{"use strict";c.d(b,{NH:()=>m,qR:()=>l,qS:()=>k});var d=c(48249),e=c(67484),f=c(74429),g=c(11001);let h="z-[250]";function i({children:a}){return"u"<typeof document?null:(0,f.createPortal)(a,document.body)}function j(a){let[b,c]=(0,e.useState)(a),[d,f]=(0,e.useState)(a);return{shouldRender:b,visible:d}}function k({open:a,title:b,message:c,okLabel:f,onClose:l}){let m=(0,e.useId)(),n=(0,e.useId)(),{shouldRender:o,visible:p}=j(a);return o?(0,d.jsx)(i,{children:(0,d.jsx)("div",{className:`fixed inset-0 ${h} flex items-center justify-center bg-black/60 p-4 transition-opacity duration-150 ease-out motion-reduce:transition-none ${p?"opacity-100":"opacity-0"}`,role:"alertdialog","aria-modal":"true","aria-labelledby":b?m:n,"aria-describedby":b?n:void 0,children:(0,d.jsxs)("div",{className:`max-h-[90vh] w-full max-w-md overflow-y-auto rounded-xl border border-zinc-200 bg-white p-5 shadow-xl transition-all duration-150 ease-out motion-reduce:transition-none dark:border-zinc-700 dark:bg-zinc-900 ${p?"translate-y-0 scale-100 opacity-100":"translate-y-1 scale-[0.985] opacity-0"}`,children:[b?(0,d.jsx)("h2",{id:m,className:"text-lg font-semibold text-zinc-900 dark:text-zinc-100",children:b}):null,(0,d.jsx)("p",{id:n,className:`whitespace-pre-wrap text-sm leading-relaxed text-zinc-600 dark:text-zinc-300 ${b?"mt-3":""}`,children:c}),(0,d.jsx)("div",{className:"mt-6 flex justify-end",children:(0,d.jsx)("button",{type:"button",className:g.Sx,onClick:l,children:f})})]})})}):null}function l({open:a,title:b,message:c,cancelLabel:f,confirmLabel:k,confirmVariant:m="neutral",dismissCheckbox:n,typeToConfirm:o,extra:p,pending:q=!1,onCancel:r,onConfirm:s}){let t=(0,e.useId)(),u=(0,e.useId)(),v=(0,e.useId)(),[w,x]=(0,e.useState)(""),{shouldRender:y,visible:z}=j(a);if(!y)return null;let A=!o||w===o.expected,B="danger"===m?g.fO:g.Sx;return(0,d.jsx)(i,{children:(0,d.jsx)("div",{className:`fixed inset-0 ${h} flex items-center justify-center bg-black/60 p-4 transition-opacity duration-150 ease-out motion-reduce:transition-none ${z?"opacity-100":"opacity-0"}`,role:"dialog","aria-modal":"true","aria-labelledby":b?t:u,"aria-describedby":b?u:void 0,children:(0,d.jsxs)("div",{className:`max-h-[90vh] w-full max-w-md overflow-y-auto rounded-xl border border-zinc-200 bg-white p-5 shadow-xl transition-all duration-150 ease-out motion-reduce:transition-none dark:border-zinc-700 dark:bg-zinc-900 ${z?"translate-y-0 scale-100 opacity-100":"translate-y-1 scale-[0.985] opacity-0"}`,children:[b?(0,d.jsx)("h2",{id:t,className:"text-lg font-semibold text-zinc-900 dark:text-zinc-100",children:b}):null,(0,d.jsx)("p",{id:u,className:`whitespace-pre-wrap text-sm leading-relaxed text-zinc-600 dark:text-zinc-300 ${b?"mt-3":""}`,children:c}),n?(0,d.jsxs)("label",{className:"mt-4 flex cursor-pointer items-start gap-2.5 text-sm text-zinc-600 dark:text-zinc-400",children:[(0,d.jsx)("input",{type:"checkbox",className:"mt-0.5 size-4 shrink-0 rounded border-zinc-300 bg-white text-violet-600 focus:ring-2 focus:ring-violet-500/50 dark:border-zinc-600 dark:bg-zinc-950",checked:n.checked,disabled:q,onChange:a=>n.onChange(a.target.checked)}),(0,d.jsx)("span",{className:"leading-snug",children:n.label})]}):null,p?(0,d.jsx)("div",{className:"mt-4",children:p}):null,o?(0,d.jsxs)("div",{className:"mt-4 space-y-2",children:[(0,d.jsx)("p",{className:"text-sm leading-relaxed text-zinc-600 dark:text-zinc-400",children:o.instruction}),(0,d.jsx)("label",{htmlFor:v,className:"block text-xs font-semibold uppercase tracking-wide text-zinc-500",children:o.label}),(0,d.jsx)("input",{id:v,type:"text",value:w,onChange:a=>x(a.target.value),placeholder:o.expected,disabled:q,className:"w-full rounded-lg border border-zinc-300 bg-white px-3 py-2 font-mono text-sm text-zinc-900 outline-none ring-violet-500/30 focus:ring-2 disabled:opacity-50 dark:border-zinc-600 dark:bg-zinc-950 dark:text-zinc-100",autoComplete:"off",spellCheck:!1,"aria-label":o.inputAriaLabel})]}):null,(0,d.jsxs)("div",{className:"mt-6 flex flex-wrap justify-end gap-2",children:[(0,d.jsx)("button",{type:"button",className:"rounded-lg border border-zinc-300 px-4 py-2 text-sm text-zinc-700 hover:bg-zinc-100 disabled:opacity-50 dark:border-zinc-600 dark:text-zinc-300 dark:hover:bg-zinc-800",disabled:q,onClick:r,children:f}),(0,d.jsx)("button",{type:"button",className:`${B} disabled:cursor-not-allowed disabled:opacity-40`,disabled:!A||q,onClick:()=>{A&&!q&&s()},children:k})]})]})})})}function m({open:a,title:b,message:c,dismissLabel:f,tertiaryLabel:k,secondaryLabel:l,primaryLabel:n,primaryVariant:o="danger",dismissCheckbox:p,onDismiss:q,onTertiary:r,onSecondary:s,onPrimary:t}){let u=(0,e.useId)(),v=(0,e.useId)(),{shouldRender:w,visible:x}=j(a);if(!w)return null;let y="danger"===o?g.fO:g.Sx;return(0,d.jsx)(i,{children:(0,d.jsx)("div",{className:`fixed inset-0 ${h} flex items-center justify-center bg-black/60 p-4 transition-opacity duration-150 ease-out motion-reduce:transition-none ${x?"opacity-100":"opacity-0"}`,role:"dialog","aria-modal":"true","aria-labelledby":b?u:v,"aria-describedby":b?v:void 0,children:(0,d.jsxs)("div",{className:`max-h-[90vh] w-full max-w-md overflow-y-auto rounded-xl border border-zinc-200 bg-white p-5 shadow-xl transition-all duration-150 ease-out motion-reduce:transition-none dark:border-zinc-700 dark:bg-zinc-900 ${x?"translate-y-0 scale-100 opacity-100":"translate-y-1 scale-[0.985] opacity-0"}`,children:[b?(0,d.jsx)("h2",{id:u,className:"text-lg font-semibold text-zinc-900 dark:text-zinc-100",children:b}):null,(0,d.jsx)("p",{id:v,className:`whitespace-pre-wrap text-sm leading-relaxed text-zinc-600 dark:text-zinc-300 ${b?"mt-3":""}`,children:c}),p?(0,d.jsxs)("label",{className:"mt-4 flex cursor-pointer items-start gap-2.5 text-sm text-zinc-600 dark:text-zinc-400",children:[(0,d.jsx)("input",{type:"checkbox",className:"mt-0.5 size-4 shrink-0 rounded border-zinc-300 bg-white text-violet-600 focus:ring-2 focus:ring-violet-500/50 dark:border-zinc-600 dark:bg-zinc-950",checked:p.checked,onChange:a=>p.onChange(a.target.checked)}),(0,d.jsx)("span",{className:"leading-snug",children:p.label})]}):null,(0,d.jsxs)("div",{className:"mt-6 flex flex-wrap justify-end gap-2",children:[(0,d.jsx)("button",{type:"button",className:"rounded-lg border border-zinc-300 px-4 py-2 text-sm text-zinc-700 hover:bg-zinc-100 dark:border-zinc-600 dark:text-zinc-300 dark:hover:bg-zinc-800",onClick:q,children:f}),k&&r?(0,d.jsx)("button",{type:"button",className:"rounded-lg border border-violet-400/60 bg-violet-500/10 px-4 py-2 text-sm font-medium text-violet-900 hover:bg-violet-500/16 dark:border-violet-400/45 dark:bg-violet-950/45 dark:text-violet-100 dark:hover:bg-violet-950/70",onClick:()=>void r(),children:k}):null,(0,d.jsx)("button",{type:"button",className:g.Sx,onClick:()=>void s(),children:l}),(0,d.jsx)("button",{type:"button",className:y,onClick:()=>void t(),children:n})]})]})})})}},89806:(a,b,c)=>{"use strict";function d(){return null}c.d(b,{PwaRegister:()=>d}),c(67484)},90595:(a,b,c)=>{"use strict";c.d(b,{SemanticChipAccessibleModeSync:()=>d});let d=(0,c(77943).registerClientReference)(function(){throw Error("Attempted to call SemanticChipAccessibleModeSync() from the server but SemanticChipAccessibleModeSync is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/SemanticChipAccessibleModeSync.tsx","SemanticChipAccessibleModeSync")},90665:(a,b,c)=>{"use strict";c.d(b,{DocumentTitleSync:()=>d});let d=(0,c(77943).registerClientReference)(function(){throw Error("Attempted to call DocumentTitleSync() from the server but DocumentTitleSync is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/DocumentTitleSync.tsx","DocumentTitleSync")},91355:(a,b,c)=>{"use strict";function d(a,b){let c="string"==typeof b?b.trim():"";if(!c)return a;let d=a.indexOf("#"),e=d>=0?a.slice(0,d):a,f=d>=0?a.slice(d):"",g=e.includes("?")?"&":"?";return`${e}${g}session=${encodeURIComponent(c)}${f}`}function e(a,b,c){let d=new URLSearchParams(b);null===c||""===c?d.delete("session"):d.set("session",c);let e=d.toString();return e?`${a}?${e}`:a}c.d(b,{c:()=>d,q:()=>e})},91592:(a,b,c)=>{"use strict";c.d(b,{x:()=>g});let d=[{version:"1.0.0-beta.49",items:["**Variance hors cong\xe9s** : la ligne d'\xe9cart (Variance / \xc9cart) dans le tableau \xab Temps enregistr\xe9 par projet \xbb exclut d\xe9sormais les jours marqu\xe9s comme f\xe9ri\xe9s, vacances, maladie ou autre cong\xe9.","**Calendrier provincial** : dans les param\xe8tres, un s\xe9lecteur de province canadienne g\xe9n\xe8re automatiquement les jours f\xe9ri\xe9s dans le calendrier des rapports.","**D\xe9placement des cong\xe9s** : chaque jour f\xe9ri\xe9 g\xe9n\xe9r\xe9 peut \xeatre modifi\xe9, d\xe9plac\xe9 ou supprim\xe9 depuis la page des rapports."]},{version:"1.0.0-beta.48",items:["**T\xe2ches planifi\xe9es exclues** : les t\xe2ches planifi\xe9es (d\xe9but dans le futur) ne sont plus compt\xe9es dans les totaux de temps enregistr\xe9 (grilles par \xe9tiquette, par projet, et breakdown par session).","**Scope projet sur le breakdown session** : le breakdown par session respecte maintenant le filtre work/personal/all, alignant ses totaux avec les grilles par \xe9tiquette et par projet.","**D\xe9tails de t\xe2che — session unique** : la modale de d\xe9tails d'une t\xe2che n'affiche plus qu'une seule session (celle avec la dur\xe9e la plus \xe9lev\xe9e) au lieu de lister toutes les sessions contenant un snapshot de la t\xe2che.","**Tableau d'anomalies** : nouvelle section dans l'onglet Avanc\xe9 d\xe9tectant 7 types d'anomalies (sessions sans t\xe2ches, t\xe2ches sans dur\xe9e, dur\xe9es > 24 h, chevauchements, t\xe2ches dupliqu\xe9es entre sessions, \xe9carts dur\xe9e session vs somme t\xe2ches).","**Totaux align\xe9s** : le footer du Gantt somme maintenant par t\xe2che unique (pas par lap), ce qui correspond au total affich\xe9 dans le panneau lat\xe9ral de session. Le nombre de t\xe2ches est affich\xe9.","**Alignement horizontal** : les lignes de noms et de barres utilisent une hauteur fixe identique (`h-11`) — plus de d\xe9calage vertical entre les deux colonnes.","**Popover d\xe9tails** : au survol du nom d'une t\xe2che, un popover affiche le nom complet, le projet, les heures d\xe9but/fin et la dur\xe9e track\xe9e.","**Prolongation de t\xe2che termin\xe9e** : lorsqu'une t\xe2che termin\xe9e est rouverte (heure de fin repouss\xe9e), les ancres de minuteur (`MAIN_TIMER_SEGMENT_STARTED_AT`, `TASK_CURRENT_LAP_STARTED_AT`) sont positionn\xe9es \xe0 `nowMs` au lieu de rester vides. Cela emp\xeache la cr\xe9ation d'un nouveau lap qui chevaucherait l'ancien.","**Affichage \xe9tiquettes scop\xe9es** : `formatTagDisplay` n'ajoute plus le pr\xe9fixe `@` pour les \xe9tiquettes `projet#code` (ex. `acme#dev` reste `acme#dev`, pas `@acme#dev`).","**Activation minuteur planifi\xe9** : `activateDuePlannedTaskTimersInSession` ancre le minuteur au `startTime` de la t\xe2che (pas `nowMs`) pour que la dur\xe9e s'accumule correctement depuis le d\xe9but planifi\xe9.","next 16.2.3 → 16.2.9, react 19.2.4 → 19.2.7, react-dom 19.2.4 → 19.2.7, eslint-config-next 16.2.3 → 16.2.9, plus mises \xe0 jour semver-range (playwright, tailwindcss, date-fns, lucide-react, vitest, etc.)."]},{version:"1.0.0-beta.47",items:["**Correction d\xe9but/fin** : lorsqu’une session **cl\xf4tur\xe9e** a ses bornes modifi\xe9es, `sessionDurationMinutes` est recalcul\xe9e \xe0 partir de la **nouvelle plage** en conservant l’\xe9cart de pause implicite (plus seulement un delta qui laissait une dur\xe9e obsol\xe8te, p. ex. 24 h pour une fen\xeatre de 8 h 30). \xc0 la **cl\xf4ture live** avec une fin pass\xe9e, la dur\xe9e est **plafonn\xe9e** au span mural `d\xe9but → fin`."]},{version:"1.0.0-beta.46",items:["**Tri chronologique** : les t\xe2ches planifi\xe9es sont maintenant affich\xe9es de la plus proche (en haut) \xe0 la plus \xe9loign\xe9e (en bas), tri\xe9es par `startTime` ascendant.","**Compteur \xe0 z\xe9ro** : les t\xe2ches planifi\xe9es affichent `0:00` au lieu de leur dur\xe9e planifi\xe9e, puisqu'elles n'ont pas encore d\xe9marr\xe9."]},{version:"1.0.0-beta.45",items:["**Bouton +N min** : dans la carte lat\xe9rale et la liste des sessions, un bouton ambre prolonge la session de N minutes (configurable via `dashboardSessionExtendMinutes`, d\xe9faut 30).",'**Fin auto planifi\xe9e** : le mode "Planifi\xe9" de la nouvelle session calcule automatiquement la fin \xe0 `d\xe9but + heures de base` (configurable via `dashboardBaseDailyHours`).',"**Nouveau param\xe8tre** : `dashboardSessionExtendMinutes` (30 par d\xe9faut) dans les param\xe8tres serveur.","**Minuteur t\xe2che temps r\xe9el** : correction du red\xe9marrage toutes les 2 secondes — `derivedLiveBaseMs` utilise d\xe9sormais `task.durationMs` quand il n'y a pas de laps, au lieu de repartir de z\xe9ro.","**Heure de fin sur t\xe2che temps r\xe9el** : le champ `taskEndDraft` n'est plus auto-rempli avec `startTime + dur\xe9e mini` pour les t\xe2ches sans heure de fin explicite.","**Suggestions de mod\xe8les invisibles** : la liste `<ul>` \xe9tait rendue dans un anc\xeatre avec `backdrop-filter`, ce qui brisait le positionnement `fixed`. Passage par `createPortal` → `document.body`.","**Format `@projet#tag` dans les mod\xe8les** : les tags scop\xe9s sont maintenant format\xe9s correctement (`@acme#dev` au lieu de `#acme#dev`) et le projet implicite n'est plus dupliqu\xe9.",'**Autocomplete navigateur d\xe9sactiv\xe9** : `autoComplete="off"` sur le champ titre de t\xe2che pour ne plus m\xe9langer suggestions navigateur et mod\xe8les Kronosys.',"**D\xe9filement panneaux lat\xe9raux** : \xe9couteur `scroll` ajout\xe9 dans `DashboardSideDrawerTopSync` + `overflow-y-auto` sur le `<nav>` de la liste des sessions.",'**Titre panneau droit** : mis \xe0 jour en "\xc9tiquettes, projets et mod\xe8les" (FR) / "Tags, projects & templates" (EN).']},{version:"1.0.0-beta.44",items:["**Before/After payload** : chaque action enregistre maintenant un snapshot JSON de la session live avant et apr\xe8s l'ex\xe9cution. Dans `/logs`, cliquez sur une ligne pour voir le d\xe9tail (requ\xeate, \xe9tat avant, \xe9tat apr\xe8s)."]},{version:"1.0.0-beta.43",items:['**T\xe2ches planifi\xe9es** : les t\xe2ches dont le d\xe9but est dans le futur s\'affichent avec un style distinct (fond sky, bordure pointill\xe9e, pastille "Planifi\xe9" dans la colonne des noms). L\xe9gende mise \xe0 jour.',"**Correction d\xe9rive affichage minuteur** : si `mainTimerSegmentStartedAt` est ant\xe9rieur \xe0 `startTime`, le calcul utilise `startTime` comme borne minimale → plus de dur\xe9es gonfl\xe9es."]},{version:"1.0.0-beta.42",items:["**Ajout de laps manuel** : nouvelle action serveur `addTaskTimerLap` pour ins\xe9rer un laps dans une t\xe2che existante, avec recalcule de `durationMs`. Permet de combler les trous dans la frise sans recr\xe9er une t\xe2che.","**Clic sur les trous** : cliquez sur une zone vide du Gantt pour ajouter une t\xe2che \xe0 cet instant pr\xe9cis.","**Suppression de t\xe2che** : le bouton Corbeille est r\xe9activ\xe9 dans la modale d'inspection des t\xe2ches (Rapports), avec confirmation de suppression."]},{version:"1.0.0-beta.41",items:["**Timeline dans Rapports** : s\xe9lectionnez une journ\xe9e dans le tableau \xab Recorded time by project \xbb pour afficher le Gantt (t\xe2ches, laps, barres). Bouton \xab + Ajouter une t\xe2che \xbb pour ajouter une t\xe2che oubli\xe9e \xe0 une session de la journ\xe9e. Navigation par semaine int\xe9gr\xe9e.","**Gantt — colonne sticky** : les noms de t\xe2ches restent fixes au scroll horizontal (tableau → `position: sticky`).","**Gantt — barres cliquables** : cliquez sur une barre pour ouvrir la modale de modification de la t\xe2che.","**Gantt — fen\xeatre temporelle** : d\xe9but 30 min avant la session, fin 30 min apr\xe8s (ou fin de journ\xe9e si session live). Scroll automatique \xe0 la premi\xe8re t\xe2che.","**Boutons Today/Now** : \xab Today \xbb conserve l'heure s\xe9lectionn\xe9e (ne change que la date) ; \xab Now \xbb met date et heure \xe0 l'instant courant.","**Scroll restoration** : la sauvegarde/restauration de position dans Rapports ne s'ex\xe9cute qu'au premier chargement, plus de fighting avec le scroll.",'**Variance nette** : la colonne totale de la ligne "\xc9cart" affiche maintenant la diff\xe9rence nette entre le temps enregistr\xe9 et les heures de base (ex. `+2 h 30 min`) au lieu des heures de base seules, avec la m\xeame colorim\xe9trie que les cellules individuelles.']},{version:"1.0.0-beta.39",items:["**Gantt \xab Aujourd'hui \xbb** : les laps des t\xe2ches \xe9taient perdus dans la vue \xab Today timeline \xbb — une seule barre apparaissait par t\xe2che au lieu d'une barre par lap. Corrig\xe9 en copiant `taskTimerLaps` et `taskCurrentLapStartedAt` dans les t\xe2ches merg\xe9es."]},{version:"1.0.0-beta.38",items:["**@default** : les t\xe2ches sans projet explicite re\xe7oivent automatiquement le projet `@default` pour un suivi \xe9quilibr\xe9 dans les rapports.","**Avertissement** : un bandeau appara\xeet dans *Billing allocation* quand du temps est allou\xe9 \xe0 `@default`.","**Heures de base** : nouveau champ configurable dans *Settings* (d\xe9faut 7,5 h/jour) avec tol\xe9rance (d\xe9faut \xb110 min).",'**Ligne d\'\xe9cart** : dans *Recorded time by project*, une ligne "\xc9cart" compare le total journalier aux heures de base. Color\xe9e en \uD83D\uDD34\uD83D\uDFE2\uD83D\uDFE0 selon le seuil de tol\xe9rance.',"**Arrondi quart d'heure** : chaque cellule dur\xe9e affiche l'arrondi au 15 min entre parenth\xe8ses (ex. `31 min 55 s (0,50 h)`).","**Chevron align\xe9** : le bouton collapse/expand est maintenant \xe0 droite du nom du projet dans le tableau, pour un alignement vertical parfait.","**Abr\xe9viation** : toutes les dates (sessions, t\xe2ches, Gantt) incluent le jour de la semaine (ex. `lun. 2026-06-03`).","**Inspecteur persistant** : le panneau de d\xe9tail des t\xe2ches (clic sur une cellule dur\xe9e) ne se ferme plus au clic \xe0 l'ext\xe9rieur — permet des modifications multiples sans rouvrir.","**R\xe9sum\xe9 session** : l'en-t\xeate du panneau affiche maintenant les bornes d\xe9but/fin de la session concern\xe9e, pour \xe9viter de corriger des entr\xe9es hors p\xe9riode.","**Timer t\xe2che planifi\xe9e** : le minuteur n'affiche plus la dur\xe9e totale depuis le d\xe9but pr\xe9vu au moment de l'activation (ex. 30 min pour une t\xe2che 9h30 activ\xe9e \xe0 10h). Il d\xe9marre maintenant pr\xe8s de z\xe9ro et s'accumule progressivement.","**Conflit concurrent** : la modale de conflit ne s'affiche plus quand on ajoute une t\xe2che pass\xe9e (mode *past*) alors qu'une t\xe2che est active dans la session live.","**S\xe9lecteur de mode t\xe2che** : les ic\xf4nes Temps r\xe9el (⚡) et Pass\xe9 (\uD83D\uDD50) ont maintenant un anneau violet (`ring-2`) quand elles sont s\xe9lectionn\xe9es, pour un rep\xe8re visuel clair sur les deux th\xe8mes.","**Ic\xf4nes plus nettes** : dimensions des boutons ic\xf4nes pass\xe9es de `rem` \xe0 `px` (`30px`), `strokeWidth` uniformis\xe9 \xe0 `2`, et `box-sizing: border-box` ajout\xe9 — \xe9limine le flou d\xfb aux dimensions fractionnaires.","**Format chronom\xe8tre** : le temps est toujours affich\xe9 `HH:MM:SS.cc` (ex. `00:02:00.00` au lieu de `2:00.00`) pour \xe9viter la confusion entre minutes et heures."]},{version:"1.0.0-beta.37",items:["**Migration compl\xe8te** : toutes les pr\xe9f\xe9rences locales (`localStorage`) sont d\xe9sormais g\xe9r\xe9es par **Zustand** avec middleware `persist`, rempla\xe7ant le pattern manuel `useState` + `useEffect` + `read/write`. 8 stores, ~200 lignes de code en moins.","**Vue active** (Allocation / Rythme / Avanc\xe9) : conserv\xe9e entre les visites.","**Scope Travail/Personnel** : m\xe9moris\xe9.","**Filtres p\xe9riode et tags** : persist\xe9s.","**D\xe9tail des sections** (d\xe9pli\xe9/repli\xe9) : conserv\xe9.","**Position de d\xe9filement** : restaur\xe9e en revenant sur la page (sauvegard\xe9e par onglet).","**194 issues utilisateur** cr\xe9\xe9es sur GitLab \xe0 partir des *user stories* de la page `/implementation`.","**Labels** : `group::*` (8 groupes), `implemented`, `integration-checked`, `e2e-checked`, `discarded`.","**Synchro au build** : `npm run build` met \xe0 jour `implementationNotes.ts` depuis GitLab (si token configur\xe9), les flags `implemented`/`integrationChecked`/`e2eChecked` sont align\xe9s sur les labels GitLab.","**D\xe9pendance** : `zustand` (state management).","**Refactor** : 6 anciens fichiers de stockage localStorage supprim\xe9s, ~150 lignes de hooks et `useEffect` retir\xe9es.","**Pipeline** : la commande `build` inclut d\xe9sormais `node scripts/sync-implementation.mjs` avant Next build."]},{version:"1.0.0-beta.36",items:["**D\xe9filement (xl+)** : la liste des sessions d\xe9file **dans le tiroir** (une seule zone scroll) ; la carte session s\xe9lectionn\xe9e reste fixe au-dessus de la liste quand elle y est affich\xe9e. Corrige le double scroll ou le d\xe9filement bloqu\xe9 avec les tiroirs lat\xe9raux.","**Dur\xe9e session** (correction d\xe9but/fin) : l'ajustement du d\xe9but ou de la fin d'une session modifie `sessionDurationMinutes` par **\xe9cart** (delta) au lieu de recalculer toute la plage `d\xe9but → fin` — le temps de pause reste donc d\xe9duit quand on recale les bornes.","**Finalisation intempestive** : le s\xe9lecteur date/heure ne conserve plus des `hour`/`minute` obsol\xe8tes du montage initial — un `useEffect` rafra\xeechit les parties \xab maintenant \xbb \xe0 chaque ouverture, ce qui \xe9vite la soumission involontaire d'un horaire pass\xe9 et la finalisation de session au moment de choisir une fin future.","**Affichage dur\xe9e** : le panneau session pr\xe9f\xe8re la valeur serveur `sessionDurationMinutes` (qui d\xe9duit les pauses) \xe0 la d\xe9rivation `endAt − startAt` c\xf4t\xe9 client.","**Saisie automatique des horaires** : lorsqu'un mod\xe8le fournit `lastUsedStartTime` et `lastUsedEndTime`, la modale horaire est **contourn\xe9e** ; les cr\xe9neaux (d\xe9cal\xe9s sur la journ\xe9e courante) et la dur\xe9e du minuteur sont pr\xe9remplis directement dans le lanceur — l'utilisateur peut valider imm\xe9diatement par **Entr\xe9e**, sans confirmation interm\xe9diaire.","**Point vert dans la barre d'outils** : un **point vert puls\xe9** appara\xeet dans la barre de navigation (\xe0 c\xf4t\xe9 des ic\xf4nes de route) lorsqu'une **version plus r\xe9cente** est disponible sur le registre npm. Au survol, un tooltip affiche le num\xe9ro de version (`vX.Y.Z`) ; un clic m\xe8ne au **changelog** (`/changelog`). La v\xe9rification est mise en cache **1 heure** c\xf4t\xe9 serveur (`GET /api/version-check`) et rafra\xeechie toutes les heures c\xf4t\xe9 client.","**Dur\xe9e session delta** : trois tests unitaires (`server/actionDispatch.test.ts`) v\xe9rifient que `setSessionStartTime` et `setSessionEndTime` ajustent `sessionDurationMinutes` par \xe9cart (delta) plut\xf4t que par recalcul int\xe9gral — y compris pour une session live avec pause.","**Comparaison semver** : `lib/semverCompare.test.ts` — `isNewerVersion` couvre majeurs, mineurs, correctifs, pr\xe9release (beta.N) et formats invalides (8 cas).","**Guide utilisateur** : mod\xe8les de t\xe2che — contournement de la modale quand les horaires sont fournis par le mod\xe8le (`lib/userGuideCopy.ts`, `docs/USER_GUIDE.md`).","**Impl\xe9mentation** : `lib/implementationNotes.ts`, `docs/IMPLEMENTATION_DETAILS.md` — p\xe9rim\xe8tre **1.0.0-beta.36** (nouvelle story **indicateur version**, flags `integrationChecked` sur correction horodatage)."]},{version:"1.0.0-beta.35",items:["**Dur\xe9e totale planifi\xe9e** : affich\xe9e seulement lorsqu’une session live a une **fin planifi\xe9e** (`scheduledEndAt`) ; ligne masqu\xe9e sinon. **Total planifi\xe9 (t\xe2ches)** : idem — uniquement s’il existe des t\xe2ches encore planifi\xe9es.","**D\xe9but / fin** sur les cartes (planifi\xe9es, en cours, termin\xe9es) : **m\xeame interaction** que le lanceur en mode pass\xe9 — bouton r\xe9sum\xe9 **d\xe9but → fin** ouvrant une **seule modale** avec les deux calendriers **inline** (plus de popover/modale empil\xe9e) ; **fin facultative** ; dur\xe9e du minuteur affich\xe9e seulement si une fin est renseign\xe9e. **Laps de suivi** : m\xeame bouton et modale, avec le **#** et la **dur\xe9e** du lap sur la ligne. **Nouvelle session** : calendriers pass\xe9 / imm\xe9diat \xe9galement inline dans la modale.","**Allocation facturation** : le KPI **Temps de t\xe2che enregistr\xe9** refl\xe8te le **total de la semaine affich\xe9e** (navigation de semaine), pas toute la plage filtr\xe9e.","**Vues** : trois **cartes centr\xe9es** (Allocation facturation, Rythme, Avanc\xe9) avec une courte description de l’objectif de chaque vue.","**Aide (?)** : **un seul** bouton d’aide par section (grilles #/@, graphiques, synth\xe8se, tableau journalier, etc.) ; sous-titres \xab Calendrier hebdomadaire \xbb redondants retir\xe9s.","**Mise en page** : sections **Temps par \xe9tiquette** et **Temps par projet** align\xe9es (m\xeame encadr\xe9, m\xeame indentation des colonnes).","**Guide utilisateur** : modale horaire unique (calendriers inline, fin facultative), laps de suivi, rapports et totaux planifi\xe9s session (`lib/userGuideCopy.ts`, `docs/USER_GUIDE.md`).","**Impl\xe9mentation** : `lib/implementationNotes.ts`, `docs/IMPLEMENTATION_DETAILS.md` — p\xe9rim\xe8tre **1.0.0-beta.35**.","Release **1.0.0-beta.35** : `npm test`, `npm run changelog:build`, `npm run pack:release`, `npm run release:verify` (voir `.cursor/rules/release-workflow.mdc`)."]},{version:"1.0.0-beta.34",items:["**Correctif tarball** : le paquet npm embarque un **changelog in-app** et un **`kronosys-package-meta.json`** align\xe9s sur la version semver du paquet (corrige **1.0.0-beta.33**, publi\xe9e avec un build stale affichant encore **beta.32** dans le changelog et la version standalone).","**Garde-fous release** (obligatoires avant publish) :","`scripts/lib/releaseVersionAlignment.mjs` — logique partag\xe9e + tests ;","`verify-standalone-pack-alignment.mjs` — pr\xe9-pack : semver, lockfile, m\xe9ta standalone, changelog embarqu\xe9 ;","`verify-packed-tarball.mjs` — post-pack : contenu r\xe9el du `.tgz` ;","`pack-with-zip.sh` — build explicite → v\xe9rif pr\xe9-pack → `npm pack --ignore-scripts` → v\xe9rif tarball ;","`prepublishOnly` — rebuild + v\xe9rif standalone si publish sans tarball pr\xe9-construit ;","`sync-standalone-assets.mjs` — auto-v\xe9rif apr\xe8s \xe9criture du m\xe9ta-fichier."]},{version:"1.0.0-beta.33",items:["**Sessions** (gauche) et **\xc9tiquettes / projets** (droite) : tiroirs **coll\xe9s au bord du viewport** (`left` / `right` : 0 + encoche safe-area) au lieu d’\xeatre d\xe9cal\xe9s vers le centre du conteneur max 1920px ; largeur ouverte toujours proportionnelle (**1fr** de l’ancienne grille `1fr / 2,25fr / 1fr`, calcul\xe9e sur **100vw**). La colonne **T\xe2ches** reste centr\xe9e dans le flux ; repli\xe9 : bande **2,75 rem** au bord d’\xe9cran. Mode focus inchang\xe9 (alignement bord + repli haut).","**Mode pass\xe9 / archive** : bouton **R\xe9gler d\xe9but, fin et dur\xe9e…** ouvrant une **modale** (d\xe9but, fin, dur\xe9e du minuteur) — plus de bloc horaire inline dans le lanceur ; les calendriers internes s’ouvrent en popover ancr\xe9 dans cette modale.","**Mod\xe8les et titres r\xe9currents** : liste d\xe9roulante **pleine largeur** de la ligne titre (remplace le `datalist` natif \xe9troit) ; filtrage diff\xe9r\xe9 inchang\xe9 ; m\xe9morisation des **derni\xe8res heures de d\xe9but/fin** utilis\xe9es (r\xe9appliqu\xe9es sur la **journ\xe9e courante** \xe0 la s\xe9lection, mode pass\xe9).","**Carte t\xe2che — horaires** : calendriers **d\xe9but** / **fin** (et laps) en **modale centr\xe9e** plein \xe9cran (portail `document.body`, plus de popover rogn\xe9 dans la carte) ; question d’**ajustement de dur\xe9e** uniquement \xe0 la modification de la **fin** ; le **d\xe9but** s’applique directement et **r\xe9aligne** le lap en cours (minuteur actif ou en pause) sur le nouveau d\xe9but ; t\xe2che **termin\xe9e** \xe0 un seul lap : le lap suit les bornes corrig\xe9es. **Correctif** : \xe0 la terminaison, `durationMs` est **r\xe9concili\xe9** sur la somme des laps (\xe9vite l’affichage 1 h pour un cr\xe9neau 10:30→11:00 avec lap 30 min).","**Points de d\xe9tail** : lien **Ajouter un point de d\xe9tail** (comme **Ajouter une note**) tant qu’il n’y en a aucun ; le champ d’ajout n’appara\xeet qu’apr\xe8s clic ou lorsqu’au moins un point est d\xe9j\xe0 list\xe9.","**Correctif terminer une t\xe2che** : une t\xe2che **termin\xe9e** (bouton Terminer) n’appara\xeet plus \xe0 tort dans **En pause** lorsque la pile active contenait des copies dupliqu\xe9es du m\xeame identifiant.","**Correctif lanceur pass\xe9** : le bascule **Temps r\xe9el / Pass\xe9** et les champs d\xe9but/fin/dur\xe9e restent accessibles **sans session live** (ex. apr\xe8s cl\xf4ture) ; l’ajout d’une t\xe2che pass\xe9e **cr\xe9e la session** automatiquement si besoin.","**Correctif minuteur t\xe2che planifi\xe9e** : apr\xe8s correction du **d\xe9but** (alignement au cr\xe9neau), le gros compteur vert ne **double** plus le temps (ex. ~58 min affich\xe9es pour ~28 min r\xe9elles) ; une **fin planifi\xe9e future** ne gonfle plus `durationMs` sur toute la plage lors du recalcul des bornes.","**Guide utilisateur** : modale **entr\xe9e pass\xe9e** (lanceur), calendriers modale sur cartes t\xe2che, tiroirs bord viewport, correctifs minuteur / terminaison (`lib/userGuideCopy.ts`, `docs/USER_GUIDE.md`)."]},{version:"1.0.0-beta.32",items:["**Fin planifi\xe9e / fin renseign\xe9e** : la **barre de progression** est sur la **m\xeame ligne** que **D\xe9but** et **Fin** (\xe0 droite), au lieu d’une ligne pleine largeur en dessous.","**Note libre** : lien **Ajouter une note** / **Add a note** pour afficher le champ ; si la note est **vide**, le bloc est masqu\xe9 (carte et lanceur). Au **lanceur**, le champ source n’appara\xeet qu’apr\xe8s ouverture explicite du lien (brouillon non vide sans \xe9diteur ouvert reste masqu\xe9). Une note **enregistr\xe9e** sur une carte reste affich\xe9e en lecture (clic pour modifier) ; aide Markdown **(?)** \xe0 c\xf4t\xe9 du lien ou du champ.","**Correctif note au lanceur** : suppression de l’aper\xe7u Markdown sous le champ pendant la saisie — le texte n’appara\xeet plus en double (source + rendu).","**Espacement** : r\xe9duction de l’\xe9cart entre la note et le bloc **sous-t\xe2ches**.","**Disposition align\xe9e sur les cartes** : mode maintenant/pass\xe9, KronoFocus, aide et pastilles projet / `#\xe9tiquettes` **en haut \xe0 droite** ; **titre** avec bouton **D\xe9marrer / Ajouter** **en fin de ligne** (comme avant pour ce seul contr\xf4le), puis **note** en dessous (`TaskFocusPanel.tsx`).","**Tiroir repliable (xl+)** : le lanceur est encadr\xe9 comme les tiroirs lat\xe9raux (bordure, flou, coins arrondis) ; **une seule ligne d’en-t\xeate** fusionne le titre **T\xe2ches** / **Tasks**, le **d\xe9compte par statut**, l’indicateur **SUIVI**, les **dates pass\xe9es** (mode pass\xe9) et le **chevron** d\xe9plier / replier (pas de languette) ; repli\xe9 : bandeau compact (m\xeame ligne, formulaire masqu\xe9) ; \xe9tat m\xe9moris\xe9 (`kronosys.dashboard.taskLauncherDrawer.open.v1`, `DashboardTaskLauncherDrawer.tsx`). Sous xl : toujours d\xe9ploy\xe9.","**Libell\xe9 du lanceur** : l’en-t\xeate du formulaire d’entr\xe9e et l’en-t\xeate repli\xe9 affichent **T\xe2ches** / **Tasks** (align\xe9 sur la colonne) au lieu de **En cours** / **In focus** ; **En cours (minuteur)** reste r\xe9serv\xe9 \xe0 la liste des t\xe2ches au minuteur actif.","**Guide utilisateur** : note repliable, position de la barre de progression sur les cartes, disposition du **lanceur de t\xe2che** (libell\xe9 **T\xe2ches** / **Tasks**, **expand/collapse** par chevron), **tiroir repliable** du lanceur (`lib/userGuideCopy.ts`, `docs/USER_GUIDE.md`).","**Aide (?)** : texte d’intro Markdown align\xe9 sur le flux **Ajouter une note** (`lib/dashboardCopy.ts`).","Release **1.0.0-beta.32** : bump semver, `npm run build`, `npm run pack:release`, `npm run changelog:build`, `npm run release:verify`. Publication npm au commit `chore(release): 1.0.0-beta.32` (voir `.cursor/rules/release-workflow.mdc`)."]},{version:"1.0.0-beta.31",items:["**Changelog in-app** : r\xe9g\xe9n\xe9ration `lib/generatedUserChangelog.ts` (`npm run changelog:build`) align\xe9e sur **1.0.0-beta.31**.","**Guide utilisateur** : en-t\xeate `docs/USER_GUIDE.md` et r\xe9f\xe9rences semver **`1.0.0-beta.31`** (2026-05-29).","**Impl\xe9mentation** : `lib/implementationNotes.ts`, `docs/IMPLEMENTATION_DETAILS.md`, `docs/README.md`, `README.md` — r\xe9f\xe9rences semver synchronis\xe9es.","**Workflow release** : script `scripts/verify-release-alignment.mjs` et r\xe8gle `.cursor/rules/release-workflow.mdc` — v\xe9rification locale avant tag et publish.","**Build standalone** : `npm run build` obligatoire avant `npm run pack:release` pour garantir un tarball npm avec l’UI \xe0 jour.","Release **1.0.0-beta.31** : bump semver, `npm run build`, `npm run pack:release`, `npm run changelog:build`, `npm run release:verify`. Publication npm au commit `chore(release): 1.0.0-beta.31` (voir `.cursor/rules/release-workflow.mdc`)."]},{version:"1.0.0-beta.30",items:["**Mode focus** : masque l’en-t\xeate, les bandeaux et le pied de page pour n’afficher que les **trois colonnes** (sessions, t\xe2ches, \xe9tiquettes / projets). Bouton **agrandir** dans la barre d’outils (\xe0 c\xf4t\xe9 du th\xe8me) ; **\xc9chap** ou bouton **r\xe9duire** en haut \xe0 droite pour quitter. Raccourci par d\xe9faut : **Alt+Shift+F** (modifiable dans la modale raccourcis). Pr\xe9f\xe9rence m\xe9moris\xe9e dans le navigateur.","**Palette donn\xe9es** (Ctrl+K / ⌘K) : commande **Basculer le mode focus** (`toggle-focus-mode`, `DashboardCommandCenter`) — en compl\xe9ment du bouton **agrandir**, du raccourci **Alt+Shift+F** et de la sortie **\xc9chap** / bouton **r\xe9duire**.","**Sessions** (gauche) et **\xc9tiquettes et projets** (droite) : panneaux repliables en tiroirs (`DashboardSideDrawer`, xl+) ; \xe0 l’ouverture, largeur lat\xe9rale identique \xe0 l’ancienne colonne **1fr** (grille `1fr / 2.25fr / 1fr`, conteneur max 1920px) ; repli\xe9 : languette **2,75 rem** avec libell\xe9 vertical (titre de colonne). La colonne **T\xe2ches** reste centr\xe9e sans d\xe9calage ; sa largeur max augmente de **20 % par tiroir repli\xe9** (base **42 rem**). \xc9tat m\xe9moris\xe9 dans le navigateur (`lib/dashboardSideDrawerStorage.ts`). Sous xl : disposition empil\xe9e inchang\xe9e.","**Bande repli\xe9e** : ic\xf4ne de colonne (`DashboardColumnTitleIcon`) au-dessus du **libell\xe9 vertical** ; languette vers la colonne T\xe2ches ; **Alignement sous l’en-t\xeate** via `DashboardSideDrawerTopSync` (`--kronosys-dash-drawer-top`) ; en mode focus, tiroirs cal\xe9s en haut de page.","**Ligne de titre** : \xe0 c\xf4t\xe9 du **total**, d\xe9compte par bloc (**En cours**, **Planifi\xe9es**, **En pause**, **Compl\xe9t\xe9es**, **Non termin\xe9es (instantan\xe9)**) — segments non nuls align\xe9s sur les en-t\xeates de `TaskFocusPanel` (`lib/taskColumnStatusSummary.ts`).","**KronoFocus** reste **toujours visible** dans la barre d’outils (\xe0 c\xf4t\xe9 de l’horloge), sur toutes les pages principales.","**Carte t\xe2che** : **minuteur live** \xe0 droite sur la **ligne du titre** ; boutons d’action ic\xf4ne compacts sur une ligne sous le titre.","**Dur\xe9e restante** sous **Dur\xe9e** lorsque `scheduledEndAt` est renseign\xe9 ; barre de progression sous **Fin** ; **Nouvelle session** avec fin planifi\xe9e optionnelle → cl\xf4ture automatique.","**Markdown** titre (inline) et note (block) ; aide **(?)** ; GFM ; popover **laps de suivi** au survol Gantt.","**Note** : champ source auto-ajust\xe9 en hauteur (`TaskNoteTextarea`, `ResizeObserver`).","**D\xe9but avec minuteur actif** : modale **Tour de minuteur en cours** (`lapAdjustMode`).","**Laps enregistr\xe9s** : \xe9dition d\xe9but/fin et suppression sur la carte.","**Rouvrir** (↺) une t\xe2che termin\xe9e ; **dur\xe9e minimale** et pr\xe9remplissage fin ; **\xe9tiquette \xab d\xe9faut \xbb** et retrait automatique avec `#tag` explicite.","**Nouvelle session** d\xe9but r\xe9troactif + fin future → session live planifi\xe9e.","Bascule **Prod** / **QA** imm\xe9diate (`resetSqliteConnection`) — sans red\xe9marrage requis.","**Param\xe8tres → Tableau de bord web** : **\xab Ne pas distinguer par la couleur seule \xbb** — pr\xe9fixes `#` / `@` / `!` et bordures distinctes sur les pastilles (`lib/semanticChipAccessibleMode.ts`).","**Guide utilisateur** : `lib/userGuideCopy.ts`, `docs/USER_GUIDE.md` — en-t\xeate **`1.0.0-beta.30`** (2026-05-28).","**Impl\xe9mentation** : `lib/implementationNotes.ts`, `docs/IMPLEMENTATION_DETAILS.md`, `docs/README.md`.","**Tests** : suite Vitest compl\xe8te (543 tests) ; couverture tiroirs, focus mode, r\xe9sum\xe9 statuts, pastilles accessibles, Markdown, laps, QA switch, etc.","**Correctifs build** : `lib/taskMarkdownComponents.tsx`, `lib/taskTimelineGantt.ts`, `formatProjectDisplay` (libell\xe9s `!` en rapports).","Release **1.0.0-beta.30** : bump semver, `npm run build`, `npm run pack:release`, `npm run changelog:build`, `npm run release:verify`. Publication npm au commit `chore(release): 1.0.0-beta.30` (voir `.cursor/rules/release-workflow.mdc`)."]},{version:"1.0.0-beta.29",items:["**Mode focus** : masque l’en-t\xeate, les bandeaux et le pied de page pour n’afficher que les **trois colonnes** (sessions, t\xe2ches, \xe9tiquettes / projets). Bouton **agrandir** dans la barre d’outils (\xe0 c\xf4t\xe9 du th\xe8me) ; **\xc9chap** ou bouton **r\xe9duire** en haut \xe0 droite pour quitter. Raccourci par d\xe9faut : **Alt+Shift+F** (modifiable dans la modale raccourcis). Pr\xe9f\xe9rence m\xe9moris\xe9e dans le navigateur.","**Palette donn\xe9es** (Ctrl+K / ⌘K) : commande **Basculer le mode focus** (`toggle-focus-mode`, `DashboardCommandCenter`) — en compl\xe9ment du bouton **agrandir**, du raccourci **Alt+Shift+F** et de la sortie **\xc9chap** / bouton **r\xe9duire**.","**Sessions** (gauche) et **\xc9tiquettes et projets** (droite) : panneaux repliables en tiroirs (`DashboardSideDrawer`, xl+) ; \xe0 l’ouverture, largeur lat\xe9rale identique \xe0 l’ancienne colonne **1fr** (grille `1fr / 2.25fr / 1fr`, conteneur max 1920px) ; repli\xe9 : languette **2,75 rem** avec libell\xe9 vertical (titre de colonne). La colonne **T\xe2ches** reste centr\xe9e sans d\xe9calage \xe0 l’ouverture ou la fermeture ; sa largeur max augmente de **20 % par tiroir repli\xe9** (base **42 rem**). \xc9tat m\xe9moris\xe9 dans le navigateur (`lib/dashboardSideDrawerStorage.ts`). Sous xl : disposition empil\xe9e inchang\xe9e.","**Bande repli\xe9e** : ic\xf4ne de colonne (`DashboardColumnTitleIcon` — Historique / \xc9tiquettes) au-dessus du **libell\xe9 vertical** du titre ; m\xeame pictogramme que la rang\xe9e titre ouverte.","**Languette** : centr\xe9e verticalement sur le **bord int\xe9rieur** (vers la colonne T\xe2ches) ; en repli, positionn\xe9e vers le bas pour \xe9viter le chevauchement du libell\xe9 vertical.","**Alignement sous l’en-t\xeate** : `DashboardSideDrawerTopSync` mesure la bande des colonnes et pose `--kronosys-dash-drawer-top` pour que les tiroirs restent visibles sous la barre d’outils ; en **mode focus**, les tiroirs se calent en haut de page (`app/globals.css`).","**Ligne de titre** : \xe0 c\xf4t\xe9 du **total**, d\xe9compte par bloc (**En cours**, **Planifi\xe9es**, **En pause**, **Compl\xe9t\xe9es**, **Non termin\xe9es (instantan\xe9)**) — segments non nuls align\xe9s sur les en-t\xeates de `TaskFocusPanel` (`lib/taskColumnStatusSummary.ts`, `buildTaskColumnStatusSegments`).","**Panneau timing** : sous **Dur\xe9e**, **Dur\xe9e restante** affiche le temps jusqu’\xe0 la fin planifi\xe9e (`scheduledEndAt`) lorsqu’une heure de fin est renseign\xe9e ; sinon **Ind\xe9termin\xe9e** — bloc **Session en cours** (`SelectedSessionSidebarBlock.tsx`).","**Fin planifi\xe9e** : barre de progression sous la ligne **Fin** (m\xeame logique que les cartes t\xe2che : avancement de `startAt` vers `scheduledEndAt`, alerte visuelle < 15 / 5 min).","**Actions session** : boutons Gantt / terminer la session, **Nouvelle session** (+), **Archives**, crayon nom, et ic\xf4nes de ligne de liste — gabarit compact des cartes t\xe2che (`TASK_CARD_ICON_BTN_*`, 30\xd730 px, ic\xf4nes 14 px).","**Nouvelle session (Maintenant)** : fin planifi\xe9e optionnelle d\xe8s la modale **Nouvelle session** → cl\xf4ture automatique \xe0 l’\xe9ch\xe9ance (`scheduledEndAt` sur `newSession`).","**Actions** : boutons ic\xf4ne compacts (m\xeame \xe9chelle que les pastilles `#` / `@`) sur une **ligne sous le titre** ; le titre occupe toute la largeur (minuteur live \xe0 droite sur la ligne du titre).","**Fin planifi\xe9e** : barre de progression sous **D\xe9but** / **Fin** lorsque `scheduledEndAt` est d\xe9fini (avancement de `startTime` vers l’\xe9ch\xe9ance).","**Modale enrichie** : lorsqu’une t\xe2che **au minuteur** (lap en cours) voit son **d\xe9but** modifi\xe9, une section **Tour de minuteur en cours** propose de **conserver** le lap, le **cl\xf4turer** (enregistr\xe9 dans `taskTimerLaps`) ou le **r\xe9aligner** sur le nouveau d\xe9but — en plus du recalcul de la **dur\xe9e totale** d\xe9j\xe0 existant.","**Serveur** : `setTaskStartTime` accepte `lapAdjustMode` (`keep` | `flush` | `align_start`) ; impl\xe9ment\xe9 dans `updateTaskStartTimeInSession`.","**Titre** : en lecture sur la carte, Markdown **inline** rendu (`TaskMarkdownContent`, variante `inline`) — gras, italique, lien, code ; les listes et aper\xe7us compacts retirent la syntaxe (`stripTaskMarkdownPlainText`).","**Note libre** : Markdown **block** rendu sur la carte (`TaskNoteField`) ; clic pour \xe9diter la source ; aper\xe7u live sous le champ au **lanceur** de t\xe2che ; ic\xf4ne **(?)** (`TaskMarkdownHelpTrigger`) avec exemples source + rendu.","**Saisie note** : le champ source (`TaskNoteTextarea`) s’**ajuste en hauteur** automatiquement \xe0 la saisie (`ResizeObserver`) — meilleure lisibilit\xe9 lors de l’\xe9dition Markdown.","**S\xe9curit\xe9** : pas de HTML brut (`react-markdown` sans `rehype-raw`) ; liens externes `noopener`.","**GFM** : plugin `remark-gfm` — tableaux, `~~barr\xe9~~`, listes `- [ ]` / `- [x]`, autolinks ; hors scope GitLab : Mermaid, @mentions, alertes `> [!note]`, HTML.","**Gantt** : survol d’un segment de t\xe2che — popover listant tous les **laps de suivi** (`TaskTimelineGanttModal`).","**Carte t\xe2che** : section **Laps de suivi** — correction **d\xe9but/fin** par lap (popover date-heure) et **suppression** avec confirmation ; le lap **en cours** reste en lecture seule jusqu’\xe0 cl\xf4ture.","**Serveur** : actions `setTaskTimerLap` et `deleteTaskTimerLap` (`updateTaskTimerLapInSession`, `deleteTaskTimerLapInSession`) — ajustement de `durationMs` par delta, ordre chronologique entre laps contigus.","**Correctif** : la bascule **Prod** / **QA** rouvre imm\xe9diatement le bon fichier SQLite (`resetSqliteConnection` avant toute \xe9criture payload) — y compris lorsque le coffre QA existe d\xe9j\xe0 (sans modale d’amor\xe7age) ou via **Param\xe8tres → G\xe9n\xe9ral**.","**Documentation** : guide in-app (`lib/userGuideCopy.ts`) et `docs/USER_GUIDE.md` (FR/EN) — bascule **imm\xe9diate** (plus de red\xe9marrage requis) ; `lib/settingsCopy.ts` (libell\xe9s coffres) ; `lib/implementationNotes.ts` et `docs/IMPLEMENTATION_DETAILS.md`.","**Param\xe8tre** `taskMinimumDurationMinutes` (d\xe9faut **30 min**, plage **15–480**) dans **Param\xe8tres → T\xe2ches et \xe9tiquettes** (`/settings#settings-task-tags`).","**Entr\xe9e pass\xe9e** (mode \xab Pass\xe9 \xbb ou session archiv\xe9e) : le **d\xe9but** est arrondi \xe0 la **demi-heure pr\xe9c\xe9dente** ; la **fin** est pr\xe9remplie \xe0 **d\xe9but + dur\xe9e minimale** (recalcul\xe9e quand le d\xe9but change) ; la **dur\xe9e du minuteur** suit la plage d\xe9but/fin.","**T\xe2che planifi\xe9e** : sur la carte t\xe2che, la **fin** (brouillon) suit le **d\xe9but** avec le m\xeame \xe9cart ; si aucune fin n’\xe9tait encore enregistr\xe9e, une **fin planifi\xe9e** est pos\xe9e automatiquement \xe0 la validation du d\xe9but (`scheduledEndAt` via `setTaskEndTime`).","**Correctif** : une t\xe2che **termin\xe9e** dont le cr\xe9neau planifi\xe9 (d\xe9but + fin futurs) atteint son **d\xe9but** se **rouvre** et **active** le minuteur automatiquement au lieu de rester dans **Compl\xe9t\xe9es** ; un d\xe9but futur sur une t\xe2che ouverte **l\xe8ve** la pause manuelle pour permettre l’activation \xe0 l’\xe9ch\xe9ance.","**Seau par d\xe9faut** (`taskDefaultTagBucketEnabled`, inchang\xe9) : une t\xe2che **sans** `#` explicite re\xe7oit l’\xe9tiquette r\xe9serv\xe9e `default` (affich\xe9e \xab d\xe9faut \xbb en fran\xe7ais).","**Retrait automatique** (`taskStripDefaultTagWhenExplicitTags`, **activ\xe9** par d\xe9faut) : d\xe8s qu’**au moins une autre** \xe9tiquette explicite est pr\xe9sente (saisie `#…`, tableau `tags`, \xe9dition du titre), l’\xe9tiquette `default` est **retir\xe9e** — y compris lors d’une **cr\xe9ation** avec `#tag` dans le titre ou d’une **mise \xe0 jour** (`updateTask`).","**Persistance serveur** : fusion titre + `tags` \xe0 la cr\xe9ation (`startTask`, `addHistoricalTask`) via `resolveStoredTaskTagsFromTaskLine` ; normalisation centralis\xe9e dans `normalizeTaskTagsForStorage` (`lib/taskParsing.ts`).","**Param\xe8tres** : second commutateur dans **T\xe2ches et \xe9tiquettes** (`#settings-task-tags`) pour conserver volontairement `default` \xe0 c\xf4t\xe9 d’autres \xe9tiquettes.","**Fin future autoris\xe9e** : en mode \xab Dans le pass\xe9 \xbb, une **fin encore \xe0 venir** ouvre une **session live** avec `startAt` r\xe9troactif et **`scheduledEndAt`** ; l’horloge murale part du d\xe9but saisi (dur\xe9e initiale = maintenant − d\xe9but) et la session se **cl\xf4ture automatiquement** \xe0 l’\xe9ch\xe9ance — m\xeame m\xe9canisme que `setSessionEndTime` sur une session live. Si la fin est **d\xe9j\xe0 pass\xe9e**, la plage **close** reste **historis\xe9e** comme avant.","**Session live d\xe9j\xe0 ouverte** : un d\xe9but r\xe9troactif avec **fin future** d\xe9clenche d’abord le flux **fin de session** (comme \xab Maintenant \xbb), en conservant les bornes saisies ; une session **enti\xe8rement pass\xe9e** n’interrompt toujours **pas** la session active.","**Bouton Rouvrir** (↺) sur chaque carte **termin\xe9e** (session live ou archive).","**Modale** : reprendre le **minuteur** (dur\xe9e conserv\xe9e), rouvrir en **pause**, **dur\xe9e manuelle** (h/m/s) ou **remise \xe0 z\xe9ro** ; les **sous-t\xe2ches** sont rouvertes.","**Session live** : si un autre minuteur tourne d\xe9j\xe0 lors d’une **reprise**, modale **pause / terminer / parall\xe8le** (m\xeame m\xe9morisation que pour un d\xe9marrage).","**Instantan\xe9 cl\xf4tur\xe9** : pas de minuteur live — correction de **statut** et de **dur\xe9e** ; regroupement **Non termin\xe9es (instantan\xe9)** dans la colonne t\xe2ches.","**Param\xe8tres → Tableau de bord web** : option **\xab Ne pas distinguer par la couleur seule \xbb** (`dashboardSemanticChipAccessibleMode`) — pr\xe9fixes `#` / `@` / `!` et bordures distinctes (pleine, double, pointill\xe9e) sur les pastilles \xe9tiquette / projet travail / projet personnel, en compl\xe9ment des teintes vert / bleu ciel / rose (`lib/semanticChipAccessibleMode.ts`, `globals.css`, `taskFieldStyles.ts`).","**Guide utilisateur** : `lib/userGuideCopy.ts`, `docs/USER_GUIDE.md` — lot **beta.28–beta.29** (mode focus et palette, tiroirs lat\xe9raux xl+, r\xe9sum\xe9 statuts colonne T\xe2ches, note auto-ajust\xe9e, Markdown t\xe2che, laps, rouvrir t\xe2che, dur\xe9e minimale, \xe9tiquette d\xe9faut, nouvelle session fin future, pastilles accessibles, coffres Prod/QA imm\xe9diats) ; en-t\xeate **`1.0.0-beta.29`**.","**Impl\xe9mentation** : `lib/implementationNotes.ts`, `docs/IMPLEMENTATION_DETAILS.md`, `docs/README.md` — cartographie compl\xe8te du cycle ; user stories **beta.28** et **beta.29**.","**Tests** : `server/actionDispatch.test.ts`, `server/actionTaskSession.test.ts`, `test/integration/apiActionNewSessionScope.test.ts`, `test/integration/apiActionDataEnvironmentQaSeed.test.ts` ; `lib/taskMinimumDuration.test.ts`, `lib/taskParsing.test.ts`, `lib/taskColumnStatusSummary.test.ts` ; `lib/dashboardSideDrawerStorage.test.ts`, `lib/dashboardFocusMode.test.ts`, `lib/dashboardSideDrawerLayout.test.ts`, `lib/semanticChipAccessibleMode.test.ts` ; `server/mainTimerHydrate.test.ts` ; composants Markdown (`TaskMarkdownContent.test.tsx`, `TaskMarkdownHelpTrigger.test.tsx`, `TaskNotesDisplay.test.tsx`).","Release **1.0.0-beta.29** sur npm (dist-tag `beta`) : lot **beta.28** non publi\xe9 s\xe9par\xe9ment — contenu usager consolid\xe9 sous cette section ; bump `package.json` / `package-lock.json`, r\xe9g\xe9n\xe9ration `lib/generatedUserChangelog.ts` (`npm run changelog:build`), v\xe9rification `npm run release:verify` (voir `.cursor/rules/release-workflow.mdc`)."]},{version:"1.0.0-beta.28",items:["**Version non publi\xe9e sur npm** : le d\xe9veloppement \xe9tiquet\xe9 beta.28 a \xe9t\xe9 livr\xe9 dans le paquet **1.0.0-beta.29** ; l’historique d\xe9taill\xe9 des changements usagers figure dans la section **1.0.0-beta.29** ci-dessus."]},{version:"1.0.0-beta.27",items:["**Toast global** : lorsqu’une **t\xe2che planifi\xe9e** atteint son heure de d\xe9but (`startTime`) ou qu’une **session live** atteint son **`startAt` officiel**, un message temporaire s’affiche en bas \xe0 droite **sur toute route** de l’app (tableau de bord, param\xe8tres, rapports, guide, etc.) — le titre de la t\xe2che ou le nom de la session est rappel\xe9 dans le libell\xe9.","La **modale de conflit** (pause / terminer / parall\xe8le) reste affich\xe9e lorsque le passage planifi\xe9 → en cours co\xefncide avec un autre minuteur d\xe9j\xe0 actif ; le toast d’activation s’ajoute en compl\xe9ment, pas en remplacement.","**Alignement livraison** : `lib/userGuideCopy.ts`, `docs/USER_GUIDE.md`, `lib/implementationNotes.ts` et `docs/IMPLEMENTATION_DETAILS.md` — p\xe9rim\xe8tre **beta.26** document\xe9 de fa\xe7on homog\xe8ne (coffres Prod/QA et amor\xe7age QA, journal `/logs`, cr\xe9neaux planifi\xe9s, suggestions `#` / `@` / `!`, rapports avec **Travail / Personnel** et **Total jour**) ; **beta.27** : toast global \xe0 l’activation d’un cr\xe9neau planifi\xe9 ; en-t\xeates et r\xe9f\xe9rences de version **`1.0.0-beta.27`**.","**Index d\xe9p\xf4t** : `docs/README.md` (r\xf4les des fichiers, cartographie, r\xe8gles de maintenance) ; `README.md` racine — section **API HTTP** compl\xe8te (six routes, plus de mention \xab stub \xbb pour `/api/state`).","**Conception** : `docs/IMPLEMENTATION_DETAILS.md` — cartographie du code, contrats API ; **documentation in-code** sur le noyau (`server/payloadStore`, `actionDispatch`, `db`, `userActionLog`, `app/api/*`, `lib/kronosysApi.ts`).","**CHANGELOG usager** : r\xe9g\xe9n\xe9ration via `npm run changelog:build` (`lib/generatedUserChangelog.ts`).","**Tests** : `lib/plannedScheduleActivation.test.ts` — d\xe9tection planifi\xe9 → minuteur et session ; composant global `PlannedScheduleActivationWatcher` (layout racine).","Les versions **pr\xe9release** (`1.0.0-beta.*`) doivent \xeatre publi\xe9es avec un dist-tag explicite, par ex. `npm publish … --access public --tag beta` (sinon npm refuse la publication).","Bump applicatif : **`1.0.0-beta.27`** (`package.json`, `package-lock.json`)."]},{version:"1.0.0-beta.26",items:["**Deux coffres SQLite** : lorsque l’option est activ\xe9e dans **Param\xe8tres → G\xe9n\xe9ral** (*Coffres production et QA*), les donn\xe9es de production restent dans `…/v4` et un coffre **QA** isol\xe9 vit dans `…/v4-qa` (pr\xe9f\xe9rence sur disque : `data-environment-preference.json`, hors des deux dossiers).","**Bascule** : boutons **Prod** / **QA** dans la barre de navigation (visible seulement si les deux coffres sont activ\xe9s) ; action `switchDataEnvironment` ; **red\xe9marrage du serveur** requis pour ouvrir le bon fichier SQLite (comme tout changement de r\xe9pertoire de donn\xe9es).",'**Rep\xe8re visuel QA** : bandeau violet persistant, liser\xe9 et fond l\xe9g\xe8rement teint\xe9s (`data-kronosys-env="qa"` sur `<html>`) lorsque le processus sert effectivement le coffre QA.',"**Priorit\xe9** : si `TRACE_DATA_DIR` est d\xe9fini, les options prod/QA sont d\xe9sactiv\xe9es ; en `next dev`, lorsque les deux coffres sont activ\xe9s, ils priment sur le segment `v4-dev` (coffres `v4` ou `v4-qa`).","**Premier passage en QA** : si le coffre `v4-qa` n’existe pas encore, une modale propose de **copier la production** ou de **d\xe9marrer vide** avant d’enregistrer la bascule (`switchDataEnvironment` avec `qaSeed`).","**Page** `/logs` (ic\xf4ne **liste** dans le bloc navigation principal) : historique des **mutations** pass\xe9es par `POST /api/action` (type d’action, succ\xe8s/\xe9chec, horodatage, session li\xe9e, IP source).","**Persistance** : table SQLite `user_action_log` (`server/userActionLog.ts`) ; champs sensibles du corps (`token`, `password`, `uri`) **masqu\xe9s** dans le JSON archiv\xe9.","**Lecture** : `GET /api/action-logs?limit=…` ; action `clearUserActionLogs` pour vider le journal depuis l’UI.","**D\xe9but planifi\xe9** : tant que le **d\xe9but officiel** (`startTime`) d’une t\xe2che **non termin\xe9e** est encore **futur**, le **serveur** n’accumule **pas** de dur\xe9e et ne laisse **pas** tourner un segment de minuteur en arri\xe8re-plan ; \xe0 l’**heure de d\xe9but**, la t\xe2che **rejoint le suivi actif** (pile `activeTasks` si besoin) et le minuteur s’**ancre** \xe0 ce `startTime` (synchronisation d’\xe9tat, typiquement toutes les **~2 s** via `/api/state`).","**Fin planifi\xe9e** : une **heure de fin** sur une t\xe2che **en cours** pose toujours `scheduledEndAt` ; \xe0 l’\xe9ch\xe9ance, la t\xe2che se **termine** automatiquement (comportement existant, coh\xe9rent avec le d\xe9but planifi\xe9).","**`setTaskStartTime`** : un d\xe9but **futur** ne pose plus de segment de minuteur **imm\xe9diat**.","**Conflit planifi\xe9 → en cours** : si plusieurs cr\xe9neaux deviennent actifs en m\xeame temps qu’un autre minuteur tournait d\xe9j\xe0, la **modale** pause / terminer / parall\xe8le (m\xe9morisation possible) s’applique comme avant.","**Liste d\xe9roulante** : lorsque le jeton **`#`** (\xe9tiquette), **`@`** (projet travail) ou **`!`** (projet personnel) est actif dans le champ \xab sur quoi travaillez-vous \xbb ou en **\xe9dition du titre** d’une t\xe2che, une liste propose les choix **les plus utilis\xe9s** puis **les plus r\xe9cents** (fr\xe9quence dans l’historique des t\xe2ches, puis listes `knownTags` / `knownProjects` / `knownPersonalProjects`).","**Interaction** : filtrage au fil de la frappe ; navigation clavier (**↑** / **↓**, **Entr\xe9e**, **Tab**, **\xc9chap**) et s\xe9lection \xe0 la souris.","**Port\xe9e projet** : apr\xe8s `@projet#` ou `!projet#`, les suggestions **`#`** ciblent les **\xe9tiquettes li\xe9es** \xe0 ce projet.","Les **mod\xe8les de t\xe2che** (pr\xe9fixe **Mod\xe8le :**) restent propos\xe9s via le m\xe9canisme existant (`datalist`), en parall\xe8le de cette liste.","**Sessions par jour — temps des t\xe2ches** : sous chaque t\xe2che, chaque **#** affiche la **dur\xe9e compl\xe8te** enregistr\xe9e (m\xeame r\xe8gle que les grilles d’allocation #) — **plus** de r\xe9partition \xe0 parts \xe9gales lorsque plusieurs \xe9tiquettes portent sur la m\xeame ligne.","**Temps enregistr\xe9 vs planifi\xe9** : les **totaux**, graphiques et grilles # / @ ne comptent que le **temps r\xe9ellement pass\xe9** (`durationMs`, r\xe8gles d’archives inchang\xe9es). Les t\xe2ches dont le cr\xe9neau est encore **dans le futur** (m\xeame crit\xe8re d’affichage \xab planifi\xe9 \xbb que le tableau de bord) montrent une **fen\xeatre planifi\xe9e** \xe0 part (libell\xe9 ambre), sans l’ajouter aux totaux enregistr\xe9s.","**Calendriers hebdomadaires** (# et @) : ligne **Total jour** en bas de chaque tableau de semaine — **somme par colonne** (chaque jour) et **total de semaine** dans la derni\xe8re colonne.","**Grille par projet (@)** : s\xe9lecteur **Travail (@)** / **Personnel (!)** sous le calendrier hebdomadaire par projet — **Travail** (d\xe9faut) exclut le registre personnel ; **Personnel** n’affiche que le temps `!` (`personalProject` ou jeton `!` reconnu dans le titre si le drapeau manque sur d’anciennes donn\xe9es).","**Tests** : `lib/dataDir.test.ts`, `lib/dataEnvironmentPreferenceFile.test.ts` — r\xe9solution `v4` / `v4-qa`, priorit\xe9 du double coffre en dev ; `server/mainTimerHydrate.test.ts`, `server/actionTaskSession.test.ts` — d\xe9but planifi\xe9 (pas d’accumulation avant l’heure, activation et fin \xe0 l’\xe9ch\xe9ance) ; `setTaskStartTime` avec d\xe9but futur sans segment imm\xe9diat.","**Tests** : `lib/taskEntryTokenSuggest.test.ts` — d\xe9tection des jetons actifs, classement et insertion d’une suggestion.","**Tests** : `lib/reportingAggregate.test.ts` — temps planifi\xe9 exclu des agr\xe9gats enregistr\xe9s ; `lib/reportingWeekLayout.test.ts` — `sumWeekCalendarSlots`.","**Tests** : `test/integration/apiActionLogs.test.ts`, `test/integration/apiActionDataEnvironmentQaSeed.test.ts`.","**Guide utilisateur** : `lib/userGuideCopy.ts` et `docs/USER_GUIDE.md` (FR/EN) — **coffres production / QA** (activation, bascule Prod/QA, amor\xe7age QA, red\xe9marrage, rep\xe8re visuel) ; **journal des actions** (`/logs`) ; **cr\xe9neau planifi\xe9** (activation au d\xe9but, fin automatique) ; liste d\xe9roulante `#` / `@` / `!` ; **Rapports** (dur\xe9e compl\xe8te par # en sessions/jour, temps planifi\xe9 \xe0 part, **Total jour** sur calendriers hebdo, s\xe9lecteur **Travail / Personnel** sur la grille @) ; en-t\xeate **`1.0.0-beta.26`**.","**Impl\xe9mentation** : `lib/implementationNotes.ts` (FR + EN, `lastUpdated`) ; `docs/IMPLEMENTATION_DETAILS.md` — `lib/dataDir.ts` / `lib/dataEnvironmentPreferenceFile.ts`, `switchDataEnvironment`, `server/userActionLog.ts`, `activateDuePlannedTaskTimersInSession` / `deferFutureStartMainTimersInSession`, `lib/taskEntryTokenSuggest.ts`, agr\xe9gats reporting (scopes `work` / `personal`).","**D\xe9p\xf4t** : `README.md` (r\xe9f\xe9rence de version npm).","**Aide Rapports** : `lib/reportingStrings.ts` (textes **Rythme**, calendriers, totaux journaliers).","Bump applicatif : **`1.0.0-beta.26`** (`package.json`, `package-lock.json`) ; **CHANGELOG** usager r\xe9g\xe9n\xe9r\xe9 (`npm run changelog:build`)."]},{version:"1.0.0-beta.25",items:["**Cause** : en production, **`node server.js`** s’ex\xe9cute avec **`cwd` = `.next/standalone`** ; le tarball npm ne publie pas le **`package.json`** racine de l’app, et le **`package.json`** minimal g\xe9n\xe9r\xe9 par Next dans le standalone ne porte pas la version **`@nightkatana/kronosys-app`** — l’UI et **`/api/health`** pouvaient donc afficher une version **d\xe9cal\xe9e** (ex. livraison **beta.24** lue comme **beta.23**).","**Correctif** : apr\xe8s **`next build`**, **`scripts/sync-standalone-assets.mjs`** \xe9crit **`kronosys-package-meta.json`** dans le standalone avec la **`version`** du **`package.json`** source ; **`readKronosysPackageVersion()`** lit ce fichier (ou **`KRONOSYS_APP_VERSION`**, pos\xe9e par **`bin/kronosys.mjs`** au lancement du serveur standalone).","**`app/layout.tsx`** : le layout reste **`force-dynamic`** pour \xe9viter une version RSC fig\xe9e au build lorsque la lecture fichier est pertinente.","Bump applicatif : **`1.0.0-beta.25`** (`package.json`, `package-lock.json`) ; **CHANGELOG** usager r\xe9g\xe9n\xe9r\xe9 (`npm run changelog:build`)."]},{version:"1.0.0-beta.24",items:['**`output: "standalone"`** (`next.config.ts`) + **`scripts/sync-standalone-assets.mjs`** apr\xe8s **`npm run build`** : **`kronosys start`** et **`npm run start`** ex\xe9cutent **`node server.js`** dans **`.next/standalone`** (plus **`next start`** sur ce livrable).','**`package.json` → `"files"`** : le tarball publi\xe9 se limite \xe0 **`bin/`**, **`.next/BUILD_ID`** et **`.next/standalone`** (sans sources `app/` / `server/`), pour une archive nettement plus l\xe9g\xe8re qu’un paquet monolithique.',"**Portabilit\xe9** : exclusion du tra\xe7age **`sharp` / `@img/sharp*`** (**`outputFileTracingExcludes`**) + **`images.unoptimized`**, afin d’\xe9viter des binaires **Linux-only** dans un paquet vis\xe9 **Windows / macOS**.","**Docker** : image d’ex\xe9cution all\xe9g\xe9e (**`node server.js`** depuis le standalone copi\xe9).","**`kronosys dev`** : refus explicite depuis un install tarball slim sans dossier **`app/`** (flux dev = checkout source).","Bump applicatif : **`1.0.0-beta.24`** (`package.json`, `package-lock.json`) ; **CHANGELOG** usager r\xe9g\xe9n\xe9r\xe9 (`npm run changelog:build`)."]},{version:"1.0.0-beta.23",items:["**SQLite** : **`better-sqlite3` retir\xe9** au profit de **`node:sqlite`** (`DatabaseSync`) ; **`engines.node`** **≥ 22.13.0** ; r\xe8gle **`.cursor/rules/platform-native-deps.mdc`**.","**Publication / CLI** : cadre **Linux, Windows, macOS** et strat\xe9gie **`kronosys`** — r\xe8gle **`.cursor/rules/kronosys-npm-packaging.mdc`** (it\xe9rations ult\xe9rieures du contenu du tarball : voir **1.0.0-beta.25**).","Bump applicatif : **`1.0.0-beta.23`** (`package.json`, `package-lock.json`) ; **CHANGELOG** usager r\xe9g\xe9n\xe9r\xe9 (`npm run changelog:build`)."]},{version:"1.0.0-beta.22",items:["**Plus de barre de d\xe9filement horizontale** sur la barre d’outils d’en-t\xeate (`lib/appShellHeaderClasses.ts`) : les segments **horloge / KronoFocus / palette de commandes / navigation de routes / utilitaires (th\xe8me, actualiser, langue)** passent d\xe9sormais **\xe0 la ligne** (`flex-wrap`) lorsqu’ils ne tiennent plus, en gardant chaque rang\xe9e **centr\xe9e**, au lieu de produire un ascenseur horizontal sur le conteneur. Le comportement est identique sur **toutes** les routes principales (tableau de bord, rapports, param\xe8tres, journaux, guide, impl\xe9mentation, changelog, licences).","**Bandeau \xab Donn\xe9es actualis\xe9es \xbb du bouton actualiser** (`components/dashboard/PageRefreshButton.tsx`) : rendu via **portail** vers `document.body` avec **`position: fixed`** au lieu d’un positionnement absolu sous le bouton. Corrige l’apparition intermittente d’une **barre de d\xe9filement verticale** sur la page \xe0 chaque clic — l’\xe9l\xe9ment absolu participait au d\xe9bordement du `<body>` et faisait osciller le `scrollHeight` pendant les ~2,8 s d’affichage du libell\xe9.",'**Popover d’\xe9dition de dur\xe9e KronoFocus** (`components/dashboard/KronoFocusPanel.tsx`) : ouvrir le temps depuis l’en-t\xeate (`variant="headerBar"`) ne d\xe9clenche plus l’apparition de **scrollbars sur les deux axes** dans l’alv\xe9ole du ruban. La cause \xe9tait la combinaison `overflow-x-auto` sur l’alv\xe9ole + popover en `position: absolute` : selon la spec CSS, d\xe8s qu’un axe d’overflow n’est pas `visible`, l’autre est promu en `auto`, donc deux ascenseurs apparaissaient sit\xf4t que le panneau d\xe9passait. Le popover est d\xe9sormais rendu en **portail** avec `position: fixed` centr\xe9 sous le bouton du temps. D\xe9tection click-outside r\xe9vis\xe9e pour v\xe9rifier le **d\xe9clencheur** et le **panneau** par leurs `ref` distinctes (ils ne partagent plus de sous-arbre DOM).',"**Surcouche carte \xab compl\xe8te \xbb** (variante `default` de `KronoFocusPanel`) align\xe9e sur le m\xeame pattern portail pour rester coh\xe9rente.",'**`useAnchoredFloatingPortalStyle`** (`components/dashboard/useAnchoredFloatingPortalStyle.ts`) gagne l’alignement **`"center"`** en plus de `start` / `end` : le panneau portail peut maintenant \xeatre centr\xe9 horizontalement sous son d\xe9clencheur. Les autres consommateurs (`PageRefreshButton`, `PlainHelpPopover`, `TagsHelpTrigger`, `InlineMetricHelpTrigger`) conservent leurs alignements existants ; le hook continue de g\xe9rer la contrainte au viewport (marge 10 px) et le **basculement au-dessus** du d\xe9clencheur s’il manque de place en bas.',"**Guide utilisateur** : `lib/userGuideCopy.ts` et `docs/USER_GUIDE.md` (FR/EN) — note explicite sur le repli en plusieurs rang\xe9es de la barre d’outils sur \xe9cran \xe9troit ; en-t\xeate de version pointe **`1.0.0-beta.22`**.","**Impl\xe9mentation** : `lib/implementationNotes.ts` (FR + EN, `lastUpdated`) ; `docs/IMPLEMENTATION_DETAILS.md` — date d’en-t\xeate et note sur le pattern \xab portail + `position: fixed` \xbb pour les surcouches ancr\xe9es \xe0 des \xe9l\xe9ments d’en-t\xeate (\xe9vite la propagation au `scrollableOverflow` du `<body>`).","**D\xe9p\xf4t** : `README.md` (r\xe9f\xe9rence de version npm).","Bump applicatif : **`1.0.0-beta.22`** (`package.json`, `package-lock.json`) ; **CHANGELOG** usager r\xe9g\xe9n\xe9r\xe9 (`npm run changelog:build`)."]},{version:"1.0.0-beta.21",items:["**Parsing** : `findProjectTokens` (`lib/taskParsing.ts`) reconna\xeet d\xe9sormais **`!projet`** et **`!projet#sous-\xe9tiquette`** lorsque le **`!`** suit **directement** un caract\xe8re autoris\xe9 (sans espace avant le sigil), sur le m\xeame principe que les **`#\xe9tiquettes`** \xab coll\xe9es \xbb au mot pr\xe9c\xe9dent. Les jetons **`@`** restent limit\xe9s \xe0 une **fronti\xe8re d\xe9but de cha\xeene ou espace** afin d’\xe9viter les faux positifs (ex. adresses courriel du type `contact@domaine`).","**Effet** : la modification d’un libell\xe9 du type `Courrier!perso#dentiste` met correctement \xe0 jour **`project`**, **`personalProject`** et les **\xe9tiquettes** persist\xe9es (y compris via **`updateTask`**), ce qui aligne le **reporting** (\xe9tiquettes, ventilation par projet selon le scope) sur l’intention utilisateur.","**Guide utilisateur** : `lib/userGuideCopy.ts` et `docs/USER_GUIDE.md` (FR/EN) — pr\xe9cision sur l’espace optionnel avant **`!`** ; en-t\xeate et exemples de livraison pointent **`1.0.0-beta.21`**.","**Impl\xe9mentation** : `docs/IMPLEMENTATION_DETAILS.md` (r\xe8gle de fronti\xe8re `!` / `@`) ; `lib/implementationNotes.ts` (version affich\xe9e et d\xe9tail parsing scoped `!`).","**D\xe9p\xf4t** : `README.md` (r\xe9f\xe9rence de version npm).","**Tests** : `lib/taskParsing.test.ts` — cas `Courrier!perso#dentiste` ; attentes **`personalProject`** pour `parseQuickAddTagOrProjectLine` / `buildStartTaskFromInput` lorsqu’un projet est pr\xe9sent.","Bump applicatif : **`1.0.0-beta.21`** (`package.json`, `package-lock.json`) ; **CHANGELOG** usager r\xe9g\xe9n\xe9r\xe9 (`npm run changelog:build`)."]},{version:"1.0.0-beta.20",items:["**D\xe9pendances runtime** : `@types/node`, `@types/react` et `@types/react-dom` pass\xe9es en **`dependencies`** avec `typescript` — Next.js 16 exige ces paquets pour la phase \xab Running TypeScript \xbb du `next build` ; une installation **`npm install --omit=dev`** ne les omet plus (\xe9vite le message *It looks like you're trying to use TypeScript…* hors environnement de d\xe9veloppement complet).","**Contenu du tarball publi\xe9** : suppression du champ **`files`** dans `package.json` (il neutralisait **`.npmignore`**, comportement **npm-packlist**) ; filtrage du paquet via **`.npmignore`** (fichiers `*.test.*` / `*.spec.*`, dossiers `e2e/`, `test/`, `docs/`, outils CI, etc.) en conservant les sources n\xe9cessaires au build.","Bump applicatif : **`1.0.0-beta.20`** (`package.json`, `package-lock.json`) ; **CHANGELOG** usager r\xe9g\xe9n\xe9r\xe9 (`npm run changelog:build`)."]},{version:"1.0.0-beta.19",items:["**Affichage planifi\xe9** : regroupement sous **Planifi\xe9es**, styles distincts (section, fond, point d’\xe9tat) ; **suppression des pastilles texte** \xab planifi\xe9 \xbb sur les cartes t\xe2che et les lignes de session. T\xe2che **non termin\xe9e** dont le **d\xe9but** (`startTime`) est encore **futur** : pas de minuteur \xab en direct \xbb. T\xe2che **termin\xe9e** : regroupement planifi\xe9 seulement si **d\xe9but et fin** parseables sont **tous deux** strictement futurs — une **fin** future seule ne retient plus la carte sous Planifi\xe9es lorsque le d\xe9but est d\xe9j\xe0 pass\xe9 (`isTaskDisplayPlanned`). Session live \xe0 **startAt** futur : ligne distincte dans la liste ; d\xe9compte planifi\xe9es sur la carte session ; tiroir AppShell sans ces entr\xe9es comme suivi actif.","**Fronti\xe8re planifi\xe9 → en cours** : lorsqu’une t\xe2che rejoint les minuteurs **en cours** alors qu’**au moins un** autre minuteur \xe9tait d\xe9j\xe0 visible comme en cours, une **modale** (pause / terminer / parall\xe8le, m\xeame m\xe9morisation que le d\xe9marrage manuel) s’applique aux t\xe2ches d\xe9j\xe0 au minuteur ; hors route `/`, l’ic\xf4ne **Tableau de bord** peut **pulser**.","**Modales globales** : correction d’un d\xe9calage de positionnement lors des transitions de route ; l’animation de conteneur ne transporte plus de `transform`, ce qui r\xe9tablit l’ancrage viewport des modales en `position: fixed`.","**Horloge murale** permanente dans la barre d’outils : fuseau IANA et format 12/24 h des param\xe8tres **Tableau de bord web**, tick chaque seconde ; correctif d’**hydratation** SSR/CSR sur les secondes au premier rendu.","**S\xe9lecteurs date/heure** : bouton **crochet** pour valider et fermer le calendrier ; pr\xe9remplissage **d\xe9but** avec minutes `:00` (bouton **Today** idem) ; **Now** \xe0 l’instant exact ; champs de **fin** arrondis \xe0 la **demi-heure** suivante (**Today** inclus).","**Heure de fin planifi\xe9e** (t\xe2che ou session) : clignotement doux entre 15 et 5 minutes restantes, puis plus rapide jusqu’\xe0 0.","**Colonne t\xe2ches** : suppression d’une troncature visuelle pendant l’animation d’ouverture ; d\xe9filement correct sur les listes longues.","**Installation desktop / PWA** : priorit\xe9 **512x512** + r\xf4le `maskable` pour l’ic\xf4ne install\xe9e.","**Jeton `!`** : en parall\xe8le de `@projet`, le libell\xe9 de t\xe2che accepte **`!projet`** et les \xe9tiquettes sous port\xe9e **`!projet#sous-\xe9tiquette`** ; le moteur distingue **`personalProject`** sur les t\xe2ches et maintient **`knownPersonalProjects`** sur le payload (liste distincte de `knownProjects`).","**Actions** : `startTask`, `addHistoricalTask`, `updateTask`, `saveTaskTemplate` ; renommage serveur avec **`renameProjectMetadata`** et **`personalOnly`** (pas encore d’inline Param\xe8tres d\xe9di\xe9 aux listes `!`).","**UI** : pastilles et suggestions **rose** pour le personnel (`taskFieldStyles`, `TaskFocusPanel`, `TaskSessionLiveCard`, `SavedProjectPicker`, `TagPills`) ; **Gantt** d’une t\xe2che : barres et **totaux s\xe9par\xe9s** temps productif (`@`) vs personnel (`!`).","**Rapports** : les grilles \xab par projet \xbb utilisent par d\xe9faut le scope **`work`** (`aggregateProjectTaskMinutesByDay`) — le temps `!` n’y est pas m\xe9lang\xe9 ; les scopes **`personal`** / **`all`** existent dans `lib/reportingAggregate.ts` pour une future vue UI d\xe9di\xe9e.","**Qualit\xe9** : tests unitaires sur les mod\xe8les avec projet personnel (`lib/taskTemplateDraft.test.ts`) ; pas de parcours E2E Playwright d\xe9di\xe9 aux jetons `!` dans cette version.","**Guide utilisateur** : `lib/userGuideCopy.ts` et `docs/USER_GUIDE.md` (FR/EN) — convention **`#` / `@` / `!`**, rapports (grilles projet `@` sans m\xe9langer `!`), limite actuelle c\xf4t\xe9 Param\xe8tres pour les projets personnels.","**Impl\xe9mentation** : `lib/implementationNotes.ts` (user stories et coches int\xe9gration/E2E) ; **`docs/IMPLEMENTATION_DETAILS.md`** — section projets personnels et scopes reporting.","**Changelog usager** : r\xe9g\xe9n\xe9ration via `npm run changelog:build` (`lib/generatedUserChangelog.ts`).","**Paquet npm** : version **`1.0.0-beta.19`** ; script **`prepublishOnly`** = `npm run build` avant `npm publish` sur `@nightkatana/kronosys-app`."]},{version:"1.0.0-beta.18",items:["Nouveaut\xe9s — Sauvegarde/restauration: ajout de l’API `POST /api/restore` (import `json` ou `sqlite`) avec couverture d’int\xe9gration d\xe9di\xe9e.","Nouveaut\xe9s — User stories in-app: ajout de la page **Impl\xe9mentation** (`/implementation`) avec inventaire exhaustif ✓/✗, checklist locale \xab revue \xbb et acc\xe8s direct au changelog usager.","Nouveaut\xe9s — Mod\xe8les de t\xe2che: section d\xe9di\xe9e dans Param\xe8tres, cr\xe9ation depuis une t\xe2che, suggestions \xab Mod\xe8le : \xbb dans la saisie, disponibilit\xe9 dans la palette **Spotlight**.","Nouveaut\xe9s — Vue **Gantt du jour**: modal timeline globale des intervalles de t\xe2ches sur les sessions de la journ\xe9e.","Nouveaut\xe9s — Pause globale contextuelle: modal de confirmation enrichie avec r\xe9sum\xe9 d\xe9taill\xe9 (murale, temps actifs/codage, compteurs t\xe2ches/sous-t\xe2ches, ventilation minuteurs).","Nouveaut\xe9s — Nom de session par d\xe9faut: gabarit configurable (`%UUID` + tokens `strftime`) appliqu\xe9 \xe0 la cr\xe9ation de session.","Am\xe9liorations — Tableau de bord: en-t\xeate AppShell consolid\xe9 (m\xe9tadonn\xe9es de session, placeholder commande, navigation), transitions de route et coh\xe9rence inter-pages accrues.","Am\xe9liorations — Reporting: ajout du temps non concurrent par jour, ventilation des sessions par type de cl\xf4ture, aides m\xe9triques et pr\xe9cision accrue des agr\xe9gats.","Am\xe9liorations — Sessions/t\xe2ches: consolidation des statistiques lat\xe9rales, gestion des notes et meilleure continuit\xe9 live/historique.","Am\xe9liorations — Param\xe8tres: \xe9volution des sections \xc9tiquettes/Projets/Mod\xe8les et meilleure ergonomie des flux de configuration.","Qualit\xe9 — Tests: renforcement substantiel de la couverture (unitaires + int\xe9gration + E2E) sur restore API, templates, Gantt, pause globale, agr\xe9gats reporting et flux session/t\xe2che.","Documentation — Guide utilisateur synchronis\xe9 pour `beta.18` sur les deux surfaces (`/guide` et `docs/USER_GUIDE.md`), Spotlight harmonis\xe9, page `/implementation` et `docs/IMPLEMENTATION_DETAILS.md` align\xe9s.","Maintenance — Bump applicatif vers `1.0.0-beta.18` (`package.json`, `package-lock.json`) et r\xe9g\xe9n\xe9ration du changelog usager (`lib/generatedUserChangelog.ts`)."]},{version:"1.0.0-beta.17",items:["Nouveaut\xe9s — Notes libres: ajout d’une **note de t\xe2che** et d’une **note de session** (texte libre) pour documenter le contexte de travail directement sur l’activit\xe9 concern\xe9e.","Am\xe9liorations — Tableau de bord: la note de t\xe2che est affich\xe9e **avant** la liste des sous-t\xe2ches pour garder le contexte visible pendant la d\xe9composition.","Am\xe9liorations — Sessions et archives: aper\xe7u de note de session (ic\xf4ne + extrait) dans la liste des sessions et dans la liste des sessions archiv\xe9es.","Qualit\xe9 — Tests: ajout de tests unitaires UI pour l’ordre d’affichage note/sous-t\xe2ches et la pr\xe9sence de l’aper\xe7u de note en liste de sessions, en plus des tests serveur sur la persistance des notes.","Documentation — Mise \xe0 jour du guide utilisateur (in-app + d\xe9p\xf4t) et des d\xe9tails d’impl\xe9mentation pour les notes de t\xe2ches/sessions.","Nouveaut\xe9s — Planification d’heure de fin sur les **t\xe2ches en cours** : d\xe9finir une heure de fin programme l’\xe9ch\xe9ance et met automatiquement le minuteur en pause lorsqu’elle est atteinte.","Nouveaut\xe9s — Planification d’heure de fin sur la **session live** : d\xe9finir une heure de fin agit comme \xe9ch\xe9ance de session et met automatiquement en pause la dur\xe9e murale \xe0 l’instant pr\xe9vu.","Am\xe9liorations — Tableau de bord : le s\xe9lecteur **Fin** est disponible aussi sur t\xe2ches/sessions en cours (plus seulement sur les \xe9l\xe9ments d\xe9j\xe0 termin\xe9s), avec affichage de l’\xe9ch\xe9ance planifi\xe9e.","Qualit\xe9 — Tests : renforcement de la couverture (dispatch + hydratation minuteurs/session) pour les sc\xe9narios planifi\xe9s et les cas d’\xe9ch\xe9ance d\xe9pass\xe9e.","Documentation — Guide utilisateur et d\xe9tails d’impl\xe9mentation mis \xe0 jour pour expliciter la diff\xe9rence \xab fin r\xe9elle \xbb vs \xab fin planifi\xe9e (auto-pause) \xbb.","Nouveaut\xe9s — \xc9tiquettes et projets : renommage **inline** dans la colonne droite du tableau de bord (\xe9dition en place, validation **Entr\xe9e**, annulation **\xc9chap**).","Am\xe9liorations — Confirmation de renommage : avertissement explicite sur l’impact reporting + option \xab ne plus afficher \xbb m\xe9moris\xe9e localement.","Qualit\xe9 — UX : suppression des ambigu\xeft\xe9s d’actions (pas de bouton de sauvegarde en double pendant le renommage inline)."]},{version:"1.0.0-beta.16",items:["Nouveaut\xe9s — Page Impl\xe9mentation (`/implementation`) avec inventaire exhaustif des user stories (✓ livr\xe9 \xb7 ✗ absent/hors p\xe9rim\xe8tre), checklist locale \xab revue \xbb et acc\xe8s direct au changelog usager.","Nouveaut\xe9s — Documentation technique d’impl\xe9mentation ajout\xe9e dans `docs/IMPLEMENTATION_DETAILS.md` (mod\xe8le temps session murale vs minuteurs de t\xe2ches, pauses, reporting, architecture et maintenance).","Nouveaut\xe9s — Mod\xe8les de t\xe2che: sauvegarde depuis une t\xe2che, suggestions \xab Mod\xe8le: \xbb dans la saisie, pr\xe9sence dans la palette `Ctrl+K`, gestion d\xe9di\xe9e dans Param\xe8tres.","Nouveaut\xe9s — Pause globale contextuelle avec modale de confirmation et aper\xe7u d\xe9taill\xe9 (murale, temps actif/codage, compteurs t\xe2ches/sous-t\xe2ches, ventilation des minuteurs).","Nouveaut\xe9s — Vue Gantt du jour: frise des intervalles de t\xe2ches sur l’ensemble des sessions de la journ\xe9e.","Nouveaut\xe9s — Nom de session par d\xe9faut avec gabarit configurable (`%UUID` + tokens `strftime`) dans les param\xe8tres.","Nouveaut\xe9s — Restauration locale via `POST /api/restore` (`json` ou `sqlite`) en compl\xe9ment de `GET /api/backup`.","Am\xe9liorations — Reporting: ajout du temps non concurrent par jour, ventilation des sessions par type de cl\xf4ture, m\xe9triques d’assiduit\xe9 quand une heure pr\xe9vue est fournie.","Am\xe9liorations — Spotlight: la palette de recherche rapide est d\xe9sormais explicitement nomm\xe9e \xab Spotlight \xbb dans l’interface.","Qualit\xe9 — Tests: ajout/renforcement des parcours E2E et tests unitaires (impl\xe9mentation, templates, pause globale, restauration API, agr\xe9gats).","Documentation — Guide utilisateur: mise \xe0 jour compl\xe8te in-app + d\xe9p\xf4t, et alignement des cha\xeenes FR/EN (dashboard, reporting, param\xe8tres, licences, impl\xe9mentation)."]},{version:"1.0.0-beta.15",items:["Ajout de la commande de version CLI: `kronosys --version` affiche d\xe9sormais la version install\xe9e.","Ajout des alias `kronosys -v` et `kronosys version` pour afficher la version install\xe9e."]},{version:"1.0.0-beta.14",items:["Ajout de la page **Impl\xe9mentation** (`/implementation`) avec inventaire exhaustif des user stories livr\xe9es ou hors p\xe9rim\xe8tre.","Ajout des **mod\xe8les de t\xe2che** (cr\xe9ation depuis une t\xe2che, gestion dans Param\xe8tres, recherche rapide Ctrl+K).","Ajout d’une **pause globale contextuelle** avec modale de confirmation et aper\xe7u des dur\xe9es associ\xe9es.","Ajout de la vue **Gantt du jour** pour visualiser les intervalles de t\xe2ches de la session affich\xe9e."]},{version:"1.0.0-beta.13",items:["Version interm\xe9diaire de stabilisation (pas de nouveaut\xe9 utilisateur majeure document\xe9e)."]},{version:"1.0.0-beta.12",items:["Correctif du runtime CLI: installation des d\xe9pendances avec `--ignore-scripts` pour \xe9viter les erreurs Husky hors d\xe9p\xf4t."]},{version:"1.0.0-beta.11",items:["Correctif Windows du lanceur CLI (PowerShell + installation runtime locale).","Rebuild explicite de `better-sqlite3` dans le runtime local."]},{version:"1.0.0-beta.10",items:["Correctif de dispatch des commandes Windows pour le runtime CLI."]},{version:"1.0.0-beta.9",items:["Correctif de quoting des commandes Windows dans le lanceur CLI."]},{version:"1.0.0-beta.8",items:["Correctif initial Windows du launcher (`npm.cmd`/`npx.cmd`)."]},{version:"1.0.0-beta.7",items:["Stabilisation du packaging b\xeata et g\xe9n\xe9ration des archives de distribution."]},{version:"1.0.0-beta.6",items:["Correctif de r\xe9solution d’alias d’import (`@/...`) pour le build de production."]},{version:"1.0.0-beta.5",items:["Retour temporaire au mode build \xe0 la premi\xe8re ex\xe9cution pour am\xe9liorer la compatibilit\xe9 multiplateforme."]},{version:"1.0.0-beta.4",items:["Ajustements de packaging et de lancement CLI pour la s\xe9rie b\xeata."]},{version:"1.0.0-beta.2",items:["Correctif des d\xe9pendances de build n\xe9cessaires au runtime CLI."]},{version:"1.0.0-beta.1",items:["`kronosys` lance maintenant le build de production automatiquement si `.next` est absent."]},{version:"1.0.0-beta.0",items:["Premi\xe8re version b\xeata publi\xe9e."]},{version:"0.1.1",items:["Added an in-app user CHANGELOG page (`/changelog`).","Added an update modal on Dashboard startup that opens the CHANGELOG after a version change.","Added browser-local tracking of the last seen app version to show update notes once per version."]}],e={title:"User CHANGELOG",subtitle:"This page lists user-visible changes after each software update.",empty:"No changelog entry is available yet.",entries:d},f={title:"CHANGELOG usager",subtitle:"Cette page liste les changements visibles c\xf4t\xe9 utilisateur apr\xe8s chaque mise \xe0 jour du logiciel.",empty:"Aucune entr\xe9e de changelog n’est encore disponible.",entries:d};function g(a){return"fr"===a?f:e}},92776:(a,b,c)=>{"use strict";c.d(b,{J:()=>f});let d={title:"Settings",subtitle:"Kronosys options stored locally on this machine.",loading:"Loading settings…",reload:"Reload from server",save:"Save",saving:"Saving…",savedOk:"Settings saved.",settingsUnsavedStickyHint:"You have unsaved changes.",resetToDefaults:"Reset to defaults",resetToDefaultsConfirm:"Restore every Kronosys option to its factory default? Stored GitLab tokens and MongoDB connection flags are not removed from secure storage; only the settings shown on this page are reset.",resettingDefaults:"Resetting…",resetDefaultsDone:"Defaults applied.",openIdeSettings:"These fields map to persisted configuration keys in the local store.",tocHeading:"On this page",tocNavAriaLabel:"Jump to a settings section",tocSearchPlaceholder:"Filter table of contents…",tocSearchAriaLabel:"Filter settings sections in the table of contents",tocSearchNoResults:"No section title matches.",sectionUsageProfile:"Usage profile",usageProfile:"Profile",usageProfileDesc:"Developer: lines written, per-language stats, coding-signal counts, workspace LOC snapshot, and Git repo card. Manager: tasks, sessions, KronoFocus, and time only — no code-linked metrics or UI.",profileDeveloper:"Developer",profileManager:"Manager",workspaceLocSectionHiddenManager:"These options apply only in Developer profile (workspace code snapshot on Reporting).",sectionGeneral:"General",sectionPrivacy:"Privacy",sectionKronoFocus:"KronoFocus (dashboard)",kronoFocusHeaderPinnedNote:"The KronoFocus timer and controls always stay in the app header toolbar (next to the clock and command palette) so the navigation bar keeps the same width on every page. While you inspect an archive, the controls stay visible but target the live session.",kronoFocusShowInTaskOps:"Show in task action buttons",kronoFocusShowInTaskOpsDesc:"KronoFocus start on active tasks and the optional “start KronoFocus with new task” toggle in the task launcher.",sectionTaskTags:"Tasks & tags",taskDefaultTagBucketEnabled:"Implicit default tag for tasks without #tags",taskDefaultTagBucketEnabledDesc:"When enabled, any task with no hashtag labels after cleanup is stored with the reserved default bucket (shown as “default” in English or “d\xe9faut” in French). When disabled, such tasks keep an empty label list until you add one.",taskStripDefaultTagWhenExplicitTags:"Drop default tag when another #tag is added",taskStripDefaultTagWhenExplicitTagsDesc:"When enabled, as soon as a task carries at least one explicit hashtag label other than the reserved default bucket, the default label is removed automatically. When disabled, default can stay alongside other labels.",taskMinimumDurationMinutes:"Minimum task duration (minutes)",taskMinimumDurationMinutesDesc:"Default span for past or planned task entry: the end time is prefilled as start plus this many minutes (e.g. 30 or 60). Range: 15–480.",dashboardAllowTaskStartTimeEdit:"Allow task start-time correction in the dashboard",dashboardAllowTaskStartTimeEditDesc:"Shows controls to edit a task start time from the Tasks column while it is running or after it is completed.",dashboardAllowSessionStartTimeEdit:"Allow session start-time correction in the dashboard",dashboardAllowSessionStartTimeEditDesc:"Shows controls to edit a session start time from the Sessions column for the live session or a historical session.",dashboardAllowTaskEndTimeEdit:"Allow task end-time correction in the dashboard",dashboardAllowTaskEndTimeEditDesc:"Shows controls to set or edit task end time in the Tasks column, including while a task is running (the task completes automatically when that planned end is reached).",dashboardAllowSessionEndTimeEdit:"Allow session end-time correction in the dashboard",dashboardAllowSessionEndTimeEditDesc:"Shows controls to set or edit a session end time in the Sessions column, including while a live session is open (the session closes automatically when that planned end is reached).",sectionCollection:"Collection & buffers",sectionHistory:"Session history",sectionDangerZone:"Danger zone",dangerClearHistoryTitle:"Clear all local dashboard data",dangerClearHistoryBodyIntro:"Permanently removes, in this dashboard’s local store:",dangerClearHistoryBodyBullets:["Every session (live view, history list, and archived list) and the session you were inspecting","All tag & project shortcuts: pinned tags, tags hidden from chips, tag/project descriptions, known tag & project suggestion lists","Git identity saved here (display name, email, forge login) and the Git statistics card data","The cached workspace lines-of-code snapshot used on Reporting (Developer profile)","The “skip archive confirm” preference for this dashboard","The browser’s saved dashboard language and explicit language choice (you will pick English or Fran\xe7ais again before the guided tour)"],dangerClearHistoryBodyAfterList1:"Afterwards, the welcome guided tour will be offered again on the dashboard, and the “show welcome on startup” option is turned back on in settings.",dangerClearHistoryBodyAfterList2:"This cannot be undone.",dangerClearHistoryButton:"Clear all local data…",dangerClearHistoryConfirm:"You are about to erase everything listed in the danger-zone description above (sessions, tags/projects metadata, Git identity in this store, etc.). Continue?",dangerClearHistoryVaultTargetTitle:"Vault targeted by this erase",dangerClearHistoryVaultTargetTrace:"Erase applies to the directory forced by TRACE_DATA_DIR: {path}. No other Kronosys vault is involved.",dangerClearHistoryVaultTargetDual:"Erase applies only to the {env} vault currently loaded by this server ({path}). The {otherEnv} vault ({otherPath}) is not modified.",dangerClearHistoryVaultTargetSingle:"Erase applies to the data directory currently loaded by this server ({path}).",dangerClearHistoryVaultTargetDev:"Erase applies to the development data directory currently loaded by this server ({path}), not the packaged production vault unless you explicitly share it.",dangerClearHistoryVaultMismatch:"Note: your saved preference points to {preferredEnv} ({preferredPath}) after restart, but this process is still using {activePath}. The erase will affect the directory in use now.",dangerClearHistoryConfirmPhrase:"DELETE",dangerClearHistoryTypeInstruction:"To enable “Confirm”, type {phrase} exactly below (all capitals, no spaces).",dangerClearHistoryTypeFieldLabel:"Confirmation word",dangerClearHistoryTypeInputAria:"Type the confirmation word to allow the full erase described above (sessions, metadata, Git identity, etc.)",dangerClearHistoryBackupIntro:"Before you confirm, you can download a local backup (same data the dashboard uses on this machine):",dangerClearHistoryBackupJson:"JSON — full state snapshot",dangerClearHistoryBackupJsonHint:"Entire persisted Kronosys payload in one file (sessions including live `current`, tasks, tag/project metadata, Git identity, `cfg`, Git stats snapshot, workspace LOC snapshot, etc.).",dangerClearHistoryBackupCsvBlockTitle:"CSV — multiple tables (one download per link)",dangerClearHistoryBackupCsvBlockHint:"Together these tables mirror what the danger-zone erase removes: sessions (with a full JSON column per row), every task and subtask, tag/project lists and descriptions, Git identity, plus configuration and JSON blobs (`cfg`, Git stats, workspace code snapshot, inspecting session id, etc.).",dangerClearHistoryBackupCsvZip:"CSV — all tables (ZIP)",dangerClearHistoryBackupCsvZipHint:"One download containing the eight UTF-8 CSV files.",dangerClearHistoryBackupCsvSeparateTitle:"Individual files (optional)",dangerClearHistoryBackupCsvSessions:"Sessions — extended metrics + full session JSON",dangerClearHistoryBackupCsvTasks:"Tasks — one row per task + full task JSON",dangerClearHistoryBackupCsvSubtasks:"Subtasks — one row per checklist item + JSON",dangerClearHistoryBackupCsvRegistry:"Tag & project registry — known / pinned / hidden lists",dangerClearHistoryBackupCsvTagDesc:"Tag descriptions",dangerClearHistoryBackupCsvProjectDesc:"Project descriptions",dangerClearHistoryBackupCsvGitId:"Git identity (saved in this store)",dangerClearHistoryBackupCsvStoreBlobs:"Config & snapshots — `cfg`, Git stats, workspace LOC, UI prefs",dangerClearHistoryBackupSqlite:"SQLite — database file",dangerClearHistoryBackupSqliteHint:"Raw kronosys.sqlite after a WAL checkpoint (restore by replacing the file when the app is stopped).",dangerBackupRestoreTitle:"Backups and full restore",dangerBackupRestoreIntro:"Download a full backup first, then restore from a previous backup file when needed (JSON snapshot or SQLite file).",dangerRestorePickFile:"Restore file (`.json` or `.sqlite`)",dangerRestoreHint:"Restoring replaces the current local store on this machine. Create a backup right before restoring if you are unsure.",dangerRestoreButton:"Restore from backup…",dangerRestoreBusy:"Restoring…",dangerRestoreConfirm:"Restore this backup file now? The current local data store will be replaced for this environment.",dangerRestoreNoFile:"Choose a backup file before starting restore.",dangerRestoreDoneJson:"Restore completed from JSON snapshot. The dashboard data has been reloaded.",dangerRestoreDoneSqlite:"Restore completed from SQLite file. The dashboard data has been reloaded.",dangerRestoreFailed:"Restore failed: {detail}",sectionArchivedSessions:"Archived sessions",archivedSessionsIntro:"Sessions hidden from the main dashboard list, newest first. Restore adds them back to the Sessions column.",archivesPaginationPrev:"Previous page",archivesPaginationNext:"Next page",archivesPaginationNavAria:"Archived sessions pagination",archivesPaginationRange:"{from}–{to} of {total}",sectionExport:"Export defaults",sectionGit:"Git sync",sectionMongo:"MongoDB mirror",sectionWeb:"Dashboard & API",devDataBlockTitle:"Development mode (local data store)",devDataIntro:"While you run the Next.js dev server (`next dev`), SQLite and local state use a separate folder (`…/v4-dev` by default) from the production build (`next start`, `…/v4`) so you do not overwrite your real data. Save with the main **Save** button at the bottom of this page, like any other setting.",devDataUseProdLabel:"Use the same data directory as production (v4)",devDataUseProdDesc:"When off (default), dev uses an isolated `v4-dev` directory. When on, dev reads and writes the same `v4` path as a packaged or `next start` run. After changing this, restart the dev server so it opens the right database file.",devDataActivePath:"Data directory in use (this process)",devDataPreferredPath:"Would apply after restart",devDataProdPath:"Default production directory (v4)",devDataPrefsFile:"Preference file on disk",devDataTraceOverride:"The server was started with TRACE_DATA_DIR; that path is used and this toggle is disabled.",devDataEnvOverride:"The environment variable KRONOSYS_DEV_USE_PROD_DATA is set; the dev server uses the production v4 path and this toggle is disabled.",devDataRestartHint:"Your saved preference no longer matches the open database. Restart the Next.js dev server to apply it.",devDataHiddenNotDev:"This block is only shown when the dashboard is served in development mode (`next dev`).",dataEnvBlockTitle:"Production and QA data stores",dataEnvIntro:"Keep your real sessions in the production folder (`…/v4`) and use a separate QA folder (`…/v4-qa`) to try features or reproduce issues without touching production data. Enable both stores below, then switch with **Prod / QA** in the navigation bar (immediate) or change the active environment here and **Save**.",dataEnvDualLabel:"Enable separate production and QA data stores",dataEnvDualDesc:"When on, SQLite and local state use either `v4` (production) or `v4-qa` (QA) depending on the active environment. When off, only the production store is used.",dataEnvActiveLabel:"Active environment",dataEnvActiveDesc:"Folder opened by this server process. You can also switch from the navigation bar without opening Settings.",dataEnvActiveProduction:"Production (v4)",dataEnvActiveQa:"QA (v4-qa)",dataEnvActivePath:"Data directory in use (this process)",dataEnvPreferredPath:"Saved preference (should match when in sync)",dataEnvProdPath:"Production directory (v4)",dataEnvQaPath:"QA directory (v4-qa)",dataEnvPrefsFile:"Preference file on disk",dataEnvTraceOverride:"The server was started with TRACE_DATA_DIR; that path is used and these options are disabled.",dataEnvRestartHint:"Your saved environment no longer matches the open database. Restart the Kronosys server to apply it.",sectionWorkspaceLoc:"Reporting — workspace code snapshot",sectionTagsProjects:"Tags & saved projects",sectionTaskTemplates:"Task templates",taskTemplatesIntro:"Saved lines for the “what are you working on” field (title, optional #tags and @project). You can still save a template from an active or completed task on the dashboard.",taskTemplatesHelpAria:"Help: task templates",taskTemplatesHelpBody:"Templates only prefill the task draft — they do not start a timer or change recorded tasks.\n\nUse the same syntax as on the dashboard: a title, optional #tags, optional @project. Editing or deleting a template does not modify existing sessions or tasks.",taskTemplatesEmpty:"No task templates yet. Add one above or save one from the dashboard.",taskTemplatesDraftPlaceholder:"e.g. Deep work #focus @acme",taskTemplatesAddBtn:"Add template",taskTemplatesSavedToast:"Task template saved.",taskTemplatesRemovedToast:"Task template removed.",taskTemplatesUpdatedToast:"Task template updated.",taskTemplatesColDraft:"Template",taskTemplatesColUpdated:"Updated",taskTemplatesColActions:"Actions",taskTemplatesEditBtn:"Edit template",taskTemplatesSaveBtn:"Save changes",taskTemplatesCancelBtn:"Cancel",taskTemplatesDeleteBtn:"Delete template",taskTemplatesDeleteConfirm:"Remove this task template from the saved list?",tagsProjectsIntro:"Manage global tags, saved projects, and project-linked tags separately. The same controls appear in the right column on the main dashboard. Actions here do not bulk-edit tasks or session files.",tagsProjectsHelpAria:"Help: impact of tag and project changes",tagsProjectsHelpBody:"This page is split into three areas: global tags (no project), saved projects, then project-linked tags grouped under each project.\n\nHide (eye-off icon): the tag no longer appears in suggestion chips. Tasks are unchanged.\n\nDelete permanently (trash icon): removes the tag from pinned and hidden lists and clears its description. Tasks are unchanged.\n\nPin icons: manage your pinned shortcut list.\n\nProject-scoped tags: use @Project#code in a task title (stored as Project#code). Suggestion chips only show that code when the task’s project matches Project.\n\nDescriptions: optional local notes; tooltips on dashboard chips.\n\nDelete project (trash): removes the project from the saved list, clears its description, and purges metadata for tags stored as Project#… under that project. Tasks are unchanged.",tagsGlobalHeading:"Global tags (no project)",tagsGlobalIntro:"Shortcuts for tags that are not tied to a specific project. They are suggested on every task, regardless of @project.",tagsByProjectHeading:"Project-linked tags",tagsByProjectIntro:"Each block is a project key; tags stored as Project#code appear under that project. Pin, hide, and descriptions are still per tag.",tagsByProjectOrphanIntro:"Project#code scopes that do not match any saved project above. Pin or edit them here, or add the project to the list first.",tagsByProjectOrphanHelpAria:"Help: project-linked tags without a matching saved project",tocSubTagsGlobal:"Global tags",tocSubTagsProjects:"Projects",tocSubTagsByProject:"Tags by project",tagsHiddenHeading:"Hidden from shortcuts",tagsPinFieldLabel:"Pin a global tag",tagsPinPlaceholder:"e.g. bugfix or deep-work",tagsPinScopedFieldLabel:"Pin a project-linked tag",tagsPinScopedPlaceholder:"e.g. 204822-1530 or ClientABC#204822-1530",tagsPinAddBtn:"Pin",tagsTableTagCol:"Tag",tagsTableActionsCol:"Actions",tagBadgePinned:"Pinned",tagPinBtn:"Add tag to pinned shortcuts",tagUnpinBtn:"Remove tag from pinned shortcuts",tagExcludeBtn:"Hide tag from suggestion shortcuts",tagRestoreBtn:"Show tag in shortcuts again",tagPurgeAriaLabel:"Delete tag metadata permanently",tagPurgeConfirm:"Permanently delete this tag’s metadata? Its description will be cleared, it will be unpinned, and it will be hidden from dashboard tag lists (it appears under “Hidden from shortcuts” if tasks still reference it). Tasks are not modified.",tagPurgeHiddenConfirm:"Remove this tag from the hidden list and clear its description? If tasks still use it, it can show again in shortcuts. Tasks are not modified.",tagPurgeHiddenAriaLabel:"Permanently delete this hidden tag’s metadata",tagRenameBtn:"Rename tag",tagRenamePrompt:"New tag name",tagRenameImpactConfirm:"Rename this tag everywhere? Reporting and historical task breakdowns will now use the new name. Existing sessions and task entries will be updated.",renameImpactDontShowAgain:"Remember this choice and don’t show again",tagUnpinConfirm:"Remove this tag from your pinned list? It may still appear if used on tasks.",tagExcludeConfirm:"Hide this tag from dashboard shortcuts? Task and session data are not changed; existing tasks keep the tag and reporting can still count it.",projectsHeading:"Saved projects",projectsIntro:"Projects you added via @project or the dashboard.",projectsHelpAria:"Help: saved projects",projectsHelpBody:"Deleting a project (trash icon) removes it from the saved list, clears its description, and purges metadata for tags stored as Project#… for that project. Tasks are not modified; any task that still references @project keeps it.",projectsAddFieldLabel:"Add a project",projectsAddPlaceholder:"e.g. ClientABC",projectsAddBtn:"Add project",projectsTableProjectCol:"Project",projectsRenameBtn:"Rename project",projectsRenamePrompt:"New project name",projectRenameImpactConfirm:"Rename this project everywhere? Reporting by project and historical task breakdowns will now use the new name. Existing sessions and task entries will be updated.",projectsRemoveBtn:"Delete project and related tag metadata",projectRemoveConfirm:"Permanently delete this project’s metadata? It will be removed from the saved list, its description cleared, and pinned/hidden/description data for tags in the form Project#… under this project will be removed. Tasks are not modified.",tagDescriptionLabel:"Description (tooltip in dashboard)",projectDescriptionLabel:"Description (tooltip in dashboard)",descriptionSaveBtn:"Save description",tagStartTrackedTaskBtn:"Start tracking a task with this tag (and project if linked)",tagStartTrackedTaskFromProjectBtn:"Start tracking a task with this project",tagStartTaskAutoSessionToast:"No active session — starting one now so your task can be tracked in this session.",tagStartTaskConflictTitle:"Tracking already active",tagStartTaskConflictMessage:"One or more tasks already have a running timer. Choose what to do with them before starting this task: finish them (moved to completed), pause them (resume later from the paused list), or keep them running and start this task in parallel.",tagStartTaskConflictPauseBtn:"Pause active tasks",tagStartTaskConflictFinishBtn:"Finish active tasks",tagStartTaskConflictParallelBtn:"Start in parallel (keep timers running)",tagStartTaskConflictDontShowAgain:"Remember this choice and don’t show this dialog again (the same action will run automatically next time).",tagsScopeToolHeading:"Tag scope migration",tagsScopeToolSourceLabel:"Source tag",tagsScopeToolTargetProjectLabel:"Target project scope",tagsScopeToolTargetGlobalOption:"Global (no project)",tagsScopeToolCopyBtn:"Copy to target scope",tagsScopeToolMoveBtn:"Move to target scope",tagsScopeToolNoTags:"No known tag available to migrate yet.",tagsEmptyGlobal:"No global tags in shortcuts yet. Pin one above or add #tags on tasks.",tagsByProjectSectionEmpty:"No project-linked tags in shortcuts yet. Use @Project#code on a task or pin one below.",tagsByProjectSubEmpty:"No linked tag for this project in shortcuts yet.",projectsEmpty:"No saved projects yet. Use @project on a task or pick a project on the dashboard.",hiddenTagsEmpty:"No tags hidden.",workspaceLocExcludedDirs:"Excluded directory name segments",workspaceLocExcludedDirsDesc:"One name per line (a single path segment, not a full path). If any segment of a file path equals a listed name, that file is skipped — for both Git-tracked lists and folder walks. Examples: node_modules, .git, .husky, .venv, dist.",workspaceLocExcludedPatterns:"Excluded path patterns",workspaceLocExcludedPatternsDesc:"One pattern per line (minimatch syntax: *, ?, **), relative to the workspace root. Examples: **/*.min.js, generated/**, **/*.gen.ts. After saving, refresh the snapshot from the Reporting page.",pickStorageFolder:"Choose folder…",hintPortRestart:"After changing the port, restart the Kronosys server process so the API listens on the new port.",hintDashboardUrl:"Display-only reference URL; does not start the Next.js server.",tocSubDashboardTour:"Guided tour",tocSubReportingTour:"Reporting tour",tocSubDashboardColumnHints:"Three-column guide",dashboardColumnHintsBlockTitle:"Three-column guide on the dashboard",dashboardColumnHintsBlockIntro:"If you removed the strip under the dashboard header (X button), restore it here. This preference is stored in the browser for this site.",dashboardColumnHintsRestoreBtn:"Show three-column guide again",dashboardColumnHintsRestoreDone:"Preference reset. Open the dashboard to see the strip.",tagsProjectsTabsAriaLabel:"Tags column sections",tagsProjectsTabGlobal:"Global tags",tagsProjectsTabProjects:"Projects & linked tags",tagsProjectsTabTemplates:"Task templates",tocSubSessionDurationAlert:"Session duration alert",tocSubDefaultSessionNameTemplate:"Default session name",dashboardSessionDurationAlertHours:"Session duration alert (hours)",dashboardSessionDurationAlertHoursDesc:"Wall-clock session duration in the dashboard sidebar: when it reaches this many hours or more, the value is shown in red with a slow blink. Default: 24. Range: 1–8760.",dashboardTourBlockTitle:"Dashboard guided tour",dashboardTourBlockIntro:"Five short steps explain sessions, tasks, tags, and shortcuts. You can reopen the tour anytime from here.",dashboardTourReplayLinkLabel:"Open dashboard and start tour",reportingTourBlockTitle:"Reporting guided tour",reportingTourBlockIntro:"Filters, KPIs, charts, and tag/project splits on the Reporting page. You can reopen this walkthrough anytime.",reportingTourReplayLinkLabel:"Open Reporting and start tour",enabled:"Enable activity collection",enabledDesc:"Global switch for activity collection.",autoStart:"Auto-start",autoStartDesc:"Start collection when the Kronosys process starts.",sectionSchedule:"Work Schedule",scheduleEnabled:"Enable automatic schedule",scheduleEnabledDesc:"Automatically start and stop tracking sessions based on your working hours.",scheduleDays:"Active days",scheduleDaysDesc:"Days of the week when auto-tracking is active.",scheduleStartTime:"Start time",scheduleEndTime:"End time",timePickerPopoverTimeLabel:"Time (24 h)",timePickerPopoverHourAria:"Hour (24 h)",timePickerPopoverMinuteAria:"Minutes",scheduleCreateDailySession:"Create daily session",scheduleCreateDailySessionDesc:"Automatically create a new session at the schedule start time for each active day.",scheduleTransferTasks:"Transfer active tasks",scheduleTransferTasksDesc:"Automatically transfer active tasks from the previous session into the new session.",schedulePauseTasks:"Pause tasks on stop",schedulePauseTasksDesc:"Automatically pause active tasks when the work schedule ends.",sectionPlannedSessions:"Specific Planned Sessions",plannedSessionsIntro:"Add specific recurring sessions. These take precedence over the general work schedule during their time block.",plannedSessionAdd:"Add planned session",plannedSessionName:"Session name",plannedSessionTags:"Tags (comma-separated)",plannedSessionProject:"Project",plannedSessionRemove:"Remove this session",showWelcome:"Welcome screen",showWelcomeDesc:"Show welcome until dismissed.",anonymizePaths:"Anonymize paths",anonymizePathsDesc:"Hash file paths before writing events.",flushInterval:"Flush interval (seconds)",flushIntervalDesc:"How often buffered events are written to storage (5–3600).",heartbeatInterval:"Heartbeat interval (seconds)",heartbeatIntervalDesc:"Minimum time between heartbeat events (30–86400).",maxBuffered:"Max buffered events",maxBufferedDesc:"Events kept in memory before trimming (100–100000).",historyPath:"History storage path",historyPathDesc:"Leave empty for the default application data directory. ~ is your home directory.",historyPartition:"History file partition",historyPartitionDesc:"How session files are split on disk.",localPersistenceDriver:"Local session storage",localPersistenceDriverDesc:"JSON keeps the legacy partitioned files. SQLite stores sessions in a single database file in the same folder; existing JSON is imported once. MongoDB mirror (if enabled) is unchanged. Restart the process after changing this.",persistenceDriverJson:"JSON files",persistenceDriverSqlite:"SQLite",localPersistenceReloadHint:"After changing the driver, restart the Kronosys process so the new setting is applied.",partitionDaily:"Daily",partitionWeekly:"Weekly",partitionMonthly:"Monthly",sessionStartMode:"When tracking starts",sessionStartModeDesc:"Continue previous session or always start fresh.",modeContinue:"Continue previous session",modeNew:"Always new session",exportFormat:"Default export format",exportFormatDesc:"Used for session history exports.",fmtJson:"JSON",fmtCsv:"CSV",fmtJira:"Jira table",fmtSap:"SAP",csvDelimiter:"CSV delimiter",csvDelimiterDesc:"Single character, e.g. , or ;",autoGitSync:"Auto Git sync",autoGitSyncDesc:"Optional: after each local save, commit and push the history folder to your remote. Session list still loads from local JSON only.",gitRemoteUrl:"Git remote URL",gitRemoteUrlDesc:"Required if auto sync is enabled.",tocSubGitIdentity:"Git author (dashboard)",gitIdentitySubheading:"Git author shown in the dashboard",gitIdentityIntro:"Stored locally with your Kronosys data (SQLite). Shown in the dashboard header next to workspace paths — this does not run git config on your machine.",gitIdentityNameLabel:"Display name",gitIdentityNameDesc:"Like git config user.name (how you want to be credited).",gitIdentityEmailLabel:"Email",gitIdentityEmailDesc:"Like git config user.email (for display only here).",gitIdentityLoginLabel:"Forge username",gitIdentityLoginDesc:"Optional: GitHub, GitLab, or other host login (not the same as the display name).",gitIdentitySave:"Save Git author",gitIdentitySaving:"Saving…",gitIdentitySavedFlash:"Git author saved.",glabRemoteSuggest:"GitLab CLI (glab) is available and a token is configured: you can create a private remote named kronosys-sessions and enable auto sync in one step.",glabRemoteCreate:"Create GitLab repo with glab",glabRemoteCreating:"Creating repository…",gitlabToken:"GitLab token",gitlabTokenDesc:"Optional personal access token for glab (private repo creation, issue list). In this dashboard, saving stores the token in local SQLite (not in the JSON state) so issue import can call GitLab; it overrides GITLAB_TOKEN from the server environment when saved. Use Test connection to enable “Import issue from Git”.",gitlabTokenSave:"Save token",gitlabTokenClear:"Clear stored token",gitlabTokenSaveNeedValue:"Paste your token in the field first — saving with an empty field does not keep a secret on this server.",gitlabTokenStoredYes:"A token is stored in the local secret store; it takes precedence over GITLAB_TOKEN when calling glab.",gitlabTokenFromEnvYes:"No stored token; glab uses GITLAB_TOKEN from the server environment.",gitlabTokenNone:"No token yet — save one below or set GITLAB_TOKEN for the dashboard server process.",gitlabInstanceUrl:"GitLab instance URL",gitlabInstanceUrlDesc:"Origin only (no /api/v4 path). Leave empty for GitLab.com. For self-managed GitLab, set your instance (e.g. https://gitlab.example.org). You can also set GITLAB_INSTANCE_URL on the server process.",gitlabTest401Help:"401 usually means the token does not match this host (wrong instance URL), or the token is expired, revoked, or missing the api scope.",gitlabTestConnection:"Test GitLab connection",gitlabTestConnectionAria:"Test GitLab API token",gitlabTestRunning:"Testing GitLab…",gitlabTestOk:"GitLab API responded successfully. Issue import is enabled in the task column.",gitlabTestFail:"GitLab API test failed. Check the token, the instance URL field above, and your network.",gitlabTestNoToken:"No token to test: paste a token in the field, save it, or ensure GITLAB_TOKEN is available to this dashboard process when using the environment token.",gitlabTestErrorGeneric:"Could not run the GitLab connection test.",gitlabApiVerifiedYes:"GitLab API: verified — task issue import is available.",gitlabApiVerifiedNo:"GitLab API: not verified — run Test connection to enable task issue import.",gitlabTestPasteStoredHint:"To test a token already saved locally, paste it temporarily in the field above (this dashboard cannot read the secret back from storage).",historyLocalFirstHint:"Session history is read from local JSON files or SQLite (see Local session storage). Git auto-sync pushes the folder after saves when enabled. MongoDB is updated only when you push sessions from the dashboard or use Resync in settings.",mongoEnabled:"MongoDB integration",mongoEnabledDesc:"When enabled, you can push individual sessions to MongoDB from the dashboard (and bulk-resync in settings). Nothing is sent automatically on each save. The dashboard still reads local storage only (JSON or SQLite).",mongoDatabase:"MongoDB database",mongoDatabaseDesc:"Database name (letters, digits, underscore, hyphen).",mongoCollection:"MongoDB collection",mongoCollectionDesc:"Collection name (one document per session).",sectionMongoConnection:"MongoDB connection",mongoConnectionIntro:"Build mongodb://user:pass@host:port/?authSource=… from the fields below, or set a full URI in Advanced. A stored full URI takes precedence. Main Save also applies host/port/user/auth and stores password or manual URI when those fields are not empty.",mongoHost:"Host",mongoHostDesc:"Hostname or IP (e.g. 127.0.0.1).",mongoPort:"Port",mongoPortDesc:"TCP port (default 27017).",mongoUser:"Username",mongoUserDesc:"Leave empty for no authentication. If set, a password is required (stored in the secret store).",mongoPassword:"Password",mongoPasswordDesc:"Stored in the local secret store only. Use Save password or the main Save button when the field is not empty.",mongoPasswordSave:"Save password",mongoPasswordClear:"Clear stored password",mongoPasswordConfiguredYes:"A password is stored.",mongoPasswordConfiguredNo:"No password stored.",mongoAuthSource:"authSource",mongoAuthSourceDesc:"Database for authentication (often admin).",mongoManualUri:"Full URI (advanced)",mongoManualUriDesc:"If set, this URI is used instead of host/user/password. Stored in the secret store. Clear to use the built connection again.",mongoUri:"Connection URI",mongoUriDesc:"mongodb:// or mongodb+srv:// — main Save stores this when not empty.",mongoUriSave:"Save URI",mongoUriClear:"Clear stored URI",mongoUriConfiguredYes:"A full connection URI is stored (advanced).",mongoUriConfiguredNo:"No full URI stored; built connection is used when possible.",mongoRemoteStatus:"MongoDB status",mongoStatusConnected:"Connected",mongoStatusFailed:"Failed or misconfigured",mongoStatusPending:"Checking…",mongoConnectionResolvableYes:"Connection parameters are sufficient.",mongoConnectionResolvableNo:"Incomplete (e.g. set password if username is filled).",mongoTestConnection:"Test connection",mongoTestConnectionAria:"Test MongoDB connection",mongoTestRunning:"Testing connection…",mongoTestOk:"Connection test succeeded (ping on the configured database).",mongoTestFail:"Connection test failed. Check host, port, credentials, URI, and network.",mongoTestDisabled:"Enable the MongoDB mirror above to run a connection test.",mongoTestErrorGeneric:"Could not run the connection test via the local API.",mongoTestUsesSavedConfigHint:"Host, port, database, collection, and user below are used for the test even if you have not clicked Save. A stored full URI or password (via the dedicated buttons) always comes from the local secret store.",mongoSyncSectionTitle:"Local vs MongoDB",mongoResyncButton:"Resync all sessions to MongoDB",mongoResyncAriaLabel:"Resync all local sessions to the MongoDB mirror",mongoResyncConfirm:"Upsert every local session snapshot into MongoDB? This can take a moment if you have many sessions.",mongoResyncRunning:"Resyncing…",mongoResyncDone:"Resync finished: {upserted} sessions written, {failed} failed.",mongoResyncHint:"Upserts every local session into MongoDB and updates push metadata in JSON. Extra documents already in MongoDB are not deleted.",mongoResyncDisabled:"Enable the MongoDB mirror in settings before resyncing.",mongoResyncUnsupported:"This storage backend does not support Mongo resync.",mongoResyncErrorGeneric:"Could not run the resync action.",mongoResyncErrorDetail:"Resync failed: {detail}",workspaceFoldersLabel:"Workspace roots",workspaceFoldersEmpty:"No workspace root is configured for this dashboard.",localApiPort:"Local API port",localApiPortDesc:"Loopback HTTP API for this dashboard (127.0.0.1 only).",dashboardWebUrl:"Dashboard URL (display)",dashboardWebUrlDesc:"Suggested URL for opening the dashboard in a browser (e.g. bookmarks). Use a loopback URL (localhost, 127.0.0.1, [::1]) or a hostname in /etc/hosts that resolves to loopback (e.g. kronosys).",dashboardDisplayTimeZone:"Display time zone",dashboardDisplayTimeZoneDesc:"Used for session dates on the dashboard, task timestamps, and reporting day buckets. Pick a suggestion or type any IANA time zone (e.g. Europe/Brussels). Default is Eastern Time (America/Toronto).",dashboardClockFormat:"Clock format",dashboardClockFormatDesc:"How times are shown on the dashboard (task start/end, past-task date preview) and in schedule time previews. Dates are unchanged.",dashboardClock24hOption:"24-hour",dashboardClock12hOption:"12-hour (AM/PM)",dashboardCalendarWeekStartsOn:"Week starts on",dashboardCalendarWeekStartsOnDesc:"First column in date-picker calendars (dashboard task times, past sessions) and weekly grids in Reports. The date filter preset “Week” still uses Monday–Sunday.",calendarWeekStartsSunday:"Sunday",calendarWeekStartsMonday:"Monday",calendarWeekStartsSaturday:"Saturday",dashboardLightThemeVariant:"Light theme tint",dashboardLightThemeVariantDesc:"Applies when the dashboard is in light mode (moon icon in the toolbar). Dark mode is unchanged. Your choice is saved in this browser and in local settings.",dashboardLightThemeWarm:"Warm",dashboardLightThemeSoft:"Soft",dashboardLightThemeContrast:"High contrast",dashboardSemanticChipAccessibleMode:"Do not rely on color alone",dashboardSemanticChipAccessibleModeDesc:"When enabled, tag, work project, and personal project chips show #, @, and ! prefixes plus distinct border styles (solid, double, dashed) in addition to their colors — on the dashboard, reporting filters, and anywhere those chips appear. Saved in this browser and in local settings.",dashboardBaseDailyHours:"Base daily hours",dashboardBaseDailyHoursDesc:"Reference hours per day for variance tracking in Billing allocation reports.",dashboardBaseDailyToleranceMinutes:"Tolerance (minutes)",dashboardBaseDailyToleranceMinutesDesc:"Allowed deviation from base hours before highlighting (default: 10 min).",dashboardDefaultSessionNameTemplate:"Default new session name template",dashboardDefaultSessionNameTemplateDesc:"Applied when a brand-new live session is created (dashboard “New session”, or the implicit session when the first task starts with no session yet). Leave empty to leave the name blank. Tokens: `%%` for a literal percent; `%UUID` for the full session id; `%Y` `%y` `%m` `%d` `%H` `%M` `%S` plus `%F` (same as `%Y-%m-%d`) follow POSIX strftime semantics (IEEE / Open Group reference: https://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html). Note: `%m` is the month; `%M` is minutes. Expansion uses the Display time zone chosen above (consistent with dashboard reporting day buckets).",invalidDashboardTimeZone:"Unrecognized time zone. Enter a valid IANA name (e.g. America/Toronto).",dialogOkBtn:"OK",dialogCancelBtn:"Cancel",dialogConfirmBtn:"Confirm",scrollToTopAria:"Back to top",licensesPageLink:"Licenses & third-party notices",sectionHolidayCalendar:"Holiday calendar",holidayCalendarProvince:"Province",holidayCalendarProvinceDesc:"Select a province to automatically populate public holidays in the reporting calendar.",holidayCalendarProvinceNone:"None",holidayCalendarApplyBtn:"Apply province holidays",holidayCalendarApplied:"Province holidays have been applied to the reporting calendar.",holidayCalendarHint:"Public holidays are populated for the current and upcoming years. You can adjust or move any holiday directly from the reporting page using the day marker control."},e={title:"Param\xe8tres",subtitle:"Options Kronosys enregistr\xe9es localement sur cette machine.",loading:"Chargement des param\xe8tres…",reload:"Recharger depuis le serveur",save:"Enregistrer",saving:"Enregistrement…",savedOk:"Param\xe8tres enregistr\xe9s.",settingsUnsavedStickyHint:"Modifications non enregistr\xe9es.",resetToDefaults:"R\xe9initialiser aux valeurs par d\xe9faut",resetToDefaultsConfirm:"R\xe9tablir toutes les options Kronosys \xe0 leurs valeurs d’usine ? Les jetons GitLab et les indicateurs de connexion MongoDB d\xe9j\xe0 enregistr\xe9s dans le stockage s\xe9curis\xe9 ne sont pas supprim\xe9s ; seuls les champs de configuration affich\xe9s sur cette page sont remis \xe0 z\xe9ro.",resettingDefaults:"R\xe9initialisation…",resetDefaultsDone:"Valeurs par d\xe9faut appliqu\xe9es.",openIdeSettings:"Ces champs correspondent aux cl\xe9s de configuration persist\xe9es dans le stockage local.",tocHeading:"Sur cette page",tocNavAriaLabel:"Aller \xe0 une section des param\xe8tres",tocSearchPlaceholder:"Filtrer le sommaire…",tocSearchAriaLabel:"Filtrer les sections affich\xe9es dans le sommaire",tocSearchNoResults:"Aucun titre de section ne correspond.",sectionUsageProfile:"Profil d’utilisation",usageProfile:"Profil",usageProfileDesc:"D\xe9veloppeur : lignes \xe9crites, stats par langage, signaux de codage, instantan\xe9 LOC et carte Git du d\xe9p\xf4t. Gestionnaire : t\xe2ches, sessions, KronoFocus et temps seulement — pas de m\xe9triques ni d’affichages li\xe9s au code source.",profileDeveloper:"D\xe9veloppeur",profileManager:"Gestionnaire",workspaceLocSectionHiddenManager:"Ces options ne s’appliquent qu’au profil D\xe9veloppeur (instantan\xe9 lignes de code dans Rapports).",sectionGeneral:"G\xe9n\xe9ral",sectionPrivacy:"Confidentialit\xe9",sectionKronoFocus:"KronoFocus (tableau de bord)",kronoFocusHeaderPinnedNote:"Le minuteur KronoFocus et ses contr\xf4les restent toujours dans la barre d’outils de l’application (\xe0 c\xf4t\xe9 de l’horloge et de la palette de commandes), afin que la barre de navigation garde la m\xeame largeur sur toutes les pages. En consultation d’archive, les contr\xf4les restent visibles mais ciblent la session live.",kronoFocusShowInTaskOps:"Afficher dans les boutons op\xe9rationnels des t\xe2ches",kronoFocusShowInTaskOpsDesc:"Bouton pour lancer le KronoFocus depuis une t\xe2che suivie et option \xab lancer aussi le KronoFocus \xbb lors de la cr\xe9ation d’une t\xe2che.",sectionTaskTags:"T\xe2ches et \xe9tiquettes",taskDefaultTagBucketEnabled:"\xc9tiquette \xab d\xe9faut \xbb pour les t\xe2ches sans #",taskDefaultTagBucketEnabledDesc:"Activ\xe9 : une t\xe2che sans aucune \xe9tiquette explicite re\xe7oit l’\xe9tiquette r\xe9serv\xe9e (affich\xe9e \xab d\xe9faut \xbb). D\xe9sactiv\xe9 : la liste d’\xe9tiquettes reste vide jusqu’\xe0 ce que vous en ajoutiez une.",taskStripDefaultTagWhenExplicitTags:"Retirer \xab d\xe9faut \xbb lorsqu’une autre \xe9tiquette est ajout\xe9e",taskStripDefaultTagWhenExplicitTagsDesc:"Activ\xe9 : d\xe8s qu’une t\xe2che re\xe7oit au moins une \xe9tiquette explicite (#autre que \xab d\xe9faut \xbb), l’\xe9tiquette r\xe9serv\xe9e \xab d\xe9faut \xbb est retir\xe9e automatiquement. D\xe9sactiv\xe9 : \xab d\xe9faut \xbb peut coexister avec d’autres \xe9tiquettes.",taskMinimumDurationMinutes:"Dur\xe9e minimale d’une t\xe2che (minutes)",taskMinimumDurationMinutesDesc:"\xc9cart par d\xe9faut pour la saisie pass\xe9e ou planifi\xe9e : la fin est pr\xe9remplie au d\xe9but plus cette dur\xe9e (ex. 30 ou 60). Plage : 15–480.",dashboardAllowTaskStartTimeEdit:"Autoriser la correction de l’heure de d\xe9but des t\xe2ches dans le tableau de bord",dashboardAllowTaskStartTimeEditDesc:"Affiche des contr\xf4les pour modifier l’heure de d\xe9but d’une t\xe2che dans la colonne T\xe2ches, pendant son ex\xe9cution ou apr\xe8s sa fin.",dashboardAllowSessionStartTimeEdit:"Autoriser la correction de l’heure de d\xe9but des sessions dans le tableau de bord",dashboardAllowSessionStartTimeEditDesc:"Affiche des contr\xf4les pour modifier l’heure de d\xe9but d’une session dans la colonne Sessions, en cours ou dans l’historique.",dashboardAllowTaskEndTimeEdit:"Autoriser la correction de l’heure de fin des t\xe2ches dans le tableau de bord",dashboardAllowTaskEndTimeEditDesc:"Affiche des contr\xf4les pour d\xe9finir ou modifier l’heure de fin d’une t\xe2che dans la colonne T\xe2ches, y compris pendant son ex\xe9cution (la t\xe2che se termine automatiquement \xe0 l’heure planifi\xe9e).",dashboardAllowSessionEndTimeEdit:"Autoriser la correction de l’heure de fin des sessions dans le tableau de bord",dashboardAllowSessionEndTimeEditDesc:"Affiche des contr\xf4les pour d\xe9finir ou modifier l’heure de fin d’une session dans la colonne Sessions, y compris sur une session live (la session se cl\xf4t automatiquement \xe0 l’heure planifi\xe9e).",sectionCollection:"Collecte et tampons",sectionHistory:"Historique des sessions",sectionDangerZone:"Zone de danger",dangerClearHistoryTitle:"Effacer toutes les donn\xe9es locales du tableau de bord",dangerClearHistoryBodyIntro:"Supprime d\xe9finitivement, dans le stockage local de ce tableau de bord :",dangerClearHistoryBodyBullets:["Toutes les sessions (vue en cours, liste principale et archives) ainsi que la session consult\xe9e","Toute la m\xe9tadonn\xe9e \xe9tiquettes / projets : raccourcis \xe9pingl\xe9s, \xe9tiquettes masqu\xe9es des pastilles, descriptions, listes de suggestions connues","L’identit\xe9 Git enregistr\xe9e ici (nom affich\xe9, courriel, identifiant forge) et les donn\xe9es de la carte statistiques Git","L’instantan\xe9 lignes de code du workspace mis en cache pour Rapports (profil D\xe9veloppeur)","La pr\xe9f\xe9rence locale \xab ne plus demander confirmation d’archivage \xbb","La langue du tableau de bord m\xe9moris\xe9e dans le navigateur et le marqueur de choix explicite (vous choisirez \xe0 nouveau anglais ou fran\xe7ais avant la visite guid\xe9e)"],dangerClearHistoryBodyAfterList1:"Ensuite, la visite guid\xe9e d’accueil sera repropos\xe9e sur le tableau de bord et l’option \xab \xe9cran d’accueil au d\xe9marrage \xbb est r\xe9activ\xe9e dans les param\xe8tres.",dangerClearHistoryBodyAfterList2:"Action irr\xe9versible.",dangerClearHistoryButton:"Tout effacer…",dangerClearHistoryConfirm:"Vous effacez tout ce qui est d\xe9crit ci-dessus dans la zone de danger (sessions, m\xe9tadonn\xe9es \xe9tiquettes/projets, identit\xe9 Git dans ce stockage, etc.). Poursuivre ?",dangerClearHistoryVaultTargetTitle:"Coffre cibl\xe9 par cet effacement",dangerClearHistoryVaultTargetTrace:"L’effacement porte sur le r\xe9pertoire impos\xe9 par TRACE_DATA_DIR : {path}. Aucun autre coffre Kronosys n’est concern\xe9.",dangerClearHistoryVaultTargetDual:"L’effacement ne concerne que le coffre {env} actuellement charg\xe9 par ce serveur ({path}). Le coffre {otherEnv} ({otherPath}) n’est pas modifi\xe9.",dangerClearHistoryVaultTargetSingle:"L’effacement porte sur le r\xe9pertoire de donn\xe9es actuellement charg\xe9 par ce serveur ({path}).",dangerClearHistoryVaultTargetDev:"L’effacement porte sur le r\xe9pertoire de d\xe9veloppement actuellement charg\xe9 par ce serveur ({path}), pas sur le coffre production packag\xe9 sauf si vous le partagez explicitement.",dangerClearHistoryVaultMismatch:"Attention : la pr\xe9f\xe9rence enregistr\xe9e vise {preferredEnv} ({preferredPath}) au prochain red\xe9marrage, mais ce processus utilise encore {activePath}. L’effacement portera sur le r\xe9pertoire en cours d’utilisation.",dangerClearHistoryConfirmPhrase:"EFFACER",dangerClearHistoryTypeInstruction:"Pour activer \xab Confirmer \xbb, saisissez exactement {phrase} ci-dessous (toutes majuscules, sans espaces).",dangerClearHistoryTypeFieldLabel:"Mot de confirmation",dangerClearHistoryTypeInputAria:"Saisir le mot de confirmation pour autoriser l’effacement complet d\xe9crit ci-dessus (sessions, m\xe9tadonn\xe9es, identit\xe9 Git, etc.)",dangerClearHistoryBackupIntro:"Avant de confirmer, vous pouvez t\xe9l\xe9charger une copie locale (les m\xeames donn\xe9es que le tableau de bord sur cette machine) :",dangerClearHistoryBackupJson:"JSON — instantan\xe9 complet d’\xe9tat",dangerClearHistoryBackupJsonHint:"Charge utile Kronosys enti\xe8re dans un seul fichier (sessions y compris la session active `current`, t\xe2ches, m\xe9tadonn\xe9es \xe9tiquettes/projets, identit\xe9 Git, `cfg`, instantan\xe9 statistiques Git, instantan\xe9 lignes de code du workspace, etc.).",dangerClearHistoryBackupCsvBlockTitle:"CSV — plusieurs tableaux (un t\xe9l\xe9chargement par lien)",dangerClearHistoryBackupCsvBlockHint:"R\xe9unis, ces fichiers refl\xe8tent ce que l’effacement de la zone de danger supprime : sessions (avec une colonne JSON compl\xe8te par ligne), chaque t\xe2che et sous-t\xe2che, listes et descriptions d’\xe9tiquettes/projets, identit\xe9 Git, ainsi que la configuration et les blocs JSON (`cfg`, stats Git, instantan\xe9 lignes de code, session inspect\xe9e, etc.).",dangerClearHistoryBackupCsvZip:"CSV — tous les tableaux (ZIP)",dangerClearHistoryBackupCsvZipHint:"Un seul t\xe9l\xe9chargement contenant les huit fichiers CSV en UTF-8.",dangerClearHistoryBackupCsvSeparateTitle:"Fichiers s\xe9par\xe9s (optionnel)",dangerClearHistoryBackupCsvSessions:"Sessions — indicateurs \xe9tendus + JSON de session complet",dangerClearHistoryBackupCsvTasks:"T\xe2ches — une ligne par t\xe2che + JSON de t\xe2che complet",dangerClearHistoryBackupCsvSubtasks:"Sous-t\xe2ches — une ligne par \xe9l\xe9ment de liste + JSON",dangerClearHistoryBackupCsvRegistry:"Registre \xe9tiquettes / projets — listes connues, \xe9pingl\xe9es, masqu\xe9es",dangerClearHistoryBackupCsvTagDesc:"Descriptions d’\xe9tiquettes",dangerClearHistoryBackupCsvProjectDesc:"Descriptions de projets",dangerClearHistoryBackupCsvGitId:"Identit\xe9 Git (enregistr\xe9e dans ce stockage)",dangerClearHistoryBackupCsvStoreBlobs:"Configuration et instantan\xe9s — `cfg`, stats Git, LOC workspace, pr\xe9f\xe9rences d’affichage",dangerClearHistoryBackupSqlite:"SQLite — fichier de base de donn\xe9es",dangerClearHistoryBackupSqliteHint:"Fichier kronosys.sqlite apr\xe8s pointage WAL (restauration en rempla\xe7ant le fichier \xe0 l’arr\xeat de l’application).",dangerBackupRestoreTitle:"Sauvegardes et restauration compl\xe8te",dangerBackupRestoreIntro:"T\xe9l\xe9chargez d’abord une sauvegarde compl\xe8te, puis restaurez un fichier de sauvegarde ant\xe9rieur au besoin (instantan\xe9 JSON ou fichier SQLite).",dangerRestorePickFile:"Fichier de restauration (`.json` ou `.sqlite`)",dangerRestoreHint:"La restauration remplace le stockage local courant sur cette machine. Faites une sauvegarde juste avant si vous avez un doute.",dangerRestoreButton:"Restaurer depuis une sauvegarde…",dangerRestoreBusy:"Restauration…",dangerRestoreConfirm:"Restaurer ce fichier de sauvegarde maintenant ? Le stockage local courant sera remplac\xe9 pour cet environnement.",dangerRestoreNoFile:"Choisissez un fichier de sauvegarde avant de lancer la restauration.",dangerRestoreDoneJson:"Restauration termin\xe9e depuis l’instantan\xe9 JSON. Les donn\xe9es du tableau de bord ont \xe9t\xe9 recharg\xe9es.",dangerRestoreDoneSqlite:"Restauration termin\xe9e depuis le fichier SQLite. Les donn\xe9es du tableau de bord ont \xe9t\xe9 recharg\xe9es.",dangerRestoreFailed:"\xc9chec de la restauration : {detail}",sectionArchivedSessions:"Sessions archiv\xe9es",archivedSessionsIntro:"Sessions retir\xe9es de la liste principale du tableau de bord, tri\xe9es par enregistrement le plus r\xe9cent. Restaurer les r\xe9int\xe8gre dans la colonne Sessions.",archivesPaginationPrev:"Page pr\xe9c\xe9dente",archivesPaginationNext:"Page suivante",archivesPaginationNavAria:"Pagination des sessions archiv\xe9es",archivesPaginationRange:"{from}–{to} sur {total}",sectionExport:"Export par d\xe9faut",sectionGit:"Synchronisation Git",sectionMongo:"Miroir MongoDB",sectionWeb:"Tableau de bord et API",devDataBlockTitle:"Mode d\xe9veloppement (coffre local)",devDataIntro:"Lorsque le serveur de d\xe9veloppement Next.js est utilis\xe9 (`next dev`), SQLite et l’\xe9tat local vont par d\xe9faut dans un dossier distinct (`…/v4-dev`) de l’instance de production (`next start`, `…/v4`) afin d’\xe9viter d’\xe9craser vos vraies donn\xe9es. Enregistrez avec le bouton **Enregistrer** en bas de page, comme les autres param\xe8tres.",devDataUseProdLabel:"Utiliser le m\xeame r\xe9pertoire de donn\xe9es qu’en production (v4)",devDataUseProdDesc:"D\xe9sactiv\xe9 (d\xe9faut) : le mode dev utilise un r\xe9pertoire isol\xe9 `v4-dev`. Activ\xe9 : le mode dev lit et \xe9crit le chemin `v4` comme une ex\xe9cution packag\xe9e ou `next start`. Apr\xe8s modification, red\xe9marrez le serveur de dev pour ouvrir le bon fichier SQLite.",devDataActivePath:"R\xe9pertoire de donn\xe9es utilis\xe9 (ce processus)",devDataPreferredPath:"S’appliquerait au prochain red\xe9marrage",devDataProdPath:"R\xe9pertoire production par d\xe9faut (v4)",devDataPrefsFile:"Fichier de pr\xe9f\xe9rence sur le disque",devDataTraceOverride:"Le serveur a \xe9t\xe9 lanc\xe9 avec TRACE_DATA_DIR ; ce chemin est utilis\xe9 et ce commutateur est d\xe9sactiv\xe9.",devDataEnvOverride:"La variable d’environnement KRONOSYS_DEV_USE_PROD_DATA est d\xe9finie ; le mode dev utilise le chemin v4 de production et ce commutateur est d\xe9sactiv\xe9.",devDataRestartHint:"La pr\xe9f\xe9rence enregistr\xe9e ne correspond plus \xe0 la base ouverte. Red\xe9marrez le serveur `next dev` pour l’appliquer.",devDataHiddenNotDev:"Ce bloc s’affiche seulement lorsque le tableau de bord est servi en mode d\xe9veloppement (`next dev`).",dataEnvBlockTitle:"Coffres production et QA",dataEnvIntro:"Conservez vos vraies sessions dans le dossier de production (`…/v4`) et utilisez un dossier QA distinct (`…/v4-qa`) pour essayer des fonctions ou reproduire un probl\xe8me sans toucher \xe0 la production. Activez les deux coffres ci-dessous, puis basculez avec **Prod / QA** dans la barre de navigation (effet imm\xe9diat) ou changez l’environnement actif ici et **Enregistrez**.",dataEnvDualLabel:"Activer deux coffres de donn\xe9es (production et QA)",dataEnvDualDesc:"Activ\xe9 : SQLite et l’\xe9tat local utilisent `v4` (production) ou `v4-qa` (QA) selon l’environnement actif. D\xe9sactiv\xe9 : seul le coffre de production est utilis\xe9.",dataEnvActiveLabel:"Environnement actif",dataEnvActiveDesc:"Dossier ouvert par ce processus serveur. Vous pouvez aussi basculer depuis la barre de navigation sans ouvrir les param\xe8tres.",dataEnvActiveProduction:"Production (v4)",dataEnvActiveQa:"QA (v4-qa)",dataEnvActivePath:"R\xe9pertoire de donn\xe9es utilis\xe9 (ce processus)",dataEnvPreferredPath:"Pr\xe9f\xe9rence enregistr\xe9e (doit correspondre si synchronis\xe9)",dataEnvProdPath:"R\xe9pertoire production (v4)",dataEnvQaPath:"R\xe9pertoire QA (v4-qa)",dataEnvPrefsFile:"Fichier de pr\xe9f\xe9rence sur le disque",dataEnvTraceOverride:"Le serveur a \xe9t\xe9 d\xe9marr\xe9 avec TRACE_DATA_DIR ; ce chemin est utilis\xe9 et ces options sont d\xe9sactiv\xe9es.",dataEnvRestartHint:"L’environnement enregistr\xe9 ne correspond plus \xe0 la base ouverte. Red\xe9marrez le serveur Kronosys pour l’appliquer.",sectionWorkspaceLoc:"Rapports — instantan\xe9 lignes de code",sectionTagsProjects:"\xc9tiquettes et projets enregistr\xe9s",sectionTaskTemplates:"Mod\xe8les de t\xe2che",taskTemplatesIntro:"Lignes enregistr\xe9es pour le champ \xab sur quoi travaillez-vous \xbb (titre, #\xe9tiquettes et @projet facultatifs). Vous pouvez aussi enregistrer un mod\xe8le depuis une t\xe2che en cours ou termin\xe9e sur le tableau de bord.",taskTemplatesHelpAria:"Aide : mod\xe8les de t\xe2che",taskTemplatesHelpBody:"Les mod\xe8les ne font que pr\xe9remplir le brouillon de t\xe2che — ils ne d\xe9marrent pas le minuteur ni ne modifient les enregistrements existants.\n\nM\xeame syntaxe que sur le tableau de bord : un titre, des #\xe9tiquettes facultatives, un @projet facultatif. Modifier ou supprimer un mod\xe8le ne change pas les sessions ou t\xe2ches d\xe9j\xe0 saisies.",taskTemplatesEmpty:"Aucun mod\xe8le de t\xe2che. Ajoutez-en un ci-dessus ou enregistrez-en un depuis le tableau de bord.",taskTemplatesDraftPlaceholder:"ex. Travail profond #focus @acme",taskTemplatesAddBtn:"Ajouter le mod\xe8le",taskTemplatesSavedToast:"Mod\xe8le de t\xe2che enregistr\xe9.",taskTemplatesRemovedToast:"Mod\xe8le de t\xe2che supprim\xe9.",taskTemplatesUpdatedToast:"Mod\xe8le de t\xe2che mis \xe0 jour.",taskTemplatesColDraft:"Mod\xe8le",taskTemplatesColUpdated:"Mis \xe0 jour",taskTemplatesColActions:"Actions",taskTemplatesEditBtn:"Modifier le mod\xe8le",taskTemplatesSaveBtn:"Enregistrer",taskTemplatesCancelBtn:"Annuler",taskTemplatesDeleteBtn:"Supprimer le mod\xe8le",taskTemplatesDeleteConfirm:"Retirer ce mod\xe8le de la liste enregistr\xe9e ?",tagsProjectsIntro:"G\xe9rez \xe0 part les \xe9tiquettes globales, les projets enregistr\xe9s et les \xe9tiquettes li\xe9es regroup\xe9es par projet. Les m\xeames contr\xf4les sont disponibles dans la colonne de droite du tableau de bord. Ces actions ne r\xe9\xe9crivent pas en masse les t\xe2ches ni les fichiers de session.",tagsProjectsHelpAria:"Aide : impact des changements d’\xe9tiquettes et de projets",tagsProjectsHelpBody:"Cette page comporte trois zones : \xe9tiquettes globales (sans projet), projets enregistr\xe9s, puis \xe9tiquettes li\xe9es regroup\xe9es par projet.\n\nMasquer (ic\xf4ne œil barr\xe9) : l’\xe9tiquette dispara\xeet des pastilles de suggestion ; les t\xe2ches ne sont pas modifi\xe9es.\n\nSupprimer d\xe9finitivement (ic\xf4ne corbeille) : retire l’\xe9tiquette des listes \xe9pingl\xe9es et masqu\xe9es et efface sa description ; les t\xe2ches ne sont pas modifi\xe9es.\n\nIc\xf4nes d’\xe9pingle : g\xe8rent la liste de raccourcis \xe9pingl\xe9s.\n\n\xc9tiquettes li\xe9es : dans une t\xe2che, @Projet#code (stock\xe9 Projet#code) ; les suggestions ne montrent le code que si le projet de la t\xe2che correspond.\n\nDescriptions : notes locales ; infobulles sur le tableau de bord.\n\nSupprimer un projet (corbeille) : retire le projet enregistr\xe9, efface sa description et purge les m\xe9tadonn\xe9es des \xe9tiquettes Projet#… associ\xe9es ; les t\xe2ches ne sont pas modifi\xe9es.",tagsGlobalHeading:"\xc9tiquettes globales (sans projet)",tagsGlobalIntro:"Raccourcis pour des \xe9tiquettes qui ne sont pas li\xe9es \xe0 un projet pr\xe9cis : elles sont propos\xe9es sur toute t\xe2che, avec ou sans @projet.",tagsByProjectHeading:"\xc9tiquettes li\xe9es \xe0 un projet",tagsByProjectIntro:"Chaque bloc correspond \xe0 une cl\xe9 de projet ; les \xe9tiquettes enregistr\xe9es sous la forme Projet#code y sont regroup\xe9es. \xc9pinglage, masquage et descriptions restent propres \xe0 chaque \xe9tiquette.",tagsByProjectOrphanIntro:"Port\xe9es Projet#code sans projet correspondant dans la liste enregistr\xe9e ci-dessus. \xc9pinglez ou modifiez-les ici, ou ajoutez d’abord le projet \xe0 la liste.",tagsByProjectOrphanHelpAria:"Aide : \xe9tiquettes li\xe9es sans projet enregistr\xe9 correspondant",tocSubTagsGlobal:"\xc9tiquettes globales",tocSubTagsProjects:"Projets",tocSubTagsByProject:"\xc9tiquettes par projet",tagsHiddenHeading:"Masqu\xe9es des raccourcis",tagsPinFieldLabel:"\xc9pingler une \xe9tiquette globale",tagsPinPlaceholder:"ex. bugfix ou deep-work",tagsPinScopedFieldLabel:"\xc9pingler une \xe9tiquette li\xe9e \xe0 un projet",tagsPinScopedPlaceholder:"ex. 204822-1530 ou ClientABC#204822-1530",tagsPinAddBtn:"\xc9pingler",tagsTableTagCol:"\xc9tiquette",tagsTableActionsCol:"Actions",tagBadgePinned:"\xc9pingl\xe9e",tagPinBtn:"Ajouter l’\xe9tiquette aux raccourcis \xe9pingl\xe9s",tagUnpinBtn:"Retirer l’\xe9tiquette des raccourcis \xe9pingl\xe9s",tagExcludeBtn:"Masquer l’\xe9tiquette des raccourcis de suggestion",tagRestoreBtn:"R\xe9afficher l’\xe9tiquette dans les raccourcis",tagPurgeAriaLabel:"Supprimer d\xe9finitivement les m\xe9tadonn\xe9es de l’\xe9tiquette",tagPurgeConfirm:"Supprimer d\xe9finitivement les m\xe9tadonn\xe9es de cette \xe9tiquette ? Sa description sera effac\xe9e, elle sera d\xe9s\xe9pingl\xe9e et masqu\xe9e des listes du tableau de bord (elle appara\xeet sous \xab Masqu\xe9es des raccourcis \xbb si des t\xe2ches y font encore r\xe9f\xe9rence). Les t\xe2ches ne sont pas modifi\xe9es.",tagPurgeHiddenConfirm:"Retirer cette \xe9tiquette de la liste masqu\xe9e et effacer sa description ? Si des t\xe2ches l’utilisent encore, elle peut r\xe9appara\xeetre dans les raccourcis. Les t\xe2ches ne sont pas modifi\xe9es.",tagPurgeHiddenAriaLabel:"Supprimer d\xe9finitivement les m\xe9tadonn\xe9es de cette \xe9tiquette masqu\xe9e",tagRenameBtn:"Renommer l’\xe9tiquette",tagRenamePrompt:"Nouveau nom de l’\xe9tiquette",tagRenameImpactConfirm:"Renommer cette \xe9tiquette partout ? Les rapports et les ventilations historiques des t\xe2ches utiliseront d\xe9sormais le nouveau nom. Les sessions et entr\xe9es de t\xe2ches existantes seront mises \xe0 jour.",renameImpactDontShowAgain:"M\xe9moriser ce choix et ne plus afficher",tagUnpinConfirm:"Retirer cette \xe9tiquette de la liste \xe9pingl\xe9e ? Elle peut r\xe9appara\xeetre si des t\xe2ches l’utilisent encore.",tagExcludeConfirm:"Masquer cette \xe9tiquette des raccourcis du tableau de bord ? Les donn\xe9es des t\xe2ches et sessions ne sont pas modifi\xe9es ; les t\xe2ches existantes gardent l’\xe9tiquette et les bilans peuvent encore la compter.",projectsHeading:"Projets enregistr\xe9s",projectsIntro:"Projets ajout\xe9s via @projet ou le tableau de bord.",projectsHelpAria:"Aide : projets enregistr\xe9s",projectsHelpBody:"La suppression (ic\xf4ne corbeille) retire le projet de la liste enregistr\xe9e, efface sa description et purge les m\xe9tadonn\xe9es des \xe9tiquettes enregistr\xe9es sous la forme Projet#… pour ce projet. Les t\xe2ches ne sont pas modifi\xe9es.",projectsAddFieldLabel:"Ajouter un projet",projectsAddPlaceholder:"ex. ClientABC",projectsAddBtn:"Ajouter le projet",projectsTableProjectCol:"Projet",projectsRenameBtn:"Renommer le projet",projectsRenamePrompt:"Nouveau nom du projet",projectRenameImpactConfirm:"Renommer ce projet partout ? Les rapports par projet et les ventilations historiques des t\xe2ches utiliseront d\xe9sormais le nouveau nom. Les sessions et entr\xe9es de t\xe2ches existantes seront mises \xe0 jour.",projectsRemoveBtn:"Supprimer le projet et les m\xe9tadonn\xe9es d’\xe9tiquettes li\xe9es",projectRemoveConfirm:"Supprimer d\xe9finitivement les m\xe9tadonn\xe9es de ce projet ? Il sera retir\xe9 de la liste enregistr\xe9e, sa description effac\xe9e, et les donn\xe9es \xe9pingl\xe9es / masqu\xe9es / descriptions des \xe9tiquettes Projet#… sous ce projet seront supprim\xe9es. Les t\xe2ches ne sont pas modifi\xe9es.",tagDescriptionLabel:"Description (infobulle dans le tableau de bord)",projectDescriptionLabel:"Description (infobulle dans le tableau de bord)",descriptionSaveBtn:"Enregistrer la description",tagStartTrackedTaskBtn:"D\xe9marrer le suivi d’une t\xe2che avec cette \xe9tiquette (et ce projet si li\xe9)",tagStartTrackedTaskFromProjectBtn:"D\xe9marrer le suivi d’une t\xe2che avec ce projet",tagStartTaskAutoSessionToast:"Aucune session en cours — d\xe9marrage d’une session pour y rattacher cette t\xe2che.",tagStartTaskConflictTitle:"Suivi d\xe9j\xe0 actif",tagStartTaskConflictMessage:"Au moins une t\xe2che a d\xe9j\xe0 un minuteur actif. Indiquez ce que vous en faites avant de lancer celle-ci : les terminer (elles passent dans \xab termin\xe9es \xbb), les mettre en pause (reprise plus tard dans \xab en pause \xbb), ou les laisser tourner et d\xe9marrer la nouvelle t\xe2che en parall\xe8le.",tagStartTaskConflictPauseBtn:"Mettre les t\xe2ches actives en pause",tagStartTaskConflictFinishBtn:"Terminer les t\xe2ches actives",tagStartTaskConflictParallelBtn:"D\xe9marrer en parall\xe8le (garder les minuteurs)",tagStartTaskConflictDontShowAgain:"M\xe9moriser ce choix et ne plus afficher cette bo\xeete (la m\xeame action sera appliqu\xe9e automatiquement la prochaine fois).",tagsScopeToolHeading:"Migration de port\xe9e des \xe9tiquettes",tagsScopeToolSourceLabel:"\xc9tiquette source",tagsScopeToolTargetProjectLabel:"Port\xe9e projet cible",tagsScopeToolTargetGlobalOption:"Globale (sans projet)",tagsScopeToolCopyBtn:"Copier vers la port\xe9e cible",tagsScopeToolMoveBtn:"D\xe9placer vers la port\xe9e cible",tagsScopeToolNoTags:"Aucune \xe9tiquette connue \xe0 migrer pour le moment.",tagsEmptyGlobal:"Aucune \xe9tiquette globale dans les raccourcis pour l’instant. \xc9pinglez-en une ci-dessus ou utilisez des #tags sur les t\xe2ches.",tagsByProjectSectionEmpty:"Aucune \xe9tiquette li\xe9e \xe0 un projet dans les raccourcis pour l’instant. Utilisez @Projet#code sur une t\xe2che ou \xe9pinglez un code ci-dessous.",tagsByProjectSubEmpty:"Aucune \xe9tiquette li\xe9e \xe0 ce projet dans les raccourcis pour l’instant.",projectsEmpty:"Aucun projet enregistr\xe9 pour l’instant. Utilisez @projet sur une t\xe2che ou choisissez un projet sur le tableau de bord.",hiddenTagsEmpty:"Aucune \xe9tiquette masqu\xe9e.",workspaceLocExcludedDirs:"Segments de dossiers exclus",workspaceLocExcludedDirsDesc:"Un nom par ligne (un seul segment de chemin, pas un chemin complet). Si un segment du chemin d’un fichier correspond \xe0 une entr\xe9e, le fichier est ignor\xe9 — pour la liste Git et le parcours disque. Ex. : node_modules, .git, .husky, .venv, dist.",workspaceLocExcludedPatterns:"Motifs de chemins exclus",workspaceLocExcludedPatternsDesc:"Un motif par ligne (syntaxe minimatch : *, ?, **), relatif \xe0 la racine du workspace. Ex. : **/*.min.js, generated/**, **/*.gen.ts. Apr\xe8s enregistrement, actualisez l’instantan\xe9 depuis la page Rapports.",pickStorageFolder:"Choisir un dossier…",hintPortRestart:"Apr\xe8s un changement de port, red\xe9marrez le processus Kronosys pour que l’API \xe9coute sur le nouveau port.",hintDashboardUrl:"URL de r\xe9f\xe9rence affich\xe9e seulement ; ne d\xe9marre pas le serveur Next.js.",tocSubDashboardTour:"Visite guid\xe9e",tocSubReportingTour:"Visite Rapports",tocSubDashboardColumnHints:"Aide trois colonnes",dashboardColumnHintsBlockTitle:"Aide \xab trois colonnes \xbb sur le tableau de bord",dashboardColumnHintsBlockIntro:"Si vous avez masqu\xe9 le bandeau sous l’en-t\xeate du tableau de bord (bouton X), vous pouvez le r\xe9afficher ici. Cette pr\xe9f\xe9rence est stock\xe9e dans le navigateur pour ce site.",dashboardColumnHintsRestoreBtn:"R\xe9afficher l’aide des trois colonnes",dashboardColumnHintsRestoreDone:"Pr\xe9f\xe9rence r\xe9initialis\xe9e. Ouvrez le tableau de bord pour voir le bandeau.",tagsProjectsTabsAriaLabel:"Sections de la colonne \xe9tiquettes",tagsProjectsTabGlobal:"\xc9tiquettes globales",tagsProjectsTabProjects:"Projets et \xe9tiquettes li\xe9es",tagsProjectsTabTemplates:"Mod\xe8les de t\xe2che",tocSubSessionDurationAlert:"Alerte dur\xe9e de session",tocSubDefaultSessionNameTemplate:"Nom de session par d\xe9faut",dashboardSessionDurationAlertHours:"Seuil d’alerte dur\xe9e de session (heures)",dashboardSessionDurationAlertHoursDesc:"Dur\xe9e murale de session (panneau lat\xe9ral du tableau de bord) : d\xe8s qu’elle atteint ce nombre d’heures (ou plus), la valeur s’affiche en rouge avec un clignotement lent. D\xe9faut : 24. Plage : 1–8760.",dashboardTourBlockTitle:"Visite guid\xe9e du tableau de bord",dashboardTourBlockIntro:"Cinq courtes \xe9tapes pr\xe9sentent les sessions, les t\xe2ches, les \xe9tiquettes et les raccourcis. Vous pouvez relancer la visite \xe0 tout moment depuis ici.",dashboardTourReplayLinkLabel:"Ouvrir le tableau de bord et lancer la visite",reportingTourBlockTitle:"Visite guid\xe9e Rapports",reportingTourBlockIntro:"Filtres, indicateurs, graphiques et ventilation par \xe9tiquette ou par projet sur la page Rapports. Vous pouvez relancer cette visite \xe0 tout moment.",reportingTourReplayLinkLabel:"Ouvrir Rapports et lancer la visite",enabled:"Activer la collecte d’activit\xe9",enabledDesc:"Interrupteur global de la collecte d’activit\xe9.",autoStart:"D\xe9marrage automatique",autoStartDesc:"Lancer la collecte au d\xe9marrage du processus Kronosys.",sectionSchedule:"Horaire de travail",scheduleEnabled:"Activer l’horaire automatique",scheduleEnabledDesc:"D\xe9marrer et arr\xeater automatiquement les sessions selon vos heures de travail.",scheduleDays:"Jours actifs",scheduleDaysDesc:"Jours de la semaine o\xf9 le suivi est actif.",scheduleStartTime:"Heure de d\xe9but",scheduleEndTime:"Heure de fin",timePickerPopoverTimeLabel:"Heure (24 h)",timePickerPopoverHourAria:"Heure (24 h)",timePickerPopoverMinuteAria:"Minutes",scheduleCreateDailySession:"Cr\xe9er une session par jour",scheduleCreateDailySessionDesc:"Cr\xe9er automatiquement une nouvelle session au d\xe9marrage de l'horaire pour chaque jour actif.",scheduleTransferTasks:"Transposer les t\xe2ches",scheduleTransferTasksDesc:"Transf\xe9rer automatiquement les t\xe2ches actives de la session pr\xe9c\xe9dente vers la nouvelle session.",schedulePauseTasks:"Mettre les t\xe2ches en pause \xe0 l'arr\xeat",schedulePauseTasksDesc:"Mettre automatiquement en pause les t\xe2ches actives lorsque l'horaire de travail se termine.",sectionPlannedSessions:"Sessions Sp\xe9cifiques Planifi\xe9es",plannedSessionsIntro:"Ajoutez des sessions r\xe9currentes sp\xe9cifiques. Celles-ci ont priorit\xe9 sur l'horaire de travail g\xe9n\xe9ral pendant leur plage horaire.",plannedSessionAdd:"Ajouter une session planifi\xe9e",plannedSessionName:"Nom de la session",plannedSessionTags:"\xc9tiquettes (s\xe9par\xe9es par des virgules)",plannedSessionProject:"Projet",plannedSessionRemove:"Supprimer cette session",showWelcome:"\xc9cran d’accueil",showWelcomeDesc:"Afficher l’accueil tant qu’il n’est pas ferm\xe9.",anonymizePaths:"Anonymiser les chemins",anonymizePathsDesc:"Hacher les chemins de fichiers avant d’\xe9crire les \xe9v\xe9nements.",flushInterval:"Intervalle de vidage (secondes)",flushIntervalDesc:"Fr\xe9quence d’\xe9criture du tampon vers le stockage (5–3600).",heartbeatInterval:"Intervalle des battements (secondes)",heartbeatIntervalDesc:"Temps minimal entre deux \xe9v\xe9nements \xab heartbeat \xbb (30–86400).",maxBuffered:"\xc9v\xe9nements tampon max",maxBufferedDesc:"\xc9v\xe9nements en m\xe9moire avant r\xe9duction (100–100000).",historyPath:"Chemin du stockage d’historique",historyPathDesc:"Vide = r\xe9pertoire de donn\xe9es applicatif par d\xe9faut. ~ d\xe9signe le dossier personnel.",historyPartition:"Partition des fichiers d’historique",historyPartitionDesc:"D\xe9coupage des fichiers de sessions sur le disque.",localPersistenceDriver:"Stockage local des sessions",localPersistenceDriverDesc:"JSON conserve l’historique en fichiers partitionn\xe9s. SQLite enregistre les sessions dans un fichier unique dans le m\xeame dossier ; les JSON existants sont import\xe9s une fois. Le miroir MongoDB (s’il est activ\xe9) reste inchang\xe9. Red\xe9marrez le processus apr\xe8s modification.",persistenceDriverJson:"Fichiers JSON",persistenceDriverSqlite:"SQLite",localPersistenceReloadHint:"Apr\xe8s un changement de moteur, red\xe9marrez le processus Kronosys pour appliquer le r\xe9glage.",partitionDaily:"Quotidien",partitionWeekly:"Hebdomadaire",partitionMonthly:"Mensuel",sessionStartMode:"Au d\xe9marrage du suivi",sessionStartModeDesc:"Reprendre la session pr\xe9c\xe9dente ou toujours repartir \xe0 neuf.",modeContinue:"Poursuivre la session pr\xe9c\xe9dente",modeNew:"Toujours une nouvelle session",exportFormat:"Format d’export par d\xe9faut",exportFormatDesc:"Utilis\xe9 pour les exports d’historique de sessions.",fmtJson:"JSON",fmtCsv:"CSV",fmtJira:"Table Jira",fmtSap:"SAP",csvDelimiter:"S\xe9parateur CSV",csvDelimiterDesc:"Un seul caract\xe8re, ex. , ou ;",autoGitSync:"Sync Git automatique",autoGitSyncDesc:"Optionnel : apr\xe8s chaque sauvegarde locale, valider et pousser le dossier d’historique vers le d\xe9p\xf4t distant. La liste des sessions reste lue depuis les fichiers JSON locaux.",gitRemoteUrl:"URL du d\xe9p\xf4t Git distant",gitRemoteUrlDesc:"Requis si la sync automatique est activ\xe9e.",tocSubGitIdentity:"Auteur Git (tableau de bord)",gitIdentitySubheading:"Auteur Git affich\xe9 dans le tableau de bord",gitIdentityIntro:"Enregistr\xe9 localement avec vos donn\xe9es Kronosys (SQLite). Affich\xe9 sous le titre du tableau de bord \xe0 c\xf4t\xe9 des chemins du workspace — cela n’ex\xe9cute pas git config sur votre machine.",gitIdentityNameLabel:"Nom affich\xe9",gitIdentityNameDesc:"\xc9quivalent \xe0 git config user.name (cr\xe9dit souhait\xe9).",gitIdentityEmailLabel:"Courriel",gitIdentityEmailDesc:"\xc9quivalent \xe0 git config user.email (affichage seulement ici).",gitIdentityLoginLabel:"Identifiant sur la forge",gitIdentityLoginDesc:"Optionnel : compte GitHub, GitLab ou autre h\xe9bergeur (distinct du nom affich\xe9).",gitIdentitySave:"Enregistrer l’auteur Git",gitIdentitySaving:"Enregistrement…",gitIdentitySavedFlash:"Auteur Git enregistr\xe9.",glabRemoteSuggest:"L’outil glab est disponible et un jeton est configur\xe9 : vous pouvez cr\xe9er un d\xe9p\xf4t priv\xe9 nomm\xe9 kronosys-sessions et activer la sync automatique en une \xe9tape.",glabRemoteCreate:"Cr\xe9er le d\xe9p\xf4t GitLab avec glab",glabRemoteCreating:"Cr\xe9ation du d\xe9p\xf4t…",gitlabToken:"Jeton GitLab",gitlabTokenDesc:"Jeton d’acc\xe8s personnel facultatif pour glab (cr\xe9ation de d\xe9p\xf4t priv\xe9, liste des issues). Dans ce tableau de bord, l’enregistrement conserve le jeton dans SQLite local (hors JSON d’\xe9tat) pour que l’import d’issues appelle GitLab ; il remplace GITLAB_TOKEN de l’environnement du serveur une fois enregistr\xe9. Utilisez \xab Tester la connexion \xbb pour activer \xab Importer une issue Git \xbb.",gitlabTokenSave:"Enregistrer le jeton",gitlabTokenClear:"Effacer le jeton stock\xe9",gitlabTokenSaveNeedValue:"Collez d’abord votre jeton dans le champ — enregistrer avec un champ vide ne conserve pas de secret sur ce serveur.",gitlabTokenStoredYes:"Un jeton est enregistr\xe9 dans le coffre de secrets local ; il est prioritaire sur GITLAB_TOKEN pour les appels \xe0 glab.",gitlabTokenFromEnvYes:"Aucun jeton enregistr\xe9 ; glab utilise GITLAB_TOKEN de l’environnement du serveur.",gitlabTokenNone:"Aucun jeton pour l’instant — enregistrez-en un ci-dessous ou d\xe9finissez GITLAB_TOKEN pour le processus du tableau de bord.",gitlabInstanceUrl:"URL de l’instance GitLab",gitlabInstanceUrlDesc:"Origine seulement (sans chemin /api/v4). Laissez vide pour GitLab.com. Pour une instance auto-h\xe9berg\xe9e, indiquez son URL (p. ex. https://gitlab.entreprise.com). Vous pouvez aussi d\xe9finir GITLAB_INSTANCE_URL sur le processus serveur.",gitlabTest401Help:"401 : souvent le jeton ne correspond pas \xe0 cet h\xf4te (mauvaise URL d’instance), ou le jeton est expir\xe9/r\xe9voqu\xe9 ou sans port\xe9e api.",gitlabTestConnection:"Tester la connexion GitLab",gitlabTestConnectionAria:"Tester le jeton d’API GitLab",gitlabTestRunning:"Test GitLab en cours…",gitlabTestOk:"L’API GitLab a r\xe9pondu correctement. L’import d’issues est activ\xe9 dans la colonne des t\xe2ches.",gitlabTestFail:"\xc9chec du test GitLab. V\xe9rifiez le jeton, l’URL d’instance ci-dessus et le r\xe9seau.",gitlabTestNoToken:"Aucun jeton \xe0 tester : collez un jeton dans le champ, enregistrez-le, ou assurez-vous que GITLAB_TOKEN est disponible pour ce processus lorsque vous utilisez le jeton d’environnement.",gitlabTestErrorGeneric:"Impossible d’ex\xe9cuter le test de connexion GitLab.",gitlabApiVerifiedYes:"API GitLab : v\xe9rifi\xe9e — l’import d’issues dans les t\xe2ches est disponible.",gitlabApiVerifiedNo:"API GitLab : non v\xe9rifi\xe9e — lancez \xab Tester la connexion \xbb pour activer l’import d’issues dans les t\xe2ches.",gitlabTestPasteStoredHint:"Pour tester un jeton d\xe9j\xe0 enregistr\xe9 localement, collez-le temporairement dans le champ ci-dessus (ce tableau de bord ne peut pas relire le secret depuis le stockage).",historyLocalFirstHint:"L’historique des sessions est lu depuis les fichiers JSON locaux ou SQLite (voir Stockage local des sessions). La sync Git automatique pousse le dossier apr\xe8s les sauvegardes si elle est activ\xe9e. MongoDB n’est mis \xe0 jour que lorsque l’envoi est d\xe9clench\xe9 depuis le tableau de bord ou via Resynchroniser dans les param\xe8tres.",mongoEnabled:"Int\xe9gration MongoDB",mongoEnabledDesc:"Si activ\xe9, vous pouvez envoyer chaque session vers MongoDB depuis le tableau de bord (et tout resynchroniser dans les param\xe8tres). Rien n’est envoy\xe9 automatiquement \xe0 chaque sauvegarde locale. Le tableau de bord lit toujours le stockage local (JSON ou SQLite).",mongoDatabase:"Base MongoDB",mongoDatabaseDesc:"Nom de la base (lettres, chiffres, tiret, soulign\xe9).",mongoCollection:"Collection MongoDB",mongoCollectionDesc:"Nom de la collection (un document par session).",sectionMongoConnection:"Connexion MongoDB",mongoConnectionIntro:"Construire mongodb://utilisateur:motdepasse@h\xf4te:port/?authSource=… avec les champs ci-dessous, ou d\xe9finir une URI compl\xe8te en mode avanc\xe9. Une URI compl\xe8te enregistr\xe9e est prioritaire. Le bouton Enregistrer en haut applique aussi h\xf4te/port/utilisateur/authSource et enregistre le mot de passe ou l’URI manuelle si les champs sont remplis.",mongoHost:"H\xf4te",mongoHostDesc:"Nom d’h\xf4te ou adresse IP (ex. 127.0.0.1).",mongoPort:"Port",mongoPortDesc:"Port TCP (d\xe9faut 27017).",mongoUser:"Utilisateur",mongoUserDesc:"Vide = sans authentification. Si renseign\xe9, un mot de passe est requis (stock\xe9 dans le coffre de secrets).",mongoPassword:"Mot de passe",mongoPasswordDesc:"Stock\xe9 uniquement dans le coffre de secrets local. Utilisez Enregistrer le mot de passe ou le bouton Enregistrer en haut si le champ n’est pas vide.",mongoPasswordSave:"Enregistrer le mot de passe",mongoPasswordClear:"Effacer le mot de passe stock\xe9",mongoPasswordConfiguredYes:"Un mot de passe est enregistr\xe9.",mongoPasswordConfiguredNo:"Aucun mot de passe enregistr\xe9.",mongoAuthSource:"authSource",mongoAuthSourceDesc:"Base d’authentification (souvent admin).",mongoManualUri:"URI compl\xe8te (avanc\xe9)",mongoManualUriDesc:"Si d\xe9finie, cette URI remplace h\xf4te / utilisateur / mot de passe. Stock\xe9e dans le coffre de secrets. Effacer pour revenir \xe0 la connexion construite.",mongoUri:"URI de connexion",mongoUriDesc:"mongodb:// ou mongodb+srv:// — le bouton Enregistrer en haut enregistre aussi cette URI si le champ n’est pas vide.",mongoUriSave:"Enregistrer l’URI",mongoUriClear:"Effacer l’URI stock\xe9e",mongoUriConfiguredYes:"Une URI compl\xe8te est enregistr\xe9e (mode avanc\xe9).",mongoUriConfiguredNo:"Aucune URI compl\xe8te ; la connexion construite est utilis\xe9e si possible.",mongoRemoteStatus:"\xc9tat MongoDB",mongoStatusConnected:"Connect\xe9",mongoStatusFailed:"\xc9chec ou configuration incompl\xe8te",mongoStatusPending:"V\xe9rification…",mongoConnectionResolvableYes:"Param\xe8tres de connexion suffisants.",mongoConnectionResolvableNo:"Incomplet (ex. mot de passe si l’utilisateur est renseign\xe9).",mongoTestConnection:"Tester la connexion",mongoTestConnectionAria:"Tester la connexion MongoDB",mongoTestRunning:"Test de connexion en cours…",mongoTestOk:"Test de connexion r\xe9ussi (ping sur la base configur\xe9e).",mongoTestFail:"\xc9chec du test de connexion. V\xe9rifiez l’h\xf4te, le port, les identifiants, l’URI et le r\xe9seau.",mongoTestDisabled:"Activez le miroir MongoDB ci-dessus pour lancer un test de connexion.",mongoTestErrorGeneric:"Impossible d’ex\xe9cuter le test de connexion via l’API locale.",mongoTestUsesSavedConfigHint:"L’h\xf4te, le port, la base, la collection et l’utilisateur ci-dessous sont pris en compte pour le test m\xeame sans cliquer sur Enregistrer. Une URI compl\xe8te ou un mot de passe enregistr\xe9 (boutons d\xe9di\xe9s) provient toujours du coffre de secrets local.",mongoSyncSectionTitle:"Fichiers locaux et MongoDB",mongoResyncButton:"Resynchroniser toutes les sessions vers MongoDB",mongoResyncAriaLabel:"Resynchroniser toutes les sessions locales vers le miroir MongoDB",mongoResyncConfirm:"Enregistrer chaque session locale dans MongoDB (upsert) ? Cela peut prendre du temps s’il y a beaucoup de sessions.",mongoResyncRunning:"Resynchronisation…",mongoResyncDone:"Resynchronisation termin\xe9e : {upserted} sessions \xe9crites, {failed} \xe9checs.",mongoResyncHint:"\xc9crit toutes les sessions locales dans MongoDB et met \xe0 jour les m\xe9tadonn\xe9es d’envoi dans les JSON. Les documents suppl\xe9mentaires d\xe9j\xe0 pr\xe9sents dans MongoDB ne sont pas supprim\xe9s.",mongoResyncDisabled:"Activez le miroir MongoDB dans les param\xe8tres avant de resynchroniser.",mongoResyncUnsupported:"Ce stockage ne prend pas en charge la resynchronisation MongoDB.",mongoResyncErrorGeneric:"Impossible d’ex\xe9cuter la resynchronisation.",mongoResyncErrorDetail:"\xc9chec de la resynchronisation : {detail}",workspaceFoldersLabel:"Racines du workspace",workspaceFoldersEmpty:"Aucune racine de workspace n’est configur\xe9e pour ce tableau de bord.",localApiPort:"Port de l’API locale",localApiPortDesc:"API HTTP loopback pour ce tableau de bord (127.0.0.1 uniquement).",dashboardWebUrl:"URL du tableau de bord (affichage)",dashboardWebUrlDesc:"URL sugg\xe9r\xe9e pour ouvrir le tableau de bord dans un navigateur (signets, etc.). Utilisez une URL loopback (localhost, 127.0.0.1, [::1]) ou un nom d’h\xf4te dans /etc/hosts r\xe9solu vers loopback (ex. kronosys).",dashboardDisplayTimeZone:"Fuseau horaire d’affichage",dashboardDisplayTimeZoneDesc:"Sert aux dates des sessions sur le tableau de bord, aux horodatages des t\xe2ches et au regroupement par jour dans les rapports. Choisissez une suggestion ou saisissez un fuseau IANA (ex. Europe/Brussels). Par d\xe9faut : heure de l’Est (America/Toronto).",dashboardClockFormat:"Format de l’horloge",dashboardClockFormatDesc:"Affichage des heures sur le tableau de bord (d\xe9but et fin des t\xe2ches, aper\xe7u des dates de t\xe2ches pass\xe9es) et dans les aper\xe7us des s\xe9lecteurs d’heure du calendrier. Les dates ne changent pas.",dashboardClock24hOption:"24 heures",dashboardClock12hOption:"12 heures (AM/PM)",dashboardCalendarWeekStartsOn:"La semaine commence",dashboardCalendarWeekStartsOnDesc:"Premi\xe8re colonne des calendriers (s\xe9lecteurs de date du tableau de bord, sessions pass\xe9es) et grilles hebdomadaires des rapports. Le pr\xe9r\xe9glage de plage \xab Semaine \xbb reste lundi–dimanche.",calendarWeekStartsSunday:"Dimanche",calendarWeekStartsMonday:"Lundi",calendarWeekStartsSaturday:"Samedi",dashboardLightThemeVariant:"Teinte du th\xe8me clair",dashboardLightThemeVariantDesc:"S’applique lorsque le tableau de bord est en mode clair (ic\xf4ne lune dans la barre d’outils). Le mode sombre n’est pas modifi\xe9. Le choix est enregistr\xe9 dans ce navigateur et dans les param\xe8tres locaux.",dashboardLightThemeWarm:"Chaud",dashboardLightThemeSoft:"Doux",dashboardLightThemeContrast:"Contraste",dashboardSemanticChipAccessibleMode:"Ne pas distinguer par la couleur seule",dashboardSemanticChipAccessibleModeDesc:"Si activ\xe9, les pastilles d'\xe9tiquette, de projet travail et de projet personnel affichent les pr\xe9fixes #, @ et ! ainsi que des bordures distinctes (pleine, double, pointill\xe9e) en compl\xe9ment de leurs couleurs — tableau de bord, filtres des rapports et partout o\xf9 ces pastilles apparaissent. Enregistr\xe9 dans ce navigateur et dans les param\xe8tres locaux.",dashboardBaseDailyHours:"Heures de base par jour",dashboardBaseDailyHoursDesc:"Heures de r\xe9f\xe9rence par jour pour le suivi d'\xe9cart dans les rapports d'allocation.",dashboardBaseDailyToleranceMinutes:"Tol\xe9rance (minutes)",dashboardBaseDailyToleranceMinutesDesc:"\xc9cart autoris\xe9 par rapport aux heures de base avant surbrillance (d\xe9faut : 10 min).",dashboardDefaultSessionNameTemplate:"Gabarit du nom des nouvelles sessions",dashboardDefaultSessionNameTemplateDesc:"Renseign\xe9 lors du d\xe9marrage d’une nouvelle session active (commande \xab Nouvelle session \xbb ou session implicite cr\xe9\xe9e par la premi\xe8re t\xe2che). Laissez vide pour garder le champ vide. S\xe9quences : `%%` pour un pourcentage litt\xe9ral ; `%UUID` pour l’identifiant complet de session ; `%Y` `%y` `%m` `%d` `%H` `%M` `%S` ainsi que `%F` (\xe9quivalent `%Y-%m-%d`) suivent la s\xe9mantique de `strftime()` POSIX (r\xe9f\xe9rence IEEE / Open Group : https://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html). Attention : `%m` est le mois ; `%M` repr\xe9sente les minutes. Les valeurs utilisent le fuseau d’affichage choisi ci-dessus (coh\xe9rent avec les regroupements quotidiens des rapports).",invalidDashboardTimeZone:"Fuseau horaire non reconnu. Saisissez un nom IANA valide (ex. America/Toronto).",dialogOkBtn:"OK",dialogCancelBtn:"Annuler",dialogConfirmBtn:"Confirmer",scrollToTopAria:"Retour en haut de la page",licensesPageLink:"Licences et logiciels tiers",sectionHolidayCalendar:"Calendrier des jours f\xe9ri\xe9s",holidayCalendarProvince:"Province",holidayCalendarProvinceDesc:"S\xe9lectionnez une province pour ins\xe9rer automatiquement les jours f\xe9ri\xe9s dans le calendrier des rapports.",holidayCalendarProvinceNone:"Aucun",holidayCalendarApplyBtn:"Appliquer les jours f\xe9ri\xe9s",holidayCalendarApplied:"Les jours f\xe9ri\xe9s ont \xe9t\xe9 appliqu\xe9s au calendrier des rapports.",holidayCalendarHint:"Les jours f\xe9ri\xe9s sont g\xe9n\xe9r\xe9s pour l'ann\xe9e courante et les ann\xe9es \xe0 venir. Vous pouvez ajuster ou d\xe9placer chaque jour f\xe9ri\xe9 directement depuis la page des rapports \xe0 l'aide du s\xe9lecteur de marqueur de journ\xe9e."};function f(a){return"fr"===a?e:d}},93356:(a,b,c)=>{"use strict";c.d(b,{KronosysPayloadProvider:()=>e});var d=c(77943);let e=(0,d.registerClientReference)(function(){throw Error("Attempted to call KronosysPayloadProvider() from the server but KronosysPayloadProvider is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/KronosysPayloadProvider.tsx","KronosysPayloadProvider");(0,d.registerClientReference)(function(){throw Error("Attempted to call useKronosysPayload() from the server but useKronosysPayload is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"/home/feelx/code/projects/business/nightkatana/project-kronosys/components/KronosysPayloadProvider.tsx","useKronosysPayload")},96487:()=>{},98257:(a,b,c)=>{"use strict";c.d(b,{DataEnvironmentSwitchProvider:()=>r,l:()=>q});var d=c(48249),e=c(67484),f=c(24682),g=c(11001);function h({open:a,dt:b,pending:c,onCancel:f,onChoose:i}){let j=(0,e.useId)(),k=(0,e.useId)(),{shouldRender:l,visible:m}=function(a){let[b,c]=(0,e.useState)(a),[d,f]=(0,e.useState)(a);return{shouldRender:b,visible:d}}(a);if(!l)return null;let n="w-full rounded-lg px-4 py-2.5 text-sm font-medium transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 disabled:opacity-40";return(0,d.jsx)("div",{className:`fixed inset-0 z-[100] flex items-center justify-center bg-black/60 p-4 transition-opacity duration-150 ease-out motion-reduce:transition-none ${m?"opacity-100":"opacity-0"}`,role:"dialog","aria-modal":"true","aria-labelledby":j,"aria-describedby":k,children:(0,d.jsxs)("div",{className:`max-h-[90vh] w-full max-w-md overflow-y-auto rounded-xl border border-zinc-200 bg-white p-5 shadow-xl transition-all duration-150 ease-out motion-reduce:transition-none dark:border-zinc-700 dark:bg-zinc-900 ${m?"translate-y-0 scale-100 opacity-100":"translate-y-1 scale-[0.985] opacity-0"}`,children:[(0,d.jsx)("h2",{id:j,className:"text-lg font-semibold text-zinc-900 dark:text-zinc-100",children:b.dataEnvironmentQaSeedTitle}),(0,d.jsx)("p",{id:k,className:"mt-3 whitespace-pre-wrap text-sm leading-relaxed text-zinc-600 dark:text-zinc-300",children:b.dataEnvironmentQaSeedMessage}),(0,d.jsxs)("div",{className:"mt-5 flex flex-col gap-2",children:[(0,d.jsx)("button",{type:"button",className:`${n} ${g.Sx}`,disabled:c,onClick:()=>void i("copy_production"),children:b.dataEnvironmentQaSeedCopyBtn}),(0,d.jsx)("button",{type:"button",className:`${n} border border-zinc-300 bg-zinc-100 text-zinc-900 hover:bg-zinc-200 dark:border-zinc-600 dark:bg-zinc-800 dark:text-zinc-100 dark:hover:bg-zinc-700`,disabled:c,onClick:()=>void i("empty"),children:b.dataEnvironmentQaSeedEmptyBtn}),(0,d.jsx)("button",{type:"button",className:`${n} text-zinc-600 hover:bg-zinc-100 dark:text-zinc-400 dark:hover:bg-zinc-800`,disabled:c,onClick:f,children:b.dialogCancelBtn})]})]})})}var i=c(88987);function j({open:a,target:b,dt:c,pending:e,onCancel:f,onConfirm:g}){if(!b)return null;let h="qa"===b?c.dataEnvironmentNavActiveQa:c.dataEnvironmentNavActiveProd,k=c.dataEnvironmentSwitchConfirmMessage.replace("{env}",h);return(0,d.jsx)(i.qR,{open:a,title:c.dataEnvironmentSwitchConfirmTitle,message:k,cancelLabel:c.dialogCancelBtn,confirmLabel:c.dataEnvironmentSwitchConfirmBtn,confirmVariant:"neutral",pending:e,onCancel:f,onConfirm:g})}function k({variant:a,dt:b}){let c="switching"===a?b.dataEnvironmentSwitchLockBackdropTitleSwitching:b.dataEnvironmentSwitchLockBackdropTitleLocked,e="switching"===a?b.dataEnvironmentSwitchLockBackdropDetailSwitching:b.dataEnvironmentSwitchLockBackdropDetailLocked,f="switching"===a?b.dataEnvironmentSwitchLockBackdropAriaSwitching:b.dataEnvironmentSwitchLockBackdropAriaLocked;return(0,d.jsxs)("div",{className:"fixed inset-0 z-[60] flex items-center justify-center p-5 sm:p-8",role:"alertdialog","aria-modal":"true","aria-live":"assertive","aria-label":f,children:[(0,d.jsx)("div",{className:"absolute inset-0 bg-zinc-950/55 dark:bg-black/65","aria-hidden":!0}),(0,d.jsxs)("div",{className:"relative z-10 max-w-md rounded-2xl border border-violet-500/45 bg-[#0f0a14]/95 px-5 py-5 text-center shadow-2xl backdrop-blur-[2px] dark:border-violet-600/40 sm:px-7 sm:py-6",children:[(0,d.jsx)("p",{className:"text-xs font-semibold uppercase tracking-wide text-violet-200/95",children:c}),(0,d.jsx)("p",{className:"mt-2.5 text-sm leading-snug text-violet-100/92",children:e})]})]})}var l=c(74464),m=c(59899),n=c(55017),o=c(23912);let p=(0,e.createContext)(null);function q(){let a=(0,e.useContext)(p);if(!a)throw Error("useDataEnvironmentSwitch must be used within DataEnvironmentSwitchProvider");return a}function r({children:a}){let b,{payload:c,refresh:g}=(0,f.y)(),{pushToast:i}=(0,l.f)(),q="fr"===(b=c?.current?.language)||"en"===b?b:"en"===n.h.getState().lang?"en":"fr",s=(0,m.z)(q),t=c?.dataEnvironmentRuntime,[u,v]=(0,e.useState)(null),[w,x]=(0,e.useState)(null),[y,z]=(0,e.useState)(null),[A,B]=(0,e.useState)(!1),C=t?.dualDataEnvironmentEnabled===!0,D=t?.traceDataDirOverride===!0,E=C&&!D&&t?.dataDirectoryResolutionMismatch===!0,F=A||E,G=(0,e.useCallback)(()=>{A||(v(null),x(null),z(null))},[A]),H=(0,e.useCallback)(a=>{if(A||E||!C||D)return;let b=t?.effectiveActiveDataEnvironment??"production",c=t?.dataDirectoryResolutionMismatch===!0;(a!==b||c)&&(v(a),z(null),x("qa"===a&&t?.qaVaultUninitialized===!0?"qaSeed":"confirm"))},[C,E,A,t,D]),I=(0,e.useCallback)(a=>{z(a),x("confirm")},[]),J=(0,e.useCallback)(async()=>{if(u&&!A&&!E){if("qa"===u&&t?.qaVaultUninitialized===!0&&!y){i(s.dataEnvironmentQaSeedRequiredError),x("qaSeed");return}B(!0);try{let b={type:"switchDataEnvironment",target:u};"qa"===u&&y&&(b.qaSeed=y);let c=await (0,o.$)(b);if(!c.ok||c.result?.dataEnvironmentError){var a;i((a=c.result?.dataEnvironmentError,"qa_seed_required"===a?s.dataEnvironmentQaSeedRequiredError:"production_missing"===a?s.dataEnvironmentQaSeedProductionMissingError:s.dataEnvironmentSwitchError)),c.result?.dataEnvironmentError==="qa_seed_required"&&x("qaSeed");return}if(v(null),x(null),z(null),await g({routerInvalidate:!0}),c.result?.dataEnvironmentReloaded===!0){let a="qa"===u?s.dataEnvironmentNavQaShort:s.dataEnvironmentNavProdShort;i(s.dataEnvironmentSwitchSuccessHint.replace("{env}",a))}else i(s.dataEnvironmentSwitchRestartHint)}catch{i(s.dataEnvironmentSwitchError)}finally{B(!1)}}},[s,E,A,y,u,i,g,t?.qaVaultUninitialized]),K=(0,e.useMemo)(()=>({requestSwitch:H,isSwitching:A,isLockedUntilRestart:E,isInteractionBlocked:F}),[F,E,A,H]),L=A&&null===w,M=E&&!A;return(0,d.jsxs)(p.Provider,{value:K,children:[a,(0,d.jsx)(h,{open:"qaSeed"===w&&"qa"===u,dt:s,pending:A,onCancel:G,onChoose:I}),(0,d.jsx)(j,{open:"confirm"===w&&null!==u,target:u,dt:s,pending:A,onCancel:G,onConfirm:()=>void J()}),L?(0,d.jsx)(k,{variant:"switching",dt:s}):null,M?(0,d.jsx)(k,{variant:"restartRequired",dt:s}):null]})}},98782:(a,b,c)=>{Promise.resolve().then(c.t.bind(c,95547,23))}};
|