@grove-dev/astro 0.1.5 → 0.2.5

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.
Files changed (148) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.d.ts +4 -25
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +56 -22
  5. package/dist/index.js.map +1 -1
  6. package/dist/layouts/index.d.ts +25 -0
  7. package/dist/layouts/index.d.ts.map +1 -0
  8. package/dist/layouts/index.js +25 -0
  9. package/dist/layouts/index.js.map +1 -0
  10. package/dist/lib/display.d.ts +33 -0
  11. package/dist/lib/display.d.ts.map +1 -0
  12. package/dist/lib/display.js +104 -0
  13. package/dist/lib/display.js.map +1 -0
  14. package/dist/lib/format.d.ts +30 -0
  15. package/dist/lib/format.d.ts.map +1 -0
  16. package/dist/lib/format.js +73 -0
  17. package/dist/lib/format.js.map +1 -0
  18. package/dist/lib/index.d.ts +26 -0
  19. package/dist/lib/index.d.ts.map +1 -0
  20. package/dist/lib/index.js +26 -0
  21. package/dist/lib/index.js.map +1 -0
  22. package/dist/lib/lenses.d.ts +96 -0
  23. package/dist/lib/lenses.d.ts.map +1 -0
  24. package/dist/lib/lenses.js +181 -0
  25. package/dist/lib/lenses.js.map +1 -0
  26. package/dist/lib/repo.d.ts +30 -0
  27. package/dist/lib/repo.d.ts.map +1 -0
  28. package/dist/lib/repo.js +44 -0
  29. package/dist/lib/repo.js.map +1 -0
  30. package/dist/lib/scores.d.ts +38 -0
  31. package/dist/lib/scores.d.ts.map +1 -0
  32. package/dist/lib/scores.js +83 -0
  33. package/dist/lib/scores.js.map +1 -0
  34. package/dist/lib/search.d.ts +199 -0
  35. package/dist/lib/search.d.ts.map +1 -0
  36. package/dist/lib/search.js +357 -0
  37. package/dist/lib/search.js.map +1 -0
  38. package/dist/lib/taxonomy-counts.d.ts +25 -0
  39. package/dist/lib/taxonomy-counts.d.ts.map +1 -0
  40. package/dist/lib/taxonomy-counts.js +41 -0
  41. package/dist/lib/taxonomy-counts.js.map +1 -0
  42. package/package.json +7 -7
  43. package/src/components/AppsIndexRow.astro +204 -0
  44. package/src/components/AppsPagination.astro +126 -0
  45. package/src/components/CategoryGrid.astro +86 -17
  46. package/src/components/ContributorsGrid.astro +149 -0
  47. package/src/components/DecisionRow.astro +89 -0
  48. package/src/components/ExploreByCategory.astro +67 -0
  49. package/src/components/ExploreByStack.astro +72 -0
  50. package/src/components/Hero.astro +246 -0
  51. package/src/components/Icon.astro +223 -0
  52. package/src/components/ItemCard.astro +306 -30
  53. package/src/components/MinimalAbout.astro +82 -0
  54. package/src/components/OriginalCollection.astro +116 -0
  55. package/src/components/RecordSection.astro +88 -0
  56. package/src/components/RefinePanel.astro +197 -0
  57. package/src/components/ScoreBars.astro +92 -22
  58. package/src/components/SmartLensTabs.astro +71 -0
  59. package/src/components/StackGrid.astro +132 -0
  60. package/src/components/WhyThisExists.astro +116 -0
  61. package/src/index.ts +61 -14
  62. package/src/layouts/BaseLayout.astro +227 -15
  63. package/src/layouts/Container.astro +57 -0
  64. package/src/layouts/Footer.astro +235 -0
  65. package/src/layouts/Header.astro +159 -0
  66. package/src/layouts/SectionHeader.astro +58 -0
  67. package/{templates/default/src/components/layout → src/layouts}/Seo.astro +62 -38
  68. package/src/layouts/ThemeToggle.astro +110 -0
  69. package/src/layouts/astro-shim.d.ts +29 -0
  70. package/src/layouts/index.ts +24 -0
  71. package/src/lib/display.ts +118 -0
  72. package/src/lib/format.ts +65 -0
  73. package/src/lib/index.ts +26 -0
  74. package/src/lib/lenses.ts +241 -0
  75. package/src/lib/repo.ts +44 -0
  76. package/src/lib/scores.ts +94 -0
  77. package/src/lib/search.ts +481 -0
  78. package/src/lib/taxonomy-counts.ts +60 -0
  79. package/src/styles.css +366 -638
  80. package/templates/default/astro.config.mjs +8 -6
  81. package/templates/default/content/pages/about.md +66 -0
  82. package/templates/default/content/pages/methodology.md +103 -0
  83. package/templates/default/data/generated/records.full.json +8 -0
  84. package/templates/default/data/generated/records.index.json +7 -0
  85. package/templates/default/data/generated/records.json +8 -0
  86. package/templates/default/data/generated/site-config.json +31 -0
  87. package/templates/default/data/records/.gitkeep +0 -0
  88. package/templates/default/grove.config.ts +36 -0
  89. package/templates/default/package.json +6 -5
  90. package/templates/default/public/llms-full.txt +14 -0
  91. package/templates/default/public/llms.txt +11 -0
  92. package/templates/default/src/components/layout/BaseLayout.astro +10 -57
  93. package/templates/default/src/components/layout/Footer.astro +16 -134
  94. package/templates/default/src/components/layout/Header.astro +25 -126
  95. package/templates/default/src/data/records.ts +193 -0
  96. package/templates/default/src/lib/markdown.ts +171 -0
  97. package/templates/default/src/pages/about.astro +95 -429
  98. package/templates/default/src/pages/index.astro +263 -61
  99. package/templates/default/src/pages/projects/[slug].astro +480 -0
  100. package/templates/default/src/pages/projects/index.astro +193 -0
  101. package/templates/default/src/pages/sitemap.xml.ts +73 -61
  102. package/templates/default/src/pages/submit.astro +122 -411
  103. package/templates/default/src/styles/global.css +42 -68
  104. package/src/components/ActiveFilterChips.astro +0 -20
  105. package/src/components/DirectoryFilters.astro +0 -100
  106. package/src/components/DirectoryHero.astro +0 -32
  107. package/src/components/HealthBadge.astro +0 -12
  108. package/src/components/LensTabs.astro +0 -26
  109. package/src/components/MethodologyPanel.astro +0 -20
  110. package/src/components/Pagination.astro +0 -24
  111. package/src/components/ProjectDetail.astro +0 -166
  112. package/src/components/SubmitDraft.astro +0 -137
  113. package/templates/default/src/components/AppCard.astro +0 -248
  114. package/templates/default/src/components/AppSection.astro +0 -58
  115. package/templates/default/src/components/AppsIndexRow.astro +0 -230
  116. package/templates/default/src/components/AppsPagination.astro +0 -147
  117. package/templates/default/src/components/CategoryGrid.astro +0 -80
  118. package/templates/default/src/components/ContributorsGrid.astro +0 -105
  119. package/templates/default/src/components/DecisionRow.astro +0 -219
  120. package/templates/default/src/components/ExploreByCategory.astro +0 -74
  121. package/templates/default/src/components/ExploreByStack.astro +0 -102
  122. package/templates/default/src/components/Hero.astro +0 -176
  123. package/templates/default/src/components/MinimalAbout.astro +0 -57
  124. package/templates/default/src/components/OriginalCollection.astro +0 -144
  125. package/templates/default/src/components/RefinePanel.astro +0 -272
  126. package/templates/default/src/components/ScoreBars.astro +0 -72
  127. package/templates/default/src/components/SmartLensTabs.astro +0 -65
  128. package/templates/default/src/components/StackGrid.astro +0 -95
  129. package/templates/default/src/components/WhyThisExists.astro +0 -81
  130. package/templates/default/src/components/icons/Icon.astro +0 -148
  131. package/templates/default/src/components/layout/SectionHeader.astro +0 -42
  132. package/templates/default/src/components/layout/ThemeToggle.astro +0 -97
  133. package/templates/default/src/data/apps.ts +0 -149
  134. package/templates/default/src/data/categories.ts +0 -27
  135. package/templates/default/src/data/config.ts +0 -28
  136. package/templates/default/src/data/contributors.ts +0 -96
  137. package/templates/default/src/data/stacks.ts +0 -47
  138. package/templates/default/src/data/stats.ts +0 -65
  139. package/templates/default/src/data/types.ts +0 -248
  140. package/templates/default/src/lib/apps-search.ts +0 -228
  141. package/templates/default/src/lib/format.ts +0 -36
  142. package/templates/default/src/lib/lenses.ts +0 -98
  143. package/templates/default/src/lib/repo.ts +0 -12
  144. package/templates/default/src/lib/scores.ts +0 -51
  145. package/templates/default/src/lib/taxonomy-counts.ts +0 -31
  146. package/templates/default/src/pages/apps/[slug].astro +0 -709
  147. package/templates/default/src/pages/apps/index.astro +0 -669
  148. package/templates/default/src/pages/contributors.astro +0 -142
@@ -1,433 +1,99 @@
1
1
  ---
2
- import { siteConfig } from "../data/config";
3
- import BaseLayout from "../components/layout/BaseLayout.astro";
4
- import Container from "../components/layout/Container.astro";
5
-
6
- const githubUrl = "https://github.com/tortuvshin/open-apps";
7
-
8
- // What the directory adds per app used as chip list in the
9
- // "What this project provides" card.
10
- const directoryFields = [
11
- "App name and repository",
12
- "Stack and language",
13
- "Supported platforms",
14
- "Category and tags",
15
- "License",
16
- "GitHub stars and forks",
17
- "Activity status",
18
- "Maturity level",
19
- "Learning value",
20
- "Contribution readiness",
21
- "Caveats or missing information",
22
- ];
23
-
24
- // Why real app codebases matter patterns you can actually study.
25
- const realAppPatterns = [
26
- "Project structure",
27
- "Navigation patterns",
28
- "State management",
29
- "API integration",
30
- "Authentication",
31
- "Local storage",
32
- "Platform setup",
33
- "Build and release configuration",
34
- "Documentation and contribution practices",
35
- ];
36
-
37
- // The questions a developer actually has when scanning a list
38
- // of repos. Drives the curation schema on detail pages.
39
- const scanQuestions = [
40
- "Is this a real app or only a demo?",
41
- "What stack does it use?",
42
- "Which platforms does it support?",
43
- "Is it actively maintained?",
44
- "Is it mature or new?",
45
- "Is it useful for learning?",
46
- "Is it beginner-friendly or complex?",
47
- "Does it have a clear license?",
48
- "Are there similar apps worth checking?",
49
- ];
50
-
51
- // Different shapes an app can take. The directory makes those
52
- // dimensions visible instead of treating every repo as "just
53
- // another project".
54
- const appShapes = [
55
- { label: "Mature and stable", note: "Long-running, production-ish" },
56
- { label: "New and interesting", note: "Recent, worth watching" },
57
- { label: "Good for studying architecture", note: "Patterns worth reading" },
58
- { label: "Easier for beginners", note: "Smaller, readable" },
59
- { label: "Useful but inactive", note: "Stale, still a reference" },
60
- { label: "Archived but worth learning from", note: "Patterns outlive the repo" },
61
- ];
62
-
63
- // Mobile stacks. Flutter is the original; others are being
64
- // added in order.
65
- const mobileStacks = [
66
- { name: "Flutter", status: "original", note: "Original collection" },
67
- { name: "React Native", status: "growing", note: "Second mobile stack" },
68
- { name: "Native iOS", status: "growing", note: "Swift / SwiftUI" },
69
- { name: "Native Android", status: "growing", note: "Kotlin / Compose" },
70
- { name: "Kotlin Multiplatform", status: "growing", note: "Shared mobile + desktop" },
71
- { name: "Ionic & Capacitor", status: "planned", note: "Web-tech mobile" },
72
- ];
73
-
74
- const title = "About — ${siteConfig.name}";
75
- const description =
76
- "About ${siteConfig.name} — a static, community-curated directory of real open-source application codebases. Mobile first.";
2
+ /**
3
+ * About page — three value props (MinimalAbout) + a long-form
4
+ * methodology section rendered from `content/pages/methodology.md`.
5
+ *
6
+ * The markdown body is read at build time and rendered as a single
7
+ * <pre> block (we keep the template dep-free; consumers can swap in
8
+ * a real markdown pipeline by overriding the page). The intent is
9
+ * that the methodology is *visible on the page* even if the prose
10
+ * isn't styled — the structured content stays discoverable.
11
+ */
12
+ import { readFileSync, existsSync } from "node:fs";
13
+ import { fileURLToPath } from "node:url";
14
+ import { dirname, resolve } from "node:path";
15
+
16
+ import siteConfig from "../../data/generated/site-config.json";
17
+ import BaseLayout from "@grove-dev/astro/layouts/BaseLayout.astro";
18
+ import Container from "@grove-dev/astro/layouts/Container.astro";
19
+ import MinimalAbout from "@grove-dev/astro/components/MinimalAbout.astro";
20
+
21
+ const title = `About — ${siteConfig.name}`;
22
+ const description = `About ${siteConfig.name} — ${siteConfig.tagline}`;
23
+
24
+ // ── Load methodology.md from content/pages/ (build time) ──────
25
+ const here = dirname(fileURLToPath(import.meta.url));
26
+ const methodologyPath = [
27
+ resolve(here, "..", "..", "..", "content", "pages", "methodology.md"),
28
+ resolve(here, "..", "..", "..", "..", "content", "pages", "methodology.md"),
29
+ resolve(process.cwd(), "content", "pages", "methodology.md"),
30
+ ].find((p) => existsSync(p));
31
+
32
+ let methodologyText: string | null = null;
33
+ if (methodologyPath) {
34
+ try {
35
+ methodologyText = readFileSync(methodologyPath, "utf8");
36
+ } catch {
37
+ methodologyText = null;
38
+ }
39
+ }
77
40
  ---
78
41
 
79
- <BaseLayout title={title} description={description}>
80
- <Container size="narrow">
81
- <article class="py-12 sm:py-16">
82
- <nav class="text-2xs text-ink-500 dark:text-ink-400" aria-label="Breadcrumb">
83
- <a href="/" class="hover:text-ink-900 dark:hover:text-ink-100">Home</a>
84
- <span class="mx-1.5 text-ink-300 dark:text-ink-700">/</span>
85
- <span class="text-ink-700 dark:text-ink-300">About</span>
86
- </nav>
87
-
88
- {/* ── Hero ─────────────────────────────────────────────────── */}
89
- <header class="mt-5">
90
- <span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
91
- About
92
- </span>
93
- <h1 class="mt-1 m-0 text-[1.75rem] sm:text-[2.25rem] font-semibold tracking-[-0.02em] leading-[1.1] text-ink-900 dark:text-ink-100">
94
- About {siteConfig.name}
95
- </h1>
96
- <p class="mt-4 m-0 text-[1rem] sm:text-[1.0625rem] leading-relaxed text-ink-700 dark:text-ink-200 max-w-[62ch]">
97
- {siteConfig.name} is a static, community-curated directory of real
98
- open-source application codebases.
99
- </p>
100
- <p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-500 dark:text-ink-400 max-w-[62ch]">
101
- The project started from the Open Source Flutter Apps collection
102
- and is now being expanded into a broader directory, starting with
103
- mobile apps.
104
- </p>
105
- <p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200 max-w-[62ch]">
106
- The goal is simple:{" "}
107
- <em class="not-italic font-medium text-ink-900 dark:text-ink-100">
108
- make real open-source apps easier to find, understand, compare,
109
- and learn from.
110
- </em>
111
- </p>
112
- </header>
113
-
114
- {/* ── Problem ──────────────────────────────────────────────── */}
115
- <section class="card mt-8 p-5 sm:p-6">
116
- <span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
117
- Problem
118
- </span>
119
- <h2 class="mt-1 m-0 text-[1.125rem] sm:text-[1.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
120
- Why this exists
121
- </h2>
122
- <p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
123
- Open-source app repositories are already available on GitHub.
124
- </p>
125
- <p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
126
- But finding useful real app codebases is still not easy.
127
- </p>
128
- <p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
129
- A developer often needs to know more than just the repository name
130
- and description:
131
- </p>
132
-
133
- <ul class="m-0 mt-3 grid list-none grid-cols-1 gap-x-5 gap-y-1.5 p-0 sm:grid-cols-2 text-[0.875rem] text-ink-700 dark:text-ink-200">
134
- {scanQuestions.map((q) => (
135
- <li class="flex items-baseline gap-2">
136
- <span aria-hidden="true" class="text-ink-400 dark:text-ink-500">·</span>
137
- <span>{q}</span>
138
- </li>
139
- ))}
140
- </ul>
141
-
142
- <p class="mt-4 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
143
- A plain README list becomes hard to scan as the number of apps
144
- grows.
145
- </p>
146
- <p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
147
- {siteConfig.name} turns that list into a structured directory.
148
- </p>
149
- </section>
150
-
151
- {/* ── What this project provides ───────────────────────────── */}
152
- <section class="card mt-4 p-5 sm:p-6">
153
- <span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
154
- What the directory adds
155
- </span>
156
- <h2 class="mt-1 m-0 text-[1.125rem] sm:text-[1.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
157
- What this project provides
158
- </h2>
159
- <p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
160
- Each app is organized with useful metadata, not just a link. The
161
- directory can show information such as:
162
- </p>
163
-
164
- <ul class="m-0 mt-4 list-none space-y-1.5 p-0">
165
- {directoryFields.map((f) => (
166
- <li class="flex items-baseline gap-2 text-[0.875rem] text-ink-700 dark:text-ink-200">
167
- <span aria-hidden="true" class="text-ink-400 dark:text-ink-500">—</span>
168
- <span>{f}</span>
169
- </li>
170
- ))}
171
- </ul>
172
-
173
- <p class="mt-4 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
174
- This makes it easier to decide whether a repository is worth
175
- opening.
176
- </p>
177
- </section>
178
-
179
- {/* ── Why real apps matter ─────────────────────────────────── */}
180
- <section class="card mt-4 p-5 sm:p-6">
181
- <span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
182
- Why real apps matter
183
- </span>
184
- <h2 class="mt-1 m-0 text-[1.125rem] sm:text-[1.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
185
- Why real app codebases matter
186
- </h2>
187
- <p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
188
- Small examples and tutorials are useful, but they do not show how
189
- real applications grow.
190
- </p>
191
- <p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
192
- Real app codebases can show:
193
- </p>
194
-
195
- <ul class="m-0 mt-4 flex flex-wrap gap-1.5 p-0">
196
- {realAppPatterns.map((p) => (
197
- <li class="inline-flex items-center rounded-md border border-ink-200 bg-ink-50 px-2 py-1 text-2xs font-medium text-ink-700 dark:border-ink-800 dark:bg-ink-900/60 dark:text-ink-300">
198
- {p}
199
- </li>
200
- ))}
201
- </ul>
202
-
203
- <p class="mt-4 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
204
- This project helps developers discover those real examples faster.
205
- </p>
206
- </section>
207
-
208
- {/* ── AI hype ──────────────────────────────────────────────── */}
209
- <section class="card mt-4 p-5 sm:p-6">
210
- <span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
211
- AI hype
212
- </span>
213
- <h2 class="mt-1 m-0 text-[1.125rem] sm:text-[1.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
214
- Why this list is still needed
215
- </h2>
216
-
217
- <p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
218
- A lot of developer attention right now is on AI coding tools. The
219
- pitch is familiar: describe the app, the model builds it, ship
220
- it.
221
- </p>
222
-
223
- <p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
224
- This project does not pretend to compete with that. It does
225
- something different.
226
- </p>
227
-
228
- <p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
229
- AI can generate code. It can also generate code that{" "}
230
- <em class="not-italic font-medium text-ink-900 dark:text-ink-100">looks like an app, runs like an app, and breaks like an app</em>.
231
- </p>
232
-
233
- <p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
234
- A generated prototype is not the same as a real application. Real
235
- apps have structure that survives years of changes, decisions,
236
- edge cases, and contributors. They handle authentication,
237
- navigation, storage, releases, deprecation. They have bugs and
238
- they fix them.
239
- </p>
240
-
241
- <p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
242
- That part does not come from prompting a model.
243
- </p>
244
-
245
- <p class="mt-4 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
246
- {siteConfig.name} is a list of those real applications. Curated by
247
- humans. Useful as a reference for:
248
- </p>
249
-
250
- <ul class="m-0 mt-3 list-none space-y-1.5 p-0 text-[0.875rem] text-ink-700 dark:text-ink-200">
251
- <li class="flex items-baseline gap-2">
252
- <span aria-hidden="true" class="text-ink-400 dark:text-ink-500">—</span>
253
- <span>Studying how a real app is structured</span>
254
- </li>
255
- <li class="flex items-baseline gap-2">
256
- <span aria-hidden="true" class="text-ink-400 dark:text-ink-500">—</span>
257
- <span>Comparing two real approaches to the same problem</span>
258
- </li>
259
- <li class="flex items-baseline gap-2">
260
- <span aria-hidden="true" class="text-ink-400 dark:text-ink-500">—</span>
261
- <span>Finding a codebase to learn from</span>
262
- </li>
263
- <li class="flex items-baseline gap-2">
264
- <span aria-hidden="true" class="text-ink-400 dark:text-ink-500">—</span>
265
- <span>Finding a codebase to contribute to</span>
266
- </li>
267
- <li class="flex items-baseline gap-2">
268
- <span aria-hidden="true" class="text-ink-400 dark:text-ink-500">—</span>
269
- <span>Finding a codebase to use as a reference when generating new code</span>
270
- </li>
271
- </ul>
272
-
273
- <p class="mt-4 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
274
- AI tools are useful. A curated directory of real codebases is
275
- also useful. They are not the same thing, and one does not
276
- replace the other.
277
- </p>
278
-
279
- <p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
280
- If you are using an AI tool to build something, you can also use
281
- this directory to find real apps to point it at.{" "}
282
- <em class="not-italic font-medium text-ink-900 dark:text-ink-100">
283
- "Build me an app like this one"
284
- </em>{" "}
285
- is a stronger instruction than{" "}
286
- <em class="not-italic font-medium text-ink-900 dark:text-ink-100">
287
- "build me an app."
288
- </em>
289
- </p>
290
-
291
- <p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
292
- That is the idea.
293
- </p>
294
- </section>
295
-
296
- {/* ── What makes an app valuable here ──────────────────────── */}
297
- <section class="card mt-4 p-5 sm:p-6">
298
- <span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
299
- Different shapes
300
- </span>
301
- <h2 class="mt-1 m-0 text-[1.125rem] sm:text-[1.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
302
- What makes an app valuable here
303
- </h2>
304
- <p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
305
- Not every repository is useful in the same way.
306
- </p>
307
-
308
- <ul class="m-0 mt-4 list-none space-y-2 p-0">
309
- {appShapes.map((s) => (
310
- <li class="flex items-baseline gap-3 text-[0.9375rem]">
311
- <span aria-hidden="true" class="mt-1.5 inline-block h-1.5 w-1.5 shrink-0 rounded-full bg-ink-400 dark:bg-ink-600"></span>
312
- <span class="font-medium text-ink-900 dark:text-ink-100">{s.label}</span>
313
- <span class="text-ink-500 dark:text-ink-400">— {s.note}</span>
314
- </li>
315
- ))}
316
- </ul>
317
-
318
- <p class="mt-4 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
319
- The directory should make those differences visible.
320
- </p>
321
- <p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
322
- Instead of treating every repository as the same, Open Source
323
- Apps adds context around each app.
324
- </p>
325
- </section>
326
-
327
- {/* ── Open data ────────────────────────────────────────────── */}
328
- <section class="card mt-4 p-5 sm:p-6">
329
- <span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
330
- How data works
331
- </span>
332
- <h2 class="mt-1 m-0 text-[1.125rem] sm:text-[1.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
333
- Open data
334
- </h2>
335
- <p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
336
- The project is open-source by design.
337
- </p>
338
- <p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
339
- The app data lives in the repository. The website is generated
340
- from static data. Metadata can be reviewed and improved through
341
- GitHub issues and pull requests.
342
- </p>
343
- <p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
344
- This keeps the project simple, transparent, and
345
- community-maintainable.
346
- </p>
347
- </section>
348
-
349
- {/* ── Current focus ────────────────────────────────────────── */}
350
- <section class="card mt-4 p-5 sm:p-6">
351
- <span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
352
- Scope right now
353
- </span>
354
- <h2 class="mt-1 m-0 text-[1.125rem] sm:text-[1.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100">
355
- Current focus
356
- </h2>
357
- <p class="mt-3 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
358
- The first focus is mobile apps.
359
- </p>
360
- <p class="mt-2 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
361
- The original collection is Flutter-based, so Flutter is the
362
- strongest starting point. The directory is also designed to
363
- support other mobile stacks over time:
364
- </p>
365
-
366
- <ul class="m-0 mt-4 list-none space-y-1.5 p-0">
367
- {mobileStacks.map((s) => (
368
- <li class="flex items-baseline gap-3 text-[0.9375rem]">
369
- <span
370
- aria-hidden="true"
371
- class={`mt-1.5 inline-block h-1.5 w-1.5 shrink-0 rounded-full ${
372
- s.status === "original"
373
- ? "bg-emerald-500"
374
- : s.status === "growing"
375
- ? "bg-amber-500"
376
- : "bg-ink-300 dark:bg-ink-700"
377
- }`}
378
- ></span>
379
- <span class="font-medium text-ink-900 dark:text-ink-100">{s.name}</span>
380
- <span class="text-ink-500 dark:text-ink-400">— {s.note}</span>
381
- </li>
382
- ))}
383
- </ul>
384
-
385
- <p class="mt-4 m-0 text-[0.9375rem] leading-relaxed text-ink-700 dark:text-ink-200">
386
- Later, the same structure can support other app types such as
387
- desktop apps.
388
- </p>
389
- </section>
390
-
391
- {/* ── Principle ────────────────────────────────────────────── */}
392
- <section class="mt-8 rounded-lg border border-ink-200 bg-ink-50/60 p-6 sm:p-7 dark:border-ink-800 dark:bg-ink-900/40">
393
- <span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
394
- The principle
395
- </span>
396
- <p class="mt-2 m-0 text-[1.125rem] sm:text-[1.375rem] font-semibold leading-[1.25] tracking-tight text-ink-900 dark:text-ink-100">
397
- Real apps are easier to learn from when they are organized with
398
- context.
399
- </p>
400
- <p class="mt-3 m-0 text-[0.9375rem] sm:text-[1rem] leading-relaxed text-ink-700 dark:text-ink-200">
401
- {siteConfig.name} exists to make open-source application
402
- codebases easier to discover, evaluate, and study.
403
- </p>
404
- </section>
405
-
406
- {/* ── CTA ──────────────────────────────────────────────────── */}
407
- <section class="mt-8 flex flex-wrap items-center gap-3">
408
- <a
409
- href="/apps"
410
- class="btn-primary"
411
- >
412
- Browse the directory
413
- </a>
414
- <a
415
- href={githubUrl}
416
- target="_blank"
417
- rel="noopener noreferrer"
418
- class="btn-outline"
419
- >
420
- View on GitHub
421
- </a>
422
- <a
423
- href={`${githubUrl}/blob/main/CONTRIBUTING.md`}
424
- target="_blank"
425
- rel="noopener noreferrer"
426
- class="btn-ghost"
427
- >
428
- Submit an app →
429
- </a>
430
- </section>
431
- </article>
432
- </Container>
42
+ <BaseLayout title={title} description={description} site={siteConfig}>
43
+ <Container>
44
+ <article class="py-12 sm:py-16">
45
+ <span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
46
+ About
47
+ </span>
48
+ <h1 class="mt-1 text-[1.75rem] sm:text-[2.25rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100 m-0">
49
+ About {siteConfig.name}
50
+ </h1>
51
+ <p class="mt-4 max-w-[62ch] text-base text-ink-700 dark:text-ink-200 m-0">
52
+ {siteConfig.name} is a community knowledge site built with{" "}
53
+ <a
54
+ href="https://github.com/tortuvshin/grove"
55
+ target="_blank"
56
+ rel="noopener noreferrer"
57
+ class="text-ink-900 underline hover:text-ink-700 dark:text-ink-100 dark:hover:text-white"
58
+ >
59
+ Grove
60
+ </a>{" "}
61
+ — an open-source framework for growing useful structured knowledge.
62
+ </p>
63
+ </article>
64
+ </Container>
65
+
66
+ <MinimalAbout
67
+ title="Why this exists"
68
+ description="Three principles guide what gets listed and how it's surfaced."
69
+ />
70
+
71
+ <Container>
72
+ <section class="py-12 sm:py-16" aria-labelledby="methodology-heading">
73
+ <span class="text-2xs font-medium uppercase tracking-wider text-ink-500 dark:text-ink-400">
74
+ Methodology
75
+ </span>
76
+ <h2
77
+ id="methodology-heading"
78
+ class="mt-1 text-[1.5rem] sm:text-[1.75rem] font-semibold tracking-tight text-ink-900 dark:text-ink-100 m-0"
79
+ >
80
+ How records are picked, scored, and surfaced
81
+ </h2>
82
+ <p class="mt-3 max-w-[62ch] text-sm text-ink-500 dark:text-ink-400 m-0">
83
+ The full editorial + scoring methodology lives in
84
+ <code class="font-mono text-ink-900 dark:text-ink-100">content/pages/methodology.md</code>.
85
+ Below is the rendered source so reviewers can audit the criteria.
86
+ </p>
87
+ {methodologyText ? (
88
+ <pre
89
+ class="mt-6 overflow-x-auto rounded-md border border-ink-200 bg-ink-50 p-4 text-xs leading-relaxed text-ink-800 dark:border-ink-800 dark:bg-ink-900/60 dark:text-ink-200"
90
+ ><code>{methodologyText}</code></pre>
91
+ ) : (
92
+ <p class="mt-6 max-w-[62ch] text-sm text-ink-500 dark:text-ink-400 m-0">
93
+ The methodology file is not yet present in this scaffold.
94
+ See <code class="font-mono">content/pages/methodology.md</code>.
95
+ </p>
96
+ )}
97
+ </section>
98
+ </Container>
433
99
  </BaseLayout>