PageSourceSearch

https://teacherforge.io/samples

html teacherforge.io collected 2026-10-06 16:54:34 UTC 132,473 bytes, 2,063 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en" data-theme="teacherforge">
3<head>
4    <meta charset="UTF-8">
5    
5<script>try{var t=localStorage.getItem('tf-theme');if(t==='dark')document.documentElement.setAttribute('data-theme','teacherforge-dark')}catch(e){}</script>
5
6    <meta name="viewport" content="width=device-width, initial-scale=1.0">
7    <title>Sample Worksheets &amp; Exams — TeacherForge</title>
8    <meta name="description" content="See real worksheets and exam papers generated by TeacherForge. Seven samples across grammar, vocabulary, reading, writing, listening, and exam composer. Preview and download free — no signup.">
9    <link rel="canonical" href="https://teacherforge.io/samples">
10
11    <!-- Open Graph -->
12    <meta property="og:type" content="website">
13    <meta property="og:site_name" content="TeacherForge">
14    <meta property="og:title" content="Sample Worksheets & Exams — TeacherForge">
15    <meta property="og:description" content="Real outputs, not mockups. Seven pre-generated samples — preview and download free.">
16    <meta property="og:image" content="https://teacherforge.io/static/images/og-image.png">
17    <meta property="og:image:width" content="1200">
18    <meta property="og:image:height" content="630">
19    <meta property="og:url" content="https://teacherforge.io/samples">
20
21    <!-- Twitter Card -->
22    <meta name="twitter:card" content="summary_large_image">
23    <meta name="twitter:title" content="Sample Worksheets & Exams — TeacherForge">
24    <meta name="twitter:description" content="Real outputs, not mockups. Seven pre-generated samples — preview and download free.">
25    <meta name="twitter:image" content="https://teacherforge.io/static/images/og-image.png">
26
27
28    <!-- Fonts (preloaded to avoid render-blocking LCP) -->
29    <link rel="preconnect" href="https://fonts.googleapis.com">
30    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
31    <link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700&family=DM+Sans:wght@400;500;600;700&display=swap">
32    <link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700&family=DM+Sans:wght@400;500;600;700&display=swap" rel="stylesheet" media="print" onload="this.media='all'">
33    <noscript><link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700&family=DM+Sans:wght@400;500;600;700&display=swap" rel="stylesheet"></noscript>
34
35    <!-- Favicon -->
36    <link rel="icon" type="image/png" sizes="32x32" href="/static/images/favicon-32x32.png">
37    <link rel="icon" type="image/png" sizes="192x192" href="/static/images/favicon-192x192.png">
38    <link rel="apple-touch-icon" href="/static/images/apple-touch-icon.png">
39    <link rel="manifest" href="/static/manifest.json">
40    <meta name="theme-color" content="#0369A1">
41    
42
43    <!-- CSS -->
44    <link rel="stylesheet" href="/static/css/main.css?v=20261006a">
45
46    
47<script type="application/ld+json">
48{
49  "@context": "https://schema.org",
50  "@type": "BreadcrumbList",
51  "itemListElement": [
52    {"@type": "ListItem", "position": 1, "name": "Home", "item": "https://teacherforge.io"},
53    {"@type": "ListItem", "position": 2, "name": "Samples", "item": "https://teacherforge.io/samples"}
54  ]
55}
56</script>
56
57<style>
58  /* Paper-on-desk surface for sample thumbnails. Matches design system's
59     bg-exam (#FFFEF9) — feels like a physical worksheet sitting on the page. */
60  .paper-surface {
61    background: var(--color-bg-exam);
62    box-shadow:
63      0 1px 1px rgba(15, 23, 42, 0.04),
64      0 4px 8px rgba(15, 23, 42, 0.06),
65      0 12px 24px rgba(15, 23, 42, 0.05);
66    border: 1px solid #f0e9d8;
67  }
68  .paper-surface:hover {
69    box-shadow:
70      0 1px 1px rgba(15, 23, 42, 0.05),
71      0 6px 14px rgba(15, 23, 42, 0.08),
72      0 20px 40px rgba(15, 23, 42, 0.07);
73  }
74  /* Editorial number — large, slightly translucent, Playfair */
75  .sample-numeral {
76    font-family: 'Playfair Display', serif;
77    font-weight: 400;
78    font-size: clamp(2.5rem, 5vw, 4rem);
79    line-height: 1;
80    color: var(--color-primary);
81    opacity: 0.18;
82    letter-spacing: -0.02em;
83  }
84  [data-theme="teacherforge-dark"] .sample-numeral {
85    opacity: 0.4;
86  }
87  /* Metadata row separators — calm, magazine-style */
88  .axis-row > * + * {
89    border-left: 1px solid var(--color-border);
90    padding-left: 1rem;
91    margin-left: 1rem;
92  }
93  /* Disclosure caret rotation */
94  details[open] > summary .disclosure-caret { transform: rotate(90deg); }
95  .disclosure-caret { transition: transform 150ms ease-out; }
96  details > summary { list-style: none; cursor: pointer; }
97  details > summary::-webkit-details-marker { display: none; }
98  /* Modal lock body scroll — only when modal is actually visible */
99  body:has(.preview-modal-active) { overflow: hidden; }
100</style>
101
102</head>
103<body class="min-h-screen bg-[var(--color-bg)] font-sans text-[var(--color-text)] flex flex-col">
104    
105    <nav class="border-b border-[var(--color-border)] bg-[var(--color-bg-card)]">
106        
107
108
109
110
111
112
113
114
115
116
117<div class="mx-auto flex max-w-6xl items-center justify-between gap-3 px-4 py-4 sm:px-6"
118     x-data="{ navMenu: false }" @keydown.escape.window="navMenu = false">
119    <div class="flex min-w-0 items-center gap-6">
120        <a href="/" class="flex shrink-0 items-center gap-2" aria-label="TeacherForge home">
121            <img src="/static/images/logo-512.png" alt="" class="h-8 w-8">
122            
123            <span class="hidden whitespace-nowrap font-display text-xl font-semibold min-[360px]:inline">Teacher<span class="tf-forge-mark text-[var(--color-primary)]">Forge</span></span>
124        </a>
125        <a href="/products" class="hidden lg:inline text-sm font-medium text-[var(--color-text-muted)] hover:text-[var(--color-text)] transition-colors">Products</a>
126        <a href="/samples" class="hidden lg:inline text-sm font-medium text-[var(--color-text-muted)] hover:text-[var(--color-text)] transition-colors">Samples</a>
127        <a href="/pricing" class="hidden lg:inline text-sm font-medium text-[var(--color-text-muted)] hover:text-[var(--color-text)] transition-colors">Pricing</a>
128        <a href="/free-resources" class="hidden lg:inline whitespace-nowrap text-sm font-medium text-[var(--color-text-muted)] hover:text-[var(--color-text)] transition-colors">Free resources</a>
129        <a href="/blog" class="hidden lg:inline text-sm font-medium text-[var(--color-text-muted)] hover:text-[var(--color-text)] transition-colors">Blog</a>
130    </div>
131    <div class="flex shrink-0 items-center gap-2 sm:gap-4">
132        
133        <button onclick="tfToggleTheme()" class="hidden cursor-pointer rounded-lg p-1.5 text-[var(--color-text-muted)] hover:bg-[var(--color-border-light)] hover:text-[var(--color-text)] transition-colors sm:inline-flex" title="Toggle dark mode" aria-label="Toggle dark mode">
134            <svg class="h-5 w-5 dark-icon" style="display:none" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z"/></svg>
135            <svg class="h-5 w-5 light-icon" style="display:none" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z"/></svg>
136        </button>
137        
138        <a href="/auth" class="whitespace-nowrap rounded-lg bg-[var(--color-primary-fill)] px-3 py-2 text-sm font-medium text-primary-content hover:bg-[var(--color-primary-hover)] sm:px-4">Get started</a>
139        
140
141        
142        <div class="relative lg:hidden" @click.outside="navMenu = false">
143            <button type="button" @click="navMenu = !navMenu"
144                    :aria-expanded="navMenu ? 'true' : 'false'" aria-controls="nav-menu-panel"
145                    aria-label="Menu"
146                    class="relative flex cursor-pointer items-center rounded-lg p-1.5 text-[var(--color-text-muted)] hover:bg-[var(--color-border-light)] hover:text-[var(--color-text)] transition-colors">
147                <svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5M3.75 17.25h16.5"/></svg>
148                
149                
150            </button>
151            <div id="nav-menu-panel" x-show="navMenu" x-cloak
152                 x-transition:enter="transition ease-out duration-150"
153                 x-transition:enter-start="opacity-0 scale-95"
154                 x-transition:enter-end="opacity-100 scale-100"
155                 x-transition:leave="transition ease-in duration-100"
156                 x-transition:leave-start="opacity-100"
157                 x-transition:leave-end="opacity-0"
158                 class="absolute right-0 top-full z-50 mt-2 min-w-[13rem] rounded-xl border border-[var(--color-border)] bg-[var(--color-bg-card)] p-1 shadow-lg">
159                
160                <a href="/products" class="block rounded-md px-3 py-2 text-sm text-[var(--color-text-strong)] hover:bg-[var(--color-border-light)]">Products</a>
161                <a href="/samples" class="block rounded-md px-3 py-2 text-sm text-[var(--color-text-strong)] hover:bg-[var(--color-border-light)]">Samples</a>
162                <a href="/pricing" class="block rounded-md px-3 py-2 text-sm text-[var(--color-text-strong)] hover:bg-[var(--color-border-light)]">Pricing</a>
163                <a href="/free-resources" class="block whitespace-nowrap rounded-md px-3 py-2 text-sm text-[var(--color-text-strong)] hover:bg-[var(--color-border-light)]">Free resources</a>
164                <a href="/blog" class="block rounded-md px-3 py-2 text-sm text-[var(--color-text-strong)] hover:bg-[var(--color-border-light)]">Blog</a>
165                <div class="sm:hidden">
166                <div class="my-1 border-t border-[var(--color-border)]"></div>
167                <button type="button" onclick="tfToggleTheme()" @click="navMenu = false"
168                        class="flex w-full cursor-pointer items-center gap-2 rounded-md px-3 py-2 text-left text-sm text-[var(--color-text-strong)] hover:bg-[var(--color-border-light)]">
169                    <svg class="h-4 w-4 shrink-0 dark-icon" style="display:none" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z"/></svg>
170                    <svg class="h-4 w-4 shrink-0 light-icon" style="display:none" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z"/></svg>
171                    Toggle theme
172                </button>
173                
174                </div>
175            </div>
176        </div>
177    </div>
178</div>
179    </nav>
180    
181
182    <main class="flex-1">
183        
184
185<div x-data="samplesGallery()">
186
187
188<section class="relative pt-20 pb-16 lg:pt-28 lg:pb-20 overflow-hidden"
189         style="background: linear-gradient(180deg, var(--color-primary-light) 0%, var(--color-bg) 100%);">
190  <div class="absolute inset-0 opacity-[0.025]" style="background-image: radial-gradient(circle, var(--color-primary) 0.8px, transparent 0.8px); background-size: 20px 20px;"></div>
191
192  <div class="relative max-w-4xl mx-auto px-6 text-center">
193    
194    <div class="flex items-center justify-center gap-2 mb-8">
195      <a href="/" class="text-xs tracking-wide uppercase font-medium text-[var(--color-text-faint)] hover:text-[var(--color-primary)] transition-colors">Home</a>
196      <span class="text-[var(--color-text-faint)] text-xs">/</span>
197      <span class="text-xs tracking-wide uppercase font-medium text-[var(--color-text-muted)]">Samples</span>
198    </div>
199
200    <h1 class="font-display text-3xl sm:text-4xl lg:text-5xl text-[var(--color-text)] leading-tight tracking-tight">
201      Sample Worksheets &amp; Exams
202    </h1>
203    <p class="mt-5 text-lg lg:text-xl text-[var(--color-text-muted)] max-w-2xl mx-auto leading-relaxed">
204      Real outputs, not mockups. Each was generated with one specific configuration. Yours can look completely different.
205    </p>
206
207    <div class="mt-8 w-16 h-0.5 bg-[var(--color-primary)] rounded-full mx-auto"></div>
208
209    <p class="mt-6 text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-medium">
210      No signup required · Preview &amp; download free
211    </p>
212  </div>
213</section>
214
215
216
217<section class="border-y border-[var(--color-border-light)] bg-[var(--color-bg-card)]">
218  <div class="max-w-6xl mx-auto px-6 py-7">
219    <p class="text-xs tracking-wider uppercase text-[var(--color-primary)] font-semibold mb-4 text-center">
220      Every sample below is one of thousands of possible outputs
221    </p>
222    <div class="flex flex-wrap items-center justify-center gap-x-8 gap-y-3 text-sm text-[var(--color-text)]">
223      
224      <div class="flex items-baseline gap-2 whitespace-nowrap">
225        <span class="font-semibold">CEFR levels</span>
226        <span class="text-[var(--color-text-muted)]">A1 · A2 · B1 · B2 · C1 · C2</span>
227      </div>
228      
229      <span class="text-[var(--color-text-faint)] hidden sm:inline">•</span>
230      
231      
232      <div class="flex items-baseline gap-2 whitespace-nowrap">
233        <span class="font-semibold">Worksheet themes</span>
234        <span class="text-[var(--color-text-muted)]">Worksheet · Quiz · Minimal</span>
235      </div>
236      
237      <span class="text-[var(--color-text-faint)] hidden sm:inline">•</span>
238      
239      
240      <div class="flex items-baseline gap-2 whitespace-nowrap">
241        <span class="font-semibold">Exam themes</span>
242        <span class="text-[var(--color-text-muted)]">Exam · Quiz · Minimal</span>
243      </div>
244      
245      <span class="text-[var(--color-text-faint)] hidden sm:inline">•</span>
246      
247      
248      <div class="flex items-baseline gap-2 whitespace-nowrap">
249        <span class="font-semibold">Fonts</span>
250        <span class="text-[var(--color-text-muted)]">Serif · Sans · Helvetica · Calibri</span>
251      </div>
252      
253      <span class="text-[var(--color-text-faint)] hidden sm:inline">•</span>
254      
255      
256      <div class="flex items-baseline gap-2 whitespace-nowrap">
257        <span class="font-semibold">Density</span>
258        <span class="text-[var(--color-text-muted)]">Compact · Normal · Spacious</span>
259      </div>
260      
261      <span class="text-[var(--color-text-faint)] hidden sm:inline">•</span>
262      
263      
264      <div class="flex items-baseline gap-2 whitespace-nowrap">
265        <span class="font-semibold">Branding</span>
266        <span class="text-[var(--color-text-muted)]">School logo (Pro+) · Teacher name</span>
267      </div>
268      
269      <span class="text-[var(--color-text-faint)] hidden sm:inline">•</span>
270      
271      
272      <div class="flex items-baseline gap-2 whitespace-nowrap">
273        <span class="font-semibold">Output formats</span>
274        <span class="text-[var(--color-text-muted)]">PDF · Editable DOCX</span>
275      </div>
276      
277      
278    </div>
279  </div>
280</section>
281
282
283
284<section class="py-16 lg:py-24 bg-[var(--color-bg)]">
285  <div class="max-w-6xl mx-auto px-6 space-y-20 lg:space-y-28">
286
287    
288    
289    
290
291    <article id="grammar-b1" class="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12 items-start scroll-mt-24">
292
293      
294      <div class="order-2 lg:col-span-5 lg:order-1 relative">
295        <div class="paper-surface rounded-md overflow-hidden transition-shadow duration-300 cursor-pointer group"
296             @click="openPreview('grammar-b1')"
297             role="button"
298             tabindex="0"
299             @keydown.enter="openPreview('grammar-b1')"
300             @keydown.space.prevent="openPreview('grammar-b1')"
301             aria-label="Preview Hallmark Upper-B1 Grammar">
302          <img src="/static/samples/thumbnails/01_grammar_b1.png" alt="First page of Hallmark Upper-B1 Grammar"
303               class="w-full h-auto block"
304               loading="lazy">
305          
306          <div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-[var(--color-text)]/40">
307            <span class="inline-flex items-center gap-2 rounded-full bg-white/95 px-4 py-2 text-sm font-semibold text-[var(--color-on-exam)] shadow-lg">
308              <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
309              Preview all pages
310            </span>
311          </div>
312        </div>
313
314        
315        <div class="mt-3 flex items-center justify-between text-xs text-[var(--color-text-muted)] px-1">
316          <span>
317            5 pages · material
318            <span class="mx-1.5 text-[var(--color-text-faint)]">+</span>
319            3 pages · answers
320          </span>
321          
322        </div>
323      </div>
324
325      
326      <div class="order-1 lg:col-span-7 lg:order-2">
327
328        
329        <div class="flex items-baseline gap-4 mb-3">
330          <span class="sample-numeral" style="color: #2563EB;">01</span>
331          <div class="flex flex-wrap items-center gap-2">
332            
333            
334            <span class="text-xs tracking-wider uppercase font-semibold" style="color: #2563EB;">Grammar Worksheet</span>
335            <span class="inline-flex items-center rounded-md px-1.5 py-0.5 text-[10px] font-bold tracking-wide text-white leading-none" style="background-color: #2563EB;">B1</span>
336          </div>
337        </div>
338
339        <h2 class="font-display text-2xl lg:text-3xl text-[var(--color-text)] tracking-tight leading-tight">
340          Hallmark Upper-B1 Grammar
341        </h2>
342        <p class="mt-2 text-base text-[var(--color-text-muted)] leading-relaxed">
343          Three core grammar topics that mark progression from intermediate to upper-intermediate.
344        </p>
345
346        
347        <div class="mt-6">
348          <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-2.5">What's inside</p>
349          <ul class="space-y-1.5 text-sm text-[var(--color-text)]">
350            
351            <li class="flex gap-2.5">
352              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
353              <span>7 sections, 30 items</span>
354            </li>
355            
356            <li class="flex gap-2.5">
357              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
358              <span>Tags covered: First Conditional, Passive: by + Agent &amp; Questions, Adverbs of Degree: very/much</span>
359            </li>
360            
361            <li class="flex gap-2.5">
362              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
363              <span>5 distinct exercise types showcased: sentence completion, select and combine, sentence transformation, gap fill, true false</span>
364            </li>
365            
366          </ul>
367        </div>
368
369        
370        <details class="mt-5 group">
371          <summary class="flex items-center gap-2 text-sm font-medium text-[var(--color-text)] hover:text-[var(--color-primary)] transition-colors py-2">
372            <svg class="w-4 h-4 disclosure-caret text-[var(--color-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
373            <span>Exact configuration used for this sample</span>
374          </summary>
375          <dl class="mt-2 ml-6 space-y-1.5 text-sm">
376            
377            <div class="flex flex-col sm:flex-row sm:gap-3">
378              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Grammar tags</dt>
379              <dd class="text-[var(--color-text)]">First Conditional · Passive: by + Agent &amp; Questions · Adverbs of Degree: very/much</dd>
380            </div>
381            
382            <div class="flex flex-col sm:flex-row sm:gap-3">
383              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Exercise types</dt>
384              <dd class="text-[var(--color-text)]">5 (sentence_completion, select_and_combine, sentence_transformation, gap_fill, true_false)</dd>
385            </div>
386            
387          </dl>
388        </details>
389
390        
391        <details class="mt-1 group">
392          <summary class="flex items-center gap-2 text-sm font-medium text-[var(--color-text)] hover:text-[var(--color-primary)] transition-colors py-2">
393            <svg class="w-4 h-4 disclosure-caret text-[var(--color-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
394            <span>What's possible with the Grammar composer</span>
395          </summary>
396          <div class="mt-2 ml-6 space-y-3 text-sm">
397            <div>
398              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Generation pathway</p>
399              <ul class="space-y-1 text-[var(--color-text)]">
400                
401                <li class="leading-snug">Tag selection (no presets — Grammar is fully custom by design)</li>
402                
403              </ul>
404            </div>
405
406            
407
408            
409            <div>
410              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Exercise types</p>
411              <p class="text-[var(--color-text)] leading-snug">9 types — gap fill, open cloze, multiple choice, error correction, word ordering, sentence transformation, true/false, sentence completion, select &amp; combine. Per-tag compatibility matrix governs which types fit which tags.</p>
412            </div>
413            
414
415            
416
417            
418
419            
420
421            
422
423            
424
425            
426            <p class="text-xs italic text-[var(--color-text-muted)] pt-1 border-t border-[var(--color-border-light)] mt-3 pt-3">300+ grammar tags from A1 to C2. Each tag carries its own level.</p>
427            
428          </div>
429        </details>
430
431        
432        <div class="mt-7 flex flex-wrap items-center gap-3">
433          <button type="button"
434                  @click="openPreview('grammar-b1')"
435                  class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-primary-fill)] px-4 py-2.5 text-sm font-semibold text-primary-content hover:bg-[var(--color-primary-hover)] transition-colors duration-150 shadow-sm">
436            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
437            Preview
438          </button>
439
440          <a href="/static/samples/01_grammar_b1/material.pdf" download
441             class="inline-flex items-center gap-2 rounded-lg border border-[var(--color-border)] bg-[var(--color-bg-card)] px-4 py-2.5 text-sm font-medium text-[var(--color-text)] hover:border-[var(--color-primary)] hover:text-[var(--color-primary)] transition-colors duration-150">
442            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/></svg>
443            Download PDF
444          </a>
445
446          
447
448          
449          <a href="/products/grammar"
450             class="inline-flex items-center gap-1.5 ml-auto text-sm font-semibold transition-colors hover:opacity-80"
451             style="color: #2563EB;">
452            Learn more about Grammar
453            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
454          </a>
455        </div>
456      </div>
457    </article>
458
459    
460    <div class="border-t border-[var(--color-border-light)]/80 max-w-2xl mx-auto"></div>
461    
462
463    
464    
465    
466
467    <article id="vocabulary-b1" class="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12 items-start scroll-mt-24">
468
469      
470      <div class="order-2 lg:col-span-5 lg:order-2 relative">
471        <div class="paper-surface rounded-md overflow-hidden transition-shadow duration-300 cursor-pointer group"
472             @click="openPreview('vocabulary-b1')"
473             role="button"
474             tabindex="0"
475             @keydown.enter="openPreview('vocabulary-b1')"
476             @keydown.space.prevent="openPreview('vocabulary-b1')"
477             aria-label="Preview Job Interviews">
478          <img src="/static/samples/thumbnails/02_vocabulary_b1.png" alt="First page of Job Interviews"
479               class="w-full h-auto block"
480               loading="lazy">
481          
482          <div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-[var(--color-text)]/40">
483            <span class="inline-flex items-center gap-2 rounded-full bg-white/95 px-4 py-2 text-sm font-semibold text-[var(--color-on-exam)] shadow-lg">
484              <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
485              Preview all pages
486            </span>
487          </div>
488        </div>
489
490        
491        <div class="mt-3 flex items-center justify-between text-xs text-[var(--color-text-muted)] px-1">
492          <span>
493            4 pages · material
494            <span class="mx-1.5 text-[var(--color-text-faint)]">+</span>
495            3 pages · answers
496          </span>
497          
498        </div>
499      </div>
500
501      
502      <div class="order-1 lg:col-span-7 lg:order-1">
503
504        
505        <div class="flex items-baseline gap-4 mb-3">
506          <span class="sample-numeral" style="color: #16A34A;">02</span>
507          <div class="flex flex-wrap items-center gap-2">
508            
509            
510            <span class="text-xs tracking-wider uppercase font-semibold" style="color: #16A34A;">Vocabulary Worksheet</span>
511            <span class="inline-flex items-center rounded-md px-1.5 py-0.5 text-[10px] font-bold tracking-wide text-white leading-none" style="background-color: #16A34A;">B1</span>
512          </div>
513        </div>
514
515        <h2 class="font-display text-2xl lg:text-3xl text-[var(--color-text)] tracking-tight leading-tight">
516          Job Interviews
517        </h2>
518        <p class="mt-2 text-base text-[var(--color-text-muted)] leading-relaxed">
519          Vocabulary set built from the catalog around a topic adult classes actually need.
520        </p>
521
522        
523        <div class="mt-6">
524          <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-2.5">What's inside</p>
525          <ul class="space-y-1.5 text-sm text-[var(--color-text)]">
526            
527            <li class="flex gap-2.5">
528              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
529              <span>5 sections, 30 items</span>
530            </li>
531            
532            <li class="flex gap-2.5">
533              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
534              <span>Words from Work &amp; Learning → Job Interviews (B1)</span>
535            </li>
536            
537            <li class="flex gap-2.5">
538              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
539              <span>5 distinct exercise types showcased: gap fill, multiple choice, matching, word ordering, true false</span>
540            </li>
541            
542          </ul>
543        </div>
544
545        
546        <details class="mt-5 group">
547          <summary class="flex items-center gap-2 text-sm font-medium text-[var(--color-text)] hover:text-[var(--color-primary)] transition-colors py-2">
548            <svg class="w-4 h-4 disclosure-caret text-[var(--color-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
549            <span>Exact configuration used for this sample</span>
550          </summary>
551          <dl class="mt-2 ml-6 space-y-1.5 text-sm">
552            
553            <div class="flex flex-col sm:flex-row sm:gap-3">
554              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Path used</dt>
555              <dd class="text-[var(--color-text)]">Topic Explorer (catalog domain + subtopic)</dd>
556            </div>
557            
558            <div class="flex flex-col sm:flex-row sm:gap-3">
559              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Domain</dt>
560              <dd class="text-[var(--color-text)]">Work &amp; Learning</dd>
561            </div>
562            
563            <div class="flex flex-col sm:flex-row sm:gap-3">
564              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Subtopic</dt>
565              <dd class="text-[var(--color-text)]">Job Interviews</dd>
566            </div>
567            
568            <div class="flex flex-col sm:flex-row sm:gap-3">
569              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Exercise types</dt>
570              <dd class="text-[var(--color-text)]">5 (gap_fill, multiple_choice, matching, word_ordering, true_false)</dd>
571            </div>
572            
573          </dl>
574        </details>
575
576        
577        <details class="mt-1 group">
578          <summary class="flex items-center gap-2 text-sm font-medium text-[var(--color-text)] hover:text-[var(--color-primary)] transition-colors py-2">
579            <svg class="w-4 h-4 disclosure-caret text-[var(--color-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
580            <span>What's possible with the Vocabulary composer</span>
581          </summary>
582          <div class="mt-2 ml-6 space-y-3 text-sm">
583            <div>
584              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Generation pathways</p>
585              <ul class="space-y-1 text-[var(--color-text)]">
586                
587                <li class="leading-snug">Path A — My Words: paste your own word list, AI enriches with POS + CEFR-adapted definitions</li>
588                
589                <li class="leading-snug">Path B — Topic Explorer: pick from 11 domains × 528 curated subtopics across A1–C2</li>
590                
591                <li class="leading-snug">Path C — Paste Text: drop in a passage, AI extracts vocabulary + auto-detects topic and CEFR level</li>
592                
593              </ul>
594            </div>
595
596            
597
598            
599            <div>
600              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Exercise types</p>
601              <p class="text-[var(--color-text)] leading-snug">5 types — matching, gap fill, multiple choice, true/false, word ordering</p>
602            </div>
603            
604
605            
606
607            
608
609            
610
611            
612
613            
614
615            
616            <p class="text-xs italic text-[var(--color-text-muted)] pt-1 border-t border-[var(--color-border-light)] mt-3 pt-3">11 domains × 528 catalog subtopics, plus unlimited custom subtopics and pasted text</p>
617            
618          </div>
619        </details>
620
621        
622        <div class="mt-7 flex flex-wrap items-center gap-3">
623          <button type="button"
624                  @click="openPreview('vocabulary-b1')"
625                  class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-primary-fill)] px-4 py-2.5 text-sm font-semibold text-primary-content hover:bg-[var(--color-primary-hover)] transition-colors duration-150 shadow-sm">
626            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
627            Preview
628          </button>
629
630          <a href="/static/samples/02_vocabulary_b1/material.pdf" download
631             class="inline-flex items-center gap-2 rounded-lg border border-[var(--color-border)] bg-[var(--color-bg-card)] px-4 py-2.5 text-sm font-medium text-[var(--color-text)] hover:border-[var(--color-primary)] hover:text-[var(--color-primary)] transition-colors duration-150">
632            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/></svg>
633            Download PDF
634          </a>
635
636          
637
638          
639          <a href="/products/vocabulary"
640             class="inline-flex items-center gap-1.5 ml-auto text-sm font-semibold transition-colors hover:opacity-80"
641             style="color: #16A34A;">
642            Learn more about Vocabulary
643            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
644          </a>
645        </div>
646      </div>
647    </article>
648
649    
650    <div class="border-t border-[var(--color-border-light)]/80 max-w-2xl mx-auto"></div>
651    
652
653    
654    
655    
656
657    <article id="reading-b2" class="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12 items-start scroll-mt-24">
658
659      
660      <div class="order-2 lg:col-span-5 lg:order-1 relative">
661        <div class="paper-surface rounded-md overflow-hidden transition-shadow duration-300 cursor-pointer group"
662             @click="openPreview('reading-b2')"
663             role="button"
664             tabindex="0"
665             @keydown.enter="openPreview('reading-b2')"
666             @keydown.space.prevent="openPreview('reading-b2')"
667             aria-label="Preview Urban Farming in Southeast Asia">
668          <img src="/static/samples/thumbnails/03_reading_b2.png" alt="First page of Urban Farming in Southeast Asia"
669               class="w-full h-auto block"
670               loading="lazy">
671          
672          <div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-[var(--color-text)]/40">
673            <span class="inline-flex items-center gap-2 rounded-full bg-white/95 px-4 py-2 text-sm font-semibold text-[var(--color-on-exam)] shadow-lg">
674              <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
675              Preview all pages
676            </span>
677          </div>
678        </div>
679
680        
681        <div class="mt-3 flex items-center justify-between text-xs text-[var(--color-text-muted)] px-1">
682          <span>
683            7 pages · material
684            <span class="mx-1.5 text-[var(--color-text-faint)]">+</span>
685            3 pages · answers
686          </span>
687          
688        </div>
689      </div>
690
691      
692      <div class="order-1 lg:col-span-7 lg:order-2">
693
694        
695        <div class="flex items-baseline gap-4 mb-3">
696          <span class="sample-numeral" style="color: #D97706;">03</span>
697          <div class="flex flex-wrap items-center gap-2">
698            
699            
700            <span class="text-xs tracking-wider uppercase font-semibold" style="color: #D97706;">Reading Comprehension</span>
701            <span class="inline-flex items-center rounded-md px-1.5 py-0.5 text-[10px] font-bold tracking-wide text-white leading-none" style="background-color: #D97706;">B2</span>
702          </div>
703        </div>
704
705        <h2 class="font-display text-2xl lg:text-3xl text-[var(--color-text)] tracking-tight leading-tight">
706          Urban Farming in Southeast Asia
707        </h2>
708        <p class="mt-2 text-base text-[var(--color-text-muted)] leading-relaxed">
709          AI-generated article on a contemporary topic, with a full comprehension set.
710        </p>
711
712        
713        <div class="mt-6">
714          <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-2.5">What's inside</p>
715          <ul class="space-y-1.5 text-sm text-[var(--color-text)]">
716            
717            <li class="flex gap-2.5">
718              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
719              <span>5 sections, 30 items</span>
720            </li>
721            
722            <li class="flex gap-2.5">
723              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
724              <span>5 distinct exercise types showcased: multiple choice, true false, short answer, cause effect, note completion</span>
725            </li>
726            
727          </ul>
728        </div>
729
730        
731        <details class="mt-5 group">
732          <summary class="flex items-center gap-2 text-sm font-medium text-[var(--color-text)] hover:text-[var(--color-primary)] transition-colors py-2">
733            <svg class="w-4 h-4 disclosure-caret text-[var(--color-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
734            <span>Exact configuration used for this sample</span>
735          </summary>
736          <dl class="mt-2 ml-6 space-y-1.5 text-sm">
737            
738            <div class="flex flex-col sm:flex-row sm:gap-3">
739              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Path used</dt>
740              <dd class="text-[var(--color-text)]">Generate Passage (AI from topic)</dd>
741            </div>
742            
743            <div class="flex flex-col sm:flex-row sm:gap-3">
744              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Topic</dt>
745              <dd class="text-[var(--color-text)]">Urban farming on the rooftops of Southeast Asian cities</dd>
746            </div>
747            
748            <div class="flex flex-col sm:flex-row sm:gap-3">
749              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Text style</dt>
750              <dd class="text-[var(--color-text)]">Article</dd>
751            </div>
752            
753            <div class="flex flex-col sm:flex-row sm:gap-3">
754              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Length</dt>
755              <dd class="text-[var(--color-text)]">Long</dd>
756            </div>
757            
758            <div class="flex flex-col sm:flex-row sm:gap-3">
759              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Exercise types</dt>
760              <dd class="text-[var(--color-text)]">5 (multiple_choice, true_false, short_answer, cause_effect, note_completion)</dd>
761            </div>
762            
763          </dl>
764        </details>
765
766        
767        <details class="mt-1 group">
768          <summary class="flex items-center gap-2 text-sm font-medium text-[var(--color-text)] hover:text-[var(--color-primary)] transition-colors py-2">
769            <svg class="w-4 h-4 disclosure-caret text-[var(--color-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
770            <span>What's possible with the Reading composer</span>
771          </summary>
772          <div class="mt-2 ml-6 space-y-3 text-sm">
773            <div>
774              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Generation pathways</p>
775              <ul class="space-y-1 text-[var(--color-text)]">
776                
777                <li class="leading-snug">Generate Passage: provide a topic, AI writes a passage at the target CEFR level</li>
778                
779                <li class="leading-snug">Paste Your Text: bring your own article/text, AI auto-detects level and topic</li>
780                
781              </ul>
782            </div>
783
784            
785            <div>
786              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Presets available</p>
787              <ul class="space-y-1 text-[var(--color-text)]">
788                
789                <li class="leading-snug">Quick Comprehension (all levels)</li>
790                
791                <li class="leading-snug">Cambridge Style (B1+)</li>
792                
793                <li class="leading-snug">IELTS Style (B1+)</li>
794                
795                <li class="leading-snug">Comprehensive (B1+)</li>
796                
797                <li class="leading-snug">Deep Analysis (B1+)</li>
798                
799              </ul>
800            </div>
801            
802
803            
804            <div>
805              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Exercise types</p>
806              <p class="text-[var(--color-text)] leading-snug">8 types — multiple choice, true/false/not given, short answer, matching headings, multiple matching, note completion, cause &amp; effect, sequencing</p>
807            </div>
808            
809
810            
811
812            
813            <div>
814              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Text styles</p>
815              <p class="text-[var(--color-text)] leading-snug">7 styles — article, story, email, letter, dialogue, report, blog post</p>
816            </div>
817            
818
819            
820
821            
822
823            
824
825            
826            <p class="text-xs italic text-[var(--color-text-muted)] pt-1 border-t border-[var(--color-border-light)] mt-3 pt-3">Any topic, any of 7 text styles, 3 length presets, 5 reading presets, fully custom exercise mix</p>
827            
828          </div>
829        </details>
830
831        
832        <div class="mt-7 flex flex-wrap items-center gap-3">
833          <button type="button"
834                  @click="openPreview('reading-b2')"
835                  class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-primary-fill)] px-4 py-2.5 text-sm font-semibold text-primary-content hover:bg-[var(--color-primary-hover)] transition-colors duration-150 shadow-sm">
836            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
837            Preview
838          </button>
839
840          <a href="/static/samples/03_reading_b2/material.pdf" download
841             class="inline-flex items-center gap-2 rounded-lg border border-[var(--color-border)] bg-[var(--color-bg-card)] px-4 py-2.5 text-sm font-medium text-[var(--color-text)] hover:border-[var(--color-primary)] hover:text-[var(--color-primary)] transition-colors duration-150">
842            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/></svg>
843            Download PDF
844          </a>
845
846          
847
848          
849          <a href="/products/reading"
850             class="inline-flex items-center gap-1.5 ml-auto text-sm font-semibold transition-colors hover:opacity-80"
851             style="color: #D97706;">
852            Learn more about Reading
853            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
854          </a>
855        </div>
856      </div>
857    </article>
858
859    
860    <div class="border-t border-[var(--color-border-light)]/80 max-w-2xl mx-auto"></div>
861    
862
863    
864    
865    
866
867    <article id="writing-b2" class="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12 items-start scroll-mt-24">
868
869      
870      <div class="order-2 lg:col-span-5 lg:order-2 relative">
871        <div class="paper-surface rounded-md overflow-hidden transition-shadow duration-300 cursor-pointer group"
872             @click="openPreview('writing-b2')"
873             role="button"
874             tabindex="0"
875             @keydown.enter="openPreview('writing-b2')"
876             @keydown.space.prevent="openPreview('writing-b2')"
877             aria-label="Preview Library Closure — Formal Letter">
878          <img src="/static/samples/thumbnails/04_writing_b2.png" alt="First page of Library Closure — Formal Letter"
879               class="w-full h-auto block"
880               loading="lazy">
881          
882          <div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-[var(--color-text)]/40">
883            <span class="inline-flex items-center gap-2 rounded-full bg-white/95 px-4 py-2 text-sm font-semibold text-[var(--color-on-exam)] shadow-lg">
884              <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
885              Preview all pages
886            </span>
887          </div>
888        </div>
889
890        
891        <div class="mt-3 flex items-center justify-between text-xs text-[var(--color-text-muted)] px-1">
892          <span>
893            3 pages · material
894            <span class="mx-1.5 text-[var(--color-text-faint)]">+</span>
895            2 pages · answers
896          </span>
897          
898        </div>
899      </div>
900
901      
902      <div class="order-1 lg:col-span-7 lg:order-1">
903
904        
905        <div class="flex items-baseline gap-4 mb-3">
906          <span class="sample-numeral" style="color: #E11D48;">04</span>
907          <div class="flex flex-wrap items-center gap-2">
908            
909            
910            <span class="text-xs tracking-wider uppercase font-semibold" style="color: #E11D48;">Writing Task</span>
911            <span class="inline-flex items-center rounded-md px-1.5 py-0.5 text-[10px] font-bold tracking-wide text-white leading-none" style="background-color: #E11D48;">B2</span>
912          </div>
913        </div>
914
915        <h2 class="font-display text-2xl lg:text-3xl text-[var(--color-text)] tracking-tight leading-tight">
916          Library Closure — Formal Letter
917        </h2>
918        <p class="mt-2 text-base text-[var(--color-text-muted)] leading-relaxed">
919          Complete writing task package, generated in a single LLM call.
920        </p>
921
922        
923        <div class="mt-6">
924          <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-2.5">What's inside</p>
925          <ul class="space-y-1.5 text-sm text-[var(--color-text)]">
926            
927            <li class="flex gap-2.5">
928              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
929              <span>Formal Letter task at B2</span>
930            </li>
931            
932            <li class="flex gap-2.5">
933              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
934              <span>Writing prompt with a full scenario, not a one-line title</span>
935            </li>
936            
937          </ul>
938        </div>
939
940        
941        <details class="mt-5 group">
942          <summary class="flex items-center gap-2 text-sm font-medium text-[var(--color-text)] hover:text-[var(--color-primary)] transition-colors py-2">
943            <svg class="w-4 h-4 disclosure-caret text-[var(--color-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
944            <span>Exact configuration used for this sample</span>
945          </summary>
946          <dl class="mt-2 ml-6 space-y-1.5 text-sm">
947            
948            <div class="flex flex-col sm:flex-row sm:gap-3">
949              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Task type</dt>
950              <dd class="text-[var(--color-text)]">Formal Letter</dd>
951            </div>
952            
953            <div class="flex flex-col sm:flex-row sm:gap-3">
954              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Topic</dt>
955              <dd class="text-[var(--color-text)]">Opposing the closure of the neighbourhood library</dd>
956            </div>
957            
958            <div class="flex flex-col sm:flex-row sm:gap-3">
959              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Level</dt>
960              <dd class="text-[var(--color-text)]">B2</dd>
961            </div>
962            
963            <div class="flex flex-col sm:flex-row sm:gap-3">
964              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Components</dt>
965              <dd class="text-[var(--color-text)]">Prompt · Planning checklist · Useful language · Criteria · Model answer</dd>
966            </div>
967            
968          </dl>
969        </details>
970
971        
972        <details class="mt-1 group">
973          <summary class="flex items-center gap-2 text-sm font-medium text-[var(--color-text)] hover:text-[var(--color-primary)] transition-colors py-2">
974            <svg class="w-4 h-4 disclosure-caret text-[var(--color-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
975            <span>What's possible with the Writing composer</span>
976          </summary>
977          <div class="mt-2 ml-6 space-y-3 text-sm">
978            <div>
979              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Generation pathway</p>
980              <ul class="space-y-1 text-[var(--color-text)]">
981                
982                <li class="leading-snug">Choose a task type, set a topic, generate.</li>
983                
984              </ul>
985            </div>
986
987            
988            <div>
989              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Presets available</p>
990              <ul class="space-y-1 text-[var(--color-text)]">
991                
992                <li class="leading-snug">Cambridge mode (B1+, non-story types) — turns on every component and sets four-criteria assessment</li>
993                
994                <li class="leading-snug">Custom mode — choose which components to include, and the criteria style</li>
995                
996              </ul>
997            </div>
998            
999
1000            
1001
1002            
1003            <div>
1004              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Task types</p>
1005              <p class="text-[var(--color-text)] leading-snug">8 task types — Essay (B1+), Informal Letter (all), Formal Letter (B1+), Report (B1+), Proposal (C1+), Review (A2+), Article (B1+), Story (all)</p>
1006            </div>
1007            
1008
1009            
1010
1011            
1012
1013            
1014
1015            
1016            <div>
1017              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Toggleable components</p>
1018              <ul class="space-y-1 text-[var(--color-text)]">
1019                
1020                <li class="leading-snug">Planning checklist (on/off)</li>
1021                
1022                <li class="leading-snug">Useful language box (on/off)</li>
1023                
1024                <li class="leading-snug">Model answer (on/off)</li>
1025                
1026                <li class="leading-snug">Assessment criteria (always on)</li>
1027                
1028              </ul>
1029            </div>
1030            
1031
1032            
1033            <p class="text-xs italic text-[var(--color-text-muted)] pt-1 border-t border-[var(--color-border-light)] mt-3 pt-3">8 task types across A1–C2 with level-appropriate gating</p>
1034            
1035          </div>
1036        </details>
1037
1038        
1039        <div class="mt-7 flex flex-wrap items-center gap-3">
1040          <button type="button"
1041                  @click="openPreview('writing-b2')"
1042                  class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-primary-fill)] px-4 py-2.5 text-sm font-semibold text-primary-content hover:bg-[var(--color-primary-hover)] transition-colors duration-150 shadow-sm">
1043            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
1044            Preview
1045          </button>
1046
1047          <a href="/static/samples/04_writing_b2/material.pdf" download
1048             class="inline-flex items-center gap-2 rounded-lg border border-[var(--color-border)] bg-[var(--color-bg-card)] px-4 py-2.5 text-sm font-medium text-[var(--color-text)] hover:border-[var(--color-primary)] hover:text-[var(--color-primary)] transition-colors duration-150">
1049            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/></svg>
1050            Download PDF
1051          </a>
1052
1053          
1054
1055          
1056          <a href="/products/writing"
1057             class="inline-flex items-center gap-1.5 ml-auto text-sm font-semibold transition-colors hover:opacity-80"
1058             style="color: #E11D48;">
1059            Learn more about Writing
1060            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
1061          </a>
1062        </div>
1063      </div>
1064    </article>
1065
1066    
1067    <div class="border-t border-[var(--color-border-light)]/80 max-w-2xl mx-auto"></div>
1068    
1069
1070    
1071    
1072    
1073
1074    <article id="listening-c1" class="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12 items-start scroll-mt-24">
1075
1076      
1077      <div class="order-2 lg:col-span-5 lg:order-1 relative">
1078        <div class="paper-surface rounded-md overflow-hidden transition-shadow duration-300 cursor-pointer group"
1079             @click="openPreview('listening-c1')"
1080             role="button"
1081             tabindex="0"
1082             @keydown.enter="openPreview('listening-c1')"
1083             @keydown.space.prevent="openPreview('listening-c1')"
1084             aria-label="Preview Colleagues Debate AI Hiring Ethics">
1085          <img src="/static/samples/thumbnails/05_listening_c1.png" alt="First page of Colleagues Debate AI Hiring Ethics"
1086               class="w-full h-auto block"
1087               loading="lazy">
1088          
1089          <div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-[var(--color-text)]/40">
1090            <span class="inline-flex items-center gap-2 rounded-full bg-white/95 px-4 py-2 text-sm font-semibold text-[var(--color-on-exam)] shadow-lg">
1091              <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
1092              Preview all pages
1093            </span>
1094          </div>
1095        </div>
1096
1097        
1098        <div class="mt-3 flex items-center justify-between text-xs text-[var(--color-text-muted)] px-1">
1099          <span>
1100            5 pages · material
1101            <span class="mx-1.5 text-[var(--color-text-faint)]">+</span>
1102            4 pages · answers
1103          </span>
1104          
1105          <span class="inline-flex items-center gap-1 text-[var(--color-primary)] font-medium">
1106            <svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19.114 5.636a9 9 0 010 12.728M16.463 8.288a5.25 5.25 0 010 7.424M6.75 8.25l4.72-4.72a.75.75 0 011.28.53v15.88a.75.75 0 01-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.01 9.01 0 012.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75z"/></svg>
1107            Includes audio
1108          </span>
1109          
1110        </div>
1111      </div>
1112
1113      
1114      <div class="order-1 lg:col-span-7 lg:order-2">
1115
1116        
1117        <div class="flex items-baseline gap-4 mb-3">
1118          <span class="sample-numeral" style="color: #0891B2;">05</span>
1119          <div class="flex flex-wrap items-center gap-2">
1120            
1121            
1122            <span class="text-xs tracking-wider uppercase font-semibold" style="color: #0891B2;">Listening Set</span>
1123            <span class="inline-flex items-center rounded-md px-1.5 py-0.5 text-[10px] font-bold tracking-wide text-white leading-none" style="background-color: #0891B2;">C1</span>
1124          </div>
1125        </div>
1126
1127        <h2 class="font-display text-2xl lg:text-3xl text-[var(--color-text)] tracking-tight leading-tight">
1128          Colleagues Debate AI Hiring Ethics
1129        </h2>
1130        <p class="mt-2 text-base text-[var(--color-text-muted)] leading-relaxed">
1131          Pre-recorded three-speaker conversation from the library, with a full comprehension set.
1132        </p>
1133
1134        
1135        <div class="mt-6">
1136          <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-2.5">What's inside</p>
1137          <ul class="space-y-1.5 text-sm text-[var(--color-text)]">
1138            
1139            <li class="flex gap-2.5">
1140              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
1141              <span>6 sections, 30 items</span>
1142            </li>
1143            
1144            <li class="flex gap-2.5">
1145              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
1146              <span>6 distinct exercise types showcased: multiple choice, true false, gap fill, note completion, matching, sentence completion</span>
1147            </li>
1148            
1149          </ul>
1150        </div>
1151
1152        
1153        <details class="mt-5 group">
1154          <summary class="flex items-center gap-2 text-sm font-medium text-[var(--color-text)] hover:text-[var(--color-primary)] transition-colors py-2">
1155            <svg class="w-4 h-4 disclosure-caret text-[var(--color-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
1156            <span>Exact configuration used for this sample</span>
1157          </summary>
1158          <dl class="mt-2 ml-6 space-y-1.5 text-sm">
1159            
1160            <div class="flex flex-col sm:flex-row sm:gap-3">
1161              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Library item</dt>
1162              <dd class="text-[var(--color-text)]">C1:conversation:0</dd>
1163            </div>
1164            
1165            <div class="flex flex-col sm:flex-row sm:gap-3">
1166              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Level</dt>
1167              <dd class="text-[var(--color-text)]">C1</dd>
1168            </div>
1169            
1170            <div class="flex flex-col sm:flex-row sm:gap-3">
1171              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Exercise types</dt>
1172              <dd class="text-[var(--color-text)]">6 (multiple_choice, true_false, gap_fill, note_completion, matching, sentence_completion)</dd>
1173            </div>
1174            
1175          </dl>
1176        </details>
1177
1178        
1179        <details class="mt-1 group">
1180          <summary class="flex items-center gap-2 text-sm font-medium text-[var(--color-text)] hover:text-[var(--color-primary)] transition-colors py-2">
1181            <svg class="w-4 h-4 disclosure-caret text-[var(--color-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
1182            <span>What's possible with the Listening composer</span>
1183          </summary>
1184          <div class="mt-2 ml-6 space-y-3 text-sm">
1185            <div>
1186              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Generation pathway</p>
1187              <ul class="space-y-1 text-[var(--color-text)]">
1188                
1189                <li class="leading-snug">Browse the library (free), pick a script, configure exercises.</li>
1190                
1191              </ul>
1192            </div>
1193
1194            
1195            <div>
1196              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Presets available</p>
1197              <ul class="space-y-1 text-[var(--color-text)]">
1198                
1199                <li class="leading-snug">Quick Listen (all levels)</li>
1200                
1201                <li class="leading-snug">IELTS Listening (B1+, speakers students can tell apart, not interviews or phone calls)</li>
1202                
1203                <li class="leading-snug">Cambridge Listening (B1+)</li>
1204                
1205                <li class="leading-snug">Comprehensive (B1+, conversations)</li>
1206                
1207                <li class="leading-snug">Detail Focus (B1+)</li>
1208                
1209              </ul>
1210            </div>
1211            
1212
1213            
1214            <div>
1215              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Exercise types</p>
1216              <p class="text-[var(--color-text)] leading-snug">8 types — multiple choice, true/false, gap fill, short answer, sentence completion, note completion, matching, classification</p>
1217            </div>
1218            
1219
1220            
1221
1222            
1223
1224            
1225            <div>
1226              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Library scope</p>
1227              <p class="text-[var(--color-text)] leading-snug">335 audio scripts across A1–C2 in 7 formats: conversation, interview, lecture, monologue, news report, phone call, announcement</p>
1228            </div>
1229            
1230
1231            
1232
1233            
1234
1235            
1236            <p class="text-xs italic text-[var(--color-text-muted)] pt-1 border-t border-[var(--color-border-light)] mt-3 pt-3">Browse library free, generate exercises on credit</p>
1237            
1238          </div>
1239        </details>
1240
1241        
1242        <div class="mt-7 flex flex-wrap items-center gap-3">
1243          <button type="button"
1244                  @click="openPreview('listening-c1')"
1245                  class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-primary-fill)] px-4 py-2.5 text-sm font-semibold text-primary-content hover:bg-[var(--color-primary-hover)] transition-colors duration-150 shadow-sm">
1246            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/>
1246<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
1247            Preview
1248          </button>
1249
1250          <a href="/static/samples/05_listening_c1/material.pdf" download
1251             class="inline-flex items-center gap-2 rounded-lg border border-[var(--color-border)] bg-[var(--color-bg-card)] px-4 py-2.5 text-sm font-medium text-[var(--color-text)] hover:border-[var(--color-primary)] hover:text-[var(--color-primary)] transition-colors duration-150">
1252            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/></svg>
1253            Download PDF
1254          </a>
1255
1256          
1257
1258          
1259          <a href="/products/listening"
1260             class="inline-flex items-center gap-1.5 ml-auto text-sm font-semibold transition-colors hover:opacity-80"
1261             style="color: #0891B2;">
1262            Learn more about Listening
1263            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
1264          </a>
1265        </div>
1266      </div>
1267    </article>
1268
1269    
1270    <div class="border-t border-[var(--color-border-light)]/80 max-w-2xl mx-auto"></div>
1271    
1272
1273    
1274    
1275    
1276
1277    <article id="exam-fce-b2" class="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12 items-start scroll-mt-24">
1278
1279      
1280      <div class="order-2 lg:col-span-5 lg:order-2 relative">
1281        <div class="paper-surface rounded-md overflow-hidden transition-shadow duration-300 cursor-pointer group"
1282             @click="openPreview('exam-fce-b2')"
1283             role="button"
1284             tabindex="0"
1285             @keydown.enter="openPreview('exam-fce-b2')"
1286             @keydown.space.prevent="openPreview('exam-fce-b2')"
1287             aria-label="Preview Cambridge B2 First Practice">
1288          <img src="/static/samples/thumbnails/06_exam_fce_b2.png" alt="First page of Cambridge B2 First Practice"
1289               class="w-full h-auto block"
1290               loading="lazy">
1291          
1292          <div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-[var(--color-text)]/40">
1293            <span class="inline-flex items-center gap-2 rounded-full bg-white/95 px-4 py-2 text-sm font-semibold text-[var(--color-on-exam)] shadow-lg">
1294              <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
1295              Preview all pages
1296            </span>
1297          </div>
1298        </div>
1299
1300        
1301        <div class="mt-3 flex items-center justify-between text-xs text-[var(--color-text-muted)] px-1">
1302          <span>
1303            22 pages · material
1304            <span class="mx-1.5 text-[var(--color-text-faint)]">+</span>
1305            13 pages · answers
1306          </span>
1307          
1308        </div>
1309      </div>
1310
1311      
1312      <div class="order-1 lg:col-span-7 lg:order-1">
1313
1314        
1315        <div class="flex items-baseline gap-4 mb-3">
1316          <span class="sample-numeral" style="color: #9333EA;">06</span>
1317          <div class="flex flex-wrap items-center gap-2">
1318            
1319            
1320            <span class="text-xs tracking-wider uppercase font-semibold" style="color: #9333EA;">Exam Paper</span>
1321            <span class="inline-flex items-center rounded-md px-1.5 py-0.5 text-[10px] font-bold tracking-wide text-white leading-none" style="background-color: #9333EA;">B2</span>
1322          </div>
1323        </div>
1324
1325        <h2 class="font-display text-2xl lg:text-3xl text-[var(--color-text)] tracking-tight leading-tight">
1326          Cambridge B2 First Practice
1327        </h2>
1328        <p class="mt-2 text-base text-[var(--color-text-muted)] leading-relaxed">
1329          Full multi-domain exam paper combining grammar, reading, writing, and Cambridge-style exam-only sections.
1330        </p>
1331
1332        
1333        <div class="mt-6">
1334          <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-2.5">What's inside</p>
1335          <ul class="space-y-1.5 text-sm text-[var(--color-text)]">
1336            
1337            <li class="flex gap-2.5">
1338              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
1339              <span>3 domains, 110 marks, 155-minute paper</span>
1340            </li>
1341            
1342            <li class="flex gap-2.5">
1343              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
1344              <span>Use of English: multiple-choice cloze (8 items), open cloze (8 items), word formation (8 items), key word transformation (6 items), gapped text (6 items) — 48 marks, exam-only types</span>
1345            </li>
1346            
1347            <li class="flex gap-2.5">
1348              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
1349              <span>Reading: 2 texts, 2 task types (16 items, 22 marks)</span>
1350            </li>
1351            
1352            <li class="flex gap-2.5">
1353              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
1354              <span>Writing: Essay, then a choice of 3 tasks drawn from Article, Formal Letter, Review, Report — 40 marks</span>
1355            </li>
1356            
1357            <li class="flex gap-2.5">
1358              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
1359              <span>Parts print in the official order; detailed answer key</span>
1360            </li>
1361            
1362          </ul>
1363        </div>
1364
1365        
1366        <details class="mt-5 group">
1367          <summary class="flex items-center gap-2 text-sm font-medium text-[var(--color-text)] hover:text-[var(--color-primary)] transition-colors py-2">
1368            <svg class="w-4 h-4 disclosure-caret text-[var(--color-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
1369            <span>Exact configuration used for this sample</span>
1370          </summary>
1371          <dl class="mt-2 ml-6 space-y-1.5 text-sm">
1372            
1373            <div class="flex flex-col sm:flex-row sm:gap-3">
1374              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Preset</dt>
1375              <dd class="text-[var(--color-text)]">Cambridge B2 First (FCE)</dd>
1376            </div>
1377            
1378            <div class="flex flex-col sm:flex-row sm:gap-3">
1379              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Domains</dt>
1380              <dd class="text-[var(--color-text)]">Reading · Writing · Exam-only (Multiple-choice Cloze, Open Cloze, Word Formation, Key Word Transformation, Gapped Text)</dd>
1381            </div>
1382            
1383            <div class="flex flex-col sm:flex-row sm:gap-3">
1384              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Total marks</dt>
1385              <dd class="text-[var(--color-text)]">110</dd>
1386            </div>
1387            
1388            <div class="flex flex-col sm:flex-row sm:gap-3">
1389              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Time</dt>
1390              <dd class="text-[var(--color-text)]">155 minutes</dd>
1391            </div>
1392            
1393          </dl>
1394        </details>
1395
1396        
1397        <details class="mt-1 group">
1398          <summary class="flex items-center gap-2 text-sm font-medium text-[var(--color-text)] hover:text-[var(--color-primary)] transition-colors py-2">
1399            <svg class="w-4 h-4 disclosure-caret text-[var(--color-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
1400            <span>What's possible with the Exam composer</span>
1401          </summary>
1402          <div class="mt-2 ml-6 space-y-3 text-sm">
1403            <div>
1404              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Generation pathway</p>
1405              <ul class="space-y-1 text-[var(--color-text)]">
1406                
1407                <li class="leading-snug">Pick a preset and tweak, or build a fully custom exam from scratch.</li>
1408                
1409              </ul>
1410            </div>
1411
1412            
1413            <div>
1414              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Presets available</p>
1415              <ul class="space-y-1 text-[var(--color-text)]">
1416                
1417                <li class="leading-snug">Cambridge B2 First (FCE) — the Reading &amp; Use of English and Writing papers, part by part</li>
1418                
1419                <li class="leading-snug">Cambridge C1 Advanced (CAE) — the Reading &amp; Use of English and Writing papers, part by part</li>
1420                
1421                <li class="leading-snug">Grammar &amp; Vocab Quiz — short multi-domain knowledge check</li>
1422                
1423                <li class="leading-snug">Grammar Focus — in-depth grammar-only exam</li>
1424                
1425                <li class="leading-snug">Comprehensive Assessment — balanced multi-domain test</li>
1426                
1427              </ul>
1428            </div>
1429            
1430
1431            
1432
1433            
1434
1435            
1436
1437            
1438
1439            
1440            <div>
1441              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Exam-only exercise types</p>
1442              <p class="text-[var(--color-text)] leading-snug">6 types not available in standalone products — Multiple-choice Cloze (B2+), Open Cloze (B2+), Word Formation (B2+), Key Word Transformation (B2+), Gapped Text (B2+), Cross-text Multiple Matching (C1 only)</p>
1443            </div>
1444            
1445
1446            
1447
1448            
1449            <p class="text-xs italic text-[var(--color-text-muted)] pt-1 border-t border-[var(--color-border-light)] mt-3 pt-3">Combines all 5 standalone products + 6 exam-only types. Domains can be reordered. Per-section marks customizable. Header (teacher name, time, instructions) fully editable.</p>
1450            
1451          </div>
1452        </details>
1453
1454        
1455        <div class="mt-7 flex flex-wrap items-center gap-3">
1456          <button type="button"
1457                  @click="openPreview('exam-fce-b2')"
1458                  class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-primary-fill)] px-4 py-2.5 text-sm font-semibold text-primary-content hover:bg-[var(--color-primary-hover)] transition-colors duration-150 shadow-sm">
1459            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
1460            Preview
1461          </button>
1462
1463          <a href="/static/samples/06_exam_fce_b2/material.pdf" download
1464             class="inline-flex items-center gap-2 rounded-lg border border-[var(--color-border)] bg-[var(--color-bg-card)] px-4 py-2.5 text-sm font-medium text-[var(--color-text)] hover:border-[var(--color-primary)] hover:text-[var(--color-primary)] transition-colors duration-150">
1465            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/></svg>
1466            Download PDF
1467          </a>
1468
1469          
1470
1471          
1472          <a href="/products/exam"
1473             class="inline-flex items-center gap-1.5 ml-auto text-sm font-semibold transition-colors hover:opacity-80"
1474             style="color: #9333EA;">
1475            Learn more about Exam
1476            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
1477          </a>
1478        </div>
1479      </div>
1480    </article>
1481
1482    
1483    <div class="border-t border-[var(--color-border-light)]/80 max-w-2xl mx-auto"></div>
1484    
1485
1486    
1487    
1488    
1489
1490    <article id="exam-cae-c1" class="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12 items-start scroll-mt-24">
1491
1492      
1493      <div class="order-2 lg:col-span-5 lg:order-1 relative">
1494        <div class="paper-surface rounded-md overflow-hidden transition-shadow duration-300 cursor-pointer group"
1495             @click="openPreview('exam-cae-c1')"
1496             role="button"
1497             tabindex="0"
1498             @keydown.enter="openPreview('exam-cae-c1')"
1499             @keydown.space.prevent="openPreview('exam-cae-c1')"
1500             aria-label="Preview Cambridge C1 Advanced Practice">
1501          <img src="/static/samples/thumbnails/07_exam_cae_c1.png" alt="First page of Cambridge C1 Advanced Practice"
1502               class="w-full h-auto block"
1503               loading="lazy">
1504          
1505          <div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 bg-[var(--color-text)]/40">
1506            <span class="inline-flex items-center gap-2 rounded-full bg-white/95 px-4 py-2 text-sm font-semibold text-[var(--color-on-exam)] shadow-lg">
1507              <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
1508              Preview all pages
1509            </span>
1510          </div>
1511        </div>
1512
1513        
1514        <div class="mt-3 flex items-center justify-between text-xs text-[var(--color-text-muted)] px-1">
1515          <span>
1516            26 pages · material
1517            <span class="mx-1.5 text-[var(--color-text-faint)]">+</span>
1518            15 pages · answers
1519          </span>
1520          
1521        </div>
1522      </div>
1523
1524      
1525      <div class="order-1 lg:col-span-7 lg:order-2">
1526
1527        
1528        <div class="flex items-baseline gap-4 mb-3">
1529          <span class="sample-numeral" style="color: #7C3AED;">07</span>
1530          <div class="flex flex-wrap items-center gap-2">
1531            
1532            
1533            <span class="text-xs tracking-wider uppercase font-semibold" style="color: #7C3AED;">Exam Paper</span>
1534            <span class="inline-flex items-center rounded-md px-1.5 py-0.5 text-[10px] font-bold tracking-wide text-white leading-none" style="background-color: #7C3AED;">C1</span>
1535          </div>
1536        </div>
1537
1538        <h2 class="font-display text-2xl lg:text-3xl text-[var(--color-text)] tracking-tight leading-tight">
1539          Cambridge C1 Advanced Practice
1540        </h2>
1541        <p class="mt-2 text-base text-[var(--color-text-muted)] leading-relaxed">
1542          The C1 paper: longer reading, a report task, and 220-260 word limits.
1543        </p>
1544
1545        
1546        <div class="mt-6">
1547          <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-2.5">What's inside</p>
1548          <ul class="space-y-1.5 text-sm text-[var(--color-text)]">
1549            
1550            <li class="flex gap-2.5">
1551              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
1552              <span>3 domains, 118 marks, 180-minute paper</span>
1553            </li>
1554            
1555            <li class="flex gap-2.5">
1556              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
1557              <span>Use of English: multiple-choice cloze (8 items), open cloze (8 items), word formation (8 items), key word transformation (6 items), cross-text multiple matching (4 items), gapped text (6 items) — 56 marks, exam-only types</span>
1558            </li>
1559            
1560            <li class="flex gap-2.5">
1561              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
1562              <span>Reading: 2 texts, 2 task types (16 items, 22 marks)</span>
1563            </li>
1564            
1565            <li class="flex gap-2.5">
1566              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
1567              <span>Writing: Essay, then a choice of 3 tasks drawn from Formal Letter, Proposal, Report, Review — 40 marks</span>
1568            </li>
1569            
1570            <li class="flex gap-2.5">
1571              <svg class="w-4 h-4 mt-0.5 shrink-0 text-[var(--color-primary)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
1572              <span>Parts print in the official order; detailed answer key</span>
1573            </li>
1574            
1575          </ul>
1576        </div>
1577
1578        
1579        <details class="mt-5 group">
1580          <summary class="flex items-center gap-2 text-sm font-medium text-[var(--color-text)] hover:text-[var(--color-primary)] transition-colors py-2">
1581            <svg class="w-4 h-4 disclosure-caret text-[var(--color-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
1582            <span>Exact configuration used for this sample</span>
1583          </summary>
1584          <dl class="mt-2 ml-6 space-y-1.5 text-sm">
1585            
1586            <div class="flex flex-col sm:flex-row sm:gap-3">
1587              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Preset</dt>
1588              <dd class="text-[var(--color-text)]">Cambridge C1 Advanced (CAE)</dd>
1589            </div>
1590            
1591            <div class="flex flex-col sm:flex-row sm:gap-3">
1592              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Domains</dt>
1593              <dd class="text-[var(--color-text)]">Reading · Writing · Exam-only (Multiple-choice Cloze, Open Cloze, Word Formation, Key Word Transformation, Cross-text Multiple Matching, Gapped Text)</dd>
1594            </div>
1595            
1596            <div class="flex flex-col sm:flex-row sm:gap-3">
1597              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Total marks</dt>
1598              <dd class="text-[var(--color-text)]">118</dd>
1599            </div>
1600            
1601            <div class="flex flex-col sm:flex-row sm:gap-3">
1602              <dt class="text-[var(--color-text-muted)] sm:w-40 sm:shrink-0">Time</dt>
1603              <dd class="text-[var(--color-text)]">180 minutes</dd>
1604            </div>
1605            
1606          </dl>
1607        </details>
1608
1609        
1610        <details class="mt-1 group">
1611          <summary class="flex items-center gap-2 text-sm font-medium text-[var(--color-text)] hover:text-[var(--color-primary)] transition-colors py-2">
1612            <svg class="w-4 h-4 disclosure-caret text-[var(--color-text-muted)]" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"/></svg>
1613            <span>What's possible with the Exam composer</span>
1614          </summary>
1615          <div class="mt-2 ml-6 space-y-3 text-sm">
1616            <div>
1617              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Generation pathway</p>
1618              <ul class="space-y-1 text-[var(--color-text)]">
1619                
1620                <li class="leading-snug">Pick a preset and tweak, or build a fully custom exam from scratch.</li>
1621                
1622              </ul>
1623            </div>
1624
1625            
1626            <div>
1627              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Presets available</p>
1628              <ul class="space-y-1 text-[var(--color-text)]">
1629                
1630                <li class="leading-snug">Cambridge B2 First (FCE) — the Reading &amp; Use of English and Writing papers, part by part</li>
1631                
1632                <li class="leading-snug">Cambridge C1 Advanced (CAE) — the Reading &amp; Use of English and Writing papers, part by part</li>
1633                
1634                <li class="leading-snug">Grammar &amp; Vocab Quiz — short multi-domain knowledge check</li>
1635                
1636                <li class="leading-snug">Grammar Focus — in-depth grammar-only exam</li>
1637                
1638                <li class="leading-snug">Comprehensive Assessment — balanced multi-domain test</li>
1639                
1640              </ul>
1641            </div>
1642            
1643
1644            
1645
1646            
1647
1648            
1649
1650            
1651
1652            
1653            <div>
1654              <p class="text-xs tracking-wider uppercase text-[var(--color-text-faint)] font-semibold mb-1">Exam-only exercise types</p>
1655              <p class="text-[var(--color-text)] leading-snug">6 types not available in standalone products — Multiple-choice Cloze (B2+), Open Cloze (B2+), Word Formation (B2+), Key Word Transformation (B2+), Gapped Text (B2+), Cross-text Multiple Matching (C1 only)</p>
1656            </div>
1657            
1658
1659            
1660
1661            
1662            <p class="text-xs italic text-[var(--color-text-muted)] pt-1 border-t border-[var(--color-border-light)] mt-3 pt-3">
1662Any mix of the 5 standalone products, at any level from A1 to C2.</p>
1663            
1664          </div>
1665        </details>
1666
1667        
1668        <div class="mt-7 flex flex-wrap items-center gap-3">
1669          <button type="button"
1670                  @click="openPreview('exam-cae-c1')"
1671                  class="inline-flex items-center gap-2 rounded-lg bg-[var(--color-primary-fill)] px-4 py-2.5 text-sm font-semibold text-primary-content hover:bg-[var(--color-primary-hover)] transition-colors duration-150 shadow-sm">
1672            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
1673            Preview
1674          </button>
1675
1676          <a href="/static/samples/07_exam_cae_c1/material.pdf" download
1677             class="inline-flex items-center gap-2 rounded-lg border border-[var(--color-border)] bg-[var(--color-bg-card)] px-4 py-2.5 text-sm font-medium text-[var(--color-text)] hover:border-[var(--color-primary)] hover:text-[var(--color-primary)] transition-colors duration-150">
1678            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/></svg>
1679            Download PDF
1680          </a>
1681
1682          
1683
1684          
1685          <a href="/products/exam"
1686             class="inline-flex items-center gap-1.5 ml-auto text-sm font-semibold transition-colors hover:opacity-80"
1687             style="color: #7C3AED;">
1688            Learn more about Exam
1689            <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
1690          </a>
1691        </div>
1692      </div>
1693    </article>
1694
1695    
1696
1697    
1698  </div>
1699</section>
1700
1701
1702
1703<section class="py-16 lg:py-24" style="background-color: var(--color-primary-light);">
1704  <div class="max-w-3xl mx-auto px-6 text-center">
1705    <h2 class="font-display text-3xl lg:text-4xl text-[var(--color-text)]">
1706      None of these match what you need?
1707    </h2>
1708    <p class="mt-4 text-lg text-[var(--color-text-muted)] max-w-2xl mx-auto">
1709      That&#39;s the point — every parameter above is yours to set. Pick a product and tweak it for your class.
1710    </p>
1711
1712    <div class="mt-8 flex flex-wrap justify-center gap-2">
1713      
1714      
1715      
1716      <a href="/products/grammar"
1717         class="inline-flex items-center gap-1.5 rounded-lg bg-[var(--color-bg-card)] border px-4 py-2 text-sm font-medium hover:shadow-sm transition-all duration-150"
1718         style="border-color: #2563EB30; color: #2563EB;"
1719         onmouseenter="this.style.borderColor='#2563EB'; this.style.backgroundColor='#2563EB08';"
1720         onmouseleave="this.style.borderColor='#2563EB30'; this.style.backgroundColor='var(--color-bg-card)';">
1721        Grammar
1722        <svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
1723      </a>
1724      
1725      
1726      <a href="/products/vocabulary"
1727         class="inline-flex items-center gap-1.5 rounded-lg bg-[var(--color-bg-card)] border px-4 py-2 text-sm font-medium hover:shadow-sm transition-all duration-150"
1728         style="border-color: #16A34A30; color: #16A34A;"
1729         onmouseenter="this.style.borderColor='#16A34A'; this.style.backgroundColor='#16A34A08';"
1730         onmouseleave="this.style.borderColor='#16A34A30'; this.style.backgroundColor='var(--color-bg-card)';">
1731        Vocabulary
1732        <svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
1733      </a>
1734      
1735      
1736      <a href="/products/reading"
1737         class="inline-flex items-center gap-1.5 rounded-lg bg-[var(--color-bg-card)] border px-4 py-2 text-sm font-medium hover:shadow-sm transition-all duration-150"
1738         style="border-color: #D9770630; color: #D97706;"
1739         onmouseenter="this.style.borderColor='#D97706'; this.style.backgroundColor='#D9770608';"
1740         onmouseleave="this.style.borderColor='#D9770630'; this.style.backgroundColor='var(--color-bg-card)';">
1741        Reading
1742        <svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
1743      </a>
1744      
1745      
1746      <a href="/products/writing"
1747         class="inline-flex items-center gap-1.5 rounded-lg bg-[var(--color-bg-card)] border px-4 py-2 text-sm font-medium hover:shadow-sm transition-all duration-150"
1748         style="border-color: #E11D4830; color: #E11D48;"
1749         onmouseenter="this.style.borderColor='#E11D48'; this.style.backgroundColor='#E11D4808';"
1750         onmouseleave="this.style.borderColor='#E11D4830'; this.style.backgroundColor='var(--color-bg-card)';">
1751        Writing
1752        <svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
1753      </a>
1754      
1755      
1756      <a href="/products/listening"
1757         class="inline-flex items-center gap-1.5 rounded-lg bg-[var(--color-bg-card)] border px-4 py-2 text-sm font-medium hover:shadow-sm transition-all duration-150"
1758         style="border-color: #0891B230; color: #0891B2;"
1759         onmouseenter="this.style.borderColor='#0891B2'; this.style.backgroundColor='#0891B208';"
1760         onmouseleave="this.style.borderColor='#0891B230'; this.style.backgroundColor='var(--color-bg-card)';">
1761        Listening
1762        <svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
1763      </a>
1764      
1765      
1766      <a href="/products/exam"
1767         class="inline-flex items-center gap-1.5 rounded-lg bg-[var(--color-bg-card)] border px-4 py-2 text-sm font-medium hover:shadow-sm transition-all duration-150"
1768         style="border-color: #9333EA30; color: #9333EA;"
1769         onmouseenter="this.style.borderColor='#9333EA'; this.style.backgroundColor='#9333EA08';"
1770         onmouseleave="this.style.borderColor='#9333EA30'; this.style.backgroundColor='var(--color-bg-card)';">
1771        Exam
1772        <svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
1773      </a>
1774      
1775      
1776      <a href="/products/exam"
1777         class="inline-flex items-center gap-1.5 rounded-lg bg-[var(--color-bg-card)] border px-4 py-2 text-sm font-medium hover:shadow-sm transition-all duration-150"
1778         style="border-color: #7C3AED30; color: #7C3AED;"
1779         onmouseenter="this.style.borderColor='#7C3AED'; this.style.backgroundColor='#7C3AED08';"
1780         onmouseleave="this.style.borderColor='#7C3AED30'; this.style.backgroundColor='var(--color-bg-card)';">
1781        Exam
1782        <svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
1783      </a>
1784      
1785    </div>
1786
1787    
1788    <p class="mt-10 text-sm text-[var(--color-text-muted)]">
1789      18 free credits at signup — enough to try every composer.
1790    </p>
1791    <a href="/auth"
1792       class="mt-3 inline-flex items-center gap-2 rounded-lg px-7 py-3 text-base font-semibold text-primary-content bg-[var(--color-primary-fill)] shadow-md transition-all duration-200 hover:-translate-y-0.5 hover:shadow-lg hover:bg-[var(--color-primary-hover)]">
1793      Start composing
1794      <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
1795    </a>
1796    
1797  </div>
1798</section>
1799
1800
1801
1802<div x-show="open"
1803     x-cloak
1804     x-transition.opacity
1805     :class="open ? 'preview-modal-active' : ''"
1806     class="fixed inset-0 z-50 bg-[var(--color-text)]/85 backdrop-blur-sm flex flex-col"
1807     role="dialog" aria-modal="true" aria-label="Sample preview"
1808     x-effect="open ? tfFocusFirst($el) : null"
1809     @keydown.tab="tfTrapTab($event, $el)"
1810     @keydown.escape.window="closePreview()">
1811
1812  
1813  <div class="flex items-center justify-between gap-4 px-4 sm:px-6 py-3 bg-[var(--color-bg-card)] border-b border-[var(--color-border)] shrink-0">
1814    <div class="min-w-0 flex-1">
1815      <p class="text-xs tracking-wider uppercase font-semibold text-[var(--color-primary)]"
1816         x-text="currentSample ? ((currentSample.product.toLowerCase() === currentSample.type_label.toLowerCase().split(' ')[0].toLowerCase() ? currentSample.type_label : currentSample.product + ' ' + currentSample.type_label) + ' · ' + currentSample.level) : ''"></p>
1817      <h3 class="font-display text-lg sm:text-xl text-[var(--color-text)] truncate" x-text="currentSample ? currentSample.title : ''"></h3>
1818    </div>
1819
1820    
1821    <div class="hidden sm:inline-flex rounded-lg border border-[var(--color-border)] bg-[var(--color-bg)] p-0.5">
1822      <button type="button"
1823              @click="view = 'material'"
1824              :class="view === 'material' ? 'bg-[var(--color-primary-fill)] text-primary-content' : 'text-[var(--color-text-muted)] hover:text-[var(--color-text)]'"
1825              class="rounded-md px-3 py-1.5 text-xs font-semibold transition-colors">Material</button>
1826      <button type="button"
1827              @click="view = 'answers'"
1828              :class="view === 'answers' ? 'bg-[var(--color-primary-fill)] text-primary-content' : 'text-[var(--color-text-muted)] hover:text-[var(--color-text)]'"
1829              class="rounded-md px-3 py-1.5 text-xs font-semibold transition-colors">Answer key</button>
1830    </div>
1831
1832    
1833    <div class="flex items-center gap-2 shrink-0">
1834      <a x-show="currentSample"
1835         :href="view === 'material' ? currentSample.files.material_pdf : currentSample.files.answers_pdf"
1836         download
1837         class="hidden sm:inline-flex items-center gap-1.5 rounded-md border border-[var(--color-border)] px-3 py-1.5 text-xs font-medium text-[var(--color-text)] hover:border-[var(--color-primary)] hover:text-[var(--color-primary)]">
1838        <svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/></svg>
1839        Download
1840      </a>
1841      <button type="button"
1842              @click="closePreview()"
1843              class="p-2 rounded-md text-[var(--color-text-muted)] hover:text-[var(--color-text)] hover:bg-[var(--color-border-light)] transition-colors"
1844              aria-label="Close preview">
1845        <svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
1846      </button>
1847    </div>
1848  </div>
1849
1850  
1851  <div class="sm:hidden bg-[var(--color-bg-card)] border-b border-[var(--color-border)] px-4 pb-3 flex items-center gap-2">
1852    <div class="inline-flex rounded-lg border border-[var(--color-border)] bg-[var(--color-bg)] p-0.5">
1853      <button type="button" @click="view = 'material'"
1854              :class="view === 'material' ? 'bg-[var(--color-primary-fill)] text-primary-content' : 'text-[var(--color-text-muted)]'"
1855              class="rounded-md px-3 py-1 text-xs font-semibold">Material</button>
1856      <button type="button" @click="view = 'answers'"
1857              :class="view === 'answers' ? 'bg-[var(--color-primary-fill)] text-primary-content' : 'text-[var(--color-text-muted)]'"
1858              class="rounded-md px-3 py-1 text-xs font-semibold">Answer key</button>
1859    </div>
1860    <a x-show="currentSample"
1861       :href="view === 'material' ? currentSample.files.material_pdf : currentSample.files.answers_pdf"
1862       download
1863       class="ml-auto inline-flex items-center gap-1 rounded-md border border-[var(--color-border)] px-2.5 py-1 text-xs font-medium text-[var(--color-text)]">
1864      <svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/></svg>
1865      PDF
1866    </a>
1867  </div>
1868
1869  
1870  <div x-show="currentSample && currentSample.files.audio_mp3" class="bg-[var(--color-bg-card)] border-b border-[var(--color-border)] px-4 sm:px-6 py-3 flex items-center gap-3">
1871    <span class="text-xs tracking-wider uppercase font-semibold text-[var(--color-primary)] shrink-0">Audio</span>
1872    <audio x-show="currentSample && currentSample.files.audio_mp3"
1873           :src="currentSample ? currentSample.files.audio_mp3 : ''"
1874           controls preload="none"
1875           class="w-full max-w-md"></audio>
1876  </div>
1877
1878  
1879  <div class="flex-1 overflow-y-auto py-8 px-4 sm:px-6">
1880    <div class="max-w-3xl mx-auto space-y-4">
1881      <template x-for="(page, idx) in (currentSample ? (view === 'material' ? currentSample.preview_pages.material : currentSample.preview_pages.answers) : [])" :key="page">
1882        <div class="paper-surface rounded-md overflow-hidden">
1883          <img :src="page" :alt="'Page ' + (idx + 1)" class="w-full h-auto block" loading="lazy">
1884        </div>
1885      </template>
1886    </div>
1887
1888    <p class="max-w-3xl mx-auto mt-6 text-center text-xs text-white/60">
1889      End of preview · <a x-show="currentSample" :href="view === 'material' ? currentSample.files.material_pdf : currentSample.files.answers_pdf" download class="underline hover:text-white">Download the full PDF</a>
1890    </p>
1891  </div>
1892</div>
1893
1894</div>
1895
1896<script>
1897function samplesGallery() {
1898  return {
1899    open: false,
1900    view: 'material',
1901    currentSample: null,
1902    samples: [{"accent_hex": "#2563EB", "composer_url": "/grammar-composer", "config_used": {"Exercise types": "5 (sentence_completion, select_and_combine, sentence_transformation, gap_fill, true_false)", "Grammar tags": "First Conditional \u00b7 Passive: by + Agent \u0026 Questions \u00b7 Adverbs of Degree: very/much"}, "files": {"answers_docx": "/static/samples/01_grammar_b1/answers.docx", "answers_pdf": "/static/samples/01_grammar_b1/answers.pdf", "material_docx": "/static/samples/01_grammar_b1/material.docx", "material_pdf": "/static/samples/01_grammar_b1/material.pdf", "thumbnail": "/static/samples/thumbnails/01_grammar_b1.png"}, "id": "grammar-b1", "level": "B1", "preview_pages": {"answers": ["/static/samples/01_grammar_b1/preview/answers-1.png", "/static/samples/01_grammar_b1/preview/answers-2.png", "/static/samples/01_grammar_b1/preview/answers-3.png"], "material": ["/static/samples/01_grammar_b1/preview/material-1.png", "/static/samples/01_grammar_b1/preview/material-2.png", "/static/samples/01_grammar_b1/preview/material-3.png", "/static/samples/01_grammar_b1/preview/material-4.png", "/static/samples/01_grammar_b1/preview/material-5.png"]}, "product": "Grammar", "product_breadth": {"exercise_types_available": "9 types \u2014 gap fill, open cloze, multiple choice, error correction, word ordering, sentence transformation, true/false, sentence completion, select \u0026 combine. Per-tag compatibility matrix governs which types fit which tags.", "pathway": "Tag-based \u2014 pick 1 to 3 grammar tags from the curriculum", "pathways_available": ["Tag selection (no presets \u2014 Grammar is fully custom by design)"], "presets_available": [], "scope": "300+ grammar tags from A1 to C2. Each tag carries its own level."}, "product_slug": "grammar", "subtitle": "Three core grammar topics that mark progression from intermediate to upper-intermediate.", "title": "Hallmark Upper-B1 Grammar", "type_label": "Worksheet", "whats_inside": ["7 sections, 30 items", "Tags covered: First Conditional, Passive: by + Agent \u0026 Questions, Adverbs of Degree: very/much", "5 distinct exercise types showcased: sentence completion, select and combine, sentence transformation, gap fill, true false"]}, {"accent_hex": "#16A34A", "composer_url": "/vocab-composer", "config_used": {"Domain": "Work \u0026 Learning", "Exercise types": "5 (gap_fill, multiple_choice, matching, word_ordering, true_false)", "Path used": "Topic Explorer (catalog domain + subtopic)", "Subtopic": "Job Interviews"}, "files": {"answers_docx": "/static/samples/02_vocabulary_b1/answers.docx", "answers_pdf": "/static/samples/02_vocabulary_b1/answers.pdf", "material_docx": "/static/samples/02_vocabulary_b1/material.docx", "material_pdf": "/static/samples/02_vocabulary_b1/material.pdf", "thumbnail": "/static/samples/thumbnails/02_vocabulary_b1.png"}, "id": "vocabulary-b1", "level": "B1", "preview_pages": {"answers": ["/static/samples/02_vocabulary_b1/preview/answers-1.png", "/static/samples/02_vocabulary_b1/preview/answers-2.png", "/static/samples/02_vocabulary_b1/preview/answers-3.png"], "material": ["/static/samples/02_vocabulary_b1/preview/material-1.png", "/static/samples/02_vocabulary_b1/preview/material-2.png", "/static/samples/02_vocabulary_b1/preview/material-3.png", "/static/samples/02_vocabulary_b1/preview/material-4.png"]}, "product": "Vocabulary", "product_breadth": {"exercise_types_available": "5 types \u2014 matching, gap fill, multiple choice, true/false, word ordering", "pathway": "3 ways to source words", "pathways_available": ["Path A \u2014 My Words: paste your own word list, AI enriches with POS + CEFR-adapted definitions", "Path B \u2014 Topic 
1902Explorer: pick from 11 domains \u00d7 528 curated subtopics across A1\u2013C2", "Path C \u2014 Paste Text: drop in a passage, AI extracts vocabulary + auto-detects topic and CEFR level"], "presets_available": [], "scope": "11 domains \u00d7 528 catalog subtopics, plus unlimited custom subtopics and pasted text"}, "product_slug": "vocabulary", "subtitle": "Vocabulary set built from the catalog around a topic adult classes actually need.", "title": "Job Interviews", "type_label": "Worksheet", "whats_inside": ["5 sections, 30 items", "Words from Work \u0026 Learning \u2192 Job Interviews (B1)", "5 distinct exercise types showcased: gap fill, multiple choice, matching, word ordering, true false"]}, {"accent_hex": "#D97706", "composer_url": "/reading-composer", "config_used": {"Exercise types": "5 (multiple_choice, true_false, short_answer, cause_effect, note_completion)", "Length": "Long", "Path used": "Generate Passage (AI from topic)", "Text style": "Article", "Topic": "Urban farming on the rooftops of Southeast Asian cities"}, "files": {"answers_docx": "/static/samples/03_reading_b2/answers.docx", "answers_pdf": "/static/samples/03_reading_b2/answers.pdf", "material_docx": "/static/samples/03_reading_b2/material.docx", "material_pdf": "/static/samples/03_reading_b2/material.pdf", "thumbnail": "/static/samples/thumbnails/03_reading_b2.png"}, "id": "reading-b2", "level": "B2", "preview_pages": {"answers": ["/static/samples/03_reading_b2/preview/answers-1.png", "/static/samples/03_reading_b2/preview/answers-2.png", "/static/samples/03_reading_b2/preview/answers-3.png"], "material": ["/static/samples/03_reading_b2/preview/material-1.png", "/static/samples/03_reading_b2/preview/material-2.png", "/static/samples/03_reading_b2/preview/material-3.png", "/static/samples/03_reading_b2/preview/material-4.png", "/static/samples/03_reading_b2/preview/material-5.png", "/static/samples/03_reading_b2/preview/material-6.png", "/static/samples/03_reading_b2/preview/material-7.png"]}, "product": "Reading", "product_breadth": {"exercise_types_available": "8 types \u2014 multiple choice, true/false/not given, short answer, matching headings, multiple matching, note completion, cause \u0026 effect, sequencing", "pathway": "2 ways to source the passage", "pathways_available": ["Generate Passage: provide a topic, AI writes a passage at the target CEFR level", "Paste Your Text: bring your own article/text, AI auto-detects level and topic"], "presets_available": ["Quick Comprehension (all levels)", "Cambridge Style (B1+)", "IELTS Style (B1+)", "Comprehensive (B1+)", "Deep Analysis (B1+)"], "scope": "Any topic, any of 7 text styles, 3 length presets, 5 reading presets, fully custom exercise mix", "text_styles": "7 styles \u2014 article, story, email, letter, dialogue, report, blog post"}, "product_slug": "reading", "subtitle": "AI-generated article on a contemporary topic, with a full comprehension set.", "title": "Urban Farming in Southeast Asia", "type_label": "Comprehension", "whats_inside": ["5 sections, 30 items", "5 distinct exercise types showcased: multiple choice, true false, short answer, cause effect, note completion"]}, {"accent_hex": "#E11D48", "composer_url": "/writing-composer", "config_used": {"Components": "Prompt \u00b7 Planning checklist \u00b7 Useful language \u00b7 Criteria \u00b7 Model answer", "Level": "B2", "Task type": "Formal Letter", "Topic": "Opposing the closure of the neighbourhood library"}, "files": {"answers_docx": "/static/samples/04_writing_b2/answers.docx", "answers_pdf": "/static/samples/04_writing_b2/answers.pdf", "material_docx": "/static/samples/04_writing_b2/material.docx", "material_pdf": "/static/samples/04_writing_b2/material.pdf", "thumbnail": "/static/samples/thumbnails/04_writing_b2.png"}, "id": "writing-b2", "level": "B2", "preview_pages": {"answers": ["/static/samples/04_writing_b2/preview/answers-1.png", "/static/samples/04_writing_b2/preview/answers-2.png"], "material": ["/static/samples/04_writing_b2/preview/material-1.png", "/static/samples/04_writing_b2/preview/material-2.png", "/static/samples/04_writing_b2/preview/material-3.png"]}, "product": "Writing", "product_breadth": {"components_toggleable": ["Planning checklist (on/off)", "Useful language box (on/off)", "Model answer (on/off)", "Assessment criteria (always on)"], "pathway": "Single-call generation \u2014 task type + topic, AI produces every component in one shot", "pathways_available": ["Choose a task type, set a topic, generate."], "presets_available": ["Cambridge mode (B1+, non-story types) \u2014 turns on every component and sets four-criteria assessment", "Custom mode \u2014 choose which components to include, and the criteria style"], "scope": "8 task types across A1\u2013C2 with level-appropriate gating", "task_types_available": "8 task types \u2014 Essay (B1+), Informal Letter (all), Formal Letter (B1+), Report (B1+), Proposal (C1+), Review (A2+), Article (B1+), Story (all)"}, "product_slug": "writing", "subtitle": "Complete writing task package, generated in a single LLM call.", "title": "Library Closure \u2014 Formal Letter", "type_label": "Task", "whats_inside": ["Formal Letter task at B2", "Writing prompt with a full scenario, not a one-line title"]}, {"accent_hex": "#0891B2", "composer_url": "/listening-composer", "config_used": {"Exercise types": "6 (multiple_choice, true_false, gap_fill, note_completion, matching, sentence_completion)", "Level": "C1", "Library item": "C1:conversation:0"}, "files": {"answers_docx": "/static/samples/05_listening_c1/answers.docx", "answers_pdf": "/static/samples/05_listening_c1/answers.pdf", "audio_mp3": "/static/samples/05_listening_c1/audio.mp3", "material_docx": "/static/samples/05_listening_c1/material.docx", "material_pdf": "/static/samples/05_listening_c1/material.pdf", "script_pdf": "/static/samples/05_listening_c1/script.pdf", "thumbnail": "/static/samples/thumbnails/05_listening_c1.png"}, "id": "listening-c1", "level": "C1", "preview_pages": {"answers": ["/static/samples/05_listening_c1/preview/answers-1.png", "/static/samples/05_listening_c1/preview/answers-2.png", "/static/samples/05_listening_c1/preview/answers-3.png", "/static/samples/05_listening_c1/preview/answers-4.png"], "material": ["/static/samples/05_listening_c1/preview/material-1.png", "/static/samples/05_listening_c1/preview/material-2.png", "/static/samples/05_listening_c1/preview/material-3.png", "/static/samples/05_listening_c1/preview/material-4.png", "/static/samples/05_listening_c1/preview/material-5.png"]}, "product": "Listening", "product_breadth": {"exercise_types_available": "8 types \u2014 multiple choice, true/false, gap fill, short answer, sentence completion, note completion, matching, classification", "library_scope": "335 audio scripts across A1\u2013C2 in 7 formats: conversation, interview, lecture, monologue, news report, phone call, announcement", "pathway": "Library-based \u2014 pick a pre-generated script + audio, AI generates fresh exercises on demand", "pathways_available": ["Browse the library (free), pick a script, configure exercises."], "presets_available": ["Quick Listen (all levels)", "IELTS Listening (B1+, speakers students can tell apart, not interviews or phone calls)", "Cambridge Listening (B1+)", "Comprehensive (B1+, conversations)", "Detail Focus (B1+)"], "scope": "Browse library free, generate exercises on credit"}, "product_slug": "listening", "subtitle": "Pre-recorded three-speaker 
1902conversation from the library, with a full comprehension set.", "title": "Colleagues Debate AI Hiring Ethics", "type_label": "Set", "whats_inside": ["6 sections, 30 items", "6 distinct exercise types showcased: multiple choice, true false, gap fill, note completion, matching, sentence completion"]}, {"accent_hex": "#9333EA", "composer_url": "/exam-composer", "config_used": {"Domains": "Reading \u00b7 Writing \u00b7 Exam-only (Multiple-choice Cloze, Open Cloze, Word Formation, Key Word Transformation, Gapped Text)", "Preset": "Cambridge B2 First (FCE)", "Time": "155 minutes", "Total marks": "110"}, "files": {"answers_docx": "/static/samples/06_exam_fce_b2/answers.docx", "answers_pdf": "/static/samples/06_exam_fce_b2/answers.pdf", "material_docx": "/static/samples/06_exam_fce_b2/material.docx", "material_pdf": "/static/samples/06_exam_fce_b2/material.pdf", "thumbnail": "/static/samples/thumbnails/06_exam_fce_b2.png"}, "id": "exam-fce-b2", "level": "B2", "preview_pages": {"answers": ["/static/samples/06_exam_fce_b2/preview/answers-1.png", "/static/samples/06_exam_fce_b2/preview/answers-2.png", "/static/samples/06_exam_fce_b2/preview/answers-3.png", "/static/samples/06_exam_fce_b2/preview/answers-4.png", "/static/samples/06_exam_fce_b2/preview/answers-5.png", "/static/samples/06_exam_fce_b2/preview/answers-6.png", "/static/samples/06_exam_fce_b2/preview/answers-7.png", "/static/samples/06_exam_fce_b2/preview/answers-8.png", "/static/samples/06_exam_fce_b2/preview/answers-9.png", "/static/samples/06_exam_fce_b2/preview/answers-10.png", "/static/samples/06_exam_fce_b2/preview/answers-11.png", "/static/samples/06_exam_fce_b2/preview/answers-12.png", "/static/samples/06_exam_fce_b2/preview/answers-13.png"], "material": ["/static/samples/06_exam_fce_b2/preview/material-1.png", "/static/samples/06_exam_fce_b2/preview/material-2.png", "/static/samples/06_exam_fce_b2/preview/material-3.png", "/static/samples/06_exam_fce_b2/preview/material-4.png", "/static/samples/06_exam_fce_b2/preview/material-5.png", "/static/samples/06_exam_fce_b2/preview/material-6.png", "/static/samples/06_exam_fce_b2/preview/material-7.png", "/static/samples/06_exam_fce_b2/preview/material-8.png", "/static/samples/06_exam_fce_b2/preview/material-9.png", "/static/samples/06_exam_fce_b2/preview/material-10.png", "/static/samples/06_exam_fce_b2/preview/material-11.png", "/static/samples/06_exam_fce_b2/preview/material-12.png", "/static/samples/06_exam_fce_b2/preview/material-13.png", "/static/samples/06_exam_fce_b2/preview/material-14.png", "/static/samples/06_exam_fce_b2/preview/material-15.png", "/static/samples/06_exam_fce_b2/preview/material-16.png", "/static/samples/06_exam_fce_b2/preview/material-17.png", "/static/samples/06_exam_fce_b2/preview/material-18.png", "/static/samples/06_exam_fce_b2/preview/material-19.png", "/static/samples/06_exam_fce_b2/preview/material-20.png", "/static/samples/06_exam_fce_b2/preview/material-21.png", "/static/samples/06_exam_fce_b2/preview/material-22.png"]}, "product": "Exam", "product_breadth": {"exam_only_types": "6 types not available in standalone products \u2014 Multiple-choice Cloze (B2+), Open Cloze (B2+), Word Formation (B2+), Key Word Transformation (B2+), Gapped Text (B2+), Cross-text Multiple Matching (C1 only)", "pathway": "Multi-domain composer \u2014 wrap any combination of standalone products into one cohesive exam", "pathways_available": ["Pick a preset and tweak, or build a fully custom exam from scratch."], "presets_available": ["Cambridge B2 First (FCE) \u2014 the Reading \u0026 Use of English and Writing papers, part by part", "Cambridge C1 Advanced (CAE) \u2014 the Reading \u0026 Use of English and Writing papers, part by part", "Grammar \u0026 Vocab Quiz \u2014 short multi-domain knowledge check", "Grammar Focus \u2014 in-depth grammar-only exam", "Comprehensive Assessment \u2014 balanced multi-domain test"], "scope": "Combines all 5 standalone products + 6 exam-only types. Domains can be reordered. Per-section marks customizable. Header (teacher name, time, instructions) fully editable."}, "product_slug": "exam", "subtitle": "Full multi-domain exam paper combining grammar, reading, writing, and Cambridge-style exam-only sections.", "title": "Cambridge B2 First Practice", "type_label": "Exam Paper", "whats_inside": ["3 domains, 110 marks, 155-minute paper", "Use of English: multiple-choice cloze (8 items), open cloze (8 items), word formation (8 items), key word transformation (6 items), gapped text (6 items) \u2014 48 marks, exam-only types", "Reading: 2 texts, 2 task types (16 items, 22 marks)", "Writing: Essay, then a choice of 3 tasks drawn from Article, Formal Letter, Review, Report \u2014 40 marks", "Parts print in the official order; detailed answer key"]}, {"accent_hex": "#7C3AED", "composer_url": "/exam-composer", "config_used": {"Domains": "Reading \u00b7 Writing \u00b7 Exam-only (Multiple-choice Cloze, Open Cloze, Word Formation, Key Word Transformation, Cross-text Multiple Matching, Gapped Text)", "Preset": "Cambridge C1 Advanced (CAE)", "Time": "180 minutes", "Total marks": "118"}
1902, "files": {"answers_docx": "/static/samples/07_exam_cae_c1/answers.docx", "answers_pdf": "/static/samples/07_exam_cae_c1/answers.pdf", "material_docx": "/static/samples/07_exam_cae_c1/material.docx", "material_pdf": "/static/samples/07_exam_cae_c1/material.pdf", "thumbnail": "/static/samples/thumbnails/07_exam_cae_c1.png"}, "id": "exam-cae-c1", "level": "C1", "preview_pages": {"answers": ["/static/samples/07_exam_cae_c1/preview/answers-1.png", "/static/samples/07_exam_cae_c1/preview/answers-2.png", "/static/samples/07_exam_cae_c1/preview/answers-3.png", "/static/samples/07_exam_cae_c1/preview/answers-4.png", "/static/samples/07_exam_cae_c1/preview/answers-5.png", "/static/samples/07_exam_cae_c1/preview/answers-6.png", "/static/samples/07_exam_cae_c1/preview/answers-7.png", "/static/samples/07_exam_cae_c1/preview/answers-8.png", "/static/samples/07_exam_cae_c1/preview/answers-9.png", "/static/samples/07_exam_cae_c1/preview/answers-10.png", "/static/samples/07_exam_cae_c1/preview/answers-11.png", "/static/samples/07_exam_cae_c1/preview/answers-12.png", "/static/samples/07_exam_cae_c1/preview/answers-13.png", "/static/samples/07_exam_cae_c1/preview/answers-14.png", "/static/samples/07_exam_cae_c1/preview/answers-15.png"], "material": ["/static/samples/07_exam_cae_c1/preview/material-1.png", "/static/samples/07_exam_cae_c1/preview/material-2.png", "/static/samples/07_exam_cae_c1/preview/material-3.png", "/static/samples/07_exam_cae_c1/preview/material-4.png", "/static/samples/07_exam_cae_c1/preview/material-5.png", "/static/samples/07_exam_cae_c1/preview/material-6.png", "/static/samples/07_exam_cae_c1/preview/material-7.png", "/static/samples/07_exam_cae_c1/preview/material-8.png", "/static/samples/07_exam_cae_c1/preview/material-9.png", "/static/samples/07_exam_cae_c1/preview/material-10.png", "/static/samples/07_exam_cae_c1/preview/material-11.png", "/static/samples/07_exam_cae_c1/preview/material-12.png", "/static/samples/07_exam_cae_c1/preview/material-13.png", "/static/samples/07_exam_cae_c1/preview/material-14.png", "/static/samples/07_exam_cae_c1/preview/material-15.png", "/static/samples/07_exam_cae_c1/preview/material-16.png", "/static/samples/07_exam_cae_c1/preview/material-17.png", "/static/samples/07_exam_cae_c1/preview/material-18.png", "/static/samples/07_exam_cae_c1/preview/material-19.png", "/static/samples/07_exam_cae_c1/preview/material-20.png", "/static/samples/07_exam_cae_c1/preview/material-21.png", "/static/samples/07_exam_cae_c1/preview/material-22.png", "/static/samples/07_exam_cae_c1/preview/material-23.png", "/static/samples/07_exam_cae_c1/preview/material-24.png", "/static/samples/07_exam_cae_c1/preview/material-25.png", "/static/samples/07_exam_cae_c1/preview/material-26.png"]}, "product": "Exam", "product_breadth": {"exam_only_types": "6 types not available in standalone products \u2014 Multiple-choice Cloze (B2+), Open Cloze (B2+), Word Formation (B2+), Key Word Transformation (B2+), Gapped Text (B2+), Cross-text Multiple Matching (C1 only)", "pathway": "Multi-domain composer \u2014 wrap any combination of standalone products into one cohesive exam", "pathways_available": ["Pick a preset and tweak, or build a fully custom exam from scratch."], "presets_available": ["Cambridge B2 First (FCE) \u2014 the Reading \u0026 Use of English and Writing papers, part by part", "Cambridge C1 Advanced (CAE) \u2014 the Reading \u0026 Use of English and Writing papers, part by part", "Grammar \u0026 Vocab Quiz \u2014 short multi-domain knowledge check", "Grammar Focus \u2014 in-depth grammar-only exam", "Comprehensive Assessment \u2014 balanced multi-domain test"], "scope": "Any mix of the 5 standalone products, at any level from A1 to C2."}, "product_slug": "exam", "subtitle": "The C1 paper: longer reading, a report task, and 220-260 word limits.", "title": "Cambridge C1 Advanced Practice", "type_label": "Exam Paper", "whats_inside": ["3 domains, 118 marks, 180-minute paper", "Use of English: multiple-choice cloze (8 items), open cloze (8 items), word formation (8 items), key word transformation (6 items), cross-text multiple matching (4 items), gapped text (6 items) \u2014 56 marks, exam-only types", "Reading: 2 texts, 2 task types (16 items, 22 marks)", "Writing: Essay, then a choice of 3 tasks drawn from Formal Letter, Proposal, Report, Review \u2014 40 marks", "Parts print in the official order; detailed answer key"]}],
1903
1904    openPreview(id) {
1905      const found = this.samples.find(s => s.id === id);
1906      if (!found) return;
1907      this.currentSample = found;
1908      this.view = 'material';
1909      this.open = true;
1910    },
1911
1912    closePreview() {
1913      this.open = false;
1914      tfRestoreFocus();
1915      // Delay clearing the sample so the closing transition can finish
1916      setTimeout(() => { this.currentSample = null; }, 200);
1917    },
1918  };
1919}
1920</script>
1920
1921
1922
1923    </main>
1924
1925    
1926    <footer class="border-t border-[var(--color-border)] bg-[var(--color-bg-card)] mt-auto">
1927        <div class="mx-auto max-w-6xl px-6 py-5">
1928            <div class="flex flex-col items-center justify-between gap-4 sm:flex-row">
1929                <p class="text-sm text-[var(--color-text-muted)]">&copy; 2026 TeacherForge. All rights reserved.</p>
1930                <div class="flex flex-col items-center gap-3 sm:items-end">
1931                    
1932                    <div class="flex flex-wrap justify-center gap-x-5 gap-y-2 text-sm text-[var(--color-text-muted)] sm:justify-end">
1933                        <a href="/terms" class="whitespace-nowrap hover:text-[var(--color-text)]">Terms</a>
1934                        <a href="/privacy" class="whitespace-nowrap hover:text-[var(--color-text)]">Privacy</a>
1935                        <a href="#" data-u="support" data-d="teacherforge.io" class="whitespace-nowrap hover:text-[var(--color-text)]">Contact</a>
1936                    </div>
1937                </div>
1938            </div>
1939        </div>
1940    </footer>
1941    
1942
1943    <!-- HTMX + Alpine.js -->
1944    
1944<script src="/static/js/htmx.min.js" defer></script>
1944
1945    
1945<script src="/static/js/alpine.min.js" defer></script>
1945
1946    <!-- Lemon Squeezy checkout overlay -->
1947    
1947<script src="https://app.lemonsqueezy.com/js/lemon.js" defer></script>
1947
1948    
1948<script>document.addEventListener('DOMContentLoaded', function(){ if(window.createLemonSqueezy) window.createLemonSqueezy(); });</script>
1948
1949
1950    <!-- Modal focus handling — no Alpine focus plugin is loaded, so these two helpers
1951         are what keep Tab inside an open dialog and hand focus back when it closes. -->
1952    
1952<script>
1953    function tfFocusFirst(el) {
1954        if (!el) return;
1955        window.__tfLastFocus = document.activeElement;
1956        requestAnimationFrame(function () {
1957            var f = el.querySelector('[autofocus]') || tfFocusables(el)[0];
1958            if (f) f.focus();
1959        });
1960    }
1961    function tfFocusables(el) {
1962        return Array.prototype.slice.call(el.querySelectorAll(
1963            'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])'
1964        )).filter(function (e) { return e.offsetWidth > 0 || e.offsetHeight > 0; });
1965    }
1966    function tfTrapTab(event, el) {
1967        var f = tfFocusables(el);
1968        if (!f.length) return;
1969        var first = f[0], last = f[f.length - 1];
1970        if (event.shiftKey && document.activeElement === first) {
1971            event.preventDefault(); last.focus();
1972        } else if (!event.shiftKey && document.activeElement === last) {
1973            event.preventDefault(); first.focus();
1974        }
1975    }
1976    function tfRestoreFocus() {
1977        if (window.__tfLastFocus && window.__tfLastFocus.focus) window.__tfLastFocus.focus();
1978        window.__tfLastFocus = null;
1979    }
1980    </script>
1980
1981
1982    <!-- Email decoder -->
1983    
1983<script>
1984    document.addEventListener("DOMContentLoaded",function(){
1985        document.querySelectorAll("a[data-u][data-d]").forEach(function(a){var e=a.dataset.u+"@"+a.dataset.d;a.href="mailto:"+e;if(a.dataset.show!==undefined||!a.textContent.trim())a.textContent=e});
1986    });
1987    </script>
1987
1988
1989    
1990
1991    <!-- Toast container -->
1992    <div id="tf-toast" style="display:none" role="status" aria-live="polite" class="fixed bottom-6 left-1/2 -translate-x-1/2 z-[9999] max-w-sm px-5 py-3 rounded-xl shadow-lg border text-sm font-medium transition-all duration-300 opacity-0 translate-y-2"></div>
1993
1994    <!-- Lemon Squeezy checkout handler -->
1995    
1995<script>
1996    function tfToast(msg, type) {
1997        var t = document.getElementById('tf-toast');
1998        t.textContent = msg;
1999        t.className = 'fixed bottom-6 left-1/2 -translate-x-1/2 z-[9999] max-w-sm px-5 py-3 rounded-xl shadow-lg border text-sm font-medium transition-all duration-300';
2000        if (type === 'error') {
2001            t.style.background = 'var(--color-error-light)';
2002            t.style.borderColor = 'var(--color-error-border)';
2003            t.style.color = 'var(--color-error)';
2004        } else {
2005            t.style.background = 'var(--color-success-light)';
2006            t.style.borderColor = 'var(--color-success)';
2007            t.style.color = 'var(--color-success)';
2008        }
2009        t.style.display = 'block';
2010        requestAnimationFrame(function(){ t.classList.remove('opacity-0','translate-y-2'); });
2011        clearTimeout(t._timer);
2012        t._timer = setTimeout(function(){
2013            t.classList.add('opacity-0','translate-y-2');
2014            setTimeout(function(){ t.style.display = 'none'; }, 300);
2015        }, 4000);
2016    }
2017    document.addEventListener('tf-checkout', async function(e) {
2018        var btn = e.target;
2019        if (btn && btn.disabled) return;
2020        if (btn) btn.disabled = true;
2021        try {
2022            var res = await fetch('/api/payments/checkout', {
2023                method: 'POST',
2024                headers: {'Content-Type': 'application/json'},
2025                body: JSON.stringify({plan: e.detail.plan})
2026            });
2027            if (!res.ok) {
2028                var data = await res.json().catch(function(){return {}});
2029                tfToast(data.error || 'Could not start checkout. Please try again.', 'error');
2030                return;
2031            }
2032            var result = await res.json();
2033            if (window.LemonSqueezy) {
2034                window.LemonSqueezy.Url.Open(result.checkout_url);
2035            } else {
2036                window.location.href = result.checkout_url;
2037            }
2038        } finally {
2039            if (btn) btn.disabled = false;
2040        }
2041    });
2042    </script>
2042
2043
2044    <!-- Theme toggle -->
2045    
2045<script>
2046    function tfToggleTheme(){
2047        var isDark=document.documentElement.getAttribute('data-theme')==='teacherforge-dark';
2048        var next=isDark?'teacherforge':'teacherforge-dark';
2049        document.documentElement.setAttribute('data-theme',next);
2050        localStorage.setItem('tf-theme',isDark?'light':'dark');
2051        tfUpdateThemeIcons();
2052    }
2053    function tfUpdateThemeIcons(){
2054        var isDark=document.documentElement.getAttribute('data-theme')==='teacherforge-dark';
2055        document.querySelectorAll('.dark-icon').forEach(function(el){el.style.display=isDark?'none':'block'});
2056        document.querySelectorAll('.light-icon').forEach(function(el){el.style.display=isDark?'block':'none'});
2057    }
2058    document.addEventListener('DOMContentLoaded',tfUpdateThemeIcons);
2059    </script>
2059
2060
2061    
2062</body>
2063</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.