@vibes.diy/prompts 14.1.50 → 14.1.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/llms/access.md CHANGED
@@ -560,6 +560,7 @@ App.jsx — `useVibe().can` gates every write surface (posts AND owner-only mana
560
560
  import React from "react";
561
561
  import { useFireproof } from "use-fireproof";
562
562
  import { useViewer, useVibe } from "use-vibes";
563
+ import { Button, Textarea } from "@vibes.diy/look";
563
564
 
564
565
  export default function App() {
565
566
  const { viewer, isViewerPending, ViewerTag } = useViewer();
@@ -604,8 +605,8 @@ export default function App() {
604
605
  submitPost();
605
606
  }}
606
607
  >
607
- <textarea value={draft} onChange={(e) => setDraft(e.target.value)} />
608
- <button type="submit">Post</button>
608
+ <Textarea value={draft} onChange={(e) => setDraft(e.target.value)} className="w-full" />
609
+ <Button type="submit">Post</Button>
609
610
  </form>
610
611
  ) : (
611
612
  viewer && <p className="text-muted-foreground">{canPost.reason}</p>
@@ -613,16 +614,20 @@ export default function App() {
613
614
 
614
615
  {/* owner-only management — gated on can.* */}
615
616
  {canGrant.ok && (
616
- <button onClick={() => database.put({ type: "roleGrant", role: "poster", userHandle: "newUser" })}>
617
+ <Button variant="secondary" onClick={() => database.put({ type: "roleGrant", role: "poster", userHandle: "newUser" })}>
617
618
  Grant poster role
618
- </button>
619
+ </Button>
619
620
  )}
620
621
 
621
622
  {posts.map((p) => (
622
623
  <div key={p._id}>
623
624
  <ViewerTag userHandle={p.authorHandle} />
624
625
  <p>{p.body}</p>
625
- {can.delete(p).ok && <button onClick={() => database.del(p._id)}>Delete</button>}
626
+ {can.delete(p).ok && (
627
+ <Button variant="destructive" size="sm" onClick={() => database.del(p._id)}>
628
+ Delete
629
+ </Button>
630
+ )}
626
631
  </div>
627
632
  ))}
628
633
  </div>
@@ -641,10 +646,10 @@ const canRevoke = can.delete(grantDoc);
641
646
  {(canAppoint.ok || canRevoke.ok) && (
642
647
  <ModeratorPanel>
643
648
  {canAppoint.ok && (
644
- <button onClick={() => database.put({ type: "modGrant", role: "moderator", userHandle })}>Appoint</button>
649
+ <Button onClick={() => database.put({ type: "modGrant", role: "moderator", userHandle })}>Appoint</Button>
645
650
  )}
646
651
  {canRevoke.ok ? (
647
- <button onClick={() => database.del(grantDoc._id)}>Revoke</button>
652
+ <Button variant="destructive" onClick={() => database.del(grantDoc._id)}>Revoke</Button>
648
653
  ) : (
649
654
  <p>{canRevoke.reason}</p>
650
655
  )}
package/llms/backend.md CHANGED
@@ -544,6 +544,7 @@ App.jsx
544
544
  ```jsx file=App.jsx
545
545
  import React from "react";
546
546
  import { useFireproof } from "use-fireproof";
547
+ import { Badge, Card, CardContent } from "@vibes.diy/look";
547
548
 
548
549
  export default function App() {
549
550
  const { useLiveQuery } = useFireproof("nodeReleases");
@@ -556,17 +557,21 @@ export default function App() {
556
557
  <main className="min-h-screen bg-background text-foreground font-sans mx-auto max-w-2xl p-6">
557
558
  <h1 className="text-3xl font-bold">Node.js releases</h1>
558
559
  {status?.state === "egress-denied" && (
559
- <p role="status" className="my-4 rounded-md bg-secondary text-secondary-foreground p-3 shadow-sm">
560
+ <Badge variant="secondary" role="status" className="my-4">
560
561
  showing saved data — live refresh unavailable
561
- </p>
562
+ </Badge>
562
563
  )}
563
564
  <ul className="mt-6 space-y-3">
564
565
  {releases.map((release) => (
565
- <li key={release._id} className="rounded-md bg-card text-card-foreground p-3 shadow-sm">
566
- <a className="font-bold underline" href={release.url} target="_blank" rel="noreferrer">
567
- {release.title}
568
- </a>
569
- <time className="ml-3 text-muted-foreground">{release.publishedAt.slice(0, 10)}</time>
566
+ <li key={release._id}>
567
+ <Card>
568
+ <CardContent>
569
+ <a className="font-bold underline" href={release.url} target="_blank" rel="noreferrer">
570
+ {release.title}
571
+ </a>
572
+ <time className="ml-3 text-muted-foreground">{release.publishedAt.slice(0, 10)}</time>
573
+ </CardContent>
574
+ </Card>
570
575
  </li>
571
576
  ))}
572
577
  </ul>
@@ -27,18 +27,18 @@ when they're ready.
27
27
  ```jsx file=App.jsx
28
28
  import React from "react";
29
29
  import { createVibe } from "use-vibes";
30
+ import { Button } from "@vibes.diy/look";
30
31
 
31
32
  export default function App() {
32
- const c = { btn: "min-h-11 px-5 rounded-md bg-primary text-primary-foreground shadow-sm active:translate-y-px active:shadow-sm" };
33
33
  // `ready` + `spec` come from the interview (see the full example below).
34
34
  return (
35
- <button
36
- className={c.btn}
35
+ <Button
36
+ size="lg"
37
37
  disabled={!ready}
38
38
  onClick={() => createVibe(spec)} // ← user gesture: the new tab is allowed
39
39
  >
40
40
  Create my pitch deck
41
- </button>
41
+ </Button>
42
42
  );
43
43
  }
44
44
  ```
@@ -67,6 +67,7 @@ Let the user edit each slide inline and present full-screen.`;
67
67
  import React from "react";
68
68
  import { callAI } from "call-ai";
69
69
  import { createVibe } from "use-vibes";
70
+ import { Button } from "@vibes.diy/look";
70
71
 
71
72
  export default function App() {
72
73
  const [answers, setAnswers] = React.useState({});
@@ -88,19 +89,18 @@ export default function App() {
88
89
  }
89
90
  }
90
91
 
91
- const c = { btn: "min-h-11 px-5 rounded-md bg-primary text-primary-foreground shadow-sm active:translate-y-px active:shadow-sm" };
92
92
  return (
93
93
  <main id="app">
94
94
  {/* ...interview... */}
95
95
  {!spec ? (
96
- <button className={c.btn} disabled={building} onClick={finish}>
96
+ <Button size="lg" disabled={building} onClick={finish}>
97
97
  {building ? "Preparing…" : "I'm ready"}
98
- </button>
98
+ </Button>
99
99
  ) : (
100
100
  // Prompt is prepared; THIS click opens the builder (user gesture).
101
- <button className={c.btn} onClick={() => createVibe(spec)}>
101
+ <Button size="lg" onClick={() => createVibe(spec)}>
102
102
  Create my pitch deck
103
- </button>
103
+ </Button>
104
104
  )}
105
105
  </main>
106
106
  );
@@ -471,6 +471,7 @@ App.jsx
471
471
  ```jsx
472
472
  import React from "react";
473
473
  import { useFireproof } from "use-fireproof";
474
+ import { Button, Card, CardContent, Input, Label } from "@vibes.diy/look";
474
475
 
475
476
  export default function App() {
476
477
  const { useDocument, useLiveQuery } = useFireproof("imageUploads");
@@ -497,9 +498,6 @@ export default function App() {
497
498
 
498
499
  const c = {
499
500
  page: "bg-background text-foreground font-sans",
500
- card: "bg-card text-card-foreground",
501
- field: "border border-input rounded-md focus:ring-2 focus:ring-ring",
502
- action: "bg-primary text-primary-foreground active:translate-y-px active:shadow-sm",
503
501
  meta: "text-muted-foreground",
504
502
  };
505
503
 
@@ -507,26 +505,29 @@ export default function App() {
507
505
  <div className={`min-h-screen p-6 max-w-lg mx-auto ${c.page}`}>
508
506
  <h2 className="text-2xl font-bold mb-4">Image Uploader</h2>
509
507
  <form onSubmit={onSubmit} className="space-y-3">
510
- <input type="file" accept="image/*" onChange={onPickFile} className={`w-full ${c.field} p-2`} />
511
- <input
508
+ <Label htmlFor="photo">Photo</Label>
509
+ <Input id="photo" type="file" accept="image/*" onChange={onPickFile} className="w-full" />
510
+ <Input
512
511
  type="text"
513
512
  placeholder="Caption"
514
513
  value={doc.caption}
515
514
  onChange={(e) => merge({ caption: e.target.value })}
516
- className={`w-full ${c.field} p-2`}
515
+ className="w-full"
517
516
  />
518
- <button type="submit" className={`px-4 py-2 rounded-md shadow-sm ${c.action}`}>
517
+ <Button type="submit" size="lg">
519
518
  Upload
520
- </button>
519
+ </Button>
521
520
  </form>
522
521
 
523
522
  <h3 className="text-lg font-bold mt-8">Recent Uploads</h3>
524
523
  <div className="grid grid-cols-2 gap-4 mt-2">
525
524
  {docs.map((d) => (
526
- <div key={d._id} className={`p-3 rounded-md shadow-sm ${c.card}`}>
527
- {d._files?.photo?.url && <img src={d._files.photo.url} alt={d.caption || "upload"} className="w-full h-auto rounded-md" />}
528
- <p className={`${c.meta} mt-2`}>{d.caption || "No caption"}</p>
529
- </div>
525
+ <Card key={d._id}>
526
+ <CardContent>
527
+ {d._files?.photo?.url && <img src={d._files.photo.url} alt={d.caption || "upload"} className="w-full h-auto rounded-md" />}
528
+ <p className={`${c.meta} mt-2`}>{d.caption || "No caption"}</p>
529
+ </CardContent>
530
+ </Card>
530
531
  ))}
531
532
  </div>
532
533
  </div>
@@ -606,6 +607,7 @@ Code listing for todo tracker App.jsx. Note the code ordering: hooks, then handl
606
607
  import React from "react";
607
608
  import { useFireproof } from "use-fireproof";
608
609
  import { useVibe } from "use-vibes";
610
+ import { Button, Card, CardContent, Input, Label } from "@vibes.diy/look";
609
611
 
610
612
  export default function App() {
611
613
  // 1. Hooks and document shapes
@@ -643,12 +645,10 @@ export default function App() {
643
645
  submitNewTodo();
644
646
  };
645
647
 
646
- // 3. ClassNames — right before JSX so colors stay consistent
648
+ // 3. ClassNames — right before JSX, for the plain elements only; the look's
649
+ // components carry their own surface, ink and shape.
647
650
  const c = {
648
651
  page: "bg-background text-foreground font-sans",
649
- card: "bg-card text-card-foreground",
650
- field: "border border-input rounded-md focus:ring-2 focus:ring-ring",
651
- danger: "bg-destructive text-foreground active:translate-y-px active:shadow-sm",
652
652
  meta: "text-muted-foreground",
653
653
  };
654
654
 
@@ -657,35 +657,33 @@ export default function App() {
657
657
  <div className={`min-h-screen max-w-md mx-auto p-6 ${c.page}`}>
658
658
  <h2 className="text-2xl font-bold mb-4">Todo List</h2>
659
659
  <form onSubmit={handleSubmit} className="mb-4">
660
- <label htmlFor="todo" className="block mb-2 font-bold">
660
+ <Label htmlFor="todo" className="mb-2 block">
661
661
  Todo
662
- </label>
663
- <input
664
- className={`w-full ${c.field} px-3 py-2`}
665
- id="todo"
666
- type="text"
667
- onChange={handleInputChange}
668
- value={newTodo.todo}
669
- />
662
+ </Label>
663
+ <Input className="w-full" id="todo" type="text" onChange={handleInputChange} value={newTodo.todo} />
670
664
  </form>
671
665
  <ul className="space-y-3">
672
666
  {todos.map((doc) => (
673
- <li className={`flex flex-col items-start p-3 rounded-md shadow-sm ${c.card}`} key={doc._id}>
674
- <div className="flex items-center justify-between w-full">
675
- <div className="flex items-center">
676
- <input
677
- className="mr-2"
678
- type="checkbox"
679
- checked={doc.completed}
680
- onChange={() => database.put({ ...doc, completed: !doc.completed })}
681
- />
682
- <span className="font-medium">{doc.todo}</span>
683
- </div>
684
- <button className={`text-sm px-3 py-2 rounded-md shadow-sm ${c.danger}`} onClick={() => database.del(doc._id)}>
685
- Delete
686
- </button>
687
- </div>
688
- <div className={`${c.meta} mt-1`}>{new Date(doc.createdAt).toISOString()}</div>
667
+ <li key={doc._id}>
668
+ <Card>
669
+ <CardContent className="flex flex-col items-start">
670
+ <div className="flex items-center justify-between w-full">
671
+ <div className="flex items-center">
672
+ <input
673
+ className="mr-2"
674
+ type="checkbox"
675
+ checked={doc.completed}
676
+ onChange={() => database.put({ ...doc, completed: !doc.completed })}
677
+ />
678
+ <span className="font-medium">{doc.todo}</span>
679
+ </div>
680
+ <Button variant="destructive" size="sm" onClick={() => database.del(doc._id)}>
681
+ Delete
682
+ </Button>
683
+ </div>
684
+ <div className={`${c.meta} mt-1`}>{new Date(doc.createdAt).toISOString()}</div>
685
+ </CardContent>
686
+ </Card>
689
687
  </li>
690
688
  ))}
691
689
  </ul>
package/llms/fireproof.md CHANGED
@@ -445,6 +445,7 @@ App.jsx
445
445
  ```jsx file=App.jsx
446
446
  import React from "react";
447
447
  import { useFireproof } from "use-fireproof";
448
+ import { Button, Card, CardContent, Input, Label } from "@vibes.diy/look";
448
449
 
449
450
  export default function App() {
450
451
  const { useDocument, useLiveQuery } = useFireproof("imageUploads");
@@ -471,9 +472,6 @@ export default function App() {
471
472
 
472
473
  const c = {
473
474
  page: "bg-background text-foreground font-sans",
474
- card: "bg-card text-card-foreground",
475
- field: "border border-input rounded-md focus:ring-2 focus:ring-ring",
476
- action: "bg-primary text-primary-foreground active:translate-y-px active:shadow-sm",
477
475
  meta: "text-muted-foreground",
478
476
  };
479
477
 
@@ -481,26 +479,29 @@ export default function App() {
481
479
  <div className={`min-h-screen p-6 max-w-lg mx-auto ${c.page}`}>
482
480
  <h2 className="text-2xl font-bold mb-4">Image Uploader</h2>
483
481
  <form onSubmit={onSubmit} className="space-y-3">
484
- <input type="file" accept="image/*" onChange={onPickFile} className={`w-full ${c.field} p-2`} />
485
- <input
482
+ <Label htmlFor="photo">Photo</Label>
483
+ <Input id="photo" type="file" accept="image/*" onChange={onPickFile} className="w-full" />
484
+ <Input
486
485
  type="text"
487
486
  placeholder="Caption"
488
487
  value={doc.caption}
489
488
  onChange={(e) => merge({ caption: e.target.value })}
490
- className={`w-full ${c.field} p-2`}
489
+ className="w-full"
491
490
  />
492
- <button type="submit" className={`px-4 py-2 rounded-md shadow-sm ${c.action}`}>
491
+ <Button type="submit" size="lg">
493
492
  Upload
494
- </button>
493
+ </Button>
495
494
  </form>
496
495
 
497
496
  <h3 className="text-lg font-bold mt-8">Recent Uploads</h3>
498
497
  <div className="grid grid-cols-2 gap-4 mt-2">
499
498
  {docs.map((d) => (
500
- <div key={d._id} className={`p-3 rounded-md shadow-sm ${c.card}`}>
501
- {d._files?.photo?.url && <img src={d._files.photo.url} alt={d.caption || "upload"} className="w-full h-auto rounded-md" />}
502
- <p className={`${c.meta} mt-2`}>{d.caption || "No caption"}</p>
503
- </div>
499
+ <Card key={d._id}>
500
+ <CardContent>
501
+ {d._files?.photo?.url && <img src={d._files.photo.url} alt={d.caption || "upload"} className="w-full h-auto rounded-md" />}
502
+ <p className={`${c.meta} mt-2`}>{d.caption || "No caption"}</p>
503
+ </CardContent>
504
+ </Card>
504
505
  ))}
505
506
  </div>
506
507
  </div>
@@ -579,6 +580,7 @@ Code listing for todo tracker App.jsx. Note the code ordering: hooks, then handl
579
580
  ```js file=App.jsx
580
581
  import React from "react";
581
582
  import { useFireproof } from "use-fireproof";
583
+ import { Button, Card, CardContent, Input, Label } from "@vibes.diy/look";
582
584
 
583
585
  export default function App() {
584
586
  // 1. Hooks and document shapes
@@ -610,12 +612,10 @@ export default function App() {
610
612
  submitNewTodo();
611
613
  };
612
614
 
613
- // 3. ClassNames — right before JSX so colors stay consistent
615
+ // 3. ClassNames — right before JSX, for the plain elements only; the look's
616
+ // components carry their own surface, ink and shape.
614
617
  const c = {
615
618
  page: "bg-background text-foreground font-sans",
616
- card: "bg-card text-card-foreground",
617
- field: "border border-input rounded-md focus:ring-2 focus:ring-ring",
618
- danger: "bg-destructive text-foreground active:translate-y-px active:shadow-sm",
619
619
  meta: "text-muted-foreground",
620
620
  };
621
621
 
@@ -624,35 +624,33 @@ export default function App() {
624
624
  <div className={`min-h-screen max-w-md mx-auto p-6 ${c.page}`}>
625
625
  <h2 className="text-2xl font-bold mb-4">Todo List</h2>
626
626
  <form onSubmit={handleSubmit} className="mb-4">
627
- <label htmlFor="todo" className="block mb-2 font-bold">
627
+ <Label htmlFor="todo" className="mb-2 block">
628
628
  Todo
629
- </label>
630
- <input
631
- className={`w-full ${c.field} px-3 py-2`}
632
- id="todo"
633
- type="text"
634
- onChange={handleInputChange}
635
- value={newTodo.todo}
636
- />
629
+ </Label>
630
+ <Input className="w-full" id="todo" type="text" onChange={handleInputChange} value={newTodo.todo} />
637
631
  </form>
638
632
  <ul className="space-y-3">
639
633
  {todos.map((doc) => (
640
- <li className={`flex flex-col items-start p-3 rounded-md shadow-sm ${c.card}`} key={doc._id}>
641
- <div className="flex items-center justify-between w-full">
642
- <div className="flex items-center">
643
- <input
644
- className="mr-2"
645
- type="checkbox"
646
- checked={doc.completed}
647
- onChange={() => database.put({ ...doc, completed: !doc.completed })}
648
- />
649
- <span className="font-medium">{doc.todo}</span>
650
- </div>
651
- <button className={`text-sm px-3 py-2 rounded-md shadow-sm ${c.danger}`} onClick={() => database.del(doc._id)}>
652
- Delete
653
- </button>
654
- </div>
655
- <div className={`${c.meta} mt-1`}>{new Date(doc.createdAt).toISOString()}</div>
634
+ <li key={doc._id}>
635
+ <Card>
636
+ <CardContent className="flex flex-col items-start">
637
+ <div className="flex items-center justify-between w-full">
638
+ <div className="flex items-center">
639
+ <input
640
+ className="mr-2"
641
+ type="checkbox"
642
+ checked={doc.completed}
643
+ onChange={() => database.put({ ...doc, completed: !doc.completed })}
644
+ />
645
+ <span className="font-medium">{doc.todo}</span>
646
+ </div>
647
+ <Button variant="destructive" size="sm" onClick={() => database.del(doc._id)}>
648
+ Delete
649
+ </Button>
650
+ </div>
651
+ <div className={`${c.meta} mt-1`}>{new Date(doc.createdAt).toISOString()}</div>
652
+ </CardContent>
653
+ </Card>
656
654
  </li>
657
655
  ))}
658
656
  </ul>
package/llms/p5.md CHANGED
@@ -25,6 +25,7 @@ App.jsx
25
25
  ```jsx file=App.jsx
26
26
  import React from "react";
27
27
  import p5 from "https://esm.sh/p5@1.11.13";
28
+ import { Button } from "@vibes.diy/look";
28
29
 
29
30
  const TAU = Math.PI * 2;
30
31
 
@@ -195,12 +196,12 @@ export default function App() {
195
196
  ref={hostRef}
196
197
  className="w-full h-[70vh] overflow-hidden rounded-lg border border-border shadow-md touch-none"
197
198
  />
198
- <button
199
- className="mt-3 rounded-md bg-primary text-primary-foreground px-4 py-2 text-sm shadow-sm active:translate-y-px active:shadow-sm"
199
+ <Button
200
+ className="mt-3"
200
201
  onClick={() => setParams((prev) => ({ ...prev, seed: Math.floor(Math.random() * 100000) }))}
201
202
  >
202
203
  Reseed
203
- </button>
204
+ </Button>
204
205
  </div>
205
206
  );
206
207
  }