@freereportjs/core 0.1.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.
@@ -1,168 +1,168 @@
1
- /* FreeReport viewer and designer. Override the --fr-* variables to theme. */
2
- .fr-viewer, .fr-designer {
3
- --fr-bg: #e9ecf1;
4
- --fr-panel: #ffffff;
5
- --fr-ink: #0e1726;
6
- --fr-ink-2: #4a5568;
7
- --fr-rule: #d5dbe3;
8
- --fr-accent: #2340f5;
9
- --fr-accent-ink: #ffffff;
10
- --fr-hover: #f1f3f7;
11
- --fr-radius: 6px;
12
- --fr-font: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Malgun Gothic", "Segoe UI", sans-serif;
13
- display: flex; flex-direction: column; min-height: 0; height: 100%;
14
- font: 13px/1.4 var(--fr-font); color: var(--fr-ink); background: var(--fr-bg);
15
- border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); overflow: hidden; box-sizing: border-box;
16
- }
17
- .fr-viewer *, .fr-designer * { box-sizing: border-box; }
18
-
19
- .fr-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 2px; padding: 6px 8px; background: var(--fr-panel); border-bottom: 1px solid var(--fr-rule); }
20
- .fr-btn { display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 9px; border: 1px solid transparent; border-radius: var(--fr-radius); background: none; color: var(--fr-ink); font: inherit; font-weight: 500; cursor: pointer; white-space: nowrap; }
21
- .fr-btn:hover { background: var(--fr-hover); }
22
- .fr-btn:focus-visible, .fr-viewer select:focus-visible, .fr-viewer input:focus-visible { outline: 2px solid var(--fr-accent); outline-offset: 1px; }
23
- .fr-btn:disabled { opacity: .45; cursor: default; }
24
- .fr-btn.fr-icon { width: 30px; padding: 0; justify-content: center; }
25
- .fr-btn.fr-primary { background: var(--fr-accent); color: var(--fr-accent-ink); }
26
- .fr-btn.fr-primary:hover { filter: brightness(1.08); }
27
- .fr-btn[aria-expanded="true"], .fr-btn[aria-pressed="true"] { background: var(--fr-hover); border-color: var(--fr-rule); }
28
- .fr-btn svg { flex: none; }
29
- .fr-sep { width: 1px; height: 20px; margin: 0 6px; background: var(--fr-rule); }
30
- .fr-spacer { flex: 1; }
31
- .fr-pageno { display: inline-flex; align-items: center; gap: 4px; margin: 0 4px; color: var(--fr-ink-2); font-variant-numeric: tabular-nums; }
32
- .fr-pageno input { width: 44px; height: 28px; text-align: center; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); font: inherit; color: var(--fr-ink); }
33
- .fr-zoom { height: 30px; padding: 0 6px; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); background: var(--fr-panel); font: inherit; color: var(--fr-ink); }
34
- .fr-menu { position: relative; }
35
- .fr-menu-list { position: absolute; right: 0; top: calc(100% + 4px); z-index: 20; min-width: 180px; padding: 4px; background: var(--fr-panel); border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); box-shadow: 0 8px 24px rgba(14, 23, 38, .14); display: flex; flex-direction: column; }
36
- .fr-menu-list[hidden] { display: none; }
37
- .fr-menu-list button { text-align: left; padding: 8px 10px; border: 0; background: none; border-radius: 4px; font: inherit; color: var(--fr-ink); cursor: pointer; }
38
- .fr-menu-list button:hover, .fr-menu-list button:focus-visible { background: var(--fr-hover); outline: none; }
39
-
40
- .fr-params { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 14px; padding: 10px 12px; background: var(--fr-panel); border-bottom: 1px solid var(--fr-rule); }
41
- .fr-params[hidden] { display: none; }
42
- .fr-param { display: flex; flex-direction: column; gap: 3px; }
43
- .fr-param label { font-size: 12px; color: var(--fr-ink-2); font-weight: 600; }
44
- .fr-param label b { color: #c8102e; }
45
- .fr-param input, .fr-param select { height: 30px; min-width: 140px; padding: 0 8px; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); font: inherit; background: #fff; color: var(--fr-ink); }
46
-
47
- .fr-body { position: relative; flex: 1; min-height: 0; overflow: auto; outline: none; }
48
- .fr-pages { display: flex; flex-direction: column; align-items: center; gap: 16px; padding: 16px 24px 32px; min-width: min-content; }
49
- .fr-page { width: var(--fr-page-w, 794px); height: var(--fr-page-h, 1123px); flex: none; background: #fff; box-shadow: 0 1px 3px rgba(14, 23, 38, .18), 0 6px 18px -8px rgba(14, 23, 38, .25); }
50
- .fr-page-svg { display: block; width: 100%; height: 100%; }
51
- .fr-page { position: relative; }
52
- .fr-hit { position: absolute; background: rgba(242, 169, 0, .38); outline: 2px solid #f2a900; border-radius: 2px; pointer-events: none; }
53
- .fr-search { display: inline-flex; align-items: center; gap: 4px; height: 30px; padding: 0 8px; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); color: var(--fr-ink-2); background: var(--fr-panel); }
54
- .fr-search input { width: 120px; border: 0; outline: none; font: inherit; color: var(--fr-ink); background: none; }
55
- .fr-search:focus-within { border-color: var(--fr-accent); }
56
- .fr-search-count { font-size: 12px; white-space: nowrap; font-variant-numeric: tabular-nums; }
57
- .fr-empty { margin: 48px auto; color: var(--fr-ink-2); }
58
- .fr-overlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 10px; background: rgba(233, 236, 241, .72); font-weight: 600; color: var(--fr-ink-2); z-index: 5; }
59
- .fr-overlay[hidden] { display: none; }
60
- .fr-spinner { width: 18px; height: 18px; border: 2px solid var(--fr-rule); border-top-color: var(--fr-accent); border-radius: 50%; animation: fr-spin .8s linear infinite; }
61
- @keyframes fr-spin { to { transform: rotate(360deg); } }
62
- @media (prefers-reduced-motion: reduce) { .fr-spinner { animation-duration: 2.4s; } }
63
- .fr-status { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 4px 10px; background: var(--fr-panel); border-top: 1px solid var(--fr-rule); color: var(--fr-ink-2); font-size: 12px; font-variant-numeric: tabular-nums; min-height: 26px; }
64
- .fr-badge { color: var(--fr-ink-2); text-decoration: none; border: 1px solid var(--fr-rule); border-radius: 999px; padding: 0 8px; }
65
- .fr-badge[hidden] { display: none; }
66
-
67
- @media (max-width: 640px) {
68
- .fr-btn span { display: none; }
69
- .fr-btn { padding: 0 7px; }
70
- .fr-pages { padding: 10px 8px 24px; }
71
- }
72
- @media print {
73
- .fr-viewer .fr-toolbar, .fr-viewer .fr-status, .fr-viewer .fr-params { display: none; }
74
- }
75
-
76
- /* ── Designer ─────────────────────────────────── */
77
- .fr-designer { outline: none; }
78
- .fr-designer .fr-toolbar { gap: 1px; }
79
- .fr-designer .fr-group { display: inline-flex; align-items: center; gap: 1px; flex-wrap: wrap; }
80
- .fr-designer.is-preview .fr-design-only, .fr-designer.is-json .fr-design-only { display: none; }
81
- .fr-tabs { display: inline-flex; padding: 2px; background: var(--fr-bg); border-radius: 7px; }
82
- .fr-tab { height: 26px; padding: 0 12px; border: 0; border-radius: 5px; background: none; font: inherit; font-weight: 600; color: var(--fr-ink-2); cursor: pointer; }
83
- .fr-tab[aria-selected="true"] { background: var(--fr-panel); color: var(--fr-ink); box-shadow: 0 1px 2px rgba(14, 23, 38, .12); }
84
- .fr-zoom-label { min-width: 42px; text-align: center; font-variant-numeric: tabular-nums; color: var(--fr-ink-2); }
85
- .fr-dz { flex: 1; min-height: 0; display: grid; grid-template-columns: 200px minmax(0, 1fr) 270px; }
86
- .fr-designer.is-preview .fr-dz, .fr-designer.is-json .fr-dz { grid-template-columns: minmax(0, 1fr); }
87
- .fr-designer.is-preview .fr-dz-left, .fr-designer.is-preview .fr-dz-right, .fr-designer.is-json .fr-dz-left, .fr-designer.is-json .fr-dz-right { display: none; }
88
- .fr-dz-left, .fr-dz-right { background: var(--fr-panel); overflow: auto; min-height: 0; }
89
- .fr-dz-left { border-right: 1px solid var(--fr-rule); padding: 8px; }
90
- .fr-dz-right { border-left: 1px solid var(--fr-rule); }
91
- .fr-dz-left h3 { margin: 10px 4px 6px; font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--fr-ink-2); }
92
- .fr-dz-left h3:first-child { margin-top: 2px; }
93
- .fr-dz-tools { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; }
94
- .fr-dz-tool { display: flex; align-items: center; gap: 6px; padding: 6px; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); background: var(--fr-panel); font: inherit; font-size: 12px; color: var(--fr-ink); cursor: grab; text-align: left; }
95
- .fr-dz-tool:hover, .fr-dz-field:hover { border-color: var(--fr-accent); color: var(--fr-accent); }
96
- .fr-dz-fields { display: flex; flex-wrap: wrap; gap: 4px; }
97
- .fr-dz-field { padding: 3px 8px; border: 1px solid var(--fr-rule); border-radius: 999px; background: #f7f9fc; font: 12px/1.4 ui-monospace, Consolas, monospace; color: var(--fr-ink); cursor: grab; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
98
- .fr-dz-empty { margin: 0 4px; color: var(--fr-ink-2); font-size: 12px; }
99
- .fr-dz-bandopt { display: flex; align-items: center; gap: 6px; padding: 2px 4px; font-size: 12.5px; cursor: pointer; }
100
- .fr-dz-groupopt { display: flex; align-items: center; justify-content: space-between; gap: 4px; padding: 2px 4px; font-size: 12px; }
101
- .fr-dz-groupopt code { font-size: 11.5px; }
102
- .fr-dz-addgroup { display: flex; gap: 4px; margin-top: 6px; }
103
- .fr-dz-addgroup select { flex: 1; min-width: 0; height: 30px; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); font: inherit; font-size: 12px; }
104
- .fr-dz-addgroup .fr-btn span { font-size: 12px; }
105
- .fr-dz-center { position: relative; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
106
- .fr-dz-canvas { flex: 1; overflow: auto; padding: 24px 32px 64px; outline: none; }
107
- .fr-dz-canvas[hidden], .fr-dz-preview[hidden], .fr-dz-json[hidden] { display: none; }
108
- .fr-dz-page { margin: 0 auto; background: #fff; box-shadow: 0 1px 3px rgba(14, 23, 38, .16), 0 8px 24px -12px rgba(14, 23, 38, .3); user-select: none; }
109
- .fr-dz-band { position: relative; }
110
- .fr-dz-band-head { display: flex; justify-content: space-between; align-items: center; height: 20px; padding: 0 8px; background: #eef1f6; border-top: 1px solid var(--fr-rule); border-bottom: 1px solid var(--fr-rule); font-size: 11px; font-weight: 600; color: var(--fr-ink-2); cursor: pointer; }
111
- .fr-dz-band-head small { font-weight: 500; font-variant-numeric: tabular-nums; }
112
- .fr-dz-band.is-selected .fr-dz-band-head { background: #dfe6ff; color: var(--fr-accent); }
113
- .fr-dz-band-area { position: relative; background-image: radial-gradient(circle, #d3d9e3 .8px, transparent .9px); overflow: visible; }
114
- .fr-dz-band-resize { height: 5px; margin-top: -2px; position: relative; z-index: 3; cursor: ns-resize; }
115
- .fr-dz-band-resize:hover { background: var(--fr-accent); opacity: .5; }
116
- .fr-dz-hint { position: absolute; left: 8px; top: 50%; transform: translateY(-50%); color: #a6b0c0; font-size: 11px; pointer-events: none; white-space: nowrap; }
117
- .fr-dz-el { position: absolute; cursor: move; outline: 1px dashed rgba(35, 64, 245, .18); }
118
- .fr-dz-el:hover { outline-color: rgba(35, 64, 245, .55); }
119
- .fr-dz-el.is-selected { outline: 1.5px solid var(--fr-accent); z-index: 2; }
120
- .fr-dz-el.is-line { outline-offset: 2px; }
121
- .fr-dz-el > * { pointer-events: none; }
122
- .fr-dz-el > .fr-dz-h, .fr-dz-el > .fr-dz-inline { pointer-events: auto; }
123
- .fr-dz-text { position: absolute; inset: 0; display: flex; flex-direction: column; overflow: hidden; white-space: pre-wrap; word-break: break-all; }
124
- .fr-dz-text small { margin-left: 4px; font-size: 9px; color: #7a8599; font-weight: 400; }
125
- .fr-dz-expr { color: #1a2fc0; }
126
- .fr-dz-rect { position: absolute; inset: 0; }
127
- .fr-dz-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
128
- .fr-dz-el img { width: 100%; height: 100%; display: block; }
129
- .fr-dz-ph { position: absolute; inset: 0; display: grid; place-items: center; background: repeating-linear-gradient(45deg, #f4f6fa, #f4f6fa 4px, #eceff5 4px, #eceff5 8px); color: #8a94a6; }
130
- .fr-dz-h { position: absolute; width: 8px; height: 8px; background: #fff; border: 1.5px solid var(--fr-accent); border-radius: 2px; z-index: 3; }
131
- .fr-dz-h-nw { left: -4px; top: -4px; cursor: nwse-resize; }
132
- .fr-dz-h-n { left: calc(50% - 4px); top: -4px; cursor: ns-resize; }
133
- .fr-dz-h-ne { right: -4px; top: -4px; cursor: nesw-resize; }
134
- .fr-dz-h-e { right: -4px; top: calc(50% - 4px); cursor: ew-resize; }
135
- .fr-dz-h-se { right: -4px; bottom: -4px; cursor: nwse-resize; }
136
- .fr-dz-h-s { left: calc(50% - 4px); bottom: -4px; cursor: ns-resize; }
137
- .fr-dz-h-sw { left: -4px; bottom: -4px; cursor: nesw-resize; }
138
- .fr-dz-h-w { left: -4px; top: calc(50% - 4px); cursor: ew-resize; }
139
- .fr-dz-marquee { position: absolute; border: 1px solid var(--fr-accent); background: rgba(35, 64, 245, .08); pointer-events: none; z-index: 4; }
140
- .fr-dz-inline { position: absolute; inset: 0; min-height: 24px; z-index: 5; font: 13px/1.4 var(--fr-font); padding: 2px 4px; border: 2px solid var(--fr-accent); resize: none; }
141
- .fr-dz-preview { flex: 1; min-height: 0; }
142
- .fr-dz-preview .fr-viewer { border: 0; border-radius: 0; }
143
- .fr-dz-json { flex: 1; min-height: 0; display: flex; flex-direction: column; }
144
- .fr-dz-json textarea { flex: 1; border: 0; padding: 14px 16px; font: 12.5px/1.55 ui-monospace, "Cascadia Code", Consolas, monospace; resize: none; outline: none; background: #fbfcfe; color: var(--fr-ink); }
145
- .fr-dz-json-bar { display: flex; justify-content: flex-end; align-items: center; gap: 12px; padding: 8px 12px; border-top: 1px solid var(--fr-rule); background: var(--fr-panel); }
146
- .fr-dz-json-err { color: #c8102e; font-size: 12px; }
147
- .fr-dz-props { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding: 4px 12px 24px; }
148
- .fr-dz-sec { grid-column: 1 / -1; margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--fr-rule); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--fr-ink-2); }
149
- .fr-dz-sec:first-child { border-top: 0; margin-top: 4px; padding-top: 4px; }
150
- .fr-dz-prop { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
151
- .fr-dz-prop.is-wide { grid-column: 1 / -1; }
152
- .fr-dz-prop.is-check { flex-direction: row; align-items: center; gap: 6px; grid-column: 1 / -1; font-size: 12.5px; cursor: pointer; }
153
- .fr-dz-plabel { font-size: 11.5px; color: var(--fr-ink-2); font-weight: 600; }
154
- .fr-dz-prop input[type=text], .fr-dz-prop input[type=number], .fr-dz-prop select, .fr-dz-prop textarea { width: 100%; height: 28px; padding: 0 7px; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); font: inherit; font-size: 12.5px; color: var(--fr-ink); background: #fff; }
155
- .fr-dz-prop textarea { height: auto; padding: 5px 7px; font-family: ui-monospace, Consolas, monospace; resize: vertical; }
156
- .fr-dz-prop input.is-expr { font-family: ui-monospace, Consolas, monospace; }
157
- .fr-dz-prop :focus-visible { outline: 2px solid var(--fr-accent); outline-offset: 0; }
158
- .fr-dz-err { color: #c8102e; font-size: 11px; }
159
- .fr-dz-err:empty { display: none; }
160
- .fr-dz-color { display: flex; gap: 4px; }
161
- .fr-dz-color input[type=color] { width: 30px; height: 28px; padding: 1px; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); background: #fff; flex: none; }
162
- .fr-dz-toggles { display: flex; gap: 3px; flex-wrap: wrap; }
163
- .fr-dz-toggle { width: 30px; height: 28px; padding: 0; justify-content: center; border: 1px solid var(--fr-rule); font-weight: 700; }
164
- .fr-dz-toggle[aria-pressed="true"] { background: #dfe6ff; border-color: var(--fr-accent); color: var(--fr-accent); }
165
- @media (max-width: 960px) {
166
- .fr-dz { grid-template-columns: 150px minmax(0, 1fr); }
167
- .fr-dz-right { display: none; }
168
- }
1
+ /* FreeReport viewer and designer. Override the --fr-* variables to theme. */
2
+ .fr-viewer, .fr-designer {
3
+ --fr-bg: #e9ecf1;
4
+ --fr-panel: #ffffff;
5
+ --fr-ink: #0e1726;
6
+ --fr-ink-2: #4a5568;
7
+ --fr-rule: #d5dbe3;
8
+ --fr-accent: #2340f5;
9
+ --fr-accent-ink: #ffffff;
10
+ --fr-hover: #f1f3f7;
11
+ --fr-radius: 6px;
12
+ --fr-font: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Malgun Gothic", "Segoe UI", sans-serif;
13
+ display: flex; flex-direction: column; min-height: 0; height: 100%;
14
+ font: 13px/1.4 var(--fr-font); color: var(--fr-ink); background: var(--fr-bg);
15
+ border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); overflow: hidden; box-sizing: border-box;
16
+ }
17
+ .fr-viewer *, .fr-designer * { box-sizing: border-box; }
18
+
19
+ .fr-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 2px; padding: 6px 8px; background: var(--fr-panel); border-bottom: 1px solid var(--fr-rule); }
20
+ .fr-btn { display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 9px; border: 1px solid transparent; border-radius: var(--fr-radius); background: none; color: var(--fr-ink); font: inherit; font-weight: 500; cursor: pointer; white-space: nowrap; }
21
+ .fr-btn:hover { background: var(--fr-hover); }
22
+ .fr-btn:focus-visible, .fr-viewer select:focus-visible, .fr-viewer input:focus-visible { outline: 2px solid var(--fr-accent); outline-offset: 1px; }
23
+ .fr-btn:disabled { opacity: .45; cursor: default; }
24
+ .fr-btn.fr-icon { width: 30px; padding: 0; justify-content: center; }
25
+ .fr-btn.fr-primary { background: var(--fr-accent); color: var(--fr-accent-ink); }
26
+ .fr-btn.fr-primary:hover { filter: brightness(1.08); }
27
+ .fr-btn[aria-expanded="true"], .fr-btn[aria-pressed="true"] { background: var(--fr-hover); border-color: var(--fr-rule); }
28
+ .fr-btn svg { flex: none; }
29
+ .fr-sep { width: 1px; height: 20px; margin: 0 6px; background: var(--fr-rule); }
30
+ .fr-spacer { flex: 1; }
31
+ .fr-pageno { display: inline-flex; align-items: center; gap: 4px; margin: 0 4px; color: var(--fr-ink-2); font-variant-numeric: tabular-nums; }
32
+ .fr-pageno input { width: 44px; height: 28px; text-align: center; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); font: inherit; color: var(--fr-ink); }
33
+ .fr-zoom { height: 30px; padding: 0 6px; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); background: var(--fr-panel); font: inherit; color: var(--fr-ink); }
34
+ .fr-menu { position: relative; }
35
+ .fr-menu-list { position: absolute; right: 0; top: calc(100% + 4px); z-index: 20; min-width: 180px; padding: 4px; background: var(--fr-panel); border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); box-shadow: 0 8px 24px rgba(14, 23, 38, .14); display: flex; flex-direction: column; }
36
+ .fr-menu-list[hidden] { display: none; }
37
+ .fr-menu-list button { text-align: left; padding: 8px 10px; border: 0; background: none; border-radius: 4px; font: inherit; color: var(--fr-ink); cursor: pointer; }
38
+ .fr-menu-list button:hover, .fr-menu-list button:focus-visible { background: var(--fr-hover); outline: none; }
39
+
40
+ .fr-params { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 14px; padding: 10px 12px; background: var(--fr-panel); border-bottom: 1px solid var(--fr-rule); }
41
+ .fr-params[hidden] { display: none; }
42
+ .fr-param { display: flex; flex-direction: column; gap: 3px; }
43
+ .fr-param label { font-size: 12px; color: var(--fr-ink-2); font-weight: 600; }
44
+ .fr-param label b { color: #c8102e; }
45
+ .fr-param input, .fr-param select { height: 30px; min-width: 140px; padding: 0 8px; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); font: inherit; background: #fff; color: var(--fr-ink); }
46
+
47
+ .fr-body { position: relative; flex: 1; min-height: 0; overflow: auto; outline: none; }
48
+ .fr-pages { display: flex; flex-direction: column; align-items: center; gap: 16px; padding: 16px 24px 32px; min-width: min-content; }
49
+ .fr-page { width: var(--fr-page-w, 794px); height: var(--fr-page-h, 1123px); flex: none; background: #fff; box-shadow: 0 1px 3px rgba(14, 23, 38, .18), 0 6px 18px -8px rgba(14, 23, 38, .25); }
50
+ .fr-page-svg { display: block; width: 100%; height: 100%; }
51
+ .fr-page { position: relative; }
52
+ .fr-hit { position: absolute; background: rgba(242, 169, 0, .38); outline: 2px solid #f2a900; border-radius: 2px; pointer-events: none; }
53
+ .fr-search { display: inline-flex; align-items: center; gap: 4px; height: 30px; padding: 0 8px; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); color: var(--fr-ink-2); background: var(--fr-panel); }
54
+ .fr-search input { width: 120px; border: 0; outline: none; font: inherit; color: var(--fr-ink); background: none; }
55
+ .fr-search:focus-within { border-color: var(--fr-accent); }
56
+ .fr-search-count { font-size: 12px; white-space: nowrap; font-variant-numeric: tabular-nums; }
57
+ .fr-empty { margin: 48px auto; color: var(--fr-ink-2); }
58
+ .fr-overlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 10px; background: rgba(233, 236, 241, .72); font-weight: 600; color: var(--fr-ink-2); z-index: 5; }
59
+ .fr-overlay[hidden] { display: none; }
60
+ .fr-spinner { width: 18px; height: 18px; border: 2px solid var(--fr-rule); border-top-color: var(--fr-accent); border-radius: 50%; animation: fr-spin .8s linear infinite; }
61
+ @keyframes fr-spin { to { transform: rotate(360deg); } }
62
+ @media (prefers-reduced-motion: reduce) { .fr-spinner { animation-duration: 2.4s; } }
63
+ .fr-status { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 4px 10px; background: var(--fr-panel); border-top: 1px solid var(--fr-rule); color: var(--fr-ink-2); font-size: 12px; font-variant-numeric: tabular-nums; min-height: 26px; }
64
+ .fr-badge { color: var(--fr-ink-2); text-decoration: none; border: 1px solid var(--fr-rule); border-radius: 999px; padding: 0 8px; }
65
+ .fr-badge[hidden] { display: none; }
66
+
67
+ @media (max-width: 640px) {
68
+ .fr-btn span { display: none; }
69
+ .fr-btn { padding: 0 7px; }
70
+ .fr-pages { padding: 10px 8px 24px; }
71
+ }
72
+ @media print {
73
+ .fr-viewer .fr-toolbar, .fr-viewer .fr-status, .fr-viewer .fr-params { display: none; }
74
+ }
75
+
76
+ /* ── Designer ─────────────────────────────────── */
77
+ .fr-designer { outline: none; }
78
+ .fr-designer .fr-toolbar { gap: 1px; }
79
+ .fr-designer .fr-group { display: inline-flex; align-items: center; gap: 1px; flex-wrap: wrap; }
80
+ .fr-designer.is-preview .fr-design-only, .fr-designer.is-json .fr-design-only { display: none; }
81
+ .fr-tabs { display: inline-flex; padding: 2px; background: var(--fr-bg); border-radius: 7px; }
82
+ .fr-tab { height: 26px; padding: 0 12px; border: 0; border-radius: 5px; background: none; font: inherit; font-weight: 600; color: var(--fr-ink-2); cursor: pointer; }
83
+ .fr-tab[aria-selected="true"] { background: var(--fr-panel); color: var(--fr-ink); box-shadow: 0 1px 2px rgba(14, 23, 38, .12); }
84
+ .fr-zoom-label { min-width: 42px; text-align: center; font-variant-numeric: tabular-nums; color: var(--fr-ink-2); }
85
+ .fr-dz { flex: 1; min-height: 0; display: grid; grid-template-columns: 200px minmax(0, 1fr) 270px; }
86
+ .fr-designer.is-preview .fr-dz, .fr-designer.is-json .fr-dz { grid-template-columns: minmax(0, 1fr); }
87
+ .fr-designer.is-preview .fr-dz-left, .fr-designer.is-preview .fr-dz-right, .fr-designer.is-json .fr-dz-left, .fr-designer.is-json .fr-dz-right { display: none; }
88
+ .fr-dz-left, .fr-dz-right { background: var(--fr-panel); overflow: auto; min-height: 0; }
89
+ .fr-dz-left { border-right: 1px solid var(--fr-rule); padding: 8px; }
90
+ .fr-dz-right { border-left: 1px solid var(--fr-rule); }
91
+ .fr-dz-left h3 { margin: 10px 4px 6px; font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--fr-ink-2); }
92
+ .fr-dz-left h3:first-child { margin-top: 2px; }
93
+ .fr-dz-tools { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; }
94
+ .fr-dz-tool { display: flex; align-items: center; gap: 6px; padding: 6px; word-break: keep-all; overflow-wrap: anywhere; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); background: var(--fr-panel); font: inherit; font-size: 12px; color: var(--fr-ink); cursor: grab; text-align: left; }
95
+ .fr-dz-tool:hover, .fr-dz-field:hover { border-color: var(--fr-accent); color: var(--fr-accent); }
96
+ .fr-dz-fields { display: flex; flex-wrap: wrap; gap: 4px; }
97
+ .fr-dz-field { padding: 3px 8px; border: 1px solid var(--fr-rule); border-radius: 999px; background: #f7f9fc; font: 12px/1.4 ui-monospace, Consolas, monospace; color: var(--fr-ink); cursor: grab; max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
98
+ .fr-dz-empty { margin: 0 4px; color: var(--fr-ink-2); font-size: 12px; }
99
+ .fr-dz-bandopt { display: flex; align-items: center; gap: 6px; padding: 2px 4px; font-size: 12.5px; cursor: pointer; }
100
+ .fr-dz-groupopt { display: flex; align-items: center; justify-content: space-between; gap: 4px; padding: 2px 4px; font-size: 12px; }
101
+ .fr-dz-groupopt code { font-size: 11.5px; }
102
+ .fr-dz-addgroup { display: flex; gap: 4px; margin-top: 6px; }
103
+ .fr-dz-addgroup select { flex: 1; min-width: 0; height: 30px; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); font: inherit; font-size: 12px; }
104
+ .fr-dz-addgroup .fr-btn span { font-size: 12px; }
105
+ .fr-dz-center { position: relative; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
106
+ .fr-dz-canvas { flex: 1; overflow: auto; padding: 24px 32px 64px; outline: none; }
107
+ .fr-dz-canvas[hidden], .fr-dz-preview[hidden], .fr-dz-json[hidden] { display: none; }
108
+ .fr-dz-page { margin: 0 auto; background: #fff; box-shadow: 0 1px 3px rgba(14, 23, 38, .16), 0 8px 24px -12px rgba(14, 23, 38, .3); user-select: none; }
109
+ .fr-dz-band { position: relative; }
110
+ .fr-dz-band-head { display: flex; justify-content: space-between; align-items: center; height: 20px; padding: 0 8px; background: #eef1f6; border-top: 1px solid var(--fr-rule); border-bottom: 1px solid var(--fr-rule); font-size: 11px; font-weight: 600; color: var(--fr-ink-2); cursor: pointer; }
111
+ .fr-dz-band-head small { font-weight: 500; font-variant-numeric: tabular-nums; }
112
+ .fr-dz-band.is-selected .fr-dz-band-head { background: #dfe6ff; color: var(--fr-accent); }
113
+ .fr-dz-band-area { position: relative; background-image: radial-gradient(circle, #d3d9e3 .8px, transparent .9px); overflow: visible; }
114
+ .fr-dz-band-resize { height: 5px; margin-top: -2px; position: relative; z-index: 3; cursor: ns-resize; }
115
+ .fr-dz-band-resize:hover { background: var(--fr-accent); opacity: .5; }
116
+ .fr-dz-hint { position: absolute; left: 8px; top: 50%; transform: translateY(-50%); color: #a6b0c0; font-size: 11px; pointer-events: none; white-space: nowrap; }
117
+ .fr-dz-el { position: absolute; cursor: move; outline: 1px dashed rgba(35, 64, 245, .18); }
118
+ .fr-dz-el:hover { outline-color: rgba(35, 64, 245, .55); }
119
+ .fr-dz-el.is-selected { outline: 1.5px solid var(--fr-accent); z-index: 2; }
120
+ .fr-dz-el.is-line { outline-offset: 2px; }
121
+ .fr-dz-el > * { pointer-events: none; }
122
+ .fr-dz-el > .fr-dz-h, .fr-dz-el > .fr-dz-inline { pointer-events: auto; }
123
+ .fr-dz-text { position: absolute; inset: 0; display: flex; flex-direction: column; overflow: hidden; white-space: pre-wrap; word-break: break-all; }
124
+ .fr-dz-text small { margin-left: 4px; font-size: 9px; color: #7a8599; font-weight: 400; }
125
+ .fr-dz-expr { color: #1a2fc0; }
126
+ .fr-dz-rect { position: absolute; inset: 0; }
127
+ .fr-dz-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
128
+ .fr-dz-el img { width: 100%; height: 100%; display: block; }
129
+ .fr-dz-ph { position: absolute; inset: 0; display: grid; place-items: center; background: repeating-linear-gradient(45deg, #f4f6fa, #f4f6fa 4px, #eceff5 4px, #eceff5 8px); color: #8a94a6; }
130
+ .fr-dz-h { position: absolute; width: 8px; height: 8px; background: #fff; border: 1.5px solid var(--fr-accent); border-radius: 2px; z-index: 3; }
131
+ .fr-dz-h-nw { left: -4px; top: -4px; cursor: nwse-resize; }
132
+ .fr-dz-h-n { left: calc(50% - 4px); top: -4px; cursor: ns-resize; }
133
+ .fr-dz-h-ne { right: -4px; top: -4px; cursor: nesw-resize; }
134
+ .fr-dz-h-e { right: -4px; top: calc(50% - 4px); cursor: ew-resize; }
135
+ .fr-dz-h-se { right: -4px; bottom: -4px; cursor: nwse-resize; }
136
+ .fr-dz-h-s { left: calc(50% - 4px); bottom: -4px; cursor: ns-resize; }
137
+ .fr-dz-h-sw { left: -4px; bottom: -4px; cursor: nesw-resize; }
138
+ .fr-dz-h-w { left: -4px; top: calc(50% - 4px); cursor: ew-resize; }
139
+ .fr-dz-marquee { position: absolute; border: 1px solid var(--fr-accent); background: rgba(35, 64, 245, .08); pointer-events: none; z-index: 4; }
140
+ .fr-dz-inline { position: absolute; inset: 0; min-height: 24px; z-index: 5; font: 13px/1.4 var(--fr-font); padding: 2px 4px; border: 2px solid var(--fr-accent); resize: none; }
141
+ .fr-dz-preview { flex: 1; min-height: 0; }
142
+ .fr-dz-preview .fr-viewer { border: 0; border-radius: 0; }
143
+ .fr-dz-json { flex: 1; min-height: 0; display: flex; flex-direction: column; }
144
+ .fr-dz-json textarea { flex: 1; border: 0; padding: 14px 16px; font: 12.5px/1.55 ui-monospace, "Cascadia Code", Consolas, monospace; resize: none; outline: none; background: #fbfcfe; color: var(--fr-ink); }
145
+ .fr-dz-json-bar { display: flex; justify-content: flex-end; align-items: center; gap: 12px; padding: 8px 12px; border-top: 1px solid var(--fr-rule); background: var(--fr-panel); }
146
+ .fr-dz-json-err { color: #c8102e; font-size: 12px; }
147
+ .fr-dz-props { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding: 4px 12px 24px; }
148
+ .fr-dz-sec { grid-column: 1 / -1; margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--fr-rule); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; color: var(--fr-ink-2); }
149
+ .fr-dz-sec:first-child { border-top: 0; margin-top: 4px; padding-top: 4px; }
150
+ .fr-dz-prop { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
151
+ .fr-dz-prop.is-wide { grid-column: 1 / -1; }
152
+ .fr-dz-prop.is-check { flex-direction: row; align-items: center; gap: 6px; grid-column: 1 / -1; font-size: 12.5px; cursor: pointer; }
153
+ .fr-dz-plabel { font-size: 11.5px; color: var(--fr-ink-2); font-weight: 600; }
154
+ .fr-dz-prop input[type=text], .fr-dz-prop input[type=number], .fr-dz-prop select, .fr-dz-prop textarea { width: 100%; height: 28px; padding: 0 7px; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); font: inherit; font-size: 12.5px; color: var(--fr-ink); background: #fff; }
155
+ .fr-dz-prop textarea { height: auto; padding: 5px 7px; font-family: ui-monospace, Consolas, monospace; resize: vertical; }
156
+ .fr-dz-prop input.is-expr { font-family: ui-monospace, Consolas, monospace; }
157
+ .fr-dz-prop :focus-visible { outline: 2px solid var(--fr-accent); outline-offset: 0; }
158
+ .fr-dz-err { color: #c8102e; font-size: 11px; }
159
+ .fr-dz-err:empty { display: none; }
160
+ .fr-dz-color { display: flex; gap: 4px; }
161
+ .fr-dz-color input[type=color] { width: 30px; height: 28px; padding: 1px; border: 1px solid var(--fr-rule); border-radius: var(--fr-radius); background: #fff; flex: none; }
162
+ .fr-dz-toggles { display: flex; gap: 3px; flex-wrap: wrap; }
163
+ .fr-dz-toggle { width: 30px; height: 28px; padding: 0; justify-content: center; border: 1px solid var(--fr-rule); font-weight: 700; }
164
+ .fr-dz-toggle[aria-pressed="true"] { background: #dfe6ff; border-color: var(--fr-accent); color: var(--fr-accent); }
165
+ @media (max-width: 960px) {
166
+ .fr-dz { grid-template-columns: 150px minmax(0, 1fr); }
167
+ .fr-dz-right { display: none; }
168
+ }