feat: A1 短材料复现本单元理解词,并加入黑夜模式

课程内容
- 重写全部 21 个 A1 单元的听读材料,把本单元理解词织进听/读文本,
  单元内理解词复现率从约 20% 提升到约 77%(各单元 56–96%)。
- 修正 U01 房间号与机场大巴同为 thirty 的撞车(改为 17/30/40)。
- 校验器容差按级别读取(A1 为 8%),materials 覆盖率、字数、
  选项子串等校验全部通过;course_content_test 通过。

黑夜模式
- app_theme 拆分明/暗两套调色板,AppColors 随亮度切换;
  main 用 theme/darkTheme/themeMode + builder 镜像已解析亮度;
  主题偏好持久化到快照;进度页新增“外观主题”切换。

文档
- COURSE-PACK-JSON.md 更新 A1 词池覆盖(840/933)与材料复现约定。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-18 11:16:09 +09:00
co-authored by Claude Opus 4.8
parent 9ab08c25ef
commit febfd30f49
93 changed files with 72676 additions and 274 deletions
+975
View File
@@ -0,0 +1,975 @@
{
"schemaVersion": 1,
"id": "A1-U13",
"revision": 1,
"level": "A1",
"title": "日期与约时间",
"categories": [
"日常"
],
"canDo": "说日期、约见面、改时间",
"status": "draft",
"meta": {
"draftedBy": "claude-opus-5",
"draftedAt": "2026-09-17",
"sources": [
"CEFR-J Vocabulary Profile 1.5",
"CEFR-J Grammar Profile 20180315"
],
"reviews": [],
"frozenAt": null
},
"names": [],
"grammar": [
{
"id": "239",
"use": "active"
},
{
"id": "236",
"use": "active",
"reason": "CEFR-J 未标级别,When 问句是约时间的必需句型"
},
{
"id": "120",
"use": "active"
},
{
"id": "21",
"use": "active",
"reason": "日期用 in March、on Friday、at three"
},
{
"id": "59-2",
"use": "receptive"
}
],
"coreItems": [
{
"id": "A1-U13-P01",
"type": "phrase",
"en": "What's the date today?",
"zh": "今天几号?",
"sceneWord": false,
"match": [
[
"what's the date",
"what is the date"
]
],
"example": {
"en": "What's the date tomorrow?",
"zh": "明天几号?"
},
"review": {
"prompt": "问今天几号。"
}
},
{
"id": "A1-U13-P02",
"type": "phrase",
"en": "When is your birthday?",
"zh": "你的生日是哪天?",
"sceneWord": false,
"match": [
[
"when is your birthday",
"when's your birthday"
]
],
"example": {
"en": "When is your birthday, Anna?",
"zh": "安娜,你的生日是哪天?"
},
"review": {
"prompt": "问新朋友的生日。"
}
},
{
"id": "A1-U13-P03",
"type": "phrase",
"en": "My birthday is in March.",
"zh": "我的生日在三月。",
"sceneWord": false,
"match": [
[
"in january",
"in february",
"in march",
"in april",
"in may",
"in june",
"in july",
"in august",
"in september",
"in october",
"in november",
"in december"
]
],
"example": {
"en": "The party is in July.",
"zh": "聚会在七月。"
},
"review": {
"prompt": "说你的生日在几月。"
}
},
{
"id": "A1-U13-P04",
"type": "phrase",
"en": "Are you free on Saturday?",
"zh": "你周六有空吗?",
"sceneWord": false,
"match": [
[
"are you free"
]
],
"example": {
"en": "Are you free tomorrow?",
"zh": "你明天有空吗?"
},
"review": {
"prompt": "问朋友周六有没有空。"
}
},
{
"id": "A1-U13-P05",
"type": "phrase",
"en": "Sorry, I'm busy.",
"zh": "抱歉,我没空。",
"sceneWord": false,
"match": [
[
"i'm busy",
"i am busy"
]
],
"example": {
"en": "Sorry, I'm busy on Friday.",
"zh": "抱歉,我周五没空。"
},
"review": {
"prompt": "礼貌地说你那天没空。"
}
},
{
"id": "A1-U13-P06",
"type": "phrase",
"en": "How about Sunday?",
"zh": "周日怎么样?",
"sceneWord": false,
"match": [
[
"how about"
]
],
"example": {
"en": "How about next week?",
"zh": "下周怎么样?"
},
"review": {
"prompt": "提议改到周日。"
}
},
{
"id": "A1-U13-P07",
"type": "phrase",
"en": "Let's meet at three.",
"zh": "我们三点见吧。",
"sceneWord": false,
"match": [
[
"let's meet",
"let us meet"
]
],
"example": {
"en": "Let's meet at the station.",
"zh": "我们在车站见吧。"
},
"review": {
"prompt": "约朋友三点见面。"
}
},
{
"id": "A1-U13-P08",
"type": "phrase",
"en": "What time is good for you?",
"zh": "你几点方便?",
"sceneWord": false,
"match": [
[
"good for you"
]
],
"example": {
"en": "Is Friday good for you?",
"zh": "周五你方便吗?"
},
"review": {
"prompt": "问对方几点方便。"
}
},
{
"id": "A1-U13-P09",
"type": "phrase",
"en": "See you then.",
"zh": "到时见。",
"sceneWord": false,
"match": [
[
"see you then"
]
],
"example": {
"en": "OK, Saturday at two. See you then.",
"zh": "好,周六两点。到时见。"
},
"review": {
"prompt": "约好时间后道别。"
}
},
{
"id": "A1-U13-P10",
"type": "phrase",
"en": "next week",
"zh": "下周",
"sceneWord": false,
"match": [
[
"next week",
"next month",
"next monday",
"next friday"
]
],
"example": {
"en": "I'm free next week.",
"zh": "我下周有空。"
},
"review": {
"prompt": "说你下周有空。"
}
},
{
"id": "A1-U13-P11",
"type": "phrase",
"en": "Can we change the date?",
"zh": "我们能改个日期吗?",
"sceneWord": false,
"match": [
[
"change the date",
"change the time"
]
],
"example": {
"en": "Sorry, can we change the time?",
"zh": "抱歉,我们能改个时间吗?"
},
"review": {
"prompt": "请对方改个日期。"
}
},
{
"id": "A1-U13-W01",
"type": "word",
"en": "tomorrow",
"zh": "明天",
"sceneWord": false,
"match": [
[
"tomorrow"
]
],
"example": {
"en": "See you tomorrow!",
"zh": "明天见!"
},
"review": {
"prompt": "说你明天有空。"
}
},
{
"id": "A1-U13-W02",
"type": "word",
"en": "party",
"zh": "聚会",
"sceneWord": false,
"match": [
[
"party",
"parties"
]
],
"example": {
"en": "Come to my birthday party!",
"zh": "来参加我的生日聚会吧!"
},
"review": {
"prompt": "请朋友来你的聚会。"
}
}
],
"receptiveWords": [
{
"id": "A1-U13-R01",
"en": "January",
"zh": "一月"
},
{
"id": "A1-U13-R02",
"en": "February",
"zh": "二月"
},
{
"id": "A1-U13-R03",
"en": "April",
"zh": "四月"
},
{
"id": "A1-U13-R04",
"en": "June",
"zh": "六月"
},
{
"id": "A1-U13-R05",
"en": "July",
"zh": "七月"
},
{
"id": "A1-U13-R06",
"en": "August",
"zh": "八月"
},
{
"id": "A1-U13-R07",
"en": "September",
"zh": "九月"
},
{
"id": "A1-U13-R08",
"en": "October",
"zh": "十月"
},
{
"id": "A1-U13-R09",
"en": "November",
"zh": "十一月"
},
{
"id": "A1-U13-R10",
"en": "December",
"zh": "十二月"
},
{
"id": "A1-U13-R11",
"en": "month",
"zh": "月"
},
{
"id": "A1-U13-R12",
"en": "later",
"zh": "稍后;以后"
},
{
"id": "A1-U13-R13",
"en": "ago",
"zh": "以前"
},
{
"id": "A1-U13-R14",
"en": "pm",
"zh": "下午(p.m.)"
},
{
"id": "A1-U13-R15",
"en": "plan",
"zh": "计划"
},
{
"id": "A1-U13-R16",
"en": "celebrate",
"zh": "庆祝"
},
{
"id": "A1-U13-R17",
"en": "remember",
"zh": "记得"
},
{
"id": "A1-U13-R18",
"en": "forget",
"zh": "忘记"
},
{
"id": "A1-U13-R19",
"en": "hope",
"zh": "希望"
},
{
"id": "A1-U13-R20",
"en": "wish",
"zh": "祝愿"
},
{
"id": "A1-U13-R21",
"en": "dear",
"zh": "亲爱的"
},
{
"id": "A1-U13-R22",
"en": "luck",
"zh": "运气"
},
{
"id": "A1-U13-R23",
"en": "age",
"zh": "年龄"
},
{
"id": "A1-U13-R24",
"en": "invite",
"zh": "邀请"
},
{
"id": "A1-U13-R25",
"en": "wedding",
"zh": "婚礼"
},
{
"id": "A1-U13-R26",
"en": "holiday",
"zh": "假日"
},
{
"id": "A1-U13-R27",
"en": "festival",
"zh": "节日"
},
{
"id": "A1-U13-R28",
"en": "calendar",
"zh": "日历"
},
{
"id": "A1-U13-R29",
"en": "bye",
"zh": "再见"
},
{
"id": "A1-U13-R30",
"en": "cut",
"zh": "切"
},
{
"id": "A1-U13-R31",
"en": "mom",
"zh": "妈妈"
},
{
"id": "A1-U13-R32",
"en": "dad",
"zh": "爸爸"
},
{
"id": "A1-U13-R33",
"en": "maybe",
"zh": "也许"
},
{
"id": "A1-U13-R34",
"en": "together",
"zh": "一起"
},
{
"id": "A1-U13-R35",
"en": "know",
"zh": "知道"
}
],
"segments": [
{
"id": "A1-U13-S1",
"title": "日期和生日",
"minutes": 12,
"itemIds": [
"A1-U13-P01",
"A1-U13-P02",
"A1-U13-P03",
"A1-U13-W01"
],
"listening": {
"text": "What's the date today? It's May 5. And tomorrow is May 6. Oh, tomorrow is my birthday!",
"question": "说话人的生日是几号?",
"options": [
"五月六日",
"五月五日",
"六月五日"
]
},
"speaking": [
{
"text": "What's the date today?"
},
{
"text": "When is your birthday?"
},
{
"text": "My birthday is in March.",
"tip": "March 读 /mɑːtʃ/,月份首字母要大写"
},
{
"text": "See you tomorrow!"
}
],
"reading": {
"text": "Our birthdays\nThere are twelve months in a year. Look at our family calendar:\nMom: January 12\nDad: April 3\nMy sister: August 20\nMy brother: October 9\nMe: December 25\nMy grandfather: February, my grandmother: June, my aunt: July, my uncle: September, my cousin: November.\nMy grandmother's age? Eighty! We always celebrate with a big cake, and she cuts it.",
"question": "谁的生日在十月?",
"options": [
"哥哥",
"妈妈",
"姐姐"
]
},
"writing": {
"prompt": "写两句话:问朋友生日是哪天,再说你的生日在几月。",
"example": "When is your birthday? My birthday is in March.",
"itemIds": [
"A1-U13-P02",
"A1-U13-P03"
]
},
"independent": {
"prompt": "用英语说说你家里两个人的生日在几月。",
"itemIds": [
"A1-U13-P03"
]
}
},
{
"id": "A1-U13-S2",
"title": "约时间",
"minutes": 13,
"itemIds": [
"A1-U13-P04",
"A1-U13-P05",
"A1-U13-P06",
"A1-U13-P07",
"A1-U13-P08",
"A1-U13-P09"
],
"listening": {
"text": "Are you free on Saturday? Sorry, I'm busy on Saturday. How about Sunday? Sunday is good. Let's meet at three. OK, see you then.",
"question": "他们约在哪天见面?",
"options": [
"周日",
"周六",
"周五"
]
},
"speaking": [
{
"text": "Are you free on Saturday?"
},
{
"text": "Sorry, I'm busy."
},
{
"text": "How about Sunday?"
},
{
"text": "Let's meet at three."
},
{
"text": "What time is good for you?"
},
{
"text": "See you then."
}
],
"reading": {
"text": "Nina: Hi Leo! Are you free on Friday? Let's have dinner.\nLeo: Sorry, I'm busy on Friday. I work until 9 pm. How about Saturday?\nNina: Saturday is good. What time is good for you?\nLeo: 7 pm? Let's meet at the restaurant.\nNina: OK! See you then. Bye!",
"question": "Leo 为什么周五不行?",
"options": [
"他要工作到九点",
"他要去生日聚会",
"他忘了时间"
]
},
"writing": {
"prompt": "写两句话:问朋友周六有没有空,再约三点见面。",
"example": "Are you free on Saturday? Let's meet at three.",
"itemIds": [
"A1-U13-P04",
"A1-U13-P07"
]
},
"independent": {
"prompt": "朋友约你周五见,你没空,用英语拒绝并提议别的时间。",
"itemIds": [
"A1-U13-P05",
"A1-U13-P06",
"A1-U13-P08"
]
}
},
{
"id": "A1-U13-S3",
"title": "改期和聚会",
"minutes": 12,
"itemIds": [
"A1-U13-P10",
"A1-U13-P11",
"A1-U13-W02"
],
"listening": {
"text": "Hi, it's Tom. Sorry, I can't come to the party tomorrow. Can we change the date? Maybe next week?",
"question": "Tom 想把见面改到什么时候?",
"options": [
"下周",
"明天",
"下个月"
]
},
"speaking": [
{
"text": "Can we change the date?"
},
{
"text": "I'm free next week."
},
{
"text": "Come to my birthday party!"
},
{
"text": "Remember the date!"
}
],
"reading": {
"text": "Dear friends,\nI want to invite you to my birthday party! It's on Saturday, June 14, at 6 pm. We can eat cake and celebrate together. Please don't forget! We had this plan two months ago!\nIt's a holiday plan too: there's a festival in the park later that night.\nSorry, we can't change the date. My brother's wedding is two days later.\nI hope you can come. Wish me luck with the cake!\nMia",
"question": "聚会是哪一天?",
"options": [
"六月十四日",
"六月六日",
"六月十六日"
]
},
"writing": {
"prompt": "写两句话:说抱歉,然后问能不能改到下周。",
"example": "Sorry, can we change the date? How about next week?",
"itemIds": [
"A1-U13-P11",
"A1-U13-P10"
]
},
"independent": {
"prompt": "用英语邀请朋友来你的聚会,说出日期和时间。",
"itemIds": [
"A1-U13-W02",
"A1-U13-P07"
]
}
}
],
"scenes": [
{
"id": "A1-U13-C1",
"kind": "main",
"title": "约朋友吃饭",
"learnerRole": "你",
"aiRole": "朋友",
"setting": "你给朋友打电话,想约周末一起吃饭。",
"turns": [
{
"ai": "Hi! What's up?",
"goal": "问朋友周六有没有空",
"model": "Are you free on Saturday?",
"zh": "你周六有空吗?",
"itemIds": [
"A1-U13-P04"
]
},
{
"ai": "Sorry, I'm busy on Saturday. It's my mom's birthday.",
"goal": "提议周日",
"model": "How about Sunday?",
"zh": "周日怎么样?",
"itemIds": [
"A1-U13-P06"
]
},
{
"ai": "Sunday is OK. What time?",
"goal": "问对方几点方便",
"model": "What time is good for you?",
"zh": "你几点方便?",
"itemIds": [
"A1-U13-P08"
]
},
{
"ai": "Six pm is good for me.",
"goal": "约在饭店六点见",
"model": "Let's meet at six at the restaurant.",
"zh": "我们六点在饭店见吧。",
"itemIds": [
"A1-U13-P07"
]
},
{
"ai": "Great. I can't wait!",
"goal": "说到时见",
"model": "See you then.",
"zh": "到时见。",
"itemIds": [
"A1-U13-P09"
]
}
]
},
{
"id": "A1-U13-C2",
"kind": "variant",
"title": "邀请同事来生日聚会",
"learnerRole": "过生日的人",
"aiRole": "同事",
"setting": "你下周过生日,想邀请同事来聚会。",
"turns": [
{
"ai": "Hi! You look happy today.",
"goal": "说你的生日在下周",
"model": "My birthday is next week.",
"zh": "我的生日在下周。",
"itemIds": [
"A1-U13-P10"
]
},
{
"ai": "Oh, nice! What's the date?",
"goal": "说是五月九日,请对方来聚会",
"model": "It's May 9. Come to my party!",
"zh": "是五月九日。来参加我的聚会吧!",
"itemIds": [
"A1-U13-W02"
]
},
{
"ai": "I'd love to. When is it?",
"goal": "说还不知道时间,也许明天知道",
"model": "I don't know the time yet. Maybe tomorrow.",
"zh": "我还不知道时间,也许明天就知道。",
"itemIds": [
"A1-U13-W01"
]
},
{
"ai": "OK. When is your birthday, then?",
"goal": "说你的生日在五月",
"model": "My birthday is in May.",
"zh": "我的生日在五月。",
"itemIds": [
"A1-U13-P03"
]
},
{
"ai": "And when is my birthday? Do you remember?",
"goal": "反问对方生日是哪天",
"model": "No! When is your birthday?",
"zh": "不记得!你的生日是哪天?",
"itemIds": [
"A1-U13-P02"
]
}
]
},
{
"id": "A1-U13-C3",
"kind": "variant",
"title": "改期",
"learnerRole": "你",
"aiRole": "朋友",
"setting": "你们本来约好明天见,但你临时有事,需要改期。",
"turns": [
{
"ai": "Hi! Are we OK for tomorrow at three?",
"goal": "说抱歉明天没空",
"model": "Sorry, I'm busy tomorrow.",
"zh": "抱歉,我明天没空。",
"itemIds": [
"A1-U13-P05",
"A1-U13-W01"
]
},
{
"ai": "Oh no. What's the problem?",
"goal": "问能不能改个日期",
"model": "I have to work. Can we change the date?",
"zh": "我要上班。我们能改个日期吗?",
"itemIds": [
"A1-U13-P11"
]
},
{
"ai": "Sure. When are you free?",
"goal": "说下周有空",
"model": "I'm free next week.",
"zh": "我下周有空。",
"itemIds": [
"A1-U13-P10"
]
},
{
"ai": "Next week I'm busy on Monday.",
"goal": "提议下周五",
"model": "How about Friday?",
"zh": "周五怎么样?",
"itemIds": [
"A1-U13-P06"
]
},
{
"ai": "Friday is good.",
"goal": "问今天几号,确认日期",
"model": "Great. What's the date today?",
"zh": "太好了。今天几号?",
"itemIds": [
"A1-U13-P01"
]
}
]
}
],
"tasks": [
{
"id": "A1-U13-T1",
"sceneId": "A1-U13-C1",
"goal": "约朋友周末吃饭,定下日子、时间和地点",
"itemIds": [
"A1-U13-P04",
"A1-U13-P06",
"A1-U13-P08",
"A1-U13-P07",
"A1-U13-P09"
],
"slots": [
"哪天",
"几点",
"在哪儿"
]
},
{
"id": "A1-U13-T2",
"sceneId": "A1-U13-C2",
"goal": "邀请同事参加你的生日聚会",
"itemIds": [
"A1-U13-P10",
"A1-U13-W02",
"A1-U13-W01",
"A1-U13-P03",
"A1-U13-P02"
],
"slots": [
"日期",
"聚会",
"生日"
]
},
{
"id": "A1-U13-T3",
"sceneId": "A1-U13-C3",
"goal": "临时没空,和朋友改约时间",
"itemIds": [
"A1-U13-P05",
"A1-U13-W01",
"A1-U13-P11",
"A1-U13-P10",
"A1-U13-P06",
"A1-U13-P01"
],
"slots": [
"原因",
"新日期"
]
}
],
"materials": [
{
"id": "A1-U13-M1",
"mode": "listening",
"title": "朋友打来约生日聚会",
"text": "Hi, it's me! I want to have a birthday party next month, in April. Are you free? My birthday is on the fifteenth. Please remember the date and write it on your calendar; don't forget! The party is at my home at three pm. My mom and dad will cook, and we will cut a big cake and celebrate together. I hope you can come. Maybe you can bring a small gift. I invited some old friends too. If Saturday is not good, how about later, on Sunday? I wish you a good week. Let me know. Bye!",
"glosses": {
"games": "游戏",
"fifteenth": "(每月)十五号",
"invited": "邀请(过去式)",
"bring": "带来"
},
"questions": [
{
"type": "gist",
"question": "这段留言是关于什么的?",
"options": [
"邀请你参加生日聚会",
"改机票",
"问天气"
]
},
{
"type": "detail",
"question": "聚会几点开始?",
"options": [
"下午三点",
"上午三点",
"晚上七点"
]
}
]
},
{
"id": "A1-U13-M2",
"mode": "reading",
"title": "读一段对话:约见面时间",
"text": "Ben: Are you free on Sunday? Let's meet.\nMia: Sorry, I'm busy on Sunday. My cousin's wedding is that day! How about Monday?\nBen: Monday is good. What time? Do you remember the cafe near the station?\nMia: Yes. Let's meet at ten in the morning. Don't forget!\nBen: I won't. Oh, can we change the time to eleven?\nMia: Sure. Wait, next Monday is a holiday, a big festival. Maybe the cafe is closed.\nBen: Good point. Let me check the calendar. It's open. See you at eleven then.\nMia: Great. I hope the weather is nice. Do you want lunch after that?\nBen: Yes! And happy birthday for last month, by the way.\nMia: Oh, that was months ago! Thank you. See you Monday. Bye!\nBen: Bye, and good luck at the wedding!",
"glosses": {
"sounds": "听起来",
"point": "good point 说得对",
"won't": "不会",
"check": "查看",
"weather": "天气"
},
"questions": [
{
"type": "detail",
"question": "他们最后约在星期几?",
"options": [
"星期一",
"星期天",
"星期六"
]
},
{
"type": "detail",
"question": "Mia 星期天为什么没空?",
"options": [
"要去参加表亲的婚礼",
"要上班",
"要考试"
]
}
]
}
],
"excluded": [
{
"en": "appointment",
"reason": "A2;A1 先用 meet 表达约见"
},
{
"en": "fifth",
"reason": "序数词 fourth 以后不在 A1 表里;日期先用数字读法(May 5)"
}
]
}