diff --git a/Atomic-Blog-Generation-Pipeline/visuals/posts/atomic_notes_architecture.py b/Atomic-Blog-Generation-Pipeline/visuals/posts/atomic_notes_architecture.py
new file mode 100644
index 0000000..b189daf
--- /dev/null
+++ b/Atomic-Blog-Generation-Pipeline/visuals/posts/atomic_notes_architecture.py
@@ -0,0 +1,77 @@
+"""Figures for L5: Local First Architecture: 4 Layers Behind Atomic Notes."""
+from atomic_viz import figure, banner, box, phone, arrow
+
+LAYERS = [("01 · DEVICE", "THE REAL COPY", "Flutter app, Hive CE storage. Every note saves here first."),
+ ("02 · SYNC SERVER", "THE COORDINATOR", "Hono on Vercel, MongoDB Atlas. Metadata, versions, energy."),
+ ("03 · YOUR DRIVE", "THE CLOUD COPY", "One .atomic file per note, in a folder you own."),
+ ("04 · VAULT", "THE OPTIONAL LOCK", "Argon2id + AES-256-GCM on the device. Off by default.")]
+
+
+def build():
+ out = {}
+
+ art = ""
+ for i, (l, t, _) in enumerate(LAYERS):
+ cls = "signal sigshadow" if i == 0 else ("ink" if i == 3 else "")
+ art += box(700 + i * 22, 96 + i * 118, 420, 100, f'
{l}
{t}
',
+ cls=cls, style="padding:12px 20px")
+ out["01-banner"] = banner("ARCHITECTURE · ATOMIC NOTES", 'LOCAL FIRST ARCHITECTURE',
+ "Four layers behind Atomic Notes, and what each one can and can't see.", art, title_size=104, text_width=600)
+
+ body = ""
+ for i, (l, t, d) in enumerate(LAYERS[:3]):
+ y = 196 + i * 162
+ cls = "signal sigshadow" if i == 0 else ("surface" if i == 1 else "")
+ body += box(56, y, 800, 136, f'
{l}
{t}
{d}
',
+ cls=cls, style="padding:14px 22px")
+ l, t, d = LAYERS[3]
+ body += box(906, 196, 238, 460, f'
{l}
{t}
{d}
'
+ '
Wraps layers 2 and 3: they hold ciphertext once it is on.
Per-user lock, base-version check, one transaction per push.
', cls="surface")
+ body += box(870, 210, 274, 210, '
GOOGLE DRIVE
WRITE FILES
8 writes in flight, with retry.
')
+ body += box(420, 500, 724, 170, '
PULL
OTHER DEVICES CATCH UP
They ask for changes since their last cursor, 10 files per page, and open each note on the device.
')
+ body += ('
PUSH + REQUEST ID
'
+ '
.ATOMIC FILES
')
+ lines = (arrow(306, 320, 414, 320, color="sig") + arrow(756, 320, 864, 320, color="sig")
+ + arrow(1006, 426, 1006, 494, color="ink", dash=True) + arrow(414, 585, 300, 585, color="ink", dash=True, curve=(330, 600)))
+ out["03-push-and-pull"] = figure("FIG 2 · THE DATA FLOW", 'PUSH UP. PULL DOWN.', body,
+ "Measured in production: a 9-note push took 3.2 s, a 22-note push 6.8 s.", lines=lines, h=740)
+
+ rows = [("YOUR PHONE", "Everything", "Everything, after unlock"),
+ ("SYNC SERVER", "Metadata. Note text in transit only", "Metadata and ciphertext"),
+ ("GOOGLE (YOUR DRIVE)", "Readable .atomic files", "Ciphertext files"),
+ ("THE DEVELOPER", "Metadata in the database", "Metadata in the database"),
+ ("ANYONE IN YOUR GOOGLE ACCOUNT", "Your notes", "Ciphertext they can't open")]
+ trs = "".join(f"
{a}
{b}
{c}
" for a, b, c in rows)
+ body = (f'
WHO
VAULT OFF
'
+ f'
VAULT ON
{trs}
')
+ out["04-who-sees-what"] = figure("FIG 3 · VISIBILITY", 'WHO SEES WHAT', body,
+ "The server never stores note titles or text, with the vault on or off.", h=700)
+
+ rows = [("NO NETWORK", "Notes save locally. Sync waits and runs on reconnect."),
+ ("TIMEOUT MID-PUSH", "The same request ID is resent. The server replays its answer, so nothing is charged or written twice."),
+ ("TWO DEVICES EDIT ONE NOTE", "The stale edit is refused and kept as a conflict copy. Nothing is overwritten."),
+ ("STALE DELETE", "A delete based on an old version is refused, so a newer edit survives."),
+ ("DRIVE IS SLOW", "Writes retry. The note stays pending on the phone until confirmed."),
+ ("PHONE IS LOST", "Synced notes are in your Drive. Sign in on a new phone to pull them back.")]
+ trs = "".join(f"
{a}
{b}
" for a, b in rows)
+ body = (f'
WHEN THIS HAPPENS
'
+ f'
WHAT ATOMIC NOTES DOES
{trs}
')
+ out["05-failure-modes"] = figure("FIG 4 · WHEN THINGS GO WRONG", 'DESIGNED FOR BAD DAYS', body, h=800)
+
+ stack = [("APP", "Flutter (Dart), flutter_bloc, Hive CE. Android 9 or newer."),
+ ("SERVER", "Hono (TypeScript) on Vercel, Mumbai region."),
+ ("DATABASE", "MongoDB Atlas. Metadata, sessions, energy ledger."),
+ ("STORAGE", "Google Drive API with the drive.file scope only."),
+ ("CRYPTO", "Argon2id (64 MiB, 3 passes) and AES-256-GCM, on the device."),
+ ("WEBSITE", "Next.js 15. Cookieless page analytics, no ad pixels.")]
+ rws = "".join(f'
'
+ f'{a}{b}
' for a, b in stack)
+ body = box(56, 196, 1088, 500, f'
THE STACK, IN ONE CARD
{rws}
', cls="sigshadow")
+ out["06-the-stack"] = figure("FIG 5 · TECH STACK", 'WHAT IT\'S BUILT WITH', body, h=760)
+ return out
diff --git a/Atomic-Blog-Generation-Pipeline/visuals/posts/best_privacy_first_notes_apps_android.py b/Atomic-Blog-Generation-Pipeline/visuals/posts/best_privacy_first_notes_apps_android.py
new file mode 100644
index 0000000..d22f57d
--- /dev/null
+++ b/Atomic-Blog-Generation-Pipeline/visuals/posts/best_privacy_first_notes_apps_android.py
@@ -0,0 +1,83 @@
+"""Figures for P2: 7 Best Private Notes Apps for Android in 2026."""
+from atomic_viz import figure, banner, box, phone, arrow
+
+APPS = ["Atomic Notes", "SilentNotes", "CypherLeaf", "NoteSR", "Quillpad", "Fossify Notes", "Notes (Privacy Friendly)"]
+
+
+def build():
+ out = {}
+
+ rows = "".join(f'
'
+ f'{i + 1:02d}'
+ f'{a}
' for i, a in enumerate(APPS))
+ art = box(740, 92, 400, 460, f'
CHECKED OCTOBER 2026
{rows}', cls="sigshadow", style="padding:18px 22px")
+ out["01-banner"] = banner("PRIVACY · ANDROID · 2026", '7 BEST PRIVATE NOTES APPS FOR ANDROID',
+ "No ads, no trackers, public source code. Picked for how they treat your notes.", art, title_size=88, text_width=640)
+
+ y, n, p = 'YES', 'NO', 'OPTIONAL'
+ data = [("ATOMIC NOTES", "Phone + your Google Drive", p, y, "Google", "Source-available"),
+ ("SILENTNOTES", "Phone + storage you pick", y, y, "None", "MPL-2.0"),
+ ("CYPHERLEAF", "Phone only", "Locked notes", n, "None", "MIT"),
+ ("NOTESR", "Phone only", y, n, "None", "MIT"),
+ ("QUILLPAD", "Phone + your Nextcloud", n, y, "None", "GPL-3.0"),
+ ("FOSSIFY NOTES", "Phone only", n, n, "None", "GPL-3.0"),
+ ("PRIVACY FRIENDLY", "Phone only", n, n, "None", "GPL-3.0")]
+ trs = "".join(f"
{a}
{b}
{c}
{d}
{e}
{f}
" for a, b, c, d, e, f in data)
+ body = (f'
APP
WHERE NOTES LIVE
ENCRYPTED
'
+ f'
SYNC
ACCOUNT
LICENSE
{trs}
')
+ out["02-comparison"] = figure("FIG 1 · AT A GLANCE", 'SEVEN APPS, SIDE BY SIDE', body,
+ "Checked against each app's repository or F-Droid listing on October 7, 2026.", h=790)
+
+ rules = [("NO ADS", "No ad slots, no ad SDKs."), ("NO TRACKERS", "No analytics or tracking libraries."),
+ ("PUBLIC CODE", "Source you can read and check."), ("ALIVE IN 2026", "Updated recently, not abandoned."),
+ ("PRIVATE BY DEFAULT", "Notes stay on the phone unless you choose sync."), ("HONEST LIMITS", "Each pick's weak spot is named.")]
+ body = ""
+ for i, (t, d) in enumerate(rules):
+ x, yy = 56 + (i % 3) * 370, 196 + (i // 3) * 236
+ body += box(x, yy, 340, 206, f'
{i + 1:02d}
{t}
'
+ f'
{d}
', cls="sigshadow" if i == 0 else "", style="padding:16px 20px")
+ out["03-how-we-picked"] = figure("FIG 2 · THE RULES", 'HOW THESE APPS MADE THE LIST', body,
+ "Popular apps with ads, trackers, or closed code were left out on purpose.", h=720)
+
+ # Pick by need.
+ q = lambda x, yy, t: box(x, yy, 300, 110, f'
QUESTION
{t}
', cls="surface flat", style="padding:12px 18px")
+ a = lambda x, yy, t, d: box(x, yy, 300, 120, f'
{t}
{d}
', style="padding:12px 18px")
+ body = q(56, 220, "SYNC ACROSS DEVICES?")
+ body += q(450, 150, "ENCRYPTED BY DEFAULT?") + q(450, 470, "STORE FILES TOO?")
+ body += a(844, 100, "SILENTNOTES", "Always encrypted, your storage") + a(844, 250, "ATOMIC NOTES", "Your Google Drive, optional vault")
+ body += a(844, 420, "NOTESR", "Encrypted notes and files") + a(844, 570, "FOSSIFY NOTES", "Fast, simple, widgets")
+ body += ('
')
+ out["05-permissions"] = figure("FIG 4 · PERMISSIONS", 'WHO CAN EVEN REACH THE INTERNET?', body,
+ "From each app's AndroidManifest.xml or F-Droid listing. No internet permission means notes can't leave by the app itself.", h=790)
+
+ body = phone(12, 64, 190, 260, crop=470, shadow="ink")
+ facts = [("WHERE NOTES LIVE", "Your phone first, then your own Google Drive"), ("ENCRYPTION", "Optional end-to-end vault, off by default"),
+ ("SERVER", "Metadata only, never note titles or text"), ("NO", "Ads, trackers, or AI"),
+ ("PRICE", "Free, 30 notes, daily sync energy"), ("HONEST LIMITS", "Google sign-in required. No export button yet")]
+ rws = "".join(f'
'
+ f'{a}{b}
' for a, b in facts)
+ body += box(400, 190, 744, 500, f'
ATOMIC NOTES
{rws}
', cls="sigshadow")
+ out["06-atomic-notes-card"] = figure("FIG 5 · OUR PICK, DISCLOSED", 'WHY ATOMIC NOTES IS FIRST', body,
+ "It's my app, so it goes first. Every fact on this card is checkable in its public code.", h=760)
+ return out
diff --git a/Atomic-Blog-Generation-Pipeline/visuals/posts/encrypted_notes_explained.py b/Atomic-Blog-Generation-Pipeline/visuals/posts/encrypted_notes_explained.py
new file mode 100644
index 0000000..7cd2880
--- /dev/null
+++ b/Atomic-Blog-Generation-Pipeline/visuals/posts/encrypted_notes_explained.py
@@ -0,0 +1,84 @@
+"""Figures for S1: Encrypted Notes Explained: T2T vs End to End Encryption."""
+from atomic_viz import figure, banner, box, arrow
+
+CIPHER = "q3Nf0Vb8LJ2kYp9Hc4WuR1mE7TzaX6oPdgKs5tB0iQwlUvC2rh8eMyFnG7jA3SxD"
+
+
+def build():
+ out = {}
+
+ art = (box(690, 96, 450, 196,
+ '
VAULT OFF · T2T
'
+ '
{"enc_v": 0, "body": "Locker code 4471. Call Dr. Rao."}
',
+ cls="ink", style="padding:18px 22px"))
+ out["01-banner"] = banner("SECURITY · THE GUIDE", 'ENCRYPTED NOTES, EXPLAINED',
+ "Three things \"encrypted\" can mean, and the one that keeps the company out of your notes.",
+ art, title_size=104, text_width=600)
+
+ # Where plain text exists under each model.
+ plain, locked = 'PLAIN', 'LOCKED'
+ rows = [("HTTPS ONLY", [plain, locked, plain, plain]),
+ ("AT REST", [plain, locked, plain, locked]),
+ ("END TO END", [plain, locked, locked, locked])]
+ trs = "".join(f"
{n}
" + "".join(f"
{c}
" for c in cells) + "
" for n, cells in rows)
+ body = (f'
MODEL
'
+ f'
YOUR PHONE
THE NETWORK
THE SERVER
THE DISK
{trs}
'
+ '
'
+ 'Your own phone always shows plain text, because you read your notes there. The question is where else plain text exists. '
+ 'Only end-to-end encryption keeps it off the server and the disk.
')
+ out["02-three-meanings"] = figure("FIG 1 · THREE MEANINGS", 'WHERE IS YOUR NOTE READABLE?', body, h=720)
+
+ # Key flow in the Atomic Notes vault.
+ words = " ".join(f'{w}' for w in ["gopher", "beckon", "cultivate", "dolphin", "mentor", "clause"])
+ body = box(56, 196, 330, 262, f'
1 · RECOVERY PHRASE
{words}
'
+ '
6 words from 1,024. Shown once.
', cls="sigshadow")
+ body += box(456, 196, 300, 262, '
2 · ARGON2ID
64 MIB · 3 PASSES
'
+ '
Salt = SHA-256 of an app tag plus your account ID. Slow on purpose.
Fresh 12-byte nonce, 16-byte tag. Title, body, and checklist items go into one sealed payload.
')
+ body += box(626, 520, 518, 210, f'
5 · WHAT LEAVES THE PHONE
{CIPHER}
'
+ '
The server and Drive store only this.
', cls="ink")
+ lines = arrow(392, 326, 450, 326, color="sig") + arrow(762, 326, 820, 326, color="sig") + arrow(985, 464, 360, 514, color="sig", curve=(700, 500)) + arrow(562, 624, 620, 624, color="sig")
+ out["03-vault-key-flow"] = figure("FIG 2 · THE VAULT", 'FROM SIX WORDS TO CIPHERTEXT', body,
+ "The server keeps a verifier: a known phrase sealed with your key, so a wrong phrase fails without revealing anything.", lines=lines, h=820)
+
+ # T2T vs vault.
+ rows = [("LEAVES YOUR PHONE", "Plain text over HTTPS", "Ciphertext over HTTPS"),
+ ("SYNC SERVER SEES", "Note text in transit, never stored", "Ciphertext only"),
+ ("YOUR DRIVE HOLDS", "Readable JSON file", "Sealed JSON file"),
+ ("WHO CAN READ IT", "You, and anyone in your Google account", "Only your devices with the phrase"),
+ ("LOSE THE PHRASE", "Nothing to lose", "Vault notes are gone for good")]
+ trs = "".join(f"
{a}
{b}
{c}
" for a, b, c in rows)
+ body = (f'
T2T · DEFAULT
'
+ f'
VAULT · OPTIONAL
{trs}
')
+ out["04-t2t-vs-vault"] = figure("FIG 3 · ATOMIC NOTES", 'TWO MODES. YOUR CHOICE.', body,
+ "T2T means transport encryption: HTTPS protects the trip, not the destination.", h=700)
+
+ # What end-to-end hides and what it doesn't.
+ hidden = "".join(f'
{x}
' for x in ["Note titles", "Note text", "Checklist items"])
+ visible = "".join(f'
{x}
' for x in
+ ["That a note exists, and its ID", "Text note or checklist", "Pinned or deleted", "When it was created and changed", "Roughly how big it is", "Which Google account owns it"])
+ body = box(56, 196, 470, 470, f'
HIDDEN BY THE VAULT
THE CONTENT
{hidden}
', cls="ink")
+ body += box(586, 196, 558, 470, f'
STILL VISIBLE TO THE SERVER
THE METADATA
{visible}
', cls="surface flat")
+ out["05-what-e2e-hides"] = figure("FIG 4 · THE LIMITS", 'WHAT END-TO-END CAN AND CAN\'T HIDE', body,
+ "Every end-to-end encrypted app leaks some metadata. Good ones keep it small and say what it is.", h=740)
+
+ # Recovery tradeoff.
+ body = box(56, 196, 520, 400, '
PROVIDER CAN RESET
CONVENIENT
'
+ '
Forget your password and support restores your notes.
'
+ '
The catch: if the company can restore your notes, it can read them.
Nobody else holds a copy of the key, including the developer.
'
+ '
The catch: lose the phrase and the vault stays locked forever.
',
+ cls="signal sigshadow")
+ body += ('
'
+ 'Pick by threat model. A shopping list doesn\'t need the vault. A note about your health, money, or safety probably does.
')
+ out["06-recovery-tradeoff"] = figure("FIG 5 · THE TRADE", 'WHO CAN RECOVER YOUR NOTES?', body, h=740)
+ return out
diff --git a/Atomic-Blog-Generation-Pipeline/visuals/posts/notes_app_data_collection.py b/Atomic-Blog-Generation-Pipeline/visuals/posts/notes_app_data_collection.py
new file mode 100644
index 0000000..940c876
--- /dev/null
+++ b/Atomic-Blog-Generation-Pipeline/visuals/posts/notes_app_data_collection.py
@@ -0,0 +1,83 @@
+"""Figures for P5: Notes App Metadata: 8 Things It Knows Without Reading Notes."""
+import random
+from atomic_viz import figure, banner, box
+
+POINTS = [("EMAIL ADDRESS", "Ties every note to your real identity."),
+ ("IP ADDRESS", "Your rough location, and when it changes."),
+ ("DEVICE MODEL", "What you own, and when you switch phones."),
+ ("OS AND APP VERSION", "How current, and how exposed, your phone is."),
+ ("SIGN-IN TIMES", "When you start your day, and from where."),
+ ("SYNC ACTIVITY", "When you write, and how much."),
+ ("USAGE FREQUENCY", "How much the app matters to your routine."),
+ ("NOTE COUNTS AND EDIT TIMES", "The shape of your thinking over time.")]
+
+
+def build():
+ out = {}
+
+ log = "".join(f'
{x}
' for x in
+ ["23:52 · sync · 1 note · 2.1 KB", "23:47 · sync · 1 note · 2.4 KB", "09:12 · sign-in · new device", "14:03 · sync · 6 notes",
+ "00:21 · sync · 1 note · 3.6 KB", "11:40 · delete · 1 note"])
+ art = box(700, 92, 440, 450, f'
SERVER LOG · NO NOTE TEXT
STILL A STORY
{log}
',
+ cls="sigshadow", style="padding:18px 22px")
+ out["01-banner"] = banner("PRIVACY · WHAT APPS KNOW", 'NOTES APP METADATA',
+ "8 things a notes app can know about you without reading a single note.", art, title_size=110, text_width=620)
+
+ content = ["Note titles", "Note text", "Checklist items", "Attachments"]
+ meta = ["Email address", "IP address", "Device model", "OS and app version", "Sign-in times", "Sync activity", "Usage frequency", "Note counts and edit times"]
+ c = "".join(f'
{x}
' for x in content)
+ m = "".join(f'
{x}
' for x in meta)
+ body = box(56, 196, 450, 500, f'
CONTENT
WHAT YOU WROTE
{c}
'
+ '
End-to-end encryption can hide this.
', cls="ink")
+ body += box(566, 196, 578, 500, f'
METADATA
EVERYTHING AROUND IT
{m}
', cls="flat")
+ out["02-content-vs-metadata"] = figure("FIG 1 · TWO KINDS OF DATA", 'CONTENT VS METADATA', body,
+ "Encryption protects the left box. Data minimization protects the right one.", h=760)
+
+ body = ""
+ for i, (t, d) in enumerate(POINTS):
+ x, y = 56 + (i % 4) * 276, 196 + (i // 4) * 262
+ body += box(x, y, 246, 230, f'
{i + 1:02d}
{t}
'
+ f'
{d}
', style="padding:14px 18px")
+ out["03-eight-data-points"] = figure("FIG 2 · THE LIST", 'EIGHT THINGS IT CAN KNOW', body,
+ "None of these needs a single word of your notes.", h=760)
+
+ # A week of sync timestamps as a heatmap.
+ random.seed(7)
+ days = ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"]
+ hits = {(d, h) for d in range(7) for h in (23,) if d < 5} | {(d, 0) for d in (1, 3, 4)} | {(2, 9), (3, 14), (3, 15), (5, 11), (6, 10), (0, 8), (4, 8)}
+ grid = ""
+ for d in range(7):
+ grid += f'
{days[d]}
'
+ for h in range(24):
+ on = (d, h) in hits
+ grid += (f'')
+ for h in (0, 6, 12, 18, 23):
+ grid += f'
{h:02d}:00
'
+ grid += box(130, 660, 1010, 96, '
What it suggests: a long note almost every night near midnight, short bursts on Thursday afternoon, and quiet weekend mornings.
',
+ cls="flat", style="padding:14px 20px")
+ out["04-week-of-sync-times"] = figure("FIG 3 · ONE WEEK OF TIMESTAMPS", 'METADATA MAKES A PATTERN', grid, h=800)
+
+ yes, no, part = 'NEEDED', 'EXTRA', 'BRIEFLY'
+ rows = [("ACCOUNT EMAIL", yes, "To sign you in and own your notes"), ("IP ADDRESS", part, "Every request carries one. Keeping it is a choice"),
+ ("DEVICE MODEL", part, "Useful for spotting a strange sign-in"), ("SYNC TIMES AND VERSIONS", yes, "To merge edits without losing any"),
+ ("SCREEN AND TAP ANALYTICS", no, "Product dashboards, not your notes"), ("ADVERTISING ID", no, "Only needed to target ads"),
+ ("LOCATION OR CONTACTS", no, "Nothing a notes app needs")]
+ trs = "".join(f"
{a}
{b}
{c}
" for a, b, c in rows)
+ body = (f'
DATA
TO SYNC NOTES?
'
+ f'
WHY
{trs}
')
+ out["05-needed-vs-extra"] = figure("FIG 4 · DATA MINIMIZATION", 'NEEDED OR JUST COLLECTED?', body,
+ "A sync service needs a little metadata. Everything past that is a business choice.", h=780)
+
+ keeps = [("ACCOUNT", "Email and display name from Google"), ("SESSIONS", "A SHA-256 hash of each token, the device's user agent, expiry"),
+ ("NOTE METADATA", "IDs, kind, pinned, deleted, versions, Drive file IDs, a content hash, timestamps"),
+ ("ENERGY LEDGER", "Energy and coin balance changes"), ("SECURITY LOG", "Sign-ins and sync events, deleted after 30 days")]
+ never = ["Note titles or text", "Analytics or ad IDs", "Location or contacts", "Crash-reporting SDKs"]
+ k = "".join(f'
'
+ f'{a}{b}
' for a, b in keeps)
+ nv = "".join(f'
✕ {x}
' for x in never)
+ body = box(56, 196, 700, 520, f'
THE SERVER KEEPS
METADATA ONLY
{k}
', cls="flat")
+ body += box(804, 196, 340, 520, f'
NEVER
NOT COLLECTED
{nv}
', cls="signal sigshadow")
+ out["06-what-atomic-notes-keeps"] = figure("FIG 5 · OUR OWN LIST", 'WHAT ATOMIC NOTES ACTUALLY KEEPS', body,
+ "The hosting provider sees IP addresses with each request, like every web service.", h=780)
+ return out
diff --git a/Atomic-Blog-Generation-Pipeline/visuals/posts/why_notes_should_work_offline.py b/Atomic-Blog-Generation-Pipeline/visuals/posts/why_notes_should_work_offline.py
new file mode 100644
index 0000000..284675a
--- /dev/null
+++ b/Atomic-Blog-Generation-Pipeline/visuals/posts/why_notes_should_work_offline.py
@@ -0,0 +1,77 @@
+"""Figures for L3: Notes App Without Internet: Why Offline Should Be the Default."""
+from atomic_viz import figure, banner, box, phone, arrow
+
+
+def build():
+ out = {}
+
+ art = (phone(4, 830, 92, 290, crop=560)
+ + box(660, 330, 330, 210,
+ '
AIRPLANE MODE · ON
'
+ '
NOTE SAVED
'
+ '
0 MS · SYNCS LATER
',
+ cls="sigshadow", style="padding:18px 20px"))
+ out["01-banner"] = banner("LOCAL FIRST · OFFLINE", 'NOTES THAT WORK WITHOUT INTERNET',
+ "Signal drops all the time. Your notes app shouldn't care.", art, title_size=96, text_width=600)
+
+ spots = [("SUBWAYS AND TRAINS", "Tunnels cut the signal between stations."),
+ ("FLIGHTS", "Hours in airplane mode, often with time to think."),
+ ("ELEVATORS AND BASEMENTS", "Concrete and steel block the signal."),
+ ("RURAL ROADS", "Coverage maps are optimistic between towns."),
+ ("CROWDED EVENTS", "Thousands of phones share one set of towers."),
+ ("SECURE BUILDINGS", "Hospitals, labs, and offices that limit networks.")]
+ body = ""
+ for i, (t, d) in enumerate(spots):
+ x, y = 56 + (i % 3) * 370, 196 + (i // 3) * 236
+ body += box(x, y, 340, 206, f'
{i + 1:02d}
{t}
'
+ f'
{d}
', style="padding:16px 20px")
+ out["02-where-signal-drops"] = figure("FIG 1 · REAL LIFE", 'WHERE NOTES LOSE SIGNAL', body,
+ "These are often the moments you most need to write something down.", h=720)
+
+ yes, no, part = 'WORKS', 'FAILS', 'MAYBE'
+ rows = [("OPEN THE APP", part + " cached screen or spinner", yes + " from device storage"),
+ ("READ A NOTE", part + " if it was cached", yes),
+ ("WRITE A NEW NOTE", no + " or a fragile queue", yes + " saved on the device"),
+ ("SEARCH", no + " search runs on a server", yes + " search runs on the phone"),
+ ("DELETE OR EDIT", part, yes),
+ ("SYNC", no + " until the network returns", part + " waits, then catches up")]
+ trs = "".join(f"
{a}
{b}
{c}
" for a, b, c in rows)
+ body = (f'
WITH NO INTERNET
'
+ f'
CLOUD-FIRST APP
LOCAL-FIRST APP
{trs}
')
+ out["03-offline-actions"] = figure("FIG 2 · THE DIFFERENCE", 'WHAT STILL WORKS OFFLINE?', body,
+ "Cloud-first apps vary. Many cache recent notes, but few treat offline as normal.", h=760)
+
+ # A morning offline, then the catch-up.
+ events = [("09:00", "SIGNAL LOST", "Train enters the tunnel.", "surface flat"),
+ ("09:04", "3 EDITS", "Saved on the phone, marked to sync.", "signal flat"),
+ ("09:18", "NEW NOTE", "Saved on the phone too.", "signal flat"),
+ ("09:40", "SIGNAL BACK", "The app notices the network.", "surface flat"),
+ ("09:40", "AUTO SYNC", "All 4 changes upload. Retries at 5, 15, then 45 s if needed.", "")]
+ body = ""
+ for i, (t, h, d, cls) in enumerate(events):
+ x = 56 + i * 222
+ body += box(x, 280, 198, 300, f'
{t}
{h}
{d}
',
+ cls=cls + (" sigshadow" if cls == "" else ""), style="padding:16px 16px")
+ body += ('
NO NETWORK · 40 MINUTES
')
+ lines = "".join(arrow(56 + i * 222 + 202, 430, 56 + (i + 1) * 222 - 6, 430, color="ink", width=3) for i in range(4))
+ out["04-reconnect-timeline"] = figure("FIG 3 · A MORNING OFFLINE", 'WRITE NOW. SYNC LATER.', body,
+ "Nothing waited on the network. The network waited on nothing.", lines=lines, h=700)
+
+ works = ["Write and edit notes", "Checklists", "Search every note", "Pin and delete", "Biometric app lock"]
+ needs = ["First sign-in", "Sync to your Google Drive", "Atomic Energy and coins", "Notifications"]
+ w = "".join(f'
→ {x}
' for x in works)
+ n = "".join(f'
{x}
' for x in needs)
+ body = phone(3, 64, 196, 250, crop=460, shadow="ink")
+ body += box(380, 196, 370, 470, f'
WORKS OFFLINE
EVERYDAY NOTES
{w}
', cls="signal sigshadow")
+ body += box(800, 196, 344, 470, f'
NEEDS A NETWORK
THE CLOUD PARTS
{n}
', cls="surface flat")
+ out["05-atomic-notes-offline"] = figure("FIG 4 · ATOMIC NOTES", 'WHAT WORKS IN AIRPLANE MODE', body,
+ "Notes save to on-device Hive storage first. Only cloud features wait for a connection.", h=740)
+
+ checks = ["Opens with no spinner", "New notes survive a restart", "Search runs offline", "Edits and deletes work", "Sync catches up alone", "Notes live in a place you control"]
+ rows = "".join(f'
'
+ f'{i + 1:02d}{c}'
+ f'
' for i, c in enumerate(checks))
+ body = box(260, 186, 680, 500, f'
SAVE THIS · OFFLINE READINESS
SIX CHECKS
{rows}
', cls="sigshadow")
+ out["06-offline-checklist"] = figure("FIG 5 · THE CHECKLIST", 'IS YOUR NOTES APP OFFLINE READY?', body, h=740)
+ return out
diff --git a/content/blog/atomic-notes-architecture.md b/content/blog/atomic-notes-architecture.md
new file mode 100644
index 0000000..efbe092
--- /dev/null
+++ b/content/blog/atomic-notes-architecture.md
@@ -0,0 +1,199 @@
+---
+title: "Local First Architecture: 4 Layers Behind Atomic Notes"
+slug: "atomic-notes-architecture"
+description: "A walk through a real local first architecture: the device, sync server, user-owned Google Drive, and optional vault behind Atomic Notes, with code and failure modes."
+excerpt: "The phone holds the real copy, a metadata-only server coordinates, your own Google Drive holds the cloud copy, and an optional vault seals it all."
+author: "ashutosh-sharma"
+publishedAt: "2026-10-07"
+updatedAt: "2026-10-07"
+category: "engineering"
+tags: ["local-first", "architecture", "sync", "flutter", "google-drive"]
+featured: false
+draft: false
+coverImage: "/blog/atomic-notes-architecture/01-banner.png"
+coverAlt: "Cover reading Local First Architecture, beside four stacked layer cards: device, sync server, your Drive, and vault"
+canonical: "https://atomic-notes.devbehindyou.com/blog/atomic-notes-architecture"
+keywords: "local first architecture, local first app architecture, atomic notes architecture, Flutter, Hive CE, Hono, MongoDB metadata, Google Drive API, sync engine, request id replay"
+readingTime: "11 min read"
+---
+
+
+
Quick answer
+
Atomic Notes uses a local first architecture with four layers. Your phone holds the real copy in on-device storage. A sync server coordinates devices but stores only metadata. Your own Google Drive holds the cloud copy, one file per note. An optional vault encrypts notes on the phone, so the server and Drive only ever see ciphertext.
+
+
+Most "how it works" pages for notes apps are a diagram with three boxes and an arrow labeled "magic." This isn't one of those.
+
+I designed and built every layer of Atomic Notes, and the code for the app is public. So this is the real local first architecture behind it: what each layer does, what each one can and can't see, what happens when things break, and where the design still falls short.
+
+If you're new to the idea, start with [what a local first notes app is](/blog/what-is-a-local-first-notes-app). This guide is the deep dive.
+
+## What does a local first architecture need?
+
+**Three jobs, kept apart on purpose: store, coordinate, and copy.** Most cloud apps blend all three into one server. A local first app architecture splits them, so no single part can hold your notes hostage.
+
+1. **Store.** The device keeps the authoritative copy and does all the reading and writing.
+2. **Coordinate.** Something has to tell devices what changed, in what order, and settle disagreements.
+3. **Copy.** A durable place for the cloud copy, so a lost phone isn't lost notes.
+
+In Atomic Notes, each job has its own layer, plus a fourth that wraps the other two in encryption when you want it.
+
+## Why not one cloud database, like most apps?
+
+**Because a single database makes the company the owner of your notes by default.** I started there. Early versions of Atomic Notes kept note content in a hosted database, and it was simpler to build. It also meant every note lived on infrastructure I controlled, readable by anyone with database access, and gone if the service ever closed.
+
+Moving to a local first architecture changed three things. The phone became the source of truth, so the app stopped waiting on servers. Note content moved to each user's own Google Drive, so the cloud copy stopped being ours. And the server shrank to MongoDB metadata plus coordination, which is a much smaller thing to protect.
+
+It cost a rewrite of sync, and it's the best design decision in the project. Here's how the Atomic Notes architecture fits together now.
+
+
+
+## Layer 1: what does the device do?
+
+**Everything you touch.** The app is written in Flutter (Dart) with flutter_bloc for state, and every note lives in Hive CE, an on-device database. Writing, editing, search, checklists, and deletes all run against that local copy.
+
+The key design rule: a save finishes on the phone. The note is written to Hive, marked dirty, and the screen updates. No network call sits in that path, which is why the app opens and saves the same way in airplane mode as on Wi-Fi. I cover that behavior in detail in [why notes should work without internet](/blog/why-notes-should-work-offline).
+
+Each note also carries the bookkeeping sync needs: a version number from the server, a fingerprint of its synced content, and a dirty flag. If you edit a note and then undo the change, the fingerprint matches what the cloud already holds, so nothing is uploaded. Small detail, real savings on battery and energy.
+
+## Layer 2: what does the sync server do?
+
+**It coordinates, and it remembers metadata, never your writing.** The server is written in TypeScript on Hono, runs on Vercel in the Mumbai region, and keeps its records in MongoDB Atlas.
+
+On every push, it takes a per-user lock, checks each note's base version, spends Atomic Energy, and records the result, all in one database transaction. Then it writes each note to your Drive, with up to eight writes in flight and retries for slow responses.
+
+In this local first architecture, what the server stores is metadata: note IDs, type, pinned and deleted flags, versions, Drive file IDs, a content hash, and timestamps. The full list is in the guide to [notes app metadata](/blog/notes-app-data-collection). What it never stores is a note title or a line of text.
+
+There's one honest catch in this local first architecture. With the vault off, note text passes through the server on its way to your Drive. It isn't stored, but it is handled. That's why the vault exists.
+
+## Layer 3: why your own Google Drive?
+
+**Because the cloud copy should belong to you, not to us.** Each note becomes its own `.atomic` file, readable JSON, in a My-Atomic-Notes folder in your Google Drive.
+
+The app asks Google for the narrow `drive.file` scope. That means it can only see files it created itself. It can't read your documents, photos, or anything else in your Drive.
+
+User-owned cloud storage changes what a shutdown means. If Atomic Notes disappeared tomorrow, your notes would still be on your phone and in your Drive, as files you can open, copy, or move. That's the part of the Atomic Notes architecture I'm most stubborn about.
+
+The trade: Drive is slower than a database built for sync, and that's the main performance cost of this local first architecture. A single file write takes about 1.5 seconds in production. Batching and parallel writes hide most of it, but it's a real cost, paid for ownership.
+
+## Layer 4: what does the vault change?
+
+**It moves encryption onto the phone, so layers 2 and 3 only ever hold ciphertext.** The vault is optional and off by default.
+
+Turn it on and you get a six-word recovery phrase. The phone stretches it into a 256-bit key with Argon2id (64 MiB, 3 passes), then seals each note's title, body, and checklist items with AES-256-GCM before upload. The key never leaves your devices. The server keeps only a verifier, so a wrong phrase fails without revealing anything.
+
+The [encrypted notes guide](/blog/encrypted-notes-explained) explains the cryptography and has a live demo. For the architecture, the point is simple: the vault changes what the middle layers can see, without changing how sync works.
+
+
+
+## How does one sync actually work?
+
+**Push up, pull down.** The phone pushes its changes in a batch, and other devices pull what they missed.
+
+
+
+Step through one sync below, then switch to a dropped connection to see why retries are safe:
+
+:::widget sync-stepper
+
+The safety comes from one decision: the phone saves the push to disk before sending it, with a fresh request ID. If the connection drops, the retry resends the same saved push. If the server already applied it, it recognizes the ID and returns the stored result. That's request ID replay, and it's why a retry never charges energy twice or writes a duplicate note.
+
+Here's that step in the app's source, trimmed:
+
+
+
+```dart
+// Up to 50 dirty notes per push, sealed if the vault is on.
+final candidates = _notes.values.where((n) => n.dirty).take(_maxPushRows).toList();
+final rows = await Future.wait(candidates.map((n) => _sealRemote(n, uid)));
+
+final pending = {
+ 'requestId': newId(), // the same ID is resent on every retry
+ 'rows': rows,
+ // the base version of each note, so the server can refuse stale edits
+ 'versions': {for (final n in candidates) n.id: n.updatedAt.toIso8601String()},
+ 'conflictIds': {for (final n in candidates) n.id: newId()},
+};
+await _box.put(_pendingPushKey, pending); // saved before it's sent
+```
+
+## What happens when things go wrong?
+
+**Each failure has a defined answer, and none of them is "lose the note."** A local first architecture is only as good as its bad days.
+
+
+
+Two of these deserve a closer look:
+
+- **Two devices edit the same note offline.** Whichever arrives second is based on an old version, so the server refuses it with a conflict. The phone saves that edit as a separate "conflict copy" note. You decide what to keep. Nothing is silently overwritten.
+- **A stale delete.** If one device deletes a note that another device has since edited, the delete is refused. A newer edit always beats an older delete.
+
+Retries follow a fixed schedule of 5, 15, and then 45 seconds. After that, the app waits for the next natural trigger: an edit, the app resuming, or the network coming back.
+
+## What is Atomic Notes built with?
+
+
+
+| Layer | Technology | Holds |
+|---|---|---|
+| Device | Flutter, flutter_bloc, Hive CE | The real copy of every note |
+| Sync server | Hono (TypeScript) on Vercel, MongoDB Atlas | Metadata, versions, sessions, energy |
+| Cloud copy | Google Drive API, `drive.file` scope | One `.atomic` file per note |
+| Vault | Argon2id + AES-256-GCM, on the device | Nothing. It changes what the others hold |
+
+## Where does this local first app architecture fall short?
+
+**Honest limits, all on the roadmap.** A local first architecture is easier to trust when it names its own gaps.
+
+- **Sync only runs while the app is open.** Background sync is planned, not shipped.
+- **Google sign-in is required.** Email sign-in is planned. Until then, the app needs a Google account.
+- **No export button yet.** Your Drive copy is readable JSON, so the way out exists, but a one-tap export is still coming.
+- **No real-time collaboration.** It's a personal notes app. Shared editing would need a very different sync model.
+- **Android only.** A web version and iOS are planned, and the local first architecture was chosen with them in mind.
+
+My view after building it: this local first architecture costs more engineering than a plain cloud app, and every bit of that cost lands in the sync engine. In return, the server can go down, the network can vanish, and the company can disappear, and your notes are still yours.
+
+## FAQ
+
+
+
+What is a local first architecture?
+
It's a design where the device holds the authoritative copy of your data and works without a network, while sync copies changes to the cloud and other devices. The server coordinates rather than owns. Atomic Notes follows this design, with your own Google Drive as the cloud copy.
+
+
+Does the Atomic Notes server store my notes?
+
No. It stores metadata only: IDs, flags, versions, Drive file IDs, and timestamps. Note content goes to your own Google Drive. With the vault off, text passes through the server in transit. With the vault on, the server only handles ciphertext.
+
+
+Why use Google Drive instead of a database?
+
So the cloud copy belongs to you. Your notes stay in your own Drive as readable files, even if the app shuts down. The app's narrow drive.file access means it can only see the files it created, nothing else in your Drive.
+
+
+What happens if two devices edit the same note?
+
The second edit to arrive is based on an old version, so the server refuses it. The phone keeps that edit as a separate conflict copy, and you choose what to keep. Nothing is overwritten without you seeing it.
+
+
+Can I read the Atomic Notes code?
+
Yes. The app is source-available on GitHub, so you can read and verify every layer described here that runs on your phone, including sync and the vault. The license allows reading and verifying, not reuse. The server is private.
+
+
+
+## Keep reading
+
+- [What is a local first notes app, and why does it matter?](/blog/what-is-a-local-first-notes-app)
+- [Encrypted notes explained: T2T vs end to end encryption](/blog/encrypted-notes-explained)
+- [Notes app metadata: 8 things it knows without reading notes](/blog/notes-app-data-collection)
+
+
+
Atomic Notes by DevBehindYou
+
Every layer on your phone is public to read: the Hive storage, the sync engine, and the vault. If something in this guide sounds too good, check the code. Browse the source on GitHub.
+
+
+## Sources
+
+- [Local-first software: you own your data, in spite of the cloud. Ink & Switch, 2019](https://www.inkandswitch.com/essay/local-first/)
+- [Choose Google Drive API scopes. Google for Developers](https://developers.google.com/workspace/drive/api/guides/api-specific-auth)
+- [hive_ce. pub.dev](https://pub.dev/packages/hive_ce)
+- [Hono web framework](https://hono.dev/)
+- [Argon2 memory-hard function, RFC 9106. IETF](https://www.rfc-editor.org/rfc/rfc9106)
+- [Atomic Notes source code. GitHub](https://github.com/DevBehindYou/Atomic-Notes-App-V0.2)
diff --git a/content/blog/best-privacy-first-notes-apps-android.md b/content/blog/best-privacy-first-notes-apps-android.md
new file mode 100644
index 0000000..d1b69f5
--- /dev/null
+++ b/content/blog/best-privacy-first-notes-apps-android.md
@@ -0,0 +1,241 @@
+---
+title: "7 Best Private Notes Apps for Android in 2026"
+slug: "best-privacy-first-notes-apps-android"
+description: "The 7 best private notes apps for Android in 2026, checked for ads, trackers, permissions, encryption, and sync. Find the private notes app Android users can trust."
+excerpt: "No ads, no trackers, public source code. Seven private notes apps for Android, each checked on October 7, 2026, with honest limits."
+author: "ashutosh-sharma"
+publishedAt: "2026-10-07"
+updatedAt: "2026-10-07"
+category: "privacy"
+tags: ["privacy", "android", "notes-apps", "comparison", "encryption"]
+featured: false
+draft: false
+coverImage: "/blog/best-privacy-first-notes-apps-android/01-banner.png"
+coverAlt: "Cover reading 7 Best Private Notes Apps for Android, beside a numbered list of seven apps checked in October 2026"
+canonical: "https://atomic-notes.devbehindyou.com/blog/best-privacy-first-notes-apps-android"
+keywords: "private notes app android, best private notes app, secure notes app android, privacy first notes app, F-Droid, no ads, encrypted sync, offline access, local storage, data safety section"
+readingTime: "11 min read"
+---
+
+
+
Quick answer
+
The best private notes app for Android depends on what you need. Atomic Notes syncs to your own Google Drive with an optional end-to-end vault. SilentNotes encrypts everything and syncs to storage you pick. NoteSR, CypherLeaf, Fossify Notes, and Privacy Friendly Notes never touch the internet. Quillpad syncs through your own Nextcloud.
+
+
+Search the Play Store for a private notes app and you'll find hundreds of them. Many show ads. Some ship analytics SDKs. A few ask for your contacts. "Private" on an app icon is a marketing word, not a promise.
+
+So I set rules first and picked apps second. Every private notes app Android users will find below has no ads, no trackers, public source code, and a release or code update in 2026. I checked each one on October 7, 2026, including its Android permissions.
+
+One disclosure up front: Atomic Notes is my app, so it goes first. Its facts are checkable in its public code, and its weak spots are listed like everyone else's.
+
+## What makes a notes app private on Android?
+
+**Four things, in this order: where notes are stored, whether the app can reach the internet, who holds the key to any synced copy, and how the app makes money.** Everything else is detail.
+
+- **Storage.** A privacy first notes app keeps notes in local storage on your phone by default. Cloud sync should be a choice, not the starting point.
+- **Network access.** Android only lets an app use the internet if it asks for that permission. No internet permission means your notes can't leave through the app, ever.
+- **The synced copy.** If an app syncs, encrypted sync or storage you own makes the difference between a backup and a copy someone else can read.
+- **The money.** Ads and analytics pay for many free apps. A private notes app Android users can trust is funded by its users or its community instead.
+
+Offline access matters too. Every app on this list opens and saves with no connection, which is the baseline for any notes app worth trusting.
+
+## How did these apps make the list?
+
+**Six rules, applied to every app, including mine.** Popular apps that failed any of them were left out on purpose.
+
+
+
+The rules exist because the Play Store's data safety section is self-declared by developers. A label can say "no data collected" and still be wrong. Public code, a permission list, and a recent release are harder to fake.
+
+Here's the whole list at a glance:
+
+
+
+Not sure where to start? Tell the finder what you need:
+
+:::widget app-finder
+
+## The 7 best private notes apps for Android
+
+Each entry lists where notes live, how they're protected, what the app is allowed to reach, and the one thing to watch out for.
+
+### 1. Atomic Notes
+
+**Pick it for:** syncing across devices without your notes ever landing in a company database.
+
+- **Storage:** written to the phone as you type, then copied to a My-Atomic-Notes folder in your own Google Drive
+- **Protection:** a vault you can switch on (Argon2id key, AES-256-GCM per note). It starts switched off.
+- **Tracking:** none. No ads, analytics, crash reporting, or AI features.
+- **Can reach:** the internet for sync, network state, and the fingerprint lock
+- **Source:** public on GitHub under a source-available license (read and verify, no reuse)
+- **Latest:** version 2.03.5, released September 28, 2026
+- **Trade-off:** sign-in needs a Google account, a one-tap export is still coming, and the free plan stops at 30 notes
+
+
+
+Atomic Notes is the private notes app Android users should reach for when they want sync but refuse to hand their writing to someone else's server. Its server tracks only metadata, and the files in your Drive are yours to open. The [four-layer architecture guide](/blog/atomic-notes-architecture) shows exactly how.
+
+### 2. SilentNotes
+
+**Pick it for:** encryption you can't forget to turn on.
+
+- **Storage:** on the device, with sync through FTP, WebDAV, Dropbox, Google Drive, or OneDrive, whichever you set up
+- **Protection:** every note is encrypted before it leaves the phone, with no plain-text mode
+- **Tracking:** the project says it gathers no user information
+- **Can reach:** the internet and network state, for sync
+- **Source:** open source under MPL-2.0
+- **Latest:** version 8.8.7, October 5, 2026
+- **Trade-off:** it runs on Android and Windows only, and the design is deliberately plain
+
+You supply the cloud storage and SilentNotes seals each note before it gets there, so the storage provider holds only ciphertext. It also shipped a new release in October 2026.
+
+### 3. CypherLeaf
+
+**Pick it for:** a notebook that lives on one phone and stays there.
+
+- **Storage:** device only, and you never create an account
+- **Protection:** notes you mark as protected are sealed with AES-GCM, using keys kept in the Android Keystore. Backups are encrypted too.
+- **Tracking:** nothing, and the app has no internet permission to send anything with
+- **Can reach:** notifications, start at boot, and the biometric lock
+- **Source:** open source under MIT
+- **Latest:** version 1.0.1, which joined F-Droid on September 3, 2026
+- **Trade-off:** it's very new, and there's no way to sync
+
+Even at version 1.0.1, CypherLeaf covers folders, tags, reminders, and backups you can restore later.
+
+### 4. NoteSR
+
+**Pick it for:** keeping sensitive notes and the files that go with them in one sealed place.
+
+- **Storage:** on the phone, with no account and no cloud of any kind
+- **Protection:** notes and attachments are encrypted with AES-256, and exports stay encrypted
+- **Tracking:** none, and no internet permission
+- **Can reach:** storage access and a background service used for exports
+- **Source:** open source under MIT
+- **Latest:** version 5.6.0 on F-Droid
+- **Trade-off:** it requires Android 10 or newer, and making backups is your job
+
+Think of NoteSR as a safe for journals, scans, and documents. For anyone who never wants a cloud copy, it's the most secure notes app Android offers on this list.
+
+### 5. Quillpad
+
+**Pick it for:** writing in Markdown, with sync through a Nextcloud you run yourself.
+
+- **Storage:** on the phone, plus optional sync to your own Nextcloud server
+- **Protection:** no note encryption, though notes can be hidden from the main list
+- **Tracking:** no ads and no trackers
+- **Can reach:** the internet for Nextcloud, and the microphone for voice notes
+- **Source:** open source under GPL-3.0
+- **Latest:** version 1.5.14, September 3, 2026
+- **Trade-off:** syncing requires the Notes app installed on your Nextcloud server
+
+For Nextcloud owners, Quillpad makes private sync feel easy. Without Nextcloud, it still works as a clean offline Markdown notebook.
+
+### 6. Fossify Notes
+
+**Pick it for:** fast lists and notes pinned to your home screen.
+
+- **Storage:** device only
+- **Protection:** no encryption, but individual notes can sit behind a password, pattern, or fingerprint
+- **Tracking:** no ads, and it can't go online at all
+- **Can reach:** storage, alarms for reminders, and home screen widgets
+- **Source:** open source under GPL-3.0
+- **Latest:** version 1.7.0 from January 30, 2026, with code updates continuing through 2026
+- **Trade-off:** minimal on purpose, and nothing syncs
+
+Fossify Notes is the quickest route to a private checklist on your home screen. Fossify is a community project that continues the Simple Mobile Tools apps, without ads or tracking.
+
+### 7. Notes (Privacy Friendly)
+
+**Pick it for:** mixing typed notes, checklists, voice memos, and sketches with very few permissions.
+
+- **Storage:** on the phone, with exports saved to device storage
+- **Protection:** none built in
+- **Tracking:** no ads, and no internet permission
+- **Can reach:** the camera and microphone, used only for photo and audio notes
+- **Source:** open source under GPL-3.0
+- **Latest:** version 2.2.2, June 15, 2026
+- **Trade-off:** there's no sync and no encryption
+
+It comes from the SECUSO research group at the Karlsruhe Institute of Technology, which publishes a whole family of Privacy Friendly Apps.
+
+## Which private notes app for Android fits you?
+
+**Start with one question: do you need sync?** If you don't, the four offline-only apps give you the smallest possible footprint. If you do, choose by where the synced copy lives.
+
+
+
+| If you want | Pick |
+|---|---|
+| Sync to storage you own, with an optional vault | Atomic Notes |
+| Encryption that's always on, plus sync | SilentNotes |
+| Encrypted notes and files, never online | NoteSR |
+| A new offline notebook with locked notes | CypherLeaf |
+| Markdown and your own Nextcloud | Quillpad |
+| Fast checklists and widgets | Fossify Notes |
+| Audio and sketch notes, few permissions | Notes (Privacy Friendly) |
+
+## Which apps can even reach the internet?
+
+**Four of the seven can't.** An app without the internet permission has no way to send your notes anywhere by itself. That's the strongest privacy guarantee Android offers, and it's checkable.
+
+
+
+The trade is the same every time: no internet means no sync and no cloud backup. If you pick an offline-only app, copy its export to a safe place now and then. If you pick a syncing app, check where the synced copy lives and who holds its key. That's the real difference between a secure notes app Android users can trust and one that only says so. My [notes app privacy checklist](/blog/notes-app-privacy-red-flags) covers the other eight things to check.
+
+## Why aren't Google Keep, Notesnook, or Standard Notes here?
+
+**Google Keep** fails the rules: notes live in your Google account, readable by Google, with no end-to-end encryption. It's convenient, not private by design.
+
+**Notesnook, Standard Notes, and Joplin** are excellent encrypted apps with encrypted sync. They're cross-platform first rather than Android-first, and I'm covering them in a separate guide to end-to-end encrypted notes apps, so this list stays unique.
+
+## FAQ
+
+
+
+What is the best private notes app for Android?
+
For sync you control, Atomic Notes, which saves to your own Google Drive with an optional vault. For always-on encryption, SilentNotes. For notes that never leave the phone, NoteSR. All three have no ads, no trackers, and public code.
+
+
+Are F-Droid notes apps always private?
+
Mostly, though it's worth a look. F-Droid compiles each app from its public code and labels anti-features such as tracking. The permission list is the final word: with no internet permission, an app has no way to send your notes off the phone.
+
+
+Does a private notes app need encryption?
+
For notes that stay on the phone, your screen lock already does most of the work. The moment notes sync to a cloud, encryption becomes important, because end-to-end encryption is what stops the storage provider from reading the copy it holds.
+
+
+Which Android notes apps work without internet?
+
CypherLeaf, NoteSR, Fossify Notes, and Privacy Friendly Notes have no internet permission at all. Atomic Notes, SilentNotes, and Quillpad work fully offline too, and sync when a connection returns.
+
+
+Are free private notes apps safe?
+
Free isn't the risk. Ads and analytics are. Every app here is free to use, and none shows ads or ships trackers. The open source apps here are community or research projects, and Atomic Notes is funded by the people who use it.
+
+
+Why is Atomic Notes first on this list?
+
Because it's my app, and I'd rather say so than hide it. Every fact on its card is checkable in its public source code, and its limits are listed: a Google account is required, there's no export button yet, and the free tier holds 30 notes.
+
+
+
+## Keep reading
+
+- [Notes app privacy: 9 red flags to check](/blog/notes-app-privacy-red-flags)
+- [Encrypted notes explained: T2T vs end to end encryption](/blog/encrypted-notes-explained)
+- [What is a local first notes app?](/blog/what-is-a-local-first-notes-app)
+
+
+
Atomic Notes by DevBehindYou
+
A private notes app for Android that keeps your notes on your phone and in your own Google Drive, never in our database. No ads, no trackers, no AI, and an optional end-to-end vault. See how it works.
+
+
+## Sources
+
+- [Atomic Notes source code and releases. GitHub](https://github.com/DevBehindYou/Atomic-Notes-App-V0.2)
+- [SilentNotes. GitHub](https://github.com/martinstoeckli/SilentNotes)
+- [CypherLeaf. F-Droid](https://f-droid.org/en/packages/io.gitlab.jrock902.cypherleaf/)
+- [NoteSR. F-Droid](https://f-droid.org/en/packages/app.notesr/)
+- [Quillpad. F-Droid](https://f-droid.org/en/packages/io.github.quillpad/)
+- [Fossify Notes. GitHub](https://github.com/FossifyOrg/Notes)
+- [Notes (Privacy Friendly). F-Droid](https://f-droid.org/en/packages/org.secuso.privacyfriendlynotes/)
+- [Provide information for Google Play's data safety section. Play Console Help](https://support.google.com/googleplay/android-developer/answer/10787469?hl=en)
diff --git a/content/blog/encrypted-notes-explained.md b/content/blog/encrypted-notes-explained.md
new file mode 100644
index 0000000..1f21558
--- /dev/null
+++ b/content/blog/encrypted-notes-explained.md
@@ -0,0 +1,209 @@
+---
+title: "Encrypted Notes Explained: T2T vs End to End Encryption"
+slug: "encrypted-notes-explained"
+description: "Encrypted notes can mean three very different things. End to end encryption explained in plain English, how T2T differs, and what a vault really protects."
+excerpt: "\"Encrypted\" can mean HTTPS, encrypted disks, or end-to-end. Only one keeps the company out of your notes. Here's how to tell them apart."
+author: "ashutosh-sharma"
+publishedAt: "2026-10-07"
+updatedAt: "2026-10-07"
+category: "security"
+tags: ["encryption", "security", "end-to-end", "vault", "privacy"]
+featured: false
+draft: false
+coverImage: "/blog/encrypted-notes-explained/01-banner.png"
+coverAlt: "Cover reading Encrypted Notes, Explained, beside two code cards: a readable note with the vault off and a ciphertext payload with the vault on"
+canonical: "https://atomic-notes.devbehindyou.com/blog/encrypted-notes-explained"
+keywords: "encrypted notes, end to end encryption explained, what is end to end encryption, T2T, TLS, AES-256-GCM, Argon2id, recovery phrase, ciphertext, threat model"
+readingTime: "10 min read"
+---
+
+
+
Quick answer
+
Encrypted notes can be locked in three places: on the network (HTTPS), on the company's disks (encryption at rest), or on your own device before anything leaves it (end-to-end). Only end-to-end encryption keeps the company itself from reading your notes. The other two protect against outsiders, not against the app.
+
+
+Almost every notes app promises encrypted notes. Most of them are telling the truth. And most of them can still read every word you write.
+
+That isn't a contradiction. "Encrypted" describes a lock, and a lock only matters if you know who holds the key. Apple, for example, encrypts iCloud data by default but keeps the keys for most of it, unless you turn on Advanced Data Protection.
+
+I build Atomic Notes, which offers both kinds: plain transport encryption by default, and an optional vault for end-to-end encrypted notes. Here's what each one actually protects, with a live demo you can run in this page.
+
+## What does "encrypted notes" really mean?
+
+**It means a lock exists somewhere between your thumb and the server's disk.** Where that lock sits decides who can open it.
+
+There are three common places:
+
+1. **In transit.** HTTPS (TLS) scrambles your note while it travels. Someone on the same café Wi-Fi sees noise. The server unwraps it on arrival and reads it.
+2. **At rest.** The company encrypts the disks its data sits on. A thief who steals a hard drive gets nothing. The company, which holds the disk keys, still reads everything.
+3. **End-to-end.** Your device encrypts the note before it leaves, with a key only you have. The server stores ciphertext it can't open.
+
+
+
+So when an app advertises encrypted notes, the useful follow-up is always: encrypted where, and with whose key? Pick a model below and see who can still read the note.
+
+:::widget who-can-read
+
+## What is end to end encryption?
+
+**End-to-end encryption means only the "ends" of the conversation can read the data: your devices.** Everything in the middle, including the company's servers, only ever handles ciphertext.
+
+Here's end to end encryption explained in four steps, using encrypted notes as the example:
+
+1. **You create a secret.** Usually a password or a recovery phrase that never leaves your devices.
+2. **Your device turns it into a key.** A slow key derivation function stretches the secret into a strong 256-bit key, so guessing it by brute force stays impractical.
+3. **Your device seals each note.** A cipher like AES-256-GCM turns the note into ciphertext and adds a tag that detects tampering.
+4. **Only ciphertext travels.** The server stores it, syncs it, and backs it up without ever being able to read it.
+
+The defining detail is the key. If the company ever holds a copy, the system isn't end-to-end, however strong the cipher is. That's why "military-grade encryption" means nothing on its own: AES is the same lock everywhere. The question is always who holds the key.
+
+## How do T2T and the vault differ in Atomic Notes?
+
+**T2T is Atomic Notes' name for plain transport encryption, and it's the default.** The vault is the optional end-to-end mode. They protect very different things, so here they are side by side.
+
+
+
+With T2T, your note travels over HTTPS to the sync server, which passes it straight into a `.atomic` file in your own Google Drive. The server never stores the text, but it does handle it in transit, and the file in your Drive is readable by you and by anyone who gets into your Google account. For a grocery list, that's fine.
+
+With the vault on, your phone encrypts the title, body, and checklist items before anything leaves. The server and Google only ever see ciphertext. Try it below with real AES-256-GCM, running in your browser:
+
+:::widget encryption-playground
+
+Notice two things. The ciphertext changes every time, because each save uses a fresh random 12-byte nonce. And changing a single word of the phrase makes decryption fail outright, because the 16-byte authentication tag no longer matches.
+
+## How does the Atomic Notes vault work?
+
+**Six words become a key, the key never leaves your phone, and every note is sealed before upload.** These are the exact parameters in the 2.03.5 source code.
+
+
+
+- **The phrase.** Six words drawn at random from a 1,024-word list, which gives 60 bits of entropy. It's shown once and never sent anywhere.
+- **The key derivation.** Argon2id with 64 MiB of memory and 3 passes. Memory-hard on purpose: every guess costs an attacker real hardware. The salt is a SHA-256 hash of an app tag and your account ID, so the same phrase gives the same key on every device.
+- **The cipher.** AES-256-GCM with a 12-byte nonce and a 16-byte tag, the standard NIST mode for authenticated encryption.
+- **The verifier.** The server stores a known phrase sealed with your key. When you open the vault on a new device, a wrong phrase fails the check, and the server learns nothing about your key.
+
+Here's the sealing code, trimmed from the public source:
+
+
+
+```dart
+static Future deriveKey(String phrase, List salt,
+ {required int memory, required int iterations, required int parallelism}) {
+ final argon = Argon2id(
+ memory: memory, // 65536 KiB, so 64 MiB per guess
+ iterations: iterations, // 3 passes
+ parallelism: parallelism,
+ hashLength: 32, // a 256-bit key
+ );
+ return argon.deriveKeyFromPassword(password: phrase, nonce: salt);
+}
+
+/// Returns base64(nonce ++ ciphertext ++ mac).
+static Future seal(List clear, SecretKey key) async {
+ final box = await aes.encrypt(clear, secretKey: key); // AES-256-GCM
+ return base64Encode(box.concatenation());
+}
+```
+
+Anyone can read this file and check that the key is derived on the device and never sent. That's the point of public source code for encrypted notes: you don't have to take the claim on trust.
+
+One more practical detail. Argon2id is slow on purpose, but it only runs when you open the vault, not on every save. After that, each note is sealed as you save it, so the optional vault doesn't add a spinner to your writing.
+
+## How can you check an app's encrypted notes claims?
+
+**Ask five questions, and expect a plain answer to each one.** If an app's security page can't answer them, treat its encrypted notes as a marketing line.
+
+1. **Where does encryption happen?** On your device before upload, or only on the network and the server's disks?
+2. **Who holds the key?** You alone, or a copy on the company's side "for recovery"?
+3. **Is it on by default?** Some apps encrypt every note. Others, like Atomic Notes, make end-to-end optional and say so.
+4. **What stays visible?** Every app keeps some metadata. A good one names it.
+5. **Can you check?** Public source code, an independent audit, or at least a detailed write-up of the key derivation and the cipher.
+
+Here are the terms you'll meet while checking, in one place:
+
+| Term | What it means |
+|---|---|
+| TLS or HTTPS | Encryption on the network. Protects the trip, not the destination. |
+| Encryption at rest | Encrypted disks. Protects against stolen hardware. The provider keeps the keys. |
+| End-to-end encryption | Your devices encrypt and decrypt. Servers only handle ciphertext. |
+| Key derivation | Turning a password or phrase into a strong key. Argon2id is a modern choice. |
+| Nonce | A random number used once, so the same note never encrypts the same way twice. |
+| Authentication tag | A short checksum that fails loudly if the ciphertext or the key is wrong. |
+| Ciphertext | The scrambled output. Useless without the key. |
+
+## What can't encrypted notes hide?
+
+**End-to-end encryption hides what you wrote, not the fact that you wrote it.** Every sync service needs some metadata to do its job, and that metadata stays visible.
+
+
+
+In Atomic Notes, the vault seals the title, body, and checklist items. The server can still see that a note exists, whether it's a text note or a checklist, whether it's pinned or deleted, when it changed, and roughly how large it is. That's enough to sync without conflicts. It's also enough to show patterns, which is why metadata deserves its own guide.
+
+Any app that claims its encrypted notes hide "everything" either syncs nothing or is overselling. The honest version is: content hidden, metadata kept small, and the remaining metadata named in public.
+
+## What does end-to-end encryption cost you?
+
+**Recovery.** If only you hold the key, only you can recover your notes. Lose the phrase and nobody can help, including the developer.
+
+
+
+This is the honest trade at the heart of encrypted notes, and no clever design removes it. Services that can reset your password for you can also, by design, decrypt your data. Services that can't, can't. Some apps offer a recovery key you store yourself, which helps, but it's still a second copy of the secret that you have to protect.
+
+So before you choose between plain and encrypted notes, start with your threat model. It's a plain question: who are you protecting these notes from?
+
+| If you worry about | You need | Atomic Notes setting |
+|---|---|---|
+| Someone on public Wi-Fi | HTTPS | T2T, on by default |
+| A stolen server disk | Encryption at rest | Your Drive's own encryption |
+| The app company, a breach, or a legal request | End-to-end encryption | Turn on the vault |
+| Someone holding your unlocked phone | A device lock | Biometric app lock |
+
+My take after building both modes: most notes don't need the vault, and some encrypted notes really do earn their keep. Health, money, and anything about other people's safety belong behind a key only you hold. If you're unsure, turn the vault on for a week and watch for any difference in how you write. Once it's open, encrypted notes save and search like any others, so the only real cost is keeping the phrase safe.
+
+## FAQ
+
+
+
+Are encrypted notes safe from the app company?
+
Only if they're end-to-end encrypted. HTTPS and encryption at rest stop outsiders, but the company still holds the keys and can read your notes. With end-to-end encryption, the company stores ciphertext it has no way to open.
+
+
+What is end to end encryption, explained simply?
+
Your device locks the note before it leaves, with a key that never leaves your devices. Servers in the middle store and sync the locked version but can't open it. Only your own devices, with your key, can read it again.
+
+
+What does T2T mean in Atomic Notes?
+
T2T is the default transport encryption mode. Notes travel over HTTPS and are saved as readable files in your own Google Drive. The sync server handles the text in transit but never stores it. Turn on the vault for end-to-end encryption.
+
+
+Do encrypted notes still work offline?
+
Yes, in Atomic Notes. Notes save on the phone first, vault on or off, and sync later. Encrypted notes are sealed on the device, so encryption never needs a network. You do need a connection to sync, and to set up the vault the first time.
+
+
+What happens if I lose my recovery phrase?
+
Vault notes stay encrypted forever. The phrase is the only way to rebuild the key, and nobody else holds a copy, including the developer. Write it down and keep it somewhere safe and offline, not in a notes app.
+
+
+Is AES-256-GCM enough to keep notes private?
+
The cipher is strong, but it's only half the story. What matters is who holds the key and what metadata stays visible. AES-256-GCM with a company-held key protects you from thieves, not from the company itself.
+
+
+
+## Keep reading
+
+- [Local first architecture: the 4 layers behind Atomic Notes](/blog/atomic-notes-architecture)
+- [Notes app metadata: 8 things it knows without reading notes](/blog/notes-app-data-collection)
+- [Notes app privacy: 9 red flags to check](/blog/notes-app-privacy-red-flags)
+
+
+
Atomic Notes by DevBehindYou
+
Turn on the vault and your notes are sealed with AES-256-GCM on your phone, behind a six-word phrase only you know. The sync server and Google only ever store ciphertext. Read the vault code.
+
+
+## Sources
+
+- [Advanced Encryption Standard (AES), FIPS 197. NIST](https://csrc.nist.gov/pubs/fips/197/final)
+- [Galois/Counter Mode (GCM), SP 800-38D. NIST](https://csrc.nist.gov/pubs/sp/800/38/d/final)
+- [Argon2 memory-hard function, RFC 9106. IETF](https://www.rfc-editor.org/rfc/rfc9106)
+- [iCloud data security overview. Apple Support](https://support.apple.com/en-us/102651)
+- [Atomic Notes vault source code. GitHub](https://github.com/DevBehindYou/Atomic-Notes-App-V0.2)
diff --git a/content/blog/notes-app-data-collection.md b/content/blog/notes-app-data-collection.md
new file mode 100644
index 0000000..b801a46
--- /dev/null
+++ b/content/blog/notes-app-data-collection.md
@@ -0,0 +1,208 @@
+---
+title: "Notes App Metadata: 8 Things It Knows Without Reading Notes"
+slug: "notes-app-data-collection"
+description: "Notes app metadata can reveal your routine without a single word of your notes. The 8 kinds of notes app data collection to know, and what's actually needed."
+excerpt: "Encryption can hide what you wrote. It can't hide when, where, and how often you write. Here's what a notes app can know without reading a note."
+author: "ashutosh-sharma"
+publishedAt: "2026-10-07"
+updatedAt: "2026-10-07"
+category: "privacy"
+tags: ["privacy", "metadata", "data-minimization", "tracking", "encryption"]
+featured: false
+draft: false
+coverImage: "/blog/notes-app-data-collection/01-banner.png"
+coverAlt: "Cover reading Notes App Metadata, beside a server log card with sync times and events but no note text"
+canonical: "https://atomic-notes.devbehindyou.com/blog/notes-app-data-collection"
+keywords: "notes app metadata, notes app data collection, apps that don't collect data, IP address, device model, login timestamps, sync activity, server logs, retention period, privacy policy"
+readingTime: "10 min read"
+---
+
+
+
Quick answer
+
Notes app metadata is everything around your notes: your email, IP address, device, sign-in times, sync activity, how often you open the app, and when notes change. None of it needs a word of what you wrote, yet together it can reveal your routine, your location, and your life events. Encryption hides content. Only collecting less hides metadata.
+
+
+"Metadata absolutely tells you everything about somebody's life." That's Stewart Baker, a former general counsel of the NSA, as quoted by law professor David Cole in 2014. He meant it as a plain description of how surveillance works.
+
+Notes apps don't run spy agencies. But every one that syncs keeps some notes app metadata, and most keep more than they need. That data sits in logs and analytics tools long after you forget the note.
+
+I build Atomic Notes, so I've had to decide what our own server keeps. This guide covers the eight kinds of metadata a notes app can know about you, what each one reveals, which ones a sync service actually needs, and how to check any app.
+
+## What is notes app metadata?
+
+**Metadata is data about your notes, not the notes themselves.** If content is the letter, metadata is the envelope: who sent it, when, from where, and how heavy it was.
+
+
+
+This split matters because the two are protected in different ways. End-to-end encryption can make your note text unreadable to the company. It does nothing for notes app metadata, because the server needs some of it just to sync. The only protection for metadata is a company that collects little, keeps it briefly, and tells you exactly what it keeps.
+
+## The 8 things a notes app can know without reading your notes
+
+
+
+### 1. Your account email
+
+Almost every syncing app needs an account email, and it ties every other piece of notes app metadata to your real identity. Ask whether it's ever shared, and whether deleting your account deletes it.
+
+### 2. Your IP address
+
+Every request carries one, so the server sees it whether it wants to or not. IP address tracking reveals your rough location and when it changes. The question is how long the app keeps it, and whether it lands in analytics.
+
+### 3. Your device model
+
+Device information helps spot a suspicious sign-in. It also reveals what you own and when you switch phones. Combined with screen size, fonts, and settings, it can feed device fingerprinting, which identifies you without any cookie.
+
+### 4. Your OS and app version
+
+Useful for support, and harmless on its own. It also shows how current your phone is, which can hint at how exposed it is to known bugs.
+
+### 5. Your sign-in times
+
+Login activity shows when your day starts and from where. A new sign-in from a strange country is worth flagging. A full history of every sign-in is worth questioning.
+
+### 6. Your sync activity
+
+Sync metadata says when you write and how much. A sync at 23:52 every night is a habit. A burst of small notes from a hospital network on a Thursday afternoon is a story.
+
+### 7. How often you use the app
+
+Usage analytics, the screens you open and how long you stay, is the most common extra a notes app collects. It powers product dashboards. It isn't needed to sync a single note.
+
+### 8. Your note counts and edit times
+
+How many notes you have, when each one changed, and roughly how big it is. Even when every note is encrypted, this part of notes app metadata shows the shape of your thinking over time.
+
+## What can notes app metadata reveal?
+
+**More than any single note.** One timestamp means nothing. A month of them is a diary of your habits. Click through the example below. It's a made-up week of sync events, the kind a server could log, with zero note content.
+
+:::widget metadata-inference
+
+Now picture that pattern as a chart. This is the kind of view anyone with access to the logs could build in a few minutes:
+
+
+
+The EFF gives a blunt example: call metadata can show that someone spoke with an HIV testing service, then their doctor, then their health insurer within the same hour, without anyone hearing a word. Notes app metadata works the same way. The when and where often tell the story the what was meant to keep private.
+
+## Which notes app data collection is actually necessary?
+
+**A sync service needs a little metadata. Everything past that is a business decision.** This is the principle of data minimization, written into Article 5 of the GDPR: collect only what you need, for a stated purpose, and keep it only as long as you need it.
+
+
+
+Here's the practical test. For every piece of data, ask two questions: would sync break without it, and how many days is it kept? A good answer names a retention period. "As long as necessary" isn't a number.
+
+| Ask the app | A good answer sounds like |
+|---|---|
+| What do you store about each note? | "IDs, timestamps, and sync versions. Never the text." |
+| Do you keep IP addresses? | "Only in request logs, deleted after a fixed number of days." |
+| Which analytics do you run? | "None in the app," or a named, privacy-friendly tool. |
+| How long do you keep logs? | A specific retention period, like 30 days. |
+| What happens when I delete my account? | "Everything tied to it is deleted," with a timeline. |
+
+## How do you check what a notes app collects?
+
+**Read three things, and ask for a fourth.** Mapping an app's notes app metadata takes about fifteen minutes.
+
+1. **The store label.** Google Play's data safety section lists what the developer says is collected. It's self-declared, so treat it as a starting point. My [notes app privacy guide](/blog/notes-app-privacy-red-flags) explains why.
+2. **The privacy policy.** Search for "collect," "analytics," "third parties," "retain," and "IP." Vague phrases usually mean more collection, not less.
+3. **A tracker scan.** Exodus Privacy lists the analytics and advertising SDKs inside an Android app. Usage analytics almost always arrives through one of these.
+4. **Your own data.** In many places, privacy law lets you ask a company for a copy of what it holds about you. The answer often shows server logs nobody mentioned.
+
+## Why do notes apps collect more than they need?
+
+**Because metadata is cheap to keep and useful to almost every team except yours.** Product teams want usage analytics to see which features people use. Growth teams want device and location data to measure campaigns. Support wants long logs for the rare hard bug. Advertising, if the app has any, wants all of it.
+
+None of that is sinister on its own. The problem is accumulation. Notes app data collection tends to grow one reasonable request at a time, and nobody goes back to delete old logs. Years later, the company holds a detailed timeline of your writing habits that it never set out to build.
+
+That's why the useful question isn't "does this app collect notes app metadata?" Every syncing app does. The useful question is whether the list is short, written down, and on a deletion schedule.
+
+## What does Atomic Notes keep?
+
+**Metadata only, and here's the list.** Our server never stores note titles or text, with the vault on or off. This is our full notes app data collection, in plain words. It does keep what sync and security need, and some of that is personal, so it belongs in public.
+
+
+
+This is the shape of what the server stores for one note. The field names come from the server's schema, and the values here are made up:
+
+
One note's record on the Atomic Notes server · example values
+
+```json
+{
+ "_id": "3f2a9c41-8b2e-4c1d-9e57-0a6f2d1b7c90",
+ "userId": "b81e4f02-5d7a-4c3b-a1e9-62c0f8d4a3e1",
+ "kind": "todo",
+ "pinned": false,
+ "deleted": false,
+ "encV": 1,
+ "driveFileId": "1AbCdEfGhIjKlMnOpQrStUvWxYz",
+ "localVersion": 7,
+ "contentHash": "9c1f0e…",
+ "syncStatus": "synced",
+ "createdAt": "2026-09-30T21:14:02Z",
+ "updatedAt": "2026-10-06T23:52:11Z"
+}
+```
+
+No title, no body, no checklist items. With the vault on, `encV` is 1 and the note's file in your Drive holds only ciphertext. With it off, the text goes to your Drive in readable form, passing through the server on the way without being stored.
+
+The rest of the list:
+
+- **Account:** your email and display name, from your Google sign-in.
+- **Sessions:** a SHA-256 hash of each session token, never the token itself, plus the device's user agent and an expiry date. You can see and revoke sessions.
+- **Energy ledger:** changes to your Atomic Energy and coin balance.
+- **Security log:** sign-ins and sync events, deleted automatically after 30 days. Deleted notes' records are cleared after 30 days too.
+- **Not collected:** analytics, advertising IDs, location, contacts, and crash reports. The app ships none of those SDKs.
+
+Two honest footnotes. Our hosting provider sees IP addresses with every request, like any web service. And this website uses a cookieless page analytics tool, separate from the app, which never sees your notes.
+
+## Are there apps that don't collect data at all?
+
+**Yes, if they never sync.** An app with no internet permission can't send anything anywhere, so it collects nothing on a server. Several private Android notes apps work this way, and I list them in the [best private notes apps for Android](/blog/best-privacy-first-notes-apps-android).
+
+The catch is the same one every time: no sync means no backup and no second device, unless you copy files yourself. Any app that syncs keeps some notes app metadata, because sync can't work without it. Apps that don't collect data in the strict sense don't sync. The realistic goal for a syncing app is the smallest possible list, with a short retention period, published in plain words.
+
+## FAQ
+
+
+
+What is notes app metadata?
+
It's the data around your notes rather than the notes themselves: your account email, IP address, device, sign-in times, sync activity, how often you use the app, and when each note changes. It can reveal a lot about you even when every note is encrypted.
No. End-to-end encryption hides what you wrote. The server still needs some metadata to sync, such as note IDs, versions, and timestamps. The best protection for metadata is collecting as little as possible and deleting it on a fixed schedule.
+
+
+Can a notes app track my location?
+
Without location permission, it can't read your GPS. It still sees your IP address with every sync, which gives a rough location. Check whether the app stores IP addresses, for how long, and whether it sends them to analytics or advertising tools.
+
+
+How do I find out what data a notes app has on me?
+
Read its privacy policy and store data safety label first. Then ask the company for a copy of your data, which privacy laws in many regions require it to provide. The response usually lists logs and metadata the policy only hinted at.
+
+
+Are there notes apps that don't collect data?
+
Yes. Apps without internet permission keep everything on your phone and collect nothing on a server. The trade-off is no sync. Syncing apps always keep some metadata, so look for a short, published list and fixed retention periods.
+
+
+
+## Keep reading
+
+- [Notes app privacy: 9 red flags to check](/blog/notes-app-privacy-red-flags)
+- [Encrypted notes explained: T2T vs end to end encryption](/blog/encrypted-notes-explained)
+- [Local first architecture: the 4 layers behind Atomic Notes](/blog/atomic-notes-architecture)
+
+
+
Atomic Notes by DevBehindYou
+
No analytics SDKs, no ad IDs, and no note text on the server. The metadata we do keep is listed above and in our privacy policy, with logs deleted after 30 days. Read the privacy policy.
+
+
+## Sources
+
+- [Why metadata matters. Electronic Frontier Foundation, Surveillance Self-Defense](https://ssd.eff.org/module/why-metadata-matters)
+- [We kill people based on metadata. David Cole, The New York Review of Books, May 2014](https://www.nybooks.com/online/2014/05/10/we-kill-people-based-metadata/)
+- [GDPR Article 5: principles relating to processing of personal data](https://gdpr-info.eu/art-5-gdpr/)
+- [Provide information for Google Play's data safety section. Play Console Help](https://support.google.com/googleplay/android-developer/answer/10787469?hl=en)
+- [What Exodus Privacy does. Exodus Privacy](https://exodus-privacy.eu.org/en/page/what/)
+- [Atomic Notes privacy policy](https://atomic-notes.devbehindyou.com/privacy)
diff --git a/content/blog/notes-app-privacy-red-flags.md b/content/blog/notes-app-privacy-red-flags.md
index f3d314d..2453dc2 100644
--- a/content/blog/notes-app-privacy-red-flags.md
+++ b/content/blog/notes-app-privacy-red-flags.md
@@ -62,7 +62,7 @@ If you can't export, you don't own your notes. You rent them. Good data export o
### 3. "Encrypted" with no word on the key
-"Your data is encrypted in transit and at rest" sounds reassuring. It usually means HTTPS on the wire and encrypted disks on the server, while the company keeps the keys. Good notes app encryption says plainly whether it's end-to-end, and who can decrypt.
+"Your data is encrypted in transit and at rest" sounds reassuring. It usually means HTTPS on the wire and encrypted disks on the server, while the company keeps the keys. Good notes app encryption says plainly whether it's end-to-end, and who can decrypt. If those terms are new, start with [encrypted notes explained](/blog/encrypted-notes-explained).
**Check:** find the security page and look for the words "end-to-end" and "only you hold the key." **Better:** a one-page explanation in plain English, including what happens if you lose your key. This one flag tells you more about notes app privacy than any marketing page.
@@ -94,7 +94,7 @@ Every ad slot runs on a profile of the person looking at it. The FTC's 2023 case
### 6. Third party trackers and analytics
-Third party trackers send your behavior to companies you've never heard of: which screens you open, when you write, how long you stay. Even with encrypted notes, that pattern reveals your routine, which is why trackers matter so much for notes app privacy.
+Third party trackers send your behavior to companies you've never heard of: which screens you open, when you write, how long you stay. Even with encrypted notes, that pattern reveals your routine, which is why trackers matter so much for notes app privacy. The [notes app metadata guide](/blog/notes-app-data-collection) shows how much a week of timestamps gives away.
**Check:** search the app on Exodus Privacy, a free service that lists the trackers and permissions inside Android apps. **Better:** zero trackers and a privacy policy that says so in one line.
@@ -191,8 +191,9 @@ That's why the third question, who pays, matters as much as encryption. A privac
## Keep reading
+- [7 best private notes apps for Android in 2026](/blog/best-privacy-first-notes-apps-android)
+- [Notes app metadata: 8 things it knows without reading notes](/blog/notes-app-data-collection)
- [What is a local first notes app, and why does it matter?](/blog/what-is-a-local-first-notes-app)
-- [The Atomic Notes privacy policy](/privacy), in plain English
- [Read the Atomic Notes code on GitHub](https://github.com/DevBehindYou/Atomic-Notes-App-V0.2) and check every claim on this page
diff --git a/content/blog/what-is-a-local-first-notes-app.md b/content/blog/what-is-a-local-first-notes-app.md
index 547d6e4..8ebae66 100644
--- a/content/blog/what-is-a-local-first-notes-app.md
+++ b/content/blog/what-is-a-local-first-notes-app.md
@@ -50,7 +50,7 @@ The difference looks small on a diagram. In daily use, it decides whether your n
That distinction shows up the moment something goes wrong. In a cache-based app, a new note written offline often sits in a temporary queue. If the app crashes or the cache clears, that note can vanish. In a local first notes app, the note is already saved. Sync is the only thing waiting.
-There's a middle ground called offline first. Writes queue on the device, but the server's copy still wins any disagreement when you reconnect. It's a big step up from a plain cache, yet the server remains the source of truth.
+For a hands-on test of your own app, see [why notes should work without internet](/blog/why-notes-should-work-offline). There's a middle ground called offline first. Writes queue on the device, but the server's copy still wins any disagreement when you reconnect. It's a big step up from a plain cache, yet the server remains the source of truth.

@@ -101,7 +101,7 @@ Score the app you use today against what a local first notes app should do. You
## How a local first notes app actually works
-**Three parts do the work: on-device storage, a sync engine, and a cloud copy.** The interesting engineering is in how they talk to each other when the network is unreliable.
+**Three parts do the work: on-device storage, a sync engine, and a cloud copy.** The interesting engineering is in how they talk to each other when the network is unreliable. The [full architecture guide](/blog/atomic-notes-architecture) goes layer by layer.
Here's how Atomic Notes splits those jobs:
@@ -184,8 +184,9 @@ Local first is also one of the strongest privacy signals a notes app can send. F
## Keep reading
+- [Notes app without internet: why offline should be the default](/blog/why-notes-should-work-offline)
+- [Local first architecture: the 4 layers behind Atomic Notes](/blog/atomic-notes-architecture)
- [Notes app privacy: 9 red flags to check before you trust one](/blog/notes-app-privacy-red-flags)
-- [How Atomic Notes works, on the home page](/)
- [The Atomic Notes source code on GitHub](https://github.com/DevBehindYou/Atomic-Notes-App-V0.2), public to read and verify
diff --git a/content/blog/why-notes-should-work-offline.md b/content/blog/why-notes-should-work-offline.md
new file mode 100644
index 0000000..f59566f
--- /dev/null
+++ b/content/blog/why-notes-should-work-offline.md
@@ -0,0 +1,188 @@
+---
+title: "Notes App Without Internet: Why Offline Should Be the Default"
+slug: "why-notes-should-work-offline"
+description: "Does your notes app work without internet? Why offline should be the default, what breaks when it isn't, and a five-minute test you can run on any app."
+excerpt: "Signal drops in tunnels, elevators, and hospitals. A notes app without internet access should keep working, and here's how to check yours."
+author: "ashutosh-sharma"
+publishedAt: "2026-10-07"
+updatedAt: "2026-10-07"
+category: "local-first"
+tags: ["offline", "local-first", "sync", "reliability", "android"]
+featured: false
+draft: false
+coverImage: "/blog/why-notes-should-work-offline/01-banner.png"
+coverAlt: "Cover reading Notes That Work Without Internet, beside a phone showing an Atomic Notes checklist and a card that says airplane mode on, note saved, 0 ms"
+canonical: "https://atomic-notes.devbehindyou.com/blog/why-notes-should-work-offline"
+keywords: "notes app without internet, notes app no internet, does notes app work without internet, airplane mode, local storage, sync later, cloud dependency, latency, dead zones, source of truth"
+readingTime: "10 min read"
+---
+
+
+
Quick answer
+
A notes app without internet access should still open, save, search, edit, and delete, then sync on its own when the signal returns. Many apps only cache recent notes and fail on new writes. Offline should be the default because the moments you need to write something down are often the moments you have no signal.
+
+
+You're in a hospital waiting room with one bar of signal. The doctor has just told you three things you need to remember. You open your notes app, and it shows a spinner.
+
+That's the worst possible time for a notes app to need the internet. It's also a surprisingly common one. Signal disappears in elevators, basements, trains, planes, and the crowded places where life actually happens.
+
+I build Atomic Notes, an Android app that saves every note on the phone first. This guide explains why a notes app without internet should be normal rather than a special mode, what breaks when it isn't, and how to test the app you use today.
+
+## Does your notes app work without internet?
+
+**Probably partly.** Most apps can show notes you opened recently. Far fewer can save a new note, search everything, and sync it later without losing anything.
+
+The difference comes from where the app keeps the real copy of your notes. A cloud-first app keeps it on a server and shows you a cached view. A local-first app keeps it on your phone and treats the server as a copy. Offline, those two designs behave very differently.
+
+
+
+Search is the quiet giveaway. If search runs on the company's servers, it stops the moment you lose signal, even when the notes themselves are cached. A notes app without internet access needs its search index on the phone.
+
+You don't have to guess. Run this test on your own phone right now:
+
+:::widget airplane-test
+
+If the test failed at step three, take note. That's the step where a new note can be lost, and it's the one that matters most.
+
+## Where do notes lose signal?
+
+**In exactly the places you're most likely to need them.** Coverage maps show where a network exists, not where your phone can actually reach it.
+
+
+
+Think about when you reach for a notes app. Mid-commute, when an idea lands. On a flight, with hours to think. In a meeting room deep inside an office building. At a concert, writing down a setlist. Every one of those is a dead zone or close to it.
+
+Search engines see this too. People type "notes app no internet" after an app has just shown them an error, which is exactly when it's too late to switch apps. Pick a notes app without internet dependence before the trip, not during it.
+
+## Why should offline be the default?
+
+**Because a notes app's job is to catch a thought before it's gone, and a network request is the slowest, least reliable part of that job.** Four reasons make the case.
+
+### Speed: the waiting tax
+
+Every cloud-first save is a round trip to a server. On good Wi-Fi, that's barely noticeable. On weak signal, it can take seconds, and some saves fail outright. A local save finishes in milliseconds, whatever the network is doing. That latency is a tax a notes app without internet dependence never charges you.
+
+Try the numbers for your own day:
+
+:::widget wait-calculator
+
+The round-trip times above are assumptions for illustration, not measurements. The shape of the result holds anyway: local saves cost nothing, and cloud saves cost the most exactly when signal is worst.
+
+### Reliability: other people's outages
+
+Your own signal isn't the only risk. When a cloud provider has a bad day, every app built on it can stall at once. I covered a real example, the October 2025 AWS outage, in the guide to [what a local first notes app is](/blog/what-is-a-local-first-notes-app). Cloud dependency means every server between you and your notes has to be working.
+
+### Privacy: less in transit
+
+A notes app without internet access by default sends less, less often. Notes that live on your phone first don't need to cross a network every time you open them, and that means fewer copies and fewer logs.
+
+### Ownership: the copy that matters is yours
+
+If the real copy lives on your phone, the app can't hold your notes hostage behind a login screen or a server outage. Local storage is the plainest form of owning your data.
+
+## How do you set up offline notes for travel?
+
+**Do it before you leave, while you still have good Wi-Fi.** Travel is where dead zones stack up: airports, flights, border crossings, and roaming data you'd rather not pay for.
+
+1. **Sync everything before you go.** Open the app on Wi-Fi and let it finish, so every device has the latest copy.
+2. **Run the airplane test once.** Five minutes at home beats a failed save at 30,000 feet.
+3. **Turn on the app lock.** A phone on a tray table or a hotel nightstand is easier to pick up than you think.
+4. **Write freely on the way.** A notes app without internet needs nothing from the plane's Wi-Fi. Your notes queue up and sync when you land.
+5. **Check sync after you land.** Open the app on a stable connection and confirm the changes went through before you rely on another device.
+
+If you've ever stood at a gate typing "notes app no internet" into a search bar, this five-step routine is the fix. It takes less time than boarding.
+
+## What happens when the signal comes back?
+
+**A good app catches up on its own.** You shouldn't have to press a retry button, and you should never lose a change you made offline.
+
+
+
+Behind the scenes, three things have to go right:
+
+1. **The app remembers what changed.** Each edited note is marked as waiting to sync, and that mark survives a restart.
+2. **It notices the network.** When the connection returns, it starts syncing without being asked.
+3. **It survives a bad connection.** Weak signal often drops mid-upload, so retries must never create duplicates or overwrite newer edits.
+
+In Atomic Notes, sync runs about eight seconds after you stop typing, when the app resumes, and when the network reconnects. Failed uploads retry after 5, 15, and then 45 seconds, and every retry carries the same request ID, so the server can't apply the same change twice. If two devices edited the same note offline, the older edit is kept as a separate conflict copy instead of being thrown away.
+
+For developers testing their own app, Android can switch airplane mode from a computer, which makes the reconnect path easy to repeat:
+
+
Terminal · Android 11 or newer, USB debugging on
+
+```bash
+# Go offline, use the app, then come back online and watch it sync
+adb shell cmd connectivity airplane-mode enable
+adb shell cmd connectivity airplane-mode disable
+```
+
+## What does Atomic Notes do without internet?
+
+**Everything you do with notes every day works offline. Only the cloud parts wait.** Every note saves to on-device Hive storage as you type, and that local copy is the source of truth.
+
+
+
+Being honest about the limits matters here. You need a connection to sign in the first time, because sign-in goes through your Google account. Sync to your Google Drive, Atomic Energy, and notifications all need a network too. And sync only runs while the app is open, since background sync while the app is closed is still on the roadmap.
+
+What never waits is the writing, which is the whole point of a notes app without internet dependence. Open the app in airplane mode and your notes are there. Write a new one, close the app, restart the phone, and it's still there when you come back.
+
+## How can you make any notes app more offline-friendly?
+
+**Check its settings, keep critical notes where you can always reach them, and don't trust a cache with anything you can't lose.**
+
+- **Look for an offline setting.** Some cloud-first apps let you mark notebooks or pages for offline use. Turn it on for anything you'd need on a trip.
+- **Open what you'll need before you lose signal.** Cached apps usually keep what you viewed last.
+- **Don't write important notes into a "waiting to sync" state.** If the app shows a pending or retrying banner for new notes, copy them somewhere safe until they sync.
+- **Keep one source of truth on the device.** If your current app can't work offline, move the notes that matter most to a notes app without internet dependence.
+- **Export now and then.** An export is a copy no outage or account problem can take away.
+
+
+
+My opinion, after building one: a notes app that needs a network to save is really a website you carry around. Offline shouldn't be a premium feature or a hidden setting. Every notes app without internet access should still do its one job, which is keeping what you write. That's how notes apps should work.
+
+## FAQ
+
+
+
+Does a notes app work without internet?
+
It depends on how it's built. Local-first apps save, search, and edit with no connection and sync later. Cloud-first apps often show cached notes but can fail on new writes or search. Run the airplane test above to see how yours behaves.
+
+
+What's the best notes app without internet for Android?
+
Look for a local-first app: one that saves every note on the phone, searches on the device, and syncs only when it can. Atomic Notes works this way and syncs to your own Google Drive. Several open source apps never touch the internet at all.
+
+
+Why does my notes app say no internet connection?
+
The app is trying to reach its server to load or save notes, and can't. Cloud-first apps need that connection for parts of their job. A local-first app saves on your phone instead and only needs the network to sync.
+
+
+Will notes I write offline be lost?
+
In a local-first app, no. Each note is saved on the device first and marked to sync later, and that survives restarts. In apps that only queue changes in memory, a crash or force-close before reconnecting can lose new notes.
+
+
+Can Atomic Notes sync when the app is closed?
+
Not yet. Sync runs while the app is open: after you stop typing, when the app resumes, and when the network returns. Background sync while the app is closed is on the roadmap. Your notes stay safe on the phone either way.
+
+
+Is an offline notes app less secure?
+
Usually the opposite. Notes on your phone sit behind your device lock, and an app lock adds another layer. Less data crossing the network means fewer copies in transit. For the cloud copy, end-to-end encryption keeps synced notes private.
+
+
+
+## Keep reading
+
+- [What is a local first notes app, and why does it matter?](/blog/what-is-a-local-first-notes-app)
+- [Local first architecture: the 4 layers behind Atomic Notes](/blog/atomic-notes-architecture)
+- [Encrypted notes explained: T2T vs end to end encryption](/blog/encrypted-notes-explained)
+
+
+
Atomic Notes by DevBehindYou
+
Built to be a notes app without internet dependence. Every note saves on your phone first, search runs on the device, and sync to your own Google Drive catches up when the signal does. See how it works.
+
+
+## Sources
+
+- [Local-first software: you own your data, in spite of the cloud. Ink & Switch, 2019](https://www.inkandswitch.com/essay/local-first/)
+- [Build an offline-first app. Android Developers](https://developer.android.com/topic/architecture/data-layer/offline-first)
+- [hive_ce, the on-device database Atomic Notes uses. pub.dev](https://pub.dev/packages/hive_ce)
+- [Atomic Notes source code. GitHub](https://github.com/DevBehindYou/Atomic-Notes-App-V0.2)
diff --git a/public/blog/atomic-notes-architecture/01-banner.png b/public/blog/atomic-notes-architecture/01-banner.png
new file mode 100644
index 0000000..b5bf966
Binary files /dev/null and b/public/blog/atomic-notes-architecture/01-banner.png differ
diff --git a/public/blog/atomic-notes-architecture/02-four-layers.png b/public/blog/atomic-notes-architecture/02-four-layers.png
new file mode 100644
index 0000000..39b2087
Binary files /dev/null and b/public/blog/atomic-notes-architecture/02-four-layers.png differ
diff --git a/public/blog/atomic-notes-architecture/03-push-and-pull.png b/public/blog/atomic-notes-architecture/03-push-and-pull.png
new file mode 100644
index 0000000..d3a933a
Binary files /dev/null and b/public/blog/atomic-notes-architecture/03-push-and-pull.png differ
diff --git a/public/blog/atomic-notes-architecture/04-who-sees-what.png b/public/blog/atomic-notes-architecture/04-who-sees-what.png
new file mode 100644
index 0000000..4c4c688
Binary files /dev/null and b/public/blog/atomic-notes-architecture/04-who-sees-what.png differ
diff --git a/public/blog/atomic-notes-architecture/05-failure-modes.png b/public/blog/atomic-notes-architecture/05-failure-modes.png
new file mode 100644
index 0000000..37b529c
Binary files /dev/null and b/public/blog/atomic-notes-architecture/05-failure-modes.png differ
diff --git a/public/blog/atomic-notes-architecture/06-the-stack.png b/public/blog/atomic-notes-architecture/06-the-stack.png
new file mode 100644
index 0000000..61d2247
Binary files /dev/null and b/public/blog/atomic-notes-architecture/06-the-stack.png differ
diff --git a/public/blog/best-privacy-first-notes-apps-android/01-banner.png b/public/blog/best-privacy-first-notes-apps-android/01-banner.png
new file mode 100644
index 0000000..772304b
Binary files /dev/null and b/public/blog/best-privacy-first-notes-apps-android/01-banner.png differ
diff --git a/public/blog/best-privacy-first-notes-apps-android/02-comparison.png b/public/blog/best-privacy-first-notes-apps-android/02-comparison.png
new file mode 100644
index 0000000..562deab
Binary files /dev/null and b/public/blog/best-privacy-first-notes-apps-android/02-comparison.png differ
diff --git a/public/blog/best-privacy-first-notes-apps-android/03-how-we-picked.png b/public/blog/best-privacy-first-notes-apps-android/03-how-we-picked.png
new file mode 100644
index 0000000..68a9b8b
Binary files /dev/null and b/public/blog/best-privacy-first-notes-apps-android/03-how-we-picked.png differ
diff --git a/public/blog/best-privacy-first-notes-apps-android/04-pick-by-need.png b/public/blog/best-privacy-first-notes-apps-android/04-pick-by-need.png
new file mode 100644
index 0000000..1e55f91
Binary files /dev/null and b/public/blog/best-privacy-first-notes-apps-android/04-pick-by-need.png differ
diff --git a/public/blog/best-privacy-first-notes-apps-android/05-permissions.png b/public/blog/best-privacy-first-notes-apps-android/05-permissions.png
new file mode 100644
index 0000000..01e9369
Binary files /dev/null and b/public/blog/best-privacy-first-notes-apps-android/05-permissions.png differ
diff --git a/public/blog/best-privacy-first-notes-apps-android/06-atomic-notes-card.png b/public/blog/best-privacy-first-notes-apps-android/06-atomic-notes-card.png
new file mode 100644
index 0000000..73a2dfc
Binary files /dev/null and b/public/blog/best-privacy-first-notes-apps-android/06-atomic-notes-card.png differ
diff --git a/public/blog/encrypted-notes-explained/01-banner.png b/public/blog/encrypted-notes-explained/01-banner.png
new file mode 100644
index 0000000..5f9e140
Binary files /dev/null and b/public/blog/encrypted-notes-explained/01-banner.png differ
diff --git a/public/blog/encrypted-notes-explained/02-three-meanings.png b/public/blog/encrypted-notes-explained/02-three-meanings.png
new file mode 100644
index 0000000..0c5a476
Binary files /dev/null and b/public/blog/encrypted-notes-explained/02-three-meanings.png differ
diff --git a/public/blog/encrypted-notes-explained/03-vault-key-flow.png b/public/blog/encrypted-notes-explained/03-vault-key-flow.png
new file mode 100644
index 0000000..a040b73
Binary files /dev/null and b/public/blog/encrypted-notes-explained/03-vault-key-flow.png differ
diff --git a/public/blog/encrypted-notes-explained/04-t2t-vs-vault.png b/public/blog/encrypted-notes-explained/04-t2t-vs-vault.png
new file mode 100644
index 0000000..61d5bf8
Binary files /dev/null and b/public/blog/encrypted-notes-explained/04-t2t-vs-vault.png differ
diff --git a/public/blog/encrypted-notes-explained/05-what-e2e-hides.png b/public/blog/encrypted-notes-explained/05-what-e2e-hides.png
new file mode 100644
index 0000000..b883370
Binary files /dev/null and b/public/blog/encrypted-notes-explained/05-what-e2e-hides.png differ
diff --git a/public/blog/encrypted-notes-explained/06-recovery-tradeoff.png b/public/blog/encrypted-notes-explained/06-recovery-tradeoff.png
new file mode 100644
index 0000000..6f8f7c7
Binary files /dev/null and b/public/blog/encrypted-notes-explained/06-recovery-tradeoff.png differ
diff --git a/public/blog/notes-app-data-collection/01-banner.png b/public/blog/notes-app-data-collection/01-banner.png
new file mode 100644
index 0000000..40e9eed
Binary files /dev/null and b/public/blog/notes-app-data-collection/01-banner.png differ
diff --git a/public/blog/notes-app-data-collection/02-content-vs-metadata.png b/public/blog/notes-app-data-collection/02-content-vs-metadata.png
new file mode 100644
index 0000000..aa7a6ae
Binary files /dev/null and b/public/blog/notes-app-data-collection/02-content-vs-metadata.png differ
diff --git a/public/blog/notes-app-data-collection/03-eight-data-points.png b/public/blog/notes-app-data-collection/03-eight-data-points.png
new file mode 100644
index 0000000..f4ee423
Binary files /dev/null and b/public/blog/notes-app-data-collection/03-eight-data-points.png differ
diff --git a/public/blog/notes-app-data-collection/04-week-of-sync-times.png b/public/blog/notes-app-data-collection/04-week-of-sync-times.png
new file mode 100644
index 0000000..49ecf33
Binary files /dev/null and b/public/blog/notes-app-data-collection/04-week-of-sync-times.png differ
diff --git a/public/blog/notes-app-data-collection/05-needed-vs-extra.png b/public/blog/notes-app-data-collection/05-needed-vs-extra.png
new file mode 100644
index 0000000..bcfe67f
Binary files /dev/null and b/public/blog/notes-app-data-collection/05-needed-vs-extra.png differ
diff --git a/public/blog/notes-app-data-collection/06-what-atomic-notes-keeps.png b/public/blog/notes-app-data-collection/06-what-atomic-notes-keeps.png
new file mode 100644
index 0000000..7956276
Binary files /dev/null and b/public/blog/notes-app-data-collection/06-what-atomic-notes-keeps.png differ
diff --git a/public/blog/why-notes-should-work-offline/01-banner.png b/public/blog/why-notes-should-work-offline/01-banner.png
new file mode 100644
index 0000000..aac012b
Binary files /dev/null and b/public/blog/why-notes-should-work-offline/01-banner.png differ
diff --git a/public/blog/why-notes-should-work-offline/02-where-signal-drops.png b/public/blog/why-notes-should-work-offline/02-where-signal-drops.png
new file mode 100644
index 0000000..00fb2d0
Binary files /dev/null and b/public/blog/why-notes-should-work-offline/02-where-signal-drops.png differ
diff --git a/public/blog/why-notes-should-work-offline/03-offline-actions.png b/public/blog/why-notes-should-work-offline/03-offline-actions.png
new file mode 100644
index 0000000..fbe33c1
Binary files /dev/null and b/public/blog/why-notes-should-work-offline/03-offline-actions.png differ
diff --git a/public/blog/why-notes-should-work-offline/04-reconnect-timeline.png b/public/blog/why-notes-should-work-offline/04-reconnect-timeline.png
new file mode 100644
index 0000000..aa3003a
Binary files /dev/null and b/public/blog/why-notes-should-work-offline/04-reconnect-timeline.png differ
diff --git a/public/blog/why-notes-should-work-offline/05-atomic-notes-offline.png b/public/blog/why-notes-should-work-offline/05-atomic-notes-offline.png
new file mode 100644
index 0000000..0a3d436
Binary files /dev/null and b/public/blog/why-notes-should-work-offline/05-atomic-notes-offline.png differ
diff --git a/public/blog/why-notes-should-work-offline/06-offline-checklist.png b/public/blog/why-notes-should-work-offline/06-offline-checklist.png
new file mode 100644
index 0000000..4aa6ad4
Binary files /dev/null and b/public/blog/why-notes-should-work-offline/06-offline-checklist.png differ
diff --git a/public/llms.txt b/public/llms.txt
index 1879c30..a530f17 100644
--- a/public/llms.txt
+++ b/public/llms.txt
@@ -24,6 +24,11 @@ Key facts:
- [What Is a Local First Notes App and Why Does It Matter?](https://atomic-notes.devbehindyou.com/blog/what-is-a-local-first-notes-app): local-first software defined, offline first vs local first, the seven Ink & Switch ideals, how Atomic Notes syncs, and the tradeoffs
- [Notes App Privacy in 2026: 9 Red Flags to Check First](https://atomic-notes.devbehindyou.com/blog/notes-app-privacy-red-flags): nine checks for any notes app (accounts, export, encryption keys, permissions, ads, trackers, AI, formats, storage) and how Atomic Notes scores
+- [Encrypted Notes Explained: T2T vs End to End Encryption](https://atomic-notes.devbehindyou.com/blog/encrypted-notes-explained): HTTPS vs at rest vs end-to-end, the Atomic Notes vault (Argon2id, AES-256-GCM), what encryption can't hide, and the recovery trade-off
+- [Notes App Without Internet: Why Offline Should Be the Default](https://atomic-notes.devbehindyou.com/blog/why-notes-should-work-offline): what works offline in cloud-first vs local-first apps, an airplane-mode test, and how sync catches up
+- [Notes App Metadata: 8 Things It Knows Without Reading Notes](https://atomic-notes.devbehindyou.com/blog/notes-app-data-collection): the metadata a notes app can collect, what it reveals, data minimization, and exactly what the Atomic Notes server keeps
+- [Local First Architecture: 4 Layers Behind Atomic Notes](https://atomic-notes.devbehindyou.com/blog/atomic-notes-architecture): the device, metadata-only sync server, user-owned Google Drive, and optional vault, with failure modes and the tech stack
+- [7 Best Private Notes Apps for Android in 2026](https://atomic-notes.devbehindyou.com/blog/best-privacy-first-notes-apps-android): Atomic Notes, SilentNotes, CypherLeaf, NoteSR, Quillpad, Fossify Notes, and Privacy Friendly Notes, checked October 7, 2026
- [Atomic Notes v1.18.2 Demo Build](https://atomic-notes.devbehindyou.com/blog/atomic-notes-v1-18-2): Atomic Energy, in-app email flows, notification center, offline launch fix
- [RSS feed](https://atomic-notes.devbehindyou.com/feed.xml) and [sitemap](https://atomic-notes.devbehindyou.com/sitemap.xml): every published page and post
diff --git a/src/app/globals.css b/src/app/globals.css
index 98621c7..5b96a20 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -665,7 +665,7 @@ section h2 {
.kpis {
display: grid;
gap: 14px;
- grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
+ grid-template-columns: repeat(auto-fit, minmax(122px, 1fr));
}
.stat {
font-family: var(--mono);
@@ -1421,6 +1421,227 @@ section h2 {
font-size: 1.5rem;
line-height: 1;
}
+.bw-chips {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin: 0 0 16px;
+}
+.bw-chips button {
+ font-family: var(--mono);
+ font-size: 0.75rem;
+ letter-spacing: 1px;
+ text-transform: uppercase;
+ padding: 9px 14px;
+ min-height: 40px;
+ border: 1.5px solid var(--ink);
+ border-radius: 999px;
+ background: #fff;
+ color: var(--ink);
+ cursor: pointer;
+}
+.bw-chips button.on {
+ background: var(--ink);
+ color: var(--paper);
+}
+.bw .bw-code {
+ font-family: var(--mono);
+ font-size: 0.8rem;
+ line-height: 1.5;
+ word-break: break-all;
+ background: #0b0c0e;
+ color: #d8d6ff;
+ border-radius: 4px;
+ padding: 10px 12px;
+ margin-top: 8px;
+ min-height: 3em;
+}
+.bw .bw-code.plain {
+ background: #fff;
+ color: var(--ink);
+ border: 1px solid var(--line);
+}
+.bw .bw-grid {
+ list-style: none;
+ padding: 0;
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(122px, 1fr));
+ gap: 8px;
+ margin-bottom: 14px;
+}
+.bw-grid li {
+ border-radius: 4px;
+ padding: 12px;
+ display: grid;
+ gap: 6px;
+ font-size: 0.92rem;
+ line-height: 1.35;
+}
+.bw-grid li b {
+ font-family: var(--mono);
+ font-size: 0.72rem;
+ letter-spacing: 1px;
+}
+.bw-grid li.can {
+ background: #ffdad6;
+ color: #93000a;
+ border: 1.5px solid var(--error);
+}
+.bw-grid li.cant {
+ background: #fff;
+ border: 1.5px solid var(--ink);
+}
+.bw-grid li.cant b {
+ color: var(--signal);
+}
+.bw-grid li.self {
+ background: var(--signal);
+ color: #fff;
+ border: 1.5px solid var(--ink);
+}
+.bw-grid li.self b {
+ color: #d8d6ff;
+}
+.bw .bw-big {
+ font-family: var(--display);
+ font-size: 2.6rem;
+ line-height: 1;
+ margin-top: 6px;
+}
+.bw .bw-big.ok {
+ color: var(--signal);
+}
+.bw input[type="range"] {
+ accent-color: var(--signal);
+ min-height: 0;
+ border: 0;
+ padding: 0;
+ background: transparent;
+ grid-column: 1 / -1;
+ width: 100%;
+}
+.bw-table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 0.9rem;
+ min-width: 480px;
+}
+.bw-table th {
+ font-family: var(--mono);
+ font-size: 0.72rem;
+ letter-spacing: 1px;
+ text-align: left;
+ background: var(--surface);
+ padding: 8px 10px;
+}
+.bw-table td {
+ padding: 8px 10px;
+ border-top: 1px solid var(--line);
+}
+.bw-table td.mono {
+ font-family: var(--mono);
+ font-size: 0.8rem;
+ white-space: nowrap;
+}
+.bw .bw-infer {
+ margin: 0 0 14px;
+ padding: 0;
+ list-style: none;
+ display: grid;
+ gap: 8px;
+ counter-reset: inf;
+}
+.bw-infer li {
+ counter-increment: inf;
+ background: var(--ink);
+ color: var(--paper);
+ border-radius: 4px;
+ padding: 10px 12px 10px 44px;
+ position: relative;
+ font-size: 0.95rem;
+}
+.bw-infer li::before {
+ content: counter(inf, decimal-leading-zero);
+ position: absolute;
+ left: 12px;
+ top: 11px;
+ font-family: var(--mono);
+ font-size: 0.75rem;
+ color: #8f88ff;
+}
+.bw .bw-track {
+ list-style: none;
+ padding: 0;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px;
+ margin: 0 0 14px;
+}
+.bw-track button {
+ font-family: var(--mono);
+ font-size: 0.72rem;
+ letter-spacing: 1px;
+ padding: 8px 10px;
+ min-height: 38px;
+ border: 1.5px solid var(--line);
+ border-radius: 4px;
+ background: #fff;
+ color: var(--slate);
+ cursor: pointer;
+}
+.bw-track li.done button {
+ border-color: var(--ink);
+ color: var(--ink);
+}
+.bw-track li.now button {
+ background: var(--signal);
+ border-color: var(--signal);
+ color: #fff;
+}
+.bw-track li.now .bw-num,
+.bw-panel .bw-num {
+ color: inherit;
+}
+.bw-panel.warn {
+ box-shadow: inset 4px 0 0 var(--error);
+}
+.bw .bw-results {
+ list-style: none;
+ padding: 0;
+ display: grid;
+ gap: 8px;
+ margin: 0 0 14px;
+}
+.bw-results a {
+ display: grid;
+ gap: 2px;
+ background: #fff;
+ border: 1.5px solid var(--ink);
+ border-radius: 4px;
+ padding: 10px 12px;
+ color: var(--ink);
+ text-decoration: none;
+}
+.bw-results a:hover {
+ box-shadow: 3px 3px 0 var(--signal);
+}
+.bw-results b {
+ font-family: var(--display);
+ font-weight: 400;
+ text-transform: uppercase;
+ font-size: 1.3rem;
+ line-height: 1;
+}
+.bw-results span {
+ font-size: 0.9rem;
+ color: var(--slate);
+}
+.bw .btn-signal:disabled,
+.bw .btn-ghost:disabled {
+ opacity: 0.4;
+ box-shadow: none;
+ cursor: not-allowed;
+}
.bw button:focus-visible,
.bw input:focus-visible,
.toc a:focus-visible,
diff --git a/src/components/blog/AirplaneTest.tsx b/src/components/blog/AirplaneTest.tsx
new file mode 100644
index 0000000..f041567
--- /dev/null
+++ b/src/components/blog/AirplaneTest.tsx
@@ -0,0 +1,56 @@
+"use client";
+
+import { useState } from "react";
+
+// A guided airplane-mode test. The reader runs each step on their own phone and records the result.
+
+const STEPS = [
+ { t: "Turn on airplane mode, then force-close the app.", why: "Clears anything the app kept in memory while it had a network." },
+ { t: "Reopen the app. Do your notes appear right away?", why: "A local-first app opens from device storage. A cloud app shows a spinner or an error." },
+ { t: "Create a new note and close the app again.", why: "The real test: did the app save it, or only queue it in memory?" },
+ { t: "Reopen and search for a word in an older note.", why: "Search should run on the device, not on a server." },
+ { t: "Edit a note and delete another.", why: "Every daily action should work offline, not just reading." },
+ { t: "Turn the network back on. Do the changes sync by themselves?", why: "Good sync catches up on its own, with no manual retry." },
+];
+
+type R = "pass" | "fail" | null;
+
+export function AirplaneTest() {
+ const [res, setRes] = useState(STEPS.map(() => null));
+ const done = res.filter(Boolean).length;
+ const pass = res.filter((r) => r === "pass").length;
+ const verdict =
+ done < STEPS.length
+ ? `${STEPS.length - done} steps left`
+ : pass === STEPS.length
+ ? "Your notes app works without internet. It passes the test."
+ : pass >= 4
+ ? "It mostly works offline. Note which step failed before you trust it on a trip."
+ : "It depends on the network. Keep anything urgent somewhere that works offline.";
+ const set = (i: number, v: R) => setRes((r) => r.map((x, j) => (j === i ? v : x)));
+
+ return (
+
+
DO IT NOW · THE AIRPLANE TEST
+
Six steps. Five minutes.
+
Grab your phone and run each step on the notes app you use today.
+
+ {STEPS.map((s, i) => (
+
+ {String(i + 1).padStart(2, "0")}
+
{s.t}
{s.why}
+
+
+
+
+
+ ))}
+
+
+
+
{pass} / {STEPS.length} {verdict}
+
+
+
+ );
+}
diff --git a/src/components/blog/AppFinder.tsx b/src/components/blog/AppFinder.tsx
new file mode 100644
index 0000000..91a72c0
--- /dev/null
+++ b/src/components/blog/AppFinder.tsx
@@ -0,0 +1,53 @@
+"use client";
+
+import { useState } from "react";
+
+// Filters the seven private Android notes apps from the listicle by what a reader needs.
+// Facts checked against each app's repository or F-Droid listing on October 7, 2026.
+
+type App = { name: string; anchor: string; tags: string[]; line: string };
+
+const APPS: App[] = [
+ { name: "Atomic Notes", anchor: "1-atomic-notes", tags: ["sync", "own-cloud", "e2e", "public-code", "checklists"], line: "Local first, synced to your own Google Drive, optional end-to-end vault." },
+ { name: "SilentNotes", anchor: "2-silentnotes", tags: ["sync", "own-cloud", "e2e", "public-code", "no-account", "checklists"], line: "Always encrypted, syncs through storage you pick." },
+ { name: "CypherLeaf", anchor: "3-cypherleaf", tags: ["no-account", "offline-only", "lock", "public-code"], line: "Offline notebook with locked notes and encrypted backups." },
+ { name: "NoteSR", anchor: "4-notesr", tags: ["no-account", "offline-only", "lock", "public-code"], line: "Encrypted notes and file attachments in one vault." },
+ { name: "Quillpad", anchor: "5-quillpad", tags: ["sync", "own-cloud", "no-account", "public-code", "checklists"], line: "Markdown notes with optional Nextcloud sync." },
+ { name: "Fossify Notes", anchor: "6-fossify-notes", tags: ["no-account", "offline-only", "public-code", "checklists", "lock"], line: "Quick notes, checklists, and home screen widgets." },
+ { name: "Notes (Privacy Friendly)", anchor: "7-notes-privacy-friendly", tags: ["no-account", "offline-only", "public-code", "checklists"], line: "Text, checklist, audio, and sketch notes with few permissions." },
+];
+
+const NEEDS = [
+ { id: "sync", label: "Sync between devices" },
+ { id: "own-cloud", label: "Sync through my own storage" },
+ { id: "e2e", label: "End-to-end encryption" },
+ { id: "no-account", label: "No account at all" },
+ { id: "offline-only", label: "Never touches the internet" },
+ { id: "checklists", label: "Checklists" },
+];
+
+export function AppFinder() {
+ const [need, setNeed] = useState([]);
+ const toggle = (id: string) => setNeed((n) => (n.includes(id) ? n.filter((x) => x !== id) : [...n, id]));
+ const hits = APPS.filter((a) => need.every((n) => a.tags.includes(n)));
+
+ return (
+
+
FIND YOURS · 7 APPS, 6 FILTERS
+
What do you need from a private notes app?
+
Tick what matters. The list narrows to apps that do all of it.
+
+ {NEEDS.map((x) => (
+
+ ))}
+
+
+ {hits.length === 0 &&
No app on this list does all of that. Drop one filter.
+ {unlock ? <>{unlock.ok ? "DECRYPTED · " : "LOCKED · "}{unlock.text}> : vault ? "Each save uses a fresh random 12-byte nonce, so the same note never encrypts the same way twice." : "With the vault off, anyone who can open the file can read it."}
+
+
Demo key: PBKDF2-SHA256, built into browsers. The app derives its key with Argon2id (64 MiB, 3 passes).
+
+ );
+}
diff --git a/src/components/blog/MetadataInference.tsx b/src/components/blog/MetadataInference.tsx
new file mode 100644
index 0000000..d048aef
--- /dev/null
+++ b/src/components/blog/MetadataInference.tsx
@@ -0,0 +1,50 @@
+"use client";
+
+import { useState } from "react";
+
+// A sample week of sync events with no note content at all, and what someone could infer from them.
+
+const LOG = [
+ { at: "MON 23:52", ev: "sync push · 1 note · 2.1 KB", ip: "home Wi-Fi" },
+ { at: "TUE 23:47", ev: "sync push · 1 note · 2.4 KB", ip: "home Wi-Fi" },
+ { at: "WED 09:12", ev: "sign-in · new device · Pixel 8", ip: "office network" },
+ { at: "WED 23:58", ev: "sync push · 1 note · 2.9 KB", ip: "home Wi-Fi" },
+ { at: "THU 14:03", ev: "sync push · 6 notes · 0.4 KB each", ip: "hospital guest Wi-Fi" },
+ { at: "FRI 00:21", ev: "sync push · 1 note · 3.6 KB", ip: "home Wi-Fi" },
+ { at: "SAT 11:40", ev: "delete · 1 note", ip: "airport Wi-Fi" },
+];
+
+const INFER = [
+ "Writes one long note almost every night near midnight: probably a journal.",
+ "Lives and works in two places that never change: home and office.",
+ "Bought or switched to a new phone on Wednesday.",
+ "Spent Thursday afternoon at a hospital, taking short notes.",
+ "Was traveling on Saturday, and deleted something before the trip.",
+];
+
+export function MetadataInference() {
+ const [shown, setShown] = useState(0);
+ return (
+
+
TRY IT · NO CONTENT, STILL REVEALING
+
A week of metadata. Zero note text.
+
This is a made-up log of the kind a sync service could keep. Not one word of any note is in it.
+
+
+
WHEN
EVENT
WHERE (FROM THE IP)
+ {LOG.map((r) =>
{r.at}
{r.ev}
{r.ip}
)}
+
+
+
+ {INFER.slice(0, shown).map((x) =>
{x}
)}
+
+
+
{shown} / {INFER.length} {shown === INFER.length ? "All of that, without reading a single note." : "inferences revealed"}
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/blog/SyncStepper.tsx b/src/components/blog/SyncStepper.tsx
new file mode 100644
index 0000000..739027c
--- /dev/null
+++ b/src/components/blog/SyncStepper.tsx
@@ -0,0 +1,64 @@
+"use client";
+
+import { useState } from "react";
+
+// Walks through one Atomic Notes sync, step by step, with an optional dropped connection
+// to show why retries never double-charge or duplicate a note.
+
+type Step = { layer: string; title: string; body: string };
+
+const HAPPY: Step[] = [
+ { layer: "PHONE", title: "You stop typing", body: "The note is already saved in Hive on the device and marked dirty." },
+ { layer: "PHONE", title: "Eight seconds pass", body: "Auto sync waits for a pause, so a burst of edits becomes one upload." },
+ { layer: "PHONE", title: "A push leaves with a request ID", body: "The phone saves the pending push, with a fresh request ID, before sending it." },
+ { layer: "SERVER", title: "Lock, check, charge once", body: "The server takes a per-user lock, checks each note's base version, and spends energy in one transaction." },
+ { layer: "DRIVE", title: "One file per note", body: "The note is written to its .atomic file in your My-Atomic-Notes folder. The server keeps only metadata." },
+ { layer: "PHONE", title: "Acknowledged", body: "The reply clears the dirty flag. Your other devices pull the change on their next sync." },
+];
+
+const RETRY: Step[] = [
+ HAPPY[0], HAPPY[1], HAPPY[2],
+ { layer: "NETWORK", title: "The connection drops", body: "The push may or may not have reached the server. The phone can't tell." },
+ { layer: "PHONE", title: "Retry after 5, 15, then 45 seconds", body: "The phone resends the same saved push with the same request ID." },
+ { layer: "SERVER", title: "Seen this ID? Replay the answer", body: "If the first try already landed, the server returns the stored result. No second charge, no duplicate note." },
+ HAPPY[4], HAPPY[5],
+];
+
+export function SyncStepper() {
+ const [flaky, setFlaky] = useState(false);
+ const [i, setI] = useState(0);
+ const steps = flaky ? RETRY : HAPPY;
+ const s = steps[Math.min(i, steps.length - 1)];
+ const mode = (f: boolean) => { setFlaky(f); setI(0); };
+
+ return (
+
+
STEP THROUGH IT · ONE SYNC
+
From your thumb to your Drive.
+
+
+
+
+
+
+
+ {steps.map((x, j) => (
+
+
+
+ ))}
+
+
+
STEP {i + 1} OF {steps.length} · {s.layer}
+
{s.title}
+
{s.body}
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/blog/WaitCalculator.tsx b/src/components/blog/WaitCalculator.tsx
new file mode 100644
index 0000000..9e27c1d
--- /dev/null
+++ b/src/components/blog/WaitCalculator.tsx
@@ -0,0 +1,53 @@
+"use client";
+
+import { useState } from "react";
+
+// How long a day of note saves spends waiting on the network, cloud-first vs local-first.
+// The round-trip times are illustrative assumptions, shown in the UI, not measurements.
+
+const NETS = [
+ { name: "Good Wi-Fi", rtt: 0.08, fail: 0 },
+ { name: "Busy 4G", rtt: 0.35, fail: 0.02 },
+ { name: "Weak signal", rtt: 1.6, fail: 0.15 },
+ { name: "Train tunnel", rtt: 6, fail: 0.6 },
+ { name: "Airplane mode", rtt: 0, fail: 1 },
+];
+
+export function WaitCalculator() {
+ const [net, setNet] = useState(2);
+ const [saves, setSaves] = useState(40);
+ const n = NETS[net];
+ const failed = Math.round(saves * n.fail);
+ const waited = n.fail === 1 ? 0 : (saves - failed) * n.rtt;
+ const fmt = (s: number) => (s < 60 ? `${s.toFixed(s < 10 ? 1 : 0)} s` : `${(s / 60).toFixed(1)} min`);
+
+ return (
+
+
TRY IT · THE WAITING TAX
+
How long do you wait for a server?
+
Pick a network and how many times a day you save a note.
+
+ {NETS.map((x, i) => (
+
+ ))}
+
+
+
+ setSaves(+e.target.value)} />
+
+
+
+
CLOUD-FIRST APP
+
{n.fail === 1 ? "0 SAVED" : fmt(waited)}
+
{n.fail === 1 ? `All ${saves} saves fail or wait for a network.` : `spent waiting${failed ? `, and ${failed} saves fail` : ""}.`}
+
+
+
LOCAL-FIRST APP
+
0 S
+
{`All ${saves} saves finish on the device. Sync waits, you don't.`}
+
+
+
Assumes one round trip per save: {NETS.map((x) => `${x.name.toLowerCase()} ${x.fail === 1 ? "no network" : `${x.rtt} s`}`).join(", ")}. Real apps vary.
+
+ );
+}
diff --git a/src/components/blog/WhoCanRead.tsx b/src/components/blog/WhoCanRead.tsx
new file mode 100644
index 0000000..b0e0cc1
--- /dev/null
+++ b/src/components/blog/WhoCanRead.tsx
@@ -0,0 +1,40 @@
+"use client";
+
+import { useState } from "react";
+
+// Pick what "encrypted" means for an app and see who can still read a note.
+
+const ACTORS = ["Someone on your Wi-Fi", "Someone who steals the server disks", "The app company", "A legal request to the company", "You, on your devices"];
+
+const MODELS: { name: string; tag: string; reads: boolean[]; note: string }[] = [
+ { name: "No encryption", tag: "PLAIN", reads: [true, true, true, true, true], note: "Everyone along the path can read your notes. Rare today, but some old sync tools still work this way." },
+ { name: "HTTPS only", tag: "IN TRANSIT", reads: [false, true, true, true, true], note: "TLS locks the trip. On arrival, the server holds plain text." },
+ { name: "Encrypted at rest", tag: "PROVIDER KEYS", reads: [false, false, true, true, true], note: "Disks are encrypted, but the company holds the keys, so it can still decrypt." },
+ { name: "End-to-end", tag: "YOUR KEY", reads: [false, false, false, false, true], note: "Notes are encrypted on your device. The company stores ciphertext it can't open." },
+];
+
+export function WhoCanRead() {
+ const [m, setM] = useState(1);
+ const model = MODELS[m];
+ return (
+