diff --git a/images/ios-foreign-key-preview-dark.png b/images/ios-foreign-key-preview-dark.png
new file mode 100644
index 00000000..265d6d7f
Binary files /dev/null and b/images/ios-foreign-key-preview-dark.png differ
diff --git a/images/ios-foreign-key-preview.png b/images/ios-foreign-key-preview.png
new file mode 100644
index 00000000..67cec716
Binary files /dev/null and b/images/ios-foreign-key-preview.png differ
diff --git a/ios/index.mdx b/ios/index.mdx
index 066f3a1b..a1559ce9 100644
--- a/ios/index.mdx
+++ b/ios/index.mdx
@@ -107,7 +107,14 @@ On iPhone Duo the system draws the toolbar and the tab bar down the side of the
### Browsing
-A row in the list previews four of its fields, and eight where the display is wide enough. Search the table list by name. A PostgreSQL materialized view sits under **Views** and opens read only. Page a table at 50, 100, 200, or 500 rows, jump to a page number, sort by a column, search text columns, and stack filters with AND or OR. A foreign key value previews the row it points at.
+A row in the list previews four of its fields, and eight where the display is wide enough. Search the table list by name. A PostgreSQL materialized view sits under **Views** and opens read only. Page a table at 50, 100, 200, or 500 rows, jump to a page number, sort by a column, search text columns, and stack filters with AND or OR.
+
+To follow a foreign key, tap the link under its value on a row, or long-press a row in the list and pick the key. A sheet previews the row it points at, titled with the table and, when it differs from the one open, the schema. A value in the preview that is itself a foreign key opens the next row in the same sheet, and **Back** returns one step. **Open Table** opens that table filtered to the key, and when one row matches it lands on that row, ready to edit. **Back** then returns to the filtered list and to the row you started from. While that row has an edit open, **Open Table** is dimmed.
+
+
+
+
+
**Table Structure** lists columns, indexes, and foreign keys, read only. An index shows its key columns and expressions in key order, then any `INCLUDE` columns and a partial index's `WHERE` clause. On Redshift the index list holds the DISTKEY and SORTKEY columns.
@@ -115,7 +122,7 @@ On Redis the list holds the current database's keys. A key opens by type: a stri
### Editing
-Tap a row to open it full screen, page between rows, edit values, toggle one to `NULL`, and save. An emptied date, number or boolean field saves `NULL`, and in a NOT NULL column it keeps its value; an emptied text field saves an empty string. While you edit, **Cancel** takes the place of the back button and asks before it throws away a changed value, and so does **Connections** in another tab. Inserting and deleting rows, and truncating or dropping a table, are here too; a PostgreSQL foreign table offers neither Truncate nor Drop. Editing needs a primary key.
+Tap a row to open it full screen, page between rows, edit values, toggle one to `NULL`, and save. An emptied date, number or boolean field saves `NULL`, and in a NOT NULL column it keeps its value; an emptied text field saves an empty string. While you edit, **Cancel** takes the place of the back button and asks before it throws away a changed value, and so does **Connections** in another tab. Inserting and deleting rows, and truncating or dropping a table, are here too; a PostgreSQL foreign table offers neither Truncate nor Drop. Editing needs a primary key, and a row whose key holds binary data opens read only.
A new row starts with every column on **DEFAULT**, which leaves that column out of the `INSERT` so the database fills it in. The badge beside a field switches it between **DEFAULT**, **NULL** and a typed value, and **NULL** is offered on nullable columns only. Generated columns are never written, and an auto-increment key stays on **DEFAULT** until you type one.