yumiamd 0.1.21 → 0.1.23

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/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runCli
4
- } from "./chunk-TJR6MU2I.js";
4
+ } from "./chunk-GKERS3TA.js";
5
5
 
6
6
  // src/bin.ts
7
7
  var result = await runCli(process.argv);
@@ -31,12 +31,13 @@ function createList(items, ordered = false) {
31
31
  items: normalizedItems
32
32
  };
33
33
  }
34
- function createImage(src, alt, caption) {
34
+ function createImage(src, alt, caption, options) {
35
35
  return {
36
36
  type: "image",
37
37
  src,
38
38
  ...alt ? { alt } : {},
39
- ...caption ? { caption } : {}
39
+ ...caption ? { caption } : {},
40
+ ...options || {}
40
41
  };
41
42
  }
42
43
  function createCard(elements, title, variant) {
@@ -1501,6 +1502,147 @@ var NativeYumiaParser = class {
1501
1502
  }
1502
1503
  return { element: createList(items, false), nextIdx };
1503
1504
  }
1505
+ case "image":
1506
+ case "img": {
1507
+ const srcMatch = tok.args.match(/^(?:src=)?["']([^"']+)["']/);
1508
+ const altMatch = tok.args.match(/\balt=["']([^"']+)["']/);
1509
+ const capMatch = tok.args.match(/\bcaption=["']([^"']+)["']/);
1510
+ const fitMatch = tok.args.match(/\bfit=["']?([^"'\s]+)["']?/);
1511
+ const widthMatch = tok.args.match(/\bwidth=["']?([^"'\s]+)["']?/);
1512
+ const heightMatch = tok.args.match(/\bheight=["']?([^"'\s]+)["']?/);
1513
+ const radiusMatch = tok.args.match(/\bradius=["']?([^"'\s]+)["']?/);
1514
+ const aspectMatch = tok.args.match(/\baspect=["']?([^"'\s]+)["']?/);
1515
+ const src = srcMatch ? srcMatch[1] : this.stripQuotes(tok.args);
1516
+ return {
1517
+ element: createImage(src, altMatch ? altMatch[1] : void 0, capMatch ? capMatch[1] : void 0, {
1518
+ fit: fitMatch ? fitMatch[1] : void 0,
1519
+ width: widthMatch ? widthMatch[1] : void 0,
1520
+ height: heightMatch ? heightMatch[1] : void 0,
1521
+ radius: radiusMatch ? radiusMatch[1] : void 0,
1522
+ aspectRatio: aspectMatch ? aspectMatch[1] : void 0
1523
+ }),
1524
+ nextIdx: idx + 1
1525
+ };
1526
+ }
1527
+ case "chart": {
1528
+ const typeMatch = tok.args.match(/type=["']?([^"'\s]+)["']?/);
1529
+ const titleMatch = tok.args.match(/title=["']([^"']+)["']/);
1530
+ const chartType = typeMatch ? typeMatch[1] : "bar";
1531
+ const title = titleMatch ? titleMatch[1] : void 0;
1532
+ const labels = [];
1533
+ const series = [];
1534
+ let nextIdx = idx + 1;
1535
+ while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
1536
+ const sub = tokens[nextIdx];
1537
+ if (sub.command === "labels") {
1538
+ const rawLabels = sub.args.split(",").map((l) => this.stripQuotes(l.trim()));
1539
+ labels.push(...rawLabels);
1540
+ } else if (sub.command === "series") {
1541
+ const sNameMatch = sub.args.match(/^["']?([^:"']+):/);
1542
+ const name = sNameMatch ? sNameMatch[1].trim() : "Series";
1543
+ const dataStr = sub.args.replace(/^["']?[^:"']+:?\s*/, "").replace(/["']$/, "");
1544
+ const values = dataStr.split(",").map((v) => parseFloat(v.trim())).filter((v) => !isNaN(v));
1545
+ series.push({ name, values });
1546
+ }
1547
+ nextIdx++;
1548
+ }
1549
+ if (labels.length === 0)
1550
+ labels.push("A", "B", "C");
1551
+ if (series.length === 0)
1552
+ series.push({ name: "Data", values: [10, 20, 30] });
1553
+ return { element: createChart(chartType, labels, series, title), nextIdx };
1554
+ }
1555
+ case "compare": {
1556
+ const leftTitleMatch = tok.args.match(/left(?:Title)?=["']([^"']+)["']/);
1557
+ const rightTitleMatch = tok.args.match(/right(?:Title)?=["']([^"']+)["']/);
1558
+ const leftTitle = leftTitleMatch ? leftTitleMatch[1] : void 0;
1559
+ const rightTitle = rightTitleMatch ? rightTitleMatch[1] : void 0;
1560
+ const leftEls = [];
1561
+ const rightEls = [];
1562
+ let currentSide = "left";
1563
+ let nextIdx = idx + 1;
1564
+ while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
1565
+ const sub = tokens[nextIdx];
1566
+ if (sub.command === "left") {
1567
+ currentSide = "left";
1568
+ nextIdx++;
1569
+ continue;
1570
+ } else if (sub.command === "right") {
1571
+ currentSide = "right";
1572
+ nextIdx++;
1573
+ continue;
1574
+ }
1575
+ const childRes = this.parseElement(tokens, nextIdx);
1576
+ if (childRes) {
1577
+ if (currentSide === "left")
1578
+ leftEls.push(childRes.element);
1579
+ else
1580
+ rightEls.push(childRes.element);
1581
+ nextIdx = childRes.nextIdx;
1582
+ } else {
1583
+ nextIdx++;
1584
+ }
1585
+ }
1586
+ return { element: createCompare(leftEls, rightEls, leftTitle, rightTitle), nextIdx };
1587
+ }
1588
+ case "timeline": {
1589
+ const layoutMatch = tok.args.match(/layout=["']?(horizontal|vertical)["']?/);
1590
+ const layout = layoutMatch ? layoutMatch[1] : "horizontal";
1591
+ const items = [];
1592
+ let nextIdx = idx + 1;
1593
+ while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
1594
+ const sub = tokens[nextIdx];
1595
+ if (sub.command === "item") {
1596
+ const dateMatch = sub.args.match(/date=["']([^"']+)["']/);
1597
+ const titleMatch = sub.args.match(/title=["']([^"']+)["']/);
1598
+ const descMatch = sub.args.match(/desc(?:ription)?=["']([^"']+)["']/);
1599
+ items.push({
1600
+ date: dateMatch ? dateMatch[1] : "2026",
1601
+ title: titleMatch ? titleMatch[1] : "Milestone",
1602
+ description: descMatch ? descMatch[1] : void 0
1603
+ });
1604
+ }
1605
+ nextIdx++;
1606
+ }
1607
+ return { element: createTimeline(items, layout), nextIdx };
1608
+ }
1609
+ case "mermaid": {
1610
+ const mLines = [];
1611
+ let nextIdx = idx + 1;
1612
+ while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
1613
+ mLines.push(tokens[nextIdx].text);
1614
+ nextIdx++;
1615
+ }
1616
+ return { element: createMermaid(mLines.join("\n")), nextIdx };
1617
+ }
1618
+ case "math": {
1619
+ let expr = this.stripQuotes(tok.args);
1620
+ let nextIdx = idx + 1;
1621
+ if (!expr) {
1622
+ const mathLines = [];
1623
+ while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
1624
+ mathLines.push(tokens[nextIdx].text);
1625
+ nextIdx++;
1626
+ }
1627
+ expr = mathLines.join("\n");
1628
+ }
1629
+ return { element: createMath(expr), nextIdx };
1630
+ }
1631
+ case "table": {
1632
+ let headers = void 0;
1633
+ const rows = [];
1634
+ let nextIdx = idx + 1;
1635
+ while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
1636
+ const sub = tokens[nextIdx];
1637
+ if (sub.command === "headers" || sub.command === "header") {
1638
+ headers = sub.args.split(",").map((h) => this.stripQuotes(h.trim()));
1639
+ } else if (sub.command === "row") {
1640
+ rows.push(sub.args.split(",").map((c) => this.stripQuotes(c.trim())));
1641
+ }
1642
+ nextIdx++;
1643
+ }
1644
+ return { element: createTable(rows, headers), nextIdx };
1645
+ }
1504
1646
  case "quote": {
1505
1647
  const authorMatch = tok.args.match(/\bauthor=["']([^"']+)["']/);
1506
1648
  const textLines = [];
@@ -2333,36 +2475,36 @@ var terminalTheme = {
2333
2475
  },
2334
2476
  radius: {
2335
2477
  none: 0,
2336
- sm: 0,
2337
- md: 0,
2338
- lg: 0,
2339
- xl: 0,
2340
- full: 0,
2341
- default: 0
2478
+ sm: 4,
2479
+ md: 8,
2480
+ lg: 12,
2481
+ xl: 16,
2482
+ full: 9999,
2483
+ default: 10
2342
2484
  },
2343
2485
  shadows: {
2344
2486
  none: "none",
2345
- sm: "none",
2346
- md: "none",
2347
- lg: "none",
2348
- glow: "0 0 15px rgba(0, 255, 102, 0.4)"
2487
+ sm: "0 2px 4px rgba(0, 0, 0, 0.3)",
2488
+ md: "0 4px 12px rgba(0, 0, 0, 0.4)",
2489
+ lg: "0 10px 24px rgba(0, 0, 0, 0.5)",
2490
+ glow: "0 0 16px rgba(0, 255, 102, 0.35)"
2349
2491
  },
2350
2492
  components: {
2351
2493
  card: {
2352
- background: "#141A14",
2353
- borderColor: "#00FF66",
2354
- borderRadius: 0,
2494
+ background: "#111711",
2495
+ borderColor: "rgba(0, 255, 102, 0.35)",
2496
+ borderRadius: 12,
2355
2497
  padding: 24
2356
2498
  },
2357
2499
  metric: {
2358
2500
  valueColor: "#00FF66",
2359
2501
  labelColor: "#4E7A4E",
2360
- borderRadius: 0
2502
+ borderRadius: 12
2361
2503
  },
2362
2504
  code: {
2363
- background: "#070A07",
2505
+ background: "#080C08",
2364
2506
  textColor: "#00FF66",
2365
- borderRadius: 0
2507
+ borderRadius: 8
2366
2508
  },
2367
2509
  table: {
2368
2510
  headerBackground: "#1F331F",
@@ -4754,6 +4896,8 @@ var HtmlRenderer = class {
4754
4896
  const aspectRatio = presentation.metadata.aspectRatio || "16:9";
4755
4897
  const is43 = aspectRatio === "4:3";
4756
4898
  const ratioAspect = is43 ? "4 / 3" : "16 / 9";
4899
+ const ratioW = is43 ? 4 : 16;
4900
+ const ratioH = is43 ? 3 : 9;
4757
4901
  const options = context.options || {};
4758
4902
  const liveReloadScript = options.liveReload ? `
4759
4903
  <!-- YumiaMD Live Reload -->
@@ -4796,6 +4940,7 @@ var HtmlRenderer = class {
4796
4940
  <title>${this.escapeHtml(title)}</title>
4797
4941
  <link rel="preconnect" href="https://fonts.googleapis.com">
4798
4942
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
4943
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Cinzel:wght@500;700;900&family=Fira+Code:wght@400;500;600;700&family=Inter:wght@300;400;500;600;700;800;900&family=JetBrains+Mono:ital,wght@0,400;0,600;0,700;0,800;1,400&family=Orbitron:wght@500;700;900&family=Outfit:wght@400;500;600;700;800;900&family=Playfair+Display:ital,wght@0,500;0,700;0,900;1,400;1,700&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=Space+Grotesk:wght@400;600;700&display=swap">
4799
4944
  ${customStyles}
4800
4945
  ${customScripts}
4801
4946
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" crossorigin="anonymous">
@@ -4869,6 +5014,8 @@ var HtmlRenderer = class {
4869
5014
  --yumia-radius-card: ${theme.components?.card?.borderRadius ?? theme.radius.default}px;
4870
5015
  --yumia-shadow-glow: ${theme.shadows?.glow || "none"};
4871
5016
  --yumia-ratio: ${ratioAspect};
5017
+ --yumia-ratio-w: ${ratioW};
5018
+ --yumia-ratio-h: ${ratioH};
4872
5019
  }
4873
5020
 
4874
5021
  * {
@@ -4890,19 +5037,34 @@ var HtmlRenderer = class {
4890
5037
  user-select: none;
4891
5038
  }
4892
5039
 
5040
+ #deck-container {
5041
+ position: relative;
5042
+ width: 100vw;
5043
+ height: 100vh;
5044
+ display: flex;
5045
+ align-items: center;
5046
+ justify-content: center;
5047
+ overflow: hidden;
5048
+ background: #050508;
5049
+ }
5050
+
4893
5051
  #yumia-deck {
4894
5052
  position: relative;
4895
5053
  width: 100%;
4896
5054
  height: 100%;
5055
+ max-width: calc(100vh * var(--yumia-ratio-w) / var(--yumia-ratio-h));
5056
+ max-height: calc(100vw * var(--yumia-ratio-h) / var(--yumia-ratio-w));
5057
+ aspect-ratio: var(--yumia-ratio);
4897
5058
  display: flex;
4898
5059
  align-items: center;
4899
5060
  justify-content: center;
4900
5061
  }
4901
5062
 
4902
5063
  .yumia-slide-wrapper {
4903
- position: relative;
4904
- width: min(94vw, calc(94vh * (${is43 ? "4 / 3" : "16 / 9"})));
4905
- height: min(calc(94vw / (${is43 ? "4 / 3" : "16 / 9"})), 94vh);
5064
+ position: absolute;
5065
+ inset: 0;
5066
+ width: 100%;
5067
+ height: 100%;
4906
5068
  aspect-ratio: var(--yumia-ratio);
4907
5069
  background-color: var(--yumia-bg);
4908
5070
  border-radius: var(--yumia-radius-default);
@@ -4910,7 +5072,10 @@ var HtmlRenderer = class {
4910
5072
  overflow: hidden;
4911
5073
  display: none;
4912
5074
  flex-direction: column;
4913
- padding: 4.5% 5.5%;
5075
+ justify-content: flex-start;
5076
+ align-items: stretch;
5077
+ padding: clamp(2rem, 4vw, 3.5rem) clamp(2.5rem, 5vw, 4.5rem);
5078
+ box-sizing: border-box;
4914
5079
  animation: fadeIn 0.25s cubic-bezier(0.16, 1, 0.3, 1);
4915
5080
  }
4916
5081
 
@@ -4928,38 +5093,40 @@ var HtmlRenderer = class {
4928
5093
  font-family: var(--yumia-font-heading), system-ui, -apple-system, sans-serif;
4929
5094
  font-weight: 700;
4930
5095
  line-height: var(--yumia-line-height-tight);
4931
- margin-bottom: 0.7em;
5096
+ margin-bottom: 0.4em;
4932
5097
  letter-spacing: var(--yumia-letter-spacing-tight);
4933
5098
  overflow-wrap: break-word;
4934
5099
  word-break: break-word;
4935
5100
  }
4936
5101
 
4937
5102
  h1 {
4938
- font-size: clamp(2rem, 3.8vw, 3.4rem);
5103
+ font-size: clamp(1.8rem, 3.2vw, 2.9rem);
4939
5104
  color: var(--yumia-primary);
5105
+ line-height: 1.15;
4940
5106
  }
4941
5107
 
4942
5108
  h2 {
4943
- font-size: clamp(1.6rem, 2.8vw, 2.5rem);
5109
+ font-size: clamp(1.5rem, 2.6vw, 2.3rem);
4944
5110
  color: var(--yumia-text);
5111
+ line-height: 1.2;
4945
5112
  }
4946
5113
 
4947
5114
  h3 {
4948
- font-size: clamp(1.3rem, 2.2vw, 1.9rem);
5115
+ font-size: clamp(1.25rem, 2vw, 1.8rem);
4949
5116
  color: var(--yumia-text);
4950
5117
  }
4951
5118
 
4952
5119
  h4 {
4953
- font-size: clamp(1.1rem, 1.7vw, 1.4rem);
5120
+ font-size: clamp(1.05rem, 1.5vw, 1.35rem);
4954
5121
  color: var(--yumia-muted);
4955
5122
  }
4956
5123
 
4957
5124
  /* Paragraphs */
4958
5125
  p {
4959
- font-size: clamp(1rem, 1.4vw, 1.25rem);
5126
+ font-size: clamp(0.95rem, 1.35vw, 1.2rem);
4960
5127
  line-height: var(--yumia-line-height-normal);
4961
5128
  color: var(--yumia-text);
4962
- margin-bottom: 0.8em;
5129
+ margin-bottom: 0.6em;
4963
5130
  overflow-wrap: break-word;
4964
5131
  }
4965
5132
 
@@ -4984,14 +5151,14 @@ var HtmlRenderer = class {
4984
5151
 
4985
5152
  /* Lists */
4986
5153
  ul, ol {
4987
- font-size: clamp(1rem, 1.35vw, 1.2rem);
4988
- line-height: 1.65;
4989
- margin-bottom: 1em;
5154
+ font-size: clamp(0.95rem, 1.3vw, 1.15rem);
5155
+ line-height: 1.6;
5156
+ margin-bottom: 0.8em;
4990
5157
  padding-left: 1.5em;
4991
5158
  }
4992
5159
 
4993
5160
  li {
4994
- margin-bottom: 0.5em;
5161
+ margin-bottom: 0.4em;
4995
5162
  color: var(--yumia-text);
4996
5163
  }
4997
5164
 
@@ -4999,12 +5166,41 @@ var HtmlRenderer = class {
4999
5166
  color: var(--yumia-primary);
5000
5167
  }
5001
5168
 
5169
+ /* Grid & Stack Layout Containers */
5170
+ .yumia-grid {
5171
+ display: grid;
5172
+ width: 100%;
5173
+ flex: 1;
5174
+ min-height: 0;
5175
+ gap: clamp(1rem, 1.8vw, 1.6rem);
5176
+ align-items: stretch;
5177
+ margin-top: 0.4rem;
5178
+ }
5179
+
5180
+ .yumia-stack {
5181
+ display: flex;
5182
+ width: 100%;
5183
+ flex: 1;
5184
+ min-height: 0;
5185
+ gap: clamp(1rem, 1.8vw, 1.6rem);
5186
+ align-items: stretch;
5187
+ margin-top: 0.4rem;
5188
+ }
5189
+
5190
+ .yumia-stack.stack-horizontal > * {
5191
+ flex: 1 1 0px;
5192
+ min-width: 0;
5193
+ height: 100%;
5194
+ }
5195
+
5002
5196
  /* Columns */
5003
5197
  .yumia-columns {
5004
5198
  display: grid;
5005
- gap: 1.5rem;
5199
+ gap: clamp(1rem, 1.8vw, 1.6rem);
5006
5200
  width: 100%;
5007
- margin: 0.8rem 0;
5201
+ flex: 1;
5202
+ min-height: 0;
5203
+ margin: 0.4rem 0;
5008
5204
  align-items: stretch;
5009
5205
  }
5010
5206
 
@@ -5012,18 +5208,29 @@ var HtmlRenderer = class {
5012
5208
  display: flex;
5013
5209
  flex-direction: column;
5014
5210
  gap: 0.8rem;
5211
+ height: 100%;
5015
5212
  }
5016
5213
 
5017
5214
  /* Cards */
5018
5215
  .yumia-card {
5019
5216
  background: var(--yumia-surface);
5020
5217
  border: 1.5px solid var(--yumia-border);
5021
- border-radius: 12px;
5022
- padding: 1.25rem 1.5rem;
5218
+ border-radius: 14px;
5219
+ padding: clamp(1.2rem, 2vw, 1.8rem);
5023
5220
  display: flex;
5024
5221
  flex-direction: column;
5025
- gap: 0.6rem;
5026
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
5222
+ justify-content: flex-start;
5223
+ gap: 0.7rem;
5224
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
5225
+ height: 100%;
5226
+ min-height: 0;
5227
+ box-sizing: border-box;
5228
+ transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
5229
+ }
5230
+
5231
+ .yumia-card:hover {
5232
+ transform: translateY(-2px);
5233
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
5027
5234
  }
5028
5235
 
5029
5236
  .yumia-card[data-variant="primary"] {
@@ -5047,6 +5254,13 @@ var HtmlRenderer = class {
5047
5254
  color: var(--yumia-success);
5048
5255
  }
5049
5256
 
5257
+ .yumia-card[data-variant="accent"] {
5258
+ border-color: var(--yumia-accent);
5259
+ }
5260
+ .yumia-card[data-variant="accent"] .yumia-card-title {
5261
+ color: var(--yumia-accent);
5262
+ }
5263
+
5050
5264
  .yumia-card[data-variant="info"] {
5051
5265
  border-color: var(--yumia-info);
5052
5266
  }
@@ -5056,30 +5270,41 @@ var HtmlRenderer = class {
5056
5270
 
5057
5271
  .yumia-card-title {
5058
5272
  font-family: var(--yumia-font-heading);
5059
- font-size: 1.25rem;
5273
+ font-size: clamp(1.1rem, 1.6vw, 1.35rem);
5060
5274
  font-weight: 700;
5061
5275
  color: var(--yumia-primary);
5062
- margin-bottom: 0.3rem;
5276
+ margin-bottom: 0.2rem;
5063
5277
  }
5064
5278
 
5065
5279
  /* Metrics */
5066
5280
  .yumia-metric {
5067
5281
  background: var(--yumia-surface);
5068
5282
  border: 1.5px solid var(--yumia-border);
5069
- border-radius: 12px;
5070
- padding: 1rem 1.2rem;
5283
+ border-radius: 14px;
5284
+ padding: clamp(1.4rem, 2.5vw, 2.4rem) clamp(1rem, 2vw, 1.8rem);
5071
5285
  display: flex;
5072
5286
  flex-direction: column;
5073
5287
  align-items: center;
5074
5288
  justify-content: center;
5075
5289
  text-align: center;
5076
- gap: 0.25rem;
5290
+ gap: 0.5rem;
5291
+ height: 100%;
5292
+ min-height: 150px;
5293
+ box-sizing: border-box;
5294
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
5295
+ transition: transform 0.2s ease, border-color 0.2s ease;
5296
+ }
5297
+
5298
+ .yumia-metric:hover {
5299
+ transform: translateY(-2px);
5077
5300
  }
5078
5301
 
5079
5302
  .yumia-metric[data-variant="primary"] { border-color: var(--yumia-primary); }
5080
5303
  .yumia-metric[data-variant="primary"] .yumia-metric-value { color: var(--yumia-primary); }
5081
5304
  .yumia-metric[data-variant="success"] { border-color: var(--yumia-success); }
5082
5305
  .yumia-metric[data-variant="success"] .yumia-metric-value { color: var(--yumia-success); }
5306
+ .yumia-metric[data-variant="accent"] { border-color: var(--yumia-accent); }
5307
+ .yumia-metric[data-variant="accent"] .yumia-metric-value { color: var(--yumia-accent); }
5083
5308
  .yumia-metric[data-variant="info"] { border-color: var(--yumia-info); }
5084
5309
  .yumia-metric[data-variant="info"] .yumia-metric-value { color: var(--yumia-info); }
5085
5310
  .yumia-metric[data-variant="warning"] { border-color: var(--yumia-warning); }
@@ -5088,28 +5313,55 @@ var HtmlRenderer = class {
5088
5313
  .yumia-metric[data-variant="danger"] .yumia-metric-value { color: var(--yumia-danger); }
5089
5314
 
5090
5315
  .yumia-metric-label {
5091
- font-size: 0.75rem;
5316
+ font-size: clamp(0.72rem, 1vw, 0.9rem);
5092
5317
  font-weight: 700;
5093
5318
  text-transform: uppercase;
5094
- letter-spacing: 0.08em;
5319
+ letter-spacing: 0.1em;
5095
5320
  color: var(--yumia-muted);
5096
5321
  }
5097
5322
 
5098
5323
  .yumia-metric-value {
5099
5324
  font-family: var(--yumia-font-heading);
5100
- font-size: clamp(1.8rem, 3.2vw, 2.6rem);
5325
+ font-size: clamp(2.3rem, 4.2vw, 3.8rem);
5101
5326
  font-weight: 800;
5102
- line-height: 1.1;
5327
+ line-height: 1.05;
5103
5328
  color: var(--yumia-primary);
5104
5329
  }
5105
5330
 
5106
5331
  .yumia-metric-change {
5107
- font-size: 0.85rem;
5332
+ font-size: clamp(0.8rem, 1.1vw, 1rem);
5108
5333
  font-weight: 600;
5334
+ padding: 4px 12px;
5335
+ border-radius: 9999px;
5336
+ background: rgba(255, 255, 255, 0.08);
5109
5337
  }
5110
5338
  .yumia-metric-change.positive { color: var(--yumia-success); }
5111
5339
  .yumia-metric-change.negative { color: var(--yumia-danger); }
5112
5340
 
5341
+ /* Chart Containers */
5342
+ .yumia-chart-container {
5343
+ width: 100%;
5344
+ flex: 1;
5345
+ min-height: 220px;
5346
+ display: flex;
5347
+ flex-direction: column;
5348
+ justify-content: center;
5349
+ background: var(--yumia-surface);
5350
+ border: 1.5px solid var(--yumia-border);
5351
+ border-radius: 14px;
5352
+ padding: clamp(1rem, 2vw, 1.6rem);
5353
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
5354
+ }
5355
+
5356
+ .yumia-chart-title {
5357
+ font-family: var(--yumia-font-heading);
5358
+ font-size: clamp(1.1rem, 1.5vw, 1.35rem);
5359
+ font-weight: 700;
5360
+ color: var(--yumia-primary);
5361
+ margin-bottom: 0.6rem;
5362
+ text-align: center;
5363
+ }
5364
+
5113
5365
  /* Tables */
5114
5366
  table {
5115
5367
  width: 100%;
@@ -6263,8 +6515,8 @@ var HtmlRenderer = class {
6263
6515
  const transition = slide.transition || "fade";
6264
6516
  const transType = typeof transition === "string" ? transition : transition.type;
6265
6517
  const transClass = `transition-${transType || "fade"}`;
6266
- const isWatermarkEnabled = watermarkOpt !== false;
6267
- const watermarkText = typeof watermarkOpt === "string" && watermarkOpt.trim().length > 0 ? watermarkOpt : "YumiaMD";
6518
+ const isWatermarkEnabled = watermarkOpt !== void 0 && watermarkOpt !== false && watermarkOpt !== "none" && watermarkOpt !== "false" && watermarkOpt !== "off";
6519
+ const watermarkText = typeof watermarkOpt === "string" && watermarkOpt.trim().length > 0 && watermarkOpt !== "true" && watermarkOpt !== "yes" && watermarkOpt !== "on" ? watermarkOpt : "Yumia";
6268
6520
  const watermarkHtml = isWatermarkEnabled ? `<div class="yumia-watermark">${this.escapeHtml(watermarkText)}</div>` : "";
6269
6521
  const elementsHtml = slide.elements.map((el) => this.renderElement(el, theme, presentation)).join("\n");
6270
6522
  return `
@@ -6416,7 +6668,18 @@ var HtmlRenderer = class {
6416
6668
  case "image": {
6417
6669
  const img = element;
6418
6670
  const alt = img.alt ? `alt="${this.escapeHtml(img.alt)}"` : "";
6419
- return `<img src="${this.escapeHtml(img.src)}" ${alt} style="max-width: 100%; border-radius: 8px;">`;
6671
+ const width = img.width ? typeof img.width === "number" ? `${img.width}px` : img.width : "100%";
6672
+ const height = img.height ? typeof img.height === "number" ? `${img.height}px` : img.height : "auto";
6673
+ const fit = img.fit || "cover";
6674
+ const radius = img.radius !== void 0 ? typeof img.radius === "number" ? `${img.radius}px` : img.radius : "var(--yumia-radius-card)";
6675
+ const shadowStyle = img.shadow ? "box-shadow: 0 12px 30px rgba(0,0,0,0.45);" : "";
6676
+ const aspect = img.aspectRatio ? `aspect-ratio: ${img.aspectRatio};` : "";
6677
+ const cap = img.caption ? `<figcaption style="margin-top: 6px; font-size: 0.85rem; color: var(--yumia-muted); text-align: center;">${this.formatInline(img.caption)}</figcaption>` : "";
6678
+ return `
6679
+ <figure class="yumia-image-wrapper" style="margin: 0.4rem 0; width: ${width}; max-width: 100%; display: flex; flex-direction: column; align-items: center;">
6680
+ <img src="${this.escapeHtml(img.src)}" ${alt} style="width: 100%; height: ${height}; object-fit: ${fit}; border-radius: ${radius}; ${aspect} ${shadowStyle} border: 1.5px solid var(--yumia-border);">
6681
+ ${cap}
6682
+ </figure>`;
6420
6683
  }
6421
6684
  case "metric": {
6422
6685
  const m = element;
@@ -6477,24 +6740,25 @@ var HtmlRenderer = class {
6477
6740
  }
6478
6741
  case "icon": {
6479
6742
  const ic = element;
6480
- const iconSvg = defaultIconResolver.toSvg(ic.name, ic.size || 24, ic.color || "currentColor", "yumia-icon");
6743
+ const iconSvg = defaultIconResolver.toSvg(ic.name, ic.size || 28, ic.color || "currentColor", "yumia-icon");
6481
6744
  return `<span class="yumia-icon-wrapper" style="display:inline-flex; align-items:center; vertical-align:middle;">${iconSvg}</span>`;
6482
6745
  }
6483
6746
  case "grid": {
6484
6747
  const g = element;
6485
- const cols = typeof g.columns === "number" ? `repeat(${g.columns}, 1fr)` : g.columns;
6748
+ const cols = typeof g.columns === "number" ? `repeat(${g.columns}, minmax(0, 1fr))` : g.columns;
6486
6749
  const gap = g.gap !== void 0 ? typeof g.gap === "number" ? `${g.gap}px` : g.gap : "1.5rem";
6487
6750
  const inner = g.elements.map((child) => this.renderElement(child, theme, presentation)).join("\n");
6488
- return `<div class="yumia-grid" style="display:grid; grid-template-columns:${cols}; gap:${gap}; width:100%;">${inner}</div>`;
6751
+ return `<div class="yumia-grid" style="grid-template-columns:${cols}; gap:${gap};">${inner}</div>`;
6489
6752
  }
6490
6753
  case "stack": {
6491
6754
  const st = element;
6492
- const dir = st.direction === "horizontal" ? "row" : "column";
6493
- const gap = st.gap !== void 0 ? typeof st.gap === "number" ? `${st.gap}px` : st.gap : "1rem";
6755
+ const isHoriz = st.direction === "horizontal";
6756
+ const dir = isHoriz ? "row" : "column";
6757
+ const gap = st.gap !== void 0 ? typeof st.gap === "number" ? `${st.gap}px` : st.gap : "1.5rem";
6494
6758
  const align = st.align ? `align-items:${st.align};` : "";
6495
6759
  const justify = st.justify ? `justify-content:${st.justify};` : "";
6496
6760
  const inner = st.elements.map((child) => this.renderElement(child, theme, presentation)).join("\n");
6497
- return `<div class="yumia-stack" style="display:flex; flex-direction:${dir}; gap:${gap}; ${align} ${justify} width:100%;">${inner}</div>`;
6761
+ return `<div class="yumia-stack ${isHoriz ? "stack-horizontal" : "stack-vertical"}" style="flex-direction:${dir}; gap:${gap}; ${align} ${justify}">${inner}</div>`;
6498
6762
  }
6499
6763
  case "compare": {
6500
6764
  return this.renderCompare(element, theme);
@@ -6554,11 +6818,18 @@ var HtmlRenderer = class {
6554
6818
  if (c.chartType === "line") {
6555
6819
  const allValues = series.flatMap((s) => s.values);
6556
6820
  const maxVal2 = Math.max(...allValues, 1);
6557
- const width2 = 500;
6558
- const height2 = 180;
6559
- const padding2 = 35;
6821
+ const width2 = 640;
6822
+ const height2 = 240;
6823
+ const padding2 = 45;
6560
6824
  const plotW2 = width2 - padding2 * 2;
6561
6825
  const plotH2 = height2 - padding2 * 2;
6826
+ const gridLines2 = [0.25, 0.5, 0.75, 1].map((ratio) => {
6827
+ const y = height2 - padding2 - ratio * plotH2;
6828
+ const valLabel = Math.round(ratio * maxVal2);
6829
+ return `
6830
+ <line x1="${padding2}" y1="${y}" x2="${width2 - padding2}" y2="${y}" stroke="rgba(255,255,255,0.08)" stroke-dasharray="4 4" />
6831
+ <text x="${padding2 - 8}" y="${y + 4}" text-anchor="end" fill="${theme.colors.muted || "#64748b"}" font-size="10" font-family="sans-serif">${valLabel}</text>`;
6832
+ }).join("");
6562
6833
  let pathsHtml = "";
6563
6834
  series.forEach((s, sIdx) => {
6564
6835
  const sColor = s.color || colors[sIdx % colors.length];
@@ -6568,20 +6839,21 @@ var HtmlRenderer = class {
6568
6839
  return `${x},${y}`;
6569
6840
  });
6570
6841
  const pointsStr = pts.join(" ");
6571
- const circles = pts.map((pt) => `<circle cx="${pt.split(",")[0]}" cy="${pt.split(",")[1]}" r="4" fill="${sColor}" />`).join("");
6842
+ const circles = pts.map((pt) => `<circle cx="${pt.split(",")[0]}" cy="${pt.split(",")[1]}" r="5" fill="${sColor}" stroke="var(--yumia-surface)" stroke-width="2" />`).join("");
6572
6843
  pathsHtml += `
6573
- <polyline fill="none" stroke="${sColor}" stroke-width="3" stroke-linecap="round" points="${pointsStr}" />
6844
+ <polyline fill="none" stroke="${sColor}" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round" points="${pointsStr}" />
6574
6845
  ${circles}`;
6575
6846
  });
6576
6847
  const labelTexts = labels.map((l, i) => {
6577
6848
  const x = padding2 + i / Math.max(labels.length - 1, 1) * plotW2;
6578
- return `<text x="${x}" y="${height2 - 10}" text-anchor="middle" fill="${theme.colors.muted || "#94a3b8"}" font-size="11" font-family="sans-serif">${this.escapeHtml(l)}</text>`;
6849
+ return `<text x="${x}" y="${height2 - 12}" text-anchor="middle" fill="${theme.colors.muted || "#94a3b8"}" font-size="11" font-weight="600" font-family="sans-serif">${this.escapeHtml(l)}</text>`;
6579
6850
  }).join("");
6580
6851
  return `
6581
6852
  <div class="yumia-chart-container">
6582
6853
  ${titleHtml}
6583
- <svg viewBox="0 0 ${width2} ${height2}" style="width:100%; max-height:220px;">
6584
- <line x1="${padding2}" y1="${height2 - padding2}" x2="${width2 - padding2}" y2="${height2 - padding2}" stroke="rgba(255,255,255,0.15)" stroke-width="1" />
6854
+ <svg viewBox="0 0 ${width2} ${height2}" style="width:100%; height:100%; max-height:280px;">
6855
+ ${gridLines2}
6856
+ <line x1="${padding2}" y1="${height2 - padding2}" x2="${width2 - padding2}" y2="${height2 - padding2}" stroke="rgba(255,255,255,0.2)" stroke-width="1.5" />
6585
6857
  ${pathsHtml}
6586
6858
  ${labelTexts}
6587
6859
  </svg>
@@ -6591,10 +6863,10 @@ var HtmlRenderer = class {
6591
6863
  const values2 = series[0]?.values || [];
6592
6864
  const total = values2.reduce((a, b) => a + b, 0) || 1;
6593
6865
  let cumulativePercent = 0;
6594
- const radius = 60;
6595
- const cx = 100;
6596
- const cy = 100;
6597
- const strokeWidth = c.chartType === "doughnut" ? 24 : 60;
6866
+ const radius = 65;
6867
+ const cx = 110;
6868
+ const cy = 110;
6869
+ const strokeWidth = c.chartType === "doughnut" ? 26 : 65;
6598
6870
  const circ = 2 * Math.PI * radius;
6599
6871
  const slices = values2.map((val, i) => {
6600
6872
  const percent = val / total;
@@ -6607,27 +6879,34 @@ var HtmlRenderer = class {
6607
6879
  const legend = labels.map((l, i) => {
6608
6880
  const sColor = colors[i % colors.length];
6609
6881
  const pct = Math.round((values2[i] || 0) / total * 100);
6610
- return `<div style="display:flex; align-items:center; gap:8px; font-size:12px; margin:4px 0;"><span style="width:10px; height:10px; border-radius:50%; background:${sColor};"></span><span style="color:var(--yumia-text);">${this.escapeHtml(l)} (${pct}%)</span></div>`;
6882
+ return `<div style="display:flex; align-items:center; gap:10px; font-size:13px; font-weight:600; margin:6px 0;"><span style="width:12px; height:12px; border-radius:50%; background:${sColor}; box-shadow:0 0 6px ${sColor};"></span><span style="color:var(--yumia-text);">${this.escapeHtml(l)} <strong style="color:var(--yumia-primary);">(${pct}%)</strong></span></div>`;
6611
6883
  }).join("");
6612
6884
  return `
6613
6885
  <div class="yumia-chart-container">
6614
6886
  ${titleHtml}
6615
- <div style="display:flex; align-items:center; justify-content:center; gap:28px; width:100%;">
6616
- <svg viewBox="0 0 200 200" style="width:160px; height:160px; transform: rotate(-90deg);">
6887
+ <div style="display:flex; align-items:center; justify-content:center; gap:36px; width:100%; padding:10px 0;">
6888
+ <svg viewBox="0 0 220 220" style="width:180px; height:180px; transform: rotate(-90deg);">
6617
6889
  ${slices}
6618
6890
  </svg>
6619
- <div style="display:flex; flex-direction:column;">${legend}</div>
6891
+ <div style="display:flex; flex-direction:column; justify-content:center;">${legend}</div>
6620
6892
  </div>
6621
6893
  </div>`;
6622
6894
  }
6623
6895
  const values = series[0]?.values || [];
6624
6896
  const maxVal = Math.max(...values, 1);
6625
- const width = 500;
6626
- const height = 180;
6627
- const padding = 35;
6897
+ const width = 640;
6898
+ const height = 240;
6899
+ const padding = 45;
6628
6900
  const plotW = width - padding * 2;
6629
6901
  const plotH = height - padding * 2;
6630
- const barWidth = Math.min(48, Math.max(16, plotW / Math.max(values.length, 1) * 0.6));
6902
+ const barWidth = Math.min(56, Math.max(20, plotW / Math.max(values.length, 1) * 0.55));
6903
+ const gridLines = [0.25, 0.5, 0.75, 1].map((ratio) => {
6904
+ const y = height - padding - ratio * plotH;
6905
+ const valLabel = Math.round(ratio * maxVal);
6906
+ return `
6907
+ <line x1="${padding}" y1="${y}" x2="${width - padding}" y2="${y}" stroke="rgba(255,255,255,0.08)" stroke-dasharray="4 4" />
6908
+ <text x="${padding - 8}" y="${y + 4}" text-anchor="end" fill="${theme.colors.muted || "#64748b"}" font-size="10" font-family="sans-serif">${valLabel}</text>`;
6909
+ }).join("");
6631
6910
  const bars = values.map((val, i) => {
6632
6911
  const x = padding + (i + 0.5) * (plotW / Math.max(values.length, 1)) - barWidth / 2;
6633
6912
  const barH = val / maxVal * plotH;
@@ -6635,15 +6914,16 @@ var HtmlRenderer = class {
6635
6914
  const color = colors[i % colors.length];
6636
6915
  const label = labels[i] || "";
6637
6916
  return `
6638
- <rect x="${x}" y="${y}" width="${barWidth}" height="${barH}" rx="4" fill="${color}" opacity="0.9" />
6639
- <text x="${x + barWidth / 2}" y="${y - 6}" text-anchor="middle" fill="${color}" font-size="11" font-weight="600" font-family="sans-serif">${val}</text>
6640
- <text x="${x + barWidth / 2}" y="${height - 12}" text-anchor="middle" fill="${theme.colors.muted || "#94a3b8"}" font-size="11" font-family="sans-serif">${this.escapeHtml(label)}</text>`;
6917
+ <rect x="${x}" y="${y}" width="${barWidth}" height="${barH}" rx="6" fill="${color}" opacity="0.95" />
6918
+ <text x="${x + barWidth / 2}" y="${y - 8}" text-anchor="middle" fill="${color}" font-size="12" font-weight="700" font-family="sans-serif">${val}</text>
6919
+ <text x="${x + barWidth / 2}" y="${height - 12}" text-anchor="middle" fill="${theme.colors.text || "#f8fafc"}" font-size="11" font-weight="600" font-family="sans-serif">${this.escapeHtml(label)}</text>`;
6641
6920
  }).join("");
6642
6921
  return `
6643
6922
  <div class="yumia-chart-container">
6644
6923
  ${titleHtml}
6645
- <svg viewBox="0 0 ${width} ${height}" style="width:100%; max-height:220px;">
6646
- <line x1="${padding}" y1="${height - padding}" x2="${width - padding}" y2="${height - padding}" stroke="rgba(255,255,255,0.15)" stroke-width="1" />
6924
+ <svg viewBox="0 0 ${width} ${height}" style="width:100%; height:100%; max-height:280px;">
6925
+ ${gridLines}
6926
+ <line x1="${padding}" y1="${height - padding}" x2="${width - padding}" y2="${height - padding}" stroke="rgba(255,255,255,0.2)" stroke-width="1.5" />
6647
6927
  ${bars}
6648
6928
  </svg>
6649
6929
  </div>`;
@@ -7295,7 +7575,7 @@ function startDevServer(filePath, options = {}) {
7295
7575
  // src/cli.ts
7296
7576
  import { mkdirSync, readFileSync as readFileSync2, watch as fsWatch, writeFileSync } from "fs";
7297
7577
  import { basename, dirname, extname, join, resolve as resolve2 } from "path";
7298
- var VERSION = "0.1.21";
7578
+ var VERSION = "0.1.23";
7299
7579
  function printHelp() {
7300
7580
  return `
7301
7581
  YumiaMD \u2014 Markdown-based presentation compiler (v${VERSION})
package/dist/index.d.ts CHANGED
@@ -9,7 +9,7 @@ export * from '@yumiamd/renderer-pptx';
9
9
  export * from '@yumiamd/renderer-html';
10
10
  export * from '@yumiamd/renderer-pdf';
11
11
 
12
- declare const VERSION = "0.1.21";
12
+ declare const VERSION = "0.1.23";
13
13
  declare function printHelp(): string;
14
14
  declare function runCli(argv: string[]): Promise<{
15
15
  exitCode: number;
package/dist/index.js CHANGED
@@ -66,7 +66,7 @@ import {
66
66
  terminalTheme,
67
67
  tokyoNightTheme,
68
68
  validate
69
- } from "./chunk-TJR6MU2I.js";
69
+ } from "./chunk-GKERS3TA.js";
70
70
  export {
71
71
  DEFAULT_VIEWPORT,
72
72
  DefaultLayoutEngine,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yumiamd",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "Command line interface and compiler for YumiaMD presentations",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,15 +21,15 @@
21
21
  },
22
22
  "devDependencies": {
23
23
  "tsup": "^8.5.1",
24
- "@yumiamd/ast": "0.1.21",
25
- "@yumiamd/layout": "0.1.21",
26
- "@yumiamd/renderer": "0.1.21",
27
- "@yumiamd/renderer-html": "0.1.21",
28
- "@yumiamd/core": "0.1.21",
29
- "@yumiamd/renderer-pptx": "0.1.21",
30
- "@yumiamd/renderer-pdf": "0.1.21",
31
- "@yumiamd/theme": "0.1.21",
32
- "@yumiamd/parser": "0.1.21"
24
+ "@yumiamd/ast": "0.1.23",
25
+ "@yumiamd/core": "0.1.23",
26
+ "@yumiamd/parser": "0.1.23",
27
+ "@yumiamd/layout": "0.1.23",
28
+ "@yumiamd/renderer": "0.1.23",
29
+ "@yumiamd/renderer-html": "0.1.23",
30
+ "@yumiamd/renderer-pdf": "0.1.23",
31
+ "@yumiamd/renderer-pptx": "0.1.23",
32
+ "@yumiamd/theme": "0.1.23"
33
33
  },
34
34
  "keywords": [
35
35
  "yumia",