Docs: namespaced icon keys, picker sources, and third-party notices

- ADMIN-SPEC §3.3: picker sources (curated Lucide, curated Font Awesome
  Free solid subset, emoji input), stored lucide:/fa:/emoji: keys, legacy
  bare-name handling, and fallback glyphs.
- PANEL-SPEC §3.2/§3.3: open-card tile resolves the keys (Lucide stroked,
  Font Awesome filled, emoji as text) with the star fallback; the sealed
  card keeps its static star.
- DESIGN-HANDOFF: mark the icon-subset open question resolved (dated).
- ENTITIES-AND-SERVICES: payload example uses a namespaced icon key.
- THIRD-PARTY-NOTICES.md: Font Awesome Free (icons CC BY 4.0, fonts
  SIL OFL 1.1, code MIT) and Lucide (ISC), generated from
  tools/icons/curated-icons.json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-26 08:27:14 -04:00
co-authored by Claude Opus 5.5
parent 3bd30a0b9f
commit 1bddc9fde9
5 changed files with 73 additions and 7 deletions
+31
View File
@@ -0,0 +1,31 @@
# Third-party notices
NestQuest bundles glyph data from the icon sets below. The curated names are listed in
`tools/icons/curated-icons.json`; `tools/icons/generate.mjs` reads each glyph's SVG path
data from the locally installed packages and generates it into both bundles
(`admin/src/icons/registry.generated.ts` and `frontend/src/icons/registry.generated.ts`).
Nothing is loaded from a CDN or fetched at runtime. The package versions used are recorded
in the header of each generated file.
## Font Awesome Free
- Project: <https://fontawesome.com> · repository: <https://github.com/FortAwesome/Font-Awesome>
- Package: `@fortawesome/free-solid-svg-icons`
- Licence: <https://fontawesome.com/license/free>
- Icons: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)
- Fonts: [SIL OFL 1.1](https://openfontlicense.org)
- Code: [MIT](https://opensource.org/licenses/MIT)
- Use in NestQuest: a curated subset of the Free **solid** icon set, embedded as SVG path
data. No fonts are bundled.
Font Awesome Free by @fontawesome — https://fontawesome.com — icons licensed under CC BY 4.0.
## Lucide
- Project: <https://lucide.dev> · repository: <https://github.com/lucide-icons/lucide>
- Package: `lucide-react`
- Licence: [ISC](https://github.com/lucide-icons/lucide/blob/main/LICENSE)
- Use in NestQuest: a curated subset of Lucide icons, embedded as SVG path data.
Lucide icons are Copyright (c) Lucide Contributors, licensed under the ISC License.
Portions derived from Feather are Copyright (c) Cole Bemis, licensed under the MIT License.
+27 -2
View File
@@ -84,8 +84,33 @@ Footer: `Cancel` (flex 1, bordered) + `Save changes` (flex 2, gradient), both 13
padding. Sheet enters over the dimmed list in `--nq-dur-modal`.
### 3.3 Icon picker
Each definition carries a Lucide glyph, shown on both surfaces. **The allowed subset is not
yet defined** — pick 24–40 household-relevant glyphs and ship them as a grid picker.
Each definition carries one optional icon, shown on both surfaces. The picker offers three
sources:
- **Lucide** — a grid of the curated Lucide glyphs, drawn stroked.
- **Font Awesome** — a grid of a curated subset of the Font Awesome Free *solid* set,
drawn filled.
- **Emoji** — a text input; the typed emoji is stored as entered (not trimmed) and must be
1–8 code points with no whitespace, control characters, `<`, `>` or `&`.
Both curated lists come from `tools/icons/curated-icons.json`; their glyph path data is
generated into the admin and panel bundles by `tools/icons/generate.mjs` (no CDN, no
runtime fetch). See `THIRD-PARTY-NOTICES.md` for licences.
The stored value is a **namespaced key**:
| Source | Stored key | Example |
|---|---|---|
| Lucide | `lucide:<name>` | `lucide:dog` |
| Font Awesome | `fa:<name>` | `fa:paw` |
| Emoji | `emoji:<grapheme>` | `emoji:🐶` |
`<name>` is a lowercase kebab name (`[a-z0-9-]`, no leading or trailing `-`). A **legacy
bare name** written before namespacing (`dog`) reads as `lucide:<name>` — the API returns it
namespaced, and any write of a bare name is stored as `lucide:<name>`; no data migration. An
empty value clears the icon. An empty, unknown, or unresolvable key renders the **fallback
glyph** — in the admin, the generic task glyph (clipboard with a check); on the panel, the
star (`PANEL-SPEC.md` §3.2).
## 4. Schedule (1f)
+3 -2
View File
@@ -78,5 +78,6 @@ The panel speaks tabletop; the admin speaks plainly. Both sit on the same `quest
decide before shipping the card.
- No gamification is in scope. XP, levels, streaks and rarity were explicitly deferred,
but the append-only event log already supports computing them later.
- Icon per quest definition is chosen by the parent from a Lucide subset; the subset is
not yet defined (`ADMIN-SPEC.md` §3.3).
- Icon per quest definition is chosen by the parent from curated Lucide and Font Awesome
Free sets or as an emoji, stored as a namespaced key (`lucide:`/`fa:`/`emoji:`) —
resolved 2026-09-26, see `ADMIN-SPEC.md` §3.3.
+1 -1
View File
@@ -35,7 +35,7 @@ implementer's call), shaped:
{
"instances": [
{ "id": 4821, "definition_id": 12, "child_id": 3, "title": "Fill bird feeder",
"icon": "bird", "window": "afternoon", "due_time": "17:00",
"icon": "lucide:bird", "window": "afternoon", "due_time": "17:00",
"state": "open", "overdue": true, "completed_at": null, "on_time": null }
]
}
+11 -2
View File
@@ -91,7 +91,14 @@ collapse the column, the three-column rhythm is the layout.
`--nq-p-quest-min-height` 116px, radius 12px, `--nq-p-card-open`, 1px
`--nq-p-card-border`, `--nq-p-card-shadow`, padding 22px, 22px gap, row layout:
1. **Icon tile** 64×64, radius 10px, `--nq-p-icon-tile`, Lucide glyph 34px white.
1. **Icon tile** 64×64, radius 10px, `--nq-p-icon-tile`, glyph 34px white — the
definition's icon, resolved from its namespaced key (`ADMIN-SPEC.md` §3.3):
`lucide:<name>` draws the curated Lucide glyph **stroked** (fill none, stroke-width 2,
round caps and joins); `fa:<name>` draws the curated Font Awesome glyph **filled**;
`emoji:<grapheme>` renders the emoji **as text**. A legacy bare name resolves as
`lucide:<name>`. No icon, or any key that does not resolve (unknown namespace or name,
malformed emoji), falls back to the **star** glyph. Glyph data is bundled from the
shared registry — nothing is fetched at runtime.
2. **Text** title 30px/700 Cinzel `--nq-p-ink`; meta 22px/600 Nunito
`--nq-p-ink-secondary` reading `Due by <h:mm A>`. If past due:
`Overdue · due <h:mm A>` in 22px/700 Cinzel uppercase, tracking .10em,
@@ -106,7 +113,9 @@ Both the card body and the button open the confirm dialog (§4). Press feedback:
### 3.3 Quest card — sealed
`--nq-p-card-done`, `opacity: .82`, no shadow, **not tappable**. Icon tile
`--nq-p-icon-tile-done` with the glyph in `--nq-p-ink-secondary`. Title 30px/700 Cinzel
`--nq-p-icon-tile-done` with the glyph in `--nq-p-ink-secondary`. The sealed tile keeps
the static star glyph — it does **not** render the definition icon — alongside the wax
seal below. Title 30px/700 Cinzel
`--nq-p-ink-muted` with `text-decoration: line-through`. Meta reads
`Claimed <h:mm A>` 22px/600 Nunito `--nq-p-ink-secondary`.