prop-for-that
Use when building web or PWA UI that must react in CSS to runtime state CSS can't see (pointer, size, visibility, network, battery, media, form validity…
Skill by courtneyr-dev
Chalk Labs
Need help deploying prop-for-that?
Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/courtneyr-dev-prop-for-that
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: design, frontend
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/prop-for-that
What's inside
- Skill name
prop-for-that- Description
- Use when building web or PWA UI that must react in CSS to runtime state CSS can't see (pointer, size, visibility, network, battery, media, form validity, image color), or when the user says 'react to X in CSS' or 'what JS knows that CSS doesn't'. Checks native CSS first.
- License
- MIT
- Instructions
- 122 lines in SKILL.md · view on GitHub
Files (2)
- SKILL.md
- reference.md
SKILL.md (first lines)
# prop-for-that — runtime state as CSS custom properties
CSS can't see most of what the browser already knows: where the pointer is, how
big an element is, whether you're offline, battery level, whether a video is
playing, how full a textarea is. `prop-for-that` runs one tiny batched loop that
writes that state into CSS custom properties (`--live-*` reactive, `--const-*`
write-once), so your stylesheets react with plain `var()`/`calc()` (continuous
values) or `@container style()` (discrete values) — no per-element event
handlers, no JS in the animation path.
Zero deps, TypeScript, SSR-safe, MIT. **Pinned to `prop-for-that@0.7.2` — it's
pre-1.0, so pin the version and re-read the changelog before bumping.** Full
catalog, gotchas, and complete recipes live in `reference.md` (read it before
writing CSS against these props).
## Step 1 — check native CSS FIRST (this is the rule, not a footnote)
Most "JS knows, CSS doesn't" is *already* native CSS. Don't add a JS dependency
for anything in this list — use the platform:
| You want… | Use native CSS | Not the library |
| --- | --- | --- |
| React to scroll position/progress | `animation-timeline: scroll()` / `view()` | ✅ |
| Element size → layout | container queries + `cqw/cqh` units | ✅ |
| Viewport size → layout | media queries + `dvh/svh/lvh` units | ✅ |
| Dark/light mode | `prefers-color-scheme`, `light-dark()` | ✅ |
| Reduce motion | `prefers-reduced-motion` | ✅ |
| Hover/touch capability | `@media (hover)`, `(pointer: fine/coarse)` | ✅ |
| Per-field validity styling | `:user-valid` / `:user-invalid` / `:required` | ✅ |
| Installed-PWA styling | `@media (display-mode: standalone)` | ✅ |
| "Form has an invalid field" | `form:has(:invalid)` | ✅ |
Reach for the library **only** for state the platform genuinely can't expose:
- **Pointer position** as numbers (x/y, ratios) — `pointer`, `pointer-local`
- **Connectivity** — `online`, `network` (downlink/rtt/save-data/effective-type)
- **Device** — `battery`, `fps`, `orientation`, `motion`, `geo`, `cpu-pressure`
- **Page state** — `page-focused`, `page-visible`, `nav-type`, `visual-viewport`
(pinch-zoom/offset — the one viewport read CSS *can't* do)
- **Numeric reads CSS lacks** — element size *as a variable* (`size`), char
count / fill % (`field`), form completion counts (`form-state`), select index
(`select`), color-input value (`color-input`), image natural size/loaded/broken
(`img`), scroll velocity & direction (`scroll-velocity`), clock (`clock`)
- **Media** — playback time/paused/volume (`media`), dominant/accent color of an
image or video (`img-color`, `video-color`)
> Edge note: scroll *direction* has a Chromium-only `@container scroll-state(scrolled:)`
> condition and there's a Chromium-only scroll-velocity approximation, but neither
> is Baseline — use `scroll-velocity` for portable, numeric values.
## Step 2 — is this even the right kind of project?
- **Strong fit:** a live-browser PWA or site (this is the home — e.g. the Outpost
PWA). The whole value is *live* runtime state.
- **Caveated fit — WordPress / public front-ends:** every effect ships JS to
every visitor. The `/head` constants are cheap and fine site-wide; live sources
only for a justified, measured effect. The block *editor* is freer than the
front end. Justify per-effect against the performance budget.
- **Non-fit — skip entirely:** deterministic renderers (Remotion and other
frame-by-frame video), SSR-only output with no client runtime, Node CLIs.
Pointer/battery/network mean nothing in a pre-rendered frame.
## Step 3 — install and wire it
```bash
npm i prop-for-that@0.7.2
```
| Entry | When |
| --- | --- |
| `prop-for-that/auto` | Declarative. `<script type="module">import 'prop-for-that/auto'</script>` then add `data-props-for="key …"` to elements (globals on `<html>`). Lazy-loads each plugin chunk on first use. Must be a module. |
| `prop-for-that` | Imperative — `propsFor()`, `register()`, `configure()`. Use for shadow-DOM (auto only sees light DOM) and explicit teardown. |
| `prop-for-that/head` | FOUC-safe `--const-*` (scrollbar width, DPR, cores) written inline before first paint. Inline a synchronous build in `<head>`. |
For Vite/Preact apps (like Outpost), `import 'prop-for-that/auto'` once at entry,
then drive styling from attributes — see the recipes in `reference.md`.
## Spotlight recipes (full copy-paste versions in `reference.md`)
1. **Offline / save-data banner + network-aware imagery** — `online` + `network`
on `<html>`; discrete booleans → `@container style(--live-online: 0)` /
`style(--live-net-save-data: 1)` drop heavy imagery, show a banner. Pure CSS.
2. **Pointer-reactive card tilt + size-aware text** — `pointer` (global) +
`size` (on the card); continuous ratios → `rotateY(calc((var(--live-pointer-x-ratio) - .5) * 16deg))`.
3. **Char counter / fill bar + submit-gating** — `field` on a wrapper (so the
sibling counter inherits its vars), `form-state` on the `<form>`;
`inline-size: calc(var(--live-fill-pct) * 100%)` and unlock the button under
`@container style(--live-all-valid: 1)`.
4. **FOUC-safe scrollbar gutter + DPR** — `/head` constants; reserve
`calc(var(--const-scrollbar-w) * 1px)`, crisp hairlines with `calc(1px / var(--const-dpr))`.
## Five gotchas that bite (full list in `reference.md`)
1. **Custom properties inherit downward only.** Element-scoped vars land on the
bound element — to let *siblings* react, bind a common ancestor. (`field` /
`range` help: bind the wrapper, they find the inner `<input>`.)
2. **Right consumer for the value.** Continuous numbers → `var()` + `calc()`.
Discrete/boolean/integer → `@container style()`, which matches on **equality
only** (`style(--x < 5)` isn't stable) — emit booleans/tiers for thresholds.
3. **Values are unitless.** Multiply by `1px` / `1deg` / `100%` in CSS.
4. **Global `--live-*` go into an adopted stylesheet,** not inline `<html>` style
— read computed style, not `documentElement.style`.
5. **`auto` sees light DOM only** and loads plugin chunks only from verbatim CDNs
(unpkg/jsDelivr file paths), not rewriting ones (esm.sh, `+esm`).
## Performance posture (maps to the Code Output Verification Checklist)
One `requestAnimationFrame` flush per frame, write-on-change diffing, shared
observers, element sources paused off-screen, whole loop frozen while the tab is
hidden, `configure({ liveHz: 30 })` to throttle. **Strong** on JS-minimization
(JS only samples; CSS does the reacting), complexity (zero deps, platform
primitives), and trade-off honesty. **Watch:** it *is* client JS; per-frame style
recalc scales with how many `--live-*` your selectors consume; `pointer` is
high-frequency (drive expensive transforms sparingly); it ships **no
observability** — wire your own INP / Long-Animation-Frame RUM if an effect is
load-bearing.
Links: [docs](https://prop-for-that.netlify.app/docsite/) ·
[llms.txt](https://prop-for-that.netlify.app/llms.txt) ·From courtneyr-dev/agent-skills, MIT.
More from courtneyr-dev/agent-skills
- 0.529score
anti-slop-git-writing
courtneyr-dev
Use when writing a commit message, PR or MR title and body, GitHub or GitLab issue, bug report, or code-review comment, and when a bug found while testing or…
SkillBFreshness: BClaude Code +9 - 0.529score
job-search
courtneyr-dev
Run a repeatable job-search scan across job boards, company ATS pages, email alerts, LinkedIn, and community chat; diff against the previous run to separate…
SkillBFreshness: BClaude Code +9 - 0.529score
credit-routing
courtneyr-dev
Use at the start of any non-trivial task, when deciding whether to delegate, when a task has failed twice, before escalating model or effort, or when the user…
SkillBFreshness: BClaude Code +9 - 0.529score
lmk
courtneyr-dev
Use when the user says 'LMK when you're done', 'let me know', 'notify me', 'ping me when you're done', or says you are stepping away and wants a phone push…
SkillBFreshness: BClaude Code +9 - 0.529score
obsid-link-builder
courtneyr-dev
Use when asked to create or normalize shareable obsid.net links for Obsidian notes, convert obsidian:// links, or check the URL encoding of vault and file…
SkillBFreshness: BClaude Code +9 - 0.529score
church-bulletin-to-obsidian
courtneyr-dev
Use when the user shares a church bulletin (image or text) or says 'church bulletin' and wants the sermon-notes file for the vault.
SkillBFreshness: BClaude Code +9 - 0.529score
plaud
courtneyr-dev
Use when the user says 'Plaud', 'my recordings', 'what did I record', or wants a Plaud transcript, summary, digest, follow-up, or export.
SkillBFreshness: BClaude Code +9 - 0.529score
gatherer
courtneyr-dev
Use when the user says 'gather my work', 'what's on my plate', or 'daily gather', or when a review needs your open GitHub issues and PRs, watched Trac…
SkillBFreshness: BClaude Code +9 - 0.529score
ollie
courtneyr-dev
Use when working with the Ollie block theme or Ollie Pro: building a page or site in Ollie, styling, colors, typography, buttons, spacing, block markup…
SkillBFreshness: BClaude Code +9 - 0.524score
github-repo
courtneyr-dev
Use when the user says 'make my repo look good', 'prepare this repo for open source', or asks to audit or add a README, CONTRIBUTING, SECURITY…
SkillBFreshness: BClaude Code +9 - 0.524score
codex-first
courtneyr-dev
Use when a task is mechanical enough to specify completely (implementation from a settled design, refactor, migration, tests, coverage, CI fix, dependency…
SkillBFreshness: BClaude Code +9 - 0.524score
email-draft-review
courtneyr-dev
Use when the user says 'draft my email replies', 'handle my inbox', 'triage Gmail', or asks to prepare (never send) replies to the emails that need answers.
SkillBFreshness: BClaude Code +9
Signals
- Stars
- 0
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Sep 5, 2026 (1 month ago)
- Last release
- Sep 5, 2026 (1 month ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/courtneyr-dev/agent-skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from courtneyr-dev
- 0.570score
block-runner
courtneyr-dev
Turn WordPress page content or authored design HTML into valid, native, editable Gutenberg blocks, or plan a reusable named registered block for deterministic…
SkillAFreshness: AClaude Code +9 - 0.559score
better-documents
courtneyr-dev
Use when asked to write or review a memo, deck, proposal, report, brief, one-pager, or email, or when Courtney says 'review my doc', 'does this land', 'is…
SkillAFreshness: AClaude Code +9 - 0.559score
agents-md-lint
courtneyr-dev
Audit and trim AI agent instruction files (AGENTS.md, CLAUDE.md, CONVENTIONS.md, .cursorrules, etc.) by testing which facts an AI agent can discover from code…
SkillAFreshness: AClaude Code +9 - 0.559score
add-expert
courtneyr-dev
Add a new expert to the Remotion experts page — places the headshot in docs and promo-pages, appends the entry to experts-data.tsx, and renders the expert card.
SkillAFreshness: AClaude Code +9 - 0.559score
aim
courtneyr-dev
Use when the user is starting a new decision, framing a question for AI, or about to prompt for analysis on a real call.
SkillAFreshness: AClaude Code +9 - 0.556score
book-review
courtneyr-dev
Draft a long-form book review from your Reader highlights — synthesizing the book with your broader reading history to generate original arguments
SkillAFreshness: AClaude Code +9
Done for you
Rather not set it up yourself?
Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.
See how we build AI agents →Read the case studies
Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.
- launches shipped
- 50+
- launches shipped
- media placements
- 500+
- media placements
- founders on every account
- 2
- founders on every account
Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block
Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.
Get prop-for-that running in your business
Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.
Cite this page
prop-for-that skill. Agent Mart. https://agentmart.dev/skills/courtneyr-dev-prop-for-that (last updated 2026-10-24)