@aquera/nile-visualization 0.6.0 → 0.8.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.
@@ -100,3 +100,5 @@ export { NileWidgetViewer } from './nile-widget-viewer/index.js';
100
100
  export type { NileWidgetConfig, NileWidgetChartConfig, NileWidgetKpiConfig, WidgetLayout, } from './nile-widget-viewer/index.js';
101
101
  export { NileDashboardViewer } from './nile-dashboard-viewer/index.js';
102
102
  export type { NileDashboardConfig } from './nile-dashboard-viewer/index.js';
103
+ export { NileExecutiveSummary } from './nile-executive-summary/index.js';
104
+ export type { NileExecutiveSummaryConfig } from './nile-executive-summary/index.js';
package/dist/src/index.js CHANGED
@@ -54,4 +54,5 @@ export { NileAiSender } from './nile-ai-sender/index.js';
54
54
  export { NileAiPanel } from './nile-ai-panel/index.js';
55
55
  export { NileWidgetViewer } from './nile-widget-viewer/index.js';
56
56
  export { NileDashboardViewer } from './nile-dashboard-viewer/index.js';
57
+ export { NileExecutiveSummary } from './nile-executive-summary/index.js';
57
58
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,11 @@
1
1
  import type { ChartConfigType } from './chart-config.type.js';
2
2
  import type { AqConfigType } from './aq-config.type.js';
3
- /** Input to nileChartConfig(). Discriminated on chart.type. */
4
- export interface NileChartConfigInputType {
3
+ import type { NileChartConfigBase } from '../../nile-chart/nile-chart-config.js';
4
+ /**
5
+ * Input to nileChartConfig(). Discriminated on chart.type.
6
+ * Card-level fields may sit on chart, in aq, or on the root (merged: root, then chart, then aq).
7
+ */
8
+ export interface NileChartConfigInputType extends Partial<NileChartConfigBase> {
5
9
  chart: ChartConfigType;
6
10
  aq?: AqConfigType;
7
11
  }
@@ -1,8 +1,9 @@
1
1
  /** Merges separated chart + aq config into a flat NileChartConfig. */
2
2
  export function nileChartConfig(input) {
3
- const { chart, aq } = input;
3
+ const { chart, aq, ...fromRoot } = input;
4
4
  const { ai, switchable, ...rest } = aq ?? {};
5
5
  return {
6
+ ...fromRoot,
6
7
  ...chart,
7
8
  ...rest,
8
9
  ...(ai && { ai }),
@@ -19,7 +19,6 @@ export const styles = css `
19
19
  box-shadow: var(--nile-box-shadow-3, var(--ng-shadow-sm));
20
20
  transition: box-shadow var(--nile-transition-duration-default, var(--ng-transition-duration-default)) ease;
21
21
  }
22
-
23
22
  .chart-card:hover {
24
23
  box-shadow: var(--nile-box-shadow-7, var(--ng-shadow-md));
25
24
  }
@@ -28,8 +27,10 @@ export const styles = css `
28
27
 
29
28
  .chart-header {
30
29
  display: flex;
30
+ flex-direction: row;
31
31
  align-items: center;
32
32
  justify-content: space-between;
33
+ gap: var(--nile-spacing-lg, var(--ng-spacing-lg));
33
34
  position: relative;
34
35
  z-index: 10;
35
36
  padding: var(--nile-spacing-2xl, var(--ng-spacing-2xl)) var(--nile-spacing-3xl, var(--ng-spacing-3xl)) var(--nile-spacing-xl, var(--ng-spacing-xl));
@@ -38,16 +39,24 @@ export const styles = css `
38
39
  border-radius: var(--nile-radius-radius-3xl, var(--ng-radius-xl)) var(--nile-radius-radius-3xl, var(--ng-radius-xl)) 0 0;
39
40
  }
40
41
 
42
+ .chart-header.chart-header--compact {
43
+ padding: var(--nile-spacing-xl, var(--ng-spacing-xl)) var(--nile-spacing-3xl, var(--ng-spacing-3xl)) var(--nile-spacing-lg, var(--ng-spacing-lg));
44
+ }
45
+
41
46
  .chart-header-titles {
47
+ display: flex;
48
+ flex-direction: column;
49
+ align-items: flex-start;
50
+ justify-content: center;
42
51
  min-width: 0;
43
- flex: 1;
52
+ flex: 1 1 auto;
44
53
  }
45
54
 
46
55
  .chart-header-title {
47
56
  margin: 0;
48
57
  font-family: var(--nile-font-family-serif-colfax-medium, var(--ng-font-family-display));
49
- font-size: var(--nile-type-scale-6, var(--ng-font-size-text-xl));
50
- font-weight: var(--nile-font-weight-semi-bold, var(--ng-font-weight-semibold));
58
+ font-size: var(--nile-type-scale-6, var(--ng-font-size-text-l));
59
+ font-weight: var(--nile-font-weight-semi-bold, var(--ng-font-weight-semibold));
51
60
  color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));
52
61
  line-height: 1.3;
53
62
  }
@@ -66,7 +75,7 @@ export const styles = css `
66
75
  align-items: center;
67
76
  gap: var(--nile-spacing-xs, var(--ng-spacing-xs));
68
77
  flex-shrink: 0;
69
- margin-left: var(--nile-spacing-lg, var(--ng-spacing-lg));
78
+ align-self: center;
70
79
  }
71
80
 
72
81
  /* ── Card Body ── */
@@ -287,7 +296,12 @@ export const styles = css `
287
296
  background: transparent;
288
297
  color: var(--nile-colors-primary-600, var(--ng-colors-fg-brand-primary-600));
289
298
  }
290
-
299
+ .chart-inner--kpi {
300
+ overflow-x: hidden;
301
+ overflow-y: auto;
302
+ -webkit-overflow-scrolling: touch;
303
+ contain: none;
304
+ }
291
305
  .ai-trigger.active {
292
306
  background: var(--nile-colors-primary-100, var(--ng-colors-bg-brand-primary));
293
307
  color: var(--nile-colors-primary-700, var(--ng-colors-bg-brand-solid-hover));
@@ -319,5 +333,103 @@ export const styles = css `
319
333
  .ai-panel-overlay[data-open] {
320
334
  transform: translateY(0);
321
335
  }
336
+
337
+ /* ── Skeleton loader (matches nile-skeleton-loader animation style) ── */
338
+
339
+ :host([loading]) .chart-card {
340
+ pointer-events: none;
341
+ }
342
+
343
+ .chart-skeleton {
344
+ display: flex;
345
+ flex-direction: column;
346
+ gap: 0;
347
+ padding: var(--nile-spacing-3xl, 24px) var(--nile-spacing-3xl, 24px) var(--nile-spacing-xl, 16px);
348
+ min-height: var(--nile-chart-skeleton-height, 300px);
349
+ }
350
+
351
+ .chart-skeleton-body {
352
+ display: flex;
353
+ flex-direction: column;
354
+ justify-content: space-around;
355
+ flex: 1;
356
+ gap: var(--nile-spacing-xl, 14px);
357
+ padding-left: 44px;
358
+ position: relative;
359
+ }
360
+
361
+ /* Vertical y-axis rule */
362
+ .chart-skeleton-body::before {
363
+ content: '';
364
+ position: absolute;
365
+ left: 34px;
366
+ top: 4px;
367
+ bottom: 4px;
368
+ width: 2px;
369
+ border-radius: 1px;
370
+ background: var(--nile-colors-neutral-400, #e5e7eb);
371
+ }
372
+
373
+ .chart-skeleton-row {
374
+ display: flex;
375
+ align-items: center;
376
+ gap: var(--nile-spacing-md, 8px);
377
+ height: 24px;
378
+ }
379
+
380
+ .chart-skeleton-ylabel {
381
+ width: 26px;
382
+ height: 10px;
383
+ border-radius: 3px;
384
+ flex-shrink: 0;
385
+ background: var(--nile-colors-neutral-400, #e5e7eb);
386
+ animation: nile-skeleton-blink 1.2s ease-in-out infinite;
387
+ }
388
+
389
+ .chart-skeleton-bar {
390
+ height: 20px;
391
+ width: var(--w, 60%);
392
+ border-radius: 0 3px 3px 0;
393
+ background: var(--nile-colors-neutral-400, #e5e7eb);
394
+ animation: nile-skeleton-blink 1.2s ease-in-out infinite;
395
+ }
396
+
397
+ /* Staggered wave across the bars */
398
+ .chart-skeleton-row:nth-child(1) .chart-skeleton-bar { animation-delay: 0ms; }
399
+ .chart-skeleton-row:nth-child(2) .chart-skeleton-bar { animation-delay: 100ms; }
400
+ .chart-skeleton-row:nth-child(3) .chart-skeleton-bar { animation-delay: 200ms; }
401
+ .chart-skeleton-row:nth-child(4) .chart-skeleton-bar { animation-delay: 300ms; }
402
+ .chart-skeleton-row:nth-child(5) .chart-skeleton-bar { animation-delay: 400ms; }
403
+
404
+ /* Horizontal x-axis labels row */
405
+ .chart-skeleton-xaxis-row {
406
+ display: flex;
407
+ justify-content: space-around;
408
+ padding-left: 44px;
409
+ margin-top: var(--nile-spacing-xl, 14px);
410
+ }
411
+
412
+ .chart-skeleton-xlabel {
413
+ height: 10px;
414
+ width: 30px;
415
+ border-radius: 3px;
416
+ background: var(--nile-colors-neutral-400, #e5e7eb);
417
+ animation: nile-skeleton-blink 1.2s ease-in-out infinite;
418
+ animation-delay: var(--d, 0ms);
419
+ }
420
+
421
+ @keyframes nile-skeleton-blink {
422
+ 0%, 100% { opacity: 0.5; }
423
+ 50% { opacity: 1; }
424
+ }
425
+
426
+ @media (prefers-reduced-motion: reduce) {
427
+ .chart-skeleton-bar,
428
+ .chart-skeleton-ylabel,
429
+ .chart-skeleton-xlabel {
430
+ animation: none;
431
+ opacity: 0.7;
432
+ }
433
+ }
322
434
  `;
323
435
  //# sourceMappingURL=nile-chart.css.js.map
@@ -53,6 +53,17 @@ export declare class NileChart extends NileElement {
53
53
  static styles: CSSResultGroup;
54
54
  /** Full chart configuration. Accepts flat NileChartConfig or separated { chart, aq } input. */
55
55
  config: NileChartConfig | NileChartConfigInputType | null;
56
+ /**
57
+ * When true, hides the chart and shows a skeleton bar-chart loader.
58
+ * Set to false once data is ready to reveal the chart.
59
+ *
60
+ * @example
61
+ * ```js
62
+ * chart.loading = true;
63
+ * fetchData().then(data => { chart.config = buildConfig(data); chart.loading = false; });
64
+ * ```
65
+ */
66
+ loading: boolean;
56
67
  /**
57
68
  * When set, fills `chart.type` if the config omits it (same values as `chart.type`, e.g. `stacked`, `pie`).
58
69
  * Usage: `<nile-chart chart-type="pie" />` plus `config.chart` with series data only.
@@ -108,6 +119,7 @@ export declare class NileChart extends NileElement {
108
119
  private renderHeader;
109
120
  private renderAiPanel;
110
121
  private renderChartContent;
122
+ private renderSkeleton;
111
123
  render(): TemplateResult;
112
124
  }
113
125
  declare global {
@@ -103,6 +103,17 @@ let NileChart = class NileChart extends NileElement {
103
103
  super(...arguments);
104
104
  /** Full chart configuration. Accepts flat NileChartConfig or separated { chart, aq } input. */
105
105
  this.config = null;
106
+ /**
107
+ * When true, hides the chart and shows a skeleton bar-chart loader.
108
+ * Set to false once data is ready to reveal the chart.
109
+ *
110
+ * @example
111
+ * ```js
112
+ * chart.loading = true;
113
+ * fetchData().then(data => { chart.config = buildConfig(data); chart.loading = false; });
114
+ * ```
115
+ */
116
+ this.loading = false;
106
117
  /**
107
118
  * When set, fills `chart.type` if the config omits it (same values as `chart.type`, e.g. `stacked`, `pie`).
108
119
  * Usage: `<nile-chart chart-type="pie" />` plus `config.chart` with series data only.
@@ -329,13 +340,14 @@ let NileChart = class NileChart extends NileElement {
329
340
  const title = this.headerTitle;
330
341
  const subtitle = this.headerSubtitle;
331
342
  const showDefaultTitles = !this.hasHeaderSlotContent && !!(title || subtitle);
343
+ const headerCompact = !subtitle?.trim();
332
344
  return html `
333
- <div class="chart-header">
345
+ <div class="chart-header ${headerCompact ? 'chart-header--compact' : ''}">
334
346
  <div class="chart-header-titles">
335
347
  <slot name="header" @slotchange=${this.onHeaderSlotChange}></slot>
336
348
  ${showDefaultTitles
337
349
  ? html `
338
- ${title ? html `<h3 class="chart-header-title">${title}</h3>` : nothing}
350
+ ${title ? html `<p class="chart-header-title">${title}</p>` : nothing}
339
351
  ${subtitle ? html `<p class="chart-header-subtitle">${subtitle}</p>` : nothing}
340
352
  `
341
353
  : nothing}
@@ -851,6 +863,7 @@ let NileChart = class NileChart extends NileElement {
851
863
  case 'kpi': {
852
864
  const k = config;
853
865
  return html `<nile-kpi-chart
866
+ embed-in-nile-chart
854
867
  .config=${{
855
868
  chart: {
856
869
  type: 'kpi',
@@ -885,18 +898,39 @@ let NileChart = class NileChart extends NileElement {
885
898
  }
886
899
  }
887
900
  }
901
+ renderSkeleton() {
902
+ return html `
903
+ <div class="chart-skeleton" aria-busy="true" aria-label="Loading chart">
904
+ <div class="chart-skeleton-body">
905
+ ${[78, 55, 91, 42, 68].map(w => html `
906
+ <div class="chart-skeleton-row">
907
+ <div class="chart-skeleton-ylabel"></div>
908
+ <div class="chart-skeleton-bar" style="--w: ${w}%"></div>
909
+ </div>
910
+ `)}
911
+ </div>
912
+ <div class="chart-skeleton-xaxis-row">
913
+ ${[0, 1, 2, 3, 4].map(i => html `<div class="chart-skeleton-xlabel" style="--d: ${i * 80}ms"></div>`)}
914
+ </div>
915
+ </div>
916
+ `;
917
+ }
888
918
  render() {
919
+ const isLoading = this.loading || (this.activeConfig?.loading ?? false);
889
920
  return html `
890
921
  <div class="chart-card">
891
922
  ${this.renderHeader()}
892
923
  <div class="chart-wrapper">
893
- <div class="chart-inner">
894
- ${this.activeConfig ? this.renderChartContent() : html `<slot></slot>`}
924
+ <div class="chart-inner ${this.activeConfig?.type === 'kpi' ? 'chart-inner--kpi' : ''}">
925
+ ${isLoading
926
+ ? this.renderSkeleton()
927
+ : this.activeConfig
928
+ ? this.renderChartContent()
929
+ : html `<slot></slot>`}
895
930
  ${this.renderAiPanel()}
896
931
  </div>
897
932
  </div>
898
933
  <slot name="footer"></slot>
899
- <slot name="footer"></slot>
900
934
  </div>
901
935
  `;
902
936
  }
@@ -905,6 +939,9 @@ NileChart.styles = styles;
905
939
  __decorate([
906
940
  property({ type: Object })
907
941
  ], NileChart.prototype, "config", void 0);
942
+ __decorate([
943
+ property({ type: Boolean, reflect: true })
944
+ ], NileChart.prototype, "loading", void 0);
908
945
  __decorate([
909
946
  property({ type: String, attribute: 'chart-type' })
910
947
  ], NileChart.prototype, "chartTypeAttr", void 0);
@@ -0,0 +1,2 @@
1
+ export { NileExecutiveSummary } from './nile-executive-summary.js';
2
+ export type { NileExecutiveSummaryConfig } from './nile-executive-summary-config.js';
@@ -0,0 +1,2 @@
1
+ export { NileExecutiveSummary } from './nile-executive-summary.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Copyright Aquera Inc 2023
3
+ *
4
+ * This source code is licensed under the BSD-3-Clause license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ /**
8
+ * Configuration interface for the nile-executive-summary component.
9
+ * Assign to the component's `config` property via JavaScript.
10
+ *
11
+ * @example
12
+ * ```js
13
+ * const el = document.querySelector('nile-executive-summary');
14
+ * el.config = {
15
+ * summary: '<p>Q1 revenue grew <strong>23%</strong> YoY...</p>',
16
+ * buttonLabel: 'View Summary',
17
+ * drawerLabel: 'AI Executive Summary',
18
+ * };
19
+ * ```
20
+ */
21
+ export interface NileExecutiveSummaryConfig {
22
+ /** Text or HTML string displayed with the typewriter effect inside the drawer. */
23
+ summary: string;
24
+ /** Label rendered on the built-in trigger nile-button. Default: 'Executive Summary' */
25
+ buttonLabel?: string;
26
+ /**
27
+ * Variant forwarded to the internal nile-button. Default: 'primary'
28
+ * Mirrors nile-button's `variant` property.
29
+ */
30
+ buttonVariant?: 'primary' | 'secondary' | 'tertiary' | 'caution' | 'ghost' | 'destructive' | 'secondary-grey' | 'secondary-blue';
31
+ /** Title displayed in the drawer header. Default: 'Executive Summary' */
32
+ drawerLabel?: string;
33
+ /** Milliseconds per character for the typing animation. Default: 30 */
34
+ typingSpeed?: number;
35
+ /** Close the drawer when the user presses Escape. Default: true */
36
+ closeOnEscape?: boolean;
37
+ /** Prevent the drawer from closing when the overlay is clicked. Default: false */
38
+ preventOverlayClose?: boolean;
39
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright Aquera Inc 2023
3
+ *
4
+ * This source code is licensed under the BSD-3-Clause license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=nile-executive-summary-config.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright Aquera Inc 2023
3
+ *
4
+ * This source code is licensed under the BSD-3-Clause license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ export declare const styles: import("lit").CSSResult;
8
+ declare const _default: import("lit").CSSResult[];
9
+ export default _default;
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Copyright Aquera Inc 2023
3
+ *
4
+ * This source code is licensed under the BSD-3-Clause license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import { css } from 'lit';
8
+ export const styles = css `
9
+ :host {
10
+ box-sizing: border-box;
11
+ -webkit-font-smoothing: antialiased;
12
+ -moz-osx-font-smoothing: grayscale;
13
+ text-rendering: optimizeLegibility;
14
+ display: inline-block;
15
+ position: relative;
16
+ }
17
+
18
+ :host *,
19
+ :host *::before,
20
+ :host *::after {
21
+ box-sizing: inherit;
22
+ }
23
+
24
+ [hidden] {
25
+ display: none !important;
26
+ }
27
+
28
+ /* ─── Trigger button ───────────────────────────────────────────────────── */
29
+
30
+ .es-trigger {
31
+ display: inline-flex;
32
+ align-items: center;
33
+ gap: 6px;
34
+ padding: var(--executive-summary-btn-padding, 8px 14px);
35
+ border: none;
36
+ border-radius: var(--executive-summary-btn-radius, var(--nile-radius-base-standard, 4px));
37
+ background-color: var(--executive-summary-btn-bg, var(--nile-colors-primary-600, #0052a3));
38
+ color: var(--executive-summary-btn-color, var(--nile-colors-white-base, #fff));
39
+ font-family: var(--nile-font-family-body, sans-serif);
40
+ font-size: var(--nile-type-scale-3, 14px);
41
+ font-weight: 500;
42
+ line-height: 1.4;
43
+ cursor: pointer;
44
+ transition: background-color 0.2s ease, box-shadow 0.2s ease;
45
+ outline: none;
46
+ white-space: nowrap;
47
+ user-select: none;
48
+ }
49
+
50
+ .es-trigger:hover {
51
+ background-color: var(--executive-summary-btn-bg-hover, var(--nile-colors-primary-700, #003d7a));
52
+ }
53
+
54
+ .es-trigger:focus-visible {
55
+ box-shadow: 0 0 0 3px var(--nile-colors-primary-200, rgba(0, 82, 163, 0.3));
56
+ }
57
+
58
+ .es-trigger:active {
59
+ background-color: var(--executive-summary-btn-bg-active, var(--nile-colors-primary-800, #002e5b));
60
+ }
61
+
62
+ /* ─── Backdrop wrapper (fixed, full viewport) ──────────────────────────── */
63
+
64
+ .es-backdrop {
65
+ position: fixed;
66
+ top: 0;
67
+ left: 0;
68
+ width: 100%;
69
+ height: 100%;
70
+ pointer-events: none;
71
+ overflow: hidden;
72
+ z-index: var(--executive-summary-z-index, 700);
73
+ }
74
+
75
+ /* ─── Overlay ──────────────────────────────────────────────────────────── */
76
+
77
+ .es-overlay {
78
+ position: fixed;
79
+ top: 0;
80
+ right: 0;
81
+ bottom: 0;
82
+ left: 0;
83
+ background-color: var(--executive-summary-overlay-color, hsl(240 3.8% 46.1% / 33%));
84
+ pointer-events: all;
85
+ }
86
+
87
+ /* ─── Drawer panel ─────────────────────────────────────────────────────── */
88
+
89
+ .es-panel {
90
+ position: absolute;
91
+ top: 0;
92
+ right: 0;
93
+ bottom: 0;
94
+ width: var(--executive-summary-size, 480px);
95
+ max-width: 100%;
96
+ display: flex;
97
+ flex-direction: column;
98
+ z-index: 2;
99
+ background-color: var(--nile-colors-white-base, #fff);
100
+ box-shadow: var(
101
+ --executive-summary-shadow,
102
+ var(
103
+ --nile-box-shadow-2,
104
+ 0px 20px 24px -4px rgba(16, 24, 40, 0.08),
105
+ 0px 8px 8px -4px rgba(16, 24, 40, 0.03)
106
+ )
107
+ );
108
+ pointer-events: all;
109
+ outline: none;
110
+ }
111
+
112
+ /* ─── Header ───────────────────────────────────────────────────────────── */
113
+
114
+ .es-header {
115
+ display: flex;
116
+ align-items: center;
117
+ flex-shrink: 0;
118
+ padding: var(--executive-summary-header-spacing, 16px 20px);
119
+ border-bottom: 1px solid var(--nile-colors-neutral-100, #e5e7eb);
120
+ }
121
+
122
+ .es-title {
123
+ flex: 1 1 auto;
124
+ margin: 0;
125
+ font-family: var(--nile-font-family-body, sans-serif);
126
+ font-size: var(--nile-font-size-rem-small, 16px);
127
+ font-weight: 600;
128
+ line-height: 1.4;
129
+ color: var(--nile-colors-dark-900, #111827);
130
+ }
131
+
132
+ /* ─── Close button ─────────────────────────────────────────────────────── */
133
+
134
+ .es-close {
135
+ flex-shrink: 0;
136
+ display: inline-flex;
137
+ align-items: center;
138
+ justify-content: center;
139
+ width: 32px;
140
+ height: 32px;
141
+ padding: 0;
142
+ border: none;
143
+ background: none;
144
+ border-radius: var(--nile-radius-sm, 4px);
145
+ cursor: pointer;
146
+ color: var(--nile-colors-dark-900, #374151);
147
+ transition: background-color 0.15s ease;
148
+ margin-left: 8px;
149
+ }
150
+
151
+ .es-close:hover {
152
+ background-color: var(--nile-colors-neutral-50, #f3f4f6);
153
+ }
154
+
155
+ .es-close:focus-visible {
156
+ outline: 2px solid var(--nile-colors-primary-600, #0052a3);
157
+ outline-offset: 1px;
158
+ }
159
+
160
+ .es-close svg {
161
+ width: 18px;
162
+ height: 18px;
163
+ stroke: currentColor;
164
+ fill: none;
165
+ stroke-width: 2;
166
+ stroke-linecap: round;
167
+ stroke-linejoin: round;
168
+ }
169
+
170
+ /* ─── Body ─────────────────────────────────────────────────────────────── */
171
+
172
+ .es-body {
173
+ flex: 1 1 auto;
174
+ overflow-y: auto;
175
+ padding: var(--executive-summary-body-spacing, 20px);
176
+ -webkit-overflow-scrolling: touch;
177
+ }
178
+
179
+ /* ─── Typed text ───────────────────────────────────────────────────────── */
180
+
181
+ .es-typed-text {
182
+ font-family: var(--nile-font-family-body, sans-serif);
183
+ font-size: var(--nile-type-scale-3, 14px);
184
+ line-height: 1.7;
185
+ color: var(--nile-colors-dark-900, #111827);
186
+ word-break: break-word;
187
+ }
188
+
189
+ @media (forced-colors: active) {
190
+ .es-panel {
191
+ border: 1px solid ButtonText;
192
+ }
193
+ }
194
+ `;
195
+ export default [styles];
196
+ //# sourceMappingURL=nile-executive-summary.css.js.map