|
|
|
|
@@ -9,10 +9,77 @@
|
|
|
|
|
|
|
|
|
|
@layer app {
|
|
|
|
|
|
|
|
|
|
/* ---------- Theme tokens ----------
|
|
|
|
|
Only the colours reused across several rules are variables here; the
|
|
|
|
|
rest of the file is still one-off hex per rule (see the file header for
|
|
|
|
|
why). Dark is the default — the inline script in ui/base.html puts
|
|
|
|
|
`dark` on <html> before first paint unless localStorage says "light" —
|
|
|
|
|
so :root itself carries the dark values and :root.light carries the
|
|
|
|
|
original light ones. Values line up with the Penguin UI dark palette in
|
|
|
|
|
ui/base.html's @theme block where a token overlaps with one of these. */
|
|
|
|
|
|
|
|
|
|
:root {
|
|
|
|
|
--bg: #f3f5f7;
|
|
|
|
|
--surface: #ffffff;
|
|
|
|
|
--surface-alt: #fafbfc;
|
|
|
|
|
--border: #d9dfe7;
|
|
|
|
|
--border-soft: #e4e7ec;
|
|
|
|
|
--text-strong: #17202a;
|
|
|
|
|
--text: #33415c;
|
|
|
|
|
--text-secondary: #24324a;
|
|
|
|
|
--text-muted: #7c8796;
|
|
|
|
|
--text-subtle: #667385;
|
|
|
|
|
--label: #465267;
|
|
|
|
|
--primary: #2563eb;
|
|
|
|
|
--primary-strong: #1d4ed8;
|
|
|
|
|
--danger: #a12b2b;
|
|
|
|
|
--danger-bg: #fdf3f3;
|
|
|
|
|
--danger-border: #eccfcf;
|
|
|
|
|
--success: #21643a;
|
|
|
|
|
--hover-bg: #e9edf4;
|
|
|
|
|
--secondary-bg: #f4f6fa;
|
|
|
|
|
--secondary-border: #c9d2de;
|
|
|
|
|
--select-border: #a9c7f6;
|
|
|
|
|
--input-bg: #ffffff;
|
|
|
|
|
--input-border: #cbd3dd;
|
|
|
|
|
--input-text: #1e2938;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Dark is the default — see the inline script in ui/base.html, which puts
|
|
|
|
|
this class on <html> before first paint unless localStorage says
|
|
|
|
|
"light". Values line up with the Penguin UI dark palette in
|
|
|
|
|
ui/base.html's @theme block where a token overlaps with one of these. */
|
|
|
|
|
:root.dark {
|
|
|
|
|
--bg: #0f1722;
|
|
|
|
|
--surface: #152238;
|
|
|
|
|
--surface-alt: #1b2a42;
|
|
|
|
|
--border: #33415a;
|
|
|
|
|
--border-soft: #26334c;
|
|
|
|
|
--text-strong: #f3f6fb;
|
|
|
|
|
--text: #c7d3e6;
|
|
|
|
|
--text-secondary: #b7c4da;
|
|
|
|
|
--text-muted: #8b9ab3;
|
|
|
|
|
--text-subtle: #7d8ca6;
|
|
|
|
|
--label: #aebbd0;
|
|
|
|
|
--primary: #68a4ff;
|
|
|
|
|
--primary-strong: #8fbfff;
|
|
|
|
|
--danger: #e5837e;
|
|
|
|
|
--danger-bg: #3a2224;
|
|
|
|
|
--danger-border: #5c3236;
|
|
|
|
|
--success: #6cbf8c;
|
|
|
|
|
--hover-bg: #223049;
|
|
|
|
|
--secondary-bg: #1a2740;
|
|
|
|
|
--secondary-border: #3a4a68;
|
|
|
|
|
--select-border: #4a6da3;
|
|
|
|
|
--input-bg: #101a29;
|
|
|
|
|
--input-border: #33415a;
|
|
|
|
|
--input-text: #e5ebf3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ---------- Foundations ---------- */
|
|
|
|
|
|
|
|
|
|
* { box-sizing: border-box; }
|
|
|
|
|
:root { color: #17202a; background: #f3f5f7; font: 14px/1.45 Inter, ui-sans-serif, system-ui, sans-serif; }
|
|
|
|
|
:root { color: var(--text-strong); background: var(--bg); font: 14px/1.45 Inter, ui-sans-serif, system-ui, sans-serif; }
|
|
|
|
|
body { margin: 0; }
|
|
|
|
|
[x-cloak] { display: none !important; }
|
|
|
|
|
/* Penguin UI's toast component file (included by ui/base.html) opens with the
|
|
|
|
|
@@ -21,7 +88,7 @@
|
|
|
|
|
own trigger is the dispatch in ui/toast.html. */
|
|
|
|
|
.penguin-toast > button { display: none; }
|
|
|
|
|
button, input, select, textarea { font: inherit; }
|
|
|
|
|
select, input, textarea { width: 100%; padding: 9px 10px; border: 1px solid #cbd3dd; border-radius: 6px; color: #1e2938; background: white; }
|
|
|
|
|
select, input, textarea { width: 100%; padding: 9px 10px; border: 1px solid var(--input-border); border-radius: 6px; color: var(--input-text); background: var(--input-bg); }
|
|
|
|
|
textarea { resize: vertical; font: 13px/1.5 ui-monospace, monospace; }
|
|
|
|
|
main { width: min(1500px, calc(100% - 40px)); margin: 34px auto; }
|
|
|
|
|
|
|
|
|
|
@@ -35,58 +102,58 @@
|
|
|
|
|
.heading { display: flex; justify-content: space-between; align-items: end; gap: 24px; margin-bottom: 22px; }
|
|
|
|
|
.heading h1 { margin: 0; font-size: 28px; }
|
|
|
|
|
.heading p { margin: 5px 0 0; color: #687384; }
|
|
|
|
|
.eyebrow { color: #2563eb !important; font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; }
|
|
|
|
|
.eyebrow { color: var(--primary) !important; font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; }
|
|
|
|
|
.actions { display: flex; flex-wrap: wrap; gap: 8px; }
|
|
|
|
|
.actions a, .actions span { padding: 8px 12px; border: 1px solid #cfd7e1; border-radius: 7px; color: #283548; background: white; text-decoration: none; }
|
|
|
|
|
.actions a, .actions span { padding: 8px 12px; border: 1px solid #cfd7e1; border-radius: 7px; color: #283548; background: var(--surface); text-decoration: none; }
|
|
|
|
|
|
|
|
|
|
/* ---------- Admin three-pane browser ---------- */
|
|
|
|
|
|
|
|
|
|
.workspace { display: grid; grid-template-columns: minmax(210px, .75fr) minmax(280px, 1.15fr) minmax(300px, 1.25fr); min-height: 560px; border: 1px solid #d9dfe7; border-radius: 11px; overflow: hidden; background: white; box-shadow: 0 10px 26px rgb(31 43 58 / 7%); }
|
|
|
|
|
.workspace { display: grid; grid-template-columns: minmax(210px, .75fr) minmax(280px, 1.15fr) minmax(300px, 1.25fr); min-height: 560px; border: 1px solid var(--border); border-radius: 11px; overflow: hidden; background: var(--surface); box-shadow: 0 10px 26px rgb(31 43 58 / 7%); }
|
|
|
|
|
.pane + .pane { border-left: 1px solid #e1e5eb; }
|
|
|
|
|
.pane-title { height: 54px; padding: 0 17px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #e5e8ed; background: #fafbfc; }
|
|
|
|
|
.pane-title { height: 54px; padding: 0 17px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #e5e8ed; background: var(--surface-alt); }
|
|
|
|
|
.pane-title h2 { margin: 0; font-size: 14px; }
|
|
|
|
|
.pane-title span { color: #7c8796; font-size: 12px; }
|
|
|
|
|
.pane-title span { color: var(--text-muted); font-size: 12px; }
|
|
|
|
|
.pane-list { padding: 10px; }
|
|
|
|
|
.pane-list form { margin: 0; }
|
|
|
|
|
.browser-item { width: 100%; display: grid; gap: 3px; padding: 11px 12px; text-align: left; border: 1px solid transparent; border-radius: 7px; color: #253246; background: transparent; cursor: pointer; }
|
|
|
|
|
.browser-item:hover { background: #f2f6fc; }
|
|
|
|
|
.browser-item.selected { border-color: #a9c7f6; background: #eaf2ff; }
|
|
|
|
|
.browser-item.selected { border-color: var(--select-border); background: #eaf2ff; }
|
|
|
|
|
.browser-item small, .column small { color: #788495; }
|
|
|
|
|
.column { display: grid; grid-template-columns: minmax(100px, 1fr) auto; gap: 3px 12px; padding: 10px 11px; border-bottom: 1px solid #edf0f3; }
|
|
|
|
|
.column code { color: #315078; font-size: 12px; }
|
|
|
|
|
.column small { grid-column: 1 / -1; }
|
|
|
|
|
.column.system { color: #6b7686; background: #fafbfc; }
|
|
|
|
|
.column.system { color: #6b7686; background: var(--surface-alt); }
|
|
|
|
|
.column.system code { color: #67788e; }
|
|
|
|
|
.group-label { margin: 14px 0 4px; padding: 0 11px; color: #7c8796; font-size: 11px; letter-spacing: .04em; text-transform: uppercase; }
|
|
|
|
|
.group-label { margin: 14px 0 4px; padding: 0 11px; color: var(--text-muted); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; }
|
|
|
|
|
|
|
|
|
|
/* What can be done to whatever the pane is pointed at, rendered directly
|
|
|
|
|
under it: under the selected table, and under the tables list for the
|
|
|
|
|
profile-wide actions. Each link is a page of its own. */
|
|
|
|
|
.browser-actions { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 12px 12px; }
|
|
|
|
|
.browser-actions a { padding: 6px 12px; border: 1px solid #a9c7f6; border-radius: 7px; color: #1d4ed8; background: #eaf2ff; font-size: 13px; font-weight: 600; text-decoration: none; }
|
|
|
|
|
.browser-actions a { padding: 6px 12px; border: 1px solid var(--select-border); border-radius: 7px; color: #1d4ed8; background: #eaf2ff; font-size: 13px; font-weight: 600; text-decoration: none; }
|
|
|
|
|
.browser-actions a:hover { background: #d8e8ff; }
|
|
|
|
|
.browser-actions a.danger-action { border-color: #eccfcf; color: #a12b2b; background: #fdf3f3; }
|
|
|
|
|
.browser-actions a.danger-action { border-color: var(--danger-border); color: var(--danger); background: var(--danger-bg); }
|
|
|
|
|
.browser-actions a.danger-action:hover { background: #fbe6e6; }
|
|
|
|
|
.pane-footer { margin: 0 10px 10px; border-top: 1px solid #e5e8ed; padding-top: 12px; }
|
|
|
|
|
.pane-footer a { border-color: #d9dfe7; color: #33415c; background: white; font-weight: 500; }
|
|
|
|
|
.pane-footer a { border-color: var(--border); color: var(--text); background: var(--surface); font-weight: 500; }
|
|
|
|
|
.pane-footer a:hover { background: #f2f6fc; }
|
|
|
|
|
.empty { margin: 8px; color: #7c8796; }
|
|
|
|
|
.empty { margin: 8px; color: var(--text-muted); }
|
|
|
|
|
|
|
|
|
|
/* ---------- Forms (components/form_card.html) ---------- */
|
|
|
|
|
|
|
|
|
|
.form-main { width: min(900px, calc(100% - 32px)); }
|
|
|
|
|
.back-link { display: inline-block; margin-bottom: 14px; color: #315f9d; text-decoration: none; }
|
|
|
|
|
.form-card { padding: 25px; border: 1px solid #d9dfe7; border-radius: 11px; background: white; box-shadow: 0 10px 26px rgb(31 43 58 / 7%); }
|
|
|
|
|
.form-card { padding: 25px; border: 1px solid var(--border); border-radius: 11px; background: var(--surface); box-shadow: 0 10px 26px rgb(31 43 58 / 7%); }
|
|
|
|
|
.form-card h1 { margin: 0; }
|
|
|
|
|
.form-card > p { color: #687384; }
|
|
|
|
|
.form-grid { margin-top: 22px; display: grid; grid-template-columns: 1fr 1fr; gap: 17px; }
|
|
|
|
|
.form-grid label { display: grid; align-content: start; gap: 6px; color: #465267; font-size: 12px; }
|
|
|
|
|
.form-grid label { display: grid; align-content: start; gap: 6px; color: var(--label); font-size: 12px; }
|
|
|
|
|
.form-grid label.wide { grid-column: 1 / -1; }
|
|
|
|
|
.form-grid small { color: #7c8796; }
|
|
|
|
|
.form-grid small { color: var(--text-muted); }
|
|
|
|
|
/* Where a field would be, when the answer is the server's rather than the
|
|
|
|
|
user's — a link's index, which the server always makes. It sits in the
|
|
|
|
|
grid like the label it replaces. */
|
|
|
|
|
.form-grid .field-note { display: grid; align-content: start; gap: 6px; color: #465267; font-size: 12px; }
|
|
|
|
|
.form-grid .field-note { display: grid; align-content: start; gap: 6px; color: var(--label); font-size: 12px; }
|
|
|
|
|
.form-grid .field-note p { margin: 0; }
|
|
|
|
|
.form-actions { margin-top: 20px; display: flex; justify-content: end; align-items: center; gap: 14px; }
|
|
|
|
|
.form-actions a { color: #59677a; }
|
|
|
|
|
@@ -102,65 +169,65 @@
|
|
|
|
|
use. */
|
|
|
|
|
.error { color: #b42318; }
|
|
|
|
|
.success { color: #067647; }
|
|
|
|
|
.hint, .result-meta { color: #667385; }
|
|
|
|
|
.error-page { width: min(600px, calc(100% - 32px)); margin: 15vh auto; padding: 24px; border: 1px solid #f1c4c0; border-radius: 10px; background: white; }
|
|
|
|
|
.hint, .result-meta { color: var(--text-subtle); }
|
|
|
|
|
.error-page { width: min(600px, calc(100% - 32px)); margin: 15vh auto; padding: 24px; border: 1px solid #f1c4c0; border-radius: 10px; background: var(--surface); }
|
|
|
|
|
.error-page h1 { margin-top: 0; }
|
|
|
|
|
.error-page p { color: #a33a31; }
|
|
|
|
|
|
|
|
|
|
/* ---------- Login and register (pages/login, pages/register) ---------- */
|
|
|
|
|
|
|
|
|
|
.login-main { width: min(420px, calc(100% - 32px)); margin: 12vh auto; }
|
|
|
|
|
.login-card { padding: 25px; border: 1px solid #d9dfe7; border-radius: 11px; background: white; box-shadow: 0 10px 26px rgb(31 43 58 / 7%); }
|
|
|
|
|
.login-card { padding: 25px; border: 1px solid var(--border); border-radius: 11px; background: var(--surface); box-shadow: 0 10px 26px rgb(31 43 58 / 7%); }
|
|
|
|
|
.login-card h1 { margin: 0 0 18px; font-size: 24px; }
|
|
|
|
|
.login-card label { display: grid; gap: 5px; margin-bottom: 14px; color: #465267; font-size: 12px; }
|
|
|
|
|
.login-card label { display: grid; gap: 5px; margin-bottom: 14px; color: var(--label); font-size: 12px; }
|
|
|
|
|
.login-card button { width: 100%; border: 0; border-radius: 6px; padding: 10px 18px; color: white; background: #2563eb; cursor: pointer; }
|
|
|
|
|
.login-card button:disabled, .login-card button.htmx-request { opacity: .55; cursor: wait; }
|
|
|
|
|
.login-alt { margin: 14px 0 0; color: #667385; font-size: 12px; text-align: center; }
|
|
|
|
|
.login-alt { margin: 14px 0 0; color: var(--text-subtle); font-size: 12px; text-align: center; }
|
|
|
|
|
|
|
|
|
|
/* ---------- Analytics (pages/analytics.html) ---------- */
|
|
|
|
|
|
|
|
|
|
.analytics { display: grid; grid-template-columns: minmax(290px, 380px) minmax(0, 1fr); align-items: start; gap: 16px; }
|
|
|
|
|
.panel { margin-bottom: 16px; padding: 18px; border: 1px solid #dfe4ea; border-radius: 10px; background: white; }
|
|
|
|
|
.panel { margin-bottom: 16px; padding: 18px; border: 1px solid #dfe4ea; border-radius: 10px; background: var(--surface); }
|
|
|
|
|
.panel h2 { margin: 0 0 14px; font-size: 17px; }
|
|
|
|
|
.sidebar { position: sticky; top: 16px; max-height: calc(100vh - 32px); overflow: auto; }
|
|
|
|
|
.sidebar h2 { margin-bottom: 6px; }
|
|
|
|
|
.catalog-load { display: grid; grid-template-columns: 1fr auto; align-items: end; gap: 8px; margin: 14px 0; }
|
|
|
|
|
.catalog-load label { margin: 0; }
|
|
|
|
|
.schema-summary { margin: 8px 0; }
|
|
|
|
|
.catalog-table { border-top: 1px solid #e4e7ec; padding: 9px 0; }
|
|
|
|
|
.catalog-table { border-top: 1px solid var(--border-soft); padding: 9px 0; }
|
|
|
|
|
.catalog-table summary { display: flex; align-items: center; gap: 8px; cursor: pointer; }
|
|
|
|
|
.currency { color: #667385; font-size: 11px; }
|
|
|
|
|
.currency { color: var(--text-subtle); font-size: 11px; }
|
|
|
|
|
.starter-query, .secondary { margin-top: 9px; padding: 6px 9px; width: auto; border: 0; border-radius: 6px; color: #344054; background: #eef2f6; cursor: pointer; }
|
|
|
|
|
.columns, .links ul { margin: 8px 0; padding: 0; list-style: none; }
|
|
|
|
|
.columns li { display: flex; justify-content: space-between; gap: 8px; padding: 3px 0; }
|
|
|
|
|
.columns li span { color: #667385; font-size: 11px; text-align: right; }
|
|
|
|
|
.column-name { width: auto; padding: 0; border: 0; color: #2563eb; background: none; font-family: ui-monospace, monospace; text-align: left; cursor: pointer; }
|
|
|
|
|
.links { color: #667385; font-size: 12px; }
|
|
|
|
|
.columns li span { color: var(--text-subtle); font-size: 11px; text-align: right; }
|
|
|
|
|
.column-name { width: auto; padding: 0; border: 0; color: var(--primary); background: none; font-family: ui-monospace, monospace; text-align: left; cursor: pointer; }
|
|
|
|
|
.links { color: var(--text-subtle); font-size: 12px; }
|
|
|
|
|
.links li { padding: 2px 0; }
|
|
|
|
|
.llm-context { border-top: 1px solid #e4e7ec; margin-top: 10px; padding-top: 10px; }
|
|
|
|
|
.llm-context { border-top: 1px solid var(--border-soft); margin-top: 10px; padding-top: 10px; }
|
|
|
|
|
.llm-context summary { cursor: pointer; font-weight: 600; }
|
|
|
|
|
.llm-context textarea { min-height: 320px; margin-top: 8px; font-size: 11px; }
|
|
|
|
|
.query-row { display: grid; grid-template-columns: 180px 120px; gap: 12px; margin-bottom: 12px; }
|
|
|
|
|
.query-form label { display: grid; gap: 5px; color: #465267; font-size: 12px; }
|
|
|
|
|
.query-form label { display: grid; gap: 5px; color: var(--label); font-size: 12px; }
|
|
|
|
|
.query-form textarea { min-height: 130px; }
|
|
|
|
|
.query-form .actions { margin-top: 12px; align-items: center; gap: 12px; }
|
|
|
|
|
.query-form button { border: 0; border-radius: 6px; padding: 10px 18px; width: auto; color: white; background: #2563eb; cursor: pointer; }
|
|
|
|
|
.query-form button:disabled, .htmx-request button, button.htmx-request { opacity: .55; cursor: wait; }
|
|
|
|
|
.chart { height: 560px; }
|
|
|
|
|
.table-wrap { max-height: 560px; overflow: auto; }
|
|
|
|
|
table { width: 100%; border-collapse: collapse; background: white; }
|
|
|
|
|
th, td { padding: 9px 11px; border: 1px solid #e4e7ec; text-align: left; white-space: nowrap; }
|
|
|
|
|
table { width: 100%; border-collapse: collapse; background: var(--surface); }
|
|
|
|
|
th, td { padding: 9px 11px; border: 1px solid var(--border-soft); text-align: left; white-space: nowrap; }
|
|
|
|
|
th { position: sticky; top: 0; background: #f9fafb; }
|
|
|
|
|
|
|
|
|
|
/* ---------- Table builder (Add table) ---------- */
|
|
|
|
|
|
|
|
|
|
.builder-section { margin-top: 26px; padding-top: 20px; border-top: 1px solid #e8ebf0; }
|
|
|
|
|
.builder-section:first-of-type { margin-top: 0; padding-top: 0; border-top: 0; }
|
|
|
|
|
.builder-section h2 { margin: 0; font-size: 15px; color: #33415c; }
|
|
|
|
|
.builder-section h2 { margin: 0; font-size: 15px; color: var(--text); }
|
|
|
|
|
.builder-section > .hint { margin: 8px 0 0; font-size: 13px; }
|
|
|
|
|
.builder-section .count { margin-left: 6px; padding: 1px 7px; border-radius: 9px; font-size: 12px; color: #4b5563; background: #eef1f6; }
|
|
|
|
|
.builder-section > button.secondary { margin-top: 16px; padding: 9px 16px; border: 1px solid #c9d2de; border-radius: 6px; color: #24324a; background: #f4f6fa; cursor: pointer; }
|
|
|
|
|
.builder-section > button.secondary:hover { background: #e9edf4; }
|
|
|
|
|
.builder-section > button.secondary { margin-top: 16px; padding: 9px 16px; border: 1px solid var(--secondary-border); border-radius: 6px; color: var(--text-secondary); background: var(--secondary-bg); cursor: pointer; }
|
|
|
|
|
.builder-section > button.secondary:hover { background: var(--hover-bg); }
|
|
|
|
|
|
|
|
|
|
.builder-table { margin-top: 14px; }
|
|
|
|
|
.builder-table th { position: static; font-size: 12px; color: #5b6678; }
|
|
|
|
|
@@ -180,30 +247,30 @@
|
|
|
|
|
|
|
|
|
|
/* What a compound choice will add, shown before it is added. */
|
|
|
|
|
.compound-note { margin-top: 14px; padding: 12px 14px; border: 1px solid #dfe6f3; border-radius: 8px; background: #f7f9fe; }
|
|
|
|
|
.compound-note p { margin: 0; font-size: 13px; color: #33415c; }
|
|
|
|
|
.compound-note p { margin: 0; font-size: 13px; color: var(--text); }
|
|
|
|
|
.compound-note ul { margin: 8px 0; padding-left: 18px; font-size: 13px; }
|
|
|
|
|
.compound-note li { padding: 1px 0; }
|
|
|
|
|
.compound-note .hint { font-size: 12px; }
|
|
|
|
|
|
|
|
|
|
/* Renaming what a compound row generates: closed by default, because the
|
|
|
|
|
backend's names are the answer most tables keep. */
|
|
|
|
|
.rename-generated > summary { font-size: 15px; color: #33415c; cursor: pointer; }
|
|
|
|
|
.rename-generated > summary { font-size: 15px; color: var(--text); cursor: pointer; }
|
|
|
|
|
.rename-generated > summary::marker { color: #8a94a6; }
|
|
|
|
|
.rename-generated > .hint { margin: 8px 0 0; font-size: 13px; }
|
|
|
|
|
.rename-list { margin: 12px 0 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 8px; }
|
|
|
|
|
.rename-list li { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border: 1px solid #e1e6ee; border-radius: 7px; background: white; }
|
|
|
|
|
.rename-list li { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border: 1px solid #e1e6ee; border-radius: 7px; background: var(--surface); }
|
|
|
|
|
.rename-list li > code { flex: none; }
|
|
|
|
|
.rename-list li > .hint { flex: none; font-size: 12px; }
|
|
|
|
|
.rename-list input { flex: 1; min-width: 90px; }
|
|
|
|
|
|
|
|
|
|
.builder-list { margin: 12px 0 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 8px; }
|
|
|
|
|
.builder-list li { display: flex; align-items: center; gap: 8px; padding: 5px 10px; border: 1px solid #e1e6ee; border-radius: 7px; background: white; }
|
|
|
|
|
.builder-list li { display: flex; align-items: center; gap: 8px; padding: 5px 10px; border: 1px solid #e1e6ee; border-radius: 7px; background: var(--surface); }
|
|
|
|
|
|
|
|
|
|
button.toggle { min-width: 34px; padding: 3px 7px; border: 1px solid #cdd5e0; border-radius: 5px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: #24324a; background: #f6f8fb; cursor: pointer; }
|
|
|
|
|
button.toggle:hover { background: #e9edf4; }
|
|
|
|
|
button.toggle { min-width: 34px; padding: 3px 7px; border: 1px solid #cdd5e0; border-radius: 5px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--text-secondary); background: #f6f8fb; cursor: pointer; }
|
|
|
|
|
button.toggle:hover { background: var(--hover-bg); }
|
|
|
|
|
button.toggle.mode-optional { color: #1d4ed8; border-color: #bfd0f5; background: #eef3fe; }
|
|
|
|
|
button.toggle.mode-required { color: #a1410a; border-color: #f0cfae; background: #fdf3e9; }
|
|
|
|
|
button.danger { padding: 4px 10px; border: 1px solid #eccfcf; border-radius: 5px; font-size: 12px; color: #a12b2b; background: #fdf3f3; cursor: pointer; }
|
|
|
|
|
button.danger { padding: 4px 10px; border: 1px solid var(--danger-border); border-radius: 5px; font-size: 12px; color: var(--danger); background: var(--danger-bg); cursor: pointer; }
|
|
|
|
|
button.danger:hover { background: #f8e5e5; }
|
|
|
|
|
|
|
|
|
|
.tag { display: inline-block; padding: 1px 7px; border-radius: 9px; font-size: 11px; color: #4b5563; background: #eef1f6; }
|
|
|
|
|
@@ -213,51 +280,51 @@
|
|
|
|
|
|
|
|
|
|
/* Each operation is a .panel of its own, stacked; the deleting one is the
|
|
|
|
|
only place on the site that drops data, so it is coloured like it. */
|
|
|
|
|
.panel-subhead { margin: 22px 0 0; font-size: 13px; color: #33415c; }
|
|
|
|
|
.panel-subhead { margin: 22px 0 0; font-size: 13px; color: var(--text); }
|
|
|
|
|
.panel-actions { margin-top: 16px; }
|
|
|
|
|
.panel .form-grid { margin-top: 14px; }
|
|
|
|
|
.panel .form-actions { margin-top: 16px; }
|
|
|
|
|
.panel .count { margin-left: 6px; padding: 1px 7px; border-radius: 9px; font-size: 12px; color: #4b5563; background: #eef1f6; }
|
|
|
|
|
.panel > button.secondary { margin-top: 16px; padding: 9px 16px; border: 1px solid #c9d2de; border-radius: 6px; color: #24324a; background: #f4f6fa; cursor: pointer; }
|
|
|
|
|
.panel > button.secondary:hover { background: #e9edf4; }
|
|
|
|
|
.panel > button.secondary { margin-top: 16px; padding: 9px 16px; border: 1px solid var(--secondary-border); border-radius: 6px; color: var(--text-secondary); background: var(--secondary-bg); cursor: pointer; }
|
|
|
|
|
.panel > button.secondary:hover { background: var(--hover-bg); }
|
|
|
|
|
.presentation-layout { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(320px, .9fr); align-items: start; gap: 16px; }
|
|
|
|
|
.presentation-panel > .hint { min-height: 40px; margin: -7px 0 15px; }
|
|
|
|
|
.alias-list { overflow: hidden; border: 1px solid #e2e7ee; border-radius: 8px; background: white; }
|
|
|
|
|
.alias-list { overflow: hidden; border: 1px solid #e2e7ee; border-radius: 8px; background: var(--surface); }
|
|
|
|
|
.alias-list-head, .alias-row { display: grid; grid-template-columns: minmax(90px, .8fr) 20px minmax(120px, 1.2fr) auto; align-items: center; gap: 8px; }
|
|
|
|
|
.alias-list-head { padding: 8px 10px 6px; color: #7b8797; background: #f7f9fb; font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
|
|
|
|
|
.alias-row { margin: 0; padding: 8px 10px; border-top: 1px solid #e8ecf1; }
|
|
|
|
|
.alias-current { min-width: 0; overflow: hidden; color: #33415c; font-size: 13px; text-overflow: ellipsis; }
|
|
|
|
|
.alias-current { min-width: 0; overflow: hidden; color: var(--text); font-size: 13px; text-overflow: ellipsis; }
|
|
|
|
|
.alias-arrow { color: #9aa5b4; text-align: center; }
|
|
|
|
|
.alias-row > input { min-width: 0; color: #24324a; font-size: 13px; font-weight: 500; }
|
|
|
|
|
.alias-row > input { min-width: 0; color: var(--text-secondary); font-size: 13px; font-weight: 500; }
|
|
|
|
|
.alias-row > input:focus { border-color: #6ea1ed; outline: 3px solid rgb(37 99 235 / 12%); }
|
|
|
|
|
.alias-row > button { padding: 9px 14px; border: 1px solid #b9cdf0; border-radius: 6px; color: #1d4ed8; background: #eef4ff; font-weight: 600; cursor: pointer; }
|
|
|
|
|
.alias-row > button:hover { border-color: #8eb1eb; background: #deebff; }
|
|
|
|
|
.alias-row > button:focus-visible { outline: 3px solid rgb(37 99 235 / 18%); outline-offset: 2px; }
|
|
|
|
|
.alias-row-locked { background: #fafbfc; }
|
|
|
|
|
.alias-row-locked { background: var(--surface-alt); }
|
|
|
|
|
.alias-row-locked .locked-label { grid-column: 3 / -1; }
|
|
|
|
|
.locked-label { color: #8a94a4; font-size: 12px; }
|
|
|
|
|
.column-order { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
|
|
|
|
|
.column-order li { display: grid; grid-template-columns: 32px 30px minmax(0, 1fr); align-items: center; gap: 8px; min-height: 52px; padding: 8px 12px 8px 8px; border: 1px solid #e2e7ee; border-radius: 8px; background: #fafbfc; transition: border-color 120ms ease, box-shadow 120ms ease, transform 120ms ease, opacity 120ms ease; }
|
|
|
|
|
.column-order li { display: grid; grid-template-columns: 32px 30px minmax(0, 1fr); align-items: center; gap: 8px; min-height: 52px; padding: 8px 12px 8px 8px; border: 1px solid #e2e7ee; border-radius: 8px; background: var(--surface-alt); transition: border-color 120ms ease, box-shadow 120ms ease, transform 120ms ease, opacity 120ms ease; }
|
|
|
|
|
.column-order li:hover { border-color: #b8cae3; box-shadow: 0 3px 10px rgb(31 43 58 / 7%); }
|
|
|
|
|
.column-order li.is-dragging { z-index: 1; border-color: #7fa5df; box-shadow: 0 9px 22px rgb(31 43 58 / 18%); opacity: .82; transform: scale(1.015); }
|
|
|
|
|
.drag-handle { display: grid; place-items: center; width: 32px; height: 34px; padding: 0; border: 0; border-radius: 6px; color: #8b97a8; background: transparent; font-size: 22px; line-height: 1; cursor: grab; touch-action: none; user-select: none; }
|
|
|
|
|
.drag-handle:hover { color: #315f9d; background: #e9f0fb; }
|
|
|
|
|
.drag-handle:focus-visible { color: #1d4ed8; outline: 3px solid rgb(37 99 235 / 18%); }
|
|
|
|
|
.drag-handle:focus-visible { color: var(--primary-strong); outline: 3px solid rgb(37 99 235 / 18%); }
|
|
|
|
|
.drag-handle:active { cursor: grabbing; }
|
|
|
|
|
.order-position { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; color: #64748b; background: #e9eef5; font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; }
|
|
|
|
|
.order-name { min-width: 0; overflow: hidden; color: #33415c; font-size: 13px; text-overflow: ellipsis; }
|
|
|
|
|
.order-name { min-width: 0; overflow: hidden; color: var(--text); font-size: 13px; text-overflow: ellipsis; }
|
|
|
|
|
.order-actions { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 8px; margin-top: 14px; padding-top: 14px; border-top: 1px solid #e5e9ef; }
|
|
|
|
|
.order-status { color: #788495; font-size: 12px; }
|
|
|
|
|
.order-editor.is-dirty .order-status { color: #9a5a08; font-weight: 600; }
|
|
|
|
|
.order-actions button { margin: 0; padding: 8px 13px; border: 0; border-radius: 6px; color: white; background: #2563eb; font-weight: 600; cursor: pointer; }
|
|
|
|
|
.order-actions button.secondary { border: 1px solid #c9d2de; color: #344054; background: white; }
|
|
|
|
|
.order-actions button.secondary { border: 1px solid var(--secondary-border); color: #344054; background: var(--surface); }
|
|
|
|
|
.order-actions button:hover:not(:disabled) { background: #1d4ed8; }
|
|
|
|
|
.order-actions button.secondary:hover:not(:disabled) { background: #eef2f6; }
|
|
|
|
|
.order-actions button:focus-visible { outline: 3px solid rgb(37 99 235 / 18%); outline-offset: 2px; }
|
|
|
|
|
.order-actions button:disabled { border-color: #e1e6ed; color: #adb6c3; background: #f3f5f7; cursor: default; }
|
|
|
|
|
.sql-preview { margin: 12px 0 0; padding: 12px; max-height: 260px; overflow: auto; border: 1px solid #e4e7ec; border-radius: 8px; font: 12px/1.5 ui-monospace, monospace; color: #33415c; background: #fafbfc; white-space: pre-wrap; }
|
|
|
|
|
.danger-panel { border-color: #eccfcf; }
|
|
|
|
|
.danger-panel h2 { color: #a12b2b; }
|
|
|
|
|
.sql-preview { margin: 12px 0 0; padding: 12px; max-height: 260px; overflow: auto; border: 1px solid var(--border-soft); border-radius: 8px; font: 12px/1.5 ui-monospace, monospace; color: var(--text); background: var(--surface-alt); white-space: pre-wrap; }
|
|
|
|
|
.danger-panel { border-color: var(--danger-border); }
|
|
|
|
|
.danger-panel h2 { color: var(--danger); }
|
|
|
|
|
.form-actions button.danger-submit { background: #a12b2b; }
|
|
|
|
|
|
|
|
|
|
/* ---------- Permissions (pages/permissions) ---------- */
|
|
|
|
|
@@ -268,11 +335,11 @@
|
|
|
|
|
Both split one crowded screen into a page per decision, so both need the
|
|
|
|
|
same thing — a way back to the siblings. */
|
|
|
|
|
.tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
|
|
|
|
|
.tab { display: grid; gap: 2px; padding: 10px 16px; border: 1px solid #d9dfe7; border-radius: 9px; color: #33415c; background: white; text-decoration: none; }
|
|
|
|
|
.tab small { color: #7c8796; font-size: 11px; }
|
|
|
|
|
.tab { display: grid; gap: 2px; padding: 10px 16px; border: 1px solid var(--border); border-radius: 9px; color: var(--text); background: var(--surface); text-decoration: none; }
|
|
|
|
|
.tab small { color: var(--text-muted); font-size: 11px; }
|
|
|
|
|
.tab:hover { background: #f2f6fc; }
|
|
|
|
|
.tab.selected { border-color: #a9c7f6; background: #eaf2ff; }
|
|
|
|
|
.tab.selected span { font-weight: 700; color: #1d4ed8; }
|
|
|
|
|
.tab.selected { border-color: var(--select-border); background: #eaf2ff; }
|
|
|
|
|
.tab.selected span { font-weight: 700; color: var(--primary-strong); }
|
|
|
|
|
|
|
|
|
|
/* ---------- Exchange rates (pages/admin/ecb) ---------- */
|
|
|
|
|
|
|
|
|
|
@@ -280,17 +347,17 @@
|
|
|
|
|
amount be posted right now", so it is the one thing on the page that has
|
|
|
|
|
to be readable without reading. */
|
|
|
|
|
.status-card { border-left-width: 4px; }
|
|
|
|
|
.status-card.healthy { border-left-color: #21643a; }
|
|
|
|
|
.status-card.unhealthy { border-left-color: #a12b2b; }
|
|
|
|
|
.status-card.unhealthy h2 { color: #a12b2b; }
|
|
|
|
|
.status-card.healthy { border-left-color: var(--success); }
|
|
|
|
|
.status-card.unhealthy { border-left-color: var(--danger); }
|
|
|
|
|
.status-card.unhealthy h2 { color: var(--danger); }
|
|
|
|
|
/* The postable limits. This is what the reader came for -- coverage dates
|
|
|
|
|
are the mechanism behind it -- so it sits directly under the headline and
|
|
|
|
|
is the only thing on the card set at reading size. */
|
|
|
|
|
.postable { margin-top: 16px; padding: 14px; border: 1px solid #dfe4ea; border-radius: 8px; background: white; }
|
|
|
|
|
.postable-lead { margin: 0 0 10px; color: #7c8796; font-size: 11px; letter-spacing: .04em; text-transform: uppercase; }
|
|
|
|
|
.postable { margin-top: 16px; padding: 14px; border: 1px solid #dfe4ea; border-radius: 8px; background: var(--surface); }
|
|
|
|
|
.postable-lead { margin: 0 0 10px; color: var(--text-muted); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; }
|
|
|
|
|
.postable-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; margin: 0 0 10px; }
|
|
|
|
|
.postable-grid dt { color: #33415c; font-size: 13px; font-weight: 600; }
|
|
|
|
|
.postable-grid dd { margin: 3px 0 0; color: #17202a; font-size: 14px; }
|
|
|
|
|
.postable-grid dt { color: var(--text); font-size: 13px; font-weight: 600; }
|
|
|
|
|
.postable-grid dd { margin: 3px 0 0; color: var(--text-strong); font-size: 14px; }
|
|
|
|
|
.postable-grid dd strong { font-size: 16px; font-variant-numeric: tabular-nums; }
|
|
|
|
|
.postable-grid dd.hint { font-size: 12px; }
|
|
|
|
|
|
|
|
|
|
@@ -298,16 +365,16 @@
|
|
|
|
|
the two dates are compared rather than looked up one at a time. */
|
|
|
|
|
.coverage { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 16px; padding: 12px 14px; border-radius: 8px; background: #f7f9fc; }
|
|
|
|
|
.coverage-point { display: flex; flex-direction: column; gap: 2px; }
|
|
|
|
|
.coverage-label { color: #7c8796; font-size: 11px; letter-spacing: .04em; text-transform: uppercase; }
|
|
|
|
|
.coverage-date { color: #17202a; font-size: 20px; font-variant-numeric: tabular-nums; }
|
|
|
|
|
.coverage-label { color: var(--text-muted); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; }
|
|
|
|
|
.coverage-date { color: var(--text-strong); font-size: 20px; font-variant-numeric: tabular-nums; }
|
|
|
|
|
.coverage-gap { flex: 1; text-align: center; }
|
|
|
|
|
.status-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; margin: 16px 0 0; }
|
|
|
|
|
.status-grid dt { color: #7c8796; font-size: 11px; letter-spacing: .04em; text-transform: uppercase; }
|
|
|
|
|
.status-grid dd { margin: 3px 0 0; color: #17202a; font-size: 15px; font-variant-numeric: tabular-nums; }
|
|
|
|
|
.status-grid dt { color: var(--text-muted); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; }
|
|
|
|
|
.status-grid dd { margin: 3px 0 0; color: var(--text-strong); font-size: 15px; font-variant-numeric: tabular-nums; }
|
|
|
|
|
.currency-list { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 14px; }
|
|
|
|
|
.failure-note { margin-top: 14px; padding-top: 12px; border-top: 1px solid #edf0f3; }
|
|
|
|
|
.tag-ok { color: #21643a; background: #f2f9f3; border-color: #cfe0c4; }
|
|
|
|
|
.tag-bad { color: #a12b2b; background: #fdf3f3; border-color: #eccfcf; }
|
|
|
|
|
.tag-ok { color: var(--success); background: #f2f9f3; border-color: #cfe0c4; }
|
|
|
|
|
.tag-bad { color: var(--danger); background: var(--danger-bg); border-color: var(--danger-border); }
|
|
|
|
|
/* Two facts per cell, so the second sits under the first rather than
|
|
|
|
|
stretching the column. */
|
|
|
|
|
.status-grid dd { font-size: 14px; line-height: 1.45; }
|
|
|
|
|
@@ -320,11 +387,11 @@
|
|
|
|
|
truncated so it cannot set the column width, full text in the tooltip. */
|
|
|
|
|
.endpoint { display: block; max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
|
|
|
.attempt-failed td { background: #fdf7f7; }
|
|
|
|
|
.attempt-error td { padding-top: 0; color: #a12b2b; font-size: 12px; background: #fdf7f7; border-top: 0; }
|
|
|
|
|
.attempt-error td { padding-top: 0; color: var(--danger); font-size: 12px; background: #fdf7f7; border-top: 0; }
|
|
|
|
|
|
|
|
|
|
.table-scroll { overflow-x: auto; }
|
|
|
|
|
.link-action { color: #2563eb; text-decoration: none; }
|
|
|
|
|
.notice { padding: 10px 12px; border: 1px solid #cfe0c4; border-radius: 8px; color: #21643a; background: #f2f9f3; }
|
|
|
|
|
.link-action { color: var(--primary); text-decoration: none; }
|
|
|
|
|
.notice { padding: 10px 12px; border: 1px solid #cfe0c4; border-radius: 8px; color: var(--success); background: #f2f9f3; }
|
|
|
|
|
|
|
|
|
|
/* The shortcut buttons — read everything, full access, clear — sit above the
|
|
|
|
|
matrix they fill in, so they are wider than the cell buttons and read as
|
|
|
|
|
@@ -336,19 +403,19 @@
|
|
|
|
|
because a grant is one call to the server either way. */
|
|
|
|
|
.grant-matrix td, .grant-matrix th { white-space: normal; }
|
|
|
|
|
.grant-matrix th { text-transform: capitalize; }
|
|
|
|
|
.grant-matrix .object-label { display: block; font-weight: 600; color: #24324a; }
|
|
|
|
|
.grant-matrix td small { display: block; margin: 2px 0; color: #7c8796; }
|
|
|
|
|
.grant-matrix .object-label { display: block; font-weight: 600; color: var(--text-secondary); }
|
|
|
|
|
.grant-matrix td small { display: block; margin: 2px 0; color: var(--text-muted); }
|
|
|
|
|
.grant-matrix td code { font-size: 11px; color: #5b6678; }
|
|
|
|
|
.grant-cell { width: 82px; text-align: center; vertical-align: middle; }
|
|
|
|
|
.grant-cell .actions { justify-content: center; gap: 4px; }
|
|
|
|
|
.grant-cell form { margin: 0 auto; }
|
|
|
|
|
.grant-cell button { min-width: 34px; padding: 4px 9px; border-radius: 5px; cursor: pointer; }
|
|
|
|
|
button.cell-on { border: 1px solid #a9d3b4; color: #21643a; background: #eefaf1; }
|
|
|
|
|
button.cell-on:hover { border-color: #e0b7b3; color: #a12b2b; background: #fdf3f3; }
|
|
|
|
|
button.cell-off { border: 1px dashed #cdd5e0; color: #8a94a4; background: white; }
|
|
|
|
|
button.cell-off:hover { border-style: solid; border-color: #a9c7f6; color: #1d4ed8; background: #eef3fe; }
|
|
|
|
|
button.cell-on { border: 1px solid #a9d3b4; color: var(--success); background: #eefaf1; }
|
|
|
|
|
button.cell-on:hover { border-color: #e0b7b3; color: var(--danger); background: var(--danger-bg); }
|
|
|
|
|
button.cell-off { border: 1px dashed #cdd5e0; color: #8a94a4; background: var(--surface); }
|
|
|
|
|
button.cell-off:hover { border-style: solid; border-color: var(--select-border); color: #1d4ed8; background: #eef3fe; }
|
|
|
|
|
.cell-closed { color: #c3cad4; }
|
|
|
|
|
.cell-inherited { color: #1d4ed8; }
|
|
|
|
|
.cell-inherited { color: var(--primary-strong); }
|
|
|
|
|
|
|
|
|
|
/* ---------- A running import (import/progress.html) ---------- */
|
|
|
|
|
|
|
|
|
|
@@ -357,17 +424,17 @@
|
|
|
|
|
number is tabular: the figures update every second, and digits that change
|
|
|
|
|
width make the whole line jitter. */
|
|
|
|
|
.import-progress { margin: 14px 0; padding: 14px 16px; border: 1px solid #cfdcef; border-radius: 9px; background: #f7faff; }
|
|
|
|
|
.import-progress h3 { margin: 0 0 10px; color: #24324a; font-size: 14px; }
|
|
|
|
|
.import-progress h3 { margin: 0 0 10px; color: var(--text-secondary); font-size: 14px; }
|
|
|
|
|
.progress-line { display: flex; align-items: center; gap: 10px; }
|
|
|
|
|
.import-progress progress { flex: 1; width: 100%; height: 10px; border: 0; border-radius: 999px; background: #dde6f2; overflow: hidden; }
|
|
|
|
|
.import-progress progress::-webkit-progress-bar { border-radius: 999px; background: #dde6f2; }
|
|
|
|
|
.import-progress progress::-webkit-progress-value { border-radius: 999px; background: #3b6fc4; transition: width 400ms ease; }
|
|
|
|
|
.import-progress progress::-moz-progress-bar { border-radius: 999px; background: #3b6fc4; }
|
|
|
|
|
.progress-percent { min-width: 42px; color: #24324a; font-size: 13px; font-variant-numeric: tabular-nums; text-align: right; }
|
|
|
|
|
.progress-rows { margin: 8px 0 0; color: #33415c; font-size: 13px; font-variant-numeric: tabular-nums; }
|
|
|
|
|
.progress-percent { min-width: 42px; color: var(--text-secondary); font-size: 13px; font-variant-numeric: tabular-nums; text-align: right; }
|
|
|
|
|
.progress-rows { margin: 8px 0 0; color: var(--text); font-size: 13px; font-variant-numeric: tabular-nums; }
|
|
|
|
|
.progress-stats { display: flex; flex-wrap: wrap; gap: 6px 24px; margin: 10px 0 0; }
|
|
|
|
|
.progress-stats dt { color: #6d798a; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; }
|
|
|
|
|
.progress-stats dd { margin: 2px 0 0; color: #24324a; font-size: 14px; font-variant-numeric: tabular-nums; }
|
|
|
|
|
.progress-stats dd { margin: 2px 0 0; color: var(--text-secondary); font-size: 14px; font-variant-numeric: tabular-nums; }
|
|
|
|
|
.import-progress .hint { margin: 10px 0 0; font-size: 12px; }
|
|
|
|
|
|
|
|
|
|
/* ---------- Import preparation (pages/import_export/import) ---------- */
|
|
|
|
|
@@ -376,30 +443,30 @@
|
|
|
|
|
destinations. A select in every row is the keyboard/touch equivalent of
|
|
|
|
|
dragging a source chip onto it. */
|
|
|
|
|
.mapping-summary { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin: 14px 0; padding: 10px 12px; border-radius: 8px; background: #f5f7fa; }
|
|
|
|
|
.mapping-summary strong { color: #24324a; font-variant-numeric: tabular-nums; }
|
|
|
|
|
.mapping-workbench h3 { margin: 0; color: #24324a; font-size: 14px; }
|
|
|
|
|
.mapping-summary strong { color: var(--text-secondary); font-variant-numeric: tabular-nums; }
|
|
|
|
|
.mapping-workbench h3 { margin: 0; color: var(--text-secondary); font-size: 14px; }
|
|
|
|
|
.mapping-workbench h3 + .hint { margin: 4px 0 12px; font-size: 12px; }
|
|
|
|
|
|
|
|
|
|
/* The batch actions stay reachable while a long destination list scrolls. */
|
|
|
|
|
.mapping-toolbar { position: sticky; top: 0; z-index: 2; display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin-bottom: 12px; padding: 8px; border: 1px solid #d8e1ec; border-radius: 8px; background: rgb(255 255 255 / 96%); box-shadow: 0 3px 12px rgb(31 43 58 / 7%); }
|
|
|
|
|
.mapping-toolbar button.secondary { margin: 0; padding: 6px 10px; border: 1px solid #c9d2de; border-radius: 6px; color: #24324a; background: #f4f6fa; font-size: 12px; cursor: pointer; }
|
|
|
|
|
.mapping-toolbar button.secondary:hover { background: #e9edf4; }
|
|
|
|
|
.mapping-toolbar button.secondary { margin: 0; padding: 6px 10px; border: 1px solid var(--secondary-border); border-radius: 6px; color: var(--text-secondary); background: var(--secondary-bg); font-size: 12px; cursor: pointer; }
|
|
|
|
|
.mapping-toolbar button.secondary:hover { background: var(--hover-bg); }
|
|
|
|
|
|
|
|
|
|
.mapping-panels { display: grid; grid-template-columns: minmax(240px, .8fr) minmax(460px, 1.5fr); align-items: start; gap: 14px; }
|
|
|
|
|
.source-palette, .destination-map { padding: 14px; border: 1px solid #dfe5ed; border-radius: 9px; background: #fafbfc; }
|
|
|
|
|
.source-palette, .destination-map { padding: 14px; border: 1px solid #dfe5ed; border-radius: 9px; background: var(--surface-alt); }
|
|
|
|
|
/* The palette follows the destination list down, so a column near the bottom
|
|
|
|
|
of a wide table still has something to be dropped from. */
|
|
|
|
|
.source-palette { position: sticky; top: 56px; max-height: calc(100vh - 76px); overflow: auto; }
|
|
|
|
|
.palette-heading { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 6px; }
|
|
|
|
|
.palette-actions { display: flex; align-items: center; gap: 6px; }
|
|
|
|
|
.palette-actions button.secondary { margin: 0; padding: 4px 8px; border: 1px solid #cfd8e5; border-radius: 6px; color: #46566d; background: white; font-size: 11px; cursor: pointer; }
|
|
|
|
|
.palette-actions button.secondary { margin: 0; padding: 4px 8px; border: 1px solid #cfd8e5; border-radius: 6px; color: #46566d; background: var(--surface); font-size: 11px; cursor: pointer; }
|
|
|
|
|
.selection-count { min-width: 42px; color: #6d798a; font-size: 11px; font-variant-numeric: tabular-nums; text-align: right; }
|
|
|
|
|
|
|
|
|
|
/* Every track is a fixed width and there is only ever one row, so selecting a
|
|
|
|
|
chip or mapping it changes colour and nothing else — no part of the list
|
|
|
|
|
moves under the pointer that just clicked it. */
|
|
|
|
|
.source-chips { display: grid; gap: 7px; }
|
|
|
|
|
.source-chip { display: grid; grid-template-columns: 19px minmax(0, 1fr) 108px; align-items: center; gap: 8px; width: 100%; padding: 9px 10px; border: 1px solid #cfd9e6; border-radius: 7px; color: #33415c; background: white; text-align: left; cursor: grab; transition: border-color 120ms ease, box-shadow 120ms ease, opacity 120ms ease; }
|
|
|
|
|
.source-chip { display: grid; grid-template-columns: 19px minmax(0, 1fr) 108px; align-items: center; gap: 8px; width: 100%; padding: 9px 10px; border: 1px solid #cfd9e6; border-radius: 7px; color: var(--text); background: var(--surface); text-align: left; cursor: grab; transition: border-color 120ms ease, box-shadow 120ms ease, opacity 120ms ease; }
|
|
|
|
|
.source-chip:hover { border-color: #78a1df; box-shadow: 0 3px 10px rgb(31 43 58 / 9%); }
|
|
|
|
|
.source-chip.is-mapped { border-color: #a8cfb3; background: #f4fbf6; }
|
|
|
|
|
.source-chip.is-selected { border-color: #78a1df; background: #f3f7ff; outline: 3px solid rgb(37 99 235 / 12%); }
|
|
|
|
|
@@ -418,20 +485,20 @@
|
|
|
|
|
.source-chip.is-mapped small, .chip-target:empty { display: none; }
|
|
|
|
|
|
|
|
|
|
.destination-rows { display: grid; gap: 7px; margin: 0; padding: 0; list-style: none; }
|
|
|
|
|
.destination-rows li { display: grid; grid-template-columns: minmax(100px, .7fr) 22px minmax(210px, 1.3fr) minmax(70px, .65fr) auto; align-items: center; gap: 8px; min-height: 62px; padding: 8px 9px; border: 1px dashed #cdd6e2; border-radius: 7px; background: white; transition: border-color 120ms ease, background 120ms ease, box-shadow 120ms ease; }
|
|
|
|
|
.destination-rows li { display: grid; grid-template-columns: minmax(100px, .7fr) 22px minmax(210px, 1.3fr) minmax(70px, .65fr) auto; align-items: center; gap: 8px; min-height: 62px; padding: 8px 9px; border: 1px dashed #cdd6e2; border-radius: 7px; background: var(--surface); transition: border-color 120ms ease, background 120ms ease, box-shadow 120ms ease; }
|
|
|
|
|
.destination-rows li.is-mapped { border-style: solid; border-color: #b9cce8; }
|
|
|
|
|
/* With a selection live, every row is somewhere the batch can be dropped. */
|
|
|
|
|
.mapping-workbench.has-selection .destination-rows li { border-color: #9bbcf0; cursor: copy; }
|
|
|
|
|
.destination-rows li.drop-ready { border-style: solid; border-color: #2563eb; background: #edf4ff; box-shadow: 0 0 0 3px rgb(37 99 235 / 12%); }
|
|
|
|
|
.destination-rows li.drop-ready { border-style: solid; border-color: var(--primary); background: #edf4ff; box-shadow: 0 0 0 3px rgb(37 99 235 / 12%); }
|
|
|
|
|
.destination-rows li.just-mapped { background: #eef8f1; }
|
|
|
|
|
.destination-name { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; min-width: 0; }
|
|
|
|
|
.destination-name code { overflow: hidden; color: #24324a; text-overflow: ellipsis; }
|
|
|
|
|
.destination-name code { overflow: hidden; color: var(--text-secondary); text-overflow: ellipsis; }
|
|
|
|
|
.mapping-arrow { color: #9aa5b4; text-align: center; }
|
|
|
|
|
.destination-rows label { display: grid; gap: 3px; color: #778396; font-size: 10px; letter-spacing: .04em; text-transform: uppercase; cursor: auto; }
|
|
|
|
|
.destination-rows select { min-width: 0; color: #24324a; font-size: 13px; letter-spacing: normal; text-transform: none; }
|
|
|
|
|
.mapped-example { min-width: 0; overflow: hidden; color: #667385; font: 11px/1.4 ui-monospace, monospace; text-overflow: ellipsis; white-space: nowrap; }
|
|
|
|
|
.clear-mapping { padding: 6px 8px; border: 1px solid #d6dde7; border-radius: 6px; color: #59677a; background: white; font-size: 11px; cursor: pointer; }
|
|
|
|
|
.clear-mapping:hover:not(:disabled) { color: #a12b2b; background: #fdf3f3; }
|
|
|
|
|
.destination-rows select { min-width: 0; color: var(--text-secondary); font-size: 13px; letter-spacing: normal; text-transform: none; }
|
|
|
|
|
.mapped-example { min-width: 0; overflow: hidden; color: var(--text-subtle); font: 11px/1.4 ui-monospace, monospace; text-overflow: ellipsis; white-space: nowrap; }
|
|
|
|
|
.clear-mapping { padding: 6px 8px; border: 1px solid #d6dde7; border-radius: 6px; color: #59677a; background: var(--surface); font-size: 11px; cursor: pointer; }
|
|
|
|
|
.clear-mapping:hover:not(:disabled) { color: var(--danger); background: var(--danger-bg); }
|
|
|
|
|
.clear-mapping:disabled { color: #bdc4ce; background: #f7f8fa; cursor: default; }
|
|
|
|
|
|
|
|
|
|
@media (max-width: 850px) {
|
|
|
|
|
@@ -445,8 +512,8 @@
|
|
|
|
|
/* A secondary action in a form's action row — "back a step". The row's own
|
|
|
|
|
rule paints every button as the primary one, so this has to say otherwise
|
|
|
|
|
at the same specificity. */
|
|
|
|
|
.form-actions button.secondary { margin-top: 0; border: 1px solid #c9d2de; color: #24324a; background: #f4f6fa; }
|
|
|
|
|
.form-actions button.secondary:hover { background: #e9edf4; }
|
|
|
|
|
.form-actions button.secondary { margin-top: 0; border: 1px solid var(--secondary-border); color: var(--text-secondary); background: var(--secondary-bg); }
|
|
|
|
|
.form-actions button.secondary:hover { background: var(--hover-bg); }
|
|
|
|
|
|
|
|
|
|
/* ---------- Narrow screens ---------- */
|
|
|
|
|
|
|
|
|
|
|