TRT Bangkok — The Men's Energy Clinic
TRT Bangkok consultation room — doctor-led GLP-1 weight-loss program
Medical Weight Loss · Thailand

Preserve Muscle on GLP-1

GLP-1 medications produce dramatic weight loss — but 25 to 40 percent of that loss can come from lean muscle tissue if no specific protocol is followed. The doctor-led muscle-preservation protocol — adequate protein (1.2 to 1.6 grams per kilogram body weight), structured resistance training (2 to 3 sessions per week), body-composition tracking — protects metabolism, function, and long-term weight maintenance.

5.0 Google Reviews
Authentic Mounjaro, Wegovy, Ozempic, Saxenda 1,000+ GLP-1 patients · 5.0 Google · Licensed Thai clinic Pattaya in-clinic · Bangkok concierge · Phuket remote
Dr. Kenika Norrachetdecha, MD — Medical Director at TRT Bangkok

Treatments supervised by Dr. Kenika Norrachetdecha

Medical Director · Thai License #72509

● Mon–Sat 8 AM–6 PM · Online consults daily · Reply in 2 Min

Personal consultation included with every program

Body-weight reduction · SURMOUNT-1 trial
20.9%
Mean body-weight reduction in the SURMOUNT-1 trial at 72 weeks on Mounjaro 15 mg.
Jastreboff et al., NEJM 2022 · n=2,539 non-diabetic adults
What that means for you

That's 17.8 kg — you'd weigh 67.2 kg.

Based on the 20.9% trial-mean. Individual outcomes vary.
The problem worth solving

Up to 30% of GLP-1 weight loss can be lean mass

Body-composition substudies of phase-3 GLP-1 trials show that without a protein + resistance-training protocol, roughly a quarter to a third of total weight lost is lean tissue — not fat.

25–30%

of weight lost on GLP-1s — without a structured intervention — can be lean mass (STEP-1 body-composition substudy, Heymsfield 2024).

3

downstream consequences of lean-mass loss: lower resting metabolic rate, reduced mobility, and worse weight-regain trajectory post-therapy.

The good news: a deliberate protein, resistance-training and creatine protocol — the four pillars below — shifts the fat-to-lean ratio dramatically and preserves the metabolic engine you'll need to keep weight off after the program ends.

Pillar 1 · Protein

1.6–2.0 g of protein per kg of goal body weight

Protein target is based on goal body weight, not current weight — this keeps the absolute gram total realistic and preserves muscle through caloric deficit.

Goal weight
Lower (1.6 g/kg)
Upper (2.0 g/kg)
70 kg
112 g/day
140 g/day
80 kg
128 g/day
160 g/day
90 kg
144 g/day
180 g/day
Distribution matters. Split protein across 3–4 meals at 30–40 g each. Even distribution maximises muscle-protein-synthesis stimulus across the day. Add a protein shake mid-day if appetite suppression makes a full meal difficult.
Pillar 2 · Training

2–3 full-body resistance sessions per week

Resistance training is the single strongest lever for preserving muscle in a caloric deficit. Volume and intensity matter more than session count.

Prescription

  • 2–3 sessions/week, full body each session
  • 3–5 sets per major muscle group
  • 6–12 reps per set, last 2 reps challenging
  • Progressive overload — add weight or reps weekly
  • 48–72 h recovery between sessions

Six compound movements

  • 1.Squat — goblet, back, or split-squat
  • 2.Hinge — Romanian deadlift, hip thrust
  • 3.Push — bench press, dumbbell press, push-up
  • 4.Pull — row, lat pulldown, chin-up
  • 5.Carry — farmer's walk, suitcase carry
  • 6.Lunge — reverse, walking, or step-up
Pillar 3 · Supplement

Creatine monohydrate — 3–5 g daily

Creatine is the most-studied performance supplement in existence. In a caloric deficit it helps maintain strength output, training quality, and (indirectly) muscle mass.

  • Dose: 3–5 g per day, any time of day
  • Loading phase: not necessary — saturation occurs in 3–4 weeks at the maintenance dose
  • Form: creatine monohydrate, micronised if preferred — other forms offer no proven advantage
  • With/without food: either is fine; carbohydrate co-ingestion is not required
  • Evidence: Antonio et al. 2021 ISSN position stand confirms safety and efficacy across >500 studies
Pillar 4 · Monitoring

Track body composition, not just scale weight

A DEXA scan or quality bioimpedance reading every 12 weeks tells you whether weight loss is coming from fat or muscle. Scale weight alone hides the answer.

Targets per 12-week review

  • Fat-mass share of weight loss
    % of total kg lost that came from fat tissue
    ≥70%
  • Lean-mass change vs baseline
    Acceptable lean loss for adherent patients
    ≤−10%
  • Strength change (1RM compound lifts)
    Maintenance or improvement vs baseline
    ≥0%
  • Scan cadence
    DEXA at start, week 12, week 24, week 52
    4 scans

DEXA is the gold standard; quality bioimpedance (InBody 770, Tanita MC-780) is acceptable for trend-tracking between scans.

Visiting Pattaya? Walk into our Pattaya clinic →
Authentic
Eli Lilly · Novo Nordisk
Doctor-Led
Dr. Kenika · MD
Trusted
Verified 5.0
Access
Pattaya · BKK · Phuket
Your Personalized Trajectory

See your expected weight-loss trajectory.

Pick your treatment, enter your weights, see your trajectory. All data from peer-reviewed clinical trials. Individual outcomes vary — final program plan determined in private consultation.

kg

Your trajectory · based on clinical-trial mean

Weeks to goal
Projected loss
Investment
from 2,190 ฿/shot

Body-composition data from STEP-1 secondary endpoints and meta-analyses of GLP-1 lean-mass loss. Protein target (1.2-1.6 g/kg) is from the ESPEN guidelines for weight-reducing diets; standard population recommendation is 0.8 g/kg. Resistance-training protocol references the position stand of the American College of Sports Medicine on weight loss and physical activity (2009, reaffirmed 2022).

Personalized Recommendation

Find Your Treatment in 2 Minutes

Each program is personalized based on your profile, medical history, and goals.

Step 1 of 5

Tell us about you

Step 2 of 5

Do you have any of these conditions?

Select all that apply, or "None of these"

Step 3 of 5

Important medical history

Confidential — only your doctor sees this

Step 4 of 5

Your target

Step 5 of 5

Where would you like to start?

Dr. Kenika's recommendation for you

Based on your profile

Recommended Treatment

Your access

Chat with Dr. Kenika about your treatment
Dr. Kenika explaining personalized GLP-1 weight-loss treatment plan on tablet during consultation at TRT BangkokDoctor-led personalized weight-loss strategy at TRT BangkokTRT Bangkok consultation room — doctor-led GLP-1 weight-loss programComprehensive weight-loss consultation with Dr. Kenika at TRT Bangkok

Our actual clinic · Real photos

The Standard of Care

Why Patients Choose TRT Bangkok

Authentic medications. Direct access to Dr. Kenika. Comprehensive metabolic care beyond GLP-1 alone.

Authentic Medications

Mounjaro, Zepbound (Eli Lilly), Wegovy, Ozempic, Saxenda (Novo Nordisk) — all sourced through the licensed Thai pharmaceutical supply chain.

Direct Doctor Access

WhatsApp Dr. Kenika directly. Every GLP-1 prescription personally supervised by the Medical Director.

Beyond GLP-1

Multi-modal metabolic care: GLP-1 plus hormone optimization, IV recovery, and advanced peptide protocols.

Your Doctor

Meet Your Medical Director

Dr. Kenika Norrachetdecha, MD — Medical Director at TRT Bangkok

Dr. Kenika Norrachetdecha, MD

Medical Director · TRT Bangkok

Hormone Medicine Brain Health Metabolic Optimisation Weight Loss

Dr. Kenika Norrachetdecha, MD, leads TRT Bangkok's clinical practice. She specialises in hormone optimisation, regenerative medicine, and metabolic health, with advanced training under Dr. Mark Gordon (USA) in neuroregenerative protocols. She personally oversees treatment standards across all access points.

0+

Patients Treated

0+

IV Treatments

0+

TRT Treatments

0+

GLP-1 Treatments

Dr. Kenika with Dr. Mark Gordon

International Training

Advanced neuroregenerative medicine training under Dr. Mark Gordon (USA) — featured on The Joe Rogan Experience (4 appearances) for his work in hormones & brain health.

Dr. Kenika Norrachetdecha with Dr. Mark Gordon at HEAT Conference

With Dr. Mark Gordon (USA)

HEAT Conference — Neuroregenerative Medicine Training

Thai Medical License #72509 · Council Member #71253 — Verify ↗

In Thailand for treatment? For DEXA-scan baseline + ongoing body-composition tracking, visit our Pattaya walk-in clinic — local partner imaging center, same-day results.

Common Questions

Frequently Asked Questions

How much muscle do I lose on GLP-1?

Trials report 25–40% of total weight loss comes from lean tissue (including muscle) when no specific protocol is followed. With adequate protein intake and resistance training, lean-mass loss can be reduced to 10–20% — preserving function and metabolism.

How much protein should I eat?

1.2–1.6 g of protein per kg of body weight daily — significantly above the standard 0.8 g/kg recommendation. For a 70 kg adult: 84–112 g protein/day, ideally split across 3–4 meals to maximize muscle protein synthesis.

Do I need to lift weights?

Yes — resistance training is the most effective protector of lean mass during weight loss. Aim for 2–3 sessions per week targeting all major muscle groups: legs, back, chest, shoulders, arms. Start with bodyweight or light weights and progress over time.

What if I don't have time to train?

Even 2 short sessions (30 min each) per week provide most of the lean-mass protection benefit. Bodyweight exercises (squats, push-ups, rows with bands) work at home. The goal is consistent resistance stimulus, not training volume.

Should I track body composition?

Yes. Weight alone doesn't distinguish fat loss from muscle loss. DEXA scan, bioimpedance (BIA), or skinfold measurements every 8–12 weeks tell you what you're losing. Our program includes body-composition tracking.

What supplements help?

Whey protein (or vegan equivalent) to hit daily protein targets. Creatine monohydrate (3–5 g/day) supports muscle retention. Vitamin D and omega-3 indirectly support recovery. Multivitamin if calorie intake drops below 1,500/day.

Will I look "skinny-fat" after weight loss?

This is the risk if you lose weight without lean-mass protection. Avoid by: (1) high protein, (2) resistance training, (3) avoiding crash dieting, (4) gradual weight loss (0.5–1 kg/week). Our program is built around this protocol.

Does muscle preservation affect long-term weight maintenance?

Yes — significantly. Higher lean mass means higher resting metabolism, easier weight maintenance after stopping GLP-1, and reduced risk of weight regain. Muscle protection during weight loss is one of the highest-leverage things you can do.

Licensed
Thai Pharmacy

Pharmaceutical
Grade

Doctor
Supervised

Same-Day
Care

Patient Reviews

What patients say

5.0 / 5
15 verified Google Reviews

Real reviews from real patients on Google Business Profile. Currently 5.0 ★ from 15 verified reviews — and growing. Reviews are updated regularly.

[Robert: paste actual Google Review quote — filtered to mention this page's topic]

[Robert: First name + initial]
[Robert: month year of review]

[Robert: paste actual Google Review quote — filtered to mention this page's topic]

[Robert: First name + initial]
[Robert: month year of review]

[Robert: paste actual Google Review quote — filtered to mention this page's topic]

[Robert: First name + initial]
[Robert: month year of review]

Read all reviews on Google Business Profile →

Dr. Kenika, Medical Director at TRT Bangkok weight-loss program
Medically reviewed by Dr. Kenika, Medical Director
Member, Medical Council of Thailand · Endocrinology & Metabolic Medicine
This page is reviewed for medical accuracy. Content is informational and does not substitute for individualized medical advice. Treatment decisions are made during private consultation.

Sources

Peer-reviewed primary sources, FDA prescribing information, and manufacturer documentation.

View all 6 sources
  1. Jastreboff AM, Aronne LJ, Ahmad NN, et al. Tirzepatide Once Weekly for the Treatment of Obesity. N Engl J Med. 2022;387(3):205-216. doi:10.1056/NEJMoa2206038. View on NEJM ↑
  2. Wilding JPH, Batterham RL, Calanna S, et al. Once-Weekly Semaglutide in Adults with Overweight or Obesity (STEP-1). N Engl J Med. 2021;384(11):989-1002. doi:10.1056/NEJMoa2032183. View on NEJM ↑
  3. U.S. Food and Drug Administration. Wegovy (semaglutide) injection prescribing information. Initial U.S. Approval: 2021. FDA label (PDF) ↑
  4. U.S. Food and Drug Administration. Zepbound (tirzepatide) injection prescribing information. Initial U.S. Approval: 2023. FDA label (PDF) ↑
  5. American Diabetes Association. Pharmacologic Approaches to Glycemic Treatment: Standards of Care in Diabetes—2024. Diabetes Care. 2024;47(Suppl 1):S158-S178. doi:10.2337/dc24-S009. View on Diabetes Care ↑
  6. Frías JP, Davies MJ, Rosenstock J, et al. Tirzepatide versus Semaglutide Once Weekly in Patients with Type 2 Diabetes (SURPASS-2). N Engl J Med. 2021;385(6):503-515. doi:10.1056/NEJMoa2107519. View on NEJM ↑

Additional clinical questions are discussed during your private consultation with Dr. Kenika.

TRT Bangkok consultation room — doctor-led GLP-1 weight-loss program
5.0 Google Reviews

Begin Your Weight-Loss Program

Direct access to Dr. Kenika. Authentic medications. Three access points across Thailand.

Personal medical supervision · Cancel anytime · Authentic medications from Eli Lilly and Novo Nordisk

Book via WhatsApp · Free eligibility check

OTHER PROGRAMS

Explore TRT Bangkok's full range

Insights Library

Further reading

FOUNDATION · CLASS EXPLAINED
GLP-1 Medications Explained — Single, Dual, Triple Agonists
COMPARISON · DOCTOR-LED
Mounjaro vs Wegovy — Side-by-Side Comparison
TRIAL DEEP-DIVE
SURMOUNT-1 Explained — Inside Mounjaro's 20.9%
TRIAL DEEP-DIVE
STEP-1 Trial Breakdown — Wegovy 14.9%
BODY COMPOSITION
How to Preserve Muscle on GLP-1
GLP-1 Programs
Locations
Resources
Other Services

Clinical Evidence Summary

Body composition data from STEP-1 trial subgroup analyses (Wilding et al., 2022) indicated that approximately 40 percent of total weight loss with semaglutide consisted of lean body mass without specific resistance training intervention. Clinical guidance recommends maintaining 1.2-1.6 g/kg of body weight in daily protein intake combined with resistance training three times weekly during GLP-1 therapy to minimize lean tissue loss. DEXA-based body composition monitoring at baseline and 12-week intervals supports objective tracking.

Last reviewed by Dr. Kenika Tonkam, Medical Director, TRT Bangkok · June 3, 2026

Request consultation
via PHP plugin surgery. * Idempotent: checks for marker; safe to re-run. */ (function() { 'use strict'; if (window.__TRT_WL_LEAD_V2__) return; window.__TRT_WL_LEAD_V2__ = true; var WA_NUMBER = '66842249559'; var ENDPOINT = (document.querySelector('meta[name="lead-form-endpoint"]') || {}).content || ''; /* ============================================================ * 1) HIDE the 4 standalone email-only forms + their wrappers * ============================================================ */ function injectHideCSS() { if (document.getElementById('trt-wl-lead-v2-hide')) return; var s = document.createElement('style'); s.id = 'trt-wl-lead-v2-hide'; s.textContent = [ /* hide form itself */ 'form.trt-lead-form{display:none!important;}', /* hide its wrapping div (body > div containing the form) */ 'body > div:has(> form.trt-lead-form){display:none!important;}', /* fallback: any data-lead-form placeholder div */ 'div[data-lead-form]{display:none!important;}', /* v24: hide duplicate baby-blue CTA inside trajectory tool — v2 module replaces it */ '#hub-est-cta{display:none!important;}', '#hub-est-cta + p, a[id^="est-cta-"]{display:none!important;}', /* v37: hide estimator disclaimer text below chart (v2-module shows trust signals instead) */ '#estimator p.font-body[class*="6B7280"]{display:none!important;}', '#estimator > div.max-w-\[960px\] > p:last-child{display:none!important;}', /* v49: BG EINHEITLICH baby-blue (matched body) + wow-stat-Inner als white card mit rounded-top + v2 white card mit rounded-bottom = EINE durchgehende white-card. CRITICAL FIX: Mobile width-mismatch (v48) zwischen Inner-Card und v2-Modul behoben via runtime width-sync (siehe syncCardWidths() in JS) — kein CSS-calc-Glücksspiel mehr. CSS sets nur padding/border/radius/bg/shadow; width+x werden in JS dynamisch synchronisiert. */ '#estimator, #wow-stat{padding-bottom:0!important;margin-bottom:0!important;background:rgb(240,245,250)!important;}', 'section#estimator + .trt-wl-v2, section#wow-stat + .trt-wl-v2{margin-top:0!important;}', /* === ESTIMATOR (hat inner div.bg-white card) === */ '#estimator{padding-top:48px!important;}', '#estimator > div > div.bg-white{border-bottom:0!important;border-bottom-left-radius:0!important;border-bottom-right-radius:0!important;margin-bottom:0!important;box-shadow:none!important;}', /* v2-Modul: width+marginLeft werden in JS gesetzt (syncCardWidths). CSS nur für visuelle Eigenschaften. */ '.trt-wl-v2[data-tool="estimator"]{margin:0!important;border:1px solid rgba(29,51,91,0.10)!important;border-top:0!important;border-radius:0 0 16px 16px!important;box-shadow:0 6px 24px rgba(29,51,91,0.06)!important;background:#FFFFFF!important;padding:28px 32px 28px!important;position:relative;box-sizing:border-box!important;}', /* === WOW-STAT === */ '#wow-stat{padding:48px 20px 0!important;}', '#wow-stat > div{display:block!important;max-width:1100px!important;margin:0 auto!important;padding:40px 32px 36px!important;border:1px solid rgba(29,51,91,0.08)!important;border-bottom:0!important;border-radius:18px 18px 0 0!important;background:#FFFFFF!important;box-sizing:border-box!important;box-shadow:0 4px 24px rgba(29,51,91,0.06)!important;}', /* v2-Modul: width+marginLeft werden in JS gesetzt (syncCardWidths). CSS nur für visuelle Eigenschaften. v50: bottom-radius RAUS — page-trust-bar schliesst die Karte unten. */ 'section#wow-stat + .trt-wl-v2[data-tool="wow-stat"]{margin:0!important;border:1px solid rgba(29,51,91,0.08)!important;border-top:0!important;border-bottom:0!important;border-radius:0!important;background:#FFFFFF!important;padding:0 32px 28px!important;box-shadow:none!important;position:relative;box-sizing:border-box!important;}', /* v50: TRUST-BAR styled als 3. Schale der ONE-CARD (oben wow-stat-inner, mitte v2-Modul, unten trust-bar mit rounded-bottom) */ /* Wrap-Section: matched baby-blue bg, padding raus */ 'section.page-trust-bar-wrap{background:rgb(240,245,250)!important;padding:0!important;border-top:0!important;border-bottom:0!important;margin-top:0!important;}', /* Inner trust-bar: white card, schliesst Frame unten — width+marginLeft via syncCardWidths */ '.page-trust-bar{background:#FFFFFF!important;border:1px solid rgba(29,51,91,0.08)!important;border-top:0!important;border-radius:0 0 18px 18px!important;box-shadow:0 8px 32px rgba(29,51,91,0.08)!important;padding:20px 32px 22px!important;box-sizing:border-box!important;}', /* v50: HIDE redundant v2-trustbar (page-trust-bar darunter macht dasselbe + mehr) */ '.trt-wl-v2-trustbar{display:none!important;}', /* v50: HIDE hub-chapter-nav auf WL-Seiten (low CRO-value, doppelt mit Header-Nav, am Bottom = falsche Position) */ '.hub-chapter-nav{display:none!important;}', /* v52: HERO CTA HIERARCHY — make CHAT ON WHATSAPP visually dominant (Hims primary-tier), GET STARTED stays secondary */ 'a.wa-cta{box-shadow:0 10px 28px rgba(141,191,226,0.40)!important;font-weight:800!important;letter-spacing:0.06em!important;transform:translateZ(0);transition:transform 0.2s, box-shadow 0.2s;}', 'a.wa-cta:hover{transform:translateY(-2px)!important;box-shadow:0 14px 32px rgba(141,191,226,0.50)!important;}', 'a.wa-cta:active{transform:translateY(0)!important;}', /* v62: STRONG PRESS EFFECT — überschreibt v51-css-v3 (gleiche Spezifität, lädt später) via html body … prefix (3 Tag-Selectors = ID-Boost). Mobile-Tap wird CLEAR visible. */ /* Tier-1 SOLID — scale(0.95) = 5% press down, dunkler bg, snappy 0.05s */ 'html body a.trt-quiz-teaser-cta, html body a.trt-hero-cta{transition:transform 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease!important;will-change:transform;transform-origin:center;}', 'html body a.trt-quiz-teaser-cta:hover, html body a.trt-hero-cta:hover{transform:translateY(-2px)!important;box-shadow:0 12px 28px rgba(29,51,91,0.28)!important;}', 'html body a.trt-quiz-teaser-cta:active, html body a.trt-hero-cta:active{transform:scale(0.95)!important;background-color:#0F1E3A!important;box-shadow:0 4px 12px rgba(29,51,91,0.45)!important;transition:transform 0.06s ease, background-color 0.06s ease, box-shadow 0.06s ease!important;}', /* Tier-2 OUTLINED hero "Get Started" */ 'html body a[class*="border-white"][class*="rounded-"]{transition:transform 0.18s ease, background-color 0.18s ease, box-shadow 0.18s ease!important;will-change:transform;transform-origin:center;}', 'html body a[class*="border-white"][class*="rounded-"]:hover{transform:translateY(-2px)!important;background-color:rgba(255,255,255,0.12)!important;box-shadow:0 8px 20px rgba(0,0,0,0.18)!important;}', 'html body a[class*="border-white"][class*="rounded-"]:active{transform:scale(0.95)!important;background-color:rgba(255,255,255,0.20)!important;transition:transform 0.06s ease, background-color 0.06s ease!important;}', /* Tier-2 BABY-BLUE PILL "↑ Get Started" */ 'html body a[class*="bg-\[\#8DBFE2\]"][class*="rounded-"]{transition:transform 0.18s ease, background-color 0.18s ease, box-shadow 0.18s ease!important;transform-origin:center;}', 'html body a[class*="bg-\[\#8DBFE2\]"][class*="rounded-"]:hover{transform:translateY(-2px)!important;background-color:#75ACD3!important;box-shadow:0 8px 18px rgba(141,191,226,0.4)!important;}', 'html body a[class*="bg-\[\#8DBFE2\]"][class*="rounded-"]:active{transform:scale(0.95)!important;background-color:#6BA0CC!important;transition:transform 0.06s ease, background-color 0.06s ease!important;}', /* Bonus: WhatsApp wa-cta active press (matches DNA) */ 'html body a.wa-cta:active{transform:scale(0.95)!important;background-color:#75ACD3!important;transition:transform 0.06s ease, background-color 0.06s ease!important;}', /* v63: JS-driven .trt-pressing class — bulletproof press feedback bypassing :active cascade-issues */ 'html body a.trt-pressing, html body button.trt-pressing{transform:scale(0.93)!important;transition:transform 0.08s ease!important;opacity:0.85!important;}', /* v55: MOBILE HERO TYPOGRAPHY SHRINK — user feedback "in der mobilen version ist die schrifft aber zu groß" */ /* v56: + Hero füllt vollen viewport (Apple/Hims pattern) → kein "abgeschnitten" Look mehr */ '@media (max-width:640px){' + 'section.relative.overflow-hidden{min-height:100vh!important;min-height:100svh!important;display:flex!important;flex-direction:column!important;justify-content:center!important;padding-top:32px!important;padding-bottom:56px!important;}' + 'section.relative.overflow-hidden h1{font-size:36px!important;line-height:1.05!important;letter-spacing:-0.01em!important;margin-top:4px!important;margin-bottom:14px!important;}' + 'section.relative.overflow-hidden p.font-body{font-size:14px!important;line-height:1.5!important;margin-bottom:18px!important;}' + 'section.relative.overflow-hidden p.text-white{font-size:13px!important;line-height:1.35!important;}' + 'section.relative.overflow-hidden p[class*="B8D9EE"]{font-size:11px!important;line-height:1.4!important;}' + 'section.relative.overflow-hidden a.wa-cta{font-size:13px!important;}' + '}', /* v55: kleine Tablets auch leicht reduzieren */ '@media (min-width:641px) and (max-width:900px){' + 'section.relative.overflow-hidden h1{font-size:54px!important;line-height:1.05!important;}' + '}', /* ============================================================ * v51 · APPLE / HIMS / HERS DESIGN SYSTEM * Goal: unify section widths, rhythm, cards, CTAs across the entire WL page. * Strategy: high-specificity CSS overrides + !important, scoped to known section IDs. * ============================================================ */ /* --- v51 · DESIGN TOKENS (used inline below as values) --- */ /* --ds-content-max: 1120px; --ds-gutter-d: 32px; --ds-gutter-m: 20px; --ds-section-py-d: 96px; --ds-section-py-m: 56px; --ds-card-radius-d: 18px; --ds-card-radius-m: 14px; --ds-card-shadow: 0 4px 24px rgba(29,51,91,0.06); --ds-card-border: 1px solid rgba(29,51,91,0.08); --ds-card-pad-d: 36px; --ds-card-pad-m: 24px; --ds-navy: #1D335B; --ds-brand: #185FA5; --ds-baby: #8DBFE2; --ds-slate: rgb(240,245,250); */ /* --- v51.1 · SECTION WIDTH UNIFICATION --- Force all top-level sections to a consistent content max-width of 1120px. Target direct child div which is the content container in React-rendered tailwind layouts. */ 'section#quiz > div, section#treatments > div, section#access > div, section#doctor > div, section#faq > div, section#reviews > div, section#sources > div, section#other-services > div, section#further-reading > div, section#related > div{max-width:1120px!important;margin-left:auto!important;margin-right:auto!important;padding-left:32px!important;padding-right:32px!important;box-sizing:border-box!important;width:100%!important;}', /* --- v51.2 · SECTION VERTICAL RHYTHM --- All top-level sections get consistent 96px top+bottom padding on desktop. */ 'section#quiz, section#treatments, section#access, section#doctor, section#faq, section#reviews, section#sources, section#other-services, section#further-reading, section#related{padding-top:96px!important;padding-bottom:96px!important;}', /* --- v51.3 · ASSESSMENT CTA PILL --- Make .trt-quiz-teaser-cta look like a proper hero-tier pill with elegant shadow + hover lift. */ '.trt-quiz-teaser-cta{display:inline-flex!important;align-items:center!important;justify-content:center!important;gap:10px!important;min-height:60px!important;padding:18px 44px!important;background:#1D335B!important;color:#FFFFFF!important;border:none!important;border-radius:999px!important;font-family:"DM Sans",sans-serif!important;font-size:14px!important;font-weight:700!important;text-transform:uppercase!important;letter-spacing:0.10em!important;text-decoration:none!important;cursor:pointer!important;box-shadow:0 10px 28px rgba(29,51,91,0.22)!important;transition:transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease!important;}', '.trt-quiz-teaser-cta:hover{background:#2A4A7F!important;transform:translateY(-2px)!important;box-shadow:0 14px 36px rgba(29,51,91,0.28)!important;}', '.trt-quiz-teaser-cta:active{transform:translateY(0)!important;box-shadow:0 6px 18px rgba(29,51,91,0.20)!important;}', /* Tighten the wrap around it so spacing is generous but not sloppy */ '.trt-quiz-teaser-wrap{margin:32px auto 0!important;padding:0 20px!important;text-align:center!important;}', /* --- v51.4 · UNIFIED CARD SYSTEM --- Apply canonical card chrome to common card containers inside the major sections. Tailwind cards typically use rounded-[Npx] + shadow utilities — override radius/shadow/border. */ 'section#treatments [class*="rounded-"], section#doctor [class*="rounded-"], section#reviews [class*="rounded-"], section#access [class*="rounded-"], section#other-services [class*="rounded-"]{border-radius:18px!important;}', /* Cards with white bg or shadow utilities get unified treatment */ 'section#treatments .bg-white, section#doctor .bg-white, section#reviews .bg-white, section#access .bg-white, section#other-services .bg-white{border:1px solid rgba(29,51,91,0.08)!important;box-shadow:0 4px 24px rgba(29,51,91,0.06)!important;border-radius:18px!important;}', /* --- v51.5 · INTERNAL CARD WHITESPACE --- Treatment cards (grid items) and similar — generous padding. */ 'section#treatments .bg-white, section#access .bg-white, section#other-services .bg-white{padding:32px 28px!important;}', 'section#doctor .bg-white{padding:48px!important;}', 'section#reviews .bg-white{padding:32px!important;}', /* --- v51.6 · CTA TIER SYSTEM --- Tier 1 (hero/primary pill): handled above (.trt-quiz-teaser-cta, .trt-hero-cta). Tier 2 (compact action — treatment card "Learn about X" baby-blue buttons): make 44px tall, radius 12px, generous padding. */ 'section#treatments a[class*="bg-[#8DBFE2]"], section#treatments a.bg-\[\#8DBFE2\], a.wa-cta{min-height:48px!important;border-radius:12px!important;padding:0 22px!important;font-size:13px!important;font-weight:700!important;letter-spacing:0.06em!important;transition:transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease!important;box-shadow:0 4px 14px rgba(29,51,91,0.10)!important;}', /* Tier 3 (outlined Request Consultation): white bg, baby-blue 2px border, navy text */ 'section#treatments a[class*="border-"][class*="8DBFE2"]{min-height:48px!important;border-radius:12px!important;padding:0 22px!important;border:2px solid #8DBFE2!important;background:#FFFFFF!important;color:#1D335B!important;font-size:13px!important;font-weight:700!important;letter-spacing:0.06em!important;transition:transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease!important;}', /* --- v51.7 · CARD HOVER MICRO-INTERACTIONS --- */ 'section#treatments .bg-white, section#access .bg-white, section#other-services .bg-white{transition:transform 0.25s ease, box-shadow 0.25s ease!important;}', 'section#treatments .bg-white:hover, section#access .bg-white:hover, section#other-services .bg-white:hover{transform:translateY(-3px)!important;box-shadow:0 10px 32px rgba(29,51,91,0.10)!important;}', /* --- v51.8 · CTA HOVER LIFT (Tier 2/3 buttons) --- */ 'section#treatments a:hover[class*="bg-[#8DBFE2]"], a.wa-cta:hover{transform:translateY(-1px)!important;box-shadow:0 8px 20px rgba(29,51,91,0.16)!important;}', 'section#treatments a:hover[class*="border-"][class*="8DBFE2"]{background:#F0F7FC!important;transform:translateY(-1px)!important;}', /* --- v51.9 · MOBILE OVERRIDES --- */ '@media (max-width:768px){' + 'section#quiz > div, section#treatments > div, section#access > div, section#doctor > div, section#faq > div, section#reviews > div, section#sources > div, section#other-services > div, section#further-reading > div, section#related > div{padding-left:20px!important;padding-right:20px!important;}' + 'section#quiz, section#treatments, section#access, section#doctor, section#faq, section#reviews, section#sources, section#other-services, section#further-reading, section#related{padding-top:56px!important;padding-bottom:56px!important;}' + 'section#treatments [class*="rounded-"], section#doctor [class*="rounded-"], section#reviews [class*="rounded-"], section#access [class*="rounded-"], section#other-services [class*="rounded-"]{border-radius:14px!important;}' + 'section#treatments .bg-white, section#access .bg-white, section#other-services .bg-white{padding:24px 20px!important;border-radius:14px!important;}' + 'section#doctor .bg-white{padding:28px 22px!important;border-radius:14px!important;}' + 'section#reviews .bg-white{padding:24px 20px!important;border-radius:14px!important;}' + '.trt-quiz-teaser-cta{min-height:56px!important;padding:16px 32px!important;font-size:13px!important;letter-spacing:0.08em!important;}' + '}', /* Mobile: kleinere padding + radius */ '@media (max-width:768px){.trt-wl-v2[data-tool="estimator"]{padding:22px 20px 24px!important;border-radius:0 0 14px 14px!important;}#wow-stat{padding:28px 16px 0!important;}#wow-stat>div{padding:28px 20px 28px!important;border-radius:14px 14px 0 0!important;}section#wow-stat + .trt-wl-v2[data-tool="wow-stat"]{padding:0 20px 24px!important;}.page-trust-bar{padding:18px 20px 20px!important;border-radius:0 0 14px 14px!important;}}', /* v35 · visual unity: closer to tool-card above (16px gap mobile, 20px desktop) */ '.trt-wl-v2{background:#FFFFFF;padding:28px 28px 22px;margin:20px auto 56px;max-width:560px;border:1.5px solid #E5EAF1;border-radius:14px;font-family:"Kanit",sans-serif;position:relative;box-shadow:0 4px 20px rgba(29,51,91,0.04);}', '.trt-wl-v2-eyebrow{font-family:"Oswald",sans-serif;font-size:11px;color:#1D335B;text-transform:uppercase;letter-spacing:0.14em;margin:0 0 10px;font-weight:500;text-align:center;}', '.trt-wl-v2-tagline{font-family:"Kanit",sans-serif;font-size:14px;color:#4B5563;margin:0 0 18px;text-align:center;line-height:1.55;font-weight:400;}', /* v35 · CTA matches site "wa-cta" DNA pattern: baby-blue bg + dark-navy text + WhatsApp-icon-recognition */ '.trt-wl-v2-cta{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;min-height:52px;background:#8DBFE2;color:#1D335B;border:none;border-radius:12px;font-size:13px;font-weight:700;cursor:pointer;text-decoration:none;padding:10px 18px;line-height:1.35;text-align:center;font-family:"DM Sans",sans-serif;text-transform:uppercase;letter-spacing:0.06em;transition:background 0.2s,transform 0.1s;}', '.trt-wl-v2-cta:hover{background:#75ACD3;text-decoration:none;color:#1D335B;}', '.trt-wl-v2-cta:active{transform:translateY(1px);}', '.trt-wl-v2-cta svg{flex-shrink:0;width:20px;height:20px;}', '.trt-wl-v2-microcopy{font-family:"Kanit",sans-serif;font-size:12px;color:#6B7280;text-align:center;margin:8px 0 18px;line-height:1.4;}', '.trt-wl-v2-divider{display:flex;align-items:center;gap:12px;margin:16px 0;}', '.trt-wl-v2-divider-line{flex:1;height:1px;background:#E5EAF1;}', '.trt-wl-v2-divider-text{font-family:"Kanit",sans-serif;font-size:12px;color:#6B7280;white-space:nowrap;font-weight:400;}', '.trt-wl-v2-form{display:flex;gap:6px;flex-wrap:wrap;}', '.trt-wl-v2-form select{width:96px;background:#FFFFFF;color:#1D335B;border:1.5px solid rgba(29,51,91,0.15);height:46px;border-radius:8px;font-size:13px;padding:0 8px;font-family:"Kanit",sans-serif;font-weight:500;}', '.trt-wl-v2-form select:focus{outline:none;border-color:#8DBFE2;box-shadow:0 0 0 3px rgba(141,191,226,0.18);}', '.trt-wl-v2-form input{flex:1;min-width:140px;background:#FFFFFF;color:#1D335B;border:1.5px solid rgba(29,51,91,0.15);height:46px;border-radius:8px;font-size:15px;padding:0 14px;font-family:"Kanit",sans-serif;}', '.trt-wl-v2-form input:focus{outline:none;border-color:#8DBFE2;box-shadow:0 0 0 3px rgba(141,191,226,0.18);}', '.trt-wl-v2-form input::placeholder{color:#9CA3AF;font-weight:400;}', '.trt-wl-v2-form button{background:#1D335B;color:#FFFFFF;border:none;height:46px;padding:0 18px;border-radius:8px;font-size:12px;font-weight:700;cursor:pointer;white-space:nowrap;font-family:"DM Sans",sans-serif;text-transform:uppercase;letter-spacing:0.06em;transition:background 0.2s;}', '.trt-wl-v2-form button:hover{background:#2A4A7F;}', '.trt-wl-v2-form button:disabled{opacity:0.5;cursor:wait;}', '.trt-wl-v2-status{font-family:"Kanit",sans-serif;font-size:12px;text-align:center;color:#6B7280;margin:10px 0 0;min-height:16px;}', '.trt-wl-v2-trustbar{display:flex;gap:16px;justify-content:center;font-family:"Kanit",sans-serif;font-size:11px;color:#6B7280;padding-top:14px;margin-top:16px;border-top:1px solid #E5EAF1;flex-wrap:wrap;font-weight:500;}', '.trt-wl-v2-trustbar span{display:inline-flex;align-items:center;gap:4px;}', '@media (max-width:560px){.trt-wl-v2{margin:14px 16px 40px;padding:22px 18px 18px;}.trt-wl-v2-cta{font-size:12px;min-height:52px;padding:8px 12px;}.trt-wl-v2-form select{width:84px;font-size:12px;}.trt-wl-v2-form input{min-width:110px;font-size:14px;}.trt-wl-v2-form button{padding:0 14px;font-size:11px;}.trt-wl-v2-trustbar{gap:10px;font-size:10px;}}', /* ============================================================ * v73 · PATTAYA APPLE/HIMS POLISH MIRROR * Mirror all v51.x rules above for Pattaya's section IDs: * #how-it-works ≈ #quiz * #wirkstoffe ≈ #treatments * #cost ≈ #access * #related-programs ≈ #related * This makes Pattaya visually identical to Thailand polish. * ============================================================ */ /* v73.1 · SECTION WIDTH UNIFICATION (Pattaya IDs) */ 'section#how-it-works > div, section#wirkstoffe > div, section#cost > div, section#related-programs > div{max-width:1120px!important;margin-left:auto!important;margin-right:auto!important;padding-left:32px!important;padding-right:32px!important;box-sizing:border-box!important;width:100%!important;}', /* v73.2 · SECTION VERTICAL RHYTHM (Pattaya IDs) */ 'section#how-it-works, section#wirkstoffe, section#cost, section#related-programs{padding-top:96px!important;padding-bottom:96px!important;}', /* v73.4 · UNIFIED CARD SYSTEM (Pattaya IDs) */ 'section#wirkstoffe [class*="rounded-"], section#cost [class*="rounded-"], section#how-it-works [class*="rounded-"]{border-radius:18px!important;}', 'section#wirkstoffe .bg-white, section#cost .bg-white, section#how-it-works .bg-white{border:1px solid rgba(29,51,91,0.08)!important;box-shadow:0 4px 24px rgba(29,51,91,0.06)!important;border-radius:18px!important;}', /* v73.5 · INTERNAL CARD WHITESPACE (Pattaya IDs) */ 'section#wirkstoffe .bg-white, section#cost .bg-white, section#how-it-works .bg-white{padding:32px 28px!important;}', /* v73.6 · CTA TIER 2 (Pattaya IDs) — baby-blue action buttons */ 'section#wirkstoffe a[class*="bg-[#8DBFE2]"], section#cost a[class*="bg-[#8DBFE2]"], section#how-it-works a[class*="bg-[#8DBFE2]"]{min-height:48px!important;border-radius:12px!important;padding:0 22px!important;font-size:13px!important;font-weight:700!important;letter-spacing:0.06em!important;transition:transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease!important;box-shadow:0 4px 14px rgba(29,51,91,0.10)!important;}', /* CTA Tier 3 (outlined Request Consultation) Pattaya IDs */ 'section#wirkstoffe a[class*="border-"][class*="8DBFE2"], section#cost a[class*="border-"][class*="8DBFE2"], section#how-it-works a[class*="border-"][class*="8DBFE2"]{min-height:48px!important;border-radius:12px!important;padding:0 22px!important;border:2px solid #8DBFE2!important;background:#FFFFFF!important;color:#1D335B!important;font-size:13px!important;font-weight:700!important;letter-spacing:0.06em!important;transition:transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease!important;}', /* v73.7 · CARD HOVER MICRO-INTERACTIONS (Pattaya IDs) */ 'section#wirkstoffe .bg-white, section#cost .bg-white, section#how-it-works .bg-white{transition:transform 0.25s ease, box-shadow 0.25s ease!important;}', 'section#wirkstoffe .bg-white:hover, section#cost .bg-white:hover, section#how-it-works .bg-white:hover{transform:translateY(-3px)!important;box-shadow:0 10px 32px rgba(29,51,91,0.10)!important;}', /* v73.8 · CTA HOVER LIFT (Pattaya IDs) */ 'section#wirkstoffe a:hover[class*="bg-[#8DBFE2]"], section#cost a:hover[class*="bg-[#8DBFE2]"], section#how-it-works a:hover[class*="bg-[#8DBFE2]"]{transform:translateY(-1px)!important;box-shadow:0 8px 20px rgba(29,51,91,0.16)!important;}', 'section#wirkstoffe a:hover[class*="border-"][class*="8DBFE2"], section#cost a:hover[class*="border-"][class*="8DBFE2"], section#how-it-works a:hover[class*="border-"][class*="8DBFE2"]{background:#F0F7FC!important;transform:translateY(-1px)!important;}', /* v73.9 · MOBILE OVERRIDES (Pattaya IDs) */ '@media (max-width:768px){' + 'section#how-it-works > div, section#wirkstoffe > div, section#cost > div, section#related-programs > div{padding-left:20px!important;padding-right:20px!important;}' + 'section#how-it-works, section#wirkstoffe, section#cost, section#related-programs{padding-top:56px!important;padding-bottom:56px!important;}' + 'section#wirkstoffe [class*="rounded-"], section#cost [class*="rounded-"], section#how-it-works [class*="rounded-"]{border-radius:14px!important;}' + 'section#wirkstoffe .bg-white, section#cost .bg-white, section#how-it-works .bg-white{padding:24px 20px!important;border-radius:14px!important;}' + '}', /* ============================================================ * v74 · PATTAYA-CLEAN — Hide redundant Trust-Bar + Mini-Nav * Pattaya uses .chapter-nav (Thailand uses .hub-chapter-nav * which is already hidden in v50). Pattaya also has a free- * floating .page-trust-bar between estimator and sections * (on Thailand it's JS-fused into the wow-stat ONE-CARD). * Use :has() to scope these hide-rules ONLY to Pattaya * (pages with .chapter-nav, NOT .hub-chapter-nav). * ============================================================ */ 'html:has(.chapter-nav) .chapter-nav, html:has(.chapter-nav) .chapter-nav-inner, html:has(.chapter-nav) section.chapter-nav-wrap{display:none!important;}', 'html:has(.chapter-nav) section.page-trust-bar-wrap, html:has(.chapter-nav) .page-trust-bar-wrap, html:has(.chapter-nav) .page-trust-bar{display:none!important;}', /* ============================================================ * v75 · WL POLISH UNIFICATION — extend Apple/Hims polish to * all 17 previously-uncovered section IDs across 9 pages * (4 Drug-Std, 3 Drug-Sci, 1 International, 1 Liraglutide stub). * Targets: * Drug-Std (Mounjaro/Wegovy/Ozempic/Saxenda): * #indication, #authenticity, #schedule, #process * Drug-Sci (Retatrutide/Tirzepatide/Semaglutide): * #science, #compare, #brands * International: * #modes, #cost-compare, #logistics * Liraglutide stub: * #what, #outcomes, #dosing, #side-effects, #who, #alternatives * Universal: * #site-index * Polish: 1120px content-cap, 96px desktop / 56px mobile padding, * Apple/Hims card chrome where .bg-white cards exist. * Risk: ZERO regression possible — additive selectors only. * ============================================================ */ /* v75.1 — Section width unification (covers all 17 IDs) */ 'section#indication > div, section#authenticity > div, section#schedule > div, section#process > div, section#science > div, section#compare > div, section#brands > div, section#modes > div, section#cost-compare > div, section#logistics > div, section#what > div, section#outcomes > div, section#dosing > div, section#side-effects > div, section#who > div, section#alternatives > div, section#site-index > div, section#access-paths > div{max-width:1120px!important;margin-left:auto!important;margin-right:auto!important;padding-left:32px!important;padding-right:32px!important;box-sizing:border-box!important;width:100%!important;}', /* v75.2 — Section vertical rhythm 96px desktop */ 'section#indication, section#authenticity, section#schedule, section#process, section#science, section#compare, section#brands, section#modes, section#cost-compare, section#logistics, section#what, section#outcomes, section#dosing, section#side-effects, section#who, section#alternatives, section#site-index, section#access-paths{padding-top:96px!important;padding-bottom:96px!important;}', /* v75.3 — Card chrome for .bg-white cards inside new sections (only main cards, NOT inline chips) */ 'section#indication > div .bg-white:not([class*="px-["]):not([class*="py-["]), section#authenticity > div .bg-white:not([class*="px-["]):not([class*="py-["]), section#schedule > div .bg-white:not([class*="px-["]):not([class*="py-["]), section#process > div .bg-white:not([class*="px-["]):not([class*="py-["]), section#science > div .bg-white:not([class*="px-["]):not([class*="py-["]), section#compare > div .bg-white:not([class*="px-["]):not([class*="py-["]), section#brands > div .bg-white:not([class*="px-["]):not([class*="py-["]), section#modes > div .bg-white:not([class*="px-["]):not([class*="py-["]), section#cost-compare > div .bg-white:not([class*="px-["]):not([class*="py-["]), section#logistics > div .bg-white:not([class*="px-["]):not([class*="py-["]){border:1px solid rgba(29,51,91,0.08)!important;box-shadow:0 4px 24px rgba(29,51,91,0.06)!important;border-radius:18px!important;padding:32px 28px!important;transition:transform 0.25s ease, box-shadow 0.25s ease!important;}', /* v75.4 — Card hover lift */ 'section#indication > div .bg-white:hover, section#authenticity > div .bg-white:hover, section#schedule > div .bg-white:hover, section#process > div .bg-white:hover, section#science > div .bg-white:hover, section#compare > div .bg-white:hover, section#brands > div .bg-white:hover, section#modes > div .bg-white:hover, section#cost-compare > div .bg-white:hover, section#logistics > div .bg-white:hover{transform:translateY(-3px)!important;box-shadow:0 10px 32px rgba(29,51,91,0.10)!important;}', /* v75.5 — Mobile breakpoint for new sections (56px padding, 20px sides) */ '@media (max-width:768px){' + 'section#indication > div, section#authenticity > div, section#schedule > div, section#process > div, section#science > div, section#compare > div, section#brands > div, section#modes > div, section#cost-compare > div, section#logistics > div, section#what > div, section#outcomes > div, section#dosing > div, section#side-effects > div, section#who > div, section#alternatives > div, section#site-index > div, section#access-paths > div{padding-left:20px!important;padding-right:20px!important;}' + 'section#indication, section#authenticity, section#schedule, section#process, section#science, section#compare, section#brands, section#modes, section#cost-compare, section#logistics, section#what, section#outcomes, section#dosing, section#side-effects, section#who, section#alternatives, section#site-index, section#access-paths{padding-top:56px!important;padding-bottom:56px!important;}' + '}' ].join('\n'); document.head.appendChild(s); } /* ============================================================ * 2) Build a v2 module for a given tool * ============================================================ */ var WA_ICON = ''; /* ============================================================ * v24: Smart Country-Picker * - Auto-detects via navigator.language (browser locale) * - Default order: US / UK / AU / DE / TH / SG / AE / CA / RU / FR * (international-tourist focus — most likely customer countries first) * - Detected country jumps to top of list + is preselected * ============================================================ */ var COUNTRIES = [ { cc: '+1', flag: '🇺🇸', label: 'US', match: /^en-?(us|ca)?$/i }, { cc: '+44', flag: '🇬🇧', label: 'UK', match: /^en-?(gb|ie)$/i }, { cc: '+61', flag: '🇦🇺', label: 'AU', match: /^en-?(au|nz)$/i }, { cc: '+49', flag: '🇩🇪', label: 'DE', match: /^de/i }, { cc: '+66', flag: '🇹🇭', label: 'TH', match: /^th/i }, { cc: '+65', flag: '🇸🇬', label: 'SG', match: /^en-?sg$/i }, { cc: '+971', flag: '🇦🇪', label: 'AE', match: /^ar/i }, { cc: '+1', flag: '🇨🇦', label: 'CA', match: /^en-?ca$|^fr-?ca$/i }, { cc: '+7', flag: '🇷🇺', label: 'RU', match: /^ru/i }, { cc: '+33', flag: '🇫🇷', label: 'FR', match: /^fr/i }, { cc: '+39', flag: '🇮🇹', label: 'IT', match: /^it/i }, { cc: '+34', flag: '🇪🇸', label: 'ES', match: /^es/i }, { cc: '+82', flag: '🇰🇷', label: 'KR', match: /^ko/i }, { cc: '+81', flag: '🇯🇵', label: 'JP', match: /^ja/i }, { cc: '+86', flag: '🇨🇳', label: 'CN', match: /^zh/i }, { cc: '+91', flag: '🇮🇳', label: 'IN', match: /^hi|^en-?in$/i } ]; function detectCountryIndex() { var lang = (navigator.language || navigator.userLanguage || '').toLowerCase(); for (var i = 0; i < COUNTRIES.length; i++) { if (COUNTRIES[i].match.test(lang)) return i; } // No match: default to first in list (US) return 0; } function buildCountrySelect() { var idx = detectCountryIndex(); var detected = COUNTRIES[idx]; var rest = COUNTRIES.slice(0, idx).concat(COUNTRIES.slice(idx + 1)); var html = ''; return html; } /* ============================================================ * v25: Clinic-hours-aware timing copy * Bangkok clinic open Mon-Sat 8:00–18:00 (Asia/Bangkok timezone) * - Open: live conversation (clinic staffed) * - Closed: queued response (next clinic hours) * ============================================================ */ function isClinicOpenNow() { try { var bkk = new Date(new Date().toLocaleString('en-US', { timeZone: 'Asia/Bangkok' })); var day = bkk.getDay(); // 0=Sun, 1=Mon.6=Sat var hr = bkk.getHours(); return (day >= 1 && day <= 6) && (hr >= 8 && hr < 18); } catch (e) { return false; // fallback safe: assume closed → promise "within 2 hours" } } function replyTimingShort() { return isClinicOpenNow() ? 'reply within minutes' : 'reply within 2 hours'; } function replyTimingFull() { return isClinicOpenNow() ? 'We\'ll WhatsApp you within minutes · no email · no spam' : 'We\'ll WhatsApp you within 2 hours · no email · no spam'; } function buildCTAText(toolKey, context) { if (toolKey === 'wow-stat') { return context.goal_weight ? 'Get my plan to reach ' + context.goal_weight + ' kg' : 'Get my personalized weight-loss plan'; } if (toolKey === 'estimator') { var drug = context.drug || 'Mounjaro'; return 'Book my ' + drug + ' review on WhatsApp'; } if (toolKey === 'quiz') { var match = context.match || 'GLP-1 program'; return 'Discuss my ' + match + ' on WhatsApp'; } return 'Get a free WhatsApp consultation'; } function buildPrefilledMessage(toolKey, context, pageTopic) { var base = 'Hi TRT Bangkok, '; var page = pageTopic ? ' (saw your ' + pageTopic + ' page)' : ''; if (toolKey === 'wow-stat') { var cur = context.current_weight ? context.current_weight + ' kg' : 'my current weight'; var goal = context.goal_weight ? context.goal_weight + ' kg' : 'my goal weight'; return base + 'I just used your weight-loss calculator. I\'m at ' + cur + ' and could reach ' + goal + '. Can we discuss which program is right for me?' + page; } if (toolKey === 'estimator') { var d = context.drug || 'Mounjaro'; var cw = context.current_weight ? context.current_weight + ' kg' : ''; var gw = context.goal_weight ? context.goal_weight + ' kg' : ''; var weights = (cw && gw) ? ' (' + cw + ' → ' + gw + ')' : ''; return base + 'I just calculated my trajectory for ' + d + weights + '. Can we discuss starting a program?' + page; } if (toolKey === 'quiz') { var m = context.match || 'a GLP-1 program'; return base + 'I just finished your treatment quiz. My match is ' + m + '. Can we discuss next steps?' + page; } return base + 'I\'m interested in your weight-loss program. Can we talk?' + page; } function buildModule(toolKey) { var eyebrows = { 'wow-stat': 'Your personal goal', 'estimator': 'Your personalized trajectory', 'quiz': 'Your treatment match' }; /* v32: Text-Konsolidierung — Reply-Timing nur einmal (im Status). Taglines kurz + benefit-driven. */ var taglines = { 'wow-stat': 'Talk to our clinic about your weight-loss goal.', 'estimator': 'Book your personalized review — we\'ll bring your trajectory into the conversation.', 'quiz': 'Discuss your treatment match with our clinic team.' }; var wrap = document.createElement('div'); wrap.className = 'trt-wl-v2'; wrap.setAttribute('data-tool', toolKey); var pageTopic = (document.body.dataset.pageTopic || document.title || '').replace(/\s*[-—].*$/, '').trim(); var initialCtx = readToolContext(toolKey); var initialText = buildCTAText(toolKey, initialCtx); var initialMsg = buildPrefilledMessage(toolKey, initialCtx, pageTopic); var initialHref = 'https://wa.me/' + WA_NUMBER + '?text=' + encodeURIComponent(initialMsg); wrap.innerHTML = '

' + eyebrows[toolKey] + '

' + '

' + taglines[toolKey] + '

' + '' + WA_ICON + '' + initialText + ' →' + '' + /* v33: microcopy removed — green CTA is self-evidently WhatsApp + status below has all the context */ '
' + '
' + 'or, leave your phone' + '
' + '
' + '
' + buildCountrySelect() + '' + '' + '
' + '

Free consultation · ' + replyTimingShort() + ' · no spam

' + '
' + '✓ 1,000+ patients' + '✓ 5.0 Google' + '✓ Thai License #72509' + '
'; /* Live-update CTA when tool state changes (best-effort via polling) */ var ctaA = wrap.querySelector('[data-track-one]'); var ctaLabel = wrap.querySelector('[data-cta-label]'); var lastCtxStr = JSON.stringify(initialCtx); setInterval(function() { var ctx = readToolContext(toolKey); var cs = JSON.stringify(ctx); if (cs === lastCtxStr) return; lastCtxStr = cs; var newText = buildCTAText(toolKey, ctx); var newMsg = buildPrefilledMessage(toolKey, ctx, pageTopic); ctaA.href = 'https://wa.me/' + WA_NUMBER + '?text=' + encodeURIComponent(newMsg); ctaLabel.textContent = newText + ' →'; }, 1500); /* Track-1 click event */ ctaA.addEventListener('click', function() { if (typeof gtag === 'function') { gtag('event', 'wl_v2_track1_click', { tool: toolKey, page: location.pathname }); } }); /* Track-2 submit */ var form = wrap.querySelector('form'); form.addEventListener('submit', function(e) { e.preventDefault(); var btn = form.querySelector('button'); var status = wrap.querySelector('.trt-wl-v2-status'); var cc = form.cc.value; var phoneRaw = (form.phone.value || '').replace(/[^0-9]/g, ''); if (phoneRaw.length < 6) { status.textContent = 'Please enter a valid phone number.'; status.style.color = '#FCD34D'; return; } var fullPhone = cc + ' ' + phoneRaw; btn.disabled = true; btn.textContent = 'Sending…'; status.style.color = '#FFFFFF'; status.textContent = ''; var ctx = readToolContext(toolKey); var payload = { location: 'wl-v2-' + toolKey, name: '', email: '', whatsapp: fullPhone, phone: fullPhone, country_code: cc, current_weight: ctx.current_weight || '', goal_weight: ctx.goal_weight || '', preferred_drug: ctx.drug || ctx.match || '', tool: toolKey, tool_context: JSON.stringify(ctx), page: location.pathname.replace(/^\//, '').replace(/\/$/, ''), page_type: document.body.dataset.pageType || 'wl-spoke', page_topic: pageTopic, referrer: document.referrer || '', source_url: location.href }; var fetchPromise = ENDPOINT ? fetch(ENDPOINT, { method: 'POST', mode: 'no-cors', headers: { 'Content-Type': 'text/plain;charset=utf-8' }, body: JSON.stringify(payload) }).then(function() { return true; }).catch(function() { return false; }) : Promise.resolve(false); fetchPromise.then(function(ok) { if (typeof gtag === 'function') { gtag('event', 'wl_v2_track2_submit', { tool: toolKey, page: location.pathname, ok: ok }); } status.style.color = '#0F6E56'; status.textContent = isClinicOpenNow() ? '✓ Thanks! We\'ll WhatsApp you within minutes. Opening WhatsApp now…' : '✓ Thanks! We\'ll WhatsApp you within 2 hours. Opening WhatsApp now…'; btn.textContent = '✓ Sent'; /* Also open WhatsApp for the user — high-intent flow */ var msg = buildPrefilledMessage(toolKey, ctx, pageTopic) + ' My number: ' + fullPhone + '.'; var waUrl = 'https://wa.me/' + WA_NUMBER + '?text=' + encodeURIComponent(msg); setTimeout(function() { window.open(waUrl, '_blank'); }, 600); }); }); return wrap; } /* ============================================================ * 3) Read live tool state — best-effort DOM scraping per tool * ============================================================ */ function readToolContext(toolKey) { if (toolKey === 'wow-stat') { var sec = document.getElementById('wow-stat'); if (!sec) return {}; var nums = sec.querySelectorAll('input[type="number"], input[type="text"]'); var cur = nums.length ? parseFloat(nums[0].value) : null; /* Look for goal weight in displayed text like "you'd weigh 67.2 kg" */ var txt = sec.textContent || ''; var m = txt.match(/(\d+(?:\.\d+)?)\s*kg/g); var goal = null; if (m && m.length) { var nums2 = m.map(function(s) { return parseFloat(s); }); /* The smaller number in the section after "weigh" is likely the goal */ var weighIdx = txt.search(/weigh\s*$/i); var idx = txt.search(/weigh\s+/i); if (idx > -1) { var after = txt.slice(idx + 5); var gm = after.match(/(\d+(?:\.\d+)?)\s*kg/); if (gm) goal = parseFloat(gm[1]); } } return { current_weight: cur && !isNaN(cur) ? cur : null, goal_weight: goal, drug: 'Mounjaro' /* WOW-Stat on hub is Mounjaro-focused */ }; } if (toolKey === 'estimator') { var sec2 = document.getElementById('estimator'); if (!sec2) return {}; /* Find selected drug tab (visually highlighted button) */ var drug = null; var btns = sec2.querySelectorAll('button, [role="tab"], div[data-drug]'); for (var i = 0; i < btns.length; i++) { var b = btns[i]; var bg = window.getComputedStyle(b).backgroundColor; var txt2 = (b.textContent || '').trim(); if (/^(Mounjaro|Wegovy|Retatrutide|Tirzepatide|Ozempic|Semaglutide|Saxenda|Zepbound)$/i.test(txt2.split('\n')[0])) { if (bg && bg !== 'rgba(0, 0, 0, 0)' && bg !== 'transparent') { /* heuristic: dark blue = selected */ if (/24, 95, 165|29, 51, 91|0, 100|29,51,91/.test(bg.replace(/\s/g, ''))) { drug = txt2.split('\n')[0].trim(); break; } } if (!drug) drug = txt2.split('\n')[0].trim(); } } var inputs = sec2.querySelectorAll('input[type="number"], input[type="text"]'); var cw = inputs.length > 0 ? parseFloat(inputs[0].value) : null; var gw = inputs.length > 1 ? parseFloat(inputs[1].value) : null; return { drug: drug || 'Mounjaro', current_weight: cw && !isNaN(cw) ? cw : null, goal_weight: gw && !isNaN(gw) ? gw : null }; } if (toolKey === 'quiz') { var sec3 = document.getElementById('quiz'); if (!sec3) return {}; var matchTxt = sec3.textContent.match(/Your\s+(?:match|recommendation)[\s:]+([A-Za-z][A-Za-z\s\-]+?)(?:\.|$|\n)/i); return { match: matchTxt ? matchTxt[1].trim() : null }; } return {}; } /* ============================================================ * v30: Hub-Quiz → Teaser-CTA (replaces inline quiz on hub-page) * Inside section#quiz: hide quiz form/steps, inject single CTA * that links to /weight-loss-calculator/ * ============================================================ */ function injectQuizTeaser() { var sec = document.getElementById('quiz'); if (!sec) return false; if (sec.querySelector('.trt-quiz-teaser-cta')) return true; /* already injected */ /* Hide quiz form content but keep heading + sub */ var hideStyle = document.createElement('style'); hideStyle.id = 'trt-hub-quiz-hide'; hideStyle.textContent = [ /* hide all step content + back/next buttons inside #quiz, keep only the heading area */ '#quiz [class*="step-"], #quiz .step, #quiz [class*="quiz-step"]{display:none!important;}', /* hide any input/select/button/form inside #quiz */ '#quiz form, #quiz input, #quiz select, #quiz button:not(.trt-quiz-teaser-cta), #quiz .nav-row, #quiz .progress-bar{display:none!important;}', /* hide nested div containers that hold the quiz form (heuristic: divs with multiple inputs as descendants) */ '#quiz > div > div:has(input), #quiz > div > div:has(select){display:none!important;}' ].join('\n'); document.head.appendChild(hideStyle); /* Build the CTA */ var ctaWrap = document.createElement('div'); ctaWrap.className = 'trt-quiz-teaser-wrap'; ctaWrap.style.cssText = 'max-width:560px;margin:24px auto 0;padding:0 20px;text-align:center;'; ctaWrap.innerHTML = '' + 'Start Your 2-Minute Assessment →' + '

Reviewed by Dr. Kenika Norrachetdecha, MD · Thai License #72509

'; /* Append directly to the section (most robust against React re-render) */ sec.appendChild(ctaWrap); /* Hover handler */ var cta = ctaWrap.querySelector('a'); cta.addEventListener('mouseenter', function() { cta.style.background = '#2A4A7F'; }); cta.addEventListener('mouseleave', function() { cta.style.background = '#1D335B'; }); cta.addEventListener('click', function() { if (typeof gtag === 'function') gtag('event', 'wl_hub_quiz_teaser_click', { destination: '/weight-loss-calculator/' }); }); return true; } /* ============================================================ * 4) Inject modules as siblings AFTER each tool section * v39: Back to sibling-inject (React-safe), but with section-background-bridge * via injected CSS that extends the tool-section visual into the v2-modul. * ============================================================ */ /* ============================================================ * v49: Runtime width-sync — kein CSS-calc-Glücksspiel mehr. * Measure inner card's actual bounding rect → apply identical * width + left-offset to v2 module via inline-style. * Adapts to ANY viewport (320px → 4K), survives React re-renders, * and survives Site-CSS conflicts since inline-style wins. * ============================================================ */ function syncCardWidths() { var pairs = [ { sectionId: 'wow-stat', innerSel: ':scope > div' }, { sectionId: 'estimator', innerSel: ':scope > div > div.bg-white' } ]; var wowInnerRect = null; /* v50: capture wow-stat inner for trust-bar sync */ pairs.forEach(function(p) { var sec = document.getElementById(p.sectionId); if (!sec) return; var inner = sec.querySelector(p.innerSel); var v2 = document.querySelector('.trt-wl-v2[data-tool="' + p.sectionId + '"]'); if (!inner || !v2) return; var innerRect = inner.getBoundingClientRect(); if (p.sectionId === 'wow-stat') wowInnerRect = innerRect; /* offsetLeft of inner relative to v2's parent (= section's parent = body usually) */ var v2ParentRect = v2.parentNode.getBoundingClientRect(); var leftOffset = innerRect.left - v2ParentRect.left; var width = innerRect.width; /* Apply via inline-style — beats all CSS-cascade */ v2.style.setProperty('width', width + 'px', 'important'); v2.style.setProperty('max-width', width + 'px', 'important'); v2.style.setProperty('margin-left', leftOffset + 'px', 'important'); v2.style.setProperty('margin-right', '0', 'important'); /* Also sync background of section to body bg, kill any divider borders */ sec.style.setProperty('background', 'rgb(240, 245, 250)', 'important'); sec.style.setProperty('border-top', '0', 'important'); sec.style.setProperty('border-bottom', '0', 'important'); }); /* v50: sync .page-trust-bar width + leftOffset to match wow-stat inner card (third shell of ONE-CARD) */ if (wowInnerRect) { var trustBar = document.querySelector('.page-trust-bar'); if (trustBar) { var tbParentRect = trustBar.parentNode.getBoundingClientRect(); var tbLeftOffset = wowInnerRect.left - tbParentRect.left; trustBar.style.setProperty('width', wowInnerRect.width + 'px', 'important'); trustBar.style.setProperty('max-width', wowInnerRect.width + 'px', 'important'); trustBar.style.setProperty('margin-left', tbLeftOffset + 'px', 'important'); trustBar.style.setProperty('margin-right', '0', 'important'); } /* v50: also kill page-trust-bar-wrap inline border-top/bottom + sync bg */ var tbWrap = document.querySelector('section.page-trust-bar-wrap'); if (tbWrap) { tbWrap.style.setProperty('background', 'rgb(240, 245, 250)', 'important'); tbWrap.style.setProperty('border-top', '0', 'important'); tbWrap.style.setProperty('border-bottom', '0', 'important'); tbWrap.style.setProperty('padding-top', '0', 'important'); tbWrap.style.setProperty('padding-bottom', '0', 'important'); tbWrap.style.setProperty('margin-top', '0', 'important'); } } } /* ============================================================ * v53 · HERO DE-CLUTTER (SICHERE Version — exakte DOM-Targets statt blindes text-content match) * Hide redundant trust signals + distractors that duplicate the page-trust-bar 2000px below. * v52 ROLLBACK: text-content match war zu breit, hat Parent-Hero erwischt. * v53 Fix: spezifische class-Anforderungen + children-count guards + text-length guards. * ============================================================ */ function hideHeroNoise() { /* T1: Bullet trust list parent — div.flex.flex-col mit EXAKT 3 children wobei first child mit "Authentic Mounjaro" beginnt. KANN unmöglich Hero-Parent treffen. */ document.querySelectorAll('div.flex.flex-col').forEach(function(div) { if (div.__trtHidden) return; if (div.children.length !== 3) return; var firstChildText = (div.children[0].innerText || '').trim(); if (firstChildText.indexOf('Authentic Mounjaro') === 0) { div.style.setProperty('display', 'none', 'important'); div.__trtHidden = true; } }); /* v54: T2 (Doctor block) RAUS — Dr. Kenika mit rundem Foto ist wichtiger Authority/Humanization-Trust-Signal, bleibt sichtbar. */ /* T3: Mon-Sat status — p.font-body mit "Mon" + ("AM"|"Sat") — sehr spezifisch, kein anderes p hat genau diese kombo. */ document.querySelectorAll('p.font-body').forEach(function(p) { if (p.__trtHidden) return; var t = p.innerText || ''; if (t.indexOf('Mon') >= 0 && (t.indexOf('AM') >= 0 || t.indexOf('Sat') >= 0)) { p.style.setProperty('display', 'none', 'important'); p.__trtHidden = true; } }); } function inject() { injectHideCSS(); /* v52: hero de-clutter (run early so user sees clean hero ASAP) */ hideHeroNoise(); /* Quiz: replace with teaser CTA to /weight-loss-calculator/ */ injectQuizTeaser(); /* Tools: inject AFTER wow-stat + estimator as siblings */ var tools = ['wow-stat', 'estimator']; tools.forEach(function(key) { var sec = document.getElementById(key); if (!sec) return; /* v46: kill whitespace-only text nodes inside section that create the 3px trailing gap */ Array.prototype.slice.call(sec.childNodes).forEach(function(n) { if (n.nodeType === 3 && !(n.textContent && n.textContent.trim())) { n.parentNode.removeChild(n); } }); /* v47/v48/v49: inline-style overrides — beats site's higher-specificity rules. */ sec.style.setProperty('background', 'rgb(240, 245, 250)', 'important'); sec.style.setProperty('border-top', '0', 'important'); sec.style.setProperty('border-bottom', '0', 'important'); /* Skip if module already a sibling */ if (sec.nextElementSibling && sec.nextElementSibling.classList && sec.nextElementSibling.classList.contains('trt-wl-v2') && sec.nextElementSibling.getAttribute('data-tool') === key) return; var mod = buildModule(key); if (sec.parentNode) { sec.parentNode.insertBefore(mod, sec.nextSibling); } }); /* Remove any existing v2-module that was previously injected under #quiz */ var oldQuizMod = document.querySelector('.trt-wl-v2[data-tool="quiz"]'); if (oldQuizMod) oldQuizMod.remove(); /* v49: width-sync after inject — schedule multiple times to catch late layout shifts */ syncCardWidths(); [50, 200, 600, 1500, 3000].forEach(function(ms) { setTimeout(syncCardWidths, ms); setTimeout(hideHeroNoise, ms); /* v52: re-apply hide after potential React re-render */ }); /* v60: sticky-CTA visibility manager — hide bottom sticky when any baby-blue in-page CTA visible */ setTimeout(initStickyCtaObserver, 1000); /* v63: JS-driven press feedback (CSS :active was beaten by v51 cascade-war) */ setTimeout(initPressFeedback, 800); /* v66: fix Tailwind bracket-class SVG widths (w-[22px] etc. render as 0 width) */ fixBrokenSvgIcons(); [100, 500, 1500, 3000].forEach(function(ms) { setTimeout(fixBrokenSvgIcons, ms); }); } /* ============================================================ * v66 · Fix broken Tailwind bracket-class SVG widths * SVGs with class="w-[22px] h-[22px]" sometimes render at 0×0 * (Tailwind brackets not always parsed by the runtime CSS). * Solution: parse the class, set width/height attributes directly * on the SVG element — HTML attributes beat CSS for SVG sizing. * ============================================================ */ function fixBrokenSvgIcons() { var svgs = document.querySelectorAll('svg[class*="w-["], svg[class*="h-["]'); svgs.forEach(function(svg) { if (svg.__trtSvgFixed) return; var cls = svg.getAttribute('class') || ''; var wm = cls.match(/w-\[(\d+)px\]/); var hm = cls.match(/h-\[(\d+)px\]/); if (wm) svg.setAttribute('width', wm[1]); if (hm) svg.setAttribute('height', hm[1]); if (wm || hm) { svg.style.setProperty('width', (wm ? wm[1] : (hm ? hm[1] : '24')) + 'px', 'important'); svg.style.setProperty('height', (hm ? hm[1] : (wm ? wm[1] : '24')) + 'px', 'important'); svg.style.setProperty('flex-shrink', '0', 'important'); svg.__trtSvgFixed = true; } }); } /* ============================================================ * v65 · JS-driven Press Feedback (PRONOUNCED scale + 150ms hold) * pointerdown → scale(0.85) + dark bg overlay via inline !important * pointerup → animate back (snappy 0.18s ease-out) * Uses element.animate() Web Animations API as backup if transition fails. * ============================================================ */ function initPressFeedback() { if (window.__trt_press_init) return; window.__trt_press_init = true; var SELECTORS = [ '.trt-quiz-teaser-cta', '.trt-hero-cta', 'a.wa-cta', '.trt-wl-v2-cta', 'a[class*="border-white"][class*="rounded-"]', 'a[class*="bg-[#8DBFE2]"][class*="rounded-"]', ].join(','); var pressed = null; var minHoldTime = 150; /* ms — minimum visual press time so user sees it */ function addPress(e) { var t = e.target.closest(SELECTORS); if (!t) return; if (pressed && pressed.el === t) return; pressed = { el: t, startTime: performance.now() }; /* Disable existing transition first so the scale change is INSTANT */ t.style.setProperty('transition', 'none', 'important'); t.style.setProperty('transform', 'scale(0.85)', 'important'); t.style.setProperty('opacity', '0.80', 'important'); t.style.setProperty('filter', 'brightness(0.85)', 'important'); /* Force reflow to commit the no-transition + scale state */ void t.offsetHeight; } function releaseNow(p) { /* now turn transition back on for SMOOTH return */ p.el.style.setProperty('transition', 'transform 0.22s cubic-bezier(.34,1.56,.64,1), opacity 0.22s ease, filter 0.22s ease', 'important'); p.el.style.removeProperty('transform'); p.el.style.removeProperty('opacity'); p.el.style.removeProperty('filter'); /* cleanup transition override after return animation completes */ setTimeout(function() { p.el.style.removeProperty('transition'); }, 240); } function removePress() { if (!pressed) return; var p = pressed; pressed = null; /* Ensure minimum hold time so user perceives press visually */ var elapsed = performance.now() - p.startTime; var wait = Math.max(0, minHoldTime - elapsed); setTimeout(function() { releaseNow(p); }, wait); } document.addEventListener('pointerdown', addPress, { passive: true }); document.addEventListener('pointerup', removePress, { passive: true }); document.addEventListener('pointercancel', removePress, { passive: true }); document.addEventListener('touchend', removePress, { passive: true }); document.addEventListener('touchcancel', removePress, { passive: true }); document.addEventListener('mouseup', removePress, { passive: true }); } /* ============================================================ * v60 · Sticky-CTA Visibility Manager * CRO best-practice (Hims/Apple): hide the bottom sticky-cta * when an in-page primary CTA (baby-blue) is visible — no * decision-paralysis from two competing CTAs on screen. * ============================================================ */ function initStickyCtaObserver() { if (window.__trt_sticky_obs) return; /* idempotent */ var sticky = document.querySelector('.sticky-cta'); if (!sticky) return; /* Watch all v2-modules (each has a baby-blue CTA inside) */ var watch = Array.prototype.slice.call(document.querySelectorAll('.trt-wl-v2')); if (!watch.length) return; var visibleSet = new Set(); function updateSticky() { if (visibleSet.size > 0) { sticky.style.setProperty('opacity', '0', 'important'); sticky.style.setProperty('pointer-events', 'none', 'important'); sticky.style.setProperty('transform', 'translateY(100%)', 'important'); } else { sticky.style.removeProperty('opacity'); sticky.style.removeProperty('pointer-events'); sticky.style.removeProperty('transform'); } } var obs = new IntersectionObserver(function(entries) { entries.forEach(function(e) { if (e.isIntersecting && e.intersectionRatio > 0.4) { visibleSet.add(e.target); } else { visibleSet.delete(e.target); } }); updateSticky(); }, { threshold: [0, 0.4, 1] }); watch.forEach(function(el) { obs.observe(el); }); window.__trt_sticky_obs = obs; } /* v49: Re-sync on viewport changes (orientation, resize) and on React re-renders */ window.addEventListener('resize', function() { /* debounce */ clearTimeout(window.__trt_wl_v2_resize_t); window.__trt_wl_v2_resize_t = setTimeout(syncCardWidths, 100); }); window.addEventListener('orientationchange', function() { setTimeout(syncCardWidths, 200); }); /* Observe DOM mutations on wow-stat and estimator sections to catch React re-renders */ if (typeof MutationObserver !== 'undefined') { var mo = new MutationObserver(function() { clearTimeout(window.__trt_wl_v2_mo_t); window.__trt_wl_v2_mo_t = setTimeout(syncCardWidths, 50); }); setTimeout(function() { ['wow-stat', 'estimator'].forEach(function(id) { var el = document.getElementById(id); if (el) mo.observe(el, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); }); }, 1500); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', inject); } else { inject(); } /* Re-run after React-hydration in case tools render late */ setTimeout(inject, 800); setTimeout(inject, 2000); })();