diff --git a/apps/portal/src/app/features/profile/components/SeafarerScopeFields.tsx b/apps/portal/src/app/features/profile/components/SeafarerScopeFields.tsx
new file mode 100644
index 000000000..c1ee599ac
--- /dev/null
+++ b/apps/portal/src/app/features/profile/components/SeafarerScopeFields.tsx
@@ -0,0 +1,92 @@
+import { Paper, SimpleGrid, Stack, Text, TextInput, Title } from '@mantine/core';
+import { useTranslation } from 'react-i18next';
+import {
+ displaySeafarerAnswer,
+ useGetActiveDepartmentsQuery,
+ useGetMySeafarerRegistrationQuery,
+ useLocalized,
+} from '@ema-platform/api';
+import { PORTAL_PERMISSIONS, usePermissions } from '@ema-platform/auth';
+
+/**
+ * Department and STCW limitation, read-only.
+ *
+ * Answered once in the registration wizard and never again, yet between them
+ * they decide which certificates, examinations and services the portal offers
+ * — so a seafarer has to be able to see what they are without reopening a
+ * submitted registration. Not editable here on purpose: either answer moves
+ * the applicant onto a different CoC ladder, which is EMA's decision on
+ * review, not a profile edit.
+ *
+ * `tier` lives only on the registration record — the profile carries the
+ * department alone (`seafarerDepartment`) — so the registration is the source
+ * for both, with the profile's department as the fallback for an account whose
+ * registration is not readable.
+ */
+export function SeafarerScopeFields({
+ fallbackDepartment,
+}: {
+ /** `profile.seafarerDepartment`, used when no registration comes back. */
+ fallbackDepartment?: string | null;
+}) {
+ const { t } = useTranslation();
+ const localized = useLocalized();
+ // Same permission the registration page and `/seafarer-registrations/mine`
+ // are behind — asking without it would only 403.
+ const { can } = usePermissions();
+ const mayRegister = can([PORTAL_PERMISSIONS.APPLY_SEAFARER_REGISTRATION]);
+ const { data, isLoading } = useGetMySeafarerRegistrationQuery(undefined, {
+ skip: !mayRegister,
+ });
+ const registration = data?.registration ?? null;
+
+ const department = registration?.department ?? fallbackDepartment ?? null;
+ const tier = registration?.tier ?? null;
+
+ // Live department names, so a department configured after this release still
+ // shows its own name — the same list the registration wizard picks from.
+ const { data: departments } = useGetActiveDepartmentsQuery(undefined, { skip: !department });
+ const departmentOptions = departments?.map((d) => ({ value: d.code, label: localized(d.name) }));
+
+ // Nothing recorded yet — the registration wizard is where these are answered.
+ if (isLoading || (!department && !tier)) return null;
+
+ return (
+
+
+