Skip to content

Modernize banner with backwards-compatible style=classic opt-out#356

Open
rainxchzed wants to merge 1 commit intokeepandroidopen:mainfrom
rainxchzed:feat/banner-modern-style
Open

Modernize banner with backwards-compatible style=classic opt-out#356
rainxchzed wants to merge 1 commit intokeepandroidopen:mainfrom
rainxchzed:feat/banner-modern-style

Conversation

@rainxchzed
Copy link
Copy Markdown

TL;DR

This PR refreshes public/banner.js with a slimmer, more embeddable warning bar while preserving every existing query parameter, language string, and embed contract. Embedders who prefer the current look can pin to it with one new opt-in parameter: ?style=classic.

Why

  • Visual weight on host sites: the current bold all-caps red banner can dominate supporter pages and discourage embedding above the fold.
  • No theme awareness: the banner ignores prefers-color-scheme, which clashes with the growing number of dark-themed supporter sites.
  • Accessibility gaps: no prefers-reduced-motion fallback and no RTL flow handling for Arabic / Hebrew / Persian embedders.

What changes

  • Slim amber warning bar replaces the all-caps red block, with a warning-triangle SVG icon for instant recognition (filled, ISO-7010-style for crisp rendering at 18–22 px).
  • Countdown is rendered in a monospace pill so digits stop reflowing on each tick.
  • A subtle Read why CTA link sits next to the message for clearer affordance.
  • Adds dark-mode tokens (light / dark / auto), prefers-reduced-motion fallback, and RTL mirroring (arrow flips, inset-inline-end everywhere).
  • Visually-hidden aria-live="polite" status node updates once per day (not per tick) so screen readers aren't flooded by the countdown.

What stays the same

  • Every existing query param works identically: lang, id, size, link, hidebutton, animation.
  • All 30+ language strings are unchanged — no translator action required (verified byte-equal).
  • Same <script src="…/banner.js"> embed pattern — no markup changes on supporter sites.
  • Same localStorage dismiss key (kao-banner-hidden) and 30-day re-show window.
  • Same DOM injection point (target id or prepend(<body>)).
  • Same single-file IIFE / ES5 floor — var, string concatenation, no template literals, no arrow functions. Intl.NumberFormat({ style: "unit" }) remains the highest floor.

New optional params

Param Values Default Purpose
theme auto | light | dark auto Override system theme detection
style modern | classic modern classic renders the pre-PR design 1:1

Compatibility & rollout

  • style=classic preserves the original look pixel-for-pixel — single-param opt-out for embedders. The classic block is namespaced under .kao-banner.kao-banner--style-classic and reuses the original CSS verbatim, so the red Arial-Black aesthetic is byte-faithful (verified visually side-by-side).
  • Modern selectors are namespaced under .kao-banner.kao-banner--style-modern so they cannot leak into classic.
  • Close-button keeps both the legacy .kao-banner-close and the new .kao-banner__close class hooks for any embedder CSS overrides in the wild.
  • Deployment is a single-file replacement of public/banner.js; no new assets, no build step, no breaking change to the embed contract.

Try it

<!-- Default (modern, auto theme) -->
<script src="https://keepandroidopen.org/banner.js?lang=en"></script>

<!-- Force dark theme -->
<script src="https://keepandroidopen.org/banner.js?lang=en&theme=dark"></script>

<!-- Force light theme -->
<script src="https://keepandroidopen.org/banner.js?lang=en&theme=light"></script>

<!-- Original design preserved 1:1 -->
<script src="https://keepandroidopen.org/banner.js?lang=en&style=classic"></script>

Verified locally

  • All three sizes (normal / mini / minimal) × both styles (modern / classic) × both themes (light / dark) × theme=auto under both light and dark OS settings.
  • All 30+ locales render their localized strings (German, Russian, Thai, Japanese, Chinese, Korean, etc.).
  • Arabic with dir="rtl": arrow flips, dismiss button mirrors to the start side.
  • animation=off disables the icon pulse (modern) and the box-shadow pulse (classic).
  • hidebutton=off removes the close button.
  • link=none removes the CTA link in modern; preserves text-only behavior in classic.
  • Close → reload re-suppresses; advancing the timestamp 31 days re-shows.
  • Tested under prefers-reduced-motion: reduce — animations replaced with static states.
  • No console errors / warnings across all variants.

Open questions

  1. Should style=classic be the default for the first ~2 weeks (soft launch) before flipping the default to modern? Happy to flip the ternary.
  2. Should position=top|inline ship in this PR, or land as a follow-up? It's not implemented here — kept the PR small.

Closing

Fully open to your judgment here — the campaign's voice and visual urgency are yours to set, and we'd be glad to tune tokens (color, height, copy weight), drop sections, or pull the PR back entirely if the current design is serving the cause better. Thank you for keeping this banner maintained and easy to embed; happy to iterate on whatever direction is most useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant