/* Capsule 02 · the annotated manifest (beat 1), the sandbox (beat 2), the lifecycle simulator in two modes (beats 3
   and 4). Loaded with figures/android-manifest.js, android-sandbox.js and android-lifecycle.js, on capsule 02 only. */

/* ======================= Every figure: the static version stays for no-JS and print ======================= */
.fx-fallback[hidden] { display: none; }
@media print {
  .fx.is-mounted .fx-fallback[hidden] { display: block !important; }
  .fx.is-mounted > .fx__stage { display: none !important; }
}

/* ======================= Lifecycle simulator ======================= */
.al-top { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: clamp(18px, 4cqi, 40px); align-items: start; }
.al-phonecol { display: grid; justify-items: center; align-content: start; gap: 12px; min-width: 0; }
.al-phonebox { --w: clamp(150px, 19cqi, 186px); width: calc(var(--w) * 2.09); height: calc(var(--w) * 2.09); display: grid; place-items: center; }
/* Beat 3 never rotates the phone: its box is the phone's own size. */
.al--kill .al-phonebox { width: var(--w); }
.al-phone { --w: inherit; transition: transform .62s var(--fx-ease-io), box-shadow var(--fx-t-med) ease; }
.al-phone.is-land { transform: rotate(-90deg); }
.al-phone.is-tap { transform: scale(.985); }

/* The screen's content counter-rotates in landscape: the new activity lays itself out for the new shape. */
.al-ui { --sw: calc(var(--w) * .932); --sh: calc(var(--w) * 2.089 - var(--w) * .068); position: absolute; left: 50%; top: 50%; width: var(--sw); height: var(--sh); transform: translate(-50%, -50%); }
.al-phone.is-land .al-ui { width: var(--sh); height: var(--sw); transform: translate(-50%, -50%) rotate(90deg); }
.al-layer { position: absolute; inset: 9% 0 0; transition: opacity .26s ease, transform .26s var(--fx-ease-out); }
.al-layer.is-off { opacity: 0; transform: scale(.97); pointer-events: none; visibility: hidden; transition: opacity .26s ease, transform .26s var(--fx-ease-out), visibility 0s linear .26s; }

/* Launcher */
.al-launcher { padding: 1.2em 1.1em; display: grid; grid-template-columns: repeat(4, 1fr); align-content: start; gap: 1.2em .7em;
  background: radial-gradient(90% 60% at 10% 0%, rgba(255, 61, 139, .35), transparent 60%), radial-gradient(80% 60% at 100% 30%, rgba(122, 92, 255, .4), transparent 60%), radial-gradient(90% 60% at 40% 110%, rgba(47, 125, 255, .35), transparent 60%), #10121d; }
.al-phone.is-land .al-launcher { grid-template-columns: repeat(7, 1fr); }
.al-app-ic { display: grid; justify-items: center; gap: .35em; font: 500 .56em/1.1 var(--font-body); color: rgba(255, 255, 255, .8); }
.al-app-ic i { display: block; width: 2.3em; height: 2.3em; border-radius: .7em; background: var(--c, #3b3f63); }
.al-notes { all: unset; display: grid; justify-items: center; gap: .35em; cursor: pointer; font: 600 .56em/1.1 var(--font-body); color: #fff; border-radius: .6em; -webkit-tap-highlight-color: transparent; }
/* Notes is your app: your code's amber (the other apps on the ladder are neutral). */
.al-notes i { display: grid; place-items: center; width: 2.3em; height: 2.3em; border-radius: .7em; background: linear-gradient(135deg, #fcd34d, #d97706); box-shadow: 0 0 0 .15em rgba(251, 191, 36, .35), 0 .4em 1em rgba(217, 119, 6, .45); }
.al-notes i::before { content: ""; width: 1em; height: 1.2em; border-radius: .15em; background: linear-gradient(#fff, #fff) 50% 30% / 60% 1.5px no-repeat, linear-gradient(#fff, #fff) 50% 55% / 60% 1.5px no-repeat, linear-gradient(#fff, #fff) 50% 80% / 40% 1.5px no-repeat; border: 1.5px solid #fff; }
.al-notes:focus-visible { outline: 2px solid #a8a3ff; outline-offset: 3px; }
.al-notes span { font-size: 1em; }

/* The app: one screen, one draft */
.al-app { display: flex; flex-direction: column; gap: .8em; padding: .7em .8em; background: #f7f6fb; color: #1d1d27; }
.al-appbar { display: flex; align-items: center; gap: .5em; height: 2.4em; padding: 0 .3em; font: 700 .9em/1 var(--font-body); }
.al-appbar::before { content: ""; width: .9em; height: .9em; border-radius: .25em; background: linear-gradient(135deg, #fcd34d, #d97706); }
.al-field { display: grid; gap: .35em; font: 600 .62em/1.2 var(--font-body); color: #5b5b6b; letter-spacing: .04em; text-transform: uppercase; }
.al-draft { font: 500 1.45em/1.35 var(--font-body); letter-spacing: 0; text-transform: none; color: #1d1d27; background: #fff; border: 1px solid #d9d7e3; border-radius: .6em; padding: .6em .7em; resize: none; min-height: 5.2em; width: 100%; box-sizing: border-box; }
.al-draft:focus { outline: 2px solid #4f46e5; outline-offset: 1px; }
.al-draft::placeholder { color: #a5a3b3; }
.al-phone.is-land .al-app { flex-direction: row; flex-wrap: wrap; align-content: flex-start; }
.al-phone.is-land .al-appbar { width: 100%; }
.al-phone.is-land .al-field { flex: 1; }
.al-phone.is-land .al-draft { min-height: 3.6em; }
/* In landscape the camera cutout sits on the left edge: the app keeps clear of it, as Android's insets make a real app do. */
.al-phone.is-land .al-app, .al-phone.is-land .al-launcher { padding-left: 2.6em; }

/* Under the phone: which activity instance, in which process. A new instance flashes once. */
.al-instbadge {
  display: inline-flex; flex-wrap: wrap; justify-content: center; gap: 0 .45em; max-width: 100%; margin: 0 !important; padding: 5px 12px;
  border-radius: 999px; border: 1px solid var(--rule-strong); background: var(--surface);
  font: 600 .76rem/1.35 var(--font-mono) !important; color: var(--ink-2); text-align: center;
}
.al-instbadge b { font-weight: 700; color: var(--you); }
.al-instbadge.is-none { border-style: dashed; color: var(--ink-3); background: transparent; }
.al-instbadge.is-none b { color: var(--ink-3); font-weight: 600; }
.al-inst-n:empty, .al-inst-p:empty { display: none; }
.al-inst-n:not(:empty) + .al-inst-p::before { content: "· "; color: var(--ink-3); }
.al-instbadge.is-new { animation: al-newinst .8s var(--fx-ease-out); }
@keyframes al-newinst { 0% { border-color: var(--you); box-shadow: 0 0 0 0 color-mix(in srgb, var(--you) 50%, transparent); } 100% { box-shadow: 0 0 0 9px transparent; } }

/* A fresh instance flashes in; a destroyed one fades out. */
.al-app.is-born { animation: al-born .5s var(--fx-ease-out); }
@keyframes al-born { from { opacity: 0; transform: scale(.96); } }
.al-app.is-dying { opacity: .25; filter: grayscale(1); transition: opacity .2s ease, filter .2s ease; }

/* The system's permission dialog: another app's window on top of yours. */
.al-dialog { display: grid; place-items: center; padding: 1em; background: rgba(10, 10, 20, .45); inset: 0; }
.al-dialog__card { width: 100%; max-width: 15em; padding: 1em .9em .6em; border-radius: 1.1em; background: #fff; color: #1d1d27; text-align: center; box-shadow: 0 1em 2.4em rgba(0, 0, 0, .35); }
.al-dialog__card p { margin: 0 0 .8em !important; font: 600 .78em/1.35 var(--font-body) !important; }
.al-dialog__card button { all: unset; display: block; width: 100%; box-sizing: border-box; margin: .3em 0; padding: .55em .4em; border-radius: 1em; background: #e9e7f7; font: 600 .66em/1.2 var(--font-body); color: #3730a3; cursor: pointer; text-align: center; }
.al-dialog__card button:focus-visible { outline: 2px solid #4f46e5; outline-offset: 2px; }
.al-navpill { position: absolute; z-index: 2; left: 50%; bottom: 1.5%; width: 34%; height: .3em; border-radius: 1em; background: rgba(255, 255, 255, .55); transform: translateX(-50%); }
.al-screen.is-app .al-navpill { background: rgba(29, 29, 39, .45); }
.al-screen .fx-sb { color: #fff; }
.al-screen.is-app .fx-sb { color: #1d1d27; background: #f7f6fb; }
.al-screen.is-dead .al-app { opacity: 0; }

/* ---------- Side: the process, the importance ladder, the six callbacks ---------- */
.al-side { display: grid; gap: 14px; min-width: 0; }
.al-k { display: block; margin: 0 0 6px; font: 700 .68rem/1.3 var(--font-body); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-3); }
/* A Linux path keeps its case inside an uppercase label. */
.al-path { font: 600 .95em/1 var(--font-mono); letter-spacing: 0; text-transform: none; }

.al-lad { position: relative; }
.al-ladder { position: relative; list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-radius: 12px; border: 1px solid var(--rule); background: var(--fx-plate); overflow: hidden; }
.al-ladder > li { position: relative; margin: 0; padding: 8px 8px 64px; font: 600 .78rem/1.2 var(--font-body); color: var(--ink-2); border-left: 1px solid var(--rule); min-width: 0; }
.al-ladder > li:first-child { border-left: 0; }
.al-ladder > li small { display: block; margin-top: 2px; font: 500 .68rem/1.2 var(--font-body); color: var(--ink-3); }
.al-ladder > li.is-here { background: color-mix(in srgb, var(--accent) 9%, transparent); color: var(--ink); }
.al-others { position: absolute; left: 8px; bottom: 7px; display: flex; gap: 4px; }
.al-badge { display: inline-grid; place-items: center; height: 22px; padding: 0 7px; border-radius: 999px; font: 700 .66rem/1 var(--font-body); color: #fff; background: var(--c, #6b6f86); white-space: nowrap; transition: transform .2s var(--fx-ease-in), opacity .2s ease; }
.al-badge.is-killed { transform: scale(.4); opacity: 0; transition: transform .12s var(--fx-ease-in), opacity .12s linear; }
/* Your app's badge slides from rung to rung. */
.al-me { position: absolute; z-index: 2; left: 0; bottom: 34px; width: 25%; display: grid; justify-items: start; padding-left: 8px; transition: transform .5s var(--fx-ease-io), opacity .2s ease; pointer-events: none; }
/* Your app on the ladder: your code's colour (amber), as everywhere in the course. */
.al-me .al-badge { background: var(--you); color: var(--bg); box-shadow: 0 2px 8px color-mix(in srgb, var(--you) 45%, transparent); }
.al-me[data-at="vis"] { transform: translateX(100%); }
.al-me[data-at="svc"] { transform: translateX(200%); }
.al-me[data-at="cached"] { transform: translateX(300%); }
.al-me[data-at="none"] { opacity: 0; }
.al-ladder-cap { display: flex; justify-content: space-between; margin-top: 5px; font-size: .74rem; color: var(--ink-3); }

.al-mem { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 10px; }
.al-proc { position: relative; padding: 10px 12px 12px; border-radius: 12px; border: 1.5px solid var(--you); background: color-mix(in srgb, var(--you) 6%, var(--fx-plate)); transition: border-color .2s ease, background-color .2s ease, opacity .2s ease; min-width: 0; }
.al-proc__id { display: block; font: 600 .74rem/1.3 var(--font-mono); color: var(--you); margin-bottom: 8px; overflow-wrap: anywhere; }
.al-proc.is-none { border-style: dashed; border-color: var(--rule-strong); background: transparent; }
.al-proc.is-none .al-proc__id { color: var(--ink-3); }
.al-proc.is-cut { animation: al-cut .3s var(--fx-ease-in); }
@keyframes al-cut { 0% { box-shadow: 0 0 0 0 var(--fx-kill); border-color: var(--fx-kill); } 40% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--fx-kill) 30%, transparent); border-color: var(--fx-kill); } 100% { box-shadow: 0 0 0 0 transparent; } }
.al-store { padding: 10px 12px 12px; border-radius: 12px; border: 1px solid var(--rule); background: var(--fx-plate); min-width: 0; }
.al-store + .al-store { margin-top: 8px; }
.al-val { display: inline-flex; max-width: 100%; padding: 4px 8px; border-radius: 7px; font: 600 .76rem/1.3 var(--font-mono); background: var(--surface); border: 1px solid var(--rule-strong); color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.al-val.is-empty { color: var(--ink-3); border-style: dashed; background: transparent; font-weight: 500; }
.al-val.is-new { animation: fx-in var(--fx-t-short) var(--fx-ease-out); }
.al-val.is-gone { animation: al-gone .4s var(--fx-ease-in); }
@keyframes al-gone { 0% { background: color-mix(in srgb, var(--fx-kill) 20%, var(--surface)); border-color: var(--fx-kill); } }

/* The six callbacks: the capsule's own chain, now with a cursor. Your code runs in each one: the cursor is amber
   (your code), the names neutral (the course's colours keep their meanings: design review S8). */
.al-rail { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 6px; }
.al-rail li { position: relative; margin: 0; padding: 7px 3px; border-radius: 9px; border: 1px solid var(--rule); background: var(--fx-plate); font: 600 .68rem/1.2 var(--font-mono); letter-spacing: -.02em; color: var(--ink-2); text-align: center; overflow-wrap: anywhere; transition: background-color .2s ease, border-color .2s ease, color .2s ease, transform .2s var(--fx-ease-out); }
.al-rail li.is-now { border-color: var(--you); background: color-mix(in srgb, var(--you) 12%, var(--surface)); color: var(--ink); transform: translateY(-2px); box-shadow: 0 0 0 3px color-mix(in srgb, var(--you) 16%, transparent); }
.al-rail li[data-cb="onDestroy"] { border-style: dashed; }
.al-rail.is-cut li { opacity: .45; }
.al-rail.is-cut::after { content: "✂ " attr(data-cut); grid-column: 1 / -1; justify-self: start; font: 700 .8rem/1.3 var(--font-body); color: var(--fx-kill); }

/* ---------- Controls ---------- */
.al-controls { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 20px; }
.al-controls .fx-btn { flex: 1 1 auto; }
.al-opts { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 22px; margin: 10px 0 0; }
.al-opts .fx-btn { margin-left: auto; }

/* ---------- Narrow ---------- */
@container fx (max-width: 719px) {
  .al-top { grid-template-columns: minmax(0, 1fr); }
  .al-phonebox { --w: min(40cqi, 168px); }
  .al--loop .al-phonebox { --w: min(34cqi, 124px); }
  .al-mem { grid-template-columns: minmax(0, 1fr); }
  .al-rail { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .al-controls .fx-btn { flex: 1 1 40%; }
  .al-opts .fx-btn { margin-left: 0; width: 100%; }
}
@container fx (max-width: 420px) {
  .al-ladder > li { padding: 7px 5px 80px; font-size: .7rem; }
  .al-me { padding-left: 5px; bottom: 50px; } .al-others { left: 5px; flex-direction: column; align-items: flex-start; bottom: 5px; gap: 3px; } .al-badge { height: 18px; padding: 0 6px; font-size: .62rem; }
  .al-ladder > li small { display: none; }
}

/* ======================= The sandbox: one Linux user per app ======================= */
.sb-grid { position: relative; display: grid; grid-template-columns: minmax(190px, .72fr) minmax(0, 2.28fr); gap: clamp(14px, 2.6cqi, 26px); align-items: stretch; }
.sb-world { position: relative; min-width: 0; }
.sb-apps { position: relative; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
/* The package: a zip whose files you open one by one. */
.sb-apk { position: relative; display: flex; flex-direction: column; gap: 10px; padding: 12px 12px 14px; border-radius: 14px; border: 1.5px solid var(--you); background: color-mix(in srgb, var(--you) 6%, var(--fx-plate)); min-width: 0; }
.sb-apk__h { display: flex; align-items: center; gap: 10px; margin: 0 !important; }
.sb-apk__h b { display: block; font: 700 .95rem/1.2 var(--font-mono); color: var(--ink); }
.sb-apk__h small { display: block; font: 500 .74rem/1.3 var(--font-body); color: var(--ink-3); }
.sb-apk__zip { flex: none; width: 26px; height: 30px; border-radius: 5px; background: linear-gradient(135deg, #fcd34d, #d97706); position: relative; box-shadow: 0 4px 10px -4px rgba(217, 119, 6, .6); }
.sb-apk__zip::before { content: ""; position: absolute; left: 50%; top: 3px; bottom: 9px; width: 3px; margin-left: -1.5px; background: repeating-linear-gradient(180deg, #fff 0 2px, transparent 2px 4px); opacity: .9; }
.sb-files { list-style: none; margin: 0 !important; padding: 0 !important; display: grid; gap: 4px; }
.sb-files li { margin: 0 !important; }
.sb-file { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 34px; padding: 5px 9px; border-radius: 9px; border: 1px solid transparent; background: transparent; color: var(--ink-2); font: 600 .78rem/1.2 var(--font-mono); text-align: left; cursor: pointer; transition: background-color var(--fx-t-micro) ease, border-color var(--fx-t-micro) ease, color var(--fx-t-micro) ease; }
.sb-file svg { width: 15px; height: 15px; flex: none; color: var(--ink-3); }
.sb-file:hover { background: var(--surface); border-color: var(--rule); color: var(--ink); }
.sb-file[aria-pressed="true"] { background: var(--surface); border-color: var(--accent); color: var(--ink); box-shadow: 0 0 0 3px var(--accent-soft); }
.sb-file:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sb-file-line { margin: 0 !important; min-height: 4.2em; font-size: .84rem !important; line-height: 1.45; color: var(--ink-2); }
.sb-file-line code { font-size: .92em; }
.sb-install { margin-top: auto; }
.sb-install[aria-disabled="true"] { opacity: 1; background: transparent; color: var(--ok); border-color: color-mix(in srgb, var(--ok) 55%, transparent); cursor: default; }
/* Notes before install: an empty, dashed place; after: its own user and folder. */
.sb-app.is-new { border-style: dashed; background: transparent; }
.sb-app.is-new .sb-uid, .sb-app.is-new .sb-dir { visibility: hidden; }
.sb-notyet { position: absolute; left: 12px; right: 12px; top: 50%; margin-top: 2px; font: 500 .78rem/1.3 var(--font-body); color: var(--ink-3); text-align: center; }
.sb-app:not(.is-new) .sb-notyet { display: none; }
.sb-app.is-born { animation: sb-born .55s var(--fx-ease-out); }
@keyframes sb-born { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--you) 45%, transparent); } 50% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--you) 18%, transparent); } 100% { box-shadow: 0 0 0 0 transparent; } }
.sb-app { position: relative; padding: 12px 12px 14px; border-radius: 14px; border: 1.5px solid var(--c); background: color-mix(in srgb, var(--c) 6%, var(--fx-plate)); min-width: 0; }
.sb-app__h { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: .95rem; }
.sb-app__h i { width: 22px; height: 22px; border-radius: 7px; background: var(--c); flex: none; }
.sb-uid { display: block; margin: 6px 0 10px; font: 600 .74rem/1.3 var(--font-mono); color: var(--c); }
.sb-dir { position: relative; padding: 9px 10px; border-radius: 10px; background: var(--surface); border: 1px dashed var(--rule-strong); font: 600 .7rem/1.35 var(--font-mono); color: var(--ink-2); overflow-wrap: anywhere; transition: box-shadow .25s ease, border-color .25s ease; }
.sb-dir small { display: block; margin-top: 4px; font: 500 .7rem/1.3 var(--font-body); color: var(--ink-3); }
.sb-dir.is-hit { border-color: var(--fx-kill); box-shadow: 0 0 0 4px color-mix(in srgb, var(--fx-kill) 18%, transparent); }
.sb-dir.is-ok { border-color: var(--screen); box-shadow: 0 0 0 4px color-mix(in srgb, var(--screen) 16%, transparent); }
.sb-kernel { margin-top: 12px; padding: 9px 12px; border-radius: 12px; border: 1px solid var(--rule); background: color-mix(in srgb, var(--os) 7%, var(--fx-plate)); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 14px; font-size: .86rem; color: var(--ink-2); }
.sb-kernel b { color: var(--os); font: 700 .7rem/1.3 var(--font-body); letter-spacing: .1em; text-transform: uppercase; }
.sb-sys b { color: var(--os); }   /* the Android system is the OS: sky, like the kernel bar */
.sb-kernel.is-ok { border-color: var(--screen); box-shadow: 0 0 0 4px color-mix(in srgb, var(--screen) 14%, transparent); }
.sb-kernel.is-hit { border-color: var(--os); box-shadow: 0 0 0 4px color-mix(in srgb, var(--os) 14%, transparent); }
.sb-pkt { position: absolute; z-index: 3; left: 0; top: 0; padding: 4px 9px; border-radius: 999px; font: 700 .72rem/1.2 var(--font-mono); color: var(--bg); background: var(--you); box-shadow: 0 6px 16px -6px rgba(0, 0, 0, .5); opacity: 0; pointer-events: none; white-space: nowrap; }
.sb-pkt.is-denied { background: var(--fx-kill); }
.sb-pkt.is-ok { background: var(--screen); color: #0d1a14; }
.sb-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.sb-out { min-height: 3em; margin: 12px 0 0 !important; font-size: .98rem !important; line-height: 1.5; }
.sb-out code { font-size: .84em; }
@container fx (max-width: 760px) {
  .sb-grid { grid-template-columns: minmax(0, 1fr); }
  .sb-files { display: flex; flex-wrap: wrap; gap: 4px 6px; }
  .sb-file { width: auto; border-color: var(--rule); background: var(--surface); }
  .sb-file-line { min-height: 2.9em; }
}
@container fx (max-width: 560px) {
  .sb-apps { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .sb-app { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 12px; align-items: center; padding: 10px 12px; }
  .sb-app .sb-uid { margin: 0; text-align: right; }
  .sb-app .sb-dir { grid-column: 1 / -1; margin-top: 8px; }
  .sb-notyet { position: static; grid-column: 1 / -1; margin: 6px 0 0; text-align: left; }
  .sb-actions .fx-btn { width: 100%; }
}

/* ======================= The simulator, one beat at a time ======================= */
/* Beat 3, "kill": the ladder and where the draft lives. Beat 4, "loop": the six callbacks as a loop. */
.al--kill .al-railbox, .al--loop .al-ladbox, .al--loop .al-membox,
.al--kill [data-act="dialog"], .al--kill [data-act="back"], .al--kill [data-act="rotate"],
.al--loop [data-act="dialog"], .al--loop [data-act="back"],
.al--kill .al-a12-sw, .al--loop .al-a12-sw { display: none !important; }
.al--kill .al-ladder > li small, .al--kill .fx-switch small, .al--loop .fx-switch small { display: none; }
.al--kill .al-ladder > li { padding-bottom: 54px; }
.al--kill .al-me { bottom: 26px; }
.al--kill .al-side, .al--loop .al-side { gap: 18px; }
.al--kill .al-controls .fx-btn, .al--loop .al-controls .fx-btn { flex: 1 1 0; }
.al--kill .fx__hint, .al--loop .fx__hint { margin-bottom: 14px; }

/* The loop: down the right side (onResume to onPause), back up through onStart (come back), up the left side after
   onDestroy (rotate: a new activity), and the cut below onStop (killed: no callback runs). */
.al-loop {
  --node: color-mix(in srgb, var(--surface) 90%, transparent);
  display: grid; grid-template-columns: minmax(0, 1fr) 26px minmax(0, 1fr) 26px minmax(0, 1fr);
  grid-template-rows: auto 66px auto auto; align-items: center; color: var(--ink-3);
}
.al-node {
  position: relative; display: block; padding: 10px 4px; border-radius: 11px; border: 1px solid var(--rule-strong); background: var(--node);
  font: 600 .8rem/1.2 var(--font-mono); letter-spacing: -.02em; color: var(--ink-2); text-align: center; overflow-wrap: anywhere;
  box-shadow: var(--shadow-sm);
  transition: background-color .2s ease, border-color .2s ease, color .2s ease, transform .2s var(--fx-ease-out), opacity .2s ease;
}
.al-node[data-cb="onDestroy"] { border-style: dashed; box-shadow: none; }
.al-node.is-now { border-color: var(--you); background: color-mix(in srgb, var(--you) 13%, var(--surface)); color: var(--ink); transform: translateY(-2px); box-shadow: 0 0 0 3px color-mix(in srgb, var(--you) 16%, transparent); }
.al-loop > :nth-child(1) { grid-area: 1 / 1; } .al-loop > :nth-child(2) { grid-area: 1 / 2; } .al-loop > :nth-child(3) { grid-area: 1 / 3; }
.al-loop > :nth-child(4) { grid-area: 1 / 4; } .al-loop > :nth-child(5) { grid-area: 1 / 5; }
.al-v--rot { grid-area: 2 / 1; } .al-v--back { grid-area: 2 / 3; } .al-v--down { grid-area: 2 / 5; }
.al-loop > :nth-child(9) { grid-area: 3 / 1; } .al-loop > :nth-child(10) { grid-area: 3 / 2; } .al-loop > :nth-child(11) { grid-area: 3 / 3; }
.al-loop > :nth-child(12) { grid-area: 3 / 4; } .al-loop > :nth-child(13) { grid-area: 3 / 5; }
.al-cut { grid-area: 4 / 3 / 5 / 6; }
/* Horizontal arrows */
.al-ar { position: relative; display: block; height: 2px; margin: 0 4px; background: currentColor; opacity: .7; }
.al-ar::after { content: ""; position: absolute; top: -4px; border: 5px solid transparent; }
.al-ar--r::after { right: -5px; border-left: 7px solid currentColor; border-right: 0; }
.al-ar--l::after { left: -5px; border-right: 7px solid currentColor; border-left: 0; }
/* Vertical arrows, each with its label */
.al-v { position: relative; display: flex; align-items: center; justify-content: center; gap: 8px; align-self: stretch; padding: 6px 0; }
.al-v i { position: relative; flex: none; width: 2px; align-self: stretch; background: currentColor; opacity: .7; }
.al-v i::after { content: ""; position: absolute; left: -4px; border: 5px solid transparent; }
.al-v--rot i::after, .al-v--back i::after { top: -5px; border-bottom: 7px solid currentColor; border-top: 0; }
.al-v--down i::after { bottom: -5px; border-top: 7px solid currentColor; border-bottom: 0; }
.al-v small { font: 500 .74rem/1.25 var(--font-body); color: var(--ink-2); max-width: 9.5em; }
.al-v--rot small { order: -1; text-align: right; }
/* The cut: below onStop, in the kill's red. */
.al-cut { display: flex; align-items: flex-start; gap: 8px; padding: 0 0 0 calc((100% - 52px) / 6 - 1px); color: var(--fx-kill); }
.al-cut i { flex: none; width: 0; height: 22px; border-left: 2px dashed currentColor; }
.al-cut small { padding-top: 6px; font: 600 .76rem/1.25 var(--font-body); }
.al-loop.is-cut .al-node { opacity: .45; }
.al-loop.is-cut .al-cut small { text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 3px; }
@container fx (max-width: 719px) {
  .al-loop { grid-template-columns: minmax(0, 1fr) 16px minmax(0, 1fr) 16px minmax(0, 1fr); grid-template-rows: auto 74px auto auto; }
  .al-node { font-size: .7rem; padding: 9px 2px; }
  .al-v { flex-direction: column; gap: 4px; }
  .al-v i { align-self: center; flex: 1; min-height: 18px; }
  .al-v small { text-align: center !important; font-size: .68rem; order: 2 !important; max-width: none; }
  .al-cut { padding-left: calc((100% - 32px) / 6 - 1px); }
}

/* Beats 3 and 4 on a wide stage: the phone on the left; on the right, top to bottom, the panels, the controls, the
   switch and the log. The phone and its effects stay on one screen, with no empty band under the switch. */
@container fx (min-width: 720px) {
  .al--kill .fx__stage, .al--loop .fx__stage {
    display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: clamp(18px, 4cqi, 44px); align-items: start;
    grid-template-areas: "k k" "h h" "p s" "p c" "p o" "p r" "p l" "p z";
    grid-template-rows: auto auto auto auto auto auto auto 1fr;
  }
  .al--kill .al-top, .al--loop .al-top { display: contents; }
  .al--kill .fx__kicker, .al--loop .fx__kicker { grid-area: k; }
  .al--kill .fx__hint, .al--loop .fx__hint { grid-area: h; }
  .al--kill .al-phonecol, .al--loop .al-phonecol { grid-area: p; }
  .al--kill .al-side, .al--loop .al-side { grid-area: s; }
  .al--kill .al-controls, .al--loop .al-controls { grid-area: c; margin-top: 18px; }
  .al--kill .al-opts, .al--loop .al-opts { grid-area: o; }
  .al--kill .fx-refuse, .al--loop .fx-refuse { grid-area: r; }
  .al--kill .fx-log, .al--loop .fx-log { grid-area: l; margin-top: 8px; }
  .al--kill .fx-lesson, .al--loop .fx-lesson { grid-area: z; }
  /* Beat 3: memory, Bundle and file side by side, one row. */
  .al--kill .al-mem { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr) minmax(0, 1fr); }
  .al--kill .al-mem > div:not(.al-proc) { display: contents; }
  .al--kill .al-store + .al-store { margin-top: 0; }
}
/* Beat 3 on a phone: the phone beside its three buttons, then the switch, then what the system did (pedagogy S5:
   the variable and its effect on one screen). Beat 4 keeps the phone above, since it turns. */
@container fx (max-width: 719px) {
  .al--kill .fx__stage { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 14px; align-items: center; grid-template-areas: "k k" "h h" "p c" "p x" "o o" "s s" "r r" "l l" "z z"; }
  .al--kill .al-top { display: contents; }
  .al--kill .fx__kicker { grid-area: k; } .al--kill .fx__hint { grid-area: h; }
  .al--kill .al-phonecol { grid-area: p; } .al--kill .al-phonebox { --w: min(32cqi, 120px); }
  .al--kill .al-controls { grid-area: c; align-self: end; flex-direction: column; margin: 0; }
  .al--kill .al-controls .fx-btn { flex: none; width: 100%; }
  .al--kill .al-opts { display: contents; }
  .al--kill .al-opts .fx-switch:not(.al-a12-sw) { grid-area: o; margin-top: 14px; }
  .al--kill .al-reset { grid-area: x; align-self: start; width: 100%; margin: 8px 0 0; }
  .al--kill .al-mem > div:not(.al-proc) { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; }
  .al--kill .al-store + .al-store { margin-top: 0; }
  .al--kill .al-side { grid-area: s; margin-top: 16px; gap: 14px; }
  .al--kill .fx-refuse { grid-area: r; } .al--kill .fx-log { grid-area: l; margin-top: 8px; } .al--kill .fx-lesson { grid-area: z; }
  .al--loop .al-phonecol { margin-bottom: 4px; }
  .al--loop .al-side { margin-top: 6px; }
}
.al--kill .fx-lesson:empty, .al--loop .fx-lesson:empty { min-height: 0; margin: 0 !important; }

/* Presenting: a smaller phone and a tighter stage, so each simulator fits one slide. */
[data-teaching="true"] .al--kill .al-phonebox, [data-teaching="true"] .al--loop .al-phonebox { --w: 132px; }
[data-teaching="true"] .al--kill .fx__stage, [data-teaching="true"] .al--loop .fx__stage { padding: 14px 22px 16px; }
[data-teaching="true"] .al--kill .fx__kicker, [data-teaching="true"] .al--loop .fx__kicker { display: none; }
[data-teaching="true"] .al--kill .fx-log, [data-teaching="true"] .al--loop .fx-log { min-height: 48px; padding: 10px 12px 8px; }
[data-teaching="true"] .al--kill .al-ladder > li { padding-bottom: 44px; }
[data-teaching="true"] .al--kill .al-me { bottom: 18px; }
[data-teaching="true"] .al--kill .al-side, [data-teaching="true"] .al--loop .al-side { gap: 10px; }
[data-teaching="true"] .al--kill .al-controls, [data-teaching="true"] .al--loop .al-controls { margin-top: 12px; }
[data-teaching="true"] .al--loop .al-loop { grid-template-rows: auto 54px auto auto; }
[data-teaching="true"] .al--kill .fx__hint, [data-teaching="true"] .al--loop .fx__hint { margin-bottom: 8px; }
[data-teaching="true"] .al--kill .fx-refuse:empty, [data-teaching="true"] .al--loop .fx-refuse:empty { min-height: 0; margin: 0 !important; }

/* ======================= Beat 1: the annotated manifest ======================= */
/* A paper figure like the others; only the code is a night panel (code is a night chip in both themes). On the right,
   the four notes, all listed, one open: the one whose highlight or title was pressed. */
.mf__grid { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: clamp(16px, 3cqi, 30px); align-items: start; }
.mf__code {
  min-width: 0; padding: 12px 14px 14px; border-radius: 16px; background: var(--code-bg); border: 1px solid var(--code-rule);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05), 0 22px 40px -28px rgba(12, 14, 30, .75);
}
.mf__bar { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; margin: 0 0 10px !important; padding: 0 2px 10px; border-bottom: 1px dashed var(--code-rule); }
.mf__file { font: 600 .78rem/1.3 var(--font-mono); color: var(--ink); }
.mf__as { font: 500 .78rem/1.3 var(--font-body); color: var(--ink-3); }
.mf__pre {
  margin: 0; padding: 2px 2px 0; overflow-x: auto; -webkit-overflow-scrolling: touch; background: none; border: 0;
  font: 500 .8rem/1.75 var(--font-mono); color: var(--ink-2); white-space: pre; tab-size: 2;
}
.mf__pre .t { color: var(--ink-3); }
.mf__hl {
  position: relative; display: inline; margin: 0 -3px; padding: 3px; border: 0; border-radius: 6px; cursor: pointer; line-height: inherit; vertical-align: baseline;
  font: inherit; color: var(--ink); text-align: left; background: color-mix(in srgb, var(--accent) 16%, transparent);
  box-shadow: inset 0 -1.5px 0 color-mix(in srgb, var(--accent) 70%, transparent);
  transition: background-color .16s ease, box-shadow .16s ease;
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
}
.mf__hl:hover { background: color-mix(in srgb, var(--accent) 26%, transparent); }
.mf__hl[aria-pressed="true"] { background: var(--accent); color: #12131a; box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent); }
.mf__hl:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.mf__n {
  display: inline-grid; place-items: center; width: 1.45em; height: 1.45em; margin-left: 6px; border-radius: 50%; vertical-align: .08em;
  font: 700 .66rem/1 var(--font-mono); color: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
}
/* The digit comes from data-n: a pointer between the code and its note, not a word to read (aria-hidden). */
.mf__n::before { content: attr(data-n); }
.mf__side { min-width: 0; }
.mf__side > .fx__hint { margin-bottom: 12px; }
.mf:not(.js-ready) .mf__hint { display: none; }
.mf__notes { display: grid; gap: 8px; }
.mf__note { margin: 0; border-radius: 14px; border: 1px solid var(--rule); background: var(--fx-plate); transition: border-color .16s ease, background-color .16s ease, box-shadow .16s ease; }
.mf__k { display: flex; align-items: center; gap: 10px; margin: 0 !important; padding: 12px 14px 4px; font: 600 .8rem/1.3 var(--font-mono) !important; color: var(--ink-2); }
.mf__k .mf__n { margin: 0; flex: none; }
.mf__t { margin: 0 !important; padding: 0 14px 12px; font-size: .95rem !important; line-height: 1.55; color: var(--ink); }
.mf__t code { font-size: .84em; }
/* With JavaScript: each title is a button, 44 px tall; the open note is lit. */
.mf.js-ready .mf__k { padding: 0; }
.mf__key {
  all: unset; box-sizing: border-box; display: flex; align-items: center; gap: 10px; width: 100%; min-height: 44px; padding: 8px 14px;
  border-radius: 13px; cursor: pointer; font: inherit; color: inherit; -webkit-tap-highlight-color: transparent;
}
.mf__key:hover { color: var(--ink); }
.mf__key:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.mf__note.is-on { border-color: color-mix(in srgb, var(--accent) 55%, transparent); background: color-mix(in srgb, var(--accent) 6%, var(--surface)); box-shadow: 0 0 0 3px var(--accent-soft); }
.mf__note.is-on .mf__k { color: var(--accent); }
.mf.js-ready .mf__t { padding-left: 48px; }
.mf.js-ready .mf__t:not([hidden]) { animation: fx-in .32s cubic-bezier(.2, .7, .2, 1) both; }
@container fx (max-width: 760px) { .mf__grid { grid-template-columns: minmax(0, 1fr); } }
/* Phones: the code wraps (an attribute goes under its element) rather than run off the right edge. */
@container fx (max-width: 560px) {
  .mf__code { padding: 10px 8px 12px; }
  .mf__pre { white-space: pre-wrap; overflow-wrap: break-word; font-size: .7rem; line-height: 1.7; }
  .mf__n { margin-left: 3px; }
}
@media (prefers-reduced-motion: reduce) { .mf.js-ready .mf__t { animation: none !important; } }
[data-teaching="true"] .mf .fx__stage { padding: 18px 22px; }
[data-teaching="true"] .mf .fx__kicker { display: none; }
@media print { .mf__t[hidden] { display: block !important; } }
