PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.7.1
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.7.1
2.7.1 2.7.2 2.7.0 2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 All 141 releases
← All changes | admin/css/metasync-dashboard.css +217 -21 2.6.13 → 2.7.1 View file →
@@ -9,9 +9,11 @@
9 9 [data-theme="dark"] {
10 10 --dashboard-bg: #0f1419;
11 11 --dashboard-card-bg: #1a1f26;
12 12 --dashboard-card-hover: #222831;
13 + --dashboard-input-bg: #22272e;
13 14 --dashboard-text-primary: #ffffff;
15 + --dashboard-text: #ffffff;
14 16 --dashboard-text-secondary: #9ca3af;
15 17 --dashboard-accent: #3b82f6;
16 18 --dashboard-accent-hover: #2563eb;
17 19 --dashboard-success: #10b981;
@@ -28,9 +30,11 @@
28 30 [data-theme="light"] {
29 31 --dashboard-bg: #f8f9fa;
30 32 --dashboard-card-bg: #ffffff;
31 33 --dashboard-card-hover: #f1f3f5;
34 + --dashboard-input-bg: #ffffff;
32 35 --dashboard-text-primary: #1a1f26;
36 + --dashboard-text: #1a1f26;
33 37 --dashboard-text-secondary: #6b7280;
34 38 --dashboard-accent: #3b82f6;
35 39 --dashboard-accent-hover: #2563eb;
36 40 --dashboard-success: #10b981;
@@ -123,8 +127,19 @@
123 127 border-left-color: var(--dashboard-error) !important;
124 128 background: rgba(239, 68, 68, 0.15) !important;
125 129 }
126 130
131 +/* Specific warning notice styling ONLY in plugin.
132 + Without this, warning notices fell through to the base .notice rule above
133 + (blue border-left, plain card background) because that rule is !important
134 + and the .notice-warning colours defined further down this file are not —
135 + !important always wins regardless of source order, so the warning never
136 + actually rendered yellow/amber. Mirrors the .notice-error override above. */
137 +.metasync-dashboard-wrap .notice.notice-warning {
138 + border-left-color: var(--dashboard-warning) !important;
139 + background: rgba(245, 158, 11, 0.15) !important;
140 +}
141 +
127 142 /* License mismatch notice specific styling ONLY in plugin */
128 143 .metasync-dashboard-wrap .notice:has(.dashicons-warning):before,
129 144 .metasync-dashboard-wrap .notice[class*="license"]:before,
130 145 .metasync-dashboard-wrap .notice[class*="mismatch"]:before {
@@ -283,8 +298,15 @@
283 298 .metasync-header[data-current-theme="dark"] .metasync-logo-light {
284 299 display: none;
285 300 }
286 301
302 +/* Light theme must explicitly show the light logo: its base state is
303 + display:none, and hiding the dark logo alone would leave no logo visible. */
304 +[data-theme="light"] .metasync-logo-light,
305 +.metasync-header[data-current-theme="light"] .metasync-logo-light {
306 + display: block;
307 +}
308 +
287 309 /* Default (non-whitelabel) SA logo: invert on light theme so the white asset
288 310 stays visible against a light background. Dark theme keeps the original. */
289 311 [data-theme="light"] .metasync-logo-default,
290 312 .metasync-header[data-current-theme="light"] .metasync-logo-default {
@@ -1021,9 +1043,9 @@
1021 1043
1022 1044 /* Disabled state — needed because the base .button-primary rule keeps the
1023 1045 full gradient even when prop('disabled', true) is set. Without this,
1024 1046 the Sync Now button stays blue/purple while the cooldown countdown is
1025 - active (WP-350 QA report).
1047 + active (QA report).
1026 1048
1027 1049 The .is-throttled class is the primary driver for the Sync Now cooldown
1028 1050 visual because earlier code in the AJAX callback chain calls
1029 1051 .prop('disabled', false) before our refresh runs, and in some browsers
@@ -1040,9 +1062,9 @@
1040 1062 .metasync-dashboard-wrap .button-primary.is-throttled,
1041 1063 .metasync-dashboard-wrap .button-secondary.is-throttled {
1042 1064 /* Replace the blue/purple gradient with a solid grey. The base rule sets
1043 1065 `background: var(--dashboard-gradient-primary)`, so opacity + grayscale
1044 - alone left the button a dimmed blue (WP-350 QA: "still blue on Elementor").
1066 + alone left the button a dimmed blue (QA: "still blue on Elementor").
1045 1067 background/filter/pointer-events carry !important so a page-builder's
1046 1068 admin stylesheet (Elementor ships more than Divi) can't override them. */
1047 1069 background: #d5d7da !important;
1048 1070 background-image: none !important;
@@ -1332,9 +1354,13 @@
1332 1354 border-color: var(--dashboard-error);
1333 1355 /* Removed translateY animation - was too distracting */
1334 1356 }
1335 1357
1336 -/* Connect Status Messages - Dashboard Style */
1358 +/* Connect Status Messages - Dashboard Style
1359 + The box holds two block children — .metasync-sa-connect-status-content and
1360 + .metasync-sa-connect-actions — so it must stack. As a row, the actions block
1361 + sized to its buttons while the content block (flex: 1, so flex-basis: 0) was
1362 + squeezed into whatever was left, wrapping the message one word per line. */
1337 1363 .metasync-dashboard-wrap .metasync-sa-connect-status,
1338 1364 .metasync-dashboard-wrap #sa-connect-status-message {
1339 1365 margin-top: 16px;
1340 1366 padding: 16px 20px;
@@ -1339,9 +1365,10 @@
1339 1365 margin-top: 16px;
1340 1366 padding: 16px 20px;
1341 1367 border-radius: 12px;
1342 1368 display: flex;
1343 - align-items: flex-start;
1369 + flex-direction: column;
1370 + align-items: stretch;
1344 1371 gap: 12px;
1345 1372 font-weight: 500;
1346 1373 /* Removed slideInNotice animation - was too distracting */
1347 1374 backdrop-filter: blur(10px);
@@ -1597,9 +1624,14 @@
1597 1624 }
1598 1625
1599 1626 /* Connect Status Message Content */
1600 1627 .metasync-dashboard-wrap .metasync-sa-connect-status-content {
1601 - flex: 1;
1628 + /* min-width: 0 keeps a long unbroken string (a pasted URL, a UUID) from
1629 + setting the flex item's min-content width and re-inflating the box. */
1630 + flex: 0 0 auto;
1631 + min-width: 0;
1632 + /* Spacing between content and actions is the container's gap now. */
1633 + margin-bottom: 0;
1602 1634 }
1603 1635
1604 1636 .metasync-dashboard-wrap .metasync-sa-connect-status-title {
1605 1637 font-weight: 600;
@@ -1604,11 +1636,15 @@
1604 1636 .metasync-dashboard-wrap .metasync-sa-connect-status-title {
1605 1637 font-weight: 600;
1606 1638 font-size: 15px;
1607 1639 margin-bottom: 8px;
1608 - display: flex;
1609 - align-items: center;
1610 - gap: 8px;
1640 + /* Block, not flex. WordPress core's emoji script rewrites the leading
1641 + emoji into <img class="emoji">; as a flex container that image became a
1642 + flex item of its own and, under align-items: center, floated to the
1643 + vertical middle of a wrapped title. Inline flow keeps it on the first
1644 + line and wraps with the text. The title string already carries the
1645 + separating space, so the old gap is not needed. */
1646 + display: block;
1611 1647 }
1612 1648
1613 1649 .metasync-dashboard-wrap .metasync-sa-connect-status-message {
1614 1650 font-size: 14px;
@@ -1613,14 +1649,14 @@
1613 1649 .metasync-dashboard-wrap .metasync-sa-connect-status-message {
1614 1650 font-size: 14px;
1615 1651 line-height: 1.5;
1616 1652 opacity: 0.9;
1617 - margin-bottom: 12px;
1653 + margin-bottom: 0;
1618 1654 }
1619 1655
1620 1656 /* Existing Connect Actions Container */
1621 1657 .metasync-dashboard-wrap .metasync-sa-connect-actions {
1622 - margin-top: 16px;
1658 + margin-top: 0;
1623 1659 display: flex;
1624 1660 gap: 12px;
1625 1661 flex-wrap: wrap;
1626 1662 align-items: center;
@@ -1697,10 +1733,8 @@
1697 1733
1698 1734 .metasync-dashboard-wrap .metasync-sa-connect-status {
1699 1735 padding: 16px;
1700 1736 margin-top: 12px;
1701 - flex-direction: column;
1702 - align-items: flex-start;
1703 1737 gap: 8px;
1704 1738 }
1705 1739
1706 1740 .metasync-dashboard-wrap .metasync-sa-connect-status-title {
@@ -2452,9 +2486,13 @@
2452 2486 /* Sync Log Header */
2453 2487 .sync-log-header {
2454 2488 display: flex;
2455 2489 justify-content: space-between;
2456 - align-items: flex-start;
2490 + /* Centred rather than flex-start: the title section used to be a two-line
2491 + * block (24px heading + description) that read fine top-aligned, but it is
2492 + * now a single line of copy sitting beside a 34px control row. Top-aligning
2493 + * a one-line block against that row leaves the text visibly high. */
2494 + align-items: center;
2457 2495 margin-bottom: 30px;
2458 2496 gap: 20px;
2459 2497 }
2460 2498
@@ -2461,14 +2499,11 @@
2461 2499 .sync-log-title-section {
2462 2500 flex: 1;
2463 2501 }
2464 2502
2465 -.sync-log-title-section h2 {
2466 - color: var(--dashboard-text-primary);
2467 - margin-bottom: 8px;
2468 - font-size: 24px;
2469 - font-weight: 600;
2470 -}
2503 +/* The card no longer renders an <h2> — the page title and description come
2504 + * from the layout header (render_layout_open), and the card carries only the
2505 + * 90-day retention hint. See admin/class-metasync-admin.php. */
2471 2506
2472 2507 /* Sync Log Filters */
2473 2508 .sync-log-filters {
2474 2509 flex-shrink: 0;
@@ -2496,8 +2531,49 @@
2496 2531 min-width: 150px;
2497 2532 }
2498 2533 }
2499 2534
2535 +/*
2536 + * Changes Log toolbar — one shared height for the Clear Log button and the two
2537 + * filter selects.
2538 + *
2539 + * The button is styled inline in the renderer (padding:6px 14px, no height) and
2540 + * rendered ~29px, while the selects picked up WordPress core's own
2541 + * `select { min-height: 40px }` (wp-admin forms.css) on top of
2542 + * .sync-filter-select's padding — so the button sat noticeably shorter than the
2543 + * controls beside it.
2544 + *
2545 + * min-height is the load-bearing declaration here: core's min-height:40px beats
2546 + * a plain height:34px no matter how specific the selector, because min-height
2547 + * wins over height by definition. Setting both pins the row at 34px.
2548 + */
2549 +#metasync-clear-sync-log-btn,
2550 +.sync-log-filters .sync-filter-select {
2551 + height: 34px;
2552 + min-height: 34px;
2553 + box-sizing: border-box;
2554 +}
2555 +
2556 +/* Vertical padding is zeroed so the fixed height above is what the row sees;
2557 + * .sync-filter-select's own padding:8px 12px would otherwise fight it. The base
2558 + * padding-right (34px, reserving space for the chevron) is !important there and
2559 + * still applies. */
2560 +.sync-log-filters .sync-filter-select {
2561 + padding-top: 0;
2562 + padding-bottom: 0;
2563 + line-height: 32px;
2564 +}
2565 +
2566 +/* The button keeps its inline padding:6px 14px, which leaves a 20px content box
2567 + * inside the 34px border-box height — too short for a 32px line-height, so the
2568 + * label would sit off-centre. Flex centering makes line-height irrelevant. */
2569 +#metasync-clear-sync-log-btn {
2570 + display: inline-flex;
2571 + align-items: center;
2572 + justify-content: center;
2573 + line-height: 1;
2574 +}
2575 +
2500 2576 .sync-filter-select {
2501 2577 background-color: var(--dashboard-card-bg);
2502 2578 border: 1px solid var(--dashboard-border);
2503 2579 color: var(--dashboard-text-primary);
@@ -2690,13 +2766,20 @@
2690 2766 opacity: 0.6;
2691 2767 color: var(--dashboard-text-secondary);
2692 2768 }
2693 2769
2694 -.sync-log-empty h3 {
2770 +/* The empty-state heading is an <h2>: the card's own <h2> is gone, so the
2771 + * layout's <h1> is the only heading above it and an <h3> here would skip a
2772 + * level. Scoped through .metasync-dashboard-wrap to out-specify
2773 + * ".metasync-dashboard-wrap .dashboard-card h2" (0,3,1) above, which would
2774 + * otherwise impose its 1.5rem card-title sizing and flex display on what is
2775 + * a centred empty-state message. Sizing matches the previous <h3>. */
2776 +.metasync-dashboard-wrap .sync-log-empty h2 {
2695 2777 color: var(--dashboard-text-primary);
2696 - margin-bottom: 8px;
2778 + margin: 0 0 8px 0;
2697 2779 font-size: 18px;
2698 2780 font-weight: 600;
2781 + display: block;
2699 2782 }
2700 2783
2701 2784 .sync-log-empty p {
2702 2785 font-size: 14px;
@@ -2726,8 +2809,61 @@
2726 2809 align-items: center;
2727 2810 gap: 8px;
2728 2811 }
2729 2812
2813 +/*
2814 + * Rows-per-page selector on the Changes Log footer.
2815 + *
2816 + * .metasync-per-page-select is emitted by Metasync_Per_Page_Helper::render_selector()
2817 + * on four screens (Redirections, 404 Monitor, Changes Log, Media Library), but
2818 + * only the other three style it. On the Changes Log it fell through to the
2819 + * generic ".metasync-dashboard-wrap select" rule — width:100%, max-width:400px,
2820 + * padding:12px 16px — so a two-digit control rendered ~295px wide and 64px tall
2821 + * next to 34px dashboard controls.
2822 + *
2823 + * Scoped to .sync-log-pagination-info, a Changes Log-only wrapper, rather than
2824 + * to the shared class: the other three screens already size this control via
2825 + * their own rules (".wrap .tablenav select" for Redirections and 404 Monitor,
2826 + * "#metasync-image-library-form .tablenav select" for Media Library), and a
2827 + * shared rule here would be one more thing competing with them. Keeping it
2828 + * page-scoped means those screens are untouched by construction, not by
2829 + * winning a specificity tie.
2830 + *
2831 + * min-height pairs with height for the same reason as the toolbar rule above —
2832 + * core's select{min-height:40px} would otherwise inflate it back to 40px.
2833 + *
2834 + * Sizing only: admin/js/metasync-per-page.js drives behaviour off the element's
2835 + * data-* attributes, which CSS must not disturb.
2836 + */
2837 +.sync-log-pagination-info .metasync-per-page-select {
2838 + height: 34px;
2839 + min-height: 34px;
2840 + line-height: 32px;
2841 + padding: 0 28px 0 10px;
2842 + font-size: 13px;
2843 + width: auto;
2844 + border-radius: 6px;
2845 + box-sizing: border-box;
2846 + vertical-align: middle;
2847 + cursor: pointer;
2848 + appearance: none;
2849 + -webkit-appearance: none;
2850 + -moz-appearance: none;
2851 + background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23d1d5db' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6,9 12,15 18,9'%3e%3c/polyline%3e%3c/svg%3E");
2852 + background-repeat: no-repeat;
2853 + background-position: right 10px center;
2854 + background-size: 14px;
2855 +}
2856 +
2857 +/* Mirrors .sync-filter-select option. The rule above is the first to apply
2858 + * appearance:none to this control, and dark-theme <option> popups need their
2859 + * colours stated explicitly rather than inherited. */
2860 +.sync-log-pagination-info .metasync-per-page-select option {
2861 + background: var(--dashboard-card-bg);
2862 + color: var(--dashboard-text-primary);
2863 + padding: 8px;
2864 +}
2865 +
2730 2866 .sync-pagination-btn {
2731 2867 display: inline-flex;
2732 2868 align-items: center;
2733 2869 justify-content: center;
@@ -2827,8 +2963,13 @@
2827 2963 gap: 8px;
2828 2964 width: 100%;
2829 2965 }
2830 2966
2967 + /* The vertical half of this padding is intentionally overridden by
2968 + * ".sync-log-filters .sync-filter-select" (0,2,0) above, which pins the
2969 + * toolbar row at 34px. Do NOT re-declare padding here under that
2970 + * descendant selector: it would tie on specificity, win on source order,
2971 + * and silently restore the misalignment this rule set exists to avoid. */
2831 2972 .sync-filter-select {
2832 2973 min-width: 110px;
2833 2974 font-size: 13px;
2834 2975 padding: 6px 8px;
@@ -3349,5 +3490,60 @@
3349 3490 font-size: 24px;
3350 3491 width: 24px;
3351 3492 height: 24px;
3352 3493 color: var(--dashboard-text-secondary);
3494 +}
3495 +
3496 +/* Dismiss button on plugin notices.
3497 + The dashboard script appends a .notice-dismiss to every notice inside
3498 + .metasync-dashboard-wrap, but the notice itself was never given a
3499 + positioning context, so WordPress core's `position: absolute` on the
3500 + button resolved against whatever ancestor happened to be positioned
3501 + instead of the notice box — landing the icon mid-text rather than in the
3502 + notice's own top-right corner. Anchor it explicitly to the notice. */
3503 +.metasync-dashboard-wrap .notice {
3504 + position: relative;
3505 +}
3506 +
3507 +.metasync-dashboard-wrap .notice-dismiss {
3508 + position: absolute;
3509 + top: 8px;
3510 + right: 8px;
3511 + width: 28px;
3512 + height: 28px;
3513 + display: flex;
3514 + align-items: center;
3515 + justify-content: center;
3516 +}
3517 +
3518 +/* WordPress core colours the dismiss icon a near-black grey (#1e1e1e), which
3519 + reads fine on the light theme but is effectively invisible against the dark
3520 + theme's card background. Give it a theme-aware colour instead. !important
3521 + because the icon's colour otherwise wins on specificity alone, the same way
3522 + the base .notice rule above needs !important to beat WP core.
3523 + `.metasync-dashboard-wrap[data-theme="dark"]` matches the common case: the
3524 + wrap carries data-theme itself (set server-side on page load). The plain
3525 + `[data-theme="dark"] .metasync-dashboard-wrap` descendant form is kept too,
3526 + since the in-page theme switcher additionally stamps data-theme on <html>
3527 + once the user toggles it, and either could be the one present. */
3528 +.metasync-dashboard-wrap[data-theme="dark"] .notice-dismiss::before,
3529 +[data-theme="dark"] .metasync-dashboard-wrap .notice-dismiss::before {
3530 + color: var(--dashboard-text-secondary) !important;
3531 +}
3532 +
3533 +.metasync-dashboard-wrap[data-theme="dark"] .notice-dismiss:hover::before,
3534 +.metasync-dashboard-wrap[data-theme="dark"] .notice-dismiss:focus::before,
3535 +[data-theme="dark"] .metasync-dashboard-wrap .notice-dismiss:hover::before,
3536 +[data-theme="dark"] .metasync-dashboard-wrap .notice-dismiss:focus::before {
3537 + color: var(--dashboard-text-primary) !important;
3538 +}
3539 +
3540 +/* Remove WordPress footer space on MetaSync admin pages. */
3541 +body:has(.metasync-dashboard-wrap) #wpbody-content,
3542 +body:has(.metasync-otto-debug) #wpbody-content {
3543 + padding-bottom: 0;
3544 +}
3545 +
3546 +body:has(.metasync-dashboard-wrap) #wpfooter,
3547 +body:has(.metasync-otto-debug) #wpfooter {
3548 + display: none;
3353 3549 }