- Fix babel.cfg with [extractors] so pybabel resolves jinja2 templates on
toolchains where babel.extractors entry points are not loaded.
- Regenerate messages from source: extract POT, update all locales, drop
obsolete entries (--ignore-obsolete). Portuguese msgstr filled with
offline Argos en→pt (machine output; human QA still recommended).
- Add scripts/fill_po_argos.py for optional first-pass locale fills.
- Gitignore root messages.pot; document extract/update/Argos in
TRANSLATION_SYSTEM and CONTRIBUTING_TRANSLATIONS.
Register Português in LANGUAGES and normalize pt-BR/pt-PT (and similar)
to pt in _normalize_locale so Accept-Language and stored preferences resolve
to translations/pt/.
Add translations/pt/LC_MESSAGES/messages.po seeded from English msgids;
translators can fill msgstr incrementally.
Extend i18n tests for pt presence and catalog file. Update translation
docs (TRANSLATION_SYSTEM, CONTRIBUTING_TRANSLATIONS, implementation note).
Document https://crowdin.com/project/drytrix-timetracker in CONTRIBUTING.md, docs/TRANSLATION_SYSTEM.md, and contributor guides. Update CONTRIBUTING_TRANSLATIONS.md with the public project URL, clearer translator vs maintainer onboarding, and an optional "Further Crowdin integration" section (GitHub app, automation, QA, glossary, notifications).
Refresh crowdin.yml header comments (project URL, secrets pointers), normalize preserve_hierarchy to a boolean, and keep the nb→no languages_mapping quoted for YAML 1.1 compatibility.
Add crowdin.yml mapping the English gettext catalog to per-locale messages.po paths, with an explicit nb→no mapping so Norwegian matches app/config.py.
Add a manual GitHub Action (Crowdin sync) to upload sources and download translations when CROWDIN_PROJECT_ID and CROWDIN_PERSONAL_TOKEN are configured.
Extend CONTRIBUTING_TRANSLATIONS with maintainer steps, cross-link TRANSLATION_SYSTEM and contributor guides, refresh TRANSLATION_SYSTEM metadata, and note the integration under [Unreleased] in CHANGELOG.md.
Add Move up / Move down controls and an Order column for quote line items, Costs, and Extra goods on create and edit pages (Issue #584). DOM row order matches POST field order so existing QuoteItem.position handling stays correct.
Fix the quote detail Valid until row by using quote.is_expired instead of an undefined Jinja now() (Issue #583). Submit a past valid_until in the web regression test so the view path is exercised.
Document translation contributions without Git: add docs/CONTRIBUTING_TRANSLATIONS.md, a Translation improvement issue template, links from CONTRIBUTING.md and TRANSLATION_SYSTEM.md, and a Translations subsection in docs/development/CONTRIBUTING.md. Refresh CHANGELOG [Unreleased] for these items.