=== Seven Digits Dilemmas ===
Contributors: 7digits
Tags: poll, vote, survey, engagement, shortcode
Requires at least: 6.9
Tested up to: 7.0
Requires PHP: 8.1
Stable tag: 1.2.1
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Two-option dilemma polls in any post via shortcode: one-click voting, animated result bars, live statistics, and SEO-friendly server rendering.

== Description ==

**Every good post has two sides. Let your readers pick one.**

Coffee or tea. Remote or office. Print or digital. A *dilemma* is the smallest possible piece of interactive content — one question, two options, one click — and it is remarkably good at turning a passive reader into a participant.

Seven Digits Dilemmas gives you exactly that. Write a question with two options, paste one shortcode into any post or page, and visitors vote with a single click. No account, no form, no page reload. The moment they choose, the two option cards animate into result bars showing live percentages and vote counts.

A dilemma gives people a reason to stop scrolling, a reason to come back ("who's winning?"), and a reason to share. And every vote is first-party audience insight, stored in your own database — not somebody else's.

= How it works =

1. **Create a dilemma.** Go to **Dilemmas → Add New**, type your question and two options, set a voting period (or leave the 30-day default), and publish.
2. **Drop in the shortcode.** Each dilemma gets its own tag, ready to copy: `[sevendigits_dilemma id="1"]`
3. **Readers vote.** The two options render as real, server-side HTML. A click sends one small REST request, and the cards animate into result bars — percentages, vote counts, and the total underneath.
4. **You watch the split.** The Statistics dashboard shows KPIs, a votes-per-day chart, and a per-dilemma A/B breakdown you can export to CSV.

Behind the scenes, one vote per visitor is enforced *twice*: a first-party cookie on the client, and a unique database index on the server. Clearing the cookie does not buy a second vote.

= One-click voting that just works =

* Visitors vote with a single click; the result view animates in instantly.
* One vote per visitor, enforced by both a first-party cookie and a database-level unique index.
* Per-dilemma voting periods (default 30 days). When a period ends, voting closes automatically but results stay visible with a "closed" badge.
* Schedule a dilemma to open in the future with an explicit start date.
* Works for logged-out visitors — no registration required.

= Make it look like your site =

* Colours, typography, spacing, rectangle height, border radius, max width, and mobile stacking are all configurable from a tabbed Settings screen — no CSS needed.
* Nine result-reveal animations (fade, slide down, slide up, flip, fold, rotate, scale, reveal, or none) with adjustable duration, overridable per dilemma.
* Respects the visitor's reduced-motion preference and falls back to instant transitions.
* Every tab can be restored to its defaults independently, so experimenting is safe.
* BEM-style class names (`sd-dilemma`, `sd-dilemma__option`, `sd-dilemma__results`, …) for theme developers who want to go further in CSS.

= Know what your audience thinks =

* A Statistics dashboard with KPIs, date-range filters, and a top-10 dilemmas chart.
* Per-dilemma drilldowns: the A/B split, a votes-per-day chart, and the most recent votes.
* CSV export of both the overview and per-dilemma vote logs (UTF-8 with BOM, so accented characters open correctly in Excel).
* An append-only audit log of every privileged admin action — who did what, to which dilemma, and when — with configurable retention.
* Full lifecycle management: create, edit, clone, archive, restore, reset votes, delete.

= Fast, private, and dependency-free =

* **Server-side rendering.** The question and both options are real HTML, visible to search engines and no-JS visitors, with an optional Schema.org `Question` JSON-LD block.
* **Cache-friendly.** The pre-vote markup is identical for every visitor, so full-page caches serve a single version; per-visitor state hydrates via one lightweight REST call.
* **No tracking.** No raw IP addresses or user agents are ever stored — only salted hashes, used solely for fraud prevention and rate limiting.
* **No dependencies.** Vanilla JavaScript. No jQuery, no external CDN requests, no build step, no Composer.
* **Translation-ready**, with separate Hungarian and English front-end labels you can edit in Settings, plus locale-aware date formatting.

= Privacy =

The plugin sets a single first-party, strictly-necessary functional cookie (`7d_dv`) whose only purpose is to enforce the one-vote-per-visitor rule. No personal data is collected, no raw IP addresses or user agents are stored (only salted HMAC-SHA256 hashes, for fraud prevention and rate limiting), and nothing is sent to any external service. A ready-made paragraph for your site's privacy policy is provided through the WordPress privacy policy helper.

= External services and bundled libraries =

This plugin does **not** connect to any external service. All processing happens on your own server, and all assets are bundled locally.

It bundles one third-party library: [Chart.js](https://www.chartjs.org/) (MIT licence), loaded only on the plugin's own admin statistics screens — never on the front end.

= REST API =

The plugin registers two endpoints under `sevendigits/v1`:

* `POST /dilemmas/{id}/vote` — casts a vote. Protected by a REST nonce and rate-limited per IP.
* `GET /dilemmas/{id}/results` — returns the public vote counts for a published dilemma. This endpoint is intentionally public: it exposes only the same aggregate numbers already rendered on the page.

= Support =

Seven Digits Dilemmas is built and maintained by **[Seven Digits Media](https://7digits.net)**, a performance-driven digital marketing agency.

Questions, bug reports, feature ideas, or help fitting dilemmas into your content strategy? Get in touch at **[7digits.net](https://7digits.net)** — we read everything, and we are happy to help.

== Installation ==

1. Install the plugin from the WordPress.org plugin directory, or upload the `seven-digits-dilemmas` folder to `/wp-content/plugins/`.
2. Activate the plugin through the **Plugins** menu. Activation creates the plugin's database tables and grants the `sevendigits_manage_dilemmas` capability to Administrators and Editors.
3. Go to **Dilemmas → Add New**, enter a question and two options, and publish.
4. Copy the generated shortcode and paste it into any post or page, for example: `[sevendigits_dilemma id="1"]`
5. Optionally visit **Dilemmas → Settings** to match colours, typography, and animations to your theme.

Deactivating the plugin preserves all data. Deleting it removes the plugin's tables, options, and capability.

== Frequently Asked Questions ==

= Can a visitor vote more than once? =

No. A first-party functional cookie plus a database-level unique index enforce exactly one vote per visitor. The database constraint holds even if the cookie is cleared or forged.

= Does it store IP addresses or personal data? =

No. Only salted HMAC-SHA256 hashes of the IP and user agent are stored, used solely for fraud prevention and rate limiting — never for tracking or profiling. No personal data is collected.

= Does it work with page caching? =

Yes. The pre-vote markup is identical for every visitor, so it caches as a single version. Each visitor's own state (voted or not, and their choice) is hydrated client-side via a lightweight REST call.

= Does it require jQuery, a build step, or a CDN? =

No. The plugin ships plain vanilla JavaScript and locally bundled assets only. It makes no requests to external services.

= Can I style the polls to match my theme? =

Yes. Colours, fonts, sizes, spacing, and animations are configurable from the Settings screen without any CSS. Theme developers can also target the plugin's BEM-style class names directly.

= Can I put more than one dilemma on a page? =

Yes. Each shortcode is independent, with its own question, voting period, animation, and results.

= What happens when a voting period ends? =

Voting closes automatically and the dilemma keeps displaying its final results with a "closed" badge. You can also set an explicit start date so a dilemma opens in the future.

= Is it translation-ready? =

Yes. All strings are translatable (text domain `seven-digits-dilemmas`) and translations are delivered automatically through translate.wordpress.org — no files to install. Separately, the visitor-facing labels ("Total votes:", the closed/opens badges) are editable settings with independent Hungarian and English values, so those read correctly even before a language pack exists.

= Who can manage dilemmas? =

Users with the `sevendigits_manage_dilemmas` capability — Administrators and Editors by default. Every privileged action is recorded in an audit log.

= Where do I get help? =

Use the WordPress.org support forum for this plugin, or contact us directly at [7digits.net](https://7digits.net).

== Screenshots ==

1. A dilemma embedded in a post — the pre-vote state, with both options waiting for a single click.
2. The same dilemma right after voting: the chosen option is highlighted, both cards show percentage and vote count, and the total appears below. (Shown with custom colours; the defaults are a pale blue winner and a near-white runner-up.)
3. All Dilemmas — status, voting period, running totals and A/B split, plus a copy-to-clipboard shortcode for every dilemma.
4. The dilemma editor: question and two options, voting period with optional explicit start and end dates, per-dilemma visual and animation overrides, and a live preview.
5. Settings → Colours: every colour in the widget, including the winning and losing fills after a vote and the "voting closed" badge.
6. Settings → Typography: font family, size, and weight for the question and the option text.
7. Settings → Layout: rectangle height, border radius and width, spacing, max width, and mobile stacking.
8. Settings → Animation defaults: one of nine reveal animations, its duration, and reduced-motion handling.
9. Settings → Behaviour: cookie lifetime, default voting period, Hungarian and English badge and label text, Schema.org output, and audit log retention.
10. The Audit Log — a read-only, filterable record of every privileged action.

== Changelog ==

= 1.2.1 =
* Renamed the shortcode from `[dilemma]` to `[sevendigits_dilemma]` so the tag cannot collide with another plugin.
* Prefixed the plugin's transient keys (results cache and rate-limit counters) with `sevendigits_dilemmas_`.
* Renamed the three custom tables from the `7d_` prefix to `sevendigits_dilemmas*`, and the capability from `manage_dilemmas` to `sevendigits_manage_dilemmas`. Existing installs are migrated automatically on upgrade — tables are renamed in place (no data is copied or lost) and any role holding the old capability is moved to the new one.
* Hardened the inline CSS output: settings-driven values are now escaped with a dedicated CSS-context escaper instead of `esc_attr()`.
* Removed the bundled Hungarian translation files — translations are delivered through translate.wordpress.org.

= 1.2.0 =
* Initial release.

== Upgrade Notice ==

= 1.2.1 =
The shortcode is now `[sevendigits_dilemma id="1"]`. If you used the previous `[dilemma]` tag anywhere, update those posts — the old tag is no longer registered.

= 1.2.0 =
Initial release.
