<section class="apw-tcm-tool">

<div class="apw-wrap">

<h2>TCM Symptom Checklist & Differential Builder</h2>

<p class="apw-intro">

Select symptoms below to see which TCM patterns are most strongly represented.

</p>

<div class="apw-grid">

<div class="apw-left">

<div class="apw-card">

<h3>Head / Location</h3>

<label><input type="checkbox" data-pattern="shaoyang" data-score="3"> One-sided headache</label>

<label><input type="checkbox" data-pattern="shaoyang" data-score="2"> Temporal pain</label>

<label><input type="checkbox" data-pattern="liverYang" data-score="2"> Vertex headache</label>

<label><input type="checkbox" data-pattern="taiyang" data-score="2"> Occipital headache</label>

<label><input type="checkbox" data-pattern="yangming" data-score="2"> Frontal headache</label>

</div>

<div class="apw-card">

<h3>Headache Quality</h3>

<label><input type="checkbox" data-pattern="liverYang" data-score="3"> Pounding / throbbing</label>

<label><input type="checkbox" data-pattern="liverQi" data-score="2"> Distending pressure</label>

<label><input type="checkbox" data-pattern="dampPhlegm" data-score="3"> Heavy / foggy</label>

<label><input type="checkbox" data-pattern="bloodYinDef" data-score="3"> Dull / empty</label>

<label><input type="checkbox" data-pattern="bloodStasis" data-score="3"> Sharp / fixed pain</label>

</div>

<div class="apw-card">

<h3>Eyes</h3>

<label><input type="checkbox" data-pattern="bloodYinDef" data-score="2"> Dry eyes</label>

<label><input type="checkbox" data-pattern="bloodYinDef" data-score="2"> Floaters</label>

<label><input type="checkbox" data-pattern="liverYang" data-score="2"> Red eyes</label>

<label><input type="checkbox" data-pattern="bloodYinDef" data-score="1"> Blurry vision</label>

</div>

<div class="apw-card">

<h3>Ears</h3>

<label><input type="checkbox" data-pattern="shaoyang" data-score="3"> Ear fullness</label>

<label><input type="checkbox" data-pattern="shaoyang" data-score="3"> Muffled hearing</label>

<label><input type="checkbox" data-pattern="liverYang" data-score="2"> High-pitched tinnitus</label>

<label><input type="checkbox" data-pattern="kidneyDef" data-score="2"> Hearing loss</label>

</div>

<div class="apw-card">

<h3>Jaw / Neck / Muscular</h3>

<label><input type="checkbox" data-pattern="liverQi" data-score="2"> Jaw tension / clenching</label>

<label><input type="checkbox" data-pattern="shaoyang" data-score="2"> SCM tension</label>

<label><input type="checkbox" data-pattern="shaoyang" data-score="2"> Side-of-neck tightness</label>

<label><input type="checkbox" data-pattern="taiyang" data-score="2"> Suboccipital tension</label>

<label><input type="checkbox" data-pattern="bloodStasis" data-score="2"> Chronic fixed muscular pain</label>

</div>

<div class="apw-card">

<h3>Stress / Mood / Nervous System</h3>

<label><input type="checkbox" data-pattern="liverQi" data-score="3"> Stress</label>

<label><input type="checkbox" data-pattern="liverYang" data-score="2"> Irritability</label>

<label><input type="checkbox" data-pattern="shenDisturbance" data-score="2"> Anxiety</label>

<label><input type="checkbox" data-pattern="shenDisturbance" data-score="2"> Insomnia</label>

<label><input type="checkbox" data-pattern="liverQi" data-score="2"> Mood swings</label>

</div>

<div class="apw-card">

<h3>Fatigue / Deficiency / Dryness</h3>

<label><input type="checkbox" data-pattern="qiDef" data-score="2"> Fatigue</label>

<label><input type="checkbox" data-pattern="bloodYinDef" data-score="2"> General dryness</label>

<label><input type="checkbox" data-pattern="bloodYinDef" data-score="2"> Pale complexion</label>

<label><input type="checkbox" data-pattern="kidneyDef" data-score="2"> Low back weakness</label>

<label><input type="checkbox" data-pattern="bloodYinDef" data-score="1"> Dizziness</label>

</div>

<div class="apw-card">

<h3>Damp / Digestive</h3>

<label><input type="checkbox" data-pattern="dampPhlegm" data-score="3"> Brain fog</label>

<label><input type="checkbox" data-pattern="dampPhlegm" data-score="3"> Heaviness</label>

<label><input type="checkbox" data-pattern="dampPhlegm" data-score="2"> Sticky stools</label>

<label><input type="checkbox" data-pattern="qiDef" data-score="2"> Poor appetite</label>

<label><input type="checkbox" data-pattern="qiDef" data-score="2"> Bloating</label>

</div>

<div class="apw-actions">

<button type="button" id="apw-reset-btn">Reset</button>

</div>

</div>

<div class="apw-right">

<div class="apw-card apw-results">

<h3>Pattern Scores</h3>

<ul id="apw-score-list"></ul>

</div>

<div class="apw-card apw-results">

<h3>Evolving Differential</h3>

<ol id="apw-differential-list"></ol>

</div>

<div class="apw-card apw-results">

<h3>Interpretive Notes</h3>

<div id="apw-notes"></div>

</div>

</div>

</div>

</div>

</section>

<style>

.apw-tcm-tool {

--apw-green: #4d7c57;

--apw-green-dark: #35563c;

--apw-green-soft: #edf5ef;

--apw-border: #d7e4da;

--apw-text: #243127;

--apw-muted: #5c6b60;

--apw-white: #ffffff;

--apw-shadow: 0 8px 24px rgba(0,0,0,0.06);

font-family: Arial, Helvetica, sans-serif;

color: var(--apw-text);

background: #f7faf7;

padding: 32px 16px;

}

.apw-tcm-tool * {

box-sizing: border-box;

}

.apw-wrap {

max-width: 1200px;

margin: 0 auto;

}

.apw-tcm-tool h2 {

margin: 0 0 10px;

font-size: 2rem;

color: var(--apw-green-dark);

}

.apw-intro {

margin: 0 0 24px;

color: var(--apw-muted);

font-size: 1rem;

line-height: 1.5;

}

.apw-grid {

display: grid;

grid-template-columns: 1.4fr 0.9fr;

gap: 24px;

}

.apw-left,

.apw-right {

display: grid;

gap: 18px;

}

.apw-card {

background: var(--apw-white);

border: 1px solid var(--apw-border);

border-radius: 16px;

padding: 18px 18px 14px;

box-shadow: var(--apw-shadow);

}

.apw-card h3 {

margin: 0 0 14px;

font-size: 1.1rem;

color: var(--apw-green-dark);

}

.apw-card label {

display: block;

margin: 0 0 10px;

line-height: 1.45;

cursor: pointer;

color: var(--apw-text);

}

.apw-card input[type="checkbox"] {

margin-right: 10px;

transform: scale(1.1);

accent-color: var(--apw-green);

}

.apw-actions {

display: flex;

justify-content: flex-start;

}

#apw-reset-btn {

border: none;

background: var(--apw-green);

color: #fff;

padding: 12px 18px;

border-radius: 999px;

cursor: pointer;

font-size: 0.95rem;

transition: background 0.2s ease;

}

#apw-reset-btn:hover {

background: var(--apw-green-dark);

}

.apw-results ul,

.apw-results ol {

margin: 0;

padding-left: 20px;

}

.apw-results li {

margin-bottom: 10px;

line-height: 1.45;

}

.apw-score-badge {

display: inline-block;

margin-left: 8px;

background: var(--apw-green-soft);

color: var(--apw-green-dark);

border: 1px solid var(--apw-border);

border-radius: 999px;

padding: 2px 8px;

font-size: 0.85rem;

font-weight: bold;

}

#apw-notes {

color: var(--apw-muted);

line-height: 1.6;

}

.apw-note {

margin-bottom: 12px;

padding: 10px 12px;

background: var(--apw-green-soft);

border-left: 4px solid var(--apw-green);

border-radius: 10px;

}

@media (max-width: 900px) {

.apw-grid {

grid-template-columns: 1fr;

}

}

</style>

<script>

(function () {

const patternNames = {

shaoyang: "Shaoyang Disorder / GB-SJ Obstruction",

liverYang: "Liver Yang Rising",

liverQi: "Liver Qi Stagnation",

bloodYinDef: "Liver Blood / Yin Deficiency",

dampPhlegm: "Damp / Phlegm Accumulation",

bloodStasis: "Blood Stasis",

qiDef: "Qi Deficiency / Spleen Qi Deficiency",

kidneyDef: "Kidney Deficiency",

taiyang: "Taiyang Channel Pattern",

yangming: "Yangming Channel Pattern",

shenDisturbance: "Shen Disturbance"

};

const patternNotes = {

shaoyang: "Often rises to the top when symptoms cluster around the side of the head, ear, jaw, and lateral neck.",

liverYang: "Often associated with pounding headache quality, irritability, rising tension, and eye involvement.",

liverQi: "Frequently linked with stress, jaw clenching, distending pain, and constrained movement.",

bloodYinDef: "Consider when dryness, floaters, pale complexion, fatigue, or dull empty pain are present.",

dampPhlegm: "Often suggested by heaviness, fogginess, sticky stools, and cloudy thinking.",

bloodStasis: "More likely when pain is fixed, sharp, chronic, and localized.",

qiDef: "Often appears with fatigue, bloating, poor appetite, and low overall resilience.",

kidneyDef: "Can underlie chronicity, hearing issues, low back weakness, and deeper depletion patterns.",

taiyang: "Think occiput, suboccipitals, posterior neck, and more exterior tension patterns.",

yangming: "Think frontal symptoms, face, jaw, sinus, and digestive involvement.",

shenDisturbance: "Often contributes when sleep, anxiety, agitation, or nervous system overactivation are prominent."

};

const checkboxes = document.querySelectorAll('.apw-tcm-tool input[type="checkbox"]');

const scoreList = document.getElementById('apw-score-list');

const differentialList = document.getElementById('apw-differential-list');

const notesBox = document.getElementById('apw-notes');

const resetBtn = document.getElementById('apw-reset-btn');

function calculateScores() {

const scores = {};

Object.keys(patternNames).forEach(key => scores[key] = 0);

checkboxes.forEach(box => {

if (box.checked) {

const pattern = box.dataset.pattern;

const score = parseInt(box.dataset.score, 10) || 0;

if (scores.hasOwnProperty(pattern)) {

scores[pattern] += score;

}

}

});

return scores;

}

function render() {

const scores = calculateScores();

const ranked = Object.entries(scores)

.filter(([, score]) => score > 0)

.sort((a, b) => b[1] - a[1]);

scoreList.innerHTML = '';

differentialList.innerHTML = '';

notesBox.innerHTML = '';

if (ranked.length === 0) {

scoreList.innerHTML = '<li>No symptoms selected yet.</li>';

differentialList.innerHTML = '<li>Select symptoms to generate a differential.</li>';

notesBox.innerHTML = '<div class="apw-note">This tool is educational and pattern-based. It does not replace individualized clinical assessment.</div>';

return;

}

ranked.forEach(([pattern, score]) => {

const li = document.createElement('li');

li.innerHTML = `${patternNames[pattern]} <span class="apw-score-badge">${score}</span>`;

scoreList.appendChild(li);

});

ranked.slice(0, 5).forEach(([pattern, score], index) => {

const li = document.createElement('li');

let label = patternNames[pattern];

if (index === 0) label += ' — Primary';

if (index === 1) label += ' — Secondary';

if (index === 2) label += ' — Tertiary';

li.textContent = `${label} (${score})`;

differentialList.appendChild(li);

});

ranked.slice(0, 3).forEach(([pattern]) => {

const div = document.createElement('div');

div.className = 'apw-note';

div.textContent = patternNotes[pattern];

notesBox.appendChild(div);

});

}

checkboxes.forEach(box => {

box.addEventListener('change', render);

});

resetBtn.addEventListener('click', function () {

checkboxes.forEach(box => box.checked = false);

render();

});

render();

})();

</script>