Skip to content

hotspot, info-circle and slide-box - #23

Merged
ecropolis merged 5 commits into
mainfrom
claude/reveal-cards
Sep 26, 2026
Merged

ecropolis merged 5 commits into
mainfrom
claude/reveal-cards

Conversation

@ecropolis

@ecropolis ecropolis commented Sep 26, 2026 •

Copy link
Copy Markdown
Owner

Round 3, chip A: three reveal cards, one commit each (plus a naming fix and a guard, below), built from the UABB references and the decisions in library-round-3.md. Each is one self-contained .astro with no imports, themed through its own prefix with fallbacks, with a demo, a catalogue entry and a section in the new scripts/check-reveal-cards.mjs (in the npm run check chain).

hotspot

What it does. Numbered pins at percent coordinates on a <figure> image; each opens a panel (title and text, optionally a small image). Hover and focus open a pin on fine pointers; click and tap toggle everywhere. One panel is open at a time. The optional tour adds a Start tour button, then "2 of 5", Previous, Next and End tour in each panel, plus repeat. autoplay (ms) steps on only after Start tour is pressed. Panels open toward the larger space by a build-time rule. In a figure under 34rem the open panel sits under the image.

Accessibility.

  • Each pin is a 44px <button aria-expanded> with aria-controls pointing at its panel. It is named by the title and described by the text through aria-describedby.
  • Escape closes a panel and returns focus to its pin. A click or tap off the pins closes it too.
  • Tour steps move focus to the same control in the next panel. Each step's controls are a group labelled "2 of 5" plus the title.
  • Autoplay waits while the pointer is on the open pin or panel, while keyboard focus is in the figure, and while the tab is hidden. It never runs under reduced motion.

Without JavaScript. The pins are # links into a numbered <ol role="list"> under the image. Every point's title, text and image is on the page, and print shows the list.

What the check pins.

  • 9 golden placement cases for the <hs-place> block.
  • On the demo page and the gallery index: link pins at the fixture's coordinates pointing at their list items, and button pins hidden with aria-expanded="false", aria-controls and aria-describedby.
  • Each item's placement matches the rule.
  • Tour markup follows repeat: no Previous on the first step and no Next on the last unless it is set.
  • The script is emitted once per page, and the pin rule keeps its 44px size.
  • Fallback contrast: 14.75, 6.09 and 7.27 to 1.
  • 7 mutations are refused.

Search. image hotspot is 320/mo at difficulty 23. The page should also rank for these variants:

Query Volume/mo Difficulty
interactive image 390 10
image hotspots 320 24
image tooltip 70 13

"image map" (760/41) is the old HTML <map> term. "hotspot" (90,500/93) is Wi-Fi.

info-circle

What it does. Between 2 and 10 items (an icon or a round image each) sit on a circle, with positions computed at build by sin/cos, clockwise from the top. The chosen item's title, text and optional link show in the middle. Hover, focus and click choose, and startAt sets the item chosen on load. Optional autoplay comes with a pause button.

Accessibility.

  • Items are <button aria-pressed>, with exactly one pressed, and aria-controls pointing at the centre.
  • The centre is aria-live="polite". It switches to off while autoplay runs, so nothing is read out on its own.
  • Autoplay has a pause button (WCAG 2.2.2). It waits on hover, focus, off screen and in a hidden tab. A click on an item stops it for good, and it never runs under reduced motion.
  • Items are at least 44px.

Without JavaScript. The element is a vertical list with every item's icon, title and text showing. The same list shows in any container under 28rem. That list is the only copy of the content; the centre gets a copy of the chosen entry.

What the check pins.

  • Golden ring positions for n = 2 to 6, with three decimals and never -0.
  • The circle renders hidden and the centre is polite and empty.
  • Each button's --inc-x/--inc-y matches the geometry, and aria-pressed marks startAt only.
  • List headings, texts and links match the fixture.
  • The pause button is present only with autoplay.
  • Each demo icon is byte-for-byte the installed Font Awesome Free path, with its attribution comment.
  • Fallback contrast: 13.24, 7.27 and 6.53 to 1.
  • 8 mutations are refused.

Search. circular infographic is 320/mo at difficulty 7. "circle infographic" and "infographic circle" are the same cluster. The page should also rank for these variants:

Query Volume/mo Difficulty
info circle 40 10
interactive infographic 320 25
cycle diagram 810 7

"cycle diagram" people are mostly making slides, so it is a variant, not the title.

slide-box

What it does. The front is an icon or image, a title and a line; the back is text and a CTA. The back slides in over the front from direction: up (the default), down, left or right. Hover slides it on fine pointers unless trigger="click", and click, Enter and Space always do. Both panels share one grid cell, so there is no fixed height.

Accessibility.

  • It uses flip-box's contract as a copy, not an import. The card is a real <button aria-expanded aria-controls> named from the title.
  • The panel out of view is inert and aria-hidden.
  • Escape slides the back out and returns focus to the button.
  • On touch, the first tap slides the back in and the second follows its link.
  • Reduced motion crossfades instead of sliding.

Without JavaScript. Both panels render, back below front, with the link.

notFor. It explains flip-box versus slide-box. flip-box is two equal faces; slide-box is a teaser and its detail.

What the check pins.

  • Each direction's parking transform, the open state, and the card's clip.
  • The control renders hidden with aria-expanded="false", and aria-controls points at the back.
  • Both panels are readable, the front has no link, and the CTA is a real link.
  • data-direction and data-trigger match the fixture.
  • The demo's icons are Font Awesome Free.
  • Fallback contrast: 14.75, 7.27 and 7.27 to 1.
  • 8 mutations are refused.

Search. reveal card is 110/mo at difficulty 14. The page should also rank for these variants:

Query Volume/mo Difficulty
sliding card 260 8
card hover effects 30 12
card overlay 50 10

"slide box" itself is 1,300/55, but its results are microscope-slide boxes and toolbox drawer slides. It stays an aka.

All volumes are SE Ranking US, 2026-09-26, and each sits in a comment next to its query.

Verification

  • npm run check and npm run build pass. The check catalogue now holds 25 elements, and the reveal-cards check refuses 23 mutations.
  • The Website type check passes: in a scratch clone of ecropolis/SuperheroTech main, ELEMENTS_SOURCE=<this checkout> npm run check:types reported 0 errors and 0 warnings. Its 12 hints are all in files that already existed.
  • The Website build against this branch generates all three pages, and its check:elements passes.
  • Headless Chrome (Playwright) tested each element:
    • no-JS rendering, hover, click and touch taps;
    • keyboard and Escape with focus return;
    • tour stepping and focus, autoplay pauses, reduced motion;
    • the narrow and phone layouts, with no horizontal scroll at 390px.

Naming

The prefixes are --hs-* for hotspot, --inc-* for info-circle and --slb-* for slide-box.

  • info-circle moved off --ic-*. That is icon's prefix on main (--ic-color).
  • slide-box moved off --sb-* and data-sb. Both belong to scrollbox in Round 4: tags, scrollbox and sticker #20. Slide-box's boot selector would also have visited every scrollbox on a page.
  • The library's rule applies. When two letters are taken, the prefix gets three, as with --anb- and --ofc-.
  • Everything uses the new prefix. Custom properties, classes, data attributes, ids and block markers all changed, so each element matches its prefix everywhere, as flip-box does.

New guard. check-catalog.mjs now refuses two entries whose theming variables share a prefix. It names both entries and the fix. A simulated merge of main and all seven open PRs gives 43 elements and 43 prefixes, with no clash.

The same sweep fixed two other open PRs. I pushed each without force, and each branch's own npm run check is green.

Other notes.

  • The skill is not updated here. Per the round-3 plan, the superhero-ui-library skill sections for all nine elements come in one agent-skills chip after these land.
  • Demo assets are neutral. They are one new SVG room illustration and existing tiles. The icons are Font Awesome Free with their attribution comments, and there is no Adobe Stock.

🤖 Generated with Claude Code

ecropolis and others added 5 commits September 26, 2026 11:30
… a tour

UABB's Hotspot, rebuilt: pins at percent coordinates are 44px buttons with
aria-expanded, named by the title and described by the text. Click, tap,
Enter and Space toggle everywhere; hover and focus also open on fine
pointers. One open at a time, Escape closes and returns focus. The optional
tour carries "2 of 5", Previous, Next and End tour in each panel, with
repeat and an autoplay that starts only from the Start tour button, waits
while the visitor reads and never runs under reduced motion.

Panels open toward the larger space by a build-time rule; below a 34rem
figure the open panel sits under the image. Without JavaScript the pins
link to a numbered list of every point under the image.

scripts/check-reveal-cards.mjs pins placement against golden cases, the
no-JS render and ARIA contract on both pages, the 44px hit area and the
fallback contrast, and refuses seven mutations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
UABB's Info Circle, rebuilt: positions are computed at build (clockwise
from the top, on the circumference) and nothing measures at runtime. Each
item is a button with aria-pressed, exactly one pressed, and aria-controls
to the centre, which is a polite live region. Hover, focus and click
choose. Optional autoplay has a pause button, waits on hover, focus, off
screen and in a hidden tab, stops for good on a click, silences the live
region while it runs and never runs under reduced motion.

In a container under 28rem, and without JavaScript, it is a plain list
with every item's icon, title and text; that list is the only copy of the
content and the centre shows a copy of the chosen entry.

The check adds golden ring positions, the no-JS render and ARIA contract
on both pages, 44px items, fallback contrast, a byte-for-byte Font Awesome
Free pin on the demo's icons, and eight more mutations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
UABB's Slide Box in its overlay style, on flip-box's proven contract: the
card is a real button with aria-expanded and aria-controls to the back;
click, tap, Enter and Space always slide it, hover also does on fine
pointers unless trigger="click". `direction` picks the edge the back comes
from (up by default). The panel out of view is inert and aria-hidden;
Escape slides it out and returns focus. Both panels share one grid cell,
so the card is as tall as the taller one. Reduced motion crossfades.
Without JavaScript both panels render, the back below the front.

notFor says when to pick it over flip-box: two equal faces turn over, a
teaser and its detail slide.

The check adds each direction's parking transform and the clip, the no-JS
render and ARIA contract on both pages, fallback contrast, the Font
Awesome Free pin on the demo's icons, and eight more mutations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
info-circle's --ic-* was icon's prefix (--ic-color), and slide-box's
--sb-* and data-sb are scrollbox's in the open round-4 PR, where
slide-box's boot selector would also have visited every scrollbox on the
page. Following the library's rule when two letters are taken (--anb-,
--ofc-): info-circle is now inc and slide-box slb, in their custom
properties, classes, data attributes, ids and block markers alike, so each
element matches its prefix everywhere, as flip-box does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A host that themes one element through a shared prefix silently themes
the other. Every theming variable's first segment is its prefix; an
element may use several, no two elements may share one. The drill rebuilds
the catalogue from every branch, so a clash between parallel chips fails
there, naming both entries, instead of surfacing on a client site.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ecropolis
ecropolis merged commit 26bcb28 into main Sep 26, 2026
2 checks passed
@ecropolis
ecropolis deleted the claude/reveal-cards branch September 26, 2026 17:06
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