diff --git a/.gitea/workflows/build-and-publish.yaml b/.gitea/workflows/build-and-publish.yaml
index d62768a..0943af5 100644
--- a/.gitea/workflows/build-and-publish.yaml
+++ b/.gitea/workflows/build-and-publish.yaml
@@ -51,10 +51,12 @@ jobs:
echo "tag=${TAGS%% *}" >> "$GITHUB_OUTPUT"
echo "tags=${TAGS}" >> "$GITHUB_OUTPUT"
echo "actor=${ACTOR_NAME}" >> "$GITHUB_OUTPUT"
- # Releases (tags) show the tag as version in the app header
+ # Version in the app header: tags show the tag, main the package version, everything else
+ # (dev, feature branches) keeps the "-dev" suffix from vite.config.ts
APP_VERSION=""
case "${GITHUB_REF:-}" in
refs/tags/*) APP_VERSION="${REF_NAME}" ;;
+ refs/heads/main) APP_VERSION="v$(sed -nE 's/^ "version": "([^"]+)".*/\1/p' frontend/package.json | head -n1)" ;;
esac
echo "app_version=${APP_VERSION}" >> "$GITHUB_OUTPUT"
echo "Target Docker image: ${IMAGE_NAME} tags: ${TAGS} (Registry: ${REGISTRY_HOST}, Actor: ${ACTOR_NAME})"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 96c2ae3..6b8dbf4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,15 @@ Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), die V
## [Unreleased]
+### Changed
+- Schrift: MindSift liefert die Schrift Inter jetzt selbst aus (ohne externen Dienst), damit die Oberfläche auf allen Geräten gleich aussieht. Notiztitel stehen in einer feinen, dünnen Schrift und etwas größer.
+- Notizen: Der Titel in der Kopfleiste erscheint erst, wenn der große Titel aus dem Bild gescrollt ist; am Handy passt die Kopfleiste in eine Zeile.
+- Das Bild für `main` (`latest`) zeigt die Versionsnummer ohne `-dev`; nur `dev` und andere Zweige behalten den Zusatz.
+
### Fixed
+- Workspace: kein doppelter Scrollbalken mehr – die Seite selbst scrollt nicht, nur die Notiz; am Handy scrollt die Notiz nicht mehr getrennt von der Seite.
+- Workspace: Ein abgebrochenes Ziehen in der Seitenleiste lässt „Auf Hauptebene verschieben“ nicht mehr stehen.
+- Workspace: Der Knopf zum Ein-/Ausklappen der Ordnerleiste ist im eingeklappten Zustand dezent (nur das Symbol in Akzentfarbe).
- Kontoeinstellungen: Der Bereich „Profil & Anmeldedaten“ nutzt die volle Breite wie die übrigen Bereiche.
- Light-Theme: Notizen stehen auf einem weißen Blatt, die Ordnerleiste ist dezent grau abgesetzt (bisher umgekehrt). Themes können das über die neuen Variablen `--bg-editor` und `--bg-sidebar` selbst festlegen.
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 50b1f35..44a9660 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.9.0",
"license": "Unlicense",
"dependencies": {
+ "@fontsource-variable/inter": "5.3.0",
"@types/prismjs": "^1.26.6",
"emoji-picker-react": "4.12.0",
"framer-motion": "^11.15.0",
@@ -1024,6 +1025,15 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
+ "node_modules/@fontsource-variable/inter": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.3.0.tgz",
+ "integrity": "sha512-OupL48va4JNofb97w6NYeF9S7W/kHNKM0Er8Dem5nqi4jeOLrVJDoE8tZEpnMJmtkvNbB1EIPPwHcdkF6b1oUA==",
+ "license": "OFL-1.1",
+ "funding": {
+ "url": "https://github.com/sponsors/ayuhito"
+ }
+ },
"node_modules/@humanfs/core": {
"version": "0.19.2",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index d2277c8..76e2ec3 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -13,6 +13,7 @@
"test:run": "vitest run"
},
"dependencies": {
+ "@fontsource-variable/inter": "5.3.0",
"@types/prismjs": "^1.26.6",
"emoji-picker-react": "4.12.0",
"framer-motion": "^11.15.0",
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 28a7672..5b36801 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -750,7 +750,11 @@ export const App: React.FC = () => {
};
return (
-
+
{/* Top Header Bar: Floating on mobile, solid panel on desktop */}
{/* Mobile Header: Floating Bar with Logo Action Dropdown Left & Profile Avatar Right */}
@@ -1113,9 +1117,14 @@ export const App: React.FC = () => {
)}
{/* Main Container */}
-
+ {/* The workspace fills the window exactly and scrolls only inside the note, never the page */}
+ setActiveTab('triage')}>
-
+
{activeTab === 'triage' && (
= ({
const titleInputRef = useRef(null);
+ const scrollRef = useRef(null);
+ // The header repeats the title only once the big title has scrolled out of view
+ const [titleScrolledAway, setTitleScrolledAway] = useState(false);
const outlinerTreeRef = useRef(null);
const docRef = useRef(doc);
docRef.current = doc;
@@ -239,6 +242,22 @@ export const DocumentEditor: React.FC = ({
const currentBlocksRef = useRef(blocks);
currentBlocksRef.current = blocks;
+ useEffect(() => {
+ const root = scrollRef.current;
+ const el = titleInputRef.current;
+ if (!root || !el || typeof IntersectionObserver === 'undefined') {
+ setTitleScrolledAway(false);
+ return;
+ }
+ const observer = new IntersectionObserver(
+ ([entry]) => setTitleScrolledAway(!entry.isIntersecting),
+ // the sticky header covers the top of the scroll area
+ { root, rootMargin: '-56px 0px 0px 0px' }
+ );
+ observer.observe(el);
+ return () => observer.disconnect();
+ }, [zoomedBlockId, doc?.id]);
+
useEffect(() => {
if (!loading && (autoFocusTitle || (doc?.title === 'Neue Notiz' && (!doc?.blocks || doc?.blocks.length <= 1)))) {
const focusTitle = () => {
@@ -763,15 +782,15 @@ export const DocumentEditor: React.FC = ({
}
return (
-