2203bc471c
7 個設定分區各自加「儲存此區塊」按鈕,經 wp_ajax_wpdo_save_settings_section 以 AJAX 存檔,不再需要整頁 reload。 - 新增 ajax_save_settings_section() + 7 個 private save_section_*() - 新增 admin/assets/wpdo-settings.js(106 行)與 4 條 CSS 規則 - render_settings() 的 7 個 h3 各包上 .wpdo-settings-section[data-section] - 全頁送出按鈕改標「儲存全部設定」,原本的 POST handler 保持不變(漸進增強) hp-transient / wc-term-count 兩個分區的 toggle 仍由核心 admin 呈現(實作在 AddOn),只寫 wp_options,故不需 class_exists 守衛。
544 lines
15 KiB
CSS
544 lines
15 KiB
CSS
/**
|
|
* WP Data Optimizer — Admin Styles (Morandi Design System)
|
|
*
|
|
* Morandi tokens are provided via the 'morandi-design-system' CSS dependency
|
|
* registered in WPDO_Admin::enqueue_assets(). No @import needed.
|
|
*/
|
|
|
|
/* ── KPI Hero Strip (v2.16.0) ────────────────────────────────────────── */
|
|
|
|
.wpdo-kpi-hero {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
|
gap: var(--space-4);
|
|
margin: var(--space-5) 0;
|
|
}
|
|
|
|
.wpdo-kpi-card {
|
|
background: var(--color-bg-secondary, #FAF9F6);
|
|
border: 1px solid var(--color-bg-divider, #E8E3D9);
|
|
border-radius: var(--radius-lg);
|
|
padding: var(--space-4) var(--space-5);
|
|
box-shadow: var(--shadow-sm, 0 1px 3px rgba(58,53,48,0.08));
|
|
position: relative;
|
|
overflow: hidden;
|
|
transition: transform var(--duration-normal, 200ms) var(--ease-default, ease-out),
|
|
box-shadow var(--duration-normal, 200ms) var(--ease-default, ease-out);
|
|
}
|
|
|
|
.wpdo-kpi-card::before {
|
|
content: "";
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 3px;
|
|
background: linear-gradient(90deg,
|
|
var(--color-accent-warm, #c4a986),
|
|
var(--color-accent-warm, #c4a986));
|
|
opacity: 0.6;
|
|
}
|
|
|
|
.wpdo-kpi-card:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: var(--shadow-md, 0 4px 12px rgba(58,53,48,0.10));
|
|
}
|
|
|
|
.wpdo-kpi-label {
|
|
font-family: var(--font-family-body);
|
|
font-size: var(--text-sm, 13px);
|
|
color: var(--color-text-secondary, #6b6256);
|
|
font-weight: 500;
|
|
letter-spacing: 0.02em;
|
|
text-transform: uppercase;
|
|
margin-bottom: var(--space-2);
|
|
}
|
|
|
|
.wpdo-kpi-value {
|
|
font-family: var(--font-family-display);
|
|
font-size: 2.25rem;
|
|
line-height: 1.1;
|
|
font-weight: 700;
|
|
color: var(--color-text-primary, #3a3530);
|
|
margin-bottom: var(--space-2);
|
|
letter-spacing: -0.02em;
|
|
}
|
|
|
|
.wpdo-kpi-unit {
|
|
font-size: 1.1rem;
|
|
color: var(--color-text-secondary, #6b6256);
|
|
font-weight: 500;
|
|
margin-left: 2px;
|
|
}
|
|
|
|
.wpdo-kpi-empty {
|
|
color: var(--color-text-tertiary, #9a8e7e);
|
|
font-weight: 400;
|
|
}
|
|
|
|
.wpdo-kpi-sub {
|
|
font-family: var(--font-family-body);
|
|
font-size: var(--text-xs, 12px);
|
|
color: var(--color-text-secondary, #6b6256);
|
|
line-height: 1.4;
|
|
}
|
|
|
|
/* Per-KPI accent stripe color */
|
|
.wpdo-kpi--ratio::before { background: linear-gradient(90deg, #c4a986, #d4b89a); }
|
|
.wpdo-kpi--speedup::before { background: linear-gradient(90deg, #5a9a85, #7eb39e); }
|
|
.wpdo-kpi--coverage::before { background: linear-gradient(90deg, #8b7eb3, #a397c9); }
|
|
|
|
.wpdo-kpi--health-excellent::before { background: linear-gradient(90deg, #5a9a85, #7eb39e); }
|
|
.wpdo-kpi--health-good::before { background: linear-gradient(90deg, #c4a986, #d4b89a); }
|
|
.wpdo-kpi--health-warn::before { background: linear-gradient(90deg, #d4a574, #e0b888); }
|
|
.wpdo-kpi--health-crit::before { background: linear-gradient(90deg, #c47a7a, #d49090); }
|
|
|
|
.wpdo-kpi--health-excellent .wpdo-kpi-value { color: #4a8270; }
|
|
.wpdo-kpi--health-good .wpdo-kpi-value { color: #a8906f; }
|
|
.wpdo-kpi--health-warn .wpdo-kpi-value { color: #b88955; }
|
|
.wpdo-kpi--health-crit .wpdo-kpi-value { color: #a86060; }
|
|
|
|
@media (max-width: 600px) {
|
|
.wpdo-kpi-hero {
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: var(--space-3);
|
|
}
|
|
.wpdo-kpi-value {
|
|
font-size: 1.75rem;
|
|
}
|
|
}
|
|
|
|
/* ── Grouped Tab Navigation (v2.16.0) ────────────────────────────────── */
|
|
|
|
.wpdo-tab-nav {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-3) var(--space-4);
|
|
align-items: flex-end;
|
|
padding-bottom: 0;
|
|
border-bottom: 1px solid var(--color-bg-divider, #E8E3D9);
|
|
margin-bottom: var(--space-4);
|
|
}
|
|
|
|
.wpdo-tab-group {
|
|
display: inline-flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
margin-right: var(--space-2);
|
|
padding-right: var(--space-3);
|
|
position: relative;
|
|
}
|
|
|
|
.wpdo-tab-group:not(:last-child)::after {
|
|
content: "";
|
|
position: absolute;
|
|
right: 0;
|
|
top: 24px;
|
|
bottom: 4px;
|
|
width: 1px;
|
|
background: var(--color-bg-divider, #E8E3D9);
|
|
}
|
|
|
|
.wpdo-tab-group-label {
|
|
font-family: var(--font-family-body);
|
|
font-size: 11px;
|
|
letter-spacing: 0.06em;
|
|
text-transform: uppercase;
|
|
color: var(--color-text-tertiary, #9a8e7e);
|
|
font-weight: 500;
|
|
padding-left: var(--space-2);
|
|
user-select: none;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.wpdo-tab-group .nav-tab {
|
|
margin: 0 2px -1px 0;
|
|
transition: background-color var(--duration-fast, 120ms) ease,
|
|
color var(--duration-fast, 120ms) ease;
|
|
}
|
|
|
|
.wpdo-tab-group .nav-tab:hover {
|
|
background-color: var(--color-bg-tertiary, #F2EEE8);
|
|
color: var(--color-text-primary, #3a3530);
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.wpdo-tab-nav {
|
|
gap: var(--space-2);
|
|
}
|
|
.wpdo-tab-group {
|
|
margin-right: 0;
|
|
padding-right: var(--space-2);
|
|
}
|
|
.wpdo-tab-group-label {
|
|
font-size: 10px;
|
|
}
|
|
}
|
|
|
|
/* ── Layout ──────────────────────────────────────────────────────────── */
|
|
.wpdo-wrap .wpdo-tab-content {
|
|
margin-top: var(--space-5);
|
|
}
|
|
|
|
.wpdo-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
|
|
gap: var(--space-5);
|
|
margin-bottom: var(--space-5);
|
|
}
|
|
|
|
.wpdo-card {
|
|
background: var(--color-bg-secondary, #FAF9F6);
|
|
border: 1px solid var(--color-bg-divider, #E8E3D9);
|
|
border-radius: var(--radius-lg);
|
|
padding: var(--space-4) var(--space-5);
|
|
box-shadow: var(--shadow-sm, 0 1px 3px rgba(58,53,48,0.08));
|
|
overflow-x: auto; /* WCAG 1.4.10 Reflow: tables scroll within card, not page */
|
|
}
|
|
|
|
.wpdo-card h2 {
|
|
margin-top: 0;
|
|
padding-top: 0;
|
|
border-bottom: 1px solid var(--color-bg-divider, #E8E3D9);
|
|
padding-bottom: var(--space-3);
|
|
font-family: var(--font-family-display);
|
|
}
|
|
|
|
.wpdo-card h3,
|
|
.wpdo-card h4 {
|
|
margin-top: var(--space-3);
|
|
font-family: var(--font-family-display);
|
|
}
|
|
|
|
.wpdo-card-wide {
|
|
grid-column: 1 / -1;
|
|
}
|
|
|
|
/* Utility spacers replacing inline style="margin-top:N" */
|
|
.wpdo-mt-1 { margin-top: var(--space-2); }
|
|
.wpdo-mt-2 { margin-top: var(--space-3); }
|
|
.wpdo-mt-3 { margin-top: var(--space-5); }
|
|
.wpdo-mb-2 { margin-bottom: var(--space-3); }
|
|
.wpdo-table--narrow { max-width: 480px; }
|
|
.wpdo-table--medium { max-width: 700px; }
|
|
.wpdo-block--wide { max-width: 900px; }
|
|
.wpdo-col-param { width: 180px; }
|
|
|
|
/* Inline form row */
|
|
.wpdo-form-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-2);
|
|
flex-wrap: wrap;
|
|
margin: var(--space-3) 0;
|
|
}
|
|
|
|
/* ── Tables ──────────────────────────────────────────────────────────── */
|
|
.wpdo-table {
|
|
font-size: var(--text-sm);
|
|
font-family: var(--font-family-body);
|
|
}
|
|
|
|
.wpdo-table code,
|
|
.wpdo-wrap code {
|
|
font-size: var(--text-xs);
|
|
background: var(--color-bg-tertiary, #F2EEE8);
|
|
padding: 2px var(--space-1);
|
|
border-radius: var(--radius-sm);
|
|
font-family: var(--font-family-mono);
|
|
}
|
|
|
|
.wpdo-log-msg {
|
|
max-width: 400px;
|
|
word-break: break-word;
|
|
}
|
|
|
|
/* ── Touch targets (CLAUDE.md: 44px minimum) ─────────────────────────── */
|
|
.wpdo-wrap .button,
|
|
.wpdo-wrap .button-secondary,
|
|
.wpdo-wrap .button-primary,
|
|
.wpdo-wrap input[type="number"],
|
|
.wpdo-wrap input[type="text"],
|
|
.wpdo-wrap input[type="search"],
|
|
.wpdo-wrap select {
|
|
min-height: 44px;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.wpdo-wrap .button-small {
|
|
min-height: 40px; /* WCAG 2.2 AA: 24px min; 40px exceeds 2.5.8 while remaining compact */
|
|
padding: 0 var(--space-2);
|
|
}
|
|
|
|
.wpdo-wrap input[type="number"] {
|
|
padding: 6px var(--space-2);
|
|
}
|
|
|
|
.wpdo-wrap input[type="number"].wpdo-input--xs {
|
|
width: 72px; /* was inline 60px — bumped to fit 44px height without clipping digits */
|
|
}
|
|
|
|
.wpdo-wrap .button:focus-visible,
|
|
.wpdo-wrap input:focus-visible,
|
|
.wpdo-wrap select:focus-visible {
|
|
outline: 2px solid var(--color-terra-primary, #C4897A);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
/* ── Method pill for REST API tab (was inline #0073aa) ───────────────── */
|
|
.wpdo-method-pill {
|
|
background: var(--color-blue-primary, #9EB3C2);
|
|
color: var(--color-text-primary, #3A3530);
|
|
padding: 2px var(--space-2);
|
|
border-radius: var(--radius-sm);
|
|
font-size: var(--text-xs);
|
|
font-weight: var(--font-weight-semibold);
|
|
font-family: var(--font-family-mono);
|
|
}
|
|
|
|
/* Code block for curl examples (was inline #EFEFEF) */
|
|
.wpdo-wrap .wpdo-code-block {
|
|
background: var(--color-bg-tertiary, #F2EEE8);
|
|
color: var(--color-text-primary, #3A3530);
|
|
padding: var(--space-3);
|
|
border-radius: var(--radius-sm);
|
|
font-size: var(--text-xs);
|
|
font-family: var(--font-family-mono);
|
|
overflow: auto;
|
|
white-space: pre;
|
|
border: 1px solid var(--color-bg-divider, #E8E3D9);
|
|
}
|
|
|
|
/* ── Zone badges (icon + text, not colour alone — WCAG 1.4.1) ────────── */
|
|
.wpdo-zone {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 2px var(--space-2);
|
|
border-radius: var(--radius-sm);
|
|
font-size: var(--text-xs);
|
|
font-weight: var(--font-weight-semibold);
|
|
color: var(--color-text-primary, #3A3530);
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.wpdo-zone::before {
|
|
font-family: var(--font-family-mono);
|
|
font-weight: var(--font-weight-bold);
|
|
}
|
|
|
|
.wpdo-zone-hot {
|
|
background: var(--color-terra-primary, #C4897A);
|
|
}
|
|
.wpdo-zone-hot::before { content: "🔥"; }
|
|
|
|
.wpdo-zone-warm {
|
|
background: var(--color-apricot-medium, #C8B090);
|
|
}
|
|
.wpdo-zone-warm::before { content: "◐"; }
|
|
|
|
.wpdo-zone-cold {
|
|
background: var(--color-blue-medium, #8AA0B2);
|
|
}
|
|
.wpdo-zone-cold::before { content: "❄"; }
|
|
|
|
.wpdo-zone-archive {
|
|
background: var(--color-gray-medium, #AFA8A0);
|
|
}
|
|
.wpdo-zone-archive::before { content: "▦"; }
|
|
|
|
/* ── State badges (shape-prefixed for colour-blind legibility) ───────── */
|
|
.wpdo-state {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 2px var(--space-2);
|
|
border-radius: var(--radius-sm);
|
|
font-size: var(--text-xs);
|
|
font-weight: var(--font-weight-semibold);
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.wpdo-state::before {
|
|
font-family: var(--font-family-mono);
|
|
}
|
|
|
|
.wpdo-state-idle {
|
|
background: var(--color-bg-tertiary, #F2EEE8);
|
|
color: var(--color-text-primary, #3A3530);
|
|
}
|
|
.wpdo-state-idle::before { content: "○"; }
|
|
|
|
.wpdo-state-dual_write {
|
|
background: var(--color-apricot-lightest, #EDD9C0);
|
|
color: var(--color-text-primary, #3A3530);
|
|
}
|
|
.wpdo-state-dual_write::before { content: "⇄"; }
|
|
|
|
.wpdo-state-backfill {
|
|
background: var(--color-blue-lightest, #C8D6DE);
|
|
color: var(--color-text-primary, #3A3530);
|
|
}
|
|
.wpdo-state-backfill::before { content: "⟲"; }
|
|
|
|
.wpdo-state-verify {
|
|
background: var(--color-apricot-lightest, #EDD9C0);
|
|
color: var(--color-text-primary, #3A3530);
|
|
}
|
|
.wpdo-state-verify::before { content: "⚠"; }
|
|
|
|
.wpdo-state-cutover {
|
|
background: var(--color-green-lightest, #C8D5C4);
|
|
color: var(--color-text-primary, #3A3530);
|
|
}
|
|
.wpdo-state-cutover::before { content: "✓"; }
|
|
|
|
.wpdo-state-cleanup {
|
|
background: var(--color-blue-lightest, #C8D6DE);
|
|
color: var(--color-text-primary, #3A3530);
|
|
}
|
|
.wpdo-state-cleanup::before { content: "✂"; }
|
|
|
|
.wpdo-state-complete {
|
|
background: var(--color-green-primary, #A8B9A4);
|
|
color: var(--color-text-primary, #3A3530);
|
|
}
|
|
.wpdo-state-complete::before { content: "✔"; }
|
|
|
|
/* ── Generic badges ──────────────────────────────────────────────────── */
|
|
.wpdo-badge {
|
|
display: inline-block;
|
|
padding: 2px var(--space-2);
|
|
border-radius: var(--radius-sm);
|
|
font-size: var(--text-xs);
|
|
background: var(--color-bg-tertiary, #F2EEE8);
|
|
color: var(--color-text-primary, #3A3530);
|
|
}
|
|
|
|
.wpdo-badge-ok {
|
|
background: var(--color-green-lightest, #C8D5C4);
|
|
color: var(--color-text-primary, #3A3530);
|
|
}
|
|
|
|
.wpdo-badge-warn {
|
|
background: var(--color-apricot-lightest, #EDD9C0);
|
|
color: var(--color-text-primary, #3A3530);
|
|
}
|
|
|
|
/* ── Progress bars (transform-based — no layout-thrashing) ───────────── */
|
|
.wpdo-progress {
|
|
display: inline-block;
|
|
width: 120px;
|
|
height: 14px;
|
|
background: var(--color-bg-tertiary, #F2EEE8);
|
|
border-radius: var(--radius-full);
|
|
overflow: hidden;
|
|
vertical-align: middle;
|
|
margin-right: var(--space-2);
|
|
}
|
|
|
|
.wpdo-progress-bar {
|
|
height: 100%;
|
|
width: 100%;
|
|
background: var(--color-blue-primary, #9EB3C2);
|
|
border-radius: var(--radius-full);
|
|
transform-origin: left center;
|
|
transform: scaleX(var(--wpdo-progress, 0));
|
|
transition: transform var(--duration-slow, 0.4s) var(--ease-default, ease);
|
|
}
|
|
|
|
.wpdo-progress-text {
|
|
font-size: var(--text-xs);
|
|
color: var(--color-text-primary, #3A3530);
|
|
}
|
|
|
|
/* ── Confidence bar ──────────────────────────────────────────────────── */
|
|
.wpdo-confidence {
|
|
display: inline-block;
|
|
width: 60px;
|
|
height: 10px;
|
|
background: var(--color-bg-tertiary, #F2EEE8);
|
|
border-radius: var(--radius-full);
|
|
overflow: hidden;
|
|
vertical-align: middle;
|
|
margin-right: var(--space-1);
|
|
}
|
|
|
|
.wpdo-confidence-bar {
|
|
height: 100%;
|
|
width: 100%;
|
|
background: var(--color-green-primary, #A8B9A4);
|
|
border-radius: var(--radius-full);
|
|
transform-origin: left center;
|
|
transform: scaleX(var(--wpdo-confidence, 0));
|
|
}
|
|
|
|
/* ── Screen reader only ──────────────────────────────────────────────── */
|
|
.wpdo-sr-only {
|
|
position: absolute;
|
|
width: 1px;
|
|
height: 1px;
|
|
margin: -1px;
|
|
padding: 0;
|
|
overflow: hidden;
|
|
clip: rect(0 0 0 0);
|
|
border: 0;
|
|
}
|
|
|
|
/* ── Tab red-dot badge (v2.8.1) ──────────────────────────────────────── */
|
|
.nav-tab .wpdo-tab-dot {
|
|
display: inline-block;
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 50%;
|
|
background: #dc3232;
|
|
margin-left: 6px;
|
|
vertical-align: middle;
|
|
box-shadow: 0 0 6px rgba(220, 50, 50, 0.6);
|
|
animation: wpdo-tab-dot-pulse 2s ease infinite;
|
|
}
|
|
|
|
@keyframes wpdo-tab-dot-pulse {
|
|
0% { box-shadow: 0 0 0 0 rgba(220, 50, 50, 0.7); }
|
|
70% { box-shadow: 0 0 0 6px rgba(220, 50, 50, 0); }
|
|
100% { box-shadow: 0 0 0 0 rgba(220, 50, 50, 0); }
|
|
}
|
|
|
|
/* ── Reduced motion ──────────────────────────────────────────────────── */
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.wpdo-progress-bar {
|
|
transition-duration: 0.01ms;
|
|
}
|
|
.nav-tab .wpdo-tab-dot {
|
|
animation: none;
|
|
}
|
|
}
|
|
|
|
/* ── Settings per-section instant save (v3.0.2 backport) ────────────── */
|
|
|
|
.wpdo-settings-section {
|
|
background: var(--color-surface-card, #fbf7f0);
|
|
border: 1px solid var(--color-border-soft, #e5dccd);
|
|
border-radius: var(--radius-md, 12px);
|
|
padding: var(--space-4, 16px) var(--space-6, 24px);
|
|
margin-bottom: var(--space-5, 20px);
|
|
}
|
|
|
|
.wpdo-section-save-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-3, 12px);
|
|
padding-top: var(--space-3, 12px);
|
|
}
|
|
|
|
.wpdo-section-save-status {
|
|
font-size: 0.9rem;
|
|
color: var(--color-success, #5a8c5a);
|
|
opacity: 0;
|
|
transition: opacity var(--duration-normal, 200ms) var(--ease-default, ease);
|
|
}
|
|
|
|
.wpdo-section-save-status.visible {
|
|
opacity: 1;
|
|
}
|