aznatkoiny commited on
Commit
f0eb505
·
verified ·
1 Parent(s): 4e2b7fd

Launch accounting-facing CFO HRM demo

Browse files

Public static Space with the EIL5 guide front and center, browser-side ONNX inference, fictional reconciliation cases, and explicit human-review controls.

Files changed (8) hide show
  1. EIL5.md +327 -0
  2. README.md +360 -6
  3. SHA256SUMS +1 -0
  4. app.js +490 -0
  5. demo_cases.json +3901 -0
  6. index.html +326 -17
  7. model/cfo_hrm.onnx +3 -0
  8. style.css +2128 -18
EIL5.md ADDED
@@ -0,0 +1,327 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Training Specialized HRMs, Explained Like You Are Five
2
+
3
+ Think of an HRM as a child learning to solve little boxes of accounting
4
+ puzzles.
5
+
6
+ Each training example is one box containing:
7
+
8
+ 1. The puzzle pieces.
9
+ 2. The rules for which pieces may fit together.
10
+ 3. The correct answer.
11
+ 4. Any special reason the puzzle needs adult review.
12
+
13
+ The HRM studies thousands of solved boxes and learns how to solve new ones.
14
+
15
+ ## The basic dataset shape
16
+
17
+ Do not think of the dataset as one enormous spreadsheet where every row is
18
+ unrelated. It should be a collection of complete cases:
19
+
20
+ ```text
21
+ Case 1
22
+ ├── Company and accounting period
23
+ ├── Input records
24
+ ├── Possible relationships
25
+ └── Correct answer
26
+
27
+ Case 2
28
+ ├── Company and accounting period
29
+ ├── Input records
30
+ ├── Possible relationships
31
+ └── Correct answer
32
+ ```
33
+
34
+ In our bank-reconciliation model, one case looks like:
35
+
36
+ ```text
37
+ Input:
38
+ 20 bank transactions
39
+ 19 general-ledger entries
40
+
41
+ Correct answer:
42
+ Bank row 1 → GL row 8
43
+ Bank row 2 → GL row 3
44
+ Bank row 3 → unmatched bank fee
45
+ ...
46
+ ```
47
+
48
+ The entire group is one example because the model must reason globally: two
49
+ bank transactions cannot both consume the same GL entry.
50
+
51
+ ## Example: accounts-payable matching
52
+
53
+ Suppose we want an HRM that performs invoice-to-purchase-order matching.
54
+
55
+ A human-readable training example could look like this:
56
+
57
+ ```json
58
+ {
59
+ "case_id": "AP-2025-0042",
60
+ "as_of_date": "2025-10-31",
61
+ "context": {
62
+ "company": "COMPANY_A",
63
+ "currency": "USD"
64
+ },
65
+ "inputs": {
66
+ "invoice": {
67
+ "invoice_id": "INV-104",
68
+ "vendor": "VENDOR_17",
69
+ "invoice_date": "2025-10-14",
70
+ "total_cents": 125000,
71
+ "description": "Office chairs"
72
+ },
73
+ "purchase_orders": [
74
+ {
75
+ "po_id": "PO-88",
76
+ "vendor": "VENDOR_17",
77
+ "total_cents": 125000,
78
+ "description": "20 office chairs"
79
+ },
80
+ {
81
+ "po_id": "PO-91",
82
+ "vendor": "VENDOR_17",
83
+ "total_cents": 140000,
84
+ "description": "Office desks"
85
+ }
86
+ ],
87
+ "receipts": [
88
+ {
89
+ "receipt_id": "REC-31",
90
+ "po_id": "PO-88",
91
+ "quantity_received": 20
92
+ }
93
+ ]
94
+ },
95
+ "answer": {
96
+ "purchase_order": "PO-88",
97
+ "receipts": ["REC-31"],
98
+ "disposition": "MATCH",
99
+ "exception": "NONE"
100
+ }
101
+ }
102
+ ```
103
+
104
+ That example teaches the model:
105
+
106
+ > Invoice `INV-104` belongs to `PO-88` and receipt `REC-31`.
107
+
108
+ An exception example might instead say:
109
+
110
+ ```json
111
+ {
112
+ "answer": {
113
+ "purchase_order": "PO-88",
114
+ "receipts": ["REC-31"],
115
+ "disposition": "REVIEW",
116
+ "exception": "PRICE_VARIANCE"
117
+ }
118
+ }
119
+ ```
120
+
121
+ Now it learns both matching and exception handling.
122
+
123
+ ## What the model actually sees
124
+
125
+ The data adapter turns the readable records into arrays:
126
+
127
+ ```text
128
+ Invoice features:
129
+ amount, date, vendor, currency, description
130
+
131
+ PO features:
132
+ amount, date, vendor, currency, description
133
+
134
+ Candidate mask:
135
+ PO-88 is allowed
136
+ PO-91 is allowed
137
+ unrelated-company POs are forbidden
138
+
139
+ Answer:
140
+ correct candidate index = PO-88
141
+ exception class = NONE
142
+ ```
143
+
144
+ In tensor terms:
145
+
146
+ ```text
147
+ input rows [cases, maximum rows, features]
148
+ candidate mask [cases, invoice rows, PO rows]
149
+ match targets [cases, invoice rows]
150
+ exception target [cases, invoice rows]
151
+ padding masks [cases, maximum rows]
152
+ ```
153
+
154
+ Padding lets one case contain 10 records and another contain 20 while still
155
+ fitting into fixed-size batches.
156
+
157
+ ## Examples for other CFO specialists
158
+
159
+ | Specialist | Puzzle pieces | Correct answer |
160
+ | --- | --- | --- |
161
+ | AP matching | Invoices, PO lines, receipts | Which records match and why review is needed |
162
+ | Intercompany | Due-to and due-from entries | Correct counterparty pairs and elimination group |
163
+ | Journal review | Journal lines, accounts, policy context | Accept, review, or reject; violated control |
164
+ | Expense audit | Expense, receipt, employee, policy | Valid, duplicate, missing receipt, policy violation |
165
+ | Close management | Tasks, dependencies, status, owners | Next task, correct order, blocker category |
166
+ | Revenue recognition | Contract, invoice, delivery, obligations | Allocation and recognition schedule |
167
+ | Variance analysis | Actuals, budget, operational drivers | Driver classification and materiality |
168
+ | Cash forecasting | Historical and scheduled cash flows | Future cash balances and uncertainty bands |
169
+
170
+ HRMs are especially attractive when there are several related records,
171
+ multi-step reasoning, global constraints, and an answer you can objectively
172
+ check.
173
+
174
+ For ordinary forecasting, traditional time-series and regression baselines may
175
+ still be better. An HRM should have to beat those baselines.
176
+
177
+ ## How to create a new specialist
178
+
179
+ ### 1. Define the puzzle
180
+
181
+ Write down exactly:
182
+
183
+ ```text
184
+ What information is available before the decision?
185
+ What answer should the model produce?
186
+ What rules must never be violated?
187
+ When should it abstain and ask a human?
188
+ ```
189
+
190
+ If you cannot define the correct answer precisely, you cannot train the model
191
+ reliably.
192
+
193
+ ### 2. Find trustworthy answers
194
+
195
+ Good labels come from:
196
+
197
+ - approved reconciliations;
198
+ - finalized invoice matches;
199
+ - controller-reviewed journal decisions;
200
+ - completed close workflows;
201
+ - resolved exceptions; or
202
+ - carefully generated synthetic cases.
203
+
204
+ Avoid using unreviewed historical decisions as truth. Historical accounting
205
+ records can contain mistakes.
206
+
207
+ ### 3. Separate inputs from answers
208
+
209
+ Never accidentally show the model the answer inside its input.
210
+
211
+ For example, do not give it:
212
+
213
+ ```json
214
+ {
215
+ "matched_po_id": "PO-88"
216
+ }
217
+ ```
218
+
219
+ as an input when `PO-88` is the answer.
220
+
221
+ Other dangerous leakage fields include:
222
+
223
+ - final reconciliation status;
224
+ - approval timestamp;
225
+ - payment created from the matched invoice;
226
+ - exception resolution code;
227
+ - downstream journal-entry ID; and
228
+ - fields populated only after review.
229
+
230
+ ### 4. Include difficult and rare cases
231
+
232
+ A useful dataset needs more than ordinary matches:
233
+
234
+ ```text
235
+ Exact matches
236
+ Small amount differences
237
+ Date differences
238
+ Missing references
239
+ Duplicate invoices
240
+ Partial receipts
241
+ Split payments
242
+ Aggregated payments
243
+ Currency differences
244
+ Reversals
245
+ Wrong entities
246
+ Unmatched records
247
+ Policy exceptions
248
+ Ambiguous cases requiring review
249
+ ```
250
+
251
+ If the model never sees duplicate invoices during training, it will not
252
+ magically understand duplicate invoices later.
253
+
254
+ ### 5. Split by time
255
+
256
+ A safe split looks like:
257
+
258
+ ```text
259
+ Train: January 2023 – June 2025
260
+ Validation: July 2025 – September 2025
261
+ Test: October 2025 – December 2025
262
+ ```
263
+
264
+ Do not randomly put almost-identical records from the same transaction into
265
+ both training and testing. That lets the model memorize instead of reason.
266
+
267
+ For an even harder test, hold out an entire company, vendor group, or accounting
268
+ system.
269
+
270
+ ### 6. Build an adapter and output head
271
+
272
+ You usually cannot point our current model at a new CSV and expect it to work.
273
+
274
+ The existing model has outputs specifically designed for:
275
+
276
+ - bank-to-GL pair scores;
277
+ - unmatched scores; and
278
+ - six reconciliation exception classes.
279
+
280
+ For AP matching, we could reuse much of the architecture and replace the row
281
+ types and exception classes.
282
+
283
+ For close planning, we would need a different output head that predicts next
284
+ actions or task order.
285
+
286
+ For forecasting, we would need a numerical prediction head and a different
287
+ loss function.
288
+
289
+ ## A practical folder format
290
+
291
+ A clean specialist dataset could use:
292
+
293
+ ```text
294
+ ap-matching/
295
+ ├── schema.json
296
+ ├── train.jsonl
297
+ ├── validation.jsonl
298
+ ├── test.jsonl
299
+ └── manifest.json
300
+ ```
301
+
302
+ Each line in `train.jsonl` is one complete case, not one invoice row.
303
+
304
+ The manifest records:
305
+
306
+ ```json
307
+ {
308
+ "dataset_version": "1.0",
309
+ "created_at": "2026-07-23",
310
+ "source_system": "anonymized-read-only-export",
311
+ "train_period": ["2023-01", "2025-06"],
312
+ "validation_period": ["2025-07", "2025-09"],
313
+ "test_period": ["2025-10", "2025-12"],
314
+ "currencies": ["USD"],
315
+ "label_method": "controller-approved final disposition"
316
+ }
317
+ ```
318
+
319
+ The simplest rule is:
320
+
321
+ > One example should contain everything needed to solve one complete accounting
322
+ > puzzle, followed by an answer key created from a trustworthy outcome.
323
+
324
+ For multiple specialists, give each HRM its own dataset and answer type. Then
325
+ connect their proposals through the typed Go control layer instead of mixing AP,
326
+ forecasting, reconciliation, and close-management records into one
327
+ undifferentiated training file.
README.md CHANGED
@@ -1,10 +1,364 @@
1
  ---
2
- title: Cfo Hrm Accounting Lab
3
- emoji: 😻
4
- colorFrom: purple
5
- colorTo: indigo
6
  sdk: static
7
- pinned: false
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: CFO HRM · Reconciliation Review
3
+ emoji: 🧾
4
+ colorFrom: gray
5
+ colorTo: yellow
6
  sdk: static
7
+ app_file: index.html
8
+ short_description: Bank reconciliation reasoning for accounting teams
9
  ---
10
 
11
+ # Training Specialized HRMs, Explained Like You Are Five
12
+
13
+ This is a working bank-reconciliation demonstration for accounting teams. It
14
+ runs a browser-ready ONNX export of the
15
+ [released CFO-HRM checkpoint](https://huggingface.co/aznatkoiny/cfo-hrm), not a
16
+ scripted mock-up, against fictional accounting cases. The calculation happens
17
+ inside your browser: records are not uploaded or processed by a server. It
18
+ produces proposals for a person to review. It cannot post a journal entry, move
19
+ money, approve a reconciliation, or make an autonomous financial decision.
20
+
21
+ [MODEL + RESULTS](https://huggingface.co/aznatkoiny/cfo-hrm) ·
22
+ [SOURCE + CONTROLS](https://github.com/Aznatkoiny/cfo-hrm)
23
+
24
+ Think of an HRM as a child learning to solve little boxes of accounting
25
+ puzzles.
26
+
27
+ Each training example is one box containing:
28
+
29
+ 1. The puzzle pieces.
30
+ 2. The rules for which pieces may fit together.
31
+ 3. The correct answer.
32
+ 4. Any special reason the puzzle needs adult review.
33
+
34
+ The HRM studies thousands of solved boxes and learns how to solve new ones.
35
+
36
+ ## The basic dataset shape
37
+
38
+ Do not think of the dataset as one enormous spreadsheet where every row is
39
+ unrelated. It should be a collection of complete cases:
40
+
41
+ ```text
42
+ Case 1
43
+ ├── Company and accounting period
44
+ ├── Input records
45
+ ├── Possible relationships
46
+ └── Correct answer
47
+
48
+ Case 2
49
+ ├── Company and accounting period
50
+ ├── Input records
51
+ ├── Possible relationships
52
+ └── Correct answer
53
+ ```
54
+
55
+ In our bank-reconciliation model, one case looks like:
56
+
57
+ ```text
58
+ Input:
59
+ 20 bank transactions
60
+ 19 general-ledger entries
61
+
62
+ Correct answer:
63
+ Bank row 1 → GL row 8
64
+ Bank row 2 → GL row 3
65
+ Bank row 3 → unmatched bank fee
66
+ ...
67
+ ```
68
+
69
+ The entire group is one example because the model must reason globally: two
70
+ bank transactions cannot both consume the same GL entry.
71
+
72
+ ## Example: accounts-payable matching
73
+
74
+ Suppose we want an HRM that performs invoice-to-purchase-order matching.
75
+
76
+ A human-readable training example could look like this:
77
+
78
+ ```json
79
+ {
80
+ "case_id": "AP-2025-0042",
81
+ "as_of_date": "2025-10-31",
82
+ "context": {
83
+ "company": "COMPANY_A",
84
+ "currency": "USD"
85
+ },
86
+ "inputs": {
87
+ "invoice": {
88
+ "invoice_id": "INV-104",
89
+ "vendor": "VENDOR_17",
90
+ "invoice_date": "2025-10-14",
91
+ "total_cents": 125000,
92
+ "description": "Office chairs"
93
+ },
94
+ "purchase_orders": [
95
+ {
96
+ "po_id": "PO-88",
97
+ "vendor": "VENDOR_17",
98
+ "total_cents": 125000,
99
+ "description": "20 office chairs"
100
+ },
101
+ {
102
+ "po_id": "PO-91",
103
+ "vendor": "VENDOR_17",
104
+ "total_cents": 140000,
105
+ "description": "Office desks"
106
+ }
107
+ ],
108
+ "receipts": [
109
+ {
110
+ "receipt_id": "REC-31",
111
+ "po_id": "PO-88",
112
+ "quantity_received": 20
113
+ }
114
+ ]
115
+ },
116
+ "answer": {
117
+ "purchase_order": "PO-88",
118
+ "receipts": ["REC-31"],
119
+ "disposition": "MATCH",
120
+ "exception": "NONE"
121
+ }
122
+ }
123
+ ```
124
+
125
+ That example teaches the model:
126
+
127
+ > Invoice `INV-104` belongs to `PO-88` and receipt `REC-31`.
128
+
129
+ An exception example might instead say:
130
+
131
+ ```json
132
+ {
133
+ "answer": {
134
+ "purchase_order": "PO-88",
135
+ "receipts": ["REC-31"],
136
+ "disposition": "REVIEW",
137
+ "exception": "PRICE_VARIANCE"
138
+ }
139
+ }
140
+ ```
141
+
142
+ Now it learns both matching and exception handling.
143
+
144
+ ## What the model actually sees
145
+
146
+ The data adapter turns the readable records into arrays:
147
+
148
+ ```text
149
+ Invoice features:
150
+ amount, date, vendor, currency, description
151
+
152
+ PO features:
153
+ amount, date, vendor, currency, description
154
+
155
+ Candidate mask:
156
+ PO-88 is allowed
157
+ PO-91 is allowed
158
+ unrelated-company POs are forbidden
159
+
160
+ Answer:
161
+ correct candidate index = PO-88
162
+ exception class = NONE
163
+ ```
164
+
165
+ In tensor terms:
166
+
167
+ ```text
168
+ input rows [cases, maximum rows, features]
169
+ candidate mask [cases, invoice rows, PO rows]
170
+ match targets [cases, invoice rows]
171
+ exception target [cases, invoice rows]
172
+ padding masks [cases, maximum rows]
173
+ ```
174
+
175
+ Padding lets one case contain 10 records and another contain 20 while still
176
+ fitting into fixed-size batches.
177
+
178
+ ## Examples for other CFO specialists
179
+
180
+ | Specialist | Puzzle pieces | Correct answer |
181
+ | --- | --- | --- |
182
+ | AP matching | Invoices, PO lines, receipts | Which records match and why review is needed |
183
+ | Intercompany | Due-to and due-from entries | Correct counterparty pairs and elimination group |
184
+ | Journal review | Journal lines, accounts, policy context | Accept, review, or reject; violated control |
185
+ | Expense audit | Expense, receipt, employee, policy | Valid, duplicate, missing receipt, policy violation |
186
+ | Close management | Tasks, dependencies, status, owners | Next task, correct order, blocker category |
187
+ | Revenue recognition | Contract, invoice, delivery, obligations | Allocation and recognition schedule |
188
+ | Variance analysis | Actuals, budget, operational drivers | Driver classification and materiality |
189
+ | Cash forecasting | Historical and scheduled cash flows | Future cash balances and uncertainty bands |
190
+
191
+ HRMs are especially attractive when there are several related records,
192
+ multi-step reasoning, global constraints, and an answer you can objectively
193
+ check.
194
+
195
+ For ordinary forecasting, traditional time-series and regression baselines may
196
+ still be better. An HRM should have to beat those baselines.
197
+
198
+ ## How to create a new specialist
199
+
200
+ ### 1. Define the puzzle
201
+
202
+ Write down exactly:
203
+
204
+ ```text
205
+ What information is available before the decision?
206
+ What answer should the model produce?
207
+ What rules must never be violated?
208
+ When should it abstain and ask a human?
209
+ ```
210
+
211
+ If you cannot define the correct answer precisely, you cannot train the model
212
+ reliably.
213
+
214
+ ### 2. Find trustworthy answers
215
+
216
+ Good labels come from:
217
+
218
+ - approved reconciliations;
219
+ - finalized invoice matches;
220
+ - controller-reviewed journal decisions;
221
+ - completed close workflows;
222
+ - resolved exceptions; or
223
+ - carefully generated synthetic cases.
224
+
225
+ Avoid using unreviewed historical decisions as truth. Historical accounting
226
+ records can contain mistakes.
227
+
228
+ ### 3. Separate inputs from answers
229
+
230
+ Never accidentally show the model the answer inside its input.
231
+
232
+ For example, do not give it:
233
+
234
+ ```json
235
+ {
236
+ "matched_po_id": "PO-88"
237
+ }
238
+ ```
239
+
240
+ as an input when `PO-88` is the answer.
241
+
242
+ Other dangerous leakage fields include:
243
+
244
+ - final reconciliation status;
245
+ - approval timestamp;
246
+ - payment created from the matched invoice;
247
+ - exception resolution code;
248
+ - downstream journal-entry ID; and
249
+ - fields populated only after review.
250
+
251
+ ### 4. Include difficult and rare cases
252
+
253
+ A useful dataset needs more than ordinary matches:
254
+
255
+ ```text
256
+ Exact matches
257
+ Small amount differences
258
+ Date differences
259
+ Missing references
260
+ Duplicate invoices
261
+ Partial receipts
262
+ Split payments
263
+ Aggregated payments
264
+ Currency differences
265
+ Reversals
266
+ Wrong entities
267
+ Unmatched records
268
+ Policy exceptions
269
+ Ambiguous cases requiring review
270
+ ```
271
+
272
+ If the model never sees duplicate invoices during training, it will not
273
+ magically understand duplicate invoices later.
274
+
275
+ ### 5. Split by time
276
+
277
+ A safe split looks like:
278
+
279
+ ```text
280
+ Train: January 2023 – June 2025
281
+ Validation: July 2025 – September 2025
282
+ Test: October 2025 – December 2025
283
+ ```
284
+
285
+ Do not randomly put almost-identical records from the same transaction into
286
+ both training and testing. That lets the model memorize instead of reason.
287
+
288
+ For an even harder test, hold out an entire company, vendor group, or accounting
289
+ system.
290
+
291
+ ### 6. Build an adapter and output head
292
+
293
+ You usually cannot point our current model at a new CSV and expect it to work.
294
+
295
+ The existing model has outputs specifically designed for:
296
+
297
+ - bank-to-GL pair scores;
298
+ - unmatched scores; and
299
+ - six reconciliation exception classes.
300
+
301
+ For AP matching, we could reuse much of the architecture and replace the row
302
+ types and exception classes.
303
+
304
+ For close planning, we would need a different output head that predicts next
305
+ actions or task order.
306
+
307
+ For forecasting, we would need a numerical prediction head and a different
308
+ loss function.
309
+
310
+ ## A practical folder format
311
+
312
+ A clean specialist dataset could use:
313
+
314
+ ```text
315
+ ap-matching/
316
+ ├── schema.json
317
+ ├── train.jsonl
318
+ ├── validation.jsonl
319
+ ├── test.jsonl
320
+ └── manifest.json
321
+ ```
322
+
323
+ Each line in `train.jsonl` is one complete case, not one invoice row.
324
+
325
+ The manifest records:
326
+
327
+ ```json
328
+ {
329
+ "dataset_version": "1.0",
330
+ "created_at": "2026-07-23",
331
+ "source_system": "anonymized-read-only-export",
332
+ "train_period": ["2023-01", "2025-06"],
333
+ "validation_period": ["2025-07", "2025-09"],
334
+ "test_period": ["2025-10", "2025-12"],
335
+ "currencies": ["USD"],
336
+ "label_method": "controller-approved final disposition"
337
+ }
338
+ ```
339
+
340
+ The simplest rule is:
341
+
342
+ > One example should contain everything needed to solve one complete accounting
343
+ > puzzle, followed by an answer key created from a trustworthy outcome.
344
+
345
+ For multiple specialists, give each HRM its own dataset and answer type. Then
346
+ connect their proposals through the typed Go control layer instead of mixing AP,
347
+ forecasting, reconciliation, and close-management records into one
348
+ undifferentiated training file.
349
+
350
+ ---
351
+
352
+ ## Demonstration and licensing notes
353
+
354
+ - Every transaction shown by this Space is fictional. The demonstration does
355
+ not ask for uploads or send accounting records to a processing server.
356
+ - Reconciliation inference runs inside the visitor's browser using an ONNX
357
+ export of the released checkpoint.
358
+ - The checkpoint is real and its output is probabilistic. A correct-looking
359
+ proposal is not evidence that a reconciliation is complete or approved.
360
+ - The interface ends at human review. It has no posting credentials or
361
+ connection to an accounting system.
362
+ - The source code is Apache-2.0. The released weights were trained with
363
+ Mindweave data licensed under CC BY-NC 4.0 and are released under CC BY-NC
364
+ 4.0 for non-commercial learning and research.
SHA256SUMS ADDED
@@ -0,0 +1 @@
 
 
1
+ 912502b6a5ef711b6aacdce00cb4f48fbdf43c451f93a81a6ab93e4beda23ccb model/cfo_hrm.onnx
app.js ADDED
@@ -0,0 +1,490 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const ORT_VERSION = "1.27.0";
2
+ const MODEL_PATH = "./model/cfo_hrm.onnx";
3
+ const CASES_PATH = "./demo_cases.json";
4
+ const GUIDE_PATH = "./EIL5.md";
5
+
6
+ const EXCEPTION_NAMES = [
7
+ "MATCHED",
8
+ "UNMATCHED",
9
+ "BANK FEE",
10
+ "DUPLICATE",
11
+ "TIMING",
12
+ "REVIEW",
13
+ ];
14
+
15
+ const state = {
16
+ cases: [],
17
+ session: null,
18
+ };
19
+
20
+ const elements = {
21
+ caseSelect: document.querySelector("#case-select"),
22
+ caseTitle: document.querySelector("#case-title"),
23
+ caseDescription: document.querySelector("#case-description"),
24
+ casePeriod: document.querySelector("#case-period"),
25
+ threshold: document.querySelector("#threshold"),
26
+ thresholdValue: document.querySelector("#threshold-value"),
27
+ runButton: document.querySelector("#run-review"),
28
+ modelStatus: document.querySelector("#model-status"),
29
+ demoOutput: document.querySelector("#demo-output"),
30
+ reviewStatus: document.querySelector("#review-status"),
31
+ summaryCards: document.querySelector("#summary-cards"),
32
+ proposalRows: document.querySelector("#proposal-rows"),
33
+ bankRows: document.querySelector("#bank-rows"),
34
+ glRows: document.querySelector("#gl-rows"),
35
+ guide: document.querySelector("#guide-content"),
36
+ };
37
+
38
+ function escapeHtml(value) {
39
+ return String(value)
40
+ .replaceAll("&", "&")
41
+ .replaceAll("<", "&lt;")
42
+ .replaceAll(">", "&gt;")
43
+ .replaceAll('"', "&quot;")
44
+ .replaceAll("'", "&#039;");
45
+ }
46
+
47
+ function formatMoney(value, currency = "USD") {
48
+ return new Intl.NumberFormat("en-US", {
49
+ style: "currency",
50
+ currency,
51
+ minimumFractionDigits: 2,
52
+ }).format(Number(value));
53
+ }
54
+
55
+ function formatPercent(value) {
56
+ return `${(Number(value) * 100).toFixed(1)}%`;
57
+ }
58
+
59
+ async function loadGuide() {
60
+ try {
61
+ const response = await fetch(GUIDE_PATH);
62
+ if (!response.ok) throw new Error(`Guide request failed: ${response.status}`);
63
+ const markdown = await response.text();
64
+ if (!window.marked) throw new Error("Markdown renderer did not load");
65
+ window.marked.use({ gfm: true, breaks: false });
66
+ elements.guide.innerHTML = window.marked.parse(markdown);
67
+ } catch (error) {
68
+ elements.guide.innerHTML = `
69
+ <p class="error-copy">The guide could not be rendered in this browser.</p>
70
+ <p><a href="${GUIDE_PATH}">Open the original EIL5.md file →</a></p>
71
+ <p class="microcopy">${escapeHtml(error.message)}</p>
72
+ `;
73
+ }
74
+ }
75
+
76
+ async function loadCases() {
77
+ const response = await fetch(CASES_PATH);
78
+ if (!response.ok) throw new Error(`Demo cases request failed: ${response.status}`);
79
+ const payload = await response.json();
80
+ state.cases = payload.cases ?? [];
81
+ if (state.cases.length === 0) throw new Error("No demo cases were packaged");
82
+
83
+ elements.caseSelect.replaceChildren(
84
+ ...state.cases.map((item) => {
85
+ const option = document.createElement("option");
86
+ option.value = item.id;
87
+ option.textContent = item.label;
88
+ return option;
89
+ }),
90
+ );
91
+ renderCaseNote();
92
+ }
93
+
94
+ function selectedCase() {
95
+ return state.cases.find((item) => item.id === elements.caseSelect.value) ?? state.cases[0];
96
+ }
97
+
98
+ function renderCaseNote() {
99
+ const item = selectedCase();
100
+ if (!item) return;
101
+ elements.caseTitle.textContent = item.label;
102
+ elements.caseDescription.textContent = item.description;
103
+ elements.casePeriod.textContent = item.period;
104
+ }
105
+
106
+ async function ensureModel() {
107
+ if (state.session) return state.session;
108
+ if (!window.ort) throw new Error("ONNX Runtime Web did not load");
109
+
110
+ elements.modelStatus.textContent = "LOADING CHECKPOINT / FIRST RUN ONLY";
111
+ window.ort.env.wasm.numThreads = 1;
112
+ window.ort.env.wasm.proxy = false;
113
+ window.ort.env.wasm.wasmPaths =
114
+ `https://cdn.jsdelivr.net/npm/onnxruntime-web@${ORT_VERSION}/dist/`;
115
+
116
+ state.session = await window.ort.InferenceSession.create(MODEL_PATH, {
117
+ executionProviders: ["wasm"],
118
+ graphOptimizationLevel: "all",
119
+ });
120
+ elements.modelStatus.textContent = "MODEL READY / RUNNING LOCALLY";
121
+ return state.session;
122
+ }
123
+
124
+ function ortTensor(spec, type) {
125
+ const values = spec.data;
126
+ let data;
127
+ if (type === "float32") data = Float32Array.from(values);
128
+ else if (type === "int64") data = BigInt64Array.from(values, (value) => BigInt(value));
129
+ else if (type === "bool") data = Uint8Array.from(values, (value) => (value ? 1 : 0));
130
+ else throw new Error(`Unsupported tensor type: ${type}`);
131
+ return new window.ort.Tensor(type, data, spec.dims);
132
+ }
133
+
134
+ function buildFeeds(item) {
135
+ return {
136
+ bank_cont: ortTensor(item.inputs.bank_cont, "float32"),
137
+ gl_cont: ortTensor(item.inputs.gl_cont, "float32"),
138
+ bank_cat: ortTensor(item.inputs.bank_cat, "int64"),
139
+ gl_cat: ortTensor(item.inputs.gl_cat, "int64"),
140
+ bank_mask: ortTensor(item.inputs.bank_mask, "bool"),
141
+ gl_mask: ortTensor(item.inputs.gl_mask, "bool"),
142
+ candidate_mask: ortTensor(item.inputs.candidate_mask, "bool"),
143
+ };
144
+ }
145
+
146
+ function flatIndex(row, column, width) {
147
+ return row * width + column;
148
+ }
149
+
150
+ function rectangularHungarian(cost) {
151
+ const rowCount = cost.length;
152
+ const columnCount = cost[0]?.length ?? 0;
153
+ if (rowCount === 0) return [];
154
+ if (rowCount > columnCount) throw new Error("Assignment matrix is not rectangular");
155
+
156
+ const rowPotential = new Float64Array(rowCount + 1);
157
+ const columnPotential = new Float64Array(columnCount + 1);
158
+ const columnRow = new Int32Array(columnCount + 1);
159
+ const predecessor = new Int32Array(columnCount + 1);
160
+
161
+ for (let row = 1; row <= rowCount; row += 1) {
162
+ columnRow[0] = row;
163
+ const minimumSlack = new Float64Array(columnCount + 1);
164
+ minimumSlack.fill(Number.POSITIVE_INFINITY);
165
+ const used = new Uint8Array(columnCount + 1);
166
+ let currentColumn = 0;
167
+
168
+ while (true) {
169
+ used[currentColumn] = 1;
170
+ const currentRow = columnRow[currentColumn];
171
+ let delta = Number.POSITIVE_INFINITY;
172
+ let nextColumn = 0;
173
+
174
+ for (let column = 1; column <= columnCount; column += 1) {
175
+ if (used[column]) continue;
176
+ const edgeCost = cost[currentRow - 1][column - 1];
177
+ if (Number.isFinite(edgeCost)) {
178
+ const slack =
179
+ edgeCost - rowPotential[currentRow] - columnPotential[column];
180
+ if (slack < minimumSlack[column]) {
181
+ minimumSlack[column] = slack;
182
+ predecessor[column] = currentColumn;
183
+ }
184
+ }
185
+ if (minimumSlack[column] < delta) {
186
+ delta = minimumSlack[column];
187
+ nextColumn = column;
188
+ }
189
+ }
190
+
191
+ if (!Number.isFinite(delta)) throw new Error("No feasible assignment exists");
192
+
193
+ for (let column = 0; column <= columnCount; column += 1) {
194
+ if (used[column]) {
195
+ rowPotential[columnRow[column]] += delta;
196
+ columnPotential[column] -= delta;
197
+ } else if (column > 0) {
198
+ minimumSlack[column] -= delta;
199
+ }
200
+ }
201
+
202
+ currentColumn = nextColumn;
203
+ if (columnRow[currentColumn] === 0) break;
204
+ }
205
+
206
+ while (currentColumn !== 0) {
207
+ const previousColumn = predecessor[currentColumn];
208
+ columnRow[currentColumn] = columnRow[previousColumn];
209
+ currentColumn = previousColumn;
210
+ }
211
+ }
212
+
213
+ const assignment = Array(rowCount).fill(-1);
214
+ for (let column = 1; column <= columnCount; column += 1) {
215
+ const row = columnRow[column];
216
+ if (row !== 0) assignment[row - 1] = column - 1;
217
+ }
218
+ return assignment;
219
+ }
220
+
221
+ function decodeAssignment(pairScores, unmatchedScores, item) {
222
+ const bankMask = item.inputs.bank_mask.data;
223
+ const glMask = item.inputs.gl_mask.data;
224
+ const candidateMask = item.inputs.candidate_mask.data;
225
+ const bankCount = item.inputs.bank_mask.dims.at(-1);
226
+ const glCount = item.inputs.gl_mask.dims.at(-1);
227
+ const validBanks = [...Array(bankCount).keys()].filter((index) => bankMask[index]);
228
+ const validGls = [...Array(glCount).keys()].filter((index) => glMask[index]);
229
+ const cost = validBanks.map((bankIndex, localBankIndex) => {
230
+ const row = Array(validGls.length + validBanks.length).fill(
231
+ Number.POSITIVE_INFINITY,
232
+ );
233
+ validGls.forEach((glIndex, localGlIndex) => {
234
+ if (candidateMask[flatIndex(bankIndex, glIndex, glCount)]) {
235
+ row[localGlIndex] = -pairScores[flatIndex(bankIndex, glIndex, glCount)];
236
+ }
237
+ });
238
+ row[validGls.length + localBankIndex] = -unmatchedScores[bankIndex];
239
+ return row;
240
+ });
241
+
242
+ const selectedColumns = rectangularHungarian(cost);
243
+ const bankToGl = Array(bankCount).fill(-1);
244
+ selectedColumns.forEach((column, localBankIndex) => {
245
+ if (column < validGls.length) {
246
+ bankToGl[validBanks[localBankIndex]] = validGls[column];
247
+ }
248
+ });
249
+ return { bankToGl, validBanks, validGls };
250
+ }
251
+
252
+ function localConfidence(
253
+ bankIndex,
254
+ selectedGl,
255
+ pairScores,
256
+ unmatchedScores,
257
+ item,
258
+ ) {
259
+ const glMask = item.inputs.gl_mask.data;
260
+ const candidateMask = item.inputs.candidate_mask.data;
261
+ const glCount = item.inputs.gl_mask.dims.at(-1);
262
+ const choices = [];
263
+ const selectedPositions = new Map();
264
+
265
+ for (let glIndex = 0; glIndex < glCount; glIndex += 1) {
266
+ if (glMask[glIndex] && candidateMask[flatIndex(bankIndex, glIndex, glCount)]) {
267
+ selectedPositions.set(glIndex, choices.length);
268
+ choices.push(pairScores[flatIndex(bankIndex, glIndex, glCount)]);
269
+ }
270
+ }
271
+ const unmatchedPosition = choices.length;
272
+ choices.push(unmatchedScores[bankIndex]);
273
+
274
+ const maximum = Math.max(...choices);
275
+ const exponentials = choices.map((value) => Math.exp(value - maximum));
276
+ const denominator = exponentials.reduce((total, value) => total + value, 0);
277
+ const selectedPosition =
278
+ selectedGl < 0 ? unmatchedPosition : selectedPositions.get(selectedGl);
279
+ return exponentials[selectedPosition] / denominator;
280
+ }
281
+
282
+ function exceptionPredictions(values, bankCount, exceptionCount) {
283
+ return [...Array(bankCount).keys()].map((bankIndex) => {
284
+ let bestIndex = 0;
285
+ let bestValue = Number.NEGATIVE_INFINITY;
286
+ for (let exceptionIndex = 0; exceptionIndex < exceptionCount; exceptionIndex += 1) {
287
+ const value = values[flatIndex(bankIndex, exceptionIndex, exceptionCount)];
288
+ if (value > bestValue) {
289
+ bestValue = value;
290
+ bestIndex = exceptionIndex;
291
+ }
292
+ }
293
+ return bestIndex;
294
+ });
295
+ }
296
+
297
+ function decisionRoute(exceptionName, confidence, threshold, selectedGl) {
298
+ if (confidence < threshold) return "REVIEW / LOW CONFIDENCE";
299
+ if (selectedGl < 0) return "REVIEW / UNMATCHED";
300
+ if (exceptionName !== "MATCHED") return `REVIEW / ${exceptionName}`;
301
+ return "CONTROL CHECK";
302
+ }
303
+
304
+ function renderTableRows(target, rows, fields) {
305
+ target.innerHTML = rows
306
+ .map(
307
+ (row) =>
308
+ `<tr>${fields
309
+ .map((field) => `<td>${field(row)}</td>`)
310
+ .join("")}</tr>`,
311
+ )
312
+ .join("");
313
+ }
314
+
315
+ function renderResult(item, result, threshold) {
316
+ const pairOutput = result.pair_logits;
317
+ const unmatchedOutput = result.unmatched_logits;
318
+ const exceptionOutput = result.exception_logits;
319
+ if (!pairOutput || !unmatchedOutput || !exceptionOutput) {
320
+ throw new Error("The model returned an unexpected output contract");
321
+ }
322
+
323
+ const decoded = decodeAssignment(pairOutput.data, unmatchedOutput.data, item);
324
+ const bankCount = item.inputs.bank_mask.dims.at(-1);
325
+ const exceptionCount = exceptionOutput.dims.at(-1);
326
+ const exceptionIndices = exceptionPredictions(
327
+ exceptionOutput.data,
328
+ bankCount,
329
+ exceptionCount,
330
+ );
331
+
332
+ const proposals = decoded.validBanks.map((bankIndex) => {
333
+ const selectedGl = decoded.bankToGl[bankIndex];
334
+ const confidence = localConfidence(
335
+ bankIndex,
336
+ selectedGl,
337
+ pairOutput.data,
338
+ unmatchedOutput.data,
339
+ item,
340
+ );
341
+ const exceptionName = EXCEPTION_NAMES[exceptionIndices[bankIndex]] ?? "REVIEW";
342
+ return {
343
+ bankIndex,
344
+ bank: item.display.bank_rows[bankIndex],
345
+ glIndex: selectedGl,
346
+ gl: selectedGl >= 0 ? item.display.gl_rows[selectedGl] : null,
347
+ confidence,
348
+ exceptionName,
349
+ route: decisionRoute(
350
+ exceptionName,
351
+ confidence,
352
+ threshold,
353
+ selectedGl,
354
+ ),
355
+ };
356
+ });
357
+
358
+ const matched = proposals.filter((proposal) => proposal.gl).length;
359
+ const unmatched = proposals.length - matched;
360
+ const reviewItems = proposals.filter((proposal) => proposal.route !== "CONTROL CHECK");
361
+ const averageConfidence =
362
+ proposals.reduce((total, proposal) => total + proposal.confidence, 0) /
363
+ Math.max(proposals.length, 1);
364
+ const exactReference = item.truth?.bank_to_gl
365
+ ? proposals.every(
366
+ (proposal) =>
367
+ Number(item.truth.bank_to_gl[proposal.bankIndex]) === proposal.glIndex,
368
+ )
369
+ : null;
370
+
371
+ elements.reviewStatus.className = `status-strip ${
372
+ reviewItems.length ? "status-review" : "status-standard"
373
+ }`;
374
+ elements.reviewStatus.innerHTML = `
375
+ <div>
376
+ <span>REVIEW ROUTE</span>
377
+ <strong>${reviewItems.length ? "HUMAN REVIEW REQUIRED" : "STANDARD REVIEW"}</strong>
378
+ </div>
379
+ <div>
380
+ <span>POSTING AUTHORIZED</span>
381
+ <strong>FALSE</strong>
382
+ </div>
383
+ `;
384
+
385
+ const cards = [
386
+ [matched, "proposed matches"],
387
+ [unmatched, "unmatched rows"],
388
+ [reviewItems.length, "items flagged"],
389
+ [formatPercent(averageConfidence), "mean confidence"],
390
+ ];
391
+ elements.summaryCards.innerHTML = cards
392
+ .map(
393
+ ([value, label], index) => `
394
+ <article class="stat-card">
395
+ <span class="stat-index">0${index + 1}</span>
396
+ <strong>${escapeHtml(value)}</strong>
397
+ <span>${escapeHtml(label)}</span>
398
+ </article>
399
+ `,
400
+ )
401
+ .join("");
402
+
403
+ elements.proposalRows.innerHTML = proposals
404
+ .map(
405
+ (proposal) => `
406
+ <tr>
407
+ <td><strong>${escapeHtml(proposal.bank.id)}</strong></td>
408
+ <td class="amount">${formatMoney(
409
+ proposal.bank.amount,
410
+ proposal.bank.currency,
411
+ )}</td>
412
+ <td>${proposal.gl ? escapeHtml(proposal.gl.id) : "— UNMATCHED —"}</td>
413
+ <td>${formatPercent(proposal.confidence)}</td>
414
+ <td><span class="signal signal-${proposal.exceptionName
415
+ .toLowerCase()
416
+ .replaceAll(" ", "-")}">${escapeHtml(proposal.exceptionName)}</span></td>
417
+ <td>${escapeHtml(proposal.route)}</td>
418
+ </tr>
419
+ `,
420
+ )
421
+ .join("");
422
+
423
+ renderTableRows(elements.bankRows, item.display.bank_rows, [
424
+ (row) => `<strong>${escapeHtml(row.id)}</strong>`,
425
+ (row) => escapeHtml(row.date),
426
+ (row) => escapeHtml(row.narrative),
427
+ (row) => `<span class="amount">${formatMoney(row.amount, row.currency)}</span>`,
428
+ ]);
429
+ renderTableRows(elements.glRows, item.display.gl_rows, [
430
+ (row) => `<strong>${escapeHtml(row.id)}</strong>`,
431
+ (row) => escapeHtml(row.date),
432
+ (row) => escapeHtml(row.narrative),
433
+ (row) => `<span class="amount">${formatMoney(row.amount, row.currency)}</span>`,
434
+ ]);
435
+
436
+ if (exactReference !== null) {
437
+ elements.modelStatus.textContent = exactReference
438
+ ? "RUN COMPLETE / MATCHES FICTIONAL REFERENCE ANSWER"
439
+ : "RUN COMPLETE / DIFFERS FROM FICTIONAL REFERENCE ANSWER";
440
+ } else {
441
+ elements.modelStatus.textContent = "RUN COMPLETE / HUMAN REVIEW REQUIRED";
442
+ }
443
+ elements.demoOutput.hidden = false;
444
+ elements.demoOutput.scrollIntoView({ behavior: "smooth", block: "start" });
445
+ }
446
+
447
+ async function runReview() {
448
+ const item = selectedCase();
449
+ if (!item) return;
450
+ const threshold = Number(elements.threshold.value) / 100;
451
+ elements.runButton.disabled = true;
452
+ elements.runButton.textContent = "Reviewing…";
453
+ elements.modelStatus.textContent = "PREPARING FICTIONAL RECORDS";
454
+
455
+ try {
456
+ const session = await ensureModel();
457
+ elements.modelStatus.textContent = "REASONING / ENFORCING ONE-TO-ONE USE";
458
+ const output = await session.run(buildFeeds(item));
459
+ renderResult(item, output, threshold);
460
+ } catch (error) {
461
+ console.error(error);
462
+ elements.modelStatus.textContent = `MODEL ERROR / ${error.message}`;
463
+ elements.reviewStatus.className = "status-strip status-error";
464
+ elements.reviewStatus.innerHTML = `
465
+ <div>
466
+ <span>DEMO STATUS</span>
467
+ <strong>COULD NOT RUN IN THIS BROWSER</strong>
468
+ </div>
469
+ <div>
470
+ <span>SAFE RESULT</span>
471
+ <strong>NO DECISION / NO POSTING</strong>
472
+ </div>
473
+ `;
474
+ elements.demoOutput.hidden = false;
475
+ } finally {
476
+ elements.runButton.disabled = false;
477
+ elements.runButton.textContent = "Review this batch →";
478
+ }
479
+ }
480
+
481
+ elements.threshold.addEventListener("input", () => {
482
+ elements.thresholdValue.value = `${elements.threshold.value}%`;
483
+ });
484
+ elements.caseSelect.addEventListener("change", renderCaseNote);
485
+ elements.runButton.addEventListener("click", runReview);
486
+
487
+ Promise.all([loadGuide(), loadCases()]).catch((error) => {
488
+ console.error(error);
489
+ elements.modelStatus.textContent = `SETUP ERROR / ${error.message}`;
490
+ });
demo_cases.json ADDED
@@ -0,0 +1,3901 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": 1,
3
+ "cases": [
4
+ {
5
+ "id": "clean-close",
6
+ "label": "A clean month-end close",
7
+ "kicker": "START HERE",
8
+ "description": "Eight ordinary operating-account transactions. The model must pair each bank line to one\u2014and only one\u2014general-ledger line.",
9
+ "period": "July 2026",
10
+ "inputs": {
11
+ "bank_cont": {
12
+ "data": [
13
+ 0.49339696764945984,
14
+ -0.800000011920929,
15
+ 1.0,
16
+ -0.24957138299942017,
17
+ -1.0,
18
+ -1.0,
19
+ -0.46732231974601746,
20
+ 0.13333334028720856,
21
+ -1.0,
22
+ -0.747965395450592,
23
+ -1.0,
24
+ -1.0,
25
+ 0.42121371626853943,
26
+ 0.6666666865348816,
27
+ 1.0,
28
+ 0.47333502769470215,
29
+ 0.06666667014360428,
30
+ 1.0,
31
+ 0.6987425088882446,
32
+ 0.2666666805744171,
33
+ 1.0,
34
+ 0.7583048343658447,
35
+ -0.7333333492279053,
36
+ 1.0,
37
+ 0.0,
38
+ 0.0,
39
+ 0.0,
40
+ 0.0,
41
+ 0.0,
42
+ 0.0,
43
+ 0.0,
44
+ 0.0,
45
+ 0.0,
46
+ 0.0,
47
+ 0.0,
48
+ 0.0,
49
+ 0.0,
50
+ 0.0,
51
+ 0.0,
52
+ 0.0,
53
+ 0.0,
54
+ 0.0,
55
+ 0.0,
56
+ 0.0,
57
+ 0.0,
58
+ 0.0,
59
+ 0.0,
60
+ 0.0,
61
+ 0.0,
62
+ 0.0,
63
+ 0.0,
64
+ 0.0,
65
+ 0.0,
66
+ 0.0,
67
+ 0.0,
68
+ 0.0,
69
+ 0.0,
70
+ 0.0,
71
+ 0.0,
72
+ 0.0,
73
+ 0.0,
74
+ 0.0,
75
+ 0.0,
76
+ 0.0,
77
+ 0.0,
78
+ 0.0,
79
+ 0.0,
80
+ 0.0,
81
+ 0.0,
82
+ 0.0,
83
+ 0.0,
84
+ 0.0
85
+ ],
86
+ "dims": [
87
+ 1,
88
+ 24,
89
+ 3
90
+ ]
91
+ },
92
+ "gl_cont": {
93
+ "data": [
94
+ 0.49339696764945984,
95
+ -0.6666666865348816,
96
+ 1.0,
97
+ -0.46732231974601746,
98
+ 0.06666667014360428,
99
+ -1.0,
100
+ 0.6987425088882446,
101
+ 0.3333333432674408,
102
+ 1.0,
103
+ -0.24957138299942017,
104
+ -0.8666666746139526,
105
+ -1.0,
106
+ 0.7583048343658447,
107
+ -0.6666666865348816,
108
+ 1.0,
109
+ -0.747965395450592,
110
+ -0.9333333373069763,
111
+ -1.0,
112
+ 0.42121371626853943,
113
+ 0.46666666865348816,
114
+ 1.0,
115
+ 0.47333502769470215,
116
+ 0.13333334028720856,
117
+ 1.0,
118
+ 0.0,
119
+ 0.0,
120
+ 0.0,
121
+ 0.0,
122
+ 0.0,
123
+ 0.0,
124
+ 0.0,
125
+ 0.0,
126
+ 0.0,
127
+ 0.0,
128
+ 0.0,
129
+ 0.0,
130
+ 0.0,
131
+ 0.0,
132
+ 0.0,
133
+ 0.0,
134
+ 0.0,
135
+ 0.0,
136
+ 0.0,
137
+ 0.0,
138
+ 0.0,
139
+ 0.0,
140
+ 0.0,
141
+ 0.0,
142
+ 0.0,
143
+ 0.0,
144
+ 0.0,
145
+ 0.0,
146
+ 0.0,
147
+ 0.0,
148
+ 0.0,
149
+ 0.0,
150
+ 0.0,
151
+ 0.0,
152
+ 0.0,
153
+ 0.0,
154
+ 0.0,
155
+ 0.0,
156
+ 0.0,
157
+ 0.0,
158
+ 0.0,
159
+ 0.0,
160
+ 0.0,
161
+ 0.0,
162
+ 0.0,
163
+ 0.0,
164
+ 0.0,
165
+ 0.0
166
+ ],
167
+ "dims": [
168
+ 1,
169
+ 24,
170
+ 3
171
+ ]
172
+ },
173
+ "bank_cat": {
174
+ "data": [
175
+ 1,
176
+ 1,
177
+ 12,
178
+ 92,
179
+ 1,
180
+ 185,
181
+ 2,
182
+ 3,
183
+ 9,
184
+ 1,
185
+ 1104,
186
+ 111,
187
+ 1,
188
+ 3,
189
+ 17,
190
+ 26,
191
+ 841,
192
+ 96,
193
+ 2,
194
+ 3,
195
+ 6,
196
+ 66,
197
+ 722,
198
+ 191,
199
+ 2,
200
+ 4,
201
+ 12,
202
+ 42,
203
+ 6774,
204
+ 223,
205
+ 1,
206
+ 2,
207
+ 23,
208
+ 44,
209
+ 4085,
210
+ 96,
211
+ 1,
212
+ 1,
213
+ 4,
214
+ 67,
215
+ 3116,
216
+ 92,
217
+ 3,
218
+ 3,
219
+ 15,
220
+ 16,
221
+ 1,
222
+ 216,
223
+ 0,
224
+ 0,
225
+ 0,
226
+ 0,
227
+ 0,
228
+ 0,
229
+ 0,
230
+ 0,
231
+ 0,
232
+ 0,
233
+ 0,
234
+ 0,
235
+ 0,
236
+ 0,
237
+ 0,
238
+ 0,
239
+ 0,
240
+ 0,
241
+ 0,
242
+ 0,
243
+ 0,
244
+ 0,
245
+ 0,
246
+ 0,
247
+ 0,
248
+ 0,
249
+ 0,
250
+ 0,
251
+ 0,
252
+ 0,
253
+ 0,
254
+ 0,
255
+ 0,
256
+ 0,
257
+ 0,
258
+ 0,
259
+ 0,
260
+ 0,
261
+ 0,
262
+ 0,
263
+ 0,
264
+ 0,
265
+ 0,
266
+ 0,
267
+ 0,
268
+ 0,
269
+ 0,
270
+ 0,
271
+ 0,
272
+ 0,
273
+ 0,
274
+ 0,
275
+ 0,
276
+ 0,
277
+ 0,
278
+ 0,
279
+ 0,
280
+ 0,
281
+ 0,
282
+ 0,
283
+ 0,
284
+ 0,
285
+ 0,
286
+ 0,
287
+ 0,
288
+ 0,
289
+ 0,
290
+ 0,
291
+ 0,
292
+ 0,
293
+ 0,
294
+ 0,
295
+ 0,
296
+ 0,
297
+ 0,
298
+ 0,
299
+ 0,
300
+ 0,
301
+ 0,
302
+ 0,
303
+ 0,
304
+ 0,
305
+ 0,
306
+ 0,
307
+ 0,
308
+ 0,
309
+ 0,
310
+ 0,
311
+ 0,
312
+ 0,
313
+ 0,
314
+ 0,
315
+ 0,
316
+ 0,
317
+ 0,
318
+ 0
319
+ ],
320
+ "dims": [
321
+ 1,
322
+ 24,
323
+ 6
324
+ ]
325
+ },
326
+ "gl_cat": {
327
+ "data": [
328
+ 1,
329
+ 1,
330
+ 13,
331
+ 92,
332
+ 7199,
333
+ 185,
334
+ 1,
335
+ 3,
336
+ 16,
337
+ 26,
338
+ 841,
339
+ 96,
340
+ 1,
341
+ 1,
342
+ 5,
343
+ 67,
344
+ 3116,
345
+ 92,
346
+ 2,
347
+ 3,
348
+ 24,
349
+ 1,
350
+ 1104,
351
+ 111,
352
+ 3,
353
+ 3,
354
+ 5,
355
+ 16,
356
+ 1602,
357
+ 216,
358
+ 2,
359
+ 3,
360
+ 5,
361
+ 66,
362
+ 722,
363
+ 191,
364
+ 2,
365
+ 4,
366
+ 7,
367
+ 42,
368
+ 6774,
369
+ 173,
370
+ 1,
371
+ 2,
372
+ 2,
373
+ 44,
374
+ 4085,
375
+ 96,
376
+ 0,
377
+ 0,
378
+ 0,
379
+ 0,
380
+ 0,
381
+ 0,
382
+ 0,
383
+ 0,
384
+ 0,
385
+ 0,
386
+ 0,
387
+ 0,
388
+ 0,
389
+ 0,
390
+ 0,
391
+ 0,
392
+ 0,
393
+ 0,
394
+ 0,
395
+ 0,
396
+ 0,
397
+ 0,
398
+ 0,
399
+ 0,
400
+ 0,
401
+ 0,
402
+ 0,
403
+ 0,
404
+ 0,
405
+ 0,
406
+ 0,
407
+ 0,
408
+ 0,
409
+ 0,
410
+ 0,
411
+ 0,
412
+ 0,
413
+ 0,
414
+ 0,
415
+ 0,
416
+ 0,
417
+ 0,
418
+ 0,
419
+ 0,
420
+ 0,
421
+ 0,
422
+ 0,
423
+ 0,
424
+ 0,
425
+ 0,
426
+ 0,
427
+ 0,
428
+ 0,
429
+ 0,
430
+ 0,
431
+ 0,
432
+ 0,
433
+ 0,
434
+ 0,
435
+ 0,
436
+ 0,
437
+ 0,
438
+ 0,
439
+ 0,
440
+ 0,
441
+ 0,
442
+ 0,
443
+ 0,
444
+ 0,
445
+ 0,
446
+ 0,
447
+ 0,
448
+ 0,
449
+ 0,
450
+ 0,
451
+ 0,
452
+ 0,
453
+ 0,
454
+ 0,
455
+ 0,
456
+ 0,
457
+ 0,
458
+ 0,
459
+ 0,
460
+ 0,
461
+ 0,
462
+ 0,
463
+ 0,
464
+ 0,
465
+ 0,
466
+ 0,
467
+ 0,
468
+ 0,
469
+ 0,
470
+ 0,
471
+ 0
472
+ ],
473
+ "dims": [
474
+ 1,
475
+ 24,
476
+ 6
477
+ ]
478
+ },
479
+ "bank_mask": {
480
+ "data": [
481
+ true,
482
+ true,
483
+ true,
484
+ true,
485
+ true,
486
+ true,
487
+ true,
488
+ true,
489
+ false,
490
+ false,
491
+ false,
492
+ false,
493
+ false,
494
+ false,
495
+ false,
496
+ false,
497
+ false,
498
+ false,
499
+ false,
500
+ false,
501
+ false,
502
+ false,
503
+ false,
504
+ false
505
+ ],
506
+ "dims": [
507
+ 1,
508
+ 24
509
+ ]
510
+ },
511
+ "gl_mask": {
512
+ "data": [
513
+ true,
514
+ true,
515
+ true,
516
+ true,
517
+ true,
518
+ true,
519
+ true,
520
+ true,
521
+ false,
522
+ false,
523
+ false,
524
+ false,
525
+ false,
526
+ false,
527
+ false,
528
+ false,
529
+ false,
530
+ false,
531
+ false,
532
+ false,
533
+ false,
534
+ false,
535
+ false,
536
+ false
537
+ ],
538
+ "dims": [
539
+ 1,
540
+ 24
541
+ ]
542
+ },
543
+ "candidate_mask": {
544
+ "data": [
545
+ true,
546
+ false,
547
+ false,
548
+ false,
549
+ false,
550
+ false,
551
+ false,
552
+ false,
553
+ false,
554
+ false,
555
+ false,
556
+ false,
557
+ false,
558
+ false,
559
+ false,
560
+ false,
561
+ false,
562
+ false,
563
+ false,
564
+ false,
565
+ false,
566
+ false,
567
+ false,
568
+ false,
569
+ false,
570
+ false,
571
+ false,
572
+ true,
573
+ false,
574
+ false,
575
+ false,
576
+ false,
577
+ false,
578
+ false,
579
+ false,
580
+ false,
581
+ false,
582
+ false,
583
+ false,
584
+ false,
585
+ false,
586
+ false,
587
+ false,
588
+ false,
589
+ false,
590
+ false,
591
+ false,
592
+ false,
593
+ false,
594
+ true,
595
+ false,
596
+ false,
597
+ false,
598
+ false,
599
+ false,
600
+ false,
601
+ false,
602
+ false,
603
+ false,
604
+ false,
605
+ false,
606
+ false,
607
+ false,
608
+ false,
609
+ false,
610
+ false,
611
+ false,
612
+ false,
613
+ false,
614
+ false,
615
+ false,
616
+ false,
617
+ false,
618
+ false,
619
+ false,
620
+ false,
621
+ false,
622
+ true,
623
+ false,
624
+ false,
625
+ false,
626
+ false,
627
+ false,
628
+ false,
629
+ false,
630
+ false,
631
+ false,
632
+ false,
633
+ false,
634
+ false,
635
+ false,
636
+ false,
637
+ false,
638
+ false,
639
+ false,
640
+ false,
641
+ false,
642
+ false,
643
+ false,
644
+ false,
645
+ false,
646
+ false,
647
+ true,
648
+ false,
649
+ false,
650
+ false,
651
+ false,
652
+ false,
653
+ false,
654
+ false,
655
+ false,
656
+ false,
657
+ false,
658
+ false,
659
+ false,
660
+ false,
661
+ false,
662
+ false,
663
+ false,
664
+ false,
665
+ false,
666
+ false,
667
+ false,
668
+ false,
669
+ false,
670
+ false,
671
+ false,
672
+ true,
673
+ false,
674
+ false,
675
+ false,
676
+ false,
677
+ false,
678
+ false,
679
+ false,
680
+ false,
681
+ false,
682
+ false,
683
+ false,
684
+ false,
685
+ false,
686
+ false,
687
+ false,
688
+ false,
689
+ false,
690
+ false,
691
+ true,
692
+ false,
693
+ false,
694
+ false,
695
+ false,
696
+ false,
697
+ false,
698
+ false,
699
+ false,
700
+ false,
701
+ false,
702
+ false,
703
+ false,
704
+ false,
705
+ false,
706
+ false,
707
+ false,
708
+ false,
709
+ false,
710
+ false,
711
+ false,
712
+ false,
713
+ false,
714
+ false,
715
+ false,
716
+ false,
717
+ true,
718
+ false,
719
+ false,
720
+ false,
721
+ false,
722
+ false,
723
+ false,
724
+ false,
725
+ false,
726
+ false,
727
+ false,
728
+ false,
729
+ false,
730
+ false,
731
+ false,
732
+ false,
733
+ false,
734
+ false,
735
+ false,
736
+ false,
737
+ false,
738
+ false,
739
+ false,
740
+ false,
741
+ false,
742
+ false,
743
+ false,
744
+ false,
745
+ false,
746
+ false,
747
+ false,
748
+ false,
749
+ false,
750
+ false,
751
+ false,
752
+ false,
753
+ false,
754
+ false,
755
+ false,
756
+ false,
757
+ false,
758
+ false,
759
+ false,
760
+ false,
761
+ false,
762
+ false,
763
+ false,
764
+ false,
765
+ false,
766
+ false,
767
+ false,
768
+ false,
769
+ false,
770
+ false,
771
+ false,
772
+ false,
773
+ false,
774
+ false,
775
+ false,
776
+ false,
777
+ false,
778
+ false,
779
+ false,
780
+ false,
781
+ false,
782
+ false,
783
+ false,
784
+ false,
785
+ false,
786
+ false,
787
+ false,
788
+ false,
789
+ false,
790
+ false,
791
+ false,
792
+ false,
793
+ false,
794
+ false,
795
+ false,
796
+ false,
797
+ false,
798
+ false,
799
+ false,
800
+ false,
801
+ false,
802
+ false,
803
+ false,
804
+ false,
805
+ false,
806
+ false,
807
+ false,
808
+ false,
809
+ false,
810
+ false,
811
+ false,
812
+ false,
813
+ false,
814
+ false,
815
+ false,
816
+ false,
817
+ false,
818
+ false,
819
+ false,
820
+ false,
821
+ false,
822
+ false,
823
+ false,
824
+ false,
825
+ false,
826
+ false,
827
+ false,
828
+ false,
829
+ false,
830
+ false,
831
+ false,
832
+ false,
833
+ false,
834
+ false,
835
+ false,
836
+ false,
837
+ false,
838
+ false,
839
+ false,
840
+ false,
841
+ false,
842
+ false,
843
+ false,
844
+ false,
845
+ false,
846
+ false,
847
+ false,
848
+ false,
849
+ false,
850
+ false,
851
+ false,
852
+ false,
853
+ false,
854
+ false,
855
+ false,
856
+ false,
857
+ false,
858
+ false,
859
+ false,
860
+ false,
861
+ false,
862
+ false,
863
+ false,
864
+ false,
865
+ false,
866
+ false,
867
+ false,
868
+ false,
869
+ false,
870
+ false,
871
+ false,
872
+ false,
873
+ false,
874
+ false,
875
+ false,
876
+ false,
877
+ false,
878
+ false,
879
+ false,
880
+ false,
881
+ false,
882
+ false,
883
+ false,
884
+ false,
885
+ false,
886
+ false,
887
+ false,
888
+ false,
889
+ false,
890
+ false,
891
+ false,
892
+ false,
893
+ false,
894
+ false,
895
+ false,
896
+ false,
897
+ false,
898
+ false,
899
+ false,
900
+ false,
901
+ false,
902
+ false,
903
+ false,
904
+ false,
905
+ false,
906
+ false,
907
+ false,
908
+ false,
909
+ false,
910
+ false,
911
+ false,
912
+ false,
913
+ false,
914
+ false,
915
+ false,
916
+ false,
917
+ false,
918
+ false,
919
+ false,
920
+ false,
921
+ false,
922
+ false,
923
+ false,
924
+ false,
925
+ false,
926
+ false,
927
+ false,
928
+ false,
929
+ false,
930
+ false,
931
+ false,
932
+ false,
933
+ false,
934
+ false,
935
+ false,
936
+ false,
937
+ false,
938
+ false,
939
+ false,
940
+ false,
941
+ false,
942
+ false,
943
+ false,
944
+ false,
945
+ false,
946
+ false,
947
+ false,
948
+ false,
949
+ false,
950
+ false,
951
+ false,
952
+ false,
953
+ false,
954
+ false,
955
+ false,
956
+ false,
957
+ false,
958
+ false,
959
+ false,
960
+ false,
961
+ false,
962
+ false,
963
+ false,
964
+ false,
965
+ false,
966
+ false,
967
+ false,
968
+ false,
969
+ false,
970
+ false,
971
+ false,
972
+ false,
973
+ false,
974
+ false,
975
+ false,
976
+ false,
977
+ false,
978
+ false,
979
+ false,
980
+ false,
981
+ false,
982
+ false,
983
+ false,
984
+ false,
985
+ false,
986
+ false,
987
+ false,
988
+ false,
989
+ false,
990
+ false,
991
+ false,
992
+ false,
993
+ false,
994
+ false,
995
+ false,
996
+ false,
997
+ false,
998
+ false,
999
+ false,
1000
+ false,
1001
+ false,
1002
+ false,
1003
+ false,
1004
+ false,
1005
+ false,
1006
+ false,
1007
+ false,
1008
+ false,
1009
+ false,
1010
+ false,
1011
+ false,
1012
+ false,
1013
+ false,
1014
+ false,
1015
+ false,
1016
+ false,
1017
+ false,
1018
+ false,
1019
+ false,
1020
+ false,
1021
+ false,
1022
+ false,
1023
+ false,
1024
+ false,
1025
+ false,
1026
+ false,
1027
+ false,
1028
+ false,
1029
+ false,
1030
+ false,
1031
+ false,
1032
+ false,
1033
+ false,
1034
+ false,
1035
+ false,
1036
+ false,
1037
+ false,
1038
+ false,
1039
+ false,
1040
+ false,
1041
+ false,
1042
+ false,
1043
+ false,
1044
+ false,
1045
+ false,
1046
+ false,
1047
+ false,
1048
+ false,
1049
+ false,
1050
+ false,
1051
+ false,
1052
+ false,
1053
+ false,
1054
+ false,
1055
+ false,
1056
+ false,
1057
+ false,
1058
+ false,
1059
+ false,
1060
+ false,
1061
+ false,
1062
+ false,
1063
+ false,
1064
+ false,
1065
+ false,
1066
+ false,
1067
+ false,
1068
+ false,
1069
+ false,
1070
+ false,
1071
+ false,
1072
+ false,
1073
+ false,
1074
+ false,
1075
+ false,
1076
+ false,
1077
+ false,
1078
+ false,
1079
+ false,
1080
+ false,
1081
+ false,
1082
+ false,
1083
+ false,
1084
+ false,
1085
+ false,
1086
+ false,
1087
+ false,
1088
+ false,
1089
+ false,
1090
+ false,
1091
+ false,
1092
+ false,
1093
+ false,
1094
+ false,
1095
+ false,
1096
+ false,
1097
+ false,
1098
+ false,
1099
+ false,
1100
+ false,
1101
+ false,
1102
+ false,
1103
+ false,
1104
+ false,
1105
+ false,
1106
+ false,
1107
+ false,
1108
+ false,
1109
+ false,
1110
+ false,
1111
+ false,
1112
+ false,
1113
+ false,
1114
+ false,
1115
+ false,
1116
+ false,
1117
+ false,
1118
+ false,
1119
+ false,
1120
+ false
1121
+ ],
1122
+ "dims": [
1123
+ 1,
1124
+ 24,
1125
+ 24
1126
+ ]
1127
+ }
1128
+ },
1129
+ "display": {
1130
+ "bank_rows": [
1131
+ {
1132
+ "id": "BANK-CLEAN-CLOSE-01",
1133
+ "date": "2026-07-04",
1134
+ "amount": 146.89,
1135
+ "currency": "USD",
1136
+ "entity": "Northstar Studio LLC",
1137
+ "reference": "\u2014",
1138
+ "narrative": "Supplier payment \u00b7 Ember Insurance"
1139
+ },
1140
+ {
1141
+ "id": "BANK-CLEAN-CLOSE-02",
1142
+ "date": "2026-07-01",
1143
+ "amount": -11.52,
1144
+ "currency": "EUR",
1145
+ "entity": "Northstar Retail LLC",
1146
+ "reference": "PAY-01104",
1147
+ "narrative": "Operating expense \u00b7 Beacon Telecom"
1148
+ },
1149
+ {
1150
+ "id": "BANK-CLEAN-CLOSE-03",
1151
+ "date": "2026-07-18",
1152
+ "amount": -112.57,
1153
+ "currency": "USD",
1154
+ "entity": "Northstar Retail LLC",
1155
+ "reference": "PAY-00841",
1156
+ "narrative": "Customer receipt \u00b7 Cedar Payroll"
1157
+ },
1158
+ {
1159
+ "id": "BANK-CLEAN-CLOSE-04",
1160
+ "date": "2026-07-01",
1161
+ "amount": -1946.69,
1162
+ "currency": "EUR",
1163
+ "entity": "Northstar Retail LLC",
1164
+ "reference": "PAY-00722",
1165
+ "narrative": "Operating expense \u00b7 Cedar Payroll"
1166
+ },
1167
+ {
1168
+ "id": "BANK-CLEAN-CLOSE-05",
1169
+ "date": "2026-07-26",
1170
+ "amount": 70.2,
1171
+ "currency": "EUR",
1172
+ "entity": "Northstar Holdings LLC",
1173
+ "reference": "PAY-06774",
1174
+ "narrative": "Operating expense \u00b7 Cedar Payroll"
1175
+ },
1176
+ {
1177
+ "id": "BANK-CLEAN-CLOSE-06",
1178
+ "date": "2026-07-17",
1179
+ "amount": 119.7,
1180
+ "currency": "USD",
1181
+ "entity": "Northstar Services LLC",
1182
+ "reference": "PAY-04085",
1183
+ "narrative": "Customer receipt \u00b7 Ember Insurance"
1184
+ },
1185
+ {
1186
+ "id": "BANK-CLEAN-CLOSE-07",
1187
+ "date": "2026-07-20",
1188
+ "amount": 1182.15,
1189
+ "currency": "USD",
1190
+ "entity": "Northstar Studio LLC",
1191
+ "reference": "PAY-03116",
1192
+ "narrative": "Software subscription \u00b7 Dovetail Logistics"
1193
+ },
1194
+ {
1195
+ "id": "BANK-CLEAN-CLOSE-08",
1196
+ "date": "2026-07-05",
1197
+ "amount": 2161.68,
1198
+ "currency": "GBP",
1199
+ "entity": "Northstar Retail LLC",
1200
+ "reference": "\u2014",
1201
+ "narrative": "Customer receipt \u00b7 Atlas Office Co."
1202
+ }
1203
+ ],
1204
+ "gl_rows": [
1205
+ {
1206
+ "id": "GL-CLEAN-CLOSE-01",
1207
+ "date": "2026-07-06",
1208
+ "amount": 146.89,
1209
+ "currency": "USD",
1210
+ "entity": "Northstar Studio LLC",
1211
+ "reference": "PAY-07199",
1212
+ "narrative": "Supplier payment \u00b7 Ember Insurance"
1213
+ },
1214
+ {
1215
+ "id": "GL-CLEAN-CLOSE-02",
1216
+ "date": "2026-07-17",
1217
+ "amount": -112.57,
1218
+ "currency": "USD",
1219
+ "entity": "Northstar Retail LLC",
1220
+ "reference": "PAY-00841",
1221
+ "narrative": "Customer receipt \u00b7 Cedar Payroll"
1222
+ },
1223
+ {
1224
+ "id": "GL-CLEAN-CLOSE-03",
1225
+ "date": "2026-07-21",
1226
+ "amount": 1182.15,
1227
+ "currency": "USD",
1228
+ "entity": "Northstar Studio LLC",
1229
+ "reference": "PAY-03116",
1230
+ "narrative": "Software subscription \u00b7 Dovetail Logistics"
1231
+ },
1232
+ {
1233
+ "id": "GL-CLEAN-CLOSE-04",
1234
+ "date": "2026-07-03",
1235
+ "amount": -11.52,
1236
+ "currency": "EUR",
1237
+ "entity": "Northstar Retail LLC",
1238
+ "reference": "PAY-01104",
1239
+ "narrative": "Operating expense \u00b7 Beacon Telecom"
1240
+ },
1241
+ {
1242
+ "id": "GL-CLEAN-CLOSE-05",
1243
+ "date": "2026-07-06",
1244
+ "amount": 2161.68,
1245
+ "currency": "GBP",
1246
+ "entity": "Northstar Retail LLC",
1247
+ "reference": "PAY-01602",
1248
+ "narrative": "Customer receipt \u00b7 Atlas Office Co."
1249
+ },
1250
+ {
1251
+ "id": "GL-CLEAN-CLOSE-06",
1252
+ "date": "2026-07-02",
1253
+ "amount": -1946.69,
1254
+ "currency": "EUR",
1255
+ "entity": "Northstar Retail LLC",
1256
+ "reference": "PAY-00722",
1257
+ "narrative": "Operating expense \u00b7 Cedar Payroll"
1258
+ },
1259
+ {
1260
+ "id": "GL-CLEAN-CLOSE-07",
1261
+ "date": "2026-07-23",
1262
+ "amount": 70.2,
1263
+ "currency": "EUR",
1264
+ "entity": "Northstar Holdings LLC",
1265
+ "reference": "PAY-06774",
1266
+ "narrative": "Insurance payment \u00b7 Cedar Payroll"
1267
+ },
1268
+ {
1269
+ "id": "GL-CLEAN-CLOSE-08",
1270
+ "date": "2026-07-18",
1271
+ "amount": 119.7,
1272
+ "currency": "USD",
1273
+ "entity": "Northstar Services LLC",
1274
+ "reference": "PAY-04085",
1275
+ "narrative": "Customer receipt \u00b7 Ember Insurance"
1276
+ }
1277
+ ]
1278
+ },
1279
+ "truth": {
1280
+ "bank_to_gl": [
1281
+ 0,
1282
+ 3,
1283
+ 1,
1284
+ 5,
1285
+ 6,
1286
+ 7,
1287
+ 2,
1288
+ 4
1289
+ ],
1290
+ "exceptions": [
1291
+ "MATCHED",
1292
+ "MATCHED",
1293
+ "MATCHED",
1294
+ "MATCHED",
1295
+ "MATCHED",
1296
+ "MATCHED",
1297
+ "MATCHED",
1298
+ "MATCHED"
1299
+ ]
1300
+ }
1301
+ },
1302
+ {
1303
+ "id": "bank-fee",
1304
+ "label": "A statement with a bank fee",
1305
+ "kicker": "EXCEPTION",
1306
+ "description": "A mixed month-end statement includes an item with no corresponding ledger entry. The proposal remains a review aid and cannot post.",
1307
+ "period": "July 2026",
1308
+ "inputs": {
1309
+ "bank_cont": {
1310
+ "data": [
1311
+ 0.443437397480011,
1312
+ 0.0,
1313
+ 1.0,
1314
+ 0.31825539469718933,
1315
+ -0.13333334028720856,
1316
+ 1.0,
1317
+ 0.7283854484558105,
1318
+ -0.8666666746139526,
1319
+ 1.0,
1320
+ -0.3498953878879547,
1321
+ 0.20000000298023224,
1322
+ -1.0,
1323
+ 0.7850978970527649,
1324
+ 0.6000000238418579,
1325
+ 1.0,
1326
+ -0.49646052718162537,
1327
+ -0.9333333373069763,
1328
+ -1.0,
1329
+ 0.5367476940155029,
1330
+ 0.800000011920929,
1331
+ 1.0,
1332
+ 0.581236720085144,
1333
+ 0.13333334028720856,
1334
+ 1.0,
1335
+ -0.15571896731853485,
1336
+ 0.800000011920929,
1337
+ -1.0,
1338
+ 0.0,
1339
+ 0.0,
1340
+ 0.0,
1341
+ 0.0,
1342
+ 0.0,
1343
+ 0.0,
1344
+ 0.0,
1345
+ 0.0,
1346
+ 0.0,
1347
+ 0.0,
1348
+ 0.0,
1349
+ 0.0,
1350
+ 0.0,
1351
+ 0.0,
1352
+ 0.0,
1353
+ 0.0,
1354
+ 0.0,
1355
+ 0.0,
1356
+ 0.0,
1357
+ 0.0,
1358
+ 0.0,
1359
+ 0.0,
1360
+ 0.0,
1361
+ 0.0,
1362
+ 0.0,
1363
+ 0.0,
1364
+ 0.0,
1365
+ 0.0,
1366
+ 0.0,
1367
+ 0.0,
1368
+ 0.0,
1369
+ 0.0,
1370
+ 0.0,
1371
+ 0.0,
1372
+ 0.0,
1373
+ 0.0,
1374
+ 0.0,
1375
+ 0.0,
1376
+ 0.0,
1377
+ 0.0,
1378
+ 0.0,
1379
+ 0.0,
1380
+ 0.0,
1381
+ 0.0,
1382
+ 0.0
1383
+ ],
1384
+ "dims": [
1385
+ 1,
1386
+ 24,
1387
+ 3
1388
+ ]
1389
+ },
1390
+ "gl_cont": {
1391
+ "data": [
1392
+ 0.7850978970527649,
1393
+ 0.4000000059604645,
1394
+ 1.0,
1395
+ 0.7283854484558105,
1396
+ -0.800000011920929,
1397
+ 1.0,
1398
+ 0.31825539469718933,
1399
+ 0.06666667014360428,
1400
+ 1.0,
1401
+ -0.3498953878879547,
1402
+ 0.20000000298023224,
1403
+ -1.0,
1404
+ -0.49646052718162537,
1405
+ -0.9333333373069763,
1406
+ -1.0,
1407
+ 0.443437397480011,
1408
+ 0.20000000298023224,
1409
+ 1.0,
1410
+ 0.5367476940155029,
1411
+ 0.800000011920929,
1412
+ 1.0,
1413
+ 0.581236720085144,
1414
+ 0.13333334028720856,
1415
+ 1.0,
1416
+ 0.39781689643859863,
1417
+ -0.8666666746139526,
1418
+ 1.0,
1419
+ 0.0,
1420
+ 0.0,
1421
+ 0.0,
1422
+ 0.0,
1423
+ 0.0,
1424
+ 0.0,
1425
+ 0.0,
1426
+ 0.0,
1427
+ 0.0,
1428
+ 0.0,
1429
+ 0.0,
1430
+ 0.0,
1431
+ 0.0,
1432
+ 0.0,
1433
+ 0.0,
1434
+ 0.0,
1435
+ 0.0,
1436
+ 0.0,
1437
+ 0.0,
1438
+ 0.0,
1439
+ 0.0,
1440
+ 0.0,
1441
+ 0.0,
1442
+ 0.0,
1443
+ 0.0,
1444
+ 0.0,
1445
+ 0.0,
1446
+ 0.0,
1447
+ 0.0,
1448
+ 0.0,
1449
+ 0.0,
1450
+ 0.0,
1451
+ 0.0,
1452
+ 0.0,
1453
+ 0.0,
1454
+ 0.0,
1455
+ 0.0,
1456
+ 0.0,
1457
+ 0.0,
1458
+ 0.0,
1459
+ 0.0,
1460
+ 0.0,
1461
+ 0.0,
1462
+ 0.0,
1463
+ 0.0
1464
+ ],
1465
+ "dims": [
1466
+ 1,
1467
+ 24,
1468
+ 3
1469
+ ]
1470
+ },
1471
+ "bank_cat": {
1472
+ "data": [
1473
+ 2,
1474
+ 1,
1475
+ 10,
1476
+ 54,
1477
+ 6870,
1478
+ 81,
1479
+ 2,
1480
+ 2,
1481
+ 8,
1482
+ 7,
1483
+ 4528,
1484
+ 195,
1485
+ 2,
1486
+ 3,
1487
+ 16,
1488
+ 25,
1489
+ 6517,
1490
+ 175,
1491
+ 3,
1492
+ 2,
1493
+ 12,
1494
+ 36,
1495
+ 7942,
1496
+ 46,
1497
+ 3,
1498
+ 1,
1499
+ 7,
1500
+ 33,
1501
+ 6216,
1502
+ 32,
1503
+ 2,
1504
+ 1,
1505
+ 11,
1506
+ 81,
1507
+ 4520,
1508
+ 32,
1509
+ 2,
1510
+ 2,
1511
+ 24,
1512
+ 78,
1513
+ 1,
1514
+ 153,
1515
+ 1,
1516
+ 3,
1517
+ 20,
1518
+ 42,
1519
+ 7247,
1520
+ 161,
1521
+ 2,
1522
+ 2,
1523
+ 24,
1524
+ 78,
1525
+ 1,
1526
+ 25,
1527
+ 0,
1528
+ 0,
1529
+ 0,
1530
+ 0,
1531
+ 0,
1532
+ 0,
1533
+ 0,
1534
+ 0,
1535
+ 0,
1536
+ 0,
1537
+ 0,
1538
+ 0,
1539
+ 0,
1540
+ 0,
1541
+ 0,
1542
+ 0,
1543
+ 0,
1544
+ 0,
1545
+ 0,
1546
+ 0,
1547
+ 0,
1548
+ 0,
1549
+ 0,
1550
+ 0,
1551
+ 0,
1552
+ 0,
1553
+ 0,
1554
+ 0,
1555
+ 0,
1556
+ 0,
1557
+ 0,
1558
+ 0,
1559
+ 0,
1560
+ 0,
1561
+ 0,
1562
+ 0,
1563
+ 0,
1564
+ 0,
1565
+ 0,
1566
+ 0,
1567
+ 0,
1568
+ 0,
1569
+ 0,
1570
+ 0,
1571
+ 0,
1572
+ 0,
1573
+ 0,
1574
+ 0,
1575
+ 0,
1576
+ 0,
1577
+ 0,
1578
+ 0,
1579
+ 0,
1580
+ 0,
1581
+ 0,
1582
+ 0,
1583
+ 0,
1584
+ 0,
1585
+ 0,
1586
+ 0,
1587
+ 0,
1588
+ 0,
1589
+ 0,
1590
+ 0,
1591
+ 0,
1592
+ 0,
1593
+ 0,
1594
+ 0,
1595
+ 0,
1596
+ 0,
1597
+ 0,
1598
+ 0,
1599
+ 0,
1600
+ 0,
1601
+ 0,
1602
+ 0,
1603
+ 0,
1604
+ 0,
1605
+ 0,
1606
+ 0,
1607
+ 0,
1608
+ 0,
1609
+ 0,
1610
+ 0,
1611
+ 0,
1612
+ 0,
1613
+ 0,
1614
+ 0,
1615
+ 0,
1616
+ 0
1617
+ ],
1618
+ "dims": [
1619
+ 1,
1620
+ 24,
1621
+ 6
1622
+ ]
1623
+ },
1624
+ "gl_cat": {
1625
+ "data": [
1626
+ 3,
1627
+ 1,
1628
+ 14,
1629
+ 33,
1630
+ 1821,
1631
+ 32,
1632
+ 2,
1633
+ 3,
1634
+ 23,
1635
+ 25,
1636
+ 6517,
1637
+ 175,
1638
+ 2,
1639
+ 2,
1640
+ 24,
1641
+ 7,
1642
+ 5852,
1643
+ 195,
1644
+ 3,
1645
+ 2,
1646
+ 18,
1647
+ 36,
1648
+ 7942,
1649
+ 46,
1650
+ 2,
1651
+ 1,
1652
+ 18,
1653
+ 81,
1654
+ 4520,
1655
+ 32,
1656
+ 2,
1657
+ 1,
1658
+ 19,
1659
+ 54,
1660
+ 1629,
1661
+ 146,
1662
+ 2,
1663
+ 2,
1664
+ 13,
1665
+ 78,
1666
+ 7295,
1667
+ 153,
1668
+ 1,
1669
+ 3,
1670
+ 7,
1671
+ 42,
1672
+ 1,
1673
+ 128,
1674
+ 3,
1675
+ 4,
1676
+ 5,
1677
+ 74,
1678
+ 1,
1679
+ 75,
1680
+ 0,
1681
+ 0,
1682
+ 0,
1683
+ 0,
1684
+ 0,
1685
+ 0,
1686
+ 0,
1687
+ 0,
1688
+ 0,
1689
+ 0,
1690
+ 0,
1691
+ 0,
1692
+ 0,
1693
+ 0,
1694
+ 0,
1695
+ 0,
1696
+ 0,
1697
+ 0,
1698
+ 0,
1699
+ 0,
1700
+ 0,
1701
+ 0,
1702
+ 0,
1703
+ 0,
1704
+ 0,
1705
+ 0,
1706
+ 0,
1707
+ 0,
1708
+ 0,
1709
+ 0,
1710
+ 0,
1711
+ 0,
1712
+ 0,
1713
+ 0,
1714
+ 0,
1715
+ 0,
1716
+ 0,
1717
+ 0,
1718
+ 0,
1719
+ 0,
1720
+ 0,
1721
+ 0,
1722
+ 0,
1723
+ 0,
1724
+ 0,
1725
+ 0,
1726
+ 0,
1727
+ 0,
1728
+ 0,
1729
+ 0,
1730
+ 0,
1731
+ 0,
1732
+ 0,
1733
+ 0,
1734
+ 0,
1735
+ 0,
1736
+ 0,
1737
+ 0,
1738
+ 0,
1739
+ 0,
1740
+ 0,
1741
+ 0,
1742
+ 0,
1743
+ 0,
1744
+ 0,
1745
+ 0,
1746
+ 0,
1747
+ 0,
1748
+ 0,
1749
+ 0,
1750
+ 0,
1751
+ 0,
1752
+ 0,
1753
+ 0,
1754
+ 0,
1755
+ 0,
1756
+ 0,
1757
+ 0,
1758
+ 0,
1759
+ 0,
1760
+ 0,
1761
+ 0,
1762
+ 0,
1763
+ 0,
1764
+ 0,
1765
+ 0,
1766
+ 0,
1767
+ 0,
1768
+ 0,
1769
+ 0
1770
+ ],
1771
+ "dims": [
1772
+ 1,
1773
+ 24,
1774
+ 6
1775
+ ]
1776
+ },
1777
+ "bank_mask": {
1778
+ "data": [
1779
+ true,
1780
+ true,
1781
+ true,
1782
+ true,
1783
+ true,
1784
+ true,
1785
+ true,
1786
+ true,
1787
+ true,
1788
+ false,
1789
+ false,
1790
+ false,
1791
+ false,
1792
+ false,
1793
+ false,
1794
+ false,
1795
+ false,
1796
+ false,
1797
+ false,
1798
+ false,
1799
+ false,
1800
+ false,
1801
+ false,
1802
+ false
1803
+ ],
1804
+ "dims": [
1805
+ 1,
1806
+ 24
1807
+ ]
1808
+ },
1809
+ "gl_mask": {
1810
+ "data": [
1811
+ true,
1812
+ true,
1813
+ true,
1814
+ true,
1815
+ true,
1816
+ true,
1817
+ true,
1818
+ true,
1819
+ true,
1820
+ false,
1821
+ false,
1822
+ false,
1823
+ false,
1824
+ false,
1825
+ false,
1826
+ false,
1827
+ false,
1828
+ false,
1829
+ false,
1830
+ false,
1831
+ false,
1832
+ false,
1833
+ false,
1834
+ false
1835
+ ],
1836
+ "dims": [
1837
+ 1,
1838
+ 24
1839
+ ]
1840
+ },
1841
+ "candidate_mask": {
1842
+ "data": [
1843
+ false,
1844
+ false,
1845
+ false,
1846
+ false,
1847
+ false,
1848
+ true,
1849
+ false,
1850
+ false,
1851
+ false,
1852
+ false,
1853
+ false,
1854
+ false,
1855
+ false,
1856
+ false,
1857
+ false,
1858
+ false,
1859
+ false,
1860
+ false,
1861
+ false,
1862
+ false,
1863
+ false,
1864
+ false,
1865
+ false,
1866
+ false,
1867
+ false,
1868
+ false,
1869
+ true,
1870
+ false,
1871
+ false,
1872
+ false,
1873
+ false,
1874
+ false,
1875
+ false,
1876
+ false,
1877
+ false,
1878
+ false,
1879
+ false,
1880
+ false,
1881
+ false,
1882
+ false,
1883
+ false,
1884
+ false,
1885
+ false,
1886
+ false,
1887
+ false,
1888
+ false,
1889
+ false,
1890
+ false,
1891
+ false,
1892
+ true,
1893
+ false,
1894
+ false,
1895
+ false,
1896
+ false,
1897
+ false,
1898
+ false,
1899
+ false,
1900
+ false,
1901
+ false,
1902
+ false,
1903
+ false,
1904
+ false,
1905
+ false,
1906
+ false,
1907
+ false,
1908
+ false,
1909
+ false,
1910
+ false,
1911
+ false,
1912
+ false,
1913
+ false,
1914
+ false,
1915
+ false,
1916
+ false,
1917
+ false,
1918
+ true,
1919
+ false,
1920
+ false,
1921
+ false,
1922
+ false,
1923
+ false,
1924
+ false,
1925
+ false,
1926
+ false,
1927
+ false,
1928
+ false,
1929
+ false,
1930
+ false,
1931
+ false,
1932
+ false,
1933
+ false,
1934
+ false,
1935
+ false,
1936
+ false,
1937
+ false,
1938
+ false,
1939
+ true,
1940
+ false,
1941
+ false,
1942
+ false,
1943
+ false,
1944
+ false,
1945
+ false,
1946
+ false,
1947
+ false,
1948
+ false,
1949
+ false,
1950
+ false,
1951
+ false,
1952
+ false,
1953
+ false,
1954
+ false,
1955
+ false,
1956
+ false,
1957
+ false,
1958
+ false,
1959
+ false,
1960
+ false,
1961
+ false,
1962
+ false,
1963
+ false,
1964
+ false,
1965
+ false,
1966
+ false,
1967
+ true,
1968
+ false,
1969
+ false,
1970
+ false,
1971
+ false,
1972
+ false,
1973
+ false,
1974
+ false,
1975
+ false,
1976
+ false,
1977
+ false,
1978
+ false,
1979
+ false,
1980
+ false,
1981
+ false,
1982
+ false,
1983
+ false,
1984
+ false,
1985
+ false,
1986
+ false,
1987
+ false,
1988
+ false,
1989
+ false,
1990
+ false,
1991
+ false,
1992
+ false,
1993
+ true,
1994
+ false,
1995
+ false,
1996
+ false,
1997
+ false,
1998
+ false,
1999
+ false,
2000
+ false,
2001
+ false,
2002
+ false,
2003
+ false,
2004
+ false,
2005
+ false,
2006
+ false,
2007
+ false,
2008
+ false,
2009
+ false,
2010
+ false,
2011
+ false,
2012
+ false,
2013
+ false,
2014
+ false,
2015
+ false,
2016
+ false,
2017
+ false,
2018
+ true,
2019
+ false,
2020
+ false,
2021
+ false,
2022
+ false,
2023
+ false,
2024
+ false,
2025
+ false,
2026
+ false,
2027
+ false,
2028
+ false,
2029
+ false,
2030
+ false,
2031
+ false,
2032
+ false,
2033
+ false,
2034
+ false,
2035
+ false,
2036
+ false,
2037
+ false,
2038
+ false,
2039
+ false,
2040
+ false,
2041
+ false,
2042
+ false,
2043
+ false,
2044
+ false,
2045
+ false,
2046
+ false,
2047
+ false,
2048
+ false,
2049
+ false,
2050
+ false,
2051
+ false,
2052
+ false,
2053
+ false,
2054
+ false,
2055
+ false,
2056
+ false,
2057
+ false,
2058
+ false,
2059
+ false,
2060
+ false,
2061
+ false,
2062
+ false,
2063
+ false,
2064
+ false,
2065
+ false,
2066
+ false,
2067
+ false,
2068
+ false,
2069
+ false,
2070
+ false,
2071
+ false,
2072
+ false,
2073
+ false,
2074
+ false,
2075
+ false,
2076
+ false,
2077
+ false,
2078
+ false,
2079
+ false,
2080
+ false,
2081
+ false,
2082
+ false,
2083
+ false,
2084
+ false,
2085
+ false,
2086
+ false,
2087
+ false,
2088
+ false,
2089
+ false,
2090
+ false,
2091
+ false,
2092
+ false,
2093
+ false,
2094
+ false,
2095
+ false,
2096
+ false,
2097
+ false,
2098
+ false,
2099
+ false,
2100
+ false,
2101
+ false,
2102
+ false,
2103
+ false,
2104
+ false,
2105
+ false,
2106
+ false,
2107
+ false,
2108
+ false,
2109
+ false,
2110
+ false,
2111
+ false,
2112
+ false,
2113
+ false,
2114
+ false,
2115
+ false,
2116
+ false,
2117
+ false,
2118
+ false,
2119
+ false,
2120
+ false,
2121
+ false,
2122
+ false,
2123
+ false,
2124
+ false,
2125
+ false,
2126
+ false,
2127
+ false,
2128
+ false,
2129
+ false,
2130
+ false,
2131
+ false,
2132
+ false,
2133
+ false,
2134
+ false,
2135
+ false,
2136
+ false,
2137
+ false,
2138
+ false,
2139
+ false,
2140
+ false,
2141
+ false,
2142
+ false,
2143
+ false,
2144
+ false,
2145
+ false,
2146
+ false,
2147
+ false,
2148
+ false,
2149
+ false,
2150
+ false,
2151
+ false,
2152
+ false,
2153
+ false,
2154
+ false,
2155
+ false,
2156
+ false,
2157
+ false,
2158
+ false,
2159
+ false,
2160
+ false,
2161
+ false,
2162
+ false,
2163
+ false,
2164
+ false,
2165
+ false,
2166
+ false,
2167
+ false,
2168
+ false,
2169
+ false,
2170
+ false,
2171
+ false,
2172
+ false,
2173
+ false,
2174
+ false,
2175
+ false,
2176
+ false,
2177
+ false,
2178
+ false,
2179
+ false,
2180
+ false,
2181
+ false,
2182
+ false,
2183
+ false,
2184
+ false,
2185
+ false,
2186
+ false,
2187
+ false,
2188
+ false,
2189
+ false,
2190
+ false,
2191
+ false,
2192
+ false,
2193
+ false,
2194
+ false,
2195
+ false,
2196
+ false,
2197
+ false,
2198
+ false,
2199
+ false,
2200
+ false,
2201
+ false,
2202
+ false,
2203
+ false,
2204
+ false,
2205
+ false,
2206
+ false,
2207
+ false,
2208
+ false,
2209
+ false,
2210
+ false,
2211
+ false,
2212
+ false,
2213
+ false,
2214
+ false,
2215
+ false,
2216
+ false,
2217
+ false,
2218
+ false,
2219
+ false,
2220
+ false,
2221
+ false,
2222
+ false,
2223
+ false,
2224
+ false,
2225
+ false,
2226
+ false,
2227
+ false,
2228
+ false,
2229
+ false,
2230
+ false,
2231
+ false,
2232
+ false,
2233
+ false,
2234
+ false,
2235
+ false,
2236
+ false,
2237
+ false,
2238
+ false,
2239
+ false,
2240
+ false,
2241
+ false,
2242
+ false,
2243
+ false,
2244
+ false,
2245
+ false,
2246
+ false,
2247
+ false,
2248
+ false,
2249
+ false,
2250
+ false,
2251
+ false,
2252
+ false,
2253
+ false,
2254
+ false,
2255
+ false,
2256
+ false,
2257
+ false,
2258
+ false,
2259
+ false,
2260
+ false,
2261
+ false,
2262
+ false,
2263
+ false,
2264
+ false,
2265
+ false,
2266
+ false,
2267
+ false,
2268
+ false,
2269
+ false,
2270
+ false,
2271
+ false,
2272
+ false,
2273
+ false,
2274
+ false,
2275
+ false,
2276
+ false,
2277
+ false,
2278
+ false,
2279
+ false,
2280
+ false,
2281
+ false,
2282
+ false,
2283
+ false,
2284
+ false,
2285
+ false,
2286
+ false,
2287
+ false,
2288
+ false,
2289
+ false,
2290
+ false,
2291
+ false,
2292
+ false,
2293
+ false,
2294
+ false,
2295
+ false,
2296
+ false,
2297
+ false,
2298
+ false,
2299
+ false,
2300
+ false,
2301
+ false,
2302
+ false,
2303
+ false,
2304
+ false,
2305
+ false,
2306
+ false,
2307
+ false,
2308
+ false,
2309
+ false,
2310
+ false,
2311
+ false,
2312
+ false,
2313
+ false,
2314
+ false,
2315
+ false,
2316
+ false,
2317
+ false,
2318
+ false,
2319
+ false,
2320
+ false,
2321
+ false,
2322
+ false,
2323
+ false,
2324
+ false,
2325
+ false,
2326
+ false,
2327
+ false,
2328
+ false,
2329
+ false,
2330
+ false,
2331
+ false,
2332
+ false,
2333
+ false,
2334
+ false,
2335
+ false,
2336
+ false,
2337
+ false,
2338
+ false,
2339
+ false,
2340
+ false,
2341
+ false,
2342
+ false,
2343
+ false,
2344
+ false,
2345
+ false,
2346
+ false,
2347
+ false,
2348
+ false,
2349
+ false,
2350
+ false,
2351
+ false,
2352
+ false,
2353
+ false,
2354
+ false,
2355
+ false,
2356
+ false,
2357
+ false,
2358
+ false,
2359
+ false,
2360
+ false,
2361
+ false,
2362
+ false,
2363
+ false,
2364
+ false,
2365
+ false,
2366
+ false,
2367
+ false,
2368
+ false,
2369
+ false,
2370
+ false,
2371
+ false,
2372
+ false,
2373
+ false,
2374
+ false,
2375
+ false,
2376
+ false,
2377
+ false,
2378
+ false,
2379
+ false,
2380
+ false,
2381
+ false,
2382
+ false,
2383
+ false,
2384
+ false,
2385
+ false,
2386
+ false,
2387
+ false,
2388
+ false,
2389
+ false,
2390
+ false,
2391
+ false,
2392
+ false,
2393
+ false,
2394
+ false,
2395
+ false,
2396
+ false,
2397
+ false,
2398
+ false,
2399
+ false,
2400
+ false,
2401
+ false,
2402
+ false,
2403
+ false,
2404
+ false,
2405
+ false,
2406
+ false,
2407
+ false,
2408
+ false,
2409
+ false,
2410
+ false,
2411
+ false,
2412
+ false,
2413
+ false,
2414
+ false,
2415
+ false,
2416
+ false,
2417
+ false,
2418
+ false
2419
+ ],
2420
+ "dims": [
2421
+ 1,
2422
+ 24,
2423
+ 24
2424
+ ]
2425
+ }
2426
+ },
2427
+ "display": {
2428
+ "bank_rows": [
2429
+ {
2430
+ "id": "BANK-BANK-FEE-01",
2431
+ "date": "2026-07-16",
2432
+ "amount": 88.17,
2433
+ "currency": "EUR",
2434
+ "entity": "Northstar Studio LLC",
2435
+ "reference": "PAY-06870",
2436
+ "narrative": "Supplier payment \u00b7 Granite Software"
2437
+ },
2438
+ {
2439
+ "id": "BANK-BANK-FEE-02",
2440
+ "date": "2026-07-14",
2441
+ "amount": 24.1,
2442
+ "currency": "EUR",
2443
+ "entity": "Northstar Services LLC",
2444
+ "reference": "PAY-04528",
2445
+ "narrative": "Card settlement \u00b7 Harbor Utilities"
2446
+ },
2447
+ {
2448
+ "id": "BANK-BANK-FEE-03",
2449
+ "date": "2026-07-03",
2450
+ "amount": 1596.38,
2451
+ "currency": "EUR",
2452
+ "entity": "Northstar Retail LLC",
2453
+ "reference": "PAY-06517",
2454
+ "narrative": "Operating expense \u00b7 Beacon Telecom"
2455
+ },
2456
+ {
2457
+ "id": "BANK-BANK-FEE-04",
2458
+ "date": "2026-07-19",
2459
+ "amount": -33.58,
2460
+ "currency": "GBP",
2461
+ "entity": "Northstar Services LLC",
2462
+ "reference": "PAY-07942",
2463
+ "narrative": "Intercompany transfer \u00b7 Ember Insurance"
2464
+ },
2465
+ {
2466
+ "id": "BANK-BANK-FEE-05",
2467
+ "date": "2026-07-25",
2468
+ "amount": 2835.79,
2469
+ "currency": "GBP",
2470
+ "entity": "Northstar Studio LLC",
2471
+ "reference": "PAY-06216",
2472
+ "narrative": "Customer receipt \u00b7 Beacon Telecom"
2473
+ },
2474
+ {
2475
+ "id": "BANK-BANK-FEE-06",
2476
+ "date": "2026-07-02",
2477
+ "amount": -151.55,
2478
+ "currency": "EUR",
2479
+ "entity": "Northstar Studio LLC",
2480
+ "reference": "PAY-04520",
2481
+ "narrative": "Customer receipt \u00b7 Beacon Telecom"
2482
+ },
2483
+ {
2484
+ "id": "BANK-BANK-FEE-07",
2485
+ "date": "2026-07-28",
2486
+ "amount": 228.4,
2487
+ "currency": "EUR",
2488
+ "entity": "Northstar Services LLC",
2489
+ "reference": "\u2014",
2490
+ "narrative": "Supplier payment \u00b7 Granite Software"
2491
+ },
2492
+ {
2493
+ "id": "BANK-BANK-FEE-08",
2494
+ "date": "2026-07-18",
2495
+ "amount": 358.96,
2496
+ "currency": "USD",
2497
+ "entity": "Northstar Retail LLC",
2498
+ "reference": "PAY-07247",
2499
+ "narrative": "Supplier payment \u00b7 Cedar Payroll"
2500
+ },
2501
+ {
2502
+ "id": "BANK-BANK-FEE-09",
2503
+ "date": "2026-07-28",
2504
+ "amount": -3.84,
2505
+ "currency": "EUR",
2506
+ "entity": "Northstar Services LLC",
2507
+ "reference": "\u2014",
2508
+ "narrative": "Supplier payment \u00b7 Granite Software"
2509
+ }
2510
+ ],
2511
+ "gl_rows": [
2512
+ {
2513
+ "id": "GL-BANK-FEE-01",
2514
+ "date": "2026-07-22",
2515
+ "amount": 2835.79,
2516
+ "currency": "GBP",
2517
+ "entity": "Northstar Studio LLC",
2518
+ "reference": "PAY-01821",
2519
+ "narrative": "Customer receipt \u00b7 Beacon Telecom"
2520
+ },
2521
+ {
2522
+ "id": "GL-BANK-FEE-02",
2523
+ "date": "2026-07-04",
2524
+ "amount": 1596.38,
2525
+ "currency": "EUR",
2526
+ "entity": "Northstar Retail LLC",
2527
+ "reference": "PAY-06517",
2528
+ "narrative": "Operating expense \u00b7 Beacon Telecom"
2529
+ },
2530
+ {
2531
+ "id": "GL-BANK-FEE-03",
2532
+ "date": "2026-07-17",
2533
+ "amount": 24.1,
2534
+ "currency": "EUR",
2535
+ "entity": "Northstar Services LLC",
2536
+ "reference": "PAY-05852",
2537
+ "narrative": "Card settlement \u00b7 Harbor Utilities"
2538
+ },
2539
+ {
2540
+ "id": "GL-BANK-FEE-04",
2541
+ "date": "2026-07-19",
2542
+ "amount": -33.58,
2543
+ "currency": "GBP",
2544
+ "entity": "Northstar Services LLC",
2545
+ "reference": "PAY-07942",
2546
+ "narrative": "Intercompany transfer \u00b7 Ember Insurance"
2547
+ },
2548
+ {
2549
+ "id": "GL-BANK-FEE-05",
2550
+ "date": "2026-07-02",
2551
+ "amount": -151.55,
2552
+ "currency": "EUR",
2553
+ "entity": "Northstar Studio LLC",
2554
+ "reference": "PAY-04520",
2555
+ "narrative": "Customer receipt \u00b7 Beacon Telecom"
2556
+ },
2557
+ {
2558
+ "id": "GL-BANK-FEE-06",
2559
+ "date": "2026-07-19",
2560
+ "amount": 88.17,
2561
+ "currency": "EUR",
2562
+ "entity": "Northstar Studio LLC",
2563
+ "reference": "PAY-01629",
2564
+ "narrative": "Payroll settlement \u00b7 Granite Software"
2565
+ },
2566
+ {
2567
+ "id": "GL-BANK-FEE-07",
2568
+ "date": "2026-07-28",
2569
+ "amount": 228.4,
2570
+ "currency": "EUR",
2571
+ "entity": "Northstar Services LLC",
2572
+ "reference": "PAY-07295",
2573
+ "narrative": "Supplier payment \u00b7 Granite Software"
2574
+ },
2575
+ {
2576
+ "id": "GL-BANK-FEE-08",
2577
+ "date": "2026-07-18",
2578
+ "amount": 358.96,
2579
+ "currency": "USD",
2580
+ "entity": "Northstar Retail LLC",
2581
+ "reference": "\u2014",
2582
+ "narrative": "Customer receipt \u00b7 Cedar Payroll"
2583
+ },
2584
+ {
2585
+ "id": "GL-BANK-FEE-09",
2586
+ "date": "2026-07-03",
2587
+ "amount": 55.18,
2588
+ "currency": "GBP",
2589
+ "entity": "Northstar Holdings LLC",
2590
+ "reference": "\u2014",
2591
+ "narrative": "Card settlement \u00b7 Cedar Payroll"
2592
+ }
2593
+ ]
2594
+ },
2595
+ "truth": {
2596
+ "bank_to_gl": [
2597
+ 5,
2598
+ 2,
2599
+ 1,
2600
+ 3,
2601
+ 0,
2602
+ 4,
2603
+ 6,
2604
+ 7,
2605
+ -1
2606
+ ],
2607
+ "exceptions": [
2608
+ "MATCHED",
2609
+ "MATCHED",
2610
+ "MATCHED",
2611
+ "MATCHED",
2612
+ "MATCHED",
2613
+ "MATCHED",
2614
+ "MATCHED",
2615
+ "MATCHED",
2616
+ "BANK_FEE"
2617
+ ]
2618
+ }
2619
+ },
2620
+ {
2621
+ "id": "reference-light",
2622
+ "label": "References are missing",
2623
+ "kicker": "STRESS TEST",
2624
+ "description": "Payment references have been removed from both sides. The model must lean on amount, date, entity and the full one-to-one puzzle.",
2625
+ "period": "July 2026",
2626
+ "inputs": {
2627
+ "bank_cont": {
2628
+ "data": [
2629
+ 0.1820656806230545,
2630
+ 0.20000000298023224,
2631
+ 1.0,
2632
+ 0.3928423523902893,
2633
+ 0.4000000059604645,
2634
+ 1.0,
2635
+ 0.2593981921672821,
2636
+ 0.20000000298023224,
2637
+ 1.0,
2638
+ -0.7501629590988159,
2639
+ 0.06666667014360428,
2640
+ -1.0,
2641
+ 0.46272146701812744,
2642
+ -0.20000000298023224,
2643
+ 1.0,
2644
+ -0.09548881649971008,
2645
+ -0.06666667014360428,
2646
+ -1.0,
2647
+ -0.868613064289093,
2648
+ -0.20000000298023224,
2649
+ -1.0,
2650
+ 0.3065752387046814,
2651
+ -0.800000011920929,
2652
+ 1.0,
2653
+ 0.0,
2654
+ 0.0,
2655
+ 0.0,
2656
+ 0.0,
2657
+ 0.0,
2658
+ 0.0,
2659
+ 0.0,
2660
+ 0.0,
2661
+ 0.0,
2662
+ 0.0,
2663
+ 0.0,
2664
+ 0.0,
2665
+ 0.0,
2666
+ 0.0,
2667
+ 0.0,
2668
+ 0.0,
2669
+ 0.0,
2670
+ 0.0,
2671
+ 0.0,
2672
+ 0.0,
2673
+ 0.0,
2674
+ 0.0,
2675
+ 0.0,
2676
+ 0.0,
2677
+ 0.0,
2678
+ 0.0,
2679
+ 0.0,
2680
+ 0.0,
2681
+ 0.0,
2682
+ 0.0,
2683
+ 0.0,
2684
+ 0.0,
2685
+ 0.0,
2686
+ 0.0,
2687
+ 0.0,
2688
+ 0.0,
2689
+ 0.0,
2690
+ 0.0,
2691
+ 0.0,
2692
+ 0.0,
2693
+ 0.0,
2694
+ 0.0,
2695
+ 0.0,
2696
+ 0.0,
2697
+ 0.0,
2698
+ 0.0,
2699
+ 0.0,
2700
+ 0.0
2701
+ ],
2702
+ "dims": [
2703
+ 1,
2704
+ 24,
2705
+ 3
2706
+ ]
2707
+ },
2708
+ "gl_cont": {
2709
+ "data": [
2710
+ 0.46272146701812744,
2711
+ -0.06666667014360428,
2712
+ 1.0,
2713
+ 0.1820656806230545,
2714
+ 0.20000000298023224,
2715
+ 1.0,
2716
+ 0.3928423523902893,
2717
+ 0.3333333432674408,
2718
+ 1.0,
2719
+ 0.9003928899765015,
2720
+ 1.0,
2721
+ 1.0,
2722
+ 0.3065752387046814,
2723
+ -0.7333333492279053,
2724
+ 1.0,
2725
+ 0.2593981921672821,
2726
+ 0.20000000298023224,
2727
+ 1.0,
2728
+ 0.0,
2729
+ 0.0,
2730
+ 0.0,
2731
+ 0.0,
2732
+ 0.0,
2733
+ 0.0,
2734
+ 0.0,
2735
+ 0.0,
2736
+ 0.0,
2737
+ 0.0,
2738
+ 0.0,
2739
+ 0.0,
2740
+ 0.0,
2741
+ 0.0,
2742
+ 0.0,
2743
+ 0.0,
2744
+ 0.0,
2745
+ 0.0,
2746
+ 0.0,
2747
+ 0.0,
2748
+ 0.0,
2749
+ 0.0,
2750
+ 0.0,
2751
+ 0.0,
2752
+ 0.0,
2753
+ 0.0,
2754
+ 0.0,
2755
+ 0.0,
2756
+ 0.0,
2757
+ 0.0,
2758
+ 0.0,
2759
+ 0.0,
2760
+ 0.0,
2761
+ 0.0,
2762
+ 0.0,
2763
+ 0.0,
2764
+ 0.0,
2765
+ 0.0,
2766
+ 0.0,
2767
+ 0.0,
2768
+ 0.0,
2769
+ 0.0,
2770
+ 0.0,
2771
+ 0.0,
2772
+ 0.0,
2773
+ 0.0,
2774
+ 0.0,
2775
+ 0.0,
2776
+ 0.0,
2777
+ 0.0,
2778
+ 0.0,
2779
+ 0.0,
2780
+ 0.0,
2781
+ 0.0
2782
+ ],
2783
+ "dims": [
2784
+ 1,
2785
+ 24,
2786
+ 3
2787
+ ]
2788
+ },
2789
+ "bank_cat": {
2790
+ "data": [
2791
+ 2,
2792
+ 2,
2793
+ 2,
2794
+ 6,
2795
+ 1,
2796
+ 92,
2797
+ 2,
2798
+ 1,
2799
+ 3,
2800
+ 51,
2801
+ 1,
2802
+ 37,
2803
+ 1,
2804
+ 2,
2805
+ 10,
2806
+ 49,
2807
+ 1,
2808
+ 78,
2809
+ 2,
2810
+ 1,
2811
+ 5,
2812
+ 79,
2813
+ 1,
2814
+ 143,
2815
+ 3,
2816
+ 4,
2817
+ 4,
2818
+ 64,
2819
+ 1,
2820
+ 240,
2821
+ 3,
2822
+ 4,
2823
+ 4,
2824
+ 64,
2825
+ 1,
2826
+ 184,
2827
+ 3,
2828
+ 1,
2829
+ 18,
2830
+ 60,
2831
+ 1,
2832
+ 51,
2833
+ 3,
2834
+ 4,
2835
+ 22,
2836
+ 92,
2837
+ 1,
2838
+ 209,
2839
+ 0,
2840
+ 0,
2841
+ 0,
2842
+ 0,
2843
+ 0,
2844
+ 0,
2845
+ 0,
2846
+ 0,
2847
+ 0,
2848
+ 0,
2849
+ 0,
2850
+ 0,
2851
+ 0,
2852
+ 0,
2853
+ 0,
2854
+ 0,
2855
+ 0,
2856
+ 0,
2857
+ 0,
2858
+ 0,
2859
+ 0,
2860
+ 0,
2861
+ 0,
2862
+ 0,
2863
+ 0,
2864
+ 0,
2865
+ 0,
2866
+ 0,
2867
+ 0,
2868
+ 0,
2869
+ 0,
2870
+ 0,
2871
+ 0,
2872
+ 0,
2873
+ 0,
2874
+ 0,
2875
+ 0,
2876
+ 0,
2877
+ 0,
2878
+ 0,
2879
+ 0,
2880
+ 0,
2881
+ 0,
2882
+ 0,
2883
+ 0,
2884
+ 0,
2885
+ 0,
2886
+ 0,
2887
+ 0,
2888
+ 0,
2889
+ 0,
2890
+ 0,
2891
+ 0,
2892
+ 0,
2893
+ 0,
2894
+ 0,
2895
+ 0,
2896
+ 0,
2897
+ 0,
2898
+ 0,
2899
+ 0,
2900
+ 0,
2901
+ 0,
2902
+ 0,
2903
+ 0,
2904
+ 0,
2905
+ 0,
2906
+ 0,
2907
+ 0,
2908
+ 0,
2909
+ 0,
2910
+ 0,
2911
+ 0,
2912
+ 0,
2913
+ 0,
2914
+ 0,
2915
+ 0,
2916
+ 0,
2917
+ 0,
2918
+ 0,
2919
+ 0,
2920
+ 0,
2921
+ 0,
2922
+ 0,
2923
+ 0,
2924
+ 0,
2925
+ 0,
2926
+ 0,
2927
+ 0,
2928
+ 0,
2929
+ 0,
2930
+ 0,
2931
+ 0,
2932
+ 0,
2933
+ 0,
2934
+ 0
2935
+ ],
2936
+ "dims": [
2937
+ 1,
2938
+ 24,
2939
+ 6
2940
+ ]
2941
+ },
2942
+ "gl_cat": {
2943
+ "data": [
2944
+ 3,
2945
+ 4,
2946
+ 14,
2947
+ 64,
2948
+ 1,
2949
+ 123,
2950
+ 2,
2951
+ 2,
2952
+ 18,
2953
+ 6,
2954
+ 1,
2955
+ 92,
2956
+ 2,
2957
+ 1,
2958
+ 19,
2959
+ 51,
2960
+ 1,
2961
+ 37,
2962
+ 1,
2963
+ 2,
2964
+ 4,
2965
+ 66,
2966
+ 1,
2967
+ 208,
2968
+ 3,
2969
+ 4,
2970
+ 5,
2971
+ 92,
2972
+ 1,
2973
+ 195,
2974
+ 1,
2975
+ 2,
2976
+ 16,
2977
+ 49,
2978
+ 1,
2979
+ 224,
2980
+ 0,
2981
+ 0,
2982
+ 0,
2983
+ 0,
2984
+ 0,
2985
+ 0,
2986
+ 0,
2987
+ 0,
2988
+ 0,
2989
+ 0,
2990
+ 0,
2991
+ 0,
2992
+ 0,
2993
+ 0,
2994
+ 0,
2995
+ 0,
2996
+ 0,
2997
+ 0,
2998
+ 0,
2999
+ 0,
3000
+ 0,
3001
+ 0,
3002
+ 0,
3003
+ 0,
3004
+ 0,
3005
+ 0,
3006
+ 0,
3007
+ 0,
3008
+ 0,
3009
+ 0,
3010
+ 0,
3011
+ 0,
3012
+ 0,
3013
+ 0,
3014
+ 0,
3015
+ 0,
3016
+ 0,
3017
+ 0,
3018
+ 0,
3019
+ 0,
3020
+ 0,
3021
+ 0,
3022
+ 0,
3023
+ 0,
3024
+ 0,
3025
+ 0,
3026
+ 0,
3027
+ 0,
3028
+ 0,
3029
+ 0,
3030
+ 0,
3031
+ 0,
3032
+ 0,
3033
+ 0,
3034
+ 0,
3035
+ 0,
3036
+ 0,
3037
+ 0,
3038
+ 0,
3039
+ 0,
3040
+ 0,
3041
+ 0,
3042
+ 0,
3043
+ 0,
3044
+ 0,
3045
+ 0,
3046
+ 0,
3047
+ 0,
3048
+ 0,
3049
+ 0,
3050
+ 0,
3051
+ 0,
3052
+ 0,
3053
+ 0,
3054
+ 0,
3055
+ 0,
3056
+ 0,
3057
+ 0,
3058
+ 0,
3059
+ 0,
3060
+ 0,
3061
+ 0,
3062
+ 0,
3063
+ 0,
3064
+ 0,
3065
+ 0,
3066
+ 0,
3067
+ 0,
3068
+ 0,
3069
+ 0,
3070
+ 0,
3071
+ 0,
3072
+ 0,
3073
+ 0,
3074
+ 0,
3075
+ 0,
3076
+ 0,
3077
+ 0,
3078
+ 0,
3079
+ 0,
3080
+ 0,
3081
+ 0,
3082
+ 0,
3083
+ 0,
3084
+ 0,
3085
+ 0,
3086
+ 0,
3087
+ 0
3088
+ ],
3089
+ "dims": [
3090
+ 1,
3091
+ 24,
3092
+ 6
3093
+ ]
3094
+ },
3095
+ "bank_mask": {
3096
+ "data": [
3097
+ true,
3098
+ true,
3099
+ true,
3100
+ true,
3101
+ true,
3102
+ true,
3103
+ true,
3104
+ true,
3105
+ false,
3106
+ false,
3107
+ false,
3108
+ false,
3109
+ false,
3110
+ false,
3111
+ false,
3112
+ false,
3113
+ false,
3114
+ false,
3115
+ false,
3116
+ false,
3117
+ false,
3118
+ false,
3119
+ false,
3120
+ false
3121
+ ],
3122
+ "dims": [
3123
+ 1,
3124
+ 24
3125
+ ]
3126
+ },
3127
+ "gl_mask": {
3128
+ "data": [
3129
+ true,
3130
+ true,
3131
+ true,
3132
+ true,
3133
+ true,
3134
+ true,
3135
+ false,
3136
+ false,
3137
+ false,
3138
+ false,
3139
+ false,
3140
+ false,
3141
+ false,
3142
+ false,
3143
+ false,
3144
+ false,
3145
+ false,
3146
+ false,
3147
+ false,
3148
+ false,
3149
+ false,
3150
+ false,
3151
+ false,
3152
+ false
3153
+ ],
3154
+ "dims": [
3155
+ 1,
3156
+ 24
3157
+ ]
3158
+ },
3159
+ "candidate_mask": {
3160
+ "data": [
3161
+ false,
3162
+ true,
3163
+ false,
3164
+ false,
3165
+ false,
3166
+ false,
3167
+ false,
3168
+ false,
3169
+ false,
3170
+ false,
3171
+ false,
3172
+ false,
3173
+ false,
3174
+ false,
3175
+ false,
3176
+ false,
3177
+ false,
3178
+ false,
3179
+ false,
3180
+ false,
3181
+ false,
3182
+ false,
3183
+ false,
3184
+ false,
3185
+ false,
3186
+ false,
3187
+ true,
3188
+ false,
3189
+ false,
3190
+ false,
3191
+ false,
3192
+ false,
3193
+ false,
3194
+ false,
3195
+ false,
3196
+ false,
3197
+ false,
3198
+ false,
3199
+ false,
3200
+ false,
3201
+ false,
3202
+ false,
3203
+ false,
3204
+ false,
3205
+ false,
3206
+ false,
3207
+ false,
3208
+ false,
3209
+ false,
3210
+ false,
3211
+ false,
3212
+ false,
3213
+ false,
3214
+ true,
3215
+ false,
3216
+ false,
3217
+ false,
3218
+ false,
3219
+ false,
3220
+ false,
3221
+ false,
3222
+ false,
3223
+ false,
3224
+ false,
3225
+ false,
3226
+ false,
3227
+ false,
3228
+ false,
3229
+ false,
3230
+ false,
3231
+ false,
3232
+ false,
3233
+ false,
3234
+ false,
3235
+ false,
3236
+ false,
3237
+ false,
3238
+ false,
3239
+ false,
3240
+ false,
3241
+ false,
3242
+ false,
3243
+ false,
3244
+ false,
3245
+ false,
3246
+ false,
3247
+ false,
3248
+ false,
3249
+ false,
3250
+ false,
3251
+ false,
3252
+ false,
3253
+ false,
3254
+ false,
3255
+ false,
3256
+ false,
3257
+ true,
3258
+ false,
3259
+ false,
3260
+ false,
3261
+ false,
3262
+ false,
3263
+ false,
3264
+ false,
3265
+ false,
3266
+ false,
3267
+ false,
3268
+ false,
3269
+ false,
3270
+ false,
3271
+ false,
3272
+ false,
3273
+ false,
3274
+ false,
3275
+ false,
3276
+ false,
3277
+ false,
3278
+ false,
3279
+ false,
3280
+ false,
3281
+ false,
3282
+ false,
3283
+ false,
3284
+ false,
3285
+ false,
3286
+ false,
3287
+ false,
3288
+ false,
3289
+ false,
3290
+ false,
3291
+ false,
3292
+ false,
3293
+ false,
3294
+ false,
3295
+ false,
3296
+ false,
3297
+ false,
3298
+ false,
3299
+ false,
3300
+ false,
3301
+ false,
3302
+ false,
3303
+ false,
3304
+ false,
3305
+ false,
3306
+ false,
3307
+ false,
3308
+ false,
3309
+ false,
3310
+ false,
3311
+ false,
3312
+ false,
3313
+ false,
3314
+ false,
3315
+ false,
3316
+ false,
3317
+ false,
3318
+ false,
3319
+ false,
3320
+ false,
3321
+ false,
3322
+ false,
3323
+ false,
3324
+ false,
3325
+ false,
3326
+ false,
3327
+ false,
3328
+ false,
3329
+ false,
3330
+ false,
3331
+ false,
3332
+ false,
3333
+ true,
3334
+ false,
3335
+ false,
3336
+ false,
3337
+ false,
3338
+ false,
3339
+ false,
3340
+ false,
3341
+ false,
3342
+ false,
3343
+ false,
3344
+ false,
3345
+ false,
3346
+ false,
3347
+ false,
3348
+ false,
3349
+ false,
3350
+ false,
3351
+ false,
3352
+ false,
3353
+ false,
3354
+ false,
3355
+ false,
3356
+ false,
3357
+ false,
3358
+ false,
3359
+ false,
3360
+ false,
3361
+ false,
3362
+ false,
3363
+ false,
3364
+ false,
3365
+ false,
3366
+ false,
3367
+ false,
3368
+ false,
3369
+ false,
3370
+ false,
3371
+ false,
3372
+ false,
3373
+ false,
3374
+ false,
3375
+ false,
3376
+ false,
3377
+ false,
3378
+ false,
3379
+ false,
3380
+ false,
3381
+ false,
3382
+ false,
3383
+ false,
3384
+ false,
3385
+ false,
3386
+ false,
3387
+ false,
3388
+ false,
3389
+ false,
3390
+ false,
3391
+ false,
3392
+ false,
3393
+ false,
3394
+ false,
3395
+ false,
3396
+ false,
3397
+ false,
3398
+ false,
3399
+ false,
3400
+ false,
3401
+ false,
3402
+ false,
3403
+ false,
3404
+ false,
3405
+ false,
3406
+ false,
3407
+ false,
3408
+ false,
3409
+ false,
3410
+ false,
3411
+ false,
3412
+ false,
3413
+ false,
3414
+ false,
3415
+ false,
3416
+ false,
3417
+ false,
3418
+ false,
3419
+ false,
3420
+ false,
3421
+ false,
3422
+ false,
3423
+ false,
3424
+ false,
3425
+ false,
3426
+ false,
3427
+ false,
3428
+ false,
3429
+ false,
3430
+ false,
3431
+ false,
3432
+ false,
3433
+ false,
3434
+ false,
3435
+ false,
3436
+ false,
3437
+ false,
3438
+ false,
3439
+ false,
3440
+ false,
3441
+ false,
3442
+ false,
3443
+ false,
3444
+ false,
3445
+ false,
3446
+ false,
3447
+ false,
3448
+ false,
3449
+ false,
3450
+ false,
3451
+ false,
3452
+ false,
3453
+ false,
3454
+ false,
3455
+ false,
3456
+ false,
3457
+ false,
3458
+ false,
3459
+ false,
3460
+ false,
3461
+ false,
3462
+ false,
3463
+ false,
3464
+ false,
3465
+ false,
3466
+ false,
3467
+ false,
3468
+ false,
3469
+ false,
3470
+ false,
3471
+ false,
3472
+ false,
3473
+ false,
3474
+ false,
3475
+ false,
3476
+ false,
3477
+ false,
3478
+ false,
3479
+ false,
3480
+ false,
3481
+ false,
3482
+ false,
3483
+ false,
3484
+ false,
3485
+ false,
3486
+ false,
3487
+ false,
3488
+ false,
3489
+ false,
3490
+ false,
3491
+ false,
3492
+ false,
3493
+ false,
3494
+ false,
3495
+ false,
3496
+ false,
3497
+ false,
3498
+ false,
3499
+ false,
3500
+ false,
3501
+ false,
3502
+ false,
3503
+ false,
3504
+ false,
3505
+ false,
3506
+ false,
3507
+ false,
3508
+ false,
3509
+ false,
3510
+ false,
3511
+ false,
3512
+ false,
3513
+ false,
3514
+ false,
3515
+ false,
3516
+ false,
3517
+ false,
3518
+ false,
3519
+ false,
3520
+ false,
3521
+ false,
3522
+ false,
3523
+ false,
3524
+ false,
3525
+ false,
3526
+ false,
3527
+ false,
3528
+ false,
3529
+ false,
3530
+ false,
3531
+ false,
3532
+ false,
3533
+ false,
3534
+ false,
3535
+ false,
3536
+ false,
3537
+ false,
3538
+ false,
3539
+ false,
3540
+ false,
3541
+ false,
3542
+ false,
3543
+ false,
3544
+ false,
3545
+ false,
3546
+ false,
3547
+ false,
3548
+ false,
3549
+ false,
3550
+ false,
3551
+ false,
3552
+ false,
3553
+ false,
3554
+ false,
3555
+ false,
3556
+ false,
3557
+ false,
3558
+ false,
3559
+ false,
3560
+ false,
3561
+ false,
3562
+ false,
3563
+ false,
3564
+ false,
3565
+ false,
3566
+ false,
3567
+ false,
3568
+ false,
3569
+ false,
3570
+ false,
3571
+ false,
3572
+ false,
3573
+ false,
3574
+ false,
3575
+ false,
3576
+ false,
3577
+ false,
3578
+ false,
3579
+ false,
3580
+ false,
3581
+ false,
3582
+ false,
3583
+ false,
3584
+ false,
3585
+ false,
3586
+ false,
3587
+ false,
3588
+ false,
3589
+ false,
3590
+ false,
3591
+ false,
3592
+ false,
3593
+ false,
3594
+ false,
3595
+ false,
3596
+ false,
3597
+ false,
3598
+ false,
3599
+ false,
3600
+ false,
3601
+ false,
3602
+ false,
3603
+ false,
3604
+ false,
3605
+ false,
3606
+ false,
3607
+ false,
3608
+ false,
3609
+ false,
3610
+ false,
3611
+ false,
3612
+ false,
3613
+ false,
3614
+ false,
3615
+ false,
3616
+ false,
3617
+ false,
3618
+ false,
3619
+ false,
3620
+ false,
3621
+ false,
3622
+ false,
3623
+ false,
3624
+ false,
3625
+ false,
3626
+ false,
3627
+ false,
3628
+ false,
3629
+ false,
3630
+ false,
3631
+ false,
3632
+ false,
3633
+ false,
3634
+ false,
3635
+ false,
3636
+ false,
3637
+ false,
3638
+ false,
3639
+ false,
3640
+ false,
3641
+ false,
3642
+ false,
3643
+ false,
3644
+ false,
3645
+ false,
3646
+ false,
3647
+ false,
3648
+ false,
3649
+ false,
3650
+ false,
3651
+ false,
3652
+ false,
3653
+ false,
3654
+ false,
3655
+ false,
3656
+ false,
3657
+ false,
3658
+ false,
3659
+ false,
3660
+ false,
3661
+ false,
3662
+ false,
3663
+ false,
3664
+ false,
3665
+ false,
3666
+ false,
3667
+ false,
3668
+ false,
3669
+ false,
3670
+ false,
3671
+ false,
3672
+ false,
3673
+ false,
3674
+ false,
3675
+ false,
3676
+ false,
3677
+ false,
3678
+ false,
3679
+ false,
3680
+ false,
3681
+ false,
3682
+ false,
3683
+ false,
3684
+ false,
3685
+ false,
3686
+ false,
3687
+ false,
3688
+ false,
3689
+ false,
3690
+ false,
3691
+ false,
3692
+ false,
3693
+ false,
3694
+ false,
3695
+ false,
3696
+ false,
3697
+ false,
3698
+ false,
3699
+ false,
3700
+ false,
3701
+ false,
3702
+ false,
3703
+ false,
3704
+ false,
3705
+ false,
3706
+ false,
3707
+ false,
3708
+ false,
3709
+ false,
3710
+ false,
3711
+ false,
3712
+ false,
3713
+ false,
3714
+ false,
3715
+ false,
3716
+ false,
3717
+ false,
3718
+ false,
3719
+ false,
3720
+ false,
3721
+ false,
3722
+ false,
3723
+ false,
3724
+ false,
3725
+ false,
3726
+ false,
3727
+ false,
3728
+ false,
3729
+ false,
3730
+ false,
3731
+ false,
3732
+ false,
3733
+ false,
3734
+ false,
3735
+ false,
3736
+ false
3737
+ ],
3738
+ "dims": [
3739
+ 1,
3740
+ 24,
3741
+ 24
3742
+ ]
3743
+ }
3744
+ },
3745
+ "display": {
3746
+ "bank_rows": [
3747
+ {
3748
+ "id": "BANK-REFERENCE-LIGHT-01",
3749
+ "date": "2026-07-19",
3750
+ "amount": 5.32,
3751
+ "currency": "EUR",
3752
+ "entity": "Northstar Services LLC",
3753
+ "reference": "\u2014",
3754
+ "narrative": "Software subscription \u00b7 Granite Software"
3755
+ },
3756
+ {
3757
+ "id": "BANK-REFERENCE-LIGHT-02",
3758
+ "date": "2026-07-22",
3759
+ "amount": 52.42,
3760
+ "currency": "EUR",
3761
+ "entity": "Northstar Studio LLC",
3762
+ "reference": "\u2014",
3763
+ "narrative": "Insurance payment \u00b7 Dovetail Logistics"
3764
+ },
3765
+ {
3766
+ "id": "BANK-REFERENCE-LIGHT-03",
3767
+ "date": "2026-07-19",
3768
+ "amount": 12.83,
3769
+ "currency": "USD",
3770
+ "entity": "Northstar Services LLC",
3771
+ "reference": "\u2014",
3772
+ "narrative": "Intercompany transfer \u00b7 Beacon Telecom"
3773
+ },
3774
+ {
3775
+ "id": "BANK-REFERENCE-LIGHT-04",
3776
+ "date": "2026-07-17",
3777
+ "amount": -1990.52,
3778
+ "currency": "EUR",
3779
+ "entity": "Northstar Studio LLC",
3780
+ "reference": "\u2014",
3781
+ "narrative": "Operating expense \u00b7 Harbor Utilities"
3782
+ },
3783
+ {
3784
+ "id": "BANK-REFERENCE-LIGHT-05",
3785
+ "date": "2026-07-13",
3786
+ "amount": 107.4,
3787
+ "currency": "GBP",
3788
+ "entity": "Northstar Holdings LLC",
3789
+ "reference": "\u2014",
3790
+ "narrative": "Customer receipt \u00b7 Atlas Office Co."
3791
+ },
3792
+ {
3793
+ "id": "BANK-REFERENCE-LIGHT-06",
3794
+ "date": "2026-07-15",
3795
+ "amount": -1.63,
3796
+ "currency": "GBP",
3797
+ "entity": "Northstar Holdings LLC",
3798
+ "reference": "\u2014",
3799
+ "narrative": "Customer receipt \u00b7 Atlas Office Co."
3800
+ },
3801
+ {
3802
+ "id": "BANK-REFERENCE-LIGHT-07",
3803
+ "date": "2026-07-13",
3804
+ "amount": -6607.81,
3805
+ "currency": "GBP",
3806
+ "entity": "Northstar Studio LLC",
3807
+ "reference": "\u2014",
3808
+ "narrative": "Card settlement \u00b7 Ember Insurance"
3809
+ },
3810
+ {
3811
+ "id": "BANK-REFERENCE-LIGHT-08",
3812
+ "date": "2026-07-04",
3813
+ "amount": 21.3,
3814
+ "currency": "GBP",
3815
+ "entity": "Northstar Holdings LLC",
3816
+ "reference": "\u2014",
3817
+ "narrative": "Supplier payment \u00b7 Ember Insurance"
3818
+ }
3819
+ ],
3820
+ "gl_rows": [
3821
+ {
3822
+ "id": "GL-REFERENCE-LIGHT-01",
3823
+ "date": "2026-07-15",
3824
+ "amount": 107.4,
3825
+ "currency": "GBP",
3826
+ "entity": "Northstar Holdings LLC",
3827
+ "reference": "\u2014",
3828
+ "narrative": "Card settlement \u00b7 Atlas Office Co."
3829
+ },
3830
+ {
3831
+ "id": "GL-REFERENCE-LIGHT-02",
3832
+ "date": "2026-07-19",
3833
+ "amount": 5.32,
3834
+ "currency": "EUR",
3835
+ "entity": "Northstar Services LLC",
3836
+ "reference": "\u2014",
3837
+ "narrative": "Software subscription \u00b7 Granite Software"
3838
+ },
3839
+ {
3840
+ "id": "GL-REFERENCE-LIGHT-03",
3841
+ "date": "2026-07-21",
3842
+ "amount": 52.42,
3843
+ "currency": "EUR",
3844
+ "entity": "Northstar Studio LLC",
3845
+ "reference": "\u2014",
3846
+ "narrative": "Insurance payment \u00b7 Dovetail Logistics"
3847
+ },
3848
+ {
3849
+ "id": "GL-REFERENCE-LIGHT-04",
3850
+ "date": "2026-07-31",
3851
+ "amount": 9116.79,
3852
+ "currency": "USD",
3853
+ "entity": "Northstar Services LLC",
3854
+ "reference": "\u2014",
3855
+ "narrative": "Customer receipt \u00b7 Cedar Payroll"
3856
+ },
3857
+ {
3858
+ "id": "GL-REFERENCE-LIGHT-05",
3859
+ "date": "2026-07-05",
3860
+ "amount": 21.3,
3861
+ "currency": "GBP",
3862
+ "entity": "Northstar Holdings LLC",
3863
+ "reference": "\u2014",
3864
+ "narrative": "Card settlement \u00b7 Ember Insurance"
3865
+ },
3866
+ {
3867
+ "id": "GL-REFERENCE-LIGHT-06",
3868
+ "date": "2026-07-19",
3869
+ "amount": 12.83,
3870
+ "currency": "USD",
3871
+ "entity": "Northstar Services LLC",
3872
+ "reference": "\u2014",
3873
+ "narrative": "Customer receipt \u00b7 Beacon Telecom"
3874
+ }
3875
+ ]
3876
+ },
3877
+ "truth": {
3878
+ "bank_to_gl": [
3879
+ 1,
3880
+ 2,
3881
+ 5,
3882
+ -1,
3883
+ 0,
3884
+ -1,
3885
+ -1,
3886
+ 4
3887
+ ],
3888
+ "exceptions": [
3889
+ "TIMING",
3890
+ "MATCHED",
3891
+ "TIMING",
3892
+ "TIMING",
3893
+ "TIMING",
3894
+ "BANK_FEE",
3895
+ "UNMATCHED",
3896
+ "MATCHED"
3897
+ ]
3898
+ }
3899
+ }
3900
+ ]
3901
+ }
index.html CHANGED
@@ -1,19 +1,328 @@
1
  <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
  <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <meta
7
+ name="description"
8
+ content="An accounting-first guide to training hierarchical reasoning models, with a live bank-reconciliation model running entirely in your browser."
9
+ />
10
+ <meta name="theme-color" content="#f2f0e9" />
11
+ <title>CFO-HRM Accounting Puzzle Lab</title>
12
+ <link rel="stylesheet" href="./style.css" />
13
+ <script
14
+ defer
15
+ src="https://cdn.jsdelivr.net/npm/marked@18.0.7/lib/marked.umd.js"
16
+ ></script>
17
+ <script
18
+ defer
19
+ src="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.27.0/dist/ort.min.js"
20
+ ></script>
21
+ <script type="module" src="./app.js"></script>
22
+ </head>
23
+ <body>
24
+ <a class="skip-link" href="#main">Skip to the guide</a>
25
+
26
+ <header class="topbar" aria-label="Primary navigation">
27
+ <a class="wordmark" href="#hero" aria-label="CFO-HRM home">
28
+ <span class="wordmark-mark">CFO</span>
29
+ <span>HRM / ACCOUNTING LAB</span>
30
+ </a>
31
+ <nav>
32
+ <a href="#guide">The guide</a>
33
+ <a href="#demo">Live case</a>
34
+ <a href="#controls">Controls</a>
35
+ <a
36
+ href="https://huggingface.co/aznatkoiny/cfo-hrm"
37
+ target="_blank"
38
+ rel="noreferrer"
39
+ >Model ↗</a
40
+ >
41
+ </nav>
42
+ </header>
43
+
44
+ <main id="main">
45
+ <section id="hero" class="page-section">
46
+ <div class="hero-grid">
47
+ <div class="hero-copy">
48
+ <p class="eyebrow">“TRAINING DATA, EXPLAINED” / VOL. 01</p>
49
+ <h1>Teach the model the way you train a new accountant.</h1>
50
+ <p class="hero-deck">
51
+ Give it complete cases, clear rules, and approved answers. Then
52
+ make it ask for help when the evidence is not good enough.
53
+ </p>
54
+ <div class="hero-actions">
55
+ <a class="button button-primary" href="#guide">Start with the guide</a>
56
+ <a class="button button-ghost" href="#demo">See a live reconciliation</a>
57
+ </div>
58
+ </div>
59
+
60
+ <aside class="hero-aside" aria-label="Project status">
61
+ <div class="model-badge">
62
+ <span class="signal-dot" aria-hidden="true"></span>
63
+ ACTUAL CHECKPOINT / BROWSER-RUN
64
+ </div>
65
+ <p class="quote-label">“SHADOW MODE”</p>
66
+ <p>
67
+ The model proposes. Deterministic controls check. A person
68
+ decides.
69
+ </p>
70
+ <div class="audit-stamp" aria-label="Posting status">
71
+ <span>POSTING AUTHORIZED</span>
72
+ <strong>FALSE</strong>
73
+ </div>
74
+ <p class="microcopy">
75
+ Fictional demonstration records. No files are uploaded. Nothing
76
+ can reach an ERP.
77
+ </p>
78
+ </aside>
79
+ </div>
80
+ </section>
81
+
82
+ <section class="stats-grid page-section" aria-label="Project facts">
83
+ <article class="stat-card">
84
+ <span class="stat-index">01</span>
85
+ <strong>702</strong>
86
+ <span>held-out bank rows</span>
87
+ </article>
88
+ <article class="stat-card">
89
+ <span class="stat-index">02</span>
90
+ <strong>100%</strong>
91
+ <span>test match F1*</span>
92
+ </article>
93
+ <article class="stat-card">
94
+ <span class="stat-index">03</span>
95
+ <strong>0</strong>
96
+ <span>authorized postings</span>
97
+ </article>
98
+ <article class="stat-card">
99
+ <span class="stat-index">04</span>
100
+ <strong>LOCAL</strong>
101
+ <span>in-browser inference</span>
102
+ </article>
103
+ <p class="stats-footnote">
104
+ *The deterministic rules baseline also matched 100%. The honest lesson
105
+ is exception recognition—not a claim that HRM beats ordinary matching.
106
+ </p>
107
+ </section>
108
+
109
+ <section id="guide" class="page-section content-section">
110
+ <div class="section-heading">
111
+ <p class="section-label">SECTION 01 / THE DATASET</p>
112
+ <div>
113
+ <h2>What does a specialist training dataset look like?</h2>
114
+ <p>
115
+ The original explanation is presented below with its wording and
116
+ examples intact.
117
+ </p>
118
+ </div>
119
+ </div>
120
+ <article id="guide-content" class="accounting-panel guide-content">
121
+ <p class="loading-copy">Loading the accounting-puzzle guide…</p>
122
+ </article>
123
+ </section>
124
+
125
+ <section id="demo" class="page-section content-section">
126
+ <div class="section-heading">
127
+ <p class="section-label">SECTION 02 / MODEL IN ACTION</p>
128
+ <div>
129
+ <h2>Review a fictional reconciliation batch.</h2>
130
+ <p>
131
+ The released step-50 model runs on your device. It scores the
132
+ candidates; a one-to-one decoder prevents double-use of GL rows.
133
+ </p>
134
+ </div>
135
+ </div>
136
+
137
+ <div class="demo-shell">
138
+ <div class="demo-controls">
139
+ <label for="case-select">Choose a case</label>
140
+ <select id="case-select" name="case"></select>
141
+
142
+ <label for="threshold">
143
+ Confidence needed before a match can pass
144
+ <output id="threshold-value" for="threshold">90%</output>
145
+ </label>
146
+ <input
147
+ id="threshold"
148
+ type="range"
149
+ min="50"
150
+ max="99"
151
+ value="90"
152
+ step="1"
153
+ />
154
+
155
+ <button id="run-review" class="button button-primary" type="button">
156
+ Review this batch →
157
+ </button>
158
+ <p id="model-status" class="model-status" role="status" aria-live="polite">
159
+ MODEL STANDBY / LOADS ON FIRST RUN
160
+ </p>
161
+ </div>
162
+
163
+ <div class="demo-case-note">
164
+ <p class="quote-label">“CASE NOTE”</p>
165
+ <h3 id="case-title">Select a case</h3>
166
+ <p id="case-description">
167
+ Each example uses fictional names and amounts generated for this
168
+ demonstration.
169
+ </p>
170
+ <dl>
171
+ <div>
172
+ <dt>Period</dt>
173
+ <dd id="case-period">—</dd>
174
+ </div>
175
+ <div>
176
+ <dt>Data</dt>
177
+ <dd>Fictional</dd>
178
+ </div>
179
+ <div>
180
+ <dt>Decision</dt>
181
+ <dd>Human review</dd>
182
+ </div>
183
+ </dl>
184
+ </div>
185
+ </div>
186
+
187
+ <div id="demo-output" class="demo-output" hidden>
188
+ <div id="review-status" class="status-strip" role="status"></div>
189
+ <div id="summary-cards" class="stats-grid compact"></div>
190
+
191
+ <div class="table-block">
192
+ <div class="table-heading">
193
+ <p class="section-label">PROPOSED DISPOSITIONS</p>
194
+ <p>Every GL row can be used at most once.</p>
195
+ </div>
196
+ <div class="table-scroll">
197
+ <table>
198
+ <thead>
199
+ <tr>
200
+ <th>Bank row</th>
201
+ <th>Amount</th>
202
+ <th>Proposed GL</th>
203
+ <th>Confidence</th>
204
+ <th>Model signal</th>
205
+ <th>Route</th>
206
+ </tr>
207
+ </thead>
208
+ <tbody id="proposal-rows"></tbody>
209
+ </table>
210
+ </div>
211
+ </div>
212
+
213
+ <details class="record-details">
214
+ <summary>Inspect the fictional bank and GL records</summary>
215
+ <div class="record-grid">
216
+ <div>
217
+ <h3>Bank statement</h3>
218
+ <div class="table-scroll">
219
+ <table>
220
+ <thead>
221
+ <tr>
222
+ <th>ID</th>
223
+ <th>Date</th>
224
+ <th>Narrative</th>
225
+ <th>Amount</th>
226
+ </tr>
227
+ </thead>
228
+ <tbody id="bank-rows"></tbody>
229
+ </table>
230
+ </div>
231
+ </div>
232
+ <div>
233
+ <h3>General ledger</h3>
234
+ <div class="table-scroll">
235
+ <table>
236
+ <thead>
237
+ <tr>
238
+ <th>ID</th>
239
+ <th>Date</th>
240
+ <th>Narrative</th>
241
+ <th>Amount</th>
242
+ </tr>
243
+ </thead>
244
+ <tbody id="gl-rows"></tbody>
245
+ </table>
246
+ </div>
247
+ </div>
248
+ </div>
249
+ </details>
250
+
251
+ <p class="caveat">
252
+ Confidence is a routing signal, not proof. This educational model
253
+ was trained on synthetic records and is not accounting software.
254
+ </p>
255
+ </div>
256
+ </section>
257
+
258
+ <section id="controls" class="page-section content-section">
259
+ <div class="section-heading">
260
+ <p class="section-label">SECTION 03 / THE CONTROL BOUNDARY</p>
261
+ <div>
262
+ <h2>The model never gets the final word.</h2>
263
+ <p>
264
+ A useful accounting system separates prediction from authority.
265
+ </p>
266
+ </div>
267
+ </div>
268
+
269
+ <div class="workflow-grid">
270
+ <article class="workflow-step">
271
+ <span>01 / SCORE</span>
272
+ <h3>The model proposes</h3>
273
+ <p>It scores possible bank-to-ledger links and exception types.</p>
274
+ </article>
275
+ <article class="workflow-step">
276
+ <span>02 / CONSTRAIN</span>
277
+ <h3>Rules enforce consistency</h3>
278
+ <p>Entity, currency, amount, date, and one-to-one use are checked.</p>
279
+ </article>
280
+ <article class="workflow-step">
281
+ <span>03 / ABSTAIN</span>
282
+ <h3>Weak evidence stops</h3>
283
+ <p>Low-confidence and unusual items are routed to review.</p>
284
+ </article>
285
+ <article class="workflow-step">
286
+ <span>04 / DECIDE</span>
287
+ <h3>A person remains accountable</h3>
288
+ <p>The public demo has no posting client, credentials, or approval path.</p>
289
+ </article>
290
+ </div>
291
+ </section>
292
+
293
+ <section class="page-section disclosure-panel">
294
+ <p class="section-label">READ BEFORE USE</p>
295
+ <h2>Educational, synthetic, non-commercial.</h2>
296
+ <p>
297
+ The source code is Apache-2.0. The checkpoint was trained using
298
+ CC BY-NC 4.0 Mindweave datasets and is released under CC BY-NC 4.0.
299
+ It is not cleared for commercial accounting use. The public examples
300
+ are fictional and are not copied from the source datasets.
301
+ </p>
302
+ <div class="link-row">
303
+ <a href="https://github.com/Aznatkoiny/cfo-hrm" target="_blank" rel="noreferrer"
304
+ >Source + controls ↗</a
305
+ >
306
+ <a
307
+ href="https://huggingface.co/aznatkoiny/cfo-hrm"
308
+ target="_blank"
309
+ rel="noreferrer"
310
+ >Model + evaluation ↗</a
311
+ >
312
+ <a
313
+ href="https://arxiv.org/html/2506.21734v3"
314
+ target="_blank"
315
+ rel="noreferrer"
316
+ >HRM research inspiration ↗</a
317
+ >
318
+ </div>
319
+ </section>
320
+ </main>
321
+
322
+ <footer class="site-footer">
323
+ <p>CFO-HRM / ACCOUNTING PUZZLE LAB</p>
324
+ <p class="footer-note">“PROPOSALS, NOT POSTINGS”</p>
325
+ <p>EDUCATIONAL RELEASE / V0.1.0</p>
326
+ </footer>
327
+ </body>
328
  </html>
model/cfo_hrm.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:912502b6a5ef711b6aacdce00cb4f48fbdf43c451f93a81a6ab93e4beda23ccb
3
+ size 8784084
style.css CHANGED
@@ -1,28 +1,2138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
 
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
 
 
28
  }
 
1
+ /*
2
+ * CFO HRM — industrial editorial interface
3
+ *
4
+ * Original visual language built from ledger grids, registration marks,
5
+ * utilitarian labels, and safety-color wayfinding. No external fonts or
6
+ * trademarked visual assets are used.
7
+ */
8
+
9
+ :root {
10
+ color-scheme: light;
11
+ --paper: #f2eee4;
12
+ --paper-bright: #fbf9f3;
13
+ --paper-deep: #dfd8ca;
14
+ --ink: #11110f;
15
+ --ink-soft: #302f2b;
16
+ --muted: #6b675e;
17
+ --line: #bbb3a5;
18
+ --line-soft: rgba(17, 17, 15, 0.13);
19
+ --orange: #ff5100;
20
+ --orange-deep: #963000;
21
+ --success: #125438;
22
+ --danger: #98261e;
23
+ --focus: #006fc9;
24
+ --display: "Arial Black", "Helvetica Neue", Helvetica, Arial, sans-serif;
25
+ --body: "Helvetica Neue", Helvetica, Arial, sans-serif;
26
+ --mono: "IBM Plex Mono", "SFMono-Regular", Consolas, "Liberation Mono", monospace;
27
+ --measure: 72ch;
28
+ --site-width: 1440px;
29
+ --gutter: clamp(1rem, 3.2vw, 3.25rem);
30
+ --space-1: 0.375rem;
31
+ --space-2: 0.75rem;
32
+ --space-3: 1rem;
33
+ --space-4: 1.5rem;
34
+ --space-5: 2rem;
35
+ --space-6: 3rem;
36
+ --space-7: 4.5rem;
37
+ --border: 1px solid var(--ink);
38
+ --border-heavy: 2px solid var(--ink);
39
+ --shadow-offset: 7px 7px 0 var(--ink);
40
+ }
41
+
42
+ *,
43
+ *::before,
44
+ *::after {
45
+ box-sizing: border-box;
46
+ }
47
+
48
+ html {
49
+ scroll-behavior: smooth;
50
+ scroll-padding-top: 6.5rem;
51
+ background: var(--paper);
52
+ }
53
+
54
  body {
55
+ min-width: 320px;
56
+ margin: 0;
57
+ color: var(--ink);
58
+ background-color: var(--paper);
59
+ background-image:
60
+ linear-gradient(rgba(17, 17, 15, 0.038) 1px, transparent 1px),
61
+ linear-gradient(90deg, rgba(17, 17, 15, 0.038) 1px, transparent 1px);
62
+ background-size: 48px 48px;
63
+ font-family: var(--body);
64
+ font-size: 1rem;
65
+ line-height: 1.55;
66
+ text-rendering: optimizeLegibility;
67
+ -webkit-font-smoothing: antialiased;
68
+ }
69
+
70
+ img,
71
+ svg {
72
+ display: block;
73
+ max-width: 100%;
74
+ }
75
+
76
+ button,
77
+ input,
78
+ select,
79
+ textarea {
80
+ font: inherit;
81
+ }
82
+
83
+ button,
84
+ select {
85
+ cursor: pointer;
86
+ }
87
+
88
+ a {
89
+ color: var(--orange-deep);
90
+ text-decoration-color: currentColor;
91
+ text-decoration-thickness: 1px;
92
+ text-underline-offset: 0.2em;
93
+ }
94
+
95
+ a:hover {
96
+ color: var(--ink);
97
+ text-decoration-thickness: 2px;
98
+ }
99
+
100
+ :focus-visible {
101
+ outline: 3px solid var(--focus);
102
+ outline-offset: 4px;
103
+ }
104
+
105
+ ::selection {
106
+ color: var(--ink);
107
+ background: var(--orange);
108
+ }
109
+
110
+ [hidden] {
111
+ display: none !important;
112
+ }
113
+
114
+ .skip-link {
115
+ position: fixed;
116
+ z-index: 1000;
117
+ top: 0.75rem;
118
+ left: 0.75rem;
119
+ padding: 0.75rem 1rem;
120
+ border: var(--border-heavy);
121
+ color: var(--ink);
122
+ background: var(--paper-bright);
123
+ font-family: var(--mono);
124
+ font-weight: 800;
125
+ transform: translateY(-160%);
126
+ }
127
+
128
+ .skip-link:focus {
129
+ transform: translateY(0);
130
+ }
131
+
132
+ .site-shell,
133
+ main,
134
+ .site-footer {
135
+ width: min(100%, var(--site-width));
136
+ margin-inline: auto;
137
+ }
138
+
139
+ .site-nav {
140
+ position: sticky;
141
+ z-index: 100;
142
+ top: 0;
143
+ display: flex;
144
+ min-height: 4.25rem;
145
+ align-items: stretch;
146
+ justify-content: space-between;
147
+ border-right: var(--border);
148
+ border-bottom: var(--border-heavy);
149
+ border-left: var(--border);
150
+ background: rgba(242, 238, 228, 0.96);
151
+ backdrop-filter: blur(14px);
152
+ }
153
+
154
+ .site-nav .brand,
155
+ .site-nav > a:first-child {
156
+ display: inline-flex;
157
+ min-width: 15rem;
158
+ align-items: center;
159
+ padding: 0.75rem var(--gutter);
160
+ border-right: var(--border);
161
+ color: var(--ink);
162
+ font-family: var(--display);
163
+ font-size: 0.86rem;
164
+ font-weight: 900;
165
+ letter-spacing: -0.02em;
166
+ line-height: 1;
167
+ text-decoration: none;
168
+ text-transform: uppercase;
169
+ }
170
+
171
+ .site-nav .brand::before,
172
+ .site-nav > a:first-child::before {
173
+ width: 0.72rem;
174
+ height: 0.72rem;
175
+ margin-right: 0.6rem;
176
+ background: var(--orange);
177
+ content: "";
178
+ }
179
+
180
+ .site-nav ul,
181
+ .site-nav .nav-links {
182
+ display: flex;
183
+ margin: 0;
184
+ padding: 0;
185
+ align-items: stretch;
186
+ list-style: none;
187
+ }
188
+
189
+ .site-nav li {
190
+ display: flex;
191
+ }
192
+
193
+ .site-nav li + li {
194
+ border-left: var(--border);
195
+ }
196
+
197
+ .site-nav li a,
198
+ .site-nav .nav-links > a {
199
+ display: inline-flex;
200
+ min-height: 4.125rem;
201
+ padding: 0.75rem 1.15rem;
202
+ align-items: center;
203
+ color: var(--ink);
204
+ font-family: var(--mono);
205
+ font-size: 0.71rem;
206
+ font-weight: 800;
207
+ letter-spacing: 0.06em;
208
+ text-decoration: none;
209
+ text-transform: uppercase;
210
+ }
211
+
212
+ .site-nav li a:hover,
213
+ .site-nav li a[aria-current="page"],
214
+ .site-nav .nav-links > a:hover {
215
+ color: var(--ink);
216
+ background: var(--orange);
217
+ }
218
+
219
+ #hero,
220
+ .hero {
221
+ position: relative;
222
+ display: grid;
223
+ min-height: min(730px, 82vh);
224
+ grid-template-columns: minmax(0, 1.68fr) minmax(18rem, 0.62fr);
225
+ overflow: hidden;
226
+ border-right: var(--border-heavy);
227
+ border-bottom: var(--border-heavy);
228
+ border-left: var(--border-heavy);
229
+ background: var(--paper-bright);
230
+ }
231
+
232
+ #hero::before,
233
+ .hero::before {
234
+ position: absolute;
235
+ z-index: 4;
236
+ top: 1rem;
237
+ right: 1rem;
238
+ width: 1rem;
239
+ height: 1rem;
240
+ border-radius: 50%;
241
+ background:
242
+ linear-gradient(transparent 46%, var(--ink) 46% 54%, transparent 54%),
243
+ linear-gradient(90deg, transparent 46%, var(--ink) 46% 54%, transparent 54%);
244
+ content: "";
245
+ }
246
+
247
+ .hero-grid {
248
+ display: contents;
249
+ }
250
+
251
+ .hero-copy {
252
+ position: relative;
253
+ display: flex;
254
+ min-width: 0;
255
+ padding: clamp(5rem, 9vw, 9.5rem) var(--gutter) clamp(3rem, 6vw, 6rem);
256
+ flex-direction: column;
257
+ justify-content: space-between;
258
+ }
259
+
260
+ .hero-copy::after {
261
+ position: absolute;
262
+ right: clamp(1rem, 3vw, 2.5rem);
263
+ bottom: 1rem;
264
+ color: var(--muted);
265
+ content: "X 01 / Y 01";
266
+ font-family: var(--mono);
267
+ font-size: 0.64rem;
268
+ letter-spacing: 0.09em;
269
+ }
270
+
271
+ .eyebrow,
272
+ .quote-label,
273
+ .section-label {
274
+ display: inline-flex;
275
+ width: fit-content;
276
+ align-items: center;
277
+ margin: 0 0 var(--space-4);
278
+ padding: 0.42rem 0.62rem;
279
+ color: var(--ink);
280
+ background: var(--orange);
281
+ font-family: var(--mono);
282
+ font-size: 0.68rem;
283
+ font-weight: 900;
284
+ letter-spacing: 0.08em;
285
+ line-height: 1.2;
286
+ text-transform: uppercase;
287
+ }
288
+
289
+ .quote-label::before {
290
+ margin-right: 0.24rem;
291
+ content: "\201C";
292
+ font-family: Georgia, serif;
293
+ font-size: 1.1em;
294
+ }
295
+
296
+ .quote-label::after {
297
+ margin-left: 0.24rem;
298
+ content: "\201D";
299
+ font-family: Georgia, serif;
300
+ font-size: 1.1em;
301
+ }
302
+
303
+ #hero h1,
304
+ .hero h1 {
305
+ max-width: 11ch;
306
+ margin: 0;
307
+ font-family: var(--display);
308
+ font-size: clamp(3.65rem, 8.4vw, 9rem);
309
+ font-weight: 950;
310
+ letter-spacing: -0.085em;
311
+ line-height: 0.82;
312
+ text-transform: uppercase;
313
+ }
314
+
315
+ #hero h1 em,
316
+ #hero h1 strong,
317
+ .hero h1 em,
318
+ .hero h1 strong {
319
+ color: var(--ink);
320
+ font-style: normal;
321
+ -webkit-text-stroke: 2px var(--ink);
322
+ -webkit-text-fill-color: transparent;
323
+ }
324
+
325
+ .hero-deck,
326
+ .hero-copy > p {
327
+ max-width: 52ch;
328
+ margin: clamp(2rem, 5vw, 5rem) 0 0;
329
+ font-size: clamp(1.05rem, 1.55vw, 1.42rem);
330
+ font-weight: 550;
331
+ letter-spacing: -0.015em;
332
+ line-height: 1.42;
333
+ }
334
+
335
+ .hero-aside {
336
+ position: relative;
337
+ display: flex;
338
+ min-width: 0;
339
+ padding: clamp(4.5rem, 8vw, 8rem) clamp(1.35rem, 3vw, 3rem) 2rem;
340
+ flex-direction: column;
341
+ justify-content: space-between;
342
+ border-left: var(--border-heavy);
343
+ color: var(--paper-bright);
344
+ background-color: var(--ink);
345
+ background-image: repeating-linear-gradient(
346
+ -45deg,
347
+ transparent,
348
+ transparent 19px,
349
+ rgba(255, 255, 255, 0.045) 20px,
350
+ rgba(255, 255, 255, 0.045) 21px
351
+ );
352
+ }
353
+
354
+ .hero-aside::before {
355
+ position: absolute;
356
+ top: 1.1rem;
357
+ left: 1.2rem;
358
+ color: var(--paper-deep);
359
+ content: "MODEL / 001";
360
+ font-family: var(--mono);
361
+ font-size: 0.66rem;
362
+ font-weight: 700;
363
+ letter-spacing: 0.1em;
364
+ }
365
+
366
+ .hero-aside h2,
367
+ .hero-aside h3 {
368
+ max-width: 12ch;
369
+ margin: 0 0 var(--space-4);
370
+ font-family: var(--display);
371
+ font-size: clamp(1.7rem, 3vw, 3.1rem);
372
+ letter-spacing: -0.05em;
373
+ line-height: 0.95;
374
+ text-transform: uppercase;
375
+ }
376
+
377
+ .hero-aside p {
378
+ max-width: 34ch;
379
+ color: var(--paper-deep);
380
+ }
381
+
382
+ .model-badge {
383
+ display: flex;
384
+ width: fit-content;
385
+ max-width: 100%;
386
+ margin-top: var(--space-4);
387
+ padding: 0.65rem 0.8rem;
388
+ align-items: center;
389
+ border: 1px solid var(--orange);
390
+ color: var(--paper-bright);
391
+ background: rgba(17, 17, 15, 0.82);
392
+ font-family: var(--mono);
393
+ font-size: 0.68rem;
394
+ font-weight: 750;
395
+ letter-spacing: 0.04em;
396
+ overflow-wrap: anywhere;
397
+ text-transform: uppercase;
398
+ }
399
+
400
+ .model-badge::before {
401
+ width: 0.52rem;
402
+ height: 0.52rem;
403
+ margin-right: 0.55rem;
404
+ flex: 0 0 auto;
405
+ border-radius: 50%;
406
+ background: var(--orange);
407
+ box-shadow: 0 0 0 3px rgba(255, 81, 0, 0.2);
408
+ content: "";
409
+ }
410
+
411
+ .stats-grid {
412
+ display: grid;
413
+ grid-template-columns: repeat(4, minmax(0, 1fr));
414
+ border-right: var(--border-heavy);
415
+ border-bottom: var(--border-heavy);
416
+ border-left: var(--border-heavy);
417
+ background: var(--paper-bright);
418
+ }
419
+
420
+ .stat-card {
421
+ position: relative;
422
+ min-height: 10rem;
423
+ padding: var(--space-4);
424
+ }
425
+
426
+ .stat-card + .stat-card {
427
+ border-left: var(--border);
428
+ }
429
+
430
+ .stat-card::before {
431
+ display: block;
432
+ margin-bottom: 1.65rem;
433
+ color: var(--muted);
434
+ content: attr(data-index);
435
+ font-family: var(--mono);
436
+ font-size: 0.62rem;
437
+ letter-spacing: 0.08em;
438
+ }
439
+
440
+ .stat-card strong,
441
+ .stat-card .stat-value {
442
+ display: block;
443
+ font-family: var(--display);
444
+ font-size: clamp(2rem, 3.8vw, 4.3rem);
445
+ font-weight: 950;
446
+ letter-spacing: -0.065em;
447
+ line-height: 0.9;
448
+ }
449
+
450
+ .stat-card span,
451
+ .stat-card .stat-label {
452
+ display: block;
453
+ max-width: 24ch;
454
+ margin-top: 0.85rem;
455
+ color: var(--muted);
456
+ font-family: var(--mono);
457
+ font-size: 0.68rem;
458
+ font-weight: 700;
459
+ letter-spacing: 0.055em;
460
+ line-height: 1.4;
461
+ text-transform: uppercase;
462
+ }
463
+
464
+ .content-section,
465
+ section.guide,
466
+ #guide-content,
467
+ .demo-shell {
468
+ border-right: var(--border-heavy);
469
+ border-bottom: var(--border-heavy);
470
+ border-left: var(--border-heavy);
471
+ }
472
+
473
+ .content-section,
474
+ section.guide {
475
+ padding: clamp(3rem, 8vw, 8rem) var(--gutter);
476
+ background: var(--paper);
477
+ }
478
+
479
+ .section-heading {
480
+ display: grid;
481
+ margin-bottom: clamp(2.5rem, 6vw, 5rem);
482
+ grid-template-columns: minmax(0, 1fr) minmax(16rem, 0.42fr);
483
+ gap: var(--space-5);
484
+ align-items: end;
485
+ }
486
+
487
+ .section-heading h2 {
488
+ max-width: 13ch;
489
+ margin: 0;
490
+ font-family: var(--display);
491
+ font-size: clamp(2.7rem, 6.4vw, 6.5rem);
492
+ font-weight: 950;
493
+ letter-spacing: -0.075em;
494
+ line-height: 0.88;
495
+ text-transform: uppercase;
496
+ }
497
+
498
+ .section-heading p {
499
+ max-width: 38ch;
500
+ margin: 0;
501
+ color: var(--ink-soft);
502
+ font-size: 1.08rem;
503
+ }
504
+
505
+ #guide-content {
506
+ padding: clamp(3rem, 7vw, 7rem) var(--gutter);
507
+ background: var(--paper-bright);
508
+ }
509
+
510
+ #guide-content > * {
511
+ max-width: var(--measure);
512
+ margin-right: auto;
513
+ margin-left: auto;
514
+ }
515
+
516
+ #guide-content > .section-label,
517
+ #guide-content > h1,
518
+ #guide-content > h2,
519
+ #guide-content > h3,
520
+ #guide-content > h4,
521
+ #guide-content > table,
522
+ #guide-content > pre,
523
+ #guide-content > blockquote,
524
+ #guide-content > details {
525
+ width: 100%;
526
+ max-width: 980px;
527
+ }
528
+
529
+ #guide-content > h1 {
530
+ margin-top: 0;
531
+ margin-bottom: clamp(2rem, 4vw, 4rem);
532
+ font-family: var(--display);
533
+ font-size: clamp(2.8rem, 6vw, 6rem);
534
+ font-weight: 950;
535
+ letter-spacing: -0.075em;
536
+ line-height: 0.88;
537
+ text-transform: uppercase;
538
+ }
539
+
540
+ #guide-content h2 {
541
+ position: relative;
542
+ margin-top: clamp(4rem, 9vw, 8rem);
543
+ margin-bottom: 1.35rem;
544
+ padding-top: 1rem;
545
+ border-top: var(--border-heavy);
546
+ font-family: var(--display);
547
+ font-size: clamp(2rem, 4vw, 4.15rem);
548
+ font-weight: 950;
549
+ letter-spacing: -0.06em;
550
+ line-height: 0.95;
551
+ }
552
+
553
+ #guide-content h2::after {
554
+ position: absolute;
555
+ top: -0.52rem;
556
+ right: 0;
557
+ width: 0.95rem;
558
+ height: 0.95rem;
559
+ border: var(--border);
560
+ background: var(--orange);
561
+ content: "";
562
+ }
563
+
564
+ #guide-content h3 {
565
+ margin-top: 3rem;
566
+ margin-bottom: 0.8rem;
567
+ font-family: var(--display);
568
+ font-size: clamp(1.35rem, 2.4vw, 2.15rem);
569
+ font-weight: 900;
570
+ letter-spacing: -0.035em;
571
+ line-height: 1.05;
572
+ }
573
+
574
+ #guide-content h4 {
575
+ margin-top: 2rem;
576
+ margin-bottom: 0.7rem;
577
+ font-family: var(--mono);
578
+ font-size: 0.8rem;
579
+ font-weight: 900;
580
+ letter-spacing: 0.07em;
581
+ text-transform: uppercase;
582
+ }
583
+
584
+ #guide-content p,
585
+ #guide-content li {
586
+ color: var(--ink-soft);
587
+ font-size: clamp(1rem, 1.2vw, 1.12rem);
588
+ }
589
+
590
+ #guide-content p {
591
+ margin-top: 0;
592
+ margin-bottom: 1.15rem;
593
+ }
594
+
595
+ #guide-content ul,
596
+ #guide-content ol {
597
+ margin-top: 0.5rem;
598
+ margin-bottom: 1.75rem;
599
+ padding-left: 1.5rem;
600
+ }
601
+
602
+ #guide-content li {
603
+ margin-bottom: 0.48rem;
604
+ padding-left: 0.3rem;
605
+ }
606
+
607
+ #guide-content li::marker {
608
+ color: var(--orange-deep);
609
+ font-family: var(--mono);
610
+ font-weight: 900;
611
+ }
612
+
613
+ #guide-content blockquote {
614
+ position: relative;
615
+ margin-top: 2.25rem;
616
+ margin-bottom: 2.25rem;
617
+ padding: clamp(1.4rem, 3vw, 2.5rem);
618
+ border: var(--border-heavy);
619
+ border-left: 0.8rem solid var(--orange);
620
+ background: var(--paper);
621
+ }
622
+
623
+ #guide-content blockquote::before {
624
+ position: absolute;
625
+ top: 0.25rem;
626
+ right: 0.7rem;
627
+ color: var(--orange);
628
+ content: "\201C";
629
+ font-family: Georgia, serif;
630
+ font-size: 4rem;
631
+ font-weight: 900;
632
+ line-height: 1;
633
+ }
634
+
635
+ #guide-content blockquote p {
636
+ max-width: 52ch;
637
+ margin: 0;
638
+ color: var(--ink);
639
+ font-family: var(--display);
640
+ font-size: clamp(1.2rem, 2vw, 1.75rem);
641
+ font-weight: 850;
642
+ letter-spacing: -0.03em;
643
+ line-height: 1.2;
644
+ }
645
+
646
+ code,
647
+ kbd,
648
+ samp,
649
+ pre {
650
+ font-family: var(--mono);
651
+ }
652
+
653
+ code {
654
+ padding: 0.1em 0.26em;
655
+ color: var(--ink);
656
+ background: var(--paper-deep);
657
+ font-size: 0.88em;
658
+ overflow-wrap: anywhere;
659
+ }
660
+
661
+ pre {
662
+ position: relative;
663
+ margin-top: 1.5rem;
664
+ margin-bottom: 2rem;
665
+ padding: 2.6rem 1.25rem 1.25rem;
666
+ overflow-x: auto;
667
+ border: var(--border-heavy);
668
+ color: var(--paper-bright);
669
+ background: var(--ink);
670
+ font-size: clamp(0.74rem, 1vw, 0.9rem);
671
+ line-height: 1.65;
672
+ tab-size: 2;
673
+ }
674
+
675
+ pre::before {
676
+ position: absolute;
677
+ top: 0.62rem;
678
+ left: 0.75rem;
679
+ color: var(--paper-deep);
680
+ content: "EXAMPLE / READ-ONLY";
681
+ font-size: 0.58rem;
682
+ font-weight: 800;
683
+ letter-spacing: 0.1em;
684
+ }
685
+
686
+ pre code {
687
+ padding: 0;
688
+ color: inherit;
689
+ background: transparent;
690
+ font-size: inherit;
691
+ overflow-wrap: normal;
692
+ }
693
+
694
+ table {
695
+ width: 100%;
696
+ margin: 1.5rem 0 2.5rem;
697
+ border-collapse: collapse;
698
+ border: var(--border-heavy);
699
+ background: var(--paper-bright);
700
+ font-variant-numeric: tabular-nums;
701
+ }
702
+
703
+ caption {
704
+ padding: 0.7rem 0;
705
+ color: var(--muted);
706
+ font-family: var(--mono);
707
+ font-size: 0.68rem;
708
+ font-weight: 750;
709
+ letter-spacing: 0.06em;
710
+ text-align: left;
711
+ text-transform: uppercase;
712
+ }
713
+
714
+ th,
715
+ td {
716
+ padding: 0.82rem 0.9rem;
717
+ border-right: var(--border);
718
+ border-bottom: var(--border);
719
+ text-align: left;
720
+ vertical-align: top;
721
+ }
722
+
723
+ th:last-child,
724
+ td:last-child {
725
+ border-right: 0;
726
+ }
727
+
728
+ tr:last-child td {
729
+ border-bottom: 0;
730
+ }
731
+
732
+ th {
733
+ color: var(--ink);
734
+ background: var(--paper-deep);
735
+ font-family: var(--mono);
736
+ font-size: 0.68rem;
737
+ font-weight: 900;
738
+ letter-spacing: 0.055em;
739
+ text-transform: uppercase;
740
+ }
741
+
742
+ tbody tr:nth-child(even) {
743
+ background: rgba(223, 216, 202, 0.3);
744
+ }
745
+
746
+ tbody tr:hover {
747
+ background: rgba(255, 81, 0, 0.11);
748
+ }
749
+
750
+ .accounting-panel {
751
+ position: relative;
752
+ padding: clamp(1.25rem, 3vw, 2.5rem);
753
+ border: var(--border-heavy);
754
+ background: var(--paper-bright);
755
+ box-shadow: var(--shadow-offset);
756
+ }
757
+
758
+ .accounting-panel::after {
759
+ position: absolute;
760
+ right: 0.45rem;
761
+ bottom: 0.3rem;
762
+ color: var(--muted);
763
+ content: "CONTROLLED";
764
+ font-family: var(--mono);
765
+ font-size: 0.55rem;
766
+ letter-spacing: 0.11em;
767
+ }
768
+
769
+ .workflow-grid {
770
+ display: grid;
771
+ grid-template-columns: repeat(4, minmax(0, 1fr));
772
+ border-top: var(--border-heavy);
773
+ border-left: var(--border-heavy);
774
+ }
775
+
776
+ .workflow-step {
777
+ position: relative;
778
+ min-height: 15rem;
779
+ padding: 4rem 1.25rem 1.4rem;
780
+ border-right: var(--border-heavy);
781
+ border-bottom: var(--border-heavy);
782
+ background: var(--paper-bright);
783
+ }
784
+
785
+ .workflow-step::before {
786
+ position: absolute;
787
+ top: 1.1rem;
788
+ left: 1.2rem;
789
+ color: var(--orange-deep);
790
+ content: attr(data-step);
791
+ font-family: var(--display);
792
+ font-size: 1.5rem;
793
+ font-weight: 950;
794
+ line-height: 1;
795
+ }
796
+
797
+ .workflow-step::after {
798
+ position: absolute;
799
+ top: 1.25rem;
800
+ right: -0.42rem;
801
+ z-index: 2;
802
+ width: 0.78rem;
803
+ height: 0.78rem;
804
+ background: var(--orange);
805
+ content: "";
806
+ }
807
+
808
+ .workflow-step:last-child::after {
809
+ display: none;
810
+ }
811
+
812
+ .workflow-step h3 {
813
+ margin: 0 0 0.7rem;
814
+ font-family: var(--display);
815
+ font-size: 1.35rem;
816
+ letter-spacing: -0.035em;
817
+ line-height: 1.05;
818
+ text-transform: uppercase;
819
+ }
820
+
821
+ .workflow-step p {
822
+ margin: 0;
823
+ color: var(--muted);
824
+ font-size: 0.92rem;
825
+ }
826
+
827
+ .demo-shell {
828
+ padding: clamp(3rem, 7vw, 7rem) var(--gutter);
829
+ background: var(--ink);
830
+ color: var(--paper-bright);
831
+ }
832
+
833
+ .demo-shell .section-heading p {
834
+ color: var(--paper-deep);
835
+ }
836
+
837
+ .demo-shell .section-label {
838
+ color: var(--ink);
839
+ }
840
+
841
+ #demo-tabs,
842
+ [role="tablist"] {
843
+ display: flex;
844
+ gap: 0;
845
+ margin-top: var(--space-5);
846
+ overflow-x: auto;
847
+ border: 1px solid var(--paper-deep);
848
+ scrollbar-width: thin;
849
+ }
850
+
851
+ #demo-tabs button,
852
+ [role="tab"] {
853
+ min-height: 3.25rem;
854
+ padding: 0.85rem 1.15rem;
855
+ flex: 1 0 auto;
856
+ border: 0;
857
+ border-right: 1px solid var(--paper-deep);
858
+ color: var(--paper-bright);
859
+ background: transparent;
860
+ font-family: var(--mono);
861
+ font-size: 0.69rem;
862
+ font-weight: 900;
863
+ letter-spacing: 0.065em;
864
+ text-transform: uppercase;
865
+ }
866
+
867
+ #demo-tabs button:last-child,
868
+ [role="tab"]:last-child {
869
+ border-right: 0;
870
+ }
871
+
872
+ #demo-tabs button:hover,
873
+ [role="tab"]:hover {
874
+ color: var(--ink);
875
+ background: var(--paper-deep);
876
+ }
877
+
878
+ #demo-tabs button[aria-selected="true"],
879
+ [role="tab"][aria-selected="true"] {
880
+ color: var(--ink);
881
+ background: var(--orange);
882
+ }
883
+
884
+ [role="tabpanel"] {
885
+ padding: clamp(1.2rem, 3vw, 2.25rem);
886
+ border: 1px solid var(--paper-deep);
887
+ border-top: 0;
888
+ background: var(--paper-bright);
889
+ color: var(--ink);
890
+ }
891
+
892
+ .demo-grid {
893
+ display: grid;
894
+ grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
895
+ gap: 0;
896
+ border: var(--border-heavy);
897
+ background: var(--paper-bright);
898
+ color: var(--ink);
899
+ }
900
+
901
+ .demo-grid > * {
902
+ min-width: 0;
903
+ padding: clamp(1.15rem, 3vw, 2.35rem);
904
+ }
905
+
906
+ .demo-grid > * + * {
907
+ border-left: var(--border-heavy);
908
+ }
909
+
910
+ label {
911
+ display: block;
912
+ margin-bottom: 0.4rem;
913
+ color: var(--ink);
914
+ font-family: var(--mono);
915
+ font-size: 0.67rem;
916
+ font-weight: 900;
917
+ letter-spacing: 0.06em;
918
+ text-transform: uppercase;
919
+ }
920
+
921
+ input,
922
+ select,
923
+ textarea {
924
+ width: 100%;
925
+ min-height: 3rem;
926
+ padding: 0.7rem 0.8rem;
927
+ border: var(--border-heavy);
928
+ border-radius: 0;
929
+ color: var(--ink);
930
+ background: var(--paper-bright);
931
+ }
932
+
933
+ input:hover,
934
+ select:hover,
935
+ textarea:hover {
936
+ border-color: var(--orange-deep);
937
+ }
938
+
939
+ input:disabled,
940
+ select:disabled,
941
+ textarea:disabled {
942
+ cursor: not-allowed;
943
+ opacity: 0.62;
944
+ }
945
+
946
+ button,
947
+ .button,
948
+ [role="button"] {
949
+ display: inline-flex;
950
+ min-height: 3rem;
951
+ padding: 0.72rem 1rem;
952
+ align-items: center;
953
+ justify-content: center;
954
+ border: var(--border-heavy);
955
+ border-radius: 0;
956
+ color: var(--ink);
957
+ background: var(--paper-bright);
958
+ font-family: var(--mono);
959
+ font-size: 0.7rem;
960
+ font-weight: 900;
961
+ letter-spacing: 0.055em;
962
+ line-height: 1.2;
963
+ text-decoration: none;
964
+ text-transform: uppercase;
965
+ transition:
966
+ background-color 120ms ease,
967
+ color 120ms ease,
968
+ transform 120ms ease,
969
+ box-shadow 120ms ease;
970
+ }
971
+
972
+ button:hover,
973
+ .button:hover,
974
+ [role="button"]:hover {
975
+ color: var(--paper-bright);
976
+ background: var(--ink);
977
+ }
978
+
979
+ button:active,
980
+ .button:active,
981
+ [role="button"]:active {
982
+ transform: translate(2px, 2px);
983
+ }
984
+
985
+ button:disabled,
986
+ .button[aria-disabled="true"] {
987
+ cursor: not-allowed;
988
+ opacity: 0.55;
989
+ }
990
+
991
+ #run-review,
992
+ .button-primary,
993
+ button.primary {
994
+ width: 100%;
995
+ min-height: 3.65rem;
996
+ margin-top: var(--space-3);
997
+ color: var(--ink);
998
+ background: var(--orange);
999
+ box-shadow: 5px 5px 0 var(--ink);
1000
+ }
1001
+
1002
+ #run-review:hover,
1003
+ .button-primary:hover,
1004
+ button.primary:hover {
1005
+ color: var(--paper-bright);
1006
+ background: var(--ink);
1007
+ box-shadow: 5px 5px 0 var(--orange);
1008
+ }
1009
+
1010
+ .status-strip {
1011
+ display: flex;
1012
+ min-height: 3rem;
1013
+ margin: 0;
1014
+ padding: 0.65rem 0.9rem;
1015
+ align-items: center;
1016
+ justify-content: space-between;
1017
+ gap: var(--space-3);
1018
+ border: var(--border-heavy);
1019
+ color: var(--ink);
1020
+ background: var(--paper-deep);
1021
+ font-family: var(--mono);
1022
+ font-size: 0.67rem;
1023
+ font-weight: 800;
1024
+ letter-spacing: 0.045em;
1025
+ text-transform: uppercase;
1026
+ }
1027
+
1028
+ .status-strip[data-status="ready"]::before,
1029
+ .status-strip[data-status="pass"]::before {
1030
+ width: 0.62rem;
1031
+ height: 0.62rem;
1032
+ flex: 0 0 auto;
1033
+ border-radius: 50%;
1034
+ background: var(--success);
1035
+ content: "";
1036
+ }
1037
+
1038
+ .status-strip[data-status="review"]::before {
1039
+ width: 0.62rem;
1040
+ height: 0.62rem;
1041
+ flex: 0 0 auto;
1042
+ background: var(--orange);
1043
+ content: "";
1044
+ }
1045
+
1046
+ .caveat {
1047
+ position: relative;
1048
+ margin: var(--space-5) 0;
1049
+ padding: 1.15rem 1.25rem 1.15rem 3.5rem;
1050
+ border: var(--border-heavy);
1051
+ color: var(--ink);
1052
+ background: #ffd9c7;
1053
+ font-size: 0.92rem;
1054
+ }
1055
+
1056
+ .caveat::before {
1057
+ position: absolute;
1058
+ top: 50%;
1059
+ left: 1.1rem;
1060
+ color: var(--ink);
1061
+ content: "!";
1062
+ font-family: var(--display);
1063
+ font-size: 1.55rem;
1064
+ font-weight: 950;
1065
+ transform: translateY(-50%);
1066
+ }
1067
+
1068
+ .caveat strong {
1069
+ font-family: var(--mono);
1070
+ font-size: 0.75rem;
1071
+ letter-spacing: 0.04em;
1072
+ text-transform: uppercase;
1073
+ }
1074
+
1075
+ .audit-stamp {
1076
+ display: inline-grid;
1077
+ width: min(100%, 14rem);
1078
+ min-height: 5.6rem;
1079
+ padding: 0.65rem;
1080
+ place-content: center;
1081
+ border: 3px double var(--success);
1082
+ color: var(--success);
1083
+ background: transparent;
1084
+ font-family: var(--mono);
1085
+ font-size: 0.72rem;
1086
+ font-weight: 900;
1087
+ letter-spacing: 0.1em;
1088
+ line-height: 1.35;
1089
+ text-align: center;
1090
+ text-transform: uppercase;
1091
+ transform: rotate(-1.5deg);
1092
+ }
1093
+
1094
+ .audit-stamp[data-state="review"] {
1095
+ border-color: var(--orange-deep);
1096
+ color: var(--orange-deep);
1097
+ }
1098
+
1099
+ .audit-stamp[data-state="blocked"] {
1100
+ border-color: var(--danger);
1101
+ color: var(--danger);
1102
+ }
1103
+
1104
+ details {
1105
+ border-top: var(--border);
1106
+ border-right: var(--border);
1107
+ border-left: var(--border);
1108
+ background: var(--paper-bright);
1109
+ }
1110
+
1111
+ details:last-of-type {
1112
+ border-bottom: var(--border);
1113
+ }
1114
+
1115
+ summary {
1116
+ position: relative;
1117
+ padding: 1rem 3.2rem 1rem 1rem;
1118
+ cursor: pointer;
1119
+ font-family: var(--mono);
1120
+ font-size: 0.74rem;
1121
+ font-weight: 900;
1122
+ letter-spacing: 0.045em;
1123
+ list-style: none;
1124
+ text-transform: uppercase;
1125
+ }
1126
+
1127
+ summary::-webkit-details-marker {
1128
+ display: none;
1129
+ }
1130
+
1131
+ summary::after {
1132
+ position: absolute;
1133
+ top: 50%;
1134
+ right: 1rem;
1135
+ content: "+";
1136
+ font-family: var(--display);
1137
+ font-size: 1.4rem;
1138
+ transform: translateY(-50%);
1139
+ }
1140
+
1141
+ details[open] summary {
1142
+ color: var(--ink);
1143
+ background: var(--orange);
1144
+ }
1145
+
1146
+ details[open] summary::after {
1147
+ content: "\2212";
1148
+ }
1149
+
1150
+ details > :not(summary) {
1151
+ margin-right: 1rem;
1152
+ margin-left: 1rem;
1153
+ }
1154
+
1155
+ details > :last-child {
1156
+ margin-bottom: 1.25rem;
1157
+ }
1158
+
1159
+ .site-footer {
1160
+ display: grid;
1161
+ padding: clamp(2rem, 4vw, 4rem) var(--gutter);
1162
+ grid-template-columns: minmax(0, 1fr) auto;
1163
+ gap: var(--space-5);
1164
+ border-right: var(--border-heavy);
1165
+ border-bottom: var(--border-heavy);
1166
+ border-left: var(--border-heavy);
1167
+ color: var(--paper-bright);
1168
+ background: var(--ink);
1169
+ }
1170
+
1171
+ .footer-note {
1172
+ max-width: 62ch;
1173
+ margin: 0;
1174
+ color: var(--paper-deep);
1175
+ font-size: 0.84rem;
1176
+ }
1177
+
1178
+ .site-footer nav,
1179
+ .site-footer .footer-links {
1180
+ display: flex;
1181
+ flex-wrap: wrap;
1182
+ gap: 0.75rem 1.15rem;
1183
+ align-content: start;
1184
+ justify-content: flex-end;
1185
+ }
1186
+
1187
+ .site-footer a {
1188
+ color: var(--paper-bright);
1189
+ font-family: var(--mono);
1190
+ font-size: 0.68rem;
1191
+ font-weight: 800;
1192
+ letter-spacing: 0.05em;
1193
+ text-transform: uppercase;
1194
+ }
1195
+
1196
+ .site-footer a:hover {
1197
+ color: var(--orange);
1198
+ }
1199
+
1200
+ .mono,
1201
+ .metadata,
1202
+ .construction-note {
1203
+ font-family: var(--mono);
1204
+ font-variant-numeric: tabular-nums;
1205
+ }
1206
+
1207
+ .construction-note {
1208
+ color: var(--muted);
1209
+ font-size: 0.63rem;
1210
+ font-weight: 700;
1211
+ letter-spacing: 0.075em;
1212
+ text-transform: uppercase;
1213
+ }
1214
+
1215
+ .numeric {
1216
+ font-variant-numeric: tabular-nums;
1217
+ text-align: right;
1218
+ }
1219
+
1220
+ .sr-only {
1221
+ position: absolute !important;
1222
+ width: 1px !important;
1223
+ height: 1px !important;
1224
+ padding: 0 !important;
1225
+ overflow: hidden !important;
1226
+ border: 0 !important;
1227
+ clip: rect(0, 0, 0, 0) !important;
1228
+ white-space: nowrap !important;
1229
+ }
1230
+
1231
+ @media (max-width: 980px) {
1232
+ #hero,
1233
+ .hero {
1234
+ min-height: auto;
1235
+ grid-template-columns: 1fr;
1236
+ }
1237
+
1238
+ .hero-copy {
1239
+ min-height: 38rem;
1240
+ }
1241
+
1242
+ .hero-aside {
1243
+ min-height: 22rem;
1244
+ border-top: var(--border-heavy);
1245
+ border-left: 0;
1246
+ }
1247
+
1248
+ .stats-grid {
1249
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1250
+ }
1251
+
1252
+ .stat-card:nth-child(odd) {
1253
+ border-left: 0;
1254
+ }
1255
+
1256
+ .stat-card:nth-child(n + 3) {
1257
+ border-top: var(--border);
1258
+ }
1259
+
1260
+ .section-heading {
1261
+ grid-template-columns: 1fr;
1262
+ }
1263
+
1264
+ .workflow-grid {
1265
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1266
+ }
1267
+
1268
+ .workflow-step:nth-child(even)::after {
1269
+ display: none;
1270
+ }
1271
+
1272
+ .demo-grid {
1273
+ grid-template-columns: 1fr;
1274
+ }
1275
+
1276
+ .demo-grid > * + * {
1277
+ border-top: var(--border-heavy);
1278
+ border-left: 0;
1279
+ }
1280
+ }
1281
+
1282
+ @media (max-width: 720px) {
1283
+ html {
1284
+ scroll-padding-top: 4.4rem;
1285
+ }
1286
+
1287
+ body {
1288
+ background-size: 32px 32px;
1289
+ }
1290
+
1291
+ .site-nav {
1292
+ min-height: 3.8rem;
1293
+ }
1294
+
1295
+ .site-nav .brand,
1296
+ .site-nav > a:first-child {
1297
+ min-width: 0;
1298
+ padding-inline: 0.85rem;
1299
+ }
1300
+
1301
+ .site-nav ul,
1302
+ .site-nav .nav-links {
1303
+ max-width: 62%;
1304
+ overflow-x: auto;
1305
+ }
1306
+
1307
+ .site-nav li a,
1308
+ .site-nav .nav-links > a {
1309
+ min-height: 3.7rem;
1310
+ padding-inline: 0.82rem;
1311
+ white-space: nowrap;
1312
+ }
1313
+
1314
+ .hero-copy {
1315
+ min-height: 33rem;
1316
+ padding-top: 5.8rem;
1317
+ }
1318
+
1319
+ #hero h1,
1320
+ .hero h1 {
1321
+ font-size: clamp(3.15rem, 18vw, 5.3rem);
1322
+ }
1323
+
1324
+ .hero-aside {
1325
+ min-height: 20rem;
1326
+ }
1327
+
1328
+ .stats-grid {
1329
+ grid-template-columns: 1fr;
1330
+ }
1331
+
1332
+ .stat-card {
1333
+ min-height: 8.5rem;
1334
+ }
1335
+
1336
+ .stat-card + .stat-card,
1337
+ .stat-card:nth-child(n + 3) {
1338
+ border-top: var(--border);
1339
+ border-left: 0;
1340
+ }
1341
+
1342
+ #guide-content > h1 {
1343
+ font-size: clamp(2.65rem, 14vw, 4.5rem);
1344
+ }
1345
+
1346
+ #guide-content h2 {
1347
+ margin-top: 4.8rem;
1348
+ }
1349
+
1350
+ .workflow-grid {
1351
+ grid-template-columns: 1fr;
1352
+ }
1353
+
1354
+ .workflow-step {
1355
+ min-height: 11rem;
1356
+ }
1357
+
1358
+ .workflow-step::after {
1359
+ display: none;
1360
+ }
1361
+
1362
+ .site-footer {
1363
+ grid-template-columns: 1fr;
1364
+ }
1365
+
1366
+ .site-footer nav,
1367
+ .site-footer .footer-links {
1368
+ justify-content: flex-start;
1369
+ }
1370
+
1371
+ table {
1372
+ display: block;
1373
+ max-width: 100%;
1374
+ overflow-x: auto;
1375
+ white-space: nowrap;
1376
+ }
1377
+
1378
+ #guide-content blockquote {
1379
+ padding-right: 1.1rem;
1380
+ }
1381
+ }
1382
+
1383
+ @media (max-width: 430px) {
1384
+ .site-nav .brand,
1385
+ .site-nav > a:first-child {
1386
+ font-size: 0;
1387
+ }
1388
+
1389
+ .site-nav .brand::before,
1390
+ .site-nav > a:first-child::before {
1391
+ width: 1rem;
1392
+ height: 1rem;
1393
+ margin: 0;
1394
+ }
1395
+
1396
+ .site-nav ul,
1397
+ .site-nav .nav-links {
1398
+ max-width: calc(100% - 3.3rem);
1399
+ }
1400
+
1401
+ .hero-copy {
1402
+ min-height: 30rem;
1403
+ }
1404
+
1405
+ .hero-deck,
1406
+ .hero-copy > p {
1407
+ font-size: 1rem;
1408
+ }
1409
+
1410
+ .audit-stamp {
1411
+ width: 100%;
1412
+ }
1413
+ }
1414
+
1415
+ @media (prefers-reduced-motion: reduce) {
1416
+ *,
1417
+ *::before,
1418
+ *::after {
1419
+ scroll-behavior: auto !important;
1420
+ transition-duration: 0.01ms !important;
1421
+ animation-duration: 0.01ms !important;
1422
+ animation-iteration-count: 1 !important;
1423
+ }
1424
+ }
1425
+
1426
+ @media (forced-colors: active) {
1427
+ :focus-visible {
1428
+ outline: 3px solid Highlight;
1429
+ }
1430
+
1431
+ .eyebrow,
1432
+ .quote-label,
1433
+ .section-label,
1434
+ .model-badge::before,
1435
+ .workflow-step::after {
1436
+ forced-color-adjust: none;
1437
+ background: Highlight;
1438
+ }
1439
+ }
1440
+
1441
+ @media print {
1442
+ :root {
1443
+ --paper: #fff;
1444
+ --paper-bright: #fff;
1445
+ --paper-deep: #eee;
1446
+ --ink: #000;
1447
+ }
1448
+
1449
+ body {
1450
+ background: #fff;
1451
+ font-size: 10.5pt;
1452
+ }
1453
+
1454
+ .site-nav,
1455
+ .demo-shell,
1456
+ .skip-link,
1457
+ button {
1458
+ display: none !important;
1459
+ }
1460
+
1461
+ #hero,
1462
+ .hero {
1463
+ min-height: auto;
1464
+ grid-template-columns: 1fr;
1465
+ }
1466
+
1467
+ .hero-copy {
1468
+ min-height: auto;
1469
+ padding: 2rem;
1470
+ }
1471
+
1472
+ .hero-aside {
1473
+ min-height: auto;
1474
+ border-top: var(--border);
1475
+ border-left: 0;
1476
+ color: #000;
1477
+ background: #fff;
1478
+ }
1479
+
1480
+ .hero-aside p,
1481
+ .footer-note {
1482
+ color: #000;
1483
+ }
1484
+
1485
+ #guide-content h2,
1486
+ #guide-content h3,
1487
+ pre,
1488
+ blockquote,
1489
+ table,
1490
+ details {
1491
+ break-inside: avoid;
1492
+ }
1493
+
1494
+ a {
1495
+ color: #000;
1496
+ }
1497
+
1498
+ a[href^="http"]::after {
1499
+ content: " (" attr(href) ")";
1500
+ font-family: var(--mono);
1501
+ font-size: 0.72em;
1502
+ overflow-wrap: anywhere;
1503
+ }
1504
+ }
1505
+
1506
+ /* --------------------------------------------------------------------------
1507
+ Static Space compatibility layer
1508
+ -------------------------------------------------------------------------- */
1509
+
1510
+ .topbar {
1511
+ position: sticky;
1512
+ z-index: 100;
1513
+ top: 0;
1514
+ display: flex;
1515
+ width: min(100%, var(--site-width));
1516
+ min-height: 4.25rem;
1517
+ margin-inline: auto;
1518
+ align-items: stretch;
1519
+ justify-content: space-between;
1520
+ border-right: var(--border);
1521
+ border-bottom: var(--border-heavy);
1522
+ border-left: var(--border);
1523
+ background: rgba(242, 238, 228, 0.96);
1524
+ backdrop-filter: blur(14px);
1525
+ }
1526
+
1527
+ .topbar .wordmark {
1528
+ display: inline-flex;
1529
+ min-width: 17rem;
1530
+ padding: 0.75rem var(--gutter);
1531
+ align-items: center;
1532
+ gap: 0.65rem;
1533
+ border-right: var(--border);
1534
+ color: var(--ink);
1535
+ font-family: var(--display);
1536
+ font-size: 0.78rem;
1537
+ font-weight: 900;
1538
+ letter-spacing: -0.01em;
1539
+ line-height: 1;
1540
+ text-decoration: none;
1541
+ text-transform: uppercase;
1542
+ }
1543
+
1544
+ .wordmark-mark {
1545
+ display: inline-grid;
1546
+ width: 2.15rem;
1547
+ height: 2.15rem;
1548
+ flex: 0 0 auto;
1549
+ place-items: center;
1550
+ color: var(--ink);
1551
+ background: var(--orange);
1552
+ font-family: var(--display);
1553
+ font-size: 0.68rem;
1554
+ font-weight: 950;
1555
+ letter-spacing: -0.04em;
1556
+ }
1557
+
1558
+ .topbar nav {
1559
+ display: flex;
1560
+ margin: 0;
1561
+ align-items: stretch;
1562
+ overflow-x: auto;
1563
+ }
1564
+
1565
+ .topbar nav a {
1566
+ display: inline-flex;
1567
+ min-height: 4.125rem;
1568
+ padding: 0.75rem 1.15rem;
1569
+ align-items: center;
1570
+ border-left: var(--border);
1571
+ color: var(--ink);
1572
+ font-family: var(--mono);
1573
+ font-size: 0.68rem;
1574
+ font-weight: 800;
1575
+ letter-spacing: 0.055em;
1576
+ text-decoration: none;
1577
+ text-transform: uppercase;
1578
+ white-space: nowrap;
1579
+ }
1580
+
1581
+ .topbar nav a:hover {
1582
+ color: var(--ink);
1583
+ background: var(--orange);
1584
+ }
1585
+
1586
+ .hero-actions {
1587
+ display: flex;
1588
+ max-width: 46rem;
1589
+ margin-top: var(--space-5);
1590
+ flex-wrap: wrap;
1591
+ gap: 0.75rem;
1592
+ }
1593
+
1594
+ .hero-actions .button {
1595
+ width: auto;
1596
+ margin-top: 0;
1597
+ }
1598
+
1599
+ .hero-actions .button-primary {
1600
+ box-shadow: 5px 5px 0 var(--ink);
1601
+ }
1602
+
1603
+ .hero-actions .button-ghost {
1604
+ background: transparent;
1605
+ }
1606
+
1607
+ .signal-dot {
1608
+ display: inline-block;
1609
+ width: 0.52rem;
1610
+ height: 0.52rem;
1611
+ margin-right: 0.1rem;
1612
+ flex: 0 0 auto;
1613
+ border-radius: 50%;
1614
+ background: var(--orange);
1615
+ box-shadow: 0 0 0 3px rgba(255, 81, 0, 0.2);
1616
+ }
1617
+
1618
+ .model-badge:has(.signal-dot)::before {
1619
+ display: none;
1620
+ }
1621
+
1622
+ .microcopy {
1623
+ color: var(--muted);
1624
+ font-family: var(--mono);
1625
+ font-size: 0.67rem;
1626
+ letter-spacing: 0.035em;
1627
+ line-height: 1.55;
1628
+ }
1629
+
1630
+ .stat-index {
1631
+ margin-top: 0 !important;
1632
+ color: var(--orange-deep) !important;
1633
+ }
1634
+
1635
+ .stats-footnote {
1636
+ margin: 0;
1637
+ padding: 0.8rem var(--space-4);
1638
+ grid-column: 1 / -1;
1639
+ border-top: var(--border);
1640
+ color: var(--muted);
1641
+ font-family: var(--mono);
1642
+ font-size: 0.64rem;
1643
+ font-weight: 700;
1644
+ letter-spacing: 0.035em;
1645
+ line-height: 1.45;
1646
+ text-transform: uppercase;
1647
+ }
1648
+
1649
+ .demo-shell {
1650
+ display: grid;
1651
+ padding: 0;
1652
+ grid-template-columns: minmax(0, 0.92fr) minmax(18rem, 1.08fr);
1653
+ color: var(--ink);
1654
+ background: var(--paper-bright);
1655
+ }
1656
+
1657
+ .demo-controls,
1658
+ .demo-case-note {
1659
+ min-width: 0;
1660
+ padding: clamp(1.5rem, 4vw, 3.5rem);
1661
+ }
1662
+
1663
+ .demo-controls {
1664
+ background: var(--paper-bright);
1665
+ }
1666
+
1667
+ .demo-controls label:not(:first-child) {
1668
+ margin-top: 1.5rem;
1669
+ }
1670
+
1671
+ .demo-controls output {
1672
+ float: right;
1673
+ min-width: 3.2rem;
1674
+ padding: 0.15rem 0.35rem;
1675
+ color: var(--paper-bright);
1676
+ background: var(--ink);
1677
+ font-variant-numeric: tabular-nums;
1678
+ text-align: center;
1679
+ }
1680
+
1681
+ .demo-case-note {
1682
+ display: flex;
1683
+ flex-direction: column;
1684
+ justify-content: space-between;
1685
+ border-left: var(--border-heavy);
1686
+ color: var(--paper-bright);
1687
+ background-color: var(--ink);
1688
+ background-image: repeating-linear-gradient(
1689
+ -45deg,
1690
+ transparent,
1691
+ transparent 19px,
1692
+ rgba(255, 255, 255, 0.045) 20px,
1693
+ rgba(255, 255, 255, 0.045) 21px
1694
+ );
1695
+ }
1696
+
1697
+ .demo-case-note h3 {
1698
+ max-width: 14ch;
1699
+ margin: 0 0 1rem;
1700
+ font-family: var(--display);
1701
+ font-size: clamp(1.8rem, 3.7vw, 3.75rem);
1702
+ font-weight: 950;
1703
+ letter-spacing: -0.06em;
1704
+ line-height: 0.95;
1705
+ text-transform: uppercase;
1706
+ }
1707
+
1708
+ .demo-case-note > p:not(.quote-label) {
1709
+ max-width: 40ch;
1710
+ color: var(--paper-deep);
1711
+ }
1712
+
1713
+ .demo-case-note dl {
1714
+ display: grid;
1715
+ margin: var(--space-5) 0 0;
1716
+ grid-template-columns: repeat(3, minmax(0, 1fr));
1717
+ border-top: 1px solid var(--paper-deep);
1718
+ border-left: 1px solid var(--paper-deep);
1719
+ }
1720
+
1721
+ .demo-case-note dl > div {
1722
+ min-width: 0;
1723
+ padding: 0.72rem;
1724
+ border-right: 1px solid var(--paper-deep);
1725
+ border-bottom: 1px solid var(--paper-deep);
1726
+ }
1727
+
1728
+ .demo-case-note dt {
1729
+ color: var(--paper-deep);
1730
+ font-family: var(--mono);
1731
+ font-size: 0.57rem;
1732
+ font-weight: 800;
1733
+ letter-spacing: 0.07em;
1734
+ text-transform: uppercase;
1735
+ }
1736
+
1737
+ .demo-case-note dd {
1738
+ margin: 0.35rem 0 0;
1739
+ color: var(--paper-bright);
1740
+ font-family: var(--mono);
1741
+ font-size: 0.69rem;
1742
+ font-weight: 800;
1743
+ overflow-wrap: anywhere;
1744
+ }
1745
+
1746
+ input[type="range"] {
1747
+ height: 2.8rem;
1748
+ padding: 0;
1749
+ border: 0;
1750
+ accent-color: var(--orange);
1751
+ background: transparent;
1752
+ }
1753
+
1754
+ input[type="range"]::-webkit-slider-runnable-track {
1755
+ height: 0.45rem;
1756
+ border: 1px solid var(--ink);
1757
+ background: var(--paper-deep);
1758
+ }
1759
+
1760
+ input[type="range"]::-webkit-slider-thumb {
1761
+ width: 1.3rem;
1762
+ height: 1.3rem;
1763
+ margin-top: -0.49rem;
1764
+ appearance: none;
1765
+ border: 2px solid var(--ink);
1766
+ border-radius: 0;
1767
+ background: var(--orange);
1768
+ }
1769
+
1770
+ input[type="range"]::-moz-range-track {
1771
+ height: 0.45rem;
1772
+ border: 1px solid var(--ink);
1773
+ background: var(--paper-deep);
1774
+ }
1775
+
1776
+ input[type="range"]::-moz-range-thumb {
1777
+ width: 1.15rem;
1778
+ height: 1.15rem;
1779
+ border: 2px solid var(--ink);
1780
+ border-radius: 0;
1781
+ background: var(--orange);
1782
+ }
1783
+
1784
+ .model-status {
1785
+ min-height: 2.6rem;
1786
+ margin: 1.4rem 0 0;
1787
+ padding: 0.7rem 0;
1788
+ border-top: var(--border);
1789
+ border-bottom: var(--border);
1790
+ color: var(--muted);
1791
+ font-family: var(--mono);
1792
+ font-size: 0.63rem;
1793
+ font-weight: 800;
1794
+ letter-spacing: 0.055em;
1795
+ line-height: 1.45;
1796
+ text-transform: uppercase;
1797
+ }
1798
+
1799
+ .model-status::before {
1800
+ display: inline-block;
1801
+ width: 0.52rem;
1802
+ height: 0.52rem;
1803
+ margin-right: 0.5rem;
1804
+ border-radius: 50%;
1805
+ background: var(--orange);
1806
+ content: "";
1807
+ }
1808
+
1809
+ .status-strip > div {
1810
+ display: flex;
1811
+ align-items: center;
1812
+ gap: 0.55rem;
1813
+ }
1814
+
1815
+ .status-strip span {
1816
+ color: var(--muted);
1817
+ font-size: 0.57rem;
1818
+ }
1819
+
1820
+ .status-strip strong {
1821
+ font-size: 0.7rem;
1822
+ }
1823
+
1824
+ .status-standard {
1825
+ border-color: var(--success);
1826
+ background: #d8e8df;
1827
+ }
1828
+
1829
+ .status-review {
1830
+ border-color: var(--orange-deep);
1831
+ background: #ffd9c7;
1832
+ }
1833
+
1834
+ .status-error {
1835
+ border-color: var(--danger);
1836
+ background: #f2d6d2;
1837
+ }
1838
+
1839
+ .demo-output {
1840
+ margin-top: var(--space-5);
1841
+ scroll-margin-top: 5.5rem;
1842
+ }
1843
+
1844
+ .demo-output > .stats-grid {
1845
+ border-top: 0;
1846
+ }
1847
+
1848
+ .stats-grid.compact .stat-card {
1849
+ min-height: 8.5rem;
1850
+ background: var(--paper-bright);
1851
+ }
1852
+
1853
+ .stats-grid.compact .stat-card strong {
1854
+ font-size: clamp(1.8rem, 3vw, 3.25rem);
1855
+ }
1856
+
1857
+ .table-block {
1858
+ border-right: var(--border-heavy);
1859
+ border-bottom: var(--border-heavy);
1860
+ border-left: var(--border-heavy);
1861
+ background: var(--paper-bright);
1862
+ }
1863
+
1864
+ .table-heading {
1865
+ display: flex;
1866
+ min-height: 4.5rem;
1867
+ padding: 1rem 1.2rem;
1868
+ align-items: center;
1869
+ justify-content: space-between;
1870
+ gap: 1rem;
1871
+ border-bottom: var(--border-heavy);
1872
+ color: var(--paper-bright);
1873
+ background: var(--ink);
1874
+ }
1875
+
1876
+ .table-heading .section-label {
1877
+ margin: 0;
1878
+ }
1879
+
1880
+ .table-heading > p:last-child {
1881
+ margin: 0;
1882
+ color: var(--paper-deep);
1883
+ font-family: var(--mono);
1884
+ font-size: 0.64rem;
1885
+ text-align: right;
1886
+ text-transform: uppercase;
1887
+ }
1888
+
1889
+ .table-scroll {
1890
+ max-width: 100%;
1891
+ overflow-x: auto;
1892
+ }
1893
+
1894
+ .table-scroll table {
1895
+ min-width: 48rem;
1896
+ margin: 0;
1897
+ border: 0;
1898
+ }
1899
+
1900
+ .amount {
1901
+ font-family: var(--mono);
1902
+ font-variant-numeric: tabular-nums;
1903
+ font-weight: 750;
1904
+ white-space: nowrap;
1905
+ }
1906
+
1907
+ .signal {
1908
+ display: inline-flex;
1909
+ padding: 0.28rem 0.42rem;
1910
+ border: 1px solid currentColor;
1911
+ color: var(--ink-soft);
1912
+ background: var(--paper-deep);
1913
+ font-family: var(--mono);
1914
+ font-size: 0.59rem;
1915
+ font-weight: 850;
1916
+ letter-spacing: 0.035em;
1917
+ line-height: 1.25;
1918
+ text-transform: uppercase;
1919
+ white-space: nowrap;
1920
+ }
1921
+
1922
+ .signal-none,
1923
+ .signal-match {
1924
+ color: var(--success);
1925
+ background: #d8e8df;
1926
+ }
1927
+
1928
+ .signal-bank-fee,
1929
+ .signal-review,
1930
+ .signal-unmatched {
1931
+ color: var(--orange-deep);
1932
+ background: #ffd9c7;
1933
+ }
1934
+
1935
+ .record-details {
1936
+ border: var(--border-heavy);
1937
+ border-top: 0;
1938
+ }
1939
+
1940
+ .record-grid {
1941
+ display: grid;
1942
+ margin: 0 !important;
1943
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1944
+ }
1945
+
1946
+ .record-grid > div {
1947
+ min-width: 0;
1948
+ padding: var(--space-4);
1949
+ }
1950
+
1951
+ .record-grid > div + div {
1952
+ border-left: var(--border-heavy);
1953
+ }
1954
+
1955
+ .record-grid h3 {
1956
+ margin: 0 0 1rem;
1957
+ font-family: var(--display);
1958
+ font-size: 1.25rem;
1959
+ letter-spacing: -0.03em;
1960
+ text-transform: uppercase;
1961
+ }
1962
+
1963
+ .disclosure-panel {
1964
+ position: relative;
1965
+ padding: clamp(2.5rem, 6vw, 5.5rem) var(--gutter);
1966
+ overflow: hidden;
1967
+ border-right: var(--border-heavy);
1968
+ border-bottom: var(--border-heavy);
1969
+ border-left: var(--border-heavy);
1970
+ background: var(--orange);
1971
+ }
1972
+
1973
+ .disclosure-panel::after {
1974
+ position: absolute;
1975
+ right: -0.06em;
1976
+ bottom: -0.3em;
1977
+ color: rgba(17, 17, 15, 0.09);
1978
+ content: "!";
1979
+ font-family: var(--display);
1980
+ font-size: clamp(12rem, 31vw, 30rem);
1981
+ font-weight: 950;
1982
+ line-height: 0.7;
1983
+ pointer-events: none;
1984
+ }
1985
+
1986
+ .disclosure-panel > * {
1987
+ position: relative;
1988
+ z-index: 1;
1989
+ max-width: 72ch;
1990
+ }
1991
+
1992
+ .disclosure-panel .section-label {
1993
+ color: var(--paper-bright);
1994
+ background: var(--ink);
1995
+ }
1996
+
1997
+ .disclosure-panel h2 {
1998
+ max-width: 13ch;
1999
+ margin: 0 0 1.5rem;
2000
+ font-family: var(--display);
2001
+ font-size: clamp(2.6rem, 6vw, 6rem);
2002
+ font-weight: 950;
2003
+ letter-spacing: -0.07em;
2004
+ line-height: 0.88;
2005
+ text-transform: uppercase;
2006
+ }
2007
+
2008
+ .disclosure-panel > p:not(.section-label) {
2009
+ color: var(--ink);
2010
+ font-size: 1.05rem;
2011
+ font-weight: 600;
2012
+ }
2013
+
2014
+ .link-row {
2015
+ display: flex;
2016
+ margin-top: var(--space-5);
2017
+ flex-wrap: wrap;
2018
+ gap: 0.65rem;
2019
+ }
2020
+
2021
+ .link-row a {
2022
+ display: inline-flex;
2023
+ min-height: 2.8rem;
2024
+ padding: 0.7rem 0.85rem;
2025
+ align-items: center;
2026
+ border: var(--border-heavy);
2027
+ color: var(--ink);
2028
+ background: var(--paper-bright);
2029
+ font-family: var(--mono);
2030
+ font-size: 0.66rem;
2031
+ font-weight: 900;
2032
+ letter-spacing: 0.04em;
2033
+ text-decoration: none;
2034
+ text-transform: uppercase;
2035
+ }
2036
+
2037
+ .link-row a:hover {
2038
+ color: var(--paper-bright);
2039
+ background: var(--ink);
2040
+ }
2041
+
2042
+ @media (max-width: 980px) {
2043
+ .demo-shell {
2044
+ grid-template-columns: 1fr;
2045
+ }
2046
+
2047
+ .demo-case-note {
2048
+ min-height: 22rem;
2049
+ border-top: var(--border-heavy);
2050
+ border-left: 0;
2051
+ }
2052
+
2053
+ .record-grid {
2054
+ grid-template-columns: 1fr;
2055
+ }
2056
+
2057
+ .record-grid > div + div {
2058
+ border-top: var(--border-heavy);
2059
+ border-left: 0;
2060
+ }
2061
+ }
2062
+
2063
+ @media (max-width: 720px) {
2064
+ .topbar {
2065
+ min-height: 3.8rem;
2066
+ }
2067
+
2068
+ .topbar .wordmark {
2069
+ min-width: 0;
2070
+ padding-inline: 0.8rem;
2071
+ }
2072
+
2073
+ .topbar .wordmark > span:last-child {
2074
+ display: none;
2075
+ }
2076
+
2077
+ .topbar nav {
2078
+ max-width: calc(100% - 4rem);
2079
+ }
2080
+
2081
+ .topbar nav a {
2082
+ min-height: 3.7rem;
2083
+ padding-inline: 0.8rem;
2084
+ }
2085
+
2086
+ .status-strip,
2087
+ .table-heading {
2088
+ align-items: flex-start;
2089
+ flex-direction: column;
2090
+ }
2091
+
2092
+ .status-strip > div {
2093
+ width: 100%;
2094
+ justify-content: space-between;
2095
+ }
2096
+
2097
+ .table-heading > p:last-child {
2098
+ text-align: left;
2099
+ }
2100
+
2101
+ .demo-case-note dl {
2102
+ grid-template-columns: 1fr;
2103
+ }
2104
+ }
2105
+
2106
+ @media print {
2107
+ .topbar {
2108
+ display: none !important;
2109
+ }
2110
+ }
2111
+
2112
+ /* Final semantic-hook corrections. */
2113
+
2114
+ .hero-copy {
2115
+ justify-content: flex-start;
2116
  }
2117
 
2118
+ .hero-copy > .eyebrow {
2119
+ margin: 0 0 var(--space-4);
2120
+ font-size: 0.68rem;
2121
+ line-height: 1.2;
2122
  }
2123
 
2124
+ .hero-aside .audit-stamp {
2125
+ border-color: var(--orange);
2126
+ color: var(--orange);
 
 
2127
  }
2128
 
2129
+ .signal-matched {
2130
+ color: var(--success);
2131
+ background: #d8e8df;
 
 
 
2132
  }
2133
 
2134
+ .signal-timing,
2135
+ .signal-duplicate {
2136
+ color: var(--orange-deep);
2137
+ background: #ffd9c7;
2138
  }