File size: 34,759 Bytes
4691cfc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e6a6189
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Substrate Math Translation Simulator v0.1</title>
<style>
:root{
  --bg:#07090d;--panel:#0f1420;--panel2:#121a2a;--ink:#eef5ff;--muted:#a9b6cc;--line:#263347;
  --green:#49d17c;--yellow:#ffd166;--orange:#ff9f43;--red:#ff5c7a;--blue:#65b8ff;--violet:#a78bfa;--cyan:#58e6d9;
  --shadow:0 18px 60px rgba(0,0,0,.35);
}
*{box-sizing:border-box}
body{
  margin:0;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:var(--ink);
  background:
    radial-gradient(circle at 10% 10%,rgba(101,184,255,.16),transparent 28%),
    radial-gradient(circle at 86% 12%,rgba(167,139,250,.14),transparent 30%),
    radial-gradient(circle at 50% 105%,rgba(88,230,217,.08),transparent 42%),
    var(--bg);
}
header{
  padding:28px 24px 18px;border-bottom:1px solid var(--line);
  background:linear-gradient(180deg,rgba(18,26,42,.94),rgba(7,9,13,.72));
  position:sticky;top:0;z-index:20;backdrop-filter:blur(12px);
}
.wrap{max-width:1480px;margin:0 auto}
h1{margin:0 0 6px;font-size:clamp(24px,3vw,42px);letter-spacing:-.04em}
.subtitle{color:var(--muted);font-size:15px;line-height:1.45;max-width:1120px}
.tagrow{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px}
.tag{border:1px solid var(--line);background:rgba(255,255,255,.04);color:#dbeafe;padding:6px 9px;border-radius:999px;font-size:12px}
main{padding:22px 24px 34px}
.grid{display:grid;grid-template-columns:390px minmax(0,1fr) 420px;gap:18px;align-items:start}
.panel{
  background:linear-gradient(180deg,rgba(18,26,42,.96),rgba(15,20,32,.96));
  border:1px solid var(--line);border-radius:20px;box-shadow:var(--shadow);overflow:hidden;
}
.panel h2{margin:0;padding:16px 18px;border-bottom:1px solid var(--line);font-size:16px;letter-spacing:-.02em}
.body{padding:16px 18px}
label{display:block;font-size:12px;color:var(--muted);margin-bottom:8px}
select,button,textarea,input[type=text]{
  width:100%;border:1px solid var(--line);background:#0a0f19;color:var(--ink);border-radius:12px;padding:11px 12px;font-size:14px;outline:none;
}
textarea{min-height:105px;resize:vertical;line-height:1.4}
button{cursor:pointer;transition:.18s ease transform,.18s ease border-color,.18s ease background;font-weight:800}
button:hover{transform:translateY(-1px);border-color:#46658f;background:#0c1422}
button.primary{background:linear-gradient(135deg,#1f6feb,#5b8cff);border-color:#65b8ff}
button.good{background:linear-gradient(135deg,#116e43,#24a861);border-color:#49d17c}
button.warn{background:linear-gradient(135deg,#865b0b,#b98200);border-color:#ffd166}
.controls{display:grid;gap:14px}
.sliderRow{border:1px solid var(--line);border-radius:16px;padding:12px;background:rgba(255,255,255,.03)}
.sliderTop{display:flex;justify-content:space-between;gap:8px;align-items:center;margin-bottom:8px}
.sliderTop strong{font-size:13px}
.val{font-variant-numeric:tabular-nums;color:#dbeafe;font-size:12px}
input[type=range]{width:100%;accent-color:#65b8ff}
.hint{font-size:12px;color:var(--muted);line-height:1.35;margin-top:6px}
.buttons{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.metricGrid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:18px}
.metric{background:rgba(255,255,255,.035);border:1px solid var(--line);border-radius:18px;padding:14px;min-height:104px}
.metric .name{font-size:12px;color:var(--muted)}
.metric .num{font-size:22px;font-weight:900;margin:4px 0;letter-spacing:-.03em;line-height:1.05}
.metric .desc{font-size:12px;color:var(--muted);line-height:1.35}
.output{display:grid;gap:14px}
.card{border:1px solid var(--line);border-radius:18px;background:rgba(255,255,255,.035);padding:14px}
.card h3{margin:0 0 8px;font-size:15px}
.card p{margin:0 0 10px;color:#dce8f7;line-height:1.48}
.card ul{margin:8px 0 0 20px;color:#dce8f7;line-height:1.45;padding:0}
.card li{margin:4px 0}
.small{font-size:12px;color:var(--muted);line-height:1.35}
.eq{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;background:#080d15;border:1px solid var(--line);border-radius:18px;
  padding:14px;color:#d8f3ff;margin-bottom:18px;line-height:1.55;overflow:auto;
}
.blue{color:var(--blue)}.green{color:var(--green)}.yellow{color:var(--yellow)}.orange{color:var(--orange)}.red{color:var(--red)}.violet{color:var(--violet)}.cyan{color:var(--cyan)}
#mathCanvas{width:100%;height:180px;border:1px solid var(--line);border-radius:16px;background:#0a0f19;display:block}
.log{max-height:560px;overflow:auto;display:flex;flex-direction:column;gap:9px;padding-right:4px}
.logItem{border:1px solid var(--line);border-radius:14px;padding:10px 11px;background:rgba(255,255,255,.035)}
.logItem .time{font-size:11px;color:#8190a8;margin-bottom:5px}
.logItem .msg{font-size:12px;line-height:1.35;color:#dce8f7}
.footerNote{margin:18px auto 0;color:var(--muted);line-height:1.45;font-size:13px;border:1px solid var(--line);background:rgba(255,255,255,.03);border-radius:18px;padding:14px}
.descBox{font-size:12px;color:var(--muted);line-height:1.35;border:1px solid var(--line);border-radius:14px;padding:10px;background:rgba(255,255,255,.03);min-height:54px;margin-top:8px}
.previewBox{border:1px solid var(--line);border-radius:16px;padding:12px;background:rgba(255,255,255,.03)}
hr{border:0;border-top:1px solid var(--line);margin:10px 0}
@media(max-width:1240px){.grid{grid-template-columns:1fr}header{position:static}.metricGrid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:760px){.metricGrid{grid-template-columns:1fr}.buttons{grid-template-columns:1fr}}
</style>
</head>
<body>
<header>
  <div class="wrap">
    <h1>Substrate Math Translation Simulator <span class="blue">v0.1</span></h1>
    <div class="subtitle">
      A non-diagnostic learning translator that explains math concepts through different cognition styles.
      Select a math topic, choose an explanation route, tune support preferences, and generate a dignity-preserving explanation.
      <br><strong>Math stays math. The route changes so the learner can meet the structure.</strong>
    </div>
    <div class="tagrow">
      <span class="tag">Math translation, not replacement</span>
      <span class="tag">Cognition-aware learning</span>
      <span class="tag">No diagnosis</span>
      <span class="tag">No forced closure</span>
      <span class="tag">Substrate education layer</span>
    </div>
  </div>
</header>

<main>
<div class="wrap grid">
  <section class="panel">
    <h2>Learning Input</h2>
    <div class="body controls">
      <div>
        <label for="topic">Math topic</label>
        <select id="topic"></select>
        <div id="topicDesc" class="descBox"></div>
      </div>

      <div>
        <label for="mode">Cognition / explanation mode</label>
        <select id="mode"></select>
        <div id="modeDesc" class="descBox"></div>
      </div>

      <div>
        <label for="selfDesc">Optional learner note</label>
        <textarea id="selfDesc" placeholder="Example: I need visual structure before symbols. I understand math through real examples. I need proof boundaries and misconception checks."></textarea>
        <div class="hint">Self-described support only. This is not diagnosis or assessment.</div>
      </div>

      <div class="sliderRow">
        <div class="sliderTop"><strong>Abstraction Tolerance</strong><span class="val" id="vAbs"></span></div>
        <input id="abstraction" type="range" min="0" max="1" step="0.01" value="0.50">
        <div class="hint">Lower = concrete first. Higher = structure/symbols first.</div>
      </div>

      <div class="sliderRow">
        <div class="sliderTop"><strong>Example Need</strong><span class="val" id="vEx"></span></div>
        <input id="examples" type="range" min="0" max="1" step="0.01" value="0.78">
        <div class="hint">How much the explanation should lean on examples and worked cases.</div>
      </div>

      <div class="sliderRow">
        <div class="sliderTop"><strong>Symbol Density</strong><span class="val" id="vSym"></span></div>
        <input id="symbols" type="range" min="0" max="1" step="0.01" value="0.46">
        <div class="hint">Controls how much equation/symbol language appears.</div>
      </div>

      <div class="sliderRow">
        <div class="sliderTop"><strong>Metaphor Density</strong><span class="val" id="vMet"></span></div>
        <input id="metaphor" type="range" min="0" max="1" step="0.01" value="0.58">
        <div class="hint">Controls analogy, imagery, and story language.</div>
      </div>

      <div class="sliderRow">
        <div class="sliderTop"><strong>Pacing / Scaffold</strong><span class="val" id="vPace"></span></div>
        <input id="pacing" type="range" min="0" max="1" step="0.01" value="0.74">
        <div class="hint">Higher = slower sequencing and more definitions.</div>
      </div>

      <div class="buttons">
        <button class="primary" id="generateBtn">Generate Math Translation</button>
        <button id="randomBtn">Try Sample Learner</button>
      </div>

      <div class="buttons">
        <button class="good" id="exportJSON">Export JSON</button>
        <button class="warn" id="copyBtn">Copy Output</button>
      </div>
    </div>
  </section>

  <section>
    <div class="metricGrid">
      <div class="metric">
        <div class="name">Learning Accessibility</div>
        <div class="num" id="accessScore">0.00</div>
        <div class="desc">How well supports match the chosen cognition route.</div>
      </div>
      <div class="metric">
        <div class="name">Understanding Layer</div>
        <div class="num" id="closureState">FIRST PASS</div>
        <div class="desc">Whether the output targets intuition, working model, or formal layer.</div>
      </div>
      <div class="metric">
        <div class="name">Translation Route</div>
        <div class="num" id="routeName"></div>
        <div class="desc">The cognitive route used for this explanation.</div>
      </div>
    </div>

    <div class="eq">
      <div><strong>Math translation pressure form:</strong></div>
      <div>S_learning,t = A_translation,t × B_math,t − P_mismatch,t</div>
      <div><strong>Rule:</strong> preserve the mathematical structure, adapt the explanation route.</div>
      <hr>
      <div id="liveEq"></div>
      <div id="formulaLine" style="margin-top:8px;color:#eef5ff"></div>
    </div>

    <div class="panel" style="margin-bottom:18px">
      <h2>Math Structure Field</h2>
      <div class="body">
        <canvas id="mathCanvas" width="760" height="200"></canvas>
        <div class="hint" style="text-align:center;margin-top:10px">
          Concept = structure · Symbols = compressed map · Translation = route into understanding.
        </div>
      </div>
    </div>

    <div class="panel">
      <h2>Generated Math Explanation</h2>
      <div class="body output" id="output"></div>
    </div>

    <div class="footerNote">
      <strong>Boundary statement:</strong> This simulator is an educational translation prototype. It does not replace teachers,
      textbooks, practice, formal proof, or mathematical rigor. It does not diagnose cognition or rank intelligence.
      It adapts explanation format while preserving the math concept and its boundaries.
    </div>
  </section>

  <aside class="panel">
    <h2>Learning Steward Log</h2>
    <div class="body">
      <div class="previewBox" style="margin-bottom:12px">
        <div class="small"><strong>Steward function:</strong> preserve the concept, translate the route, mark misconceptions, and prevent confusion from being treated as failure.</div>
      </div>
      <div class="log" id="log"></div>
    </div>
  </aside>
</div>
</main>

<footer class="footerNote wrap">
  <strong>Substrate education principle:</strong> A learner should not be made to feel stupid because the explanation arrives in the wrong format.
  The format should adapt while the mathematical structure remains honest.
</footer>

<script>
const modes = {
  visual_map:{label:"Visual / map-based",route:"VISUAL_MAP",desc:"Prefers diagrams, number lines, shapes, graphs, arrows, and spatial relationships.",bias:{abstraction:.55,examples:.72,symbols:.36,metaphor:.70,pacing:.64}},
  concrete_examples:{label:"Concrete examples first",route:"CONCRETE_EXAMPLES",desc:"Prefers worked examples and ordinary-life situations before symbols.",bias:{abstraction:.26,examples:.95,symbols:.25,metaphor:.50,pacing:.82}},
  technical_symbolic:{label:"Technical / symbolic",route:"TECHNICAL_SYMBOLIC",desc:"Prefers notation, definitions, formulas, transformations, and formal relationships.",bias:{abstraction:.88,examples:.44,symbols:.94,metaphor:.18,pacing:.46}},
  story_metaphor:{label:"Story / metaphor",route:"STORY_METAPHOR",desc:"Prefers analogies, image-rich explanations, and narrative movement.",bias:{abstraction:.46,examples:.70,symbols:.22,metaphor:.94,pacing:.70}},
  stepwise_literal:{label:"Stepwise / literal",route:"STEPWISE_LITERAL",desc:"Prefers definitions, slow sequencing, one operation at a time, and low ambiguity.",bias:{abstraction:.32,examples:.84,symbols:.46,metaphor:.16,pacing:.96}},
  fast_associative:{label:"Fast associative / pattern-jump",route:"FAST_ASSOCIATIVE",desc:"Prefers pattern links across topics and seeing the full structure quickly.",bias:{abstraction:.78,examples:.60,symbols:.58,metaphor:.82,pacing:.28}},
  skeptical_redteam:{label:"Skeptical / red-team",route:"SKEPTICAL_REDTEAM",desc:"Prefers assumptions, edge cases, invalid moves, proof boundaries, and misconception checks.",bias:{abstraction:.66,examples:.64,symbols:.64,metaphor:.20,pacing:.60}},
  lived_context:{label:"Lived-context / practical stakes",route:"LIVED_CONTEXT",desc:"Prefers practical use, money/time/measurement examples, agency, and why the concept matters.",bias:{abstraction:.40,examples:.90,symbols:.30,metaphor:.68,pacing:.80}},
  teacher_scaffold:{label:"Teacher / scaffolded lesson",route:"TEACHER_SCAFFOLD",desc:"Prefers learning objective, definitions, examples, guided practice, and takeaway.",bias:{abstraction:.48,examples:.86,symbols:.48,metaphor:.42,pacing:.90}}
};

const topics = {
  arithmetic:{
    label:"Arithmetic operations",
    desc:"How addition, subtraction, multiplication, and division transform quantities.",
    formula:"a + b, a − b, a × b, a ÷ b",
    plain:"Arithmetic is the basic language of changing and comparing quantities.",
    example:"If you have 3 groups of 4 apples, multiplication says 3 × 4 = 12 apples.",
    misconception:"Multiplication is not always just 'making bigger' once negative numbers, fractions, and scaling enter."
  },
  fractions:{
    label:"Fractions and ratios",
    desc:"How parts, wholes, and comparisons are represented.",
    formula:"a/b ; ratio a:b ; proportion a/b = c/d",
    plain:"A fraction compares a part to a whole, and a ratio compares quantities to each other.",
    example:"If 3 out of 8 slices are eaten, 3/8 of the pizza is gone.",
    misconception:"A larger denominator does not always mean a larger value. 1/8 is smaller than 1/4."
  },
  algebra:{
    label:"Algebra",
    desc:"How symbols represent unknowns, relationships, and reusable patterns.",
    formula:"ax + b = c",
    plain:"Algebra uses symbols to hold places for numbers so relationships can be solved or reused.",
    example:"If x + 3 = 10, then x = 7 because 7 plus 3 gives 10.",
    misconception:"The letter is not the math. The letter is a placeholder for a value or variable relationship."
  },
  functions:{
    label:"Functions",
    desc:"How inputs map to outputs according to a rule.",
    formula:"f(x) = y",
    plain:"A function is a rule that takes an input and produces an output.",
    example:"If f(x)=2x+1, then f(3)=7 because 2×3+1=7.",
    misconception:"A function is not just an equation; it is a mapping rule from inputs to outputs."
  },
  geometry:{
    label:"Geometry",
    desc:"How shape, space, length, area, angle, and structure relate.",
    formula:"A_rectangle = l × w ; a² + b² = c²",
    plain:"Geometry studies spatial relationships: shapes, distances, areas, angles, and how they fit together.",
    example:"A rectangle that is 5 units long and 3 units wide has area 15 square units.",
    misconception:"Area and perimeter are not the same. Perimeter measures boundary length; area measures covered space."
  },
  graphing:{
    label:"Graphing",
    desc:"How visual coordinate maps show relationships between quantities.",
    formula:"y = mx + b",
    plain:"A graph turns a relationship into a visual map. The x-axis tracks input, and the y-axis tracks output.",
    example:"In y=2x+1, every time x increases by 1, y increases by 2.",
    misconception:"A graph is not decoration. It is a structured visual form of the relationship."
  },
  probability:{
    label:"Probability",
    desc:"How uncertainty, likelihood, and outcomes are measured.",
    formula:"P(event) = favorable outcomes / total possible outcomes",
    plain:"Probability measures how likely an event is under a defined set of possible outcomes.",
    example:"A fair coin has probability 1/2 of landing heads on a single flip.",
    misconception:"Unlikely does not mean impossible. Likely does not mean guaranteed."
  },
  statistics:{
    label:"Statistics",
    desc:"How data, variation, averages, spread, and inference are handled.",
    formula:"mean = sum of values / number of values",
    plain:"Statistics helps summarize data and reason about variation without pretending the variation vanished.",
    example:"The average of 2, 4, and 9 is 5 because (2+4+9)/3 = 5.",
    misconception:"An average can hide important spread. Two groups can have the same mean but very different distributions."
  },
  calculus:{
    label:"Calculus basics",
    desc:"How change and accumulation are modeled.",
    formula:"derivative ≈ rate of change ; integral ≈ accumulated total",
    plain:"Calculus studies how quantities change and how small pieces add up into totals.",
    example:"Speed is a rate of change of position; distance traveled can be accumulated from speed over time.",
    misconception:"Calculus is not just hard algebra. It is a language for change, accumulation, and limits."
  },
  linear_algebra:{
    label:"Linear algebra basics",
    desc:"How vectors, matrices, transformations, and systems are represented.",
    formula:"A x = b",
    plain:"Linear algebra studies structured relationships among many quantities at once using vectors and matrices.",
    example:"A matrix can rotate, stretch, or combine coordinates in a controlled way.",
    misconception:"A matrix is not just a grid of numbers. It can represent a transformation or a system of relationships."
  }
};

const ids=["abstraction","examples","symbols","metaphor","pacing"];
const els=Object.fromEntries(ids.map(id=>[id,document.getElementById(id)]));
let lastRecord=null, logRecords=[], phase=0;

function fmt(n){return Number(n).toFixed(2)}
function iso(){return new Date().toISOString()}
function now(){return new Date().toLocaleTimeString([], {hour:"2-digit",minute:"2-digit",second:"2-digit"})}

function initSelects(){
  const topicSel=document.getElementById("topic");
  Object.entries(topics).forEach(([k,t])=>{
    const opt=document.createElement("option"); opt.value=k; opt.textContent=t.label; opt.title=t.desc; topicSel.appendChild(opt);
  });
  topicSel.value="algebra";
  const modeSel=document.getElementById("mode");
  Object.entries(modes).forEach(([k,m])=>{
    const opt=document.createElement("option"); opt.value=k; opt.textContent=m.label; opt.title=m.desc; modeSel.appendChild(opt);
  });
  modeSel.value="visual_map";
  updateDescriptions();
}
function updateDescriptions(){
  const t=topics[document.getElementById("topic").value];
  const m=modes[document.getElementById("mode").value];
  document.getElementById("topicDesc").textContent=t.desc;
  document.getElementById("modeDesc").textContent=m.desc;
}
function updateLabels(){
  document.getElementById("vAbs").textContent=fmt(els.abstraction.value);
  document.getElementById("vEx").textContent=fmt(els.examples.value);
  document.getElementById("vSym").textContent=fmt(els.symbols.value);
  document.getElementById("vMet").textContent=fmt(els.metaphor.value);
  document.getElementById("vPace").textContent=fmt(els.pacing.value);
}
function getState(){
  const topic=document.getElementById("topic").value;
  const mode=document.getElementById("mode").value;
  return {
    topic, topicLabel:topics[topic].label,
    mode, modeLabel:modes[mode].label,
    learnerNote:document.getElementById("selfDesc").value.trim(),
    abstraction:parseFloat(els.abstraction.value),
    examples:parseFloat(els.examples.value),
    symbols:parseFloat(els.symbols.value),
    metaphor:parseFloat(els.metaphor.value),
    pacing:parseFloat(els.pacing.value)
  };
}
function score(s){
  const b=modes[s.mode].bias;
  let dist=0; ids.forEach(k=>dist+=Math.abs(s[k]-b[k]));
  const match=Math.max(0,1-dist/5);
  const A_translation=match;
  const B_math=.89; // stable concept substrate, not learner rank
  const P_mismatch=(1-match)*.62;
  const S=(A_translation*B_math)-P_mismatch;
  return {match,A_translation,B_math,P_mismatch,S};
}
function layer(S){
  if(S>.63)return ["FORMAL_READY","FORMAL + INTUITIVE"];
  if(S>.44)return ["WORKING_MODEL","WORKING MODEL"];
  if(S>.22)return ["FIRST_PASS","FIRST PASS"];
  return ["OPEN_LOOP","NEEDS RETRANSLATION"];
}
function addLog(msg){
  const item=document.createElement("div"); item.className="logItem";
  const t=now();
  item.innerHTML=`<div class="time">${t}</div><div class="msg">${msg}</div>`;
  document.getElementById("log").prepend(item);
  logRecords.push({timestamp:iso(),displayTime:t,message:msg});
}
function generate(){
  const s=getState(), t=topics[s.topic], m=modes[s.mode], sc=score(s), [closure, layerName]=layer(sc.S);
  document.getElementById("accessScore").textContent=fmt(sc.match);
  document.getElementById("accessScore").style.color=sc.match>.75?"var(--green)":sc.match>.55?"var(--yellow)":"var(--orange)";
  document.getElementById("closureState").textContent=layerName;
  document.getElementById("closureState").style.color=layerName.includes("FORMAL")?"var(--green)":layerName==="WORKING MODEL"?"var(--yellow)":"var(--orange)";
  document.getElementById("routeName").textContent=m.route;
  document.getElementById("routeName").style.color="var(--blue)";
  document.getElementById("liveEq").innerHTML=`S_learning,t = (${fmt(sc.A_translation)} × ${fmt(sc.B_math)}) − ${fmt(sc.P_mismatch)} ≈ <strong>${fmt(sc.S)}</strong>`;
  document.getElementById("formulaLine").innerHTML=`Topic structure: <strong>${t.formula}</strong>`;
  const out=buildOutput(s,t,m,sc,layerName);
  renderOutput(out);
  lastRecord={metadata:{title:"Substrate Math Translation Simulator",version:"v0.1",timestamp:iso(),boundary:"Educational translation prototype; not diagnosis or replacement for formal instruction."},state:s,metrics:sc,understandingLayer:layerName,output:out};
  addLog(`Generated ${t.label} through ${m.route}: ${layerName}. Math structure preserved; route adapted.`);
  draw();
}
function buildOutput(s,t,m,sc,layerName){
  return {
    topic:t.label, mode:m.label, route:m.route, understandingLayer:layerName,
    sections:[
      {title:"1. Main idea", text:modeIntro(s,t)},
      {title:"2. Mathematical structure", text:structureText(s,t)},
      {title:"3. How to picture it", text:pictureText(s,t)},
      {title:"4. Worked example / entry point", text:exampleText(s,t)},
      {title:"5. Misconception guardrail", text:guardrailText(s,t)},
      {title:"6. Check-for-understanding", text:checkText(s,t)},
      {title:"7. Closure boundary", text:closureText(layerName)}
    ],
    supports:supports(s,sc)
  };
}
function modeIntro(s,t){
  const map={
    visual_map:`Map it visually: the concept is the center node, the symbols are the compressed structure, the example is the path into the map, and the misconception is the boundary marker. For ${t.label}, the map starts here: ${t.plain}`,
    concrete_examples:`Start with the example: ${t.example} From there, the math idea is: ${t.plain}`,
    technical_symbolic:`Formal read: ${t.formula}. The concept is ${t.label}. Plain interpretation: ${t.plain}`,
    story_metaphor:`Imagine the math as a machine that preserves relationships. For ${t.label}, the machine does this: ${t.plain}`,
    stepwise_literal:`Step 1: the topic is ${t.label}. Step 2: the core structure is ${t.formula}. Step 3: the meaning is: ${t.plain}`,
    fast_associative:`Pattern bridge: ${t.label} links structure, symbol, example, operation, graph, and proof boundary. Core: ${t.plain}`,
    skeptical_redteam:`Bounded claim: this is a first-pass model of ${t.label}, not the entire field. The structure ${t.formula} is useful inside its assumptions. Core: ${t.plain}`,
    lived_context:`Human-scale read: ${t.label} matters because it helps people measure, compare, plan, build, check claims, and avoid being fooled by bad numbers. Core: ${t.plain}`,
    teacher_scaffold:`Learning objective: explain ${t.label} in plain language and connect it to ${t.formula}. Main idea: ${t.plain}`
  };
  return map[s.mode];
}
function structureText(s,t){
  let text=`The key structure is ${t.formula}. `;
  if(s.symbols>.65) text+=`Read the symbols as compressed meaning: each symbol holds a role, and each operation changes the relationship according to rules. `;
  else text+=`You do not have to start by manipulating symbols. First, treat the expression as a sentence about relationships. `;
  if(s.pacing>.72) text+=`Name the parts, identify what is known, identify what is unknown, then apply one rule at a time.`;
  return text;
}
function pictureText(s,t){
  if(s.mode==="visual_map") return `Draw ${t.label} as a map. Put the known quantities on one side, the unknown or target on the other, and the rule as the bridge between them.`;
  if(s.mode==="story_metaphor") return `Picture ${t.label} as a transformation story: something enters, a rule acts on it, and a relationship is preserved or revealed.`;
  if(s.mode==="technical_symbolic") return `Picture it as a rule-governed structure. The notation is not decoration; it encodes allowed moves and dependencies.`;
  if(s.mode==="stepwise_literal") return `Picture one move at a time: define, substitute, simplify, check. Do not combine steps until the prior step is clear.`;
  return `Picture the relationship first, then attach the symbols. The picture prevents the notation from floating without meaning.`;
}
function exampleText(s,t){
  let text=t.example;
  if(s.examples>.72) text+=` Ask: what is given, what is being asked, what relationship connects them, and what would count as a correct answer?`;
  if(s.metaphor>.72) text+=` The example is a bridge, not the whole territory: use it to enter the structure, then return to the math.`;
  return text;
}
function guardrailText(s,t){
  let text=t.misconception;
  if(s.mode==="skeptical_redteam") text+=` Red-team rule: every move must preserve equality, definition, or stated assumption.`;
  if(s.pacing>.72) text+=` This is where the loop should stay open until the distinction is clear.`;
  return text;
}
function checkText(s,t){
  const checks={
    arithmetic:"Can you explain why multiplication can mean repeated groups, scaling, or area depending on context?",
    fractions:"Which is larger, 1/4 or 1/8, and how can you see it without only using rules?",
    algebra:"In x + 3 = 10, what operation undoes +3 and why does it preserve the equation?",
    functions:"If f(x)=2x+1, what input gives output 9?",
    geometry:"How are perimeter and area different for the same rectangle?",
    graphing:"In y=2x+1, what does the 2 do to the graph?",
    probability:"Does a 1/6 chance mean an event must happen exactly once every six trials?",
    statistics:"Why can an average hide important differences in a dataset?",
    calculus:"What is the difference between rate of change and accumulated total?",
    linear_algebra:"Why can a matrix be more than a table of numbers?"
  };
  return checks[s.topic] || "Can you explain the concept without using the formal notation first?";
}
function closureText(layerName){
  if(layerName.includes("FORMAL")) return "This translation can close at both the first-pass and working-model layers. Formal proof and practice still remain open for deeper validation.";
  if(layerName==="WORKING MODEL") return "This translation can close as a working model. Keep formal proof, edge cases, and independent practice open.";
  if(layerName==="FIRST PASS") return "This translation can close as a first-pass explanation. Keep examples, symbol manipulation, and proof boundaries open.";
  return "This loop should remain open. The explanation route needs retranslation before claiming understanding.";
}
function supports(s,sc){
  const arr=[];
  if(s.examples>.65) arr.push("Use a worked example before symbolic manipulation.");
  if(s.pacing>.70) arr.push("Define each symbol and operation before combining steps.");
  if(s.symbols>.60) arr.push("Show notation, allowed moves, and assumptions.");
  if(s.metaphor>.65) arr.push("Use analogy, but mark where the analogy stops.");
  if(s.abstraction>.70) arr.push("Give the general structure before the example.");
  if(sc.P_mismatch>.25) arr.push("Mismatch pressure remains: do not force closure; try another route.");
  arr.push("Confusion is not failure. It is a signal that the route into the structure may need adjustment.");
  return arr;
}
function renderOutput(o){
  const box=document.getElementById("output"); box.innerHTML="";
  const head=document.createElement("div"); head.className="card";
  head.innerHTML=`<h3>${o.topic} via <span class="blue">${o.route}</span></h3>
  <p><strong>Selected mode:</strong> ${o.mode}</p>
  <p><strong>Understanding layer:</strong> ${o.understandingLayer}. This is an explanation route, not a learner diagnosis.</p>`;
  box.appendChild(head);
  o.sections.forEach(sec=>{
    const div=document.createElement("div"); div.className="card";
    div.innerHTML=`<h3>${sec.title}</h3><p>${sec.text}</p>`;
    box.appendChild(div);
  });
  const sup=document.createElement("div"); sup.className="card";
  sup.innerHTML=`<h3>Recommended supports</h3><ul>${o.supports.map(x=>`<li>${x}</li>`).join("")}</ul>`;
  box.appendChild(sup);
}
function copyOutput(){
  if(!lastRecord)generate();
  const lines=[];
  lines.push("Substrate Math Translation Simulator v0.1");
  lines.push(`Topic: ${lastRecord.output.topic}`);
  lines.push(`Mode: ${lastRecord.output.mode}`);
  lines.push(`Route: ${lastRecord.output.route}`);
  lines.push(`Understanding layer: ${lastRecord.output.understandingLayer}`);
  lines.push("");
  lastRecord.output.sections.forEach(s=>{lines.push(s.title);lines.push(s.text);lines.push("");});
  lines.push("Recommended supports:");
  lastRecord.output.supports.forEach(x=>lines.push("- "+x));
  navigator.clipboard.writeText(lines.join("\n")).then(()=>addLog("Copied generated math translation to clipboard."));
}
function exportJSON(){
  if(!lastRecord)generate();
  const data={...lastRecord, steward_log:logRecords};
  const blob=new Blob([JSON.stringify(data,null,2)],{type:"application/json"});
  const url=URL.createObjectURL(blob);
  const a=document.createElement("a"); a.href=url; a.download=`substrate-math-translation-${Date.now()}.json`;
  document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url);
}
function trySample(){
  const modeKeys=Object.keys(modes), topicKeys=Object.keys(topics);
  const mk=modeKeys[Math.floor(Math.random()*modeKeys.length)];
  const tk=topicKeys[Math.floor(Math.random()*topicKeys.length)];
  document.getElementById("mode").value=mk; document.getElementById("topic").value=tk;
  const b=modes[mk].bias; ids.forEach(id=>els[id].value=b[id]);
  const samples=[
    "I need the picture before the symbols.",
    "I trust the formula when I know what each symbol is allowed to do.",
    "Examples first, then the rule.",
    "I see patterns quickly and want the full map.",
    "Please slow it down and define each move before combining them."
  ];
  document.getElementById("selfDesc").value=samples[Math.floor(Math.random()*samples.length)];
  updateLabels(); updateDescriptions(); generate();
}
function draw(){
  const c=document.getElementById("mathCanvas"), ctx=c.getContext("2d"), w=c.width,h=c.height;
  const s=getState(), sc=score(s), t=topics[s.topic];
  phase+=.035;
  ctx.clearRect(0,0,w,h);
  const bg=ctx.createLinearGradient(0,0,w,h); bg.addColorStop(0,"#080d15"); bg.addColorStop(1,"#0f1420"); ctx.fillStyle=bg; ctx.fillRect(0,0,w,h);
  const color=sc.S>.63?"#49d17c":sc.S>.44?"#ffd166":sc.S>.22?"#ff9f43":"#ff5c7a";
  const yMid=h*.56, amp=10+(1-sc.match)*42;
  for(let layer=0;layer<4;layer++){
    ctx.beginPath();
    for(let x=0;x<=w;x+=5){
      const y=yMid+Math.sin((x+phase*90+layer*25)/(45-layer*4))*(amp*(1-layer*.14));
      if(x===0)ctx.moveTo(x,y); else ctx.lineTo(x,y);
    }
    ctx.strokeStyle=layer===0?color:`rgba(101,184,255,${.12+layer*.05})`;
    ctx.lineWidth=layer===0?2.8:1.2; ctx.stroke();
  }
  const nodes=["concept","symbols","example","rule","guardrail","check","closure"];
  nodes.forEach((n,i)=>{
    const x=58+i*(w-116)/(nodes.length-1);
    const y=yMid+Math.sin((x+phase*90)/45)*amp;
    ctx.beginPath(); ctx.arc(x,y,6+s.examples*3,0,Math.PI*2);
    ctx.fillStyle=`rgba(88,230,217,${.28+s.pacing*.34})`; ctx.fill();
    ctx.strokeStyle=color; ctx.lineWidth=1.5; ctx.stroke();
    ctx.fillStyle="rgba(238,245,255,.72)"; ctx.font="11px ui-monospace,monospace"; ctx.textAlign="center"; ctx.fillText(n,x,y-14);
  });
  ctx.fillStyle="rgba(238,245,255,.84)"; ctx.font="12px ui-monospace,monospace"; ctx.textAlign="center";
  ctx.fillText(`${t.label}: ${t.formula}`,w/2,32);
  ctx.fillText(`S_learning ≈ ${fmt(sc.S)} · route match ${fmt(sc.match)}`,w/2,52);
}
function loop(){draw();requestAnimationFrame(loop);}

ids.forEach(id=>els[id].addEventListener("input",()=>{updateLabels();generate();}));
document.getElementById("topic").addEventListener("change",()=>{updateDescriptions();generate();});
document.getElementById("mode").addEventListener("change",()=>{updateDescriptions();generate();});
document.getElementById("generateBtn").addEventListener("click",generate);
document.getElementById("randomBtn").addEventListener("click",trySample);
document.getElementById("copyBtn").addEventListener("click",copyOutput);
document.getElementById("exportJSON").addEventListener("click",exportJSON);

initSelects(); updateLabels();
addLog("Simulator initialized. Math structure preserved; cognition route adapted.");
generate(); loop();
</script>
</body>
</html>