diff --git a/apps/mobile/src/components/LocalTiptapEditor.tsx b/apps/mobile/src/components/LocalTiptapEditor.tsx
index 92b9fd33..08421693 100644
--- a/apps/mobile/src/components/LocalTiptapEditor.tsx
+++ b/apps/mobile/src/components/LocalTiptapEditor.tsx
@@ -2871,6 +2871,21 @@ const getEditorStyles = (theme: "light" | "dark", options?: { viewer?: boolean }
border-spacing: 0;
table-layout: fixed;
}
+ /* Let compact tables use the full content width. The fallback on
+ .tableWrapper remains the minimum column budget for 5+ columns, so only
+ wider tables scroll. TipTap always renders one
per logical column. */
+ .edgeever-editor-content table:has(> colgroup > col:first-child:last-child) {
+ --mobile-table-column-width: 100cqi;
+ }
+ .edgeever-editor-content table:has(> colgroup > col:first-child:nth-last-child(2)) {
+ --mobile-table-column-width: 50cqi;
+ }
+ .edgeever-editor-content table:has(> colgroup > col:first-child:nth-last-child(3)) {
+ --mobile-table-column-width: calc(100cqi / 3);
+ }
+ .edgeever-editor-content table:has(> colgroup > col:first-child:nth-last-child(4)) {
+ --mobile-table-column-width: 25cqi;
+ }
/* Override TipTap/desktop col widths with the mobile equal-ish column budget. */
.edgeever-editor-content table col {
width: var(--mobile-table-column-width) !important;
diff --git a/apps/mobile/src/lib/mobile-table-layout.test.ts b/apps/mobile/src/lib/mobile-table-layout.test.ts
new file mode 100644
index 00000000..02c02c0d
--- /dev/null
+++ b/apps/mobile/src/lib/mobile-table-layout.test.ts
@@ -0,0 +1,36 @@
+import { readFileSync } from "node:fs";
+import { describe, expect, test } from "bun:test";
+
+const editorSource = readFileSync(
+ new URL("../components/LocalTiptapEditor.tsx", import.meta.url),
+ "utf8",
+);
+
+describe("mobile TipTap table layout contract", () => {
+ test.each([
+ ["col:first-child:last-child", "100cqi"],
+ ["col:first-child:nth-last-child(2)", "50cqi"],
+ ["col:first-child:nth-last-child(3)", "calc(100cqi / 3)"],
+ ["col:first-child:nth-last-child(4)", "25cqi"],
+ ])("fills the content width for a table matched by %s", (columnSelector, expectedWidth) => {
+ const selector = `.edgeever-editor-content table:has(> colgroup > ${columnSelector})`;
+ const selectorStart = editorSource.indexOf(selector);
+
+ expect(selectorStart).toBeGreaterThanOrEqual(0);
+ expect(editorSource.slice(selectorStart, selectorStart + selector.length + 100)).toContain(
+ `--mobile-table-column-width: ${expectedWidth};`,
+ );
+ });
+
+ test("keeps wide tables readable and scrolls them inside the wrapper", () => {
+ expect(editorSource).toContain(
+ "--mobile-table-column-width: clamp(4.25rem, 24cqi, 10rem);",
+ );
+ expect(editorSource).toMatch(
+ /\.edgeever-editor-content \.tableWrapper \{[\s\S]*?overflow-x: auto;/,
+ );
+ expect(editorSource).toMatch(
+ /\.edgeever-editor-content table \{[\s\S]*?min-width: 100%;/,
+ );
+ });
+});