pgkiln 0.48.0 → 0.50.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.
Files changed (63) hide show
  1. package/SECURITY.md +3 -2
  2. package/db/migrations/116_dump_jobs.sql +41 -0
  3. package/db/migrations/117_rest_handlers.sql +63 -0
  4. package/db/migrations/118_change_log.sql +54 -0
  5. package/docs/apex-feature-parity.md +9 -9
  6. package/docs/guide/01-installation.md +7 -0
  7. package/docs/guide/03-builder.md +227 -10
  8. package/docs/guide/08-security.md +11 -0
  9. package/docs/guide/12-development.md +64 -13
  10. package/docs/guide/13-rest-api.md +59 -1
  11. package/docs/guide/15-extensions.md +1 -1
  12. package/examples/hr/hr_62_rest_module.sql +39 -0
  13. package/package.json +1 -1
  14. package/public/app.css +1 -1
  15. package/public/builder-icons.svg +2 -0
  16. package/public/builder.css +478 -173
  17. package/public/builder.js +48 -0
  18. package/public/code-editor.css +32 -79
  19. package/public/code-editor.js +58 -3
  20. package/public/data-modeler.css +17 -14
  21. package/public/sql-monitor.js +73 -0
  22. package/public/worksheet.css +14 -7
  23. package/public/worksheet.js +119 -3
  24. package/src/app.ts +6 -0
  25. package/src/automations.ts +6 -0
  26. package/src/binds.ts +2 -1
  27. package/src/builder/advisor.ts +24 -2
  28. package/src/builder/autorest.ts +3 -2
  29. package/src/builder/changelog.ts +240 -0
  30. package/src/builder/components.ts +1 -1
  31. package/src/builder/data-modeler.ts +1 -1
  32. package/src/builder/datapump.ts +364 -0
  33. package/src/builder/db-users.ts +2 -2
  34. package/src/builder/ddl-tools.ts +13 -4
  35. package/src/builder/find-workspace.ts +2 -2
  36. package/src/builder/object-browser.ts +4 -4
  37. package/src/builder/plan-view.ts +25 -0
  38. package/src/builder/querybuilder.ts +1 -1
  39. package/src/builder/quicksql.ts +1 -1
  40. package/src/builder/rest-modules.ts +629 -0
  41. package/src/builder/rest.ts +1 -0
  42. package/src/builder/routes.ts +4 -2
  43. package/src/builder/scheduling.ts +495 -0
  44. package/src/builder/scripts.ts +1 -1
  45. package/src/builder/sql-charts.ts +1 -1
  46. package/src/builder/sql-monitor.ts +397 -0
  47. package/src/builder/sql-tools.ts +6 -2
  48. package/src/builder/sql-utilities.ts +7 -39
  49. package/src/builder/sql.ts +6 -0
  50. package/src/builder/table-editor.ts +6 -3
  51. package/src/builder/top-sql.ts +24 -6
  52. package/src/builder/ui.ts +6 -4
  53. package/src/builder/worksheet.ts +173 -41
  54. package/src/changelog.ts +109 -0
  55. package/src/cron-schedule.ts +282 -0
  56. package/src/datapump.ts +546 -0
  57. package/src/dumpscript.ts +407 -0
  58. package/src/pgcron.ts +225 -0
  59. package/src/runtime/rest-handlers.ts +75 -0
  60. package/src/runtime/rest.ts +116 -22
  61. package/src/session.ts +5 -0
  62. package/src/sqlworksheet.ts +9 -6
  63. package/src/worksheet-txn.ts +270 -0
@@ -1,100 +1,295 @@
1
1
  /* pgkiln builder: an IDE look (dark chrome, icon rail, dense panes), loaded
2
2
  only by builder pages after app.css; the runtime never loads it.
3
- Colours are tokens: the light set first, the dark set for data-theme="dark"
4
- and for "System" when the OS prefers dark. The chrome (rail and toolbar)
5
- is dark in both themes. */
3
+
4
+ (sprint 105) Design tokens. Everything below draws from these custom
5
+ properties: change a colour, radius or shadow here, not in a rule.
6
+ - neutrals: a warm "stone" scale (--bg, --surface…, --text, --muted, --border)
7
+ - brand: the kiln's ember (--hot for primary actions and the logo, --accent for
8
+ links, focus rings and selections); contrast: --hot on white text 5.2:1,
9
+ --accent ≥ 4.8:1 on every surface, --muted ≥ 5.6:1, in both themes
10
+ - elevation: --shadow-xs … --shadow-lg; radius: --radius-sm / --radius / --radius-lg
11
+ - type: --fs-xs … --fs-xl; motion: --ease and --dur (none under prefers-reduced-motion)
12
+ - code (sprint 108): --ce-* for public/code-editor.js and read-only <pre data-code-view>; every
13
+ syntax colour ≥ 4.5:1 on --ce-bg in both themes (test/e2e/code-editor.test.ts checks it)
14
+ The light set first, the dark set for data-theme="dark" and for "System" when
15
+ the OS prefers dark. The chrome (rail, toolbar, status bar) is dark in both
16
+ themes (the same colours), a shade deeper than the page in the dark one. */
6
17
 
7
18
  :is(.ide, .ide-login) {
8
- --rail-w: 52px;
19
+ --rail-w: 56px;
9
20
  --bar-h: 48px;
10
- --chrome: #2b2a28;
11
- --chrome-2: #3a3935;
12
- --chrome-3: #4a4844;
13
- --chrome-text: #efece7;
14
- --chrome-muted: #b6b1a9;
15
- --chrome-border: #45433f;
16
- --hot: #1a73a8;
17
- --hot-hover: #1f83bd;
21
+ --page-px: 22px;
22
+ --page-py: 18px;
23
+
24
+ /* chrome: the rail, the top toolbar and the status bar */
25
+ --chrome: #13110f;
26
+ --chrome-2: #25221f;
27
+ --chrome-3: #37332f;
28
+ --chrome-text: #f5f4f2;
29
+ --chrome-muted: #aca59f;
30
+ --chrome-border: #2a2623;
31
+ --chrome-glow: rgb(234 88 12 / 16%);
32
+
33
+ /* brand: ember */
34
+ --ember-1: #fb923c;
35
+ --ember-2: #ea580c;
36
+ --ember-3: #c2410c;
37
+ --hot: #c2410c;
38
+ --hot-hover: #ad3a0b;
18
39
  --hot-text: #ffffff;
19
- --sel-bg: #1a73a8;
20
- --sel-text: #ffffff;
40
+ --sel-bg: #fde3d2;
41
+ --sel-text: var(--text);
42
+ --sel-bar: var(--hot);
21
43
  --warn: #b7791f;
22
44
 
23
- --bg: #e8e6e2;
45
+ /* neutrals */
46
+ --bg: #f6f5f3;
24
47
  --surface: #ffffff;
25
- --surface-2: #f6f5f2;
26
- --surface-3: #ebe9e5;
27
- --text: #1e1d1b;
28
- --muted: #5e5a54;
29
- --border: #d3d0ca;
30
- --accent: #0f66a0;
48
+ --surface-2: #faf9f7;
49
+ --surface-3: #f1efec;
50
+ --text: #1c1917;
51
+ --muted: #5c5650;
52
+ --border: #e7e4e0;
53
+ --border-strong: #d6d1cb;
54
+ --accent: #b8410c;
31
55
  --accent-text: #ffffff;
32
- --accent-soft: #dbeaf5;
33
- --gold: #8a5a00;
34
- --canvas: #dad8d3;
56
+ --accent-soft: #fdeee4;
57
+ --ring: rgb(194 65 12 / 28%);
58
+ --gold: #b8410c;
59
+ --canvas: #efede9;
60
+ --canvas-dot: #d9d5cf;
35
61
  --block: #ffffff;
36
- --block-head: #f1efeb;
37
- --code-bg: #f8f7f4;
38
- --radius: 4px;
39
- --shadow: none;
62
+ --block-head: #f7f5f2;
63
+ --code-bg: #fbfaf8;
64
+ --field-border: var(--border-strong);
65
+
66
+ /* code editor (sprint 108, public/code-editor.js): every token colour is at least 4.5:1 on --ce-bg
67
+ (keywords take the ember; the others cool hues so they stay apart) */
68
+ --ce-bg: #fdfcfb;
69
+ --ce-gutter: #f5f3f0;
70
+ --ce-gutter-text: #6b645d;
71
+ --ce-gutter-active: #1c1917;
72
+ --ce-text: #1c1917;
73
+ --ce-kw: #b23a0a;
74
+ --ce-type: #0e6b66;
75
+ --ce-fn: #2457a6;
76
+ --ce-str: #3a7516;
77
+ --ce-num: #8a3ea0;
78
+ --ce-com: #736c66;
79
+ --ce-bind: #b02a5c;
80
+ --ce-qid: #80590a;
81
+ --ce-op: #5c5650;
82
+ --ce-tag: #2457a6;
83
+ --ce-attr: #b23a0a;
84
+ --ce-err: #c0262d;
85
+ --ce-match: rgb(234 88 12 / 16%);
86
+ --ce-match-ring: rgb(194 65 12 / 55%);
87
+ --ce-line: rgb(28 25 23 / 4.5%);
88
+ --ce-select: rgb(234 88 12 / 20%);
89
+
90
+ /* shape, elevation, type, motion */
91
+ --radius-sm: 6px;
92
+ --radius: 8px;
93
+ --radius-lg: 12px;
94
+ --shadow-xs: 0 1px 1px rgb(28 25 23 / 4%);
95
+ --shadow-sm: 0 1px 2px rgb(28 25 23 / 6%), 0 1px 3px rgb(28 25 23 / 4%);
96
+ --shadow-md: 0 2px 4px rgb(28 25 23 / 4%), 0 8px 20px -4px rgb(28 25 23 / 10%);
97
+ --shadow-lg: 0 4px 8px rgb(28 25 23 / 6%), 0 16px 40px -8px rgb(28 25 23 / 22%);
98
+ --shadow: var(--shadow-xs);
99
+ --font: "Inter", "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, "SF Pro Text", Roboto, "Noto Sans", "Helvetica Neue", sans-serif;
100
+ --mono: "JetBrains Mono", "Cascadia Code", "SF Mono", ui-monospace, Menlo, Consolas, "Liberation Mono", monospace;
101
+ --fs-xs: 11.5px;
102
+ --fs-sm: 12.5px;
103
+ --fs-base: 13px;
104
+ --fs-md: 14px;
105
+ --fs-lg: 16px;
106
+ --fs-xl: 20px;
107
+ --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
108
+ --dur: 140ms;
40
109
  color-scheme: light;
41
110
  }
42
111
  @media (prefers-color-scheme: dark) {
43
112
  :root:not([data-theme="light"]) :is(.ide, .ide-login) {
44
- --bg: #1d1c1b; --surface: #2a2927; --surface-2: #31302d; --surface-3: #3b3936; --text: #e9e6e1; --muted: #aaa59d;
45
- --border: #44423e; --accent: #62b2ea; --accent-text: #0b1824; --accent-soft: #233a4c; --gold: #e3b75e;
46
- --canvas: #211f1e; --block: #33322f; --block-head: #3d3b38; --code-bg: #242321; --warn: #e0a740;
113
+ --chrome-glow: rgb(234 88 12 / 13%);
114
+ --bg: #181715; --surface: #1f1d1b; --surface-2: #242220; --surface-3: #2d2b28; --text: #edebe8; --muted: #a8a19a;
115
+ --border: #312e2b; --border-strong: #423e39; --accent: #ff9152; --accent-text: #1a0b03; --accent-soft: #3a1f12; --ring: rgb(255 145 82 / 30%); --sel-bg: #4a2816; --sel-bar: #ff9152;
116
+ --gold: #ff9152; --canvas: #151412; --canvas-dot: #2a2825; --block: #222120; --block-head: #292725; --code-bg: #1a1917; --warn: #e0a740;
117
+ --ce-bg: #1a1917; --ce-gutter: #1f1d1b; --ce-gutter-text: #8f8880; --ce-gutter-active: #e9e6e3; --ce-text: #e9e6e3;
118
+ --ce-kw: #ff9152; --ce-type: #5cc8bd; --ce-fn: #8ab4ff; --ce-str: #a5d68a; --ce-num: #d4a8ff; --ce-com: #938b83; --ce-bind: #ff8fb8;
119
+ --ce-qid: #e6c26a; --ce-op: #b8b0a8; --ce-tag: #8ab4ff; --ce-attr: #ff9152; --ce-err: #ff7a70;
120
+ --ce-match: rgb(255 145 82 / 22%); --ce-match-ring: rgb(255 145 82 / 60%); --ce-line: rgb(255 255 255 / 4.5%); --ce-select: rgb(255 145 82 / 28%);
121
+ --shadow-xs: 0 1px 1px rgb(0 0 0 / 30%);
122
+ --shadow-sm: 0 1px 2px rgb(0 0 0 / 40%), inset 0 1px 0 rgb(255 255 255 / 3%);
123
+ --shadow-md: 0 4px 16px -2px rgb(0 0 0 / 50%), inset 0 1px 0 rgb(255 255 255 / 4%);
124
+ --shadow-lg: 0 18px 44px -8px rgb(0 0 0 / 65%), 0 0 0 1px rgb(255 255 255 / 5%);
47
125
  --pd-c-region: #7fb4ea; --pd-c-item: #7ccf8c; --pd-c-button: #f0a35e; --pd-c-da: #c49cf0; --pd-c-process: #ee8fbf;
48
126
  color-scheme: dark;
49
127
  }
50
128
  }
51
129
  :root[data-theme="dark"] :is(.ide, .ide-login) {
52
- --bg: #1d1c1b; --surface: #2a2927; --surface-2: #31302d; --surface-3: #3b3936; --text: #e9e6e1; --muted: #aaa59d;
53
- --border: #44423e; --accent: #62b2ea; --accent-text: #0b1824; --accent-soft: #233a4c; --gold: #e3b75e;
54
- --canvas: #211f1e; --block: #33322f; --block-head: #3d3b38; --code-bg: #242321; --warn: #e0a740;
130
+ --chrome-glow: rgb(234 88 12 / 13%);
131
+ --bg: #181715; --surface: #1f1d1b; --surface-2: #242220; --surface-3: #2d2b28; --text: #edebe8; --muted: #a8a19a;
132
+ --border: #312e2b; --border-strong: #423e39; --accent: #ff9152; --accent-text: #1a0b03; --accent-soft: #3a1f12; --ring: rgb(255 145 82 / 30%); --sel-bg: #4a2816; --sel-bar: #ff9152;
133
+ --gold: #ff9152; --canvas: #151412; --canvas-dot: #2a2825; --block: #222120; --block-head: #292725; --code-bg: #1a1917; --warn: #e0a740;
134
+ --ce-bg: #1a1917; --ce-gutter: #1f1d1b; --ce-gutter-text: #8f8880; --ce-gutter-active: #e9e6e3; --ce-text: #e9e6e3;
135
+ --ce-kw: #ff9152; --ce-type: #5cc8bd; --ce-fn: #8ab4ff; --ce-str: #a5d68a; --ce-num: #d4a8ff; --ce-com: #938b83; --ce-bind: #ff8fb8;
136
+ --ce-qid: #e6c26a; --ce-op: #b8b0a8; --ce-tag: #8ab4ff; --ce-attr: #ff9152; --ce-err: #ff7a70;
137
+ --ce-match: rgb(255 145 82 / 22%); --ce-match-ring: rgb(255 145 82 / 60%); --ce-line: rgb(255 255 255 / 4.5%); --ce-select: rgb(255 145 82 / 28%);
138
+ --shadow-xs: 0 1px 1px rgb(0 0 0 / 30%);
139
+ --shadow-sm: 0 1px 2px rgb(0 0 0 / 40%), inset 0 1px 0 rgb(255 255 255 / 3%);
140
+ --shadow-md: 0 4px 16px -2px rgb(0 0 0 / 50%), inset 0 1px 0 rgb(255 255 255 / 4%);
141
+ --shadow-lg: 0 18px 44px -8px rgb(0 0 0 / 65%), 0 0 0 1px rgb(255 255 255 / 5%);
55
142
  --pd-c-region: #7fb4ea; --pd-c-item: #7ccf8c; --pd-c-button: #f0a35e; --pd-c-da: #c49cf0; --pd-c-process: #ee8fbf;
56
143
  color-scheme: dark;
57
144
  }
58
145
 
59
- body.ide { margin: 0; min-height: 100vh; min-height: 100dvh; padding-left: var(--rail-w); background: var(--bg); color: var(--text); font-size: 13px; line-height: 1.45; }
60
- .ide :focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
146
+ body.ide {
147
+ margin: 0; min-height: 100vh; min-height: 100dvh; padding-left: var(--rail-w); background: var(--bg); color: var(--text);
148
+ font-family: var(--font); font-size: var(--fs-base); line-height: 1.45;
149
+ font-feature-settings: "cv11", "ss01", "ss03"; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility;
150
+ }
151
+ .ide ::selection { background: color-mix(in srgb, var(--accent) 26%, transparent); }
152
+ .ide :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }
61
153
  .ide .icon { width: 16px; height: 16px; }
62
- .ide h1 { font-size: 17px; font-weight: 650; }
63
- .ide h2 { font-size: 13.5px; }
64
- .ide h3 { font-size: 13px; }
154
+ .ide h1 { font-size: var(--fs-xl); font-weight: 680; letter-spacing: -0.018em; line-height: 1.25; }
155
+ .ide h2 { font-size: var(--fs-md); font-weight: 650; letter-spacing: -0.006em; }
156
+ .ide h3 { font-size: var(--fs-base); font-weight: 650; }
65
157
  .ide code { font-size: 0.92em; }
66
158
  .ide .small { font-size: 12px; }
67
159
  .ide .skip-link { z-index: 60; }
160
+ .ide { scrollbar-color: var(--border-strong) transparent; }
161
+ .ide a { text-underline-offset: 2px; text-decoration-thickness: from-font; }
162
+
163
+ /* ------------------------------------------------------------ foundations (sprint 105): the shared controls */
164
+ .ide .btn {
165
+ min-height: 30px; font-weight: 560; border-color: var(--border-strong); background: var(--surface); box-shadow: var(--shadow-xs);
166
+ transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), color var(--dur) var(--ease);
167
+ }
168
+ .ide .btn:hover { background: var(--surface-3); border-color: color-mix(in srgb, var(--text) 22%, var(--border-strong)); }
169
+ .ide .btn:active { box-shadow: none; translate: 0 0.5px; }
170
+ .ide .btn .icon { width: 15px; height: 15px; }
171
+ .ide .btn-run, .ide .btn-hot, .ide-login .btn-hot {
172
+ background: var(--hot); border-color: color-mix(in srgb, var(--hot) 80%, black); color: var(--hot-text);
173
+ box-shadow: inset 0 1px 0 rgb(255 255 255 / 16%), 0 1px 2px rgb(124 45 18 / 30%);
174
+ }
175
+ .ide .btn-run:hover, .ide .btn-hot:hover, .ide-login .btn-hot:hover { background: var(--hot-hover); border-color: color-mix(in srgb, var(--hot-hover) 80%, black); }
176
+ .ide .btn-danger { color: var(--danger); }
177
+ .ide .btn-danger:hover { background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); }
178
+ /* fields: app.css draws their border with var(--field-border); a ring on focus (a field that draws its own
179
+ frame, like the code editor or the property filter, sets box-shadow: none) */
180
+ .ide :where(input:not([type=checkbox], [type=radio], [type=color], [type=range], [type=file]), select, textarea) {
181
+ transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
182
+ }
183
+ .ide :where(input:not([type=checkbox], [type=radio], [type=color], [type=range], [type=file]), select, textarea):focus-visible {
184
+ outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--ring);
185
+ }
186
+ .ide input::placeholder, .ide textarea::placeholder { color: color-mix(in srgb, var(--muted) 85%, transparent); }
187
+ /* selects: one chevron in both themes (img-src allows data: URIs) */
188
+ .ide select:not([multiple]):not([size]) {
189
+ appearance: none; -webkit-appearance: none; padding-right: 1.9rem;
190
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23857d75' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m7 10 5 5 5-5'/%3E%3C/svg%3E");
191
+ background-repeat: no-repeat; background-position: right 0.5rem center; background-size: 14px;
192
+ }
193
+ .ide input[type=checkbox], .ide input[type=radio] { accent-color: var(--hot); }
194
+ .ide .label { color: var(--muted); font-weight: 600; }
195
+ .ide .help { color: var(--muted); }
196
+ .ide .alert { border-radius: var(--radius); box-shadow: var(--shadow-xs); }
197
+ .ide .badge { background: var(--accent-soft); color: var(--accent); font-weight: 650; }
198
+ .ide .tag { border-radius: 99px; padding: 0.05rem 0.5rem; font-weight: 600; background: var(--surface-3); color: var(--muted); box-shadow: inset 0 0 0 1px var(--border); }
199
+ .ide kbd { border-radius: 4px; border-color: var(--border-strong); background: var(--surface); color: var(--muted); }
200
+ /* menus: rounded, elevated, rows with a hover background */
201
+ .ide .menu-panel { border-radius: var(--radius); border-color: var(--border-strong); box-shadow: var(--shadow-lg); padding: 4px 0; }
202
+ .ide .menu-section { padding: 6px 8px; gap: 2px; }
203
+ .ide .menu-section > :is(strong, .small) { padding: 2px 8px; }
204
+ .ide .menu-links a, .ide .menu-links button { padding: 6px 8px; border-radius: var(--radius-sm); transition: background-color var(--dur) var(--ease); }
205
+ .ide .menu-links a:hover, .ide .menu-links button:hover, .ide .menu-links a:focus-visible { background: var(--surface-3); color: var(--text); }
206
+ .ide .menu-links .icon { color: var(--muted); }
207
+ /* segmented controls */
208
+ .ide .segmented { border-color: var(--border-strong); background: var(--surface-2); padding: 2px; gap: 2px; border-radius: var(--radius-sm); }
209
+ .ide .segmented button { border-radius: 4px; border: 0; }
210
+ .ide .segmented button + button { border-left: 0; }
211
+ .ide .segmented button[aria-pressed="true"] { background: var(--surface); color: var(--text); box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--border-strong); }
212
+ /* reports: quiet headers, row hover, headers that stick inside a scrolling box */
213
+ .ide .table-wrap { border-radius: var(--radius); border-color: var(--border); background: var(--surface); box-shadow: var(--shadow-xs); }
214
+ .ide .report th {
215
+ position: sticky; top: 0; z-index: 1; background: var(--surface-2); color: var(--muted);
216
+ font-size: var(--fs-xs); font-weight: 650; letter-spacing: 0.035em; text-transform: uppercase;
217
+ }
218
+ .ide .report tbody tr { transition: background-color var(--dur) var(--ease); }
219
+ .ide .report tbody tr:hover { background: color-mix(in srgb, var(--accent-soft) 50%, var(--surface-2)); }
220
+ .ide .report td { font-variant-numeric: tabular-nums; }
221
+ .ide .report td.empty, .ide p.empty { color: var(--muted); }
222
+
223
+ /* links in reports and side lists: no underline until hovered */
224
+ .ide .report td a:not(.btn), .ide .sc-links a, .ide .tree a { text-decoration: none; }
225
+ .ide .report td a:not(.btn):hover, .ide .sc-links a:hover { text-decoration: underline; }
226
+ .ide .report td a:not(.btn) { font-weight: 550; color: var(--text); }
227
+ .ide .report td a:not(.btn):hover { color: var(--accent); }
228
+ .ide .sc-links a { color: var(--text); }
229
+ .ide .sc-links a:hover { color: var(--accent); }
230
+ .ide .sc-links a .icon { color: var(--muted); }
231
+ /* link groups (.seg: Report / Icons…) as a segmented control */
232
+ .ide .seg:not(.col) { display: inline-flex; gap: 2px; padding: 2px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface-2); }
233
+ .ide .seg:not(.col) a { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.2rem 0.6rem; border: 0; border-radius: 4px; color: var(--muted); font-weight: 550; transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease); }
234
+ .ide .seg:not(.col) a:hover { color: var(--text); }
235
+ .ide .seg:not(.col) a[aria-current] { background: var(--surface); color: var(--text); box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--border-strong); }
236
+ /* fields in the dark toolbar (search, the designer's page number and page list) */
237
+ .ide-bar :is(input:not([type=checkbox]):not([type=radio]), select) { background-color: var(--chrome-2); color: var(--chrome-text); border-color: var(--chrome-3); }
238
+ .ide-bar input::placeholder { color: var(--chrome-muted); }
239
+ .ide .ide-bar .ide-search input[type=search] {
240
+ height: 30px; padding: 3px 8px 3px 28px; border-radius: var(--radius-sm);
241
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23aca59f' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E");
242
+ background-repeat: no-repeat; background-position: 9px center; background-size: 14px;
243
+ }
244
+ .ide-bar .ide-search input:hover { border-color: color-mix(in srgb, var(--chrome-text) 25%, var(--chrome-3)); }
245
+ .ide-bar :is(input, select):focus-visible { border-color: var(--ember-1); box-shadow: 0 0 0 3px rgb(251 146 60 / 25%); }
246
+ /* phones: the designer's crowded toolbar shows the search as its icon until it has the focus */
247
+ @media (max-width: 640px) {
248
+ .ide.ide-full .ide-bar .ide-search input[type=search]:not(:focus) { width: 30px; padding-right: 0; color: transparent; }
249
+ .ide-full .ide-bar .ide-search input:not(:focus)::placeholder { color: transparent; }
250
+ }
68
251
 
69
252
  /* ------------------------------------------------------------ icon rail */
70
253
  .ide-rail {
71
254
  position: fixed; inset: 0 auto 0 0; z-index: 40; width: var(--rail-w);
72
- display: flex; flex-direction: column; align-items: stretch; padding: 8px 0;
255
+ display: flex; flex-direction: column; align-items: stretch; padding: 10px 0;
73
256
  background: var(--chrome); color: var(--chrome-text); border-right: 1px solid var(--chrome-border);
257
+ background-image: radial-gradient(120px 90px at 50% 0, var(--chrome-glow), transparent 70%);
74
258
  }
259
+ /* the brand mark: an ember flame on a glowing tile */
75
260
  .rail-logo {
76
- display: grid; place-items: center; width: 34px; height: 34px; margin: 0 auto 10px; border-radius: 8px;
77
- background: var(--hot); color: #fff; font-weight: 800; font-size: 15px; letter-spacing: -0.04em; text-decoration: none;
261
+ display: grid; place-items: center; width: 36px; height: 36px; margin: 0 auto 14px; border-radius: 10px;
262
+ background: linear-gradient(150deg, var(--ember-1), var(--ember-2) 55%, var(--ember-3)); color: #fff; text-decoration: none;
263
+ box-shadow: inset 0 1px 0 rgb(255 255 255 / 30%), 0 0 0 1px rgb(0 0 0 / 25%), 0 4px 14px -2px rgb(234 88 12 / 55%);
264
+ transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
78
265
  }
79
- .rail-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
266
+ .rail-logo:hover { box-shadow: inset 0 1px 0 rgb(255 255 255 / 30%), 0 0 0 1px rgb(0 0 0 / 25%), 0 6px 20px -2px rgb(234 88 12 / 75%); transform: translateY(-1px); }
267
+ .rail-logo .icon, .signin-logo .icon { width: 22px; height: 22px; }
268
+ .rail-list { list-style: none; margin: 0; padding: 0 8px; display: flex; flex-direction: column; gap: 4px; }
80
269
  .rail-bottom { margin-top: auto; }
81
- .rail-link { position: relative; display: grid; place-items: center; height: 42px; color: var(--chrome-muted); text-decoration: none; }
82
- .rail-link .icon { width: 22px; height: 22px; stroke-width: 1.7; }
270
+ .rail-link {
271
+ position: relative; display: grid; place-items: center; height: 40px; border-radius: var(--radius); color: var(--chrome-muted); text-decoration: none;
272
+ transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease);
273
+ }
274
+ .rail-link .icon { width: 20px; height: 20px; stroke-width: 1.75; }
83
275
  .rail-link:hover { color: var(--chrome-text); background: var(--chrome-2); }
84
- .rail-link[aria-current] { color: #fff; background: var(--chrome-2); box-shadow: inset 3px 0 0 var(--hot); }
276
+ .rail-link[aria-current] { color: var(--ember-1); background: color-mix(in srgb, var(--ember-2) 16%, var(--chrome-2)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ember-2) 28%, transparent); }
277
+ .rail-link[aria-current]::before { content: ""; position: absolute; left: -8px; top: 9px; bottom: 9px; width: 3px; border-radius: 0 3px 3px 0; background: var(--ember-2); }
85
278
  .rail-label {
86
- position: absolute; left: calc(100% + 8px); top: 50%; transform: translateY(-50%); z-index: 2;
87
- padding: 3px 8px; border-radius: 4px; background: #111; color: #fff; font-size: 12px; white-space: nowrap;
88
- opacity: 0; pointer-events: none; transition: opacity 0.12s;
279
+ position: absolute; left: calc(100% + 12px); top: 50%; transform: translate(-4px, -50%); z-index: 2;
280
+ padding: 4px 9px; border-radius: var(--radius-sm); background: #0c0b0a; color: #f5f4f2; font-size: 12px; font-weight: 550; white-space: nowrap;
281
+ box-shadow: 0 6px 18px rgb(0 0 0 / 35%), 0 0 0 1px rgb(255 255 255 / 8%);
282
+ opacity: 0; pointer-events: none; transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
89
283
  }
90
- .rail-link:hover .rail-label, .rail-link:focus-visible .rail-label { opacity: 1; }
284
+ .rail-link:hover .rail-label, .rail-link:focus-visible .rail-label { opacity: 1; transform: translate(0, -50%); }
91
285
  .rail-user { display: flex; justify-content: center; padding: 6px 0 2px; }
92
286
  .rail-avatar {
93
287
  display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%; cursor: pointer;
94
- background: #2f6f95; color: #fff; font-weight: 700; font-size: 12px; letter-spacing: 0.02em;
288
+ background: linear-gradient(150deg, #57534e, #292524); color: #fff; font-weight: 700; font-size: 12px; letter-spacing: 0.02em;
289
+ box-shadow: inset 0 1px 0 rgb(255 255 255 / 18%), 0 0 0 1px var(--chrome-3); transition: box-shadow var(--dur) var(--ease);
95
290
  }
96
- .rail-avatar:hover { box-shadow: 0 0 0 2px var(--chrome-3); }
97
- .rail-user .menu-panel { position: fixed; left: calc(var(--rail-w) + 6px); top: auto; bottom: 8px; min-width: 250px; font-size: 13px; }
291
+ .rail-avatar:hover { box-shadow: inset 0 1px 0 rgb(255 255 255 / 18%), 0 0 0 2px var(--ember-2); }
292
+ .rail-user .menu-panel { position: fixed; left: calc(var(--rail-w) + 8px); top: auto; bottom: 8px; min-width: 260px; font-size: 13px; }
98
293
  .rail-user .menu-section > strong { font-size: 13.5px; }
99
294
  .ide-theme { margin: 0; }
100
295
  .ide-theme button { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 12.5px; padding: 0.3rem 0.6rem; min-height: 30px; }
@@ -102,9 +297,9 @@ body.ide { margin: 0; min-height: 100vh; min-height: 100dvh; padding-left: var(-
102
297
  .rail-user .menu-links form { margin: 0; }
103
298
  /* workspace switcher in the account menu (064) */
104
299
  .ws-switch { display: flex; flex-direction: column; gap: 2px; margin: 0.35rem 0 0; }
105
- .ws-switch button { display: flex; align-items: center; gap: 0.45rem; width: 100%; border: 0; border-radius: 6px; background: none; color: var(--text); font: inherit; font-size: 13px; padding: 0.35rem 0.5rem; min-height: 32px; cursor: pointer; text-align: left; }
106
- .ws-switch button:hover { color: var(--accent); }
107
- .ws-switch button[aria-pressed="true"] { background: var(--accent); color: var(--accent-text); }
300
+ .ws-switch button { display: flex; align-items: center; gap: 0.45rem; width: 100%; border: 0; border-radius: var(--radius-sm); background: none; color: var(--text); font: inherit; font-size: 13px; padding: 0.35rem 0.5rem; min-height: 32px; cursor: pointer; text-align: left; }
301
+ .ws-switch button:hover { background: var(--surface-3); }
302
+ .ws-switch button[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
108
303
  .ws-switch button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
109
304
  .ws-switch .icon { width: 14px; height: 14px; flex: none; }
110
305
 
@@ -112,28 +307,30 @@ body.ide { margin: 0; min-height: 100vh; min-height: 100dvh; padding-left: var(-
112
307
  .ide-main { min-width: 0; }
113
308
  .ide-bar {
114
309
  position: sticky; top: 0; z-index: 30; display: flex; align-items: center; gap: 6px;
115
- height: var(--bar-h); padding: 0 8px 0 6px; background: var(--chrome); color: var(--chrome-text);
310
+ height: var(--bar-h); padding: 0 10px 0 8px; background: var(--chrome); color: var(--chrome-text);
116
311
  border-bottom: 1px solid var(--chrome-border);
312
+ background-image: linear-gradient(90deg, var(--chrome-glow), transparent 32%);
117
313
  }
118
- .ide-back { display: inline-grid; place-items: center; width: 32px; height: 32px; border-radius: 4px; color: var(--chrome-text); flex: none; }
119
- .ide-back:hover { background: var(--chrome-2); }
314
+ .ide-back { display: inline-grid; place-items: center; width: 30px; height: 30px; border-radius: var(--radius-sm); color: var(--chrome-muted); flex: none; transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease); }
315
+ .ide-back:hover { background: var(--chrome-2); color: var(--chrome-text); }
120
316
  .ide-back .icon { width: 18px; height: 18px; }
121
317
  .ide-crumbs { flex: 1 1 auto; min-width: 0; }
122
318
  .ide-crumbs:first-child { padding-left: 8px; }
123
319
  .ide-crumbs ol { display: flex; align-items: center; list-style: none; margin: 0; padding: 0; min-width: 0; white-space: nowrap; }
124
320
  .ide-crumbs li { min-width: 0; overflow: hidden; text-overflow: ellipsis; flex: 0 3 auto; }
125
321
  .ide-crumbs li:last-child { flex-shrink: 1; }
126
- .ide-crumbs li + li::before { content: "\\"; padding: 0 0.55em; color: var(--chrome-muted); opacity: 0.7; }
127
- .ide-crumbs a { color: var(--chrome-muted); text-decoration: none; }
322
+ .ide-crumbs li + li::before { content: "/"; padding: 0 0.6em; color: var(--chrome-muted); opacity: 0.5; }
323
+ .ide-crumbs a { color: var(--chrome-muted); text-decoration: none; border-radius: 4px; transition: color var(--dur) var(--ease); }
128
324
  .ide-crumbs a:hover { color: var(--chrome-text); text-decoration: underline; }
129
- .ide-crumbs [aria-current] { color: var(--chrome-text); font-weight: 650; }
325
+ .ide-crumbs [aria-current] { color: var(--chrome-text); font-weight: 600; }
130
326
  .ide-tools { display: flex; align-items: center; flex: none; min-width: 0; }
131
327
  .tb-group { display: flex; align-items: center; gap: 2px; padding: 0 6px; }
132
328
  .tb-group + .tb-group { border-left: 1px solid var(--chrome-border); }
133
329
  .tb-form { display: inline-flex; align-items: center; margin: 0; }
134
330
  .tb-btn {
135
331
  display: inline-flex; align-items: center; justify-content: center; gap: 4px; min-width: 32px; height: 32px; padding: 0 6px;
136
- border: 1px solid transparent; border-radius: 4px; background: transparent; color: inherit; font: inherit; font-size: 12.5px;
332
+ border: 1px solid transparent; border-radius: var(--radius-sm); background: transparent; color: inherit; font: inherit; font-size: 12.5px;
333
+ transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
137
334
  cursor: pointer; text-decoration: none; white-space: nowrap;
138
335
  }
139
336
  .tb-btn:hover { background: color-mix(in srgb, currentColor 12%, transparent); }
@@ -148,66 +345,70 @@ body.ide { margin: 0; min-height: 100vh; min-height: 100dvh; padding-left: var(-
148
345
  .ide-bar .menu-panel { font-size: 13px; }
149
346
  .pd-goto select {
150
347
  height: 30px; width: auto; max-width: 13rem; padding: 0 0.4rem; font-size: 12.5px;
151
- background: var(--chrome-2); color: var(--chrome-text); border: 1px solid var(--chrome-border); border-radius: 4px;
348
+ background-color: var(--chrome-2); color: var(--chrome-text); border: 1px solid var(--chrome-3); border-radius: var(--radius-sm);
152
349
  }
153
350
  .js .pd-goto-go { display: none; }
154
351
  .ide .btn-sm { padding: 0.28rem 0.7rem; font-size: 12.5px; gap: 0.3rem; }
155
- .ide-bar .btn { border-radius: 4px; height: 32px; }
156
- .tb-save { background: var(--chrome-2); border-color: var(--chrome-3); color: var(--chrome-text); }
157
- .tb-save:hover { background: var(--chrome-3); }
352
+ .ide-bar .btn { border-radius: var(--radius-sm); height: 32px; }
353
+ .ide .tb-save { background: var(--chrome-2); border-color: var(--chrome-3); color: var(--chrome-text); box-shadow: none; }
354
+ .ide .tb-save:hover { background: var(--chrome-3); border-color: var(--chrome-3); }
158
355
  .tb-save.is-dirty { border-color: var(--hot); box-shadow: inset 0 0 0 1px var(--hot); }
159
- .ide .btn-run, .ide .btn-hot { background: var(--hot); border-color: var(--hot); color: var(--hot-text); }
160
- .ide .btn-run:hover, .ide .btn-hot:hover { background: var(--hot-hover); }
161
356
  .tb-main { gap: 6px; }
162
357
 
163
358
  /* ------------------------------------------------------------ messages */
164
- .ide-alerts { padding: 8px 12px 0; }
165
- .ide-alerts .alert { padding: 0.4rem 2rem 0.4rem 0.75rem; margin-bottom: 8px; font-size: 13px; border-radius: 4px; }
359
+ .ide-alerts { padding: 10px 18px 0; }
360
+ .ide-alerts .alert { padding: 0.5rem 2rem 0.5rem 0.85rem; margin-bottom: 8px; font-size: 13px; border-radius: var(--radius); }
166
361
  .ide-full .ide-alerts { padding: 6px 8px 0; background: var(--bg); }
167
362
  .ide-full .ide-alerts .alert { margin-bottom: 6px; }
168
363
 
169
364
  /* ------------------------------------------------------------ document pages (app home, shared components, SQL Workshop…) */
170
- .ide-page { max-width: 1680px; margin: 0 auto; padding: 14px 18px 48px; }
171
- .ide .region-standard, .ide .region-collapsible { border-radius: var(--radius); box-shadow: none; }
172
- .ide .region-header { min-height: 38px; padding: 0.35rem 0.85rem; background: var(--surface-2); border-radius: var(--radius) var(--radius) 0 0; }
173
- .ide .region-header h2 { font-size: 13px; font-weight: 650; min-width: 0; overflow-wrap: anywhere; }
174
- .ide .region-body { padding: 0.85rem; }
175
- .ide .btn { font-size: 13px; padding: 0.34rem 0.8rem; border-radius: 4px; }
176
- .ide input:not([type=checkbox]):not([type=radio]), .ide select, .ide textarea { padding: 0.32rem 0.5rem; border-radius: 3px; font-size: 13px; }
365
+ .ide .ide-page { max-width: 1680px; margin: 0 auto; padding: var(--page-py) var(--page-px) 48px; }
366
+ .ide .region-standard, .ide .region-collapsible { border-radius: var(--radius-lg); border-color: var(--border); box-shadow: var(--shadow-sm); }
367
+ .ide .region-header { min-height: 42px; padding: 0.45rem 1rem; background: transparent; border-bottom-color: var(--border); border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
368
+ .ide .region-header h2 { font-size: 13.5px; font-weight: 650; letter-spacing: -0.005em; min-width: 0; overflow-wrap: anywhere; }
369
+ .ide .region-body { padding: 1rem; }
370
+ .ide .region-footer { background: var(--surface-2); border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
371
+ .ide .btn { font-size: 13px; padding: 0.34rem 0.8rem; border-radius: var(--radius-sm); }
372
+ .ide input:not([type=checkbox]):not([type=radio]), .ide select, .ide textarea { padding: 0.36rem 0.6rem; border-radius: var(--radius-sm); font-size: 13px; }
177
373
  .ide textarea.code { font-size: 12.5px; background: var(--code-bg); }
178
374
  .ide .label { font-size: 12.5px; }
179
375
  .ide .form-grid { gap: 0.7rem 1rem; }
180
376
  .ide table.report { font-size: 13px; }
181
- .ide .report th, .ide .report td { padding: 0.32rem 0.6rem; }
182
- .ide .report th { font-size: 11.5px; }
183
- .ide .table-wrap { border-radius: var(--radius); }
184
- .ide .columns { gap: 0.85rem; margin-top: 0.85rem; }
185
- .ide .title-row { margin-bottom: 0.75rem; }
186
- .ide .tile, .ide .app-card, .ide .stat { border-radius: var(--radius); box-shadow: none; }
187
- .ide .tile { padding: 0.8rem; }
188
- .ide .tile .tile-icon { width: 40px; height: 40px; border-radius: 8px; }
377
+ .ide .report th, .ide .report td { padding: 0.42rem 0.7rem; }
378
+ .ide .report th { padding-top: 0.5rem; padding-bottom: 0.5rem; }
379
+ .ide .columns { gap: 1rem; margin-top: 1rem; }
380
+ .ide .title-row { margin-bottom: 1rem; }
381
+ .ide .tile, .ide .app-card, .ide .stat { border-radius: var(--radius-lg); border-color: var(--border); box-shadow: var(--shadow-xs); transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease); }
382
+ .ide :is(a.tile, a.stat, .app-card):hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); transform: translateY(-1px); }
383
+ .ide .tile { padding: 0.9rem; }
384
+ .ide .tile .tile-icon { width: 40px; height: 40px; border-radius: 10px; background: var(--accent-soft); color: var(--accent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 18%, transparent); }
189
385
  .ide .tiles { gap: 0.75rem; margin-bottom: 1rem; }
190
386
  .ide .app-cards { gap: 0.75rem; }
191
387
  .ide .app-card { padding: 0.8rem; gap: 0.5rem; }
192
388
  .ide .app-card .app-icon { width: 38px; height: 38px; border-radius: 6px; }
193
389
  .ide fieldset.prop-group > legend { font-size: 11.5px; }
194
- .ide .alert { border-radius: var(--radius); }
195
390
 
196
391
  /* application header with its tabs */
197
- .ide-head { margin: -14px -18px 14px; padding: 12px 18px 0; background: var(--surface); border-bottom: 1px solid var(--border); }
198
- .ide-head-title { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; }
392
+ .ide-head { margin: calc(-1 * var(--page-py)) calc(-1 * var(--page-px)) var(--page-py); padding: 16px var(--page-px) 0; background: var(--surface); border-bottom: 1px solid var(--border); background-image: linear-gradient(180deg, var(--surface-2), var(--surface) 70%); }
393
+ .ide-head-title { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; min-width: 0; }
199
394
  .ide-head-title > div:not(.buttons) { min-width: 0; }
200
395
  .ide-head-title h1 { overflow-wrap: anywhere; }
201
- .ide-app-icon { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 6px; background: var(--hot); color: #fff; font-weight: 750; font-size: 16px; flex: none; }
396
+ .ide-app-icon {
397
+ display: grid; place-items: center; width: 40px; height: 40px; border-radius: 10px; flex: none;
398
+ background: linear-gradient(150deg, var(--ember-2), var(--ember-3)); color: #fff; font-weight: 750; font-size: 17px;
399
+ box-shadow: inset 0 1px 0 rgb(255 255 255 / 25%), var(--shadow-sm);
400
+ }
202
401
  .ide-head-actions { margin-left: auto; }
203
- .ide-tabs { display: flex; gap: 2px; margin-top: 8px; overflow-x: auto; scrollbar-width: thin; }
402
+ .ide-tabs { display: flex; gap: 4px; margin-top: 12px; overflow-x: auto; scrollbar-width: thin; }
204
403
  .ide-page > .ide-tabs { margin-top: 0; border-bottom: 1px solid var(--border); }
205
404
  .ide-tab {
206
- display: inline-flex; align-items: center; gap: 6px; padding: 7px 11px 8px; color: var(--muted); text-decoration: none;
207
- border-bottom: 2px solid transparent; white-space: nowrap; font-weight: 550;
405
+ position: relative; display: inline-flex; align-items: center; gap: 6px; padding: 8px 11px 9px; color: var(--muted); text-decoration: none;
406
+ border-bottom: 2px solid transparent; border-radius: var(--radius-sm) var(--radius-sm) 0 0; white-space: nowrap; font-weight: 550;
407
+ transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
208
408
  }
209
- .ide-tab:hover { color: var(--text); background: var(--surface-2); }
409
+ .ide-tab:hover { color: var(--text); background: var(--surface-3); }
210
410
  .ide-tab[aria-current] { color: var(--text); border-bottom-color: var(--hot); }
411
+ .ide-tab[aria-current] .icon { color: var(--accent); }
211
412
  .ide-tab .icon { width: 15px; height: 15px; }
212
413
 
213
414
  /* ------------------------------------------------------------ generic tabs (builder.js turns [data-tabs] into tabs) */
@@ -215,8 +416,10 @@ body.ide { margin: 0; min-height: 100vh; min-height: 100dvh; padding-left: var(-
215
416
  .tablist [role=tab] {
216
417
  display: inline-flex; align-items: center; gap: 6px; padding: 8px 10px 7px; border: 0; border-bottom: 2px solid transparent;
217
418
  background: none; color: var(--muted); font: inherit; font-weight: 600; cursor: pointer; white-space: nowrap;
419
+ transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
218
420
  }
219
421
  .tablist [role=tab]:hover { color: var(--text); }
422
+ .tablist [role=tab][aria-selected="true"] .icon { color: var(--accent); }
220
423
  .tablist [role=tab][aria-selected="true"] { color: var(--text); border-bottom-color: var(--hot); }
221
424
  .tablist [role=tab]:focus-visible { outline-offset: -2px; }
222
425
  .tabs-on > .tab-panel > .tab-title { display: none; }
@@ -273,7 +476,7 @@ body.ide { margin: 0; min-height: 100vh; min-height: 100dvh; padding-left: var(-
273
476
  .pd-tree ul { padding-left: 14px; }
274
477
  .pd-node {
275
478
  position: relative; display: flex; align-items: center; gap: 6px; min-height: 26px; padding: 2px 6px 2px 20px;
276
- border-radius: 3px; color: var(--text); text-decoration: none; white-space: nowrap;
479
+ border-radius: var(--radius-sm); color: var(--text); text-decoration: none; white-space: nowrap;
277
480
  }
278
481
  .pd-node .icon { width: 16px; height: 16px; color: var(--muted); }
279
482
  a.pd-node:hover { background: var(--surface-3); }
@@ -282,8 +485,7 @@ a.pd-node:hover { background: var(--surface-3); }
282
485
  .pd-folder { color: var(--muted); font-weight: 600; cursor: default; }
283
486
  .pd-tag { display: inline-flex; }
284
487
  .pd-tag .icon { width: 13px; height: 13px; color: var(--warn); }
285
- .pd-node[aria-current], .pd-node[aria-selected="true"] { background: var(--sel-bg); color: var(--sel-text); }
286
- .pd-node[aria-current] :is(.icon, .pd-note), .pd-node[aria-selected="true"] :is(.icon, .pd-note) { color: var(--sel-text); }
488
+ .pd-node[aria-current], .pd-node[aria-selected="true"] { background: var(--sel-bg); color: var(--sel-text); box-shadow: inset 2px 0 0 var(--sel-bar); font-weight: 600; }
287
489
  .pd-empty { padding: 2px 6px 2px 20px; color: var(--muted); font-style: italic; font-size: 12px; }
288
490
  /* twisties (builder.js marks nodes with children) */
289
491
  .pd-node.has-kids::before {
@@ -298,19 +500,22 @@ a.pd-node:hover { background: var(--surface-3); }
298
500
  /* ------------------------------------------------------------ layout canvas */
299
501
  .pd-canvas-bar { display: flex; align-items: center; gap: 2px; min-height: 36px; padding: 2px 8px; background: var(--surface); border-bottom: 1px solid var(--border); color: var(--text); flex: none; }
300
502
  .pd-canvas-hint { margin-left: auto; color: var(--muted); font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
301
- .pd-canvas { --zoom: 1; padding: 12px; font-size: calc(13px * var(--zoom)); background: var(--canvas); }
503
+ .pd-canvas {
504
+ --zoom: 1; padding: 14px; font-size: calc(13px * var(--zoom)); background-color: var(--canvas);
505
+ background-image: radial-gradient(var(--canvas-dot) 1px, transparent 1.2px); background-size: 16px 16px;
506
+ }
302
507
  .pd-page-label { display: flex; align-items: center; gap: 6px; margin: 0 0 8px; color: var(--muted); font-size: 0.92em; font-weight: 600; }
303
508
  .pd-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 8px; align-items: start; }
304
509
  .pd-span-1 { grid-column: span 1; } .pd-span-2 { grid-column: span 2; } .pd-span-3 { grid-column: span 3; }
305
510
  .pd-span-4 { grid-column: span 4; } .pd-span-5 { grid-column: span 5; } .pd-span-6 { grid-column: span 6; }
306
511
  .pd-span-7 { grid-column: span 7; } .pd-span-8 { grid-column: span 8; } .pd-span-9 { grid-column: span 9; }
307
512
  .pd-span-10 { grid-column: span 10; } .pd-span-11 { grid-column: span 11; } .pd-span-12 { grid-column: span 12; }
308
- .pd-region { position: relative; min-width: 0; background: var(--block); border: 1px solid var(--border); border-radius: 4px; }
309
- .pd-region:hover { border-color: color-mix(in srgb, var(--hot) 55%, var(--border)); }
310
- .pd-region.is-selected { border-color: var(--hot); box-shadow: 0 0 0 1px var(--hot); }
513
+ .pd-region { position: relative; min-width: 0; background: var(--block); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-xs); transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
514
+ .pd-region:hover { border-color: color-mix(in srgb, var(--hot) 55%, var(--border)); box-shadow: var(--shadow-sm); }
515
+ .pd-region.is-selected { border-color: var(--hot); box-shadow: 0 0 0 1px var(--hot), 0 0 0 4px var(--ring); }
311
516
  .pd-region-head {
312
517
  display: flex; align-items: center; gap: 4px; min-height: 2.3em; padding: 0.2em 0.45em 0.2em 0.2em;
313
- background: var(--block-head); border-bottom: 1px solid var(--border); border-radius: 3px 3px 0 0;
518
+ background: var(--block-head); border-bottom: 1px solid var(--border); border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0;
314
519
  }
315
520
  .js .pd-region-head { cursor: grab; }
316
521
  .pd-region.is-selected > .pd-region-head { background: var(--sel-bg); color: var(--sel-text); }
@@ -325,12 +530,13 @@ a.pd-node:hover { background: var(--surface-3); }
325
530
  .pd-region-body { display: flex; flex-direction: column; gap: 0.45em; padding: 0.45em; }
326
531
  .pd-region-type { color: var(--muted); font-size: 0.76em; font-weight: 650; text-transform: uppercase; letter-spacing: 0.05em; }
327
532
  .pd-region-src { display: block; padding: 0; background: none; color: var(--muted); font-size: 0.8em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
328
- .pd-slot { display: flex; flex-direction: column; gap: 0.3em; min-height: 2em; padding: 0.3em; border: 1px dashed var(--border); border-radius: 3px; }
533
+ .pd-slot { display: flex; flex-direction: column; gap: 0.3em; min-height: 2em; padding: 0.3em; border: 1px dashed var(--border-strong); border-radius: var(--radius-sm); }
329
534
  .pd-slot-button { flex-direction: row; flex-wrap: wrap; }
330
535
  .pd-slot-hint { align-self: center; padding: 0.15em 0.3em; color: var(--muted); font-size: 0.74em; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; }
331
536
  .pd-chip {
332
537
  display: flex; align-items: center; gap: 0.4em; min-width: 0; padding: 0.25em 0.45em;
333
- background: var(--surface-2); color: var(--text); border: 1px solid var(--border); border-radius: 3px; text-decoration: none; font-size: 0.92em;
538
+ background: var(--surface-2); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius-sm); text-decoration: none; font-size: 0.92em;
539
+ transition: border-color var(--dur) var(--ease);
334
540
  }
335
541
  .js .pd-chip { cursor: grab; }
336
542
  .pd-chip:hover { border-color: var(--hot); }
@@ -344,7 +550,8 @@ a.pd-node:hover { background: var(--surface-3); }
344
550
  .js .pd-resize { display: block; }
345
551
  .pd-resize::after { content: ""; position: absolute; top: 25%; bottom: 25%; left: 3px; width: 3px; border-radius: 2px; background: var(--hot); opacity: 0; transition: opacity 0.12s; }
346
552
  .pd-region:hover > .pd-resize::after, .pd-region.is-resizing > .pd-resize::after { opacity: 0.8; }
347
- .pd-grid-end { grid-column: 1 / -1; padding: 0.55em; text-align: center; border: 1px dashed var(--border); border-radius: 4px; }
553
+ .pd-grid-end { grid-column: 1 / -1; padding: 0.55em; text-align: center; border: 1px dashed var(--border-strong); border-radius: var(--radius); background: color-mix(in srgb, var(--surface) 55%, transparent); transition: border-color var(--dur) var(--ease); }
554
+ .pd-grid-end:hover { border-color: var(--accent); }
348
555
  .pd-grid-end a { display: inline-flex; align-items: center; gap: 0.35em; color: var(--muted); text-decoration: none; font-size: 0.9em; }
349
556
  .pd-grid-end a:hover { color: var(--accent); }
350
557
  .pd-pagelevel { display: grid; gap: 0.4em; margin-top: 12px; padding: 0.5em; border: 1px dashed var(--border); border-radius: 4px; }
@@ -364,9 +571,10 @@ a.pd-node:hover { background: var(--surface-3); }
364
571
  .pd-gallery { background: var(--surface); border-top: 1px solid var(--border); }
365
572
  .pd-gallery .tablist { position: sticky; top: 0; z-index: 1; }
366
573
  .pd-gallery-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 2px 8px; margin: 0; padding: 8px; list-style: none; }
367
- .pd-gal { display: flex; align-items: center; gap: 8px; min-height: 32px; padding: 4px 8px; border-radius: 4px; color: var(--text); text-decoration: none; }
574
+ .pd-gal { display: flex; align-items: center; gap: 8px; min-height: 32px; padding: 4px 8px; border-radius: var(--radius-sm); color: var(--text); text-decoration: none; transition: background-color var(--dur) var(--ease); }
368
575
  .js .pd-gal { cursor: grab; }
369
576
  .pd-gal:hover { background: var(--surface-3); }
577
+ .pd-gal:hover .icon { color: var(--accent); }
370
578
  .pd-gal .icon { width: 22px; height: 22px; color: var(--muted); stroke-width: 1.5; }
371
579
  .pd-gal span { min-width: 0; overflow-wrap: anywhere; line-height: 1.2; }
372
580
 
@@ -384,10 +592,10 @@ kbd { display: inline-block; padding: 0 0.35em; border: 1px solid var(--border);
384
592
  .pe-title { display: flex; align-items: center; gap: 6px; min-width: 0; font-weight: 650; }
385
593
  .pe-title span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
386
594
  .pe-title .icon { color: var(--muted); }
387
- .pe-filter-row { display: flex; align-items: center; gap: 6px; padding: 0 8px; border: 1px solid var(--border); border-radius: 4px; background: var(--surface-2); }
388
- .pe-filter-row:focus-within { outline: 2px solid var(--accent); outline-offset: 0; }
595
+ .pe-filter-row { display: flex; align-items: center; gap: 6px; padding: 0 8px; border: 1px solid var(--field-border, var(--border)); border-radius: var(--radius-sm); background: var(--surface-2); }
596
+ .pe-filter-row:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--ring); }
389
597
  .pe-filter-row .icon { color: var(--muted); }
390
- .ide .pe-filter-row input.pe-filter { border: 0; background: transparent; padding: 5px 0; outline: none; }
598
+ .ide .pe-filter-row input.pe-filter { border: 0; background: transparent; padding: 5px 0; outline: none; box-shadow: none; }
391
599
  .pe-arrange { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; padding: 4px 8px; border-bottom: 1px solid var(--border); background: var(--surface-2); }
392
600
  .pe-arrange-label { margin-right: 4px; color: var(--muted); font-size: 11.5px; font-weight: 650; letter-spacing: 0.05em; text-transform: uppercase; }
393
601
  .pe-arrange-form { display: inline-flex; align-items: center; gap: 4px; margin: 0; }
@@ -436,32 +644,37 @@ kbd { display: inline-block; padding: 0 0.35em; border: 1px solid var(--border);
436
644
  .pe-empty-filter { margin: 10px; color: var(--muted); }
437
645
 
438
646
  /* ------------------------------------------------------------ sign-in */
439
- .ide-login { background: linear-gradient(180deg, var(--chrome) 0 40%, var(--bg) 40%); color: var(--text); }
440
- .ide-login .btn-hot { background: var(--hot); border-color: var(--hot); color: var(--hot-text); }
441
- .ide-login .btn-hot:hover { background: var(--hot-hover); }
647
+ .ide-login { background: linear-gradient(180deg, var(--chrome) 0 40%, var(--bg) 40%); color: var(--text); font-family: var(--font); -webkit-font-smoothing: antialiased; }
442
648
  .signin-body.ide-login { display: block; background: var(--bg); }
443
649
  .signin { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); width: 100%; max-width: none; min-height: 100vh; min-height: 100dvh; margin: 0; padding: 0; }
444
650
  .signin-hero {
445
651
  display: flex; flex-direction: column; justify-content: flex-start; gap: 0.75rem; padding: 3rem;
446
652
  color: var(--chrome-text); background-color: var(--chrome);
447
- background-image: repeating-linear-gradient(135deg, rgb(255 255 255 / 0.025) 0 2px, transparent 2px 14px),
448
- repeating-linear-gradient(45deg, rgb(255 255 255 / 0.02) 0 1px, transparent 1px 22px);
653
+ /* the kiln's glow rising from the bottom, over a faint grid */
654
+ background-image: radial-gradient(70% 55% at 30% 105%, rgb(234 88 12 / 38%), rgb(194 65 12 / 10%) 55%, transparent 80%),
655
+ linear-gradient(rgb(255 255 255 / 0.03) 1px, transparent 1px), linear-gradient(90deg, rgb(255 255 255 / 0.03) 1px, transparent 1px);
656
+ background-size: auto, 32px 32px, 32px 32px;
657
+ }
658
+ .signin-logo {
659
+ display: grid; place-items: center; width: 48px; height: 48px; border-radius: 13px; margin-bottom: 2rem; color: #fff;
660
+ background: linear-gradient(150deg, var(--ember-1), var(--ember-2) 55%, var(--ember-3));
661
+ box-shadow: inset 0 1px 0 rgb(255 255 255 / 30%), 0 8px 26px -4px rgb(234 88 12 / 60%);
449
662
  }
450
- .signin-logo { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 8px; background: var(--hot); color: var(--hot-text); font-weight: 700; font-size: 18px; margin-bottom: 2rem; }
451
- .signin-title { margin: 0; font-size: clamp(2rem, 4vw, 2.75rem); font-weight: 750; color: var(--chrome-text); }
663
+ .signin-logo .icon { width: 28px; height: 28px; }
664
+ .signin-title { margin: 0; font-size: clamp(2rem, 4vw, 2.75rem); font-weight: 750; letter-spacing: -0.03em; color: var(--chrome-text); }
452
665
  .signin-tagline { margin: 0; font-size: 1.2rem; color: var(--chrome-muted); max-width: 30ch; }
453
666
  .signin-foot { margin: auto 0 0; font-size: 0.85rem; color: var(--chrome-muted); }
454
667
  .signin-panel { display: grid; place-items: center; padding: 2rem 1rem; background: var(--surface); }
455
668
  .signin-form { display: flex; flex-direction: column; gap: 0.85rem; width: 100%; max-width: 420px; }
456
- .signin-form h2 { margin: 0; font-size: 1.5rem; }
669
+ .signin-form h2 { margin: 0; font-size: 1.5rem; letter-spacing: -0.02em; }
457
670
  .signin-form .field { margin: 0; }
458
- .signin-input { display: flex; align-items: center; gap: 0.6rem; padding: 0 0.75rem; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); }
459
- .signin-input:focus-within { border-color: var(--accent); outline: 2px solid var(--accent); outline-offset: -1px; }
671
+ .signin-input { display: flex; align-items: center; gap: 0.6rem; padding: 0 0.75rem; border: 1px solid var(--border-strong); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-xs); transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
672
+ .signin-input:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--ring); }
460
673
  .signin-input > .icon { flex: none; width: 18px; height: 18px; color: var(--muted); }
461
674
  .ide-login .signin-input input { flex: 1; width: auto; min-width: 0; border: 0; border-radius: 0; box-shadow: none; background: transparent; padding: 0.7rem 0; font-size: 1rem; color: var(--text); outline: none; }
462
675
  .signin-reveal { flex: none; border: 0; background: none; color: var(--accent); cursor: pointer; font-size: 0.85rem; padding: 0.25rem; }
463
676
  .signin-remember { font-size: 0.9rem; }
464
- .signin-submit { padding: 0.75rem; font-size: 1rem; }
677
+ .signin-submit { padding: 0.75rem; font-size: 1rem; border-radius: var(--radius); }
465
678
  .signin-hint { margin: 0; text-align: center; }
466
679
  .signin-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.5rem 1.5rem; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--border); }
467
680
  .signin-actions a { display: inline-flex; align-items: center; gap: 0.4rem; color: var(--gold); text-decoration: none; }
@@ -481,35 +694,42 @@ kbd { display: inline-block; padding: 0 0.35em; border: 1px solid var(--border);
481
694
  .ide-main > .ide-page { flex: 1 0 auto; width: 100%; }
482
695
  .ide-status {
483
696
  position: sticky; bottom: 0; z-index: 20; display: flex; align-items: center; gap: 18px; flex: none;
484
- min-height: 30px; padding: 0 14px; background: var(--chrome); color: var(--chrome-muted); border-top: 1px solid var(--chrome-border);
485
- font-size: 12px; white-space: nowrap; overflow: hidden;
697
+ min-height: 28px; padding: 0 14px; background: var(--chrome); color: var(--chrome-muted); border-top: 1px solid var(--chrome-border);
698
+ font-size: 11.5px; white-space: nowrap; overflow: hidden;
486
699
  }
487
700
  .ide-status > span { display: inline-flex; align-items: center; gap: 6px; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
488
701
  .ide-status .icon { width: 14px; height: 14px; flex: none; }
489
- .ide-status-version { margin-left: auto; }
702
+ .ide-status-version { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; }
703
+ .ide-status-version::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--ember-1); box-shadow: 0 0 6px var(--ember-2); }
490
704
 
491
705
  /* ------------------------------------------------------------ App Builder home (tiles, applications, side column) */
492
706
  .ab-home { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; }
493
707
  .ab-main { min-width: 0; }
494
- .ab-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-bottom: 16px; }
708
+ .ab-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin-bottom: 20px; }
495
709
  .ab-tiles-wrap { grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); }
496
710
  .ab-tile {
497
- display: grid; grid-template-columns: auto; align-content: start; gap: 4px; min-height: 132px; padding: 14px 14px 16px;
498
- background: var(--surface-2); border: 1px solid var(--border); border-radius: 6px; color: var(--text); text-decoration: none;
711
+ position: relative; display: grid; grid-template-columns: auto; align-content: start; gap: 4px; min-height: 132px; padding: 16px 16px 18px;
712
+ background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); color: var(--text); text-decoration: none;
713
+ box-shadow: var(--shadow-sm); transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
499
714
  }
500
- .ab-tile:hover { background: var(--surface-3); border-color: var(--accent); }
501
- .ab-tile-icon { display: grid; place-items: center; width: 40px; height: 40px; margin-bottom: 10px; border-radius: 4px; background: var(--hot); color: #fff; }
502
- .ab-tile-icon .icon { width: 22px; height: 22px; }
503
- .ab-tile strong { font-size: 15px; font-weight: 650; }
715
+ .ab-tile:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); box-shadow: var(--shadow-md); transform: translateY(-2px); }
716
+ .ab-tile-icon {
717
+ display: grid; place-items: center; width: 40px; height: 40px; margin-bottom: 12px; border-radius: 10px;
718
+ background: var(--accent-soft); color: var(--accent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 18%, transparent);
719
+ transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
720
+ }
721
+ .ab-tile:hover .ab-tile-icon { background: var(--hot); color: var(--hot-text); }
722
+ .ab-tile-icon .icon { width: 20px; height: 20px; }
723
+ .ab-tile strong { font-size: 14.5px; font-weight: 650; letter-spacing: -0.01em; }
504
724
  .ab-tile > span:last-child { color: var(--muted); font-size: 13px; }
505
725
 
506
726
  .ab-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 0 0 10px; }
507
727
  .ab-search { position: relative; flex: 0 1 260px; min-width: 160px; }
508
728
  .ab-search .icon { position: absolute; left: 9px; top: 50%; translate: 0 -50%; color: var(--muted); pointer-events: none; }
509
- .ab-search input[type=search] { width: 100%; height: 34px; padding-left: 32px !important; background: var(--surface); border: 1px solid var(--border); }
510
- .ab-views { display: inline-flex; border: 1px solid var(--border); border-radius: 4px; overflow: hidden; }
511
- .ab-views .tb-btn { height: 32px; width: 40px; border-radius: 0; color: var(--muted); }
512
- .ab-views .tb-btn[aria-current] { background: var(--surface-3); color: var(--text); }
729
+ .ab-search input[type=search] { width: 100%; height: 34px; padding-left: 32px !important; background: var(--surface); }
730
+ .ab-views { display: inline-flex; gap: 2px; padding: 2px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface-2); }
731
+ .ab-views .tb-btn { height: 28px; width: 36px; min-width: 0; border-radius: 4px; color: var(--muted); }
732
+ .ab-views .tb-btn[aria-current] { background: var(--surface); color: var(--text); box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--border-strong); }
513
733
  .ab-menu > summary { display: inline-flex; align-items: center; gap: 4px; height: 34px; list-style: none; }
514
734
  .ab-menu > summary::-webkit-details-marker { display: none; }
515
735
  .ab-menu > summary .icon { width: 14px; height: 14px; rotate: 90deg; }
@@ -518,24 +738,27 @@ kbd { display: inline-block; padding: 0 0.35em; border: 1px solid var(--border);
518
738
  .ab-create { height: 34px; display: inline-flex; align-items: center; }
519
739
 
520
740
  .ide .ab-table { background: var(--surface); position: relative; } /* keeps the .sr-only labels inside its scroll area */
521
- .ide table.ab-apps th { color: var(--gold); font-size: 12.5px; text-transform: none; letter-spacing: 0; font-weight: 700; padding: 10px 12px; background: var(--surface); }
741
+ .ide table.ab-apps th { padding: 10px 12px; }
522
742
  .ide table.ab-apps th a { color: inherit; }
523
743
  .ide table.ab-apps td { padding: 9px 12px; height: 56px; }
524
744
  .ide table.ab-apps tbody tr:hover { background: var(--surface-2); }
525
745
  .ab-sorted { margin-left: 4px; }
526
746
  .ide table.ab-apps th.num { text-align: right; }
527
- .ab-name a { display: inline-flex; align-items: center; gap: 12px; color: var(--gold); font-weight: 650; text-decoration: none; }
747
+ .ab-name a { display: inline-flex; align-items: center; gap: 12px; color: var(--text); font-weight: 650; text-decoration: none; }
748
+ .ab-name a:hover { color: var(--accent); }
528
749
  .ab-name a:hover span { text-decoration: underline; }
529
- .ab-name .app-icon, .ab-card .app-icon { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 4px; color: #fff; font-weight: 750; flex: none; }
750
+ .ab-name .app-icon, .ab-card .app-icon { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 8px; color: #fff; font-weight: 750; flex: none; box-shadow: inset 0 1px 0 rgb(255 255 255 / 22%), var(--shadow-xs); }
530
751
  .ab-actions-col { text-align: right; }
531
752
  .ab-actions { text-align: right; white-space: nowrap; }
532
753
  .ab-actions .tb-btn, .ab-card-actions .tb-btn { color: var(--text); }
533
754
  .ab-actions .tb-btn:hover, .ab-card-actions .tb-btn:hover { background: var(--surface-3); }
534
- .ab-empty { padding: 28px; text-align: center; color: var(--muted); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
755
+ .ab-empty { padding: 40px 28px; text-align: center; color: var(--muted); background: var(--surface); border: 1px dashed var(--border-strong); border-radius: var(--radius-lg); }
535
756
 
536
757
  .ab-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr)); gap: 12px; }
537
- .ab-card { display: flex; flex-direction: column; gap: 10px; padding: 12px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 6px; }
538
- .ab-card-main { display: flex; align-items: center; gap: 12px; color: var(--gold); text-decoration: none; min-width: 0; }
758
+ .ab-card { display: flex; flex-direction: column; gap: 10px; padding: 14px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
759
+ .ab-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); }
760
+ .ab-card-main { display: flex; align-items: center; gap: 12px; color: var(--text); text-decoration: none; min-width: 0; }
761
+ .ab-card-main:hover strong { color: var(--accent); }
539
762
  .ab-card-main > span:last-child { display: grid; min-width: 0; }
540
763
  .ab-card-main strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
541
764
  .ab-card-main small { color: var(--muted); }
@@ -544,12 +767,14 @@ kbd { display: inline-block; padding: 0 0.35em; border: 1px solid var(--border);
544
767
 
545
768
  .ab-side { padding: 4px 2px 0; }
546
769
  .ab-side section { padding: 12px 0; border-top: 1px solid var(--border); }
547
- .ab-side h2 { margin: 0 0 8px; font-size: 13.5px; font-weight: 700; }
770
+ .ab-side h2 { margin: 0 0 8px; font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
548
771
  .ab-side p { margin: 0 0 6px; color: var(--muted); }
549
- .ab-side a { color: var(--gold); text-decoration: none; }
772
+ .ab-side a { color: var(--accent); text-decoration: none; }
550
773
  .ab-side a:hover { text-decoration: underline; }
551
- .ab-links { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
552
- .ab-tasks a { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
774
+ .ab-links { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
775
+ .ab-tasks a { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 -8px; padding: 5px 8px; border-radius: var(--radius-sm); color: var(--text); transition: background-color var(--dur) var(--ease); }
776
+ .ab-side .ab-tasks a:hover { background: var(--surface-3); text-decoration: none; }
777
+ .ab-tasks a:hover .icon { color: var(--accent); }
553
778
  .ab-tasks .icon { width: 14px; height: 14px; color: var(--muted); }
554
779
  .ab-narrow { max-width: 900px; }
555
780
  .ab-narrow > h1 { margin-top: 4px; }
@@ -557,9 +782,9 @@ kbd { display: inline-block; padding: 0 0.35em; border: 1px solid var(--border);
557
782
 
558
783
  @media (min-width: 1280px) {
559
784
  /* the side column runs along the right edge, as in APEX */
560
- .ab-home { grid-template-columns: minmax(0, 1fr) 280px; margin: -14px -18px -48px 0; min-height: calc(100vh - var(--bar-h) - 30px); }
561
- .ab-main { padding: 0 18px 48px 0; padding-top: 14px; }
562
- .ab-side { padding: 14px 16px 24px; background: var(--surface); border-left: 1px solid var(--border); }
785
+ .ab-home { grid-template-columns: minmax(0, 1fr) 288px; margin: calc(-1 * var(--page-py)) calc(-1 * var(--page-px)) -48px 0; min-height: calc(100vh - var(--bar-h) - 28px); }
786
+ .ab-main { padding: var(--page-py) var(--page-px) 48px 0; }
787
+ .ab-side { padding: 18px 20px 24px; background: var(--surface); border-left: 1px solid var(--border); }
563
788
  .ab-side section:first-child { border-top: 0; padding-top: 0; }
564
789
  }
565
790
  @media (max-width: 1023px) {
@@ -590,12 +815,16 @@ kbd { display: inline-block; padding: 0 0.35em; border: 1px solid var(--border);
590
815
 
591
816
  @media (max-width: 640px) {
592
817
  .ide { --rail-w: 44px; --bar-h: 46px; }
593
- .ide-page { padding: 10px 10px 40px; }
594
- .ide-head { margin: -10px -10px 10px; padding: 10px 10px 0; }
818
+ .ide { --page-px: 12px; --page-py: 12px; }
819
+ .ide .ide-page { padding-bottom: 40px; }
820
+ .ide-head { padding-top: 12px; }
595
821
  .ide-head-actions { margin-left: 0; width: 100%; }
596
- .rail-link { height: 40px; }
597
- .rail-link .icon { width: 20px; height: 20px; }
598
- .rail-logo { width: 30px; height: 30px; font-size: 13px; }
822
+ .rail-list { padding: 0 5px; }
823
+ .rail-link { height: 38px; }
824
+ .rail-link[aria-current]::before { left: -5px; }
825
+ .rail-link .icon { width: 19px; height: 19px; }
826
+ .rail-logo { width: 32px; height: 32px; border-radius: 9px; }
827
+ .rail-logo .icon { width: 19px; height: 19px; }
599
828
  .ide-bar { gap: 2px; padding: 0 4px; }
600
829
  .ide-crumbs li:not(:last-child) { display: none; }
601
830
  .ide-crumbs li:last-child::before { content: none; }
@@ -665,7 +894,7 @@ pre.ddl { max-height: 36rem; overflow: auto; }
665
894
  .qb-col .check { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
666
895
  .qb-col .qb-type { display: none; }
667
896
  .qb-col select { max-width: 6.5rem; font-size: 0.8rem; padding: 1px 2px; }
668
- .qb-col.qb-target { background: var(--accent); color: var(--sel-text, #fff); }
897
+ .qb-col.qb-target { background: var(--accent); color: var(--accent-text); }
669
898
  .qb-link { width: 22px; height: 22px; padding: 0; border: 0; background: none; cursor: crosshair; touch-action: none; }
670
899
  .qb-link::before { content: ''; display: block; width: 10px; height: 10px; margin: auto; border-radius: 50%; border: 2px solid var(--accent); }
671
900
  .qb-lines { position: absolute; left: 0; top: 0; pointer-events: none; overflow: visible; }
@@ -768,7 +997,7 @@ button.is-busy { opacity: 0.7; cursor: progress; }
768
997
  .tr-preview { --bg: #f3f4f6; --surface: #ffffff; --surface-2: #f6f7f9; --surface-3: #eceef2; --text: #1b2330; --muted: #5e6a7a; --border: #dfe3e8;
769
998
  --accent: #0b63c5; --accent-text: #ffffff; --accent-soft: #e7f0fb; --header: #13294b; --header-text: #eef2f8; --radius: 8px;
770
999
  --font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; --font-size: 15px; --shadow: 0 1px 2px rgb(16 24 40 / 6%), 0 1px 3px rgb(16 24 40 / 6%);
771
- color-scheme: light; margin-bottom: 1rem; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden;
1000
+ --field-border: var(--border); color-scheme: light; margin-bottom: 1rem; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden;
772
1001
  background: var(--bg); color: var(--text); font: var(--font-size)/1.5 var(--font); }
773
1002
  .tr-preview-iris { --bg: #ffffff; --surface-2: #f7f6f5; --surface-3: #efedeb; --text: #1f1c1a; --muted: #645e59; --border: #e2dfdc;
774
1003
  --accent: #2b62c4; --accent-soft: #e9f0fb; --header: #3a3632; --header-text: #f7f5f3; --radius: 4px; --shadow: none;
@@ -837,7 +1066,7 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
837
1066
  .ab-message { display: flex; gap: 0.6rem; align-items: flex-start; margin-bottom: 12px; }
838
1067
  .ab-message p { margin: 0.15rem 0 0; white-space: pre-line; }
839
1068
  .rail-admin { padding: 0; }
840
- .rail-admin > summary { list-style: none; cursor: pointer; }
1069
+ .rail-admin > summary { list-style: none; cursor: pointer; width: 100%; }
841
1070
  .rail-admin > summary::-webkit-details-marker { display: none; }
842
1071
  .rail-admin .menu-panel { bottom: 56px; }
843
1072
  .rail-admin .menu-links strong { padding: 2px 0 4px; }
@@ -845,14 +1074,13 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
845
1074
 
846
1075
  /* ------------------------------------------------------------ SQL Workshop home (sprint 61) */
847
1076
  .sw-tiles { grid-template-columns: repeat(5, minmax(0, 1fr)); }
848
- .sw-tile-icon { background: #2f7d32; }
849
- .sw-recents { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
1077
+ .sw-recents { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); box-shadow: var(--shadow-sm); overflow: hidden; }
850
1078
  .sw-recent { min-width: 0; border-left: 1px solid var(--border); }
851
1079
  .sw-recent:first-child { border-left: 0; }
852
1080
  .sw-recent h2 { margin: 0; padding: 10px 12px; font-size: 13.5px; border-bottom: 1px solid var(--border); }
853
1081
  .sw-recent ul { list-style: none; margin: 0; padding: 0; max-height: 440px; overflow-y: auto; }
854
1082
  .sw-recent li { display: flex; justify-content: space-between; gap: 12px; padding: 7px 12px; border-bottom: 1px solid var(--border); }
855
- .sw-recent li a { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--gold); text-decoration: none; }
1083
+ .sw-recent li a { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--accent); text-decoration: none; }
856
1084
  .sw-recent li a:hover { text-decoration: underline; }
857
1085
  .sw-recent li .muted { flex: none; font-size: 12px; }
858
1086
  .sw-recent > p { padding: 0 12px; }
@@ -870,10 +1098,11 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
870
1098
  .gal-tabs a:last-child { border-radius: 0 var(--radius) var(--radius) 0; }
871
1099
  .gal-tabs a[aria-current] { background: var(--surface-3); font-weight: 650; }
872
1100
  .gal-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); gap: 12px; }
873
- .gal-card { display: flex; flex-direction: column; gap: 10px; padding: 16px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface); min-width: 0; }
1101
+ .gal-card { display: flex; flex-direction: column; gap: 10px; padding: 16px; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); box-shadow: var(--shadow-sm); min-width: 0; transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
1102
+ .gal-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); }
874
1103
  .gal-head { display: flex; gap: 12px; align-items: center; }
875
1104
  .gal-head h2 { margin: 0; font-size: 15px; }
876
- .gal-icon { flex: none; display: grid; place-items: center; width: 48px; height: 48px; border-radius: 8px; background: var(--accent-soft); color: var(--accent); }
1105
+ .gal-icon { flex: none; display: grid; place-items: center; width: 48px; height: 48px; border-radius: var(--radius-lg); background: var(--accent-soft); color: var(--accent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 18%, transparent); }
877
1106
  .gal-icon .icon { width: 26px; height: 26px; }
878
1107
  .gal-card > p { margin: 0; flex: 1; line-height: 1.5; }
879
1108
  .gal-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; }
@@ -882,8 +1111,8 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
882
1111
 
883
1112
  /* (sprint 73) the Create Application wizard on one page */
884
1113
  .create-sources { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 0.5rem; margin: 0.75rem 0 1rem; }
885
- .create-source { display: flex; gap: 0.6rem; align-items: flex-start; padding: 0.6rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text); text-decoration: none; }
886
- .create-source:hover, .create-source:focus-visible { border-color: var(--accent); }
1114
+ .create-source { display: flex; gap: 0.6rem; align-items: flex-start; padding: 0.7rem 0.85rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text); text-decoration: none; box-shadow: var(--shadow-xs); transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
1115
+ .create-source:hover, .create-source:focus-visible { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); box-shadow: var(--shadow-md); }
887
1116
  .create-source .icon { color: var(--accent); margin-top: 0.15rem; }
888
1117
  .create-source span { display: grid; gap: 0.1rem; min-width: 0; overflow-wrap: anywhere; }
889
1118
  .create-app .region + form, .create-app form .region { margin-top: 1rem; }
@@ -898,8 +1127,8 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
898
1127
  .aw-advanced .region-body { padding: 1rem; }
899
1128
  /* the overlay while a long form (Create application) is being processed */
900
1129
  .progress-overlay { position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center; background: rgb(0 0 0 / 35%); }
901
- .progress-box { display: flex; align-items: center; gap: 0.75rem; padding: 1rem 1.25rem; border-radius: var(--radius); background: var(--surface); color: var(--text); box-shadow: 0 8px 24px rgb(0 0 0 / 25%); }
902
- .progress-spinner { width: 1.25rem; height: 1.25rem; border-radius: 50%; border: 3px solid var(--border); border-top-color: var(--accent); animation: progress-spin 0.8s linear infinite; }
1130
+ .progress-box { display: flex; align-items: center; gap: 0.75rem; padding: 1rem 1.25rem; border-radius: var(--radius-lg); background: var(--surface); color: var(--text); box-shadow: var(--shadow-lg); }
1131
+ .progress-spinner { width: 1.25rem; height: 1.25rem; border-radius: 50%; border: 3px solid var(--border); border-top-color: var(--hot); animation: progress-spin 0.8s linear infinite; }
903
1132
  @keyframes progress-spin { to { transform: rotate(360deg); } }
904
1133
  @media (prefers-reduced-motion: reduce) { .progress-spinner { animation: none; } }
905
1134
 
@@ -907,7 +1136,7 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
907
1136
  .alert-dismissible { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
908
1137
  .alert-dismissible form { margin: 0; }
909
1138
  .rail-avatar.has-dot { position: relative; }
910
- .rail-avatar.has-dot::after { content: ""; position: absolute; top: 2px; right: 2px; width: 9px; height: 9px; border-radius: 50%; background: var(--danger, #c23028); box-shadow: 0 0 0 2px var(--rail-bg, #1b2330); }
1139
+ .rail-avatar.has-dot::after { content: ""; position: absolute; top: 2px; right: 2px; width: 9px; height: 9px; border-radius: 50%; background: var(--danger, #c23028); box-shadow: 0 0 0 2px var(--chrome, #1c1917); }
911
1140
  .weak-note { color: var(--danger, #c23028) !important; }
912
1141
 
913
1142
  /* (sprint 74) Shared Components: groups of component types with counts; a list per type */
@@ -916,15 +1145,17 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
916
1145
  .sc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: 1rem; align-items: start; }
917
1146
  .sc-group .region-header h2 { display: flex; align-items: center; gap: 0.5rem; }
918
1147
  .sc-links { list-style: none; margin: 0; padding: 0.4rem 0; }
919
- .sc-links li { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; padding: 0.3rem 1rem; }
1148
+ .sc-links li { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; padding: 0.32rem 1rem; }
1149
+ .sc-links li:hover { background: var(--surface-2); }
1150
+ .sc-group .region-header h2 .icon { color: var(--accent); }
920
1151
  .sc-links a { overflow-wrap: anywhere; min-width: 0; }
921
1152
  .sc-count { font-size: 0.78rem; font-weight: 600; color: var(--muted); background: var(--surface-3); border-radius: 99px; padding: 0.05rem 0.5rem; }
922
1153
 
923
1154
  /* (sprint 74) application Settings in tabs */
924
1155
  .settings-tabs { display: flex; flex-wrap: wrap; gap: 0.25rem; border-bottom: 1px solid var(--border); margin: 0 0 1rem; }
925
- .settings-tabs a { padding: 0.5rem 0.85rem; color: var(--muted); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; }
1156
+ .settings-tabs a { padding: 0.5rem 0.85rem; color: var(--muted); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; font-weight: 550; transition: color var(--dur) var(--ease); }
926
1157
  .settings-tabs a:hover { color: var(--text); }
927
- .settings-tabs a[aria-current="page"] { color: var(--text); border-bottom-color: var(--accent); font-weight: 600; }
1158
+ .settings-tabs a[aria-current="page"] { color: var(--text); border-bottom-color: var(--hot); }
928
1159
  .settings-body { display: grid; gap: 1rem; max-width: 64rem; }
929
1160
  .settings-form { display: grid; gap: 1rem; }
930
1161
 
@@ -937,8 +1168,8 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
937
1168
  .pages-bar .search input { flex: 1; min-width: 0; }
938
1169
  .view-toggle a { display: inline-flex; align-items: center; gap: 0.3rem; }
939
1170
  .page-icons { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: 0.6rem; }
940
- .page-icon { display: grid; gap: 0.15rem; padding: 0.7rem 0.8rem; border: 1px solid var(--border); border-radius: var(--radius); color: var(--text); text-decoration: none; overflow-wrap: anywhere; }
941
- .page-icon:hover, .page-icon:focus-visible { border-color: var(--accent); }
1171
+ .page-icon { display: grid; gap: 0.15rem; padding: 0.75rem 0.85rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); color: var(--text); text-decoration: none; overflow-wrap: anywhere; box-shadow: var(--shadow-xs); transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
1172
+ .page-icon:hover, .page-icon:focus-visible { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); box-shadow: var(--shadow-md); }
942
1173
  .page-icon-no { font-size: 1.3rem; font-weight: 700; color: var(--accent); }
943
1174
  .app-tasks .sc-links a { display: inline-flex; align-items: center; gap: 0.45rem; }
944
1175
 
@@ -985,12 +1216,12 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
985
1216
  @media (max-width: 640px) { .pd-canvas .pd-columns:has(> .pd-zone) { grid-template-columns: minmax(0, 1fr); } }
986
1217
 
987
1218
  /* (sprint 77) the rendering tree's context menu, the Copy to other page dialog, component colours */
988
- .pd-menu { position: fixed; z-index: 60; min-width: 13rem; padding: 4px; background: var(--surface, #fff); color: var(--text); border: 1px solid var(--border); border-radius: 4px; box-shadow: 0 6px 20px rgb(0 0 0 / 0.18); font-size: 13px; }
989
- .pd-menu [role=menuitem] { display: block; width: 100%; padding: 0.35rem 0.6rem; border: 0; border-radius: 3px; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
1219
+ .pd-menu { position: fixed; z-index: 60; min-width: 13rem; padding: 4px; background: var(--surface, #fff); color: var(--text); border: 1px solid var(--border-strong); border-radius: var(--radius); box-shadow: var(--shadow-lg); font-size: 13px; }
1220
+ .pd-menu [role=menuitem] { display: block; width: 100%; padding: 0.35rem 0.6rem; border: 0; border-radius: 4px; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
990
1221
  .pd-menu [role=menuitem]:is(:hover, :focus-visible) { background: var(--sel-bg); color: var(--sel-text); outline: none; }
991
1222
  .pd-menu [role=menuitem].is-danger { color: var(--danger); }
992
1223
  .pd-menu [role=separator] { height: 1px; margin: 4px 2px; background: var(--border); }
993
- .pd-dialog { width: min(28rem, calc(100vw - 32px)); padding: 1rem 1.1rem; border: 1px solid var(--border); border-radius: 6px; background: var(--surface, #fff); color: var(--text); }
1224
+ .pd-dialog { width: min(28rem, calc(100vw - 32px)); padding: 1rem 1.1rem; border: 1px solid var(--border-strong); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); background: var(--surface, #fff); color: var(--text); }
994
1225
  .pd-dialog::backdrop { background: rgb(0 0 0 / 0.35); }
995
1226
  .pd-dialog h2 { margin: 0 0 0.5rem; font-size: 1.05rem; }
996
1227
  .pd-dialog-buttons { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 1rem; }
@@ -1054,3 +1285,77 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
1054
1285
  }
1055
1286
  /* (sprint 100) RESTful Services: examples wrap instead of scrolling sideways */
1056
1287
  pre.wrap-pre { white-space: pre-wrap; overflow-wrap: anywhere; }
1288
+
1289
+ /* (sprint 103) SQL Workshop › Schema Export / Import */
1290
+ .dp-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 0.3rem 1rem; margin: 0 0 1rem; }
1291
+ .dp-facts dt { color: var(--muted); }
1292
+ .dp-facts dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
1293
+ .dp-tables { display: grid; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); gap: 0.2rem 1rem; margin: 0.5rem 0; }
1294
+ .dp-log { max-height: 32rem; }
1295
+ /* (sprint 101, DA-12) SQL Workshop › Scheduling */
1296
+ .cron-list td, .cron-runs-table td { overflow-wrap: anywhere; }
1297
+ .cron-cmd { display: inline-block; max-width: 40ch; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; }
1298
+ .cron-wide { grid-column: 1 / -1; }
1299
+ .cron-inline { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; }
1300
+ .cron-inline select { min-width: 0; max-width: 100%; flex: 1 1 12rem; }
1301
+ .cron-fields { border: 1px solid var(--border); border-radius: 6px; padding: 0.6rem 0.8rem; margin: 0.8rem 0; min-width: 0; }
1302
+ .cron-field-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); gap: 0.6rem; }
1303
+ .cron-field-grid input { width: 100%; font-family: var(--mono, monospace); }
1304
+ .cron-preview { border-left: 3px solid var(--accent); padding: 0.4rem 0.8rem; margin: 0.6rem 0; background: var(--accent-soft); border-radius: 0 4px 4px 0; }
1305
+ .cron-runs { margin: 0.25rem 0 0; padding-left: 1.4rem; font-variant-numeric: tabular-nums; }
1306
+ .cron-error { color: var(--danger, #b42318); }
1307
+ .cron-sql { white-space: pre-wrap; overflow-wrap: anywhere; }
1308
+ /* (sprint 102) SQL Monitor: refresh controls, session actions, bars in Top SQL */
1309
+ .sm-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-bottom: 0.75rem; }
1310
+ .sm-live.is-paused .sm-updated::after { content: " · paused"; }
1311
+ .sm-actions { display: flex; flex-wrap: wrap; gap: 0.25rem; }
1312
+ .sm-action { margin: 0; }
1313
+ .sm-sessions tr.is-blocked td { background: var(--warning-soft); }
1314
+ .sm-filter { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
1315
+ .sm-filter input[type=search] { flex: 1 1 12rem; min-width: 0; }
1316
+ .sm-top th a { color: inherit; text-decoration: none; white-space: nowrap; }
1317
+ .sm-top th[aria-sort] a { text-decoration: underline; }
1318
+ .sm-barcell { white-space: nowrap; }
1319
+ .sm-bar { display: inline-block; width: 4.5rem; height: 0.5rem; margin-right: 0.4rem; vertical-align: middle; }
1320
+ .sm-bar-track { fill: var(--border); }
1321
+ .sm-bar-fill { fill: var(--accent); }
1322
+ /* a statement's text is clipped to 1000 characters on the server: no scroll box inside the table */
1323
+ .sm-top .sql-text { max-height: none; overflow: visible; }
1324
+ .sm-sql { white-space: pre-wrap; overflow-wrap: anywhere; max-height: 20rem; overflow: auto; }
1325
+ @media (max-width: 640px) { .sm-bar { width: 3rem; } }
1326
+
1327
+ /* (sprint 104) SQL Workshop › RESTful Services › Modules: the module's tree beside the page */
1328
+ .rm-layout { display: grid; grid-template-columns: minmax(0, 17rem) minmax(0, 1fr); gap: 1rem; align-items: start; }
1329
+ .rm-layout > .region, .rm-main > .region { margin-top: 0; }
1330
+ .rm-main { display: grid; gap: 1rem; min-width: 0; }
1331
+ .rm-tree .tree code { font-size: 0.75rem; min-width: 3.4rem; }
1332
+ @media (max-width: 760px) { .rm-layout { grid-template-columns: minmax(0, 1fr); } }
1333
+
1334
+ /* ------------------------------------------------------------ page polish (sprint 108): Object Browser, wizards, SQL Monitor */
1335
+ /* Object Browser: the tree in the builder's type scale, the selected object with the ember bar */
1336
+ .ob-folder .tree { font-size: var(--fs-base); }
1337
+ .ob-folder .tree a { padding-block: 0.28rem; }
1338
+ .ob-folder .tree a[aria-current="page"] { background: var(--sel-bg); color: var(--sel-text); box-shadow: inset 2px 0 0 var(--sel-bar); font-weight: 600; }
1339
+ .ob-folder > summary { border-radius: var(--radius-sm); }
1340
+ .ob-folder > summary:hover { background: var(--surface-3); }
1341
+ .ob-folder > summary .icon { color: var(--muted); }
1342
+ /* wizards: the icon picker looks like a select; a colour field is a swatch, not a bar */
1343
+ .ide .icon-picker > summary { border-color: var(--field-border); border-radius: var(--radius-sm); box-shadow: var(--shadow-xs); transition: border-color var(--dur) var(--ease); }
1344
+ .ide .icon-picker > summary:hover { border-color: color-mix(in srgb, var(--text) 22%, var(--border-strong)); }
1345
+ .ide .icon-picker > summary::after {
1346
+ content: ""; width: 14px; height: 14px; margin-left: 0.15rem;
1347
+ background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23857d75' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m7 10 5 5 5-5'/%3E%3C/svg%3E") center / 14px no-repeat;
1348
+ }
1349
+ .ide .icon-picker[open] > summary { border-color: var(--accent); box-shadow: 0 0 0 3px var(--ring); }
1350
+ .ide .icon-picker-panel { border-color: var(--border-strong); border-radius: var(--radius); box-shadow: var(--shadow-md); background: var(--surface); }
1351
+ .ide .field input[type=color]:not(.swatch) {
1352
+ width: 4.5rem; height: 34px; min-height: 0; padding: 3px; cursor: pointer;
1353
+ border: 1px solid var(--field-border); border-radius: var(--radius-sm); background: var(--surface); box-shadow: var(--shadow-xs);
1354
+ }
1355
+ .ide .field input[type=color]::-webkit-color-swatch-wrapper { padding: 0; }
1356
+ .ide .field input[type=color]::-webkit-color-swatch { border: 0; border-radius: 4px; }
1357
+ .ide .field input[type=color]::-moz-color-swatch { border: 0; border-radius: 4px; }
1358
+ /* SQL Monitor: the refresh controls on one row */
1359
+ .sm-toolbar:not([hidden]) { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin: 0.25rem 0 0.75rem; }
1360
+ .sm-toolbar select { width: auto; }
1361
+ .sm-toolbar [aria-pressed="true"] { background: var(--accent-soft); color: var(--accent); }