Commit Graph

28357 Commits

Author SHA1 Message Date
claude 685a7ffca1 fix: language picker links, dropdown position, and editor layout defaults
Build and Deploy Verso / deploy (push) Successful in 14m34s
Language picker:
- Add fallback href in Pug so language links navigate even if JS fails
- Anchor dropdown to right edge (right:0) so it stays on-screen when
  the picker is near the right side of the footer on mobile

Editor layout:
- Read stored pdfLayout from localStorage on init so the last-used
  layout is remembered across sessions
- Default to verticalSplit (top/bottom) on mobile when no preference
  is stored, so the editor opens in a sensible layout on phones

Translations:
- Add top_bottom_split_view key to all 16 locales that were missing it

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 14:40:02 +00:00
claude 84d1efc271 fix: use <details>/<summary> for Pug language picker to get native toggle
Build and Deploy Verso / deploy (push) Successful in 14m10s
The manual JS click-handler approach (tried with stopPropagation,
containment check, and mousedown variants) never worked reliably on
login/password/settings pages. The browser's native <details>/<summary>
toggle behaviour requires no JavaScript and is immune to Bootstrap JS or
React event delegation interference.

The inline script now only builds the return_to hrefs and handles
outside-click-to-close (setting details.open=false). The CSS gains a
.language-picker-details rule that sets position:relative so the
absolutely-positioned dropdown-menu is positioned correctly, and
details[open] .dropdown-menu { display: block } to show the menu.

The #language-picker-toggle id remains on the <summary> so the existing
CSS (cursor, text-decoration, material-symbols alignment) continues to
apply. The React LanguagePicker is unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 12:55:39 +00:00
claude b461343b23 fix: project list phone layout and language picker
Build and Deploy Verso / deploy (push) Successful in 14m3s
- Search bar overflow: min-width:0 on form prevents input min-content
  from overflowing flex container on narrow screens
- Remove duplicate New Project button from header row (tableTopArea
  already provides it for mobile)
- Simplify tableTopArea: single button+search layout regardless of
  isLibraryEnabled flag
- 2-line project rows on mobile: merge dash-cell-date-owner +
  dash-cell-tag into a single dash-cell-meta so date/owner/tags flow
  inline on line 2 below the project name
- Footer mobile: hide language-picker-text on mobile (icon only) to
  prevent 3rd line in 2-row footer
- Language picker: use mousedown instead of click for outside-close
  handler — click bubbling is unreliable on iOS for non-interactive
  elements; mousedown fires for all taps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 11:47:32 +00:00
claude be353d53bd Center footer items on mobile for harmonious two-line layout
Build and Deploy Verso / deploy (push) Successful in 9m44s
Both ul.site-footer-items rows are now justify-content: center on small
screens, so the copyright/language row and the licence/source row are
symmetrically aligned instead of left-justified.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 11:05:22 +00:00
claude 0a5bd4e47d Fix mobile layout key, language picker close handler, and presentation download
Build and Deploy Verso / deploy (push) Has been cancelled
- Mobile vertical layout: add key= based on direction so react-resizable-panels
  remounts cleanly when switching between horizontal and vertical; also use
  isVertical (not just pdfLayout) for the autoSaveId to avoid restoring a
  mismatched layout from localStorage
- Language picker: replace stopPropagation pattern with a containment check on
  the document click handler — more robust on React pages where Bootstrap JS or
  React's event delegation can interfere with stopPropagation
- Presentation download dropdown: use popperConfig strategy:'fixed' so the menu
  escapes overflow:hidden table cells; remove forced drop='up' and let Popper
  choose; defer URL.revokeObjectURL by 10 s to give the browser time to start
  the download before the blob URL is released

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 11:01:15 +00:00
claude 11227d59e3 Editor mobile ergonomics: vertical split layout on phones and as desktop option
Build and Deploy Verso / deploy (push) Successful in 14m3s
On mobile (< 768 px) the existing side-by-side layout automatically switches
to a vertical stack (editor on top, PDF/presentation on bottom) without
changing the stored layout preference.

A new "Top / bottom split" option is added to the layout menu so desktop
users can choose the same vertical split explicitly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 09:25:15 +00:00
claude 0f585ea5bb Fix: use picture_as_pdf icon for presentation download toggle
Using the generic 'download' icon duplicated the ZIP button icon,
giving two identical icons side by side. Switch to picture_as_pdf to
match the previous compile-and-download button's appearance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 08:51:29 +00:00
claude a6ea291ea8 Add PDF/HTML download dropdown for Quarto Slides in project list
Quarto Slides (RevealJS) projects compile to output.html, not output.pdf,
so the existing "Download PDF" button was meaningless for them. Replace it
with a two-option dropdown matching the editor's PdfHybridDownloadButton:

- Desktop (ActionsCell): icon button opens a dropup with
  "Download standalone HTML" and "Download PDF slides"
- Mobile (ActionsDropdown): two separate dropdown items with the same
  choices and per-format spinner while the export is in progress

Both use the same /project/:id/presentation-export/:format endpoint and
show a loading modal (with error reporting) during the server-side render,
exactly as the editor toolbar does.

Non-RevealJS projects continue to show the compile-and-download-PDF button
unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 08:48:03 +00:00
claude 703f4d6ee2 Replace native <select> language picker with styled dropdown
Build and Deploy Verso / deploy (push) Successful in 13m43s
The native <select> looked like a form control ("cheap"). Replace it with
the same HTML+CSS pattern as the React LanguagePicker: btn-inline-link
toggle with a translate icon, Bootstrap dropdown-menu for the list, active
item highlighted in green.

A tiny self-contained inline script handles the toggle since Bootstrap JS
is not loaded on React-layout pages. It builds the return_to URL from
window.location.pathname at click time (same as the old select approach).

Added top: auto / bottom: 100% to .language-picker .dropdown-menu so the
list always opens upward regardless of whether Popper.js is present.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 08:29:10 +00:00
claude 86a902c197 Improve mobile ergonomics for footer and project list
Footer (both React and Pug):
- Below md: switch to flex-wrap so items wrap naturally instead of
  overflowing; reset line-height from the fixed 49px to normal; add
  row-gap so wrapped rows aren't crammed together
- Add footer-sep class to pipe separator <li>s so they can be hidden
  on small screens (wrapping mid-separator looks wrong)
- Change col-lg-3 text-end → text-lg-end so the right column (licence,
  source code) aligns left when it stacks full-width below lg

Project list:
- Show NewProjectButton on mobile in the header row (the sidebar that
  holds the button is already hidden below md via d-none d-md-flex,
  leaving users with no way to create projects on their phone)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 08:22:57 +00:00
claude 36f5e9fb06 Remove rounded top-left corner from project list content area
The content panel had border-top-left-radius: var(--border-radius-large)
at md+ breakpoint, left over from the old Overleaf theme. Everything else
is square now so this corner stood out. Removing it makes the edge flush.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 07:58:33 +00:00
claude 2b9ebe5522 Replace Overleaf O with Verso icon mark in editor state favicons
Build and Deploy Verso / deploy (push) Successful in 10m0s
favicon-compiled.svg, favicon-compiling.svg, favicon-error.svg all used
the Overleaf O logo as the base. Replace with the Verso icon mark (dark
background, four colored circles, white V polygon, clipped to a circle)
while keeping the existing status badge icons (✓ / ↻ / ✗) unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-16 07:54:33 +00:00
claude e4f1eead25 Branding polish: Verso favicons, OG image, and meta tag fixes
Build and Deploy Verso / deploy (push) Successful in 10m24s
Replace Overleaf favicons with Verso icon mark across all sizes (16x16,
32x32, 180x180 apple-touch, 192x192/512x512 android-chrome, ICO). Add
OG social preview image (1200x630) for Discord/Twitter link cards.

- New favicon.svg: Verso icon mark with four overlapping circles and V
- mask-favicon.svg: monochrome V polygon (was Overleaf chevron)
- og-image.png: 1200x630 social card with icon mark and "Verso" wordmark
- web.sitemanifest.json: rename "Overleaf" → "Verso", theme_color updated
- _metadata.pug: add og:url tag, fix og:type missing content= attribute,
  point CE default OG/twitter images to og-image.png instead of apple-touch-icon.png

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 20:19:01 +00:00
claude 323d74cc66 fix: replace Pug language picker dropdown with native select
Build and Deploy Verso / deploy (push) Successful in 14m31s
The old dropdown relied on data-bs-toggle and AngularJS directives,
neither of which are loaded on React-layout pages (layout-react.pug
intentionally excludes Bootstrap JS). The toggle button was inert on
pages like /user/settings.

Replace with a plain <select> that navigates via window.location.href
onchange — works without any framework on all page types.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 18:46:03 +00:00
claude 81c1fc92d1 fix: remove data-bs-toggle from LanguagePicker dropdown toggle
Build and Deploy Verso / deploy (push) Successful in 10m8s
Bootstrap vanilla JS and react-bootstrap were both handling the dropdown,
causing the toggle to be unresponsive. react-bootstrap manages its own
state and does not need this attribute.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 14:15:36 +00:00
claude 319ccc32ee feat: add language picker to logged-in footer and editor settings
Build and Deploy Verso / deploy (push) Successful in 18m46s
- Rewrites LanguagePicker to use availableLanguages from ol-footer meta
  instead of subdomainLang (which is always empty in single-domain setup)
- Passes availableLanguages through layout-react.pug → ol-footer meta so
  React footer picks it up
- Adds InterfaceLanguageSetting component to the editor settings modal
  ("Spelling and language" tab) for use when no footer is present
- Adds interface_language key to all five locale files (en/fr/de/es/it)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 12:22:55 +00:00
claude 1a0197812d feat: cookie+DB language preference, eliminating subdomain requirement
Build and Deploy Verso / deploy (push) Successful in 14m53s
Users can now select their UI language directly without relying on
subdomain routing (fr.verso.alocoq.fr etc.).

Resolution order: (1) verso-lang cookie, (2) subdomain host header,
(3) OVERLEAF_SITE_LANGUAGE default — fully backward compatible.

Changes:
- Translations.mjs: read verso-lang cookie in middleware; include all
  bundled locale files in availableLanguageCodes regardless of subdomain
  config so every loaded locale appears in the picker
- User.mjs: add languageCode field to persist preference per user
- UserController.mjs: setLanguage handler — sets cookie (1 year) and
  writes languageCode to DB when called by a logged-in user
- AuthenticationController.mjs: on login, sync DB languageCode to cookie
  so preference follows the user to any new browser/device after login
- ExpressLocals.mjs: expose availableLanguages to all Pug templates
- router.mjs: GET /set-language?lng=<code> (anonymous + logged-in),
  POST /user/language (logged-in, REST-style)
- language-picker.pug: replace subdomain href links with /set-language
  redirect links; iterate availableLanguages instead of subdomainLang
- thin-footer.pug: show picker whenever availableLanguages.length > 1,
  not only when multiple subdomains are configured

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 11:44:56 +00:00
claude 589c60a325 i18n(de/es/it): correct machine-translation errors in German, Spanish, Italian
Build and Deploy Verso / deploy (push) Successful in 14m22s
German (43 fixes): table→Tabelle (was Tisch/furniture), figure→Abbildung (was Figur),
no_borders→Keine Rahmen (was Grenzen/national borders), run→Ausführen (was Lauf),
right→Rechts (was Richtig/correct), unpausing was "Ununterbrochen" (uninterrupted),
unlink_provider said "verknüpfen" (link) instead of "trennen" (unlink),
unpause_subscription said "pausieren" (pause) instead of "fortsetzen",
zotero_reference_loading_error mentioned Mendeley, light_themes→Helle Themen,
review_panel→Überprüfungsbereich (was Gremium/committee), x_price_per_month untranslated,
Writefull/Papers/booktabs/Labs product names preserved

Spanish (58 fixes): no_borders→Sin bordes (was fronteras/national borders),
invite_resent→Invitación reenviada (was "Invita a resentirse"),
trash→Papelera, trashed→En papelera (was "Destrozado"/destroyed),
plan→Plan (was Planificar/verb), premium→Premium (was prima/bonus),
disabled→Desactivado (was Discapacitado/handicapped), breadcrumbs navigation fixed,
cookie_banner→Banner de cookies, search_match_case fixed, Writefull/Papers/Dropbox/Git preserved

Italian (85 fixes): no_borders→Nessun bordo (was confini/national borders),
right→Destra (was Giusto/correct), run→Esegui (was Corri/run physically),
standard→Standard (was Norma), premium→Premium (was Premio/prize),
characters→Caratteri (was Personaggi), editor→Editor (was Editore/publisher) throughout,
light_themes→Temi chiari (was leggeri/lightweight), unpausing→Riattivazione,
back_to_x buttons fixed from "Torniamo" (we return) to imperative "Torna",
~20 infinitives corrected to imperatives for button labels,
booktabs/Writefull/Papers product names preserved, triple-r typo fixed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 11:30:04 +00:00
claude 38144b1033 i18n(fr): correct 41 machine-translation errors in French locale
Fix a batch of severe mistranslations produced by automated translation:
- typographic terms: bold→Gras (was "Audacieux"), figure→Figure (was "Chiffre"),
  characters→Caractères (was "Personnages"), borders→bordures (was "frontières")
- UI action labels: apply→Appliquer (was "Postuler"/job application),
  run→Exécuter (was "Courir"/to run physically), chat→Chat (was "Discuter"/verb),
  code→Code (was "Coder"/verb), more_actions→Plus d'actions (was "propositions")
- subscription plan terms: plan→Forfait (was "Planifier"/verb),
  premium→Premium (was "Prime"), standard→Standard (was "Norme")
- role/position: role→Rôle, position→Poste (both were "Grade"/military rank)
- light mode: mode lumière→mode clair throughout
- upload direction: Télécharger→Téléverser (download vs upload)
- invite_resent: catastrophic mis-parse of "resent" as resentment
- search_match_case: "Étui de correspondance" (phone case)→"Respecter la casse"
- product names preserved: booktabs, Writefull, GPT (were translated literally)
- typo: "toruvé"→"trouvé", missing spaces: "viaGit"→"via Git", "SSOconfiguration"→"Configuration SSO"
- untranslated: x_price_per_month was left in English
- accent: "Suedois"→"Suédois", "Koréen"→"Coréen", "Turque"→"Turc"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 11:17:32 +00:00
claude 00ccb9748e docs: red CAUTION block for security warning, fix hallucinated Overleaf/Typst claim
Use GitHub's > [!CAUTION] admonition (renders with red background) for the
trusted-environment security warning, matching the style used by Collabst.

Remove invented claim that Overleaf is working on Typst support — that was
a hallucination. Replace with a plain "Verso is built on Overleaf's infra"
statement. Add RevealJS as a separate ecosystem project worth supporting.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 09:31:35 +00:00
claude a16ad0b977 docs: no contributions/donations, add security model + Collabst + ecosystem support
Build and Deploy Verso / deploy (push) Successful in 15m37s
- Remove Contributing section (not accepting PRs/issues)
- Add Security model section: Verso is for trusted environments only;
  point untrusted-user use cases at Overleaf non-Community offerings
- Mention Collabst as a promising open-source Typst-only alternative
  in the Verso vs Typst.app comparison
- Add Supporting the ecosystem section redirecting to Overleaf (Typst +
  RevealJS work) and the Typst project instead of Verso donations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 09:22:34 +00:00
claude c2a21da47c docs: rewrite README — positioning vs Overleaf/Quarto/Typst.app, add releases section
Build and Deploy Verso / deploy (push) Has been cancelled
Replace the "how to write a .qmd / .typ / .tex" tutorial content with a
clear positioning narrative: what Verso is vs Overleaf (same engine + more
languages), vs Quarto CLI (browser-based, collaborative, multi-language),
and vs Typst.app (self-hosted, AGPL, OT-backed, three languages).

Add a Releases section covering Alpha 1 (core multi-compiler foundation),
Alpha 2 (Typst grammar overhaul, format sub-types, Python for collaborators),
and Alpha 3 in-progress (Lumière, i18n, visual editors, upload fix).

Keep Quick start, Architecture, Env vars, and License sections intact.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 09:11:02 +00:00
claude 94d3764c05 fix: stream HTTP 200 heartbeat before upload body to prevent proxy timeouts
Build and Deploy Verso / deploy (push) Has been cancelled
Uploads from slow connections consistently fail with 502 after ~60-120s
because an upstream proxy (Traefik or cloud load-balancer) has a
"first response byte" deadline that fires before the request body arrives.

Fix: add startStreamingResponse middleware (after auth, before multer)
that immediately writes HTTP 200 + Transfer-Encoding: chunked + '\n'.
With proxy_request_buffering off in Nginx, this reaches the proxy at T≈0,
so no timeout triggers. The upload body continues streaming; multer writes
to disk; the actual JSON result arrives as the final chunk. Periodic
heartbeat '\n' writes every 30s keep response-idle timeouts at bay too.

Client-side: override Uppy's getResponseData/validateStatus to trim
leading whitespace before JSON.parse so the extra '\n' bytes are ignored.
Server-side: sendUploadResponse() helper handles both streaming mode
(res.headersSent → res.end(json)) and normal mode (res.status(N).json()).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 08:59:02 +00:00
claude 8f372d13f8 fix: Lumière layout/navbar on settings+404, drop proxy_request_buffering
Build and Deploy Verso / deploy (push) Successful in 14m28s
- Move min-height:100vh from body to html:has(body[data-lumiere]) so the
  gradient fills the viewport on short pages without inflating document
  height or pushing the footer below the fold
- Remove min-height:60vh from .error-container (was causing scrollbar on
  404 when combined with thin footer)
- Replace Bootstrap 3 navbar selectors (.navbar-nav > li > a) with CSS
  custom property overrides (--navbar-link-color, --navbar-link-hover-*,
  --navbar-bg, etc.) consumed by navbar.scss — fixes header button colours
- Remove position:relative from .navbar-default override; base CSS already
  has position:absolute which provides the stacking context for ::before
- Drop proxy_request_buffering off from upload location: buffered mode +
  global client_body_timeout 15m (nginx.conf.template) is more compatible
  with multer's multipart stream handling on slow connections

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 20:38:00 +00:00
claude 211ca9c46d Fix Lumière theming + upload timeout via global middleware
Build and Deploy Verso / deploy (push) Successful in 14m26s
Theming: replace per-controller isLumiere lookups with a single
ExpressLocals middleware that sets res.locals.isLumiere for every
web request. Uses getOverallTheme() (now exported from
UserSettingsHelper) so the date-based default is handled correctly.
This covers 404, settings, setPassword, activate, and all future
server-rendered pages automatically.

Upload timeout: add client_body_timeout 15m to nginx.conf.template
at the http level (was defaulting to 60s globally). This is more
reliable than the location-specific override from build 229.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 19:33:53 +00:00
claude 2ec6ca827e Fix upload timeout + apply Lumière to settings/auth pages
Build and Deploy Verso / deploy (push) Successful in 15m0s
Nginx: add dedicated upload location with client_body_timeout 15m,
client_max_body_size 550m, and proxy_request_buffering off. Default
client_body_timeout of 60s was the actual culprit cutting slow uploads.
Node.js requestTimeout (build 228) remains as a backstop.

Lumière: pass isLumiere from UserPagesController (settings),
PasswordResetController (set-password), and UserActivateController
(first-time activation). auth.scss adds card styling for auth pages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 17:47:03 +00:00
claude 41d38a70ed Increase upload timeout to 15 min for slow connections
Build and Deploy Verso / deploy (push) Successful in 15m39s
Frontend fetch gets AbortSignal.timeout(15 min) so hung connections
fail cleanly. Server requestTimeout raised from Node default (5 min)
to match, preventing large-file uploads from being cut off server-side.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 16:58:10 +00:00
claude b8d5cb9816 fix: XS badge column, lumiere on welcome and 404 pages
Build and Deploy Verso / deploy (push) Successful in 14m39s
- XS compact row: format column 70px→96px so "QUARTO SLIDES" stays on one line;
  trim owner/date cols slightly to compensate
- Welcome page (0 projects): Lumière branch now renders before the 0-projects
  check; ProjectListLumiere renders WelcomePageContent when totalProjectsCount=0
  so new users get the full onboarding experience in the Lumière shell
- 404 page: notFound() now detects the user's overallTheme and passes isLumiere
  to the template; layout-base.pug sets data-lumiere on the body; error-pages.scss
  and project-list-lumiere.scss add [data-lumiere='true'] rules for the body
  background gradient, navbar white+stripe, and styled error box

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 16:33:23 +00:00
claude c5883e5954 feat: generate first-slide thumbnail for Quarto RevealJS presentations
Build and Deploy Verso / deploy (push) Successful in 14m10s
thumbnailFromBuild() now tries output.pdf → output-slides.pdf → decktape
on output.html (slide 1 only). The web service's ThumbnailManager already
calls this endpoint fire-and-forget on every successful compile, so RevealJS
project cards will show the first slide thumbnail automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 16:02:54 +00:00
claude 1ddd219449 fix: nowrap on format badges, widen search bar to 360px
Build and Deploy Verso / deploy (push) Successful in 14m25s
Prevents "Quarto Slides" from wrapping to two lines in XS view.
Widens search input from 300px to 360px so French placeholder text fits.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 15:44:57 +00:00
claude be6034afcf fix: remove block comments containing closing delimiter causing babel parse errors
Build and Deploy Verso / deploy (push) Successful in 15m19s
JSDoc blocks in typst-decorations.ts and quarto-decorations.ts contained
*/ sequences inside them, which Babel's parser treats as terminating the
block comment prematurely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 14:55:35 +00:00
claude 37ed70c7e9 build 223: Quarto visual editor — bold, italic, headings, inline code, strikethrough
Build and Deploy Verso / deploy (push) Has been cancelled
Add quarto-decorations.ts ViewPlugin for .qmd/.md files in visual mode:
- ATXHeading1-6: hide # prefix, apply font-size per level (2em → 1em)
- StrongEmphasis: hide ** markers, apply font-weight:700
- Emphasis: hide * or _ markers, apply font-style:italic
- Strikethrough: hide ~~ markers, apply text-decoration:line-through
- InlineCode: hide backtick markers, apply monospace + subtle bg
Markers reappear when cursor enters the node (selectionSet trigger).
Uses getChildren('EmphasisMark'/'StrikethroughMark'/'CodeMark') to locate
delimiters generically, handling both single- and double-backtick inline code.

CSS rules (.ol-cm-md-{strong,emph,strikethrough,inline-code,heading,h1-h6})
added to visual-theme.ts. Plugin wired into visual.ts after typstDecorations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 13:27:34 +00:00
claude e4dc5f3f5d build 222: Typst visual editor — bold, italic, headings, inline code
Build and Deploy Verso / deploy (push) Has been cancelled
Add typst-decorations.ts ViewPlugin that runs alongside the existing
LaTeX visual decorations. For Typst files in visual mode it:
- Hides *…* markers and applies font-weight:700 to the StrongBody
- Hides _…_ markers and applies font-style:italic to the EmphBody
- Hides = prefix marks and applies heading CSS (h1–h6 font sizes)
- Hides backtick delimiters and applies monospace to RawInlineContent
Markers reappear when the cursor enters the node (selectionSet trigger).

Register CSS rules for .ol-cm-typst-{strong,emph,heading,h1-h6,raw-inline}
in visual-theme.ts. Wire the plugin into visual.ts after markDecorations.

The visual editor toggle was already available for .typ files since 'typ'
is in validRootDocExtensions — no gating change needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 13:10:09 +00:00
claude 0058cc17b5 build 221: fix panel bg cascade, center toggle pill, Lumière XS compact rows
Build and Deploy Verso / deploy (push) Successful in 15m1s
- ide-lumiere.scss: declare --file-tree-bg/--outline-bg-color/--outline-container-color-bg:
  transparent at [data-lumiere] .ide-redesign-main scope to beat file-tree.scss +
  outline.scss which re-declare the same vars at .ide-redesign-main (closer ancestor)
- linked-file-highlight and disconnected-overlay get explicit fallback colors so they
  remain usable when --file-tree-bg is transparent
- custom-toggler: replace left:-5px with left:50%/transform:translateX(-50%) for
  reliable centering of the 16px pill over the 4px resize handle
- project-list-lumiere.scss: compact rows get teal-tinted bg + teal border (Lumière feel)
- project-format-badge-* overrides inside .project-list-lumiere so the XS compact view
  shows the soft Lumière palette (matching .lumiere-format-badge--* on cards)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 12:33:18 +00:00
claude 0754d986e9 build 220: XS compact view reuses classic table cells for full detail
Build and Deploy Verso / deploy (push) Successful in 20m14s
Replace the CSS-only compact card hack with a dedicated
ProjectCardCompact component that reuses FormatCell, OwnerCell,
LastUpdatedCell (with tooltip + updated-by), ActionsCell (full set),
and InlineTags — identical data to the classic table view. CSS Grid
aligns columns across rows: checkbox | name+tags | format | owner |
date | actions. Actions fade in on row hover.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 11:47:00 +00:00
claude 6e230e250e build 219: wider toggle pill, transparent panel bg, shorter panel names
Build and Deploy Verso / deploy (push) Has been cancelled
Resize handle toggle: 14px wide (centered over 4px handle) so the
arrow icon is clearly visible. File tree and outline backgrounds set
to transparent so the panel-group noise+gradient shows through.
FR: file_tree→"Fichiers", file_outline→"Plan" (+ hide variants).
IT: file_tree→"File", IT/ES hide keys shortened to match.
DE unchanged (Dateibaum/Gliederung already concise).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 11:35:12 +00:00
claude 4f299c6204 build 221: wider search bar, XS compact list view
Build and Deploy Verso / deploy (push) Successful in 14m55s
Search bar: set min-width: 300px so the placeholder text is fully
visible. XS zoom level (value 0): adds lumiere-card-grid--compact class
which switches cards to horizontal rows, hides the thumbnail, and shows
only name / badge / owner / date / actions in a compact strip. Stored
0.75 from old S already fell back to 1 (S); new 0 is cleanly additive.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 11:06:49 +00:00
claude 261ca98103 build 220: remap tile zoom levels S/M/L
Old S (0.75×) removed — too small. Old M→S (1×), old L→M (1.35×),
new L added at 1.75×. Stored 0.75 in localStorage falls back to 1×.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 10:58:55 +00:00
claude 60f1e2c511 build 219: Lumière styling for file tree, outline, and panel dividers
Outline: override all CSS variables to use teal palette (bg, border,
hover, highlight, guide line) — was completely unstyled.
File tree: add teal inset left-accent bar on selected item.
Resize handles: narrow from 7→4px, remove dot-grip SVGs, teal hover
highlight. Collapse toggle: teal pill instead of grey.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 10:54:34 +00:00
claude f6bded1596 build 218: Verso logos on set-password and email-check pages, i18n zoom aria-label
Replace Overleaf icons with Verso branding on setPassword.pug
(square icon) and primaryEmailCheck.pug (wordmark). Replace hardcoded
French aria-label "Taille des cartes" on zoom control with t('card_size')
and add card_size key to all 5 locale files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 10:48:20 +00:00
claude 2f4b60574c build 217: square logo on password reset, align tile colours to classic badges
Build and Deploy Verso / deploy (push) Successful in 15m11s
Use verso-square.svg (small icon) instead of the wordmark on the
password reset page. Align card thumbnail gradients and format badge
colours to match the classic project list badge colours (LaTeX green
#098842, Typst teal #239dad, Quarto blue #447099, Quarto Slides
pink-red #e4637c). Split quarto-slides badge from quarto badge.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 10:38:05 +00:00
claude 29880d1cf9 build 216: Verso logo on password reset page, fix SSO/ES translations
Build and Deploy Verso / deploy (push) Successful in 15m31s
Replace Overleaf icon with Verso wordmark on passwordReset.pug.
Fix ES password_reset_email_sent (meaning error: said the password
was sent, not a link). Translate <0>Log in with SSO</0> link text
in FR/DE/IT/ES (was left in English in all languages).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 10:15:37 +00:00
claude 9de127f879 i18n: fix login button and related strings in FR/DE/IT/ES
Build and Deploy Verso / deploy (push) Successful in 19m6s
- FR login button: 'Identifiant' (username field label) → 'Connexion'
- ES forgot_your_password: missing closing '?' added
- DE logging_in: 'Anmeldung' (noun) → 'Anmelden' (verb, fits spinner)
- IT logging_in: 'Entrata in corso' → 'Accesso in corso'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 09:51:16 +00:00
claude ae4e95312d i18n: translate hardcoded strings on project page and footer
Build and Deploy Verso / deploy (push) Successful in 17m39s
- Card owner: "You" now goes through t('you') so it renders as
  "Vous"/"Tu"/"Du" etc. instead of always "You"
- Relative dates (fromNow): moment.locale() is now set from the app
  language so "2 days ago" becomes "il y a 2 jours" etc.
- Footer: "Built on", "Source code", "AGPL licence" are now translated
  via t() with keys added to all locale files and extracted-translations
- New keys: built_on, source_code, agpl_licence (FR/DE/IT/ES translations
  added manually)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 09:33:22 +00:00
claude 093c25f3dd i18n: validate and fix 212 translation errors across FR/DE/IT/ES
Build and Deploy Verso / deploy (push) Successful in 13m46s
Automated validation pass found and corrected:
- Brand names translated literally (Overleaf→"au verso"/dorso/retro/umseitig,
  Verso→"verso", LaTeX→"látex", Quarto→"en cuarto", TeXGPT→"TestoGPT")
- React-Trans <N> tags eaten by Google Translate (5 strings)
- FR grammar: "va sera écrasé" → "sera écrasé"
- FR preposition: "en <b>__email__</b>" → "sur <b>__email__</b>" (×2)
- FR title: "Accepter l'erreur de modification" → "Erreur d'acceptation des modifications"
- FR redundancy: "la version Rolling TeX Live" → "le build Rolling TeX Live"
- ES: "mesa" (furniture) → "tabla" (document table) in 3 strings

Tooling committed: translate_missing.py, fix_translations.py,
validate_translations.py — reusable for future locale additions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 09:16:57 +00:00
claude 375c18873e i18n: complete FR/DE/IT/ES translations via Google Translate (free tier)
Build and Deploy Verso / deploy (push) Successful in 14m37s
All four locales are now at 100% key coverage (was FR 38%, DE 50%,
IT 12%, ES 21%). Translated ~7,700 missing keys using deep-translator
with placeholder preservation (__varName__, <N>…</N> React-Trans tags).
Manual corrections can be made on top of this baseline as needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 22:15:47 +00:00
claude 3ee564ef70 ui: fix header row layout, selected-tile contrast, toolbar gradient
Build and Deploy Verso / deploy (push) Successful in 14m19s
- Header: revert column layout; title+zoom stay on left, search+button
  on right — all on one row (flex-wrap handles narrow viewports)
- Selected cards: switch from teal tint (invisible on teal bg) to solid
  white + blue ring, clearly distinguishable from the page background
- Editor toolbar: replace flat teal wash with an exponential-like decay
  (20%→9%→3%→0% teal overlay) so only the very top has colour

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 20:47:31 +00:00
claude 4ca6ec2b58 ui: move zoom picker next to section title, fix tooltip hover-stealing
Build and Deploy Verso / deploy (push) Successful in 14m18s
S/M/L buttons now appear inline with the page title rather than in the
action bar. Bootstrap tooltips get pointer-events:none so they can no
longer steal :hover from the card beneath them, preventing the lift
animation from flickering when hovering over tag dots.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 20:09:48 +00:00
claude be529e53f6 Fix translation keys and remove sidebar logo border
Build and Deploy Verso / deploy (push) Successful in 14m14s
- extracted-translations.json: add n_projects_selected, n_projects_selected_plural,
  deselect_all — the translations-loader.js only bundles keys present in this file,
  which is why the FR translations were silently stripped from the webpack chunk
- Revert lang.default workaround in i18n.ts (not needed)
- SCSS: remove border-top above .ds-nav-verso-logo in sidebar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 18:31:04 +00:00
claude 592b4d3dad Fix translations, center logo/footer, add tile zoom control
Build and Deploy Verso / deploy (push) Successful in 14m8s
- i18n: unwrap webpack module object on dynamic JSON import (lang.default ?? lang)
  so French bundle keys are correctly registered in the i18next store
- Login logo: use flex centering on wrapper instead of display:block + margin:auto
- Footer (project list + login): align-items:center on .row for vertical centering
- Tile zoom: S/M/L control in header with CSS custom property (--lum-card-scale)
  that scales grid column width and card thumbnail height; persisted in localStorage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 17:20:21 +00:00