diff --git a/app/pages/classroom.vue b/app/pages/classroom.vue
index e9de6d3..dad4463 100644
--- a/app/pages/classroom.vue
+++ b/app/pages/classroom.vue
@@ -1058,38 +1058,40 @@
Your readback
@@ -1423,7 +1425,7 @@ import {
altitudeToWords,
minutesToWords
} from '~~/shared/learn/scenario'
-import type {BlankWidth, Frequency, Lesson, LessonField, ModuleDef, Scenario} from '~~/shared/learn/types'
+import type {BlankWidth, Frequency, Lesson, LessonField, ModuleDef, ReadbackSegment, Scenario} from '~~/shared/learn/types'
import {loadPizzicatoLite} from '~~/shared/utils/pizzicatoLite'
import type {PizzicatoLite} from '~~/shared/utils/pizzicatoLite'
import {createNoiseGenerators, getReadabilityProfile} from '~~/shared/utils/radioEffects'
@@ -3376,6 +3378,33 @@ const correctReadbackText = computed(() => {
}).join('').trim()
})
+// Pair each input field with its preceding text label so they wrap together
+// as a single visual unit — otherwise the label (e.g. "runway") can land on
+// one line while the input lands on the next, forcing the user to look up to
+// remember what they're typing. Reported by Detlef (FSC e.V.).
+type ClozeGroup = { id: string; segments: ReadbackSegment[] }
+const clozeGroups = computed(() => {
+ if (!activeLesson.value) return []
+ const segments = activeLesson.value.readback
+ const groups: ClozeGroup[] = []
+ let i = 0
+ while (i < segments.length) {
+ const seg = segments[i]!
+ const next = segments[i + 1]
+ if (seg.type === 'text' && next && next.type === 'field') {
+ groups.push({ id: `g-${next.key}`, segments: [seg, next] })
+ i += 2
+ } else if (seg.type === 'field') {
+ groups.push({ id: `g-${seg.key}`, segments: [seg] })
+ i += 1
+ } else {
+ groups.push({ id: `g-t-${i}`, segments: [seg] })
+ i += 1
+ }
+ }
+ return groups
+})
+
async function speakCorrectReadback() {
const text = correctReadbackText.value
if (!text || ttsLoading.value) return
@@ -6605,12 +6634,28 @@ onMounted(() => {
display: flex;
flex-wrap: wrap;
gap: 10px;
- align-items: stretch;
+ align-items: flex-start;
line-height: 1.4;
text-transform: uppercase;
letter-spacing: .08em;
}
+/* Each label/text + its input field travel together as one wrap-unit so the
+ user always sees the prompt next to the blank they're filling. */
+.cloze-group {
+ display: inline-flex;
+ flex-wrap: nowrap;
+ gap: 10px;
+ align-items: stretch;
+ max-width: 100%;
+}
+
+@media (max-width: 640px) {
+ .cloze-group {
+ flex-wrap: wrap;
+ }
+}
+
.cloze-chunk {
display: inline-flex;
align-items: center;