diff --git a/tutorials/bicep/tags-labels-taints/README.md b/tutorials/bicep/tags-labels-taints/README.md
index 819ccf0..2649224 100644
--- a/tutorials/bicep/tags-labels-taints/README.md
+++ b/tutorials/bicep/tags-labels-taints/README.md
@@ -24,6 +24,7 @@ By default the user agent pool carries the `workload=batch` node label, the `ded
[main.bicep](main.bicep) is a resource-group-scoped template that composes nine local Bicep modules (`deploy.sh` creates the `local-rg` resource group first):
```mermaid
+%%{init: {'themeVariables': {'clusterBkg': 'transparent', 'clusterBorder': '#8c8c8c'}}}%%
graph TD
LA[module logAnalytics] --> ACR[module containerRegistry]
LA --> KV[module keyVault]
diff --git a/tutorials/ccm/scripts/README.md b/tutorials/ccm/scripts/README.md
index e03f619..b40a3f2 100644
--- a/tutorials/ccm/scripts/README.md
+++ b/tutorials/ccm/scripts/README.md
@@ -10,6 +10,43 @@ Because the emulated load balancer has no real dataplane, the `EXTERNAL-IP` is a
> **Running on LocalStack?** Install the [lstk CLI](https://docs.localstack.cloud/aws/developer-tools/running-localstack/lstk/) and run `lstk az start-interception` to route Azure CLI calls to the emulator. See [Run against LocalStack](../../../README.md#run-against-localstack) for the full setup.
+## Architecture
+
+The cloud controller manager turns Kubernetes `Service` objects into Azure load-balancer resources in the node resource group, and writes the assigned address back onto the Service:
+
+```mermaid
+%%{init: {'themeVariables': {'clusterBkg': 'transparent', 'clusterBorder': '#8c8c8c'}}}%%
+flowchart LR
+ subgraph aks["AKS cluster"]
+ subgraph kubesystem["kube-system"]
+ ccm["cloud-controller-manager"]
+ cnm["cloud-node-manager"]
+ end
+ subgraph appns["test namespace"]
+ svcpub["Service
type LoadBalancer"]
+ svcint["Service
internal annotation"]
+ backend["backend Deployment"]
+ end
+ end
+
+ subgraph noderg["node resource group MC_*"]
+ lb["kubernetes
load balancer"]
+ lbint["kubernetes-internal
load balancer"]
+ pip["public IP address"]
+ nsg["network security group"]
+ end
+
+ svcpub -.->|"watched by"| ccm
+ svcint -.->|"watched by"| ccm
+ ccm -->|"frontend, rule, backend pool"| lb
+ ccm -->|"private frontend"| lbint
+ ccm -->|"allocates"| pip
+ ccm -->|"Allow rule per loadBalancerSourceRanges"| nsg
+ ccm -->|"writes EXTERNAL-IP back"| svcpub
+ cnm -->|"labels and addresses nodes"| aks
+ lb -.->|"backend pool targets"| backend
+```
+
## Prerequisites
- An AKS cluster reachable through `kubectl`, created by [scripts/01-user-assigned-managed-identity.sh](../../../scripts/01-user-assigned-managed-identity.sh). The scripts do not create the cluster; they source `./00-variables.sh`, whose values must match it (`local-aks-test` in resource group `local-rg`, location `ItalyNorth`).
diff --git a/tutorials/gateway-api/scripts/README.md b/tutorials/gateway-api/scripts/README.md
index a8d5493..5edcba1 100644
--- a/tutorials/gateway-api/scripts/README.md
+++ b/tutorials/gateway-api/scripts/README.md
@@ -18,6 +18,41 @@ This tutorial enables the Managed Gateway API on an AKS cluster (or the [LocalSt
The cluster-creation scripts already enable the Managed Gateway API at create time, so `01-enable-gateway-api.sh` is idempotent: on such a cluster it detects the installation and leaves it in place. It still runs cleanly on a cluster created without it, enabling it through the live `az aks update` path.
+## Architecture
+
+The Managed Gateway API add-on installs only the CRDs; NGINX Gateway Fabric is the implementation that claims the `GatewayClass` and serves the traffic:
+
+```mermaid
+%%{init: {'themeVariables': {'clusterBkg': 'transparent', 'clusterBorder': '#8c8c8c'}}}%%
+flowchart LR
+ client(["curl -H 'Host: echo.local'"])
+
+ subgraph aks["AKS cluster"]
+ crds["gateway.networking.k8s.io CRDs
installed by the add-on"]
+ gwclass["GatewayClass nginx"]
+
+ subgraph ngfns["namespace nginx-gateway"]
+ controller["NGINX Gateway Fabric
controller"]
+ dataplane["per-Gateway NGINX
data-plane Service and pods"]
+ end
+
+ subgraph testns["namespace gateway-api-test"]
+ gw["Gateway
HTTP listener for echo.local"]
+ route["HTTPRoute
every path of echo.local"]
+ svc["echo-server
ClusterIP Service"]
+ deploy["echo-server
Deployment"]
+ end
+ end
+
+ crds -.->|"define"| gw
+ gwclass -.->|"claimed by"| controller
+ gw -.->|"provisions"| dataplane
+ route -.->|"attached to"| gw
+ client -->|"kubectl port-forward"| dataplane
+ dataplane -->|"routes per HTTPRoute"| svc
+ svc --> deploy
+```
+
## How it works
Run the numbered scripts in order. Each one sources [00-variables.sh](00-variables.sh) and is idempotent, so it can be re-run safely.
diff --git a/tutorials/keda/event-hubs/README.md b/tutorials/keda/event-hubs/README.md
index 4a1bec0..d61c68a 100644
--- a/tutorials/keda/event-hubs/README.md
+++ b/tutorials/keda/event-hubs/README.md
@@ -13,6 +13,7 @@ This tutorial creates an Event Hubs namespace with one event hub, a dedicated co
The producer and the consumer are two workloads in the same Kubernetes namespace inside the AKS cluster. The producer sends events to the event hub, the consumer reads them and records its progress as checkpoints in blob storage, and the KEDA add-on in `kube-system` compares the two to work out the lag that drives the scaling.
```mermaid
+%%{init: {'themeVariables': {'clusterBkg': 'transparent', 'clusterBorder': '#8c8c8c'}}}%%
flowchart LR
subgraph aks["Azure Kubernetes Service cluster"]
subgraph kubesystem["kube-system: KEDA add-on"]
diff --git a/tutorials/keda/queue-storage/README.md b/tutorials/keda/queue-storage/README.md
index ee7e265..0c9414a 100644
--- a/tutorials/keda/queue-storage/README.md
+++ b/tutorials/keda/queue-storage/README.md
@@ -16,6 +16,7 @@ The KEDA scaler **and** both applications authenticate with the same shared user
The producer and the consumer are two workloads in the same Kubernetes namespace inside the AKS cluster, both running as the federated `queue-app` service account. The producer fills the storage queue, the consumer drains it, and the KEDA add-on in `kube-system` reads the queue's depth to decide how many consumer replicas should exist. Every arrow that touches Azure is authenticated with workload identity.
```mermaid
+%%{init: {'themeVariables': {'clusterBkg': 'transparent', 'clusterBorder': '#8c8c8c'}}}%%
flowchart LR
subgraph aks["Azure Kubernetes Service cluster"]
subgraph kubesystem["kube-system: KEDA add-on"]
diff --git a/tutorials/keda/service-bus/README.md b/tutorials/keda/service-bus/README.md
index 1e6ee97..53066a5 100644
--- a/tutorials/keda/service-bus/README.md
+++ b/tutorials/keda/service-bus/README.md
@@ -15,6 +15,7 @@ The producer and consumer applications themselves use the namespace connection s
The producer and the consumer are two workloads in the same Kubernetes namespace inside the AKS cluster. The producer fills the Service Bus queue, the consumer drains it, and the KEDA add-on in `kube-system` reads the queue's depth to decide how many consumer replicas should exist.
```mermaid
+%%{init: {'themeVariables': {'clusterBkg': 'transparent', 'clusterBorder': '#8c8c8c'}}}%%
flowchart LR
subgraph aks["Azure Kubernetes Service cluster"]
subgraph kubesystem["kube-system: KEDA add-on"]
diff --git a/tutorials/terraform/tags-labels-taints/README.md b/tutorials/terraform/tags-labels-taints/README.md
index 01c502d..d7d56fb 100644
--- a/tutorials/terraform/tags-labels-taints/README.md
+++ b/tutorials/terraform/tags-labels-taints/README.md
@@ -25,6 +25,7 @@ By default the user agent pool carries the `workload=batch` node label, the `ded
The root [main.tf](main.tf) composes seven local Terraform modules around a single resource group, then adds the cross-module role assignments and the Managed Gateway API installation that no single module can own:
```mermaid
+%%{init: {'themeVariables': {'clusterBkg': 'transparent', 'clusterBorder': '#8c8c8c'}}}%%
graph TD
RG[azurerm_resource_group] --> LA[module log_analytics]
RG --> VNET[module virtual_network]