Plain text and markdown snippets with raw URLs. Browse, search, and share with LLMs, tools, or anyone.
qwen-coordinates
# Qwen GUI Coordinates — MAI-UI / Qwen-UI-Agent Reference **Primary target: Qwen-UI-Agent (MAI-UI).** Qwen2.5-VL and Qwen3-VL are covered only as the "legacy path" you also need to support. **Source of truth for this document:** `github.com/Tongyi-MAI/MAI-UI`, files `MAI-UI/src/mai_naivigation_agent.py`, `mai_grounding_agent.py`, `prompt.py`, `utils.py`, and `cookbook/grounding.ipynb`. Facts below tagged `[SOURCE]` were read directly from that code. Facts tagged `[PAPER]` come from the technical report and **are not backed by the shipped code** — several of them contradict it. Facts tagged `[LEGACY]` concern the older Qwen VL models. ** Version pin.** Read against the default branch, late August 2026. The repo README was rebranded from MAI-UI to Qwen-UI-Agent on 2026-07-30, and `src/` changed materially around then — in particular, `start_coordinate` / `end_coordinate` normalization (§2.4) is **absent** from pre-rebrand snapshots. If your checkout predates that, drag coordinates come out in raw 0–999 space and everything in §2.4 is wrong for you. `git pull` and diff `src/` before finalizing a profile. The repo still has zero tagged releases, so there is no version string to pin against — pin a commit SHA. --- ## 0. The headline For MAI-UI / Qwen-UI-Agent the entire coordinate story is three lines `[SOURCE]`: ``` SCALE_FACTOR = 999 normalized_x = raw_x / 999 # model emits integers in 0..999 device_x = normalized_x * screenshot.width ``` **There is no `smart_resize` in this pipeline.** The screenshot is PNG-encoded to base64 and sent as-is. Coordinates are divided by a constant, then multiplied by the **original screenshot dimensions**. No patch factor, no resized-image space, no inverse resize transform. This makes MAI-UI dramatically simpler than Qwen2.5-VL, and it means most of what you know about Qwen2.5-VL coordinate handling is not just unnecessary here — applying it will actively break your clicks. --- ## 1. Your normalization utility is correct — this is what the reference does You were second-guessing the "convert everything to normalized coordinates" design. Don't. It is exactly what MAI-UI ships `[SOURCE]`: - `parse_action_to_structure_output()` divides every coordinate by 999 and stores `action["coordinate"] = [point_x, point_y]` in `[0, 1]`. - `parse_grounding_response()` does the same for the grounding agent. - `cookbook/grounding.ipynb` then multiplies the normalized pair by `test_image.width` / `test_image.height` to get pixels. So the canonical space is `[0, 1]` floats, and the model-space ↔ canonical conversion is a named, isolated step. That is the design. The "two-step" concern is unfounded — the second step (canonical → device) is where crop, rotation, and virtual-display handling live, and you need it regardless. One detail worth copying: MAI-UI stores normalized coordinates in memory and converts **back** to `int(x * 999)` when replaying history into the prompt `[SOURCE]`. The path is `_build_messages()` → `mem2response(step)` → `int(point_x * SCALE_FACTOR)`. The raw `prediction` string is stored on `TrajStep` but is **not** what gets replayed. (A `history_responses` property does the same re-encoding, but its call site in `_build_messages` is commented out — dead code.) Keeping the canonical form as the stored form, and re-encoding only at the prompt boundary, is what makes multi-turn history consistent. That round-trip uses `int()`, which truncates rather than rounds. A coordinate can drift by 1 unit (~0.1% of screen) per round-trip through history. Harmless for taps, but don't build anything that assumes round-trip stability. ### Known bug in HEAD: drag is normalized but not re-encoded `parse_action_to_structure_output` guards `coordinate`, `start_coordinate`, **and** `end_coordinate` — all three get divided by 999. But `mem2response` guards **only** `if "coordinate" in action_json`. Consequence: a `drag` action is stored normalized, and then replayed into the next turn's prompt as ```json {"action":"drag","start_coordinate":[0.43,0.21],"end_coordinate":[0.43,0.78]} ``` instead of `[430,210]` / `[430,778]`. The model sees history in a different coordinate space than it emits. The parse side was extended for drag; the re-encode side was not. **If you use `drag` in multi-turn tasks, mirror the start/end guards into your own `mem2response` equivalent.** Symptom if you don't: degraded behaviour on turns following a drag, with no parse error and no exception — the model just gets confused history. --- ## 2. The shipped action space `[SOURCE]` This is from `prompt.py`, not the paper. **It differs from the paper in ways that will break an executor written from the report.** `prompt.py` defines **four** prompts: three navigation variants (below) plus `MAI_MOBILE_SYS_PROMPT_GROUNDING`, covered separately in §4. ### 2.1 `MAI_MOBILE_SYS_PROMPT` (default) and `MAI_MOBILE_SYS_PROMPT_NO_THINKING` ``` {"action": "click", "coordinate": [x, y]} {"action": "long_press", "coordinate": [x, y]} {"action": "type", "text": ""} {"action": "swipe", "direction": "up|down|left|right", "coordinate": [x, y]} # coordinate OPTIONAL {"action": "open", "text": "app_name"} {"action": "drag", "start_coordinate": [x1, y1], "end_coordinate": [x2, y2]} {"action": "system_button", "button": "back|home|menu|enter"} {"action": "wait"} {"action": "terminate", "status": "success|fail"} {"action": "answer", "text": "xxx"} ``` ### 2.2 `MAI_MOBILE_SYS_PROMPT_ASK_USER_MCP` (Jinja template, used when `mcp_tools` is passed) All of the above, **plus**: ``` {"action": "ask_user", "text": "xxx"} {"action": "double_click", "coordinate": [x, y]} ``` …and an injected `## MCP Tools` section listing external tool JSON. MCP tools are called with the same `<tool_call>` envelope but a different `name`. ### 2.3 Corrections against the technical report | Claim | Reality | |---|---| | `[PAPER]` `swipe` was replaced by `drag` | **Both exist.** And `swipe` is **direction-based** (`"direction": "up"`) with an *optional* coordinate — it is not two-point. `drag` is the two-point action, and it uses `start_coordinate` / `end_coordinate`, **not** `coordinate` / `coordinate2`. | | `[PAPER]` `double_click` is in the action space | Only in the MCP prompt variant. Not in the default prompt. | | `[PAPER]` `ask_user` is in the action space | Only in the MCP prompt variant. | | `[PAPER]` `cli_command` / bash execution | **Not present in any shipped prompt.** No shell action schema in the repo. | | `[PAPER]` `api_call` | **Not present.** The nearest thing is the MCP tool escape hatch. | | `[PAPER]` batched actions — one turn returns an ordered action sequence | **Not supported.** See §3. | | Not in the paper's table | `answer` — returns a text answer to the user. You must handle it. | If you built an executor from the report's Table 1, it will emit `swipe` with `coordinate2`, and the model will never produce that. ### 2.4 Coordinate arity — 2 **or** 4 values `[SOURCE]` (navigation only) **This rule is navigation-only.** The grounding parser (`parse_grounding_response`) accepts length 2 and **raises on length 4** (`expected 2 values, got {n}`). Do not share an arity policy between the two agents. In `parse_action_to_structure_output`, every coordinate field is parsed as either a point or a bbox: ``` len == 2 -> [x, y] use directly len == 4 -> [x1, y1, x2, y2] take the center: ((x1+x2)/2, (y1+y2)/2) anything else -> raise ``` This applies to `coordinate`, `start_coordinate`, and `end_coordinate` independently. If your parser only handles length-2 you will crash on a valid model output. --- ## 3. One action per turn — no batching `[SOURCE]` The parser is: ``` pattern = r"<thinking>(.*?)</thinking>.*?<tool_call>(.*?)</tool_call>" match = re.search(pattern, text, re.DOTALL) ``` `re.search` returns the **first** match only. If the model emits multiple `<tool_call>` blocks, everything after the first is silently discarded. There is no loop, no `findall`, no batch executor. The paper's "batched actions in a single model turn" is not in this codebase. **Implication for your framework:** do not build batch-execution plumbing for this model. If you want it, you are writing it yourself and changing the parser, and you should expect the model's training distribution to be one-action-per-turn. ### Thinking-tag normalization `[SOURCE]` The parser also handles reasoning-model output that closes with `</think>` instead of `</thinking>`: ``` if "</think>" in text and "</thinking>" not in text: text = text.replace("</think>", "</thinking>") text = "<thinking>" + text ``` Note it prepends an opening tag — the model in that mode does not emit one. Copy this or thinking-mode outputs will fail to parse. --- ## 4. The grounding agent uses a different format `[SOURCE]` Two agents, two envelopes. Don't share a parser. | | Navigation (`MAIUINaivigationAgent`) | Grounding (`MAIGroundingAgent`) | |---|---|---| | Reasoning tag | `<thinking>` | `<grounding_think>` | | Payload tag | `<tool_call>` | `<answer>` | | Payload | `{"name": "mobile_use", "arguments": {...}}` | `{"coordinate": [x, y]}` | | Scale | 999 | 999 | | History | multi-turn, `history_n` default 3 | stateless, single image | If you only need "where is element X" — your earlier question — the grounding agent is the cheaper path: one image, no history, no tool schema, a much shorter system prompt. --- ## 5. `max_pixels` / `min_pixels` are accepted and ignored `[SOURCE]` Both agents' docstrings list `max_pixels` and `min_pixels` as valid `runtime_conf` keys. **Neither is ever read.** The constructor extracts only `temperature`, `top_k`, `top_p`, `max_tokens`, and (navigation only) `history_n`. `pil_to_base64()` saves the image at full resolution with no resize step anywhere in the call path. Consequences: 1. Setting `max_pixels` in `runtime_conf` does nothing. If you are tuning it for latency, you are tuning nothing. 2. **The serving layer decides the resolution.** Whatever vLLM / your OpenAI- compatible endpoint is configured with is what actually applies. Token budget is a *deployment* concern here, not an *agent config* concern. 3. If you want to reduce tokens, you must downscale the PIL image yourself before calling `predict()`. Because coordinates are normalized rather than in pixel space, **downscaling is safe** — normalized output is resolution-independent, so the inverse mapping is unaffected. This is the one place where the normalized convention genuinely buys you something over Qwen2.5-VL. --- ## 6. Screen size handling Because the model outputs normalized coordinates, the transform chain is much shorter than for Qwen2.5-VL: ``` screenshot (any size) → base64 PNG → model → [0..999]² ↓ /999 [0..1]² ↓ × (W, H) screenshot pixels ↓ crop/rotate/scale inverse device pixels → adb input tap ``` The reference cookbook multiplies by the dimensions of the **image it sent**. So the rule is: *multiply by the dimensions of the exact image you passed to `predict()`.* Everything after that is your own capture geometry. Things that still bite you, none of them model-specific: - **Capture ≠ device resolution.** scrcpy, virtual displays, and scaled capture pipelines produce screenshots whose size differs from the panel. Track capture dimensions per session. - **Cropping.** If you strip the status bar to save tokens, add the offset back before tapping. Symptom: x correct, y consistently off. - **Rotation.** Landscape changes which dimension is which. Capture orientation with the screenshot. - **Downscaling is free here** (see §5) but changes nothing about the returned numbers — do not "correct" for it. Since there is no `smart_resize`, the classic Qwen2.5-VL failure mode — encoding with one resize config and inverting with another — **cannot happen** on this path. Don't port that defensive code over; it will only add opportunities to introduce an error. --- ## 7. Legacy path: Qwen2.5-VL `[LEGACY]` Only relevant if your framework must also drive older models. Fundamentally different, and the difference is not cosmetic. - Emits **absolute pixels in the smart-resized image space**, not normalized. - Patch factor 28. `smart_resize` rounds H and W to multiples of 28 and clamps total pixels into `[min_pixels, max_pixels]`. - Ceiling is `16384 * 28²` = 12,845,056 px, which is what ships in `preprocessor_config.json`; the *recommended* range is 256–1280 visual tokens, i.e. 200,704 to 1,003,520 px. Running at the ceiling measurably degrades grounding on UI screenshots. - Inverse mapping: `x_screenshot = x_model / resized_w * orig_w` - Reported bug (**issue-tracker sourced, not code-verified** — QwenLM/Qwen3-VL issue #1052, version-dependent): passing `max_pixels` to `AutoProcessor.from_pretrained` may not update the processor's internal `size`. Mitigation regardless of whether your version is affected: read back actual grid dimensions rather than trusting config. - `mobile_use` schema here uses `swipe` with `coordinate` + `coordinate2` — the *opposite* of MAI-UI's direction-based swipe. Qwen3-VL sits between the two: patch factor 32, normalized output, but its published range is inconsistently documented (0–1, 0–999, and 0–1000 all appear in official sources) and its cookbooks apply `smart_resize` for `computer_use` but not for `mobile_use`. If you must support it, probe it. --- ## 8. Framework shape, revised Given the above, the profile is small and the important fields are not the ones I would have guessed from the paper. ```yaml # profiles/mai-ui.yaml # VERIFIED against MAI-UI source id: MAI-UI-8B family: mai-ui coordinates: space: normalized_scaled scale: 999 # divide by this; do NOT use 1000 accepts_bbox: true # len-4 coordinate => take center denominator: submitted_image # multiply by the image you sent, not device vision: resize_owner: none # no smart_resize in the client client_side_downscale: allowed # safe: output is resolution-independent runtime_conf_pixel_keys: ignored # max_pixels/min_pixels are dead config protocol: reasoning_tag: thinking also_accept: think # normalize </think> -> </thinking>, prepend open tag payload_tag: tool_call tool_name: mobile_use actions_per_turn: 1 # first <tool_call> only; rest discarded action_schema: click: { coordinate } long_press: { coordinate } type: { text } swipe: { direction, coordinate? } # direction-based! open: { text } drag: { start_coordinate, end_coordinate } system_button: { button } wait: {} terminate: { status } answer: { text } # MCP prompt variant only: ask_user: { text } double_click: { coordinate } ``` ```yaml # profiles/mai-ui-grounding.yaml id: MAI-UI-8B-grounding coordinates: { space: normalized_scaled, scale: 999 } protocol: reasoning_tag: grounding_think payload_tag: answer payload_shape: { coordinate: [x, y] } stateless: true ``` The three fields that actually matter and that differ across your two target generations are `coordinates.space`, `coordinates.scale`, and `vision.resize_owner`. `resize_owner: none` vs `resize_owner: caller` is the single switch that decides whether the inverse-resize machinery runs at all. Everything downstream of canonical `[0,1]` — crop offset, rotation, device scaling, ADB dispatch — is written once and shared. That's the payoff, and it's the same payoff MAI-UI gets from normalizing at the parser boundary. --- ## 9. Pre-flight checklist - [ ] Divide by **999**, not 1000. A 1000 divisor is a ~0.1% error — small enough to pass casual testing, large enough to miss small targets at screen edges. - [ ] Handle length-4 coordinates by taking the center — **navigation only**. Grounding raises on length 4; don't "fix" that by accepting bboxes there. - [ ] Mirror the `start_coordinate` / `end_coordinate` guards into your history re-encoder, not just your parser (§1). HEAD gets this wrong. - [ ] Confirm your checkout is post-2026-07-30, or drag isn't normalized at all. - [ ] Handle `answer` and `terminate` as terminal actions, not gestures. - [ ] `swipe` carries `direction`; only `drag` carries two points. - [ ] Only parse the first `<tool_call>`. - [ ] Normalize `</think>` → `</thinking>` and prepend the opening tag. - [ ] Don't set `max_pixels` in `runtime_conf` and expect it to do anything. Configure the serving layer instead. - [ ] Multiply by the dimensions of the image you actually sent. - [ ] Only enable `ask_user` / `double_click` when using the MCP prompt variant — the model isn't told about them otherwise. --- ## 10. Sources - `Tongyi-MAI/MAI-UI` — `src/mai_naivigation_agent.py` (SCALE_FACTOR, parser, history round-trip), `src/mai_grounding_agent.py`, `src/prompt.py` (the three system prompts and the real action space), `src/utils.py`, `cookbook/grounding.ipynb` (normalized × image dims). - Note: `Tongyi-MAI/Qwen-UI-Agent` is the **report website repo only** — PDF, README, assets. No implementation. The code lives under `MAI-UI/`. - Qwen-UI-Agent technical report, arXiv 2607.28227 — useful for training methodology and benchmarks; **do not implement from its Table 1.** - Qwen2.5-VL model cards and cookbooks — legacy `smart_resize` path. - `bytedance/UI-TARS` `README_coordinates.md` — reference `smart_resize` and inverse mapping, for the legacy path only.
web-tui
--- version: alpha name: WebTUI Void description: >- A terminal user interface rendered in the browser with WebTUI. The canvas is pitch black (#000000) and never lifts off it; depth comes from three narrow charcoal steps and from box-drawing borders, never from shadow, blur, or gradient. Type is monospace only and laid out on a character-cell grid (ch/lh), so every element snaps to the same columns and rows. Six saturated accents — cyan, mint, amber, rose, azure, magenta — sit at 7:1 or better against the void and carry all meaning; color is a data channel, not decoration. Interaction is keyboard-first: focus is a cyan border, selection is reverse video, and a contextual key-hint bar is always visible. colors: background0: "#000000" background1: "#0B0B0B" background2: "#161616" background3: "#242424" foreground0: "#FFFFFF" foreground1: "#C6C6C6" foreground2: "#8A8A8A" border-idle: "#5A5A5A" border-dim: "#3D3D3D" accent: "#00E5FF" accent-alt: "#FF6FD8" success: "#00FF9C" warning: "#FFD400" error: "#FF5F6E" info: "#57A6FF" on-accent: "#000000" selection-bg: "{colors.accent}" selection-fg: "{colors.on-accent}" scrim: "rgba(0, 0, 0, 0.72)" typography: display: fontFamily: "JetBrains Mono, IBM Plex Mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" fontSize: 32px fontWeight: 700 lineHeight: 1.1 letterSpacing: 0 h1: fontFamily: "{typography.display.fontFamily}" fontSize: 24px fontWeight: 700 lineHeight: 1.2 letterSpacing: 0 h2: fontFamily: "{typography.display.fontFamily}" fontSize: 20px fontWeight: 700 lineHeight: 1.3 letterSpacing: 0 h3: fontFamily: "{typography.display.fontFamily}" fontSize: 16px fontWeight: 700 lineHeight: 1.3 letterSpacing: 0.04em body: fontFamily: "{typography.display.fontFamily}" fontSize: 16px fontWeight: 400 lineHeight: 1.3 letterSpacing: 0 body-sm: fontFamily: "{typography.display.fontFamily}" fontSize: 14px fontWeight: 400 lineHeight: 1.3 letterSpacing: 0 data: fontFamily: "{typography.display.fontFamily}" fontSize: 16px fontWeight: 400 lineHeight: 1.3 letterSpacing: 0 fontFeature: "'tnum' 1, 'zero' 1" label: fontFamily: "{typography.display.fontFamily}" fontSize: 14px fontWeight: 700 lineHeight: 1.3 letterSpacing: 0.08em caption: fontFamily: "{typography.display.fontFamily}" fontSize: 12px fontWeight: 400 lineHeight: 1.3 letterSpacing: 0 keyhint: fontFamily: "{typography.display.fontFamily}" fontSize: 14px fontWeight: 700 lineHeight: 1.3 letterSpacing: 0 badge: fontFamily: "{typography.display.fontFamily}" fontSize: 12px fontWeight: 700 lineHeight: 1.3 letterSpacing: 0.06em code: fontFamily: "{typography.display.fontFamily}" fontSize: 14px fontWeight: 400 lineHeight: 1.3 letterSpacing: 0 glyph: fontFamily: "{typography.display.fontFamily}" fontSize: 16px fontWeight: 400 lineHeight: 1 letterSpacing: 0 rounded: none: 0px sm: 2px md: 4px full: 9999px spacing: cell-x: "1ch" cell-y: "1lh" pad-x: "1ch" pad-y: "0lh" panel-x: "2ch" panel-y: "1lh" gutter: "2ch" stack: "1lh" section: "2lh" min-cols: 80 min-rows: 24 components: app-shell: backgroundColor: "{colors.background0}" textColor: "{colors.foreground1}" typography: "{typography.body}" panel: backgroundColor: "{colors.background0}" textColor: "{colors.foreground1}" borderColor: "{colors.border-idle}" rounded: "{rounded.none}" padding: "1lh 2ch" panel-focused: backgroundColor: "{colors.background0}" textColor: "{colors.foreground0}" borderColor: "{colors.accent}" panel-title: backgroundColor: "{colors.background0}" textColor: "{colors.foreground2}" typography: "{typography.label}" padding: "0lh 1ch" panel-title-focused: backgroundColor: "{colors.background0}" textColor: "{colors.accent}" typography: "{typography.label}" statusbar: backgroundColor: "{colors.background1}" textColor: "{colors.foreground2}" typography: "{typography.keyhint}" padding: "0lh 1ch" height: "1lh" keyhint-key: backgroundColor: "{colors.background0}" textColor: "{colors.accent}" typography: "{typography.keyhint}" mode-indicator: backgroundColor: "{colors.accent}" textColor: "{colors.on-accent}" typography: "{typography.label}" padding: "0lh 1ch" button-primary: backgroundColor: "{colors.accent}" textColor: "{colors.on-accent}" typography: "{typography.label}" rounded: "{rounded.none}" padding: "0lh 2ch" height: "1lh" button-primary-active: backgroundColor: "{colors.foreground0}" textColor: "{colors.background0}" button-secondary: backgroundColor: "{colors.background0}" textColor: "{colors.foreground0}" borderColor: "{colors.border-idle}" typography: "{typography.label}" padding: "0lh 2ch" button-danger: backgroundColor: "{colors.error}" textColor: "{colors.on-accent}" typography: "{typography.label}" padding: "0lh 2ch" button-disabled: backgroundColor: "{colors.background2}" textColor: "{colors.foreground2}" input: backgroundColor: "{colors.background1}" textColor: "{colors.foreground0}" borderColor: "{colors.border-idle}" typography: "{typography.body}" rounded: "{rounded.none}" padding: "0lh 1ch" height: "1lh" input-focused: backgroundColor: "{colors.background1}" textColor: "{colors.foreground0}" borderColor: "{colors.accent}" search-prompt: backgroundColor: "{colors.background0}" textColor: "{colors.accent}" typography: "{typography.body}" table-header: backgroundColor: "{colors.background0}" textColor: "{colors.foreground2}" typography: "{typography.label}" padding: "0lh 1ch" table-row: backgroundColor: "{colors.background0}" textColor: "{colors.foreground1}" typography: "{typography.data}" padding: "0lh 1ch" table-row-alt: backgroundColor: "{colors.background1}" textColor: "{colors.foreground1}" table-row-selected: backgroundColor: "{colors.selection-bg}" textColor: "{colors.selection-fg}" typography: "{typography.data}" table-row-cursor-blur: backgroundColor: "{colors.background3}" textColor: "{colors.foreground0}" tree-row: backgroundColor: "{colors.background0}" textColor: "{colors.foreground1}" typography: "{typography.body}" tree-guide: backgroundColor: transparent textColor: "{colors.border-dim}" typography: "{typography.glyph}" tab: backgroundColor: "{colors.background0}" textColor: "{colors.foreground2}" typography: "{typography.label}" padding: "0lh 2ch" tab-active: backgroundColor: "{colors.background0}" textColor: "{colors.accent}" borderColor: "{colors.accent}" typography: "{typography.label}" dialog: backgroundColor: "{colors.background2}" textColor: "{colors.foreground0}" borderColor: "{colors.foreground0}" rounded: "{rounded.none}" padding: "1lh 2ch" dialog-danger: backgroundColor: "{colors.background2}" textColor: "{colors.foreground0}" borderColor: "{colors.error}" scrim: backgroundColor: "{colors.scrim}" command-palette: backgroundColor: "{colors.background2}" textColor: "{colors.foreground0}" borderColor: "{colors.accent}" typography: "{typography.body}" padding: "1lh 2ch" badge-status: backgroundColor: "{colors.background3}" textColor: "{colors.foreground0}" typography: "{typography.badge}" padding: "0lh 1ch" badge-success: backgroundColor: "{colors.success}" textColor: "{colors.on-accent}" typography: "{typography.badge}" badge-warning: backgroundColor: "{colors.warning}" textColor: "{colors.on-accent}" typography: "{typography.badge}" badge-error: backgroundColor: "{colors.error}" textColor: "{colors.on-accent}" typography: "{typography.badge}" progress-track: backgroundColor: transparent textColor: "{colors.border-dim}" typography: "{typography.glyph}" progress-fill: backgroundColor: transparent textColor: "{colors.accent}" typography: "{typography.glyph}" gauge-nominal: backgroundColor: transparent textColor: "{colors.success}" typography: "{typography.glyph}" gauge-elevated: backgroundColor: transparent textColor: "{colors.warning}" typography: "{typography.glyph}" gauge-critical: backgroundColor: transparent textColor: "{colors.error}" typography: "{typography.glyph}" sparkline: backgroundColor: transparent textColor: "{colors.accent}" typography: "{typography.glyph}" toast: backgroundColor: "{colors.background2}" textColor: "{colors.foreground0}" borderColor: "{colors.border-idle}" typography: "{typography.body-sm}" padding: "0lh 2ch" separator: backgroundColor: transparent textColor: "{colors.border-dim}" diff-add: backgroundColor: transparent textColor: "{colors.success}" typography: "{typography.code}" diff-remove: backgroundColor: transparent textColor: "{colors.error}" typography: "{typography.code}" log-error: backgroundColor: transparent textColor: "{colors.error}" typography: "{typography.code}" log-warn: backgroundColor: transparent textColor: "{colors.warning}" typography: "{typography.code}" log-info: backgroundColor: transparent textColor: "{colors.foreground1}" typography: "{typography.code}" log-debug: backgroundColor: transparent textColor: "{colors.info}" typography: "{typography.code}" log-trace: backgroundColor: transparent textColor: "{colors.foreground2}" typography: "{typography.code}" --- # WebTUI Void — DESIGN.md ## Overview This is a terminal user interface that happens to run in a browser, built on [WebTUI](https://webtui.ironclad.sh). Everything that makes a great TUI great — spatial consistency, keyboard fluency, information density that respects attention — is preserved; everything the browser adds that a terminal never had (shadows, gradients, blur, rounded cards, easing curves, mixed typefaces) is deliberately refused. The defining decision is the canvas: **`{colors.background0}` is `#000000`, pitch black**. Not near-black, not a tinted charcoal. Every other surface is a narrow step off that floor (`#0B0B0B` → `#161616` → `#242424`), and the accents are pushed to full saturation so they read as *voltage against void*. Cyan on pure black clears 13:1; the weakest accent in the system still clears 7:1. That headroom is the point: on a black canvas, a single saturated character carries more signal than an entire card would in a conventional web UI. Layout thinks in **character cells, not pixels**. Horizontal measurements use `ch`, vertical measurements use `lh`, and both derive from `--font-size` and `--line-height` on the `base` layer. A panel is `2ch` of horizontal padding and `1lh` of vertical padding because that is one cell of breathing room, not because 16px looked right. Borders are drawn with WebTUI's `box-` utility, which means a border occupies real cells and the grid stays honest. Type is **monospace only** — one family, no exceptions. Hierarchy is built from size, weight, color, inverse video, and position, never from a second typeface. Numbers use `{typography.data}` with tabular figures so columns align down the page the way they do in a real terminal. **Key characteristics:** - Single canvas: `{colors.background0}` (#000000) everywhere. Panels do not have their own fill; they are defined by their border, not by a lighter rectangle. - Four background levels, three foreground levels — the WebTUI base contract (`--background0`–`--background3`, `--foreground0`–`--foreground2`), retuned for a pitch-black floor. - Six accents mapped to ANSI semantics: `{colors.accent}` cyan (interaction), `{colors.success}` mint, `{colors.warning}` amber, `{colors.error}` rose, `{colors.info}` azure, `{colors.accent-alt}` magenta (secondary interaction). - Focus is a **border color change** to `{colors.accent}`; selection is **reverse video** (`{colors.selection-bg}` fill, `{colors.selection-fg}` text). These two states never use the same treatment. - Depth is tonal and typographic: `background0` → `background3` plus square vs. double box borders. **Zero box-shadows. Zero gradients. Zero blur.** - Radius defaults to `{rounded.none}`. `box-="round"` exists but is reserved for buttons inside dialogs, matching lazygit-style popup affordances. - A contextual key-hint bar (`{component.statusbar}`) is always present and always reflects the focused region — the interface teaches itself. --- ## Colors The palette is a pitch-black void with six high-voltage accents. Nothing in the middle: there are no mid-grays used as surfaces, because a mid-gray surface on a black canvas reads as a *web card*, and this is not a web card system. ### Canvas & Surfaces Four levels, mapping directly to WebTUI's `--background0`–`--background3`: - **Void** (`{colors.background0}` — #000000): The floor. The application shell, every panel interior, every table row by default. OLED-true black. - **Surface** (`{colors.background1}` — #0B0B0B): Status bar, input wells, zebra stripes. Barely perceptible on its own; readable as a zone when adjacent to the void. - **Elevated** (`{colors.background2}` — #161616): Dialogs, command palette, toasts, popovers. The only level that reads as "floating." - **Raised** (`{colors.background3}` — #242424): Inactive cursor rows, hover fills, badge backgrounds. The top of the stack; nothing goes lighter. Each step is roughly 4–7% lightness. The gradient is deliberately shallow — depth is a whisper here because the borders and accents do the loud work. ### Text - **Bright** (`{colors.foreground0}` — #FFFFFF, 21:1 on void): Headings, focused panel content, selected values, dialog body. Pure white is affordable on pure black and is used without hesitation. - **Body** (`{colors.foreground1}` — #C6C6C6, 12.3:1): Default running text and table cells. Slightly off-white so that `{colors.foreground0}` retains its emphasis role. - **Muted** (`{colors.foreground2}` — #8A8A8A, 6.1:1): Timestamps, column headers, unfocused panel titles, inactive tabs, key-hint labels. Still clears WCAG AA for body text — muted here means *quieter*, never *unreadable*. ### Borders - **Idle** (`{colors.border-idle}` — #5A5A5A, 3.04:1): The default `box-` border on unfocused panels. Meets the 3:1 non-text UI threshold exactly. - **Dim** (`{colors.border-dim}` — #3D3D3D): Purely decorative rules — tree guides, table dividers, progress track. Never the only indicator of anything. - **Focus**: `{colors.accent}`. A focused panel swaps `--box-border-color` to cyan. No glow, no ring, no shadow — the border itself changes color. ### Accents Every accent clears **7:1 against `{colors.background0}`**, which is AAA for normal text. Values are the measured contrast on pitch black: | Token | Hex | Contrast | Role | |---|---|---|---| | `{colors.accent}` | #00E5FF | 13.65:1 | Focus, links, primary CTA fill, active tab, sparklines, cursor | | `{colors.success}` | #00FF9C | 15.78:1 | Success, additions, running/healthy, nominal gauge | | `{colors.warning}` | #FFD400 | 14.67:1 | Warnings, pending, modified, elevated gauge | | `{colors.accent-alt}` | #FF6FD8 | 8.52:1 | Secondary interaction, filters, tags, alternate series | | `{colors.info}` | #57A6FF | 8.30:1 | Informational, debug logs, hints | | `{colors.error}` | #FF5F6E | 7.11:1 | Errors, deletions, stopped, critical gauge, destructive actions | **Black on accent.** Every accent fill takes `{colors.on-accent}` (#000000) text, never white. The inverted pair is the system's signature: a cyan block with black glyphs is how selection, primary buttons, and mode indicators all announce themselves. ### Semantic Rules - `{colors.accent}` is reserved for **interaction and focus**. It is never used to color static content, decorative headings, or a chart series that has no interactive meaning. - Status colors are **status**, not styling. `{colors.success}` means a thing succeeded or is healthy; it is never "the green option." - Color never carries meaning alone. Every colored state is paired with a glyph (`●` `○` `✓` `✗` `▲` `▼` `⚠`), a text label, or a position. Strip the palette to monochrome and the interface must still be operable. - `--box-border-color`, `--table-border-color`, and `--separator-color` all default to `{colors.border-dim}` on this theme, overridden to `{colors.border-idle}` for panel chrome and `{colors.accent}` on focus. --- ## Typography ### Font Family One family, everywhere: **JetBrains Mono**, falling back through `IBM Plex Mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace`. Set it once on the `base` layer via `--font-family`. A monospace face is not a stylistic choice here — it is structural. The `ch` unit is the width of the `0` glyph, so a monospace font is what makes `ch` mean "column." A proportional font would silently break every alignment in the system. The family must render box-drawing (U+2500–U+257F), block elements (U+2580–U+259F), and braille (U+2800–U+28FF) at full cell width. Nerd Font icons are optional and always require a Unicode fallback; do not assume them. ### Base Rhythm ```css @layer base { :root { --font-size: 16px; --line-height: 1.3; --font-weight-normal: 400; --font-weight-bold: 700; --font-family: "JetBrains Mono", ui-monospace, monospace; } } ``` Two weights only — 400 and 700. There is no 500, no 600. In a terminal, weight is a binary (SGR 1 or not), and honoring that keeps the illusion intact. ### Hierarchy | Token | Size | Weight | Line Height | Use | |---|---|---|---|---| | `{typography.display}` | 32px | 700 | 1.1 | ASCII banners, splash headers, empty-state art | | `{typography.h1}` | 24px | 700 | 1.2 | View titles | | `{typography.h2}` | 20px | 700 | 1.3 | Section headings inside a panel | | `{typography.h3}` | 16px | 700 | 1.3 | Sub-headings; letterspaced 0.04em | | `{typography.body}` | 16px | 400 | 1.3 | Default running text | | `{typography.body-sm}` | 14px | 400 | 1.3 | Dense lists, secondary detail, toasts | | `{typography.data}` | 16px | 400 | 1.3 | Numbers and table cells — tabular figures + slashed zero | | `{typography.label}` | 14px | 700 | 1.3 | Panel titles, column headers, buttons; uppercase, 0.08em | | `{typography.caption}` | 12px | 400 | 1.3 | Timestamps, footnotes, counts | | `{typography.keyhint}` | 14px | 700 | 1.3 | Status bar shortcuts — `[q]uit`, `[/]search` | | `{typography.badge}` | 12px | 700 | 1.3 | `is-="badge"` content; uppercase, 0.06em | | `{typography.code}` | 14px | 400 | 1.3 | `<pre>`, diffs, log lines | | `{typography.glyph}` | 16px | 400 | 1 | Box-drawing, block, and braille runs — line-height 1 so cells tile seamlessly | ### Principles - **`{typography.glyph}` must use `lineHeight: 1`.** Sparklines, gauges, and braille charts are built from characters that fill their cell; any leading at all opens visible seams between stacked rows. - **Numbers always use `{typography.data}`.** Tabular figures are non-negotiable in tables, gauges, and counters — a jittering column breaks the terminal illusion faster than any color mistake. - **Uppercase is a hierarchy device.** `{typography.label}` and `{typography.badge}` are uppercase with positive letterspacing, which is how panel titles and column headers read as chrome rather than content. - Headings do not change family or color by default; they change size and weight. Color on a heading means something is *focused* or *erroring*. --- ## Layout ### The Character Grid All spacing is expressed in cells: `ch` horizontally, `lh` vertically. These are stored as strings in the token block because they are not px/em/rem dimensions. At the base rhythm (16px, 1.3 line-height, a 0.6em monospace advance), `1ch ≈ 9.6px` and `1lh ≈ 20.8px` — but never hardcode those derived values. Changing `--font-size` must rescale the entire interface. | Token | Value | Use | |---|---|---| | `{spacing.cell-x}` | `1ch` | The horizontal atom | | `{spacing.cell-y}` | `1lh` | The vertical atom | | `{spacing.pad-x}` / `{spacing.pad-y}` | `1ch` / `0lh` | Inline element padding (badges, cells, key hints) | | `{spacing.panel-x}` / `{spacing.panel-y}` | `2ch` / `1lh` | Panel interior padding | | `{spacing.gutter}` | `2ch` | Space between sibling panels and grid columns | | `{spacing.stack}` | `1lh` | Vertical gap between stacked blocks | | `{spacing.section}` | `2lh` | Gap between major regions | Rule: **every vertical measurement is an integer multiple of `1lh`.** A `12px` margin anywhere throws every subsequent row off the grid and the box-drawing characters stop lining up. This is the single easiest way to break the design. ### Layout Paradigms Pick one primary paradigm per application and hold it. Panels keep fixed positions across sessions; users navigate by spatial memory, not by search. | App type | Paradigm | Structure | |---|---|---| | Git / DevOps tool | Persistent multi-panel | Stacked selector column left, detail pane right | | File / hierarchy browser | Miller columns | Three columns: parent / current / preview | | Deep data browser | Drill-down stack | Enter descends, Esc ascends, `:` jumps directly | | Monitor / dashboard | Widget grid | Self-contained bordered widgets, each with a title | | Editor-like tool | IDE three-panel | Sidebar / main / output, tab bar on top | | Shell augmentation | Overlay | Summoned, used, dismissed; never disturbs the page | | Single-list tool | Header + scrollable list | Fixed meter header, scrolling body, key-hint footer | ``` ┌─ status ──┬─────────────── detail ───────────────┐ ├─ files ───┤ │ │ > main.rs │ content for the selected item │ │ lib.rs │ │ ├─ branches ┤ │ │ * main │ │ └───────────┴──────────────────────────────────────┘ NORMAL [q]uit [/]search [Tab]focus [?]help ``` ### Grid & Container - **Minimum viewport**: `{spacing.min-cols}` × `{spacing.min-rows}` (80×24 cells). Below that, render a single centered "viewport too small" message rather than a broken layout. - **Maximum width**: none. A TUI fills its container. If a max is required for reading comfort, cap at `120ch` and center. - **Panel sizing**: use `fr` ratios or percentages, never fixed px. Selector columns typically take `28ch`–`36ch`; detail panes take the remainder. - **Whitespace philosophy**: dense. One cell of padding is generous in this system. Separation comes from borders and contrast, not from air. If a layout feels empty, it is under-informative, not well-spaced. --- ## Elevation & Depth There are no shadows in this system. Depth is conveyed by three mechanisms, applied in this order of preference: | Level | Treatment | Use | |---|---|---| | Flat | `{colors.background0}`, no border | App shell, panel interiors, table rows | | Bordered | `box-="square"`, `{colors.border-idle}` | Panels, widget boxes, inputs, cards | | Focused | Same box, border → `{colors.accent}` | The one region receiving keyboard input | | Tonal lift | `{colors.background1}` / `{colors.background2}` | Status bar, inputs / dialogs, palettes, toasts | | Emphatic | `box-="double"`, border `{colors.foreground0}` | Modal dialogs and destructive confirmations only | | Scrim | `{colors.scrim}` over the page | Behind any modal, to create the focus trap | The layering order is `background0` → `background1` → `background2` → `background3`. A dialog sits on `{colors.background2}` with a double border; the page beneath it dims under `{colors.scrim}` rather than blurring. Blur is a glass-morphism idiom and has no terminal analogue — it is prohibited. Panels do **not** get a lighter fill to indicate elevation. In a terminal, a panel is its border. Reserve tonal lift for things that genuinely float above the layout (dialogs, popovers, toasts, the command palette). --- ## Shapes Square by default. `box-="square"` is the system's shape. | Token | Value | Use | |---|---|---| | `{rounded.none}` | 0px | Everything: panels, inputs, tables, badges, buttons, dialogs | | `{rounded.sm}` | 2px | Optional softening on `is-="badge"` caps | | `{rounded.md}` | 4px | `--box-rounded-radius` for `box-="round"` — dialog action buttons only | | `{rounded.full}` | 9999px | Status dots and avatar glyphs only | WebTUI's box utility offers `square`, `round`, and `double` (and combinations such as `box-="double round"`). This system uses: - **`square`** — all panels, widgets, inputs, and containers. The default. - **`double`** — modal dialogs and destructive confirmations. Doubling the border is the terminal-native way to say "this is on top and it matters." - **`round`** — the Cancel/OK button pair inside a dialog, echoing lazygit's popup affordances. Nowhere else. Box borders are drawn with `--box-border-width`; keep it at a single hairline so the border occupies exactly one cell. ### Glyph Vocabulary The visual language is Unicode, restricted to ranges that render consistently across platforms: - **Box-drawing**: `─ │ ┌ ┐ └ ┘ ├ ┤ ┬ ┴ ┼` (light), `━ ┃ ┏ ┓ ┗ ┛` (heavy), `═ ║ ╔ ╗ ╚ ╝` (double). - **Blocks**: `▁▂▃▄▅▆▇█` (vertical eighths, sparklines), `▏▎▍▌▋▊▉█` (horizontal eighths, bars), `░▒▓█` (shades, heatmaps). - **Braille**: U+2800–U+28FF for 2×4 sub-cell resolution line charts. - **Status**: `● ○ ◉ ◆ ◇ ✓ ✗ ▲ ▼ ⚠ ℹ`. - **Tree**: `├── `, `└── `, `│ `, four cells per level. Emoji are prohibited — they break cell width. Nerd Font glyphs require the `@webtui/plugin-nf` plugin and must always degrade to a Unicode fallback. --- ## Components Built on WebTUI's attribute-driven API: `box-`, `is-`, `variant-`, `size-`, `cap-`, `marker-`, `shear-`. Custom variants (`variant-="accent"`, `variant-="error"`) are registered by extending the relevant stylesheet on the `components` layer, which is WebTUI's documented extension mechanism. ### Shell & Chrome **`app-shell`** — `{colors.background0}` filling the viewport, `{typography.body}` in `{colors.foreground1}`. Sets `data-webtui-theme="void"` on `<html>` so every descendant inherits the palette. **`panel`** — The workhorse. `<div box-="square">` with `--box-border-color: {colors.border-idle}`, no fill, `1lh 2ch` padding. Panels never move between sessions. **`panel-focused`** — The same element with `--box-border-color: {colors.accent}` and body text lifted to `{colors.foreground0}`. Exactly one panel is focused at a time. Unfocused panels keep `{colors.border-idle}` and `{colors.foreground1}` — dimmed, never hidden. **`panel-title`** — A `<span is-="badge" variant-="background0">` overlaid on the top border using `shear-="top"`. `{typography.label}` in `{colors.foreground2}`, switching to `{colors.accent}` when the panel is focused (`panel-title-focused`). This is the WebTUI idiom for a titled terminal box and should be used for every panel. **`statusbar`** — Full-width bar pinned to the bottom, `{colors.background1}`, one cell tall. Left: `mode-indicator`. Center: contextual key hints. Right: position/count. It updates as focus changes — show only what is actionable now. **`mode-indicator`** — `{colors.accent}` fill with `{colors.on-accent}` text, `{typography.label}`, uppercase: `NORMAL`, `INSERT`, `SEARCH`, `VISUAL`. Colors shift with mode severity — use `{colors.error}` for any destructive mode. **`keyhint-key`** — The bracketed key inside a hint. The key glyph renders in `{colors.accent}`, the label in `{colors.foreground2}`: `[q]uit` `[/]search` `[?]help` `[Tab]focus`. Three to five hints maximum; the full set lives behind `?`. ### Buttons **`button-primary`** — `<button variant-="accent">`. `{colors.accent}` fill, `{colors.on-accent}` text, `{typography.label}`, `0lh 2ch` padding, square. One per view. Active state (`button-primary-active`) inverts to a white fill with black text — the terminal's flash-on-press. **`button-secondary`** — `<button box-="square">` with a transparent fill, `{colors.border-idle}` border, `{colors.foreground0}` text. WebTUI switches a button between `--button-primary` and `--button-secondary` automatically based on whether `box-` is present, so bordered buttons read as secondary for free. **`button-danger`** — `{colors.error}` fill with `{colors.on-accent}` text. Destructive actions only, and always inside a confirmation dialog. **`button-disabled`** — `{colors.background2}` fill, `{colors.foreground2}` text, plus the native `disabled` attribute. Never communicate disabled state with opacity alone. Sizes use WebTUI's `size-="small"` and `size-="large"`; the default is one cell tall and should cover most cases. ### Inputs **`input`** — `<input box-="square">` on `{colors.background1}` with `{colors.border-idle}`. Text is `{colors.foreground0}`; placeholder is `{colors.foreground2}`. Focus swaps the border to `{colors.accent}` (`input-focused`) — no outline, no shadow. **`search-prompt`** — The `/` search idiom. A single row that appears at the bottom of the focused panel, prefixed by a `{colors.accent}` `/` glyph, filtering results live as the user types. `n`/`N` cycle matches; matched substrings are marked with `<mark>` in `{colors.warning}`; `Esc` dismisses. **Checkbox / radio / switch** — use WebTUI's `is-="switch"` and native `<input type="checkbox">` / `<input type="radio">` styling. Checked state uses `{colors.accent}`; the glyph (`☑` / `◉`) must remain distinguishable in monochrome. ### Data Display **`table-header`** — `{typography.label}` in `{colors.foreground2}`, uppercase, with a `{colors.border-dim}` rule beneath. Sortable columns append `▲`/`▼`. **`table-row`** / **`table-row-alt`** — Zebra striping alternates `{colors.background0}` and `{colors.background1}`. Numbers right-aligned in `{typography.data}`, text left-aligned, overflow truncated with `…`. **`table-row-selected`** — **Reverse video**: `{colors.selection-bg}` fill with `{colors.selection-fg}` text across the full row width. This is the strongest signal in the system and is reserved for the cursor row in the focused panel. **`table-row-cursor-blur`** — When a panel loses focus, its cursor row degrades to `{colors.background3}` with `{colors.foreground0}` text, so the user can still see where they were without competing with the active panel. **`tree-row`** / **`tree-guide`** — Guides (`├── `, `└── `, `│ `) render in `{colors.border-dim}`; the node label follows the row's own state colors. Directories may take `{colors.info}`, executables `{colors.success}` — the `ls --color` convention. Use WebTUI's `marker-="tree"` on `<ul>` where the content is a genuine list. **`tab` / `tab-active`** — Tabs sit along the top edge. Inactive: `{colors.foreground2}`, no border. Active: `{colors.accent}` text with a `{colors.accent}` bottom border. Tabs are landmarks; their order never changes. **Diff** — `{component.diff-add}` renders `+` lines in `{colors.success}`, `{component.diff-remove}` renders `-` lines in `{colors.error}`, context stays `{colors.foreground1}`. Word-level changes within a line are marked with a `{colors.background3}` fill. Never rely on the color alone — keep the `+`/`-` gutter characters. **Logs** — Level colors: `log-trace` `{colors.foreground2}`, `log-debug` `{colors.info}`, `log-info` `{colors.foreground1}`, `log-warn` `{colors.warning}`, `log-error` `{colors.error}` (bold). Timestamp in `{colors.foreground2}`, message in `{typography.code}`. ### Visualization **`progress-track` / `progress-fill`** — Character-built, not a styled `<div>`: `[████████░░░░░░] 57%`. Fill is `{colors.accent}`, track is `{colors.border-dim}`, percentage in `{typography.data}`. WebTUI's `progress` component is acceptable where a semantic element is needed, themed to the same two colors. **Gauges** — Threshold-colored: `{component.gauge-nominal}` at 0–60%, `{component.gauge-elevated}` at 60–80%, `{component.gauge-critical}` above 80%. Always `label + bar + value`, e.g. `CPU [██████████░░░░] 67%`. **`sparkline`** — `▁▂▃▅▇█▇▅▃▂` in `{colors.accent}` at `{typography.glyph}`. Braille (`⣀⣤⣶⣿⣶⣤⣀`) for higher-resolution series. A second series on the same chart uses `{colors.accent-alt}`. **Spinner** — Braille dots `⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏` at 80ms in `{colors.accent}`. Only shown after 200ms of waiting, so fast operations never flash. ### Overlays **`scrim`** — `{colors.scrim}` covering the viewport whenever a modal is open. It creates the focus trap; background elements receive no keyboard events. **`dialog`** — `<dialog box-="double">` on `{colors.background2}` with a `{colors.foreground0}` double border, `1lh 2ch` padding. Title in `{typography.h3}`, body in `{typography.body}`, actions right-aligned as `box-="round"` buttons. Severity scales the pattern: reversible actions get a status-bar message, moderate ones get an inline `Press y to confirm`, and irreversible ones get `dialog-danger` — a `{colors.error}` double border plus a typed-confirmation input. **`command-palette`** — `Ctrl+K` / `:` overlay on `{colors.background2}` with a `{colors.accent}` border, anchored one third from the top. A search prompt row, then a fuzzy-filtered list where matched characters render in `{colors.warning}`, and the highlighted row uses the reverse-video selection treatment. **`toast`** — Bottom-right, `{colors.background2}` with `{colors.border-idle}`, one line of `{typography.body-sm}`, auto-dismissing in 3–5s. A leading glyph carries the semantics: `✓` in `{colors.success}`, `⚠` in `{colors.warning}`, `✗` in `{colors.error}`. Toasts never require interaction. **`badge-status`** — `<span is-="badge">` for inline state. Neutral badges use `{colors.background3}`; semantic badges (`badge-success`, `badge-warning`, `badge-error`) fill with their accent and take `{colors.on-accent}` text. Caps default to `square`; `cap-="round"` is permitted for a softer inline feel. **`separator`** — `─` runs in `{colors.border-dim}`, optionally labeled: `──── Section ──────`. Use `--separator-color` to theme WebTUI's separator component. --- ## Do's and Don'ts ### Do - Keep `{colors.background0}` at `#000000` on every surface that isn't explicitly floating. The void is the brand. - Give every panel a border and a title badge. A bordered, titled box is the atomic unit of this system. - Use `{colors.accent}` for focus and interaction only, and reverse video for selection. Two distinct states, two distinct treatments. - Put black text on every accent fill. `{colors.on-accent}` is #000000, always. - Measure horizontally in `ch` and vertically in `lh`, in whole cells. - Pair every color with a glyph or label, so the interface survives monochrome and color-blind viewing. - Keep the key-hint bar visible and context-aware; put the full keymap behind `?`. - Right-align numbers, use `{typography.data}`, and truncate with `…`. - Give every surface an escape hatch: `q` quits, `Esc` steps back, `?` helps. ### Don't - Don't lighten the canvas to a "softer" charcoal. `#0B0B0B` and above are surfaces, not backgrounds — the floor stays absolute black. - Don't add box-shadows, gradients, backdrop blur, or glow. Elevation is tonal and typographic. A cyan `text-shadow` "CRT glow" is the most common way this design gets ruined. - Don't round panels or tables. `{rounded.none}` is the default; `box-="round"` is limited to dialog action buttons. - Don't introduce a second font family, or a weight between 400 and 700. - Don't use accent colors for body text, large fills, or decoration. They mark state and interaction. - Don't animate selection or focus. Highlight changes are instantaneous — 0ms. Animation belongs to transitions and loading, never to cursor movement. - Don't use px for layout spacing. A single `12px` margin desynchronizes the entire vertical grid. - Don't emit emoji or unguarded Nerd Font glyphs; both break cell width. - Don't hide state behind hover. This is a keyboard-first system; anything only reachable by pointer is unreachable. - Don't let a panel change position between sessions. Spatial memory is the primary navigation mechanism. --- ## Interaction Model Keyboard-first, mouse-optional. Every feature must be reachable without a pointer. | Layer | Keys | Discoverability | |---|---|---| | L0 Universal | `↑↓←→` `Enter` `Esc` `q` | Always in the status bar | | L1 Motions | `hjkl` `/` `?` `:` `gg` `G` | Always in the status bar | | L2 Actions | Single mnemonics — `d`elete, `c`ommit, `r`efresh | `?` help overlay | | L3 Power | Composed commands, custom bindings | Documentation | - `Tab` / `Shift+Tab` cycle panel focus; `Enter` descends, `Esc` ascends. - `/` searches, `n`/`N` cycle matches, `:` opens command mode. - Reserved by the browser and the terminal: never bind `Ctrl+C`, `Ctrl+W`, `Ctrl+T`, `Ctrl+N`, or `Ctrl+Shift+I`. - Mouse support is additive: click to focus, wheel to scroll, click column headers to sort. Text selection must never be captured. - Focus is always visible and always singular. `:focus-visible` maps to the `{colors.accent}` border treatment; the default browser outline is replaced, never removed. --- ## Motion | Situation | Treatment | Duration | |---|---|---| | Selection / focus change | None | 0ms | | Panel resize / reflow | None | 0ms | | View transition | Opacity or single-axis slide | 100–200ms | | Overlay open / close | Opacity on scrim + dialog | 120ms | | Loading (indeterminate) | Braille spinner, 80ms frames | Until complete | | Loading (determinate) | Character progress bar | Until complete | | Success confirmation | Glyph flash, no movement | 1–2s | | Streaming text | Paced at a readable rate | — | Nothing eases with a bounce, nothing scales, nothing rotates except the spinner frames. Input always interrupts animation — if a key is pressed mid-transition, cancel and respond immediately. Honor `prefers-reduced-motion: reduce` by dropping every transition to 0ms; the design loses nothing. --- ## Responsive Behavior The terminal analogue of a resize is a viewport change, and it is handled the same way: constraint-based, never absolute. | Width | Behavior | |---|---| | `< 80ch` | Collapse to a single panel with a tab or drill-down navigation | | `80–120ch` | Two panels: selector + detail. Preview column hides first | | `120–180ch` | Full multi-panel layout | | `> 180ch` | Same layout, panels grow proportionally; do not add new regions | - Collapse by priority: preview panes hide before selector panes; selector panes collapse to title-only bars before disappearing. - Below `{spacing.min-cols}` × `{spacing.min-rows}`, show a centered message rather than degrading further. - Touch targets need `2lh` of height minimum where a pointer is expected — taller than the `1lh` terminal norm. - Tables reflow to stacked key/value rows on narrow viewports; they never shrink the font to fit. --- ## Accessibility & Degradation - **Contrast**: body text ≥ 4.5:1, UI elements and borders ≥ 3:1. Every token in this palette is measured against `{colors.background0}` and documented in the Colors section. - **Never color alone**: pair every semantic color with a glyph, a label, or a position. The safest accent pairs on black are cyan/amber and azure/amber — do not lean on the `{colors.success}` / `{colors.error}` distinction by itself. - **Monochrome test**: render the interface with all accents mapped to `{colors.foreground1}`. If it is still operable, the design is sound. - **Focus**: visible at all times, single, and keyboard-reachable. Skip links precede the panel grid. - **Semantics**: WebTUI styles native elements, so use them — `<button>`, `<dialog>`, `<table>`, `<input>`, `<progress>`. Panels are `<section>` with an `aria-label` matching the visible title badge. Live regions announce toasts and status-bar changes. - **Reduced motion and forced colors**: honor `prefers-reduced-motion` and `forced-colors`; in forced-colors mode, borders must fall back to `CanvasText`. --- ## Iteration Guide 1. Work one component at a time and reference its token key directly (`{component.panel}`, `{component.table-row-selected}`). 2. New surfaces choose a background level first (0 for content, 1 for chrome, 2 for floating, 3 for raised), then a border, then — only if genuinely interactive — an accent. 3. Component states live as sibling entries (`-focused`, `-active`, `-disabled`), never as nested objects. 4. Reference tokens in prose with `{token.refs}`; never write a raw hex value into component CSS. 5. Register new `variant-` values by extending the relevant WebTUI stylesheet on the `components` layer — do not override with `!important`. 6. Before shipping any component, check it at 80×24 cells, in monochrome, and with `prefers-reduced-motion` enabled. --- ## Known Gaps - Light mode is intentionally undefined. This system is a pitch-black theme; a light variant would need its own contrast audit and is out of scope here. - Nerd Font glyph mappings are not tokenized. If `@webtui/plugin-nf` is adopted, each icon needs a documented Unicode fallback. - Syntax-highlighting tokens (for `<pre>` / code panes) are not defined; they would need a full Base16-style mapping onto this palette. - Chart libraries beyond character-cell rendering (canvas, SVG) are not covered. Anything drawn outside the cell grid is outside this design system. - Print styles are undefined; a pitch-black canvas is not printable as-is.
qwen-grounding
--- title: Qwen Grounding & Coordinate Systems (Qwen2.5-VL → Qwen3.8) description: Coordinate conventions, output formats, preprocessing effects, and post-processing rules for visual grounding across Qwen vision model families. tags: [reference, vision, coordinates, grounding, qwen, agent-context] audience: agents --- # Qwen Grounding & Coordinate Systems Reference for agents doing object detection, visual grounding, or GUI element localization with Qwen vision models. Covers **Qwen2.5-VL through Qwen3.8**. There are **two incompatible coordinate conventions** across these families. Using the wrong one produces boxes that are plausibly shaped but wrongly placed — a silent failure that looks like poor model accuracy. Identify the regime before writing post-processing. --- ## 1. Quick reference | Model family | Coordinate regime | Reference frame | px per visual token | Resize factor | Confidence | |---|---|---|---|---|---| | `qwen2.5-vl-*-instruct` (open source) | Absolute pixels | **Scaled** image | 28 × 28 | 28 | Documented | | `qvq-*` | Absolute pixels | **Scaled** image | 28 × 28 | 28 | Documented | | `qwen-vl-max` / `qwen-vl-plus` (2025 snapshots) | Absolute pixels | **Scaled** image | 32 × 32 | 32 | Likely — verify | | `qwen3-vl-*` (plus, flash, open source) | Normalized 0–1000 | Whole image | 32 × 32 | 32 | Documented | | `qwen3.5-*` | Normalized 0–1000 | Whole image | 32 × 32 | 32 | Well-corroborated | | `qwen3.6-*` | Normalized 0–1000 | Whole image | 32 × 32 | 32 | **Inferred — verify** | | `qwen3.7-*` | Normalized 0–1000 | Whole image | 32 × 32 | 32 | **Inferred — verify** | | `qwen3.8-max` | Normalized 0–1000 | Whole image | 32 × 32 | 32 | **Inferred — verify** | **Confidence levels used in this document:** - **Documented** — stated explicitly in official Qwen / QwenCloud documentation. - **Well-corroborated** — stated in official tooling (e.g. ms-swift training guides) but not in the API docs. - **Inferred** — not stated anywhere; extrapolated from shared lineage and identical preprocessing parameters. Treat as a hypothesis and run §9 before relying on it. > **Do not present inferred rows as fact.** As of this writing, QwenCloud's own > bounding-box rendering scripts stop at Qwen3-VL. No official source states the > coordinate convention for Qwen3.6, 3.7, or 3.8. --- ## 2. Regime A — Absolute pixels on the scaled image (Qwen2.5-VL family) The model emits **un-normalized pixel values**. The critical and frequently misunderstood part: those pixels refer to the image **as the model received it**, after internal resizing — *not* to your original file. ### Why this trips people up Qwen's materials describe Qwen2.5-VL as retaining "the original coordinate scale without normalization." This means *un-normalized absolute pixels*, in contrast to Qwen2-VL's 0–1000 scheme. It does **not** mean "your original file's dimensions." Several third-party guides propagate this misreading. QwenCloud's own FAQ is unambiguous: Qwen2.5-VL returns absolute pixel values relative to the top-left corner of the **scaled** image. ### Recovering the reference frame **Local inference (transformers):** the processor reports the grid it built. ``` input_width = image_grid_thw[0][2] * patch_size # patch_size = 14 input_height = image_grid_thw[0][1] * patch_size ``` Then rescale to your original: ``` x_orig = x_model * (original_width / input_width) y_orig = y_model * (original_height / input_height) ``` **Hosted API:** `image_grid_thw` is not exposed. You must reproduce `smart_resize` locally (§5) using the same `max_pixels` the request used, or — simpler and recommended — pre-resize the image yourself so the model input equals what you sent. ### The no-rescale shortcut If you resize the image yourself to a valid shape (dimensions already multiples of the resize factor, total pixels under the cap) and disable further resizing (`do_resize=False` locally), the model input *is* your image and coordinates land directly. This eliminates the entire class of bug. Prefer it when you control preprocessing. ### Known accuracy envelope For Qwen2.5-VL, detection is robust roughly between 480×480 and 2560×2560. Outside that band accuracy degrades, with occasional bounding-box drift. --- ## 3. Regime B — Normalized 0–1000 (Qwen3-VL onward) Coordinates are integers on a 0–1000 scale, **normalized independently per axis** against the full image. | Value | Meaning | |---|---| | `(0, 0)` | Top-left corner | | `(1000, 1000)` | Bottom-right corner | | `(500, 500)` | Center | `[0, 0, 1000, 1000]` covers the entire image regardless of input resolution. Emitted values are integers and in practice top out at 999. ### Per-axis, not a square grid Width maps to 0–1000 and height maps to 0–1000 **separately**. Nothing is squashed into a square, and you must not letterbox or pad your input to a square to "match" the grid. Conversion is per-axis: ``` x_pixel = x_norm * (image_width / 1000) y_pixel = y_norm * (image_height / 1000) ``` Example — model returns `(250, 400)` on a 1920×1080 image: - `x = 250 * 1920/1000 = 480` - `y = 400 * 1080/1000 = 432` ### Why this regime is safer Internal resizing becomes irrelevant to post-processing. `smart_resize` still runs (§5) and still affects *what the model can see*, but the output scale is decoupled from it. You always apply the same conversion, against the dimensions of whatever image you sent. ### Precision is not resolution-agnostic The **format** is resolution-independent; the **precision** is not. Integer quantization on a 1000-step scale bounds error at `dimension / 1000` per axis: | Image width | Horizontal quantization | |---|---| | 1280 | ~1.3 px | | 1920 | ~1.9 px | | 2560 | ~2.6 px | | 3840 | ~3.8 px | Adequate for buttons and text fields. Marginal for 16 px icons on a 4K display. --- ## 4. Output formats ### 2D bounding boxes (all families) ```json {"bbox_2d": [x1, y1, x2, y2], "label": "object name"} ``` Multiple objects return a JSON array of such objects. | Field | Meaning | |---|---| | `bbox_2d[0], bbox_2d[1]` | Top-left corner (`x1, y1`) | | `bbox_2d[2], bbox_2d[3]` | Bottom-right corner (`x2, y2`) | | `label` | Class or description | Corner format, **not** `[x, y, w, h]`. Some prompts also elicit an optional `sub_label` for extra attributes. ### Points Two forms are in circulation and both are prompt-driven: - JSON: `{"point_2d": [x, y], "label": "..."}` - XML: QwenCloud's own examples request point output in XML format Ask for the one you want to parse, explicitly. ### 3D bounding boxes (Qwen3-VL — documented) ```json {"bbox_3d": [x_center, y_center, z_center, x_size, y_size, z_size, roll, pitch, yaw], "label": "category"} ``` 3D localization was introduced with Qwen3-VL. **Not documented** for Qwen3.5–3.8; do not assume availability without testing. ### Document layout parsing Structured layout extraction (text plus element positions) uses dedicated prompts: - `qwenvl html` — parse into HTML with position information - `qwenvl markdown` — parse into Markdown (added in Qwen3-VL) ### Output hygiene The model frequently wraps JSON in a Markdown code fence. Strip the fence before parsing. When stripping, anchor the pattern to the string's start and end rather than to line boundaries — a multiline-anchored pattern can remove a fence that appears mid-response and corrupt the payload. --- ## 5. Preprocessing: `smart_resize` Every family resizes before the vision encoder sees anything. 1. Round height and width to the nearest multiple of the **resize factor** (28 for Qwen2.5-VL/QVQ, 32 for Qwen3-VL and later). 2. If total pixels exceed the ceiling, scale down proportionally, re-flooring to the factor. 3. If total pixels fall below the floor (4 tokens' worth), scale up. Rounding to a factor perturbs the aspect ratio very slightly — negligible for rendering, but it means "preserves aspect ratio" is an approximation, not an identity. Aspect ratio is hard-capped at 200:1; beyond that the request errors. ### Token cost ``` tokens = (h_scaled * w_scaled) / (factor * factor) + 2 ``` The `+2` covers the `<vision_bos>` and `<vision_eos>` markers. --- ## 6. Resolution controls These do not change the coordinate convention. They change **how much detail exists to ground against** — the dominant factor in real grounding accuracy. | Family | `vl_high_resolution_images` | Default `max_pixels` | Max `max_pixels` | |---|---|---|---| | Qwen3-VL, Qwen3.5 – Qwen3.8 | Supported | 2,621,440 | 16,777,216 (≈16,384 tokens) | | `qwen-vl-max` / `qwen-vl-plus` 2025 snapshots | Supported | 2,621,440 | 16,777,216 | | QVQ and other Qwen2.5-VL | **Not supported** | 1,003,520 | 12,845,056 | - `vl_high_resolution_images = true` pins a fixed high-resolution policy and **ignores `max_pixels` entirely**. - `vl_high_resolution_images = false` (default) means `max_pixels` governs. ### The screenshot trap Default `max_pixels` of 2,621,440 ≈ 2.6 MP. A 2560×1440 screenshot is 3.7 MP and a 3840×2160 screenshot is 8.3 MP — both are **silently downscaled** before the model sees them. Small UI targets lose the pixels that distinguish them, and grounding degrades in a way that looks like model weakness but is a configuration choice. For GUI work, raise the budget. Expect roughly 10k–16k input tokens for a single full-resolution screenshot, scaling linearly with pixel budget. --- ## 7. Post-processing reference ### Regime B (Qwen3-VL → Qwen3.8) — normalized ```python def norm_to_pixels(box, image_width, image_height): """Convert 0-1000 normalized coordinates to pixels of the image you sent.""" x1, y1, x2, y2 = box return ( x1 * image_width / 1000, y1 * image_height / 1000, x2 * image_width / 1000, y2 * image_height / 1000, ) ``` Clamp to image bounds before drawing or clicking; the model can emit values that round slightly outside the valid range. ### Regime A (Qwen2.5-VL family) — absolute on scaled image ```python def scaled_to_pixels(box, input_width, input_height, orig_width, orig_height): """Rescale absolute model-space pixels back to the original image.""" sx = orig_width / input_width sy = orig_height / input_height x1, y1, x2, y2 = box return (x1 * sx, y1 * sy, x2 * sx, y2 * sy) ``` `input_width` / `input_height` come from `image_grid_thw * patch_size` locally, or from reproducing `smart_resize` when using the hosted API. QwenCloud publishes ready-made rendering scripts per family in the vision guide's FAQ — `qwen2_5-vl-2d.py`, `qwen3-vl-2d.py`, and a 3D bundle for Qwen3-VL. Prefer these over hand-rolled math when the family matches. --- ## 8. GUI and screen element grounding Practical guidance for clicking things in screenshots. - **Raise the pixel budget first.** Almost every "the model can't find the button" report is a downscaling problem, not a grounding problem. See §6. - **Budget the quantization error.** On Regime B, error is `width/1000` per axis (§3). Click the box center, not an edge — center-clicking absorbs the error. - **Consider a purpose-built model.** Qwen3.8-Max and the Qwen3.x flagships are general multimodal models; their vision is framed around document, video, and screenshot *understanding* inside agent loops. Alibaba ships a separate GUI-agent line benchmarked on ScreenSpot-Pro / ScreenSpot-V2 for element localization. For long multi-step click workflows, per-step grounding accuracy compounds — a specialist is worth evaluating. - **Thinking mode is on by default** for Qwen3.8-Max. Good for deciding *which* element to act on; wasteful latency for a pure one-shot localization call. Disable it for the localization step if you split the two. - **Prompt for structure explicitly.** Name the exact JSON shape you will parse. A representative documented prompt: *"locate every instance that belongs to the following categories: CATEGORY. For each, report bbox coordinates in JSON format like this: {"bbox_2d": [x1, y1, x2, y2], "label": CATEGORY}"* --- ## 9. Verification procedure for undocumented models Run this before trusting an **Inferred** row. It takes one request. 1. Take a screenshot or image with an element whose pixel position you know exactly. A non-square image is essential — a square one makes the two regimes indistinguishable. 2. Ask for that single element's `bbox_2d`. 3. Read the returned values: | Observation | Regime | |---|---| | All values ≤ 1000, and don't track image dimensions | **B** — normalized | | Values scale with image dimensions, exceed 1000 on large images | **A** — absolute | | Values ≤ 1000 but the image is under 1000 px | Ambiguous — retest with a larger image | 4. Confirm by re-sending the **same** image at a different resolution. Regime B returns near-identical numbers; Regime A returns proportionally different ones. Record the result. Do not re-derive it per session. --- ## 10. Failure modes | Symptom | Likely cause | |---|---| | Boxes correct in x, offset in y (or vice versa) | Regime A with wrong reference frame; aspect ratio changed by resizing | | Boxes uniformly too small / too large | Regime confusion — dividing by 1000 on absolute output, or not dividing on normalized output | | Boxes roughly right but consistently drifting | Resolution outside the model's reliable band, or over-aggressive downscaling | | Small UI elements missed entirely | `max_pixels` downscaling; raise the budget (§6) | | JSON parse failures | Markdown code fence not stripped, or fence stripped with a line-anchored pattern (§4) | | Correct on one image, wrong on another | Per-image `smart_resize` producing different scale factors — Regime A only | --- ## 11. Source notes - **Documented:** QwenCloud vision guide and its bounding-box FAQ; Qwen3-VL repository README; QwenCloud visual-understanding model tables. - **Well-corroborated:** ms-swift best-practice guides for Qwen3-VL and Qwen3.5, which convert absolute training annotations to a normalized 1000 scale; multiple independent implementations and issue threads confirming the 0–1000 range. - **Inferred:** the Qwen3.6 / 3.7 / 3.8 rows. These share Qwen3-VL's 32×32 tiling, `max_pixels` defaults, and `vl_high_resolution_images` behavior, which makes inheritance likely — but no official source states it. Verify per §9. Qwen ships new vision models frequently. Re-check the coordinate convention when a new family appears rather than assuming continuity; the Qwen2-VL → Qwen2.5-VL → Qwen3-VL sequence already reversed convention twice.
ui-responsive-guide
# Responsive Implementation Guide Reference for making a UI responsive — whether you are building it from scratch or adding responsiveness to something already built. **How to use this document** | Situation | Read | |---|---| | Building new UI | Part 1 → Part 2 → Part 5 | | Existing UI, not responsive | Part 1 → Part 3 → Part 5 | | Fixing a specific component | Part 4 → Part 6 | | Reviewing someone's work | Part 5 → Part 6 | Part 1 (defaults) and Part 5 (verification) apply to every path. Everything else is situational. --- ## Part 1 — Model and defaults ### 1.1 Five layers, five tools Responsiveness is not one mechanism. Pick the layer first, then the tool. | Layer | Tool | Use for | |---|---|---| | Item flow inside a region | Intrinsic layout (`auto-fit` + `minmax`, `flex-wrap`) | Card grids, tag lists, toolbars — reflows with **no breakpoint at all** | | Component internals | Container queries | Anything reusable that appears in more than one context | | Page structure | Media queries | Nav ↔ sidebar, region count, shell composition | | Type and space | `clamp()` | Sizes that should scale continuously | | User and device context | Preference/capability queries | Motion, contrast, color scheme, pointer type | **Order of preference: intrinsic → container → media.** Every breakpoint is a maintenance liability and a place the design can break between. Reach for a media query only when the *page structure* actually changes. ### 1.2 Defaults that prevent most bugs **Prerequisite — the viewport meta tag.** Without `<meta name="viewport" content="width=device-width, initial-scale=1">`, none of what follows does anything: mobile browsers lay out against a ~980px virtual viewport and scale the result down. Two rules attach to it: - **Never `user-scalable=no` or `maximum-scale=1`.** Suppressing pinch-zoom is a WCAG 1.4.4 (Resize Text) failure and is the most commonly shipped accessibility defect in a single line of HTML. If zooming breaks the layout, the layout is the bug — do not disable the zoom. - **`interactive-widget=resizes-content`** changes virtual-keyboard behavior so the layout viewport shrinks instead of the keyboard overlaying it. This is usually what you want for fixed bottom bars and full-height panels; the default is `resizes-visual`. Behavior still varies by browser, so verify (Part 6). The rules below are not optional style choices. Most responsive failures trace back to one of them. 1. **`min-width: 0` on flex and grid children.** The default `min-width: auto` refuses to shrink below content size — this is the single most common cause of horizontal overflow. Same for `min-height: 0` on the block axis. 2. **`minmax(0, 1fr)`, not `1fr`,** for any grid track holding text, media, or a nested scroll container. `1fr` is `minmax(auto, 1fr)` and inherits the same problem. 3. **Never `100vw` for full-bleed.** It includes the scrollbar width on desktop and produces horizontal scroll. Use `100%` of a full-width ancestor, or a margin-based bleed technique. 4. **No fixed heights on anything containing text.** Use `min-height`. Text length varies by locale, font-size setting, and wrapping. 5. **Cap the text measure.** `max-inline-size: 60ch–75ch` on prose. Fluid width without a cap produces unreadable 200-character lines on wide screens. 6. **Media gets `aspect-ratio` + `object-fit`,** plus intrinsic `width`/`height` attributes on `<img>` so the browser reserves space before load (CLS). 7. **Logical properties** (`inline`/`block`, `-start`/`-end`) instead of left/right — required for RTL, free if adopted from the start. 8. **`overflow-wrap: anywhere`** on user-generated content, and anywhere URLs, emails, hashes, or IDs can appear. One unbreakable string breaks an entire layout. 9. **Viewport height:** `dvh` when the element should fill the visible area, `svh` when the value must be stable. `dvh` changes as the mobile URL bar collapses, which causes visible jitter if it drives an animation or a measured value. Avoid bare `vh` on mobile. 10. **Interactive targets — know which number you are meeting.** There are two, and they are frequently conflated: - **24×24 CSS px is the compliance floor** (WCAG 2.2 SC 2.5.8, Level AA). It can be met by size *or* by spacing — an undersized target passes if a 24px-diameter circle centered on it doesn't intersect another target's circle, i.e. centers at least 24px apart. Exceptions exist for inline links inside a sentence and for controls rendered by the browser and left unstyled. - **44×44 CSS px is the enhanced target** (SC 2.5.5, Level AAA), and matches Apple's 44pt guidance; Material asks 48dp. Design to 44 wherever the pointer may be coarse and AA comes for free. Treat 24 as a floor you must not go under, not as a goal. Either way the measurement is the **tap area**, not the visual box — a 16px icon is fine inside a 44px hit region. 11. **`scrollbar-gutter: stable`** on scroll containers, to stop layout shifting when a scrollbar appears. 12. **`env(safe-area-inset-*)`** on fixed or edge-anchored UI, or it lands under the notch and home indicator. ### 1.3 Breakpoints - **Content-driven, not device-driven.** Widen the window until the design breaks; that width is the breakpoint. Device widths are a coincidence, and there are too many of them to target. - The conventional scale is a starting grid, not a truth: `sm 40rem/640px`, `md 48rem/768px`, `lg 64rem/1024px`, `xl 80rem/1280px`, `2xl 96rem/1536px` (Tailwind's defaults). Delete the ones you don't use; add the ones your content needs. - **Define breakpoints in `rem`,** so they respond to the user's browser font-size setting. - **Mobile-first (`min-width`) for new work.** For existing codebases see §3.1 — this rule flips. - **The floor is 320 CSS px.** WCAG 1.4.10 (Reflow) requires content to work at 320px wide without two-dimensional scrolling. ### 1.4 Fluid sizing - The shape is `clamp(min, preferred, max)`, bounds in `rem`. - **The preferred term must include a `rem` component,** e.g. `clamp(1rem, 0.9rem + 0.5vw, 1.25rem)`. A pure `vw` middle term makes text ignore the user's font-size preference entirely, which is an accessibility failure, not a styling detail. - Fluid sizing removes breakpoints for **size**. It does not remove them for **structure** — a two-column layout still has to become one column somewhere. - Inside a container-query context, `cqi` scales type to the *component's* width instead of the viewport's. This is the right unit for a card that lives in both a sidebar and a full-width region. ### 1.5 Responsive is not only about width Width is one axis. These are the others, and they are usually the ones skipped: | Query | What it protects | |---|---| | `prefers-reduced-motion` | Vestibular disorders; also a general performance escape hatch | | `prefers-color-scheme` | Dark mode | | `prefers-contrast` | Low-vision users | | `forced-colors` | Windows High Contrast — your custom colors are discarded, check nothing disappears | | `pointer: coarse` / `fine` | Hit-target sizing, hover affordances | | `any-hover: none` | Touch devices where hover cannot happen | | `orientation` / short viewports | Landscape phones, split-screen | **Rule:** any affordance revealed only on hover must have a non-hover path. On touch there is no hover, and the first tap becomes a hover the user cannot dismiss. --- ## Part 2 — Building new UI Ordered. Each step has an exit condition; do not carry a failure forward. ### Step 0 — Decide content constraints Before any CSS: what must be visible at 320px, what is the minimum usable width of the densest element (a table, a chart, a code block), what is the reading measure. **Content parity is the constraint** — plan to *restructure* content at small sizes, never to delete it. If something must be hidden on mobile, question whether it belongs on desktop. *Exit: you can name the narrowest element on the page and its minimum width.* ### Step 1 — Build the skeleton at 320px Single column, real content (not lorem, not three-word labels), zero breakpoints, zero fixed widths. Confirm the viewport meta tag is present and does not block zoom (§1.2). *Exit: the page is usable and readable at 320px with no horizontal scroll.* ### Step 2 — Establish tokens Fluid type scale and spacing scale per §1.4. Define them once as custom properties. Do not hand-tune sizes per component afterwards. *Exit: no raw font-size or spacing values in component CSS.* ### Step 3 — Stretch it, unmodified Widen from 320px to 1600px+ with no breakpoints added. Write down every width where it breaks and what breaks — line measure too long, cards absurdly wide, whitespace collapsing, controls drifting apart. *Exit: a list of failure widths with causes. This list defines your breakpoints; nothing else does.* ### Step 4 — Solve with intrinsic layout first For each failure, ask whether flow solves it: `repeat(auto-fit, minmax(min(280px, 100%), 1fr))` for card grids, `flex-wrap` for toolbars, `max-inline-size` for prose. Anything solved here needs no breakpoint and no maintenance. *Exit: only genuine structural changes remain on the list.* ### Step 5 — Add media queries for page structure only Nav collapsing, sidebar appearing, region count changing. Put the breakpoint at the width you recorded in Step 3, not at a device width. *Exit: each media query maps to a recorded failure. Any query you cannot justify gets deleted.* ### Step 6 — Container queries for component internals Any component that appears in more than one context (sidebar and main, modal and page, grid cell and full width) responds to its own container, not the viewport. Set the containment on a **wrapper**, since an element cannot query itself (§6). *Exit: dropping any component into a narrow container produces its compact layout, with no parent-specific overrides.* ### Step 7 — Media, tables, embeds, overlays See Part 4. ### Step 8 — Input modality and preferences Apply §1.5. Hit targets, hover guards, reduced motion, focus visibility. ### Step 9 — Verify Part 5, in full. --- ## Part 3 — Retrofitting an existing UI Different problem. This is diagnosis and controlled change, not authoring. The failure mode is not "I don't know the CSS" — it is breaking desktop while fixing mobile. ### 3.0 Before touching anything - **Capture a baseline.** Screenshots of every critical screen at desktop width, in each significant state (empty, loaded, error, modal open). This is your non-regression contract: desktop must be unchanged unless a change was explicitly requested. - **Scope to one route or screen at a time.** A codebase-wide responsive pass with no checkpoints is unreviewable and unrevertable. - **Identify shared surfaces** (shell, nav, design tokens, base components). Changes there are global; treat them as a separate, higher-risk workstream. ### 3.1 Determine the codebase's existing direction Count `max-width` versus `min-width` media queries. - **Desktop-first (`max-width` dominant):** *stay desktop-first.* Inverting to mobile-first means rewriting every rule, re-specifying every default, and re-QAing every screen. It is a rewrite disguised as a refactor. Add `max-width` queries consistent with what is there. - **Mobile-first:** continue mobile-first. - **Mixed:** normalize per-file as you touch each file. Never do a global sweep as a side quest. This decision comes first because it determines the shape of every change that follows. ### 3.2 Audit — find, do not fix Scan the scoped area and record findings without changing anything. Fixing while auditing produces half-fixes and lost context. What to search for, roughly in order of damage caused: - a missing viewport meta tag, or one carrying `user-scalable=no` / `maximum-scale=1` — check this first, it is one line and it invalidates everything downstream - `width`/`height` in `px` on layout containers - `100vw` - `position: absolute` / `fixed` with pixel offsets - `white-space: nowrap` - fixed column counts in `grid-template-columns` - `min-width` on containers, tables, and modals - `overflow: hidden` used to hide a symptom - fixed-height headers, footers, and cards containing text - inline styles and JS-computed dimensions - third-party embeds: iframes, charts, maps, video players, payment widgets - hover-dependent interactions - `vh` units *Exit: a written list of findings mapped to elements. This is the work plan.* ### 3.3 Fix in ancestor-first order Bottom-up retrofits fail: a component cannot be responsive inside a container that isn't. 1. **Overflow first.** Nothing else can be evaluated while the page scrolls sideways — every downstream measurement is wrong. To locate the source: set the viewport to 320px, then bisect by hiding subtrees until the scroll disappears. Usual culprits are §1.2 rules 1–3, unbreakable strings, tables, and absolutely positioned elements. 2. **Page shell** — header, nav, footer, main/sidebar regions. 3. **Layout containers** within each region. 4. **Components** — introduce container queries here, once ancestors are fluid. 5. **Typography and spacing.** 6. **Media and embeds.** 7. **Tables and dense data.** 8. **Interaction targets and preferences.** **One concern per change, verified before the next.** Batched retrofit changes cannot be attributed when something regresses, and something will. ### 3.4 Blast radius - Editing a shared token or base component requires re-verifying every screen that consumes it. Budget for that or don't make the edit. - Early on, prefer additive, scoped changes. Once the same fix appears three or more times, consolidate it into a token or shared rule — then re-verify consumers. - Never widen a selector's scope to fix one screen. That converts a local fix into a global risk. ### 3.5 What not to do - **Do not add `display: none` breakpoints to make problems disappear.** That is content loss, and screen-reader and SEO loss, dressed up as responsiveness. - **Do not build a parallel mobile DOM** (a second nav, a table plus a duplicate card list). It duplicates the accessibility tree, splits state, breaks focus order, and doubles every future change. Restructure one tree with CSS instead. - **Do not fork rendering on JS breakpoints.** `matchMedia`-driven conditional rendering causes SSR hydration mismatch and a visible flash, and it fails before JS loads. CSS handles layout; JS is for behavior. - **Do not put `overflow-x: hidden` on `body`.** It hides the symptom, leaves the broken element in place, and can break `position: sticky` in ancestor contexts. - **Do not chase pixel-perfect parity with the desktop design at small sizes.** Small-screen layouts are a different composition, not a scaled one. --- ## Part 4 — Component playbook **Navigation.** One DOM tree, two presentations. Mobile: disclosure pattern with `aria-expanded`, focus trap only if it's a true overlay, and a working Escape. Ensure the trigger is reachable and the menu doesn't exceed viewport height without scrolling. **Tables.** Pick one strategy per table, deliberately: (a) horizontal scroll inside a wrapper with a sticky first column — best for genuine comparison data; (b) column priority, dropping low-value columns as width decreases; (c) restructure to a definition-list layout at small widths. Never duplicate the table's content into a second markup tree. **Modals and drawers.** Height is the failure axis, not width. Content must scroll inside the dialog; the dialog must not exceed the *visible* viewport (`dvh`) and must clear the mobile keyboard and safe areas. **Forms.** Full-width inputs below the tablet breakpoint. Labels above, not beside. Font-size ≥ 16px on iOS or the browser zooms on focus. Group related fields so the layout can collapse from multi-column without reordering meaning. **Images.** `srcset` + `sizes` for resolution switching; `<picture>` only when the *crop* changes, not merely the size. `sizes` must reflect the actual rendered width — a wrong `sizes` silently downloads the wrong file and the bug is invisible locally. For lazy-loaded images, `sizes="auto"` hands that calculation to the browser, which uses the element's real laid-out size; write it as `sizes="auto, <your normal sizes list>"` so browsers without support fall back rather than defaulting to `100vw`. **Charts and embeds.** Third-party content usually isn't responsive. Wrap it in a container with a set `aspect-ratio`, and check whether the library needs an explicit resize call. Charts frequently need a *different* configuration at small widths (fewer ticks, rotated labels, legend moved), not just a smaller canvas. **Long-form text.** Measure cap, fluid type, and check hyphenation and wrapping in the longest supported locale — German and Finnish break layouts that pass in English. --- ## Part 5 — Verification (definition of done) Not one of these is optional. Most responsive bugs shipped to production pass a desktop-browser resize test. - [ ] **Viewport meta** present, with zoom not disabled - [ ] **320 CSS px wide** — no horizontal scroll, all content reachable, nothing clipped - [ ] **Between breakpoints** — check 700, 900, 1100, 1400px, not only the breakpoint values themselves - [ ] **200% browser zoom** at desktop width - [ ] **Root font-size raised** (browser setting, e.g. 24px) — layout and breakpoints still behave - [ ] **Short viewport** — landscape phone, ~500px tall: modals scroll, sticky elements don't consume the screen - [ ] **Mobile URL bar collapse** — no layout jump, no clipped fixed elements - [ ] **Container resize** — drag the container edge in DevTools for every container-query component - [ ] **Touch** — nothing under the 24×24 AA floor (by size or by 24px spacing), 44×44 on primary and frequently-used controls; no hover-only affordance, no sticky hover state after tap - [ ] **Keyboard** — focus visible and focus order sane at every size, including with the mobile menu open - [ ] **`prefers-reduced-motion`** honored - [ ] **No CLS** — media has reserved dimensions - [ ] **Real devices** — at least one iOS and one Android; simulators miss keyboard, URL bar, and safe-area behavior - [ ] **RTL**, if supported - [ ] **Desktop regression** against the Part 3.0 baseline *(retrofit only)* --- ## Part 6 — Gotchas - **`container-type: inline-size` applies size containment.** The element can no longer be sized by its own content in that axis. Applying it to the wrong element silently collapses layouts. - **An element cannot query itself.** The container must be an ancestor — always wrap. - **Container *size* queries are baseline and safe. Container *style* queries are newly interoperable.** Size queries have been interoperable since 2023. Style queries (`@container style(--x: y)`) shipped in Chromium and Safari first and reached Firefox in version 151 (May 2026), so all three engines now support them — but that interop is recent enough that anything below a current-version browser floor won't have it. Use them as progressive enhancement and confirm against your own support matrix before making them load-bearing. - **Don't make everything a container.** Containment has a cost, and deep nesting of query containers gets expensive. - **Tailwind's container scale is not its viewport scale.** `@md:` fires around 28rem/448px while `md:` fires at 48rem/768px. Assuming they match is a common and hard-to-spot bug. Container queries are built into v4; v3.2+ needs the container-queries plugin. v4 configures breakpoints via `@theme` in CSS rather than `tailwind.config.js`. - **`vw`-only font sizing ignores user font preferences** — see §1.4. - **Sticky hover on touch.** Guard hover styles with `@media (hover: hover)`. - **Fixed elements and the mobile keyboard.** A `position: fixed` bottom bar can sit under or over the keyboard depending on the browser. `interactive-widget=resizes-content` in the viewport meta tag (§1.2) is the intended lever, but coverage is uneven — test with a focused input on real iOS and Android, and fall back to the VisualViewport API only if you must. - **`min-height: 100vh` on the shell plus an inner scroll container** produces nested scrollbars. Pick one scroll owner. - **Subgrid** is the correct tool for aligning content across sibling cards (equal-height headers, aligned footers) — better than fixed heights or JS measurement. - **Sibling-selector layouts** (`:has()`, `nth-child` based grids) can behave differently once wrapping changes the visual order. Re-check them at each width. --- ## Part 7 — Quick reference **Units** | Unit | Relative to | Use for | |---|---|---| | `%` | Parent | Widths inside a known container | | `rem` | Root font-size | Everything sizing-related; honors user settings | | `ch` | Character width | Text measure caps | | `vw` | Viewport width | Fluid terms inside `clamp()` only | | `dvh` / `svh` / `lvh` | Dynamic / small / large viewport | Fill / stable / maximum height | | `cqi` / `cqw` / `cqh` | Query container | Component-relative sizing | | `fr` + `minmax(0, …)` | Grid track | Layout tracks | **Recipes** - Fluid value: `clamp(<min>rem, <base>rem + <n>vw, <max>rem)` — the middle term keeps a `rem` component. - Breakpoint-free grid: `repeat(auto-fit, minmax(min(<ideal>, 100%), 1fr))` — the inner `min()` prevents overflow below the ideal width. - Full-bleed: width from a full-width ancestor, never `100vw`. **Target sizes** | Number | Source | Status | |---|---|---| | 24×24 CSS px | WCAG 2.2 SC 2.5.8 (AA) | Floor. Size *or* 24px spacing. Inline-text and unstyled-control exceptions apply. | | 44×44 CSS px | WCAG 2.2 SC 2.5.5 (AAA); Apple 44pt | Design target for coarse pointers | | 48×48 dp | Material Design | Android platform guidance | **Standard breakpoint scale (rem-based)** `sm 40rem` · `md 48rem` · `lg 64rem` · `xl 80rem` · `2xl 96rem` Treat as a starting grid. Content decides the real values.
build-prompts-msr4c9d1
# BUILD PROMPTS Landscape — Links & Titles ## Ranked Shortlist 1. [github/spec-kit](https://github.com/github/spec-kit) 2. [ai-boost/awesome-prompts](https://github.com/ai-boost/awesome-prompts) 3. [commit-0/commit0](https://github.com/commit-0/commit0) 4. [Fission-AI/OpenSpec](https://github.com/Fission-AI/openspec) 5. [bmad-code-org/BMAD-METHOD](https://github.com/bmad-code-org/bmad-method) 6. [ProjectEval — RyanLoil/ProjectEval](https://github.com/RyanLoil/ProjectEval) 7. [facebookresearch/ProgramBench](https://github.com/facebookresearch/programbench) 8. [Shubhamsaboo/awesome-llm-apps](https://github.com/Shubhamsaboo/awesome-llm-apps) 9. [NL2RepoBench — multimodal-art-projection/NL2RepoBench](https://github.com/multimodal-art-projection/NL2RepoBench) 10. [gsd-build/get-shit-done](https://github.com/gsd-build/get-shit-done) 11. [KhazP/vibe-coding-prompt-template](https://github.com/KhazP/vibe-coding-prompt-template) 12. [TechNomadCode/AI-Product-Development-Toolkit](https://github.com/TechNomadCode/AI-Product-Development-Toolkit) 13. [eyaltoledano/claude-task-master](https://github.com/eyaltoledano/claude-task-master) 14. [nl2code/codes (CodeS)](https://github.com/nl2code/codes) 15. [nurettincoban/ai-prd-workflow](https://github.com/nurettincoban/ai-prd-workflow) 16. [wundercorp/awesome-prompts](https://github.com/wundercorp/awesome-prompts) 17. [bigcode-project/bigcodebench](https://github.com/bigcode-project/bigcodebench) 18. [VoltAgent/awesome-design-md](https://github.com/voltagent/awesome-design-md) 19. [agigante80/vibe-coding-prompts](https://github.com/agigante80/vibe-coding-prompts) 20. [singhprakhar/kaiju-samples](https://huggingface.co/datasets/singhprakhar/kaiju-samples) --- ## Bucket 1 — Frontend / Web Apps - [VoltAgent/awesome-design-md](https://github.com/voltagent/awesome-design-md) - [wundercorp/awesome-prompts](https://github.com/wundercorp/awesome-prompts) - [Bolt.new Mega Prompt](https://gist.github.com/iamnolanhu/d0f6b04cea7b83e36fc83895e1cef7d1) - [langgptai/awesome-claude-prompts](https://github.com/langgptai/awesome-claude-prompts) --- ## Bucket 2 — Fullstack SaaS - [github/spec-kit](https://github.com/github/spec-kit) - [ai-boost/awesome-prompts](https://github.com/ai-boost/awesome-prompts) - [abhiprojectz/SaaS-GPT4-Prompts](https://github.com/abhiprojectz/SaaS-GPT4-Prompts) - [KhazP/vibe-coding-prompt-template](https://github.com/KhazP/vibe-coding-prompt-template) - [TechNomadCode/AI-Product-Development-Toolkit](https://github.com/TechNomadCode/AI-Product-Development-Toolkit) --- ## Bucket 3 — Backend / APIs - [eyaltoledano/claude-task-master](https://github.com/eyaltoledano/claude-task-master) - [agigante80/vibe-coding-prompts](https://github.com/agigante80/vibe-coding-prompts) - [nurettincoban/ai-prd-workflow](https://github.com/nurettincoban/ai-prd-workflow) --- ## Bucket 4 — Data Engineering & Analytics - [ai-boost/awesome-prompts — data_engineer.md](https://github.com/ai-boost/awesome-prompts/blob/main/prompts/data_engineer.md) --- ## Bucket 5 — ML / AI Engineering - [Shubhamsaboo/awesome-llm-apps](https://github.com/Shubhamsaboo/awesome-llm-apps) - [MendoLeo/awesome-llms-apps](https://github.com/MendoLeo/awesome-llms-apps) - [sickn33/agentic-awesome-skills](https://github.com/sickn33/agentic-awesome-skills) - [benchflow-ai/awesome-evals](https://github.com/benchflow-ai/awesome-evals) --- ## Bucket 6 — Android No dedicated link listed. Partial coverage mentioned through: - [ai-boost/awesome-prompts](https://github.com/ai-boost/awesome-prompts) - [sickn33/agentic-awesome-skills](https://github.com/sickn33/agentic-awesome-skills) --- ## Bucket 7 — iOS No dedicated link listed. Partial coverage mentioned through: - [ai-boost/awesome-prompts](https://github.com/ai-boost/awesome-prompts) --- ## Bucket 8 — Cross-Platform Mobile - [machinemindsai/react-native-prompts](https://github.com/machinemindsai/react-native-prompts) - [RapidNative AI Prompt Library](https://www.rapidnative.com/blogs/ai-prompt-library) --- ## Bucket 9 — DevOps / Infra - [agigante80/vibe-coding-prompts](https://github.com/agigante80/vibe-coding-prompts) --- ## Bucket 10 — CLI Tools, Desktop Apps, Browser Extensions - [browser-use/awesome-prompts](https://github.com/browser-use/awesome-prompts) --- ## Bucket 11 — Games, Simulations, Creative Coding - [DocsBot Game Development Prompts](https://docsbot.ai/prompts/tags?tag=Game%20Development) --- ## Bucket 12 — Bots and Automation Workflows - [enescingoz/awesome-n8n-templates](https://github.com/enescingoz/awesome-n8n-templates) - [lucaswalter/n8n-ai-automations](https://github.com/lucaswalter/n8n-ai-automations) - [mergisi/awesome-openclaw-agents](https://github.com/mergisi/awesome-openclaw-agents) --- ## Cross-Domain / Spec-Driven Development Tools - [Fission-AI/OpenSpec](https://github.com/Fission-AI/openspec) - [bmad-code-org/BMAD-METHOD](https://github.com/bmad-code-org/bmad-method) - [gsd-build/get-shit-done](https://github.com/gsd-build/get-shit-done) - [buildermethods/agent-os](https://github.com/buildermethods/agent-os) --- # Benchmark / Dataset Build Prompts - [SWE-bench Verified — HuggingFace](https://huggingface.co/datasets/SWE-bench/SWE-bench_Verified) - [SWE-bench — GitHub](https://github.com/swe-bench/SWE-bench) - [commit-0/commit0 — GitHub](https://github.com/commit-0/commit0) - [commit0/commit0 — HuggingFace](https://huggingface.co/datasets/commit0/commit0) - [ProgramBench — GitHub](https://github.com/facebookresearch/programbench) - [ProgramBench-Tests — HuggingFace](https://huggingface.co/datasets/programbench/ProgramBench-Tests) - [NL2RepoBench — GitHub](https://github.com/multimodal-art-projection/NL2RepoBench) - [ProjectEval — GitHub](https://github.com/RyanLoil/ProjectEval) - [CodeS / SketchEval — GitHub](https://github.com/nl2code/codes) - [BigCodeBench — GitHub](https://github.com/bigcode-project/bigcodebench) - [codeparrot/apps — HuggingFace](https://huggingface.co/datasets/codeparrot/apps) - [hendrycks/apps — GitHub](https://github.com/hendrycks/apps) - [Leolty/repobench — GitHub](https://github.com/Leolty/repobench) - [singhprakhar/kaiju-samples — HuggingFace](https://huggingface.co/datasets/singhprakhar/kaiju-samples) - [RealBench — Figshare](https://figshare.com/articles/dataset/RealBench_A_Repo-Level_Code_Generation_Benchmark_Aligned_with_Real-World_Software_Development_Practices/28596638) - [RepoZero — arXiv](https://arxiv.org/html/2605.07122v1) - [FEA-Bench — HuggingFace Papers](https://huggingface.co/papers/2503.06680) --- # Extraction Appendix — Raw Prompt Locations ## SWE-bench Verified - [SWE-bench/SWE-bench_Verified — HuggingFace](https://huggingface.co/datasets/SWE-bench/SWE-bench_Verified) - [SWE-bench — GitHub](https://github.com/swe-bench/SWE-bench) ## Commit0 - [commit-0/commit0 — GitHub](https://github.com/commit-0/commit0) - [commit0/commit0 — HuggingFace](https://huggingface.co/datasets/commit0/commit0) - [Commit0: Library Generation from Scratch — arXiv](https://arxiv.org/abs/2412.01769) ## ProgramBench - [facebookresearch/ProgramBench — GitHub](https://github.com/facebookresearch/programbench) - [programbench/ProgramBench-Tests — HuggingFace](https://huggingface.co/datasets/programbench/ProgramBench-Tests) - [ProgramBench — arXiv](https://arxiv.org/html/2605.03546v1) ## NL2RepoBench - [multimodal-art-projection/NL2RepoBench — GitHub](https://github.com/multimodal-art-projection/NL2RepoBench) - [NL2Repo-Bench — arXiv](https://arxiv.org/html/2512.12730v1) ## ProjectEval - [RyanLoil/ProjectEval — GitHub](https://github.com/RyanLoil/ProjectEval) - [ProjectEval — ACL Findings 2025](https://aclanthology.org/2025.findings-acl.1036.pdf) ## CodeS / SketchEval - [nl2code/codes — GitHub](https://github.com/nl2code/codes) - [CodeS: NL to Code Repository — ACM TOSEM](https://dl.acm.org/doi/10.1145/3768577) ## BigCodeBench - [bigcode-project/bigcodebench — GitHub](https://github.com/bigcode-project/bigcodebench) - [BigCodeBench Leaderboard](https://bigcode-bench.github.io/) ## APPS - [codeparrot/apps — HuggingFace](https://huggingface.co/datasets/codeparrot/apps) - [hendrycks/apps — GitHub](https://github.com/hendrycks/apps) ## RepoBench - [Leolty/repobench — GitHub](https://github.com/Leolty/repobench) - [RepoBench — ICLR 2024](https://proceedings.iclr.cc/paper_files/paper/2024/file/d191ba4c8923ed8fd8935b7c98658b5f-Paper-Conference.pdf) ## Kaiju - [singhprakhar/kaiju-samples — HuggingFace](https://huggingface.co/datasets/singhprakhar/kaiju-samples) ## RealBench - [RealBench — Figshare](https://figshare.com/articles/dataset/RealBench_A_Repo-Level_Code_Generation_Benchmark_Aligned_with_Real-World_Software_Development_Practices/28596638) ## RepoZero - [RepoZero — arXiv](https://arxiv.org/html/2605.07122v1) ## FEA-Bench - [FEA-Bench — HuggingFace Papers](https://huggingface.co/papers/2503.06680) --- # Meta-Lists and Indexes - [codefuse-ai/Awesome-Code-LLM](https://github.com/codefuse-ai/Awesome-Code-LLM) - [tongye98/Awesome-Code-Benchmark](https://github.com/tongye98/Awesome-Code-Benchmark) - [YerbaPage/Awesome-Repo-Level-Code-Generation](https://github.com/YerbaPage/Awesome-Repo-Level-Code-Generation) - [allanj/repo-level-codegen-papers](https://github.com/allanj/repo-level-codegen-papers) - [dukeluo/awesome-awesome-prompts](https://github.com/dukeluo/awesome-awesome-prompts) - [danielrosehill/awesome-llm-prompt-libraries](https://github.com/danielrosehill/awesome-llm-prompt-libraries) - [chendongqi/awesome-ai-coding](https://github.com/chendongqi/awesome-ai-coding) - [filipecalegario/awesome-vibe-coding](https://github.com/filipecalegario/awesome-vibe-coding) - [taskade/awesome-vibe-coding](https://github.com/taskade/awesome-vibe-coding) - [saviorand/awesome-ai-assisted-coding](https://github.com/saviorand/awesome-ai-assisted-coding) --- # Additional Sources - [GitHub Blog — Spec-driven development with AI](https://github.blog/ai-and-ml/generative-ai/spec-driven-development-with-ai-get-started-with-a-new-open-source-toolkit/) - [9 PRD and Spec Templates Built for AI Coding Agents — SSOJet](https://ssojet.com/blog/prd-spec-templates-ai-agents) - [RapidNative AI Prompt Library](https://www.rapidnative.com/blogs/ai-prompt-library) - [DocsBot Game Development Prompts](https://docsbot.ai/prompts/tags?tag=Game%20Development) --- # Unverified / Excluded Leads Mentioned - `samuxbuilds/awesome-prompts` — excluded; identified as an AI image-generation prompt collection. - `instructa/ai-prompts` — excluded; primarily `.cursorrules` and system prompt files. - `convertscout/awesome-ai-prompts` — excluded; primarily Cursor rules / `.cursorrules`. - `piyushrajyadav/awesome-ai-dev-prompts` — excluded; system prompts for AI coding tools. - [RapidNative AI Prompt Library](https://www.rapidnative.com/blogs/ai-prompt-library) — mentioned as a web-based resource rather than a GitHub raw-prompt repository. - [gsd-build/get-shit-done](https://github.com/gsd-build/get-shit-done) — mentioned as having moved to a new repository. --- # Unique Links From the Original Paste 1. [ai-boost/awesome-prompts](https://github.com/ai-boost/awesome-prompts) 2. [github/spec-kit](https://github.com/github/spec-kit) 3. [GitHub Blog — Spec-driven development with AI](https://github.blog/ai-and-ml/generative-ai/spec-driven-development-with-ai-get-started-with-a-new-open-source-toolkit/) 4. [Fission-AI/OpenSpec](https://github.com/Fission-AI/openspec) 5. [bmad-code-org/BMAD-METHOD](https://github.com/bmad-code-org/bmad-method) 6. [gsd-build/get-shit-done](https://github.com/gsd-build/get-shit-done) 7. [eyaltoledano/claude-task-master](https://github.com/eyaltoledano/claude-task-master) 8. [buildermethods/agent-os](https://github.com/buildermethods/agent-os) 9. [KhazP/vibe-coding-prompt-template](https://github.com/KhazP/vibe-coding-prompt-template) 10. [TechNomadCode/AI-Product-Development-Toolkit](https://github.com/TechNomadCode/AI-Product-Development-Toolkit) 11. [nurettincoban/ai-prd-workflow](https://github.com/nurettincoban/ai-prd-workflow) 12. [agigante80/vibe-coding-prompts](https://github.com/agigante80/vibe-coding-prompts) 13. [wundercorp/awesome-prompts](https://github.com/wundercorp/awesome-prompts) 14. [abhiprojectz/SaaS-GPT4-Prompts](https://github.com/abhiprojectz/SaaS-GPT4-Prompts) 15. [Bolt.new Mega Prompt](https://gist.github.com/iamnolanhu/d0f6b04cea7b83e36fc83895e1cef7d1) 16. [machinemindsai/react-native-prompts](https://github.com/machinemindsai/react-native-prompts) 17. [langgptai/awesome-claude-prompts](https://github.com/langgptai/awesome-claude-prompts) 18. [Shubhamsaboo/awesome-llm-apps](https://github.com/Shubhamsaboo/awesome-llm-apps) 19. [MendoLeo/awesome-llms-apps](https://github.com/MendoLeo/awesome-llms-apps) 20. [VoltAgent/awesome-design-md](https://github.com/voltagent/awesome-design-md) 21. [browser-use/awesome-prompts](https://github.com/browser-use/awesome-prompts) 22. [enescingoz/awesome-n8n-templates](https://github.com/enescingoz/awesome-n8n-templates) 23. [mergisi/awesome-openclaw-agents](https://github.com/mergisi/awesome-openclaw-agents) 24. [lucaswalter/n8n-ai-automations](https://github.com/lucaswalter/n8n-ai-automations) 25. [sickn33/agentic-awesome-skills](https://github.com/sickn33/agentic-awesome-skills) 26. [benchflow-ai/awesome-evals](https://github.com/benchflow-ai/awesome-evals) 27. [SWE-bench Verified — HuggingFace](https://huggingface.co/datasets/SWE-bench/SWE-bench_Verified) 28. [SWE-bench — GitHub](https://github.com/swe-bench/SWE-bench) 29. [commit-0/commit0 — GitHub](https://github.com/commit-0/commit0) 30. [commit0/commit0 — HuggingFace](https://huggingface.co/datasets/commit0/commit0) 31. [Commit0 — arXiv](https://arxiv.org/abs/2412.01769) 32. [ProgramBench — GitHub](https://github.com/facebookresearch/programbench) 33. [ProgramBench-Tests — HuggingFace](https://huggingface.co/datasets/programbench/ProgramBench-Tests) 34. [ProgramBench — arXiv](https://arxiv.org/html/2605.03546v1) 35. [NL2RepoBench — GitHub](https://github.com/multimodal-art-projection/NL2RepoBench) 36. [NL2Repo-Bench — arXiv](https://arxiv.org/html/2512.12730v1) 37. [ProjectEval — GitHub](https://github.com/RyanLoil/ProjectEval) 38. [ProjectEval — ACL](https://aclanthology.org/2025.findings-acl.1036.pdf) 39. [nl2code/codes — GitHub](https://github.com/nl2code/codes) 40. [CodeS — ACM TOSEM](https://dl.acm.org/doi/10.1145/3768577) 41. [bigcode-project/bigcodebench](https://github.com/bigcode-project/bigcodebench) 42. [BigCodeBench Leaderboard](https://bigcode-bench.github.io/) 43. [codeparrot/apps — HuggingFace](https://huggingface.co/datasets/codeparrot/apps) 44. [hendrycks/apps — GitHub](https://github.com/hendrycks/apps) 45. [Leolty/repobench](https://github.com/Leolty/repobench) 46. [RepoBench — ICLR](https://proceedings.iclr.cc/paper_files/paper/2024/file/d191ba4c8923ed8fd8935b7c98658b5f-Paper-Conference.pdf) 47. [singhprakhar/kaiju-samples](https://huggingface.co/datasets/singhprakhar/kaiju-samples) 48. [RealBench — Figshare](https://figshare.com/articles/dataset/RealBench_A_Repo-Level_Code_Generation_Benchmark_Aligned_with_Real-World_Software_Development_Practices/28596638) 49. [RepoZero — arXiv](https://arxiv.org/html/2605.07122v1) 50. [FEA-Bench — HuggingFace Papers](https://huggingface.co/papers/2503.06680) 51. [codefuse-ai/Awesome-Code-LLM](https://github.com/codefuse-ai/Awesome-Code-LLM) 52. [tongye98/Awesome-Code-Benchmark](https://github.com/tongye98/Awesome-Code-Benchmark) 53. [YerbaPage/Awesome-Repo-Level-Code-Generation](https://github.com/YerbaPage/Awesome-Repo-Level-Code-Generation) 54. [allanj/repo-level-codegen-papers](https://github.com/allanj/repo-level-codegen-papers) 55. [dukeluo/awesome-awesome-prompts](https://github.com/dukeluo/awesome-awesome-prompts) 56. [danielrosehill/awesome-llm-prompt-libraries](https://github.com/danielrosehill/awesome-llm-prompt-libraries) 57. [chendongqi/awesome-ai-coding](https://github.com/chendongqi/awesome-ai-coding) 58. [filipecalegario/awesome-vibe-coding](https://github.com/filipecalegario/awesome-vibe-coding) 59. [taskade/awesome-vibe-coding](https://github.com/taskade/awesome-vibe-coding) 60. [saviorand/awesome-ai-assisted-coding](https://github.com/saviorand/awesome-ai-assisted-coding) 61. [DocsBot Game Development Prompts](https://docsbot.ai/prompts/tags?tag=Game%20Development) 62. [9 PRD and Spec Templates Built for AI Coding Agents — SSOJet](https://ssojet.com/blog/prd-spec-templates-ai-agents) 63. [RapidNative AI Prompt Library](https://www.rapidnative.com/blogs/ai-prompt-library)
build-prompts
# BUILD PROMPTS Landscape — Links & Titles ## Ranked Shortlist 1. [github/spec-kit](https://github.com/github/spec-kit) 2. [ai-boost/awesome-prompts](https://github.com/ai-boost/awesome-prompts) 3. [commit-0/commit0](https://github.com/commit-0/commit0) 4. [Fission-AI/OpenSpec](https://github.com/Fission-AI/openspec) 5. [bmad-code-org/BMAD-METHOD](https://github.com/bmad-code-org/bmad-method) 6. [ProjectEval — RyanLoil/ProjectEval](https://github.com/RyanLoil/ProjectEval) 7. [facebookresearch/ProgramBench](https://github.com/facebookresearch/programbench) 8. [Shubhamsaboo/awesome-llm-apps](https://github.com/Shubhamsaboo/awesome-llm-apps) 9. [NL2RepoBench — multimodal-art-projection/NL2RepoBench](https://github.com/multimodal-art-projection/NL2RepoBench) 10. [gsd-build/get-shit-done](https://github.com/gsd-build/get-shit-done) 11. [KhazP/vibe-coding-prompt-template](https://github.com/KhazP/vibe-coding-prompt-template) 12. [TechNomadCode/AI-Product-Development-Toolkit](https://github.com/TechNomadCode/AI-Product-Development-Toolkit) 13. [eyaltoledano/claude-task-master](https://github.com/eyaltoledano/claude-task-master) 14. [nl2code/codes (CodeS)](https://github.com/nl2code/codes) 15. [nurettincoban/ai-prd-workflow](https://github.com/nurettincoban/ai-prd-workflow) 16. [wundercorp/awesome-prompts](https://github.com/wundercorp/awesome-prompts) 17. [bigcode-project/bigcodebench](https://github.com/bigcode-project/bigcodebench) 18. [VoltAgent/awesome-design-md](https://github.com/voltagent/awesome-design-md) 19. [agigante80/vibe-coding-prompts](https://github.com/agigante80/vibe-coding-prompts) 20. [singhprakhar/kaiju-samples](https://huggingface.co/datasets/singhprakhar/kaiju-samples) --- ## Bucket 1 — Frontend / Web Apps - [VoltAgent/awesome-design-md](https://github.com/voltagent/awesome-design-md) - [wundercorp/awesome-prompts](https://github.com/wundercorp/awesome-prompts) - [Bolt.new Mega Prompt](https://gist.github.com/iamnolanhu/d0f6b04cea7b83e36fc83895e1cef7d1) - [langgptai/awesome-claude-prompts](https://github.com/langgptai/awesome-claude-prompts) --- ## Bucket 2 — Fullstack SaaS - [github/spec-kit](https://github.com/github/spec-kit) - [ai-boost/awesome-prompts](https://github.com/ai-boost/awesome-prompts) - [abhiprojectz/SaaS-GPT4-Prompts](https://github.com/abhiprojectz/SaaS-GPT4-Prompts) - [KhazP/vibe-coding-prompt-template](https://github.com/KhazP/vibe-coding-prompt-template) - [TechNomadCode/AI-Product-Development-Toolkit](https://github.com/TechNomadCode/AI-Product-Development-Toolkit) --- ## Bucket 3 — Backend / APIs - [eyaltoledano/claude-task-master](https://github.com/eyaltoledano/claude-task-master) - [agigante80/vibe-coding-prompts](https://github.com/agigante80/vibe-coding-prompts) - [nurettincoban/ai-prd-workflow](https://github.com/nurettincoban/ai-prd-workflow) --- ## Bucket 4 — Data Engineering & Analytics - [ai-boost/awesome-prompts — data_engineer.md](https://github.com/ai-boost/awesome-prompts/blob/main/prompts/data_engineer.md) --- ## Bucket 5 — ML / AI Engineering - [Shubhamsaboo/awesome-llm-apps](https://github.com/Shubhamsaboo/awesome-llm-apps) - [MendoLeo/awesome-llms-apps](https://github.com/MendoLeo/awesome-llms-apps) - [sickn33/agentic-awesome-skills](https://github.com/sickn33/agentic-awesome-skills) - [benchflow-ai/awesome-evals](https://github.com/benchflow-ai/awesome-evals) --- ## Bucket 6 — Android No dedicated link listed. Partial coverage mentioned through: - [ai-boost/awesome-prompts](https://github.com/ai-boost/awesome-prompts) - [sickn33/agentic-awesome-skills](https://github.com/sickn33/agentic-awesome-skills) --- ## Bucket 7 — iOS No dedicated link listed. Partial coverage mentioned through: - [ai-boost/awesome-prompts](https://github.com/ai-boost/awesome-prompts) --- ## Bucket 8 — Cross-Platform Mobile - [machinemindsai/react-native-prompts](https://github.com/machinemindsai/react-native-prompts) - [RapidNative AI Prompt Library](https://www.rapidnative.com/blogs/ai-prompt-library) --- ## Bucket 9 — DevOps / Infra - [agigante80/vibe-coding-prompts](https://github.com/agigante80/vibe-coding-prompts) --- ## Bucket 10 — CLI Tools, Desktop Apps, Browser Extensions - [browser-use/awesome-prompts](https://github.com/browser-use/awesome-prompts) --- ## Bucket 11 — Games, Simulations, Creative Coding - [DocsBot Game Development Prompts](https://docsbot.ai/prompts/tags?tag=Game%20Development) --- ## Bucket 12 — Bots and Automation Workflows - [enescingoz/awesome-n8n-templates](https://github.com/enescingoz/awesome-n8n-templates) - [lucaswalter/n8n-ai-automations](https://github.com/lucaswalter/n8n-ai-automations) - [mergisi/awesome-openclaw-agents](https://github.com/mergisi/awesome-openclaw-agents) --- ## Cross-Domain / Spec-Driven Development Tools - [Fission-AI/OpenSpec](https://github.com/Fission-AI/openspec) - [bmad-code-org/BMAD-METHOD](https://github.com/bmad-code-org/bmad-method) - [gsd-build/get-shit-done](https://github.com/gsd-build/get-shit-done) - [buildermethods/agent-os](https://github.com/buildermethods/agent-os) --- # Benchmark / Dataset Build Prompts - [SWE-bench Verified — HuggingFace](https://huggingface.co/datasets/SWE-bench/SWE-bench_Verified) - [SWE-bench — GitHub](https://github.com/swe-bench/SWE-bench) - [commit-0/commit0 — GitHub](https://github.com/commit-0/commit0) - [commit0/commit0 — HuggingFace](https://huggingface.co/datasets/commit0/commit0) - [ProgramBench — GitHub](https://github.com/facebookresearch/programbench) - [ProgramBench-Tests — HuggingFace](https://huggingface.co/datasets/programbench/ProgramBench-Tests) - [NL2RepoBench — GitHub](https://github.com/multimodal-art-projection/NL2RepoBench) - [ProjectEval — GitHub](https://github.com/RyanLoil/ProjectEval) - [CodeS / SketchEval — GitHub](https://github.com/nl2code/codes) - [BigCodeBench — GitHub](https://github.com/bigcode-project/bigcodebench) - [codeparrot/apps — HuggingFace](https://huggingface.co/datasets/codeparrot/apps) - [hendrycks/apps — GitHub](https://github.com/hendrycks/apps) - [Leolty/repobench — GitHub](https://github.com/Leolty/repobench) - [singhprakhar/kaiju-samples — HuggingFace](https://huggingface.co/datasets/singhprakhar/kaiju-samples) - [RealBench — Figshare](https://figshare.com/articles/dataset/RealBench_A_Repo-Level_Code_Generation_Benchmark_Aligned_with_Real-World_Software_Development_Practices/28596638) - [RepoZero — arXiv](https://arxiv.org/html/2605.07122v1) - [FEA-Bench — HuggingFace Papers](https://huggingface.co/papers/2503.06680) --- # Extraction Appendix — Raw Prompt Locations ## SWE-bench Verified - [SWE-bench/SWE-bench_Verified — HuggingFace](https://huggingface.co/datasets/SWE-bench/SWE-bench_Verified) - [SWE-bench — GitHub](https://github.com/swe-bench/SWE-bench) ## Commit0 - [commit-0/commit0 — GitHub](https://github.com/commit-0/commit0) - [commit0/commit0 — HuggingFace](https://huggingface.co/datasets/commit0/commit0) - [Commit0: Library Generation from Scratch — arXiv](https://arxiv.org/abs/2412.01769) ## ProgramBench - [facebookresearch/ProgramBench — GitHub](https://github.com/facebookresearch/programbench) - [programbench/ProgramBench-Tests — HuggingFace](https://huggingface.co/datasets/programbench/ProgramBench-Tests) - [ProgramBench — arXiv](https://arxiv.org/html/2605.03546v1) ## NL2RepoBench - [multimodal-art-projection/NL2RepoBench — GitHub](https://github.com/multimodal-art-projection/NL2RepoBench) - [NL2Repo-Bench — arXiv](https://arxiv.org/html/2512.12730v1) ## ProjectEval - [RyanLoil/ProjectEval — GitHub](https://github.com/RyanLoil/ProjectEval) - [ProjectEval — ACL Findings 2025](https://aclanthology.org/2025.findings-acl.1036.pdf) ## CodeS / SketchEval - [nl2code/codes — GitHub](https://github.com/nl2code/codes) - [CodeS: NL to Code Repository — ACM TOSEM](https://dl.acm.org/doi/10.1145/3768577) ## BigCodeBench - [bigcode-project/bigcodebench — GitHub](https://github.com/bigcode-project/bigcodebench) - [BigCodeBench Leaderboard](https://bigcode-bench.github.io/) ## APPS - [codeparrot/apps — HuggingFace](https://huggingface.co/datasets/codeparrot/apps) - [hendrycks/apps — GitHub](https://github.com/hendrycks/apps) ## RepoBench - [Leolty/repobench — GitHub](https://github.com/Leolty/repobench) - [RepoBench — ICLR 2024](https://proceedings.iclr.cc/paper_files/paper/2024/file/d191ba4c8923ed8fd8935b7c98658b5f-Paper-Conference.pdf) ## Kaiju - [singhprakhar/kaiju-samples — HuggingFace](https://huggingface.co/datasets/singhprakhar/kaiju-samples) ## RealBench - [RealBench — Figshare](https://figshare.com/articles/dataset/RealBench_A_Repo-Level_Code_Generation_Benchmark_Aligned_with_Real-World_Software_Development_Practices/28596638) ## RepoZero - [RepoZero — arXiv](https://arxiv.org/html/2605.07122v1) ## FEA-Bench - [FEA-Bench — HuggingFace Papers](https://huggingface.co/papers/2503.06680) --- # Meta-Lists and Indexes - [codefuse-ai/Awesome-Code-LLM](https://github.com/codefuse-ai/Awesome-Code-LLM) - [tongye98/Awesome-Code-Benchmark](https://github.com/tongye98/Awesome-Code-Benchmark) - [YerbaPage/Awesome-Repo-Level-Code-Generation](https://github.com/YerbaPage/Awesome-Repo-Level-Code-Generation) - [allanj/repo-level-codegen-papers](https://github.com/allanj/repo-level-codegen-papers) - [dukeluo/awesome-awesome-prompts](https://github.com/dukeluo/awesome-awesome-prompts) - [danielrosehill/awesome-llm-prompt-libraries](https://github.com/danielrosehill/awesome-llm-prompt-libraries) - [chendongqi/awesome-ai-coding](https://github.com/chendongqi/awesome-ai-coding) - [filipecalegario/awesome-vibe-coding](https://github.com/filipecalegario/awesome-vibe-coding) - [taskade/awesome-vibe-coding](https://github.com/taskade/awesome-vibe-coding) - [saviorand/awesome-ai-assisted-coding](https://github.com/saviorand/awesome-ai-assisted-coding) --- # Additional Sources - [GitHub Blog — Spec-driven development with AI](https://github.blog/ai-and-ml/generative-ai/spec-driven-development-with-ai-get-started-with-a-new-open-source-toolkit/) - [9 PRD and Spec Templates Built for AI Coding Agents — SSOJet](https://ssojet.com/blog/prd-spec-templates-ai-agents) - [RapidNative AI Prompt Library](https://www.rapidnative.com/blogs/ai-prompt-library) - [DocsBot Game Development Prompts](https://docsbot.ai/prompts/tags?tag=Game%20Development) --- # Unverified / Excluded Leads Mentioned - `samuxbuilds/awesome-prompts` — excluded; identified as an AI image-generation prompt collection. - `instructa/ai-prompts` — excluded; primarily `.cursorrules` and system prompt files. - `convertscout/awesome-ai-prompts` — excluded; primarily Cursor rules / `.cursorrules`. - `piyushrajyadav/awesome-ai-dev-prompts` — excluded; system prompts for AI coding tools. - [RapidNative AI Prompt Library](https://www.rapidnative.com/blogs/ai-prompt-library) — mentioned as a web-based resource rather than a GitHub raw-prompt repository. - [gsd-build/get-shit-done](https://github.com/gsd-build/get-shit-done) — mentioned as having moved to a new repository. --- # Unique Links From the Original Paste 1. [ai-boost/awesome-prompts](https://github.com/ai-boost/awesome-prompts) 2. [github/spec-kit](https://github.com/github/spec-kit) 3. [GitHub Blog — Spec-driven development with AI](https://github.blog/ai-and-ml/generative-ai/spec-driven-development-with-ai-get-started-with-a-new-open-source-toolkit/) 4. [Fission-AI/OpenSpec](https://github.com/Fission-AI/openspec) 5. [bmad-code-org/BMAD-METHOD](https://github.com/bmad-code-org/bmad-method) 6. [gsd-build/get-shit-done](https://github.com/gsd-build/get-shit-done) 7. [eyaltoledano/claude-task-master](https://github.com/eyaltoledano/claude-task-master) 8. [buildermethods/agent-os](https://github.com/buildermethods/agent-os) 9. [KhazP/vibe-coding-prompt-template](https://github.com/KhazP/vibe-coding-prompt-template) 10. [TechNomadCode/AI-Product-Development-Toolkit](https://github.com/TechNomadCode/AI-Product-Development-Toolkit) 11. [nurettincoban/ai-prd-workflow](https://github.com/nurettincoban/ai-prd-workflow) 12. [agigante80/vibe-coding-prompts](https://github.com/agigante80/vibe-coding-prompts) 13. [wundercorp/awesome-prompts](https://github.com/wundercorp/awesome-prompts) 14. [abhiprojectz/SaaS-GPT4-Prompts](https://github.com/abhiprojectz/SaaS-GPT4-Prompts) 15. [Bolt.new Mega Prompt](https://gist.github.com/iamnolanhu/d0f6b04cea7b83e36fc83895e1cef7d1) 16. [machinemindsai/react-native-prompts](https://github.com/machinemindsai/react-native-prompts) 17. [langgptai/awesome-claude-prompts](https://github.com/langgptai/awesome-claude-prompts) 18. [Shubhamsaboo/awesome-llm-apps](https://github.com/Shubhamsaboo/awesome-llm-apps) 19. [MendoLeo/awesome-llms-apps](https://github.com/MendoLeo/awesome-llms-apps) 20. [VoltAgent/awesome-design-md](https://github.com/voltagent/awesome-design-md) 21. [browser-use/awesome-prompts](https://github.com/browser-use/awesome-prompts) 22. [enescingoz/awesome-n8n-templates](https://github.com/enescingoz/awesome-n8n-templates) 23. [mergisi/awesome-openclaw-agents](https://github.com/mergisi/awesome-openclaw-agents) 24. [lucaswalter/n8n-ai-automations](https://github.com/lucaswalter/n8n-ai-automations) 25. [sickn33/agentic-awesome-skills](https://github.com/sickn33/agentic-awesome-skills) 26. [benchflow-ai/awesome-evals](https://github.com/benchflow-ai/awesome-evals) 27. [SWE-bench Verified — HuggingFace](https://huggingface.co/datasets/SWE-bench/SWE-bench_Verified) 28. [SWE-bench — GitHub](https://github.com/swe-bench/SWE-bench) 29. [commit-0/commit0 — GitHub](https://github.com/commit-0/commit0) 30. [commit0/commit0 — HuggingFace](https://huggingface.co/datasets/commit0/commit0) 31. [Commit0 — arXiv](https://arxiv.org/abs/2412.01769) 32. [ProgramBench — GitHub](https://github.com/facebookresearch/programbench) 33. [ProgramBench-Tests — HuggingFace](https://huggingface.co/datasets/programbench/ProgramBench-Tests) 34. [ProgramBench — arXiv](https://arxiv.org/html/2605.03546v1) 35. [NL2RepoBench — GitHub](https://github.com/multimodal-art-projection/NL2RepoBench) 36. [NL2Repo-Bench — arXiv](https://arxiv.org/html/2512.12730v1) 37. [ProjectEval — GitHub](https://github.com/RyanLoil/ProjectEval) 38. [ProjectEval — ACL](https://aclanthology.org/2025.findings-acl.1036.pdf) 39. [nl2code/codes — GitHub](https://github.com/nl2code/codes) 40. [CodeS — ACM TOSEM](https://dl.acm.org/doi/10.1145/3768577) 41. [bigcode-project/bigcodebench](https://github.com/bigcode-project/bigcodebench) 42. [BigCodeBench Leaderboard](https://bigcode-bench.github.io/) 43. [codeparrot/apps — HuggingFace](https://huggingface.co/datasets/codeparrot/apps) 44. [hendrycks/apps — GitHub](https://github.com/hendrycks/apps) 45. [Leolty/repobench](https://github.com/Leolty/repobench) 46. [RepoBench — ICLR](https://proceedings.iclr.cc/paper_files/paper/2024/file/d191ba4c8923ed8fd8935b7c98658b5f-Paper-Conference.pdf) 47. [singhprakhar/kaiju-samples](https://huggingface.co/datasets/singhprakhar/kaiju-samples) 48. [RealBench — Figshare](https://figshare.com/articles/dataset/RealBench_A_Repo-Level_Code_Generation_Benchmark_Aligned_with_Real-World_Software_Development_Practices/28596638) 49. [RepoZero — arXiv](https://arxiv.org/html/2605.07122v1) 50. [FEA-Bench — HuggingFace Papers](https://huggingface.co/papers/2503.06680) 51. [codefuse-ai/Awesome-Code-LLM](https://github.com/codefuse-ai/Awesome-Code-LLM) 52. [tongye98/Awesome-Code-Benchmark](https://github.com/tongye98/Awesome-Code-Benchmark) 53. [YerbaPage/Awesome-Repo-Level-Code-Generation](https://github.com/YerbaPage/Awesome-Repo-Level-Code-Generation) 54. [allanj/repo-level-codegen-papers](https://github.com/allanj/repo-level-codegen-papers) 55. [dukeluo/awesome-awesome-prompts](https://github.com/dukeluo/awesome-awesome-prompts) 56. [danielrosehill/awesome-llm-prompt-libraries](https://github.com/danielrosehill/awesome-llm-prompt-libraries) 57. [chendongqi/awesome-ai-coding](https://github.com/chendongqi/awesome-ai-coding) 58. [filipecalegario/awesome-vibe-coding](https://github.com/filipecalegario/awesome-vibe-coding) 59. [taskade/awesome-vibe-coding](https://github.com/taskade/awesome-vibe-coding) 60. [saviorand/awesome-ai-assisted-coding](https://github.com/saviorand/awesome-ai-assisted-coding) 61. [DocsBot Game Development Prompts](https://docsbot.ai/prompts/tags?tag=Game%20Development) 62. [9 PRD and Spec Templates Built for AI Coding Agents — SSOJet](https://ssojet.com/blog/prd-spec-templates-ai-agents) 63. [RapidNative AI Prompt Library](https://www.rapidnative.com/blogs/ai-prompt-library)
app-store-generator
# App Store Screenshots Gallery Generator **Create a professional, production-ready screenshots gallery for an iOS/macOS/Android app that looks like it was designed by the top 1% of app developers.** ## Context You are building a screenshots gallery page for an app. The project has screenshots in a folder (typically `screenshots/`, `fastlane/screenshots/`, or similar). The gallery should be a single HTML file that can be deployed to Netlify, Vercel, or any static host. ## Requirements ### 1. Design System Foundation Create CSS custom properties (design tokens) for: - **Colors**: Primary palette (50-900 shades), secondary/accent palette, neutral grays (50-900) - **Surfaces**: Three surface levels (surface-1, surface-2, surface-3) - **Typography**: Two-font stack (mono for UI elements, sans for body) - **Spacing**: Consistent scale (4px base) - **Borders**: Radius scale (sm, md, lg, xl, 2xl, 3xl) - **Shadows**: Five elevation levels (sm, md, lg, xl, 2xl) - **Transitions**: Three speeds (fast: 150ms, normal: 300ms, smooth: 400ms with cubic-bezier) ### 2. Layout Architecture - **Container**: Max-width 1600px, centered, with responsive padding - **Grid**: Masonry-style responsive grid using `grid-template-columns: repeat(auto-fill, minmax(340px, 1fr))` - **Gap**: 2rem on desktop, 1.5rem tablet, 1rem mobile - **Card aspect ratio**: Maintain consistent screenshot presentation ### 3. Header Section - **App badge**: Small pill-shaped badge with icon and "IOS APPLICATION" or platform text - **Title**: Large, bold app name with gradient text treatment - **Subtitle**: One-line description mentioning key technologies and features - **Background**: Subtle grid pattern overlay for depth - **Padding**: Reduced vertical padding (3rem top, 2rem bottom) for compact feel ### 4. Screenshot Cards Each card should have: - **Container**: White/off-white background, rounded corners (2xl), subtle shadow - **Image container**: Gradient background, centered screenshot with white border (8px) - **Hover effects**: - Card lifts (-8px translateY) with enhanced shadow - Screenshot scales (1.04) with slight rotation (0.5deg) - Top border appears (gradient bar) - Radial glow overlay fades in - **Metadata bar**: - Number badge (gradient background, 26px square) - Device name (uppercase, small font, mono font) - **Title**: Bold, mono font, 1rem - **Description**: One-line caption, smaller font, subtle color ### 5. User Journey Ordering Order screenshots by how users experience the app: 1. **Login/Onboarding** - First screen users see 2. **Dashboard/Home** - Main landing after login 3. **Primary feature views** - Core app functionality 4. **Settings/Configuration** - Customization screens 5. **Permissions/Integrations** - HealthKit, notifications, etc. 6. **Advanced features** - Sync, sharing, cloud features 7. **Analytics/Reports** - Data visualization screens 8. **Archive/History** - Historical data views ### 6. Animations - **Entrance**: Staggered fade-in with translateY (0.1s delays between cards) - **Hover**: Smooth cubic-bezier easing (0.16, 1, 0.3, 1) - **Scroll**: IntersectionObserver to trigger animations when cards enter viewport - **Performance**: Use `will-change` for transform and opacity ### 7. Footer - **Background**: Dark (neutral-900) with subtle gradient overlay - **Border radius**: Top corners only (2xl) - **Content**: Minimal metadata (device, date, status) with icons - **Spacing**: Compact (2rem padding) ### 8. Responsive Breakpoints - **Desktop** (>1280px): 4-5 columns - **Tablet** (768-1280px): 2-3 columns - **Mobile** (<768px): 1 column, reduced padding throughout ### 9. Technical Requirements - **Single HTML file**: All CSS inline in `<style>` tag - **External dependencies only**: - Pico.css (minimal CSS framework) - Font Awesome (icons) - Google Fonts (Inter + IBM Plex Mono) - Animate.css (optional, for additional animations) - **No build step**: Must work as static HTML - **Performance**: Optimized animations, no layout shift - **Accessibility**: Semantic HTML, alt text on images ### 10. Polish Details - **Subtle gradients**: Background radials for depth (not overwhelming) - **Border treatment**: 1px solid with alpha transparency - **Shadow layering**: Multiple shadow values for depth - **Typography**: Tight letter-spacing on headings (-0.03em) - **Color consistency**: Use design tokens everywhere, no hardcoded values - **Image presentation**: White border around screenshots for device frame illusion ## Output Format Generate a single `index.html` file with: 1. Complete HTML structure 2. Inline CSS with design tokens 3. JavaScript for scroll animations (IntersectionObserver) 4. All screenshot cards with proper metadata 5. Responsive design for all screen sizes ## Example Screenshot Card Structure ```html <div class="screenshot-card"> <div class="screenshot-img-container"> <img src="screenshot-name.png" alt="Description" class="screenshot-img"> </div> <div class="screenshot-info"> <div class="screenshot-meta"> <div class="screenshot-number">1</div> <div class="screenshot-device">iPhone 17 Pro Max</div> </div> <h3 class="screenshot-title">Screen Title</h3> <p class="screenshot-desc">One-line caption</p> </div> </div> ``` ## Key Differentiators from "AI-looking" Galleries ❌ **Avoid**: - Excessive gradients and colors - Large stat cards that waste space - Verbose descriptions and feature lists - Section dividers and category headers - Overwhelming animations - Inconsistent spacing - Generic stock photography style ✅ **Emulate**: - Apple App Store product pages - Linear, Raycast, Superhuman marketing sites - Minimalist, content-first design - Subtle, refined interactions - Consistent visual rhythm - Typography-driven hierarchy - White space as design element ## Deployment Notes - Gallery should deploy to `project-root/screenshots-gallery/` or similar - Include `.netlify` folder with `netlify.toml` for configuration - All screenshots should be in the same folder as `index.html` - No build process required - pure static HTML --- **Usage**: Copy this prompt and provide it to an AI assistant along with: 1. The list of screenshot files in your project 2. Your app name and one-line description 3. The platform (iOS, macOS, Android, web) 4. Key technologies used (SwiftUI, React Native, Flutter, etc.) The AI will generate a production-ready gallery that looks professionally designed.
multi-tenant-platforms
# Headless / API-First Platforms The most-starred open-source e-commerce platforms on GitHub are **Medusa (~35k)**, **Bagisto (~26.5k)**, **Saleor (~21.8k)**, and **Spree (~15.3k)**, spanning a range from headless/API-first architectures (Medusa, Saleor, Vendure) to traditional monolithic platforms (Magento, PrestaShop, OpenCart, nopCommerce), with most offering native multi-store/multi-tenant capabilities and storefront APIs. --- ## Tier 1 — Highest-Starred Platforms (15k+ Stars) ### 1. Medusa — medusajs/medusa - **GitHub:** [github.com/medusajs/medusa](https://github.com/medusajs/medusa) - **Stars:** ~35,000 (the #1 most-starred e-commerce platform on GitHub; first to cross 30k) - **Tech Stack:** Node.js / TypeScript - **Architecture:** Headless, modular commerce framework - **Multi-Tenant:** Ships with a **Store Module** that enables managing multiple stores within a single backend instance. Native multi-tenancy is evolving — the `createStoresWorkflow` supports multi-tenant and marketplace setups. - **Storefront API:** Yes — REST and GraphQL APIs; ships with a production-ready Next.js storefront starter. - **License:** MIT ### 2. Bagisto — bagisto/bagisto - **GitHub:** [github.com/bagisto/bagisto](https://github.com/bagisto/bagisto) - **Stars:** ~26,500 (growing rapidly; crossed 25k in 2025) - **Tech Stack:** Laravel (PHP) + Vue.js - **Architecture:** Modular monolith with headless option - **Multi-Tenant:** Yes — dedicated **Multi-Tenant SaaS Module** for building multi-store platforms from a single installation; also supports multi-vendor marketplaces. - **Storefront API:** Yes — REST API and GraphQL API (headless package available separately). - **License:** MIT ### 3. Saleor — saleor/saleor - **GitHub:** [github.com/saleor/saleor](https://github.com/saleor/saleor) - **Stars:** ~21,800 - **Tech Stack:** Python / Django / GraphQL / PostgreSQL - **Architecture:** Headless, API-first (MACH-aligned) - **Multi-Tenant:** Multi-channel and multi-storefront built in — a single backend instance supports multi-currency, multi-regional, and multi-language storefronts. Full multi-tenancy is available via Saleor Cloud (SaaS tier). - **Storefront API:** Yes — **GraphQL-native**; one unified API for storefront, admin, webhooks, and extensions. Ships with React/Next.js dashboard and storefront. - **License:** BSD-3-Clause ### 4. Spree Commerce — spree/spree - **GitHub:** [github.com/spree/spree](https://github.com/spree/spree) - **Stars:** ~15,300 (crossed 15k in October 2025) - **Tech Stack:** Ruby on Rails - **Architecture:** Headless (decoupled storefront since v5.x); historically monolithic - **Multi-Tenant:** Yes — dedicated **Multi-Tenant module** in the Enterprise tier; supports hosting hundreds of independent stores from one dashboard with per-store theming and white-label capabilities. - **Storefront API:** Yes — full **REST API** + TypeScript SDK + production-ready Next.js storefront. Supports multi-vendor marketplaces with vendor accounts and split payments. - **License:** BSD-3-Clause --- ## Tier 2 — Major Platforms (8k–15k Stars) ### 5. Magento Open Source (Adobe Commerce) — magento/magento2 - **GitHub:** [github.com/magento/magento2](https://github.com/magento/magento2) - **Stars:** ~12,100 - **Tech Stack:** PHP (Zend/Symfony components) - **Architecture:** **Monolithic** with modular extension system; the most feature-rich traditional platform - **Multi-Tenant:** Yes — native **multi-store/multi-website** architecture; manage multiple storefronts, each with independent catalogs, pricing, and themes from one installation. - **Storefront API:** Yes — both **REST and GraphQL** APIs (GraphQL since v2.3); headless PWA storefronts supported. - **License:** OSL-3.0 ### 6. Reaction Commerce — reactioncommerce/reaction - **GitHub:** [github.com/reactioncommerce/reaction](https://github.com/reactioncommerce/reaction) - **Stars:** ~12,400 - **Tech Stack:** Node.js / React / GraphQL - **Architecture:** Headless, API-first (microservices via Docker/Kubernetes) - **Multi-Tenant:** Supported multi-shop configurations - **Storefront API:** Yes — GraphQL API - **⚠️ Status:** **DISCONTINUED** (project archived by Mailchimp). Listed here for historical reference only — not recommended for new projects. - **License:** GPL-3.0 ### 7. WooCommerce — woocommerce/woocommerce - **GitHub:** [github.com/woocommerce/woocommerce](https://github.com/woocommerce/woocommerce) - **Stars:** ~10,300 - **Tech Stack:** PHP / WordPress - **Architecture:** **Monolithic** (WordPress plugin); headless mode available via Store API - **Multi-Tenant:** Via **WordPress Multisite** (each subsite = independent store); also supports multi-vendor via extensions. - **Storefront API:** Yes — **WooCommerce Store API** (REST) for headless React/Next.js frontends; also traditional REST API. - **License:** GPL-3.0 ### 8. nopCommerce — nopSolutions/nopCommerce - **GitHub:** [github.com/nopSolutions/nopCommerce](https://github.com/nopSolutions/nopCommerce) - **Stars:** ~10,000+ (crossed 10k in mid-2024) - **Tech Stack:** ASP.NET Core / .NET - **Architecture:** Modular monolith - **Multi-Tenant:** Yes — native **multi-store** support; manage multiple stores with shared or separate catalogs from one installation. - **Storefront API:** Yes — REST API available; headless frontends supported. - **License:** nopCommerce Public License (source-available, free to use) ### 9. PrestaShop — PrestaShop/PrestaShop - **GitHub:** [github.com/PrestaShop/PrestaShop](https://github.com/PrestaShop/PrestaShop) - **Stars:** ~9,100 - **Tech Stack:** PHP (Symfony components since v1.7+) - **Architecture:** **Monolithic**; PrestaShop 9 (released 2025) added headless/API improvements - **Multi-Tenant:** Yes — native **Multistore** feature; configure different stores with independent product catalogs, themes, and domains. - **Storefront API:** Yes — REST API (Webservice); headless storefront support expanding in v9. - **License:** OSL-3.0 ### 10. OpenCart — opencart/opencart - **GitHub:** [github.com/opencart/opencart](https://github.com/opencart/opencart) - **Stars:** ~8,200 - **Tech Stack:** PHP - **Architecture:** **Monolithic** (MVC) - **Multi-Tenant:** Yes — native **multi-store** support; manage multiple stores from one admin panel with shared or independent settings. - **Storefront API:** Yes — REST API available via the API extension. - **License:** GPL-3.0 ### 11. Sylius — sylius/sylius - **GitHub:** [github.com/sylius/sylius](https://github.com/sylius/sylius) - **Stars:** ~8,500 - **Tech Stack:** PHP / Symfony / API Platform - **Architecture:** Headless framework (modular components); domain-driven design - **Multi-Tenant:** Multi-channel support; advanced **multi-store management** available in Sylius Plus (commercial tier). Open-source core supports multi-channel catalogs and locales. - **Storefront API:** Yes — **API Platform** (REST + GraphQL); fully headless with decoupled storefronts. - **License:** MIT ### 12. Vendure — vendurehq/vendure - **GitHub:** [github.com/vendurehq/vendure](https://github.com/vendurehq/vendure) - **Stars:** ~7,000–8,000 (6.9k as of Dec 2025 per independent ranking; ~8k per comparison aggregators) - **Tech Stack:** TypeScript / Node.js / NestJS / GraphQL - **Architecture:** Headless, API-first framework - **Multi-Tenant:** Yes — native **Channels** feature allows running multiple shops or a marketplace from one Vendure instance. Admin-configurable per-tenant roles, storefronts, and catalogs without code. A MultivendorPlugin supports marketplace setups. - **Storefront API:** Yes — **GraphQL** API; starter storefronts available in Angular, Next.js, and others. - **License:** MIT --- ## Tier 3 — Notable Mentions & Storefront Frameworks ### Shopify Hydrogen — shopify/hydrogen - **GitHub:** [github.com/shopify/hydrogen](https://github.com/shopify/hydrogen) - **Stars:** ~1,200+ - **Tech Stack:** React / Remix (now React Router 7) / Vite - **Architecture:** Open-source **storefront framework only** — requires Shopify's proprietary backend (Storefront API). Not a self-hosted commerce platform. - **Storefront API:** Yes — built specifically to consume the **Shopify Storefront API**. - **License:** MIT ### Vercel Commerce (Next.js Commerce) - **GitHub:** [github.com/vercel/commerce](https://github.com/vercel/commerce) - **Stars:** ~12,000+ - **Architecture:** Next.js storefront template/demo (not a full backend commerce platform); integrates with Shopify, Saleor, Spree, Swell, etc. --- ## Summary Comparison Table | # | Platform | GitHub Repo | Stars (~) | Architecture | Multi-Tenant | Storefront API | License | |---|----------|-------------|-----------|--------------|-------------|----------------|---------| | 1 | **Medusa** | [medusajs/medusa](https://github.com/medusajs/medusa) | 35k | Headless / Modular | Store Module | REST + GraphQL | MIT | | 2 | **Bagisto** | [bagisto/bagisto](https://github.com/bagisto/bagisto) | 26.5k | Modular Monolith + Headless | Multi-Tenant SaaS Module | REST + GraphQL | MIT | | 3 | **Saleor** | [saleor/saleor](https://github.com/saleor/saleor) | 21.8k | Headless / API-first | Multi-channel / Multi-storefront | GraphQL | BSD-3 | | 4 | **Spree** | [spree/spree](https://github.com/spree/spree) | 15.3k | Headless | Multi-Tenant Module (Enterprise) | REST + TS SDK | BSD-3 | | 5 | **Magento** | [magento/magento2](https://github.com/magento/magento2) | 12.1k | Monolithic | Native Multi-store | REST + GraphQL | OSL-3.0 | | 6 | **Reaction** ⚠️ | [reactioncommerce/reaction](https://github.com/reactioncommerce/reaction) | 12.4k | Headless | Multi-shop | GraphQL | GPL-3.0 | | 7 | **WooCommerce** | [woocommerce/woocommerce](https://github.com/woocommerce/woocommerce) | 10.3k | Monolithic (WP plugin) | WordPress Multisite | Store API (REST) | GPL-3.0 | | 8 | **nopCommerce** | [nopSolutions/nopCommerce](https://github.com/nopSolutions/nopCommerce) | 10k+ | Modular Monolith | Native Multi-store | REST | Source-available | | 9 | **PrestaShop** | [PrestaShop/PrestaShop](https://github.com/PrestaShop/PrestaShop) | 9.1k | Monolithic | Native Multistore | REST (Webservice) | OSL-3.0 | | 10 | **Sylius** | [sylius/sylius](https://github.com/sylius/sylius) | 8.5k | Headless Framework | Multi-channel (Plus: Multi-store) | REST + GraphQL | MIT | | 11 | **OpenCart** | [opencart/opencart](https://github.com/opencart/opencart) | 8.2k | Monolithic | Native Multi-store | REST | GPL-3.0 | | 12 | **Vendure** | [vendurehq/vendure](https://github.com/vendurehq/vendure) | 7–8k | Headless / API-first | Native Channels | GraphQL | MIT | --- ## Key Architectural Distinctions ### Headless / API-First Platforms **Medusa, Saleor, Vendure, Sylius, and Spree (v5+)** decouple the commerce backend from the storefront entirely. Every feature is exposed through APIs (GraphQL and/or REST), and you build or plug in any frontend (Next.js, React, mobile apps). These are the strongest fit for multi-tenant SaaS deployments where each tenant needs a custom or white-labeled storefront hitting the same backend. ### Monolithic Platforms **Magento, WooCommerce, PrestaShop, OpenCart, and nopCommerce** bundle backend + admin + storefront rendering in one codebase. They all support multi-store configurations natively (multiple storefronts from one installation), and most now offer REST/GraphQL APIs for headless use, though the primary experience remains the built-in storefront. Bagisto sits between these two camps — it is a Laravel modular monolith that also ships headless APIs. ### Multi-Tenancy Maturity - **Strongest native multi-tenancy:** Vendure (Channels), Bagisto (Multi-Tenant SaaS Module), Spree (Enterprise Multi-Tenant Module) - **Multi-store/multi-channel (near-tenant):** Saleor (multi-channel/multi-storefront), Magento (multi-website), nopCommerce (multi-store), PrestaShop (multistore), OpenCart (multi-store) - **Evolving:** Medusa (Store Module enables multi-store; full tenant isolation via PostgreSQL RLS patterns) --- ## Sources - [Medusa GitHub Repository](https://github.com/medusajs/medusa) - [Medusa — Store Module Documentation](https://docs.medusajs.com/resources/commerce-modules/store) - [Medusa Multi-Tenant Blog Post](https://medusajs.com/blog/multi-tenant-rigby/) - [Medusa 30k Stars Announcement (X/Twitter)](https://x.com/medusajs/status/1950114208982642878) - [Bagisto GitHub Repository](https://github.com/bagisto/bagisto) - [Bagisto Star History (star-history.com)](https://www.star-history.com/bagisto/bagisto) - [Bagisto OSSInsight Analytics](https://ossinsight.io/analyze/bagisto/bagisto) - [Bagisto Multi-Tenant SaaS Module](https://bagisto.com/en/laravel-multi-tenant-saas/) - [Bagisto Headless eCommerce](https://bagisto.com/en/headless-ecommerce/) - [Saleor GitHub Repository](https://github.com/saleor/saleor) - [Saleor Open Source Page (21.8k stars)](https://saleor.io/open-source) - [Saleor Multi-Channel Commerce](https://saleor.io/solutions/multi-channel-commerce) - [Spree Commerce GitHub Repository](https://github.com/spree/spree) - [Spree Commerce 15,000 GitHub Stars](https://spreecommerce.org/spree-commerce-open-source-15000-github-stars/) - [Spree Multi-Tenant eCommerce](https://spreecommerce.org/multi-tenant-white-label-ecommerce/) - [Magento Open Source GitHub Repository](https://github.com/magento/magento2) - [Magento Organization Star Ranking (GitStarClub)](https://gitstarclub.com/o/magento) - [WooCommerce GitHub Repository](https://github.com/woocommerce/woocommerce) - [WooCommerce Star History (GitStarClub)](https://gitstarclub.com/woocommerce/woocommerce) - [nopCommerce GitHub Repository](https://github.com/nopSolutions/nopCommerce) - [nopCommerce Star History (GitStarClub)](https://gitstarclub.com/nopSolutions/nopCommerce) - [PrestaShop GitHub Repository](https://github.com/PrestaShop/PrestaShop) - [OpenCart GitHub Repository](https://github.com/opencart/opencart) - [OpenCart Star History (star-history.com)](https://www.star-history.com/opencart/opencart) - [Sylius GitHub Repository](https://github.com/sylius/sylius) - [Sylius Star History (star-history.com)](https://www.star-history.com/sylius/sylius) - [Vendure GitHub Repository](https://github.com/vendurehq/vendure) - [Multi-Tenant Commerce with Vendure](https://vendure.io/blog/multi-tenant-commerce-with-vendure) - [Reaction Commerce GitHub (Discontinued)](https://github.com/reactioncommerce/reaction) - [Shopify Hydrogen GitHub Repository](https://github.com/shopify/hydrogen) - [Top 20 Open-Source E-Commerce Platforms on GitHub (florinelchis, Medium)](https://florinelchis.medium.com/top-20-open-source-e-commerce-platforms-on-github-by-stars-c812d4c85917) - [Top 20 Open Source Ecommerce Platforms (Magendoo)](https://magendoo.ro/insights/top-20-open-source-ecommerce-platforms-on-github-a-strategic-analysis-2026/) - [Open-source eCommerce Platforms and their GitHub stars (Spree)](https://spreecommerce.org/open-source-ecommerce-platforms-and-their-github-stars/) - [Bagisto — Top 11 Open Source eCommerce Platforms on GitHub](https://bagisto.com/en/open-source-ecommerce-github/) - [Spree vs Vendure Comparison (OpenAlternative)](https://openalternative.co/compare/spree-commerce/vs/vendure) - [Saleor vs Shopify (Saleor)](https://saleor.io/shopify-alternative) - [Vendure vs Spree (LibHunt)](https://www.libhunt.com/compare-vendure-vs-spree)
telegram-notification-setup
# Telegram Notifications — Integration Context A reference for sending notification messages to a Telegram chat via a bot. This document is the single source of truth: an agent should be able to wire up notifications using only the endpoint, parameters, formatting rules, and message recipes below. > **How to use this:** Read the two secrets (`TELEGRAM_BOT_TOKEN`, `TELEGRAM_ALLOWED_CHAT_ID`) from configuration — they are provided separately and must never be hardcoded or logged. Build every request from the documented parameter set and reuse the message recipes rather than inventing new shapes. --- ## 1. Foundations ### 1.1 What this does A Telegram bot can push messages into a chat (a user, group, or channel) over a plain HTTPS API. There is no SDK requirement — every action is an HTTPS request. For notifications, the only method needed is `sendMessage`. ### 1.2 Secrets (supplied separately) | Name | Meaning | Source | |---|---|---| | `TELEGRAM_BOT_TOKEN` | Bot auth token from BotFather. Forms part of the URL path. | Provided out-of-band | | `TELEGRAM_ALLOWED_CHAT_ID` | Destination chat ID the bot is allowed to message. | Provided out-of-band | - Treat both as secrets. Load from environment variables or a secrets manager. - Never commit them, never echo them in logs, never include them in error messages. - A user must have started a conversation with the bot (or added it to the group) at least once before the bot can message them. ### 1.3 Base endpoint ``` POST https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/sendMessage Content-Type: application/json ``` The token is concatenated directly after `bot` in the path. The body is JSON. --- ## 2. Request contract ### 2.1 Core parameters (`sendMessage`) | Field | Type | Required | Use | |---|---|---|---| | `chat_id` | string/int | yes | Destination. Use `TELEGRAM_ALLOWED_CHAT_ID`. | | `text` | string | yes | Message body. Max **4096** characters. | | `parse_mode` | string | no | `HTML`, `MarkdownV2`, or `Markdown` (legacy). Omit for plain text. | | `disable_notification` | bool | no | `true` = deliver silently (no sound/vibration). | | `protect_content` | bool | no | `true` = recipient cannot forward or save. | | `link_preview_options` | object | no | `{ "is_disabled": true }` to suppress URL preview cards. | | `reply_markup` | object | no | Attach inline buttons (see 4.5). | | `message_thread_id` | int | no | Target a specific topic in a forum/group. | | `reply_parameters` | object | no | `{ "message_id": <id> }` to reply to a prior message. | ### 2.2 Response On success Telegram returns `{ "ok": true, "result": { ... } }` where `result` is the sent Message (contains `message_id`). On failure: `{ "ok": false, "error_code": <int>, "description": "<reason>" }`. ### 2.3 Verifying setup `GET https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/getMe` returns the bot identity if the token is valid. Run this once at startup as a health check before sending notifications. --- ## 3. Formatting Pick **one** `parse_mode`. If you set one, unescaped reserved characters will cause a `400 Bad Request`. ### 3.1 HTML (recommended default) Simplest to generate safely. Supported tags: `<b>`, `<i>`, `<u>`, `<s>`, `<code>`, `<pre>`, `<a href="...">`, `<blockquote>`. - Escape these in any dynamic text: `&` → `&`, `<` → `<`, `>` → `>`. ### 3.2 MarkdownV2 Stricter. These characters must be backslash-escaped **everywhere** they appear literally: ``` _ * [ ] ( ) ~ ` > # + - = | { } . ! ``` Prefer HTML unless MarkdownV2 is specifically required — it is easy to break with un-escaped punctuation. ### 3.3 Plain text Omit `parse_mode` entirely. No escaping needed. Use this when the message contains arbitrary/user content you cannot guarantee is safe to format. --- ## 4. Message recipes Compose notifications from these patterns. All examples use `HTML` parse mode unless noted. **Status prefix convention** — lead messages with the matching indicator: 🟢 success · 🟡 alert · 🔴 error. ### 4.1 Plain notification ```json { "chat_id": "<TELEGRAM_ALLOWED_CHAT_ID>", "text": "Task completed successfully." } ``` ### 4.2 Success summary (structured) ```json { "chat_id": "<TELEGRAM_ALLOWED_CHAT_ID>", "parse_mode": "HTML", "text": "🟢 <b>Backup completed</b>\n\n<b>Host:</b> db-01\n<b>Size:</b> 4.2 GB\n<b>Duration:</b> 38s" } ``` ### 4.3 Alert / failure with detail ```json { "chat_id": "<TELEGRAM_ALLOWED_CHAT_ID>", "parse_mode": "HTML", "text": "🟡 <b>Alert</b>\n<i>Service:</i> api-gateway\n<i>Status:</i> <u>DOWN</u>" } ``` ### 4.4 Error with stack trace ```json { "chat_id": "<TELEGRAM_ALLOWED_CHAT_ID>", "parse_mode": "HTML", "text": "🔴 <b>Job failed</b>\n<pre>ValueError: invalid payload</pre>" } ``` ### 4.5 Notification with action button ```json { "chat_id": "<TELEGRAM_ALLOWED_CHAT_ID>", "text": "Deployment requires approval.", "reply_markup": { "inline_keyboard": [[ { "text": "View build", "url": "https://ci.example.com/build/1423" } ]] } } ``` ### 4.6 Silent / low-priority ```json { "chat_id": "<TELEGRAM_ALLOWED_CHAT_ID>", "text": "Nightly job finished.", "disable_notification": true } ``` ### 4.7 Sensitive (no forward/save) ```json { "chat_id": "<TELEGRAM_ALLOWED_CHAT_ID>", "text": "One-time code: 4827. Do not share.", "protect_content": true } ``` ### 4.8 Link without preview card ```json { "chat_id": "<TELEGRAM_ALLOWED_CHAT_ID>", "text": "New PR: https://github.com/org/repo/pull/123", "link_preview_options": { "is_disabled": true } } ``` --- ## 5. Operational rules ### 5.1 Limits | Constraint | Value | |---|---| | Message text length | 4096 characters (split longer messages) | | Per-chat send rate | ~1 message/second sustained | | Global send rate | ~30 messages/second across all chats | | Same group/channel | ~20 messages/minute | Exceeding limits returns `429 Too Many Requests` with a `parameters.retry_after` (seconds) value. ### 5.2 Error handling - Inspect `ok`. On `false`, read `error_code` + `description`. - On `429`, wait `parameters.retry_after` seconds, then retry once. - `400` usually means malformed `text`/formatting — most often an unescaped character under a `parse_mode`. Fall back to plain text if formatting fails. - `403` means the bot was blocked by the user or removed from the chat — do not retry. - Use a short timeout (e.g. 10s) and treat network failures as non-fatal for notifications. ### 5.3 Allowed-chat guard Send only to `TELEGRAM_ALLOWED_CHAT_ID`. If the integration receives or derives any other chat ID, reject it rather than messaging an unintended recipient. --- ## 6. Usage rules - Read `TELEGRAM_BOT_TOKEN` and `TELEGRAM_ALLOWED_CHAT_ID` from config; never hardcode or log them. - Use `getMe` as a startup health check before sending. - Default to `parse_mode: HTML`; escape `& < >` in all dynamic content; fall back to plain text on a formatting `400`. - Keep messages under 4096 chars; split or summarize longer payloads. - Respect rate limits; honor `retry_after` on `429`. - Use `disable_notification` for low-priority events and `protect_content` for sensitive ones. - Treat `403` as a permanent stop for that chat; never retry it.
spark-design-system
# Spark Dark — Design System A dark-theme design system for building UIs. Electric-violet accent, deep near-black surfaces, subtle grid texture, humanist sans for content and monospace for metadata. This document is the single source of truth: an agent should be able to build any interface using only the tokens, scales, and component patterns below. > **How to use this:** Reference tokens by their CSS variable name (e.g. `--spark-accent`), never raw hex, when generating components. Reuse the documented component patterns and layout rules rather than inventing new values. --- ## 1. Foundations ### 1.1 Color tokens Exposed as CSS custom properties on `:root`. **Surfaces** (darkest → lightest — this is the elevation ladder) | Token | Value | Use | |---|---|---| | `--spark-bg-root` | `#08090c` | Page background | | `--spark-bg-input` | `#0d0f16` | Input / textarea fields | | `--spark-bg-panel` | `#10121a` | Panels and shells | | `--spark-bg-card` | `#161926` | Cards, chips | | `--spark-bg-elevated` | `#1c2033` | Raised elements | | `--spark-bg-hover` | `#1f2340` | Hover state for raised elements | **Borders** | Token | Value | Use | |---|---|---| | `--spark-border` | `rgba(255,255,255,0.06)` | Default hairline border on containers | | `--spark-border-focus` | `rgba(120,100,255,0.50)` | Focus / hover border | **Accent — electric violet** | Token | Value | Use | |---|---|---| | `--spark-accent` | `#8b6eff` | Primary accent: buttons, active states, primary fills | | `--spark-accent-light` | `#b8a4ff` | Accent text, links, gradient endpoints | | `--spark-accent-dim` | `rgba(139,110,255,0.18)` | Tinted backgrounds, focus rings | | `--spark-accent-glow` | `rgba(139,110,255,0.40)` | Glow shadows | **Semantic** | Token | Value | Use | |---|---|---| | `--spark-success` | `#34d399` | Success / online | | `--spark-warning` | `#fbbf24` | Warning / in-progress | | `--spark-danger` | `#f87171` | Error / destructive | **Text** (highest → lowest emphasis) | Token | Value | Use | |---|---|---| | `--spark-text-1` | `#ecedf4` | Primary text, titles | | `--spark-text-2` | `#9698ad` | Secondary / body copy | | `--spark-text-3` | `#7e8099` | Muted: labels, captions, placeholders | ### 1.2 Typography | Token | Stack | |---|---| | `--font-sans` | `'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif` | | `--font-mono` | `'JetBrains Mono', 'SF Mono', Consolas, monospace` | - **Import:** Plus Jakarta Sans (400,500,600,700,800) + JetBrains Mono (400,500,600). - **Base:** `16px` root, antialiased. - **Sans** = all human-facing content: body, titles, buttons. **Mono** = metadata: labels, badges, status, stats, captions, and any machine/code output. **Type scale** | Role | Size | Weight | Tracking | |---|---|---|---| | Page title | `clamp(1.5rem, 4vw, 2.25rem)` | 800 | `-0.035em` | | Section / card title | `1.15rem` | 700 | `-0.02em` | | Subtitle | `0.82rem` | 500 | — | | Body | `0.84–0.88rem` | 400 | line-height `1.55` | | Label (mono, uppercase) | `0.72rem` | 700 | `0.06em` | | Badge / chip (mono, uppercase) | `0.62–0.7rem` | 600 | `0.06–0.08em` | | Micro / stats (mono) | `0.6rem` | — | — | ### 1.3 Radii | Token | Value | Use | |---|---|---| | `--radius-sm` | `8px` | Inputs, buttons, small tints, banners | | `--radius-md` | `14px` | Message bubbles, mid containers | | `--radius-lg` | `20px` | Cards, panels, shells | | `--radius-xl` | `28px` | Largest containers | Pills / fully-rounded use `999px`. ### 1.4 Shadows | Token | Value | Use | |---|---|---| | `--shadow-card` | `0 2px 8px rgba(0,0,0,.35), 0 12px 40px rgba(0,0,0,.25)` | Default elevation | | `--shadow-glow` | `0 0 30px var(--spark-accent-glow)` | Accent glow | | `--shadow-input` | `inset 0 1px 3px rgba(0,0,0,.4)` | Recessed inputs | Hover elevation composes both: `var(--shadow-card), 0 0 26px var(--spark-accent-glow)`. ### 1.5 Background texture Optional faint violet grid on the page background: two crossed linear-gradients at `rgba(139,110,255,0.018)`, `background-size: 48px 48px`. Keep opacity near-invisible — it reads as texture, not pattern. --- ## 2. Layout ### 2.1 Container widths Fluid-capped with `min(viewport, max)`: | Context | Width | |---|---| | Standard single column | `min(92vw, 680px)` | | Wide content grid | `min(92vw, 960px)` | | Two-column workspace | `min(96vw, 1120px)` | | Reading / conversation column | `min(94vw, 760px)` | ### 2.2 Page shell Vertical flex column, centered, `padding: 24px 16px 40px`, `gap: 20px`, `min-height: 100svh`. ### 2.3 Grids - **Auto grid:** `repeat(auto-fit, minmax(260px, 1fr))`, `gap: 18px` — self-wrapping cards. - **Two-column workspace:** `minmax(0,1.15fr) minmax(0,1fr)`, `gap: 18px`, `align-items: start`. - **Input row:** `1fr auto` — field + adjacent button. ### 2.4 Breakpoints | Max-width | Change | |---|---| | `860px` | Two-column layouts collapse to one column | | `640px` | Tighter page padding/gap; input rows stack; buttons go full-width and taller (44px); status bars stack left-aligned; page title shrinks to `1.3rem` | --- ## 3. Motion | Keyframe | Behavior | Used by | |---|---|---| | `pulse-dot` | opacity `1→.5`, scale `1→.8` over `1.2–2s` | status dots, streaming/loading dots | | `spin` | continuous 360° | spinners | **Transition conventions:** transforms `.12–.15s`; color/border `.2s`; box-shadow `.25–.3s`. Hover lift is `translateY(-1px to -3px)`, reset to `0` on `:active`. --- ## 4. Components Recipes list defining properties. Compose every value from the tokens above. ### 4.1 Badge / pill - Pill (`999px`), `--spark-accent-dim` bg, `1px` accent border at `0.2` alpha, `--spark-accent-light` text. - Mono, uppercase, `0.62–0.7rem`, weight 600. - Status variant: prepend a 6px pulsing `--spark-accent` dot (glow + `pulse-dot`). ### 4.2 Gradient title - `linear-gradient(135deg, #ecedf4 30%, var(--spark-accent-light) 100%)` clipped to text. ### 4.3 Card - `--spark-bg-card`, `1px --spark-border`, `--radius-lg`, `--shadow-card`, `padding: 22px`, flex column `gap: 10px`. - **Hover:** lift `-3px`, border → `--spark-border-focus`, add accent glow. - Anatomy: optional badge → title → description (`flex: 1`) → call-to-action (accent-light, 600). ### 4.4 Panel - `--spark-bg-panel`, `1px --spark-border`, `--radius-lg`, `--shadow-card`, `padding: 16px 18px`, flex column `gap: 14px`. ### 4.5 Field + label - Field: flex column `gap: 5px`. - Label: mono uppercase, `0.72rem`, 700, tracking `0.06em`, `--spark-text-3`. ### 4.6 Input / textarea - `--spark-bg-input`, `1px --spark-border`, `--radius-sm`, `--shadow-input`, `padding: 10px 14px`, sans `0.85rem`, `resize: none`. - **Focus:** border → `--spark-border-focus` + `0 0 0 3px --spark-accent-dim` ring. - Read-only → `--spark-text-2`. Placeholder → `--spark-text-3`. - Output/scroll variant: mono, scrollable, thin custom scrollbar (5px track, `--spark-accent-dim` thumb). ### 4.7 Primary button - `--radius-sm`, height `40px` (44px on mobile), sans `0.82rem`/700, flex-centered with optional icon gap. - **Default:** `--spark-accent` bg, white text, shadow `0 4px 18px rgba(139,110,255,.35)` (deepens on hover). - **Destructive:** `--spark-danger` bg, white text, red shadow. - `:hover` lift `-1px`; `:disabled` opacity `.45`, `not-allowed`. ### 4.8 Secondary / small button - `--spark-bg-elevated`, `1px --spark-border`, `--radius-sm`, sans `0.74rem`/600, `--spark-text-2`. Hover → `--spark-bg-hover` + `--spark-text-1`. ### 4.9 Status indicator - Chip: pill, `--spark-bg-card`, hairline border, mono `0.68rem`, `--spark-text-3`, with leading dot. - Dot states: neutral `--spark-text-3`; success → `--spark-success` + glow; loading → `--spark-warning` + `pulse-dot`; error → `--spark-danger`. - Semantic tag (e.g. a feature flag): tinted pill in the matching semantic color at low alpha. ### 4.10 Overlay & loader - Floating overlay element: absolute pill, `backdrop-filter: blur(12px) saturate(1.4)`, translucent dark bg, `1px` white-10 border, mono `0.68rem`. - Full-cover loading overlay: `rgba(8,9,12,.88)`, centered, with spinner + label. - Spinner: ring with `--spark-accent` top border on a faint track, `spin .9s` (10px inline variant available). ### 4.11 Message bubble - Container: scrollable, panel surface, `--radius-lg`, flex column `gap: 16px`. - Bubble: `--radius-md`, `0.88rem`, `white-space: pre-wrap`, max-width `88%`. - **Own/user:** `--spark-accent` bg, white, clipped bottom-right corner (`4px`), right-aligned. - **Other/assistant:** `--spark-bg-elevated`, hairline border, clipped bottom-left, left-aligned. - Role caption: mono uppercase `0.62rem`, `--spark-text-3`. - Collapsible detail block: left accent border, `--spark-bg-input`, muted `0.78rem`; toggle via a `collapsed` class (`display:none`) with an accent-light label. - Streaming indicator: three 6px accent-light dots with staggered `pulse-dot` (delays `0 / 0.2s / 0.4s`). ### 4.12 Banner - Semantic-tinted: e.g. error uses `rgba(248,113,113,0.1)` bg, `1px rgba(248,113,113,0.2)` border, `--spark-danger` text, `--radius-sm`. Swap the color token for warning/success/info equivalents. ### 4.13 Utilities - `.hidden` → `display: none !important`. --- ## 5. Usage rules - Drive every surface, border, accent, and shadow from `--spark-*` tokens — no raw hex in components. - Mono for metadata (labels, badges, stats, status, machine output); sans for everything human-facing. - Follow the elevation ladder: root → input → panel → card → elevated → hover. - Pair hover lift with the composed `card + glow` shadow; reset transform on `:active`. - Stay within the documented radii set, container max-widths, and breakpoints. - Keep the optional grid texture near-invisible.