suppressPackageStartupMessages(library(tidyverse))
blue <- "#2C7FB8"
gold <- "#EDB458"
grey <- "#5B6770"
fill_n <- "#D6EAF2" # NOW boxes
fill_t <- "grey95" # THEN boxes
ink_n <- "#1b3b52"
hw <- 0.95; hh <- 0.42 # box half-width / half-height
# ---- THEN: a straight, linear track (y = 3.6) ------------------------
ty <- 3.6
tx <- c(1.4, 4.0, 6.6, 9.2)
then_rect <- tibble(xmin = tx - hw, xmax = tx + hw, ymin = ty - hh, ymax = ty + hh)
then_txt <- tibble(
x = tx, y = ty,
label = c("Pick a\nskill", "Study\nbooks & docs",
"Get stuck,\nsearch, ask", "Finally\napply")
)
then_arr <- tibble(x = tx[-4] + hw, xend = tx[-1] - hw, y = ty, yend = ty)
# ---- NOW: a loop you enter through a gate (y = 1.0) ------------------
ny <- 1.0
gx <- 1.1
nx <- c(3.7, 6.3, 8.9) # Try, Ask, Learn
now_rect <- tibble(xmin = nx - hw, xmax = nx + hw, ymin = ny - hh, ymax = ny + hh)
now_txt <- tibble(x = nx, y = ny,
label = c("Try it in\nreal work", "Ask the\nagent", "Learn"))
gate_rect <- tibble(xmin = gx - hw, xmax = gx + hw, ymin = ny - hh, ymax = ny + hh)
gate_txt <- tibble(x = gx, y = ny, label = "Cognitive\ncourage")
# forward arrows: gate -> Try -> Ask -> Learn
now_arr <- tibble(x = c(gx, nx[1], nx[2]) + hw,
xend = c(nx[1], nx[2], nx[3]) - hw, y = ny, yend = ny)
# return loop: Learn -> Try, arcing up and over the row
ret <- tibble(x = nx[3], y = ny + hh, xend = nx[1], yend = ny + hh)
ggplot() +
annotate("text", x = 0.15, y = 4.62, hjust = 0, fontface = "bold",
size = 4.1, colour = grey,
label = "THEN · learning was a separate project") +
annotate("text", x = 0.15, y = 2.62, hjust = 0, fontface = "bold",
size = 4.1, colour = blue,
label = "NOW · learning happens inside the work") +
# THEN track
geom_rect(data = then_rect,
aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax),
fill = fill_t, colour = grey, linewidth = 0.5) +
geom_segment(data = then_arr, aes(x = x, y = y, xend = xend, yend = yend),
arrow = arrow(length = unit(0.16, "cm"), type = "closed"),
linewidth = 0.5, colour = grey) +
geom_text(data = then_txt, aes(x, y, label = label),
fontface = "bold", size = 3.05, lineheight = 0.92, colour = grey) +
annotate("text", x = 10.75, y = ty, hjust = 0, fontface = "italic",
size = 3.1, colour = grey, label = "weeks") +
# NOW return loop (behind the boxes)
geom_curve(data = ret, aes(x = x, y = y, xend = xend, yend = yend),
curvature = 0.24, ncp = 16, angle = 90,
arrow = arrow(length = unit(0.16, "cm"), type = "closed"),
linewidth = 0.55, colour = blue) +
annotate("text", x = (nx[1] + nx[3]) / 2, y = 2.34, fontface = "italic",
size = 3.1, colour = blue, label = "repeat in minutes") +
# NOW gate, forward arrows, boxes
geom_rect(data = gate_rect,
aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax),
fill = gold, colour = "grey35", linewidth = 0.5) +
geom_text(data = gate_txt, aes(x, y, label = label),
fontface = "bold", size = 3.05, lineheight = 0.92, colour = "grey15") +
geom_segment(data = now_arr, aes(x = x, y = y, xend = xend, yend = yend),
arrow = arrow(length = unit(0.16, "cm"), type = "closed"),
linewidth = 0.55, colour = blue) +
geom_rect(data = now_rect,
aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax),
fill = fill_n, colour = blue, linewidth = 0.6) +
geom_text(data = now_txt, aes(x, y, label = label),
fontface = "bold", size = 3.05, lineheight = 0.92, colour = ink_n) +
coord_fixed(clip = "off", xlim = c(0, 11.7), ylim = c(0.4, 4.95)) +
theme_void() -> p
ggsave(
here::here("posts", "2026-07-27-cognitive-courage", "courage-loop.png"),
p, width = 8, height = 3.2, dpi = 160, bg = "white"
)
p