Size: 39.69 KB
<!-- ============================================================
SMART WORD COUNTER — Blogger Embed (With Banner Ads)
Mode A (default): Embedded — theme header/footer remains
Mode B: Set SWC_CONFIG.showHeader / showFooter = true
============================================================ -->
<div class="swc-app" id="swc-app">
<!-- ================= INTERNAL HEADER (Mode B) ================= -->
<header class="swc-header" id="swc-header" hidden>
<div class="swc-header-inner">
<a href="#swc-top" class="swc-brand" aria-label="Smart Word Counter home">
<svg class="swc-logo" viewBox="0 0 32 32" aria-hidden="true" focusable="false">
<rect x="3" y="4" width="26" height="24" rx="4" fill="none" stroke="currentColor" stroke-width="2"/>
<path d="M8 11h10M8 16h16M8 21h12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
</svg>
<span class="swc-brand-text">
<span class="swc-brand-name">Smart Word Counter</span>
<span class="swc-brand-tag">Count Words, Characters & More Instantly</span>
</span>
</a>
<button class="swc-nav-toggle" id="swc-nav-toggle" aria-expanded="false" aria-controls="swc-nav" aria-label="Open navigation menu">
<span class="swc-nav-toggle-bar"></span>
<span class="swc-nav-toggle-bar"></span>
<span class="swc-nav-toggle-bar"></span>
</button>
<nav class="swc-nav" id="swc-nav" aria-label="Primary">
<ul>
<li><a href="#swc-top">Home</a></li>
<li><a href="#swc-tool">Word Counter</a></li>
<li><a href="#swc-how">How It Works</a></li>
<li><a href="#swc-faq">FAQ</a></li>
<li><a href="#swc-about">About</a></li>
<li><a href="#swc-contact">Contact</a></li>
</ul>
</nav>
</div>
</header>
<main id="swc-top" class="swc-main">
<!-- ================= AD SLOT 1: Top Banner ================= -->
<div class="swc-ad swc-ad-top" aria-label="Advertisement">
<span class="swc-ad-label">Advertisement</span>
<div class="swc-ad-inner">
<!-- ADSENSE CODE — TOP BANNER (728x90 / Responsive) -->
<div class="swc-ad-placeholder">Ads Code Here</div>
</div>
</div>
<!-- ================= HERO ================= -->
<section class="swc-hero" aria-labelledby="swc-hero-title">
<h1 id="swc-hero-title" class="swc-hero-title">Free Online Word Counter</h1>
<p class="swc-hero-sub">
<center>Count words, characters, sentences, and paragraphs instantly with our
simple and easy-to-use online word counter.<center>
</p>
<p class="swc-hero-privacy">
<svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true" focusable="false">
<path fill="currentColor" d="M10 1 3 4v6c0 4 3 7.5 7 9 4-1.5 7-5 7-9V4l-7-3Zm0 5a2 2 0 0 1 1 3.7V13H9v-3.3A2 2 0 0 1 10 6Z"/>
</svg>
Your text is processed in your browser and is not uploaded to our server.
</p>
</section>
<!-- ================= WORD COUNTER TOOL ================= -->
<section class="swc-tool" id="swc-tool" aria-labelledby="swc-tool-title">
<div class="swc-card swc-editor-card">
<div class="swc-editor-head">
<label for="swc-textarea" class="swc-label">Enter your text</label>
<span class="swc-live-badge" id="swc-live-badge">
<span class="swc-dot" aria-hidden="true"></span>
Live counting
</span>
</div>
<textarea
id="swc-textarea"
class="swc-textarea"
placeholder="Type or paste your text here to count words and characters..."
spellcheck="true"
aria-describedby="swc-live-status"></textarea>
<p id="swc-live-status" class="swc-visually-hidden" role="status" aria-live="polite"></p>
<div class="swc-actions" role="group" aria-label="Text actions">
<button type="button" class="swc-btn swc-btn-primary" id="swc-copy" disabled>
<svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true" focusable="false">
<path fill="currentColor" d="M7 2h7a2 2 0 0 1 2 2v9h-2V4H7V2Zm-2 4h7a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2Z"/>
</svg>
Copy Text
</button>
<button type="button" class="swc-btn swc-btn-ghost" id="swc-clear" disabled>
<svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true" focusable="false">
<path fill="currentColor" d="M7 3h6v2h5v2H2V5h5V3Zm-3 6h12l-1 9a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 9Zm4 2v7h2v-7H8Zm4 0v7h2v-7h-2Z"/>
</svg>
Clear Text
</button>
<button type="button" class="swc-btn swc-btn-secondary" id="swc-download" disabled>
<svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true" focusable="false">
<path fill="currentColor" d="M9 2h2v9l3-3 1.4 1.4L10 14.8 4.6 9.4 6 8l3 3V2ZM4 17h12v2H4v-2Z"/>
</svg>
Download TXT
</button>
</div>
<p class="swc-feedback" id="swc-feedback" role="status" aria-live="polite"></p>
</div>
<!-- ============ STATS DASHBOARD ============ -->
<div class="swc-stats" role="group" aria-label="Text statistics">
<div class="swc-stat">
<span class="swc-stat-label">Words</span>
<span class="swc-stat-value" id="swc-words">0</span>
</div>
<div class="swc-stat">
<span class="swc-stat-label">Characters <small>(with spaces)</small></span>
<span class="swc-stat-value" id="swc-chars">0</span>
</div>
<div class="swc-stat">
<span class="swc-stat-label">Characters <small>(no spaces)</small></span>
<span class="swc-stat-value" id="swc-chars-ns">0</span>
</div>
<div class="swc-stat">
<span class="swc-stat-label">Sentences</span>
<span class="swc-stat-value" id="swc-sentences">0</span>
</div>
<div class="swc-stat">
<span class="swc-stat-label">Paragraphs</span>
<span class="swc-stat-value" id="swc-paragraphs">0</span>
</div>
<div class="swc-stat">
<span class="swc-stat-label">Reading Time</span>
<span class="swc-stat-value" id="swc-reading">0 min</span>
</div>
</div>
</section>
<!-- ================= AD SLOT 2: After Stats ================= -->
<div class="swc-ad swc-ad-mid" aria-label="Advertisement">
<span class="swc-ad-label">Advertisement</span>
<div class="swc-ad-inner">
<!-- ADSENSE CODE — MID BANNER (Responsive) -->
<div class="swc-ad-placeholder">Ads Code Here</div>
</div>
</div>
<!-- ================= HOW IT WORKS ================= -->
<section class="swc-section" id="swc-how" aria-labelledby="swc-how-title">
<h2 id="swc-how-title" class="swc-section-title">How It Works</h2>
<ol class="swc-steps">
<li class="swc-step">
<span class="swc-step-num" aria-hidden="true">1</span>
<div>
<h3>Paste or type your text</h3>
<p>Enter your content into the editor above. Counting starts automatically.</p>
</div>
</li>
<li class="swc-step">
<span class="swc-step-num" aria-hidden="true">2</span>
<div>
<h3>View live statistics</h3>
<p>See words, characters, sentences, paragraphs, and reading time update instantly.</p>
</div>
</li>
<li class="swc-step">
<span class="swc-step-num" aria-hidden="true">3</span>
<div>
<h3>Copy or download</h3>
<p>Copy your text to the clipboard or download it as a plain .txt file.</p>
</div>
</li>
</ol>
</section>
<!-- ================= BENEFITS ================= -->
<section class="swc-section" aria-labelledby="swc-benefits-title">
<h2 id="swc-benefits-title" class="swc-section-title">Why Use Smart Word Counter?</h2>
<ul class="swc-benefits">
<li>Instant live counting as you type.</li>
<li>Simple, distraction-free interface.</li>
<li>Works on mobile, tablet, and desktop.</li>
<li>No account or sign-up required.</li>
<li>Text is processed locally in your browser.</li>
<li>Convenient copy and TXT download options.</li>
</ul>
</section>
<!-- ================= AD SLOT 3: Between Content ================= -->
<div class="swc-ad swc-ad-mid" aria-label="Advertisement">
<span class="swc-ad-label">Advertisement</span>
<div class="swc-ad-inner">
<!-- ADSENSE CODE — 300x250 / Responsive -->
<div class="swc-ad-placeholder">Ads Code Here</div>
</div>
</div>
<!-- ================= FAQ ================= -->
<section class="swc-section" id="swc-faq" aria-labelledby="swc-faq-title">
<h2 id="swc-faq-title" class="swc-section-title">Frequently Asked Questions</h2>
<div class="swc-faq" id="swc-faq-list">
<div class="swc-faq-item">
<h3>
<button type="button" class="swc-faq-q" aria-expanded="false" aria-controls="swc-faq-a1" id="swc-faq-q1">
<span>What is a word counter?</span>
<svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true" focusable="false" class="swc-faq-icon"><path fill="currentColor" d="M10 3l1.4 1.4L15.8 9H4.2l4.4-4.6L10 3Zm0 14-1.4-1.4L4.2 11h11.6l-4.4 4.6L10 17Z"/></svg>
</button>
</h3>
<div class="swc-faq-a" id="swc-faq-a1" role="region" aria-labelledby="swc-faq-q1" hidden>
A word counter is a tool that counts the number of words, characters, sentences, and paragraphs in a piece of text.
</div>
</div>
<div class="swc-faq-item">
<h3>
<button type="button" class="swc-faq-q" aria-expanded="false" aria-controls="swc-faq-a2" id="swc-faq-q2">
<span>How does this online word counter work?</span>
<svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true" focusable="false" class="swc-faq-icon"><path fill="currentColor" d="M10 3l1.4 1.4L15.8 9H4.2l4.4-4.6L10 3Zm0 14-1.4-1.4L4.2 11h11.6l-4.4 4.6L10 17Z"/></svg>
</button>
</h3>
<div class="swc-faq-a" id="swc-faq-a2" role="region" aria-labelledby="swc-faq-q2" hidden>
You type or paste text into the editor. JavaScript analyzes the text in your browser and updates the statistics in real time.
</div>
</div>
<div class="swc-faq-item">
<h3>
<button type="button" class="swc-faq-q" aria-expanded="false" aria-controls="swc-faq-a3" id="swc-faq-q3">
<span>Does it count spaces as characters?</span>
<svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true" focusable="false" class="swc-faq-icon"><path fill="currentColor" d="M10 3l1.4 1.4L15.8 9H4.2l4.4-4.6L10 3Zm0 14-1.4-1.4L4.2 11h11.6l-4.4 4.6L10 17Z"/></svg>
</button>
</h3>
<div class="swc-faq-a" id="swc-faq-a3" role="region" aria-labelledby="swc-faq-q3" hidden>
Yes — one counter includes spaces and line breaks, and a second counter shows characters excluding whitespace so you can compare both.
</div>
</div>
<div class="swc-faq-item">
<h3>
<button type="button" class="swc-faq-q" aria-expanded="false" aria-controls="swc-faq-a4" id="swc-faq-q4">
<span>How are paragraphs counted?</span>
<svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true" focusable="false" class="swc-faq-icon"><path fill="currentColor" d="M10 3l1.4 1.4L15.8 9H4.2l4.4-4.6L10 3Zm0 14-1.4-1.4L4.2 11h11.6l-4.4 4.6L10 17Z"/></svg>
</button>
</h3>
<div class="swc-faq-a" id="swc-faq-a4" role="region" aria-labelledby="swc-faq-q4" hidden>
Paragraphs are separated by one or more blank lines. Empty lines are ignored, so only non-empty blocks are counted.
</div>
</div>
<div class="swc-faq-item">
<h3>
<button type="button" class="swc-faq-q" aria-expanded="false" aria-controls="swc-faq-a5" id="swc-faq-q5">
<span>How is reading time calculated?</span>
<svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true" focusable="false" class="swc-faq-icon"><path fill="currentColor" d="M10 3l1.4 1.4L15.8 9H4.2l4.4-4.6L10 3Zm0 14-1.4-1.4L4.2 11h11.6l-4.4 4.6L10 17Z"/></svg>
</button>
</h3>
<div class="swc-faq-a" id="swc-faq-a5" role="region" aria-labelledby="swc-faq-q5" hidden>
Reading time is estimated at 200 words per minute. Text shorter than one minute shows "Less than 1 min".
</div>
</div>
<div class="swc-faq-item">
<h3>
<button type="button" class="swc-faq-q" aria-expanded="false" aria-controls="swc-faq-a6" id="swc-faq-q6">
<span>Is my text uploaded to a server?</span>
<svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true" focusable="false" class="swc-faq-icon"><path fill="currentColor" d="M10 3l1.4 1.4L15.8 9H4.2l4.4-4.6L10 3Zm0 14-1.4-1.4L4.2 11h11.6l-4.4 4.6L10 17Z"/></svg>
</button>
</h3>
<div class="swc-faq-a" id="swc-faq-a6" role="region" aria-labelledby="swc-faq-q6" hidden>
No. All counting happens locally in your browser. Your text is not sent to any server by this tool.
</div>
</div>
<div class="swc-faq-item">
<h3>
<button type="button" class="swc-faq-q" aria-expanded="false" aria-controls="swc-faq-a7" id="swc-faq-q7">
<span>Can I use this tool on a mobile phone?</span>
<svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true" focusable="false" class="swc-faq-icon"><path fill="currentColor" d="M10 3l1.4 1.4L15.8 9H4.2l4.4-4.6L10 3Zm0 14-1.4-1.4L4.2 11h11.6l-4.4 4.6L10 17Z"/></svg>
</button>
</h3>
<div class="swc-faq-a" id="swc-faq-a7" role="region" aria-labelledby="swc-faq-q7" hidden>
Yes. The layout is fully responsive and works on mobile phones, tablets, laptops, and desktops.
</div>
</div>
<div class="swc-faq-item">
<h3>
<button type="button" class="swc-faq-q" aria-expanded="false" aria-controls="swc-faq-a8" id="swc-faq-q8">
<span>Can I download my text?</span>
<svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true" focusable="false" class="swc-faq-icon"><path fill="currentColor" d="M10 3l1.4 1.4L15.8 9H4.2l4.4-4.6L10 3Zm0 14-1.4-1.4L4.2 11h11.6l-4.4 4.6L10 17Z"/></svg>
</button>
</h3>
<div class="swc-faq-a" id="swc-faq-a8" role="region" aria-labelledby="swc-faq-q8" hidden>
Yes. The "Download TXT" button saves your text as a plain .txt file directly from your browser.
</div>
</div>
</div>
</section>
<!-- ================= AD SLOT 4: Bottom Banner ================= -->
<div class="swc-ad swc-ad-bottom" aria-label="Advertisement">
<span class="swc-ad-label">Advertisement</span>
<div class="swc-ad-inner">
<!-- ADSENSE CODE — BOTTOM BANNER (Responsive) -->
<div class="swc-ad-placeholder">Ads Code Here</div>
</div>
</div>
<!-- ================= ABOUT ================= -->
<section class="swc-section" id="swc-about" aria-labelledby="swc-about-title">
<h2 id="swc-about-title" class="swc-section-title">About Smart Word Counter</h2>
<p>
Smart Word Counter is a free, browser-based tool for counting words and analyzing
basic text statistics. It runs entirely in your browser with no account required
and no server-side processing.
</p>
</section>
<!-- ================= CONTACT ANCHOR ================= -->
<section class="swc-section" id="swc-contact" aria-labelledby="swc-contact-title">
<h2 id="swc-contact-title" class="swc-section-title">Contact</h2>
<p>
For questions or feedback, please use the contact page linked in the footer below.
</p>
</section>
</main>
<!-- ================= INTERNAL FOOTER (Mode B) ================= -->
<footer class="swc-footer" id="swc-footer" hidden>
<div class="swc-footer-inner">
<div class="swc-footer-col">
<div class="swc-brand swc-brand-footer">
<svg class="swc-logo" viewBox="0 0 32 32" aria-hidden="true" focusable="false">
<rect x="3" y="4" width="26" height="24" rx="4" fill="none" stroke="currentColor" stroke-width="2"/>
<path d="M8 11h10M8 16h16M8 21h12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
</svg>
<span class="swc-brand-name">Smart Word Counter</span>
</div>
<p class="swc-footer-desc">
A simple, free tool to count words, characters, sentences, and paragraphs instantly.
</p>
</div>
<nav class="swc-footer-col" aria-label="Footer quick links">
<h3 class="swc-footer-title">Quick Links</h3>
<ul>
<li><a href="#swc-tool">Word Counter</a></li>
<li><a href="#swc-how">How It Works</a></li>
<li><a href="#swc-faq">FAQ</a></li>
<li><a href="#swc-about">About</a></li>
</ul>
</nav>
<nav class="swc-footer-col" aria-label="Footer legal links">
<h3 class="swc-footer-title">Legal</h3>
<ul>
<li><a href="#" data-swc-url="privacy">Privacy Policy</a></li>
<li><a href="#" data-swc-url="terms">Terms of Use</a></li>
<li><a href="#swc-contact">Contact</a></li>
</ul>
</nav>
</div>
<div class="swc-footer-bottom">
<p>© <span id="swc-year">2025</span> Smart Word Counter. All rights reserved.</p>
</div>
</footer>
</div>
<style>
/* =========================================================
SMART WORD COUNTER — SCOPED STYLES
========================================================= */
.swc-app {
--swc-accent: #4f46e5;
--swc-accent-dark: #4338ca;
--swc-accent-soft: #eef2ff;
--swc-bg: #ffffff;
--swc-bg-soft: #f8fafc;
--swc-border: #e2e8f0;
--swc-text: #0f172a;
--swc-muted: #64748b;
--swc-radius: 12px;
--swc-shadow: 0 1px 3px rgba(15,23,42,.06), 0 8px 24px rgba(15,23,42,.06);
--swc-shadow-sm: 0 1px 2px rgba(15,23,42,.05);
color: var(--swc-text);
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
line-height: 1.6;
font-size: 16px;
background: var(--swc-bg);
max-width: 1100px;
margin: 0 auto;
padding: 0 16px;
box-sizing: border-box;
}
.swc-app *, .swc-app *::before, .swc-app *::after { box-sizing: border-box; }
.swc-app img, .swc-app svg { display: block; max-width: 100%; }
.swc-app p { margin: 0 0 12px; }
.swc-app a { color: var(--swc-accent); text-decoration: none; }
.swc-app a:hover, .swc-app a:focus-visible { text-decoration: underline; }
.swc-app button { font: inherit; cursor: pointer; }
.swc-app :focus-visible { outline: 3px solid var(--swc-accent); outline-offset: 2px; border-radius: 6px; }
.swc-visually-hidden {
position: absolute !important; width: 1px; height: 1px;
padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0);
white-space: nowrap; border: 0;
}
/* ---------- Header (Mode B) ---------- */
.swc-header {
position: sticky; top: 0; z-index: 20;
background: rgba(255,255,255,.92);
backdrop-filter: saturate(1.4) blur(8px);
border-bottom: 1px solid var(--swc-border);
}
.swc-header-inner {
display: flex; align-items: center; justify-content: space-between;
gap: 12px; padding: 12px 0; max-width: 1100px; margin: 0 auto;
}
.swc-brand { display: inline-flex; align-items: center; gap: 10px; color: var(--swc-text); text-decoration: none; }
.swc-brand:hover { text-decoration: none; }
.swc-logo { width: 30px; height: 30px; color: var(--swc-accent); flex: 0 0 auto; }
.swc-brand-text { display: flex; flex-direction: column; line-height: 1.15; }
.swc-brand-name { font-weight: 700; font-size: 1rem; }
.swc-brand-tag { font-size: .72rem; color: var(--swc-muted); }
.swc-nav ul { list-style: none; display: flex; gap: 4px; margin: 0; padding: 0; }
.swc-nav a {
display: inline-block; padding: 8px 12px; border-radius: 8px;
color: var(--swc-text); font-size: .92rem; font-weight: 500;
}
.swc-nav a:hover, .swc-nav a:focus-visible { background: var(--swc-accent-soft); color: var(--swc-accent-dark); text-decoration: none; }
.swc-nav-toggle {
display: none; width: 42px; height: 42px; border: 1px solid var(--swc-border);
background: #fff; border-radius: 10px; padding: 10px; flex-direction: column; justify-content: space-between;
}
.swc-nav-toggle-bar { display: block; height: 2px; background: var(--swc-text); border-radius: 2px; }
/* ---------- Hero ---------- */
.swc-hero { text-align: center; padding: 40px 0 24px; }
.swc-hero-title {
font-size: clamp(1.6rem, 4.5vw, 2.4rem);
font-weight: 800; letter-spacing: -0.02em; margin: 0 0 12px; color: var(--swc-text);
}
.swc-hero-sub { color: var(--swc-muted); max-width: 640px; margin: 0 auto 14px; font-size: 1.02rem; }
.swc-hero-privacy {
display: inline-flex; align-items: center; gap: 8px;
font-size: .85rem; color: var(--swc-accent-dark); background: var(--swc-accent-soft);
padding: 6px 12px; border-radius: 999px; margin: 0;
}
.swc-hero-privacy svg { color: var(--swc-accent); }
/* ---------- Tool Card ---------- */
.swc-tool { margin: 8px 0 32px; }
.swc-card {
background: var(--swc-bg); border: 1px solid var(--swc-border);
border-radius: var(--swc-radius); box-shadow: var(--swc-shadow);
padding: 20px; margin-bottom: 20px;
}
.swc-editor-head {
display: flex; align-items: center; justify-content: space-between;
gap: 12px; margin-bottom: 10px; flex-wrap: wrap;
}
.swc-label { font-weight: 600; font-size: .95rem; }
.swc-live-badge {
display: inline-flex; align-items: center; gap: 8px;
font-size: .78rem; color: var(--swc-muted);
background: var(--swc-bg-soft); border: 1px solid var(--swc-border);
padding: 4px 10px; border-radius: 999px;
}
.swc-dot { width: 8px; height: 8px; border-radius: 50%; background: #22c55e; box-shadow: 0 0 0 3px rgba(34,197,94,.2); animation: swc-pulse 1.8s infinite; }
@keyframes swc-pulse { 0%,100% { opacity: 1; } 50% { opacity: .45; } }
.swc-textarea {
width: 100%; min-height: 220px; resize: vertical;
padding: 14px; font-family: inherit; font-size: 1rem; line-height: 1.6;
color: var(--swc-text); background: var(--swc-bg-soft);
border: 1px solid var(--swc-border); border-radius: 10px;
transition: border-color .15s, box-shadow .15s, background .15s;
}
.swc-textarea::placeholder { color: #94a3b8; }
.swc-textarea:focus {
outline: none; background: #fff;
border-color: var(--swc-accent);
box-shadow: 0 0 0 4px rgba(79,70,229,.15);
}
.swc-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.swc-btn {
display: inline-flex; align-items: center; gap: 8px;
padding: 10px 16px; border-radius: 10px; font-weight: 600; font-size: .92rem;
border: 1px solid transparent; transition: transform .05s, background .15s, color .15s, border-color .15s;
min-height: 42px;
}
.swc-btn:active:not(:disabled) { transform: translateY(1px); }
.swc-btn:disabled { opacity: .5; cursor: not-allowed; }
.swc-btn-primary { background: var(--swc-accent); color: #fff; }
.swc-btn-primary:hover:not(:disabled) { background: var(--swc-accent-dark); }
.swc-btn-secondary { background: var(--swc-bg-soft); color: var(--swc-text); border-color: var(--swc-border); }
.swc-btn-secondary:hover:not(:disabled) { background: #eef2f7; }
.swc-btn-ghost { background: transparent; color: #b91c1c; border-color: #fecaca; }
.swc-btn-ghost:hover:not(:disabled) { background: #fef2f2; }
.swc-feedback { margin: 10px 0 0; font-size: .88rem; min-height: 1.2em; color: var(--swc-muted); }
.swc-feedback.swc-ok { color: #166534; }
.swc-feedback.swc-err { color: #b91c1c; }
/* ---------- Stats ---------- */
.swc-stats {
display: grid; gap: 12px;
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.swc-stat {
background: var(--swc-bg); border: 1px solid var(--swc-border);
border-radius: var(--swc-radius); padding: 14px 16px;
box-shadow: var(--swc-shadow-sm); display: flex; flex-direction: column; gap: 4px;
min-width: 0;
}
.swc-stat-label { font-size: .8rem; color: var(--swc-muted); font-weight: 500; }
.swc-stat-label small { font-weight: 400; }
.swc-stat-value {
font-size: clamp(1.2rem, 3.5vw, 1.6rem); font-weight: 700;
color: var(--swc-text); word-break: break-word; line-height: 1.2;
}
/* ---------- Sections ---------- */
.swc-section { padding: 28px 0; border-top: 1px solid var(--swc-border); }
.swc-section-title { font-size: clamp(1.2rem, 3vw, 1.5rem); margin: 0 0 16px; font-weight: 700; letter-spacing: -0.01em; }
.swc-steps { list-style: none; padding: 0; margin: 0; display: grid; gap: 14px; }
.swc-step { display: flex; gap: 14px; align-items: flex-start; background: var(--swc-bg-soft); border: 1px solid var(--swc-border); border-radius: var(--swc-radius); padding: 14px; }
.swc-step-num {
flex: 0 0 auto; width: 32px; height: 32px; border-radius: 50%;
background: var(--swc-accent); color: #fff; display: inline-flex;
align-items: center; justify-content: center; font-weight: 700;
}
.swc-step h3 { margin: 0 0 4px; font-size: 1rem; }
.swc-step p { margin: 0; color: var(--swc-muted); font-size: .92rem; }
.swc-benefits { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; grid-template-columns: repeat(2, minmax(0,1fr)); }
.swc-benefits li {
padding: 12px 14px 12px 40px; position: relative;
background: var(--swc-bg-soft); border: 1px solid var(--swc-border);
border-radius: 10px; font-size: .93rem;
}
.swc-benefits li::before {
content: ""; position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
width: 16px; height: 16px; border-radius: 50%;
background: var(--swc-accent); box-shadow: inset 0 0 0 4px #fff;
}
/* ---------- FAQ ---------- */
.swc-faq { display: grid; gap: 8px; }
.swc-faq-item { background: var(--swc-bg); border: 1px solid var(--swc-border); border-radius: 10px; overflow: hidden; }
.swc-faq-item h3 { margin: 0; }
.swc-faq-q {
width: 100%; background: transparent; border: 0; padding: 14px 16px;
display: flex; justify-content: space-between; align-items: center; gap: 12px;
font-weight: 600; font-size: .95rem; text-align: left; color: var(--swc-text);
}
.swc-faq-q:hover { background: var(--swc-bg-soft); }
.swc-faq-icon { transition: transform .2s ease; color: var(--swc-muted); flex: 0 0 auto; }
.swc-faq-q[aria-expanded="true"] .swc-faq-icon { transform: rotate(180deg); }
.swc-faq-a { padding: 0 16px 14px; color: var(--swc-muted); font-size: .93rem; }
/* ---------- Footer (Mode B) ---------- */
.swc-footer { border-top: 1px solid var(--swc-border); background: var(--swc-bg-soft); margin-top: 20px; padding: 28px 0 16px; border-radius: var(--swc-radius) var(--swc-radius) 0 0; }
.swc-footer-inner { display: grid; gap: 22px; grid-template-columns: 1fr; max-width: 1100px; margin: 0 auto; padding: 0 16px; }
.swc-footer-col h3, .swc-footer-title { font-size: .95rem; margin: 0 0 10px; }
.swc-footer-col ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 6px; }
.swc-footer-col a { color: var(--swc-muted); font-size: .9rem; }
.swc-footer-col a:hover { color: var(--swc-accent); }
.swc-brand-footer { margin-bottom: 8px; }
.swc-footer-desc { color: var(--swc-muted); font-size: .9rem; max-width: 320px; }
.swc-footer-bottom { text-align: center; margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--swc-border); color: var(--swc-muted); font-size: .85rem; }
.swc-footer-bottom p { margin: 0; }
/* ---------- AD SLOTS ---------- */
.swc-ad {
margin: 22px 0;
padding: 10px;
background: #fbfcfe;
border: 1px dashed var(--swc-border);
border-radius: var(--swc-radius);
text-align: center;
position: relative;
overflow: hidden;
min-height: 70px;
}
.swc-ad-label {
display: block;
font-size: .68rem;
text-transform: uppercase;
letter-spacing: .08em;
color: #94a3b8;
margin-bottom: 6px;
font-weight: 600;
}
.swc-ad-inner {
display: flex;
align-items: center;
justify-content: center;
min-height: 60px;
width: 100%;
}
.swc-ad-inner ins { display: block; width: 100%; }
.swc-ad-placeholder {
color: #cbd5e1;
font-size: .85rem;
padding: 24px 10px;
width: 100%;
}
/* ---------- Responsive ---------- */
@media (min-width: 600px) {
.swc-stats { grid-template-columns: repeat(3, minmax(0,1fr)); }
.swc-benefits { grid-template-columns: repeat(2, minmax(0,1fr)); }
}
@media (min-width: 900px) {
.swc-stats { grid-template-columns: repeat(6, minmax(0,1fr)); }
.swc-footer-inner { grid-template-columns: 1.4fr 1fr 1fr; }
.swc-card { padding: 28px; }
.swc-hero { padding: 56px 0 28px; }
}
@media (max-width: 720px) {
.swc-nav-toggle { display: inline-flex; }
.swc-nav {
position: absolute; top: calc(100% + 1px); left: 0; right: 0;
background: #fff; border-bottom: 1px solid var(--swc-border);
padding: 8px 16px 16px; display: none;
}
.swc-nav.swc-open { display: block; }
.swc-nav ul { flex-direction: column; gap: 2px; }
.swc-nav a { display: block; padding: 12px; }
.swc-header-inner { position: relative; padding: 12px 16px; }
.swc-brand-tag { display: none; }
.swc-actions { flex-direction: column; }
.swc-btn { width: 100%; justify-content: center; }
.swc-ad { margin: 16px 0; padding: 8px; }
.swc-ad-placeholder { padding: 16px 8px; font-size: .78rem; }
}
@media (prefers-reduced-motion: reduce) {
.swc-app *, .swc-app *::before, .swc-app *::after {
animation-duration: .001ms !important;
transition-duration: .001ms !important;
}
}
</style>
<script>
/* =========================================================
SMART WORD COUNTER — APPLICATION SCRIPT
========================================================= */
(function () {
"use strict";
var SWC_CONFIG = {
showHeader: false,
showFooter: false,
wordsPerMinute: 200,
urls: {
privacy: "#",
terms: "#",
about: "#",
contact: "#"
}
};
function ready(fn) {
if (document.readyState !== "loading") fn();
else document.addEventListener("DOMContentLoaded", fn);
}
ready(function () {
var root = document.getElementById("swc-app");
if (!root) return;
var textarea = root.querySelector("#swc-textarea");
var liveStatus = root.querySelector("#swc-live-status");
var feedback = root.querySelector("#swc-feedback");
var btnCopy = root.querySelector("#swc-copy");
var btnClear = root.querySelector("#swc-clear");
var btnDown = root.querySelector("#swc-download");
var statWords = root.querySelector("#swc-words");
var statChars = root.querySelector("#swc-chars");
var statCharsNS= root.querySelector("#swc-chars-ns");
var statSent = root.querySelector("#swc-sentences");
var statPara = root.querySelector("#swc-paragraphs");
var statRead = root.querySelector("#swc-reading");
var header = root.querySelector("#swc-header");
var footer = root.querySelector("#swc-footer");
if (SWC_CONFIG.showHeader && header) header.hidden = false;
if (SWC_CONFIG.showFooter && footer) footer.hidden = false;
var yearEl = root.querySelector("#swc-year");
if (yearEl) yearEl.textContent = String(new Date().getFullYear());
if (SWC_CONFIG.showFooter) {
var urlMap = SWC_CONFIG.urls || {};
root.querySelectorAll("[data-swc-url]").forEach(function (a) {
var key = a.getAttribute("data-swc-url");
if (urlMap[key] && urlMap[key] !== "#") a.setAttribute("href", urlMap[key]);
});
}
/* ---------- Counting Logic ---------- */
var segmenter = null;
try {
if (typeof Intl !== "undefined" && typeof Intl.Segmenter === "function") {
segmenter = new Intl.Segmenter(undefined, { granularity: "word" });
}
} catch (e) { segmenter = null; }
function countWords(text) {
if (!text) return 0;
if (segmenter) {
var count = 0;
var it = segmenter.segment(text)[Symbol.iterator]();
for (var r = it.next(); !r.done; r = it.next()) {
if (r.value && r.value.isWordLike) count++;
}
return count;
}
var parts = text.trim().split(/\s+/u);
if (parts.length === 1 && parts[0] === "") return 0;
return parts.length;
}
function countCharsIncluding(text) { return Array.from(text).length; }
function countCharsExcluding(text) {
var stripped = text.replace(/\s+/gu, "");
return Array.from(stripped).length;
}
function countSentences(text) {
var trimmed = text.trim();
if (!trimmed) return 0;
var matches = trimmed.match(/[^.!?…]+[.!?…]+(\s|$)/gu);
if (matches && matches.length) return matches.length;
return 1;
}
function countParagraphs(text) {
if (!text || !text.trim()) return 0;
var blocks = text.split(/\n\s*\n+/u);
var count = 0;
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].trim().length > 0) count++;
}
return count;
}
function readingTime(words) {
if (words === 0) return "0 min";
var minutes = words / SWC_CONFIG.wordsPerMinute;
if (minutes < 1) return "Less than 1 min";
if (minutes < 60) return Math.round(minutes) + " min";
var h = Math.floor(minutes / 60);
var m = Math.round(minutes % 60);
return h + "h " + m + "m";
}
/* ---------- Render ---------- */
var rafId = null;
function updateStats() {
var text = textarea.value;
var words = countWords(text);
var chars = countCharsIncluding(text);
var charsNS = countCharsExcluding(text);
var sentences = countSentences(text);
var paragraphs = countParagraphs(text);
var read = readingTime(words);
statWords.textContent = words.toLocaleString();
statChars.textContent = chars.toLocaleString();
statCharsNS.textContent = charsNS.toLocaleString();
statSent.textContent = sentences.toLocaleString();
statPara.textContent = paragraphs.toLocaleString();
statRead.textContent = read;
var hasText = text.trim().length > 0;
btnCopy.disabled = !hasText;
btnClear.disabled = !hasText;
btnDown.disabled = !hasText;
liveStatus.textContent =
words + " words, " + chars + " characters, " +
sentences + " sentences, " + paragraphs + " paragraphs.";
}
function scheduleUpdate() {
if (rafId) return;
rafId = requestAnimationFrame(function () {
rafId = null;
updateStats();
});
}
/* ---------- Feedback ---------- */
var feedbackTimer = null;
function setFeedback(msg, kind) {
feedback.textContent = msg || "";
feedback.className = "swc-feedback" + (kind ? " swc-" + kind : "");
if (feedbackTimer) clearTimeout(feedbackTimer);
if (msg) {
feedbackTimer = setTimeout(function () {
feedback.textContent = "";
feedback.className = "swc-feedback";
}, 3500);
}
}
/* ---------- Copy ---------- */
btnCopy.addEventListener("click", function () {
var text = textarea.value;
if (!text) return;
function fallbackCopy() {
try {
textarea.focus();
textarea.select();
var ok = document.execCommand && document.execCommand("copy");
if (ok) setFeedback("Text copied to clipboard.", "ok");
else setFeedback("Could not copy. Please copy manually.", "err");
} catch (e) {
setFeedback("Could not copy. Please copy manually.", "err");
} finally {
var end = textarea.value.length;
try { textarea.setSelectionRange(end, end); } catch (e) {}
}
}
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(
function () { setFeedback("Text copied to clipboard.", "ok"); },
function () { fallbackCopy(); }
);
} else {
fallbackCopy();
}
});
/* ---------- Clear ---------- */
btnClear.addEventListener("click", function () {
if (!textarea.value) return;
var ok = window.confirm("Clear all text? This cannot be undone.");
if (!ok) return;
textarea.value = "";
updateStats();
textarea.focus();
setFeedback("Text cleared.", "ok");
});
/* ---------- Download ---------- */
btnDown.addEventListener("click", function () {
var text = textarea.value;
if (!text) return;
var blob, url;
try {
blob = new Blob([text], { type: "text/plain;charset=utf-8" });
url = URL.createObjectURL(blob);
var a = document.createElement("a");
a.href = url;
a.download = "smart-word-counter-text.txt";
a.style.display = "none";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
setFeedback("Download started.", "ok");
} catch (e) {
setFeedback("Download failed. Please try again.", "err");
} finally {
if (url) setTimeout(function () { URL.revokeObjectURL(url); }, 1500);
}
});
/* ---------- Input Events ---------- */
textarea.addEventListener("input", scheduleUpdate);
textarea.addEventListener("change", scheduleUpdate);
textarea.addEventListener("paste", function () { setTimeout(scheduleUpdate, 0); });
textarea.addEventListener("cut", function () { setTimeout(scheduleUpdate, 0); });
/* ---------- Mobile Nav (Mode B) ---------- */
var navToggle = root.querySelector("#swc-nav-toggle");
var nav = root.querySelector("#swc-nav");
if (navToggle && nav) {
navToggle.addEventListener("click", function () {
var open = nav.classList.toggle("swc-open");
navToggle.setAttribute("aria-expanded", open ? "true" : "false");
navToggle.setAttribute("aria-label", open ? "Close navigation menu" : "Open navigation menu");
});
nav.addEventListener("click", function (e) {
if (e.target && e.target.tagName === "A") {
nav.classList.remove("swc-open");
navToggle.setAttribute("aria-expanded", "false");
navToggle.setAttribute("aria-label", "Open navigation menu");
}
});
navToggle.addEventListener("keydown", function (e) {
if (e.key === "Escape" && nav.classList.contains("swc-open")) {
nav.classList.remove("swc-open");
navToggle.setAttribute("aria-expanded", "false");
navToggle.focus();
}
});
}
/* ---------- FAQ Accordion ---------- */
root.querySelectorAll(".swc-faq-q").forEach(function (btn) {
btn.addEventListener("click", function () {
var expanded = btn.getAttribute("aria-expanded") === "true";
var panelId = btn.getAttribute("aria-controls");
var panel = document.getElementById(panelId);
btn.setAttribute("aria-expanded", expanded ? "false" : "true");
if (panel) panel.hidden = expanded;
});
});
/* ---------- Init ---------- */
updateStats();
});
})();
</script>
⬇️ Download Now