{"id":2101,"date":"2026-06-28T03:04:12","date_gmt":"2026-06-28T08:04:12","guid":{"rendered":"https:\/\/davidcelestin.com\/?page_id=2101"},"modified":"2026-06-28T17:25:16","modified_gmt":"2026-06-28T22:25:16","slug":"grade-calculator","status":"publish","type":"page","link":"https:\/\/davidcelestin.com\/en\/tools\/calculators\/grade-calculator\/","title":{"rendered":"Easy Free Grade Calculator"},"content":{"rendered":"\n<!-- ============================================================\n  Grade Calculator \u2014 v2\n  David Celestin Studiolab \u00b7 davidcelestin.com\n  Paste into a WordPress Custom HTML block.\n  Zero external dependencies \u00b7 Mobile-first \u00b7 US market\n  ============================================================ -->\n\n<!-- JSON-LD: WebApplication + FAQPage structured data -->\n<script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@graph\": [\n    {\n      \"@type\": \"WebApplication\",\n      \"name\": \"Grade Calculator\",\n      \"url\": \"https:\/\/davidcelestin.com\/en\/tools\/calculators\/grade-calculator\/\",\n      \"description\": \"Free online grade calculator for US students. Calculate weighted grades, find out what score you need on your final exam, compute a simple average, and convert letter grades to GPA \u2014 all in one tool.\",\n      \"applicationCategory\": \"EducationalApplication\",\n      \"operatingSystem\": \"Any\",\n      \"offers\": { \"@type\": \"Offer\", \"price\": \"0\", \"priceCurrency\": \"USD\" },\n      \"creator\": { \"@type\": \"Organization\", \"name\": \"David Celestin Studiolab\", \"url\": \"https:\/\/davidcelestin.com\/en\/studiolab\/\" }\n    },\n    {\n      \"@type\": \"FAQPage\",\n      \"mainEntity\": [\n        { \"@type\": \"Question\", \"name\": \"Why don't my weights add up to 100%?\", \"acceptedAnswer\": { \"@type\": \"Answer\", \"text\": \"Common causes: forgetting a category like participation, double-entering something, or confusing raw points with percentages. The warning badge tells you exactly how many percentage points you're off. The tool still shows a proportional result while you adjust.\" } },\n        { \"@type\": \"Question\", \"name\": \"What if my class uses a point system, not percentages?\", \"acceptedAnswer\": { \"@type\": \"Answer\", \"text\": \"Switch to \\\"Points\\\" format in the dropdown. Enter your earned points and the max possible per assignment \u2014 the tool converts to a percentage automatically. For example, 47\/50 = 94%.\" } },\n        { \"@type\": \"Question\", \"name\": \"Can I enter letter grades?\", \"acceptedAnswer\": { \"@type\": \"Answer\", \"text\": \"Yes. Select \\\"Letter Grade\\\" format. Conversions used: A+=97, A=93, A-=90, B+=87, B=83, B-=80, C+=77, C=73, C-=70, D+=67, D=63, D-=60, F=50.\" } },\n        { \"@type\": \"Question\", \"name\": \"Is my data saved or sent anywhere?\", \"acceptedAnswer\": { \"@type\": \"Answer\", \"text\": \"No. All calculations happen entirely in your browser. Nothing is sent to any server. Refreshing the page clears your entries.\" } },\n        { \"@type\": \"Question\", \"name\": \"What's the difference between current grade and overall grade?\", \"acceptedAnswer\": { \"@type\": \"Answer\", \"text\": \"Current grade counts only completed work (empty rows are ignored). Overall grade treats missing entries as zeros. Mid-semester, current grade is more useful for planning.\" } },\n        { \"@type\": \"Question\", \"name\": \"How is a 4.0 GPA calculated?\", \"acceptedAnswer\": { \"@type\": \"Answer\", \"text\": \"GPA is calculated across all courses weighted by credit hours. A=4.0, B=3.0, C=2.0, D=1.0, F=0.0 (\u00b10.3 for plus\/minus). Multiply each course's GPA value by its credit hours, sum them, then divide by total credit hours.\" } },\n        { \"@type\": \"Question\", \"name\": \"What score do I need on my final exam to pass?\", \"acceptedAnswer\": { \"@type\": \"Answer\", \"text\": \"Use the Final Exam tab. Enter your current grade, the weight of the final, and your desired course grade. The tool calculates the exact score needed and shows a scenario table for every possible final score from 50 to 100.\" } },\n        { \"@type\": \"Question\", \"name\": \"How do US letter grades map to percentages?\", \"acceptedAnswer\": { \"@type\": \"Answer\", \"text\": \"The most common US scale: A+ (97\u2013100%), A (93\u201396%), A- (90\u201392%), B+ (87\u201389%), B (83\u201386%), B- (80\u201382%), C+ (77\u201379%), C (73\u201376%), C- (70\u201372%), D+ (67\u201369%), D (63\u201366%), D- (60\u201362%), F (below 60%). Some institutions use a simpler A\/B\/C\/D\/F scale without plus\/minus.\" } }\n      ]\n    }\n  ]\n}\n<\/script>\n\n<style>\n\/* ============================================================\n   ALL STYLES SCOPED TO #gc-app \u2014 v2\n   Palette: #7000F4 (primary) \u00b7 #000000 (text) \u00b7 white surfaces\n   System fonts only \u2014 zero CDN dependencies\n   ============================================================ *\/\n\n#gc-app {\n  --gc-primary:       #7000F4;\n  --gc-primary-light: #9B4DFF;\n  --gc-primary-pale:  #F3EAFF;\n  --gc-primary-mid:   #E4CCFF;\n  --gc-text:          #000000;\n  --gc-muted:         #555566;\n  --gc-border:        #E2D9F3;\n  --gc-surface:       #FAFAFA;\n  --gc-success:       #16A34A;\n  --gc-warning:       #B45309;\n  --gc-danger:        #DC2626;\n  --gc-radius:        12px;\n  --gc-radius-sm:     8px;\n  --gc-radius-lg:     20px;\n  --gc-transition:    0.2s ease;\n  --gc-font-head:     'Space Grotesk', system-ui, -apple-system, 'Segoe UI', sans-serif;\n  --gc-font-body:     'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;\n\n  box-sizing: border-box;\n  background: transparent;\n  color: var(--gc-text);\n  font-family: var(--gc-font-body);\n  font-size: 16px;\n  line-height: 1.6;\n  -webkit-font-smoothing: antialiased;\n}\n#gc-app *, #gc-app *::before, #gc-app *::after { box-sizing: border-box; margin: 0; padding: 0; }\n\n\/* ---- LAYOUT ---- *\/\n#gc-app .gc-wrap { max-width: 880px; margin: 0 auto; padding: 0 16px 64px; }\n\n\/* ---- HERO ---- *\/\n#gc-app .gc-hero { text-align: center; padding: 40px 16px 32px; }\n#gc-app .gc-eyebrow {\n  display: inline-flex; align-items: center; gap: 7px;\n  background: var(--gc-primary-pale); border: 1px solid var(--gc-primary-mid);\n  color: var(--gc-primary); font-family: var(--gc-font-head);\n  font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;\n  padding: 5px 14px; border-radius: 100px; margin-bottom: 18px;\n}\n#gc-app .gc-eyebrow::before {\n  content: ''; width: 6px; height: 6px; border-radius: 50%;\n  background: var(--gc-primary); animation: gc-pulse 2s ease-in-out infinite;\n}\n@keyframes gc-pulse { 0%,100%{opacity:1;transform:scale(1)} 50%{opacity:.4;transform:scale(.7)} }\n\n#gc-app h1.gc-h1 {\n  font-family: var(--gc-font-head); font-size: clamp(26px,5vw,46px);\n  font-weight: 700; line-height: 1.1; letter-spacing: -.02em;\n  margin-bottom: 12px; color: var(--gc-text);\n}\n#gc-app .gc-hero-sub {\n  font-size: clamp(14px,2.2vw,17px); color: var(--gc-muted);\n  max-width: 540px; margin: 0 auto;\n}\n\n\/* ---- TABS ---- *\/\n#gc-app .gc-tabs {\n  display: grid;\n  grid-template-columns: repeat(4, 1fr);\n  background: var(--gc-surface);\n  border: 1px solid var(--gc-border);\n  border-radius: var(--gc-radius-lg);\n  padding: 4px;\n  gap: 4px;\n  margin-bottom: 24px;\n}\n#gc-app .gc-tab {\n  padding: 10px 8px;\n  border-radius: 12px;\n  border: none;\n  background: transparent;\n  color: var(--gc-muted);\n  font-family: var(--gc-font-body);\n  font-size: 12px;\n  font-weight: 500;\n  cursor: pointer;\n  transition: var(--gc-transition);\n  text-align: center;\n  line-height: 1.3;\n  min-height: 44px;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  gap: 3px;\n  -webkit-tap-highlight-color: transparent;\n  touch-action: manipulation;\n}\n#gc-app .gc-tab:hover { color: var(--gc-primary); }\n#gc-app .gc-tab.active {\n  background: var(--gc-primary);\n  color: #fff;\n  box-shadow: 0 2px 10px rgba(112,0,244,.28);\n}\n\n\/* ---- PANELS ---- *\/\n#gc-app .gc-panel { display: none; }\n#gc-app .gc-panel.active { display: block; animation: gc-fadeup .22s ease; }\n@keyframes gc-fadeup { from{opacity:0;transform:translateY(8px)} to{opacity:1;transform:none} }\n\n\/* ---- CARD ---- *\/\n#gc-app .gc-card {\n  background: #fff; border: 1px solid var(--gc-border);\n  border-radius: var(--gc-radius-lg); padding: 22px; margin-bottom: 16px;\n}\n#gc-app .gc-card-hdr {\n  display: flex; align-items: flex-start; justify-content: space-between;\n  gap: 10px; margin-bottom: 20px; flex-wrap: wrap;\n}\n#gc-app .gc-card-title {\n  font-family: var(--gc-font-head); font-size: 15px; font-weight: 600;\n  color: var(--gc-text); display: flex; align-items: center; gap: 7px;\n}\n\n\/* ---- ARC ---- *\/\n#gc-app .gc-arc-wrap { display: flex; justify-content: center; margin-bottom: 22px; }\n#gc-app .gc-arc-box { position: relative; width: 160px; height: 160px; flex-shrink: 0; }\n#gc-app .gc-arc-svg { width: 160px; height: 160px; transform: rotate(-90deg); }\n#gc-app .gc-arc-track { fill: none; stroke: var(--gc-border); stroke-width: 10; }\n#gc-app .gc-arc-fill {\n  fill: none; stroke-width: 10; stroke-linecap: round;\n  stroke-dasharray: 502; stroke-dashoffset: 502;\n  transition: stroke-dashoffset .8s cubic-bezier(.34,1.56,.64,1);\n}\n#gc-app .gc-arc-txt {\n  position: absolute; top: 50%; left: 50%;\n  transform: translate(-50%,-50%); text-align: center; pointer-events: none;\n}\n#gc-app .gc-arc-pct {\n  font-family: var(--gc-font-head); font-size: 30px; font-weight: 700;\n  color: var(--gc-text); line-height: 1;\n}\n#gc-app .gc-arc-ltr {\n  font-family: var(--gc-font-head); font-size: 16px; font-weight: 700;\n  color: var(--gc-primary); margin-top: 4px;\n}\n\n\/* ---- STATS ---- *\/\n#gc-app .gc-stats {\n  display: grid; grid-template-columns: repeat(4,1fr); gap: 10px; margin-bottom: 16px;\n}\n#gc-app .gc-stat {\n  background: var(--gc-surface); border: 1px solid var(--gc-border);\n  border-radius: var(--gc-radius); padding: 12px 10px; text-align: center;\n}\n#gc-app .gc-stat-val {\n  font-family: var(--gc-font-head); font-size: 18px; font-weight: 700;\n  color: var(--gc-text); margin-bottom: 2px;\n}\n#gc-app .gc-stat-lbl {\n  font-size: 10px; color: var(--gc-muted); font-weight: 600;\n  text-transform: uppercase; letter-spacing: .06em;\n}\n\n\/* ---- WEIGHT BADGE ---- *\/\n#gc-app .gc-wbadge {\n  display: flex; align-items: center; gap: 8px; padding: 8px 12px;\n  border-radius: var(--gc-radius); font-size: 12px; font-weight: 500;\n  transition: var(--gc-transition);\n}\n#gc-app .gc-wbadge.ok    { background:#F0FDF4; color:var(--gc-success); border:1px solid #BBF7D0; }\n#gc-app .gc-wbadge.warn  { background:#FFFBEB; color:var(--gc-warning); border:1px solid #FDE68A; }\n#gc-app .gc-wbadge.error { background:#FEF2F2; color:var(--gc-danger);  border:1px solid #FECACA; }\n\n\/* ---- TABLE ---- *\/\n#gc-app .gc-tbl-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }\n#gc-app .gc-tbl { width: 100%; border-collapse: collapse; min-width: 440px; }\n#gc-app .gc-tbl th {\n  font-size: 10px; font-weight: 700; color: var(--gc-muted); text-transform: uppercase;\n  letter-spacing: .07em; text-align: left; padding: 7px 8px;\n  border-bottom: 2px solid var(--gc-border);\n}\n#gc-app .gc-tbl td { padding: 7px 5px; border-bottom: 1px solid var(--gc-border); vertical-align: middle; }\n#gc-app .gc-tbl tr:last-child td { border-bottom: none; }\n\n\/* ---- INPUT \/ SELECT ---- *\/\n#gc-app .gc-inp {\n  width: 100%; background: #fff; border: 1px solid var(--gc-border);\n  border-radius: var(--gc-radius-sm); padding: 8px 10px; color: var(--gc-text);\n  font-family: var(--gc-font-body); font-size: 13px;\n  transition: border-color var(--gc-transition), box-shadow var(--gc-transition);\n  -webkit-appearance: none; appearance: none; outline: none;\n}\n#gc-app .gc-inp:focus { border-color: var(--gc-primary); box-shadow: 0 0 0 3px rgba(112,0,244,.12); }\n#gc-app .gc-inp::placeholder { color: #AAAABC; }\n#gc-app .gc-inp-name { background: var(--gc-surface); }\n#gc-app .gc-sel {\n  width: 100%; background: #fff; border: 1px solid var(--gc-border);\n  border-radius: var(--gc-radius-sm); padding: 8px 28px 8px 10px; color: var(--gc-text);\n  font-family: var(--gc-font-body); font-size: 13px; cursor: pointer;\n  -webkit-appearance: none; appearance: none; outline: none;\n  background-image: url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23555566' d='M1 1l5 5 5-5'\/%3E%3C\/svg%3E\");\n  background-repeat: no-repeat; background-position: right 10px center;\n}\n#gc-app .gc-sel:focus { border-color: var(--gc-primary); box-shadow: 0 0 0 3px rgba(112,0,244,.12); }\n\n\/* ---- BUTTONS ---- *\/\n#gc-app .gc-btn {\n  display: inline-flex; align-items: center; gap: 5px; padding: 8px 14px;\n  border-radius: var(--gc-radius); border: none; font-family: var(--gc-font-body);\n  font-size: 13px; font-weight: 600; cursor: pointer; transition: var(--gc-transition); line-height: 1;\n}\n#gc-app .gc-btn-ghost {\n  background: var(--gc-surface); color: var(--gc-muted); border: 1px solid var(--gc-border);\n}\n#gc-app .gc-btn-ghost:hover { color: var(--gc-primary); border-color: var(--gc-primary-mid); background: var(--gc-primary-pale); }\n#gc-app .gc-btn-primary {\n  background: var(--gc-primary); color: #fff;\n  box-shadow: 0 2px 8px rgba(112,0,244,.25);\n}\n#gc-app .gc-btn-primary:hover { background: var(--gc-primary-light); }\n#gc-app .gc-btn-del {\n  background: #FEF2F2; color: var(--gc-danger); border: 1px solid #FECACA;\n  padding: 5px 9px; font-size: 12px; border-radius: 8px; cursor: pointer;\n  font-family: var(--gc-font-body); font-weight: 600; transition: var(--gc-transition); line-height: 1;\n}\n#gc-app .gc-btn-del:hover { background: #FEE2E2; }\n#gc-app .gc-btn-row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }\n\n\/* ---- ALERTS ---- *\/\n#gc-app .gc-alert {\n  padding: 12px 16px; border-radius: var(--gc-radius); font-size: 14px; font-weight: 500;\n  display: flex; align-items: flex-start; gap: 10px; margin-top: 14px;\n}\n#gc-app .gc-alert.success { background:#F0FDF4; border:1px solid #BBF7D0; color:var(--gc-success); }\n#gc-app .gc-alert.info    { background:var(--gc-primary-pale); border:1px solid var(--gc-primary-mid); color:var(--gc-primary); }\n#gc-app .gc-alert.danger  { background:#FEF2F2; border:1px solid #FECACA; color:var(--gc-danger); }\n\n\/* ---- FORM GRID ---- *\/\n#gc-app .gc-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }\n#gc-app .gc-field label { display: block; font-size: 12px; font-weight: 600; color: var(--gc-text); margin-bottom: 5px; }\n#gc-app .gc-field .hint { font-size: 11px; color: var(--gc-muted); margin-top: 3px; }\n\n\/* ---- DIVIDER ---- *\/\n#gc-app .gc-hr { border: none; border-top: 1px solid var(--gc-border); margin: 18px 0; }\n\n\/* ---- SCALE PILLS ---- *\/\n#gc-app .gc-pills { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 10px; }\n#gc-app .gc-pill {\n  padding: 3px 9px; border-radius: 100px; font-family: var(--gc-font-head);\n  font-size: 11px; font-weight: 700; border: 1px solid;\n}\n\n\/* ---- CONTRIBUTION BADGE ---- *\/\n#gc-app .gc-ctb { display: inline-block; padding: 2px 7px; border-radius: 100px; font-size: 11px; font-weight: 600; }\n#gc-app .gc-ctb.high { background:rgba(112,0,244,.12); color:var(--gc-primary); }\n#gc-app .gc-ctb.med  { background:rgba(112,0,244,.07); color:var(--gc-primary-light); }\n#gc-app .gc-ctb.low  { background:var(--gc-surface); color:var(--gc-muted); border:1px solid var(--gc-border); }\n\n\/* ---- HOW IT WORKS ---- *\/\n#gc-app .gc-how { display: grid; grid-template-columns: repeat(4,1fr); gap: 12px; margin: 20px 0 36px; }\n#gc-app .gc-how-step {\n  background: #fff; border: 1px solid var(--gc-border); border-radius: var(--gc-radius);\n  padding: 18px; border-top: 3px solid var(--gc-primary);\n}\n#gc-app .gc-how-n { font-family: var(--gc-font-head); font-size: 26px; font-weight: 700; color: var(--gc-primary); line-height: 1; margin-bottom: 8px; }\n#gc-app .gc-how-t { font-size: 13px; font-weight: 600; color: var(--gc-text); margin-bottom: 4px; }\n#gc-app .gc-how-d { font-size: 12px; color: var(--gc-muted); line-height: 1.55; }\n\n\/* ---- CONTENT CARD ---- *\/\n#gc-app .gc-content {\n  background: #fff; border: 1px solid var(--gc-border);\n  border-radius: var(--gc-radius-lg); padding: 24px; margin-bottom: 24px;\n}\n#gc-app .gc-content h2 { font-family: var(--gc-font-head); font-size: 17px; font-weight: 700; margin-bottom: 10px; color: var(--gc-text); }\n#gc-app .gc-content h3 { font-family: var(--gc-font-head); font-size: 14px; font-weight: 700; margin: 16px 0 6px; color: var(--gc-text); }\n#gc-app .gc-content p { font-size: 14px; color: var(--gc-muted); line-height: 1.75; margin-bottom: 10px; }\n#gc-app .gc-content ul { padding-left: 18px; margin-bottom: 10px; }\n#gc-app .gc-content li { font-size: 14px; color: var(--gc-muted); line-height: 1.7; margin-bottom: 3px; }\n#gc-app .gc-content a { color: var(--gc-primary); text-decoration: none; }\n#gc-app .gc-content a:hover { text-decoration: underline; }\n\n\/* ---- SECTION HEAD ---- *\/\n#gc-app .gc-sec-h { font-family: var(--gc-font-head); font-size: 20px; font-weight: 700; color: var(--gc-text); margin-bottom: 6px; text-align: center; }\n#gc-app .gc-sec-s { font-size: 14px; color: var(--gc-muted); text-align: center; margin-bottom: 20px; }\n\n\/* ---- FAQ ---- *\/\n#gc-app .gc-faq { margin-bottom: 36px; }\n#gc-app .gc-faq-item { border-bottom: 1px solid var(--gc-border); }\n#gc-app .gc-faq-q {\n  width: 100%; background: transparent; border: none; color: var(--gc-text);\n  font-family: var(--gc-font-body); font-size: 14px; font-weight: 500; text-align: left;\n  padding: 14px 0; cursor: pointer; display: flex; align-items: center;\n  justify-content: space-between; gap: 10px;\n}\n#gc-app .gc-faq-q:hover { color: var(--gc-primary); }\n#gc-app .gc-faq-ico { font-size: 18px; color: var(--gc-primary); flex-shrink: 0; transition: transform var(--gc-transition); }\n#gc-app .gc-faq-item.open .gc-faq-ico { transform: rotate(45deg); }\n#gc-app .gc-faq-a {\n  font-size: 13px; color: var(--gc-muted); line-height: 1.7;\n  max-height: 0; overflow: hidden;\n  transition: max-height .35s ease, padding .2s ease;\n}\n#gc-app .gc-faq-item.open .gc-faq-a { max-height: 400px; padding-bottom: 14px; }\n\n\/* ---- FORMULA BOX ---- *\/\n#gc-app .gc-formula {\n  background: var(--gc-primary-pale); border: 1px solid var(--gc-primary-mid);\n  border-radius: var(--gc-radius); padding: 14px 16px;\n}\n#gc-app .gc-formula-t { font-size: 13px; font-weight: 600; color: var(--gc-text); margin-bottom: 6px; }\n#gc-app .gc-formula-b { font-size: 12px; color: var(--gc-muted); line-height: 1.7; }\n#gc-app .gc-formula-hl { color: var(--gc-primary); font-weight: 600; }\n\n\/* ---- RELATED TOOLS ---- *\/\n#gc-app .gc-related {\n  background: var(--gc-primary-pale); border: 1px solid var(--gc-primary-mid);\n  border-radius: var(--gc-radius-lg); padding: 22px; margin-bottom: 28px;\n}\n#gc-app .gc-related h2 { font-family: var(--gc-font-head); font-size: 15px; font-weight: 700; color: var(--gc-text); margin-bottom: 14px; }\n#gc-app .gc-related-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 10px; }\n#gc-app .gc-rel-item {\n  background: #fff; border: 1px solid var(--gc-border); border-radius: var(--gc-radius);\n  padding: 14px; text-decoration: none; display: block;\n  transition: border-color var(--gc-transition), box-shadow var(--gc-transition);\n}\n#gc-app .gc-rel-item:hover { border-color: var(--gc-primary); box-shadow: 0 2px 10px rgba(112,0,244,.12); }\n#gc-app .gc-rel-icon { font-size: 20px; margin-bottom: 6px; }\n#gc-app .gc-rel-name { font-size: 13px; font-weight: 600; color: var(--gc-text); margin-bottom: 2px; }\n#gc-app .gc-rel-desc { font-size: 11px; color: var(--gc-muted); line-height: 1.45; }\n\n\/* ---- GPA TABLE ---- *\/\n#gc-app .gc-gpa-courses { width: 100%; }\n#gc-app .gc-gpa-total {\n  background: var(--gc-primary-pale); border: 1px solid var(--gc-primary-mid);\n  border-radius: var(--gc-radius); padding: 16px 20px; margin-top: 16px;\n  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px;\n}\n#gc-app .gc-gpa-result-label { font-size: 13px; color: var(--gc-muted); font-weight: 500; }\n#gc-app .gc-gpa-result-val { font-family: var(--gc-font-head); font-size: 32px; font-weight: 700; color: var(--gc-primary); }\n#gc-app .gc-gpa-letter { font-family: var(--gc-font-head); font-size: 18px; font-weight: 700; color: var(--gc-text); margin-left: 8px; }\n\n\/* ---- DISCLAIMER ---- *\/\n#gc-app .gc-disclaimer {\n  font-size: 11px; color: var(--gc-muted); text-align: center;\n  padding: 10px 16px; border-top: 1px solid var(--gc-border); margin-top: 8px;\n}\n\n\/* ---- FOOTER ---- *\/\n#gc-app .gc-footer {\n  text-align: center; font-size: 12px; color: var(--gc-muted);\n  margin-top: 28px; padding-top: 18px; border-top: 1px solid var(--gc-border);\n}\n#gc-app .gc-footer a { color: var(--gc-primary); text-decoration: none; }\n#gc-app .gc-footer a:hover { text-decoration: underline; }\n\n\/* ---- UTILITY ---- *\/\n#gc-app .gc-hidden    { display: none !important; }\n#gc-app .gc-t-muted   { color: var(--gc-muted); }\n#gc-app .gc-t-ok      { color: var(--gc-success); }\n#gc-app .gc-t-danger  { color: var(--gc-danger); }\n#gc-app .gc-t-primary { color: var(--gc-primary); }\n\n\/* ---- RESPONSIVE ---- *\/\n@media (max-width: 680px) {\n  #gc-app .gc-stats        { grid-template-columns: repeat(2,1fr); }\n  #gc-app .gc-how          { grid-template-columns: repeat(2,1fr); }\n  #gc-app .gc-grid2        { grid-template-columns: 1fr; }\n  #gc-app .gc-card         { padding: 16px 12px; }\n  #gc-app .gc-tabs         { grid-template-columns: repeat(2,1fr); }\n  #gc-app .gc-tab          { font-size: 12px; padding: 10px 8px; }\n  #gc-app .gc-related-grid { grid-template-columns: 1fr 1fr; }\n}\n@media (max-width: 420px) {\n  #gc-app .gc-how          { grid-template-columns: 1fr; }\n  #gc-app .gc-related-grid { grid-template-columns: 1fr; }\n  #gc-app .gc-gpa-total    { flex-direction: column; text-align: center; }\n  #gc-app .gc-tab          { font-size: 11.5px; }\n}\n@media (prefers-reduced-motion: reduce) {\n  #gc-app *, #gc-app *::before, #gc-app *::after {\n    transition-duration: 0s !important; animation-duration: 0s !important;\n  }\n}\n<\/style>\n\n<!-- ===== TOOL ROOT ===== -->\n<div id=\"gc-app\">\n<div class=\"gc-wrap\">\n\n  <!-- HERO -->\n  <header class=\"gc-hero\">\n    <div class=\"gc-eyebrow\">Free Online Tool<\/div>\n    <h1 class=\"gc-h1\">Grade Calculator<\/h1>\n    <p class=\"gc-hero-sub\">Know exactly where you stand \u2014 and what you need. Weighted grades, final exam targets, simple averages, and GPA conversion in one place. No signup. No data stored.<\/p>\n  <\/header>\n\n  <!-- TABS -->\n  <nav aria-label=\"Calculator tabs\">\n    <div class=\"gc-tabs\" role=\"tablist\">\n      <button class=\"gc-tab active\" role=\"tab\" aria-selected=\"true\"  onclick=\"gcTab('weighted')\"><span style=\"font-size:16px\">\ud83d\udcca<\/span><span>Weighted Grade<\/span><\/button>\n      <button class=\"gc-tab\"        role=\"tab\" aria-selected=\"false\" onclick=\"gcTab('final')\"><span style=\"font-size:16px\">\ud83c\udfaf<\/span><span>Final Exam<\/span><\/button>\n      <button class=\"gc-tab\"        role=\"tab\" aria-selected=\"false\" onclick=\"gcTab('simple')\"><span style=\"font-size:16px\">\u2797<\/span><span>Simple Average<\/span><\/button>\n      <button class=\"gc-tab\"        role=\"tab\" aria-selected=\"false\" onclick=\"gcTab('gpa')\"><span style=\"font-size:16px\">\ud83c\udf93<\/span><span>GPA Calculator<\/span><\/button>\n    <\/div>\n  <\/nav>\n\n  <!-- ===== PANEL 1: WEIGHTED ===== -->\n  <div id=\"gc-panel-weighted\" class=\"gc-panel active\" role=\"tabpanel\">\n\n    <div class=\"gc-card\">\n      <div class=\"gc-card-hdr\">\n        <div class=\"gc-card-title\">\ud83d\udcca Your Current Grade<\/div>\n        <div id=\"gc-w-badge\" class=\"gc-wbadge warn\">\n          <span id=\"gc-w-bico\">\u26a0\ufe0f<\/span>\n          <span id=\"gc-w-bmsg\">Weights total <strong id=\"gc-w-bsum\">0<\/strong>% \u2014 should add to 100%<\/span>\n        <\/div>\n      <\/div>\n\n      <div class=\"gc-arc-wrap\">\n        <div class=\"gc-arc-box\">\n          <svg class=\"gc-arc-svg\" viewBox=\"0 0 180 180\" aria-hidden=\"true\">\n            <defs>\n              <linearGradient id=\"gc-ag1\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n                <stop offset=\"0%\" stop-color=\"#7000F4\"\/>\n                <stop offset=\"100%\" stop-color=\"#9B4DFF\"\/>\n              <\/linearGradient>\n            <\/defs>\n            <circle class=\"gc-arc-track\" cx=\"90\" cy=\"90\" r=\"80\"\/>\n            <circle class=\"gc-arc-fill\" id=\"gc-w-arc\" style=\"stroke:url(#gc-ag1)\" cx=\"90\" cy=\"90\" r=\"80\"\/>\n          <\/svg>\n          <div class=\"gc-arc-txt\">\n            <div class=\"gc-arc-pct\" id=\"gc-w-pct\">\u2014<\/div>\n            <div class=\"gc-arc-ltr\" id=\"gc-w-ltr\">\u2013<\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n\n      <div class=\"gc-stats\">\n        <div class=\"gc-stat\"><div class=\"gc-stat-val\" id=\"gc-w-hi\">\u2014<\/div><div class=\"gc-stat-lbl\">Highest<\/div><\/div>\n        <div class=\"gc-stat\"><div class=\"gc-stat-val\" id=\"gc-w-lo\">\u2014<\/div><div class=\"gc-stat-lbl\">Lowest<\/div><\/div>\n        <div class=\"gc-stat\"><div class=\"gc-stat-val\" id=\"gc-w-ct\">0<\/div><div class=\"gc-stat-lbl\">Entries<\/div><\/div>\n        <div class=\"gc-stat\"><div class=\"gc-stat-val\" id=\"gc-w-st\">\u2014<\/div><div class=\"gc-stat-lbl\">Status<\/div><\/div>\n      <\/div>\n      <div id=\"gc-w-tgtresult\" class=\"gc-hidden\"><\/div>\n    <\/div>\n\n    <div class=\"gc-card\">\n      <div class=\"gc-card-hdr\">\n        <div class=\"gc-card-title\">\ud83d\udcdd Assignments &amp; Categories<\/div>\n        <div style=\"display:flex;align-items:center;gap:8px;flex-wrap:wrap\">\n          <label style=\"font-size:12px;color:var(--gc-muted);font-weight:500\">Format:<\/label>\n          <select class=\"gc-sel\" id=\"gc-w-fmt\" onchange=\"gcRenderW()\" style=\"width:auto;min-width:130px\">\n            <option value=\"percent\">Percentage (%)<\/option>\n            <option value=\"points\">Points (e.g. 85\/100)<\/option>\n            <option value=\"letter\">Letter Grade<\/option>\n          <\/select>\n        <\/div>\n      <\/div>\n\n      <div class=\"gc-tbl-wrap\">\n        <table class=\"gc-tbl\" aria-label=\"Grade entries\">\n          <thead><tr>\n            <th style=\"min-width:110px\">Assignment<\/th>\n            <th style=\"min-width:110px\">Score<\/th>\n            <th style=\"min-width:80px\">Weight %<\/th>\n            <th style=\"min-width:90px\">Contribution<\/th>\n            <th style=\"width:36px\"><\/th>\n          <\/tr><\/thead>\n          <tbody id=\"gc-w-body\"><\/tbody>\n        <\/table>\n      <\/div>\n\n      <div class=\"gc-btn-row\">\n        <button class=\"gc-btn gc-btn-ghost\" onclick=\"gcWAdd()\">+ Add Row<\/button>\n        <button class=\"gc-btn gc-btn-ghost\" onclick=\"gcWReset()\">Reset<\/button>\n      <\/div>\n\n      <div class=\"gc-hr\"><\/div>\n      <div style=\"display:flex;gap:12px;flex-wrap:wrap;align-items:flex-end\">\n        <div class=\"gc-field\" style=\"flex:1;min-width:130px\">\n          <label for=\"gc-w-tgt\">Target Grade (%)<\/label>\n          <input type=\"number\" class=\"gc-inp\" id=\"gc-w-tgt\" placeholder=\"e.g. 90\" min=\"0\" max=\"100\" oninput=\"gcWCalc()\">\n          <div class=\"hint\">Leave blank to skip<\/div>\n        <\/div>\n        <div class=\"gc-field\" style=\"flex:2;min-width:180px\">\n          <label for=\"gc-w-scale\">Grade Scale<\/label>\n          <select class=\"gc-sel\" id=\"gc-w-scale\" onchange=\"gcWCalc()\">\n            <option value=\"plus\">US Standard (A+ \/ A \/ A-)<\/option>\n            <option value=\"simple\">Simple (A \/ B \/ C \/ D \/ F)<\/option>\n            <option value=\"pct\">Percentage Only<\/option>\n          <\/select>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <div class=\"gc-card\">\n      <div class=\"gc-card-title\" style=\"margin-bottom:10px\">\ud83c\udf93 Grade Scale Reference<\/div>\n      <div class=\"gc-pills\" id=\"gc-w-pills\"><\/div>\n    <\/div>\n\n  <\/div><!-- \/panel-weighted -->\n\n  <!-- ===== PANEL 2: FINAL EXAM ===== -->\n  <div id=\"gc-panel-final\" class=\"gc-panel\" role=\"tabpanel\">\n    <div class=\"gc-card\">\n      <div class=\"gc-card-title\" style=\"margin-bottom:18px\">\ud83c\udfaf What Score Do I Need on My Final Exam?<\/div>\n      <div class=\"gc-grid2\">\n        <div class=\"gc-field\">\n          <label for=\"gc-f-cur\">Current Grade (%)<\/label>\n          <input type=\"number\" class=\"gc-inp\" id=\"gc-f-cur\" placeholder=\"e.g. 84\" min=\"0\" max=\"100\" oninput=\"gcFCalc()\">\n          <div class=\"hint\">Your grade before the final<\/div>\n        <\/div>\n        <div class=\"gc-field\">\n          <label for=\"gc-f-wt\">Final Exam Weight (%)<\/label>\n          <input type=\"number\" class=\"gc-inp\" id=\"gc-f-wt\" placeholder=\"e.g. 30\" min=\"1\" max=\"100\" oninput=\"gcFCalc()\">\n          <div class=\"hint\">How much the final counts<\/div>\n        <\/div>\n        <div class=\"gc-field\">\n          <label for=\"gc-f-des\">Desired Course Grade (%)<\/label>\n          <input type=\"number\" class=\"gc-inp\" id=\"gc-f-des\" placeholder=\"e.g. 90\" min=\"0\" max=\"100\" oninput=\"gcFCalc()\">\n          <div class=\"hint\">The grade you want overall<\/div>\n        <\/div>\n        <div class=\"gc-field\">\n          <label for=\"gc-f-ex\">Extra Credit Available (%)<\/label>\n          <input type=\"number\" class=\"gc-inp\" id=\"gc-f-ex\" placeholder=\"0\" min=\"0\" max=\"20\" oninput=\"gcFCalc()\">\n          <div class=\"hint\">Optional \u2014 leave blank if none<\/div>\n        <\/div>\n      <\/div>\n      <div id=\"gc-f-result\" class=\"gc-hidden\"><\/div>\n      <div class=\"gc-hr\"><\/div>\n      <div class=\"gc-formula\">\n        <div class=\"gc-formula-t\">\ud83d\udcd0 The Formula<\/div>\n        <div class=\"gc-formula-b\">Required Score = <span class=\"gc-formula-hl\">(Desired \u2212 Current \u00d7 (1 \u2212 Final Weight))<\/span> \u00f7 Final Weight<\/div>\n      <\/div>\n      <div class=\"gc-disclaimer\">This tool provides estimates only and does not constitute academic advice. Verify weight calculations with your course syllabus.<\/div>\n    <\/div>\n\n    <div class=\"gc-card\">\n      <div class=\"gc-card-title\" style=\"margin-bottom:12px\">\ud83d\udd2e Scenario Planner<\/div>\n      <p style=\"font-size:13px;color:var(--gc-muted);margin-bottom:12px\">See what every possible final exam score does to your overall grade \u2014 so you can plan realistically.<\/p>\n      <div class=\"gc-tbl-wrap\">\n        <table class=\"gc-tbl\" aria-label=\"Final exam scenarios\">\n          <thead><tr><th>Final Score<\/th><th>Course Grade<\/th><th>Letter<\/th><th>Verdict<\/th><\/tr><\/thead>\n          <tbody id=\"gc-f-rows\"><tr><td colspan=\"4\" style=\"color:var(--gc-muted);font-size:12px;padding:10px 8px\">Fill in the three required fields above to see results.<\/td><\/tr><\/tbody>\n        <\/table>\n      <\/div>\n    <\/div>\n  <\/div><!-- \/panel-final -->\n\n  <!-- ===== PANEL 3: SIMPLE ===== -->\n  <div id=\"gc-panel-simple\" class=\"gc-panel\" role=\"tabpanel\">\n    <div class=\"gc-card\">\n      <div class=\"gc-card-title\" style=\"margin-bottom:6px\">\u2797 Simple Grade Average<\/div>\n      <p style=\"font-size:13px;color:var(--gc-muted);margin-bottom:18px\">No weights \u2014 just a straight average of all scores you enter. Perfect for quick checks.<\/p>\n\n      <div class=\"gc-arc-wrap\">\n        <div class=\"gc-arc-box\">\n          <svg class=\"gc-arc-svg\" viewBox=\"0 0 180 180\" aria-hidden=\"true\">\n            <defs>\n              <linearGradient id=\"gc-ag2\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n                <stop offset=\"0%\" stop-color=\"#7000F4\"\/>\n                <stop offset=\"100%\" stop-color=\"#9B4DFF\"\/>\n              <\/linearGradient>\n            <\/defs>\n            <circle class=\"gc-arc-track\" cx=\"90\" cy=\"90\" r=\"80\"\/>\n            <circle class=\"gc-arc-fill\" id=\"gc-s-arc\" style=\"stroke:url(#gc-ag2)\" cx=\"90\" cy=\"90\" r=\"80\"\/>\n          <\/svg>\n          <div class=\"gc-arc-txt\">\n            <div class=\"gc-arc-pct\" id=\"gc-s-pct\">\u2014<\/div>\n            <div class=\"gc-arc-ltr\" id=\"gc-s-ltr\">\u2013<\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n\n      <div class=\"gc-tbl-wrap\">\n        <table class=\"gc-tbl\" aria-label=\"Simple average entries\">\n          <thead><tr><th>Assignment<\/th><th>Score (0\u2013100)<\/th><th><\/th><\/tr><\/thead>\n          <tbody id=\"gc-s-body\"><\/tbody>\n        <\/table>\n      <\/div>\n      <div class=\"gc-btn-row\">\n        <button class=\"gc-btn gc-btn-ghost\" onclick=\"gcSAdd()\">+ Add Score<\/button>\n        <button class=\"gc-btn gc-btn-ghost\" onclick=\"gcSReset()\">Reset<\/button>\n      <\/div>\n    <\/div>\n  <\/div><!-- \/panel-simple -->\n\n  <!-- ===== PANEL 4: GPA ===== -->\n  <div id=\"gc-panel-gpa\" class=\"gc-panel\" role=\"tabpanel\">\n    <div class=\"gc-card\">\n      <div class=\"gc-card-title\" style=\"margin-bottom:6px\">\ud83c\udf93 GPA Calculator<\/div>\n      <p style=\"font-size:13px;color:var(--gc-muted);margin-bottom:18px\">Enter each course, its letter grade, and credit hours. Your cumulative GPA updates instantly.<\/p>\n\n      <div class=\"gc-tbl-wrap\">\n        <table class=\"gc-tbl gc-gpa-courses\" aria-label=\"GPA course entries\">\n          <thead><tr>\n            <th style=\"min-width:120px\">Course Name<\/th>\n            <th style=\"min-width:100px\">Letter Grade<\/th>\n            <th style=\"min-width:90px\">Credit Hours<\/th>\n            <th style=\"min-width:80px\">Grade Points<\/th>\n            <th style=\"width:36px\"><\/th>\n          <\/tr><\/thead>\n          <tbody id=\"gc-g-body\"><\/tbody>\n        <\/table>\n      <\/div>\n\n      <div class=\"gc-btn-row\">\n        <button class=\"gc-btn gc-btn-ghost\" onclick=\"gcGAdd()\">+ Add Course<\/button>\n        <button class=\"gc-btn gc-btn-ghost\" onclick=\"gcGReset()\">Reset<\/button>\n      <\/div>\n\n      <div class=\"gc-gpa-total\">\n        <div>\n          <div class=\"gc-gpa-result-label\">Cumulative GPA<\/div>\n          <div>\n            <span class=\"gc-gpa-result-val\" id=\"gc-g-gpa\">\u2014<\/span>\n            <span class=\"gc-gpa-letter\" id=\"gc-g-ltr\"><\/span>\n          <\/div>\n          <div style=\"font-size:11px;color:var(--gc-muted);margin-top:4px\">\n            <span id=\"gc-g-cred\">0<\/span> total credit hours \u00b7\n            <span id=\"gc-g-pts\">0.00<\/span> quality points\n          <\/div>\n        <\/div>\n        <div id=\"gc-g-status\" style=\"font-size:13px;font-weight:600;\"><\/div>\n      <\/div>\n      <div class=\"gc-disclaimer\">GPA scales vary by institution. This tool uses the standard 4.0 US scale. Always verify with your registrar.<\/div>\n    <\/div>\n\n    <div class=\"gc-card\">\n      <div class=\"gc-card-title\" style=\"margin-bottom:12px\">\ud83d\udcd6 GPA Scale Reference<\/div>\n      <div class=\"gc-tbl-wrap\">\n        <table class=\"gc-tbl\" aria-label=\"GPA scale\">\n          <thead><tr><th>Letter<\/th><th>% Range<\/th><th>GPA Points<\/th><th>Description<\/th><\/tr><\/thead>\n          <tbody>\n            <tr><td style=\"font-weight:700;color:#7000F4\">A+<\/td><td>97\u2013100%<\/td><td style=\"font-weight:600\">4.0<\/td><td style=\"color:var(--gc-muted)\">Exceptional<\/td><\/tr>\n            <tr><td style=\"font-weight:700;color:#7000F4\">A<\/td><td>93\u201396%<\/td><td style=\"font-weight:600\">4.0<\/td><td style=\"color:var(--gc-muted)\">Excellent<\/td><\/tr>\n            <tr><td style=\"font-weight:700;color:#7000F4\">A\u2212<\/td><td>90\u201392%<\/td><td style=\"font-weight:600\">3.7<\/td><td style=\"color:var(--gc-muted)\">Excellent<\/td><\/tr>\n            <tr><td style=\"font-weight:700;color:#1D4ED8\">B+<\/td><td>87\u201389%<\/td><td style=\"font-weight:600\">3.3<\/td><td style=\"color:var(--gc-muted)\">Very good<\/td><\/tr>\n            <tr><td style=\"font-weight:700;color:#1D4ED8\">B<\/td><td>83\u201386%<\/td><td style=\"font-weight:600\">3.0<\/td><td style=\"color:var(--gc-muted)\">Good<\/td><\/tr>\n            <tr><td style=\"font-weight:700;color:#1D4ED8\">B\u2212<\/td><td>80\u201382%<\/td><td style=\"font-weight:600\">2.7<\/td><td style=\"color:var(--gc-muted)\">Good<\/td><\/tr>\n            <tr><td style=\"font-weight:700;color:#B45309\">C+<\/td><td>77\u201379%<\/td><td style=\"font-weight:600\">2.3<\/td><td style=\"color:var(--gc-muted)\">Average<\/td><\/tr>\n            <tr><td style=\"font-weight:700;color:#B45309\">C<\/td><td>73\u201376%<\/td><td style=\"font-weight:600\">2.0<\/td><td style=\"color:var(--gc-muted)\">Average<\/td><\/tr>\n            <tr><td style=\"font-weight:700;color:#B45309\">C\u2212<\/td><td>70\u201372%<\/td><td style=\"font-weight:600\">1.7<\/td><td style=\"color:var(--gc-muted)\">Average<\/td><\/tr>\n            <tr><td style=\"font-weight:700;color:#DC2626\">D+<\/td><td>67\u201369%<\/td><td style=\"font-weight:600\">1.3<\/td><td style=\"color:var(--gc-muted)\">Below average<\/td><\/tr>\n            <tr><td style=\"font-weight:700;color:#DC2626\">D<\/td><td>63\u201366%<\/td><td style=\"font-weight:600\">1.0<\/td><td style=\"color:var(--gc-muted)\">Below average<\/td><\/tr>\n            <tr><td style=\"font-weight:700;color:#DC2626\">D\u2212<\/td><td>60\u201362%<\/td><td style=\"font-weight:600\">0.7<\/td><td style=\"color:var(--gc-muted)\">Below average<\/td><\/tr>\n            <tr><td style=\"font-weight:700;color:#6B7280\">F<\/td><td>0\u201359%<\/td><td style=\"font-weight:600\">0.0<\/td><td style=\"color:var(--gc-muted)\">Failing<\/td><\/tr>\n          <\/tbody>\n        <\/table>\n      <\/div>\n    <\/div>\n  <\/div><!-- \/panel-gpa -->\n\n  <!-- HOW IT WORKS -->\n  <div style=\"margin-top:40px\">\n    <div class=\"gc-sec-h\">How to Use This Grade Calculator<\/div>\n    <div class=\"gc-sec-s\">Four tools. One page. Total academic clarity.<\/div>\n    <div class=\"gc-how\">\n      <div class=\"gc-how-step\">\n        <div class=\"gc-how-n\">01<\/div>\n        <div class=\"gc-how-t\">Enter your scores<\/div>\n        <div class=\"gc-how-d\">Add assignments, quizzes, or exams. Choose percentage, points, or letter grade format.<\/div>\n      <\/div>\n      <div class=\"gc-how-step\">\n        <div class=\"gc-how-n\">02<\/div>\n        <div class=\"gc-how-t\">Set the weights<\/div>\n        <div class=\"gc-how-d\">Enter how much each category counts toward your final grade. The badge tells you when weights hit 100%.<\/div>\n      <\/div>\n      <div class=\"gc-how-step\">\n        <div class=\"gc-how-n\">03<\/div>\n        <div class=\"gc-how-t\">See your grade live<\/div>\n        <div class=\"gc-how-d\">The arc and letter update instantly as you type. Set a target grade to see exactly what you still need.<\/div>\n      <\/div>\n      <div class=\"gc-how-step\">\n        <div class=\"gc-how-n\">04<\/div>\n        <div class=\"gc-how-t\">Calculate your GPA<\/div>\n        <div class=\"gc-how-d\">Switch to the GPA tab, add each course with its grade and credit hours, and get your cumulative GPA instantly.<\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <!-- CONTENT -->\n  <div class=\"gc-content\">\n    <h2>What Is a Weighted Grade Calculator?<\/h2>\n    <p>A weighted grade calculator multiplies each score by its relative importance in the course. Most courses don&#8217;t treat every assignment equally \u2014 a final exam worth 40% of your grade moves your average far more than a 5% homework set.<\/p>\n    <p>The formula is: <strong>Weighted Grade = \u03a3 (Score \u00d7 Weight) \u00f7 \u03a3 Weights<\/strong>. If your weights don&#8217;t add up to 100%, this tool normalizes them automatically so you still see a proportional result as you work.<\/p>\n\n    <h2>How the US Grading System Works<\/h2>\n    <p>The US uses a letter-grade system backed by percentages and a 4.0 GPA scale. Most colleges and universities follow this standard, though exact cutoffs can vary slightly by institution:<\/p>\n    <ul>\n      <li><strong>A range (90\u2013100%):<\/strong> Excellent work \u2014 GPA value of 3.7 to 4.0<\/li>\n      <li><strong>B range (80\u201389%):<\/strong> Good work \u2014 GPA value of 2.7 to 3.3<\/li>\n      <li><strong>C range (70\u201379%):<\/strong> Satisfactory \u2014 GPA value of 1.7 to 2.3<\/li>\n      <li><strong>D range (60\u201369%):<\/strong> Passing but below expectations \u2014 GPA value of 0.7 to 1.3<\/li>\n      <li><strong>F (below 60%):<\/strong> Failing \u2014 0.0 GPA points, course typically must be repeated<\/li>\n    <\/ul>\n    <p>Many institutions use plus\/minus grades (A+, A, A\u2212, B+, etc.) for finer precision. The GPA tab in this calculator handles both systems.<\/p>\n\n    <h2>What Score Do I Need on My Final Exam?<\/h2>\n    <p>Use the &#8220;Final Exam Needed&#8221; tab. Enter your current grade, how much the final counts (its weight), and the course grade you&#8217;re aiming for. The calculator tells you exactly what score you need \u2014 and the Scenario Planner shows you what every score from 50 to 100 would do to your final grade, so you can plan realistically rather than just hope.<\/p>\n    <ul>\n      <li>Result &gt; 100%: the target is mathematically impossible without extra credit<\/li>\n      <li>Result &lt; 0%: you&#8217;ve already secured your target \u2014 the final can&#8217;t drop you below it<\/li>\n      <li>Result between 0\u2013100%: achievable \u2014 check the Scenario Planner for a full breakdown<\/li>\n    <\/ul>\n    <p>Need more academic tools? Explore the full <a href=\"https:\/\/davidcelestin.com\/en\/tools\/calculators\/\" target=\"_blank\" rel=\"noopener\">calculators collection<\/a> on this site, or browse all <a href=\"https:\/\/davidcelestin.com\/en\/tools\/\" target=\"_blank\" rel=\"noopener\">free tools<\/a> available.<\/p>\n  <\/div>\n\n  <!-- FAQ -->\n  <div class=\"gc-sec-h\">Frequently Asked Questions<\/div>\n  <div class=\"gc-sec-s\">Real questions students ask about calculating grades and GPA.<\/div>\n  <div class=\"gc-faq\">\n\n    <div class=\"gc-faq-item\">\n      <button class=\"gc-faq-q\" onclick=\"gcFAQ(this)\">Why don&#8217;t my weights add up to 100%? <span class=\"gc-faq-ico\">+<\/span><\/button>\n      <div class=\"gc-faq-a\">Common causes: forgetting a category like participation or attendance, entering a weight twice, or confusing raw points with percentages. The warning badge in the Weighted Grade tab shows exactly how many percentage points you&#8217;re over or under. The tool still displays a proportional result while you correct the weights.<\/div>\n    <\/div>\n\n    <div class=\"gc-faq-item\">\n      <button class=\"gc-faq-q\" onclick=\"gcFAQ(this)\">What if my class uses a point system instead of percentages? <span class=\"gc-faq-ico\">+<\/span><\/button>\n      <div class=\"gc-faq-a\">Switch to &#8220;Points&#8221; format using the dropdown at the top of the Weighted Grade tab. Enter your earned points and the maximum possible points per assignment \u2014 the tool converts each one to a percentage automatically. For example, 47 out of 50 = 94%.<\/div>\n    <\/div>\n\n    <div class=\"gc-faq-item\">\n      <button class=\"gc-faq-q\" onclick=\"gcFAQ(this)\">Can I enter letter grades directly? <span class=\"gc-faq-ico\">+<\/span><\/button>\n      <div class=\"gc-faq-a\">Yes. Select &#8220;Letter Grade&#8221; format. The conversions used are the US standard midpoints: A+=97, A=93, A\u2212=90, B+=87, B=83, B\u2212=80, C+=77, C=73, C\u2212=70, D+=67, D=63, D\u2212=60, F=50. These are conservative midpoints \u2014 your actual percentage within each band may be higher.<\/div>\n    <\/div>\n\n    <div class=\"gc-faq-item\">\n      <button class=\"gc-faq-q\" onclick=\"gcFAQ(this)\">Is my data saved or sent anywhere? <span class=\"gc-faq-ico\">+<\/span><\/button>\n      <div class=\"gc-faq-a\">No. Every calculation happens entirely in your browser. Nothing leaves your device \u2014 no data is sent to any server, no cookies are set for your entries, and no account is needed. Refreshing the page clears all your entries.<\/div>\n    <\/div>\n\n    <div class=\"gc-faq-item\">\n      <button class=\"gc-faq-q\" onclick=\"gcFAQ(this)\">What&#8217;s the difference between current grade and overall grade? <span class=\"gc-faq-ico\">+<\/span><\/button>\n      <div class=\"gc-faq-a\">Your current grade counts only the work you&#8217;ve completed \u2014 empty rows are ignored entirely. Your overall grade treats any missing or incomplete entries as zeros. Mid-semester, current grade is more useful for understanding where you actually stand. By finals week, they should converge.<\/div>\n    <\/div>\n\n    <div class=\"gc-faq-item\">\n      <button class=\"gc-faq-q\" onclick=\"gcFAQ(this)\">How do I calculate my GPA from letter grades? <span class=\"gc-faq-ico\">+<\/span><\/button>\n      <div class=\"gc-faq-a\">Use the GPA tab. Add each course, its letter grade, and its credit hours. The tool calculates quality points (grade value \u00d7 credit hours) for each course, sums them, and divides by total credit hours. For reference: A\/A+=4.0, A\u2212=3.7, B+=3.3, B=3.0, B\u2212=2.7, C+=2.3, C=2.0, C\u2212=1.7, D+=1.3, D=1.0, D\u2212=0.7, F=0.0.<\/div>\n    <\/div>\n\n    <div class=\"gc-faq-item\">\n      <button class=\"gc-faq-q\" onclick=\"gcFAQ(this)\">What score do I need on my final exam to pass the course? <span class=\"gc-faq-ico\">+<\/span><\/button>\n      <div class=\"gc-faq-a\">Open the &#8220;Final Exam Needed&#8221; tab. Enter your current grade (before the final), the percentage weight of the final exam, and the minimum overall grade you need (usually 60% or D to pass). The calculator gives you the exact score needed. If the result is over 100%, passing is mathematically impossible without extra credit \u2014 the tool will show you the realistic ceiling instead.<\/div>\n    <\/div>\n\n    <div class=\"gc-faq-item\">\n      <button class=\"gc-faq-q\" onclick=\"gcFAQ(this)\">How do US letter grades map to percentages? <span class=\"gc-faq-ico\">+<\/span><\/button>\n      <div class=\"gc-faq-a\">The most widely used US scale: A+ (97\u2013100%), A (93\u201396%), A\u2212 (90\u201392%), B+ (87\u201389%), B (83\u201386%), B\u2212 (80\u201382%), C+ (77\u201379%), C (73\u201376%), C\u2212 (70\u201372%), D+ (67\u201369%), D (63\u201366%), D\u2212 (60\u201362%), F (below 60%). Some institutions use a simpler five-letter scale without plus\/minus grades \u2014 you can switch to this in the Grade Scale dropdown.<\/div>\n    <\/div>\n\n  <\/div>\n\n  <!-- RELATED TOOLS & INTERNAL LINKS -->\n  <div class=\"gc-related\">\n    <h2>\ud83d\udd17 More from David Celestin Studiolab<\/h2>\n    <div class=\"gc-related-grid\">\n      <a href=\"https:\/\/davidcelestin.com\/en\/tools\/calculators\/\" class=\"gc-rel-item\" target=\"_blank\" rel=\"noopener\">\n        <div class=\"gc-rel-icon\">\ud83e\uddee<\/div>\n        <div class=\"gc-rel-name\">All Calculators<\/div>\n        <div class=\"gc-rel-desc\">Browse every free calculator tool on this site.<\/div>\n      <\/a>\n      <a href=\"https:\/\/davidcelestin.com\/en\/tools\/\" class=\"gc-rel-item\" target=\"_blank\" rel=\"noopener\">\n        <div class=\"gc-rel-icon\">\ud83d\udee0\ufe0f<\/div>\n        <div class=\"gc-rel-name\">Free Tools Hub<\/div>\n        <div class=\"gc-rel-desc\">All free online tools, in one place.<\/div>\n      <\/a>\n      <a href=\"https:\/\/davidcelestin.com\/en\/articles-categories\/\" class=\"gc-rel-item\" target=\"_blank\" rel=\"noopener\">\n        <div class=\"gc-rel-icon\">\ud83d\udcda<\/div>\n        <div class=\"gc-rel-name\">Articles<\/div>\n        <div class=\"gc-rel-desc\">Read expert articles on education, strategy, and more.<\/div>\n      <\/a>\n      <a href=\"https:\/\/davidcelestin.com\/en\/studiolab\/\" class=\"gc-rel-item\" target=\"_blank\" rel=\"noopener\">\n        <div class=\"gc-rel-icon\">\u2697\ufe0f<\/div>\n        <div class=\"gc-rel-name\">Studiolab<\/div>\n        <div class=\"gc-rel-desc\">Discover products and services from David Celestin Studiolab.<\/div>\n      <\/a>\n      <a href=\"https:\/\/davidcelestin.com\/en\/store\/\" class=\"gc-rel-item\" target=\"_blank\" rel=\"noopener\">\n        <div class=\"gc-rel-icon\">\ud83d\udecd\ufe0f<\/div>\n        <div class=\"gc-rel-name\">Store<\/div>\n        <div class=\"gc-rel-desc\">Shop exclusive products from davidcelestin.com.<\/div>\n      <\/a>\n      <a href=\"https:\/\/davidcelestin.com\/en\/newsletters\/\" class=\"gc-rel-item\" target=\"_blank\" rel=\"noopener\">\n        <div class=\"gc-rel-icon\">\u2709\ufe0f<\/div>\n        <div class=\"gc-rel-name\">Newsletter<\/div>\n        <div class=\"gc-rel-desc\">Stay in the loop with David Celestin&#8217;s latest updates.<\/div>\n      <\/a>\n    <\/div>\n  <\/div>\n\n  <div class=\"gc-footer\">\n    <p>Built by <a href=\"https:\/\/davidcelestin.com\/en\/studiolab\/\" target=\"_blank\" rel=\"noopener\">David Celestin Studiolab<\/a> \u00b7 Free \u00b7 No signup required \u00b7 No data stored \u00b7 Runs entirely in your browser<\/p>\n  <\/div>\n\n<\/div><!-- \/gc-wrap -->\n<\/div><!-- \/gc-app -->\n\n<script>\n(function(){\n'use strict';\n\n\/* ============================================================\n   CONSTANTS\n   ============================================================ *\/\nvar L2P = {'A+':97,'A':93,'A-':90,'B+':87,'B':83,'B-':80,'C+':77,'C':73,'C-':70,'D+':67,'D':63,'D-':60,'F':50};\nvar L2G = {'A+':4.0,'A':4.0,'A-':3.7,'B+':3.3,'B':3.0,'B-':2.7,'C+':2.3,'C':2.0,'C-':1.7,'D+':1.3,'D':1.0,'D-':0.7,'F':0.0};\n\nvar SP = [\n  {l:'A+',m:97,c:'#7000F4',bg:'rgba(112,0,244,.12)'},\n  {l:'A', m:93,c:'#7000F4',bg:'rgba(112,0,244,.10)'},\n  {l:'A-',m:90,c:'#7000F4',bg:'rgba(112,0,244,.08)'},\n  {l:'B+',m:87,c:'#1D4ED8',bg:'rgba(29,78,216,.10)'},\n  {l:'B', m:83,c:'#1D4ED8',bg:'rgba(29,78,216,.08)'},\n  {l:'B-',m:80,c:'#1D4ED8',bg:'rgba(29,78,216,.06)'},\n  {l:'C+',m:77,c:'#B45309',bg:'rgba(180,83,9,.10)'},\n  {l:'C', m:73,c:'#B45309',bg:'rgba(180,83,9,.08)'},\n  {l:'C-',m:70,c:'#B45309',bg:'rgba(180,83,9,.06)'},\n  {l:'D+',m:67,c:'#DC2626',bg:'rgba(220,38,38,.10)'},\n  {l:'D', m:63,c:'#DC2626',bg:'rgba(220,38,38,.08)'},\n  {l:'D-',m:60,c:'#DC2626',bg:'rgba(220,38,38,.06)'},\n  {l:'F', m:0, c:'#6B7280',bg:'rgba(107,114,128,.10)'}\n];\nvar SS = [\n  {l:'A',m:90,c:'#7000F4',bg:'rgba(112,0,244,.12)'},\n  {l:'B',m:80,c:'#1D4ED8',bg:'rgba(29,78,216,.10)'},\n  {l:'C',m:70,c:'#B45309',bg:'rgba(180,83,9,.10)'},\n  {l:'D',m:60,c:'#DC2626',bg:'rgba(220,38,38,.10)'},\n  {l:'F',m:0, c:'#6B7280',bg:'rgba(107,114,128,.10)'}\n];\nvar ARC = 2*Math.PI*80;\n\n\/* ---- state ---- *\/\nvar wRows=[], wId=0, sRows=[], sId=0, gRows=[], gId=0;\n\nfunction $(id){return document.getElementById(id);}\n\n\/* ============================================================\n   HELPERS\n   ============================================================ *\/\nfunction scale(){\n  var s=$('gc-w-scale'); return (s&&s.value==='simple')?SS:SP;\n}\nfunction p2l(p){\n  if(p===null||isNaN(p))return'\u2013';\n  var s=$('gc-w-scale');\n  if(s&&s.value==='pct')return p.toFixed(1)+'%';\n  var sc=scale();\n  for(var i=0;i<sc.length;i++)if(p>=sc[i].m)return sc[i].l;\n  return'F';\n}\nfunction p2lFinal(p){\n  \/* final tab always uses plus scale *\/\n  for(var i=0;i<SP.length;i++)if(p>=SP[i].m)return SP[i].l;\n  return'F';\n}\nfunction lColor(l){\n  var all=SP.concat(SS);\n  for(var i=0;i<all.length;i++)if(all[i].l===l)return all[i].c;\n  return'#6B7280';\n}\nfunction parsePct(v,fmt,mx){\n  if(v===''||v==null)return null;\n  v=String(v).trim().toUpperCase();\n  if(fmt==='letter')return(L2P[v]!==undefined?L2P[v]:null);\n  if(fmt==='points'){var n=parseFloat(v);return(isNaN(n)||isNaN(mx)||mx<=0)?null:(n\/mx)*100;}\n  var n2=parseFloat(v);return isNaN(n2)?null:Math.min(100,Math.max(0,n2));\n}\nfunction setArc(id,pct){\n  var el=$(id);if(!el)return;\n  el.style.strokeDashoffset=ARC-(Math.max(0,Math.min(100,pct||0))\/100)*ARC;\n}\n\n\/* ============================================================\n   TAB SWITCHING\n   ============================================================ *\/\nwindow.gcTab=function(p){\n  var app=document.getElementById('gc-app');if(!app)return;\n  var panels=['weighted','final','simple','gpa'];\n  app.querySelectorAll('.gc-tab').forEach(function(t,i){\n    t.classList.toggle('active',panels[i]===p);\n    t.setAttribute('aria-selected',panels[i]===p?'true':'false');\n  });\n  app.querySelectorAll('.gc-panel').forEach(function(el){\n    el.classList.toggle('active',el.id==='gc-panel-'+p);\n  });\n};\n\n\/* ============================================================\n   PANEL 1 \u2014 WEIGHTED\n   ============================================================ *\/\nwindow.gcWAdd=function(nm,sc,wt,mx){\n  wRows.push({id:wId++,name:nm||'',score:sc||'',weight:wt||'',mx:mx||''});\n  gcRenderW();\n};\nwindow.gcRenderW=function(){\n  var tb=$('gc-w-body');if(!tb)return;\n  var fmt=$('gc-w-fmt')?$('gc-w-fmt').value:'percent';\n  tb.innerHTML='';\n  wRows.forEach(function(r,i){\n    var tr=document.createElement('tr');\n    var sc;\n    if(fmt==='points'){\n      sc='<div style=\"display:flex;gap:3px;align-items:center\">'\n        +'<input type=\"number\" class=\"gc-inp\" style=\"width:58px\" placeholder=\"Got\" value=\"'+r.score+'\" oninput=\"gcWF('+i+',\\'score\\',this.value)\">'\n        +'<span style=\"color:var(--gc-muted)\">\/<\/span>'\n        +'<input type=\"number\" class=\"gc-inp\" style=\"width:58px\" placeholder=\"Max\" value=\"'+r.mx+'\" oninput=\"gcWF('+i+',\\'mx\\',this.value)\">'\n        +'<\/div>';\n    }else if(fmt==='letter'){\n      sc='<input type=\"text\" class=\"gc-inp\" style=\"text-transform:uppercase\" placeholder=\"A, B+\u2026\" maxlength=\"2\" value=\"'+r.score+'\" oninput=\"gcWF('+i+',\\'score\\',this.value.toUpperCase())\">';\n    }else{\n      sc='<input type=\"number\" class=\"gc-inp\" placeholder=\"0\u2013100\" min=\"0\" max=\"100\" step=\".1\" value=\"'+r.score+'\" oninput=\"gcWF('+i+',\\'score\\',this.value)\">';\n    }\n    tr.innerHTML=''\n      +'<td><input type=\"text\" class=\"gc-inp gc-inp-name\" placeholder=\"e.g. Midterm\" value=\"'+r.name+'\" oninput=\"gcWF('+i+',\\'name\\',this.value)\"><\/td>'\n      +'<td>'+sc+'<\/td>'\n      +'<td><input type=\"number\" class=\"gc-inp\" placeholder=\"%\" min=\"0\" max=\"100\" value=\"'+r.weight+'\" oninput=\"gcWF('+i+',\\'weight\\',this.value)\"><\/td>'\n      +'<td id=\"gc-wc-'+i+'\"><span class=\"gc-t-muted\" style=\"font-size:12px\">\u2014<\/span><\/td>'\n      +'<td><button class=\"gc-btn-del\" aria-label=\"Remove row\" onclick=\"gcWDel('+i+')\">\u2715<\/button><\/td>';\n    tb.appendChild(tr);\n  });\n  gcWCalc();\n};\nwindow.gcWF=function(i,f,v){wRows[i][f]=v;gcWCalc();};\nwindow.gcWDel=function(i){wRows.splice(i,1);gcRenderW();};\nwindow.gcWReset=function(){\n  wRows=[];wId=0;\n  var t=$('gc-w-tgt');if(t)t.value='';\n  gcWAdd('Homework','','20','');\n  gcWAdd('Quizzes','','20','');\n  gcWAdd('Midterm','','30','');\n  gcWAdd('Final Exam','','30','');\n};\nwindow.gcWCalc=function(){\n  var fmt=$('gc-w-fmt')?$('gc-w-fmt').value:'percent';\n  var tw=0,ws=0,valid=0,scores=[];\n  wRows.forEach(function(r,i){\n    var w=parseFloat(r.weight)||0;\n    var p=parsePct(r.score,fmt,parseFloat(r.mx));\n    tw+=w;\n    if(p!==null&&w>0){ws+=p*w;valid++;scores.push(p);}\n    var cell=$('gc-wc-'+i);\n    if(cell){\n      if(p!==null&&w>0){\n        var cb=(p*w\/100).toFixed(1);\n        var cls=w>=30?'high':(w>=15?'med':'low');\n        cell.innerHTML='<span class=\"gc-ctb '+cls+'\">+'+cb+' pts<\/span>';\n      }else{\n        cell.innerHTML='<span class=\"gc-t-muted\" style=\"font-size:12px\">\u2014<\/span>';\n      }\n    }\n  });\n  var rnd=Math.round(tw);\n  var bd=$('gc-w-badge'),bs=$('gc-w-bsum'),bm=$('gc-w-bmsg'),bi=$('gc-w-bico');\n  if(bs)bs.textContent=rnd;\n  if(bd){\n    bd.className='gc-wbadge '+(rnd===100?'ok':rnd>100?'error':'warn');\n    if(bi)bi.textContent=rnd===100?'\u2705':(rnd>100?'\u274c':'\u26a0\ufe0f');\n    if(bm)bm.innerHTML=rnd===100\n      ?'Weights total <strong>100%<\/strong> \u2014 perfect!'\n      :rnd>100\n      ?'Weights total <strong>'+rnd+'%<\/strong> \u2014 reduce by '+(rnd-100)+'%'\n      :'Weights total <strong>'+rnd+'%<\/strong> \u2014 add '+(100-rnd)+'% more';\n  }\n  var grade=(tw>0&&valid>0)?ws\/tw:null;\n  var pe=$('gc-w-pct'),le=$('gc-w-ltr');\n  if(pe&&le){\n    if(grade!==null){\n      pe.textContent=grade.toFixed(1)+'%';\n      var lt=p2l(grade);\n      le.textContent=lt;le.style.color=lColor(lt);\n      setArc('gc-w-arc',grade);\n    }else{pe.textContent='\u2014';le.textContent='\u2013';setArc('gc-w-arc',0);}\n  }\n  var hi=$('gc-w-hi'),lo=$('gc-w-lo'),ct=$('gc-w-ct'),st=$('gc-w-st');\n  if(ct)ct.textContent=scores.length;\n  if(hi)hi.textContent=scores.length?Math.max.apply(null,scores).toFixed(1)+'%':'\u2014';\n  if(lo)lo.textContent=scores.length?Math.min.apply(null,scores).toFixed(1)+'%':'\u2014';\n  if(st){\n    st.style.color='';\n    if(grade!==null){\n      if(grade>=90){st.textContent='Excellent';st.className='gc-stat-val gc-t-ok';}\n      else if(grade>=80){st.textContent='Good';st.className='gc-stat-val gc-t-primary';}\n      else if(grade>=70){st.textContent='Average';st.className='gc-stat-val';}\n      else if(grade>=60){st.textContent='Below Avg';st.className='gc-stat-val';st.style.color='var(--gc-warning)';}\n      else{st.textContent='Failing';st.className='gc-stat-val gc-t-danger';}\n    }else{st.textContent='\u2014';st.className='gc-stat-val';}\n  }\n  var tgt=$('gc-w-tgt'),tr2=$('gc-w-tgtresult');\n  if(tgt&&tr2){\n    var tv=parseFloat(tgt.value);\n    if(!isNaN(tv)&&grade!==null){\n      var d=grade-tv;\n      tr2.className='gc-alert '+(d>=0?'success':'info');\n      tr2.innerHTML=d>=0\n        ?'<span>\ud83c\udf89<\/span><div>You\\'ve <strong>already met<\/strong> your '+tv+'% target \u2014 currently '+d.toFixed(1)+' points above it.<\/div>'\n        :'<span>\ud83d\udccc<\/span><div>You need <strong>'+Math.abs(d).toFixed(1)+' more points<\/strong> to reach your '+tv+'% target.<\/div>';\n      tr2.classList.remove('gc-hidden');\n    }else{tr2.classList.add('gc-hidden');}\n  }\n  gcWPills();\n};\nfunction gcWPills(){\n  var c=$('gc-w-pills');if(!c)return;\n  var sc=$('gc-w-scale');if(!sc)return;\n  if(sc.value==='pct'){\n    c.innerHTML='<span style=\"font-size:12px;color:var(--gc-muted)\">Showing raw percentages \u2014 no letter conversion.<\/span>';return;\n  }\n  var s=scale();\n  c.innerHTML=s.map(function(g,idx){\n    var prev=s[idx-1];var mx=prev?prev.m-1:100;\n    return'<span class=\"gc-pill\" style=\"color:'+g.c+';border-color:'+g.c+';background:'+g.bg+'\">'+g.l+' ('+g.m+'\u2013'+mx+'%)<\/span>';\n  }).join('');\n}\n\n\/* ============================================================\n   PANEL 2 \u2014 FINAL EXAM\n   ============================================================ *\/\nwindow.gcFCalc=function(){\n  var cur=parseFloat($('gc-f-cur')?$('gc-f-cur').value:'');\n  var wt =parseFloat($('gc-f-wt') ?$('gc-f-wt').value :'') \/100;\n  var des=parseFloat($('gc-f-des')?$('gc-f-des').value:'');\n  var ex =parseFloat($('gc-f-ex') ?$('gc-f-ex').value :'') ||0;\n  var re=$('gc-f-result'),sb=$('gc-f-rows');\n  if(isNaN(cur)||isNaN(wt)||isNaN(des)){\n    if(re)re.classList.add('gc-hidden');\n    if(sb)sb.innerHTML='<tr><td colspan=\"4\" style=\"color:var(--gc-muted);font-size:12px;padding:10px 8px\">Fill in the first three fields to see results.<\/td><\/tr>';\n    return;\n  }\n  var req=(des-cur*(1-wt))\/wt-ex;\n  var cls,icon,msg;\n  if(req<=0){\n    cls='success';icon='\ud83c\udf89';\n    msg='You\\'ve <strong>already secured your '+des+'% target<\/strong> \u2014 no matter what you score on the final'+(ex>0?' (with extra credit)':'')+'.';\n  }else if(req<=100){\n    cls='info';icon='\ud83c\udfaf';\n    msg='You need at least <strong>'+req.toFixed(1)+'%<\/strong> on the final to achieve a <strong>'+des+'%<\/strong> course grade'+(ex>0?' (after '+ex+'% extra credit)':'')+'.';\n  }else{\n    cls='danger';icon='\u26a0\ufe0f';\n    var ceil=Math.floor(100*wt+cur*(1-wt)+ex*wt);\n    msg='You\\'d need <strong>'+req.toFixed(1)+'%<\/strong> \u2014 impossible without extra credit. <strong>Realistic ceiling: ~'+ceil+'%<\/strong>. Consider adjusting your target.';\n  }\n  if(re){re.className='gc-alert '+cls;re.innerHTML='<span>'+icon+'<\/span><div>'+msg+'<\/div>';re.classList.remove('gc-hidden');}\n  var scenarios=[50,60,65,70,75,80,85,90,95,100];\n  if(sb)sb.innerHTML=scenarios.map(function(score){\n    var fg=cur*(1-wt)+score*wt;\n    var lt=p2lFinal(fg);\n    var pass=fg>=60,met=fg>=des;\n    return'<tr>'\n      +'<td style=\"font-weight:600;color:var(--gc-text)\">'+score+'%<\/td>'\n      +'<td style=\"color:var(--gc-text)\">'+fg.toFixed(1)+'%<\/td>'\n      +'<td><span style=\"color:'+lColor(lt)+';font-weight:700\">'+lt+'<\/span><\/td>'\n      +'<td><span style=\"font-size:11px;padding:2px 8px;border-radius:100px;font-weight:600;'\n      +(met?'background:#F0FDF4;color:#16A34A;border:1px solid #BBF7D0'\n           :pass?'background:#FFFBEB;color:#B45309;border:1px solid #FDE68A'\n                :'background:#FEF2F2;color:#DC2626;border:1px solid #FECACA')\n      +'\">'+(met?'\u2713 Target met':pass?'Passing':'\u2717 Failing')+'<\/span><\/td>'\n      +'<\/tr>';\n  }).join('');\n};\n\n\/* ============================================================\n   PANEL 3 \u2014 SIMPLE AVERAGE\n   ============================================================ *\/\nwindow.gcSAdd=function(nm,sc){\n  sRows.push({id:sId++,name:nm||'',score:sc||''});gcSRender();\n};\nwindow.gcSRender=function(){\n  var tb=$('gc-s-body');if(!tb)return;\n  tb.innerHTML='';\n  sRows.forEach(function(r,i){\n    var tr=document.createElement('tr');\n    tr.innerHTML='<td><input type=\"text\" class=\"gc-inp gc-inp-name\" placeholder=\"e.g. Quiz 1\" value=\"'+r.name+'\" oninput=\"gcSF('+i+',\\'name\\',this.value)\"><\/td>'\n      +'<td><input type=\"number\" class=\"gc-inp\" placeholder=\"0\u2013100\" min=\"0\" max=\"100\" step=\".1\" value=\"'+r.score+'\" oninput=\"gcSF('+i+',\\'score\\',this.value)\"><\/td>'\n      +'<td><button class=\"gc-btn-del\" aria-label=\"Remove row\" onclick=\"gcSDel('+i+')\">\u2715<\/button><\/td>';\n    tb.appendChild(tr);\n  });gcSCalc();\n};\nwindow.gcSF=function(i,f,v){sRows[i][f]=v;gcSCalc();};\nwindow.gcSDel=function(i){sRows.splice(i,1);gcSRender();};\nwindow.gcSCalc=function(){\n  var sc=sRows.map(function(r){return parseFloat(r.score);}).filter(function(v){return!isNaN(v);});\n  var avg=sc.length?sc.reduce(function(a,b){return a+b;},0)\/sc.length:null;\n  var pe=$('gc-s-pct'),le=$('gc-s-ltr');\n  if(pe&&le){\n    if(avg!==null){\n      pe.textContent=avg.toFixed(1)+'%';\n      var lt=p2lFinal(avg);\n      le.textContent=lt;le.style.color=lColor(lt);\n      setArc('gc-s-arc',avg);\n    }else{pe.textContent='\u2014';le.textContent='\u2013';setArc('gc-s-arc',0);}\n  }\n};\nwindow.gcSReset=function(){\n  sRows=[];sId=0;\n  gcSAdd('Assignment 1');gcSAdd('Assignment 2');gcSAdd('Assignment 3');\n};\n\n\/* ============================================================\n   PANEL 4 \u2014 GPA CALCULATOR\n   ============================================================ *\/\nwindow.gcGAdd=function(nm,gr,cr){\n  gRows.push({id:gId++,name:nm||'',grade:gr||'',credits:cr||''});gcGRender();\n};\nwindow.gcGRender=function(){\n  var tb=$('gc-g-body');if(!tb)return;\n  tb.innerHTML='';\n  gRows.forEach(function(r,i){\n    var tr=document.createElement('tr');\n    var gv=L2G[r.grade.toUpperCase()];\n    var pts=(gv!==undefined&&r.credits!=='')?(gv*parseFloat(r.credits)).toFixed(1):'\u2014';\n    tr.innerHTML=''\n      +'<td><input type=\"text\" class=\"gc-inp gc-inp-name\" placeholder=\"e.g. English 101\" value=\"'+r.name+'\" oninput=\"gcGF('+i+',\\'name\\',this.value)\"><\/td>'\n      +'<td><input type=\"text\" class=\"gc-inp\" style=\"text-transform:uppercase;max-width:90px\" placeholder=\"A, B+\u2026\" maxlength=\"2\" value=\"'+r.grade+'\" oninput=\"gcGF('+i+',\\'grade\\',this.value.toUpperCase())\"><\/td>'\n      +'<td><input type=\"number\" class=\"gc-inp\" placeholder=\"e.g. 3\" min=\"0.5\" max=\"6\" step=\".5\" style=\"max-width:90px\" value=\"'+r.credits+'\" oninput=\"gcGF('+i+',\\'credits\\',this.value)\"><\/td>'\n      +'<td><span style=\"font-weight:600;font-size:13px;color:var(--gc-text)\">'+pts+'<\/span><\/td>'\n      +'<td><button class=\"gc-btn-del\" aria-label=\"Remove course\" onclick=\"gcGDel('+i+')\">\u2715<\/button><\/td>';\n    tb.appendChild(tr);\n  });gcGCalc();\n};\nwindow.gcGF=function(i,f,v){gRows[i][f]=v;gcGRender();};\nwindow.gcGDel=function(i){gRows.splice(i,1);gcGRender();};\nwindow.gcGCalc=function(){\n  var totalCr=0,totalPts=0,valid=0;\n  gRows.forEach(function(r){\n    var gv=L2G[r.grade.toUpperCase()];\n    var cr=parseFloat(r.credits);\n    if(gv!==undefined&&!isNaN(cr)&&cr>0){totalCr+=cr;totalPts+=gv*cr;valid++;}\n  });\n  var gpa=valid>0?totalPts\/totalCr:null;\n  var gv=$('gc-g-gpa'),gl=$('gc-g-ltr'),gc=$('gc-g-cred'),gp=$('gc-g-pts'),gs=$('gc-g-status');\n  if(gc)gc.textContent=totalCr.toFixed(1);\n  if(gp)gp.textContent=totalPts.toFixed(2);\n  if(gv&&gl){\n    if(gpa!==null){\n      gv.textContent=gpa.toFixed(2);\n      var lbl=gpa>=3.7?'A range':gpa>=3.3?'B+ range':gpa>=3.0?'B range':gpa>=2.7?'B- range':gpa>=2.0?'C range':gpa>=1.0?'D range':'F range';\n      gl.textContent='('+lbl+')';\n    }else{gv.textContent='\u2014';gl.textContent='';}\n  }\n  if(gs){\n    if(gpa===null){gs.textContent='';gs.style.color='';}\n    else if(gpa>=3.7){gs.textContent='\ud83c\udfc6 Dean\\'s List territory';gs.style.color='var(--gc-success)';}\n    else if(gpa>=3.0){gs.textContent='\ud83d\udc4d Good standing';gs.style.color='var(--gc-primary)';}\n    else if(gpa>=2.0){gs.textContent='\ud83d\udcd8 Satisfactory';gs.style.color='var(--gc-warning)';}\n    else{gs.textContent='\u26a0\ufe0f Academic probation risk';gs.style.color='var(--gc-danger)';}\n  }\n};\nwindow.gcGReset=function(){\n  gRows=[];gId=0;\n  gcGAdd('English 101','','3');\n  gcGAdd('Math 201','','4');\n  gcGAdd('History 110','','3');\n  gcGAdd('Biology 101','','4');\n};\n\n\/* ============================================================\n   FAQ\n   ============================================================ *\/\nwindow.gcFAQ=function(btn){btn.parentElement.classList.toggle('open');};\n\n\/* ============================================================\n   INIT\n   ============================================================ *\/\ngcWReset();\ngcSReset();\ngcGReset();\ngcFCalc();\ngcWPills();\n\n}());\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Free Online Tool Grade Calculator Know exactly where you stand \u2014 and what you need. Weighted grades, final exam targets, simple averages, and GPA conversion in one place. No signup. No data stored. \ud83d\udccaWeighted Grade \ud83c\udfafFinal Exam \u2797Simple Average \ud83c\udf93GPA Calculator \ud83d\udcca Your Current Grade \u26a0\ufe0f Weights total 0% \u2014 should add to 100% \u2014 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":87,"parent":2097,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"page-templates\/full-width.php","meta":{"_gspb_post_css":"","footnotes":""},"class_list":["post-2101","page","type-page","status-publish","has-post-thumbnail","hentry"],"_links":{"self":[{"href":"https:\/\/davidcelestin.com\/en\/wp-json\/wp\/v2\/pages\/2101","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/davidcelestin.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/davidcelestin.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/davidcelestin.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/davidcelestin.com\/en\/wp-json\/wp\/v2\/comments?post=2101"}],"version-history":[{"count":6,"href":"https:\/\/davidcelestin.com\/en\/wp-json\/wp\/v2\/pages\/2101\/revisions"}],"predecessor-version":[{"id":2129,"href":"https:\/\/davidcelestin.com\/en\/wp-json\/wp\/v2\/pages\/2101\/revisions\/2129"}],"up":[{"embeddable":true,"href":"https:\/\/davidcelestin.com\/en\/wp-json\/wp\/v2\/pages\/2097"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/davidcelestin.com\/en\/wp-json\/wp\/v2\/media\/87"}],"wp:attachment":[{"href":"https:\/\/davidcelestin.com\/en\/wp-json\/wp\/v2\/media?parent=2101"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}