This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Journal S·P·É is a French-language CBT (cognitive-behavioral therapy) journaling app — Situation, Pensée (thought), Émotion. It is a single self-contained HTML file (journal-spe_1.html) with no build step, no dependencies, and no server. Open the file directly in a browser to run it.
Licensed under GPL v3.
Everything lives in journal-spe_1.html: CSS in <style>, HTML structure, and all JavaScript inline in <script>. There are no external JS dependencies — only two Google Fonts are loaded remotely.
A single global object S holds all runtime state:
S.view— current tab ('list'or'form')S.entries— array of journal entries, persisted tolocalStorageunder the key'spe'S.form— the in-progress entry object{ eventDate, situation, pensee, emotion, intensite, note }S.expanded/S.confirmDel/S.confirmClear— UI state for the list viewS.pickerMode—'vertical'(accordion) or'wheel'(SVG)S.pickerOpenSub— which secondary accordion is explicitly expanded (decoupled fromS.form.emotion)
EMOTIONS is a hardcoded array of 8 primary emotions (Plutchik's wheel), each with 3 secondary groups, each with 3 tertiary items — 72 leaf emotions total. Colors are defined per primary emotion and lightened algorithmically for sub-levels.
The app uses innerHTML string-based rendering — no virtual DOM, no framework. The two main render functions are:
renderList()— builds the entries list and import/export buttonsrenderForm()— builds the new-entry form including the emotion picker
snapForm() reads current DOM values back into S.form before any state change that triggers a re-render (picker interactions, tab switches).
Two modes toggled by S.pickerMode:
- Vertical (
buildPicker()): accordion-style nested buttons. Emotion selection and accordion expansion are intentionally decoupled —S.form.emotiontracks the selected emotion at any level (primary, secondary, or tertiary);S.pickerOpenSubtracks which secondary accordion is open for browsing. First click on a secondary selects it without expanding; second click expands tertiary items as optional refinements. - Wheel (
buildWheel()): procedurally generated SVG using arc path math. The wheel is rebuilt as a string on every selection change.
findColor(label) resolves any emotion label (primary, secondary, or tertiary) to its primary hex color — used throughout for consistent theming.
save()/load()— read/writeS.entriesas JSON inlocalStorage- JSON export: uses Web Share API (mobile) with fallback to
<a download>(desktop) - Import: merges by
id, deduplicating against existing entries, then sorts by recorded date - Word export (
exportDocx()): generates a.docxfile in-browser using a self-contained pure-JS ZIP writer (_zip+_crc32) and OOXML. Produces a landscape table matching the CBT grid template — columns: Situation, Pensées automatiques, Émotions (X/10), Comportements (mapped from thenotefield). No external library required._xe(s)is the XML-safe escape helper (distinct fromehtmlwhich is for HTML).
No build tooling. Edit journal-spe_1.html directly and open in a browser. Use browser DevTools for debugging.
To validate HTML/JS syntax locally, any standard linter works (e.g. npx htmlhint journal-spe_1.html or browser console errors on load).
- All user-facing strings are in French.
- HTML output is sanitized through
ehtml(s)which escapes& < > "— always use it when interpolating user data or emotion names into innerHTML strings. - Entry IDs are
Date.now().toString()— millisecond timestamps as strings. nowLocal()produces adatetime-local-compatible string adjusted for the user's timezone offset.