From 79b5a9b73745c1679c695f5c618236d7c0477b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 12 Dec 2025 14:12:15 +0100 Subject: [PATCH 01/16] Admin UI: Add design system tokens for admin reskin Introduces _tokens.scss with Sass variables derived from the WordPress Design System in Figma. These tokens provide consistent values for: - Spacing (4px grid units) - Border radius - Gray scale - Semantic colors (alerts/notices) - Typography scale - Elevation (box shadows) - Component sizing (buttons, inputs, checkboxes) The tokens are imported into _variables.scss and can be used across all admin stylesheets compiled via Sass. Note: These are Sass-only variables. No new CSS custom properties are exposed to maintain backward compatibility. The only CSS custom properties available remain those from wp-base-styles. Part of the WordPress 7.0 admin visual reskin initiative. See: https://core.trac.wordpress.org/ticket/64308 --- src/wp-admin/css/colors/_tokens.scss | 212 ++++++++++++++++++++++++ src/wp-admin/css/colors/_variables.scss | 5 +- 2 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 src/wp-admin/css/colors/_tokens.scss diff --git a/src/wp-admin/css/colors/_tokens.scss b/src/wp-admin/css/colors/_tokens.scss new file mode 100644 index 0000000000000..785f1f47f5076 --- /dev/null +++ b/src/wp-admin/css/colors/_tokens.scss @@ -0,0 +1,212 @@ +// ========================================================================== +// WordPress Design System Tokens +// ========================================================================== +// +// These tokens are derived from the WordPress Design System in Figma: +// https://www.figma.com/design/804HN2REV2iap2ytjRQ055/WordPress-Design-System +// +// IMPORTANT: Do NOT expose these as CSS custom properties. +// Use these Sass variables to compile to static CSS values. +// The only CSS custom properties available are those in wp-base-styles: +// - --wp-admin-theme-color +// - --wp-admin-theme-color--rgb +// - --wp-admin-theme-color-darker-10 +// - --wp-admin-theme-color-darker-20 +// - --wp-admin-border-width-focus +// +// ========================================================================== + + +// -------------------------------------------------------------------------- +// Grid Units (Spacing) +// -------------------------------------------------------------------------- +// Based on 4px base unit. Use for padding, margin, and gap values. + +$grid-unit-05: 4px; // Scales/grid unit 05 +$grid-unit-10: 8px; // Scales/grid unit 10 +$grid-unit-15: 12px; // Scales/grid unit 15 +$grid-unit-20: 16px; // Scales/grid unit 20 +$grid-unit-30: 24px; // Scales/grid unit 30 +$grid-unit-40: 32px; // Scales/grid unit 40 +$grid-unit-50: 40px; // Scales/grid unit 50 +$grid-unit-60: 48px; // Scales/grid unit 60 +$grid-unit-70: 56px; // Scales/grid unit 70 + + +// -------------------------------------------------------------------------- +// Border Radius +// -------------------------------------------------------------------------- + +$radius-xs: 1px; // radius-xs +$radius-s: 2px; // radius-s - Buttons, inputs +$radius-m: 4px; // radius-m - Focus rings +$radius-l: 8px; // radius-l - Cards, dashboard widgets +$radius-30: 12px; // Radius 30 +$radius-full: 9999px; // radius-full - Pills, avatars, circles + + +// -------------------------------------------------------------------------- +// Gray Scale +// -------------------------------------------------------------------------- +// Neutral colors for backgrounds, borders, and text. + +$gray-100: #f0f0f0; // Scales/Grays/gray-100 - Page background, disabled inputs +$gray-200: #e0e0e0; // Scales/Grays/gray-200 +$gray-300: #dddddd; // Scales/Grays/gray-300 +$gray-400: #cccccc; // Scales/Grays/gray-400 - Disabled borders +$gray-600: #949494; // Scales/Grays/gray-600 - Input borders, disabled text +$gray-700: #757575; // Scales/Grays/gray-700 +$gray-800: #2f2f2f; // Scales/Grays/gray-800 +$gray-900: #1e1e1e; // Scales/Grays/gray-900 - Primary text + +$white: #ffffff; // Scales/Black & White/white + + +// -------------------------------------------------------------------------- +// Theme Colors (Static reference values) +// -------------------------------------------------------------------------- +// For actual theme color usage, use var(--wp-admin-theme-color) instead. +// These are provided for reference and for contexts where CSS vars aren't available. + +$theme-reference: #3858e9; // Scales/Theme/theme (modern scheme) +$theme-darker-10-reference: #2145e6; // Scales/Theme/theme-darker-10 +$theme-darker-20-reference: #183ad6; // Scales/Theme/theme-darker-20 +$theme-alpha-04: rgba(56, 88, 233, 0.04); // Scales/Theme/theme-alpha-04 (4% opacity) +$theme-alpha-08: rgba(56, 88, 233, 0.08); // Scales/Theme/theme-alpha-08 (8% opacity) + +$brand-9: #4465db; // Scales/brand-9 - Focus ring color (static, not theme-dependent) + + +// -------------------------------------------------------------------------- +// Semantic Colors +// -------------------------------------------------------------------------- +// Use these for notices, alerts, and status indicators. +// These are intentionally NOT theme-dependent for consistency. + +$alert-yellow: #f0b849; // Scales/Yellow/alert-yellow - Warnings +$alert-green: #4ab866; // Scales/Green/alert-green - Success +$alert-red: #cc1818; // Scales/Red/alert-red - Errors +$alert-blue: #3858e9; // Info notices (matches modern theme) + +// Background tints for notices +$alert-yellow-bg: #fef8ee; // Warning notice background +$alert-green-bg: #eff9f1; // Success notice background +$alert-red-bg: #fcf0f0; // Error notice background + +$synced-color: #7a00df; // Scales/Purple/--wp-block-synced-color + + +// -------------------------------------------------------------------------- +// Text Colors +// -------------------------------------------------------------------------- + +$text-primary: $gray-900; // Primary text color +$text-secondary: $gray-700; // Secondary text +$text-tertiary: #5d5d5d; // Alias/text/text-tertiary - Placeholder, hints +$text-disabled: $gray-600; // Disabled text + + +// -------------------------------------------------------------------------- +// Component Tokens +// -------------------------------------------------------------------------- + +// Inputs +$input-bg: $white; // Alias/bg/bg-input +$input-border-color: $gray-600; // Default input border +$input-border-color-disabled: $gray-400; +$input-bg-disabled: $gray-100; +$input-border-width-default: 1px; // Input/Default +$input-border-width-focus: 1.5px; // Input/Focus +$field-spacing-horizontal: 8px; // Alias/field-spacing-horizontal + +// Checkboxes and Radios +$checkbox-size: 16px; // Alias/checkbox +$radio-size: 16px; // Alias/radio + +// Toggles +$toggle-width: 32px; // Alias/toggle-width +$toggle-height: 16px; // Alias/toggle-height + +// Buttons +// Note: Gutenberg is transitioning to 40px as the default button size. +// The "compact" size (32px) is available for space-constrained contexts. +$button-height-default: 40px; // Default button height (next-default-40px) +$button-height-compact: 32px; // Compact button height +$button-height-small: 24px; // Small button height + +// Cards and Surfaces +$card-bg: $white; +$card-border-color: rgba(0, 0, 0, 0.1); +$card-border-width: 1px; +$card-border-radius: $radius-l; // 8px for dashboard widgets +$card-border-radius-metabox: 0; // 0 for post editor metaboxes +$card-divider-color: rgba(0, 0, 0, 0.1); + +// Card Padding Sizes +$card-padding-xs: $grid-unit-10; // 8px - xSmall cards +$card-padding-sm: $grid-unit-20; // 16px - Small cards (metaboxes, dashboard widgets) +$card-padding-md-h: $grid-unit-30; // 24px - Medium cards horizontal +$card-padding-md-v: $grid-unit-20; // 16px - Medium cards vertical +$card-padding-lg-h: $grid-unit-40; // 32px - Large cards horizontal +$card-padding-lg-v: $grid-unit-30; // 24px - Large cards vertical + +// Page Layout +$page-padding-large: 48px; // Alias/page-large +$page-padding-small: 24px; // Alias/page-small + + +// -------------------------------------------------------------------------- +// Typography Scale +// -------------------------------------------------------------------------- + +// Font Sizes +$font-size-xs: 11px; // xs - Small labels, button small +$font-size-s: 12px; // s - Body small +$font-size-m: 13px; // m - Base body text, buttons +$font-size-l: 15px; // l - Body large, heading large +$font-size-xl: 20px; // xl - Heading XL + +// Line Heights +$line-height-xs: 16px; // xs +$line-height-s: 20px; // s - Most UI elements +$line-height-m: 24px; // m - Body large + +// Font Weights +$font-weight-regular: 400; // Regular - Body text +$font-weight-medium: 500; // Medium - Headings, buttons + + +// -------------------------------------------------------------------------- +// Elevation (Box Shadows) +// -------------------------------------------------------------------------- + +$elevation-xs: + 0 4px 4px rgba(0, 0, 0, 0.01), + 0 3px 3px rgba(0, 0, 0, 0.02), + 0 1px 2px rgba(0, 0, 0, 0.02), + 0 1px 1px rgba(0, 0, 0, 0.03); + +$elevation-s: + 0 8px 8px rgba(0, 0, 0, 0.02), + 0 1px 2px rgba(0, 0, 0, 0.05); + +$elevation-m: + 0 16px 16px rgba(0, 0, 0, 0.02), + 0 4px 5px rgba(0, 0, 0, 0.03), + 0 2px 3px rgba(0, 0, 0, 0.05); + +$elevation-l: + 0 50px 43px rgba(0, 0, 0, 0.02), + 0 30px 36px rgba(0, 0, 0, 0.04), + 0 15px 27px rgba(0, 0, 0, 0.07), + 0 5px 15px rgba(0, 0, 0, 0.08); + + +// -------------------------------------------------------------------------- +// Layout +// -------------------------------------------------------------------------- + +$modal-width-small: 384px; // Layout/Modal small +$modal-width-medium: 512px; // Layout/Modal medium +$modal-width-large: 840px; // Layout/Modal large + diff --git a/src/wp-admin/css/colors/_variables.scss b/src/wp-admin/css/colors/_variables.scss index 8a073f830e4b6..d37c2b1392f00 100644 --- a/src/wp-admin/css/colors/_variables.scss +++ b/src/wp-admin/css/colors/_variables.scss @@ -1,5 +1,8 @@ @use "sass:color"; +// Import design system tokens +@use "tokens" as *; + // assign default value to all undefined variables $scheme-name: "default" !default; @@ -15,7 +18,7 @@ $notification-color: #d54e21 !default; // global -$body-background: #f1f1f1 !default; +$body-background: $gray-100 !default; $link: #0073aa !default; $link-focus: color.adjust($link, $lightness: 10%) !default; From 1fbb28715e5b9d9b52b801fb7ce19252b6775546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 12 Dec 2025 15:11:10 +0100 Subject: [PATCH 02/16] Admin UI: Reskin buttons to align with WordPress Design System Update all button styles to match Gutenberg's component patterns and the WordPress Design System specifications. **Sizing (aligned with Gutenberg's next-default-40px):** - Default buttons: 40px height (was 30px) - Compact buttons: 32px (new class for space-constrained contexts) - Small buttons: 24px (was 26px) - Hero buttons: 48px (was 46px) - Use min-height + line-height for accessibility with browser zoom **Visual updates:** - Border radius: 2px (was 3px) - Font weight: 500 (was 400/normal) - Transparent background for secondary/tertiary buttons **Focus states (Gutenberg-style outer ring):** - Primary: outer theme color ring + inner white ring for contrast - Secondary/Tertiary/Link: single outer theme color ring - Use var(--wp-admin-theme-color) for focus ring color **Hover/Active states:** - Secondary buttons: subtle rgba() background tint on hover/active - Use theme-color-darker-20 for hover text/border colors - Link buttons: theme-color-darker-20 on hover **Components updated:** - .button, .button-primary, .button-secondary - .button-link, .button-link-delete - .page-title-action (now uses secondary button pattern) See: https://core.trac.wordpress.org/ticket/64308 --- src/wp-admin/css/colors/_admin.scss | 144 ++++++++++----------------- src/wp-admin/css/colors/_mixins.scss | 123 ++++++++++++++++++++--- src/wp-admin/css/common.css | 10 +- src/wp-includes/css/buttons.css | 143 ++++++++++++++------------ 4 files changed, 246 insertions(+), 174 deletions(-) diff --git a/src/wp-admin/css/colors/_admin.scss b/src/wp-admin/css/colors/_admin.scss index 1b69b0102da59..512f9c994e15c 100644 --- a/src/wp-admin/css/colors/_admin.scss +++ b/src/wp-admin/css/colors/_admin.scss @@ -3,6 +3,7 @@ @forward 'variables' show $scheme-name, $base-color, $body-background, $button-color, $custom-welcome-panel, $dashboard-accent-1, $dashboard-accent-2, $dashboard-icon-background, $form-checked, $highlight-color, $icon-color, $link, $link-focus, $low-contrast-theme, $menu-bubble-text, $menu-collapse-focus-icon, $menu-collapse-text, $menu-highlight-background, $menu-highlight-icon, $menu-highlight-text, $menu-submenu-text, $menu-submenu-focus-text, $menu-submenu-background, $notification-color, $text-color; @use 'variables'; @use 'mixins'; +@use 'tokens'; /** * This function name uses British English to maintain backward compatibility, as developers @@ -37,13 +38,27 @@ span.wp-media-buttons-icon:before { color: currentColor; } -.wp-core-ui .button-link { - color: variables.$link; +/* Link button - appears as text link, no border or background */ +/* Matches Gutenberg's .is-link button variant */ +.wp-core-ui .button-link, +.wp-core-ui .button.button-link { + color: var(--wp-admin-theme-color); &:hover, - &:active, + &:active { + color: var(--wp-admin-theme-color-darker-20); + } + &:focus { - color: variables.$link-focus; + color: var(--wp-admin-theme-color); + border-radius: tokens.$radius-s; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + outline: 1px solid transparent; + } + + &:disabled, + &[aria-disabled="true"] { + color: tokens.$gray-600; } } @@ -51,7 +66,7 @@ span.wp-media-buttons-icon:before { .media-modal .trash-attachment, .media-modal .untrash-attachment, .wp-core-ui .button-link-delete { - color: #a00; + color: tokens.$alert-red; } .media-modal .delete-attachment:hover, @@ -62,7 +77,7 @@ span.wp-media-buttons-icon:before { .media-modal .untrash-attachment:focus, .wp-core-ui .button-link-delete:hover, .wp-core-ui .button-link-delete:focus { - color: #dc3232; + color: color.adjust(tokens.$alert-red, $lightness: 10%); } /* Forms */ @@ -108,79 +123,24 @@ textarea:focus { .wp-core-ui { + /* Default button - theme color border and text (matches secondary) */ .button { - border-color: #7e8993; - color: #32373c; - } - - .button.hover, - .button:hover, - .button.focus, - .button:focus { - border-color: color.adjust(#7e8993, $lightness: -5%); - color: color.adjust(#32373c, $lightness: -5%); - } - - .button.focus, - .button:focus { - border-color: #7e8993; - color: color.adjust(#32373c, $lightness: -5%); - box-shadow: 0 0 0 1px #32373c; - } - - .button:active { - border-color: #7e8993; - color: color.adjust(#32373c, $lightness: -5%); - box-shadow: none; - } - - .button.active, - .button.active:focus, - .button.active:hover { - border-color: variables.$button-color; - color: color.adjust(#32373c, $lightness: -5%); - box-shadow: inset 0 2px 5px -3px variables.$button-color; + @include mixins.button-secondary(); } - .button.active:focus { - box-shadow: 0 0 0 1px #32373c; - } - - @if ( variables.$low-contrast-theme != "true" ) { - .button, - .button-secondary { - color: variables.$highlight-color; - border-color: variables.$highlight-color; - } - - .button.hover, - .button:hover, - .button-secondary:hover{ - border-color: color.adjust(variables.$highlight-color, $lightness: -10%); - color: color.adjust(variables.$highlight-color, $lightness: -10%); - } - - .button.focus, - .button:focus, - .button-secondary:focus { - border-color: color.adjust(variables.$highlight-color, $lightness: 10%); - color: color.adjust(variables.$highlight-color, $lightness: -20%); - box-shadow: 0 0 0 1px color.adjust(variables.$highlight-color, $lightness: 10%); - } - - .button-primary { - &:hover { - color: #fff; - } - } + /* Secondary button - same as default */ + .button-secondary { + @include mixins.button-secondary(); } + /* Primary button - theme color background */ .button-primary { @include mixins.button( variables.$button-color ); } .button-group > .button.active { - border-color: variables.$button-color; + border-color: var(--wp-admin-theme-color); + background: rgba(var(--wp-admin-theme-color--rgb), 0.04); } .wp-ui-primary { @@ -214,28 +174,34 @@ textarea:focus { /* List tables */ -@if variables.$low-contrast-theme == "true" { - .wrap .page-title-action:hover { - color: variables.$menu-text; - background-color: variables.$menu-background; - } -} @else { - .wrap .page-title-action, - .wrap .page-title-action:active { - border: 1px solid variables.$highlight-color; - color: variables.$highlight-color; - } - .wrap .page-title-action:hover { - color: color.adjust(variables.$highlight-color, $lightness: -10%); - border-color: color.adjust(variables.$highlight-color, $lightness: -10%); - } +// .page-title-action uses secondary button styling +.wrap .page-title-action { + background: transparent; + border: 1px solid var(--wp-admin-theme-color); + border-radius: tokens.$radius-s; + color: var(--wp-admin-theme-color); +} - .wrap .page-title-action:focus { - border-color: color.adjust(variables.$highlight-color, $lightness: 10%); - color: color.adjust(variables.$highlight-color, $lightness: -20%); - box-shadow: 0 0 0 1px color.adjust(variables.$highlight-color, $lightness: 10%); - } +.wrap .page-title-action:hover { + background: rgba(var(--wp-admin-theme-color--rgb), 0.04); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); +} + +.wrap .page-title-action:focus { + background: transparent; + border-color: var(--wp-admin-theme-color); + color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + outline: 1px solid transparent; +} + +.wrap .page-title-action:active { + background: rgba(var(--wp-admin-theme-color--rgb), 0.08); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); + box-shadow: none; } .view-switch a.current:before { diff --git a/src/wp-admin/css/colors/_mixins.scss b/src/wp-admin/css/colors/_mixins.scss index d33cf3bb2d854..d783bf268613e 100644 --- a/src/wp-admin/css/colors/_mixins.scss +++ b/src/wp-admin/css/colors/_mixins.scss @@ -1,39 +1,132 @@ @use 'sass:color'; +@use 'tokens'; /* - * Button mixin- creates a button effect with correct - * highlights/shadows, based on a base color. + * Button mixin - creates a primary button effect. + * Uses CSS custom properties for theme color support across color schemes. */ @mixin button( $button-color, $button-text-color: #fff ) { - background: $button-color; - border-color: $button-color; + background: var(--wp-admin-theme-color); + border-color: transparent; + border-radius: tokens.$radius-s; color: $button-text-color; - &:hover, - &:focus { - background: color.adjust($button-color, $lightness: 3%); - border-color: color.adjust($button-color, $lightness: -3%); + &:hover { + background: var(--wp-admin-theme-color-darker-10); + border-color: transparent; color: $button-text-color; } &:focus { + background: var(--wp-admin-theme-color); + border-color: transparent; + color: $button-text-color; + /* Gutenberg-style focus ring: outer theme color + inset white for contrast */ box-shadow: - 0 0 0 1px #fff, - 0 0 0 3px $button-color; + 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color), + inset 0 0 0 1px tokens.$white; + /* Visible in Windows High Contrast mode */ + outline: 1px solid transparent; } &:active { - background: color.adjust($button-color, $lightness: -5%); - border-color: color.adjust($button-color, $lightness: -5%); + background: var(--wp-admin-theme-color-darker-20); + border-color: transparent; color: $button-text-color; } + &:disabled, + &.disabled { + background: tokens.$gray-100; + border-color: transparent; + color: tokens.$gray-600; + cursor: not-allowed; + } + &.active, &.active:focus, &.active:hover { - background: $button-color; + background: var(--wp-admin-theme-color-darker-10); color: $button-text-color; - border-color: color.adjust($button-color, $lightness: -15%); - box-shadow: inset 0 2px 5px -3px color.adjust($button-color, $lightness: -50%); + border-color: transparent; + box-shadow: none; + } +} + +/* + * Secondary button mixin - outlined style with theme color. + * Matches Gutenberg's .is-secondary button variant. + */ +@mixin button-secondary() { + background: transparent; + border: 1px solid var(--wp-admin-theme-color); + border-radius: tokens.$radius-s; + color: var(--wp-admin-theme-color); + + &:hover { + background: rgba(var(--wp-admin-theme-color--rgb), 0.04); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); + } + + &:focus { + background: transparent; + border-color: var(--wp-admin-theme-color); + color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + outline: 1px solid transparent; + } + + &:active { + background: rgba(var(--wp-admin-theme-color--rgb), 0.08); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); + box-shadow: none; + } + + &:disabled, + &.disabled { + background: transparent; + border-color: tokens.$gray-300; + color: tokens.$gray-600; + cursor: not-allowed; + } +} + +/* + * Tertiary button mixin - transparent background, gray text. + */ +@mixin button-tertiary() { + background: transparent; + border: 1px solid tokens.$gray-600; + border-radius: tokens.$radius-s; + color: tokens.$gray-900; + + &:hover { + background: rgba(0, 0, 0, 0.05); + border-color: tokens.$gray-700; + color: tokens.$gray-900; + } + + &:focus { + background: transparent; + border-color: var(--wp-admin-theme-color); + color: tokens.$gray-900; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + outline: 1px solid transparent; + } + + &:active { + background: rgba(0, 0, 0, 0.1); + border-color: tokens.$gray-700; + color: tokens.$gray-900; + } + + &:disabled, + &.disabled { + background: transparent; + border-color: tokens.$gray-400; + color: tokens.$gray-600; + cursor: not-allowed; } } diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css index 3ea8a878bcf68..ded9dee9506f3 100644 --- a/src/wp-admin/css/common.css +++ b/src/wp-admin/css/common.css @@ -630,11 +630,12 @@ code { top: -3px; margin-left: 4px; border: 1px solid #2271b1; - border-radius: 3px; - background: #f6f7f7; + border-radius: 2px; + background: transparent; font-size: 13px; - font-weight: 400; - line-height: 2.15384615; + font-weight: 500; + min-height: 40px; + line-height: 2.92307692; /* 38px for 40px height */ color: #2271b1; /* use the standard color used for buttons */ padding: 0 10px; min-height: 30px; @@ -648,7 +649,6 @@ code { .wrap .add-new-h2:hover, /* deprecated */ .wrap .page-title-action:hover { - background: #f0f0f1; border-color: #0a4b78; color: #0a4b78; } diff --git a/src/wp-includes/css/buttons.css b/src/wp-includes/css/buttons.css index 5146be4274254..3eda51ae5d788 100644 --- a/src/wp-includes/css/buttons.css +++ b/src/wp-includes/css/buttons.css @@ -46,15 +46,16 @@ TABLE OF CONTENTS: display: inline-block; text-decoration: none; font-size: 13px; - line-height: 2.15384615; /* 28px */ - min-height: 30px; + font-weight: 500; + line-height: 2.92307692; /* 38px - allows 40px min-height with 1px border */ + min-height: 40px; margin: 0; - padding: 0 10px; + padding: 0 16px; cursor: pointer; border-width: 1px; border-style: solid; -webkit-appearance: none; - border-radius: 3px; + border-radius: 2px; white-space: nowrap; box-sizing: border-box; } @@ -69,26 +70,36 @@ TABLE OF CONTENTS: padding: 0; } -.wp-core-ui .button.button-large, -.wp-core-ui .button-group.button-large .button { +/* Compact size - 32px, for space-constrained contexts */ +.wp-core-ui .button.button-compact, +.wp-core-ui .button-group.button-compact .button { + line-height: 2.30769231; /* 30px - allows 32px min-height with 1px border */ min-height: 32px; - line-height: 2.30769231; /* 30px */ padding: 0 12px; } +/* Small size - 24px */ .wp-core-ui .button.button-small, .wp-core-ui .button-group.button-small .button { - min-height: 26px; - line-height: 2.18181818; /* 24px */ + line-height: 2; /* 22px - allows 24px min-height with 1px border */ + min-height: 24px; padding: 0 8px; font-size: 11px; } +/* Large size - explicit 40px (same as default, for semantic clarity) */ +.wp-core-ui .button.button-large, +.wp-core-ui .button-group.button-large .button { + line-height: 2.92307692; /* 38px - allows 40px min-height with 1px border */ + min-height: 40px; + padding: 0 16px; +} + .wp-core-ui .button.button-hero, .wp-core-ui .button-group.button-hero .button { font-size: 14px; - min-height: 46px; - line-height: 3.14285714; + line-height: 3.28571429; /* 46px - allows 48px min-height with 1px border */ + min-height: 48px; padding: 0 36px; } @@ -115,9 +126,9 @@ TABLE OF CONTENTS: .wp-core-ui .button, .wp-core-ui .button-secondary { - color: #2271b1; - border-color: #2271b1; - background: #f6f7f7; + color: #3858e9; + border-color: #3858e9; + background: transparent; vertical-align: top; } @@ -127,21 +138,21 @@ TABLE OF CONTENTS: .wp-core-ui .button.hover, .wp-core-ui .button:hover, -.wp-core-ui .button-secondary:hover{ - background: #f0f0f1; - border-color: #0a4b78; - color: #0a4b78; +.wp-core-ui .button-secondary:hover { + background: rgba(56, 88, 233, 0.04); + border-color: #183ad6; + color: #183ad6; } .wp-core-ui .button.focus, .wp-core-ui .button:focus, .wp-core-ui .button-secondary:focus { - background: #f6f7f7; - border-color: #3582c4; - color: #0a4b78; - box-shadow: 0 0 0 1px #3582c4; + background: transparent; + border-color: #3858e9; + color: #3858e9; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) #3858e9; /* Only visible in Windows High Contrast mode */ - outline: 2px solid transparent; + outline: 1px solid transparent; /* Reset inherited offset from Gutenberg */ outline-offset: 0; } @@ -149,25 +160,24 @@ TABLE OF CONTENTS: /* :active state */ .wp-core-ui .button:active, .wp-core-ui .button-secondary:active { - background: #f6f7f7; - border-color: #8c8f94; + background: rgba(56, 88, 233, 0.08); + border-color: #183ad6; + color: #183ad6; box-shadow: none; } /* pressed state e.g. a selected setting */ .wp-core-ui .button.active, .wp-core-ui .button.active:hover { - background-color: #dcdcde; - color: #135e96; - border-color: #0a4b78; - box-shadow: inset 0 2px 5px -3px #0a4b78; + background-color: rgba(56, 88, 233, 0.04); + color: #3858e9; + border-color: #3858e9; + box-shadow: none; } .wp-core-ui .button.active:focus { - border-color: #3582c4; - box-shadow: - inset 0 2px 5px -3px #0a4b78, - 0 0 0 1px #3582c4; + border-color: #3858e9; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) #3858e9; } .wp-core-ui .button[disabled], @@ -177,9 +187,9 @@ TABLE OF CONTENTS: .wp-core-ui .button-secondary:disabled, .wp-core-ui .button-secondary.disabled, .wp-core-ui .button-disabled { - color: #a7aaad !important; - border-color: #dcdcde !important; - background: #f6f7f7 !important; + color: #949494 !important; + border-color: #dddddd !important; + background: transparent !important; box-shadow: none !important; cursor: default; transform: none !important; @@ -201,7 +211,7 @@ TABLE OF CONTENTS: cursor: pointer; text-align: left; /* Mimics the default link style in common.css */ - color: #2271b1; + color: #3858e9; text-decoration: underline; transition-property: border, background, color; transition-duration: .05s; @@ -210,14 +220,15 @@ TABLE OF CONTENTS: .wp-core-ui .button-link:hover, .wp-core-ui .button-link:active { - color: #135e96; + color: #183ad6; } .wp-core-ui .button-link:focus { - color: #043959; - box-shadow: 0 0 0 2px #2271b1; + color: #3858e9; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) #3858e9; + border-radius: 2px; /* Only visible in Windows High Contrast mode */ - outline: 2px solid transparent; + outline: 1px solid transparent; } .wp-core-ui .button-link-delete { @@ -241,35 +252,37 @@ TABLE OF CONTENTS: ---------------------------------------------------------------------------- */ .wp-core-ui .button-primary { - background: #2271b1; - border-color: #2271b1; + background: #3858e9; + border-color: #3858e9; color: #fff; text-decoration: none; text-shadow: none; } .wp-core-ui .button-primary.hover, -.wp-core-ui .button-primary:hover, -.wp-core-ui .button-primary.focus, -.wp-core-ui .button-primary:focus { - background: #135e96; - border-color: #135e96; +.wp-core-ui .button-primary:hover { + background: #2145e6; + border-color: #2145e6; color: #fff; } .wp-core-ui .button-primary.focus, .wp-core-ui .button-primary:focus { + background: #3858e9; + border-color: #3858e9; + color: #fff; box-shadow: - 0 0 0 1px #fff, - 0 0 0 3px #2271b1; + 0 0 0 var(--wp-admin-border-width-focus, 1.5px) #3858e9, + inset 0 0 0 1px #fff; + outline: 1px solid transparent; } .wp-core-ui .button-primary.active, .wp-core-ui .button-primary.active:hover, .wp-core-ui .button-primary.active:focus, .wp-core-ui .button-primary:active { - background: #135e96; - border-color: #135e96; + background: #183ad6; + border-color: #183ad6; box-shadow: none; color: #fff; } @@ -278,9 +291,9 @@ TABLE OF CONTENTS: .wp-core-ui .button-primary:disabled, .wp-core-ui .button-primary-disabled, .wp-core-ui .button-primary.disabled { - color: #a7aaad !important; - background: #f6f7f7 !important; - border-color: #dcdcde !important; + color: #949494 !important; + background: #f0f0f0 !important; + border-color: #f0f0f0 !important; box-shadow: none !important; text-shadow: none !important; cursor: default; @@ -309,11 +322,11 @@ TABLE OF CONTENTS: } .wp-core-ui .button-group > .button:first-child { - border-radius: 3px 0 0 3px; + border-radius: 2px 0 0 2px; } .wp-core-ui .button-group > .button:last-child { - border-radius: 0 3px 3px 0; + border-radius: 0 2px 2px 0; } .wp-core-ui .button-group > .button-primary + .button { @@ -353,7 +366,7 @@ TABLE OF CONTENTS: input#save-post, a.preview { padding: 0 14px; - line-height: 2.71428571; /* 38px */ + line-height: 2.71428571; /* 38px - allows 40px min-height with 1px border */ font-size: 14px; vertical-align: middle; min-height: 40px; @@ -366,9 +379,9 @@ TABLE OF CONTENTS: } #media-upload.wp-core-ui .button { - padding: 0 10px 1px; + padding: 0 10px; + line-height: 1.69230769; /* 22px */ min-height: 24px; - line-height: 22px; font-size: 13px; } @@ -386,8 +399,8 @@ TABLE OF CONTENTS: .wp-core-ui.wp-customizer .button { font-size: 13px; - line-height: 2.15384615; /* 28px */ - min-height: 30px; + line-height: 2.30769231; /* 30px */ + min-height: 32px; margin: 0; vertical-align: inherit; } @@ -404,9 +417,9 @@ TABLE OF CONTENTS: /* Reset responsive styles on Log in button on iframed login form */ .interim-login .button.button-large { - min-height: 30px; - line-height: 2; - padding: 0 12px 2px; + min-height: 32px; + line-height: 2.30769231; /* 30px */ + padding: 0 12px; } } From f3e2bdb2defa91c8e0cebc0e8abaf3b9dcaf991e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 12 Dec 2025 16:18:45 +0100 Subject: [PATCH 03/16] Admin UI: Fix theme card button sizing and visibility Update theme card buttons to work with the new design system sizing. **Button sizing:** - Use compact size (32px) for theme card buttons since they're in a space-constrained context - Set explicit min-height, line-height, and padding to match compact spec **Button visibility:** - Add white background to secondary buttons for visibility against the semi-transparent theme card overlay - Use :not(.button-primary) selector to preserve primary button styling - Adjust hover state to use #f0f0f0 background **Layout adjustments:** - Increase theme name vertical padding from 15px to 16px to accommodate taller buttons - Adjust active theme padding-right from 110px to 115px for button width - Reduce theme-actions horizontal padding from 15px to 12px See: https://core.trac.wordpress.org/ticket/64308 --- src/wp-admin/css/themes.css | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/wp-admin/css/themes.css b/src/wp-admin/css/themes.css index 326531528ee62..36e662d375a18 100644 --- a/src/wp-admin/css/themes.css +++ b/src/wp-admin/css/themes.css @@ -83,7 +83,7 @@ body.js .theme-browser.search-loading { font-weight: 600; height: 18px; margin: 0; - padding: 15px; + padding: 16px 15px; box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1); overflow: hidden; white-space: nowrap; @@ -112,9 +112,26 @@ body.js .theme-browser.search-loading { margin-right: 3px; } +/* Use compact size for space-constrained theme cards */ .theme-browser .theme .theme-actions .button { float: none; margin-left: 3px; + min-height: 32px; + line-height: 2.30769231; /* 30px for 32px min-height */ + padding: 0 12px; +} + +/* Secondary buttons need white background for visibility on semi-transparent overlay */ +.theme-browser .theme .theme-actions .button:not(.button-primary) { + background: #fff; +} + +.theme-browser .theme .theme-actions .button:not(.button-primary):hover { + background: #f0f0f0; +} + +.theme-browser .theme .theme-actions .button:not(.button-primary):focus { + background: #fff; } /** @@ -211,7 +228,7 @@ body.js .theme-browser.search-loading { .theme-browser .theme.active .theme-name { background: #1d2327; color: #fff; - padding-right: 110px; + padding-right: 115px; font-weight: 300; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5); } @@ -240,7 +257,7 @@ body.js .theme-browser.search-loading { top: 50%; transform: translateY(-50%); right: 0; - padding: 9px 15px; + padding: 9px 12px; box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1); } @@ -248,6 +265,19 @@ body.js .theme-browser.search-loading { margin-right: 0; } +/* Active theme secondary buttons need white background for visibility on dark overlay */ +.theme-browser .theme.active .theme-actions .button:not(.button-primary) { + background: #fff; +} + +.theme-browser .theme.active .theme-actions .button:not(.button-primary):hover { + background: #f0f0f0; +} + +.theme-browser .theme.active .theme-actions .button:not(.button-primary):focus { + background: #fff; +} + .theme-browser .theme .theme-author { background: #1d2327; color: #f0f0f1; From b4106d3b6e1af71841055b0b770d61f6a2f55bbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 12 Dec 2025 15:32:39 +0100 Subject: [PATCH 04/16] Admin UI: Reskin form controls to align with WordPress Design System Update all form control styles to match Gutenberg's component patterns and the WordPress Design System specifications. **Text Inputs:** - Default height: 40px (was 30px) - Border radius: 2px (was 4px) - Border color: #949494 (was #8c8f94) - Text color: #1e1e1e (was #2c3338) - Padding: 0 12px (was 0 8px) - Focus: Gutenberg-style 0.5px outer ring with theme color **Select Dropdowns:** - Height: 40px (was 30px) - Border radius: 2px (was 3px) - Border color: #949494 (was #8c8f94) - Arrow icon: updated to #1e1e1e - Focus: Gutenberg-style 0.5px outer ring **Textarea:** - Padding: 8px 12px (was 2px 6px) **Checkbox/Radio:** - Border: 1px #1e1e1e (was #8c8f94) - Border radius: 2px (checkbox), unchanged (radio) - Focus: outset ring (2px white + 4px theme color) - Checked: theme color background + border, white checkmark/dot **Disabled/Readonly States:** - Disabled: #f0f0f0 background, #cccccc border, #949494 text - Readonly: #f0f0f0 background **Password Fields:** - Height: 40px (was 30px) - Toggle button focus: 2px border-radius - Strength meter: 2px border-radius, updated colors **Other Updates:** - Placeholder: #757575 (was #646970) - Autocomplete focus: uses theme color - All focus states use var(--wp-admin-theme-color) See: https://core.trac.wordpress.org/ticket/64308 --- src/wp-admin/css/colors/_admin.scss | 62 ++++++++++-- src/wp-admin/css/dashboard.css | 2 +- src/wp-admin/css/forms.css | 142 ++++++++++++++++------------ 3 files changed, 138 insertions(+), 68 deletions(-) diff --git a/src/wp-admin/css/colors/_admin.scss b/src/wp-admin/css/colors/_admin.scss index 512f9c994e15c..96d50e84bd2fa 100644 --- a/src/wp-admin/css/colors/_admin.scss +++ b/src/wp-admin/css/colors/_admin.scss @@ -82,12 +82,26 @@ span.wp-media-buttons-icon:before { /* Forms */ -input[type=checkbox]:checked::before { - content: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.83%204.89l1.34.94-5.81%208.38H9.02L5.78%209.67l1.34-1.25%202.57%202.4z%27%20fill%3D%27#{url-friendly-colour(variables.$form-checked)}%27%2F%3E%3C%2Fsvg%3E") / ''; +// Checkbox checked state - uses theme color +input[type="checkbox"]:checked { + background: var(--wp-admin-theme-color); + border-color: var(--wp-admin-theme-color); +} + +// Checkbox checkmark - white for visibility on theme color background +input[type="checkbox"]:checked::before { + content: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.83%204.89l1.34.94-5.81%208.38H9.02L5.78%209.67l1.34-1.25%202.57%202.4z%27%20fill%3D%27%23ffffff%27%2F%3E%3C%2Fsvg%3E") / ''; +} + +// Radio checked state - uses theme color +input[type="radio"]:checked { + background: var(--wp-admin-theme-color); + border-color: var(--wp-admin-theme-color); } -input[type=radio]:checked::before { - background: variables.$form-checked; +// Radio dot - white for visibility on theme color background +input[type="radio"]:checked::before { + background: tokens.$white; } .wp-core-ui input[type="reset"]:hover, @@ -95,6 +109,7 @@ input[type=radio]:checked::before { color: variables.$link-focus; } +// Text input focus - Gutenberg-style 1.5px border effect input[type="text"]:focus, input[type="password"]:focus, input[type="color"]:focus, @@ -106,16 +121,45 @@ input[type="month"]:focus, input[type="number"]:focus, input[type="search"]:focus, input[type="tel"]:focus, -input[type="text"]:focus, input[type="time"]:focus, input[type="url"]:focus, input[type="week"]:focus, -input[type="checkbox"]:focus, -input[type="radio"]:focus, select:focus, textarea:focus { - border-color: variables.$highlight-color; - box-shadow: 0 0 0 1px variables.$highlight-color; + border-color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 0.5px var(--wp-admin-theme-color); +} + +// Checkbox/Radio focus - Gutenberg-style outset focus ring +input[type="checkbox"]:focus, +input[type="radio"]:focus { + border-color: tokens.$gray-900; + box-shadow: 0 0 0 2px tokens.$white, 0 0 0 4px var(--wp-admin-theme-color); + outline: 2px solid transparent; +} + +// Select focus (wp-core-ui styled selects) +.wp-core-ui select:focus { + border-color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 0.5px var(--wp-admin-theme-color); +} + +// Autocomplete focus state +.wp-tags-autocomplete .ui-state-focus, +.wp-tags-autocomplete [aria-selected="true"] { + background-color: var(--wp-admin-theme-color); +} + +// Password field focus +#pass1:focus, +#pass1-text:focus { + box-shadow: 0 0 0 0.5px var(--wp-admin-theme-color); +} + +// Password toggle button focus +.mailserver-pass-wrap .button.wp-hide-pw:focus { + border-color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 0.5px var(--wp-admin-theme-color); } diff --git a/src/wp-admin/css/dashboard.css b/src/wp-admin/css/dashboard.css index 9901d1c2a2c13..251d79ae03801 100644 --- a/src/wp-admin/css/dashboard.css +++ b/src/wp-admin/css/dashboard.css @@ -786,7 +786,7 @@ body #dashboard-widgets .postbox form .submit { min-height: 90px; max-height: 1300px; margin: 0 0 8px; - padding: 6px 7px; + padding: 8px 12px; resize: none; } diff --git a/src/wp-admin/css/forms.css b/src/wp-admin/css/forms.css index 3fec3b72c37d1..37f2135a7ef84 100644 --- a/src/wp-admin/css/forms.css +++ b/src/wp-admin/css/forms.css @@ -16,7 +16,7 @@ input { textarea { overflow: auto; - padding: 2px 6px; + padding: 8px 12px; /* inherits font size 14px */ line-height: 1.42857143; /* 20px */ resize: vertical; @@ -28,7 +28,7 @@ select { } textarea.code { - padding: 4px 6px 1px; + padding: 8px 12px; } input[type="text"], @@ -48,10 +48,10 @@ input[type="week"], select, textarea { box-shadow: 0 0 0 transparent; - border-radius: 4px; - border: 1px solid #8c8f94; + border-radius: 2px; + border: 1px solid #949494; background-color: #fff; - color: #2c3338; + color: #1e1e1e; } input[type="text"], @@ -67,11 +67,17 @@ input[type="tel"], input[type="time"], input[type="url"], input[type="week"] { - padding: 0 8px; + padding: 0 12px; /* inherits font size 14px */ - line-height: 2; /* 28px */ - /* Only necessary for IE11 */ - min-height: 30px; + line-height: 2.71428571; /* 38px for 40px min-height */ + min-height: 40px; +} + +select { + padding: 0 24px 0 12px; + /* inherits font size 14px */ + line-height: 2.71428571; /* 38px for 40px min-height */ + min-height: 40px; } ::-webkit-datetime-edit { @@ -93,12 +99,20 @@ input[type="tel"]:focus, input[type="time"]:focus, input[type="url"]:focus, input[type="week"]:focus, -input[type="checkbox"]:focus, -input[type="radio"]:focus, select:focus, textarea:focus { - border-color: #2271b1; - box-shadow: 0 0 0 1px #2271b1; + border-color: #3858e9; + /* Expand border by 0.5px for total 1.5px effect */ + box-shadow: 0 0 0 0.5px #3858e9; + /* Only visible in Windows High Contrast mode */ + outline: 2px solid transparent; +} + +/* Checkbox and radio use outset focus style */ +input[type="checkbox"]:focus, +input[type="radio"]:focus { + border-color: #1e1e1e; + box-shadow: 0 0 0 2px #fff, 0 0 0 4px #3858e9; /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -111,10 +125,10 @@ input[type="url"] { input[type="checkbox"], input[type="radio"] { - border: 1px solid #8c8f94; - border-radius: 4px; + border: 1px solid #1e1e1e; + border-radius: 2px; background: #fff; - color: #50575e; + color: #1e1e1e; clear: none; cursor: pointer; display: inline-block; @@ -128,12 +142,12 @@ input[type="radio"] { width: 1rem; min-width: 1rem; -webkit-appearance: none; - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: none; transition: .05s border-color ease-in-out; } input[type="radio"]:checked + label:before { - color: #8c8f94; + color: #949494; } .wp-core-ui input[type="reset"]:hover, @@ -173,20 +187,30 @@ input[type="radio"]:checked::before { } input[type="checkbox"]:checked::before { - /* Use the "Yes" SVG Dashicon */ - content: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.83%204.89l1.34.94-5.81%208.38H9.02L5.78%209.67l1.34-1.25%202.57%202.4z%27%20fill%3D%27%233582c4%27%2F%3E%3C%2Fsvg%3E") / ''; + /* Use the "Yes" SVG Dashicon - color will be overridden by color scheme */ + content: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.83%204.89l1.34.94-5.81%208.38H9.02L5.78%209.67l1.34-1.25%202.57%202.4z%27%20fill%3D%27%23ffffff%27%2F%3E%3C%2Fsvg%3E") / ''; margin: -0.1875rem 0 0 -0.25rem; height: 1.3125rem; width: 1.3125rem; } +input[type="checkbox"]:checked { + background: #3858e9; + border-color: #3858e9; +} + +input[type="radio"]:checked { + background: #3858e9; + border-color: #3858e9; +} + input[type="radio"]:checked::before { content: ""; border-radius: 50%; width: 0.5rem; /* 8px */ height: 0.5rem; /* 8px */ margin: 0.1875rem; /* 3px */ - background-color: #3582c4; + background-color: #fff; /* 16px not sure if still necessary, comes from the MP6 redesign in r26072 */ line-height: 1.14285714; } @@ -217,15 +241,15 @@ input.readonly, input[readonly], textarea.readonly, textarea[readonly] { - background-color: #f0f0f1; + background-color: #f0f0f0; } ::-webkit-input-placeholder { - color: #646970; + color: #757575; } ::-moz-placeholder { - color: #646970; + color: #757575; } .form-invalid .form-required, @@ -269,10 +293,10 @@ select:disabled, select.disabled, textarea:disabled, textarea.disabled { - background: rgba(255, 255, 255, 0.5); - border-color: rgba(220, 220, 222, 0.75); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.04); - color: rgba(44, 51, 56, 0.5); + background: #f0f0f0; + border-color: #cccccc; + box-shadow: none; + color: #949494; } input[type="file"]:disabled, @@ -307,34 +331,35 @@ input[type="radio"].disabled:checked:before { /* Select styles are based on the default button in buttons.css */ .wp-core-ui select { font-size: 14px; - line-height: 2; /* 28px */ - color: #2c3338; - border-color: #8c8f94; + line-height: 2.71428571; /* 38px for 40px min-height */ + color: #1e1e1e; + border-color: #949494; box-shadow: none; - border-radius: 3px; - padding: 0 24px 0 8px; - min-height: 30px; + border-radius: 2px; + padding: 0 24px 0 12px; + min-height: 40px; max-width: 25rem; -webkit-appearance: none; /* The SVG is arrow-down-alt2 from Dashicons. */ - background: #fff url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E') no-repeat right 5px top 55%; + background: #fff url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%231e1e1e%22%2F%3E%3C%2Fsvg%3E') no-repeat right 8px top 55%; background-size: 16px 16px; cursor: pointer; vertical-align: middle; } .wp-core-ui select:hover { - color: #2271b1; + color: #1e1e1e; + border-color: #1e1e1e; } .wp-core-ui select:focus { - border-color: #2271b1; - color: #0a4b78; - box-shadow: 0 0 0 1px #2271b1; + border-color: #3858e9; + color: #1e1e1e; + box-shadow: 0 0 0 0.5px #3858e9; } .wp-core-ui select:active { - border-color: #8c8f94; + border-color: #949494; box-shadow: none; } @@ -369,7 +394,7 @@ input[type="radio"].disabled:checked:before { } .wp-core-ui select:hover::-ms-value { - color: #2271b1; + color: #1e1e1e; } .wp-core-ui select:focus::-ms-value { @@ -464,7 +489,7 @@ textarea.large-text { input.small-text { width: 50px; - padding: 0 6px; + padding: 0 8px; } label input.small-text { @@ -473,7 +498,7 @@ label input.small-text { input[type="number"].small-text { width: 65px; - padding-right: 0; + padding-right: 4px; } input.tiny-text { @@ -596,9 +621,9 @@ fieldset label, .mailserver-pass-wrap .button.wp-hide-pw:focus { background: transparent; - border-color: #3582c4; - border-radius: 4px; - box-shadow: 0 0 0 1px #3582c4; + border-color: #3858e9; + border-radius: 2px; + box-shadow: 0 0 0 0.5px #3858e9; /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -614,9 +639,10 @@ fieldset label, } #pass-strength-result { - background-color: #f0f0f1; - border: 1px solid #dcdcde; - color: #1d2327; + background-color: #f0f0f0; + border: 1px solid #cccccc; + border-radius: 2px; + color: #1e1e1e; margin: -1px 1px 5px; padding: 3px 5px; text-align: center; @@ -675,7 +701,7 @@ fieldset label, #pass1:focus, #pass1-text:focus { - box-shadow: 0 0 0 2px #2271b1; + box-shadow: 0 0 0 0.5px #3858e9; /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; } @@ -692,7 +718,7 @@ fieldset label, .wp-pwd [type="password"] { margin-bottom: 0; /* Same height as the buttons */ - min-height: 30px; + min-height: 40px; } /* Hide the Edge "reveal password" native button */ @@ -727,7 +753,7 @@ fieldset label, .profile-php .wp-pwd .caps-warning { padding: 3px 5px; top: -4px; - border-radius: 4px; + border-radius: 2px; } .wp-pwd .caps-icon { @@ -812,7 +838,7 @@ ul#add-to-blog-users { /* Colors for the tags autocomplete. */ .wp-tags-autocomplete .ui-state-focus, .wp-tags-autocomplete [aria-selected="true"] { - background-color: #2271b1; + background-color: #3858e9; color: #fff; /* Only visible in Windows High Contrast mode */ outline: 2px solid transparent; @@ -1358,7 +1384,7 @@ table.form-table td .updated p { } .request-filesystem-credentials-dialog .ftp-password em { - color: #8c8f94; + color: #757575; } .request-filesystem-credentials-dialog label { @@ -1523,9 +1549,9 @@ table.form-table td .updated p { input[type="url"], input[type="week"] { -webkit-appearance: none; - padding: 3px 10px; - /* Only necessary for IE11 */ + padding: 0 12px; min-height: 40px; + line-height: 2.5; /* 40px for 16px font */ } ::-webkit-datetime-edit { @@ -1577,8 +1603,8 @@ table.form-table td .updated p { .wp-admin .form-table select { min-height: 40px; font-size: 16px; - line-height: 1.625; /* 26px */ - padding: 5px 24px 5px 8px; + line-height: 2.5; /* 40px for 16px font */ + padding: 0 24px 0 12px; } .wp-admin .button-cancel { From 62f0c5ef75d08a95a878a03ac6fb179ddcb1b477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 12 Dec 2025 14:12:15 +0100 Subject: [PATCH 05/16] Admin UI: Add design system tokens for admin reskin Introduces _tokens.scss with Sass variables derived from the WordPress Design System in Figma. These tokens provide consistent values for: - Spacing (4px grid units) - Border radius - Gray scale - Semantic colors (alerts/notices) - Typography scale - Elevation (box shadows) - Component sizing (buttons, inputs, checkboxes) The tokens are imported into _variables.scss and can be used across all admin stylesheets compiled via Sass. Note: These are Sass-only variables. No new CSS custom properties are exposed to maintain backward compatibility. The only CSS custom properties available remain those from wp-base-styles. Part of the WordPress 7.0 admin visual reskin initiative. See: https://core.trac.wordpress.org/ticket/64308 --- src/wp-admin/css/colors/_tokens.scss | 212 ++++++++++++++++++++++++ src/wp-admin/css/colors/_variables.scss | 5 +- 2 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 src/wp-admin/css/colors/_tokens.scss diff --git a/src/wp-admin/css/colors/_tokens.scss b/src/wp-admin/css/colors/_tokens.scss new file mode 100644 index 0000000000000..785f1f47f5076 --- /dev/null +++ b/src/wp-admin/css/colors/_tokens.scss @@ -0,0 +1,212 @@ +// ========================================================================== +// WordPress Design System Tokens +// ========================================================================== +// +// These tokens are derived from the WordPress Design System in Figma: +// https://www.figma.com/design/804HN2REV2iap2ytjRQ055/WordPress-Design-System +// +// IMPORTANT: Do NOT expose these as CSS custom properties. +// Use these Sass variables to compile to static CSS values. +// The only CSS custom properties available are those in wp-base-styles: +// - --wp-admin-theme-color +// - --wp-admin-theme-color--rgb +// - --wp-admin-theme-color-darker-10 +// - --wp-admin-theme-color-darker-20 +// - --wp-admin-border-width-focus +// +// ========================================================================== + + +// -------------------------------------------------------------------------- +// Grid Units (Spacing) +// -------------------------------------------------------------------------- +// Based on 4px base unit. Use for padding, margin, and gap values. + +$grid-unit-05: 4px; // Scales/grid unit 05 +$grid-unit-10: 8px; // Scales/grid unit 10 +$grid-unit-15: 12px; // Scales/grid unit 15 +$grid-unit-20: 16px; // Scales/grid unit 20 +$grid-unit-30: 24px; // Scales/grid unit 30 +$grid-unit-40: 32px; // Scales/grid unit 40 +$grid-unit-50: 40px; // Scales/grid unit 50 +$grid-unit-60: 48px; // Scales/grid unit 60 +$grid-unit-70: 56px; // Scales/grid unit 70 + + +// -------------------------------------------------------------------------- +// Border Radius +// -------------------------------------------------------------------------- + +$radius-xs: 1px; // radius-xs +$radius-s: 2px; // radius-s - Buttons, inputs +$radius-m: 4px; // radius-m - Focus rings +$radius-l: 8px; // radius-l - Cards, dashboard widgets +$radius-30: 12px; // Radius 30 +$radius-full: 9999px; // radius-full - Pills, avatars, circles + + +// -------------------------------------------------------------------------- +// Gray Scale +// -------------------------------------------------------------------------- +// Neutral colors for backgrounds, borders, and text. + +$gray-100: #f0f0f0; // Scales/Grays/gray-100 - Page background, disabled inputs +$gray-200: #e0e0e0; // Scales/Grays/gray-200 +$gray-300: #dddddd; // Scales/Grays/gray-300 +$gray-400: #cccccc; // Scales/Grays/gray-400 - Disabled borders +$gray-600: #949494; // Scales/Grays/gray-600 - Input borders, disabled text +$gray-700: #757575; // Scales/Grays/gray-700 +$gray-800: #2f2f2f; // Scales/Grays/gray-800 +$gray-900: #1e1e1e; // Scales/Grays/gray-900 - Primary text + +$white: #ffffff; // Scales/Black & White/white + + +// -------------------------------------------------------------------------- +// Theme Colors (Static reference values) +// -------------------------------------------------------------------------- +// For actual theme color usage, use var(--wp-admin-theme-color) instead. +// These are provided for reference and for contexts where CSS vars aren't available. + +$theme-reference: #3858e9; // Scales/Theme/theme (modern scheme) +$theme-darker-10-reference: #2145e6; // Scales/Theme/theme-darker-10 +$theme-darker-20-reference: #183ad6; // Scales/Theme/theme-darker-20 +$theme-alpha-04: rgba(56, 88, 233, 0.04); // Scales/Theme/theme-alpha-04 (4% opacity) +$theme-alpha-08: rgba(56, 88, 233, 0.08); // Scales/Theme/theme-alpha-08 (8% opacity) + +$brand-9: #4465db; // Scales/brand-9 - Focus ring color (static, not theme-dependent) + + +// -------------------------------------------------------------------------- +// Semantic Colors +// -------------------------------------------------------------------------- +// Use these for notices, alerts, and status indicators. +// These are intentionally NOT theme-dependent for consistency. + +$alert-yellow: #f0b849; // Scales/Yellow/alert-yellow - Warnings +$alert-green: #4ab866; // Scales/Green/alert-green - Success +$alert-red: #cc1818; // Scales/Red/alert-red - Errors +$alert-blue: #3858e9; // Info notices (matches modern theme) + +// Background tints for notices +$alert-yellow-bg: #fef8ee; // Warning notice background +$alert-green-bg: #eff9f1; // Success notice background +$alert-red-bg: #fcf0f0; // Error notice background + +$synced-color: #7a00df; // Scales/Purple/--wp-block-synced-color + + +// -------------------------------------------------------------------------- +// Text Colors +// -------------------------------------------------------------------------- + +$text-primary: $gray-900; // Primary text color +$text-secondary: $gray-700; // Secondary text +$text-tertiary: #5d5d5d; // Alias/text/text-tertiary - Placeholder, hints +$text-disabled: $gray-600; // Disabled text + + +// -------------------------------------------------------------------------- +// Component Tokens +// -------------------------------------------------------------------------- + +// Inputs +$input-bg: $white; // Alias/bg/bg-input +$input-border-color: $gray-600; // Default input border +$input-border-color-disabled: $gray-400; +$input-bg-disabled: $gray-100; +$input-border-width-default: 1px; // Input/Default +$input-border-width-focus: 1.5px; // Input/Focus +$field-spacing-horizontal: 8px; // Alias/field-spacing-horizontal + +// Checkboxes and Radios +$checkbox-size: 16px; // Alias/checkbox +$radio-size: 16px; // Alias/radio + +// Toggles +$toggle-width: 32px; // Alias/toggle-width +$toggle-height: 16px; // Alias/toggle-height + +// Buttons +// Note: Gutenberg is transitioning to 40px as the default button size. +// The "compact" size (32px) is available for space-constrained contexts. +$button-height-default: 40px; // Default button height (next-default-40px) +$button-height-compact: 32px; // Compact button height +$button-height-small: 24px; // Small button height + +// Cards and Surfaces +$card-bg: $white; +$card-border-color: rgba(0, 0, 0, 0.1); +$card-border-width: 1px; +$card-border-radius: $radius-l; // 8px for dashboard widgets +$card-border-radius-metabox: 0; // 0 for post editor metaboxes +$card-divider-color: rgba(0, 0, 0, 0.1); + +// Card Padding Sizes +$card-padding-xs: $grid-unit-10; // 8px - xSmall cards +$card-padding-sm: $grid-unit-20; // 16px - Small cards (metaboxes, dashboard widgets) +$card-padding-md-h: $grid-unit-30; // 24px - Medium cards horizontal +$card-padding-md-v: $grid-unit-20; // 16px - Medium cards vertical +$card-padding-lg-h: $grid-unit-40; // 32px - Large cards horizontal +$card-padding-lg-v: $grid-unit-30; // 24px - Large cards vertical + +// Page Layout +$page-padding-large: 48px; // Alias/page-large +$page-padding-small: 24px; // Alias/page-small + + +// -------------------------------------------------------------------------- +// Typography Scale +// -------------------------------------------------------------------------- + +// Font Sizes +$font-size-xs: 11px; // xs - Small labels, button small +$font-size-s: 12px; // s - Body small +$font-size-m: 13px; // m - Base body text, buttons +$font-size-l: 15px; // l - Body large, heading large +$font-size-xl: 20px; // xl - Heading XL + +// Line Heights +$line-height-xs: 16px; // xs +$line-height-s: 20px; // s - Most UI elements +$line-height-m: 24px; // m - Body large + +// Font Weights +$font-weight-regular: 400; // Regular - Body text +$font-weight-medium: 500; // Medium - Headings, buttons + + +// -------------------------------------------------------------------------- +// Elevation (Box Shadows) +// -------------------------------------------------------------------------- + +$elevation-xs: + 0 4px 4px rgba(0, 0, 0, 0.01), + 0 3px 3px rgba(0, 0, 0, 0.02), + 0 1px 2px rgba(0, 0, 0, 0.02), + 0 1px 1px rgba(0, 0, 0, 0.03); + +$elevation-s: + 0 8px 8px rgba(0, 0, 0, 0.02), + 0 1px 2px rgba(0, 0, 0, 0.05); + +$elevation-m: + 0 16px 16px rgba(0, 0, 0, 0.02), + 0 4px 5px rgba(0, 0, 0, 0.03), + 0 2px 3px rgba(0, 0, 0, 0.05); + +$elevation-l: + 0 50px 43px rgba(0, 0, 0, 0.02), + 0 30px 36px rgba(0, 0, 0, 0.04), + 0 15px 27px rgba(0, 0, 0, 0.07), + 0 5px 15px rgba(0, 0, 0, 0.08); + + +// -------------------------------------------------------------------------- +// Layout +// -------------------------------------------------------------------------- + +$modal-width-small: 384px; // Layout/Modal small +$modal-width-medium: 512px; // Layout/Modal medium +$modal-width-large: 840px; // Layout/Modal large + diff --git a/src/wp-admin/css/colors/_variables.scss b/src/wp-admin/css/colors/_variables.scss index 8a073f830e4b6..d37c2b1392f00 100644 --- a/src/wp-admin/css/colors/_variables.scss +++ b/src/wp-admin/css/colors/_variables.scss @@ -1,5 +1,8 @@ @use "sass:color"; +// Import design system tokens +@use "tokens" as *; + // assign default value to all undefined variables $scheme-name: "default" !default; @@ -15,7 +18,7 @@ $notification-color: #d54e21 !default; // global -$body-background: #f1f1f1 !default; +$body-background: $gray-100 !default; $link: #0073aa !default; $link-focus: color.adjust($link, $lightness: 10%) !default; From 24579b778fb527b87dbbb03994ec73d52384fde3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 12 Dec 2025 15:11:10 +0100 Subject: [PATCH 06/16] Admin UI: Reskin buttons to align with WordPress Design System Update all button styles to match Gutenberg's component patterns and the WordPress Design System specifications. **Sizing (aligned with Gutenberg's next-default-40px):** - Default buttons: 40px height (was 30px) - Compact buttons: 32px (new class for space-constrained contexts) - Small buttons: 24px (was 26px) - Hero buttons: 48px (was 46px) - Use min-height + line-height for accessibility with browser zoom **Visual updates:** - Border radius: 2px (was 3px) - Font weight: 500 (was 400/normal) - Transparent background for secondary/tertiary buttons **Focus states (Gutenberg-style outer ring):** - Primary: outer theme color ring + inner white ring for contrast - Secondary/Tertiary/Link: single outer theme color ring - Use var(--wp-admin-theme-color) for focus ring color **Hover/Active states:** - Secondary buttons: subtle rgba() background tint on hover/active - Use theme-color-darker-20 for hover text/border colors - Link buttons: theme-color-darker-20 on hover **Components updated:** - .button, .button-primary, .button-secondary - .button-link, .button-link-delete - .page-title-action (now uses secondary button pattern) See: https://core.trac.wordpress.org/ticket/64308 --- src/wp-admin/css/colors/_admin.scss | 144 ++++++++++----------------- src/wp-admin/css/colors/_mixins.scss | 123 ++++++++++++++++++++--- src/wp-admin/css/common.css | 10 +- src/wp-includes/css/buttons.css | 143 ++++++++++++++------------ 4 files changed, 246 insertions(+), 174 deletions(-) diff --git a/src/wp-admin/css/colors/_admin.scss b/src/wp-admin/css/colors/_admin.scss index 553037e3d30d1..97904e7e9e352 100644 --- a/src/wp-admin/css/colors/_admin.scss +++ b/src/wp-admin/css/colors/_admin.scss @@ -3,6 +3,7 @@ @forward 'variables' show $scheme-name, $base-color, $body-background, $button-color, $custom-welcome-panel, $dashboard-accent-1, $dashboard-accent-2, $dashboard-icon-background, $form-checked, $highlight-color, $icon-color, $link, $link-focus, $low-contrast-theme, $menu-bubble-text, $menu-collapse-focus-icon, $menu-collapse-text, $menu-highlight-background, $menu-highlight-icon, $menu-highlight-text, $menu-submenu-text, $menu-submenu-focus-text, $menu-submenu-background, $notification-color, $text-color; @use 'variables'; @use 'mixins'; +@use 'tokens'; /** * This function name uses British English to maintain backward compatibility, as developers @@ -37,13 +38,27 @@ span.wp-media-buttons-icon:before { color: currentColor; } -.wp-core-ui .button-link { - color: variables.$link; +/* Link button - appears as text link, no border or background */ +/* Matches Gutenberg's .is-link button variant */ +.wp-core-ui .button-link, +.wp-core-ui .button.button-link { + color: var(--wp-admin-theme-color); &:hover, - &:active, + &:active { + color: var(--wp-admin-theme-color-darker-20); + } + &:focus { - color: variables.$link-focus; + color: var(--wp-admin-theme-color); + border-radius: tokens.$radius-s; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + outline: 1px solid transparent; + } + + &:disabled, + &[aria-disabled="true"] { + color: tokens.$gray-600; } } @@ -51,7 +66,7 @@ span.wp-media-buttons-icon:before { .media-modal .trash-attachment, .media-modal .untrash-attachment, .wp-core-ui .button-link-delete { - color: #a00; + color: tokens.$alert-red; } .media-modal .delete-attachment:hover, @@ -62,7 +77,7 @@ span.wp-media-buttons-icon:before { .media-modal .untrash-attachment:focus, .wp-core-ui .button-link-delete:hover, .wp-core-ui .button-link-delete:focus { - color: #dc3232; + color: color.adjust(tokens.$alert-red, $lightness: 10%); } /* Forms */ @@ -109,79 +124,24 @@ textarea:focus { .wp-core-ui { + /* Default button - theme color border and text (matches secondary) */ .button { - border-color: #7e8993; - color: #32373c; - } - - .button.hover, - .button:hover, - .button.focus, - .button:focus { - border-color: color.adjust(#7e8993, $lightness: -5%); - color: color.adjust(#32373c, $lightness: -5%); - } - - .button.focus, - .button:focus { - border-color: #7e8993; - color: color.adjust(#32373c, $lightness: -5%); - box-shadow: 0 0 0 1px #32373c; - } - - .button:active { - border-color: #7e8993; - color: color.adjust(#32373c, $lightness: -5%); - box-shadow: none; - } - - .button.active, - .button.active:focus, - .button.active:hover { - border-color: variables.$button-color; - color: color.adjust(#32373c, $lightness: -5%); - box-shadow: inset 0 2px 5px -3px variables.$button-color; + @include mixins.button-secondary(); } - .button.active:focus { - box-shadow: 0 0 0 1px #32373c; - } - - @if ( variables.$low-contrast-theme != "true" ) { - .button, - .button-secondary { - color: variables.$highlight-color; - border-color: variables.$highlight-color; - } - - .button.hover, - .button:hover, - .button-secondary:hover{ - border-color: color.adjust(variables.$highlight-color, $lightness: -10%); - color: color.adjust(variables.$highlight-color, $lightness: -10%); - } - - .button.focus, - .button:focus, - .button-secondary:focus { - border-color: color.adjust(variables.$highlight-color, $lightness: 10%); - color: color.adjust(variables.$highlight-color, $lightness: -20%); - box-shadow: 0 0 0 1px color.adjust(variables.$highlight-color, $lightness: 10%); - } - - .button-primary { - &:hover { - color: #fff; - } - } + /* Secondary button - same as default */ + .button-secondary { + @include mixins.button-secondary(); } + /* Primary button - theme color background */ .button-primary { @include mixins.button( variables.$button-color ); } .button-group > .button.active { - border-color: variables.$button-color; + border-color: var(--wp-admin-theme-color); + background: rgba(var(--wp-admin-theme-color--rgb), 0.04); } .wp-ui-primary { @@ -215,28 +175,34 @@ textarea:focus { /* List tables */ -@if variables.$low-contrast-theme == "true" { - .wrap .page-title-action:hover { - color: variables.$menu-text; - background-color: variables.$menu-background; - } -} @else { - .wrap .page-title-action, - .wrap .page-title-action:active { - border: 1px solid variables.$highlight-color; - color: variables.$highlight-color; - } - .wrap .page-title-action:hover { - color: color.adjust(variables.$highlight-color, $lightness: -10%); - border-color: color.adjust(variables.$highlight-color, $lightness: -10%); - } +// .page-title-action uses secondary button styling +.wrap .page-title-action { + background: transparent; + border: 1px solid var(--wp-admin-theme-color); + border-radius: tokens.$radius-s; + color: var(--wp-admin-theme-color); +} - .wrap .page-title-action:focus { - border-color: color.adjust(variables.$highlight-color, $lightness: 10%); - color: color.adjust(variables.$highlight-color, $lightness: -20%); - box-shadow: 0 0 0 1px color.adjust(variables.$highlight-color, $lightness: 10%); - } +.wrap .page-title-action:hover { + background: rgba(var(--wp-admin-theme-color--rgb), 0.04); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); +} + +.wrap .page-title-action:focus { + background: transparent; + border-color: var(--wp-admin-theme-color); + color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + outline: 1px solid transparent; +} + +.wrap .page-title-action:active { + background: rgba(var(--wp-admin-theme-color--rgb), 0.08); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); + box-shadow: none; } .view-switch a.current:before { diff --git a/src/wp-admin/css/colors/_mixins.scss b/src/wp-admin/css/colors/_mixins.scss index d33cf3bb2d854..d783bf268613e 100644 --- a/src/wp-admin/css/colors/_mixins.scss +++ b/src/wp-admin/css/colors/_mixins.scss @@ -1,39 +1,132 @@ @use 'sass:color'; +@use 'tokens'; /* - * Button mixin- creates a button effect with correct - * highlights/shadows, based on a base color. + * Button mixin - creates a primary button effect. + * Uses CSS custom properties for theme color support across color schemes. */ @mixin button( $button-color, $button-text-color: #fff ) { - background: $button-color; - border-color: $button-color; + background: var(--wp-admin-theme-color); + border-color: transparent; + border-radius: tokens.$radius-s; color: $button-text-color; - &:hover, - &:focus { - background: color.adjust($button-color, $lightness: 3%); - border-color: color.adjust($button-color, $lightness: -3%); + &:hover { + background: var(--wp-admin-theme-color-darker-10); + border-color: transparent; color: $button-text-color; } &:focus { + background: var(--wp-admin-theme-color); + border-color: transparent; + color: $button-text-color; + /* Gutenberg-style focus ring: outer theme color + inset white for contrast */ box-shadow: - 0 0 0 1px #fff, - 0 0 0 3px $button-color; + 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color), + inset 0 0 0 1px tokens.$white; + /* Visible in Windows High Contrast mode */ + outline: 1px solid transparent; } &:active { - background: color.adjust($button-color, $lightness: -5%); - border-color: color.adjust($button-color, $lightness: -5%); + background: var(--wp-admin-theme-color-darker-20); + border-color: transparent; color: $button-text-color; } + &:disabled, + &.disabled { + background: tokens.$gray-100; + border-color: transparent; + color: tokens.$gray-600; + cursor: not-allowed; + } + &.active, &.active:focus, &.active:hover { - background: $button-color; + background: var(--wp-admin-theme-color-darker-10); color: $button-text-color; - border-color: color.adjust($button-color, $lightness: -15%); - box-shadow: inset 0 2px 5px -3px color.adjust($button-color, $lightness: -50%); + border-color: transparent; + box-shadow: none; + } +} + +/* + * Secondary button mixin - outlined style with theme color. + * Matches Gutenberg's .is-secondary button variant. + */ +@mixin button-secondary() { + background: transparent; + border: 1px solid var(--wp-admin-theme-color); + border-radius: tokens.$radius-s; + color: var(--wp-admin-theme-color); + + &:hover { + background: rgba(var(--wp-admin-theme-color--rgb), 0.04); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); + } + + &:focus { + background: transparent; + border-color: var(--wp-admin-theme-color); + color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + outline: 1px solid transparent; + } + + &:active { + background: rgba(var(--wp-admin-theme-color--rgb), 0.08); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); + box-shadow: none; + } + + &:disabled, + &.disabled { + background: transparent; + border-color: tokens.$gray-300; + color: tokens.$gray-600; + cursor: not-allowed; + } +} + +/* + * Tertiary button mixin - transparent background, gray text. + */ +@mixin button-tertiary() { + background: transparent; + border: 1px solid tokens.$gray-600; + border-radius: tokens.$radius-s; + color: tokens.$gray-900; + + &:hover { + background: rgba(0, 0, 0, 0.05); + border-color: tokens.$gray-700; + color: tokens.$gray-900; + } + + &:focus { + background: transparent; + border-color: var(--wp-admin-theme-color); + color: tokens.$gray-900; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + outline: 1px solid transparent; + } + + &:active { + background: rgba(0, 0, 0, 0.1); + border-color: tokens.$gray-700; + color: tokens.$gray-900; + } + + &:disabled, + &.disabled { + background: transparent; + border-color: tokens.$gray-400; + color: tokens.$gray-600; + cursor: not-allowed; } } diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css index e062a471d7150..393787f8e6c2a 100644 --- a/src/wp-admin/css/common.css +++ b/src/wp-admin/css/common.css @@ -631,11 +631,12 @@ code { top: -3px; margin-left: 4px; border: 1px solid #2271b1; - border-radius: 3px; - background: #f6f7f7; + border-radius: 2px; + background: transparent; font-size: 13px; - font-weight: 400; - line-height: 2.15384615; + font-weight: 500; + min-height: 40px; + line-height: 2.92307692; /* 38px for 40px height */ color: #2271b1; /* use the standard color used for buttons */ padding: 0 10px; min-height: 30px; @@ -649,7 +650,6 @@ code { .wrap .add-new-h2:hover, /* deprecated */ .wrap .page-title-action:hover { - background: #f0f0f1; border-color: #0a4b78; color: #0a4b78; } diff --git a/src/wp-includes/css/buttons.css b/src/wp-includes/css/buttons.css index 5146be4274254..3eda51ae5d788 100644 --- a/src/wp-includes/css/buttons.css +++ b/src/wp-includes/css/buttons.css @@ -46,15 +46,16 @@ TABLE OF CONTENTS: display: inline-block; text-decoration: none; font-size: 13px; - line-height: 2.15384615; /* 28px */ - min-height: 30px; + font-weight: 500; + line-height: 2.92307692; /* 38px - allows 40px min-height with 1px border */ + min-height: 40px; margin: 0; - padding: 0 10px; + padding: 0 16px; cursor: pointer; border-width: 1px; border-style: solid; -webkit-appearance: none; - border-radius: 3px; + border-radius: 2px; white-space: nowrap; box-sizing: border-box; } @@ -69,26 +70,36 @@ TABLE OF CONTENTS: padding: 0; } -.wp-core-ui .button.button-large, -.wp-core-ui .button-group.button-large .button { +/* Compact size - 32px, for space-constrained contexts */ +.wp-core-ui .button.button-compact, +.wp-core-ui .button-group.button-compact .button { + line-height: 2.30769231; /* 30px - allows 32px min-height with 1px border */ min-height: 32px; - line-height: 2.30769231; /* 30px */ padding: 0 12px; } +/* Small size - 24px */ .wp-core-ui .button.button-small, .wp-core-ui .button-group.button-small .button { - min-height: 26px; - line-height: 2.18181818; /* 24px */ + line-height: 2; /* 22px - allows 24px min-height with 1px border */ + min-height: 24px; padding: 0 8px; font-size: 11px; } +/* Large size - explicit 40px (same as default, for semantic clarity) */ +.wp-core-ui .button.button-large, +.wp-core-ui .button-group.button-large .button { + line-height: 2.92307692; /* 38px - allows 40px min-height with 1px border */ + min-height: 40px; + padding: 0 16px; +} + .wp-core-ui .button.button-hero, .wp-core-ui .button-group.button-hero .button { font-size: 14px; - min-height: 46px; - line-height: 3.14285714; + line-height: 3.28571429; /* 46px - allows 48px min-height with 1px border */ + min-height: 48px; padding: 0 36px; } @@ -115,9 +126,9 @@ TABLE OF CONTENTS: .wp-core-ui .button, .wp-core-ui .button-secondary { - color: #2271b1; - border-color: #2271b1; - background: #f6f7f7; + color: #3858e9; + border-color: #3858e9; + background: transparent; vertical-align: top; } @@ -127,21 +138,21 @@ TABLE OF CONTENTS: .wp-core-ui .button.hover, .wp-core-ui .button:hover, -.wp-core-ui .button-secondary:hover{ - background: #f0f0f1; - border-color: #0a4b78; - color: #0a4b78; +.wp-core-ui .button-secondary:hover { + background: rgba(56, 88, 233, 0.04); + border-color: #183ad6; + color: #183ad6; } .wp-core-ui .button.focus, .wp-core-ui .button:focus, .wp-core-ui .button-secondary:focus { - background: #f6f7f7; - border-color: #3582c4; - color: #0a4b78; - box-shadow: 0 0 0 1px #3582c4; + background: transparent; + border-color: #3858e9; + color: #3858e9; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) #3858e9; /* Only visible in Windows High Contrast mode */ - outline: 2px solid transparent; + outline: 1px solid transparent; /* Reset inherited offset from Gutenberg */ outline-offset: 0; } @@ -149,25 +160,24 @@ TABLE OF CONTENTS: /* :active state */ .wp-core-ui .button:active, .wp-core-ui .button-secondary:active { - background: #f6f7f7; - border-color: #8c8f94; + background: rgba(56, 88, 233, 0.08); + border-color: #183ad6; + color: #183ad6; box-shadow: none; } /* pressed state e.g. a selected setting */ .wp-core-ui .button.active, .wp-core-ui .button.active:hover { - background-color: #dcdcde; - color: #135e96; - border-color: #0a4b78; - box-shadow: inset 0 2px 5px -3px #0a4b78; + background-color: rgba(56, 88, 233, 0.04); + color: #3858e9; + border-color: #3858e9; + box-shadow: none; } .wp-core-ui .button.active:focus { - border-color: #3582c4; - box-shadow: - inset 0 2px 5px -3px #0a4b78, - 0 0 0 1px #3582c4; + border-color: #3858e9; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) #3858e9; } .wp-core-ui .button[disabled], @@ -177,9 +187,9 @@ TABLE OF CONTENTS: .wp-core-ui .button-secondary:disabled, .wp-core-ui .button-secondary.disabled, .wp-core-ui .button-disabled { - color: #a7aaad !important; - border-color: #dcdcde !important; - background: #f6f7f7 !important; + color: #949494 !important; + border-color: #dddddd !important; + background: transparent !important; box-shadow: none !important; cursor: default; transform: none !important; @@ -201,7 +211,7 @@ TABLE OF CONTENTS: cursor: pointer; text-align: left; /* Mimics the default link style in common.css */ - color: #2271b1; + color: #3858e9; text-decoration: underline; transition-property: border, background, color; transition-duration: .05s; @@ -210,14 +220,15 @@ TABLE OF CONTENTS: .wp-core-ui .button-link:hover, .wp-core-ui .button-link:active { - color: #135e96; + color: #183ad6; } .wp-core-ui .button-link:focus { - color: #043959; - box-shadow: 0 0 0 2px #2271b1; + color: #3858e9; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) #3858e9; + border-radius: 2px; /* Only visible in Windows High Contrast mode */ - outline: 2px solid transparent; + outline: 1px solid transparent; } .wp-core-ui .button-link-delete { @@ -241,35 +252,37 @@ TABLE OF CONTENTS: ---------------------------------------------------------------------------- */ .wp-core-ui .button-primary { - background: #2271b1; - border-color: #2271b1; + background: #3858e9; + border-color: #3858e9; color: #fff; text-decoration: none; text-shadow: none; } .wp-core-ui .button-primary.hover, -.wp-core-ui .button-primary:hover, -.wp-core-ui .button-primary.focus, -.wp-core-ui .button-primary:focus { - background: #135e96; - border-color: #135e96; +.wp-core-ui .button-primary:hover { + background: #2145e6; + border-color: #2145e6; color: #fff; } .wp-core-ui .button-primary.focus, .wp-core-ui .button-primary:focus { + background: #3858e9; + border-color: #3858e9; + color: #fff; box-shadow: - 0 0 0 1px #fff, - 0 0 0 3px #2271b1; + 0 0 0 var(--wp-admin-border-width-focus, 1.5px) #3858e9, + inset 0 0 0 1px #fff; + outline: 1px solid transparent; } .wp-core-ui .button-primary.active, .wp-core-ui .button-primary.active:hover, .wp-core-ui .button-primary.active:focus, .wp-core-ui .button-primary:active { - background: #135e96; - border-color: #135e96; + background: #183ad6; + border-color: #183ad6; box-shadow: none; color: #fff; } @@ -278,9 +291,9 @@ TABLE OF CONTENTS: .wp-core-ui .button-primary:disabled, .wp-core-ui .button-primary-disabled, .wp-core-ui .button-primary.disabled { - color: #a7aaad !important; - background: #f6f7f7 !important; - border-color: #dcdcde !important; + color: #949494 !important; + background: #f0f0f0 !important; + border-color: #f0f0f0 !important; box-shadow: none !important; text-shadow: none !important; cursor: default; @@ -309,11 +322,11 @@ TABLE OF CONTENTS: } .wp-core-ui .button-group > .button:first-child { - border-radius: 3px 0 0 3px; + border-radius: 2px 0 0 2px; } .wp-core-ui .button-group > .button:last-child { - border-radius: 0 3px 3px 0; + border-radius: 0 2px 2px 0; } .wp-core-ui .button-group > .button-primary + .button { @@ -353,7 +366,7 @@ TABLE OF CONTENTS: input#save-post, a.preview { padding: 0 14px; - line-height: 2.71428571; /* 38px */ + line-height: 2.71428571; /* 38px - allows 40px min-height with 1px border */ font-size: 14px; vertical-align: middle; min-height: 40px; @@ -366,9 +379,9 @@ TABLE OF CONTENTS: } #media-upload.wp-core-ui .button { - padding: 0 10px 1px; + padding: 0 10px; + line-height: 1.69230769; /* 22px */ min-height: 24px; - line-height: 22px; font-size: 13px; } @@ -386,8 +399,8 @@ TABLE OF CONTENTS: .wp-core-ui.wp-customizer .button { font-size: 13px; - line-height: 2.15384615; /* 28px */ - min-height: 30px; + line-height: 2.30769231; /* 30px */ + min-height: 32px; margin: 0; vertical-align: inherit; } @@ -404,9 +417,9 @@ TABLE OF CONTENTS: /* Reset responsive styles on Log in button on iframed login form */ .interim-login .button.button-large { - min-height: 30px; - line-height: 2; - padding: 0 12px 2px; + min-height: 32px; + line-height: 2.30769231; /* 30px */ + padding: 0 12px; } } From 646d99837a77009bdc06ae8ba18494e3ce5a7c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 12 Dec 2025 16:18:45 +0100 Subject: [PATCH 07/16] Admin UI: Fix theme card button sizing and visibility Update theme card buttons to work with the new design system sizing. **Button sizing:** - Use compact size (32px) for theme card buttons since they're in a space-constrained context - Set explicit min-height, line-height, and padding to match compact spec **Button visibility:** - Add white background to secondary buttons for visibility against the semi-transparent theme card overlay - Use :not(.button-primary) selector to preserve primary button styling - Adjust hover state to use #f0f0f0 background **Layout adjustments:** - Increase theme name vertical padding from 15px to 16px to accommodate taller buttons - Adjust active theme padding-right from 110px to 115px for button width - Reduce theme-actions horizontal padding from 15px to 12px See: https://core.trac.wordpress.org/ticket/64308 --- src/wp-admin/css/themes.css | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/wp-admin/css/themes.css b/src/wp-admin/css/themes.css index ea62a09cf1ed1..113cec87f50e7 100644 --- a/src/wp-admin/css/themes.css +++ b/src/wp-admin/css/themes.css @@ -83,7 +83,7 @@ body.js .theme-browser.search-loading { font-weight: 600; height: 18px; margin: 0; - padding: 15px; + padding: 16px 15px; box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1); overflow: hidden; white-space: nowrap; @@ -112,9 +112,26 @@ body.js .theme-browser.search-loading { margin-right: 3px; } +/* Use compact size for space-constrained theme cards */ .theme-browser .theme .theme-actions .button { float: none; margin-left: 3px; + min-height: 32px; + line-height: 2.30769231; /* 30px for 32px min-height */ + padding: 0 12px; +} + +/* Secondary buttons need white background for visibility on semi-transparent overlay */ +.theme-browser .theme .theme-actions .button:not(.button-primary) { + background: #fff; +} + +.theme-browser .theme .theme-actions .button:not(.button-primary):hover { + background: #f0f0f0; +} + +.theme-browser .theme .theme-actions .button:not(.button-primary):focus { + background: #fff; } /** @@ -211,7 +228,7 @@ body.js .theme-browser.search-loading { .theme-browser .theme.active .theme-name { background: #1d2327; color: #fff; - padding-right: 110px; + padding-right: 115px; font-weight: 300; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5); } @@ -240,7 +257,7 @@ body.js .theme-browser.search-loading { top: 50%; transform: translateY(-50%); right: 0; - padding: 9px 15px; + padding: 9px 12px; box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1); } @@ -248,6 +265,19 @@ body.js .theme-browser.search-loading { margin-right: 0; } +/* Active theme secondary buttons need white background for visibility on dark overlay */ +.theme-browser .theme.active .theme-actions .button:not(.button-primary) { + background: #fff; +} + +.theme-browser .theme.active .theme-actions .button:not(.button-primary):hover { + background: #f0f0f0; +} + +.theme-browser .theme.active .theme-actions .button:not(.button-primary):focus { + background: #fff; +} + .theme-browser .theme .theme-author { background: #1d2327; color: #f0f0f1; From 23472a1a8f835f791eaa1b6c2ac9ca6f9ec0ccae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 12 Dec 2025 14:12:15 +0100 Subject: [PATCH 08/16] Admin UI: Add design system tokens for admin reskin Introduces _tokens.scss with Sass variables derived from the WordPress Design System in Figma. These tokens provide consistent values for: - Spacing (4px grid units) - Border radius - Gray scale - Semantic colors (alerts/notices) - Typography scale - Elevation (box shadows) - Component sizing (buttons, inputs, checkboxes) The tokens are imported into _variables.scss and can be used across all admin stylesheets compiled via Sass. Note: These are Sass-only variables. No new CSS custom properties are exposed to maintain backward compatibility. The only CSS custom properties available remain those from wp-base-styles. Part of the WordPress 7.0 admin visual reskin initiative. See: https://core.trac.wordpress.org/ticket/64308 --- src/wp-admin/css/colors/_tokens.scss | 212 ++++++++++++++++++++++++ src/wp-admin/css/colors/_variables.scss | 5 +- 2 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 src/wp-admin/css/colors/_tokens.scss diff --git a/src/wp-admin/css/colors/_tokens.scss b/src/wp-admin/css/colors/_tokens.scss new file mode 100644 index 0000000000000..785f1f47f5076 --- /dev/null +++ b/src/wp-admin/css/colors/_tokens.scss @@ -0,0 +1,212 @@ +// ========================================================================== +// WordPress Design System Tokens +// ========================================================================== +// +// These tokens are derived from the WordPress Design System in Figma: +// https://www.figma.com/design/804HN2REV2iap2ytjRQ055/WordPress-Design-System +// +// IMPORTANT: Do NOT expose these as CSS custom properties. +// Use these Sass variables to compile to static CSS values. +// The only CSS custom properties available are those in wp-base-styles: +// - --wp-admin-theme-color +// - --wp-admin-theme-color--rgb +// - --wp-admin-theme-color-darker-10 +// - --wp-admin-theme-color-darker-20 +// - --wp-admin-border-width-focus +// +// ========================================================================== + + +// -------------------------------------------------------------------------- +// Grid Units (Spacing) +// -------------------------------------------------------------------------- +// Based on 4px base unit. Use for padding, margin, and gap values. + +$grid-unit-05: 4px; // Scales/grid unit 05 +$grid-unit-10: 8px; // Scales/grid unit 10 +$grid-unit-15: 12px; // Scales/grid unit 15 +$grid-unit-20: 16px; // Scales/grid unit 20 +$grid-unit-30: 24px; // Scales/grid unit 30 +$grid-unit-40: 32px; // Scales/grid unit 40 +$grid-unit-50: 40px; // Scales/grid unit 50 +$grid-unit-60: 48px; // Scales/grid unit 60 +$grid-unit-70: 56px; // Scales/grid unit 70 + + +// -------------------------------------------------------------------------- +// Border Radius +// -------------------------------------------------------------------------- + +$radius-xs: 1px; // radius-xs +$radius-s: 2px; // radius-s - Buttons, inputs +$radius-m: 4px; // radius-m - Focus rings +$radius-l: 8px; // radius-l - Cards, dashboard widgets +$radius-30: 12px; // Radius 30 +$radius-full: 9999px; // radius-full - Pills, avatars, circles + + +// -------------------------------------------------------------------------- +// Gray Scale +// -------------------------------------------------------------------------- +// Neutral colors for backgrounds, borders, and text. + +$gray-100: #f0f0f0; // Scales/Grays/gray-100 - Page background, disabled inputs +$gray-200: #e0e0e0; // Scales/Grays/gray-200 +$gray-300: #dddddd; // Scales/Grays/gray-300 +$gray-400: #cccccc; // Scales/Grays/gray-400 - Disabled borders +$gray-600: #949494; // Scales/Grays/gray-600 - Input borders, disabled text +$gray-700: #757575; // Scales/Grays/gray-700 +$gray-800: #2f2f2f; // Scales/Grays/gray-800 +$gray-900: #1e1e1e; // Scales/Grays/gray-900 - Primary text + +$white: #ffffff; // Scales/Black & White/white + + +// -------------------------------------------------------------------------- +// Theme Colors (Static reference values) +// -------------------------------------------------------------------------- +// For actual theme color usage, use var(--wp-admin-theme-color) instead. +// These are provided for reference and for contexts where CSS vars aren't available. + +$theme-reference: #3858e9; // Scales/Theme/theme (modern scheme) +$theme-darker-10-reference: #2145e6; // Scales/Theme/theme-darker-10 +$theme-darker-20-reference: #183ad6; // Scales/Theme/theme-darker-20 +$theme-alpha-04: rgba(56, 88, 233, 0.04); // Scales/Theme/theme-alpha-04 (4% opacity) +$theme-alpha-08: rgba(56, 88, 233, 0.08); // Scales/Theme/theme-alpha-08 (8% opacity) + +$brand-9: #4465db; // Scales/brand-9 - Focus ring color (static, not theme-dependent) + + +// -------------------------------------------------------------------------- +// Semantic Colors +// -------------------------------------------------------------------------- +// Use these for notices, alerts, and status indicators. +// These are intentionally NOT theme-dependent for consistency. + +$alert-yellow: #f0b849; // Scales/Yellow/alert-yellow - Warnings +$alert-green: #4ab866; // Scales/Green/alert-green - Success +$alert-red: #cc1818; // Scales/Red/alert-red - Errors +$alert-blue: #3858e9; // Info notices (matches modern theme) + +// Background tints for notices +$alert-yellow-bg: #fef8ee; // Warning notice background +$alert-green-bg: #eff9f1; // Success notice background +$alert-red-bg: #fcf0f0; // Error notice background + +$synced-color: #7a00df; // Scales/Purple/--wp-block-synced-color + + +// -------------------------------------------------------------------------- +// Text Colors +// -------------------------------------------------------------------------- + +$text-primary: $gray-900; // Primary text color +$text-secondary: $gray-700; // Secondary text +$text-tertiary: #5d5d5d; // Alias/text/text-tertiary - Placeholder, hints +$text-disabled: $gray-600; // Disabled text + + +// -------------------------------------------------------------------------- +// Component Tokens +// -------------------------------------------------------------------------- + +// Inputs +$input-bg: $white; // Alias/bg/bg-input +$input-border-color: $gray-600; // Default input border +$input-border-color-disabled: $gray-400; +$input-bg-disabled: $gray-100; +$input-border-width-default: 1px; // Input/Default +$input-border-width-focus: 1.5px; // Input/Focus +$field-spacing-horizontal: 8px; // Alias/field-spacing-horizontal + +// Checkboxes and Radios +$checkbox-size: 16px; // Alias/checkbox +$radio-size: 16px; // Alias/radio + +// Toggles +$toggle-width: 32px; // Alias/toggle-width +$toggle-height: 16px; // Alias/toggle-height + +// Buttons +// Note: Gutenberg is transitioning to 40px as the default button size. +// The "compact" size (32px) is available for space-constrained contexts. +$button-height-default: 40px; // Default button height (next-default-40px) +$button-height-compact: 32px; // Compact button height +$button-height-small: 24px; // Small button height + +// Cards and Surfaces +$card-bg: $white; +$card-border-color: rgba(0, 0, 0, 0.1); +$card-border-width: 1px; +$card-border-radius: $radius-l; // 8px for dashboard widgets +$card-border-radius-metabox: 0; // 0 for post editor metaboxes +$card-divider-color: rgba(0, 0, 0, 0.1); + +// Card Padding Sizes +$card-padding-xs: $grid-unit-10; // 8px - xSmall cards +$card-padding-sm: $grid-unit-20; // 16px - Small cards (metaboxes, dashboard widgets) +$card-padding-md-h: $grid-unit-30; // 24px - Medium cards horizontal +$card-padding-md-v: $grid-unit-20; // 16px - Medium cards vertical +$card-padding-lg-h: $grid-unit-40; // 32px - Large cards horizontal +$card-padding-lg-v: $grid-unit-30; // 24px - Large cards vertical + +// Page Layout +$page-padding-large: 48px; // Alias/page-large +$page-padding-small: 24px; // Alias/page-small + + +// -------------------------------------------------------------------------- +// Typography Scale +// -------------------------------------------------------------------------- + +// Font Sizes +$font-size-xs: 11px; // xs - Small labels, button small +$font-size-s: 12px; // s - Body small +$font-size-m: 13px; // m - Base body text, buttons +$font-size-l: 15px; // l - Body large, heading large +$font-size-xl: 20px; // xl - Heading XL + +// Line Heights +$line-height-xs: 16px; // xs +$line-height-s: 20px; // s - Most UI elements +$line-height-m: 24px; // m - Body large + +// Font Weights +$font-weight-regular: 400; // Regular - Body text +$font-weight-medium: 500; // Medium - Headings, buttons + + +// -------------------------------------------------------------------------- +// Elevation (Box Shadows) +// -------------------------------------------------------------------------- + +$elevation-xs: + 0 4px 4px rgba(0, 0, 0, 0.01), + 0 3px 3px rgba(0, 0, 0, 0.02), + 0 1px 2px rgba(0, 0, 0, 0.02), + 0 1px 1px rgba(0, 0, 0, 0.03); + +$elevation-s: + 0 8px 8px rgba(0, 0, 0, 0.02), + 0 1px 2px rgba(0, 0, 0, 0.05); + +$elevation-m: + 0 16px 16px rgba(0, 0, 0, 0.02), + 0 4px 5px rgba(0, 0, 0, 0.03), + 0 2px 3px rgba(0, 0, 0, 0.05); + +$elevation-l: + 0 50px 43px rgba(0, 0, 0, 0.02), + 0 30px 36px rgba(0, 0, 0, 0.04), + 0 15px 27px rgba(0, 0, 0, 0.07), + 0 5px 15px rgba(0, 0, 0, 0.08); + + +// -------------------------------------------------------------------------- +// Layout +// -------------------------------------------------------------------------- + +$modal-width-small: 384px; // Layout/Modal small +$modal-width-medium: 512px; // Layout/Modal medium +$modal-width-large: 840px; // Layout/Modal large + diff --git a/src/wp-admin/css/colors/_variables.scss b/src/wp-admin/css/colors/_variables.scss index 8a073f830e4b6..d37c2b1392f00 100644 --- a/src/wp-admin/css/colors/_variables.scss +++ b/src/wp-admin/css/colors/_variables.scss @@ -1,5 +1,8 @@ @use "sass:color"; +// Import design system tokens +@use "tokens" as *; + // assign default value to all undefined variables $scheme-name: "default" !default; @@ -15,7 +18,7 @@ $notification-color: #d54e21 !default; // global -$body-background: #f1f1f1 !default; +$body-background: $gray-100 !default; $link: #0073aa !default; $link-focus: color.adjust($link, $lightness: 10%) !default; From a91510a7857cbb345a1006ec8b035fd4865626f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 12 Dec 2025 15:11:10 +0100 Subject: [PATCH 09/16] Admin UI: Reskin buttons to align with WordPress Design System Update all button styles to match Gutenberg's component patterns and the WordPress Design System specifications. **Sizing (aligned with Gutenberg's next-default-40px):** - Default buttons: 40px height (was 30px) - Compact buttons: 32px (new class for space-constrained contexts) - Small buttons: 24px (was 26px) - Hero buttons: 48px (was 46px) - Use min-height + line-height for accessibility with browser zoom **Visual updates:** - Border radius: 2px (was 3px) - Font weight: 500 (was 400/normal) - Transparent background for secondary/tertiary buttons **Focus states (Gutenberg-style outer ring):** - Primary: outer theme color ring + inner white ring for contrast - Secondary/Tertiary/Link: single outer theme color ring - Use var(--wp-admin-theme-color) for focus ring color **Hover/Active states:** - Secondary buttons: subtle rgba() background tint on hover/active - Use theme-color-darker-20 for hover text/border colors - Link buttons: theme-color-darker-20 on hover **Components updated:** - .button, .button-primary, .button-secondary - .button-link, .button-link-delete - .page-title-action (now uses secondary button pattern) See: https://core.trac.wordpress.org/ticket/64308 --- src/wp-admin/css/colors/_admin.scss | 144 ++++++++++----------------- src/wp-admin/css/colors/_mixins.scss | 123 ++++++++++++++++++++--- src/wp-admin/css/common.css | 10 +- src/wp-includes/css/buttons.css | 143 ++++++++++++++------------ 4 files changed, 246 insertions(+), 174 deletions(-) diff --git a/src/wp-admin/css/colors/_admin.scss b/src/wp-admin/css/colors/_admin.scss index 553037e3d30d1..97904e7e9e352 100644 --- a/src/wp-admin/css/colors/_admin.scss +++ b/src/wp-admin/css/colors/_admin.scss @@ -3,6 +3,7 @@ @forward 'variables' show $scheme-name, $base-color, $body-background, $button-color, $custom-welcome-panel, $dashboard-accent-1, $dashboard-accent-2, $dashboard-icon-background, $form-checked, $highlight-color, $icon-color, $link, $link-focus, $low-contrast-theme, $menu-bubble-text, $menu-collapse-focus-icon, $menu-collapse-text, $menu-highlight-background, $menu-highlight-icon, $menu-highlight-text, $menu-submenu-text, $menu-submenu-focus-text, $menu-submenu-background, $notification-color, $text-color; @use 'variables'; @use 'mixins'; +@use 'tokens'; /** * This function name uses British English to maintain backward compatibility, as developers @@ -37,13 +38,27 @@ span.wp-media-buttons-icon:before { color: currentColor; } -.wp-core-ui .button-link { - color: variables.$link; +/* Link button - appears as text link, no border or background */ +/* Matches Gutenberg's .is-link button variant */ +.wp-core-ui .button-link, +.wp-core-ui .button.button-link { + color: var(--wp-admin-theme-color); &:hover, - &:active, + &:active { + color: var(--wp-admin-theme-color-darker-20); + } + &:focus { - color: variables.$link-focus; + color: var(--wp-admin-theme-color); + border-radius: tokens.$radius-s; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + outline: 1px solid transparent; + } + + &:disabled, + &[aria-disabled="true"] { + color: tokens.$gray-600; } } @@ -51,7 +66,7 @@ span.wp-media-buttons-icon:before { .media-modal .trash-attachment, .media-modal .untrash-attachment, .wp-core-ui .button-link-delete { - color: #a00; + color: tokens.$alert-red; } .media-modal .delete-attachment:hover, @@ -62,7 +77,7 @@ span.wp-media-buttons-icon:before { .media-modal .untrash-attachment:focus, .wp-core-ui .button-link-delete:hover, .wp-core-ui .button-link-delete:focus { - color: #dc3232; + color: color.adjust(tokens.$alert-red, $lightness: 10%); } /* Forms */ @@ -109,79 +124,24 @@ textarea:focus { .wp-core-ui { + /* Default button - theme color border and text (matches secondary) */ .button { - border-color: #7e8993; - color: #32373c; - } - - .button.hover, - .button:hover, - .button.focus, - .button:focus { - border-color: color.adjust(#7e8993, $lightness: -5%); - color: color.adjust(#32373c, $lightness: -5%); - } - - .button.focus, - .button:focus { - border-color: #7e8993; - color: color.adjust(#32373c, $lightness: -5%); - box-shadow: 0 0 0 1px #32373c; - } - - .button:active { - border-color: #7e8993; - color: color.adjust(#32373c, $lightness: -5%); - box-shadow: none; - } - - .button.active, - .button.active:focus, - .button.active:hover { - border-color: variables.$button-color; - color: color.adjust(#32373c, $lightness: -5%); - box-shadow: inset 0 2px 5px -3px variables.$button-color; + @include mixins.button-secondary(); } - .button.active:focus { - box-shadow: 0 0 0 1px #32373c; - } - - @if ( variables.$low-contrast-theme != "true" ) { - .button, - .button-secondary { - color: variables.$highlight-color; - border-color: variables.$highlight-color; - } - - .button.hover, - .button:hover, - .button-secondary:hover{ - border-color: color.adjust(variables.$highlight-color, $lightness: -10%); - color: color.adjust(variables.$highlight-color, $lightness: -10%); - } - - .button.focus, - .button:focus, - .button-secondary:focus { - border-color: color.adjust(variables.$highlight-color, $lightness: 10%); - color: color.adjust(variables.$highlight-color, $lightness: -20%); - box-shadow: 0 0 0 1px color.adjust(variables.$highlight-color, $lightness: 10%); - } - - .button-primary { - &:hover { - color: #fff; - } - } + /* Secondary button - same as default */ + .button-secondary { + @include mixins.button-secondary(); } + /* Primary button - theme color background */ .button-primary { @include mixins.button( variables.$button-color ); } .button-group > .button.active { - border-color: variables.$button-color; + border-color: var(--wp-admin-theme-color); + background: rgba(var(--wp-admin-theme-color--rgb), 0.04); } .wp-ui-primary { @@ -215,28 +175,34 @@ textarea:focus { /* List tables */ -@if variables.$low-contrast-theme == "true" { - .wrap .page-title-action:hover { - color: variables.$menu-text; - background-color: variables.$menu-background; - } -} @else { - .wrap .page-title-action, - .wrap .page-title-action:active { - border: 1px solid variables.$highlight-color; - color: variables.$highlight-color; - } - .wrap .page-title-action:hover { - color: color.adjust(variables.$highlight-color, $lightness: -10%); - border-color: color.adjust(variables.$highlight-color, $lightness: -10%); - } +// .page-title-action uses secondary button styling +.wrap .page-title-action { + background: transparent; + border: 1px solid var(--wp-admin-theme-color); + border-radius: tokens.$radius-s; + color: var(--wp-admin-theme-color); +} - .wrap .page-title-action:focus { - border-color: color.adjust(variables.$highlight-color, $lightness: 10%); - color: color.adjust(variables.$highlight-color, $lightness: -20%); - box-shadow: 0 0 0 1px color.adjust(variables.$highlight-color, $lightness: 10%); - } +.wrap .page-title-action:hover { + background: rgba(var(--wp-admin-theme-color--rgb), 0.04); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); +} + +.wrap .page-title-action:focus { + background: transparent; + border-color: var(--wp-admin-theme-color); + color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + outline: 1px solid transparent; +} + +.wrap .page-title-action:active { + background: rgba(var(--wp-admin-theme-color--rgb), 0.08); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); + box-shadow: none; } .view-switch a.current:before { diff --git a/src/wp-admin/css/colors/_mixins.scss b/src/wp-admin/css/colors/_mixins.scss index d33cf3bb2d854..d783bf268613e 100644 --- a/src/wp-admin/css/colors/_mixins.scss +++ b/src/wp-admin/css/colors/_mixins.scss @@ -1,39 +1,132 @@ @use 'sass:color'; +@use 'tokens'; /* - * Button mixin- creates a button effect with correct - * highlights/shadows, based on a base color. + * Button mixin - creates a primary button effect. + * Uses CSS custom properties for theme color support across color schemes. */ @mixin button( $button-color, $button-text-color: #fff ) { - background: $button-color; - border-color: $button-color; + background: var(--wp-admin-theme-color); + border-color: transparent; + border-radius: tokens.$radius-s; color: $button-text-color; - &:hover, - &:focus { - background: color.adjust($button-color, $lightness: 3%); - border-color: color.adjust($button-color, $lightness: -3%); + &:hover { + background: var(--wp-admin-theme-color-darker-10); + border-color: transparent; color: $button-text-color; } &:focus { + background: var(--wp-admin-theme-color); + border-color: transparent; + color: $button-text-color; + /* Gutenberg-style focus ring: outer theme color + inset white for contrast */ box-shadow: - 0 0 0 1px #fff, - 0 0 0 3px $button-color; + 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color), + inset 0 0 0 1px tokens.$white; + /* Visible in Windows High Contrast mode */ + outline: 1px solid transparent; } &:active { - background: color.adjust($button-color, $lightness: -5%); - border-color: color.adjust($button-color, $lightness: -5%); + background: var(--wp-admin-theme-color-darker-20); + border-color: transparent; color: $button-text-color; } + &:disabled, + &.disabled { + background: tokens.$gray-100; + border-color: transparent; + color: tokens.$gray-600; + cursor: not-allowed; + } + &.active, &.active:focus, &.active:hover { - background: $button-color; + background: var(--wp-admin-theme-color-darker-10); color: $button-text-color; - border-color: color.adjust($button-color, $lightness: -15%); - box-shadow: inset 0 2px 5px -3px color.adjust($button-color, $lightness: -50%); + border-color: transparent; + box-shadow: none; + } +} + +/* + * Secondary button mixin - outlined style with theme color. + * Matches Gutenberg's .is-secondary button variant. + */ +@mixin button-secondary() { + background: transparent; + border: 1px solid var(--wp-admin-theme-color); + border-radius: tokens.$radius-s; + color: var(--wp-admin-theme-color); + + &:hover { + background: rgba(var(--wp-admin-theme-color--rgb), 0.04); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); + } + + &:focus { + background: transparent; + border-color: var(--wp-admin-theme-color); + color: var(--wp-admin-theme-color); + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + outline: 1px solid transparent; + } + + &:active { + background: rgba(var(--wp-admin-theme-color--rgb), 0.08); + border-color: var(--wp-admin-theme-color-darker-20); + color: var(--wp-admin-theme-color-darker-20); + box-shadow: none; + } + + &:disabled, + &.disabled { + background: transparent; + border-color: tokens.$gray-300; + color: tokens.$gray-600; + cursor: not-allowed; + } +} + +/* + * Tertiary button mixin - transparent background, gray text. + */ +@mixin button-tertiary() { + background: transparent; + border: 1px solid tokens.$gray-600; + border-radius: tokens.$radius-s; + color: tokens.$gray-900; + + &:hover { + background: rgba(0, 0, 0, 0.05); + border-color: tokens.$gray-700; + color: tokens.$gray-900; + } + + &:focus { + background: transparent; + border-color: var(--wp-admin-theme-color); + color: tokens.$gray-900; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); + outline: 1px solid transparent; + } + + &:active { + background: rgba(0, 0, 0, 0.1); + border-color: tokens.$gray-700; + color: tokens.$gray-900; + } + + &:disabled, + &.disabled { + background: transparent; + border-color: tokens.$gray-400; + color: tokens.$gray-600; + cursor: not-allowed; } } diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css index e062a471d7150..393787f8e6c2a 100644 --- a/src/wp-admin/css/common.css +++ b/src/wp-admin/css/common.css @@ -631,11 +631,12 @@ code { top: -3px; margin-left: 4px; border: 1px solid #2271b1; - border-radius: 3px; - background: #f6f7f7; + border-radius: 2px; + background: transparent; font-size: 13px; - font-weight: 400; - line-height: 2.15384615; + font-weight: 500; + min-height: 40px; + line-height: 2.92307692; /* 38px for 40px height */ color: #2271b1; /* use the standard color used for buttons */ padding: 0 10px; min-height: 30px; @@ -649,7 +650,6 @@ code { .wrap .add-new-h2:hover, /* deprecated */ .wrap .page-title-action:hover { - background: #f0f0f1; border-color: #0a4b78; color: #0a4b78; } diff --git a/src/wp-includes/css/buttons.css b/src/wp-includes/css/buttons.css index 5146be4274254..3eda51ae5d788 100644 --- a/src/wp-includes/css/buttons.css +++ b/src/wp-includes/css/buttons.css @@ -46,15 +46,16 @@ TABLE OF CONTENTS: display: inline-block; text-decoration: none; font-size: 13px; - line-height: 2.15384615; /* 28px */ - min-height: 30px; + font-weight: 500; + line-height: 2.92307692; /* 38px - allows 40px min-height with 1px border */ + min-height: 40px; margin: 0; - padding: 0 10px; + padding: 0 16px; cursor: pointer; border-width: 1px; border-style: solid; -webkit-appearance: none; - border-radius: 3px; + border-radius: 2px; white-space: nowrap; box-sizing: border-box; } @@ -69,26 +70,36 @@ TABLE OF CONTENTS: padding: 0; } -.wp-core-ui .button.button-large, -.wp-core-ui .button-group.button-large .button { +/* Compact size - 32px, for space-constrained contexts */ +.wp-core-ui .button.button-compact, +.wp-core-ui .button-group.button-compact .button { + line-height: 2.30769231; /* 30px - allows 32px min-height with 1px border */ min-height: 32px; - line-height: 2.30769231; /* 30px */ padding: 0 12px; } +/* Small size - 24px */ .wp-core-ui .button.button-small, .wp-core-ui .button-group.button-small .button { - min-height: 26px; - line-height: 2.18181818; /* 24px */ + line-height: 2; /* 22px - allows 24px min-height with 1px border */ + min-height: 24px; padding: 0 8px; font-size: 11px; } +/* Large size - explicit 40px (same as default, for semantic clarity) */ +.wp-core-ui .button.button-large, +.wp-core-ui .button-group.button-large .button { + line-height: 2.92307692; /* 38px - allows 40px min-height with 1px border */ + min-height: 40px; + padding: 0 16px; +} + .wp-core-ui .button.button-hero, .wp-core-ui .button-group.button-hero .button { font-size: 14px; - min-height: 46px; - line-height: 3.14285714; + line-height: 3.28571429; /* 46px - allows 48px min-height with 1px border */ + min-height: 48px; padding: 0 36px; } @@ -115,9 +126,9 @@ TABLE OF CONTENTS: .wp-core-ui .button, .wp-core-ui .button-secondary { - color: #2271b1; - border-color: #2271b1; - background: #f6f7f7; + color: #3858e9; + border-color: #3858e9; + background: transparent; vertical-align: top; } @@ -127,21 +138,21 @@ TABLE OF CONTENTS: .wp-core-ui .button.hover, .wp-core-ui .button:hover, -.wp-core-ui .button-secondary:hover{ - background: #f0f0f1; - border-color: #0a4b78; - color: #0a4b78; +.wp-core-ui .button-secondary:hover { + background: rgba(56, 88, 233, 0.04); + border-color: #183ad6; + color: #183ad6; } .wp-core-ui .button.focus, .wp-core-ui .button:focus, .wp-core-ui .button-secondary:focus { - background: #f6f7f7; - border-color: #3582c4; - color: #0a4b78; - box-shadow: 0 0 0 1px #3582c4; + background: transparent; + border-color: #3858e9; + color: #3858e9; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) #3858e9; /* Only visible in Windows High Contrast mode */ - outline: 2px solid transparent; + outline: 1px solid transparent; /* Reset inherited offset from Gutenberg */ outline-offset: 0; } @@ -149,25 +160,24 @@ TABLE OF CONTENTS: /* :active state */ .wp-core-ui .button:active, .wp-core-ui .button-secondary:active { - background: #f6f7f7; - border-color: #8c8f94; + background: rgba(56, 88, 233, 0.08); + border-color: #183ad6; + color: #183ad6; box-shadow: none; } /* pressed state e.g. a selected setting */ .wp-core-ui .button.active, .wp-core-ui .button.active:hover { - background-color: #dcdcde; - color: #135e96; - border-color: #0a4b78; - box-shadow: inset 0 2px 5px -3px #0a4b78; + background-color: rgba(56, 88, 233, 0.04); + color: #3858e9; + border-color: #3858e9; + box-shadow: none; } .wp-core-ui .button.active:focus { - border-color: #3582c4; - box-shadow: - inset 0 2px 5px -3px #0a4b78, - 0 0 0 1px #3582c4; + border-color: #3858e9; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) #3858e9; } .wp-core-ui .button[disabled], @@ -177,9 +187,9 @@ TABLE OF CONTENTS: .wp-core-ui .button-secondary:disabled, .wp-core-ui .button-secondary.disabled, .wp-core-ui .button-disabled { - color: #a7aaad !important; - border-color: #dcdcde !important; - background: #f6f7f7 !important; + color: #949494 !important; + border-color: #dddddd !important; + background: transparent !important; box-shadow: none !important; cursor: default; transform: none !important; @@ -201,7 +211,7 @@ TABLE OF CONTENTS: cursor: pointer; text-align: left; /* Mimics the default link style in common.css */ - color: #2271b1; + color: #3858e9; text-decoration: underline; transition-property: border, background, color; transition-duration: .05s; @@ -210,14 +220,15 @@ TABLE OF CONTENTS: .wp-core-ui .button-link:hover, .wp-core-ui .button-link:active { - color: #135e96; + color: #183ad6; } .wp-core-ui .button-link:focus { - color: #043959; - box-shadow: 0 0 0 2px #2271b1; + color: #3858e9; + box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) #3858e9; + border-radius: 2px; /* Only visible in Windows High Contrast mode */ - outline: 2px solid transparent; + outline: 1px solid transparent; } .wp-core-ui .button-link-delete { @@ -241,35 +252,37 @@ TABLE OF CONTENTS: ---------------------------------------------------------------------------- */ .wp-core-ui .button-primary { - background: #2271b1; - border-color: #2271b1; + background: #3858e9; + border-color: #3858e9; color: #fff; text-decoration: none; text-shadow: none; } .wp-core-ui .button-primary.hover, -.wp-core-ui .button-primary:hover, -.wp-core-ui .button-primary.focus, -.wp-core-ui .button-primary:focus { - background: #135e96; - border-color: #135e96; +.wp-core-ui .button-primary:hover { + background: #2145e6; + border-color: #2145e6; color: #fff; } .wp-core-ui .button-primary.focus, .wp-core-ui .button-primary:focus { + background: #3858e9; + border-color: #3858e9; + color: #fff; box-shadow: - 0 0 0 1px #fff, - 0 0 0 3px #2271b1; + 0 0 0 var(--wp-admin-border-width-focus, 1.5px) #3858e9, + inset 0 0 0 1px #fff; + outline: 1px solid transparent; } .wp-core-ui .button-primary.active, .wp-core-ui .button-primary.active:hover, .wp-core-ui .button-primary.active:focus, .wp-core-ui .button-primary:active { - background: #135e96; - border-color: #135e96; + background: #183ad6; + border-color: #183ad6; box-shadow: none; color: #fff; } @@ -278,9 +291,9 @@ TABLE OF CONTENTS: .wp-core-ui .button-primary:disabled, .wp-core-ui .button-primary-disabled, .wp-core-ui .button-primary.disabled { - color: #a7aaad !important; - background: #f6f7f7 !important; - border-color: #dcdcde !important; + color: #949494 !important; + background: #f0f0f0 !important; + border-color: #f0f0f0 !important; box-shadow: none !important; text-shadow: none !important; cursor: default; @@ -309,11 +322,11 @@ TABLE OF CONTENTS: } .wp-core-ui .button-group > .button:first-child { - border-radius: 3px 0 0 3px; + border-radius: 2px 0 0 2px; } .wp-core-ui .button-group > .button:last-child { - border-radius: 0 3px 3px 0; + border-radius: 0 2px 2px 0; } .wp-core-ui .button-group > .button-primary + .button { @@ -353,7 +366,7 @@ TABLE OF CONTENTS: input#save-post, a.preview { padding: 0 14px; - line-height: 2.71428571; /* 38px */ + line-height: 2.71428571; /* 38px - allows 40px min-height with 1px border */ font-size: 14px; vertical-align: middle; min-height: 40px; @@ -366,9 +379,9 @@ TABLE OF CONTENTS: } #media-upload.wp-core-ui .button { - padding: 0 10px 1px; + padding: 0 10px; + line-height: 1.69230769; /* 22px */ min-height: 24px; - line-height: 22px; font-size: 13px; } @@ -386,8 +399,8 @@ TABLE OF CONTENTS: .wp-core-ui.wp-customizer .button { font-size: 13px; - line-height: 2.15384615; /* 28px */ - min-height: 30px; + line-height: 2.30769231; /* 30px */ + min-height: 32px; margin: 0; vertical-align: inherit; } @@ -404,9 +417,9 @@ TABLE OF CONTENTS: /* Reset responsive styles on Log in button on iframed login form */ .interim-login .button.button-large { - min-height: 30px; - line-height: 2; - padding: 0 12px 2px; + min-height: 32px; + line-height: 2.30769231; /* 30px */ + padding: 0 12px; } } From f66c7b69e2338bcc57d6374a2876de292663fc64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 12 Dec 2025 16:18:45 +0100 Subject: [PATCH 10/16] Admin UI: Fix theme card button sizing and visibility Update theme card buttons to work with the new design system sizing. **Button sizing:** - Use compact size (32px) for theme card buttons since they're in a space-constrained context - Set explicit min-height, line-height, and padding to match compact spec **Button visibility:** - Add white background to secondary buttons for visibility against the semi-transparent theme card overlay - Use :not(.button-primary) selector to preserve primary button styling - Adjust hover state to use #f0f0f0 background **Layout adjustments:** - Increase theme name vertical padding from 15px to 16px to accommodate taller buttons - Adjust active theme padding-right from 110px to 115px for button width - Reduce theme-actions horizontal padding from 15px to 12px See: https://core.trac.wordpress.org/ticket/64308 --- src/wp-admin/css/themes.css | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/wp-admin/css/themes.css b/src/wp-admin/css/themes.css index ea62a09cf1ed1..113cec87f50e7 100644 --- a/src/wp-admin/css/themes.css +++ b/src/wp-admin/css/themes.css @@ -83,7 +83,7 @@ body.js .theme-browser.search-loading { font-weight: 600; height: 18px; margin: 0; - padding: 15px; + padding: 16px 15px; box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1); overflow: hidden; white-space: nowrap; @@ -112,9 +112,26 @@ body.js .theme-browser.search-loading { margin-right: 3px; } +/* Use compact size for space-constrained theme cards */ .theme-browser .theme .theme-actions .button { float: none; margin-left: 3px; + min-height: 32px; + line-height: 2.30769231; /* 30px for 32px min-height */ + padding: 0 12px; +} + +/* Secondary buttons need white background for visibility on semi-transparent overlay */ +.theme-browser .theme .theme-actions .button:not(.button-primary) { + background: #fff; +} + +.theme-browser .theme .theme-actions .button:not(.button-primary):hover { + background: #f0f0f0; +} + +.theme-browser .theme .theme-actions .button:not(.button-primary):focus { + background: #fff; } /** @@ -211,7 +228,7 @@ body.js .theme-browser.search-loading { .theme-browser .theme.active .theme-name { background: #1d2327; color: #fff; - padding-right: 110px; + padding-right: 115px; font-weight: 300; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5); } @@ -240,7 +257,7 @@ body.js .theme-browser.search-loading { top: 50%; transform: translateY(-50%); right: 0; - padding: 9px 15px; + padding: 9px 12px; box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1); } @@ -248,6 +265,19 @@ body.js .theme-browser.search-loading { margin-right: 0; } +/* Active theme secondary buttons need white background for visibility on dark overlay */ +.theme-browser .theme.active .theme-actions .button:not(.button-primary) { + background: #fff; +} + +.theme-browser .theme.active .theme-actions .button:not(.button-primary):hover { + background: #f0f0f0; +} + +.theme-browser .theme.active .theme-actions .button:not(.button-primary):focus { + background: #fff; +} + .theme-browser .theme .theme-author { background: #1d2327; color: #f0f0f1; From 0cb45934e647acfb3f988f41bbc64d25b3f675d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 23 Jan 2026 11:48:17 +0100 Subject: [PATCH 11/16] Admin UI: Add global dashicons centering for buttons Adds line-height rules to buttons.css to vertically center dashicons inside all button variants (default, compact, small, hero). This provides a consistent solution instead of scattered individual fixes. Removes redundant dashicon centering fixes from dashboard.css and themes.css that are now handled by the global rules. --- src/wp-admin/css/dashboard.css | 4 ---- src/wp-admin/css/themes.css | 4 ---- src/wp-includes/css/buttons.css | 27 +++++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/wp-admin/css/dashboard.css b/src/wp-admin/css/dashboard.css index ddd2307e33534..eb333384d011b 100644 --- a/src/wp-admin/css/dashboard.css +++ b/src/wp-admin/css/dashboard.css @@ -1240,10 +1240,6 @@ a.rsswidget { margin: 12px 0; } -#dashboard_php_nag .button .dashicons-external { - line-height: 25px; -} - .bigger-bolder-text { font-weight: 600; font-size: 14px; diff --git a/src/wp-admin/css/themes.css b/src/wp-admin/css/themes.css index 113cec87f50e7..b27859dc9e5f2 100644 --- a/src/wp-admin/css/themes.css +++ b/src/wp-admin/css/themes.css @@ -1378,10 +1378,6 @@ div#custom-background-image img { transform: rotate( 45deg ); } -.background-position-control .button-group .dashicons { - margin-top: 9px; -} - .background-position-control .button-group + .button-group { margin-top: -1px; } diff --git a/src/wp-includes/css/buttons.css b/src/wp-includes/css/buttons.css index 3eda51ae5d788..f7060323c05eb 100644 --- a/src/wp-includes/css/buttons.css +++ b/src/wp-includes/css/buttons.css @@ -107,6 +107,26 @@ TABLE OF CONTENTS: display: none; } +/* Button Icons - Dashicons centering for all button sizes */ +.wp-core-ui .button .dashicons, +.wp-core-ui .button-primary .dashicons, +.wp-core-ui .button-secondary .dashicons { + line-height: 2.92307692; /* 38px - matches default button */ + vertical-align: top; +} + +.wp-core-ui .button.button-compact .dashicons { + line-height: 2.30769231; /* 30px - matches compact button */ +} + +.wp-core-ui .button.button-small .dashicons { + line-height: 2; /* 22px - matches small button */ +} + +.wp-core-ui .button.button-hero .dashicons { + line-height: 3.28571429; /* 46px - matches hero button */ +} + /* Style Reset buttons as simple text links */ .wp-core-ui input[type="reset"], @@ -373,6 +393,13 @@ TABLE OF CONTENTS: margin-bottom: 4px; } + /* Responsive Button Icons - Dashicons centering */ + .wp-core-ui .button .dashicons, + .wp-core-ui .button-primary .dashicons, + .wp-core-ui .button-secondary .dashicons { + line-height: 2.71428571; /* 38px - matches responsive button */ + } + /* Copy attachment URL button in the legacy edit media page. */ .wp-core-ui .copy-to-clipboard-container .copy-attachment-url { margin-bottom: 0; From b3cd5e0734ddc9f10b1689c37b154281b9931897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 23 Jan 2026 12:15:56 +0100 Subject: [PATCH 12/16] Admin UI: Fix dashicon line-height calculation in buttons Corrects the line-height values for dashicons inside buttons. The previous calculation incorrectly used the button's font-size (13px) as the base, but dashicons have their own font-size of 20px. Correct values: line-height = target-height / 20px - Default (38px): 1.9 - Compact (30px): 1.5 - Small (22px): 1.1 - Hero (46px): 2.3 --- src/wp-includes/css/buttons.css | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/css/buttons.css b/src/wp-includes/css/buttons.css index f7060323c05eb..0ceeb14900fcf 100644 --- a/src/wp-includes/css/buttons.css +++ b/src/wp-includes/css/buttons.css @@ -108,23 +108,24 @@ TABLE OF CONTENTS: } /* Button Icons - Dashicons centering for all button sizes */ +/* Dashicons are 20px font-size, so line-height = target-height / 20 */ .wp-core-ui .button .dashicons, .wp-core-ui .button-primary .dashicons, .wp-core-ui .button-secondary .dashicons { - line-height: 2.92307692; /* 38px - matches default button */ + line-height: 1.9; /* 38px (20px * 1.9) - matches default button */ vertical-align: top; } .wp-core-ui .button.button-compact .dashicons { - line-height: 2.30769231; /* 30px - matches compact button */ + line-height: 1.5; /* 30px (20px * 1.5) - matches compact button */ } .wp-core-ui .button.button-small .dashicons { - line-height: 2; /* 22px - matches small button */ + line-height: 1.1; /* 22px (20px * 1.1) - matches small button */ } .wp-core-ui .button.button-hero .dashicons { - line-height: 3.28571429; /* 46px - matches hero button */ + line-height: 2.3; /* 46px (20px * 2.3) - matches hero button */ } /* Style Reset buttons as simple text links */ @@ -397,7 +398,7 @@ TABLE OF CONTENTS: .wp-core-ui .button .dashicons, .wp-core-ui .button-primary .dashicons, .wp-core-ui .button-secondary .dashicons { - line-height: 2.71428571; /* 38px - matches responsive button */ + line-height: 1.9; /* 38px (20px * 1.9) - matches responsive button */ } /* Copy attachment URL button in the legacy edit media page. */ From fa76e97cc6bfc8c9907ecdfa0f489fe7eab38a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 23 Jan 2026 12:16:03 +0100 Subject: [PATCH 13/16] Admin UI: Fix button state icon centering Updates the icon positioning for button states (updating-message, installed, installing, etc.) to use line-height instead of margin-top hacks. This ensures icons are vertically centered in 40px buttons. --- src/wp-admin/css/common.css | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css index 393787f8e6c2a..ab7466bdf255c 100644 --- a/src/wp-admin/css/common.css +++ b/src/wp-admin/css/common.css @@ -1715,7 +1715,9 @@ p.auto-update-status { .button.installing:before, .button.activated-message:before, .button.activating-message:before { - margin: 3px 5px 0 -2px; + margin: 0 5px 0 -2px; + line-height: 1.9; /* 38px (20px * 1.9) - matches button */ + vertical-align: top; } #plugin-information-footer .button { @@ -1733,11 +1735,13 @@ p.auto-update-status { #plugin-information-footer .button.updated-message:before, #plugin-information-footer .button.activated-message:before, #plugin-information-footer .button.activating-message:before { - margin: 9px 5px 0 -2px; + margin: 0 5px 0 -2px; + line-height: 1.9; /* 38px (20px * 1.9) - matches button */ + vertical-align: top; } #plugin-information-footer .button.update-now.updating-message:before { - margin: -3px 5px 0 -2px; + margin: 0 5px 0 -2px; } .button-primary.updating-message:before, From dc30cee44fceae8dcb1b2c235fd33fe5ec9227b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 23 Jan 2026 12:16:10 +0100 Subject: [PATCH 14/16] Admin UI: Fix tablenav and plugin card for 40px buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates tablenav container and pagination buttons to match 40px button height: - tablenav height: 30px → 40px - Pagination buttons: min-width/height 30px → 40px, line-height adjusted Fixes plugin card update icon centering using line-height instead of margin-top hack. --- src/wp-admin/css/list-tables.css | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/wp-admin/css/list-tables.css b/src/wp-admin/css/list-tables.css index 80e652003a33c..43bca353ee1dc 100644 --- a/src/wp-admin/css/list-tables.css +++ b/src/wp-admin/css/list-tables.css @@ -680,9 +680,8 @@ th.sorted a span { .tablenav { clear: both; - height: 30px; + height: 40px; margin: 6px 0 4px; - padding-top: 5px; vertical-align: middle; } @@ -704,12 +703,12 @@ th.sorted a span { .tablenav .tablenav-pages .tablenav-pages-navspan { display: inline-block; vertical-align: baseline; - min-width: 30px; - min-height: 30px; + min-width: 40px; + min-height: 40px; margin: 0; padding: 0 4px; font-size: 16px; - line-height: 1.625; /* 26px */ + line-height: 2.375; /* 38px - matches default button */ text-align: center; } @@ -1421,11 +1420,11 @@ ul.cat-checklist input[name="post_category[]"]:indeterminate::before { content: "\f463"; content: "\f463" / ''; display: inline-block; - font: normal 20px/1 dashicons; - margin: -3px 5px 0 -2px; + font: normal 20px/1.9 dashicons; /* line-height 1.9 = 38px to match button */ + margin: 0 5px 0 -2px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - vertical-align: middle; + vertical-align: top; } .plugin-card .updating-message:before { From feb17ab5ac2465d05b578c3a74c3aa3b2501a46d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 23 Jan 2026 12:19:11 +0100 Subject: [PATCH 15/16] Admin UI: Use compact size for Screen Options and Help buttons Sets explicit compact button sizing (32px) for the Screen Options and Help toggle buttons in the admin header. These buttons should remain smaller than the default 40px buttons used elsewhere. --- src/wp-admin/css/common.css | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/wp-admin/css/common.css b/src/wp-admin/css/common.css index ab7466bdf255c..8edb946b9300f 100644 --- a/src/wp-admin/css/common.css +++ b/src/wp-admin/css/common.css @@ -1819,12 +1819,13 @@ p.auto-update-status { border: 1px solid #c3c4c7; border-top: none; height: auto; + min-height: 32px; /* Compact size for header buttons */ margin-bottom: 0; padding: 3px 6px 3px 16px; background: #fff; border-radius: 0 0 4px 4px; color: #646970; - line-height: 1.7; + line-height: 2.30769231; /* 30px - matches compact button */ box-shadow: 0 0 0 transparent; transition: box-shadow 0.1s linear; } @@ -1850,12 +1851,10 @@ p.auto-update-status { right: 0; content: "\f140"; content: "\f140" / ''; - font: normal 20px/1 dashicons; + font: normal 20px/1.5 dashicons; /* line-height 1.5 = 30px to match compact button */ display: inline-block; padding: 0 5px 0 0; - bottom: 2px; - position: relative; - vertical-align: bottom; + vertical-align: top; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-decoration: none; From 375478210378d261304776913faa1624e7fcd3b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 23 Jan 2026 17:10:02 +0100 Subject: [PATCH 16/16] fix positioning of password hide / show icon --- src/wp-admin/css/forms.css | 14 ++++---------- src/wp-admin/css/login.css | 1 - 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/wp-admin/css/forms.css b/src/wp-admin/css/forms.css index 72aa968fcc307..7ad0092fc4d2e 100644 --- a/src/wp-admin/css/forms.css +++ b/src/wp-admin/css/forms.css @@ -543,14 +543,13 @@ input[type="number"].tiny-text { margin-left: 1em; } -.wp-hide-pw > .dashicons, -.wp-cancel-pw > .dashicons { - position: relative; - top: 3px; +.wp-core-ui .button.wp-hide-pw > .dashicons, +.wp-core-ui .button.wp-cancel-pw > .dashicons { width: 1.25rem; height: 1.25rem; - top: 0.25rem; font-size: 20px; + line-height: 1; + vertical-align: middle; } .wp-cancel-pw .dashicons-no { @@ -585,11 +584,6 @@ fieldset label, height: min-content; } -.wp-pwd button.pwd-toggle .dashicons { - position: relative; - top: 0.25rem; -} - .wp-pwd { margin-top: 1em; position: relative; diff --git a/src/wp-admin/css/login.css b/src/wp-admin/css/login.css index bd14b6db22a8e..b5f424fee7434 100644 --- a/src/wp-admin/css/login.css +++ b/src/wp-admin/css/login.css @@ -127,7 +127,6 @@ p { .login .button.wp-hide-pw .dashicons { width: 1.25rem; height: 1.25rem; - top: 0.25rem; } .login .wp-pwd {