pgkiln 0.47.0 → 0.49.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 (69) hide show
  1. package/SECURITY.md +2 -2
  2. package/db/migrations/109_builder_pins.sql +19 -0
  3. package/db/migrations/110_sql_charts.sql +23 -0
  4. package/db/migrations/111_sql_diagram.sql +24 -0
  5. package/db/migrations/113_rest_objects.sql +49 -0
  6. package/db/migrations/116_dump_jobs.sql +41 -0
  7. package/db/migrations/117_rest_handlers.sql +63 -0
  8. package/db/migrations/118_change_log.sql +54 -0
  9. package/docs/apex-feature-parity.md +11 -11
  10. package/docs/guide/01-installation.md +4 -0
  11. package/docs/guide/03-builder.md +267 -7
  12. package/docs/guide/08-security.md +29 -0
  13. package/docs/guide/12-development.md +70 -6
  14. package/docs/guide/13-rest-api.md +133 -10
  15. package/docs/guide/15-extensions.md +1 -1
  16. package/examples/hr/hr_62_rest_module.sql +39 -0
  17. package/package.json +1 -1
  18. package/public/app.css +1 -1
  19. package/public/builder-icons.svg +2 -0
  20. package/public/builder.css +442 -173
  21. package/public/builder.js +48 -0
  22. package/public/data-modeler.css +56 -0
  23. package/public/data-modeler.js +367 -0
  24. package/public/palette.js +133 -0
  25. package/public/sql-monitor.js +73 -0
  26. package/public/worksheet.css +49 -0
  27. package/public/worksheet.js +4 -0
  28. package/src/app.ts +10 -0
  29. package/src/automations.ts +6 -0
  30. package/src/binds.ts +2 -1
  31. package/src/builder/advisor.ts +24 -2
  32. package/src/builder/autorest.ts +363 -0
  33. package/src/builder/changelog.ts +240 -0
  34. package/src/builder/components.ts +1 -1
  35. package/src/builder/data-modeler.ts +382 -0
  36. package/src/builder/datapump.ts +364 -0
  37. package/src/builder/db-users.ts +472 -0
  38. package/src/builder/ddl-tools.ts +13 -4
  39. package/src/builder/find-workspace.ts +2 -2
  40. package/src/builder/launchpad.ts +140 -0
  41. package/src/builder/object-actions.ts +1 -0
  42. package/src/builder/object-browser.ts +7 -1
  43. package/src/builder/plan-view.ts +25 -0
  44. package/src/builder/rest-modules.ts +629 -0
  45. package/src/builder/rest.ts +1 -0
  46. package/src/builder/routes.ts +4 -2
  47. package/src/builder/scheduling.ts +495 -0
  48. package/src/builder/sql-charts.ts +203 -0
  49. package/src/builder/sql-monitor.ts +397 -0
  50. package/src/builder/sql-tools.ts +53 -0
  51. package/src/builder/sql-utilities.ts +7 -39
  52. package/src/builder/sql.ts +20 -9
  53. package/src/builder/table-editor.ts +4 -1
  54. package/src/builder/top-sql.ts +24 -6
  55. package/src/builder/ui.ts +25 -17
  56. package/src/builder/worksheet.ts +35 -28
  57. package/src/builder/workspaces.ts +4 -2
  58. package/src/changelog.ts +109 -0
  59. package/src/cli/replace.ts +3 -1
  60. package/src/cron-schedule.ts +282 -0
  61. package/src/datamodel.ts +324 -0
  62. package/src/datapump.ts +546 -0
  63. package/src/dbroles.ts +215 -0
  64. package/src/dumpscript.ts +407 -0
  65. package/src/pgcron.ts +225 -0
  66. package/src/runtime/autorest.ts +336 -0
  67. package/src/runtime/rest-handlers.ts +75 -0
  68. package/src/runtime/rest.ts +120 -26
  69. package/src/session.ts +2 -0
@@ -1,100 +1,266 @@
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
+ The light set first, the dark set for data-theme="dark" and for "System" when
13
+ the OS prefers dark. The chrome (rail, toolbar, status bar) is dark in both
14
+ themes (the same colours), a shade deeper than the page in the dark one. */
6
15
 
7
16
  :is(.ide, .ide-login) {
8
- --rail-w: 52px;
17
+ --rail-w: 56px;
9
18
  --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;
19
+ --page-px: 22px;
20
+ --page-py: 18px;
21
+
22
+ /* chrome: the rail, the top toolbar and the status bar */
23
+ --chrome: #13110f;
24
+ --chrome-2: #25221f;
25
+ --chrome-3: #37332f;
26
+ --chrome-text: #f5f4f2;
27
+ --chrome-muted: #aca59f;
28
+ --chrome-border: #2a2623;
29
+ --chrome-glow: rgb(234 88 12 / 16%);
30
+
31
+ /* brand: ember */
32
+ --ember-1: #fb923c;
33
+ --ember-2: #ea580c;
34
+ --ember-3: #c2410c;
35
+ --hot: #c2410c;
36
+ --hot-hover: #ad3a0b;
18
37
  --hot-text: #ffffff;
19
- --sel-bg: #1a73a8;
20
- --sel-text: #ffffff;
38
+ --sel-bg: #fde3d2;
39
+ --sel-text: var(--text);
40
+ --sel-bar: var(--hot);
21
41
  --warn: #b7791f;
22
42
 
23
- --bg: #e8e6e2;
43
+ /* neutrals */
44
+ --bg: #f6f5f3;
24
45
  --surface: #ffffff;
25
- --surface-2: #f6f5f2;
26
- --surface-3: #ebe9e5;
27
- --text: #1e1d1b;
28
- --muted: #5e5a54;
29
- --border: #d3d0ca;
30
- --accent: #0f66a0;
46
+ --surface-2: #faf9f7;
47
+ --surface-3: #f1efec;
48
+ --text: #1c1917;
49
+ --muted: #5c5650;
50
+ --border: #e7e4e0;
51
+ --border-strong: #d6d1cb;
52
+ --accent: #b8410c;
31
53
  --accent-text: #ffffff;
32
- --accent-soft: #dbeaf5;
33
- --gold: #8a5a00;
34
- --canvas: #dad8d3;
54
+ --accent-soft: #fdeee4;
55
+ --ring: rgb(194 65 12 / 28%);
56
+ --gold: #b8410c;
57
+ --canvas: #efede9;
58
+ --canvas-dot: #d9d5cf;
35
59
  --block: #ffffff;
36
- --block-head: #f1efeb;
37
- --code-bg: #f8f7f4;
38
- --radius: 4px;
39
- --shadow: none;
60
+ --block-head: #f7f5f2;
61
+ --code-bg: #fbfaf8;
62
+ --ce-bg: #fdfcfb;
63
+ --ce-gutter: #f5f3f0;
64
+ --ce-gutter-text: #6b645d;
65
+ --field-border: var(--border-strong);
66
+
67
+ /* shape, elevation, type, motion */
68
+ --radius-sm: 6px;
69
+ --radius: 8px;
70
+ --radius-lg: 12px;
71
+ --shadow-xs: 0 1px 1px rgb(28 25 23 / 4%);
72
+ --shadow-sm: 0 1px 2px rgb(28 25 23 / 6%), 0 1px 3px rgb(28 25 23 / 4%);
73
+ --shadow-md: 0 2px 4px rgb(28 25 23 / 4%), 0 8px 20px -4px rgb(28 25 23 / 10%);
74
+ --shadow-lg: 0 4px 8px rgb(28 25 23 / 6%), 0 16px 40px -8px rgb(28 25 23 / 22%);
75
+ --shadow: var(--shadow-xs);
76
+ --font: "Inter", "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, "SF Pro Text", Roboto, "Noto Sans", "Helvetica Neue", sans-serif;
77
+ --mono: "JetBrains Mono", "Cascadia Code", "SF Mono", ui-monospace, Menlo, Consolas, "Liberation Mono", monospace;
78
+ --fs-xs: 11.5px;
79
+ --fs-sm: 12.5px;
80
+ --fs-base: 13px;
81
+ --fs-md: 14px;
82
+ --fs-lg: 16px;
83
+ --fs-xl: 20px;
84
+ --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
85
+ --dur: 140ms;
40
86
  color-scheme: light;
41
87
  }
42
88
  @media (prefers-color-scheme: dark) {
43
89
  :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;
90
+ --chrome-glow: rgb(234 88 12 / 13%);
91
+ --bg: #181715; --surface: #1f1d1b; --surface-2: #242220; --surface-3: #2d2b28; --text: #edebe8; --muted: #a8a19a;
92
+ --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;
93
+ --gold: #ff9152; --canvas: #151412; --canvas-dot: #2a2825; --block: #222120; --block-head: #292725; --code-bg: #1a1917; --warn: #e0a740;
94
+ --ce-bg: #1a1917; --ce-gutter: #1f1d1b; --ce-gutter-text: #8f8880;
95
+ --shadow-xs: 0 1px 1px rgb(0 0 0 / 30%);
96
+ --shadow-sm: 0 1px 2px rgb(0 0 0 / 40%), inset 0 1px 0 rgb(255 255 255 / 3%);
97
+ --shadow-md: 0 4px 16px -2px rgb(0 0 0 / 50%), inset 0 1px 0 rgb(255 255 255 / 4%);
98
+ --shadow-lg: 0 18px 44px -8px rgb(0 0 0 / 65%), 0 0 0 1px rgb(255 255 255 / 5%);
47
99
  --pd-c-region: #7fb4ea; --pd-c-item: #7ccf8c; --pd-c-button: #f0a35e; --pd-c-da: #c49cf0; --pd-c-process: #ee8fbf;
48
100
  color-scheme: dark;
49
101
  }
50
102
  }
51
103
  :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;
104
+ --chrome-glow: rgb(234 88 12 / 13%);
105
+ --bg: #181715; --surface: #1f1d1b; --surface-2: #242220; --surface-3: #2d2b28; --text: #edebe8; --muted: #a8a19a;
106
+ --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;
107
+ --gold: #ff9152; --canvas: #151412; --canvas-dot: #2a2825; --block: #222120; --block-head: #292725; --code-bg: #1a1917; --warn: #e0a740;
108
+ --ce-bg: #1a1917; --ce-gutter: #1f1d1b; --ce-gutter-text: #8f8880;
109
+ --shadow-xs: 0 1px 1px rgb(0 0 0 / 30%);
110
+ --shadow-sm: 0 1px 2px rgb(0 0 0 / 40%), inset 0 1px 0 rgb(255 255 255 / 3%);
111
+ --shadow-md: 0 4px 16px -2px rgb(0 0 0 / 50%), inset 0 1px 0 rgb(255 255 255 / 4%);
112
+ --shadow-lg: 0 18px 44px -8px rgb(0 0 0 / 65%), 0 0 0 1px rgb(255 255 255 / 5%);
55
113
  --pd-c-region: #7fb4ea; --pd-c-item: #7ccf8c; --pd-c-button: #f0a35e; --pd-c-da: #c49cf0; --pd-c-process: #ee8fbf;
56
114
  color-scheme: dark;
57
115
  }
58
116
 
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; }
117
+ body.ide {
118
+ margin: 0; min-height: 100vh; min-height: 100dvh; padding-left: var(--rail-w); background: var(--bg); color: var(--text);
119
+ font-family: var(--font); font-size: var(--fs-base); line-height: 1.45;
120
+ font-feature-settings: "cv11", "ss01", "ss03"; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility;
121
+ }
122
+ .ide ::selection { background: color-mix(in srgb, var(--accent) 26%, transparent); }
123
+ .ide :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }
61
124
  .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; }
125
+ .ide h1 { font-size: var(--fs-xl); font-weight: 680; letter-spacing: -0.018em; line-height: 1.25; }
126
+ .ide h2 { font-size: var(--fs-md); font-weight: 650; letter-spacing: -0.006em; }
127
+ .ide h3 { font-size: var(--fs-base); font-weight: 650; }
65
128
  .ide code { font-size: 0.92em; }
66
129
  .ide .small { font-size: 12px; }
67
130
  .ide .skip-link { z-index: 60; }
131
+ .ide { scrollbar-color: var(--border-strong) transparent; }
132
+ .ide a { text-underline-offset: 2px; text-decoration-thickness: from-font; }
133
+
134
+ /* ------------------------------------------------------------ foundations (sprint 105): the shared controls */
135
+ .ide .btn {
136
+ min-height: 30px; font-weight: 560; border-color: var(--border-strong); background: var(--surface); box-shadow: var(--shadow-xs);
137
+ transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), color var(--dur) var(--ease);
138
+ }
139
+ .ide .btn:hover { background: var(--surface-3); border-color: color-mix(in srgb, var(--text) 22%, var(--border-strong)); }
140
+ .ide .btn:active { box-shadow: none; translate: 0 0.5px; }
141
+ .ide .btn .icon { width: 15px; height: 15px; }
142
+ .ide .btn-run, .ide .btn-hot, .ide-login .btn-hot {
143
+ background: var(--hot); border-color: color-mix(in srgb, var(--hot) 80%, black); color: var(--hot-text);
144
+ box-shadow: inset 0 1px 0 rgb(255 255 255 / 16%), 0 1px 2px rgb(124 45 18 / 30%);
145
+ }
146
+ .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); }
147
+ .ide .btn-danger { color: var(--danger); }
148
+ .ide .btn-danger:hover { background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); }
149
+ /* fields: app.css draws their border with var(--field-border); a ring on focus (a field that draws its own
150
+ frame, like the code editor or the property filter, sets box-shadow: none) */
151
+ .ide :where(input:not([type=checkbox], [type=radio], [type=color], [type=range], [type=file]), select, textarea) {
152
+ transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
153
+ }
154
+ .ide :where(input:not([type=checkbox], [type=radio], [type=color], [type=range], [type=file]), select, textarea):focus-visible {
155
+ outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--ring);
156
+ }
157
+ .ide input::placeholder, .ide textarea::placeholder { color: color-mix(in srgb, var(--muted) 85%, transparent); }
158
+ /* selects: one chevron in both themes (img-src allows data: URIs) */
159
+ .ide select:not([multiple]):not([size]) {
160
+ appearance: none; -webkit-appearance: none; padding-right: 1.9rem;
161
+ 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");
162
+ background-repeat: no-repeat; background-position: right 0.5rem center; background-size: 14px;
163
+ }
164
+ .ide input[type=checkbox], .ide input[type=radio] { accent-color: var(--hot); }
165
+ .ide .label { color: var(--muted); font-weight: 600; }
166
+ .ide .help { color: var(--muted); }
167
+ .ide .alert { border-radius: var(--radius); box-shadow: var(--shadow-xs); }
168
+ .ide .badge { background: var(--accent-soft); color: var(--accent); font-weight: 650; }
169
+ .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); }
170
+ .ide kbd { border-radius: 4px; border-color: var(--border-strong); background: var(--surface); color: var(--muted); }
171
+ /* menus: rounded, elevated, rows with a hover background */
172
+ .ide .menu-panel { border-radius: var(--radius); border-color: var(--border-strong); box-shadow: var(--shadow-lg); padding: 4px 0; }
173
+ .ide .menu-section { padding: 6px 8px; gap: 2px; }
174
+ .ide .menu-section > :is(strong, .small) { padding: 2px 8px; }
175
+ .ide .menu-links a, .ide .menu-links button { padding: 6px 8px; border-radius: var(--radius-sm); transition: background-color var(--dur) var(--ease); }
176
+ .ide .menu-links a:hover, .ide .menu-links button:hover, .ide .menu-links a:focus-visible { background: var(--surface-3); color: var(--text); }
177
+ .ide .menu-links .icon { color: var(--muted); }
178
+ /* segmented controls */
179
+ .ide .segmented { border-color: var(--border-strong); background: var(--surface-2); padding: 2px; gap: 2px; border-radius: var(--radius-sm); }
180
+ .ide .segmented button { border-radius: 4px; border: 0; }
181
+ .ide .segmented button + button { border-left: 0; }
182
+ .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); }
183
+ /* reports: quiet headers, row hover, headers that stick inside a scrolling box */
184
+ .ide .table-wrap { border-radius: var(--radius); border-color: var(--border); background: var(--surface); box-shadow: var(--shadow-xs); }
185
+ .ide .report th {
186
+ position: sticky; top: 0; z-index: 1; background: var(--surface-2); color: var(--muted);
187
+ font-size: var(--fs-xs); font-weight: 650; letter-spacing: 0.035em; text-transform: uppercase;
188
+ }
189
+ .ide .report tbody tr { transition: background-color var(--dur) var(--ease); }
190
+ .ide .report tbody tr:hover { background: color-mix(in srgb, var(--accent-soft) 50%, var(--surface-2)); }
191
+ .ide .report td { font-variant-numeric: tabular-nums; }
192
+ .ide .report td.empty, .ide p.empty { color: var(--muted); }
193
+
194
+ /* links in reports and side lists: no underline until hovered */
195
+ .ide .report td a:not(.btn), .ide .sc-links a, .ide .tree a { text-decoration: none; }
196
+ .ide .report td a:not(.btn):hover, .ide .sc-links a:hover { text-decoration: underline; }
197
+ .ide .report td a:not(.btn) { font-weight: 550; color: var(--text); }
198
+ .ide .report td a:not(.btn):hover { color: var(--accent); }
199
+ .ide .sc-links a { color: var(--text); }
200
+ .ide .sc-links a:hover { color: var(--accent); }
201
+ .ide .sc-links a .icon { color: var(--muted); }
202
+ /* link groups (.seg: Report / Icons…) as a segmented control */
203
+ .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); }
204
+ .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); }
205
+ .ide .seg:not(.col) a:hover { color: var(--text); }
206
+ .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); }
207
+ /* fields in the dark toolbar (search, the designer's page number and page list) */
208
+ .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); }
209
+ .ide-bar input::placeholder { color: var(--chrome-muted); }
210
+ .ide .ide-bar .ide-search input[type=search] {
211
+ height: 30px; padding: 3px 8px 3px 28px; border-radius: var(--radius-sm);
212
+ 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");
213
+ background-repeat: no-repeat; background-position: 9px center; background-size: 14px;
214
+ }
215
+ .ide-bar .ide-search input:hover { border-color: color-mix(in srgb, var(--chrome-text) 25%, var(--chrome-3)); }
216
+ .ide-bar :is(input, select):focus-visible { border-color: var(--ember-1); box-shadow: 0 0 0 3px rgb(251 146 60 / 25%); }
217
+ /* phones: the designer's crowded toolbar shows the search as its icon until it has the focus */
218
+ @media (max-width: 640px) {
219
+ .ide.ide-full .ide-bar .ide-search input[type=search]:not(:focus) { width: 30px; padding-right: 0; color: transparent; }
220
+ .ide-full .ide-bar .ide-search input:not(:focus)::placeholder { color: transparent; }
221
+ }
68
222
 
69
223
  /* ------------------------------------------------------------ icon rail */
70
224
  .ide-rail {
71
225
  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;
226
+ display: flex; flex-direction: column; align-items: stretch; padding: 10px 0;
73
227
  background: var(--chrome); color: var(--chrome-text); border-right: 1px solid var(--chrome-border);
228
+ background-image: radial-gradient(120px 90px at 50% 0, var(--chrome-glow), transparent 70%);
74
229
  }
230
+ /* the brand mark: an ember flame on a glowing tile */
75
231
  .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;
232
+ display: grid; place-items: center; width: 36px; height: 36px; margin: 0 auto 14px; border-radius: 10px;
233
+ background: linear-gradient(150deg, var(--ember-1), var(--ember-2) 55%, var(--ember-3)); color: #fff; text-decoration: none;
234
+ 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%);
235
+ transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
78
236
  }
79
- .rail-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
237
+ .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); }
238
+ .rail-logo .icon, .signin-logo .icon { width: 22px; height: 22px; }
239
+ .rail-list { list-style: none; margin: 0; padding: 0 8px; display: flex; flex-direction: column; gap: 4px; }
80
240
  .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; }
241
+ .rail-link {
242
+ position: relative; display: grid; place-items: center; height: 40px; border-radius: var(--radius); color: var(--chrome-muted); text-decoration: none;
243
+ transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease);
244
+ }
245
+ .rail-link .icon { width: 20px; height: 20px; stroke-width: 1.75; }
83
246
  .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); }
247
+ .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); }
248
+ .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
249
  .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;
250
+ position: absolute; left: calc(100% + 12px); top: 50%; transform: translate(-4px, -50%); z-index: 2;
251
+ padding: 4px 9px; border-radius: var(--radius-sm); background: #0c0b0a; color: #f5f4f2; font-size: 12px; font-weight: 550; white-space: nowrap;
252
+ box-shadow: 0 6px 18px rgb(0 0 0 / 35%), 0 0 0 1px rgb(255 255 255 / 8%);
253
+ opacity: 0; pointer-events: none; transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
89
254
  }
90
- .rail-link:hover .rail-label, .rail-link:focus-visible .rail-label { opacity: 1; }
255
+ .rail-link:hover .rail-label, .rail-link:focus-visible .rail-label { opacity: 1; transform: translate(0, -50%); }
91
256
  .rail-user { display: flex; justify-content: center; padding: 6px 0 2px; }
92
257
  .rail-avatar {
93
258
  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;
259
+ background: linear-gradient(150deg, #57534e, #292524); color: #fff; font-weight: 700; font-size: 12px; letter-spacing: 0.02em;
260
+ 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
261
  }
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; }
262
+ .rail-avatar:hover { box-shadow: inset 0 1px 0 rgb(255 255 255 / 18%), 0 0 0 2px var(--ember-2); }
263
+ .rail-user .menu-panel { position: fixed; left: calc(var(--rail-w) + 8px); top: auto; bottom: 8px; min-width: 260px; font-size: 13px; }
98
264
  .rail-user .menu-section > strong { font-size: 13.5px; }
99
265
  .ide-theme { margin: 0; }
100
266
  .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 +268,9 @@ body.ide { margin: 0; min-height: 100vh; min-height: 100dvh; padding-left: var(-
102
268
  .rail-user .menu-links form { margin: 0; }
103
269
  /* workspace switcher in the account menu (064) */
104
270
  .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); }
271
+ .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; }
272
+ .ws-switch button:hover { background: var(--surface-3); }
273
+ .ws-switch button[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
108
274
  .ws-switch button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
109
275
  .ws-switch .icon { width: 14px; height: 14px; flex: none; }
110
276
 
@@ -112,28 +278,30 @@ body.ide { margin: 0; min-height: 100vh; min-height: 100dvh; padding-left: var(-
112
278
  .ide-main { min-width: 0; }
113
279
  .ide-bar {
114
280
  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);
281
+ height: var(--bar-h); padding: 0 10px 0 8px; background: var(--chrome); color: var(--chrome-text);
116
282
  border-bottom: 1px solid var(--chrome-border);
283
+ background-image: linear-gradient(90deg, var(--chrome-glow), transparent 32%);
117
284
  }
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); }
285
+ .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); }
286
+ .ide-back:hover { background: var(--chrome-2); color: var(--chrome-text); }
120
287
  .ide-back .icon { width: 18px; height: 18px; }
121
288
  .ide-crumbs { flex: 1 1 auto; min-width: 0; }
122
289
  .ide-crumbs:first-child { padding-left: 8px; }
123
290
  .ide-crumbs ol { display: flex; align-items: center; list-style: none; margin: 0; padding: 0; min-width: 0; white-space: nowrap; }
124
291
  .ide-crumbs li { min-width: 0; overflow: hidden; text-overflow: ellipsis; flex: 0 3 auto; }
125
292
  .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; }
293
+ .ide-crumbs li + li::before { content: "/"; padding: 0 0.6em; color: var(--chrome-muted); opacity: 0.5; }
294
+ .ide-crumbs a { color: var(--chrome-muted); text-decoration: none; border-radius: 4px; transition: color var(--dur) var(--ease); }
128
295
  .ide-crumbs a:hover { color: var(--chrome-text); text-decoration: underline; }
129
- .ide-crumbs [aria-current] { color: var(--chrome-text); font-weight: 650; }
296
+ .ide-crumbs [aria-current] { color: var(--chrome-text); font-weight: 600; }
130
297
  .ide-tools { display: flex; align-items: center; flex: none; min-width: 0; }
131
298
  .tb-group { display: flex; align-items: center; gap: 2px; padding: 0 6px; }
132
299
  .tb-group + .tb-group { border-left: 1px solid var(--chrome-border); }
133
300
  .tb-form { display: inline-flex; align-items: center; margin: 0; }
134
301
  .tb-btn {
135
302
  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;
303
+ border: 1px solid transparent; border-radius: var(--radius-sm); background: transparent; color: inherit; font: inherit; font-size: 12.5px;
304
+ transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
137
305
  cursor: pointer; text-decoration: none; white-space: nowrap;
138
306
  }
139
307
  .tb-btn:hover { background: color-mix(in srgb, currentColor 12%, transparent); }
@@ -148,66 +316,70 @@ body.ide { margin: 0; min-height: 100vh; min-height: 100dvh; padding-left: var(-
148
316
  .ide-bar .menu-panel { font-size: 13px; }
149
317
  .pd-goto select {
150
318
  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;
319
+ background-color: var(--chrome-2); color: var(--chrome-text); border: 1px solid var(--chrome-3); border-radius: var(--radius-sm);
152
320
  }
153
321
  .js .pd-goto-go { display: none; }
154
322
  .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); }
323
+ .ide-bar .btn { border-radius: var(--radius-sm); height: 32px; }
324
+ .ide .tb-save { background: var(--chrome-2); border-color: var(--chrome-3); color: var(--chrome-text); box-shadow: none; }
325
+ .ide .tb-save:hover { background: var(--chrome-3); border-color: var(--chrome-3); }
158
326
  .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
327
  .tb-main { gap: 6px; }
162
328
 
163
329
  /* ------------------------------------------------------------ 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; }
330
+ .ide-alerts { padding: 10px 18px 0; }
331
+ .ide-alerts .alert { padding: 0.5rem 2rem 0.5rem 0.85rem; margin-bottom: 8px; font-size: 13px; border-radius: var(--radius); }
166
332
  .ide-full .ide-alerts { padding: 6px 8px 0; background: var(--bg); }
167
333
  .ide-full .ide-alerts .alert { margin-bottom: 6px; }
168
334
 
169
335
  /* ------------------------------------------------------------ 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; }
336
+ .ide .ide-page { max-width: 1680px; margin: 0 auto; padding: var(--page-py) var(--page-px) 48px; }
337
+ .ide .region-standard, .ide .region-collapsible { border-radius: var(--radius-lg); border-color: var(--border); box-shadow: var(--shadow-sm); }
338
+ .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; }
339
+ .ide .region-header h2 { font-size: 13.5px; font-weight: 650; letter-spacing: -0.005em; min-width: 0; overflow-wrap: anywhere; }
340
+ .ide .region-body { padding: 1rem; }
341
+ .ide .region-footer { background: var(--surface-2); border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
342
+ .ide .btn { font-size: 13px; padding: 0.34rem 0.8rem; border-radius: var(--radius-sm); }
343
+ .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
344
  .ide textarea.code { font-size: 12.5px; background: var(--code-bg); }
178
345
  .ide .label { font-size: 12.5px; }
179
346
  .ide .form-grid { gap: 0.7rem 1rem; }
180
347
  .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; }
348
+ .ide .report th, .ide .report td { padding: 0.42rem 0.7rem; }
349
+ .ide .report th { padding-top: 0.5rem; padding-bottom: 0.5rem; }
350
+ .ide .columns { gap: 1rem; margin-top: 1rem; }
351
+ .ide .title-row { margin-bottom: 1rem; }
352
+ .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); }
353
+ .ide :is(a.tile, a.stat, .app-card):hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); transform: translateY(-1px); }
354
+ .ide .tile { padding: 0.9rem; }
355
+ .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
356
  .ide .tiles { gap: 0.75rem; margin-bottom: 1rem; }
190
357
  .ide .app-cards { gap: 0.75rem; }
191
358
  .ide .app-card { padding: 0.8rem; gap: 0.5rem; }
192
359
  .ide .app-card .app-icon { width: 38px; height: 38px; border-radius: 6px; }
193
360
  .ide fieldset.prop-group > legend { font-size: 11.5px; }
194
- .ide .alert { border-radius: var(--radius); }
195
361
 
196
362
  /* 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; }
363
+ .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%); }
364
+ .ide-head-title { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; min-width: 0; }
199
365
  .ide-head-title > div:not(.buttons) { min-width: 0; }
200
366
  .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; }
367
+ .ide-app-icon {
368
+ display: grid; place-items: center; width: 40px; height: 40px; border-radius: 10px; flex: none;
369
+ background: linear-gradient(150deg, var(--ember-2), var(--ember-3)); color: #fff; font-weight: 750; font-size: 17px;
370
+ box-shadow: inset 0 1px 0 rgb(255 255 255 / 25%), var(--shadow-sm);
371
+ }
202
372
  .ide-head-actions { margin-left: auto; }
203
- .ide-tabs { display: flex; gap: 2px; margin-top: 8px; overflow-x: auto; scrollbar-width: thin; }
373
+ .ide-tabs { display: flex; gap: 4px; margin-top: 12px; overflow-x: auto; scrollbar-width: thin; }
204
374
  .ide-page > .ide-tabs { margin-top: 0; border-bottom: 1px solid var(--border); }
205
375
  .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;
376
+ position: relative; display: inline-flex; align-items: center; gap: 6px; padding: 8px 11px 9px; color: var(--muted); text-decoration: none;
377
+ border-bottom: 2px solid transparent; border-radius: var(--radius-sm) var(--radius-sm) 0 0; white-space: nowrap; font-weight: 550;
378
+ transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
208
379
  }
209
- .ide-tab:hover { color: var(--text); background: var(--surface-2); }
380
+ .ide-tab:hover { color: var(--text); background: var(--surface-3); }
210
381
  .ide-tab[aria-current] { color: var(--text); border-bottom-color: var(--hot); }
382
+ .ide-tab[aria-current] .icon { color: var(--accent); }
211
383
  .ide-tab .icon { width: 15px; height: 15px; }
212
384
 
213
385
  /* ------------------------------------------------------------ generic tabs (builder.js turns [data-tabs] into tabs) */
@@ -215,8 +387,10 @@ body.ide { margin: 0; min-height: 100vh; min-height: 100dvh; padding-left: var(-
215
387
  .tablist [role=tab] {
216
388
  display: inline-flex; align-items: center; gap: 6px; padding: 8px 10px 7px; border: 0; border-bottom: 2px solid transparent;
217
389
  background: none; color: var(--muted); font: inherit; font-weight: 600; cursor: pointer; white-space: nowrap;
390
+ transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
218
391
  }
219
392
  .tablist [role=tab]:hover { color: var(--text); }
393
+ .tablist [role=tab][aria-selected="true"] .icon { color: var(--accent); }
220
394
  .tablist [role=tab][aria-selected="true"] { color: var(--text); border-bottom-color: var(--hot); }
221
395
  .tablist [role=tab]:focus-visible { outline-offset: -2px; }
222
396
  .tabs-on > .tab-panel > .tab-title { display: none; }
@@ -273,7 +447,7 @@ body.ide { margin: 0; min-height: 100vh; min-height: 100dvh; padding-left: var(-
273
447
  .pd-tree ul { padding-left: 14px; }
274
448
  .pd-node {
275
449
  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;
450
+ border-radius: var(--radius-sm); color: var(--text); text-decoration: none; white-space: nowrap;
277
451
  }
278
452
  .pd-node .icon { width: 16px; height: 16px; color: var(--muted); }
279
453
  a.pd-node:hover { background: var(--surface-3); }
@@ -282,8 +456,7 @@ a.pd-node:hover { background: var(--surface-3); }
282
456
  .pd-folder { color: var(--muted); font-weight: 600; cursor: default; }
283
457
  .pd-tag { display: inline-flex; }
284
458
  .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); }
459
+ .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
460
  .pd-empty { padding: 2px 6px 2px 20px; color: var(--muted); font-style: italic; font-size: 12px; }
288
461
  /* twisties (builder.js marks nodes with children) */
289
462
  .pd-node.has-kids::before {
@@ -298,19 +471,22 @@ a.pd-node:hover { background: var(--surface-3); }
298
471
  /* ------------------------------------------------------------ layout canvas */
299
472
  .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
473
  .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); }
474
+ .pd-canvas {
475
+ --zoom: 1; padding: 14px; font-size: calc(13px * var(--zoom)); background-color: var(--canvas);
476
+ background-image: radial-gradient(var(--canvas-dot) 1px, transparent 1.2px); background-size: 16px 16px;
477
+ }
302
478
  .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
479
  .pd-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 8px; align-items: start; }
304
480
  .pd-span-1 { grid-column: span 1; } .pd-span-2 { grid-column: span 2; } .pd-span-3 { grid-column: span 3; }
305
481
  .pd-span-4 { grid-column: span 4; } .pd-span-5 { grid-column: span 5; } .pd-span-6 { grid-column: span 6; }
306
482
  .pd-span-7 { grid-column: span 7; } .pd-span-8 { grid-column: span 8; } .pd-span-9 { grid-column: span 9; }
307
483
  .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); }
484
+ .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); }
485
+ .pd-region:hover { border-color: color-mix(in srgb, var(--hot) 55%, var(--border)); box-shadow: var(--shadow-sm); }
486
+ .pd-region.is-selected { border-color: var(--hot); box-shadow: 0 0 0 1px var(--hot), 0 0 0 4px var(--ring); }
311
487
  .pd-region-head {
312
488
  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;
489
+ background: var(--block-head); border-bottom: 1px solid var(--border); border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0;
314
490
  }
315
491
  .js .pd-region-head { cursor: grab; }
316
492
  .pd-region.is-selected > .pd-region-head { background: var(--sel-bg); color: var(--sel-text); }
@@ -325,12 +501,13 @@ a.pd-node:hover { background: var(--surface-3); }
325
501
  .pd-region-body { display: flex; flex-direction: column; gap: 0.45em; padding: 0.45em; }
326
502
  .pd-region-type { color: var(--muted); font-size: 0.76em; font-weight: 650; text-transform: uppercase; letter-spacing: 0.05em; }
327
503
  .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; }
504
+ .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
505
  .pd-slot-button { flex-direction: row; flex-wrap: wrap; }
330
506
  .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
507
  .pd-chip {
332
508
  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;
509
+ background: var(--surface-2); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius-sm); text-decoration: none; font-size: 0.92em;
510
+ transition: border-color var(--dur) var(--ease);
334
511
  }
335
512
  .js .pd-chip { cursor: grab; }
336
513
  .pd-chip:hover { border-color: var(--hot); }
@@ -344,7 +521,8 @@ a.pd-node:hover { background: var(--surface-3); }
344
521
  .js .pd-resize { display: block; }
345
522
  .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
523
  .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; }
524
+ .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); }
525
+ .pd-grid-end:hover { border-color: var(--accent); }
348
526
  .pd-grid-end a { display: inline-flex; align-items: center; gap: 0.35em; color: var(--muted); text-decoration: none; font-size: 0.9em; }
349
527
  .pd-grid-end a:hover { color: var(--accent); }
350
528
  .pd-pagelevel { display: grid; gap: 0.4em; margin-top: 12px; padding: 0.5em; border: 1px dashed var(--border); border-radius: 4px; }
@@ -364,9 +542,10 @@ a.pd-node:hover { background: var(--surface-3); }
364
542
  .pd-gallery { background: var(--surface); border-top: 1px solid var(--border); }
365
543
  .pd-gallery .tablist { position: sticky; top: 0; z-index: 1; }
366
544
  .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; }
545
+ .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
546
  .js .pd-gal { cursor: grab; }
369
547
  .pd-gal:hover { background: var(--surface-3); }
548
+ .pd-gal:hover .icon { color: var(--accent); }
370
549
  .pd-gal .icon { width: 22px; height: 22px; color: var(--muted); stroke-width: 1.5; }
371
550
  .pd-gal span { min-width: 0; overflow-wrap: anywhere; line-height: 1.2; }
372
551
 
@@ -384,10 +563,10 @@ kbd { display: inline-block; padding: 0 0.35em; border: 1px solid var(--border);
384
563
  .pe-title { display: flex; align-items: center; gap: 6px; min-width: 0; font-weight: 650; }
385
564
  .pe-title span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
386
565
  .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; }
566
+ .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); }
567
+ .pe-filter-row:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--ring); }
389
568
  .pe-filter-row .icon { color: var(--muted); }
390
- .ide .pe-filter-row input.pe-filter { border: 0; background: transparent; padding: 5px 0; outline: none; }
569
+ .ide .pe-filter-row input.pe-filter { border: 0; background: transparent; padding: 5px 0; outline: none; box-shadow: none; }
391
570
  .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
571
  .pe-arrange-label { margin-right: 4px; color: var(--muted); font-size: 11.5px; font-weight: 650; letter-spacing: 0.05em; text-transform: uppercase; }
393
572
  .pe-arrange-form { display: inline-flex; align-items: center; gap: 4px; margin: 0; }
@@ -436,32 +615,37 @@ kbd { display: inline-block; padding: 0 0.35em; border: 1px solid var(--border);
436
615
  .pe-empty-filter { margin: 10px; color: var(--muted); }
437
616
 
438
617
  /* ------------------------------------------------------------ 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); }
618
+ .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
619
  .signin-body.ide-login { display: block; background: var(--bg); }
443
620
  .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
621
  .signin-hero {
445
622
  display: flex; flex-direction: column; justify-content: flex-start; gap: 0.75rem; padding: 3rem;
446
623
  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);
624
+ /* the kiln's glow rising from the bottom, over a faint grid */
625
+ background-image: radial-gradient(70% 55% at 30% 105%, rgb(234 88 12 / 38%), rgb(194 65 12 / 10%) 55%, transparent 80%),
626
+ linear-gradient(rgb(255 255 255 / 0.03) 1px, transparent 1px), linear-gradient(90deg, rgb(255 255 255 / 0.03) 1px, transparent 1px);
627
+ background-size: auto, 32px 32px, 32px 32px;
628
+ }
629
+ .signin-logo {
630
+ display: grid; place-items: center; width: 48px; height: 48px; border-radius: 13px; margin-bottom: 2rem; color: #fff;
631
+ background: linear-gradient(150deg, var(--ember-1), var(--ember-2) 55%, var(--ember-3));
632
+ box-shadow: inset 0 1px 0 rgb(255 255 255 / 30%), 0 8px 26px -4px rgb(234 88 12 / 60%);
449
633
  }
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); }
634
+ .signin-logo .icon { width: 28px; height: 28px; }
635
+ .signin-title { margin: 0; font-size: clamp(2rem, 4vw, 2.75rem); font-weight: 750; letter-spacing: -0.03em; color: var(--chrome-text); }
452
636
  .signin-tagline { margin: 0; font-size: 1.2rem; color: var(--chrome-muted); max-width: 30ch; }
453
637
  .signin-foot { margin: auto 0 0; font-size: 0.85rem; color: var(--chrome-muted); }
454
638
  .signin-panel { display: grid; place-items: center; padding: 2rem 1rem; background: var(--surface); }
455
639
  .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; }
640
+ .signin-form h2 { margin: 0; font-size: 1.5rem; letter-spacing: -0.02em; }
457
641
  .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; }
642
+ .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); }
643
+ .signin-input:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--ring); }
460
644
  .signin-input > .icon { flex: none; width: 18px; height: 18px; color: var(--muted); }
461
645
  .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
646
  .signin-reveal { flex: none; border: 0; background: none; color: var(--accent); cursor: pointer; font-size: 0.85rem; padding: 0.25rem; }
463
647
  .signin-remember { font-size: 0.9rem; }
464
- .signin-submit { padding: 0.75rem; font-size: 1rem; }
648
+ .signin-submit { padding: 0.75rem; font-size: 1rem; border-radius: var(--radius); }
465
649
  .signin-hint { margin: 0; text-align: center; }
466
650
  .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
651
  .signin-actions a { display: inline-flex; align-items: center; gap: 0.4rem; color: var(--gold); text-decoration: none; }
@@ -481,35 +665,42 @@ kbd { display: inline-block; padding: 0 0.35em; border: 1px solid var(--border);
481
665
  .ide-main > .ide-page { flex: 1 0 auto; width: 100%; }
482
666
  .ide-status {
483
667
  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;
668
+ min-height: 28px; padding: 0 14px; background: var(--chrome); color: var(--chrome-muted); border-top: 1px solid var(--chrome-border);
669
+ font-size: 11.5px; white-space: nowrap; overflow: hidden;
486
670
  }
487
671
  .ide-status > span { display: inline-flex; align-items: center; gap: 6px; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
488
672
  .ide-status .icon { width: 14px; height: 14px; flex: none; }
489
- .ide-status-version { margin-left: auto; }
673
+ .ide-status-version { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; }
674
+ .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
675
 
491
676
  /* ------------------------------------------------------------ App Builder home (tiles, applications, side column) */
492
677
  .ab-home { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; }
493
678
  .ab-main { min-width: 0; }
494
- .ab-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-bottom: 16px; }
679
+ .ab-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin-bottom: 20px; }
495
680
  .ab-tiles-wrap { grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); }
496
681
  .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;
682
+ position: relative; display: grid; grid-template-columns: auto; align-content: start; gap: 4px; min-height: 132px; padding: 16px 16px 18px;
683
+ background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); color: var(--text); text-decoration: none;
684
+ box-shadow: var(--shadow-sm); transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
499
685
  }
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; }
686
+ .ab-tile:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); box-shadow: var(--shadow-md); transform: translateY(-2px); }
687
+ .ab-tile-icon {
688
+ display: grid; place-items: center; width: 40px; height: 40px; margin-bottom: 12px; border-radius: 10px;
689
+ background: var(--accent-soft); color: var(--accent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 18%, transparent);
690
+ transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
691
+ }
692
+ .ab-tile:hover .ab-tile-icon { background: var(--hot); color: var(--hot-text); }
693
+ .ab-tile-icon .icon { width: 20px; height: 20px; }
694
+ .ab-tile strong { font-size: 14.5px; font-weight: 650; letter-spacing: -0.01em; }
504
695
  .ab-tile > span:last-child { color: var(--muted); font-size: 13px; }
505
696
 
506
697
  .ab-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 0 0 10px; }
507
698
  .ab-search { position: relative; flex: 0 1 260px; min-width: 160px; }
508
699
  .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); }
700
+ .ab-search input[type=search] { width: 100%; height: 34px; padding-left: 32px !important; background: var(--surface); }
701
+ .ab-views { display: inline-flex; gap: 2px; padding: 2px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface-2); }
702
+ .ab-views .tb-btn { height: 28px; width: 36px; min-width: 0; border-radius: 4px; color: var(--muted); }
703
+ .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
704
  .ab-menu > summary { display: inline-flex; align-items: center; gap: 4px; height: 34px; list-style: none; }
514
705
  .ab-menu > summary::-webkit-details-marker { display: none; }
515
706
  .ab-menu > summary .icon { width: 14px; height: 14px; rotate: 90deg; }
@@ -518,24 +709,27 @@ kbd { display: inline-block; padding: 0 0.35em; border: 1px solid var(--border);
518
709
  .ab-create { height: 34px; display: inline-flex; align-items: center; }
519
710
 
520
711
  .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); }
712
+ .ide table.ab-apps th { padding: 10px 12px; }
522
713
  .ide table.ab-apps th a { color: inherit; }
523
714
  .ide table.ab-apps td { padding: 9px 12px; height: 56px; }
524
715
  .ide table.ab-apps tbody tr:hover { background: var(--surface-2); }
525
716
  .ab-sorted { margin-left: 4px; }
526
717
  .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; }
718
+ .ab-name a { display: inline-flex; align-items: center; gap: 12px; color: var(--text); font-weight: 650; text-decoration: none; }
719
+ .ab-name a:hover { color: var(--accent); }
528
720
  .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; }
721
+ .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
722
  .ab-actions-col { text-align: right; }
531
723
  .ab-actions { text-align: right; white-space: nowrap; }
532
724
  .ab-actions .tb-btn, .ab-card-actions .tb-btn { color: var(--text); }
533
725
  .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); }
726
+ .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
727
 
536
728
  .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; }
729
+ .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); }
730
+ .ab-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); }
731
+ .ab-card-main { display: flex; align-items: center; gap: 12px; color: var(--text); text-decoration: none; min-width: 0; }
732
+ .ab-card-main:hover strong { color: var(--accent); }
539
733
  .ab-card-main > span:last-child { display: grid; min-width: 0; }
540
734
  .ab-card-main strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
541
735
  .ab-card-main small { color: var(--muted); }
@@ -544,12 +738,14 @@ kbd { display: inline-block; padding: 0 0.35em; border: 1px solid var(--border);
544
738
 
545
739
  .ab-side { padding: 4px 2px 0; }
546
740
  .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; }
741
+ .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
742
  .ab-side p { margin: 0 0 6px; color: var(--muted); }
549
- .ab-side a { color: var(--gold); text-decoration: none; }
743
+ .ab-side a { color: var(--accent); text-decoration: none; }
550
744
  .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; }
745
+ .ab-links { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
746
+ .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); }
747
+ .ab-side .ab-tasks a:hover { background: var(--surface-3); text-decoration: none; }
748
+ .ab-tasks a:hover .icon { color: var(--accent); }
553
749
  .ab-tasks .icon { width: 14px; height: 14px; color: var(--muted); }
554
750
  .ab-narrow { max-width: 900px; }
555
751
  .ab-narrow > h1 { margin-top: 4px; }
@@ -557,9 +753,9 @@ kbd { display: inline-block; padding: 0 0.35em; border: 1px solid var(--border);
557
753
 
558
754
  @media (min-width: 1280px) {
559
755
  /* 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); }
756
+ .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); }
757
+ .ab-main { padding: var(--page-py) var(--page-px) 48px 0; }
758
+ .ab-side { padding: 18px 20px 24px; background: var(--surface); border-left: 1px solid var(--border); }
563
759
  .ab-side section:first-child { border-top: 0; padding-top: 0; }
564
760
  }
565
761
  @media (max-width: 1023px) {
@@ -590,12 +786,16 @@ kbd { display: inline-block; padding: 0 0.35em; border: 1px solid var(--border);
590
786
 
591
787
  @media (max-width: 640px) {
592
788
  .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; }
789
+ .ide { --page-px: 12px; --page-py: 12px; }
790
+ .ide .ide-page { padding-bottom: 40px; }
791
+ .ide-head { padding-top: 12px; }
595
792
  .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; }
793
+ .rail-list { padding: 0 5px; }
794
+ .rail-link { height: 38px; }
795
+ .rail-link[aria-current]::before { left: -5px; }
796
+ .rail-link .icon { width: 19px; height: 19px; }
797
+ .rail-logo { width: 32px; height: 32px; border-radius: 9px; }
798
+ .rail-logo .icon { width: 19px; height: 19px; }
599
799
  .ide-bar { gap: 2px; padding: 0 4px; }
600
800
  .ide-crumbs li:not(:last-child) { display: none; }
601
801
  .ide-crumbs li:last-child::before { content: none; }
@@ -665,7 +865,7 @@ pre.ddl { max-height: 36rem; overflow: auto; }
665
865
  .qb-col .check { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
666
866
  .qb-col .qb-type { display: none; }
667
867
  .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); }
868
+ .qb-col.qb-target { background: var(--accent); color: var(--accent-text); }
669
869
  .qb-link { width: 22px; height: 22px; padding: 0; border: 0; background: none; cursor: crosshair; touch-action: none; }
670
870
  .qb-link::before { content: ''; display: block; width: 10px; height: 10px; margin: auto; border-radius: 50%; border: 2px solid var(--accent); }
671
871
  .qb-lines { position: absolute; left: 0; top: 0; pointer-events: none; overflow: visible; }
@@ -768,7 +968,7 @@ button.is-busy { opacity: 0.7; cursor: progress; }
768
968
  .tr-preview { --bg: #f3f4f6; --surface: #ffffff; --surface-2: #f6f7f9; --surface-3: #eceef2; --text: #1b2330; --muted: #5e6a7a; --border: #dfe3e8;
769
969
  --accent: #0b63c5; --accent-text: #ffffff; --accent-soft: #e7f0fb; --header: #13294b; --header-text: #eef2f8; --radius: 8px;
770
970
  --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;
971
+ --field-border: var(--border); color-scheme: light; margin-bottom: 1rem; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden;
772
972
  background: var(--bg); color: var(--text); font: var(--font-size)/1.5 var(--font); }
773
973
  .tr-preview-iris { --bg: #ffffff; --surface-2: #f7f6f5; --surface-3: #efedeb; --text: #1f1c1a; --muted: #645e59; --border: #e2dfdc;
774
974
  --accent: #2b62c4; --accent-soft: #e9f0fb; --header: #3a3632; --header-text: #f7f5f3; --radius: 4px; --shadow: none;
@@ -837,7 +1037,7 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
837
1037
  .ab-message { display: flex; gap: 0.6rem; align-items: flex-start; margin-bottom: 12px; }
838
1038
  .ab-message p { margin: 0.15rem 0 0; white-space: pre-line; }
839
1039
  .rail-admin { padding: 0; }
840
- .rail-admin > summary { list-style: none; cursor: pointer; }
1040
+ .rail-admin > summary { list-style: none; cursor: pointer; width: 100%; }
841
1041
  .rail-admin > summary::-webkit-details-marker { display: none; }
842
1042
  .rail-admin .menu-panel { bottom: 56px; }
843
1043
  .rail-admin .menu-links strong { padding: 2px 0 4px; }
@@ -845,14 +1045,13 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
845
1045
 
846
1046
  /* ------------------------------------------------------------ SQL Workshop home (sprint 61) */
847
1047
  .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); }
1048
+ .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
1049
  .sw-recent { min-width: 0; border-left: 1px solid var(--border); }
851
1050
  .sw-recent:first-child { border-left: 0; }
852
1051
  .sw-recent h2 { margin: 0; padding: 10px 12px; font-size: 13.5px; border-bottom: 1px solid var(--border); }
853
1052
  .sw-recent ul { list-style: none; margin: 0; padding: 0; max-height: 440px; overflow-y: auto; }
854
1053
  .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; }
1054
+ .sw-recent li a { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--accent); text-decoration: none; }
856
1055
  .sw-recent li a:hover { text-decoration: underline; }
857
1056
  .sw-recent li .muted { flex: none; font-size: 12px; }
858
1057
  .sw-recent > p { padding: 0 12px; }
@@ -870,10 +1069,11 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
870
1069
  .gal-tabs a:last-child { border-radius: 0 var(--radius) var(--radius) 0; }
871
1070
  .gal-tabs a[aria-current] { background: var(--surface-3); font-weight: 650; }
872
1071
  .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; }
1072
+ .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); }
1073
+ .gal-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); }
874
1074
  .gal-head { display: flex; gap: 12px; align-items: center; }
875
1075
  .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); }
1076
+ .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
1077
  .gal-icon .icon { width: 26px; height: 26px; }
878
1078
  .gal-card > p { margin: 0; flex: 1; line-height: 1.5; }
879
1079
  .gal-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; }
@@ -882,8 +1082,8 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
882
1082
 
883
1083
  /* (sprint 73) the Create Application wizard on one page */
884
1084
  .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); }
1085
+ .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); }
1086
+ .create-source:hover, .create-source:focus-visible { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); box-shadow: var(--shadow-md); }
887
1087
  .create-source .icon { color: var(--accent); margin-top: 0.15rem; }
888
1088
  .create-source span { display: grid; gap: 0.1rem; min-width: 0; overflow-wrap: anywhere; }
889
1089
  .create-app .region + form, .create-app form .region { margin-top: 1rem; }
@@ -898,8 +1098,8 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
898
1098
  .aw-advanced .region-body { padding: 1rem; }
899
1099
  /* the overlay while a long form (Create application) is being processed */
900
1100
  .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; }
1101
+ .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); }
1102
+ .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
1103
  @keyframes progress-spin { to { transform: rotate(360deg); } }
904
1104
  @media (prefers-reduced-motion: reduce) { .progress-spinner { animation: none; } }
905
1105
 
@@ -907,7 +1107,7 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
907
1107
  .alert-dismissible { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
908
1108
  .alert-dismissible form { margin: 0; }
909
1109
  .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); }
1110
+ .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
1111
  .weak-note { color: var(--danger, #c23028) !important; }
912
1112
 
913
1113
  /* (sprint 74) Shared Components: groups of component types with counts; a list per type */
@@ -916,15 +1116,17 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
916
1116
  .sc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: 1rem; align-items: start; }
917
1117
  .sc-group .region-header h2 { display: flex; align-items: center; gap: 0.5rem; }
918
1118
  .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; }
1119
+ .sc-links li { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; padding: 0.32rem 1rem; }
1120
+ .sc-links li:hover { background: var(--surface-2); }
1121
+ .sc-group .region-header h2 .icon { color: var(--accent); }
920
1122
  .sc-links a { overflow-wrap: anywhere; min-width: 0; }
921
1123
  .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
1124
 
923
1125
  /* (sprint 74) application Settings in tabs */
924
1126
  .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; }
1127
+ .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
1128
  .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; }
1129
+ .settings-tabs a[aria-current="page"] { color: var(--text); border-bottom-color: var(--hot); }
928
1130
  .settings-body { display: grid; gap: 1rem; max-width: 64rem; }
929
1131
  .settings-form { display: grid; gap: 1rem; }
930
1132
 
@@ -937,8 +1139,8 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
937
1139
  .pages-bar .search input { flex: 1; min-width: 0; }
938
1140
  .view-toggle a { display: inline-flex; align-items: center; gap: 0.3rem; }
939
1141
  .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); }
1142
+ .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); }
1143
+ .page-icon:hover, .page-icon:focus-visible { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); box-shadow: var(--shadow-md); }
942
1144
  .page-icon-no { font-size: 1.3rem; font-weight: 700; color: var(--accent); }
943
1145
  .app-tasks .sc-links a { display: inline-flex; align-items: center; gap: 0.45rem; }
944
1146
 
@@ -985,12 +1187,12 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
985
1187
  @media (max-width: 640px) { .pd-canvas .pd-columns:has(> .pd-zone) { grid-template-columns: minmax(0, 1fr); } }
986
1188
 
987
1189
  /* (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; }
1190
+ .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; }
1191
+ .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
1192
  .pd-menu [role=menuitem]:is(:hover, :focus-visible) { background: var(--sel-bg); color: var(--sel-text); outline: none; }
991
1193
  .pd-menu [role=menuitem].is-danger { color: var(--danger); }
992
1194
  .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); }
1195
+ .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
1196
  .pd-dialog::backdrop { background: rgb(0 0 0 / 0.35); }
995
1197
  .pd-dialog h2 { margin: 0 0 0.5rem; font-size: 1.05rem; }
996
1198
  .pd-dialog-buttons { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 1rem; }
@@ -1032,3 +1234,70 @@ details.prop-group-more[open] > summary { margin-bottom: 8px; }
1032
1234
 
1033
1235
  /* (sprint 90, PD-4) a commented-out component in the tree (APEX: Comment Out): struck through and muted */
1034
1236
  .pd-node[data-commented] .pd-label { text-decoration: line-through; color: var(--muted); }
1237
+
1238
+ /* (sprint 99, DA-13) Administration → Database Users */
1239
+ .dbu-stats { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0.6rem; }
1240
+ .dbu-stats a.stat { color: inherit; text-decoration: none; }
1241
+ .dbu-stats a.stat:hover, .dbu-stats a.stat:focus-visible { border-color: var(--accent); }
1242
+ .dbu-stats a.stat[aria-current="page"] { border-color: var(--accent); background: var(--accent-soft); }
1243
+ .dbu-search { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }
1244
+ .dbu-search input { flex: 1 1 12rem; max-width: 24rem; }
1245
+ .dbu-members { max-height: 16rem; overflow: auto; }
1246
+ .dbu-schemas .te-c { text-align: center; width: 1%; white-space: nowrap; }
1247
+ .dbu-sql { white-space: pre-wrap; overflow-wrap: anywhere; }
1248
+ .dbu-list td { white-space: normal; overflow: visible; max-width: 24rem; }
1249
+ .dbu-list td .tag { margin: 0.1rem 0; }
1250
+ .dbu-facts { display: grid; grid-template-columns: max-content 1fr; gap: 0.35rem 1rem; margin: 0; }
1251
+ .dbu-facts dt { color: var(--muted); }
1252
+ .dbu-facts dd { margin: 0; min-width: 0; }
1253
+ @media (max-width: 640px) {
1254
+ .dbu-facts { grid-template-columns: 1fr; } .dbu-facts dd { margin-bottom: 0.4rem; }
1255
+ .dbu-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } .dbu-stats a.stat { padding: 0.5rem 0.7rem; } .dbu-stats .stat b { font-size: 1.15rem; }
1256
+ }
1257
+ /* (sprint 100) RESTful Services: examples wrap instead of scrolling sideways */
1258
+ pre.wrap-pre { white-space: pre-wrap; overflow-wrap: anywhere; }
1259
+
1260
+ /* (sprint 103) SQL Workshop › Schema Export / Import */
1261
+ .dp-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 0.3rem 1rem; margin: 0 0 1rem; }
1262
+ .dp-facts dt { color: var(--muted); }
1263
+ .dp-facts dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
1264
+ .dp-tables { display: grid; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); gap: 0.2rem 1rem; margin: 0.5rem 0; }
1265
+ .dp-log { max-height: 32rem; }
1266
+ /* (sprint 101, DA-12) SQL Workshop › Scheduling */
1267
+ .cron-list td, .cron-runs-table td { overflow-wrap: anywhere; }
1268
+ .cron-cmd { display: inline-block; max-width: 40ch; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; }
1269
+ .cron-wide { grid-column: 1 / -1; }
1270
+ .cron-inline { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; }
1271
+ .cron-inline select { min-width: 0; max-width: 100%; flex: 1 1 12rem; }
1272
+ .cron-fields { border: 1px solid var(--border); border-radius: 6px; padding: 0.6rem 0.8rem; margin: 0.8rem 0; min-width: 0; }
1273
+ .cron-field-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); gap: 0.6rem; }
1274
+ .cron-field-grid input { width: 100%; font-family: var(--mono, monospace); }
1275
+ .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; }
1276
+ .cron-runs { margin: 0.25rem 0 0; padding-left: 1.4rem; font-variant-numeric: tabular-nums; }
1277
+ .cron-error { color: var(--danger, #b42318); }
1278
+ .cron-sql { white-space: pre-wrap; overflow-wrap: anywhere; }
1279
+ /* (sprint 102) SQL Monitor: refresh controls, session actions, bars in Top SQL */
1280
+ .sm-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-bottom: 0.75rem; }
1281
+ .sm-live.is-paused .sm-updated::after { content: " · paused"; }
1282
+ .sm-actions { display: flex; flex-wrap: wrap; gap: 0.25rem; }
1283
+ .sm-action { margin: 0; }
1284
+ .sm-sessions tr.is-blocked td { background: var(--warning-soft); }
1285
+ .sm-filter { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
1286
+ .sm-filter input[type=search] { flex: 1 1 12rem; min-width: 0; }
1287
+ .sm-top th a { color: inherit; text-decoration: none; white-space: nowrap; }
1288
+ .sm-top th[aria-sort] a { text-decoration: underline; }
1289
+ .sm-barcell { white-space: nowrap; }
1290
+ .sm-bar { display: inline-block; width: 4.5rem; height: 0.5rem; margin-right: 0.4rem; vertical-align: middle; }
1291
+ .sm-bar-track { fill: var(--border); }
1292
+ .sm-bar-fill { fill: var(--accent); }
1293
+ /* a statement's text is clipped to 1000 characters on the server: no scroll box inside the table */
1294
+ .sm-top .sql-text { max-height: none; overflow: visible; }
1295
+ .sm-sql { white-space: pre-wrap; overflow-wrap: anywhere; max-height: 20rem; overflow: auto; }
1296
+ @media (max-width: 640px) { .sm-bar { width: 3rem; } }
1297
+
1298
+ /* (sprint 104) SQL Workshop › RESTful Services › Modules: the module's tree beside the page */
1299
+ .rm-layout { display: grid; grid-template-columns: minmax(0, 17rem) minmax(0, 1fr); gap: 1rem; align-items: start; }
1300
+ .rm-layout > .region, .rm-main > .region { margin-top: 0; }
1301
+ .rm-main { display: grid; gap: 1rem; min-width: 0; }
1302
+ .rm-tree .tree code { font-size: 0.75rem; min-width: 3.4rem; }
1303
+ @media (max-width: 760px) { .rm-layout { grid-template-columns: minmax(0, 1fr); } }