diff --git a/CHANGELOG.md b/CHANGELOG.md
index b1caf700..7f8bf6fa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,24 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
---
+## v26.06.112 (2026-06-16)
+
+### Changed
+
+- **"PyFly by Example" — all diagrams redesigned.** Every content figure in both
+ the English and Spanish editions was rebuilt in a single, polished design
+ language (consistent cards, gradient headers, numbered step flows, monospace
+ code tokens, brand palette, vector iconography). This fixes real defects in the
+ previous artwork — broken/tofu glyphs (font-dependent arrows, circled numbers
+ and check marks) and clipped/overflowing content — by drawing all arrows,
+ checkmarks and numbered badges as vector shapes and keeping figure text to
+ ASCII/Latin-1 only.
+- **Two new figures** where they help most: *Page / Pageable / Sort* (Chapter 5)
+ and *Value Object vs Entity* (Chapter 6). Both editions rebuilt and re-attached
+ to the release.
+
+---
+
## v26.06.111 (2026-06-16)
### Added
diff --git a/book/art/figures/01-choice.svg b/book/art/figures/01-choice.svg
index 02635927..54c41080 100644
--- a/book/art/figures/01-choice.svg
+++ b/book/art/figures/01-choice.svg
@@ -1,81 +1,100 @@
-
diff --git a/book/art/figures/01-layers.svg b/book/art/figures/01-layers.svg
index b04a75ea..0909336e 100644
--- a/book/art/figures/01-layers.svg
+++ b/book/art/figures/01-layers.svg
@@ -1,75 +1,63 @@
-
diff --git a/book/art/figures/02-di.svg b/book/art/figures/02-di.svg
index 87f997a7..c561854d 100644
--- a/book/art/figures/02-di.svg
+++ b/book/art/figures/02-di.svg
@@ -1,84 +1,83 @@
-
diff --git a/book/art/figures/02-lifecycle.svg b/book/art/figures/02-lifecycle.svg
index dee442a5..50ea2540 100644
--- a/book/art/figures/02-lifecycle.svg
+++ b/book/art/figures/02-lifecycle.svg
@@ -1,94 +1,108 @@
-
diff --git a/book/art/figures/03-config.svg b/book/art/figures/03-config.svg
index 071160f9..da9658ee 100644
--- a/book/art/figures/03-config.svg
+++ b/book/art/figures/03-config.svg
@@ -1,71 +1,95 @@
-
diff --git a/book/art/figures/04-request.svg b/book/art/figures/04-request.svg
index d20d1df6..4f29f398 100644
--- a/book/art/figures/04-request.svg
+++ b/book/art/figures/04-request.svg
@@ -1,129 +1,92 @@
-
diff --git a/book/art/figures/05-pagination.svg b/book/art/figures/05-pagination.svg
new file mode 100644
index 00000000..49b76d4f
--- /dev/null
+++ b/book/art/figures/05-pagination.svg
@@ -0,0 +1,68 @@
+
diff --git a/book/art/figures/05-repository.svg b/book/art/figures/05-repository.svg
index 5e1a0064..2be76833 100644
--- a/book/art/figures/05-repository.svg
+++ b/book/art/figures/05-repository.svg
@@ -1,102 +1,90 @@
-
diff --git a/book/art/figures/06-aggregate.svg b/book/art/figures/06-aggregate.svg
index 51bc6747..5e0606ea 100644
--- a/book/art/figures/06-aggregate.svg
+++ b/book/art/figures/06-aggregate.svg
@@ -1,96 +1,132 @@
-
diff --git a/book/art/figures/06-vo-entity.svg b/book/art/figures/06-vo-entity.svg
new file mode 100644
index 00000000..8aa03765
--- /dev/null
+++ b/book/art/figures/06-vo-entity.svg
@@ -0,0 +1,50 @@
+
diff --git a/book/art/figures/07-cqrs.svg b/book/art/figures/07-cqrs.svg
index 3764136a..af52a817 100644
--- a/book/art/figures/07-cqrs.svg
+++ b/book/art/figures/07-cqrs.svg
@@ -1,140 +1,118 @@
-
diff --git a/book/art/figures/08-eda.svg b/book/art/figures/08-eda.svg
index e0eb2f55..07997146 100644
--- a/book/art/figures/08-eda.svg
+++ b/book/art/figures/08-eda.svg
@@ -1,106 +1,95 @@
-
diff --git a/book/art/figures/09-eventsourcing.svg b/book/art/figures/09-eventsourcing.svg
index 86097362..80fe6d87 100644
--- a/book/art/figures/09-eventsourcing.svg
+++ b/book/art/figures/09-eventsourcing.svg
@@ -1,170 +1,156 @@
-
diff --git a/book/art/figures/10-messaging.svg b/book/art/figures/10-messaging.svg
index afb3c6ce..da9b9205 100644
--- a/book/art/figures/10-messaging.svg
+++ b/book/art/figures/10-messaging.svg
@@ -1,135 +1,112 @@
-
diff --git a/book/art/figures/11-client.svg b/book/art/figures/11-client.svg
index 08890244..59aa0018 100644
--- a/book/art/figures/11-client.svg
+++ b/book/art/figures/11-client.svg
@@ -1,96 +1,87 @@
-
diff --git a/book/art/figures/12-saga.svg b/book/art/figures/12-saga.svg
index 3b617fa0..a7987e3a 100644
--- a/book/art/figures/12-saga.svg
+++ b/book/art/figures/12-saga.svg
@@ -1,130 +1,103 @@
-
diff --git a/book/art/figures/13-cache.svg b/book/art/figures/13-cache.svg
index 680a6078..73a3c64d 100644
--- a/book/art/figures/13-cache.svg
+++ b/book/art/figures/13-cache.svg
@@ -1,112 +1,131 @@
-
diff --git a/book/art/figures/13-resilience.svg b/book/art/figures/13-resilience.svg
index 2697661e..426ea923 100644
--- a/book/art/figures/13-resilience.svg
+++ b/book/art/figures/13-resilience.svg
@@ -1,134 +1,109 @@
-
diff --git a/book/art/figures/14-security.svg b/book/art/figures/14-security.svg
index b5377b34..db6ee907 100644
--- a/book/art/figures/14-security.svg
+++ b/book/art/figures/14-security.svg
@@ -1,122 +1,122 @@
-
\ No newline at end of file
+ Authorization:
+ Bearer eyJ...
+ signed token per request
+ 1
+
+
+
+
+
+ Resource filter
+
+ validate signature
+ JWKS · issuer · audience
+ check exp
+ 2
+
+
+
+
+
+ claims -> roles
+
+ SecurityContext
+ sub · roles · permissions
+ readable by handlers
+ 3
+
+
+
+
+
+ Authz gate
+
+ @secure
+ role / permission
+ expression eval
+ 4
+
+
+
+
+
+ Identity provider
+
+ OIDC issuer
+ publishes JWKS keys
+
+
+
+ signing keys
+
+
+
+
+
+ Service
+
+ @service
+ business logic runs
+
+
+
+
+
+
+
+ 403 Forbidden
+
diff --git a/book/art/figures/15-observability.svg b/book/art/figures/15-observability.svg
index 3ac21a5e..4c87574d 100644
--- a/book/art/figures/15-observability.svg
+++ b/book/art/figures/15-observability.svg
@@ -1,98 +1,165 @@
-
\ No newline at end of file
+
+
+
+
+ Metrics
+
+ Prometheus
+
+
+
+
+
+
+
+
+
+
+ Traces
+
+ OpenTelemetry
+
+
+
+
+
+
+
+
+ Logs
+
+ structured JSON
+
+
+
+
+
+
+
+
+ Health
+
+ UP / DOWN
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Management port
+
+
+ port 9090
+ Actuator endpoints
+ /actuator/health
+ /actuator/prometheus
+ /actuator/loggers
+ /actuator/beans
+
+
+
+
+
+
+
+
+
+ Admin dashboard
+
+ /admin
+
+
+
+
+
+ Ops tooling
+
+ Prometheus scrape
+ Grafana / kubectl
+
+
+
+
+
+
+
+ Kubernetes probes
+
+ liveness and readiness hit the dedicated health sub-paths on 9090
+
+
+
+ /actuator/health/liveness
+
+
+ /actuator/health/readiness
+
+
+
+
+
+
diff --git a/book/art/figures/16-testing.svg b/book/art/figures/16-testing.svg
index 4489e738..2f3c3b23 100644
--- a/book/art/figures/16-testing.svg
+++ b/book/art/figures/16-testing.svg
@@ -1,103 +1,124 @@
-
\ No newline at end of file
+
+ PYRAMID
+ DEPENDENCIES + LUMEN APPROACH
+
diff --git a/book/art/figures/17-integrations.svg b/book/art/figures/17-integrations.svg
index bb5910ec..6c2a91a3 100644
--- a/book/art/figures/17-integrations.svg
+++ b/book/art/figures/17-integrations.svg
@@ -1,153 +1,169 @@
-
\ No newline at end of file
+
+
+
+
+
+ POST /webhook
+
+
+
+ POST
+
+
+ retry
+
diff --git a/book/art/figures/18-production.svg b/book/art/figures/18-production.svg
index fe3e3afb..8f26ba3e 100644
--- a/book/art/figures/18-production.svg
+++ b/book/art/figures/18-production.svg
@@ -1,120 +1,120 @@
-
\ No newline at end of file
+ Set management.server.port equal to server.port to collapse onto one port, or -1 to disable management endpoints.
+
diff --git a/book/dist/pyfly-by-example-es.epub b/book/dist/pyfly-by-example-es.epub
index a12314a3..633a000e 100644
Binary files a/book/dist/pyfly-by-example-es.epub and b/book/dist/pyfly-by-example-es.epub differ
diff --git a/book/dist/pyfly-by-example-es.pdf b/book/dist/pyfly-by-example-es.pdf
index 73adcd20..9c69f4aa 100644
Binary files a/book/dist/pyfly-by-example-es.pdf and b/book/dist/pyfly-by-example-es.pdf differ
diff --git a/book/dist/pyfly-by-example.epub b/book/dist/pyfly-by-example.epub
index 663ec5f0..da03f5c5 100644
Binary files a/book/dist/pyfly-by-example.epub and b/book/dist/pyfly-by-example.epub differ
diff --git a/book/dist/pyfly-by-example.pdf b/book/dist/pyfly-by-example.pdf
index e3b63631..10d2219f 100644
Binary files a/book/dist/pyfly-by-example.pdf and b/book/dist/pyfly-by-example.pdf differ
diff --git a/book/manuscript-es/05-persistence.md b/book/manuscript-es/05-persistence.md
index c7e603b8..86523612 100644
--- a/book/manuscript-es/05-persistence.md
+++ b/book/manuscript-es/05-persistence.md
@@ -269,6 +269,8 @@ El prefijo decide la *forma* del resultado: `find_by` devuelve una lista, `count
Un endpoint de listado nunca debería devolver *todos* los monederos. La *paginación* es la solución estándar: devolver una **página** de filas de tamaño fijo a la vez, más los metadatos suficientes para que el cliente pueda pedir la siguiente. Los tipos de paginación de PyFly —`Pageable` (qué página, qué tamaño, qué orden), `Sort` (la ordenación) y `Page[T]` (el fragmento más los metadatos)— se heredan directamente de la superficie CRUD a través de `find_all(pageable)`.
+::: figure art/figures/05-pagination.svg | Figura 5.2 — Un solo viaje de ida y vuelta: un Pageable (página, tamaño, orden) entra en find_all y vuelve un Page con el fragmento de filas más los totales que el cliente necesita para dibujar los controles de paginación.
+
Hay tres piezas pequeñas que ensamblar: el manejador que llama a `find_all(pageable)`, el `Page[T]` que devuelve y el controlador que construye el `Pageable` a partir de la petición. Las veremos en ese orden.
El manejador de consulta `ListWallets` de Lumen es toda la historia en tres líneas:
diff --git a/book/manuscript-es/06-domain-driven-design.md b/book/manuscript-es/06-domain-driven-design.md
index d8afcc19..2d550d0b 100644
--- a/book/manuscript-es/06-domain-driven-design.md
+++ b/book/manuscript-es/06-domain-driven-design.md
@@ -30,6 +30,8 @@ El DDD da nombre a estos dos roles: **entidades** y **objetos de valor**, y el m
Las entidades transitorias (las que tienen `id=None`) se comparan iguales solo por la identidad de objeto de Python, así que puedes meter entidades en conjuntos y diccionarios sin preocuparte por colisiones de hash de objetos sin guardar.
+::: figure art/figures/06-vo-entity.svg | Figura 6.1 — Dos clases de objeto de dominio: un objeto de valor Money (sin identidad, inmutable, comparado por sus campos) frente a una entidad Wallet (con identidad estable, mutable, comparada por id).
+
El dinero es el objeto de valor de manual. Un importe de cien euros no es un objeto específico que sigues en el tiempo; es un valor. Dos instancias separadas de `Money(100, "EUR")` son iguales. Un depósito no muta el importe existente: produce uno nuevo, dejando el original intacto y el modelo libre de efectos secundarios ocultos.
Aquí está el objeto de valor `Money` para Lumen:
@@ -367,7 +369,7 @@ uv run --extra dev pytest tests/test_wallet_aggregate.py -q
El diagrama de abajo muestra el panorama completo: estado, invariantes y los eventos que el monedero emite.
-::: figure art/figures/06-aggregate.svg | Figura 6.1 — El agregado Wallet: estado, invariantes y los eventos que emite.
+::: figure art/figures/06-aggregate.svg | Figura 6.2 — El agregado Wallet: estado, invariantes y los eventos que emite.
!!! spring "Equivalencia con Spring"
`AggregateRoot[str]` se corresponde con `org.jmolecules.ddd.types.AggregateRoot` de jMolecules y con `AbstractAggregateRoot` de Spring Data, que ofrece el mismo mecanismo `registerEvent()` / `@DomainEvents` / `@AfterDomainEventPublication`. El patrón es idéntico en espíritu: el agregado acumula eventos en un búfer; el repositorio los vacía tras un guardado exitoso; un `DomainEventPublisher` los despacha. El `raise_event` + `clear_events` de PyFly es el equivalente Python de `registerEvent` + `@AfterDomainEventPublication`.
diff --git a/book/manuscript/05-persistence.md b/book/manuscript/05-persistence.md
index c3b04677..7b9169c0 100644
--- a/book/manuscript/05-persistence.md
+++ b/book/manuscript/05-persistence.md
@@ -269,6 +269,8 @@ The prefix decides the *shape* of the result: `find_by` returns a list, `count_b
A list endpoint should never return *every* wallet. *Pagination* is the standard fix: return one fixed-size **page** of rows at a time, plus enough metadata for the client to ask for the next one. PyFly's pagination types — `Pageable` (what page, what size, what sort), `Sort` (the ordering), and `Page[T]` (the slice plus metadata) — are inherited straight from the CRUD surface via `find_all(pageable)`.
+::: figure art/figures/05-pagination.svg | Figure 5.2 — One round-trip: a Pageable (page, size, sort) goes into find_all, and a Page comes back carrying the row slice plus the total counts the client needs to render pagination controls.
+
There are three small pieces to assemble: the handler that calls `find_all(pageable)`, the `Page[T]` it returns, and the controller that builds the `Pageable` from the request. We will take them in that order.
Lumen's `ListWallets` query handler is the whole story in three lines:
diff --git a/book/manuscript/06-domain-driven-design.md b/book/manuscript/06-domain-driven-design.md
index 52170ede..a0169537 100644
--- a/book/manuscript/06-domain-driven-design.md
+++ b/book/manuscript/06-domain-driven-design.md
@@ -30,6 +30,8 @@ DDD names these two roles **entities** and **value objects**, and PyFly's `pyfly
Transient entities (those with `id=None`) compare equal only by Python's object identity, so you can safely put entities in sets and dicts without worrying about hash collisions from unsaved objects.
+::: figure art/figures/06-vo-entity.svg | Figure 6.1 — Two kinds of domain object: a Money value object (no identity, immutable, compared by its fields) versus a Wallet entity (a stable identity, mutable, compared by id).
+
Money is the textbook value object. An amount of one hundred euros is not a specific object you track over time; it is a value. Two separate `Money(100, "EUR")` instances are equal. A deposit does not mutate the existing amount — it produces a new one, leaving the original untouched and the model free of hidden side-effects.
Here is the `Money` value object for Lumen:
@@ -367,7 +369,7 @@ uv run --extra dev pytest tests/test_wallet_aggregate.py -q
The diagram below shows the complete picture: state, invariants, and the events the wallet emits.
-::: figure art/figures/06-aggregate.svg | Figure 6.1 — The Wallet aggregate: state, invariants, and the events it emits.
+::: figure art/figures/06-aggregate.svg | Figure 6.2 — The Wallet aggregate: state, invariants, and the events it emits.
!!! spring "Spring parity"
`AggregateRoot[str]` maps to jMolecules's `org.jmolecules.ddd.types.AggregateRoot` and to Spring Data's `AbstractAggregateRoot`, which offers the same `registerEvent()` / `@DomainEvents` / `@AfterDomainEventPublication` mechanism. The pattern is identical in spirit: the aggregate accumulates events in a buffer; the repository drains them after a successful save; a `DomainEventPublisher` dispatches them. PyFly's `raise_event` + `clear_events` is the Python equivalent of `registerEvent` + `@AfterDomainEventPublication`.
diff --git a/pyproject.toml b/pyproject.toml
index e23d62ab..2fa80297 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -7,7 +7,7 @@ name = "pyfly"
# CalVer YY.MM.PATCH — package metadata uses PEP 440 normalized form (26.5.4);
# git tag, GitHub release and human-readable display use leading-zero form
# (v26.05.04) to match the Java/.NET/Go siblings.
-version = "26.6.111"
+version = "26.6.112"
description = "The official Python implementation of the Firefly Framework — DI, CQRS, EDA, hexagonal architecture, and more."
readme = "README.md"
license = "Apache-2.0"
diff --git a/src/pyfly/__init__.py b/src/pyfly/__init__.py
index 82f07d35..b7fe128d 100644
--- a/src/pyfly/__init__.py
+++ b/src/pyfly/__init__.py
@@ -13,4 +13,4 @@
# limitations under the License.
"""PyFly — Enterprise Python Framework."""
-__version__ = "26.06.111"
+__version__ = "26.06.112"