# NOTES — SPUN Medika

Clone target: `https://spun.global/id`
Mode: **content overhaul (内容爆改)** — SPUN's information architecture, section rhythm and visual
grammar retained; the domain replaced with outbound medical tourism price estimation.
Built 2026-07-30. Source of visual truth: `RECON/original-recon-summary.md`. Product spec: `plan.md`.

---

## 1. Complexity and mode

**Complexity: L2.** Next.js + Tailwind marketing/transactional front end. Recon found **no** WebGL,
no Canvas, no GSAP, no Lenis, no scroll-snap — native scroll only. There is no reverse-engineering
problem here; the whole difficulty is in the domain model, not the rendering.

**Why content overhaul rather than faithful clone.** The skill's default for "clone this site" is
faithful reproduction. That default is overridden here by the user's explicit request in the same
message: research medical tourism price estimation and build an estimator that works from a medical
resume or diagnosis. A faithful visa-platform clone would not answer the request. So SPUN supplies
the visual language and the IA; the product is different by instruction, and `design-dna.json`
records the identity that carries over.

**Structural mapping that makes the borrow legitimate** (full table in `plan.md` §1): search a
corridor → priced options → upload documents → AI-verified outcome is the same shape as search a
condition → priced procedures → upload resume medis → itemised estimate. SPUN's paid "Approval
Insight" pre-check is a direct analogue of the resume-medis estimator.

## 2. What was built

| File | Role | Priority |
|---|---|---|
| `index.html` | Launcher / screen map + key decisions + doc index | P1 |
| `beranda.html` | Home — recon's 13-section order, medical content | P0 |
| `rincian-estimasi.html` | **The itemised estimate.** Live ledger + levers | P0 |
| `estimasi-resume-medis.html` | Upload → reading → extraction review (human-gated) | P0 |
| `bandingkan-rumah-sakit.html` | 5 hospitals, comparing *inclusions* not just totals | P1 |
| `prosedur-detail.html` | Published anchor → in-package vs out-of-package → questions to ask | P1 |
| `assets/tokens.css` | Design tokens, bound to measured values | — |
| `assets/ui.css` | Shared components | — |
| `assets/data.js` | Seed data + provenance-graded price model | — |
| `assets/estimator.js` | Deterministic price engine + shared chrome | — |

`dasbor-kasus.html` (case tracking) from `plan.md` §4 was **not** built — see §8.

## 3. Tech stack

Plain HTML + CSS + vanilla ES5-compatible JS. No framework, no build step, no dependencies. This
matches the recon (the original ships a compiled Next.js bundle; reproducing the framework would add
nothing to a design prototype). Self-hosted fonts, local images, relative paths throughout — opens
correctly from the filesystem and inside the Open Design preview pane.

Run it: any static server from the project root, e.g. `python3 -m http.server 8791`, then
`http://127.0.0.1:8791/index.html`.

## 4. Fidelity scoring

Scored against `references/assessment.md` dimensions. Because this is a content overhaul, "visual
fidelity" means *fidelity of the design system*, not pixel identity — the content is deliberately
different, so a pixel diff against the original is not a meaningful measure and was not run.

| Dimension | Score | Evidence |
|---|---|---|
| Design-system fidelity | 5/5 | All 12 colour literals, the type family, the 8-step type scale and the radius ladder are copied verbatim from computed styles. Zero invented values. Verified by grep, §6. |
| Structural fidelity | 5/5 | All 13 home sections reproduced in the recon's documented order, including the chip scrollers, filter row, rose promo band, tabbed how-it-works and warm-cream footer. |
| Interaction fidelity | 4/5 | Chip scrollers, filter cycling, tabs, sticky header all present. Not reproduced: the original's search dropdown internals and card hover transform — `interaction-probe.mjs` was never run, so those remain `GUESS` in `design-dna.json` and were deliberately not invented. |
| Responsive | 5/5 | 390 / 768 / 1440 all verified zero horizontal overflow and zero clipped elements in a real browser (§7). The ledger re-flows to stacked rows rather than scrolling sideways. |
| Content replacement | 5/5 | No SPUN copy, testimonials, reviewer names, ratings, logo or product screenshots reused. All product UI mocks are our own markup. |
| Product depth | 4/5 | Price engine is real and reconciles; every lever recomputes live. Loses a point for the two unbuilt P2 screens. |
| Domain rigour | 4/5 | Every money value traces to a published figure or a stated derivation. Loses a point because two destination multipliers rest on qualitative statements only — flagged in-product as "dasar lemah". |

## 5. The price model

Full domain reasoning is in `plan.md` §3. Engine: `assets/estimator.js`, data: `assets/data.js`.

**Four line-item groups** — A core medical · B workup & stay · C post-discharge · D travel.

**Provenance grades on every row.** `Harga acuan` (published price guide) · `Estimasi` (derived,
basis stated) · `Belum diketahui` (no defensible figure — carries no money and is excluded from
every total, listed separately). The confidence chip is the weakest link, never optimistic.

**Anchor-based rather than invented splits.** Where the research gives a single published figure
(cataract RM 8,400; TKR RM 33,400 at 4.1 days; angiogram RM 11,700), that figure is presented as
*one* row — a package — and the value we add is showing what sits *outside* it. Fabricating a
plausible surgeon/anaesthetist/OT breakdown under a published total would have been exactly the
kind of invention the skill's first rule forbids.

**Stent count drives the PCI range rather than adding to it**, because the source states the
RM 25,000–50,000 spread *is* stent-count variance, not price uncertainty.

**Reconciliation is machine-verified** (§7): row = qty × unit × multiplier, group = Σ rows,
medical = A+B+C, total = medical + travel.

**Deliberate conservatism, surfaced not hidden.** Choosing a room class *below* the package-included
class produces no credit, because published package prices are average total bills and hospitals
rarely refund downgrades. Rather than silently flooring at zero, the ledger prints a note saying so
and telling the user to ask about a discount.

**The travel cross-check.** Group D is compared against the sourced "30–50% on top of procedure
cost" reference. For Jakarta→Penang it lands around 15%, and the UI says that is *expected* — the
30–50% figure comes from long-haul Western medical tourism, and Penang is a 1.5-hour flight. The
check reports a divergence honestly instead of either hiding it or padding the itemisation to hit
the benchmark.

## 6. Assets and colour fidelity — the skill's three hard gates

1. **Fonts — PASS.** Instrument Sans real `woff2` faces downloaded from Google Fonts (SIL OFL) to
   `assets/fonts/`, with `assets/fonts/fonts.css` rewritten to local paths. Variable axis 400–700
   covers every weight in the recon scale. No system-font substitute anywhere; verified in-browser
   that `getComputedStyle(body).fontFamily` resolves to `"Instrument Sans"` on all six pages.
   `asset-harvest.mjs` was not used because the family is a public OFL font available directly —
   no hotlink-protected CDN to work around.
2. **Images — PASS, with a caveat.** Real photographs, downloaded locally, referenced by relative
   path, never hotlinked. **They are not the original site's images**, which would be inappropriate
   to lift for a different product; they are freely-licensed photographs of the actual destinations
   this product covers. Attribution in §9. Image *generation* was attempted first per the charter
   (`od media generate`) and failed — no OpenAI credential and no Codex login in this run — so the
   documented fallback (web search → local copy) was used.
3. **Colours — PASS.** All 12 literals in `assets/tokens.css` are the recon's area-weighted computed
   values, copied digit for digit. Nothing eyeballed. Semantic additions (`--ok/--warn/--risk`) are
   scoped to confidence chips and open-item status only, always with icon + text label, never as a
   large fill, and never used for triage or acuity.
4. **Scroll feel — PASS.** Recon found no smooth-scroll library, so none was added. Native scroll,
   `position: sticky` header, horizontally scrolling chip rows. No `scrollIntoView` anywhere.

## 7. Browser verification — actually run, not assumed

Local server on `127.0.0.1:8791`, real Chromium via Playwright.

- **Console: clean.** Zero JS errors on all six pages. The only console entry across the whole run
  was a `favicon.ico` 404, which is a missing-file artefact of the dev server, not a code fault.
- **Arithmetic: 11 assertions pass.** Row arithmetic, group sums, medical subtotal, header total,
  open items carrying no money, every rendered row having a provenance badge, all 8 procedures
  computing without throwing, and each lever measurably moving the total (suite vs ward, LOS 4→10,
  1→3 stents).
  - One assertion I wrote initially failed and **the test was wrong, not the code**: I asserted the
    FX field scales the whole medical subtotal. It does not scale the discharge-medication row,
    because that row's basis is a USD figure, so a MYR→IDR change should not move it. Correct
    behaviour; assertion corrected.
- **Layout: zero defects at 390 / 768 / 1440.** No horizontal page overflow, no clipped elements, no
  cell overlapping its neighbour. Two real defects were found *by* this pass and fixed: the ledger's
  item column collapsed to one word per line (fixed with `table-layout: fixed` + explicit
  `<colgroup>` widths), and the header's right-hand cluster overflowed 390px by 17px (fixed by
  dropping the currency pill and login button below 520px).
- **Not verifiable here, stated honestly:** file-input selection and real PDF parsing are not
  exercised — the upload flow runs on the synthetic sample document. Print-to-PDF is `window.print()`
  against a screen stylesheet; no dedicated print sheet was authored.

## 8. Known gaps

- **`dasbor-kasus.html` not built.** P2 in `plan.md` §4; the launcher does not link a stub for it.
- **Gastroenterology and endocrinology have no priced procedures.** Both are top specialities for
  Indonesian patients, but the research contains no tariff for either. They appear in the taxonomy
  with a "belum ada tarif" marker and the grid prints an explicit gap notice rather than an invented
  estimate.
- **Health-screening packages are only partly priced.** Only the consultation component has a
  published figure; the lab/imaging panel is an open item.
- **Singapore ×2.40 and Bangkok ×1.05 multipliers are directional only.** The sources say Malaysia
  is "substantially cheaper" than Singapore without numbers, and contain nothing on Thailand. Both
  are marked `Dasar lemah` in the UI and the comparison screen carries a standing warning.
- **FX rate RM 1 = IDR 3,900 is an assumption**, editable in the UI, not a live rate.
- **SST 6% is a placeholder rate** on a genuinely moving policy target; flagged as such in the row.
- **Partner hospital names are placeholders.** Attaching derived prices to real institutions would
  be fabrication.
- **Recon steps never run:** `asset-harvest.mjs`, `route-crawl.mjs`, `interaction-probe.mjs`,
  `network-capture.mjs`, `sourcemap-hunt.mjs`. Consequences: the `/id/visa/[id]` detail template was
  inferred from the full-page capture rather than crawled, and card-hover/search-dropdown behaviour
  stays `GUESS` in `design-dna.json` and was not invented.
- **No pixel diff against the original**, deliberately — see §4.

## 9. Image attribution

All photographs from Wikimedia Commons, downloaded to `assets/images/`, used under their stated
licences. Attribution is also surfaced in the site footer.

| File | Source work | Author | Licence |
|---|---|---|---|
| `dest-penang.jpg` | Skyline of George Town, Penang at dusk, March 2025 | HundenvonPenang | CC BY-SA 4.0 |
| `dest-kualalumpur.jpg` | KL skyline from Bandar Sunway | Azreey | CC BY-SA 4.0 |
| `dest-singapore.jpg` | Marina Bay Sands and the CBD skyline, Singapore | Basile Morin | CC BY-SA 4.0 |
| `dest-bangkok.jpg` | Bangkok — city skyline at mid day | Azreey | CC BY-SA 3.0 |

CC BY-SA is share-alike: if these images are redistributed as part of a published site, the
attribution must travel with them and the licence terms apply to the images.

Font: Instrument Sans, SIL Open Font License 1.1, via Google Fonts.

## 10. Deliberate deviations from the recon

Recorded because the recon is the source of visual truth and these differ from it.

1. **Procedure cards carry no thumbnail.** The recon's visa card has a photo/flag on the right. Our
   cards are filtered to one destination at a time, so the slot rendered as eight identical dark
   city thumbnails — repetition with no information the price line ("Perkiraan total di Penang 🇲🇾")
   doesn't already carry. Replaced with a speciality eyebrow in the accent colour. Real photography
   is kept where it is informative: the 4-up coverage grid and the procedure-detail hero.
2. **No strikethrough comparison price.** The recon card shows `Dari IDR X` against a struck-through
   original. We have no sourced Indonesian private-hospital comparison, so filling that slot would
   have required inventing a number. The two-number rhythm is preserved honestly as
   `Dari … / sampai …`. The one comparative claim the research does support (50–80% saving vs
   Western countries) appears once, in the hero, attributed.
3. **A semantic colour layer was added.** SPUN has none. A medical estimator needs to distinguish
   confidence levels; scoped tightly, per §6.
4. **Six routes instead of the original's many.** Scope decision from `plan.md` §10 Q6 — four
   screens done properly over eight thin ones.

## 11. Legal position

`spun.global` is a live commercial service operated by PT Solutopia Untuk Nusantara. This project is
a **visual-language study and design prototype**, not a redeployment and not a competing service.
No SPUN trademark, logo, copy, testimonial, rating or product screenshot is reproduced. Pre-release
replacement obligations are tracked in `CLONE_AUDIT.md`.

Nothing here is a medical device, clinical decision support, or a source of medical advice, and the
prototype states this on every screen that renders a number.
