1<!DOCTYPE html> 2<html lang="en" class="app-layout"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1"> 6 <meta name="csrf-token" content="fde8dc2ddb50524b642c796a4f6f5899e996eed013c4026221d1ab3c7c1df9cb"> 7 <title>Membership Plans â WriteUpCafe</title> 8 <meta name="description" content="WriteUpCafe is a free publishing platform where writers and bloggers share original articles, grow their audience, and connect with a vibrant writing community. Publish your ideas, list your blog, and get discovered."> 9 <link rel="alternate" type="application/rss+xml" title="WriteUpCafe RSS Feed" href="/feed.xml"> 10 <link rel="icon" href="/data/branding/favicon-1782720251.png?v=1782720271" sizes="any"> 11 <link rel="apple-touch-icon" href="/data/branding/apple-touch-1782720251.png?v=1782720271"> <link rel="manifest" href="/manifest.json"> 12 <!-- Critical inline CSS for instant first paint --> 13 <style> 14 *,*::before,*::after{box-sizing:border-box;margin:0;padding:0} 15 html{-webkit-text-size-adjust:100%} 16 body{font-family:'DM Sans',system-ui,-apple-system,sans-serif;background:#faf9f7;color:#1a1612;-webkit-font-smoothing:antialiased} 17 .layout-app{display:flex;flex-direction:column;min-height:100vh} 18 img{max-width:100%;height:auto} 19 </style> 20 <!-- Full CSS: non-blocking preload --> 21 <link rel="preload" href="/assets/css/app.css?v=1780723093" as="style" onload="this.onload=null;this.rel='stylesheet'"> 22 <noscript><link rel="stylesheet" href="/assets/css/app.css?v=1780723093"></noscript> 23 <!-- Design system tokens â namespaced .wuc-* / --wuc-*, safe alongside app.css --> 24 <link rel="stylesheet" href="/assets/css/wuc-tokens.css?v=1777043721"> 25 <link rel="stylesheet" href="/assets/css/wuc-nav-app.css?v=1777129320"> 26 <!-- Fonts: non-blocking --> 27 <link rel="preconnect" href="https://fonts.googleapis.com"> 28 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 29 <link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700;800&family=DM+Sans:wght@400;500;600;700&family=DM+Mono:wght@400&display=swap" onload="this.onload=null;this.rel='stylesheet'"> 30 <!-- Google Analytics -->
vendor: 65 bytes, lines 30-31
30 31<script async src="https://www.googletagmanager.com/gtag/js?id=
31G-PX1J0S6JZ1
vendor: 13 bytes, line 31
31"></script>
32<script>
vendor: 130 bytes, lines 33-36
33window.dataLayer = window.dataLayer || []; 34function gtag(){dataLayer.push(arguments);} 35gtag('js', new Date()); 36gtag('config', '
36G-PX1J0S6JZ1
vendor: 5 bytes, line 36
36');
37</script>
37 38 39<!-- Google tag (gtag.js) -->
vendor: 65 bytes, lines 39-40
39 40<script async src="https://www.googletagmanager.com/gtag/js?id=
40AW-18084003911
vendor: 13 bytes, line 40
40"></script>
41<script> 42
vendor: 138 bytes, lines 42-46
42window.dataLayer = window.dataLayer || []; 43 function gtag(){dataLayer.push(arguments);} 44 gtag('js', new Date()); 45 46 gtag('config', '
46AW-18084003911
vendor: 5 bytes, line 46
46');
47</script>
47 48</head> 49<body> 50 <div class="layout-app"> 51 <nav class="nav-app" data-theme="espresso"> 52 <div class="container nav-app__inner"> 53 54 <!-- Logo --> 55 <a href="/" class="site-logo site-logo--dark"><img src="/assets/img/wc_dark.svg?v=1782720271" alt="WriteUpCafe" class="site-logo-icon"><span style="padding-bottom:2px">Write<em>Up</em>Cafe</span></a> 56 57 <!-- Search --> 58 <div class="nav-search" style="position:relative;"> 59 <svg class="nav-search__icon" width="16" height="16" viewBox="0 0 24 24" fill="none" 60 stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 61 <circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/> 62 </svg> 63 <input type="text" class="nav-search__input" id="nav-search-input" 64 placeholder="Search writeups, blogs, authorsâ¦" 65 aria-label="Search" autocomplete="off"> 66 <div class="srch-dropdown" id="srch-dropdown"></div> 67 </div> 68 69 <!-- Right actions --> 70 <div class="nav__actions"> 71 <a href="/login" class="wuc-btn wuc-btn-outline wuc-btn--sm">Log in</a> 72 <a href="/register" class="wuc-btn wuc-btn-primary wuc-btn--sm">Join free</a> 73 </div> 74 75 </div> 76</nav> 77 78 79 <style> 80/* ââ Pricing page (scoped under .pricing-wrap) âââââââââââââââââââââââââââ */ 81/* Palette rebound to WriteUpCafe design system (src/design-system/design.md). 82 Local var names kept to avoid churning the 1,500 lines of layout CSS below. */ 83.pricing-wrap { 84 --espresso: var(--wuc-espresso-dark); 85 --espresso-mid: var(--wuc-espresso-mid); 86 --copper: var(--wuc-primary); /* #e87a35 â spec primary CTA fill */ 87 --copper-light: var(--wuc-primary-hover); /* #f08a45 */ 88 --copper-pale: var(--wuc-gold-warm); /* #e0a030 â eyebrow bg */ 89 --cream: var(--wuc-parchment); 90 --cream-dark: var(--wuc-parchment-sunken); 91 --ink: #1A1008; 92 --muted: #7A6248; 93 --pr-border: var(--wuc-border); 94 --white: #FFFFFF; 95 font-family: var(--wuc-font-body); 96 background: var(--cream); 97 color: var(--espresso); 98 overflow-x: hidden; 99} 100 101/* ââ HERO ââ */ 102.pr-hero { 103 text-align: center; 104 padding: 64px 24px 40px; 105 position: relative; 106 overflow: hidden; 107} 108.pr-hero::before { 109 content: ''; 110 position: absolute; 111 top: -60px; left: 50%; 112 transform: translateX(-50%); 113 width: 600px; height: 300px; 114 background: radial-gradient(ellipse, rgba(181,114,42,.15) 0%, transparent 70%); 115 pointer-events: none; 116} 117.pr-eyebrow { 118 display: inline-block; 119 background: var(--copper-pale); 120 color: var(--espresso); 121 font-size: .72rem; font-weight: 600; 122 letter-spacing: .12em; text-transform: uppercase; 123 padding: 5px 14px; border-radius: 2px; margin-bottom: 20px; 124} 125.pr-hero h1 { 126 font-family: 'Playfair Display', serif; 127 font-size: clamp(2.2rem, 5vw, 3.6rem); 128 font-weight: 700; line-height: 1.1; 129 color: var(--espresso); margin-bottom: 14px; 130} 131.pr-hero h1 em { font-style: italic; color: var(--copper); } 132.pr-hero p { 133 color: var(--muted); font-size: 1.02rem; 134 max-width: 460px; margin: 0 auto; line-height: 1.6; 135} 136 137/* ââ BILLING TOGGLE ââ */ 138.pr-toggle-wrap { 139 display: flex; align-items: center; justify-content: center; 140 gap: 14px; margin: 32px 0 44px; 141} 142.pr-toggle-label { font-size: .88rem; font-weight: 500; color: var(--muted); transition: color .2s; } 143.pr-toggle-label.active { color: var(--espresso); font-weight: 600; } 144.pr-toggle-sw { 145 width: 52px; height: 28px; 146 background: var(--pr-border); border-radius: 14px; 147 position: relative; cursor: pointer; transition: background .3s; 148} 149.pr-toggle-sw.on { background: var(--copper); } 150.pr-toggle-sw::after { 151 content: ''; position: absolute; 152 top: 3px; left: 3px; 153 width: 22px; height: 22px; 154 background: white; border-radius: 50%; 155 transition: transform .3s cubic-bezier(.4,0,.2,1); 156 box-shadow: 0 1px 4px rgba(0,0,0,.2); 157} 158.pr-toggle-sw.on::after { transform: translateX(24px); } 159.pr-save-badge { 160 background: linear-gradient(135deg, var(--copper), var(--copper-light)); 161 color: white; font-size: .7rem; font-weight: 600; 162 padding: 3px 9px; border-radius: 20px; letter-spacing: .04em; 163} 164 165/* ââ CARDS GRID ââ */ 166.pr-section { max-width: 960px; margin: 0 auto; padding: 0 24px 72px; } 167.pr-cards-grid { 168 display: grid; 169 grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); 170 gap: 24px; align-items: start; 171} 172 173/* ââ CARD ââ */ 174.pr-card { 175 background: var(--white); 176 border: 1.5px solid var(--pr-border); 177 border-radius: 16px; overflow: hidden; 178 transition: transform .3s, box-shadow .3s; 179 position: relative; 180} 181.pr-card:hover { 182 transform: translateY(-4px); 183 box-shadow: 0 20px 60px rgba(44,26,14,.12); 184} 185.pr-card.featured { 186 border-color: var(--copper); 187 box-shadow: 0 8px 40px rgba(181,114,42,.2); 188 transform: translateY(-8px); 189} 190.pr-card.featured:hover { 191 transform: translateY(-14px); 192 box-shadow: 0 28px 70px rgba(181,114,42,.28); 193} 194.pr-card-badge { 195 position: absolute; top: -1px; right: 24px; 196 background: linear-gradient(135deg, var(--copper), var(--copper-light)); 197 color: white; font-size: .68rem; font-weight: 700; 198 letter-spacing: .1em; text-transform: uppercase; 199 padding: 6px 14px; border-radius: 0 0 8px 8px; 200} 201.pr-card-header { padding: 30px 30px 22px; border-bottom: 1px solid var(--pr-border); } 202.pr-card.featured .pr-card-header { 203 background: linear-gradient(160deg, var(--espresso) 0%, var(--espresso-mid) 100%); 204 border-bottom-color: rgba(255,255,255,.1); 205} 206.pr-plan-name { 207 font-family: 'Playfair Display', serif; 208 font-size: 1.4rem; font-weight: 700; 209 color: var(--espresso); margin-bottom: 5px; 210} 211.pr-card.featured .pr-plan-name { color: var(--cream); } 212.pr-plan-tag { font-size: .82rem; color: var(--muted); margin-bottom: 18px; } 213.pr-card.featured .pr-plan-tag { color: rgba(250,246,239,.6); } 214.pr-price-row { display: flex; align-items: flex-end; gap: 4px; } 215.pr-price-currency { font-size: 1.1rem; font-weight: 600; color: var(--copper); padding-bottom: 6px; } 216.pr-card.featured .pr-price-currency { color: var(--copper-pale); } 217.pr-price-amount { 218 font-family: 'Playfair Display', serif; 219 font-size: 3rem; font-weight: 700; line-height: 1; 220 color: var(--espresso); transition: all .3s; 221} 222.pr-card.featured .pr-price-amount { color: var(--cream); } 223.pr-price-per { font-size: .8rem; color: var(--muted); padding-bottom: 8px; }
224.pr-card.featured .pr-price-per { color: rgba(250,246,239,.5); } 225.pr-price-note { font-size: .75rem; color: var(--copper); margin-top: 6px; font-weight: 500; min-height: 18px; } 226.pr-card.featured .pr-price-note { color: var(--copper-pale); } 227 228/* ââ FEATURES ââ */ 229.pr-card-body { padding: 26px 30px; } 230.pr-feat-list { 231 list-style: none; display: flex; flex-direction: column; gap: 13px; margin-bottom: 28px; 232} 233.pr-feat-item { display: flex; align-items: center; gap: 12px; font-size: .88rem; color: var(--espresso); } 234.pr-feat-item.locked { color: #B8A898; } 235.feat-icon { 236 width: 20px; height: 20px; border-radius: 50%; 237 display: flex; align-items: center; justify-content: center; 238 flex-shrink: 0; font-size: .65rem; 239} 240.feat-icon.check { background: linear-gradient(135deg, #4CAF50, #45A049); color: white; } 241.feat-icon.x { background: var(--pr-border); color: #B8A898; } 242.feat-icon.copper { background: linear-gradient(135deg, var(--copper), var(--copper-light)); color: white; } 243.feat-label { flex: 1; } 244.feat-value { font-weight: 600; color: var(--copper); font-size: .82rem; white-space: nowrap; margin-left: auto; text-align: right; } 245.feat-na { font-size: .78rem; color: #C0B0A0; white-space: nowrap; margin-left: auto; text-align: right; } 246.feat-highlight { 247 background: rgba(181,114,42,.1); color: var(--copper); 248 font-size: .7rem; font-weight: 600; 249 padding: 2px 8px; border-radius: 4px; letter-spacing: .04em; 250} 251 252/* ââ CTA BUTTONS (design.md §4 â pill, solid fill, no transform on hover) ââ */ 253.pr-cta { 254 width: 100%; padding: 14px 22px; border-radius: 999px; 255 font-family: var(--wuc-font-body); font-size: .92rem; font-weight: 500; 256 cursor: pointer; transition: background .15s ease-out, border-color .15s ease-out, color .15s ease-out; 257 border: none; letter-spacing: 0; text-align: center; display: block; 258 text-decoration: none; 259} 260.pr-cta-free { background: transparent; border: 1px solid var(--wuc-border-strong); color: var(--muted); } 261.pr-cta-free:hover { border-color: var(--copper); color: var(--copper); background: rgba(232,122,53,0.06); } 262.pr-cta-pro { 263 background: var(--wuc-primary); 264 color: #fff; border: 1px solid var(--wuc-primary); 265 box-shadow: inset 0 1px 0 rgba(255,255,255,0.12); 266} 267.pr-cta-pro:hover { background: var(--wuc-primary-hover); border-color: var(--wuc-primary-hover); } 268.pr-cta-pro:active { background: var(--wuc-primary-press); border-color: var(--wuc-primary-press); box-shadow: none; } 269.pr-cta-trial-link { 270 display: block; 271 width: 100%; 272 margin-top: 8px; 273 padding: 8px 12px; 274 background: transparent; 275 border: 0; 276 border-radius: 8px; 277 font: inherit; 278 font-size: .82rem; 279 font-weight: 500; 280 color: var(--copper); 281 text-align: center; 282 cursor: pointer; 283 text-decoration: underline; 284 text-underline-offset: 3px; 285} 286.pr-cta-trial-link:hover { color: var(--copper-pale, var(--copper)); background: rgba(232,122,53,0.06); } 287.pr-cta-trial-link[disabled] { opacity: .5; cursor: progress; } 288.pr-cta-current { 289 background: transparent; border: 1px solid rgba(232,122,53,.4); 290 color: var(--copper); cursor: default; opacity: .8; 291} 292 293/* ââ COMPARE TABLE ââ */ 294.pr-compare-section { max-width: 960px; margin: 0 auto; padding: 0 24px 72px; } 295.pr-compare-heading { 296 font-family: 'Playfair Display', serif; font-size: 1.8rem; font-weight: 700; 297 text-align: center; color: var(--espresso); margin-bottom: 28px; 298} 299.pr-compare-heading em { font-style: italic; color: var(--copper); } 300.pr-compare-table { 301 width: 100%; border-collapse: collapse; background: white; 302 border-radius: 14px; overflow: hidden; 303 box-shadow: 0 4px 24px rgba(44,26,14,.07); 304} 305.pr-compare-table thead tr { background: var(--espresso); } 306.pr-compare-table th { 307 padding: 17px 20px; text-align: left; 308 font-size: .78rem; font-weight: 600; 309 letter-spacing: .06em; text-transform: uppercase; 310 color: rgba(250,246,239,.6); 311} 312.pr-compare-table th:not(:first-child) { text-align: center; } 313.pr-compare-table th.pr-th-featured { color: var(--copper-pale); } 314.pr-compare-table td { 315 padding: 14px 20px; font-size: .86rem; 316 color: var(--espresso); border-bottom: 1px solid var(--cream-dark); 317} 318.pr-compare-table tbody tr:last-child td { border-bottom: none; } 319.pr-compare-table tbody tr:hover { background: var(--cream); } 320.pr-compare-table td:not(:first-child) { text-align: center; font-weight: 600; } 321.pr-compare-table td:nth-last-child(1) { color: var(--copper); } 322.tick { color: #4CAF50; font-size: 1rem; } 323.cross { color: #ccc; font-size: 1rem; } 324 325/* ââ OVERLAY / MODAL ââ */ 326.pr-overlay { 327 display: none; position: fixed; inset: 0; 328 background: rgba(26,16,8,.65); backdrop-filter: blur(4px); 329 z-index: 1000; align-items: flex-start; justify-content: center; 330 padding: 32px 24px; overflow-y: auto; 331} 332.pr-overlay.active { display: flex; } 333.pr-modal { 334 background: var(--white); border-radius: 20px; 335 width: 100%; max-width: 520px; 336 position: relative; flex-shrink: 0; 337 animation: prModalIn .35s cubic-bezier(.34,1.56,.64,1); 338 margin: auto; 339} 340@keyframes prModalIn { 341 from { opacity: 0; transform: scale(.88) translateY(20px); } 342 to { opacity: 1; transform: scale(1) translateY(0); } 343} 344.pr-modal-header { 345 background: linear-gradient(160deg, var(--espresso), var(--espresso-mid)); 346 padding: 26px 30px 22px; border-radius: 20px 20px 0 0; position: relative; 347} 348.pr-modal-close { 349 position: absolute; top: 14px; right: 14px; 350 width: 32px; height: 32px; background: rgba(255,255,255,.1); 351 border: none; border-radius: 50%; color: white; 352 font-size: 1.1rem; cursor: pointer; 353 display: flex; align-items: center; justify-content: center; 354 transition: background .2s; 355}
356.pr-modal-close:hover { background: rgba(255,255,255,.2); } 357.pr-modal-eyebrow { font-size: .7rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--copper-pale); margin-bottom: 7px; } 358.pr-modal-title { font-family: 'Playfair Display', serif; font-size: 1.55rem; font-weight: 700; color: var(--cream); margin-bottom: 3px; } 359.pr-modal-subtitle { font-size: .82rem; color: rgba(250,246,239,.55); } 360.pr-modal-body { padding: 26px 30px; } 361 362/* Steps */ 363.pr-steps { display: flex; align-items: center; margin-bottom: 22px; } 364.pr-step { flex: 1; text-align: center; position: relative; } 365.pr-step:not(:last-child)::after { 366 content: ''; position: absolute; top: 13px; right: 0; 367 width: 100%; height: 2px; background: var(--pr-border); z-index: 0; 368} 369.pr-step:not(:last-child).done::after { background: var(--copper); } 370.pr-step-circle { 371 width: 28px; height: 28px; border-radius: 50%; background: var(--pr-border); 372 color: var(--muted); font-size: .72rem; font-weight: 700; 373 display: flex; align-items: center; justify-content: center; 374 margin: 0 auto 5px; position: relative; z-index: 1; transition: all .3s; 375} 376.pr-step.active .pr-step-circle { background: var(--copper); color: white; box-shadow: 0 0 0 4px rgba(181,114,42,.2); } 377.pr-step.done .pr-step-circle { background: var(--copper); color: white; } 378.pr-step-name { font-size: .65rem; color: var(--muted); font-weight: 500; letter-spacing: .04em; } 379.pr-step.active .pr-step-name { color: var(--copper); font-weight: 600; } 380 381/* Duration cards */ 382.pr-dur-label { font-size: .78rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-bottom: 10px; } 383.pr-dur-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 24px; } 384.pr-dur-card { 385 border: 2px solid var(--pr-border); border-radius: 12px; padding: 16px 14px; 386 cursor: pointer; transition: all .2s; position: relative; text-align: center; 387} 388.pr-dur-card:hover { border-color: var(--copper-light); } 389.pr-dur-card.selected { border-color: var(--copper); background: rgba(181,114,42,.05); } 390.pr-dur-card.selected::after { 391 content: 'â'; position: absolute; top: 8px; right: 10px; 392 width: 18px; height: 18px; background: var(--copper); color: white; 393 border-radius: 50%; font-size: .6rem; 394 display: flex; align-items: center; justify-content: center; font-weight: 700; 395} 396.pr-dur-name { font-family: 'Playfair Display', serif; font-size: 1rem; font-weight: 700; color: var(--espresso); margin-bottom: 3px; } 397.pr-dur-price { font-size: 1.45rem; font-weight: 700; font-family: 'Playfair Display', serif; color: var(--copper); margin-bottom: 2px; } 398.pr-dur-price span { font-size: .75rem; color: var(--muted); font-family: 'DM Sans', sans-serif; font-weight: 400; } 399.pr-dur-save { font-size: .68rem; font-weight: 600; color: #4CAF50; background: rgba(76,175,80,.1); padding: 2px 8px; border-radius: 4px; display: inline-block; margin-top: 3px; } 400.pr-dur-note { font-size: .7rem; color: var(--muted);
400 margin-top: 1px; } 401 402/* Country step */ 403.pr-country-label { font-size: .78rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-bottom: 9px; } 404.pr-country-alert { 405 background: rgba(181,114,42,.08); border: 1px solid rgba(181,114,42,.3); 406 border-radius: 8px; padding: 11px 13px; 407 font-size: .8rem; color: var(--copper); margin-bottom: 12px; 408 display: flex; gap: 8px; align-items: flex-start; line-height: 1.5; 409} 410.pr-country-select { 411 width: 100%; padding: 11px 13px; 412 border: 1.5px solid var(--pr-border); border-radius: 10px; 413 font-family: 'DM Sans', sans-serif; font-size: .9rem; 414 color: var(--espresso); background: white; appearance: none; 415 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 d='M1 1l5 5 5-5' stroke='%237A6248' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E"); 416 background-repeat: no-repeat; background-position: right 13px center; 417 cursor: pointer; margin-bottom: 18px; transition: border-color .2s; 418} 419.pr-country-select:focus { outline: none; border-color: var(--copper); } 420.pr-amount-summary { 421 background: var(--cream); border-radius: 10px; padding: 14px 16px; 422 margin-bottom: 18px; display: flex; justify-content: space-between; align-items: center; 423} 424.pr-amount-label { font-size: .82rem; color: var(--muted); } 425.pr-amount-value { font-family: 'Playfair Display', serif; font-size: 1.45rem; font-weight: 700; color: var(--espresso); } 426.pr-amount-value small { font-family: 'DM Sans', sans-serif; font-size: .75rem; color: var(--muted); font-weight: 400; margin-left: 3px; } 427.pr-currency-note { font-size: .72rem; color: var(--muted); margin-top: 2px; } 428 429/* Detecting */ 430.pr-detecting { font-size: .78rem; color: var(--muted); text-align: center; margin-bottom: 7px; display: none; align-items: center; justify-content: center; gap: 5px; } 431.pr-detecting.show { display: flex; } 432.pr-detect-dot { width: 6px; height: 6px; background: var(--copper); border-radius: 50%; animation: prPulse 1.2s ease-in-out infinite; } 433.pr-detect-dot:nth-child(2) { animation-delay: .2s; } 434.pr-detect-dot:nth-child(3) { animation-delay: .4s; } 435@keyframes prPulse { 0%,80%,100% { opacity:.3; transform:scale(.8); } 40% { opacity:1; transform:scale(1); } } 436 437/* PayPal button container */ 438#pr-paypal-container { min-height: 48px; } 439#pr-paypal-container .pr-paypal-placeholder { 440 width: 100%; background: #FFC439; border: none; border-radius: 10px; 441 padding: 15px; cursor: pointer; font-size: 1rem; font-weight: 700; 442 color: #003087; display: flex; align-items: center; justify-content: center; 443 gap: 10px; box-shadow: 0 4px 16px rgba(255,196,57,.4); transition: all .2s; 444} 445#pr-paypal-container .pr-paypal-placeholder:disabled { opacity: .45; cursor: not-allowed; } 446#pr-paypal-container .pr-paypal-placeholder:not(:disabled):hover { background: #FFB800; transform: translateY(-2px); box-shadow: 0 8px 24px rgba(255,196,57,.5); } 447.pr-paypal-logo .pr-pay { color: #003087; font-size: 1.15rem; font-weight: 800; letter-spacing: -.02em; } 448.pr-paypal-logo .pr-pal { color: #009CDE; font-size: 1.15rem; font-weight: 800; letter-spacing: -.02em; } 449.pr-gateway-loading { text-align: center; padding: 14px; font-size: .82rem; color: var(--muted); } 450.pr-gateway-error { background: rgba(220,38,38,.07); border: 1px solid rgba(220,38,38,.2); color: #dc2626; padding: 11px 14px; border-radius: 8px; font-size: .83rem; margin-bottom: 14px; display: none; } 451.pr-gateway-error.show { display: block; } 452 453/* Proceed button */ 454.pr-proceed-btn { 455 width: 100%; padding: 14px 22px; 456 background: var(--wuc-primary); 457 border: 1px solid var(--wuc-primary); border-radius: 999px; 458 color: white; 459 font-family: var(--wuc-font-body); font-size: .92rem; font-weight: 500; 460 cursor: pointer; 461 transition: background .15s ease-out, border-color .15s ease-out; 462 box-shadow: inset 0 1px 0 rgba(255,255,255,0.12); 463 margin-bottom: 0; 464} 465.pr-proceed-btn:hover { background: var(--wuc-primary-hover); border-color: var(--wuc-primary-hover); } 466.pr-proceed-btn:active { background: var(--wuc-primary-press); border-color: var(--wuc-primary-press); box-shadow: none; } 467.pr-proceed-btn:disabled { opacity: .4;
467 cursor: not-allowed; } 468 469/* Back button */ 470.pr-back-btn { 471 background: none; border: none; padding: 0; 472 font-size: .82rem; font-weight: 600; color: rgba(26,22,18,0.45); 473 cursor: pointer; font-family: var(--font-sans); 474 margin-bottom: 12px; display: inline-flex; align-items: center; gap: 5px; 475 transition: color .18s; 476} 477.pr-back-btn:hover { color: var(--ink); } 478 479/* Billing address form */ 480.pr-billing-form { margin: 12px 0; display: flex; flex-direction: column; gap: 10px; } 481.pr-billing-row { display: flex; flex-direction: column; gap: 4px; } 482.pr-billing-row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; } 483.pr-billing-row2 > div { display: flex; flex-direction: column; gap: 4px; } 484.pr-billing-label { 485 font-size: .72rem; font-weight: 600; color: rgba(26,22,18,0.6); 486 letter-spacing: .3px; text-transform: uppercase; 487} 488.pr-billing-input { 489 font-family: var(--font-sans); font-size: .875rem; color: var(--ink); 490 background: #f9f6f1; border: 1.5px solid #e4ddd5; 491 border-radius: 8px; padding: 7px 11px; outline: none; transition: border-color .2s; 492 width: 100%; box-sizing: border-box; 493} 494.pr-billing-input:focus { border-color: var(--copper); background: #fff; } 495.pr-billing-input::placeholder { color: rgba(26,22,18,0.3); } 496.pr-opt { font-weight: 400; font-size: .7rem; color: rgba(26,22,18,0.4); text-transform: none; letter-spacing: 0; } 497.pr-billing-save-note { 498 font-size: .75rem; color: #16a34a; font-weight: 600; 499 min-height: 18px; margin-bottom: 4px; 500} 501 502/* 4-step progress */ 503.pr-steps { display: flex; align-items: center; gap: 0; margin-bottom: 24px; } 504.pr-step { display: flex; flex-direction: column; align-items: center; gap: 4px; flex: 1; position: relative; } 505.pr-step + .pr-step::before { 506 content: ''; position: absolute; top: 13px; right: 50%; left: -50%; 507 height: 2px; background: #e8e2d9; z-index: 0; 508} 509.pr-step.done + .pr-step::before { background: var(--copper); } 510 511/* Success */ 512.pr-success-modal { 513 background: white; border-radius: 20px; 514 width: 100%; max-width: 440px; 515 padding: 44px 34px; text-align: center; 516 animation: prModalIn .4s cubic-bezier(.34,1.56,.64,1); 517} 518.pr-success-icon { 519 width: 72px; height: 72px; 520 background: linear-gradient(135deg, var(--copper), var(--copper-light)); 521 border-radius: 50%; display: flex; align-items: center; justify-content: center; 522 margin: 0 auto 22px; font-size: 2rem; 523 box-shadow: 0 8px 32px rgba(181,114,42,.35); 524 animation: prPop .5s .2s cubic-bezier(.34,1.56,.64,1) both; 525} 526@keyframes prPop { from { transform:scale(0); opacity:0; } to { transform:scale(1); opacity:1; } } 527.pr-success-title { font-family: 'Playfair Display', serif; font-size: 1.8rem; font-weight: 700; color: var(--espresso); margin-bottom: 8px; } 528.pr-success-sub { color: var(--muted); font-size: .9rem; line-height: 1.6; margin-bottom: 24px; } 529.pr-success-name { color: var(--copper); font-weight: 600; } 530.pr-success-perks { background: var(--cream); border-radius: 10px; padding: 14px 16px; text-align: left; margin-bottom: 24px; } 531.pr-success-perks p { font-size: .78rem; color: var(--muted); margin-bottom: 7px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; } 532.pr-perk-row { display: flex; align-items: center; gap: 8px; font-size: .84rem; color: var(--espresso); margin-top: 7px; } 533.pr-perk-icon { color: var(--copper); } 534.pr-success-btn { 535 width: 100%; padding: 14px 22px; 536 background: var(--wuc-primary); 537 border: 1px solid var(--wuc-primary); border-radius: 999px; 538 color: white; 539 font-family: var(--wuc-font-body); font-size: .92rem; font-weight: 500; 540 cursor: pointer; 541 transition: background .15s ease-out, border-color .15s ease-out; 542 box-shadow: inset 0 1px 0 rgba(255,255,255,0.12); 543} 544.pr-success-btn:hover { background: var(--wuc-primary-hover); border-color: var(--wuc-primary-hover); } 545.pr-success-btn:active { background: var(--wuc-primary-press); border-color: var(--wuc-primary-press); box-shadow: none; } 546 547/* Spinner */ 548.pr-spinner { 549 display: inline-block; width: 16px; height: 16px; 550 border: 2px solid rgba(255,255,255,.4); border-top-color: white; 551 border-radius: 50%; animation: prSpin .7s linear infinite; 552} 553@keyframes prSpin { to { transform:rotate(360deg); } } 554 555/* FAQ */ 556.pr-faq-section { max-width: 680px; margin: 0 auto; padding: 0 24px 72px; } 557.pr-faq-heading { font-family: 'Playfair Display', serif; font-size: 1.6rem; font-weight: 700; text-align: center; color: var(--espresso); margin-bottom: 28px; } 558.pr-faq-item { border-bottom: 1px solid var(--pr-border); padding: 15px 0; } 559.pr-faq-q { font-weight: 600; font-size: .9rem; color: var(--espresso); cursor: pointer; display: flex; justify-content: space-between; align-items: center; } 560.pr-faq-q::after { content: '+'; font-size: 1.2rem; color: var(--copper); transition: transform .2s; } 561.pr-faq-item.open .pr-faq-q::after { transform: rotate(45deg); } 562.pr-faq-a { font-size: .84rem; color: var(--muted); line-height: 1.6; max-height: 0; overflow: hidden; transition: max-height .3s ease, padding .2s; } 563.pr-faq-item.open .pr-faq-a { max-height: 200px; padding-top: 10px; } 564 565/* Footer */ 566.pr-footer { background: var(--espresso); padding: 24px 40px; text-align: center; color: rgba(250,246,239,.4); font-size: .78rem; } 567.pr-footer a { color: var(--copper-pale); text-decoration: none; } 568 569@media (max-width: 640px) { 570 .pr-cards-grid { grid-template-columns: 1fr; } 571 .pr-card.featured { transform: none; } 572} 573</style> 574 575<div class="pricing-wrap"> 576 577 578 <!-- HERO --> 579 <section class="pr-hero"> 580 <div class="pr-eyebrow">⦠Membership Plans</div> 581 <h1>
581Write more.<br><em>Reach further.</em></h1> 582 <p>Choose the plan that fits your creative ambitions. Upgrade anytime â no friction, no lock-in.</p> 583 </section> 584 585 <!-- BILLING TOGGLE (hidden while a quota offer is active â locked to the $18/yr annual offer) --> 586 <div class="pr-toggle-wrap"> 587 <span class="pr-toggle-label" id="pr-lbl-monthly">Monthly</span> 588 <div class="pr-toggle-sw on" id="pr-billing-toggle" onclick="prToggleBilling()"></div> 589 <span class="pr-toggle-label active" id="pr-lbl-annual">Annual</span> 590 <span class="pr-save-badge">Save 50%</span> 591 </div> 592 593 594 <!-- PRICING CARDS --> 595 <section class="pr-section"> 596 <div class="pr-cards-grid"> 597 <div class="pr-card"> 598 599 <div class="pr-card-header"> 600 <div class="pr-plan-name">Free</div> 601 <div class="pr-plan-tag">Basic access to WriteUpCafe</div> 602 603 <div class="pr-price-row"> 604 <span class="pr-price-currency"></span> 605 <span class="pr-price-amount" 606 data-monthly="0" 607 data-annual="0" 608 id="pr-price-1"> 609 0 </span> 610 <span class="pr-price-per"> / forever</span> 611 </div> 612 613 </div> 614 615 <div class="pr-card-body"> 616 <ul class="pr-feat-list"> 617 <li class="pr-feat-item"> 618 <span class="feat-icon check">â</span> <span class="feat-label">Writeups per month</span> 619 <span class="feat-value">5</span> </li> 620 <li class="pr-feat-item"> 621 <span class="feat-icon check">â</span> <span class="feat-label">Series</span> 622 <span class="feat-value">2</span> </li> 623 <li class="pr-feat-item"> 624 <span class="feat-icon check">â</span> <span class="feat-label">Blogs</span> 625 <span class="feat-value">1</span> </li> 626 <li class="pr-feat-item"> 627 <span class="feat-icon check">â</span> <span class="feat-label">Free SEO tools</span> 628 <span class="feat-value">All 29</span> </li> 629 <li class="pr-feat-item locked"> 630 <span class="feat-icon x">â</span> <span class="feat-label">In-editor AI (headline/meta/FAQ)</span> 631 <span class="feat-na">Not available</span> </li> 632 <li class="pr-feat-item"> 633 <span class="feat-icon check">â</span> <span class="feat-label">Analytics</span> 634 <span class="feat-value">Basic</span> </li> 635 <li class="pr-feat-item locked"> 636 <span class="feat-icon x">â</span> <span class="feat-label">Schedule posts + series progress</span> 637 <span class="feat-na">Not available</span> </li> 638 <li class="pr-feat-item locked"> 639 <span class="feat-icon x">â</span> <span class="feat-label">FAQ schema + alt-text auto-gen</span> 640 <span class="feat-na">Not available</span> </li> 641 <li class="pr-feat-item locked"> 642 <span class="feat-icon x">â</span> <span class="feat-label">Chat with fellow authors</span> 643 <span class="feat-na">Not available</span> </li> 644 <li class="pr-feat-item"> 645 <span class="feat-icon check">â</span> <span class="feat-label">Public author profile + blog listing</span> 646 </li> 647 <li class="pr-feat-item"> 648 <span class="feat-icon check">â</span> <span class="feat-label">Community discovery (topics & tags)</span> 649 </li> 650 <li class="pr-feat-item locked"> 651 <span class="feat-icon x">â</span> <span class="feat-label">Priority support + Pro badge</span>
652 <span class="feat-na">Not available</span> </li> 653 </ul> 654 655 <span class="pr-cta pr-cta-current">⦠Current Plan</span> 656 </div> 657 </div> 658 <div class="pr-card featured"> 659 <div class="pr-card-badge">Most Popular</div> 660 661 <div class="pr-card-header"> 662 <div class="pr-plan-name">Pro</div> 663 <div class="pr-plan-tag">Unlimited writing, analytics, and more</div> 664 665 <div class="pr-price-row"> 666 <span class="pr-price-currency">$</span> 667 <span class="pr-price-amount" 668 data-monthly="5" 669 data-annual="2.50" 670 id="pr-price-2"> 671 2.50 </span> 672 <span class="pr-price-per"> / month</span> 673 </div> 674 675 <div class="pr-price-note" id="pr-note-2">$30 billed annually</div> 676 </div> 677 678 <div class="pr-card-body"> 679 <ul class="pr-feat-list"> 680 <li class="pr-feat-item"> 681 <span class="feat-icon copper">â</span> <span class="feat-label">Writeups per month</span> 682 <span class="feat-value">Unlimited</span> </li> 683 <li class="pr-feat-item"> 684 <span class="feat-icon copper">â</span> <span class="feat-label">Series</span> 685 <span class="feat-value">Unlimited</span> </li> 686 <li class="pr-feat-item"> 687 <span class="feat-icon copper">â</span> <span class="feat-label">Blogs</span> 688 <span class="feat-value">Unlimited</span> </li> 689 <li class="pr-feat-item"> 690 <span class="feat-icon copper">â</span> <span class="feat-label">Free SEO tools</span> 691 <span class="feat-value">All 29</span> </li> 692 <li class="pr-feat-item"> 693 <span class="feat-icon copper">â</span> <span class="feat-label">In-editor AI (headline/meta/FAQ)</span> 694 <span class="feat-value">All 6 (50 runs / tool / mo)</span> </li> 695 <li class="pr-feat-item"> 696 <span class="feat-icon copper">â</span> <span class="feat-label">Analytics</span> 697 <span class="feat-value">Full + reader insights</span> </li> 698 <li class="pr-feat-item"> 699 <span class="feat-icon copper">â</span> <span class="feat-label">Schedule posts + series progress</span> 700 </li> 701 <li class="pr-feat-item"> 702 <span class="feat-icon copper">â</span> <span class="feat-label">FAQ schema + alt-text auto-gen</span> 703 </li> 704 <li class="pr-feat-item"> 705 <span class="feat-icon copper">â</span> <span class="feat-label">Chat with fellow authors</span> 706 <span class="feat-value">Unlimited</span> </li> 707 <li class="pr-feat-item"> 708 <span class="feat-icon copper">â</span> <span class="feat-label">Public author profile + blog listing</span> 709 </li> 710 <li class="pr-feat-item"> 711 <span class="feat-icon copper">â</span> <span class="feat-label">Community discovery (topics & tags)</span> 712 </li> 713 <li class="pr-feat-item"> 714 <span class="feat-icon copper">â</span> <span class="feat-label">Priority support + Pro badge</span> 715 </li> 716 </ul> 717 718 <button class="pr-cta pr-cta-pro" 719 onclick="prOpenModal(2)" 720 data-guest> 721 ⦠Upgrade to Pro </button> 722 </div> 723 </div> 724 </div> 725 </section> 726 727 <!-- COMPARISON TABLE --> 728 <section class="pr-compare-section"> 729 <h2 class="pr-compare-heading">Side-by-side <em>comparison</em></h2> 730 <table class="pr-compare-table"> 731 <thead> 732 <tr> 733 <th>Feature</th> 734 <th class=""> 735 Free </th> 736 <th class="pr-th-featured"> 737 Pro ⦠</th> 738 </tr> 739 </thead> 740 <tbody> 741 <tr> 742 <td>Writeups per month</td> 743 <td>5</td> 744 <td>Unlimited</td> 745 </tr> 746 <tr> 747 <td>Series</td> 748 <td>2</td> 749 <td>Unlimited</td> 750 </tr> 751 <tr> 752 <td>Blogs</td> 753 <td>1</td> 754 <td>Unlimited</td> 755 </tr> 756 <tr> 757 <td>Free SEO tools</td> 758 <td>All 29</td> 759 <td>All 29</td> 760 </tr> 761 <tr> 762 <td>In-editor AI (headline/meta/FAQ)</td> 763 <td><span class="cross">â</span></td> 764 <td>All 6 (50 runs / tool / mo)</td> 765 </tr> 766 <tr> 767 <td>Analytics</td> 768 <td>Basic</td> 769 <td>Full + reader insights</td> 770 </tr> 771 <tr> 772 <td>Schedule posts + series progress</td> 773 <td><span class="cross">â</span></td> 774 <td><span class="tick">â</span></td> 775 </tr> 776 <tr> 777 <td>FAQ schema + alt-text auto-gen</td> 778 <td><span class="cross">â</span></td> 779 <td><span class="tick">â</span></td> 780 </tr> 781 <tr> 782 <td>Chat with fellow authors</td> 783 <td><span class="cross">â</span></td> 784 <td>Unlimited</td> 785 </tr> 786 <tr> 787 <td>Public author profile + blog listing</td> 788 <td><span class="tick">â</span></td> 789 <td><span class="tick">â</span></td> 790 </tr> 791 <tr> 792 <td>Community discovery (topics & tags)</td> 793 <td><span class="tick">â</span></td> 794 <td><span class="tick">â</span></td> 795 </tr> 796 <tr> 797 <td>Priority support + Pro badge</td> 798 <td><span class="cross">â</span></td> 799 <td><span class="tick">â</span></td> 800 </tr> 801 </tbody> 802 </table> 803 </section> 804 805 <!-- FAQ --> 806 <section class="pr-faq-section"> 807 <h2 class="pr-faq-heading">Frequently asked</h2> 808 <div class="pr-faq-item"> 809 <div class="pr-faq-q" onclick="prToggleFaq(this)">Can I switch from monthly to annual later?</div> 810 <div class="pr-faq-a">Yes! You can switch billing cycles anytime from your account settings. We'll prorate any remaining balance automatically.</div> 811 </div> 812 <div class="pr-faq-item"> 813 <div class="pr-faq-q" onclick="prToggleFaq(this)">Is my payment secure?</div> 814 <div class="pr-faq-a">Absolutely. All payments are processed via PayPal's secure infrastru
814cture. We never store your payment details on our servers.</div> 815 </div> 816 <div class="pr-faq-item"> 817 <div class="pr-faq-q" onclick="prToggleFaq(this)">What happens to my content if I downgrade?</div> 818 <div class="pr-faq-a">Your content is always safe. If you exceed the free tier limits after downgrading, content over the limit will be archived (not deleted) until you upgrade again.</div> 819 </div> 820 <div class="pr-faq-item"> 821 <div class="pr-faq-q" onclick="prToggleFaq(this)">Can I cancel anytime?</div> 822 <div class="pr-faq-a">Yes â no strings attached. Cancel from your dashboard at any time, and Pro features remain active until the end of your billing period.</div> 823 </div> 824 <div class="pr-faq-item"> 825 <div class="pr-faq-q" onclick="prToggleFaq(this)">Which payment methods are accepted?</div> 826 <div class="pr-faq-a">We accept all major payment methods via PayPal, including credit cards, debit cards, and PayPal balance. The payment gateway is automatically selected based on your country for the best experience.</div> 827 </div> 828 </section> 829 830<!-- ââââââââââââââââââââââââââââââââââââââââââââââââââââââ 831 MODAL OVERLAY 832ââââââââââââââââââââââââââââââââââââââââââââââââââââââ --> 833<div class="pr-overlay" id="pr-overlay"> 834 835 <!-- STEP 1: Choose billing cycle --> 836 <div class="pr-modal" id="pr-modal-step1"> 837 <div class="pr-modal-header"> 838 <button class="pr-modal-close" onclick="prCloseModal()">â</button> 839 <div class="pr-modal-eyebrow">⦠Upgrade Plan</div> 840 <div class="pr-modal-title">Choose your plan</div> 841 <div class="pr-modal-subtitle">Pick the billing cycle that works for you</div> 842 </div> 843 <div class="pr-modal-body"> 844 <div class="pr-steps"> 845 <div class="pr-step active"><div class="pr-step-circle">1</div><div class="pr-step-name">Plan</div></div> 846 <div class="pr-step" ><div class="pr-step-circle">2</div><div class="pr-step-name">Payment</div></div> 847 <div class="pr-step" ><div class="pr-step-circle">3</div><div class="pr-step-name">Done</div></div> 848 </div> 849 850 <div class="pr-dur-label">Select billing cycle</div> 851 <div class="pr-dur-cards"> 852 <div class="pr-dur-card" id="pr-dur-monthly" onclick="prSelectDuration('monthly')"> 853 <div class="pr-dur-name">Monthly</div> 854 <div class="pr-dur-price" id="pr-modal-monthly-price">â<span>/mo</span></div> 855 <div class="pr-dur-note">Billed monthly</div> 856 </div> 857 <div class="pr-dur-card selected" id="pr-dur-annual" onclick="prSelectDuration('annual')"> 858 <div class="pr-dur-name">Annual</div> 859 <div class="pr-dur-price" id="pr-modal-annual-price">â<span>/mo</span></div> 860 <div class="pr-dur-save" id="pr-modal-annual-save"></div> 861 <div class="pr-dur-note" id="pr-modal-annual-note">â</div> 862 </div> 863 </div> 864 865 866 <button class="pr-proceed-btn" onclick="prGoToPayment()">Continue to Payment â</button> 867 </div> 868 </div> 869 870 <!-- STEP 2: Country detection --> 871 <div class="pr-modal" id="pr-modal-step2" style="display:none"> 872 <div class="pr-modal-header"> 873 <button class="pr-modal-close" onclick="prCloseModal()">â</button> 874 <div class="pr-modal-eyebrow">⦠Upgrade Plan</div> 875 <div class="pr-modal-title">Your location</div> 876 <div class="pr-modal-subtitle" id="pr-pay-subtitle"></div> 877 </div> 878 <div class="pr-modal-body"> 879 <div class="pr-steps"> 880 <div class="pr-step done" ><div class="pr-step-circle">â</div><div class="pr-step-name">Plan</div></div> 881 <div class="pr-step active"><div class="pr-step-circle">2</div><div class="pr-step-name">Location</div></div> 882 <div class="pr-step" ><div class="pr-step-circle">3</div><div class="pr-step-name">Billing</div></div> 883 <div class="pr-step" ><div class="pr-step-circle">4</div><div class="pr-step-name">Done</div></div> 884 </div> 885 886 <div class="pr-country-label">Your billing country</div> 887 <div class="pr-country-alert">
888 <span>â ï¸</span> 889 <span>Please ensure the selected country matches your PayPal account's registered country for a smooth payment experience.</span> 890 </div> 891 892 <div class="pr-detecting" id="pr-detecting"> 893 <div class="pr-detect-dot"></div> 894 <div class="pr-detect-dot"></div> 895 <div class="pr-detect-dot"></div> 896 <span>Detecting your locationâ¦</span> 897 </div> 898 899 <select class="pr-country-select" id="pr-country-select" onchange="prOnCountryChange()"> 900 <option value="">â Select your country â</option> 901 <option value="AF" data-currency="USD" data-symbol="$" data-rate="1">Afghanistan</option> 902 <option value="AX" data-currency="USD" data-symbol="$" data-rate="1">Aland Islands</option> 903 <option value="AL" data-currency="USD" data-symbol="$" data-rate="1">Albania</option> 904 <option value="DZ" data-currency="USD" data-symbol="$" data-rate="1">Algeria</option> 905 <option value="AS" data-currency="USD" data-symbol="$" data-rate="1">American Samoa</option> 906 <option value="AD" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Andorra</option> 907 <option value="AO" data-currency="USD" data-symbol="$" data-rate="1">Angola</option> 908 <option value="AI" data-currency="USD" data-symbol="$" data-rate="1">Anguilla</option> 909 <option value="AQ" data-currency="USD" data-symbol="$" data-rate="1">Antarctica</option> 910 <option value="AG" data-currency="USD" data-symbol="$" data-rate="1">Antigua and Barbuda</option> 911 <option value="AR" data-currency="USD" data-symbol="$" data-rate="1">Argentina</option> 912 <option value="AM" data-currency="USD" data-symbol="$" data-rate="1">Armenia</option> 913 <option value="AW" data-currency="USD" data-symbol="$" data-rate="1">Aruba</option> 914 <option value="AU" data-currency="AUD" data-symbol="A$" data-rate="1.53">Australia</option> 915 <option value="AT" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Austria</option> 916 <option value="AZ" data-currency="USD" data-symbol="$" data-rate="1">Azerbaijan</option> 917 <option value="BS" data-currency="USD" data-symbol="$" data-rate="1">Bahamas</option> 918 <option value="BH" data-currency="USD" data-symbol="$" data-rate="1">Bahrain</option> 919 <option value="BD" data-currency="BDT" data-symbol="à§³" data-rate="110">Bangladesh</option> 920 <option value="BB" data-currency="USD" data-symbol="$" data-rate="1">Barbados</option> 921 <option value="BY" data-currency="USD" data-symbol="$" data-rate="1">Belarus</option> 922 <option value="BE" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Belgium</option> 923 <option value="BZ" data-currency="USD" data-symbol="$" data-rate="1">Belize</option> 924 <option value="BJ" data-currency="USD" data-symbol="$" data-rate="1">Benin</option> 925 <option value="BM" data-currency="USD" data-symbol="$" data-rate="1">Bermuda</option> 926 <option value="BT" data-currency="USD" data-symbol="$" data-rate="1">Bhutan</option> 927 <option value="BO" data-currency="USD" data-symbol="$" data-rate="1">Bolivia</option> 928 <option value="BQ" data-currency="USD" data-symbol="$" data-rate="1">Bonaire, Saint Eustatius and Saba</option> 929 <option value="BA" data-currency="USD" data-symbol="$" data-rate="1">Bosnia and Herzegovina</option> 930 <option value="BW" data-currency="USD" data-symbol="$" data-rate="1">Botswana</option> 931 <option value="BV" data-currency="USD" data-symbol="$" data-rate="1">Bouvet Island</option> 932 <option value="BR" data-currency="BRL" data-symbol="R$" data-rate="4.97">Brazil</option> 933 <option value="IO" data-currency="USD" data-symbol="$" data-rate="1">British Indian Ocean Territory</option> 934 <option value="VG" data-currency="USD" data-symbol
934="$" data-rate="1">British Virgin Islands</option> 935 <option value="BN" data-currency="USD" data-symbol="$" data-rate="1">Brunei</option> 936 <option value="BG" data-currency="USD" data-symbol="$" data-rate="1">Bulgaria</option> 937 <option value="BF" data-currency="USD" data-symbol="$" data-rate="1">Burkina Faso</option> 938 <option value="BI" data-currency="USD" data-symbol="$" data-rate="1">Burundi</option> 939 <option value="CV" data-currency="USD" data-symbol="$" data-rate="1">Cabo Verde</option> 940 <option value="KH" data-currency="USD" data-symbol="$" data-rate="1">Cambodia</option> 941 <option value="CM" data-currency="USD" data-symbol="$" data-rate="1">Cameroon</option> 942 <option value="CA" data-currency="CAD" data-symbol="CA$" data-rate="1.36">Canada</option> 943 <option value="KY" data-currency="USD" data-symbol="$" data-rate="1">Cayman Islands</option> 944 <option value="CF" data-currency="USD" data-symbol="$" data-rate="1">Central African Republic</option> 945 <option value="TD" data-currency="USD" data-symbol="$" data-rate="1">Chad</option> 946 <option value="CL" data-currency="USD" data-symbol="$" data-rate="1">Chile</option> 947 <option value="CN" data-currency="CNY" data-symbol="Â¥" data-rate="7.24">China</option> 948 <option value="CX" data-currency="USD" data-symbol="$" data-rate="1">Christmas Island</option> 949 <option value="CC" data-currency="USD" data-symbol="$" data-rate="1">Cocos Islands</option> 950 <option value="CO" data-currency="USD" data-symbol="$" data-rate="1">Colombia</option> 951 <option value="KM" data-currency="USD" data-symbol="$" data-rate="1">Comoros</option> 952 <option value="CK" data-currency="USD" data-symbol="$" data-rate="1">Cook Islands</option> 953 <option value="CR" data-currency="USD" data-symbol="$" data-rate="1">Costa Rica</option> 954 <option value="HR" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Croatia</option> 955 <option value="CU" data-currency="USD" data-symbol="$" data-rate="1">Cuba</option> 956 <option value="CW" data-currency="USD" data-symbol="$" data-rate="1">Curacao</option> 957 <option value="CY" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Cyprus</option> 958 <option value="CZ" data-currency="USD" data-symbol="$" data-rate="1">Czechia</option> 959 <option value="CD" data-currency="USD" data-symbol="$" data-rate="1">Democratic Republic of the Congo</option> 960 <option value="DK" data-currency="DKK" data-symbol="kr" data-rate="6.89">Denmark</option> 961 <option value="DJ" data-currency="USD" data-symbol="$" data-rate="1">Djibouti</option> 962 <option value="DM" data-currency="USD" data-symbol="$" data-rate="1">Dominica</option> 963 <option value="DO" data-currency="USD" data-symbol="$" data-rate="1">Dominican Republic</option> 964 <option value="EC" data-currency="USD" data-symbol="$" data-rate="1">Ecuador</option> 965 <option value="EG" data-currency="USD" data-symbol="$" data-rate="1">Egypt</option> 966 <option value="SV" data-currency="USD" data-symbol="$" data-rate="1">El Salvador</option> 967 <option value="GQ" data-currency="USD" data-symbol="$" data-rate="1">Equatorial Guinea</option> 968 <option value="ER" data-currency="USD" data-symbol="$" data-rate="1">Eritrea</option> 969 <option value="EE" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Estonia</option> 970 <option value="SZ" data-currency="USD" data-symbol="$" data-rate="1">Eswatini</option> 971 <option value="ET" data-currency="USD" data-symbol="$" data-rate="1">Ethiopia</option> 972 <option value="FK" data-currency="USD" data-symbol="$" data-rate="1">Falkland Islands</option> 973 <option value="FO" data-currency="USD" data-symbol
973="$" data-rate="1">Faroe Islands</option> 974 <option value="FJ" data-currency="USD" data-symbol="$" data-rate="1">Fiji</option> 975 <option value="FI" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Finland</option> 976 <option value="FR" data-currency="EUR" data-symbol="â¬" data-rate="0.92">France</option> 977 <option value="GF" data-currency="USD" data-symbol="$" data-rate="1">French Guiana</option> 978 <option value="PF" data-currency="USD" data-symbol="$" data-rate="1">French Polynesia</option> 979 <option value="TF" data-currency="USD" data-symbol="$" data-rate="1">French Southern Territories</option> 980 <option value="GA" data-currency="USD" data-symbol="$" data-rate="1">Gabon</option> 981 <option value="GM" data-currency="USD" data-symbol="$" data-rate="1">Gambia</option> 982 <option value="GE" data-currency="USD" data-symbol="$" data-rate="1">Georgia</option> 983 <option value="DE" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Germany</option> 984 <option value="GH" data-currency="USD" data-symbol="$" data-rate="1">Ghana</option> 985 <option value="GI" data-currency="USD" data-symbol="$" data-rate="1">Gibraltar</option> 986 <option value="GR" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Greece</option> 987 <option value="GL" data-currency="USD" data-symbol="$" data-rate="1">Greenland</option> 988 <option value="GD" data-currency="USD" data-symbol="$" data-rate="1">Grenada</option> 989 <option value="GP" data-currency="USD" data-symbol="$" data-rate="1">Guadeloupe</option> 990 <option value="GU" data-currency="USD" data-symbol="$" data-rate="1">Guam</option> 991 <option value="GT" data-currency="USD" data-symbol="$" data-rate="1">Guatemala</option> 992 <option value="GG" data-currency="USD" data-symbol="$" data-rate="1">Guernsey</option> 993 <option value="GN" data-currency="USD" data-symbol="$" data-rate="1">Guinea</option> 994 <option value="GW" data-currency="USD" data-symbol="$" data-rate="1">Guinea-Bissau</option> 995 <option value="GY" data-currency="USD" data-symbol="$" data-rate="1">Guyana</option> 996 <option value="HT" data-currency="USD" data-symbol="$" data-rate="1">Haiti</option> 997 <option value="HM" data-currency="USD" data-symbol="$" data-rate="1">Heard Island and McDonald Islands</option> 998 <option value="HN" data-currency="USD" data-symbol="$" data-rate="1">Honduras</option> 999 <option value="HK" data-currency="USD" data-symbol="$" data-rate="1">Hong Kong</option> 1000 <option value="HU" data-currency="USD" data-symbol="$" data-rate="1">Hungary</option> 1001 <option value="IS" data-currency="USD" data-symbol="$" data-rate="1">Iceland</option> 1002 <option value="IN" data-currency="INR" data-symbol="â¹" data-rate="83.5">India</option> 1003 <option value="ID" data-currency="IDR" data-symbol="Rp" data-rate="15800">Indonesia</option> 1004 <option value="IR" data-currency="USD" data-symbol="$" data-rate="1">Iran</option> 1005 <option value="IQ" data-currency="USD" data-symbol="$" data-rate="1">Iraq</option> 1006 <option value="IE" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Ireland</option> 1007 <option value="IM" data-currency="USD" data-symbol="$" data-rate="1">Isle of Man</option> 1008 <option value="IL" data-currency="ILS" data-symbol="âª" data-rate="3.72">Israel</option> 1009 <option value="IT" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Italy</option> 1010 <option value="CI" data-currency="USD" data-symbol="$" data-rate="1">Ivory Coast</option> 1011 <option value="JM" data-currency="USD" data-symbol="$" data-rate="1">Jamaica</option> 1012 <option value="JP" data-currency="JPY" data-symbol="Â¥" data-rate="149">Japan</option> 1013 <option value="JE" data-currency="USD" data-symbol
1013="$" data-rate="1">Jersey</option> 1014 <option value="JO" data-currency="USD" data-symbol="$" data-rate="1">Jordan</option> 1015 <option value="KZ" data-currency="USD" data-symbol="$" data-rate="1">Kazakhstan</option> 1016 <option value="KE" data-currency="KES" data-symbol="KSh" data-rate="130">Kenya</option> 1017 <option value="KI" data-currency="USD" data-symbol="$" data-rate="1">Kiribati</option> 1018 <option value="XK" data-currency="USD" data-symbol="$" data-rate="1">Kosovo</option> 1019 <option value="KW" data-currency="USD" data-symbol="$" data-rate="1">Kuwait</option> 1020 <option value="KG" data-currency="USD" data-symbol="$" data-rate="1">Kyrgyzstan</option> 1021 <option value="LA" data-currency="USD" data-symbol="$" data-rate="1">Laos</option> 1022 <option value="LV" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Latvia</option> 1023 <option value="LB" data-currency="USD" data-symbol="$" data-rate="1">Lebanon</option> 1024 <option value="LS" data-currency="USD" data-symbol="$" data-rate="1">Lesotho</option> 1025 <option value="LR" data-currency="USD" data-symbol="$" data-rate="1">Liberia</option> 1026 <option value="LY" data-currency="USD" data-symbol="$" data-rate="1">Libya</option> 1027 <option value="LI" data-currency="CHF" data-symbol="Fr" data-rate="0.9">Liechtenstein</option> 1028 <option value="LT" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Lithuania</option> 1029 <option value="LU" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Luxembourg</option> 1030 <option value="MO" data-currency="USD" data-symbol="$" data-rate="1">Macao</option> 1031 <option value="MG" data-currency="USD" data-symbol="$" data-rate="1">Madagascar</option> 1032 <option value="MW" data-currency="USD" data-symbol="$" data-rate="1">Malawi</option> 1033 <option value="MY" data-currency="MYR" data-symbol="RM" data-rate="4.72">Malaysia</option> 1034 <option value="MV" data-currency="USD" data-symbol="$" data-rate="1">Maldives</option> 1035 <option value="ML" data-currency="USD" data-symbol="$" data-rate="1">Mali</option> 1036 <option value="MT" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Malta</option> 1037 <option value="MH" data-currency="USD" data-symbol="$" data-rate="1">Marshall Islands</option> 1038 <option value="MQ" data-currency="USD" data-symbol="$" data-rate="1">Martinique</option> 1039 <option value="MR" data-currency="USD" data-symbol="$" data-rate="1">Mauritania</option> 1040 <option value="MU" data-currency="USD" data-symbol="$" data-rate="1">Mauritius</option> 1041 <option value="YT" data-currency="USD" data-symbol="$" data-rate="1">Mayotte</option> 1042 <option value="MX" data-currency="MXN" data-symbol="MX$" data-rate="17.1">Mexico</option> 1043 <option value="FM" data-currency="USD" data-symbol="$" data-rate="1">Micronesia</option> 1044 <option value="MD" data-currency="USD" data-symbol="$" data-rate="1">Moldova</option> 1045 <option value="MC" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Monaco</option> 1046 <option value="MN" data-currency="USD" data-symbol="$" data-rate="1">Mongolia</option> 1047 <option value="ME" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Montenegro</option> 1048 <option value="MS" data-currency="USD" data-symbol="$" data-rate="1">Montserrat</option> 1049 <option value="MA" data-currency="USD" data-symbol="$" data-rate="1">Morocco</option> 1050 <option value="MZ" data-currency="USD" data-symbol="$" data-rate="1">Mozambique</option> 1051 <option value="MM" data-currency="USD" data-symbol="$" data-rate="1">Myanmar</option> 1052 <option value="NA" data-currency="USD" data-symbol="$" data-rate="1">Namibia</option> 1053 <option value="NR" data-currency="AUD" data-symbol
1053="A$" data-rate="1.53">Nauru</option> 1054 <option value="NP" data-currency="USD" data-symbol="$" data-rate="1">Nepal</option> 1055 <option value="AN" data-currency="USD" data-symbol="$" data-rate="1">Netherlands Antilles</option> 1056 <option value="NC" data-currency="USD" data-symbol="$" data-rate="1">New Caledonia</option> 1057 <option value="NZ" data-currency="NZD" data-symbol="NZ$" data-rate="1.63">New Zealand</option> 1058 <option value="NI" data-currency="USD" data-symbol="$" data-rate="1">Nicaragua</option> 1059 <option value="NE" data-currency="USD" data-symbol="$" data-rate="1">Niger</option> 1060 <option value="NG" data-currency="NGN" data-symbol="â¦" data-rate="1600">Nigeria</option> 1061 <option value="NU" data-currency="USD" data-symbol="$" data-rate="1">Niue</option> 1062 <option value="NF" data-currency="USD" data-symbol="$" data-rate="1">Norfolk Island</option> 1063 <option value="KP" data-currency="USD" data-symbol="$" data-rate="1">North Korea</option> 1064 <option value="MK" data-currency="USD" data-symbol="$" data-rate="1">North Macedonia</option> 1065 <option value="MP" data-currency="USD" data-symbol="$" data-rate="1">Northern Mariana Islands</option> 1066 <option value="NO" data-currency="NOK" data-symbol="kr" data-rate="10.6">Norway</option> 1067 <option value="OM" data-currency="USD" data-symbol="$" data-rate="1">Oman</option> 1068 <option value="PK" data-currency="PKR" data-symbol="â¨" data-rate="278">Pakistan</option> 1069 <option value="PW" data-currency="USD" data-symbol="$" data-rate="1">Palau</option> 1070 <option value="PS" data-currency="USD" data-symbol="$" data-rate="1">Palestinian Territory</option> 1071 <option value="PA" data-currency="USD" data-symbol="$" data-rate="1">Panama</option> 1072 <option value="PG" data-currency="USD" data-symbol="$" data-rate="1">Papua New Guinea</option> 1073 <option value="PY" data-currency="USD" data-symbol="$" data-rate="1">Paraguay</option> 1074 <option value="PE" data-currency="USD" data-symbol="$" data-rate="1">Peru</option> 1075 <option value="PH" data-currency="PHP" data-symbol="â±" data-rate="56.5">Philippines</option> 1076 <option value="PN" data-currency="USD" data-symbol="$" data-rate="1">Pitcairn</option> 1077 <option value="PL" data-currency="PLN" data-symbol="zÅ" data-rate="4.01">Poland</option> 1078 <option value="PT" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Portugal</option> 1079 <option value="PR" data-currency="USD" data-symbol="$" data-rate="1">Puerto Rico</option> 1080 <option value="QA" data-currency="USD" data-symbol="$" data-rate="1">Qatar</option> 1081 <option value="CG" data-currency="USD" data-symbol="$" data-rate="1">Republic of the Congo</option> 1082 <option value="RE" data-currency="USD" data-symbol="$" data-rate="1">Reunion</option> 1083 <option value="RO" data-currency="USD" data-symbol="$" data-rate="1">Romania</option> 1084 <option value="RU" data-currency="RUB" data-symbol="â½" data-rate="91">Russia</option> 1085 <option value="RW" data-currency="USD" data-symbol="$" data-rate="1">Rwanda</option> 1086 <option value="BL" data-currency="USD" data-symbol="$" data-rate="1">Saint Barthelemy</option> 1087 <option value="SH" data-currency="USD" data-symbol="$" data-rate="1">Saint Helena</option> 1088 <option value="KN" data-currency="USD" data-symbol="$" data-rate="1">Saint Kitts and Nevis</option> 1089 <option value="LC" data-currency="USD" data-symbol="$" data-rate="1">Saint Lucia</option> 1090 <option value="MF" data-currency="USD" data-symbol="$" data-rate="1">Saint Martin</option> 1091 <option value="PM" data-currency="USD" data-symbol="$" data-rate="1">Saint Pierre and Miquelon</option> 1092 <option value="VC" data-currency="USD" data-symbol
1092="$" data-rate="1">Saint Vincent and the Grenadines</option> 1093 <option value="WS" data-currency="USD" data-symbol="$" data-rate="1">Samoa</option> 1094 <option value="SM" data-currency="EUR" data-symbol="â¬" data-rate="0.92">San Marino</option> 1095 <option value="ST" data-currency="USD" data-symbol="$" data-rate="1">Sao Tome and Principe</option> 1096 <option value="SA" data-currency="SAR" data-symbol="ï·¼" data-rate="3.75">Saudi Arabia</option> 1097 <option value="SN" data-currency="USD" data-symbol="$" data-rate="1">Senegal</option> 1098 <option value="RS" data-currency="USD" data-symbol="$" data-rate="1">Serbia</option> 1099 <option value="CS" data-currency="USD" data-symbol="$" data-rate="1">Serbia and Montenegro</option> 1100 <option value="SC" data-currency="USD" data-symbol="$" data-rate="1">Seychelles</option> 1101 <option value="SL" data-currency="USD" data-symbol="$" data-rate="1">Sierra Leone</option> 1102 <option value="SG" data-currency="SGD" data-symbol="S$" data-rate="1.35">Singapore</option> 1103 <option value="SX" data-currency="USD" data-symbol="$" data-rate="1">Sint Maarten</option> 1104 <option value="SK" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Slovakia</option> 1105 <option value="SI" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Slovenia</option> 1106 <option value="SB" data-currency="USD" data-symbol="$" data-rate="1">Solomon Islands</option> 1107 <option value="SO" data-currency="USD" data-symbol="$" data-rate="1">Somalia</option> 1108 <option value="ZA" data-currency="ZAR" data-symbol="R" data-rate="18.6">South Africa</option> 1109 <option value="GS" data-currency="USD" data-symbol="$" data-rate="1">South Georgia and the South Sandwich Islands</option> 1110 <option value="KR" data-currency="USD" data-symbol="$" data-rate="1">South Korea</option> 1111 <option value="SS" data-currency="USD" data-symbol="$" data-rate="1">South Sudan</option> 1112 <option value="ES" data-currency="EUR" data-symbol="â¬" data-rate="0.92">Spain</option> 1113 <option value="LK" data-currency="USD" data-symbol="$" data-rate="1">Sri Lanka</option> 1114 <option value="SD" data-currency="USD" data-symbol="$" data-rate="1">Sudan</option> 1115 <option value="SR" data-currency="USD" data-symbol="$" data-rate="1">Suriname</option> 1116 <option value="SJ" data-currency="USD" data-symbol="$" data-rate="1">Svalbard and Jan Mayen</option> 1117 <option value="SE" data-currency="SEK" data-symbol="kr" data-rate="10.4">Sweden</option> 1118 <option value="CH" data-currency="CHF" data-symbol="Fr" data-rate="0.9">Switzerland</option> 1119 <option value="SY" data-currency="USD" data-symbol="$" data-rate="1">Syria</option> 1120 <option value="TW" data-currency="TWD" data-symbol="NT$" data-rate="31.9">Taiwan</option> 1121 <option value="TJ" data-currency="USD" data-symbol="$" data-rate="1">Tajikistan</option> 1122 <option value="TZ" data-currency="USD" data-symbol="$" data-rate="1">Tanzania</option> 1123 <option value="TH" data-currency="THB" data-symbol="฿" data-rate="35.1">Thailand</option> 1124 <option value="NL" data-currency="EUR" data-symbol="â¬" data-rate="0.92">The Netherlands</option> 1125 <option value="TL" data-currency="USD" data-symbol="$" data-rate="1">Timor Leste</option> 1126 <option value="TG" data-currency="USD" data-symbol="$" data-rate="1">Togo</option> 1127 <option value="TK" data-currency="USD" data-symbol="$" data-rate="1">Tokelau</option> 1128 <option value="TO" data-currency="USD" data-symbol="$" data-rate="1">Tonga</option> 1129 <option value="TT" data-currency="USD" data-symbol="$" data-rate="1">Trinidad and Tobago</option> 1130 <option value="TN" data-currency="USD" data-symbol
1130="$" data-rate="1">Tunisia</option> 1131 <option value="TR" data-currency="TRY" data-symbol="âº" data-rate="32.3">Turkey</option> 1132 <option value="TM" data-currency="USD" data-symbol="$" data-rate="1">Turkmenistan</option> 1133 <option value="TC" data-currency="USD" data-symbol="$" data-rate="1">Turks and Caicos Islands</option> 1134 <option value="TV" data-currency="AUD" data-symbol="A$" data-rate="1.53">Tuvalu</option> 1135 <option value="VI" data-currency="USD" data-symbol="$" data-rate="1">U.S. Virgin Islands</option> 1136 <option value="UG" data-currency="USD" data-symbol="$" data-rate="1">Uganda</option> 1137 <option value="UA" data-currency="UAH" data-symbol="â´" data-rate="39.5">Ukraine</option> 1138 <option value="AE" data-currency="AED" data-symbol="AED" data-rate="3.67">United Arab Emirates</option> 1139 <option value="GB" data-currency="GBP" data-symbol="£" data-rate="0.79">United Kingdom</option> 1140 <option value="US" data-currency="USD" data-symbol="$" data-rate="1">United States</option> 1141 <option value="UM" data-currency="USD" data-symbol="$" data-rate="1">United States Minor Outlying Islands</option> 1142 <option value="UY" data-currency="USD" data-symbol="$" data-rate="1">Uruguay</option> 1143 <option value="UZ" data-currency="USD" data-symbol="$" data-rate="1">Uzbekistan</option> 1144 <option value="VU" data-currency="USD" data-symbol="$" data-rate="1">Vanuatu</option> 1145 <option value="VA" data-currency="USD" data-symbol="$" data-rate="1">Vatican</option> 1146 <option value="VE" data-currency="USD" data-symbol="$" data-rate="1">Venezuela</option> 1147 <option value="VN" data-currency="VND" data-symbol="â«" data-rate="24500">Vietnam</option> 1148 <option value="WF" data-currency="USD" data-symbol="$" data-rate="1">Wallis and Futuna</option> 1149 <option value="EH" data-currency="USD" data-symbol="$" data-rate="1">Western Sahara</option> 1150 <option value="YE" data-currency="USD" data-symbol="$" data-rate="1">Yemen</option> 1151 <option value="ZM" data-currency="USD" data-symbol="$" data-rate="1">Zambia</option> 1152 <option value="ZW" data-currency="USD" data-symbol="$" data-rate="1">Zimbabwe</option> 1153 </select> 1154 1155 <div class="pr-amount-summary" id="pr-amount-summary" style="display:none"> 1156 <div> 1157 <div class="pr-amount-label" id="pr-plan-label-small"></div> 1158 <div class="pr-currency-note" id="pr-currency-note"></div> 1159 </div> 1160 <div class="pr-amount-value" id="pr-display-amount">â</div> 1161 </div> 1162 1163 <button class="pr-proceed-btn" id="pr-continue-billing-btn" 1164 onclick="prGoToBilling()" style="display:none; margin-top:20px;"> 1165 Continue to Billing Details â 1166 </button> 1167 </div> 1168 </div> 1169 1170 <!-- STEP 3: Billing address + payment --> 1171 <div class="pr-modal" id="pr-modal-step3" style="display:none"> 1172 <div class="pr-modal-header" style="padding:20px 28px 16px;"> 1173 <button class="pr-modal-close" onclick="prCloseModal()">â</button> 1174 <div class="pr-modal-eyebrow">⦠Upgrade Plan</div> 1175 <div class="pr-modal-title">Billing details</div> 1176 <div class="pr-modal-subtitle" id="pr-billing-subtitle"></div> 1177 </div> 1178 <div class="pr-modal-body" style="padding:20px 28px 24px;"> 1179 <div class="pr-steps"> 1180 <div class="pr-step done" ><div class="pr-step-circle">â</div><div class="pr-step-name">Plan</div></div> 1181 <div class="pr-step done" ><div class="pr-step-circle">â</div><div class="pr-step-name">Location</div></div> 1182 <div class="pr-step active"><div class="pr-step-circle">3</div><div class="pr-step-name">Billing</div></div> 1183 <div class="pr-step" ><div class="pr-step-circle">4</div><div class="pr-step-name">Done</div></div> 1184 </div> 1185 1186 <button type="button" class="pr-back-btn" onclick="prBackToCountry()">â Back</button> 1187 1188 <div class="pr-billing-form"> 1189 <div class="pr-billing-row full"> 1190 <label class="pr-billing-label">Full name</label> 1191 <input class="pr-billing-input" type="text" id="pr-full-name" 1192 placeholder="As it appears on your payment method" maxlength="120"> 1193 </div> 1194 <div class="pr-billing-row full"> 1195 <label class="pr-billing-label">Address line 1</label> 1196 <input class="pr-billing-input" type="text" id="pr-address1" 1197 placeholder="Street address, P.O. box" maxlength="200"> 1198 </div> 1199 <div class="pr-billing-row full"> 1200 <label class="pr-billing-label">Address line 2 <span class="pr-opt">optional</span></label> 1201 <input class="pr-billing-input" type="text" id="pr-address2" 1202 placeholder="Apartment, suite, unitâ¦" maxlength="200"> 1203 </div> 1204 <div class="pr-billing-row2"> 1205 <div> 1206 <label class="pr-billing-label">City</label> 1207 <input class="pr-billing-input" type="text" id="pr-city" 1208 placeholder="City" maxlength="100"> 1209 </div> 1210 <div> 1211 <label class="pr-billing-label">State / Province</label> 1212 <input class="pr-billing-input" type="text" id="pr-state" 1213 placeholder="State or province" maxlength="100"> 1214 </div> 1215 </div> 1216 <div class="pr-billing-row2"> 1217 <div> 1218 <label class="pr-billing-label">Postal / ZIP code</label> 1219 <input class="pr-billing-input" type="text" id="pr-postal" 1220 placeholder="Postal code" maxlength="20"> 1221 </div> 1222 <div> 1223 <label class="pr-billing-label">Country</label> 1224 <input class="pr-billing-input" type="text" id="pr-country-display" 1225 readonly style="background:rgba(0,0,0,0.04); cursor:not-allowed;"> 1226 </div> 1227 </div> 1228 </div> 1229 1230 <div class="pr-billing-save-note" id="pr-billing-save-note"></div> 1231 1232 <div class="pr-gateway-error" id="pr-gateway-error"></div> 1233 1234 <!-- Payment-method picker: only shown when the country resolves more 1235 than one gateway (India â UPI/Razorpay in â¹ + PayPal in $). --> 1236 <div id="pr-method-block" style="display:none; margin-bottom:14px;"> 1237 <div class="pr-dur-label">Pay with</div> 1238 <div class="pr-dur-cards" style="margin-bottom:0;"> 1239 <div class="pr-dur-card" id="pr-method-razorpay" onclick="prSelectMethod('razorpay')"> 1240 <div class="pr-dur-name">UPI / Cards</div> 1241 <div class="pr-dur-price" id="pr-method-price-inr" style="font-size:1.15rem;"></div> 1242 <div class="pr-dur-note">GPay · PhonePe · Paytm · RuPay</div> 1243 </div> 1244 <div class="pr-dur-card" id="pr-method-paypal" onclick="prSelectMethod('paypal')"> 1245 <div class="pr-dur-name">PayPal</div> 1246 <div class="pr-dur-price" id="pr-method-price-usd" style="font-size:1.15rem;"></div> 1247 <div class="pr-dur-note">PayPal balance · Intl. cards</div> 1248 </div> 1249 </div> 1250 </div> 1251 1252 <div id="pr-paypal-container"> 1253 <button class="pr-paypal-placeholder" id="pr-paypal-placeholder" disabled>
1254 <span style="font-size:.8rem;font-weight:600;color:#003087">Pay with</span> 1255 <span class="pr-paypal-logo"><span class="pr-pay">Pay</span><span class="pr-pal">Pal</span></span> 1256 </button> 1257 </div> 1258 <div id="pr-razorpay-container" style="display:none"> 1259 <button class="pr-proceed-btn" id="pr-razorpay-btn" onclick="prPayWithRazorpay(this)"> 1260 Pay with UPI â 1261 </button> 1262 </div> 1263 <div id="pr-secure-note" style="text-align:center;margin-top:12px;font-size:.72rem;color:var(--muted)"> 1264 ð Secured by PayPal · Your payment info is never stored on our servers. 1265 </div> 1266 </div> 1267 </div> 1268 1269 <!-- SUCCESS --> 1270 <div class="pr-success-modal" id="pr-modal-success" style="display:none"> 1271 <div class="pr-success-icon">ð</div> 1272 <div class="pr-success-title">You're <span id="pr-success-plan-name">Pro</span> now!</div> 1273 <div class="pr-success-sub"> 1274 Congratulations â welcome to the <span class="pr-success-name">WriteUpCafe</span> family. 1275 Your membership is now active and all features are unlocked. 1276 </div> 1277 <div class="pr-success-perks"> 1278 <p>ð Now unlocked for you</p> 1279 <div class="pr-perk-row"><span class="pr-perk-icon">â¦</span> Unlimited writeups & blogs</div> 1280 <div class="pr-perk-row"><span class="pr-perk-icon">â¦</span> Full analytics & post insights</div> 1281 <div class="pr-perk-row"><span class="pr-perk-icon">â¦</span> Boost posts & priority support</div> 1282 <div class="pr-perk-row"><span class="pr-perk-icon">â¦</span> Pro badge on your profile</div> 1283 </div> 1284 <button class="pr-success-btn" onclick="prCloseSuccess()">Start Writing â</button> 1285 </div> 1286 1287</div><!-- /pr-overlay --> 1288 1289</div><!-- /pricing-wrap --> 1290
1291<script> 1292(function () { 1293 'use strict'; 1294 1295 /* ââ Config from PHP âââââââââââââââââââââââââââââââââââââââââââ */ 1296 var PLANS = [{"id":1,"name":"Free","slug":"free","price_monthly":0,"price_yearly":0,"price_monthly_inr":null,"price_yearly_inr":null,"featured":false},{"id":2,"name":"Pro","slug":"pro","price_monthly":5,"price_yearly":30,"price_monthly_inr":399,"price_yearly_inr":2499,"featured":true}]; 1297 var CSRF = "d94fb2079996dbee4e885462012551b5980c5d55e344802d"; 1298 var IS_GUEST = true; 1299 var SAVED_BILLING = null; 1300 var DISPLAY_CURRENCY = "USD"; // 'USD' | 'INR' (IP-geo, server-decided) 1301 var CUR = DISPLAY_CURRENCY === 'INR' ? 'â¹' : '$'; 1302 var GEO_CC = "AM"; // ISO country from request IP, may be null 1303 1304 /* ââ Helpers âââââââââââââââââââââââââââââââââââââââââââââââââââ */ 1305 function fmtPrice(n) { 1306 return n % 1 === 0 ? String(Math.round(n)) : n.toFixed(2); 1307 } 1308 // Display-price accessors: â¹ price points when the page is in INR mode 1309 // (falling back to USD values), otherwise USD. Charged amounts are always 1310 // re-decided server-side at checkout. 1311 function dispMonthly(p) { 1312 return DISPLAY_CURRENCY === 'INR' && p.price_monthly_inr ? p.price_monthly_inr : p.price_monthly; 1313 } 1314 function dispYearly(p) { 1315 return DISPLAY_CURRENCY === 'INR' && p.price_yearly_inr ? p.price_yearly_inr : p.price_yearly; 1316 } 1317 1318 /* ââ State âââââââââââââââââââââââââââââââââââââââââââââââââââââ */ 1319 var isAnnual = true; 1320 var selectedCycle = 'annual'; 1321 var selectedPlanId = 2; 1322 var selectedCountry = ''; 1323 var gatewayClientId = ''; 1324 var gatewayEnv = 'sandbox'; 1325 var paypalLoaded = false; 1326 var paypalRendered = false; 1327 var orderErrorShown = false; 1328 var paypalOpt = null; // paypal entry from resolve-gateway options[] 1329 var razorpayOpt = null; // razorpay entry (only for countries routed to it) 1330 var selectedMethod = 'paypal'; // 'paypal' | 'razorpay' 1331 var razorpayLoaded = false; 1332 var razorpayBusy = false; 1333 1334 /* ââ Method helpers ââââââââââââââââââââââââââââââââââââââââââââ */ 1335 function currentPlan() { 1336 return PLANS.find(function(p){ return p.id === selectedPlanId; }); 1337 } 1338 function planInrPrice() { 1339 var plan = currentPlan(); 1340 if (!plan) return 0; 1341 var v = selectedCycle === 'annual' ? plan.price_yearly_inr : plan.price_monthly_inr; 1342 return v && v > 0 ? v : 0; 1343 } 1344 function planUsdPrice() { 1345 var plan = currentPlan(); 1346 if (!plan) return 0; 1347 return selectedCycle === 'annual' ? plan.price_yearly : plan.price_monthly; 1348 } 1349 function fmtInr(n) { 1350 return 'â¹' + Number(n).toLocaleString('en-IN', { maximumFractionDigits: 0 }); 1351 } 1352 function step3Open() { 1353 return document.getElementById('pr-modal-step3').style.display !== 'none'; 1354 } 1355 1356 /* ââ Billing toggle ââââââââââââââââââââââââââââââââââââââââââââ */ 1357 function prToggleBilling() { 1358 prSelectDuration(isAnnual ? 'monthly' : 'annual'); 1359 } 1360 1361 /* ââ FAQ âââââââââââââââââââââââââââââââââââââââââââââââââââââââ */ 1362 function prToggleFaq(el) { 1363 el.closest('.pr-faq-item').classList.toggle('open'); 1364 } 1365 1366 /* ââ Open modal ââââââââââââââââââââââââââââââââââââââââââââââââ */ 1367 function prOpenModal(planId) { 1368 if (IS_GUEST) { 1369 window.location.href = '/login?next=/pricing'; 1370 return; 1371 } 1372 selectedPlanId = planId || 2; 1373 var plan = PLANS.find(function(p){ return p.id === selectedPlanId; }); 1374 if (!plan) return; 1375 1376 // Populate modal step-1 (display currency: â¹ for India, $ otherwise) 1377 var mPrice = dispMonthly(plan); 1378 var aTotal = dispYearly(plan); 1379 var aPriceMo = aTotal / 12; 1380 var savings = ((mPrice * 12 - aTotal) / (mPrice * 12) * 100).toFixed(0); 1381 1382 document.getElementById('pr-modal-monthly-price').innerHTML = CUR + Math.floor(mPrice) + '<span>/mo</span>'; 1383 document.getElementById('pr-modal-annual-price').innerHTML = CUR + aPriceMo.toFixed(2) + '<span>/mo</span>'; 1384 document.getElementById('pr-modal-annual-save').textContent = 'Save ' + CUR + (mPrice * 12 - aTotal).toFixed(0) + '/year'; 1385 document.getElementById('pr-modal-annual-note').textContent = CUR + aTotal.toFixed(0) + ' billed once'; 1386 1387 prSelectDuration(isAnnual ? 'annual' : 'monthly'); 1388 1389 document.getElementById('pr-modal-step1').style.display = 'block'; 1390 document.getElementById('pr-modal-step2').style.display = 'none'; 1391 document.getElementById('pr-modal-step3').style.display = 'none'; 1392 document.getElementById('pr-modal-success').style.display = 'none'; 1393 document.getElementById('pr-overlay').classList.add('active'); 1394 } 1395 1396 function prCloseModal() { 1397 document.getElementById('pr-overlay').classList.remove('active'); 1398 paypalRendered = false;
1399 } 1400 1401 /* ââ Duration selection (single source of truth for both toggle + modal) */ 1402 function prSelectDuration(type) { 1403 selectedCycle = type; 1404 isAnnual = (type === 'annual'); 1405 1406 // Sync page toggle 1407 var tog = document.getElementById('pr-billing-toggle'); 1408 var lblM = document.getElementById('pr-lbl-monthly'); 1409 var lblA = document.getElementById('pr-lbl-annual'); 1410 if (tog) tog.classList.toggle('on', isAnnual); 1411 if (lblM) lblM.classList.toggle('active', !isAnnual); 1412 if (lblA) lblA.classList.toggle('active', isAnnual); 1413 1414 // Sync page price cards (use data-* attrs set by PHP to avoid rounding drift) 1415 PLANS.forEach(function (p) { 1416 var el = document.getElementById('pr-price-' + p.id); 1417 var noteEl = document.getElementById('pr-note-' + p.id); 1418 if (!el || p.price_monthly === 0) return; 1419 if (isAnnual) { 1420 el.textContent = fmtPrice(dispYearly(p) / 12); 1421 if (noteEl) noteEl.textContent = CUR + fmtPrice(dispYearly(p)) + ' billed annually'; 1422 } else { 1423 el.textContent = fmtPrice(dispMonthly(p)); 1424 if (noteEl) noteEl.innerHTML = ' '; 1425 } 1426 }); 1427 1428 // Sync modal duration cards 1429 var durM = document.getElementById('pr-dur-monthly'); 1430 var durA = document.getElementById('pr-dur-annual'); 1431 if (durM) durM.classList.toggle('selected', type === 'monthly'); 1432 if (durA) durA.classList.toggle('selected', type === 'annual'); 1433 } 1434 1435 /* ââ Go to location/country step ââââââââââââââââââââââââââââââ */ 1436 function prGoToPayment() { 1437 var plan = PLANS.find(function(p){ return p.id === selectedPlanId; }); 1438 if (!plan) return; 1439 1440 var amount = selectedCycle === 'annual' ? dispYearly(plan) : dispMonthly(plan); 1441 var label = plan.name + ' ' + (selectedCycle === 'annual' ? 'Annual' : 'Monthly') + ' Plan'; 1442 1443 document.getElementById('pr-pay-subtitle').textContent = label + ' · ' + CUR + amount.toFixed(0) + (selectedCycle === 'monthly' ? '/month' : ' total'); 1444 document.getElementById('pr-plan-label-small').textContent = label; 1445 document.getElementById('pr-amount-summary').style.display = 'none'; 1446 document.getElementById('pr-continue-billing-btn').style.display = 'none'; 1447 1448 document.getElementById('pr-modal-step1').style.display = 'none'; 1449 document.getElementById('pr-modal-step2').style.display = 'block'; 1450 1451 // Pre-select country from saved billing if available 1452 if (SAVED_BILLING && SAVED_BILLING.country_code) { 1453 var sel = document.getElementById('pr-country-select'); 1454 for (var i = 0; i < sel.options.length; i++) { 1455 if (sel.options[i].value === SAVED_BILLING.country_code) { sel.selectedIndex = i; break; } 1456 } 1457 prOnCountryChange(); 1458 } else { 1459 detectCountry(); 1460 } 1461 } 1462 1463 /* ââ Go to billing details step ââââââââââââââââââââââââââââââââ */ 1464 function prGoToBilling() { 1465 if (!selectedCountry) return; 1466 1467 var plan = PLANS.find(function(p){ return p.id === selectedPlanId; }); 1468 if (!plan) return; 1469 var amount = selectedCycle === 'annual' ? dispYearly(plan) : dispMonthly(plan); 1470 var label = plan.name + ' ' + (selectedCycle === 'annual' ? 'Annual' : 'Monthly') + ' Plan'; 1471 document.getElementById('pr-billing-subtitle').textContent = 1472 label + ' · ' + CUR + amount.toFixed(0) + (selectedCycle === 'monthly' ? '/month' : ' total'); 1473 1474 // Pre-fill country display 1475 var sel = document.getElementById('pr-country-select'); 1476 var opt = sel.options[sel.selectedIndex]; 1477 document.getElementById('pr-country-display').value = opt ? opt.text.trim() : selectedCountry; 1478 1479 // Pre-fill from saved billing or blank 1480 var b = SAVED_BILLING || {}; 1481 document.getElementById('pr-full-name').value = b.full_name || ''; 1482 document.getElementById('pr-address1').value = b.address_line1 || ''; 1483 document.getElementById('pr-address2').value = b.address_line2 || ''; 1484 document.getElementById('pr-city').value = b.city || ''; 1485 document.getElementById('pr-state').value = b.state || ''; 1486 document.getElementById('pr-postal').value = b.postal_code || ''; 1487 1488 document.getElementById('pr-billing-save-note').textContent = ''; 1489 document.getElementById('pr-gateway-error').classList.remove('show'); 1490 1491 document.getElementById('pr-modal-step2').style.display = 'none'; 1492 document.getElementById('pr-modal-step3').style.display = 'block'; 1493 1494 // Show UPI/PayPal picker where applicable; renders the PayPal button 1495 // (already pre-loading from prOnCountryChange) when it's the method. 1496 updatePaymentMethodUI(); 1497 } 1498 1499 /* ââ Back to country step ââââââââââââââââââââââââââââââââââââââ */ 1500 function prBackToCountry() { 1501 document.getElementById('pr-modal-step3').style.display = 'none'; 1502 document.getElementById('pr-modal-step2').style.display = 'block'; 1503 } 1504 1505 /* ââ Detect country via IP âââââââââââââââââââââââââââââââââââââ */ 1506 // Server already resolved the request IP against the local MaxMind db and 1507 // handed us GEO_CC â instant, no third-party call. ipapi.co remains only as 1508 // a fallback for the rare request the local db couldn't place. 1509 function detectCountry() { 1510 var sel = document.getElementById('pr-country-select'); 1511 if (GEO_CC) { 1512 var matched = false;
1513 for (var i = 0; i < sel.options.length; i++) { 1514 if (sel.options[i].value === GEO_CC) { sel.value = GEO_CC; matched = true; break; } 1515 } 1516 if (!matched) sel.value = 'OTHER'; 1517 prOnCountryChange(); 1518 return; 1519 } 1520 var det = document.getElementById('pr-detecting'); 1521 det.classList.add('show'); 1522 fetch('https://ipapi.co/json/') 1523 .then(function(r){ return r.json(); }) 1524 .then(function(d){ 1525 var cc = d.country_code || ''; 1526 var matched = false; 1527 for (var i = 0; i < sel.options.length; i++) { 1528 if (sel.options[i].value === cc) { sel.value = cc; matched = true; break; } 1529 } 1530 if (!matched && cc) sel.value = 'OTHER'; 1531 det.classList.remove('show'); 1532 prOnCountryChange(); 1533 }) 1534 .catch(function(){ det.classList.remove('show'); }); 1535 } 1536 1537 /* ââ Country changed âââââââââââââââââââââââââââââââââââââââââââ */ 1538 function prOnCountryChange() { 1539 var sel = document.getElementById('pr-country-select'); 1540 var opt = sel.options[sel.selectedIndex]; 1541 var plan = PLANS.find(function(p){ return p.id === selectedPlanId; }); 1542 1543 if (!opt || !opt.value || !plan) { 1544 document.getElementById('pr-amount-summary').style.display = 'none'; 1545 document.getElementById('pr-continue-billing-btn').style.display = 'none'; 1546 return; 1547 } 1548 1549 selectedCountry = opt.value; 1550 if (DISPLAY_CURRENCY === 'INR' && opt.value === 'IN' && planInrPrice()) { 1551 // India in INR mode: show the REAL chargeable â¹ price point, not an FX 1552 // conversion of the USD price (â¹399 â $5Ãrate â it's a fixed price). 1553 document.getElementById('pr-display-amount').innerHTML = 1554 fmtInr(planInrPrice()) + ' <small>INR</small>'; 1555 document.getElementById('pr-currency-note').textContent = 1556 'Charged in INR via UPI/cards, or in USD via PayPal · ' 1557 + (selectedCycle === 'annual' ? 'one-time annual charge' : 'recurring monthly'); 1558 } else { 1559 var currency = opt.dataset.currency || 'USD'; 1560 var symbol = opt.dataset.symbol || '$'; 1561 var rate = parseFloat(opt.dataset.rate || '1'); 1562 var baseAmt = selectedCycle === 'annual' ? plan.price_yearly : plan.price_monthly; 1563 var converted = (baseAmt * rate).toFixed(2); 1564 1565 document.getElementById('pr-display-amount').innerHTML = 1566 symbol + Number(converted).toLocaleString() + ' <small>' + currency + '</small>'; 1567 document.getElementById('pr-currency-note').textContent = 1568 'Informational · charged in USD · ' 1569 + (selectedCycle === 'annual' ? 'one-time annual charge' : 'recurring monthly'); 1570 } 1571 document.getElementById('pr-amount-summary').style.display = 'flex'; 1572 document.getElementById('pr-continue-billing-btn').style.display = 'block'; 1573 1574 // Start loading the PayPal SDK in the background so it's ready by the time user fills billing 1575 resolveGatewayInBackground(selectedCountry); 1576 } 1577 1578 /* ââ Resolve gateway options + pre-load SDKs in background âââââ */ 1579 function resolveGatewayInBackground(country) { 1580 paypalRendered = false; 1581 paypalOpt = null; 1582 razorpayOpt = null; 1583 1584 fetch('/pricing/resolve-gateway?country=' + encodeURIComponent(country)) 1585 .then(function(r){ return r.json(); }) 1586 .then(function(d){ 1587 if (!d.ok) { 1588 showGatewayError(d.error || 'Payment gateway not available. Please contact support.'); 1589 return; 1590 } 1591 1592 var options = d.options || []; 1593 // Legacy response shape (no options[]) â synthesize a PayPal option 1594 if (!options.length && d.client_id) { 1595 options = [{ method: 'paypal', client_id: d.client_id, environment: d.environment || 'sandbox' }]; 1596 } 1597 options.forEach(function(o){ 1598 if (o.method === 'razorpay' && !razorpayOpt) razorpayOpt = o; 1599 if (o.method === 'paypal' && !paypalOpt) paypalOpt = o; 1600 }); 1601 1602 // UPI needs an INR price point for the selected plan; without one the 1603 // page quietly behaves as PayPal-only. 1604 if (razorpayOpt && planInrPrice()) { 1605 selectedMethod = 'razorpay'; 1606 loadRazorpaySDK(); 1607 updateCurrencyNoteForUpi(); 1608 } else { 1609 razorpayOpt = null; 1610 selectedMethod = 'paypal'; 1611 } 1612 1613 if (!paypalOpt || !paypalOpt.client_id) { 1614 if (!razorpayOpt) { 1615 showGatewayError(d.error || 'Payment gateway not available. Please contact support.'); 1616 return; 1617 } 1618 paypalOpt = null; // unconfigured PayPal â offer UPI alone 1619 } else if (window.paypal && paypalOpt.client_id === gatewayClientId) { 1620 // Same gateway already loaded â render only if step 3 is open 1621 gatewayEnv = paypalOpt.environment || 'sandbox'; 1622 if (step3Open() && selectedMethod === 'paypal') renderPayPalButton(); 1623 } else { 1624 gatewayClientId = paypalOpt.client_id;
1625 gatewayEnv = paypalOpt.environment || 'sandbox'; 1626 loadPayPalSDK(gatewayClientId); 1627 } 1628 1629 if (step3Open()) updatePaymentMethodUI(); 1630 }) 1631 .catch(function(){ 1632 showGatewayError('Could not load payment gateway. Please try again.'); 1633 }); 1634 } 1635 1636 /* ââ Payment-method picker (UPI vs PayPal) âââââââââââââââââââââ */ 1637 function updatePaymentMethodUI() { 1638 var block = document.getElementById('pr-method-block'); 1639 var rzWrap = document.getElementById('pr-razorpay-container'); 1640 var ppWrap = document.getElementById('pr-paypal-container'); 1641 var note = document.getElementById('pr-secure-note'); 1642 var hasUpi = !!(razorpayOpt && planInrPrice()); 1643 1644 // Keep the step-3 subtitle honest about what will actually be charged 1645 var plan = currentPlan(); 1646 if (plan) { 1647 var label = plan.name + ' ' + (selectedCycle === 'annual' ? 'Annual' : 'Monthly') + ' Plan'; 1648 var sub = document.getElementById('pr-billing-subtitle'); 1649 if (sub) sub.textContent = label + ' · ' 1650 + (hasUpi && selectedMethod === 'razorpay' ? fmtInr(planInrPrice()) : '$' + planUsdPrice().toFixed(0)) 1651 + (selectedCycle === 'monthly' ? '/month' : ' total'); 1652 } 1653 1654 if (!hasUpi) { 1655 block.style.display = 'none'; 1656 rzWrap.style.display = 'none'; 1657 ppWrap.style.display = ''; 1658 if (note) note.textContent = 'ð Secured by PayPal · Your payment info is never stored on our servers.'; 1659 if (paypalLoaded && !paypalRendered) renderPayPalButton(); 1660 return; 1661 } 1662 1663 block.style.display = ''; 1664 document.getElementById('pr-method-price-inr').textContent = fmtInr(planInrPrice()); 1665 document.getElementById('pr-method-price-usd').textContent = '$' + fmtPrice(planUsdPrice()); 1666 document.getElementById('pr-method-razorpay').classList.toggle('selected', selectedMethod === 'razorpay'); 1667 document.getElementById('pr-method-paypal').classList.toggle('selected', selectedMethod === 'paypal'); 1668 document.getElementById('pr-method-paypal').style.display = paypalOpt ? '' : 'none'; 1669 1670 if (selectedMethod === 'razorpay') { 1671 rzWrap.style.display = ''; 1672 ppWrap.style.display = 'none'; 1673 document.getElementById('pr-razorpay-btn').textContent = 'Pay ' + fmtInr(planInrPrice()) + ' · UPI / Cards â'; 1674 if (note) note.textContent = 'ð Secured by Razorpay · UPI, cards, netbanking & wallets.'; 1675 } else { 1676 rzWrap.style.display = 'none'; 1677 ppWrap.style.display = ''; 1678 if (note) note.textContent = 'ð Secured by PayPal · Your payment info is never stored on our servers.'; 1679 if (paypalLoaded && !paypalRendered) renderPayPalButton(); 1680 } 1681 } 1682 1683 function prSelectMethod(m) { 1684 selectedMethod = m; 1685 document.getElementById('pr-gateway-error').classList.remove('show'); 1686 updatePaymentMethodUI(); 1687 } 1688 1689 // Step-2 note says "charged in USD" â once UPI is on the table that's only 1690 // half the story, so upgrade it as soon as the options are known. 1691 function updateCurrencyNoteForUpi() { 1692 var inr = planInrPrice(); 1693 if (!inr) return; 1694 var el = document.getElementById('pr-currency-note'); 1695 if (el) el.textContent = 'Pay ' + fmtInr(inr) + ' by UPI/cards, or in USD via PayPal · ' 1696 + (selectedCycle === 'annual' ? 'one-time annual charge' : 'recurring monthly'); 1697 } 1698 1699 function showGatewayError(msg) { 1700 var errEl = document.getElementById('pr-gateway-error'); 1701 errEl.textContent = msg; 1702 errEl.classList.add('show'); 1703 document.getElementById('pr-paypal-container').innerHTML = 1704 '<button class="pr-paypal-placeholder" disabled>' 1705 + '<span style="font-size:.8rem;font-weight:600;color:#003087">Pay with</span>' 1706 + '<span class="pr-paypal-logo"><span class="pr-pay">Pay</span><span class="pr-pal">Pal</span></span>' 1707 + '</button>'; 1708 } 1709 1710 /* ââ Load PayPal SDK âââââââââââââââââââââââââââââââââââââââââââ */ 1711 function loadPayPalSDK(clientId) { 1712 // Remove previous SDK script if any 1713 var old = document.getElementById('pr-paypal-sdk'); 1714 if (old) old.remove(); 1715 1716 // Use a unique namespace so multiple SDK loads don't collide 1717 var ns = 'paypalSdk_' + Date.now(); 1718 1719 var script = document.createElement('script'); 1720 script.id = 'pr-paypal-sdk'; 1721 script.src = 'https://www.paypal.com/sdk/js?client-id=' 1722 + encodeURIComponent(clientId) 1723 + '¤cy=USD&intent=capture'; 1724 script.setAttribute('data-namespace', ns); 1725 script.onload = function () { 1726 paypalLoaded = true; 1727 // Expose the namespaced instance as window.paypal for renderPayPalButton 1728 if (window[ns]) window.paypal = window[ns]; 1729 // Only render if the user has reached the billing step 1730 if (document.getElementById('pr-modal-step3').style.display !== 'none') { 1731 renderPayPalButton(); 1732 } 1733 }; 1734 script.onerror = function () { 1735 showGatewayError('Failed to load PayPal. Please refresh and try again.'); 1736 }; 1737 document.head.appendChild(script); 1738 } 1739 1740 /* ââ Razorpay (UPI/cards, INR) âââââââââââââââââââââââââââââââââ */ 1741 function loadRazorpaySDK() { 1742 if (razorpayLoaded || document.getElementById('pr-razorpay-sdk')) return; 1743 var s = document.createElement('script'); 1744 s.id = 'pr-razorpay-sdk';
1745 s.src = 'https://checkout.razorpay.com/v1/checkout.js'; 1746 s.onload = function(){ razorpayLoaded = true; }; 1747 s.onerror = function(){ showPayError('Could not load the UPI checkout. Please refresh and try again.'); }; 1748 document.head.appendChild(s); 1749 } 1750 1751 // Error box only â unlike showGatewayError this never clobbers the PayPal 1752 // button container, so a UPI failure leaves the PayPal fallback intact. 1753 function showPayError(msg) { 1754 var errEl = document.getElementById('pr-gateway-error'); 1755 errEl.textContent = msg; 1756 errEl.classList.add('show'); 1757 } 1758 1759 function prPayWithRazorpay(btn) { 1760 if (razorpayBusy || !razorpayOpt) return; 1761 if (!window.Razorpay) { 1762 loadRazorpaySDK(); 1763 showPayError('UPI checkout is still loading â try again in a moment.'); 1764 return; 1765 } 1766 razorpayBusy = true; 1767 var orig = btn.textContent; 1768 btn.disabled = true; 1769 btn.textContent = 'Preparing your orderâ¦'; 1770 document.getElementById('pr-gateway-error').classList.remove('show'); 1771 1772 var resetBtn = function () { 1773 razorpayBusy = false; 1774 btn.disabled = false; 1775 btn.textContent = orig; 1776 }; 1777 1778 // Save billing address first (best-effort, same as the PayPal flow) 1779 var billingBody = new URLSearchParams({ 1780 _token: CSRF, 1781 full_name: document.getElementById('pr-full-name').value, 1782 address_line1: document.getElementById('pr-address1').value, 1783 address_line2: document.getElementById('pr-address2').value, 1784 city: document.getElementById('pr-city').value, 1785 state: document.getElementById('pr-state').value, 1786 postal_code: document.getElementById('pr-postal').value, 1787 country_code: selectedCountry, 1788 }); 1789 fetch('/settings/billing/ajax', { method: 'POST', body: billingBody }) 1790 .then(function(r){ return r.json(); }) 1791 .then(function(b){ 1792 if (b.ok) { 1793 CSRF = b.token; 1794 SAVED_BILLING = { 1795 full_name: document.getElementById('pr-full-name').value, 1796 address_line1: document.getElementById('pr-address1').value, 1797 address_line2: document.getElementById('pr-address2').value, 1798 city: document.getElementById('pr-city').value, 1799 state: document.getElementById('pr-state').value, 1800 postal_code: document.getElementById('pr-postal').value, 1801 country_code: selectedCountry, 1802 }; 1803 document.getElementById('pr-billing-save-note').textContent = 'â Billing address saved'; 1804 } 1805 return fetch('/pricing/create-order', { 1806 method: 'POST', 1807 headers: { 'Content-Type': 'application/json' }, 1808 body: JSON.stringify({ 1809 csrf: CSRF, 1810 planId: selectedPlanId, 1811 billingCycle: selectedCycle, 1812 countryCode: selectedCountry, 1813 method: 'razorpay', 1814 }), 1815 }); 1816 }) 1817 .then(function(r){ return r.json(); }) 1818 .then(function(d){ 1819 if (!d.ok) { 1820 if (d.redirect) { window.location.href = d.redirect; return; } 1821 showPayError(d.error || 'Order creation failed. Please try again.'); 1822 resetBtn(); 1823 return; 1824 } 1825 var rzOrderId = d.orderID; 1826 var rzFailed = false; // popup reported payment.failed at least once 1827 var rzSettled = false; // activation confirmed (verify or status poll) 1828 var rzPolling = false; 1829 1830 // Checkout breadcrumbs â payment_funnel_events (monitoring only). 1831 var rzLog = function (ev, detail) { 1832 try { 1833 fetch('/pricing/razorpay-event', { 1834 method: 'POST', keepalive: true, 1835 headers: { 'Content-Type': 'application/json' }, 1836 body: JSON.stringify({ csrf: CSRF, event: ev, order_id: rzOrderId, 1837 country: selectedCountry, detail: detail || '' }), 1838 }).catch(function(){}); 1839 } catch (e) {} 1840 }; 1841 1842 var rzShowActivated = function (planName) { 1843 if (rzSettled) return; 1844 rzSettled = true; 1845 document.getElementById('pr-gateway-error').classList.remove('show'); 1846 document.getElementById('pr-success-plan-name').textContent = planName || 'Pro'; 1847 ['pr-modal-step1', 'pr-modal-step2', 'pr-modal-step3'].forEach(function (id) { 1848 document.getElementById(id).style.display = 'none'; 1849 }); 1850 document.getElementById('pr-modal-success').style.display = 'block'; 1851 document.getElementById('pr-overlay').classList.add('active'); 1852 }; 1853 1854 // Late authorization: the bank can confirm a payment the popup already 1855 // reported as failed, and Razorpay then auto-captures it. Ask the 1856 // server (which asks Razorpay) for ~3 min so the buyer isn't left 1857 // believing they lost the money â and doesn't pay twice. 1858 var rzPollDelays = [3, 5, 7, 10, 15, 20, 30, 40, 50]; 1859 var rzStartPolling = function () { 1860 if (rzPolling || rzSettled) return; 1861 rzPolling = true; 1862 var step = function (n) { 1863 if (rzSettled) return; 1864 if (n >= rzPollDelays.length) { 1865 showPayError('We haven\'t had confirmation from your bank yet. If money was deducted, please don\'t pay again: your Pro will activate automatically within 15 minutes and you\'ll get a confirmation email.'); 1866 return; 1867 } 1868 setTimeout(function () { 1869 if (rzSettled) return; 1870 fetch('/pricing/razorpay-status', { 1871 method: 'POST', 1872 headers: { 'Content-Type': 'application/json' }, 1873 body: JSON.stringify({ csrf: CSRF, razorpay_order_id: rzOrderId }), 1874 }) 1875 .then(function(r){ return r.json(); }) 1876 .then(function(sd){ 1877 if (sd.ok && sd.state === 'paid') { rzShowActivated(sd.plan); return; } 1878 step(n + 1); 1879 }) 1880 .catch(function(){ step(n + 1); }); 1881 }, rzPollDelays[n] * 1000); 1882 }; 1883 step(0); 1884 }; 1885 1886 var rz = new window.Razorpay({ 1887 key: d.key, 1888 order_id: d.orderID, 1889 amount: d.amount, 1890 currency: d.currency, 1891 name: 'WriteUpCafe', 1892 description: d.description, 1893 prefill: d.prefill || {}, 1894 theme: { color: '#e87a35' }, 1895 modal: { ondismiss: function(){ 1896 rzLog('dismiss', rzFailed ? 'after_failure' : ''); 1897 resetBtn(); 1898 } },
1899 handler: function (resp) { 1900 rzLog('success', resp.razorpay_payment_id); 1901 btn.textContent = 'Activating your subscriptionâ¦'; 1902 fetch('/pricing/checkout', { 1903 method: 'POST', 1904 headers: { 'Content-Type': 'application/json' }, 1905 body: JSON.stringify({ 1906 csrf: CSRF, 1907 method: 'razorpay', 1908 razorpay_order_id: resp.razorpay_order_id, 1909 razorpay_payment_id: resp.razorpay_payment_id, 1910 razorpay_signature: resp.razorpay_signature, 1911 planId: selectedPlanId, 1912 billingCycle: selectedCycle, 1913 countryCode: selectedCountry, 1914 }), 1915 }) 1916 .then(function(r){ return r.json(); }) 1917 .then(function(cd){ 1918 if (cd.ok) { 1919 rzShowActivated(cd.plan); 1920 } else { 1921 rzLog('verify_error', cd.error || ''); 1922 showPayError(cd.error || 'Payment verification failed. If money was deducted it will be reconciled automatically.'); 1923 resetBtn(); 1924 rzStartPolling(); 1925 } 1926 }) 1927 .catch(function(){ 1928 rzLog('verify_error', 'network'); 1929 showPayError('Network error while confirming your payment. If money was deducted it will be reconciled automatically.'); 1930 resetBtn(); 1931 rzStartPolling(); 1932 }); 1933 }, 1934 }); 1935 rz.on('payment.failed', function (resp) { 1936 var e = resp.error || {}; 1937 rzFailed = true; 1938 rzLog('failed', [e.code, e.reason, e.step, e.source, (e.metadata || {}).payment_id, e.description] 1939 .map(function (v) { return v || ''; }).join(' | ')); 1940 showPayError((e.description ? e.description + ' ' : 'Payment failed. ') 1941 + 'If money was deducted from your account, please don\'t pay again: we\'re checking with the bank, and your Pro will activate automatically (usually within a few minutes, at most 15). You\'ll get a confirmation email.'); 1942 rzStartPolling(); 1943 }); 1944 rzLog('open'); 1945 rz.open(); 1946 }) 1947 .catch(function(){ 1948 showPayError('Network error. Please try again.'); 1949 resetBtn(); 1950 }); 1951 } 1952 1953 /* ââ Render PayPal buttons âââââââââââââââââââââââââââââââââââââ */ 1954 function renderPayPalButton() { 1955 if (!window.paypal || paypalRendered) return; 1956 paypalRendered = true; 1957 1958 var container = document.getElementById('pr-paypal-container'); 1959 container.innerHTML = ''; 1960 1961 window.paypal.Buttons({ 1962 style: { layout: 'horizontal', color: 'gold', shape: 'rect', label: 'pay', height: 48 }, 1963 1964 createOrder: function () { 1965 orderErrorShown = false; 1966 // Save billing address first, then create order 1967 var billingBody = new URLSearchParams({ 1968 _token: CSRF, 1969 full_name: document.getElementById('pr-full-name').value, 1970 address_line1:document.getElementById('pr-address1').value, 1971 address_line2:document.getElementById('pr-address2').value, 1972 city: document.getElementById('pr-city').value, 1973 state: document.getElementById('pr-state').value, 1974 postal_code: document.getElementById('pr-postal').value, 1975 country_code: selectedCountry, 1976 }); 1977 return fetch('/settings/billing/ajax', { method: 'POST', body: billingBody }) 1978 .then(function(r){ return r.json(); }) 1979 .then(function(b){ 1980 if (b.ok) { 1981 CSRF = b.token; // refresh CSRF token 1982 // Update SAVED_BILLING cache 1983 SAVED_BILLING = { 1984 full_name: document.getElementById('pr-full-name').value, 1985 address_line1: document.getElementById('pr-address1').value, 1986 address_line2: document.getElementById('pr-address2').value, 1987 city: document.getElementById('pr-city').value, 1988 state: document.getElementById('pr-state').value, 1989 postal_code: document.getElementById('pr-postal').value, 1990 country_code: selectedCountry, 1991 }; 1992 document.getElementById('pr-billing-save-note').textContent = 'â Billing address saved'; 1993 } 1994 // Proceed to create order regardless (billing save is best-effort) 1995 return fetch('/pricing/create-order', { 1996 method: 'POST', 1997 headers: { 'Content-Type': 'application/json' }, 1998 body: JSON.stringify({ 1999 csrf: CSRF, 2000 planId: selectedPlanId, 2001 billingCycle: selectedCycle, 2002 countryCode: selectedCountry, 2003 }), 2004 }); 2005 }) 2006 .then(function(r){ return r.json(); }) 2007 .then(function(d){ 2008 if (!d.ok) { 2009 if (d.redirect) { window.location.href = d.redirect; return Promise.reject(); } 2010 orderErrorShown = true; 2011 showGatewayError(d.error || 'Order creation failed. Please try again.'); 2012 return Promise.reject(new Error(d.error)); 2013 } 2014 return d.orderID; 2015 }); 2016 }, 2017 2018 onApprove: function (data) { 2019 var container = document.getElementById('pr-paypal-container'); 2020 container.innerHTML = '<div class="pr-gateway-loading"><span class="pr-spinner"></span> Activating your subscriptionâ¦</div>'; 2021 2022 return fetch('/pricing/checkout', { 2023 method: 'POST', 2024 headers: { 'Content-Type': 'application/json' }, 2025 body: JSON.stringify({ 2026 csrf: CSRF, 2027 orderID: data.orderID, 2028 planId: selectedPlanId, 2029 billingCycle: selectedCycle, 2030 countryCode: selectedCountry, 2031 }), 2032 }) 2033 .then(function(r){ return r.json(); }) 2034 .then(function(d){ 2035 if (d.ok) { 2036 document.getElementById('pr-success-plan-name').textContent = d.plan || 'Pro'; 2037 document.getElementById('pr-modal-step3').style.display = 'none'; 2038 document.getElementById('pr-modal-success').style.display = 'block'; 2039 } else { 2040 showGatewayError(d.error || 'Payment failed. Please try again.'); 2041 renderPayPalButton(); 2042 } 2043 }); 2044 }, 2045 2046 onCancel: function () { 2047 // User closed PayPal popup â do nothing, let them try again 2048 }, 2049 2050 onError: function (err) { 2051 if (!orderErrorShown) { 2052 showGatewayError('PayPal encountered an error. Please try again.'); 2053 } 2054 paypalRendered = false;
2055 renderPayPalButton(); 2056 }, 2057 }).render('#pr-paypal-container'); 2058 } 2059 2060 /* ââ Close success âââââââââââââââââââââââââââââââââââââââââââââ */ 2061 function prCloseSuccess() { 2062 document.getElementById('pr-overlay').classList.remove('active'); 2063 window.location.href = '/home'; 2064 } 2065 2066 /* ââ Backdrop click ââââââââââââââââââââââââââââââââââââââââââââ */ 2067 document.getElementById('pr-overlay').addEventListener('click', function(e) { 2068 if (e.target === this) prCloseModal(); 2069 }); 2070 2071 /* ââ Initialise display to match PHP-rendered state âââââââââââ */ 2072 prSelectDuration(isAnnual ? 'annual' : 'monthly'); 2073 2074 /* ââ Self-serve trial start (no card) âââââââââââââââââââââââââââ */ 2075 async function prStartTrial(btn) { 2076 if (btn.disabled) return; 2077 btn.disabled = true; 2078 var orig = btn.textContent; 2079 btn.textContent = 'Starting your trialâ¦'; 2080 try { 2081 var meta = document.querySelector('meta[name="csrf-token"]'); 2082 var token = meta ? meta.content : ''; 2083 var fd = new FormData(); 2084 fd.append('_token', token); 2085 var resp = await fetch('/pro-trial/start', { 2086 method: 'POST', 2087 credentials: 'same-origin', 2088 headers: { 'Accept': 'application/json' }, 2089 body: fd 2090 }); 2091 var d = await resp.json(); 2092 if (d.ok) { 2093 // Reload to surface trial_active_early banner above the feed 2094 window.location.href = d.redirect_to || '/'; 2095 return; 2096 } 2097 if (d.code === 'not_logged_in') { window.location.href = d.redirect || '/login'; return; } 2098 btn.textContent = d.error || 'Could not start trial'; 2099 setTimeout(function () { btn.textContent = orig; btn.disabled = false; }, 3500); 2100 } catch (e) { 2101 btn.textContent = 'Network error â try again'; 2102 setTimeout(function () { btn.textContent = orig; btn.disabled = false; }, 3500); 2103 } 2104 } 2105 2106 /* ââ Expose to global scope (used by inline onclick) âââââââââââ */ 2107 window.prToggleBilling = prToggleBilling; 2108 window.prToggleFaq = prToggleFaq; 2109 window.prOpenModal = prOpenModal; 2110 window.prCloseModal = prCloseModal; 2111 window.prSelectDuration = prSelectDuration; 2112 window.prGoToPayment = prGoToPayment; 2113 window.prGoToBilling = prGoToBilling; 2114 window.prBackToCountry = prBackToCountry; 2115 window.prOnCountryChange = prOnCountryChange; 2116 window.prCloseSuccess = prCloseSuccess; 2117 window.prStartTrial = prStartTrial; 2118 window.prSelectMethod = prSelectMethod; 2119 window.prPayWithRazorpay = prPayWithRazorpay; 2120})(); 2121</script>
2121 2122 </div> 2123 <footer class="site-footer"> 2124 <div class="container"> 2125 <div class="footer-links"> 2126 <a href="/about-us">About Us</a> 2127 <a href="/contact">Contact</a> 2128 <a href="/privacy-policy">Privacy Policy</a> 2129 <a href="/refund-policy">Refund Policy</a> 2130 <a href="/terms-of-use">Terms of Use</a> 2131 <a href="/disclaimers">Disclaimers</a> 2132 <a href="/content-ownership">Content Ownership</a> 2133 <a href="/help">Help Center</a> 2134 <a href="/tools">Free SEO Tools</a> 2135 </div> 2136 <div class="footer-copy" style="font-size:12px;color:var(--ink-muted);"> 2137 © 2026 WriteUpCafe. Built for writers & bloggers. 2138 </div> 2139 </div> 2140</footer> 2141
2141<script src="/assets/js/search.js" defer></script>
2141 2142
2142<script src="/assets/js/engage.js" defer></script>
2142 2143
2143<script src="/assets/js/comments.js" defer></script>
2143 2144 <style> 2145/* Scope our own box-sizing + margin/padding reset so pages that don't set 2146 a global reset (e.g. landing.css) don't overflow the modal inputs. */ 2147.cb-btn, .cb-btn *, .cb-btn *::before, .cb-btn *::after, 2148.cb-overlay, .cb-overlay *, .cb-overlay *::before, .cb-overlay *::after { 2149 box-sizing:border-box; 2150} 2151.cb-btn { 2152 position:fixed; bottom:22px; right:22px; z-index:9500; 2153 width:54px; height:54px; border-radius:50%; 2154 background:#C4622D; color:#fff; border:none; 2155 display:flex; align-items:center; justify-content:center; 2156 cursor:pointer; box-shadow:0 6px 18px rgba(26,18,8,0.25),0 2px 6px rgba(26,18,8,0.15); 2157 transition:transform .2s ease, background .2s ease, opacity .25s ease; 2158 padding:0; 2159} 2160.cb-btn:hover { background:#a7531f; transform:scale(1.06); } 2161.cb-btn svg { width:24px; height:24px; display:block; } 2162.cb-btn.cb-scroll-fade { opacity:0.7; } 2163@media (max-width:600px) { 2164 .cb-btn { width:48px; height:48px; bottom:18px; right:18px; } 2165 .cb-btn svg { width:22px; height:22px; } 2166} 2167 2168.cb-overlay { 2169 position:fixed; inset:0; z-index:9600; 2170 background:rgba(26,18,8,0.55); backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px); 2171 opacity:0; visibility:hidden; 2172 transition:opacity .2s ease, visibility .2s ease; 2173 display:flex; align-items:flex-end; justify-content:flex-end; 2174 padding:22px; 2175} 2176.cb-overlay.cb-open { opacity:1; visibility:visible; } 2177@media (max-width:600px) { .cb-overlay { padding:0; align-items:stretch; justify-content:stretch; } } 2178 2179.cb-panel { 2180 background:#faf8f6; border:1.5px solid rgba(14,110,90,0.08); border-radius:16px; 2181 width:100%; max-width:420px; max-height:calc(100vh - 44px); overflow-y:auto; 2182 box-shadow:0 20px 50px rgba(26,18,8,0.3); 2183 transform:translateY(24px) scale(0.97); opacity:0; 2184 transition:transform .25s ease, opacity .25s ease; 2185 font-family:'DM Sans',system-ui,-apple-system,sans-serif; color:#1a1612; 2186} 2187.cb-overlay.cb-open .cb-panel { transform:translateY(0) scale(1); opacity:1; } 2188@media (max-width:600px) { .cb-panel { max-width:none; max-height:100vh; border-radius:0; border:none; } } 2189 2190.cb-header { 2191 display:flex; align-items:center; justify-content:space-between; 2192 padding:18px 22px 14px; border-bottom:1px solid rgba(14,110,90,0.08); 2193} 2194.cb-header-title { 2195 font-family:'Playfair Display',Georgia,serif; 2196 font-size:1.1rem; font-weight:700; color:#1a1612; margin:0; 2197} 2198.cb-close { 2199 width:30px; height:30px; border-radius:50%; border:none; 2200 background:transparent; color:#5a4a3a; cursor:pointer; 2201 display:flex; align-items:center; justify-content:center; 2202 transition:background .15s, color .15s; 2203} 2204.cb-close:hover { background:rgba(0,0,0,0.05); color:#1a1612; } 2205 2206.cb-body { padding:20px 22px; } 2207.cb-field { margin-bottom:14px; } 2208.cb-field:last-of-type { margin-bottom:0; } 2209.cb-label { display:block; font-size:.82rem; font-weight:600; color:#2C1F14; margin-bottom:5px; } 2210.cb-label span { color:#C4622D; } 2211.cb-input, .cb-select, .cb-textarea { 2212 width:100%; padding:10px 13px; border:1.5px solid rgba(0,0,0,0.1); border-radius:8px; 2213 font-size:.92rem; font-family:inherit; background:#fff; color:#1a1612; 2214 transition:border-color .2s; outline:none; 2215} 2216.cb-input:focus, .cb-select:focus, .cb-textarea:focus { 2217 border-color:#0E6E5A; box-shadow:0 0 0 3px rgba(14,110,90,0.08); 2218} 2219.cb-select { 2220 appearance:none; background-image:url("data:image/svg+xml,%3Csvg width='12' height='7' viewBox='0 0 12 7' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%235a4a3a' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); 2221 background-repeat:no-repeat; background-position:right 12px center; padding-right:34px; 2222} 2223.cb-textarea { min-height:110px; resize:vertical; line-height:1.55; } 2224.cb-submit { 2225 display:inline-flex; align-items:center; gap:8px; 2226 background:#0E6E5A; color:#fff; font-weight:700; font-size:.92rem; 2227 padding:11px 24px; border:none; border-radius:9px; cursor:pointer; 2228 transition:background .2s; width:100%; justify-content:center; 2229 font-family:inherit; 2230} 2231.cb-submit:hover { background:#0a5a49; } 2232.cb-submit:disabled { opacity:.6; cursor:not-allowed; } 2233.cb-submit svg { width:16px; height:16px; } 2234 2235.cb-msg { padding:11px 14px; border-radius:9px; font-size:.85rem; line-height:1.5; margin-bottom:14px; display:none; } 2236.cb-msg.cb-err { background:rgba(196,58,45,0.06); border:1.5px solid rgba(196,58,45,0.15); color:#7a3020; display:block; } 2237.cb-msg.cb-ok { background:rgba(14,110,90,0.06); border:1.5px solid rgba(14,110,90,0.15); color:#0a5a49; display:block; } 2238.cb-msg ul { margin:4px 0 0; padding-left:18px; } 2239.cb-msg li { line-height:1.5; } 2240</style> 2241 2242<button type="button" class="cb-btn" id="cbTrigger" aria-label="Contact us" data-tooltip="Contact us"> 2243 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> 2244 <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/> 2245 </svg> 2246</button> 2247 2248<div class="cb-overlay" id="cbOverlay" role="dialog" aria-modal="true" aria-labelledby="cbTitle"> 2249 <div class="cb-panel" role="document"> 2250 <div class="cb-header"> 2251 <h3 class="cb-header-title" id="cbTitle">Contact us</h3> 2252 <button type="button" class="cb-close" id="cbClose" aria-label="Close">
2253 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg> 2254 </button> 2255 </div> 2256 2257 <div class="cb-body"> 2258 <div class="cb-msg" id="cbMsg" role="status" aria-live="polite"></div> 2259 2260 <form id="cbForm" novalidate> 2261 <input type="hidden" name="_token" id="cbToken" value=""> 2262 2263 <div aria-hidden="true" style="position:absolute;left:-10000px;top:auto;width:1px;height:1px;overflow:hidden;"> 2264 <label for="cb-website">Website (leave blank)</label> 2265 <input type="text" id="cb-website" name="website" tabindex="-1" autocomplete="off" value=""> 2266 </div> 2267 2268 <div class="cb-field"> 2269 <label class="cb-label" for="cb-name">Your name <span>*</span></label> 2270 <input type="text" id="cb-name" name="name" class="cb-input" placeholder="Jane Doe" required maxlength="255" autocomplete="name"> 2271 </div> 2272 2273 <div class="cb-field"> 2274 <label class="cb-label" for="cb-email">Email address <span>*</span></label> 2275 <input type="email" id="cb-email" name="email" class="cb-input" placeholder="[email protected]" required maxlength="255" autocomplete="email"> 2276 </div> 2277 2278 <div class="cb-field"> 2279 <label class="cb-label" for="cb-subject">Subject <span>*</span></label> 2280 <select id="cb-subject" name="subject" class="cb-select" required> 2281 <option value="">Select a topicâ¦</option> 2282 <option value="sponsored_posts">Sponsored Posts</option> 2283 <option value="feature_request">Feature Request</option> 2284 <option value="website_issue">Website Issue</option> 2285 <option value="advertisements">Advertisements</option> 2286 <option value="blog_directory">Blog Directory</option> 2287 <option value="account_help">Account Help</option> 2288 <option value="partnership">Partnership Inquiry</option> 2289 <option value="others">Others</option> 2290 </select> 2291 </div> 2292 2293 <div class="cb-field"> 2294 <label class="cb-label" for="cb-message">Message <span>*</span></label> 2295 <textarea id="cb-message" name="message" class="cb-textarea" placeholder="How can we help?" required maxlength="5000"></textarea> 2296 </div> 2297 2298 <input type="hidden" name="g-recaptcha-response" id="cbRcToken" value=""> 2299 2300 <button type="submit" class="cb-submit" id="cbSubmit"> 2301 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg> 2302 Send message 2303 </button> 2304 </form> 2305 </div> 2306 </div> 2307</div> 2308
2309<script> 2310(function(){ 2311 if (window.__cbRecaptchaLoaded) return; 2312 window.__cbRecaptchaLoaded = true; 2313 var s = document.createElement('script'); 2314 s.src = 'https://www.google.com/recaptcha/enterprise.js?render=6Lfj9KQsAAAAAOfmTJ5-QQz4OEG7tTps49vot8p1'; 2315 s.async = true; 2316 document.head.appendChild(s); 2317})(); 2318</script>
2318 2319
2320<script> 2321(function(){ 2322 var trigger = document.getElementById('cbTrigger'); 2323 var overlay = document.getElementById('cbOverlay'); 2324 var closeBtn = document.getElementById('cbClose'); 2325 var form = document.getElementById('cbForm'); 2326 var tokenEl = document.getElementById('cbToken'); 2327 var msg = document.getElementById('cbMsg'); 2328 var submit = document.getElementById('cbSubmit'); 2329 var rcKey = "6Lfj9KQsAAAAAOfmTJ5-QQz4OEG7tTps49vot8p1"; 2330 2331 var appeared = false; 2332 // Tiny delay so the bubble doesn't feel pushy on arrival. 2333 setTimeout(function(){ trigger.style.opacity = '1'; appeared = true; }, 1200); 2334 trigger.style.opacity = '0'; 2335 trigger.style.transition = 'opacity .3s ease'; 2336 2337 // Fade while actively scrolling so it doesn't compete with reading. 2338 var scrollTimer = null; 2339 window.addEventListener('scroll', function(){ 2340 if (!appeared) return; 2341 trigger.classList.add('cb-scroll-fade'); 2342 clearTimeout(scrollTimer); 2343 scrollTimer = setTimeout(function(){ trigger.classList.remove('cb-scroll-fade'); }, 400); 2344 }, { passive: true }); 2345 2346 function open(){ 2347 overlay.classList.add('cb-open'); 2348 document.body.style.overflow = 'hidden'; 2349 fetchToken(); 2350 setTimeout(function(){ document.getElementById('cb-name').focus(); }, 150); 2351 } 2352 function close(){ 2353 overlay.classList.remove('cb-open'); 2354 document.body.style.overflow = ''; 2355 } 2356 2357 trigger.addEventListener('click', open); 2358 closeBtn.addEventListener('click', close); 2359 overlay.addEventListener('click', function(e){ if (e.target === overlay) close(); }); 2360 document.addEventListener('keydown', function(e){ 2361 if (e.key === 'Escape' && overlay.classList.contains('cb-open')) close(); 2362 }); 2363 2364 function fetchToken(){ 2365 if (tokenEl.value) return; 2366 fetch('/contact/csrf', { 2367 method: 'POST', 2368 headers: { 'X-Requested-With': 'XMLHttpRequest' }, 2369 credentials: 'same-origin', 2370 cache: 'no-store' 2371 }) 2372 .then(function(r){ return r.json(); }) 2373 .then(function(d){ if (d && d.token) tokenEl.value = d.token; }) 2374 .catch(function(){}); 2375 } 2376 2377 function showErrors(list){ 2378 if (!Array.isArray(list) || !list.length) list = ['Something went wrong. Please try again.']; 2379 msg.className = 'cb-msg cb-err'; 2380 msg.innerHTML = list.length === 1 2381 ? _esc(list[0]) 2382 : '<strong>Please fix:</strong><ul>' + list.map(function(x){ return '<li>' + _esc(x) + '</li>'; }).join('') + '</ul>'; 2383 } 2384 function showOk(text){ 2385 msg.className = 'cb-msg cb-ok'; 2386 msg.textContent = text; 2387 } 2388 function _esc(s){ return String(s).replace(/[&<>"']/g, function(c){ 2389 return {'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]; 2390 }); } 2391 2392 function runRecaptcha(){ 2393 return new Promise(function(resolve){ 2394 if (!rcKey || typeof grecaptcha === 'undefined' || !grecaptcha.enterprise) { resolve(''); return; } 2395 try { 2396 grecaptcha.enterprise.ready(function(){ 2397 grecaptcha.enterprise.execute(rcKey, { action: 'contact' }) 2398 .then(function(t){ resolve(t || ''); }) 2399 .catch(function(){ resolve(''); }); 2400 }); 2401 } catch(e) { resolve(''); } 2402 }); 2403 } 2404 2405 form.addEventListener('submit', function(e){ 2406 e.preventDefault(); 2407 msg.className = 'cb-msg'; 2408 msg.textContent = ''; 2409 2410 if (!tokenEl.value) fetchToken(); 2411 2412 submit.disabled = true; 2413 var originalHtml = submit.innerHTML; 2414 submit.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/></svg> Sendingâ¦'; 2415 2416 runRecaptcha().then(function(rcToken){ 2417 var rcField = document.getElementById('cbRcToken'); 2418 if (rcField) rcField.value = rcToken; 2419 2420 var body = new URLSearchParams(new FormData(form)); 2421 return fetch('/contact', { 2422 method: 'POST', 2423 headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' }, 2424 body: body, 2425 credentials: 'same-origin', 2426 cache: 'no-store' 2427 }); 2428 }) 2429 .then(function(r){ return r.json(); }) 2430 .then(function(d){ 2431 if (d && d.ok) { 2432 showOk(d.message || 'Thanks â we will get back to you shortly.'); 2433 form.reset(); 2434 setTimeout(close, 3000); 2435 } else { 2436 showErrors((d && d.errors) || []); 2437 } 2438 }) 2439 .catch(function(){ 2440 showErrors(['Network error. Please try again.']); 2441 }) 2442 .finally(function(){ 2443 submit.disabled = false;
2444 submit.innerHTML = originalHtml; 2445 }); 2446 }); 2447})(); 2448</script>
vendor: 1 bytes, line 2448
2448
2449<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"7000b5438b3a47579e83fe5202f1a1fa","r":1,"spa":2}' crossorigin="anonymous"></script>
vendor: 1 bytes, line 2449
2449
2450<script>(function(){function c(){var b=a.contentDocument||(a.contentWindow&&a.contentWindow.document);if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'a43965756ca9127b',t:'MTc5MDgzNTk5MQ=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script>
2450</body> 2451</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.