backpr commited on
Commit
8f20a8c
·
verified ·
1 Parent(s): a3d1069

Sample handbooks: one click starts the check

Browse files
Files changed (4) hide show
  1. README.md +1 -1
  2. index.html +4 -4
  3. static/app.js +13 -7
  4. static/style.css +3 -0
README.md CHANGED
@@ -122,7 +122,7 @@ Whole rulebook: each state's questions were asked together, up to 25 per call, s
122
  ## Try it in 2 minutes
123
 
124
  1. **See a finished report:** open the sample report (one made-up handbook checked for Texas, North Carolina and Oregon) or any of the 8 sample reports, each with its answer key. They load instantly and cost nothing.
125
- 2. **Run a live check, no code needed:** under "No handbook handy? Try a sample handbook", load one of the eight sample handbooks, change a sentence or two so they break a rule (for example "no more than four babies" to "up to six babies" in the Texas one), and press Check. Beam checks it against that state's rules in about 10 to 60 seconds. A planted Texas infant-ratio mistake took 10 seconds and about 1 cent.
126
  3. **Your own handbook** needs a free access code (one check a day, sent on request to hi@backpr.com). Checking the same file again is free.
127
 
128
  This Space is a static page: the handbook is read, the rule pages are chosen and every quote is checked in your browser. A small Cloudflare Worker keeps the Beam token, checks the code, accepts only CareRules prompts, enforces spending limits and caches replies. The same page runs at [care.backpr.com](https://care.backpr.com).
 
122
  ## Try it in 2 minutes
123
 
124
  1. **See a finished report:** open the sample report (one made-up handbook checked for Texas, North Carolina and Oregon) or any of the 8 sample reports, each with its answer key. They load instantly and cost nothing.
125
+ 2. **Run a live check, no code needed:** under "No handbook handy? Try a sample handbook", load one of the eight sample handbooks, change a sentence or two so they break a rule (for example "no more than four babies" to "up to six babies" in the Texas one), and click "Check this handbook". Beam checks it against that state's rules in about 10 to 60 seconds. A planted Texas infant-ratio mistake took 10 seconds and about 1 cent.
126
  3. **Your own handbook** needs a free access code (one check a day, sent on request to hi@backpr.com). Checking the same file again is free.
127
 
128
  This Space is a static page: the handbook is read, the rule pages are chosen and every quote is checked in your browser. A small Cloudflare Worker keeps the Beam token, checks the code, accepts only CareRules prompts, enforces spending limits and caches replies. The same page runs at [care.backpr.com](https://care.backpr.com).
index.html CHANGED
@@ -26,7 +26,7 @@
26
  <meta name="twitter:title" content="Does your parent handbook break your state's licensing rules?">
27
  <meta name="twitter:description" content="Sentences that break your state's child care licensing rules, missing policies and new wording. 22 states and DC. Free.">
28
  <meta name="twitter:image" content="https://care.backpr.com/static/media/og.jpg">
29
- <link rel="stylesheet" href="static/style.css?v=4936a0810c">
30
  <script type="application/ld+json">{"@context":"https://schema.org","@graph":[
31
  {"@type":"WebApplication","@id":"https://care.backpr.com/#app","name":"CareRules","alternateName":"CareRules Handbook Inspector","url":"https://care.backpr.com/",
32
  "description":"Checks a child care center's parent handbook against the official licensing rules of 22 states and DC, and lists conflicting sentences, missing required policies and suggested wording. Every quote is checked word for word. Not legal advice.",
@@ -234,9 +234,9 @@
234
  <p class="small">See how it works. These made-up handbooks were written to follow their state's rules. Load one, change a sentence or two to break a rule (a ratio, a nap rule, a medicine rule), and see if CareRules catches it. No code needed: up to 3 checks a day, each against that handbook's state.</p>
235
  <div class="access-row"><select id="test-states" aria-label="Sample handbook"></select><button type="button" class="btn btn-ghost" id="test-load">Load handbook</button></div>
236
  <div id="test-edit" hidden>
237
- <label class="label" for="test-text">Edit the text below, then click "Use this handbook"</label>
238
  <textarea id="test-text" rows="12" spellcheck="false"></textarea>
239
- <button type="button" class="btn btn-ghost" id="test-use">Use this handbook</button>
240
  </div>
241
  </details>
242
  <div class="field">
@@ -352,6 +352,6 @@
352
  </div>
353
  </footer>
354
  <script src="static/engine.js?v=ddf3462180"></script>
355
- <script src="static/app.js?v=3726d9ba70"></script>
356
  </body>
357
  </html>
 
26
  <meta name="twitter:title" content="Does your parent handbook break your state's licensing rules?">
27
  <meta name="twitter:description" content="Sentences that break your state's child care licensing rules, missing policies and new wording. 22 states and DC. Free.">
28
  <meta name="twitter:image" content="https://care.backpr.com/static/media/og.jpg">
29
+ <link rel="stylesheet" href="static/style.css?v=409b4b1ba2">
30
  <script type="application/ld+json">{"@context":"https://schema.org","@graph":[
31
  {"@type":"WebApplication","@id":"https://care.backpr.com/#app","name":"CareRules","alternateName":"CareRules Handbook Inspector","url":"https://care.backpr.com/",
32
  "description":"Checks a child care center's parent handbook against the official licensing rules of 22 states and DC, and lists conflicting sentences, missing required policies and suggested wording. Every quote is checked word for word. Not legal advice.",
 
234
  <p class="small">See how it works. These made-up handbooks were written to follow their state's rules. Load one, change a sentence or two to break a rule (a ratio, a nap rule, a medicine rule), and see if CareRules catches it. No code needed: up to 3 checks a day, each against that handbook's state.</p>
235
  <div class="access-row"><select id="test-states" aria-label="Sample handbook"></select><button type="button" class="btn btn-ghost" id="test-load">Load handbook</button></div>
236
  <div id="test-edit" hidden>
237
+ <label class="label" for="test-text">Change a sentence or two below, then click "Check this handbook"</label>
238
  <textarea id="test-text" rows="12" spellcheck="false"></textarea>
239
+ <button type="button" class="btn" id="test-use"><span>Check this handbook</span> <small>(no code needed)</small></button>
240
  </div>
241
  </details>
242
  <div class="field">
 
352
  </div>
353
  </footer>
354
  <script src="static/engine.js?v=ddf3462180"></script>
355
+ <script src="static/app.js?v=7626d1f43b"></script>
356
  </body>
357
  </html>
static/app.js CHANGED
@@ -442,19 +442,23 @@ document.addEventListener("click", async (ev) => {
442
  /* "Plant your own mistake": a compliant test handbook to edit and check */
443
  $("#test-load").addEventListener("click", async () => {
444
  const code = $("#test-states").value;
 
445
  const text = await fetch(`samples/eval/${code}/clean.md`).then((r) => r.text());
446
  $("#test-text").value = text;
447
  $("#test-edit").hidden = false;
448
  state.chosen = new Set([code]);
449
  renderChips(); requestLink();
450
  });
451
- $("#test-use").addEventListener("click", () => {
 
452
  if (state.running) return; // a running check keeps its file
453
  const code = $("#test-states").value;
454
- setFile(new File([$("#test-text").value], `sample-handbook-${code}.md`, { type: "text/markdown" }), code);
 
 
455
  state.chosen = new Set([code]); renderChips(); requestLink();
456
- help($("#code").value.trim() ? "" : `No code needed: this sample handbook will be checked against ${stateName(code)}'s rules at Standard.`, false);
457
- $("#go").focus();
458
  });
459
 
460
  document.querySelectorAll(".choice").forEach((b) => b.addEventListener("click", () => {
@@ -483,11 +487,12 @@ drop.addEventListener("drop", (ev) => { if (ev.dataTransfer.files[0]) setFile(ev
483
 
484
  const help = (text, bad = true) => { $("#go-help").textContent = text; $("#go-help").classList.toggle("bad", !!text && bad); };
485
 
486
- $("#go").addEventListener("click", async () => {
 
487
  if (!state.pages) { help(state.fileError || "Add your parent handbook first."); drop.classList.add("over"); setTimeout(() => drop.classList.remove("over"), 900); return; }
488
  if (!state.chosen.size) { help("Pick your state first."); return; }
489
  let code = $("#code").value.trim(), status;
490
- const demo = !code && state.demo; // a sample handbook: no code needed, its own state, Standard
491
  if (!code && !demo) { $("#code").focus(); help(`Live checks need a free access code: email ${REQUEST_EMAIL}. Or try a sample handbook, no code needed.`); return; }
492
  if (demo) {
493
  code = "DEMO"; status = { max_states: 1 };
@@ -552,7 +557,8 @@ $("#go").addEventListener("click", async () => {
552
  $("#progress").hidden = true; $("#go").disabled = false;
553
  checkCode();
554
  }
555
- });
 
556
  document.addEventListener("click", (ev) => { if (ev.target.id === "retry") $("#go").click(); });
557
 
558
  const save = (blob, name) => {
 
442
  /* "Plant your own mistake": a compliant test handbook to edit and check */
443
  $("#test-load").addEventListener("click", async () => {
444
  const code = $("#test-states").value;
445
+ if (!code) return; // the list is still loading
446
  const text = await fetch(`samples/eval/${code}/clean.md`).then((r) => r.text());
447
  $("#test-text").value = text;
448
  $("#test-edit").hidden = false;
449
  state.chosen = new Set([code]);
450
  renderChips(); requestLink();
451
  });
452
+ /* One click: read the edited sample handbook and start the live check at once (no code, its own state, Standard). */
453
+ $("#test-use").addEventListener("click", async () => {
454
  if (state.running) return; // a running check keeps its file
455
  const code = $("#test-states").value;
456
+ $("#test-use").disabled = true;
457
+ await setFile(new File([$("#test-text").value], `sample-handbook-${code}.md`, { type: "text/markdown" }), code);
458
+ $("#test-use").disabled = false;
459
  state.chosen = new Set([code]); renderChips(); requestLink();
460
+ if (!state.pages) { help(state.fileError || "Couldn't read the edited handbook. Load it again and retry."); return; }
461
+ runCheck();
462
  });
463
 
464
  document.querySelectorAll(".choice").forEach((b) => b.addEventListener("click", () => {
 
487
 
488
  const help = (text, bad = true) => { $("#go-help").textContent = text; $("#go-help").classList.toggle("bad", !!text && bad); };
489
 
490
+ async function runCheck() {
491
+ if (state.running) return;
492
  if (!state.pages) { help(state.fileError || "Add your parent handbook first."); drop.classList.add("over"); setTimeout(() => drop.classList.remove("over"), 900); return; }
493
  if (!state.chosen.size) { help("Pick your state first."); return; }
494
  let code = $("#code").value.trim(), status;
495
+ const demo = !!state.demo; // a sample handbook: no code needed (a typed code isn't spent on it), its own state, Standard
496
  if (!code && !demo) { $("#code").focus(); help(`Live checks need a free access code: email ${REQUEST_EMAIL}. Or try a sample handbook, no code needed.`); return; }
497
  if (demo) {
498
  code = "DEMO"; status = { max_states: 1 };
 
557
  $("#progress").hidden = true; $("#go").disabled = false;
558
  checkCode();
559
  }
560
+ }
561
+ $("#go").addEventListener("click", runCheck);
562
  document.addEventListener("click", (ev) => { if (ev.target.id === "retry") $("#go").click(); });
563
 
564
  const save = (blob, name) => {
static/style.css CHANGED
@@ -64,6 +64,9 @@ h2 { font-size: clamp(32px, 5vw, 56px); line-height: 1.08; margin: 0 0 18px; max
64
  .ctas.center { justify-content: center; }
65
  .btn { display: inline-flex; align-items: center; justify-content: center; min-height: 48px; padding: 12px 24px; border-radius: 999px; border: 0; background: var(--grad); color: #16121f; font-weight: 700; font-size: 16px; text-decoration: none; cursor: pointer; font-family: var(--sans); }
66
  .btn:hover { filter: brightness(1.07); }
 
 
 
67
  .btn-ghost { background: rgba(255,255,255,.06); color: var(--text); border: 1px solid rgba(255,255,255,.25); }
68
  .btn-big { min-height: 54px; padding: 14px 30px; font-size: 17px; }
69
  .btn[disabled] { opacity: .55; cursor: wait; }
 
64
  .ctas.center { justify-content: center; }
65
  .btn { display: inline-flex; align-items: center; justify-content: center; min-height: 48px; padding: 12px 24px; border-radius: 999px; border: 0; background: var(--grad); color: #16121f; font-weight: 700; font-size: 16px; text-decoration: none; cursor: pointer; font-family: var(--sans); }
66
  .btn:hover { filter: brightness(1.07); }
67
+ .btn small { font-size: 13px; font-weight: 500; opacity: .75; }
68
+ .btn:has(small) { flex-wrap: wrap; column-gap: 6px; text-align: center; }
69
+ .btn:has(small) > * { white-space: nowrap; }
70
  .btn-ghost { background: rgba(255,255,255,.06); color: var(--text); border: 1px solid rgba(255,255,255,.25); }
71
  .btn-big { min-height: 54px; padding: 14px 30px; font-size: 17px; }
72
  .btn[disabled] { opacity: .55; cursor: wait; }