@chronoter/main 0.1.11 → 0.2.0

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/dist/cli.js CHANGED
@@ -8,6 +8,10 @@ import { visit } from 'unist-util-visit';
8
8
  import { compile } from '@mdx-js/mdx';
9
9
  import matter from 'gray-matter';
10
10
  import remarkGfm from 'remark-gfm';
11
+ import rehypeSlug from 'rehype-slug';
12
+ import { unified } from 'unified';
13
+ import remarkParse from 'remark-parse';
14
+ import GithubSlugger from 'github-slugger';
11
15
  import { fileURLToPath } from 'url';
12
16
  import { Command } from 'commander';
13
17
  import chalk2 from 'chalk';
@@ -237,12 +241,14 @@ var init_processor = __esm({
237
241
  throw new MDXError(`Failed to parse frontmatter: ${message}`, filePath);
238
242
  }
239
243
  const code = await this.compile(content, filePath, options?.baseUrl);
244
+ const headings = this.extractHeadings(content);
240
245
  const slug = this.generateSlug(filePath);
241
246
  const frontmatter = this.parseFrontmatter(data);
242
247
  return {
243
248
  code,
244
249
  frontmatter,
245
- slug
250
+ slug,
251
+ headings
246
252
  };
247
253
  } catch (error) {
248
254
  if (error instanceof MDXError) {
@@ -295,7 +301,8 @@ var init_processor = __esm({
295
301
  const result = await compile(source, {
296
302
  outputFormat: "function-body",
297
303
  development: false,
298
- remarkPlugins
304
+ remarkPlugins,
305
+ rehypePlugins: [rehypeSlug]
299
306
  });
300
307
  return String(result);
301
308
  } catch (error) {
@@ -320,6 +327,52 @@ var init_processor = __esm({
320
327
  const fileName = basename(filePath, extname(filePath));
321
328
  return fileName;
322
329
  }
330
+ /**
331
+ * Markdownコンテンツから見出しを抽出する
332
+ *
333
+ * @param content - Markdownコンテンツ
334
+ * @returns 見出しの配列(h2, h3のみ)
335
+ * @private
336
+ */
337
+ extractHeadings(content) {
338
+ const headings = [];
339
+ const slugger = new GithubSlugger();
340
+ try {
341
+ const tree = unified().use(remarkParse).parse(content);
342
+ visit(tree, "heading", (node) => {
343
+ if (node.depth === 2 || node.depth === 3) {
344
+ const text = this.extractTextFromNode(node.children);
345
+ const id = slugger.slug(text);
346
+ headings.push({
347
+ id,
348
+ text,
349
+ level: node.depth
350
+ });
351
+ }
352
+ });
353
+ } catch (error) {
354
+ console.warn("Failed to extract headings:", error);
355
+ }
356
+ return headings;
357
+ }
358
+ /**
359
+ * 見出しノードの子要素からテキストを抽出する
360
+ *
361
+ * @param children - 見出しノードの子要素
362
+ * @returns テキスト
363
+ * @private
364
+ */
365
+ extractTextFromNode(children) {
366
+ return children.map((child) => {
367
+ if (child.type === "text") {
368
+ return child.value;
369
+ }
370
+ if ("children" in child && Array.isArray(child.children)) {
371
+ return this.extractTextFromNode(child.children);
372
+ }
373
+ return "";
374
+ }).join("");
375
+ }
323
376
  };
324
377
  }
325
378
  });
@@ -446,16 +499,17 @@ var init_router = __esm({
446
499
  /**
447
500
  * ファイルパスからルートを作成
448
501
  *
449
- * @param filePath - MDXまたはMDファイルのパス
450
- * @param baseDir - ベースディレクトリパス
502
+ * @param filePath - MDXまたはMDファイルの絶対パス
503
+ * @param baseDir - ベースディレクトリパス(docsDir)
451
504
  * @returns 生成されたルート
452
505
  */
453
506
  async createRoute(filePath, baseDir) {
454
507
  const frontmatter = await this.extractFrontmatter(filePath);
455
508
  const urlPath = this.filePathToUrlPath(filePath, baseDir);
509
+ const relativeFilePath = path.relative(baseDir, filePath);
456
510
  return {
457
511
  path: urlPath,
458
- filePath,
512
+ filePath: relativeFilePath,
459
513
  frontmatter
460
514
  };
461
515
  }
@@ -513,12 +567,17 @@ var routing_middleware_exports = {};
513
567
  __export(routing_middleware_exports, {
514
568
  createRoutingMiddleware: () => createRoutingMiddleware
515
569
  });
516
- var __filename$1, __dirname$1, createRoutingMiddleware, handleAllRoutesRequest, handleRouteRequest, handleMDXRequest, handle500;
570
+ var __filename$1, __dirname$1, hasFileExtension, createRoutingMiddleware, handleAllRoutesRequest, handleRouteRequest, handleMDXRequest, handle500;
517
571
  var init_routing_middleware = __esm({
518
572
  "src/server/routing-middleware.ts"() {
519
573
  init_router();
520
574
  __filename$1 = fileURLToPath(import.meta.url);
521
575
  __dirname$1 = dirname(__filename$1);
576
+ hasFileExtension = (urlPath) => {
577
+ const lastSegment = urlPath.split("/").pop() || "";
578
+ const dotIndex = lastSegment.lastIndexOf(".");
579
+ return dotIndex > 0;
580
+ };
522
581
  createRoutingMiddleware = (server, options) => {
523
582
  const { config, cwd } = options;
524
583
  const routeGenerator = new RouteGenerator();
@@ -569,7 +628,8 @@ var init_routing_middleware = __esm({
569
628
  }
570
629
  const urlPath = url.split("?")[0];
571
630
  if (urlPath === "/__chronoter_mdx__") {
572
- return handleMDXRequest(req, res, cwd);
631
+ const docsDir = config.docsDir ? resolve(cwd, config.docsDir) : cwd;
632
+ return handleMDXRequest(req, res, docsDir);
573
633
  }
574
634
  if (urlPath === "/__chronoter_routes__") {
575
635
  return handleRouteRequest(req, res, getRoutes, routeGenerator);
@@ -579,7 +639,7 @@ var init_routing_middleware = __esm({
579
639
  }
580
640
  if (urlPath.startsWith("/@") || // Vite内部リクエスト
581
641
  urlPath.startsWith("/node_modules") || urlPath.startsWith("/src/") || // Viteが処理するソースファイル
582
- urlPath.includes(".") && !urlPath.endsWith("/") && !urlPath.startsWith("/src/")) {
642
+ hasFileExtension(urlPath) && !urlPath.endsWith("/") && !urlPath.startsWith("/src/")) {
583
643
  return next();
584
644
  }
585
645
  try {
@@ -689,7 +749,7 @@ var init_routing_middleware = __esm({
689
749
  );
690
750
  }
691
751
  };
692
- handleMDXRequest = async (req, res, cwd) => {
752
+ handleMDXRequest = async (req, res, docsDir) => {
693
753
  try {
694
754
  const url = new URL(req.url || "", `http://${req.headers.host}`);
695
755
  const filePath = url.searchParams.get("path");
@@ -699,8 +759,8 @@ var init_routing_middleware = __esm({
699
759
  res.end(JSON.stringify({ error: "Missing 'path' query parameter" }));
700
760
  return;
701
761
  }
702
- const absolutePath = resolve(cwd, filePath);
703
- if (!absolutePath.startsWith(cwd)) {
762
+ const absolutePath = resolve(docsDir, filePath);
763
+ if (!absolutePath.startsWith(docsDir)) {
704
764
  res.statusCode = 403;
705
765
  res.setHeader("Content-Type", "application/json");
706
766
  res.end(JSON.stringify({ error: "Access denied" }));
@@ -715,7 +775,8 @@ var init_routing_middleware = __esm({
715
775
  JSON.stringify({
716
776
  code: processedMDX.code,
717
777
  frontmatter: processedMDX.frontmatter,
718
- slug: processedMDX.slug
778
+ slug: processedMDX.slug,
779
+ headings: processedMDX.headings
719
780
  })
720
781
  );
721
782
  } catch (error) {
@@ -1665,7 +1726,7 @@ var runVersionCheck = async (packageName, currentVersion) => {
1665
1726
 
1666
1727
  // src/cli/index.ts
1667
1728
  var PACKAGE_NAME = "chronoter";
1668
- var CURRENT_VERSION = "0.1.11";
1729
+ var CURRENT_VERSION = "0.2.0";
1669
1730
  var createCliProgram = () => {
1670
1731
  const program = new Command();
1671
1732
  program.name("chronoter").description("Chronoter - MDX-based documentation site generator").version(CURRENT_VERSION);
package/dist/index.js CHANGED
@@ -7,6 +7,10 @@ import { visit } from 'unist-util-visit';
7
7
  import { compile } from '@mdx-js/mdx';
8
8
  import matter from 'gray-matter';
9
9
  import remarkGfm from 'remark-gfm';
10
+ import rehypeSlug from 'rehype-slug';
11
+ import { unified } from 'unified';
12
+ import remarkParse from 'remark-parse';
13
+ import GithubSlugger from 'github-slugger';
10
14
  import { fileURLToPath } from 'url';
11
15
  import chalk2 from 'chalk';
12
16
  import { defineConfig, createServer } from 'vite';
@@ -232,12 +236,14 @@ var init_processor = __esm({
232
236
  throw new MDXError(`Failed to parse frontmatter: ${message}`, filePath);
233
237
  }
234
238
  const code = await this.compile(content, filePath, options?.baseUrl);
239
+ const headings = this.extractHeadings(content);
235
240
  const slug = this.generateSlug(filePath);
236
241
  const frontmatter = this.parseFrontmatter(data);
237
242
  return {
238
243
  code,
239
244
  frontmatter,
240
- slug
245
+ slug,
246
+ headings
241
247
  };
242
248
  } catch (error) {
243
249
  if (error instanceof MDXError) {
@@ -290,7 +296,8 @@ var init_processor = __esm({
290
296
  const result = await compile(source, {
291
297
  outputFormat: "function-body",
292
298
  development: false,
293
- remarkPlugins
299
+ remarkPlugins,
300
+ rehypePlugins: [rehypeSlug]
294
301
  });
295
302
  return String(result);
296
303
  } catch (error) {
@@ -315,6 +322,52 @@ var init_processor = __esm({
315
322
  const fileName = basename(filePath, extname(filePath));
316
323
  return fileName;
317
324
  }
325
+ /**
326
+ * Markdownコンテンツから見出しを抽出する
327
+ *
328
+ * @param content - Markdownコンテンツ
329
+ * @returns 見出しの配列(h2, h3のみ)
330
+ * @private
331
+ */
332
+ extractHeadings(content) {
333
+ const headings = [];
334
+ const slugger = new GithubSlugger();
335
+ try {
336
+ const tree = unified().use(remarkParse).parse(content);
337
+ visit(tree, "heading", (node) => {
338
+ if (node.depth === 2 || node.depth === 3) {
339
+ const text = this.extractTextFromNode(node.children);
340
+ const id = slugger.slug(text);
341
+ headings.push({
342
+ id,
343
+ text,
344
+ level: node.depth
345
+ });
346
+ }
347
+ });
348
+ } catch (error) {
349
+ console.warn("Failed to extract headings:", error);
350
+ }
351
+ return headings;
352
+ }
353
+ /**
354
+ * 見出しノードの子要素からテキストを抽出する
355
+ *
356
+ * @param children - 見出しノードの子要素
357
+ * @returns テキスト
358
+ * @private
359
+ */
360
+ extractTextFromNode(children) {
361
+ return children.map((child) => {
362
+ if (child.type === "text") {
363
+ return child.value;
364
+ }
365
+ if ("children" in child && Array.isArray(child.children)) {
366
+ return this.extractTextFromNode(child.children);
367
+ }
368
+ return "";
369
+ }).join("");
370
+ }
318
371
  };
319
372
  }
320
373
  });
@@ -441,16 +494,17 @@ var init_router = __esm({
441
494
  /**
442
495
  * ファイルパスからルートを作成
443
496
  *
444
- * @param filePath - MDXまたはMDファイルのパス
445
- * @param baseDir - ベースディレクトリパス
497
+ * @param filePath - MDXまたはMDファイルの絶対パス
498
+ * @param baseDir - ベースディレクトリパス(docsDir)
446
499
  * @returns 生成されたルート
447
500
  */
448
501
  async createRoute(filePath, baseDir) {
449
502
  const frontmatter = await this.extractFrontmatter(filePath);
450
503
  const urlPath = this.filePathToUrlPath(filePath, baseDir);
504
+ const relativeFilePath = path.relative(baseDir, filePath);
451
505
  return {
452
506
  path: urlPath,
453
- filePath,
507
+ filePath: relativeFilePath,
454
508
  frontmatter
455
509
  };
456
510
  }
@@ -508,12 +562,17 @@ var routing_middleware_exports = {};
508
562
  __export(routing_middleware_exports, {
509
563
  createRoutingMiddleware: () => createRoutingMiddleware
510
564
  });
511
- var __filename$1, __dirname$1, createRoutingMiddleware, handleAllRoutesRequest, handleRouteRequest, handleMDXRequest, handle500;
565
+ var __filename$1, __dirname$1, hasFileExtension, createRoutingMiddleware, handleAllRoutesRequest, handleRouteRequest, handleMDXRequest, handle500;
512
566
  var init_routing_middleware = __esm({
513
567
  "src/server/routing-middleware.ts"() {
514
568
  init_router();
515
569
  __filename$1 = fileURLToPath(import.meta.url);
516
570
  __dirname$1 = dirname(__filename$1);
571
+ hasFileExtension = (urlPath) => {
572
+ const lastSegment = urlPath.split("/").pop() || "";
573
+ const dotIndex = lastSegment.lastIndexOf(".");
574
+ return dotIndex > 0;
575
+ };
517
576
  createRoutingMiddleware = (server, options) => {
518
577
  const { config, cwd } = options;
519
578
  const routeGenerator = new RouteGenerator();
@@ -564,7 +623,8 @@ var init_routing_middleware = __esm({
564
623
  }
565
624
  const urlPath = url.split("?")[0];
566
625
  if (urlPath === "/__chronoter_mdx__") {
567
- return handleMDXRequest(req, res, cwd);
626
+ const docsDir = config.docsDir ? resolve(cwd, config.docsDir) : cwd;
627
+ return handleMDXRequest(req, res, docsDir);
568
628
  }
569
629
  if (urlPath === "/__chronoter_routes__") {
570
630
  return handleRouteRequest(req, res, getRoutes, routeGenerator);
@@ -574,7 +634,7 @@ var init_routing_middleware = __esm({
574
634
  }
575
635
  if (urlPath.startsWith("/@") || // Vite内部リクエスト
576
636
  urlPath.startsWith("/node_modules") || urlPath.startsWith("/src/") || // Viteが処理するソースファイル
577
- urlPath.includes(".") && !urlPath.endsWith("/") && !urlPath.startsWith("/src/")) {
637
+ hasFileExtension(urlPath) && !urlPath.endsWith("/") && !urlPath.startsWith("/src/")) {
578
638
  return next();
579
639
  }
580
640
  try {
@@ -684,7 +744,7 @@ var init_routing_middleware = __esm({
684
744
  );
685
745
  }
686
746
  };
687
- handleMDXRequest = async (req, res, cwd) => {
747
+ handleMDXRequest = async (req, res, docsDir) => {
688
748
  try {
689
749
  const url = new URL(req.url || "", `http://${req.headers.host}`);
690
750
  const filePath = url.searchParams.get("path");
@@ -694,8 +754,8 @@ var init_routing_middleware = __esm({
694
754
  res.end(JSON.stringify({ error: "Missing 'path' query parameter" }));
695
755
  return;
696
756
  }
697
- const absolutePath = resolve(cwd, filePath);
698
- if (!absolutePath.startsWith(cwd)) {
757
+ const absolutePath = resolve(docsDir, filePath);
758
+ if (!absolutePath.startsWith(docsDir)) {
699
759
  res.statusCode = 403;
700
760
  res.setHeader("Content-Type", "application/json");
701
761
  res.end(JSON.stringify({ error: "Access denied" }));
@@ -710,7 +770,8 @@ var init_routing_middleware = __esm({
710
770
  JSON.stringify({
711
771
  code: processedMDX.code,
712
772
  frontmatter: processedMDX.frontmatter,
713
- slug: processedMDX.slug
773
+ slug: processedMDX.slug,
774
+ headings: processedMDX.headings
714
775
  })
715
776
  );
716
777
  } catch (error) {
@@ -103,6 +103,8 @@
103
103
  --color-sidebar-accent-foreground: oklch(0.205 0 0);
104
104
  --color-sidebar-border: oklch(0.922 0 0);
105
105
  --color-sidebar-ring: oklch(0.708 0 0);
106
+ --color-sidebar-active: oklch(0.95 0.02 264);
107
+ --color-sidebar-active-foreground: oklch(58.42% 0.2274 263.02);
106
108
  }
107
109
  }
108
110
  @layer base {
@@ -378,6 +380,9 @@
378
380
  .top-4 {
379
381
  top: calc(var(--spacing) * 4);
380
382
  }
383
+ .top-20 {
384
+ top: calc(var(--spacing) * 20);
385
+ }
381
386
  .top-\[1px\] {
382
387
  top: 1px;
383
388
  }
@@ -979,6 +984,9 @@
979
984
  .block {
980
985
  display: block;
981
986
  }
987
+ .contents {
988
+ display: contents;
989
+ }
982
990
  .flex {
983
991
  display: flex;
984
992
  }
@@ -1142,6 +1150,9 @@
1142
1150
  .max-h-\[300px\] {
1143
1151
  max-height: 300px;
1144
1152
  }
1153
+ .max-h-\[calc\(100vh-5rem\)\] {
1154
+ max-height: calc(100vh - 5rem);
1155
+ }
1145
1156
  .min-h-0 {
1146
1157
  min-height: calc(var(--spacing) * 0);
1147
1158
  }
@@ -1199,6 +1210,18 @@
1199
1210
  .w-16 {
1200
1211
  width: calc(var(--spacing) * 16);
1201
1212
  }
1213
+ .w-24 {
1214
+ width: calc(var(--spacing) * 24);
1215
+ }
1216
+ .w-32 {
1217
+ width: calc(var(--spacing) * 32);
1218
+ }
1219
+ .w-40 {
1220
+ width: calc(var(--spacing) * 40);
1221
+ }
1222
+ .w-48 {
1223
+ width: calc(var(--spacing) * 48);
1224
+ }
1202
1225
  .w-64 {
1203
1226
  width: calc(var(--spacing) * 64);
1204
1227
  }
@@ -1489,9 +1512,19 @@
1489
1512
  .gap-7 {
1490
1513
  gap: calc(var(--spacing) * 7);
1491
1514
  }
1515
+ .gap-8 {
1516
+ gap: calc(var(--spacing) * 8);
1517
+ }
1492
1518
  .gap-\[--spacing\(var\(--gap\)\)\] {
1493
1519
  gap: calc(var(--spacing) * var(--gap));
1494
1520
  }
1521
+ .space-y-1 {
1522
+ :where(& > :not(:last-child)) {
1523
+ --tw-space-y-reverse: 0;
1524
+ margin-block-start: calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));
1525
+ margin-block-end: calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)));
1526
+ }
1527
+ }
1495
1528
  .space-y-2 {
1496
1529
  :where(& > :not(:last-child)) {
1497
1530
  --tw-space-y-reverse: 0;
@@ -1499,6 +1532,13 @@
1499
1532
  margin-block-end: calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)));
1500
1533
  }
1501
1534
  }
1535
+ .space-y-3 {
1536
+ :where(& > :not(:last-child)) {
1537
+ --tw-space-y-reverse: 0;
1538
+ margin-block-start: calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));
1539
+ margin-block-end: calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)));
1540
+ }
1541
+ }
1502
1542
  .gap-y-0\.5 {
1503
1543
  row-gap: calc(var(--spacing) * 0.5);
1504
1544
  }
@@ -1606,6 +1646,10 @@
1606
1646
  border-left-style: var(--tw-border-style);
1607
1647
  border-left-width: 1px;
1608
1648
  }
1649
+ .border-l-2 {
1650
+ border-left-style: var(--tw-border-style);
1651
+ border-left-width: 2px;
1652
+ }
1609
1653
  .border-dashed {
1610
1654
  --tw-border-style: dashed;
1611
1655
  border-style: dashed;
@@ -1826,6 +1870,9 @@
1826
1870
  .pl-4 {
1827
1871
  padding-left: calc(var(--spacing) * 4);
1828
1872
  }
1873
+ .pl-7 {
1874
+ padding-left: calc(var(--spacing) * 7);
1875
+ }
1829
1876
  .pl-8 {
1830
1877
  padding-left: calc(var(--spacing) * 8);
1831
1878
  }
@@ -1838,6 +1885,9 @@
1838
1885
  .align-middle {
1839
1886
  vertical-align: middle;
1840
1887
  }
1888
+ .font-mono {
1889
+ font-family: var(--font-mono);
1890
+ }
1841
1891
  .font-sans {
1842
1892
  font-family: var(--font-sans);
1843
1893
  }
@@ -2789,6 +2839,16 @@
2789
2839
  border-bottom-width: 0px;
2790
2840
  }
2791
2841
  }
2842
+ .hover\:border-muted-foreground\/40 {
2843
+ &:hover {
2844
+ @media (hover: hover) {
2845
+ border-color: color-mix(in srgb, oklch(56.41% 0.0194 285.88) 40%, transparent);
2846
+ @supports (color: color-mix(in lab, red, red)) {
2847
+ border-color: color-mix(in oklab, var(--color-muted-foreground) 40%, transparent);
2848
+ }
2849
+ }
2850
+ }
2851
+ }
2792
2852
  .hover\:bg-accent {
2793
2853
  &:hover {
2794
2854
  @media (hover: hover) {
@@ -3397,9 +3457,9 @@
3397
3457
  }
3398
3458
  }
3399
3459
  }
3400
- .data-\[active\=true\]\:bg-sidebar-accent {
3460
+ .data-\[active\=true\]\:bg-sidebar-active {
3401
3461
  &[data-active=true] {
3402
- background-color: var(--color-sidebar-accent);
3462
+ background-color: var(--color-sidebar-active);
3403
3463
  }
3404
3464
  }
3405
3465
  .data-\[active\=true\]\:font-medium {
@@ -3413,9 +3473,9 @@
3413
3473
  color: var(--color-accent-foreground);
3414
3474
  }
3415
3475
  }
3416
- .data-\[active\=true\]\:text-sidebar-accent-foreground {
3476
+ .data-\[active\=true\]\:text-sidebar-active-foreground {
3417
3477
  &[data-active=true] {
3418
- color: var(--color-sidebar-accent-foreground);
3478
+ color: var(--color-sidebar-active-foreground);
3419
3479
  }
3420
3480
  }
3421
3481
  .data-\[active\=true\]\:hover\:bg-accent {
@@ -4209,6 +4269,11 @@
4209
4269
  top: calc(var(--spacing) * 16);
4210
4270
  }
4211
4271
  }
4272
+ .md\:top-\[5\.5rem\] {
4273
+ @media (width >= 48rem) {
4274
+ top: 5.5rem;
4275
+ }
4276
+ }
4212
4277
  .md\:block {
4213
4278
  @media (width >= 48rem) {
4214
4279
  display: block;
@@ -4229,6 +4294,11 @@
4229
4294
  height: calc(100svh - 4rem);
4230
4295
  }
4231
4296
  }
4297
+ .md\:max-h-\[calc\(100vh-5\.5rem\)\] {
4298
+ @media (width >= 48rem) {
4299
+ max-height: calc(100vh - 5.5rem);
4300
+ }
4301
+ }
4232
4302
  .md\:w-\[var\(--radix-navigation-menu-viewport-width\)\] {
4233
4303
  @media (width >= 48rem) {
4234
4304
  width: var(--radix-navigation-menu-viewport-width);
@@ -4331,11 +4401,26 @@
4331
4401
  }
4332
4402
  }
4333
4403
  }
4404
+ .lg\:top-24 {
4405
+ @media (width >= 64rem) {
4406
+ top: calc(var(--spacing) * 24);
4407
+ }
4408
+ }
4409
+ .lg\:max-h-\[calc\(100vh-6rem\)\] {
4410
+ @media (width >= 64rem) {
4411
+ max-height: calc(100vh - 6rem);
4412
+ }
4413
+ }
4334
4414
  .lg\:p-8 {
4335
4415
  @media (width >= 64rem) {
4336
4416
  padding: calc(var(--spacing) * 8);
4337
4417
  }
4338
4418
  }
4419
+ .xl\:block {
4420
+ @media (width >= 80rem) {
4421
+ display: block;
4422
+ }
4423
+ }
4339
4424
  .\@md\/field-group\:flex-row {
4340
4425
  @container field-group (width >= 28rem) {
4341
4426
  flex-direction: row;
@@ -5267,14 +5352,130 @@
5267
5352
  --color-sidebar-accent-foreground: oklch(0.985 0 0);
5268
5353
  --color-sidebar-border: oklch(1 0 0 / 10%);
5269
5354
  --color-sidebar-ring: oklch(0.439 0 0);
5355
+ --color-sidebar-active: oklch(0.30 0.05 264);
5356
+ --color-sidebar-active-foreground: oklch(67.17% 0.2174 263.71);
5357
+ }
5358
+ }
5359
+ @layer base {
5360
+ * {
5361
+ border-color: var(--color-border);
5270
5362
  }
5363
+ body {
5364
+ background-color: var(--color-background);
5365
+ color: var(--color-foreground);
5366
+ }
5367
+ }
5368
+ .theme-blue {
5369
+ --color-primary: oklch(58.42% 0.2274 263.02);
5370
+ --color-primary-foreground: oklch(98.04% 0.0058 264.53);
5371
+ --color-ring: oklch(58.42% 0.2274 263.02);
5372
+ --color-sidebar-active: oklch(0.95 0.02 264);
5373
+ --color-sidebar-active-foreground: oklch(58.42% 0.2274 263.02);
5374
+ }
5375
+ .theme-blue:where(.dark, .dark *) {
5376
+ --color-primary: oklch(67.17% 0.2174 263.71);
5377
+ --color-primary-foreground: oklch(20.09% 0.0211 285.88);
5378
+ --color-ring: oklch(54.89% 0.2068 263.71);
5379
+ --color-sidebar-active: oklch(0.30 0.05 264);
5380
+ --color-sidebar-active-foreground: oklch(67.17% 0.2174 263.71);
5381
+ }
5382
+ .theme-violet {
5383
+ --color-primary: oklch(58.42% 0.22 285);
5384
+ --color-primary-foreground: oklch(98.04% 0.0058 285);
5385
+ --color-ring: oklch(58.42% 0.22 285);
5386
+ --color-sidebar-active: oklch(0.95 0.02 285);
5387
+ --color-sidebar-active-foreground: oklch(58.42% 0.22 285);
5388
+ }
5389
+ .theme-violet:where(.dark, .dark *) {
5390
+ --color-primary: oklch(67.17% 0.20 285);
5391
+ --color-primary-foreground: oklch(20.09% 0.02 285);
5392
+ --color-ring: oklch(54.89% 0.19 285);
5393
+ --color-sidebar-active: oklch(0.30 0.05 285);
5394
+ --color-sidebar-active-foreground: oklch(67.17% 0.20 285);
5395
+ }
5396
+ .theme-slate {
5397
+ --color-primary: oklch(45% 0.03 250);
5398
+ --color-primary-foreground: oklch(98% 0.005 250);
5399
+ --color-ring: oklch(45% 0.03 250);
5400
+ --color-sidebar-active: oklch(0.95 0.01 250);
5401
+ --color-sidebar-active-foreground: oklch(45% 0.03 250);
5402
+ }
5403
+ .theme-slate:where(.dark, .dark *) {
5404
+ --color-primary: oklch(70% 0.03 250);
5405
+ --color-primary-foreground: oklch(20% 0.02 250);
5406
+ --color-ring: oklch(55% 0.03 250);
5407
+ --color-sidebar-active: oklch(0.30 0.02 250);
5408
+ --color-sidebar-active-foreground: oklch(70% 0.03 250);
5409
+ }
5410
+ .theme-green {
5411
+ --color-primary: oklch(60% 0.18 150);
5412
+ --color-primary-foreground: oklch(98% 0.01 150);
5413
+ --color-ring: oklch(60% 0.18 150);
5414
+ --color-sidebar-active: oklch(0.95 0.03 150);
5415
+ --color-sidebar-active-foreground: oklch(60% 0.18 150);
5416
+ }
5417
+ .theme-green:where(.dark, .dark *) {
5418
+ --color-primary: oklch(70% 0.17 150);
5419
+ --color-primary-foreground: oklch(20% 0.02 150);
5420
+ --color-ring: oklch(55% 0.16 150);
5421
+ --color-sidebar-active: oklch(0.30 0.05 150);
5422
+ --color-sidebar-active-foreground: oklch(70% 0.17 150);
5423
+ }
5424
+ .theme-orange {
5425
+ --color-primary: oklch(65% 0.18 50);
5426
+ --color-primary-foreground: oklch(98% 0.01 50);
5427
+ --color-ring: oklch(65% 0.18 50);
5428
+ --color-sidebar-active: oklch(0.95 0.03 50);
5429
+ --color-sidebar-active-foreground: oklch(65% 0.18 50);
5430
+ }
5431
+ .theme-orange:where(.dark, .dark *) {
5432
+ --color-primary: oklch(72% 0.17 50);
5433
+ --color-primary-foreground: oklch(20% 0.02 50);
5434
+ --color-ring: oklch(58% 0.16 50);
5435
+ --color-sidebar-active: oklch(0.30 0.05 50);
5436
+ --color-sidebar-active-foreground: oklch(72% 0.17 50);
5437
+ }
5438
+ .theme-red {
5439
+ --color-primary: oklch(60% 0.22 25);
5440
+ --color-primary-foreground: oklch(98% 0.01 25);
5441
+ --color-ring: oklch(60% 0.22 25);
5442
+ --color-sidebar-active: oklch(0.95 0.03 25);
5443
+ --color-sidebar-active-foreground: oklch(60% 0.22 25);
5444
+ }
5445
+ .theme-red:where(.dark, .dark *) {
5446
+ --color-primary: oklch(68% 0.20 25);
5447
+ --color-primary-foreground: oklch(20% 0.02 25);
5448
+ --color-ring: oklch(55% 0.19 25);
5449
+ --color-sidebar-active: oklch(0.30 0.05 25);
5450
+ --color-sidebar-active-foreground: oklch(68% 0.20 25);
5451
+ }
5452
+ .theme-rose {
5453
+ --color-primary: oklch(60% 0.20 350);
5454
+ --color-primary-foreground: oklch(98% 0.01 350);
5455
+ --color-ring: oklch(60% 0.20 350);
5456
+ --color-sidebar-active: oklch(0.95 0.03 350);
5457
+ --color-sidebar-active-foreground: oklch(60% 0.20 350);
5458
+ }
5459
+ .theme-rose:where(.dark, .dark *) {
5460
+ --color-primary: oklch(68% 0.18 350);
5461
+ --color-primary-foreground: oklch(20% 0.02 350);
5462
+ --color-ring: oklch(55% 0.17 350);
5463
+ --color-sidebar-active: oklch(0.30 0.05 350);
5464
+ --color-sidebar-active-foreground: oklch(68% 0.18 350);
5271
5465
  }
5272
- * {
5273
- border-color: var(--color-border);
5466
+ .theme-zinc {
5467
+ --color-primary: oklch(50% 0 0);
5468
+ --color-primary-foreground: oklch(98% 0 0);
5469
+ --color-ring: oklch(50% 0 0);
5470
+ --color-sidebar-active: oklch(0.95 0 0);
5471
+ --color-sidebar-active-foreground: oklch(50% 0 0);
5274
5472
  }
5275
- body {
5276
- background-color: var(--color-background);
5277
- color: var(--color-foreground);
5473
+ .theme-zinc:where(.dark, .dark *) {
5474
+ --color-primary: oklch(70% 0 0);
5475
+ --color-primary-foreground: oklch(20% 0 0);
5476
+ --color-ring: oklch(55% 0 0);
5477
+ --color-sidebar-active: oklch(0.30 0 0);
5478
+ --color-sidebar-active-foreground: oklch(70% 0 0);
5278
5479
  }
5279
5480
  @property --tw-translate-x { syntax: "*"; inherits: false; initial-value: 0; }
5280
5481
  @property --tw-translate-y { syntax: "*"; inherits: false; initial-value: 0; }