snapshot: preserve shell cleanup and login/dashboard fixes
This commit is contained in:
45
backend/workflows/static/workflows/css/admin_tools.css
Normal file
45
backend/workflows/static/workflows/css/admin_tools.css
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
body { margin: 0; font-family: Arial, sans-serif; background: #f4f8ff; color: #0f172a; padding: 20px; }
|
||||||
|
.shell { max-width: 1100px; margin: 0 auto; background: #fff; border: 1px solid #d8e3f0; border-radius: 14px; padding: 16px; }
|
||||||
|
h1 { margin: 12px 0 6px; color: #000078; }
|
||||||
|
.sub { margin: 0 0 12px; color: #54657c; }
|
||||||
|
.flash, .msg { border-radius: 10px; padding: 10px 12px; margin: 0 0 12px; border: 1px solid #d6e1ef; background: #f8fbff; color: #1f3a5f; }
|
||||||
|
.flash.error, .msg.error { border-color: #fecaca; background: #fff1f2; color: #991b1b; }
|
||||||
|
.flash.success { border-color: #bfe6c9; background: #edf9f1; color: #116634; }
|
||||||
|
.card { border: 1px solid #d8e3f0; border-radius: 12px; background: #fbfdff; padding: 12px; margin-bottom: 14px; }
|
||||||
|
.grid { display: grid; grid-template-columns: repeat(2, minmax(240px, 1fr)); gap: 10px; }
|
||||||
|
label { display: block; margin-bottom: 4px; font-size: 12px; color: #334155; font-weight: 700; }
|
||||||
|
input, select, textarea { width: 100%; box-sizing: border-box; border: 1px solid #cbd5e1; border-radius: 8px; padding: 8px 9px; background: #fff; }
|
||||||
|
textarea { min-height: 120px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; }
|
||||||
|
.actions { margin-top: 10px; display: flex; gap: 8px; flex-wrap: wrap; }
|
||||||
|
.hint { margin-top: 6px; color: #64748b; font-size: 12px; }
|
||||||
|
.toolbar { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
|
||||||
|
.switch { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
|
||||||
|
.switch .tab { border: 1px solid #c9d6e7; border-radius: 999px; padding: 8px 14px; text-decoration: none; color: #1f2f49; font-weight: 700; background: #f6f9ff; }
|
||||||
|
.switch .tab.active { background: #000078; color: #fff; border-color: #000078; }
|
||||||
|
.check-row { margin-top: 8px; display: flex; gap: 12px; flex-wrap: wrap; }
|
||||||
|
.check-row label { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: 13px; }
|
||||||
|
.check-row input[type="checkbox"] { width: auto; }
|
||||||
|
.table-wrap, .option-table-wrap { overflow-x: auto; }
|
||||||
|
table { width: 100%; border-collapse: collapse; font-size: 14px; }
|
||||||
|
th, td { border: 1px solid #dce5f1; padding: 8px; text-align: left; vertical-align: top; }
|
||||||
|
th { background: #f6f9ff; color: #334155; }
|
||||||
|
.template-block { border: 1px solid #d8e3f0; border-radius: 10px; background: #fff; padding: 10px; margin-top: 10px; }
|
||||||
|
.template-title, .rule-title { margin: 0 0 8px; color: #24344e; font-weight: 700; font-size: 14px; }
|
||||||
|
.rule-card { margin-top: 12px; border: 1px solid #d8e3f0; border-radius: 12px; padding: 10px; background: #fff; }
|
||||||
|
.badge { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 12px; font-weight: 700; }
|
||||||
|
.scheduled { background: #eff6ff; color: #1d4ed8; }
|
||||||
|
.paused { background: #fef9c3; color: #854d0e; }
|
||||||
|
.cancelled { background: #f1f5f9; color: #334155; }
|
||||||
|
.sent { background: #ecfdf3; color: #166534; }
|
||||||
|
.failed { background: #fff1f2; color: #991b1b; }
|
||||||
|
.bulk-bar { margin: 0 0 10px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
|
||||||
|
.bulk-bar select { width: auto; min-width: 180px; }
|
||||||
|
.select-col { width: 42px; text-align: center; }
|
||||||
|
.bulk-note { color: #64748b; font-size: 12px; }
|
||||||
|
.field label { display: block; font-weight: 600; margin-bottom: 6px; }
|
||||||
|
.field input, .field select { min-height: 40px; }
|
||||||
|
.mini { color: #64748b; font-size: 12px; }
|
||||||
|
.table-controls input[type="text"], .table-controls select { width: 100%; min-height: 36px; padding: 7px 9px; border: 1px solid #cfd9e8; border-radius: 8px; box-sizing: border-box; }
|
||||||
|
.table-controls input[type="checkbox"] { transform: scale(1.1); width: auto; }
|
||||||
|
.actions { white-space: nowrap; }
|
||||||
|
@media (max-width: 760px) { .grid { grid-template-columns: 1fr; } }
|
||||||
22
backend/workflows/static/workflows/css/docs_pages.css
Normal file
22
backend/workflows/static/workflows/css/docs_pages.css
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
body { margin: 0; font-family: Arial, sans-serif; background: #f4f8ff; color: #1b2b43; padding: 20px; }
|
||||||
|
.shell { max-width: 1120px; margin: 0 auto; background: #fff; border: 1px solid #d7e0ea; border-radius: 14px; padding: 18px; }
|
||||||
|
.brand-logo { width: 190px; max-width: 100%; height: auto; margin: 0 0 10px; display: block; }
|
||||||
|
.top { display: flex; justify-content: space-between; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; }
|
||||||
|
h1 { margin: 0; color: #000078; font-size: 30px; }
|
||||||
|
.sub { margin: 8px 0 16px; color: #5f6f85; }
|
||||||
|
.toc { border: 1px solid #d7e0ea; border-radius: 10px; padding: 10px; background: #f7fbff; margin-bottom: 16px; }
|
||||||
|
.toc a { color: #0b4da2; text-decoration: none; margin-right: 10px; white-space: nowrap; }
|
||||||
|
h2 { margin: 20px 0 8px; color: #113a74; border-bottom: 1px solid #e1e8f2; padding-bottom: 4px; }
|
||||||
|
h3 { margin: 14px 0 6px; color: #183f77; }
|
||||||
|
ul { margin: 8px 0 12px 20px; }
|
||||||
|
li { margin: 4px 0; }
|
||||||
|
code { background: #f1f5fb; border: 1px solid #dce6f3; border-radius: 6px; padding: 2px 6px; }
|
||||||
|
pre { background: #f7fbff; border: 1px solid #dce6f3; border-radius: 10px; padding: 10px; overflow-x: auto; }
|
||||||
|
.box { border: 1px solid #d7e0ea; border-radius: 10px; padding: 10px; background: #fcfdff; margin: 8px 0 12px; }
|
||||||
|
.note { border-left: 4px solid #000078; padding: 8px 10px; background: #f4f8ff; margin: 10px 0; }
|
||||||
|
.grid { display: grid; grid-template-columns: repeat(3, minmax(260px, 1fr)); gap: 14px; }
|
||||||
|
.card { border: 1px solid #d7e0ea; border-radius: 14px; background: #fcfdff; padding: 16px; }
|
||||||
|
.eyebrow { display: inline-block; padding: 5px 10px; border-radius: 999px; background: #eef4ff; color: #244a8f; border: 1px solid #d5e2f9; font-size: 12px; font-weight: 700; margin-bottom: 10px; }
|
||||||
|
p { margin: 0 0 14px; color: #5f6f85; }
|
||||||
|
.actions { display: flex; gap: 8px; flex-wrap: wrap; }
|
||||||
|
@media (max-width: 760px) { .grid { grid-template-columns: 1fr; } }
|
||||||
432
backend/workflows/static/workflows/css/home.css
Normal file
432
backend/workflows/static/workflows/css/home.css
Normal file
@@ -0,0 +1,432 @@
|
|||||||
|
:root {
|
||||||
|
--brand-blue: #000078;
|
||||||
|
--brand-red: #8c1d1d;
|
||||||
|
--ink: #102039;
|
||||||
|
--muted: #5f6f85;
|
||||||
|
--line: #d8e1ee;
|
||||||
|
--panel: #ffffff;
|
||||||
|
--bg-soft: #eff4ff;
|
||||||
|
--ok-bg: #effaf2;
|
||||||
|
--ok-ink: #166534;
|
||||||
|
--warn-bg: #fff6ea;
|
||||||
|
--warn-ink: #8a4f00;
|
||||||
|
}
|
||||||
|
|
||||||
|
* { box-sizing: border-box; }
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
|
||||||
|
color: var(--ink);
|
||||||
|
background:
|
||||||
|
radial-gradient(80% 120% at 85% 8%, rgba(0, 0, 120, 0.12), rgba(0, 0, 120, 0)),
|
||||||
|
radial-gradient(70% 90% at 8% 92%, rgba(140, 29, 29, 0.10), rgba(140, 29, 29, 0)),
|
||||||
|
linear-gradient(165deg, #eef3ff, #f7f9ff 48%, #f0f5ff);
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shell {
|
||||||
|
width: min(1380px, 100%);
|
||||||
|
margin: 0 auto;
|
||||||
|
background: var(--panel);
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: 20px;
|
||||||
|
box-shadow: 0 20px 44px rgba(16, 32, 57, 0.13);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 18px 22px;
|
||||||
|
border-bottom: 1px solid var(--line);
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-wrap {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-logo {
|
||||||
|
width: 210px;
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.lang-switch { display:flex; gap:6px; }
|
||||||
|
.lang-btn { border:1px solid var(--line); background:#f8fbff; color:#1f3a5f; border-radius:999px; padding:6px 10px; font-size:12px; font-weight:700; cursor:pointer; }
|
||||||
|
.lang-btn.active { background:var(--brand-blue); border-color:var(--brand-blue); color:#fff; }
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
padding: 24px;
|
||||||
|
border-bottom: 1px solid var(--line);
|
||||||
|
background:
|
||||||
|
linear-gradient(135deg, rgba(0, 0, 120, 0.08), rgba(0, 0, 120, 0) 44%),
|
||||||
|
linear-gradient(180deg, rgba(255,255,255,0.96), rgba(246,250,255,0.92));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 18px;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-card,
|
||||||
|
.hero-sidecard {
|
||||||
|
border: 1px solid rgba(217, 227, 238, 0.94);
|
||||||
|
background: rgba(255,255,255,0.92);
|
||||||
|
border-radius: 22px;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.92);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-card {
|
||||||
|
padding: 24px;
|
||||||
|
background:
|
||||||
|
radial-gradient(100% 140% at 10% 10%, rgba(31,79,214,0.12), rgba(31,79,214,0)),
|
||||||
|
linear-gradient(180deg, rgba(255,255,255,0.98), rgba(247,250,255,0.95));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-sidecard {
|
||||||
|
padding: 18px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
background:
|
||||||
|
radial-gradient(120% 120% at 100% 0%, rgba(163,32,32,0.10), rgba(163,32,32,0)),
|
||||||
|
linear-gradient(180deg, rgba(255,255,255,0.98), rgba(253,247,247,0.96));
|
||||||
|
}
|
||||||
|
|
||||||
|
.eyebrow {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid rgba(0,0,120,0.12);
|
||||||
|
background: rgba(0,0,120,0.05);
|
||||||
|
color: var(--brand-blue);
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero h1 {
|
||||||
|
margin: 14px 0 8px;
|
||||||
|
font-size: clamp(30px, 5vw, 46px);
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: -0.04em;
|
||||||
|
color: var(--brand-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero p {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--muted);
|
||||||
|
max-width: 720px;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.55;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-row {
|
||||||
|
margin-top: 16px;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-pill {
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
background: #fff;
|
||||||
|
color: #30445f;
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-pill.ok {
|
||||||
|
background: var(--ok-bg);
|
||||||
|
color: var(--ok-ink);
|
||||||
|
border-color: #c7ecd2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-pill.warn {
|
||||||
|
background: var(--warn-bg);
|
||||||
|
color: var(--warn-ink);
|
||||||
|
border-color: #f7dfbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-sidecard h2 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #1a3359;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-sidecard p {
|
||||||
|
margin: 8px 0 0;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-metrics {
|
||||||
|
margin-top: 18px;
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-metric {
|
||||||
|
padding: 12px 14px;
|
||||||
|
border-radius: 16px;
|
||||||
|
background: rgba(255,255,255,0.86);
|
||||||
|
border: 1px solid rgba(217, 227, 238, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-metric-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--muted);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-metric-value {
|
||||||
|
margin-top: 5px;
|
||||||
|
font-size: 26px;
|
||||||
|
font-weight: 800;
|
||||||
|
color: var(--brand-blue);
|
||||||
|
letter-spacing: -0.03em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
padding: 20px 22px 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-head {
|
||||||
|
margin: 0 0 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: flex-end;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-head h2 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 19px;
|
||||||
|
color: #172b4a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-head p {
|
||||||
|
margin: 0;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apps-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 14px;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-card {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid rgba(217, 227, 238, 0.94);
|
||||||
|
border-radius: 22px;
|
||||||
|
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(247,250,255,0.95));
|
||||||
|
padding: 18px;
|
||||||
|
min-height: 222px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.92);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-card::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: auto -24px -38px auto;
|
||||||
|
width: 118px;
|
||||||
|
height: 118px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(31, 79, 214, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-card.primary {
|
||||||
|
background: linear-gradient(180deg, rgba(255,255,255,0.99), rgba(242,247,255,0.97));
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-card.red {
|
||||||
|
background: linear-gradient(180deg, rgba(255,255,255,0.99), rgba(255,245,245,0.97));
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-card.red::before { background: rgba(163, 32, 32, 0.08); }
|
||||||
|
|
||||||
|
.app-card .top-line {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accent {
|
||||||
|
width: 38px;
|
||||||
|
height: 38px;
|
||||||
|
border-radius: 14px;
|
||||||
|
background: rgba(0, 0, 120, 0.06);
|
||||||
|
color: var(--brand-blue);
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accent.red {
|
||||||
|
background: rgba(163, 32, 32, 0.08);
|
||||||
|
color: var(--brand-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 1.05;
|
||||||
|
letter-spacing: -0.03em;
|
||||||
|
color: var(--ink);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-text {
|
||||||
|
margin: 10px 0 12px;
|
||||||
|
color: #5a6a81;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
max-width: 34ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
border: 1px solid rgba(217, 227, 238, 0.96);
|
||||||
|
border-radius: 14px;
|
||||||
|
padding: 7px 10px;
|
||||||
|
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(248,251,255,0.96));
|
||||||
|
color: #486183;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 800;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-card {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid rgba(217, 227, 238, 0.94);
|
||||||
|
border-radius: 18px;
|
||||||
|
padding: 14px;
|
||||||
|
background: linear-gradient(180deg, rgba(255,255,255,0.99), rgba(247,250,255,0.96));
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.92);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-card::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: auto -18px -30px auto;
|
||||||
|
width: 84px;
|
||||||
|
height: 84px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(31, 79, 214, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-card h3 {
|
||||||
|
margin: 0 0 7px;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #18345f;
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-card p {
|
||||||
|
margin: 0 0 11px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #607088;
|
||||||
|
min-height: 34px;
|
||||||
|
line-height: 1.45;
|
||||||
|
max-width: 26ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg {
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
margin: 0 0 14px;
|
||||||
|
border: 1px solid #d6e1ef;
|
||||||
|
background: #f8fbff;
|
||||||
|
color: #1f3a5f;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg.error {
|
||||||
|
border-color: #fecaca;
|
||||||
|
background: #fff1f2;
|
||||||
|
color: #991b1b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-note {
|
||||||
|
margin-top: 16px;
|
||||||
|
border-top: 1px solid var(--line);
|
||||||
|
padding-top: 12px;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1080px) {
|
||||||
|
.hero-grid { grid-template-columns: 1fr; }
|
||||||
|
.apps-grid { grid-template-columns: 1fr 1fr; }
|
||||||
|
.admin-grid { grid-template-columns: 1fr 1fr; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 760px) {
|
||||||
|
body { padding: 12px; }
|
||||||
|
.topbar, .hero, .main { padding-left: 14px; padding-right: 14px; }
|
||||||
|
.hero h1 { font-size: 28px; }
|
||||||
|
.apps-grid, .admin-grid { grid-template-columns: 1fr; }
|
||||||
|
.quick-actions { justify-content: flex-start; }
|
||||||
|
}
|
||||||
99
backend/workflows/static/workflows/css/login.css
Normal file
99
backend/workflows/static/workflows/css/login.css
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
min-height: 100vh;
|
||||||
|
font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
|
||||||
|
background:
|
||||||
|
radial-gradient(70% 90% at 8% 8%, rgba(0, 0, 120, 0.14), rgba(0, 0, 120, 0)),
|
||||||
|
radial-gradient(60% 85% at 92% 88%, rgba(163, 32, 32, 0.12), rgba(163, 32, 32, 0)),
|
||||||
|
linear-gradient(160deg, #eef3ff 0%, #f9fbff 48%, #edf4ff 100%);
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shell {
|
||||||
|
background: rgba(255, 255, 255, 0.78);
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
border: 1px solid rgba(217, 227, 238, 0.9);
|
||||||
|
border-radius: 28px;
|
||||||
|
box-shadow: 0 22px 48px rgba(18, 34, 56, 0.14);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-shell-body {
|
||||||
|
padding: 24px;
|
||||||
|
background:
|
||||||
|
radial-gradient(90% 120% at 10% 0%, rgba(31, 79, 214, 0.06), rgba(31, 79, 214, 0)),
|
||||||
|
linear-gradient(180deg, rgba(255,255,255,0.72), rgba(248,251,255,0.48));
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-card {
|
||||||
|
width: min(440px, 100%);
|
||||||
|
margin: 0 auto;
|
||||||
|
background: rgba(255, 255, 255, 0.94);
|
||||||
|
border: 1px solid #d9e3f0;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 22px;
|
||||||
|
box-shadow: 0 14px 32px rgba(28, 45, 79, 0.10), inset 0 1px 0 rgba(255,255,255,0.92);
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-card h1 {
|
||||||
|
margin: 0 0 8px;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #132238;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-card p {
|
||||||
|
margin: 0 0 14px;
|
||||||
|
color: #607086;
|
||||||
|
line-height: 1.45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field label {
|
||||||
|
display: block;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
color: #132238;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid #cbd5e1;
|
||||||
|
border-radius: 10px;
|
||||||
|
min-height: 44px;
|
||||||
|
font: inherit;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.errorlist {
|
||||||
|
color: #b91c1c;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid #f0c8c8;
|
||||||
|
background: #fff3f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 760px) {
|
||||||
|
body {
|
||||||
|
padding: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-shell-body {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-card {
|
||||||
|
width: 100%;
|
||||||
|
padding: 18px;
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
:root {
|
||||||
|
--brand-blue: #000078;
|
||||||
|
--ink: #17253b;
|
||||||
|
--muted: #607087;
|
||||||
|
--line: #d7e0ea;
|
||||||
|
--panel: #ffffff;
|
||||||
|
--soft: #f4f8ff;
|
||||||
|
--soft-strong: #eef4ff;
|
||||||
|
--ok-bg: #edf9f1;
|
||||||
|
--ok-ink: #116634;
|
||||||
|
--warn-bg: #fff8ea;
|
||||||
|
--warn-ink: #8a5a00;
|
||||||
|
}
|
||||||
|
* { box-sizing: border-box; }
|
||||||
|
body { margin: 0; font-family: "Segoe UI", Arial, sans-serif; background: linear-gradient(180deg, #eef4ff, #f8fbff); color: var(--ink); padding: 24px; }
|
||||||
|
.shell { width: min(var(--app-shell-width), 100%); margin: 0 auto; background: var(--panel); border: 1px solid var(--line); border-radius: 28px; box-shadow: 0 22px 48px rgba(18,34,56,.14); overflow: hidden; }
|
||||||
|
.hero { padding: 20px 22px 18px; border-bottom: 1px solid var(--line); background: linear-gradient(135deg, rgba(0,0,120,.06), rgba(0,0,120,0) 48%), linear-gradient(180deg, #ffffff, #f8fbff); }
|
||||||
|
.hero h1 { margin: 0; font-size: 32px; line-height: 1.08; color: var(--brand-blue); }
|
||||||
|
.sub { margin: 8px 0 0; color: var(--muted); max-width: 780px; }
|
||||||
|
.content { padding: 20px 22px 24px; }
|
||||||
|
.flash { margin: 0 0 12px; padding: 10px 12px; border-radius: 10px; border: 1px solid #bfe6c9; background: var(--ok-bg); color: var(--ok-ink); }
|
||||||
|
.meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-bottom: 16px; }
|
||||||
|
.card { border: 1px solid var(--line); border-radius: 14px; background: #fff; padding: 14px; }
|
||||||
|
.card h2 { margin: 0 0 10px; font-size: 16px; color: #1b3764; }
|
||||||
|
.progress-block { border: 1px solid var(--line); border-radius: 14px; background: linear-gradient(180deg, #ffffff, #f9fbff); padding: 14px; margin-bottom: 16px; }
|
||||||
|
.progress-top { display: flex; justify-content: space-between; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; }
|
||||||
|
.progress-label { font-size: 15px; font-weight: 700; color: #18345f; }
|
||||||
|
.progress-meta { color: var(--muted); font-size: 13px; }
|
||||||
|
.progress-bar { width: 100%; height: 12px; border-radius: 999px; overflow: hidden; background: #e7eefb; border: 1px solid #d6e1f5; }
|
||||||
|
.progress-fill { height: 100%; background: linear-gradient(90deg, #3056a3, #0f5fcf); }
|
||||||
|
.meta-grid { display: grid; grid-template-columns: 170px 1fr; gap: 8px 10px; font-size: 14px; }
|
||||||
|
.meta-grid strong { color: #334155; }
|
||||||
|
.status-pill { display: inline-block; padding: 4px 10px; border-radius: 999px; border: 1px solid #d7e0ea; background: #f8fbff; color: #486183; font-size: 12px; font-weight: 700; }
|
||||||
|
.status-pill.done { background: var(--ok-bg); color: var(--ok-ink); border-color: #bfe6c9; }
|
||||||
|
.status-pill.draft { background: var(--warn-bg); color: var(--warn-ink); border-color: #f5d8a8; }
|
||||||
|
.section { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; margin-bottom: 14px; background: #fff; }
|
||||||
|
.section-head { padding: 11px 14px; font-weight: 700; color: #1f376b; background: var(--soft-strong); border-bottom: 1px solid #d5e2f9; }
|
||||||
|
.items { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0; padding: 6px 14px 10px; }
|
||||||
|
.item { display: flex; align-items: flex-start; gap: 12px; padding: 10px 0; border-bottom: 1px solid #eef3f8; }
|
||||||
|
.item:nth-last-child(-n+2) { border-bottom: 0; }
|
||||||
|
.item input { margin-top: 2px; width: 18px; height: 18px; accent-color: var(--brand-blue); }
|
||||||
|
.item span { line-height: 1.45; }
|
||||||
|
textarea { width: 100%; min-height: 150px; border: 1px solid #cfd9e8; border-radius: 10px; padding: 11px 12px; font: inherit; resize: vertical; }
|
||||||
|
.help { color: var(--muted); font-size: 13px; margin-top: 8px; }
|
||||||
|
.actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
|
||||||
|
@media (max-width: 900px) { .meta, .items { grid-template-columns: 1fr; } .meta-grid { grid-template-columns: 1fr; } .item:nth-last-child(-n+2) { border-bottom: 1px solid #eef3f8; } .item:last-child { border-bottom: 0; } }
|
||||||
20
backend/workflows/static/workflows/css/release_checklist.css
Normal file
20
backend/workflows/static/workflows/css/release_checklist.css
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
body { margin: 0; font-family: Arial, sans-serif; background: #f4f8ff; color: #1b2b43; padding: 20px; }
|
||||||
|
.shell { max-width: 1120px; margin: 0 auto; }
|
||||||
|
.brand-logo { width: 190px; max-width: 100%; height: auto; margin: 0 0 10px; display: block; }
|
||||||
|
.hero, .panel { background: #fff; border: 1px solid #d7e0ea; border-radius: 16px; box-shadow: 0 20px 40px rgba(17, 58, 116, 0.08); }
|
||||||
|
.hero { padding: 20px; margin-bottom: 18px; }
|
||||||
|
.top { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
|
||||||
|
.eyebrow { display: inline-block; padding: 5px 10px; border-radius: 999px; background: #eef4ff; color: #244a8f; border: 1px solid #d5e2f9; font-size: 12px; font-weight: 700; margin-bottom: 10px; }
|
||||||
|
h1 { margin: 0; color: #000078; font-size: 30px; }
|
||||||
|
.sub { margin: 8px 0 0; color: #5f6f85; max-width: 820px; }
|
||||||
|
.grid { display: grid; grid-template-columns: repeat(2, minmax(320px, 1fr)); gap: 16px; }
|
||||||
|
.panel { padding: 18px; }
|
||||||
|
h2 { margin: 0 0 12px; color: #113a74; font-size: 20px; }
|
||||||
|
ol, ul { margin: 0; padding-left: 20px; }
|
||||||
|
li { margin: 8px 0; color: #334155; }
|
||||||
|
.checklist li { list-style: none; position: relative; padding-left: 28px; }
|
||||||
|
.checklist li::before { content: '\25A1'; position: absolute; left: 0; top: 0; color: #66758c; font-size: 16px; }
|
||||||
|
pre { margin: 12px 0 0; padding: 14px; border-radius: 12px; background: #f7faff; border: 1px solid #dfe8f4; overflow-x: auto; color: #16345f; }
|
||||||
|
code { font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; }
|
||||||
|
.note { margin-top: 16px; padding: 14px 16px; border-radius: 12px; background: #f7faff; border: 1px solid #dfe8f4; color: #355175; }
|
||||||
|
@media (max-width: 820px) { .grid { grid-template-columns: 1fr; } }
|
||||||
863
backend/workflows/static/workflows/css/requests_dashboard.css
Normal file
863
backend/workflows/static/workflows/css/requests_dashboard.css
Normal file
@@ -0,0 +1,863 @@
|
|||||||
|
:root {
|
||||||
|
--brand-blue: #000078;
|
||||||
|
--brand-blue-soft: #1f4fd6;
|
||||||
|
--brand-red: #a32020;
|
||||||
|
--ink: #132238;
|
||||||
|
--muted: #607086;
|
||||||
|
--line: #d9e3ee;
|
||||||
|
--line-strong: #c8d5e5;
|
||||||
|
--panel: rgba(255, 255, 255, 0.9);
|
||||||
|
--panel-strong: #ffffff;
|
||||||
|
--bg-soft: #eef3ff;
|
||||||
|
--ok-bg: #ecf9f0;
|
||||||
|
--ok-ink: #1f7a3f;
|
||||||
|
--warn-bg: #fff6e5;
|
||||||
|
--warn-ink: #9a6400;
|
||||||
|
--danger-bg: #fff1f1;
|
||||||
|
--danger-ink: #982222;
|
||||||
|
--shadow: 0 22px 48px rgba(18, 34, 56, 0.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
* { box-sizing: border-box; }
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
|
||||||
|
color: var(--ink);
|
||||||
|
min-height: 100vh;
|
||||||
|
background:
|
||||||
|
radial-gradient(70% 90% at 8% 8%, rgba(0, 0, 120, 0.14), rgba(0, 0, 120, 0)),
|
||||||
|
radial-gradient(60% 85% at 92% 88%, rgba(163, 32, 32, 0.12), rgba(163, 32, 32, 0)),
|
||||||
|
linear-gradient(160deg, #eef3ff 0%, #f9fbff 48%, #edf4ff 100%);
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shell {
|
||||||
|
width: min(1380px, 100%);
|
||||||
|
margin: 0 auto;
|
||||||
|
background: rgba(255, 255, 255, 0.78);
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
border: 1px solid rgba(217, 227, 238, 0.9);
|
||||||
|
border-radius: 28px;
|
||||||
|
box-shadow: var(--shadow);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 18px;
|
||||||
|
padding: 22px 24px 18px;
|
||||||
|
border-bottom: 1px solid rgba(217, 227, 238, 0.9);
|
||||||
|
background: linear-gradient(180deg, rgba(255,255,255,0.95), rgba(248,251,255,0.84));
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-wrap {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brand-logo {
|
||||||
|
width: 212px;
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quick-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.lang-switch { display:flex; gap:6px; }
|
||||||
|
.lang-btn { border:1px solid var(--line); background:#f8fbff; color:#1f3a5f; border-radius:999px; padding:6px 10px; font-size:12px; font-weight:700; cursor:pointer; }
|
||||||
|
.lang-btn.active { background:var(--brand-blue); border-color:var(--brand-blue); color:#fff; }
|
||||||
|
|
||||||
|
.hero {
|
||||||
|
padding: 0;
|
||||||
|
border-bottom: 0;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1.4fr) minmax(320px, 0.8fr);
|
||||||
|
gap: 12px;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-card,
|
||||||
|
.pulse-card,
|
||||||
|
.controls-card,
|
||||||
|
.table-card,
|
||||||
|
.chart-card,
|
||||||
|
.stat-card {
|
||||||
|
border: 1px solid rgba(217, 227, 238, 0.94);
|
||||||
|
background: var(--panel);
|
||||||
|
border-radius: 22px;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.92);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-card {
|
||||||
|
padding: 14px;
|
||||||
|
background:
|
||||||
|
radial-gradient(100% 140% at 10% 10%, rgba(31,79,214,0.10), rgba(31,79,214,0)),
|
||||||
|
linear-gradient(180deg, rgba(255,255,255,0.99), rgba(248,251,255,0.97));
|
||||||
|
}
|
||||||
|
|
||||||
|
.eyebrow {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid rgba(0,0,120,0.12);
|
||||||
|
background: rgba(0,0,120,0.05);
|
||||||
|
color: var(--brand-blue);
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero h1 {
|
||||||
|
margin: 8px 0 4px;
|
||||||
|
font-size: clamp(24px, 3.6vw, 34px);
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: -0.04em;
|
||||||
|
color: var(--brand-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero p {
|
||||||
|
margin: 0;
|
||||||
|
max-width: 760px;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-pills {
|
||||||
|
margin-top: 12px;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-pill {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
min-height: 34px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-radius: 14px;
|
||||||
|
border: 1px solid rgba(217, 227, 238, 0.96);
|
||||||
|
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(248,251,255,0.96));
|
||||||
|
color: #294465;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.94);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pulse-card {
|
||||||
|
padding: 18px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
min-height: 100%;
|
||||||
|
background:
|
||||||
|
radial-gradient(120% 120% at 100% 0%, rgba(163,32,32,0.10), rgba(163,32,32,0)),
|
||||||
|
linear-gradient(180deg, rgba(255,255,255,0.98), rgba(253,247,247,0.96));
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-card {
|
||||||
|
padding: 18px;
|
||||||
|
background: rgba(255,255,255,0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-card .chart {
|
||||||
|
min-height: 150px;
|
||||||
|
padding-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.activity-card .bar-wrap {
|
||||||
|
min-height: 104px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pulse-card h2 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #1a3359;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pulse-card p {
|
||||||
|
margin: 8px 0 0;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pulse-metrics {
|
||||||
|
margin-top: 18px;
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pulse-metric {
|
||||||
|
padding: 12px 14px;
|
||||||
|
border-radius: 16px;
|
||||||
|
background: rgba(255,255,255,0.86);
|
||||||
|
border: 1px solid rgba(217, 227, 238, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pulse-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--muted);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pulse-value {
|
||||||
|
margin-top: 5px;
|
||||||
|
font-size: 26px;
|
||||||
|
font-weight: 800;
|
||||||
|
color: var(--brand-blue);
|
||||||
|
letter-spacing: -0.03em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metrics-grid {
|
||||||
|
padding: 0;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card {
|
||||||
|
padding: 14px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 110px;
|
||||||
|
border-radius: 18px;
|
||||||
|
box-shadow: 0 10px 24px rgba(18, 33, 56, 0.04), inset 0 1px 0 rgba(255,255,255,0.92);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: auto -24px -36px auto;
|
||||||
|
width: 110px;
|
||||||
|
height: 110px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(31, 79, 214, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.red::before { background: rgba(163, 32, 32, 0.08); }
|
||||||
|
.stat-card.gold::before { background: rgba(194, 137, 26, 0.10); }
|
||||||
|
.stat-card.ink::before { background: rgba(19, 34, 56, 0.08); }
|
||||||
|
|
||||||
|
.stat-head {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-title {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--muted);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-kicker {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 34px;
|
||||||
|
height: 34px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: rgba(0, 0, 120, 0.06);
|
||||||
|
color: var(--brand-blue);
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.red .stat-kicker {
|
||||||
|
background: rgba(163, 32, 32, 0.08);
|
||||||
|
color: var(--brand-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.gold .stat-kicker {
|
||||||
|
background: rgba(194, 137, 26, 0.10);
|
||||||
|
color: #9a6400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-card.ink .stat-kicker {
|
||||||
|
background: rgba(19, 34, 56, 0.08);
|
||||||
|
color: #132238;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
margin-top: 12px;
|
||||||
|
font-size: clamp(24px, 2.6vw, 30px);
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -0.05em;
|
||||||
|
color: var(--ink);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-foot {
|
||||||
|
margin-top: 5px;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.4;
|
||||||
|
max-width: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-grid {
|
||||||
|
padding: 18px 24px 24px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 16px;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-stack {
|
||||||
|
padding: 12px 24px 0;
|
||||||
|
display: grid;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.top-content-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1.5fr) minmax(320px, 1fr);
|
||||||
|
gap: 16px;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-card,
|
||||||
|
.controls-card,
|
||||||
|
.table-card {
|
||||||
|
padding: 14px;
|
||||||
|
background: rgba(255,255,255,0.94);
|
||||||
|
border-radius: 22px;
|
||||||
|
box-shadow: 0 12px 28px rgba(18, 33, 56, 0.045), inset 0 1px 0 rgba(255,255,255,0.92);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-head {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-end;
|
||||||
|
gap: 10px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-head h2 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #18345f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-head p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(14, minmax(0, 1fr));
|
||||||
|
gap: 6px;
|
||||||
|
align-items: end;
|
||||||
|
min-height: 180px;
|
||||||
|
padding-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-col {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-wrap {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 124px;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 34px;
|
||||||
|
background: linear-gradient(180deg, #2b5bda, #071f7d);
|
||||||
|
border-radius: 14px 14px 6px 6px;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.28);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-value {
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #294465;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-label {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--muted);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls-card {
|
||||||
|
position: static;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-form {
|
||||||
|
display: grid;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box input {
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid var(--line-strong);
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 14px 16px;
|
||||||
|
font: inherit;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--ink);
|
||||||
|
background: rgba(255,255,255,0.98);
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.98);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: rgba(0, 0, 120, 0.3);
|
||||||
|
box-shadow: 0 0 0 4px rgba(0, 0, 120, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-help {
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.55;
|
||||||
|
max-width: 70ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-panel {
|
||||||
|
margin-top: 16px;
|
||||||
|
padding-top: 16px;
|
||||||
|
border-top: 1px solid var(--line);
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bulk-toolbar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin: 0;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bulk-info {
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-card {
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 26px;
|
||||||
|
box-shadow: 0 16px 48px rgba(18, 33, 56, 0.06), inset 0 1px 0 rgba(255,255,255,0.92);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-controls {
|
||||||
|
padding: 14px 18px 14px;
|
||||||
|
border-bottom: 1px solid var(--line);
|
||||||
|
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(244,248,255,0.96));
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-controls-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) auto;
|
||||||
|
gap: 14px;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-stack {
|
||||||
|
display: grid;
|
||||||
|
gap: 12px;
|
||||||
|
padding: 14px;
|
||||||
|
border: 1px solid rgba(217, 227, 238, 0.95);
|
||||||
|
border-radius: 18px;
|
||||||
|
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(249,251,255,0.95));
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-card {
|
||||||
|
padding: 18px;
|
||||||
|
background: rgba(255,255,255,0.92);
|
||||||
|
border: 1px solid rgba(217, 227, 238, 0.94);
|
||||||
|
border-radius: 22px;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.92);
|
||||||
|
display: grid;
|
||||||
|
gap: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-head {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 14px;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: 16px 18px 14px;
|
||||||
|
border-bottom: 1px solid var(--line);
|
||||||
|
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(245,249,255,0.96));
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-head h2 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #18345f;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-head p {
|
||||||
|
margin: 5px 0 0;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-head-meta {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 10px 14px;
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid rgba(0, 0, 120, 0.10);
|
||||||
|
background: rgba(0, 0, 120, 0.05);
|
||||||
|
color: var(--brand-blue);
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 800;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-wrap {
|
||||||
|
overflow-x: auto;
|
||||||
|
padding: 0 18px 18px;
|
||||||
|
background: linear-gradient(180deg, rgba(249,251,255,0.72), rgba(255,255,255,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: separate;
|
||||||
|
border-spacing: 0 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
min-width: 980px;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead th {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 2;
|
||||||
|
background: rgba(245,248,252,0.94);
|
||||||
|
color: #5b6b7f;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 11px;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 800;
|
||||||
|
padding: 12px 14px;
|
||||||
|
border-top: 1px solid var(--line);
|
||||||
|
border-bottom: 1px solid var(--line);
|
||||||
|
}
|
||||||
|
|
||||||
|
thead th:first-child {
|
||||||
|
border-left: 1px solid var(--line);
|
||||||
|
border-radius: 14px 0 0 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead th:last-child {
|
||||||
|
border-right: 1px solid var(--line);
|
||||||
|
border-radius: 0 14px 14px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody td {
|
||||||
|
background: rgba(255,255,255,0.98);
|
||||||
|
border-top: 1px solid var(--line);
|
||||||
|
border-bottom: 1px solid var(--line);
|
||||||
|
padding: 15px 14px;
|
||||||
|
vertical-align: middle;
|
||||||
|
box-shadow: 0 8px 22px rgba(26, 51, 89, 0.035);
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody td:first-child {
|
||||||
|
border-left: 1px solid var(--line);
|
||||||
|
border-radius: 18px 0 0 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody td:last-child {
|
||||||
|
border-right: 1px solid var(--line);
|
||||||
|
border-radius: 0 18px 18px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:hover td {
|
||||||
|
background: #fbfdff;
|
||||||
|
border-color: #cad7e8;
|
||||||
|
box-shadow: 0 12px 26px rgba(26, 51, 89, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-col {
|
||||||
|
width: 42px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
th.select-col,
|
||||||
|
td.select-col {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.actions-cell {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.intro-panel {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-col input[type="checkbox"] {
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kind-pill,
|
||||||
|
.status-badge,
|
||||||
|
.doc-link {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 6px;
|
||||||
|
min-height: 38px;
|
||||||
|
padding: 10px 14px;
|
||||||
|
border-radius: 14px;
|
||||||
|
font-weight: 800;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: 0.01em;
|
||||||
|
text-decoration: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
border: 1px solid rgba(217, 227, 238, 0.96);
|
||||||
|
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(248,251,255,0.96));
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.94);
|
||||||
|
}
|
||||||
|
|
||||||
|
.kind-pill {
|
||||||
|
color: #294465;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kind-pill.onboarding {
|
||||||
|
background: linear-gradient(180deg, rgba(245,247,255,0.98), rgba(236,241,255,0.98));
|
||||||
|
border-color: rgba(0, 0, 120, 0.12);
|
||||||
|
color: var(--brand-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.kind-pill.offboarding {
|
||||||
|
background: linear-gradient(180deg, rgba(255,247,247,0.98), rgba(255,240,240,0.98));
|
||||||
|
border-color: rgba(163, 32, 32, 0.14);
|
||||||
|
color: var(--brand-red);
|
||||||
|
}
|
||||||
|
|
||||||
|
.name-cell {
|
||||||
|
display: grid;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.person-name {
|
||||||
|
font-weight: 800;
|
||||||
|
color: var(--ink);
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.person-meta {
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mail-link {
|
||||||
|
color: #294465;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 600;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mail-link:hover { text-decoration: underline; }
|
||||||
|
|
||||||
|
.status-badge.ok {
|
||||||
|
background: linear-gradient(180deg, #f3fcf6, #e8f8ee);
|
||||||
|
color: var(--ok-ink);
|
||||||
|
border-color: #cdeed8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.pending {
|
||||||
|
background: linear-gradient(180deg, #fffaf0, #fff3dc);
|
||||||
|
color: var(--warn-ink);
|
||||||
|
border-color: #f3dfb5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-link {
|
||||||
|
color: var(--brand-blue);
|
||||||
|
background: linear-gradient(180deg, rgba(255,255,255,0.99), rgba(244,248,255,0.98));
|
||||||
|
border-color: rgba(0, 0, 120, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-link:hover {
|
||||||
|
background: linear-gradient(180deg, rgba(248,251,255,0.99), rgba(238,244,255,0.98));
|
||||||
|
border-color: rgba(0, 0, 120, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions-cell { white-space: normal; }
|
||||||
|
.inline-form { display: inline; margin: 0; }
|
||||||
|
.inline-delete { display: inline-flex; align-items: center; }
|
||||||
|
.inline-delete .btn { min-height: 38px; display: inline-flex; align-items: center; justify-content: center; }
|
||||||
|
.intro-panel { min-width: 260px; }
|
||||||
|
|
||||||
|
details {
|
||||||
|
border: 1px solid var(--line);
|
||||||
|
border-radius: 16px;
|
||||||
|
background: linear-gradient(180deg, #ffffff, #f8fbff);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
details[open] {
|
||||||
|
border-color: #cad7e8;
|
||||||
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-toggle {
|
||||||
|
cursor: pointer;
|
||||||
|
list-style: none;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 12px 14px;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #18345f;
|
||||||
|
background: rgba(255,255,255,0.65);
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-toggle::after {
|
||||||
|
content: "+";
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 1;
|
||||||
|
color: var(--brand-blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
details[open] .intro-toggle::after { content: "−"; }
|
||||||
|
.intro-toggle::-webkit-details-marker { display: none; }
|
||||||
|
|
||||||
|
.intro-menu {
|
||||||
|
padding: 0 14px 14px;
|
||||||
|
display: grid;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-group {
|
||||||
|
border-top: 1px solid var(--line);
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-group:first-child {
|
||||||
|
border-top: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-group-title {
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 800;
|
||||||
|
color: var(--muted);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
margin-bottom: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.intro-meta {
|
||||||
|
padding: 0 14px 14px;
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flash {
|
||||||
|
margin: 0 24px 14px;
|
||||||
|
padding: 12px 14px;
|
||||||
|
border-radius: 16px;
|
||||||
|
border: 1px solid rgba(217, 227, 238, 0.9);
|
||||||
|
background: rgba(248, 251, 255, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.flash.success { border-color: #bfe6c9; background: #edf9f1; color: #116634; }
|
||||||
|
.flash.warning { border-color: #f5d8a8; background: #fff8ea; color: #8a5a00; }
|
||||||
|
.flash.error { border-color: #f4c7c7; background: #fff1f1; color: #8e1e1e; }
|
||||||
|
|
||||||
|
.empty-state {
|
||||||
|
text-align: center;
|
||||||
|
color: var(--muted);
|
||||||
|
padding: 26px 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-bar {
|
||||||
|
padding: 0 24px 24px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-note {
|
||||||
|
color: var(--muted);
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1180px) {
|
||||||
|
.hero-grid,
|
||||||
|
.metrics-grid,
|
||||||
|
.top-content-grid,
|
||||||
|
.table-controls-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 760px) {
|
||||||
|
body { padding: 14px; }
|
||||||
|
.topbar,
|
||||||
|
.hero,
|
||||||
|
.metrics-grid,
|
||||||
|
.content-grid,
|
||||||
|
.footer-bar { padding-left: 16px; padding-right: 16px; }
|
||||||
|
.topbar { flex-direction: column; }
|
||||||
|
.quick-actions { justify-content: flex-start; }
|
||||||
|
.table-wrap { padding-left: 12px; padding-right: 12px; }
|
||||||
|
}
|
||||||
6
backend/workflows/static/workflows/css/success_pages.css
Normal file
6
backend/workflows/static/workflows/css/success_pages.css
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
body { margin: 0; font-family: Arial, sans-serif; background: #f4f8ff; color: #1b2b43; padding: 24px; }
|
||||||
|
.shell { background: #fff; border: 1px solid #d7e0ea; border-radius: 16px; padding: 20px; box-shadow: 0 16px 36px rgba(18,34,56,0.10); }
|
||||||
|
h1 { margin: 0 0 10px; color: #000078; }
|
||||||
|
p { margin: 0 0 10px; }
|
||||||
|
code { background: #f4f6fa; padding: 2px 6px; border-radius: 6px; }
|
||||||
|
.actions { display:flex; gap:8px; flex-wrap:wrap; margin-top: 14px; }
|
||||||
51
backend/workflows/static/workflows/js/offboarding_form.js
Normal file
51
backend/workflows/static/workflows/js/offboarding_form.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
(function () {
|
||||||
|
function byName(name) {
|
||||||
|
return document.querySelector('[name="' + name + '"]');
|
||||||
|
}
|
||||||
|
|
||||||
|
function slugifyForEmail(value) {
|
||||||
|
const map = { 'ä': 'ae', 'ö': 'oe', 'ü': 'ue', 'ß': 'ss' };
|
||||||
|
const lower = (value || '').toLowerCase();
|
||||||
|
const mapped = lower.replace(/[äöüß]/g, function (m) { return map[m] || m; });
|
||||||
|
return mapped
|
||||||
|
.normalize('NFD')
|
||||||
|
.replace(/[\u0300-\u036f]/g, '')
|
||||||
|
.replace(/[^a-z0-9]+/g, '.')
|
||||||
|
.replace(/^\.+|\.+$/g, '')
|
||||||
|
.replace(/\.{2,}/g, '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractLastName(fullName) {
|
||||||
|
const parts = (fullName || '').trim().split(/\s+/).filter(Boolean);
|
||||||
|
return parts.length ? parts[parts.length - 1] : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const fullName = byName('full_name');
|
||||||
|
const workEmail = byName('work_email');
|
||||||
|
if (!fullName || !workEmail) return;
|
||||||
|
|
||||||
|
let lastSuggested = '';
|
||||||
|
let userEditedEmail = false;
|
||||||
|
|
||||||
|
function suggestEmail() {
|
||||||
|
const lastName = extractLastName(fullName.value);
|
||||||
|
const slug = slugifyForEmail(lastName);
|
||||||
|
if (!slug) return;
|
||||||
|
const suggestion = slug + '@tub.co';
|
||||||
|
const current = (workEmail.value || '').trim();
|
||||||
|
if (!userEditedEmail || current === '' || current === lastSuggested) {
|
||||||
|
workEmail.value = suggestion;
|
||||||
|
lastSuggested = suggestion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
workEmail.addEventListener('input', function () {
|
||||||
|
const current = (workEmail.value || '').trim();
|
||||||
|
userEditedEmail = current !== '' && current !== lastSuggested;
|
||||||
|
});
|
||||||
|
|
||||||
|
fullName.addEventListener('input', suggestEmail);
|
||||||
|
fullName.addEventListener('change', suggestEmail);
|
||||||
|
fullName.addEventListener('blur', suggestEmail);
|
||||||
|
suggestEmail();
|
||||||
|
}());
|
||||||
253
backend/workflows/static/workflows/js/onboarding_form.js
Normal file
253
backend/workflows/static/workflows/js/onboarding_form.js
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
(function () {
|
||||||
|
const pages = Array.from(document.querySelectorAll('.page'));
|
||||||
|
const navItems = Array.from(document.querySelectorAll('.step-item'));
|
||||||
|
const btnPrev = document.getElementById('btn-prev');
|
||||||
|
const btnNext = document.getElementById('btn-next');
|
||||||
|
const btnSubmit = document.getElementById('btn-submit');
|
||||||
|
const form = document.getElementById('onboarding-form');
|
||||||
|
let current = 0;
|
||||||
|
form.setAttribute('novalidate', 'novalidate');
|
||||||
|
|
||||||
|
function byName(name) { return document.querySelector('[name="' + name + '"]'); }
|
||||||
|
function toggle(id, state) {
|
||||||
|
const el = document.getElementById(id);
|
||||||
|
if (!el) return;
|
||||||
|
el.classList.toggle('hidden', !state);
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncConditionals() {
|
||||||
|
const orderCards = byName('order_business_cards');
|
||||||
|
toggle('business-card-box', orderCards && orderCards.checked);
|
||||||
|
|
||||||
|
const employmentType = byName('employment_type');
|
||||||
|
toggle('employment-end-box', employmentType && employmentType.value === 'befristet');
|
||||||
|
|
||||||
|
const groupMailbox = byName('group_mailboxes_required_choice');
|
||||||
|
toggle('group-mailboxes-box', groupMailbox && groupMailbox.value === 'ja');
|
||||||
|
|
||||||
|
const extraHardware = byName('additional_hardware_needed_choice');
|
||||||
|
toggle('extra-hardware-box', extraHardware && extraHardware.value === 'ja');
|
||||||
|
|
||||||
|
const extraSoftware = byName('additional_software_needed_choice');
|
||||||
|
toggle('extra-software-box', extraSoftware && extraSoftware.value === 'ja');
|
||||||
|
|
||||||
|
const extraAccess = byName('additional_access_needed_choice');
|
||||||
|
toggle('extra-access-box', extraAccess && extraAccess.value === 'ja');
|
||||||
|
|
||||||
|
const successor = byName('successor_required_choice');
|
||||||
|
const showSuccessor = successor && successor.value === 'ja';
|
||||||
|
toggle('successor-box', showSuccessor);
|
||||||
|
|
||||||
|
const inheritPhone = byName('inherit_phone_number_choice');
|
||||||
|
const hidePhone = showSuccessor && inheritPhone && inheritPhone.value === 'ja';
|
||||||
|
toggle('phone-box', !hidePhone);
|
||||||
|
|
||||||
|
// Hidden conditional groups must not block submit with invisible required fields.
|
||||||
|
document.querySelectorAll('.field-group').forEach(function (group) {
|
||||||
|
const hidden = group.classList.contains('hidden');
|
||||||
|
group.querySelectorAll('input, select, textarea').forEach(function (el) {
|
||||||
|
if (el.type === 'hidden' || el.disabled) return;
|
||||||
|
if (hidden) {
|
||||||
|
if (el.required) {
|
||||||
|
el.dataset.requiredOriginal = '1';
|
||||||
|
el.required = false;
|
||||||
|
}
|
||||||
|
} else if (el.dataset.requiredOriginal === '1') {
|
||||||
|
el.required = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function slugifyForEmail(value) {
|
||||||
|
const map = { 'ä': 'ae', 'ö': 'oe', 'ü': 'ue', 'ß': 'ss' };
|
||||||
|
const lower = (value || '').toLowerCase();
|
||||||
|
const mapped = lower.replace(/[äöüß]/g, function (m) { return map[m] || m; });
|
||||||
|
return mapped
|
||||||
|
.normalize('NFD')
|
||||||
|
.replace(/[\u0300-\u036f]/g, '')
|
||||||
|
.replace(/[^a-z0-9]+/g, '.')
|
||||||
|
.replace(/^\.+|\.+$/g, '')
|
||||||
|
.replace(/\.{2,}/g, '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupWorkEmailAutofill() {
|
||||||
|
const lastName = byName('last_name');
|
||||||
|
const workEmail = byName('work_email');
|
||||||
|
if (!lastName || !workEmail) return;
|
||||||
|
|
||||||
|
let lastSuggested = '';
|
||||||
|
let userEditedEmail = !!(workEmail.value && workEmail.value.trim());
|
||||||
|
|
||||||
|
function suggestEmail() {
|
||||||
|
const slug = slugifyForEmail(lastName.value);
|
||||||
|
if (!slug) return;
|
||||||
|
const suggestion = slug + '@tub.co';
|
||||||
|
if (!userEditedEmail || workEmail.value === '' || workEmail.value === lastSuggested) {
|
||||||
|
workEmail.value = suggestion;
|
||||||
|
lastSuggested = suggestion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
workEmail.addEventListener('input', function () {
|
||||||
|
const current = (workEmail.value || '').trim();
|
||||||
|
userEditedEmail = current !== '' && current !== lastSuggested;
|
||||||
|
});
|
||||||
|
|
||||||
|
lastName.addEventListener('input', suggestEmail);
|
||||||
|
suggestEmail();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupBusinessCardAutofill() {
|
||||||
|
const checkbox = byName('order_business_cards');
|
||||||
|
const firstName = byName('first_name');
|
||||||
|
const lastName = byName('last_name');
|
||||||
|
const jobTitle = byName('job_title');
|
||||||
|
const workEmail = byName('work_email');
|
||||||
|
const cardName = byName('business_card_name');
|
||||||
|
const cardTitle = byName('business_card_title');
|
||||||
|
const cardEmail = byName('business_card_email');
|
||||||
|
if (!checkbox || !cardName || !cardTitle || !cardEmail) return;
|
||||||
|
const cardBox = document.getElementById('business-card-box');
|
||||||
|
|
||||||
|
function suggestionName() {
|
||||||
|
const first = (firstName && firstName.value || '').trim();
|
||||||
|
const last = (lastName && lastName.value || '').trim();
|
||||||
|
return [first, last].filter(Boolean).join(' ').trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setField(field, value, force) {
|
||||||
|
if (!field || !value) return;
|
||||||
|
const current = (field.value || '').trim();
|
||||||
|
const autoMarked = field.dataset.autofilled === '1';
|
||||||
|
if (force || !current || autoMarked) {
|
||||||
|
field.value = value;
|
||||||
|
field.dataset.autofilled = '1';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyDefaults(force) {
|
||||||
|
if (!checkbox.checked) return;
|
||||||
|
const name = suggestionName();
|
||||||
|
const title = (jobTitle && jobTitle.value || '').trim();
|
||||||
|
const email = (workEmail && workEmail.value || '').trim();
|
||||||
|
setField(cardName, name, force);
|
||||||
|
setField(cardTitle, title, force);
|
||||||
|
setField(cardEmail, email, force);
|
||||||
|
}
|
||||||
|
|
||||||
|
[cardName, cardTitle, cardEmail].forEach(function (field) {
|
||||||
|
field.addEventListener('input', function () {
|
||||||
|
field.dataset.autofilled = '0';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (cardBox) {
|
||||||
|
const grid = cardBox.querySelector('.grid-2');
|
||||||
|
if (grid && !document.getElementById('business-card-autofill-btn')) {
|
||||||
|
const actionWrap = document.createElement('div');
|
||||||
|
actionWrap.className = 'field field-full';
|
||||||
|
const btn = document.createElement('button');
|
||||||
|
btn.type = 'button';
|
||||||
|
btn.id = 'business-card-autofill-btn';
|
||||||
|
btn.className = 'btn btn-secondary';
|
||||||
|
btn.textContent = 'Visitenkarten-Felder automatisch ausfüllen';
|
||||||
|
btn.addEventListener('click', function () {
|
||||||
|
applyDefaults(true);
|
||||||
|
});
|
||||||
|
actionWrap.appendChild(btn);
|
||||||
|
grid.insertBefore(actionWrap, grid.firstChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Manual-only behavior: fill only when button is clicked.
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupChecklistToggles() {
|
||||||
|
document.querySelectorAll('[data-checklist-toggle]').forEach(function (button) {
|
||||||
|
const panel = button.closest('.itsetup-checklist-panel');
|
||||||
|
if (!panel) return;
|
||||||
|
|
||||||
|
const getCheckboxes = function () {
|
||||||
|
return Array.from(panel.querySelectorAll('input[type="checkbox"]'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const refreshButtonLabel = function () {
|
||||||
|
const checkboxes = getCheckboxes();
|
||||||
|
if (!checkboxes.length) return;
|
||||||
|
const allChecked = checkboxes.every(function (box) { return box.checked; });
|
||||||
|
button.textContent = allChecked ? (button.dataset.labelClear || 'Auswahl aufheben') : (button.dataset.labelSelect || 'Alle auswählen');
|
||||||
|
};
|
||||||
|
|
||||||
|
button.addEventListener('click', function () {
|
||||||
|
const checkboxes = getCheckboxes();
|
||||||
|
if (!checkboxes.length) return;
|
||||||
|
const shouldCheck = checkboxes.some(function (box) { return !box.checked; });
|
||||||
|
checkboxes.forEach(function (box) {
|
||||||
|
box.checked = shouldCheck;
|
||||||
|
box.dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
|
});
|
||||||
|
refreshButtonLabel();
|
||||||
|
});
|
||||||
|
|
||||||
|
getCheckboxes().forEach(function (box) {
|
||||||
|
box.addEventListener('change', refreshButtonLabel);
|
||||||
|
});
|
||||||
|
|
||||||
|
refreshButtonLabel();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupChecklistColumns() {
|
||||||
|
document.querySelectorAll('.itsetup-checklist-body > [id^="id_"]').forEach(function (container) {
|
||||||
|
const itemCount = container.querySelectorAll(':scope > div').length;
|
||||||
|
container.classList.toggle('cols-3', itemCount > 8);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateStep() {
|
||||||
|
pages.forEach((p, i) => p.classList.toggle('active', i === current));
|
||||||
|
navItems.forEach((n, i) => n.classList.toggle('active', i === current));
|
||||||
|
btnPrev.disabled = current === 0;
|
||||||
|
const last = current === pages.length - 1;
|
||||||
|
btnNext.classList.toggle('hidden', last);
|
||||||
|
btnSubmit.classList.toggle('hidden', !last);
|
||||||
|
}
|
||||||
|
|
||||||
|
function jumpToFirstErrorPage() {
|
||||||
|
const firstError = document.querySelector('.errorlist');
|
||||||
|
if (!firstError) return;
|
||||||
|
const page = firstError.closest('.page');
|
||||||
|
if (!page) return;
|
||||||
|
const step = Number(page.getAttribute('data-step') || '1') - 1;
|
||||||
|
current = Math.max(0, step);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('change', syncConditionals);
|
||||||
|
navItems.forEach((n, idx) => {
|
||||||
|
n.addEventListener('click', function () { current = idx; updateStep(); });
|
||||||
|
n.addEventListener('keydown', function (e) {
|
||||||
|
if (e.key === 'Enter' || e.key === ' ') {
|
||||||
|
e.preventDefault();
|
||||||
|
current = idx;
|
||||||
|
updateStep();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
btnPrev.addEventListener('click', function () { if (current > 0) { current -= 1; updateStep(); } });
|
||||||
|
btnNext.addEventListener('click', function () { if (current < pages.length - 1) { current += 1; updateStep(); } });
|
||||||
|
btnSubmit.addEventListener('click', function () {
|
||||||
|
syncConditionals();
|
||||||
|
btnSubmit.disabled = true;
|
||||||
|
btnSubmit.textContent = btnSubmit.dataset.loadingLabel || 'Wird gesendet...';
|
||||||
|
form.submit();
|
||||||
|
});
|
||||||
|
|
||||||
|
syncConditionals();
|
||||||
|
setupWorkEmailAutofill();
|
||||||
|
setupBusinessCardAutofill();
|
||||||
|
setupChecklistToggles();
|
||||||
|
setupChecklistColumns();
|
||||||
|
jumpToFirstErrorPage();
|
||||||
|
updateStep();
|
||||||
|
})();
|
||||||
20
backend/workflows/static/workflows/js/requests_dashboard.js
Normal file
20
backend/workflows/static/workflows/js/requests_dashboard.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
(function () {
|
||||||
|
const selectAll = document.getElementById('select-all');
|
||||||
|
const rowChecks = Array.from(document.querySelectorAll('.row-select'));
|
||||||
|
const selectedCount = document.getElementById('selected-count');
|
||||||
|
if (!selectAll || !selectedCount || !rowChecks.length) return;
|
||||||
|
|
||||||
|
function updateCount() {
|
||||||
|
const checked = rowChecks.filter((c) => c.checked).length;
|
||||||
|
selectedCount.textContent = String(checked);
|
||||||
|
selectAll.checked = checked > 0 && checked === rowChecks.length;
|
||||||
|
selectAll.indeterminate = checked > 0 && checked < rowChecks.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectAll.addEventListener('change', function () {
|
||||||
|
rowChecks.forEach((c) => { c.checked = selectAll.checked; });
|
||||||
|
updateCount();
|
||||||
|
});
|
||||||
|
rowChecks.forEach((c) => c.addEventListener('change', updateCount));
|
||||||
|
updateCount();
|
||||||
|
})();
|
||||||
52
backend/workflows/static/workflows/js/welcome_emails.js
Normal file
52
backend/workflows/static/workflows/js/welcome_emails.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
(function () {
|
||||||
|
const selectAll = document.getElementById('select-all-welcome');
|
||||||
|
const rowChecks = Array.from(document.querySelectorAll('.welcome-select'));
|
||||||
|
const selectedCount = document.getElementById('selected-count');
|
||||||
|
const selectedIds = document.getElementById('selected_ids');
|
||||||
|
const bulkForm = document.getElementById('welcome-bulk-form');
|
||||||
|
const bulkAction = document.getElementById('bulk_action');
|
||||||
|
|
||||||
|
function currentSelected() {
|
||||||
|
return rowChecks.filter((c) => c.checked).map((c) => c.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncState() {
|
||||||
|
const ids = currentSelected();
|
||||||
|
selectedCount.textContent = String(ids.length);
|
||||||
|
selectedIds.value = ids.join(',');
|
||||||
|
if (!rowChecks.length) {
|
||||||
|
selectAll.checked = false;
|
||||||
|
selectAll.indeterminate = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selectAll.checked = ids.length > 0 && ids.length === rowChecks.length;
|
||||||
|
selectAll.indeterminate = ids.length > 0 && ids.length < rowChecks.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectAll.addEventListener('change', function () {
|
||||||
|
rowChecks.forEach((c) => { c.checked = selectAll.checked; });
|
||||||
|
syncState();
|
||||||
|
});
|
||||||
|
|
||||||
|
rowChecks.forEach((c) => c.addEventListener('change', syncState));
|
||||||
|
bulkForm.addEventListener('submit', syncState);
|
||||||
|
|
||||||
|
window.confirmBulkAction = function () {
|
||||||
|
syncState();
|
||||||
|
const count = currentSelected().length;
|
||||||
|
if (!count) {
|
||||||
|
alert(bulkForm.dataset.alertEmpty || 'Bitte mindestens einen Welcome-Eintrag auswählen.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const action = bulkAction.value;
|
||||||
|
if (action === 'delete') {
|
||||||
|
return confirm(bulkForm.dataset.confirmDelete || 'Ausgewählte Welcome-Einträge wirklich löschen?');
|
||||||
|
}
|
||||||
|
if (action === 'pause') {
|
||||||
|
return confirm(bulkForm.dataset.confirmPause || 'Ausgewählte Welcome-Einträge pausieren?');
|
||||||
|
}
|
||||||
|
return confirm(bulkForm.dataset.confirmSend || 'Ausgewählte Welcome-Einträge sofort senden?');
|
||||||
|
};
|
||||||
|
|
||||||
|
syncState();
|
||||||
|
})();
|
||||||
@@ -3,26 +3,20 @@
|
|||||||
|
|
||||||
{% block title %}{% trans "Anmeldung" %}{% endblock %}
|
{% block title %}{% trans "Anmeldung" %}{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
<style>
|
|
||||||
body { margin: 0; font-family: Arial, sans-serif; min-height: 100vh; background: linear-gradient(160deg, #eef6ff, #fff3f3); padding: 24px; }
|
|
||||||
.card { width: min(420px, calc(100% - 28px)); margin: 0 auto; background: #fff; border: 1px solid #d9e3f0; border-radius: 14px; padding: 20px; box-shadow: 0 12px 30px rgba(28, 45, 79, 0.12); }
|
|
||||||
h1 { margin: 0 0 8px; font-size: 24px; }
|
|
||||||
p { margin: 0 0 14px; color: #607086; }
|
|
||||||
.field { margin-bottom: 12px; }
|
|
||||||
label { display: block; font-weight: 600; margin-bottom: 6px; }
|
|
||||||
input { width: 100%; padding: 10px; box-sizing: border-box; border: 1px solid #cbd5e1; border-radius: 8px; }
|
|
||||||
.btn { width: 100%; }
|
|
||||||
.errorlist { color: #b91c1c; margin: 6px 0; }
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block shell_header %}
|
{% block shell_header %}
|
||||||
{% include 'workflows/includes/app_header.html' %}
|
{% include 'workflows/includes/app_header.html' with header_inside_shell=1 %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_css %}
|
||||||
|
<link rel="stylesheet" href="{% static 'workflows/css/login.css' %}" />
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block shell_body %}
|
{% block shell_body %}
|
||||||
<div class="card"><h1>{% trans "Anmeldung" %}</h1>
|
<section class="login-shell-body">
|
||||||
|
<div class="login-card">
|
||||||
|
<h1>{% trans "Anmeldung" %}</h1>
|
||||||
<p>{% trans "Bitte melden Sie sich mit Ihrem Benutzerkonto an." %}</p>
|
<p>{% trans "Bitte melden Sie sich mit Ihrem Benutzerkonto an." %}</p>
|
||||||
|
|
||||||
<form method="post" action="/accounts/login/">
|
<form method="post" action="/accounts/login/">
|
||||||
@@ -35,6 +29,5 @@
|
|||||||
<button class="btn btn-primary" type="submit">{% trans "Anmelden" %}</button>
|
<button class="btn btn-primary" type="submit">{% trans "Anmelden" %}</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,25 +3,10 @@
|
|||||||
|
|
||||||
{% block title %}Developer Handbook{% endblock %}
|
{% block title %}Developer Handbook{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
<style>
|
|
||||||
body { margin: 0; font-family: Arial, sans-serif; background: #f4f8ff; color: #1b2b43; padding: 20px; }
|
{% block extra_css %}
|
||||||
.shell { max-width: 1120px; margin: 0 auto; background: #fff; border: 1px solid #d7e0ea; border-radius: 14px; padding: 18px; }
|
<link rel="stylesheet" href="{% static 'workflows/css/docs_pages.css' %}" />
|
||||||
.brand-logo { width: 190px; max-width: 100%; height: auto; margin: 0 0 10px; display: block; }
|
|
||||||
.top { display: flex; justify-content: space-between; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; }
|
|
||||||
h1 { margin: 0; color: #000078; font-size: 30px; }
|
|
||||||
.sub { margin: 8px 0 16px; color: #5f6f85; }
|
|
||||||
.toc { border: 1px solid #d7e0ea; border-radius: 10px; padding: 10px; background: #f7fbff; margin-bottom: 16px; }
|
|
||||||
.toc a { color: #0b4da2; text-decoration: none; margin-right: 10px; white-space: nowrap; }
|
|
||||||
h2 { margin: 20px 0 8px; color: #113a74; border-bottom: 1px solid #e1e8f2; padding-bottom: 4px; }
|
|
||||||
h3 { margin: 14px 0 6px; color: #183f77; }
|
|
||||||
ul { margin: 8px 0 12px 20px; }
|
|
||||||
li { margin: 4px 0; }
|
|
||||||
code { background: #f1f5fb; border: 1px solid #dce6f3; border-radius: 6px; padding: 2px 6px; }
|
|
||||||
pre { background: #f7fbff; border: 1px solid #dce6f3; border-radius: 10px; padding: 10px; overflow-x: auto; }
|
|
||||||
.box { border: 1px solid #d7e0ea; border-radius: 10px; padding: 10px; background: #fcfdff; margin: 8px 0 12px; }
|
|
||||||
.note { border-left: 4px solid #000078; padding: 8px 10px; background: #f4f8ff; margin: 10px 0; }
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block shell_body %}
|
{% block shell_body %}
|
||||||
|
|||||||
@@ -3,24 +3,10 @@
|
|||||||
|
|
||||||
{% block title %}{% trans "Handbook" %}{% endblock %}
|
{% block title %}{% trans "Handbook" %}{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
<style>
|
|
||||||
body { margin: 0; font-family: Arial, sans-serif; background: #f4f8ff; color: #1b2b43; padding: 20px; }
|
{% block extra_css %}
|
||||||
.shell { max-width: 1120px; margin: 0 auto; background: #fff; border: 1px solid #d7e0ea; border-radius: 14px; padding: 18px; }
|
<link rel="stylesheet" href="{% static 'workflows/css/docs_pages.css' %}" />
|
||||||
.brand-logo { width: 190px; max-width: 100%; height: auto; margin: 0 0 10px; display: block; }
|
|
||||||
.top { display: flex; justify-content: space-between; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; }
|
|
||||||
h1 { margin: 0; color: #000078; font-size: 30px; }
|
|
||||||
.sub { margin: 8px 0 18px; color: #5f6f85; max-width: 760px; }
|
|
||||||
.grid { display: grid; grid-template-columns: repeat(3, minmax(260px, 1fr)); gap: 14px; }
|
|
||||||
.card { border: 1px solid #d7e0ea; border-radius: 14px; background: #fcfdff; padding: 16px; }
|
|
||||||
.eyebrow { display: inline-block; padding: 5px 10px; border-radius: 999px; background: #eef4ff; color: #244a8f; border: 1px solid #d5e2f9; font-size: 12px; font-weight: 700; margin-bottom: 10px; }
|
|
||||||
h2 { margin: 0 0 8px; color: #113a74; }
|
|
||||||
p { margin: 0 0 14px; color: #5f6f85; }
|
|
||||||
ul { margin: 0 0 14px 18px; color: #334155; }
|
|
||||||
li { margin: 4px 0; }
|
|
||||||
.actions { display: flex; gap: 8px; flex-wrap: wrap; }
|
|
||||||
@media (max-width: 760px) { .grid { grid-template-columns: 1fr; } }
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block shell_body %}
|
{% block shell_body %}
|
||||||
|
|||||||
@@ -3,441 +3,10 @@
|
|||||||
|
|
||||||
{% block title %}{% trans "TUBCO Onboarding & Offboarding Portal" %}{% endblock %}
|
{% block title %}{% trans "TUBCO Onboarding & Offboarding Portal" %}{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
<style>
|
|
||||||
:root {
|
|
||||||
--brand-blue: #000078;
|
|
||||||
--brand-red: #8c1d1d;
|
|
||||||
--ink: #102039;
|
|
||||||
--muted: #5f6f85;
|
|
||||||
--line: #d8e1ee;
|
|
||||||
--panel: #ffffff;
|
|
||||||
--bg-soft: #eff4ff;
|
|
||||||
--ok-bg: #effaf2;
|
|
||||||
--ok-ink: #166534;
|
|
||||||
--warn-bg: #fff6ea;
|
|
||||||
--warn-ink: #8a4f00;
|
|
||||||
}
|
|
||||||
|
|
||||||
* { box-sizing: border-box; }
|
|
||||||
|
|
||||||
body {
|
{% block extra_css %}
|
||||||
margin: 0;
|
<link rel="stylesheet" href="{% static 'workflows/css/home.css' %}" />
|
||||||
font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
|
|
||||||
color: var(--ink);
|
|
||||||
background:
|
|
||||||
radial-gradient(80% 120% at 85% 8%, rgba(0, 0, 120, 0.12), rgba(0, 0, 120, 0)),
|
|
||||||
radial-gradient(70% 90% at 8% 92%, rgba(140, 29, 29, 0.10), rgba(140, 29, 29, 0)),
|
|
||||||
linear-gradient(165deg, #eef3ff, #f7f9ff 48%, #f0f5ff);
|
|
||||||
min-height: 100vh;
|
|
||||||
padding: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shell {
|
|
||||||
width: min(1380px, 100%);
|
|
||||||
margin: 0 auto;
|
|
||||||
background: var(--panel);
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 20px;
|
|
||||||
box-shadow: 0 20px 44px rgba(16, 32, 57, 0.13);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topbar {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: flex-start;
|
|
||||||
gap: 16px;
|
|
||||||
padding: 18px 22px;
|
|
||||||
border-bottom: 1px solid var(--line);
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.brand-wrap {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.brand-logo {
|
|
||||||
width: 210px;
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
display: block;
|
|
||||||
margin: 0;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.quick-actions {
|
|
||||||
display: flex;
|
|
||||||
gap: 8px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.lang-switch { display:flex; gap:6px; }
|
|
||||||
.lang-btn { border:1px solid var(--line); background:#f8fbff; color:#1f3a5f; border-radius:999px; padding:6px 10px; font-size:12px; font-weight:700; cursor:pointer; }
|
|
||||||
.lang-btn.active { background:var(--brand-blue); border-color:var(--brand-blue); color:#fff; }
|
|
||||||
|
|
||||||
.hero {
|
|
||||||
padding: 24px;
|
|
||||||
border-bottom: 1px solid var(--line);
|
|
||||||
background:
|
|
||||||
linear-gradient(135deg, rgba(0, 0, 120, 0.08), rgba(0, 0, 120, 0) 44%),
|
|
||||||
linear-gradient(180deg, rgba(255,255,255,0.96), rgba(246,250,255,0.92));
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
gap: 18px;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-card,
|
|
||||||
.hero-sidecard {
|
|
||||||
border: 1px solid rgba(217, 227, 238, 0.94);
|
|
||||||
background: rgba(255,255,255,0.92);
|
|
||||||
border-radius: 22px;
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.92);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-card {
|
|
||||||
padding: 24px;
|
|
||||||
background:
|
|
||||||
radial-gradient(100% 140% at 10% 10%, rgba(31,79,214,0.12), rgba(31,79,214,0)),
|
|
||||||
linear-gradient(180deg, rgba(255,255,255,0.98), rgba(247,250,255,0.95));
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-sidecard {
|
|
||||||
padding: 18px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
background:
|
|
||||||
radial-gradient(120% 120% at 100% 0%, rgba(163,32,32,0.10), rgba(163,32,32,0)),
|
|
||||||
linear-gradient(180deg, rgba(255,255,255,0.98), rgba(253,247,247,0.96));
|
|
||||||
}
|
|
||||||
|
|
||||||
.eyebrow {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 6px 10px;
|
|
||||||
border-radius: 999px;
|
|
||||||
border: 1px solid rgba(0,0,120,0.12);
|
|
||||||
background: rgba(0,0,120,0.05);
|
|
||||||
color: var(--brand-blue);
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 700;
|
|
||||||
letter-spacing: 0.03em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero h1 {
|
|
||||||
margin: 14px 0 8px;
|
|
||||||
font-size: clamp(30px, 5vw, 46px);
|
|
||||||
line-height: 1;
|
|
||||||
letter-spacing: -0.04em;
|
|
||||||
color: var(--brand-blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--muted);
|
|
||||||
max-width: 720px;
|
|
||||||
font-size: 15px;
|
|
||||||
line-height: 1.55;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-row {
|
|
||||||
margin-top: 16px;
|
|
||||||
display: flex;
|
|
||||||
gap: 8px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-pill {
|
|
||||||
border-radius: 999px;
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
background: #fff;
|
|
||||||
color: #30445f;
|
|
||||||
padding: 8px 12px;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-pill.ok {
|
|
||||||
background: var(--ok-bg);
|
|
||||||
color: var(--ok-ink);
|
|
||||||
border-color: #c7ecd2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-pill.warn {
|
|
||||||
background: var(--warn-bg);
|
|
||||||
color: var(--warn-ink);
|
|
||||||
border-color: #f7dfbb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-sidecard h2 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #1a3359;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-sidecard p {
|
|
||||||
margin: 8px 0 0;
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-metrics {
|
|
||||||
margin-top: 18px;
|
|
||||||
display: grid;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-metric {
|
|
||||||
padding: 12px 14px;
|
|
||||||
border-radius: 16px;
|
|
||||||
background: rgba(255,255,255,0.86);
|
|
||||||
border: 1px solid rgba(217, 227, 238, 0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-metric-label {
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--muted);
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.04em;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-metric-value {
|
|
||||||
margin-top: 5px;
|
|
||||||
font-size: 26px;
|
|
||||||
font-weight: 800;
|
|
||||||
color: var(--brand-blue);
|
|
||||||
letter-spacing: -0.03em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main {
|
|
||||||
padding: 20px 22px 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-head {
|
|
||||||
margin: 0 0 12px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 10px;
|
|
||||||
align-items: flex-end;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-head h2 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 19px;
|
|
||||||
color: #172b4a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-head p {
|
|
||||||
margin: 0;
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.apps-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
||||||
gap: 14px;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-card {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
border: 1px solid rgba(217, 227, 238, 0.94);
|
|
||||||
border-radius: 22px;
|
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(247,250,255,0.95));
|
|
||||||
padding: 18px;
|
|
||||||
min-height: 222px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.92);
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-card::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
inset: auto -24px -38px auto;
|
|
||||||
width: 118px;
|
|
||||||
height: 118px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: rgba(31, 79, 214, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-card.primary {
|
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.99), rgba(242,247,255,0.97));
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-card.red {
|
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.99), rgba(255,245,245,0.97));
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-card.red::before { background: rgba(163, 32, 32, 0.08); }
|
|
||||||
|
|
||||||
.app-card .top-line {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: flex-start;
|
|
||||||
gap: 12px;
|
|
||||||
margin-bottom: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.accent {
|
|
||||||
width: 38px;
|
|
||||||
height: 38px;
|
|
||||||
border-radius: 14px;
|
|
||||||
background: rgba(0, 0, 120, 0.06);
|
|
||||||
color: var(--brand-blue);
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 800;
|
|
||||||
letter-spacing: 0.04em;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.accent.red {
|
|
||||||
background: rgba(163, 32, 32, 0.08);
|
|
||||||
color: var(--brand-red);
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-title {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 1.05;
|
|
||||||
letter-spacing: -0.03em;
|
|
||||||
color: var(--ink);
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-text {
|
|
||||||
margin: 10px 0 12px;
|
|
||||||
color: #5a6a81;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.5;
|
|
||||||
max-width: 34ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-row {
|
|
||||||
display: flex;
|
|
||||||
gap: 8px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
border: 1px solid rgba(217, 227, 238, 0.96);
|
|
||||||
border-radius: 14px;
|
|
||||||
padding: 7px 10px;
|
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(248,251,255,0.96));
|
|
||||||
color: #486183;
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 800;
|
|
||||||
letter-spacing: 0.03em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-actions {
|
|
||||||
display: flex;
|
|
||||||
gap: 8px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.admin-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.admin-card {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
border: 1px solid rgba(217, 227, 238, 0.94);
|
|
||||||
border-radius: 18px;
|
|
||||||
padding: 14px;
|
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.99), rgba(247,250,255,0.96));
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.92);
|
|
||||||
}
|
|
||||||
|
|
||||||
.admin-card::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
inset: auto -18px -30px auto;
|
|
||||||
width: 84px;
|
|
||||||
height: 84px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: rgba(31, 79, 214, 0.06);
|
|
||||||
}
|
|
||||||
|
|
||||||
.admin-card h3 {
|
|
||||||
margin: 0 0 7px;
|
|
||||||
font-size: 15px;
|
|
||||||
color: #18345f;
|
|
||||||
letter-spacing: -0.01em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.admin-card p {
|
|
||||||
margin: 0 0 11px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #607088;
|
|
||||||
min-height: 34px;
|
|
||||||
line-height: 1.45;
|
|
||||||
max-width: 26ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.msg {
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 10px 12px;
|
|
||||||
margin: 0 0 14px;
|
|
||||||
border: 1px solid #d6e1ef;
|
|
||||||
background: #f8fbff;
|
|
||||||
color: #1f3a5f;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.msg.error {
|
|
||||||
border-color: #fecaca;
|
|
||||||
background: #fff1f2;
|
|
||||||
color: #991b1b;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-note {
|
|
||||||
margin-top: 16px;
|
|
||||||
border-top: 1px solid var(--line);
|
|
||||||
padding-top: 12px;
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 1080px) {
|
|
||||||
.hero-grid { grid-template-columns: 1fr; }
|
|
||||||
.apps-grid { grid-template-columns: 1fr 1fr; }
|
|
||||||
.admin-grid { grid-template-columns: 1fr 1fr; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 760px) {
|
|
||||||
body { padding: 12px; }
|
|
||||||
.topbar, .hero, .main { padding-left: 14px; padding-right: 14px; }
|
|
||||||
.hero h1 { font-size: 28px; }
|
|
||||||
.apps-grid, .admin-grid { grid-template-columns: 1fr; }
|
|
||||||
.quick-actions { justify-content: flex-start; }
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block shell_body %}
|
{% block shell_body %}
|
||||||
|
|||||||
@@ -3,70 +3,10 @@
|
|||||||
|
|
||||||
{% block title %}{% trans "Integrationen Setup" %}{% endblock %}
|
{% block title %}{% trans "Integrationen Setup" %}{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
<style>
|
|
||||||
body { margin: 0; font-family: Arial, sans-serif; background: #f4f8ff; color: #0f172a; padding: 20px; }
|
{% block extra_css %}
|
||||||
.shell { max-width: 980px; margin: 0 auto; background: #fff; border: 1px solid #d8e3f0; border-radius: 14px; padding: 16px; }
|
<link rel="stylesheet" href="{% static 'workflows/css/admin_tools.css' %}" />
|
||||||
.topbar { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
|
|
||||||
.brand-logo { width: 190px; max-width: 100%; height: auto; display: block; }
|
|
||||||
h1 { margin: 12px 0 6px; color: #000078; }
|
|
||||||
.sub { margin: 0 0 12px; color: #54657c; }
|
|
||||||
.switch { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
|
|
||||||
.switch .tab {
|
|
||||||
border: 1px solid #c9d6e7; border-radius: 999px; padding: 8px 14px; text-decoration: none;
|
|
||||||
color: #1f2f49; font-weight: 700; background: #f6f9ff;
|
|
||||||
}
|
|
||||||
.switch .tab.active { background: #000078; color: #fff; border-color: #000078; }
|
|
||||||
.msg { border-radius: 10px; padding: 10px 12px; margin: 0 0 12px; border: 1px solid #d6e1ef; background: #f8fbff; color: #1f3a5f; }
|
|
||||||
.msg.error { border-color: #fecaca; background: #fff1f2; color: #991b1b; }
|
|
||||||
.card { border: 1px solid #d8e3f0; border-radius: 12px; background: #fbfdff; padding: 12px; }
|
|
||||||
.grid { display: grid; grid-template-columns: repeat(2, minmax(240px, 1fr)); gap: 10px; }
|
|
||||||
label { display: block; margin-bottom: 4px; font-size: 12px; color: #334155; font-weight: 700; }
|
|
||||||
input { width: 100%; box-sizing: border-box; border: 1px solid #cbd5e1; border-radius: 8px; padding: 8px 9px; }
|
|
||||||
select { width: 100%; box-sizing: border-box; border: 1px solid #cbd5e1; border-radius: 8px; padding: 8px 9px; background: #fff; }
|
|
||||||
.check-row { margin-top: 8px; display: flex; gap: 12px; flex-wrap: wrap; }
|
|
||||||
.check-row label { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: 13px; }
|
|
||||||
.check-row input[type="checkbox"] { width: auto; }
|
|
||||||
.actions { margin-top: 10px; display: flex; gap: 8px; flex-wrap: wrap; }
|
|
||||||
.hint { margin-top: 6px; color: #64748b; font-size: 12px; }
|
|
||||||
.template-block {
|
|
||||||
border: 1px solid #d8e3f0;
|
|
||||||
border-radius: 10px;
|
|
||||||
background: #fff;
|
|
||||||
padding: 10px;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
.template-title {
|
|
||||||
margin: 0 0 8px;
|
|
||||||
color: #24344e;
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.rule-card {
|
|
||||||
margin-top: 12px;
|
|
||||||
border: 1px solid #d8e3f0;
|
|
||||||
border-radius: 12px;
|
|
||||||
padding: 10px;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
.rule-title {
|
|
||||||
margin: 0 0 8px;
|
|
||||||
color: #23344f;
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
textarea {
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
border: 1px solid #cbd5e1;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 8px 9px;
|
|
||||||
min-height: 120px;
|
|
||||||
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
@media (max-width: 760px) { .grid { grid-template-columns: 1fr; } }
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block shell_body %}
|
{% block shell_body %}
|
||||||
|
|||||||
@@ -3,32 +3,10 @@
|
|||||||
|
|
||||||
{% block title %}{% trans "Einweisungs-Builder" %}{% endblock %}
|
{% block title %}{% trans "Einweisungs-Builder" %}{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
<style>
|
|
||||||
body { margin: 0; font-family: Arial, sans-serif; background: #f4f8ff; color: #1b2b43; padding: 20px; }
|
{% block extra_css %}
|
||||||
.shell { max-width: 1180px; margin: 0 auto; background: #fff; border: 1px solid #d7e0ea; border-radius: 14px; padding: 18px; }
|
<link rel="stylesheet" href="{% static 'workflows/css/admin_tools.css' %}" />
|
||||||
.topbar { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
|
|
||||||
.brand-logo { width: 190px; max-width: 100%; height: auto; display: block; }
|
|
||||||
h1 { margin: 0; color: #000078; font-size: 28px; }
|
|
||||||
.sub { margin: 8px 0 14px; color: #5f6f85; }
|
|
||||||
.flash { margin: 0 0 12px; padding: 10px; border-radius: 8px; border: 1px solid #dbe5f2; background: #f8fbff; }
|
|
||||||
.flash.error { border-color: #f4c7c7; background: #fff1f1; color: #8e1e1e; }
|
|
||||||
.flash.success { border-color: #bfe6c9; background: #edf9f1; color: #116634; }
|
|
||||||
.card { border: 1px solid #d7e0ea; border-radius: 12px; padding: 14px; background: #fcfdff; margin-bottom: 14px; }
|
|
||||||
.grid { display: grid; grid-template-columns: 1.1fr 1.4fr 1fr 1fr 1fr auto; gap: 10px; align-items: end; }
|
|
||||||
.field label { display: block; font-weight: 600; margin-bottom: 6px; }
|
|
||||||
.field input, .field select { width: 100%; min-height: 40px; padding: 8px 10px; border: 1px solid #cfd9e8; border-radius: 8px; box-sizing: border-box; }
|
|
||||||
.table-wrap { overflow-x: auto; }
|
|
||||||
table { width: 100%; border-collapse: collapse; }
|
|
||||||
th, td { border: 1px solid #e2e8f0; padding: 8px; text-align: left; vertical-align: top; }
|
|
||||||
th { background: #f6f8fb; color: #334155; }
|
|
||||||
.mini { color: #64748b; font-size: 12px; }
|
|
||||||
.hint { margin-top: 6px; color: #5f6f85; font-size: 13px; }
|
|
||||||
.table-controls input[type="text"], .table-controls select { width: 100%; min-height: 36px; padding: 7px 9px; border: 1px solid #cfd9e8; border-radius: 8px; box-sizing: border-box; }
|
|
||||||
.table-controls input[type="checkbox"] { transform: scale(1.1); }
|
|
||||||
.actions { white-space: nowrap; }
|
|
||||||
.toolbar { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block shell_body %}
|
{% block shell_body %}
|
||||||
|
|||||||
@@ -69,57 +69,6 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_scripts %}
|
{% block extra_scripts %}
|
||||||
<script>(function () {
|
<script src="{% static 'workflows/js/offboarding_form.js' %}"></script>
|
||||||
function byName(name) {
|
|
||||||
return document.querySelector('[name="' + name + '"]');
|
|
||||||
}
|
|
||||||
|
|
||||||
function slugifyForEmail(value) {
|
|
||||||
const map = { 'ä': 'ae', 'ö': 'oe', 'ü': 'ue', 'ß': 'ss' };
|
|
||||||
const lower = (value || '').toLowerCase();
|
|
||||||
const mapped = lower.replace(/[äöüß]/g, function (m) { return map[m] || m; });
|
|
||||||
return mapped
|
|
||||||
.normalize('NFD')
|
|
||||||
.replace(/[\u0300-\u036f]/g, '')
|
|
||||||
.replace(/[^a-z0-9]+/g, '.')
|
|
||||||
.replace(/^\.+|\.+$/g, '')
|
|
||||||
.replace(/\.{2,}/g, '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractLastName(fullName) {
|
|
||||||
const parts = (fullName || '').trim().split(/\s+/).filter(Boolean);
|
|
||||||
return parts.length ? parts[parts.length - 1] : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const fullName = byName('full_name');
|
|
||||||
const workEmail = byName('work_email');
|
|
||||||
if (!fullName || !workEmail) return;
|
|
||||||
|
|
||||||
let lastSuggested = '';
|
|
||||||
let userEditedEmail = false;
|
|
||||||
|
|
||||||
function suggestEmail() {
|
|
||||||
const lastName = extractLastName(fullName.value);
|
|
||||||
const slug = slugifyForEmail(lastName);
|
|
||||||
if (!slug) return;
|
|
||||||
const suggestion = slug + '@tub.co';
|
|
||||||
const current = (workEmail.value || '').trim();
|
|
||||||
if (!userEditedEmail || current === '' || current === lastSuggested) {
|
|
||||||
workEmail.value = suggestion;
|
|
||||||
lastSuggested = suggestion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
workEmail.addEventListener('input', function () {
|
|
||||||
const current = (workEmail.value || '').trim();
|
|
||||||
userEditedEmail = current !== '' && current !== lastSuggested;
|
|
||||||
});
|
|
||||||
|
|
||||||
fullName.addEventListener('input', suggestEmail);
|
|
||||||
fullName.addEventListener('change', suggestEmail);
|
|
||||||
fullName.addEventListener('blur', suggestEmail);
|
|
||||||
suggestEmail();
|
|
||||||
}());
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
@@ -3,21 +3,16 @@
|
|||||||
|
|
||||||
{% block title %}{% trans "Offboarding gespeichert" %}{% endblock %}
|
{% block title %}{% trans "Offboarding gespeichert" %}{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
<style>
|
|
||||||
body { margin: 0; font-family: Arial, sans-serif; background: #f4f8ff; color: #1b2b43; padding: 24px; }
|
|
||||||
.shell { background: #fff; border: 1px solid #d7e0ea; border-radius: 16px; padding: 20px; box-shadow: 0 16px 36px rgba(18,34,56,0.10); }
|
|
||||||
h1 { margin: 0 0 10px; color: #000078; }
|
|
||||||
p { margin: 0 0 10px; }
|
|
||||||
code { background: #f4f6fa; padding: 2px 6px; border-radius: 6px; }
|
|
||||||
.actions { display:flex; gap:8px; flex-wrap:wrap; margin-top: 14px; }
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block shell_header %}
|
{% block shell_header %}
|
||||||
{% include 'workflows/includes/app_header.html' with header_show_home=1 %}
|
{% include 'workflows/includes/app_header.html' with header_show_home=1 %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_css %}
|
||||||
|
<link rel="stylesheet" href="{% static 'workflows/css/success_pages.css' %}" />
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block shell_body %}
|
{% block shell_body %}
|
||||||
<h1>{% trans "Offboarding gespeichert" %}</h1>
|
<h1>{% trans "Offboarding gespeichert" %}</h1>
|
||||||
<p>{% trans "Vorgangs-ID:" %} <code>{{ obj.id }}</code></p>
|
<p>{% trans "Vorgangs-ID:" %} <code>{{ obj.id }}</code></p>
|
||||||
|
|||||||
@@ -154,7 +154,7 @@
|
|||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button class="btn btn-secondary" type="button" id="btn-prev">{% trans "Zurück" %}</button>
|
<button class="btn btn-secondary" type="button" id="btn-prev">{% trans "Zurück" %}</button>
|
||||||
<button class="btn btn-primary" type="button" id="btn-next">{% trans "Weiter" %}</button>
|
<button class="btn btn-primary" type="button" id="btn-next">{% trans "Weiter" %}</button>
|
||||||
<button type="submit" id="btn-submit" class="btn btn-primary hidden">{% trans "Onboarding-Anfrage absenden" %}</button>
|
<button type="submit" id="btn-submit" class="btn btn-primary hidden" data-loading-label="{% trans 'Wird gesendet...' %}">{% trans "Onboarding-Anfrage absenden" %}</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</main>
|
</main>
|
||||||
@@ -163,259 +163,6 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_scripts %}
|
{% block extra_scripts %}
|
||||||
<script>(function () {
|
<script src="{% static 'workflows/js/onboarding_form.js' %}"></script>
|
||||||
const pages = Array.from(document.querySelectorAll('.page'));
|
|
||||||
const navItems = Array.from(document.querySelectorAll('.step-item'));
|
|
||||||
const btnPrev = document.getElementById('btn-prev');
|
|
||||||
const btnNext = document.getElementById('btn-next');
|
|
||||||
const btnSubmit = document.getElementById('btn-submit');
|
|
||||||
const form = document.getElementById('onboarding-form');
|
|
||||||
let current = 0;
|
|
||||||
form.setAttribute('novalidate', 'novalidate');
|
|
||||||
|
|
||||||
function byName(name) { return document.querySelector('[name="' + name + '"]'); }
|
|
||||||
function toggle(id, state) {
|
|
||||||
const el = document.getElementById(id);
|
|
||||||
if (!el) return;
|
|
||||||
el.classList.toggle('hidden', !state);
|
|
||||||
}
|
|
||||||
|
|
||||||
function syncConditionals() {
|
|
||||||
const orderCards = byName('order_business_cards');
|
|
||||||
toggle('business-card-box', orderCards && orderCards.checked);
|
|
||||||
|
|
||||||
const employmentType = byName('employment_type');
|
|
||||||
toggle('employment-end-box', employmentType && employmentType.value === 'befristet');
|
|
||||||
|
|
||||||
const groupMailbox = byName('group_mailboxes_required_choice');
|
|
||||||
toggle('group-mailboxes-box', groupMailbox && groupMailbox.value === 'ja');
|
|
||||||
|
|
||||||
const extraHardware = byName('additional_hardware_needed_choice');
|
|
||||||
toggle('extra-hardware-box', extraHardware && extraHardware.value === 'ja');
|
|
||||||
|
|
||||||
const extraSoftware = byName('additional_software_needed_choice');
|
|
||||||
toggle('extra-software-box', extraSoftware && extraSoftware.value === 'ja');
|
|
||||||
|
|
||||||
const extraAccess = byName('additional_access_needed_choice');
|
|
||||||
toggle('extra-access-box', extraAccess && extraAccess.value === 'ja');
|
|
||||||
|
|
||||||
const successor = byName('successor_required_choice');
|
|
||||||
const showSuccessor = successor && successor.value === 'ja';
|
|
||||||
toggle('successor-box', showSuccessor);
|
|
||||||
|
|
||||||
const inheritPhone = byName('inherit_phone_number_choice');
|
|
||||||
const hidePhone = showSuccessor && inheritPhone && inheritPhone.value === 'ja';
|
|
||||||
toggle('phone-box', !hidePhone);
|
|
||||||
|
|
||||||
// Hidden conditional groups must not block submit with invisible required fields.
|
|
||||||
document.querySelectorAll('.field-group').forEach(function (group) {
|
|
||||||
const hidden = group.classList.contains('hidden');
|
|
||||||
group.querySelectorAll('input, select, textarea').forEach(function (el) {
|
|
||||||
if (el.type === 'hidden' || el.disabled) return;
|
|
||||||
if (hidden) {
|
|
||||||
if (el.required) {
|
|
||||||
el.dataset.requiredOriginal = '1';
|
|
||||||
el.required = false;
|
|
||||||
}
|
|
||||||
} else if (el.dataset.requiredOriginal === '1') {
|
|
||||||
el.required = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function slugifyForEmail(value) {
|
|
||||||
const map = { 'ä': 'ae', 'ö': 'oe', 'ü': 'ue', 'ß': 'ss' };
|
|
||||||
const lower = (value || '').toLowerCase();
|
|
||||||
const mapped = lower.replace(/[äöüß]/g, function (m) { return map[m] || m; });
|
|
||||||
return mapped
|
|
||||||
.normalize('NFD')
|
|
||||||
.replace(/[\u0300-\u036f]/g, '')
|
|
||||||
.replace(/[^a-z0-9]+/g, '.')
|
|
||||||
.replace(/^\.+|\.+$/g, '')
|
|
||||||
.replace(/\.{2,}/g, '.');
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupWorkEmailAutofill() {
|
|
||||||
const lastName = byName('last_name');
|
|
||||||
const workEmail = byName('work_email');
|
|
||||||
if (!lastName || !workEmail) return;
|
|
||||||
|
|
||||||
let lastSuggested = '';
|
|
||||||
let userEditedEmail = !!(workEmail.value && workEmail.value.trim());
|
|
||||||
|
|
||||||
function suggestEmail() {
|
|
||||||
const slug = slugifyForEmail(lastName.value);
|
|
||||||
if (!slug) return;
|
|
||||||
const suggestion = slug + '@tub.co';
|
|
||||||
if (!userEditedEmail || workEmail.value === '' || workEmail.value === lastSuggested) {
|
|
||||||
workEmail.value = suggestion;
|
|
||||||
lastSuggested = suggestion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
workEmail.addEventListener('input', function () {
|
|
||||||
const current = (workEmail.value || '').trim();
|
|
||||||
userEditedEmail = current !== '' && current !== lastSuggested;
|
|
||||||
});
|
|
||||||
|
|
||||||
lastName.addEventListener('input', suggestEmail);
|
|
||||||
suggestEmail();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupBusinessCardAutofill() {
|
|
||||||
const checkbox = byName('order_business_cards');
|
|
||||||
const firstName = byName('first_name');
|
|
||||||
const lastName = byName('last_name');
|
|
||||||
const jobTitle = byName('job_title');
|
|
||||||
const workEmail = byName('work_email');
|
|
||||||
const cardName = byName('business_card_name');
|
|
||||||
const cardTitle = byName('business_card_title');
|
|
||||||
const cardEmail = byName('business_card_email');
|
|
||||||
if (!checkbox || !cardName || !cardTitle || !cardEmail) return;
|
|
||||||
const cardBox = document.getElementById('business-card-box');
|
|
||||||
|
|
||||||
function suggestionName() {
|
|
||||||
const first = (firstName && firstName.value || '').trim();
|
|
||||||
const last = (lastName && lastName.value || '').trim();
|
|
||||||
return [first, last].filter(Boolean).join(' ').trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setField(field, value, force) {
|
|
||||||
if (!field || !value) return;
|
|
||||||
const current = (field.value || '').trim();
|
|
||||||
const autoMarked = field.dataset.autofilled === '1';
|
|
||||||
if (force || !current || autoMarked) {
|
|
||||||
field.value = value;
|
|
||||||
field.dataset.autofilled = '1';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyDefaults(force) {
|
|
||||||
if (!checkbox.checked) return;
|
|
||||||
const name = suggestionName();
|
|
||||||
const title = (jobTitle && jobTitle.value || '').trim();
|
|
||||||
const email = (workEmail && workEmail.value || '').trim();
|
|
||||||
setField(cardName, name, force);
|
|
||||||
setField(cardTitle, title, force);
|
|
||||||
setField(cardEmail, email, force);
|
|
||||||
}
|
|
||||||
|
|
||||||
[cardName, cardTitle, cardEmail].forEach(function (field) {
|
|
||||||
field.addEventListener('input', function () {
|
|
||||||
field.dataset.autofilled = '0';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (cardBox) {
|
|
||||||
const grid = cardBox.querySelector('.grid-2');
|
|
||||||
if (grid && !document.getElementById('business-card-autofill-btn')) {
|
|
||||||
const actionWrap = document.createElement('div');
|
|
||||||
actionWrap.className = 'field field-full';
|
|
||||||
const btn = document.createElement('button');
|
|
||||||
btn.type = 'button';
|
|
||||||
btn.id = 'business-card-autofill-btn';
|
|
||||||
btn.className = 'btn btn-secondary';
|
|
||||||
btn.textContent = 'Visitenkarten-Felder automatisch ausfüllen';
|
|
||||||
btn.addEventListener('click', function () {
|
|
||||||
applyDefaults(true);
|
|
||||||
});
|
|
||||||
actionWrap.appendChild(btn);
|
|
||||||
grid.insertBefore(actionWrap, grid.firstChild);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manual-only behavior: fill only when button is clicked.
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupChecklistToggles() {
|
|
||||||
document.querySelectorAll('[data-checklist-toggle]').forEach(function (button) {
|
|
||||||
const panel = button.closest('.itsetup-checklist-panel');
|
|
||||||
if (!panel) return;
|
|
||||||
|
|
||||||
const getCheckboxes = function () {
|
|
||||||
return Array.from(panel.querySelectorAll('input[type="checkbox"]'));
|
|
||||||
};
|
|
||||||
|
|
||||||
const refreshButtonLabel = function () {
|
|
||||||
const checkboxes = getCheckboxes();
|
|
||||||
if (!checkboxes.length) return;
|
|
||||||
const allChecked = checkboxes.every(function (box) { return box.checked; });
|
|
||||||
button.textContent = allChecked ? (button.dataset.labelClear || 'Auswahl aufheben') : (button.dataset.labelSelect || 'Alle auswählen');
|
|
||||||
};
|
|
||||||
|
|
||||||
button.addEventListener('click', function () {
|
|
||||||
const checkboxes = getCheckboxes();
|
|
||||||
if (!checkboxes.length) return;
|
|
||||||
const shouldCheck = checkboxes.some(function (box) { return !box.checked; });
|
|
||||||
checkboxes.forEach(function (box) {
|
|
||||||
box.checked = shouldCheck;
|
|
||||||
box.dispatchEvent(new Event('change', { bubbles: true }));
|
|
||||||
});
|
|
||||||
refreshButtonLabel();
|
|
||||||
});
|
|
||||||
|
|
||||||
getCheckboxes().forEach(function (box) {
|
|
||||||
box.addEventListener('change', refreshButtonLabel);
|
|
||||||
});
|
|
||||||
|
|
||||||
refreshButtonLabel();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupChecklistColumns() {
|
|
||||||
document.querySelectorAll('.itsetup-checklist-body > [id^="id_"]').forEach(function (container) {
|
|
||||||
const itemCount = container.querySelectorAll(':scope > div').length;
|
|
||||||
container.classList.toggle('cols-3', itemCount > 8);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateStep() {
|
|
||||||
pages.forEach((p, i) => p.classList.toggle('active', i === current));
|
|
||||||
navItems.forEach((n, i) => n.classList.toggle('active', i === current));
|
|
||||||
btnPrev.disabled = current === 0;
|
|
||||||
const last = current === pages.length - 1;
|
|
||||||
btnNext.classList.toggle('hidden', last);
|
|
||||||
btnSubmit.classList.toggle('hidden', !last);
|
|
||||||
}
|
|
||||||
|
|
||||||
function jumpToFirstErrorPage() {
|
|
||||||
const firstError = document.querySelector('.errorlist');
|
|
||||||
if (!firstError) return;
|
|
||||||
const page = firstError.closest('.page');
|
|
||||||
if (!page) return;
|
|
||||||
const step = Number(page.getAttribute('data-step') || '1') - 1;
|
|
||||||
current = Math.max(0, step);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener('change', syncConditionals);
|
|
||||||
navItems.forEach((n, idx) => {
|
|
||||||
n.addEventListener('click', function () { current = idx; updateStep(); });
|
|
||||||
n.addEventListener('keydown', function (e) {
|
|
||||||
if (e.key === 'Enter' || e.key === ' ') {
|
|
||||||
e.preventDefault();
|
|
||||||
current = idx;
|
|
||||||
updateStep();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
btnPrev.addEventListener('click', function () { if (current > 0) { current -= 1; updateStep(); } });
|
|
||||||
btnNext.addEventListener('click', function () { if (current < pages.length - 1) { current += 1; updateStep(); } });
|
|
||||||
btnSubmit.addEventListener('click', function () {
|
|
||||||
syncConditionals();
|
|
||||||
btnSubmit.disabled = true;
|
|
||||||
btnSubmit.textContent = 'Wird gesendet...';
|
|
||||||
form.submit();
|
|
||||||
});
|
|
||||||
|
|
||||||
syncConditionals();
|
|
||||||
setupWorkEmailAutofill();
|
|
||||||
setupBusinessCardAutofill();
|
|
||||||
setupChecklistToggles();
|
|
||||||
setupChecklistColumns();
|
|
||||||
jumpToFirstErrorPage();
|
|
||||||
updateStep();
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
@@ -3,55 +3,10 @@
|
|||||||
|
|
||||||
{% block title %}{% trans "Einweisung durchführen" %}{% endblock %}
|
{% block title %}{% trans "Einweisung durchführen" %}{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
<style>
|
|
||||||
:root {
|
{% block extra_css %}
|
||||||
--brand-blue: #000078;
|
<link rel="stylesheet" href="{% static 'workflows/css/onboarding_intro_session.css' %}" />
|
||||||
--ink: #17253b;
|
|
||||||
--muted: #607087;
|
|
||||||
--line: #d7e0ea;
|
|
||||||
--panel: #ffffff;
|
|
||||||
--soft: #f4f8ff;
|
|
||||||
--soft-strong: #eef4ff;
|
|
||||||
--ok-bg: #edf9f1;
|
|
||||||
--ok-ink: #116634;
|
|
||||||
--warn-bg: #fff8ea;
|
|
||||||
--warn-ink: #8a5a00;
|
|
||||||
}
|
|
||||||
* { box-sizing: border-box; }
|
|
||||||
body { margin: 0; font-family: "Segoe UI", Arial, sans-serif; background: linear-gradient(180deg, #eef4ff, #f8fbff); color: var(--ink); padding: 24px; }
|
|
||||||
.shell { width: min(var(--app-shell-width), 100%); margin: 0 auto; background: var(--panel); border: 1px solid var(--line); border-radius: 28px; box-shadow: 0 22px 48px rgba(18,34,56,.14); overflow: hidden; }
|
|
||||||
.hero { padding: 20px 22px 18px; border-bottom: 1px solid var(--line); background: linear-gradient(135deg, rgba(0,0,120,.06), rgba(0,0,120,0) 48%), linear-gradient(180deg, #ffffff, #f8fbff); }
|
|
||||||
.hero h1 { margin: 0; font-size: 32px; line-height: 1.08; color: var(--brand-blue); }
|
|
||||||
.sub { margin: 8px 0 0; color: var(--muted); max-width: 780px; }
|
|
||||||
.content { padding: 20px 22px 24px; }
|
|
||||||
.flash { margin: 0 0 12px; padding: 10px 12px; border-radius: 10px; border: 1px solid #bfe6c9; background: var(--ok-bg); color: var(--ok-ink); }
|
|
||||||
.meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-bottom: 16px; }
|
|
||||||
.card { border: 1px solid var(--line); border-radius: 14px; background: #fff; padding: 14px; }
|
|
||||||
.card h2 { margin: 0 0 10px; font-size: 16px; color: #1b3764; }
|
|
||||||
.progress-block { border: 1px solid var(--line); border-radius: 14px; background: linear-gradient(180deg, #ffffff, #f9fbff); padding: 14px; margin-bottom: 16px; }
|
|
||||||
.progress-top { display: flex; justify-content: space-between; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; }
|
|
||||||
.progress-label { font-size: 15px; font-weight: 700; color: #18345f; }
|
|
||||||
.progress-meta { color: var(--muted); font-size: 13px; }
|
|
||||||
.progress-bar { width: 100%; height: 12px; border-radius: 999px; overflow: hidden; background: #e7eefb; border: 1px solid #d6e1f5; }
|
|
||||||
.progress-fill { height: 100%; background: linear-gradient(90deg, #3056a3, #0f5fcf); }
|
|
||||||
.meta-grid { display: grid; grid-template-columns: 170px 1fr; gap: 8px 10px; font-size: 14px; }
|
|
||||||
.meta-grid strong { color: #334155; }
|
|
||||||
.status-pill { display: inline-block; padding: 4px 10px; border-radius: 999px; border: 1px solid #d7e0ea; background: #f8fbff; color: #486183; font-size: 12px; font-weight: 700; }
|
|
||||||
.status-pill.done { background: var(--ok-bg); color: var(--ok-ink); border-color: #bfe6c9; }
|
|
||||||
.status-pill.draft { background: var(--warn-bg); color: var(--warn-ink); border-color: #f5d8a8; }
|
|
||||||
.section { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; margin-bottom: 14px; background: #fff; }
|
|
||||||
.section-head { padding: 11px 14px; font-weight: 700; color: #1f376b; background: var(--soft-strong); border-bottom: 1px solid #d5e2f9; }
|
|
||||||
.items { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0; padding: 6px 14px 10px; }
|
|
||||||
.item { display: flex; align-items: flex-start; gap: 12px; padding: 10px 0; border-bottom: 1px solid #eef3f8; }
|
|
||||||
.item:nth-last-child(-n+2) { border-bottom: 0; }
|
|
||||||
.item input { margin-top: 2px; width: 18px; height: 18px; accent-color: var(--brand-blue); }
|
|
||||||
.item span { line-height: 1.45; }
|
|
||||||
textarea { width: 100%; min-height: 150px; border: 1px solid #cfd9e8; border-radius: 10px; padding: 11px 12px; font: inherit; resize: vertical; }
|
|
||||||
.help { color: var(--muted); font-size: 13px; margin-top: 8px; }
|
|
||||||
.actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
|
|
||||||
@media (max-width: 900px) { .meta, .items { grid-template-columns: 1fr; } .meta-grid { grid-template-columns: 1fr; } .item:nth-last-child(-n+2) { border-bottom: 1px solid #eef3f8; } .item:last-child { border-bottom: 0; } }
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block shell_body %}
|
{% block shell_body %}
|
||||||
|
|||||||
@@ -3,21 +3,16 @@
|
|||||||
|
|
||||||
{% block title %}{% trans "Onboarding gespeichert" %}{% endblock %}
|
{% block title %}{% trans "Onboarding gespeichert" %}{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
<style>
|
|
||||||
body { margin: 0; font-family: Arial, sans-serif; background: #f4f8ff; color: #1b2b43; padding: 24px; }
|
|
||||||
.shell { background: #fff; border: 1px solid #d7e0ea; border-radius: 16px; padding: 20px; box-shadow: 0 16px 36px rgba(18,34,56,0.10); }
|
|
||||||
h1 { margin: 0 0 10px; color: #000078; }
|
|
||||||
p { margin: 0 0 10px; }
|
|
||||||
code { background: #f4f6fa; padding: 2px 6px; border-radius: 6px; }
|
|
||||||
.actions { display:flex; gap:8px; flex-wrap:wrap; margin-top: 14px; }
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block shell_header %}
|
{% block shell_header %}
|
||||||
{% include 'workflows/includes/app_header.html' with header_show_home=1 %}
|
{% include 'workflows/includes/app_header.html' with header_show_home=1 %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_css %}
|
||||||
|
<link rel="stylesheet" href="{% static 'workflows/css/success_pages.css' %}" />
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block shell_body %}
|
{% block shell_body %}
|
||||||
<h1>{% trans "Anfrage erfolgreich gespeichert" %}</h1>
|
<h1>{% trans "Anfrage erfolgreich gespeichert" %}</h1>
|
||||||
<p>{% trans "Vorgangs-ID:" %} <code>{{ obj.id }}</code></p>
|
<p>{% trans "Vorgangs-ID:" %} <code>{{ obj.id }}</code></p>
|
||||||
|
|||||||
@@ -3,24 +3,10 @@
|
|||||||
|
|
||||||
{% block title %}Project Wiki{% endblock %}
|
{% block title %}Project Wiki{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
<style>
|
|
||||||
body { margin: 0; font-family: Arial, sans-serif; background: #f4f8ff; color: #1b2b43; padding: 20px; }
|
{% block extra_css %}
|
||||||
.shell { max-width: 1120px; margin: 0 auto; background: #fff; border: 1px solid #d7e0ea; border-radius: 14px; padding: 18px; }
|
<link rel="stylesheet" href="{% static 'workflows/css/docs_pages.css' %}" />
|
||||||
.brand-logo { width: 190px; max-width: 100%; height: auto; margin: 0 0 10px; display: block; }
|
|
||||||
.top { display: flex; justify-content: space-between; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; }
|
|
||||||
h1 { margin: 0; color: #000078; font-size: 30px; }
|
|
||||||
.sub { margin: 8px 0 16px; color: #5f6f85; }
|
|
||||||
.toc { border: 1px solid #d7e0ea; border-radius: 10px; padding: 10px; background: #f7fbff; margin-bottom: 16px; }
|
|
||||||
.toc a { color: #0b4da2; text-decoration: none; margin-right: 10px; white-space: nowrap; }
|
|
||||||
h2 { margin: 20px 0 8px; color: #113a74; border-bottom: 1px solid #e1e8f2; padding-bottom: 4px; }
|
|
||||||
h3 { margin: 14px 0 6px; color: #183f77; }
|
|
||||||
ul { margin: 8px 0 12px 20px; }
|
|
||||||
li { margin: 4px 0; }
|
|
||||||
code { background: #f1f5fb; border: 1px solid #dce6f3; border-radius: 6px; padding: 2px 6px; }
|
|
||||||
.box { border: 1px solid #d7e0ea; border-radius: 10px; padding: 10px; background: #fcfdff; margin: 8px 0 12px; }
|
|
||||||
.note { border-left: 4px solid #000078; padding: 8px 10px; background: #f4f8ff; margin: 10px 0; }
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block shell_body %}
|
{% block shell_body %}
|
||||||
|
|||||||
@@ -3,29 +3,10 @@
|
|||||||
|
|
||||||
{% block title %}{% trans "Release Checklist" %}{% endblock %}
|
{% block title %}{% trans "Release Checklist" %}{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
<style>
|
|
||||||
body { margin: 0; font-family: Arial, sans-serif; background: #f4f8ff; color: #1b2b43; padding: 20px; }
|
{% block extra_css %}
|
||||||
.shell { max-width: 1120px; margin: 0 auto; }
|
<link rel="stylesheet" href="{% static 'workflows/css/release_checklist.css' %}" />
|
||||||
.brand-logo { width: 190px; max-width: 100%; height: auto; margin: 0 0 10px; display: block; }
|
|
||||||
.hero, .panel { background: #fff; border: 1px solid #d7e0ea; border-radius: 16px; box-shadow: 0 20px 40px rgba(17, 58, 116, 0.08); }
|
|
||||||
.hero { padding: 20px; margin-bottom: 18px; }
|
|
||||||
.top { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
|
|
||||||
.eyebrow { display: inline-block; padding: 5px 10px; border-radius: 999px; background: #eef4ff; color: #244a8f; border: 1px solid #d5e2f9; font-size: 12px; font-weight: 700; margin-bottom: 10px; }
|
|
||||||
h1 { margin: 0; color: #000078; font-size: 30px; }
|
|
||||||
.sub { margin: 8px 0 0; color: #5f6f85; max-width: 820px; }
|
|
||||||
.grid { display: grid; grid-template-columns: repeat(2, minmax(320px, 1fr)); gap: 16px; }
|
|
||||||
.panel { padding: 18px; }
|
|
||||||
h2 { margin: 0 0 12px; color: #113a74; font-size: 20px; }
|
|
||||||
ol, ul { margin: 0; padding-left: 20px; }
|
|
||||||
li { margin: 8px 0; color: #334155; }
|
|
||||||
.checklist li { list-style: none; position: relative; padding-left: 28px; }
|
|
||||||
.checklist li::before { content: '\25A1'; position: absolute; left: 0; top: 0; color: #66758c; font-size: 16px; }
|
|
||||||
pre { margin: 12px 0 0; padding: 14px; border-radius: 12px; background: #f7faff; border: 1px solid #dfe8f4; overflow-x: auto; color: #16345f; }
|
|
||||||
code { font-family: Menlo, Monaco, Consolas, monospace; font-size: 13px; }
|
|
||||||
.note { margin-top: 16px; padding: 14px 16px; border-radius: 12px; background: #f7faff; border: 1px solid #dfe8f4; color: #355175; }
|
|
||||||
@media (max-width: 820px) { .grid { grid-template-columns: 1fr; } }
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block shell_body %}
|
{% block shell_body %}
|
||||||
|
|||||||
@@ -3,872 +3,10 @@
|
|||||||
|
|
||||||
{% block title %}{% trans "Anfragen Dashboard" %}{% endblock %}
|
{% block title %}{% trans "Anfragen Dashboard" %}{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
<style>
|
|
||||||
:root {
|
|
||||||
--brand-blue: #000078;
|
|
||||||
--brand-blue-soft: #1f4fd6;
|
|
||||||
--brand-red: #a32020;
|
|
||||||
--ink: #132238;
|
|
||||||
--muted: #607086;
|
|
||||||
--line: #d9e3ee;
|
|
||||||
--line-strong: #c8d5e5;
|
|
||||||
--panel: rgba(255, 255, 255, 0.9);
|
|
||||||
--panel-strong: #ffffff;
|
|
||||||
--bg-soft: #eef3ff;
|
|
||||||
--ok-bg: #ecf9f0;
|
|
||||||
--ok-ink: #1f7a3f;
|
|
||||||
--warn-bg: #fff6e5;
|
|
||||||
--warn-ink: #9a6400;
|
|
||||||
--danger-bg: #fff1f1;
|
|
||||||
--danger-ink: #982222;
|
|
||||||
--shadow: 0 22px 48px rgba(18, 34, 56, 0.14);
|
|
||||||
}
|
|
||||||
|
|
||||||
* { box-sizing: border-box; }
|
|
||||||
|
|
||||||
body {
|
{% block extra_css %}
|
||||||
margin: 0;
|
<link rel="stylesheet" href="{% static 'workflows/css/requests_dashboard.css' %}" />
|
||||||
font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
|
|
||||||
color: var(--ink);
|
|
||||||
min-height: 100vh;
|
|
||||||
background:
|
|
||||||
radial-gradient(70% 90% at 8% 8%, rgba(0, 0, 120, 0.14), rgba(0, 0, 120, 0)),
|
|
||||||
radial-gradient(60% 85% at 92% 88%, rgba(163, 32, 32, 0.12), rgba(163, 32, 32, 0)),
|
|
||||||
linear-gradient(160deg, #eef3ff 0%, #f9fbff 48%, #edf4ff 100%);
|
|
||||||
padding: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shell {
|
|
||||||
width: min(1380px, 100%);
|
|
||||||
margin: 0 auto;
|
|
||||||
background: rgba(255, 255, 255, 0.78);
|
|
||||||
backdrop-filter: blur(12px);
|
|
||||||
border: 1px solid rgba(217, 227, 238, 0.9);
|
|
||||||
border-radius: 28px;
|
|
||||||
box-shadow: var(--shadow);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topbar {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: flex-start;
|
|
||||||
gap: 18px;
|
|
||||||
padding: 22px 24px 18px;
|
|
||||||
border-bottom: 1px solid rgba(217, 227, 238, 0.9);
|
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.95), rgba(248,251,255,0.84));
|
|
||||||
}
|
|
||||||
|
|
||||||
.brand-wrap {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.brand-logo {
|
|
||||||
width: 212px;
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
display: block;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.quick-actions {
|
|
||||||
display: flex;
|
|
||||||
gap: 8px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: flex-end;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.lang-switch { display:flex; gap:6px; }
|
|
||||||
.lang-btn { border:1px solid var(--line); background:#f8fbff; color:#1f3a5f; border-radius:999px; padding:6px 10px; font-size:12px; font-weight:700; cursor:pointer; }
|
|
||||||
.lang-btn.active { background:var(--brand-blue); border-color:var(--brand-blue); color:#fff; }
|
|
||||||
|
|
||||||
.hero {
|
|
||||||
padding: 0;
|
|
||||||
border-bottom: 0;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: minmax(0, 1.4fr) minmax(320px, 0.8fr);
|
|
||||||
gap: 12px;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-card,
|
|
||||||
.pulse-card,
|
|
||||||
.controls-card,
|
|
||||||
.table-card,
|
|
||||||
.chart-card,
|
|
||||||
.stat-card {
|
|
||||||
border: 1px solid rgba(217, 227, 238, 0.94);
|
|
||||||
background: var(--panel);
|
|
||||||
border-radius: 22px;
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.92);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-card {
|
|
||||||
padding: 14px;
|
|
||||||
background:
|
|
||||||
radial-gradient(100% 140% at 10% 10%, rgba(31,79,214,0.10), rgba(31,79,214,0)),
|
|
||||||
linear-gradient(180deg, rgba(255,255,255,0.99), rgba(248,251,255,0.97));
|
|
||||||
}
|
|
||||||
|
|
||||||
.eyebrow {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 6px 10px;
|
|
||||||
border-radius: 999px;
|
|
||||||
border: 1px solid rgba(0,0,120,0.12);
|
|
||||||
background: rgba(0,0,120,0.05);
|
|
||||||
color: var(--brand-blue);
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 700;
|
|
||||||
letter-spacing: 0.03em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero h1 {
|
|
||||||
margin: 8px 0 4px;
|
|
||||||
font-size: clamp(24px, 3.6vw, 34px);
|
|
||||||
line-height: 1;
|
|
||||||
letter-spacing: -0.04em;
|
|
||||||
color: var(--brand-blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero p {
|
|
||||||
margin: 0;
|
|
||||||
max-width: 760px;
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 1.45;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-pills {
|
|
||||||
margin-top: 12px;
|
|
||||||
display: flex;
|
|
||||||
gap: 8px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hero-pill {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
min-height: 34px;
|
|
||||||
padding: 8px 12px;
|
|
||||||
border-radius: 14px;
|
|
||||||
border: 1px solid rgba(217, 227, 238, 0.96);
|
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(248,251,255,0.96));
|
|
||||||
color: #294465;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 800;
|
|
||||||
line-height: 1;
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.94);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pulse-card {
|
|
||||||
padding: 18px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
min-height: 100%;
|
|
||||||
background:
|
|
||||||
radial-gradient(120% 120% at 100% 0%, rgba(163,32,32,0.10), rgba(163,32,32,0)),
|
|
||||||
linear-gradient(180deg, rgba(255,255,255,0.98), rgba(253,247,247,0.96));
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity-card {
|
|
||||||
padding: 18px;
|
|
||||||
background: rgba(255,255,255,0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity-card .chart {
|
|
||||||
min-height: 150px;
|
|
||||||
padding-top: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity-card .bar-wrap {
|
|
||||||
min-height: 104px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pulse-card h2 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #1a3359;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pulse-card p {
|
|
||||||
margin: 8px 0 0;
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pulse-metrics {
|
|
||||||
margin-top: 18px;
|
|
||||||
display: grid;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pulse-metric {
|
|
||||||
padding: 12px 14px;
|
|
||||||
border-radius: 16px;
|
|
||||||
background: rgba(255,255,255,0.86);
|
|
||||||
border: 1px solid rgba(217, 227, 238, 0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
.pulse-label {
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--muted);
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.04em;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pulse-value {
|
|
||||||
margin-top: 5px;
|
|
||||||
font-size: 26px;
|
|
||||||
font-weight: 800;
|
|
||||||
color: var(--brand-blue);
|
|
||||||
letter-spacing: -0.03em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.metrics-grid {
|
|
||||||
padding: 0;
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
||||||
gap: 12px;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card {
|
|
||||||
padding: 14px;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
min-height: 110px;
|
|
||||||
border-radius: 18px;
|
|
||||||
box-shadow: 0 10px 24px rgba(18, 33, 56, 0.04), inset 0 1px 0 rgba(255,255,255,0.92);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
inset: auto -24px -36px auto;
|
|
||||||
width: 110px;
|
|
||||||
height: 110px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: rgba(31, 79, 214, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card.red::before { background: rgba(163, 32, 32, 0.08); }
|
|
||||||
.stat-card.gold::before { background: rgba(194, 137, 26, 0.10); }
|
|
||||||
.stat-card.ink::before { background: rgba(19, 34, 56, 0.08); }
|
|
||||||
|
|
||||||
.stat-head {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 10px;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-title {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 12px;
|
|
||||||
color: var(--muted);
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.05em;
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-kicker {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 34px;
|
|
||||||
height: 34px;
|
|
||||||
border-radius: 12px;
|
|
||||||
background: rgba(0, 0, 120, 0.06);
|
|
||||||
color: var(--brand-blue);
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card.red .stat-kicker {
|
|
||||||
background: rgba(163, 32, 32, 0.08);
|
|
||||||
color: var(--brand-red);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card.gold .stat-kicker {
|
|
||||||
background: rgba(194, 137, 26, 0.10);
|
|
||||||
color: #9a6400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-card.ink .stat-kicker {
|
|
||||||
background: rgba(19, 34, 56, 0.08);
|
|
||||||
color: #132238;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-value {
|
|
||||||
margin-top: 12px;
|
|
||||||
font-size: clamp(24px, 2.6vw, 30px);
|
|
||||||
font-weight: 900;
|
|
||||||
letter-spacing: -0.05em;
|
|
||||||
color: var(--ink);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-foot {
|
|
||||||
margin-top: 5px;
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.4;
|
|
||||||
max-width: 220px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-grid {
|
|
||||||
padding: 18px 24px 24px;
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
gap: 16px;
|
|
||||||
align-items: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-stack {
|
|
||||||
padding: 12px 24px 0;
|
|
||||||
display: grid;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.top-content-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: minmax(0, 1.5fr) minmax(320px, 1fr);
|
|
||||||
gap: 16px;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart-card,
|
|
||||||
.controls-card,
|
|
||||||
.table-card {
|
|
||||||
padding: 14px;
|
|
||||||
background: rgba(255,255,255,0.94);
|
|
||||||
border-radius: 22px;
|
|
||||||
box-shadow: 0 12px 28px rgba(18, 33, 56, 0.045), inset 0 1px 0 rgba(255,255,255,0.92);
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-head {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: flex-end;
|
|
||||||
gap: 10px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-head h2 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #18345f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-head p {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--muted);
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(14, minmax(0, 1fr));
|
|
||||||
gap: 6px;
|
|
||||||
align-items: end;
|
|
||||||
min-height: 180px;
|
|
||||||
padding-top: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chart-col {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar-wrap {
|
|
||||||
width: 100%;
|
|
||||||
min-height: 124px;
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 0 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 34px;
|
|
||||||
background: linear-gradient(180deg, #2b5bda, #071f7d);
|
|
||||||
border-radius: 14px 14px 6px 6px;
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.28);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar-value {
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 800;
|
|
||||||
color: #294465;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bar-label {
|
|
||||||
font-size: 11px;
|
|
||||||
color: var(--muted);
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.controls-card {
|
|
||||||
position: static;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-form {
|
|
||||||
display: grid;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-box {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-box input {
|
|
||||||
width: 100%;
|
|
||||||
border: 1px solid var(--line-strong);
|
|
||||||
border-radius: 16px;
|
|
||||||
padding: 14px 16px;
|
|
||||||
font: inherit;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--ink);
|
|
||||||
background: rgba(255,255,255,0.98);
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.98);
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-box input:focus {
|
|
||||||
outline: none;
|
|
||||||
border-color: rgba(0, 0, 120, 0.3);
|
|
||||||
box-shadow: 0 0 0 4px rgba(0, 0, 120, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-help {
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.55;
|
|
||||||
max-width: 70ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-panel {
|
|
||||||
margin-top: 16px;
|
|
||||||
padding-top: 16px;
|
|
||||||
border-top: 1px solid var(--line);
|
|
||||||
display: grid;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bulk-toolbar {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
margin: 0;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bulk-info {
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-card {
|
|
||||||
padding: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 26px;
|
|
||||||
box-shadow: 0 16px 48px rgba(18, 33, 56, 0.06), inset 0 1px 0 rgba(255,255,255,0.92);
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-controls {
|
|
||||||
padding: 14px 18px 14px;
|
|
||||||
border-bottom: 1px solid var(--line);
|
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(244,248,255,0.96));
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-controls-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: minmax(0, 1fr) auto;
|
|
||||||
gap: 14px;
|
|
||||||
align-items: stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-stack {
|
|
||||||
display: grid;
|
|
||||||
gap: 12px;
|
|
||||||
padding: 14px;
|
|
||||||
border: 1px solid rgba(217, 227, 238, 0.95);
|
|
||||||
border-radius: 18px;
|
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(249,251,255,0.95));
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.9);
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-card {
|
|
||||||
padding: 18px;
|
|
||||||
background: rgba(255,255,255,0.92);
|
|
||||||
border: 1px solid rgba(217, 227, 238, 0.94);
|
|
||||||
border-radius: 22px;
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.92);
|
|
||||||
display: grid;
|
|
||||||
gap: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-head {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 14px;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
padding: 16px 18px 14px;
|
|
||||||
border-bottom: 1px solid var(--line);
|
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(245,249,255,0.96));
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-head h2 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 20px;
|
|
||||||
color: #18345f;
|
|
||||||
letter-spacing: -0.02em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-head p {
|
|
||||||
margin: 5px 0 0;
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-head-meta {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding: 10px 14px;
|
|
||||||
border-radius: 999px;
|
|
||||||
border: 1px solid rgba(0, 0, 120, 0.10);
|
|
||||||
background: rgba(0, 0, 120, 0.05);
|
|
||||||
color: var(--brand-blue);
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 800;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-wrap {
|
|
||||||
overflow-x: auto;
|
|
||||||
padding: 0 18px 18px;
|
|
||||||
background: linear-gradient(180deg, rgba(249,251,255,0.72), rgba(255,255,255,0));
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: separate;
|
|
||||||
border-spacing: 0 12px;
|
|
||||||
font-size: 14px;
|
|
||||||
min-width: 980px;
|
|
||||||
}
|
|
||||||
|
|
||||||
thead th {
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
z-index: 2;
|
|
||||||
background: rgba(245,248,252,0.94);
|
|
||||||
color: #5b6b7f;
|
|
||||||
text-align: left;
|
|
||||||
font-size: 11px;
|
|
||||||
letter-spacing: 0.05em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: 800;
|
|
||||||
padding: 12px 14px;
|
|
||||||
border-top: 1px solid var(--line);
|
|
||||||
border-bottom: 1px solid var(--line);
|
|
||||||
}
|
|
||||||
|
|
||||||
thead th:first-child {
|
|
||||||
border-left: 1px solid var(--line);
|
|
||||||
border-radius: 14px 0 0 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
thead th:last-child {
|
|
||||||
border-right: 1px solid var(--line);
|
|
||||||
border-radius: 0 14px 14px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody td {
|
|
||||||
background: rgba(255,255,255,0.98);
|
|
||||||
border-top: 1px solid var(--line);
|
|
||||||
border-bottom: 1px solid var(--line);
|
|
||||||
padding: 15px 14px;
|
|
||||||
vertical-align: middle;
|
|
||||||
box-shadow: 0 8px 22px rgba(26, 51, 89, 0.035);
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody td:first-child {
|
|
||||||
border-left: 1px solid var(--line);
|
|
||||||
border-radius: 18px 0 0 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody td:last-child {
|
|
||||||
border-right: 1px solid var(--line);
|
|
||||||
border-radius: 0 18px 18px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tbody tr:hover td {
|
|
||||||
background: #fbfdff;
|
|
||||||
border-color: #cad7e8;
|
|
||||||
box-shadow: 0 12px 26px rgba(26, 51, 89, 0.06);
|
|
||||||
}
|
|
||||||
|
|
||||||
.select-col {
|
|
||||||
width: 42px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
th.select-col,
|
|
||||||
td.select-col {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
td.actions-cell {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
td.intro-panel {
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select-col input[type="checkbox"] {
|
|
||||||
display: block;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.kind-pill,
|
|
||||||
.status-badge,
|
|
||||||
.doc-link {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 6px;
|
|
||||||
min-height: 38px;
|
|
||||||
padding: 10px 14px;
|
|
||||||
border-radius: 14px;
|
|
||||||
font-weight: 800;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1;
|
|
||||||
letter-spacing: 0.01em;
|
|
||||||
text-decoration: none;
|
|
||||||
white-space: nowrap;
|
|
||||||
border: 1px solid rgba(217, 227, 238, 0.96);
|
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(248,251,255,0.96));
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.94);
|
|
||||||
}
|
|
||||||
|
|
||||||
.kind-pill {
|
|
||||||
color: #294465;
|
|
||||||
}
|
|
||||||
|
|
||||||
.kind-pill.onboarding {
|
|
||||||
background: linear-gradient(180deg, rgba(245,247,255,0.98), rgba(236,241,255,0.98));
|
|
||||||
border-color: rgba(0, 0, 120, 0.12);
|
|
||||||
color: var(--brand-blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
.kind-pill.offboarding {
|
|
||||||
background: linear-gradient(180deg, rgba(255,247,247,0.98), rgba(255,240,240,0.98));
|
|
||||||
border-color: rgba(163, 32, 32, 0.14);
|
|
||||||
color: var(--brand-red);
|
|
||||||
}
|
|
||||||
|
|
||||||
.name-cell {
|
|
||||||
display: grid;
|
|
||||||
gap: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.person-name {
|
|
||||||
font-weight: 800;
|
|
||||||
color: var(--ink);
|
|
||||||
letter-spacing: -0.01em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.person-meta {
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mail-link {
|
|
||||||
color: #294465;
|
|
||||||
text-decoration: none;
|
|
||||||
font-weight: 600;
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mail-link:hover { text-decoration: underline; }
|
|
||||||
|
|
||||||
.status-badge.ok {
|
|
||||||
background: linear-gradient(180deg, #f3fcf6, #e8f8ee);
|
|
||||||
color: var(--ok-ink);
|
|
||||||
border-color: #cdeed8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-badge.pending {
|
|
||||||
background: linear-gradient(180deg, #fffaf0, #fff3dc);
|
|
||||||
color: var(--warn-ink);
|
|
||||||
border-color: #f3dfb5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.doc-link {
|
|
||||||
color: var(--brand-blue);
|
|
||||||
background: linear-gradient(180deg, rgba(255,255,255,0.99), rgba(244,248,255,0.98));
|
|
||||||
border-color: rgba(0, 0, 120, 0.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
.doc-link:hover {
|
|
||||||
background: linear-gradient(180deg, rgba(248,251,255,0.99), rgba(238,244,255,0.98));
|
|
||||||
border-color: rgba(0, 0, 120, 0.18);
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions-cell { white-space: normal; }
|
|
||||||
.inline-form { display: inline; margin: 0; }
|
|
||||||
.inline-delete { display: inline-flex; align-items: center; }
|
|
||||||
.inline-delete .btn { min-height: 38px; display: inline-flex; align-items: center; justify-content: center; }
|
|
||||||
.intro-panel { min-width: 260px; }
|
|
||||||
|
|
||||||
details {
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
border-radius: 16px;
|
|
||||||
background: linear-gradient(180deg, #ffffff, #f8fbff);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
details[open] {
|
|
||||||
border-color: #cad7e8;
|
|
||||||
box-shadow: inset 0 1px 0 rgba(255,255,255,0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro-toggle {
|
|
||||||
cursor: pointer;
|
|
||||||
list-style: none;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 10px;
|
|
||||||
padding: 12px 14px;
|
|
||||||
font-weight: 800;
|
|
||||||
color: #18345f;
|
|
||||||
background: rgba(255,255,255,0.65);
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro-toggle::after {
|
|
||||||
content: "+";
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 1;
|
|
||||||
color: var(--brand-blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
details[open] .intro-toggle::after { content: "−"; }
|
|
||||||
.intro-toggle::-webkit-details-marker { display: none; }
|
|
||||||
|
|
||||||
.intro-menu {
|
|
||||||
padding: 0 14px 14px;
|
|
||||||
display: grid;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro-group {
|
|
||||||
border-top: 1px solid var(--line);
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro-group:first-child {
|
|
||||||
border-top: 0;
|
|
||||||
padding-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro-group-title {
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 800;
|
|
||||||
color: var(--muted);
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.05em;
|
|
||||||
margin-bottom: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro-actions {
|
|
||||||
display: flex;
|
|
||||||
gap: 6px;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.intro-meta {
|
|
||||||
padding: 0 14px 14px;
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flash {
|
|
||||||
margin: 0 24px 14px;
|
|
||||||
padding: 12px 14px;
|
|
||||||
border-radius: 16px;
|
|
||||||
border: 1px solid rgba(217, 227, 238, 0.9);
|
|
||||||
background: rgba(248, 251, 255, 0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
.flash.success { border-color: #bfe6c9; background: #edf9f1; color: #116634; }
|
|
||||||
.flash.warning { border-color: #f5d8a8; background: #fff8ea; color: #8a5a00; }
|
|
||||||
.flash.error { border-color: #f4c7c7; background: #fff1f1; color: #8e1e1e; }
|
|
||||||
|
|
||||||
.empty-state {
|
|
||||||
text-align: center;
|
|
||||||
color: var(--muted);
|
|
||||||
padding: 26px 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-bar {
|
|
||||||
padding: 0 24px 24px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 12px;
|
|
||||||
align-items: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-note {
|
|
||||||
color: var(--muted);
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 1180px) {
|
|
||||||
.hero-grid,
|
|
||||||
.metrics-grid,
|
|
||||||
.top-content-grid,
|
|
||||||
.table-controls-grid {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 760px) {
|
|
||||||
body { padding: 14px; }
|
|
||||||
.topbar,
|
|
||||||
.hero,
|
|
||||||
.metrics-grid,
|
|
||||||
.content-grid,
|
|
||||||
.footer-bar { padding-left: 16px; padding-right: 16px; }
|
|
||||||
.topbar { flex-direction: column; }
|
|
||||||
.quick-actions { justify-content: flex-start; }
|
|
||||||
.table-wrap { padding-left: 12px; padding-right: 12px; }
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block shell_body %}
|
{% block shell_body %}
|
||||||
@@ -997,10 +135,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div class="search-help">{% trans "Datensätze können direkt in der Tabelle gefiltert, geöffnet, geprüft oder gelöscht werden." %}</div>
|
<div class="search-help">{% trans "Datensätze können direkt in der Tabelle gefiltert, geöffnet, geprüft oder gelöscht werden." %}</div>
|
||||||
{% endblock %}
|
</div>
|
||||||
|
{% if request.user.is_staff %}
|
||||||
{% block extra_scripts %}
|
<div class="control-stack">
|
||||||
{% if request.user.is_staff %}<div class="control-stack">
|
|
||||||
<form method="post" action="/requests/" id="bulk-delete-form" onsubmit="return confirm('Ausgewählte Einträge wirklich löschen?');">
|
<form method="post" action="/requests/" id="bulk-delete-form" onsubmit="return confirm('Ausgewählte Einträge wirklich löschen?');">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="bulk-toolbar">
|
<div class="bulk-toolbar">
|
||||||
@@ -1116,30 +253,8 @@
|
|||||||
<div class="footer-note">{% trans "TUBCO Onboarding & Offboarding Portal" %}</div>
|
<div class="footer-note">{% trans "TUBCO Onboarding & Offboarding Portal" %}</div>
|
||||||
<a class="btn btn-secondary" href="/">{% trans "Zur Startseite" %}</a>
|
<a class="btn btn-secondary" href="/">{% trans "Zur Startseite" %}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% if request.user.is_staff %}
|
|
||||||
<script>
|
|
||||||
(function () {
|
|
||||||
const selectAll = document.getElementById('select-all');
|
|
||||||
const rowChecks = Array.from(document.querySelectorAll('.row-select'));
|
|
||||||
const selectedCount = document.getElementById('selected-count');
|
|
||||||
if (!selectAll || !selectedCount || !rowChecks.length) return;
|
|
||||||
|
|
||||||
function updateCount() {
|
|
||||||
const checked = rowChecks.filter((c) => c.checked).length;
|
|
||||||
selectedCount.textContent = String(checked);
|
|
||||||
selectAll.checked = checked > 0 && checked === rowChecks.length;
|
|
||||||
selectAll.indeterminate = checked > 0 && checked < rowChecks.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
selectAll.addEventListener('change', function () {
|
|
||||||
rowChecks.forEach((c) => { c.checked = selectAll.checked; });
|
|
||||||
updateCount();
|
|
||||||
});
|
|
||||||
rowChecks.forEach((c) => c.addEventListener('change', updateCount));
|
|
||||||
updateCount();
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_scripts %}
|
||||||
|
<script src="{% static 'workflows/js/requests_dashboard.js' %}"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|||||||
@@ -3,41 +3,10 @@
|
|||||||
|
|
||||||
{% block title %}{% trans "Welcome E-Mails" %}{% endblock %}
|
{% block title %}{% trans "Welcome E-Mails" %}{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
|
||||||
<style>
|
|
||||||
body { margin: 0; font-family: Arial, sans-serif; background: #f4f8ff; color: #0f172a; padding: 20px; }
|
{% block extra_css %}
|
||||||
.shell { max-width: 1100px; margin: 0 auto; background: #fff; border: 1px solid #d8e3f0; border-radius: 14px; padding: 16px; }
|
<link rel="stylesheet" href="{% static 'workflows/css/admin_tools.css' %}" />
|
||||||
.topbar { display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap; }
|
|
||||||
.brand-logo { width: 190px; max-width: 100%; height: auto; display: block; }
|
|
||||||
h1 { margin: 12px 0 6px; color: #000078; }
|
|
||||||
.sub { margin: 0 0 12px; color: #54657c; }
|
|
||||||
.msg { border-radius: 10px; padding: 10px 12px; margin: 0 0 12px; border: 1px solid #d6e1ef; background: #f8fbff; color: #1f3a5f; }
|
|
||||||
.msg.error { border-color: #fecaca; background: #fff1f2; color: #991b1b; }
|
|
||||||
.card { border: 1px solid #d8e3f0; border-radius: 12px; background: #fbfdff; padding: 12px; margin-bottom: 14px; }
|
|
||||||
.grid { display: grid; grid-template-columns: repeat(2, minmax(260px, 1fr)); gap: 10px; }
|
|
||||||
label { display: block; margin-bottom: 4px; font-size: 12px; color: #334155; font-weight: 700; }
|
|
||||||
input, textarea { width: 100%; box-sizing: border-box; border: 1px solid #cbd5e1; border-radius: 8px; padding: 8px 9px; }
|
|
||||||
textarea { min-height: 120px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; }
|
|
||||||
.check-row { margin-top: 8px; display: flex; gap: 12px; flex-wrap: wrap; }
|
|
||||||
.check-row label { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: 13px; }
|
|
||||||
.check-row input[type="checkbox"] { width: auto; }
|
|
||||||
table { width: 100%; border-collapse: collapse; font-size: 14px; }
|
|
||||||
th, td { border: 1px solid #dce5f1; padding: 8px; text-align: left; vertical-align: top; }
|
|
||||||
th { background: #f6f9ff; }
|
|
||||||
.badge { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 12px; font-weight: 700; }
|
|
||||||
.scheduled { background: #eff6ff; color: #1d4ed8; }
|
|
||||||
.paused { background: #fef9c3; color: #854d0e; }
|
|
||||||
.cancelled { background: #f1f5f9; color: #334155; }
|
|
||||||
.sent { background: #ecfdf3; color: #166534; }
|
|
||||||
.failed { background: #fff1f2; color: #991b1b; }
|
|
||||||
.actions { margin-top: 10px; display: flex; gap: 8px; flex-wrap: wrap; }
|
|
||||||
.table-actions { display: flex; gap: 6px; flex-wrap: wrap; }
|
|
||||||
.hint { margin-top: 6px; color: #64748b; font-size: 12px; }
|
|
||||||
.bulk-bar { margin: 0 0 10px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
|
|
||||||
.bulk-bar select { width: auto; min-width: 180px; }
|
|
||||||
.select-col { width: 42px; text-align: center; }
|
|
||||||
.bulk-note { color: #64748b; font-size: 12px; }
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block shell_body %}
|
{% block shell_body %}
|
||||||
@@ -93,7 +62,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<form class="bulk-bar" id="welcome-bulk-form" method="post" action="/admin-tools/welcome-emails/bulk-action/" onsubmit="return confirmBulkAction();">
|
<form class="bulk-bar" id="welcome-bulk-form" method="post" action="/admin-tools/welcome-emails/bulk-action/" onsubmit="return confirmBulkAction();" data-alert-empty="{% trans 'Bitte mindestens einen Welcome-Eintrag auswählen.' %}" data-confirm-delete="{% trans 'Ausgewählte Welcome-Einträge wirklich löschen?' %}" data-confirm-pause="{% trans 'Ausgewählte Welcome-Einträge pausieren?' %}" data-confirm-send="{% trans 'Ausgewählte Welcome-Einträge sofort senden?' %}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<label style="display:inline-flex; align-items:center; gap:6px; margin:0;">
|
<label style="display:inline-flex; align-items:center; gap:6px; margin:0;">
|
||||||
<input type="checkbox" id="select-all-welcome" />
|
<input type="checkbox" id="select-all-welcome" />
|
||||||
@@ -180,58 +149,6 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_scripts %}
|
{% block extra_scripts %}
|
||||||
<script>(function () {
|
<script src="{% static 'workflows/js/welcome_emails.js' %}"></script>
|
||||||
const selectAll = document.getElementById('select-all-welcome');
|
|
||||||
const rowChecks = Array.from(document.querySelectorAll('.welcome-select'));
|
|
||||||
const selectedCount = document.getElementById('selected-count');
|
|
||||||
const selectedIds = document.getElementById('selected_ids');
|
|
||||||
const bulkForm = document.getElementById('welcome-bulk-form');
|
|
||||||
const bulkAction = document.getElementById('bulk_action');
|
|
||||||
|
|
||||||
function currentSelected() {
|
|
||||||
return rowChecks.filter((c) => c.checked).map((c) => c.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function syncState() {
|
|
||||||
const ids = currentSelected();
|
|
||||||
selectedCount.textContent = String(ids.length);
|
|
||||||
selectedIds.value = ids.join(',');
|
|
||||||
if (!rowChecks.length) {
|
|
||||||
selectAll.checked = false;
|
|
||||||
selectAll.indeterminate = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
selectAll.checked = ids.length > 0 && ids.length === rowChecks.length;
|
|
||||||
selectAll.indeterminate = ids.length > 0 && ids.length < rowChecks.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
selectAll.addEventListener('change', function () {
|
|
||||||
rowChecks.forEach((c) => { c.checked = selectAll.checked; });
|
|
||||||
syncState();
|
|
||||||
});
|
|
||||||
|
|
||||||
rowChecks.forEach((c) => c.addEventListener('change', syncState));
|
|
||||||
bulkForm.addEventListener('submit', syncState);
|
|
||||||
|
|
||||||
window.confirmBulkAction = function () {
|
|
||||||
syncState();
|
|
||||||
const count = currentSelected().length;
|
|
||||||
if (!count) {
|
|
||||||
alert('{% trans "Bitte mindestens einen Welcome-Eintrag auswählen." %}');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const action = bulkAction.value;
|
|
||||||
if (action === 'delete') {
|
|
||||||
return confirm('{% trans "Ausgewählte Welcome-Einträge wirklich löschen?" %}');
|
|
||||||
}
|
|
||||||
if (action === 'pause') {
|
|
||||||
return confirm('{% trans "Ausgewählte Welcome-Einträge pausieren?" %}');
|
|
||||||
}
|
|
||||||
return confirm('{% trans "Ausgewählte Welcome-Einträge sofort senden?" %}');
|
|
||||||
};
|
|
||||||
|
|
||||||
syncState();
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user