Skip to content
Back to skills

Tinyworld Block Button Style

ASecurity

Use when styling any tool/block button, palette tile, icon chip, or new clickable square in Tiny World Builder. The locked-in "block" aesthetic — a raised square with a dark category-colored outline, an inner white line, and a white-bodied glyph outlined in the same dark color. Apply this whenever a new icon button/tile is added so the UI stays consistent.

  • 1,587 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 3, 2026
designgogit

Works with

  • cli

Security analysis

A100/100

Scanned September 3, 2026

npx -y skills add jasonkneen/tiny-world-builder --skill tinyworld-block-button-style --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Tinyworld Block Button Style?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Tinyworld Block Button Style
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jasonkneen-tinyworld-block-button-style/badge)](https://www.skillsdirectory.com/skills/jasonkneen-tinyworld-block-button-style)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: tinyworld-block-button-style
description: Use when styling any tool/block button, palette tile, icon chip, or new clickable square in Tiny World Builder. The locked-in "block" aesthetic — a raised square with a dark category-colored outline, an inner white line, and a white-bodied glyph outlined in the same dark color. Apply this whenever a new icon button/tile is added so the UI stays consistent.
---

# Tiny World "Block" button style (locked design language)

The canonical look for tool/block buttons (the floating palette `.tool-palette`,
the group popout `.flyout`, and the bottom toolbar `.tool` blocks). Jason signed
off on this as the house style — reuse it for any new icon square/tile.

## The three ingredients

1. **Outlined square** — a `1.5px` border in a *darkened* version of the tile's
   category color, an inner white line, and a slight raised lift.
2. **Outlined glyph** — a white icon body with a matching dark colored outline,
   drawn with `paint-order: stroke` + `vector-effect: non-scaling-stroke` so one
   `stroke-width` looks identical across every glyph viewBox (24, 512, …).
3. **Category color** — the dark outline is the darkened category tint; the
   square keeps a faint translucent category background.

## Category palette

| posType   | background tint            | dark outline (border + glyph stroke) |
|-----------|----------------------------|--------------------------------------|
| terrain   | `rgba(123,194,48,0.16)`    | `#3a6511`                            |
| primary   | `rgba(23,107,235,0.13)`    | `#1e428a`                            |
| tertiary  | `rgba(254,146,14,0.18)`    | `#a05600`                            |
| shield    | `rgba(45,215,255,0.15)`    | `#0e5f7e`                            |
| neutral   | (none)                     | `#2f3b57` (default `--glyph-outline`)|

The dark outline = the category tint darkened ~50–60%. For a new category,
pick the same hue at roughly that lightness.

## Recipe (lives in `styles/tiny-world.css`)

Glyph (white body + colored outline):

```css
.tool .tool-glyph { color: #fff; --glyph-outline: #2f3b57; }
.tool .tool-glyph svg { fill: currentColor; overflow: visible; }
.tool .tool-glyph svg * {
  fill: currentColor;
  stroke: var(--glyph-outline);
  stroke-width: 2.1;
  vector-effect: non-scaling-stroke;
  paint-order: stroke;
  stroke-linejoin: round;
  stroke-linecap: round;
}
/* per posType: set --glyph-outline on the .tool-glyph */
```

Raised, outlined square (per posType; same pattern for `.tool` and
`.tool.flyout-tool[data-pos-type]`):

```css
.tool[data-pos-type="primary"] {
  border: 1.5px solid #1e428a;                 /* dark category outline */
  box-shadow:
    inset 0 0 0 1.5px rgba(255,255,255,0.92),   /* inner white line */
    inset 0 -3px 0 rgba(30,66,138,0.22),        /* bottom bevel */
    0 2px 3px -1px rgba(20,30,50,0.22);         /* raised drop shadow */
}
```

## Applying it to a new button/tile

- Give the tile a `data-pos-type` (terrain/primary/tertiary) — the existing
  rules then paint it automatically. `posTypeForTool()` in
  `19-tools-toolbar.js` maps a tool to its posType.
- Bottom-toolbar buttons must all carry a stable `data-pos-type`: Select uses
  `primary`, Erase uses `neutral`, and inactive group buttons use
  `posTypeForToolGroup(group)` so their borders do not disappear until a group
  becomes active. The late `Unified block buttons` CSS block applies the same
  raised border/inner-line treatment to `.toolbar .tool`,
  `.toolbar .tool-group-btn`, `.flyout .tool.flyout-tool`, and the floating
  `.tool-palette`; keep that block after generic flyout sizing rules.
- Selection radial buttons stay circular, but they still use the same category
  contract. `33-radial-menu.js` passes `data-pos-type` through `makeBtn()`
  (root actions = `primary`, close/back = `neutral`, reset swatch = `neutral`).
  Close/Back sits as the compact center button (`.radial-center`), with action
  buttons on a tight orbit; do not put close/back back into an outer top slot or
  expand the ring radius. The mooring style radial in `36-mooring-interaction.js`
  uses `tertiary`. Style them via `.radial-btn[data-pos-type]`, not by returning
  to pale generic circles.
- Radial labels/icons need a separate high-contrast `--radial-ink` on an
  opaque `--radial-bg`. Do not use very transparent category fills for radial
  buttons; the 3D scene bleeds through and makes the icon text unreadable.
- Appbar icon buttons, the single language picker trigger, and the left side-rail
  controls are also category chrome now. Keep `data-pos-type` on those static
  HTML buttons and style them through `.appbar .btn.icon[data-pos-type]`,
  `.controls .btn.icon[data-pos-type]`, and `.language-trigger[data-pos-type]`.
  The language choices live in the upward menu; do not put the four-flag strip
  back in the appbar.
- The top-center `.world-pill[data-pos-type="primary"]` keeps the primary blue
  outline, but its resting fill is deliberately bright white glass
  (`rgba(255,255,255,0.82)`) rather than the generic blue primary tint so the
  world selector matches the whiter chrome surfaces. Its hover state must keep
  `transform: translateX(-50%)`; do not apply the generic hover lift to this
  fixed centered pill or it jumps.
- The token corner is deliberately plain text, not a pill panel. Keep
  `.token-corner` free of `data-pos-type`, borders, backdrop blur, and hover
  transforms; only the nested GitHub link uses
  `.token-corner .btn.icon[data-pos-type]` block-button chrome.
- Build the icon with `buildToolButton(tool, { flyout: true })` so it reuses the
  `.tool-glyph` / `.tool-icon` machinery and the outline rules.
- Bottom-toolbar utility buttons use `buildToolbarUtilityButton(...)` and the
  same `.tool icon-only` block square. Keep Home and Shield as adjacent utility
  buttons at the front of the bottom toolbar; Shield uses `data-pos-type="shield"`
  and reflects the raised/lowered `VoxelShield` state with `.active` and
  `aria-pressed`.
- Active/pressed toolbar states must override dark/after-hours theme rules: keep
  the category outline color, use a light raised fill, a visible 2px outer ring,
  and a short bottom accent bar so selected tools do not read like pale disabled
  buttons. Because the theme blocks use `body.ui-theme-dark ... !important`,
  add matching `body.ui-theme-dark` active selectors after the generic selected
  block; a lower-specificity late rule is not enough.
- If a component hard-codes button `background`, `color`, `border`, or local
  category variables (for example launch/game-type, auth, account, or corner
  chrome buttons), add a component-scoped `body.ui-theme-dark ...` rule after the
  light rule. Do not rely on inherited `--ink`: `background: var(--ink)` plus
  `color: #fff` becomes unreadable when dark mode flips `--ink` to light text.
- Light-mode selected option chips/tabs in the selection and Layers properties
  panels are part of the same glass language. Keep their old translucent fills
  (`rgba(60,130,247,0.15)` for active chips, `rgba(23,107,235,0.14)` for active
  Layers tabs) plus backdrop blur; do not replace them with solid white fills.
- Mono/utility icons (select, erase) use `.tool-icon` and render as
  `fill:none; stroke:currentColor` outlines (the rule is shared between
  `.toolbar`, `.flyout`, and `.tool-palette`). Keep them line-art, not filled.
- Never go back to solid-filled (`fill:currentColor; stroke:none`) glyphs for
  block buttons — that is the *old* look this style replaced.

## Gotchas

- `vector-effect`/`paint-order` must be on the path/shape elements
  (`svg *`), not the `<svg>` — they don't inherit.
- The global `[data-tooltip]{position:relative}` rule can clobber `position` at
  tied specificity; if a styled button mispositions, raise selector specificity
  (e.g. `button.foo`).
- Verify in a real browser, not synthetic events: sample the rendered pixels
  (a primary block reads dark border `30,66,138` → white line `~250` → tint).

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.