Index: src/routes/guardian.js
===================================================================
--- src/routes/guardian.js	(revision 99a7b40b231a44b799a0c58f64a40bb1e97ff2b4)
+++ src/routes/guardian.js	(revision 792af539e3b665ec03cb8927cd16b3af858defec)
@@ -57,5 +57,11 @@
     'prop_line', 'prop_embeds', 'prop_play', 'prop_on', 'prop_off',
     'prop_st_open', 'prop_st_accepted', 'prop_st_rejected', 'prop_st_expired',
-    'panel_guards_far'];
+    'panel_guards_far',
+    // Het gate-paneel per ward (shaer-ahy.1): een rij per gate, met het soort en
+    // de drempel erbij. De namen volgen de catalogus in gated.js.
+    'gate_externalEmbeds', 'gate_externalPlayback', 'gate_follows',
+    'gate_kind_setting', 'gate_kind_perRequest', 'gate_kind_handover',
+    'gate_unknown', 'gate_threshold', 'gate_threshold_unknown',
+    'gate_irreversible', 'gate_waiting', 'gate_blocked', 'gate_propose'];
   const s = Object.fromEntries(keys.map((k) => [k, i18nT(L, `guardian.${k}`)]));
   s.wave = i18nT(L, 'guardian.wave');
@@ -103,4 +109,8 @@
         status: Guardianship.gated.sentStatus(p, Date.now()),
       })),
+      // Alles wat voor dit kind gated is op EEN plek, met per gate het soort en
+      // de drempel (shaer-ahy.1). Losse knoppen lieten een guardian zelf
+      // uitzoeken wat er allemaal geldt; wat niet verstelbaar is stond nergens.
+      gates: wardGates(site.slug, w.other_uri),
     })),
     offers: Guardianship.offersCollection(`${me}/queues/offers`, site.slug, me).orderedItems,
@@ -538,4 +548,29 @@
 /** The playback gate of a ward we host (5.6): the heavier sibling. */
 function wardPlaybackSetting(uri) { return wardGateSetting(uri, 'external_playback'); }
+/**
+ * De gate-rijen van een ward voor het paneel.
+ *
+ * De standen komen uit onze eigen kolommen als we het kind hosten; bij een ward
+ * elders weten we ze niet en blijft het NULL -- onbekend, niet uit. Het aantal
+ * guardians idem: dat wordt op de server van die ward bijgehouden, en zonder dat
+ * getal wordt er geen drempel verzonnen.
+ */
+function wardGates(mySlug, wardUri) {
+  const statuses = wardGuardianStatuses(wardUri);
+  const wachtend = Guardianship.follows.listReviewsByDirection(mySlug, 'incoming')
+    .filter((r) => r.ward_uri === wardUri).length;
+  return Guardianship.gated.gateRows({
+    settings: {
+      'shaer:externalEmbeds': wardEmbedSetting(wardUri),
+      'shaer:externalPlayback': wardPlaybackSetting(wardUri),
+    },
+    guardianCount: statuses ? statuses.length : null,
+    proposals: Guardianship.gated.listSent(mySlug, wardUri).map((p) => ({
+      feature: p.feature, value: !!p.value, status: Guardianship.gated.sentStatus(p, Date.now()),
+    })),
+    waiting: { 'shaer:follows': wachtend || undefined },
+  });
+}
+
 function wardGateSetting(uri, column) {
   const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, '');
